sync rostests to r44455
authorSamuel Serapion <samuel.serapion@gmail.com>
Mon, 7 Dec 2009 18:40:32 +0000 (18:40 +0000)
committerSamuel Serapion <samuel.serapion@gmail.com>
Mon, 7 Dec 2009 18:40:32 +0000 (18:40 +0000)
svn path=/branches/ros-amd64-bringup/; revision=44456

152 files changed:
1  2 
rostests/apitests/directory.rbuild
rostests/dxtest/ddraw/Surface/misc.cpp
rostests/tests/directory.rbuild
rostests/winetests/GUI/browsewnd.c
rostests/winetests/GUI/lang/en-US.rc
rostests/winetests/GUI/mainwnd.c
rostests/winetests/GUI/misc.c
rostests/winetests/advapi32/advapi32.rbuild
rostests/winetests/advapi32/crypt.c
rostests/winetests/advapi32/crypt_sha.c
rostests/winetests/advapi32/security.c
rostests/winetests/advpack/files.c
rostests/winetests/cabinet/extract.c
rostests/winetests/cabinet/fdi.c
rostests/winetests/comcat/comcat.c
rostests/winetests/comctl32/header.c
rostests/winetests/comctl32/listview.c
rostests/winetests/comctl32/monthcal.c
rostests/winetests/comctl32/rebar.c
rostests/winetests/comctl32/status.c
rostests/winetests/comctl32/tab.c
rostests/winetests/comctl32/toolbar.c
rostests/winetests/comctl32/trackbar.c
rostests/winetests/comctl32/treeview.c
rostests/winetests/gdi32/bitmap.c
rostests/winetests/gdi32/clipping.c
rostests/winetests/gdi32/font.c
rostests/winetests/gdi32/gdi32.rbuild
rostests/winetests/gdi32/generated.c
rostests/winetests/gdi32/metafile.c
rostests/winetests/gdiplus/font.c
rostests/winetests/gdiplus/graphics.c
rostests/winetests/icmp/icmp.rbuild
rostests/winetests/imm32/imm32.c
rostests/winetests/kernel32/comm.c
rostests/winetests/kernel32/console.c
rostests/winetests/kernel32/debugger.c
rostests/winetests/kernel32/directory.c
rostests/winetests/kernel32/drive.c
rostests/winetests/kernel32/file.c
rostests/winetests/kernel32/format_msg.c
rostests/winetests/kernel32/heap.c
rostests/winetests/kernel32/kernel32.rbuild
rostests/winetests/kernel32/locale.c
rostests/winetests/kernel32/mailslot.c
rostests/winetests/kernel32/path.c
rostests/winetests/kernel32/pipe.c
rostests/winetests/kernel32/process.c
rostests/winetests/kernel32/profile.c
rostests/winetests/kernel32/resource.c
rostests/winetests/kernel32/thread.c
rostests/winetests/kernel32/toolhelp.c
rostests/winetests/kernel32/virtual.c
rostests/winetests/kernel32/volume.c
rostests/winetests/mlang/mlang.c
rostests/winetests/msacm32/msacm.c
rostests/winetests/mshtml/dom.c
rostests/winetests/mshtml/htmldoc.c
rostests/winetests/mshtml/protocol.c
rostests/winetests/mshtml/script.c
rostests/winetests/mshtml/testlist.c
rostests/winetests/msi/db.c
rostests/winetests/msi/format.c
rostests/winetests/msi/install.c
rostests/winetests/msi/msi.c
rostests/winetests/msi/package.c
rostests/winetests/msi/source.c
rostests/winetests/msvcrt/dir.c
rostests/winetests/msvcrt/file.c
rostests/winetests/msvcrt/printf.c
rostests/winetests/msvcrt/string.c
rostests/winetests/msvcrt/time.c
rostests/winetests/netapi32/apibuf.c
rostests/winetests/netapi32/wksta.c
rostests/winetests/ntdll/atom.c
rostests/winetests/ntdll/file.c
rostests/winetests/ntdll/generated.c
rostests/winetests/ntdll/info.c
rostests/winetests/ntdll/ntdll.rbuild
rostests/winetests/ntdll/om.c
rostests/winetests/ntdll/port.c
rostests/winetests/ntdll/reg.c
rostests/winetests/ntdll/rtlstr.c
rostests/winetests/ntdll/string.c
rostests/winetests/odbccp32/misc.c
rostests/winetests/ole32/clipboard.c
rostests/winetests/ole32/marshal.c
rostests/winetests/ole32/moniker.c
rostests/winetests/ole32/ole2.c
rostests/winetests/ole32/propvariant.c
rostests/winetests/oleaut32/olefont.c
rostests/winetests/oleaut32/safearray.c
rostests/winetests/oleaut32/tmarshal.c
rostests/winetests/oleaut32/typelib.c
rostests/winetests/oleaut32/usrmarshal.c
rostests/winetests/oleaut32/vartest.c
rostests/winetests/powrprof/powrprof.rbuild
rostests/winetests/powrprof/pwrprof.c
rostests/winetests/psapi/psapi.rbuild
rostests/winetests/psapi/psapi_main.c
rostests/winetests/riched20/editor.c
rostests/winetests/riched20/testlist.c
rostests/winetests/riched32/editor.c
rostests/winetests/rpcrt4/generated.c
rostests/winetests/rpcrt4/ndr_marshall.c
rostests/winetests/rpcrt4/server.c
rostests/winetests/rsaenh/rsaenh.c
rostests/winetests/setupapi/devinst.c
rostests/winetests/setupapi/parser.c
rostests/winetests/setupapi/query.c
rostests/winetests/setupapi/setupapi.rbuild
rostests/winetests/setupapi/stringtable.c
rostests/winetests/shell32/generated.c
rostests/winetests/shell32/shellpath.c
rostests/winetests/shell32/shlexec.c
rostests/winetests/shell32/shlfileop.c
rostests/winetests/shell32/shlfolder.c
rostests/winetests/shell32/systray.c
rostests/winetests/shell32/testlist.c
rostests/winetests/shlwapi/generated.c
rostests/winetests/shlwapi/istream.c
rostests/winetests/shlwapi/path.c
rostests/winetests/shlwapi/shreg.c
rostests/winetests/shlwapi/string.c
rostests/winetests/urlmon/generated.c
rostests/winetests/urlmon/misc.c
rostests/winetests/urlmon/protocol.c
rostests/winetests/urlmon/testlist.c
rostests/winetests/urlmon/url.c
rostests/winetests/user32/broadcast.c
rostests/winetests/user32/class.c
rostests/winetests/user32/cursoricon.c
rostests/winetests/user32/dde.c
rostests/winetests/user32/edit.c
rostests/winetests/user32/generated.c
rostests/winetests/user32/input.c
rostests/winetests/user32/listbox.c
rostests/winetests/user32/menu.c
rostests/winetests/user32/monitor.c
rostests/winetests/user32/msg.c
rostests/winetests/user32/resource.c
rostests/winetests/user32/scroll.c
rostests/winetests/user32/sysparams.c
rostests/winetests/user32/text.c
rostests/winetests/user32/user32.rbuild
rostests/winetests/user32/win.c
rostests/winetests/uxtheme/system.c
rostests/winetests/wininet/ftp.c
rostests/winetests/wininet/generated.c
rostests/winetests/wininet/http.c
rostests/winetests/wininet/internet.c
rostests/winetests/wininet/url.c

Simple merge
Simple merge
@@@ -217,10 -215,14 +215,14 @@@ BuildTestItemData(LPWSTR lpName
                                    sizeof(TEST_ITEM));
      if (pItem)
      {
-         if (lpDll)
-             wcsncpy(pItem->szSelectedDll, lpDll, MAX_PATH);
-         if (lpRun)
-             wcsncpy(pItem->szRunString, lpRun, MAX_RUN_CMD);
+         if (lpName)
+         {
+             wcsncpy(pItem->szName, lpName, MAX_PATH);
 -        }
++    }
+         if (lpRunCmd)
+         {
+             wcsncpy(pItem->szRunCmd, lpRunCmd, MAX_RUN_CMD);
+         }
      }
  
      return pItem;
@@@ -285,52 -284,12 +284,12 @@@ PopulateTreeView(PMAIN_WND_INFO pInfo
                  hParent = InsertIntoTreeView(pInfo->hBrowseTV,
                                               hRoot,
                                               lpTestName,
-                                              pTestItem,
+                                              (LPARAM)pTestItem,
                                               IL_TEST,
                                               HAS_CHILD);
-                 if (hParent)
-                 {
-                     /* Get the list of modules a dll offers. This is returned as list of
-                      * Ansi null-terminated strings, terminated with an empty string (double null) */
-                     GetModulesInTest = (MODULES)GetProcAddress(hDll, "GetModulesInTest");
-                     if ((numMods = GetModulesInTest(&lpModules)))
-                     {
-                         ptr = lpModules;
-                         while (numMods && *ptr != '\0')
-                         {
-                             /* convert the string to unicode */
-                             if (AnsiToUnicode(ptr, &lpModW))
-                             {
-                                 WCHAR szRunCmd[MAX_RUN_CMD];
-                                 _snwprintf(szRunCmd, MAX_RUN_CMD, L"%s:%s", lpTestName, lpModW);
-                                 pTestItem = BuildTestItemData(lpDllPath, szRunCmd);
-                                 InsertIntoTreeView(pInfo->hBrowseTV,
-                                                    hParent,
-                                                    lpModW,
-                                                    pTestItem,
-                                                    IL_TEST,
-                                                    HAS_NO_CHILD);
-                                 HeapFree(GetProcessHeap(), 0, lpModW);
 -            }
 -        }
 -    }
 +                            }
-                             /* move onto next string */
-                             while (*(ptr++) != '\0')
-                                 ;
-                             numMods--;
 +                        }
-                         HeapFree(GetProcessHeap(), 0, lpModules);
 +                    }
-                 }
-             }
-             FreeLibrary(hDll);
-         }
-     }
  
      if (hRoot)
      {
@@@ -29,7 -30,18 +30,18 @@@ STYLE DS_SHELLFONT | WS_BORDER | WS_DLG
  CAPTION "Test hierarchy"
  FONT 8, "MS Shell Dlg", 0, 0, 0x1
  BEGIN
 -    PUSHBUTTON       "Select", IDOK, 202, 7, 50, 14
 -    PUSHBUTTON       "Close", IDCANCEL, 202, 34, 50, 14
 -    CONTROL          "", IDC_TREEVIEW, "SysTreeView32", WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 7, 7, 189, 236 
 +   PUSHBUTTON       "Select", IDOK, 202, 7, 50, 14
 +   PUSHBUTTON       "Close", IDCANCEL, 202, 34, 50, 14
 +   CONTROL          "", IDC_TREEVIEW, "SysTreeView32", WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 7, 7, 189, 236 
  END
+ IDD_OPTIONS DIALOGEX 0, 0, 180, 100
+ STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME
+ CAPTION "Options"
+ FONT 8, "MS Shell Dlg", 0, 0, 0x1
+ BEGIN
+     PUSHBUTTON       "OK", IDOK, 70, 80, 50, 14
+     PUSHBUTTON       "Cancel", IDCANCEL, 125, 80, 50, 14
+     CONTROL          "Hide console window",IDC_HIDECONSOLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,10,80,10
+     CONTROL          "Run on start",IDC_RUNONSTART,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,30,80,10
+ END
@@@ -79,49 -204,29 +204,29 @@@ RunSelectedTest(PMAIN_WND_INFO pInfo
          if (SendMessageW(hRunCmd,
                           CB_GETLBTEXT,
                           sel,
-                          szTextCmd) != CB_ERR)
+                          (LPARAM)szTextCmd) != CB_ERR)
          {
-             lpDllPath = SendMessage(hRunCmd,
+             pInfo->lpCmdLine = (LPWSTR)SendMessage(hRunCmd,
 -                                                   CB_GETITEMDATA,
 -                                                   0,
 -                                                   0);
 +                                    CB_GETITEMDATA,
 +                                    0,
 +                                    0);
-             if (lpDllPath)
+             if (pInfo->lpCmdLine)
              {
-                 LPWSTR module = szTextCmd;
-                 LPSTR lpTest;
-                 while (*(module++) != L':' && *module != L'\0')
-                     ;
-                 if (*module)
-                 {
-                     if (UnicodeToAnsi(module, &lpTest))
-                     {
-                         HMODULE hDll;
-                         RUNTEST RunTest;
-                         hDll = LoadLibraryW(lpDllPath);
-                         if (hDll)
-                         {
-                             RunTest = (RUNTEST)GetProcAddress(hDll, "RunTest");
-                             if (RunTest)
-                             {
-                                 RunTest(lpTest);
+                 //
+                 // Create a new thread to create the client process
+                 // and recieve any ouput via stdout
+                 //
+                 CreateThread(NULL,
+                              0,
+                              CreateClientProcess,
+                              pInfo,
+                              0,
+                              NULL);
 -            }
 -        }
 -    }
 -}
 +                            }
-                             FreeLibrary(hDll);
 +                        }
-                         DisplayError(GetLastError());
-                         HeapFree(GetProcessHeap(), 0, lpTest);
 +                    }
 +                }
  
-             }
-         }
-     }
- }
  static VOID
  AddTestToCombo(PMAIN_WND_INFO pInfo)
  {
@@@ -175,13 -279,13 +279,13 @@@ FreeTestCmdStrings(PMAIN_WND_INFO pInfo
      {
          for (i = 0; i < cnt; i++)
          {
-             lpDllPath = SendMessage(hRunCmd,
+             lpExePath = (LPWSTR)SendMessage(hRunCmd,
 -                                            CB_GETITEMDATA,
 -                                            i,
 -                                            0);
 +                                    CB_GETITEMDATA,
 +                                    i,
 +                                    0);
-             if (lpDllPath)
+             if (lpExePath)
              {
-                 HeapFree(GetProcessHeap(), 0, lpDllPath);
+                 HeapFree(GetProcessHeap(), 0, lpExePath);
              }
          }
      }
@@@ -238,12 -238,12 +238,12 @@@ InitImageList(UINT StartResource
      /* Add all icons to the image list */
      for (i = StartResource; i <= EndResource; i++)
      {
-         hIcon = (HBITMAP)LoadImageW(hInstance,
+         hIcon = (HICON)LoadImageW(hInstance,
 -                                  MAKEINTRESOURCEW(i),
 -                                  IMAGE_ICON,
 -                                  Width,
 -                                  Height,
 -                                  LR_DEFAULTCOLOR);
 +                                    MAKEINTRESOURCEW(i),
 +                                    IMAGE_ICON,
 +                                    Width,
 +                                    Height,
 +                                    LR_DEFAULTCOLOR);
          if (hIcon == NULL)
              goto fail;
  
@@@ -1,24 -1,21 +1,21 @@@
  <?xml version="1.0"?>
  <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
- <group>
  <module name="advapi32_winetest" type="win32cui" installbase="bin" installname="advapi32_winetest.exe" allowwarnings="true">
 -      <include base="advapi32_winetest">.</include>
 +    <include base="advapi32_winetest">.</include>
-     <define name="__USE_W32API" />
+       <define name="__ROS_LONG64__" />
 -      <library>advapi32</library>
 -      <library>ntdll</library>
 -      <library>uuid</library>
 -      <library>ole32</library>
 -      <file>cred.c</file>
 -      <file>crypt.c</file>
 -      <file>crypt_lmhash.c</file>
 -      <file>crypt_md4.c</file>
 -      <file>crypt_md5.c</file>
 -      <file>crypt_sha.c</file>
 -      <file>lsa.c</file>
 -      <file>registry.c</file>
 -      <file>security.c</file>
 -      <file>service.c</file>
 -      <file>testlist.c</file>
 +    <library>advapi32</library>
-     <library>kernel32</library>
 +    <library>ntdll</library>
 +    <library>uuid</library>
 +    <library>ole32</library>
 +    <file>cred.c</file>
 +    <file>crypt.c</file>
 +    <file>crypt_lmhash.c</file>
 +    <file>crypt_md4.c</file>
 +    <file>crypt_md5.c</file>
 +    <file>crypt_sha.c</file>
 +    <file>lsa.c</file>
 +    <file>registry.c</file>
 +    <file>security.c</file>
 +    <file>service.c</file>
 +    <file>testlist.c</file>
  </module>
- </group>
@@@ -461,8 -461,8 +461,8 @@@ static BOOL FindProvRegVals(DWORD dwInd
        RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName, 
                                 NULL, NULL, NULL, NULL, NULL, NULL);
        (*pcbProvName)++;
 -
 +      
-       if (!(*pszProvName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbProvName))))
+       if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))
                return FALSE;
        
        RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
@@@ -566,43 -566,61 +566,61 @@@ static BOOL FindProvTypesRegVals(DWORD 
        HKEY hKey;
        HKEY hSubKey;
        PSTR ch;
 -
+       LPSTR szName;
+       DWORD cbName;
+       BOOL ret = FALSE;
 +      
        if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
                return FALSE;
 -
 +      
-       if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, pcbTypeName, NULL,
+       if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, &cbName, NULL,
                        NULL, NULL, NULL, NULL, NULL))
-           return FALSE;
-       (*pcbTypeName)++;
+               goto cleanup;
+       cbName++;
 -
 +      
-       if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
-               return FALSE;
+       if (!(szName = LocalAlloc(LMEM_ZEROINIT, cbName)))
+               goto cleanup;
 -
 +      
-       if (RegEnumKeyEx(hKey, dwIndex, *pszTypeName, pcbTypeName, NULL, NULL, NULL, NULL))
-           return FALSE;
-       (*pcbTypeName)++;
-       ch = *pszTypeName + strlen(*pszTypeName);
+       while (!RegEnumKeyEx(hKey, *pdwIndex, szName, &cbName, NULL, NULL, NULL, NULL))
+       {
+               cbName++;
+               ch = szName + strlen(szName);
 -              /* Convert "Type 000" to 0, etc/ */
 -              *pdwProvType = *(--ch) - '0';
 -              *pdwProvType += (*(--ch) - '0') * 10;
 -              *pdwProvType += (*(--ch) - '0') * 100;
 -
 +      /* Convert "Type 000" to 0, etc/ */
 +      *pdwProvType = *(--ch) - '0';
 +      *pdwProvType += (*(--ch) - '0') * 10;
 +      *pdwProvType += (*(--ch) - '0') * 100;
 +      
-       if (RegOpenKey(hKey, *pszTypeName, &hSubKey))
-           return FALSE;
+               if (RegOpenKey(hKey, szName, &hSubKey))
+                       break;
 -
 +      
-       if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
-             return FALSE;
+               if (!RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
+               {
+                       if (!(*pszTypeName = LocalAlloc(LMEM_ZEROINIT, *pcbTypeName)))
+                               break;
  
-       if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
-               return FALSE;
+                       if (!RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
+                       {
+                               ret = TRUE;
+                               break;
+                       }
 -
 +      
-       if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName, pcbTypeName))
-           return FALSE;
+                       LocalFree(*pszTypeName);
+               }
 -
 -              RegCloseKey(hSubKey);
 +      
 +      RegCloseKey(hSubKey);
+               (*pdwIndex)++;
+       }
+       if (!ret)
+               LocalFree(*pszTypeName);
+       RegCloseKey(hSubKey);
+       LocalFree(szName);
+ cleanup:
        RegCloseKey(hKey);
 -
 +      
-       return TRUE;
+       return ret;
  }
  
  static void test_enum_provider_types(void)
        DWORD result;
        DWORD notNull = 5;
        DWORD notZeroFlags = 5;
 -
 +      
        if(!pCryptEnumProviderTypesA)
        {
-           skip("CryptEnumProviderTypesA is not available\n");
+               win_skip("CryptEnumProviderTypesA is not available\n");
 -              return;
 +          return;
        }
 -
 +      
-       if (!FindProvTypesRegVals(index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
+       if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))
        {
 -              skip("Could not find provider types in registry\n");
 -              return;
 +          skip("Could not find provider types in registry\n");
 +          return;
        }
 -
 +      
        /* check pdwReserved for NULL */
        result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);
-       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n", 
-               ERROR_INVALID_PARAMETER, GetLastError());
+       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n",
+               GetLastError());
 -
 +      
        /* check dwFlags == zero */
        result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);
-       ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %i, got %d\n",
-               ERROR_INVALID_PARAMETER, GetLastError());
+       ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n",
+               GetLastError());
 -
 +      
+       /* This test fails under Win2k SP4:
+        * result = TRUE, GetLastError() == 0xdeadbeef */
+       if (0)
+       {
 -              /* alloc provider type to half the size required
 -               * cbTypeName holds the size required */
 -              typeNameSize = cbTypeName / 2;
 +      /* alloc provider type to half the size required
 +       * cbTypeName holds the size required */
 +      typeNameSize = cbTypeName / 2;
-       if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
-               return;
+               if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
+                       goto cleanup;
  
-       /* This test fails under Win2k SP4:
-          result = TRUE, GetLastError() == 0xdeadbeef
 -              SetLastError(0xdeadbeef);
 -              result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
 +      SetLastError(0xdeadbeef);
 +      result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
-       ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%08lx\n",
+               ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n",
 -                      result, GetLastError());
 -
 -              LocalFree(typeName);
 +              result, GetLastError());
-       */
 +      
 +      LocalFree(typeName);
+       }
 -
 +      
        /* loop through the provider types to get the number of provider types 
         * after loop ends, count should be dwTypeCount + 1 so subtract 1
         * to get actual number of provider types */
         * ERROR_NO_MORE_ITEMS */
        for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
                result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);
-       ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", 
-                       ERROR_NO_MORE_ITEMS, GetLastError());
+       ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n",
+               GetLastError());
 -
 +      
        /* check expected versus actual values returned */
        result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);
        ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
-       if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
-               return;
+       if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize)))
+               goto cleanup;
 -
 +              
        typeNameSize = 0xdeadbeef;
        result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);
        ok(result, "expected TRUE, got %d\n", result);
        ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
        if (pszTypeName)
 -              ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
 +          ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);
        ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize);
 -
 +      
        LocalFree(typeName);
+ cleanup:
+       LocalFree(pszTypeName);
  }
  
  static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)
@@@ -35,12 -35,13 +35,13 @@@ typedef struct 
  
  static void test_sha_ctx(void)
  {
-    FARPROC pA_SHAInit, pA_SHAUpdate, pA_SHAFinal;
-    static const char test_buffer[] = "In our Life there's If"
+     void (WINAPI *pA_SHAInit)(PSHA_CTX);
+     void (WINAPI *pA_SHAUpdate)(PSHA_CTX, const unsigned char *, UINT);
+     void (WINAPI *pA_SHAFinal)(PSHA_CTX, PULONG);
+     static const unsigned char test_buffer[] = "In our Life there's If"
 -                                               "In our beliefs there's Lie"
 -                                               "In our business there is Sin"
 -                                               "In our bodies, there is Die";
 +                       "In our beliefs there's Lie"
 +                       "In our business there is Sin"
 +                       "In our bodies, there is Die";
-    ULONG test_buffer_size = strlen(test_buffer);
     HMODULE hmod;
     SHA_CTX ctx;
     ULONG result[5];
@@@ -701,15 -730,106 +730,106 @@@ static void test_FileSecurity(void
          return;
      }
  
-     strcpy(directory, "\\Should not exist");
+     if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) {
+         win_skip ("GetTempPathA failed\n");
+         return;
+     }
+     /* Create a temporary directory and in it a temporary file */
+     strcat (strcpy (path, wintmpdir), "rary");
+     SetLastError(0xdeadbeef);
+     rc = CreateDirectoryA (path, NULL);
+     ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA "
+         "failed for '%s' with %d\n", path, GetLastError());
+     strcat (strcpy (file, path), "\\ess");
+     SetLastError(0xdeadbeef);
+     fh = CreateFileA (file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+     ok (fh != INVALID_HANDLE_VALUE, "CreateFileA "
+         "failed for '%s' with %d\n", file, GetLastError());
+     CloseHandle (fh);
+     /* For the temporary file ... */
+     /* Get size needed */
+     retSize = 0;
+     SetLastError(0xdeadbeef);
+     rc = pGetFileSecurityA (file, request, NULL, 0, &retSize);
+     if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
+         win_skip("GetFileSecurityA is not implemented\n");
+         goto cleanup;
 -    }
