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;
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)
{
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
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)
{
{
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);
}
}
}
/* 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;
<?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>
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);
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, ¬Null, 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)
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];
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)
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);
{
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)
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) \
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);
/* 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");
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;
}
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;
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;
}
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;
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;
}
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;
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)
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();
}
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
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)
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)
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));
/* 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);
/* 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);
/* 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);
{
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) );
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;
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.
*/
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);
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);
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);
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;
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 */
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);
}
*/
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);
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);
<?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)
{
{
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)
{
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);
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)
{
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
<?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>
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) {
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;
}
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);
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);
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)
{
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);
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);
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);
}
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");
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,
static const WCHAR unix_style_root_pathW[] = { '/', 0 };
ret = GetDiskFreeSpaceW(NULL, §ors_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());
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");
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");
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))))
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");
"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) */
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() );
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;
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() );
}
}
/* 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());
++}
}
/*
}
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;
}
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 */
<?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>
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);
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);
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));
/* 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++)
}
/* 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 */
}
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;
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)
/* 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,
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);
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");
/* 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));
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);
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");
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);
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)
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);
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" );
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");
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),
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)
"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)
{
{
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 ));
}
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());
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)
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;
IMLangFontLink_Test(iMLFL);
IMLangFontLink_Release(iMLFL);
-
+
+ /* IMLangFontLink2 */
+ ret = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMLangFontLink2, (void&nb