Sync advapi32, comctl32, crypt32, cryptui, cryptnet, fusion, gdi32, gdiplus, hlink, imm32, jscript, kernel32, localspl, msacm32, mscms, msi, mstask, msvcrtd, msxml3, ntdll, ole32, pdh, psapi, quartz, rasapi32, riched20 AND rsaenh Winetests.

TBD mshtml, shell32, oleaut32 which still fail to build here

svn path=/trunk/; revision=47931
This commit is contained in:
Daniel Reimer 2010-07-03 12:45:23 +00:00
parent 74b08b2f54
commit a15dcc4250
80 changed files with 19174 additions and 1529 deletions

View file

@ -64,7 +64,7 @@ static BOOL (WINAPI *pCryptSetHashParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
static BOOL (WINAPI *pCryptSetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD);
static BOOL (WINAPI *pCryptSetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD);
static BOOL (WINAPI *pCryptVerifySignatureW)(HCRYPTHASH, BYTE*, DWORD, HCRYPTKEY, LPCWSTR, DWORD);
static BOOL (WINAPI *pSystemFunction036)(PVOID, ULONG);
static BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG);
static void init_function_pointers(void)
{
@ -856,6 +856,8 @@ static void test_set_provider_ex(void)
{
DWORD result;
DWORD notNull = 5;
LPSTR curProvName = NULL;
DWORD curlen;
/* results */
LPSTR pszProvName = NULL;
@ -867,6 +869,13 @@ static void test_set_provider_ex(void)
return;
}
/* store the current one */
pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &curlen);
if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen)))
return;
result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen);
ok(result, "%d\n", GetLastError());
/* check pdwReserved for NULL */
result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);
ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n",
@ -880,6 +889,7 @@ static void test_set_provider_ex(void)
ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER),
"wrong error %u\n", GetLastError() );
skip("Not enough rights to remove the default provider\n");
LocalFree(curProvName);
return;
}
@ -889,13 +899,19 @@ static void test_set_provider_ex(void)
/* call CryptGetDefaultProvider to see if they match */
result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);
if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))
return;
goto reset;
result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);
ok(result && !strcmp(MS_DEF_PROV, pszProvName), "expected %s, got %s\n", MS_DEF_PROV, pszProvName);
ok(result && cbProvName==(strlen(MS_DEF_PROV) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV) + 1), cbProvName);
LocalFree(pszProvName);
reset:
/* Set the provider back to it's original */
result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);
ok(result, "%d\n", GetLastError());
LocalFree(curProvName);
}
static void test_machine_guid(void)

View file

@ -1862,7 +1862,9 @@ static void test_redirection(void)
ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err );
check_key_value( key, "Winetest", 0, ptr_size );
check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : ptr_size );
check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 );
dw = get_key_value( key, "Winetest", KEY_WOW64_32KEY );
if (ptr_size == 32) ok( dw == 32, "wrong value %u\n", dw );
else todo_wine ok( dw == 32, "wrong value %u\n", dw );
RegCloseKey( key );
if (ptr_size == 32)
@ -1910,6 +1912,79 @@ static void test_redirection(void)
RegCloseKey( root64 );
}
static void test_deleted_key(void)
{
HKEY hkey, hkey2;
char value[20];
DWORD val_count, type;
LONG res;
/* Open the test key, then delete it while it's open */
RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey );
delete_key( hkey_main );
val_count = sizeof(value);
type = 0;
res = RegEnumValueA( hkey, 0, value, &val_count, NULL, &type, 0, 0 );
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
res = RegEnumKeyA( hkey, 0, value, sizeof(value) );
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
val_count = sizeof(value);
type = 0;
res = RegQueryValueExA( hkey, "test", NULL, &type, (BYTE *)value, &val_count );
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
res = RegSetValueExA( hkey, "test", 0, REG_SZ, (const BYTE*)"value", 6);
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
res = RegOpenKeyA( hkey, "test", &hkey2 );
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
if (res == 0)
RegCloseKey( hkey2 );
res = RegCreateKeyA( hkey, "test", &hkey2 );
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
if (res == 0)
RegCloseKey( hkey2 );
res = RegFlushKey( hkey );
ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res);
RegCloseKey( hkey );
setup_main_key();
}
static void test_delete_value(void)
{
LONG res;
char longname[401];
res = RegSetValueExA( hkey_main, "test", 0, REG_SZ, (const BYTE*)"value", 6 );
ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %i\n", res);
res = RegQueryValueExA( hkey_main, "test", NULL, NULL, NULL, NULL);
ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %i\n", res);
res = RegDeleteValueA( hkey_main, "test" );
ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %i\n", res);
res = RegQueryValueExA( hkey_main, "test", NULL, NULL, NULL, NULL);
ok(res == ERROR_FILE_NOT_FOUND, "expect ERROR_FILE_NOT_FOUND, got %i\n", res);
res = RegDeleteValueA( hkey_main, "test" );
ok(res == ERROR_FILE_NOT_FOUND, "expect ERROR_FILE_NOT_FOUND, got %i\n", res);
memset(longname, 'a', 400);
longname[400] = 0;
res = RegDeleteValueA( hkey_main, longname );
ok(res == ERROR_FILE_NOT_FOUND || broken(res == ERROR_MORE_DATA), /* nt4, win2k */
"expect ERROR_FILE_NOT_FOUND, got %i\n", res);
}
START_TEST(registry)
{
/* Load pointers for functions that are not available in all Windows versions */
@ -1944,6 +2019,8 @@ START_TEST(registry)
test_reg_delete_tree();
test_rw_order();
test_deleted_key();
test_delete_value();
/* cleanup */
delete_key( hkey_main );

View file

@ -656,7 +656,7 @@ static void test_lookupPrivilegeValue(void)
{ "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
};
BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
int i;
unsigned int i;
LUID luid;
BOOL ret;
@ -913,13 +913,13 @@ static void test_AccessCheck(void)
/* SD without owner/group */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, KEY_QUERY_VALUE, &Mapping,
PrivSet, &PrivSetLen, &Access, &AccessStatus);
err = GetLastError();
ok(!ret && err == ERROR_INVALID_SECURITY_DESCR, "AccessCheck should have "
"failed with ERROR_INVALID_SECURITY_DESCR, instead of %d\n", err);
ok(Access == 0xdeadbeef && AccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* Set owner and group */
@ -930,50 +930,50 @@ static void test_AccessCheck(void)
/* Generic access mask */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
PrivSet, &PrivSetLen, &Access, &AccessStatus);
err = GetLastError();
ok(!ret && err == ERROR_GENERIC_NOT_MAPPED, "AccessCheck should have failed "
"with ERROR_GENERIC_NOT_MAPPED, instead of %d\n", err);
ok(Access == 0xdeadbeef && AccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* Generic access mask - no privilegeset buffer */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
NULL, &PrivSetLen, &Access, &AccessStatus);
err = GetLastError();
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
"with ERROR_NOACCESS, instead of %d\n", err);
ok(Access == 0xdeadbeef && AccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* Generic access mask - no returnlength */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
PrivSet, NULL, &Access, &AccessStatus);
err = GetLastError();
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
"with ERROR_NOACCESS, instead of %d\n", err);
ok(Access == 0xdeadbeef && AccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* Generic access mask - no privilegeset buffer, no returnlength */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
NULL, NULL, &Access, &AccessStatus);
err = GetLastError();
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
"with ERROR_NOACCESS, instead of %d\n", err);
ok(Access == 0xdeadbeef && AccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* sd with no dacl present */
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = SetSecurityDescriptorDacl(SecurityDescriptor, FALSE, NULL, FALSE);
ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
@ -985,20 +985,20 @@ static void test_AccessCheck(void)
/* sd with no dacl present - no privilegeset buffer */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
NULL, &PrivSetLen, &Access, &AccessStatus);
err = GetLastError();
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
"with ERROR_NOACCESS, instead of %d\n", err);
ok(Access == 0xdeadbeef && AccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
if(pNtAccessCheck)
{
/* Generic access mask - no privilegeset buffer */
SetLastError(0xdeadbeef);
Access = ntAccessStatus = 0xdeadbeef;
Access = ntAccessStatus = 0x1abe11ed;
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
NULL, &PrivSetLen, &Access, &ntAccessStatus);
err = GetLastError();
@ -1006,12 +1006,12 @@ static void test_AccessCheck(void)
"NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
ok(err == 0xdeadbeef,
"NtAccessCheck shouldn't set last error, got %d\n", err);
ok(Access == 0xdeadbeef && ntAccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* Generic access mask - no returnlength */
SetLastError(0xdeadbeef);
Access = ntAccessStatus = 0xdeadbeef;
Access = ntAccessStatus = 0x1abe11ed;
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
PrivSet, NULL, &Access, &ntAccessStatus);
err = GetLastError();
@ -1019,12 +1019,12 @@ static void test_AccessCheck(void)
"NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
ok(err == 0xdeadbeef,
"NtAccessCheck shouldn't set last error, got %d\n", err);
ok(Access == 0xdeadbeef && ntAccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
/* Generic access mask - no privilegeset buffer, no returnlength */
SetLastError(0xdeadbeef);
Access = ntAccessStatus = 0xdeadbeef;
Access = ntAccessStatus = 0x1abe11ed;
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
NULL, NULL, &Access, &ntAccessStatus);
err = GetLastError();
@ -1032,14 +1032,14 @@ static void test_AccessCheck(void)
"NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
ok(err == 0xdeadbeef,
"NtAccessCheck shouldn't set last error, got %d\n", err);
ok(Access == 0xdeadbeef && ntAccessStatus == 0xdeadbeef,
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
"Access and/or AccessStatus were changed!\n");
}
else
win_skip("NtAccessCheck unavailable. Skipping.\n");
/* sd with NULL dacl */
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, NULL, FALSE);
ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
@ -1067,7 +1067,7 @@ static void test_AccessCheck(void)
ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError());
/* sd with dacl */
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
PrivSet, &PrivSetLen, &Access, &AccessStatus);
ok(ret, "AccessCheck failed with error %d\n", GetLastError());
@ -1085,7 +1085,7 @@ static void test_AccessCheck(void)
/* Access denied by SD */
SetLastError(0xdeadbeef);
Access = AccessStatus = 0xdeadbeef;
Access = AccessStatus = 0x1abe11ed;
ret = AccessCheck(SecurityDescriptor, Token, KEY_WRITE, &Mapping,
PrivSet, &PrivSetLen, &Access, &AccessStatus);
ok(ret, "AccessCheck failed with error %d\n", GetLastError());
@ -1420,7 +1420,7 @@ static void test_CreateWellKnownSid(void)
PSID domainsid, sid;
DWORD size, error;
BOOL ret;
int i;
unsigned int i;
if (!pCreateWellKnownSid)
{
@ -1466,13 +1466,13 @@ static void test_CreateWellKnownSid(void)
cb = sizeof(sid_buffer);
if (!pCreateWellKnownSid(i, domainsid, sid_buffer, &cb))
{
skip("Well known SIDs starting from %d are not implemented\n", i);
skip("Well known SIDs starting from %u are not implemented\n", i);
break;
}
}
cb = sizeof(sid_buffer);
ok(pCreateWellKnownSid(i, value->without_domain ? NULL : domainsid, sid_buffer, &cb), "Couldn't create well known sid %d\n", i);
ok(pCreateWellKnownSid(i, value->without_domain ? NULL : domainsid, sid_buffer, &cb), "Couldn't create well known sid %u\n", i);
expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d");
ok(IsValidSid(sid_buffer), "The sid is not valid\n");
ok(pConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n");
@ -1484,9 +1484,9 @@ static void test_CreateWellKnownSid(void)
{
char buf2[SECURITY_MAX_SID_SIZE];
cb = sizeof(buf2);
ok(pCreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %d with optional domain\n", i);
ok(pCreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %u with optional domain\n", i);
expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d");
ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%d)\n", i);
ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%u)\n", i);
}
}
@ -2674,7 +2674,7 @@ static void test_ConvertStringSecurityDescriptor(void)
BOOL ret;
PSECURITY_DESCRIPTOR pSD;
static const WCHAR Blank[] = { 0 };
int i;
unsigned int i;
static const struct
{
const char *sidstring;
@ -2733,11 +2733,11 @@ static void test_ConvertStringSecurityDescriptor(void)
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
cssd[i].sidstring, cssd[i].revision, &pSD, NULL);
GLE = GetLastError();
ok(ret == cssd[i].ret, "(%02d) Expected %s (%d)\n", i, cssd[i].ret ? "success" : "failure", GLE);
ok(ret == cssd[i].ret, "(%02u) Expected %s (%d)\n", i, cssd[i].ret ? "success" : "failure", GLE);
if (!cssd[i].ret)
ok(GLE == cssd[i].GLE ||
(cssd[i].altGLE && GLE == cssd[i].altGLE),
"(%02d) Unexpected last error %d\n", i, GLE);
"(%02u) Unexpected last error %d\n", i, GLE);
if (ret)
LocalFree(pSD);
}
@ -2807,12 +2807,12 @@ static void test_ConvertSecurityDescriptorToString(void)
* don't replicate this feature so we only test len >= strlen+1. */
#define CHECK_RESULT_AND_FREE(exp_str) \
ok(strcmp(string, (exp_str)) == 0, "String mismatch (expected \"%s\", got \"%s\")\n", (exp_str), string); \
ok(len >= (lstrlen(exp_str) + 1), "Length mismatch (expected %d, got %d)\n", lstrlen(exp_str) + 1, len); \
ok(len >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %d)\n", lstrlen(exp_str) + 1, len); \
LocalFree(string);
#define CHECK_ONE_OF_AND_FREE(exp_str1, exp_str2) \
ok(strcmp(string, (exp_str1)) == 0 || strcmp(string, (exp_str2)) == 0, "String mismatch (expected\n\"%s\" or\n\"%s\", got\n\"%s\")\n", (exp_str1), (exp_str2), string); \
ok(len >= (strlen(string) + 1), "Length mismatch (expected %d, got %d)\n", lstrlen(string) + 1, len); \
ok(len >= (strlen(exp_str1) + 1) || len >= (strlen(exp_str2) + 1), "Length mismatch (expected %d or %d, got %d)\n", lstrlen(exp_str1) + 1, lstrlen(exp_str2) + 1, len); \
LocalFree(string);
InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION);

View file

@ -126,6 +126,7 @@ static HIMAGELIST createImageList(int cx, int cy)
HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
ImageList_Add(himl, hbm, NULL);
DeleteObject(hbm);
return himl;
}
@ -831,7 +832,7 @@ static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
#endif
}
static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max)
static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow)
{
const ILHEAD *ilh = (const ILHEAD *)ilh_data;
@ -839,7 +840,7 @@ static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT
ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
ok(ilh->cGrow == 4, "wrong cGrow %d (expected 4)\n", ilh->cGrow);
ok(ilh->cGrow == grow, "wrong cGrow %d (expected %d)\n", ilh->cGrow, grow);
ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
@ -892,38 +893,20 @@ static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment
return hbmp;
}
static void image_list_init(HIMAGELIST himl)
{
HBITMAP hbm;
char comment[16];
INT n = 1;
#define add_bitmap(grey) \
sprintf(comment, "%d", n++); \
hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
ImageList_Add(himl, hbm, NULL);
add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
#undef add_bitmap
}
#define iml_clear_stream_data() \
HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
Test_Stream.iml_data = NULL; \
Test_Stream.iml_data_size = 0;
static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max,
static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow,
INT width, INT height, INT bpp, const char *comment)
{
INT ret, cxx, cyy;
trace("%s\n", comment);
ret = ImageList_GetImageCount(himl);
ok(ret == cur, "expected cur %d got %d\n", cur, ret);
ok(ret == cur, "expected image count %d got %d\n", cur, ret);
ret = ImageList_GetIconSize(himl, &cxx, &cyy);
ok(ret, "ImageList_GetIconSize failed\n");
@ -937,57 +920,191 @@ static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max,
ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max);
check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow);
check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
Test_Stream.iml_data_size - sizeof(ILHEAD),
width, height, bpp, comment);
}
static void image_list_init(HIMAGELIST himl)
{
HBITMAP hbm;
char comment[16];
INT n = 1, i;
static const struct test_data
{
BYTE grey;
INT cx, cy, cur, max, grow, width, height, bpp;
const char *comment;
} td[] =
{
{ 255, BMP_CX, BMP_CX, 1, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 1" },
{ 170, BMP_CX, BMP_CX, 2, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 2" },
{ 85, BMP_CX, BMP_CX, 3, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 3" },
{ 0, BMP_CX, BMP_CX, 4, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 4" },
{ 0, BMP_CX, BMP_CX, 5, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 5" },
{ 85, BMP_CX, BMP_CX, 6, 7, 4, BMP_CX * 4, BMP_CX * 2, 24, "total 6" },
{ 170, BMP_CX, BMP_CX, 7, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 7" },
{ 255, BMP_CX, BMP_CX, 8, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 8" },
{ 255, BMP_CX, BMP_CX, 9, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 9" },
{ 170, BMP_CX, BMP_CX, 10, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 10" },
{ 85, BMP_CX, BMP_CX, 11, 12, 4, BMP_CX * 4, BMP_CX * 3, 24, "total 11" },
{ 0, BMP_CX, BMP_CX, 12, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 12" },
{ 0, BMP_CX, BMP_CX, 13, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 13" },
{ 85, BMP_CX, BMP_CX, 14, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 14" },
{ 170, BMP_CX, BMP_CX, 15, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 15" },
{ 255, BMP_CX, BMP_CX, 16, 17, 4, BMP_CX * 4, BMP_CX * 5, 24, "total 16" },
{ 255, BMP_CX, BMP_CX, 17, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 17" },
{ 170, BMP_CX, BMP_CX, 18, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 18" },
{ 85, BMP_CX, BMP_CX, 19, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 19" },
{ 0, BMP_CX, BMP_CX, 20, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 20" },
{ 0, BMP_CX, BMP_CX, 21, 22, 4, BMP_CX * 4, BMP_CX * 6, 24, "total 21" },
{ 85, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 22" },
{ 170, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 23" },
{ 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" }
};
check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 0");
#define add_bitmap(grey) \
sprintf(comment, "%d", n++); \
hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
ImageList_Add(himl, hbm, NULL); \
DeleteObject(hbm);
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
{
add_bitmap(td[i].grey);
check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, td[i].grow,
td[i].width, td[i].height, td[i].bpp, td[i].comment);
}
#undef add_bitmap
}
static void test_imagelist_storage(void)
{
HIMAGELIST himl;
BOOL ret;
HBITMAP hbm;
INT ret;
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, BMP_CX * 4, BMP_CX * 1, 24, "empty");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "empty");
image_list_init(himl);
check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, BMP_CX * 4, BMP_CX * 7, 24, "orig");
check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "orig");
ret = ImageList_Remove(himl, 4);
ok(ret, "ImageList_Remove failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, BMP_CX * 4, BMP_CX * 7, 24, "1");
check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "1");
ret = ImageList_Remove(himl, 5);
ok(ret, "ImageList_Remove failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, BMP_CX * 4, BMP_CX * 7, 24, "2");
check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "2");
ret = ImageList_Remove(himl, 6);
ok(ret, "ImageList_Remove failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, BMP_CX * 4, BMP_CX * 7, 24, "3");
check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "3");
ret = ImageList_Remove(himl, 7);
ok(ret, "ImageList_Remove failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "4");
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "4");
ret = ImageList_Remove(himl, -2);
ok(!ret, "ImageList_Remove(-2) should fail\n");
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "5");
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "5");
ret = ImageList_Remove(himl, 20);
ok(!ret, "ImageList_Remove(20) should fail\n");
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "6");
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "6");
ret = ImageList_Remove(himl, -1);
ok(ret, "ImageList_Remove(-1) failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
/* test ImageList_Create storage allocation */
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, 24, "init 0 grow 32");
hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9");
ret = ImageList_Add(himl, hbm, NULL);
ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, 24, "add 1 x 9");
DeleteObject(hbm);
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 4");
hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9");
ret = ImageList_Add(himl, hbm, NULL);
ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret);
check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "add 9 x 1");
ret = ImageList_Add(himl, hbm, NULL);
ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret);
check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, 24, "add 9 x 1");
DeleteObject(hbm);
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, 24, "init 207 grow 209");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, 24, "init 209 grow 207");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "init 14 grow 4");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, 24, "init 5 grow 9");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, 24, "init 9 grow 5");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, 24, "init 2 grow 4");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2);
ok(himl != 0, "ImageList_Create failed\n");
check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 2");
ret = ImageList_Destroy(himl);
ok(ret, "ImageList_Destroy failed\n");
iml_clear_stream_data();
}
static void test_shell_imagelist(void)

View file

@ -371,6 +371,7 @@ static void test_wiznavigation(void)
DestroyWindow(hdlg);
}
static void test_buttons(void)
{
HPROPSHEETPAGE hpsp[1];
@ -436,6 +437,94 @@ static void test_buttons(void)
DestroyWindow(hdlg);
}
static BOOL add_button_has_been_pressed;
static INT_PTR CALLBACK
page_with_custom_default_button_dlg_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_COMMAND:
switch(LOWORD(wparam))
{
case IDC_PS_PUSHBUTTON1:
switch(HIWORD(wparam))
{
case BN_CLICKED:
add_button_has_been_pressed = TRUE;
return TRUE;
}
break;
}
break;
}
return FALSE;
}
static void test_custom_default_button(void)
{
HWND hdlg;
PROPSHEETPAGEA psp[1];
PROPSHEETHEADERA psh;
MSG msg;
LRESULT result;
psp[0].dwSize = sizeof (PROPSHEETPAGEA);
psp[0].dwFlags = PSP_USETITLE;
psp[0].hInstance = GetModuleHandleA(NULL);
U(psp[0]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON);
U2(psp[0]).pszIcon = NULL;
psp[0].pfnDlgProc = page_with_custom_default_button_dlg_proc;
psp[0].pszTitle = "Page1";
psp[0].lParam = 0;
psh.dwSize = sizeof (PROPSHEETHEADERA);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS;
psh.hwndParent = GetDesktopWindow();
psh.hInstance = GetModuleHandleA(NULL);
U(psh).pszIcon = NULL;
psh.pszCaption = "PropertySheet1";
psh.nPages = 1;
U3(psh).ppsp = psp;
U2(psh).nStartPage = 0;
/* The goal of the test is to make sure that the Add button is pressed
* when the ENTER key is pressed and a different control, a combobox,
* has the keyboard focus. */
add_button_has_been_pressed = FALSE;
/* Create the modeless property sheet. */
hdlg = (HWND)PropertySheetA(&psh);
ok(hdlg != INVALID_HANDLE_VALUE, "Cannot create the property sheet\n");
/* Set the Add button as the default button. */
SendMessage(hdlg, DM_SETDEFID, (WPARAM)IDC_PS_PUSHBUTTON1, 0);
/* Make sure the default button is the Add button. */
result = SendMessage(hdlg, DM_GETDEFID, 0, 0);
ok(DC_HASDEFID == HIWORD(result), "The property sheet does not have a default button\n");
ok(IDC_PS_PUSHBUTTON1 == LOWORD(result), "The default button is not the Add button\n");
/* At this point, the combobox should have keyboard focus, so we press ENTER.
* Pull the lever, Kronk! */
keybd_event(VK_RETURN, 0, 0, 0);
/* Process all the messages in the queue for this thread. */
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (!PropSheet_IsDialogMessage(hdlg, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
todo_wine
ok(add_button_has_been_pressed, "The Add button has not been pressed!\n");
DestroyWindow(hdlg);
}
START_TEST(propsheet)
{
test_title();
@ -443,4 +532,5 @@ START_TEST(propsheet)
test_disableowner();
test_wiznavigation();
test_buttons();
test_custom_default_button();
}

View file

@ -925,6 +925,36 @@ static HWND create_parent_window(void)
return hwnd;
}
static void test_showband(void)
{
HWND hRebar;
REBARBANDINFOA rbi;
BOOL ret;
hRebar = create_rebar_control();
/* no bands */
ret = SendMessageA(hRebar, RB_SHOWBAND, 0, TRUE);
ok(ret == FALSE, "got %d\n", ret);
rbi.cbSize = REBARBANDINFOA_V6_SIZE;
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
rbi.cx = 200;
rbi.cxMinChild = 100;
rbi.cyMinChild = 30;
rbi.hwndChild = NULL;
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
/* index out of range */
ret = SendMessageA(hRebar, RB_SHOWBAND, 1, TRUE);
ok(ret == FALSE, "got %d\n", ret);
ret = SendMessageA(hRebar, RB_SHOWBAND, 0, TRUE);
ok(ret == TRUE, "got %d\n", ret);
DestroyWindow(hRebar);
}
START_TEST(rebar)
{
HMODULE hComctl32;
@ -948,6 +978,7 @@ START_TEST(rebar)
test_bandinfo();
test_colors();
test_showband();
if(!is_font_installed("System") || !is_font_installed("Tahoma"))
{

View file

@ -36,9 +36,14 @@
#define IDD_PROP_PAGE_RADIO 32
#define IDD_PROP_PAGE_EXIT 33
#define IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON 34
#define IDC_PS_EDIT1 1000
#define IDC_PS_EDIT2 1001
#define IDC_PS_RADIO1 1010
#define IDC_PS_RADIO2 1011
#define IDC_PS_COMBO1 1020
#define IDC_PS_PUSHBUTTON1 1021
#endif /* __WINE_COMCTL32_TEST_RESOURCES_H */

View file

@ -79,3 +79,11 @@ IDB_BITMAP_128x15 BITMAP bmp128x15.bmp
/* @makedep: bmp80x15.bmp */
IDB_BITMAP_80x15 BITMAP bmp80x15.bmp
IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON DIALOG DISCARDABLE 5, 43, 227, 215
STYLE WS_CHILD | WS_DISABLED
FONT 8, "MS Shell Dlg"
{
COMBOBOX IDC_PS_COMBO1, 16, 68, 140, 14, CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Add", IDC_PS_PUSHBUTTON1, 164, 68, 40, 13
}

View file

@ -34,12 +34,13 @@
const char *TEST_CALLBACK_TEXT = "callback_text";
#define NUM_MSG_SEQUENCES 1
#define NUM_MSG_SEQUENCES 2
#define TREEVIEW_SEQ_INDEX 0
#define PARENT_SEQ_INDEX 1
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
static struct msg_sequence *MsgSequences[NUM_MSG_SEQUENCES];
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
static const struct message FillRootSeq[] = {
{ TVM_INSERTITEM, sent },
@ -184,6 +185,16 @@ static const struct message test_get_set_unicodeformat_seq[] = {
{ 0 }
};
static const struct message parent_expand_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDING },
{ WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDED },
{ 0 }
};
static const struct message empty_seq[] = {
{ 0 }
};
static HWND hMainWnd;
static HTREEITEM hRoot, hChild;
@ -233,7 +244,7 @@ static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LP
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
add_message(MsgSequences, TREEVIEW_SEQ_INDEX, &msg);
add_message(sequences, TREEVIEW_SEQ_INDEX, &msg);
defwndproc_counter++;
ret = CallWindowProcA(lpOldProc, hwnd, message, wParam, lParam);
@ -286,7 +297,7 @@ static void test_fillroot(void)
hTree = create_treeview_control();
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
fill_tree(hTree);
@ -296,7 +307,7 @@ static void test_fillroot(void)
AddItem('B');
assert(hChild);
AddItem('.');
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, FillRootSeq, "FillRoot", FALSE);
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, FillRootSeq, "FillRoot", FALSE);
ok(!strcmp(sequence, "AB."), "Item creation\n");
/* UMLPad 1.15 depends on this being not -1 (I_IMAGECALLBACK) */
@ -386,7 +397,7 @@ static void test_select(void)
fill_tree(hTree);
/* root-none select tests */
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
r = TreeView_SelectItem(hTree, NULL);
expect(TRUE, r);
Clear();
@ -407,11 +418,11 @@ static void test_select(void)
expect(TRUE, r);
AddItem('.');
ok(!strcmp(sequence, "1(nR)nR23(Rn)Rn45(nR)nR."), "root-none select test\n");
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, rootnone_select_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, rootnone_select_seq,
"root-none select seq", FALSE);
/* root-child select tests */
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
r = TreeView_SelectItem(hTree, NULL);
expect(TRUE, r);
@ -433,7 +444,7 @@ static void test_select(void)
expect(TRUE, r);
AddItem('.');
ok(!strcmp(sequence, "1(nR)nR23(RC)RC45(CR)CR."), "root-child select test\n");
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, rootchild_select_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, rootchild_select_seq,
"root-child select seq", FALSE);
DestroyWindow(hTree);
@ -452,7 +463,7 @@ static void test_getitemtext(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* add an item without TVIF_TEXT mask and pszText == NULL */
ins.hParent = hRoot;
@ -472,7 +483,7 @@ static void test_getitemtext(void)
SendMessageA( hTree, TVM_GETITEM, 0, (LPARAM)&tvi );
ok(!strcmp(szBuffer, ""), "szBuffer=\"%s\", expected \"\"\n", szBuffer);
ok(SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild), "DeleteItem failed\n");
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, getitemtext_seq, "get item text seq", FALSE);
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, getitemtext_seq, "get item text seq", FALSE);
DestroyWindow(hTree);
}
@ -489,7 +500,7 @@ static void test_focus(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* This test verifies that when a label is being edited, scrolling
* the treeview does not cause the label to lose focus. To test
@ -513,7 +524,7 @@ static void test_focus(void)
hEdit = TreeView_EditLabel(hTree, hChild);
ScrollWindowEx(hTree, -10, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN);
ok(GetFocus() == hEdit, "Edit control should have focus\n");
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, focus_seq, "focus test", TRUE);
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, focus_seq, "focus test", TRUE);
DestroyWindow(hTree);
}
@ -526,7 +537,7 @@ static void test_get_set_bkcolor(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* If the value is -1, the control is using the system color for the background color. */
crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 );
@ -545,7 +556,7 @@ static void test_get_set_bkcolor(void)
/* Reset the default background */
SendMessage( hTree, TVM_SETBKCOLOR, 0, -1 );
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_bkcolor_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_bkcolor_seq,
"test get set bkcolor", FALSE);
DestroyWindow(hTree);
@ -559,7 +570,7 @@ static void test_get_set_imagelist(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* Test a NULL HIMAGELIST */
SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList );
@ -568,7 +579,7 @@ static void test_get_set_imagelist(void)
/* TODO: Test an actual image list */
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_imagelist_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_imagelist_seq,
"test get imagelist", FALSE);
DestroyWindow(hTree);
@ -584,7 +595,7 @@ static void test_get_set_indent(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* Finding the minimum indent */
SendMessage( hTree, TVM_SETINDENT, 0, 0 );
@ -596,7 +607,7 @@ static void test_get_set_indent(void)
ulIndent = (DWORD)SendMessage( hTree, TVM_GETINDENT, 0, 0 );
ok(ulIndent == ulMoreThanTwiceMin, "Indent reported as %d, expected %d\n", ulIndent, ulMoreThanTwiceMin);
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_indent_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_indent_seq,
"test get set indent", FALSE);
DestroyWindow(hTree);
@ -610,13 +621,13 @@ static void test_get_set_insertmark(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
SendMessage( hTree, TVM_SETINSERTMARKCOLOR, 0, crColor );
crColor = (COLORREF)SendMessage( hTree, TVM_GETINSERTMARKCOLOR, 0, 0 );
ok(crColor == RGB(0,0,0), "Insert mark color reported as 0x%.8x, expected 0x00000000\n", crColor);
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_insertmarkcolor_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_insertmarkcolor_seq,
"test get set insertmark color", FALSE);
DestroyWindow(hTree);
@ -632,7 +643,7 @@ static void test_get_set_item(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* Test the root item */
tviRoot.hItem = hRoot;
@ -654,7 +665,7 @@ static void test_get_set_item(void)
strncpy(szBuffer, "Root", nBufferSize);
SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot );
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq,
"test get set item", FALSE);
DestroyWindow(hTree);
@ -669,7 +680,7 @@ static void test_get_set_itemheight(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* Assuming default height to begin with */
ulOldHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 );
@ -689,7 +700,7 @@ static void test_get_set_itemheight(void)
ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 );
ok(ulNewHeight == 8, "Uneven height not set properly, reported %d, expected %d\n", ulNewHeight, 8);
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_itemheight_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_itemheight_seq,
"test get set item height", FALSE);
DestroyWindow(hTree);
@ -704,13 +715,13 @@ static void test_get_set_scrolltime(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
SendMessage( hTree, TVM_SETSCROLLTIME, ulExpectedTime, 0 );
ulTime = (int)SendMessage( hTree, TVM_GETSCROLLTIME, 0, 0 );
ok(ulTime == ulExpectedTime, "Scroll time reported as %d, expected %d\n", ulTime, ulExpectedTime);
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_scrolltime_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_scrolltime_seq,
"test get set scroll time", FALSE);
DestroyWindow(hTree);
@ -725,7 +736,7 @@ static void test_get_set_textcolor(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 );
ok(crColor == -1, "Default text color reported as 0x%.8x\n", crColor);
@ -743,7 +754,7 @@ static void test_get_set_textcolor(void)
/* Reset the default text color */
SendMessage( hTree, TVM_SETTEXTCOLOR, 0, CLR_NONE );
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_textcolor_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_textcolor_seq,
"test get set text color", FALSE);
DestroyWindow(hTree);
@ -758,7 +769,7 @@ static void test_get_set_tooltips(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */
hPopupTreeView = CreateWindow(WC_TREEVIEW, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100, hMainWnd, NULL, NULL, NULL);
@ -769,7 +780,7 @@ static void test_get_set_tooltips(void)
hwndLastToolTip = (HWND)SendMessage( hTree, TVM_GETTOOLTIPS, 0, 0 );
ok(hwndLastToolTip == NULL, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip);
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_tooltips_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_tooltips_seq,
"test get set tooltips", TRUE);
/* TODO: Add a test of an actual tooltip */
@ -785,7 +796,7 @@ static void test_get_set_unicodeformat(void)
hTree = create_treeview_control();
fill_tree(hTree);
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
/* Set to Unicode */
bPreviousSetting = (BOOL)SendMessage( hTree, TVM_SETUNICODEFORMAT, 1, 0 );
@ -800,54 +811,131 @@ static void test_get_set_unicodeformat(void)
/* Revert to original setting */
SendMessage( hTree, TVM_SETUNICODEFORMAT, bPreviousSetting, 0 );
ok_sequence(MsgSequences, TREEVIEW_SEQ_INDEX, test_get_set_unicodeformat_seq,
ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_unicodeformat_seq,
"test get set unicode format", FALSE);
DestroyWindow(hTree);
}
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
static TVITEMA g_item_expanding, g_item_expanded;
static BOOL g_get_from_expand;
static BOOL g_get_rect_in_expand;
static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(msg) {
static LONG defwndproc_counter = 0;
struct message msg;
LRESULT ret;
RECT rect;
HTREEITEM visibleItem;
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
/* log system messages, except for painting */
if (message < WM_USER &&
message != WM_PAINT &&
message != WM_ERASEBKGND &&
message != WM_NCPAINT &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
message != WM_GETICON &&
message != WM_DEVICECHANGE)
{
trace("parent: %p, %04x, %08lx, %08lx\n", hWnd, message, wParam, lParam);
add_message(sequences, PARENT_SEQ_INDEX, &msg);
}
switch(message) {
case WM_NOTIFY:
{
NMHDR *pHdr = (NMHDR *)lParam;
ok(pHdr->code != NM_FIRST - 19, "Treeview should not send NM_TOOLTIPSCREATED\n");
if (pHdr->idFrom == 100) {
ok(pHdr->code != NM_TOOLTIPSCREATED, "Treeview should not send NM_TOOLTIPSCREATED\n");
if (pHdr->idFrom == 100)
{
NMTREEVIEWA *pTreeView = (LPNMTREEVIEWA) lParam;
switch(pHdr->code) {
switch(pHdr->code)
{
case TVN_SELCHANGINGA:
AddItem('(');
IdentifyItem(pTreeView->itemOld.hItem);
IdentifyItem(pTreeView->itemNew.hItem);
return 0;
break;
case TVN_SELCHANGEDA:
AddItem(')');
IdentifyItem(pTreeView->itemOld.hItem);
IdentifyItem(pTreeView->itemNew.hItem);
return 0;
break;
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;
break;
}
case TVN_ENDLABELEDIT: return TRUE;
case TVN_ITEMEXPANDING:
ok(pTreeView->itemNew.mask ==
(TVIF_HANDLE | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_PARAM | TVIF_STATE),
"got wrong mask %x\n", pTreeView->itemNew.mask);
ok((pTreeView->itemNew.state & TVIS_EXPANDED) == 0,
"got wrong state %x\n", pTreeView->itemNew.state);
ok(pTreeView->itemOld.mask == 0,
"got wrong mask %x\n", pTreeView->itemOld.mask);
if (g_get_from_expand)
{
g_item_expanding.mask = TVIF_STATE;
g_item_expanding.hItem = hRoot;
ret = SendMessageA(pHdr->hwndFrom, TVM_GETITEMA, 0, (LPARAM)&g_item_expanding);
ok(ret == TRUE, "got %lu\n", ret);
}
break;
case TVN_ITEMEXPANDED:
ok(pTreeView->itemNew.mask & TVIF_STATE, "got wrong mask %x\n", pTreeView->itemNew.mask);
ok(pTreeView->itemNew.state & (TVIS_EXPANDED|TVIS_EXPANDEDONCE),
"got wrong mask %x\n", pTreeView->itemNew.mask);
ok(pTreeView->itemOld.mask == 0,
"got wrong mask %x\n", pTreeView->itemOld.mask);
if (g_get_from_expand)
{
g_item_expanded.mask = TVIF_STATE;
g_item_expanded.hItem = hRoot;
ret = SendMessageA(pHdr->hwndFrom, TVM_GETITEMA, 0, (LPARAM)&g_item_expanded);
ok(ret == TRUE, "got %lu\n", ret);
}
if (g_get_rect_in_expand) {
visibleItem = TreeView_GetNextItem(pHdr->hwndFrom, NULL, TVGN_FIRSTVISIBLE);
ok(pTreeView->itemNew.hItem == visibleItem, "expanded item == first visible item\n");
*(HTREEITEM*)&rect = visibleItem;
ok(SendMessage(pHdr->hwndFrom, TVM_GETITEMRECT, TRUE, (LPARAM)&rect), "Failed to get rect for first visible item.\n");
visibleItem = TreeView_GetNextItem(pHdr->hwndFrom, visibleItem, TVGN_NEXTVISIBLE);
*(HTREEITEM*)&rect = visibleItem;
ok(visibleItem != NULL, "There must be a visible item after the first visisble item.\n");
todo_wine
ok(SendMessage(pHdr->hwndFrom, TVM_GETITEMRECT, TRUE, (LPARAM)&rect), "Failed to get rect for second visible item.\n");
}
break;
}
}
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcA(hWnd, msg, wParam, lParam);
}
return 0L;
defwndproc_counter++;
ret = DefWindowProcA(hWnd, message, wParam, lParam);
defwndproc_counter--;
return ret;
}
static void test_expandinvisible(void)
@ -1037,6 +1125,73 @@ static void test_get_insertmarkcolor(void)
DestroyWindow(hTree);
}
static void test_expandnotify(void)
{
HWND hTree;
BOOL ret;
TVITEMA item;
hTree = create_treeview_control();
fill_tree(hTree);
item.hItem = hRoot;
item.mask = TVIF_STATE;
item.state = TVIS_EXPANDED;
ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item);
ok(ret == TRUE, "got %d\n", ret);
ok((item.state & TVIS_EXPANDED) == 0, "expected collapsed\n");
/* preselect root node here */
ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot);
ok(ret == TRUE, "got %d\n", ret);
g_get_from_expand = TRUE;
/* expand */
flush_sequences(sequences, NUM_MSG_SEQUENCES);
g_item_expanding.state = 0xdeadbeef;
g_item_expanded.state = 0xdeadbeef;
ret = SendMessageA(hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hRoot);
ok(ret == TRUE, "got %d\n", ret);
ok(g_item_expanding.state == TVIS_SELECTED, "got state on TVN_ITEMEXPANDING 0x%08x\n",
g_item_expanding.state);
ok(g_item_expanded.state == (TVIS_SELECTED|TVIS_EXPANDED), "got state on TVN_ITEMEXPANDED 0x%08x\n",
g_item_expanded.state);
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_seq, "expand notifications", FALSE);
g_get_from_expand = FALSE;
/* check that it's expanded */
item.state = TVIS_EXPANDED;
ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item);
ok(ret == TRUE, "got %d\n", ret);
ok((item.state & TVIS_EXPANDED) == TVIS_EXPANDED, "expected expanded\n");
/* collapse */
flush_sequences(sequences, NUM_MSG_SEQUENCES);
ret = SendMessageA(hTree, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hRoot);
ok(ret == TRUE, "got %d\n", ret);
item.state = TVIS_EXPANDED;
ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item);
ok(ret == TRUE, "got %d\n", ret);
ok((item.state & TVIS_EXPANDED) == 0, "expected collapsed\n");
/* all next collapse/expand attempts won't produce any notifications,
the only way is to reset with all children removed */
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "collapse after expand notifications", FALSE);
DestroyWindow(hTree);
}
static void test_rect_retrieval_after_expand_with_select(void) {
BOOL ret;
HWND hTree;
hTree = create_treeview_control();
fill_tree(hTree);
g_get_rect_in_expand = TRUE;
ret = TreeView_Select(hTree, hChild, TVGN_CARET);
g_get_rect_in_expand = FALSE;
ok(ret,"TreeView_Select should return true\n");
}
START_TEST(treeview)
{
HMODULE hComctl32;
@ -1056,7 +1211,7 @@ START_TEST(treeview)
else
InitCommonControls();
init_msg_sequences(MsgSequences, NUM_MSG_SEQUENCES);
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
@ -1067,7 +1222,7 @@ START_TEST(treeview)
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyTestWnd";
wc.lpfnWndProc = MyWndProc;
wc.lpfnWndProc = parent_wnd_proc;
RegisterClassA(&wc);
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
@ -1096,6 +1251,8 @@ START_TEST(treeview)
test_expandinvisible();
test_itemedit();
test_treeview_classinfo();
test_expandnotify();
test_rect_retrieval_after_expand_with_select();
PostMessageA(hMainWnd, WM_CLOSE, 0, 0);
while(GetMessageA(&msg,0,0,0)) {

View file

@ -60,11 +60,25 @@ static BOOL (WINAPI *pCertVerifyCertificateChainPolicy)(LPCSTR,PCCERT_CHAIN_CONT
#define IS_INTOID(x) (((ULONG_PTR)(x) >> 16) == 0)
typedef struct _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT
{
DWORD cbSize;
HCERTSTORE hRestrictedRoot;
HCERTSTORE hRestrictedTrust;
HCERTSTORE hRestrictedOther;
DWORD cAdditionalStore;
HCERTSTORE *rghAdditionalStore;
DWORD dwFlags;
DWORD dwUrlRetrievalTimeout;
DWORD MaximumCachedCertificates;
DWORD CycleDetectionModulus;
} CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT;
static void testCreateCertChainEngine(void)
{
BOOL ret;
CERT_CHAIN_ENGINE_CONFIG config = { 0 };
CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT config = { 0 };
CERT_CHAIN_ENGINE_CONFIG *pConfig = (CERT_CHAIN_ENGINE_CONFIG *)&config;
HCERTCHAINENGINE engine;
HCERTSTORE store;
@ -77,21 +91,21 @@ static void testCreateCertChainEngine(void)
/* Crash
ret = pCertCreateCertificateChainEngine(NULL, NULL);
ret = pCertCreateCertificateChainEngine(NULL, &engine);
ret = pCertCreateCertificateChainEngine(&config, NULL);
ret = pCertCreateCertificateChainEngine(pConfig, NULL);
*/
ret = pCertCreateCertificateChainEngine(&config, &engine);
ret = pCertCreateCertificateChainEngine(pConfig, &engine);
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
/* Crashes
config.cbSize = sizeof(config);
ret = pCertCreateCertificateChainEngine(&config, NULL);
ret = pCertCreateCertificateChainEngine(pConfig, NULL);
*/
config.cbSize = sizeof(config);
ret = pCertCreateCertificateChainEngine(&config, &engine);
ret = pCertCreateCertificateChainEngine(pConfig, &engine);
ok(ret, "CertCreateCertificateChainEngine failed: %08x\n", GetLastError());
pCertFreeCertificateChainEngine(engine);
config.dwFlags = 0xff000000;
ret = pCertCreateCertificateChainEngine(&config, &engine);
ret = pCertCreateCertificateChainEngine(pConfig, &engine);
ok(ret, "CertCreateCertificateChainEngine failed: %08x\n", GetLastError());
pCertFreeCertificateChainEngine(engine);
@ -99,7 +113,7 @@ static void testCreateCertChainEngine(void)
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
config.hRestrictedRoot = store;
ret = pCertCreateCertificateChainEngine(&config, &engine);
ret = pCertCreateCertificateChainEngine(pConfig, &engine);
ok(ret, "CertCreateCertificateChainEngine failed: %08x\n", GetLastError());
pCertFreeCertificateChainEngine(engine);
@ -108,7 +122,7 @@ static void testCreateCertChainEngine(void)
*/
CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, selfSignedCert,
sizeof(selfSignedCert), CERT_STORE_ADD_ALWAYS, NULL);
ret = pCertCreateCertificateChainEngine(&config, &engine);
ret = pCertCreateCertificateChainEngine(pConfig, &engine);
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
@ -2458,6 +2472,37 @@ static const BYTE chain28_1[] = {
0x44,0x76,0x66,0x26,0xa7,0x05,0x3c,0x68,0x66,0x1c,0x07,0x4d,0xcf,0x54,0xaa,
0x5d,0xba,0x7a,0x8f,0x06,0xa7,0x1e,0x86,0xf1,0x5a,0x4b,0x50,0x16,0xad,0x9f,
0x89 };
/* A chain whose end certificate is issued to *.winehq.org. */
static const BYTE chain29_1[] = {
0x30,0x82,0x01,0xab,0x30,0x82,0x01,0x16,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,
0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,
0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,
0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,0x30,
0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,0x30,
0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,
0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,
0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f,
0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e,
0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe,
0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71,
0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87,
0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68,
0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36,
0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22,
0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01,
0x00,0x01,0xa3,0x1b,0x30,0x19,0x30,0x17,0x06,0x03,0x55,0x1d,0x07,0x04,0x10,
0x30,0x0e,0x82,0x0c,0x2a,0x2e,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
0x67,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,
0x81,0x81,0x00,0x65,0xbf,0xfa,0xf7,0xc3,0x09,0x70,0x25,0x8a,0x46,0x69,0xf6,
0xdc,0x07,0x1e,0x30,0xc9,0xe4,0x58,0x89,0x65,0x3a,0xa8,0xda,0xbd,0x17,0xf8,
0x1d,0x0d,0x7d,0x47,0xb1,0xb2,0xda,0x17,0x9f,0xf6,0x47,0xe0,0xe4,0x4a,0xeb,
0x02,0xc9,0x2e,0x69,0x1c,0x57,0x2a,0x80,0xc9,0x01,0x77,0x7b,0x27,0xff,0x2f,
0xaf,0xdf,0xf3,0x65,0x12,0xd8,0x7d,0xc2,0xbf,0x1b,0x1d,0x18,0x96,0x5c,0xf6,
0xba,0x43,0xc5,0x43,0x57,0xc0,0xdd,0x97,0x95,0xfb,0x1c,0xad,0x64,0x0f,0x61,
0x3a,0xe9,0x27,0xa4,0x57,0x27,0x34,0xa7,0x42,0xde,0x78,0x1a,0x71,0x80,0x23,
0xd6,0xd7,0x22,0xf0,0x24,0x0d,0x71,0xf1,0x2b,0xd0,0xd8,0x76,0x3d,0xef,0x4c,
0xce,0x1c,0x3b,0x83,0x1b,0x63,0x10,0x6c,0x63,0xe5,0x69 };
typedef struct _CONST_DATA_BLOB
{
@ -2482,9 +2527,9 @@ typedef struct _CONST_BLOB_ARRAY
* certArray, where the last certificate in the chain is expected to be the
* end certificate (the one from which the chain is built.)
*/
static PCCERT_CHAIN_CONTEXT getChain(const CONST_BLOB_ARRAY *certArray,
DWORD flags, BOOL includeStore, LPSYSTEMTIME checkTime, DWORD todo,
DWORD testIndex)
static PCCERT_CHAIN_CONTEXT getChain(HCERTCHAINENGINE engine,
const CONST_BLOB_ARRAY *certArray, DWORD flags, BOOL includeStore,
LPSYSTEMTIME checkTime, DWORD todo, DWORD testIndex)
{
HCERTSTORE store;
PCCERT_CHAIN_CONTEXT chain = NULL;
@ -2522,7 +2567,7 @@ static PCCERT_CHAIN_CONTEXT getChain(const CONST_BLOB_ARRAY *certArray,
FILETIME fileTime;
SystemTimeToFileTime(checkTime, &fileTime);
ret = pCertGetCertificateChain(NULL, endCert, &fileTime,
ret = pCertGetCertificateChain(engine, endCert, &fileTime,
includeStore ? store : NULL, &chainPara, flags, NULL, &chain);
if (todo & TODO_CHAIN)
todo_wine ok(ret, "Chain %d: CertGetCertificateChain failed: %08x\n",
@ -3055,6 +3100,18 @@ static const CERT_TRUST_STATUS elementStatus28[] = {
static const SimpleChainStatusCheck simpleStatus28[] = {
{ sizeof(elementStatus28) / sizeof(elementStatus28[0]), elementStatus28 },
};
static CONST_DATA_BLOB chain29[] = {
{ sizeof(chain0_0), chain0_0 },
{ sizeof(chain29_1), chain29_1 },
};
static const CERT_TRUST_STATUS elementStatus29[] = {
{ CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER },
{ CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT,
CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER },
};
static const SimpleChainStatusCheck simpleStatus29[] = {
{ sizeof(elementStatus29) / sizeof(elementStatus29[0]), elementStatus29 },
};
static CONST_DATA_BLOB selfSignedChain[] = {
{ sizeof(selfSignedCert), selfSignedCert }
};
@ -3340,6 +3397,7 @@ static ChainCheck chainCheck[] = {
CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 },
1, simpleStatus28 },
0 },
/* chain29 is handled separately elsewhere */
{ { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain },
{ { 0, CERT_TRUST_HAS_PREFERRED_ISSUER },
{ CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT, 0 },
@ -3555,7 +3613,7 @@ static void testGetCertChain(void)
for (i = 0; i < sizeof(chainCheck) / sizeof(chainCheck[0]); i++)
{
chain = getChain(&chainCheck[i].certs, 0, TRUE, &oct2007,
chain = getChain(NULL, &chainCheck[i].certs, 0, TRUE, &oct2007,
chainCheck[i].todo, i);
if (chain)
{
@ -3567,7 +3625,7 @@ static void testGetCertChain(void)
for (i = 0; i < sizeof(chainCheckNoStore) / sizeof(chainCheckNoStore[0]);
i++)
{
chain = getChain(&chainCheckNoStore[i].certs, 0, FALSE, &oct2007,
chain = getChain(NULL, &chainCheckNoStore[i].certs, 0, FALSE, &oct2007,
chainCheckNoStore[i].todo, i);
if (chain)
{
@ -3576,7 +3634,7 @@ static void testGetCertChain(void)
pCertFreeCertificateChain(chain);
}
}
chain = getChain(&chainCheckEmbeddedNull.certs, 0, TRUE, &oct2007,
chain = getChain(NULL, &chainCheckEmbeddedNull.certs, 0, TRUE, &oct2007,
chainCheckEmbeddedNull.todo, 0);
if (chain)
{
@ -3758,6 +3816,16 @@ static const ChainPolicyCheck opensslPolicyCheckWithoutMatchingName = {
{ 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0
};
static const ChainPolicyCheck winehqPolicyCheckWithMatchingName = {
{ sizeof(chain29) / sizeof(chain29[0]), chain29 },
{ 0, 0, -1, -1, NULL}, NULL, 0
};
static const ChainPolicyCheck winehqPolicyCheckWithoutMatchingName = {
{ sizeof(chain29) / sizeof(chain29[0]), chain29 },
{ 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0
};
static const ChainPolicyCheck stanfordPolicyCheckWithMatchingName = {
{ sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain },
{ 0, 0, -1, -1, NULL}, NULL, 0
@ -3869,12 +3937,12 @@ static const char *num_to_str(WORD num)
return buf;
}
static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
DWORD testIndex, SYSTEMTIME *sysTime, PCERT_CHAIN_POLICY_PARA para)
static void checkChainPolicyStatus(LPCSTR policy, HCERTCHAINENGINE engine,
const ChainPolicyCheck *check, DWORD testIndex, SYSTEMTIME *sysTime,
PCERT_CHAIN_POLICY_PARA para)
{
PCCERT_CHAIN_CONTEXT chain = getChain(&check->certs, 0, TRUE, sysTime,
check->todo, testIndex);
PCCERT_CHAIN_CONTEXT chain = getChain(engine, &check->certs, 0, TRUE,
sysTime, check->todo, testIndex);
if (chain)
{
@ -3986,37 +4054,44 @@ static void check_ssl_policy(void)
's','t','a','n','f','o','r','d','.','e','d','u',0 };
WCHAR a_dot_cs_dot_stanford_dot_edu[] = { 'a','.','c','s','.',
's','t','a','n','f','o','r','d','.','e','d','u',0 };
WCHAR test_dot_winehq_dot_org[] = { 't','e','s','t','.',
'w','i','n','e','h','q','.','o','r','g',0 };
WCHAR a_dot_b_dot_winehq_dot_org[] = { 'a','.','b','.',
'w','i','n','e','h','q','.','o','r','g',0 };
HCERTSTORE testRoot;
CERT_CHAIN_ENGINE_CONFIG engineConfig = { sizeof(engineConfig), 0 };
HCERTCHAINENGINE engine;
/* Check ssl policy with no parameter */
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, NULL);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, NULL);
/* Check again with a policy parameter that specifies nothing */
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* Check yet again, but specify an empty SSL_EXTRA_CERT_CHAIN_POLICY_PARA
* argument.
*/
policyPara.pvExtraPolicyPara = &sslPolicyPara;
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* And again, but specify the auth type as a client */
sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT;
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* And again, but specify the auth type as a server */
sslPolicyPara.dwAuthType = AUTHTYPE_SERVER;
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* And again authenticating a client, but specify the size of the policy
* parameter.
*/
@ -4024,79 +4099,107 @@ static void check_ssl_policy(void)
sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT;
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* One more time authenticating a client, but specify winehq.org as the
* server name.
*/
sslPolicyPara.pwszServerName = winehq;
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* And again authenticating a server, still specifying winehq.org as the
* server name.
*/
sslPolicyPara.dwAuthType = AUTHTYPE_SERVER;
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* And again authenticating a server, this time specifying the size of the
* policy param.
*/
policyPara.cbSize = sizeof(policyPara);
for (i = 0;
i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i,
&oct2007, &policyPara);
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL, &sslPolicyCheck[i],
i, &oct2007, &policyPara);
/* Yet again, but checking the iTunes chain, which contains a name
* extension.
*/
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&iTunesPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara);
/* And again, but checking the Google chain at a bad date */
sslPolicyPara.pwszServerName = google_dot_com;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&googlePolicyCheckWithMatchingNameExpired, 0, &oct2007, &policyPara);
/* And again, but checking the Google chain at a good date */
sslPolicyPara.pwszServerName = google_dot_com;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&googlePolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
/* Check again with the openssl cert, which has a wildcard in its name,
* with various combinations of matching and non-matching names.
* With "a.openssl.org": match
*/
sslPolicyPara.pwszServerName = a_dot_openssl_dot_org;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&opensslPolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
/* With "openssl.org": no match */
sslPolicyPara.pwszServerName = openssl_dot_org;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
/* With "fopenssl.org": no match */
sslPolicyPara.pwszServerName = fopenssl_dot_org;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
/* with "a.b.openssl.org": no match */
sslPolicyPara.pwszServerName = a_dot_b_dot_openssl_dot_org;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
/* Check again with the cs.stanford.edu, which has both cs.stanford.edu
* and www.cs.stanford.edu in its subject alternative name.
* With "cs.stanford.edu": match
*/
sslPolicyPara.pwszServerName = cs_dot_stanford_dot_edu;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
/* With "www.cs.stanford.edu": match */
sslPolicyPara.pwszServerName = www_dot_cs_dot_stanford_dot_edu;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara);
/* With "a.cs.stanford.edu": no match */
sslPolicyPara.pwszServerName = a_dot_cs_dot_stanford_dot_edu;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL,
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, NULL,
&stanfordPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara);
/* Check chain29, which has a wildcard in its subject alternative name,
* but not in its distinguished name.
* Step 1: create a chain engine that trusts chain29's root.
*/
testRoot = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
CertAddEncodedCertificateToStore(testRoot, X509_ASN_ENCODING, chain0_0,
sizeof(chain0_0), CERT_STORE_ADD_ALWAYS, NULL);
engineConfig.hExclusiveRoot = testRoot;
if (!CertCreateCertificateChainEngine(&engineConfig, &engine))
{
skip("Couldn't create chain engine\n");
return;
}
/* With "winehq.org": no match */
sslPolicyPara.pwszServerName = winehq;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine,
&winehqPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara);
/* With "test.winehq.org": match */
sslPolicyPara.pwszServerName = test_dot_winehq_dot_org;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine,
&winehqPolicyCheckWithMatchingName, 0, &oct2007, &policyPara);
/* With "a.b.winehq.org": no match */
sslPolicyPara.pwszServerName = a_dot_b_dot_winehq_dot_org;
checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, engine,
&winehqPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara);
CertFreeCertificateChainEngine(engine);
CertCloseStore(testRoot, 0);
}
static void testVerifyCertChainPolicy(void)
@ -4163,8 +4266,8 @@ static void testVerifyCertChainPolicy(void)
for (i = 0;
i < sizeof(basePolicyCheck) / sizeof(basePolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_BASE, &basePolicyCheck[i], i,
&oct2007, NULL);
checkChainPolicyStatus(CERT_CHAIN_POLICY_BASE, NULL,
&basePolicyCheck[i], i, &oct2007, NULL);
check_ssl_policy();
/* The authenticode policy doesn't seem to check anything beyond the base
* policy. It might check for chains signed by the MS test cert, but none
@ -4172,12 +4275,12 @@ static void testVerifyCertChainPolicy(void)
*/
for (i = 0; i <
sizeof(authenticodePolicyCheck) / sizeof(authenticodePolicyCheck[0]); i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_AUTHENTICODE,
checkChainPolicyStatus(CERT_CHAIN_POLICY_AUTHENTICODE, NULL,
&authenticodePolicyCheck[i], i, &oct2007, NULL);
for (i = 0; i <
sizeof(basicConstraintsPolicyCheck) / sizeof(basicConstraintsPolicyCheck[0]);
i++)
checkChainPolicyStatus(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS,
checkChainPolicyStatus(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, NULL,
&basicConstraintsPolicyCheck[i], i, &oct2007, NULL);
}

View file

@ -4595,13 +4595,11 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding)
if (buf)
{
CRL_INFO *info = (CRL_INFO *)buf;
CRL_ENTRY *entry;
ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
info->cCRLEntry);
ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
entry = info->rgCRLEntry;
ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
info->cExtension);
LocalFree(buf);
@ -7964,6 +7962,7 @@ static void testPortPublicKeyInfo(void)
CRYPT_DELETEKEYSET);
ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
CRYPT_NEWKEYSET);
ok(ret,"CryptAcquireContextA failed\n");
testExportPublicKey(csp, &info);
testImportPublicKey(csp, info);
@ -7972,6 +7971,7 @@ static void testPortPublicKeyInfo(void)
CryptReleaseContext(csp, 0);
ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
CRYPT_DELETEKEYSET);
ok(ret,"CryptAcquireContextA failed\n");
}
START_TEST(encode)

View file

@ -277,29 +277,35 @@ static void testMemStore(void)
CertCloseStore(store1, 0);
}
static void compareFile(LPCWSTR filename, const BYTE *pb, DWORD cb)
static void compareStore(HCERTSTORE store, LPCSTR name, const BYTE *pb,
DWORD cb, BOOL todo)
{
HANDLE h;
BYTE buf[200];
BOOL ret;
DWORD cbRead = 0, totalRead = 0;
CRYPT_DATA_BLOB blob = { 0, NULL };
h = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return;
do {
ret = ReadFile(h, buf, sizeof(buf), &cbRead, NULL);
if (ret && cbRead)
{
ok(totalRead + cbRead <= cb, "Expected total count %d, see %d\n",
cb, totalRead + cbRead);
ok(!memcmp(pb + totalRead, buf, cbRead),
"Unexpected data in file\n");
totalRead += cbRead;
}
} while (ret && cbRead);
CloseHandle(h);
ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE,
CERT_STORE_SAVE_TO_MEMORY, &blob, 0);
ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
if (todo)
todo_wine
ok(blob.cbData == cb, "%s: expected size %d, got %d\n", name, cb,
blob.cbData);
else
ok(blob.cbData == cb, "%s: expected size %d, got %d\n", name, cb,
blob.cbData);
blob.pbData = HeapAlloc(GetProcessHeap(), 0, blob.cbData);
if (blob.pbData)
{
ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE,
CERT_STORE_SAVE_TO_MEMORY, &blob, 0);
ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
if (todo)
todo_wine
ok(!memcmp(pb, blob.pbData, cb), "%s: unexpected value\n", name);
else
ok(!memcmp(pb, blob.pbData, cb), "%s: unexpected value\n", name);
HeapFree(GetProcessHeap(), 0, blob.pbData);
}
}
static const BYTE serializedStoreWithCert[] = {
@ -689,11 +695,10 @@ static void testCollectionStore(void)
GetLastError());
ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(ret, "CertControlStore failed: %d\n", ret);
compareStore(collection, "serialized store with cert",
serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE);
CertCloseStore(collection, 0);
compareFile(filename, serializedStoreWithCert,
sizeof(serializedStoreWithCert));
DeleteFileW(filename);
}
@ -1294,8 +1299,8 @@ static void testFileStore(void)
/* with commits enabled, commit is allowed */
ret = pCertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(ret, "CertControlStore failed: %d\n", ret);
compareFile(filename, serializedStoreWithCert,
sizeof(serializedStoreWithCert));
compareStore(store, "serialized store with cert",
serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE);
CertCloseStore(store, 0);
}
file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
@ -1311,9 +1316,10 @@ static void testFileStore(void)
ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
compareStore(store, "serialized store with cert and CRL",
serializedStoreWithCertAndCRL, sizeof(serializedStoreWithCertAndCRL),
FALSE);
CertCloseStore(store, 0);
compareFile(filename, serializedStoreWithCertAndCRL,
sizeof(serializedStoreWithCertAndCRL));
}
DeleteFileW(filename);
@ -1517,9 +1523,9 @@ static void testFileNameStore(void)
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
GetLastError());
compareStore(store, "serialized store with cert",
serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE);
CertCloseStore(store, 0);
compareFile(filename, serializedStoreWithCert,
sizeof(serializedStoreWithCert));
}
store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, filename);
@ -1529,9 +1535,10 @@ static void testFileNameStore(void)
ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
compareStore(store, "serialized store with cert and CRL",
serializedStoreWithCertAndCRL, sizeof(serializedStoreWithCertAndCRL),
FALSE);
CertCloseStore(store, 0);
compareFile(filename, serializedStoreWithCertAndCRL,
sizeof(serializedStoreWithCertAndCRL));
}
DeleteFileW(filename);
@ -1757,6 +1764,69 @@ static void testMessageStore(void)
"Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
}
static void testSerializedStore(void)
{
HCERTSTORE store;
CRYPT_DATA_BLOB blob;
if (0)
{
/* Crash */
store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, NULL);
store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0,
CERT_STORE_DELETE_FLAG, NULL);
}
blob.cbData = sizeof(serializedStoreWithCert);
blob.pbData = (BYTE *)serializedStoreWithCert;
store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0,
CERT_STORE_DELETE_FLAG, &blob);
ok(!store && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
"Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob);
ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
if (store)
{
PCCERT_CONTEXT cert;
PCCRL_CONTEXT crl;
cert = CertEnumCertificatesInStore(store, NULL);
ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
GetLastError());
cert = CertEnumCertificatesInStore(store, cert);
ok(!cert, "Expected only one cert\n");
if (pCertEnumCRLsInStore)
{
crl = pCertEnumCRLsInStore(store, NULL);
ok(!crl, "Expected no CRLs\n");
}
CertCloseStore(store, 0);
}
blob.cbData = sizeof(serializedStoreWithCertAndCRL);
blob.pbData = (BYTE *)serializedStoreWithCertAndCRL;
store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob);
ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
if (store)
{
PCCERT_CONTEXT cert;
PCCRL_CONTEXT crl;
cert = CertEnumCertificatesInStore(store, NULL);
ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
GetLastError());
cert = CertEnumCertificatesInStore(store, cert);
ok(!cert, "Expected only one cert\n");
if (pCertEnumCRLsInStore)
{
crl = pCertEnumCRLsInStore(store, NULL);
ok(crl != NULL, "CertEnumCRLsInStore failed: %08x\n",
GetLastError());
crl = pCertEnumCRLsInStore(store, crl);
ok(!crl, "Expected only one CRL\n");
}
CertCloseStore(store, 0);
}
}
static void testCertOpenSystemStore(void)
{
HCERTSTORE store;
@ -2063,6 +2133,334 @@ static void testAddSerialized(void)
CertCloseStore(store, 0);
}
static const BYTE serializedCertWithFriendlyName[] = {
0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,
0x00,0x6e,0x00,0x65,0x00,0x54,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,
0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,
0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,
0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
0x01 };
static const BYTE serializedStoreWithCertWithFriendlyName[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,0x00,0x6e,0x00,0x65,0x00,0x54,0x00,
0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00 };
static const BYTE serializedStoreWithCertAndHash[] = {
0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x03,0x00,0x00,0x00,0x01,0x00,0x00,
0x00,0x14,0x00,0x00,0x00,0x6e,0x30,0x90,0x71,0x5f,0xd9,0x23,0x56,0xeb,0xae,
0x25,0x40,0xe6,0x22,0xda,0x19,0x26,0x02,0xa6,0x08,0x20,0x00,0x00,0x00,0x01,
0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,
0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,
0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static void testAddCertificateLink(void)
{
BOOL ret;
HCERTSTORE store1, store2;
PCCERT_CONTEXT source, linked;
DWORD size;
LPBYTE buf;
CERT_NAME_BLOB blob;
static const WCHAR szPrefix[] = { 'c','e','r',0 };
static const WCHAR szDot[] = { '.',0 };
static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 };
WCHAR filename1[MAX_PATH], filename2[MAX_PATH];
HANDLE file;
if (0)
{
/* Crashes, i.e. the store is dereferenced without checking. */
ret = CertAddCertificateLinkToStore(NULL, NULL, 0, NULL);
}
/* Adding a certificate link to a store requires a valid add disposition */
store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
SetLastError(0xdeadbeef);
ret = CertAddCertificateLinkToStore(store1, NULL, 0, NULL);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
sizeof(bigCert));
SetLastError(0xdeadbeef);
ret = CertAddCertificateLinkToStore(store1, source, 0, NULL);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
NULL);
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (0)
{
/* Crashes, i.e. the source certificate is dereferenced without
* checking when a valid add disposition is given.
*/
ret = CertAddCertificateLinkToStore(store1, NULL, CERT_STORE_ADD_ALWAYS,
NULL);
}
CertCloseStore(store1, 0);
store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
&linked);
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store1, "unexpected store\n");
ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
/* The serialized linked certificate is identical to the serialized
* original certificate.
*/
ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
ok(!memcmp(serializedCert, buf, size),
"Unexpected serialized cert\n");
HeapFree(GetProcessHeap(), 0, buf);
}
/* Set a friendly name on the source certificate... */
blob.pbData = (LPBYTE)WineTestW;
blob.cbData = sizeof(WineTestW);
ret = CertSetCertificateContextProperty(source,
CERT_FRIENDLY_NAME_PROP_ID, 0, &blob);
ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
GetLastError());
/* and the linked certificate has the same friendly name. */
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, NULL, &size);
ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, buf, &size);
ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
"unexpected friendly name\n");
HeapFree(GetProcessHeap(), 0, buf);
}
CertFreeCertificateContext(linked);
}
CertFreeCertificateContext(source);
CertCloseStore(store1, 0);
/* Test adding a cert to a file store, committing the change to the store,
* and creating a link to the resulting cert.
*/
if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
return;
DeleteFileW(filename1);
file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
GetLastError());
/* Test adding a link to a memory store. */
store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store\n");
ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
/* The serialized linked certificate is identical to the serialized
* original certificate.
*/
ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
ok(!memcmp(serializedCert, buf, size),
"Unexpected serialized cert\n");
HeapFree(GetProcessHeap(), 0, buf);
}
/* Set a friendly name on the source certificate... */
blob.pbData = (LPBYTE)WineTestW;
blob.cbData = sizeof(WineTestW);
ret = CertSetCertificateContextProperty(source,
CERT_FRIENDLY_NAME_PROP_ID, 0, &blob);
ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
GetLastError());
/* and the linked certificate has the same friendly name. */
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, NULL, &size);
ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertGetCertificateContextProperty(linked,
CERT_FRIENDLY_NAME_PROP_ID, buf, &size);
ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
"unexpected friendly name\n");
HeapFree(GetProcessHeap(), 0, buf);
}
CertFreeCertificateContext(linked);
}
CertCloseStore(store2, 0);
if (!GetTempFileNameW(szDot, szPrefix, 0, filename2))
return;
DeleteFileW(filename2);
file = CreateFileW(filename2, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
/* Test adding a link to a file store. */
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store\n");
ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
buf = HeapAlloc(GetProcessHeap(), 0, size);
if (buf)
{
ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
GetLastError());
/* The serialized linked certificate now contains the friendly
* name property.
*/
ok(size == sizeof(serializedCertWithFriendlyName),
"Wrong size %d\n", size);
ok(!memcmp(serializedCertWithFriendlyName, buf, size),
"Unexpected serialized cert\n");
HeapFree(GetProcessHeap(), 0, buf);
}
CertFreeCertificateContext(linked);
compareStore(store2, "file store -> file store",
serializedStoreWithCertWithFriendlyName,
sizeof(serializedStoreWithCertWithFriendlyName), FALSE);
}
CertCloseStore(store2, 0);
DeleteFileW(filename2);
CertFreeCertificateContext(source);
CertCloseStore(store1, 0);
DeleteFileW(filename1);
/* Test adding a link to a system store (which is a collection store.) */
store1 = CertOpenSystemStoreA(0, "My");
source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
sizeof(bigCert));
SetLastError(0xdeadbeef);
ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
&linked);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
CertFreeCertificateContext(source);
/* Test adding a link to a file store, where the linked certificate is
* in a system store.
*/
ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source);
ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
GetLastError());
if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
return;
DeleteFileW(filename1);
file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return;
store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
CloseHandle(file);
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store\n");
ret = pCertControlStore(store2, 0, CERT_STORE_CTRL_COMMIT, NULL);
ok(ret, "CertControlStore failed: %d\n", ret);
compareStore(store2, "file store -> system store",
serializedStoreWithCertAndHash,
sizeof(serializedStoreWithCertAndHash), TRUE);
CertFreeCertificateContext(linked);
}
CertCloseStore(store2, 0);
DeleteFileW(filename1);
/* Test adding a link to a registry store, where the linked certificate is
* in a system store.
*/
store2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
CERT_SYSTEM_STORE_CURRENT_USER, WineTestW);
ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
&linked);
ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
if (ret)
{
ok(linked->hCertStore == store2, "unexpected store\n");
CertDeleteCertificateFromStore(linked);
}
CertCloseStore(store2, 0);
CertFreeCertificateContext(source);
CertCloseStore(store1, 0);
}
static DWORD countCertsInStore(HCERTSTORE store)
{
PCCERT_CONTEXT cert = NULL;
@ -2185,12 +2583,14 @@ START_TEST(store)
testFileStore();
testFileNameStore();
testMessageStore();
testSerializedStore();
testCertOpenSystemStore();
testCertEnumSystemStore();
testStoreProperty();
testAddSerialized();
testAddCertificateLink();
test_I_UpdateStore();
}

View file

@ -60,6 +60,29 @@ static const BYTE certWithCRLDistPoint[] = {
0x25,0x06,0x03,0x55,0x1d,0x1f,0x01,0x01,0xff,0x04,0x1b,0x30,0x19,0x30,0x17,
0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,
0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67, };
static const BYTE certWithAIAWithCAIssuers[] = {
0x30,0x82,0x01,0x3c,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,0x30,0x0b,0x06,
0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,0x14,0x31,0x12,0x30,
0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
0x6e,0x67,0x30,0x1e,0x17,0x0d,0x30,0x39,0x31,0x30,0x32,0x38,0x30,0x30,0x30,
0x30,0x30,0x30,0x5a,0x17,0x0d,0x32,0x30,0x31,0x31,0x32,0x37,0x30,0x30,0x30,
0x30,0x30,0x30,0x5a,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,
0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x30,0x81,0xa5,0x30,
0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x95,
0x00,0x06,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x04,
0x00,0x00,0x01,0x00,0x01,0x00,0x2f,0xb2,0x8c,0xff,0x6c,0xf1,0xb1,0x61,0x9c,
0x3a,0x8f,0x5e,0x35,0x2f,0x1f,0xd5,0xcf,0x2a,0xf6,0x9e,0x37,0xe8,0x89,0xa2,
0xb1,0x1c,0xc0,0x1c,0xb6,0x72,0x45,0x97,0xe5,0x88,0x3d,0xfe,0xa6,0x27,0xea,
0xd6,0x07,0x0f,0xcd,0xba,0x49,0x06,0x16,0xdb,0xad,0x06,0x76,0x39,0x4c,0x15,
0xdf,0xe2,0x07,0xc5,0x99,0x1b,0x98,0x4b,0xc3,0x8e,0x89,0x12,0x95,0x9e,0x3b,
0xb9,0x59,0xfe,0x91,0x33,0xc1,0x1f,0xce,0x8f,0xab,0x93,0x25,0x01,0x3e,0xde,
0xf1,0x58,0x3b,0xe7,0x7a,0x03,0x14,0x07,0x09,0x0a,0x21,0x2d,0x12,0x11,0x08,
0x78,0x07,0x9e,0x34,0xc3,0xc5,0xde,0xb2,0xd8,0xd7,0x86,0x0d,0x0d,0xcd,0x81,
0xa4,0x2d,0x7c,0x82,0x50,0xca,0x2a,0xc2,0x99,0xe5,0xf3,0xca,0x7e,0xad,0xa3,
0x31,0x30,0x2f,0x30,0x2d,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
0x04,0x21,0x30,0x1f,0x30,0x1d,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
0x02,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,
0x71,0x2e,0x6f,0x72,0x67 };
static void compareUrlArray(const CRYPT_URL_ARRAY *expected,
const CRYPT_URL_ARRAY *got)
@ -231,6 +254,45 @@ static void test_getObjectUrl(void)
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
CertFreeCertificateContext(cert);
}
cert = CertCreateCertificateContext(X509_ASN_ENCODING,
certWithAIAWithCAIssuers, sizeof(certWithAIAWithCAIssuers));
if (cert)
{
PCRYPT_URL_ARRAY urlArray;
/* This has an AIA extension with the CA Issuers set, so expect it
* to succeed:
*/
ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER,
(void *)cert, 0, NULL, &urlArraySize, NULL, NULL, NULL);
ok(ret, "CryptGetObjectUrl failed: %08x\n", GetLastError());
if (ret)
{
urlArray = HeapAlloc(GetProcessHeap(), 0, urlArraySize);
if (urlArray)
{
ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_ISSUER,
(void *)cert, CRYPT_GET_URL_FROM_EXTENSION, urlArray,
&urlArraySize, NULL, NULL, NULL);
ok(ret, "CryptGetObjectUrl failed: %08x\n", GetLastError());
if (ret)
{
LPWSTR pUrl = url;
CRYPT_URL_ARRAY expectedUrl = { 1, &pUrl };
compareUrlArray(&expectedUrl, urlArray);
}
HeapFree(GetProcessHeap(), 0, urlArray);
}
}
/* It doesn't have a CRL dist points extension, so this should fail */
SetLastError(0xdeadbeef);
ret = CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT,
(void *)cert, 0, NULL, &urlArraySize, NULL, NULL, NULL);
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
"expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
CertFreeCertificateContext(cert);
}
}
static void make_tmp_file(LPSTR path)
@ -376,10 +438,13 @@ static void test_retrieveObjectByUrl(void)
skip("no usable CertificateContext\n");
return;
}
CertFreeCertificateContext(cert);
aux.pLastSyncTime = &ft;
ret = CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CERTIFICATE, 0, 0,
(void **)&cert, NULL, NULL, NULL, &aux);
ok(ret, "CryptRetrieveObjectByUrlA failed: %08x\n", GetLastError());
CertFreeCertificateContext(cert);
ok(ft.dwLowDateTime || ft.dwHighDateTime,
"Expected last sync time to be set\n");
DeleteFileA(tmpfile);
@ -393,8 +458,234 @@ static void test_retrieveObjectByUrl(void)
GetLastError());
}
static const BYTE rootWithKeySignAndCRLSign[] = {
0x30,0x82,0x01,0xdf,0x30,0x82,0x01,0x4c,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
0x5b,0xc7,0x0b,0x27,0x99,0xbb,0x2e,0x99,0x47,0x9d,0x45,0x4e,0x7c,0x1a,0xca,
0xe8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
0x00,0x01,0xa3,0x42,0x30,0x40,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,
0xff,0x04,0x04,0x03,0x02,0x00,0x06,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,
0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,
0x0e,0x04,0x16,0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,
0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x09,0x06,0x05,0x2b,
0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x74,0xcb,0x21,0xfd,0x2d,
0x25,0xdc,0xa5,0xaa,0xa1,0x26,0xdc,0x8b,0x40,0x11,0x64,0xae,0x5c,0x71,0x3c,
0x28,0xbc,0xf9,0xb3,0xcb,0xa5,0x94,0xb2,0x8d,0x4c,0x23,0x2b,0x9b,0xde,0x2c,
0x4c,0x30,0x04,0xc6,0x88,0x10,0x2f,0x53,0xfd,0x6c,0x82,0xf1,0x13,0xfb,0xda,
0x27,0x75,0x25,0x48,0xe4,0x72,0x09,0x2a,0xee,0xb4,0x1e,0xc9,0x55,0xf5,0xf7,
0x82,0x91,0xd8,0x4b,0xe4,0x3a,0xfe,0x97,0x87,0xdf,0xfb,0x15,0x5a,0x12,0x3e,
0x12,0xe6,0xad,0x40,0x0b,0xcf,0xee,0x1a,0x44,0xe0,0x83,0xb2,0x67,0x94,0xd4,
0x2e,0x7c,0xf2,0x06,0x9d,0xb3,0x3b,0x7e,0x2f,0xda,0x25,0x66,0x7e,0xa7,0x1f,
0x45,0xd4,0xf5,0xe3,0xdf,0x2a,0xf1,0x18,0x28,0x20,0xb5,0xf8,0xf5,0x8d,0x7a,
0x2e,0x84,0xee };
static const BYTE eeCert[] = {
0x30,0x82,0x01,0xb9,0x30,0x82,0x01,0x22,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,
0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,
0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,
0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,
0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,
0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,
0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,
0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,
0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,
0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,
0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,
0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,
0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,
0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,
0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,
0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x1f,0x06,0x03,0x55,
0x1d,0x23,0x04,0x18,0x30,0x18,0x80,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,
0x28,0x89,0xa0,0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,
0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,
0x81,0x00,0x8a,0x49,0xa9,0x86,0x5e,0xc9,0x33,0x7e,0xfd,0xab,0x64,0x1f,0x6d,
0x00,0xd7,0x9b,0xec,0xd1,0x5b,0x38,0xcc,0xd6,0xf3,0xf2,0xb4,0x75,0x70,0x00,
0x82,0x9d,0x37,0x58,0xe1,0xcd,0x2c,0x61,0xb3,0x28,0xe7,0x8a,0x00,0xbe,0x6e,
0xca,0xe8,0x55,0xd5,0xad,0x3a,0xea,0xaf,0x13,0x20,0x1c,0x44,0xfc,0xb4,0xf9,
0x29,0x2b,0xdc,0x8a,0x2d,0x1b,0x27,0x9e,0xb9,0x3b,0x4a,0x71,0x9d,0x47,0x7d,
0xf7,0x92,0x6b,0x21,0x7f,0xfa,0x88,0x79,0x94,0x33,0xf6,0xdd,0x92,0x04,0x92,
0xd6,0x5e,0x0a,0x74,0xf2,0x85,0xa6,0xd5,0x3c,0x28,0xc0,0x89,0x5d,0xda,0xf3,
0xa6,0x01,0xc2,0xe9,0xa3,0xc1,0xb7,0x21,0x08,0xba,0x18,0x07,0x45,0xeb,0x77,
0x7d,0xcd,0xc6,0xe7,0x2a,0x7b,0x46,0xd2,0x3d,0xb5 };
static const BYTE rootSignedCRL[] = {
0x30,0x82,0x01,0x1f,0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,
0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x10,0x31,0x0e,0x30,
0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x17,0x0d,
0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x14,
0x30,0x12,0x02,0x01,0x01,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,
0x30,0x30,0x30,0x30,0x5a,0xa0,0x2f,0x30,0x2d,0x30,0x0a,0x06,0x03,0x55,0x1d,
0x14,0x04,0x03,0x02,0x01,0x01,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,
0x30,0x18,0x80,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,0x58,
0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,0x06,0x09,0x2a,0x86,
0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xa3,0xcf,
0x17,0x5d,0x7a,0x08,0xab,0x11,0x1a,0xbd,0x5c,0xde,0x9a,0x22,0x92,0x38,0xe6,
0x96,0xcc,0xb1,0xc5,0x42,0x86,0xa6,0xae,0xad,0xa3,0x1a,0x2b,0xa0,0xb0,0x65,
0xaa,0x9c,0xd7,0x2d,0x44,0x8c,0xae,0x61,0xc7,0x30,0x17,0x89,0x84,0x3b,0x4a,
0x8f,0x17,0x08,0x06,0x37,0x1c,0xf7,0x2d,0x4e,0x47,0x07,0x61,0x50,0xd9,0x06,
0xd1,0x46,0xed,0x0a,0xbb,0xc3,0x9b,0x36,0x0b,0xa7,0x27,0x2f,0x2b,0x55,0xce,
0x2a,0xa5,0x60,0xc6,0x53,0x28,0xe8,0xee,0xad,0x0e,0x2b,0xe8,0xd7,0x5f,0xc9,
0xa5,0xed,0xf9,0x77,0xb0,0x3c,0x81,0xcf,0xcc,0x49,0xb2,0x1a,0xc3,0xfd,0x34,
0xd5,0xbc,0xb0,0xd5,0xa5,0x9c,0x1b,0x72,0xc3,0x0f,0xa3,0xe3,0x3c,0xf0,0xc3,
0x91,0xe8,0x93,0x4f,0xd4,0x2f };
BOOL (WINAPI *pCertVerifyRevocation)(DWORD, DWORD, DWORD, void **, DWORD,
PCERT_REVOCATION_PARA, PCERT_REVOCATION_STATUS);
/* Wednesday, Oct 1, 2007 */
static SYSTEMTIME oct2007 = { 2007, 10, 1, 1, 0, 0, 0, 0 };
static void test_verifyRevocation(void)
{
HMODULE hCryptNet = GetModuleHandleA("cryptnet.dll");
BOOL ret;
CERT_REVOCATION_STATUS status = { sizeof(status), 0 };
PCCERT_CONTEXT certs[2];
CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 };
FILETIME time;
pCertVerifyRevocation = (void *)GetProcAddress(hCryptNet,
"CertDllVerifyRevocation");
if (!pCertVerifyRevocation)
{
win_skip("no CertDllVerifyRevocation\n");
return;
}
if (0)
{
/* Crash */
ret = pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
}
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(X509_ASN_ENCODING, 0, 0, NULL, 0, NULL,
&status);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 0, NULL, 0,
NULL, &status);
ok(!ret && GetLastError() == E_INVALIDARG,
"expected E_INVALIDARG, got %08x\n", GetLastError());
certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
sizeof(bigCert));
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)certs, 0, NULL, &status);
ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
CertFreeCertificateContext(certs[0]);
certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING,
rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign));
certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING,
eeCert, sizeof(eeCert));
/* The root cert itself can't be checked for revocation */
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)certs, 0, NULL, &status);
ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
/* Neither can the end cert */
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, NULL, &status);
ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
/* Both certs together can't, either (they're not CRLs) */
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
2, (void **)certs, 0, NULL, &status);
ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
/* Now add a CRL to the hCrlStore */
revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING,
rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL);
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
2, (void **)certs, 0, &revPara, &status);
ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
/* Specifying CERT_VERIFY_REV_CHAIN_FLAG doesn't change things either */
SetLastError(0xdeadbeef);
ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE,
2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, &revPara, &status);
ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK,
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
/* Again, specifying the issuer cert: no change */
revPara.pIssuerCert = certs[0];
SetLastError(0xdeadbeef);
ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status);
/* Win2k thinks the cert is revoked, and it is, except the CRL is out of
* date, hence the revocation status should be unknown.
*/
ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK ||
broken(GetLastError() == CRYPT_E_REVOKED /* Win2k */)),
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
broken(status.dwError == CRYPT_E_REVOKED /* Win2k */),
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
/* Specifying the time to check: still no change */
SystemTimeToFileTime(&oct2007, &time);
revPara.pftTimeToUse = &time;
ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status);
ok(!ret, "Expected failure\n");
ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK ||
broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */
"expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
CertCloseStore(revPara.hCrlStore, 0);
CertFreeCertificateContext(certs[1]);
CertFreeCertificateContext(certs[0]);
}
START_TEST(cryptnet)
{
test_getObjectUrl();
test_retrieveObjectByUrl();
test_verifyRevocation();
}

View file

@ -317,7 +317,6 @@ static BOOL find_and_delete_cert_in_store(HCERTSTORE store, PCCERT_CONTEXT cert)
return FALSE;
CertDeleteCertificateFromStore(found);
CertFreeCertificateContext(found);
return TRUE;
}
@ -560,7 +559,7 @@ static void test_crypt_ui_wiz_import(void)
crl = CertEnumCRLsInStore(store, crl);
if (crl)
count++;
} while (cert);
} while (crl);
ok(count == 1, "expected 1 CRL, got %d\n", count);
}
CertCloseStore(store, 0);
@ -596,7 +595,7 @@ static void test_crypt_ui_wiz_import(void)
crl = CertEnumCRLsInStore(store, crl);
if (crl)
count++;
} while (cert);
} while (crl);
ok(count == 0, "expected 0 CRLs, got %d\n", count);
}
SetLastError(0xdeadbeef);
@ -636,7 +635,7 @@ static void test_crypt_ui_wiz_import(void)
crl = CertEnumCRLsInStore(store, crl);
if (crl)
count++;
} while (cert);
} while (crl);
ok(count == 1, "expected 1 CRL, got %d\n", count);
}
SetLastError(0xdeadbeef);

View file

@ -28,10 +28,6 @@
#include "wine/test.h"
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
#define CLDB_E_FILE_OLDVER EMAKEHR(0x1107)
typedef struct _tagASSEMBLY ASSEMBLY;
typedef struct

View file

@ -411,7 +411,7 @@ static void test_dib_bits_access( HBITMAP hdib, void *bits )
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
DWORD data[256];
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
HDC hdc = GetDC(0);
HDC hdc;
char filename[MAX_PATH];
HANDLE file;
DWORD written;
@ -435,11 +435,15 @@ static void test_dib_bits_access( HBITMAP hdib, void *bits )
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biCompression = BI_RGB;
hdc = GetDC(0);
ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
ok(ret == 16 ||
broken(ret == 0), /* win9x */
"SetDIBits failed: expected 16 got %d\n", ret);
ReleaseDC(0, hdc);
ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
"VirtualQuery failed\n");
ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
@ -542,6 +546,18 @@ static void test_dibsections(void)
ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
for (i = 0; i < 128; i++)
{
pbmi->bmiHeader.biBitCount = i;
pbmi->bmiHeader.biCompression = BI_RGB;
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
if (i == 1 || i == 4 || i == 8 || i == 16 || i == 24 || i == 32)
ok(hdib != NULL, "CreateDIBSection bpp %u\n", i);
else
todo_wine ok(hdib == NULL, "CreateDIBSection bpp %u succeeded\n", i);
if (hdib) DeleteObject( hdib );
}
pbmi->bmiHeader.biBitCount = 16;
pbmi->bmiHeader.biCompression = BI_BITFIELDS;
((PDWORD)pbmi->bmiColors)[0] = 0xf800;
@ -864,8 +880,8 @@ static void test_dibsections(void)
DeleteObject(hdib);
DeleteObject(hpal);
DeleteDC(hdcmem);
DeleteDC(hdcmem2);
ReleaseDC(0, hdc);
}
@ -1805,9 +1821,11 @@ static void test_GetDIBits_BI_BITFIELDS(void)
char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
DWORD bits[32];
LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
HDC hdc;
HBITMAP hbm;
int ret;
void *ptr;
memset(dibinfo, 0, sizeof(dibinfo_buf));
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@ -1822,8 +1840,6 @@ static void test_GetDIBits_BI_BITFIELDS(void)
ok(ret == 1, "GetDIBits failed\n");
if (dibinfo->bmiHeader.biBitCount > 8)
{
DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
"compression is %u\n", dibinfo->bmiHeader.biCompression );
@ -1887,6 +1903,135 @@ static void test_GetDIBits_BI_BITFIELDS(void)
}
else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
DeleteObject(hbm);
/* same thing now with a 32-bpp DIB section */
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dibinfo->bmiHeader.biWidth = 1;
dibinfo->bmiHeader.biHeight = 1;
dibinfo->bmiHeader.biPlanes = 1;
dibinfo->bmiHeader.biBitCount = 32;
dibinfo->bmiHeader.biCompression = BI_RGB;
dibinfo->bmiHeader.biSizeImage = 0;
dibinfo->bmiHeader.biXPelsPerMeter = 0;
dibinfo->bmiHeader.biYPelsPerMeter = 0;
dibinfo->bmiHeader.biClrUsed = 0;
dibinfo->bmiHeader.biClrImportant = 0;
bitmasks[0] = 0x0000ff;
bitmasks[1] = 0x00ff00;
bitmasks[2] = 0xff0000;
hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
ok( hbm != 0, "failed to create bitmap\n" );
memset(dibinfo, 0, sizeof(dibinfo_buf));
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
"compression is %u\n", dibinfo->bmiHeader.biCompression );
ok( !bitmasks[0], "red mask is set\n" );
ok( !bitmasks[1], "green mask is set\n" );
ok( !bitmasks[2], "blue mask is set\n" );
dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
ok( dibinfo->bmiHeader.biBitCount == 32, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
ok( bitmasks[0] == 0xff0000, "wrong red mask %08x\n", bitmasks[0] );
ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
ok( bitmasks[2] == 0x0000ff, "wrong blue mask %08x\n", bitmasks[2] );
ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef ||
broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */
"size image not set\n" );
DeleteObject(hbm);
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dibinfo->bmiHeader.biWidth = 1;
dibinfo->bmiHeader.biHeight = 1;
dibinfo->bmiHeader.biPlanes = 1;
dibinfo->bmiHeader.biBitCount = 32;
dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
dibinfo->bmiHeader.biSizeImage = 0;
dibinfo->bmiHeader.biXPelsPerMeter = 0;
dibinfo->bmiHeader.biYPelsPerMeter = 0;
dibinfo->bmiHeader.biClrUsed = 0;
dibinfo->bmiHeader.biClrImportant = 0;
bitmasks[0] = 0x0000ff;
bitmasks[1] = 0x00ff00;
bitmasks[2] = 0xff0000;
hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
ok( hbm != 0 || broken(!hbm), /* win9x */ "failed to create bitmap\n" );
if (hbm)
{
memset(dibinfo, 0, sizeof(dibinfo_buf));
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
"compression is %u\n", dibinfo->bmiHeader.biCompression );
ok( !bitmasks[0], "red mask is set\n" );
ok( !bitmasks[1], "green mask is set\n" );
ok( !bitmasks[2], "blue mask is set\n" );
dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
ok( bitmasks[0] == 0x0000ff, "wrong red mask %08x\n", bitmasks[0] );
ok( bitmasks[1] == 0x00ff00, "wrong green mask %08x\n", bitmasks[1] );
ok( bitmasks[2] == 0xff0000, "wrong blue mask %08x\n", bitmasks[2] );
ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
DeleteObject(hbm);
}
/* 24-bpp DIB sections don't have bitfields */
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dibinfo->bmiHeader.biWidth = 1;
dibinfo->bmiHeader.biHeight = 1;
dibinfo->bmiHeader.biPlanes = 1;
dibinfo->bmiHeader.biBitCount = 24;
dibinfo->bmiHeader.biCompression = BI_BITFIELDS;
dibinfo->bmiHeader.biSizeImage = 0;
dibinfo->bmiHeader.biXPelsPerMeter = 0;
dibinfo->bmiHeader.biYPelsPerMeter = 0;
dibinfo->bmiHeader.biClrUsed = 0;
dibinfo->bmiHeader.biClrImportant = 0;
hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
ok( hbm == 0, "creating 24-bpp BI_BITFIELDS dibsection should fail\n" );
dibinfo->bmiHeader.biCompression = BI_RGB;
hbm = CreateDIBSection( hdc, dibinfo, DIB_RGB_COLORS, &ptr, NULL, 0 );
ok( hbm != 0, "failed to create bitmap\n" );
memset(dibinfo, 0, sizeof(dibinfo_buf));
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
ret = GetDIBits(hdc, hbm, 0, 0, NULL, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
ok( dibinfo->bmiHeader.biCompression == BI_RGB,
"compression is %u\n", dibinfo->bmiHeader.biCompression );
ok( !bitmasks[0], "red mask is set\n" );
ok( !bitmasks[1], "green mask is set\n" );
ok( !bitmasks[2], "blue mask is set\n" );
dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
ok(ret == 1, "GetDIBits failed\n");
ok( dibinfo->bmiHeader.biBitCount == 24, "wrong bit count %u\n", dibinfo->bmiHeader.biBitCount );
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 ||
broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */
"size image not set\n" );
DeleteObject(hbm);
ReleaseDC(NULL, hdc);
}
@ -2806,9 +2951,7 @@ static void test_GdiAlphaBlend(void)
static void test_clipping(void)
{
HBITMAP bmpDst;
HBITMAP oldDst;
HBITMAP bmpSrc;
HBITMAP oldSrc;
HRGN hRgn;
LPVOID bits;
BOOL result;
@ -2826,11 +2969,11 @@ static void test_clipping(void)
bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
oldDst = SelectObject( hdcDst, bmpDst );
SelectObject( hdcDst, bmpDst );
bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
oldSrc = SelectObject( hdcSrc, bmpSrc );
SelectObject( hdcSrc, bmpSrc );
result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
ok(result, "BitBlt failed\n");
@ -2848,6 +2991,54 @@ static void test_clipping(void)
DeleteDC( hdcSrc );
}
static void test_32bit_bitmap_blt(void)
{
BITMAPINFO biDst;
HBITMAP bmpSrc, bmpDst;
HBITMAP oldSrc, oldDst;
HDC hdcSrc, hdcDst, hdcScreen;
UINT32 *dstBuffer;
DWORD colorSrc = 0x11223344;
memset(&biDst, 0, sizeof(BITMAPINFO));
biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
biDst.bmiHeader.biWidth = 2;
biDst.bmiHeader.biHeight = -2;
biDst.bmiHeader.biPlanes = 1;
biDst.bmiHeader.biBitCount = 32;
biDst.bmiHeader.biCompression = BI_RGB;
hdcScreen = CreateCompatibleDC(0);
if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
{
DeleteDC(hdcScreen);
trace("Skipping 32-bit DDB test\n");
return;
}
hdcSrc = CreateCompatibleDC(hdcScreen);
bmpSrc = CreateBitmap(1, 1, 1, 32, &colorSrc);
oldSrc = SelectObject(hdcSrc, bmpSrc);
hdcDst = CreateCompatibleDC(hdcScreen);
bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
oldDst = SelectObject(hdcDst, bmpDst);
StretchBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, 1, 1, SRCCOPY);
ok(dstBuffer[0] == colorSrc, "Expected color=%x, received color=%x\n", colorSrc, dstBuffer[0]);
/* Tidy up */
SelectObject(hdcDst, oldDst);
DeleteObject(bmpDst);
DeleteDC(hdcDst);
SelectObject(hdcSrc, oldSrc);
DeleteObject(bmpSrc);
DeleteDC(hdcSrc);
DeleteDC(hdcScreen);
}
START_TEST(bitmap)
{
HMODULE hdll;
@ -2874,6 +3065,7 @@ START_TEST(bitmap)
test_StretchBlt();
test_StretchDIBits();
test_GdiAlphaBlend();
test_32bit_bitmap_blt();
test_bitmapinfoheadersize();
test_get16dibits();
test_clipping();

View file

@ -162,15 +162,35 @@ static void test_savedc(void)
ret = RestoreDC(hdc, 3);
ok(!ret, "ret = %d\n", ret);
/* Under win98 the following two succeed and both clear the save stack
/* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
ret = RestoreDC(hdc, -3);
ok(!ret ||
broken(ret), /* Win9x */
"ret = %d\n", ret);
/* Trying to clear an empty save stack fails. */
ret = RestoreDC(hdc, -3);
ok(!ret, "ret = %d\n", ret);
ret = SaveDC(hdc);
ok(ret == 3 ||
broken(ret == 1), /* Win9x */
"ret = %d\n", ret);
/* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
ret = RestoreDC(hdc, 0);
ok(!ret ||
broken(ret), /* Win9x */
"ret = %d\n", ret);
/* Trying to clear an empty save stack fails. */
ret = RestoreDC(hdc, 0);
ok(!ret, "ret = %d\n", ret);
*/
ret = RestoreDC(hdc, 1);
ok(ret, "ret = %d\n", ret);
ok(ret ||
broken(!ret), /* Win9x */
"ret = %d\n", ret);
DeleteDC(hdc);
}
@ -474,6 +494,107 @@ todo_wine
ok(ret, "UnregisterClassA failed\n");
}
static void test_boundsrect_invalid(void)
{
HDC hdc;
RECT rect, expect;
UINT ret;
hdc = GetDC(NULL);
ok(hdc != NULL, "GetDC failed\n");
ret = GetBoundsRect(hdc, NULL, 0);
ok(ret == 0 ||
broken(ret == DCB_RESET), /* Win9x */
"Expected GetBoundsRect to return 0, got %u\n", ret);
ret = GetBoundsRect(hdc, NULL, ~0U);
ok(ret == 0 ||
broken(ret == DCB_RESET), /* Win9x */
"Expected GetBoundsRect to return 0, got %u\n", ret);
if (GetBoundsRect(hdc, NULL, 0) == DCB_RESET)
win_skip("Win9x fails catastrophically with first GetBoundsRect call\n");
else
{
/* Test parameter handling order. */
SetRect(&rect, 0, 0, 50, 50);
ret = SetBoundsRect(hdc, &rect, DCB_SET);
ok(ret & DCB_RESET,
"Expected return flag DCB_RESET to be set, got %u\n", ret);
ret = GetBoundsRect(hdc, NULL, DCB_RESET);
ok(ret == 0,
"Expected GetBoundsRect to return 0, got %u\n", ret);
ret = GetBoundsRect(hdc, &rect, 0);
ok(ret == DCB_RESET,
"Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
SetRect(&expect, 0, 0, 0, 0);
ok(EqualRect(&rect, &expect),
"Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
rect.left, rect.top, rect.right, rect.bottom);
}
if (GetBoundsRect(hdc, NULL, 0) == DCB_RESET)
win_skip("Win9x fails catastrophically with NULL device context parameter\n");
else
{
ret = GetBoundsRect(NULL, NULL, 0);
ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
ret = GetBoundsRect(NULL, NULL, ~0U);
ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
ret = SetBoundsRect(NULL, NULL, 0);
ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
ret = SetBoundsRect(NULL, NULL, ~0U);
ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
}
DeleteDC(hdc);
}
static void test_desktop_colorres(void)
{
HDC hdc = GetDC(NULL);
int bitspixel, colorres;
bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
colorres = GetDeviceCaps(hdc, COLORRES);
ok(colorres != 0 ||
broken(colorres == 0), /* Win9x */
"Expected to get valid COLORRES capability value\n");
if (colorres)
{
switch (bitspixel)
{
case 8:
ok(colorres == 18,
"Expected COLORRES to be 18, got %d\n", colorres);
break;
case 16:
ok(colorres == 16,
"Expected COLORRES to be 16, got %d\n", colorres);
break;
case 24:
case 32:
ok(colorres == 24,
"Expected COLORRES to be 24, got %d\n", bitspixel);
break;
default:
ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
break;
}
}
DeleteDC(hdc);
}
START_TEST(dc)
{
test_savedc();
@ -482,4 +603,6 @@ START_TEST(dc)
test_CreateCompatibleDC();
test_DC_bitmap();
test_DeleteDC();
test_boundsrect_invalid();
test_desktop_colorres();
}

View file

@ -30,6 +30,9 @@
#include "wine/test.h"
/* Do not allow more than 1 deviation here */
#define match_off_by_1(a, b) (abs((a) - (b)) <= 1)
#define near_match(a, b) (abs((a) - (b)) <= 6)
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
@ -40,6 +43,7 @@ DWORD (WINAPI *pGetFontUnicodeRanges)(HDC hdc, LPGLYPHSET lpgs);
DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi, DWORD flags);
DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *);
HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *);
static HMODULE hgdi32 = 0;
@ -54,6 +58,7 @@ static void init(void)
pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA");
pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW");
pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo");
pCreateFontIndirectExA = (void *)GetProcAddress(hgdi32, "CreateFontIndirectExA");
}
static INT CALLBACK is_truetype_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
@ -308,9 +313,6 @@ static void test_bitmap_font(void)
SIZE size_orig;
INT ret, i, width_orig, height_orig, scale, lfWidth;
skip("ROS-HACK: Skipping bitmap font tests!\n");
return;
hdc = GetDC(0);
/* "System" has only 1 pixel size defined, otherwise the test breaks */
@ -1169,9 +1171,9 @@ static void test_GetKerningPairs(void)
otm.otmSize = sizeof(otm); /* just in case for Win9x compatibility */
ok(GetOutlineTextMetricsW(hdc, sizeof(otm), &otm) == sizeof(otm), "GetOutlineTextMetricsW error %d\n", GetLastError());
ok(kd[i].tmHeight == otm.otmTextMetrics.tmHeight, "expected %d, got %d\n",
ok(match_off_by_1(kd[i].tmHeight, otm.otmTextMetrics.tmHeight), "expected %d, got %d\n",
kd[i].tmHeight, otm.otmTextMetrics.tmHeight);
ok(kd[i].tmAscent == otm.otmTextMetrics.tmAscent, "expected %d, got %d\n",
ok(match_off_by_1(kd[i].tmAscent, otm.otmTextMetrics.tmAscent), "expected %d, got %d\n",
kd[i].tmAscent, otm.otmTextMetrics.tmAscent);
ok(kd[i].tmDescent == otm.otmTextMetrics.tmDescent, "expected %d, got %d\n",
kd[i].tmDescent, otm.otmTextMetrics.tmDescent);
@ -1186,13 +1188,13 @@ static void test_GetKerningPairs(void)
kd[i].otmLineGap, otm.otmLineGap);
ok(near_match(kd[i].otmMacDescent, otm.otmMacDescent), "expected %d, got %d\n",
kd[i].otmMacDescent, otm.otmMacDescent);
ok(near_match(kd[i].otmMacAscent, otm.otmMacAscent), "expected %d, got %d\n",
kd[i].otmMacAscent, otm.otmMacAscent);
todo_wine {
ok(kd[i].otmsCapEmHeight == otm.otmsCapEmHeight, "expected %u, got %u\n",
kd[i].otmsCapEmHeight, otm.otmsCapEmHeight);
ok(kd[i].otmsXHeight == otm.otmsXHeight, "expected %u, got %u\n",
kd[i].otmsXHeight, otm.otmsXHeight);
ok(kd[i].otmMacAscent == otm.otmMacAscent, "expected %d, got %d\n",
kd[i].otmMacAscent, otm.otmMacAscent);
/* FIXME: this one sometimes succeeds due to expected 0, enable it when removing todo */
if (0) ok(kd[i].otmMacLineGap == otm.otmMacLineGap, "expected %u, got %u\n",
kd[i].otmMacLineGap, otm.otmMacLineGap);
@ -1257,6 +1259,74 @@ todo_wine {
ReleaseDC(0, hdc);
}
static void test_height_selection(void)
{
static const struct font_data
{
const char face_name[LF_FACESIZE];
int requested_height;
int weight, height, ascent, descent, int_leading, ext_leading, dpi;
} fd[] =
{
{"Tahoma", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96 },
{"Tahoma", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96 },
{"Tahoma", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96 },
{"Tahoma", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96 },
{"Tahoma", -192, FW_NORMAL, 232, 192, 40, 40, 0, 96 },
{"Tahoma", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96 },
{"Tahoma", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96 },
{"Tahoma", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96 },
{"Tahoma", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96 },
{"Tahoma", 192, FW_NORMAL, 192, 159, 33, 33, 0, 96 }
};
HDC hdc;
LOGFONT lf;
HFONT hfont, old_hfont;
TEXTMETRIC tm;
INT ret, i;
hdc = CreateCompatibleDC(0);
assert(hdc);
for (i = 0; i < sizeof(fd)/sizeof(fd[0]); i++)
{
if (!is_truetype_font_installed(fd[i].face_name))
{
skip("%s is not installed\n", fd[i].face_name);
continue;
}
memset(&lf, 0, sizeof(lf));
lf.lfHeight = fd[i].requested_height;
lf.lfWeight = fd[i].weight;
strcpy(lf.lfFaceName, fd[i].face_name);
hfont = CreateFontIndirect(&lf);
assert(hfont);
old_hfont = SelectObject(hdc, hfont);
ret = GetTextMetrics(hdc, &tm);
ok(ret, "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].requested_height, tm.tmWeight, fd[i].weight);
ok(match_off_by_1(tm.tmHeight, fd[i].height), "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmHeight, fd[i].height);
ok(match_off_by_1(tm.tmAscent, fd[i].ascent), "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmAscent, fd[i].ascent);
ok(match_off_by_1(tm.tmDescent, fd[i].descent), "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmDescent, fd[i].descent);
#if 0 /* FIXME: calculation of tmInternalLeading in Wine doesn't match what Windows does */
ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmInternalLeading, fd[i].int_leading);
#endif
ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmExternalLeading, fd[i].ext_leading);
}
SelectObject(hdc, old_hfont);
DeleteObject(hfont);
}
DeleteDC(hdc);
}
static void test_GetOutlineTextMetrics(void)
{
OUTLINETEXTMETRIC *otm;
@ -1346,7 +1416,7 @@ static void test_GetOutlineTextMetrics(void)
static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
{
INT x, y,
INT y,
breakCount,
justifiedWidth = 0, /* to test GetTextExtentExPointW() */
areaWidth = clientArea->right - clientArea->left,
@ -1402,8 +1472,6 @@ static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
}
else lastExtent = TRUE;
x = clientArea->left;
/* catch errors and report them */
if (!lastExtent && (justifiedWidth != areaWidth))
{
@ -2970,7 +3038,7 @@ static void test_GetTextMetrics2(const char *fontname, int font_height)
DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_LH_ANGLES,
DEFAULT_QUALITY, VARIABLE_PITCH,
fontname);
ok( hf != NULL, "CreateFontA failed\n");
ok( hf != NULL, "CreateFontA(%s, %d) failed\n", fontname, font_height);
of = SelectObject( hdc, hf);
ret = GetTextMetricsA( hdc, &tm);
ok(ret, "GetTextMetricsA error %u\n", GetLastError());
@ -2993,7 +3061,7 @@ static void test_GetTextMetrics2(const char *fontname, int font_height)
SelectObject(hdc, of);
DeleteObject(hf);
if (tm.tmAveCharWidth == ave_width || width / height > 200)
if (match_off_by_1(tm.tmAveCharWidth, ave_width) || width / height > 200)
break;
}
@ -3029,7 +3097,9 @@ static void test_CreateFontIndirect(void)
lstrcpyA(lf.lfFaceName, TestName[i]);
hfont = CreateFontIndirectA(&lf);
ok(hfont != 0, "CreateFontIndirectA failed\n");
SetLastError(0xdeadbeef);
ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf);
ok(ret, "GetObject failed: %d\n", GetLastError());
ok(lf.lfItalic == getobj_lf.lfItalic, "lfItalic: expect %02x got %02x\n", lf.lfItalic, getobj_lf.lfItalic);
ok(lf.lfWeight == getobj_lf.lfWeight ||
broken((SHORT)lf.lfWeight == getobj_lf.lfWeight), /* win9x */
@ -3041,9 +3111,41 @@ static void test_CreateFontIndirect(void)
}
}
static void test_CreateFontIndirectEx(void)
{
ENUMLOGFONTEXDVA lfex;
HFONT hfont;
if (!pCreateFontIndirectExA)
{
win_skip("CreateFontIndirectExA is not available\n");
return;
}
if (!is_truetype_font_installed("Arial"))
{
skip("Arial is not installed\n");
return;
}
SetLastError(0xdeadbeef);
hfont = pCreateFontIndirectExA(NULL);
ok(hfont == NULL, "got %p\n", hfont);
ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
memset(&lfex, 0, sizeof(lfex));
lstrcpyA(lfex.elfEnumLogfontEx.elfLogFont.lfFaceName, "Arial");
hfont = pCreateFontIndirectExA(&lfex);
ok(hfont != 0, "CreateFontIndirectEx failed\n");
if (hfont)
check_font("Arial", &lfex.elfEnumLogfontEx.elfLogFont, hfont);
DeleteObject(hfont);
}
START_TEST(font)
{
init();
test_logfont();
test_bitmap_font();
test_outline_font();
@ -3059,6 +3161,7 @@ START_TEST(font)
test_GetFontUnicodeRanges();
test_nonexistent_font();
test_orientation();
test_height_selection();
/* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
* I'd like to avoid them in this test.
@ -3085,5 +3188,6 @@ START_TEST(font)
test_GetTextMetrics2("Arial", -55);
test_GetTextMetrics2("Arial", -110);
test_CreateFontIndirect();
test_CreateFontIndirectEx();
test_oemcharset();
}

File diff suppressed because it is too large Load diff

View file

@ -1427,11 +1427,10 @@ static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
const ENHMETARECORD *emr1 = (const ENHMETARECORD *)(bits + offset1);
const ENHMETARECORD *emr2 = (const ENHMETARECORD *)(buf + offset2);
skip("skipping match_emf_record(), bug 5392\n");
// trace("%s: EMF record %u, size %u/record %u, size %u\n",
// desc, emr1->iType, emr1->nSize, emr2->iType, emr2->nSize);
trace("%s: EMF record %u, size %u/record %u, size %u\n",
desc, emr1->iType, emr1->nSize, emr2->iType, emr2->nSize);
// if (!match_emf_record(emr1, emr2, desc, ignore_scaling)) return -1;
if (!match_emf_record(emr1, emr2, desc, ignore_scaling)) return -1;
/* We have already bailed out if iType or nSize don't match */
offset1 += emr1->nSize;

View file

@ -37,13 +37,12 @@ static void test_widenpath(void)
{
HDC hdc = GetDC(0);
HPEN greenPen, narrowPen;
HPEN oldPen;
POINT pnt[6];
INT nSize, ret;
/* Create a pen to be used in WidenPath */
greenPen = CreatePen(PS_SOLID, 10, RGB(0,0,0));
oldPen = SelectObject(hdc, greenPen);
SelectObject(hdc, greenPen);
/* Prepare a path */
pnt[0].x = 100;
@ -85,7 +84,7 @@ static void test_widenpath(void)
/* Test when the pen width is equal to 1. The path should change too */
narrowPen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
oldPen = SelectObject(hdc, narrowPen);
SelectObject(hdc, narrowPen);
BeginPath(hdc);
Polyline(hdc, pnt, 6);
EndPath(hdc);
@ -260,9 +259,9 @@ static const path_test_t anglearc_path[] = {
{245, 200, PT_BEZIERTO, 0, 0}, /* 5 */
{200, 245, PT_BEZIERTO, 0, 0}, /* 6 */
{200, 300, PT_BEZIERTO, 0, 0}, /* 7 */
{200, 300, PT_BEZIERTO, 0, 2}, /* 8 */
{200, 300, PT_BEZIERTO, 0, 2}, /* 9 */
{200, 300, PT_BEZIERTO, 0, 2}, /* 10 */
{200, 300, PT_BEZIERTO, 0, 0}, /* 8 */
{200, 300, PT_BEZIERTO, 0, 0}, /* 9 */
{200, 300, PT_BEZIERTO, 0, 0}, /* 10 */
{231, 260, PT_LINETO, 0, 0}, /* 11 */
{245, 235, PT_BEZIERTO, 0, 0}, /* 12 */
{271, 220, PT_BEZIERTO, 0, 0}, /* 13 */
@ -289,7 +288,7 @@ static void test_anglearc(void)
CloseFigure(hdc);
EndPath(hdc);
ok_path(hdc, "anglearc_path", anglearc_path, sizeof(anglearc_path)/sizeof(path_test_t), 1);
ok_path(hdc, "anglearc_path", anglearc_path, sizeof(anglearc_path)/sizeof(path_test_t), 0);
done:
ReleaseDC(0, hdc);
}
@ -393,7 +392,6 @@ done:
}
static void test_closefigure(void) {
BOOL retb;
int nSize, nSizeWitness;
HDC hdc = GetDC(0);
@ -402,7 +400,7 @@ static void test_closefigure(void) {
LineTo(hdc, 95, 0);
LineTo(hdc, 0, 95);
retb = CloseFigure(hdc);
CloseFigure(hdc);
EndPath(hdc);
nSize = GetPath(hdc, NULL, NULL, 0);

View file

@ -2353,8 +2353,7 @@ static void test_GdipGetNearestColor(void)
expect(Ok, status);
expect(0xdeadbeef, color);
GdipDeleteGraphics(graphics);
skip("skipping GdipDisposeImage, see bug 5395\n");
//GdipDisposeImage((GpImage*)bitmap);
GdipDisposeImage((GpImage*)bitmap);
status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, &bitmap);
expect(Ok, status);
@ -2364,8 +2363,7 @@ static void test_GdipGetNearestColor(void)
expect(Ok, status);
expect(0xdeadbeef, color);
GdipDeleteGraphics(graphics);
skip("skipping GdipDisposeImage, see bug 5395\n");
//GdipDisposeImage((GpImage*)bitmap);
GdipDisposeImage((GpImage*)bitmap);
status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, &bitmap);
expect(Ok, status);
@ -2375,8 +2373,7 @@ static void test_GdipGetNearestColor(void)
expect(Ok, status);
expect(0xdeadbeef, color);
GdipDeleteGraphics(graphics);
skip("skipping GdipDisposeImage, see bug 5395\n");
//GdipDisposeImage((GpImage*)bitmap);
GdipDisposeImage((GpImage*)bitmap);
status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, &bitmap);
expect(Ok, status);

View file

@ -560,12 +560,6 @@ static void test_linei(void)
{
GpStatus status;
GpPath *path;
GpPointF points[2];
points[0].X = 7.0;
points[0].Y = 11.0;
points[1].X = 13.0;
points[1].Y = 17.0;
GdipCreatePath(FillModeAlternate, &path);
status = GdipAddPathLineI(path, 5.0, 5.0, 6.0, 8.0);

View file

@ -158,6 +158,117 @@ static void test_Scan0(void)
ok( !bm, "expected null bitmap\n" );
}
static void test_FromGdiDib(void)
{
GpBitmap *bm;
GpStatus stat;
BYTE buff[400];
BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
PixelFormat format;
bm = NULL;
memset(rbmi, 0, sizeof(rbmi));
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = 10;
bmi->bmiHeader.biHeight = 10;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = 32;
bmi->bmiHeader.biCompression = BI_RGB;
stat = GdipCreateBitmapFromGdiDib(NULL, buff, &bm);
expect(InvalidParameter, stat);
stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm);
expect(InvalidParameter, stat);
stat = GdipCreateBitmapFromGdiDib(bmi, buff, NULL);
expect(InvalidParameter, stat);
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(Ok, stat);
ok(NULL != bm, "Expected bitmap to be initialized\n");
if (stat == Ok)
{
stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
expect(Ok, stat);
expect(PixelFormat32bppRGB, format);
GdipDisposeImage((GpImage*)bm);
}
bmi->bmiHeader.biBitCount = 24;
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(Ok, stat);
ok(NULL != bm, "Expected bitmap to be initialized\n");
if (stat == Ok)
{
stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
expect(Ok, stat);
expect(PixelFormat24bppRGB, format);
GdipDisposeImage((GpImage*)bm);
}
bmi->bmiHeader.biBitCount = 16;
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(Ok, stat);
ok(NULL != bm, "Expected bitmap to be initialized\n");
if (stat == Ok)
{
stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
expect(Ok, stat);
expect(PixelFormat16bppRGB555, format);
GdipDisposeImage((GpImage*)bm);
}
bmi->bmiHeader.biBitCount = 8;
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(Ok, stat);
ok(NULL != bm, "Expected bitmap to be initialized\n");
if (stat == Ok)
{
stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
expect(Ok, stat);
expect(PixelFormat8bppIndexed, format);
GdipDisposeImage((GpImage*)bm);
}
bmi->bmiHeader.biBitCount = 4;
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(Ok, stat);
ok(NULL != bm, "Expected bitmap to be initialized\n");
if (stat == Ok)
{
stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
expect(Ok, stat);
expect(PixelFormat4bppIndexed, format);
GdipDisposeImage((GpImage*)bm);
}
bmi->bmiHeader.biBitCount = 1;
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(Ok, stat);
ok(NULL != bm, "Expected bitmap to be initialized\n");
if (stat == Ok)
{
stat = GdipGetImagePixelFormat((GpImage*)bm, &format);
expect(Ok, stat);
expect(PixelFormat1bppIndexed, format);
GdipDisposeImage((GpImage*)bm);
}
bmi->bmiHeader.biBitCount = 0;
stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
expect(InvalidParameter, stat);
}
static void test_GetImageDimension(void)
{
GpBitmap *bm;
@ -1101,6 +1212,78 @@ static void test_createhbitmap(void)
expect(Ok, stat);
}
static void test_getthumbnail(void)
{
GpStatus stat;
GpImage *bitmap1, *bitmap2;
UINT width, height;
stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL);
expect(InvalidParameter, stat);
stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
expect(Ok, stat);
stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
expect(InvalidParameter, stat);
stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
expect(Ok, stat);
if (stat == Ok)
{
stat = GdipGetImageWidth(bitmap2, &width);
expect(Ok, stat);
expect(120, width);
stat = GdipGetImageHeight(bitmap2, &height);
expect(Ok, stat);
expect(120, height);
GdipDisposeImage(bitmap2);
}
GdipDisposeImage(bitmap1);
stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
expect(Ok, stat);
stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
expect(Ok, stat);
if (stat == Ok)
{
stat = GdipGetImageWidth(bitmap2, &width);
expect(Ok, stat);
expect(32, width);
stat = GdipGetImageHeight(bitmap2, &height);
expect(Ok, stat);
expect(32, height);
GdipDisposeImage(bitmap2);
}
stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
expect(Ok, stat);
if (stat == Ok)
{
stat = GdipGetImageWidth(bitmap2, &width);
expect(Ok, stat);
expect(120, width);
stat = GdipGetImageHeight(bitmap2, &height);
expect(Ok, stat);
expect(120, height);
GdipDisposeImage(bitmap2);
}
GdipDisposeImage(bitmap1);
}
static void test_getsetpixel(void)
{
GpStatus stat;
@ -1888,6 +2071,76 @@ static void test_remaptable(void)
GdipFree(map);
}
static void test_colorkey(void)
{
GpStatus stat;
GpImageAttributes *imageattr;
GpBitmap *bitmap1, *bitmap2;
GpGraphics *graphics;
ARGB color;
stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
expect(InvalidParameter, stat);
stat = GdipCreateImageAttributes(&imageattr);
expect(Ok, stat);
stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
expect(InvalidParameter, stat);
stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
expect(InvalidParameter, stat);
stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
expect(Ok, stat);
stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1);
expect(Ok, stat);
stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2);
expect(Ok, stat);
stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
expect(Ok, stat);
stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
expect(Ok, stat);
stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
expect(Ok, stat);
stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
expect(Ok, stat);
stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics);
expect(Ok, stat);
stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
UnitPixel, imageattr, NULL, NULL);
expect(Ok, stat);
stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
expect(Ok, stat);
ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
expect(Ok, stat);
ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
expect(Ok, stat);
ok(color_match(0x00000000, color, 1), "Expected ffff00ff, got %.8x\n", color);
stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
expect(Ok, stat);
ok(color_match(0xffffffff, color, 1), "Expected ffff00ff, got %.8x\n", color);
GdipDeleteGraphics(graphics);
GdipDisposeImage((GpImage*)bitmap1);
GdipDisposeImage((GpImage*)bitmap2);
GdipDisposeImageAttributes(imageattr);
}
START_TEST(image)
{
struct GdiplusStartupInput gdiplusStartupInput;
@ -1901,6 +2154,7 @@ START_TEST(image)
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
test_Scan0();
test_FromGdiDib();
test_GetImageDimension();
test_GdipImageGetFrameDimensionsCount();
test_LoadingImages();
@ -1917,6 +2171,7 @@ START_TEST(image)
test_createfromwmf();
test_resolution();
test_createhbitmap();
test_getthumbnail();
test_getsetpixel();
test_palette();
test_colormatrix();
@ -1924,6 +2179,7 @@ START_TEST(image)
test_multiframegif();
test_rotateflip();
test_remaptable();
test_colorkey();
GdiplusShutdown(gdiplusToken);
}

View file

@ -80,11 +80,58 @@ static void test_SetInitialHlink(void)
IMoniker_Release(dummy);
}
static void test_BrowseWindowInfo(void)
{
IHlinkBrowseContext *bc;
HLBWINFO bwinfo_set, bwinfo_get;
HRESULT hres;
hres = HlinkCreateBrowseContext(NULL, &IID_IHlinkBrowseContext, (void**)&bc);
ok(hres == S_OK, "HlinkCreateBrowseContext failed: 0x%08x\n", hres);
hres = IHlinkBrowseContext_GetBrowseWindowInfo(bc, NULL);
ok(hres == E_INVALIDARG, "GetBrowseWindow failed with wrong code: 0x%08x\n", hres);
hres = IHlinkBrowseContext_SetBrowseWindowInfo(bc, NULL);
ok(hres == E_INVALIDARG, "SetBrowseWindow failed with wrong code: 0x%08x\n", hres);
memset(&bwinfo_get, -1, sizeof(HLBWINFO));
hres = IHlinkBrowseContext_GetBrowseWindowInfo(bc, &bwinfo_get);
ok(hres == S_OK, "GetBrowseWindowInfo failed: 0x%08x\n", hres);
ok(bwinfo_get.cbSize == 0, "Got wrong size: %x\n", bwinfo_get.cbSize);
bwinfo_set.cbSize = sizeof(HLBWINFO);
bwinfo_set.grfHLBWIF = HLBWIF_WEBTOOLBARHIDDEN;
bwinfo_set.rcFramePos.left = 1;
bwinfo_set.rcFramePos.right = 2;
bwinfo_set.rcFramePos.top = 3;
bwinfo_set.rcFramePos.bottom = 4;
bwinfo_set.rcDocPos.left = 5;
bwinfo_set.rcDocPos.right = 6;
bwinfo_set.rcDocPos.top = 7;
bwinfo_set.rcDocPos.bottom = 8;
bwinfo_set.hltbinfo.uDockType = 4321;
bwinfo_set.hltbinfo.rcTbPos.left = 9;
bwinfo_set.hltbinfo.rcTbPos.right = 10;
bwinfo_set.hltbinfo.rcTbPos.top = 11;
bwinfo_set.hltbinfo.rcTbPos.bottom = 12;
hres = IHlinkBrowseContext_SetBrowseWindowInfo(bc, &bwinfo_set);
ok(hres == S_OK, "SetBrowseWindowInfo failed: 0x%08x\n", hres);
memset(&bwinfo_get, 0, sizeof(HLBWINFO));
hres = IHlinkBrowseContext_GetBrowseWindowInfo(bc, &bwinfo_get);
ok(hres == S_OK, "GetBrowseWindowInfo failed: 0x%08x\n", hres);
ok(!memcmp(&bwinfo_set, &bwinfo_get, sizeof(HLBWINFO)), "Set and Get differ\n");
}
START_TEST(browse_ctx)
{
CoInitialize(NULL);
test_SetInitialHlink();
test_BrowseWindowInfo();
CoUninitialize();
}

View file

@ -1093,7 +1093,8 @@ static void test_HlinkGetSetMonikerReference(void)
/* invalid HLINKSETF flags */
hres = IHlink_SetMonikerReference(hlink, 12, dummy2, two);
ok(hres == 12, "IHlink_SetMonikerReference should've failed with 0x%08x, failed with 0x%08x\n", 12, hres);
/* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
if (0) ok(hres == 12, "IHlink_SetMonikerReference should've failed with 0x%08x, failed with 0x%08x\n", 12, hres);
hres = IHlink_GetMonikerReference(hlink, HLINKGETREF_DEFAULT, &found_trgt, &found_loc);
ok(found_trgt == dummy, "Found target should've been %p, was: %p\n", dummy, found_trgt);
@ -1244,10 +1245,11 @@ static void test_HlinkGetSetStringReference(void)
CoTaskMemFree(fnd_loc);
hres = IHlink_SetStringReference(link, 4, NULL, NULL);
ok(hres == 4, "IHlink_SetStringReference should have failed with 0x4, instead: 0x%08x\n", hres);
/* Windows returns garbage; on 32-bit it returns the flags probably because the compiler happened to store them in %eax at some point */
if (0) ok(hres == 4, "IHlink_SetStringReference should have failed with 0x4, instead: 0x%08x\n", hres);
hres = IHlink_SetStringReference(link, -4, NULL, NULL);
ok(hres == -4, "IHlink_SetStringReference should have failed with 0xFFFFFFFC, instead: 0x%08x\n", hres);
if (0) ok(hres == -4, "IHlink_SetStringReference should have failed with 0xFFFFFFFC, instead: 0x%08x\n", hres);
IHlink_Release(link);
}
@ -1272,12 +1274,12 @@ static void r_getStringRef(unsigned line, IHlink *hlink, const WCHAR *exp_tgt, c
if(exp_tgt)
ok_(__FILE__,line) (!lstrcmpW(fnd_tgt, exp_tgt), "Found string target should have been %s, was: %s\n", wine_dbgstr_w(exp_tgt), wine_dbgstr_w(fnd_tgt));
else
ok_(__FILE__,line) (exp_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
ok_(__FILE__,line) (fnd_tgt == NULL, "Found string target should have been NULL, was: %s\n", wine_dbgstr_w(fnd_tgt));
if(exp_loc)
ok_(__FILE__,line) (!lstrcmpW(fnd_loc, exp_loc), "Found string location should have been %s, was: %s\n", wine_dbgstr_w(exp_loc), wine_dbgstr_w(fnd_loc));
else
ok_(__FILE__,line) (exp_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
CoTaskMemFree(fnd_tgt);
CoTaskMemFree(fnd_loc);
@ -1305,7 +1307,7 @@ static IMoniker *r_getMonikerRef(unsigned line, IHlink *hlink, IMoniker *exp_tgt
if(exp_loc)
ok_(__FILE__,line) (!lstrcmpW(fnd_loc, exp_loc), "Found string location should have been %s, was: %s\n", wine_dbgstr_w(exp_loc), wine_dbgstr_w(fnd_loc));
else
ok_(__FILE__,line) (exp_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
ok_(__FILE__,line) (fnd_loc == NULL, "Found string location should have been NULL, was: %s\n", wine_dbgstr_w(fnd_loc));
CoTaskMemFree(fnd_loc);
@ -1363,6 +1365,83 @@ static void test_HlinkMoniker(void)
IHlink_Release(hlink);
}
static void test_HashLink(void)
{
IHlink *hlink;
IMoniker *pmk;
const WCHAR hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r',0};
const WCHAR two_hash_targetW[] = {'a','f','i','l','e','#','a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
const WCHAR hash_no_tgtW[] = {'#','a','n','a','n','c','h','o','r',0};
const WCHAR tgt_partW[] = {'a','f','i','l','e',0};
const WCHAR loc_partW[] = {'a','n','a','n','c','h','o','r',0};
const WCHAR two_hash_loc_partW[] = {'a','n','a','n','c','h','o','r','#','a','n','o','t','h','e','r',0};
const WCHAR test_locW[] = {'t','e','s','t','l','o','c',0};
HRESULT hres;
/* simple single hash test */
hres = HlinkCreateFromString(hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
ok(hlink != NULL, "Didn't get an hlink\n");
if(hlink){
getStringRef(hlink, tgt_partW, loc_partW);
pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
ok(pmk != NULL, "Found moniker should not be NULL\n");
if(pmk)
IMoniker_Release(pmk);
setStringRef(hlink, HLINKSETF_TARGET, hash_targetW, NULL);
getStringRef(hlink, hash_targetW, loc_partW);
IHlink_Release(hlink);
}
/* two hashes in the target */
hres = HlinkCreateFromString(two_hash_targetW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
ok(hlink != NULL, "Didn't get an hlink\n");
if(hlink){
getStringRef(hlink, tgt_partW, two_hash_loc_partW);
pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, two_hash_loc_partW);
ok(pmk != NULL, "Found moniker should not be NULL\n");
if(pmk)
IMoniker_Release(pmk);
IHlink_Release(hlink);
}
/* target with hash plus a location string */
hres = HlinkCreateFromString(hash_targetW, test_locW, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
ok(hlink != NULL, "Didn't get an hlink\n");
if(hlink){
getStringRef(hlink, tgt_partW, test_locW);
pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, test_locW);
ok(pmk != NULL, "Found moniker should not be NULL\n");
if(pmk)
IMoniker_Release(pmk);
IHlink_Release(hlink);
}
/* target with hash containing no "target part" */
hres = HlinkCreateFromString(hash_no_tgtW, NULL, NULL, NULL, 0, NULL, &IID_IHlink, (void*)&hlink);
ok(hres == S_OK, "HlinkCreateFromString failed: 0x%08x\n", hres);
ok(hlink != NULL, "Didn't get an hlink\n");
if(hlink){
getStringRef(hlink, NULL, loc_partW);
pmk = getMonikerRef(hlink, (IMoniker*)0xFFFFFFFF, loc_partW);
ok(pmk == NULL, "Found moniker should be NULL\n");
if(pmk)
IMoniker_Release(pmk);
IHlink_Release(hlink);
}
}
START_TEST(hlink)
{
CoInitialize(NULL);
@ -1377,6 +1456,7 @@ START_TEST(hlink)
test_HlinkGetSetMonikerReference();
test_HlinkGetSetStringReference();
test_HlinkMoniker();
test_HashLink();
CoUninitialize();
}

View file

@ -26,6 +26,8 @@
#define NUMELEMS(array) (sizeof((array))/sizeof((array)[0]))
static BOOL (WINAPI *pImmAssociateContextEx)(HWND,HIMC,DWORD);
/*
* msgspy - record and analyse message traces sent to a certain window
*/
@ -90,7 +92,7 @@ static void msg_spy_flush_msgs(void) {
}
static CWPSTRUCT* msg_spy_find_msg(UINT message) {
int i;
UINT i;
msg_spy_pump_msg_queue();
@ -118,7 +120,7 @@ static void msg_spy_init(HWND hwnd) {
msg_spy_flush_msgs();
}
static void msg_spy_cleanup() {
static void msg_spy_cleanup(void) {
if (msg_spy.get_msg_hook)
UnhookWindowsHookEx(msg_spy.get_msg_hook);
if (msg_spy.call_wnd_proc_hook)
@ -133,9 +135,13 @@ static void msg_spy_cleanup() {
static const char wndcls[] = "winetest_imm32_wndcls";
static HWND hwnd;
static int init(void) {
static BOOL init(void) {
WNDCLASSEX wc;
HIMC imc;
HMODULE hmod;
hmod = GetModuleHandleA("imm32.dll");
pImmAssociateContextEx = (void*)GetProcAddress(hmod, "ImmAssociateContextEx");
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
@ -151,19 +157,19 @@ static int init(void) {
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassExA(&wc))
return 0;
return FALSE;
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
240, 120, NULL, NULL, GetModuleHandle(0), NULL);
if (!hwnd)
return 0;
return FALSE;
imc = ImmGetContext(hwnd);
if (!imc)
{
win_skip("IME support not implemented\n");
return 0;
return FALSE;
}
ImmReleaseContext(hwnd, imc);
@ -172,7 +178,7 @@ static int init(void) {
msg_spy_init(hwnd);
return 1;
return TRUE;
}
static void cleanup(void) {
@ -191,11 +197,10 @@ static void test_ImmNotifyIME(void) {
imc = ImmGetContext(hwnd);
msg_spy_flush_msgs();
todo_wine
{
ok(!ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0), "Canceling an "
"empty composition string should fail.\n");
}
ret = ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ok(broken(!ret) ||
ret, /* Vista+ */
"Canceling an empty composition string should succeed.\n");
ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
"WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
"the composition string being canceled is empty.\n");
@ -210,15 +215,14 @@ static void test_ImmNotifyIME(void) {
/* behavior differs between win9x and NT */
ret = ImmGetCompositionString(imc, GCS_COMPSTR, resstr, sizeof(resstr));
ok(ret || !ret, "You'll never read this.\n");
ok(!ret, "After being cancelled the composition string is empty.\n");
msg_spy_flush_msgs();
todo_wine
{
ok(!ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0), "Canceling an "
"empty composition string should fail.\n");
}
ret = ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ok(broken(!ret) ||
ret, /* Vista+ */
"Canceling an empty composition string should succeed.\n");
ok(!msg_spy_find_msg(WM_IME_COMPOSITION), "Windows does not post "
"WM_IME_COMPOSITION in response to NI_COMPOSITIONSTR / CPS_CANCEL, if "
"the composition string being canceled is empty.\n");
@ -263,22 +267,24 @@ static void test_ImmSetCompositionString(void)
return;
ret = ImmSetCompositionStringW(imc, SCS_SETSTR, NULL, 0, NULL, 0);
todo_wine
ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
ok(broken(!ret) ||
ret, /* Vista+ */
"ImmSetCompositionStringW() failed.\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");
ret = ImmSetCompositionStringW(imc, SCS_SETSTR | SCS_CHANGEATTR | SCS_CHANGECLAUSE,
NULL, 0, NULL, 0);
ok(!ret, "ImmSetCompositionStringW() succeeded.\n");
ImmReleaseContext(hwnd, imc);
@ -300,6 +306,45 @@ static void test_ImmIME(void)
ImmReleaseContext(hwnd,imc);
}
static void test_ImmAssociateContextEx(void)
{
HIMC imc;
BOOL rc;
if (!pImmAssociateContextEx) return;
imc = ImmGetContext(hwnd);
if (imc)
{
HIMC retimc, newimc;
newimc = ImmCreateContext();
ok(newimc != imc, "handles should not be the same\n");
rc = pImmAssociateContextEx(NULL, NULL, 0);
ok(!rc, "ImmAssociateContextEx succeeded\n");
rc = pImmAssociateContextEx(hwnd, NULL, 0);
ok(rc, "ImmAssociateContextEx failed\n");
rc = pImmAssociateContextEx(NULL, imc, 0);
ok(!rc, "ImmAssociateContextEx succeeded\n");
rc = pImmAssociateContextEx(hwnd, imc, 0);
ok(rc, "ImmAssociateContextEx failed\n");
retimc = ImmGetContext(hwnd);
ok(retimc == imc, "handles should be the same\n");
ImmReleaseContext(hwnd,retimc);
rc = pImmAssociateContextEx(hwnd, newimc, 0);
ok(rc, "ImmAssociateContextEx failed\n");
retimc = ImmGetContext(hwnd);
ok(retimc == newimc, "handles should be the same\n");
ImmReleaseContext(hwnd,retimc);
rc = pImmAssociateContextEx(hwnd, NULL, IACE_DEFAULT);
ok(rc, "ImmAssociateContextEx failed\n");
}
ImmReleaseContext(hwnd,imc);
}
START_TEST(imm32) {
if (init())
{
@ -307,6 +352,7 @@ START_TEST(imm32) {
test_ImmGetCompositionString();
test_ImmSetCompositionString();
test_ImmIME();
test_ImmAssociateContextEx();
}
cleanup();
}

View file

@ -2129,7 +2129,7 @@ ok(ActiveXObject.length == 1, "ActiveXObject.length = " + ActiveXObject.length);
ok(Array.length == 1, "Array.length = " + Array.length);
ok(Boolean.length == 1, "Boolean.length = " + Boolean.length);
ok(CollectGarbage.length == 0, "CollectGarbage.length = " + CollectGarbage.length);
//ok(Date.length == 7, "Date.length = " + Date.length);
ok(Date.length == 7, "Date.length = " + Date.length);
ok(Enumerator.length == 7, "Enumerator.length = " + Enumerator.length);
ok(Error.length == 1, "Error.length = " + Error.length);
ok(EvalError.length == 1, "EvalError.length = " + EvalError.length);
@ -2147,7 +2147,7 @@ ok(ScriptEngineMajorVersion.length == 0,
"ScriptEngineMajorVersion.length = " + ScriptEngineMajorVersion.length);
ok(ScriptEngineMinorVersion.length == 0,
"ScriptEngineMinorVersion.length = " + ScriptEngineMinorVersion.length);
//ok(String.length == 1, "String.length = " + String.length);
ok(String.length == 1, "String.length = " + String.length);
ok(SyntaxError.length == 1, "SyntaxError.length = " + SyntaxError.length);
ok(TypeError.length == 1, "TypeError.length = " + TypeError.length);
ok(URIError.length == 1, "URIError.length = " + URIError.length);
@ -2164,4 +2164,7 @@ ok(parseFloat.length == 1, "parseFloat.length = " + parseFloat.length);
ok(parseInt.length == 2, "parseInt.length = " + parseInt.length);
ok(unescape.length == 1, "unescape.length = " + unescape.length);
String.length = 3;
ok(String.length == 1, "String.length = " + String.length);
reportSuccess();

View file

@ -263,7 +263,9 @@ ok(tmp === 7, "2*3.5 !== 7");
ok(getVT(tmp) === "VT_I4", "getVT(2*3.5) !== VT_I4");
tmp = 2.5*3.5;
ok(tmp === 8.75, "2.5*3.5 !== 8.75");
/* FIXME: the parser loses precision */
/* ok(tmp === 8.75, "2.5*3.5 !== 8.75"); */
ok(tmp > 8.749999 && tmp < 8.750001, "2.5*3.5 !== 8.75");
ok(getVT(tmp) === "VT_R8", "getVT(2.5*3.5) !== VT_R8");
tmp = 4/2;

View file

@ -19,6 +19,10 @@
var m, re, b, i, obj;
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
RegExp.leftContext = "abc";
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
re = /a+/;
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
@ -28,6 +32,8 @@ ok(m.index === 1, "m.index = " + m.index);
ok(m.input === " aabaaa", "m.input = " + m.input);
ok(m.length === 1, "m.length = " + m.length);
ok(m[0] === "aa", "m[0] = " + m[0]);
ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "baaa", "RegExp.rightContext = " + RegExp.rightContext);
m = re.exec(" aabaaa");
ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
@ -35,6 +41,8 @@ ok(m.index === 1, "m.index = " + m.index);
ok(m.input === " aabaaa", "m.input = " + m.input);
ok(m.length === 1, "m.length = " + m.length);
ok(m[0] === "aa", "m[0] = " + m[0]);
ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "baaa", "RegExp.rightContext = " + RegExp.rightContext);
re = /a+/g;
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
@ -59,6 +67,9 @@ ok(m === null, "m is not null");
re.exec(" a");
ok(re.lastIndex === 16, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === " ",
"RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
m = re.exec(" a");
ok(m === null, "m is not null");
@ -79,10 +90,14 @@ ok(m[2] === "", "m[2] = " + m[2]);
b = re.test(" a ");
ok(b === true, "re.test(' a ') returned " + b);
ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " ", "RegExp.rightContext = " + RegExp.rightContext);
b = re.test(" a ");
ok(b === false, "re.test(' a ') returned " + b);
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " ", "RegExp.rightContext = " + RegExp.rightContext);
re = /\[([^\[]+)\]/g;
m = re.exec(" [test] ");
@ -95,6 +110,18 @@ ok(m[1] === "test", "m[1] = " + m[1]);
b = /a*/.test();
ok(b === true, "/a*/.test() returned " + b);
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "undefined", "RegExp.rightContext = " + RegExp.rightContext);
b = /f/.test();
ok(b === true, "/f/.test() returned " + b);
ok(RegExp.leftContext === "unde", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "ined", "RegExp.rightContext = " + RegExp.rightContext);
b = /abc/.test();
ok(b === false, "/abc/.test() returned " + b);
ok(RegExp.leftContext === "unde", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "ined", "RegExp.rightContext = " + RegExp.rightContext);
m = "abcabc".match(re = /ca/);
ok(typeof(m) === "object", "typeof m is not object");
@ -102,11 +129,15 @@ ok(m.length === 1, "m.length is not 1");
ok(m["0"] === "ca", "m[0] is not \"ca\"");
ok(m.constructor === Array, "unexpected m.constructor");
ok(re.lastIndex === 4, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === "ab", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "bc", "RegExp.rightContext = " + RegExp.rightContext);
m = "abcabc".match(/ab/);
ok(typeof(m) === "object", "typeof m is not object");
ok(m.length === 1, "m.length is not 1");
ok(m["0"] === "ab", "m[0] is not \"ab\"");
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "cabc", "RegExp.rightContext = " + RegExp.rightContext);
m = "abcabc".match(/ab/g);
ok(typeof(m) === "object", "typeof m is not object");
@ -124,6 +155,8 @@ ok(typeof(m) === "object", "typeof m is not object");
ok(m.length === 2, "m.length is not 2");
ok(m["0"] === "ab", "m[0] is not \"ab\"");
ok(m["1"] === "ab", "m[1] is not \"ab\"");
ok(RegExp.leftContext === "abc", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "c", "RegExp.rightContext = " + RegExp.rightContext);
m = "aaabcabc".match(/a+b/g);
ok(typeof(m) === "object", "typeof m is not object");
@ -147,6 +180,8 @@ ok(typeof(m) === "object", "typeof m is not object");
ok(m.length === 2, "m.length is not 2");
ok(m["0"] === "ab", "m[0] is not \"ab\"");
ok(m["1"] === "ab", "m[1] is not \"ab\"");
ok(RegExp.leftContext === "abc", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "c", "RegExp.rightContext = " + RegExp.rightContext);
m = "abcabc".match(new RegExp(/ab/g));
ok(typeof(m) === "object", "typeof m is not object");
@ -164,9 +199,13 @@ m = "abcabcg".match("ab", "g");
ok(typeof(m) === "object", "typeof m is not object");
ok(m.length === 1, "m.length is not 1");
ok(m["0"] === "ab", "m[0] is not \"ab\"");
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "cabcg", "RegExp.rightContext = " + RegExp.rightContext);
m = "abcabc".match();
ok(m === null, "m is not null");
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "cabcg", "RegExp.rightContext = " + RegExp.rightContext);
m = "abcabc".match(/(a)(b)cabc/);
ok(typeof(m) === "object", "typeof m is not object");
@ -197,9 +236,15 @@ ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
r = "- [test] -".replace(re = /\[([^\[]+)\]/g, "success");
ok(r === "- success -", "r = " + r + " expected '- success -'");
ok(re.lastIndex === 8, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === "- ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " -", "RegExp.rightContext = " + RegExp.rightContext);
r = "[test] [test]".replace(/\[([^\[]+)\]/g, "aa");
ok(r === "aa aa", "r = " + r + "aa aa");
ok(RegExp.leftContext === "[test] ",
"RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "",
"RegExp.rightContext = " + RegExp.rightContext);
r = "[test] [test]".replace(/\[([^\[]+)\]/, "aa");
ok(r === "aa [test]", "r = " + r + " expected 'aa [test]'");
@ -212,6 +257,8 @@ ok(r === "- true -", "r = " + r + " expected '- true -'");
r = "- [test] -".replace(/\[([^\[]+)\]/g, true, "test");
ok(r === "- true -", "r = " + r + " expected '- true -'");
ok(RegExp.leftContext === "- ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " -", "RegExp.rightContext = " + RegExp.rightContext);
var tmp = 0;
@ -222,10 +269,18 @@ function replaceFunc1(m, off, str) {
case 0:
ok(m === "[test1]", "m = " + m + " expected [test1]");
ok(off === 0, "off = " + off + " expected 0");
ok(RegExp.leftContext === "- ",
"RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " -",
"RegExp.rightContext = " + RegExp.rightContext);
break;
case 1:
ok(m === "[test2]", "m = " + m + " expected [test2]");
ok(off === 8, "off = " + off + " expected 8");
ok(RegExp.leftContext === "- ",
"RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " -",
"RegExp.rightContext = " + RegExp.rightContext);
break;
default:
ok(false, "unexpected call");
@ -237,6 +292,8 @@ function replaceFunc1(m, off, str) {
r = "[test1] [test2]".replace(/\[[^\[]+\]/g, replaceFunc1);
ok(r === "r0 r1", "r = " + r + " expected 'r0 r1'");
ok(RegExp.leftContext === "[test1] ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
tmp = 0;
@ -267,9 +324,13 @@ ok(r === "r0 r1", "r = '" + r + "' expected 'r0 r1'");
r = "$1,$2".replace(/(\$(\d))/g, "$$1-$1$2");
ok(r === "$1-$11,$1-$22", "r = '" + r + "' expected '$1-$11,$1-$22'");
ok(RegExp.leftContext === "$1,", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
r = "abc &1 123".replace(/(\&(\d))/g, "$&");
ok(r === "abc &1 123", "r = '" + r + "' expected 'abc &1 123'");
ok(RegExp.leftContext === "abc ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " 123", "RegExp.rightContext = " + RegExp.rightContext);
r = "abc &1 123".replace(/(\&(\d))/g, "$'");
ok(r === "abc 123 123", "r = '" + r + "' expected 'abc 123 123'");
@ -292,8 +353,11 @@ ok(r === "abc &11 123", "r = '" + r + "' expected 'abc &11 123'");
r = "abc &1 123".replace(/(\&(\d))/g, "$0");
ok(r === "abc $0 123", "r = '" + r + "' expected 'abc $0 123'");
/a/.test("a");
r = "1 2 3".replace("2", "$&");
ok(r === "1 $& 3", "r = '" + r + "' expected '1 $& 3'");
ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
r = "1 2 3".replace("2", "$'");
ok(r === "1 $' 3", "r = '" + r + "' expected '1 $' 3'");
@ -303,6 +367,8 @@ ok(r.length === 3, "r.length = " + r.length);
ok(r[0] === "1", "r[0] = " + r[0]);
ok(r[1] === "2", "r[1] = " + r[1]);
ok(r[2] === "3", "r[2] = " + r[2]);
ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
r = "1,,2,3".split(/,+/);
ok(r.length === 3, "r.length = " + r.length);
@ -341,6 +407,8 @@ ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
r = "1 12 \t3".split(re = /(\s)+/g).join(";");
ok(r === "1;12;3", "r = " + r);
ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === "1 12", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
re = /,+/;
re.lastIndex = 4;
@ -374,6 +442,8 @@ ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
m = re.exec(" a ");
ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 2");
ok(m.index === 1, "m.index = " + m.index + " expected 1");
ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " ", "RegExp.rightContext = " + RegExp.rightContext);
m = re.exec(" a ");
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
@ -443,6 +513,8 @@ ok(re.lastIndex === -3, "re.lastIndex = " + re.lastIndex + " expected -3");
m = re.exec(" a a ");
ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 0");
ok(m.index === 1, "m = " + m + " expected 1");
ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === " a ", "RegExp.rightContext = " + RegExp.rightContext);
re.lastIndex = -1;
ok(re.lastIndex === -1, "re.lastIndex = " + re.lastIndex + " expected -1");
@ -454,6 +526,8 @@ re = /aa/g;
i = 'baacd'.search(re);
ok(i === 1, "'baacd'.search(re) = " + i);
ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === "b", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "cd", "RegExp.rightContext = " + RegExp.rightContext);
re.lastIndex = 2;
i = 'baacdaa'.search(re);
@ -469,12 +543,16 @@ re.lastIndex = 2;
i = 'baacdaa'.search(re);
ok(i === 1, "'baacd'.search(re) = " + i);
ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === "b", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "cdaa", "RegExp.rightContext = " + RegExp.rightContext);
re = /d/g;
re.lastIndex = 1;
i = 'abc'.search(re);
ok(i === -1, "'abc'.search(/d/g) = " + i);
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
ok(RegExp.leftContext === "b", "RegExp.leftContext = " + RegExp.leftContext);
ok(RegExp.rightContext === "cdaa", "RegExp.rightContext = " + RegExp.rightContext);
i = 'abcdde'.search(/[df]/);
ok(i === 3, "'abc'.search(/[df]/) = " + i);

View file

@ -144,7 +144,9 @@ static int load_blackbox(const char* logfile, void* blackbox, int size)
ok(0, "unable to open '%s'\n", logfile);
return 0;
}
SetLastError(0xdeadbeef);
ret=ReadFile(hFile, blackbox, size, &read, NULL);
ok(ret, "ReadFile failed: %d\n", GetLastError());
ok(read == size, "wrong size for '%s': read=%d\n", logfile, read);
CloseHandle(hFile);
return 1;

View file

@ -591,6 +591,11 @@ static void test_CopyFileA(void)
ret = MoveFileA(source, source);
todo_wine ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
/* copying a file to itself must fail */
retok = CopyFileA(source, source, FALSE);
ok( !retok && (GetLastError() == ERROR_SHARING_VIOLATION || broken(GetLastError() == ERROR_FILE_EXISTS) /* Win 9x */),
"copying a file to itself didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
/* make the source have not zero size */
hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
@ -618,6 +623,70 @@ static void test_CopyFileA(void)
ret = CopyFileA(source, dest, FALSE);
ok(ret, "CopyFileA: error %d\n", GetLastError());
/* copying from a read-locked source fails */
hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
retok = CopyFileA(source, dest, FALSE);
ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
"copying from a read-locked file succeeded when it shouldn't have\n");
/* in addition, the source is opened before the destination */
retok = CopyFileA("25f99d3b-4ba4-4f66-88f5-2906886993cc", dest, FALSE);
ok(!retok && GetLastError() == ERROR_FILE_NOT_FOUND,
"copying from a file that doesn't exist failed in an unexpected way (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
/* copying from a r+w opened, r shared source succeeds */
hfile = CreateFileA(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
retok = CopyFileA(source, dest, FALSE);
ok(retok,
"copying from an r+w opened and r shared file failed (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
/* copying from a delete-locked source is unreliable */
hfile = CreateFileA(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
retok = CopyFileA(source, dest, FALSE);
ok((!retok && GetLastError() == ERROR_SHARING_VIOLATION) || broken(retok) /* 98, Vista, 2k8, 7 */,
"copying from a delete-locked file failed (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
/* copying to a write-locked destination fails */
hfile = CreateFileA(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
retok = CopyFileA(source, dest, FALSE);
ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
"copying to a write-locked file didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
/* copying to a r+w opened, w shared destination mostly succeeds */
hfile = CreateFileA(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
retok = CopyFileA(source, dest, FALSE);
ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
"copying to a r+w opened and w shared file failed (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
/* copying to a delete-locked destination fails, even when the destination is delete-shared */
hfile = CreateFileA(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Win 9x */,
"failed to open destination file, error %d\n", GetLastError());
if (hfile != INVALID_HANDLE_VALUE)
{
retok = CopyFileA(source, dest, FALSE);
ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
"copying to a delete-locked shared file didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
}
/* copy to a file that's opened the way Wine opens the source */
hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
retok = CopyFileA(source, dest, FALSE);
ok(retok || broken(GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
"copying to a file opened the way Wine opens the source failed (ret=%d, err=%d)\n", retok, GetLastError());
CloseHandle(hfile);
/* make sure that destination has correct size */
hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,6 @@
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include "wine/test.h"
#define MAGIC_DEAD 0xdeadbeef
@ -250,14 +249,27 @@ static void test_heap(void)
res = GlobalUnlock(gbl);
ok(res == 1 ||
res == 0, /* win9x */
broken(res == 0), /* win9x */
"Expected 1 or 0, got %d\n", res);
res = GlobalUnlock(gbl);
ok(res == 1 ||
res == 0, /* win9x */
broken(res == 0), /* win9x */
"Expected 1 or 0, got %d\n", res);
GlobalFree(gbl);
gbl = GlobalAlloc(GMEM_FIXED, 100);
SetLastError(0xdeadbeef);
res = GlobalUnlock(gbl);
ok(res == 1 ||
broken(res == 0), /* win9x */
"Expected 1 or 0, got %d\n", res);
ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError());
GlobalFree(gbl);
/* GlobalSize on an invalid handle */
if (sizeof(void *) != 8) /* crashes on 64-bit Vista */
{
@ -269,8 +281,6 @@ static void test_heap(void)
"Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
GlobalFree(gbl);
/* ####################################### */
/* Local*() functions */
gbl = LocalAlloc(LMEM_MOVEABLE, 0);
@ -372,6 +382,15 @@ static void test_heap(void)
"returned %d with %d (expected '0' with ERROR_INVALID_HANDLE)\n",
res, GetLastError());
/* trying to unlock pointer from LocalAlloc */
gbl = LocalAlloc(LMEM_FIXED, 100);
SetLastError(0xdeadbeef);
res = LocalUnlock(gbl);
ok(res == 0, "Expected 0, got %d\n", res);
ok(GetLastError() == ERROR_NOT_LOCKED ||
broken(GetLastError() == 0xdeadbeef) /* win9x */, "got %d\n", GetLastError());
LocalFree(gbl);
/* trying to lock empty memory should give an error */
gbl = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,0);
ok(gbl != NULL, "returned NULL\n");

View file

@ -1347,6 +1347,9 @@ static void test_CompareStringA(void)
ret = CompareStringA(lcid, NORM_IGNORECASE | LOCALE_USE_CP_ACP, "#", -1, ".", -1);
todo_wine ok(ret == CSTR_LESS_THAN, "\"#\" vs \".\" expected CSTR_LESS_THAN, got %d\n", ret);
ret = CompareStringA(lcid, NORM_IGNORECASE, "_", -1, ".", -1);
todo_wine ok(ret == CSTR_GREATER_THAN, "\"_\" vs \".\" expected CSTR_GREATER_THAN, got %d\n", ret);
ret = lstrcmpi("#", ".");
todo_wine ok(ret == -1, "\"#\" vs \".\" expected -1, got %d\n", ret);
}

View file

@ -1569,6 +1569,120 @@ if (0)
"Expected ERROR_INVALID_PARAMETER, got %x\n", GetLastError());
}
static void test_GetFullPathNameA(void)
{
char output[MAX_PATH], *filepart;
DWORD ret;
int is_win9x, i;
const struct
{
LPCSTR name;
DWORD len;
LPSTR buffer;
LPSTR *lastpart;
int win9x_crash;
} invalid_parameters[] =
{
{NULL, 0, NULL, NULL, 1},
{NULL, MAX_PATH, NULL, NULL, 1},
{NULL, MAX_PATH, output, NULL, 1},
{NULL, MAX_PATH, output, &filepart, 1},
{"", 0, NULL, NULL},
{"", MAX_PATH, NULL, NULL},
{"", MAX_PATH, output, NULL},
{"", MAX_PATH, output, &filepart},
};
SetLastError(0xdeadbeef);
ret = GetFullPathNameW(NULL, 0, NULL, NULL);
is_win9x = !ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
if (is_win9x)
win_skip("Skipping some tests that cause GetFullPathNameA to crash on Win9x\n");
for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
{
if (is_win9x && invalid_parameters[i].win9x_crash)
continue;
SetLastError(0xdeadbeef);
strcpy(output, "deadbeef");
filepart = (char *)0xdeadbeef;
ret = GetFullPathNameA(invalid_parameters[i].name,
invalid_parameters[i].len,
invalid_parameters[i].buffer,
invalid_parameters[i].lastpart);
ok(!ret, "[%d] Expected GetFullPathNameA to return 0, got %u\n", i, ret);
ok(!strcmp(output, "deadbeef"), "[%d] Expected the output buffer to be unchanged, got \"%s\"\n", i, output);
ok(filepart == (char *)0xdeadbeef, "[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
ok(GetLastError() == 0xdeadbeef ||
GetLastError() == ERROR_BAD_PATHNAME || /* Win9x */
GetLastError() == ERROR_INVALID_NAME, /* Win7 */
"[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
i, GetLastError());
}
}
static void test_GetFullPathNameW(void)
{
static const WCHAR emptyW[] = {0};
static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
WCHAR output[MAX_PATH], *filepart;
DWORD ret;
int i;
const struct
{
LPCWSTR name;
DWORD len;
LPWSTR buffer;
LPWSTR *lastpart;
int win7_expect;
} invalid_parameters[] =
{
{NULL, 0, NULL, NULL},
{NULL, 0, NULL, &filepart, 1},
{NULL, MAX_PATH, NULL, NULL},
{NULL, MAX_PATH, output, NULL},
{NULL, MAX_PATH, output, &filepart, 1},
{emptyW, 0, NULL, NULL},
{emptyW, 0, NULL, &filepart, 1},
{emptyW, MAX_PATH, NULL, NULL},
{emptyW, MAX_PATH, output, NULL},
{emptyW, MAX_PATH, output, &filepart, 1},
};
SetLastError(0xdeadbeef);
ret = GetFullPathNameW(NULL, 0, NULL, NULL);
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip("GetFullPathNameW is not available\n");
return;
}
for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
{
SetLastError(0xdeadbeef);
lstrcpyW(output, deadbeefW);
filepart = (WCHAR *)0xdeadbeef;
ret = GetFullPathNameW(invalid_parameters[i].name,
invalid_parameters[i].len,
invalid_parameters[i].buffer,
invalid_parameters[i].lastpart);
ok(!ret, "[%d] Expected GetFullPathNameW to return 0, got %u\n", i, ret);
ok(!lstrcmpW(output, deadbeefW), "[%d] Expected the output buffer to be unchanged, got %s\n", i, wine_dbgstr_w(output));
ok(filepart == (WCHAR *)0xdeadbeef ||
(invalid_parameters[i].win7_expect && filepart == NULL),
"[%d] Expected output file part pointer to be untouched, got %p\n", i, filepart);
ok(GetLastError() == 0xdeadbeef ||
GetLastError() == ERROR_INVALID_NAME, /* Win7 */
"[%d] Expected GetLastError() to return 0xdeadbeef, got %u\n",
i, GetLastError());
}
}
static void init_pointers(void)
{
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
@ -1601,8 +1715,7 @@ START_TEST(path)
test_CleanupPathA(origdir,curdir);
test_GetTempPath();
test_GetLongPathNameA();
skip("skipping test_GetLongPathNameW(), bug 5370\n");
//test_GetLongPathNameW();
test_GetLongPathNameW();
test_GetShortPathNameW();
test_GetSystemDirectory();
test_GetWindowsDirectory();
@ -1611,4 +1724,6 @@ START_TEST(path)
test_drive_letter_case();
test_SearchPathA();
test_SearchPathW();
test_GetFullPathNameA();
test_GetFullPathNameW();
}

View file

@ -547,28 +547,36 @@ static DWORD CALLBACK serverThreadMain3(LPVOID arg)
oOverlap.hEvent = hEvent;
/* Wait for client to connect */
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");
trace("overlapped ConnectNamedPipe returned.\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);
if (i == 0) {
trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
success = ConnectNamedPipe(hnp, NULL);
err = GetLastError();
ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
trace("ConnectNamedPipe operation complete.\n");
} else {
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");
trace("overlapped ConnectNamedPipe returned.\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);
}
}
ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n");
trace("overlapped ConnectNamedPipe operation complete.\n");
}
ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n");
trace("overlapped ConnectNamedPipe operation complete.\n");
/* Echo bytes once */
memset(buf, 0, sizeof(buf));
@ -794,33 +802,39 @@ static void test_NamedPipe_2(void)
DWORD alarmThreadId;
trace("test_NamedPipe_2 starting\n");
/* Set up a ten second timeout */
/* Set up a twenty second timeout */
alarm_event = CreateEvent( NULL, TRUE, FALSE, NULL );
alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 10000, 0, &alarmThreadId);
SetLastError(0xdeadbeef);
alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 20000, 0, &alarmThreadId);
ok(alarmThread != NULL, "CreateThread failed: %d\n", GetLastError());
/* The servers we're about to exercize do try to clean up carefully,
* but to reduce the change of a test failure due to a pipe handle
/* The servers we're about to exercise do try to clean up carefully,
* but to reduce the chance of a test failure due to a pipe handle
* leak in the test code, we'll use a different pipe name for each server.
*/
/* Try server #1 */
SetLastError(0xdeadbeef);
serverThread = CreateThread(NULL, 0, serverThreadMain1, (void *)8, 0, &serverThreadId);
ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
exercizeServer(PIPENAME "serverThreadMain1", serverThread);
/* Try server #2 */
SetLastError(0xdeadbeef);
serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId);
ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
exercizeServer(PIPENAME "serverThreadMain2", serverThread);
/* Try server #3 */
SetLastError(0xdeadbeef);
serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId);
ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
exercizeServer(PIPENAME "serverThreadMain3", serverThread);
/* Try server #4 */
SetLastError(0xdeadbeef);
serverThread = CreateThread(NULL, 0, serverThreadMain4, 0, 0, &serverThreadId);
ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
exercizeServer(PIPENAME "serverThreadMain4", serverThread);
ok(SetEvent( alarm_event ), "SetEvent\n");

View file

@ -55,6 +55,8 @@
} while (0)
static HINSTANCE hkernel32;
static void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO);
static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
static LPVOID (WINAPI *pVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD);
static BOOL (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD);
static BOOL (WINAPI *pQueryFullProcessImageNameA)(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize);
@ -194,6 +196,8 @@ static int init(void)
if ((p = strrchr(exename, '/')) != NULL) exename = p + 1;
hkernel32 = GetModuleHandleA("kernel32");
pGetNativeSystemInfo = (void *) GetProcAddress(hkernel32, "GetNativeSystemInfo");
pIsWow64Process = (void *) GetProcAddress(hkernel32, "IsWow64Process");
pVirtualAllocEx = (void *) GetProcAddress(hkernel32, "VirtualAllocEx");
pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx");
pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA");
@ -523,6 +527,7 @@ static void test_Startup(void)
char buffer[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup,si;
char *result;
static CHAR title[] = "I'm the title string",
desktop[] = "winsta0\\default",
empty[] = "";
@ -656,7 +661,7 @@ static void test_Startup(void)
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
todo_wine okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
@ -695,8 +700,9 @@ static void test_Startup(void)
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
ok (startup.lpTitle == NULL || !strcmp(startup.lpTitle, selfname),
"StartupInfoA:lpTitle expected '%s' or null, got '%s'\n", selfname, startup.lpTitle);
result = getChildString( "StartupInfoA", "lpTitle" );
ok( broken(!result) || (result && !strCmp( result, selfname, 0 )),
"expected '%s' or null, got '%s'\n", selfname, result );
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
@ -734,7 +740,7 @@ static void test_Startup(void)
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
todo_wine okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
@ -771,8 +777,8 @@ static void test_Startup(void)
WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
todo_wine okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
todo_wine okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
@ -794,7 +800,6 @@ static void test_CommandLine(void)
char buffer2[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup;
DWORD len;
BOOL ret;
memset(&startup, 0, sizeof(startup));
@ -873,7 +878,7 @@ static void test_CommandLine(void)
assert(DeleteFileA(resfile) != 0);
get_file_name(resfile);
len = GetFullPathNameA(selfname, MAX_PATH, fullpath, &lpFilePart);
GetFullPathNameA(selfname, MAX_PATH, fullpath, &lpFilePart);
assert ( lpFilePart != 0);
*(lpFilePart -1 ) = 0;
p = strrchr(fullpath, '\\');
@ -895,7 +900,7 @@ static void test_CommandLine(void)
/* Using AppName */
get_file_name(resfile);
len = GetFullPathNameA(selfname, MAX_PATH, fullpath, &lpFilePart);
GetFullPathNameA(selfname, MAX_PATH, fullpath, &lpFilePart);
assert ( lpFilePart != 0);
*(lpFilePart -1 ) = 0;
p = strrchr(fullpath, '\\');
@ -1182,6 +1187,7 @@ static void test_SuspendFlag(void)
PROCESS_INFORMATION info;
STARTUPINFOA startup, us;
DWORD exit_status;
char *result;
/* let's start simplistic */
memset(&startup, 0, sizeof(startup));
@ -1207,8 +1213,9 @@ static void test_SuspendFlag(void)
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
ok (startup.lpTitle == NULL || !strcmp(startup.lpTitle, selfname),
"StartupInfoA:lpTitle expected '%s' or null, got '%s'\n", selfname, startup.lpTitle);
result = getChildString( "StartupInfoA", "lpTitle" );
ok( broken(!result) || (result && !strCmp( result, selfname, 0 )),
"expected '%s' or null, got '%s'\n", selfname, result );
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
@ -1230,6 +1237,7 @@ static void test_DebuggingFlag(void)
STARTUPINFOA startup, us;
DEBUG_EVENT de;
unsigned dbg = 0;
char *result;
/* let's start simplistic */
memset(&startup, 0, sizeof(startup));
@ -1267,8 +1275,9 @@ static void test_DebuggingFlag(void)
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
ok (startup.lpTitle == NULL || !strcmp(startup.lpTitle, selfname),
"StartupInfoA:lpTitle expected '%s' or null, got '%s'\n", selfname, startup.lpTitle);
result = getChildString( "StartupInfoA", "lpTitle" );
ok( broken(!result) || (result && !strCmp( result, selfname, 0 )),
"expected '%s' or null, got '%s'\n", selfname, result );
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
@ -1301,6 +1310,7 @@ static void test_Console(void)
const char* msg = "This is a std-handle inheritance test.";
unsigned msg_len;
BOOL run_tests = TRUE;
char *result;
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
@ -1378,8 +1388,9 @@ static void test_Console(void)
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
ok (startup.lpTitle == NULL || !strcmp(startup.lpTitle, selfname),
"StartupInfoA:lpTitle expected '%s' or null, got '%s'\n", selfname, startup.lpTitle);
result = getChildString( "StartupInfoA", "lpTitle" );
ok( broken(!result) || (result && !strCmp( result, selfname, 0 )),
"expected '%s' or null, got '%s'\n", selfname, result );
okChildInt("StartupInfoA", "dwX", startup.dwX);
okChildInt("StartupInfoA", "dwY", startup.dwY);
okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
@ -1739,6 +1750,7 @@ static void test_ProcessName(void)
static void test_Handles(void)
{
HANDLE handle = GetCurrentProcess();
HANDLE h2, h3;
BOOL ret;
DWORD code;
@ -1766,6 +1778,57 @@ static void test_Handles(void)
ok( !ret, "GetExitCodeProcess succeeded for %p\n", handle );
ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
#endif
handle = GetStdHandle( STD_ERROR_HANDLE );
ok( handle != 0, "handle %p\n", handle );
DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &h3,
0, TRUE, DUPLICATE_SAME_ACCESS );
SetStdHandle( STD_ERROR_HANDLE, h3 );
CloseHandle( (HANDLE)STD_ERROR_HANDLE );
h2 = GetStdHandle( STD_ERROR_HANDLE );
ok( h2 == 0 ||
broken( h2 == h3) || /* nt4, w2k */
broken( h2 == INVALID_HANDLE_VALUE), /* win9x */
"wrong handle %p/%p\n", h2, h3 );
SetStdHandle( STD_ERROR_HANDLE, handle );
}
static void test_SystemInfo(void)
{
SYSTEM_INFO si, nsi;
BOOL is_wow64;
if (!pGetNativeSystemInfo)
{
win_skip("GetNativeSystemInfo is not available\n");
return;
}
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
GetSystemInfo(&si);
pGetNativeSystemInfo(&nsi);
if (is_wow64)
{
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
ok(nsi.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64,
"Expected PROCESSOR_ARCHITECTURE_AMD64, got %d\n",
nsi.wProcessorArchitecture);
ok(nsi.dwProcessorType == PROCESSOR_AMD_X8664,
"Expected PROCESSOR_AMD_X8664, got %d\n",
nsi.dwProcessorType);
}
}
else
{
ok(si.wProcessorArchitecture == nsi.wProcessorArchitecture,
"Expected no difference for wProcessorArchitecture, got %d and %d\n",
si.wProcessorArchitecture, nsi.wProcessorArchitecture);
ok(si.dwProcessorType == nsi.dwProcessorType,
"Expected no difference for dwProcessorType, got %d and %d\n",
si.dwProcessorType, nsi.dwProcessorType);
}
}
START_TEST(process)
@ -1792,6 +1855,7 @@ START_TEST(process)
test_ProcessNameA();
test_ProcessName();
test_Handles();
test_SystemInfo();
/* things that can be tested:
* lookup: check the way program to be executed is searched
* handles: check the handle inheritance stuff (+sec options)

View file

@ -1329,6 +1329,89 @@ static void test_ThreadErrorMode(void)
pSetThreadErrorMode(oldmode, NULL);
}
void _fpreset(void) {} /* override the mingw fpu init code */
static inline void set_fpu_cw(WORD cw)
{
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
__asm__ volatile ("fnclex; fldcw %0" : : "m" (cw));
#endif
}
static inline WORD get_fpu_cw(void)
{
WORD cw = 0;
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
__asm__ volatile ("fnstcw %0" : "=m" (cw));
#endif
return cw;
}
struct fpu_thread_ctx
{
WORD cw;
HANDLE finished;
};
static DWORD WINAPI fpu_thread(void *param)
{
struct fpu_thread_ctx *ctx = param;
BOOL ret;
ctx->cw = get_fpu_cw();
ret = SetEvent(ctx->finished);
ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
return 0;
}
static WORD get_thread_fpu_cw(void)
{
struct fpu_thread_ctx ctx;
DWORD tid, res;
HANDLE thread;
ctx.finished = CreateEvent(NULL, FALSE, FALSE, NULL);
ok(!!ctx.finished, "Failed to create event, last error %#x.\n", GetLastError());
thread = CreateThread(NULL, 0, fpu_thread, &ctx, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError());
res = WaitForSingleObject(ctx.finished, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
res = CloseHandle(ctx.finished);
ok(!!res, "Failed to close event handle, last error %#x.\n", GetLastError());
return ctx.cw;
}
static void test_thread_fpu_cw(void)
{
WORD initial_cw, cw;
initial_cw = get_fpu_cw();
ok(initial_cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", initial_cw);
cw = get_thread_fpu_cw();
ok(cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", cw);
set_fpu_cw(0xf60);
cw = get_fpu_cw();
ok(cw == 0xf60, "Expected FPU control word 0xf60, got %#x.\n", cw);
cw = get_thread_fpu_cw();
ok(cw == 0x27f, "Expected FPU control word 0x27f, got %#x.\n", cw);
cw = get_fpu_cw();
ok(cw == 0xf60, "Expected FPU control word 0xf60, got %#x.\n", cw);
set_fpu_cw(initial_cw);
cw = get_fpu_cw();
ok(cw == initial_cw, "Expected FPU control word %#x, got %#x.\n", initial_cw, cw);
}
START_TEST(thread)
{
HINSTANCE lib;
@ -1401,4 +1484,7 @@ START_TEST(thread)
test_RegisterWaitForSingleObject();
test_TLS();
test_ThreadErrorMode();
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
test_thread_fpu_cw();
#endif
}

View file

@ -101,9 +101,9 @@ static void test_GetVersionEx(void)
static void test_VerifyVersionInfo(void)
{
OSVERSIONINFOEX info = { sizeof(info) };
OSVERSIONINFOEX info;
BOOL ret;
DWORD servicepack;
DWORD servicepack, error;
if(!pVerifyVersionInfoA || !pVerSetConditionMask)
{
@ -114,21 +114,24 @@ static void test_VerifyVersionInfo(void)
/* Before we start doing some tests we should check what the version of
* the ServicePack is. Tests on a box with no ServicePack will fail otherwise.
*/
GetVersionEx((OSVERSIONINFO *)&info);
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionExA((OSVERSIONINFO *)&info);
servicepack = info.wServicePackMajor;
memset(&info, 0, sizeof(info));
info.dwOSVersionInfoSize = sizeof(info);
ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION,
pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_BUILDNUMBER | VER_MAJORVERSION |
VER_MINORVERSION/* | VER_PLATFORMID | VER_SERVICEPACKMAJOR |
VER_SERVICEPACKMINOR | VER_SUITENAME | VER_PRODUCT_TYPE */,
pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
/* tests special handling of VER_SUITENAME */
@ -163,22 +166,17 @@ static void test_VerifyVersionInfo(void)
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
VER_MAJORVERSION, VER_GREATER_EQUAL));
if (servicepack == 0)
{
ok(!ret || broken(ret), /* win2k3 */
"VerifyVersionInfoA should have failed\n");
ok(GetLastError() == ERROR_OLD_WIN_VERSION,
"Expected ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
}
else
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMinor++;
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some wink2 */,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
if (servicepack == 0)
{
@ -186,83 +184,107 @@ static void test_VerifyVersionInfo(void)
}
else
{
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMajor--;
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMajor--;
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
}
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMajor++;
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMajor++;
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_LESS_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMajor--;
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
/* test the failure hierarchy for the four version fields */
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.wServicePackMajor++;
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.dwMinorVersion++;
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.dwMajorVersion++;
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.dwBuildNumber++;
SetLastError(0xdeadbeef);
ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(!ret && (GetLastError() == ERROR_OLD_WIN_VERSION),
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", GetLastError());
error = GetLastError();
ok(!ret, "VerifyVersionInfoA succeeded\n");
ok(error == ERROR_OLD_WIN_VERSION || broken(error == ERROR_BAD_ARGUMENTS) /* some win2k */,
"VerifyVersionInfoA should have failed with ERROR_OLD_WIN_VERSION instead of %d\n", error);
ret = pVerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
/* test bad dwOSVersionInfoSize */
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((OSVERSIONINFO *)&info);
info.dwOSVersionInfoSize = 0;
ret = pVerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
pVerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret || broken(!ret) /* some win2k */, "VerifyVersionInfoA failed with error %d\n", GetLastError());
}
START_TEST(version)

View file

@ -777,7 +777,6 @@ static void test_XcvDataPort_AddPort(void)
{
DWORD res;
/*
* The following tests crash with native localspl.dll on w2k and xp,
* but it works, when the native dll (w2k and xp) is used in wine.
@ -791,18 +790,17 @@ static void test_XcvDataPort_AddPort(void)
/* create a Port for a normal, writable file */
SetLastError(0xdeadbeef);
res = pXcvDataPort(hXcv, cmd_AddPortW, (PBYTE) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR), NULL, 0, NULL);
ok( res == ERROR_SUCCESS, "returned %d with %u (expected ERROR_SUCCESS)\n", res, GetLastError());
/* add our testport again */
SetLastError(0xdeadbeef);
res = pXcvDataPort(hXcv, cmd_AddPortW, (PBYTE) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR), NULL, 0, NULL);
ok( res == ERROR_ALREADY_EXISTS, "returned %d with %u (expected ERROR_ALREADY_EXISTS)\n", res, GetLastError());
/* create a well-known Port */
SetLastError(0xdeadbeef);
res = pXcvDataPort(hXcv, cmd_AddPortW, (PBYTE) portname_lpt1W, (lstrlenW(portname_lpt1W) + 1) * sizeof(WCHAR), NULL, 0, NULL);
SetLastError(0xdeadbeef);
res = pXcvDataPort(hXcv, cmd_AddPortW, (PBYTE) portname_lpt1W, (lstrlenW(portname_lpt1W) + 1) * sizeof(WCHAR), NULL, 0, NULL);
/* native localspl.dll on wine: ERROR_ALREADY_EXISTS */
ok( res == ERROR_ALREADY_EXISTS, "returned %d with %u (expected ERROR_ALREADY_EXISTS)\n", res, GetLastError());
/* ERROR_ALREADY_EXISTS is also returned from native localspl.dll on wine,
when "RPT1:" was already installed for redmonnt.dll:
@ -812,6 +810,7 @@ static void test_XcvDataPort_AddPort(void)
/* cleanup */
SetLastError(0xdeadbeef);
res = pXcvDataPort(hXcv, cmd_DeletePortW, (PBYTE) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR), NULL, 0, NULL);
ok( res == ERROR_SUCCESS, "returned %d with %u (expected ERROR_SUCCESS)\n", res, GetLastError());
}
}

View file

@ -423,7 +423,7 @@ static const char * get_metric(UINT uMetric)
return "UNKNOWN";
}
static DWORD check_count(UINT uMetric)
static void check_count(UINT uMetric)
{
DWORD dwMetric;
MMRESULT rc;
@ -452,14 +452,11 @@ static DWORD check_count(UINT uMetric)
if (rc == MMSYSERR_NOERROR && winetest_interactive)
trace("%s: %u\n", get_metric(uMetric), dwMetric);
return dwMetric;
}
static void msacm_tests(void)
{
MMRESULT rc;
DWORD dwCount;
DWORD dwACMVersion = acmGetVersion();
if (winetest_interactive) {
@ -470,17 +467,17 @@ static void msacm_tests(void)
LOWORD(dwACMVersion) == 0 ? " (Retail)" : "");
}
dwCount = check_count(ACM_METRIC_COUNT_CODECS);
dwCount = check_count(ACM_METRIC_COUNT_CONVERTERS);
dwCount = check_count(ACM_METRIC_COUNT_DISABLED);
dwCount = check_count(ACM_METRIC_COUNT_DRIVERS);
dwCount = check_count(ACM_METRIC_COUNT_FILTERS);
dwCount = check_count(ACM_METRIC_COUNT_HARDWARE);
dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CODECS);
dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS);
dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DISABLED);
dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS);
dwCount = check_count(ACM_METRIC_COUNT_LOCAL_FILTERS);
check_count(ACM_METRIC_COUNT_CODECS);
check_count(ACM_METRIC_COUNT_CONVERTERS);
check_count(ACM_METRIC_COUNT_DISABLED);
check_count(ACM_METRIC_COUNT_DRIVERS);
check_count(ACM_METRIC_COUNT_FILTERS);
check_count(ACM_METRIC_COUNT_HARDWARE);
check_count(ACM_METRIC_COUNT_LOCAL_CODECS);
check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS);
check_count(ACM_METRIC_COUNT_LOCAL_DISABLED);
check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS);
check_count(ACM_METRIC_COUNT_LOCAL_FILTERS);
if (winetest_interactive)
trace("enabled drivers:\n");

View file

@ -453,148 +453,7 @@ static void test_GetCountColorProfileElements(void)
}
}
typedef struct colorspace_description_struct {
DWORD dwID;
const char *szName;
BOOL registered;
char filename[MAX_PATH];
} colorspace_descr;
#define describe_colorspace(id) {id, #id, FALSE, ""}
colorspace_descr known_colorspaces[] = {
describe_colorspace(SPACE_XYZ),
describe_colorspace(SPACE_Lab),
describe_colorspace(SPACE_Luv),
describe_colorspace(SPACE_YCbCr),
describe_colorspace(SPACE_Yxy),
describe_colorspace(SPACE_RGB),
describe_colorspace(SPACE_GRAY),
describe_colorspace(SPACE_HSV),
describe_colorspace(SPACE_HLS),
describe_colorspace(SPACE_CMYK),
describe_colorspace(SPACE_CMY),
describe_colorspace(SPACE_2_CHANNEL),
describe_colorspace(SPACE_3_CHANNEL),
describe_colorspace(SPACE_4_CHANNEL),
describe_colorspace(SPACE_5_CHANNEL),
describe_colorspace(SPACE_6_CHANNEL),
describe_colorspace(SPACE_7_CHANNEL),
describe_colorspace(SPACE_8_CHANNEL)
};
static void enum_registered_color_profiles(void)
{
BOOL ret;
DWORD size, count, i, present;
CHAR profile[MAX_PATH];
size = sizeof(profile);
count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
present = 0;
trace("\n");
trace("Querying registered standard colorspace profiles via GetStandardColorSpaceProfileA():\n");
for (i=0; i<count; i++)
{
ret = pGetStandardColorSpaceProfileA(NULL, known_colorspaces[i].dwID, profile, &size);
if (ret)
{
lstrcpynA(known_colorspaces[i].filename, profile, MAX_PATH);
known_colorspaces[i].registered = TRUE;
present++;
trace(" found %s, pointing to '%s' (%d chars)\n", known_colorspaces[i].szName, profile, lstrlenA(profile));
}
}
trace("Total profiles found: %d.\n", present);
trace("\n");
}
static colorspace_descr *query_colorspace(DWORD dwID)
{
DWORD count, i;
count = sizeof(known_colorspaces)/sizeof(known_colorspaces[0]);
for (i=0; i<count; i++)
if (known_colorspaces[i].dwID == dwID)
{
if (!known_colorspaces[i].registered) break;
return &known_colorspaces[i];
}
return NULL;
}
static HKEY reg_open_mscms_key(void)
{
char win9x[] = "SOFTWARE\\Microsoft\\Windows";
char winNT[] = "SOFTWARE\\Microsoft\\Windows NT";
char ICM[] = "CurrentVersion\\ICM\\RegisteredProfiles";
HKEY win9x_key, winNT_key, ICM_key;
RegOpenKeyExA( HKEY_LOCAL_MACHINE, win9x, 0, KEY_READ, &win9x_key );
RegOpenKeyExA( HKEY_LOCAL_MACHINE, winNT, 0, KEY_READ, &winNT_key );
if (RegOpenKeyExA( winNT_key, ICM, 0, KEY_READ, &ICM_key ))
RegOpenKeyExA( win9x_key, ICM, 0, KEY_READ, &ICM_key );
RegCloseKey( win9x_key );
RegCloseKey( winNT_key );
return ICM_key;
}
static void check_registry(BOOL *has_space_rgb)
{
HKEY hkIcmKey;
LONG res;
DWORD i, dwValCount;
char szName[16383];
char szData[MAX_PATH+1];
DWORD dwNameLen, dwDataLen, dwType;
*has_space_rgb = FALSE;
hkIcmKey = reg_open_mscms_key();
if (!hkIcmKey)
{
trace("Key 'HKLM\\SOFTWARE\\Microsoft\\Windows*\\CurrentVersion\\ICM\\RegisteredProfiles' not found\n" );
return;
}
res = RegQueryInfoKeyA(hkIcmKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValCount, NULL, NULL, NULL, NULL);
if (res)
{
trace("RegQueryInfoKeyA() failed : %d\n", res);
return;
}
trace("Count of profile entries found directly in the registry: %d\n", dwValCount);
for (i = 0; i<dwValCount; i++)
{
dwNameLen = sizeof(szName);
dwDataLen = sizeof(szData);
res = RegEnumValueA( hkIcmKey, i, szName, &dwNameLen, NULL, &dwType, (LPBYTE)szData, &dwDataLen );
if (!strncmp(szName, "RGB", 3))
*has_space_rgb = TRUE;
if (res != ERROR_SUCCESS)
{
trace("RegEnumValueA() failed (%d), cannot enumerate profiles\n", res);
break;
}
ok( dwType == REG_SZ || dwType == REG_DWORD, "RegEnumValueA() returned unexpected value type (%d)\n", dwType );
if (dwType == REG_SZ)
trace(" found string value '%s' containing '%s' (%d chars)\n", szName, szData, lstrlenA(szData));
else if (dwType == REG_DWORD)
trace(" found DWORD value '%s' containing '%x'\n", szName, *(DWORD *)szData);
else
break;
}
RegCloseKey( hkIcmKey );
}
static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
static void test_GetStandardColorSpaceProfileA(void)
{
BOOL ret;
DWORD size;
@ -609,7 +468,7 @@ static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
/* Single invalid parameter checks: */
SetLastError(0xfaceabee); /* 1st param, */
ret = pGetStandardColorSpaceProfileA(machine, SPACE_RGB, newprofile, &sizeP);
ret = pGetStandardColorSpaceProfileA(machine, LCS_sRGB, newprofile, &sizeP);
ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 2nd param, */
@ -617,33 +476,24 @@ static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 4th param, */
ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, NULL);
ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, NULL);
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
if (query_colorspace(SPACE_RGB))
{
SetLastError(0xfaceabee); /* 3rd param, */
ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 3rd param, */
ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, NULL, &sizeP);
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* dereferenced 4th param, */
ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &zero);
ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
} else {
SetLastError(0xfaceabee); /* 3rd param, */
ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, NULL, &sizeP);
ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* dereferenced 4th param. */
ret = pGetStandardColorSpaceProfileA(NULL, SPACE_RGB, newprofile, &sizeP);
ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
}
SetLastError(0xfaceabee); /* dereferenced 4th param, */
ret = pGetStandardColorSpaceProfileA(NULL, LCS_sRGB, newprofile, &zero);
ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER),
"GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
/* Several invalid parameter checks: */
SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
ret = pGetStandardColorSpaceProfileA(machine, 0, newprofile, &zero);
ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
"GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, NULL);
@ -651,50 +501,46 @@ static void test_GetStandardColorSpaceProfileA(BOOL has_space_rgb)
SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
ret = pGetStandardColorSpaceProfileA(NULL, 0, NULL, &zero);
ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND),
"GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* maybe 2nd param. */
ret = pGetStandardColorSpaceProfileA(NULL, 0, newprofile, &sizeP);
if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
else ok( !lstrcmpiA( newprofile, emptyA ) && GetLastError() == 0xfaceabee,
"GetStandardColorSpaceProfileA() returns %d (GLE=%d)\n", ret, GetLastError() );
/* Functional checks */
if (has_space_rgb)
size = sizeof(oldprofile);
ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile, &size );
ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
SetLastError(0xdeadbeef);
ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, standardprofile );
if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
{
size = sizeof(oldprofile);
ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile, &size );
ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
SetLastError(0xdeadbeef);
ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, standardprofile );
if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
{
skip("Not enough rights for SetStandardColorSpaceProfileA\n");
return;
}
ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
size = sizeof(newprofile);
ret = pGetStandardColorSpaceProfileA( NULL, SPACE_RGB, newprofile, &size );
ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
ok( !lstrcmpiA( (LPSTR)&newprofile, standardprofile ), "Unexpected profile\n" );
ret = pSetStandardColorSpaceProfileA( NULL, SPACE_RGB, oldprofile );
ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
skip("Not enough rights for SetStandardColorSpaceProfileA\n");
return;
}
ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
size = sizeof(newprofile);
ret = pGetStandardColorSpaceProfileA( NULL, LCS_sRGB, newprofile, &size );
ok( ret, "GetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
ret = pSetStandardColorSpaceProfileA( NULL, LCS_sRGB, oldprofile );
ok( ret, "SetStandardColorSpaceProfileA() failed (%d)\n", GetLastError() );
}
static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
static void test_GetStandardColorSpaceProfileW(void)
{
BOOL ret;
DWORD size;
WCHAR oldprofile[MAX_PATH];
WCHAR newprofile[MAX_PATH];
const WCHAR emptyW[] = {0};
CHAR newprofileA[MAX_PATH];
const CHAR empty[] = "";
DWORD zero = 0;
DWORD sizeP = sizeof(newprofile);
@ -703,37 +549,38 @@ static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
/* Single invalid parameter checks: */
SetLastError(0xfaceabee); /* 1st param, */
ret = pGetStandardColorSpaceProfileW(machineW, SPACE_RGB, newprofile, &sizeP);
ret = pGetStandardColorSpaceProfileW(machineW, LCS_sRGB, newprofile, &sizeP);
ok( !ret && GetLastError() == ERROR_NOT_SUPPORTED, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 2nd param, */
ret = pGetStandardColorSpaceProfileW(NULL, (DWORD)-1, newprofile, &sizeP);
ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 2nd param, */
ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
ok( (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) ||
broken(ret), /* Win98 and WinME */
"GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 3rd param, */
ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, NULL, &sizeP);
if (has_space_rgb)
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
else
todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, NULL, &sizeP);
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* 4th param, */
ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, NULL);
ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, NULL);
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* dereferenced 4th param. */
ret = pGetStandardColorSpaceProfileW(NULL, SPACE_RGB, newprofile, &zero);
if (has_space_rgb)
ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
else
todo_wine ok( !ret && GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
ret = pGetStandardColorSpaceProfileW(NULL, LCS_sRGB, newprofile, &zero);
ok( !ret && (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER),
"GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
/* Several invalid parameter checks: */
SetLastError(0xfaceabee); /* 1st, maybe 2nd and then dereferenced 4th param, */
ret = pGetStandardColorSpaceProfileW(machineW, 0, newprofile, &zero);
ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
ok( !ret && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED),
"GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* maybe 2nd and then 4th param, */
ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, NULL);
@ -741,41 +588,40 @@ static void test_GetStandardColorSpaceProfileW(BOOL has_space_rgb)
SetLastError(0xfaceabee); /* maybe 2nd, then 3rd and dereferenced 4th param, */
ret = pGetStandardColorSpaceProfileW(NULL, 0, NULL, &zero);
ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND), "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
ok( !ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_FILE_NOT_FOUND),
"GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
SetLastError(0xfaceabee); /* maybe 2nd param. */
ret = pGetStandardColorSpaceProfileW(NULL, 0, newprofile, &sizeP);
if (!ret) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
else ok( !lstrcmpiW( newprofile, emptyW ) && GetLastError() == 0xfaceabee, "GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
else
{
WideCharToMultiByte(CP_ACP, 0, newprofile, -1, newprofileA, sizeof(newprofileA), NULL, NULL);
ok( !lstrcmpiA( newprofileA, empty ) && GetLastError() == 0xfaceabee,
"GetStandardColorSpaceProfileW() returns %d (GLE=%d)\n", ret, GetLastError() );
}
/* Functional checks */
if (has_space_rgb)
size = sizeof(oldprofile);
ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile, &size );
ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
SetLastError(0xdeadbeef);
ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, standardprofileW );
if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
{
size = sizeof(oldprofile);
ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile, &size );
ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
SetLastError(0xdeadbeef);
ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, standardprofileW );
if (!ret && (GetLastError() == ERROR_ACCESS_DENIED))
{
skip("Not enough rights for SetStandardColorSpaceProfileW\n");
return;
}
ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
size = sizeof(newprofile);
ret = pGetStandardColorSpaceProfileW( NULL, SPACE_RGB, newprofile, &size );
ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
ok( !lstrcmpiW( (LPWSTR)&newprofile, standardprofileW ), "Unexpected profile\n" );
ret = pSetStandardColorSpaceProfileW( NULL, SPACE_RGB, oldprofile );
ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
skip("Not enough rights for SetStandardColorSpaceProfileW\n");
return;
}
ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
size = sizeof(newprofile);
ret = pGetStandardColorSpaceProfileW( NULL, LCS_sRGB, newprofile, &size );
ok( ret, "GetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
ret = pSetStandardColorSpaceProfileW( NULL, LCS_sRGB, oldprofile );
ok( ret, "SetStandardColorSpaceProfileW() failed (%d)\n", GetLastError() );
}
static void test_EnumColorProfilesA(void)
@ -1458,7 +1304,6 @@ START_TEST(profile)
char path[MAX_PATH], file[MAX_PATH];
char profilefile1[MAX_PATH], profilefile2[MAX_PATH];
WCHAR profilefile1W[MAX_PATH], profilefile2W[MAX_PATH];
BOOL has_space_rgb;
WCHAR fileW[MAX_PATH];
UINT ret;
@ -1540,11 +1385,8 @@ START_TEST(profile)
test_GetCountColorProfileElements();
enum_registered_color_profiles();
check_registry(&has_space_rgb);
test_GetStandardColorSpaceProfileA(has_space_rgb);
test_GetStandardColorSpaceProfileW(has_space_rgb);
test_GetStandardColorSpaceProfileA();
test_GetStandardColorSpaceProfileW();
test_EnumColorProfilesA();
test_EnumColorProfilesW();

View file

@ -1808,12 +1808,14 @@ static void test_Session(IDispatch *pSession)
static WCHAR szEmpty[] = { 0 };
static WCHAR szEquals[] = { '=',0 };
static WCHAR szPropertyName[] = { 'P','r','o','p','e','r','t','y',',','N','a','m','e',0 };
static WCHAR szModeFlag[] = { 'M','o','d','e',',','F','l','a','g',0 };
WCHAR stringw[MAX_PATH];
CHAR string[MAX_PATH];
UINT len;
BOOL bool;
int myint;
IDispatch *pDatabase = NULL, *pInst = NULL, *record = NULL;
ULONG refs_before, refs_after;
HRESULT hr;
/* Session::Installer */
@ -1821,6 +1823,14 @@ static void test_Session(IDispatch *pSession)
ok(hr == S_OK, "Session_Installer failed, hresult 0x%08x\n", hr);
ok(pInst != NULL, "Session_Installer returned NULL IDispatch pointer\n");
ok(pInst == pInstaller, "Session_Installer does not match Installer instance from CoCreateInstance\n");
refs_before = IDispatch_AddRef(pInst);
hr = Session_Installer(pSession, &pInst);
ok(hr == S_OK, "Session_Installer failed, hresult 0x%08x\n", hr);
ok(pInst != NULL, "Session_Installer returned NULL IDispatch pointer\n");
ok(pInst == pInstaller, "Session_Installer does not match Installer instance from CoCreateInstance\n");
refs_after = IDispatch_Release(pInst);
ok(refs_before == refs_after, "got %u and %u\n", refs_before, refs_after);
/* Session::Property, get */
memset(stringw, 0, sizeof(stringw));
@ -1880,14 +1890,19 @@ static void test_Session(IDispatch *pSession)
hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, TRUE);
todo_wine ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
if (hr == DISP_E_EXCEPTION) ok_exception(hr, szModeFlag);
hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTNOW, &bool);
ok(hr == S_OK, "Session_ModeGet failed, hresult 0x%08x\n", hr);
ok(bool, "Reboot now mode is %d, expected 1\n", bool);
hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, FALSE); /* set it again so we don't reboot */
todo_wine ok(hr == S_OK, "Session_ModePut failed, hresult 0x%08x\n", hr);
if (hr == DISP_E_EXCEPTION) ok_exception(hr, szModeFlag);
hr = Session_ModePut(pSession, MSIRUNMODE_MAINTENANCE, TRUE);
ok(hr == DISP_E_EXCEPTION, "Session_ModePut failed, hresult 0x%08x\n", hr);
ok_exception(hr, szModeFlag);
/* Session::Database, get */
hr = Session_Database(pSession, &pDatabase);

View file

@ -479,6 +479,9 @@ static void test_msidecomposedesc(void)
r = pMsiDecomposeDescriptorA(NULL, NULL, NULL, NULL, &len);
ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
ok(len == 0, "length wrong\n");
r = pMsiDecomposeDescriptorA(desc, NULL, NULL, NULL, NULL);
ok(r == ERROR_SUCCESS, "returned wrong error\n");
}
static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
@ -1930,7 +1933,7 @@ static void test_where(void)
rec = 0;
query = "SELECT * FROM `Media` WHERE `DiskPrompt` <> 'Cabinet'";
r = do_query(hdb, query, &rec);
todo_wine ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
MsiCloseHandle( rec );
rec = 0;
@ -8842,6 +8845,112 @@ static void test_columnorder(void)
DeleteFileA(msifile);
}
static void test_createtable(void)
{
MSIHANDLE hdb, htab = 0, hrec = 0;
LPCSTR query;
UINT res;
DWORD size;
char buffer[0x20];
hdb = create_db();
ok(hdb, "failed to create db\n");
query = "CREATE TABLE `blah` (`foo` CHAR(72) NOT NULL PRIMARY KEY `foo`)";
res = MsiDatabaseOpenView( hdb, query, &htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
if(res == ERROR_SUCCESS )
{
res = MsiViewExecute( htab, hrec );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
size = sizeof(buffer);
res = MsiRecordGetString(hrec, 1, buffer, &size );
todo_wine ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiViewClose( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiCloseHandle( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
}
query = "CREATE TABLE `a` (`b` INT PRIMARY KEY `b`)";
res = MsiDatabaseOpenView( hdb, query, &htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
if(res == ERROR_SUCCESS )
{
res = MsiViewExecute( htab, 0 );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiViewClose( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiCloseHandle( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
query = "SELECT * FROM `a`";
res = MsiDatabaseOpenView( hdb, query, &htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
size = sizeof(buffer);
res = MsiRecordGetString(hrec, 1, buffer, &size );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
ok(!strcmp(buffer,"b"), "b != %s\n", buffer);
res = MsiViewClose( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiCloseHandle( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiDatabaseCommit(hdb);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiCloseHandle(hdb);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiOpenDatabase(msifile, MSIDBOPEN_TRANSACT, &hdb );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
query = "SELECT * FROM `a`";
res = MsiDatabaseOpenView( hdb, query, &htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiViewGetColumnInfo( htab, MSICOLINFO_NAMES, &hrec );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
size = sizeof(buffer);
res = MsiRecordGetString(hrec, 1, buffer, &size );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
todo_wine ok(!strcmp(buffer,"b"), "b != %s\n", buffer);
res = MsiCloseHandle( hrec );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiViewClose( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiCloseHandle( htab );
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
}
res = MsiDatabaseCommit(hdb);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = MsiCloseHandle(hdb);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
DeleteFileA(msifile);
}
START_TEST(db)
{
test_msidatabase();
@ -8893,4 +9002,5 @@ START_TEST(db)
test_insertorder();
test_columnorder();
test_suminfo_import();
test_createtable();
}

File diff suppressed because it is too large Load diff

View file

@ -247,10 +247,10 @@ static void test_null(void)
r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", NULL, 0);
ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", 0);
r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000001}", "foo", 0);
ok( r == ERROR_INVALID_PARAMETER, "wrong error %d\n", r);
r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000000}", "foo", INSTALLSTATE_DEFAULT);
r = MsiConfigureFeatureA("{00000000-0000-0000-0000-000000000002}", "foo", INSTALLSTATE_DEFAULT);
ok( r == ERROR_UNKNOWN_PRODUCT, "wrong error %d\n", r);
/* make sure empty string to MsiGetProductInfo is not a handle to default registry value, saving and restoring the
@ -467,7 +467,7 @@ static BOOL squash_guid(LPCWSTR in, LPWSTR out)
DWORD i,n=1;
GUID guid;
if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
return FALSE;
for(i=0; i<8; i++)
@ -1555,24 +1555,44 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(NULL, path, &size);
ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
/* NULL lpPathBuf */
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, NULL, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, NULL, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
/* NULL pcchBuf */
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, NULL);
ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, NULL);
ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
/* all params valid */
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
lstrcatA(keypath, comp_squashed);
@ -1586,16 +1606,29 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
lstrcatA(keypath, prod_squashed);
@ -1609,21 +1642,37 @@ static void test_MsiGetComponentPath(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* install properties key exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
create_file("C:\\imapath", "C:\\imapath", 11);
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
RegDeleteValueA(compkey, prod_squashed);
RegDeleteKeyA(compkey, "");
RegDeleteValueA(installprop, "WindowsInstaller");
@ -1647,16 +1696,29 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
lstrcatA(keypath, prod_squashed);
@ -1670,21 +1732,37 @@ static void test_MsiGetComponentPath(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* install properties key exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
create_file("C:\\imapath", "C:\\imapath", 11);
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
RegDeleteValueA(compkey, prod_squashed);
RegDeleteKeyA(compkey, "");
RegDeleteValueA(installprop, "WindowsInstaller");
@ -1708,6 +1786,11 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\");
lstrcatA(keypath, usersid);
@ -1723,16 +1806,29 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
lstrcatA(keypath, prod_squashed);
@ -1746,21 +1842,37 @@ static void test_MsiGetComponentPath(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* install properties key exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
create_file("C:\\imapath", "C:\\imapath", 11);
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
RegDeleteValueA(compkey, prod_squashed);
RegDeleteKeyA(prodkey, "");
RegDeleteKeyA(compkey, "");
@ -1783,6 +1895,11 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\");
lstrcatA(keypath, usersid);
@ -1798,25 +1915,46 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
create_file("C:\\imapath", "C:\\imapath", 11);
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
RegDeleteValueA(compkey, prod_squashed);
RegDeleteKeyA(prodkey, "");
RegDeleteKeyA(compkey, "");
@ -1836,6 +1974,11 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
lstrcatA(keypath, comp_squashed);
@ -1849,25 +1992,46 @@ static void test_MsiGetComponentPath(void)
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* product value exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
create_file("C:\\imapath", "C:\\imapath", 11);
/* file exists */
path[0] = 0;
size = MAX_PATH;
state = MsiGetComponentPathA(prodcode, component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
path[0] = 0;
size = MAX_PATH;
state = MsiLocateComponentA(component, path, &size);
ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
ok(!lstrcmpA(path, "C:\\imapath"), "Expected C:\\imapath, got %s\n", path);
ok(size == 10, "Expected 10, got %d\n", size);
RegDeleteValueA(compkey, prod_squashed);
RegDeleteKeyA(prodkey, "");
RegDeleteKeyA(compkey, "");
@ -8221,7 +8385,9 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
&context, targetsid, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patchcode, "apple"),
"Expected patchcode to be unchanged, got %s\n", patchcode);
ok(!lstrcmpA(targetprod, "banana"),
@ -8245,7 +8411,9 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
&context, targetsid, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_BAD_CONFIGURATION), /* Windows Installer 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patchcode, "apple"),
"Expected patchcode to be unchanged, got %s\n", patchcode);
ok(!lstrcmpA(targetprod, "banana"),
@ -9352,7 +9520,9 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
@ -9369,7 +9539,8 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_BAD_CONFIGURATION,
ok(r == ERROR_BAD_CONFIGURATION ||
broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
"Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
@ -9405,8 +9576,11 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple") ||
broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
"Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
@ -9467,7 +9641,8 @@ static void test_MsiEnumPatches(void)
ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
ok(!lstrcmpA(patch, patchcode),
"Expected \"%s\", got \"%s\"\n", patchcode, patch);
ok(!lstrcmpA(transforms, "whate"),
ok(!lstrcmpA(transforms, "whate") ||
broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
"Expected \"whate\", got \"%s\"\n", transforms);
ok(size == 8 || size == 16, "Expected 8 or 16, got %d\n", size);
@ -9541,7 +9716,9 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
@ -9558,7 +9735,8 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_BAD_CONFIGURATION,
ok(r == ERROR_BAD_CONFIGURATION ||
broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
"Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
@ -9594,8 +9772,11 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple") ||
broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
"Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
@ -9610,10 +9791,14 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple") ||
broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
ok(!lstrcmpA(transforms, "banana") ||
broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
"Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
@ -9686,7 +9871,9 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
@ -9703,7 +9890,8 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_BAD_CONFIGURATION,
ok(r == ERROR_BAD_CONFIGURATION ||
broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
"Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
@ -9739,8 +9927,11 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple") ||
broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
"Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
@ -9804,10 +9995,14 @@ static void test_MsiEnumPatches(void)
lstrcpyA(patch, "apple");
lstrcpyA(transforms, "banana");
r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple"),
ok(r == ERROR_NO_MORE_ITEMS ||
broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
"Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
ok(!lstrcmpA(patch, "apple") ||
broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
"Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
ok(!lstrcmpA(transforms, "banana"),
ok(!lstrcmpA(transforms, "banana") ||
broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
"Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
@ -9841,7 +10036,8 @@ static void test_MsiEnumPatches(void)
WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
ok(!lstrcmpA(patch, patchcode),
"Expected \"%s\", got \"%s\"\n", patchcode, patch);
ok(!lstrcmpA(transforms, "whate"),
ok(!lstrcmpA(transforms, "whate") ||
broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
"Expected \"whate\", got \"%s\"\n", transforms);
ok(size == 8, "Expected 8, got %d\n", size);

View file

@ -10,6 +10,7 @@
<file>install.c</file>
<file>msi.c</file>
<file>package.c</file>
<file>patch.c</file>
<file>record.c</file>
<file>source.c</file>
<file>suminfo.c</file>

View file

@ -153,7 +153,7 @@ static BOOL squash_guid(LPCWSTR in, LPWSTR out)
DWORD i,n=1;
GUID guid;
if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
return FALSE;
for(i=0; i<8; i++)
@ -2007,7 +2007,7 @@ static void test_property_table(void)
const char *query;
UINT r;
MSIHANDLE hpkg, hdb, hrec;
char buffer[MAX_PATH];
char buffer[MAX_PATH], package[10];
DWORD sz;
BOOL found;
@ -2050,15 +2050,14 @@ static void test_property_table(void)
r = run_query(hdb, query);
ok(r == ERROR_SUCCESS, "failed to add column\n");
hpkg = package_from_db(hdb);
todo_wine
{
ok(!hpkg, "package should not be created\n");
}
sprintf(package, "#%i", hdb);
r = MsiOpenPackage(package, &hpkg);
todo_wine ok(r != ERROR_SUCCESS, "MsiOpenPackage succeeded\n");
if (r == ERROR_SUCCESS)
MsiCloseHandle(hpkg);
MsiCloseHandle(hdb);
MsiCloseHandle(hpkg);
DeleteFile(msifile);
r = MsiCloseHandle(hdb);
ok(r == ERROR_SUCCESS, "MsiCloseHandle failed %u\n", r);
hdb = create_package_db();
ok (hdb, "failed to create package database\n");
@ -8743,6 +8742,9 @@ static void test_appsearch_drlocator(void)
r = add_appsearch_entry(hdb, "'SIGPROP11', 'NewSignature11'");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = add_appsearch_entry(hdb, "'SIGPROP13', 'NewSignature13'");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = create_drlocator_table(hdb);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@ -8801,6 +8803,18 @@ static void test_appsearch_drlocator(void)
r = add_drlocator_entry(hdb, path);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = create_reglocator_table(hdb);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
/* parent */
r = add_reglocator_entry(hdb, "'NewSignature12', 2, 'htmlfile\\shell\\open\\nonexistent', '', 1");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
/* parent is in RegLocator, no path, depth 0, no signature */
sprintf(path, "'NewSignature13', 'NewSignature12', '', 0");
r = add_drlocator_entry(hdb, path);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = create_signature_table(hdb);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@ -8907,6 +8921,12 @@ static void test_appsearch_drlocator(void)
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpiA(prop, path), "Expected \"%s\", got \"%s\"\n", path, prop);
size = MAX_PATH;
strcpy(path, "c:\\");
r = MsiGetPropertyA(hpkg, "SIGPROP13", prop, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!prop[0], "Expected \"\", got \"%s\"\n", prop);
DeleteFileA("FileName1");
DeleteFileA("FileName3.dll");
DeleteFileA("FileName4.dll");

File diff suppressed because it is too large Load diff

View file

@ -81,7 +81,7 @@ static BOOL squash_guid(LPCWSTR in, LPWSTR out)
DWORD i,n=1;
GUID guid;
if (FAILED(CLSIDFromString((LPOLESTR)in, &guid)))
if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
return FALSE;
for(i=0; i<8; i++)

View file

@ -12,10 +12,12 @@ extern void func_format(void);
extern void func_install(void);
extern void func_msi(void);
extern void func_package(void);
extern void func_patch(void);
extern void func_record(void);
extern void func_source(void);
extern void func_suminfo(void);
const struct test winetest_testlist[] =
{
{ "automation", func_automation },
@ -24,6 +26,7 @@ const struct test winetest_testlist[] =
{ "install", func_install },
{ "msi", func_msi },
{ "package", func_package },
{ "patch", func_patch },
{ "record", func_record },
{ "source", func_source },
{ "suminfo", func_suminfo },

View file

@ -427,7 +427,7 @@ static void test_SetAccountInformation_GetAccountInformation(void)
/* WinXP returns HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): 0x80070002 but
* Win2K returns SCHED_E_CANNOT_OPEN_TASK: 0x8004130d
* Win9x doesn't support security services */
if (hres == SCHED_E_NO_SECURITY_SERVICES)
if (hres == SCHED_E_NO_SECURITY_SERVICES || hres == SCHED_E_SERVICE_NOT_RUNNING)
{
win_skip("Security services are not supported\n");
cleanup_task();
@ -445,7 +445,8 @@ static void test_SetAccountInformation_GetAccountInformation(void)
hres = ITask_GetAccountInformation(test_task, &account_name);
ok(hres == S_OK ||
broken(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
hres == SCHED_E_CANNOT_OPEN_TASK),
hres == SCHED_E_CANNOT_OPEN_TASK ||
hres == 0x200), /* win2k */
"GetAccountInformation failed: %08x\n", hres);
if (hres == S_OK)
{
@ -464,7 +465,8 @@ static void test_SetAccountInformation_GetAccountInformation(void)
hres = ITask_GetAccountInformation(test_task, &account_name);
ok(hres == S_OK ||
broken(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
hres == SCHED_E_CANNOT_OPEN_TASK),
hres == SCHED_E_CANNOT_OPEN_TASK ||
hres == 0x200), /* win2k */
"GetAccountInformation failed: %08x\n", hres);
if (hres == S_OK)
{
@ -480,7 +482,8 @@ static void test_SetAccountInformation_GetAccountInformation(void)
hres = ITask_GetAccountInformation(test_task, &account_name);
ok(hres == S_OK ||
broken(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
hres == SCHED_E_CANNOT_OPEN_TASK),
hres == SCHED_E_CANNOT_OPEN_TASK ||
hres == 0x200), /* win2k */
"GetAccountInformation failed: %08x\n", hres);
if (hres == S_OK)
{

View file

@ -60,6 +60,7 @@ static void test_new(void)
mem = pMSVCRTD_operator_new_dbg(42, _NORMAL_BLOCK, __FILE__, __LINE__);
ok(mem != NULL, "memory not allocated\n");
HeapFree(GetProcessHeap(), 0, mem);
}
/**********************************************************************/

View file

@ -90,6 +90,16 @@ static const WCHAR szComplete5[] = {
'<','/','S',':','s','e','a','r','c','h','>',0
};
static const WCHAR szComplete6[] = {
'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\'','1','.','0','\'',' ',
'e','n','c','o','d','i','n','g','=','\'','W','i','n','d','o','w','s','-','1','2','5','2','\'','?','>','\n',
'<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
};
static const CHAR szNonUnicodeXML[] =
"<?xml version='1.0' encoding='Windows-1252'?>\n"
"<open></open>\n";
static const CHAR szExampleXML[] =
"<?xml version='1.0' encoding='utf-8'?>\n"
"<root xmlns:foo='urn:uuid:86B2F87F-ACB6-45cd-8B77-9BDB92A01A29'>\n"
@ -460,20 +470,8 @@ static void node_to_string(IXMLDOMNode *node, char *buf)
}
else
{
int pos = get_node_position(node);
DOMNodeType parent_type = NODE_INVALID;
r = IXMLDOMNode_get_parentNode(node, &new_node);
/* currently wine doesn't create a node for the <?xml ... ?>. To be able to test query
* results we "fix" it */
if (r == S_OK)
ole_check(IXMLDOMNode_get_nodeType(new_node, &parent_type));
if ((parent_type == NODE_DOCUMENT) && type != NODE_PROCESSING_INSTRUCTION && pos==1)
{
todo_wine ok(FALSE, "The first child of the document node in MSXML is the <?xml ... ?> processing instruction\n");
pos++;
}
wsprintf(buf, "%d", pos);
wsprintf(buf, "%d", get_node_position(node));
buf += strlen(buf);
}
@ -537,8 +535,9 @@ static void test_domdoc( void )
LONG nLength = 0;
WCHAR buff[100];
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -552,11 +551,11 @@ if (0)
/* try some stupid things */
r = IXMLDOMDocument_loadXML( doc, NULL, NULL );
ok( r == S_FALSE, "loadXML failed\n");
ok( r == S_FALSE, "loadXML succeeded\n");
b = VARIANT_TRUE;
r = IXMLDOMDocument_loadXML( doc, NULL, &b );
ok( r == S_FALSE, "loadXML failed\n");
ok( r == S_FALSE, "loadXML succeeded\n");
ok( b == VARIANT_FALSE, "failed to load XML string\n");
/* try to load a document from a nonexistent file */
@ -567,16 +566,16 @@ if (0)
V_BSTR(&var) = str;
r = IXMLDOMDocument_load( doc, var, &b);
ok( r == S_FALSE, "load (from file) failed\n");
ok( b == VARIANT_FALSE, "failed to load XML file\n");
ok( r == S_FALSE, "loadXML succeeded\n");
ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
SysFreeString( str );
/* try load an empty document */
b = VARIANT_TRUE;
str = SysAllocString( szEmpty );
r = IXMLDOMDocument_loadXML( doc, str, &b );
ok( r == S_FALSE, "loadXML failed\n");
ok( b == VARIANT_FALSE, "failed to load XML string\n");
ok( r == S_FALSE, "loadXML succeeded\n");
ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
SysFreeString( str );
r = IXMLDOMDocument_get_async( doc, &b );
@ -598,8 +597,8 @@ if (0)
b = VARIANT_TRUE;
str = SysAllocString( szIncomplete );
r = IXMLDOMDocument_loadXML( doc, str, &b );
ok( r == S_FALSE, "loadXML failed\n");
ok( b == VARIANT_FALSE, "failed to load XML string\n");
ok( r == S_FALSE, "loadXML succeeded\n");
ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
SysFreeString( str );
/* check that there's no document element */
@ -617,6 +616,22 @@ if (0)
ok( r == S_OK, "loadXML failed\n");
ok( b == VARIANT_TRUE, "failed to load XML string\n");
/* loadXML ignores the encoding attribute and always expects Unicode */
b = VARIANT_FALSE;
str = SysAllocString( szComplete6 );
r = IXMLDOMDocument_loadXML( doc, str, &b );
ok( r == S_OK, "loadXML failed\n");
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
/* try a BSTR containing a Windows-1252 document */
b = VARIANT_TRUE;
str = SysAllocStringByteLen( szNonUnicodeXML, sizeof(szNonUnicodeXML) - 1 );
r = IXMLDOMDocument_loadXML( doc, str, &b );
ok( r == S_FALSE, "loadXML succeeded\n");
ok( b == VARIANT_FALSE, "succeeded in loading XML string\n");
SysFreeString( str );
/* try to load something valid */
b = VARIANT_FALSE;
str = SysAllocString( szComplete1 );
@ -629,6 +644,11 @@ if (0)
r = IXMLDOMDocument_get_nodeName( doc, NULL );
ok ( r == E_INVALIDARG, "get_nodeName (NULL) wrong code\n");
str = (BSTR)0xdeadbeef;
r = IXMLDOMDocument_get_baseName( doc, &str );
ok ( r == S_FALSE, "got 0x%08x\n", r);
ok (str == NULL, "got %p\n", str);
/* content doesn't matter here */
str = NULL;
r = IXMLDOMDocument_get_nodeName( doc, &str );
@ -1222,6 +1242,27 @@ if (0)
free_bstrs();
}
static void test_persiststreaminit(void)
{
IXMLDOMDocument *doc;
IPersistStreamInit *streaminit;
HRESULT hr;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
ok( hr == S_OK, "failed with 0x%08x\n", hr );
if( hr != S_OK )
return;
hr = IXMLDOMDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&streaminit);
ok( hr == S_OK, "failed with 0x%08x\n", hr );
hr = IPersistStreamInit_InitNew(streaminit);
ok( hr == S_OK, "failed with 0x%08x\n", hr );
IXMLDOMDocument_Release(doc);
}
static void test_domnode( void )
{
HRESULT r;
@ -1237,14 +1278,11 @@ static void test_domnode( void )
VARIANT var;
LONG count;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
if (!doc) {
ok( FALSE, "no document\n");
return;
}
b = FALSE;
str = SysAllocString( szComplete4 );
@ -1680,15 +1718,17 @@ static void test_refs(void)
LONG ref;
IUnknown *unk, *unk2;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
ref = IXMLDOMDocument_Release(doc);
ok( ref == 0, "ref %d\n", ref);
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -1784,8 +1824,9 @@ static void test_create(void)
LONG ref;
LONG num;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -1988,6 +2029,17 @@ static void test_create(void)
if( SUCCEEDED(r) ) IXMLDOMNode_Release( node );
SysFreeString(str);
/* a name is required for attribute, try a BSTR with first null wchar */
V_VT(&var) = VT_I1;
V_I1(&var) = NODE_ATTRIBUTE;
str = SysAllocString( szstr1 );
str[0] = 0;
node = (IXMLDOMNode*)0x1;
r = IXMLDOMDocument_createNode( doc, var, str, NULL, &node );
ok( r == E_FAIL, "returns %08x\n", r );
ok( node == (void*)0x1, "expected same ptr, got %p\n", node);
SysFreeString(str);
/* NODE_PROCESSING_INSTRUCTION */
V_VT(&var) = VT_I1;
V_I1(&var) = NODE_PROCESSING_INSTRUCTION;
@ -2224,8 +2276,9 @@ static void test_getElementsByTagName(void)
IXMLDOMNodeList *node_list;
LONG len;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2289,8 +2342,9 @@ static void test_get_text(void)
IXMLDOMNamedNodeMap *node_map;
LONG len;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2390,8 +2444,9 @@ static void test_get_childNodes(void)
IXMLDOMNodeList *node_list, *node_list2;
LONG len;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2431,6 +2486,40 @@ static void test_get_childNodes(void)
IXMLDOMDocument_Release( doc );
}
static void test_get_firstChild(void)
{
static WCHAR xmlW[] = {'x','m','l',0};
IXMLDOMDocument *doc;
IXMLDOMNode *node;
VARIANT_BOOL b;
HRESULT r;
BSTR str;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&doc );
ok( r == S_OK, "failed with 0x%08x\n", r );
if( r != S_OK )
return;
str = SysAllocString( szComplete4 );
r = IXMLDOMDocument_loadXML( doc, str, &b );
ok( r == S_OK, "loadXML failed\n");
ok( b == VARIANT_TRUE, "failed to load XML string\n");
SysFreeString( str );
r = IXMLDOMDocument_get_firstChild( doc, &node );
ok( r == S_OK, "ret %08x\n", r);
r = IXMLDOMNode_get_nodeName( node, &str );
ok( r == S_OK, "ret %08x\n", r);
ok(memcmp(str, xmlW, sizeof(xmlW)) == 0, "expected \"xml\" node name\n");
SysFreeString(str);
IXMLDOMNode_Release( node );
IXMLDOMDocument_Release( doc );
}
static void test_removeChild(void)
{
HRESULT r;
@ -2441,8 +2530,9 @@ static void test_removeChild(void)
IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node, *lc_node;
IXMLDOMNodeList *root_list, *fo_list;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2532,6 +2622,7 @@ static void test_replaceChild(void)
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2642,6 +2733,7 @@ static void test_removeNamedItem(void)
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2729,9 +2821,11 @@ static void test_XMLHTTP(void)
HRESULT hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLHttpRequest,
(void **)&pXMLHttpRequest);
ok(hr == S_OK, "CoCreateInstance(CLSID_XMLHTTPRequest) should have succeeded instead of failing with 0x%08x\n", hr);
if (hr != S_OK)
if (FAILED(hr))
{
win_skip("IXMLHTTPRequest is not available (0x%08x)\n", hr);
return;
}
VariantInit(&dummy);
V_VT(&dummy) = VT_ERROR;
@ -2785,6 +2879,7 @@ static void test_IXMLDOMDocument2(void)
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2856,6 +2951,7 @@ static void test_XPath(void)
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -2916,6 +3012,8 @@ static void test_XPath(void)
expect_list_and_release(list, "");
ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("//elem[4]"), &list));
expect_list_and_release(list, "");
ole_check(IXMLDOMDocument_selectNodes(doc, _bstr_("root//elem[0]"), &list));
expect_list_and_release(list, "");
/* foo undeclared in document node */
ole_expect(IXMLDOMDocument_selectNodes(doc, _bstr_("root//foo:c"), &list), E_FAIL);
@ -2980,6 +3078,7 @@ static void test_cloneNode(void )
static const WCHAR szSearch[] = { 'l', 'c', '/', 'p', 'r', 0 };
r = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
@ -3141,6 +3240,7 @@ static void test_xmlTypes(void)
LONG len = 0;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -4209,6 +4309,7 @@ static void test_nodeTypeTests( void )
HRESULT hr;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -4554,10 +4655,12 @@ static void test_DocumentSaveToDocument(void)
HRESULT hr;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc2 );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
{
IXMLDOMDocument_Release(doc);
@ -4609,6 +4712,7 @@ static void test_DocumentSaveToFile(void)
HRESULT hr;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -4656,10 +4760,12 @@ static void test_testTransforms(void)
HRESULT hr;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&docSS );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
{
IXMLDOMDocument_Release(doc);
@ -4707,6 +4813,7 @@ static void test_Namespaces(void)
"</root>";
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -4762,6 +4869,7 @@ static void test_FormattingXML(void)
static const CHAR szLinefeedRootXML[] = "<Root>\r\n\t<Sub val=\"A\"/>\r\n</Root>";
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -4798,6 +4906,7 @@ static void test_NodeTypeValue(void)
VARIANT v;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -5187,10 +5296,12 @@ static void test_TransformWithLoadingLocalFile(void)
}
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&xsl );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
{
IXMLDOMDocument2_Release(doc);
@ -5256,6 +5367,7 @@ static void test_put_nodeValue(void)
VARIANT data, type;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -5357,6 +5469,7 @@ static void test_document_IObjectSafety(void)
HRESULT hr;
hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
ok( hr == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", hr );
if( hr != S_OK )
return;
@ -5456,38 +5569,86 @@ static void test_document_IObjectSafety(void)
IXMLDOMDocument_Release(doc);
}
static void test_XSLPattern(void)
{
IXMLDOMDocument2 *doc;
IXMLDOMNodeList *list;
VARIANT_BOOL b;
HRESULT r;
LONG len;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void**)&doc );
ok( r == S_OK, "CoCreateInstance(CLSID_DOMDocument) should have succeeded instead of failing with 0x%08x\n", r );
if( r != S_OK )
return;
ole_check(IXMLDOMDocument2_loadXML(doc, _bstr_(szExampleXML), &b));
ok(b == VARIANT_TRUE, "failed to load XML string\n");
/* switch to XPath */
ole_check(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), _variantbstr_("XSLPattern")));
/* for XSLPattern start index is 0, for XPath it's 1 */
ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root//elem[0]"), &list));
len = 0;
ole_check(IXMLDOMNodeList_get_length(list, &len));
todo_wine ok(len != 0, "expected filled list\n");
if (len)
todo_wine expect_list_and_release(list, "E1.E2.D1");
IXMLDOMDocument2_Release(doc);
free_bstrs();
}
START_TEST(domdoc)
{
IXMLDOMDocument *doc;
HRESULT r;
r = CoInitialize( NULL );
ok( r == S_OK, "failed to init com\n");
if (r != S_OK)
return;
r = CoCreateInstance( &CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (LPVOID*)&doc );
if (SUCCEEDED(r))
{
IXMLDOMDocument_Release(doc);
test_domdoc();
test_persiststreaminit();
test_domnode();
test_refs();
test_create();
test_getElementsByTagName();
test_get_text();
test_get_childNodes();
test_get_firstChild();
test_removeChild();
test_replaceChild();
test_removeNamedItem();
test_IXMLDOMDocument2();
test_XPath();
test_XSLPattern();
test_cloneNode();
test_xmlTypes();
test_nodeTypeTests();
test_DocumentSaveToDocument();
test_DocumentSaveToFile();
test_testTransforms();
test_Namespaces();
test_FormattingXML();
test_NodeTypeValue();
test_TransformWithLoadingLocalFile();
test_put_nodeValue();
test_document_IObjectSafety();
}
else
win_skip("IXMLDOMDocument is not available (0x%08x)\n", r);
test_domdoc();
test_domnode();
test_refs();
test_create();
test_getElementsByTagName();
test_get_text();
test_get_childNodes();
test_removeChild();
test_replaceChild();
test_removeNamedItem();
test_XMLHTTP();
test_IXMLDOMDocument2();
test_XPath();
test_cloneNode();
test_xmlTypes();
test_nodeTypeTests();
test_DocumentSaveToDocument();
test_DocumentSaveToFile();
test_testTransforms();
test_Namespaces();
test_FormattingXML();
test_NodeTypeValue();
test_TransformWithLoadingLocalFile();
test_put_nodeValue();
test_document_IObjectSafety();
CoUninitialize();
}

View file

@ -357,6 +357,16 @@ static void test_xmlelem_collection(void)
ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
/* try advance further, no children left */
hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
ok(V_VT(&var) == 0, "Expected 0, got %d\n", V_VT(&var));
ok(num_vars == 0, "Expected 0, got %d\n", num_vars);
hr = IEnumVARIANT_Next(enumVar, 1, &var, NULL);
ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
ok(V_VT(&var) == 0, "Expected 0, got %d\n", V_VT(&var));
hr = IUnknown_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(child != NULL, "Expected non-NULL child\n");

View file

@ -479,6 +479,10 @@ START_TEST(atom)
InitFunctionPtr();
if (pRtlCreateAtomTable)
{
/* Global atom table seems to be available to GUI apps only in
Win7, so let's turn this app into a GUI app */
GetDesktopWindow();
test_NtAtom();
test_NtIntAtom();
test_NtRefPinAtom();

View file

@ -33,15 +33,16 @@
#include "winternl.h"
/* FIXME!!! this test checks only mappings, defined by MSDN
* It is necessary to add other mappings and to test them up to Windows XP.
* It is necessary to add other mappings and to test them
* up to the latest Windows platform.
*
* Some Windows platforms don't know about all the mappings, and in such
* cases they return somewhat strange results (Win98) or a generic error
* like ERROR_MR_MID_NOT_FOUND (NT4). Our tests have to know about these to
* not fail, but we would very much prefer Wine not to return such garbage.
* To you can pass the 'strict' option to this test to force it to only check
* So you can pass the 'strict' option to this test to force it to only check
* results against the first listed value. This test should pass in strict
* mode on the latest Windows platform (currently XP) and in Wine.
* mode on the latest Windows platform and in Wine.
* (of course older Windows platforms will fail to pass the strict mode)
*/
@ -167,6 +168,7 @@ static void run_error_tests(void)
cmp(STATUS_INTEGER_OVERFLOW, ERROR_ARITHMETIC_OVERFLOW);
cmp(STATUS_BUFFER_OVERFLOW, ERROR_MORE_DATA);
cmp(STATUS_NO_MORE_FILES, ERROR_NO_MORE_FILES);
cmp2(STATUS_HANDLES_CLOSED, ERROR_HANDLES_CLOSED);
cmp(STATUS_NO_INHERITANCE, ERROR_NO_INHERITANCE);
cmp(STATUS_NO_MORE_EAS, ERROR_NO_MORE_ITEMS);
cmp(STATUS_NO_MORE_ENTRIES, ERROR_NO_MORE_ITEMS);
@ -189,7 +191,7 @@ static void run_error_tests(void)
cmp(STATUS_HANDLE_NOT_CLOSABLE, ERROR_INVALID_HANDLE);
cmp(STATUS_NOT_COMMITTED, ERROR_INVALID_ADDRESS);
cmp(STATUS_PARTIAL_COPY, ERROR_PARTIAL_COPY);
cmp3(STATUS_LPC_REPLY_LOST, ERROR_INTERNAL_ERROR, ERROR_CONNECTION_ABORTED);
cmp3(STATUS_LPC_REPLY_LOST, ERROR_CONNECTION_ABORTED, ERROR_INTERNAL_ERROR);
cmp(STATUS_INVALID_PARAMETER, ERROR_INVALID_PARAMETER);
cmp(STATUS_INVALID_PARAMETER_1, ERROR_INVALID_PARAMETER);
cmp(STATUS_INVALID_PARAMETER_2, ERROR_INVALID_PARAMETER);
@ -738,8 +740,8 @@ static void run_error_tests(void)
cmp(STATUS_LOGIN_WKSTA_RESTRICTION, ERROR_LOGIN_WKSTA_RESTRICTION);
cmp(STATUS_LICENSE_QUOTA_EXCEEDED, ERROR_LICENSE_QUOTA_EXCEEDED);
cmp(STATUS_RESOURCE_NOT_OWNED, ERROR_NOT_OWNER);
cmp3(STATUS_DUPLICATE_OBJECTID, STATUS_DUPLICATE_OBJECTID, ERROR_OBJECT_ALREADY_EXISTS);
cmp3(STATUS_OBJECTID_EXISTS, STATUS_OBJECTID_EXISTS, ERROR_OBJECT_ALREADY_EXISTS);
cmp3(STATUS_DUPLICATE_OBJECTID, ERROR_OBJECT_ALREADY_EXISTS, STATUS_DUPLICATE_OBJECTID);
cmp3(STATUS_OBJECTID_EXISTS, ERROR_OBJECT_ALREADY_EXISTS, STATUS_OBJECTID_EXISTS);
cmp2(STATUS_OBJECTID_NOT_FOUND, ERROR_FILE_NOT_FOUND);
cmp2(STATUS_MFT_TOO_FRAGMENTED, ERROR_DISK_TOO_FRAGMENTED);
cmp(SEC_E_INSUFFICIENT_MEMORY, ERROR_NO_SYSTEM_RESOURCES);

View file

@ -49,6 +49,7 @@ static NTSTATUS (WINAPI *pNtReadVirtualMemory)(HANDLE, const void*, void*, SIZE
static NTSTATUS (WINAPI *pNtTerminateProcess)(HANDLE handle, LONG exit_code);
static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
static NTSTATUS (WINAPI *pNtSetInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#ifdef __i386__
@ -63,6 +64,8 @@ static int my_argc;
static char** my_argv;
static int test_stage;
static BOOL is_wow64;
/* Test various instruction combinations that cause a protection fault on the i386,
* and check what the resulting exception looks like.
*/
@ -72,121 +75,134 @@ static const struct exception
BYTE code[18]; /* asm code */
BYTE offset; /* offset of faulting instruction */
BYTE length; /* length of faulting instruction */
BOOL wow64_broken; /* broken on Wow64, should be skipped */
NTSTATUS status; /* expected status code */
DWORD nb_params; /* expected number of parameters */
DWORD params[4]; /* expected parameters */
} exceptions[] =
{
/* 0 */
/* test some privileged instructions */
{ { 0xfb, 0xc3 }, /* 0: sti; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6c, 0xc3 }, /* 1: insb (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6d, 0xc3 }, /* 2: insl (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6e, 0xc3 }, /* 3: outsb (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x6f, 0xc3 }, /* 4: outsl (%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* 5 */
{ { 0xe4, 0x11, 0xc3 }, /* 5: inb $0x11,%al; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 2, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe5, 0x11, 0xc3 }, /* 6: inl $0x11,%eax; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 2, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe6, 0x11, 0xc3 }, /* 7: outb %al,$0x11; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 2, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xe7, 0x11, 0xc3 }, /* 8: outl %eax,$0x11; ret */
0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 2, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xed, 0xc3 }, /* 9: inl (%dx),%eax; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* 10 */
{ { 0xee, 0xc3 }, /* 10: outb %al,(%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xef, 0xc3 }, /* 11: outl %eax,(%dx); ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xf4, 0xc3 }, /* 12: hlt; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0xfa, 0xc3 }, /* 13: cli; ret */
0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 1, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test long jump to invalid selector */
{ { 0xea, 0, 0, 0, 0, 0, 0, 0xc3 }, /* 14: ljmp $0,$0; ret */
0, 7, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
0, 7, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* 15 */
/* test iret to invalid selector */
{ { 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0xcf, 0x83, 0xc4, 0x0c, 0xc3 },
/* 15: pushl $0; pushl $0; pushl $0; iret; addl $12,%esp; ret */
6, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
6, 1, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test loading an invalid selector */
{ { 0xb8, 0xef, 0xbe, 0x00, 0x00, 0x8e, 0xe8, 0xc3 }, /* 16: mov $beef,%ax; mov %ax,%gs; ret */
5, 2, STATUS_ACCESS_VIOLATION, 2, { 0, 0xbee8 } }, /* 0xbee8 or 0xffffffff */
5, 2, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xbee8 } }, /* 0xbee8 or 0xffffffff */
/* test accessing a zero selector */
/* test accessing a zero selector (%es broken on Wow64) */
{ { 0x06, 0x31, 0xc0, 0x8e, 0xc0, 0x26, 0xa1, 0, 0, 0, 0, 0x07, 0xc3 },
/* 17: push %es; xor %eax,%eax; mov %ax,%es; mov %es:(0),%ax; pop %es; ret */
5, 6, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* push %es; xor %eax,%eax; mov %ax,%es; mov %es:(0),%ax; pop %es; ret */
5, 6, TRUE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
{ { 0x0f, 0xa8, 0x31, 0xc0, 0x8e, 0xe8, 0x65, 0xa1, 0, 0, 0, 0, 0x0f, 0xa9, 0xc3 },
/* push %gs; xor %eax,%eax; mov %ax,%gs; mov %gs:(0),%ax; pop %gs; ret */
6, 6, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test moving %cs -> %ss */
{ { 0x0e, 0x17, 0x58, 0xc3 }, /* 18: pushl %cs; popl %ss; popl %eax; ret */
1, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
1, 1, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* 19: test overlong instruction (limit is 15 bytes, 5 on Win7) */
/* 20 */
/* test overlong instruction (limit is 15 bytes, 5 on Win7) */
{ { 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0xfa,0xc3 },
0, 16, STATUS_ILLEGAL_INSTRUCTION, 0 },
0, 16, TRUE, STATUS_ILLEGAL_INSTRUCTION, 0 },
{ { 0x64,0x64,0x64,0x64,0xfa,0xc3 },
0, 5, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 5, TRUE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test invalid interrupt */
{ { 0xcd, 0xff, 0xc3 }, /* 21: int $0xff; ret */
0, 2, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
0, 2, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test moves to/from Crx */
{ { 0x0f, 0x20, 0xc0, 0xc3 }, /* 22: movl %cr0,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x20, 0xe0, 0xc3 }, /* 23: movl %cr4,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* 25 */
{ { 0x0f, 0x22, 0xc0, 0xc3 }, /* 24: movl %eax,%cr0; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x22, 0xe0, 0xc3 }, /* 25: movl %eax,%cr4; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test moves to/from Drx */
{ { 0x0f, 0x21, 0xc0, 0xc3 }, /* 26: movl %dr0,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x21, 0xc8, 0xc3 }, /* 27: movl %dr1,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x21, 0xf8, 0xc3 }, /* 28: movl %dr7,%eax; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* 30 */
{ { 0x0f, 0x23, 0xc0, 0xc3 }, /* 29: movl %eax,%dr0; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x23, 0xc8, 0xc3 }, /* 30: movl %eax,%dr1; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
{ { 0x0f, 0x23, 0xf8, 0xc3 }, /* 31: movl %eax,%dr7; ret */
0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 },
0, 3, FALSE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
/* test memory reads */
{ { 0xa1, 0xfc, 0xff, 0xff, 0xff, 0xc3 }, /* 32: movl 0xfffffffc,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffc } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffc } },
{ { 0xa1, 0xfd, 0xff, 0xff, 0xff, 0xc3 }, /* 33: movl 0xfffffffd,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffd } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffd } },
/* 35 */
{ { 0xa1, 0xfe, 0xff, 0xff, 0xff, 0xc3 }, /* 34: movl 0xfffffffe,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffe } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffe } },
{ { 0xa1, 0xff, 0xff, 0xff, 0xff, 0xc3 }, /* 35: movl 0xffffffff,%eax; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } },
/* test memory writes */
{ { 0xa3, 0xfc, 0xff, 0xff, 0xff, 0xc3 }, /* 36: movl %eax,0xfffffffc; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffc } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffc } },
{ { 0xa3, 0xfd, 0xff, 0xff, 0xff, 0xc3 }, /* 37: movl %eax,0xfffffffd; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffd } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffd } },
{ { 0xa3, 0xfe, 0xff, 0xff, 0xff, 0xc3 }, /* 38: movl %eax,0xfffffffe; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffe } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffe } },
/* 40 */
{ { 0xa3, 0xff, 0xff, 0xff, 0xff, 0xc3 }, /* 39: movl %eax,0xffffffff; ret */
0, 5, STATUS_ACCESS_VIOLATION, 2, { 1, 0xffffffff } },
0, 5, FALSE, STATUS_ACCESS_VIOLATION, 2, { 1, 0xffffffff } },
/* 40: test exception with cleared %ds and %es */
/* test exception with cleared %ds and %es (broken on Wow64) */
{ { 0x1e, 0x06, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0xfa, 0x07, 0x1f, 0xc3 },
/* push %ds; push %es; xorl %eax,%eax; mov %ax,%ds; mov %ax,%es; cli; pop %es; pop %ds; ret */
8, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 },
8, 1, TRUE, STATUS_PRIVILEGED_INSTRUCTION, 0 },
};
static int got_exception;
@ -230,7 +246,9 @@ static LONG CALLBACK rtlraiseexception_vectored_handler(EXCEPTION_POINTERS *Exce
rec->ExceptionAddress, (char *)code_mem + 0xb);
if (pNtCurrentTeb()->Peb->BeingDebugged)
ok((void *)context->Eax == pRtlRaiseException, "debugger managed to modify Eax to %x should be %p\n",
ok((void *)context->Eax == pRtlRaiseException ||
broken( is_wow64 && context->Eax == 0xf00f00f1 ), /* broken on vista */
"debugger managed to modify Eax to %x should be %p\n",
context->Eax, pRtlRaiseException);
/* check that context.Eip is fixed up only for EXCEPTION_BREAKPOINT
@ -365,8 +383,8 @@ static DWORD handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *fram
unsigned int i, entry = except - exceptions;
got_exception++;
trace( "exception: %x flags:%x addr:%p\n",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
trace( "exception %u: %x flags:%x addr:%p\n",
entry, rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
ok( rec->ExceptionCode == except->status,
"%u: Wrong exception code %x/%x\n", entry, rec->ExceptionCode, except->status );
@ -412,6 +430,11 @@ static void test_prot_fault(void)
for (i = 0; i < sizeof(exceptions)/sizeof(exceptions[0]); i++)
{
if (is_wow64 && exceptions[i].wow64_broken && !strcmp( winetest_platform, "windows" ))
{
skip( "Exception %u broken on Wow64\n", i );
continue;
}
got_exception = 0;
run_exception_test(handler, &exceptions[i], &exceptions[i].code,
sizeof(exceptions[i].code), 0);
@ -752,7 +775,9 @@ static void test_debugger(void)
/* ctx.Eip is the same value the exception handler got */
if (de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
{
ok((char *)ctx.Eip == (char *)code_mem_address + 0xa, "Eip at 0x%x instead of %p\n",
ok((char *)ctx.Eip == (char *)code_mem_address + 0xa ||
broken(is_wow64 && (char *)ctx.Eip == (char *)code_mem_address + 0xb),
"Eip at 0x%x instead of %p\n",
ctx.Eip, (char *)code_mem_address + 0xa);
/* need to fixup Eip for debuggee */
if ((char *)ctx.Eip == (char *)code_mem_address + 0xa)
@ -803,7 +828,8 @@ static DWORD simd_fault_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_R
ok( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS,
"exception code: %#x, should be %#x\n",
rec->ExceptionCode, STATUS_FLOAT_MULTIPLE_TRAPS);
ok( rec->NumberParameters == 1, "# of params: %i, should be 1\n",
ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2),
"# of params: %i, should be 1\n",
rec->NumberParameters);
if( rec->NumberParameters == 1 )
ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]);
@ -924,14 +950,18 @@ static void test_fpu_exceptions(void)
run_exception_test(fpu_exception_handler, &info, fpu_exception_test_ie, sizeof(fpu_exception_test_ie), 0);
ok(info.exception_code == EXCEPTION_FLT_STACK_CHECK,
"Got exception code %#x, expected EXCEPTION_FLT_STACK_CHECK\n", info.exception_code);
ok(info.exception_offset == 0x19, "Got exception offset %#x, expected 0x19\n", info.exception_offset);
ok(info.exception_offset == 0x19 ||
broken( is_wow64 && info.exception_offset == info.eip_offset ),
"Got exception offset %#x, expected 0x19\n", info.exception_offset);
ok(info.eip_offset == 0x1b, "Got EIP offset %#x, expected 0x1b\n", info.eip_offset);
memset(&info, 0, sizeof(info));
run_exception_test(fpu_exception_handler, &info, fpu_exception_test_de, sizeof(fpu_exception_test_de), 0);
ok(info.exception_code == EXCEPTION_FLT_DIVIDE_BY_ZERO,
"Got exception code %#x, expected EXCEPTION_FLT_DIVIDE_BY_ZERO\n", info.exception_code);
ok(info.exception_offset == 0x17, "Got exception offset %#x, expected 0x17\n", info.exception_offset);
ok(info.exception_offset == 0x17 ||
broken( is_wow64 && info.exception_offset == info.eip_offset ),
"Got exception offset %#x, expected 0x17\n", info.exception_offset);
ok(info.eip_offset == 0x19, "Got EIP offset %#x, expected 0x19\n", info.eip_offset);
}
@ -1379,6 +1409,7 @@ START_TEST(exception)
"NtQueryInformationProcess" );
pNtSetInformationProcess = (void*)GetProcAddress( hntdll,
"NtSetInformationProcess" );
pIsWow64Process = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
#ifdef __i386__
if (!pNtCurrentTeb)
@ -1386,6 +1417,7 @@ START_TEST(exception)
skip( "NtCurrentTeb not found\n" );
return;
}
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
if (pRtlAddVectoredExceptionHandler && pRtlRemoveVectoredExceptionHandler)
have_vectored_api = TRUE;

View file

@ -116,7 +116,7 @@ ULONG_PTR completionKey;
IO_STATUS_BLOCK ioSb;
ULONG_PTR completionValue;
static long get_pending_msgs(HANDLE h)
static ULONG get_pending_msgs(HANDLE h)
{
NTSTATUS res;
ULONG a, req;
@ -163,9 +163,8 @@ static void create_file_test(void)
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
UNICODE_STRING nameW;
UINT len;
len = GetCurrentDirectoryW( MAX_PATH, path );
GetCurrentDirectoryW( MAX_PATH, path );
pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
@ -247,7 +246,6 @@ static void create_file_test(void)
todo_wine
ok( status == STATUS_INVALID_PARAMETER,
"open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
pRtlFreeUnicodeString( &nameW );
}
static void open_file_test(void)
@ -255,7 +253,7 @@ static void open_file_test(void)
NTSTATUS status;
HANDLE dir, root, handle;
WCHAR path[MAX_PATH];
BYTE data[8192];
BYTE data[1024];
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
UNICODE_STRING nameW;
@ -270,8 +268,8 @@ static void open_file_test(void)
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
status = pNtOpenFile( &dir, GENERIC_READ, &attr, &io,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE );
status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT );
ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
pRtlFreeUnicodeString( &nameW );
@ -321,56 +319,61 @@ static void open_file_test(void)
/* try open by file id */
while (!pNtQueryDirectoryFile( dir, NULL, NULL, NULL, &io, data, sizeof(data),
FileIdBothDirectoryInformation, FALSE, NULL, restart ))
FileIdBothDirectoryInformation, TRUE, NULL, restart ))
{
FILE_ID_BOTH_DIRECTORY_INFORMATION *info = (FILE_ID_BOTH_DIRECTORY_INFORMATION *)data;
restart = FALSE;
for (;;)
if (!info->FileId.QuadPart) continue;
nameW.Buffer = (WCHAR *)&info->FileId;
nameW.Length = sizeof(info->FileId);
info->FileName[info->FileNameLength/sizeof(WCHAR)] = 0;
attr.RootDirectory = dir;
/* We skip 'open' files by not specifying FILE_SHARE_WRITE */
status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
FILE_SHARE_READ,
FILE_OPEN_BY_FILE_ID |
((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED || status == STATUS_NOT_IMPLEMENTED || status == STATUS_SHARING_VIOLATION,
"open %s failed %x\n", wine_dbgstr_w(info->FileName), status );
if (status == STATUS_NOT_IMPLEMENTED)
{
if (!info->FileId.QuadPart) goto next;
nameW.Buffer = (WCHAR *)&info->FileId;
nameW.Length = sizeof(info->FileId);
info->FileName[info->FileNameLength/sizeof(WCHAR)] = 0;
attr.RootDirectory = dir;
win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
break;
}
if (status == STATUS_SHARING_VIOLATION)
trace( "%s is currently open\n", wine_dbgstr_w(info->FileName) );
if (!status)
{
BYTE buf[sizeof(FILE_ALL_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
if (!pNtQueryInformationFile( handle, &io, buf, sizeof(buf), FileAllInformation ))
{
FILE_ALL_INFORMATION *fai = (FILE_ALL_INFORMATION *)buf;
/* check that it's the same file/directory */
/* don't check the size for directories */
if (!(info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
ok( info->EndOfFile.QuadPart == fai->StandardInformation.EndOfFile.QuadPart,
"mismatched file size for %s\n", wine_dbgstr_w(info->FileName));
ok( info->CreationTime.QuadPart == fai->BasicInformation.CreationTime.QuadPart,
"mismatched creation time for %s\n", wine_dbgstr_w(info->FileName));
}
CloseHandle( handle );
/* try same thing from drive root */
attr.RootDirectory = root;
status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_BY_FILE_ID |
((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED || status == STATUS_NOT_IMPLEMENTED,
ok( status == STATUS_SUCCESS || status == STATUS_NOT_IMPLEMENTED,
"open %s failed %x\n", wine_dbgstr_w(info->FileName), status );
if (status == STATUS_NOT_IMPLEMENTED)
{
win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
break;
}
if (!status)
{
FILE_ALL_INFORMATION all_info;
if (!pNtQueryInformationFile( handle, &io, &all_info, sizeof(all_info), FileAllInformation ))
{
/* check that it's the same file */
ok( info->EndOfFile.QuadPart == all_info.StandardInformation.EndOfFile.QuadPart,
"mismatched file size for %s\n", wine_dbgstr_w(info->FileName));
ok( info->LastWriteTime.QuadPart == all_info.BasicInformation.LastWriteTime.QuadPart,
"mismatched write time for %s\n", wine_dbgstr_w(info->FileName));
}
CloseHandle( handle );
/* try same thing from drive root */
attr.RootDirectory = root;
status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN_BY_FILE_ID |
((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
ok( status == STATUS_SUCCESS || status == STATUS_NOT_IMPLEMENTED,
"open %s failed %x\n", wine_dbgstr_w(info->FileName), status );
if (!status) CloseHandle( handle );
}
next:
if (!info->NextEntryOffset) break;
info = (FILE_ID_BOTH_DIRECTORY_INFORMATION *)((char *)info + info->NextEntryOffset);
if (!status) CloseHandle( handle );
}
}
@ -907,13 +910,13 @@ static void nt_mailslot_test(void)
static void test_iocp_setcompletion(HANDLE h)
{
NTSTATUS res;
long count;
ULONG count;
res = pNtSetIoCompletion( h, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, 3 );
ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %x\n", res );
count = get_pending_msgs(h);
ok( count == 1, "Unexpected msg count: %ld\n", count );
ok( count == 1, "Unexpected msg count: %d\n", count );
if (get_msg(h))
{
@ -924,7 +927,7 @@ static void test_iocp_setcompletion(HANDLE h)
}
count = get_pending_msgs(h);
ok( !count, "Unexpected msg count: %ld\n", count );
ok( !count, "Unexpected msg count: %d\n", count );
}
static void test_iocp_fileio(HANDLE h)
@ -1473,8 +1476,7 @@ START_TEST(file)
pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile");
create_file_test();
ok(0, "broken test: open_file_test\n");
//open_file_test();
open_file_test();
delete_file_test();
read_file_test();
nt_mailslot_test();
@ -1483,6 +1485,5 @@ START_TEST(file)
test_file_all_information();
test_file_both_information();
test_file_name_information();
ok(0, "broken test: test_file_all_name_information \n");
//test_file_all_name_information();
test_file_all_name_information();
}

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@
#include "ntdll_test.h"
#include <winnls.h>
#include <stdio.h>
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
@ -27,6 +28,9 @@ static NTSTATUS (WINAPI * pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PV
static NTSTATUS (WINAPI * pNtSetInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG);
static NTSTATUS (WINAPI * pNtSetInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG);
static NTSTATUS (WINAPI * pNtReadVirtualMemory)(HANDLE, const void*, void*, SIZE_T, SIZE_T*);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static BOOL is_wow64;
/* one_before_last_pid is used to be able to compare values of a still running process
with the output of the test_query_process_times and test_query_process_handlecount tests.
@ -58,6 +62,8 @@ static BOOL InitFunctionPtrs(void)
NTDLL_GET_PROC(NtSetInformationThread);
NTDLL_GET_PROC(NtReadVirtualMemory);
pIsWow64Process = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
return TRUE;
}
@ -128,21 +134,25 @@ static void test_query_performance(void)
{
NTSTATUS status;
ULONG ReturnLength;
ULONGLONG buffer[sizeof(SYSTEM_PERFORMANCE_INFORMATION)/sizeof(ULONGLONG) + 1];
ULONGLONG buffer[sizeof(SYSTEM_PERFORMANCE_INFORMATION)/sizeof(ULONGLONG) + 5];
DWORD size = sizeof(SYSTEM_PERFORMANCE_INFORMATION);
status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, 0, &ReturnLength);
ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer,
sizeof(SYSTEM_PERFORMANCE_INFORMATION), &ReturnLength);
status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, size, &ReturnLength);
if (status == STATUS_INFO_LENGTH_MISMATCH && is_wow64)
{
/* size is larger on wow64 under w2k8/win7 */
size += 16;
status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, size, &ReturnLength);
}
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( ReturnLength == sizeof(SYSTEM_PERFORMANCE_INFORMATION), "Inconsistent length %d\n", ReturnLength);
ok( ReturnLength == size, "Inconsistent length %d\n", ReturnLength);
status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer,
sizeof(SYSTEM_PERFORMANCE_INFORMATION) + 2, &ReturnLength);
status = pNtQuerySystemInformation(SystemPerformanceInformation, buffer, size + 2, &ReturnLength);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( ReturnLength == sizeof(SYSTEM_PERFORMANCE_INFORMATION) ||
ReturnLength == sizeof(SYSTEM_PERFORMANCE_INFORMATION) + 2,
ok( ReturnLength == size || ReturnLength == size + 2,
"Inconsistent length %d\n", ReturnLength);
/* Not return values yet, as struct members are unknown */
@ -747,10 +757,84 @@ static void test_query_process_times(void)
status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes, &spti, sizeof(spti) * 2, &ReturnLength);
ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
ok( sizeof(spti) == ReturnLength || ReturnLength == 0 /* vista */,
ok( sizeof(spti) == ReturnLength ||
ReturnLength == 0 /* vista */ ||
broken(is_wow64), /* returns garbage on wow64 */
"Inconsistent length %d\n", ReturnLength);
}
static void test_query_process_debug_port(int argc, char **argv)
{
DWORD_PTR debug_port = 0xdeadbeef;
char cmdline[MAX_PATH];
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
NTSTATUS status;
BOOL ret;
sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
si.cb = sizeof(si);
ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
if (!ret) return;
status = pNtQueryInformationProcess(NULL, ProcessDebugPort,
NULL, 0, NULL);
ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
status = pNtQueryInformationProcess(NULL, ProcessDebugPort,
NULL, sizeof(debug_port), NULL);
ok(status == STATUS_INVALID_HANDLE || status == STATUS_ACCESS_VIOLATION,
"Expected STATUS_INVALID_HANDLE, got %#x.\n", status);
status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
NULL, sizeof(debug_port), NULL);
ok(status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
status = pNtQueryInformationProcess(NULL, ProcessDebugPort,
&debug_port, sizeof(debug_port), NULL);
ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
&debug_port, sizeof(debug_port) - 1, NULL);
ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
&debug_port, sizeof(debug_port) + 1, NULL);
ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %#x.\n", status);
status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort,
&debug_port, sizeof(debug_port), NULL);
ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
ok(debug_port == 0, "Expected port 0, got %#lx.\n", debug_port);
status = pNtQueryInformationProcess(pi.hProcess, ProcessDebugPort,
&debug_port, sizeof(debug_port), NULL);
ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
ok(debug_port == ~(DWORD_PTR)0, "Expected port %#lx, got %#lx.\n", ~(DWORD_PTR)0, debug_port);
for (;;)
{
DEBUG_EVENT ev;
ret = WaitForDebugEvent(&ev, INFINITE);
ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
if (!ret) break;
if (ev.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
if (!ret) break;
}
ret = CloseHandle(pi.hThread);
ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
ret = CloseHandle(pi.hProcess);
ok(ret, "CloseHandle failed, last error %#x.\n", GetLastError());
}
static void test_query_process_handlecount(void)
{
NTSTATUS status;
@ -928,7 +1012,7 @@ static void test_affinity(void)
ok( tbi.AffinityMask == 1, "Unexpected thread affinity\n" );
/* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
thread_affinity = ~0UL;
thread_affinity = ~(DWORD_PTR)0;
status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
ok( broken(status == STATUS_INVALID_PARAMETER) || status == STATUS_SUCCESS,
"Expected STATUS_SUCCESS, got %08x\n", status);
@ -978,9 +1062,15 @@ static void test_affinity(void)
START_TEST(info)
{
char **argv;
int argc;
if(!InitFunctionPtrs())
return;
argc = winetest_get_mainargs(&argv);
if (argc >= 3) return; /* Child */
/* NtQuerySystemInformation */
/* 0x0 SystemBasicInformation */
@ -1049,6 +1139,10 @@ START_TEST(info)
trace("Starting test_query_process_times()\n");
test_query_process_times();
/* 0x7 ProcessDebugPort */
trace("Starting test_process_debug_port()\n");
test_query_process_debug_port(argc, argv);
/* 0x14 ProcessHandleCount */
trace("Starting test_query_process_handlecount()\n");
test_query_process_handlecount();

View file

@ -226,6 +226,9 @@ static void test_RtlIsNameLegalDOS8Dot3(void)
}
static void test_RtlGetFullPathName_U(void)
{
static const WCHAR emptyW[] = {0};
static const WCHAR deadbeefW[] = {'d','e','a','d','b','e','e','f',0};
struct test
{
const char *path;
@ -269,6 +272,26 @@ static void test_RtlGetFullPathName_U(void)
DWORD reslen;
UINT len;
file_part = (WCHAR *)0xdeadbeef;
lstrcpyW(rbufferW, deadbeefW);
ret = pRtlGetFullPathName_U(NULL, MAX_PATH, rbufferW, &file_part);
ok(!ret, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret);
ok(!lstrcmpW(rbufferW, deadbeefW),
"Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW));
ok(file_part == (WCHAR *)0xdeadbeef ||
file_part == NULL, /* Win7 */
"Expected file part pointer to be untouched, got %p\n", file_part);
file_part = (WCHAR *)0xdeadbeef;
lstrcpyW(rbufferW, deadbeefW);
ret = pRtlGetFullPathName_U(emptyW, MAX_PATH, rbufferW, &file_part);
ok(!ret, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret);
ok(!lstrcmpW(rbufferW, deadbeefW),
"Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW));
ok(file_part == (WCHAR *)0xdeadbeef ||
file_part == NULL, /* Win7 */
"Expected file part pointer to be untouched, got %p\n", file_part);
for (test = tests; test->path; test++)
{
len= strlen(test->rname) * sizeof(WCHAR);

View file

@ -69,6 +69,25 @@ typedef struct _LPC_MESSAGE
#endif
/* on Wow64 we have to use the 64-bit layout */
typedef struct
{
USHORT DataSize;
USHORT MessageSize;
USHORT MessageType;
USHORT VirtualRangesOffset;
ULONGLONG ClientId[2];
ULONGLONG MessageId;
ULONGLONG SectionSize;
UCHAR Data[ANYSIZE_ARRAY];
} LPC_MESSAGE64;
union lpc_message
{
LPC_MESSAGE msg;
LPC_MESSAGE64 msg64;
};
/* Types of LPC messages */
#define UNUSED_MSG_TYPE 0
#define LPC_REQUEST 1
@ -110,6 +129,9 @@ static NTSTATUS (WINAPI *pNtConnectPort)(PHANDLE,PUNICODE_STRING,
PVOID,PVOID,PULONG);
static NTSTATUS (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING,LPCWSTR);
static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE,BOOLEAN,PLARGE_INTEGER);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static BOOL is_wow64;
static BOOL init_function_ptrs(void)
{
@ -140,47 +162,75 @@ static BOOL init_function_ptrs(void)
return FALSE;
}
pIsWow64Process = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
return TRUE;
}
static void ProcessConnectionRequest(PLPC_MESSAGE LpcMessage, PHANDLE pAcceptPortHandle)
static void ProcessConnectionRequest(union lpc_message *LpcMessage, PHANDLE pAcceptPortHandle)
{
NTSTATUS status;
ok(LpcMessage->MessageType == LPC_CONNECTION_REQUEST,
"Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->MessageType);
ok(!*LpcMessage->Data, "Expected empty string!\n");
if (is_wow64)
{
ok(LpcMessage->msg64.MessageType == LPC_CONNECTION_REQUEST,
"Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->msg64.MessageType);
ok(!*LpcMessage->msg64.Data, "Expected empty string!\n");
}
else
{
ok(LpcMessage->msg.MessageType == LPC_CONNECTION_REQUEST,
"Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->msg.MessageType);
ok(!*LpcMessage->msg.Data, "Expected empty string!\n");
}
status = pNtAcceptConnectPort(pAcceptPortHandle, 0, LpcMessage, 1, 0, NULL);
status = pNtAcceptConnectPort(pAcceptPortHandle, 0, &LpcMessage->msg, 1, 0, NULL);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
status = pNtCompleteConnectPort(*pAcceptPortHandle);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
}
static void ProcessLpcRequest(HANDLE PortHandle, PLPC_MESSAGE LpcMessage)
static void ProcessLpcRequest(HANDLE PortHandle, union lpc_message *LpcMessage)
{
NTSTATUS status;
ok(LpcMessage->MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST2),
"Expected %s, got %s\n", REQUEST2, LpcMessage->Data);
if (is_wow64)
{
ok(LpcMessage->msg64.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REQUEST2),
"Expected %s, got %s\n", REQUEST2, LpcMessage->msg64.Data);
lstrcpy((LPSTR)LpcMessage->msg64.Data, REPLY);
lstrcpy((LPSTR)LpcMessage->Data, REPLY);
status = pNtReplyPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg64.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REPLY),
"Expected %s, got %s\n", REPLY, LpcMessage->msg64.Data);
}
else
{
ok(LpcMessage->msg.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REQUEST2),
"Expected %s, got %s\n", REQUEST2, LpcMessage->msg.Data);
lstrcpy((LPSTR)LpcMessage->msg.Data, REPLY);
status = pNtReplyPort(PortHandle, LpcMessage);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->Data, REPLY),
"Expected %s, got %s\n", REPLY, LpcMessage->Data);
status = pNtReplyPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REPLY),
"Expected %s, got %s\n", REPLY, LpcMessage->msg.Data);
}
}
static DWORD WINAPI test_ports_client(LPVOID arg)
{
SECURITY_QUALITY_OF_SERVICE sqos;
LPC_MESSAGE *LpcMessage, *out;
union lpc_message *LpcMessage, *out;
HANDLE PortHandle;
ULONG len, size;
NTSTATUS status;
@ -197,31 +247,62 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
status = pNtRegisterThreadTerminatePort(PortHandle);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN;
LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
out = HeapAlloc(GetProcessHeap(), 0, size);
if (is_wow64)
{
size = FIELD_OFFSET(LPC_MESSAGE64, Data[MAX_MESSAGE_LEN]);
LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
out = HeapAlloc(GetProcessHeap(), 0, size);
LpcMessage->DataSize = lstrlen(REQUEST1) + 1;
LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data) + LpcMessage->DataSize;
lstrcpy((LPSTR)LpcMessage->Data, REQUEST1);
LpcMessage->msg64.DataSize = lstrlen(REQUEST1) + 1;
LpcMessage->msg64.MessageSize = FIELD_OFFSET(LPC_MESSAGE64, Data[LpcMessage->msg64.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg64.Data, REQUEST1);
status = pNtRequestPort(PortHandle, LpcMessage);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->MessageType == 0, "Expected 0, got %d\n", LpcMessage->MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->Data);
status = pNtRequestPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg64.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg64.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data);
/* Fill in the message */
memset(LpcMessage, 0, size);
LpcMessage->DataSize = lstrlen(REQUEST2) + 1;
LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data) + LpcMessage->DataSize;
lstrcpy((LPSTR)LpcMessage->Data, REQUEST2);
/* Fill in the message */
memset(LpcMessage, 0, size);
LpcMessage->msg64.DataSize = lstrlen(REQUEST2) + 1;
LpcMessage->msg64.MessageSize = FIELD_OFFSET(LPC_MESSAGE64, Data[LpcMessage->msg64.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg64.Data, REQUEST2);
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, LpcMessage, out);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(!lstrcmp((LPSTR)out->Data, REPLY), "Expected %s, got %s\n", REPLY, out->Data);
ok(out->MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->MessageType);
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(!lstrcmp((LPSTR)out->msg64.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg64.Data);
ok(out->msg64.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg64.MessageType);
}
else
{
size = FIELD_OFFSET(LPC_MESSAGE, Data[MAX_MESSAGE_LEN]);
LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
out = HeapAlloc(GetProcessHeap(), 0, size);
LpcMessage->msg.DataSize = lstrlen(REQUEST1) + 1;
LpcMessage->msg.MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->msg.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg.Data, REQUEST1);
status = pNtRequestPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data);
/* Fill in the message */
memset(LpcMessage, 0, size);
LpcMessage->msg.DataSize = lstrlen(REQUEST2) + 1;
LpcMessage->msg.MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->msg.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg.Data, REQUEST2);
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(!lstrcmp((LPSTR)out->msg.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg.Data);
ok(out->msg.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg.MessageType);
}
HeapFree(GetProcessHeap(), 0, out);
HeapFree(GetProcessHeap(), 0, LpcMessage);
@ -232,7 +313,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
static void test_ports_server( HANDLE PortHandle )
{
HANDLE AcceptPortHandle;
PLPC_MESSAGE LpcMessage;
union lpc_message *LpcMessage;
ULONG size;
NTSTATUS status;
BOOL done = FALSE;
@ -242,7 +323,7 @@ static void test_ports_server( HANDLE PortHandle )
while (TRUE)
{
status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, LpcMessage);
status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, &LpcMessage->msg);
todo_wine
{
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d(%x)\n", status, status);
@ -253,7 +334,7 @@ static void test_ports_server( HANDLE PortHandle )
if ((status == STATUS_NOT_IMPLEMENTED) ||
(status == STATUS_INVALID_HANDLE)) return;
switch (LpcMessage->MessageType)
switch (is_wow64 ? LpcMessage->msg64.MessageType : LpcMessage->msg.MessageType)
{
case LPC_CONNECTION_REQUEST:
ProcessConnectionRequest(LpcMessage, &AcceptPortHandle);
@ -265,8 +346,12 @@ static void test_ports_server( HANDLE PortHandle )
break;
case LPC_DATAGRAM:
ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->Data);
if (is_wow64)
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data);
else
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data);
break;
case LPC_CLIENT_DIED:
@ -275,7 +360,8 @@ static void test_ports_server( HANDLE PortHandle )
return;
default:
ok(FALSE, "Unexpected message: %d\n", LpcMessage->MessageType);
ok(FALSE, "Unexpected message: %d\n",
is_wow64 ? LpcMessage->msg64.MessageType : LpcMessage->msg.MessageType);
break;
}
}

View file

@ -42,7 +42,7 @@ static VOID (WINAPI *pRtlCopyString)(STRING *, const STRING *);
static BOOLEAN (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
static NTSTATUS (WINAPI *pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(long, UNICODE_STRING *, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(int, UNICODE_STRING *, UNICODE_STRING *);
static BOOLEAN (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
static NTSTATUS (WINAPI *pRtlFindCharInUnicodeString)(int, const UNICODE_STRING *, const UNICODE_STRING *, USHORT *);
static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
@ -53,14 +53,14 @@ static VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING, LPCWSTR);
static NTSTATUS (WINAPI *pRtlInitUnicodeStringEx)(PUNICODE_STRING, LPCWSTR);
static NTSTATUS (WINAPI *pRtlIntegerToChar)(ULONG, ULONG, ULONG, PCHAR);
static NTSTATUS (WINAPI *pRtlIntegerToUnicodeString)(ULONG, ULONG, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlMultiAppendUnicodeStringBuffer)(UNICODE_STRING *, long, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlMultiAppendUnicodeStringBuffer)(UNICODE_STRING *, LONG, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
static NTSTATUS (WINAPI *pRtlUnicodeStringToInteger)(const UNICODE_STRING *, int, int *);
static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
static CHAR (WINAPI *pRtlUpperChar)(CHAR);
static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const STRING *);
static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(long, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(LONG, UNICODE_STRING *);
static NTSTATUS (WINAPI *pRtlGUIDFromString)(const UNICODE_STRING*,GUID*);
static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*);
static BOOLEAN (WINAPI *pRtlIsTextUnicode)(LPVOID, INT, INT *);
@ -1695,6 +1695,8 @@ static void test_RtlIntegerToChar(void)
static void test_RtlIsTextUnicode(void)
{
char ascii[] = "A simple string";
char false_positive[] = {0x41, 0x0a, 0x0d, 0x1d};
WCHAR false_negative = 0x0d0a;
WCHAR unicode[] = {'A',' ','U','n','i','c','o','d','e',' ','s','t','r','i','n','g',0};
WCHAR unicode_no_controls[] = {'A','U','n','i','c','o','d','e','s','t','r','i','n','g',0};
/* String with both byte-reversed and standard Unicode control characters. */
@ -1810,6 +1812,11 @@ static void test_RtlIsTextUnicode(void)
ok(!pRtlIsTextUnicode(mixed_controls, sizeof(mixed_controls), &flags), "Test should pass on string containing both byte-reversed and standard control characters.\n");
ok(flags == (IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_REVERSE_CONTROLS), "Expected flags 0x44, obtained %x\n", flags);
flags = IS_TEXT_UNICODE_STATISTICS;
todo_wine ok(pRtlIsTextUnicode(false_positive, sizeof(false_positive), &flags), "Test should pass on false positive.\n");
ok(!pRtlIsTextUnicode(&false_negative, sizeof(false_negative), NULL), "Test should fail on 0x0d0a (MALAYALAM LETTER UU).\n");
HeapFree(GetProcessHeap(), 0, be_unicode);
HeapFree(GetProcessHeap(), 0, be_unicode_no_controls);
}

View file

@ -37,8 +37,8 @@ static int (WINAPIV *patoi)(const char *);
static long (WINAPIV *patol)(const char *);
static LONGLONG (WINAPIV *p_atoi64)(const char *);
static LPSTR (WINAPIV *p_itoa)(int, LPSTR, INT);
static LPSTR (WINAPIV *p_ltoa)(long, LPSTR, INT);
static LPSTR (WINAPIV *p_ultoa)(unsigned long, LPSTR, INT);
static LPSTR (WINAPIV *p_ltoa)(LONG, LPSTR, INT);
static LPSTR (WINAPIV *p_ultoa)(ULONG, LPSTR, INT);
static LPSTR (WINAPIV *p_i64toa)(LONGLONG, LPSTR, INT);
static LPSTR (WINAPIV *p_ui64toa)(ULONGLONG, LPSTR, INT);
@ -46,8 +46,8 @@ static int (WINAPIV *p_wtoi)(LPWSTR);
static long (WINAPIV *p_wtol)(LPWSTR);
static LONGLONG (WINAPIV *p_wtoi64)(LPWSTR);
static LPWSTR (WINAPIV *p_itow)(int, LPWSTR, int);
static LPWSTR (WINAPIV *p_ltow)(long, LPWSTR, INT);
static LPWSTR (WINAPIV *p_ultow)(unsigned long, LPWSTR, INT);
static LPWSTR (WINAPIV *p_ltow)(LONG, LPWSTR, INT);
static LPWSTR (WINAPIV *p_ultow)(ULONG, LPWSTR, INT);
static LPWSTR (WINAPIV *p_i64tow)(LONGLONG, LPWSTR, INT);
static LPWSTR (WINAPIV *p_ui64tow)(ULONGLONG, LPWSTR, INT);
@ -57,6 +57,10 @@ static ULONG (WINAPIV *pwcstoul)(LPCWSTR, LPWSTR *, INT);
static LPWSTR (WINAPIV *p_wcschr)(LPCWSTR, WCHAR);
static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
static void (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static void* (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static void InitFunctionPtrs(void)
{
hntdll = LoadLibraryA("ntdll.dll");
@ -90,6 +94,8 @@ static void InitFunctionPtrs(void)
p_wcschr= (void *)GetProcAddress(hntdll, "wcschr");
p_wcsrchr= (void *)GetProcAddress(hntdll, "wcsrchr");
p_qsort= (void *)GetProcAddress(hntdll, "qsort");
p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
} /* if */
}
@ -228,7 +234,7 @@ static void one_itoa_test(int test_num, const ulong2str_t *ulong2str)
static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str)
{
char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
long value;
LONG value;
LPSTR result;
memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
@ -236,10 +242,10 @@ static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str)
value = ulong2str->value;
result = p_ltoa(ulong2str->value, dest_str, ulong2str->base);
ok(result == dest_str,
"(test %d): _ltoa(%ld, [out], %d) has result %p, expected: %p\n",
"(test %d): _ltoa(%d, [out], %d) has result %p, expected: %p\n",
test_num, value, ulong2str->base, result, dest_str);
ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
"(test %d): _ltoa(%ld, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
"(test %d): _ltoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
}
@ -247,7 +253,7 @@ static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str)
static void one_ultoa_test(int test_num, const ulong2str_t *ulong2str)
{
char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
unsigned long value;
ULONG value;
LPSTR result;
memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
@ -255,10 +261,10 @@ static void one_ultoa_test(int test_num, const ulong2str_t *ulong2str)
value = ulong2str->value;
result = p_ultoa(ulong2str->value, dest_str, ulong2str->base);
ok(result == dest_str,
"(test %d): _ultoa(%lu, [out], %d) has result %p, expected: %p\n",
"(test %d): _ultoa(%u, [out], %d) has result %p, expected: %p\n",
test_num, value, ulong2str->base, result, dest_str);
ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
"(test %d): _ultoa(%lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
"(test %d): _ultoa(%u, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
}
@ -323,7 +329,7 @@ static void one_ltow_test(int test_num, const ulong2str_t *ulong2str)
WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
UNICODE_STRING unicode_string;
STRING ansi_str;
long value;
LONG value;
LPWSTR result;
for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
@ -343,10 +349,10 @@ static void one_ltow_test(int test_num, const ulong2str_t *ulong2str)
result = p_ltow(value, dest_wstr, ulong2str->base);
pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
ok(result == dest_wstr,
"(test %d): _ltow(%ld, [out], %d) has result %p, expected: %p\n",
"(test %d): _ltow(%d, [out], %d) has result %p, expected: %p\n",
test_num, value, ulong2str->base, result, dest_wstr);
ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
"(test %d): _ltow(%ld, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
"(test %d): _ltow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
pRtlFreeAnsiString(&ansi_str);
}
@ -359,7 +365,7 @@ static void one_ultow_test(int test_num, const ulong2str_t *ulong2str)
WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
UNICODE_STRING unicode_string;
STRING ansi_str;
unsigned long value;
ULONG value;
LPWSTR result;
for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
@ -379,10 +385,10 @@ static void one_ultow_test(int test_num, const ulong2str_t *ulong2str)
result = p_ultow(value, dest_wstr, ulong2str->base);
pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
ok(result == dest_wstr,
"(test %d): _ultow(%lu, [out], %d) has result %p, expected: %p\n",
"(test %d): _ultow(%u, [out], %d) has result %p, expected: %p\n",
test_num, value, ulong2str->base, result, dest_wstr);
ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
"(test %d): _ultow(%lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
"(test %d): _ultow(%u, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
pRtlFreeAnsiString(&ansi_str);
}
@ -1137,6 +1143,80 @@ static void test_wcsrchr(void)
"wcsrchr should have returned NULL\n");
}
static __cdecl int intcomparefunc(const void *a, const void*b)
{
ok (a != b, "must never get the same pointer\n");
return (*(int*)a) - (*(int*)b);
}
static __cdecl int charcomparefunc(const void *a, const void*b)
{
ok (a != b, "must never get the same pointer\n");
return (*(char*)a) - (*(char*)b);
}
static __cdecl int strcomparefunc(const void *a, const void*b)
{
ok (a != b, "must never get the same pointer\n");
return lstrcmpA(*(char**)a,*(char**)b);
}
static void test_qsort(void)
{
int arr[5] = { 23, 42, 8, 4, 16 };
char carr[5] = { 42, 23, 4, 8, 16 };
const char *strarr[7] = {
"Hello",
"Wine",
"World",
"!",
"Hopefully",
"Sorted",
"."
};
p_qsort ((void*)arr, 5, sizeof(int), intcomparefunc);
ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
p_qsort ((void*)carr, 5, sizeof(char), charcomparefunc);
ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
p_qsort ((void*)strarr, 7, sizeof(char*), strcomparefunc);
ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
}
static void test_bsearch(void)
{
int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
int *x, l, i,j ;
/* just try all all sizes */
for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
for (i=0;i<j;i++) {
l = arr[i];
x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
ok (x == &arr[i], "bsearch did not find %d entry in loopsize %d.\n", i, j);
}
l = 4242;
x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
ok (x == NULL, "bsearch did find 4242 entry in loopsize %d.\n", j);
}
}
START_TEST(string)
{
InitFunctionPtrs();
@ -1165,4 +1245,8 @@ START_TEST(string)
test_atoi();
if (patol)
test_atol();
if (p_qsort)
test_qsort();
if (p_bsearch)
test_bsearch();
}

View file

@ -105,6 +105,170 @@ static const IDropTargetVtbl DropTarget_VTbl =
static IDropTarget DropTarget = { &DropTarget_VTbl };
/** stub IDropSource **/
static HRESULT WINAPI DropSource_QueryInterface(IDropSource *iface, REFIID riid, void **ppObj)
{
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IDropSource))
{
*ppObj = iface;
IDropSource_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI DropSource_AddRef(IDropSource *iface)
{
return 2;
}
static ULONG WINAPI DropSource_Release(IDropSource *iface)
{
return 1;
}
static HRESULT WINAPI DropSource_QueryContinueDrag(
IDropSource *iface,
BOOL fEscapePressed,
DWORD grfKeyState)
{
/* always drop */
return DRAGDROP_S_DROP;
}
static HRESULT WINAPI DropSource_GiveFeedback(
IDropSource *iface,
DWORD dwEffect)
{
return DRAGDROP_S_USEDEFAULTCURSORS;
}
static const IDropSourceVtbl dropsource_vtbl = {
DropSource_QueryInterface,
DropSource_AddRef,
DropSource_Release,
DropSource_QueryContinueDrag,
DropSource_GiveFeedback
};
static IDropSource DropSource = { &dropsource_vtbl };
/** IDataObject stub **/
static HRESULT WINAPI DataObject_QueryInterface(
IDataObject *iface,
REFIID riid,
void **pObj)
{
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IDataObject))
{
*pObj = iface;
IDataObject_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI DataObject_AddRef(IDataObject *iface)
{
return 2;
}
static ULONG WINAPI DataObject_Release(IDataObject *iface)
{
return 1;
}
static HRESULT WINAPI DataObject_GetData(
IDataObject *iface,
FORMATETC *pformatetcIn,
STGMEDIUM *pmedium)
{
return E_NOTIMPL;
}
static HRESULT WINAPI DataObject_GetDataHere(
IDataObject *iface,
FORMATETC *pformatetc,
STGMEDIUM *pmedium)
{
return E_NOTIMPL;
}
static HRESULT WINAPI DataObject_QueryGetData(
IDataObject *iface,
FORMATETC *pformatetc)
{
return S_OK;
}
static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
IDataObject *iface,
FORMATETC *pformatectIn,
FORMATETC *pformatetcOut)
{
return E_NOTIMPL;
}
static HRESULT WINAPI DataObject_SetData(
IDataObject *iface,
FORMATETC *pformatetc,
STGMEDIUM *pmedium,
BOOL fRelease)
{
return E_NOTIMPL;
}
static HRESULT WINAPI DataObject_EnumFormatEtc(
IDataObject *iface,
DWORD dwDirection,
IEnumFORMATETC **ppenumFormatEtc)
{
return S_OK;
}
static HRESULT WINAPI DataObject_DAdvise(
IDataObject *iface,
FORMATETC *pformatetc,
DWORD advf,
IAdviseSink *pAdvSink,
DWORD *pdwConnection)
{
return E_NOTIMPL;
}
static HRESULT WINAPI DataObject_DUnadvise(
IDataObject *iface,
DWORD dwConnection)
{
return E_NOTIMPL;
}
static HRESULT WINAPI DataObject_EnumDAdvise(
IDataObject *iface,
IEnumSTATDATA **ppenumAdvise)
{
return E_NOTIMPL;
}
static const IDataObjectVtbl dataobject_vtbl = {
DataObject_QueryInterface,
DataObject_AddRef,
DataObject_Release,
DataObject_GetData,
DataObject_GetDataHere,
DataObject_QueryGetData,
DataObject_GetCanonicalFormatEtc,
DataObject_SetData,
DataObject_EnumFormatEtc,
DataObject_DAdvise,
DataObject_DUnadvise,
DataObject_EnumDAdvise
};
static IDataObject DataObject = { &dataobject_vtbl };
static ATOM register_dummy_class(void)
{
WNDCLASS wc =
@ -124,12 +288,13 @@ static ATOM register_dummy_class(void)
return RegisterClass(&wc);
}
START_TEST(dragdrop)
static void test_Register_Revoke(void)
{
HANDLE prop;
HRESULT hr;
HWND hwnd;
hwnd = CreateWindow(MAKEINTATOM(register_dummy_class()), "Test", 0,
hwnd = CreateWindowA("WineOleTestClass", "Test", 0,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL, NULL, NULL);
@ -154,6 +319,9 @@ START_TEST(dragdrop)
ok_ole_success(hr, "RegisterDragDrop");
ok(droptarget_addref_called == 1, "DropTarget_AddRef should have been called once, not %d times\n", droptarget_addref_called);
prop = GetPropA(hwnd, "OleDropTargetInterface");
ok(prop == &DropTarget, "expected IDropTarget pointer %p, got %p\n", &DropTarget, prop);
hr = RegisterDragDrop(hwnd, &DropTarget);
ok(hr == DRAGDROP_E_ALREADYREGISTERED, "RegisterDragDrop with already registered hwnd should return DRAGDROP_E_ALREADYREGISTERED instead of 0x%08x\n", hr);
@ -171,4 +339,73 @@ START_TEST(dragdrop)
ok(hr == DRAGDROP_E_INVALIDHWND, "RevokeDragDrop with NULL hwnd should return DRAGDROP_E_INVALIDHWND instead of 0x%08x\n", hr);
DestroyWindow(hwnd);
/* try to revoke with already destroyed window */
OleInitialize(NULL);
hwnd = CreateWindowA("WineOleTestClass", "Test", 0,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL, NULL, NULL);
hr = RegisterDragDrop(hwnd, &DropTarget);
ok(hr == S_OK, "got 0x%08x\n", hr);
DestroyWindow(hwnd);
hr = RevokeDragDrop(hwnd);
ok(hr == DRAGDROP_E_INVALIDHWND, "got 0x%08x\n", hr);
OleUninitialize();
}
static void test_DoDragDrop(void)
{
DWORD effect;
HRESULT hr;
HWND hwnd;
hwnd = CreateWindowA("WineOleTestClass", "Test", 0,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL, NULL, NULL);
ok(IsWindow(hwnd), "failed to create window\n");
hr = OleInitialize(NULL);
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = RegisterDragDrop(hwnd, &DropTarget);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* incomplete arguments set */
hr = DoDragDrop(NULL, NULL, 0, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = DoDragDrop(NULL, &DropSource, 0, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = DoDragDrop(&DataObject, NULL, 0, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = DoDragDrop(NULL, NULL, 0, &effect);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = DoDragDrop(&DataObject, &DropSource, 0, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = DoDragDrop(NULL, &DropSource, 0, &effect);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
hr = DoDragDrop(&DataObject, NULL, 0, &effect);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
OleUninitialize();
DestroyWindow(hwnd);
}
START_TEST(dragdrop)
{
register_dummy_class();
test_Register_Revoke();
test_DoDragDrop();
}

View file

@ -151,7 +151,7 @@ static void test_streamonhglobal(IStream *pStream)
ok(ull.u.LowPart == 0, "should have set LowPart to 0 instead of %d\n", ull.u.LowPart);
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
/* IStream_Seek -- invalid LowPart value (seek from current position) */
/* IStream_Seek -- invalid LowPart value (seek before start of stream) */
ll.u.HighPart = 0;
ll.u.LowPart = sizeof(data);
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
@ -166,6 +166,51 @@ static void test_streamonhglobal(IStream *pStream)
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
/* IStream_Seek -- valid LowPart value (seek to start of stream) */
ll.u.HighPart = 0;
ll.u.LowPart = sizeof(data);
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
ok_ole_success(hr, "IStream_Seek");
ull.u.HighPart = 0xCAFECAFE;
ull.u.LowPart = 0xCAFECAFE;
ll.u.HighPart = 0;
ll.u.LowPart = -sizeof(data);
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
ok_ole_success(hr, "IStream_Seek");
ok(ull.u.LowPart == 0, "LowPart set to %d\n", ull.u.LowPart);
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
/* IStream_Seek -- invalid LowPart value (seek to start of stream-1) */
ll.u.HighPart = 0;
ll.u.LowPart = sizeof(data);
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
ok_ole_success(hr, "IStream_Seek");
ull.u.HighPart = 0xCAFECAFE;
ull.u.LowPart = 0xCAFECAFE;
ll.u.HighPart = 0;
ll.u.LowPart = -sizeof(data)-1;
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr);
ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart);
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
/* IStream_Seek -- valid LowPart value (seek forward to 0x80000000) */
ll.u.HighPart = 0;
ll.u.LowPart = sizeof(data);
hr = IStream_Seek(pStream, ll, STREAM_SEEK_SET, &ull);
ok_ole_success(hr, "IStream_Seek");
ull.u.HighPart = 0xCAFECAFE;
ull.u.LowPart = 0xCAFECAFE;
ll.u.HighPart = 0;
ll.u.LowPart = 0x80000000 - sizeof(data);
hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull);
ok_ole_success(hr, "IStream_Seek");
ok(ull.u.LowPart == 0x80000000, "LowPart set to %d\n", ull.u.LowPart);
ok(ull.u.HighPart == 0, "should have set HighPart to 0 instead of %d\n", ull.u.HighPart);
/* IStream_Seek -- invalid LowPart value (seek to beginning) */
ll.u.HighPart = 0;
ll.u.LowPart = sizeof(data);

View file

@ -814,21 +814,70 @@ static void test_MkParseDisplayName(void)
static const WCHAR wszDisplayNameProgId1[] = {'S','t','d','F','o','n','t',':',0};
static const WCHAR wszDisplayNameProgId2[] = {'@','S','t','d','F','o','n','t',0};
static const WCHAR wszDisplayNameProgIdFail[] = {'S','t','d','F','o','n','t',0};
static const WCHAR wszEmpty[] = {0};
char szDisplayNameFile[256];
WCHAR wszDisplayNameFile[256];
int i, len;
const struct
{
LPBC *ppbc;
LPCOLESTR szDisplayName;
LPDWORD pchEaten;
LPMONIKER *ppmk;
} invalid_parameters[] =
{
{NULL, NULL, NULL, NULL},
{NULL, NULL, NULL, &pmk},
{NULL, NULL, &eaten, NULL},
{NULL, NULL, &eaten, &pmk},
{NULL, wszEmpty, NULL, NULL},
{NULL, wszEmpty, NULL, &pmk},
{NULL, wszEmpty, &eaten, NULL},
{NULL, wszEmpty, &eaten, &pmk},
{&pbc, NULL, NULL, NULL},
{&pbc, NULL, NULL, &pmk},
{&pbc, NULL, &eaten, NULL},
{&pbc, NULL, &eaten, &pmk},
{&pbc, wszEmpty, NULL, NULL},
{&pbc, wszEmpty, NULL, &pmk},
{&pbc, wszEmpty, &eaten, NULL},
{&pbc, wszEmpty, &eaten, &pmk},
};
hr = CreateBindCtx(0, &pbc);
ok_ole_success(hr, CreateBindCtx);
for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
{
eaten = 0xdeadbeef;
pmk = (IMoniker *)0xdeadbeef;
hr = MkParseDisplayName(invalid_parameters[i].ppbc ? *invalid_parameters[i].ppbc : NULL,
invalid_parameters[i].szDisplayName,
invalid_parameters[i].pchEaten,
invalid_parameters[i].ppmk);
ok(hr == E_INVALIDARG, "[%d] MkParseDisplayName should have failed with E_INVALIDARG instead of 0x%08x\n", i, hr);
ok(eaten == 0xdeadbeef, "[%d] Processed character count should have been 0xdeadbeef instead of %u\n", i, eaten);
ok(pmk == (IMoniker *)0xdeadbeef, "[%d] Output moniker pointer should have been 0xdeadbeef instead of %p\n", i, pmk);
}
eaten = 0xdeadbeef;
pmk = (IMoniker *)0xdeadbeef;
hr = MkParseDisplayName(pbc, wszNonExistentProgId, &eaten, &pmk);
ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
"MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
ok(eaten == 0, "Processed character count should have been 0 instead of %u\n", eaten);
ok(pmk == NULL, "Output moniker pointer should have been NULL instead of %p\n", pmk);
/* no special handling of "clsid:" without the string form of the clsid
* following */
eaten = 0xdeadbeef;
pmk = (IMoniker *)0xdeadbeef;
hr = MkParseDisplayName(pbc, wszDisplayNameClsid, &eaten, &pmk);
ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
"MkParseDisplayName should have failed with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
ok(eaten == 0, "Processed character count should have been 0 instead of %u\n", eaten);
ok(pmk == NULL, "Output moniker pointer should have been NULL instead of %p\n", pmk);
/* shows clsid has higher precedence than a running object */
hr = CreateFileMoniker(wszDisplayName, &pmk);
@ -841,6 +890,8 @@ static void test_MkParseDisplayName(void)
pmk = NULL;
hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == sizeof(wszDisplayName)/sizeof(WCHAR) - 1,
"Processed character count should have been 43 instead of %u\n", eaten);
if (pmk)
{
IMoniker_IsSystemMoniker(pmk, &moniker_type);
@ -861,6 +912,8 @@ static void test_MkParseDisplayName(void)
pmk = NULL;
hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == sizeof(wszDisplayNameRunning)/sizeof(WCHAR) - 1,
"Processed character count should have been 15 instead of %u\n", eaten);
if (pmk)
{
IMoniker_IsSystemMoniker(pmk, &moniker_type);
@ -877,6 +930,8 @@ static void test_MkParseDisplayName(void)
expected_display_name = wszDisplayNameProgId1;
hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == sizeof(wszDisplayNameProgId1)/sizeof(WCHAR) - 1,
"Processed character count should have been 8 instead of %u\n", eaten);
if (pmk)
{
IMoniker_IsSystemMoniker(pmk, &moniker_type);
@ -887,6 +942,8 @@ static void test_MkParseDisplayName(void)
expected_display_name = wszDisplayNameProgId2;
hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == sizeof(wszDisplayNameProgId2)/sizeof(WCHAR) - 1,
"Processed character count should have been 8 instead of %u\n", eaten);
if (pmk)
{
IMoniker_IsSystemMoniker(pmk, &moniker_type);
@ -894,18 +951,23 @@ static void test_MkParseDisplayName(void)
IMoniker_Release(pmk);
}
eaten = 0xdeadbeef;
pmk = (IMoniker *)0xdeadbeef;
hr = MkParseDisplayName(pbc, wszDisplayNameProgIdFail, &eaten, &pmk);
ok(hr == MK_E_SYNTAX || hr == MK_E_CANTOPENFILE /* Win9x */,
"MkParseDisplayName with ProgId without marker should fail with MK_E_SYNTAX or MK_E_CANTOPENFILE instead of 0x%08x\n", hr);
ok(eaten == 0, "Processed character count should have been 0 instead of %u\n", eaten);
ok(pmk == NULL, "Output moniker pointer should have been NULL instead of %p\n", pmk);
hr = CoRevokeClassObject(pdwReg1);
ok_ole_success(hr, CoRevokeClassObject);
GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
strcat(szDisplayNameFile, "\\kernel32.dll");
MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
len = MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == len - 1, "Processed character count should have been %d instead of %u\n", len - 1, eaten);
if (pmk)
{
IMoniker_IsSystemMoniker(pmk, &moniker_type);
@ -915,6 +977,7 @@ static void test_MkParseDisplayName(void)
hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == sizeof(wszDisplayName)/sizeof(WCHAR) - 1, "Processed character count should have been 43 instead of %u\n", eaten);
if (pmk)
{

View file

@ -59,6 +59,8 @@ static void testProps(void)
PROPVARIANT var;
CLIPDATA clipdata;
unsigned char clipcontent[] = "foobar";
GUID anyOldGuid = { 0x12345678,0xdead,0xbeef, {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 } };
if(!GetTempFileNameW(szDot, szPrefix, 0, filename))
return;
@ -290,6 +292,59 @@ static void testProps(void)
IStorage_Release(storage);
DeleteFileW(filename);
/* Test creating a property set storage with a random GUID */
hr = StgCreateDocfile(filename,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage);
ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr);
if(!pStgCreatePropSetStg)
{
IStorage_Release(storage);
DeleteFileW(filename);
return;
}
hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
hr = IPropertySetStorage_Create(propSetStorage,
&anyOldGuid, NULL, PROPSETFLAG_ANSI,
STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
&propertyStorage);
ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr);
spec.ulKind = PRSPEC_PROPID;
U(spec).propid = PID_FIRST_USABLE;
U(var).lVal = 1;
hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0);
ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr);
IPropertyStorage_Release(propertyStorage);
IPropertySetStorage_Release(propSetStorage);
IStorage_Release(storage);
/* now open it again */
hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
NULL, 0, &storage);
ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr);
hr = pStgCreatePropSetStg(storage, 0, &propSetStorage);
ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr);
hr = IPropertySetStorage_Open(propSetStorage, &anyOldGuid,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage);
ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr);
spec.ulKind = PRSPEC_PROPID;
U(spec).propid = PID_FIRST_USABLE;
hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var);
ok(hr == S_FALSE, "ReadMultiple failed: 0x%08x\n", hr);
IPropertyStorage_Release(propertyStorage);
IPropertySetStorage_Release(propSetStorage);
IStorage_Release(storage);
DeleteFileW(filename);
}
static void testCodepage(void)

View file

@ -315,6 +315,55 @@ static void test_storage_stream(void)
r = IStream_Commit(stm, STGC_DEFAULT );
ok(r==S_OK, "failed to commit stream\n");
/* Read past the end of the stream. */
pos.QuadPart = 3;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 3, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to read\n");
ok(count == 3, "read bytes past end of stream\n");
pos.QuadPart = 10;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 10, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to read\n");
ok(count == 0, "read bytes past end of stream\n");
pos.QuadPart = 10000;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 10000, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to read\n");
ok(count == 0, "read bytes past end of stream\n");
/* Convert to a big block stream, and read past the end. */
p.QuadPart = 5000;
r = IStream_SetSize(stm,p);
ok(r==S_OK, "failed to set pos\n");
pos.QuadPart = 4997;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 4997, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to read\n");
ok(count == 3, "read bytes past end of stream\n");
pos.QuadPart = 5001;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 5001, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to read\n");
ok(count == 0, "read bytes past end of stream\n");
pos.QuadPart = 10000;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 10000, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to read\n");
ok(count == 0, "read bytes past end of stream\n");
/* seek round a bit, reset the stream size */
pos.QuadPart = 0;
r = IStream_Seek(stm, pos, 3, &p );
@ -329,6 +378,16 @@ static void test_storage_stream(void)
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 10, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to set pos\n");
ok(count == 0, "read bytes from empty stream\n");
pos.QuadPart = 10000;
r = IStream_Seek(stm, pos, STREAM_SEEK_SET, &p );
ok(r==S_OK, "failed to seek stream\n");
ok(p.QuadPart == 10000, "at wrong place\n");
r = IStream_Read(stm, buffer, sizeof buffer, &count );
ok(r==S_OK, "failed to set pos\n");
ok(count == 0, "read bytes from empty stream\n");
pos.QuadPart = 0;
r = IStream_Seek(stm, pos, STREAM_SEEK_END, &p );
ok(r==S_OK, "failed to seek stream\n");
@ -2750,7 +2809,7 @@ static void test_copyto_locking(void)
/* Try to copy the storage while the stream is open */
r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3);
todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r);
IStream_Release(stm);

View file

@ -603,7 +603,7 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown);
wireip = buffer;
ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p (diff %x)\n", buffer_end, buffer, buffer_end - buffer);
ok(buffer_end == buffer + marshal_size + 2 * sizeof(DWORD), "buffer_end %p buffer %p\n", buffer_end, buffer);
ok(*(DWORD *)wireip == marshal_size, "wireip + 0x0 should be %x instead of %x\n", marshal_size, *(DWORD *)wireip);
wireip += sizeof(DWORD);

View file

@ -934,6 +934,28 @@ static void test_PdhMakeCounterPathA(void)
ok(ret == PDH_INVALID_ARGUMENT, "PdhMakeCounterPathA failed 0x%08x\n", ret);
}
static void test_PdhGetDllVersion(void)
{
PDH_STATUS ret;
DWORD version;
ret = PdhGetDllVersion(NULL);
ok(ret == PDH_INVALID_ARGUMENT ||
broken(ret == ERROR_SUCCESS), /* Vista+ */
"Expected PdhGetDllVersion to return PDH_INVALID_ARGUMENT, got %d\n", ret);
ret = PdhGetDllVersion(&version);
ok(ret == ERROR_SUCCESS,
"Expected PdhGetDllVersion to return ERROR_SUCCESS, got %d\n", ret);
if (ret == ERROR_SUCCESS)
{
ok(version == PDH_CVERSION_WIN50 ||
version == PDH_VERSION,
"Expected version number to be PDH_CVERSION_WIN50 or PDH_VERSION, got %u\n", version);
}
}
START_TEST(pdh)
{
if (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)
@ -975,4 +997,5 @@ START_TEST(pdh)
test_PdhCollectQueryDataEx();
test_PdhMakeCounterPathA();
test_PdhGetDllVersion();
}

View file

@ -275,23 +275,36 @@ static void test_ws_functions(void)
ULONG_PTR pages[4096];
char *addr;
unsigned int i;
BOOL ret;
todo_wine w32_err(pEmptyWorkingSet(NULL), ERROR_INVALID_HANDLE);
todo_wine w32_err(pEmptyWorkingSet(hpSR), ERROR_ACCESS_DENIED);
w32_suc(pEmptyWorkingSet(hpAA));
todo_wine w32_err(pInitializeProcessForWsWatch(NULL), ERROR_INVALID_HANDLE);
SetLastError( 0xdeadbeef );
ret = pInitializeProcessForWsWatch( NULL );
todo_wine ok( !ret, "InitializeProcessForWsWatch succeeded\n" );
if (!ret)
{
if (GetLastError() == ERROR_INVALID_FUNCTION) /* not supported on xp in wow64 mode */
{
trace( "InitializeProcessForWsWatch not supported\n" );
return;
}
ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
}
w32_suc(pInitializeProcessForWsWatch(hpAA));
if(!w32_suc(addr = VirtualAlloc(NULL, 1, MEM_COMMIT, PAGE_READWRITE)))
return;
*addr = 0; /* make sure it's paged in (needed on wow64) */
if(!VirtualLock(addr, 1))
{
trace("locking failed (error=%d) - skipping test\n", GetLastError());
goto free_page;
}
todo_wine if(w32_suc(pQueryWorkingSet(hpQI, pages, 4096 * sizeof(ULONG_PTR))))
{
for(i = 0; i < pages[0]; i++)

View file

@ -0,0 +1,234 @@
/*
* Unit tests for DSound Renderer functions
*
* Copyright (C) 2010 Maarten Lankhorst for CodeWeavers
* Copyright (C) 2007 Google (Lei Zhang)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define NONAMELESSUNION
#define COBJMACROS
#include "wine/test.h"
#include "dshow.h"
#include "initguid.h"
#include "dsound.h"
#include "amaudio.h"
#define QI_SUCCEED(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \
ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); \
ok(ppv != NULL, "Pointer is NULL\n");
#define RELEASE_EXPECT(iface, num) if (iface) { \
hr = IUnknown_Release(iface); \
ok(hr == num, "IUnknown_Release should return %d, got %d\n", num, hr); \
}
static IUnknown *pDSRender = NULL;
static int create_dsound_renderer(void)
{
HRESULT hr;
hr = CoCreateInstance(&CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (LPVOID*)&pDSRender);
return (hr == S_OK && pDSRender != NULL);
}
static void release_dsound_renderer(void)
{
HRESULT hr;
hr = IUnknown_Release(pDSRender);
ok(hr == 0, "IUnknown_Release failed with %x\n", hr);
}
static HRESULT WINAPI PB_QueryInterface(IPropertyBag *iface, REFIID riid, void **ppv)
{
ok(0, "Should not be called\n");
*ppv = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI PB_AddRef(IPropertyBag *iface)
{
ok(0, "Should not be called\n");
return 2;
}
static ULONG WINAPI PB_Release(IPropertyBag *iface)
{
ok(0, "Should not be called\n");
return 1;
}
static HRESULT WINAPI PB_Read(IPropertyBag *iface, LPCOLESTR name, VARIANT *var, IErrorLog *log)
{
static const WCHAR dsguid[] = { 'D','S','G','u','i','d', 0 };
char temp[50];
WideCharToMultiByte(CP_ACP, 0, name, -1, temp, sizeof(temp)-1, NULL, NULL);
temp[sizeof(temp)-1] = 0;
trace("Trying to read %s, type %u\n", temp, var->n1.n2.vt);
if (!lstrcmpW(name, dsguid))
{
static const WCHAR defaultplayback[] =
{
'{','D','E','F','0','0','0','0','0','-',
'9','C','6','D','-','4','7','E','D','-',
'A','A','F','1','-','4','D','D','A','8',
'F','2','B','5','C','0','3','}',0
};
ok(var->n1.n2.vt == VT_BSTR, "Wrong type asked: %u\n", var->n1.n2.vt);
var->n1.n2.n3.bstrVal = SysAllocString(defaultplayback);
return S_OK;
}
ok(0, "Unknown property '%s' queried\n", temp);
return E_FAIL;
}
static HRESULT WINAPI PB_Write(IPropertyBag *iface, LPCOLESTR name, VARIANT *var)
{
ok(0, "Should not be called\n");
return E_FAIL;
}
static IPropertyBagVtbl PB_Vtbl =
{
PB_QueryInterface,
PB_AddRef,
PB_Release,
PB_Read,
PB_Write
};
static void test_query_interface(void)
{
HRESULT hr;
IBaseFilter *pBaseFilter = NULL;
IBasicAudio *pBasicAudio = NULL;
IMediaPosition *pMediaPosition = NULL;
IMediaSeeking *pMediaSeeking = NULL;
IQualityControl *pQualityControl = NULL;
IPersistPropertyBag *ppb = NULL;
IDirectSound3DBuffer *ds3dbuf = NULL;
IReferenceClock *clock = NULL;
IAMDirectSound *pAMDirectSound = NULL;
QI_SUCCEED(pDSRender, IID_IBaseFilter, pBaseFilter);
RELEASE_EXPECT(pBaseFilter, 1);
QI_SUCCEED(pDSRender, IID_IBasicAudio, pBasicAudio);
RELEASE_EXPECT(pBasicAudio, 1);
QI_SUCCEED(pDSRender, IID_IMediaSeeking, pMediaSeeking);
RELEASE_EXPECT(pMediaSeeking, 1);
QI_SUCCEED(pDSRender, IID_IReferenceClock, clock);
RELEASE_EXPECT(clock, 1);
QI_SUCCEED(pDSRender, IID_IAMDirectSound, pAMDirectSound);
RELEASE_EXPECT( pAMDirectSound, 1);
todo_wine {
QI_SUCCEED(pDSRender, IID_IDirectSound3DBuffer, ds3dbuf);
RELEASE_EXPECT(ds3dbuf, 1);
QI_SUCCEED(pDSRender, IID_IPersistPropertyBag, ppb);
if (ppb)
{
IPropertyBag bag = { &PB_Vtbl };
hr = IPersistPropertyBag_Load(ppb, &bag, NULL);
ok(hr == S_OK, "Couldn't load default device: %08x\n", hr);
}
RELEASE_EXPECT(ppb, 1);
QI_SUCCEED(pDSRender, IID_IMediaPosition, pMediaPosition);
RELEASE_EXPECT(pMediaPosition, 1);
QI_SUCCEED(pDSRender, IID_IQualityControl, pQualityControl);
RELEASE_EXPECT(pQualityControl, 1);
}
}
static void test_pin(IPin *pin)
{
IMemInputPin *mpin = NULL;
IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&mpin);
ok(mpin != NULL, "No IMemInputPin found!\n");
if (mpin)
{
ok(IMemInputPin_ReceiveCanBlock(mpin) == S_OK, "Receive can't block for pin!\n");
ok(IMemInputPin_NotifyAllocator(mpin, NULL, 0) == E_POINTER, "NotifyAllocator likes a NULL pointer argument\n");
IMemInputPin_Release(mpin);
}
/* TODO */
}
static void test_basefilter(void)
{
IEnumPins *pin_enum = NULL;
IBaseFilter *base = NULL;
IPin *pins[2];
ULONG ref;
HRESULT hr;
IUnknown_QueryInterface(pDSRender, &IID_IBaseFilter, (void *)&base);
if (base == NULL)
{
/* test_query_interface handles this case */
skip("No IBaseFilter\n");
return;
}
hr = IBaseFilter_EnumPins(base, NULL);
ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr);
hr= IBaseFilter_EnumPins(base, &pin_enum);
ok(hr == S_OK, "hr = %08x and not S_OK\n", hr);
hr = IEnumPins_Next(pin_enum, 1, NULL, NULL);
ok(hr == E_POINTER, "hr = %08x and not E_POINTER\n", hr);
hr = IEnumPins_Next(pin_enum, 2, pins, NULL);
ok(hr == E_INVALIDARG, "hr = %08x and not E_INVALIDARG\n", hr);
pins[0] = (void *)0xdead;
pins[1] = (void *)0xdeed;
hr = IEnumPins_Next(pin_enum, 2, pins, &ref);
ok(hr == S_FALSE, "hr = %08x instead of S_FALSE\n", hr);
ok(pins[0] != (void *)0xdead && pins[0] != NULL, "pins[0] = %p\n", pins[0]);
if (pins[0] != (void *)0xdead && pins[0] != NULL)
{
test_pin(pins[0]);
IPin_Release(pins[0]);
}
ok(pins[1] == (void *)0xdeed, "pins[1] = %p\n", pins[1]);
ref = IEnumPins_Release(pin_enum);
ok(ref == 0, "ref is %u and not 0!\n", ref);
IBaseFilter_Release(base);
}
START_TEST(dsoundrender)
{
CoInitialize(NULL);
if (!create_dsound_renderer())
return;
test_query_interface();
test_basefilter();
release_dsound_renderer();
CoUninitialize();
}

View file

@ -2,6 +2,7 @@
<include base="quartz_winetest">.</include>
<define name="__ROS_LONG64__" />
<file>avisplitter.c</file>
<file>dsoundrender.c</file>
<file>filtergraph.c</file>
<file>filtermapper.c</file>
<file>memallocator.c</file>

View file

@ -54,7 +54,7 @@ static void test_IReferenceClock_methods(const char * clockdesc, IReferenceClock
HRESULT hr;
REFERENCE_TIME time1;
REFERENCE_TIME time2;
signed long diff;
LONG diff;
/* Test response from invalid (NULL) argument */
hr = IReferenceClock_GetTime(pClock, NULL);
@ -86,7 +86,7 @@ static void test_IReferenceClock_methods(const char * clockdesc, IReferenceClock
/* FIXME: How much deviation should be allowed after a sleep? */
/* 0.3% is common, and 0.4% is sometimes observed. */
diff = time2 - time1;
ok (9940000 <= diff && diff <= 10240000, "%s - Expected difference around 10000000, got %lu\n", clockdesc, diff);
ok (9940000 <= diff && diff <= 10240000, "%s - Expected difference around 10000000, got %u\n", clockdesc, diff);
}

View file

@ -55,7 +55,8 @@ static void test_rasenum(void)
/* create the return buffer */
result = pRasEnumDevicesA(NULL, &bufsize, &cDevices);
if(ERROR_RASMAN_CANNOT_INITIALIZE == result) {
if(ERROR_RASMAN_CANNOT_INITIALIZE == result ||
ERROR_STATE_MACHINES_NOT_STARTED == result) {
win_skip("RAS configuration problem\n");
return;
}
@ -67,7 +68,7 @@ static void test_rasenum(void)
ok(result == ERROR_BUFFER_TOO_SMALL,
"Expected ERROR_BUFFER_TOO_SMALL, got %08d\n", result);
rasDevInfo = (LPRASDEVINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
rasDevInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
max(bufsize,sizeof(RASDEVINFOA)));
if(!rasDevInfo) {
win_skip("failed to allocate buffer for RasEnumDevicesA tests\n");

View file

@ -4318,7 +4318,7 @@ const struct exsetsel_s exsetsel_tests[] = {
static void check_EM_EXSETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id) {
CHARRANGE cr;
long result;
LRESULT result;
int start, end;
cr.cpMin = setsel->min;

View file

@ -135,6 +135,7 @@ static int init_base_environment(DWORD dwKeyFlags)
if (!CryptAcquireContext(&hProv, szContainer, szProvider, PROV_RSA_FULL, 0))
{
ok(GetLastError()==NTE_BAD_KEYSET ||
broken(GetLastError() == NTE_TEMPORARY_PROFILE /* some Win7 setups */) ||
broken(GetLastError() == NTE_KEYSET_NOT_DEF /* Win9x/NT4 */),
"%08x\n", GetLastError());
if (GetLastError()!=NTE_BAD_KEYSET)
@ -300,6 +301,84 @@ static BOOL derive_key(ALG_ID aiAlgid, HCRYPTKEY *phKey, DWORD len)
return TRUE;
}
static BYTE abPlainPrivateKey[596] = {
0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
0xf2, 0x5d, 0x58, 0x07
};
static void test_hashes(void)
{
static const unsigned char md2hash[16] = {
@ -317,11 +396,24 @@ static void test_hashes(void)
static const unsigned char sha1hash[20] = {
0xf1, 0x0c, 0xcf, 0xde, 0x60, 0xc1, 0x7d, 0xb2, 0x6e, 0x7d,
0x85, 0xd3, 0x56, 0x65, 0xc7, 0x66, 0x1d, 0xbb, 0xeb, 0x2c };
static const unsigned char signed_ssl3_shamd5_hash[] = {
0x4f,0xcc,0x2f,0x33,0x44,0x60,0x76,0x16,0x13,0xc8,0xff,0xd4,0x59,0x19,
0xde,0x85,0x44,0x72,0x47,0x98,0x01,0xfb,0x67,0x5c,0x5b,0x35,0x15,0x0f,
0x91,0xda,0xc7,0x7c,0xfb,0xe2,0x18,0xef,0xac,0x31,0x40,0x7b,0xa9,0x83,
0xdb,0x30,0xcd,0x94,0x4b,0x8e,0x3b,0x6c,0x7a,0x86,0x59,0xf0,0xd1,0xd2,
0x5e,0xce,0xd4,0x1b,0x7f,0xed,0x24,0xee,0x53,0x5c,0x15,0x97,0x21,0x7c,
0x5c,0xea,0xab,0xf5,0xd6,0x4b,0xb3,0xbb,0x14,0xf5,0x59,0x9e,0x21,0x90,
0x21,0x99,0x19,0xad,0xa2,0xa6,0xea,0x61,0xc1,0x41,0xe2,0x70,0x77,0xf7,
0x15,0x68,0x96,0x1e,0x5c,0x84,0x97,0xe3,0x5c,0xd2,0xd9,0xfb,0x87,0x6f,
0x11,0x21,0x82,0x43,0x76,0x32,0xa4,0x38,0x7b,0x85,0x22,0x30,0x1e,0x55,
0x79,0x93 };
unsigned char pbData[2048];
BOOL result;
HCRYPTHASH hHash, hHashClone;
HCRYPTPROV prov;
BYTE pbHashValue[36];
BYTE pbSigValue[128];
HCRYPTKEY hKeyExchangeKey;
DWORD hashlen, len, error;
int i;
@ -521,6 +613,59 @@ static void test_hashes(void)
result = CryptReleaseContext(prov, 0);
ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
/* Test CALG_SSL3_SHAMD5 */
result = CryptAcquireContextA(&prov, NULL, szProvider, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
ok(result, "CryptAcquireContext failed 0x%08x\n", GetLastError());
/* Step 1: create an MD5 hash of the data */
result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
ok(result, "%08x\n", GetLastError());
len = 16;
result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &len, 0);
ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
result = CryptDestroyHash(hHash);
ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
/* Step 2: create a SHA1 hash of the data */
result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
ok(result, "%08x\n", GetLastError());
len = 20;
result = CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue + 16, &len, 0);
ok(result, "CryptGetHashParam failed 0x%08x\n", GetLastError());
result = CryptDestroyHash(hHash);
ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
/* Step 3: create a CALG_SSL3_SHAMD5 hash handle */
result = CryptCreateHash(hProv, CALG_SSL3_SHAMD5, 0, 0, &hHash);
ok(result, "CryptCreateHash failed 0x%08x\n", GetLastError());
/* Test that CryptHashData fails on this hash */
result = CryptHashData(hHash, pbData, sizeof(pbData), 0);
ok(!result && GetLastError() == NTE_BAD_ALGID, "%08x\n", GetLastError());
result = CryptSetHashParam(hHash, HP_HASHVAL, pbHashValue, 0);
ok(result, "%08x\n", GetLastError());
len = (DWORD)sizeof(abPlainPrivateKey);
result = CryptImportKey(hProv, abPlainPrivateKey, len, 0, 0, &hKeyExchangeKey);
ok(result, "%08x\n", GetLastError());
len = 0;
result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &len);
ok(result, "%08x\n", GetLastError());
ok(len == 128, "expected len 128, got %d\n", len);
result = CryptSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSigValue, &len);
ok(result, "%08x\n", GetLastError());
ok(!memcmp(pbSigValue, signed_ssl3_shamd5_hash, len), "unexpected value\n");
if (len != 128 || memcmp(pbSigValue, signed_ssl3_shamd5_hash, len))
{
printBytes("expected", signed_ssl3_shamd5_hash,
sizeof(signed_ssl3_shamd5_hash));
printBytes("got", pbSigValue, len);
}
result = CryptDestroyHash(hHash);
ok(result, "CryptDestroyHash failed 0x%08x\n", GetLastError());
result = CryptReleaseContext(prov, 0);
ok(result, "CryptReleaseContext failed 0x%08x\n", GetLastError());
}
static void test_block_cipher_modes(void)
@ -1337,84 +1482,6 @@ static void test_mac(void) {
ok(result, "%08x\n", GetLastError());
}
static BYTE abPlainPrivateKey[596] = {
0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x9b, 0x64, 0xef, 0xce,
0x31, 0x7c, 0xad, 0x56, 0xe2, 0x1e, 0x9b, 0x96,
0xb3, 0xf0, 0x29, 0x88, 0x6e, 0xa8, 0xc2, 0x11,
0x33, 0xd6, 0xcc, 0x8c, 0x69, 0xb2, 0x1a, 0xfd,
0xfc, 0x23, 0x21, 0x30, 0x4d, 0x29, 0x45, 0xb6,
0x3a, 0x67, 0x11, 0x80, 0x1a, 0x91, 0xf2, 0x9f,
0x01, 0xac, 0xc0, 0x11, 0x50, 0x5f, 0xcd, 0xb9,
0xad, 0x76, 0x9f, 0x6e, 0x91, 0x55, 0x71, 0xda,
0x97, 0x96, 0x96, 0x22, 0x75, 0xb4, 0x83, 0x44,
0x89, 0x9e, 0xf8, 0x44, 0x40, 0x7c, 0xd6, 0xcd,
0x9d, 0x88, 0xd6, 0x88, 0xbc, 0x56, 0xb7, 0x64,
0xe9, 0x2c, 0x24, 0x2f, 0x0d, 0x78, 0x55, 0x1c,
0xb2, 0x67, 0xb1, 0x5e, 0xbc, 0x0c, 0xcf, 0x1c,
0xe9, 0xd3, 0x9e, 0xa2, 0x15, 0x24, 0x73, 0xd6,
0xdb, 0x6f, 0x83, 0xb2, 0xf8, 0xbc, 0xe7, 0x47,
0x3b, 0x01, 0xef, 0x49, 0x08, 0x98, 0xd6, 0xa3,
0xf9, 0x25, 0x57, 0xe9, 0x39, 0x3c, 0x53, 0x30,
0x1b, 0xf2, 0xc9, 0x62, 0x31, 0x43, 0x5d, 0x84,
0x24, 0x30, 0x21, 0x9a, 0xad, 0xdb, 0x62, 0x91,
0xc8, 0x07, 0xd9, 0x2f, 0xd6, 0xb5, 0x37, 0x6f,
0xfe, 0x7a, 0x12, 0xbc, 0xd9, 0xd2, 0x2b, 0xbf,
0xd7, 0xb1, 0xfa, 0x7d, 0xc0, 0x48, 0xdd, 0x74,
0xdd, 0x55, 0x04, 0xa1, 0x8b, 0xc1, 0x0a, 0xc4,
0xa5, 0x57, 0x62, 0xee, 0x08, 0x8b, 0xf9, 0x19,
0x6c, 0x52, 0x06, 0xf8, 0x73, 0x0f, 0x24, 0xc9,
0x71, 0x9f, 0xc5, 0x45, 0x17, 0x3e, 0xae, 0x06,
0x81, 0xa2, 0x96, 0x40, 0x06, 0xbf, 0xeb, 0x9e,
0x80, 0x2b, 0x27, 0x20, 0x8f, 0x38, 0xcf, 0xeb,
0xff, 0x3b, 0x38, 0x41, 0x35, 0x69, 0x66, 0x13,
0x1d, 0x3c, 0x01, 0x3b, 0xf6, 0x37, 0xca, 0x9c,
0x61, 0x74, 0x98, 0xcf, 0xc9, 0x6e, 0xe8, 0x90,
0xc7, 0xb7, 0x33, 0xc0, 0x07, 0x3c, 0xf8, 0xc8,
0xf6, 0xf2, 0xd7, 0xf0, 0x21, 0x62, 0x58, 0x8a,
0x55, 0xbf, 0xa1, 0x2d, 0x3d, 0xa6, 0x69, 0xc5,
0x02, 0x19, 0x31, 0xf0, 0x94, 0x0f, 0x45, 0x5c,
0x95, 0x1b, 0x53, 0xbc, 0xf5, 0xb0, 0x1a, 0x8f,
0xbf, 0x40, 0xe0, 0xc7, 0x73, 0xe7, 0x72, 0x6e,
0xeb, 0xb1, 0x0f, 0x38, 0xc5, 0xf8, 0xee, 0x04,
0xed, 0x34, 0x1a, 0x10, 0xf9, 0x53, 0x34, 0xf3,
0x3e, 0xe6, 0x5c, 0xd1, 0x47, 0x65, 0xcd, 0xbd,
0xf1, 0x06, 0xcb, 0xb4, 0xb1, 0x26, 0x39, 0x9f,
0x71, 0xfe, 0x3d, 0xf8, 0x62, 0xab, 0x22, 0x8b,
0x0e, 0xdc, 0xb9, 0xe8, 0x74, 0x06, 0xfc, 0x8c,
0x25, 0xa1, 0xa9, 0xcf, 0x07, 0xf9, 0xac, 0x21,
0x01, 0x7b, 0x1c, 0xdc, 0x94, 0xbd, 0x47, 0xe1,
0xa0, 0x86, 0x59, 0x35, 0x6a, 0x6f, 0xb9, 0x70,
0x26, 0x7c, 0x3c, 0xfd, 0xbd, 0x81, 0x39, 0x36,
0x42, 0xc2, 0xbd, 0xbe, 0x84, 0x27, 0x9a, 0x69,
0x81, 0xda, 0x99, 0x27, 0xc2, 0x4f, 0x62, 0x33,
0xf4, 0x79, 0x30, 0xc5, 0x63, 0x54, 0x71, 0xf1,
0x47, 0x22, 0x25, 0x9b, 0x6c, 0x00, 0x2f, 0x1c,
0xf4, 0x1f, 0x85, 0xbc, 0xf6, 0x67, 0x6a, 0xe3,
0xf6, 0x55, 0x8a, 0xef, 0xd0, 0x0b, 0xd3, 0xa2,
0xc5, 0x51, 0x70, 0x15, 0x0a, 0xf0, 0x98, 0x4c,
0xb7, 0x19, 0x62, 0x0e, 0x2d, 0x2a, 0x4a, 0x7d,
0x7a, 0x0a, 0xc4, 0x17, 0xe3, 0x5d, 0x20, 0x52,
0xa9, 0x98, 0xc3, 0xaa, 0x11, 0xf6, 0xbf, 0x4c,
0x94, 0x99, 0x81, 0x89, 0xf0, 0x7f, 0x66, 0xaa,
0xc8, 0x88, 0xd7, 0x31, 0x84, 0x71, 0xb6, 0x64,
0x09, 0x76, 0x0b, 0x7f, 0x1a, 0x1f, 0x2e, 0xfe,
0xcd, 0x59, 0x2a, 0x54, 0x11, 0x84, 0xd4, 0x6a,
0x61, 0xdf, 0xaa, 0x76, 0x66, 0x9d, 0x82, 0x11,
0x56, 0x3d, 0xd2, 0x52, 0xe6, 0x42, 0x5a, 0x77,
0x92, 0x98, 0x34, 0xf3, 0x56, 0x6c, 0x96, 0x10,
0x40, 0x59, 0x16, 0xcb, 0x77, 0x61, 0xe3, 0xbf,
0x4b, 0xd4, 0x39, 0xfb, 0xb1, 0x4e, 0xc1, 0x74,
0xec, 0x7a, 0xea, 0x3d, 0x68, 0xbb, 0x0b, 0xe6,
0xc6, 0x06, 0xbf, 0xdd, 0x7f, 0x94, 0x42, 0xc0,
0x0f, 0xe4, 0x92, 0x33, 0x6c, 0x6e, 0x1b, 0xba,
0x73, 0xf9, 0x79, 0x84, 0xdf, 0x45, 0x00, 0xe4,
0x94, 0x88, 0x9d, 0x08, 0x89, 0xcf, 0xf2, 0xa4,
0xc5, 0x47, 0x45, 0x85, 0x86, 0xa5, 0xcc, 0xa8,
0xf2, 0x5d, 0x58, 0x07
};
static void test_import_private(void)
{
DWORD dwLen, dwVal;
@ -1803,8 +1870,8 @@ static void test_rsa_encrypt(void)
/* An RSA key doesn't support salt */
result = CryptGetKeyParam(hRSAKey, KP_SALT, NULL, &dwLen, 0);
ok(!result && GetLastError() == NTE_BAD_KEY,
"expected NTE_BAD_KEY, got %08x\n", GetLastError());
ok(!result && (GetLastError() == NTE_BAD_KEY || GetLastError() == NTE_NOT_FOUND /* Win7 */),
"expected NTE_BAD_KEY or NTE_NOT_FOUND, got %08x\n", GetLastError());
/* The key exchange key's public key may be exported.. */
result = CryptExportKey(hRSAKey, 0, PUBLICKEYBLOB, 0, NULL, &dwLen);