++}
+     ok (!rc, "GetFileSecurityA "
+         "was expected to fail for '%s'\n", file);
+     ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
+         "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
+     ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize);
+     sdSize = retSize;
+     sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
+     /* Get security descriptor for real */
+     retSize = -1;
+     SetLastError(0xdeadbeef);
+     rc = pGetFileSecurityA (file, request, sd, sdSize, &retSize);
+     ok (rc, "GetFileSecurityA "
+         "was not expected to fail '%s': %d\n", file, GetLastError());
+     ok (retSize == sdSize ||
+         broken(retSize == 0), /* NT4 */
+         "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
+     /* Use it to set security descriptor */
+     SetLastError(0xdeadbeef);
+     rc = pSetFileSecurityA (file, request, sd);
+     ok (rc, "SetFileSecurityA "
+         "was not expected to fail '%s': %d\n", file, GetLastError());
+     HeapFree (GetProcessHeap (), 0, sd);
+     /* Repeat for the temporary directory ... */
  
-     SetLastError(NO_ERROR);
-     result = pGetFileSecurityA( directory,OWNER_SECURITY_INFORMATION,buffer,0x40,&outSize);
-     ok(!result, "GetFileSecurityA should fail for not existing directories/files\n"); 
-     ok( (GetLastError() == ERROR_FILE_NOT_FOUND ) ||
-         (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) , 
-         "last error ERROR_FILE_NOT_FOUND / ERROR_CALL_NOT_IMPLEMENTED (98) "
-         "expected, got %d\n", GetLastError());
+     /* Get size needed */
+     retSize = 0;
+     SetLastError(0xdeadbeef);
+     rc = pGetFileSecurityA (path, request, NULL, 0, &retSize);
+     ok (!rc, "GetFileSecurityA "
+         "was expected to fail for '%s'\n", path);
+     ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
+         "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
+     ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize);
+     sdSize = retSize;
+     sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
+     /* Get security descriptor for real */
+     retSize = -1;
+     SetLastError(0xdeadbeef);
+     rc = pGetFileSecurityA (path, request, sd, sdSize, &retSize);
+     ok (rc, "GetFileSecurityA "
+         "was not expected to fail '%s': %d\n", path, GetLastError());
+     ok (retSize == sdSize ||
+         broken(retSize == 0), /* NT4 */
+         "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
+     /* Use it to set security descriptor */
+     SetLastError(0xdeadbeef);
+     rc = pSetFileSecurityA (path, request, sd);
+     ok (rc, "SetFileSecurityA "
+         "was not expected to fail '%s': %d\n", path, GetLastError());
+     HeapFree (GetProcessHeap (), 0, sd);
+     /* Old test */
+     strcpy (wintmpdir, "\\Should not exist");
+     SetLastError(0xdeadbeef);
+     rc = pGetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize);
+     ok (!rc, "GetFileSecurityA should fail for not existing directories/files\n");
+     ok (GetLastError() == ERROR_FILE_NOT_FOUND,
+         "last error ERROR_FILE_NOT_FOUND expected, got %d\n", GetLastError());
+ cleanup:
+     /* Remove temporary file and directory */
+     DeleteFileA(file);
+     RemoveDirectoryA(path);
  }
  
  static void test_AccessCheck(void)
@@@ -1027,10 -1243,11 +1243,11 @@@ static void test_token_attr(void
          Domain[0] = '\0';
          ret = LookupAccountSid(NULL, Groups->Groups[i].Sid, Name, &NameLength, Domain, &DomainLength, &SidNameUse);
          if (ret)
-             trace("\t%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes);
-         else
-             trace("\t%s, attr: 0x%08x LookupAccountSid failed with error %d\n", SidString, Groups->Groups[i].Attributes, GetLastError());
+         {
+             trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes);
 -            LocalFree(SidString);
 -        }
 +        LocalFree(SidString);
++    }
+         else trace("attr: 0x%08x LookupAccountSid failed with error %d\n", Groups->Groups[i].Attributes, GetLastError());
      }
      HeapFree(GetProcessHeap(), 0, Groups);
  
@@@ -1545,10 -1915,10 +1915,10 @@@ static void test_LookupAccountName(void
      {
          ok(!lstrcmp(account, user_name), "Expected %s, got %s\n", user_name, account);
          ok(!lstrcmp(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
-         ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size);
-         ok(lstrlen(domain) == domain_size, "Expected %d\n", lstrlen(domain));
-         ok(sid_use == SidTypeUser, "Expected SidTypeUser, got %d\n", sid_use);
      }
 -    ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size);
++        ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size);
+     ok(lstrlen(domain) == domain_size, "Expected %d, got %d\n", lstrlen(domain), domain_size);
+     ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n", SidTypeUser, sid_use);
      domain_size = domain_save;
      sid_size = sid_save;
  
      sid_use = 0xcafebabe;
      SetLastError(0xdeadbeef);
      ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
 -        ok(!ret, "Expected 0, got %d\n", ret);
 -        ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
 -           "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
 -        ok(sid_size != 0, "Expected non-zero sid size\n");
 -        ok(domain_size != 0, "Expected non-zero domain size\n");
 -        ok(sid_use == 0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
+     if (!ret && GetLastError() == ERROR_NONE_MAPPED)
+         win_skip("NULL account name doesn't work on NT4\n");
+     else
+     {
 +    ok(!ret, "Expected 0, got %d\n", ret);
 +    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
 +       "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
 +    ok(sid_size != 0, "Expected non-zero sid size\n");
 +    ok(domain_size != 0, "Expected non-zero domain size\n");
 +    ok(sid_use == 0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
  
 -        psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
 -        domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
 +    psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
 +    domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
  
 -        /* try NULL account name */
 -        ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use);
 -        get_sid_info(psid, &account, &sid_dom);
 -        ok(ret, "Failed to lookup account name\n");
 +    /* try NULL account name */
 +    ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use);
 +    get_sid_info(psid, &account, &sid_dom);
 +    ok(ret, "Failed to lookup account name\n");
-     todo_wine
-     {
          /* Using a fixed string will not work on different locales */
          ok(!lstrcmp(account, domain),
             "Got %s for account and %s for domain, these should be the same\n",
      domain_size = 0;
      ret = LookupAccountNameA(NULL, "oogabooga", NULL, &sid_size, NULL, &domain_size, &sid_use);
      ok(!ret, "Expected 0, got %d\n", ret);
-     todo_wine
-     {
-         ok(GetLastError() == ERROR_NONE_MAPPED,
+     ok(GetLastError() == ERROR_NONE_MAPPED ||
+        broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE),
 -       "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError());
 -    ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
 -    ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
 +           "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError());
 +        ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
 +        ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
-     }
  
 -        HeapFree(GetProcessHeap(), 0, psid);
 -    }
+     /* try an invalid system name */
+     SetLastError(0xdeadbeef);
+     sid_size = 0;
+     domain_size = 0;
+     ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
+     ok(!ret, "Expected 0, got %d\n", ret);
+     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */,
+        "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
+     ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
+     ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
+     /* try with the computer name as the account name */
+     domain_size = sizeof(computer_name);
+     GetComputerNameA(computer_name, &domain_size);
+     sid_size = 0;
+     domain_size = 0;
+     ret = LookupAccountNameA(NULL, computer_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
+     ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
+        GetLastError() == ERROR_NONE_MAPPED /* in a domain */ ||
+        broken(GetLastError() == ERROR_TRUSTED_DOMAIN_FAILURE) ||
+        broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE)),
+        "LookupAccountNameA failed: %d\n", GetLastError());
+     if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+     {
+         psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
+         domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
+         ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use);
+         ok(ret, "LookupAccountNameA failed: %d\n", GetLastError());
+         ok(sid_use == SidTypeDomain, "expected SidTypeDomain, got %d\n", sid_use);
+         HeapFree(GetProcessHeap(), 0, domain);
-     HeapFree(GetProcessHeap(), 0, domain);
 +    HeapFree(GetProcessHeap(), 0, psid);
++}
+     /* Well Known names */
+     if (!pCreateWellKnownSid)
+     {
+         win_skip("CreateWellKnownSid not available\n");
+         return;
+     }
+     if (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)
+     {
+         skip("Non-english locale (skipping well known name creation tests)\n");
+         return;
+     }
+     check_wellknown_name("LocalService", WinLocalServiceSid);
+     check_wellknown_name("Local Service", WinLocalServiceSid);
+     /* 2 spaces */
+     check_wellknown_name("Local  Service", 0);
+     check_wellknown_name("NetworkService", WinNetworkServiceSid);
+     check_wellknown_name("Network Service", WinNetworkServiceSid);
+     /* example of some names where the spaces are not optional */
+     check_wellknown_name("Terminal Server User", WinTerminalServerSid);
+     check_wellknown_name("TerminalServer User", 0);
+     check_wellknown_name("TerminalServerUser", 0);
+     check_wellknown_name("Terminal ServerUser", 0);
+     check_wellknown_name("enterprise domain controllers",WinEnterpriseControllersSid);
+     check_wellknown_name("enterprisedomain controllers", 0);
+     check_wellknown_name("enterprise domaincontrollers", 0);
+     check_wellknown_name("enterprisedomaincontrollers", 0);
+     /* case insensitivity */
+     check_wellknown_name("lOCAlServICE", WinLocalServiceSid);
+     /* fully qualified account names */
+     check_wellknown_name("NT AUTHORITY\\LocalService", WinLocalServiceSid);
+     check_wellknown_name("nt authority\\Network Service", WinNetworkServiceSid);
+     check_wellknown_name("nt authority test\\Network Service", 0);
+     check_wellknown_name("Dummy\\Network Service", 0);
+     check_wellknown_name("ntauthority\\Network Service", 0);
  }
  
  static void test_security_descriptor(void)
@@@ -1714,8 -2158,13 +2158,13 @@@ static void test_granted_access(HANDLE 
      status = pNtQueryObject( handle, ObjectBasicInformation, &obj_info,
                               sizeof(obj_info), NULL );
      ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status);
 -        ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should "
 -            "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess);
+     if (alt)
+         ok_(__FILE__, line)(obj_info.GrantedAccess == access ||
+             obj_info.GrantedAccess == alt, "Granted access should be 0x%08x "
+             "or 0x%08x, instead of 0x%08x\n", access, alt, obj_info.GrantedAccess);
+     else
 +    ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should "
 +        "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess);
  }
  
  #define CHECK_SET_SECURITY(o,i,e) \
@@@ -2471,11 -3118,17 +3118,17 @@@ static void test_acls(void
      ret = IsValidAcl(pAcl);
      ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
  
+     SetLastError(0xdeadbeef);
      ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4);
 -        ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n", GetLastError());
+     if (GetLastError() != ERROR_INVALID_PARAMETER)
+     {
 +    ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n", GetLastError());
  
 -        ret = IsValidAcl(pAcl);
 -        ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
 +    ret = IsValidAcl(pAcl);
 +    ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
+     }
+     else
+         win_skip("ACL_REVISION4 is not implemented on NT4\n");
  
      SetLastError(0xdeadbeef);
      ret = InitializeAcl(pAcl, sizeof(buffer), -1);
@@@ -132,8 -133,13 +133,13 @@@ static void test_AddDelBackupEntry(void
      /* create the INF file */
      res = pAddDelBackupEntry("one\0two\0three\0", "c:\\", "basename", AADBE_ADD_ENTRY);
      ok(res == S_OK, "Expected S_OK, got %d\n", res);
 -        ok(check_ini_file_attr(path), "Expected ini file to be hidden\n");
 -        ok(DeleteFileA(path), "Expected path to exist\n");
+     if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
+     {
 +    ok(check_ini_file_attr(path), "Expected ini file to be hidden\n");
 +    ok(DeleteFileA(path), "Expected path to exist\n");
+     }
+     else
+         win_skip("Test file could not be created\n");
  
      lstrcpyA(path, CURR_DIR);
      lstrcatA(path, "\\backup\\basename.INI");
@@@ -190,8 -199,8 +199,8 @@@ static LONG CDECL progress(UINT typeSta
      return 0;
  }
  
- static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
+ static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
 -                             BOOL fContinuation, void *pv)
 +                       BOOL fContinuation, void *pv)
  {
      return 0;
  }
@@@ -290,8 -299,8 +299,8 @@@ static BOOL CDECL get_temp_file(char *p
      return FALSE;
  }
  
- static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
+ static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
 -                                   USHORT *pattribs, int *err, void *pv)
 +                             USHORT *pattribs, int *err, void *pv)
  {
      BY_HANDLE_FILE_INFORMATION finfo;
      FILETIME filetime;
@@@ -131,8 -131,8 +131,8 @@@ static LONG CDECL progress(UINT typeSta
      return 0;
  }
  
- static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
+ static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
 -                             BOOL fContinuation, void *pv)
 +                       BOOL fContinuation, void *pv)
  {
      return 0;
  }
@@@ -231,8 -231,8 +231,8 @@@ static BOOL CDECL get_temp_file(char *p
      return FALSE;
  }
  
- static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
+ static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
 -                                   USHORT *pattribs, int *err, void *pv)
 +                             USHORT *pattribs, int *err, void *pv)
  {
      BY_HANDLE_FILE_INFORMATION finfo;
      FILETIME filetime;
@@@ -335,8 -334,8 +334,8 @@@ static LONG CDECL progress(UINT typeSta
      return 0;
  }
  
- static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
+ static int CDECL file_placed(PCCAB pccab, char *pszFile, LONG cbFile,
 -                             BOOL fContinuation, void *pv)
 +                       BOOL fContinuation, void *pv)
  {
      return 0;
  }
@@@ -435,8 -434,8 +434,8 @@@ static BOOL CDECL get_temp_file(char *p
      return FALSE;
  }
  
- static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
+ static INT_PTR CDECL get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
 -                                   USHORT *pattribs, int *err, void *pv)
 +                             USHORT *pattribs, int *err, void *pv)
  {
      BY_HANDLE_FILE_INFORMATION finfo;
      FILETIME filetime;
@@@ -622,21 -619,44 +619,44 @@@ static void test_FDICopy(void
  
      FCIDestroy(hfci);
  
 -        hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
 -                         fdi_write, fdi_close, fdi_seek,
 -                         cpuUNKNOWN, &erf);
+     lstrcpyA(path, CURR_DIR);
+     /* path doesn't have a trailing backslash */
+     if (lstrlenA(path) > 2)
+     {
 +    hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
 +                     fdi_write, fdi_close, fdi_seek,
 +                     cpuUNKNOWN, &erf);
  
-     /* cabinet with no files or folders */
 -        SetLastError(0xdeadbeef);
 -        ret = FDICopy(hfdi, name, path, 0, CopyProgress, NULL, 0);
 -        ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
 -        todo_wine
 -        {
 -            ok(GetLastError() == ERROR_INVALID_HANDLE,
 -               "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
 -        }
 +    SetLastError(0xdeadbeef);
 +    ret = FDICopy(hfdi, name, path, 0, CopyProgress, NULL, 0);
 +    ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
 +    todo_wine
 +    {
 +        ok(GetLastError() == ERROR_INVALID_HANDLE,
 +           "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
 +    }
  
 -        FDIDestroy(hfdi);
 +    FDIDestroy(hfdi);
+     }
+     else
+         skip("Running on a root drive directory.\n");
+     lstrcatA(path, "\\");
+     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
+                      fdi_write, fdi_close, fdi_seek,
+                      cpuUNKNOWN, &erf);
+     /* cabinet with no files or folders */
+     SetLastError(0xdeadbeef);
+     ret = FDICopy(hfdi, name, path, 0, CopyProgress, NULL, 0);
+     todo_wine
+     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
+     ok(GetLastError() == 0, "Expected 0f, got %d\n", GetLastError());
+     FDIDestroy(hfdi);
      DeleteFileA(name);
  }
  
  
  #include "wine/test.h"
  
 -#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
 +#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x \n", hr)
  
- static void register_testentry(void)
+ static BOOL register_testentry(void)
  {
-       HKEY hkey,hkey2;
+       HKEY hkey = 0, hkey2 = 0;
+         DWORD ret;
  
-       RegCreateKeyA(HKEY_CLASSES_ROOT,"CLSID\\{deadcafe-beed-bead-dead-cafebeaddead}",
-                       &hkey);
-       RegSetValueA(hkey,NULL,REG_SZ,"ComCat Test key",16);
-       RegCreateKeyA(hkey,
+         ret = RegCreateKeyA(HKEY_CLASSES_ROOT,"CLSID\\{deadcafe-beed-bead-dead-cafebeaddead}", &hkey);
+         if (!ret) ret =       RegSetValueA(hkey,NULL,REG_SZ,"ComCat Test key",16);
+       if (!ret) ret = RegCreateKeyA(hkey,
 -                                      "Implemented Categories\\{deadcafe-0000-0000-0000-000000000000}",
 -                                      &hkey2);
 +                      "Implemented Categories\\{deadcafe-0000-0000-0000-000000000000}",
 +                      &hkey2);
        RegCloseKey(hkey);
        RegCloseKey(hkey2);
+         return !ret;
  }
  
  static void unregister_testentry(void)
@@@ -83,9 -84,9 +84,9 @@@ static void do_enum(void
  
        IEnumCLSID *pIEnum =(IEnumCLSID*)0xdeadcafe;
  
-       CLSIDFromString((LPOLESTR)szCatID,the_cat);
-       CLSIDFromString((LPOLESTR)szGuid,&wanted_guid);
+       CLSIDFromString(szCatID,the_cat);
+       CLSIDFromString(szGuid,&wanted_guid);
 -
 +      
        OleInitialize(NULL);
  
        hr = CoCreateInstance(rclsid,NULL,CLSCTX_INPROC_SERVER,
        hr = IEnumGUID_Next(pIEnum,1,the_guid, &fetched);
        ok (fetched == 0,"Fetched wrong number of guids %u\n",fetched);
        IEnumGUID_Release(pIEnum);
 -
 +      
-       register_testentry();
-       hr = ICatInformation_EnumClassesOfCategories(pICat, 1, the_cat, -1, NULL, 
-                       &pIEnum);
+       if (register_testentry())
+         {
+             hr = ICatInformation_EnumClassesOfCategories(pICat, 1, the_cat, -1, NULL, &pIEnum);
 -            ok_ole_success(hr,"ICatInformation_EnumClassesOfCategories");
 +      ok_ole_success(hr,"ICatInformation_EnumClassesOfCategories");
  
 -            hr = IEnumGUID_Next(pIEnum,1,the_guid, &fetched);
 -            ok (fetched == 1,"Fetched wrong number of guids %u\n",fetched);
 -            ok (IsEqualGUID(the_guid,&wanted_guid),"Guids do not match\n");
 +      hr = IEnumGUID_Next(pIEnum,1,the_guid, &fetched);
 +      ok (fetched == 1,"Fetched wrong number of guids %u\n",fetched);
 +      ok (IsEqualGUID(the_guid,&wanted_guid),"Guids do not match\n");
  
 -            IEnumGUID_Release(pIEnum);
 -            unregister_testentry();
 +      IEnumGUID_Release(pIEnum);
-       ICatInformation_Release(pICat);
 +      unregister_testentry();
+         }
+         else skip( "Could not register the test category\n" );
+       ICatInformation_Release(pICat);
  
        OleUninitialize();
  }
@@@ -1005,18 -1006,24 +1006,24 @@@ static void test_hdm_filterMessages(HWN
      hChild = create_custom_header_control(hParent, TRUE);
      assert(hChild);
      ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
-                                     "adder header control to parent", TRUE);
+                                     "adder header control to parent", FALSE);
+     timeout = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100);
+     SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, timeout);
  
      flush_sequences(sequences, NUM_MSG_SEQUENCES);
-     todo_wine
-     {
 -    /* msdn incorrectly states that return value
 -     * is the index of the filter control being
 -     * modified. The sendMessage here should
 -     * return previous filter timeout value
 +     /* msdn incorrectly states that return value
 +      * is the index of the filter control being
 +      * modified. The sendMessage here should
 +      * return previous filter timeout value
       */
 -    retVal = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100);
-         expect(1000, retVal);
 +        retVal = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100);
+     expect(timeout, retVal);
+     todo_wine
+     {
          retVal = SendMessage(hChild, HDM_CLEARFILTER, 0, 1);
          expect(1, retVal);
          retVal = SendMessage(hChild, HDM_EDITFILTER, 1, 0);
  #include "wine/test.h"
  #include "msg.h"
  
 -#define PARENT_SEQ_INDEX       0
 +#define PARENT_SEQ_INDEX    0
- #define LISTVIEW_SEQ_INDEX  1
- #define NUM_MSG_SEQUENCES   2
+ #define PARENT_FULL_SEQ_INDEX  1
+ #define LISTVIEW_SEQ_INDEX     2
+ #define NUM_MSG_SEQUENCES      3
  
  #define LISTVIEW_ID 0
  #define HEADER_ID   1
@@@ -1205,6 -1552,520 +1552,520 @@@ static void test_multiselect(void
          SetKeyboardState(kstate);
      }
      DestroyWindow(hwnd);
 -    }
+     /* make multiple selection, then switch to LVS_SINGLESEL */
+     hwnd = create_listview_control(0);
+     for (i=0;i<items;i++) {
+           insert_item(hwnd, 0);
++}
+     item_count = (int)SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
+     expect(items,item_count);
+     /* deselect all items */
+     ListView_SetItemState(hwnd, -1, 0, LVIS_SELECTED);
+     SendMessage(hwnd, LVM_SETSELECTIONMARK, 0, -1);
+     for (i=0;i<3;i++) {
+         ListView_SetItemState(hwnd, i, LVIS_SELECTED, LVIS_SELECTED);
+     }
+     r = SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(3, r);
+     r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+ todo_wine
+     expect(-1, r);
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(!(style & LVS_SINGLESEL), "LVS_SINGLESEL isn't expected\n");
+     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SINGLESEL);
+     /* check that style is accepted */
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(style & LVS_SINGLESEL, "LVS_SINGLESEL expected\n");
+     for (i=0;i<3;i++) {
+         r = ListView_GetItemState(hwnd, i, LVIS_SELECTED);
+         ok(r & LVIS_SELECTED, "Expected item %d to be selected\n", i);
+     }
+     r = SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(3, r);
+     SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+     expect(3, r);
+     /* select one more */
+     ListView_SetItemState(hwnd, 3, LVIS_SELECTED, LVIS_SELECTED);
+     for (i=0;i<3;i++) {
+         r = ListView_GetItemState(hwnd, i, LVIS_SELECTED);
+         ok(!(r & LVIS_SELECTED), "Expected item %d to be unselected\n", i);
+     }
+     r = ListView_GetItemState(hwnd, 3, LVIS_SELECTED);
+     ok(r & LVIS_SELECTED, "Expected item %d to be selected\n", i);
+     r = SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(1, r);
+     r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+ todo_wine
+     expect(-1, r);
+     DestroyWindow(hwnd);
+ }
+ static void test_subitem_rect(void)
+ {
+     HWND hwnd;
+     DWORD r;
+     LVCOLUMN col;
+     RECT rect;
+     /* test LVM_GETSUBITEMRECT for header */
+     hwnd = create_listview_control(0);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     /* add some columns */
+     memset(&col, 0, sizeof(LVCOLUMN));
+     col.mask = LVCF_WIDTH;
+     col.cx = 100;
+     r = -1;
+     r = SendMessage(hwnd, LVM_INSERTCOLUMN, 0, (LPARAM)&col);
+     expect(0, r);
+     col.cx = 150;
+     r = -1;
+     r = SendMessage(hwnd, LVM_INSERTCOLUMN, 1, (LPARAM)&col);
+     expect(1, r);
+     col.cx = 200;
+     r = -1;
+     r = SendMessage(hwnd, LVM_INSERTCOLUMN, 2, (LPARAM)&col);
+     expect(2, r);
+     /* item = -1 means header, subitem index is 1 based */
+     rect.left = LVIR_BOUNDS;
+     rect.top  = 0;
+     rect.right = rect.bottom = 0;
+     r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
+     expect(0, r);
+     rect.left = LVIR_BOUNDS;
+     rect.top  = 1;
+     rect.right = rect.bottom = 0;
+     r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
+     ok(r != 0, "Expected not-null LRESULT\n");
+     expect(100, rect.left);
+     expect(250, rect.right);
+ todo_wine
+     expect(3, rect.top);
+     rect.left = LVIR_BOUNDS;
+     rect.top  = 2;
+     rect.right = rect.bottom = 0;
+     r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
+     ok(r != 0, "Expected not-null LRESULT\n");
+     expect(250, rect.left);
+     expect(450, rect.right);
+ todo_wine
+     expect(3, rect.top);
+     DestroyWindow(hwnd);
+     /* try it for non LVS_REPORT style */
+     hwnd = CreateWindow("SysListView32", "Test", LVS_ICON, 0, 0, 100, 100, NULL, NULL,
+                          GetModuleHandle(NULL), 0);
+     rect.left = LVIR_BOUNDS;
+     rect.top  = 1;
+     rect.right = rect.bottom = -10;
+     r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect);
+     ok(r == 0, "Expected not-null LRESULT\n");
+     /* rect is unchanged */
+     expect(0, rect.left);
+     expect(-10, rect.right);
+     expect(1, rect.top);
+     expect(-10, rect.bottom);
+     DestroyWindow(hwnd);
+ }
+ /* comparison callback for test_sorting */
+ static INT WINAPI test_CallBackCompare(LPARAM first, LPARAM second, LPARAM lParam)
+ {
+     if (first == second) return 0;
+     return (first > second ? 1 : -1);
+ }
+ static void test_sorting(void)
+ {
+     HWND hwnd;
+     LVITEMA item = {0};
+     DWORD r;
+     LONG_PTR style;
+     static CHAR names[][5] = {"A", "B", "C", "D", "0"};
+     CHAR buff[10];
+     hwnd = create_listview_control(0);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     /* insert some items */
+     item.mask = LVIF_PARAM | LVIF_STATE;
+     item.state = LVIS_SELECTED;
+     item.iItem = 0;
+     item.iSubItem = 0;
+     item.lParam = 3;
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(0, r);
+     item.mask = LVIF_PARAM;
+     item.iItem = 1;
+     item.iSubItem = 0;
+     item.lParam = 2;
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(1, r);
+     item.mask = LVIF_STATE | LVIF_PARAM;
+     item.state = LVIS_SELECTED;
+     item.iItem = 2;
+     item.iSubItem = 0;
+     item.lParam = 4;
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(2, r);
+     r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+     expect(-1, r);
+     r = SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(2, r);
+     r = SendMessage(hwnd, LVM_SORTITEMS, 0, (LPARAM)test_CallBackCompare);
+     expect(TRUE, r);
+     r = SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(2, r);
+     r = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
+     expect(-1, r);
+     r = SendMessage(hwnd, LVM_GETITEMSTATE, 0, LVIS_SELECTED);
+     expect(0, r);
+     r = SendMessage(hwnd, LVM_GETITEMSTATE, 1, LVIS_SELECTED);
+     expect(LVIS_SELECTED, r);
+     r = SendMessage(hwnd, LVM_GETITEMSTATE, 2, LVIS_SELECTED);
+     expect(LVIS_SELECTED, r);
+     DestroyWindow(hwnd);
+     /* switch to LVS_SORTASCENDING when some items added */
+     hwnd = create_listview_control(0);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     item.mask = LVIF_TEXT;
+     item.iItem = 0;
+     item.iSubItem = 0;
+     item.pszText = names[1];
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(0, r);
+     item.mask = LVIF_TEXT;
+     item.iItem = 1;
+     item.iSubItem = 0;
+     item.pszText = names[2];
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(1, r);
+     item.mask = LVIF_TEXT;
+     item.iItem = 2;
+     item.iSubItem = 0;
+     item.pszText = names[0];
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(2, r);
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_SORTASCENDING);
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(style & LVS_SORTASCENDING, "Expected LVS_SORTASCENDING to be set\n");
+     /* no sorting performed when switched to LVS_SORTASCENDING */
+     item.mask = LVIF_TEXT;
+     item.iItem = 0;
+     item.pszText = buff;
+     item.cchTextMax = sizeof(buff);
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[1]) == 0, "Expected '%s', got '%s'\n", names[1], buff);
+     item.iItem = 1;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[2]) == 0, "Expected '%s', got '%s'\n", names[2], buff);
+     item.iItem = 2;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[0]) == 0, "Expected '%s', got '%s'\n", names[0], buff);
+     /* adding new item doesn't resort list */
+     item.mask = LVIF_TEXT;
+     item.iItem = 3;
+     item.iSubItem = 0;
+     item.pszText = names[3];
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(3, r);
+     item.mask = LVIF_TEXT;
+     item.iItem = 0;
+     item.pszText = buff;
+     item.cchTextMax = sizeof(buff);
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[1]) == 0, "Expected '%s', got '%s'\n", names[1], buff);
+     item.iItem = 1;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[2]) == 0, "Expected '%s', got '%s'\n", names[2], buff);
+     item.iItem = 2;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[0]) == 0, "Expected '%s', got '%s'\n", names[0], buff);
+     item.iItem = 3;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[3]) == 0, "Expected '%s', got '%s'\n", names[3], buff);
+     /* corner case - item should be placed at first position */
+     item.mask = LVIF_TEXT;
+     item.iItem = 4;
+     item.iSubItem = 0;
+     item.pszText = names[4];
+     r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
+     expect(0, r);
+     item.iItem = 0;
+     item.pszText = buff;
+     item.cchTextMax = sizeof(buff);
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[4]) == 0, "Expected '%s', got '%s'\n", names[4], buff);
+     item.iItem = 1;
+     item.pszText = buff;
+     item.cchTextMax = sizeof(buff);
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[1]) == 0, "Expected '%s', got '%s'\n", names[1], buff);
+     item.iItem = 2;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[2]) == 0, "Expected '%s', got '%s'\n", names[2], buff);
+     item.iItem = 3;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[0]) == 0, "Expected '%s', got '%s'\n", names[0], buff);
+     item.iItem = 4;
+     r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
+     expect(TRUE, r);
+     ok(lstrcmp(buff, names[3]) == 0, "Expected '%s', got '%s'\n", names[3], buff);
+     DestroyWindow(hwnd);
+ }
+ static void test_ownerdata(void)
+ {
+     HWND hwnd;
+     LONG_PTR style, ret;
+     DWORD res;
+     LVITEMA item;
+     /* it isn't possible to set LVS_OWNERDATA after creation */
+     hwnd = create_listview_control(0);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(!(style & LVS_OWNERDATA) && style, "LVS_OWNERDATA isn't expected\n");
+     flush_sequences(sequences, NUM_MSG_SEQUENCES);
+     ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA);
+     ok(ret == style, "Expected set GWL_STYLE to succeed\n");
+     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
+                 "try to switch to LVS_OWNERDATA seq", FALSE);
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(!(style & LVS_OWNERDATA), "LVS_OWNERDATA isn't expected\n");
+     DestroyWindow(hwnd);
+     /* try to set LVS_OWNERDATA after creation just having it */
+     hwnd = create_listview_control(LVS_OWNERDATA);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
+     flush_sequences(sequences, NUM_MSG_SEQUENCES);
+     ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style | LVS_OWNERDATA);
+     ok(ret == style, "Expected set GWL_STYLE to succeed\n");
+     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
+                 "try to switch to LVS_OWNERDATA seq", FALSE);
+     DestroyWindow(hwnd);
+     /* try to remove LVS_OWNERDATA after creation just having it */
+     hwnd = create_listview_control(LVS_OWNERDATA);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
+     flush_sequences(sequences, NUM_MSG_SEQUENCES);
+     ret = SetWindowLongPtrA(hwnd, GWL_STYLE, style & ~LVS_OWNERDATA);
+     ok(ret == style, "Expected set GWL_STYLE to succeed\n");
+     ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_ownerdata_switchto_seq,
+                 "try to switch to LVS_OWNERDATA seq", FALSE);
+     style = GetWindowLongPtrA(hwnd, GWL_STYLE);
+     ok(style & LVS_OWNERDATA, "LVS_OWNERDATA is expected\n");
+     DestroyWindow(hwnd);
+     /* try select an item */
+     hwnd = create_listview_control(LVS_OWNERDATA);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
+     ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n");
+     res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(0, res);
+     memset(&item, 0, sizeof(item));
+     item.stateMask = LVIS_SELECTED;
+     item.state     = LVIS_SELECTED;
+     res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
+     expect(TRUE, res);
+     res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
+     expect(1, res);
+     res = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
+     expect(1, res);
+     DestroyWindow(hwnd);
+     /* LVM_SETITEM is unsupported on LVS_OWNERDATA */
+     hwnd = create_listview_control(LVS_OWNERDATA);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
+     ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n");
+     res = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0);
+     expect(1, res);
+     memset(&item, 0, sizeof(item));
+     item.mask = LVIF_STATE;
+     item.iItem = 0;
+     item.stateMask = LVIS_SELECTED;
+     item.state     = LVIS_SELECTED;
+     res = SendMessageA(hwnd, LVM_SETITEM, 0, (LPARAM)&item);
+     expect(FALSE, res);
+     DestroyWindow(hwnd);
+ }
+ static void test_norecompute(void)
+ {
+     static CHAR testA[] = "test";
+     CHAR buff[10];
+     LVITEMA item;
+     HWND hwnd;
+     DWORD res;
+     /* self containing control */
+     hwnd = create_listview_control(0);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     memset(&item, 0, sizeof(item));
+     item.mask = LVIF_TEXT | LVIF_STATE;
+     item.iItem = 0;
+     item.stateMask = LVIS_SELECTED;
+     item.state     = LVIS_SELECTED;
+     item.pszText   = testA;
+     res = SendMessageA(hwnd, LVM_INSERTITEM, 0, (LPARAM)&item);
+     expect(0, res);
+     /* retrieve with LVIF_NORECOMPUTE */
+     item.mask  = LVIF_TEXT | LVIF_NORECOMPUTE;
+     item.iItem = 0;
+     item.pszText    = buff;
+     item.cchTextMax = sizeof(buff)/sizeof(CHAR);
+     res = SendMessageA(hwnd, LVM_GETITEM, 0, (LPARAM)&item);
+     expect(TRUE, res);
+     ok(lstrcmp(buff, testA) == 0, "Expected (%s), got (%s)\n", testA, buff);
+     item.mask = LVIF_TEXT;
+     item.iItem = 1;
+     item.pszText = LPSTR_TEXTCALLBACK;
+     res = SendMessageA(hwnd, LVM_INSERTITEM, 0, (LPARAM)&item);
+     expect(1, res);
+     item.mask  = LVIF_TEXT | LVIF_NORECOMPUTE;
+     item.iItem = 1;
+     item.pszText    = buff;
+     item.cchTextMax = sizeof(buff)/sizeof(CHAR);
+     flush_sequences(sequences, NUM_MSG_SEQUENCES);
+     res = SendMessageA(hwnd, LVM_GETITEM, 0, (LPARAM)&item);
+     expect(TRUE, res);
+     ok(item.pszText == LPSTR_TEXTCALLBACK, "Expected (%p), got (%p)\n",
+        LPSTR_TEXTCALLBACK, (VOID*)item.pszText);
+     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "retrieve with LVIF_NORECOMPUTE seq", FALSE);
+     DestroyWindow(hwnd);
+     /* LVS_OWNERDATA */
+     hwnd = create_listview_control(LVS_OWNERDATA);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     item.mask = LVIF_STATE;
+     item.stateMask = LVIS_SELECTED;
+     item.state     = LVIS_SELECTED;
+     item.iItem = 0;
+     res = SendMessageA(hwnd, LVM_INSERTITEM, 0, (LPARAM)&item);
+     expect(0, res);
+     item.mask  = LVIF_TEXT | LVIF_NORECOMPUTE;
+     item.iItem = 0;
+     item.pszText    = buff;
+     item.cchTextMax = sizeof(buff)/sizeof(CHAR);
+     flush_sequences(sequences, NUM_MSG_SEQUENCES);
+     res = SendMessageA(hwnd, LVM_GETITEM, 0, (LPARAM)&item);
+     expect(TRUE, res);
+     ok(item.pszText == LPSTR_TEXTCALLBACK, "Expected (%p), got (%p)\n",
+        LPSTR_TEXTCALLBACK, (VOID*)item.pszText);
+     ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "retrieve with LVIF_NORECOMPUTE seq 2", FALSE);
+     DestroyWindow(hwnd);
+ }
+ static void test_nosortheader(void)
+ {
+     HWND hwnd, header;
+     LONG_PTR style;
+     hwnd = create_listview_control(0);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
+     ok(IsWindow(header), "header expected\n");
+     style = GetWindowLongPtr(header, GWL_STYLE);
+     ok(style & HDS_BUTTONS, "expected header to have HDS_BUTTONS\n");
+     style = GetWindowLongPtr(hwnd, GWL_STYLE);
+     SetWindowLongPtr(hwnd, GWL_STYLE, style | LVS_NOSORTHEADER);
+     /* HDS_BUTTONS retained */
+     style = GetWindowLongPtr(header, GWL_STYLE);
+     ok(style & HDS_BUTTONS, "expected header to retain HDS_BUTTONS\n");
+     DestroyWindow(hwnd);
+     /* create with LVS_NOSORTHEADER */
+     hwnd = create_listview_control(LVS_NOSORTHEADER);
+     ok(hwnd != NULL, "failed to create a listview window\n");
+     header = (HWND)SendMessageA(hwnd, LVM_GETHEADER, 0, 0);
+     ok(IsWindow(header), "header expected\n");
+     style = GetWindowLongPtr(header, GWL_STYLE);
+     ok(!(style & HDS_BUTTONS), "expected header to have no HDS_BUTTONS\n");
+     style = GetWindowLongPtr(hwnd, GWL_STYLE);
+     SetWindowLongPtr(hwnd, GWL_STYLE, style & ~LVS_NOSORTHEADER);
+     /* not changed here */
+     style = GetWindowLongPtr(header, GWL_STYLE);
+     ok(!(style & HDS_BUTTONS), "expected header to have no HDS_BUTTONS\n");
+     DestroyWindow(hwnd);
  }
  
  START_TEST(listview)
@@@ -905,6 -875,27 +875,27 @@@ static void test_monthcal_HitTest(HWND 
      todo_wine {expect(MCHT_TODAYLINK, res);}
  
      ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_hit_test_seq, "monthcal hit test", TRUE);
 -        }
+     /* The horizontal position of title bar elements depends on locale (y pos
+        is constant), so we sample across a horizontal line and make sure we
+        find all elements. */
+     mchit.pt.y = 40;
+     title_index = 0;
+     for (x = 0; x < 300; x++){
+         mchit.pt.x = x;
+         res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM) & mchit);
+         expect(x, mchit.pt.x);
+         expect(40, mchit.pt.y);
+         expect(mchit.uHit, res);
+         if (res != title_hits[title_index]){
+             title_index++;
+             if (sizeof(title_hits) / sizeof(title_hits[0]) <= title_index)
+                 break;
+             todo_wine {expect(title_hits[title_index], res);}
++}
+     }
+     todo_wine {ok(300 <= x && title_index + 1 == sizeof(title_hits) / sizeof(title_hits[0]),
+         "Wrong title layout\n");}
  }
  
  static void test_monthcal_todaylink(HWND hwnd)
Simple merge
@@@ -112,17 -320,13 +320,13 @@@ static void test_status_control(void
      expect(11,LOWORD(r));
      expect(0,HIWORD(r));
      r = SendMessage(hWndStatus, SB_GETTEXT, 1, (LPARAM) charArray);
-     todo_wine
-     {
-         ok(strcmp(charArray,"InvalidChars\\7 ") == 0, "Expected InvalidChars\\7 , got %s\n", charArray);
-     }
-     expect(15,LOWORD(r));
+     ok(strcmp(charArray,"Invalid\tChars\\7 ") == 0, "Expected Invalid\tChars\\7 , got %s\n", charArray);
+     expect(16,LOWORD(r));
      expect(0,HIWORD(r));
      r = SendMessage(hWndStatus, SB_GETTEXT, 2, (LPARAM) charArray);
-     todo_wine
-     {
 -    ok(strcmp(charArray,"InvalidChars\\n ") == 0, "Expected InvalidChars\\n , got %s\n", charArray);
 +        ok(strcmp(charArray,"InvalidChars\\n ") == 0, "Expected InvalidChars\\n , got %s\n", charArray);
-     }
      expect(15,LOWORD(r));
      expect(0,HIWORD(r));
  
@@@ -756,12 -778,10 +778,10 @@@ static void test_getters_setters(HWND p
          /* Testing Flat Separators */
          extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
          prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS);
 -        expect(extendedStyle, prevExtendedStyle);
 +            expect(extendedStyle, prevExtendedStyle);
  
          extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
-         todo_wine{
 -        expect(TCS_EX_FLATSEPARATORS, extendedStyle);
 +            expect(TCS_EX_FLATSEPARATORS, extendedStyle);
-         }
  
          /* Testing Register Drop */
          prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_REGISTERDROP);
Simple merge
@@@ -579,9 -588,7 +588,7 @@@ static void test_page_size(HWND hWndTra
  
      /* test TBM_GETPAGESIZE */
      r = SendMessage(hWndTrackbar, TBM_GETPAGESIZE, 0,0);
-     todo_wine{
 -    expect(20, r);
 +        expect(20, r);
-     }
  
      ok_sequence(sequences, TRACKBAR_SEQ_INDEX, page_size_test_seq, "page size test sequence", FALSE);
      ok_sequence(sequences, PARENT_SEQ_INDEX, parent_empty_test_seq, "parent page size test sequence", FALSE);
@@@ -820,13 -852,9 +852,9 @@@ static void test_tic_placement(HWND hWn
  
      /* test TBM_GETTICPIC */
      r = SendMessage(hWndTrackbar, TBM_GETTICPOS, 0, 0);
-     todo_wine{
 -    ok(r > 0, "Expected r > 0, got %d\n", r);
 +        ok(r > 0, "Expected r > 0, got %d\n", r);
-         r = SendMessage(hWndTrackbar, TBM_GETTICPOS, 4, 0);
+     r = SendMessage(hWndTrackbar, TBM_GETTICPOS, 2, 0);
 -    ok(r > 0, "Expected r > 0, got %d\n", r);
 +        ok(r > 0, "Expected r > 0, got %d\n", r);
-     }
  
      ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_placement_test_seq, "get tic placement test sequence", FALSE);
      ok_sequence(sequences, PARENT_SEQ_INDEX, parent_empty_test_seq, "parent get tic placement test sequence", FALSE);
@@@ -331,11 -427,9 +427,9 @@@ static void TestGetSetBkColor(void
  {
      COLORREF crColor = RGB(0,0,0);
  
-     todo_wine{
 -    /* If the value is -1, the control is using the system color for the background color. */
 -    crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 );
 -    ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor);
 +        /* If the value is -1, the control is using the system color for the background color. */
 +        crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 );
 +        ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor);
-     }
  
      /* Test for black background */
      SendMessage( hTree, TVM_SETBKCOLOR, 0, (LPARAM)RGB(0,0,0) );
@@@ -628,6 -722,13 +722,13 @@@ static LRESULT CALLBACK MyWndProc(HWND 
                  IdentifyItem(pTreeView->itemOld.hItem);
                  IdentifyItem(pTreeView->itemNew.hItem);
                  return 0;
 -                }
+             case TVN_GETDISPINFOA: {
+                 NMTVDISPINFOA *disp = (NMTVDISPINFOA *)lParam;
+                 if (disp->item.mask & TVIF_TEXT) {
+                     lstrcpyn(disp->item.pszText, TEST_CALLBACK_TEXT, disp->item.cchTextMax);
 -              }
++            }
+                 return 0;
++        }
              }
          }
          return 0;
@@@ -113,7 -116,14 +116,14 @@@ static void test_bitmap_info(HBITMAP hb
      ok(ret == 0, "%d != 0\n", ret);
  
      ret = GetObject(hbm, 1, &bm);
-     ok(ret == 0, "%d != 0\n", ret);
+     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
+     /* Don't trust Win9x not to try to write to NULL */
+     if (ret == 0)
+     {
+         ret = GetObject(hbm, 0, NULL);
+         ok(ret == sizeof(bm), "wrong size %d\n", ret);
 -    }
++}
  }
  
  static void test_createdibitmap(void)
      bmih.biPlanes = 1;
      bmih.biBitCount = 32;
      bmih.biCompression = BI_RGB;
 -
 + 
+     hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
+     ok(hbm == NULL, "CreateDIBitmap should fail\n");
+     hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
+     ok(hbm == NULL, "CreateDIBitmap should fail\n");
      /* First create an un-initialised bitmap.  The depth of the bitmap
         should match that of the hdc and not that supplied in bmih.
      */
@@@ -993,9 -1089,12 +1089,12 @@@ static void test_bitmap(void
  
      SetLastError(0xdeadbeef);
      hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
-     ok(!hbmp, "CreateBitmap should fail\n");
+     ok(!hbmp || broken(hbmp != NULL /* Win9x */), "CreateBitmap should fail\n");
+     if (!hbmp)
 -        ok(GetLastError() == ERROR_INVALID_PARAMETER,
 -           "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
 +    ok(GetLastError() == ERROR_INVALID_PARAMETER,
 +       "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+     else
+         DeleteObject(hbmp);
  
      hbmp = CreateBitmap(15, 15, 1, 1, NULL);
      assert(hbmp != NULL);
@@@ -1168,10 -1272,7 +1272,7 @@@ static void test_GetDIBits_selected_DIB
              break;
          }
      }
-     if (bpp != 1)
 -    ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
 +        ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
-     else
-         todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
  
      HeapFree(GetProcessHeap(), 0, bits2);
      DeleteDC(dc);
@@@ -1675,23 -1851,30 +1851,30 @@@ static void test_GetDIBits_BI_BITFIELDS
          memset(dibinfo, 0, sizeof(dibinfo_buf));
          dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
+         SetLastError(0xdeadbeef);
          ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
+         if (ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
+             win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
+         else
+         {
+             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
  
 -            ok( !bitmasks[0], "red mask is set\n" );
 -            ok( !bitmasks[1], "green mask is set\n" );
 -            ok( !bitmasks[2], "blue mask is set\n" );
 -            ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
 +        ok( !bitmasks[0], "red mask is set\n" );
 +        ok( !bitmasks[1], "green mask is set\n" );
 +        ok( !bitmasks[2], "blue mask is set\n" );
 +        ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
  
 -            memset(bitmasks, 0, 3*sizeof(DWORD));
 -            dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
 -            ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
 -            ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
 +        memset(bitmasks, 0, 3*sizeof(DWORD));
 +        dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
 +        ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
 +        ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
  
 -            ok( bitmasks[0] != 0, "red mask is not set\n" );
 -            ok( bitmasks[1] != 0, "green mask is not set\n" );
 -            ok( bitmasks[2] != 0, "blue mask is not set\n" );
 -            ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
 -        }
 +        ok( bitmasks[0] != 0, "red mask is not set\n" );
 +        ok( bitmasks[1] != 0, "green mask is not set\n" );
 +        ok( bitmasks[2] != 0, "blue mask is not set\n" );
 +        ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
 +    }
+     }
      else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
  
      DeleteObject(hbm);
@@@ -234,9 -240,14 +240,14 @@@ if (0) /* crashes under Win9x *
  
      SetLastError(0xdeadbeef);
      hrgn = ExtCreateRegion(NULL, 1, &rgn.data);
-     ok(hrgn != 0, "ExtCreateRegion error %u\n", GetLastError());
+     ok(hrgn != 0 ||
+        broken(GetLastError() == 0xdeadbeef), /* NT4 */
+        "ExtCreateRegion error %u\n", GetLastError());
+     if(hrgn)
+     {
 -        verify_region(hrgn, &rc);
 -        DeleteObject(hrgn);
 +    verify_region(hrgn, &rc);
 +    DeleteObject(hrgn);
+     }
  
      xform.eM11 = 0.5; /* 50% width */
      xform.eM12 = 0.0;
@@@ -263,10 -355,16 +355,16 @@@ static void test_bitmap_font(void
        hfont = create_font("fractional", &bitmap_lf);
          scale = (i + height_orig - 1) / height_orig;
          nearest_height = scale * height_orig;
-         /* XP allows not more than 10% deviation */
-         if (scale > 1 && nearest_height - i > nearest_height / 10) scale--;
+         /* Only jump to the next height if the difference <= 25% original height */
+         if (scale > 2 && nearest_height - i > height_orig / 4) scale--;
+         /* The jump between unscaled and doubled is delayed by 1 in winnt+ but not in win9x,
+            so we'll not test this particular height. */
+         else if(scale == 2 && nearest_height - i == (height_orig / 4)) continue;
+         else if(scale == 2 && nearest_height - i > (height_orig / 4 - 1)) scale--;
+         old_hfont = SelectObject(hdc, hfont);
          test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, scale);
 -        DeleteObject(hfont);
+         SelectObject(hdc, old_hfont);
 +      DeleteObject(hfont);
      }
  
      /* test integer scaling 3x2 */
@@@ -404,22 -807,22 +807,22 @@@ static void test_bitmap_font_metrics(vo
              hfont = create_font(lf.lfFaceName, &lf);
              old_hfont = SelectObject(hdc, hfont);
              ok(GetTextMetrics(hdc, &tm), "GetTextMetrics error %d\n", GetLastError());
+             if(fd[i].dpi == tm.tmDigitizedAspectX)
+             {
+                 trace("found font %s, height %d charset %x dpi %d\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet, fd[i].dpi);
 -                ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %d != %d\n", fd[i].face_name, fd[i].height, tm.tmWeight, fd[i].weight);
 -                ok(tm.tmHeight == fd[i].height, "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].height, tm.tmHeight, fd[i].height);
 -                ok(tm.tmAscent == fd[i].ascent, "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].height, tm.tmAscent, fd[i].ascent);
 -                ok(tm.tmDescent == fd[i].descent, "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].height, tm.tmDescent, fd[i].descent);
 -                ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].height, tm.tmInternalLeading, fd[i].int_leading);
 -                ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %d != %d\n", fd[i].face_name, fd[i].height, tm.tmExternalLeading, fd[i].ext_leading);
 -                ok(tm.tmAveCharWidth == fd[i].ave_char_width, "%s(%d): tm.tmAveCharWidth %d != %d\n", fd[i].face_name, fd[i].height, tm.tmAveCharWidth, fd[i].ave_char_width);
 -
 -                /* Don't run the max char width test on System/ANSI_CHARSET.  We have extra characters in our font
 -                   that make the max width bigger */
 -                if(strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
 -                    ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, fd[i].height, tm.tmMaxCharWidth, fd[i].max_char_width);
 +            ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %d != %d\n", fd[i].face_name, fd[i].height, tm.tmWeight, fd[i].weight);
 +            ok(tm.tmHeight == fd[i].height, "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].height, tm.tmHeight, fd[i].height);
 +            ok(tm.tmAscent == fd[i].ascent, "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].height, tm.tmAscent, fd[i].ascent);
 +            ok(tm.tmDescent == fd[i].descent, "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].height, tm.tmDescent, fd[i].descent);
 +            ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].height, tm.tmInternalLeading, fd[i].int_leading);
 +            ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %d != %d\n", fd[i].face_name, fd[i].height, tm.tmExternalLeading, fd[i].ext_leading);
 +            ok(tm.tmAveCharWidth == fd[i].ave_char_width, "%s(%d): tm.tmAveCharWidth %d != %d\n", fd[i].face_name, fd[i].height, tm.tmAveCharWidth, fd[i].ave_char_width);
 +
 +            /* Don't run the max char width test on System/ANSI_CHARSET.  We have extra characters in our font
 +               that make the max width bigger */
 +            if(strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
 +                ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, fd[i].height, tm.tmMaxCharWidth, fd[i].max_char_width);
+             }
              SelectObject(hdc, old_hfont);
              DeleteObject(hfont);
          }
@@@ -1319,30 -1772,42 +1772,42 @@@ static void test_EnumFontFamilies(cons
       */
      if (!*font_name && font_charset == DEFAULT_CHARSET) /* do it only once */
      {
-         efd.total = 0;
+         /*
+          * Use EnumFontFamiliesW since win98 crashes when the
+          *    second parameter is NULL using EnumFontFamilies
+          */
+         efdw.total = 0;
          SetLastError(0xdeadbeef);
-         ret = EnumFontFamilies(hdc, NULL, arial_enum_proc, (LPARAM)&efd);
-         ok(ret, "EnumFontFamilies error %u\n", GetLastError());
-         get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
+         ret = EnumFontFamiliesW(hdc, NULL, arial_enum_procw, (LPARAM)&efdw);
+         ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesW error %u\n", GetLastError());
+         if(ret)
+         {
+             get_charset_statsW(&efdw, &ansi_charset, &symbol_charset, &russian_charset);
 -            trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
 -                  ansi_charset, symbol_charset, russian_charset);
 +        trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
 +              ansi_charset, symbol_charset, russian_charset);
-         ok(efd.total > 0, "no fonts enumerated: NULL\n");
+             ok(efdw.total > 0, "fonts enumerated: NULL\n");
 -            ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
 -            ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
 +        ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
 +        ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
-         ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
+             ok(russian_charset > 0 ||
+                broken(russian_charset == 0), /* NT4 */
+                "NULL family should enumerate RUSSIAN_CHARSET\n");
+         }
  
-         efd.total = 0;
+         efdw.total = 0;
          SetLastError(0xdeadbeef);
-         ret = EnumFontFamiliesEx(hdc, NULL, arial_enum_proc, (LPARAM)&efd, 0);
-         ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
-         get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
+         ret = EnumFontFamiliesExW(hdc, NULL, arial_enum_procw, (LPARAM)&efdw, 0);
+         ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesExW error %u\n", GetLastError());
+         if(ret)
+         {
+             get_charset_statsW(&efdw, &ansi_charset, &symbol_charset, &russian_charset);
 -            trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
 -                  ansi_charset, symbol_charset, russian_charset);
 +        trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
 +              ansi_charset, symbol_charset, russian_charset);
-         ok(efd.total > 0, "no fonts enumerated: NULL\n");
+             ok(efdw.total > 0, "fonts enumerated: NULL\n");
 -            ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
 -            ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
 -            ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
 -        }
 +        ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
 +        ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
 +        ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
 +    }
+     }
  
      efd.total = 0;
      SetLastError(0xdeadbeef);
@@@ -1659,81 -2328,172 +2328,172 @@@ static void test_text_metrics(const LOG
      ret = GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size);
      ok(ret == size, "GetFontData should return %u not %u\n", size, ret);
  
 -        version = GET_BE_WORD(tt_os2.version);
+     SetLastError(0xdeadbeef);
+     ret = GetTextMetricsA(hdc, &tmA);
+     ok(ret, "GetTextMetricsA error %u\n", GetLastError());
+     if(!get_first_last_from_cmap(hdc, &cmap_first, &cmap_last, &cmap_type))
+     {
+         skip("Unable to retrieve first and last glyphs from cmap\n");
+     }
+     else
+     {
+         USHORT expect_first_A, expect_last_A, expect_break_A, expect_default_A;
+         USHORT expect_first_W, expect_last_W, expect_break_W, expect_default_W;
+         UINT os2_first_char, os2_last_char, default_char, break_char;
+         USHORT version;
+         TEXTMETRICW tmW;
-     trace("OS/2 chunk version %u, vendor %4.4s\n", version, (LPCSTR)&tt_os2.achVendID);
 +    version = GET_BE_WORD(tt_os2.version);
  
-     first_unicode_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
-     last_unicode_char = GET_BE_WORD(tt_os2.usLastCharIndex);
+         os2_first_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
+         os2_last_char = GET_BE_WORD(tt_os2.usLastCharIndex);
 -        default_char = GET_BE_WORD(tt_os2.usDefaultChar);
 -        break_char = GET_BE_WORD(tt_os2.usBreakChar);
 +    default_char = GET_BE_WORD(tt_os2.usDefaultChar);
 +    break_char = GET_BE_WORD(tt_os2.usBreakChar);
  
-     trace("for %s first %x, last %x, default %x, break %x\n", font_name,
-            first_unicode_char, last_unicode_char, default_char, break_char);
+         trace("font %s charset %u: %x-%x (%x-%x) default %x break %x OS/2 version %u vendor %4.4s\n",
+               font_name, lf->lfCharSet, os2_first_char, os2_last_char, cmap_first, cmap_last,
+               default_char, break_char, version, (LPCSTR)&tt_os2.achVendID);
  
-     SetLastError(0xdeadbeef);
-     ret = GetTextMetricsA(hdc, &tmA);
-     ok(ret, "GetTextMetricsA error %u\n", GetLastError());
-     trace("A: first %x, last %x, default %x, break %x\n",
-           tmA.tmFirstChar, tmA.tmLastChar, tmA.tmDefaultChar, tmA.tmBreakChar);
- #if 0 /* FIXME: This doesn't appear to be what Windows does */
-     test_char = min(first_unicode_char - 1, 255);
-     ok(tmA.tmFirstChar == test_char, "A: tmFirstChar for %s %02x != %02x\n",
-        font_name, tmA.tmFirstChar, test_char);
- #endif
-     if (lf->lfCharSet == SYMBOL_CHARSET)
+         if (cmap_type == cmap_ms_symbol || (cmap_first >= 0xf000 && cmap_first < 0xf100))
 -        {
 +    {
-         test_char = min(last_unicode_char - 0xf000, 255);
-         ok(tmA.tmLastChar == test_char, "A: tmLastChar for %s %02x != %02x\n",
-            font_name, tmA.tmLastChar, test_char);
+             expect_first_W    = 0;
+             switch(GetACP())
+             {
+             case 1257:  /* Baltic */
+                 expect_last_W = 0xf8fd;
+                 break;
+             default:
+                 expect_last_W = 0xf0ff;
 -            }
 +    }
+             expect_break_W    = 0x20;
+             expect_default_W  = expect_break_W - 1;
+             expect_first_A    = 0x1e;
+             expect_last_A     = min(os2_last_char - os2_first_char + 0x20, 0xff);
+         }
 -        else
 -        {
 +    else
 +    {
-         test_char = min(last_unicode_char, 255);
-         ok(tmA.tmLastChar == test_char, "A: tmLastChar for %s %02x != %02x\n",
-            font_name, tmA.tmLastChar, test_char);
+             expect_first_W    = cmap_first;
+             expect_last_W     = min(cmap_last, os2_last_char);
+             if(os2_first_char <= 1)
+                 expect_break_W = os2_first_char + 2;
+             else if(os2_first_char > 0xff)
+                 expect_break_W = 0x20;
+             else
+                 expect_break_W = os2_first_char;
+             expect_default_W  = expect_break_W - 1;
+             expect_first_A    = expect_default_W - 1;
+             expect_last_A     = min(expect_last_W, 0xff);
 -        }
 +    }
+         expect_break_A    = expect_break_W;
+         expect_default_A  = expect_default_W;
+         /* Wine currently uses SYMBOL_CHARSET to identify whether the ANSI metrics need special handling */
+         if(cmap_type != cmap_ms_symbol && tmA.tmCharSet == SYMBOL_CHARSET && expect_first_A != 0x1e)
+             todo_wine ok(tmA.tmFirstChar == expect_first_A ||
+                          tmA.tmFirstChar == expect_first_A + 1 /* win9x */,
+                          "A: tmFirstChar for %s got %02x expected %02x\n", font_name, tmA.tmFirstChar, expect_first_A);
+         else
+             ok(tmA.tmFirstChar == expect_first_A ||
+                tmA.tmFirstChar == expect_first_A + 1 /* win9x */,
+                "A: tmFirstChar for %s got %02x expected %02x\n", font_name, tmA.tmFirstChar, expect_first_A);
+         ok(tmA.tmLastChar == expect_last_A ||
+            tmA.tmLastChar == 0xff /* win9x */,
+            "A: tmLastChar for %s got %02x expected %02x\n", font_name, tmA.tmLastChar, expect_last_A);
+         ok(tmA.tmBreakChar == expect_break_A, "A: tmBreakChar for %s got %02x expected %02x\n",
+            font_name, tmA.tmBreakChar, expect_break_A);
+         ok(tmA.tmDefaultChar == expect_default_A, "A: tmDefaultChar for %s got %02x expected %02x\n",
+            font_name, tmA.tmDefaultChar, expect_default_A);
  
 -        SetLastError(0xdeadbeef);
 -        ret = GetTextMetricsW(hdc, &tmW);
 -        ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
 -           "GetTextMetricsW error %u\n", GetLastError());
 -        if (ret)
 -        {
 +    SetLastError(0xdeadbeef);
 +    ret = GetTextMetricsW(hdc, &tmW);
 +    ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
 +       "GetTextMetricsW error %u\n", GetLastError());
 +    if (ret)
 +    {
-         trace("W: first %x, last %x, default %x, break %x\n",
-               tmW.tmFirstChar, tmW.tmLastChar, tmW.tmDefaultChar,
-               tmW.tmBreakChar);
-         if (lf->lfCharSet == SYMBOL_CHARSET)
-         {
-             /* It appears that for fonts with SYMBOL_CHARSET Windows always
-              * sets symbol range to 0 - f0ff
-              */
-             ok(tmW.tmFirstChar == 0, "W: tmFirstChar for %s %02x != 0\n",
-                font_name, tmW.tmFirstChar);
-             /* FIXME: Windows returns f0ff here, while Wine f0xx */
-             ok(tmW.tmLastChar >= 0xf000, "W: tmLastChar for %s %02x < 0xf000\n",
-                font_name, tmW.tmLastChar);
-             ok(tmW.tmDefaultChar == 0x1f, "W: tmDefaultChar for %s %02x != 0x1f\n",
-                font_name, tmW.tmDefaultChar);
-             ok(tmW.tmBreakChar == 0x20, "W: tmBreakChar for %s %02x != 0x20\n",
-                font_name, tmW.tmBreakChar);
-         }
-         else
-         {
-             ok(tmW.tmFirstChar == first_unicode_char, "W: tmFirstChar for %s %02x != %02x\n",
-                font_name, tmW.tmFirstChar, first_unicode_char);
-             ok(tmW.tmLastChar == last_unicode_char, "W: tmLastChar for %s %02x != %02x\n",
-                font_name, tmW.tmLastChar, last_unicode_char);
-         }
+             /* Wine uses the os2 first char */
+             if(cmap_first != os2_first_char && cmap_type != cmap_ms_symbol)
+                 todo_wine ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s got %02x expected %02x\n",
+                              font_name, tmW.tmFirstChar, expect_first_W);
+             else
+                 ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s got %02x expected %02x\n",
+                    font_name, tmW.tmFirstChar, expect_first_W);
+             /* Wine uses the os2 last char */
+             if(expect_last_W != os2_last_char && cmap_type != cmap_ms_symbol)
+                 todo_wine ok(tmW.tmLastChar == expect_last_W, "W: tmLastChar for %s got %02x expected %02x\n",
+                              font_name, tmW.tmLastChar, expect_last_W);
+             else
+                 ok(tmW.tmLastChar == expect_last_W, "W: tmLastChar for %s got %02x expected %02x\n",
+                    font_name, tmW.tmLastChar, expect_last_W);
+             ok(tmW.tmBreakChar == expect_break_W, "W: tmBreakChar for %s got %02x expected %02x\n",
+                font_name, tmW.tmBreakChar, expect_break_W);
+             ok(tmW.tmDefaultChar == expect_default_W, "W: tmDefaultChar for %s got %02x expected %02x\n",
+                font_name, tmW.tmDefaultChar, expect_default_W);
+             /* Test the aspect ratio while we have tmW */
 -            ret = GetDeviceCaps(hdc, LOGPIXELSX);
 -            ok(tmW.tmDigitizedAspectX == ret, "W: tmDigitizedAspectX %u != %u\n",
 -               tmW.tmDigitizedAspectX, ret);
 -            ret = GetDeviceCaps(hdc, LOGPIXELSY);
 -            ok(tmW.tmDigitizedAspectX == ret, "W: tmDigitizedAspectY %u != %u\n",
 -               tmW.tmDigitizedAspectX, ret);
 -        }
 +        ret = GetDeviceCaps(hdc, LOGPIXELSX);
 +        ok(tmW.tmDigitizedAspectX == ret, "W: tmDigitizedAspectX %u != %u\n",
 +           tmW.tmDigitizedAspectX, ret);
 +        ret = GetDeviceCaps(hdc, LOGPIXELSY);
 +        ok(tmW.tmDigitizedAspectX == ret, "W: tmDigitizedAspectY %u != %u\n",
 +           tmW.tmDigitizedAspectX, ret);
 +    }
+     }
+     /* test FF_ values */
+     switch(tt_os2.panose.bFamilyType)
+     {
+     case PAN_ANY:
+     case PAN_NO_FIT:
+     case PAN_FAMILY_TEXT_DISPLAY:
+     case PAN_FAMILY_PICTORIAL:
+     default:
+         if((tmA.tmPitchAndFamily & 1) == 0 || /* fixed */
+            tt_os2.panose.bProportion == PAN_PROP_MONOSPACED)
+         {
+             expect_ff(&tmA, &tt_os2, FF_MODERN, font_name);
+             break;
+         }
+         switch(tt_os2.panose.bSerifStyle)
+         {
+         case PAN_ANY:
+         case PAN_NO_FIT:
+         default:
+             expect_ff(&tmA, &tt_os2, FF_DONTCARE, font_name);
+             break;
+         case PAN_SERIF_COVE:
+         case PAN_SERIF_OBTUSE_COVE:
+         case PAN_SERIF_SQUARE_COVE:
+         case PAN_SERIF_OBTUSE_SQUARE_COVE:
+         case PAN_SERIF_SQUARE:
+         case PAN_SERIF_THIN:
+         case PAN_SERIF_BONE:
+         case PAN_SERIF_EXAGGERATED:
+         case PAN_SERIF_TRIANGLE:
+             expect_ff(&tmA, &tt_os2, FF_ROMAN, font_name);
+             break;
+         case PAN_SERIF_NORMAL_SANS:
+         case PAN_SERIF_OBTUSE_SANS:
+         case PAN_SERIF_PERP_SANS:
+         case PAN_SERIF_FLARED:
+         case PAN_SERIF_ROUNDED:
+             expect_ff(&tmA, &tt_os2, FF_SWISS, font_name);
+             break;
+         }
+         break;
+     case PAN_FAMILY_SCRIPT:
+         expect_ff(&tmA, &tt_os2, FF_SCRIPT, font_name);
+         break;
+     case PAN_FAMILY_DECORATIVE:
+         expect_ff(&tmA, &tt_os2, FF_DECORATIVE, font_name);
+         break;
+     }
  
      test_negative_width(hdc, lf);
  
@@@ -1,28 -1,24 +1,24 @@@
  <?xml version="1.0"?>
  <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
- <group>
  <module name="gdi32_winetest" type="win32cui" installbase="bin" installname="gdi32_winetest.exe" allowwarnings="true">
 -      <include base="gdi32_winetest">.</include>
 +    <include base="gdi32_winetest">.</include>
-     <define name="WINVER">0x0600</define>
-     <define name="__USE_W32API" />
+       <define name="__ROS_LONG64__" />
 -      <library>ntdll</library>
 -      <library>gdi32</library>
 -      <library>user32</library>
 -      <library>advapi32</library>
 -      <file>bitmap.c</file>
 -      <file>brush.c</file>
 -      <file>clipping.c</file>
 -      <file>dc.c</file>
 -      <file>gdiobj.c</file>
 -      <file>generated.c</file>
 -      <file>icm.c</file>
 -      <file>font.c</file>
 -      <file>mapping.c</file>
 -      <file>metafile.c</file>
 -      <file>palette.c</file>
 -      <file>path.c</file>
 -      <file>pen.c</file>
 -      <file>testlist.c</file>
 +    <library>ntdll</library>
 +    <library>gdi32</library>
-     <library>kernel32</library>
 +    <library>user32</library>
 +    <library>advapi32</library>
 +    <file>bitmap.c</file>
 +    <file>brush.c</file>
 +    <file>clipping.c</file>
 +    <file>dc.c</file>
 +    <file>gdiobj.c</file>
 +    <file>generated.c</file>
 +    <file>icm.c</file>
 +    <file>font.c</file>
 +    <file>mapping.c</file>
 +    <file>metafile.c</file>
 +    <file>palette.c</file>
 +    <file>path.c</file>
 +    <file>pen.c</file>
 +    <file>testlist.c</file>
  </module>
- </group>
   * Test helper macros
   */
  
- #ifdef FIELD_ALIGNMENT
- # define TEST_FIELD_ALIGNMENT(type, field, align) \
-    ok(FIELD_ALIGNMENT(type, field) == align, \
-        "FIELD_ALIGNMENT(" #type ", " #field ") == %d (expected " #align ")\n", \
-            (int)FIELD_ALIGNMENT(type, field))
+ #ifdef _WIN64
+ # define TEST_TYPE_SIZE(type, size)
+ # define TEST_TYPE_ALIGN(type, align)
+ # define TEST_TARGET_ALIGN(type, align)
+ # define TEST_FIELD_ALIGN(type, field, align)
+ # define TEST_FIELD_OFFSET(type, field, offset)
  #else
- # define TEST_FIELD_ALIGNMENT(type, field, align) do { } while (0)
- #endif
  
- #define TEST_FIELD_OFFSET(type, field, offset) \
-     ok(FIELD_OFFSET(type, field) == offset, \
-         "FIELD_OFFSET(" #type ", " #field ") == %ld (expected " #offset ")\n", \
-              (long int)FIELD_OFFSET(type, field))
+ # define TEST_TYPE_SIZE(type, size)             C_ASSERT(sizeof(type) == size);
  
- #ifdef _TYPE_ALIGNMENT
- #define TEST__TYPE_ALIGNMENT(type, align) \
-     ok(_TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)_TYPE_ALIGNMENT(type))
+ # ifdef TYPE_ALIGNMENT
+ #  define TEST_TYPE_ALIGN(type, align)          C_ASSERT(TYPE_ALIGNMENT(type) == align);
 -# else
 +#else
- # define TEST__TYPE_ALIGNMENT(type, align) do { } while (0)
+ #  define TEST_TYPE_ALIGN(type, align)
 -# endif
 +#endif
  
- #ifdef TYPE_ALIGNMENT
- #define TEST_TYPE_ALIGNMENT(type, align) \
-     ok(TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)TYPE_ALIGNMENT(type))
+ # ifdef _TYPE_ALIGNMENT
+ #  define TEST_TARGET_ALIGN(type, align)        C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align);
+ #  define TEST_FIELD_ALIGN(type, field, align)  C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align);
 -# else
 +#else
- # define TEST_TYPE_ALIGNMENT(type, align) do { } while (0)
+ #  define TEST_TARGET_ALIGN(type, align)
+ #  define TEST_FIELD_ALIGN(type, field, align)
 -# endif
 +#endif
  
- #define TEST_TYPE_SIZE(type, size) \
-     ok(sizeof(type) == size, "sizeof(" #type ") == %d (expected " #size ")\n", ((int) sizeof(type)))
+ # define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset);
  
- /***********************************************************************
-  * Test macros
-  */
- #define TEST_FIELD(type, field_type, field_name, field_offset, field_size, field_align) \
-   TEST_TYPE_SIZE(field_type, field_size); \
-   TEST_FIELD_ALIGNMENT(type, field_name, field_align); \
-   TEST_FIELD_OFFSET(type, field_name, field_offset); \
- #define TEST_TYPE(type, size, align) \
-   TEST_TYPE_ALIGNMENT(type, align); \
-   TEST_TYPE_SIZE(type, size)
- #define TEST_TYPE_POINTER(type, size, align) \
-     TEST__TYPE_ALIGNMENT(*(type)0, align); \
-     TEST_TYPE_SIZE(*(type)0, size)
+ #endif
  
- #define TEST_TYPE_SIGNED(type) \
-     ok((type) -1 < 0, "(" #type ") -1 < 0\n");
+ #define TEST_TARGET_SIZE(type, size)            TEST_TYPE_SIZE(*(type)0, size)
+ #define TEST_FIELD_SIZE(type, field, size)      TEST_TYPE_SIZE((((type*)0)->field), size)
+ #define TEST_TYPE_SIGNED(type)                  C_ASSERT((type) -1 < 0);
+ #define TEST_TYPE_UNSIGNED(type)                C_ASSERT((type) -1 > 0);
  
- #define TEST_TYPE_UNSIGNED(type) \
-      ok((type) -1 > 0, "(" #type ") -1 > 0\n");
  
  static void test_pack_ABC(void)
  {
@@@ -980,29 -1236,11 +1236,11 @@@ static BOOL match_emf_record(const ENHM
  {
      int diff;
  
-     if (emr1->iType != emr2->iType && todo)
-     {
-         todo_wine
-         {
 -    ok(emr1->iType == emr2->iType, "%s: emr->iType %u != %u\n",
 -       desc, emr1->iType, emr2->iType);
 +            ok(emr1->iType == emr2->iType, "%s: emr->iType %u != %u\n",
 +               desc, emr1->iType, emr2->iType);
-         }
-     }
-     else
-         ok(emr1->iType == emr2->iType, "%s: emr->iType %u != %u\n",
-            desc, emr1->iType, emr2->iType);
  
-     if (emr1->nSize != emr2->nSize && todo)
-     {
-         todo_wine
-         {
 -    ok(emr1->nSize == emr2->nSize, "%s: emr->nSize %u != %u\n",
 -       desc, emr1->nSize, emr2->nSize);
 +            ok(emr1->nSize == emr2->nSize, "%s: emr->nSize %u != %u\n",
 +               desc, emr1->nSize, emr2->nSize);
-         }
-     }
-     else
-         ok(emr1->nSize == emr2->nSize, "%s: emr->nSize %u != %u\n",
-            desc, emr1->nSize, emr2->nSize);
  
      /* iType and nSize mismatches are fatal */
      if (emr1->iType != emr2->iType || emr1->nSize != emr2->nSize) return FALSE;
      /* contents of EMR_GDICOMMENT are not interesting */
      if (emr1->iType == EMR_GDICOMMENT) return TRUE;
  
-     diff = memcmp(emr1->dParm, emr2->dParm, emr1->nSize - sizeof(EMR));
-     if (diff && todo)
+     /* different Windows versions setup DC scaling differently when
+      * converting an old style metafile to an EMF.
+      */
+     if (ignore_scaling && (emr1->iType == EMR_SETWINDOWEXTEX ||
+                            emr1->iType == EMR_SETVIEWPORTEXTEX))
+         return TRUE;
+     if (emr1->iType == EMR_EXTTEXTOUTW || emr1->iType == EMR_EXTTEXTOUTA)
+     {
+         EMREXTTEXTOUTW *eto1, *eto2;
+         eto1 = HeapAlloc(GetProcessHeap(), 0, emr1->nSize);
+         memcpy(eto1, emr1, emr1->nSize);
+         eto2 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
+         memcpy(eto2, emr2, emr2->nSize);
+         /* different Windows versions setup DC scaling differently */
+         eto1->exScale = eto1->eyScale = 0.0;
+         eto2->exScale = eto2->eyScale = 0.0;
+         diff = memcmp(eto1, eto2, emr1->nSize);
+         if (diff)
+         {
+             dump_EMREXTTEXTOUT(eto1);
+             dump_EMREXTTEXTOUT(eto2);
 -        }
++    }
+         HeapFree(GetProcessHeap(), 0, eto1);
+         HeapFree(GetProcessHeap(), 0, eto2);
+     }
+     else if (emr1->iType == EMR_EXTSELECTCLIPRGN && !lstrcmpA(desc, "emf_clipping"))
      {
-         todo_wine
-             ok(diff == 0, "%s: contents of record %u don't match\n", desc, emr1->iType);
+         /* We have to take care of NT4 differences here */
+         diff = memcmp(emr1, emr2, emr1->nSize);
+         if (diff)
+         {
+             ENHMETARECORD *emr_nt4;
+             emr_nt4 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
+             memcpy(emr_nt4, emr2, emr2->nSize);
+             /* Correct the nRgnSize field */
+             emr_nt4->dParm[5] = sizeof(RECT);
+             diff = memcmp(emr1, emr_nt4, emr1->nSize);
+             if (!diff)
+                 win_skip("Catered for NT4 differences\n");
+             HeapFree(GetProcessHeap(), 0, emr_nt4);
+         }
      }
      else
 -    ok(diff == 0, "%s: contents of record %u don't match\n", desc, emr1->iType);
+         diff = memcmp(emr1, emr2, emr1->nSize);
 +        ok(diff == 0, "%s: contents of record %u don't match\n", desc, emr1->iType);
  
      if (diff)
      {
@@@ -1044,17 -1328,18 +1328,18 @@@ static int compare_emf_bits(const HENHM
      mfsize = GetEnhMetaFileBits(mf, MF_BUFSIZE, buf);
      ok (mfsize > 0, "%s: GetEnhMetaFileBits error %d\n", desc, GetLastError());
  
+     /* ENHMETAHEADER size could differ, depending on platform */
+     diff_nt4 = sizeof(SIZEL);
+     diff_9x = sizeof(SIZEL) + 3 * sizeof(DWORD);
      if (mfsize < MF_BUFSIZE)
      {
-         if (mfsize != bsize && todo)
-         {
-         todo_wine
-         ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
+         ok(mfsize == bsize ||
+            broken(mfsize == bsize - diff_nt4) ||  /* NT4 */
+            broken(mfsize == bsize - diff_9x), /* Win9x/WinME */
+            "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
 -    }
 -    else
 +        }
 +        else
-         ok(mfsize == bsize, "%s: mfsize=%d, bsize=%d\n", desc, mfsize, bsize);
-     }
-     else
          ok(bsize >= MF_BUFSIZE, "%s: mfsize > bufsize (%d bytes), bsize=%d\n",
             desc, mfsize, bsize);
  
@@@ -152,33 -186,34 +186,34 @@@ static void test_fontfamily (void
      WCHAR itsName[LF_FACESIZE];
      GpStatus stat;
  
 -    /* FontFamily cannot be NULL */
 +    /* FontFamily can not be NULL */
-     stat = GdipCreateFontFamilyFromName (arial , NULL, family);
+     stat = GdipCreateFontFamilyFromName (arial , NULL, NULL);
      expect (InvalidParameter, stat);
  
-     family = GdipAlloc (sizeof (GpFontFamily*));
      /* FontFamily must be able to actually find the family.
-      * If it can't, any subsequent calls should fail
-      *
-      * We currently fail (meaning we don't) because we don't actually
-      * test to see if we can successfully get a family
+      * If it can't, any subsequent calls should fail.
       */
-     stat = GdipCreateFontFamilyFromName (nonexistant, NULL, family);
+     stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family);
      expect (FontFamilyNotFound, stat);
-     stat = GdipGetFamilyName (*family,itsName, LANG_NEUTRAL);
-     expect (InvalidParameter, stat);
-     ok ((lstrcmpiW(itsName,nonexistant) != 0),
-         "Expected a non-zero value for nonexistant font!\n");
-     stat = GdipDeleteFontFamily(*family);
-     expect (InvalidParameter, stat);
  
-     stat = GdipCreateFontFamilyFromName (arial, NULL, family);
+     /* Bitmap fonts are not found */
+ todo_wine
+ {
+     stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
+     expect (FontFamilyNotFound, stat);
+ }
+     stat = GdipCreateFontFamilyFromName (arial, NULL, &family);
+     if(stat == FontFamilyNotFound)
+     {
+         skip("Arial not installed\n");
+         return;
+     }
      expect (Ok, stat);
  
-     stat = GdipGetFamilyName (*family, itsName, LANG_NEUTRAL);
+     stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
      expect (Ok, stat);
 -    expect (0, lstrcmpiW(itsName, arial));
 +    expect (0, lstrcmpiW(itsName,arial));
  
      if (0)
      {
@@@ -130,12 -132,10 +132,10 @@@ static void test_save_restore(void
      GdipCreateFromHDC(hdc, &graphics1);
      GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
      stat = GdipSaveGraphics(graphics1, &state_a);
-     todo_wine
 -    expect(Ok, stat);
 +        expect(Ok, stat);
      GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
      stat = GdipRestoreGraphics(graphics1, state_a);
-     todo_wine
 -    expect(Ok, stat);
 +        expect(Ok, stat);
      GdipGetInterpolationMode(graphics1, &mode);
      todo_wine
          expect(InterpolationModeBilinear, mode);
      GdipSaveGraphics(graphics1, &state_b);
      GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
      stat = GdipRestoreGraphics(graphics1, 0xdeadbeef);
-     todo_wine
 -    expect(Ok, stat);
 +        expect(Ok, stat);
      GdipRestoreGraphics(graphics1, state_b);
      GdipGetInterpolationMode(graphics1, &mode);
      todo_wine
@@@ -1,13 -1,10 +1,10 @@@
  <?xml version="1.0"?>
  <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
- <group>
  <module name="icmp_winetest" type="win32cui" installbase="bin" installname="icmp_winetest.exe" allowwarnings="true">
 -      <include base="icmp_winetest">.</include>
 +    <include base="icmp_winetest">.</include>
-     <define name="__USE_W32API" />
-     <library>kernel32</library>
+       <define name="__ROS_LONG64__" />
 -      <library>ntdll</library>
 -      <library>icmp</library>
 -      <file>icmp.c</file>
 -      <file>testlist.c</file>
 +    <library>ntdll</library>
 +    <library>icmp</library>
 +    <file>icmp.c</file>
 +    <file>testlist.c</file>
  </module>
- </group>
@@@ -216,8 -225,79 +225,79 @@@ static void test_ImmNotifyIME(void) 
  
      msg_spy_flush_msgs();
      ImmReleaseContext(hwnd, imc);
 -    }
+ }
+ static void test_ImmGetCompositionString(void)
+ {
+     HIMC imc;
+     static const WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
+     char cstring[20];
+     WCHAR wstring[20];
+     DWORD len;
+     DWORD alen,wlen;
+     imc = ImmGetContext(hwnd);
+     ImmSetCompositionStringW(imc, SCS_SETSTR, string, sizeof(string), NULL,0);
+     alen = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, 20);
+     wlen = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, 20);
+     /* windows machines without any IME installed just return 0 above */
+     if( alen && wlen)
+     {
+         len = ImmGetCompositionStringW(imc, GCS_COMPATTR, NULL, 0);
+         ok(len*sizeof(WCHAR)==wlen,"GCS_COMPATTR(W) not returning correct count\n");
+         len = ImmGetCompositionStringA(imc, GCS_COMPATTR, NULL, 0);
+         ok(len==alen,"GCS_COMPATTR(A) not returning correct count\n");
++}
+     ImmReleaseContext(hwnd, imc);
+ }
+ static void test_ImmSetCompositionString(void)
+ {
+     HIMC imc;
+     BOOL ret;
+     SetLastError(0xdeadbeef);
+     imc = ImmGetContext(hwnd);
+     ok(imc != 0, "ImmGetContext() failed. Last error: %u\n", GetLastError());
+     if (!imc)
+         return;
+     ret = ImmSetCompositionStringW(imc, SCS_SETSTR, NULL, 0, NULL, 0);
+     todo_wine
+     ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
+     ret = ImmSetCompositionStringW(imc, SCS_SETSTR | SCS_CHANGEATTR,
+         NULL, 0, NULL, 0);
+     todo_wine
+     ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
+     ret = ImmSetCompositionStringW(imc, SCS_SETSTR | SCS_CHANGECLAUSE,
+         NULL, 0, NULL, 0);
+     todo_wine
+     ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
+     ret = ImmSetCompositionStringW(imc, SCS_CHANGEATTR | SCS_CHANGECLAUSE,
+         NULL, 0, NULL, 0);
+     todo_wine
+     ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
+     ImmReleaseContext(hwnd, imc);
+ }
+ static void test_ImmIME(void)
+ {
+     HIMC imc;
  
-     return 0;
+     imc = ImmGetContext(hwnd);
+     if (imc)
+     {
+         BOOL rc;
+         rc = ImmConfigureIMEA(imc, NULL, IME_CONFIG_REGISTERWORD, NULL);
+         ok (rc == 0, "ImmConfigureIMEA did not fail\n");
+         rc = ImmConfigureIMEW(imc, NULL, IME_CONFIG_REGISTERWORD, NULL);
+         ok (rc == 0, "ImmConfigureIMEW did not fail\n");
+     }
+     ImmReleaseContext(hwnd,imc);
  }
  
  START_TEST(imm32) {
@@@ -682,9 -692,12 +692,12 @@@ static HANDLE test_OpenComm(BOOL doOver
          BOOL ret;
  
          ret = ClearCommError(hcom, &errors, &comstat);
-         if (!ret && GetLastError() == ERROR_NOT_READY)
+         if (!ret && (GetLastError() == ERROR_NOT_READY || GetLastError() == ERROR_INVALID_HANDLE))
          {
 -                trace("%s doesn't respond, skipping the test\n", port_name);
+             if (GetLastError() == ERROR_NOT_READY)
 +            trace("%s doesn't respond, skipping the test\n", port_name);
+             else
+                 trace("%s is not a real serial port, skipping the test\n", port_name);
              CloseHandle(hcom);
              return INVALID_HANDLE_VALUE;
          }
@@@ -324,7 -407,11 +407,11 @@@ static void testWriteWrappedProcessed(H
          okCHAR(hCon, c, mytest[p], TEST_ATTRIB);
      }
      c.X = sbSize.X - 9 + p;
 -        okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
+     ReadConsoleOutputAttribute(hCon, &attr, 1, c, &len);
+     if (attr == TEST_ATTRIB)
+         win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
+     else
 +    okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
      c.X = 0; c.Y++;
      okCHAR(hCon, c, mytest[5], TEST_ATTRIB);
      for (c.X = 1; c.X < 8; c.X++)
      c.X = 0; c.Y++;
      okCHAR(hCon, c, mytest[3], TEST_ATTRIB);
      c.X++;
 -        okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
+     ReadConsoleOutputAttribute(hCon, &attr, 1, c, &len);
+     if (attr == TEST_ATTRIB)
+         win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
+     else
 +    okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
  
      c.X = 0; c.Y++;
      okCHAR(hCon, c, mytest[5], TEST_ATTRIB);
@@@ -156,7 -195,11 +195,11 @@@ static void doDebugger(int argc, char*
      else
          blackbox.debug_rc=TRUE;
  
 -        get_events(logfile, &start_event, &done_event);
+     if (logfile)
+     {
 +    get_events(logfile, &start_event, &done_event);
+     }
      if (strstr(myARGV[2], "order"))
      {
          trace("debugger: waiting for the start signal...\n");
      else
          blackbox.detach_rc=TRUE;
  
 -        save_blackbox(logfile, &blackbox, sizeof(blackbox));
+     if (logfile)
+     {
 +    save_blackbox(logfile, &blackbox, sizeof(blackbox));
+     }
      trace("debugger: done debugging...\n");
      SetEvent(done_event);
  
@@@ -319,22 -370,10 +370,10 @@@ static void test_ExitCode(void
      ret=RegCreateKeyExA(HKEY_LOCAL_MACHINE, AeDebug, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition);
      if (ret == ERROR_SUCCESS)
      {
-         auto_size=0;
-         ret=RegQueryValueExA(hkey, "auto", NULL, &auto_type, NULL, &auto_size);
-         if (ret == ERROR_SUCCESS)
-         {
-             auto_val=HeapAlloc(GetProcessHeap(), 0, auto_size);
-             RegQueryValueExA(hkey, "auto", NULL, &auto_type, auto_val, &auto_size);
+         save_value(hkey, "auto", &auto_value);
+         save_value(hkey, "debugger", &debugger_value);
+         trace("HKLM\\%s\\debugger is set to '%s'\n", AeDebug, debugger_value.data);
 -    }
 +        }
-         debugger_size=0;
-         ret=RegQueryValueExA(hkey, "debugger", NULL, &debugger_type, NULL, &debugger_size);
-         if (ret == ERROR_SUCCESS)
-         {
-             debugger_val=HeapAlloc(GetProcessHeap(), 0, debugger_size);
-             RegQueryValueExA(hkey, "debugger", NULL, &debugger_type, debugger_val, &debugger_size);
-         }
-     }
      else if (ret == ERROR_ACCESS_DENIED)
      {
          skip("not enough privileges to change the debugger\n");
          return;
      }
  
-     if (debugger_val && debugger_type == REG_SZ &&
-         strstr((char*)debugger_val, "winedbg --auto"))
+     if (debugger_value.data && debugger_value.type == REG_SZ &&
+         strstr((char*)debugger_value.data, "winedbg --auto"))
+     {
+         HKEY hkeyWinedbg;
+         ret=RegCreateKeyA(HKEY_CURRENT_USER, WineDbg, &hkeyWinedbg);
+         if (ret == ERROR_SUCCESS)
+         {
+             static DWORD zero;
+             reg_save_value crash_dlg_value;
+             save_value(hkeyWinedbg, "ShowCrashDialog", &crash_dlg_value);
+             RegSetValueExA(hkeyWinedbg, "ShowCrashDialog", 0, REG_DWORD, (BYTE *)&zero, sizeof(DWORD));
 -            crash_and_winedbg(hkey, test_exe);
 +        crash_and_winedbg(hkey, test_exe);
+             restore_value(hkeyWinedbg, &crash_dlg_value);
+             RegCloseKey(hkeyWinedbg);
+         }
+         else
+             ok(0, "Couldn't access WineDbg Key - error %u\n", ret);
+     }
  
 -        crash_and_debug(hkey, test_exe, "dbg,none");
+     if (winetest_interactive)
+         /* Since the debugging process never sets the debug event, it isn't recognized
+            as a valid debugger and, after the debugger exits, Windows will show a dialog box
+            asking the user what to do */
 +    crash_and_debug(hkey, test_exe, "dbg,none");
+     else
+         skip("\"none\" debugger test needs user interaction\n");
      crash_and_debug(hkey, test_exe, "dbg,event,order");
      crash_and_debug(hkey, test_exe, "dbg,attach,event,code2");
      if (pDebugSetProcessKillOnExit)
      }
      else
      {
-         if (auto_val)
-         {
-             RegSetValueExA(hkey, "auto", 0, auto_type, auto_val, auto_size);
-             HeapFree(GetProcessHeap(), 0, auto_val);
+         restore_value(hkey, &auto_value);
+         restore_value(hkey, &debugger_value);
+         RegCloseKey(hkey);
 -    }
 +        }
-         else
-             RegDeleteValueA(hkey, "auto");
        if (debugger_val)
+ }
static void test_RemoteDebugger(void)
 -{
 +        {
-             RegSetValueExA(hkey, "debugger", 0, debugger_type, debugger_val, debugger_size);
-             HeapFree(GetProcessHeap(), 0, debugger_val);
+     BOOL bret, present;
+     if(!pCheckRemoteDebuggerPresent)
+     {
+         win_skip("CheckRemoteDebuggerPresent is not available\n");
+         return;
 -    }
 +        }
-         else
-             RegDeleteValueA(hkey, "debugger");
-         RegCloseKey(hkey);
+     present = TRUE;
+     SetLastError(0xdeadbeef);
+     bret = pCheckRemoteDebuggerPresent(GetCurrentProcess(),&present);
+     ok(bret , "expected CheckRemoteDebuggerPresent to succeed\n");
+     ok(0xdeadbeef == GetLastError(),
+        "expected error to be unchanged, got %d/%x\n",GetLastError(), GetLastError());
+     present = TRUE;
+     SetLastError(0xdeadbeef);
+     bret = pCheckRemoteDebuggerPresent(NULL,&present);
+     ok(!bret , "expected CheckRemoteDebuggerPresent to fail\n");
+     ok(present, "expected parameter to be unchanged\n");
+     ok(ERROR_INVALID_PARAMETER == GetLastError(),
+        "expected error ERROR_INVALID_PARAMETER, got %d/%x\n",GetLastError(), GetLastError());
+     SetLastError(0xdeadbeef);
+     bret = pCheckRemoteDebuggerPresent(GetCurrentProcess(),NULL);
+     ok(!bret , "expected CheckRemoteDebuggerPresent to fail\n");
+     ok(ERROR_INVALID_PARAMETER == GetLastError(),
+        "expected error ERROR_INVALID_PARAMETER, got %d/%x\n",GetLastError(), GetLastError());
 -}
 +    }
- }
  
  START_TEST(debugger)
  {
@@@ -61,8 -61,11 +61,11 @@@ static void test_GetWindowsDirectoryW(v
      static const WCHAR fooW[] = {'f','o','o',0};
  
      len_with_null = GetWindowsDirectoryW(NULL, 0);
 -    if (len_with_null == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (len_with_null==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetWindowsDirectoryW is not implemented\n");
          return;
+     }
      ok(len_with_null <= MAX_PATH, "should fit into MAX_PATH\n");
  
      lstrcpyW(buf, fooW);
@@@ -124,8 -127,11 +127,11 @@@ static void test_GetSystemDirectoryW(vo
      static const WCHAR fooW[] = {'f','o','o',0};
  
      len_with_null = GetSystemDirectoryW(NULL, 0);
 -    if (len_with_null == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (len_with_null==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetSystemDirectoryW is not available\n");
          return;
+     }
      ok(len_with_null <= MAX_PATH, "should fit into MAX_PATH\n");
  
      lstrcpyW(buf, fooW);
@@@ -337,12 -343,17 +343,17 @@@ static void test_CreateDirectoryW(void
      static const WCHAR questionW[] = {'?',0};
  
      ret = CreateDirectoryW(NULL, NULL);
 -    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (!ret && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("CreateDirectoryW is not available\n");
          return;
-     ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND, "should not create NULL path\n");
+     }
+     ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
+        "should not create NULL path ret %u err %u\n", ret, GetLastError());
  
      ret = CreateDirectoryW(empty_strW, NULL);
-     ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND, "should not create empty path\n");
+     ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
+        "should not create empty path ret %u err %u\n", ret, GetLastError());
  
      ret = GetSystemDirectoryW(tmpdir, MAX_PATH);
      ok(ret < MAX_PATH, "System directory should fit into MAX_PATH\n");
      lstrcatW(tmpdir, slashW);
      lstrcatW(tmpdir, tmp_dir_name);
      ret = CreateDirectoryW(tmpdir, NULL);
 -    ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
 +    ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND, 
-       "CreateDirectoryW with multiple nonexistent directories in path should fail\n");
+       "CreateDirectoryW with multiple nonexistent directories in path should fail ret %u err %u\n",
+        ret, GetLastError());
      ret = RemoveDirectoryW(tmpdir);
  }
  
@@@ -434,8 -450,11 +450,11 @@@ static void test_RemoveDirectoryW(void
      GetTempPathW(MAX_PATH, tmpdir);
      lstrcatW(tmpdir, tmp_dir_name);
      ret = CreateDirectoryW(tmpdir, NULL);
 -    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (!ret && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("CreateDirectoryW is not available\n");
 -        return;
 +      return;
+     }
  
      ok(ret == TRUE, "CreateDirectoryW should always succeed\n");
  
@@@ -62,12 -63,13 +63,13 @@@ static void test_GetDriveTypeW(void
      for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
      {
          type = GetDriveTypeW(drive);
 -        if (type == DRIVE_UNKNOWN && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +        if (type == DRIVE_UNKNOWN && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
          {
-             /* Must be Win9x which doesn't support the Unicode functions */
+             win_skip("GetDriveTypeW is not available on Win9x\n");
              return;
          }
-         ok(type > 0 && type <= 6, "not a valid drive %c: type %u\n", drive[0], type);
+         ok(type > DRIVE_UNKNOWN && type <= DRIVE_RAMDISK,
+            "not a valid drive %c: type %u\n", drive[0], type);
  
          if (!(logical_drives & 1))
              ok(type == DRIVE_NO_ROOT_DIR,
@@@ -155,9 -169,9 +169,9 @@@ static void test_GetDiskFreeSpaceW(void
      static const WCHAR unix_style_root_pathW[] = { '/', 0 };
  
      ret = GetDiskFreeSpaceW(NULL, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
 -    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (ret == 0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
      {
-         /* Must be Win9x which doesn't support the Unicode functions */
+         win_skip("GetDiskFreeSpaceW is not available\n");
          return;
      }
      ok(ret, "GetDiskFreeSpaceW error %d\n", GetLastError());
@@@ -627,8 -673,11 +673,11 @@@ static void test_CopyFileW(void
      DWORD ret;
  
      ret = GetTempPathW(MAX_PATH, temp_path);
 -    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetTempPathW is not available\n");
          return;
+     }
      ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
      ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
  
@@@ -701,6 -805,284 +805,284 @@@ static void test_CreateFileA(void
  
      ret = DeleteFileA(filename);
      ok(ret, "DeleteFileA: error %d\n", GetLastError());
 -        }
+     /* get windows drive letter */
+     ret = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
+     ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
+     ok(ret != 0, "GetWindowsDirectory: error %d\n", GetLastError());
+     /* test error return codes from CreateFile for some cases */
+     ret = GetTempPathA(MAX_PATH, temp_path);
+     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
+     strcpy(dirname, temp_path);
+     strcat(dirname, directory);
+     ret = CreateDirectory(dirname, NULL);
+     ok( ret, "Createdirectory failed, gle=%d\n", GetLastError() );
+     /* set current drive & directory to known location */
+     SetCurrentDirectoryA( temp_path );
+     i = 0;
+     while (p[i].file)
+     {
+         filename[0] = 0;
+         /* update the drive id in the table entry with the current one */
+         if (p[i].file[1] == ':')
+         {
+             strcpy(filename, p[i].file);
+             filename[0] = windowsdir[0];
++}
+         else if (p[i].file[0] == '\\' && p[i].file[5] == ':')
+         {
+             strcpy(filename, p[i].file);
+             filename[4] = windowsdir[0];
+         }
+         else
+         {
+             /* prefix the table entry with the current temp directory */
+             strcpy(filename, temp_path);
+             strcat(filename, p[i].file);
+         }
+         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         p[i].options, NULL );
+         /* if we get ACCESS_DENIED when we do not expect it, assume
+          * no access to the volume
+          */
+         if (hFile == INVALID_HANDLE_VALUE &&
+             GetLastError() == ERROR_ACCESS_DENIED &&
+             p[i].err != ERROR_ACCESS_DENIED)
+         {
+             if (p[i].todo_flag)
+                 skip("Either no authority to volume, or is todo_wine for %s err=%d should be %d\n", filename, GetLastError(), p[i].err);
+             else
+                 skip("Do not have authority to access volumes. Test for %s skipped\n", filename);
+         }
+         /* otherwise validate results with expectations */
+         else if (p[i].todo_flag)
+             todo_wine ok(
+                 (hFile == INVALID_HANDLE_VALUE &&
+                   (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
+                 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
+                 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
+                 filename, hFile, GetLastError(), p[i].err);
+         else
+             ok(
+                 (hFile == INVALID_HANDLE_VALUE &&
+                  (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
+                 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
+                 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
+                 filename, hFile, GetLastError(), p[i].err);
+         if (hFile != INVALID_HANDLE_VALUE)
+             CloseHandle( hFile );
+         i++;
+     }
+     ret = RemoveDirectoryA(dirname);
+     ok(ret, "RemoveDirectoryA: error %d\n", GetLastError());
+     /* test opening directory as a directory */
+     hFile = CreateFileA( temp_path, GENERIC_READ,
+                         FILE_SHARE_READ,
+                         NULL,
+                         OPEN_EXISTING,
+                         FILE_FLAG_BACKUP_SEMANTICS, NULL );
+     if (hFile != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND)
+     {
+         ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_SUCCESS,
+             "CreateFileA did not work, last error %u on volume <%s>\n",
+              GetLastError(), temp_path );
+         if (hFile != INVALID_HANDLE_VALUE)
+         {
+             ret = GetFileInformationByHandle( hFile, &Finfo );
+             if (ret)
+             {
+                 ok(Finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY,
+                     "CreateFileA probably did not open temp directory %s correctly\n   file information does not include FILE_ATTRIBUTE_DIRECTORY, actual=0x%08x\n",
+                 temp_path, Finfo.dwFileAttributes);
+             }
+             CloseHandle( hFile );
+         }
+     }
+     else
+         skip("Probable Win9x, got ERROR_PATH_NOT_FOUND w/ FILE_FLAG_BACKUP_SEMANTICS or %s\n", temp_path);
+     /* ***  Test opening volumes/devices using drive letter  ***         */
+     /* test using drive letter in non-rewrite format without trailing \  */
+     /* this should work                                                  */
+     strcpy(filename, nt_drive);
+     filename[4] = windowsdir[0];
+     hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
+     if (hFile != INVALID_HANDLE_VALUE ||
+         (GetLastError() != ERROR_ACCESS_DENIED && GetLastError() != ERROR_BAD_NETPATH))
+     {
+         /* if we have adm rights to volume, then try rest of tests */
+         ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
+             filename, GetLastError());
+         if (hFile != INVALID_HANDLE_VALUE)
+         {
+             /* if we opened the volume/device, try to read it. Since it  */
+             /* opened, we should be able to read it.  We don't care about*/
+             /* what the data is at this time.                            */
+             len = 512;
+             ret = ReadFile( hFile, buffer, len, &len, NULL );
+             todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
+                 GetLastError(), ret, filename);
+             if (ret)
+             {
+                 trace("buffer is\n");
+                 dumpmem(buffer, 64);
+             }
+             CloseHandle( hFile );
+         }
+         /* test using drive letter with trailing \ and in non-rewrite   */
+         /* this should not work                                         */
+         strcpy(filename, nt_drive);
+         filename[4] = windowsdir[0];
+         strcat( filename, "\\" );
+         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
+         todo_wine
+         ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
+             "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
+             filename, GetLastError());
+         if (hFile != INVALID_HANDLE_VALUE)
+             CloseHandle( hFile );
+         /* test using temp path with trailing \ and in non-rewrite as dir */
+         /* this should work                                               */
+         strcpy(filename, nt_drive);
+         filename[4] = 0;
+         strcat( filename, temp_path );
+         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_FLAG_BACKUP_SEMANTICS, NULL );
+         ok(hFile != INVALID_HANDLE_VALUE,
+             "CreateFileA should have worked on %s, but got %u\n",
+             filename, GetLastError());
+         if (hFile != INVALID_HANDLE_VALUE)
+             CloseHandle( hFile );
+         /* test using drive letter without trailing \ and in device ns  */
+         /* this should work                                             */
+         strcpy(filename, nt_drive);
+         filename[4] = windowsdir[0];
+         filename[2] = '.';
+         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
+         ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
+             filename, GetLastError());
+         if (hFile != INVALID_HANDLE_VALUE)
+             CloseHandle( hFile );
+     }
+     /* If we see ERROR_BAD_NETPATH then on Win9x or WinME, so skip */
+     else if (GetLastError() == ERROR_BAD_NETPATH)
+         skip("Probable Win9x, got ERROR_BAD_NETPATH (53)\n");
+     else
+         skip("Do not have authority to access volumes. Tests skipped\n");
+     /* ***  Test opening volumes/devices using GUID  ***           */
+     if (pGetVolumeNameForVolumeMountPointA)
+     {
+         strcpy(filename, "c:\\");
+         filename[0] = windowsdir[0];
+         ret = pGetVolumeNameForVolumeMountPointA( filename, Volume_1, MAX_PATH );
+         ok(ret, "GetVolumeNameForVolumeMountPointA failed, for %s, last error=%d\n", filename, GetLastError());
+         if (ret)
+         {
+             ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name <%s>\n", Volume_1);
+             /* test the result of opening a unique volume name (GUID)
+              *  with the trailing \
+              *  this should error out
+              */
+             strcpy(filename, Volume_1);
+             hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
+             todo_wine
+             ok(hFile == INVALID_HANDLE_VALUE,
+                 "CreateFileA should not have opened %s, hFile %p\n",
+                 filename, hFile);
+             todo_wine
+             ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
+                 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
+                 filename, GetLastError());
+             if (hFile != INVALID_HANDLE_VALUE)
+                 CloseHandle( hFile );
+             /* test the result of opening a unique volume name (GUID)
+              * with the temp path string as dir
+              * this should work
+              */
+             strcpy(filename, Volume_1);
+             strcat(filename, temp_path+3);
+             hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_FLAG_BACKUP_SEMANTICS, NULL );
+             todo_wine
+             ok(hFile != INVALID_HANDLE_VALUE,
+                 "CreateFileA should have opened %s, but got %u\n",
+                 filename, GetLastError());
+             if (hFile != INVALID_HANDLE_VALUE)
+                 CloseHandle( hFile );
+             /* test the result of opening a unique volume name (GUID)
+              * without the trailing \ and in device namespace
+              * this should work
+              */
+             strcpy(filename, Volume_1);
+             filename[2] = '.';
+             filename[48] = 0;
+             hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                         NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
+             if (hFile != INVALID_HANDLE_VALUE || GetLastError() != ERROR_ACCESS_DENIED)
+             {
+                 /* if we have adm rights to volume, then try rest of tests */
+                 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
+                     filename, GetLastError());
+                 if (hFile != INVALID_HANDLE_VALUE)
+                 {
+                     /* if we opened the volume/device, try to read it. Since it  */
+                     /* opened, we should be able to read it.  We don't care about*/
+                     /* what the data is at this time.                            */
+                     len = 512;
+                     ret = ReadFile( hFile, buffer, len, &len, NULL );
+                     todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
+                         GetLastError(), ret, filename);
+                     if (ret)
+                     {
+                         trace("buffer is\n");
+                         dumpmem(buffer, 64);
+                     }
+                     CloseHandle( hFile );
+               }
+             }
+             else
+                 skip("Do not have authority to access volumes. Tests skipped\n");
+         }
+         else
+             win_skip("GetVolumeNameForVolumeMountPointA not functioning\n");
+     }
+     else
+         win_skip("GetVolumeNameForVolumeMountPointA not found\n");
  }
  
  static void test_CreateFileW(void)
      DWORD ret;
  
      ret = GetTempPathW(MAX_PATH, temp_path);
 -    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetTempPathW is not available\n");
          return;
+     }
      ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
      ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
  
@@@ -844,14 -1243,46 +1243,46 @@@ static void test_DeleteFileW( void 
      static const WCHAR emptyW[]={'\0'};
  
      ret = DeleteFileW(NULL);
 -    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("DeleteFileW is not available\n");
          return;
+     }
      ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
         "DeleteFileW(NULL) returned ret=%d error=%d\n",ret,GetLastError());
  
      ret = DeleteFileW(emptyW);
      ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
         "DeleteFileW(\"\") returned ret=%d error=%d\n",ret,GetLastError());
 -    }
+     /* test DeleteFile on empty directory */
+     ret = GetTempPathW(MAX_PATH, pathW);
+     if (ret + sizeof(dirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
+     {
+         ok(0, "MAX_PATH exceeded in constructing paths\n");
+         return;
++}
+     lstrcatW(pathW, dirW);
+     lstrcpyW(pathsubW, pathW);
+     lstrcatW(pathsubW, subdirW);
+     ret = CreateDirectoryW(pathW, NULL);
+     ok(ret == TRUE, "couldn't create directory deletefile\n");
+     ret = DeleteFileW(pathW);
+     ok(ret == FALSE, "DeleteFile should fail for empty directories\n");
+     ret = RemoveDirectoryW(pathW);
+     ok(ret == TRUE, "expected to remove directory deletefile\n");
+     /* test DeleteFile on non-empty directory */
+     ret = CreateDirectoryW(pathW, NULL);
+     ok(ret == TRUE, "couldn't create directory deletefile\n");
+     ret = CreateDirectoryW(pathsubW, NULL);
+     ok(ret == TRUE, "couldn't create directory deletefile\\sub\n");
+     ret = DeleteFileW(pathW);
+     ok(ret == FALSE, "DeleteFile should fail for non-empty directories\n");
+     ret = RemoveDirectoryW(pathsubW);
+     ok(ret == TRUE, "expected to remove directory deletefile\\sub\n");
+     ret = RemoveDirectoryW(pathW);
+     ok(ret == TRUE, "expected to remove directory deletefile\n");
  }
  
  #define IsDotDir(x)     ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
@@@ -935,8 -1413,11 +1413,11 @@@ static void test_MoveFileW(void
      DWORD ret;
  
      ret = GetTempPathW(MAX_PATH, temp_path);
 -    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetTempPathW is not available\n");
          return;
+     }
      ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
      ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
  
@@@ -1097,10 -1579,15 +1579,15 @@@ static void test_LockFile(void
              "UnlockFileEx 150,100 again succeeded\n" );
      }
  
-     ok( LockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "LockFile failed\n" );
+     ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 );
+     if (ret)
+     {
 -        ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
 -        ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
 -        ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
 +    ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
 +    ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
 +    ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
+     }
+     else  /* win9x */
+         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %u\n", GetLastError() );
  
      /* wrap-around lock should not do anything */
      /* (but still succeeds on NT4 so we don't check result) */
@@@ -1351,9 -1847,14 +1847,14 @@@ static void test_FindFirstFileA(void
      err = GetLastError();
      ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
      ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
 -        ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
 -        ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
+     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
+         FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
+         "wrong attributes %x\n", data.dwFileAttributes );
+     if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
+     {
-     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes, "wrong attributes %x\n", data.dwFileAttributes );
 +    ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
 +    ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
+     }
      SetLastError( 0xdeadbeaf );
      ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
      ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
      err = GetLastError();
      ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
      ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
 -        ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
 -        ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
+     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
+         FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
+         "wrong attributes %x\n", data.dwFileAttributes );
+     if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
+     {
-     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes, "wrong attributes %x\n", data.dwFileAttributes );
 +    ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
 +    ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
+     }
      SetLastError( 0xdeadbeaf );
      ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
      ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
@@@ -1840,15 -2487,19 +2487,19 @@@ static void test_overlapped(void
      memset( &ov, 0,  sizeof ov );
      result = 1;
      r = GetOverlappedResult(0, &ov, &result, 0);
-     ok( r == TRUE, "should return false\n");
+     if (r)
 -        ok( result == 0, "wrong result %u\n", result );
 +    ok( result == 0, "wrong result %u\n", result );
+     else  /* win9x */
+         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
  
      result = 0;
      ov.Internal = 0;
      ov.InternalHigh = 0xabcd;
      r = GetOverlappedResult(0, &ov, &result, 0);
-     ok( r == TRUE, "should return false\n");
+     if (r)
 -        ok( result == 0xabcd, "wrong result %u\n", result );
 +    ok( result == 0xabcd, "wrong result %u\n", result );
+     else  /* win9x */
+         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
  
      SetLastError( 0xb00 );
      result = 0;
@@@ -1901,16 -2555,13 +2555,13 @@@ static void test_RemoveDirectory(void
      ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
  
      rc = RemoveDirectory(".");
-     todo_wine {
-     ok( !rc, "RemoveDirectory unexpectedly worked\n" );
-     }
+     if (!rc)
+     {
 -        rc = SetCurrentDirectory("..");
 -        ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
 +    rc = SetCurrentDirectory("..");
 +    ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
  
 -        rc = RemoveDirectory(directory);
 -        ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
 +    rc = RemoveDirectory(directory);
-     todo_wine {
 +    ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
      }
  }
  
@@@ -2010,26 -2668,32 +2668,32 @@@ static void test_ReplaceFileA(void
      /* make sure that the "replaced" file has the size of the replacement file */
      hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
      ok(hReplacedFile != INVALID_HANDLE_VALUE,
-         "failed to open replaced file\n");
+         "failed to open replaced file: %d\n", GetLastError());
+     if (hReplacedFile != INVALID_HANDLE_VALUE)
+     {
 -        ret = GetFileSize(hReplacedFile, NULL);
 -        ok(ret == sizeof(replacementData),
 -            "replaced file has wrong size %d\n", ret);
 -        /* make sure that the replacement file no-longer exists */
 -        hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
 -        ok(hReplacementFile == INVALID_HANDLE_VALUE,
 -           "unexpected error, replacement file should not exist %d\n", GetLastError());
 -        /* make sure that the backup has the old "replaced" filetime */
 -        ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
 -        ok( ret, "GetFileTime error (backup %d\n", GetLastError());
 +    ret = GetFileSize(hReplacedFile, NULL);
 +    ok(ret == sizeof(replacementData),
 +        "replaced file has wrong size %d\n", ret);
 +    /* make sure that the replacement file no-longer exists */
 +    hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
 +    ok(hReplacementFile == INVALID_HANDLE_VALUE,
 +       "unexpected error, replacement file should not exist %d\n", GetLastError());
 +    /* make sure that the backup has the old "replaced" filetime */
 +    ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
 +    ok( ret, "GetFileTime error (backup %d\n", GetLastError());
-     ok(CompareFileTime(&ftBackup, &ftReplaced) == 0,
-         "backup file has wrong filetime\n");
+         ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
 -        CloseHandle(hBackupFile);
 -        /* make sure that the "replaced" has the old replacement filetime */
 -        ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
 -        ok( ret, "GetFileTime error (backup %d\n", GetLastError());
 +    CloseHandle(hBackupFile);
 +    /* make sure that the "replaced" has the old replacement filetime */
 +    ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
 +    ok( ret, "GetFileTime error (backup %d\n", GetLastError());
-     ok(CompareFileTime(&ftReplaced, &ftReplacement) == 0,
-         "replaced file has wrong filetime\n");
+         ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
+            "replaced file has wrong filetime %x%08x / %x%08x\n",
+            ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
+            ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
 -        CloseHandle(hReplacedFile);
 +    CloseHandle(hReplacedFile);
+     }
+     else
+         skip("couldn't open replacement file, skipping tests\n");
  
      /* re-create replacement file for pass w/o backup (blank) */
      ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
       */
      SetLastError(0xdeadbeef);
      ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
-     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
+     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
+        GetLastError() == ERROR_ACCESS_DENIED),
 -       "ReplaceFileA: unexpected error %d\n", GetLastError());
 +                      "ReplaceFileA: unexpected error %d\n", GetLastError());
  
      /* perform replacement w/o existing "replacement" file
       * TODO: flags are not implemented
       */
  
      /* delete temporary files, replacement and replaced are already deleted */
 -        ret = DeleteFileA(backup);
+     if (removeBackup)
+     {
-     ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
 +    ret = DeleteFileA(backup);
 -    }
+         ok(ret ||
+            broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
+            "DeleteFileA: error (backup) %d\n", GetLastError());
++}
  }
  
  /*
@@@ -2120,8 -2800,11 +2800,11 @@@ static void test_ReplaceFileW(void
      }
  
      ret = GetTempPathW(MAX_PATH, temp_path);
 -    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (ret==0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetTempPathW is not available\n");
          return;
+     }
      ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
      ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
  
      ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
  
      ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
-     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
+     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
+        GetLastError() == ERROR_ACCESS_DENIED),
          "ReplaceFileW: unexpected error %d\n", GetLastError());
  
 -        ret = DeleteFileW(backup);
+     if (removeBackup)
+     {
-     ok(ret, "DeleteFileW: error %d\n", GetLastError());
 +    ret = DeleteFileW(backup);
 -    }
+         ok(ret ||
+            broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
+            "DeleteFileW: error (backup) %d\n", GetLastError());
++}
  }
  
  START_TEST(file)
  
  /* #define ok(cond,failstr) if(!(cond)) {printf("line %d : %s\n",__LINE__,failstr);exit(1);} */
  
- static DWORD doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
+ static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
 -                          LPSTR out, DWORD outsize, ... )
 +           LPSTR out, DWORD outsize, ... )
  {
-     va_list list;
+     __ms_va_list list;
      DWORD r;
  
-     va_start(list, outsize);
+     __ms_va_start(list, outsize);
      r = FormatMessageA(flags, src, msg_id,
          lang_id, out, outsize, &list);
-     va_end(list);
+     __ms_va_end(list);
      return r;
  }
  
@@@ -183,26 -216,41 +216,41 @@@ static void test_heap(void
      ok(mem == NULL, "Expected NULL, got %p\n", mem);
  
      /* invalid free */
 -        SetLastError(MAGIC_DEAD);
 -        mem = GlobalFree(gbl);
+     if (sizeof(void *) != 8)  /* crashes on 64-bit Vista */
+     {
-     ok(mem == gbl, "Expected gbl, got %p\n", mem);
-     ok(GetLastError() == ERROR_INVALID_HANDLE,
-        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
 +    SetLastError(MAGIC_DEAD);
 +    mem = GlobalFree(gbl);
+         ok(mem == gbl || broken(mem == NULL) /* nt4 */, "Expected gbl, got %p\n", mem);
+         if (mem == gbl)
+             ok(GetLastError() == ERROR_INVALID_HANDLE ||
+                GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
+                "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+     }
  
      gbl = GlobalAlloc(GMEM_DDESHARE, 100);
  
      res = GlobalUnlock(gbl);
-     ok(res == 1, "Expected 1, got %d\n", res);
+     ok(res == 1 ||
+        res == 0, /* win9x */
+        "Expected 1 or 0, got %d\n", res);
  
      res = GlobalUnlock(gbl);
-     ok(res == 1, "Expected 1, got %d\n", res);
+     ok(res == 1 ||
+        res == 0, /* win9x */
+        "Expected 1 or 0, got %d\n", res);
  
      /* GlobalSize on an invalid handle */
 -        SetLastError(MAGIC_DEAD);
 -        size = GlobalSize((HGLOBAL)0xc042);
 -        ok(size == 0, "Expected 0, got %ld\n", size);
+     if (sizeof(void *) != 8)  /* crashes on 64-bit Vista */
+     {
-     ok(GetLastError() == ERROR_INVALID_HANDLE,
-        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
 +    SetLastError(MAGIC_DEAD);
 +    size = GlobalSize((HGLOBAL)0xc042);
 +    ok(size == 0, "Expected 0, got %ld\n", size);
+         ok(GetLastError() == ERROR_INVALID_HANDLE ||
+            GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
+            "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+     }
+     GlobalFree(gbl);
  
      /* ####################################### */
      /* Local*() functions */
@@@ -1,47 -1,43 +1,43 @@@
  <?xml version="1.0"?>
  <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
- <group>
  <module name="kernel32_winetest" type="win32cui" installbase="bin" installname="kernel32_winetest.exe" allowwarnings="true">
 -      <include base="kernel32_winetest">.</include>
 +    <include base="kernel32_winetest">.</include>
-     <define name="__USE_W32API" />
-     <define name="_WIN32_WINNT">0x0600</define>
-     <define name="WINVER">0x609</define>
+       <define name="__ROS_LONG64__" />
 -      <library>ntdll</library>
 +    <library>ntdll</library>
-     <library>kernel32</library>
+       <library>user32</library>
 -      <library>advapi32</library>
 -      <file>actctx.c</file>
 -      <file>alloc.c</file>
 -      <file>atom.c</file>
 -      <file>change.c</file>
 -      <file>codepage.c</file>
 -      <file>comm.c</file>
 -      <file>console.c</file>
 -      <file>debugger.c</file>
 -      <file>directory.c</file>
 -      <file>drive.c</file>
 -      <file>environ.c</file>
 -      <file>file.c</file>
 -      <file>format_msg.c</file>
 -      <!-- <file>generated.c</file> -->
 -      <file>heap.c</file>
 -      <file>interlck.c</file>
 -      <file>loader.c</file>
 -      <file>locale.c</file>
 -      <file>mailslot.c</file>
 -      <file>module.c</file>
 -      <file>path.c</file>
 -      <file>pipe.c</file>
 -      <file>process.c</file>
 -      <file>profile.c</file>
 -      <file>resource.c</file>
 -      <file>sync.c</file>
 -      <file>thread.c</file>
 -      <file>time.c</file>
 -      <file>timer.c</file>
 -      <file>toolhelp.c</file>
 -      <file>version.c</file>
 -      <file>virtual.c</file>
 -      <file>volume.c</file>
 -      <file>testlist.c</file>
 +    <library>advapi32</library>
 +    <file>actctx.c</file>
 +    <file>alloc.c</file>
 +    <file>atom.c</file>
 +    <file>change.c</file>
 +    <file>codepage.c</file>
 +    <file>comm.c</file>
 +    <file>console.c</file>
 +    <file>debugger.c</file>
 +    <file>directory.c</file>
 +    <file>drive.c</file>
 +    <file>environ.c</file>
 +    <file>file.c</file>
 +    <file>format_msg.c</file>
 +    <!-- <file>generated.c</file> -->
 +    <file>heap.c</file>
 +    <file>interlck.c</file>
 +    <file>loader.c</file>
 +    <file>locale.c</file>
 +    <file>mailslot.c</file>
 +    <file>module.c</file>
 +    <file>path.c</file>
 +    <file>pipe.c</file>
 +    <file>process.c</file>
 +    <file>profile.c</file>
 +    <file>resource.c</file>
 +    <file>sync.c</file>
 +    <file>thread.c</file>
 +    <file>time.c</file>
 +    <file>timer.c</file>
 +    <file>toolhelp.c</file>
 +    <file>version.c</file>
 +    <file>virtual.c</file>
 +    <file>volume.c</file>
 +    <file>testlist.c</file>
  </module>
- </group>
@@@ -401,8 -556,13 +556,13 @@@ static void test_GetDateFormatW(void
    ret = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL,
                         input, buffer, COUNTOF(buffer));
    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 -    return;
+   {
+     win_skip("GetDateFormatW is not implemented\n");
-   EXPECT_FLAGS; EXPECT_LEN(0); EXPECT_EQW;
 +      return;
+   }
+   ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
+      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
+   EXPECT_EQW;
  
    STRINGSW("",""); /* NULL buffer, len > 0 */
    SetLastError(0xdeadbeef);
@@@ -855,14 -1108,14 +1108,14 @@@ static void test_CompareStringA(void
      ok (ret == 0, "lstrcmpA(\"\", \"\") should return 0, got %d\n", ret);
  
      ret = lstrcmpA(NULL, NULL);
-     ok (ret == 0, "lstrcmpA(NULL, NULL) should return 0, got %d\n", ret);
+     ok (ret == 0 || broken(ret == -2) /* win9x */, "lstrcmpA(NULL, NULL) should return 0, got %d\n", ret);
  
      ret = lstrcmpA("", NULL);
-     ok (ret == 1, "lstrcmpA(\"\", NULL) should return 1, got %d\n", ret);
+     ok (ret == 1 || broken(ret == -2) /* win9x */, "lstrcmpA(\"\", NULL) should return 1, got %d\n", ret);
  
      ret = lstrcmpA(NULL, "");
-     ok (ret == -1, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret);
+     ok (ret == -1 || broken(ret == -2) /* win9x */, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret);
 - 
 +  
      ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"EndDialog",-1,"_Property",-1);
      ok( ret == 3, "EndDialog vs _Property ... expected 3, got %d\n", ret);
  
@@@ -1193,12 -1447,17 +1447,17 @@@ static void test_LCMapStringW(void
                         upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
      if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
      {
-         trace("Skipping LCMapStringW tests on Win9x\n");
+         win_skip("LCMapStringW is not implemented\n");
          return;
      }
 -        ok(!ret, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
 -        ok(GetLastError() == ERROR_INVALID_FLAGS,
 -           "unexpected error code %d\n", GetLastError());
+     if (broken(ret))
+         ok(lstrcmpW(buf, upper_case) == 0, "Expected upper case string\n");
+     else
+     {
 +    ok(!ret, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
 +    ok(GetLastError() == ERROR_INVALID_FLAGS,
 +       "unexpected error code %d\n", GetLastError());
+     }
  
      ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_HIRAGANA | LCMAP_KATAKANA,
                         upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
@@@ -1521,9 -1817,12 +1817,12 @@@ static void test_FoldStringA(void
    /* MAP_FOLDDIGITS */
    SetLastError(0);
    ret = pFoldStringA(MAP_FOLDDIGITS, digits_src, -1, dst, 256);
 -  if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +  if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+   {
+     win_skip("FoldStringA is not implemented\n");
      return;
-   EXPECT_LEN(4); EXPECT_VALID;
+   }
+   ok(ret == 4, "Expected ret == 4, got %d, error %d\n", ret, GetLastError());
    ok(strcmp(dst, digits_dst) == 0,
       "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", digits_dst, dst);
    for (i = 1; i < 256; i++)
          src[1] = '\0';
          SetLastError(0);
          ret = pFoldStringA(MAP_EXPAND_LIGATURES, src, -1, dst, 256);
-         EXPECT_LEN(2); EXPECT_VALID;
+         if (ret == 3)
+         {
+           /* Vista */
+           ok((i == 0xDC && lstrcmpA(dst, "UE") == 0) ||
+              (i == 0xFC && lstrcmpA(dst, "ue") == 0),
+              "Got %s for %d\n", dst, i);
+         }
+         else
+         {
+           ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
 -          ok(dst[0] == src[0],
 -             "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", src, dst);
 -        }
 +        ok(dst[0] == src[0],
 +           "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", src, dst);
        }
      }
    }
++  }
  
    /* MAP_COMPOSITE */
    SetLastError(0);
      src[1] = '\0';
      SetLastError(0);
      ret = pFoldStringA(MAP_FOLDCZONE, src, -1, dst, 256);
-     EXPECT_LEN(2); EXPECT_VALID;
+     is_special = FALSE;
+     for (j = 0; foldczone_special[j].src != 0 && ! is_special; j++)
+     {
+       if (foldczone_special[j].src == src[0])
+       {
+         ok(ret == 2 || ret == lstrlenA(foldczone_special[j].dst) + 1,
+            "Expected ret == 2 or %d, got %d, error %d\n",
+            lstrlenA(foldczone_special[j].dst) + 1, ret, GetLastError());
+         ok(src[0] == dst[0] || lstrcmpA(foldczone_special[j].dst, dst) == 0,
+            "MAP_FOLDCZONE: string mismatch for 0x%02x\n",
+            (unsigned char)src[0]);
+         is_special = TRUE;
+       }
+     }
+     if (! is_special)
+     {
+       ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
 -      ok(src[0] == dst[0],
 -         "MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x\n",
 -         (unsigned char)src[0], (unsigned char)dst[0]);
 -    }
 +    ok(src[0] == dst[0],
 +       "MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x\n",
 +       (unsigned char)src[0], (unsigned char)dst[0]);
 +  }
+   }
  
    /* MAP_PRECOMPOSED */
    for (i = 1; i < 256; i++)
@@@ -1907,63 -2151,23 +2151,23 @@@ static void test_FoldStringW(void
    }
  
    /* MAP_FOLDCZONE */
-   for (ch = 1; ch <0xffff; ch++)
-   {
-     WCHAR expected = 0;
-     if (ch >= 0xF900 && ch <= 0xFA2F)
-       expected = compat_F900_FA2F[ch - 0xF900];
-     else if (ch >= 0xFE30 && ch <= 0xFEF7)
-       expected = compat_FE30_FEF7[ch - 0xFE30];
-     else if (ch >= 0xFF00 && ch <= 0xFFEF)
-       expected = compat_FF00_FFEF[ch - 0xFF00];
-     if (!expected)
-       expected = ch;
 -  SetLastError(0);
 +    SetLastError(0);
-     src[0] = ch;
-     src[1] = dst[0] = '\0';
-     ret = pFoldStringW(MAP_FOLDCZONE, src, -1, dst, 256);
-     EXPECT_LEN(2); EXPECT_VALID;
-     ok(dst[0] == expected ||
-        /* Wine (correctly) uses updated mappings for some Unicode 4.0 chars */
-        /* FIXME: But they should be re-checked */
-        ch == 0xf92c || ch == 0xf979 || ch == 0xf995 || ch == 0xf9e7 ||
-        ch == 0xf9f1 ||
-        (0xfa0c <= ch && ch <= 0xfa6a) ||
-        (0xfa70 <= ch && ch <= 0xfad9) ||
-        ch == 0xfe47 || ch == 0xfe48 || ch == 0xfe68 ||
-        (0xfe70 <= ch && ch <= 0xfe7f) ||
-        ch == 0xff3c || ch == 0xff5f || ch == 0xff60 ||
-        ch == 0xff9e || ch == 0xff9f,
-        "MAP_FOLDCZONE: ch %d 0x%04x Expected 0x%04x got 0x%04x\n",
-        ch, ch, expected, dst[0]);
-   }
+   ret = pFoldStringW(MAP_FOLDCZONE, foldczone_src, -1, dst, 256);
+   ok(ret == sizeof(foldczone_dst)/sizeof(foldczone_dst[0]),
+      "Got %d, error %d\n", ret, GetLastError());
+   ok(!memcmp(dst, foldczone_dst, sizeof(foldczone_dst)),
+      "MAP_FOLDCZONE: Expanded incorrectly\n");
  
    /* MAP_EXPAND_LIGATURES */
    SetLastError(0);
    ret = pFoldStringW(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256);
    /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
    if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
-     EXPECT_LEN(sizeof(ligatures_dst)/sizeof(ligatures_dst[0])); EXPECT_VALID;
+     ok(ret == sizeof(ligatures_dst)/sizeof(ligatures_dst[0]),
+        "Got %d, error %d\n", ret, GetLastError());
      ok(!memcmp(dst, ligatures_dst, sizeof(ligatures_dst)),
         "MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
-     for (i = 1; i <= 0xffff; i++)
-     {
-       if (!strchrW(ligatures_src, i))
-       {
-         src[0] = i;
-         src[1] = '\0';
-         SetLastError(0);
-         ret = pFoldStringW(MAP_EXPAND_LIGATURES, src, -1, dst, 256);
-         EXPECT_LEN(2); EXPECT_VALID;
-         ok(dst[0] == src[0],
-            "MAP_EXPAND_LIGATURES: 0x%02x : Expected 0x%02x, got 0x%02x\n",
-            i, src[0], dst[0]);
 -  }
 +      }
-     }
-   }
  
    /* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
  }
@@@ -2178,25 -2420,41 +2420,41 @@@ static void test_EnumDateFormatsA(void
  
      trace("EnumDateFormatsA 0\n");
      date_fmt_buf[0] = 0;
+     SetLastError(0xdeadbeef);
      ret = EnumDateFormatsA(enum_datetime_procA, lcid, 0);
 -        ok(ret, "EnumDateFormatsA(0) error %d\n", GetLastError());
 -        trace("%s\n", date_fmt_buf);
 -        /* test the 1st enumerated format */
 -        if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
 -        ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
 -        ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
 -        ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
+     if (!ret && (GetLastError() == ERROR_INVALID_FLAGS))
+     {
+         win_skip("0 for dwFlags is not supported\n");
+     }
+     else
+     {
 +    ok(ret, "EnumDateFormatsA(0) error %d\n", GetLastError());
 +    trace("%s\n", date_fmt_buf);
 +    /* test the 1st enumerated format */
 +    if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
 +    ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
 +    ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
 +    ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
+     }
  
      trace("EnumDateFormatsA LOCALE_USE_CP_ACP\n");
      date_fmt_buf[0] = 0;
+     SetLastError(0xdeadbeef);
      ret = EnumDateFormatsA(enum_datetime_procA, lcid, LOCALE_USE_CP_ACP);
 -        ok(ret, "EnumDateFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
 -        trace("%s\n", date_fmt_buf);
 -        /* test the 1st enumerated format */
 -        if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
 -        ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
 -        ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
 -        ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
+     if (!ret && (GetLastError() == ERROR_INVALID_FLAGS))
+     {
+         win_skip("LOCALE_USE_CP_ACP is not supported\n");
+     }
+     else
+     {
 +    ok(ret, "EnumDateFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
 +    trace("%s\n", date_fmt_buf);
 +    /* test the 1st enumerated format */
 +    if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
 +    ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
 +    ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
 +    ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
+     }
  
      trace("EnumDateFormatsA DATE_SHORTDATE\n");
      date_fmt_buf[0] = 0;
@@@ -2280,21 -2539,36 +2539,36 @@@ static void test_GetCPInfo(void
  
      SetLastError(0xdeadbeef);
      ret = GetCPInfo(CP_UTF7, &cpinfo);
 -        ok(ret, "GetCPInfo(CP_UTF7) error %u\n", GetLastError());
 -        ok(cpinfo.DefaultChar[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo.DefaultChar[0]);
 -        ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
 -        ok(cpinfo.LeadByte[0] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[0]);
 -        ok(cpinfo.LeadByte[1] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[1]);
 -        ok(cpinfo.MaxCharSize == 5, "expected 5, got 0x%x\n", cpinfo.MaxCharSize);
+     if (!ret && GetLastError() == ERROR_INVALID_PARAMETER)
+     {
+         skip("Codepage CP_UTF7 is not installed/available\n");
+     }
+     else
+     {
 +    ok(ret, "GetCPInfo(CP_UTF7) error %u\n", GetLastError());
 +    ok(cpinfo.DefaultChar[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo.DefaultChar[0]);
 +    ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
 +    ok(cpinfo.LeadByte[0] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[0]);
 +    ok(cpinfo.LeadByte[1] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[1]);
 +    ok(cpinfo.MaxCharSize == 5, "expected 5, got 0x%x\n", cpinfo.MaxCharSize);
+     }
  
      SetLastError(0xdeadbeef);
      ret = GetCPInfo(CP_UTF8, &cpinfo);
 -        ok(ret, "GetCPInfo(CP_UTF8) error %u\n", GetLastError());
 -        ok(cpinfo.DefaultChar[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo.DefaultChar[0]);
 -        ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
 -        ok(cpinfo.LeadByte[0] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[0]);
 -        ok(cpinfo.LeadByte[1] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[1]);
+     if (!ret && GetLastError() == ERROR_INVALID_PARAMETER)
+     {
+         skip("Codepage CP_UTF8 is not installed/available\n");
+     }
+     else
+     {
-     ok(cpinfo.MaxCharSize == 4, "expected 5, got 0x%x\n", cpinfo.MaxCharSize);
 +    ok(ret, "GetCPInfo(CP_UTF8) error %u\n", GetLastError());
 +    ok(cpinfo.DefaultChar[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo.DefaultChar[0]);
 +    ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
 +    ok(cpinfo.LeadByte[0] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[0]);
 +    ok(cpinfo.LeadByte[1] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[1]);
 -    }
+         ok(cpinfo.MaxCharSize == 4 || broken(cpinfo.MaxCharSize == 3) /* win9x */,
+            "expected 4, got %u\n", cpinfo.MaxCharSize);
++}
  }
  
  START_TEST(locale)
@@@ -54,10 -55,13 +55,13 @@@ static int mailslot_test(void
  
      /* open a mailslot with a null name */
      hSlot = CreateMailslot( NULL, 0, 0, NULL );
-     ok( hSlot == INVALID_HANDLE_VALUE,
+     ok( hSlot == INVALID_HANDLE_VALUE || broken(hSlot != INVALID_HANDLE_VALUE), /* win9x */
 -        "Created mailslot with invalid name\n");
 +            "Created mailslot with invalid name\n");
+     if (hSlot == INVALID_HANDLE_VALUE)
 -        ok( GetLastError() == ERROR_PATH_NOT_FOUND,
 +    ok( GetLastError() == ERROR_PATH_NOT_FOUND,
              "error should be ERROR_PATH_NOT_FOUND\n");
+     else  /* succeeds on win9x */
+         CloseHandle( hSlot );
  
      /* valid open, but with wacky parameters ... then check them */
      hSlot = CreateMailslot( szmspath, -1, -1, NULL );
              "slot write\n");
      ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
  
 -    /* now try and open the client, but with the wrong sharing mode */
 +    /* now try and openthe client, but with the wrong sharing mode */
-     hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
+     hWriter = CreateFile(szmspath, GENERIC_WRITE,
                               0, NULL, OPEN_EXISTING, 0, NULL);
-     ok( hWriter == INVALID_HANDLE_VALUE, "bad sharing mode\n");
-     ok( GetLastError() == ERROR_SHARING_VIOLATION,
-             "error should be ERROR_SHARING_VIOLATION\n");
+     ok( hWriter != INVALID_HANDLE_VALUE /* vista */ || GetLastError() == ERROR_SHARING_VIOLATION,
+         "error should be ERROR_SHARING_VIOLATION got %p / %u\n", hWriter, GetLastError());
+     if (hWriter != INVALID_HANDLE_VALUE) CloseHandle( hWriter );
  
      /* now open the client with the correct sharing mode */
      hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
@@@ -384,14 -384,16 +384,16 @@@ static void test_InitPathA(CHAR *newdir
    ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
    sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
    ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
-   bRes = CreateDirectoryA("c:",NULL);
+   sprintf(tmpstr,"%c:", *curDrive);
+   bRes = CreateDirectoryA(tmpstr,NULL);
 -  ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  ||
 +  ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  || 
                 GetLastError() == ERROR_ALREADY_EXISTS),
-      "CreateDirectoryA(\"c:\" should have failed (%d)\n", GetLastError());
-   bRes = CreateDirectoryA("c:\\",NULL);
+      "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
+   sprintf(tmpstr,"%c:\\", *curDrive);
+   bRes = CreateDirectoryA(tmpstr,NULL);
    ok(!bRes && (GetLastError() == ERROR_ACCESS_DENIED  ||
                 GetLastError() == ERROR_ALREADY_EXISTS),
-      "CreateDirectoryA(\"c:\\\" should have failed (%d)\n", GetLastError());
+      "CreateDirectoryA(\"%s\" should have failed (%d)\n", tmpstr, GetLastError());
    sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
    hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
                     CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
@@@ -868,8 -878,11 +878,11 @@@ static void test_GetTempPathW(char* tmp
  
      lstrcpyW(buf, fooW);
      len = GetTempPathW(MAX_PATH, buf);
 -    if (len == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
 +    if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+     {
+         win_skip("GetTempPathW is not available\n");
          return;
+     }
      ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
      ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
  
@@@ -897,11 -910,14 +910,14 @@@ static void test_GetTempPath(void
  
      /* test default configuration */
      trace("TMP=%s\n", save_TMP);
 -        strcpy(buf,save_TMP);
 -        if (buf[strlen(buf)-1]!='\\')
 -            strcat(buf,"\\");
 -        test_GetTempPathA(buf);
 -        test_GetTempPathW(buf);
+     if (save_TMP[0])
+     {
 +    strcpy(buf,save_TMP);
 +    if (buf[strlen(buf)-1]!='\\')
 +        strcat(buf,"\\");
 +    test_GetTempPathA(buf);
 +    test_GetTempPathW(buf);
+     }
  
      /* TMP=C:\WINDOWS */
      GetWindowsDirectoryA(windir, sizeof(windir));
@@@ -1208,8 -1224,11 +1224,11 @@@ static void test_drive_letter_case(void
      ret = GetTempPath(sizeof(buf), buf);
      ok(ret, "GetTempPath error %u\n", GetLastError());
      ok(ret < sizeof(buf), "buffer should be %u bytes\n", ret);
 -        ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
 -        ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
+     if (buf[0])
+     {
 +    ok(buf[1] == ':', "expected buf[1] == ':' got %c\n", buf[1]);
 +    ok(buf[strlen(buf)-1] == '\\', "Temporary path (%s) doesn't end in a slash\n", buf);
+     }
  
      memset(buf, 0, sizeof(buf));
      SetLastError(0xdeadbeef);
@@@ -558,17 -550,24 +550,24 @@@ static DWORD CALLBACK serverThreadMain3
          trace("Server calling overlapped ConnectNamedPipe...\n");
          success = ConnectNamedPipe(hnp, &oOverlap);
          err = GetLastError();
-         ok(success || err == ERROR_IO_PENDING
-             || err == ERROR_PIPE_CONNECTED, "overlapped ConnectNamedPipe\n");
+         ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n");
          trace("overlapped ConnectNamedPipe returned.\n");
-         if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
-             ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ConnectNamedPipe\n");
+         if (!success && (err == ERROR_IO_PENDING)) {
+             if (letWFSOEwait)
+             {
+                 DWORD ret;
+                 do {
+                     ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
+                 } while (ret == WAIT_IO_COMPLETION);
+                 ok(ret == 0, "wait ConnectNamedPipe returned %x\n", ret);
+             }
 -            success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);
 -            if (!letGORwait && !letWFSOEwait && !success) {
 -                ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
 -                success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);
 -            }
 +        success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);
 +      if (!letGORwait && !letWFSOEwait && !success) {
 +          ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
 +          success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);
 +      }
-       ok(success, "GetOverlappedResult ConnectNamedPipe\n");
+         }
+         ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n");
          trace("overlapped ConnectNamedPipe operation complete.\n");
  
          /* Echo bytes once */
          err = GetLastError();
          ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n");
          trace("overlapped ReadFile returned.\n");
-         if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
-             ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ReadFile\n");
+         if (!success && (err == ERROR_IO_PENDING)) {
+             if (letWFSOEwait)
+             {
+                 DWORD ret;
+                 do {
+                     ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
+                 } while (ret == WAIT_IO_COMPLETION);
+                 ok(ret == 0, "wait ReadFile returned %x\n", ret);
+             }
 -            success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);
 -            if (!letGORwait && !letWFSOEwait && !success) {
 -                ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
 -                success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
 -            }
 +        success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);
 +      if (!letGORwait && !letWFSOEwait && !success) {
 +          ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
 +          success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
 +      }
+         }
          trace("Server done reading.\n");
          ok(success, "overlapped ReadFile\n");
  
          err = GetLastError();
          ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n");
          trace("overlapped WriteFile returned.\n");
-         if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
-             ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait WriteFile\n");
+         if (!success && (err == ERROR_IO_PENDING)) {
+             if (letWFSOEwait)
+             {
+                 DWORD ret;
+                 do {
+                     ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
+                 } while (ret == WAIT_IO_COMPLETION);
+                 ok(ret == 0, "wait WriteFile returned %x\n", ret);
+             }
 -            success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);
 -            if (!letGORwait && !letWFSOEwait && !success) {
 -                ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
 -                success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
 -            }
 +        success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);
 +      if (!letGORwait && !letWFSOEwait && !success) {
 +          ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
 +          success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
 +      }
+         }
          trace("Server done writing.\n");
          ok(success, "overlapped WriteFile\n");
          ok(written == readden, "write file len\n");
@@@ -348,8 -373,18 +373,18 @@@ static void     doChild(const char* fil
              childPrintf(hFile, "OutputMode=%ld\n", modeOut);
  
          /* now that we have written all relevant information, let's change it */
-         ok(SetConsoleCP(1252), "Setting CP\n");
+         SetLastError(0xdeadbeef);
+         ret = SetConsoleCP(1252);
+         if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+         {
+             win_skip("Setting the codepage is not implemented\n");
+         }
+         else
+         {
+             ok(ret, "Setting CP\n");
 -            ok(SetConsoleOutputCP(1252), "Setting SB CP\n");
 +        ok(SetConsoleOutputCP(1252), "Setting SB CP\n");
+         }
          ret = SetConsoleMode(hConIn, modeIn ^ 1);
          ok( ret, "Setting mode (%d)\n", GetLastError());
          ret = SetConsoleMode(hConOut, modeOut ^ 1);
@@@ -818,7 -892,97 +892,97 @@@ static void test_CommandLine(void
      okChildString("Arguments", "argvA0", buffer);
      release_memory();
      assert(DeleteFileA(resfile) != 0);
 -
 +    
+     /* Using AppName */
+     get_file_name(resfile);
+     len = GetFullPathNameA(selfname, MAX_PATH, fullpath, &lpFilePart);
+     assert ( lpFilePart != 0);
+     *(lpFilePart -1 ) = 0;
+     p = strrchr(fullpath, '\\');
+     /* Use exename to avoid buffer containing things like 'C:' */
+     if (p) sprintf(buffer, "..%s/%s", p, exename);
+     else sprintf(buffer, "./%s", exename);
+     sprintf(buffer2, "dummy tests/process.c %s \"a\\\"b\\\\\" c\\\" d", resfile);
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(buffer, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
+     /* wait for child to terminate */
+     ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+     /* child process has changed result file, so let profile functions know about it */
+     WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+     sprintf(buffer, "tests/process.c %s", resfile);
+     okChildString("Arguments", "argvA0", "dummy");
+     okChildString("Arguments", "CommandLineA", buffer2);
+     okChildStringWA("Arguments", "CommandLineW", buffer2);
+     release_memory();
+     assert(DeleteFileA(resfile) != 0);
+     if (0) /* Test crashes on NT-based Windows. */
+     {
+         /* Test NULL application name and command line parameters. */
+         SetLastError(0xdeadbeef);
+         ret = CreateProcessA(NULL, NULL, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+         ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+         ok(GetLastError() == ERROR_INVALID_PARAMETER,
+            "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
 -    }
++}
+     buffer[0] = '\0';
+     /* Test empty application name parameter. */
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(buffer, NULL, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_PATH_NOT_FOUND ||
+        broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* Win9x/WinME */ ||
+        broken(GetLastError() == ERROR_ACCESS_DENIED) /* Win98 */,
+        "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
+     buffer2[0] = '\0';
+     /* Test empty application name and command line parameters. */
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(buffer, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_PATH_NOT_FOUND ||
+        broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* Win9x/WinME */ ||
+        broken(GetLastError() == ERROR_ACCESS_DENIED) /* Win98 */,
+        "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
+     /* Test empty command line parameter. */
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(NULL, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
+        GetLastError() == ERROR_PATH_NOT_FOUND /* NT4 */ ||
+        GetLastError() == ERROR_BAD_PATHNAME /* Win98 */ ||
+        GetLastError() == ERROR_INVALID_PARAMETER /* Win7 */,
+        "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
+     strcpy(buffer, "doesnotexist.exe");
+     strcpy(buffer2, "does not exist.exe");
+     /* Test nonexistent application name. */
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(buffer, NULL, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(buffer2, NULL, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
+     /* Test nonexistent command line parameter. */
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
+     SetLastError(0xdeadbeef);
+     ret = CreateProcessA(NULL, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
+     ok(!ret, "CreateProcessA unexpectedly succeeded\n");
+     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
  }
  
  static void test_Directory(void)
@@@ -1231,8 -1410,14 +1410,14 @@@ static void test_Console(void
      okChildInt("Console", "InputMode", modeIn);
      okChildInt("Console", "OutputMode", modeOut);
  
 -        ok(cpInC == 1252, "Wrong console CP (expected 1252 got %d/%d)\n", cpInC, cpIn);
 -        ok(cpOutC == 1252, "Wrong console-SB CP (expected 1252 got %d/%d)\n", cpOutC, cpOut);
+     if (run_tests)
+     {
 +    ok(cpInC == 1252, "Wrong console CP (expected 1252 got %d/%d)\n", cpInC, cpIn);
 +    ok(cpOutC == 1252, "Wrong console-SB CP (expected 1252 got %d/%d)\n", cpOutC, cpOut);
+     }
+     else
+         win_skip("Setting the codepage is not implemented\n");
      ok(modeInC == (modeIn ^ 1), "Wrong console mode\n");
      ok(modeOutC == (modeOut ^ 1), "Wrong console-SB mode\n");
      trace("cursor position(X): %d/%d\n",sbi.dwCursorPosition.X, sbiC.dwCursorPosition.X);
@@@ -213,24 -267,44 +267,44 @@@ static void test_profile_sections_names
      CloseHandle( h);
  
      /* Test with sufficiently large buffer */
+     memset(buf, 0xc, sizeof(buf));
      ret = GetPrivateProfileSectionNamesA( buf, 29, testfile3 );
-     ok( ret == 27, "expected return size 27, got %d\n", ret );
-     ok( buf[ret-1] == 0 && buf[ret] == 0, "returned buffer not terminated with double-null\n" );
+     ok( ret == 27 ||
+         broken(ret == 28), /* Win9x, WinME */
+         "expected return size 27, got %d\n", ret );
+     ok( (buf[ret-1] == 0 && buf[ret] == 0) ||
+         broken(buf[ret-1] == 0 && buf[ret-2] == 0), /* Win9x, WinME */
+         "returned buffer not terminated with double-null\n" );
 -
 +    
      /* Test with exactly fitting buffer */
+     memset(buf, 0xc, sizeof(buf));
      ret = GetPrivateProfileSectionNamesA( buf, 28, testfile3 );
-     ok( ret == 26, "expected return size 26, got %d\n", ret );
-     ok( buf[ret+1] == 0 && buf[ret] == 0, "returned buffer not terminated with double-null\n" );
+     ok( ret == 26 ||
+         broken(ret == 28), /* Win9x, WinME */
+         "expected return size 26, got %d\n", ret );
+     todo_wine
+     ok( (buf[ret+1] == 0 && buf[ret] == 0) || /* W2K3 and higher */
+         broken(buf[ret+1] == 0xc && buf[ret] == 0) || /* NT4, W2K, WinXP */
+         broken(buf[ret-1] == 0 && buf[ret-2] == 0), /* Win9x, WinME */
+         "returned buffer not terminated with double-null\n" );
 -
 +    
      /* Test with a buffer too small */
+     memset(buf, 0xc, sizeof(buf));
      ret = GetPrivateProfileSectionNamesA( buf, 27, testfile3 );
      ok( ret == 25, "expected return size 25, got %d\n", ret );
-     ok( buf[ret+1] == 0 && buf[ret] == 0, "returned buffer not terminated with double-null\n" );
+     /* Win9x and WinME only fills the buffer with complete section names (double-null terminated) */
+     count = strlen("section1") + sizeof(CHAR) + strlen("section2");
+     todo_wine
+     ok( (buf[ret+1] == 0 && buf[ret] == 0) ||
+         broken(buf[count] == 0 && buf[count+1] == 0), /* Win9x, WinME */
+         "returned buffer not terminated with double-null\n" );
 -
 +    
      /* Tests on nonexistent file */
-     memset(buf, 0xcc, sizeof(buf));
+     memset(buf, 0xc, sizeof(buf));
      ret = GetPrivateProfileSectionNamesA( buf, 10, ".\\not_here.ini" );
-     ok( ret == 0, "expected return size 0, got %d\n", ret );
+     ok( ret == 0 ||
+         broken(ret == 1), /* Win9x, WinME */
+         "expected return size 0, got %d\n", ret );
      ok( buf[0] == 0, "returned buffer not terminated with null\n" );
      ok( buf[1] != 0, "returned buffer terminated with double-null\n" );
      
      ok( bufW[ret-1] == 0 && bufW[ret] == 0, "returned buffer not terminated with double-null\n" );
      
      /* Test with exactly fitting buffer */
+     memset(bufW, 0xcc, sizeof(bufW));
      ret = GetPrivateProfileSectionNamesW( bufW, 28, testfile3W );
      ok( ret == 26, "expected return size 26, got %d\n", ret );
-     ok( bufW[ret+1] == 0 && bufW[ret] == 0, "returned buffer not terminated with double-null\n" );
+     ok( (bufW[ret+1] == 0 && bufW[ret] == 0) || /* W2K3 and higher */
+         broken(bufW[ret+1] == 0xcccc && bufW[ret] == 0), /* NT4, W2K, WinXP */
+         "returned buffer not terminated with double-null\n" );
 -
 +    
      /* Test with a buffer too small */
+     memset(bufW, 0xcc, sizeof(bufW));
      ret = GetPrivateProfileSectionNamesW( bufW, 27, testfile3W );
      ok( ret == 25, "expected return size 25, got %d\n", ret );
      ok( bufW[ret+1] == 0 && bufW[ret] == 0, "returned buffer not terminated with double-null\n" );
@@@ -125,16 -125,21 +125,21 @@@ static void update_empty_exe( void 
      CloseHandle( file );
  
      res = BeginUpdateResource( filename, TRUE );
 -        ok( res != NULL, "BeginUpdateResource failed\n");
+     if ( res != NULL || GetLastError() != ERROR_FILE_INVALID )
+     {
 +    ok( res != NULL, "BeginUpdateResource failed\n");
  
 -        /* check if it's possible to open the file now */
 -        test = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
 -        ok (test != INVALID_HANDLE_VALUE, "failed to create file\n");
 +    /* check if it's possible to open the file now */
 +    test = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
 +    ok (test != INVALID_HANDLE_VALUE, "failed to create file\n");
  
 -        CloseHandle( test );
 +    CloseHandle( test );
  
 -        r = EndUpdateResource( res, FALSE );
 -        ok( r == FALSE, "EndUpdateResource failed\n");
 +    r = EndUpdateResource( res, FALSE );
 +    ok( r == FALSE, "EndUpdateResource failed\n");
+     }
+     else
+         skip( "Can't update resource in empty file\n" );
  
      res = BeginUpdateResource( filename, FALSE );
      ok( res == NULL, "BeginUpdateResource failed\n");
@@@ -173,12 -178,15 +178,15 @@@ static void update_resources_version(vo
      res = BeginUpdateResource( filename, TRUE );
      ok( res != NULL, "BeginUpdateResource failed\n");
  
 -        r = UpdateResource( res,
 -                            MAKEINTRESOURCE(0x1230),
 -                            MAKEINTRESOURCE(0x4567),
 -                            0xabcd,
 -                            NULL, 0 );
 -        ok( r == FALSE, "UpdateResource failed\n");
+     if (0)  /* this causes subsequent tests to fail on Vista */
+     {
 +    r = UpdateResource( res,
 +                        MAKEINTRESOURCE(0x1230),
 +                        MAKEINTRESOURCE(0x4567),
 +                        0xabcd,
 +                        NULL, 0 );
 +    ok( r == FALSE, "UpdateResource failed\n");
+     }
  
      r = UpdateResource( res,
                          MAKEINTRESOURCE(0x1230),
@@@ -627,10 -693,12 +693,12 @@@ static VOID test_thread_priority(void
     SetLastError(0xdeadbeef);
     rc=pGetThreadPriorityBoost(curthread,&disabled);
     if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
-      return; /* WinME */
+    {
+       win_skip("GetThreadPriorityBoost is not implemented on WinME\n");
+       return;
+    }
  
-    todo_wine
 -   ok(rc!=0,"error=%d\n",GetLastError());
 +     ok(rc!=0,"error=%d\n",GetLastError());
  
     if (pOpenThread) {
  /* check that access control is obeyed */
  
       rc = pSetThreadPriorityBoost(curthread,0);
       ok( rc != 0, "error=%d\n",GetLastError());
 -   rc=pGetThreadPriorityBoost(curthread,&disabled);
 -   ok(rc!=0 && disabled==0,
 -      "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
 -}
+    }
- }
 +     rc=pGetThreadPriorityBoost(curthread,&disabled);
 +     ok(rc!=0 && disabled==0,
 +        "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
 +   }
  
  /* check the GetThreadTimes function */
  static VOID test_GetThreadTimes(void)
@@@ -740,24 -811,26 +811,26 @@@ static VOID test_thread_processor(void
        "SetThreadAffinityMask passed for an illegal processor\n");
  /* NOTE: This only works on WinNT/2000/XP) */
     if (pSetThreadIdealProcessor) {
-      todo_wine {
-        SetLastError(0);
+      SetLastError(0xdeadbeef);
 -     error=pSetThreadIdealProcessor(curthread,0);
 +       error=pSetThreadIdealProcessor(curthread,0);
-        if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
-          ok(error!=-1, "SetThreadIdealProcessor failed\n");
-        }
+      if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
+      {
+        win_skip("SetThreadIdealProcessor is not implemented\n");
+        return;
       }
-      if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
 -     ok(error!=-1, "SetThreadIdealProcessor failed\n");
++         ok(error!=-1, "SetThreadIdealProcessor failed\n");
+      SetLastError(0xdeadbeef);
 -     error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
 -     ok(error==-1,
 -        "SetThreadIdealProcessor succeeded with an illegal processor #\n");
 +       error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
 +       ok(error==-1,
 +          "SetThreadIdealProcessor succeeded with an illegal processor #\n");
-        todo_wine {
+      ok(GetLastError()==ERROR_INVALID_PARAMETER,
+         "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
 -     error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
 -     ok(error==0, "SetThreadIdealProcessor returned an incorrect value\n");
 -   }
 -}
 +         error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
 +         ok(error==0, "SetThreadIdealProcessor returned an incorrect value\n");
 +       }
 +     }
-    }
- }
  
  static VOID test_GetThreadExitCode(void)
  {
@@@ -175,7 -170,8 +170,8 @@@ static void test_thread(DWORD curr_pid
          {
              if (te.th32OwnerProcessID == curr_pid) curr_found++;
              if (te.th32OwnerProcessID == sub_pcs_pid) sub_found++;
 -                trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
+             if (winetest_debug > 1)
 +            trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
              num++;
          } while (pThread32Next( hSnapshot, &te ));
      }
          {
              if (te.th32OwnerProcessID == curr_pid) curr_found++;
              if (te.th32OwnerProcessID == sub_pcs_pid) sub_found++;
 -                trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
+             if (winetest_debug > 1)
 +            trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
              num--;
          } while (pThread32Next( hSnapshot, &te ));
      }
@@@ -458,20 -590,23 +590,23 @@@ static void test_MapViewOfFile(void
      ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
      SetLastError(0xdeadbeef);
      ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
- todo_wine ok( !ptr, "MapViewOfFile FILE_MAP_WRITE should fail\n" );
- todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
+     if (!ptr)
+     {
+         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
 -        SetLastError(0xdeadbeef);
 -        ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
 -        ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
 -        SetLastError(0xdeadbeef);
 -        ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
 -            "VirtualQuery error %u\n", GetLastError() );
 -        ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
 -        ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
 +    SetLastError(0xdeadbeef);
 +    ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
 +    ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
 +    SetLastError(0xdeadbeef);
 +    ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
 +        "VirtualQuery error %u\n", GetLastError() );
 +    ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
 +    ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
todo_wine ok( info.AllocationProtect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.AllocationProtect );
        ok( info.AllocationProtect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.AllocationProtect );
 -        ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
 -        ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
 +    ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
 +    ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
- todo_wine ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
+         ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
+     }
+     else win_skip( "no access checks on win9x\n" );
      UnmapViewOfFile( ptr );
      CloseHandle( mapping );
  
      ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
      SetLastError(0xdeadbeef);
      ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
- todo_wine ok( !ptr, "MapViewOfFile FILE_MAP_READ should fail\n" );
- todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
+     if (!ptr)
+     {
+         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
 -        SetLastError(0xdeadbeef);
 -        ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
 -        ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
 -        SetLastError(0xdeadbeef);
 -        ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
 -            "VirtualQuery error %u\n", GetLastError() );
 -        ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
 -        ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
 -        ok( info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect );
 -        ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
 -        ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
 -        ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
 +    SetLastError(0xdeadbeef);
 +    ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
 +    ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
 +    SetLastError(0xdeadbeef);
 +    ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
 +        "VirtualQuery error %u\n", GetLastError() );
 +    ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
 +    ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
 +    ok( info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect );
 +    ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
 +    ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
 +    ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
+     }
+     else win_skip( "no access checks on win9x\n" );
      UnmapViewOfFile( ptr );
      CloseHandle( mapping );
  
      ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
      ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
      ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
-     ok(info.AllocationProtect == PAGE_READWRITE, "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
      ok(info.RegionSize == MAPPING_SIZE, "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
- todo_wine
      ok(info.State == MEM_RESERVE, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
- todo_wine
+     if (info.Type == MEM_PRIVATE)  /* win9x is different for uncommitted mappings */
+     {
+         ok(info.AllocationProtect == PAGE_NOACCESS,
+            "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info.AllocationProtect);
+         ok(info.Protect == PAGE_NOACCESS,
+            "Protect should have been PAGE_NOACCESS instead of 0x%x\n", info.Protect);
+     }
+     else
+     {
+         ok(info.AllocationProtect == PAGE_READWRITE,
+            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
 -        ok(info.Protect == 0, "Protect should have been 0 instead of 0x%x\n", info.Protect);
 -        ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
 +    ok(info.Protect == 0, "Protect should have been 0 instead of 0x%x\n", info.Protect);
 +    ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
+     }
  
-     ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READWRITE);
+     if (ptr != ptr2)
+     {
+         ret = VirtualQuery(ptr2, &info, sizeof(info));
+         ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
+         ok(info.BaseAddress == ptr2,
+            "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
+         ok(info.AllocationBase == ptr2,
+            "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
+         ok(info.AllocationProtect == PAGE_READWRITE,
+            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
+         ok(info.RegionSize == MAPPING_SIZE,
+            "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
+         ok(info.State == MEM_RESERVE,
+            "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
+         ok(info.Protect == 0,
+            "Protect should have been 0 instead of 0x%x\n", info.Protect);
+         ok(info.Type == MEM_MAPPED,
+            "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
+     }
+     ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READONLY);
      ok(ptr != NULL, "VirtualAlloc failed with error %d\n", GetLastError());
  
      ret = VirtualQuery(ptr, &info, sizeof(info));
      ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
      ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
      ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
-     ok(info.AllocationProtect == PAGE_READWRITE, "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
- todo_wine
      ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
      ok(info.State == MEM_COMMIT, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
-     ok(info.Protect == PAGE_READWRITE, "Protect should have been 0 instead of 0x%x\n", info.Protect);
+     ok(info.Protect == PAGE_READONLY, "Protect should have been 0 instead of 0x%x\n", info.Protect);
+     if (info.Type == MEM_PRIVATE)  /* win9x is different for uncommitted mappings */
+     {
+         ok(info.AllocationProtect == PAGE_NOACCESS,
+            "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info.AllocationProtect);
+     }
+     else
+     {
+         ok(info.AllocationProtect == PAGE_READWRITE,
+            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
 -        ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
 +    ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
-     ptr2 = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
-     /* on NT ptr != ptr2 but on Win9x ptr == ptr2 */
-     ok(ptr2 != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
-     trace("mapping same section resulted in views %p and %p\n", ptr, ptr2);
+     }
  
      /* shows that the VirtualAlloc above affects the mapping, not just the
       * virtual memory in this process - it also affects all other processes
       * with a view of the mapping, but that isn't tested here */
 -        ret = VirtualQuery(ptr2, &info, sizeof(info));
 -        ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
+     if (ptr != ptr2)
+     {
-     ok(info.BaseAddress == ptr2, "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
-     ok(info.AllocationBase == ptr2, "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
-     ok(info.AllocationProtect == PAGE_READWRITE, "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
- todo_wine
-     ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
-     ok(info.State == MEM_COMMIT, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
-     ok(info.Protect == PAGE_READWRITE, "Protect should have been 0 instead of 0x%x\n", info.Protect);
 +    ret = VirtualQuery(ptr2, &info, sizeof(info));
 +    ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
 -        ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
+         ok(info.BaseAddress == ptr2,
+            "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
+         ok(info.AllocationBase == ptr2,
+            "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
+         ok(info.AllocationProtect == PAGE_READWRITE,
+            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
+         ok(info.RegionSize == 0x10000,
+            "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
+         ok(info.State == MEM_COMMIT,
+            "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
+         ok(info.Protect == PAGE_READWRITE,
+            "Protect should have been 0 instead of 0x%x\n", info.Protect);
 +    ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
+     }
+     addr = VirtualAlloc( ptr, MAPPING_SIZE, MEM_RESET, PAGE_READONLY );
+     ok( addr == ptr || broken(!addr && GetLastError() == ERROR_INVALID_PARAMETER), /* win9x */
+         "VirtualAlloc failed with error %u\n", GetLastError() );
+     ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT );
+     ok( !ret || broken(ret) /* win9x */, "VirtualFree succeeded\n" );
+     if (!ret)
+         ok( GetLastError() == ERROR_INVALID_PARAMETER, "VirtualFree failed with %u\n", GetLastError() );
  
      ret = UnmapViewOfFile(ptr2);
      ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
@@@ -105,6 -144,43 +144,43 @@@ static void test_GetVolumeNameForVolume
  
      ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
      ok(ret == TRUE, "GetVolumeNameForVolumeMountPointA failed\n");
 -    }
+     ok(!strncmp( volume, "\\\\?\\Volume{", 11),
+         "GetVolumeNameForVolumeMountPointA failed to return valid string <%s>\n",
+         volume);
+     /* test with too small buffer */
+     ret = pGetVolumeNameForVolumeMountPointA(path, volume, 10);
+     ok(ret == FALSE && GetLastError() == ERROR_FILENAME_EXCED_RANGE,
+             "GetVolumeNameForVolumeMountPointA failed, wrong error returned, was %d, should be ERROR_FILENAME_EXCED_RANGE\n",
+              GetLastError());
+     /* Try on a arbitrary directory */
+     ret = pGetVolumeNameForVolumeMountPointA(temp_path, volume, len);
+     ok(ret == FALSE && GetLastError() == ERROR_NOT_A_REPARSE_POINT,
+         "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n",
+         temp_path, GetLastError());
+     /* Try on a nonexistent dos drive */
+     path[2] = 0;
+     for (;path[0] <= 'z'; path[0]++) {
+         ret = QueryDosDeviceA( path, volume, len);
+         if(!ret) break;
++}
+     if (path[0] <= 'z')
+     {
+         path[2] = '\\';
+         ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
+         ok(ret == FALSE && GetLastError() == ERROR_FILE_NOT_FOUND,
+             "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n",
+             path, GetLastError());
+         /* Try without trailing \ and on a nonexistent dos drive  */
+         path[2] = 0;
+         ret = pGetVolumeNameForVolumeMountPointA(path, volume, len);
+         ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
+             "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n",
+             path, GetLastError());
+     }
  }
  
  static void test_GetVolumeNameForVolumeMountPointW(void)
@@@ -316,13 -517,16 +517,16 @@@ static void test_EnumCodePages(IMultiLa
      ret = IEnumCodePage_Reset(iEnumCP);
      ok(ret == S_OK, "IEnumCodePage_Reset: expected S_OK, got %08x\n", ret);
      n = 65536;
-     TRACE_2("Call IEnumCodePage_Next\n");
      ret = IEnumCodePage_Next(iEnumCP, 0, NULL, &n);
 -        ok(n == 0 && ret == S_FALSE, "IEnumCodePage_Next: expected 0/S_FALSE, got %u/%08x\n", n, ret);
+     if (ret == S_FALSE)
-     TRACE_2("Call IEnumCodePage_Next\n");
 +    ok(n == 0 && ret == S_FALSE, "IEnumCodePage_Next: expected 0/S_FALSE, got %u/%08x\n", n, ret);
+     else if (ret == E_FAIL)
+         ok(n == 65536 && ret == E_FAIL, "IEnumCodePage_Next: expected 65536/E_FAIL, got %u/%08x\n", n, ret);
      ret = IEnumCodePage_Next(iEnumCP, 0, NULL, NULL);
 -        ok(ret == S_FALSE, "IEnumCodePage_Next: expected S_FALSE, got %08x\n", ret);
+     if (ret == S_FALSE)
 +    ok(ret == S_FALSE, "IEnumCodePage_Next: expected S_FALSE, got %08x\n", ret);
+     else if (ret == E_FAIL)
+         ok(n == 65536 && ret == E_FAIL, "IEnumCodePage_Next: expected 65536/E_FAIL, got %u/%08x\n", n, ret);
  
      cpinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*cpinfo) * total * 2);
  
  #endif
        ok(cpinfo[i].dwFlags & flags, "enumerated flags %08x do not include requested %08x\n", cpinfo[i].dwFlags, flags);
  
-       if (TranslateCharsetInfo((DWORD *)cpinfo[i].uiFamilyCodePage, &csi, TCI_SRCCODEPAGE))
+       if (TranslateCharsetInfo((DWORD *)(INT_PTR)cpinfo[i].uiFamilyCodePage, &csi, TCI_SRCCODEPAGE))
            ok(cpinfo[i].bGDICharset == csi.ciCharset, "%d != %d\n", cpinfo[i].bGDICharset, csi.ciCharset);
        else
 -                trace("TranslateCharsetInfo failed for cp %u\n", cpinfo[i].uiFamilyCodePage);
+             if (winetest_debug > 1)
 +          trace("TranslateCharsetInfo failed for cp %u\n", cpinfo[i].uiFamilyCodePage);
  
+ #ifdef DUMP_CP_INFO
          trace("%u: codepage %u family %u\n", i, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
+ #endif
          /* Win95 does not support UTF-7 */
          if (cpinfo[i].uiCodePage == CP_UTF7) continue;
  
            ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UNICODE -> %u) = %08x\n", cpinfo[i].uiCodePage, ret);
  
              convertible = check_convertible(iML2, cpinfo[i].uiCodePage, CP_UTF8);
-             if (!convertible)
-                 check = S_FALSE;
-           TRACE_2("Call IMultiLanguage2_IsConvertible\n");
+             if (convertible != E_FAIL)
+             {
 -                ret = IMultiLanguage2_IsConvertible(iML2, cpinfo[i].uiCodePage, CP_UTF8);
 +          ret = IMultiLanguage2_IsConvertible(iML2, cpinfo[i].uiCodePage, CP_UTF8);
-           ok(ret == check, "IMultiLanguage2_IsConvertible(%u -> CP_UTF8) = %08x\n", cpinfo[i].uiCodePage, ret);
-           TRACE_2("Call IMultiLanguage2_IsConvertible\n");
+                 ok(ret == convertible, "IMultiLanguage2_IsConvertible(%u -> CP_UTF8) = %08x\n", cpinfo[i].uiCodePage, ret);
 -                ret = IMultiLanguage2_IsConvertible(iML2, CP_UTF8, cpinfo[i].uiCodePage);
 +          ret = IMultiLanguage2_IsConvertible(iML2, CP_UTF8, cpinfo[i].uiCodePage);
-           ok(ret == check, "IMultiLanguage2_IsConvertible(CP_UTF8 -> %u) = %08x\n", cpinfo[i].uiCodePage, ret);
+                 ok(ret == convertible, "IMultiLanguage2_IsConvertible(CP_UTF8 -> %u) = %08x\n", cpinfo[i].uiCodePage, ret);
 -            }
++      }
        }
        else
 -                trace("IsValidCodePage failed for cp %u\n", cpinfo[i].uiCodePage);
+             if (winetest_debug > 1)
 +          trace("IsValidCodePage failed for cp %u\n", cpinfo[i].uiCodePage);
  
 -        ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszWebCharset, &mcsi);
 -        /* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
 -        if (memcmp(cpinfo[i].wszWebCharset, autoW, 5 * sizeof(WCHAR)))
 -        {
 -            ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
+     if (memcmp(cpinfo[i].wszWebCharset,feffW,sizeof(WCHAR)*11)==0)
+         skip("Legacy windows bug returning invalid charset of unicodeFEFF\n");
+     else
+     {
 +      ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszWebCharset, &mcsi);
 +      /* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
 +      if (memcmp(cpinfo[i].wszWebCharset, autoW, 5 * sizeof(WCHAR)))
 +      {
 +          ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
  #ifdef DUMP_CP_INFO
 -            trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszWebCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
 +          trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszWebCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
  #endif
 -            ok(!lstrcmpiW(cpinfo[i].wszWebCharset, mcsi.wszCharset),
 +          ok(!lstrcmpiW(cpinfo[i].wszWebCharset, mcsi.wszCharset),
  #ifdef DUMP_CP_INFO
 -                    "%s != %s\n",
 -            wine_dbgstr_w(cpinfo[i].wszWebCharset), wine_dbgstr_w(mcsi.wszCharset));
 +                "%s != %s\n",
 +              wine_dbgstr_w(cpinfo[i].wszWebCharset), wine_dbgstr_w(mcsi.wszCharset));
  #else
 -                    "wszWebCharset mismatch\n");
 +                "wszWebCharset mismatch\n");
  #endif
  
 -        if (0)
 -        {
 -            /* native mlang returns completely messed up encodings in some cases */
 -            ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
 -            "%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 -            ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
 -            "%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 -            }
 +      if (0)
 +      {
 +          /* native mlang returns completely messed up encodings in some cases */
 +          ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
 +              "%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 +          ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
 +              "%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
          }
 +      }
+     }
  
 -        ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszHeaderCharset, &mcsi);
 -        /* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
 -        if (memcmp(cpinfo[i].wszHeaderCharset, autoW, 5 * sizeof(WCHAR)))
 -        {
 -            ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
+     if (memcmp(cpinfo[i].wszHeaderCharset,feffW,sizeof(WCHAR)*11)==0)
+         skip("Legacy windows bug returning invalid charset of unicodeFEFF\n");
+     else
+     {
 +      ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszHeaderCharset, &mcsi);
 +      /* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
 +      if (memcmp(cpinfo[i].wszHeaderCharset, autoW, 5 * sizeof(WCHAR)))
 +      {
 +          ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
  #ifdef DUMP_CP_INFO
 -            trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszHeaderCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
 +          trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszHeaderCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
  #endif
 -            ok(!lstrcmpiW(cpinfo[i].wszHeaderCharset, mcsi.wszCharset),
 +          ok(!lstrcmpiW(cpinfo[i].wszHeaderCharset, mcsi.wszCharset),
  #ifdef DUMP_CP_INFO
 -                    "%s != %s\n",
 -            wine_dbgstr_w(cpinfo[i].wszHeaderCharset), wine_dbgstr_w(mcsi.wszCharset));
 +                "%s != %s\n",
 +              wine_dbgstr_w(cpinfo[i].wszHeaderCharset), wine_dbgstr_w(mcsi.wszCharset));
  #else
 -                    "wszHeaderCharset mismatch\n");
 +                "wszHeaderCharset mismatch\n");
  #endif
  
 -        if (0)
 -        {
 -            /* native mlang returns completely messed up encodings in some cases */
 -            ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
 -            "%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 -            ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
 -            "%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 -        }
 -        }
 +      if (0)
 +      {
 +          /* native mlang returns completely messed up encodings in some cases */
 +          ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
 +              "%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 +          ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
 +              "%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 +      }
 +      }
+     }
  
 -        ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszBodyCharset, &mcsi);
 -        /* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
 -        if (memcmp(cpinfo[i].wszBodyCharset, autoW, 5 * sizeof(WCHAR)))
 -        {
 -            ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
+     if (memcmp(cpinfo[i].wszBodyCharset,feffW,sizeof(WCHAR)*11)==0)
+         skip("Legacy windows bug returning invalid charset of unicodeFEFF\n");
+     else
+     {
 +      ret = IMultiLanguage2_GetCharsetInfo(iML2, cpinfo[i].wszBodyCharset, &mcsi);
 +      /* _autoxxx charsets are a fake and GetCharsetInfo fails for them */
 +      if (memcmp(cpinfo[i].wszBodyCharset, autoW, 5 * sizeof(WCHAR)))
 +      {
 +          ok (ret == S_OK, "IMultiLanguage2_GetCharsetInfo failed: %08x\n", ret);
  #ifdef DUMP_CP_INFO
 -            trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszBodyCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
 +          trace("%s: %u %u %s\n", wine_dbgstr_w(cpinfo[i].wszBodyCharset), mcsi.uiCodePage, mcsi.uiInternetEncoding, wine_dbgstr_w(mcsi.wszCharset));
  #endif
 -            ok(!lstrcmpiW(cpinfo[i].wszBodyCharset, mcsi.wszCharset),
 +          ok(!lstrcmpiW(cpinfo[i].wszBodyCharset, mcsi.wszCharset),
  #ifdef DUMP_CP_INFO
 -                    "%s != %s\n",
 -            wine_dbgstr_w(cpinfo[i].wszBodyCharset), wine_dbgstr_w(mcsi.wszCharset));
 +                "%s != %s\n",
 +              wine_dbgstr_w(cpinfo[i].wszBodyCharset), wine_dbgstr_w(mcsi.wszCharset));
  #else
 -                    "wszBodyCharset mismatch\n");
 +                "wszBodyCharset mismatch\n");
  #endif
  
 -        if (0)
 -        {
 -            /* native mlang returns completely messed up encodings in some cases */
 -            ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
 -            "%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 -            ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
 -            "%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 -        }
 -        }
 +      if (0)
 +      {
 +          /* native mlang returns completely messed up encodings in some cases */
 +          ok(mcsi.uiInternetEncoding == cpinfo[i].uiCodePage || mcsi.uiInternetEncoding == cpinfo[i].uiFamilyCodePage,
 +              "%u != %u || %u\n", mcsi.uiInternetEncoding, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 +          ok(mcsi.uiCodePage == cpinfo[i].uiCodePage || mcsi.uiCodePage == cpinfo[i].uiFamilyCodePage,
 +              "%u != %u || %u\n", mcsi.uiCodePage, cpinfo[i].uiCodePage, cpinfo[i].uiFamilyCodePage);
 +      }
 +      }
      }
+     }
  
      /* now IEnumCodePage_Next should fail, since pointer is at the end */
      n = 1;
@@@ -851,6 -2022,16 +2022,16 @@@ START_TEST(mlang
  
      IMLangFontLink_Test(iMLFL);
      IMLangFontLink_Release(iMLFL);
 -
 +    
+     /* IMLangFontLink2 */
+     ret = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
+                            &IID_IMLangFontLink2, (void&nb