From b7e05a7f587fd68c301111c9155c44d43365e137 Mon Sep 17 00:00:00 2001 From: "Carl J. Bialorucki" Date: Thu, 8 Jan 2026 17:11:49 -0600 Subject: [PATCH] [ADVAPI32_WINETEST] Sync to advapi32 winetest to wine-10.0 - [ADVAPI32_WINETEST] Sync to wine-10.0 - [ADVAPI32_WINETEST] Remove obsolete ReactOS hacks - [ADVAPI32_WINETEST] Add new hacks for Windows Server 2003+ and ReactOS --- .../winetests/advapi32/CMakeLists.txt | 12 +- modules/rostests/winetests/advapi32/cred.c | 160 +- modules/rostests/winetests/advapi32/crypt.c | 848 ++- .../winetests/advapi32/crypt_lmhash.c | 8 +- .../rostests/winetests/advapi32/eventlog.c | 812 ++- modules/rostests/winetests/advapi32/lsa.c | 279 +- modules/rostests/winetests/advapi32/perf.c | 305 + .../rostests/winetests/advapi32/registry.c | 4099 ++++++++---- .../rostests/winetests/advapi32/security.c | 5851 +++++++++-------- modules/rostests/winetests/advapi32/service.c | 1410 ++-- 10 files changed, 8633 insertions(+), 5151 deletions(-) create mode 100644 modules/rostests/winetests/advapi32/perf.c diff --git a/modules/rostests/winetests/advapi32/CMakeLists.txt b/modules/rostests/winetests/advapi32/CMakeLists.txt index bae7f85501a..22535badf2d 100644 --- a/modules/rostests/winetests/advapi32/CMakeLists.txt +++ b/modules/rostests/winetests/advapi32/CMakeLists.txt @@ -1,4 +1,6 @@ +remove_definitions(-DWINVER=0x502 -D_WIN32_WINNT=0x502) +add_definitions(-DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00 -DNTDDI_VERSION=0x0A000000) include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/wine) list(APPEND SOURCE @@ -10,6 +12,7 @@ list(APPEND SOURCE crypt_sha.c eventlog.c lsa.c + perf.c registry.c security.c service.c) @@ -22,10 +25,17 @@ add_executable(advapi32_winetest ${PCH_SKIP_SOURCE}) if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_compile_options(advapi32_winetest PRIVATE "-Wno-format") + target_compile_options(advapi32_winetest PRIVATE + -Wno-format + -Wno-unused-function + -Wno-old-style-declaration) endif() set_module_type(advapi32_winetest win32cui) add_importlibs(advapi32_winetest advapi32 ole32 user32 msvcrt kernel32 ntdll) add_pch(advapi32_winetest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET advapi32_winetest) +target_compile_definitions(advapi32_winetest PRIVATE + strcmpi=_strcmpi + wcsnicmp=_wcsnicmp + wcsicmp=_wcsicmp) diff --git a/modules/rostests/winetests/advapi32/cred.c b/modules/rostests/winetests/advapi32/cred.c index bb5fb4eace8..24815967ac8 100644 --- a/modules/rostests/winetests/advapi32/cred.c +++ b/modules/rostests/winetests/advapi32/cred.c @@ -51,19 +51,19 @@ static void test_CredReadA(void) SetLastError(0xdeadbeef); ret = pCredReadA(TEST_TARGET_NAME, -1, 0, &cred); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "CredReadA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "CredReadA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCredReadA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0xdeadbeef, &cred); ok(!ret && ( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER ), - "CredReadA should have failed with ERROR_INVALID_FLAGS or ERROR_INVALID_PARAMETER instead of %d\n", + "CredReadA should have failed with ERROR_INVALID_FLAGS or ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCredReadA(NULL, CRED_TYPE_GENERIC, 0, &cred); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "CredReadA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "CredReadA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); } @@ -75,7 +75,7 @@ static void test_CredWriteA(void) SetLastError(0xdeadbeef); ret = pCredWriteA(NULL, 0); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "CredWriteA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "CredWriteA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); new_cred.Flags = 0; @@ -93,7 +93,7 @@ static void test_CredWriteA(void) SetLastError(0xdeadbeef); ret = pCredWriteA(&new_cred, 0); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "CredWriteA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "CredWriteA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); new_cred.TargetName = (char *)TEST_TARGET_NAME; @@ -105,63 +105,63 @@ static void test_CredWriteA(void) { ok(GetLastError() == ERROR_SUCCESS || GetLastError() == ERROR_IO_PENDING, /* Vista */ - "Expected ERROR_IO_PENDING, got %d\n", GetLastError()); + "Expected ERROR_IO_PENDING, got %ld\n", GetLastError()); } else { ok(GetLastError() == ERROR_BAD_USERNAME || GetLastError() == ERROR_NO_SUCH_LOGON_SESSION, /* Vista */ "CredWrite with username without domain should return ERROR_BAD_USERNAME" - "or ERROR_NO_SUCH_LOGON_SESSION not %d\n", GetLastError()); + "or ERROR_NO_SUCH_LOGON_SESSION not %ld\n", GetLastError()); } new_cred.UserName = NULL; SetLastError(0xdeadbeef); ret = pCredWriteA(&new_cred, 0); ok(!ret && GetLastError() == ERROR_BAD_USERNAME, - "CredWriteA with NULL username should have failed with ERROR_BAD_USERNAME instead of %d\n", + "CredWriteA with NULL username should have failed with ERROR_BAD_USERNAME instead of %ld\n", GetLastError()); new_cred.UserName = (char *)"winetest"; new_cred.Persist = CRED_PERSIST_LOCAL_MACHINE; SetLastError(0xdeadbeef); ret = pCredWriteA(&new_cred, 0); - ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError()); + ok(ret || broken(!ret), "CredWriteA failed with error %lu\n", GetLastError()); if (ret) { ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_DOMAIN_PASSWORD, 0); - ok(ret, "CredDeleteA failed with error %u\n", GetLastError()); + ok(ret, "CredDeleteA failed with error %lu\n", GetLastError()); } new_cred.Type = CRED_TYPE_GENERIC; SetLastError(0xdeadbeef); ret = pCredWriteA(&new_cred, 0); - ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError()); + ok(ret || broken(!ret), "CredWriteA failed with error %lu\n", GetLastError()); if (ret) { ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0); - ok(ret, "CredDeleteA failed with error %u\n", GetLastError()); + ok(ret, "CredDeleteA failed with error %lu\n", GetLastError()); } new_cred.Persist = CRED_PERSIST_SESSION; ret = pCredWriteA(&new_cred, 0); - ok(ret, "CredWriteA failed with error %u\n", GetLastError()); + ok(ret, "CredWriteA failed with error %lu\n", GetLastError()); ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0); - ok(ret, "CredDeleteA failed with error %u\n", GetLastError()); + ok(ret, "CredDeleteA failed with error %lu\n", GetLastError()); new_cred.Type = CRED_TYPE_DOMAIN_PASSWORD; SetLastError(0xdeadbeef); ret = pCredWriteA(&new_cred, 0); - ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError()); + ok(ret || broken(!ret), "CredWriteA failed with error %lu\n", GetLastError()); if (ret) { ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_DOMAIN_PASSWORD, 0); - ok(ret, "CredDeleteA failed with error %u\n", GetLastError()); + ok(ret, "CredDeleteA failed with error %lu\n", GetLastError()); } new_cred.UserName = NULL; SetLastError(0xdeadbeef); ret = pCredWriteA(&new_cred, 0); ok(!ret, "CredWriteA succeeded\n"); - ok(GetLastError() == ERROR_BAD_USERNAME, "got %u\n", GetLastError()); + ok(GetLastError() == ERROR_BAD_USERNAME, "got %lu\n", GetLastError()); } static void test_CredDeleteA(void) @@ -171,13 +171,13 @@ static void test_CredDeleteA(void) SetLastError(0xdeadbeef); ret = pCredDeleteA(TEST_TARGET_NAME, -1, 0); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "CredDeleteA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "CredDeleteA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0xdeadbeef); ok(!ret && ( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER /* Vista */ ), - "CredDeleteA should have failed with ERROR_INVALID_FLAGS or ERROR_INVALID_PARAMETER instead of %d\n", + "CredDeleteA should have failed with ERROR_INVALID_FLAGS or ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); } @@ -208,7 +208,7 @@ if(0) SetLastError(0xdeadbeef); ret = pCredReadDomainCredentialsA(NULL, 0, &count, &creds); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "CredReadDomainCredentialsA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "CredReadDomainCredentialsA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); @@ -216,7 +216,7 @@ if(0) count = 2; ret = pCredReadDomainCredentialsA(&info, 0, &count, &creds); ok(!ret && GetLastError() == ERROR_NOT_FOUND, - "CredReadDomainCredentialsA should have failed with ERROR_NOT_FOUND instead of %d\n", + "CredReadDomainCredentialsA should have failed with ERROR_NOT_FOUND instead of %ld\n", GetLastError()); ok(count ==0 && creds == NULL, "CredReadDomainCredentialsA must not return any result\n"); @@ -227,7 +227,7 @@ if(0) ok(!ret, "CredReadDomainCredentialsA should have failed\n"); ok(GetLastError() == ERROR_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER, /* Vista, W2K8 */ - "Expected ERROR_NOT_FOUND or ERROR_INVALID_PARAMETER instead of %d\n", + "Expected ERROR_NOT_FOUND or ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); info.DnsServerName = NULL; @@ -237,7 +237,7 @@ if(0) ok(!ret, "CredReadDomainCredentialsA should have failed\n"); ok(GetLastError() == ERROR_NOT_FOUND || GetLastError() == ERROR_INVALID_PARAMETER, /* Vista, W2K8 */ - "Expected ERROR_NOT_FOUND or ERROR_INVALID_PARAMETER instead of %d\n", + "Expected ERROR_NOT_FOUND or ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); } @@ -245,15 +245,15 @@ static void check_blob(int line, DWORD cred_type, PCREDENTIALA cred) { if (cred_type == CRED_TYPE_DOMAIN_PASSWORD) { - todo_ros - ok_(__FILE__, line)(cred->CredentialBlobSize == 0, "expected CredentialBlobSize of 0 but got %d\n", cred->CredentialBlobSize); - todo_ros + todo_wine + ok_(__FILE__, line)(cred->CredentialBlobSize == 0, "expected CredentialBlobSize of 0 but got %ld\n", cred->CredentialBlobSize); + todo_wine ok_(__FILE__, line)(!cred->CredentialBlob, "expected NULL credentials but got %p\n", cred->CredentialBlob); } else { DWORD size=sizeof(TEST_PASSWORD); - ok_(__FILE__, line)(cred->CredentialBlobSize == size, "expected CredentialBlobSize of %u but got %u\n", size, cred->CredentialBlobSize); + ok_(__FILE__, line)(cred->CredentialBlobSize == size, "expected CredentialBlobSize of %lu but got %lu\n", size, cred->CredentialBlobSize); ok_(__FILE__, line)(cred->CredentialBlob != NULL, "CredentialBlob should be present\n"); if (cred->CredentialBlob) ok_(__FILE__, line)(!memcmp(cred->CredentialBlob, TEST_PASSWORD, size), "wrong CredentialBlob\n"); @@ -283,7 +283,7 @@ static void test_generic(void) ret = pCredWriteA(&new_cred, 0); ok(ret || broken(GetLastError() == ERROR_NO_SUCH_LOGON_SESSION), - "CredWriteA failed with error %d\n", GetLastError()); + "CredWriteA failed with error %ld\n", GetLastError()); if (!ret) { skip("couldn't write generic credentials, skipping tests\n"); @@ -291,7 +291,7 @@ static void test_generic(void) } ret = pCredEnumerateA(NULL, 0, &count, &creds); - ok(ret, "CredEnumerateA failed with error %d\n", GetLastError()); + ok(ret, "CredEnumerateA failed with error %ld\n", GetLastError()); for (i = 0; i < count; i++) { @@ -299,12 +299,12 @@ static void test_generic(void) { ok(creds[i]->Type == CRED_TYPE_GENERIC || creds[i]->Type == CRED_TYPE_DOMAIN_PASSWORD, /* Vista */ - "expected creds[%d]->Type CRED_TYPE_GENERIC or CRED_TYPE_DOMAIN_PASSWORD but got %d\n", i, creds[i]->Type); - ok(!creds[i]->Flags, "expected creds[%d]->Flags 0 but got 0x%x\n", i, creds[i]->Flags); - ok(!strcmp(creds[i]->Comment, "Comment"), "expected creds[%d]->Comment \"Comment\" but got \"%s\"\n", i, creds[i]->Comment); + "expected creds[%ld]->Type CRED_TYPE_GENERIC or CRED_TYPE_DOMAIN_PASSWORD but got %ld\n", i, creds[i]->Type); + ok(!creds[i]->Flags, "expected creds[%ld]->Flags 0 but got 0x%lx\n", i, creds[i]->Flags); + ok(!strcmp(creds[i]->Comment, "Comment"), "expected creds[%ld]->Comment \"Comment\" but got \"%s\"\n", i, creds[i]->Comment); check_blob(__LINE__, creds[i]->Type, creds[i]); - ok(creds[i]->Persist, "expected creds[%d]->Persist CRED_PERSIST_ENTERPRISE but got %d\n", i, creds[i]->Persist); - ok(!strcmp(creds[i]->UserName, "winetest"), "expected creds[%d]->UserName \"winetest\" but got \"%s\"\n", i, creds[i]->UserName); + ok(creds[i]->Persist, "expected creds[%ld]->Persist CRED_PERSIST_ENTERPRISE but got %ld\n", i, creds[i]->Persist); + ok(!strcmp(creds[i]->UserName, "winetest"), "expected creds[%ld]->UserName \"winetest\" but got \"%s\"\n", i, creds[i]->UserName); found = TRUE; } } @@ -312,11 +312,11 @@ static void test_generic(void) ok(found, "credentials not found\n"); ret = pCredReadA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0, &cred); - ok(ret, "CredReadA failed with error %d\n", GetLastError()); + ok(ret, "CredReadA failed with error %ld\n", GetLastError()); pCredFree(cred); ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0); - ok(ret, "CredDeleteA failed with error %d\n", GetLastError()); + ok(ret, "CredDeleteA failed with error %ld\n", GetLastError()); } static void test_domain_password(DWORD cred_type) @@ -346,21 +346,21 @@ static void test_domain_password(DWORD cred_type) "or are disabled. Skipping\n"); return; } - ok(ret, "CredWriteA failed with error %d\n", GetLastError()); + ok(ret, "CredWriteA failed with error %ld\n", GetLastError()); ret = pCredEnumerateA(NULL, 0, &count, &creds); - ok(ret, "CredEnumerateA failed with error %d\n", GetLastError()); + ok(ret, "CredEnumerateA failed with error %ld\n", GetLastError()); for (i = 0; i < count; i++) { if (creds[i]->TargetName && !strcmp(creds[i]->TargetName, TEST_TARGET_NAME)) { - ok(creds[i]->Type == cred_type, "expected creds[%d]->Type CRED_TYPE_DOMAIN_PASSWORD but got %d\n", i, creds[i]->Type); - ok(!creds[i]->Flags, "expected creds[%d]->Flags 0 but got 0x%x\n", i, creds[i]->Flags); - ok(!strcmp(creds[i]->Comment, "Comment"), "expected creds[%d]->Comment \"Comment\" but got \"%s\"\n", i, creds[i]->Comment); + ok(creds[i]->Type == cred_type, "expected creds[%ld]->Type CRED_TYPE_DOMAIN_PASSWORD but got %ld\n", i, creds[i]->Type); + ok(!creds[i]->Flags, "expected creds[%ld]->Flags 0 but got 0x%lx\n", i, creds[i]->Flags); + ok(!strcmp(creds[i]->Comment, "Comment"), "expected creds[%ld]->Comment \"Comment\" but got \"%s\"\n", i, creds[i]->Comment); check_blob(__LINE__, cred_type, creds[i]); - ok(creds[i]->Persist, "expected creds[%d]->Persist CRED_PERSIST_ENTERPRISE but got %d\n", i, creds[i]->Persist); - ok(!strcmp(creds[i]->UserName, "test\\winetest"), "expected creds[%d]->UserName \"winetest\" but got \"%s\"\n", i, creds[i]->UserName); + ok(creds[i]->Persist, "expected creds[%ld]->Persist CRED_PERSIST_ENTERPRISE but got %ld\n", i, creds[i]->Persist); + ok(!strcmp(creds[i]->UserName, "test\\winetest"), "expected creds[%ld]->UserName \"winetest\" but got \"%s\"\n", i, creds[i]->UserName); found = TRUE; } } @@ -368,7 +368,7 @@ static void test_domain_password(DWORD cred_type) ok(found, "credentials not found\n"); ret = pCredReadA(TEST_TARGET_NAME, cred_type, 0, &cred); - ok(ret, "CredReadA failed with error %d\n", GetLastError()); + ok(ret, "CredReadA failed with error %ld\n", GetLastError()); if (ret) /* don't check the values of cred, if CredReadA failed. */ { check_blob(__LINE__, cred_type, cred); @@ -376,7 +376,7 @@ static void test_domain_password(DWORD cred_type) } ret = pCredDeleteA(TEST_TARGET_NAME, cred_type, 0); - ok(ret, "CredDeleteA failed with error %d\n", GetLastError()); + ok(ret, "CredDeleteA failed with error %ld\n", GetLastError()); } static void test_CredMarshalCredentialA(void) @@ -397,7 +397,7 @@ static void test_CredMarshalCredentialA(void) ret = pCredMarshalCredentialA( 0, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) ); cert.cbSize = sizeof(cert); @@ -405,28 +405,28 @@ static void test_CredMarshalCredentialA(void) ret = pCredMarshalCredentialA( 0, &cert, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); str = (char *)0xdeadbeef; SetLastError( 0xdeadbeef ); ret = pCredMarshalCredentialA( 0, &cert, &str ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); ok( str == (char *)0xdeadbeef, "got %p\n", str ); SetLastError( 0xdeadbeef ); ret = pCredMarshalCredentialA( CertCredential, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); if (0) { /* crash */ SetLastError( 0xdeadbeef ); ret = pCredMarshalCredentialA( CertCredential, &cert, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); } cert.cbSize = 0; @@ -435,13 +435,13 @@ static void test_CredMarshalCredentialA(void) ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); ok( str == (char *)0xdeadbeef, "got %p\n", str ); cert.cbSize = sizeof(cert) + 4; str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str ); pCredFree( str ); @@ -450,7 +450,7 @@ static void test_CredMarshalCredentialA(void) cert.rgbHashOfCert[0] = 2; str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@BCAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str ); pCredFree( str ); @@ -458,7 +458,7 @@ static void test_CredMarshalCredentialA(void) cert.rgbHashOfCert[0] = 255; str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@B-DAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str ); pCredFree( str ); @@ -467,7 +467,7 @@ static void test_CredMarshalCredentialA(void) cert.rgbHashOfCert[1] = 1; str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@BBEAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str ); pCredFree( str ); @@ -477,7 +477,7 @@ static void test_CredMarshalCredentialA(void) cert.rgbHashOfCert[2] = 1; str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@BBEQAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str ); pCredFree( str ); @@ -489,7 +489,7 @@ static void test_CredMarshalCredentialA(void) cert.rgbHashOfCert[3] = 'e'; str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str ); pCredFree( str ); @@ -497,7 +497,7 @@ static void test_CredMarshalCredentialA(void) memset( cert.rgbHashOfCert, 0xff, sizeof(cert.rgbHashOfCert) ); str = NULL; ret = pCredMarshalCredentialA( CertCredential, &cert, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@B--------------------------P" ), "got %s\n", str ); pCredFree( str ); @@ -508,7 +508,7 @@ static void test_CredMarshalCredentialA(void) ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); ok( str == (char *)0xdeadbeef, "got %p\n", str ); username.UserName = emptyW; @@ -517,13 +517,13 @@ static void test_CredMarshalCredentialA(void) ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); ok( str == (char *)0xdeadbeef, "got %p\n", str ); username.UserName = tW; str = NULL; ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@CCAAAAA0BA" ), "got %s\n", str ); pCredFree( str ); @@ -531,7 +531,7 @@ static void test_CredMarshalCredentialA(void) username.UserName = teW; str = NULL; ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@CEAAAAA0BQZAA" ), "got %s\n", str ); pCredFree( str ); @@ -539,7 +539,7 @@ static void test_CredMarshalCredentialA(void) username.UserName = tesW; str = NULL; ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@CGAAAAA0BQZAMHA" ), "got %s\n", str ); pCredFree( str ); @@ -547,7 +547,7 @@ static void test_CredMarshalCredentialA(void) username.UserName = testW; str = NULL; ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@CIAAAAA0BQZAMHA0BA" ), "got %s\n", str ); pCredFree( str ); @@ -555,7 +555,7 @@ static void test_CredMarshalCredentialA(void) username.UserName = test1W; str = NULL; ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str ); - ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( ret, "unexpected failure %lu\n", GetLastError() ); ok( str != NULL, "str not set\n" ); ok( !lstrcmpA( str, "@@CKAAAAA0BQZAMHA0BQMAA" ), "got %s\n", str ); pCredFree( str ); @@ -627,14 +627,14 @@ static void test_CredUnmarshalCredentialA(void) ret = pCredUnmarshalCredentialA( NULL, NULL, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); cert = NULL; SetLastError( 0xdeadbeef ); ret = pCredUnmarshalCredentialA( NULL, NULL, (void **)&cert ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); type = 0; cert = NULL; @@ -642,23 +642,23 @@ static void test_CredUnmarshalCredentialA(void) ret = pCredUnmarshalCredentialA( NULL, &type, (void **)&cert ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); if (0) { /* crash */ SetLastError( 0xdeadbeef ); ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, NULL ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); SetLastError( 0xdeadbeef ); ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", NULL, (void **)&cert ); error = GetLastError(); ok( !ret, "unexpected success\n" ); - ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + ok( error == ERROR_INVALID_PARAMETER, "got %lu\n", error ); } - for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) + for (i = 0; i < ARRAY_SIZE(tests); i++) { SetLastError(0xdeadbeef); type = 0; @@ -667,7 +667,7 @@ static void test_CredUnmarshalCredentialA(void) error = GetLastError(); if (tests[i].unmarshaled) { - ok(ret, "[%u] unexpected failure %u\n", i, error); + ok(ret, "[%u] unexpected failure %lu\n", i, error); ok(type == tests[i].type, "[%u] got %u\n", i, type); ok(p != NULL, "[%u] returned pointer is NULL\n", i); if (tests[i].type == CertCredential) @@ -675,7 +675,7 @@ static void test_CredUnmarshalCredentialA(void) cert = p; hash = tests[i].unmarshaled; ok(cert->cbSize == sizeof(*cert), - "[%u] wrong size %u\n", i, cert->cbSize); + "[%u] wrong size %lu\n", i, cert->cbSize); for (j = 0; j < sizeof(cert->rgbHashOfCert); j++) ok(cert->rgbHashOfCert[j] == hash[j], "[%u] wrong data\n", i); } @@ -690,7 +690,7 @@ static void test_CredUnmarshalCredentialA(void) else { ok(!ret, "[%u] unexpected success\n", i); - ok(error == ERROR_INVALID_PARAMETER, "[%u] got %u\n", i, error); + ok(error == ERROR_INVALID_PARAMETER, "[%u] got %lu\n", i, error); ok(type == tests[i].type, "[%u] got %u\n", i, type); ok(p == NULL, "[%u] returned pointer is not NULL\n", i); } @@ -752,11 +752,11 @@ static void test_CredIsMarshaledCredentialA(void) SetLastError(0xdeadbeef); res = pCredIsMarshaledCredentialA(ptr[i]); if (expected) - ok(res != FALSE, "%d: got %d and %u for %s (expected TRUE)\n", i, res, GetLastError(), ptr[i]); + ok(res != FALSE, "%d: got %d and %lu for %s (expected TRUE)\n", i, res, GetLastError(), ptr[i]); else { /* Windows returns ERROR_INVALID_PARAMETER here, but that's not documented */ - ok(!res, "%d: got %d and %u for %s (expected FALSE)\n", i, res, GetLastError(), ptr[i]); + ok(!res, "%d: got %d and %lu for %s (expected FALSE)\n", i, res, GetLastError(), ptr[i]); } } } @@ -789,10 +789,10 @@ START_TEST(cred) BOOL ret; DWORD i; ret = pCredGetSessionTypes(CRED_TYPE_MAXIMUM, persists); - ok(ret, "CredGetSessionTypes failed with error %d\n", GetLastError()); - ok(persists[0] == CRED_PERSIST_NONE, "persists[0] = %u instead of CRED_PERSIST_NONE\n", persists[0]); + ok(ret, "CredGetSessionTypes failed with error %ld\n", GetLastError()); + ok(persists[0] == CRED_PERSIST_NONE, "persists[0] = %lu instead of CRED_PERSIST_NONE\n", persists[0]); for (i=0; i < CRED_TYPE_MAXIMUM; i++) - ok(persists[i] <= CRED_PERSIST_ENTERPRISE, "bad value for persists[%u]: %u\n", i, persists[i]); + ok(persists[i] <= CRED_PERSIST_ENTERPRISE, "bad value for persists[%lu]: %lu\n", i, persists[i]); } else memset(persists, CRED_PERSIST_ENTERPRISE, sizeof(persists)); @@ -809,7 +809,7 @@ START_TEST(cred) else test_generic(); - trace("domain password:\n"); + trace("domain password:\n"); if (persists[CRED_TYPE_DOMAIN_PASSWORD] == CRED_PERSIST_NONE) skip("CRED_TYPE_DOMAIN_PASSWORD credentials are not supported or are disabled. Skipping\n"); else diff --git a/modules/rostests/winetests/advapi32/crypt.c b/modules/rostests/winetests/advapi32/crypt.c index 48d08643a13..bca0c1acc6c 100644 --- a/modules/rostests/winetests/advapi32/crypt.c +++ b/modules/rostests/winetests/advapi32/crypt.c @@ -20,8 +20,6 @@ #include -#include "ntstatus.h" -#define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "wincrypt.h" @@ -30,141 +28,156 @@ #include "wine/test.h" -struct ustring { - DWORD Length; - DWORD MaximumLength; - unsigned char *Buffer; -}; - static const char szRsaBaseProv[] = MS_DEF_PROV_A; static const char szNonExistentProv[] = "Wine Nonexistent Cryptographic Provider v11.2"; static const char szKeySet[] = "wine_test_keyset"; static const char szBadKeySet[] = "wine_test_bad_keyset"; #define NON_DEF_PROV_TYPE 999 -static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*,LPCSTR,LPCSTR,DWORD,DWORD); static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*); static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*); static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*); -static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD); static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD); -static BOOL (WINAPI *pCryptCreateHash)(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*); -static BOOL (WINAPI *pCryptDestroyHash)(HCRYPTHASH); static BOOL (WINAPI *pCryptGenRandom)(HCRYPTPROV, DWORD, BYTE*); -static BOOL (WINAPI *pCryptContextAddRef)(HCRYPTPROV, DWORD*, DWORD dwFlags); -static BOOL (WINAPI *pCryptGenKey)(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*); -static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY); -static BOOL (WINAPI *pCryptDecrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*); -static BOOL (WINAPI *pCryptDeriveKey)(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*); static BOOL (WINAPI *pCryptDuplicateHash)(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*); -static BOOL (WINAPI *pCryptDuplicateKey)(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*); -static BOOL (WINAPI *pCryptEncrypt)(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE*, DWORD*, DWORD); -static BOOL (WINAPI *pCryptExportKey)(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, BYTE*, DWORD*); -static BOOL (WINAPI *pCryptGetHashParam)(HCRYPTHASH, DWORD, BYTE*, DWORD*, DWORD); -static BOOL (WINAPI *pCryptGetKeyParam)(HCRYPTKEY, DWORD, BYTE*, DWORD*, DWORD); -static BOOL (WINAPI *pCryptGetProvParam)(HCRYPTPROV, DWORD, BYTE*, DWORD*, DWORD); -static BOOL (WINAPI *pCryptGetUserKey)(HCRYPTPROV, DWORD, HCRYPTKEY*); -static BOOL (WINAPI *pCryptHashData)(HCRYPTHASH, BYTE*, DWORD, DWORD); static BOOL (WINAPI *pCryptHashSessionKey)(HCRYPTHASH, HCRYPTKEY, DWORD); -static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV, BYTE*, DWORD, HCRYPTKEY, DWORD, HCRYPTKEY*); static BOOL (WINAPI *pCryptSignHashW)(HCRYPTHASH, DWORD, LPCWSTR, DWORD, BYTE*, DWORD*); -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 NTSTATUS (WINAPI *pSystemFunction004)(struct ustring*,struct ustring*, struct ustring*); -static NTSTATUS (WINAPI *pSystemFunction005)(struct ustring*,struct ustring*, struct ustring*); static BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG); static void init_function_pointers(void) { HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); - pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA"); pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA"); pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA"); pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA"); - pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext"); pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA"); - pCryptCreateHash = (void*)GetProcAddress(hadvapi32, "CryptCreateHash"); - pCryptDestroyHash = (void*)GetProcAddress(hadvapi32, "CryptDestroyHash"); pCryptGenRandom = (void*)GetProcAddress(hadvapi32, "CryptGenRandom"); - pCryptContextAddRef = (void*)GetProcAddress(hadvapi32, "CryptContextAddRef"); - pCryptGenKey = (void*)GetProcAddress(hadvapi32, "CryptGenKey"); - pCryptDestroyKey = (void*)GetProcAddress(hadvapi32, "CryptDestroyKey"); - pCryptDecrypt = (void*)GetProcAddress(hadvapi32, "CryptDecrypt"); - pCryptDeriveKey = (void*)GetProcAddress(hadvapi32, "CryptDeriveKey"); pCryptDuplicateHash = (void*)GetProcAddress(hadvapi32, "CryptDuplicateHash"); - pCryptDuplicateKey = (void*)GetProcAddress(hadvapi32, "CryptDuplicateKey"); - pCryptEncrypt = (void*)GetProcAddress(hadvapi32, "CryptEncrypt"); - pCryptExportKey = (void*)GetProcAddress(hadvapi32, "CryptExportKey"); - pCryptGetHashParam = (void*)GetProcAddress(hadvapi32, "CryptGetHashParam"); - pCryptGetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptGetKeyParam"); - pCryptGetProvParam = (void*)GetProcAddress(hadvapi32, "CryptGetProvParam"); - pCryptGetUserKey = (void*)GetProcAddress(hadvapi32, "CryptGetUserKey"); - pCryptHashData = (void*)GetProcAddress(hadvapi32, "CryptHashData"); pCryptHashSessionKey = (void*)GetProcAddress(hadvapi32, "CryptHashSessionKey"); - pCryptImportKey = (void*)GetProcAddress(hadvapi32, "CryptImportKey"); pCryptSignHashW = (void*)GetProcAddress(hadvapi32, "CryptSignHashW"); - pCryptSetHashParam = (void*)GetProcAddress(hadvapi32, "CryptSetHashParam"); - pCryptSetKeyParam = (void*)GetProcAddress(hadvapi32, "CryptSetKeyParam"); - pCryptSetProvParam = (void*)GetProcAddress(hadvapi32, "CryptSetProvParam"); pCryptVerifySignatureW = (void*)GetProcAddress(hadvapi32, "CryptVerifySignatureW"); - pSystemFunction004 = (void*)GetProcAddress(hadvapi32, "SystemFunction004"); - pSystemFunction005 = (void*)GetProcAddress(hadvapi32, "SystemFunction005"); pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036"); } static void init_environment(void) { - HCRYPTPROV hProv; - - /* Ensure that container "wine_test_keyset" does exist */ - if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) - { - pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET); - } - pCryptReleaseContext(hProv, 0); + HCRYPTPROV hProv; + BOOL ret; - /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */ - if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0)) - { - pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET); - } - pCryptReleaseContext(hProv, 0); + /* Ensure that container "wine_test_keyset" does exist */ + if (!CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) + { + CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET); + } + ret = CryptReleaseContext(hProv, 0); + ok(ret, "got %lu\n", GetLastError()); - /* Ensure that container "wine_test_bad_keyset" does not exist. */ - if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) - { - pCryptReleaseContext(hProv, 0); - pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET); - } + /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */ + if (!CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0)) + { + CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET); + } + ret = CryptReleaseContext(hProv, 0); + ok(ret, "got %lu\n", GetLastError()); + + /* Ensure that container "wine_test_bad_keyset" does not exist. */ + if (CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) + { + ret = CryptReleaseContext(hProv, 0); + ok(ret, "got %lu\n", GetLastError()); + + CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + } } static void clean_up_environment(void) { - HCRYPTPROV hProv; + HCRYPTPROV hProv; + BOOL ret; - /* Remove container "wine_test_keyset" */ - if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) - { - pCryptReleaseContext(hProv, 0); - pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET); - } + /* Remove container "wine_test_keyset" */ + if (CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) + { + ret = CryptReleaseContext(hProv, 0); + ok(ret, "got %lu\n", GetLastError()); - /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */ - if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0)) - { - pCryptReleaseContext(hProv, 0); - pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET); - } + CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + } - /* Remove container "wine_test_bad_keyset" */ - if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) - { - pCryptReleaseContext(hProv, 0); - pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET); - } + /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */ + if (CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0)) + { + ret = CryptReleaseContext(hProv, 0); + ok(ret, "got %lu\n", GetLastError()); + + CryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + } + + /* Remove container "wine_test_bad_keyset" */ + if (CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0)) + { + ret = CryptReleaseContext(hProv, 0); + ok(ret, "got %lu\n", GetLastError()); + + CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + } +} + +static void test_CryptReleaseContext(void) +{ + BOOL ret; + HCRYPTPROV prov; + + /* TODO: Add cases for ERROR_BUSY, ERROR_INVALID_HANDLE and NTE_BAD_UID */ + + /* NULL provider */ + + SetLastError(0xdeadbeef); + ret = CryptReleaseContext(0, 0); + ok(!ret, "CryptReleaseContext succeeded unexpectedly\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = CryptReleaseContext(0, ~0); + ok(!ret, "CryptReleaseContext succeeded unexpectedly\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); + + /* Additional refcount */ + + ret = CryptAcquireContextA(&prov, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0); + ok(ret, "got %lu\n", GetLastError()); + + ret = CryptContextAddRef(prov, NULL, 0); + ok(ret, "got %lu\n", GetLastError()); + + ret = CryptContextAddRef(0, NULL, 0); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); + ret = CryptContextAddRef(0xdeadbeef, NULL, 0); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); + + ret = CryptReleaseContext(prov, 0); + ok(ret, "got %lu\n", GetLastError()); + + /* Nonzero flags, which allow release nonetheless */ + + SetLastError(0xdeadbeef); + ret = CryptReleaseContext(prov, ~0); + ok(!ret, "CryptReleaseContext succeeded unexpectedly\n"); + ok(GetLastError() == NTE_BAD_FLAGS, "got %lu\n", GetLastError()); + + /* Obsolete provider */ + + SetLastError(0xdeadbeef); + ret = CryptReleaseContext(prov, 0); + ok(!ret, "CryptReleaseContext succeeded unexpectedly\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = CryptReleaseContext(prov, ~0); + ok(!ret, "CryptReleaseContext succeeded unexpectedly\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); } static void test_acquire_context(void) @@ -177,55 +190,64 @@ static void test_acquire_context(void) * The order of the error tests seems to match Windows XP's rsaenh.dll CSP, * but since this is likely to change between CSP versions, we don't check * this. Please don't change the order of tests. */ - result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0); - ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError()); + result = CryptAcquireContextA(&hProv, NULL, NULL, 0, 0); + ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%ld\n", GetLastError()); - result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0); - ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%d\n", GetLastError()); + result = CryptAcquireContextA(&hProv, NULL, NULL, 1000, 0); + ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%ld\n", GetLastError()); - result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0); - ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%d\n", GetLastError()); + result = CryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0); + ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%ld\n", GetLastError()); - result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0); - ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%d\n", GetLastError()); + result = CryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0); + ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%ld\n", GetLastError()); - result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0); - ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%d\n", GetLastError()); + result = CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0); + ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%ld\n", GetLastError()); + +if (0) +{ /* This test fails under Win2k SP4: - result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER + result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER */ SetLastError(0xdeadbeef); - result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0); - ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%d\n", result, GetLastError()); - */ + result = CryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0); + ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%ld\n", result, GetLastError()); +} /* Last not least, try to really acquire a context. */ hProv = 0; SetLastError(0xdeadbeef); - result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0); + result = CryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0); GLE = GetLastError(); ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND || GLE == ERROR_SUCCESS || GLE == ERROR_RING2_STACK_IN_USE || GLE == NTE_FAIL || - GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GLE); + GLE == ERROR_NOT_LOGGED_ON), "%d/%ld\n", result, GLE); - if (hProv) - pCryptReleaseContext(hProv, 0); + if (hProv) + { + result = CryptReleaseContext(hProv, 0); + ok(result, "got %lu\n", GetLastError()); + } /* Try again, witch an empty ("\0") szProvider parameter */ hProv = 0; SetLastError(0xdeadbeef); - result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0); + result = CryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0); GLE = GetLastError(); ok(result && (GLE == ERROR_ENVVAR_NOT_FOUND || GLE == ERROR_SUCCESS || GLE == ERROR_RING2_STACK_IN_USE || GLE == NTE_FAIL || - GLE == ERROR_NOT_LOGGED_ON), "%d/%d\n", result, GetLastError()); + GLE == ERROR_NOT_LOGGED_ON), "%d/%ld\n", result, GetLastError()); - if (hProv) - pCryptReleaseContext(hProv, 0); + if (hProv) + { + result = CryptReleaseContext(hProv, 0); + ok(result, "got %lu\n", GetLastError()); + } } static void test_incorrect_api_usage(void) @@ -247,146 +269,219 @@ static void test_incorrect_api_usage(void) * robust here and returns an ERROR_INVALID_PARAMETER code. */ - result = pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, + result = CryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET); - ok (result, "%08x\n", GetLastError()); + ok (result, "%08lx\n", GetLastError()); if (!result) return; - result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash); - ok (result, "%d\n", GetLastError()); - if (!result) return; - pCryptDestroyHash(hHash); + /* Looks like native handles are just pointers. */ + ok(!!*(void **)hProv, "Got zero *(void **)hProv.\n"); - result = pCryptCreateHash(0, CALG_SHA, 0, 0, &hHash); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - result = pCryptGenKey(0, CALG_RC4, 0, &hKey); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey); - ok (result, "%d\n", GetLastError()); + result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash); + ok (result, "%ld\n", GetLastError()); if (!result) return; - result = pCryptDestroyKey(hKey); - ok (result, "%d\n", GetLastError()); + result = CryptDeriveKey(0, CALG_RC4, hHash, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2); - ok (result, "%d\n", GetLastError()); + result = CryptDeriveKey(hProv, CALG_RC4, 0, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptHashData(0, &temp, 1, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptGenKey(hProv, CALG_RC4, 0, &hKey); + ok (result, "%ld\n", GetLastError()); if (!result) return; - result = pCryptDestroyKey(hKey2); - ok (result, "%d\n", GetLastError()); + result = pCryptHashSessionKey(hHash, 0, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = pCryptHashSessionKey(0, hKey, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptDestroyHash(hHash); + ok (result, "%08lx\n", GetLastError()); + + result = CryptDestroyHash(0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptCreateHash(0xdeadbeef, CALG_SHA, 0, 0, &hHash); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptCreateHash(0, CALG_SHA, 0, 0, &hHash); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptGenKey(0, CALG_RC4, 0, &hKey); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 0; + SetLastError(0xdeadbeef); + result = CryptDecrypt(hKey, 0, FALSE, 0, &temp, &dwLen); + ok (result, "%lx\n", GetLastError()); + dwLen = 0; + SetLastError(0xdeadbeef); + result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == NTE_BAD_LEN, "%lx\n", GetLastError()); + dwLen = 1; + result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen); + ok (result, "%ld\n", GetLastError()); + result = CryptDecrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + result = CryptDecrypt(0, 0, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + result = CryptDecrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (result, "%ld\n", GetLastError()); + result = CryptEncrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + result = CryptEncrypt(0, 0, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + result = CryptEncrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen, sizeof(temp)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = CryptExportKey(hKey, 0xdeadbeef, 0, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptDestroyKey(hKey); + ok (result, "%ld\n", GetLastError()); + + result = CryptGenKey(hProv, CALG_RC4, 0, &hKey2); + ok (result, "%ld\n", GetLastError()); + if (!result) return; + + result = CryptDestroyKey(hKey2); + ok (result, "%ld\n", GetLastError()); + + result = CryptDestroyKey(0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); dwTemp = CRYPT_MODE_ECB; - result = pCryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD)); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - result = pCryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL, + result = CryptSetKeyParam(hKey2, KP_MODE, (BYTE*)&dwTemp, sizeof(DWORD)); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + hProv2 = 0xdeadbeef; + result = CryptAcquireContextA(&hProv2, szBadKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET); - ok (result, "%d\n", GetLastError()); - if (!result) return; - - result = pCryptReleaseContext(hProv, 0); - ok (result, "%d\n", GetLastError()); + ok (result, "%ld\n", GetLastError()); + ok (hProv2 == 0, "%Id\n", hProv2); if (!result) return; - result = pCryptReleaseContext(hProv, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptReleaseContext(hProv, 0); + ok(result, "got %lu\n", GetLastError()); + if (!result) return; + + result = pCryptGenRandom(0, 1, &temp); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); result = pCryptGenRandom(hProv, 1, &temp); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); -#ifdef CRASHES_ON_NT40 - result = pCryptContextAddRef(hProv, NULL, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptContextAddRef(hProv, NULL, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + dwLen = 1; + result = CryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + +#if defined(__REACTOS__) && defined(_M_AMD64) + if (is_reactos()) { + ok(FALSE, "FIXME: The following tests normally completes on ReactOS x64, but not after being fuzzed from other tests in our test suite.\n"); + return; + } #endif - - result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - dwLen = 1; - result = pCryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - dwLen = 1; - result = pCryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - -#ifdef CRASHES_ON_NT40 result = pCryptDuplicateHash(hHash, NULL, 0, &hHash2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptDuplicateKey(hKey, NULL, 0, &hKey2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); -#endif + result = CryptDuplicateKey(hKey, NULL, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); dwLen = 1; - result = pCryptExportKey(hKey, 0, 0, 0, &temp, &dwLen); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptExportKey(hKey, 0, 0, 0, &temp, &dwLen); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptGenKey(hProv, CALG_RC4, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); dwLen = 1; - result = pCryptGetHashParam(hHash, 0, &temp, &dwLen, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptGetHashParam(hHash, 0, &temp, &dwLen, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); dwLen = 1; - result = pCryptGetKeyParam(hKey, 0, &temp, &dwLen, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptGetKeyParam(hKey, 0, &temp, &dwLen, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); dwLen = 1; - result = pCryptGetProvParam(hProv, 0, &temp, &dwLen, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); - - result = pCryptGetUserKey(hProv, 0, &hKey2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptGetProvParam(hProv, 0, &temp, &dwLen, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptHashData(hHash, &temp, 1, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptGetUserKey(0, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptGetUserKey(hProv, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptHashData(hHash, &temp, 1, 0); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); result = pCryptHashSessionKey(hHash, hKey, 0); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptImportKey(hProv, &temp, 1, 0, 0, &hKey2); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptImportKey(hProv, &temp, 1, 0, 0, &hKey2); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); if (pCryptSignHashW) { dwLen = 1; result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen); ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER || - GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError()); + GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%ld\n", GetLastError()); + result = pCryptSignHashW(hHash, 0, NULL, 0, &temp, &dwLen); + ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%ld\n", GetLastError()); } else win_skip("CryptSignHashW is not available\n"); - result = pCryptSetKeyParam(hKey, 0, &temp, 1); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptSetKeyParam(hKey, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptSetHashParam(hHash, 0, &temp, 1); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptSetHashParam(hHash, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptSetProvParam(hProv, 0, &temp, 1); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptSetProvParam(0, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); + + result = CryptSetProvParam(hProv, 0, &temp, 1); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); if (pCryptVerifySignatureW) { result = pCryptVerifySignatureW(hHash, &temp, 1, hKey, NULL, 0); ok (!result && (GetLastError() == ERROR_INVALID_PARAMETER || - GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%d\n", GetLastError()); + GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), "%ld\n", GetLastError()); } else win_skip("CryptVerifySignatureW is not available\n"); - result = pCryptDestroyHash(hHash); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptDestroyHash(hHash); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); - result = pCryptDestroyKey(hKey); - ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + result = CryptDestroyKey(hKey); + ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); } static const BYTE privKey[] = { @@ -437,49 +532,51 @@ static void test_verify_sig(void) return; } ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, + "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError()); + ret = CryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET); if (!ret && GetLastError() == NTE_EXISTS) - ret = pCryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0); - ok(ret, "CryptAcquireContextA failed: %08x\n", GetLastError()); - ret = pCryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key); - ok(ret, "CryptImportKey failed: %08x\n", GetLastError()); - ret = pCryptCreateHash(prov, CALG_MD5, 0, 0, &hash); - ok(ret, "CryptCreateHash failed: %08x\n", GetLastError()); + ret = CryptAcquireContextA(&prov, szKeySet, NULL, PROV_RSA_FULL, 0); + ok(ret, "CryptAcquireContextA failed: %08lx\n", GetLastError()); + ret = CryptImportKey(prov, (LPBYTE)privKey, sizeof(privKey), 0, 0, &key); + ok(ret, "CryptImportKey failed: %08lx\n", GetLastError()); + ret = CryptCreateHash(prov, CALG_MD5, 0, 0, &hash); + ok(ret, "CryptCreateHash failed: %08lx\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCryptVerifySignatureW(hash, NULL, 0, 0, NULL, 0); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCryptVerifySignatureW(0, NULL, 0, key, NULL, 0); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCryptVerifySignatureW(hash, NULL, 0, key, NULL, 0); ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE || GetLastError() == ERROR_INVALID_PARAMETER), - "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n", + "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCryptVerifySignatureW(hash, NULL, sizeof(bogus), key, NULL, 0); ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE || GetLastError() == ERROR_INVALID_PARAMETER), - "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08x\n", + "Expected NTE_BAD_SIGNATURE or ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCryptVerifySignatureW(hash, bogus, 0, key, NULL, 0); ok(!ret && GetLastError() == NTE_BAD_SIGNATURE, - "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError()); + "Expected NTE_BAD_SIGNATURE, got %08lx\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0); ok(!ret && (GetLastError() == NTE_BAD_SIGNATURE || broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)), - "Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError()); - pCryptDestroyKey(key); - pCryptDestroyHash(hash); - pCryptReleaseContext(prov, 0); + "Expected NTE_BAD_SIGNATURE, got %08lx\n", GetLastError()); + CryptDestroyKey(key); + CryptDestroyHash(hash); + + ret = CryptReleaseContext(prov, 0); + ok(ret, "got %lu\n", GetLastError()); } static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName, @@ -543,11 +640,11 @@ static void test_enum_providers(void) /* check pdwReserved flag for NULL */ result = pCryptEnumProvidersA(dwIndex, ¬Null, 0, &type, NULL, &providerLen); - ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d\n", GetLastError()); + ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%ld\n", GetLastError()); /* check dwFlags == 0 */ result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen); - ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d\n", GetLastError()); + ok(!result && GetLastError()==NTE_BAD_FLAGS, "%ld\n", GetLastError()); /* alloc provider to half the size required * cbName holds the size required */ @@ -556,7 +653,7 @@ static void test_enum_providers(void) return; result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen); - ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n", + ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %ld\n", ERROR_MORE_DATA, GetLastError()); LocalFree(provider); @@ -574,7 +671,7 @@ static void test_enum_providers(void) * ERROR_NO_MORE_ITEMS */ for (count = 0; count < provCount + 1; count++) result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen); - ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %d\n", + ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %ld\n", ERROR_NO_MORE_ITEMS, GetLastError()); /* check expected versus actual values returned */ @@ -585,20 +682,20 @@ static void test_enum_providers(void) providerLen = -1; result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen); - ok(result, "expected TRUE, got %d\n", result); - ok(type==dwType, "expected %d, got %d\n", dwType, type); + ok(result, "expected TRUE, got %ld\n", result); + ok(type==dwType, "expected %ld, got %ld\n", dwType, type); if (pszProvName) ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider); - ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen); + ok(cbName==providerLen, "expected %ld, got %ld\n", cbName, providerLen); providerLen = -1000; provider[0] = 0; result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen); - ok(result, "expected TRUE, got %d\n", result); - ok(type==dwType, "expected %d, got %d\n", dwType, type); + ok(result, "expected TRUE, got %ld\n", result); + ok(type==dwType, "expected %ld, got %ld\n", dwType, type); if (pszProvName) ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider); - ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen); + ok(cbName==providerLen, "expected %ld, got %ld\n", cbName, providerLen); LocalFree(pszProvName); LocalFree(provider); @@ -696,12 +793,12 @@ static void test_enum_provider_types(void) /* check pdwReserved for NULL */ result = pCryptEnumProviderTypesA(index, ¬Null, 0, &provType, typeName, &typeNameSize); - ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", + ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* check dwFlags == zero */ result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize); - ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %d\n", + ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* This test fails under Win2k SP4: @@ -716,7 +813,7 @@ static void test_enum_provider_types(void) SetLastError(0xdeadbeef); result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize); - ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%d\n", + ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %ld/%ld\n", result, GetLastError()); LocalFree(typeName); @@ -729,28 +826,28 @@ static void test_enum_provider_types(void) while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize)) ; typeCount--; - ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount); + ok(typeCount==dwTypeCount, "expected %ld, got %ld\n", dwTypeCount, typeCount); /* loop past the actual number of provider types to get the error * ERROR_NO_MORE_ITEMS */ for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++) result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize); - ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", + ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", GetLastError()); /* check expected versus actual values returned */ result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize); - ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize); + ok(result && typeNameSize==cbTypeName, "expected %ld, got %ld\n", cbTypeName, typeNameSize); if (!(typeName = LocalAlloc(LMEM_ZEROINIT, typeNameSize))) goto cleanup; typeNameSize = 0xdeadbeef; result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize); - ok(result, "expected TRUE, got %d\n", result); - ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType); + ok(result, "expected TRUE, got %ld\n", result); + ok(provType==dwProvType, "expected %ld, got %ld\n", dwProvType, provType); if (pszTypeName) ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName); - ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName, typeNameSize); + ok(typeNameSize==cbTypeName, "expected %ld, got %ld\n", cbTypeName, typeNameSize); LocalFree(typeName); cleanup: @@ -837,13 +934,13 @@ static void test_get_default_provider(void) /* check pdwReserved for NULL */ result = pCryptGetDefaultProviderA(provType, ¬Null, flags, provName, &provNameSize); - ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n", + ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %ld\n", ERROR_INVALID_PARAMETER, GetLastError()); /* check for invalid flag */ flags = 0xdeadbeef; result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize); - ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %d, got %d\n", + ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %ld, got %ld\n", NTE_BAD_FLAGS, GetLastError()); flags = CRYPT_MACHINE_DEFAULT; @@ -852,7 +949,7 @@ static void test_get_default_provider(void) result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize); ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE || GetLastError() == ERROR_INVALID_PARAMETER), - "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %d/%d\n", + "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %ld/%ld\n", result, GetLastError()); provType = PROV_RSA_FULL; @@ -865,14 +962,14 @@ static void test_get_default_provider(void) return; result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize); - ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %d\n", + ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %ld\n", ERROR_MORE_DATA, GetLastError()); LocalFree(provName); /* check expected versus actual values returned */ result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize); - ok(result && provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize); + ok(result && provNameSize==cbProvName, "expected %ld, got %ld\n", cbProvName, provNameSize); provNameSize = cbProvName; if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize))) @@ -880,10 +977,10 @@ static void test_get_default_provider(void) provNameSize = 0xdeadbeef; result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize); - ok(result, "expected TRUE, got %d\n", result); + ok(result, "expected TRUE, got %ld\n", result); if(pszProvName) ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName); - ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName, provNameSize); + ok(provNameSize==cbProvName, "expected %ld, got %ld\n", cbProvName, provNameSize); LocalFree(pszProvName); LocalFree(provName); @@ -911,11 +1008,11 @@ static void test_set_provider_ex(void) if (!(curProvName = LocalAlloc(LMEM_ZEROINIT, curlen))) return; result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, curProvName, &curlen); - ok(result, "%d\n", GetLastError()); + ok(result, "%ld\n", GetLastError()); /* check pdwReserved for NULL */ result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, ¬Null, CRYPT_MACHINE_DEFAULT); - ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %d\n", + ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %ld\n", ERROR_INVALID_PARAMETER, GetLastError()); /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */ @@ -924,31 +1021,31 @@ static void test_set_provider_ex(void) if (!result) { ok( GetLastError() == ERROR_ACCESS_DENIED || broken(GetLastError() == ERROR_INVALID_PARAMETER), - "wrong error %u\n", GetLastError() ); + "wrong error %lu\n", GetLastError() ); skip("Not enough rights to remove the default provider\n"); LocalFree(curProvName); return; } result = pCryptSetProviderExA(MS_DEF_PROV_A, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT); - ok(result, "%d\n", GetLastError()); + ok(result, "%ld\n", GetLastError()); /* call CryptGetDefaultProvider to see if they match */ result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName); - ok(result, "%d\n", GetLastError()); + ok(result, "%ld\n", GetLastError()); if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName))) goto reset; result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName); ok(result && !strcmp(MS_DEF_PROV_A, pszProvName), "expected %s, got %s\n", MS_DEF_PROV_A, pszProvName); - ok(result && cbProvName==(strlen(MS_DEF_PROV_A) + 1), "expected %i, got %d\n", (lstrlenA(MS_DEF_PROV_A) + 1), cbProvName); + ok(result && cbProvName==(strlen(MS_DEF_PROV_A) + 1), "expected %i, got %ld\n", (lstrlenA(MS_DEF_PROV_A) + 1), cbProvName); LocalFree(pszProvName); reset: /* Set the provider back to its original */ result = pCryptSetProviderExA(curProvName, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT); - ok(result, "%d\n", GetLastError()); + ok(result, "%ld\n", GetLastError()); LocalFree(curProvName); } @@ -976,7 +1073,7 @@ static void test_machine_guid(void) { restoreGuid = TRUE; r = RegDeleteValueA(key, "MachineGuid"); - ok(!r || broken(r == ERROR_ACCESS_DENIED) /*win8*/, "RegDeleteValueA failed: %d\n", r); + ok(!r || broken(r == ERROR_ACCESS_DENIED) /*win8*/, "RegDeleteValueA failed: %ld\n", r); if (r == ERROR_ACCESS_DENIED) { skip("broken virtualization on HKLM\\Software\\Microsoft\\Cryptography\n"); @@ -985,13 +1082,14 @@ static void test_machine_guid(void) } } else - ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", + ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", r); /* Create and release a provider */ - ret = pCryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0); + ret = CryptAcquireContextA(&hCryptProv, szKeySet, NULL, PROV_RSA_FULL, 0); ok(ret || broken(!ret && GetLastError() == NTE_KEYSET_ENTRY_BAD /* NT4 */), - "CryptAcquireContextA failed: %08x\n", GetLastError()); - pCryptReleaseContext(hCryptProv, 0); + "CryptAcquireContextA failed: %08lx\n", GetLastError()); + ret = CryptReleaseContext(hCryptProv, 0); + ok(ret, "got %lu\n", GetLastError()); if (restoreGuid) RegSetValueExA(key, "MachineGuid", 0, REG_SZ, (const BYTE *)originalGuid, @@ -1019,9 +1117,9 @@ static void test_rc2_keylen(void) BOOL ret; SetLastError(0xdeadbeef); - ret = pCryptAcquireContextA(&provider, NULL, NULL, + ret = CryptAcquireContextA(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - ok(ret, "CryptAcquireContext error %u\n", GetLastError()); + ok(ret, "CryptAcquireContext error %lu\n", GetLastError()); if (ret) { key_blob.header.bType = PLAINTEXTKEYBLOB; @@ -1033,71 +1131,68 @@ static void test_rc2_keylen(void) /* Importing a 16-byte key works with the default provider. */ SetLastError(0xdeadbeef); - ret = pCryptImportKey(provider, (BYTE*)&key_blob, - sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, - 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */ ok(ret || broken(!ret && GetLastError() == NTE_BAD_FLAGS), - "CryptImportKey error %08x\n", GetLastError()); - + "CryptImportKey error %08lx\n", GetLastError()); if (ret) - pCryptDestroyKey(hkey); - pCryptReleaseContext(provider, 0); + CryptDestroyKey(hkey); + + ret = CryptReleaseContext(provider, 0); + ok(ret, "got %lu\n", GetLastError()); } SetLastError(0xdeadbeef); - ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV_A, + ret = CryptAcquireContextA(&provider, NULL, MS_DEF_PROV_A, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - ok(ret, "CryptAcquireContext error %08x\n", GetLastError()); + ok(ret, "CryptAcquireContext error %08lx\n", GetLastError()); if (ret) { /* Importing a 16-byte key doesn't work with the base provider.. */ SetLastError(0xdeadbeef); - ret = pCryptImportKey(provider, (BYTE*)&key_blob, - sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, - 0, 0, &hkey); + ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size, + 0, 0, &hkey); ok(!ret && (GetLastError() == NTE_BAD_DATA || GetLastError() == NTE_BAD_LEN || /* Win7 */ GetLastError() == NTE_BAD_TYPE || /* W2K */ GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */ - "unexpected error %08x\n", GetLastError()); + "unexpected error %08lx\n", GetLastError()); /* but importing an 56-bit (7-byte) key does.. */ key_blob.key_size = 7; SetLastError(0xdeadbeef); - ret = pCryptImportKey(provider, (BYTE*)&key_blob, - sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, - 0, 0, &hkey); + ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size, + 0, 0, &hkey); ok(ret || broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */ broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */ - "CryptAcquireContext error %08x\n", GetLastError()); + "CryptAcquireContext error %08lx\n", GetLastError()); if (ret) - pCryptDestroyKey(hkey); + CryptDestroyKey(hkey); /* as does importing a 16-byte key with the base provider when * CRYPT_IPSEC_HMAC_KEY is specified. */ key_blob.key_size = sizeof(key); SetLastError(0xdeadbeef); - ret = pCryptImportKey(provider, (BYTE*)&key_blob, - sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, - 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */ ok(ret || broken(!ret && GetLastError() == NTE_BAD_FLAGS), - "CryptImportKey error %08x\n", GetLastError()); + "CryptImportKey error %08lx\n", GetLastError()); if (ret) - pCryptDestroyKey(hkey); + CryptDestroyKey(hkey); - pCryptReleaseContext(provider, 0); + ret = CryptReleaseContext(provider, 0); + ok(ret, "got %lu\n", GetLastError()); } key_blob.key_size = sizeof(key); SetLastError(0xdeadbeef); - ret = pCryptAcquireContextA(&provider, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - ok(ret, "CryptAcquireContext error %08x\n", GetLastError()); + ret = CryptAcquireContextA(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + ok(ret, "CryptAcquireContext error %08lx\n", GetLastError()); if (ret) { @@ -1105,141 +1200,32 @@ static void test_rc2_keylen(void) * CRYPT_IPSEC_HMAC_KEY is specified. */ SetLastError(0xdeadbeef); - ret = pCryptImportKey(provider, (BYTE*)&key_blob, - sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, - 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); ok(ret || broken(!ret && GetLastError() == NTE_BAD_FLAGS), - "CryptImportKey error %08x\n", GetLastError()); + "CryptImportKey error %08lx\n", GetLastError()); if (ret) - pCryptDestroyKey(hkey); + CryptDestroyKey(hkey); /* There is no apparent limit to the size of the input key when * CRYPT_IPSEC_HMAC_KEY is specified. */ key_blob.key_size = sizeof(key_blob.key_data); SetLastError(0xdeadbeef); - ret = pCryptImportKey(provider, (BYTE*)&key_blob, - sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size, - 0, CRYPT_IPSEC_HMAC_KEY, &hkey); + ret = CryptImportKey(provider, (BYTE *)&key_blob, sizeof(BLOBHEADER) + sizeof(DWORD) + key_blob.key_size, + 0, CRYPT_IPSEC_HMAC_KEY, &hkey); ok(ret || broken(!ret && GetLastError() == NTE_BAD_FLAGS), - "CryptImportKey error %08x\n", GetLastError()); + "CryptImportKey error %08lx\n", GetLastError()); if (ret) - pCryptDestroyKey(hkey); + CryptDestroyKey(hkey); - pCryptReleaseContext(provider, 0); + ret = CryptReleaseContext(provider, 0); + ok(ret, "got %lu\n", GetLastError()); } } -static void test_SystemFunction004(void) -{ - struct ustring inData; - struct ustring keyData; - struct ustring outData; - char inString[] = "Testdata for encryption"; - char keyString[] = "EncryptionKey"; - unsigned char outBuffer[32]; - NTSTATUS Status; -#if 0 - int i; -#endif - - if (!pSystemFunction004) - { - win_skip("SystemFunction004 is not available\n"); - return; - } - - inData.Length = strlen(inString) + 1; - inData.MaximumLength = inData.Length; - inData.Buffer = (unsigned char *)inString; - - keyData.Length = strlen(keyString) + 1; - keyData.MaximumLength = keyData.Length; - keyData.Buffer = (unsigned char *)keyString; - - outData.Length = 0; - outData.MaximumLength = 0; - outData.Buffer = NULL; - - Status = pSystemFunction004(&inData, &keyData, &outData); - ok(Status == STATUS_BUFFER_TOO_SMALL, "Expected SystemFunction004 to return STATUS_BUFFER_TOO_SMALL, got 0x%08lx\n", Status); - ok(outData.Length == 32, "Expected outData.Length to be 32, got %lu\n", outData.Length); - ok(outData.MaximumLength == 0, "Expected outData.MaximumLength to be 0, got %lu\n", outData.MaximumLength); - ok(outData.Buffer == NULL, "Expected outData.Length to be NULL, got %p\n", outData.Buffer); - - outData.Length = sizeof(outBuffer); - outData.MaximumLength = outData.Length; - outData.Buffer = outBuffer; - - Status = pSystemFunction004(&inData, &keyData, &outData); - ok(Status == STATUS_SUCCESS, "Expected SystemFunction004 to return STATUS_SUCCESS, got 0x%08lx\n", Status); - ok(outData.Length == 32, "Expected outData.Length to be 32, got %lu\n", outData.Length); - ok(outData.MaximumLength == 32, "Expected outData.MaximumLength to be 32, got %lu\n", outData.MaximumLength); - ok(outData.Buffer != NULL, "Expected outData.Buffer not to be NULL, got %p\n", outData.Buffer); -#if 0 - if (Status == STATUS_SUCCESS) - { - printf("outData.Buffer:\n"); - for (i = 0; i < sizeof(outBuffer); i++) - printf("0x%02x ", outBuffer[i]); - printf("\n"); - } -#endif -} - -static void test_SystemFunction005(void) -{ - struct ustring inData; - struct ustring keyData; - struct ustring outData; - unsigned char inBuffer[32] = {0xdc, 0xff, 0x05, 0x8d, 0xaf, 0xb6, 0xe2, 0x8c, 0x4f, 0xee, 0x00, 0x06, 0xac, 0x1d, 0x56, 0xf1, - 0x24, 0xbd, 0x17, 0xe0, 0xf6, 0xb8, 0x6d, 0x3a, 0x69, 0x5d, 0x14, 0xf9, 0x5a, 0x54, 0x93, 0xd1}; - char keyString[] = "EncryptionKey"; - char outBuffer[24]; - NTSTATUS Status; - - if (!pSystemFunction005) - { - win_skip("SystemFunction005 is not available\n"); - return; - } - - inData.Length = sizeof(inBuffer); - inData.MaximumLength = inData.Length; - inData.Buffer = inBuffer; - - keyData.Length = strlen(keyString) + 1; - keyData.MaximumLength = keyData.Length; - keyData.Buffer = (unsigned char *)keyString; - - outData.Length = 0; - outData.MaximumLength = 0; - outData.Buffer = NULL; - - Status = pSystemFunction005(&inData, &keyData, &outData); - ok(Status == STATUS_BUFFER_TOO_SMALL, "Expected SystemFunction005 to return STATUS_BUFFER_TOO_SMALL, got 0x%08lx\n", Status); - ok(outData.Length == 24, "Expected outData.Length to be 24, got %lu\n", outData.Length); - ok(outData.MaximumLength == 0, "Expected outData.MaximumLength to be 0, got %lu\n", outData.MaximumLength); - ok(outData.Buffer == NULL, "Expected outData.Buffer to be NULL, got %p\n", outData.Buffer); - - outData.Length = sizeof(outBuffer); - outData.MaximumLength = outData.Length; - outData.Buffer = (unsigned char *)outBuffer; - - Status = pSystemFunction005(&inData, &keyData, &outData); - ok(Status == STATUS_SUCCESS, "Expected SystemFunction005 to return STATUS_SUCCESS, got 0x%08lx\n", Status); - ok(outData.Length == 24, "Expected outData.Length to be 24, got %lu\n", outData.Length); - ok(outData.MaximumLength == 24, "Expected outData.MaximumLength to be 24, got %lu\n", outData.MaximumLength); - ok(outData.Buffer != NULL, "Expected outData.Buffer not to be NULL, got %p\n", outData.Buffer); -#if 0 - if (Status == STATUS_SUCCESS) - printf("outData.Buffer: '%s'\n", outData.Buffer); -#endif -} - - static void test_SystemFunction036(void) { BOOL ret; @@ -1259,7 +1245,7 @@ static void test_SystemFunction036(void) { SetLastError(0xdeadbeef); ret = pSystemFunction036(NULL, 5); - trace("ret = %d, GetLastError() = %d\n", ret, GetLastError()); + trace("ret = %d, GetLastError() = %ld\n", ret, GetLastError()); } ret = pSystemFunction036(&test, 0); @@ -1278,49 +1264,49 @@ static void test_container_sd(void) ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET); - ok(ret, "got %u\n", GetLastError()); + ok(ret, "got %lu\n", GetLastError()); len = 0; SetLastError(0xdeadbeef); ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, NULL, &len, OWNER_SECURITY_INFORMATION); err = GetLastError(); - ok(ret, "got %u\n", err); - ok(err == ERROR_INSUFFICIENT_BUFFER || broken(err == ERROR_INVALID_PARAMETER), "got %u\n", err); + ok(ret, "got %lu\n", err); + ok(err == ERROR_INSUFFICIENT_BUFFER || broken(err == ERROR_INVALID_PARAMETER), "got %lu\n", err); ok(len, "expected len > 0\n"); - sd = HeapAlloc(GetProcessHeap(), 0, len); + sd = malloc(len); ret = CryptGetProvParam(prov, PP_KEYSET_SEC_DESCR, (BYTE *)sd, &len, OWNER_SECURITY_INFORMATION); - ok(ret, "got %u\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, sd); + ok(ret, "got %lu\n", GetLastError()); + free(sd); ret = CryptReleaseContext(prov, 0); - ok(ret, "got %u\n", GetLastError()); + ok(ret, "got %lu\n", GetLastError()); + prov = 0xdeadbeef; ret = CryptAcquireContextA(&prov, "winetest", "Microsoft Enhanced Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_DELETEKEYSET); - ok(ret, "got %u\n", GetLastError()); + ok(ret, "got %lu\n", GetLastError()); + ok(prov == 0, "got %Id\n", prov); } START_TEST(crypt) { init_function_pointers(); - if (pCryptAcquireContextA && pCryptReleaseContext) - { - test_rc2_keylen(); - init_environment(); - test_acquire_context(); - test_incorrect_api_usage(); - test_verify_sig(); - test_machine_guid(); - test_container_sd(); - clean_up_environment(); - } - - test_enum_providers(); - test_enum_provider_types(); - test_get_default_provider(); - test_set_provider_ex(); - test_SystemFunction004(); - test_SystemFunction005(); - test_SystemFunction036(); + + test_rc2_keylen(); + + init_environment(); + test_CryptReleaseContext(); + test_acquire_context(); + test_incorrect_api_usage(); + test_verify_sig(); + test_machine_guid(); + test_container_sd(); + clean_up_environment(); + + test_enum_providers(); + test_enum_provider_types(); + test_get_default_provider(); + test_set_provider_ex(); + test_SystemFunction036(); } diff --git a/modules/rostests/winetests/advapi32/crypt_lmhash.c b/modules/rostests/winetests/advapi32/crypt_lmhash.c index a6e812e54a9..4c96e5b7629 100644 --- a/modules/rostests/winetests/advapi32/crypt_lmhash.c +++ b/modules/rostests/winetests/advapi32/crypt_lmhash.c @@ -287,18 +287,18 @@ static void test_SystemFunction004(void) r = pSystemFunction002(out.Buffer, key.Buffer, output); ok(r == STATUS_SUCCESS, "function failed\n"); - ok(((unsigned int*)output)[0] == in.Length, "crypted length wrong\n"); - ok(((unsigned int*)output)[1] == 1, "crypted value wrong\n"); + ok(((unsigned int*)output)[0] == in.Length, "encrypted length wrong\n"); + ok(((unsigned int*)output)[1] == 1, "encrypted value wrong\n"); memset(output, 0, sizeof output); r = pSystemFunction002(out.Buffer+8, key.Buffer, output); ok(r == STATUS_SUCCESS, "function failed\n"); - ok(!memcmp(output, inbuf, sizeof output), "crypted data wrong\n"); + ok(!memcmp(output, inbuf, sizeof output), "encrypted data wrong\n"); memset(output, 0, sizeof output); r = pSystemFunction002(out.Buffer+16, key.Buffer, output); ok(r == STATUS_SUCCESS, "function failed\n"); - ok(!memcmp(output, inbuf, sizeof output), "crypted data wrong\n"); + ok(!memcmp(output, inbuf, sizeof output), "encrypted data wrong\n"); } static void test_SystemFunction005(void) diff --git a/modules/rostests/winetests/advapi32/eventlog.c b/modules/rostests/winetests/advapi32/eventlog.c index e6b2de5edb3..b83b7551d40 100644 --- a/modules/rostests/winetests/advapi32/eventlog.c +++ b/modules/rostests/winetests/advapi32/eventlog.c @@ -28,12 +28,17 @@ #include "winreg.h" #include "sddl.h" #include "wmistr.h" +#include "evntprov.h" #include "evntrace.h" +#include "netevent.h" #include "wine/test.h" static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*); static BOOL (WINAPI *pGetEventLogInformation)(HANDLE,DWORD,LPVOID,DWORD,LPDWORD); +static ULONG (WINAPI *pEventRegister)(const GUID *,PENABLECALLBACK,void *,REGHANDLE *); +static ULONG (WINAPI *pEventUnregister)(REGHANDLE); +static ULONG (WINAPI *pEventWriteString)(REGHANDLE,UCHAR,ULONGLONG,const WCHAR *); static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD); static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(PVOID *); @@ -46,6 +51,9 @@ static void init_function_pointers(void) pCreateWellKnownSid = (void*)GetProcAddress(hadvapi32, "CreateWellKnownSid"); pGetEventLogInformation = (void*)GetProcAddress(hadvapi32, "GetEventLogInformation"); + pEventWriteString = (void*)GetProcAddress(hadvapi32, "EventWriteString"); + pEventRegister = (void*)GetProcAddress(hadvapi32, "EventRegister"); + pEventUnregister = (void*)GetProcAddress(hadvapi32, "EventUnregister"); pGetComputerNameExA = (void*)GetProcAddress(hkernel32, "GetComputerNameExA"); pWow64DisableWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64DisableWow64FsRedirection"); @@ -57,8 +65,15 @@ static BOOL create_backup(const char *filename) HANDLE handle; DWORD rc, attribs; - DeleteFileA(filename); handle = OpenEventLogA(NULL, "Application"); + if (!handle && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == RPC_S_SERVER_UNAVAILABLE)) + { + win_skip( "Can't open event log\n" ); + return FALSE; + } + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); + + DeleteFileA(filename); rc = BackupEventLogA(handle, filename); if (!rc && GetLastError() == ERROR_PRIVILEGE_NOT_HELD) { @@ -66,12 +81,12 @@ static BOOL create_backup(const char *filename) CloseEventLog(handle); return FALSE; } - ok(rc, "BackupEventLogA failed, le=%u\n", GetLastError()); + ok(rc, "BackupEventLogA failed, le=%lu\n", GetLastError()); CloseEventLog(handle); attribs = GetFileAttributesA(filename); todo_wine - ok(attribs != INVALID_FILE_ATTRIBUTES, "Expected a backup file attribs=%#x le=%u\n", attribs, GetLastError()); + ok(attribs != INVALID_FILE_ATTRIBUTES, "Expected a backup file attribs=%#lx le=%lu\n", attribs, GetLastError()); return TRUE; } @@ -85,46 +100,46 @@ static void test_open_close(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE || GetLastError() == ERROR_NOACCESS, /* W2K */ - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); handle = OpenEventLogA(NULL, NULL); - ok(handle == NULL, "Didn't expect a handle\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(handle == NULL, "OpenEventLogA() succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); handle = OpenEventLogA("IDontExist", NULL); - ok(handle == NULL, "Didn't expect a handle\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(handle == NULL, "OpenEventLogA(IDontExist,) succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); handle = OpenEventLogA("IDontExist", "deadbeef"); - ok(handle == NULL, "Didn't expect a handle\n"); + ok(handle == NULL, "OpenEventLogA(IDontExist,deadbeef) succeeded\n"); ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */ - "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError()); + "Expected RPC_S_SERVER_UNAVAILABLE, got %ld\n", GetLastError()); /* This one opens the Application log */ handle = OpenEventLogA(NULL, "deadbeef"); - ok(handle != NULL, "Expected a handle\n"); + ok(handle != NULL, "OpenEventLogA(deadbeef) failed : %ld\n", GetLastError()); ret = CloseEventLog(handle); - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); /* Close a second time */ SetLastError(0xdeadbeef); ret = CloseEventLog(handle); todo_wine { ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); } /* Empty servername should be read as local server */ handle = OpenEventLogA("", "Application"); - ok(handle != NULL, "Expected a handle\n"); + ok(handle != NULL, "OpenEventLogA('',Application) failed : %ld\n", GetLastError()); CloseEventLog(handle); handle = OpenEventLogA(NULL, "Application"); - ok(handle != NULL, "Expected a handle\n"); + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); CloseEventLog(handle); } @@ -145,46 +160,47 @@ static void test_info(void) SetLastError(0xdeadbeef); ret = pGetEventLogInformation(NULL, 1, NULL, 0, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_LEVEL, "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_LEVEL, "Expected ERROR_INVALID_LEVEL, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pGetEventLogInformation(NULL, EVENTLOG_FULL_INFO, NULL, 0, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); handle = OpenEventLogA(NULL, "Application"); + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, &needed); ok(!ret, "Expected failure\n"); - ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, efi, 0, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); needed = 0xdeadbeef; efi->dwFull = 0xdeadbeef; ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, efi, 0, &needed); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %ld\n", needed); ok(efi->dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n"); /* Not that we care, but on success last error is set to ERROR_IO_PENDING */ efi->dwFull = 0xdeadbeef; needed = sizeof(buffer); ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, efi, needed, &needed); - ok(ret, "Expected success\n"); - ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed); - ok(efi->dwFull == 0 || efi->dwFull == 1, "Expected 0 (not full) or 1 (full), got %d\n", efi->dwFull); + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %ld\n", needed); + ok(efi->dwFull == 0 || efi->dwFull == 1, "Expected 0 (not full) or 1 (full), got %ld\n", efi->dwFull); CloseEventLog(handle); } @@ -199,25 +215,26 @@ static void test_count(void) SetLastError(0xdeadbeef); ret = GetNumberOfEventLogRecords(NULL, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); count = 0xdeadbeef; ret = GetNumberOfEventLogRecords(NULL, &count); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); ok(count == 0xdeadbeef, "Expected count to stay unchanged\n"); handle = OpenEventLogA(NULL, "Application"); + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = GetNumberOfEventLogRecords(handle, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); count = 0xdeadbeef; ret = GetNumberOfEventLogRecords(handle, &count); - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); ok(count != 0xdeadbeef, "Expected the number of records\n"); CloseEventLog(handle); @@ -227,14 +244,14 @@ static void test_count(void) { handle = OpenBackupEventLogA(NULL, backup); todo_wine - ok(handle != NULL, "Expected a handle, le=%d\n", GetLastError()); + ok(handle != NULL, "Expected a handle, le=%ld\n", GetLastError()); /* Does GetNumberOfEventLogRecords work with backup eventlogs? */ count = 0xdeadbeef; ret = GetNumberOfEventLogRecords(handle, &count); todo_wine { - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); ok(count != 0xdeadbeef, "Expected the number of records\n"); } @@ -253,25 +270,31 @@ static void test_oldest(void) SetLastError(0xdeadbeef); ret = GetOldestEventLogRecord(NULL, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); oldest = 0xdeadbeef; ret = GetOldestEventLogRecord(NULL, &oldest); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); ok(oldest == 0xdeadbeef, "Expected oldest to stay unchanged\n"); handle = OpenEventLogA(NULL, "Application"); + if (!handle && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == RPC_S_SERVER_UNAVAILABLE)) + { + win_skip( "Can't open event log\n" ); + return; + } + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = GetOldestEventLogRecord(handle, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); oldest = 0xdeadbeef; ret = GetOldestEventLogRecord(handle, &oldest); - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n"); CloseEventLog(handle); @@ -288,7 +311,7 @@ static void test_oldest(void) ret = GetOldestEventLogRecord(handle, &oldest); todo_wine { - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n"); } @@ -307,7 +330,7 @@ static void test_backup(void) SetLastError(0xdeadbeef); ret = BackupEventLogA(NULL, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = BackupEventLogA(NULL, backup); @@ -315,11 +338,17 @@ static void test_backup(void) ok(GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n"); handle = OpenEventLogA(NULL, "Application"); + if (!handle && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == RPC_S_SERVER_UNAVAILABLE)) + { + win_skip( "Can't open event log\n" ); + return; + } + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = BackupEventLogA(handle, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); ret = BackupEventLogA(handle, backup); if (!ret && GetLastError() == ERROR_PRIVILEGE_NOT_HELD) @@ -328,7 +357,7 @@ static void test_backup(void) CloseEventLog(handle); return; } - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); todo_wine ok(GetFileAttributesA(backup) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n"); @@ -338,7 +367,7 @@ static void test_backup(void) todo_wine { ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %ld\n", GetLastError()); } CloseEventLog(handle); @@ -351,7 +380,7 @@ static void test_backup(void) ret = BackupEventLogA(handle, backup2); todo_wine { - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); ok(GetFileAttributesA(backup2) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n"); } @@ -371,7 +400,7 @@ static void test_read(void) ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, NULL); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); read = 0xdeadbeef; SetLastError(0xdeadbeef); @@ -379,7 +408,7 @@ static void test_read(void) ok(!ret, "Expected failure\n"); ok(read == 0xdeadbeef, "Expected 'read' parameter to remain unchanged\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); needed = 0xdeadbeef; SetLastError(0xdeadbeef); @@ -387,26 +416,26 @@ static void test_read(void) ok(!ret, "Expected failure\n"); ok(needed == 0xdeadbeef, "Expected 'needed' parameter to remain unchanged\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* 'read' and 'needed' are only filled when the needed buffer size is passed back or when the call succeeds */ SetLastError(0xdeadbeef); ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, NULL, NULL); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); buf = NULL; SetLastError(0xdeadbeef); @@ -414,62 +443,68 @@ static void test_read(void) 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); - buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + buf = malloc(sizeof(EVENTLOGRECORD)); SetLastError(0xdeadbeef); ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, buf); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); + free(buf); handle = OpenEventLogA(NULL, "Application"); + if (!handle && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == RPC_S_SERVER_UNAVAILABLE)) + { + win_skip( "Can't open event log\n" ); + return; + } + ok(handle != NULL, "OpenEventLogA(Application) failed : %ld\n", GetLastError()); /* Show that we need the proper dwFlags with a (for the rest) proper call */ - buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + buf = malloc(sizeof(EVENTLOGRECORD)); SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, 0, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); todo_wine - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, buf); + free(buf); /* First check if there are any records (in practice only on Wine: FIXME) */ count = 0; @@ -482,7 +517,7 @@ static void test_read(void) } /* Get the buffer size for the first record */ - buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + buf = malloc(sizeof(EVENTLOGRECORD)); read = needed = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, @@ -490,20 +525,20 @@ static void test_read(void) ok(!ret, "Expected failure\n"); ok(read == 0, "Expected no bytes read\n"); ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be bigger than sizeof(EVENTLOGRECORD)\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* Read the first record */ toread = needed; - buf = HeapReAlloc(GetProcessHeap(), 0, buf, toread); + buf = realloc(buf, toread); read = needed = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, toread, &read, &needed); - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); ok(read == toread || broken(read < toread), /* NT4 wants a buffer size way bigger than just 1 record */ "Expected the requested size to be read\n"); ok(needed == 0, "Expected no extra bytes to be read\n"); - HeapFree(GetProcessHeap(), 0, buf); + free(buf); CloseEventLog(handle); } @@ -518,24 +553,27 @@ static void test_openbackup(void) SetLastError(0xdeadbeef); handle = OpenBackupEventLogA(NULL, NULL); ok(handle == NULL, "Didn't expect a handle\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); handle = OpenBackupEventLogA(NULL, "idontexist.evt"); ok(handle == NULL, "Didn't expect a handle\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_FILE_NOT_FOUND || + GetLastError() == ERROR_ACCESS_DENIED || + GetLastError() == RPC_S_SERVER_UNAVAILABLE, + "got %ld\n", GetLastError()); SetLastError(0xdeadbeef); handle = OpenBackupEventLogA("IDontExist", NULL); ok(handle == NULL, "Didn't expect a handle\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); handle = OpenBackupEventLogA("IDontExist", "idontexist.evt"); ok(handle == NULL, "Didn't expect a handle\n"); ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */ - "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError()); + "Expected RPC_S_SERVER_UNAVAILABLE, got %ld\n", GetLastError()); /* Make a backup eventlog to work with */ if (create_backup(backup)) @@ -552,7 +590,7 @@ static void test_openbackup(void) ok(handle == NULL, "Didn't expect a handle\n"); ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */ - "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError()); + "Expected RPC_S_SERVER_UNAVAILABLE, got %ld\n", GetLastError()); /* Empty servername should be read as local server */ handle = OpenBackupEventLogA("", backup); @@ -579,8 +617,10 @@ static void test_openbackup(void) handle = OpenBackupEventLogA(NULL, backup); ok(handle == NULL, "Didn't expect a handle\n"); ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY || + GetLastError() == ERROR_ACCESS_DENIED || + GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, /* Vista and Win7 */ - "Expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError()); + "got %ld\n", GetLastError()); CloseEventLog(handle); DeleteFileA(backup); @@ -590,7 +630,10 @@ static void test_openbackup(void) SetLastError(0xdeadbeef); handle = OpenBackupEventLogA(NULL, backup); ok(handle == NULL, "Didn't expect a handle\n"); - ok(GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, "Expected ERROR_EVENTLOG_FILE_CORRUPT, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT || + GetLastError() == ERROR_ACCESS_DENIED || + GetLastError() == RPC_S_SERVER_UNAVAILABLE, + "got %ld\n", GetLastError()); CloseEventLog(handle); DeleteFileA(backup); } @@ -605,7 +648,7 @@ static void test_clear(void) SetLastError(0xdeadbeef); ret = ClearEventLogA(NULL, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); /* Make a backup eventlog to work with */ if (!create_backup(backup)) @@ -614,7 +657,7 @@ static void test_clear(void) SetLastError(0xdeadbeef); ret = ClearEventLogA(NULL, backup); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); handle = OpenBackupEventLogA(NULL, backup); todo_wine @@ -629,19 +672,19 @@ static void test_clear(void) */ ok(GetLastError() == ERROR_INVALID_HANDLE || GetLastError() == ERROR_ACCESS_DENIED, /* Vista+ */ - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); /* Show that ClearEventLog only works for real eventlogs. */ SetLastError(0xdeadbeef); ret = ClearEventLogA(handle, backup2); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); ok(GetFileAttributesA(backup2) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n"); SetLastError(0xdeadbeef); ret = ClearEventLogA(handle, NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); CloseEventLog(handle); todo_wine @@ -674,7 +717,7 @@ static BOOL create_new_eventlog(void) } /* Create some event sources, the registry value 'Sources' is updated automatically */ - for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++) + for (i = 0; i < ARRAY_SIZE(eventsources); i++) { HKEY srckey; @@ -737,11 +780,12 @@ static void test_readwrite(void) DWORD i; char *localcomputer = NULL; DWORD size; + void* buf; if (pCreateWellKnownSid) { sidsize = SECURITY_MAX_SID_SIZE; - user = HeapAlloc(GetProcessHeap(), 0, sidsize); + user = malloc(sidsize); SetLastError(0xdeadbeef); pCreateWellKnownSid(WinInteractiveSid, NULL, user, &sidsize); sidavailable = TRUE; @@ -774,6 +818,7 @@ static void test_readwrite(void) Sleep(2000); handle = OpenEventLogA(NULL, eventlogname); + ok(handle != NULL, "OpenEventLogA(%s) failed : %ld\n", eventlogname, GetLastError()); count = 0xdeadbeef; GetNumberOfEventLogRecords(handle, &count); if (count != 0) @@ -790,7 +835,7 @@ static void test_readwrite(void) { win_skip("Win7 fails when using incorrect event types\n"); ret = ReportEventA(handle, 0, 0, 0, NULL, 0, 0, NULL, NULL); - ok(ret, "Expected success : %d\n", GetLastError()); + ok(ret, "Expected success : %ld\n", GetLastError()); } else { @@ -798,15 +843,15 @@ static void test_readwrite(void) DWORD read, needed = 0; EVENTLOGRECORD *record; - ok(ret, "Expected success : %d\n", GetLastError()); + ok(ret, "Expected success : %ld\n", GetLastError()); /* Needed to catch earlier Vista (with no ServicePack for example) */ - buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + buf = malloc(sizeof(EVENTLOGRECORD)); if (!(ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed)) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed); + buf = realloc(buf, needed); ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, needed, &read, &needed); } @@ -820,7 +865,7 @@ static void test_readwrite(void) if (record->EventType == EVENTLOG_SUCCESS) on_vista = TRUE; } - HeapFree(GetProcessHeap(), 0, buf); + free(buf); } /* This will clear the eventlog. The record numbering for new @@ -833,11 +878,13 @@ static void test_readwrite(void) CloseEventLog(handle); /* Write a bunch of events while using different event sources */ - for (i = 0; i < sizeof(read_write)/sizeof(read_write[0]); i++) + for (i = 0; i < ARRAY_SIZE(read_write); i++) { DWORD oldest; BOOL run_sidtests = read_write[i].evt_sid & sidavailable; + winetest_push_context("%lu:%s", i, read_write[i].evt_src); + /* We don't need to use RegisterEventSource to report events */ if (i % 2) handle = OpenEventLogA(NULL, read_write[i].evt_src); @@ -849,22 +896,22 @@ static void test_readwrite(void) ret = ReportEventA(handle, read_write[i].evt_type, read_write[i].evt_cat, read_write[i].evt_id, run_sidtests ? user : NULL, read_write[i].evt_numstrings, 0, read_write[i].evt_strings, NULL); - ok(ret, "Expected ReportEvent success : %d\n", GetLastError()); + ok(ret, "Expected ReportEvent success : %ld\n", GetLastError()); count = 0xdeadbeef; SetLastError(0xdeadbeef); ret = GetNumberOfEventLogRecords(handle, &count); - ok(ret, "Expected GetNumberOfEventLogRecords success : %d\n", GetLastError()); + ok(ret, "Expected GetNumberOfEventLogRecords success : %ld\n", GetLastError()); todo_wine - ok(count == (i + 1), "Expected %d records, got %d\n", i + 1, count); + ok(count == (i + 1), "Expected %ld records, got %ld\n", i + 1, count); oldest = 0xdeadbeef; ret = GetOldestEventLogRecord(handle, &oldest); - ok(ret, "Expected GetOldestEventLogRecord success : %d\n", GetLastError()); + ok(ret, "Expected GetOldestEventLogRecord success : %ld\n", GetLastError()); todo_wine ok(oldest == 1 || (oldest > 1 && oldest != 0xdeadbeef), /* Vista SP1+, W2K8 and Win7 */ - "Expected oldest to be 1 or higher, got %d\n", oldest); + "Expected oldest to be 1 or higher, got %ld\n", oldest); if (oldest > 1 && oldest != 0xdeadbeef) on_vista = TRUE; @@ -873,15 +920,17 @@ static void test_readwrite(void) ret = CloseEventLog(handle); else ret = DeregisterEventSource(handle); - ok(ret, "Expected success : %d\n", GetLastError()); + ok(ret, "Expected success : %ld\n", GetLastError()); + winetest_pop_context(); } handle = OpenEventLogA(NULL, eventlogname); + ok(handle != NULL, "OpenEventLogA(%s) failed : %ld\n", eventlogname, GetLastError()); count = 0xdeadbeef; ret = GetNumberOfEventLogRecords(handle, &count); - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); todo_wine - ok(count == i, "Expected %d records, got %d\n", i, count); + ok(count == i, "Expected %ld records, got %ld\n", i, count); CloseEventLog(handle); if (count == 0) @@ -900,23 +949,24 @@ static void test_readwrite(void) size = 0; SetLastError(0xdeadbeef); pGetComputerNameExA(ComputerNameDnsFullyQualified, NULL, &size); - localcomputer = HeapAlloc(GetProcessHeap(), 0, size); + localcomputer = malloc(size); pGetComputerNameExA(ComputerNameDnsFullyQualified, localcomputer, &size); } else { size = MAX_COMPUTERNAME_LENGTH + 1; - localcomputer = HeapAlloc(GetProcessHeap(), 0, size); + localcomputer = malloc(size); GetComputerNameA(localcomputer, &size); } /* Read all events from our created eventlog, one by one */ handle = OpenEventLogA(NULL, eventlogname); - ok(handle != NULL, "Failed to open Event Log, got %d\n", GetLastError()); + ok(handle != NULL, "OpenEventLogA(%s) failed : %ld\n", eventlogname, GetLastError()); i = 0; + size = sizeof(EVENTLOGRECORD) + 128; + buf = malloc(size); for (;;) { - void *buf; DWORD read, needed; EVENTLOGRECORD *record; char *sourcename, *computername; @@ -924,34 +974,44 @@ static void test_readwrite(void) char *ptr; BOOL run_sidtests = read_write[i].evt_sid & sidavailable; - buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); + winetest_push_context("%lu", i); + SetLastError(0xdeadbeef); ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed); ok(!ret, "Expected failure\n"); if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - HeapFree(GetProcessHeap(), 0, buf); - ok(GetLastError() == ERROR_HANDLE_EOF, "record %d, got %d\n", i, GetLastError()); + ok(GetLastError() == ERROR_HANDLE_EOF, "record %ld, got %ld\n", i, GetLastError()); + winetest_pop_context(); break; } - buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed); + if (needed > size) + { + free(buf); + size = needed; + buf = malloc(size); + } ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, needed, &read, &needed); - ok(ret, "Expected success: %d\n", GetLastError()); - + ok(ret, "Expected success: %ld\n", GetLastError()); + if (!ret) + { + winetest_pop_context(); + break; + } record = (EVENTLOGRECORD *)buf; ok(record->Length == read, - "Expected %d, got %d\n", read, record->Length); + "Expected %ld, got %ld\n", read, record->Length); ok(record->Reserved == 0x654c664c, - "Expected 0x654c664c, got %d\n", record->Reserved); + "Expected 0x654c664c, got %ld\n", record->Reserved); ok(record->RecordNumber == i + 1 || (on_vista && (record->RecordNumber > i + 1)), - "Expected %d or higher, got %d\n", i + 1, record->RecordNumber); + "Expected %ld or higher, got %ld\n", i + 1, record->RecordNumber); ok(record->EventID == read_write[i].evt_id, - "Expected %d, got %d\n", read_write[i].evt_id, record->EventID); + "Expected %ld, got %ld\n", read_write[i].evt_id, record->EventID); ok(record->EventType == read_write[i].evt_type, "Expected %d, got %d\n", read_write[i].evt_type, record->EventType); ok(record->NumStrings == read_write[i].evt_numstrings, @@ -986,15 +1046,15 @@ static void test_readwrite(void) if (run_sidtests) { - ok(record->UserSidLength == sidsize, "Expected %d, got %d\n", sidsize, record->UserSidLength); + ok(record->UserSidLength == sidsize, "Expected %ld, got %ld\n", sidsize, record->UserSidLength); } else { ok(record->StringOffset == record->UserSidOffset, "Expected offsets to be the same\n"); - ok(record->UserSidLength == 0, "Expected 0, got %d\n", record->UserSidLength); + ok(record->UserSidLength == 0, "Expected 0, got %ld\n", record->UserSidLength); } - ok(record->DataLength == 0, "Expected 0, got %d\n", record->DataLength); + ok(record->DataLength == 0, "Expected 0, got %ld\n", record->DataLength); ptr = (char *)((BYTE *)buf + record->StringOffset); for (k = 0; k < record->NumStrings; k++) @@ -1006,29 +1066,30 @@ static void test_readwrite(void) ok(record->Length == *(DWORD *)((BYTE *)buf + record->Length - sizeof(DWORD)), "Expected the closing DWORD to contain the length of the record\n"); - HeapFree(GetProcessHeap(), 0, buf); + winetest_pop_context(); i++; } + free(buf); CloseEventLog(handle); /* Test clearing a real eventlog */ handle = OpenEventLogA(NULL, eventlogname); - ok(handle != NULL, "Failed to open Event Log, got %d\n", GetLastError()); + ok(handle != NULL, "OpenEventLogA(%s) failed : %ld\n", eventlogname, GetLastError()); SetLastError(0xdeadbeef); ret = ClearEventLogA(handle, NULL); - ok(ret, "Expected success\n"); + ok(ret, "Expected success : %ld\n", GetLastError()); count = 0xdeadbeef; ret = GetNumberOfEventLogRecords(handle, &count); - ok(ret, "Expected success\n"); - ok(count == 0, "Expected an empty eventlog, got %d records\n", count); + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(count == 0, "Expected an empty eventlog, got %ld records\n", count); CloseEventLog(handle); cleanup: - HeapFree(GetProcessHeap(), 0, localcomputer); - HeapFree(GetProcessHeap(), 0, user); + free(localcomputer); + free(user); } /* Before Vista: @@ -1069,12 +1130,12 @@ static void test_autocreation(void) { char sources_verify[sizeof(eventsources)]; - ok(type == REG_MULTI_SZ, "Expected a REG_MULTI_SZ, got %d\n", type); + ok(type == REG_MULTI_SZ, "Expected a REG_MULTI_SZ, got %ld\n", type); /* Build the expected string */ memset(sources_verify, 0, sizeof(sources_verify)); p = sources_verify; - for (i = sizeof(eventsources)/sizeof(eventsources[0]); i > 0; i--) + for (i = ARRAY_SIZE(eventsources); i > 0; i--) { lstrcpyA(p, eventsources[i - 1]); p += (lstrlenA(eventsources[i - 1]) + 1); @@ -1082,7 +1143,7 @@ static void test_autocreation(void) lstrcpyA(p, eventlogname); ok(!memcmp(sources, sources_verify, size), - "Expected a correct 'Sources' value (size : %d)\n", size); + "Expected a correct 'Sources' value (size : %ld)\n", size); } RegCloseKey(eventkey); @@ -1095,24 +1156,10 @@ static void test_autocreation(void) /* On Windows we also automatically get an eventlog file */ GetSystemDirectoryA(sysdir, sizeof(sysdir)); - /* NT4 - W2K3 */ lstrcpyA(eventlogfile, sysdir); - lstrcatA(eventlogfile, "\\config\\"); + lstrcatA(eventlogfile, "\\winevt\\Logs\\"); lstrcatA(eventlogfile, eventlogname); - lstrcatA(eventlogfile, ".evt"); - - if (GetFileAttributesA(eventlogfile) == INVALID_FILE_ATTRIBUTES) - { - /* Vista+ */ - lstrcpyA(eventlogfile, sysdir); - lstrcatA(eventlogfile, "\\winevt\\Logs\\"); - lstrcatA(eventlogfile, eventlogname); - lstrcatA(eventlogfile, ".evtx"); - } - - todo_wine - ok(GetFileAttributesA(eventlogfile) != INVALID_FILE_ATTRIBUTES, - "Expected an eventlog file\n"); + lstrcatA(eventlogfile, ".evtx"); if (pWow64RevertWow64FsRedirection) pWow64RevertWow64FsRedirection(redir); @@ -1132,18 +1179,54 @@ static void cleanup_eventlog(void) lstrcatA(winesvc, eventlogname); RegOpenKeyA(HKEY_LOCAL_MACHINE, winesvc, &key); - for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++) + for (i = 0; i < ARRAY_SIZE(eventsources); i++) RegDeleteKeyA(key, eventsources[i]); RegDeleteValueA(key, "Sources"); RegCloseKey(key); lret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, winesvc); - ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %d\n", lret); + ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %ld\n", lret); /* A handle to the eventlog is locked by services.exe. We can only * delete the eventlog file after reboot. */ bret = MoveFileExA(eventlogfile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); - ok(bret, "Expected MoveFileEx to succeed: %d\n", GetLastError()); + ok(bret, "Expected MoveFileEx to succeed: %ld\n", GetLastError()); +} + +static void test_trace_event_params(void) +{ + static const WCHAR emptyW[] = {0}; + static const GUID test_guid = {0x57696E65, 0x0000, 0x0000, {0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x01}}; + + REGHANDLE reg_handle; + ULONG uret; + + if (!pEventRegister) + { + win_skip("advapi32.EventRegister is missing, skipping trace event tests\n"); + return; + } + + uret = pEventRegister(NULL, NULL, NULL, ®_handle); + todo_wine ok(uret == ERROR_INVALID_PARAMETER, "EventRegister gave wrong error: %#lx\n", uret); + + uret = pEventRegister(&test_guid, NULL, NULL, NULL); + ok(uret == ERROR_INVALID_PARAMETER, "EventRegister gave wrong error: %#lx\n", uret); + + uret = pEventRegister(&test_guid, NULL, NULL, ®_handle); + ok(uret == ERROR_SUCCESS, "EventRegister gave wrong error: %#lx\n", uret); + + uret = pEventWriteString(0, 0, 0, emptyW); + todo_wine ok(uret == ERROR_INVALID_HANDLE, "EventWriteString gave wrong error: %#lx\n", uret); + + uret = pEventWriteString(reg_handle, 0, 0, NULL); + todo_wine ok(uret == ERROR_INVALID_PARAMETER, "EventWriteString gave wrong error: %#lx\n", uret); + + uret = pEventUnregister(0); + todo_wine ok(uret == ERROR_INVALID_HANDLE, "EventUnregister gave wrong error: %#lx\n", uret); + + uret = pEventUnregister(reg_handle); + ok(uret == ERROR_SUCCESS, "EventUnregister gave wrong error: %#lx\n", uret); } static void test_start_trace(void) @@ -1157,7 +1240,7 @@ static void test_start_trace(void) LONG ret; buffersize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(sessionname) + sizeof(filepath); - properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize); + properties = calloc(1, buffersize); properties->Wnode.BufferSize = buffersize; properties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; properties->LogFileMode = EVENT_TRACE_FILE_MODE_NONE; @@ -1170,37 +1253,37 @@ static void test_start_trace(void) todo_wine ok(ret == ERROR_BAD_LENGTH || ret == ERROR_INVALID_PARAMETER, /* XP and 2k3 */ - "Expected ERROR_BAD_LENGTH, got %d\n", ret); + "Expected ERROR_BAD_LENGTH, got %ld\n", ret); properties->Wnode.BufferSize = buffersize; ret = StartTraceA(&handle, "this name is too long", properties); todo_wine - ok(ret == ERROR_BAD_LENGTH, "Expected ERROR_BAD_LENGTH, got %d\n", ret); + ok(ret == ERROR_BAD_LENGTH, "Expected ERROR_BAD_LENGTH, got %ld\n", ret); ret = StartTraceA(&handle, sessionname, NULL); todo_wine - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); ret = StartTraceA(NULL, sessionname, properties); todo_wine - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); properties->LogFileNameOffset = 1; ret = StartTraceA(&handle, sessionname, properties); todo_wine - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); properties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(sessionname); properties->LoggerNameOffset = 1; ret = StartTraceA(&handle, sessionname, properties); todo_wine - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); properties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); properties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_FILE_MODE_CIRCULAR; ret = StartTraceA(&handle, sessionname, properties); todo_wine - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); properties->LogFileMode = EVENT_TRACE_FILE_MODE_NONE; /* XP creates a file we can't delete, so change the filepath to something else */ strcpy((char *)properties + properties->LogFileNameOffset, filepath2); @@ -1208,13 +1291,13 @@ static void test_start_trace(void) properties->Wnode.Guid = SystemTraceControlGuid; ret = StartTraceA(&handle, sessionname, properties); todo_wine - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); memset(&properties->Wnode.Guid, 0, sizeof(properties->Wnode.Guid)); properties->LogFileNameOffset = 0; ret = StartTraceA(&handle, sessionname, properties); todo_wine - ok(ret == ERROR_BAD_PATHNAME, "Expected ERROR_BAD_PATHNAME, got %d\n", ret); + ok(ret == ERROR_BAD_PATHNAME, "Expected ERROR_BAD_PATHNAME, got %ld\n", ret); properties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(sessionname); ret = StartTraceA(&handle, sessionname, properties); @@ -1223,21 +1306,445 @@ static void test_start_trace(void) skip("need admin rights\n"); goto done; } - ok(ret == ERROR_SUCCESS, "Expected success, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected success, got %ld\n", ret); ret = StartTraceA(&handle, sessionname, properties); todo_wine ok(ret == ERROR_ALREADY_EXISTS || ret == ERROR_SHARING_VIOLATION, /* 2k3 */ - "Expected ERROR_ALREADY_EXISTS, got %d\n", ret); + "Expected ERROR_ALREADY_EXISTS, got %ld\n", ret); /* clean up */ ControlTraceA(handle, sessionname, properties, EVENT_TRACE_CONTROL_STOP); done: - HeapFree(GetProcessHeap(), 0, properties); + free(properties); DeleteFileA(filepath); } +static BOOL read_record(HANDLE handle, DWORD flags, DWORD offset, EVENTLOGRECORD **record, DWORD *size) +{ + DWORD read, needed; + BOOL ret; + + SetLastError(0xdeadbeef); + memset(*record, 0, *size); + needed = 0; + if (!(ret = ReadEventLogW(handle, flags, offset, *record, *size, &read, &needed)) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + free(*record); + *record = malloc(needed); + SetLastError(0xdeadbeef); + memset(*record, 0, needed); + *size = needed; + ret = ReadEventLogW(handle, flags, offset, *record, *size, &read, &needed); + } + + return ret; +} + +static void test_eventlog_start(void) +{ + BOOL ret, found; + HANDLE handle, handle2; + EVENTLOGRECORD *record, *record2; + DWORD size, size2, count, count2, read, needed; + WCHAR *sourcename, *computername, *localcomputer; + char *sourcenameA, *computernameA, *localcomputerA; + + /* ReadEventLogW */ + handle = OpenEventLogW(0, L"System"); + if (!handle && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == RPC_S_SERVER_UNAVAILABLE)) + { + win_skip( "Can't open System event log\n" ); + return; + } + ok(handle != NULL, "OpenEventLogW(System) failed : %ld\n", GetLastError()); + handle2 = OpenEventLogW(0, L"System"); + todo_wine ok(handle != handle2, "Expected different handle\n"); + CloseEventLog(handle2); + + handle2 = OpenEventLogW(0, L"SYSTEM"); + ok(!!handle2, "Expected valid handle\n"); + CloseEventLog(handle2); + + size = MAX_COMPUTERNAME_LENGTH + 1; + localcomputer = malloc(size * sizeof(WCHAR)); + GetComputerNameW(localcomputer, &size); + + ret = TRUE; + found = FALSE; + while (!found && ret) + { + read = needed = 0; + record = malloc(sizeof(EVENTLOGRECORD)); + if (!(ret = ReadEventLogW(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, + 0, record, sizeof(EVENTLOGRECORD), &read, &needed)) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + record = realloc(record, needed); + ret = ReadEventLogW(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, + 0, record, needed, &read, &needed); + ok(needed == 0, "Expected 0, got %ld\n", needed); + } + if (ret && record->EventID == EVENT_EventlogStarted) + { + ok(record->Length == read, "Expected %ld, got %ld\n", read, record->Length); + ok(record->Reserved == 0x654c664c, "Expected 0x654c664c, got %ld\n", record->Reserved); + ok(record->RecordNumber > 0, "Expected 1 or higher, got %ld\n", record->RecordNumber); + ok(record->TimeGenerated == record->TimeWritten, "Expected time values to be the same\n"); + ok(record->EventType == EVENTLOG_INFORMATION_TYPE, + "Expected %d, got %d\n", EVENTLOG_INFORMATION_TYPE, record->EventType); +#ifdef __REACTOS__ + ok(record->NumStrings == 0 || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "Expected 0, got %d\n", record->NumStrings); +#else + ok(record->NumStrings == 0, "Expected 0, got %d\n", record->NumStrings); +#endif + ok(record->EventCategory == 0, "Expected 0, got %d\n", record->EventCategory); + ok(record->ReservedFlags == 0, "Expected 0, got %d\n", record->ReservedFlags); + ok(record->ClosingRecordNumber == 0, "Expected 0, got %ld\n", record->ClosingRecordNumber); + ok(record->StringOffset == record->UserSidOffset, "Expected offsets to be the same\n"); + ok(record->UserSidLength == 0, "Expected 0, got %ld\n", record->UserSidLength); +#ifdef __REACTOS__ + ok(record->DataLength == 24 || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "Expected 24, got %ld\n", record->DataLength); + ok(record->DataOffset == record->UserSidOffset || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "Expected offsets to be the same\n"); +#else + ok(record->DataLength == 24, "Expected 24, got %ld\n", record->DataLength); + ok(record->DataOffset == record->UserSidOffset, "Expected offsets to be the same\n"); +#endif + + sourcename = (WCHAR *)(record + 1); + ok(!lstrcmpW(sourcename, L"EventLog"), + "Expected 'EventLog', got '%ls'\n", sourcename); + + computername = sourcename + sizeof("EventLog"); + ok(!lstrcmpiW(computername, localcomputer), "Expected '%ls', got '%ls'\n", + localcomputer, computername); + + size = sizeof(EVENTLOGRECORD) + sizeof(L"EventLog") + + (lstrlenW(computername) + 1) * sizeof(WCHAR); + size = (size + 7) & ~7; +#ifdef __REACTOS__ + ok(record->DataOffset == size || broken(GetNTVersion() <= _WIN32_WINNT_WS03) || + broken(record->DataOffset == (sizeof(EVENTLOGRECORD) + sizeof(L"EventLog") + (lstrlenW(computername) + 1) * sizeof(WCHAR))) /* Vista */ || +#else + ok(record->DataOffset == size || +#endif + broken(record->DataOffset == size - sizeof(WCHAR)), /* win8 */ + "Expected %ld, got %ld\n", size, record->DataOffset); + + found = TRUE; + } + free(record); + } + todo_wine ok(found, "EventlogStarted event not found\n"); + CloseEventLog(handle); + free(localcomputer); + + /* ReadEventLogA */ + size = MAX_COMPUTERNAME_LENGTH + 1; + localcomputerA = malloc(size); + GetComputerNameA(localcomputerA, &size); + + handle = OpenEventLogA(0, "System"); + handle2 = OpenEventLogA(0, "SYSTEM"); + todo_wine ok(handle != handle2, "Expected different handle\n"); + CloseEventLog(handle2); + + ret = TRUE; + found = FALSE; + while (!found && ret) + { + read = needed = 0; + record = malloc(sizeof(EVENTLOGRECORD)); + if (!(ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, + 0, record, sizeof(EVENTLOGRECORD), &read, &needed)) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + record = realloc(record, needed); + ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, + 0, record, needed, &read, &needed); + ok(needed == 0, "Expected 0, got %ld\n", needed); + } + if (ret && record->EventID == EVENT_EventlogStarted) + { + ok(record->Length == read, "Expected %ld, got %ld\n", read, record->Length); + ok(record->Reserved == 0x654c664c, "Expected 0x654c664c, got %ld\n", record->Reserved); + ok(record->RecordNumber > 0, "Expected 1 or higher, got %ld\n", record->RecordNumber); + ok(record->TimeGenerated == record->TimeWritten, "Expected time values to be the same\n"); + ok(record->EventType == EVENTLOG_INFORMATION_TYPE, + "Expected %d, got %d\n", EVENTLOG_INFORMATION_TYPE, record->EventType); +#ifdef __REACTOS__ + ok(record->NumStrings == 0 || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "Expected 0, got %d\n", record->NumStrings); +#else + ok(record->NumStrings == 0, "Expected 0, got %d\n", record->NumStrings); +#endif + ok(record->EventCategory == 0, "Expected 0, got %d\n", record->EventCategory); + ok(record->ReservedFlags == 0, "Expected 0, got %d\n", record->ReservedFlags); + ok(record->ClosingRecordNumber == 0, "Expected 0, got %ld\n", record->ClosingRecordNumber); + ok(record->StringOffset == record->UserSidOffset, "Expected offsets to be the same\n"); + ok(record->UserSidLength == 0, "Expected 0, got %ld\n", record->UserSidLength); +#ifdef __REACTOS__ + ok(record->DataLength == 24 || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "Expected 24, got %ld\n", record->DataLength); + ok(record->DataOffset == record->UserSidOffset || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "Expected offsets to be the same\n"); +#else + ok(record->DataLength == 24, "Expected 24, got %ld\n", record->DataLength); + ok(record->DataOffset == record->UserSidOffset, "Expected offsets to be the same\n"); +#endif + + sourcenameA = (char *)(record + 1); + ok(!strcmp(sourcenameA, "EventLog"), + "Expected 'EventLog', got '%s'\n", sourcenameA); + + computernameA = sourcenameA + sizeof("EventLog"); + ok(!_stricmp(computernameA, localcomputerA), "Expected '%s', got '%s'\n", + localcomputerA, computernameA); + + size = sizeof(EVENTLOGRECORD) + sizeof("EventLog") + strlen(computernameA) + 1; + size = (size + 7) & ~7; +#ifdef __REACTOS__ + ok(record->DataOffset == size || broken(GetNTVersion() <= _WIN32_WINNT_WS03) || + broken(record->DataOffset == (sizeof(EVENTLOGRECORD) + sizeof("EventLog") + strlen(computernameA) + 1)) /* Vista */ || +#else + ok(record->DataOffset == size || +#endif + broken(record->DataOffset == size - 1), /* win8 */ + "Expected %ld, got %ld\n", size, record->DataOffset); + + found = TRUE; + } + free(record); + } + todo_wine ok(found, "EventlogStarted event not found\n"); + CloseEventLog(handle); + free(localcomputerA); + + /* SEQUENTIAL | FORWARDS - dwRecordOffset is ignored */ + handle = OpenEventLogW(0, L"System"); + size = sizeof(EVENTLOGRECORD) + 128; + record = malloc(size); + todo_wine { + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 100, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 1, "Expected 1, got %lu\n", record->RecordNumber); +#endif + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 200, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 2, "Expected 2, got %lu\n", record->RecordNumber); +#endif + + /* change direction sequentially */ + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 300, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 2, "Expected 2, got %lu\n", record->RecordNumber); +#endif + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 400, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 1, "Expected 1, got %lu\n", record->RecordNumber); +#endif + } + + /* changing how is an error */ + SetLastError(0xdeadbeef); + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, 0, &record, &size); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + CloseEventLog(handle); + + /* SEQUENTIAL | BACKWARDS - dwRecordOffset is ignored */ + handle = OpenEventLogW(0, L"System"); + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success : %ld\n", GetLastError()); + todo_wine + ok(count, "Zero records in log\n"); + + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 100, &record, &size); + todo_wine + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == count, "Expected %lu, got %lu\n", count, record->RecordNumber); +#endif + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 100, &record, &size); + todo_wine { + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == count - 1, "Expected %lu, got %lu\n", count - 1, record->RecordNumber); +#endif + } + CloseEventLog(handle); + + handle = OpenEventLogW(0, L"System"); + /* SEEK | FORWARDS */ + /* bogus offset */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, 0, &record, &size); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + count = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success : %ld\n", GetLastError()); + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, count + 1, &record, &size); +#ifdef __REACTOS__ + ok(!ret || broken(GetNTVersion() == _WIN32_WINNT_VISTA), "Expected failure\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == ERROR_SUCCESS) /* Vista */, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); +#else + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); +#endif + + todo_wine { + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, 2, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 2 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 2, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 2, "Expected 2, got %lu\n", record->RecordNumber); +#endif + /* skip one */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, 4, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 4 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 4, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 4, "Expected 4, got %lu\n", record->RecordNumber); +#endif + /* seek an earlier one */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, 3, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 3 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 3, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 3, "Expected 3, got %lu\n", record->RecordNumber); +#endif + /* change how */ + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 100, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 4 || broken(record->RecordNumber == 5) /* some win10 22h2 */, + "Expected 4, got %lu\n", record->RecordNumber); +#endif + /* change direction */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, 10, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 10 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 10, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 10, "Expected 10, got %lu\n", record->RecordNumber); +#endif + } + CloseEventLog(handle); + + /* SEEK | BACKWARDS */ + handle = OpenEventLogW(0, L"system"); + /* bogus offset */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, 0, &record, &size); + ok(!ret, "Expected failure\n"); + todo_wine + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + + todo_wine { + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, 5, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 5 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 5, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 5, "Expected 5, got %lu\n", record->RecordNumber); +#endif + /* skip one */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, 3, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 3 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 3, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 3, "Expected 3, got %lu\n", record->RecordNumber); +#endif + /* seek a later one */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, 4, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 4 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 4, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 4, "Expected 4, got %lu\n", record->RecordNumber); +#endif + /* change how */ + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 100, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 3 || broken(record->RecordNumber == 2) /* some win10 22h2 */, + "Expected 3, got %lu\n", record->RecordNumber); +#endif + /* change direction */ + ret = read_record(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, 10, &record, &size); +#ifdef __REACTOS__ + ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 10 || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Vista */, "Expected 10, got %lu\n", record->RecordNumber); +#else + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(record->RecordNumber == 10, "Expected 10, got %lu\n", record->RecordNumber); +#endif + } + CloseEventLog(handle); + + /* reading same log with different handles */ + handle = OpenEventLogW(0, L"System"); + handle2 = OpenEventLogW(0, L"SYSTEM"); + todo_wine { + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 1, "Expected 1, got %lu\n", record->RecordNumber); +#endif + ret = read_record(handle2, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); +#ifndef __REACTOS__ // Flaky on WS03 and Vista + ok(record->RecordNumber == 1, "Expected 1, got %lu\n", record->RecordNumber); +#endif + } + CloseEventLog(handle2); + CloseEventLog(handle); + + /* using source name */ + size2 = size; + record2 = malloc(size2); + handle = OpenEventLogW(0, L"System"); + handle2 = OpenEventLogW(0, L"EventLog"); + todo_wine { + ret = read_record(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, &record, &size); + ok(ret, "Expected success : %ld\n", GetLastError()); + ret = read_record(handle2, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, &record2, &size2); + ok(ret, "Expected success : %ld\n", GetLastError()); + } + ok(size == size2, "Expected %lu, got %lu\n", size, size2); + ok(!memcmp(record, record2, min(size, size2)), "Records miscompare\n"); + count = 0xdeadbeef; + count2 = 0xdeadbeef; + ret = GetNumberOfEventLogRecords(handle, &count); + ok(ret, "Expected success : %ld\n", GetLastError()); + ret = GetNumberOfEventLogRecords(handle2, &count2); + ok(ret, "Expected success : %ld\n", GetLastError()); + ok(count == count2, "Expected %lu, got %lu\n", count, count2); + CloseEventLog(handle2); + CloseEventLog(handle); + + free(record2); + free(record); +} + START_TEST(eventlog) { SetLastError(0xdeadbeef); @@ -1259,6 +1766,7 @@ START_TEST(eventlog) test_openbackup(); test_read(); test_clear(); + test_trace_event_params(); /* Functional tests */ if (create_new_eventlog()) @@ -1270,4 +1778,6 @@ START_TEST(eventlog) /* Trace tests */ test_start_trace(); + + test_eventlog_start(); } diff --git a/modules/rostests/winetests/advapi32/lsa.c b/modules/rostests/winetests/advapi32/lsa.c index dcdcdc8b1e6..f09f240952c 100644 --- a/modules/rostests/winetests/advapi32/lsa.c +++ b/modules/rostests/winetests/advapi32/lsa.c @@ -2,6 +2,7 @@ * Unit tests for lsa functions * * Copyright (c) 2006 Robert Reif + * Copyright (c) 2020 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,26 +27,22 @@ #include "windef.h" #include "winbase.h" #include "winreg.h" -#ifndef __REACTOS__ #include "ntsecapi.h" -#endif #include "sddl.h" #include "winnls.h" #include "objbase.h" #include "initguid.h" #include "wine/test.h" #include "winternl.h" -#ifdef __REACTOS__ -#include -#endif #include "ntlsa.h" DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); +static BOOL (WINAPI *pGetSystemPreferredUILanguages)(DWORD, ULONG*, WCHAR*, ULONG*); +static NTSTATUS (WINAPI *pLsaGetUserName)(PUNICODE_STRING *user, PUNICODE_STRING *domain); + static void test_lsa(void) { - static WCHAR machineW[] = {'W','i','n','e','N','o','M','a','c','h','i','n','e',0}; - LSA_UNICODE_STRING machine; NTSTATUS status; LSA_HANDLE handle; LSA_OBJECT_ATTRIBUTES object_attributes; @@ -53,23 +50,15 @@ static void test_lsa(void) ZeroMemory(&object_attributes, sizeof(object_attributes)); object_attributes.Length = sizeof(object_attributes); - machine.Buffer = machineW; - machine.Length = sizeof(machineW) - 2; - machine.MaximumLength = sizeof(machineW); - - status = LsaOpenPolicy( &machine, &object_attributes, POLICY_LOOKUP_NAMES, &handle); - ok(status == RPC_NT_SERVER_UNAVAILABLE, - "LsaOpenPolicy(POLICY_LOOKUP_NAMES) for invalid machine returned 0x%08x\n", status); - status = LsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle); ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, - "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status); + "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08lx\n", status); /* try a more restricted access mask if necessary */ if (status == STATUS_ACCESS_DENIED) { trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES\n"); status = LsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES, &handle); - ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES) returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES) returned 0x%08lx\n", status); } if (status == STATUS_SUCCESS) { @@ -84,12 +73,12 @@ static void test_lsa(void) if (status == STATUS_ACCESS_DENIED) skip("Not enough rights to retrieve PolicyAuditEventsInformation\n"); else - ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAuditEventsInformation) failed, returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAuditEventsInformation) failed, returned 0x%08lx\n", status); if (status == STATUS_SUCCESS) LsaFreeMemory(audit_events_info); status = LsaQueryInformationPolicy(handle, PolicyPrimaryDomainInformation, (void **)&primary_domain_info); - ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyPrimaryDomainInformation) failed, returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyPrimaryDomainInformation) failed, returned 0x%08lx\n", status); if (status == STATUS_SUCCESS) { if (primary_domain_info->Sid) { LPSTR strsid; @@ -116,29 +105,22 @@ static void test_lsa(void) } status = LsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (void **)&account_domain_info); - ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) failed, returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) failed, returned 0x%08lx\n", status); if (status == STATUS_SUCCESS) LsaFreeMemory(account_domain_info); /* This isn't supported in NT4 */ status = LsaQueryInformationPolicy(handle, PolicyDnsDomainInformation, (void **)&dns_domain_info); ok(status == STATUS_SUCCESS || status == STATUS_INVALID_PARAMETER, - "LsaQueryInformationPolicy(PolicyDnsDomainInformation) failed, returned 0x%08x\n", status); + "LsaQueryInformationPolicy(PolicyDnsDomainInformation) failed, returned 0x%08lx\n", status); if (status == STATUS_SUCCESS) { if (dns_domain_info->Sid || !IsEqualGUID(&dns_domain_info->DomainGuid, &GUID_NULL)) { LPSTR strsid = NULL; LPSTR name = NULL; LPSTR domain = NULL; LPSTR forest = NULL; - LPSTR guidstr = NULL; - WCHAR guidstrW[64]; UINT len; - guidstrW[0] = '\0'; ConvertSidToStringSidA(dns_domain_info->Sid, &strsid); - StringFromGUID2(&dns_domain_info->DomainGuid, guidstrW, sizeof(guidstrW)/sizeof(WCHAR)); - len = WideCharToMultiByte( CP_ACP, 0, guidstrW, -1, NULL, 0, NULL, NULL ); - guidstr = LocalAlloc( 0, len ); - WideCharToMultiByte( CP_ACP, 0, guidstrW, -1, guidstr, len, NULL, NULL ); if (dns_domain_info->Name.Buffer) { len = WideCharToMultiByte( CP_ACP, 0, dns_domain_info->Name.Buffer, -1, NULL, 0, NULL, NULL ); name = LocalAlloc( 0, len ); @@ -155,12 +137,11 @@ static void test_lsa(void) WideCharToMultiByte( CP_ACP, 0, dns_domain_info->DnsForestName.Buffer, -1, forest, len, NULL, NULL ); } trace(" name: %s domain: %s forest: %s guid: %s sid: %s\n", - name ? name : "NULL", domain ? domain : "NULL", - forest ? forest : "NULL", guidstr, strsid ? strsid : "NULL"); + debugstr_a(name), debugstr_a(domain), debugstr_a(forest), + debugstr_guid(&dns_domain_info->DomainGuid), debugstr_a(strsid)); LocalFree( name ); LocalFree( forest ); LocalFree( domain ); - LocalFree( guidstr ); LocalFree( strsid ); } else @@ -170,15 +151,15 @@ static void test_lsa(void) /* We need a valid SID to pass to LsaEnumerateAccountRights */ ret = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ); - ok(ret, "Unable to obtain process token, error %u\n", GetLastError( )); + ok(ret, "Unable to obtain process token, error %lu\n", GetLastError( )); if (ret) { char buffer[64]; DWORD len; TOKEN_USER *token_user = (TOKEN_USER *) buffer; ret = GetTokenInformation( token, TokenUser, (LPVOID) token_user, sizeof(buffer), &len ); - ok(ret || GetLastError( ) == ERROR_INSUFFICIENT_BUFFER, "Unable to obtain token information, error %u\n", GetLastError( )); + ok(ret || GetLastError( ) == ERROR_INSUFFICIENT_BUFFER, "Unable to obtain token information, error %lu\n", GetLastError( )); if (! ret && GetLastError( ) == ERROR_INSUFFICIENT_BUFFER) { - trace("Resizing buffer to %u.\n", len); + trace("Resizing buffer to %lu.\n", len); token_user = LocalAlloc( 0, len ); if (token_user != NULL) ret = GetTokenInformation( token, TokenUser, (LPVOID) token_user, len, &len ); @@ -190,7 +171,7 @@ static void test_lsa(void) rights = (PLSA_UNICODE_STRING) 0xdeadbeaf; rights_count = 0xcafecafe; status = LsaEnumerateAccountRights(handle, token_user->User.Sid, &rights, &rights_count); - ok(status == STATUS_SUCCESS || status == STATUS_OBJECT_NAME_NOT_FOUND, "Unexpected status 0x%x\n", status); + ok(status == STATUS_SUCCESS || status == STATUS_OBJECT_NAME_NOT_FOUND, "Unexpected status 0x%lx\n", status); if (status == STATUS_SUCCESS) LsaFreeMemory( rights ); else @@ -202,7 +183,7 @@ static void test_lsa(void) } status = LsaClose(handle); - ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08lx\n", status); } } @@ -219,7 +200,7 @@ static void get_sid_info(PSID psid, LPSTR *user, LPSTR *dom) user_size = dom_size = 257; account[0] = domain[0] = 0; ret = LookupAccountSidA(NULL, psid, account, &user_size, domain, &dom_size, &use); - ok(ret, "LookupAccountSidA failed %u\n", GetLastError()); + ok(ret, "LookupAccountSidA failed %lu\n", GetLastError()); } static void test_LsaLookupNames2(void) @@ -247,14 +228,14 @@ static void test_LsaLookupNames2(void) status = LsaOpenPolicy(NULL, &attrs, POLICY_ALL_ACCESS, &handle); ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, - "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status); + "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08lx\n", status); /* try a more restricted access mask if necessary */ if (status == STATUS_ACCESS_DENIED) { trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n"); status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &handle); - ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08lx\n", status); } if (status != STATUS_SUCCESS) { @@ -262,15 +243,15 @@ static void test_LsaLookupNames2(void) return; } - name[0].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1)); + name[0].Buffer = malloc(sizeof(n1)); name[0].Length = name[0].MaximumLength = sizeof(n1); memcpy(name[0].Buffer, n1, sizeof(n1)); - name[1].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1)); + name[1].Buffer = malloc(sizeof(n1)); name[1].Length = name[1].MaximumLength = sizeof(n1) - sizeof(WCHAR); memcpy(name[1].Buffer, n1, sizeof(n1) - sizeof(WCHAR)); - name[2].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n2)); + name[2].Buffer = malloc(sizeof(n2)); name[2].Length = name[2].MaximumLength = sizeof(n2); memcpy(name[2].Buffer, n2, sizeof(n2)); @@ -278,10 +259,10 @@ static void test_LsaLookupNames2(void) sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 1, &name[0], &domains, &sids); - ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\n", status); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %lx)\n", status); ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use); - ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags); - ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries); + ok(sids[0].Flags == 0, "expected 0, got 0x%08lx\n", sids[0].Flags); + ok(domains->Entries == 1, "expected 1, got %lu\n", domains->Entries); get_sid_info(sids[0].Sid, &account, &sid_dom); ok(!strcmp(account, "LOCAL SERVICE"), "expected \"LOCAL SERVICE\", got \"%s\"\n", account); ok(!strcmp(sid_dom, "NT AUTHORITY"), "expected \"NT AUTHORITY\", got \"%s\"\n", sid_dom); @@ -292,10 +273,10 @@ static void test_LsaLookupNames2(void) sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 1, &name[1], &domains, &sids); - ok(status == STATUS_NONE_MAPPED, "expected STATUS_NONE_MAPPED, got %x)\n", status); + ok(status == STATUS_NONE_MAPPED, "expected STATUS_NONE_MAPPED, got %lx)\n", status); ok(sids[0].Use == SidTypeUnknown, "expected SidTypeUnknown, got %u\n", sids[0].Use); - ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags); - ok(domains->Entries == 0, "expected 0, got %u\n", domains->Entries); + ok(sids[0].Flags == 0, "expected 0, got 0x%08lx\n", sids[0].Flags); + ok(domains->Entries == 0, "expected 0, got %lu\n", domains->Entries); LsaFreeMemory(sids); LsaFreeMemory(domains); @@ -303,10 +284,10 @@ static void test_LsaLookupNames2(void) sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 1, &name[2], &domains, &sids); - ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\n", status); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %lx)\n", status); ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use); - ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags); - ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries); + ok(sids[0].Flags == 0, "expected 0, got 0x%08lx\n", sids[0].Flags); + ok(domains->Entries == 1, "expected 1, got %lu\n", domains->Entries); get_sid_info(sids[0].Sid, &account, &sid_dom); ok(!strcmp(account, "LOCAL SERVICE"), "expected \"LOCAL SERVICE\", got \"%s\"\n", account); ok(!strcmp(sid_dom, "NT AUTHORITY"), "expected \"NT AUTHORITY\", got \"%s\"\n", sid_dom); @@ -317,95 +298,140 @@ static void test_LsaLookupNames2(void) sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 3, name, &domains, &sids); - ok(status == STATUS_SOME_NOT_MAPPED, "expected STATUS_SOME_NOT_MAPPED, got %x)\n", status); + ok(status == STATUS_SOME_NOT_MAPPED, "expected STATUS_SOME_NOT_MAPPED, got %lx)\n", status); ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use); ok(sids[1].Use == SidTypeUnknown, "expected SidTypeUnknown, got %u\n", sids[1].Use); ok(sids[2].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[2].Use); - ok(sids[0].DomainIndex == 0, "expected 0, got %u\n", sids[0].DomainIndex); - ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries); + ok(sids[0].DomainIndex == 0, "expected 0, got %lu\n", sids[0].DomainIndex); + ok(domains->Entries == 1, "expected 1, got %lu\n", domains->Entries); LsaFreeMemory(sids); LsaFreeMemory(domains); - HeapFree(GetProcessHeap(), 0, name[0].Buffer); - HeapFree(GetProcessHeap(), 0, name[1].Buffer); - HeapFree(GetProcessHeap(), 0, name[2].Buffer); + free(name[0].Buffer); + free(name[1].Buffer); + free(name[2].Buffer); status = LsaClose(handle); - ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08lx\n", status); } +static void check_unicode_string_(int line, const LSA_UNICODE_STRING *string, const WCHAR *expect) +{ + ok_(__FILE__, line)(string->Length == wcslen(string->Buffer) * sizeof(WCHAR), + "expected %Iu, got %u\n", wcslen(string->Buffer) * sizeof(WCHAR), string->Length); + ok_(__FILE__, line)(string->MaximumLength == string->Length + sizeof(WCHAR), + "expected %Iu, got %u\n", string->Length + sizeof(WCHAR), string->MaximumLength); + ok_(__FILE__, line)(!wcsicmp(string->Buffer, expect), "expected %s, got %s\n", + debugstr_w(expect), debugstr_w(string->Buffer)); +} +#define check_unicode_string(a, b) check_unicode_string_(__LINE__, a, b) + static void test_LsaLookupSids(void) { + WCHAR langW[32]; + char user_buffer[64]; + LSA_OBJECT_ATTRIBUTES attrs = {sizeof(attrs)}; + TOKEN_USER *user = (TOKEN_USER *)user_buffer; + WCHAR computer_name[64], user_name[64]; LSA_REFERENCED_DOMAIN_LIST *list; - LSA_OBJECT_ATTRIBUTES attrs; LSA_TRANSLATED_NAME *names; LSA_HANDLE policy; - TOKEN_USER *user; NTSTATUS status; HANDLE token; - DWORD size; + DWORD num, size; BOOL ret; PSID sid; - memset(&attrs, 0, sizeof(attrs)); - attrs.Length = sizeof(attrs); - status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); - ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status); ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); - ok(ret, "got %d\n", ret); + ok(ret, "OpenProcessToken() failed, error %lu\n", GetLastError()); - ret = GetTokenInformation(token, TokenUser, NULL, 0, &size); - ok(!ret, "got %d\n", ret); + ret = GetTokenInformation(token, TokenUser, user, sizeof(user_buffer), &size); + ok(ret, "GetTokenInformation() failed, error %lu\n", GetLastError()); - user = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetTokenInformation(token, TokenUser, user, size, &size); - ok(ret, "got %d\n", ret); + size = ARRAY_SIZE(computer_name); + ret = GetComputerNameW(computer_name, &size); + ok(ret, "GetComputerName() failed, error %lu\n", GetLastError()); + + size = ARRAY_SIZE(user_name); + ret = GetUserNameW(user_name, &size); + ok(ret, "GetUserName() failed, error %lu\n", GetLastError()); status = LsaLookupSids(policy, 1, &user->User.Sid, &list, &names); - ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status); - ok(list->Entries > 0, "got %d\n", list->Entries); - if (list->Entries) - { - ok((char*)list->Domains - (char*)list > 0, "%p, %p\n", list, list->Domains); - ok((char*)list->Domains[0].Sid - (char*)list->Domains > 0, "%p, %p\n", list->Domains, list->Domains[0].Sid); - ok(list->Domains[0].Name.MaximumLength > list->Domains[0].Name.Length, "got %d, %d\n", list->Domains[0].Name.MaximumLength, - list->Domains[0].Name.Length); - } + ok(list->Entries == 1, "got %ld\n", list->Entries); + check_unicode_string(&list->Domains[0].Name, computer_name); + + ok(names[0].Use == SidTypeUser, "got type %u\n", names[0].Use); + ok(!names[0].DomainIndex, "got index %lu\n", names[0].DomainIndex); + check_unicode_string(&names[0].Name, user_name); LsaFreeMemory(names); LsaFreeMemory(list); - - HeapFree(GetProcessHeap(), 0, user); - CloseHandle(token); ret = ConvertStringSidToSidA("S-1-1-0", &sid); - ok(ret == TRUE, "ConvertStringSidToSidA returned false\n"); + ok(ret, "ConvertStringSidToSidA() failed, error %lu\n", GetLastError()); status = LsaLookupSids(policy, 1, &sid, &list, &names); - ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status); - ok(list->Entries > 0, "got %d\n", list->Entries); + ok(list->Entries == 1, "got %ld\n", list->Entries); + check_unicode_string(&list->Domains[0].Name, L""); - if (list->Entries) - { - ok((char*)list->Domains - (char*)list > 0, "%p, %p\n", list, list->Domains); - ok((char*)list->Domains[0].Sid - (char*)list->Domains > 0, "%p, %p\n", list->Domains, list->Domains[0].Sid); - ok(list->Domains[0].Name.MaximumLength > list->Domains[0].Name.Length, "got %d, %d\n", list->Domains[0].Name.MaximumLength, - list->Domains[0].Name.Length); - ok(list->Domains[0].Name.Buffer != NULL, "domain[0] name buffer is null\n"); - } + ok(names[0].Use == SidTypeWellKnownGroup, "got type %u\n", names[0].Use); + ok(!names[0].DomainIndex, "got index %lu\n", names[0].DomainIndex); + + /* The group name gets translated... but not in all locales */ + size = ARRAY_SIZE(langW); + if (!pGetSystemPreferredUILanguages || + !pGetSystemPreferredUILanguages(MUI_LANGUAGE_ID, &num, langW, &size)) + langW[0] = 0; + if (wcscmp(langW, L"0409") == 0 || wcscmp(langW, L"0411") == 0) + /* English and Japanese */ + check_unicode_string(&names[0].Name, L"Everyone"); + else if (wcscmp(langW, L"0407") == 0) /* German */ + todo_wine ok(!wcsicmp(names[0].Name.Buffer, L"Jeder"), "missing translation %s\n", + debugstr_w(names[0].Name.Buffer)); + else if (wcscmp(langW, L"040C") == 0) /* French */ + todo_wine ok(!wcsicmp(names[0].Name.Buffer, L"Tout le monde"), "missing translation %s\n", + debugstr_w(names[0].Name.Buffer)); + else + trace(".Name=%s\n", debugstr_w(names[0].Name.Buffer)); LsaFreeMemory(names); LsaFreeMemory(list); + FreeSid(sid); + ret = ConvertStringSidToSidA("S-1-1234-5678-1234-5678", &sid); + ok(ret, "ConvertStringSidToSidA() failed, error %lu\n", GetLastError()); + + status = LsaLookupSids(policy, 1, &sid, &list, &names); + ok(status == STATUS_NONE_MAPPED, "got 0x%08lx\n", status); + + ok(!list->Entries, "got %ld\n", list->Entries); + +#ifdef __REACTOS__ + if (!names) { + ok(FALSE, "names should not be null!\n"); + } else { +#endif + ok(names[0].Use == SidTypeUnknown, "got type %u\n", names[0].Use); + ok(names[0].DomainIndex == -1, "got index %lu\n", names[0].DomainIndex); + check_unicode_string(&names[0].Name, L"S-1-1234-5678-1234-5678"); +#ifdef __REACTOS__ + } +#endif + + LsaFreeMemory(names); + LsaFreeMemory(list); FreeSid(sid); status = LsaClose(policy); - ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); + ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status); } static void test_LsaLookupPrivilegeName(void) @@ -420,31 +446,86 @@ static void test_LsaLookupPrivilegeName(void) attrs.Length = sizeof(attrs); status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); - ok(status == STATUS_SUCCESS, "Failed to open policy, %#x.\n", status); + ok(status == STATUS_SUCCESS, "Failed to open policy, %#lx.\n", status); name = (void *)0xdeadbeef; status = LsaLookupPrivilegeName(policy, NULL, &name); - ok(status != STATUS_SUCCESS, "Unexpected status %#x.\n", status); + ok(status != STATUS_SUCCESS, "Unexpected status %#lx.\n", status); ok(name == (void *)0xdeadbeef, "Unexpected name pointer.\n"); name = (void *)0xdeadbeef; luid.HighPart = 1; luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; status = LsaLookupPrivilegeName(policy, &luid, &name); - ok(status == STATUS_NO_SUCH_PRIVILEGE, "Unexpected status %#x.\n", status); + ok(status == STATUS_NO_SUCH_PRIVILEGE, "Unexpected status %#lx.\n", status); ok(name == NULL, "Unexpected name pointer.\n"); luid.HighPart = 0; luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; status = LsaLookupPrivilegeName(policy, &luid, &name); - ok(status == 0, "got %#x.\n", status); + ok(status == 0, "got %#lx.\n", status); LsaFreeMemory(name); } +static void test_LsaGetUserName(void) +{ + NTSTATUS status; + BOOL ret; + UNICODE_STRING *lsa_user, *lsa_domain; + WCHAR user[256], computer[256]; + DWORD size; + + if (!pLsaGetUserName) + { + skip("LsaGetUserName is not available on this platform\n"); + return; + } + + size = ARRAY_SIZE(user); + ret = GetUserNameW(user, &size); + ok(ret, "GetUserName error %lu\n", GetLastError()); + + size = ARRAY_SIZE(computer); + ret = GetComputerNameW(computer, &size); + ok(ret, "GetComputerName error %lu\n", GetLastError()); + + if (0) /* crashes under Windows */ + status = pLsaGetUserName(NULL, NULL); + + if (0) /* crashes under Windows */ + status = pLsaGetUserName(NULL, &lsa_domain); + + status = pLsaGetUserName(&lsa_user, NULL); + ok(!status, "got %#lx\n", status); +#ifdef __REACTOS__ + if (status == STATUS_NOT_IMPLEMENTED) { + skip("FIXME: LsaGetUserName not implemented on ReactOS!\n"); + return; + } +#endif + check_unicode_string(lsa_user, user); + LsaFreeMemory(lsa_user); + + status = pLsaGetUserName(&lsa_user, &lsa_domain); + ok(!status, "got %#lx\n", status); + ok(!lstrcmpW(user, lsa_user->Buffer), "%s != %s\n", wine_dbgstr_w(user), wine_dbgstr_wn(lsa_user->Buffer, lsa_user->Length/sizeof(WCHAR))); + check_unicode_string(lsa_user, user); + check_unicode_string(lsa_domain, computer); + LsaFreeMemory(lsa_user); + LsaFreeMemory(lsa_domain); +} + START_TEST(lsa) { + HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); + HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); + + pGetSystemPreferredUILanguages = (void*)GetProcAddress(hkernel32, "GetSystemPreferredUILanguages"); + pLsaGetUserName = (void *)GetProcAddress(hadvapi32, "LsaGetUserName"); + test_lsa(); test_LsaLookupNames2(); test_LsaLookupSids(); test_LsaLookupPrivilegeName(); + test_LsaGetUserName(); } diff --git a/modules/rostests/winetests/advapi32/perf.c b/modules/rostests/winetests/advapi32/perf.c new file mode 100644 index 00000000000..4cbc7b94473 --- /dev/null +++ b/modules/rostests/winetests/advapi32/perf.c @@ -0,0 +1,305 @@ +/* + * Unit tests for Perflib functions + * + * Copyright (c) 2021 Paul Gofman for CodeWeavers + * + * 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 + */ + +#include + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "perflib.h" +#include "winperf.h" +#include "winternl.h" + +#include "wine/test.h" + +#include "initguid.h" + +ULONG (WINAPI *pPerfCloseQueryHandle)(HANDLE); +ULONG (WINAPI *pPerfOpenQueryHandle)(const WCHAR*, HANDLE*); +ULONG (WINAPI *pPerfAddCounters)(HANDLE, PERF_COUNTER_IDENTIFIER*, DWORD); +ULONG (WINAPI *pPerfQueryCounterData)(HANDLE, PERF_DATA_HEADER*, DWORD, DWORD*); + +static void init_functions(void) +{ + HANDLE hadvapi = GetModuleHandleA("advapi32.dll"); + +#define GET_FUNCTION(name) p##name = (void *)GetProcAddress(hadvapi, #name) + GET_FUNCTION(PerfCloseQueryHandle); + GET_FUNCTION(PerfOpenQueryHandle); + GET_FUNCTION(PerfAddCounters); + GET_FUNCTION(PerfQueryCounterData); +#undef GET_FUNCTION +} + +static ULONG WINAPI test_provider_callback(ULONG code, void *buffer, ULONG size) +{ + ok(0, "Provider callback called.\n"); + return ERROR_SUCCESS; +} + +void test_provider_init(void) +{ +#ifdef __REACTOS__ + skip("test_provider_init() can't be built until ReactOS has implementations for Perf* functions.\n"); +#else + static GUID test_set_guid = {0xdeadbeef, 0x0002, 0x0003, {0x0f, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}}; + static GUID test_set_guid2 = {0xdeadbeef, 0x0003, 0x0003, {0x0f, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}}; + static GUID test_guid = {0xdeadbeef, 0x0001, 0x0002, {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00 ,0x0a}}; + static struct + { + PERF_COUNTERSET_INFO counterset; + PERF_COUNTER_INFO counter[2]; + } + pc_template = + { + {{0}}, + { + {1, PERF_COUNTER_COUNTER, PERF_ATTRIB_BY_REFERENCE, sizeof(PERF_COUNTER_INFO), + PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, + {2, PERF_COUNTER_COUNTER, PERF_ATTRIB_BY_REFERENCE, sizeof(PERF_COUNTER_INFO), + PERF_DETAIL_NOVICE, 0, 0xdeadbeef}, + }, + }; + + PERF_COUNTERSET_INSTANCE *instance; + PERF_PROVIDER_CONTEXT prov_context; + UINT64 counter1, counter2; + HANDLE prov, prov2; + ULONG ret, size; + BOOL bret; + + prov = (HANDLE)0xdeadbeef; + ret = PerfStartProvider(NULL, test_provider_callback, &prov); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(prov == (HANDLE)0xdeadbeef, "Got unexpected prov %p.\n", prov); + + prov = (HANDLE)0xdeadbeef; + ret = PerfStartProvider(&test_guid, test_provider_callback, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(prov == (HANDLE)0xdeadbeef, "Got unexpected prov %p.\n", prov); + + prov = (HANDLE)0xdeadbeef; + ret = PerfStartProvider(&test_guid, test_provider_callback, &prov); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ok(prov != (HANDLE)0xdeadbeef, "Provider handle is not set.\n"); + + prov2 = prov; + ret = PerfStartProvider(&test_guid, test_provider_callback, &prov2); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ok(prov2 != prov, "Got the same provider handle.\n"); + + ret = PerfStopProvider(prov2); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + if (0) + { + /* Access violation on Windows. */ + PerfStopProvider(prov2); + } + + /* Provider handle is a pointer and not a kernel object handle. */ + bret = DuplicateHandle(GetCurrentProcess(), prov, GetCurrentProcess(), &prov2, 0, FALSE, DUPLICATE_SAME_ACCESS); + ok(!bret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected bret %d, err %lu.\n", bret, GetLastError()); + bret = IsBadWritePtr(prov, 8); + ok(!bret, "Handle does not point to the data.\n"); + + pc_template.counterset.CounterSetGuid = test_set_guid; + pc_template.counterset.ProviderGuid = test_guid; + pc_template.counterset.NumCounters = 0; + pc_template.counterset.InstanceType = PERF_COUNTERSET_SINGLE_INSTANCE; + ret = PerfSetCounterSetInfo(prov, &pc_template.counterset, sizeof(pc_template.counterset)); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + + pc_template.counterset.CounterSetGuid = test_set_guid; + pc_template.counterset.ProviderGuid = test_guid; + pc_template.counterset.NumCounters = 2; + pc_template.counterset.InstanceType = PERF_COUNTERSET_SINGLE_INSTANCE; + ret = PerfSetCounterSetInfo(prov, &pc_template.counterset, sizeof(pc_template)); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + pc_template.counterset.CounterSetGuid = test_set_guid2; + /* Looks like ProviderGuid doesn't need to match provider. */ + pc_template.counterset.ProviderGuid = test_set_guid; + pc_template.counterset.NumCounters = 1; + pc_template.counterset.InstanceType = PERF_COUNTERSET_SINGLE_INSTANCE; + ret = PerfSetCounterSetInfo(prov, &pc_template.counterset, sizeof(pc_template)); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetCounterSetInfo(prov, &pc_template.counterset, sizeof(pc_template)); + ok(ret == ERROR_ALREADY_EXISTS, "Got unexpected ret %lu.\n", ret); + + SetLastError(0xdeadbeef); + instance = PerfCreateInstance(prov, NULL, L"1", 1); + ok(!instance, "Got unexpected instance %p.\n", instance); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %lu.\n", GetLastError()); + + SetLastError(0xdeadbeef); + instance = PerfCreateInstance(prov, &test_guid, L"1", 1); + ok(!instance, "Got unexpected instance %p.\n", instance); + ok(GetLastError() == ERROR_NOT_FOUND, "Got unexpected error %lu.\n", GetLastError()); + + SetLastError(0xdeadbeef); + instance = PerfCreateInstance(prov, &test_guid, NULL, 1); + ok(!instance, "Got unexpected instance %p.\n", instance); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %lu.\n", GetLastError()); + + SetLastError(0xdeadbeef); + instance = PerfCreateInstance(prov, &test_set_guid, L"11", 1); + ok(!!instance, "Got NULL instance.\n"); + ok(GetLastError() == 0xdeadbeef, "Got unexpected error %lu.\n", GetLastError()); + ok(instance->InstanceId == 1, "Got unexpected InstanceId %lu.\n", instance->InstanceId); + ok(instance->InstanceNameSize == 6, "Got unexpected InstanceNameSize %lu.\n", instance->InstanceNameSize); + ok(IsEqualGUID(&instance->CounterSetGuid, &test_set_guid), "Got unexpected guid %s.\n", + debugstr_guid(&instance->CounterSetGuid)); + + ok(instance->InstanceNameOffset == sizeof(*instance) + sizeof(UINT64) * 2, + "Got unexpected InstanceNameOffset %lu.\n", instance->InstanceNameOffset); + ok(!lstrcmpW((WCHAR *)((BYTE *)instance + instance->InstanceNameOffset), L"11"), + "Got unexpected instance name %s.\n", + debugstr_w((WCHAR *)((BYTE *)instance + instance->InstanceNameOffset))); + size = ((sizeof(*instance) + sizeof(UINT64) * 2 + instance->InstanceNameSize) + 7) & ~7; + ok(size == instance->dwSize, "Got unexpected size %lu, instance->dwSize %lu.\n", size, instance->dwSize); + + ret = PerfSetCounterRefValue(prov, instance, 1, &counter1); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ret = PerfSetCounterRefValue(prov, instance, 2, &counter2); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfSetCounterRefValue(prov, instance, 0, &counter2); + ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %lu.\n", ret); + + ok(*(void **)(instance + 1) == &counter1, "Got unexpected counter value %p.\n", + *(void **)(instance + 1)); + ok(*(void **)((BYTE *)instance + sizeof(*instance) + sizeof(UINT64)) == &counter2, + "Got unexpected counter value %p.\n", *(void **)(instance + 1)); + + ret = PerfDeleteInstance(prov, instance); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + ret = PerfStopProvider(prov); + ok(!ret, "Got unexpected ret %lu.\n", ret); + + memset( &prov_context, 0, sizeof(prov_context) ); + prov = (HANDLE)0xdeadbeef; + ret = PerfStartProviderEx( &test_guid, &prov_context, &prov ); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret); + ok(prov == (HANDLE)0xdeadbeef, "Got unexpected prov %p.\n", prov); + + prov_context.ContextSize = sizeof(prov_context) + 1; + ret = PerfStartProviderEx( &test_guid, &prov_context, &prov ); + ok(!ret, "Got unexpected ret %lu.\n", ret); + ok(prov != (HANDLE)0xdeadbeef, "Provider handle is not set.\n"); + + ret = PerfStopProvider(prov); + ok(!ret, "Got unexpected ret %lu.\n", ret); +#endif +} + +DEFINE_GUID(TestCounterGUID, 0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33); + +static ULONG64 trunc_nttime_ms(ULONG64 t) +{ + return (t / 10000) * 10000; +} + +static void test_perf_counters(void) +{ + LARGE_INTEGER freq, qpc1, qpc2, nttime1, nttime2, systime; + char buffer[sizeof(PERF_COUNTER_IDENTIFIER) + 8]; + PERF_COUNTER_IDENTIFIER *counter_id; + PERF_DATA_HEADER dh; + HANDLE query; + DWORD size; + ULONG ret; + + if (!pPerfOpenQueryHandle) + { + win_skip("PerfOpenQueryHandle not found.\n"); + return; + } + + ret = pPerfOpenQueryHandle(NULL, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "got ret %lu.\n", ret); + ret = pPerfOpenQueryHandle(NULL, &query); + ok(!ret, "got ret %lu.\n", ret); + + counter_id = (PERF_COUNTER_IDENTIFIER *)buffer; + memset(buffer, 0, sizeof(buffer)); + + counter_id->CounterSetGuid = TestCounterGUID; + counter_id->CounterId = PERF_WILDCARD_COUNTER; + counter_id->InstanceId = PERF_WILDCARD_COUNTER; + + ret = pPerfAddCounters(query, counter_id, sizeof(*counter_id)); + ok(ret == ERROR_INVALID_PARAMETER, "got ret %lu.\n", ret); + + counter_id->Size = sizeof(*counter_id); + ret = pPerfAddCounters(query, counter_id, 8); + ok(ret == ERROR_INVALID_PARAMETER, "got ret %lu.\n", ret); + ret = pPerfAddCounters(query, counter_id, sizeof(*counter_id)); + ok(!ret, "got ret %lu.\n", ret); + ok(counter_id->Status == ERROR_WMI_GUID_NOT_FOUND, "got Status %#lx.\n", counter_id->Status); + + ret = pPerfQueryCounterData(query, NULL, 0, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "got ret %lu.\n", ret); + + size = 0xdeadbeef; + ret = pPerfQueryCounterData(query, NULL, 0, &size); + ok(ret == ERROR_NOT_ENOUGH_MEMORY, "got ret %lu.\n", ret); + ok(size == sizeof(dh), "got size %lu.\n", size); + + ret = pPerfQueryCounterData(query, &dh, sizeof(dh), NULL); + ok(ret == ERROR_INVALID_PARAMETER, "got ret %lu.\n", ret); + + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&qpc1); + NtQuerySystemTime(&nttime1); + + size = 0xdeadbeef; + ret = pPerfQueryCounterData(query, &dh, sizeof(dh), &size); + QueryPerformanceCounter(&qpc2); + NtQuerySystemTime(&nttime2); + SystemTimeToFileTime(&dh.SystemTime, (FILETIME *)&systime); + ok(!ret, "got ret %lu.\n", ret); + ok(size == sizeof(dh), "got size %lu.\n", size); + ok(dh.dwTotalSize == sizeof(dh), "got dwTotalSize %lu.\n", dh.dwTotalSize); + ok(!dh.dwNumCounters, "got dwNumCounters %lu.\n", dh.dwNumCounters); + ok(dh.PerfFreq == freq.QuadPart, "got PerfFreq %I64u.\n", dh.PerfFreq); + ok(dh.PerfTimeStamp >= qpc1.QuadPart && dh.PerfTimeStamp <= qpc2.QuadPart, + "got PerfTimeStamp %I64u, qpc1 %I64u, qpc2 %I64u.\n", + dh.PerfTimeStamp, qpc1.QuadPart, qpc2.QuadPart); + ok(dh.PerfTime100NSec >= nttime1.QuadPart && dh.PerfTime100NSec <= nttime2.QuadPart, + "got PerfTime100NSec %I64u, nttime1 %I64u, nttime2 %I64u.\n", + dh.PerfTime100NSec, nttime1.QuadPart, nttime2.QuadPart); + ok(systime.QuadPart >= trunc_nttime_ms(nttime1.QuadPart) && systime.QuadPart <= trunc_nttime_ms(nttime2.QuadPart), + "got systime %I64u, nttime1 %I64u, nttime2 %I64u, %d.\n", + systime.QuadPart, nttime1.QuadPart, nttime2.QuadPart, dh.SystemTime.wMilliseconds); + + ret = pPerfCloseQueryHandle(query); + ok(!ret, "got ret %lu.\n", ret); +} + +START_TEST(perf) +{ + init_functions(); + + test_provider_init(); + test_perf_counters(); +} diff --git a/modules/rostests/winetests/advapi32/registry.c b/modules/rostests/winetests/advapi32/registry.c index 716edac42e6..b75c8ca1eef 100644 --- a/modules/rostests/winetests/advapi32/registry.c +++ b/modules/rostests/winetests/advapi32/registry.c @@ -22,6 +22,8 @@ #include #include #include +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "wine/test.h" #include "windef.h" #include "winbase.h" @@ -31,6 +33,20 @@ #include "winsvc.h" #include "winerror.h" #include "aclapi.h" +#ifdef __REACTOS__ +/* FIXME: Removing this hack requires fixing our incompatible wine/test.h and wine/debug.h. */ +#ifndef wine_dbg_sprintf +static inline const char* wine_dbg_sprintf(const char* format, ...) +{ + static char buffer[256]; + va_list args; + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + return buffer; +} +#endif +#endif #define IS_HKCR(hk) ((UINT_PTR)hk > 0 && ((UINT_PTR)hk & 3) == 2) @@ -42,88 +58,42 @@ static const char * sTestpath2 = "%FOO%\\subdir1"; static const DWORD ptr_size = 8 * sizeof(void*); static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD); +static DWORD (WINAPI *pRegGetValueW)(HKEY,LPCWSTR,LPCWSTR,DWORD,LPDWORD,PVOID,LPDWORD); static LONG (WINAPI *pRegCopyTreeA)(HKEY,const char *,HKEY); static LONG (WINAPI *pRegDeleteTreeA)(HKEY,const char *); static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD); static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE); +static NTSTATUS (WINAPI * pNtUnloadKey)(POBJECT_ATTRIBUTES); static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*); static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING); +static NTSTATUS (WINAPI * pRtlInitUnicodeString)(PUNICODE_STRING,PCWSTR); static LONG (WINAPI *pRegDeleteKeyValueA)(HKEY,LPCSTR,LPCSTR); static LONG (WINAPI *pRegSetKeyValueW)(HKEY,LPCWSTR,LPCWSTR,DWORD,const void*,DWORD); +static LONG (WINAPI *pRegLoadMUIStringA)(HKEY,LPCSTR,LPSTR,DWORD,LPDWORD,DWORD,LPCSTR); +static LONG (WINAPI *pRegLoadMUIStringW)(HKEY,LPCWSTR,LPWSTR,DWORD,LPDWORD,DWORD,LPCWSTR); +static DWORD (WINAPI *pEnumDynamicTimeZoneInformation)(const DWORD, + DYNAMIC_TIME_ZONE_INFORMATION*); static BOOL limited_user; +static const BOOL is_64bit = sizeof(void *) > sizeof(int); - -/* Debugging functions from wine/libs/wine/debug.c */ - -/* allocate some tmp string space */ -/* FIXME: this is not 100% thread-safe */ -static char *get_temp_buffer( int size ) +static BOOL has_wow64(void) { - static char *list[32]; - static UINT pos; - char *ret; - UINT idx; - - idx = ++pos % (sizeof(list)/sizeof(list[0])); - if (list[idx]) - ret = HeapReAlloc( GetProcessHeap(), 0, list[idx], size ); - else - ret = HeapAlloc( GetProcessHeap(), 0, size ); - if (ret) list[idx] = ret; - return ret; + if (!is_64bit) + { + BOOL is_wow64; + if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 ) || !is_wow64) + return FALSE; + } + return TRUE; } -static const char *wine_debugstr_an( const char *str, int n ) +static const char *dbgstr_SYSTEMTIME(const SYSTEMTIME *st) { - static const char hex[16] = "0123456789abcdef"; - char *dst, *res; - size_t size; - - if (!((ULONG_PTR)str >> 16)) - { - if (!str) return "(null)"; - res = get_temp_buffer( 6 ); - sprintf( res, "#%04x", LOWORD(str) ); - return res; - } - if (n == -1) n = strlen(str); - if (n < 0) n = 0; - size = 10 + min( 300, n * 4 ); - dst = res = get_temp_buffer( size ); - *dst++ = '"'; - while (n-- > 0 && dst <= res + size - 9) - { - unsigned char c = *str++; - switch (c) - { - case '\n': *dst++ = '\\'; *dst++ = 'n'; break; - case '\r': *dst++ = '\\'; *dst++ = 'r'; break; - case '\t': *dst++ = '\\'; *dst++ = 't'; break; - case '"': *dst++ = '\\'; *dst++ = '"'; break; - case '\\': *dst++ = '\\'; *dst++ = '\\'; break; - default: - if (c >= ' ' && c <= 126) - *dst++ = c; - else - { - *dst++ = '\\'; - *dst++ = 'x'; - *dst++ = hex[(c >> 4) & 0x0f]; - *dst++ = hex[c & 0x0f]; - } - } - } - *dst++ = '"'; - if (n > 0) - { - *dst++ = '.'; - *dst++ = '.'; - *dst++ = '.'; - } - *dst++ = 0; - return res; + return wine_dbg_sprintf("%02d-%02d-%04d %02d:%02d:%02d.%03d", + st->wMonth, st->wDay, st->wYear, + st->wHour, st->wMinute, st->wSecond, st->wMilliseconds); } #define ADVAPI32_GET_PROC(func) \ @@ -137,16 +107,27 @@ static void InitFunctionPtrs(void) /* This function was introduced with Windows 2003 SP1 */ ADVAPI32_GET_PROC(RegGetValueA); + ADVAPI32_GET_PROC(RegGetValueW); ADVAPI32_GET_PROC(RegCopyTreeA); ADVAPI32_GET_PROC(RegDeleteTreeA); ADVAPI32_GET_PROC(RegDeleteKeyExA); ADVAPI32_GET_PROC(RegDeleteKeyValueA); ADVAPI32_GET_PROC(RegSetKeyValueW); + ADVAPI32_GET_PROC(RegLoadMUIStringA); + ADVAPI32_GET_PROC(RegLoadMUIStringW); + ADVAPI32_GET_PROC(EnumDynamicTimeZoneInformation); pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" ); pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" ); pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); + pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); pNtDeleteKey = (void *)GetProcAddress( hntdll, "NtDeleteKey" ); + pNtUnloadKey = (void *)GetProcAddress( hntdll, "NtUnloadKey" ); +} + +static BOOL is_special_key(HKEY key) +{ + return !!((ULONG_PTR)key & 0x80000000); } /* delete key and all its subkeys */ @@ -174,9 +155,12 @@ static DWORD delete_key( HKEY hkey ) static void setup_main_key(void) { + DWORD ret; + if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )) delete_key( hkey_main ); - assert (!RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )); + ret = RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main ); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); } static void check_user_privs(void) @@ -185,7 +169,7 @@ static void check_user_privs(void) HKEY hkey = (HKEY)0xdeadbeef; ret = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WRITE, &hkey); - ok(ret == ERROR_SUCCESS || ret == ERROR_ACCESS_DENIED, "expected success or access denied, got %i\n", ret); + ok(ret == ERROR_SUCCESS || ret == ERROR_ACCESS_DENIED, "expected success or access denied, got %li\n", ret); if (ret == ERROR_SUCCESS) { ok(hkey != NULL, "RegOpenKeyExA succeeded but returned NULL hkey\n"); @@ -216,34 +200,34 @@ static void _test_hkey_main_Value_A(int line, LPCSTR name, LPCSTR string, SetLastError(0xdeadbeef); ret = RegQueryValueExA(hkey_main, name, NULL, &type, NULL, &cbData); GLE = GetLastError(); - lok(ret == ERROR_SUCCESS, "RegQueryValueExA/1 failed: %d, GLE=%d\n", ret, GLE); + lok(ret == ERROR_SUCCESS, "RegQueryValueExA/1 failed: %ld, GLE=%ld\n", ret, GLE); /* It is wrong for the Ansi version to not be implemented */ - ok(GLE == 0xdeadbeef, "RegQueryValueExA set GLE = %u\n", GLE); + ok(GLE == 0xdeadbeef, "RegQueryValueExA set GLE = %lu\n", GLE); if(GLE == ERROR_CALL_NOT_IMPLEMENTED) return; str_byte_len = (string ? lstrlenA(string) : 0) + 1; - lok(type == REG_SZ, "RegQueryValueExA/1 returned type %d\n", type); - lok(cbData == full_byte_len, "cbData=%d instead of %d or %d\n", cbData, full_byte_len, str_byte_len); + lok(type == REG_SZ, "RegQueryValueExA/1 returned type %ld\n", type); + lok(cbData == full_byte_len, "cbData=%ld instead of %ld or %ld\n", cbData, full_byte_len, str_byte_len); - value = HeapAlloc(GetProcessHeap(), 0, cbData+1); + value = malloc(cbData+1); memset(value, 0xbd, cbData+1); type=0xdeadbeef; ret = RegQueryValueExA(hkey_main, name, NULL, &type, value, &cbData); GLE = GetLastError(); - lok(ret == ERROR_SUCCESS, "RegQueryValueExA/2 failed: %d, GLE=%d\n", ret, GLE); + lok(ret == ERROR_SUCCESS, "RegQueryValueExA/2 failed: %ld, GLE=%ld\n", ret, GLE); if (!string) { /* When cbData == 0, RegQueryValueExA() should not modify the buffer */ - lok(*value == 0xbd, "RegQueryValueExA overflowed: cbData=%u *value=%02x\n", cbData, *value); + lok(*value == 0xbd, "RegQueryValueExA overflowed: cbData=%lu *value=%02x\n", cbData, *value); } else { - lok(memcmp(value, string, cbData) == 0, "RegQueryValueExA/2 failed: %s/%d != %s/%d\n", - wine_debugstr_an((char*)value, cbData), cbData, - wine_debugstr_an(string, full_byte_len), full_byte_len); - lok(*(value+cbData) == 0xbd, "RegQueryValueExA/2 overflowed at offset %u: %02x != bd\n", cbData, *(value+cbData)); + lok(memcmp(value, string, cbData) == 0, "RegQueryValueExA/2 failed: %s/%ld != %s/%ld\n", + debugstr_an((char*)value, cbData), cbData, + debugstr_an(string, full_byte_len), full_byte_len); + lok(*(value+cbData) == 0xbd, "RegQueryValueExA/2 overflowed at offset %lu: %02x != bd\n", cbData, *(value+cbData)); } - HeapFree(GetProcessHeap(), 0, value); + free(value); } #define test_hkey_main_Value_W(name, string, full_byte_len) _test_hkey_main_Value_W(__LINE__, name, string, full_byte_len) @@ -261,46 +245,46 @@ static void _test_hkey_main_Value_W(int line, LPCWSTR name, LPCWSTR string, SetLastError(0xdeadbeef); ret = RegQueryValueExW(hkey_main, name, NULL, &type, NULL, &cbData); GLE = GetLastError(); - lok(ret == ERROR_SUCCESS, "RegQueryValueExW/1 failed: %d, GLE=%d\n", ret, GLE); + lok(ret == ERROR_SUCCESS, "RegQueryValueExW/1 failed: %ld, GLE=%ld\n", ret, GLE); if(GLE == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("RegQueryValueExW() is not implemented\n"); return; } - lok(type == REG_SZ, "RegQueryValueExW/1 returned type %d\n", type); + lok(type == REG_SZ, "RegQueryValueExW/1 returned type %ld\n", type); lok(cbData == full_byte_len, - "cbData=%d instead of %d\n", cbData, full_byte_len); + "cbData=%ld instead of %ld\n", cbData, full_byte_len); /* Give enough space to overflow by one WCHAR */ - value = HeapAlloc(GetProcessHeap(), 0, cbData+2); + value = malloc(cbData+2); memset(value, 0xbd, cbData+2); type=0xdeadbeef; ret = RegQueryValueExW(hkey_main, name, NULL, &type, value, &cbData); GLE = GetLastError(); - lok(ret == ERROR_SUCCESS, "RegQueryValueExW/2 failed: %d, GLE=%d\n", ret, GLE); + lok(ret == ERROR_SUCCESS, "RegQueryValueExW/2 failed: %ld, GLE=%ld\n", ret, GLE); if (string) { - lok(memcmp(value, string, cbData) == 0, "RegQueryValueExW failed: %s/%d != %s/%d\n", + lok(memcmp(value, string, cbData) == 0, "RegQueryValueExW failed: %s/%ld != %s/%ld\n", wine_dbgstr_wn((WCHAR*)value, cbData / sizeof(WCHAR)), cbData, wine_dbgstr_wn(string, full_byte_len / sizeof(WCHAR)), full_byte_len); } /* This implies that when cbData == 0, RegQueryValueExW() should not modify the buffer */ - lok(*(value+cbData) == 0xbd, "RegQueryValueExW/2 overflowed at %u: %02x != bd\n", cbData, *(value+cbData)); - lok(*(value+cbData+1) == 0xbd, "RegQueryValueExW/2 overflowed at %u+1: %02x != bd\n", cbData, *(value+cbData+1)); - HeapFree(GetProcessHeap(), 0, value); + lok(*(value+cbData) == 0xbd, "RegQueryValueExW/2 overflowed at %lu: %02x != bd\n", cbData, *(value+cbData)); + lok(*(value+cbData+1) == 0xbd, "RegQueryValueExW/2 overflowed at %lu+1: %02x != bd\n", cbData, *(value+cbData+1)); + free(value); } static void test_set_value(void) { DWORD ret; - static const WCHAR name1W[] = {'C','l','e','a','n','S','i','n','g','l','e','S','t','r','i','n','g', 0}; - static const WCHAR name2W[] = {'S','o','m','e','I','n','t','r','a','Z','e','r','o','e','d','S','t','r','i','n','g', 0}; - static const WCHAR emptyW[] = {0}; - static const WCHAR string1W[] = {'T','h','i','s','N','e','v','e','r','B','r','e','a','k','s', 0}; - static const WCHAR string2W[] = {'T','h','i','s', 0 ,'B','r','e','a','k','s', 0 , 0 ,'A', 0 , 0 , 0 , 'L','o','t', 0 , 0 , 0 , 0, 0}; - static const WCHAR substring2W[] = {'T','h','i','s',0}; + static const WCHAR name1W[] = L"CleanSingleString"; + static const WCHAR name2W[] = L"SomeIntraZeroedString"; + static const WCHAR emptyW[] = L""; + static const WCHAR string1W[] = L"ThisNeverBreaks"; + static const WCHAR string2W[] = L"This\0Breaks\0\0A\0\0\0Lot\0\0\0\0"; + static const WCHAR substring2W[] = L"This"; static const char name1A[] = "CleanSingleString"; static const char name2A[] = "SomeIntraZeroedString"; @@ -309,149 +293,144 @@ static void test_set_value(void) static const char string2A[] = "This\0Breaks\0\0A\0\0\0Lot\0\0\0\0"; static const char substring2A[] = "This"; - if (0) - { - /* Crashes on NT4, Windows 2000 and XP SP1 */ - ret = RegSetValueA(hkey_main, NULL, REG_SZ, NULL, 0); - ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueA should have failed with ERROR_INVALID_PARAMETER instead of %d\n", ret); - } + ret = RegSetValueA(hkey_main, NULL, REG_SZ, NULL, 0); + ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueA should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", ret); ret = RegSetValueA(hkey_main, NULL, REG_SZ, string1A, sizeof(string1A)); - ok(ret == ERROR_SUCCESS, "RegSetValueA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(NULL, string1A, sizeof(string1A)); test_hkey_main_Value_W(NULL, string1W, sizeof(string1W)); /* RegSetValueA ignores the size passed in */ ret = RegSetValueA(hkey_main, NULL, REG_SZ, string1A, 4); - ok(ret == ERROR_SUCCESS, "RegSetValueA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(NULL, string1A, sizeof(string1A)); test_hkey_main_Value_W(NULL, string1W, sizeof(string1W)); /* stops at first null */ ret = RegSetValueA(hkey_main, NULL, REG_SZ, string2A, sizeof(string2A)); - ok(ret == ERROR_SUCCESS, "RegSetValueA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(NULL, substring2A, sizeof(substring2A)); test_hkey_main_Value_W(NULL, substring2W, sizeof(substring2W)); /* only REG_SZ is supported on NT*/ ret = RegSetValueA(hkey_main, NULL, REG_BINARY, string2A, sizeof(string2A)); - ok(ret == ERROR_INVALID_PARAMETER, "got %d (expected ERROR_INVALID_PARAMETER)\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld (expected ERROR_INVALID_PARAMETER)\n", ret); ret = RegSetValueA(hkey_main, NULL, REG_EXPAND_SZ, string2A, sizeof(string2A)); - ok(ret == ERROR_INVALID_PARAMETER, "got %d (expected ERROR_INVALID_PARAMETER)\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld (expected ERROR_INVALID_PARAMETER)\n", ret); ret = RegSetValueA(hkey_main, NULL, REG_MULTI_SZ, string2A, sizeof(string2A)); - ok(ret == ERROR_INVALID_PARAMETER, "got %d (expected ERROR_INVALID_PARAMETER)\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld (expected ERROR_INVALID_PARAMETER)\n", ret); /* Test RegSetValueExA with a 'zero-byte' string (as Office 2003 does). * Surprisingly enough we're supposed to get zero bytes out of it. */ ret = RegSetValueExA(hkey_main, name1A, 0, REG_SZ, (const BYTE *)emptyA, 0); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, NULL, 0); test_hkey_main_Value_W(name1W, NULL, 0); /* test RegSetValueExA with an empty string */ ret = RegSetValueExA(hkey_main, name1A, 0, REG_SZ, (const BYTE *)emptyA, sizeof(emptyA)); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, emptyA, sizeof(emptyA)); test_hkey_main_Value_W(name1W, emptyW, sizeof(emptyW)); /* test RegSetValueExA with off-by-one size */ ret = RegSetValueExA(hkey_main, name1A, 0, REG_SZ, (const BYTE *)string1A, sizeof(string1A)-sizeof(string1A[0])); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, string1A, sizeof(string1A)); test_hkey_main_Value_W(name1W, string1W, sizeof(string1W)); /* test RegSetValueExA with normal string */ ret = RegSetValueExA(hkey_main, name1A, 0, REG_SZ, (const BYTE *)string1A, sizeof(string1A)); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, string1A, sizeof(string1A)); test_hkey_main_Value_W(name1W, string1W, sizeof(string1W)); /* test RegSetValueExA with intrazeroed string */ ret = RegSetValueExA(hkey_main, name2A, 0, REG_SZ, (const BYTE *)string2A, sizeof(string2A)); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name2A, string2A, sizeof(string2A)); test_hkey_main_Value_W(name2W, string2W, sizeof(string2W)); if (0) { - /* Crashes on NT4, Windows 2000 and XP SP1 */ ret = RegSetValueW(hkey_main, NULL, REG_SZ, NULL, 0); - ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have failed with ERROR_INVALID_PARAMETER instead of %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", ret); RegSetValueExA(hkey_main, name2A, 0, REG_SZ, (const BYTE *)1, 1); RegSetValueExA(hkey_main, name2A, 0, REG_DWORD, (const BYTE *)1, 1); } ret = RegSetValueW(hkey_main, NULL, REG_SZ, string1W, sizeof(string1W)); - ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(NULL, string1A, sizeof(string1A)); test_hkey_main_Value_W(NULL, string1W, sizeof(string1W)); ret = RegSetValueW(hkey_main, name1W, REG_SZ, string1W, sizeof(string1W)); - ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, string1A, sizeof(string1A)); test_hkey_main_Value_W(name1W, string1W, sizeof(string1W)); /* RegSetValueW ignores the size passed in */ ret = RegSetValueW(hkey_main, NULL, REG_SZ, string1W, 4 * sizeof(string1W[0])); - ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(NULL, string1A, sizeof(string1A)); test_hkey_main_Value_W(NULL, string1W, sizeof(string1W)); /* stops at first null */ ret = RegSetValueW(hkey_main, NULL, REG_SZ, string2W, sizeof(string2W)); - ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(NULL, substring2A, sizeof(substring2A)); test_hkey_main_Value_W(NULL, substring2W, sizeof(substring2W)); /* only REG_SZ is supported */ ret = RegSetValueW(hkey_main, NULL, REG_BINARY, string2W, sizeof(string2W)); - ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have returned ERROR_INVALID_PARAMETER instead of %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have returned ERROR_INVALID_PARAMETER instead of %ld\n", ret); ret = RegSetValueW(hkey_main, NULL, REG_EXPAND_SZ, string2W, sizeof(string2W)); - ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have returned ERROR_INVALID_PARAMETER instead of %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have returned ERROR_INVALID_PARAMETER instead of %ld\n", ret); ret = RegSetValueW(hkey_main, NULL, REG_MULTI_SZ, string2W, sizeof(string2W)); - ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have returned ERROR_INVALID_PARAMETER instead of %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have returned ERROR_INVALID_PARAMETER instead of %ld\n", ret); /* test RegSetValueExW with off-by-one size */ ret = RegSetValueExW(hkey_main, name1W, 0, REG_SZ, (const BYTE *)string1W, sizeof(string1W)-sizeof(string1W[0])); - ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, string1A, sizeof(string1A)); test_hkey_main_Value_W(name1W, string1W, sizeof(string1W)); /* test RegSetValueExW with normal string */ ret = RegSetValueExW(hkey_main, name1W, 0, REG_SZ, (const BYTE *)string1W, sizeof(string1W)); - ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name1A, string1A, sizeof(string1A)); test_hkey_main_Value_W(name1W, string1W, sizeof(string1W)); /* test RegSetValueExW with intrazeroed string */ ret = RegSetValueExW(hkey_main, name2W, 0, REG_SZ, (const BYTE *)string2W, sizeof(string2W)); - ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %ld, GLE=%ld\n", ret, GetLastError()); test_hkey_main_Value_A(name2A, string2A, sizeof(string2A)); test_hkey_main_Value_W(name2W, string2W, sizeof(string2W)); /* test RegSetValueExW with data = 1 */ ret = RegSetValueExW(hkey_main, name2W, 0, REG_SZ, (const BYTE *)1, 1); - ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %ld, GLE=%ld\n", ret, GetLastError()); ret = RegSetValueExW(hkey_main, name2W, 0, REG_DWORD, (const BYTE *)1, 1); - ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %ld, GLE=%ld\n", ret, GetLastError()); if (pRegGetValueA) /* avoid a crash on Windows 2000 */ { ret = RegSetValueExW(hkey_main, NULL, 0, REG_SZ, NULL, 4); - ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %ld, GLE=%ld\n", ret, GetLastError()); ret = RegSetValueExW(hkey_main, NULL, 0, REG_SZ, NULL, 0); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = RegSetValueExW(hkey_main, NULL, 0, REG_DWORD, NULL, 4); - ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %ld, GLE=%ld\n", ret, GetLastError()); ret = RegSetValueExW(hkey_main, NULL, 0, REG_DWORD, NULL, 0); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); } /* RegSetKeyValue */ @@ -459,34 +438,33 @@ static void test_set_value(void) win_skip("RegSetKeyValue() is not supported.\n"); else { - static const WCHAR subkeyW[] = {'s','u','b','k','e','y',0}; DWORD len, type; HKEY subkey; ret = pRegSetKeyValueW(hkey_main, NULL, name1W, REG_SZ, (const BYTE*)string2W, sizeof(string2W)); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); test_hkey_main_Value_A(name1A, string2A, sizeof(string2A)); test_hkey_main_Value_W(name1W, string2W, sizeof(string2W)); - ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, string1W, sizeof(string1W)); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ret = pRegSetKeyValueW(hkey_main, L"subkey", name1W, REG_SZ, string1W, sizeof(string1W)); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); - ret = RegOpenKeyExW(hkey_main, subkeyW, 0, KEY_QUERY_VALUE, &subkey); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ret = RegOpenKeyExW(hkey_main, L"subkey", 0, KEY_QUERY_VALUE, &subkey); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); type = len = 0; ret = RegQueryValueExW(subkey, name1W, 0, &type, NULL, &len); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); - ok(len == sizeof(string1W), "got %d\n", len); - ok(type == REG_SZ, "got type %d\n", type); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); + ok(len == sizeof(string1W), "got %ld\n", len); + ok(type == REG_SZ, "got type %ld\n", type); - ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, NULL, 0); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ret = pRegSetKeyValueW(hkey_main, L"subkey", name1W, REG_SZ, NULL, 0); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); - ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, NULL, 4); - ok(ret == ERROR_NOACCESS, "got %d\n", ret); + ret = pRegSetKeyValueW(hkey_main, L"subkey", name1W, REG_SZ, NULL, 4); + ok(ret == ERROR_NOACCESS, "got %ld\n", ret); - ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_DWORD, NULL, 4); - ok(ret == ERROR_NOACCESS, "got %d\n", ret); + ret = pRegSetKeyValueW(hkey_main, L"subkey", name1W, REG_DWORD, NULL, 4); + ok(ret == ERROR_NOACCESS, "got %ld\n", ret); RegCloseKey(subkey); } @@ -519,27 +497,24 @@ static void test_enum_value(void) { DWORD res; HKEY test_key; - char value[20], data[20]; + char value[20], data[30]; WCHAR valueW[20], dataW[20]; DWORD val_count, data_count, type; - static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; - static const WCHAR testW[] = {'T','e','s','t',0}; - static const WCHAR xxxW[] = {'x','x','x','x','x','x','x','x',0}; /* create the working key for new 'Test' value */ res = RegCreateKeyA( hkey_main, "TestKey", &test_key ); - ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res); /* check NULL data with zero length */ res = RegSetValueExA( test_key, "Test", 0, REG_SZ, NULL, 0 ); if (GetVersion() & 0x80000000) - ok( res == ERROR_INVALID_PARAMETER, "RegSetValueExA returned %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "RegSetValueExA returned %ld\n", res ); else - ok( !res, "RegSetValueExA returned %d\n", res ); + ok( !res, "RegSetValueExA returned %ld\n", res ); res = RegSetValueExA( test_key, "Test", 0, REG_EXPAND_SZ, NULL, 0 ); - ok( ERROR_SUCCESS == res || ERROR_INVALID_PARAMETER == res, "RegSetValueExA returned %d\n", res ); + ok( ERROR_SUCCESS == res, "RegSetValueExA returned %ld\n", res ); res = RegSetValueExA( test_key, "Test", 0, REG_BINARY, NULL, 0 ); - ok( ERROR_SUCCESS == res || ERROR_INVALID_PARAMETER == res, "RegSetValueExA returned %d\n", res ); + ok( ERROR_SUCCESS == res, "RegSetValueExA returned %ld\n", res ); /* test reading the value and data without setting them */ val_count = 20; @@ -548,28 +523,28 @@ static void test_enum_value(void) strcpy( value, "xxxxxxxxxx" ); strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); - ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); - ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); - ok( data_count == 0, "data_count set to %d instead of 0\n", data_count ); - ok( type == REG_BINARY, "type %d is not REG_BINARY\n", type ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res ); + ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count ); + ok( data_count == 0, "data_count set to %ld instead of 0\n", data_count ); + ok( type == REG_BINARY, "type %ld is not REG_BINARY\n", type ); ok( !strcmp( value, "Test" ), "value is '%s' instead of Test\n", value ); ok( !strcmp( data, "xxxxxxxxxx" ), "data is '%s' instead of xxxxxxxxxx\n", data ); val_count = 20; data_count = 20; type = 1234; - memcpy( valueW, xxxW, sizeof(xxxW) ); - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( valueW, L"xxxxxxxx" ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); - ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); - ok( data_count == 0, "data_count set to %d instead of 0\n", data_count ); - ok( type == REG_BINARY, "type %d is not REG_BINARY\n", type ); - ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" ); - ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data is not 'xxxxxxxxxx'\n" ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res ); + ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count ); + ok( data_count == 0, "data_count set to %ld instead of 0\n", data_count ); + ok( type == REG_BINARY, "type %ld is not REG_BINARY\n", type ); + ok( !wcscmp( valueW, L"Test" ), "value is not 'Test'\n" ); + ok( !wcscmp( dataW, L"xxxxxxxx" ), "data is not 'xxxxxxxx'\n" ); res = RegSetValueExA( test_key, "Test", 0, REG_SZ, (const BYTE *)"foobar", 7 ); - ok( res == 0, "RegSetValueExA failed error %d\n", res ); + ok( res == 0, "RegSetValueExA failed error %ld\n", res ); /* overflow both name and data */ val_count = 2; @@ -578,45 +553,61 @@ static void test_enum_value(void) strcpy( value, "xxxxxxxxxx" ); strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 2, "val_count set to %d\n", val_count ); - ok( data_count == 7 || broken( data_count == 8 ), "data_count set to %d instead of 7\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 2, "val_count set to %ld\n", val_count ); + /* Chinese, Japanese, and Korean editions of Windows 10 sometimes set data_count to a higher value */ + ok( data_count == 7 || broken( data_count > 7 ), "data_count set to %ld instead of 7\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value ); ok( !strcmp( data, "xxxxxxxxxx" ), "data set to '%s'\n", data ); /* overflow name */ val_count = 3; - data_count = 20; + data_count = 16; type = 1234; strcpy( value, "xxxxxxxxxx" ); - strcpy( data, "xxxxxxxxxx" ); + memset( data, 'x', sizeof(data) ); + data[sizeof(data)-1] = '\0'; res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 3, "val_count set to %d\n", val_count ); - ok( data_count == 7 || broken( data_count == 8 ), "data_count set to %d instead of 7\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); - /* v5.1.2600.0 (XP Home and Professional) does not touch value or data in this case */ + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 3, "val_count set to %ld\n", val_count ); + /* In double-byte and UTF-8 locales Windows 10 may set data_count > 7, + * potentially even more than the declared buffer size, in which case the + * buffer is not NUL-terminated. + */ + ok( data_count == 7 || broken( data_count > 7 ), "data_count set to %ld instead of 7\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); + /* v5.1.2600.0 (XP Home and Professional) does not touch value or data in + * this case. Neither does Windows 10 21H1 in UTF-8 locales. + */ ok( !strcmp( value, "Te" ) || !strcmp( value, "xxxxxxxxxx" ), "value set to '%s' instead of 'Te' or 'xxxxxxxxxx'\n", value ); - ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ) || broken( !strcmp( data, "xxxxxxxx" ) && data_count == 8 ), - "data set to '%s' instead of 'foobar' or 'xxxxxxx'\n", data ); + ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ) || + broken( data_count > 7 && data_count < 16 && + strspn( data, "x" ) == data_count && data[data_count] == 0 ) || + broken( data_count >= 16 && strspn( data, "x" ) == sizeof(data) - 1 ), + "data set to '%s' instead of 'foobar' or x's, data_count=%lu\n", data, data_count ); /* overflow empty name */ val_count = 0; - data_count = 20; + data_count = 16; type = 1234; strcpy( value, "xxxxxxxxxx" ); - strcpy( data, "xxxxxxxxxx" ); + memset( data, 'x', sizeof(data) ); + data[sizeof(data)-1] = '\0'; res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 0, "val_count set to %d\n", val_count ); - ok( data_count == 7 || broken( data_count == 8 ), "data_count set to %d instead of 7\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 0, "val_count set to %ld\n", val_count ); + /* See comment in 'overflow name' section */ + ok( data_count == 7 || broken( data_count > 7 ), "data_count set to %ld instead of 7\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value ); - /* v5.1.2600.0 (XP Home and Professional) does not touch data in this case */ - ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ) || broken( !strcmp( data, "xxxxxxxx" ) && data_count == 8 ), - "data set to '%s' instead of 'foobar' or 'xxxxxxx'\n", data ); + /* See comment in 'overflow name' section */ + ok( !strcmp( data, "foobar" ) || !strcmp( data, "xxxxxxx" ) || + broken( data_count > 7 && data_count < 16 && + strspn( data, "x" ) == data_count && data[data_count] == 0 ) || + broken( data_count >= 16 && strspn( data, "x" ) == sizeof(data) - 1 ), + "data set to '%s' instead of 'foobar' or x's, data_count=%lu\n", data, data_count ); /* overflow data */ val_count = 20; @@ -625,10 +616,10 @@ static void test_enum_value(void) strcpy( value, "xxxxxxxxxx" ); strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 20, "val_count set to %d\n", val_count ); - ok( data_count == 7, "data_count set to %d instead of 7\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 20, "val_count set to %ld\n", val_count ); + ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value ); ok( !strcmp( data, "xxxxxxxxxx" ), "data set to '%s'\n", data ); @@ -639,10 +630,10 @@ static void test_enum_value(void) strcpy( value, "xxxxxxxxxx" ); strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); - ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); - ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); - ok( data_count == 7, "data_count set to %d instead of 7\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res ); + ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count ); + ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); ok( !strcmp( value, "Test" ), "value is '%s' instead of Test\n", value ); ok( !strcmp( data, "foobar" ), "data is '%s' instead of foobar\n", data ); @@ -653,7 +644,7 @@ static void test_enum_value(void) type = 1234; strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, NULL, NULL, NULL, &type, (BYTE*)data, &data_count ); - ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", res ); /* no value parameter */ val_count = 20; @@ -661,7 +652,7 @@ static void test_enum_value(void) type = 1234; strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, NULL, &val_count, NULL, &type, (BYTE*)data, &data_count ); - ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", res ); /* no val_count parameter */ data_count = 20; @@ -669,100 +660,100 @@ static void test_enum_value(void) strcpy( value, "xxxxxxxxxx" ); strcpy( data, "xxxxxxxxxx" ); res = RegEnumValueA( test_key, 0, value, NULL, NULL, &type, (BYTE*)data, &data_count ); - ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", res ); } /* Unicode tests */ SetLastError(0xdeadbeef); - res = RegSetValueExW( test_key, testW, 0, REG_SZ, (const BYTE *)foobarW, 7*sizeof(WCHAR) ); + res = RegSetValueExW( test_key, L"Test", 0, REG_SZ, (const BYTE *)L"foobar", 7*sizeof(WCHAR) ); if (res==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) { win_skip("RegSetValueExW is not implemented\n"); goto cleanup; } - ok( res == 0, "RegSetValueExW failed error %d\n", res ); + ok( res == 0, "RegSetValueExW failed error %ld\n", res ); /* overflow both name and data */ val_count = 2; data_count = 2; type = 1234; - memcpy( valueW, xxxW, sizeof(xxxW) ); - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( valueW, L"xxxxxxxx" ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 2, "val_count set to %d\n", val_count ); - ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); - ok( !memcmp( valueW, xxxW, sizeof(xxxW) ), "value modified\n" ); - ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" ); + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 2, "val_count set to %ld\n", val_count ); + ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); + ok( !wcscmp( valueW, L"xxxxxxxx" ), "value modified\n" ); + ok( !wcscmp( dataW, L"xxxxxxxx" ), "data modified\n" ); /* overflow name */ val_count = 3; data_count = 20; type = 1234; - memcpy( valueW, xxxW, sizeof(xxxW) ); - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( valueW, L"xxxxxxxx" ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 3, "val_count set to %d\n", val_count ); - ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); - ok( !memcmp( valueW, xxxW, sizeof(xxxW) ), "value modified\n" ); - ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" ); + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 3, "val_count set to %ld\n", val_count ); + ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); + ok( !wcscmp( valueW, L"xxxxxxxx" ), "value modified\n" ); + ok( !wcscmp( dataW, L"xxxxxxxx" ), "data modified\n" ); /* overflow data */ val_count = 20; data_count = 2; type = 1234; - memcpy( valueW, xxxW, sizeof(xxxW) ); - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( valueW, L"xxxxxxxx" ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", res ); - ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); - ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); - ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" ); - ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" ); + ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res ); + ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count ); + ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); + ok( !wcscmp( valueW, L"Test" ), "value is not 'Test'\n" ); + ok( !wcscmp( dataW, L"xxxxxxxx" ), "data modified\n" ); /* no overflow */ val_count = 20; data_count = 20; type = 1234; - memcpy( valueW, xxxW, sizeof(xxxW) ); - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( valueW, L"xxxxxxxx" ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); - ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); - ok( data_count == 7*sizeof(WCHAR), "data_count set to %d instead of 7*sizeof(WCHAR)\n", data_count ); - ok( type == REG_SZ, "type %d is not REG_SZ\n", type ); - ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" ); - ok( !memcmp( dataW, foobarW, sizeof(foobarW) ), "data is not 'foobar'\n" ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res ); + ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count ); + ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count ); + ok( type == REG_SZ, "type %ld is not REG_SZ\n", type ); + ok( !wcscmp( valueW, L"Test" ), "value is not 'Test'\n" ); + ok( !wcscmp( dataW, L"foobar" ), "data is not 'foobar'\n" ); if (pRegGetValueA) /* avoid a crash on Windows 2000 */ { /* no valueW and no val_count parameter */ data_count = 20; type = 1234; - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, NULL, NULL, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", res ); /* no valueW parameter */ val_count = 20; data_count = 20; type = 1234; - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, NULL, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", res ); /* no val_count parameter */ data_count = 20; type = 1234; - memcpy( valueW, xxxW, sizeof(xxxW) ); - memcpy( dataW, xxxW, sizeof(xxxW) ); + wcscpy( valueW, L"xxxxxxxx" ); + wcscpy( dataW, L"xxxxxxxx" ); res = RegEnumValueW( test_key, 0, valueW, NULL, NULL, &type, (BYTE*)dataW, &data_count ); - ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", res ); + ok( res == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", res ); } cleanup: @@ -777,24 +768,24 @@ static void test_query_value_ex(void) size = sizeof(buffer); ret = RegQueryValueExA(hkey_main, "TP1_SZ", NULL, &type, NULL, &size); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); - ok(size == strlen(sTestpath1) + 1, "(%d,%d)\n", (DWORD)strlen(sTestpath1) + 1, size); - ok(type == REG_SZ, "type %d is not REG_SZ\n", type); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + ok(size == strlen(sTestpath1) + 1, "(%ld,%ld)\n", (DWORD)strlen(sTestpath1) + 1, size); + ok(type == REG_SZ, "type %ld is not REG_SZ\n", type); type = 0xdeadbeef; size = 0xdeadbeef; ret = RegQueryValueExA(HKEY_CLASSES_ROOT, "Nonexistent Value", NULL, &type, NULL, &size); - ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret); - ok(size == 0, "size should have been set to 0 instead of %d\n", size); + ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); + ok(size == 0, "size should have been set to 0 instead of %ld\n", size); size = sizeof(buffer); ret = RegQueryValueExA(HKEY_CLASSES_ROOT, "Nonexistent Value", NULL, &type, buffer, &size); - ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret); - ok(size == sizeof(buffer), "size shouldn't have been changed to %d\n", size); + ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); + ok(size == sizeof(buffer), "size shouldn't have been changed to %ld\n", size); size = 4; ret = RegQueryValueExA(hkey_main, "BIN32", NULL, &size, buffer, &size); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); } static void test_get_value(void) @@ -815,189 +806,199 @@ static void test_get_value(void) /* Invalid parameter */ ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD, &type, &dw, NULL); - ok(ret == ERROR_INVALID_PARAMETER, "ret=%d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "ret=%ld\n", ret); /* Query REG_DWORD using RRF_RT_REG_DWORD (ok) */ size = type = dw = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD, &type, &dw, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == 4, "size=%d\n", size); - ok(type == REG_DWORD, "type=%d\n", type); - ok(dw == 0x12345678, "dw=%d\n", dw); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == 4, "size=%ld\n", size); + ok(type == REG_DWORD, "type=%ld\n", type); + ok(dw == 0x12345678, "dw=%ld\n", dw); + + /* Check RRF_SUBKEY_WOW64*KEY validation on a case without a subkey */ + ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY | RRF_SUBKEY_WOW6432KEY, NULL, NULL, NULL); + ok(ret == ERROR_INVALID_PARAMETER || broken(ret == ERROR_SUCCESS), /* Before Win10 */ + "ret=%ld\n", ret); + ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6432KEY, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); /* Query by subkey-name */ ret = pRegGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "DWORD", RRF_RT_REG_DWORD, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + + /* Check RRF_SUBKEY_WOW64*KEY validation on a case with a subkey */ + ret = pRegGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "DWORD", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY | RRF_SUBKEY_WOW6432KEY, NULL, NULL, NULL); + ok(ret == ERROR_INVALID_PARAMETER || broken(ret == ERROR_SUCCESS), /* Before Win10 */ + "ret=%ld\n", ret); + ret = pRegGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "DWORD", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ret = pRegGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "DWORD", RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6432KEY, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); /* Query REG_DWORD using RRF_RT_REG_BINARY (restricted) */ size = type = dw = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_BINARY, &type, &dw, &size); - ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret); + ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%ld\n", ret); /* Although the function failed all values are retrieved */ - ok(size == 4, "size=%d\n", size); - ok(type == REG_DWORD, "type=%d\n", type); - ok(dw == 0x12345678, "dw=%d\n", dw); + ok(size == 4, "size=%ld\n", size); + ok(type == REG_DWORD, "type=%ld\n", type); + ok(dw == 0x12345678, "dw=%ld\n", dw); /* Test RRF_ZEROONFAILURE */ type = dw = 0xdeadbeef; size = 4; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_SZ|RRF_ZEROONFAILURE, &type, &dw, &size); - ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret); + ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%ld\n", ret); /* Again all values are retrieved ... */ - ok(size == 4, "size=%d\n", size); - ok(type == REG_DWORD, "type=%d\n", type); + ok(size == 4, "size=%ld\n", size); + ok(type == REG_DWORD, "type=%ld\n", type); /* ... except the buffer, which is zeroed out */ - ok(dw == 0, "dw=%d\n", dw); + ok(dw == 0, "dw=%ld\n", dw); /* Test RRF_ZEROONFAILURE with a NULL buffer... */ type = size = 0xbadbeef; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_REG_SZ|RRF_ZEROONFAILURE, &type, NULL, &size); - ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret); - ok(size == 4, "size=%d\n", size); - ok(type == REG_DWORD, "type=%d\n", type); + ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%ld\n", ret); + ok(size == 4, "size=%ld\n", size); + ok(type == REG_DWORD, "type=%ld\n", type); /* Query REG_DWORD using RRF_RT_DWORD (ok) */ size = type = dw = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "DWORD", RRF_RT_DWORD, &type, &dw, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == 4, "size=%d\n", size); - ok(type == REG_DWORD, "type=%d\n", type); - ok(dw == 0x12345678, "dw=%d\n", dw); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == 4, "size=%ld\n", size); + ok(type == REG_DWORD, "type=%ld\n", type); + ok(dw == 0x12345678, "dw=%ld\n", dw); /* Query 32-bit REG_BINARY using RRF_RT_DWORD (ok) */ size = type = dw = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "BIN32", RRF_RT_DWORD, &type, &dw, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == 4, "size=%d\n", size); - ok(type == REG_BINARY, "type=%d\n", type); - ok(dw == 0x12345678, "dw=%d\n", dw); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == 4, "size=%ld\n", size); + ok(type == REG_BINARY, "type=%ld\n", type); + ok(dw == 0x12345678, "dw=%ld\n", dw); /* Query 64-bit REG_BINARY using RRF_RT_DWORD (type mismatch) */ qw[0] = qw[1] = size = type = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "BIN64", RRF_RT_DWORD, &type, qw, &size); - ok(ret == ERROR_DATATYPE_MISMATCH, "ret=%d\n", ret); - ok(size == 8, "size=%d\n", size); - ok(type == REG_BINARY, "type=%d\n", type); + ok(ret == ERROR_DATATYPE_MISMATCH, "ret=%ld\n", ret); + ok(size == 8, "size=%ld\n", size); + ok(type == REG_BINARY, "type=%ld\n", type); ok(qw[0] == 0x12345678 && - qw[1] == 0x87654321, "qw={%d,%d}\n", qw[0], qw[1]); + qw[1] == 0x87654321, "qw={%ld,%ld}\n", qw[0], qw[1]); /* Query 64-bit REG_BINARY using 32-bit buffer (buffer too small) */ type = dw = 0xdeadbeef; size = 4; ret = pRegGetValueA(hkey_main, NULL, "BIN64", RRF_RT_REG_BINARY, &type, &dw, &size); - ok(ret == ERROR_MORE_DATA, "ret=%d\n", ret); - ok(dw == 0xdeadbeef, "dw=%d\n", dw); - ok(size == 8, "size=%d\n", size); + ok(ret == ERROR_MORE_DATA, "ret=%ld\n", ret); + ok(dw == 0xdeadbeef, "dw=%ld\n", dw); + ok(size == 8, "size=%ld\n", size); /* Query 64-bit REG_BINARY using RRF_RT_QWORD (ok) */ qw[0] = qw[1] = size = type = 0xdeadbeef; ret = pRegGetValueA(hkey_main, NULL, "BIN64", RRF_RT_QWORD, &type, qw, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == 8, "size=%d\n", size); - ok(type == REG_BINARY, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == 8, "size=%ld\n", size); + ok(type == REG_BINARY, "type=%ld\n", type); ok(qw[0] == 0x12345678 && - qw[1] == 0x87654321, "qw={%d,%d}\n", qw[0], qw[1]); + qw[1] == 0x87654321, "qw={%ld,%ld}\n", qw[0], qw[1]); /* Query REG_SZ using RRF_RT_REG_SZ (ok) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); - ok(type == REG_SZ, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%ld\n", lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%ld\n", type); ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf); /* Query REG_SZ using RRF_RT_REG_SZ and no buffer (ok) */ type = 0xdeadbeef; size = 0; ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ, &type, NULL, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); /* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */ ok(size == strlen(sTestpath1)+1 || broken(size == strlen(sTestpath1)+2), - "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); - ok(type == REG_SZ, "type=%d\n", type); + "strlen(sTestpath1)=%d size=%ld\n", lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%ld\n", type); /* Query REG_SZ using RRF_RT_REG_SZ on a zero-byte value (ok) */ strcpy(buf, sTestpath1); type = 0xdeadbeef; - size = sizeof(buf); + size = 0; + ret = pRegGetValueA(hkey_main, NULL, "TP1_ZB_SZ", RRF_RT_REG_SZ, &type, NULL, &size); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == 1, "size=%ld\n", size); + ok(type == REG_SZ, "type=%ld\n", type); ret = pRegGetValueA(hkey_main, NULL, "TP1_ZB_SZ", RRF_RT_REG_SZ, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - /* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */ - ok(size == 0 || - size == 1, /* win2k3 */ - "size=%d\n", size); - ok(type == REG_SZ, "type=%d\n", type); - ok(!strcmp(sTestpath1, buf) || - !strcmp(buf, ""), - "Expected \"%s\" or \"\", got \"%s\"\n", sTestpath1, buf); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == 1, "size=%ld\n", size); + ok(type == REG_SZ, "type=%ld\n", type); + ok(!strcmp(buf, ""), "Expected \"\", got \"%s\"\n", buf); /* Query REG_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (ok) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_SZ", RRF_RT_REG_SZ|RRF_NOEXPAND, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); - ok(type == REG_SZ, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%ld\n", lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%ld\n", type); ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf); /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ and no buffer (ok, expands) */ size = 0; ret = pRegGetValueA(hkey_main, NULL, "TP2_EXP_SZ", RRF_RT_REG_SZ, NULL, NULL, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok((size == strlen(expanded2)+1) || /* win2k3 SP1 */ - (size == strlen(expanded2)+2) || /* win2k3 SP2 */ - (size == strlen(sTestpath2)+1), - "strlen(expanded2)=%d, strlen(sTestpath2)=%d, size=%d\n", lstrlenA(expanded2), lstrlenA(sTestpath2), size); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == strlen(expanded2)+2, + "strlen(expanded2)=%d, strlen(sTestpath2)=%d, size=%ld\n", lstrlenA(expanded2), lstrlenA(sTestpath2), size); /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ (ok, expands) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */ - ok(size == strlen(expanded)+1 || broken(size == strlen(sTestpath1)+1), - "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded), lstrlenA(sTestpath1), size); - ok(type == REG_SZ, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + todo_wine ok(size == strlen(sTestpath1)+1, + "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%ld\n", lstrlenA(expanded), lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%ld\n", type); ok(!strcmp(expanded, buf), "expanded=\"%s\" buf=\"%s\"\n", expanded, buf); /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ (ok, expands a lot) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP2_EXP_SZ", RRF_RT_REG_SZ, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath2 length + 1 here. */ - ok(size == strlen(expanded2)+1 || broken(size == strlen(sTestpath2)+1), - "strlen(expanded2)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded2), lstrlenA(sTestpath2), size); - ok(type == REG_SZ, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == strlen(expanded2)+1, + "strlen(expanded2)=%d, strlen(sTestpath1)=%d, size=%ld\n", lstrlenA(expanded2), lstrlenA(sTestpath2), size); + ok(type == REG_SZ, "type=%ld\n", type); ok(!strcmp(expanded2, buf), "expanded2=\"%s\" buf=\"%s\"\n", expanded2, buf); /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND (ok, doesn't expand) */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); - ok(type == REG_EXPAND_SZ, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + ok(size == strlen(sTestpath1)+1, "strlen(sTestpath1)=%d size=%ld\n", lstrlenA(sTestpath1), size); + ok(type == REG_EXPAND_SZ, "type=%ld\n", type); ok(!strcmp(sTestpath1, buf), "sTestpath=\"%s\" buf=\"%s\"\n", sTestpath1, buf); /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND and no buffer (ok, doesn't expand) */ size = 0xbadbeef; ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ|RRF_NOEXPAND, NULL, NULL, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - /* v5.2.3790.1830 (2003 SP1) returns sTestpath1 length + 2 here. */ - ok(size == strlen(sTestpath1)+1 || broken(size == strlen(sTestpath1)+2), - "strlen(sTestpath1)=%d size=%d\n", lstrlenA(sTestpath1), size); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + todo_wine ok(size == strlen(sTestpath1)+2, "strlen(sTestpath1)=%d size=%ld\n", lstrlenA(sTestpath1), size); /* Query REG_EXPAND_SZ using RRF_RT_REG_SZ|RRF_NOEXPAND (type mismatch) */ ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_SZ|RRF_NOEXPAND, NULL, NULL, NULL); - ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret); + ok(ret == ERROR_UNSUPPORTED_TYPE, "ret=%ld\n", ret); /* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ (not allowed without RRF_NOEXPAND) */ ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ, NULL, NULL, NULL); /* before win8: ERROR_INVALID_PARAMETER, win8: ERROR_UNSUPPORTED_TYPE */ - ok(ret == ERROR_INVALID_PARAMETER || ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER || ret == ERROR_UNSUPPORTED_TYPE, "ret=%ld\n", ret); /* Query REG_EXPAND_SZ using RRF_RT_ANY */ buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf); ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_ANY, &type, buf, &size); - ok(ret == ERROR_SUCCESS, "ret=%d\n", ret); - /* At least v5.2.3790.1830 (2003 SP1) returns the unexpanded sTestpath1 length + 1 here. */ - ok(size == strlen(expanded)+1 || broken(size == strlen(sTestpath1)+1), - "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%d\n", lstrlenA(expanded), lstrlenA(sTestpath1), size); - ok(type == REG_SZ, "type=%d\n", type); + ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); + todo_wine ok(size == strlen(sTestpath1)+1, + "strlen(expanded)=%d, strlen(sTestpath1)=%d, size=%ld\n", lstrlenA(expanded), lstrlenA(sTestpath1), size); + ok(type == REG_SZ, "type=%ld\n", type); ok(!strcmp(expanded, buf), "expanded=\"%s\" buf=\"%s\"\n", expanded, buf); } @@ -1017,20 +1018,20 @@ static void test_reg_open_key(void) /* successful open */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != NULL, "expected hkResult != NULL\n"); hkPreserve = hkResult; /* open same key twice */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != hkPreserve, "expected hkResult != hkPreserve\n"); ok(hkResult != NULL, "hkResult != NULL\n"); RegCloseKey(hkResult); /* trailing slashes */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test\\\\", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); RegCloseKey(hkResult); /* open nonexistent key @@ -1038,13 +1039,13 @@ static void test_reg_open_key(void) */ hkResult = hkPreserve; ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Nonexistent", &hkResult); - ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); ok(hkResult == NULL, "expected hkResult == NULL\n"); /* open the same nonexistent key again to make sure the key wasn't created */ hkResult = hkPreserve; ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Nonexistent", &hkResult); - ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); ok(hkResult == NULL, "expected hkResult == NULL\n"); /* send in NULL lpSubKey @@ -1052,13 +1053,13 @@ static void test_reg_open_key(void) */ hkResult = hkPreserve; ret = RegOpenKeyA(HKEY_CURRENT_USER, NULL, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult == HKEY_CURRENT_USER, "expected hkResult == HKEY_CURRENT_USER\n"); /* send empty-string in lpSubKey */ hkResult = hkPreserve; ret = RegOpenKeyA(HKEY_CURRENT_USER, "", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult == HKEY_CURRENT_USER, "expected hkResult == HKEY_CURRENT_USER\n"); /* send in NULL lpSubKey and NULL hKey @@ -1066,7 +1067,7 @@ static void test_reg_open_key(void) */ hkResult = hkPreserve; ret = RegOpenKeyA(NULL, NULL, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult == NULL, "expected hkResult == NULL\n"); /* only send NULL hKey @@ -1075,68 +1076,75 @@ static void test_reg_open_key(void) hkResult = hkPreserve; ret = RegOpenKeyA(NULL, "Software\\Wine\\Test", &hkResult); ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 95 returns BADKEY */ - "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret); + "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %ld\n", ret); ok(hkResult == hkPreserve, "expected hkResult == hkPreserve\n"); /* send in NULL hkResult */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", NULL); - ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", ret); ret = RegOpenKeyA(HKEY_CURRENT_USER, NULL, NULL); - ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", ret); ret = RegOpenKeyA(NULL, NULL, NULL); - ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", ret); /* beginning backslash character */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "\\Software\\Wine\\Test", &hkResult); - ok(ret == ERROR_BAD_PATHNAME || /* NT/2k/XP */ - broken(ret == ERROR_SUCCESS), /* wow64 */ - "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret); + ok(ret == ERROR_BAD_PATHNAME || broken(ret == ERROR_SUCCESS), /* wow64 */ + "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %ld\n", ret); if (!ret) RegCloseKey(hkResult); hkResult = NULL; ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "\\clsid", 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_SUCCESS || /* 2k/XP */ - ret == ERROR_BAD_PATHNAME, /* NT */ - "expected ERROR_SUCCESS, ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n", ret); + ok(ret == ERROR_SUCCESS, + "expected ERROR_SUCCESS, ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %ld\n", ret); RegCloseKey(hkResult); /* NULL or empty subkey of special root */ hkResult = NULL; ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, NULL, 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult == HKEY_CLASSES_ROOT, "expected hkResult == HKEY_CLASSES_ROOT\n"); hkResult = NULL; ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "", 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult == HKEY_CLASSES_ROOT, "expected hkResult == HKEY_CLASSES_ROOT\n"); hkResult = NULL; ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "\\", 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != HKEY_CLASSES_ROOT, "expected hkResult to be a new key\n"); ok(!RegCloseKey(hkResult), "got invalid hkey\n"); /* empty subkey of existing handle */ hkResult = hkPreserve; ret = RegOpenKeyExA(hkPreserve, "", 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != hkPreserve, "expected hkResult != hkPreserve\n"); ok(!RegCloseKey(hkResult), "got invalid hkey\n"); /* NULL subkey of existing handle */ hkResult = hkPreserve; ret = RegOpenKeyExA(hkPreserve, NULL, 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != hkPreserve, "expected hkResult != hkPreserve\n"); ok(!RegCloseKey(hkResult), "got invalid hkey\n"); /* empty subkey of NULL */ + hkResult = hkPreserve; + ret = RegOpenKeyExW(NULL, L"", 0, KEY_QUERY_VALUE, &hkResult); + ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", ret); +#ifdef __REACTOS__ + ok(hkResult == NULL || broken(GetNTVersion() <= _WIN32_WINNT_WS03), "expected hkResult == NULL\n"); +#else + ok(hkResult == NULL, "expected hkResult == NULL\n"); +#endif + hkResult = hkPreserve; ret = RegOpenKeyExA(NULL, "", 0, KEY_QUERY_VALUE, &hkResult); - ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", ret); + ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", ret); ok(hkResult == hkPreserve, "expected hkResult == hkPreserve\n"); RegCloseKey(hkPreserve); @@ -1144,14 +1152,12 @@ static void test_reg_open_key(void) /* WOW64 flags */ hkResult = NULL; ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WOW64_32KEY, &hkResult); - ok((ret == ERROR_SUCCESS && hkResult != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), - "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS && hkResult, "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%lu)\n", ret); RegCloseKey(hkResult); hkResult = NULL; ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WOW64_64KEY, &hkResult); - ok((ret == ERROR_SUCCESS && hkResult != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), - "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS && hkResult, "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%lu)\n", ret); RegCloseKey(hkResult); /* check special HKEYs on 64bit @@ -1161,28 +1167,28 @@ static void test_reg_open_key(void) { /* HKEY_CURRENT_USER */ ret = RegOpenKeyA(UlongToHandle(HandleToUlong(HKEY_CURRENT_USER)), "Software", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != NULL, "expected hkResult != NULL\n"); RegCloseKey(hkResult); ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)1 << 32), "Software", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != NULL, "expected hkResult != NULL\n"); RegCloseKey(hkResult); ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)0xdeadbeef << 32), "Software", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != NULL, "expected hkResult != NULL\n"); RegCloseKey(hkResult); ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)0xffffffff << 32), "Software", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != NULL, "expected hkResult != NULL\n"); RegCloseKey(hkResult); /* HKEY_LOCAL_MACHINE */ ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_LOCAL_MACHINE) | (ULONG64)0xdeadbeef << 32), "Software", &hkResult); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ok(hkResult != NULL, "expected hkResult != NULL\n"); RegCloseKey(hkResult); } @@ -1191,34 +1197,35 @@ static void test_reg_open_key(void) * the registry access check is performed correctly. Redirection isn't * being tested, so the tests don't care about whether the process is * running under WOW64. */ - if (!pIsWow64Process) + if (!is_64bit) { - win_skip("WOW64 flags are not recognized\n"); + skip("Not running WoW64 tests on 32-bit\n"); return; } ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hkRoot32, NULL); - if (limited_user) - ok(ret == ERROR_ACCESS_DENIED && hkRoot32 == NULL, - "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); - else - ok(ret == ERROR_SUCCESS && hkRoot32 != NULL, - "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS || ret == ERROR_ACCESS_DENIED, + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%lu)\n", ret); + if (ret == ERROR_ACCESS_DENIED) return; + ok(hkRoot32 != NULL, "hkRoot32 was set\n"); ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hkRoot64, NULL); - if (limited_user) - ok(ret == ERROR_ACCESS_DENIED && hkRoot64 == NULL, - "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); - else - ok(ret == ERROR_SUCCESS && hkRoot64 != NULL, - "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS || ret == ERROR_ACCESS_DENIED, + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%lu)\n", ret); + if (ret == ERROR_ACCESS_DENIED) + { + RegDeleteKeyA(hkRoot32, ""); + RegCloseKey(hkRoot32); + return; + } + ok(hkRoot64 != NULL, "hkRoot64 was set\n"); bRet = AllocateAndInitializeSid(&sid_authority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &world_sid); ok(bRet == TRUE, - "Expected AllocateAndInitializeSid to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + "Expected AllocateAndInitializeSid to return TRUE, got %d, last error %lu\n", bRet, GetLastError()); access.grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; access.grfAccessMode = SET_ACCESS; @@ -1231,16 +1238,16 @@ static void test_reg_open_key(void) ret = SetEntriesInAclA(1, &access, NULL, &key_acl); ok(ret == ERROR_SUCCESS, - "Expected SetEntriesInAclA to return ERROR_SUCCESS, got %u, last error %u\n", ret, GetLastError()); + "Expected SetEntriesInAclA to return ERROR_SUCCESS, got %lu, last error %lu\n", ret, GetLastError()); - sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); + sd = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); bRet = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); ok(bRet == TRUE, - "Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + "Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %lu\n", bRet, GetLastError()); bRet = SetSecurityDescriptorDacl(sd, TRUE, key_acl, FALSE); ok(bRet == TRUE, - "Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + "Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %lu\n", bRet, GetLastError()); if (limited_user) { @@ -1252,26 +1259,26 @@ static void test_reg_open_key(void) error = RegSetKeySecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd); ok(error == ERROR_SUCCESS, - "Expected RegSetKeySecurity to return success, got error %u\n", error); + "Expected RegSetKeySecurity to return success, got error %lu\n", error); error = RegSetKeySecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); ok(error == ERROR_SUCCESS, - "Expected RegSetKeySecurity to return success, got error %u\n", error); + "Expected RegSetKeySecurity to return success, got error %lu\n", error); hkResult = NULL; ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_64KEY | KEY_READ, &hkResult); - ok(ret == ERROR_SUCCESS && hkResult != NULL, - "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS, "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%lu)\n", ret); + ok(hkResult != NULL, "hkResult wasn't set\n"); RegCloseKey(hkResult); hkResult = NULL; ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_32KEY | KEY_READ, &hkResult); - ok(ret == ERROR_SUCCESS && hkResult != NULL, - "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS, "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%lu)\n", ret); + ok(hkResult != NULL, "hkResult wasn't set\n"); RegCloseKey(hkResult); } - HeapFree(GetProcessHeap(), 0, sd); + free(sd); LocalFree(key_acl); FreeSid(world_sid); RegDeleteKeyA(hkRoot64, ""); @@ -1294,12 +1301,29 @@ static void test_reg_create_key(void) PACL key_acl; SECURITY_DESCRIPTOR *sd; + /* NULL return key check */ + ret = RegCreateKeyA(hkey_main, "Subkey1", NULL); + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret); + + ret = RegCreateKeyW(hkey_main, L"Subkey1", NULL); +#ifdef __REACTOS__ + ok(ret == ERROR_INVALID_PARAMETER || broken(ERROR_BADKEY) /* WS03 */, "Got unexpected ret %ld.\n", ret); +#else + ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret); +#endif + + ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, NULL, NULL); + ok(ret == ERROR_BADKEY, "Got unexpected ret %ld.\n", ret); + + ret = RegCreateKeyExW(hkey_main, L"Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, NULL, NULL); + ok(ret == ERROR_BADKEY, "Got unexpected ret %ld.\n", ret); + ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); - ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + ok(!ret, "RegCreateKeyExA failed with error %ld\n", ret); /* should succeed: all versions of Windows ignore the access rights * to the parent handle */ ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey2, NULL); - ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + ok(!ret, "RegCreateKeyExA failed with error %ld\n", ret); /* clean up */ RegDeleteKeyA(hkey2, ""); @@ -1309,16 +1333,16 @@ static void test_reg_create_key(void) /* test creation of volatile keys */ ret = RegCreateKeyExA(hkey_main, "Volatile", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey1, NULL); - ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + ok(!ret, "RegCreateKeyExA failed with error %ld\n", ret); ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey2, NULL); - ok(ret == ERROR_CHILD_MUST_BE_VOLATILE, "RegCreateKeyExA failed with error %d\n", ret); + ok(ret == ERROR_CHILD_MUST_BE_VOLATILE, "RegCreateKeyExA failed with error %ld\n", ret); if (!ret) RegCloseKey( hkey2 ); ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey2, NULL); - ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + ok(!ret, "RegCreateKeyExA failed with error %ld\n", ret); RegCloseKey(hkey2); /* should succeed if the key already exists */ ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey2, NULL); - ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); + ok(!ret, "RegCreateKeyExA failed with error %ld\n", ret); /* clean up */ RegDeleteKeyA(hkey2, ""); @@ -1328,47 +1352,34 @@ static void test_reg_create_key(void) /* beginning backslash character */ ret = RegCreateKeyExA(hkey_main, "\\Subkey3", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); - if (!(GetVersion() & 0x80000000)) - ok(ret == ERROR_BAD_PATHNAME, "expected ERROR_BAD_PATHNAME, got %d\n", ret); - else { - ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); - RegDeleteKeyA(hkey1, ""); - RegCloseKey(hkey1); - } + ok(ret == ERROR_BAD_PATHNAME, "expected ERROR_BAD_PATHNAME, got %ld\n", ret); /* trailing backslash characters */ ret = RegCreateKeyExA(hkey_main, "Subkey4\\\\", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); - ok(ret == ERROR_SUCCESS, "RegCreateKeyExA failed with error %d\n", ret); - RegDeleteKeyA(hkey1, ""); - RegCloseKey(hkey1); - - /* System\CurrentControlSet\Control\Video should be non-volatile */ - ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Video\\Wine", - 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); - ok(ret == ERROR_SUCCESS, "RegCreateKeyExA failed with error %d\n", ret); + ok(ret == ERROR_SUCCESS, "RegCreateKeyExA failed with error %ld\n", ret); RegDeleteKeyA(hkey1, ""); RegCloseKey(hkey1); /* WOW64 flags - open an existing key */ hkey1 = NULL; ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_READ|KEY_WOW64_32KEY, NULL, &hkey1, NULL); - ok((ret == ERROR_SUCCESS && hkey1 != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), - "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS && hkey1 != NULL, + "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%lu)\n", ret); RegCloseKey(hkey1); hkey1 = NULL; ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_READ|KEY_WOW64_64KEY, NULL, &hkey1, NULL); - ok((ret == ERROR_SUCCESS && hkey1 != NULL) || broken(ret == ERROR_ACCESS_DENIED /* NT4, win2k */), - "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + ok(ret == ERROR_SUCCESS && hkey1 != NULL, + "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%lu)\n", ret); RegCloseKey(hkey1); /* Try using WOW64 flags when opening a key with a DACL set to verify that * the registry access check is performed correctly. Redirection isn't * being tested, so the tests don't care about whether the process is * running under WOW64. */ - if (!pIsWow64Process) + if (!has_wow64()) { - win_skip("WOW64 flags are not recognized\n"); + skip("WOW64 flags are not recognized\n"); return; } @@ -1376,24 +1387,24 @@ static void test_reg_create_key(void) KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hkRoot32, NULL); if (limited_user) ok(ret == ERROR_ACCESS_DENIED && hkRoot32 == NULL, - "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%d)\n", ret); + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%ld)\n", ret); else ok(ret == ERROR_SUCCESS && hkRoot32 != NULL, - "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%d)\n", ret); + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%ld)\n", ret); ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hkRoot64, NULL); if (limited_user) ok(ret == ERROR_ACCESS_DENIED && hkRoot64 == NULL, - "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%d)\n", ret); + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%ld)\n", ret); else ok(ret == ERROR_SUCCESS && hkRoot64 != NULL, - "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%d)\n", ret); + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%ld)\n", ret); bRet = AllocateAndInitializeSid(&sid_authority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &world_sid); ok(bRet == TRUE, - "Expected AllocateAndInitializeSid to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + "Expected AllocateAndInitializeSid to return TRUE, got %d, last error %lu\n", bRet, GetLastError()); access.grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL; access.grfAccessMode = SET_ACCESS; @@ -1406,16 +1417,16 @@ static void test_reg_create_key(void) dwRet = SetEntriesInAclA(1, &access, NULL, &key_acl); ok(dwRet == ERROR_SUCCESS, - "Expected SetEntriesInAclA to return ERROR_SUCCESS, got %u, last error %u\n", dwRet, GetLastError()); + "Expected SetEntriesInAclA to return ERROR_SUCCESS, got %lu, last error %lu\n", dwRet, GetLastError()); - sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); + sd = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); bRet = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); ok(bRet == TRUE, - "Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + "Expected InitializeSecurityDescriptor to return TRUE, got %d, last error %lu\n", bRet, GetLastError()); bRet = SetSecurityDescriptorDacl(sd, TRUE, key_acl, FALSE); ok(bRet == TRUE, - "Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + "Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %lu\n", bRet, GetLastError()); if (limited_user) { @@ -1425,28 +1436,28 @@ static void test_reg_create_key(void) { ret = RegSetKeySecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd); ok(ret == ERROR_SUCCESS, - "Expected RegSetKeySecurity to return success, got error %u\n", ret); + "Expected RegSetKeySecurity to return success, got error %lu\n", ret); ret = RegSetKeySecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); ok(ret == ERROR_SUCCESS, - "Expected RegSetKeySecurity to return success, got error %u\n", ret); + "Expected RegSetKeySecurity to return success, got error %lu\n", ret); hkey1 = NULL; ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_READ, NULL, &hkey1, NULL); ok(ret == ERROR_SUCCESS && hkey1 != NULL, - "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%lu)\n", ret); RegCloseKey(hkey1); hkey1 = NULL; ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_32KEY | KEY_READ, NULL, &hkey1, NULL); ok(ret == ERROR_SUCCESS && hkey1 != NULL, - "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%lu)\n", ret); RegCloseKey(hkey1); } - HeapFree(GetProcessHeap(), 0, sd); + free(sd); LocalFree(key_acl); FreeSid(world_sid); RegDeleteKeyA(hkRoot64, ""); @@ -1464,19 +1475,19 @@ static void test_reg_close_key(void) * hkHandle remains changed after call to RegCloseKey */ ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkHandle); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(hkHandle); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); /* try to close the key twice */ ret = RegCloseKey(hkHandle); /* Windows 95 doesn't mind. */ ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_SUCCESS, - "expected ERROR_INVALID_HANDLE or ERROR_SUCCESS, got %d\n", ret); + "expected ERROR_INVALID_HANDLE or ERROR_SUCCESS, got %ld\n", ret); /* try to close a NULL handle */ ret = RegCloseKey(NULL); ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 95 returns BADKEY */ - "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret); + "expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %ld\n", ret); /* Check to see if we didn't potentially close our main handle, which could happen on win98 as * win98 doesn't give a new handle when the same key is opened. @@ -1495,30 +1506,31 @@ static void test_reg_delete_key(void) HKEY key; ret = RegDeleteKeyA(hkey_main, NULL); - - /* There is a bug in NT4 and W2K that doesn't check if the subkey is NULL. If - * there are also no subkeys available it will delete the key pointed to by hkey_main. - * Not re-creating will make some next tests fail. - */ - if (ret == ERROR_SUCCESS) - { - trace("We are probably running on NT4 or W2K as the main key is deleted," - " re-creating the main key\n"); - setup_main_key(); - } - else - ok(ret == ERROR_INVALID_PARAMETER || - ret == ERROR_ACCESS_DENIED || - ret == ERROR_BADKEY, /* Win95 */ - "ret=%d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld\n", ret); ret = RegCreateKeyA(hkey_main, "deleteme", &key); - ok(ret == ERROR_SUCCESS, "Could not create key, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Could not create key, got %ld\n", ret); ret = RegDeleteKeyA(key, ""); - ok(ret == ERROR_SUCCESS, "RegDeleteKeyA failed, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "RegDeleteKeyA failed, got %ld\n", ret); RegCloseKey(key); ret = RegOpenKeyA(hkey_main, "deleteme", &key); - ok(ret == ERROR_FILE_NOT_FOUND, "Key was not deleted, got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "Key was not deleted, got %ld\n", ret); + RegCloseKey(key); + + /* Test deleting 32-bit keys */ + ret = RegCreateKeyExA(hkey_main, "deleteme", 0, NULL, 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY, NULL, &key, NULL); + ok(ret == ERROR_SUCCESS, "Could not create key, got %ld\n", ret); + RegCloseKey(key); + + ret = RegOpenKeyExA(hkey_main, "deleteme", 0, KEY_READ | KEY_WOW64_32KEY, &key); + ok(ret == ERROR_SUCCESS, "Could not open key, got %ld\n", ret); + + ret = RegDeleteKeyExA(key, "", KEY_WOW64_32KEY, 0); + ok(ret == ERROR_SUCCESS, "RegDeleteKeyExA failed, got %ld\n", ret); + RegCloseKey(key); + + ret = RegOpenKeyExA(hkey_main, "deleteme", 0, KEY_READ | KEY_WOW64_32KEY, &key); + ok(ret == ERROR_FILE_NOT_FOUND, "Key was not deleted, got %ld\n", ret); RegCloseKey(key); } @@ -1556,67 +1568,203 @@ static BOOL set_privileges(LPCSTR privilege, BOOL set) return TRUE; } -static void test_reg_save_key(void) +static void delete_dir(const char *path) { - DWORD ret; + char file[2 * MAX_PATH], *p; + WIN32_FIND_DATAA fd; + HANDLE hfind; + BOOL r; - if (!set_privileges(SE_BACKUP_NAME, TRUE) || - !set_privileges(SE_RESTORE_NAME, FALSE)) + strcpy(file, path); + p = file + strlen(file); + p[0] = '\\'; + p[1] = '*'; + p[2] = 0; + hfind = FindFirstFileA(file, &fd); + if (hfind != INVALID_HANDLE_VALUE) + { + do + { + if (!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..")) + continue; + + strcpy(p + 1, fd.cFileName); + r = DeleteFileA(file); + ok(r, "DeleteFile failed on %s: %ld\n", debugstr_a(file), GetLastError()); + } while(FindNextFileA(hfind, &fd)); + FindClose(hfind); + } + + r = RemoveDirectoryA(path); + ok(r, "RemoveDirectory failed: %ld\n", GetLastError()); +} + +static void test_reg_load_key(void) +{ + char saved_key[2 * MAX_PATH], buf[16], *p; + UNICODE_STRING key_name; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + DWORD ret, size; + HKEY key; + + if (!set_privileges(SE_RESTORE_NAME, TRUE) || + !set_privileges(SE_BACKUP_NAME, TRUE)) + { + win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n"); + return; + } + + GetTempPathA(MAX_PATH, saved_key); + strcat(saved_key, "\\wine_reg_test"); + CreateDirectoryA(saved_key, NULL); + strcat(saved_key, "\\saved_key"); + + ret = RegSaveKeyA(hkey_main, saved_key, NULL); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", saved_key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + ret = RegSetValueExA(key, "test", 0, REG_SZ, (BYTE *)"value", 6); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + /* try to unload though the key handle is live */ + pRtlInitUnicodeString(&key_name, L"\\REGISTRY\\Machine\\Test"); + InitializeObjectAttributes(&attr, &key_name, OBJ_CASE_INSENSITIVE, NULL, NULL); + status = pNtUnloadKey(&attr); + ok(status == STATUS_CANNOT_DELETE, "expected STATUS_CANNOT_DELETE, got %08lx\n", status); + + RegCloseKey(key); + + ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test"); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", ""); + ok(ret == ERROR_INVALID_PARAMETER, "expected INVALID_PARAMETER, got %ld\n", ret); + + /* check if modifications are saved */ + ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", saved_key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + size = sizeof(buf); + ret = RegGetValueA(key, NULL, "test", RRF_RT_REG_SZ, NULL, buf, &size); + todo_wine ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + if (ret == ERROR_SUCCESS) + { + ok(size == 6, "size = %ld\n", size); + ok(!strcmp(buf, "value"), "buf = %s\n", buf); + } + + RegCloseKey(key); + + ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test"); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + pRtlInitUnicodeString(&key_name, L"\\REGISTRY\\User\\.Default"); + InitializeObjectAttributes(&attr, &key_name, OBJ_CASE_INSENSITIVE, NULL, NULL); + status = pNtUnloadKey(&attr); +#ifdef __REACTOS__ + ok(status == STATUS_ACCESS_DENIED || broken(status == STATUS_CANNOT_DELETE) /* WS03 */, "expected STATUS_ACCESS_DENIED, got %08lx\n", status); +#else + ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %08lx\n", status); +#endif + + ret = RegUnLoadKeyA(HKEY_USERS, ".Default"); + ok(ret == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", ret); + + set_privileges(SE_RESTORE_NAME, FALSE); + set_privileges(SE_BACKUP_NAME, FALSE); + + p = strrchr(saved_key, '\\'); + *p = 0; + delete_dir(saved_key); +} + +/* Helper function to wait for a file blocked by the registry to be available */ +static void wait_file_available(char *path) +{ + int attempts = 0; + HANDLE file = NULL; + + while (((file = CreateFileA(path, GENERIC_READ, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) + && attempts++ < 10) + { + Sleep(200); + } + ok(file != INVALID_HANDLE_VALUE, "couldn't open file %s after 10 attempts error %ld.\n", path, GetLastError()); + CloseHandle(file); +} + +static void test_reg_load_app_key(void) +{ +#if defined(__REACTOS__) && DLL_EXPORT_VERSION < 0x600 + skip("test_reg_load_app_key() can't be built unless DLL_EXPORT_VERSION >= 0x600\n"); +#else + DWORD ret, size; + char hivefilepath[2 * MAX_PATH], *p; + const BYTE test_data[] = "Hello World"; + BYTE output[sizeof(test_data)]; + HKEY appkey = NULL; + + if (!set_privileges(SE_BACKUP_NAME, TRUE)) { win_skip("Failed to set SE_BACKUP_NAME privileges, skipping tests\n"); return; } - ret = RegSaveKeyA(hkey_main, "saved_key", NULL); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + GetTempPathA(MAX_PATH, hivefilepath); + strcat(hivefilepath, "\\wine_reg_test"); + CreateDirectoryA(hivefilepath, NULL); + strcat(hivefilepath, "\\saved_key"); + + ret = RegSaveKeyA(hkey_main, hivefilepath, NULL); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); set_privileges(SE_BACKUP_NAME, FALSE); + + /* Test simple key load */ + /* Check if the changes are saved */ + ret = RegLoadAppKeyA(hivefilepath, &appkey, KEY_READ | KEY_WRITE, 0, 0); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + ok(appkey != NULL, "got a null key\n"); + + ret = RegSetValueExA(appkey, "testkey", 0, REG_BINARY, test_data, sizeof(test_data)); + todo_wine ok(ret == ERROR_SUCCESS, "couldn't set key value %lx\n", ret); + RegCloseKey(appkey); + + wait_file_available(hivefilepath); + + appkey = NULL; + ret = RegLoadAppKeyA(hivefilepath, &appkey, KEY_READ, 0, 0); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + ok(appkey != NULL, "got a null key\n"); + + size = sizeof(test_data); + memset(output, 0xff, sizeof(output)); + ret = RegGetValueA(appkey, NULL, "testkey", RRF_RT_REG_BINARY, NULL, output, &size); + todo_wine ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + ok(size == sizeof(test_data), "size doesn't match %ld != %ld\n", size, (DWORD)sizeof(test_data)); + todo_wine ok(!memcmp(test_data, output, sizeof(test_data)), "output is not what expected\n"); + + RegCloseKey(appkey); + + wait_file_available(hivefilepath); + + p = strrchr(hivefilepath, '\\'); + *p = 0; + delete_dir(hivefilepath); +#endif } -static void test_reg_load_key(void) -{ - DWORD ret; - HKEY hkHandle; - - if (!set_privileges(SE_RESTORE_NAME, TRUE) || - !set_privileges(SE_BACKUP_NAME, FALSE)) - { - win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n"); - return; - } - - ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", "saved_key"); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); - - set_privileges(SE_RESTORE_NAME, FALSE); - - ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &hkHandle); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); - - RegCloseKey(hkHandle); -} - -static void test_reg_unload_key(void) -{ - DWORD ret; - - if (!set_privileges(SE_RESTORE_NAME, TRUE) || - !set_privileges(SE_BACKUP_NAME, FALSE)) - { - win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n"); - return; - } - - ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test"); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); - - set_privileges(SE_RESTORE_NAME, FALSE); - - DeleteFileA("saved_key"); - DeleteFileA("saved_key.LOG"); -} - -/* tests that show that RegConnectRegistry and +/* tests that show that RegConnectRegistry and OpenSCManager accept computer names without the \\ prefix (what MSDN says). */ static void test_regconnectregistry( void) @@ -1631,24 +1779,18 @@ static void test_regconnectregistry( void) SetLastError(0xdeadbeef); ret = GetComputerNameA(compName, &len); - ok( ret, "GetComputerName failed err = %d\n", GetLastError()); + ok( ret, "GetComputerName failed err = %ld\n", GetLastError()); if( !ret) return; lstrcpyA(netwName, "\\\\"); lstrcpynA(netwName+2, compName, MAX_COMPUTERNAME_LENGTH + 1); retl = RegConnectRegistryA( compName, HKEY_LOCAL_MACHINE, &hkey); - ok( !retl || - retl == ERROR_DLL_INIT_FAILED || - retl == ERROR_BAD_NETPATH, /* some win2k */ - "RegConnectRegistryA failed err = %d\n", retl); + ok( !retl, "RegConnectRegistryA failed err = %ld\n", retl); if( !retl) RegCloseKey( hkey); retl = RegConnectRegistryA( netwName, HKEY_LOCAL_MACHINE, &hkey); - ok( !retl || - retl == ERROR_DLL_INIT_FAILED || - retl == ERROR_BAD_NETPATH, /* some win2k */ - "RegConnectRegistryA failed err = %d\n", retl); + ok( !retl, "RegConnectRegistryA failed err = %ld\n", retl); if( !retl) RegCloseKey( hkey); SetLastError(0xdeadbeef); @@ -1659,12 +1801,12 @@ static void test_regconnectregistry( void) return; } - ok( schnd != NULL, "OpenSCManagerA failed err = %d\n", GetLastError()); + ok( schnd != NULL, "OpenSCManagerA failed err = %ld\n", GetLastError()); CloseServiceHandle( schnd); SetLastError(0xdeadbeef); schnd = OpenSCManagerA( netwName, NULL, GENERIC_READ); - ok( schnd != NULL, "OpenSCManagerA failed err = %d\n", GetLastError()); + ok( schnd != NULL, "OpenSCManagerA failed err = %ld\n", GetLastError()); CloseServiceHandle( schnd); } @@ -1676,13 +1818,11 @@ static void test_reg_query_value(void) WCHAR valW[5]; LONG size, ret; - static const WCHAR expected[] = {'d','a','t','a',0}; - ret = RegCreateKeyA(hkey_main, "subkey", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueA(subkey, NULL, REG_SZ, "data", 4); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* try an invalid hkey */ SetLastError(0xdeadbeef); @@ -1691,58 +1831,58 @@ static void test_reg_query_value(void) ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY || /* Windows 98 returns BADKEY */ ret == ERROR_ACCESS_DENIED, /* non-admin winxp */ - "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %ld\n", ret); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a NULL hkey */ SetLastError(0xdeadbeef); size = MAX_PATH; ret = RegQueryValueA(NULL, "subkey", val, &size); ok(ret == ERROR_INVALID_HANDLE || ret == ERROR_BADKEY, /* Windows 98 returns BADKEY */ - "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %ld\n", ret); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a NULL value */ size = MAX_PATH; ret = RegQueryValueA(hkey_main, "subkey", NULL, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); - ok(size == 5, "Expected 5, got %d\n", size); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + ok(size == 5, "Expected 5, got %ld\n", size); /* try a NULL size */ SetLastError(0xdeadbeef); val[0] = '\0'; ret = RegQueryValueA(hkey_main, "subkey", val, NULL); - ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!val[0], "Expected val to be untouched, got %s\n", val); /* try a NULL value and size */ ret = RegQueryValueA(hkey_main, "subkey", NULL, NULL); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* try a size too small */ SetLastError(0xdeadbeef); val[0] = '\0'; size = 1; ret = RegQueryValueA(hkey_main, "subkey", val, &size); - ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", ret); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!val[0], "Expected val to be untouched, got %s\n", val); - ok(size == 5, "Expected 5, got %d\n", size); + ok(size == 5, "Expected 5, got %ld\n", size); /* successfully read the value using 'subkey' */ size = MAX_PATH; ret = RegQueryValueA(hkey_main, "subkey", val, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(!lstrcmpA(val, "data"), "Expected 'data', got '%s'\n", val); - ok(size == 5, "Expected 5, got %d\n", size); + ok(size == 5, "Expected 5, got %ld\n", size); /* successfully read the value using the subkey key */ size = MAX_PATH; ret = RegQueryValueA(subkey, NULL, val, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(!lstrcmpA(val, "data"), "Expected 'data', got '%s'\n", val); - ok(size == 5, "Expected 5, got %d\n", size); + ok(size == 5, "Expected 5, got %ld\n", size); /* unicode - try size too small */ SetLastError(0xdeadbeef); @@ -1754,38 +1894,38 @@ static void test_reg_query_value(void) win_skip("RegQueryValueW is not implemented\n"); goto cleanup; } - ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", ret); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!valW[0], "Expected valW to be untouched\n"); - ok(size == sizeof(expected), "Got wrong size: %d\n", size); + ok(size == 10, "Got wrong size: %ld\n", size); /* unicode - try size in WCHARS */ SetLastError(0xdeadbeef); - size = sizeof(valW) / sizeof(WCHAR); + size = ARRAY_SIZE(valW); ret = RegQueryValueW(subkey, NULL, valW, &size); - ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", ret); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!valW[0], "Expected valW to be untouched\n"); - ok(size == sizeof(expected), "Got wrong size: %d\n", size); + ok(size == 10, "Got wrong size: %ld\n", size); /* unicode - successfully read the value */ size = sizeof(valW); ret = RegQueryValueW(subkey, NULL, valW, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); - ok(!lstrcmpW(valW, expected), "Got wrong value\n"); - ok(size == sizeof(expected), "Got wrong size: %d\n", size); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + ok(!lstrcmpW(valW, L"data"), "Got wrong value\n"); + ok(size == 10, "Got wrong size: %ld\n", size); /* unicode - set the value without a NULL terminator */ - ret = RegSetValueW(subkey, NULL, REG_SZ, expected, sizeof(expected)-sizeof(WCHAR)); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ret = RegSetValueW(subkey, NULL, REG_SZ, L"data", 8); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* unicode - read the unterminated value, value is terminated for us */ memset(valW, 'a', sizeof(valW)); size = sizeof(valW); ret = RegQueryValueW(subkey, NULL, valW, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); - ok(!lstrcmpW(valW, expected), "Got wrong value\n"); - ok(size == sizeof(expected), "Got wrong size: %d\n", size); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + ok(!lstrcmpW(valW, L"data"), "Got wrong value\n"); + ok(size == 10, "Got wrong size: %ld\n", size); cleanup: RegDeleteKeyA(subkey, ""); @@ -1802,7 +1942,7 @@ static void test_reg_query_info(void) char expectbuffer[32]; WCHAR expectbufferW[32]; char subkey_class[] = "subkey class"; - WCHAR subkey_classW[] = {'s','u','b','k','e','y',' ','c','l','a','s','s',0}; + WCHAR subkey_classW[] = L"subkey class"; char subsubkey_class[] = "subsubkey class"; DWORD classlen; DWORD subkeys, maxsubkeylen, maxclasslen; @@ -1811,134 +1951,132 @@ static void test_reg_query_info(void) FILETIME lastwrite; ret = RegCreateKeyExA(hkey_main, "subkey", 0, subkey_class, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* all parameters NULL */ ret = RegQueryInfoKeyA(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_INVALID_HANDLE, "ret = %d\n", ret); + ok(ret == ERROR_INVALID_HANDLE, "ret = %ld\n", ret); ret = RegQueryInfoKeyW(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_INVALID_HANDLE, "ret = %d\n", ret); + ok(ret == ERROR_INVALID_HANDLE, "ret = %ld\n", ret); /* not requesting any information */ ret = RegQueryInfoKeyA(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); /* class without length is invalid */ memset(classbuffer, 0x55, sizeof(classbuffer)); ret = RegQueryInfoKeyA(subkey, classbuffer, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_INVALID_PARAMETER, "ret = %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "ret = %ld\n", ret); ok(classbuffer[0] == 0x55, "classbuffer[0] = 0x%x\n", classbuffer[0]); memset(classbufferW, 0x55, sizeof(classbufferW)); ret = RegQueryInfoKeyW(subkey, classbufferW, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_INVALID_PARAMETER, "ret = %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "ret = %ld\n", ret); ok(classbufferW[0] == 0x5555, "classbufferW[0] = 0x%x\n", classbufferW[0]); /* empty key */ sdlen = classlen =0; ret = RegQueryInfoKeyA(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == strlen(subkey_class), "classlen = %u\n", classlen); - ok(subkeys == 0, "subkeys = %u\n", subkeys); - ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); - ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); - ok(values == 0, "values = %u\n", values); - ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); - ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); - todo_wine ok(sdlen != 0, "sdlen = %u\n", sdlen); - ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); - ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == strlen(subkey_class), "classlen = %lu\n", classlen); + ok(subkeys == 0, "subkeys = %lu\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %lu\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %lu\n", maxclasslen); + ok(values == 0, "values = %lu\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %lu\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %lu\n", maxvaluelen); + todo_wine ok(sdlen != 0, "sdlen = %lu\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %lu\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %lu\n", lastwrite.dwHighDateTime); sdlen = classlen = 0; ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == strlen(subkey_class), "classlen = %u\n", classlen); - ok(subkeys == 0, "subkeys = %u\n", subkeys); - ok(maxsubkeylen == 0, "maxsubkeylen = %u\n", maxsubkeylen); - ok(maxclasslen == 0, "maxclasslen = %u\n", maxclasslen); - ok(values == 0, "values = %u\n", values); - ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); - ok(maxvaluelen == 0, "maxvaluelen = %u\n", maxvaluelen); - todo_wine ok(sdlen != 0, "sdlen = %u\n", sdlen); - ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); - ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == strlen(subkey_class), "classlen = %lu\n", classlen); + ok(subkeys == 0, "subkeys = %lu\n", subkeys); + ok(maxsubkeylen == 0, "maxsubkeylen = %lu\n", maxsubkeylen); + ok(maxclasslen == 0, "maxclasslen = %lu\n", maxclasslen); + ok(values == 0, "values = %lu\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %lu\n", maxvaluenamelen); + ok(maxvaluelen == 0, "maxvaluelen = %lu\n", maxvaluelen); + todo_wine ok(sdlen != 0, "sdlen = %lu\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %lu\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %lu\n", lastwrite.dwHighDateTime); ret = RegCreateKeyExA(subkey, "subsubkey", 0, subsubkey_class, 0, KEY_ALL_ACCESS, NULL, &subsubkey, NULL); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE*)"data", 5); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* with subkey & default value */ sdlen = classlen = 0; ret = RegQueryInfoKeyA(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == strlen(subkey_class), "classlen = %u\n", classlen); - ok(subkeys == 1, "subkeys = %u\n", subkeys); - ok(maxsubkeylen == strlen("subsubkey"), "maxsubkeylen = %u\n", maxsubkeylen); - ok(maxclasslen == strlen(subsubkey_class), "maxclasslen = %u\n", maxclasslen); - ok(values == 1, "values = %u\n", values); - ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); - ok(maxvaluelen == sizeof("data") * sizeof(WCHAR), "maxvaluelen = %u\n", maxvaluelen); - todo_wine ok(sdlen != 0, "sdlen = %u\n", sdlen); - ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); - ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == strlen(subkey_class), "classlen = %lu\n", classlen); + ok(subkeys == 1, "subkeys = %lu\n", subkeys); + ok(maxsubkeylen == strlen("subsubkey"), "maxsubkeylen = %lu\n", maxsubkeylen); + ok(maxclasslen == strlen(subsubkey_class), "maxclasslen = %lu\n", maxclasslen); + ok(values == 1, "values = %lu\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %lu\n", maxvaluenamelen); + ok(maxvaluelen == sizeof("data") * sizeof(WCHAR), "maxvaluelen = %lu\n", maxvaluelen); + todo_wine ok(sdlen != 0, "sdlen = %lu\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %lu\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %lu\n", lastwrite.dwHighDateTime); sdlen = classlen = 0; ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == strlen(subkey_class), "classlen = %u\n", classlen); - ok(subkeys == 1, "subkeys = %u\n", subkeys); - ok(maxsubkeylen == strlen("subsubkey"), "maxsubkeylen = %u\n", maxsubkeylen); - ok(maxclasslen == strlen(subsubkey_class), "maxclasslen = %u\n", maxclasslen); - ok(values == 1, "values = %u\n", values); - ok(maxvaluenamelen == 0, "maxvaluenamelen = %u\n", maxvaluenamelen); - ok(maxvaluelen == sizeof("data") * sizeof(WCHAR), "maxvaluelen = %u\n", maxvaluelen); - todo_wine ok(sdlen != 0, "sdlen = %u\n", sdlen); - ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %u\n", lastwrite.dwLowDateTime); - ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %u\n", lastwrite.dwHighDateTime); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == strlen(subkey_class), "classlen = %lu\n", classlen); + ok(subkeys == 1, "subkeys = %lu\n", subkeys); + ok(maxsubkeylen == strlen("subsubkey"), "maxsubkeylen = %lu\n", maxsubkeylen); + ok(maxclasslen == strlen(subsubkey_class), "maxclasslen = %lu\n", maxclasslen); + ok(values == 1, "values = %lu\n", values); + ok(maxvaluenamelen == 0, "maxvaluenamelen = %lu\n", maxvaluenamelen); + ok(maxvaluelen == sizeof("data") * sizeof(WCHAR), "maxvaluelen = %lu\n", maxvaluelen); + todo_wine ok(sdlen != 0, "sdlen = %lu\n", sdlen); + ok(lastwrite.dwLowDateTime != 0, "lastwrite.dwLowDateTime = %lu\n", lastwrite.dwLowDateTime); + ok(lastwrite.dwHighDateTime != 0, "lastwrite.dwHighDateTime = %lu\n", lastwrite.dwHighDateTime); ret = RegSetValueExA(subkey, "value one", 0, REG_SZ, (const BYTE*)"first value data", 17); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueExA(subkey, "value 2", 0, REG_SZ, (const BYTE*)"second value data", 18); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* with named value */ classlen = 0; ret = RegQueryInfoKeyA(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(values == 3, "values = %u\n", values); - ok(maxvaluenamelen == strlen("value one"), "maxvaluenamelen = %u\n", maxvaluenamelen); - ok(maxvaluelen == sizeof("second value data") * sizeof(WCHAR), "maxvaluelen = %u\n", maxvaluelen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(values == 3, "values = %lu\n", values); + ok(maxvaluenamelen == strlen("value one"), "maxvaluenamelen = %lu\n", maxvaluenamelen); + ok(maxvaluelen == sizeof("second value data") * sizeof(WCHAR), "maxvaluelen = %lu\n", maxvaluelen); classlen = 0; ret = RegQueryInfoKeyW(subkey, NULL, &classlen, NULL, &subkeys, &maxsubkeylen, &maxclasslen, &values, &maxvaluenamelen, &maxvaluelen, &sdlen, &lastwrite); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(values == 3, "values = %u\n", values); - ok(maxvaluenamelen == strlen("value one"), "maxvaluenamelen = %u\n", maxvaluenamelen); - ok(maxvaluelen == sizeof("second value data") * sizeof(WCHAR), "maxvaluelen = %u\n", maxvaluelen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(values == 3, "values = %lu\n", values); + ok(maxvaluenamelen == strlen("value one"), "maxvaluenamelen = %lu\n", maxvaluenamelen); + ok(maxvaluelen == sizeof("second value data") * sizeof(WCHAR), "maxvaluelen = %lu\n", maxvaluelen); /* class name with zero size buffer */ memset(classbuffer, 0x55, sizeof(classbuffer)); classlen = 0; ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == strlen(subkey_class) /* win2k */ || - classlen == 0, "classlen = %u\n", classlen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + todo_wine ok(classlen == 0, "classlen = %lu\n", classlen); memset(expectbuffer, 0x55, sizeof(expectbuffer)); ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)), "classbuffer was modified\n"); memset(classbufferW, 0x55, sizeof(classbufferW)); classlen = 0; ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == strlen(subkey_class) /* win2k */ || - classlen == 0, "classlen = %u\n", classlen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + todo_wine ok(classlen == 0, "classlen = %lu\n", classlen); memset(expectbufferW, 0x55, sizeof(expectbufferW)); ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW was modified\n"); @@ -1946,8 +2084,8 @@ static void test_reg_query_info(void) memset(classbuffer, 0x55, sizeof(classbuffer)); classlen = 1; ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_MORE_DATA, "ret = %d\n", ret); - ok(classlen == 0, "classlen = %u\n", classlen); + ok(ret == ERROR_MORE_DATA, "ret = %ld\n", ret); + ok(classlen == 0, "classlen = %lu\n", classlen); memset(expectbuffer, 0x55, sizeof(expectbuffer)); expectbuffer[0] = 0; ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)), "classbuffer was modified\n"); @@ -1955,9 +2093,10 @@ static void test_reg_query_info(void) memset(classbufferW, 0x55, sizeof(classbufferW)); classlen = 1; ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %d\n", ret); + /* failure-code changed to ERROR_MORE_DATA in recent win10 */ + ok((ret == ERROR_INSUFFICIENT_BUFFER) || (ret == ERROR_MORE_DATA), "ret = %ld\n", ret); ok(classlen == 0 /* win8 */ || - classlen == strlen(subkey_class), "classlen = %u\n", classlen); + classlen == strlen(subkey_class), "classlen = %lu\n", classlen); memset(expectbufferW, 0x55, sizeof(expectbufferW)); ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW was modified\n"); @@ -1965,8 +2104,8 @@ static void test_reg_query_info(void) memset(classbuffer, 0x55, sizeof(classbuffer)); classlen = sizeof(subkey_class) - 1; ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_MORE_DATA, "ret = %d\n", ret); - ok(classlen == sizeof(subkey_class) - 2, "classlen = %u\n", classlen); + ok(ret == ERROR_MORE_DATA, "ret = %ld\n", ret); + ok(classlen == sizeof(subkey_class) - 2, "classlen = %lu\n", classlen); memset(expectbuffer, 0x55, sizeof(expectbuffer)); strcpy(expectbuffer, subkey_class); expectbuffer[sizeof(subkey_class) - 2] = 0; @@ -1978,9 +2117,9 @@ static void test_reg_query_info(void) memset(classbufferW, 0x55, sizeof(classbufferW)); classlen = sizeof(subkey_class) - 1; ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %d\n", ret); + ok(ret == ERROR_INSUFFICIENT_BUFFER, "ret = %ld\n", ret); ok(classlen == sizeof(subkey_class) - 2 /* win8 */ || - classlen == strlen(subkey_class), "classlen = %u\n", classlen); + classlen == strlen(subkey_class), "classlen = %lu\n", classlen); memset(expectbufferW, 0x55, sizeof(expectbufferW)); ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW was modified\n"); @@ -1988,8 +2127,8 @@ static void test_reg_query_info(void) memset(classbuffer, 0x55, sizeof(classbuffer)); classlen = sizeof(subkey_class); ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == sizeof(subkey_class) - 1, "classlen = %u\n", classlen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == sizeof(subkey_class) - 1, "classlen = %lu\n", classlen); memset(expectbuffer, 0x55, sizeof(expectbuffer)); strcpy(expectbuffer, subkey_class); ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)), @@ -1999,8 +2138,8 @@ static void test_reg_query_info(void) memset(classbuffer, 0x55, sizeof(classbuffer)); classlen = 0xdeadbeef; ret = RegQueryInfoKeyA(subkey, classbuffer, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == sizeof(subkey_class) - 1, "classlen = %u\n", classlen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == sizeof(subkey_class) - 1, "classlen = %lu\n", classlen); memset(expectbuffer, 0x55, sizeof(expectbuffer)); strcpy(expectbuffer, subkey_class); ok(!memcmp(classbuffer, expectbuffer, sizeof(classbuffer)), @@ -2010,24 +2149,24 @@ static void test_reg_query_info(void) memset(classbufferW, 0x55, sizeof(classbufferW)); classlen = sizeof(subkey_class); ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == sizeof(subkey_class) - 1, "classlen = %u\n", classlen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == sizeof(subkey_class) - 1, "classlen = %lu\n", classlen); memset(expectbufferW, 0x55, sizeof(expectbufferW)); lstrcpyW(expectbufferW, subkey_classW); ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW = %s, expected %s\n", - wine_dbgstr_wn(classbufferW, sizeof(classbufferW) / sizeof(WCHAR)), wine_dbgstr_w(expectbufferW)); + wine_dbgstr_wn(classbufferW, ARRAY_SIZE(classbufferW)), wine_dbgstr_w(expectbufferW)); memset(classbufferW, 0x55, sizeof(classbufferW)); classlen = 0xdeadbeef; ret = RegQueryInfoKeyW(subkey, classbufferW, &classlen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "ret = %d\n", ret); - ok(classlen == sizeof(subkey_class) - 1, "classlen = %u\n", classlen); + ok(ret == ERROR_SUCCESS, "ret = %ld\n", ret); + ok(classlen == sizeof(subkey_class) - 1, "classlen = %lu\n", classlen); memset(expectbufferW, 0x55, sizeof(expectbufferW)); lstrcpyW(expectbufferW, subkey_classW); ok(!memcmp(classbufferW, expectbufferW, sizeof(classbufferW)), "classbufferW = %s, expected %s\n", - wine_dbgstr_wn(classbufferW, sizeof(classbufferW) / sizeof(WCHAR)), wine_dbgstr_w(expectbufferW)); + wine_dbgstr_wn(classbufferW, ARRAY_SIZE(classbufferW)), wine_dbgstr_w(expectbufferW)); RegDeleteKeyA(subsubkey, ""); RegCloseKey(subsubkey); @@ -2045,68 +2184,197 @@ static void test_string_termination(void) DWORD insize, outsize, nsize; ret = RegCreateKeyA(hkey_main, "string_termination", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* Off-by-one RegSetValueExA -> adds a trailing '\0'! */ insize=sizeof(string)-1; ret = RegSetValueExA(subkey, "stringtest", 0, REG_SZ, (BYTE*)string, insize); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", ret); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); outsize=insize; ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, buffer, &outsize); - ok(ret == ERROR_MORE_DATA, "RegQueryValueExA returned: %d\n", ret); + ok(ret == ERROR_MORE_DATA, "RegQueryValueExA returned: %ld\n", ret); /* Off-by-two RegSetValueExA -> no trailing '\0' */ insize=sizeof(string)-2; ret = RegSetValueExA(subkey, "stringtest", 0, REG_SZ, (BYTE*)string, insize); - ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", ret); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); outsize=0; ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, NULL, &outsize); - ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", ret); - ok(outsize == insize, "wrong size %u != %u\n", outsize, insize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size %lu != %lu\n", outsize, insize); /* RegQueryValueExA may return a string with no trailing '\0' */ outsize=insize; memset(buffer, 0xbd, sizeof(buffer)); ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, buffer, &outsize); - ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", ret); - ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize); - ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n", - wine_debugstr_an((char*)buffer, outsize), outsize, string); - ok(buffer[insize] == 0xbd, "buffer overflow at %u %02x\n", insize, buffer[insize]); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, string); + ok(buffer[insize] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); /* RegQueryValueExA adds a trailing '\0' if there is room */ outsize=insize+1; memset(buffer, 0xbd, sizeof(buffer)); ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, buffer, &outsize); - ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", ret); - ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize); - ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n", - wine_debugstr_an((char*)buffer, outsize), outsize, string); - ok(buffer[insize] == 0, "buffer overflow at %u %02x\n", insize, buffer[insize]); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, string); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); /* RegEnumValueA may return a string with no trailing '\0' */ outsize=insize; memset(buffer, 0xbd, sizeof(buffer)); nsize=sizeof(name); ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer, &outsize); - ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", ret); + ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", ret); ok(strcmp(name, "stringtest") == 0, "wrong name: %s\n", name); - ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize); - ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n", - wine_debugstr_an((char*)buffer, outsize), outsize, string); - ok(buffer[insize] == 0xbd, "buffer overflow at %u %02x\n", insize, buffer[insize]); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, string); + ok(buffer[insize] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); /* RegEnumValueA adds a trailing '\0' if there is room */ outsize=insize+1; memset(buffer, 0xbd, sizeof(buffer)); nsize=sizeof(name); ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer, &outsize); - ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", ret); + ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", ret); ok(strcmp(name, "stringtest") == 0, "wrong name: %s\n", name); - ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize); - ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n", - wine_debugstr_an((char*)buffer, outsize), outsize, string); - ok(buffer[insize] == 0, "buffer overflow at %u %02x\n", insize, buffer[insize]); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, string); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegGetValueA always adds the trailing '\0' */ + if (pRegGetValueA) + { + outsize = insize; + ret = pRegGetValueA(subkey, NULL, "stringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + ok(ret == ERROR_MORE_DATA, "RegGetValueA returned: %ld\n", ret); + ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + memset(buffer, 0xbd, sizeof(buffer)); + ret = pRegGetValueA(subkey, NULL, "stringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegGetValueA returned: %ld\n", ret); + ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + ok(memcmp(buffer, string, insize) == 0, "bad string: %s/%lu != %s\n", + debugstr_an((char*)buffer, insize), insize, string); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + } + + RegDeleteKeyA(subkey, ""); + RegCloseKey(subkey); +} + +static void test_multistring_termination(void) +{ + HKEY subkey; + LSTATUS ret; + static const char multistring[] = "Aa\0Bb\0Cc\0"; + char name[sizeof("multistringtest")]; + BYTE buffer[sizeof(multistring)]; + DWORD insize, outsize, nsize; + + ret = RegCreateKeyA(hkey_main, "multistring_termination", &subkey); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + + /* Off-by-one RegSetValueExA -> only one trailing '\0' */ + insize = sizeof(multistring) - 1; + ret = RegSetValueExA(subkey, "multistringtest", 0, REG_SZ, (BYTE*)multistring, insize); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); + outsize = 0; + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, NULL, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size %lu != %lu\n", outsize, insize); + + /* Off-by-two RegSetValueExA -> adds a trailing '\0'! */ + insize = sizeof(multistring) - 2; + ret = RegSetValueExA(subkey, "multistringtest", 0, REG_SZ, (BYTE*)multistring, insize); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); + outsize = insize; + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_MORE_DATA, "RegQueryValueExA returned: %ld\n", ret); + + /* Off-by-three RegSetValueExA -> no trailing '\0' */ + insize = sizeof(multistring) - 3; + ret = RegSetValueExA(subkey, "multistringtest", 0, REG_SZ, (BYTE*)multistring, insize); + ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", ret); + outsize = 0; + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, NULL, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size %lu != %lu\n", outsize, insize); + + /* RegQueryValueExA may return a multistring with no trailing '\0' */ + outsize = insize; + memset(buffer, 0xbd, sizeof(buffer)); + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegQueryValueExA adds one trailing '\0' if there is room */ + outsize = insize + 1; + memset(buffer, 0xbd, sizeof(buffer)); + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegQueryValueExA doesn't add a second trailing '\0' even if there is room */ + outsize = insize + 2; + memset(buffer, 0xbd, sizeof(buffer)); + ret = RegQueryValueExA(subkey, "multistringtest", NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", ret); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize + 1] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize + 1]); + + /* RegEnumValueA may return a multistring with no trailing '\0' */ + outsize = insize; + memset(buffer, 0xbd, sizeof(buffer)); + nsize = sizeof(name); + ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", ret); + ok(strcmp(name, "multistringtest") == 0, "wrong name: %s\n", name); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegEnumValueA adds one trailing '\0' even if there's room for two */ + outsize = insize + 2; + memset(buffer, 0xbd, sizeof(buffer)); + nsize = sizeof(name); + ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", ret); + ok(strcmp(name, "multistringtest") == 0, "wrong name: %s\n", name); + ok(outsize == insize, "wrong size: %lu != %lu\n", outsize, insize); + ok(memcmp(buffer, multistring, outsize) == 0, "bad multistring: %s/%lu != %s\n", + debugstr_an((char*)buffer, outsize), outsize, multistring); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + ok(buffer[insize + 1] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize]); + + /* RegGetValueA always adds one trailing '\0' even if there's room for two */ + if (pRegGetValueA) + { + outsize = insize; + ret = pRegGetValueA(subkey, NULL, "multistringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + ok(ret == ERROR_MORE_DATA, "RegGetValueA returned: %ld\n", ret); + ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + outsize = insize + 2; + memset(buffer, 0xbd, sizeof(buffer)); + ret = pRegGetValueA(subkey, NULL, "multistringtest", RRF_RT_REG_SZ, NULL, buffer, &outsize); + ok(ret == ERROR_SUCCESS, "RegGetValueA returned: %ld\n", ret); + ok(outsize == insize + 1, "wrong size: %lu != %lu\n", outsize, insize + 1); + ok(buffer[insize] == 0, "buffer overflow at %lu %02x\n", insize, buffer[insize + 1]); + ok(buffer[insize + 1] == 0xbd, "buffer overflow at %lu %02x\n", insize, buffer[insize + 1]); + } RegDeleteKeyA(subkey, ""); RegCloseKey(subkey); @@ -2126,82 +2394,82 @@ static void test_reg_copy_tree(void) } ret = RegCreateKeyA(hkey_main, "src", &src); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCreateKeyA(hkey_main, "dst", &dst); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* Copy nonexistent subkey */ ret = pRegCopyTreeA(src, "nonexistent_subkey", dst); - ok(ret == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); /* Create test keys and values */ ret = RegSetValueA(src, NULL, REG_SZ, "data", 4); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueExA(src, "value", 0, REG_SZ, (const BYTE *)"data2", 5); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCreateKeyA(src, "subkey2", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueA(subkey, NULL, REG_SZ, "data3", 5); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueExA(subkey, "value", 0, REG_SZ, (const BYTE *)"data4", 5); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCreateKeyA(src, "subkey3", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); /* Copy subkey */ ret = pRegCopyTreeA(src, "subkey2", dst); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); size = MAX_PATH; ret = RegQueryValueA(dst, NULL, buffer, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(!strcmp(buffer, "data3"), "Expected 'data3', got '%s'\n", buffer); dwsize = MAX_PATH; ret = RegQueryValueExA(dst, "value", NULL, &type, (BYTE *)buffer, &dwsize); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); - ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + ok(type == REG_SZ, "Expected REG_SZ, got %lu\n", type); ok(!strcmp(buffer, "data4"), "Expected 'data4', got '%s'\n", buffer); /* Copy full tree */ ret = pRegCopyTreeA(src, NULL, dst); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); size = MAX_PATH; ret = RegQueryValueA(dst, NULL, buffer, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(!strcmp(buffer, "data"), "Expected 'data', got '%s'\n", buffer); dwsize = MAX_PATH; ret = RegQueryValueExA(dst, "value", NULL, &type, (BYTE *)buffer, &dwsize); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); - ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + ok(type == REG_SZ, "Expected REG_SZ, got %lu\n", type); ok(!strcmp(buffer, "data2"), "Expected 'data2', got '%s'\n", buffer); ret = RegOpenKeyA(dst, "subkey2", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); size = MAX_PATH; ret = RegQueryValueA(subkey, NULL, buffer, &size); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(!strcmp(buffer, "data3"), "Expected 'data3', got '%s'\n", buffer); dwsize = MAX_PATH; ret = RegQueryValueExA(subkey, "value", NULL, &type, (BYTE *)buffer, &dwsize); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); - ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); + ok(type == REG_SZ, "Expected REG_SZ, got %lu\n", type); ok(!strcmp(buffer, "data4"), "Expected 'data4', got '%s'\n", buffer); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegOpenKeyA(dst, "subkey3", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); delete_key(src); delete_key(dst); @@ -2220,18 +2488,18 @@ static void test_reg_delete_tree(void) } ret = RegCreateKeyA(hkey_main, "subkey", &subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCreateKeyA(subkey, "subkey2", &subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueA(subkey, NULL, REG_SZ, "data", 4); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueA(subkey2, NULL, REG_SZ, "data2", 5); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = pRegDeleteTreeA(subkey, "subkey2"); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(RegOpenKeyA(subkey, "subkey2", &subkey2), "subkey2 was not deleted\n"); size = MAX_PATH; @@ -2239,30 +2507,30 @@ static void test_reg_delete_tree(void) "Default value of subkey no longer present\n"); ret = RegCreateKeyA(subkey, "subkey2", &subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = pRegDeleteTreeA(hkey_main, "subkey\\subkey2"); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(RegOpenKeyA(subkey, "subkey2", &subkey2), "subkey2 was not deleted\n"); ok(!RegQueryValueA(subkey, NULL, buffer, &size), "Default value of subkey no longer present\n"); ret = RegCreateKeyA(subkey, "subkey2", &subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCreateKeyA(subkey, "subkey3", &subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey2); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueA(subkey, NULL, REG_SZ, "data", 4); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegSetValueExA(subkey, "value", 0, REG_SZ, (const BYTE *)"data2", 5); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = pRegDeleteTreeA(subkey, NULL); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ok(!RegOpenKeyA(hkey_main, "subkey", &subkey), "subkey was deleted\n"); ok(RegOpenKeyA(subkey, "subkey2", &subkey2), @@ -2278,23 +2546,23 @@ static void test_reg_delete_tree(void) ok(RegQueryValueExA(subkey, "value", NULL, &type, (BYTE *)buffer, &dwsize), "Value is still present\n"); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegOpenKeyA(hkey_main, "subkey", &subkey); ok(ret == ERROR_SUCCESS, "subkey was deleted\n"); ret = pRegDeleteTreeA(subkey, ""); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = RegOpenKeyA(hkey_main, "subkey", &subkey); ok(ret == ERROR_SUCCESS, "subkey was deleted\n"); ret = RegCloseKey(subkey); - ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret); ret = pRegDeleteTreeA(hkey_main, "not-here"); ok(ret == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %d\n", ret); + "Expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); } static void test_rw_order(void) @@ -2324,7 +2592,7 @@ static void test_rw_order(void) ok(!RegQueryInfoKeyA(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &values, &value_name_max_len, NULL, NULL, NULL), "RegQueryInfoKeyA failed\n"); - ok(values == 4, "Expected 4 values, got %u\n", values); + ok(values == 4, "Expected 4 values, got %lu\n", values); /* Value enumeration preserves RegSetValueEx call order */ value_len = 2; @@ -2345,8 +2613,7 @@ static void test_rw_order(void) static void test_symlinks(void) { - static const WCHAR targetW[] = {'\\','S','o','f','t','w','a','r','e','\\','W','i','n','e', - '\\','T','e','s','t','\\','t','a','r','g','e','t',0}; + static const WCHAR targetW[] = L"\\Software\\Wine\\Test\\target"; BYTE buffer[1024]; UNICODE_STRING target_str; WCHAR *target; @@ -2363,129 +2630,129 @@ static void test_symlinks(void) pRtlFormatCurrentUserKeyPath( &target_str ); target_len = target_str.Length + sizeof(targetW); - target = HeapAlloc( GetProcessHeap(), 0, target_len ); + target = malloc( target_len ); memcpy( target, target_str.Buffer, target_str.Length ); memcpy( target + target_str.Length/sizeof(WCHAR), targetW, sizeof(targetW) ); err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_CREATE_LINK, KEY_ALL_ACCESS, NULL, &link, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed: %lu\n", err ); /* REG_SZ is not allowed */ err = RegSetValueExA( link, "SymbolicLinkValue", 0, REG_SZ, (BYTE *)"foobar", sizeof("foobar") ); - ok( err == ERROR_ACCESS_DENIED, "RegSetValueEx wrong error %u\n", err ); + ok( err == ERROR_ACCESS_DENIED, "RegSetValueEx wrong error %lu\n", err ); err = RegSetValueExA( link, "SymbolicLinkValue", 0, REG_LINK, (BYTE *)target, target_len - sizeof(WCHAR) ); - ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %lu\n", err ); /* other values are not allowed */ err = RegSetValueExA( link, "link", 0, REG_LINK, (BYTE *)target, target_len - sizeof(WCHAR) ); - ok( err == ERROR_ACCESS_DENIED, "RegSetValueEx wrong error %u\n", err ); + ok( err == ERROR_ACCESS_DENIED, "RegSetValueEx wrong error %lu\n", err ); /* try opening the target through the link */ err = RegOpenKeyA( hkey_main, "link", &key ); - ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKey wrong error %u\n", err ); + ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKey wrong error %lu\n", err ); err = RegCreateKeyExA( hkey_main, "target", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %lu\n", err ); dw = 0xbeef; err = RegSetValueExA( key, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); - ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %lu\n", err ); RegCloseKey( key ); err = RegOpenKeyA( hkey_main, "link", &key ); - ok( err == ERROR_SUCCESS, "RegOpenKey failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegOpenKey failed error %lu\n", err ); len = sizeof(buffer); err = RegQueryValueExA( key, "value", NULL, &type, buffer, &len ); - ok( err == ERROR_SUCCESS, "RegOpenKey failed error %u\n", err ); - ok( len == sizeof(DWORD), "wrong len %u\n", len ); + ok( err == ERROR_SUCCESS, "RegOpenKey failed error %lu\n", err ); + ok( len == sizeof(DWORD), "wrong len %lu\n", len ); len = sizeof(buffer); err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len ); - ok( err == ERROR_FILE_NOT_FOUND, "RegQueryValueEx wrong error %u\n", err ); + ok( err == ERROR_FILE_NOT_FOUND, "RegQueryValueEx wrong error %lu\n", err ); /* REG_LINK can be created in non-link keys */ err = RegSetValueExA( key, "SymbolicLinkValue", 0, REG_LINK, (BYTE *)target, target_len - sizeof(WCHAR) ); - ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegSetValueEx failed error %lu\n", err ); len = sizeof(buffer); err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len ); - ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err ); - ok( len == target_len - sizeof(WCHAR), "wrong len %u\n", len ); + ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %lu\n", err ); + ok( len == target_len - sizeof(WCHAR), "wrong len %lu\n", len ); err = RegDeleteValueA( key, "SymbolicLinkValue" ); - ok( err == ERROR_SUCCESS, "RegDeleteValue failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegDeleteValue failed error %lu\n", err ); RegCloseKey( key ); err = RegCreateKeyExA( hkey_main, "link", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %lu\n", err ); len = sizeof(buffer); err = RegQueryValueExA( key, "value", NULL, &type, buffer, &len ); - ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err ); - ok( len == sizeof(DWORD), "wrong len %u\n", len ); + ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %lu\n", err ); + ok( len == sizeof(DWORD), "wrong len %lu\n", len ); err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len ); - ok( err == ERROR_FILE_NOT_FOUND, "RegQueryValueEx wrong error %u\n", err ); + ok( err == ERROR_FILE_NOT_FOUND, "RegQueryValueEx wrong error %lu\n", err ); RegCloseKey( key ); /* now open the symlink itself */ err = RegOpenKeyExA( hkey_main, "link", REG_OPTION_OPEN_LINK, KEY_ALL_ACCESS, &key ); - ok( err == ERROR_SUCCESS, "RegOpenKeyEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegOpenKeyEx failed error %lu\n", err ); len = sizeof(buffer); err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len ); - ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err ); - ok( len == target_len - sizeof(WCHAR), "wrong len %u\n", len ); + ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %lu\n", err ); + ok( len == target_len - sizeof(WCHAR), "wrong len %lu\n", len ); RegCloseKey( key ); err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_OPEN_LINK, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyEx failed error %lu\n", err ); len = sizeof(buffer); err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len ); - ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %u\n", err ); - ok( len == target_len - sizeof(WCHAR), "wrong len %u\n", len ); + ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %lu\n", err ); + ok( len == target_len - sizeof(WCHAR), "wrong len %lu\n", len ); RegCloseKey( key ); err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_CREATE_LINK, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_ALREADY_EXISTS, "RegCreateKeyEx wrong error %u\n", err ); + ok( err == ERROR_ALREADY_EXISTS, "RegCreateKeyEx wrong error %lu\n", err ); err = RegCreateKeyExA( hkey_main, "link", 0, NULL, REG_OPTION_CREATE_LINK | REG_OPTION_OPEN_LINK, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_ALREADY_EXISTS, "RegCreateKeyEx wrong error %u\n", err ); + ok( err == ERROR_ALREADY_EXISTS, "RegCreateKeyEx wrong error %lu\n", err ); err = RegDeleteKeyA( hkey_main, "target" ); - ok( err == ERROR_SUCCESS, "RegDeleteKey failed error %u\n", err ); + ok( err == ERROR_SUCCESS, "RegDeleteKey failed error %lu\n", err ); err = RegDeleteKeyA( hkey_main, "link" ); - ok( err == ERROR_FILE_NOT_FOUND, "RegDeleteKey wrong error %u\n", err ); + ok( err == ERROR_FILE_NOT_FOUND, "RegDeleteKey wrong error %lu\n", err ); status = pNtDeleteKey( link ); - ok( !status, "NtDeleteKey failed: 0x%08x\n", status ); + ok( !status, "NtDeleteKey failed: 0x%08lx\n", status ); RegCloseKey( link ); - HeapFree( GetProcessHeap(), 0, target ); + free( target ); pRtlFreeUnicodeString( &target_str ); } static DWORD get_key_value( HKEY root, const char *name, DWORD flags ) { HKEY key; - DWORD err, type, dw, len = sizeof(dw); + DWORD err, type, dw = 1, len = sizeof(dw); - err = RegCreateKeyExA( root, name, 0, NULL, 0, flags | KEY_ALL_ACCESS, NULL, &key, NULL ); + err = RegOpenKeyExA( root, name, 0, flags | KEY_ALL_ACCESS, &key ); if (err == ERROR_FILE_NOT_FOUND) return 0; - ok( err == ERROR_SUCCESS, "%08x: RegCreateKeyEx failed: %u\n", flags, err ); + ok( err == ERROR_SUCCESS, "%08lx: RegOpenKeyEx failed: %lu\n", flags, err ); err = RegQueryValueExA( key, "value", NULL, &type, (BYTE *)&dw, &len ); if (err == ERROR_FILE_NOT_FOUND) dw = 0; else - ok( err == ERROR_SUCCESS, "%08x: RegQueryValueEx failed: %u\n", flags, err ); + ok( err == ERROR_SUCCESS, "%08lx: RegQueryValueEx failed: %lu\n", flags, err ); RegCloseKey( key ); return dw; } @@ -2493,25 +2760,49 @@ static DWORD get_key_value( HKEY root, const char *name, DWORD flags ) static void _check_key_value( int line, HANDLE root, const char *name, DWORD flags, DWORD expect ) { DWORD dw = get_key_value( root, name, flags ); - ok_(__FILE__,line)( dw == expect, "%08x: wrong value %u/%u\n", flags, dw, expect ); + ok_(__FILE__,line)( dw == expect, "%08lx: wrong value %lu/%lu\n", flags, dw, expect ); } #define check_key_value(root,name,flags,expect) _check_key_value( __LINE__, root, name, flags, expect ) +static void _check_enum_value( int line, const char *name, DWORD flags, DWORD subkeys_in, BOOL found_in) +{ + char buffer[1024]; + DWORD err, i, subkeys; + BOOL found; + HKEY key; + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, name, 0, flags, &key ); + ok_( __FILE__, line )( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegQueryInfoKeyA( key, NULL, NULL, NULL, &subkeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + ok_( __FILE__, line )( err == ERROR_SUCCESS, "RegQueryInfoKeyA failed: %lu\n", err ); + ok_( __FILE__, line )( subkeys == subkeys_in, "wrong number of subkeys: %lu\n", subkeys ); + + found = FALSE; + for (i = 0; i < subkeys; i++) + { + err = RegEnumKeyA( key, i, buffer, sizeof(buffer) ); + ok_( __FILE__, line )( err == ERROR_SUCCESS, "RegEnumKeyA failed: %lu\n", err ); + + if (!strcmp(buffer, "Wine")) + found = TRUE; + } + ok_( __FILE__, line )( found == found_in, "found equals %d\n", found ); + RegCloseKey( key ); +} +#define check_enum_value(name, flags, subkeys, found) _check_enum_value( __LINE__, name, flags, subkeys, found ) + static void test_redirection(void) { DWORD err, type, dw, len; - HKEY key, root32, root64, key32, key64, native, op_key; - BOOL is_vista = FALSE; - REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + HKEY key, key32, key64, root, root32, root64; + DWORD subkeys, subkeys32, subkeys64; - if (ptr_size != 64) + if (!has_wow64()) { - BOOL is_wow64; - if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 ) || !is_wow64) - { - skip( "Not on Wow64, no redirection\n" ); - return; - } + skip( "Not on Wow64, no redirection\n" ); + return; } if (limited_user) @@ -2519,243 +2810,177 @@ static void test_redirection(void) skip("not enough privileges to modify HKLM\n"); return; } +#if defined(__REACTOS__) && defined(_WIN64) + if (GetNTVersion() == _WIN32_WINNT_VISTA) { + skip("test_redirection() invalid for Vista x64 and hangs.\n"); + return; + } +#endif err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &root64, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &root32, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); dw = 64; err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); - ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); dw = 32; err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); - ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); dw = 0; len = sizeof(dw); err = RegQueryValueExA( key32, "value", NULL, &type, (BYTE *)&dw, &len ); - ok( err == ERROR_SUCCESS, "RegQueryValueExA failed: %u\n", err ); - ok( dw == 32, "wrong value %u\n", dw ); + ok( err == ERROR_SUCCESS, "RegQueryValueExA failed: %lu\n", err ); + ok( dw == 32, "wrong value %lu\n", dw ); dw = 0; len = sizeof(dw); err = RegQueryValueExA( key64, "value", NULL, &type, (BYTE *)&dw, &len ); - ok( err == ERROR_SUCCESS, "RegQueryValueExA failed: %u\n", err ); - ok( dw == 64, "wrong value %u\n", dw ); + ok( err == ERROR_SUCCESS, "RegQueryValueExA failed: %lu\n", err ); + ok( dw == 64, "wrong value %lu\n", dw ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - - if (ptr_size == 32) - { - /* the Vista mechanism allows opening Wow6432Node from a 32-bit key too */ - /* the new (and simpler) Win7 mechanism doesn't */ - if (get_key_value( key, "Wow6432Node\\Wine\\Winetest", 0 ) == 32) - { - trace( "using Vista-style Wow6432Node handling\n" ); - is_vista = TRUE; - } - check_key_value( key, "Wine\\Winetest", 0, 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, is_vista ? 32 : 0 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 0 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, is_vista ? 32 : 0 ); - } - else - { - if (get_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY ) == 64) - { - trace( "using Vista-style Wow6432Node handling\n" ); - is_vista = TRUE; - } - check_key_value( key, "Wine\\Winetest", 0, 64 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 ); - } + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine\\Winetest", 0, ptr_size ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, ptr_size ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, ptr_size == 32 ? 0 : 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, ptr_size == 32 ? 0 : 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, ptr_size == 32 ? 0 : 32 ); RegCloseKey( key ); - if (ptr_size == 32) - { - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, - KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - dw = get_key_value( key, "Wine\\Winetest", 0 ); - ok( dw == 64 || broken(dw == 32) /* xp64 */, "wrong value %u\n", dw ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 64 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 ); - dw = get_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY ); - ok( dw == 32 || broken(dw == 64) /* xp64 */, "wrong value %u\n", dw ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + dw = get_key_value( key, "Wine\\Winetest", 0 ); + ok( dw == 64 || broken(dw == 32) /* win7 */, "wrong value %lu\n", dw ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 64 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, - KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - check_key_value( key, "Wine\\Winetest", 0, 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, is_vista ? 32 : 0 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 0 ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, is_vista ? 32 : 0 ); - RegCloseKey( key ); - } - else - { - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, - KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - check_key_value( key, "Wine\\Winetest", 0, 64 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 64 ); - dw = get_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY ); - todo_wine ok( dw == 32, "wrong value %u\n", dw ); - check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 ); - RegCloseKey( key ); - - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, - KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - check_key_value( key, "Wine\\Winetest", 0, 32 ); - dw = get_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY ); - ok( dw == 32 || broken(dw == 64) /* vista */, "wrong value %u\n", dw ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); - } + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine\\Winetest", 0, 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 0 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, 0 ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 0 ); + RegCloseKey( key ); check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, ptr_size ); check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", 0, 32 ); - if (ptr_size == 64) - { - /* KEY_WOW64 flags have no effect on 64-bit */ - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_64KEY, 64 ); - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - } - else - { - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_64KEY, 64 ); - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - } + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_64KEY, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, 32 ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); check_key_value( key, "Wine\\Winetest", 0, 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 ); check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); RegCloseKey( key ); - if (ptr_size == 32) - { - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0, - KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - dw = get_key_value( key, "Wine\\Winetest", 0 ); - ok( dw == (is_vista ? 64 : 32) || broken(dw == 32) /* xp64 */, "wrong value %u\n", dw ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine\\Winetest", 0, 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0, - KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - check_key_value( key, "Wine\\Winetest", 0, 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); - } + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine\\Winetest", 0, 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); check_key_value( key, "Winetest", 0, 32 ); - check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); + check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 ); check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); RegCloseKey( key ); - if (ptr_size == 32) - { - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0, - KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - dw = get_key_value( key, "Winetest", 0 ); - ok( dw == 32 || (is_vista && dw == 64), "wrong value %u\n", dw ); - check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Winetest", 0, 32 ); + check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0, - KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - check_key_value( key, "Winetest", 0, 32 ); - check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); - } + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Winetest", 0, 32 ); + check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); check_key_value( key, "Winetest", 0, ptr_size ); - check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : ptr_size ); - dw = get_key_value( key, "Winetest", KEY_WOW64_32KEY ); - todo_wine_if (ptr_size != 32) - ok( dw == 32, "wrong value %u\n", dw ); + check_key_value( key, "Winetest", KEY_WOW64_64KEY, ptr_size ); + check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); RegCloseKey( key ); - if (ptr_size == 32) - { - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, - KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - dw = get_key_value( key, "Winetest", 0 ); - ok( dw == 64 || broken(dw == 32) /* xp64 */, "wrong value %u\n", dw ); - check_key_value( key, "Winetest", KEY_WOW64_64KEY, 64 ); - dw = get_key_value( key, "Winetest", KEY_WOW64_32KEY ); - todo_wine ok( dw == 32, "wrong value %u\n", dw ); - RegCloseKey( key ); + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Winetest", 0, 64 ); + check_key_value( key, "Winetest", KEY_WOW64_64KEY, 64 ); + check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); - err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, - KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); - ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); - check_key_value( key, "Winetest", 0, 32 ); - check_key_value( key, "Winetest", KEY_WOW64_64KEY, is_vista ? 64 : 32 ); - check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); - RegCloseKey( key ); - } + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %lu\n", err ); + check_key_value( key, "Winetest", 0, 32 ); + check_key_value( key, "Winetest", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); if (pRegDeleteKeyExA) { err = pRegDeleteKeyExA( key32, "", KEY_WOW64_32KEY, 0 ); - ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %lu\n", err ); err = pRegDeleteKeyExA( key64, "", KEY_WOW64_64KEY, 0 ); - ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %lu\n", err ); pRegDeleteKeyExA( key64, "", KEY_WOW64_64KEY, 0 ); pRegDeleteKeyExA( root64, "", KEY_WOW64_64KEY, 0 ); } else { err = RegDeleteKeyA( key32, "" ); - ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %lu\n", err ); err = RegDeleteKeyA( key64, "" ); - ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err ); + ok( err == ERROR_SUCCESS, "RegDeleteKey failed: %lu\n", err ); RegDeleteKeyA( key64, "" ); RegDeleteKeyA( root64, "" ); } @@ -2764,38 +2989,431 @@ static void test_redirection(void) RegCloseKey( root32 ); RegCloseKey( root64 ); - /* open key in native bit mode */ - err = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_ALL_ACCESS, &native); - ok(err == ERROR_SUCCESS, "got %i\n", err); - - pRegDeleteKeyExA(native, "AWineTest", 0, 0); - - /* write subkey in opposite bit mode */ - err = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_ALL_ACCESS | opposite, &op_key); - ok(err == ERROR_SUCCESS, "got %i\n", err); - - err = RegCreateKeyExA(op_key, "AWineTest", 0, NULL, 0, KEY_ALL_ACCESS | opposite, - NULL, &key, NULL); - ok(err == ERROR_SUCCESS || err == ERROR_ACCESS_DENIED, "got %i\n", err); - if(err != ERROR_SUCCESS){ - win_skip("Can't write to registry\n"); - RegCloseKey(op_key); - RegCloseKey(native); - return; - } + err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\WOW6432Node\\test1\\test2", 0, NULL, 0, + KEY_WRITE | KEY_WOW64_32KEY, NULL, &key, NULL ); + ok(!err, "got %#lx.\n", err); RegCloseKey(key); - /* verify subkey is not present in native mode */ - err = RegOpenKeyExA(native, "AWineTest", 0, KEY_ALL_ACCESS, &key); - ok(err == ERROR_FILE_NOT_FOUND || - broken(err == ERROR_SUCCESS), /* before Win7, HKCR is reflected instead of redirected */ - "got %i\n", err); + err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\test1\\test2", 0, NULL, 0, KEY_WRITE | KEY_WOW64_32KEY, + NULL, &key, NULL ); + ok(!err, "got %#lx.\n", err); + RegCloseKey(key); - err = pRegDeleteKeyExA(op_key, "AWineTest", opposite, 0); - ok(err == ERROR_SUCCESS, "got %i\n", err); + err = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"Software\\test1\\test2", 0, KEY_WRITE | KEY_WOW64_32KEY, &key ); + ok(!err, "got %#lx.\n", err); + RegCloseKey(key); - RegCloseKey(op_key); - RegCloseKey(native); + if (pRegDeleteTreeA) + { + err = pRegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\\WOW6432Node\\test1"); + ok(!err, "got %#lx.\n", err); + err = pRegDeleteTreeA(HKEY_LOCAL_MACHINE, "Software\\test1"); + ok(err == ERROR_FILE_NOT_FOUND, "got %#lx.\n", err); + } + + /* Software\Classes is shared/reflected so behavior is different */ + + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", + 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL); + if (err == ERROR_ACCESS_DENIED) + { + skip("Not authorized to modify the Classes key\n"); + return; + } + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + dw = 64; + err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", 0, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", KEY_WOW64_32KEY, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", 0, ptr_size == 64 ? 0 : 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_32KEY, 64 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", 0, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", KEY_WOW64_32KEY, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", 0, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", KEY_WOW64_32KEY, 0 ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key64, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegCreateKeyExA( key64, "Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + RegDeleteKeyA( key, "" ); + RegCloseKey( key ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + dw = 64; + err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 64 ); + check_key_value( root32, "Wine", 0, 64 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 64 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + check_key_value( root64, "Wine", 0, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0 ); + check_key_value( root32, "Wine", 0, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( root64, "Wine", 0, 32 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 ); + check_key_value( root32, "Wine", 0, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + + err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_CLASSES_ROOT, "Interface", + 0, KEY_ALL_ACCESS, &root ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + RegDeleteKeyA( root64, "" ); + RegDeleteKeyA( root32, "" ); + RegDeleteKeyA( root, "" ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + RegCloseKey( root ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes", + 0, KEY_ALL_ACCESS, &root ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root64, "Interface", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root32, "Interface", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root, "Interface", + 0, KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + RegCloseKey( root ); + + root64 = key64; + root32 = key32; + root = key; + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key64, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( root, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + RegDeleteKeyA( root, "" ); + RegCloseKey( root ); + + err = RegCreateKeyExA( root64, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key64, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegOpenKeyExA( root32, "Wine", 0, KEY_ALL_ACCESS, &key ); + ok( err == ERROR_FILE_NOT_FOUND, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + dw = 64; + err = RegSetValueExA( key64, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 ); + check_key_value( root32, "Wine", 0, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine", 0, 64 ); + check_key_value( key, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( key, "Wine", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + check_key_value( key, "Wine", 0, 32 ); + check_key_value( key, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( key, "Wine", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", 0, ptr_size ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", KEY_WOW64_32KEY, 32 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + check_key_value( root64, "Wine", 0, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 0 ); + check_key_value( root32, "Wine", 0, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 0 ); + + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", 0, ptr_size == 64 ? 64 : 0 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", KEY_WOW64_64KEY, 64 ); + check_key_value( HKEY_LOCAL_MACHINE, "Software\\Classes\\Interface\\Wine", KEY_WOW64_32KEY, 0 ); + + RegDeleteKeyA( key64, "" ); + RegCloseKey( key64 ); + + err = RegCreateKeyExA( root32, "Wine", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + dw = 32; + err = RegSetValueExA( key32, "value", 0, REG_DWORD, (BYTE *)&dw, sizeof(dw) ); + ok( err == ERROR_SUCCESS, "RegSetValueExA failed: %lu\n", err ); + + check_key_value( root64, "Wine", 0, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_64KEY, 0 ); + check_key_value( root64, "Wine", KEY_WOW64_32KEY, 32 ); + check_key_value( root32, "Wine", 0, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_64KEY, 32 ); + check_key_value( root32, "Wine", KEY_WOW64_32KEY, 32 ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); + + RegCloseKey( root64 ); + RegCloseKey( root32 ); + + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key32, NULL); + ok( err == ERROR_SUCCESS, "RegCreateKeyA failed: %lu\n", err ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, KEY_ALL_ACCESS, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node\\Wine", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 32 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", + 0, KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &key ); + todo_wine_if(ptr_size == 64) ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wine", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &key ); + ok( err == (ptr_size == 64 ? ERROR_FILE_NOT_FOUND : ERROR_SUCCESS), + "RegOpenKeyExA failed: %lu\n", err ); + if (!err) RegCloseKey( key ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\Wow6432Node", + 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, &root32 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegQueryInfoKeyA(root32, NULL, NULL, NULL, &subkeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + ok( err == ERROR_SUCCESS, "RegQueryInfoKeyA failed: %lu\n", err ); + ok( subkeys > 0, "wrong number of subkeys: %lu\n", subkeys ); + subkeys32 = subkeys; + RegCloseKey( root32 ); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes", + 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &root64 ); + ok( err == ERROR_SUCCESS, "RegOpenKeyExA failed: %lu\n", err ); + + err = RegQueryInfoKeyA(root64, NULL, NULL, NULL, &subkeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + ok( err == ERROR_SUCCESS, "RegQueryInfoKeyA failed: %lu\n", err ); + ok( subkeys > subkeys32, "wrong number of subkeys: %lu\n", subkeys ); + subkeys64 = subkeys; + RegCloseKey( root64 ); + + check_enum_value( "Software\\Classes", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( "Software\\Classes", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( "Software\\Classes", + KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( "Software\\Classes\\Wow6432Node", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( "Software\\Classes\\Wow6432Node", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( "Software\\Classes\\Wow6432Node", + KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( "Software\\Wow6432Node\\Classes", + KEY_WOW64_32KEY | KEY_ALL_ACCESS, subkeys64, ptr_size == 32 ); + check_enum_value( "Software\\Wow6432Node\\Classes", + KEY_WOW64_64KEY | KEY_ALL_ACCESS, subkeys32, ptr_size == 64 ); + check_enum_value( "Software\\Wow6432Node\\Classes", + KEY_ALL_ACCESS, ptr_size == 32 ? subkeys64 : subkeys32, TRUE ); + + RegDeleteKeyA( key32, "" ); + RegCloseKey( key32 ); } static void test_classesroot(void) @@ -2826,7 +3444,7 @@ static void test_classesroot(void) KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcr ); todo_wine ok(res == ERROR_SUCCESS || broken(res == ERROR_FILE_NOT_FOUND /* WinNT */), - "test key not found in hkcr: %d\n", res); + "test key not found in hkcr: %ld\n", res); if (res) { skip("HKCR key merging not supported\n"); @@ -2839,38 +3457,38 @@ static void test_classesroot(void) /* set a value in user's classes */ res = RegSetValueExA(hkey, "val1", 0, REG_SZ, (const BYTE *)"user", sizeof("user")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to find the value in hkcr */ res = RegQueryValueExA(hkcr, "val1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); /* modify the value in hkcr */ res = RegSetValueExA(hkcr, "val1", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check if the value is also modified in user's classes */ res = RegQueryValueExA(hkey, "val1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); /* set a value in hkcr */ res = RegSetValueExA(hkcr, "val0", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to find the value in user's classes */ res = RegQueryValueExA(hkey, "val0", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); /* modify the value in user's classes */ res = RegSetValueExA(hkey, "val0", 0, REG_SZ, (const BYTE *)"user", sizeof("user")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check if the value is also modified in hkcr */ res = RegQueryValueExA(hkcr, "val0", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); /* cleanup */ @@ -2898,7 +3516,7 @@ static void test_classesroot(void) res = RegOpenKeyExA( HKEY_CLASSES_ROOT, "WineTestCls", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcr ); ok(res == ERROR_SUCCESS, - "test key not found in hkcr: %d\n", res); + "test key not found in hkcr: %ld\n", res); ok(IS_HKCR(hkcr), "hkcr mask not set in %p\n", hkcr); if (res) { @@ -2909,20 +3527,20 @@ static void test_classesroot(void) /* set a value in hklm classes */ res = RegSetValueExA(hklm, "val2", 0, REG_SZ, (const BYTE *)"hklm", sizeof("hklm")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to find the value in hkcr */ res = RegQueryValueExA(hkcr, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "hklm" ), "value set to '%s'\n", buffer ); /* modify the value in hkcr */ res = RegSetValueExA(hkcr, "val2", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check that the value is modified in hklm classes */ res = RegQueryValueExA(hklm, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); if (RegCreateKeyExA( HKEY_CURRENT_USER, "Software\\Classes\\WineTestCls", 0, NULL, 0, @@ -2933,40 +3551,40 @@ static void test_classesroot(void) res = RegOpenKeyExA( HKEY_CLASSES_ROOT, "WineTestCls", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcr ); ok(res == ERROR_SUCCESS, - "test key not found in hkcr: %d\n", res); + "test key not found in hkcr: %ld\n", res); ok(IS_HKCR(hkcr), "hkcr mask not set in %p\n", hkcr); /* set a value in user's classes */ res = RegSetValueExA(hkey, "val2", 0, REG_SZ, (const BYTE *)"user", sizeof("user")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to find the value in hkcr */ res = RegQueryValueExA(hkcr, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); /* modify the value in hklm */ res = RegSetValueExA(hklm, "val2", 0, REG_SZ, (const BYTE *)"hklm", sizeof("hklm")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check that the value is not overwritten in hkcr or user's classes */ res = RegQueryValueExA(hkcr, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); res = RegQueryValueExA(hkey, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); /* modify the value in hkcr */ res = RegSetValueExA(hkcr, "val2", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check that the value is overwritten in hklm and user's classes */ res = RegQueryValueExA(hkcr, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); res = RegQueryValueExA(hkey, "val2", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); /* create a subkey in hklm */ @@ -2975,25 +3593,25 @@ static void test_classesroot(void) ok(!IS_HKCR(hklmsub1), "hkcr mask set in %p\n", hklmsub1); /* try to open that subkey in hkcr */ res = RegOpenKeyExA( hkcr, "subkey1", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcrsub1 ); - ok(res == ERROR_SUCCESS, "test key not found in hkcr: %d\n", res); + ok(res == ERROR_SUCCESS, "test key not found in hkcr: %ld\n", res); ok(IS_HKCR(hkcrsub1), "hkcr mask not set in %p\n", hkcrsub1); /* set a value in hklm classes */ res = RegSetValueExA(hklmsub1, "subval1", 0, REG_SZ, (const BYTE *)"hklm", sizeof("hklm")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to find the value in hkcr */ res = RegQueryValueExA(hkcrsub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "hklm" ), "value set to '%s'\n", buffer ); /* modify the value in hkcr */ res = RegSetValueExA(hkcrsub1, "subval1", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check that the value is modified in hklm classes */ res = RegQueryValueExA(hklmsub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); /* create a subkey in user's classes */ @@ -3003,35 +3621,35 @@ static void test_classesroot(void) /* set a value in user's classes */ res = RegSetValueExA(hkeysub1, "subval1", 0, REG_SZ, (const BYTE *)"user", sizeof("user")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to find the value in hkcr */ res = RegQueryValueExA(hkcrsub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); /* modify the value in hklm */ res = RegSetValueExA(hklmsub1, "subval1", 0, REG_SZ, (const BYTE *)"hklm", sizeof("hklm")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check that the value is not overwritten in hkcr or user's classes */ res = RegQueryValueExA(hkcrsub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); res = RegQueryValueExA(hkeysub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer ); /* modify the value in hkcr */ res = RegSetValueExA(hkcrsub1, "subval1", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* check that the value is not overwritten in hklm, but in user's classes */ res = RegQueryValueExA(hklmsub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "hklm" ), "value set to '%s'\n", buffer ); res = RegQueryValueExA(hkeysub1, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); /* new subkey in hkcr */ @@ -3039,19 +3657,19 @@ static void test_classesroot(void) KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, &hkcrsub2, NULL )) return; ok(IS_HKCR(hkcrsub2), "hkcr mask not set in %p\n", hkcrsub2); res = RegSetValueExA(hkcrsub2, "subval1", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr")); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError()); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld, GLE=%lx\n", res, GetLastError()); /* try to open that new subkey in user's classes and hklm */ res = RegOpenKeyExA( hkey, "subkey2", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hklmsub2 ); - ok(res != ERROR_SUCCESS, "test key found in user's classes: %d\n", res); + ok(res != ERROR_SUCCESS, "test key found in user's classes: %ld\n", res); hklmsub2 = 0; res = RegOpenKeyExA( hklm, "subkey2", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hklmsub2 ); - ok(res == ERROR_SUCCESS, "test key not found in hklm: %d\n", res); + ok(res == ERROR_SUCCESS, "test key not found in hklm: %ld\n", res); ok(!IS_HKCR(hklmsub2), "hkcr mask set in %p\n", hklmsub2); /* check that the value is present in hklm */ res = RegQueryValueExA(hklmsub2, "subval1", NULL, &type, (LPBYTE)buffer, &size); - ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %ld\n", res); ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer ); /* cleanup */ @@ -3060,23 +3678,23 @@ static void test_classesroot(void) /* delete subkey1 from hkcr (should point at user's classes) */ res = RegDeleteKeyA(hkcr, "subkey1"); - ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %ld\n", res); /* confirm key was removed in hkey but not hklm */ res = RegOpenKeyExA(hkey, "subkey1", 0, KEY_READ, &hkeysub1); - ok(res == ERROR_FILE_NOT_FOUND, "test key found in user's classes: %d\n", res); + ok(res == ERROR_FILE_NOT_FOUND, "test key found in user's classes: %ld\n", res); res = RegOpenKeyExA(hklm, "subkey1", 0, KEY_READ, &hklmsub1); - ok(res == ERROR_SUCCESS, "test key not found in hklm: %d\n", res); + ok(res == ERROR_SUCCESS, "test key not found in hklm: %ld\n", res); ok(!IS_HKCR(hklmsub1), "hkcr mask set in %p\n", hklmsub1); /* delete subkey1 from hkcr again (which should now point at hklm) */ res = RegDeleteKeyA(hkcr, "subkey1"); - ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %ld\n", res); /* confirm hkey was removed in hklm */ RegCloseKey( hklmsub1 ); res = RegOpenKeyExA(hklm, "subkey1", 0, KEY_READ, &hklmsub1); - ok(res == ERROR_FILE_NOT_FOUND, "test key found in hklm: %d\n", res); + ok(res == ERROR_FILE_NOT_FOUND, "test key found in hklm: %ld\n", res); /* final cleanup */ delete_key( hkey ); @@ -3122,7 +3740,7 @@ static void test_classesroot_enum(void) res = RegOpenKeyA( HKEY_CLASSES_ROOT, "WineTestCls", &hkcr ); todo_wine ok(res == ERROR_SUCCESS || broken(res == ERROR_FILE_NOT_FOUND /* WinNT */), - "test key not found in hkcr: %d\n", res); + "test key not found in hkcr: %ld\n", res); if (res) { skip("HKCR key merging not supported\n"); @@ -3132,35 +3750,35 @@ static void test_classesroot_enum(void) } res = RegSetValueExA( hkcu, "X", 0, REG_SZ, (const BYTE *) "AA", 3 ); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", res); res = RegSetValueExA( hkcu, "Y", 0, REG_SZ, (const BYTE *) "B", 2 ); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", res); res = RegCreateKeyA( hkcu, "A", &hkcusub[0] ); - ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %ld\n", res); res = RegCreateKeyA( hkcu, "B", &hkcusub[1] ); - ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %ld\n", res); /* test on values in HKCU */ size = sizeof(buffer); res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "X" ), "expected 'X', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 1, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "Y" ), "expected 'Y', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 2, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res ); + ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", res ); res = RegEnumKeyA( hkcr, 0, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "A" ), "expected 'A', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 1, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "B" ), "expected 'B', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 2, buffer, size ); - ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res ); + ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", res ); /* prepare test env in HKLM */ if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Classes\\WineTestCls", &hklm )) @@ -3184,42 +3802,42 @@ static void test_classesroot_enum(void) } res = RegSetValueExA( hklm, "X", 0, REG_SZ, (const BYTE *) "AB", 3 ); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", res); res = RegSetValueExA( hklm, "Z", 0, REG_SZ, (const BYTE *) "C", 2 ); - ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %ld\n", res); res = RegCreateKeyA( hklm, "A", &hklmsub[0] ); - ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %ld\n", res); res = RegCreateKeyA( hklm, "C", &hklmsub[1] ); - ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %ld\n", res); /* test on values/keys in both HKCU and HKLM */ size = sizeof(buffer); res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "X" ), "expected 'X', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 1, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "Y" ), "expected 'Y', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 2, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "Z" ), "expected 'Z', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 3, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res ); + ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", res ); res = RegEnumKeyA( hkcr, 0, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "A" ), "expected 'A', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 1, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "B" ), "expected 'B', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 2, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "C" ), "expected 'C', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 3, buffer, size ); - ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res ); + ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", res ); /* delete values/keys from HKCU to test only on HKLM */ RegCloseKey( hkcusub[0] ); @@ -3231,40 +3849,40 @@ static void test_classesroot_enum(void) res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL ); ok(res == ERROR_KEY_DELETED || res == ERROR_NO_SYSTEM_RESOURCES, /* Windows XP */ - "expected ERROR_KEY_DELETED, got %d\n", res); + "expected ERROR_KEY_DELETED, got %ld\n", res); size = sizeof(buffer); res = RegEnumKeyA( hkcr, 0, buffer, size ); ok(res == ERROR_KEY_DELETED || res == ERROR_NO_SYSTEM_RESOURCES, /* Windows XP */ - "expected ERROR_KEY_DELETED, got %d\n", res); + "expected ERROR_KEY_DELETED, got %ld\n", res); /* reopen HKCR handle */ RegCloseKey( hkcr ); res = RegOpenKeyA( HKEY_CLASSES_ROOT, "WineTestCls", &hkcr ); - ok(res == ERROR_SUCCESS, "test key not found in hkcr: %d\n", res); + ok(res == ERROR_SUCCESS, "test key not found in hkcr: %ld\n", res); if (res) goto cleanup; /* test on values/keys in HKLM */ size = sizeof(buffer); res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "X" ), "expected 'X', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 1, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %ld\n", res ); ok(!strcmp( buffer, "Z" ), "expected 'Z', got '%s'\n", buffer); size = sizeof(buffer); res = RegEnumValueA( hkcr, 2, buffer, &size, NULL, NULL, NULL, NULL ); - ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res ); + ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", res ); res = RegEnumKeyA( hkcr, 0, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "A" ), "expected 'A', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 1, buffer, size ); - ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res ); + ok(res == ERROR_SUCCESS, "RegEnumKey failed: %ld\n", res ); ok(!strcmp( buffer, "C" ), "expected 'C', got '%s'\n", buffer); res = RegEnumKeyA( hkcr, 2, buffer, size ); - ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res ); + ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %ld\n", res ); cleanup: RegCloseKey( hklmsub[0] ); @@ -3280,64 +3898,32 @@ static void test_classesroot_mask(void) LSTATUS res; res = RegOpenKeyA( HKEY_CLASSES_ROOT, "CLSID", &hkey ); - ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %ld\n", res); todo_wine ok(IS_HKCR(hkey) || broken(!IS_HKCR(hkey)) /* WinNT */, "hkcr mask not set in %p\n", hkey); RegCloseKey( hkey ); res = RegOpenKeyA( HKEY_CURRENT_USER, "Software", &hkey ); - ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %ld\n", res); ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey); RegCloseKey( hkey ); res = RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software", &hkey ); - ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %ld\n", res); ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey); RegCloseKey( hkey ); res = RegOpenKeyA( HKEY_USERS, ".Default", &hkey ); - ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %ld\n", res); ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey); RegCloseKey( hkey ); res = RegOpenKeyA( HKEY_CURRENT_CONFIG, "Software", &hkey ); - ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res); + ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %ld\n", res); ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey); RegCloseKey( hkey ); } -static void test_perflib_key(void) -{ - DWORD size; - LONG ret; - HKEY key; - - ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009", &key); - ok(ret == ERROR_SUCCESS, "RegOpenKeyA failed with error %u\n", ret); - - ret = RegQueryValueExA(key, "Counter", NULL, NULL, NULL, &size); - if (ret != ERROR_SUCCESS) - { - skip("Perflib\\009\\Counter does not exist, skipping perflib test\n"); - goto done; - } - ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed with error %u\n", ret); - - /* Windows only compares the first few characters of the value name. - * On Windows XP / 2003, it is sufficient to use "Cou", newer versions - * require a longer substring. */ - - ret = RegQueryValueExA(key, "Counters", NULL, NULL, NULL, &size); - ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed with error %u\n", ret); - ret = RegQueryValueExA(key, "Counter2", NULL, NULL, NULL, &size); - todo_wine ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed with error %u\n", ret); - ret = RegQueryValueExA(key, "CounterWine", NULL, NULL, NULL, &size); - todo_wine ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed with error %u\n", ret); - -done: - RegCloseKey(key); -} - static void test_deleted_key(void) { HKEY hkey, hkey2; @@ -3353,31 +3939,31 @@ static void test_deleted_key(void) 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); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\n", res); res = RegEnumKeyA( hkey, 0, value, sizeof(value) ); - ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\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); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\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); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\n", res); res = RegOpenKeyA( hkey, "test", &hkey2 ); - ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\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); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\n", res); if (res == 0) RegCloseKey( hkey2 ); res = RegFlushKey( hkey ); - ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %i\n", res); + ok(res == ERROR_KEY_DELETED, "expect ERROR_KEY_DELETED, got %li\n", res); RegCloseKey( hkey ); @@ -3390,38 +3976,37 @@ static void test_delete_value(void) 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); + ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %li\n", res); res = RegQueryValueExA( hkey_main, "test", NULL, NULL, NULL, NULL); - ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %i\n", res); + ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %li\n", res); res = RegDeleteValueA( hkey_main, "test" ); - ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %i\n", res); + ok(res == ERROR_SUCCESS, "expect ERROR_SUCCESS, got %li\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); + ok(res == ERROR_FILE_NOT_FOUND, "expect ERROR_FILE_NOT_FOUND, got %li\n", res); res = RegDeleteValueA( hkey_main, "test" ); - ok(res == ERROR_FILE_NOT_FOUND, "expect ERROR_FILE_NOT_FOUND, got %i\n", res); + ok(res == ERROR_FILE_NOT_FOUND, "expect ERROR_FILE_NOT_FOUND, got %li\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); + ok(res == ERROR_FILE_NOT_FOUND, "expect ERROR_FILE_NOT_FOUND, got %li\n", res); /* Default registry value */ res = RegSetValueExA(hkey_main, "", 0, REG_SZ, (const BYTE *)"value", 6); - ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res); res = RegQueryValueExA(hkey_main, "", NULL, NULL, NULL, NULL); - ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res); res = RegDeleteValueA(hkey_main, "" ); - ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res); + ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res); res = RegQueryValueExA(hkey_main, "", NULL, NULL, NULL, NULL); - ok(res == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", res); + ok(res == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", res); } static void test_delete_key_value(void) @@ -3436,52 +4021,52 @@ static void test_delete_key_value(void) } ret = pRegDeleteKeyValueA(NULL, NULL, NULL); - ok(ret == ERROR_INVALID_HANDLE, "got %d\n", ret); + ok(ret == ERROR_INVALID_HANDLE, "got %ld\n", ret); ret = pRegDeleteKeyValueA(hkey_main, NULL, NULL); - ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "got %ld\n", ret); ret = RegSetValueExA(hkey_main, "test", 0, REG_SZ, (const BYTE*)"value", 6); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = RegQueryValueExA(hkey_main, "test", NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); /* NULL subkey name means delete from open key */ ret = pRegDeleteKeyValueA(hkey_main, NULL, "test"); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = RegQueryValueExA(hkey_main, "test", NULL, NULL, NULL, NULL); - ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "got %ld\n", ret); /* now with real subkey */ ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_WRITE|KEY_READ, NULL, &subkey, NULL); - ok(!ret, "failed with error %d\n", ret); + ok(!ret, "failed with error %ld\n", ret); ret = RegSetValueExA(subkey, "test", 0, REG_SZ, (const BYTE*)"value", 6); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = RegQueryValueExA(subkey, "test", NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = pRegDeleteKeyValueA(hkey_main, "Subkey1", "test"); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = RegQueryValueExA(subkey, "test", NULL, NULL, NULL, NULL); - ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "got %ld\n", ret); /* Default registry value */ ret = RegSetValueExA(subkey, "", 0, REG_SZ, (const BYTE *)"value", 6); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ret = RegQueryValueExA(subkey, "", NULL, NULL, NULL, NULL); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ret = pRegDeleteKeyValueA(hkey_main, "Subkey1", "" ); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); ret = RegQueryValueExA(subkey, "", NULL, NULL, NULL, NULL); - ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", ret); + ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret); RegDeleteKeyA(subkey, ""); RegCloseKey(subkey); @@ -3494,267 +4079,1151 @@ static void test_RegOpenCurrentUser(void) key = HKEY_CURRENT_USER; ret = RegOpenCurrentUser(KEY_READ, &key); - ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(!ret, "got %ld, error %ld\n", ret, GetLastError()); ok(key != HKEY_CURRENT_USER, "got %p\n", key); RegCloseKey(key); } +struct notify_data { + HKEY key; + DWORD flags; + HANDLE event; +}; + +static DWORD WINAPI notify_change_thread(void *arg) +{ + struct notify_data *data = arg; + LONG ret; + + ret = RegNotifyChangeKeyValue(data->key, TRUE, + REG_NOTIFY_CHANGE_NAME|data->flags, data->event, TRUE); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + return 0; +} + static void test_RegNotifyChangeKeyValue(void) { - HKEY key, subkey; + struct notify_data data; + HKEY key, subkey, subsubkey; + HANDLE thread; HANDLE event; DWORD dwret; LONG ret; event = CreateEventW(NULL, FALSE, TRUE, NULL); - ok(event != NULL, "CreateEvent failed, error %u\n", GetLastError()); + ok(event != NULL, "CreateEvent failed, error %lu\n", GetLastError()); ret = RegCreateKeyA(hkey_main, "TestKey", &key); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); - ret = RegNotifyChangeKeyValue(key, TRUE, REG_NOTIFY_CHANGE_NAME, event, TRUE); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ret = RegNotifyChangeKeyValue(key, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, event, TRUE); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); dwret = WaitForSingleObject(event, 0); - ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", dwret); + ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %lu\n", dwret); ret = RegCreateKeyA(key, "SubKey", &subkey); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); dwret = WaitForSingleObject(event, 0); - ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", dwret); + ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", dwret); + /* watching deeper keys */ + ret = RegNotifyChangeKeyValue(key, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, event, TRUE); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %lu\n", dwret); + + ret = RegCreateKeyA(subkey, "SubKey", &subsubkey); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", dwret); + + /* watching deeper values */ + ret = RegNotifyChangeKeyValue(key, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, event, TRUE); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %lu\n", dwret); + + ret = RegSetValueA(subsubkey, NULL, REG_SZ, "SubSubKeyValue", 0); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", dwret); + + /* don't watch deeper values */ + RegCloseKey(key); + ret = RegOpenKeyA(hkey_main, "TestKey", &key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + ret = RegNotifyChangeKeyValue(key, FALSE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, event, TRUE); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %lu\n", dwret); + + ret = RegSetValueA(subsubkey, NULL, REG_SZ, "SubSubKeyValueNEW", 0); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %lu\n", dwret); + + RegDeleteKeyA(subkey, "SubKey"); + RegDeleteKeyA(key, "SubKey"); + RegCloseKey(subsubkey); + RegCloseKey(subkey); + RegCloseKey(key); + + /* test same thread with REG_NOTIFY_THREAD_AGNOSTIC */ + ret = RegOpenKeyA(hkey_main, "TestKey", &key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + ret = RegNotifyChangeKeyValue(key, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_THREAD_AGNOSTIC, + event, TRUE); + if (ret == ERROR_INVALID_PARAMETER) + { + win_skip("REG_NOTIFY_THREAD_AGNOSTIC is not supported\n"); + RegCloseKey(key); + CloseHandle(event); + return; + } + + ret = RegCreateKeyA(key, "SubKey", &subkey); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", dwret); + + RegDeleteKeyA(key, "SubKey"); + RegCloseKey(subkey); + RegCloseKey(key); + + /* test different thread without REG_NOTIFY_THREAD_AGNOSTIC */ + ret = RegOpenKeyA(hkey_main, "TestKey", &key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + data.key = key; + data.flags = 0; + data.event = event; + thread = CreateThread(NULL, 0, notify_change_thread, &data, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + /* the thread exiting causes event to signal on Windows + this is worked around on Windows using REG_NOTIFY_THREAD_AGNOSTIC + Wine already behaves as if the flag is set */ + dwret = WaitForSingleObject(event, 0); + todo_wine + ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", dwret); + RegCloseKey(key); + + /* test different thread with REG_NOTIFY_THREAD_AGNOSTIC */ + ret = RegOpenKeyA(hkey_main, "TestKey", &key); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + data.key = key; + data.flags = REG_NOTIFY_THREAD_AGNOSTIC; + thread = CreateThread(NULL, 0, notify_change_thread, &data, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %lu\n", dwret); + + ret = RegCreateKeyA(key, "SubKey", &subkey); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + + dwret = WaitForSingleObject(event, 0); + ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", dwret); + + RegDeleteKeyA(key, "SubKey"); RegDeleteKeyA(key, ""); + RegCloseKey(subkey); RegCloseKey(key); CloseHandle(event); } -static const char *dbgstr_longlong(ULONGLONG ll) +static const char *find_counter_value(const char *text, const char *index) { - static char buf[16][64]; - static int idx; + const char *p = text; - idx &= 0x0f; + while (*p) + { + if (!strcmp(p, index)) + return p + strlen(p) + 1; - if (sizeof(ll) > sizeof(unsigned long) && ll >> 32) - sprintf(buf[idx], "0x%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll); - else - sprintf(buf[idx], "0x%08lx", (unsigned long)ll); + p += strlen(p) + 1; + p += strlen(p) + 1; + } - return buf[idx++]; + return NULL; } -#define cmp_li(a, b, c) cmp_li_real(a, b, c, __LINE__) -static void cmp_li_real(LARGE_INTEGER *l1, LARGE_INTEGER *l2, LONGLONG slack, int line) +static void test_counter_values(const char *text, HKEY key) { - LONGLONG diff = l2->QuadPart - l1->QuadPart; - if (diff < 0) diff = -diff; - ok_(__FILE__, line)(diff <= slack, "values don't match: %s/%s\n", - dbgstr_longlong(l1->QuadPart), dbgstr_longlong(l2->QuadPart)); + const char *p = text; + const char *name; + + ok(!strcmp(p, "1"), "got first index %s\n", debugstr_a(p)); + p += strlen(p) + 1; + ok(!strcmp(p, "1847"), "got first name %s\n", debugstr_a(p)); + p += strlen(p) + 1; + + while (*p) + { + unsigned int index = atoi(p); + + ok(index > 0, "expected nonzero index\n"); + + p += strlen(p) + 1; + ok(*p, "name missing for %u\n", index); + p += strlen(p) + 1; + } + + name = find_counter_value(text, "1846"); + ok(name != NULL, "did not find name\n"); + if (key != HKEY_PERFORMANCE_NLSTEXT) + ok(!strcmp(name, "End Marker"), "got name %s\n", debugstr_a(name)); } -static void test_RegQueryValueExPerformanceData(void) +static void test_help_values(const char *text, HKEY key) { - static const WCHAR globalW[] = { 'G','l','o','b','a','l',0 }; - static const WCHAR dummyW[5] = { 'd','u','m','m','y' }; - static const char * const names[] = { NULL, "", "Global", "2" "invalid counter name" }; - DWORD cbData, len, i, type; - BYTE *value; - DWORD dwret; - LONG limit = 6; - PERF_DATA_BLOCK *pdb; - HKEY hkey; - BYTE buf[256 + sizeof(PERF_DATA_BLOCK)]; + const char *p = text; + const char *name; - /* Test with data == NULL */ - dwret = RegQueryValueExA( HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, NULL, &cbData ); - ok( dwret == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", dwret ); - - dwret = RegQueryValueExW( HKEY_PERFORMANCE_DATA, globalW, NULL, NULL, NULL, &cbData ); - ok( dwret == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", dwret ); - - /* Test ERROR_MORE_DATA, start with small buffer */ - len = 10; - value = HeapAlloc(GetProcessHeap(), 0, len); - cbData = len; - type = 0xdeadbeef; - dwret = RegQueryValueExA( HKEY_PERFORMANCE_DATA, "Global", NULL, &type, value, &cbData ); - ok( dwret == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %d\n", dwret ); - ok(type == REG_BINARY, "got %u\n", type); - while( dwret == ERROR_MORE_DATA && limit) + while (*p) { - len = len * 10; - value = HeapReAlloc( GetProcessHeap(), 0, value, len ); - cbData = len; - type = 0xdeadbeef; - dwret = RegQueryValueExA( HKEY_PERFORMANCE_DATA, "Global", NULL, &type, value, &cbData ); - limit--; - } - ok(limit > 0, "too many times ERROR_MORE_DATA returned\n"); + unsigned int index = atoi(p); - ok(dwret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", dwret); - ok(type == REG_BINARY, "got %u\n", type); + ok(index > 0, "expected nonzero index\n"); - /* Check returned data */ - if (dwret == ERROR_SUCCESS) - { - ok(len >= sizeof(PERF_DATA_BLOCK), "got size %d\n", len); - if (len >= sizeof(PERF_DATA_BLOCK)) { - pdb = (PERF_DATA_BLOCK*) value; - ok(pdb->Signature[0] == 'P', "expected Signature[0] = 'P', got 0x%x\n", pdb->Signature[0]); - ok(pdb->Signature[1] == 'E', "expected Signature[1] = 'E', got 0x%x\n", pdb->Signature[1]); - ok(pdb->Signature[2] == 'R', "expected Signature[2] = 'R', got 0x%x\n", pdb->Signature[2]); - ok(pdb->Signature[3] == 'F', "expected Signature[3] = 'F', got 0x%x\n", pdb->Signature[3]); - /* TODO: check other field */ - } + p += strlen(p) + 1; + p += strlen(p) + 1; } - HeapFree(GetProcessHeap(), 0, value); + name = find_counter_value(text, "1847"); + ok(name != NULL, "did not find name\n"); + if (key != HKEY_PERFORMANCE_NLSTEXT) + ok(!strcmp(name, "End Marker"), "got name %s\n", debugstr_a(name)); +} - for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) +static void test_performance_keys(void) +{ + static const HKEY keys[] = {HKEY_PERFORMANCE_DATA, HKEY_PERFORMANCE_TEXT, HKEY_PERFORMANCE_NLSTEXT}; + static const char *const names[] = {NULL, "", "Global", "2", "invalid counter name", "System"}; + DWORD size, type, sysname_len, expect_size, key_count, value_count; + LARGE_INTEGER perftime1, perftime2, systime1, systime2, freq; + WCHAR sysname[MAX_COMPUTERNAME_LENGTH + 1]; + unsigned int buffer_size = 1024 * 1024; + void *buffer, *bufferW; + PERF_DATA_BLOCK *data; + union { - cbData = 0xdeadbeef; - dwret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, names[i], NULL, NULL, NULL, &cbData); - ok(dwret == ERROR_MORE_DATA, "%u/%s: got %u\n", i, names[i], dwret); - ok(cbData == 0, "got %u\n", cbData); + FILETIME f; + LONGLONG l; + } file_time; + unsigned int i, j; + HKEY key; + LONG ret; - cbData = 0; - dwret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, names[i], NULL, NULL, NULL, &cbData); - ok(dwret == ERROR_MORE_DATA, "%u/%s: got %u\n", i, names[i], dwret); - ok(cbData == 0, "got %u\n", cbData); - - cbData = 0xdeadbeef; - dwret = RegQueryValueExA(HKEY_PERFORMANCE_TEXT, names[i], NULL, NULL, NULL, &cbData); -todo_wine - ok(dwret == ERROR_MORE_DATA, "%u/%s: got %u\n", i, names[i], dwret); - ok(cbData == 0, "got %u\n", cbData); - - cbData = 0; - dwret = RegQueryValueExA(HKEY_PERFORMANCE_TEXT, names[i], NULL, NULL, NULL, &cbData); -todo_wine - ok(dwret == ERROR_MORE_DATA, "%u/%s: got %u\n", i, names[i], dwret); - ok(cbData == 0, "got %u\n", cbData); - - cbData = 0xdeadbeef; - dwret = RegQueryValueExA(HKEY_PERFORMANCE_NLSTEXT, names[i], NULL, NULL, NULL, &cbData); -todo_wine - ok(dwret == ERROR_MORE_DATA, "%u/%s: got %u\n", i, names[i], dwret); - ok(cbData == 0, "got %u\n", cbData); - - cbData = 0; - dwret = RegQueryValueExA(HKEY_PERFORMANCE_NLSTEXT, names[i], NULL, NULL, NULL, &cbData); -todo_wine - ok(dwret == ERROR_MORE_DATA, "%u/%s: got %u\n", i, names[i], dwret); - ok(cbData == 0, "got %u\n", cbData); +#ifdef __REACTOS__ +#ifdef _WIN64 + if (GetNTVersion() <= _WIN32_WINNT_VISTA) { +#else + if (GetNTVersion() <= _WIN32_WINNT_WS03) { +#endif + skip("test_performance_keys() is invalid for Vista x64 and WS03\n"); + return; } +#endif + buffer = malloc(buffer_size); - memset(buf, 0x77, sizeof(buf)); - type = 0xdeadbeef; - cbData = sizeof(buf); - dwret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "invalid counter name", NULL, &type, buf, &cbData); - ok(dwret == ERROR_SUCCESS, "got %u\n", dwret); - ok(type == REG_BINARY, "got %u\n", type); - if (dwret == ERROR_SUCCESS) + sysname_len = ARRAY_SIZE(sysname); + GetComputerNameW(sysname, &sysname_len); + + for (i = 0; i < ARRAY_SIZE(keys); ++i) { - SYSTEMTIME st; - WCHAR sysname[MAX_COMPUTERNAME_LENGTH + 1]; - DWORD sysname_len; - LARGE_INTEGER counter, freq, ftime; + winetest_push_context("key %p", keys[i]); - GetSystemTime(&st); - GetSystemTimeAsFileTime((FILETIME *)&ftime); - QueryPerformanceCounter(&counter); - QueryPerformanceFrequency(&freq); - - sysname_len = MAX_COMPUTERNAME_LENGTH + 1; - GetComputerNameW(sysname, &sysname_len); - - pdb = (PERF_DATA_BLOCK *)buf; - ok(pdb->Signature[0] == 'P', "got '%c'\n", pdb->Signature[0]); - ok(pdb->Signature[1] == 'E', "got '%c'\n", pdb->Signature[1]); - ok(pdb->Signature[2] == 'R', "got '%c'\n", pdb->Signature[2]); - ok(pdb->Signature[3] == 'F', "got '%c'\n", pdb->Signature[3]); - - ok(pdb->LittleEndian == 1, "got %u\n", pdb->LittleEndian); - ok(pdb->Version == 1, "got %u\n", pdb->Version); - ok(pdb->Revision == 1, "got %u\n", pdb->Revision); - len = (sizeof(*pdb) + pdb->SystemNameLength + 7) & ~7; - ok(pdb->TotalByteLength == len, "got %u vs %u\n", pdb->TotalByteLength, len); - ok(pdb->HeaderLength == pdb->TotalByteLength, "got %u\n", pdb->HeaderLength); - ok(pdb->NumObjectTypes == 0, "got %u\n", pdb->NumObjectTypes); -todo_wine - ok(pdb->DefaultObject != 0, "got %u\n", pdb->DefaultObject); - ok(pdb->SystemTime.wYear == st.wYear, "got %u\n", pdb->SystemTime.wYear); - ok(pdb->SystemTime.wMonth == st.wMonth, "got %u\n", pdb->SystemTime.wMonth); - ok(pdb->SystemTime.wDayOfWeek == st.wDayOfWeek, "got %u\n", pdb->SystemTime.wDayOfWeek); - ok(pdb->SystemTime.wDay == st.wDay, "got %u\n", pdb->SystemTime.wDay); - if (U(pdb->PerfTime).LowPart != 0x77777777) /* TestBot is broken */ - cmp_li(&pdb->PerfTime, &counter, freq.QuadPart); - if (U(pdb->PerfFreq).LowPart != 0x77777777) /* TestBot is broken */ - cmp_li(&pdb->PerfFreq, &freq, 0); - cmp_li(&pdb->PerfTime100nSec, &ftime, 200000); /* TestBot needs huge slack value */ - ok(pdb->SystemNameLength == (sysname_len + 1) * sizeof(WCHAR), "expected %u, got %u\n", - (sysname_len + 1) * sizeof(WCHAR), pdb->SystemNameLength); - ok(pdb->SystemNameOffset == sizeof(*pdb), "got %u\n", pdb->SystemNameOffset); - ok(!lstrcmpW(sysname, (LPCWSTR)(pdb + 1)), "%s != %s\n", - wine_dbgstr_w(sysname), wine_dbgstr_w((LPCWSTR)(pdb + 1))); - - len = pdb->TotalByteLength - (sizeof(*pdb) + pdb->SystemNameLength); - if (len) + for (j = 0; j < ARRAY_SIZE(names); ++j) { - BYTE remainder[8], *p; + winetest_push_context("value %s", debugstr_a(names[j])); - memset(remainder, 0x77, sizeof(remainder)); - p = buf + sizeof(*pdb) + pdb->SystemNameLength; - ok(!memcmp(p, remainder, len), "remainder: %02x,%02x...\n", p[0], p[1]); + QueryPerformanceFrequency(&freq); + + size = 0; + ret = RegQueryValueExA(keys[i], names[j], NULL, NULL, NULL, &size); + ok(ret == ERROR_MORE_DATA, "got %lu\n", ret); + ok(!size, "got size %lu\n", size); + + size = 10; + ret = RegQueryValueExA(keys[i], names[j], NULL, NULL, buffer, &size); + ok(ret == ERROR_MORE_DATA, "got %lu\n", ret); + todo_wine + ok(size == 10, "got size %lu\n", size); + + size = buffer_size; + ret = RegQueryValueExA(keys[i], names[j], NULL, NULL, NULL, &size); + ok(ret == ERROR_MORE_DATA, "got %lu\n", ret); + + QueryPerformanceCounter(&perftime1); + NtQuerySystemTime(&systime1); + + size = buffer_size; + type = 0xdeadbeef; + ret = RegQueryValueExA(keys[i], names[j], NULL, &type, buffer, &size); + ok(!ret, "got %lu\n", ret); + ok(type == REG_BINARY, "got type %lu\n", type); + ok(size >= sizeof(PERF_DATA_BLOCK) && size < buffer_size, "got size %lu\n", size); + + QueryPerformanceCounter(&perftime2); + NtQuerySystemTime(&systime2); + + data = buffer; + ok(!wcsncmp(data->Signature, L"PERF", 4), "got signature %s\n", + debugstr_wn(data->Signature, 4)); + ok(data->LittleEndian == 1, "got endianness %lu\n", data->LittleEndian); + ok(data->Version == 1, "got version %lu\n", data->Version); + ok(data->Revision == 1, "got version %lu\n", data->Revision); + ok(data->TotalByteLength == size, "expected size %lu, got %lu\n", + size, data->TotalByteLength); + + expect_size = sizeof(PERF_DATA_BLOCK) + data->SystemNameLength; + expect_size = (expect_size + 7) & ~7; + + ok(data->HeaderLength == expect_size, "expected header size %lu, got %lu\n", + expect_size, data->HeaderLength); + /* todo: test objects... */ + todo_wine ok(data->DefaultObject == 238, "got default object %lu\n", data->DefaultObject); + + ok(data->PerfTime.QuadPart >= perftime1.QuadPart + && data->PerfTime.QuadPart <= perftime2.QuadPart, + "got times %I64d, %I64d, %I64d\n", + perftime1.QuadPart, data->PerfTime.QuadPart, perftime2.QuadPart); + ok(data->PerfFreq.QuadPart == freq.QuadPart, "expected frequency %I64d, got %I64d\n", + freq.QuadPart, data->PerfFreq.QuadPart); + ok(data->PerfTime100nSec.QuadPart >= systime1.QuadPart + && data->PerfTime100nSec.QuadPart <= systime2.QuadPart, + "got times %I64d, %I64d, %I64d\n", + systime1.QuadPart, data->PerfTime100nSec.QuadPart, systime2.QuadPart); + SystemTimeToFileTime(&data->SystemTime, &file_time.f); + /* SYSTEMTIME has a granularity of 1 ms */ + ok(file_time.l >= systime1.QuadPart - 10000 && file_time.l <= systime2.QuadPart, + "got times %I64d, %I64d, %I64d\n", systime1.QuadPart, file_time.l, systime2.QuadPart); + + ok(data->SystemNameLength == (sysname_len + 1) * sizeof(WCHAR), "got %lu\n", data->SystemNameLength); + ok(data->SystemNameOffset == sizeof(PERF_DATA_BLOCK), + "got name offset %lu\n", data->SystemNameOffset); + ok(!wcscmp(sysname, (const WCHAR *)(data + 1)), "expected name %s, got %s\n", + debugstr_w(sysname), debugstr_w((const WCHAR *)(data + 1))); + + winetest_pop_context(); } + + /* test the "Counter" value */ + + size = 0xdeadbeef; + ret = RegQueryValueExA(keys[i], "cOuNtEr", NULL, NULL, NULL, &size); + ok(!ret, "got %lu\n", ret); + ok(size > 0 && size < 0xdeadbeef, "got size %lu\n", size); + + type = 0xdeadbeef; + size = 0; + ret = RegQueryValueExA(keys[i], "cOuNtEr", NULL, &type, buffer, &size); + ok(ret == ERROR_MORE_DATA, "got %lu\n", ret); + ok(size > 0, "got size %lu\n", size); + + type = 0xdeadbeef; + size = buffer_size; + ret = RegQueryValueExA(keys[i], "cOuNtEr", NULL, &type, buffer, &size); + ok(!ret, "got %lu\n", ret); + ok(type == REG_MULTI_SZ, "got type %lu\n", type); + test_counter_values(buffer, keys[i]); + + type = 0xdeadbeef; + size = buffer_size; + ret = RegQueryValueExA(keys[i], "cOuNtErwine", NULL, &type, buffer, &size); + ok(!ret, "got %lu\n", ret); + ok(type == REG_MULTI_SZ, "got type %lu\n", type); + test_counter_values(buffer, keys[i]); + + size = 0; + ret = RegQueryValueExW(keys[i], L"cOuNtEr", NULL, NULL, NULL, &size); + ok(!ret, "got %lu\n", ret); + ok(size > 0, "got size %lu\n", size); + + bufferW = malloc(size); + + type = 0xdeadbeef; + ret = RegQueryValueExW(keys[i], L"cOuNtEr", NULL, &type, bufferW, &size); + ok(!ret, "got %lu\n", ret); + ok(type == REG_MULTI_SZ, "got type %lu\n", type); + WideCharToMultiByte(CP_ACP, 0, bufferW, size / sizeof(WCHAR), buffer, buffer_size, NULL, NULL); + test_counter_values(buffer, keys[i]); + + /* test the "Help" value */ + + size = 0xdeadbeef; + ret = RegQueryValueExA(keys[i], "hElP", NULL, NULL, NULL, &size); + ok(!ret, "got %lu\n", ret); + ok(size > 0 && size < 0xdeadbeef, "got size %lu\n", size); + + type = 0xdeadbeef; + size = 0; + ret = RegQueryValueExA(keys[i], "hElP", NULL, &type, buffer, &size); + ok(ret == ERROR_MORE_DATA, "got %lu\n", ret); + ok(size > 0, "got size %lu\n", size); + + type = 0xdeadbeef; + size = buffer_size; + ret = RegQueryValueExA(keys[i], "hElP", NULL, &type, buffer, &size); + test_help_values(buffer, keys[i]); + + type = 0xdeadbeef; + size = buffer_size; + ret = RegQueryValueExA(keys[i], "hElPwine", NULL, &type, buffer, &size); + ok(!ret, "got %lu\n", ret); + ok(type == REG_MULTI_SZ, "got type %lu\n", type); + test_help_values(buffer, keys[i]); + + size = 0; + ret = RegQueryValueExW(keys[i], L"hElP", NULL, NULL, NULL, &size); + ok(!ret, "got %lu\n", ret); + ok(size > 0, "got size %lu\n", size); + + bufferW = malloc(size); + + type = 0xdeadbeef; + ret = RegQueryValueExW(keys[i], L"hElP", NULL, &type, bufferW, &size); + ok(!ret, "got %lu\n", ret); + ok(type == REG_MULTI_SZ, "got type %lu\n", type); + WideCharToMultiByte(CP_ACP, 0, bufferW, size / sizeof(WCHAR), buffer, buffer_size, NULL, NULL); + test_help_values(buffer, keys[i]); + + /* test other registry APIs */ + + ret = RegOpenKeyA(keys[i], NULL, &key); + todo_wine ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + ret = RegOpenKeyA(keys[i], "Global", &key); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + ret = RegOpenKeyExA(keys[i], "Global", 0, KEY_READ, &key); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + size = 0; + ret = RegQueryValueA(keys[i], "Global", NULL, (LONG *)&size); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + ret = RegSetValueA(keys[i], "Global", REG_SZ, "dummy", 5); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + key_count = 0x900ddeed; + ret = RegQueryInfoKeyA(keys[i], NULL, NULL, NULL, &key_count, NULL, + NULL, &value_count, NULL, NULL, NULL, NULL); + todo_wine ok(!ret, "got %lu\n", ret); + todo_wine ok(!key_count, "got %lu subkeys\n", key_count); + todo_wine ok(value_count == 2, "got %lu values\n", value_count); + + size = buffer_size; + ret = RegEnumValueA(keys[i], 0, buffer, &size, NULL, NULL, NULL, NULL); + todo_wine ok(ret == ERROR_MORE_DATA, "got %lu\n", ret); + ok(size == buffer_size, "got size %lu\n", size); + + ret = RegCloseKey(keys[i]); + ok(!ret, "got %lu\n", ret); + + ret = RegCloseKey(keys[i]); + ok(!ret, "got %lu\n", ret); + + winetest_pop_context(); } - dwret = RegOpenKeyA(HKEY_PERFORMANCE_DATA, NULL, &hkey); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); + ret = RegSetValueExA(HKEY_PERFORMANCE_DATA, "Global", 0, REG_SZ, (const BYTE *)"dummy", 5); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); - dwret = RegOpenKeyA(HKEY_PERFORMANCE_DATA, "Global", &hkey); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); + ret = RegSetValueExA(HKEY_PERFORMANCE_TEXT, "Global", 0, REG_SZ, (const BYTE *)"dummy", 5); + todo_wine ok(ret == ERROR_BADKEY, "got %lu\n", ret); - dwret = RegOpenKeyExA(HKEY_PERFORMANCE_DATA, "Global", 0, KEY_READ, &hkey); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); - - dwret = RegQueryValueA(HKEY_PERFORMANCE_DATA, "Global", NULL, (LONG *)&cbData); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); - - dwret = RegSetValueA(HKEY_PERFORMANCE_DATA, "Global", REG_SZ, "dummy", 4); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); - - dwret = RegSetValueExA(HKEY_PERFORMANCE_DATA, "Global", 0, REG_SZ, (const BYTE *)"dummy", 40); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); - - cbData = sizeof(buf); - dwret = RegEnumKeyA(HKEY_PERFORMANCE_DATA, 0, (LPSTR)buf, cbData); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); - - cbData = sizeof(buf); - dwret = RegEnumValueA(HKEY_PERFORMANCE_DATA, 0, (LPSTR)buf, &cbData, NULL, NULL, NULL, NULL); -todo_wine - ok(dwret == ERROR_MORE_DATA, "got %u\n", dwret); -todo_wine - ok(cbData == sizeof(buf), "got %u\n", cbData); - - dwret = RegEnumValueA(HKEY_PERFORMANCE_DATA, 0, NULL, &cbData, NULL, NULL, NULL, NULL); - ok(dwret == ERROR_INVALID_PARAMETER, "got %u\n", dwret); + ret = RegSetValueExA(HKEY_PERFORMANCE_NLSTEXT, "Global", 0, REG_SZ, (const BYTE *)"dummy", 5); + todo_wine ok(ret == ERROR_BADKEY, "got %lu\n", ret); if (pRegSetKeyValueW) { - dwret = pRegSetKeyValueW(HKEY_PERFORMANCE_DATA, NULL, globalW, REG_SZ, dummyW, sizeof(dummyW)); -todo_wine - ok(dwret == ERROR_INVALID_HANDLE, "got %u\n", dwret); + ret = pRegSetKeyValueW(HKEY_PERFORMANCE_DATA, NULL, L"Global", REG_SZ, L"dummy", 10); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + ret = pRegSetKeyValueW(HKEY_PERFORMANCE_TEXT, NULL, L"Global", REG_SZ, L"dummy", 10); + todo_wine ok(ret == ERROR_BADKEY, "got %lu\n", ret); + + ret = pRegSetKeyValueW(HKEY_PERFORMANCE_NLSTEXT, NULL, L"Global", REG_SZ, L"dummy", 10); + todo_wine ok(ret == ERROR_BADKEY, "got %lu\n", ret); } - dwret = RegCloseKey(HKEY_PERFORMANCE_DATA); - ok(dwret == ERROR_SUCCESS, "got %u\n", dwret); + ret = RegEnumKeyA(HKEY_PERFORMANCE_DATA, 0, buffer, buffer_size); + ok(ret == ERROR_INVALID_HANDLE, "got %lu\n", ret); + + ret = RegEnumKeyA(HKEY_PERFORMANCE_TEXT, 0, buffer, buffer_size); + todo_wine ok(ret == ERROR_NO_MORE_ITEMS, "got %lu\n", ret); + + ret = RegEnumKeyA(HKEY_PERFORMANCE_NLSTEXT, 0, buffer, buffer_size); + todo_wine ok(ret == ERROR_NO_MORE_ITEMS, "got %lu\n", ret); + + free(buffer); +} + +static void test_perflib_key(void) +{ + unsigned int primary_lang = PRIMARYLANGID(GetUserDefaultLangID()); + unsigned int buffer_size = 1024 * 1024; + OBJECT_NAME_INFORMATION *name_info; + HKEY perflib_key, key, key2; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING string; + char lang_name[5]; + const char *knames[2] = {"009", "CurrentLanguage"}; + char *buffer; + DWORD size; + LONG ret, l; + + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib", 0, KEY_READ, &perflib_key); + ok(!ret, "got %lu\n", ret); + + ret = RegOpenKeyExA(perflib_key, "009", 0, KEY_READ, &key); + ok(!ret, "got %lu\n", ret); + /* English always returns TEXT; most other languages return NLSTEXT, but + * some (e.g. Hindi) return TEXT */ + ok(key == HKEY_PERFORMANCE_TEXT || key == HKEY_PERFORMANCE_NLSTEXT, "got key %p\n", key); + + ret = RegCloseKey(key); + ok(!ret, "got %lu\n", ret); + + RtlInitUnicodeString(&string, L"009"); + InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, perflib_key, NULL); + ret = NtOpenKey((HANDLE *)&key, KEY_ALL_ACCESS, &attr); + ok(ret == STATUS_PREDEFINED_HANDLE || ret == STATUS_ACCESS_DENIED + || ret == STATUS_SUCCESS /* Win < 7 */, "got %#lx\n", ret); + if (ret == STATUS_PREDEFINED_HANDLE) + ok(!is_special_key(key), "expected a normal handle, got %p\n", key); + else if (ret == STATUS_SUCCESS) + ok(key == HKEY_PERFORMANCE_TEXT, "got key %p\n", key); + else + { + skip("Not enough permissions to test the perflib key.\n"); + RegCloseKey(perflib_key); + return; + } + + buffer = malloc(buffer_size); + + ret = NtQueryKey(key, KeyFullInformation, buffer, buffer_size, &size); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + ret = NtEnumerateKey(key, 0, KeyFullInformation, buffer, buffer_size, &size); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + RtlInitUnicodeString(&string, L"counter"); + ret = NtQueryValueKey(key, &string, KeyValuePartialInformation, buffer, buffer_size, &size); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + ret = NtEnumerateValueKey(key, 0, KeyValuePartialInformation, buffer, buffer_size, &size); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + ret = NtSetValueKey(key, &string, 0, REG_SZ, "test", 5); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + ret = NtDeleteValueKey(key, &string); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + ret = NtDeleteKey(key); + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + + RtlInitUnicodeString(&string, L"subkey"); + InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, key, NULL); + ret = NtOpenKey((HANDLE *)&key2, KEY_READ, &attr); + if (is_special_key(key)) + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + else + ok(ret == STATUS_OBJECT_NAME_NOT_FOUND + || broken(ret == STATUS_INVALID_HANDLE) /* WoW64 */, "got %#lx\n", ret); + + ret = NtCreateKey((HANDLE *)&key2, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL); + if (is_special_key(key)) + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + else + ok(!ret || broken(ret == STATUS_ACCESS_DENIED) /* w8adm */ + || broken(ret == STATUS_INVALID_HANDLE) /* WoW64 */, "got %#lx\n", ret); + if (!ret) + { + NtDeleteKey(key2); + NtClose(key2); + } + + /* it's a real handle, though */ + ret = NtQueryObject(key, ObjectNameInformation, buffer, buffer_size, &size); + if (is_special_key(key)) + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + else + ok(!ret, "got %#lx\n", ret); + if (!ret) + { + name_info = (OBJECT_NAME_INFORMATION *)buffer; + ok(!wcsicmp(name_info->Name.Buffer, L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT" + "\\CurrentVersion\\Perflib\\009"), "got name %s\n", debugstr_w(name_info->Name.Buffer)); + } + + ret = NtClose(key); + if (is_special_key(key)) + ok(ret == STATUS_INVALID_HANDLE, "got %#lx\n", ret); + else + ok(!ret, "got %#lx\n", ret); + + for (l = 0; l < ARRAY_SIZE(knames); l++) + { + winetest_push_context("%ld", l); + todo_wine_if(l == 1) { + ret = RegOpenKeyExA(perflib_key, knames[l], 0, KEY_READ, &key); +#ifdef __REACTOS__ + if (ret == ERROR_FILE_NOT_FOUND) /* WS03, Vista */ + continue; +#endif + ok(!ret, "got %lu\n", ret); + if (is_special_key(key)) + { + size = buffer_size; + ret = RegQueryValueExA(key, "counter", NULL, NULL, (BYTE *)buffer, &size); + ok(!ret, "got %lu\n", ret); + if (!ret) + { + char *str; + int c = 0; + for (str = buffer; *str; str += strlen(str) + 1) + c++; + /* Note that the two keys may not have the same number of + * entries if they are in different languages. + */ + ok(c >= 2 && (c % 2) == 0, "%d is not a valid number of entries in %s\n", c, knames[l]); + trace("%s has %d entries\n", knames[l], c); + } + } + else + { + /* Windows 7 does not always return a special key for 009 + * when running without elevated privileges. + */ + ok(broken(l == 0), "expected a special handle, got %p\n", key); + } + + ret = RegCloseKey(key); + ok(!ret, "got %lu\n", ret); + } + winetest_pop_context(); + } + + /* multilingual support was not really completely thought through */ + switch (primary_lang) + { + case LANG_PORTUGUESE: + case LANG_CHINESE: + sprintf(lang_name, "%04x", GetUserDefaultLangID()); + break; + default: + sprintf(lang_name, "%03x", primary_lang); + break; + } + if (primary_lang != LANG_ENGLISH && + !RegOpenKeyExA(perflib_key, lang_name, 0, KEY_READ, &key)) + { + ok(!is_special_key(key), "expected a normal handle, got %p\n", key); + + size = buffer_size; + ret = RegQueryValueExA(key, "counter", NULL, NULL, (BYTE *)buffer, &size); + todo_wine ok(ret == ERROR_FILE_NOT_FOUND, "got %lu\n", ret); + + ret = RegCloseKey(key); + todo_wine ok(!ret, "got %lu\n", ret); + } + /* else some languages don't have their own key. The keys are not really + * usable anyway so assume it does not really matter. + */ + + ret = RegCloseKey(perflib_key); + ok(!ret, "got %lu\n", ret); + + RtlInitUnicodeString(&string, L"\\Registry\\PerfData"); + InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, NULL, NULL); + ret = NtOpenKey((HANDLE *)&key, KEY_READ, &attr); + ok(ret == STATUS_OBJECT_NAME_NOT_FOUND, "got %#lx\n", ret); + + free(buffer); +} + +static void test_RegLoadMUIString(void) +{ + HMODULE hUser32, hResDll, hFile; + int (WINAPI *pLoadStringW)(HMODULE, UINT, WCHAR *, int); + LONG ret; + HKEY hkey; + DWORD type, size, text_size; + UINT i; + char buf[64], *p, sysdir[MAX_PATH]; + char with_env_var[128], filename[MAX_PATH], tmp_path[MAX_PATH]; + WCHAR textW[64], bufW[64]; + WCHAR curdirW[MAX_PATH], sysdirW[MAX_PATH]; + const static char tz_value[] = "MUI_Std"; + const static WCHAR tz_valueW[] = L"MUI_Std"; + struct { + const char* value; + DWORD type; + BOOL use_sysdir; + DWORD expected; + DWORD broken_ret; + } test_case[] = { + /* 0 */ + { "", REG_SZ, FALSE, ERROR_INVALID_DATA }, + { "not a MUI string", REG_SZ, FALSE, ERROR_INVALID_DATA }, + { "@unknown.dll", REG_SZ, TRUE, ERROR_INVALID_DATA }, + { "@unknown.dll,-10", REG_SZ, TRUE, ERROR_FILE_NOT_FOUND }, + /* 4 */ + { with_env_var, REG_SZ, FALSE, ERROR_SUCCESS }, + { with_env_var, REG_EXPAND_SZ, FALSE, ERROR_SUCCESS }, + { "%WineMuiTest1%", REG_EXPAND_SZ, TRUE, ERROR_INVALID_DATA }, + { "@%WineMuiTest2%", REG_EXPAND_SZ, TRUE, ERROR_SUCCESS }, + /* 8 */ + { "@%WineMuiExe%,a", REG_SZ, FALSE, ERROR_INVALID_DATA }, + { "@%WineMuiExe%,-4", REG_SZ, FALSE, ERROR_NOT_FOUND, ERROR_FILE_NOT_FOUND }, +#ifdef __REACTOS__ + { "@%WineMuiExe%,-39", REG_SZ, FALSE, ERROR_RESOURCE_NAME_NOT_FOUND, ERROR_RESOURCE_DATA_NOT_FOUND }, +#else + { "@%WineMuiExe%,-39", REG_SZ, FALSE, ERROR_RESOURCE_NAME_NOT_FOUND }, +#endif + { "@%WineMuiDat%,-16", REG_EXPAND_SZ, FALSE, ERROR_BAD_EXE_FORMAT, ERROR_FILE_NOT_FOUND }, + }; + + if (!pRegLoadMUIStringA || !pRegLoadMUIStringW) + { + win_skip("RegLoadMUIString is not available\n"); + return; + } +#if defined(__REACTOS__) && defined(_WIN64) + if (GetNTVersion() == _WIN32_WINNT_VISTA) { + skip("test_RegLoadMUIString() spams the console with garbage and crashes on Vista x64.\n"); + return; + } +#endif + + hUser32 = LoadLibraryA("user32.dll"); + ok(hUser32 != NULL, "cannot load user32.dll\n"); + pLoadStringW = (void *)GetProcAddress(hUser32, "LoadStringW"); + ok(pLoadStringW != NULL, "failed to get LoadStringW address\n"); + + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\UTC", 0, + KEY_READ, &hkey); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); + + size = ARRAY_SIZE(buf); + ret = RegQueryValueExA(hkey, tz_value, NULL, &type, (BYTE *)buf, &size); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); + ok(buf[0] == '@', "got %s\n", buf); + + /* setup MUI string for tests */ + strcpy(with_env_var, "@%windir%\\system32\\"); + strcat(with_env_var, &buf[1]); + SetEnvironmentVariableA("WineMuiTest1", buf); + SetEnvironmentVariableA("WineMuiTest2", &buf[1]); + + /* load expecting text */ + p = strrchr(buf, ','); + *p = '\0'; + i = atoi(p + 2); /* skip ',-' */ + hResDll = LoadLibraryExA(&buf[1], NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); + memset(textW, 0xaa, sizeof(textW)); + ret = pLoadStringW(hResDll, i, textW, ARRAY_SIZE(textW)); + ok(ret > 0, "failed to load string resource\n"); + text_size = (ret + 1) * sizeof(WCHAR); + FreeLibrary(hResDll); + FreeLibrary(hUser32); + + ret = GetSystemDirectoryW(sysdirW, ARRAY_SIZE(sysdirW)); + ok(ret > 0, "GetSystemDirectoryW failed\n"); + ret = GetSystemDirectoryA(sysdir, ARRAY_SIZE(sysdir)); + ok(ret > 0, "GetSystemDirectoryA failed\n"); + + /* change the current directory to system32 */ + GetCurrentDirectoryW(ARRAY_SIZE(curdirW), curdirW); + SetCurrentDirectoryW(sysdirW); + + size = 0xdeadbeef; + ret = pRegLoadMUIStringW(hkey, tz_valueW, NULL, 0, &size, 0, NULL); + ok(ret == ERROR_MORE_DATA, "got %ld, expected ERROR_MORE_DATA\n", ret); +#ifdef __REACTOS__ + ok(size == text_size || broken(size == text_size + sizeof(WCHAR)) /* Vista */, "got %lu, expected %lu\n", size, text_size); +#else + ok(size == text_size, "got %lu, expected %lu\n", size, text_size); +#endif + + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, sizeof(WCHAR)+1, &size, 0, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld, expected ERROR_INVALID_PARAMETER\n", ret); + ok(bufW[0] == 0xffff, "got 0x%04x, expected 0xffff\n", bufW[0]); + + size = 0xdeadbeef; + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, sizeof(WCHAR)*2, &size, 0, NULL); + ok(ret == ERROR_MORE_DATA, "got %ld, expected ERROR_MORE_DATA\n", ret); + ok(size == text_size || broken(size == text_size + sizeof(WCHAR) /* vista */), + "got %lu, expected %lu\n", size, text_size); + ok(bufW[0] == 0xffff, "got 0x%04x, expected 0xffff\n", bufW[0]); + + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, sizeof(WCHAR)*2, &size, REG_MUI_STRING_TRUNCATE, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld, expected ERROR_INVALID_PARAMETER\n", ret); + ok(bufW[0] == 0xffff, "got 0x%04x, expected 0xffff\n", bufW[0]); + + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, sizeof(WCHAR)*2, NULL, 0xdeadbeef, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld, expected ERROR_INVALID_PARAMETER\n", ret); + ok(bufW[0] == 0xffff, "got 0x%04x, expected 0xffff\n", bufW[0]); + + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, sizeof(WCHAR)*2, NULL, REG_MUI_STRING_TRUNCATE, NULL); + ok(ret == ERROR_SUCCESS, "got %ld, expected ERROR_SUCCESS\n", ret); + ok(bufW[0] == textW[0], "got 0x%04x, expected 0x%04x\n", bufW[0], textW[0]); + ok(bufW[1] == 0, "got 0x%04x, expected nul\n", bufW[1]); + + size = 0xdeadbeef; + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, ARRAY_SIZE(bufW), &size, 0, NULL); + ok(ret == ERROR_SUCCESS, "got %ld, expected ERROR_SUCCESS\n", ret); + ok(size == text_size, "got %lu, expected %lu\n", size, text_size); + ok(!memcmp(textW, bufW, size), "got %s, expected %s\n", + wine_dbgstr_wn(bufW, size / sizeof(WCHAR)), wine_dbgstr_wn(textW, text_size / sizeof(WCHAR))); + + ret = pRegLoadMUIStringA(hkey, tz_value, buf, ARRAY_SIZE(buf), &size, 0, NULL); + ok(ret == ERROR_CALL_NOT_IMPLEMENTED, "got %ld, expected ERROR_CALL_NOT_IMPLEMENTED\n", ret); + + /* change the current directory to other than system32 directory */ + SetCurrentDirectoryA("\\"); + + size = 0xdeadbeef; + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, ARRAY_SIZE(bufW), &size, 0, sysdirW); + ok(ret == ERROR_SUCCESS, "got %ld, expected ERROR_SUCCESS\n", ret); + ok(size == text_size, "got %lu, expected %lu\n", size, text_size); + ok(!memcmp(textW, bufW, size), "got %s, expected %s\n", + wine_dbgstr_wn(bufW, size / sizeof(WCHAR)), wine_dbgstr_wn(textW, text_size / sizeof(WCHAR))); + + ret = pRegLoadMUIStringA(hkey, tz_value, buf, ARRAY_SIZE(buf), &size, 0, sysdir); + ok(ret == ERROR_CALL_NOT_IMPLEMENTED, "got %ld, expected ERROR_CALL_NOT_IMPLEMENTED\n", ret); + + ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, ARRAY_SIZE(bufW), &size, 0, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %ld, expected ERROR_FILE_NOT_FOUND\n", ret); + + ret = pRegLoadMUIStringA(hkey, tz_value, buf, ARRAY_SIZE(buf), &size, 0, NULL); + ok(ret == ERROR_CALL_NOT_IMPLEMENTED, "got %ld, expected ERROR_CALL_NOT_IMPLEMENTED\n", ret); + + RegCloseKey(hkey); + + GetModuleFileNameA(NULL, filename, ARRAY_SIZE(filename)); + SetEnvironmentVariableA("WineMuiExe", filename); + + GetTempPathA(ARRAY_SIZE(tmp_path), tmp_path); + GetTempFileNameA(tmp_path, "mui", 0, filename); + SetEnvironmentVariableA("WineMuiDat", filename); + + /* write dummy data to the file, i.e. it's not a PE file. */ + hFile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(hFile != INVALID_HANDLE_VALUE, "can't open %s\n", filename); + WriteFile(hFile, filename, strlen(filename), &size, NULL); + CloseHandle(hFile); + + for (i = 0; i < ARRAY_SIZE(test_case); i++) + { + size = test_case[i].value ? strlen(test_case[i].value) + 1 : 0; + ret = RegSetValueExA(hkey_main, tz_value, 0, test_case[i].type, + (const BYTE *)test_case[i].value, size); + ok(ret == ERROR_SUCCESS, "[%2u] got %ld\n", i, ret); + + size = 0xdeadbeef; + memset(bufW, 0xff, sizeof(bufW)); + ret = pRegLoadMUIStringW(hkey_main, tz_valueW, bufW, ARRAY_SIZE(bufW), + &size, 0, + test_case[i].use_sysdir ? sysdirW : NULL); + ok(ret == test_case[i].expected || +#ifdef __REACTOS__ + broken(i == 9 && ret == ERROR_RESOURCE_DATA_NOT_FOUND /* Vista */) || +#endif + broken(test_case[i].value[0] == '%' && ret == ERROR_SUCCESS /* vista */) || + broken(test_case[i].broken_ret && ret == test_case[i].broken_ret /* vista */), + "[%2u] expected %ld, got %ld\n", i, test_case[i].expected, ret); + if (ret == ERROR_SUCCESS && test_case[i].expected == ERROR_SUCCESS) + { + ok(size == text_size, "[%2u] got %lu, expected %lu\n", i, size, text_size); + ok(!memcmp(bufW, textW, size), "[%2u] got %s, expected %s\n", i, + wine_dbgstr_wn(bufW, size/sizeof(WCHAR)), + wine_dbgstr_wn(textW, text_size/sizeof(WCHAR))); + } + } + + SetCurrentDirectoryW(curdirW); + DeleteFileA(filename); + SetEnvironmentVariableA("WineMuiTest1", NULL); + SetEnvironmentVariableA("WineMuiTest2", NULL); + SetEnvironmentVariableA("WineMuiExe", NULL); + SetEnvironmentVariableA("WineMuiDat", NULL); +} + +static void test_EnumDynamicTimeZoneInformation(void) +{ + LSTATUS status; + HKEY key, subkey; + WCHAR name[128]; + WCHAR keyname[128]; + WCHAR sysdir[MAX_PATH]; + DWORD index, ret, gle, size; + DYNAMIC_TIME_ZONE_INFORMATION bogus_dtzi, dtzi; + struct tz_reg_data + { + LONG bias; + LONG std_bias; + LONG dlt_bias; + SYSTEMTIME std_date; + SYSTEMTIME dlt_date; + } tz_data; + + if (!pEnumDynamicTimeZoneInformation) + { + win_skip("EnumDynamicTimeZoneInformation is not supported.\n"); + return; + } + + if (pRegLoadMUIStringW) + GetSystemDirectoryW(sysdir, ARRAY_SIZE(sysdir)); + + SetLastError(0xdeadbeef); + ret = pEnumDynamicTimeZoneInformation(0, NULL); + gle = GetLastError(); + ok(gle == 0xdeadbeef, "got 0x%lx\n", gle); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld\n", ret); + + memset(&bogus_dtzi, 0xcc, sizeof(bogus_dtzi)); + memset(&dtzi, 0xcc, sizeof(dtzi)); + SetLastError(0xdeadbeef); + ret = pEnumDynamicTimeZoneInformation(-1, &dtzi); + gle = GetLastError(); + ok(gle == 0xdeadbeef, "got 0x%lx\n", gle); + ok(ret == ERROR_NO_MORE_ITEMS, "got %ld\n", ret); + ok(!memcmp(&dtzi, &bogus_dtzi, sizeof(dtzi)), "mismatch\n"); + + status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", 0, + KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE, &key); + ok(status == ERROR_SUCCESS, "got %ld\n", status); + index = 0; + while (!(status = RegEnumKeyW(key, index, keyname, ARRAY_SIZE(keyname)))) + { + winetest_push_context("%s" , wine_dbgstr_w(keyname)); + subkey = NULL; + status = RegOpenKeyExW(key, keyname, 0, KEY_QUERY_VALUE, &subkey); + ok(status == ERROR_SUCCESS, "got %ld\n", status); + + memset(&dtzi, 0xcc, sizeof(dtzi)); + SetLastError(0xdeadbeef); + ret = pEnumDynamicTimeZoneInformation(index, &dtzi); + gle = GetLastError(); + /* recently added time zones may not have MUI strings */ + ok(gle == ERROR_SUCCESS || + gle == ERROR_RESOURCE_TYPE_NOT_FOUND /* Win10 1809 32-bit */ || + gle == ERROR_MUI_FILE_NOT_FOUND /* Win10 1809 64-bit */, + "got 0x%lx\n", gle); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); + ok(!lstrcmpW(dtzi.TimeZoneKeyName, keyname), "expected %s, got %s\n", + wine_dbgstr_w(keyname), wine_dbgstr_w(dtzi.TimeZoneKeyName)); + + if (gle == ERROR_SUCCESS) + { + size = sizeof(name); + memset(name, 0, sizeof(name)); + status = pRegGetValueW(subkey, NULL, L"Std", RRF_RT_REG_SZ, NULL, name, &size); + ok(status == ERROR_SUCCESS, "status %ld Std %s\n", status, + wine_dbgstr_w(name)); + ok(*name, "Std name is empty\n"); + if (pRegLoadMUIStringW) + { + size = sizeof(name); + memset(name, 0, sizeof(name)); + status = pRegLoadMUIStringW(subkey, L"MUI_Std", name, size, &size, 0, sysdir); + ok(status == ERROR_SUCCESS, "status %ld MUI_Std %s\n", + status, wine_dbgstr_w(name)); + ok(*name, "MUI_Std name is empty\n"); + } + ok(!memcmp(&dtzi.StandardName, name, size), "expected %s, got %s\n", + wine_dbgstr_w(name), wine_dbgstr_w(dtzi.StandardName)); + + size = sizeof(name); + memset(name, 0, sizeof(name)); + status = pRegGetValueW(subkey, NULL, L"Dlt", RRF_RT_REG_SZ, NULL, name, &size); + ok(status == ERROR_SUCCESS, "status %ld %s Dlt %s\n", + status, wine_dbgstr_w(keyname), wine_dbgstr_w(name)); + ok(*name, "Dlt name is empty\n"); + if (pRegLoadMUIStringW) + { + size = sizeof(name); + memset(name, 0, sizeof(name)); + status = pRegLoadMUIStringW(subkey, L"MUI_Dlt", name, size, &size, 0, sysdir); + ok(status == ERROR_SUCCESS, "status %ld %s MUI_Dlt %s\n", + status, wine_dbgstr_w(keyname), wine_dbgstr_w(name)); + ok(*name, "MUI_Dlt name is empty\n"); + } + ok(!memcmp(&dtzi.DaylightName, name, size), "expected %s, got %s\n", + wine_dbgstr_w(name), wine_dbgstr_w(dtzi.DaylightName)); + + size = sizeof(name); + memset(name, 0, sizeof(name)); + status = pRegGetValueW(subkey, NULL, L"Display", RRF_RT_REG_SZ, NULL, name, &size); + ok(status == ERROR_SUCCESS, "status %ld %s Display %s\n", + status, wine_dbgstr_w(keyname), wine_dbgstr_w(name)); + ok(*name, "Display name is empty\n"); + if (pRegLoadMUIStringW) + { + size = sizeof(name); + memset(name, 0, sizeof(name)); + status = pRegLoadMUIStringW(subkey, L"MUI_Display", name, size, &size, 0, sysdir); + /* recently added time zones may not have MUI strings */ + ok((status == ERROR_SUCCESS && *name) || + broken(status == ERROR_RESOURCE_TYPE_NOT_FOUND) /* Win10 1809 32-bit */ || + broken(status == ERROR_MUI_FILE_NOT_FOUND) /* Win10 1809 64-bit */, + "status %ld MUI_Display %s\n", status, wine_dbgstr_w(name)); + } + } + else + { + ok(!dtzi.StandardName[0], "expected empty StandardName\n"); + ok(!dtzi.DaylightName[0], "expected empty DaylightName\n"); + } + + ok(!dtzi.DynamicDaylightTimeDisabled, "got %d\n", dtzi.DynamicDaylightTimeDisabled); + + size = sizeof(tz_data); + status = pRegGetValueW(key, keyname, L"TZI", RRF_RT_REG_BINARY, NULL, &tz_data, &size); + ok(status == ERROR_SUCCESS, "got %ld\n", status); + + ok(dtzi.Bias == tz_data.bias, "expected %ld, got %ld\n", + tz_data.bias, dtzi.Bias); + ok(dtzi.StandardBias == tz_data.std_bias, "expected %ld, got %ld\n", + tz_data.std_bias, dtzi.StandardBias); + ok(dtzi.DaylightBias == tz_data.dlt_bias, "expected %ld, got %ld\n", + tz_data.dlt_bias, dtzi.DaylightBias); + + ok(!memcmp(&dtzi.StandardDate, &tz_data.std_date, sizeof(dtzi.StandardDate)), + "expected %s, got %s\n", + dbgstr_SYSTEMTIME(&tz_data.std_date), dbgstr_SYSTEMTIME(&dtzi.StandardDate)); + + ok(!memcmp(&dtzi.DaylightDate, &tz_data.dlt_date, sizeof(dtzi.DaylightDate)), + "expected %s, got %s\n", + dbgstr_SYSTEMTIME(&tz_data.dlt_date), dbgstr_SYSTEMTIME(&dtzi.DaylightDate)); + + winetest_pop_context(); + RegCloseKey(subkey); + index++; + } + ok(status == ERROR_NO_MORE_ITEMS, "got %ld\n", status); + + memset(&dtzi, 0xcc, sizeof(dtzi)); + SetLastError(0xdeadbeef); + ret = pEnumDynamicTimeZoneInformation(index, &dtzi); + gle = GetLastError(); + ok(gle == 0xdeadbeef, "got 0x%lx\n", gle); + ok(ret == ERROR_NO_MORE_ITEMS, "got %ld\n", ret); + ok(!memcmp(&dtzi, &bogus_dtzi, sizeof(dtzi)), "mismatch\n"); + + RegCloseKey(key); +} + +static void test_RegRenameKey(void) +{ +#if defined(__REACTOS__) && DLL_EXPORT_VERSION < 0x600 + skip("test_RegRenameKey() can't be built unless DLL_EXPORT_VERSION >= 0x600\n"); +#else + HKEY key, key2; + LSTATUS ret; + + ret = RegRenameKey(NULL, NULL, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(NULL, NULL, L"newname"); + ok(ret == ERROR_INVALID_HANDLE, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(NULL, L"oldname", NULL); + ok(ret == ERROR_INVALID_HANDLE, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(NULL, L"oldname", L"newname"); + ok(ret == ERROR_INVALID_HANDLE, "Unexpected return value %ld.\n", ret); + + ret = RegCreateKeyExA(hkey_main, "TestRenameKey", 0, NULL, 0, KEY_READ, NULL, &key, NULL); + ok(!ret, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(key, NULL, L"TestNewRenameKey"); + ok(ret == ERROR_ACCESS_DENIED, "Unexpected return value %ld.\n", ret); + RegCloseKey(key); + + /* Rename itself. */ + ret = RegCreateKeyExA(hkey_main, "TestRenameKey", 0, NULL, 0, KEY_WRITE, NULL, &key, NULL); + ok(!ret, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(key, NULL, NULL); + ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(key, NULL, L"TestNewRenameKey"); + ok(!ret, "Unexpected return value %ld.\n", ret); + RegCloseKey(key); + + ret = RegDeleteKeyA(hkey_main, "TestNewRenameKey"); + ok(!ret, "Unexpected return value %ld.\n", ret); + ret = RegDeleteKeyA(hkey_main, "TestRenameKey"); + ok(ret, "Unexpected return value %ld.\n", ret); + + /* Subkey does not exist. */ + ret = RegCreateKeyExA(hkey_main, "TestRenameKey", 0, NULL, 0, KEY_WRITE, NULL, &key, NULL); + ok(!ret, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(key, L"unknown_subkey", NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "Unexpected return value %ld.\n", ret); + ret = RegRenameKey(key, L"unknown_subkey", L"known_subkey"); + ok(ret == ERROR_FILE_NOT_FOUND, "Unexpected return value %ld.\n", ret); + + /* Rename existing subkey. */ + ret = RegCreateKeyExA(key, "known_subkey", 0, NULL, 0, KEY_WRITE, NULL, &key2, NULL); + ok(!ret, "Unexpected return value %ld.\n", ret); + RegCloseKey(key2); + + ret = RegRenameKey(key, L"known_subkey", L"renamed_subkey"); + ok(!ret, "Unexpected return value %ld.\n", ret); + + ret = RegDeleteKeyA(key, "renamed_subkey"); + ok(!ret, "Unexpected return value %ld.\n", ret); + ret = RegDeleteKeyA(key, "known_subkey"); + ok(ret, "Unexpected return value %ld.\n", ret); + + RegCloseKey(key); +#endif +} + +static BOOL check_cs_number( const WCHAR *str ) +{ + if (str[0] < '0' || str[0] > '9' || str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9') + return FALSE; + if (str[0] == '0' && str[1] == '0' && str[2] == '0') + return FALSE; + return TRUE; +} + +static void test_control_set_symlink(void) +{ + static const WCHAR target_pfxW[] = L"\\REGISTRY\\Machine\\System\\ControlSet"; + DWORD target_len, type, len, err; + BYTE buffer[1024]; + HKEY key; + + target_len = sizeof(target_pfxW) + 3 * sizeof(WCHAR); + + err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "System\\CurrentControlSet", REG_OPTION_OPEN_LINK, KEY_QUERY_VALUE, &key ); + ok( err == ERROR_SUCCESS, "RegOpenKeyEx failed error %lu\n", err ); + len = sizeof(buffer); + err = RegQueryValueExA( key, "SymbolicLinkValue", NULL, &type, buffer, &len ); + ok( err == ERROR_SUCCESS, "RegQueryValueEx failed error %lu\n", err ); + ok( len == target_len - sizeof(WCHAR), "wrong len %lu\n", len ); + ok( !wcsnicmp( (WCHAR*)buffer, target_pfxW, ARRAY_SIZE(target_pfxW) - 1 ) && + check_cs_number( (WCHAR*)buffer + ARRAY_SIZE(target_pfxW) - 1 ), + "wrong link target\n" ); + RegCloseKey( key ); } START_TEST(registry) @@ -3776,15 +5245,14 @@ START_TEST(registry) test_reg_query_value(); test_reg_query_info(); test_string_termination(); + test_multistring_termination(); test_symlinks(); test_redirection(); test_classesroot(); test_classesroot_enum(); test_classesroot_mask(); - test_perflib_key(); - test_reg_save_key(); test_reg_load_key(); - test_reg_unload_key(); + test_reg_load_app_key(); test_reg_copy_tree(); test_reg_delete_tree(); test_rw_order(); @@ -3793,10 +5261,15 @@ START_TEST(registry) test_delete_key_value(); test_RegOpenCurrentUser(); test_RegNotifyChangeKeyValue(); - test_RegQueryValueExPerformanceData(); + test_performance_keys(); + test_RegLoadMUIString(); + test_EnumDynamicTimeZoneInformation(); + test_perflib_key(); + test_RegRenameKey(); + test_control_set_symlink(); /* cleanup */ delete_key( hkey_main ); - + test_regconnectregistry(); } diff --git a/modules/rostests/winetests/advapi32/security.c b/modules/rostests/winetests/advapi32/security.c index fdd657d6a0c..ed7e1b5036c 100644 --- a/modules/rostests/winetests/advapi32/security.c +++ b/modules/rostests/winetests/advapi32/security.c @@ -2,7 +2,7 @@ * Unit tests for security functions * * Copyright (c) 2004 Mike McCormack - * Copyright (c) 2011,2013,2014,2016 Dmitry Timoshkov + * Copyright (c) 2011 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,10 +36,54 @@ #include "wine/test.h" -/* FIXME: Inspect */ -#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3) -#define GetCurrentThreadToken() ((HANDLE)~(ULONG_PTR)4) -#define GetCurrentThreadEffectiveToken() ((HANDLE)~(ULONG_PTR)5) +#ifdef __REACTOS__ +/* FIXME: Removing these hacks requires fixing our incompatible wine/test.h and wine/debug.h. */ +#ifndef wine_dbg_sprintf +static inline const char* wine_dbg_sprintf(const char* format, ...) +{ + static char buffer[256]; + va_list args; + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + return buffer; +} +#endif + +struct debug_info +{ + unsigned int str_pos; /* current position in strings buffer */ + unsigned int out_pos; /* current position in output buffer */ + char strings[1020]; /* buffer for temporary strings */ + char output[1020]; /* current output line */ +}; + +C_ASSERT( sizeof(struct debug_info) == 0x800 ); + +static inline struct debug_info *get_info(void) +{ +#ifdef _WIN64 + return (struct debug_info *)((TEB32 *)((char *)NtCurrentTeb() + 0x2000) + 1); +#else + return (struct debug_info *)(NtCurrentTeb() + 1); +#endif +} + +const char * __cdecl __wine_dbg_strdup( const char *str ) +{ + struct debug_info *info = get_info(); + unsigned int pos = info->str_pos; + size_t n = strlen( str ) + 1; + + if (pos + n > sizeof(info->strings)) pos = 0; + info->str_pos = pos + n; + return memcpy( info->strings + pos, str, n ); +} + +BOOL WINAPI GetWindowsAccountDomainSid(_In_ PSID pSid, _Out_opt_ PSID pDomainSid, _Inout_ DWORD *cbDomainSid); +BOOL WINAPI AddAuditAccessAceEx(_Inout_ PACL pAcl, _In_ DWORD dwAceRevision, _In_ DWORD AceFlags, _In_ DWORD dwAccessMask, _In_ PSID pSid, _In_ BOOL bAuditSuccess, _In_ BOOL bAuditFailure); +BOOL WINAPI EqualDomainSid(_In_ PSID pSid1, _In_ PSID pSid2, _Out_ BOOL* pfEqual); +#endif #ifndef PROCESS_QUERY_LIMITED_INFORMATION #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000 @@ -67,9 +111,6 @@ #define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); } -static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID); -static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID); -static BOOL (WINAPI *pAddAuditAccessAceEx)(PACL, DWORD, DWORD, DWORD, PSID, BOOL, BOOL); static BOOL (WINAPI *pAddMandatoryAce)(PACL,DWORD,DWORD,DWORD,PSID); static VOID (WINAPI *pBuildTrusteeWithSidA)( PTRUSTEEA pTrustee, PSID pSid ); static VOID (WINAPI *pBuildTrusteeWithNameA)( PTRUSTEEA pTrustee, LPSTR pName ); @@ -85,86 +126,26 @@ static VOID (WINAPI *pBuildTrusteeWithObjectsAndSidA)( PTRUSTEEA pTrustee, GUID* pInheritedObjectGuid, PSID pSid ); static LPSTR (WINAPI *pGetTrusteeNameA)( PTRUSTEEA pTrustee ); -static BOOL (WINAPI *pMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, LPDWORD ); -static BOOL (WINAPI *pConvertStringSidToSidA)( LPCSTR str, PSID pSid ); -static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL); -static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR, DWORD, - PSECURITY_DESCRIPTOR*, PULONG ); -static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR, DWORD, - PSECURITY_DESCRIPTOR*, PULONG ); -static BOOL (WINAPI *pConvertSecurityDescriptorToStringSecurityDescriptorA)(PSECURITY_DESCRIPTOR, DWORD, - SECURITY_INFORMATION, LPSTR *, PULONG ); -static BOOL (WINAPI *pGetFileSecurityA)(LPCSTR, SECURITY_INFORMATION, - PSECURITY_DESCRIPTOR, DWORD, LPDWORD); -static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION, - PSECURITY_DESCRIPTOR); -static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, - PSID*, PSID*, PACL*, PACL*, - PSECURITY_DESCRIPTOR*); -static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, - PSID, PSID, PACL, PACL); -static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD); -static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID); -static BOOL (WINAPI *pIsValidSid)(PSID); static DWORD (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); -static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*); -static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES, - SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE); - -static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*); -static NTSTATUS (WINAPI *pLsaClose)(LSA_HANDLE); -static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID); -static NTSTATUS (WINAPI *pLsaOpenPolicy)(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE); -static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG); -static DWORD (WINAPI *pSetEntriesInAclW)(ULONG, PEXPLICIT_ACCESSW, PACL, PACL*); -static DWORD (WINAPI *pSetEntriesInAclA)(ULONG, PEXPLICIT_ACCESSA, PACL, PACL*); -static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, - SECURITY_DESCRIPTOR_CONTROL); -static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, - PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); -static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, - PSID, PSID, PACL, PACL); static NTSTATUS (WINAPI *pNtAccessCheck)(PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK, PGENERIC_MAPPING, PPRIVILEGE_SET, PULONG, PULONG, NTSTATUS*); -static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, - PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE); -static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS); -static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*); -static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); -static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG); static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*); -static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN); -static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*); -static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); -static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); -static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID); -static DWORD (WINAPI *pGetExplicitEntriesFromAclW)(PACL,PULONG,PEXPLICIT_ACCESSW*); static HMODULE hmod; static int myARGC; static char** myARGV; -#define SID_SLOTS 4 -static char debugsid_str[SID_SLOTS][256]; -static int debugsid_index = 0; static const char* debugstr_sid(PSID sid) { LPSTR sidstr; DWORD le = GetLastError(); - char* res = debugsid_str[debugsid_index]; - debugsid_index = (debugsid_index + 1) % SID_SLOTS; + const char *res; if (!ConvertSidToStringSidA(sid, &sidstr)) - sprintf(res, "ConvertSidToStringSidA failed le=%u", GetLastError()); - else if (strlen(sidstr) > sizeof(*debugsid_str) - 1) - { - memcpy(res, sidstr, sizeof(*debugsid_str) - 4); - strcpy(res + sizeof(*debugsid_str) - 4, "..."); - LocalFree(sidstr); - } + res = wine_dbg_sprintf("ConvertSidToStringSidA failed le=%lu", GetLastError()); else { - strcpy(res, sidstr); + res = __wine_dbg_strdup(sidstr); LocalFree(sidstr); } /* Restore the last error in case ConvertSidToStringSidA() modified it */ @@ -172,61 +153,29 @@ static const char* debugstr_sid(PSID sid) return res; } +struct sidRef +{ + SID_IDENTIFIER_AUTHORITY auth; + const char *refStr; +}; + static void init(void) { HMODULE hntdll; hntdll = GetModuleHandleA("ntdll.dll"); - pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" ); pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" ); - pNtSetSecurityObject = (void *)GetProcAddress(hntdll, "NtSetSecurityObject"); - pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile"); pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); - pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString"); - pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString"); - pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); hmod = GetModuleHandleA("advapi32.dll"); - pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx"); - pAddAccessDeniedAceEx = (void *)GetProcAddress(hmod, "AddAccessDeniedAceEx"); - pAddAuditAccessAceEx = (void *)GetProcAddress(hmod, "AddAuditAccessAceEx"); pAddMandatoryAce = (void *)GetProcAddress(hmod, "AddMandatoryAce"); - pCheckTokenMembership = (void *)GetProcAddress(hmod, "CheckTokenMembership"); - pConvertStringSecurityDescriptorToSecurityDescriptorA = - (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorA" ); - pConvertStringSecurityDescriptorToSecurityDescriptorW = - (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorW" ); - pConvertSecurityDescriptorToStringSecurityDescriptorA = - (void *)GetProcAddress(hmod, "ConvertSecurityDescriptorToStringSecurityDescriptorA" ); - pGetFileSecurityA = (void *)GetProcAddress(hmod, "GetFileSecurityA" ); - pSetFileSecurityA = (void *)GetProcAddress(hmod, "SetFileSecurityA" ); - pCreateWellKnownSid = (void *)GetProcAddress( hmod, "CreateWellKnownSid" ); - pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "GetNamedSecurityInfoA"); - pSetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "SetNamedSecurityInfoA"); - pGetSidSubAuthority = (void *)GetProcAddress(hmod, "GetSidSubAuthority"); - pGetSidSubAuthorityCount = (void *)GetProcAddress(hmod, "GetSidSubAuthorityCount"); - pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid"); - pMakeSelfRelativeSD = (void *)GetProcAddress(hmod, "MakeSelfRelativeSD"); - pSetEntriesInAclW = (void *)GetProcAddress(hmod, "SetEntriesInAclW"); - pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA"); - pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl"); - pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo"); - pSetSecurityInfo = (void *)GetProcAddress(hmod, "SetSecurityInfo"); - pCreateRestrictedToken = (void *)GetProcAddress(hmod, "CreateRestrictedToken"); - pConvertStringSidToSidA = (void *)GetProcAddress(hmod, "ConvertStringSidToSidA"); - pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation"); - pGetAce = (void *)GetProcAddress(hmod, "GetAce"); - pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid"); - pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority"); - pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx"); - pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW"); myARGC = winetest_get_mainargs( &myARGV ); } static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line) { - /* use HeapFree(GetProcessHeap(), 0, sd); when done */ + /* use free(sd); when done */ DWORD ret, length, needed; SECURITY_DESCRIPTOR *sd; @@ -235,18 +184,18 @@ static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, 0, &needed); ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n"); - ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n"); length = needed; - sd = HeapAlloc(GetProcessHeap(), 0, length); + sd = malloc(length); needed = 0xdeadbeef; SetLastError(0xdeadbeef); ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, sd, length, &needed); - ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %d\n", GetLastError()); - ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed); + ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %ld\n", GetLastError()); + ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %lu instead of %lu\n", length, needed); return sd; } @@ -260,13 +209,17 @@ static void test_owner_equal(HANDLE Handle, PSID expected, int line) queriedSD = test_get_security_descriptor( Handle, line ); res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted); - ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); +#ifdef __REACTOS__ + /* The call to EqualSid below crashes on WS03. */ + if (GetNTVersion() > _WIN32_WINNT_WS03) +#endif ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n", debugstr_sid(owner), debugstr_sid(expected)); ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n"); - HeapFree(GetProcessHeap(), 0, queriedSD); + free(queriedSD); } static void test_group_equal(HANDLE Handle, PSID expected, int line) @@ -279,22 +232,22 @@ static void test_group_equal(HANDLE Handle, PSID expected, int line) queriedSD = test_get_security_descriptor( Handle, line ); res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted); - ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); +#ifdef __REACTOS__ + /* The call to EqualSid below crashes on WS03. */ + if (GetNTVersion() > _WIN32_WINNT_WS03) +#endif ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n", debugstr_sid(group), debugstr_sid(expected)); ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n"); - HeapFree(GetProcessHeap(), 0, queriedSD); + free(queriedSD); } -static void test_sid(void) +static void test_ConvertStringSidToSid(void) { - static struct - { - SID_IDENTIFIER_AUTHORITY auth; - const char *refStr; - } refs[] = { + struct sidRef refs[] = { { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" }, { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" }, { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" }, @@ -304,99 +257,117 @@ static void test_sid(void) }; static const struct { - const char *str; - WELL_KNOWN_SID_TYPE sid_type; - BOOL optional; - } strsid_table[] = { - /* Please keep the list sorted. */ - { "AC", WinBuiltinAnyPackageSid, TRUE }, - { "AN", WinAnonymousSid }, - { "AO", WinBuiltinAccountOperatorsSid }, - { "AU", WinAuthenticatedUserSid }, - { "BA", WinBuiltinAdministratorsSid }, - { "BG", WinBuiltinGuestsSid }, - { "BO", WinBuiltinBackupOperatorsSid }, - { "BU", WinBuiltinUsersSid }, - { "CA", WinAccountCertAdminsSid, TRUE}, - { "CG", WinCreatorGroupSid }, - { "CO", WinCreatorOwnerSid }, - { "DA", WinAccountDomainAdminsSid, TRUE}, - { "DC", WinAccountComputersSid, TRUE}, - { "DD", WinAccountControllersSid, TRUE}, - { "DG", WinAccountDomainGuestsSid, TRUE}, - { "DU", WinAccountDomainUsersSid, TRUE}, - { "EA", WinAccountEnterpriseAdminsSid, TRUE}, - { "ED", WinEnterpriseControllersSid }, - { "IU", WinInteractiveSid }, - { "LA", WinAccountAdministratorSid }, - { "LG", WinAccountGuestSid }, - { "LS", WinLocalServiceSid }, - { "NO", WinBuiltinNetworkConfigurationOperatorsSid }, - { "NS", WinNetworkServiceSid }, - { "NU", WinNetworkSid }, - { "PA", WinAccountPolicyAdminsSid, TRUE}, - { "PO", WinBuiltinPrintOperatorsSid }, - { "PS", WinSelfSid }, - { "PU", WinBuiltinPowerUsersSid }, - { "RC", WinRestrictedCodeSid }, - { "RD", WinBuiltinRemoteDesktopUsersSid }, - { "RE", WinBuiltinReplicatorSid }, - { "RS", WinAccountRasAndIasServersSid, TRUE }, - { "RU", WinBuiltinPreWindows2000CompatibleAccessSid }, - { "SA", WinAccountSchemaAdminsSid, TRUE }, - { "SO", WinBuiltinSystemOperatorsSid }, - { "SU", WinServiceSid }, - { "SY", WinLocalSystemSid }, - { "WD", WinWorldSid }, + const char *name; + const char *sid; + unsigned int optional; + } + str_to_sid_tests[] = + { + { "WD", "S-1-1-0" }, + { "wD", "S-1-1-0" }, + { "CO", "S-1-3-0" }, + { "CG", "S-1-3-1" }, + { "OW", "S-1-3-4", 1 }, /* Vista+ */ + { "NU", "S-1-5-2" }, + { "IU", "S-1-5-4" }, + { "SU", "S-1-5-6" }, + { "AN", "S-1-5-7" }, + { "ED", "S-1-5-9" }, + { "PS", "S-1-5-10" }, + { "AU", "S-1-5-11" }, + { "RC", "S-1-5-12" }, + { "SY", "S-1-5-18" }, + { "LS", "S-1-5-19" }, + { "NS", "S-1-5-20" }, + { "LA", "S-1-5-21-*-*-*-500" }, + { "LG", "S-1-5-21-*-*-*-501" }, + { "BO", "S-1-5-32-551" }, + { "BA", "S-1-5-32-544" }, + { "BU", "S-1-5-32-545" }, + { "BG", "S-1-5-32-546" }, + { "PU", "S-1-5-32-547" }, + { "AO", "S-1-5-32-548" }, + { "SO", "S-1-5-32-549" }, + { "PO", "S-1-5-32-550" }, + { "RE", "S-1-5-32-552" }, + { "RU", "S-1-5-32-554" }, + { "RD", "S-1-5-32-555" }, + { "NO", "S-1-5-32-556" }, + { "AC", "S-1-15-2-1", 1 }, /* Win8+ */ + { "CA", "", 1 }, + { "DA", "", 1 }, + { "DC", "", 1 }, + { "DD", "", 1 }, + { "DG", "", 1 }, + { "DU", "", 1 }, + { "EA", "", 1 }, + { "PA", "", 1 }, + { "RS", "", 1 }, + { "SA", "", 1 }, +#ifdef __REACTOS__ + { "s-1-12-1", "S-1-12-1", 1 }, /* Crashes on ReactOS if not optional. ROSTESTS-418 */ + { "S-0x1-0XC-0x1a", "S-1-12-26", 1 }, /* Crashes on ReactOS if not optional. ROSTESTS-418 */ +#else + { "s-1-12-1", "S-1-12-1" }, + { "S-0x1-0XC-0x1a", "S-1-12-26" }, +#endif }; - SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY }; + const char noSubAuthStr[] = "S-1-5"; unsigned int i; - PSID psid, domain_sid; + PSID psid = NULL; SID *pisid; - BOOL r; - LPSTR str; + BOOL r, ret; + LPSTR str = NULL; - if( !pConvertStringSidToSidA ) - { - win_skip("ConvertSidToStringSidA or ConvertStringSidToSidA not available\n"); - return; - } - - r = pConvertStringSidToSidA( NULL, NULL ); + r = ConvertStringSidToSidA( NULL, NULL ); ok( !r, "expected failure with NULL parameters\n" ); if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED ) return; ok( GetLastError() == ERROR_INVALID_PARAMETER, - "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n", + "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n", GetLastError() ); - r = pConvertStringSidToSidA( refs[0].refStr, NULL ); + r = ConvertStringSidToSidA( refs[0].refStr, NULL ); ok( !r && GetLastError() == ERROR_INVALID_PARAMETER, - "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n", + "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n", GetLastError() ); - r = pConvertStringSidToSidA( NULL, &str ); + r = ConvertStringSidToSidA( NULL, &psid ); ok( !r && GetLastError() == ERROR_INVALID_PARAMETER, - "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n", + "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n", GetLastError() ); - r = pConvertStringSidToSidA( noSubAuthStr, &psid ); + r = ConvertStringSidToSidA( noSubAuthStr, &psid ); ok( !r, "expected failure with no sub authorities\n" ); ok( GetLastError() == ERROR_INVALID_SID, - "expected GetLastError() is ERROR_INVALID_SID, got %d\n", + "expected GetLastError() is ERROR_INVALID_SID, got %ld\n", GetLastError() ); - ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid), "ConvertStringSidToSidA failed\n"); + r = ConvertStringSidToSidA( "WDandmorecharacters", &psid ); + ok( !r, + "expected failure with too many characters\n" ); + ok( GetLastError() == ERROR_INVALID_SID, + "expected GetLastError() is ERROR_INVALID_SID, got %ld\n", + GetLastError() ); + + r = ConvertStringSidToSidA( "WD)", &psid ); + ok( !r, + "expected failure with too many characters\n" ); + ok( GetLastError() == ERROR_INVALID_SID, + "expected GetLastError() is ERROR_INVALID_SID, got %ld\n", + GetLastError() ); + + ok(ConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid), "ConvertStringSidToSidA failed\n"); pisid = psid; ok(pisid->SubAuthorityCount == 4, "Invalid sub authority count - expected 4, got %d\n", pisid->SubAuthorityCount); - ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expected 21, got %d\n", pisid->SubAuthority[0]); - ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expected 4576, got %d\n", pisid->SubAuthority[3]); + ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expected 21, got %ld\n", pisid->SubAuthority[0]); + ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expected 4576, got %ld\n", pisid->SubAuthority[3]); LocalFree(str); LocalFree(psid); - for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ ) + for( i = 0; i < ARRAY_SIZE(refs); i++ ) { r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0, &psid ); @@ -412,14 +383,14 @@ static void test_sid(void) if( psid ) FreeSid( psid ); - r = pConvertStringSidToSidA( refs[i].refStr, &psid ); + r = ConvertStringSidToSidA( refs[i].refStr, &psid ); ok( r, "failed to parse sid string\n" ); pisid = psid; ok( pisid && !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value, sizeof(refs[i].auth) ), "string sid %s didn't parse to expected value\n" - "(got 0x%04x%08x, expected 0x%04x%08x)\n", + "(got 0x%04x%08lx, expected 0x%04x%08lx)\n", refs[i].refStr, MAKEWORD( pisid->IdentifierAuthority.Value[1], pisid->IdentifierAuthority.Value[0] ), @@ -434,72 +405,31 @@ static void test_sid(void) LocalFree( psid ); } - /* string constant format not supported before XP */ - r = pConvertStringSidToSidA("AN", &psid); - if(!r) + for (i = 0; i < ARRAY_SIZE(str_to_sid_tests); i++) { - win_skip("String constant format not supported\n"); - return; - } - LocalFree(psid); + char *str; - AllocateAndInitializeSid(&domain_ident, 4, SECURITY_NT_NON_UNIQUE, 0, 0, 0, 0, 0, 0, 0, &domain_sid); - - for(i = 0; i < sizeof(strsid_table) / sizeof(strsid_table[0]); i++) - { - SetLastError(0xdeadbeef); - r = pConvertStringSidToSidA(strsid_table[i].str, &psid); - - if (!(strsid_table[i].optional)) + ret = ConvertStringSidToSidA(str_to_sid_tests[i].name, &psid); + if (!ret && str_to_sid_tests[i].optional) { - ok(r, "%s: got %u\n", strsid_table[i].str, GetLastError()); + skip("%u: failed to convert %s.\n", i, str_to_sid_tests[i].name); + continue; } + ok(ret, "%u: failed to convert string to sid.\n", i); - if (r) + if (str_to_sid_tests[i].optional || !strcmp(str_to_sid_tests[i].name, "LA") || + !strcmp(str_to_sid_tests[i].name, "LG")) { - char buf[SECURITY_MAX_SID_SIZE]; - char *sid_string, *well_known_sid_string; - DWORD n, size; - - /* zero out domain id before comparison to simplify things */ - if (strsid_table[i].sid_type == WinAccountAdministratorSid || - strsid_table[i].sid_type == WinAccountGuestSid) - { - for (n = 1; n <= 3; n++) - *GetSidSubAuthority(psid, n) = 0; - } - - r = ConvertSidToStringSidA(psid, &sid_string); - ok(r, "%s: ConvertSidToStringSid error %u\n", strsid_table[i].str, GetLastError()); - if (winetest_debug > 1) - trace("%s => %s\n", strsid_table[i].str, sid_string); - - size = sizeof(buf); - r = pCreateWellKnownSid(strsid_table[i].sid_type, domain_sid, buf, &size); - ok(r, "%u: CreateWellKnownSid(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError()); - - r = ConvertSidToStringSidA(buf, &well_known_sid_string); - ok(r, "%u: ConvertSidToStringSi(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError()); - if (winetest_debug > 1) - trace("%u => %s\n", strsid_table[i].sid_type, well_known_sid_string); - - ok(strcmp(sid_string, well_known_sid_string) == 0, - "%u: (%u) expected %s, got %s\n", i, strsid_table[i].sid_type, well_known_sid_string, sid_string); - - LocalFree(well_known_sid_string); - LocalFree(sid_string); LocalFree(psid); + continue; } - else - { - if (GetLastError() != ERROR_INVALID_SID) - trace(" %s: couldn't be converted, returned %d\n", strsid_table[i].str, GetLastError()); - else - trace(" %s: couldn't be converted\n", strsid_table[i].str); - } - } - LocalFree(domain_sid); + ret = ConvertSidToStringSidA(psid, &str); + ok(ret, "%u: failed to convert SID to string.\n", i); + ok(!strcmp(str, str_to_sid_tests[i].sid), "%u: unexpected sid %s.\n", i, str); + LocalFree(psid); + LocalFree(str); + } } static void test_trustee(void) @@ -699,17 +629,17 @@ static void test_allocateLuid(void) return; ok(ret, - "AllocateLocallyUniqueId failed: %d\n", GetLastError()); + "AllocateLocallyUniqueId failed: %ld\n", GetLastError()); ret = pAllocateLocallyUniqueId(&luid2); ok( ret, - "AllocateLocallyUniqueId failed: %d\n", GetLastError()); + "AllocateLocallyUniqueId failed: %ld\n", GetLastError()); ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0, "AllocateLocallyUniqueId returned a well-known LUID\n"); ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart, "AllocateLocallyUniqueId returned non-unique LUIDs\n"); ret = pAllocateLocallyUniqueId(NULL); ok( !ret && GetLastError() == ERROR_NOACCESS, - "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d\n", + "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n", GetLastError()); } @@ -735,18 +665,18 @@ static void test_lookupPrivilegeName(void) luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName); ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %d\n", + "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n", GetLastError()); ok(cchName == strlen("SeCreateTokenPrivilege") + 1, "LookupPrivilegeNameA returned an incorrect required length for\n" - "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName, + "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName, lstrlenA("SeCreateTokenPrivilege") + 1); /* check a known value and its returned length on success */ cchName = sizeof(buf); ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) && cchName == strlen("SeCreateTokenPrivilege"), "LookupPrivilegeNameA returned an incorrect output length for\n" - "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName, + "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName, (int)strlen("SeCreateTokenPrivilege")); /* check known values */ for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i <= SE_MAX_WELL_KNOWN_PRIVILEGE; i++) @@ -755,14 +685,14 @@ static void test_lookupPrivilegeName(void) cchName = sizeof(buf); ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName); ok( ret || GetLastError() == ERROR_NO_SUCH_PRIVILEGE, - "LookupPrivilegeNameA(0.%d) failed: %d\n", i, GetLastError()); + "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError()); } /* check a bogus LUID */ luid.LowPart = 0xdeadbeef; cchName = sizeof(buf); ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName); ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE, - "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n", + "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n", GetLastError()); /* check on a bogus system */ luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; @@ -770,7 +700,7 @@ static void test_lookupPrivilegeName(void) ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName); ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */, - "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n", + "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %ld\n", GetLastError()); } @@ -829,24 +759,24 @@ static void test_lookupPrivilegeValue(void) ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid); ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */, - "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n", + "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %ld\n", GetLastError()); /* check a NULL string */ ret = pLookupPrivilegeValueA(NULL, 0, &luid); ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE, - "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n", + "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n", GetLastError()); /* check a bogus privilege name */ ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid); ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE, - "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n", + "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n", GetLastError()); /* check case insensitive */ ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid); ok( ret, - "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %d\n", + "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n", GetLastError()); - for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++) + for (i = 0; i < ARRAY_SIZE(privs); i++) { /* Not all privileges are implemented on all Windows versions, so * don't worry if the call fails @@ -860,13 +790,6 @@ static void test_lookupPrivilegeValue(void) } } -static void test_luid(void) -{ - test_allocateLuid(); - test_lookupPrivilegeName(); - test_lookupPrivilegeValue(); -} - static void test_FileSecurity(void) { char wintmpdir [MAX_PATH]; @@ -882,16 +805,6 @@ static void test_FileSecurity(void) | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; - if (!pGetFileSecurityA) { - win_skip ("GetFileSecurity is not available\n"); - return; - } - - if (!pSetFileSecurityA) { - win_skip ("SetFileSecurity is not available\n"); - return; - } - if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) { win_skip ("GetTempPathA failed\n"); return; @@ -902,13 +815,13 @@ static void test_FileSecurity(void) SetLastError(0xdeadbeef); rc = CreateDirectoryA (path, NULL); ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA " - "failed for '%s' with %d\n", path, GetLastError()); + "failed for '%s' with %ld\n", path, GetLastError()); strcat (strcpy (file, path), "\\ess"); SetLastError(0xdeadbeef); fh = CreateFileA (file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); ok (fh != INVALID_HANDLE_VALUE, "CreateFileA " - "failed for '%s' with %d\n", file, GetLastError()); + "failed for '%s' with %ld\n", file, GetLastError()); CloseHandle (fh); /* For the temporary file ... */ @@ -916,7 +829,7 @@ static void test_FileSecurity(void) /* Get size needed */ retSize = 0; SetLastError(0xdeadbeef); - rc = pGetFileSecurityA (file, request, NULL, 0, &retSize); + rc = GetFileSecurityA (file, request, NULL, 0, &retSize); if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("GetFileSecurityA is not implemented\n"); goto cleanup; @@ -924,69 +837,67 @@ static void test_FileSecurity(void) ok (!rc, "GetFileSecurityA " "was expected to fail for '%s'\n", file); ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA " - "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); - ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize); + "returned %ld; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); + ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %ld\n", retSize); sdSize = retSize; - sd = HeapAlloc (GetProcessHeap (), 0, sdSize); + sd = malloc(sdSize); /* Get security descriptor for real */ retSize = -1; SetLastError(0xdeadbeef); - rc = pGetFileSecurityA (file, request, sd, sdSize, &retSize); + rc = GetFileSecurityA (file, request, sd, sdSize, &retSize); ok (rc, "GetFileSecurityA " - "was not expected to fail '%s': %d\n", file, GetLastError()); - ok (retSize == sdSize || - broken(retSize == 0), /* NT4 */ - "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize); + "was not expected to fail '%s': %ld\n", file, GetLastError()); + ok (retSize == sdSize, + "GetFileSecurityA returned size %ld; expected %ld\n", retSize, sdSize); /* Use it to set security descriptor */ SetLastError(0xdeadbeef); - rc = pSetFileSecurityA (file, request, sd); + rc = SetFileSecurityA (file, request, sd); ok (rc, "SetFileSecurityA " - "was not expected to fail '%s': %d\n", file, GetLastError()); + "was not expected to fail '%s': %ld\n", file, GetLastError()); - HeapFree (GetProcessHeap (), 0, sd); + free(sd); /* Repeat for the temporary directory ... */ /* Get size needed */ retSize = 0; SetLastError(0xdeadbeef); - rc = pGetFileSecurityA (path, request, NULL, 0, &retSize); + rc = GetFileSecurityA (path, request, NULL, 0, &retSize); ok (!rc, "GetFileSecurityA " "was expected to fail for '%s'\n", path); ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA " - "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); - ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize); + "returned %ld; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); + ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %ld\n", retSize); sdSize = retSize; - sd = HeapAlloc (GetProcessHeap (), 0, sdSize); + sd = malloc(sdSize); /* Get security descriptor for real */ retSize = -1; SetLastError(0xdeadbeef); - rc = pGetFileSecurityA (path, request, sd, sdSize, &retSize); + rc = GetFileSecurityA (path, request, sd, sdSize, &retSize); ok (rc, "GetFileSecurityA " - "was not expected to fail '%s': %d\n", path, GetLastError()); - ok (retSize == sdSize || - broken(retSize == 0), /* NT4 */ - "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize); + "was not expected to fail '%s': %ld\n", path, GetLastError()); + ok (retSize == sdSize, + "GetFileSecurityA returned size %ld; expected %ld\n", retSize, sdSize); /* Use it to set security descriptor */ SetLastError(0xdeadbeef); - rc = pSetFileSecurityA (path, request, sd); + rc = SetFileSecurityA (path, request, sd); ok (rc, "SetFileSecurityA " - "was not expected to fail '%s': %d\n", path, GetLastError()); - HeapFree (GetProcessHeap (), 0, sd); + "was not expected to fail '%s': %ld\n", path, GetLastError()); + free(sd); /* Old test */ strcpy (wintmpdir, "\\Should not exist"); SetLastError(0xdeadbeef); - rc = pGetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize); + rc = GetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize); ok (!rc, "GetFileSecurityA should fail for not existing directories/files\n"); ok (GetLastError() == ERROR_FILE_NOT_FOUND, - "last error ERROR_FILE_NOT_FOUND expected, got %d\n", GetLastError()); + "last error ERROR_FILE_NOT_FOUND expected, got %ld\n", GetLastError()); cleanup: /* Remove temporary file and directory */ @@ -996,233 +907,248 @@ cleanup: /* Test file access permissions for a file with FILE_ATTRIBUTE_ARCHIVE */ SetLastError(0xdeadbeef); rc = GetTempPathA(sizeof(wintmpdir), wintmpdir); - ok(rc, "GetTempPath error %d\n", GetLastError()); + ok(rc, "GetTempPath error %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = GetTempFileNameA(wintmpdir, "tmp", 0, file); - ok(rc, "GetTempFileName error %d\n", GetLastError()); + ok(rc, "GetTempFileName error %ld\n", GetLastError()); rc = GetFileAttributesA(file); rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); - ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#x\n", rc); + ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#lx\n", rc); rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &sdSize); ok(!rc, "GetFileSecurity should fail\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "expected ERROR_INSUFFICIENT_BUFFER got %d\n", GetLastError()); - ok(sdSize > sizeof(SECURITY_DESCRIPTOR), "got sd size %d\n", sdSize); + "expected ERROR_INSUFFICIENT_BUFFER got %ld\n", GetLastError()); + ok(sdSize > sizeof(SECURITY_DESCRIPTOR), "got sd size %ld\n", sdSize); - sd = HeapAlloc(GetProcessHeap (), 0, sdSize); + sd = malloc(sdSize); retSize = 0xdeadbeef; SetLastError(0xdeadbeef); rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, sdSize, &retSize); - ok(rc, "GetFileSecurity error %d\n", GetLastError()); - ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize); + ok(rc, "GetFileSecurity error %ld\n", GetLastError()); + ok(retSize == sdSize, "expected %ld, got %ld\n", sdSize, retSize); SetLastError(0xdeadbeef); rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); ok(!rc, "OpenThreadToken should fail\n"); - ok(GetLastError() == ERROR_NO_TOKEN, "expected ERROR_NO_TOKEN, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_NO_TOKEN, "expected ERROR_NO_TOKEN, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = ImpersonateSelf(SecurityIdentification); - ok(rc, "ImpersonateSelf error %d\n", GetLastError()); + ok(rc, "ImpersonateSelf error %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); - ok(rc, "OpenThreadToken error %d\n", GetLastError()); + ok(rc, "OpenThreadToken error %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = RevertToSelf(); - ok(rc, "RevertToSelf error %d\n", GetLastError()); + ok(rc, "RevertToSelf error %ld\n", GetLastError()); priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted); + ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted); + ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted); + ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == DELETE, "expected DELETE, got %#x\n", granted); + ok(granted == DELETE, "expected DELETE, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted); + ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted); + ok(granted == 0x1ff, "expected 0x1ff, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted); + ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", granted); SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, 0xffffffff, &mapping, &priv_set, &priv_set_len, &granted, &status); ok(!rc, "AccessCheck should fail\n"); - ok(GetLastError() == ERROR_GENERIC_NOT_MAPPED, "expected ERROR_GENERIC_NOT_MAPPED, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_GENERIC_NOT_MAPPED, "expected ERROR_GENERIC_NOT_MAPPED, got %ld\n", GetLastError()); /* Test file access permissions for a file with FILE_ATTRIBUTE_READONLY */ SetLastError(0xdeadbeef); fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); - ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); retSize = 0xdeadbeef; SetLastError(0xdeadbeef); rc = WriteFile(fh, "1", 1, &retSize, NULL); ok(!rc, "WriteFile should fail\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); - ok(retSize == 0, "expected 0, got %d\n", retSize); + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); + ok(retSize == 0, "expected 0, got %ld\n", retSize); CloseHandle(fh); rc = GetFileAttributesA(file); rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); -todo_wine + todo_wine ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY), - "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc); + "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#lx\n", rc); SetLastError(0xdeadbeef); rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE); - ok(rc, "SetFileAttributes error %d\n", GetLastError()); + ok(rc, "SetFileAttributes error %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = DeleteFileA(file); - ok(rc, "DeleteFile error %d\n", GetLastError()); + ok(rc, "DeleteFile error %ld\n", GetLastError()); SetLastError(0xdeadbeef); fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); - ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); retSize = 0xdeadbeef; SetLastError(0xdeadbeef); rc = WriteFile(fh, "1", 1, &retSize, NULL); ok(!rc, "WriteFile should fail\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); - ok(retSize == 0, "expected 0, got %d\n", retSize); + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); + ok(retSize == 0, "expected 0, got %ld\n", retSize); CloseHandle(fh); rc = GetFileAttributesA(file); rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY), - "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc); + "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#lx\n", rc); retSize = 0xdeadbeef; SetLastError(0xdeadbeef); rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, sdSize, &retSize); - ok(rc, "GetFileSecurity error %d\n", GetLastError()); - ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize); + ok(rc, "GetFileSecurity error %ld\n", GetLastError()); + ok(retSize == sdSize, "expected %ld, got %ld\n", sdSize, retSize); priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted); + ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); todo_wine { ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted); + ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#lx\n", granted); } granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted); + ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#lx\n", granted); granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); -todo_wine { + ok(rc, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == DELETE, "expected DELETE, got %#x\n", granted); -} + ok(granted == DELETE, "expected DELETE, got %#lx\n", granted); + + granted = 0xdeadbeef; + status = 0xdeadbeef; + SetLastError(0xdeadbeef); + rc = AccessCheck(sd, token, WRITE_OWNER, &mapping, &priv_set, &priv_set_len, &granted, &status); + ok(rc, "AccessCheck error %ld\n", GetLastError()); + ok(status == 1, "expected 1, got %d\n", status); + ok(granted == WRITE_OWNER, "expected WRITE_OWNER, got %#lx\n", granted); + + granted = 0xdeadbeef; + status = 0xdeadbeef; + SetLastError(0xdeadbeef); + rc = AccessCheck(sd, token, SYNCHRONIZE, &mapping, &priv_set, &priv_set_len, &granted, &status); + ok(rc, "AccessCheck error %ld\n", GetLastError()); + ok(status == 1, "expected 1, got %d\n", status); + ok(granted == SYNCHRONIZE, "expected SYNCHRONIZE, got %#lx\n", granted); + granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); todo_wine { ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted); + ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#lx\n", granted); } granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); todo_wine { ok(status == 1, "expected 1, got %d\n", status); - ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted); + ok(granted == 0x1ff, "expected 0x1ff, got %#lx\n", granted); } granted = 0xdeadbeef; status = 0xdeadbeef; SetLastError(0xdeadbeef); rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status); - ok(rc, "AccessCheck error %d\n", GetLastError()); + ok(rc, "AccessCheck error %ld\n", GetLastError()); todo_wine { ok(status == 1, "expected 1, got %d\n", status); - ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted); + ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", granted); } SetLastError(0xdeadbeef); rc = DeleteFileA(file); ok(!rc, "DeleteFile should fail\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE); - ok(rc, "SetFileAttributes error %d\n", GetLastError()); + ok(rc, "SetFileAttributes error %ld\n", GetLastError()); SetLastError(0xdeadbeef); rc = DeleteFileA(file); - ok(rc, "DeleteFile error %d\n", GetLastError()); + ok(rc, "DeleteFile error %ld\n", GetLastError()); CloseHandle(token); - HeapFree(GetProcessHeap(), 0, sd); + free(sd); } static void test_AccessCheck(void) @@ -1259,46 +1185,46 @@ static void test_AccessCheck(void) return; } - Acl = HeapAlloc(GetProcessHeap(), 0, 256); + Acl = malloc(256); res = InitializeAcl(Acl, 256, ACL_REVISION); if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { skip("ACLs not implemented - skipping tests\n"); - HeapFree(GetProcessHeap(), 0, Acl); + free(Acl); return; } - ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + ok(res, "InitializeAcl failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); - SecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); + SecurityDescriptor = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); - ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); + ok(res, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError()); res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); - ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]); - PrivSet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PrivSetLen); + PrivSet = calloc(1, PrivSetLen); PrivSet->PrivilegeCount = 16; res = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &ProcessToken); - ok(res, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(res, "OpenProcessToken failed with error %ld\n", GetLastError()); pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, FALSE, TRUE, &Enabled); res = DuplicateToken(ProcessToken, SecurityImpersonation, &Token); - ok(res, "DuplicateToken failed with error %d\n", GetLastError()); + ok(res, "DuplicateToken failed with error %ld\n", GetLastError()); /* SD without owner/group */ SetLastError(0xdeadbeef); @@ -1307,15 +1233,15 @@ static void test_AccessCheck(void) 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); + "failed with ERROR_INVALID_SECURITY_DESCR, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); /* Set owner and group */ res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE); - ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, TRUE); - ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); /* Generic access mask */ SetLastError(0xdeadbeef); @@ -1324,7 +1250,7 @@ static void test_AccessCheck(void) 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); + "with ERROR_GENERIC_NOT_MAPPED, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1335,7 +1261,7 @@ static void test_AccessCheck(void) NULL, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " - "with ERROR_NOACCESS, instead of %d\n", err); + "with ERROR_NOACCESS, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1346,7 +1272,7 @@ static void test_AccessCheck(void) PrivSet, NULL, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " - "with ERROR_NOACCESS, instead of %d\n", err); + "with ERROR_NOACCESS, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1357,19 +1283,19 @@ static void test_AccessCheck(void) NULL, NULL, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " - "with ERROR_NOACCESS, instead of %d\n", err); + "with ERROR_NOACCESS, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); /* sd with no dacl present */ Access = AccessStatus = 0x1abe11ed; ret = SetSecurityDescriptorDacl(SecurityDescriptor, FALSE, NULL, FALSE); - ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(ret, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); ok(AccessStatus && (Access == KEY_READ), - "AccessCheck failed to grant access with error %d\n", + "AccessCheck failed to grant access with error %ld\n", GetLastError()); /* sd with no dacl present - no privilegeset buffer */ @@ -1379,24 +1305,27 @@ static void test_AccessCheck(void) NULL, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " - "with ERROR_NOACCESS, instead of %d\n", err); + "with ERROR_NOACCESS, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); if(pNtAccessCheck) { + DWORD ntPrivSetLen = sizeof(PRIVILEGE_SET); + /* Generic access mask - no privilegeset buffer */ SetLastError(0xdeadbeef); Access = ntAccessStatus = 0x1abe11ed; ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, - NULL, &PrivSetLen, &Access, &ntAccessStatus); + NULL, &ntPrivSetLen, &Access, &ntAccessStatus); err = GetLastError(); ok(ntret == STATUS_ACCESS_VIOLATION, - "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret); + "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %lx\n", ntret); ok(err == 0xdeadbeef, - "NtAccessCheck shouldn't set last error, got %d\n", err); + "NtAccessCheck shouldn't set last error, got %ld\n", err); ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); + ok(ntPrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", ntPrivSetLen); /* Generic access mask - no returnlength */ SetLastError(0xdeadbeef); @@ -1405,9 +1334,9 @@ static void test_AccessCheck(void) PrivSet, NULL, &Access, &ntAccessStatus); err = GetLastError(); ok(ntret == STATUS_ACCESS_VIOLATION, - "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret); + "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %lx\n", ntret); ok(err == 0xdeadbeef, - "NtAccessCheck shouldn't set last error, got %d\n", err); + "NtAccessCheck shouldn't set last error, got %ld\n", err); ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1418,11 +1347,71 @@ static void test_AccessCheck(void) NULL, NULL, &Access, &ntAccessStatus); err = GetLastError(); ok(ntret == STATUS_ACCESS_VIOLATION, - "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret); + "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %lx\n", ntret); ok(err == 0xdeadbeef, - "NtAccessCheck shouldn't set last error, got %d\n", err); + "NtAccessCheck shouldn't set last error, got %ld\n", err); ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); + + /* Generic access mask - zero returnlength */ + SetLastError(0xdeadbeef); + Access = ntAccessStatus = 0x1abe11ed; + ntPrivSetLen = 0; + ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, + PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus); + err = GetLastError(); + ok(ntret == STATUS_GENERIC_NOT_MAPPED, + "NtAccessCheck should have failed with STATUS_GENERIC_NOT_MAPPED, got %lx\n", ntret); + ok(err == 0xdeadbeef, + "NtAccessCheck shouldn't set last error, got %ld\n", err); + ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, + "Access and/or AccessStatus were changed!\n"); + ok(ntPrivSetLen == 0, "PrivSetLen returns %ld\n", ntPrivSetLen); + + /* Generic access mask - insufficient returnlength */ + SetLastError(0xdeadbeef); + Access = ntAccessStatus = 0x1abe11ed; + ntPrivSetLen = sizeof(PRIVILEGE_SET)-1; + ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, + PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus); + err = GetLastError(); + ok(ntret == STATUS_GENERIC_NOT_MAPPED, + "NtAccessCheck should have failed with STATUS_GENERIC_NOT_MAPPED, got %lx\n", ntret); + ok(err == 0xdeadbeef, + "NtAccessCheck shouldn't set last error, got %ld\n", err); + ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, + "Access and/or AccessStatus were changed!\n"); + ok(ntPrivSetLen == sizeof(PRIVILEGE_SET)-1, "PrivSetLen returns %ld\n", ntPrivSetLen); + + /* Key access mask - zero returnlength */ + SetLastError(0xdeadbeef); + Access = ntAccessStatus = 0x1abe11ed; + ntPrivSetLen = 0; + ntret = pNtAccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, + PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus); + err = GetLastError(); + ok(ntret == STATUS_BUFFER_TOO_SMALL, + "NtAccessCheck should have failed with STATUS_BUFFER_TOO_SMALL, got %lx\n", ntret); + ok(err == 0xdeadbeef, + "NtAccessCheck shouldn't set last error, got %ld\n", err); + ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, + "Access and/or AccessStatus were changed!\n"); + ok(ntPrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", ntPrivSetLen); + + /* Key access mask - insufficient returnlength */ + SetLastError(0xdeadbeef); + Access = ntAccessStatus = 0x1abe11ed; + ntPrivSetLen = sizeof(PRIVILEGE_SET)-1; + ntret = pNtAccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, + PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus); + err = GetLastError(); + ok(ntret == STATUS_BUFFER_TOO_SMALL, + "NtAccessCheck should have failed with STATUS_BUFFER_TOO_SMALL, got %lx\n", ntret); + ok(err == 0xdeadbeef, + "NtAccessCheck shouldn't set last error, got %ld\n", err); + ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, + "Access and/or AccessStatus were changed!\n"); + ok(ntPrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", ntPrivSetLen); } else win_skip("NtAccessCheck unavailable. Skipping.\n"); @@ -1430,53 +1419,53 @@ static void test_AccessCheck(void) /* sd with NULL dacl */ Access = AccessStatus = 0x1abe11ed; ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, NULL, FALSE); - ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(ret, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); ok(AccessStatus && (Access == KEY_READ), - "AccessCheck failed to grant access with error %d\n", + "AccessCheck failed to grant access with error %ld\n", GetLastError()); ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); ok(AccessStatus && (Access == KEY_ALL_ACCESS), - "AccessCheck failed to grant access with error %d\n", + "AccessCheck failed to grant access with error %ld\n", GetLastError()); /* sd with blank dacl */ ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); - ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(ret, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); err = GetLastError(); ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed " - "with ERROR_ACCESS_DENIED, instead of %d\n", err); - ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access); + "with ERROR_ACCESS_DENIED, instead of %ld\n", err); + ok(!Access, "Should have failed to grant any access, got 0x%08lx\n", Access); res = AddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, EveryoneSid); - ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); res = AddAccessDeniedAce(Acl, ACL_REVISION, KEY_SET_VALUE, AdminSid); - ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError()); /* sd with dacl */ Access = AccessStatus = 0x1abe11ed; ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); ok(AccessStatus && (Access == KEY_READ), - "AccessCheck failed to grant access with error %d\n", + "AccessCheck failed to grant access with error %ld\n", GetLastError()); ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); ok(AccessStatus, - "AccessCheck failed to grant any access with error %d\n", + "AccessCheck failed to grant any access with error %ld\n", GetLastError()); - trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x\n", Access); + trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08lx\n", Access); /* Null PrivSet with null PrivSetLen pointer */ SetLastError(0xdeadbeef); @@ -1485,7 +1474,7 @@ static void test_AccessCheck(void) NULL, NULL, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " - "failed with ERROR_NOACCESS, instead of %d\n", err); + "failed with ERROR_NOACCESS, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1496,9 +1485,11 @@ static void test_AccessCheck(void) ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 0, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); + todo_wine ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " - "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err); + todo_wine + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1510,8 +1501,8 @@ static void test_AccessCheck(void) 0, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " - "failed with ERROR_NOACCESS, instead of %d\n", err); - ok(PrivSetLen == 1, "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_NOACCESS, instead of %ld\n", err); + ok(PrivSetLen == 1, "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1523,8 +1514,8 @@ static void test_AccessCheck(void) 0, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " - "failed with ERROR_NOACCESS, instead of %d\n", err); - ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_NOACCESS, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1536,8 +1527,8 @@ static void test_AccessCheck(void) 0, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " - "failed with ERROR_NOACCESS, instead of %d\n", err); - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_NOACCESS, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1549,8 +1540,8 @@ static void test_AccessCheck(void) PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " - "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1561,11 +1552,9 @@ static void test_AccessCheck(void) ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); -todo_wine ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " - "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); -todo_wine - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1573,17 +1562,16 @@ todo_wine SetLastError(0xdeadbeef); Access = AccessStatus = 0x1abe11ed; PrivSetLen = sizeof(PRIVILEGE_SET) - 1; + PrivSet->PrivilegeCount = 0xdeadbeef; ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); -todo_wine ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " - "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); -todo_wine - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); -todo_wine + "failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); + ok(PrivSet->PrivilegeCount == 0xdeadbeef, "buffer contents should not be changed\n"); /* Valid PrivSet with minimal sufficient PrivSetLen */ SetLastError(0xdeadbeef); @@ -1593,12 +1581,11 @@ todo_wine ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); -todo_wine - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(AccessStatus && (Access == KEY_READ), - "AccessCheck failed to grant access with error %d\n", GetLastError()); - ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n", + "AccessCheck failed to grant access with error %ld\n", GetLastError()); + ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %ld, expects 0\n", PrivSet->PrivilegeCount); /* Valid PrivSet with sufficient PrivSetLen */ @@ -1609,12 +1596,12 @@ todo_wine ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); -todo_wine - ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %d\n", PrivSetLen); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); + todo_wine + ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %ld\n", PrivSetLen); ok(AccessStatus && (Access == KEY_READ), - "AccessCheck failed to grant access with error %d\n", GetLastError()); - ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n", + "AccessCheck failed to grant access with error %ld\n", GetLastError()); + ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %ld, expects 0\n", PrivSet->PrivilegeCount); PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]); @@ -1626,7 +1613,7 @@ todo_wine 0, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " - "failed with ERROR_NOACCESS, instead of %d\n", err); + "failed with ERROR_NOACCESS, instead of %ld\n", err); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1635,22 +1622,22 @@ todo_wine Access = AccessStatus = 0x1abe11ed; ret = AccessCheck(SecurityDescriptor, Token, KEY_WRITE, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); err = GetLastError(); ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed " - "with ERROR_ACCESS_DENIED, instead of %d\n", err); - ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access); + "with ERROR_ACCESS_DENIED, instead of %ld\n", err); + ok(!Access, "Should have failed to grant any access, got 0x%08lx\n", Access); SetLastError(0xdeadbeef); PrivSet->PrivilegeCount = 16; ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); ok(ret && !AccessStatus && GetLastError() == ERROR_PRIVILEGE_NOT_HELD, - "AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %d\n", + "AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %ld\n", GetLastError()); ret = ImpersonateLoggedOnUser(Token); - ok(ret, "ImpersonateLoggedOnUser failed with error %d\n", GetLastError()); + ok(ret, "ImpersonateLoggedOnUser failed with error %ld\n", GetLastError()); ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled); if (!ret) { @@ -1662,8 +1649,8 @@ todo_wine PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " - "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); + "failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1674,12 +1661,9 @@ todo_wine ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " - "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); - todo_wine - ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); - todo_wine + "failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err); + ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen); ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, "Access and/or AccessStatus were changed!\n"); @@ -1691,12 +1675,12 @@ todo_wine ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); ok(ret && AccessStatus && GetLastError() == 0xdeadbeef, - "AccessCheck should have succeeded, error %d\n", + "AccessCheck should have succeeded, error %ld\n", GetLastError()); ok(Access == ACCESS_SYSTEM_SECURITY, - "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n", + "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08lx\n", Access); - ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n", + ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %ld, expects 1\n", PrivSet->PrivilegeCount); /* Valid PrivSet with large PrivSetLen */ @@ -1707,54 +1691,46 @@ todo_wine ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); ok(ret && AccessStatus && GetLastError() == 0xdeadbeef, - "AccessCheck should have succeeded, error %d\n", + "AccessCheck should have succeeded, error %ld\n", GetLastError()); ok(Access == ACCESS_SYSTEM_SECURITY, - "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n", + "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08lx\n", Access); - ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n", + ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %ld, expects 1\n", PrivSet->PrivilegeCount); } else trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n", ret); ret = RevertToSelf(); - ok(ret, "RevertToSelf failed with error %d\n", GetLastError()); + ok(ret, "RevertToSelf failed with error %ld\n", GetLastError()); /* test INHERIT_ONLY_ACE */ ret = InitializeAcl(Acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with error %d\n", GetLastError()); + ok(ret, "InitializeAcl failed with error %ld\n", GetLastError()); - /* NT doesn't have AddAccessAllowedAceEx. Skipping this call/test doesn't influence - * the next ones. - */ - if (pAddAccessAllowedAceEx) - { - ret = pAddAccessAllowedAceEx(Acl, ACL_REVISION, INHERIT_ONLY_ACE, KEY_READ, EveryoneSid); - ok(ret, "AddAccessAllowedAceEx failed with error %d\n", GetLastError()); - } - else - win_skip("AddAccessAllowedAceEx is not available\n"); + ret = AddAccessAllowedAceEx(Acl, ACL_REVISION, INHERIT_ONLY_ACE, KEY_READ, EveryoneSid); + ok(ret, "AddAccessAllowedAceEx failed with error %ld\n", GetLastError()); ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); - ok(ret, "AccessCheck failed with error %d\n", GetLastError()); + ok(ret, "AccessCheck failed with error %ld\n", GetLastError()); err = GetLastError(); ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed " - "with ERROR_ACCESS_DENIED, instead of %d\n", err); - ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access); + "with ERROR_ACCESS_DENIED, instead of %ld\n", err); + ok(!Access, "Should have failed to grant any access, got 0x%08lx\n", Access); CloseHandle(Token); res = DuplicateToken(ProcessToken, SecurityAnonymous, &Token); - ok(res, "DuplicateToken failed with error %d\n", GetLastError()); + ok(res, "DuplicateToken failed with error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping, PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_BAD_IMPERSONATION_LEVEL, "AccessCheck should have failed " - "with ERROR_BAD_IMPERSONATION_LEVEL, instead of %d\n", err); + "with ERROR_BAD_IMPERSONATION_LEVEL, instead of %ld\n", err); CloseHandle(Token); @@ -1763,7 +1739,7 @@ todo_wine PrivSet, &PrivSetLen, &Access, &AccessStatus); err = GetLastError(); ok(!ret && err == ERROR_NO_IMPERSONATION_TOKEN, "AccessCheck should have failed " - "with ERROR_NO_IMPERSONATION_TOKEN, instead of %d\n", err); + "with ERROR_NO_IMPERSONATION_TOKEN, instead of %ld\n", err); CloseHandle(ProcessToken); @@ -1773,9 +1749,63 @@ todo_wine FreeSid(AdminSid); if (UsersSid) FreeSid(UsersSid); - HeapFree(GetProcessHeap(), 0, Acl); - HeapFree(GetProcessHeap(), 0, SecurityDescriptor); - HeapFree(GetProcessHeap(), 0, PrivSet); + free(Acl); + free(SecurityDescriptor); + free(PrivSet); +} + +static TOKEN_USER *get_alloc_token_user( HANDLE token ) +{ + TOKEN_USER *token_user; + DWORD size; + BOOL ret; + + ret = GetTokenInformation( token, TokenUser, NULL, 0, &size ); + ok(!ret, "Expected failure, got %d\n", ret); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + + token_user = malloc( size ); + ret = GetTokenInformation( token, TokenUser, token_user, size, &size ); + ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError()); + + return token_user; +} + +static TOKEN_OWNER *get_alloc_token_owner( HANDLE token ) +{ + TOKEN_OWNER *token_owner; + DWORD size; + BOOL ret; + + ret = GetTokenInformation( token, TokenOwner, NULL, 0, &size ); + ok(!ret, "Expected failure, got %d\n", ret); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + + token_owner = malloc( size ); + ret = GetTokenInformation( token, TokenOwner, token_owner, size, &size ); + ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError()); + + return token_owner; +} + +static TOKEN_PRIMARY_GROUP *get_alloc_token_primary_group( HANDLE token ) +{ + TOKEN_PRIMARY_GROUP *token_primary_group; + DWORD size; + BOOL ret; + + ret = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size ); + ok(!ret, "Expected failure, got %d\n", ret); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + + token_primary_group = malloc( size ); + ret = GetTokenInformation( token, TokenPrimaryGroup, token_primary_group, size, &size ); + ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError()); + + return token_primary_group; } /* test GetTokenInformation for the various attributes */ @@ -1786,6 +1816,7 @@ static void test_token_attr(void) TOKEN_PRIVILEGES *Privileges; TOKEN_GROUPS *Groups; TOKEN_USER *User; + TOKEN_OWNER *Owner; TOKEN_DEFAULT_DACL *Dacl; BOOL ret; DWORD i, GLE; @@ -1801,56 +1832,56 @@ static void test_token_attr(void) win_skip("OpenProcessToken is not implemented\n"); return; } - ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); if (ret) { DWORD buf[256]; /* GetTokenInformation wants a dword-aligned buffer */ Size = sizeof(buf); ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size); - ok(ret, "GetTokenInformation failed with error %d\n", GetLastError()); + ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError()); Size = sizeof(ImpersonationLevel); ret = GetTokenInformation(Token, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size); GLE = GetLastError(); - ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GLE); + ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GLE); CloseHandle(Token); } SetLastError(0xdeadbeef); ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &Token); - ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); /* groups */ /* insufficient buffer length */ SetLastError(0xdeadbeef); Size2 = 0; ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size2); - ok(Size2 > 1, "got %d\n", Size2); + ok(Size2 > 1, "got %ld\n", Size2); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "%d with error %d\n", ret, GetLastError()); + "%d with error %ld\n", ret, GetLastError()); Size2 -= 1; - Groups = HeapAlloc(GetProcessHeap(), 0, Size2); + Groups = malloc(Size2); memset(Groups, 0xcc, Size2); Size = 0; ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size); - ok(Size > 1, "got %d\n", Size); + ok(Size > 1, "got %ld\n", Size); ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */, - "%d with error %d\n", ret, GetLastError()); + "%d with error %ld\n", ret, GetLastError()); if(!ret) ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n"); - HeapFree(GetProcessHeap(), 0, Groups); + free(Groups); SetLastError(0xdeadbeef); ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "GetTokenInformation(TokenGroups) %s with error %d\n", + "GetTokenInformation(TokenGroups) %s with error %ld\n", ret ? "succeeded" : "failed", GetLastError()); - Groups = HeapAlloc(GetProcessHeap(), 0, Size); + Groups = malloc(Size); SetLastError(0xdeadbeef); ret = GetTokenInformation(Token, TokenGroups, Groups, Size, &Size); - ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenGroups) failed with error %ld\n", GetLastError()); ok(GetLastError() == 0xdeadbeef, - "GetTokenInformation shouldn't have set last error to %d\n", + "GetTokenInformation shouldn't have set last error to %ld\n", GetLastError()); trace("TokenGroups:\n"); for (i = 0; i < Groups->GroupCount; i++) @@ -1866,26 +1897,40 @@ static void test_token_attr(void) if (ret) { ConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString); - trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes); + trace("%s, %s\\%s use: %d attr: 0x%08lx\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes); LocalFree(SidString); } - else trace("attr: 0x%08x LookupAccountSid failed with error %d\n", Groups->Groups[i].Attributes, GetLastError()); + else trace("attr: 0x%08lx LookupAccountSid failed with error %ld\n", Groups->Groups[i].Attributes, GetLastError()); } - HeapFree(GetProcessHeap(), 0, Groups); + free(Groups); /* user */ ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size); ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), - "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); - User = HeapAlloc(GetProcessHeap(), 0, Size); + "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); + User = malloc(Size); ret = GetTokenInformation(Token, TokenUser, User, Size, &Size); ok(ret, - "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); + "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); ConvertSidToStringSidA(User->User.Sid, &SidString); - trace("TokenUser: %s attr: 0x%08x\n", SidString, User->User.Attributes); + trace("TokenUser: %s attr: 0x%08lx\n", SidString, User->User.Attributes); LocalFree(SidString); - HeapFree(GetProcessHeap(), 0, User); + free(User); + + /* owner */ + ret = GetTokenInformation(Token, TokenOwner, NULL, 0, &Size); + ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), + "GetTokenInformation(TokenOwner) failed with error %ld\n", GetLastError()); + Owner = malloc(Size); + ret = GetTokenInformation(Token, TokenOwner, Owner, Size, &Size); + ok(ret, + "GetTokenInformation(TokenOwner) failed with error %ld\n", GetLastError()); + + ConvertSidToStringSidA(Owner->Owner, &SidString); + trace("TokenOwner: %s\n", SidString); + LocalFree(SidString); + free(Owner); /* logon */ ret = GetTokenInformation(Token, TokenLogonSid, NULL, 0, &Size); @@ -1894,14 +1939,14 @@ static void test_token_attr(void) else { ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), - "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError()); - Groups = HeapAlloc(GetProcessHeap(), 0, Size); + "GetTokenInformation(TokenLogonSid) failed with error %ld\n", GetLastError()); + Groups = malloc(Size); ret = GetTokenInformation(Token, TokenLogonSid, Groups, Size, &Size); ok(ret, - "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError()); + "GetTokenInformation(TokenLogonSid) failed with error %ld\n", GetLastError()); if (ret) { - ok(Groups->GroupCount == 1, "got %d\n", Groups->GroupCount); + ok(Groups->GroupCount == 1, "got %ld\n", Groups->GroupCount); if(Groups->GroupCount == 1) { ConvertSidToStringSidA(Groups->Groups[0].Sid, &SidString); @@ -1911,36 +1956,39 @@ static void test_token_attr(void) /* S-1-5-5-0-XXXXXX */ ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid); ok(ret, "Unknown SID\n"); + + ok(Groups->Groups[0].Attributes == (SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED | SE_GROUP_LOGON_ID), + "got %lx\n", Groups->Groups[0].Attributes); } } - HeapFree(GetProcessHeap(), 0, Groups); + free(Groups); } /* privileges */ ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size); ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), - "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError()); - Privileges = HeapAlloc(GetProcessHeap(), 0, Size); + "GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError()); + Privileges = malloc(Size); ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size); ok(ret, - "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError()); + "GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError()); trace("TokenPrivileges:\n"); for (i = 0; i < Privileges->PrivilegeCount; i++) { CHAR Name[256]; - DWORD NameLen = sizeof(Name)/sizeof(Name[0]); + DWORD NameLen = ARRAY_SIZE(Name); LookupPrivilegeNameA(NULL, &Privileges->Privileges[i].Luid, Name, &NameLen); - trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes); + trace("\t%s, 0x%lx\n", Name, Privileges->Privileges[i].Attributes); } - HeapFree(GetProcessHeap(), 0, Privileges); + free(Privileges); ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken); - ok(ret, "DuplicateToken failed with error %d\n", GetLastError()); + ok(ret, "DuplicateToken failed with error %ld\n", GetLastError()); Size = sizeof(ImpersonationLevel); ret = GetTokenInformation(ImpersonationToken, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size); - ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %ld\n", GetLastError()); ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel); CloseHandle(ImpersonationToken); @@ -1948,23 +1996,23 @@ static void test_token_attr(void) /* default dacl */ ret = GetTokenInformation(Token, TokenDefaultDacl, NULL, 0, &Size); ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), - "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError()); - Dacl = HeapAlloc(GetProcessHeap(), 0, Size); + Dacl = malloc(Size); ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size); - ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError()); SetLastError(0xdeadbeef); ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, 0); GLE = GetLastError(); ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); - ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %u\n", GLE); + ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %lu\n", GLE); SetLastError(0xdeadbeef); ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, Size); GLE = GetLastError(); ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); - ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %u\n", GLE); + ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %lu\n", GLE); acl = Dacl->DefaultDacl; Dacl->DefaultDacl = NULL; @@ -1975,22 +2023,22 @@ static void test_token_attr(void) Size2 = 0; Dacl->DefaultDacl = (ACL *)0xdeadbeef; ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2); - ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError()); ok(Dacl->DefaultDacl == NULL, "expected NULL, got %p\n", Dacl->DefaultDacl); ok(Size2 == sizeof(TOKEN_DEFAULT_DACL) || broken(Size2 == 2*sizeof(TOKEN_DEFAULT_DACL)), /* WoW64 */ - "got %u expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2); + "got %lu expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2); Dacl->DefaultDacl = acl; ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size); - ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError()); if (Size2 == sizeof(TOKEN_DEFAULT_DACL)) { ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2); - ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError()); } else win_skip("TOKEN_DEFAULT_DACL size too small on WoW64\n"); - HeapFree(GetProcessHeap(), 0, Dacl); + free(Dacl); CloseHandle(Token); } @@ -2001,7 +2049,7 @@ static void test_GetTokenInformation(void) BOOL ret; ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); - ok(ret, "OpenProcessToken failed: %u\n", GetLastError()); + ok(ret, "OpenProcessToken failed: %lu\n", GetLastError()); size = 0; is_app_container = 0xdeadbeef; @@ -2009,10 +2057,10 @@ static void test_GetTokenInformation(void) sizeof(is_app_container), &size); ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_FUNCTION), /* pre-win8 */ - "GetTokenInformation failed: %u\n", GetLastError()); + "GetTokenInformation failed: %lu\n", GetLastError()); if(ret) { - ok(size == sizeof(is_app_container), "size = %u\n", size); - ok(!is_app_container, "is_app_container = %x\n", is_app_container); + ok(size == sizeof(is_app_container), "size = %lu\n", size); + ok(!is_app_container, "is_app_container = %lx\n", is_app_container); } CloseHandle(token); @@ -2028,7 +2076,7 @@ static void test_sid_str(PSID * sid) { char *str_sid; BOOL ret = ConvertSidToStringSidA(sid, &str_sid); - ok(ret, "ConvertSidToStringSidA() failed: %d\n", GetLastError()); + ok(ret, "ConvertSidToStringSidA() failed: %ld\n", GetLastError()); if (ret) { char account[MAX_PATH], domain[MAX_PATH]; @@ -2037,7 +2085,7 @@ static void test_sid_str(PSID * sid) DWORD dom_size = MAX_PATH; ret = LookupAccountSidA (NULL, sid, account, &acc_size, domain, &dom_size, &use); ok(ret || GetLastError() == ERROR_NONE_MAPPED, - "LookupAccountSid(%s) failed: %d\n", str_sid, GetLastError()); + "LookupAccountSid(%s) failed: %ld\n", str_sid, GetLastError()); if (ret) trace(" %s %s\\%s %d\n", str_sid, domain, account, use); else if (GetLastError() == ERROR_NONE_MAPPED) @@ -2094,35 +2142,29 @@ static void test_CreateWellKnownSid(void) BOOL ret; unsigned int i; - if (!pCreateWellKnownSid) - { - win_skip("CreateWellKnownSid not available\n"); - return; - } - size = 0; SetLastError(0xdeadbeef); - ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size); + ret = CreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size); error = GetLastError(); ok(!ret, "CreateWellKnownSid succeeded\n"); - ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error); + ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", error); ok(size, "expected size > 0\n"); SetLastError(0xdeadbeef); - ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size); + ret = CreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size); error = GetLastError(); ok(!ret, "CreateWellKnownSid succeeded\n"); - ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); + ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error); - sid = HeapAlloc(GetProcessHeap(), 0, size); - ret = pCreateWellKnownSid(WinInteractiveSid, NULL, sid, &size); - ok(ret, "CreateWellKnownSid failed %u\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, sid); + sid = malloc(size); + ret = CreateWellKnownSid(WinInteractiveSid, NULL, sid, &size); + ok(ret, "CreateWellKnownSid failed %lu\n", GetLastError()); + free(sid); /* a domain sid usually have three subauthorities but we test that CreateWellKnownSid doesn't check it */ AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid); - for (i = 0; i < sizeof(well_known_sid_values)/sizeof(well_known_sid_values[0]); i++) + for (i = 0; i < ARRAY_SIZE(well_known_sid_values); i++) { const struct well_known_sid_value *value = &well_known_sid_values[i]; char sid_buffer[SECURITY_MAX_SID_SIZE]; @@ -2134,15 +2176,15 @@ static void test_CreateWellKnownSid(void) /* some SIDs aren't implemented by all Windows versions - detect it */ cb = sizeof(sid_buffer); - if (!pCreateWellKnownSid(i, NULL, sid_buffer, &cb)) + if (!CreateWellKnownSid(i, NULL, sid_buffer, &cb)) { skip("Well known SID %u not implemented\n", i); continue; } cb = sizeof(sid_buffer); - 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(CreateWellKnownSid(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, "%ld"); ok(IsValidSid(sid_buffer), "The sid is not valid\n"); ok(ConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n"); ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i, @@ -2153,8 +2195,8 @@ 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 %u with optional domain\n", i); - expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d"); + ok(CreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %u with optional domain\n", i); + expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%ld"); ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%u)\n", i); } } @@ -2169,6 +2211,7 @@ static void test_LookupAccountSid(void) DWORD acc_sizeA, dom_sizeA, user_sizeA; DWORD real_acc_sizeA, real_dom_sizeA; WCHAR accountW[MAX_PATH], domainW[MAX_PATH]; + LSA_OBJECT_ATTRIBUTES object_attributes; DWORD acc_sizeW, dom_sizeW; DWORD real_acc_sizeW, real_dom_sizeW; PSID pUsersSid = NULL; @@ -2180,13 +2223,15 @@ static void test_LookupAccountSid(void) int i; HANDLE hToken; PTOKEN_USER ptiUser = NULL; + LSA_HANDLE handle; + NTSTATUS status; /* native windows crashes if account size, domain size, or name use is NULL */ ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pUsersSid); ok(ret || (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), - "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); /* not running on NT so give up */ if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) @@ -2216,7 +2261,7 @@ static void test_LookupAccountSid(void) ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); + "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError()); /* try a 0 sized account buffer */ acc_sizeA = 0; @@ -2225,7 +2270,7 @@ static void test_LookupAccountSid(void) LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(acc_sizeA == real_acc_sizeA + 1, - "LookupAccountSidA() Expected acc_size = %u, got %u\n", + "LookupAccountSidA() Expected acc_size = %lu, got %lu\n", real_acc_sizeA + 1, acc_sizeA); /* try a 0 sized account buffer */ @@ -2234,7 +2279,7 @@ static void test_LookupAccountSid(void) LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(acc_sizeA == real_acc_sizeA + 1, - "LookupAccountSid() Expected acc_size = %u, got %u\n", + "LookupAccountSid() Expected acc_size = %lu, got %lu\n", real_acc_sizeA + 1, acc_sizeA); /* try a small domain buffer */ @@ -2244,7 +2289,7 @@ static void test_LookupAccountSid(void) ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); + "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError()); /* try a 0 sized domain buffer */ dom_sizeA = 0; @@ -2253,7 +2298,7 @@ static void test_LookupAccountSid(void) LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(dom_sizeA == real_dom_sizeA + 1, - "LookupAccountSidA() Expected dom_size = %u, got %u\n", + "LookupAccountSidA() Expected dom_size = %lu, got %lu\n", real_dom_sizeA + 1, dom_sizeA); /* try a 0 sized domain buffer */ @@ -2262,7 +2307,7 @@ static void test_LookupAccountSid(void) LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(dom_sizeA == real_dom_sizeA + 1, - "LookupAccountSidA() Expected dom_size = %u, got %u\n", + "LookupAccountSidA() Expected dom_size = %lu, got %lu\n", real_dom_sizeA + 1, dom_sizeA); real_acc_sizeW = MAX_PATH; @@ -2276,7 +2321,7 @@ static void test_LookupAccountSid(void) ret = LookupAccountSidA("deepthought", pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use); ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n"); ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */, - "LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %u\n", GetLastError()); + "LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %lu\n", GetLastError()); /* native windows crashes if domainW or accountW is NULL */ @@ -2287,7 +2332,7 @@ static void test_LookupAccountSid(void) ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); + "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError()); /* try a 0 sized account buffer */ acc_sizeW = 0; @@ -2296,7 +2341,7 @@ static void test_LookupAccountSid(void) LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(acc_sizeW == real_acc_sizeW + 1, - "LookupAccountSidW() Expected acc_size = %u, got %u\n", + "LookupAccountSidW() Expected acc_size = %lu, got %lu\n", real_acc_sizeW + 1, acc_sizeW); /* try a 0 sized account buffer */ @@ -2305,7 +2350,7 @@ static void test_LookupAccountSid(void) LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, domainW, &dom_sizeW, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(acc_sizeW == real_acc_sizeW + 1, - "LookupAccountSidW() Expected acc_size = %u, got %u\n", + "LookupAccountSidW() Expected acc_size = %lu, got %lu\n", real_acc_sizeW + 1, acc_sizeW); /* try a small domain buffer */ @@ -2315,7 +2360,7 @@ static void test_LookupAccountSid(void) ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); + "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError()); /* try a 0 sized domain buffer */ dom_sizeW = 0; @@ -2324,7 +2369,7 @@ static void test_LookupAccountSid(void) LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(dom_sizeW == real_dom_sizeW + 1, - "LookupAccountSidW() Expected dom_size = %u, got %u\n", + "LookupAccountSidW() Expected dom_size = %lu, got %lu\n", real_dom_sizeW + 1, dom_sizeW); /* try a 0 sized domain buffer */ @@ -2333,15 +2378,15 @@ static void test_LookupAccountSid(void) LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, NULL, &dom_sizeW, &use); /* this can fail or succeed depending on OS version but the size will always be returned */ ok(dom_sizeW == real_dom_sizeW + 1, - "LookupAccountSidW() Expected dom_size = %u, got %u\n", + "LookupAccountSidW() Expected dom_size = %lu, got %lu\n", real_dom_sizeW + 1, dom_sizeW); acc_sizeW = dom_sizeW = use = 0; SetLastError(0xdeadbeef); ret = LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, NULL, &dom_sizeW, &use); error = GetLastError(); - ok(!ret, "LookupAccountSidW failed %u\n", GetLastError()); - ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error); + ok(!ret, "LookupAccountSidW failed %lu\n", GetLastError()); + ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", error); ok(acc_sizeW, "expected non-zero account size\n"); ok(dom_sizeW, "expected non-zero domain size\n"); ok(!use, "expected zero use %u\n", use); @@ -2351,10 +2396,10 @@ static void test_LookupAccountSid(void) /* Test LookupAccountSid with Sid retrieved from token information. This assumes this process is running under the account of the current user.*/ ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hToken); - ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); ret = GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti); - ok(!ret, "GetTokenInformation failed with error %d\n", GetLastError()); - ptiUser = HeapAlloc(GetProcessHeap(), 0, cbti); + ok(!ret, "GetTokenInformation failed with error %ld\n", GetLastError()); + ptiUser = malloc(cbti); if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti)) { acc_sizeA = dom_sizeA = MAX_PATH; @@ -2365,108 +2410,93 @@ static void test_LookupAccountSid(void) ok(ret, "GetUserNameA() Expected TRUE, got FALSE\n"); ok(lstrcmpA(usernameA, accountA) == 0, "LookupAccountSidA() Expected account name: %s got: %s\n", usernameA, accountA ); } - HeapFree(GetProcessHeap(), 0, ptiUser); + free(ptiUser); - if (pCreateWellKnownSid) + trace("Well Known SIDs:\n"); + for (i = 0; i <= 60; i++) { - trace("Well Known SIDs:\n"); - for (i = 0; i <= 84; i++) + size = SECURITY_MAX_SID_SIZE; + if (CreateWellKnownSid(i, NULL, &max_sid.sid, &size)) { - size = SECURITY_MAX_SID_SIZE; - if (pCreateWellKnownSid(i, NULL, &max_sid.sid, &size)) + if (ConvertSidToStringSidA(&max_sid.sid, &str_sidA)) { - if (ConvertSidToStringSidA(&max_sid.sid, &str_sidA)) - { - acc_sizeA = MAX_PATH; - dom_sizeA = MAX_PATH; - if (LookupAccountSidA(NULL, &max_sid.sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use)) - trace(" %d: %s %s\\%s %d\n", i, str_sidA, domainA, accountA, use); - LocalFree(str_sidA); - } + acc_sizeA = MAX_PATH; + dom_sizeA = MAX_PATH; + if (LookupAccountSidA(NULL, &max_sid.sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use)) + trace(" %d: %s %s\\%s %d\n", i, str_sidA, domainA, accountA, use); + LocalFree(str_sidA); } + } + else + { + if (GetLastError() != ERROR_INVALID_PARAMETER) + trace(" CreateWellKnownSid(%d) failed: %ld\n", i, GetLastError()); else - { - if (GetLastError() != ERROR_INVALID_PARAMETER) - trace(" CreateWellKnownSid(%d) failed: %d\n", i, GetLastError()); - else - trace(" %d: not supported\n", i); - } + trace(" %d: not supported\n", i); } + } - pLsaQueryInformationPolicy = (void *)GetProcAddress( hmod, "LsaQueryInformationPolicy"); - pLsaOpenPolicy = (void *)GetProcAddress( hmod, "LsaOpenPolicy"); - pLsaFreeMemory = (void *)GetProcAddress( hmod, "LsaFreeMemory"); - pLsaClose = (void *)GetProcAddress( hmod, "LsaClose"); + ZeroMemory(&object_attributes, sizeof(object_attributes)); + object_attributes.Length = sizeof(object_attributes); - if (pLsaQueryInformationPolicy && pLsaOpenPolicy && pLsaFreeMemory && pLsaClose) + status = LsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle); + ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, + "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08lx\n", status); + + /* try a more restricted access mask if necessary */ + if (status == STATUS_ACCESS_DENIED) { + trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n"); + status = LsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION, &handle); + ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08lx\n", status); + } + + if (status == STATUS_SUCCESS) + { + PPOLICY_ACCOUNT_DOMAIN_INFO info; + status = LsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&info); + ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy() failed, returned 0x%08lx\n", status); + if (status == STATUS_SUCCESS) { - NTSTATUS status; - LSA_HANDLE handle; - LSA_OBJECT_ATTRIBUTES object_attributes; - - ZeroMemory(&object_attributes, sizeof(object_attributes)); - object_attributes.Length = sizeof(object_attributes); - - status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle); - ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, - "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status); - - /* try a more restricted access mask if necessary */ - if (status == STATUS_ACCESS_DENIED) { - trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n"); - status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION, &handle); - ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status); - } - - if (status == STATUS_SUCCESS) + ok(info->DomainSid!=0, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID\n"); + if (info->DomainSid) { - PPOLICY_ACCOUNT_DOMAIN_INFO info; - status = pLsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&info); - ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy() failed, returned 0x%08x\n", status); - if (status == STATUS_SUCCESS) - { - ok(info->DomainSid!=0, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID\n"); - if (info->DomainSid) - { - int count = *GetSidSubAuthorityCount(info->DomainSid); - CopySid(GetSidLengthRequired(count), &max_sid, info->DomainSid); - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_ADMIN; - max_sid.sid.SubAuthorityCount = count + 1; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_GUEST; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ADMINS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_USERS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_GUESTS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_COMPUTERS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CONTROLLERS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CERT_ADMINS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_SCHEMA_ADMINS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_POLICY_ADMINS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = DOMAIN_ALIAS_RID_RAS_SERVERS; - test_sid_str((PSID)&max_sid.sid); - max_sid.sid.SubAuthority[count] = 1000; /* first user account */ - test_sid_str((PSID)&max_sid.sid); - } - - pLsaFreeMemory((LPVOID)info); - } - - status = pLsaClose(handle); - ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); + int count = *GetSidSubAuthorityCount(info->DomainSid); + CopySid(GetSidLengthRequired(count), &max_sid, info->DomainSid); + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_ADMIN; + max_sid.sid.SubAuthorityCount = count + 1; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_GUEST; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ADMINS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_USERS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_GUESTS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_COMPUTERS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CONTROLLERS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CERT_ADMINS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_SCHEMA_ADMINS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_POLICY_ADMINS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = DOMAIN_ALIAS_RID_RAS_SERVERS; + test_sid_str((PSID)&max_sid.sid); + max_sid.sid.SubAuthority[count] = 1000; /* first user account */ + test_sid_str((PSID)&max_sid.sid); } + + LsaFreeMemory(info); } + + status = LsaClose(handle); + ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08lx\n", status); } } @@ -2504,8 +2534,8 @@ static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result) domain_size = 0; ret = LookupAccountNameA(NULL, name, NULL, &sid_size, NULL, &domain_size, &sid_use); ok(!ret, " %s Should have failed to lookup account name\n", name); - psid = HeapAlloc(GetProcessHeap(),0,sid_size); - domain = HeapAlloc(GetProcessHeap(),0,domain_size); + psid = malloc(sid_size); + domain = malloc(domain_size); ret = LookupAccountNameA(NULL, name, psid, &sid_size, domain, &domain_size, &sid_use); if (!result) @@ -2516,7 +2546,7 @@ static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result) AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid); cb = sizeof(wk_sid); - if (!pCreateWellKnownSid(result, domainsid, wk_sid, &cb)) + if (!CreateWellKnownSid(result, domainsid, wk_sid, &cb)) { win_skip("SID %i is not available on the system\n",result); goto cleanup; @@ -2534,8 +2564,10 @@ static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result) ok(ret, "Failed to lookup account name %s\n",name); ok(sid_size != 0, "sid_size was zero\n"); +#ifndef __REACTOS__ // This crashes on WS03, Vista, Win7, Win8.1, and Win10 1607. ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n", name, debugstr_sid(psid), debugstr_sid(wk_sid)); +#endif ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account); ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain); @@ -2543,8 +2575,8 @@ static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result) cleanup: FreeSid(domainsid); - HeapFree(GetProcessHeap(),0,psid); - HeapFree(GetProcessHeap(),0,domain); + free(psid); + free(domain); } static void test_LookupAccountName(void) @@ -2568,7 +2600,7 @@ static void test_LookupAccountName(void) user_size = UNLEN + 1; SetLastError(0xdeadbeef); ret = GetUserNameA(user_name, &user_size); - ok(ret, "Failed to get user name : %d\n", GetLastError()); + ok(ret, "Failed to get user name : %ld\n", GetLastError()); /* get sizes */ sid_size = 0; @@ -2583,7 +2615,7 @@ static void test_LookupAccountName(void) } ok(!ret, "Expected 0, got %d\n", ret); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); ok(sid_size != 0, "Expected non-zero sid size\n"); ok(domain_size != 0, "Expected non-zero domain size\n"); ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); @@ -2591,18 +2623,18 @@ static void test_LookupAccountName(void) sid_save = sid_size; domain_save = domain_size; - psid = HeapAlloc(GetProcessHeap(), 0, sid_size); - domain = HeapAlloc(GetProcessHeap(), 0, domain_size); + psid = malloc(sid_size); + domain = malloc(domain_size); /* try valid account name */ ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, domain, &domain_size, &sid_use); get_sid_info(psid, &account, &sid_dom); ok(ret, "Failed to lookup account name\n"); - ok(sid_size == GetLengthSid(psid), "Expected %d, got %d\n", GetLengthSid(psid), sid_size); + ok(sid_size == GetLengthSid(psid), "Expected %ld, got %ld\n", GetLengthSid(psid), sid_size); ok(!lstrcmpA(account, user_name), "Expected %s, got %s\n", user_name, account); ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain); - ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size); - ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size); + ok(domain_size == domain_save - 1, "Expected %ld, got %ld\n", domain_save - 1, domain_size); + ok(strlen(domain) == domain_size, "Expected %d, got %ld\n", lstrlenA(domain), domain_size); ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n", SidTypeUser, sid_use); domain_size = domain_save; sid_size = sid_save; @@ -2619,8 +2651,8 @@ static void test_LookupAccountName(void) ok(sid_size != 0, "sid_size was zero\n"); ok(!lstrcmpA(account, "Everyone"), "Expected Everyone, got %s\n", account); ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain); - ok(domain_size == 0, "Expected 0, got %d\n", domain_size); - ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size); + ok(domain_size == 0, "Expected 0, got %ld\n", domain_size); + ok(strlen(domain) == domain_size, "Expected %d, got %ld\n", lstrlenA(domain), domain_size); ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeWellKnownGroup (%d), got %d\n", SidTypeWellKnownGroup, sid_use); domain_size = domain_save; } @@ -2631,9 +2663,9 @@ static void test_LookupAccountName(void) ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use); ok(!ret, "Expected 0, got %d\n", ret); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size); - ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(sid_size == sid_save, "Expected %ld, got %ld\n", sid_save, sid_size); + ok(domain_size == domain_save, "Expected %ld, got %ld\n", domain_save, domain_size); /* try cchReferencedDomainName - 1 */ SetLastError(0xdeadbeef); @@ -2641,9 +2673,9 @@ static void test_LookupAccountName(void) ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use); ok(!ret, "Expected 0, got %d\n", ret); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size); - ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(sid_size == sid_save, "Expected %ld, got %ld\n", sid_save, sid_size); + ok(domain_size == domain_save, "Expected %ld, got %ld\n", domain_save, domain_size); /* NULL ReferencedDomainName with zero domain name size */ SetLastError(0xdeadbeef); @@ -2651,12 +2683,12 @@ static void test_LookupAccountName(void) ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, NULL, &domain_size, &sid_use); ok(!ret, "Expected 0, got %d\n", ret); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size); - ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(sid_size == sid_save, "Expected %ld, got %ld\n", sid_save, sid_size); + ok(domain_size == domain_save, "Expected %ld, got %ld\n", domain_save, domain_size); - HeapFree(GetProcessHeap(), 0, psid); - HeapFree(GetProcessHeap(), 0, domain); + free(psid); + free(domain); /* get sizes for NULL account name */ sid_size = 0; @@ -2664,32 +2696,27 @@ static void test_LookupAccountName(void) sid_use = 0xcafebabe; SetLastError(0xdeadbeef); ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size, &sid_use); - if (!ret && GetLastError() == ERROR_NONE_MAPPED) - win_skip("NULL account name doesn't work on NT4\n"); - else - { - ok(!ret, "Expected 0, got %d\n", ret); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(sid_size != 0, "Expected non-zero sid size\n"); - ok(domain_size != 0, "Expected non-zero domain size\n"); - ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); + ok(!ret, "Expected 0, got %d\n", ret); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(sid_size != 0, "Expected non-zero sid size\n"); + ok(domain_size != 0, "Expected non-zero domain size\n"); + ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); - psid = HeapAlloc(GetProcessHeap(), 0, sid_size); - domain = HeapAlloc(GetProcessHeap(), 0, domain_size); + psid = malloc(sid_size); + domain = malloc(domain_size); - /* try NULL account name */ - ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use); - get_sid_info(psid, &account, &sid_dom); - ok(ret, "Failed to lookup account name\n"); - /* Using a fixed string will not work on different locales */ - ok(!lstrcmpiA(account, domain), - "Got %s for account and %s for domain, these should be the same\n", account, domain); - ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n", SidTypeDomain, sid_use); + /* try NULL account name */ + ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use); + get_sid_info(psid, &account, &sid_dom); + ok(ret, "Failed to lookup account name\n"); + /* Using a fixed string will not work on different locales */ + ok(!lstrcmpiA(account, domain), + "Got %s for account and %s for domain, these should be the same\n", account, domain); + ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n", SidTypeDomain, sid_use); - HeapFree(GetProcessHeap(), 0, psid); - HeapFree(GetProcessHeap(), 0, domain); - } + free(psid); + free(domain); /* try an invalid account name */ SetLastError(0xdeadbeef); @@ -2699,9 +2726,9 @@ static void test_LookupAccountName(void) ok(!ret, "Expected 0, got %d\n", ret); ok(GetLastError() == ERROR_NONE_MAPPED || broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE), - "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError()); - ok(sid_size == 0, "Expected 0, got %d\n", sid_size); - ok(domain_size == 0, "Expected 0, got %d\n", domain_size); + "Expected ERROR_NONE_MAPPED, got %ld\n", GetLastError()); + ok(sid_size == 0, "Expected 0, got %ld\n", sid_size); + ok(domain_size == 0, "Expected 0, got %ld\n", domain_size); /* try an invalid system name */ SetLastError(0xdeadbeef); @@ -2710,9 +2737,9 @@ static void test_LookupAccountName(void) ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL, &domain_size, &sid_use); ok(!ret, "Expected 0, got %d\n", ret); ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */, - "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError()); - ok(sid_size == 0, "Expected 0, got %d\n", sid_size); - ok(domain_size == 0, "Expected 0, got %d\n", domain_size); + "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %ld\n", GetLastError()); + ok(sid_size == 0, "Expected 0, got %ld\n", sid_size); + ok(domain_size == 0, "Expected 0, got %ld\n", domain_size); /* try with the computer name as the account name */ domain_size = sizeof(computer_name); @@ -2724,26 +2751,20 @@ static void test_LookupAccountName(void) GetLastError() == ERROR_NONE_MAPPED /* in a domain */ || broken(GetLastError() == ERROR_TRUSTED_DOMAIN_FAILURE) || broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE)), - "LookupAccountNameA failed: %d\n", GetLastError()); + "LookupAccountNameA failed: %ld\n", GetLastError()); if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - psid = HeapAlloc(GetProcessHeap(), 0, sid_size); - domain = HeapAlloc(GetProcessHeap(), 0, domain_size); + psid = malloc(sid_size); + domain = malloc(domain_size); ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use); - ok(ret, "LookupAccountNameA failed: %d\n", GetLastError()); + ok(ret, "LookupAccountNameA failed: %ld\n", GetLastError()); ok(sid_use == SidTypeDomain || (sid_use == SidTypeUser && ! strcmp(computer_name, user_name)), "expected SidTypeDomain for %s, got %d\n", computer_name, sid_use); - HeapFree(GetProcessHeap(), 0, domain); - HeapFree(GetProcessHeap(), 0, psid); + free(domain); + free(psid); } /* Well Known names */ - if (!pCreateWellKnownSid) - { - win_skip("CreateWellKnownSid not available\n"); - return; - } - if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH) { skip("Non-English locale (skipping well known name creation tests)\n"); @@ -2804,7 +2825,7 @@ static void test_security_descriptor(void) SetLastError(0xdeadbeef); size = 5; expect_eq(MakeSelfRelativeSD(&sd, buf, &size), FALSE, BOOL, "%d"); - expect_eq(GetLastError(), ERROR_INSUFFICIENT_BUFFER, DWORD, "%u"); + expect_eq(GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER, DWORD, "%lu"); ok(size > 5, "Size not increased\n"); if (size <= 8192) { @@ -2825,44 +2846,44 @@ static void test_security_descriptor(void) expect_eq(isDefault, FALSE, BOOL, "%d"); } - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA( "O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)" "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" "(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, (void **)&sd_rel, NULL); - ok(ret, "got %u\n", GetLastError()); + ok(ret, "got %lu\n", GetLastError()); size = 0; ret = MakeSelfRelativeSD(sd_rel, NULL, &size); - todo_wine ok(!ret && GetLastError() == ERROR_BAD_DESCRIPTOR_FORMAT, "got %u\n", GetLastError()); + todo_wine ok(!ret && GetLastError() == ERROR_BAD_DESCRIPTOR_FORMAT, "got %lu\n", GetLastError()); /* convert to absolute form */ size = size_dacl = size_sacl = size_owner = size_group = 0; ret = MakeAbsoluteSD(sd_rel, NULL, &size, NULL, &size_dacl, NULL, &size_sacl, NULL, &size_owner, NULL, &size_group); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); - sd_abs = HeapAlloc(GetProcessHeap(), 0, size + size_dacl + size_sacl + size_owner + size_group); + sd_abs = malloc(size + size_dacl + size_sacl + size_owner + size_group); dacl = (PACL)(sd_abs + 1); sacl = (PACL)((char *)dacl + size_dacl); owner = (PSID)((char *)sacl + size_sacl); group = (PSID)((char *)owner + size_owner); ret = MakeAbsoluteSD(sd_rel, sd_abs, &size, dacl, &size_dacl, sacl, &size_sacl, owner, &size_owner, group, &size_group); - ok(ret, "got %u\n", GetLastError()); + ok(ret, "got %lu\n", GetLastError()); size = 0; ret = MakeSelfRelativeSD(sd_abs, NULL, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); - ok(size == 184, "got %u\n", size); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); + ok(size == 184, "got %lu\n", size); size += 4; - sd_rel2 = HeapAlloc(GetProcessHeap(), 0, size); + sd_rel2 = malloc(size); ret = MakeSelfRelativeSD(sd_abs, sd_rel2, &size); - ok(ret, "got %u\n", GetLastError()); - ok(size == 188, "got %u\n", size); + ok(ret, "got %lu\n", GetLastError()); + ok(size == 188, "got %lu\n", size); - HeapFree(GetProcessHeap(), 0, sd_abs); - HeapFree(GetProcessHeap(), 0, sd_rel2); + free(sd_abs); + free(sd_rel2); LocalFree(sd_rel); } @@ -2874,22 +2895,16 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access, OBJECT_BASIC_INFORMATION obj_info; NTSTATUS status; - if (!pNtQueryObject) - { - skip_(__FILE__, line)("Not NT platform - skipping tests\n"); - return; - } - - status = pNtQueryObject( handle, ObjectBasicInformation, &obj_info, - sizeof(obj_info), NULL ); - ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status); + status = NtQueryObject( handle, ObjectBasicInformation, &obj_info, + sizeof(obj_info), NULL ); + ok_(__FILE__, line)(!status, "NtQueryObject with err: %08lx\n", status); if (alt) ok_(__FILE__, line)(obj_info.GrantedAccess == access || - obj_info.GrantedAccess == alt, "Granted access should be 0x%08x " - "or 0x%08x, instead of 0x%08x\n", access, alt, obj_info.GrantedAccess); + obj_info.GrantedAccess == alt, "Granted access should be 0x%08lx " + "or 0x%08lx, instead of 0x%08lx\n", access, alt, obj_info.GrantedAccess); else ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should " - "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess); + "be 0x%08lx, instead of 0x%08lx\n", access, obj_info.GrantedAccess); } #define CHECK_SET_SECURITY(o,i,e) \ @@ -2900,10 +2915,10 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access, res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \ err = GetLastError(); \ if (e == ERROR_SUCCESS) \ - ok(res_, "SetKernelObjectSecurity failed with %d\n", err); \ + ok(res_, "SetKernelObjectSecurity failed with %ld\n", err); \ else \ ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \ - "with %s, instead of %d\n", #e, err); \ + "with %s, instead of %ld\n", #e, err); \ }while(0) static void test_process_security(void) @@ -2925,65 +2940,68 @@ static void test_process_security(void) PSID EveryoneSid = NULL; SID_NAME_USE use; - Acl = HeapAlloc(GetProcessHeap(), 0, 256); + Acl = malloc(256); res = InitializeAcl(Acl, 256, ACL_REVISION); if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("ACLs not implemented - skipping tests\n"); - HeapFree(GetProcessHeap(), 0, Acl); + free(Acl); return; } - ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + ok(res, "InitializeAcl failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); /* get owner from the token we might be running as a user not admin */ res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token ); - ok(res, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(res, "OpenProcessToken failed with error %ld\n", GetLastError()); if (!res) { - HeapFree(GetProcessHeap(), 0, Acl); + free(Acl); return; } res = GetTokenInformation( token, TokenOwner, NULL, 0, &size ); ok(!res, "Expected failure, got %d\n", res); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); - owner = HeapAlloc(GetProcessHeap(), 0, size); + owner = malloc(size); res = GetTokenInformation( token, TokenOwner, owner, size, &size ); - ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); + ok(res, "GetTokenInformation failed with error %ld\n", GetLastError()); AdminSid = owner->Owner; test_sid_str(AdminSid); res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size ); ok(!res, "Expected failure, got %d\n", res); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); - group = HeapAlloc(GetProcessHeap(), 0, size); + group = malloc(size); res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size ); - ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); + ok(res, "GetTokenInformation failed with error %ld\n", GetLastError()); UsersSid = group->PrimaryGroup; test_sid_str(UsersSid); acc_size = sizeof(account); dom_size = sizeof(domain); ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain, &dom_size, &use ); - ok(ret, "LookupAccountSid failed with %d\n", ret); + ok(ret, "LookupAccountSid failed with %ld\n", ret); ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use); - ok(!strcmp(account, "None"), "expect None, got %s\n", account); + if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH) + skip("Non-English locale (test with hardcoded 'None')\n"); + else + ok(!strcmp(account, "None"), "expect None, got %s\n", account); res = GetTokenInformation( token, TokenUser, NULL, 0, &size ); ok(!res, "Expected failure, got %d\n", res); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); - user = HeapAlloc(GetProcessHeap(), 0, size); + user = malloc(size); res = GetTokenInformation( token, TokenUser, user, size, &size ); - ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); + ok(res, "GetTokenInformation failed with error %ld\n", GetLastError()); UserSid = user->User.Sid; test_sid_str(UserSid); ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid don't match.\n"); @@ -2991,24 +3009,24 @@ static void test_process_security(void) CloseHandle( token ); if (!res) { - HeapFree(GetProcessHeap(), 0, group); - HeapFree(GetProcessHeap(), 0, owner); - HeapFree(GetProcessHeap(), 0, user); - HeapFree(GetProcessHeap(), 0, Acl); + free(group); + free(owner); + free(user); + free(Acl); return; } res = AddAccessDeniedAce(Acl, ACL_REVISION, PROCESS_VM_READ, AdminSid); - ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError()); res = AddAccessAllowedAce(Acl, ACL_REVISION, PROCESS_ALL_ACCESS, AdminSid); - ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); - SecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); + SecurityDescriptor = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); - ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); + ok(res, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError()); event = CreateEventA( NULL, TRUE, TRUE, "test_event" ); - ok(event != NULL, "CreateEvent %d\n", GetLastError()); + ok(event != NULL, "CreateEvent %ld\n", GetLastError()); SecurityDescriptor->Revision = 0; CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_UNKNOWN_REVISION ); @@ -3022,19 +3040,23 @@ static void test_process_security(void) SecurityDescriptor->Control |= SE_DACL_PRESENT; CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); +#ifdef __REACTOS__ + /* This crashes on Vista, Win7, and Win8.1. */ + if (GetNTVersion() < _WIN32_WINNT_VISTA || GetNTVersion() >= _WIN32_WINNT_WIN10) { +#endif /* Set owner and group and dacl */ res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE); - ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS ); test_owner_equal( event, AdminSid, __LINE__ ); res = SetSecurityDescriptorGroup(SecurityDescriptor, EveryoneSid, FALSE); - ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS ); test_group_equal( event, EveryoneSid, __LINE__ ); res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); - ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); /* setting a dacl should not change the owner or group */ test_owner_equal( event, AdminSid, __LINE__ ); @@ -3043,16 +3065,19 @@ static void test_process_security(void) /* Test again with a different SID in case the previous SID also happens to * be the one that is incorrectly replacing the group. */ res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE); - ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS ); test_group_equal( event, UsersSid, __LINE__ ); res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); - ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); test_group_equal( event, UsersSid, __LINE__ ); +#ifdef __REACTOS__ + } +#endif - sprintf(buffer, "%s tests/security.c test", myARGV[0]); + sprintf(buffer, "%s security test", myARGV[0]); memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); startup.dwFlags = STARTF_USESHOWWINDOW; @@ -3062,24 +3087,24 @@ static void test_process_security(void) psa.lpSecurityDescriptor = SecurityDescriptor; psa.bInheritHandle = TRUE; - ThreadSecurityDescriptor = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH ); + ThreadSecurityDescriptor = malloc( SECURITY_DESCRIPTOR_MIN_LENGTH ); res = InitializeSecurityDescriptor( ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); - ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); + ok(res, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError()); - ThreadAcl = HeapAlloc( GetProcessHeap(), 0, 256 ); + ThreadAcl = malloc( 256 ); res = InitializeAcl( ThreadAcl, 256, ACL_REVISION ); - ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + ok(res, "InitializeAcl failed with error %ld\n", GetLastError()); res = AddAccessDeniedAce( ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid ); - ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError() ); + ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError() ); res = AddAccessAllowedAce( ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid ); - ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); res = SetSecurityDescriptorOwner( ThreadSecurityDescriptor, AdminSid, FALSE ); - ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); res = SetSecurityDescriptorGroup( ThreadSecurityDescriptor, UsersSid, FALSE ); - ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); res = SetSecurityDescriptorDacl( ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE ); - ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); tsa.nLength = sizeof(tsa); tsa.lpSecurityDescriptor = ThreadSecurityDescriptor; @@ -3087,24 +3112,24 @@ static void test_process_security(void) /* Doesn't matter what ACL say we should get full access for ourselves */ res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info ); - ok(res, "CreateProcess with err:%d\n", GetLastError()); + ok(res, "CreateProcess with err:%ld\n", GetLastError()); TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); - winetest_wait_child_process( info.hProcess ); + wait_child_process( info.hProcess ); FreeSid(EveryoneSid); CloseHandle( info.hProcess ); CloseHandle( info.hThread ); CloseHandle( event ); - HeapFree(GetProcessHeap(), 0, group); - HeapFree(GetProcessHeap(), 0, owner); - HeapFree(GetProcessHeap(), 0, user); - HeapFree(GetProcessHeap(), 0, Acl); - HeapFree(GetProcessHeap(), 0, SecurityDescriptor); - HeapFree(GetProcessHeap(), 0, ThreadAcl); - HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor); + free(group); + free(owner); + free(user); + free(Acl); + free(SecurityDescriptor); + free(ThreadAcl); + free(ThreadSecurityDescriptor); } static void test_process_security_child(void) @@ -3114,12 +3139,12 @@ static void test_process_security_child(void) DWORD err; handle = OpenProcess( PROCESS_TERMINATE, FALSE, GetCurrentProcessId() ); - ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%d\n", GetLastError()); + ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%ld\n", GetLastError()); TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle1, 0, TRUE, DUPLICATE_SAME_ACCESS ); - ok(ret, "duplicating handle err:%d\n", GetLastError()); + ok(ret, "duplicating handle err:%ld\n", GetLastError()); TEST_GRANTED_ACCESS( handle1, PROCESS_TERMINATE ); CloseHandle( handle1 ); @@ -3128,21 +3153,27 @@ static void test_process_security_child(void) ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle1, PROCESS_ALL_ACCESS, TRUE, 0 ); err = GetLastError(); +#ifdef __REACTOS__ + ok((!ret && err == ERROR_ACCESS_DENIED) || broken(ret && err == 0xdeadbeef) /* Vista-Win10 1607 */, "duplicating handle should have failed " +#else ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed " - "with STATUS_ACCESS_DENIED, instead of err:%d\n", err); +#endif + "with STATUS_ACCESS_DENIED, instead of err:%ld\n", err); CloseHandle( handle ); +#ifndef __REACTOS__ // Incorrect for WS03-Win10 1607 /* These two should fail - they are denied by ACL */ handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() ); ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n"); handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() ); ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n"); +#endif /* Documented privilege elevation */ ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &handle, 0, TRUE, DUPLICATE_SAME_ACCESS ); - ok(ret, "duplicating handle err:%d\n", GetLastError()); + ok(ret, "duplicating handle err:%ld\n", GetLastError()); TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); @@ -3151,24 +3182,26 @@ static void test_process_security_child(void) /* Same only explicitly asking for all access rights */ ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &handle, PROCESS_ALL_ACCESS, TRUE, 0 ); - ok(ret, "duplicating handle err:%d\n", GetLastError()); + ok(ret, "duplicating handle err:%ld\n", GetLastError()); TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4, PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION ); ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle1, PROCESS_VM_READ, TRUE, 0 ); - ok(ret, "duplicating handle err:%d\n", GetLastError()); + ok(ret, "duplicating handle err:%ld\n", GetLastError()); TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ ); CloseHandle( handle1 ); CloseHandle( handle ); /* Test thread security */ handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() ); - ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError()); - TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); + ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%ld\n", GetLastError()); + TEST_GRANTED_ACCESS( handle, THREAD_TERMINATE ); CloseHandle( handle ); +#ifndef __REACTOS__ // Incorrect for WS03-Win10 1607 handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); +#endif } static void test_impersonation_level(void) @@ -3184,10 +3217,6 @@ static void test_impersonation_level(void) HKEY hkey; DWORD error; - if( !pDuplicateTokenEx ) { - win_skip("DuplicateTokenEx is not available\n"); - return; - } SetLastError(0xdeadbeef); ret = ImpersonateSelf(SecurityAnonymous); if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) @@ -3195,91 +3224,91 @@ static void test_impersonation_level(void) win_skip("ImpersonateSelf is not implemented\n"); return; } - ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %d\n", GetLastError()); + ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %ld\n", GetLastError()); ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token); ok(!ret, "OpenThreadToken should have failed\n"); error = GetLastError(); - ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %d\n", error); + ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %ld\n", error); /* can't perform access check when opening object against an anonymous impersonation token */ todo_wine { error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey); ok(error == ERROR_INVALID_HANDLE || error == ERROR_CANT_OPEN_ANONYMOUS || error == ERROR_BAD_IMPERSONATION_LEVEL, - "RegOpenKeyEx failed with %d\n", error); + "RegOpenKeyEx failed with %ld\n", error); } RevertToSelf(); ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken); - ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); - ret = pDuplicateTokenEx(ProcessToken, + ret = DuplicateTokenEx(ProcessToken, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, NULL, SecurityAnonymous, TokenImpersonation, &Token); - ok(ret, "DuplicateTokenEx failed with error %d\n", GetLastError()); + ok(ret, "DuplicateTokenEx failed with error %ld\n", GetLastError()); /* can't increase the impersonation level */ ret = DuplicateToken(Token, SecurityIdentification, &Token2); error = GetLastError(); ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, - "Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error); + "Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %ld\n", error); /* we can query anything from an anonymous token, including the user */ ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size); error = GetLastError(); - ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error); - User = HeapAlloc(GetProcessHeap(), 0, Size); + ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", error); + User = malloc(Size); ret = GetTokenInformation(Token, TokenUser, User, Size, &Size); - ok(ret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, User); + ok(ret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); + free(User); /* PrivilegeCheck fails with SecurityAnonymous level */ ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size); error = GetLastError(); - ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error); - Privileges = HeapAlloc(GetProcessHeap(), 0, Size); + ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", error); + Privileges = malloc(Size); ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size); - ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError()); - PrivilegeSet = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount])); + PrivilegeSet = malloc(FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount])); PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount; memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0])); PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY; - HeapFree(GetProcessHeap(), 0, Privileges); + free(Privileges); ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted); error = GetLastError(); - ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error); + ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %ld\n", error); CloseHandle(Token); ret = ImpersonateSelf(SecurityIdentification); - ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %d\n", GetLastError()); + ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %ld\n", GetLastError()); ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token); - ok(ret, "OpenThreadToken failed with error %d\n", GetLastError()); + ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError()); /* can't perform access check when opening object against an identification impersonation token */ error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey); todo_wine { - ok(error == ERROR_INVALID_HANDLE || error == ERROR_BAD_IMPERSONATION_LEVEL, - "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE or ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error); + ok(error == ERROR_INVALID_HANDLE || error == ERROR_BAD_IMPERSONATION_LEVEL || error == ERROR_ACCESS_DENIED, + "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE, ERROR_BAD_IMPERSONATION_LEVEL or ERROR_ACCESS_DENIED instead of %ld\n", error); } ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted); - ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %d\n", GetLastError()); + ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %ld\n", GetLastError()); CloseHandle(Token); RevertToSelf(); ret = ImpersonateSelf(SecurityImpersonation); - ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %d\n", GetLastError()); + ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %ld\n", GetLastError()); ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token); - ok(ret, "OpenThreadToken failed with error %d\n", GetLastError()); + ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError()); error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey); - ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %d\n", error); + ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %ld\n", error); RegCloseKey(hkey); ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted); - ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %d\n", GetLastError()); + ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %ld\n", GetLastError()); RevertToSelf(); CloseHandle(Token); CloseHandle(ProcessToken); - HeapFree(GetProcessHeap(), 0, PrivilegeSet); + free(PrivilegeSet); } static void test_SetEntriesInAclW(void) @@ -3293,44 +3322,31 @@ static void test_SetEntriesInAclW(void) static const WCHAR wszEveryone[] = {'E','v','e','r','y','o','n','e',0}; static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'}; - if (!pSetEntriesInAclW) - { - win_skip("SetEntriesInAclW is not available\n"); - return; - } - NewAcl = (PACL)0xdeadbeef; - res = pSetEntriesInAclW(0, NULL, NULL, &NewAcl); - if(res == ERROR_CALL_NOT_IMPLEMENTED) - { - win_skip("SetEntriesInAclW is not implemented\n"); - return; - } - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); - ok(NewAcl == NULL || - broken(NewAcl != NULL), /* NT4 */ - "NewAcl=%p, expected NULL\n", NewAcl); + res = SetEntriesInAclW(0, NULL, NULL, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); + ok(NewAcl == NULL, "NewAcl=%p, expected NULL\n", NewAcl); LocalFree(NewAcl); - OldAcl = HeapAlloc(GetProcessHeap(), 0, 256); + OldAcl = malloc(256); res = InitializeAcl(OldAcl, 256, ACL_REVISION); if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("ACLs not implemented - skipping tests\n"); - HeapFree(GetProcessHeap(), 0, OldAcl); + free(OldAcl); return; } - ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + ok(res, "InitializeAcl failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid); - ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); ExplicitAccess.grfAccessPermissions = KEY_WRITE; ExplicitAccess.grfAccessMode = GRANT_ACCESS; @@ -3340,16 +3356,16 @@ static void test_SetEntriesInAclW(void) ExplicitAccess.Trustee.ptstrName = EveryoneSid; ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF; ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; ExplicitAccess.Trustee.pMultipleTrustee = NULL; ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); @@ -3361,56 +3377,52 @@ static void test_SetEntriesInAclW(void) { ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ExplicitAccess.Trustee.ptstrName = (LPWSTR)wszEveryone; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_INVALID_PARAMETER || - broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ - "SetEntriesInAclW failed: %u\n", res); - ok(NewAcl == NULL || - broken(NewAcl != NULL), /* NT4 */ + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_INVALID_PARAMETER, + "SetEntriesInAclW failed: %lu\n", res); + ok(NewAcl == NULL, "returned acl wasn't NULL: %p\n", NewAcl); ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_INVALID_PARAMETER || - broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ - "SetEntriesInAclW failed: %u\n", res); - ok(NewAcl == NULL || - broken(NewAcl != NULL), /* NT4 */ + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_INVALID_PARAMETER, + "SetEntriesInAclW failed: %lu\n", res); + ok(NewAcl == NULL, "returned acl wasn't NULL: %p\n", NewAcl); ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ExplicitAccess.grfAccessMode = SET_ACCESS; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); } ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ExplicitAccess.Trustee.ptstrName = (LPWSTR)wszCurrentUser; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); ExplicitAccess.grfAccessMode = REVOKE_ACCESS; ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; ExplicitAccess.Trustee.ptstrName = UsersSid; - res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); FreeSid(UsersSid); FreeSid(EveryoneSid); - HeapFree(GetProcessHeap(), 0, OldAcl); + free(OldAcl); } static void test_SetEntriesInAclA(void) @@ -3424,44 +3436,37 @@ static void test_SetEntriesInAclA(void) static const CHAR szEveryone[] = {'E','v','e','r','y','o','n','e',0}; static const CHAR szCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'}; - if (!pSetEntriesInAclA) - { - win_skip("SetEntriesInAclA is not available\n"); - return; - } - NewAcl = (PACL)0xdeadbeef; - res = pSetEntriesInAclA(0, NULL, NULL, &NewAcl); + res = SetEntriesInAclA(0, NULL, NULL, &NewAcl); if(res == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("SetEntriesInAclA is not implemented\n"); return; } - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); - ok(NewAcl == NULL || - broken(NewAcl != NULL), /* NT4 */ + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); + ok(NewAcl == NULL, "NewAcl=%p, expected NULL\n", NewAcl); LocalFree(NewAcl); - OldAcl = HeapAlloc(GetProcessHeap(), 0, 256); + OldAcl = malloc(256); res = InitializeAcl(OldAcl, 256, ACL_REVISION); if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("ACLs not implemented - skipping tests\n"); - HeapFree(GetProcessHeap(), 0, OldAcl); + free(OldAcl); return; } - ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + ok(res, "InitializeAcl failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid); - ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); ExplicitAccess.grfAccessPermissions = KEY_WRITE; ExplicitAccess.grfAccessMode = GRANT_ACCESS; @@ -3471,16 +3476,16 @@ static void test_SetEntriesInAclA(void) ExplicitAccess.Trustee.ptstrName = EveryoneSid; ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ExplicitAccess.Trustee.pMultipleTrustee = NULL; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; ExplicitAccess.Trustee.pMultipleTrustee = NULL; ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); @@ -3492,56 +3497,52 @@ static void test_SetEntriesInAclA(void) { ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ExplicitAccess.Trustee.ptstrName = (LPSTR)szEveryone; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_INVALID_PARAMETER || - broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ - "SetEntriesInAclA failed: %u\n", res); - ok(NewAcl == NULL || - broken(NewAcl != NULL), /* NT4 */ + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_INVALID_PARAMETER, + "SetEntriesInAclA failed: %lu\n", res); + ok(NewAcl == NULL, "returned acl wasn't NULL: %p\n", NewAcl); ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_INVALID_PARAMETER || - broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ - "SetEntriesInAclA failed: %u\n", res); - ok(NewAcl == NULL || - broken(NewAcl != NULL), /* NT4 */ + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_INVALID_PARAMETER, + "SetEntriesInAclA failed: %lu\n", res); + ok(NewAcl == NULL, "returned acl wasn't NULL: %p\n", NewAcl); ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ExplicitAccess.grfAccessMode = SET_ACCESS; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); } ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ExplicitAccess.Trustee.ptstrName = (LPSTR)szCurrentUser; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); ExplicitAccess.grfAccessMode = REVOKE_ACCESS; ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; ExplicitAccess.Trustee.ptstrName = UsersSid; - res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); + res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res); ok(NewAcl != NULL, "returned acl was NULL\n"); LocalFree(NewAcl); FreeSid(UsersSid); FreeSid(EveryoneSid); - HeapFree(GetProcessHeap(), 0, OldAcl); + free(OldAcl); } /* helper function for test_CreateDirectoryA */ @@ -3552,15 +3553,15 @@ static void get_nt_pathW(const char *name, UNICODE_STRING *nameW) NTSTATUS status; BOOLEAN ret; - pRtlInitAnsiString(&str, name); + RtlInitAnsiString(&str, name); - status = pRtlAnsiStringToUnicodeString(&strW, &str, TRUE); - ok(!status, "RtlAnsiStringToUnicodeString failed with %08x\n", status); + status = RtlAnsiStringToUnicodeString(&strW, &str, TRUE); + ok(!status, "RtlAnsiStringToUnicodeString failed with %08lx\n", status); ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL); ok(ret, "RtlDosPathNameToNtPathName_U failed\n"); - pRtlFreeUnicodeString(&strW); + RtlFreeUnicodeString(&strW); } static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask, @@ -3570,17 +3571,17 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD ACCESS_ALLOWED_ACE *ace; BOOL bret; - bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation); + bret = GetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok_(__FILE__, line)(bret, "GetAclInformation failed\n"); todo_wine_if (todo_count) ok_(__FILE__, line)(acl_size.AceCount == 2, - "GetAclInformation returned unexpected entry count (%d != 2)\n", + "GetAclInformation returned unexpected entry count (%ld != 2)\n", acl_size.AceCount); if (acl_size.AceCount > 0) { - bret = pGetAce(dacl, 0, (VOID **)&ace); + bret = GetAce(dacl, 0, (VOID **)&ace); ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n"); bret = EqualSid(&ace->SidStart, user_sid); @@ -3589,16 +3590,16 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD todo_wine_if (todo_flags) ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags, - "Current User ACE has unexpected flags (0x%x != 0x%x)\n", + "Current User ACE has unexpected flags (0x%x != 0x%lx)\n", ((ACE_HEADER *)ace)->AceFlags, flags); ok_(__FILE__, line)(ace->Mask == mask, - "Current User ACE has unexpected mask (0x%x != 0x%x)\n", + "Current User ACE has unexpected mask (0x%lx != 0x%lx)\n", ace->Mask, mask); } if (acl_size.AceCount > 1) { - bret = pGetAce(dacl, 1, (VOID **)&ace); + bret = GetAce(dacl, 1, (VOID **)&ace); ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n"); bret = EqualSid(&ace->SidStart, admin_sid); @@ -3607,11 +3608,11 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD todo_wine_if (todo_flags) ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags, - "Administators Group ACE has unexpected flags (0x%x != 0x%x)\n", + "Administators Group ACE has unexpected flags (0x%x != 0x%lx)\n", ((ACE_HEADER *)ace)->AceFlags, flags); ok_(__FILE__, line)(ace->Mask == mask, - "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n", + "Administators Group ACE has unexpected mask (0x%lx != 0x%lx)\n", ace->Mask, mask); } } @@ -3637,12 +3638,6 @@ static void test_CreateDirectoryA(void) DWORD error; PACL pDacl; - if (!pGetSecurityInfo || !pGetNamedSecurityInfoA || !pCreateWellKnownSid) - { - win_skip("Required functions are not available\n"); - return; - } - if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) { if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE; @@ -3655,10 +3650,10 @@ static void test_CreateDirectoryA(void) } bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size); ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), - "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); - user = HeapAlloc(GetProcessHeap(), 0, user_size); + "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); + user = malloc(user_size); bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size); - ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); + ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); CloseHandle( token ); user_sid = ((TOKEN_USER *)user)->User.Sid; @@ -3666,15 +3661,15 @@ static void test_CreateDirectoryA(void) sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = TRUE; InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); - pDacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100); + CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); + pDacl = calloc(1, 100); bret = InitializeAcl(pDacl, 100, ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, - GENERIC_ALL, user_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, + GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, - GENERIC_ALL, admin_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, + GENERIC_ALL, admin_sid); ok(bret, "Failed to add Administrator Group to ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); ok(bret, "Failed to add ACL to security descriptor.\n"); @@ -3682,21 +3677,26 @@ static void test_CreateDirectoryA(void) GetTempPathA(MAX_PATH, tmpdir); lstrcatA(tmpdir, "Please Remove Me"); bret = CreateDirectoryA(tmpdir, &sa); - ok(bret == TRUE, "CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError()); - HeapFree(GetProcessHeap(), 0, pDacl); + ok(bret == TRUE, "CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError()); + free(pDacl); +#ifdef __REACTOS__ + /* The rest of this test crashes on WS03, Vista, Win7, and Win8.1. */ + if (GetNTVersion() < _WIN32_WINNT_WIN10) + goto done; +#endif SetLastError(0xdeadbeef); - error = pGetNamedSecurityInfoA(tmpdir, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner, - NULL, &pDacl, NULL, &pSD); + error = GetNamedSecurityInfoA(tmpdir, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner, + NULL, &pDacl, NULL, &pSD); if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("GetNamedSecurityInfoA is not implemented\n"); goto done; } - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, - 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); + 0x1f01ff, FALSE, TRUE, FALSE, __LINE__); LocalFree(pSD); /* Test inheritance of ACLs in CreateFile without security descriptor */ @@ -3705,14 +3705,14 @@ static void test_CreateDirectoryA(void) hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); - ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError()); + ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError()); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + (PSID *)&owner, NULL, &pDacl, NULL, &pSD); ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE, - 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); + 0x1f01ff, TRUE, TRUE, TRUE, __LINE__); LocalFree(pSD); CloseHandle(hTemp); @@ -3720,7 +3720,7 @@ static void test_CreateDirectoryA(void) * When a security descriptor is set, then inheritance doesn't take effect */ pSD = &sd; InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); + pDacl = malloc(sizeof(ACL)); bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); ok(bret, "Failed to initialize ACL\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); @@ -3734,28 +3734,33 @@ static void test_CreateDirectoryA(void) sa.bInheritHandle = TRUE; hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); - ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, pDacl); + ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError()); + free(pDacl); - error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + error = GetSecurityInfo(hTemp, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + (PSID *)&owner, NULL, &pDacl, NULL, &pSD); + ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", + todo_wine + ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n", acl_size.AceCount); LocalFree(pSD); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); - ok(bret, "GetAclInformation failed\n"); - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", - acl_size.AceCount); - LocalFree(pSD); + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + (PSID *)&owner, NULL, &pDacl, NULL, &pSD); + todo_wine + ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error); + if (error == ERROR_SUCCESS) + { + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); + todo_wine + ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n", + acl_size.AceCount); + LocalFree(pSD); + } CloseHandle(hTemp); /* Test inheritance of ACLs in NtCreateFile without security descriptor */ @@ -3770,17 +3775,17 @@ static void test_CreateDirectoryA(void) attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0, - FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0); - ok(!status, "NtCreateFile failed with %08x\n", status); - pRtlFreeUnicodeString(&tmpfileW); + status = NtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0, + FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0); + ok(!status, "NtCreateFile failed with %08lx\n", status); + RtlFreeUnicodeString(&tmpfileW); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + (PSID *)&owner, NULL, &pDacl, NULL, &pSD); ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE, - 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); + 0x1f01ff, TRUE, TRUE, TRUE, __LINE__); LocalFree(pSD); CloseHandle(hTemp); @@ -3788,7 +3793,7 @@ static void test_CreateDirectoryA(void) * When a security descriptor is set, then inheritance doesn't take effect */ pSD = &sd; InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); + pDacl = malloc(sizeof(ACL)); bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); ok(bret, "Failed to initialize ACL\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); @@ -3805,182 +3810,40 @@ static void test_CreateDirectoryA(void) attr.SecurityDescriptor = pSD; attr.SecurityQualityOfService = NULL; - status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0, - FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0); - ok(!status, "NtCreateFile failed with %08x\n", status); - pRtlFreeUnicodeString(&tmpfileW); - HeapFree(GetProcessHeap(), 0, pDacl); - - error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); - ok(bret, "GetAclInformation failed\n"); - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", - acl_size.AceCount); - LocalFree(pSD); - - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); - ok(bret, "GetAclInformation failed\n"); - todo_wine - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", - acl_size.AceCount); - LocalFree(pSD); - CloseHandle(hTemp); - - /* Test inheritance of ACLs in CreateDirectory without security descriptor */ - strcpy(tmpfile, tmpdir); - lstrcatA(tmpfile, "/tmpdir"); - bret = CreateDirectoryA(tmpfile, NULL); - ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError()); - - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); - test_inherited_dacl(pDacl, admin_sid, user_sid, - OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE, - 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); - LocalFree(pSD); - bret = RemoveDirectoryA(tmpfile); - ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError()); - - /* Test inheritance of ACLs in CreateDirectory with security descriptor */ - pSD = &sd; - InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); - bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); - ok(bret, "Failed to initialize ACL\n"); - bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); - ok(bret, "Failed to add ACL to security desciptor\n"); - - strcpy(tmpfile, tmpdir); - lstrcatA(tmpfile, "/tmpdir1"); - - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = TRUE; - bret = CreateDirectoryA(tmpfile, &sa); - ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, pDacl); - - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); - ok(bret, "GetAclInformation failed\n"); - todo_wine - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", - acl_size.AceCount); - LocalFree(pSD); - - SetLastError(0xdeadbeef); - bret = RemoveDirectoryA(tmpfile); - error = GetLastError(); - ok(bret == FALSE, "RemoveDirectoryA unexpected succeeded\n"); - ok(error == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %u\n", error); - - pSD = &sd; - InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pDacl = HeapAlloc(GetProcessHeap(), 0, 100); - bret = InitializeAcl(pDacl, 100, ACL_REVISION); - ok(bret, "Failed to initialize ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); - ok(bret, "Failed to add Current User to ACL.\n"); - bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); - ok(bret, "Failed to add ACL to security desciptor.\n"); - error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, - NULL, pDacl, NULL); - ok(error == ERROR_SUCCESS, "SetNamedSecurityInfoA failed with error %u\n", error); - HeapFree(GetProcessHeap(), 0, pDacl); - - bret = RemoveDirectoryA(tmpfile); - ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError()); - - /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) without security descriptor */ - strcpy(tmpfile, tmpdir); - lstrcatA(tmpfile, "/tmpdir"); - get_nt_pathW(tmpfile, &tmpfileW); - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &tmpfileW; - attr.Attributes = OBJ_CASE_INSENSITIVE; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - - status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0); - ok(!status, "NtCreateFile failed with %08x\n", status); + status = NtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0, + FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0); + ok(!status, "NtCreateFile failed with %08lx\n", status); RtlFreeUnicodeString(&tmpfileW); + free(pDacl); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); - test_inherited_dacl(pDacl, admin_sid, user_sid, - OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE, - 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); - LocalFree(pSD); - CloseHandle(hTemp); - - /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) with security descriptor */ - pSD = &sd; - InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); - bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); - ok(bret, "Failed to initialize ACL\n"); - bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); - ok(bret, "Failed to add ACL to security desciptor\n"); - - strcpy(tmpfile, tmpdir); - lstrcatA(tmpfile, "/tmpdir2"); - get_nt_pathW(tmpfile, &tmpfileW); - - attr.Length = sizeof(attr); - attr.RootDirectory = 0; - attr.ObjectName = &tmpfileW; - attr.Attributes = OBJ_CASE_INSENSITIVE; - attr.SecurityDescriptor = pSD; - attr.SecurityQualityOfService = NULL; - - status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0); - ok(!status, "NtCreateFile failed with %08x\n", status); - RtlFreeUnicodeString(&tmpfileW); - HeapFree(GetProcessHeap(), 0, pDacl); - - error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + error = GetSecurityInfo(hTemp, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + (PSID *)&owner, NULL, &pDacl, NULL, &pSD); + ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); todo_wine - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", + ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n", acl_size.AceCount); LocalFree(pSD); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - (PSID *)&owner, NULL, &pDacl, NULL, &pSD); - ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); - ok(bret, "GetAclInformation failed\n"); + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + (PSID *)&owner, NULL, &pDacl, NULL, &pSD); todo_wine - ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", - acl_size.AceCount); - LocalFree(pSD); + ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error); + if (error == ERROR_SUCCESS) + { + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); + todo_wine + ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n", + acl_size.AceCount); + LocalFree(pSD); + } CloseHandle(hTemp); done: - HeapFree(GetProcessHeap(), 0, user); + free(user); bret = RemoveDirectoryA(tmpdir); ok(bret == TRUE, "RemoveDirectoryA should always succeed\n"); } @@ -4003,7 +3866,7 @@ static void test_GetNamedSecurityInfoA(void) CHAR windows_dir[MAX_PATH]; PSECURITY_DESCRIPTOR pSD; ACCESS_ALLOWED_ACE *ace; - BOOL bret = TRUE, isNT4; + BOOL bret = TRUE; char tmpfile[MAX_PATH]; DWORD error, revision; BOOL owner_defaulted; @@ -4016,12 +3879,6 @@ static void test_GetNamedSecurityInfoA(void) BYTE flags; NTSTATUS status; - if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid) - { - win_skip("Required functions are not available\n"); - return; - } - if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) { if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE; @@ -4034,87 +3891,85 @@ static void test_GetNamedSecurityInfoA(void) } bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size); ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), - "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); - user = HeapAlloc(GetProcessHeap(), 0, user_size); + "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); + user = malloc(user_size); bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size); - ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); + ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); CloseHandle( token ); user_sid = ((TOKEN_USER *)user)->User.Sid; bret = GetWindowsDirectoryA(windows_dir, MAX_PATH); - ok(bret, "GetWindowsDirectory failed with error %d\n", GetLastError()); + ok(bret, "GetWindowsDirectory failed with error %ld\n", GetLastError()); +#ifdef __REACTOS__ + /* The rest of this test crashes on WS03, Vista, Win7, and Win8.1 */ + if (GetNTVersion() < _WIN32_WINNT_WIN10) { + free(user); + return; + } +#endif SetLastError(0xdeadbeef); - error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT, + error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("GetNamedSecurityInfoA is not implemented\n"); - HeapFree(GetProcessHeap(), 0, user); + free(user); return; } - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); bret = GetSecurityDescriptorControl(pSD, &control, &revision); - ok(bret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); - ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT) || - broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */ + ok(bret, "GetSecurityDescriptorControl failed with error %ld\n", GetLastError()); + ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT), "control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control); - ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %d instead of 1\n", revision); - - isNT4 = (control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT; + ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %ld instead of 1\n", revision); bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); - ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); ok(owner != NULL, "owner should not be NULL\n"); bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); - ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); ok(group != NULL, "group should not be NULL\n"); LocalFree(pSD); /* NULL descriptor tests */ - if(isNT4) - { - win_skip("NT4 does not support GetNamedSecutityInfo with a NULL descriptor\n"); - HeapFree(GetProcessHeap(), 0, user); - return; - } - error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, + error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, NULL); - ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error); + ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %ld\n", error); pDacl = NULL; - error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, + error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD); - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); ok(pDacl != NULL, "DACL should not be NULL\n"); LocalFree(pSD); - error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION, + error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, NULL); - ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error); + ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %ld\n", error); /* Test behavior of SetNamedSecurityInfo with an invalid path */ SetLastError(0xdeadbeef); - error = pSetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, - NULL, NULL, NULL); - ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%x\n", error); + error = SetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, + NULL, NULL, NULL); + ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%lx\n", error); ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n"); /* Create security descriptor information and test that it comes back the same */ pSD = &sd; - pDacl = HeapAlloc(GetProcessHeap(), 0, 100); + pDacl = malloc(100); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); + CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); bret = InitializeAcl(pDacl, 100, ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); ok(bret, "Failed to add Administrator Group to ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); ok(bret, "Failed to add ACL to security descriptor.\n"); @@ -4122,192 +3977,193 @@ static void test_GetNamedSecurityInfoA(void) hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); SetLastError(0xdeadbeef); - error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, - NULL, pDacl, NULL); - HeapFree(GetProcessHeap(), 0, pDacl); + error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, + NULL, pDacl, NULL); + free(pDacl); if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("SetNamedSecurityInfoA is not implemented\n"); - HeapFree(GetProcessHeap(), 0, user); + free(user); CloseHandle(hTemp); return; } - ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); + ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error); SetLastError(0xdeadbeef); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD); if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("GetNamedSecurityInfoA is not implemented\n"); - HeapFree(GetProcessHeap(), 0, user); + free(user); CloseHandle(hTemp); return; } - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); if (acl_size.AceCount > 0) { - bret = pGetAce(pDacl, 0, (VOID **)&ace); + bret = GetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); - ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", - debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); + todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", + debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, - "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%lx != 0x1f01ff)\n", + ace->Mask); } if (acl_size.AceCount > 1) { - bret = pGetAce(pDacl, 1, (VOID **)&ace); + bret = GetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); - ok(bret || broken(!bret) /* win2k */, "Administators Group ACE (%s) != Administators Group SID (%s).\n", - debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); + todo_wine ok(bret || broken(!bret) /* win2k */, + "Administators Group ACE (%s) != Administators Group SID (%s).\n", + debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, - "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + "Administators Group ACE has unexpected mask (0x%lx != 0x1f01ff)\n", ace->Mask); } LocalFree(pSD); /* show that setting empty DACL is not removing all file permissions */ - pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); + pDacl = malloc(sizeof(ACL)); bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); - error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL); - ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); - HeapFree(GetProcessHeap(), 0, pDacl); + ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error); + free(pDacl); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD); - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); if (acl_size.AceCount > 0) { - bret = pGetAce(pDacl, 0, (VOID **)&ace); + bret = GetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get ACE.\n"); - ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE, - "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags); + todo_wine ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE, + "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags); } LocalFree(pSD); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); CloseHandle(h); /* test setting NULL DACL */ - error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL); - ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); + ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error); - error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD); - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); todo_wine ok(!pDacl, "pDacl != NULL\n"); LocalFree(pSD); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); CloseHandle(h); /* NtSetSecurityObject doesn't inherit DACL entries */ pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pDacl = HeapAlloc(GetProcessHeap(), 0, 100); + pDacl = malloc(100); bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); ok(bret, "Failed to add ACL to security descriptor.\n"); - status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); - ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); + status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); + ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); CloseHandle(h); - pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ); - status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); - ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); + SetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ); + status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); + ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); CloseHandle(h); - pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED, + SetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED); - status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); - ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); + status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); + ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); CloseHandle(h); /* test if DACL is properly mapped to permission */ bret = InitializeAcl(pDacl, 100, ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); - bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + bret = AddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); ok(bret, "Failed to add ACL to security descriptor.\n"); - status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); - ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); + status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); + ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); CloseHandle(h); bret = InitializeAcl(pDacl, 100, ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); - bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + bret = AddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); ok(bret, "Failed to add ACL to security descriptor.\n"); - status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); - ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); + status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); + ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status); h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, pDacl); - HeapFree(GetProcessHeap(), 0, user); + ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); + free(pDacl); + free(user); CloseHandle(hTemp); /* Test querying the ownership of a built-in registry key */ sid_size = sizeof(system_ptr); - pCreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size); - error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, + CreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size); + error = GetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); bret = AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &localsys_sid); - ok(bret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(bret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); - ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); ok(owner != NULL, "owner should not be NULL\n"); ok(EqualSid(owner, admin_sid) || EqualSid(owner, localsys_sid), "MACHINE\\Software owner SID (%s) != Administrators SID (%s) or Local System Sid (%s).\n", debugstr_sid(owner), debugstr_sid(admin_sid), debugstr_sid(localsys_sid)); bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); - ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); ok(group != NULL, "group should not be NULL\n"); ok(EqualSid(group, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */ || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */, @@ -4317,21 +4173,21 @@ static void test_GetNamedSecurityInfoA(void) /* Test querying the DACL of a built-in registry key */ sid_size = sizeof(users_ptr); - pCreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size); - error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, + CreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size); + error = GetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); - ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error); bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); - ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); ok(dacl_present, "DACL should be present\n"); ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); for (i=0; iSidStart, users_sid); if (bret) users_ace_id = i; @@ -4342,7 +4198,7 @@ static void test_GetNamedSecurityInfoA(void) "Builtin Users ACE not found.\n"); if (users_ace_id != -1) { - bret = pGetAce(pDacl, users_ace_id, (VOID **)&ace); + bret = GetAce(pDacl, users_ace_id, (VOID **)&ace); ok(bret, "Failed to get Builtin Users ACE.\n"); flags = ((ACE_HEADER *)ace)->AceFlags; ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE) @@ -4353,13 +4209,13 @@ static void test_GetNamedSecurityInfoA(void) INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); ok(ace->Mask == GENERIC_READ || broken(ace->Mask == KEY_READ), /* win 10 */ - "Builtin Users ACE has unexpected mask (0x%x != 0x%x)\n", + "Builtin Users ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, GENERIC_READ); } ok(admins_ace_id != -1, "Builtin Admins ACE not found.\n"); if (admins_ace_id != -1) { - bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); + bret = GetAce(pDacl, admins_ace_id, (VOID **)&ace); ok(bret, "Failed to get Builtin Admins ACE.\n"); flags = ((ACE_HEADER *)ace)->AceFlags; ok(flags == 0x0 @@ -4370,7 +4226,7 @@ static void test_GetNamedSecurityInfoA(void) || broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */ "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */, - "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS); + "Builtin Admins ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS); } FreeSid(localsys_sid); @@ -4392,6 +4248,7 @@ static void test_ConvertStringSecurityDescriptor(void) BOOL ret; DWORD GLE; DWORD altGLE; + DWORD ace_Mask; } cssd[] = { { "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE, ERROR_UNKNOWN_REVISION }, @@ -4412,96 +4269,111 @@ static void test_ConvertStringSecurityDescriptor(void) { "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE }, { "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE }, /* test ACE string access rights */ - { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE }, - { "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE }, - { "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE }, + { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_ALL }, + { "D:(A;;1;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, 1 }, + { "D:(A;;020000000000;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_READ }, + { "D:(A;;0X40000000;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_WRITE }, + { "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE }, + { "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, READ_CONTROL | DELETE | WRITE_DAC | WRITE_OWNER }, { "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE }, { "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE }, { "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE }, { "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, { "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, + { "S:(AU;;0xDeAdBeEf;;;WD)", SDDL_REVISION_1, TRUE }, + { "S:(AU;;GR0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, + { "S:(AU;;0xFFFFFFFFGR;;;WD)", SDDL_REVISION_1, TRUE }, + { "S:(AU;;0xFFFFFGR;;;WD)", SDDL_REVISION_1, TRUE }, /* test ACE string access right error case */ { "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL }, /* test behaviour with empty strings */ { "", SDDL_REVISION_1, TRUE }, /* test ACE string SID */ { "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE }, - { "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID } /* W2K */ + { "D:(D;;GA;;;WDANDSUCH)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL }, + { "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID }, /* W2K */ }; - if (!pConvertStringSecurityDescriptorToSecurityDescriptorA) - { - win_skip("ConvertStringSecurityDescriptorToSecurityDescriptor is not available\n"); - return; - } - - for (i = 0; i < sizeof(cssd)/sizeof(cssd[0]); i++) + for (i = 0; i < ARRAY_SIZE(cssd); i++) { DWORD GLE; SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA( cssd[i].sidstring, cssd[i].revision, &pSD, NULL); GLE = GetLastError(); - ok(ret == cssd[i].ret, "(%02u) Expected %s (%d)\n", i, cssd[i].ret ? "success" : "failure", GLE); + ok(ret == cssd[i].ret, "(%02u) Expected %s (%ld)\n", i, cssd[i].ret ? "success" : "failure", GLE); if (!cssd[i].ret) ok(GLE == cssd[i].GLE || (cssd[i].altGLE && GLE == cssd[i].altGLE), - "(%02u) Unexpected last error %d\n", i, GLE); + "(%02u) Unexpected last error %ld\n", i, GLE); if (ret) + { + if (cssd[i].ace_Mask) + { + ACCESS_ALLOWED_ACE *ace; + + acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE)); + ok(acl->AclRevision == ACL_REVISION, "(%02u) Got %u\n", i, acl->AclRevision); + + ace = (ACCESS_ALLOWED_ACE *)(acl + 1); + ok(ace->Mask == cssd[i].ace_Mask, "(%02u) Expected %08lx, got %08lx\n", + i, cssd[i].ace_Mask, ace->Mask); + } LocalFree(pSD); + } } /* test behaviour with NULL parameters */ SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA( NULL, 0xdeadbeef, &pSD, NULL); todo_wine ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorW( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorW( NULL, 0xdeadbeef, &pSD, NULL); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA( "D:(A;;ROB;;;WD)", 0xdeadbeef, NULL, NULL); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA( "D:(A;;ROB;;;WD)", SDDL_REVISION_1, NULL, NULL); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", + "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); /* test behaviour with empty strings */ SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorW( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorW( Blank, SDDL_REVISION_1, &pSD, NULL); - ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); + ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %ld\n", GetLastError()); LocalFree(pSD); SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA( "D:P(A;;GRGW;;;BA)(A;;GRGW;;;S-1-5-21-0-0-0-1000)S:(ML;;NWNR;;;S-1-16-12288)", SDDL_REVISION_1, &pSD, NULL); ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */, - "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %u\n", GetLastError()); + "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %lu\n", GetLastError()); if (ret) LocalFree(pSD); /* empty DACL */ size = 0; SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA("D:", SDDL_REVISION_1, &pSD, &size); - ok(ret, "unexpected error %u\n", GetLastError()); - ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %u\n", size); + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA("D:", SDDL_REVISION_1, &pSD, &size); + ok(ret, "unexpected error %lu\n", GetLastError()); + ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %lu\n", size); acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE)); ok(acl->AclRevision == ACL_REVISION, "got %u\n", acl->AclRevision); ok(!acl->Sbz1, "got %u\n", acl->Sbz1); @@ -4513,9 +4385,9 @@ static void test_ConvertStringSecurityDescriptor(void) /* empty SACL */ size = 0; SetLastError(0xdeadbeef); - ret = pConvertStringSecurityDescriptorToSecurityDescriptorA("S:", SDDL_REVISION_1, &pSD, &size); - ok(ret, "unexpected error %u\n", GetLastError()); - ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %u\n", size); + ret = ConvertStringSecurityDescriptorToSecurityDescriptorA("S:", SDDL_REVISION_1, &pSD, &size); + ok(ret, "unexpected error %lu\n", GetLastError()); + ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %lu\n", size); acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE)); ok(!acl->Sbz1, "got %u\n", acl->Sbz1); ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize); @@ -4536,103 +4408,88 @@ static void test_ConvertSecurityDescriptorToString(void) char acl_buf[8192]; ULONG len; - if (!pConvertSecurityDescriptorToStringSecurityDescriptorA) - { - win_skip("ConvertSecurityDescriptorToStringSecurityDescriptor is not available\n"); - return; - } - if (!pCreateWellKnownSid) - { - win_skip("CreateWellKnownSid is not available\n"); - return; - } - /* It seems Windows XP adds an extra character to the length of the string for each ACE in an ACL. We * 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 >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %d)\n", lstrlenA(exp_str) + 1, len); \ + ok(len >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %ld)\n", lstrlenA(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(exp_str1) + 1) || len >= (strlen(exp_str2) + 1), "Length mismatch (expected %d or %d, got %d)\n", lstrlenA(exp_str1) + 1, lstrlenA(exp_str2) + 1, len); \ + ok(len >= (strlen(exp_str1) + 1) || len >= (strlen(exp_str2) + 1), "Length mismatch (expected %d or %d, got %ld)\n", lstrlenA(exp_str1) + 1, lstrlenA(exp_str2) + 1, len); \ LocalFree(string); InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE(""); size = 4096; - pCreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size); + CreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size); SetSecurityDescriptorOwner(&desc, sid_buf, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:S-1-2-0"); SetSecurityDescriptorOwner(&desc, sid_buf, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:S-1-2-0"); size = sizeof(sid_buf); - pCreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size); + CreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size); SetSecurityDescriptorOwner(&desc, sid_buf, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SY"); - pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid); + ConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid); SetSecurityDescriptorGroup(&desc, psid, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576"); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576"); pacl = (PACL)acl_buf; InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION); SetSecurityDescriptorDacl(&desc, TRUE, pacl, TRUE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:"); SetSecurityDescriptorDacl(&desc, TRUE, pacl, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:"); - pConvertStringSidToSidA("S-1-5-6", &psid2); - pAddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ConvertStringSidToSidA("S-1-5-6", &psid2); + AddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)"); - pAddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + AddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"); - pAddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + AddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"); pacl = (PACL)acl_buf; InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION); SetSecurityDescriptorSacl(&desc, TRUE, pacl, FALSE); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:"); /* fails in win2k */ SetSecurityDescriptorDacl(&desc, TRUE, NULL, FALSE); - pAddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE); - if (pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len)) - { - CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)", /* XP */ - "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" /* Vista */); - } + AddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)", /* XP */ + "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" /* Vista */); /* fails in win2k */ - pAddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE); - if (pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len)) - { - CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */ - "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */); - } + AddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */ + "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */); LocalFree(psid2); LocalFree(psid); @@ -4681,14 +4538,14 @@ static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec) ctrl = (bitOfInterest & mutable) ? ref + bitOfInterest : ref; setOrClear ^= bitOfInterest; SetLastError (0xbebecaca); - pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear); + SetSecurityDescriptorControl (sec, bitOfInterest, setOrClear); ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); GetSecurityDescriptorControl(sec, &test, &dwRevision); expect_eq(test, ctrl, int, "%x"); setOrClear ^= bitOfInterest; SetLastError (0xbebecaca); - pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear); + SetSecurityDescriptorControl (sec, bitOfInterest, setOrClear); ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); GetSecurityDescriptorControl (sec, &test, &dwRevision); expect_eq(test, ref, int, "%x"); @@ -4711,7 +4568,7 @@ static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec) ctrl = ((1 << bit) & immutable) ? test : ref | mutable; setOrClear ^= bitsOfInterest; SetLastError (0xbebecaca); - pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit)); + SetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit)); ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); GetSecurityDescriptorControl(sec, &test, &dwRevision); expect_eq(test, ctrl, int, "%x"); @@ -4719,7 +4576,7 @@ static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec) ctrl = ((1 << bit) & immutable) ? test : ref | (1 << bit); setOrClear ^= bitsOfInterest; SetLastError (0xbebecaca); - pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit)); + SetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit)); ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); GetSecurityDescriptorControl(sec, &test, &dwRevision); expect_eq(test, ctrl, int, "%x"); @@ -4739,13 +4596,7 @@ static void test_PrivateObjectSecurity(void) PSECURITY_DESCRIPTOR buf; BOOL ret; - if (!pConvertStringSecurityDescriptorToSecurityDescriptorA) - { - win_skip("ConvertStringSecurityDescriptorToSecurityDescriptor is not available\n"); - return; - } - - ok(pConvertStringSecurityDescriptorToSecurityDescriptorA( + ok(ConvertStringSecurityDescriptorToSecurityDescriptorA( "O:SY" "G:S-1-5-21-93476-23408-4576" "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)" @@ -4757,7 +4608,7 @@ static void test_PrivateObjectSecurity(void) LocalFree(sec); - ok(pConvertStringSecurityDescriptorToSecurityDescriptorA( + ok(ConvertStringSecurityDescriptorToSecurityDescriptorA( "O:SY" "G:S-1-5-21-93476-23408-4576", SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n"); @@ -4766,38 +4617,38 @@ static void test_PrivateObjectSecurity(void) LocalFree(sec); - ok(pConvertStringSecurityDescriptorToSecurityDescriptorA( + ok(ConvertStringSecurityDescriptorToSecurityDescriptorA( "O:SY" "G:S-1-5-21-93476-23408-4576" "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n"); - buf = HeapAlloc(GetProcessHeap(), 0, dwDescSize); - pSetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED); + buf = malloc(dwDescSize); + SetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED); GetSecurityDescriptorControl(sec, &ctrl, &dwRevision); expect_eq(ctrl, 0x9014, int, "%x"); ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize, &retSize); - ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); - ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError()); + ok(retSize <= dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576"); GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); expect_eq(ctrl, 0x8000, int, "%x"); ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, buf, dwDescSize, &retSize); - ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); - ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); - ret = pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len); - ok(ret, "Conversion failed err=%u\n", GetLastError()); + ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError()); + ok(retSize <= dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize); + ret = ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len); + ok(ret, "Conversion failed err=%lu\n", GetLastError()); CHECK_ONE_OF_AND_FREE("G:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)", "G:S-1-5-21-93476-23408-4576D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"); /* Win7 */ GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8004, int, "%x"); ret = GetPrivateObjectSecurity(sec, sec_info, buf, dwDescSize, &retSize); - ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); - ok(retSize == dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); - ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); + ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError()); + ok(retSize == dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize); + ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); CHECK_ONE_OF_AND_FREE("O:SY" "G:S-1-5-21-93476-23408-4576" "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" @@ -4811,15 +4662,15 @@ static void test_PrivateObjectSecurity(void) SetLastError(0xdeadbeef); ok(GetPrivateObjectSecurity(sec, sec_info, buf, 5, &retSize) == FALSE, "GetPrivateObjectSecurity should have failed\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError()); LocalFree(sec); - HeapFree(GetProcessHeap(), 0, buf); + free(buf); } #undef CHECK_RESULT_AND_FREE #undef CHECK_ONE_OF_AND_FREE -static void test_acls(void) +static void test_InitializeAcl(void) { char buffer[256]; PACL pAcl = (PACL)buffer; @@ -4833,43 +4684,38 @@ static void test_acls(void) return; } - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = InitializeAcl(pAcl, 0xffffffff, ACL_REVISION); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError()); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION1); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError()); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError()); ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION2); - ok(ret, "InitializeAcl(ACL_REVISION2) failed with error %d\n", GetLastError()); + ok(ret, "InitializeAcl(ACL_REVISION2) failed with error %ld\n", GetLastError()); ret = IsValidAcl(pAcl); - ok(ret, "IsValidAcl failed with error %d\n", GetLastError()); + ok(ret, "IsValidAcl failed with error %ld\n", GetLastError()); ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION3); - ok(ret, "InitializeAcl(ACL_REVISION3) failed with error %d\n", GetLastError()); + ok(ret, "InitializeAcl(ACL_REVISION3) failed with error %ld\n", GetLastError()); ret = IsValidAcl(pAcl); - ok(ret, "IsValidAcl failed with error %d\n", GetLastError()); + ok(ret, "IsValidAcl failed with error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4); - if (GetLastError() != ERROR_INVALID_PARAMETER) - { - ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n", GetLastError()); + ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %ld\n", GetLastError()); - ret = IsValidAcl(pAcl); - ok(ret, "IsValidAcl failed with error %d\n", GetLastError()); - } - else - win_skip("ACL_REVISION4 is not implemented on NT4\n"); + ret = IsValidAcl(pAcl); + ok(ret, "IsValidAcl failed with error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = InitializeAcl(pAcl, sizeof(buffer), -1); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %d\n", GetLastError()); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %ld\n", GetLastError()); } static void test_GetSecurityInfo(void) @@ -4881,6 +4727,7 @@ static void test_GetSecurityInfo(void) SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY }; int domain_users_ace_id = -1, admins_ace_id = -1, i; DWORD sid_size = sizeof(admin_ptr), l = sizeof(b); + SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)}; PSID admin_sid = (PSID) admin_ptr, user_sid; char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; BOOL owner_defaulted, group_defaulted; @@ -4895,11 +4742,23 @@ static void test_GetSecurityInfo(void) BYTE flags; DWORD ret; - if (!pGetSecurityInfo || !pSetSecurityInfo) + static const SE_OBJECT_TYPE kernel_types[] = { - win_skip("[Get|Set]SecurityInfo is not available\n"); - return; - } + SE_FILE_OBJECT, + SE_KERNEL_OBJECT, + SE_WMIGUID_OBJECT, + }; + + static const SE_OBJECT_TYPE invalid_types[] = + { + SE_UNKNOWN_OBJECT_TYPE, + SE_DS_OBJECT, + SE_DS_OBJECT_ALL, + SE_PROVIDER_DEFINED_OBJECT, + SE_REGISTRY_WOW64_32KEY, + SE_REGISTRY_WOW64_64KEY, + 0xdeadbeef, + }; if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) { @@ -4912,7 +4771,7 @@ static void test_GetSecurityInfo(void) return; } bret = GetTokenInformation(token, TokenUser, b, l, &l); - ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); + ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); CloseHandle( token ); user_sid = ((TOKEN_USER *)b)->User.Sid; @@ -4925,7 +4784,7 @@ static void test_GetSecurityInfo(void) return; } - ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, + ret = GetSecurityInfo(obj, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &owner, &group, &pDacl, NULL, &pSD); if (ret == ERROR_CALL_NOT_IMPLEMENTED) @@ -4934,7 +4793,7 @@ static void test_GetSecurityInfo(void) CloseHandle(obj); return; } - ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); + ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret); ok(pSD != NULL, "GetSecurityInfo\n"); ok(owner != NULL, "GetSecurityInfo\n"); ok(group != NULL, "GetSecurityInfo\n"); @@ -4945,19 +4804,12 @@ static void test_GetSecurityInfo(void) LocalFree(pSD); - if (!pCreateWellKnownSid) - { - win_skip("NULL parameter test would crash on NT4\n"); - CloseHandle(obj); - return; - } - /* If we don't ask for the security descriptor, Windows will still give us the other stuff, leaving us no way to free it. */ - ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, + ret = GetSecurityInfo(obj, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &owner, &group, &pDacl, NULL, NULL); - ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); + ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret); ok(owner != NULL, "GetSecurityInfo\n"); ok(group != NULL, "GetSecurityInfo\n"); if (pDacl != NULL) @@ -4969,45 +4821,50 @@ static void test_GetSecurityInfo(void) pSD = &sd; pDacl = (PACL)&dacl; InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); - pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); + CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION); ok(bret, "Failed to initialize ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); ok(bret, "Failed to add Current User to ACL.\n"); - bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); + bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); ok(bret, "Failed to add Administrator Group to ACL.\n"); bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); ok(bret, "Failed to add ACL to security descriptor.\n"); - ret = pSetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, - NULL, NULL, pDacl, NULL); - ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %d\n", ret); - ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + ret = SetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + NULL, NULL, pDacl, NULL); + ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %ld\n", ret); + ret = GetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD); - ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); + ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret); ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n"); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); if (acl_size.AceCount > 0) { - bret = pGetAce(pDacl, 0, (VOID **)&ace); + bret = GetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); +#ifndef __REACTOS__ // This crashes on WS03, Vista, Win7, and Win8.1. bret = EqualSid(&ace->SidStart, user_sid); - ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); + todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", + debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); +#endif ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", - ace->Mask); + ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%lx != 0x1f01ff)\n", + ace->Mask); } if (acl_size.AceCount > 1) { - bret = pGetAce(pDacl, 1, (VOID **)&ace); + bret = GetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); +#ifndef __REACTOS__ // This crashes on WS03, Vista, Win7, and Win8.1. bret = EqualSid(&ace->SidStart, admin_sid); - ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); + todo_wine ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); +#endif ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, - "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%lx != 0x1f01ff)\n", + ace->Mask); } LocalFree(pSD); CloseHandle(obj); @@ -5022,42 +4879,42 @@ static void test_GetSecurityInfo(void) return; } sid_size = sizeof(domain_users_ptr); - pCreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size); + CreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size); FreeSid(domain_sid); /* Test querying the ownership of a process */ - ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, + ret = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); - ok(!ret, "GetNamedSecurityInfo failed with error %d\n", ret); + ok(!ret, "GetNamedSecurityInfo failed with error %ld\n", ret); bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); - ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError()); ok(owner != NULL, "owner should not be NULL\n"); ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid), "Process owner SID != Administrators SID.\n"); bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); - ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError()); ok(group != NULL, "group should not be NULL\n"); ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n"); LocalFree(pSD); /* Test querying the DACL of a process */ - ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, + ret = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); - ok(!ret, "GetSecurityInfo failed with error %d\n", ret); + ok(!ret, "GetSecurityInfo failed with error %ld\n", ret); bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); - ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(bret, "GetSecurityDescriptorDacl failed with error %ld\n", GetLastError()); ok(dacl_present, "DACL should be present\n"); ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); - bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok(bret, "GetAclInformation failed\n"); ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); for (i=0; iSidStart, domain_users_sid); if (bret) domain_users_ace_id = i; @@ -5068,54 +4925,123 @@ static void test_GetSecurityInfo(void) "Domain Users ACE not found.\n"); if (domain_users_ace_id != -1) { - bret = pGetAce(pDacl, domain_users_ace_id, (VOID **)&ace); + bret = GetAce(pDacl, domain_users_ace_id, (VOID **)&ace); ok(bret, "Failed to get Domain Users ACE.\n"); flags = ((ACE_HEADER *)ace)->AceFlags; ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE), "Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags, INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); - ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%x != 0x%x)\n", + ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, GENERIC_READ); } ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */, "Builtin Admins ACE not found.\n"); if (admins_ace_id != -1) { - bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); + bret = GetAce(pDacl, admins_ace_id, (VOID **)&ace); ok(bret, "Failed to get Builtin Admins ACE.\n"); flags = ((ACE_HEADER *)ace)->AceFlags; ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */, - "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS); + "Builtin Admins ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS); } LocalFree(pSD); + + ret = GetSecurityInfo(NULL, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + ret = GetSecurityInfo(GetCurrentProcess(), SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + ok(!ret, "got error %lu\n", ret); + LocalFree(pSD); + + sa.lpSecurityDescriptor = sd; + obj = CreateEventA(&sa, TRUE, TRUE, NULL); + pDacl = (PACL)&dacl; + + for (size_t i = 0; i < ARRAY_SIZE(kernel_types); ++i) + { + winetest_push_context("Type %#x", kernel_types[i]); + + ret = GetSecurityInfo(NULL, kernel_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + ret = GetSecurityInfo(GetCurrentProcess(), kernel_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + ok(!ret, "got error %lu\n", ret); + LocalFree(pSD); + + ret = GetSecurityInfo(obj, kernel_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + ok(!ret, "got error %lu\n", ret); + LocalFree(pSD); + + ret = SetSecurityInfo(NULL, kernel_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL); + ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + ret = SetSecurityInfo(obj, kernel_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL); + ok(!ret || ret == ERROR_NO_SECURITY_ON_OBJECT /* win 7 */, "got error %lu\n", ret); + + winetest_pop_context(); + } + + ret = GetSecurityInfo(GetCurrentProcess(), SE_REGISTRY_KEY, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + todo_wine ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + ret = GetSecurityInfo(obj, SE_REGISTRY_KEY, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + todo_wine ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + CloseHandle(obj); + + for (size_t i = 0; i < ARRAY_SIZE(invalid_types); ++i) + { + winetest_push_context("Type %#x", invalid_types[i]); + + ret = GetSecurityInfo(NULL, invalid_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + ret = GetSecurityInfo((HANDLE)0xdeadbeef, invalid_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "got error %lu\n", ret); + + ret = SetSecurityInfo(NULL, invalid_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL); + ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret); + + ret = SetSecurityInfo((HANDLE)0xdeadbeef, invalid_types[i], + DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL); + todo_wine ok(ret == ERROR_INVALID_PARAMETER, "got error %lu\n", ret); + + winetest_pop_context(); + } } static void test_GetSidSubAuthority(void) { PSID psid = NULL; - if (!pGetSidSubAuthority || !pConvertStringSidToSidA || !pIsValidSid || !pGetSidSubAuthorityCount) - { - win_skip("Some functions not available\n"); - return; - } /* Note: on windows passing in an invalid index like -1, lets GetSidSubAuthority return 0x05000000 but still GetLastError returns ERROR_SUCCESS then. We don't test these unlikely cornercases here for now */ - ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576",&psid),"ConvertStringSidToSidA failed\n"); - ok(pIsValidSid(psid),"Sid is not valid\n"); + ok(ConvertStringSidToSidA("S-1-5-21-93476-23408-4576",&psid),"ConvertStringSidToSidA failed\n"); + ok(IsValidSid(psid),"Sid is not valid\n"); SetLastError(0xbebecaca); - ok(*pGetSidSubAuthorityCount(psid) == 4,"GetSidSubAuthorityCount gave %d expected 4\n",*pGetSidSubAuthorityCount(psid)); - ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); + ok(*GetSidSubAuthorityCount(psid) == 4,"GetSidSubAuthorityCount gave %d expected 4\n", *GetSidSubAuthorityCount(psid)); + ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError()); SetLastError(0xbebecaca); - ok(*pGetSidSubAuthority(psid,0) == 21,"GetSidSubAuthority gave %d expected 21\n",*pGetSidSubAuthority(psid,0)); - ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); + ok(*GetSidSubAuthority(psid,0) == 21,"GetSidSubAuthority gave %ld expected 21\n", *GetSidSubAuthority(psid,0)); + ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError()); SetLastError(0xbebecaca); - ok(*pGetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %d expected 93476\n",*pGetSidSubAuthority(psid,1)); - ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); + ok(*GetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %ld expected 93476\n", *GetSidSubAuthority(psid,1)); + ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError()); SetLastError(0xbebecaca); - ok(pGetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n"); - ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); + ok(GetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n"); + ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError()); LocalFree(psid); } @@ -5128,25 +5054,20 @@ static void test_CheckTokenMembership(void) BOOL ret; DWORD i; - if (!pCheckTokenMembership) - { - win_skip("CheckTokenMembership is not available\n"); - return; - } ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token); - ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); ret = DuplicateToken(process_token, SecurityImpersonation, &token); - ok(ret, "DuplicateToken failed with error %d\n", GetLastError()); + ok(ret, "DuplicateToken failed with error %ld\n", GetLastError()); /* groups */ ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "GetTokenInformation(TokenGroups) %s with error %d\n", + "GetTokenInformation(TokenGroups) %s with error %ld\n", ret ? "succeeded" : "failed", GetLastError()); - token_groups = HeapAlloc(GetProcessHeap(), 0, size); + token_groups = malloc(size); ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size); - ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError()); + ok(ret, "GetTokenInformation(TokenGroups) failed with error %ld\n", GetLastError()); for (i = 0; i < token_groups->GroupCount; i++) { @@ -5156,31 +5077,31 @@ static void test_CheckTokenMembership(void) if (i == token_groups->GroupCount) { - HeapFree(GetProcessHeap(), 0, token_groups); + free(token_groups); CloseHandle(token); skip("user not a member of any group\n"); return; } is_member = FALSE; - ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member); - ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); + ret = CheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member); + ok(ret, "CheckTokenMembership failed with error %ld\n", GetLastError()); ok(is_member, "CheckTokenMembership should have detected sid as member\n"); is_member = FALSE; - ret = pCheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member); - ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); + ret = CheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member); + ok(ret, "CheckTokenMembership failed with error %ld\n", GetLastError()); ok(is_member, "CheckTokenMembership should have detected sid as member\n"); is_member = TRUE; SetLastError(0xdeadbeef); - ret = pCheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member); + ret = CheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member); ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN, - "CheckTokenMembership with process token %s with error %d\n", + "CheckTokenMembership with process token %s with error %ld\n", ret ? "succeeded" : "failed", GetLastError()); ok(!is_member, "CheckTokenMembership should have cleared is_member\n"); - HeapFree(GetProcessHeap(), 0, token_groups); + free(token_groups); CloseHandle(token); CloseHandle(process_token); } @@ -5200,50 +5121,49 @@ static void test_EqualSid(void) win_skip("AllocateAndInitializeSid is not implemented\n"); return; } - ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); ok(GetLastError() == 0xdeadbeef, - "AllocateAndInitializeSid shouldn't have set last error to %d\n", + "AllocateAndInitializeSid shouldn't have set last error to %ld\n", GetLastError()); ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sid2); - ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = EqualSid(sid1, sid2); ok(!ret, "World and domain admins sids shouldn't have been equal\n"); - ok(GetLastError() == ERROR_SUCCESS || - broken(GetLastError() == 0xdeadbeef), /* NT4 */ - "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", + ok(GetLastError() == ERROR_SUCCESS, + "EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n", GetLastError()); SetLastError(0xdeadbeef); sid2 = FreeSid(sid2); ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2); ok(GetLastError() == 0xdeadbeef, - "FreeSid shouldn't have set last error to %d\n", + "FreeSid shouldn't have set last error to %ld\n", GetLastError()); ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2); - ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); +#ifndef __REACTOS__ // This crashes on WS03, Vista, Win7, and Win8.1. SetLastError(0xdeadbeef); ret = EqualSid(sid1, sid2); ok(ret, "Same sids should have been equal %s != %s\n", debugstr_sid(sid1), debugstr_sid(sid2)); - ok(GetLastError() == ERROR_SUCCESS || - broken(GetLastError() == 0xdeadbeef), /* NT4 */ - "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", + ok(GetLastError() == ERROR_SUCCESS, + "EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n", GetLastError()); +#endif ((SID *)sid2)->Revision = 2; SetLastError(0xdeadbeef); ret = EqualSid(sid1, sid2); ok(!ret, "EqualSid with invalid sid should have returned FALSE\n"); - ok(GetLastError() == ERROR_SUCCESS || - broken(GetLastError() == 0xdeadbeef), /* NT4 */ - "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", + ok(GetLastError() == ERROR_SUCCESS, + "EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n", GetLastError()); ((SID *)sid2)->Revision = SID_REVISION; @@ -5268,15 +5188,15 @@ static void test_GetUserNameA(void) required_len = 0; ret = GetUserNameA(NULL, &required_len); ok(ret == FALSE, "GetUserNameA returned %d\n", ret); - ok(required_len != 0, "Outputted buffer length was %u\n", required_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(required_len != 0, "Outputted buffer length was %lu\n", required_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); SetLastError(0xdeadbeef); required_len = 1; ret = GetUserNameA(NULL, &required_len); ok(ret == FALSE, "GetUserNameA returned %d\n", ret); - ok(required_len != 0 && required_len != 1, "Outputted buffer length was %u\n", required_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(required_len != 0 && required_len != 1, "Outputted buffer length was %lu\n", required_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); /* Tests crashes on Windows. */ if (0) @@ -5299,18 +5219,19 @@ static void test_GetUserNameA(void) ret = GetUserNameA(buffer, &required_len); ok(ret == FALSE, "GetUserNameA returned %d\n", ret); ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n"); - ok(required_len != 0, "Outputted buffer length was %u\n", required_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(required_len != 0, "Outputted buffer length was %lu\n", required_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); SetLastError(0xdeadbeef); memcpy(buffer, filler, sizeof(filler)); buffer_len = required_len; ret = GetUserNameA(buffer, &buffer_len); - ok(ret == TRUE, "GetUserNameA returned %d, last error %u\n", ret, GetLastError()); + ok(ret == TRUE, "GetUserNameA returned %d, last error %lu\n", ret, GetLastError()); ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n"); ok(buffer_len == required_len || broken(buffer_len == required_len / sizeof(WCHAR)), /* XP+ */ - "Outputted buffer length was %u\n", buffer_len); + "Outputted buffer length was %lu\n", buffer_len); + ok(GetLastError() == 0xdeadbeef, "Last error was %lu\n", GetLastError()); /* Use the reported buffer size from the last GetUserNameA call and pass * a length that is one less than the required value. */ @@ -5320,8 +5241,8 @@ static void test_GetUserNameA(void) ret = GetUserNameA(buffer, &buffer_len); ok(ret == FALSE, "GetUserNameA returned %d\n", ret); ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was untouched\n"); - ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); } static void test_GetUserNameW(void) @@ -5341,15 +5262,15 @@ static void test_GetUserNameW(void) required_len = 0; ret = GetUserNameW(NULL, &required_len); ok(ret == FALSE, "GetUserNameW returned %d\n", ret); - ok(required_len != 0, "Outputted buffer length was %u\n", required_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(required_len != 0, "Outputted buffer length was %lu\n", required_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); SetLastError(0xdeadbeef); required_len = 1; ret = GetUserNameW(NULL, &required_len); ok(ret == FALSE, "GetUserNameW returned %d\n", ret); - ok(required_len != 0 && required_len != 1, "Outputted buffer length was %u\n", required_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(required_len != 0 && required_len != 1, "Outputted buffer length was %lu\n", required_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); /* Tests crash on Windows. */ if (0) @@ -5370,16 +5291,17 @@ static void test_GetUserNameW(void) ret = GetUserNameW(buffer, &required_len); ok(ret == FALSE, "GetUserNameW returned %d\n", ret); ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n"); - ok(required_len != 0, "Outputted buffer length was %u\n", required_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(required_len != 0, "Outputted buffer length was %lu\n", required_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); SetLastError(0xdeadbeef); memcpy(buffer, filler, sizeof(filler)); buffer_len = required_len; ret = GetUserNameW(buffer, &buffer_len); - ok(ret == TRUE, "GetUserNameW returned %d, last error %u\n", ret, GetLastError()); + ok(ret == TRUE, "GetUserNameW returned %d, last error %lu\n", ret, GetLastError()); ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n"); - ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len); + ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len); + ok(GetLastError() == 0xdeadbeef, "Last error was %lu\n", GetLastError()); /* GetUserNameW on XP and newer writes a truncated portion of the username string to the buffer. */ SetLastError(0xdeadbeef); @@ -5390,186 +5312,159 @@ static void test_GetUserNameW(void) ok(!memcmp(buffer, filler, sizeof(filler)) || broken(memcmp(buffer, filler, sizeof(filler)) != 0), /* XP+ */ "Output buffer was altered\n"); - ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); + ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError()); } static void test_CreateRestrictedToken(void) { - TOKEN_PRIMARY_GROUP *primary_group, *primary_group2; HANDLE process_token, token, r_token; PTOKEN_GROUPS token_groups, groups2; + LUID_AND_ATTRIBUTES lattr; SID_AND_ATTRIBUTES sattr; SECURITY_IMPERSONATION_LEVEL level; - TOKEN_PRIVILEGES *privs; - PRIVILEGE_SET privset; + SID *removed_sid = NULL; + char privs_buffer[1000]; + TOKEN_PRIVILEGES *privs = (TOKEN_PRIVILEGES *)privs_buffer; + PRIVILEGE_SET priv_set; TOKEN_TYPE type; BOOL is_member; DWORD size; + LUID luid = { 0, 0 }; BOOL ret; - DWORD i, j; - - if (!pCreateRestrictedToken) - { - win_skip("CreateRestrictedToken is not available\n"); - return; - } + DWORD i; ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token); - ok(ret, "got error %d\n", GetLastError()); + ok(ret, "got error %ld\n", GetLastError()); - ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, + ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_QUERY, NULL, SecurityImpersonation, TokenImpersonation, &token); - ok(ret, "got error %d\n", GetLastError()); + ok(ret, "got error %ld\n", GetLastError()); - /* groups */ ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "got %d with error %d\n", ret, GetLastError()); - token_groups = HeapAlloc(GetProcessHeap(), 0, size); + "got %d with error %ld\n", ret, GetLastError()); + token_groups = malloc(size); ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size); - ok(ret, "got error %d\n", GetLastError()); + ok(ret, "got error %ld\n", GetLastError()); for (i = 0; i < token_groups->GroupCount; i++) { if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) + { + removed_sid = token_groups->Groups[i].Sid; break; + } } - - if (i == token_groups->GroupCount) - { - HeapFree(GetProcessHeap(), 0, token_groups); - CloseHandle(token); - skip("User not a member of any group\n"); - return; - } + ok(!!removed_sid, "user is not a member of any group\n"); is_member = FALSE; - ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member); - ok(ret, "got error %d\n", GetLastError()); + ret = CheckTokenMembership(token, removed_sid, &is_member); + ok(ret, "got error %ld\n", GetLastError()); ok(is_member, "not a member\n"); - privset.PrivilegeCount = 1; - privset.Control = PRIVILEGE_SET_ALL_NECESSARY; - ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privset.Privilege[0].Luid); - ok(ret, "got error %d\n", GetLastError()); + sattr.Sid = removed_sid; + sattr.Attributes = 0; + r_token = NULL; + ret = CreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token); + ok(ret, "got error %ld\n", GetLastError()); + + is_member = TRUE; + ret = CheckTokenMembership(r_token, removed_sid, &is_member); + ok(ret, "got error %ld\n", GetLastError()); + ok(!is_member, "not a member\n"); + + ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %ld\n", + ret, GetLastError()); + groups2 = malloc(size); + ret = GetTokenInformation(r_token, TokenGroups, groups2, size, &size); + ok(ret, "got error %ld\n", GetLastError()); + + for (i = 0; i < groups2->GroupCount; i++) + { + if (EqualSid(groups2->Groups[i].Sid, removed_sid)) + { + DWORD attr = groups2->Groups[i].Attributes; + ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#lx\n", attr); + ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#lx\n", attr); + break; + } + } + + free(groups2); + + size = sizeof(type); + ret = GetTokenInformation(r_token, TokenType, &type, size, &size); + ok(ret, "got error %ld\n", GetLastError()); + ok(type == TokenImpersonation, "got type %u\n", type); + + size = sizeof(level); + ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size); + ok(ret, "got error %ld\n", GetLastError()); + ok(level == SecurityImpersonation, "got level %u\n", type); + + CloseHandle(r_token); + + r_token = NULL; + ret = CreateRestrictedToken(process_token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token); + ok(ret, "got error %lu\n", GetLastError()); + + size = sizeof(type); + ret = GetTokenInformation(r_token, TokenType, &type, size, &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenPrimary, "got type %u\n", type); + + CloseHandle(r_token); + + ret = GetTokenInformation(token, TokenPrivileges, privs, sizeof(privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + + for (i = 0; i < privs->PrivilegeCount; i++) + { + if (privs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) + { + luid = privs->Privileges[i].Luid; + break; + } + } + ok(i < privs->PrivilegeCount, "user has no privileges\n"); + + lattr.Luid = luid; + lattr.Attributes = 0; + r_token = NULL; + ret = CreateRestrictedToken(token, 0, 0, NULL, 1, &lattr, 0, NULL, &r_token); + ok(ret, "got error %lu\n", GetLastError()); + + priv_set.PrivilegeCount = 1; + priv_set.Control = 0; + priv_set.Privilege[0].Luid = luid; + priv_set.Privilege[0].Attributes = 0; + ret = PrivilegeCheck(r_token, &priv_set, &is_member); + ok(ret, "got error %lu\n", GetLastError()); + ok(!is_member, "privilege should not be enabled\n"); + + ret = GetTokenInformation(r_token, TokenPrivileges, privs, sizeof(privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); is_member = FALSE; - ret = PrivilegeCheck(token, &privset, &is_member); - ok(ret, "got error %d\n", GetLastError()); - ok(is_member, "Expected SeChangeNotifyPrivilege to be enabled\n"); - - /* disable a SID and a privilege in new token */ - sattr.Sid = token_groups->Groups[i].Sid; - sattr.Attributes = 0; - r_token = NULL; - ret = pCreateRestrictedToken(token, 0, 1, &sattr, 1, &privset.Privilege[0], 0, NULL, &r_token); - ok(ret, "got error %d\n", GetLastError()); - - if (ret) + for (i = 0; i < privs->PrivilegeCount; i++) { - /* check if a SID is enabled */ - is_member = TRUE; - ret = pCheckTokenMembership(r_token, token_groups->Groups[i].Sid, &is_member); - ok(ret, "got error %d\n", GetLastError()); - ok(!is_member, "not a member\n"); - - ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", - ret, GetLastError()); - groups2 = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetTokenInformation(r_token, TokenGroups, groups2, size, &size); - ok(ret, "got error %d\n", GetLastError()); - - for (j = 0; j < groups2->GroupCount; j++) - { - if (EqualSid(groups2->Groups[j].Sid, token_groups->Groups[i].Sid)) - break; - } - - ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY, - "got wrong attributes\n"); - ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0, - "got wrong attributes\n"); - - HeapFree(GetProcessHeap(), 0, groups2); - - size = sizeof(type); - ret = GetTokenInformation(r_token, TokenType, &type, size, &size); - ok(ret, "got error %d\n", GetLastError()); - ok(type == TokenImpersonation, "got type %u\n", type); - - size = sizeof(level); - ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size); - ok(ret, "got error %d\n", GetLastError()); - ok(level == SecurityImpersonation, "got level %u\n", type); - - is_member = TRUE; - ret = PrivilegeCheck(r_token, &privset, &is_member); - ok(ret, "got error %d\n", GetLastError()); - ok(!is_member, "Expected SeChangeNotifyPrivilege not to be enabled\n"); - - ret = GetTokenInformation(r_token, TokenPrivileges, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", - ret, GetLastError()); - privs = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetTokenInformation(r_token, TokenPrivileges, privs, size, &size); - ok(ret, "got error %d\n", GetLastError()); - - is_member = FALSE; - for (j = 0; j < privs->PrivilegeCount; j++) - { - if (RtlEqualLuid(&privs->Privileges[j].Luid, &privset.Privilege[0].Luid)) - { - is_member = TRUE; - break; - } - } - - ok(!is_member, "Expected not to find privilege\n"); - HeapFree(GetProcessHeap(), 0, privs); + if (!memcmp(&privs->Privileges[i].Luid, &luid, sizeof(luid))) + is_member = TRUE; } + ok(!is_member, "disabled privilege should not be present\n"); - HeapFree(GetProcessHeap(), 0, token_groups); CloseHandle(r_token); - ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", - ret, GetLastError()); - primary_group = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetTokenInformation(token, TokenPrimaryGroup, primary_group, size, &size); - ok(ret, "got error %d\n", GetLastError()); - - /* disable primary group */ - sattr.Sid = primary_group->PrimaryGroup; - sattr.Attributes = 0; + removed_sid->SubAuthority[0] = 0xdeadbeef; + lattr.Luid.LowPart = 0xdeadbeef; r_token = NULL; - ret = pCreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token); - ok(ret, "got error %d\n", GetLastError()); - - if (ret) - { - is_member = TRUE; - ret = pCheckTokenMembership(r_token, primary_group->PrimaryGroup, &is_member); - ok(ret, "got error %d\n", GetLastError()); - ok(!is_member, "not a member\n"); - - ret = GetTokenInformation(r_token, TokenPrimaryGroup, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", - ret, GetLastError()); - primary_group2 = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetTokenInformation(r_token, TokenPrimaryGroup, primary_group2, size, &size); - ok(ret, "got error %d\n", GetLastError()); - - ok(EqualSid(primary_group2->PrimaryGroup, primary_group->PrimaryGroup), - "Expected same primary group\n"); - - HeapFree(GetProcessHeap(), 0, primary_group2); - } - - HeapFree(GetProcessHeap(), 0, primary_group); + ret = CreateRestrictedToken(token, 0, 1, &sattr, 1, &lattr, 0, NULL, &r_token); + ok(ret, "got error %lu\n", GetLastError()); CloseHandle(r_token); + free(token_groups); CloseHandle(token); CloseHandle(process_token); } @@ -5588,10 +5483,10 @@ static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd) acl = (void *)0xdeadbeef; SetLastError(0xdeadbeef); ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted); - ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError()); -todo_wine + ok(ret, "GetSecurityDescriptorDacl error %ld\n", GetLastError()); + todo_wine ok(present == 1, "acl is not present\n"); -todo_wine + todo_wine ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n"); ok(defaulted == 0, "defaulted is set to TRUE\n"); @@ -5599,8 +5494,8 @@ todo_wine sid = (void *)0xdeadbeef; SetLastError(0xdeadbeef); ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted); - ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError()); -todo_wine + ok(ret, "GetSecurityDescriptorOwner error %ld\n", GetLastError()); + todo_wine ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n"); ok(defaulted == 0, "defaulted is set to TRUE\n"); @@ -5608,8 +5503,8 @@ todo_wine sid = (void *)0xdeadbeef; SetLastError(0xdeadbeef); ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted); - ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError()); -todo_wine + ok(ret, "GetSecurityDescriptorGroup error %ld\n", GetLastError()); + todo_wine ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n"); ok(defaulted == 0, "defaulted is set to TRUE\n"); } @@ -5630,9 +5525,9 @@ static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MA SetLastError(0xdeadbeef); ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status); todo_wine { - ok(ret, "AccessCheck error %d\n", GetLastError()); + ok(ret, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == mapping->GenericAll, "expected all access %#x, got %#x\n", mapping->GenericAll, granted); + ok(granted == mapping->GenericAll, "expected all access %#lx, got %#lx\n", mapping->GenericAll, granted); } priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; @@ -5640,9 +5535,9 @@ todo_wine { SetLastError(0xdeadbeef); ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status); todo_wine { - ok(ret, "AccessCheck error %d\n", GetLastError()); - ok(status == 0 || broken(status == 1) /* NT4 */, "expected 0, got %d\n", status); - ok(granted == 0 || broken(granted == mapping->GenericRead) /* NT4 */, "expected 0, got %#x\n", granted); + ok(ret, "AccessCheck error %ld\n", GetLastError()); + ok(status == 0, "expected 0, got %d\n", status); + ok(granted == 0, "expected 0, got %#lx\n", granted); } priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; @@ -5650,9 +5545,9 @@ todo_wine { SetLastError(0xdeadbeef); ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status); todo_wine { - ok(ret, "AccessCheck error %d\n", GetLastError()); + ok(ret, "AccessCheck error %ld\n", GetLastError()); ok(status == 0, "expected 0, got %d\n", status); - ok(granted == 0, "expected 0, got %#x\n", granted); + ok(granted == 0, "expected 0, got %#lx\n", granted); } priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; @@ -5660,9 +5555,9 @@ todo_wine { SetLastError(0xdeadbeef); ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status); todo_wine { - ok(ret, "AccessCheck error %d\n", GetLastError()); + ok(ret, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == mapping->GenericRead, "expected read access %#x, got %#x\n", mapping->GenericRead, granted); + ok(granted == mapping->GenericRead, "expected read access %#lx, got %#lx\n", mapping->GenericRead, granted); } priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; @@ -5670,9 +5565,9 @@ todo_wine { SetLastError(0xdeadbeef); ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status); todo_wine { - ok(ret, "AccessCheck error %d\n", GetLastError()); + ok(ret, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == mapping->GenericWrite, "expected write access %#x, got %#x\n", mapping->GenericWrite, granted); + ok(granted == mapping->GenericWrite, "expected write access %#lx, got %#lx\n", mapping->GenericWrite, granted); } priv_set_len = sizeof(priv_set); granted = 0xdeadbeef; @@ -5680,11 +5575,11 @@ todo_wine { SetLastError(0xdeadbeef); ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status); todo_wine { - ok(ret, "AccessCheck error %d\n", GetLastError()); + ok(ret, "AccessCheck error %ld\n", GetLastError()); ok(status == 1, "expected 1, got %d\n", status); - ok(granted == mapping->GenericExecute, "expected execute access %#x, got %#x\n", mapping->GenericExecute, granted); + ok(granted == mapping->GenericExecute, "expected execute access %#lx, got %#lx\n", mapping->GenericExecute, granted); } - HeapFree(GetProcessHeap(), 0, sd); + free(sd); } static ACCESS_MASK get_obj_access(HANDLE obj) @@ -5692,10 +5587,8 @@ static ACCESS_MASK get_obj_access(HANDLE obj) OBJECT_BASIC_INFORMATION info; NTSTATUS status; - if (!pNtQueryObject) return 0; - - status = pNtQueryObject(obj, ObjectBasicInformation, &info, sizeof(info), NULL); - ok(!status, "NtQueryObject error %#x\n", status); + status = NtQueryObject(obj, ObjectBasicInformation, &info, sizeof(info), NULL); + ok(!status, "NtQueryObject error %#lx\n", status); return info.GrantedAccess; } @@ -5723,33 +5616,33 @@ static void test_mutex_security(HANDLE token) SetLastError(0xdeadbeef); mutex = OpenMutexA(0, FALSE, "WineTestMutex"); ok(!mutex, "mutex should not exist\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError()); SetLastError(0xdeadbeef); mutex = CreateMutexA(NULL, FALSE, "WineTestMutex"); - ok(mutex != 0, "CreateMutex error %d\n", GetLastError()); + ok(mutex != 0, "CreateMutex error %ld\n", GetLastError()); access = get_obj_access(mutex); - ok(access == MUTANT_ALL_ACCESS, "expected MUTANT_ALL_ACCESS, got %#x\n", access); + ok(access == MUTANT_ALL_ACCESS, "expected MUTANT_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), mutex, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); SetLastError(0xdeadbeef); dup = OpenMutexA(0, FALSE, "WineTestMutex"); -todo_wine + todo_wine ok(!dup, "OpenMutex should fail\n"); -todo_wine - ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError()); + todo_wine + ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError()); } test_default_handle_security(token, mutex, &mapping); @@ -5780,33 +5673,33 @@ static void test_event_security(HANDLE token) SetLastError(0xdeadbeef); event = OpenEventA(0, FALSE, "WineTestEvent"); ok(!event, "event should not exist\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError()); SetLastError(0xdeadbeef); event = CreateEventA(NULL, FALSE, FALSE, "WineTestEvent"); - ok(event != 0, "CreateEvent error %d\n", GetLastError()); + ok(event != 0, "CreateEvent error %ld\n", GetLastError()); access = get_obj_access(event); - ok(access == EVENT_ALL_ACCESS, "expected EVENT_ALL_ACCESS, got %#x\n", access); + ok(access == EVENT_ALL_ACCESS, "expected EVENT_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); SetLastError(0xdeadbeef); dup = OpenEventA(0, FALSE, "WineTestEvent"); -todo_wine + todo_wine ok(!dup, "OpenEvent should fail\n"); -todo_wine - ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError()); + todo_wine + ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError()); } test_default_handle_security(token, event, &mapping); @@ -5837,24 +5730,24 @@ static void test_semaphore_security(HANDLE token) SetLastError(0xdeadbeef); sem = OpenSemaphoreA(0, FALSE, "WineTestSemaphore"); ok(!sem, "semaphore should not exist\n"); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError()); SetLastError(0xdeadbeef); sem = CreateSemaphoreA(NULL, 0, 10, "WineTestSemaphore"); - ok(sem != 0, "CreateSemaphore error %d\n", GetLastError()); + ok(sem != 0, "CreateSemaphore error %ld\n", GetLastError()); access = get_obj_access(sem); - ok(access == SEMAPHORE_ALL_ACCESS, "expected SEMAPHORE_ALL_ACCESS, got %#x\n", access); + ok(access == SEMAPHORE_ALL_ACCESS, "expected SEMAPHORE_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), sem, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); } @@ -5875,14 +5768,14 @@ static void test_named_pipe_security(HANDLE token) STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }; static const struct { - int todo, generic, mapped; + int generic, mapped; } map[] = { - { 0, 0, 0 }, - { 1, GENERIC_READ, FILE_GENERIC_READ }, - { 1, GENERIC_WRITE, FILE_GENERIC_WRITE }, - { 1, GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, - { 1, GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } + { 0, 0 }, + { GENERIC_READ, FILE_GENERIC_READ }, + { GENERIC_WRITE, FILE_GENERIC_WRITE }, + { GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, + { GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } }; static const struct { @@ -5899,17 +5792,17 @@ static void test_named_pipe_security(HANDLE token) }; /* Test the different security access options for pipes */ - for (i = 0; i < sizeof(creation_access)/sizeof(creation_access[0]); i++) + for (i = 0; i < ARRAY_SIZE(creation_access); i++) { SetLastError(0xdeadbeef); pipe = CreateNamedPipeA(WINE_TEST_PIPE, creation_access[i].open_mode, PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL); - ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe(0x%x) error %d\n", + ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe(0x%lx) error %ld\n", creation_access[i].open_mode, GetLastError()); access = get_obj_access(pipe); ok(access == creation_access[i].access, - "CreateNamedPipeA(0x%x) pipe expected access 0x%x (got 0x%x)\n", + "CreateNamedPipeA(0x%lx) pipe expected access 0x%lx (got 0x%lx)\n", creation_access[i].open_mode, creation_access[i].access, access); CloseHandle(pipe); } @@ -5918,26 +5811,26 @@ static void test_named_pipe_security(HANDLE token) pipe = CreateNamedPipeA(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL); - ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %d\n", GetLastError()); + ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %ld\n", GetLastError()); test_default_handle_security(token, pipe, &mapping); SetLastError(0xdeadbeef); file = CreateFileA(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); - ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); + ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); } @@ -5947,24 +5840,22 @@ static void test_named_pipe_security(HANDLE token) SetLastError(0xdeadbeef); file = CreateFileA("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); - ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %ld\n", GetLastError()); if (file != INVALID_HANDLE_VALUE) { access = get_obj_access(file); - ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); + ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - todo_wine_if (map[i].todo) - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); - + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); } } @@ -5997,20 +5888,20 @@ static void test_file_security(HANDLE token) /* file */ SetLastError(0xdeadbeef); file = CreateFileA(file_name, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, 0, NULL); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); - ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); + ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); } @@ -6019,35 +5910,33 @@ static void test_file_security(HANDLE token) SetLastError(0xdeadbeef); file = CreateFileA(file_name, 0, 0, NULL, OPEN_EXISTING, 0, NULL); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); -todo_wine - ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#x\n", access); + ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#lx\n", access); bytes = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL); ok(!ret, "ReadFile should fail\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); - ok(bytes == 0, "expected 0, got %u\n", bytes); + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); + ok(bytes == 0, "expected 0, got %lu\n", bytes); CloseHandle(file); SetLastError(0xdeadbeef); file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); -todo_wine - ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#x\n", access); + ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#lx\n", access); bytes = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL); ok(!ret, "ReadFile should fail\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); - ok(bytes == 0, "expected 0, got %u\n", bytes); + ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); + ok(bytes == 0, "expected 0, got %lu\n", bytes); CloseHandle(file); DeleteFileA(file_name); @@ -6055,20 +5944,20 @@ todo_wine /* directory */ SetLastError(0xdeadbeef); file = CreateFileA(temp_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); - ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); + ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); } @@ -6077,21 +5966,19 @@ todo_wine SetLastError(0xdeadbeef); file = CreateFileA(temp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); -todo_wine - ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#x\n", access); + ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#lx\n", access); CloseHandle(file); SetLastError(0xdeadbeef); file = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); access = get_obj_access(file); -todo_wine - ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#x\n", access); + ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#lx\n", access); CloseHandle(file); } @@ -6140,11 +6027,11 @@ static void test_filemap_security(void) SetLastError(0xdeadbeef); file = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0); - ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); + ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError()); SetFilePointer(file, 4096, NULL, FILE_BEGIN); SetEndOfFile(file); - for (i = 0; i < sizeof(prot_map)/sizeof(prot_map[0]); i++) + for (i = 0; i < ARRAY_SIZE(prot_map); i++) { if (map[i].open_only) continue; @@ -6152,57 +6039,40 @@ static void test_filemap_security(void) mapping = CreateFileMappingW(file, NULL, prot_map[i].prot, 0, 4096, NULL); if (prot_map[i].mapped) { - if (!mapping) - { - /* NT4 and win2k don't support EXEC on file mappings */ - if (prot_map[i].prot == PAGE_EXECUTE_READ || prot_map[i].prot == PAGE_EXECUTE_READWRITE || prot_map[i].prot == PAGE_EXECUTE_WRITECOPY) - { - win_skip("CreateFileMapping doesn't support PAGE_EXECUTE protection\n"); - continue; - } - } - ok(mapping != 0, "CreateFileMapping(%04x) error %d\n", prot_map[i].prot, GetLastError()); + ok(mapping != 0, "CreateFileMapping(%04x) error %ld\n", prot_map[i].prot, GetLastError()); } else { ok(!mapping, "CreateFileMapping(%04x) should fail\n", prot_map[i].prot); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); continue; } access = get_obj_access(mapping); - ok(access == prot_map[i].mapped, "%d: expected %#x, got %#x\n", i, prot_map[i].mapped, access); + ok(access == prot_map[i].mapped, "%ld: expected %#x, got %#lx\n", i, prot_map[i].mapped, access); CloseHandle(mapping); } SetLastError(0xdeadbeef); mapping = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READWRITE, 0, 4096, NULL); - if (!mapping) - { - /* NT4 and win2k don't support EXEC on file mappings */ - win_skip("CreateFileMapping doesn't support PAGE_EXECUTE protection\n"); - CloseHandle(file); - DeleteFileA(file_name); - return; - } - ok(mapping != 0, "CreateFileMapping error %d\n", GetLastError()); + ok(mapping != 0, "CreateFileMapping error %ld\n", GetLastError()); access = get_obj_access(mapping); ok(access == (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE), - "expected STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, got %#x\n", access); + "expected STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { if (map[i].open_only) continue; SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), mapping, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); CloseHandle(dup); } @@ -6213,16 +6083,16 @@ static void test_filemap_security(void) created_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, "Wine Test Open Mapping"); - ok(created_mapping != NULL, "CreateFileMapping failed with error %u\n", GetLastError()); + ok(created_mapping != NULL, "CreateFileMapping failed with error %lu\n", GetLastError()); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { if (!map[i].generic) continue; mapping = OpenFileMappingA(map[i].generic, FALSE, "Wine Test Open Mapping"); - ok(mapping != NULL, "OpenFileMapping failed with error %d\n", GetLastError()); + ok(mapping != NULL, "OpenFileMapping failed with error %ld\n", GetLastError()); access = get_obj_access(mapping); - ok(access == map[i].mapped, "%d: unexpected access flags %#x, expected %#x\n", + ok(access == map[i].mapped, "%ld: unexpected access flags %#lx, expected %#x\n", i, access, map[i].mapped); CloseHandle(mapping); } @@ -6248,17 +6118,17 @@ static void test_thread_security(void) SetLastError(0xdeadbeef); thread = CreateThread(NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret); - ok(thread != 0, "CreateThread error %d\n", GetLastError()); + ok(thread != 0, "CreateThread error %ld\n", GetLastError()); access = get_obj_access(thread); - ok(access == THREAD_ALL_ACCESS_NT4 || access == THREAD_ALL_ACCESS_VISTA, "expected THREAD_ALL_ACCESS, got %#x\n", access); + ok(access == THREAD_ALL_ACCESS_NT4 || access == THREAD_ALL_ACCESS_VISTA, "expected THREAD_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); switch (map[i].generic) @@ -6268,21 +6138,20 @@ static void test_thread_security(void) ok(access == map[i].mapped || access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ || access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; case GENERIC_WRITE: -todo_wine ok(access == map[i].mapped || access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */ || access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; case GENERIC_ALL: ok(access == map[i].mapped || access == THREAD_ALL_ACCESS_VISTA, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; default: - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; } @@ -6292,11 +6161,11 @@ todo_wine SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup, THREAD_QUERY_INFORMATION, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); ok(access == (THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ || access == THREAD_QUERY_INFORMATION /* before Vista */, - "expected THREAD_QUERY_INFORMATION|THREAD_QUERY_LIMITED_INFORMATION, got %#x\n", access); + "expected THREAD_QUERY_INFORMATION|THREAD_QUERY_LIMITED_INFORMATION, got %#lx\n", access); CloseHandle(dup); TerminateThread(thread, 0); @@ -6327,45 +6196,45 @@ static void test_process_access(void) sti.cb = sizeof(sti); SetLastError(0xdeadbeef); ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi); - ok(ret, "CreateProcess() error %d\n", GetLastError()); + ok(ret, "CreateProcess() error %ld\n", GetLastError()); CloseHandle(pi.hThread); process = pi.hProcess; access = get_obj_access(process); - ok(access == PROCESS_ALL_ACCESS_NT4 || access == PROCESS_ALL_ACCESS_VISTA, "expected PROCESS_ALL_ACCESS, got %#x\n", access); + ok(access == PROCESS_ALL_ACCESS_NT4 || access == PROCESS_ALL_ACCESS_VISTA, "expected PROCESS_ALL_ACCESS, got %#lx\n", access); - for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) + for (i = 0; i < ARRAY_SIZE(map); i++) { SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, map[i].generic, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); switch (map[i].generic) { case GENERIC_READ: ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; case GENERIC_WRITE: ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */ || access == (map[i].mapped | PROCESS_SET_LIMITED_INFORMATION) /* win8 */ || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_LIMITED_INFORMATION) /* Win10 Anniversary Update */, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; case GENERIC_EXECUTE: ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE) /* Vista+ */, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; case GENERIC_ALL: ok(access == map[i].mapped || access == PROCESS_ALL_ACCESS_VISTA, - "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; default: - ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); + ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access); break; } @@ -6375,11 +6244,45 @@ static void test_process_access(void) SetLastError( 0xdeadbeef ); ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, PROCESS_QUERY_INFORMATION, FALSE, 0); - ok(ret, "DuplicateHandle error %d\n", GetLastError()); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); access = get_obj_access(dup); ok(access == (PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */ || access == PROCESS_QUERY_INFORMATION /* before Vista */, - "expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#x\n", access); + "expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access); + CloseHandle(dup); + + SetLastError( 0xdeadbeef ); + ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, + PROCESS_VM_OPERATION, FALSE, 0); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); + access = get_obj_access(dup); + ok(access == PROCESS_VM_OPERATION, "unexpected access right %lx\n", access); + CloseHandle(dup); + + SetLastError( 0xdeadbeef ); + ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, + PROCESS_VM_WRITE, FALSE, 0); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); + access = get_obj_access(dup); + ok(access == PROCESS_VM_WRITE, "unexpected access right %lx\n", access); + CloseHandle(dup); + + SetLastError( 0xdeadbeef ); + ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, + PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, 0); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); + access = get_obj_access(dup); + ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_LIMITED_INFORMATION) || + broken(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE)) /* Win8 and before */, + "expected PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access); + CloseHandle(dup); + + SetLastError( 0xdeadbeef ); + ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, + PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, 0); + ok(ret, "DuplicateHandle error %ld\n", GetLastError()); + access = get_obj_access(dup); + ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_READ), "unexpected access right %lx\n", access); CloseHandle(dup); TerminateProcess(process, 0); @@ -6396,7 +6299,7 @@ static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) needed = 0; SetLastError(0xdeadbeef); ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed); - ok(ret, "GetTokenInformation error %d\n", GetLastError()); + ok(ret, "GetTokenInformation error %ld\n", GetLastError()); ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n"); ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type); @@ -6406,7 +6309,7 @@ static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) needed = 0; SetLastError(0xdeadbeef); ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed); - ok(ret, "GetTokenInformation error %d\n", GetLastError()); + ok(ret, "GetTokenInformation error %ld\n", GetLastError()); ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n"); ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil); @@ -6414,7 +6317,7 @@ static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) SetLastError(0xdeadbeef); ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed); ok(!ret, "GetTokenInformation should fail\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n"); @@ -6422,7 +6325,7 @@ static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) SetLastError(0xdeadbeef); ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed); ok(!ret, "GetTokenInformation should fail\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n"); @@ -6430,7 +6333,7 @@ static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) SetLastError(0xdeadbeef); ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed); ok(!ret, "GetTokenInformation should fail\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n"); @@ -6443,18 +6346,18 @@ static void test_kernel_objects_security(void) DWORD ret, token_type; ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token); - ok(ret, "OpenProcessToken error %d\n", GetLastError()); + ok(ret, "OpenProcessToken error %ld\n", GetLastError()); ret = validate_impersonation_token(process_token, &token_type); - ok(token_type == TokenPrimary, "expected TokenPrimary, got %d\n", token_type); + ok(token_type == TokenPrimary, "expected TokenPrimary, got %ld\n", token_type); ok(!ret, "access token should not be an impersonation token\n"); ret = DuplicateToken(process_token, SecurityImpersonation, &token); - ok(ret, "DuplicateToken error %d\n", GetLastError()); + ok(ret, "DuplicateToken error %ld\n", GetLastError()); ret = validate_impersonation_token(token, &token_type); ok(ret, "access token should be a valid impersonation token\n"); - ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %d\n", token_type); + ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %ld\n", token_type); test_mutex_security(token); test_event_security(token); @@ -6484,7 +6387,7 @@ static void test_TokenIntegrityLevel(void) SetLastError(0xdeadbeef); res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); - ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError()); + ok(res, "got %ld with %ld (expected TRUE)\n", res, GetLastError()); SetLastError(0xdeadbeef); res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size); @@ -6497,7 +6400,7 @@ static void test_TokenIntegrityLevel(void) return; } - ok(res, "got %u with %u (expected TRUE)\n", res, GetLastError()); + ok(res, "got %lu with %lu (expected TRUE)\n", res, GetLastError()); if (!res) { CloseHandle(token); @@ -6506,8 +6409,11 @@ static void test_TokenIntegrityLevel(void) tml = (TOKEN_MANDATORY_LABEL*) buffer; ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED), - "got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED)); + "got 0x%lx (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED)); +#ifdef __REACTOS__ // This crashes on Vista, Win7, and Win8.1. + if (GetNTVersion() < _WIN32_WINNT_VISTA || GetNTVersion() >= _WIN32_WINNT_WIN10) +#endif ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), "got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid), debugstr_sid(&medium_level), debugstr_sid(&high_level)); @@ -6515,62 +6421,102 @@ static void test_TokenIntegrityLevel(void) CloseHandle(token); } -static void test_default_dacl_owner_sid(void) +static void test_default_dacl_owner_group_sid(void) { - HANDLE handle; + TOKEN_USER *token_user; + TOKEN_OWNER *token_owner; + TOKEN_PRIMARY_GROUP *token_primary_group; + HANDLE handle, token; BOOL ret, defaulted, present, found; DWORD size, index; SECURITY_DESCRIPTOR *sd; SECURITY_ATTRIBUTES sa; - PSID owner; + PSID owner, group; ACL *dacl; ACCESS_ALLOWED_ACE *ace; - sd = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH ); + ret = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ); + ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError()); + + token_user = get_alloc_token_user( token ); + token_owner = get_alloc_token_owner( token ); + token_primary_group = get_alloc_token_primary_group( token ); + + CloseHandle( token ); + + sd = malloc( SECURITY_DESCRIPTOR_MIN_LENGTH ); ret = InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION ); - ok( ret, "error %u\n", GetLastError() ); + ok( ret, "error %lu\n", GetLastError() ); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = sd; sa.bInheritHandle = FALSE; handle = CreateEventA( &sa, TRUE, TRUE, "test_event" ); - ok( handle != NULL, "error %u\n", GetLastError() ); + ok( handle != NULL, "error %lu\n", GetLastError() ); size = 0; - ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size ); - ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %u\n", GetLastError() ); + ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size ); + ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %lu\n", GetLastError() ); - sd = HeapAlloc( GetProcessHeap(), 0, size ); - ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size ); - ok( ret, "error %u\n", GetLastError() ); + sd = malloc( size ); + ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size ); + ok( ret, "error %lu\n", GetLastError() ); owner = (void *)0xdeadbeef; defaulted = TRUE; ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted ); - ok( ret, "error %u\n", GetLastError() ); + ok( ret, "error %lu\n", GetLastError() ); ok( owner != (void *)0xdeadbeef, "owner not set\n" ); ok( !defaulted, "owner defaulted\n" ); + ok( EqualSid( owner, token_owner->Owner ), "owner shall equal token owner\n" ); + + group = (void *)0xdeadbeef; + defaulted = TRUE; + ret = GetSecurityDescriptorGroup( sd, &group, &defaulted ); + ok( ret, "error %lu\n", GetLastError() ); + ok( group != (void *)0xdeadbeef, "group not set\n" ); + ok( !defaulted, "group defaulted\n" ); + ok( EqualSid( group, token_primary_group->PrimaryGroup ), "group shall equal token primary group\n" ); dacl = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorDacl( sd, &present, &dacl, &defaulted ); - ok( ret, "error %u\n", GetLastError() ); + ok( ret, "error %lu\n", GetLastError() ); ok( present, "dacl not present\n" ); ok( dacl != (void *)0xdeadbeef, "dacl not set\n" ); ok( !defaulted, "dacl defaulted\n" ); index = 0; found = FALSE; - while (pGetAce( dacl, index++, (void **)&ace )) + while (GetAce( dacl, index++, (void **)&ace )) { + ok( ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, + "expected ACCESS_ALLOWED_ACE_TYPE, got %d\n", ace->Header.AceType ); if (EqualSid( &ace->SidStart, owner )) found = TRUE; } ok( found, "owner sid not found in dacl\n" ); - HeapFree( GetProcessHeap(), 0, sa.lpSecurityDescriptor ); - HeapFree( GetProcessHeap(), 0, sd ); + if (!EqualSid( token_user->User.Sid, token_owner->Owner )) + { + index = 0; + found = FALSE; + while (GetAce( dacl, index++, (void **)&ace )) + { + ok( ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, + "expected ACCESS_ALLOWED_ACE_TYPE, got %d\n", ace->Header.AceType ); + if (EqualSid( &ace->SidStart, token_user->User.Sid )) found = TRUE; + } + ok( !found, "DACL shall not reference token user if it is different from token owner\n" ); + } + + free( sa.lpSecurityDescriptor ); + free( sd ); CloseHandle( handle ); + + free( token_primary_group ); + free( token_owner ); + free( token_user ); } static void test_AdjustTokenPrivileges(void) @@ -6597,7 +6543,7 @@ static void test_AdjustTokenPrivileges(void) len = 0xdeadbeef; ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, &len); ok(ret, "got %d\n", ret); - ok(len == 0xdeadbeef, "got length %d\n", len); + ok(len == 0xdeadbeef, "got length %ld\n", len); /* revert */ tp.PrivilegeCount = 1; @@ -6624,34 +6570,34 @@ static void test_AddAce(void) memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld)); ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2); - ok(ret, "InitializeAcl failed: %d\n", GetLastError()); + ok(ret, "InitializeAcl failed: %ld\n", GetLastError()); ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n", acl->AclRevision); ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision); ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision); ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); /* next test succeededs but corrupts ACL */ ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize); - ok(ret, "AddAce failed: %d\n", GetLastError()); + ok(ret, "AddAce failed: %ld\n", GetLastError()); ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n", acl->AclRevision); SetLastError(0xdeadbeef); ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize); ok(!ret, "AddAce succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %ld\n", GetLastError()); } static void test_AddMandatoryAce(void) @@ -6663,13 +6609,13 @@ static void test_AddMandatoryAce(void) static SID_IDENTIFIER_AUTHORITY sia_world = {SECURITY_WORLD_SID_AUTHORITY}; char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd; - BOOL defaulted, present, ret, found, found2; + BOOL defaulted, present, ret; ACL_SIZE_INFORMATION acl_size_info; SYSTEM_MANDATORY_LABEL_ACE *ace; char buffer_acl[256]; ACL *acl = (ACL *)&buffer_acl; SECURITY_ATTRIBUTES sa; - DWORD index, size; + DWORD size; HANDLE handle; SID *everyone; ACL *sacl; @@ -6681,238 +6627,231 @@ static void test_AddMandatoryAce(void) } ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); - ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); + ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError()); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = sd; sa.bInheritHandle = FALSE; handle = CreateEventA(&sa, TRUE, TRUE, "test_event"); - ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError()); + ok(handle != NULL, "CreateEventA failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); sacl = (void *)0xdeadbeef; present = TRUE; ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(!present, "SACL is present\n"); ok(sacl == (void *)0xdeadbeef, "SACL is set\n"); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); CloseHandle(handle); memset(buffer_acl, 0, sizeof(buffer_acl)); ret = InitializeAcl(acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with %u\n", GetLastError()); + ok(ret, "InitializeAcl failed with %lu\n", GetLastError()); SetLastError(0xdeadbeef); ret = pAddMandatoryAce(acl, ACL_REVISION, 0, 0x1234, &low_level); ok(!ret, "AddMandatoryAce succeeded\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER got %u\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER got %lu\n", GetLastError()); ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level); - ok(ret, "AddMandatoryAce failed with %u\n", GetLastError()); + ok(ret, "AddMandatoryAce failed with %lu\n", GetLastError()); - index = 0; - found = FALSE; - while (pGetAce(acl, index++, (void **)&ace)) - { - if (ace->Header.AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue; - ok(ace->Header.AceFlags == 0, "Expected flags 0, got %x\n", ace->Header.AceFlags); - ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, - "Expected mask SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, got %x\n", ace->Mask); - ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n"); - found = TRUE; - } - ok(found, "Could not find mandatory label ace\n"); + ret = GetAce(acl, 0, (void **)&ace); + ok(ret, "got error %lu\n", GetLastError()); + ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType); + ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags); + ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "got mask %#lx\n", ace->Mask); + ok(EqualSid(&ace->SidStart, &low_level), "wrong sid\n"); + + SetLastError(0xdeadbeef); + ret = GetAce(acl, 1, (void **)&ace); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); - ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); handle = CreateEventA(&sa, TRUE, TRUE, "test_event"); - ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError()); + ok(handle != NULL, "CreateEventA failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); sacl = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(present, "SACL not present\n"); ok(sacl != (void *)0xdeadbeef, "SACL not set\n"); ok(!defaulted, "SACL defaulted\n"); - ret = pGetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation); - ok(ret, "GetAclInformation failed with error %u\n", GetLastError()); - ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %u\n", acl_size_info.AceCount); + ret = GetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation); + ok(ret, "GetAclInformation failed with error %lu\n", GetLastError()); + ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %lu\n", acl_size_info.AceCount); - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ret = GetAce(sacl, 0, (void **)&ace); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType); ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags); - ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask); + ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#lx\n", ace->Mask); ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n"); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level); - ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError()); + ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError()); ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); - ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); sacl = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(present, "SACL not present\n"); ok(sacl != (void *)0xdeadbeef, "SACL not set\n"); ok(sacl->AceCount == 2, "Expected 2 ACEs, got %d\n", sacl->AceCount); ok(!defaulted, "SACL defaulted\n"); - index = 0; - found = found2 = FALSE; - while (pGetAce(sacl, index++, (void **)&ace)) - { - if (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) - { - if (EqualSid(&ace->SidStart, &low_level)) - { - found = TRUE; - ok(!ace->Header.AceFlags, "Expected 0 as flags, got %#x\n", ace->Header.AceFlags); - ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, - "Expected SYSTEM_MANDATORY_LABEL_NO_WRITE_UP as mask, got %#x\n", ace->Mask); - } - if (EqualSid(&ace->SidStart, &medium_level)) - { - found2 = TRUE; - ok(!ace->Header.AceFlags, "Expected 0 as flags, got %#x\n", ace->Header.AceFlags); - ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, - "Expected SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP as mask, got %#x\n", ace->Mask); - } - } - } - ok(found, "Could not find low mandatory label\n"); - ok(found2, "Could not find medium mandatory label\n"); + ret = GetAce(acl, 0, (void **)&ace); + ok(ret, "got error %lu\n", GetLastError()); + ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType); + ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags); + ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "got mask %#lx\n", ace->Mask); + ok(EqualSid(&ace->SidStart, &low_level), "wrong sid\n"); - HeapFree(GetProcessHeap(), 0, sd2); + ret = GetAce(acl, 1, (void **)&ace); + ok(ret, "got error %lu\n", GetLastError()); + ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType); + ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags); + ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, "got mask %#lx\n", ace->Mask); + ok(EqualSid(&ace->SidStart, &medium_level), "wrong sid\n"); + + SetLastError(0xdeadbeef); + ret = GetAce(acl, 2, (void **)&ace); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); + + free(sd2); ret = SetSecurityDescriptorSacl(sd, FALSE, NULL, FALSE); - ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); - ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); sacl = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(present, "SACL not present\n"); ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n"); ok(!defaulted, "SACL defaulted\n"); ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); ret = InitializeAcl(acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); + ok(ret, "InitializeAcl failed with error %lu\n", GetLastError()); ret = pAddMandatoryAce(acl, ACL_REVISION3, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level); - ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError()); + ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError()); ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); - ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); - ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); sacl = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(present, "SACL not present\n"); ok(sacl != (void *)0xdeadbeef, "SACL not set\n"); ok(sacl->AclRevision == ACL_REVISION3, "Expected revision 3, got %d\n", sacl->AclRevision); ok(!defaulted, "SACL defaulted\n"); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); ret = InitializeAcl(acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); + ok(ret, "InitializeAcl failed with error %lu\n", GetLastError()); ret = AllocateAndInitializeSid(&sia_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (void **)&everyone); - ok(ret, "AllocateAndInitializeSid failed with error %u\n", GetLastError()); + ok(ret, "AllocateAndInitializeSid failed with error %lu\n", GetLastError()); ret = AddAccessAllowedAce(acl, ACL_REVISION, KEY_READ, everyone); - ok(ret, "AddAccessAllowedAce failed with error %u\n", GetLastError()); + ok(ret, "AddAccessAllowedAce failed with error %lu\n", GetLastError()); ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); - ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); - ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); sacl = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(present, "SACL not present\n"); ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n"); ok(!defaulted, "SACL defaulted\n"); ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); FreeSid(everyone); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); CloseHandle(handle); } @@ -6945,34 +6884,34 @@ static void test_system_security_access(void) CloseHandle( token ); return; } - todo_wine ok( res == ERROR_PRIVILEGE_NOT_HELD, "got %d\n", res ); + todo_wine ok( res == ERROR_PRIVILEGE_NOT_HELD, "got %ld\n", res ); priv.PrivilegeCount = 1; priv.Privileges[0].Luid = luid; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - priv_prev = HeapAlloc( GetProcessHeap(), 0, len ); + priv_prev = malloc( len ); ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len ); - ok( ret, "got %u\n", GetLastError()); + ok( ret, "got %lu\n", GetLastError()); res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL ); if (res == ERROR_PRIVILEGE_NOT_HELD) { win_skip( "privilege not held\n" ); - HeapFree( GetProcessHeap(), 0, priv_prev ); + free( priv_prev ); CloseHandle( token ); return; } - ok( !res, "got %d\n", res ); + ok( !res, "got %ld\n", res ); /* restore privileges */ ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL ); - ok( ret, "got %u\n", GetLastError() ); - HeapFree( GetProcessHeap(), 0, priv_prev ); + ok( ret, "got %lu\n", GetLastError() ); + free( priv_prev ); /* privilege is checked on access */ err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); - todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", err ); + todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD || err == ERROR_ACCESS_DENIED, "got %lu\n", err ); if (err == ERROR_SUCCESS) LocalFree( sd ); @@ -6980,60 +6919,61 @@ static void test_system_security_access(void) priv.Privileges[0].Luid = luid; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - priv_prev = HeapAlloc( GetProcessHeap(), 0, len ); + priv_prev = malloc( len ); ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len ); - ok( ret, "got %u\n", GetLastError()); + ok( ret, "got %lu\n", GetLastError()); err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); - ok( err == ERROR_SUCCESS, "got %u\n", err ); + ok( err == ERROR_SUCCESS, "got %lu\n", err ); RegCloseKey( hkey ); LocalFree( sd ); /* handle created without ACCESS_SYSTEM_SECURITY, privilege held */ res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL ); - ok( res == ERROR_SUCCESS, "got %d\n", res ); + ok( res == ERROR_SUCCESS, "got %ld\n", res ); sd = NULL; err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); - todo_wine ok( err == ERROR_SUCCESS, "got %u\n", err ); + todo_wine ok( err == ERROR_SUCCESS, "got %lu\n", err ); RegCloseKey( hkey ); LocalFree( sd ); /* restore privileges */ ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL ); - ok( ret, "got %u\n", GetLastError() ); - HeapFree( GetProcessHeap(), 0, priv_prev ); + ok( ret, "got %lu\n", GetLastError() ); + free( priv_prev ); /* handle created without ACCESS_SYSTEM_SECURITY, privilege not held */ res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL ); - ok( res == ERROR_SUCCESS, "got %d\n", res ); + ok( res == ERROR_SUCCESS, "got %ld\n", res ); err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); - todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", err ); + ok( err == ERROR_PRIVILEGE_NOT_HELD || err == ERROR_ACCESS_DENIED, "got %lu\n", err ); RegCloseKey( hkey ); res = RegDeleteKeyW( HKEY_LOCAL_MACHINE, testkeyW ); - ok( !res, "got %d\n", res ); + ok( !res, "got %ld\n", res ); CloseHandle( token ); } static void test_GetWindowsAccountDomainSid(void) { +#ifdef __REACTOS__ + char *user, buffer1[SECURITY_MAX_SID_SIZE]; + PSID domain_sid = (PSID *)&buffer1; +#else char *user, buffer1[SECURITY_MAX_SID_SIZE], buffer2[SECURITY_MAX_SID_SIZE]; SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY }; PSID domain_sid = (PSID *)&buffer1; PSID domain_sid2 = (PSID *)&buffer2; +#endif DWORD sid_size; PSID user_sid; HANDLE token; BOOL bret = TRUE; +#ifndef __REACTOS__ int i; - - if (!pGetWindowsAccountDomainSid) - { - win_skip("GetWindowsAccountDomainSid not available\n"); - return; - } +#endif if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) { @@ -7048,53 +6988,55 @@ static void test_GetWindowsAccountDomainSid(void) bret = GetTokenInformation(token, TokenUser, NULL, 0, &sid_size); ok(!bret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); - user = HeapAlloc(GetProcessHeap(), 0, sid_size); + "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); + user = malloc(sid_size); bret = GetTokenInformation(token, TokenUser, user, sid_size, &sid_size); - ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); + ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError()); CloseHandle(token); user_sid = ((TOKEN_USER *)user)->User.Sid; SetLastError(0xdeadbeef); - bret = pGetWindowsAccountDomainSid(0, 0, 0); + bret = GetWindowsAccountDomainSid(0, 0, 0); ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); - ok(GetLastError() == ERROR_INVALID_SID, "expected ERROR_INVALID_SID, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_SID, "expected ERROR_INVALID_SID, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); - bret = pGetWindowsAccountDomainSid(user_sid, 0, 0); + bret = GetWindowsAccountDomainSid(user_sid, 0, 0); ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); sid_size = SECURITY_MAX_SID_SIZE; SetLastError(0xdeadbeef); - bret = pGetWindowsAccountDomainSid(user_sid, 0, &sid_size); + bret = GetWindowsAccountDomainSid(user_sid, 0, &sid_size); ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size); SetLastError(0xdeadbeef); - bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, 0); + bret = GetWindowsAccountDomainSid(user_sid, domain_sid, 0); ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); sid_size = 1; SetLastError(0xdeadbeef); - bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size); + bret = GetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size); ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size); sid_size = SECURITY_MAX_SID_SIZE; - bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size); - ok(bret, "GetWindowsAccountDomainSid failed with error %d\n", GetLastError()); - ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size); + bret = GetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size); + ok(bret, "GetWindowsAccountDomainSid failed with error %ld\n", GetLastError()); + ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size); +#ifndef __REACTOS__ // This crashes on WS03, Vista, Win7, and Win8.1. InitializeSid(domain_sid2, &domain_ident, 4); for (i = 0; i < 4; i++) *GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i); ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n", debugstr_sid(domain_sid), debugstr_sid(domain_sid2)); +#endif - HeapFree(GetProcessHeap(), 0, user); + free(user); } static void test_GetSidIdentifierAuthority(void) @@ -7104,12 +7046,6 @@ static void test_GetSidIdentifierAuthority(void) PSID_IDENTIFIER_AUTHORITY id; BOOL ret; - if (!pGetSidIdentifierAuthority) - { - win_skip("GetSidIdentifierAuthority not available\n"); - return; - } - memset(buffer, 0xcc, sizeof(buffer)); ret = IsValidSid(authority_sid); ok(!ret, "expected FALSE, got %u\n", ret); @@ -7117,12 +7053,12 @@ static void test_GetSidIdentifierAuthority(void) SetLastError(0xdeadbeef); id = GetSidIdentifierAuthority(authority_sid); ok(id != NULL, "got NULL pointer as identifier authority\n"); - ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", GetLastError()); SetLastError(0xdeadbeef); id = GetSidIdentifierAuthority(NULL); ok(id != NULL, "got NULL pointer as identifier authority\n"); - ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError()); + ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", GetLastError()); } static void test_pseudo_tokens(void) @@ -7133,10 +7069,10 @@ static void test_pseudo_tokens(void) BOOL ret; ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); - ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError()); memset(&statistics1, 0x11, sizeof(statistics1)); ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen); - ok(ret, "GetTokenInformation failed with %u\n", GetLastError()); + ok(ret, "GetTokenInformation failed with %lu\n", GetLastError()); CloseHandle(token); /* test GetCurrentProcessToken() */ @@ -7145,7 +7081,7 @@ static void test_pseudo_tokens(void) ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics, &statistics2, sizeof(statistics2), &retlen); ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE), - "GetTokenInformation failed with %u\n", GetLastError()); + "GetTokenInformation failed with %lu\n", GetLastError()); if (ret) ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n"); else @@ -7157,7 +7093,7 @@ static void test_pseudo_tokens(void) ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics, &statistics2, sizeof(statistics2), &retlen); ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE), - "GetTokenInformation failed with %u\n", GetLastError()); + "GetTokenInformation failed with %lu\n", GetLastError()); if (ret) ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n"); else @@ -7166,14 +7102,14 @@ static void test_pseudo_tokens(void) SetLastError(0xdeadbeef); ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); ok(!ret, "OpenThreadToken should have failed\n"); - ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); + ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %lu\n", GetLastError()); /* test GetCurrentThreadToken() */ SetLastError(0xdeadbeef); ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics, &statistics2, sizeof(statistics2), &retlen); todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE), - "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); + "Expected ERROR_NO_TOKEN, got %lu\n", GetLastError()); } static void test_maximum_allowed(void) @@ -7196,25 +7132,25 @@ static void test_maximum_allowed(void) } ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); - ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError()); + ok(ret, "InitializeSecurityDescriptor failed with %lu\n", GetLastError()); memset(buffer_acl, 0, sizeof(buffer_acl)); ret = InitializeAcl(acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with %u\n", GetLastError()); + ok(ret, "InitializeAcl failed with %lu\n", GetLastError()); ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE); - ok(ret, "SetSecurityDescriptorDacl failed with %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorDacl failed with %lu\n", GetLastError()); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = sd; sa.bInheritHandle = FALSE; handle = pCreateEventExA(&sa, NULL, 0, MAXIMUM_ALLOWED | 0x4); - ok(handle != NULL, "CreateEventExA failed with error %u\n", GetLastError()); + ok(handle != NULL, "CreateEventExA failed with error %lu\n", GetLastError()); mask = get_obj_access(handle); - ok(mask == EVENT_ALL_ACCESS, "Expected %x, got %x\n", EVENT_ALL_ACCESS, mask); + ok(mask == EVENT_ALL_ACCESS, "Expected %x, got %lx\n", EVENT_ALL_ACCESS, mask); CloseHandle(handle); } -static void test_token_label(void) +static void check_token_label(HANDLE token, DWORD *level, BOOL sacl_inherited) { static SID medium_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, {SECURITY_MANDATORY_MEDIUM_RID}}; @@ -7226,72 +7162,165 @@ static void test_token_label(void) SECURITY_DESCRIPTOR *sd; ACL *sacl = NULL, *dacl; DWORD size, revision; - HANDLE token; char *str; SID *sid; - ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER, &token); - ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); - ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd = HeapAlloc(GetProcessHeap(), 0, size); + sd = malloc(size); ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); ret = GetSecurityDescriptorControl(sd, &control, &revision); - ok(ret, "GetSecurityDescriptorControl failed with error %u\n", GetLastError()); - todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT) || - broken(control == SE_SELF_RELATIVE) /* WinXP, Win2003 */, - "Unexpected security descriptor control %#x\n", control); - ok(revision == 1, "Unexpected security descriptor revision %u\n", revision); + ok(ret, "GetSecurityDescriptorControl failed with error %lu\n", GetLastError()); + if (sacl_inherited) + todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT), + "Unexpected security descriptor control %#x\n", control); + else + todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_PRESENT), + "Unexpected security descriptor control %#x\n", control); + ok(revision == 1, "Unexpected security descriptor revision %lu\n", revision); sid = (void *)0xdeadbeef; defaulted = TRUE; ret = GetSecurityDescriptorOwner(sd, (void **)&sid, &defaulted); - ok(ret, "GetSecurityDescriptorOwner failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorOwner failed with error %lu\n", GetLastError()); ok(!sid, "Owner present\n"); ok(!defaulted, "Owner defaulted\n"); sid = (void *)0xdeadbeef; defaulted = TRUE; ret = GetSecurityDescriptorGroup(sd, (void **)&sid, &defaulted); - ok(ret, "GetSecurityDescriptorGroup failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorGroup failed with error %lu\n", GetLastError()); ok(!sid, "Group present\n"); ok(!defaulted, "Group defaulted\n"); ret = GetSecurityDescriptorSacl(sd, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present || broken(!present) /* WinXP, Win2003 */, "No SACL in the security descriptor\n"); - ok(sacl || broken(!sacl) /* WinXP, Win2003 */, "NULL SACL in the security descriptor\n"); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); + ok(present, "No SACL in the security descriptor\n"); + ok(!!sacl, "NULL SACL in the security descriptor\n"); + ok(!defaulted, "SACL defaulted\n"); + ok(sacl->AceCount == 1, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); - if (present) - { - ok(!defaulted, "SACL defaulted\n"); - ok(sacl->AceCount == 1, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); + ret = GetAce(sacl, 0, (void **)&ace); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, + "Unexpected ACE type %#x\n", ace->Header.AceType); + ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags); + ok(ace->Header.AceSize, "Unexpected ACE size %u\n", ace->Header.AceSize); + ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#lx\n", ace->Mask); - ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace->Header.AceType); - ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags); - ok(ace->Header.AceSize, "Unexpected ACE size %u\n", ace->Header.AceSize); - ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask); - - sid = (SID *)&ace->SidStart; - ConvertSidToStringSidA(sid, &str); - ok(EqualSid(sid, &medium_sid) || EqualSid(sid, &high_sid), "Got unexpected SID %s\n", str); - LocalFree(str); - } + sid = (SID *)&ace->SidStart; + ConvertSidToStringSidA(sid, &str); + ok(EqualSid(sid, &medium_sid) || EqualSid(sid, &high_sid), "Got unexpected SID %s\n", str); + *level = sid->SubAuthority[0]; + LocalFree(str); ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted); - ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); todo_wine ok(!present, "DACL present\n"); - HeapFree(GetProcessHeap(), 0, sd); + free(sd); +} + +static void test_token_label(void) +{ + SID low_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, + {SECURITY_MANDATORY_LOW_RID}}; + char sacl_buffer[50]; + SECURITY_ATTRIBUTES attr = {.nLength = sizeof(SECURITY_ATTRIBUTES)}; + ACL *sacl = (ACL *)sacl_buffer; + TOKEN_LINKED_TOKEN linked; + DWORD level, level2, size; + PSECURITY_DESCRIPTOR sd; + HANDLE token, token2; + BOOL ret; + + if (!pAddMandatoryAce) + { + win_skip("Mandatory integrity control is not supported.\n"); + return; + } + + ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL | TOKEN_QUERY | TOKEN_DUPLICATE, &token); + ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError()); + + check_token_label(token, &level, TRUE); + + ret = DuplicateTokenEx(token, READ_CONTROL, NULL, SecurityAnonymous, TokenPrimary, &token2); + ok(ret, "Failed to duplicate token, error %lu\n", GetLastError()); + + check_token_label(token2, &level2, TRUE); + ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2); + + CloseHandle(token2); + + ret = DuplicateTokenEx(token, READ_CONTROL, NULL, SecurityImpersonation, TokenImpersonation, &token2); + ok(ret, "Failed to duplicate token, error %lu\n", GetLastError()); + + check_token_label(token2, &level2, TRUE); + ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2); + + CloseHandle(token2); + + /* Any label set in the SD when calling DuplicateTokenEx() is ignored. */ + + ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError()); + + sd = malloc(size); + ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); + + InitializeAcl(sacl, sizeof(sacl_buffer), ACL_REVISION); +#ifdef __REACTOS__ + pAddMandatoryAce(sacl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_sid); +#else + AddMandatoryAce(sacl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_sid); +#endif + SetSecurityDescriptorSacl(sd, TRUE, sacl, FALSE); + + attr.lpSecurityDescriptor = sd; + ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, &attr, SecurityImpersonation, TokenImpersonation, &token2); + ok(ret, "Failed to duplicate token, error %lu\n", GetLastError()); + + check_token_label(token2, &level2, TRUE); + ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2); + + /* Trying to set a SD on the token also claims success but has no effect. */ + + ret = SetKernelObjectSecurity(token2, LABEL_SECURITY_INFORMATION, sd); + ok(ret, "Failed to set SD, error %lu\n", GetLastError()); + + check_token_label(token2, &level2, FALSE); + ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2); + + free(sd); + + /* Test the linked token. */ + +#ifdef __REACTOS__ + /* This test crashes on Vista and Win7 */ + if (GetNTVersion() == _WIN32_WINNT_VISTA || GetNTVersion() == _WIN32_WINNT_WIN7) { + skip("Linked token tests crash on Vista and Win7.\n"); + } + else { +#endif + ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size); + ok(ret, "Failed to get linked token, error %lu\n", GetLastError()); + + check_token_label(linked.LinkedToken, &level2, TRUE); + ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2); + + CloseHandle(linked.LinkedToken); +#ifdef __REACTOS__ + } +#endif + CloseHandle(token); } @@ -7299,19 +7328,13 @@ static void test_token_security_descriptor(void) { static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, {SECURITY_MANDATORY_LOW_RID}}; - static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, - {SECURITY_MANDATORY_MEDIUM_RID}}; - static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, - {SECURITY_MANDATORY_HIGH_RID}}; char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; - SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2, *sd3; + SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2; char buffer_acl[256], buffer[MAX_PATH]; - ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child, *sacl; + ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child; BOOL defaulted, present, ret, found; - HANDLE token, token2, token3, token4, token5, token6; + HANDLE token, token2, token3; EXPLICIT_ACCESSW exp_access; - TOKEN_MANDATORY_LABEL *tml; - BYTE buffer_integrity[64]; PROCESS_INFORMATION info; DWORD size, index, retd; ACCESS_ALLOWED_ACE *ace; @@ -7319,119 +7342,109 @@ static void test_token_security_descriptor(void) STARTUPINFOA startup; PSID psid; - if (!pDuplicateTokenEx || !pConvertStringSidToSidA || !pAddAccessAllowedAceEx || !pGetAce - || !pSetEntriesInAclW) - { - win_skip("Some functions not available\n"); - return; - } - /* Test whether we can create tokens with security descriptors */ ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); - ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError()); ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); - ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); + ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError()); memset(buffer_acl, 0, sizeof(buffer_acl)); ret = InitializeAcl(acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); + ok(ret, "InitializeAcl failed with error %lu\n", GetLastError()); - ret = pConvertStringSidToSidA("S-1-5-6", &psid); - ok(ret, "ConvertStringSidToSidA failed with error %u\n", GetLastError()); + ret = ConvertStringSidToSidA("S-1-5-6", &psid); + ok(ret, "ConvertStringSidToSidA failed with error %lu\n", GetLastError()); - ret = pAddAccessAllowedAceEx(acl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid); - ok(ret, "AddAccessAllowedAceEx failed with error %u\n", GetLastError()); + ret = AddAccessAllowedAceEx(acl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid); + ok(ret, "AddAccessAllowedAceEx failed with error %lu\n", GetLastError()); ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE); - ok(ret, "SetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = sd; sa.bInheritHandle = FALSE; - ret = pDuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2); - ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); + ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2); + ok(ret, "DuplicateTokenEx failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); acl2 = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted); - ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); ok(present, "acl2 not present\n"); ok(acl2 != (void *)0xdeadbeef, "acl2 not set\n"); ok(acl2->AceCount == 1, "Expected 1 ACE, got %d\n", acl2->AceCount); ok(!defaulted, "acl2 defaulted\n"); - ret = pGetAce(acl2, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ret = GetAce(acl2, 0, (void **)&ace); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok(ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType); ok(EqualSid(&ace->SidStart, psid), "Expected access allowed ACE\n"); ok(ace->Header.AceFlags == NO_PROPAGATE_INHERIT_ACE, "Expected NO_PROPAGATE_INHERIT_ACE as flags, got %x\n", ace->Header.AceFlags); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); /* Duplicate token without security attributes. * Tokens do not inherit the security descriptor in DuplicateToken. */ - ret = pDuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3); - ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); + ret = DuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3); + ok(ret, "DuplicateTokenEx failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); acl2 = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted); - ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); ok(present, "DACL not present\n"); - if (present) + ok(acl2 != (void *)0xdeadbeef, "DACL not set\n"); + ok(!defaulted, "DACL defaulted\n"); + + index = 0; + found = FALSE; + while (GetAce(acl2, index++, (void **)&ace)) { - ok(acl2 != (void *)0xdeadbeef, "DACL not set\n"); - ok(!defaulted, "DACL defaulted\n"); - - index = 0; - found = FALSE; - while (pGetAce(acl2, index++, (void **)&ace)) - { - if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid)) - found = TRUE; - } - ok(!found, "Access allowed ACE was inherited\n"); + if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid)) + found = TRUE; } + ok(!found, "Access allowed ACE was inherited\n"); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); /* When creating a child process, the process does inherit the token of * the parent but not the DACL of the token */ ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd2 = HeapAlloc(GetProcessHeap(), 0, size); + sd2 = malloc(size); ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd2, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); acl2 = (void *)0xdeadbeef; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted); - ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); ok(present, "DACL not present\n"); ok(acl2 != (void *)0xdeadbeef, "DACL not set\n"); ok(!defaulted, "DACL defaulted\n"); @@ -7445,300 +7458,37 @@ static void test_token_security_descriptor(void) exp_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; exp_access.Trustee.ptstrName = (void*)psid; - retd = pSetEntriesInAclW(1, &exp_access, acl2, &acl_child); - ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", retd); + retd = SetEntriesInAclW(1, &exp_access, acl2, &acl_child); + ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", retd); memset(sd, 0, sizeof(buffer_sd)); ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); - ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); + ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError()); ret = SetSecurityDescriptorDacl(sd, TRUE, acl_child, FALSE); - ok(ret, "SetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd); - ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError()); /* The security label is also not inherited */ if (pAddMandatoryAce) { - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), - "Expected medium or high integrity level\n"); - - if (EqualSid(tml->Label.Sid, &high_level)) - { - DWORD process_id; - HANDLE process; - HWND shell; - - /* This test tries to get a medium token and then impersonates this token. The - * idea is to check whether the sd label of a newly created token depends on the - * current active token or the integrity level of the newly created token. */ - - /* Steal process token of the explorer.exe process */ - shell = GetShellWindow(); - todo_wine ok(shell != NULL, "Failed to get shell window\n"); - if (!shell) shell = GetDesktopWindow(); /* FIXME: Workaround for Wine */ - ok(GetWindowThreadProcessId(shell, &process_id), - "Failed to get process id of shell window: %u\n", GetLastError()); - process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process_id); - ok(process != NULL, "Failed to open process: %u\n", GetLastError()); - ok(OpenProcessToken(process, TOKEN_ALL_ACCESS, &token4), - "Failed to open process token: %u\n", GetLastError()); - CloseHandle(process); - - /* Check TokenIntegrityLevel and LABEL_SECURITY_INFORMATION of explorer.exe token */ - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); - - size = 0; - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); - - sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - sacl = NULL; - ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "No SACL in the security descriptor\n"); - ok(sacl != NULL, "NULL SACL in the security descriptor\n"); - - if (sacl) - { - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace->Header.AceType); - ok(EqualSid(&ace->SidStart, &medium_level), - "Expected medium integrity level\n"); - } - - HeapFree(GetProcessHeap(), 0, sd3); - - /* Start child process with the explorer.exe token */ - memset(&startup, 0, sizeof(startup)); - startup.cb = sizeof(startup); - startup.dwFlags = STARTF_USESHOWWINDOW; - startup.wShowWindow = SW_SHOWNORMAL; - - sprintf(buffer, "%s tests/security.c test_token_sd_medium", myARGV[0]); - ret = CreateProcessAsUserA(token4, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); - ok(ret || GetLastError() == ERROR_PRIVILEGE_NOT_HELD, - "CreateProcess failed with error %u\n", GetLastError()); - if (ret) - { - winetest_wait_child_process(info.hProcess); - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - } - else - win_skip("Skipping test for creating process with medium level token\n"); - - ret = DuplicateTokenEx(token4, 0, NULL, SecurityImpersonation, TokenImpersonation, &token5); - ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); - ret = SetThreadToken(NULL, token5); - ok(ret, "SetThreadToken failed with error %u\n", GetLastError()); - CloseHandle(token4); - - /* Restrict current process token while impersonating a medium integrity token */ - ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token6); - ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError()); - - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token6, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n"); - - size = 0; - ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); - - sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - sacl = NULL; - ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "No SACL in the security descriptor\n"); - ok(sacl != NULL, "NULL SACL in the security descriptor\n"); - - if (sacl) - { - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace->Header.AceType); - ok(EqualSid(&ace->SidStart, &medium_level), - "Expected medium integrity level\n"); - } - - HeapFree(GetProcessHeap(), 0, sd3); - RevertToSelf(); - CloseHandle(token5); - - /* Start child process with the restricted token */ - sprintf(buffer, "%s tests/security.c test_token_sd_restricted", myARGV[0]); - ret = CreateProcessAsUserA(token6, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); - ok(ret, "CreateProcess failed with error %u\n", GetLastError()); - winetest_wait_child_process(info.hProcess); - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - CloseHandle(token6); - - /* DuplicateTokenEx should assign security label even when SA points to empty SD */ - memset(sd, 0, sizeof(buffer_sd)); - ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); - ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); - - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = sd; - sa.bInheritHandle = FALSE; - - ret = DuplicateTokenEx(token, 0, &sa, 0, TokenPrimary, &token6); - ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); - - size = 0; - ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); - - sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - sacl = NULL; - ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "No SACL in the security descriptor\n"); - ok(sacl != NULL, "NULL SACL in the security descriptor\n"); - - if (sacl) - { - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace->Header.AceType); - ok(EqualSid(&ace->SidStart, &high_level), - "Expected high integrity level\n"); - } - - HeapFree(GetProcessHeap(), 0, sd3); - CloseHandle(token6); - } - else - skip("Skipping test, running without admin rights\n"); - ret = InitializeAcl(acl, 256, ACL_REVISION); - ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); + ok(ret, "InitializeAcl failed with error %lu\n", GetLastError()); ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level); - ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError()); + ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError()); memset(sd, 0, sizeof(buffer_sd)); ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); - ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); + ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError()); ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); - ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd); - ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); - - /* changing the label of the security descriptor does not change the integrity level of the token itself */ - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), - "Expected medium or high integrity level\n"); - - /* restricting / duplicating a token resets the mandatory sd label */ - ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token4); - ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError()); - - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), - "Expected medium or high integrity level\n"); - - size = 0; - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); - - sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "No SACL in the security descriptor\n"); - ok(sacl != NULL, "NULL SACL in the security descriptor\n"); - - if (sacl) - { - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace->Header.AceType); - ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level), - "Low integrity level should not have been inherited\n"); - } - - HeapFree(GetProcessHeap(), 0, sd3); - CloseHandle(token4); - - ret = DuplicateTokenEx(token, 0, NULL, 0, TokenPrimary, &token4); - ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); - - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL*) buffer_integrity; - ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), - "Expected medium or high integrity level\n"); - - size = 0; - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); - - sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - sacl = NULL; - ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "No SACL in the security descriptor\n"); - ok(sacl != NULL, "NULL SACL in the security descriptor\n"); - - if (sacl) - { - ret = pGetAce(sacl, 0, (void **)&ace); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace->Header.AceType); - ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level), - "Low integrity level should not have been inherited\n"); - } - - HeapFree(GetProcessHeap(), 0, sd3); - CloseHandle(token4); + ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError()); } else win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); @@ -7749,15 +7499,15 @@ static void test_token_security_descriptor(void) startup.dwFlags = STARTF_USESHOWWINDOW; startup.wShowWindow = SW_SHOWNORMAL; - sprintf(buffer, "%s tests/security.c test_token_sd", myARGV[0]); + sprintf(buffer, "%s security test_token_sd", myARGV[0]); ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); - ok(ret, "CreateProcess failed with error %u\n", GetLastError()); - winetest_wait_child_process(info.hProcess); + ok(ret, "CreateProcess failed with error %lu\n", GetLastError()); + wait_child_process(info.hProcess); CloseHandle(info.hProcess); CloseHandle(info.hThread); LocalFree(acl_child); - HeapFree(GetProcessHeap(), 0, sd2); + free(sd2); LocalFree(psid); CloseHandle(token3); @@ -7778,25 +7528,25 @@ static void test_child_token_sd(void) PSID psid; ACL *acl; - ret = pConvertStringSidToSidA("S-1-5-6", &psid); - ok(ret, "ConvertStringSidToSidA failed with error %u\n", GetLastError()); + ret = ConvertStringSidToSidA("S-1-5-6", &psid); + ok(ret, "ConvertStringSidToSidA failed with error %lu\n", GetLastError()); ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); - ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); + ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError()); ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd = HeapAlloc(GetProcessHeap(), 0, size); + sd = malloc(size); ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); acl = NULL; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted); - ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); ok(present, "DACL not present\n"); ok(acl && acl != (void *)0xdeadbeef, "Got invalid DACL\n"); ok(!defaulted, "DACL defaulted\n"); @@ -7804,13 +7554,14 @@ static void test_child_token_sd(void) ok(acl->AceCount, "Expected at least one ACE\n"); for (i = 0; i < acl->AceCount; i++) { - ok(pGetAce(acl, i, (void **)&acc_ace), "GetAce failed with error %u\n", GetLastError()); + ret = GetAce(acl, i, (void **)&acc_ace); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok(acc_ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE || !EqualSid(&acc_ace->SidStart, psid), "ACE inherited from the parent\n"); } LocalFree(psid); - HeapFree(GetProcessHeap(), 0, sd); + free(sd); if (!pAddMandatoryAce) { @@ -7820,139 +7571,29 @@ static void test_child_token_sd(void) ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); + "Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError()); - sd = HeapAlloc(GetProcessHeap(), 0, size); + sd = malloc(size); ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); + ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError()); acl = NULL; present = FALSE; defaulted = TRUE; ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError()); ok(present, "SACL not present\n"); ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n"); ok(!defaulted, "SACL defaulted\n"); ok(acl->AceCount == 1, "Expected exactly one ACE\n"); - ret = pGetAce(acl, 0, (void **)&ace_label); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ret = GetAce(acl, 0, (void **)&ace_label); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace_label->Header.AceType); ok(!EqualSid(&ace_label->SidStart, &low_level), "Low integrity level should not have been inherited\n"); - HeapFree(GetProcessHeap(), 0, sd); -} - -static void test_child_token_sd_restricted(void) -{ - static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, - {SECURITY_MANDATORY_HIGH_RID}}; - SYSTEM_MANDATORY_LABEL_ACE *ace_label; - BOOL ret, present, defaulted; - TOKEN_MANDATORY_LABEL *tml; - BYTE buffer_integrity[64]; - SECURITY_DESCRIPTOR *sd; - HANDLE token; - DWORD size; - ACL *acl; - - if (!pAddMandatoryAce) - { - win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); - return; - } - - ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); - ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); - - ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); - - sd = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - acl = NULL; - present = FALSE; - defaulted = TRUE; - ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "SACL not present\n"); - ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n"); - ok(!defaulted, "SACL defaulted\n"); - ok(acl->AceCount == 1, "Expected exactly one ACE\n"); - ret = pGetAce(acl, 0, (void **)&ace_label); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace_label->Header.AceType); - ok(EqualSid(&ace_label->SidStart, &high_level), - "Expected high integrity level\n"); - - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n"); - - HeapFree(GetProcessHeap(), 0, sd); -} - -static void test_child_token_sd_medium(void) -{ - static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, - {SECURITY_MANDATORY_MEDIUM_RID}}; - SYSTEM_MANDATORY_LABEL_ACE *ace_label; - BOOL ret, present, defaulted; - TOKEN_MANDATORY_LABEL *tml; - BYTE buffer_integrity[64]; - SECURITY_DESCRIPTOR *sd; - HANDLE token; - DWORD size; - ACL *acl; - - if (!pAddMandatoryAce) - { - win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); - return; - } - - ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); - ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); - - ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); - - sd = HeapAlloc(GetProcessHeap(), 0, size); - ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); - ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); - - acl = NULL; - present = FALSE; - defaulted = TRUE; - ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); - ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); - ok(present, "SACL not present\n"); - ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n"); - ok(!defaulted, "SACL defaulted\n"); - ok(acl->AceCount == 1, "Expected exactly one ACE\n"); - ret = pGetAce(acl, 0, (void **)&ace_label); - ok(ret, "GetAce failed with error %u\n", GetLastError()); - ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, - "Unexpected ACE type %#x\n", ace_label->Header.AceType); - ok(EqualSid(&ace_label->SidStart, &medium_level), - "Expected medium integrity level\n"); - - memset(buffer_integrity, 0, sizeof(buffer_integrity)); - ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); - ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); - tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; - ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); - - HeapFree(GetProcessHeap(), 0, sd); + free(sd); } static void test_GetExplicitEntriesFromAclW(void) @@ -7967,46 +7608,28 @@ static void test_GetExplicitEntriesFromAclW(void) ULONG count; DWORD res; - if (!pGetExplicitEntriesFromAclW) - { - win_skip("GetExplicitEntriesFromAclW is not available\n"); - return; - } - - if (!pSetEntriesInAclW) - { - win_skip("SetEntriesInAclW is not available\n"); - return; - } - - old_acl = HeapAlloc(GetProcessHeap(), 0, 256); + old_acl = malloc(256); res = InitializeAcl(old_acl, 256, ACL_REVISION); - if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) - { - win_skip("ACLs not implemented - skipping tests\n"); - HeapFree(GetProcessHeap(), 0, old_acl); - return; - } - ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + ok(res, "InitializeAcl failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &users_sid); - ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError()); res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, users_sid); - ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); access2 = NULL; - res = pGetExplicitEntriesFromAclW(old_acl, &count, &access2); - ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); - ok(count == 1, "Expected count == 1, got %d\n", count); + res = GetExplicitEntriesFromAclW(old_acl, &count, &access2); + ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError()); + ok(count == 1, "Expected count == 1, got %ld\n", count); ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); - ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %d\n", access2[0].grfAccessPermissions); + ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %ld\n", access2[0].grfAccessPermissions); ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); - ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); + ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance); ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n"); LocalFree(access2); @@ -8019,79 +7642,113 @@ static void test_GetExplicitEntriesFromAclW(void) access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; access.Trustee.TrusteeForm = TRUSTEE_IS_SID; access.Trustee.ptstrName = everyone_sid; - res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &access, old_acl, &new_acl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(new_acl != NULL, "returned acl was NULL\n"); access2 = NULL; - res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); - ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); - ok(count == 2, "Expected count == 2, got %d\n", count); + res = GetExplicitEntriesFromAclW(new_acl, &count, &access2); + ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError()); + ok(count == 2, "Expected count == 2, got %ld\n", count); ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); - ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); + ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions); ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); - ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); + ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance); ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); LocalFree(access2); LocalFree(new_acl); access.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; - res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &access, old_acl, &new_acl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(new_acl != NULL, "returned acl was NULL\n"); access2 = NULL; - res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); - ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); - ok(count == 2, "Expected count == 2, got %d\n", count); + res = GetExplicitEntriesFromAclW(new_acl, &count, &access2); + ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError()); + ok(count == 2, "Expected count == 2, got %ld\n", count); ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); - ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); + ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions); ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); - ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); + ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance); ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); LocalFree(access2); LocalFree(new_acl); access.Trustee.TrusteeForm = TRUSTEE_IS_NAME; access.Trustee.ptstrName = (LPWSTR)wszCurrentUser; - res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &access, old_acl, &new_acl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(new_acl != NULL, "returned acl was NULL\n"); access2 = NULL; - res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); - ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); - ok(count == 2, "Expected count == 2, got %d\n", count); + res = GetExplicitEntriesFromAclW(new_acl, &count, &access2); + ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError()); + ok(count == 2, "Expected count == 2, got %ld\n", count); ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); - ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); + ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions); ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); - ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); + ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance); LocalFree(access2); LocalFree(new_acl); access.grfAccessMode = REVOKE_ACCESS; access.Trustee.TrusteeForm = TRUSTEE_IS_SID; access.Trustee.ptstrName = users_sid; - res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); - ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); + res = SetEntriesInAclW(1, &access, old_acl, &new_acl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); ok(new_acl != NULL, "returned acl was NULL\n"); access2 = (void *)0xdeadbeef; - res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); - ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); - ok(count == 0, "Expected count == 0, got %d\n", count); + res = GetExplicitEntriesFromAclW(new_acl, &count, &access2); + ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError()); + ok(count == 0, "Expected count == 0, got %ld\n", count); ok(access2 == NULL, "access2 was not NULL\n"); LocalFree(new_acl); + /* Make the ACL both Allow and Deny Everyone. */ + res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, everyone_sid); + ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError()); + res = AddAccessDeniedAce(old_acl, ACL_REVISION, KEY_WRITE, everyone_sid); + ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError()); + /* Revoke Everyone. */ + access.Trustee.ptstrName = everyone_sid; + access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + access.grfAccessPermissions = 0; + new_acl = NULL; + res = SetEntriesInAclW(1, &access, old_acl, &new_acl); + ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res); + ok(new_acl != NULL, "returned acl was NULL\n"); + /* Deny Everyone should remain (along with Grant Users from earlier). */ + access2 = NULL; + res = GetExplicitEntriesFromAclW(new_acl, &count, &access2); + ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError()); + ok(count == 2, "Expected count == 2, got %ld\n", count); +#ifdef __REACTOS__ + if (!access2) { + ok(FALSE, "FIXME: access2 should not be null!\n"); // Happens on ReactOS currently + } else { +#endif + ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); + ok(access2[0].grfAccessPermissions == KEY_READ , "Expected KEY_READ, got %ld\n", access2[0].grfAccessPermissions); + ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n"); + ok(access2[1].grfAccessMode == DENY_ACCESS, "Expected DENY_ACCESS, got %d\n", access2[1].grfAccessMode); + ok(access2[1].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[1].grfAccessPermissions); + ok(EqualSid(access2[1].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); + LocalFree(access2); +#ifdef __REACTOS__ + } +#endif + FreeSid(users_sid); FreeSid(everyone_sid); - HeapFree(GetProcessHeap(), 0, old_acl); + free(old_acl); } static void test_BuildSecurityDescriptorW(void) @@ -8108,30 +7765,1086 @@ static void test_BuildSecurityDescriptorW(void) buf_size = sizeof(buf); rel_sd = (SECURITY_DESCRIPTOR *)buf; success = MakeSelfRelativeSD(&old_sd, rel_sd, &buf_size); - ok(success, "MakeSelfRelativeSD failed with %u\n", GetLastError()); + ok(success, "MakeSelfRelativeSD failed with %lu\n", GetLastError()); new_sd = NULL; new_sd_size = 0; ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, NULL, &new_sd_size, (void **)&new_sd); - ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %u\n", ret); + ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %lu\n", ret); ok(new_sd != NULL, "expected new_sd != NULL\n"); - ok(new_sd_size == sizeof(old_sd), "expected new_sd_size == sizeof(old_sd), got %u\n", new_sd_size); LocalFree(new_sd); new_sd = (void *)0xdeadbeef; ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, &old_sd, &new_sd_size, (void **)&new_sd); - ok(ret == ERROR_INVALID_SECURITY_DESCR, "expected ERROR_INVALID_SECURITY_DESCR, got %u\n", ret); + ok(ret == ERROR_INVALID_SECURITY_DESCR, "expected ERROR_INVALID_SECURITY_DESCR, got %lu\n", ret); ok(new_sd == (void *)0xdeadbeef, "expected new_sd == 0xdeadbeef, got %p\n", new_sd); new_sd = NULL; new_sd_size = 0; ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, rel_sd, &new_sd_size, (void **)&new_sd); - ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %u\n", ret); + ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %lu\n", ret); ok(new_sd != NULL, "expected new_sd != NULL\n"); - ok(new_sd_size == sizeof(old_sd), "expected new_sd_size == sizeof(old_sd), got %u\n", new_sd_size); LocalFree(new_sd); } +static void test_EqualDomainSid(void) +{ + SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY }; + char sid_buffer[SECURITY_MAX_SID_SIZE], sid_buffer2[SECURITY_MAX_SID_SIZE]; + PSID domainsid, sid = sid_buffer, sid2 = sid_buffer2; + DWORD size; + BOOL ret, equal; + unsigned int i; + + ret = AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid); + ok(ret, "AllocateAndInitializeSid error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = EqualDomainSid(NULL, NULL, NULL); + ok(!ret, "got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_SID, "got %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = EqualDomainSid(domainsid, domainsid, NULL); + ok(!ret, "got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(well_known_sid_values); i++) + { + SID *pisid = sid; + + size = sizeof(sid_buffer); + if (!CreateWellKnownSid(i, NULL, sid, &size)) + { + trace("Well known SID %u not supported\n", i); + continue; + } + + equal = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = EqualDomainSid(sid, domainsid, &equal); + if (pisid->SubAuthority[0] != SECURITY_BUILTIN_DOMAIN_RID) + { + ok(!ret, "%u: got %d\n", i, ret); + ok(GetLastError() == ERROR_NON_DOMAIN_SID, "%u: got %lu\n", i, GetLastError()); + ok(equal == 0xdeadbeef, "%u: got %d\n", i, equal); + continue; + } + + ok(ret, "%u: got %d\n", i, ret); + ok(GetLastError() == 0, "%u: got %lu\n", i, GetLastError()); + ok(equal == 0, "%u: got %d\n", i, equal); + + size = sizeof(sid_buffer2); + ret = CreateWellKnownSid(i, well_known_sid_values[i].without_domain ? NULL : domainsid, sid2, &size); + ok(ret, "%u: CreateWellKnownSid error %lu\n", i, GetLastError()); + + equal = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = EqualDomainSid(sid, sid2, &equal); + ok(ret, "%u: got %d\n", i, ret); + ok(GetLastError() == 0, "%u: got %lu\n", i, GetLastError()); + ok(equal == 1, "%u: got %d\n", i, equal); + } + + FreeSid(domainsid); +} + +static DWORD WINAPI duplicate_handle_access_thread(void *arg) +{ + HANDLE event = arg, event2; + BOOL ret; + + event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup"); + ok(!!event2, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup"); + ok(!!event2, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), + &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(ret, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + return 0; +} + +static void test_duplicate_handle_access(void) +{ + char acl_buffer[200], everyone_sid_buffer[100], local_sid_buffer[100], cmdline[300]; + HANDLE token, restricted, impersonation, all_event, sync_event, event2, thread; + SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)}; + SID *everyone_sid = (SID *)everyone_sid_buffer; + SID *local_sid = (SID *)local_sid_buffer; + ACL *acl = (ACL *)acl_buffer; + SID_AND_ATTRIBUTES sid_attr; + SECURITY_DESCRIPTOR sd; + PROCESS_INFORMATION pi; + STARTUPINFOA si = {0}; + DWORD size; + BOOL ret; + + /* DuplicateHandle() validates access against the calling thread's token and + * the target process's token. It does *not* validate access against the + * calling process's token, even if the calling thread is not impersonating. + */ + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token); + ok(ret, "got error %lu\n", GetLastError()); + + size = sizeof(everyone_sid_buffer); + ret = CreateWellKnownSid(WinWorldSid, NULL, everyone_sid, &size); + ok(ret, "got error %lu\n", GetLastError()); + size = sizeof(local_sid_buffer); + ret = CreateWellKnownSid(WinLocalSid, NULL, local_sid, &size); + ok(ret, "got error %lu\n", GetLastError()); + + InitializeAcl(acl, sizeof(acl_buffer), ACL_REVISION); + ret = AddAccessAllowedAce(acl, ACL_REVISION, SYNCHRONIZE, everyone_sid); + ok(ret, "got error %lu\n", GetLastError()); + InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); + ret = AddAccessAllowedAce(acl, ACL_REVISION, EVENT_MODIFY_STATE, local_sid); + ok(ret, "got error %lu\n", GetLastError()); + InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); + ret = SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE); + ok(ret, "got error %lu\n", GetLastError()); + sa.lpSecurityDescriptor = &sd; + + sid_attr.Sid = local_sid; + sid_attr.Attributes = 0; + ret = CreateRestrictedToken(token, 0, 1, &sid_attr, 0, NULL, 0, NULL, &restricted); + ok(ret, "got error %lu\n", GetLastError()); + ret = DuplicateTokenEx(restricted, TOKEN_IMPERSONATE, NULL, + SecurityImpersonation, TokenImpersonation, &impersonation); + ok(ret, "got error %lu\n", GetLastError()); + + all_event = CreateEventA(&sa, TRUE, TRUE, "test_dup"); + ok(!!all_event, "got error %lu\n", GetLastError()); + sync_event = OpenEventA(SYNCHRONIZE, FALSE, "test_dup"); + ok(!!sync_event, "got error %lu\n", GetLastError()); + + event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup"); + ok(!!event2, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup"); + ok(!!event2, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(ret, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(ret, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + ret = SetThreadToken(NULL, impersonation); + ok(ret, "got error %lu\n", GetLastError()); + + thread = CreateThread(NULL, 0, duplicate_handle_access_thread, sync_event, 0, NULL); + ret = WaitForSingleObject(thread, 1000); + ok(!ret, "wait failed\n"); + + event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup"); + ok(!!event2, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + SetLastError(0xdeadbeef); + event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup"); + ok(!event2, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(ret, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + SetLastError(0xdeadbeef); + ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + ret = RevertToSelf(); + ok(ret, "got error %lu\n", GetLastError()); + + sprintf(cmdline, "%s security duplicate %Iu %lu %Iu", myARGV[0], + (ULONG_PTR)sync_event, GetCurrentProcessId(), (ULONG_PTR)impersonation ); + ret = CreateProcessAsUserA(restricted, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "got error %lu\n", GetLastError()); + + ret = DuplicateHandle(GetCurrentProcess(), all_event, pi.hProcess, &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(ret, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = DuplicateHandle(GetCurrentProcess(), sync_event, pi.hProcess, &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + ret = WaitForSingleObject(pi.hProcess, 1000); + ok(!ret, "wait failed\n"); + + CloseHandle(impersonation); + CloseHandle(restricted); + CloseHandle(token); + CloseHandle(sync_event); + CloseHandle(all_event); +} + +static void test_duplicate_handle_access_child(void) +{ + HANDLE event, event2, process, token; + BOOL ret; + + event = (HANDLE)(ULONG_PTR)_atoi64(myARGV[3]); + process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, atoi(myARGV[4])); + ok(!!process, "failed to open process, error %lu\n", GetLastError()); + + event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup"); + ok(!!event2, "got error %lu\n", GetLastError()); + CloseHandle(event2); + + SetLastError(0xdeadbeef); + event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup"); + ok(!event2, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(ret, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + ret = DuplicateHandle(process, (HANDLE)(ULONG_PTR)_atoi64(myARGV[5]), + GetCurrentProcess(), &token, 0, FALSE, DUPLICATE_SAME_ACCESS); + ok(ret, "failed to retrieve token, error %lu\n", GetLastError()); + ret = SetThreadToken(NULL, token); + ok(ret, "failed to set thread token, error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + + ret = RevertToSelf(); + ok(ret, "failed to revert, error %lu\n", GetLastError()); + CloseHandle(token); + CloseHandle(process); +} + +#define join_process(a) join_process_(__LINE__, a) +static void join_process_(int line, const PROCESS_INFORMATION *pi) +{ + DWORD ret = WaitForSingleObject(pi->hProcess, 1000); + ok_(__FILE__, line)(!ret, "wait failed\n"); + CloseHandle(pi->hProcess); + CloseHandle(pi->hThread); +} + +static void test_create_process_token(void) +{ + char cmdline[300], acl_buffer[200], sid_buffer[100]; + SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)}; + ACL *acl = (ACL *)acl_buffer; + SID *sid = (SID *)sid_buffer; + SID_AND_ATTRIBUTES sid_attr; + HANDLE event, token, token2; + PROCESS_INFORMATION pi; + SECURITY_DESCRIPTOR sd; + STARTUPINFOA si = {0}; + DWORD size; + BOOL ret; + + size = sizeof(sid_buffer); + ret = CreateWellKnownSid(WinLocalSid, NULL, sid, &size); + ok(ret, "got error %lu\n", GetLastError()); + ret = InitializeAcl(acl, sizeof(acl_buffer), ACL_REVISION); + ok(ret, "got error %lu\n", GetLastError()); + ret = AddAccessAllowedAce(acl, ACL_REVISION, EVENT_MODIFY_STATE, sid); + ok(ret, "got error %lu\n", GetLastError()); + InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); + ret = SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE); + ok(ret, "got error %lu\n", GetLastError()); + sa.lpSecurityDescriptor = &sd; + event = CreateEventA(&sa, TRUE, TRUE, "test_event"); + ok(!!event, "got error %lu\n", GetLastError()); + + sprintf(cmdline, "%s security restricted 0", myARGV[0]); + +#ifdef __REACTOS__ + /* This block creates test failures on WS03 */ + if (GetNTVersion() > _WIN32_WINNT_WS03) { +#endif + ret = CreateProcessAsUserA(NULL, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "got error %lu\n", GetLastError()); + join_process(&pi); +#ifdef __REACTOS__ + } +#endif + + ret = CreateProcessAsUserA(GetCurrentProcessToken(), NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + todo_wine ok(!ret, "expected failure\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError()); + if (ret) join_process(&pi); + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token); + ok(ret, "got error %lu\n", GetLastError()); + ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret || broken(GetLastError() == ERROR_ACCESS_DENIED) /* < 7 */, "got error %lu\n", GetLastError()); + if (ret) join_process(&pi); + CloseHandle(token); + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); + ok(ret, "got error %lu\n", GetLastError()); + ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + CloseHandle(token); + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY, &token); + ok(ret, "got error %lu\n", GetLastError()); + ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + CloseHandle(token); + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE, &token); + ok(ret, "got error %lu\n", GetLastError()); + + ret = DuplicateTokenEx(token, TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, NULL, + SecurityImpersonation, TokenImpersonation, &token2); + ok(ret, "got error %lu\n", GetLastError()); + ret = CreateProcessAsUserA(token2, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret || broken(GetLastError() == ERROR_BAD_TOKEN_TYPE) /* < 7 */, "got error %lu\n", GetLastError()); + if (ret) join_process(&pi); + CloseHandle(token2); + + sprintf(cmdline, "%s security restricted 1", myARGV[0]); + sid_attr.Sid = sid; + sid_attr.Attributes = 0; + ret = CreateRestrictedToken(token, 0, 1, &sid_attr, 0, NULL, 0, NULL, &token2); + ok(ret, "got error %lu\n", GetLastError()); + ret = CreateProcessAsUserA(token2, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "got error %lu\n", GetLastError()); + join_process(&pi); + CloseHandle(token2); + + CloseHandle(token); + + CloseHandle(event); +} + +static void test_create_process_token_child(void) +{ + HANDLE event; + + SetLastError(0xdeadbeef); + event = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_event"); + if (!atoi(myARGV[3])) + { + ok(!!event, "got error %lu\n", GetLastError()); + CloseHandle(event); + } + else + { + ok(!event, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); + } +} + +static void test_pseudo_handle_security(void) +{ + char buffer[200]; + PSECURITY_DESCRIPTOR sd = buffer, sd_ptr; + unsigned int i; + DWORD size; + BOOL ret; + + static const HKEY keys[] = + { + HKEY_CLASSES_ROOT, + HKEY_CURRENT_USER, + HKEY_LOCAL_MACHINE, + HKEY_USERS, + HKEY_PERFORMANCE_DATA, + HKEY_CURRENT_CONFIG, + HKEY_DYN_DATA, + }; + +#ifdef __REACTOS__ + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, sizeof(buffer), &size); +#else + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size); +#endif + ok(ret, "got error %lu\n", GetLastError()); + +#ifdef __REACTOS__ + ret = GetKernelObjectSecurity(GetCurrentThread(), OWNER_SECURITY_INFORMATION, sd, sizeof(buffer), &size); +#else + ret = GetKernelObjectSecurity(GetCurrentThread(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size); +#endif + ok(ret, "got error %lu\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(keys); ++i) + { + SetLastError(0xdeadbeef); +#ifdef __REACTOS__ + ret = GetKernelObjectSecurity(keys[i], OWNER_SECURITY_INFORMATION, sd, sizeof(buffer), &size); +#else + ret = GetKernelObjectSecurity(keys[i], OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size); +#endif + ok(!ret, "key %p: expected failure\n", keys[i]); + ok(GetLastError() == ERROR_INVALID_HANDLE, "key %p: got error %lu\n", keys[i], GetLastError()); + + ret = GetSecurityInfo(keys[i], SE_REGISTRY_KEY, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr); + if (keys[i] == HKEY_PERFORMANCE_DATA) + ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret); + else if (keys[i] == HKEY_DYN_DATA) + todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED || broken(ret == ERROR_INVALID_HANDLE) /* <7 */, + "key %p: got error %u\n", keys[i], ret); + else + ok(!ret, "key %p: got error %u\n", keys[i], ret); + if (!ret) LocalFree(sd_ptr); + + ret = GetSecurityInfo(keys[i], SE_KERNEL_OBJECT, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr); + ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret); + } +} + +static const LUID_AND_ATTRIBUTES *find_privilege(const TOKEN_PRIVILEGES *privs, const LUID *luid) +{ + DWORD i; + + for (i = 0; i < privs->PrivilegeCount; ++i) + { + if (!memcmp(luid, &privs->Privileges[i].Luid, sizeof(LUID))) + return &privs->Privileges[i]; + } + + return NULL; +} + +static void test_duplicate_token(void) +{ + const DWORD orig_access = TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_PRIVILEGES; + char prev_privs_buffer[128], ret_privs_buffer[1024]; + TOKEN_PRIVILEGES *prev_privs = (void *)prev_privs_buffer; + TOKEN_PRIVILEGES *ret_privs = (void *)ret_privs_buffer; + const LUID_AND_ATTRIBUTES *priv; + TOKEN_PRIVILEGES privs; + SECURITY_QUALITY_OF_SERVICE qos = {.Length = sizeof(qos)}; + OBJECT_ATTRIBUTES attr = {.Length = sizeof(attr)}; + SECURITY_IMPERSONATION_LEVEL level; + HANDLE token, token2; + DWORD size; + BOOL ret; + + ret = OpenProcessToken(GetCurrentProcess(), orig_access, &token); + ok(ret, "got error %lu\n", GetLastError()); + + /* Disable a privilege, to see if that privilege modification is preserved + * in the duplicated tokens. */ + privs.PrivilegeCount = 1; + ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privs.Privileges[0].Luid); + ok(ret, "got error %lu\n", GetLastError()); + privs.Privileges[0].Attributes = 0; + ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = DuplicateToken(token, SecurityAnonymous, &token2); + ok(ret, "got error %lu\n", GetLastError()); + TEST_GRANTED_ACCESS(token2, TOKEN_QUERY | TOKEN_IMPERSONATE); + ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(level == SecurityAnonymous, "got impersonation level %#x\n", level); + ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + priv = find_privilege(ret_privs, &privs.Privileges[0].Luid); + ok(!!priv, "Privilege should exist\n"); + todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes); + CloseHandle(token2); + + ret = DuplicateTokenEx(token, 0, NULL, SecurityAnonymous, TokenPrimary, &token2); + ok(ret, "got error %lu\n", GetLastError()); + TEST_GRANTED_ACCESS(token2, orig_access); + ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got error %lu.\n", GetLastError()); + ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + priv = find_privilege(ret_privs, &privs.Privileges[0].Luid); + ok(!!priv, "Privilege should exist\n"); + todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes); + CloseHandle(token2); + + ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityAnonymous, TokenPrimary, &token2); + ok(ret, "got error %lu\n", GetLastError()); + TEST_GRANTED_ACCESS(token2, TOKEN_ALL_ACCESS); + CloseHandle(token2); + + ret = DuplicateTokenEx(token, TOKEN_QUERY_SOURCE, NULL, SecurityAnonymous, TokenPrimary, &token2); + ok(ret, "got error %lu\n", GetLastError()); + TEST_GRANTED_ACCESS(token2, TOKEN_QUERY_SOURCE); + CloseHandle(token2); + + ret = DuplicateTokenEx(token, 0, NULL, SecurityIdentification, TokenImpersonation, &token2); + ok(ret, "got error %lu\n", GetLastError()); + TEST_GRANTED_ACCESS(token2, orig_access); + ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(level == SecurityIdentification, "got impersonation level %#x\n", level); + ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + priv = find_privilege(ret_privs, &privs.Privileges[0].Luid); + ok(!!priv, "Privilege should exist\n"); + todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes); + CloseHandle(token2); + + ret = NtDuplicateToken(token, 0, &attr, FALSE, TokenImpersonation, &token2); + ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret); + TEST_GRANTED_ACCESS(token2, orig_access); + ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(level == SecurityAnonymous, "got impersonation level %#x\n", level); + ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + priv = find_privilege(ret_privs, &privs.Privileges[0].Luid); + ok(!!priv, "Privilege should exist\n"); + todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes); + CloseHandle(token2); + + ret = NtDuplicateToken(token, 0, &attr, TRUE, TokenImpersonation, &token2); + ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret); + TEST_GRANTED_ACCESS(token2, orig_access); + ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + priv = find_privilege(ret_privs, &privs.Privileges[0].Luid); + todo_wine ok(!priv, "Privilege shouldn't exist\n"); + CloseHandle(token2); + + qos.ImpersonationLevel = SecurityIdentification; + qos.ContextTrackingMode = SECURITY_STATIC_TRACKING; + qos.EffectiveOnly = FALSE; + attr.SecurityQualityOfService = &qos; + ret = NtDuplicateToken(token, 0, &attr, FALSE, TokenImpersonation, &token2); + ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret); + TEST_GRANTED_ACCESS(token2, orig_access); + ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(level == SecurityIdentification, "got impersonation level %#x\n", level); + CloseHandle(token2); + + privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size); + ok(ret, "got error %lu\n", GetLastError()); + + CloseHandle(token); +} + +static void test_GetKernelObjectSecurity(void) +{ + /* Basic tests for parameter validation. */ + + SECURITY_DESCRIPTOR_CONTROL control; + DWORD size, ret_size, revision; + BOOL ret, present, defaulted; + PSECURITY_DESCRIPTOR sd; + PSID sid; + ACL *acl; + + SetLastError(0xdeadbeef); + size = 0xdeadbeef; + ret = GetKernelObjectSecurity(NULL, OWNER_SECURITY_INFORMATION, NULL, 0, &size); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError()); + ok(size == 0xdeadbeef, "got size %lu\n", size); + + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, NULL, 0, NULL); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + size = 0xdeadbeef; + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, NULL, 0, &size); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError()); + ok(size > 0 && size != 0xdeadbeef, "got size 0\n"); + + sd = malloc(size + 1); + + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, size - 1, &ret_size); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError()); + ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size); + + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, size + 1, &ret_size); + ok(ret, "expected success\n"); + ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError()); + ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size); + + free(sd); + + /* Calling the function with flags not defined succeeds and yields an empty + * descriptor. */ + + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(GetCurrentProcess(), 0x100000, NULL, 0, &size); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError()); + + sd = malloc(size); + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(GetCurrentProcess(), 0x100000, sd, size, &ret_size); + ok(ret, "expected success\n"); + ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError()); + ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size); + + ret = GetSecurityDescriptorControl(sd, &control, &revision); + ok(ret, "got error %lu\n", GetLastError()); + todo_wine ok(control == SE_SELF_RELATIVE, "got control %#x\n", control); + ok(revision == SECURITY_DESCRIPTOR_REVISION1, "got revision %lu\n", revision); + + ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted); + ok(ret, "got error %lu\n", GetLastError()); + ok(!sid, "expected no owner SID\n"); + ok(!defaulted, "expected owner not defaulted\n"); + + ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted); + ok(ret, "got error %lu\n", GetLastError()); + ok(!sid, "expected no group SID\n"); + ok(!defaulted, "expected group not defaulted\n"); + + ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted); + ok(ret, "got error %lu\n", GetLastError()); + todo_wine ok(!present, "expected no DACL present\n"); + /* the descriptor is defaulted only on Windows >= 7 */ + + ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); + ok(ret, "got error %lu\n", GetLastError()); + ok(!present, "expected no SACL present\n"); + /* the descriptor is defaulted only on Windows >= 7 */ + + free(sd); +} + +static void check_different_token(HANDLE token1, HANDLE token2) +{ + TOKEN_STATISTICS stats1, stats2; + DWORD size; + BOOL ret; + + ret = GetTokenInformation(token1, TokenStatistics, &stats1, sizeof(stats1), &size); + ok(ret, "got error %lu\n", GetLastError()); + ret = GetTokenInformation(token2, TokenStatistics, &stats2, sizeof(stats2), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ok(memcmp(&stats1.TokenId, &stats2.TokenId, sizeof(LUID)), "expected different IDs\n"); +} + +static void test_elevation(void) +{ + TOKEN_LINKED_TOKEN linked, linked2; + DWORD orig_type, type, size; + TOKEN_ELEVATION elevation; + HANDLE token, token2; + BOOL ret; + +#ifdef __REACTOS__ + if (GetNTVersion() <= _WIN32_WINNT_WS03) { + skip("test_elevation() is invalid for WS03\n"); + return; + } +#endif + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | READ_CONTROL | TOKEN_DUPLICATE + | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_DEFAULT, &token); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + orig_type = type; + ret = GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size); + if (!ret && GetLastError() == ERROR_NO_SUCH_LOGON_SESSION) /* fails on w2008s64 */ + { + win_skip("Failed to get linked token.\n"); + CloseHandle(token); + return; + } + ok(ret, "got error %lu\n", GetLastError()); + + if (type == TokenElevationTypeDefault) + { + ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated); + ok(!linked.LinkedToken, "expected no linked token\n"); + } + else if (type == TokenElevationTypeLimited) + { + ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated); + ok(!!linked.LinkedToken, "expected a linked token\n"); + + TEST_GRANTED_ACCESS(linked.LinkedToken, TOKEN_ALL_ACCESS); + ret = GetTokenInformation(linked.LinkedToken, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenElevationTypeFull, "got type %#lx\n", type); + ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated); + ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenImpersonation, "got type %#lx\n", type); + ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == SecurityIdentification, "got impersonation level %#lx\n", type); + + /* Asking for the linked token again gives us a different token. */ + ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenElevationTypeFull, "got type %#lx\n", type); + ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated); + + check_different_token(linked.LinkedToken, linked2.LinkedToken); + + CloseHandle(linked2.LinkedToken); + + /* Asking for the linked token's linked token gives us a new limited token. */ + ret = GetTokenInformation(linked.LinkedToken, TokenLinkedToken, &linked2, sizeof(linked2), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenElevationTypeLimited, "got type %#lx\n", type); + ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated); + + check_different_token(token, linked2.LinkedToken); + + CloseHandle(linked2.LinkedToken); + + CloseHandle(linked.LinkedToken); + + type = TokenElevationTypeLimited; + ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type)); + ok(!ret, "expected failure\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); + + elevation.TokenIsElevated = FALSE; + ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation)); + ok(!ret, "expected failure\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); + } + else + { + ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated); + ok(!!linked.LinkedToken, "expected a linked token\n"); + + TEST_GRANTED_ACCESS(linked.LinkedToken, TOKEN_ALL_ACCESS); + ret = GetTokenInformation(linked.LinkedToken, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenElevationTypeLimited, "got type %#lx\n", type); + ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated); + ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenImpersonation, "got type %#lx\n", type); + ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == SecurityIdentification, "got impersonation level %#lx\n", type); + + /* Asking for the linked token again gives us a different token. */ + ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenElevationTypeLimited, "got type %#lx\n", type); + ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated); + + check_different_token(linked.LinkedToken, linked2.LinkedToken); + + CloseHandle(linked2.LinkedToken); + + /* Asking for the linked token's linked token gives us a new elevated token. */ + ret = GetTokenInformation(linked.LinkedToken, TokenLinkedToken, &linked2, sizeof(linked2), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenElevationTypeFull, "got type %#lx\n", type); + ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated); + + check_different_token(token, linked2.LinkedToken); + + CloseHandle(linked2.LinkedToken); + + CloseHandle(linked.LinkedToken); + + type = TokenElevationTypeLimited; + ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type)); + ok(!ret, "expected failure\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); + + elevation.TokenIsElevated = FALSE; + ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation)); + ok(!ret, "expected failure\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); + } + + ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &token2); + ok(ret, "got error %lu\n", GetLastError()); + ret = GetTokenInformation(token2, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == orig_type, "expected same type\n"); + ret = GetTokenInformation(token2, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == (type == TokenElevationTypeFull), "got elevation %#lx\n", elevation.TokenIsElevated); + ret = GetTokenInformation(token2, TokenLinkedToken, &linked, sizeof(linked), &size); + ok(ret, "got error %lu\n", GetLastError()); + if (type == TokenElevationTypeDefault) + { + ok(!linked.LinkedToken, "expected no linked token\n"); + ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == TokenImpersonation, "got type %#lx\n", type); + ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == SecurityIdentification, "got impersonation level %#lx\n", type); + CloseHandle(linked.LinkedToken); + } + else + ok(!!linked.LinkedToken, "expected a linked token\n"); + CloseHandle(token2); + + ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token2); + ok(ret, "got error %lu\n", GetLastError()); + ret = GetTokenInformation(token2, TokenElevationType, &type, sizeof(type), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(type == orig_type, "expected same type\n"); + ret = GetTokenInformation(token2, TokenElevation, &elevation, sizeof(elevation), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(elevation.TokenIsElevated == (type == TokenElevationTypeFull), "got elevation %#lx\n", elevation.TokenIsElevated); + ret = GetTokenInformation(token2, TokenLinkedToken, &linked, sizeof(linked), &size); + ok(ret, "got error %lu\n", GetLastError()); + if (type == TokenElevationTypeDefault) + ok(!linked.LinkedToken, "expected no linked token\n"); + else + ok(!!linked.LinkedToken, "expected a linked token\n"); + CloseHandle(linked.LinkedToken); + CloseHandle(token2); + + if (type != TokenElevationTypeDefault) + { + char prev_privs_buffer[128], acl_buffer[256], prev_acl_buffer[256]; + TOKEN_PRIVILEGES privs, *prev_privs = (TOKEN_PRIVILEGES *)prev_privs_buffer; + TOKEN_DEFAULT_DACL *prev_acl = (TOKEN_DEFAULT_DACL *)prev_acl_buffer; + TOKEN_DEFAULT_DACL *ret_acl = (TOKEN_DEFAULT_DACL *)acl_buffer; + TOKEN_DEFAULT_DACL default_acl; + PRIVILEGE_SET priv_set; + BOOL ret, is_member; + DWORD size; + ACL acl; + + /* Linked tokens do not preserve privilege modifications. */ + + privs.PrivilegeCount = 1; + ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privs.Privileges[0].Luid); + ok(ret, "got error %lu\n", GetLastError()); + privs.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED; + ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size); + ok(ret, "got error %lu\n", GetLastError()); + + priv_set.PrivilegeCount = 1; + priv_set.Control = 0; + priv_set.Privilege[0] = privs.Privileges[0]; + ret = PrivilegeCheck(token, &priv_set, &is_member); + ok(ret, "got error %lu\n", GetLastError()); + ok(!is_member, "not a member\n"); + + ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = PrivilegeCheck(linked.LinkedToken, &priv_set, &is_member); + ok(ret, "got error %lu\n", GetLastError()); + ok(is_member, "not a member\n"); + + CloseHandle(linked.LinkedToken); + + ret = AdjustTokenPrivileges(token, FALSE, prev_privs, 0, NULL, NULL); + ok(ret, "got error %lu\n", GetLastError()); + + /* Linked tokens do not preserve default DACL modifications. */ + + ret = GetTokenInformation(token, TokenDefaultDacl, prev_acl, sizeof(prev_acl_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(prev_acl->DefaultDacl->AceCount, "expected non-empty default DACL\n"); + + InitializeAcl(&acl, sizeof(acl), ACL_REVISION); + default_acl.DefaultDacl = &acl; + ret = SetTokenInformation(token, TokenDefaultDacl, &default_acl, sizeof(default_acl)); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(token, TokenDefaultDacl, ret_acl, sizeof(acl_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(!ret_acl->DefaultDacl->AceCount, "expected empty default DACL\n"); + + ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetTokenInformation(linked.LinkedToken, TokenDefaultDacl, ret_acl, sizeof(acl_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + ok(ret_acl->DefaultDacl->AceCount, "expected non-empty default DACL\n"); + + CloseHandle(linked.LinkedToken); + + ret = SetTokenInformation(token, TokenDefaultDacl, prev_acl, sizeof(*prev_acl)); + ok(ret, "got error %lu\n", GetLastError()); + } + + CloseHandle(token); +} + +static void test_group_as_file_owner(void) +{ + char sd_buffer[200], sid_buffer[100]; + SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)sd_buffer; + char temp_path[MAX_PATH], path[MAX_PATH]; + SID *admin_sid = (SID *)sid_buffer; + BOOL ret, present, defaulted; + SECURITY_DESCRIPTOR new_sd; + HANDLE file; + DWORD size; + ACL *dacl; + + /* The EA Origin client sets the SD owner of a directory to Administrators, + * while using the default DACL, and subsequently tries to create + * subdirectories. */ + + size = sizeof(sid_buffer); + CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &size); + + ret = CheckTokenMembership(NULL, admin_sid, &present); + ok(ret, "got error %lu\n", GetLastError()); + if (!present) + { + skip("user is not an administrator\n"); + return; + } + + GetTempPathA(ARRAY_SIZE(temp_path), temp_path); + sprintf(path, "%s\\testdir", temp_path); + + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu\n", GetLastError()); + + file = CreateFileA(path, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); + + ret = GetKernelObjectSecurity(file, DACL_SECURITY_INFORMATION, sd_buffer, sizeof(sd_buffer), &size); + ok(ret, "got error %lu\n", GetLastError()); + ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted); + ok(ret, "got error %lu\n", GetLastError()); + + InitializeSecurityDescriptor(&new_sd, SECURITY_DESCRIPTOR_REVISION); + + ret = SetSecurityDescriptorOwner(&new_sd, admin_sid, FALSE); + ok(ret, "got error %lu\n", GetLastError()); + + ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted); + ok(ret, "got error %lu\n", GetLastError()); + + ret = SetSecurityDescriptorDacl(&new_sd, present, dacl, defaulted); + ok(ret, "got error %lu\n", GetLastError()); + + ret = SetKernelObjectSecurity(file, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &new_sd); + ok(ret, "got error %lu\n", GetLastError()); + + CloseHandle(file); + + sprintf(path, "%s\\testdir\\subdir", temp_path); + ret = CreateDirectoryA(path, NULL); + ok(ret, "got error %lu\n", GetLastError()); + + ret = RemoveDirectoryA(path); + ok(ret, "got error %lu\n", GetLastError()); + sprintf(path, "%s\\testdir", temp_path); + ret = RemoveDirectoryA(path); + ok(ret, "got error %lu\n", GetLastError()); +} + +static void test_IsValidSecurityDescriptor(void) +{ + SECURITY_DESCRIPTOR *sd; + BOOL ret; + + SetLastError(0xdeadbeef); + ret = IsValidSecurityDescriptor(NULL); + ok(!ret, "Unexpected return value %d.\n", ret); + ok(GetLastError() == ERROR_INVALID_SECURITY_DESCR, "Unexpected error %ld.\n", GetLastError()); + + sd = calloc(1, SECURITY_DESCRIPTOR_MIN_LENGTH); + + SetLastError(0xdeadbeef); + ret = IsValidSecurityDescriptor(sd); + ok(!ret, "Unexpected return value %d.\n", ret); + ok(GetLastError() == ERROR_INVALID_SECURITY_DESCR, "Unexpected error %ld.\n", GetLastError()); + + ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); + ok(ret, "Unexpected return value %d, error %ld.\n", ret, GetLastError()); + + SetLastError(0xdeadbeef); + ret = IsValidSecurityDescriptor(sd); + ok(ret, "Unexpected return value %d.\n", ret); + ok(GetLastError() == 0xdeadbeef, "Unexpected error %ld.\n", GetLastError()); + + free(sd); +} + +static void test_window_security(void) +{ + PSECURITY_DESCRIPTOR sd; + BOOL present, defaulted; + HDESK desktop; + DWORD ret; + ACL *dacl; + + desktop = GetThreadDesktop(GetCurrentThreadId()); + + ret = GetSecurityInfo(desktop, SE_WINDOW_OBJECT, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd); + ok(!ret, "got error %lu\n", ret); + + ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted); + ok(ret == TRUE, "got error %lu\n", GetLastError()); + todo_wine ok(present == TRUE, "got present %d\n", present); + ok(defaulted == FALSE, "got defaulted %d\n", defaulted); + + LocalFree(sd); +} + START_TEST(security) { init(); @@ -8141,18 +8854,20 @@ START_TEST(security) { if (!strcmp(myARGV[2], "test_token_sd")) test_child_token_sd(); - else if (!strcmp(myARGV[2], "test_token_sd_restricted")) - test_child_token_sd_restricted(); - else if (!strcmp(myARGV[2], "test_token_sd_medium")) - test_child_token_sd_medium(); - else + else if (!strcmp(myARGV[2], "test")) test_process_security_child(); + else if (!strcmp(myARGV[2], "duplicate")) + test_duplicate_handle_access_child(); + else if (!strcmp(myARGV[2], "restricted")) + test_create_process_token_child(); return; } test_kernel_objects_security(); - test_sid(); + test_ConvertStringSidToSid(); test_trustee(); - test_luid(); + test_allocateLuid(); + test_lookupPrivilegeName(); + test_lookupPrivilegeValue(); test_CreateWellKnownSid(); test_FileSecurity(); test_AccessCheck(); @@ -8170,8 +8885,9 @@ START_TEST(security) test_ConvertStringSecurityDescriptor(); test_ConvertSecurityDescriptorToString(); test_PrivateObjectSecurity(); - test_acls(); + test_InitializeAcl(); test_GetWindowsAccountDomainSid(); + test_EqualDomainSid(); test_GetSecurityInfo(); test_GetSidSubAuthority(); test_CheckTokenMembership(); @@ -8180,7 +8896,7 @@ START_TEST(security) test_GetUserNameW(); test_CreateRestrictedToken(); test_TokenIntegrityLevel(); - test_default_dacl_owner_sid(); + test_default_dacl_owner_group_sid(); test_AdjustTokenPrivileges(); test_AddAce(); test_AddMandatoryAce(); @@ -8191,6 +8907,15 @@ START_TEST(security) test_token_label(); test_GetExplicitEntriesFromAclW(); test_BuildSecurityDescriptorW(); + test_duplicate_handle_access(); + test_create_process_token(); + test_pseudo_handle_security(); + test_duplicate_token(); + test_GetKernelObjectSecurity(); + test_elevation(); + test_group_as_file_owner(); + test_IsValidSecurityDescriptor(); + test_window_security(); /* Must be the last test, modifies process token */ test_token_security_descriptor(); diff --git a/modules/rostests/winetests/advapi32/service.c b/modules/rostests/winetests/advapi32/service.c index b92625fdf05..47ad4b0e2ba 100644 --- a/modules/rostests/winetests/advapi32/service.c +++ b/modules/rostests/winetests/advapi32/service.c @@ -35,6 +35,8 @@ static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */ static CHAR selfname[MAX_PATH]; +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); + static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID); static BOOL (WINAPI *pChangeServiceConfig2W)(SC_HANDLE,DWORD,LPVOID); static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD, @@ -43,8 +45,6 @@ static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD, static BOOL (WINAPI *pEnumServicesStatusExW)(SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD, LPDWORD, LPCWSTR); -static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, - PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, @@ -61,12 +61,13 @@ static void init_function_pointers(void) pChangeServiceConfig2W = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2W"); pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA"); pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW"); - pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo"); pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A"); pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W"); pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx"); pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity"); pNotifyServiceStatusChangeW = (void*)GetProcAddress(hadvapi32, "NotifyServiceStatusChangeW"); + + pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); } static void test_open_scm(void) @@ -76,21 +77,21 @@ static void test_open_scm(void) /* No access rights */ SetLastError(0xdeadbeef); scm_handle = OpenSCManagerA(NULL, NULL, 0); - ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); + ok(scm_handle != NULL, "Expected success, got error %lu\n", GetLastError()); CloseServiceHandle(scm_handle); /* Unknown database name */ SetLastError(0xdeadbeef); scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT); ok(!scm_handle, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %ld\n", GetLastError()); CloseServiceHandle(scm_handle); /* Just in case */ /* MSDN says only ServiceActive is allowed, or NULL */ SetLastError(0xdeadbeef); scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT); ok(!scm_handle, "Expected failure\n"); - ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %ld\n", GetLastError()); CloseServiceHandle(scm_handle); /* Just in case */ /* Remote unknown host */ @@ -100,21 +101,21 @@ static void test_open_scm(void) { ok(!scm_handle, "Expected failure\n"); ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */, - "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError()); + "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %ld\n", GetLastError()); } CloseServiceHandle(scm_handle); /* Just in case */ /* Proper call with an empty hostname */ scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT); - ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); + ok(scm_handle != NULL, "Expected success, got error %lu\n", GetLastError()); CloseServiceHandle(scm_handle); /* Again a correct one */ SetLastError(0xdeadbeef); scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_IO_PENDING) /* win2k */, - "Expected ERROR_SUCCESS, got %u\n", GetLastError()); - ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); + "Expected ERROR_SUCCESS, got %lu\n", GetLastError()); + ok(scm_handle != NULL, "Expected success, got error %lu\n", GetLastError()); CloseServiceHandle(scm_handle); } @@ -128,7 +129,7 @@ static void test_open_svc(void) SetLastError(0xdeadbeef); svc_handle = OpenServiceA(NULL, NULL, 0); ok(!svc_handle, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */ @@ -139,7 +140,7 @@ static void test_open_svc(void) ok(!svc_handle, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); CloseServiceHandle(scm_handle); /* Nonexistent service */ @@ -147,7 +148,7 @@ static void test_open_svc(void) SetLastError(0xdeadbeef); svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ); ok(!svc_handle, "Expected failure\n"); - ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); CloseServiceHandle(scm_handle); /* Proper SCM handle but different access rights */ @@ -158,7 +159,7 @@ static void test_open_svc(void) skip("Not enough rights to get a handle to the service\n"); else { - ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError()); + ok(svc_handle != NULL, "Expected success, got error %lu\n", GetLastError()); CloseServiceHandle(svc_handle); } @@ -182,7 +183,7 @@ static void test_open_svc(void) SetLastError(0xdeadbeef); svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ); ok(!svc_handle, "Expected failure\n"); - ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); /* Just in case */ CloseServiceHandle(svc_handle); @@ -195,14 +196,13 @@ static void test_create_delete_svc(void) CHAR username[UNLEN + 1], domain[MAX_PATH]; DWORD user_size = UNLEN + 1; CHAR account[MAX_PATH + UNLEN + 1]; - static const CHAR servicename [] = "Winetest"; + static const CHAR servicename [] = "winetest_create_delete"; static const CHAR pathname [] = "we_dont_care.exe"; static const CHAR empty [] = ""; static const CHAR password [] = "secret"; - BOOL spooler_exists = FALSE; + char buffer[200]; + DWORD size; BOOL ret; - CHAR display[4096]; - DWORD display_size = sizeof(display); /* Get the username and turn it into an account to be used in some tests */ GetUserNameA(username, &user_size); @@ -216,7 +216,7 @@ static void test_create_delete_svc(void) SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -226,7 +226,7 @@ static void test_create_delete_svc(void) ok(!svc_handle1, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Now with a servicename */ SetLastError(0xdeadbeef); @@ -234,7 +234,7 @@ static void test_create_delete_svc(void) ok(!svc_handle1, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Or just a binary name */ SetLastError(0xdeadbeef); @@ -242,24 +242,24 @@ static void test_create_delete_svc(void) ok(!svc_handle1, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Both servicename and binary name (We only have connect rights) */ SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* They can even be empty at this stage of parameter checking */ SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* Open the Service Control Manager with minimal rights for creation * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE') @@ -279,17 +279,17 @@ static void test_create_delete_svc(void) SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %ld\n", GetLastError()); /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed * an ERROR_INVALID_PARAMETER) @@ -298,7 +298,7 @@ static void test_create_delete_svc(void) svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */ @@ -309,14 +309,14 @@ static void test_create_delete_svc(void) svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */ SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used) * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT. @@ -326,7 +326,7 @@ static void test_create_delete_svc(void) SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password); ok(!svc_handle1, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT, - "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %ld\n", GetLastError()); /* Illegal (start-type is not a mask and should only be one of the possibilities) * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as @@ -336,58 +336,61 @@ static void test_create_delete_svc(void) svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */ SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS, SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Test if ServiceType can be a combined one for drivers */ SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER, SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); - /* The service already exists (check first, just in case) */ - svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ); - if (svc_handle1) + /* Test duplicate service names */ + svc_handle1 = CreateServiceA(scm_handle, "winetest_dupname", "winetest_display", DELETE, + SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); + ok(!!svc_handle1, "Failed to create service, error %lu\n", GetLastError()); + + svc_handle2 = CreateServiceA(scm_handle, "winetest_dupname", NULL, 0, + SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); + ok(!svc_handle2, "Expected failure\n"); + ok(GetLastError() == ERROR_SERVICE_EXISTS, "Got wrong error %lu\n", GetLastError()); + + svc_handle2 = CreateServiceA(scm_handle, "winetest_dupname2", "winetest_dupname", DELETE, + SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); + todo_wine ok(!svc_handle2, "Expected failure\n"); + todo_wine ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME, "Got wrong error %lu\n", GetLastError()); + if (svc_handle2) { - spooler_exists = TRUE; - CloseServiceHandle(svc_handle1); - SetLastError(0xdeadbeef); - svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS, - SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - ok(!svc_handle1, "Expected failure\n"); - ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError()); + DeleteService(svc_handle2); + CloseServiceHandle(svc_handle2); + } + + svc_handle2 = CreateServiceA(scm_handle, "winetest_dupname2", "winetest_display", DELETE, + SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); + if (svc_handle2) /* Win10 1709+ */ + { + size = sizeof(buffer); + ret = GetServiceKeyNameA(scm_handle, "winetest_display", buffer, &size); + ok(ret, "Failed to get key name, error %lu\n", GetLastError()); + ok(!strcmp(buffer, "winetest_dupname"), "Got wrong name \"%s\"\n", buffer); + + ret = DeleteService(svc_handle2); + ok(ret, "Failed to delete service, error %lu\n", GetLastError()); + CloseServiceHandle(svc_handle2); } else - skip("Spooler service doesn't exist\n"); + ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME, "Got wrong error %lu\n", GetLastError()); - /* To find an existing displayname we check the 'Spooler' service. Although the registry - * doesn't show DisplayName on NT4, this call will return a displayname which is equal - * to the servicename and can't be used as well for a new displayname. - */ - if (spooler_exists) - { - ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size); - - if (!ret) - skip("Could not retrieve a displayname for the Spooler service\n"); - else - { - svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS, - SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - ok(!svc_handle1, "Expected failure for display name '%s'\n", display); - ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME, - "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError()); - } - } - else - skip("Could not retrieve a displayname (Spooler service doesn't exist)\n"); + ret = DeleteService(svc_handle1); + ok(ret, "Failed to delete service, error %lu\n", GetLastError()); + CloseServiceHandle(svc_handle1); /* Windows doesn't care about the access rights for creation (which makes * sense as there is no service yet) as long as there are sufficient @@ -396,14 +399,14 @@ static void test_create_delete_svc(void) SetLastError(0xdeadbeef); svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError()); + ok(svc_handle1 != NULL, "Could not create the service : %ld\n", GetLastError()); /* DeleteService however must have proper rights */ SetLastError(0xdeadbeef); ret = DeleteService(svc_handle1); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* Open the service with minimal rights for deletion. * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE') @@ -414,28 +417,22 @@ static void test_create_delete_svc(void) /* Now that we have the proper rights, we should be able to delete */ SetLastError(0xdeadbeef); ret = DeleteService(svc_handle1); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); /* Service is marked for delete, but handle is still open. Try to open service again. */ svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ); - ok(svc_handle2 != NULL, "got %p, error %u\n", svc_handle2, GetLastError()); + ok(svc_handle2 != NULL, "got %p, error %lu\n", svc_handle2, GetLastError()); CloseServiceHandle(svc_handle2); CloseServiceHandle(svc_handle1); CloseServiceHandle(scm_handle); - /* Wait a while. One of the following tests also does a CreateService for the - * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE - * error if we do this too quickly. Vista seems more picky than the others. - */ - Sleep(1000); - /* And a final NULL check */ SetLastError(0xdeadbeef); ret = DeleteService(NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); } static void test_get_displayname(void) @@ -449,7 +446,7 @@ static void test_get_displayname(void) static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0}; static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0}; static const WCHAR abcW[] = {'A','B','C',0}; - static const CHAR servicename[] = "Winetest"; + static const CHAR servicename[] = "winetest_displayname"; static const CHAR pathname[] = "we_dont_care.exe"; /* Having NULL for the size of the buffer will crash on W2K3 */ @@ -458,7 +455,7 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -467,7 +464,7 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); displaysize = sizeof(displayname); @@ -475,7 +472,7 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* Test for nonexistent service */ SetLastError(0xdeadbeef); @@ -483,22 +480,22 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(displaysize == 1, "Service size expected 1, got %ld\n", displaysize); displaysize = 15; strcpy(displayname, "ABC"); ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(displaysize == 15, "Service size expected 15, got %ld\n", displaysize); ok(displayname[0] == 0, "Service name not empty\n"); displaysize = 15; @@ -506,8 +503,8 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + ok(displaysize == 15, "Service size expected 15, got %ld\n", displaysize); ok(displaynameW[0] == 0, "Service name not empty\n"); displaysize = 0; @@ -515,17 +512,17 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(displaysize == 1, "Service size expected 1, got %ld\n", displaysize); ok(displayname[0] == 'A', "Service name changed\n"); displaysize = 0; lstrcpyW( displaynameW, abcW ); ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); - ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + ok(displaysize == 2, "Service size expected 2, got %ld\n", displaysize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); ok(displaynameW[0] == 'A', "Service name changed\n"); displaysize = 1; @@ -533,17 +530,17 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(displaysize == 1, "Service size expected 1, got %ld\n", displaysize); ok(displayname[0] == 0, "Service name not empty\n"); displaysize = 1; lstrcpyW( displaynameW, abcW ); ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); - ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + ok(displaysize == 2, "Service size expected 2, got %ld\n", displaysize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); ok(displaynameW[0] == 'A', "Service name changed\n"); displaysize = 2; @@ -551,17 +548,17 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(displaysize == 2, "Service size expected 2, got %ld\n", displaysize); ok(displayname[0] == 0, "Service name not empty\n"); displaysize = 2; lstrcpyW( displaynameW, abcW ); ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); ok(!ret, "Expected failure\n"); - ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); + ok(displaysize == 2, "Service size expected 2, got %ld\n", displaysize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); ok(displaynameW[0] == 0, "Service name not empty\n"); /* Check if 'Spooler' exists */ @@ -580,15 +577,15 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); tempsize = displaysize; displaysize = 0; ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(displaysize == tempsize, "Buffer size mismatch (%ld vs %ld)\n", tempsize, displaysize); /* Buffer is too small */ SetLastError(0xdeadbeef); @@ -597,7 +594,7 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(displaysize == tempsize, "Expected the needed buffersize\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* First try with a buffer that should be big enough to hold * the ANSI string (and terminating character). This succeeds on Windows @@ -606,21 +603,21 @@ static void test_get_displayname(void) SetLastError(0xdeadbeef); displaysize = (tempsize / 2) + 1; ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n"); /* Now with the original returned size */ SetLastError(0xdeadbeef); displaysize = tempsize; ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(displaysize == tempsize, "Expected no change for the needed buffer size\n"); /* And with a bigger than needed buffer */ SetLastError(0xdeadbeef); displaysize = tempsize * 2; ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); /* Test that shows that if the buffersize is enough, it's not changed */ ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n"); ok(strlen(displayname) == tempsize/2, @@ -632,7 +629,7 @@ static void test_get_displayname(void) ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* Buffer is too small */ SetLastError(0xdeadbeef); @@ -642,7 +639,7 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(displaysize == tempsizeW, "Expected the needed buffersize\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* Now with the original returned size */ SetLastError(0xdeadbeef); @@ -651,13 +648,13 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(displaysize == tempsizeW, "Expected the needed buffersize\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* And with a bigger than needed buffer */ SetLastError(0xdeadbeef); displaysize = tempsizeW + 1; /* This caters for the null terminating character */ ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(displaysize == tempsizeW, "Expected the needed buffersize\n"); ok(lstrlenW(displaynameW) == displaysize, "Expected the buffer to be the length of the string\n") ; @@ -681,7 +678,7 @@ static void test_get_displayname(void) svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError()); + ok(svc_handle != NULL, "Could not create the service : %ld\n", GetLastError()); if (!svc_handle) { CloseServiceHandle(scm_handle); @@ -696,7 +693,7 @@ static void test_get_displayname(void) ok(displaysize == strlen(servicename) * 2, "Expected the displaysize to be twice the size of the servicename\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* Buffer is too small */ SetLastError(0xdeadbeef); @@ -706,24 +703,21 @@ static void test_get_displayname(void) ok(!ret, "Expected failure\n"); ok(displaysize == tempsize, "Expected the needed buffersize\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* Get the displayname */ SetLastError(0xdeadbeef); ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(!lstrcmpiA(displayname, servicename), "Expected displayname to be %s, got %s\n", servicename, displayname); /* Delete the service */ ret = DeleteService(svc_handle); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); CloseServiceHandle(svc_handle); CloseServiceHandle(scm_handle); - - /* Wait a while. Just in case one of the following tests does a CreateService again */ - Sleep(1000); } static void test_get_servicekeyname(void) @@ -745,7 +739,7 @@ static void test_get_servicekeyname(void) ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -755,8 +749,8 @@ static void test_get_servicekeyname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 1, "Service size expected 1, got %ld\n", servicesize); /* Valid handle and buffer but no displayname */ servicesize = 200; @@ -765,24 +759,24 @@ static void test_get_servicekeyname(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize); + "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 200, "Service size expected 1, got %ld\n", servicesize); /* Test for nonexistent displayname */ SetLastError(0xdeadbeef); ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 1, "Service size expected 1, got %ld\n", servicesize); servicesize = 15; strcpy(servicename, "ABC"); ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 15, "Service size expected 15, got %ld\n", servicesize); ok(servicename[0] == 0, "Service name not empty\n"); servicesize = 15; @@ -790,8 +784,8 @@ static void test_get_servicekeyname(void) ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + ok(servicesize == 15, "Service size expected 15, got %ld\n", servicesize); ok(servicenameW[0] == 0, "Service name not empty\n"); servicesize = 0; @@ -799,17 +793,17 @@ static void test_get_servicekeyname(void) ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 1, "Service size expected 1, got %ld\n", servicesize); ok(servicename[0] == 'A', "Service name changed\n"); servicesize = 0; lstrcpyW( servicenameW, abcW ); ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); ok(!ret, "Expected failure\n"); - ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); + ok(servicesize == 2, "Service size expected 2, got %ld\n", servicesize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); ok(servicenameW[0] == 'A', "Service name changed\n"); servicesize = 1; @@ -817,17 +811,17 @@ static void test_get_servicekeyname(void) ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 1, "Service size expected 1, got %ld\n", servicesize); ok(servicename[0] == 0, "Service name not empty\n"); servicesize = 1; lstrcpyW( servicenameW, abcW ); ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); ok(!ret, "Expected failure\n"); - ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); + ok(servicesize == 2, "Service size expected 2, got %ld\n", servicesize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); ok(servicenameW[0] == 'A', "Service name changed\n"); servicesize = 2; @@ -835,17 +829,17 @@ static void test_get_servicekeyname(void) ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); - todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); + todo_wine ok(servicesize == 2, "Service size expected 2, got %ld\n", servicesize); ok(servicename[0] == 0, "Service name not empty\n"); servicesize = 2; lstrcpyW( servicenameW, abcW ); ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); ok(!ret, "Expected failure\n"); - ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); + ok(servicesize == 2, "Service size expected 2, got %ld\n", servicesize); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); ok(servicenameW[0] == 0, "Service name not empty\n"); /* Check if 'Spooler' exists */ @@ -867,15 +861,23 @@ static void test_get_servicekeyname(void) servicesize = 0; ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize); ok(!ret, "Expected failure\n"); + if (strcmp(displayname, "Print Spooler") != 0 && + GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) + { + win_skip("GetServiceKeyName() does not support localized display names: %s\n", displayname); /* Windows 7 */ + CloseServiceHandle(scm_handle); + return; /* All the tests that follow will fail too */ + } + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); /* Valid call with the correct buffersize */ SetLastError(0xdeadbeef); tempsize = servicesize; servicesize *= 2; ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); if (ret) { ok(strlen(servicename) == tempsize/2, @@ -889,7 +891,7 @@ static void test_get_servicekeyname(void) SetLastError(0xdeadbeef); servicesize *= 2; ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); if (ret) { ok(strlen(servicename) == tempsize/2, @@ -903,7 +905,7 @@ static void test_get_servicekeyname(void) ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); ok(servicenameW[0] == 0, "Buffer not empty\n"); CloseServiceHandle(scm_handle); @@ -922,7 +924,7 @@ static void test_query_svc(void) ret = QueryServiceStatus(NULL, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -942,13 +944,13 @@ static void test_query_svc(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = QueryServiceStatus(svc_handle, &status); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* Open the service with just enough rights. * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS') @@ -958,7 +960,7 @@ static void test_query_svc(void) SetLastError(0xdeadbeef); ret = QueryServiceStatus(svc_handle, &status); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); CloseServiceHandle(svc_handle); @@ -978,7 +980,7 @@ static void test_query_svc(void) ret = pQueryServiceStatusEx(NULL, 1, NULL, 0, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_LEVEL, - "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError()); + "Expected ERROR_INVALID_LEVEL, got %ld\n", GetLastError()); /* Passing a NULL parameter for the needed buffer size * will crash on anything but NT4. @@ -992,20 +994,20 @@ static void test_query_svc(void) { ok(!ret, "Expected failure\n"); ok(needed == sizeof(SERVICE_STATUS_PROCESS), - "Needed buffersize is wrong : %d\n", needed); + "Needed buffersize is wrong : %ld\n", needed); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); } /* Pass a correct buffer and buffersize but a NULL handle */ - statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS)); + statusproc = malloc(sizeof(SERVICE_STATUS_PROCESS)); bufsize = needed; SetLastError(0xdeadbeef); ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, statusproc); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); + free(statusproc); /* Correct handle and info level */ SetLastError(0xdeadbeef); @@ -1015,31 +1017,31 @@ static void test_query_svc(void) { ok(!ret, "Expected failure\n"); ok(needed == sizeof(SERVICE_STATUS_PROCESS), - "Needed buffersize is wrong : %d\n", needed); + "Needed buffersize is wrong : %ld\n", needed); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); } /* All parameters are OK but we don't have enough rights */ - statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS)); + statusproc = malloc(sizeof(SERVICE_STATUS_PROCESS)); bufsize = sizeof(SERVICE_STATUS_PROCESS); SetLastError(0xdeadbeef); ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, statusproc); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); + free(statusproc); /* Open the service with just enough rights. */ CloseServiceHandle(svc_handle); svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS); /* Everything should be fine now. */ - statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS)); + statusproc = malloc(sizeof(SERVICE_STATUS_PROCESS)); bufsize = sizeof(SERVICE_STATUS_PROCESS); SetLastError(0xdeadbeef); ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); if (statusproc->dwCurrentState == SERVICE_RUNNING) ok(statusproc->dwProcessId != 0, "Expect a process id for this running service\n"); @@ -1052,25 +1054,24 @@ static void test_query_svc(void) ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, NULL); ok(!ret, "Expected failure\n"); ok(broken(GetLastError() == ERROR_INVALID_PARAMETER) /* NT4 */ || - GetLastError() == ERROR_INVALID_ADDRESS, "got %d\n", GetLastError()); + GetLastError() == ERROR_INVALID_ADDRESS, "got %ld\n", GetLastError()); - HeapFree(GetProcessHeap(), 0, statusproc); + free(statusproc); CloseServiceHandle(svc_handle); CloseServiceHandle(scm_handle); } -static void test_enum_svc(void) +static BOOL test_enum_svc(int attempt) { SC_HANDLE scm_handle; - BOOL ret; + BOOL ret, alldone = FALSE; DWORD bufsize, needed, returned, resume; - DWORD neededW, returnedW; + DWORD neededA, returnedA; DWORD tempneeded, tempreturned, missing; DWORD servicecountactive, servicecountinactive; - ENUM_SERVICE_STATUSA *services; - ENUM_SERVICE_STATUSW *servicesW; - ENUM_SERVICE_STATUS_PROCESSA *exservices; + ENUM_SERVICE_STATUSA *servicesA; + ENUM_SERVICE_STATUSW *services; UINT i; /* All NULL or wrong */ @@ -1078,13 +1079,13 @@ static void test_enum_svc(void) ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = EnumServicesStatusW(NULL, 1, 0, NULL, 0, NULL, NULL, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); /* Open the service control manager with not enough rights at first */ scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -1095,14 +1096,14 @@ static void test_enum_svc(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = EnumServicesStatusW(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); /* Don't specify the two required pointers */ returned = 0xdeadbeef; @@ -1112,7 +1113,7 @@ static void test_enum_svc(void) ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); returned = 0xdeadbeef; SetLastError(0xdeadbeef); @@ -1121,7 +1122,7 @@ static void test_enum_svc(void) ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); /* Don't specify the two required pointers */ needed = 0xdeadbeef; @@ -1132,7 +1133,7 @@ static void test_enum_svc(void) "Expected no change to the needed buffer variable\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); needed = 0xdeadbeef; SetLastError(0xdeadbeef); @@ -1142,7 +1143,7 @@ static void test_enum_svc(void) "Expected no change to the needed buffer variable\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); /* No valid servicetype and servicestate */ needed = 0xdeadbeef; @@ -1151,10 +1152,10 @@ static void test_enum_svc(void) ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); - ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); + "Expected needed buffer size to be set to 0, got %ld\n", needed); + ok(returned == 0, "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); needed = 0xdeadbeef; returned = 0xdeadbeef; @@ -1162,11 +1163,11 @@ static void test_enum_svc(void) ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(returned == 0 || broken(returned != 0), /* nt4 */ - "Expected number of services to be set to 0, got %d\n", returned); + "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* No valid servicestate */ needed = 0xdeadbeef; @@ -1175,10 +1176,10 @@ static void test_enum_svc(void) ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); - ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); + "Expected needed buffer size to be set to 0, got %ld\n", needed); + ok(returned == 0, "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); needed = 0xdeadbeef; returned = 0xdeadbeef; @@ -1186,11 +1187,11 @@ static void test_enum_svc(void) ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(returned == 0 || broken(returned != 0), /* nt4 */ - "Expected number of services to be set to 0, got %d\n", returned); + "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* No valid servicetype */ needed = 0xdeadbeef; @@ -1199,10 +1200,10 @@ static void test_enum_svc(void) ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); - ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); + "Expected needed buffer size to be set to 0, got %ld\n", needed); + ok(returned == 0, "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); needed = 0xdeadbeef; returned = 0xdeadbeef; @@ -1210,11 +1211,11 @@ static void test_enum_svc(void) ret = EnumServicesStatusW(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(returned == 0 || broken(returned != 0), /* nt4 */ - "Expected number of services to be set to 0, got %d\n", returned); + "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* All parameters are correct but our access rights are wrong */ needed = 0xdeadbeef; @@ -1223,22 +1224,22 @@ static void test_enum_svc(void) ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); - ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); + "Expected needed buffer size to be set to 0, got %ld\n", needed); + ok(returned == 0, "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); + ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(returned == 0 || broken(returned != 0), /* nt4 */ - "Expected number of services to be set to 0, got %d\n", returned); + "Expected number of services to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* Open the service control manager with the needed rights */ CloseServiceHandle(scm_handle); @@ -1248,84 +1249,113 @@ static void test_enum_svc(void) needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); ok(!ret, "Expected failure\n"); ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n"); - ok(returned == 0, "Expected no service returned, got %d\n", returned); + ok(returned == 0, "Expected no service returned, got %ld\n", returned); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); - /* Test to show we get the same needed buffer size for the W-call */ - neededW = 0xdeadbeef; - returnedW = 0xdeadbeef; + /* Test to show we get the same needed buffer size for the A-call */ + neededA = 0xdeadbeef; + returnedA = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &neededW, &returnedW, NULL); + ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &neededA, &returnedA, NULL); ok(!ret, "Expected failure\n"); - ok(neededW != 0xdeadbeef && neededW > 0, "Expected the needed buffer size for this one service\n"); - ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); - ok(returnedW == 0, "Expected no service returned, got %d\n", returnedW); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); + ok(neededA != 0xdeadbeef && neededA > 0, "Expected the needed buffer size for this one service\n"); + ok(returnedA == 0, "Expected no service returned, got %ld\n", returnedA); + if (neededA != needed && attempt) + goto retry; /* service start|stop race condition */ + ok(neededA == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); /* Store the needed bytes */ tempneeded = needed; /* Allocate the correct needed bytes */ - services = HeapAlloc(GetProcessHeap(), 0, needed); + services = malloc(needed); bufsize = needed; needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services, bufsize, &needed, &returned, NULL); - ok(ret, "Expected success, got error %u\n", GetLastError()); + free(services); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n"); - HeapFree(GetProcessHeap(), 0, services); /* Store the number of returned services */ tempreturned = returned; - servicesW = HeapAlloc(GetProcessHeap(), 0, neededW); - bufsize = neededW; - neededW = 0xdeadbeef; - returnedW = 0xdeadbeef; + servicesA = malloc(neededA); + bufsize = neededA; + neededA = 0xdeadbeef; + returnedA = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, - servicesW, bufsize, &neededW, &returnedW, NULL); - ok(ret, "Expected success, got error %u\n", GetLastError()); - ok(neededW == 0, "Expected needed buffer to be 0 as we are done\n"); - ok(returnedW != 0xdeadbeef && returnedW > 0, "Expected some returned services\n"); - HeapFree(GetProcessHeap(), 0, servicesW); + ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + servicesA, bufsize, &neededA, &returnedA, NULL); + free(servicesA); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + if (!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY && GetACP() == CP_UTF8) + win_skip("Skipping some tests due to EnumServicesStatusA()'s broken UTF-8 support\n"); + else + { + ok(ret, "Expected success, got error %lu\n", GetLastError()); + ok(neededA == 0, "Expected needed buffer to be 0 as we are done\n"); + ok(returnedA != 0xdeadbeef && returnedA > 0, "Expected some returned services\n"); + } - /* Allocate less than the needed bytes and don't specify a resume handle */ - services = HeapAlloc(GetProcessHeap(), 0, tempneeded); - bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); + /* Allocate less than the needed bytes and don't specify a resume handle. + * More than one service will be missing because of the space needed for + * the strings. + */ + services = malloc(tempneeded); + bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSW); needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services, bufsize, &needed, &returned, NULL); + if (ret && needed == 0 && attempt) + { + free(services); + goto retry; /* service stop race condition */ + } ok(!ret, "Expected failure\n"); - ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n"); + ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); + todo_wine ok(needed < tempneeded, "Expected a smaller needed buffer size for the missing services\n"); + /* Experiments show bufsize + needed < tempneeded which proves the needed + * buffer size is an approximation. So it's best not to probe more. + */ ok(returned < tempreturned, "Expected fewer services to be returned\n"); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); /* Allocate less than the needed bytes, this time with a correct resume handle */ - bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); + bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSW); needed = 0xdeadbeef; returned = 0xdeadbeef; resume = 0; SetLastError(0xdeadbeef); - ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services, bufsize, &needed, &returned, &resume); + if (ret && needed == 0 && attempt) + { + free(services); + goto retry; /* service stop race condition */ + } ok(!ret, "Expected failure\n"); - ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n"); - ok(returned < tempreturned, "Expected fewer services to be returned\n"); + ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for the missing services, got %lx\n", needed); + todo_wine ok(needed < tempneeded, "Expected < %lu bytes needed for the remaining services, got %lu\n", tempneeded, needed); + ok(returned < tempreturned, "Expected < %lu remaining services, got %lu\n", tempreturned, returned); todo_wine ok(resume, "Expected a resume handle\n"); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); /* Fetch the missing services but pass a bigger buffer size */ missing = tempreturned - returned; @@ -1333,13 +1363,17 @@ static void test_enum_svc(void) needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services, bufsize, &needed, &returned, &resume); - ok(ret, "Expected success, got error %u\n", GetLastError()); - ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); - ok(returned == missing, "Expected %u services to be returned\n", missing); + free(services); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success, got error %lu\n", GetLastError()); + ok(needed == 0, "Expected 0 needed bytes as we are done, got %lu\n", needed); + if (returned < missing && strcmp(winetest_platform, "wine") && attempt) + goto retry; /* service stop race condition */ + todo_wine ok(returned == missing, "Expected %lu remaining services, got %lu\n", missing, returned); ok(resume == 0, "Expected the resume handle to be 0\n"); - HeapFree(GetProcessHeap(), 0, services); /* See if things add up */ @@ -1354,47 +1388,59 @@ static void test_enum_svc(void) */ /* Get the number of active win32 services */ - EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, + EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, &needed, &returned, NULL); - services = HeapAlloc(GetProcessHeap(), 0, needed); - EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services, - needed, &needed, &returned, NULL); - HeapFree(GetProcessHeap(), 0, services); + services = malloc(needed); + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, + services, needed, &needed, &returned, NULL); + free(services); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ servicecountactive = returned; /* Get the number of inactive win32 services */ - EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0, + EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0, &needed, &returned, NULL); - services = HeapAlloc(GetProcessHeap(), 0, needed); - EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services, - needed, &needed, &returned, NULL); - HeapFree(GetProcessHeap(), 0, services); + services = malloc(needed); + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, + services, needed, &needed, &returned, NULL); + free(services); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ servicecountinactive = returned; /* Get the number of win32 services */ - EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, + EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); - services = HeapAlloc(GetProcessHeap(), 0, needed); - EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services, - needed, &needed, &returned, NULL); - HeapFree(GetProcessHeap(), 0, services); + services = malloc(needed); + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + services, needed, &needed, &returned, NULL); + free(services); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ /* Check if total is the same as active and inactive win32 services */ - ok(returned == (servicecountactive + servicecountinactive), - "Something wrong in the calculation\n"); + if (returned != servicecountactive + servicecountinactive && attempt) + goto retry; /* service start|stop race condition */ + ok(returned == servicecountactive + servicecountinactive, + "Expected service count %ld == %ld + %ld\n", + returned, servicecountactive, servicecountinactive); /* Get all drivers and services * * Fetch the status of the last call as failing could make the following tests crash * on Wine (we don't return anything yet). */ - EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, + EnumServicesStatusW(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); - services = HeapAlloc(GetProcessHeap(), 0, needed); - ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, + services = malloc(needed); + ret = EnumServicesStatusW(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, services, needed, &needed, &returned, NULL); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success %lu\n", GetLastError()); /* Loop through all those returned drivers and services */ for (i = 0; ret && i < returned; i++) @@ -1410,24 +1456,63 @@ static void test_enum_svc(void) */ if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS)) { - if (status.dwCurrentState == SERVICE_STOPPED) - servicecountinactive--; - else + switch (status.dwCurrentState) + { + case SERVICE_START_PENDING: + case SERVICE_STOP_PENDING: + case SERVICE_PAUSE_PENDING: + case SERVICE_PAUSED: + case SERVICE_CONTINUE_PENDING: + trace("Got state %lx for service %s\n", status.dwCurrentState, + wine_dbgstr_w(services[i].lpServiceName)); + /* fall through */ + + case SERVICE_RUNNING: servicecountactive--; + break; + + case SERVICE_STOPPED: + servicecountinactive--; + break; + + default: + ok(0, "Got unknown state %lx for service %s\n", + status.dwCurrentState, wine_dbgstr_w(services[i].lpServiceName)); + break; + } } } - HeapFree(GetProcessHeap(), 0, services); + free(services); - ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive); - ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive); + if ((servicecountactive || servicecountinactive) && attempt) + goto retry; /* service start|stop race condition */ + ok(servicecountactive == 0, "Active services mismatch %lu\n", servicecountactive); + ok(servicecountinactive == 0, "Inactive services mismatch %lu\n", servicecountinactive); + alldone = TRUE; + +retry: CloseServiceHandle(scm_handle); + return alldone; +} + +static BOOL test_enum_svc_ex(int attempt) +{ + SC_HANDLE scm_handle; + BOOL ret, alldone = FALSE; + DWORD bufsize, needed, returned, resume; + DWORD neededA, returnedA; + DWORD tempneeded, tempreturned, missing; + DWORD servicecountactive, servicecountinactive; + ENUM_SERVICE_STATUSW *services; + ENUM_SERVICE_STATUS_PROCESSW *exservices; + UINT i; /* More or less the same for EnumServicesStatusExA */ if (!pEnumServicesStatusExA) { win_skip( "EnumServicesStatusExA not available\n" ); - return; + return TRUE; } /* All NULL or wrong */ @@ -1435,14 +1520,14 @@ static void test_enum_svc(void) ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_LEVEL, - "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError()); + "Expected ERROR_INVALID_LEVEL, got %ld\n", GetLastError()); /* All NULL or wrong, just the info level is correct */ SetLastError(0xdeadbeef); ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); /* Open the service control manager with not enough rights at first */ scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -1453,7 +1538,7 @@ static void test_enum_svc(void) ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); /* Don't specify the two required pointers */ needed = 0xdeadbeef; @@ -1464,7 +1549,7 @@ static void test_enum_svc(void) "Expected no change to the needed buffer variable\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); /* Don't specify the two required pointers */ returned = 0xdeadbeef; @@ -1474,7 +1559,7 @@ static void test_enum_svc(void) ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n"); ok(GetLastError() == ERROR_INVALID_ADDRESS || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error %d\n", GetLastError()); + "Unexpected last error %ld\n", GetLastError()); /* No valid servicetype and servicestate */ needed = 0xdeadbeef; @@ -1482,11 +1567,11 @@ static void test_enum_svc(void) SetLastError(0xdeadbeef); ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL); ok(!ret, "Expected failure\n"); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* No valid servicestate */ needed = 0xdeadbeef; @@ -1495,11 +1580,11 @@ static void test_enum_svc(void) ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL, NULL); ok(!ret, "Expected failure\n"); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* No valid servicetype */ needed = 0xdeadbeef; @@ -1508,11 +1593,11 @@ static void test_enum_svc(void) ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL); ok(!ret, "Expected failure\n"); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* No valid servicetype and servicestate and unknown service group */ needed = 0xdeadbeef; @@ -1521,11 +1606,11 @@ static void test_enum_svc(void) ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, "deadbeef_group"); ok(!ret, "Expected failure\n"); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); + "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* All parameters are correct but our access rights are wrong */ needed = 0xdeadbeef; @@ -1535,10 +1620,10 @@ static void test_enum_svc(void) NULL, 0, &needed, &returned, NULL, NULL); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); + "Expected needed buffer size to be set to 0, got %ld\n", needed); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* All parameters are correct, access rights are wrong but the * group name won't be checked yet. @@ -1550,10 +1635,10 @@ static void test_enum_svc(void) NULL, 0, &needed, &returned, NULL, "deadbeef_group"); ok(!ret, "Expected failure\n"); ok(needed == 0 || broken(needed != 0), /* nt4 */ - "Expected needed buffer size to be set to 0, got %d\n", needed); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); + "Expected needed buffer size to be set to 0, got %ld\n", needed); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); ok(GetLastError() == ERROR_ACCESS_DENIED, - "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); + "Expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); /* Open the service control manager with the needed rights */ CloseServiceHandle(scm_handle); @@ -1563,13 +1648,13 @@ static void test_enum_svc(void) needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, - NULL, 0, &needed, &returned, NULL, "deadbeef_group"); + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + NULL, 0, &needed, &returned, NULL, L"deadbeef_group"); ok(!ret, "Expected failure\n"); - ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); - ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed); + ok(returned == 0, "Expected number of service to be set to 0, got %ld\n", returned); + ok(needed == 0, "Expected needed buffer size to be set to 0, got %ld\n", needed); ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, - "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %ld\n", GetLastError()); /* TODO: Create a test that makes sure we enumerate all services that don't * belong to a group. (specifying ""). @@ -1579,125 +1664,185 @@ static void test_enum_svc(void) needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL); ok(!ret, "Expected failure\n"); - ok(returned == 0, "Expected no service returned, got %d\n", returned); + ok(returned == 0, "Expected no service returned, got %ld\n", returned); ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); - /* Test to show we get the same needed buffer size for the W-call */ - neededW = 0xdeadbeef; - ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, - NULL, 0, &neededW, &returnedW, NULL, NULL); + /* Test to show we get the same needed buffer size for the A-call */ + neededA = 0xdeadbeef; + returnedA = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + NULL, 0, &neededA, &returnedA, NULL, NULL); ok(!ret, "Expected failure\n"); - ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); + ok(GetLastError() == ERROR_MORE_DATA, + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); + ok(neededA != 0xdeadbeef && neededA > 0, "Expected the needed buffer size for this one service\n"); + ok(returnedA == 0, "Expected no service returned, got %ld\n", returnedA); + if (neededA != needed && attempt) + goto retry; /* service start|stop race condition */ + ok(neededA == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); + ok(GetLastError() == ERROR_MORE_DATA, + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); /* Store the needed bytes */ tempneeded = needed; - /* Allocate the correct needed bytes */ - exservices = HeapAlloc(GetProcessHeap(), 0, needed); - bufsize = needed; - needed = 0xdeadbeef; + /* Show the Ex call returns the same service count as the regular enum */ + EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + NULL, 0, &needed, &returned, NULL); + services = malloc(needed); returned = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, - (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, + services, needed, &needed, &returned, NULL); + free(services); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); - ok(returned == tempreturned, "Expected the same number of service from this function\n"); - HeapFree(GetProcessHeap(), 0, exservices); + ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n"); /* Store the number of returned services */ tempreturned = returned; - /* Allocate less than the needed bytes and don't specify a resume handle */ - exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded); - bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); + /* Allocate the correct needed bytes */ + exservices = malloc(tempneeded); + bufsize = tempneeded; needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL); + free(exservices); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success, got error %lu\n", GetLastError()); + ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); + ok(returned == tempreturned, "Expected the same number of service from this function\n"); + + /* Store the number of returned services */ + tempreturned = returned; + + /* Allocate less than the needed bytes and don't specify a resume handle. + * More than one service will be missing because of the space needed for + * the strings. + */ + exservices = malloc(tempneeded); + bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSW); + needed = 0xdeadbeef; + returned = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL); + if (ret && needed == 0 && attempt) + { + free(exservices); + goto retry; /* service stop race condition */ + } ok(!ret, "Expected failure\n"); - ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); + ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for the missing services\n"); + todo_wine ok(needed < tempneeded, "Expected a smaller needed buffer size for the missing services\n"); + /* Experiments show bufsize + needed < tempneeded which proves the needed + * buffer size is an approximation. So it's best not to probe more. + */ ok(returned < tempreturned, "Expected fewer services to be returned\n"); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); /* Allocate less than the needed bytes, this time with a correct resume handle */ - bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); + bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSW); needed = 0xdeadbeef; returned = 0xdeadbeef; resume = 0; SetLastError(0xdeadbeef); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL); + if (ret && needed == 0 && attempt) + { + free(exservices); + goto retry; /* service stop race condition */ + } ok(!ret, "Expected failure\n"); - ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); + ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for the missing services\n"); + todo_wine ok(needed < tempneeded, "Expected a smaller needed buffer size for the missing services\n"); ok(returned < tempreturned, "Expected fewer services to be returned\n"); todo_wine ok(resume, "Expected a resume handle\n"); ok(GetLastError() == ERROR_MORE_DATA, - "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); + "Expected ERROR_MORE_DATA, got %ld\n", GetLastError()); - /* Fetch that last service but pass a bigger buffer size */ + /* Fetch the missing services but pass a bigger buffer size */ missing = tempreturned - returned; bufsize = tempneeded; needed = 0xdeadbeef; returned = 0xdeadbeef; SetLastError(0xdeadbeef); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL); - ok(ret, "Expected success, got error %u\n", GetLastError()); + free(exservices); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); - ok(returned == missing, "Expected %u services to be returned\n", missing); + ok(returned == missing, "Expected %lu services to be returned\n", missing); ok(resume == 0, "Expected the resume handle to be 0\n"); - HeapFree(GetProcessHeap(), 0, exservices); /* See if things add up */ /* Get the number of active win32 services */ - pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE, + pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, &needed, &returned, NULL, NULL); - exservices = HeapAlloc(GetProcessHeap(), 0, needed); - pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE, - (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); - HeapFree(GetProcessHeap(), 0, exservices); + exservices = malloc(needed); + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE, + (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); + free(exservices); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ servicecountactive = returned; /* Get the number of inactive win32 services */ - pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE, + pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0, &needed, &returned, NULL, NULL); - exservices = HeapAlloc(GetProcessHeap(), 0, needed); - pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE, - (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); - HeapFree(GetProcessHeap(), 0, exservices); + exservices = malloc(needed); + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE, + (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); + free(exservices); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ servicecountinactive = returned; /* Get the number of win32 services */ - pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL); - exservices = HeapAlloc(GetProcessHeap(), 0, needed); - pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, - (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); - HeapFree(GetProcessHeap(), 0, exservices); + exservices = malloc(needed); + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, + (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); + free(exservices); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ /* Check if total is the same as active and inactive win32 services */ - ok(returned == (servicecountactive + servicecountinactive), - "Something wrong in the calculation\n"); + if (returned != servicecountactive + servicecountinactive && attempt) + goto retry; /* service start|stop race condition */ + ok(returned == servicecountactive + servicecountinactive, + "Expected service count %ld == %ld + %ld\n", + returned, servicecountactive, servicecountinactive); /* Get all drivers and services */ - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER, + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL); ok(!ret, "Expected failure\n"); - exservices = HeapAlloc(GetProcessHeap(), 0, needed); - ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER, + exservices = malloc(needed); + ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); - ok(ret, "Expected success %u\n", GetLastError()); + if (!ret && GetLastError() == ERROR_MORE_DATA && attempt) + goto retry; /* service start race condition */ + ok(ret, "Expected success %lu\n", GetLastError()); /* Loop through all those returned drivers and services */ for (i = 0; i < returned; i++) @@ -1721,30 +1866,60 @@ static void test_enum_svc(void) if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS)) { - if (status.dwCurrentState != SERVICE_STOPPED) + switch (status.dwCurrentState) { + case SERVICE_START_PENDING: + case SERVICE_STOP_PENDING: + trace("Got state %lx (pid=%04lx) for service %s\n", + status.dwCurrentState, status.dwProcessId, + wine_dbgstr_w(exservices[i].lpServiceName)); + /* There may or may not be a process id */ + servicecountactive--; + break; + + case SERVICE_PAUSE_PENDING: + case SERVICE_PAUSED: + case SERVICE_CONTINUE_PENDING: + trace("Got state %lx (pid=%04lx) for service %s\n", + status.dwCurrentState, status.dwProcessId, + wine_dbgstr_w(exservices[i].lpServiceName)); + /* fall through */ + + case SERVICE_RUNNING: /* We expect a process id for every running service */ ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n", - exservices[i].lpServiceName); - + wine_dbgstr_w(exservices[i].lpServiceName)); servicecountactive--; - } - else - { + break; + + case SERVICE_STOPPED: /* We shouldn't have a process id for inactive services */ - ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n", - exservices[i].lpServiceName, status.dwCurrentState); + ok(status.dwProcessId == 0, "Service %s state %lu shouldn't have an associated process id\n", + wine_dbgstr_w(exservices[i].lpServiceName), status.dwCurrentState); servicecountinactive--; + break; + + default: + ok(0, "Got unknown state %lx (pid=%04lx) for service %s\n", + status.dwCurrentState, status.dwProcessId, + wine_dbgstr_w(exservices[i].lpServiceName)); + break; } } } - HeapFree(GetProcessHeap(), 0, exservices); + free(exservices); - ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive); - ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive); + if ((servicecountactive || servicecountinactive) && attempt) + goto retry; /* service start|stop race condition */ + ok(servicecountactive == 0, "Active services mismatch %lu\n", servicecountactive); + ok(servicecountinactive == 0, "Inactive services mismatch %lu\n", servicecountinactive); + alldone = TRUE; + +retry: CloseServiceHandle(scm_handle); + return alldone; } static void test_close(void) @@ -1756,7 +1931,7 @@ static void test_close(void) SetLastError(0xdeadbeef); ret = CloseServiceHandle(NULL); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError()); /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */ @@ -1764,7 +1939,91 @@ static void test_close(void) handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); SetLastError(0xdeadbeef); ret = CloseServiceHandle(handle); - ok(ret, "Expected success got error %u\n", GetLastError()); + ok(ret, "Expected success got error %lu\n", GetLastError()); +} + +static void test_wow64(void) +{ + SC_HANDLE manager, service; + BOOL wow64, ret; + HANDLE file; + + if (!pIsWow64Process || !pIsWow64Process(GetCurrentProcess(), &wow64) || !wow64) + { + skip("Not running under WoW64.\n"); + return; + } + + if (!(manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE))) + { + skip("Not enough permissions to create a service.\n"); + return; + } + + file = CreateFileA("C:\\windows\\syswow64\\winetestsvc.exe", GENERIC_WRITE, + 0, NULL, CREATE_ALWAYS, 0, NULL); + CloseHandle(file); + + service = CreateServiceA(manager, "winetestsvc", "winetestsvc", + SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE, + SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + "C:\\windows\\system32\\winetestsvc.exe service serve", NULL, NULL, NULL, NULL, NULL); + ok(!!service, "Failed to create service, error %lu.\n", GetLastError()); + ret = StartServiceA(service, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Got error %lu.\n", GetLastError()); + + ret = DeleteService(service); + ok(ret, "Failed to delete service, error %lu.\n", GetLastError()); + CloseServiceHandle(service); + + service = CreateServiceA(manager, "winetestsvc2", "winetestsvc2", SERVICE_START | DELETE, + SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + "C:\\windows\\system32\\winetestsvc.exe", NULL, NULL, NULL, NULL, NULL); + ok(!!service, "Failed to create service, error %lu.\n", GetLastError()); + ret = StartServiceA(service, 0, NULL); + ok(!ret, "Expected failure.\n"); + todo_wine ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %lu.\n", GetLastError()); + + ret = DeleteService(service); + ok(ret, "Failed to delete service, error %lu.\n", GetLastError()); + CloseServiceHandle(service); + + ret = DeleteFileA("C:\\windows\\syswow64\\winetestsvc.exe"); + ok(ret, "Failed to delete file, error %lu.\n", GetLastError()); + + file = CreateFileA("C:\\windows\\sysnative\\winetestsvc.exe", GENERIC_WRITE, + 0, NULL, CREATE_ALWAYS, 0, NULL); + CloseHandle(file); + + service = CreateServiceA(manager, "winetestsvc3", "winetestsvc3", SERVICE_START | DELETE, + SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + "C:\\windows\\system32\\winetestsvc.exe service serve", NULL, NULL, NULL, NULL, NULL); + ok(!!service, "Failed to create service, error %lu.\n", GetLastError()); + ret = StartServiceA(service, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %lu.\n", GetLastError()); + + ret = DeleteService(service); + ok(ret, "Failed to delete service, error %lu.\n", GetLastError()); + CloseServiceHandle(service); + + service = CreateServiceA(manager, "winetestsvc4", "winetestsvc4", SERVICE_START | DELETE, + SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + "C:\\windows\\system32\\winetestsvc.exe", NULL, NULL, NULL, NULL, NULL); + ok(!!service, "Failed to create service, error %lu.\n", GetLastError()); + ret = StartServiceA(service, 0, NULL); + ok(!ret, "Expected failure.\n"); + todo_wine ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Got error %lu.\n", GetLastError()); + + ret = DeleteService(service); + ok(ret, "Failed to delete service, error %lu.\n", GetLastError()); + CloseServiceHandle(service); + + ret = DeleteFileA("C:\\windows\\sysnative\\winetestsvc.exe"); + ok(ret, "Failed to delete file, error %lu.\n", GetLastError()); + + CloseServiceHandle(manager); } static void test_sequence(void) @@ -1773,7 +2032,7 @@ static void test_sequence(void) BOOL ret, is_nt4; QUERY_SERVICE_CONFIGA *config; DWORD given, needed; - static const CHAR servicename [] = "Winetest"; + static const CHAR servicename [] = "winetest_sequence"; static const CHAR displayname [] = "Winetest dummy service"; static const CHAR displayname2[] = "Winetest dummy service (2)"; static const CHAR pathname [] = "we_dont_care.exe"; @@ -1791,7 +2050,7 @@ static void test_sequence(void) return; } else - ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError()); + ok(scm_handle != NULL, "Could not get a handle to the manager: %ld\n", GetLastError()); if (!scm_handle) return; svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ); @@ -1818,7 +2077,7 @@ static void test_sequence(void) CloseServiceHandle(scm_handle); return; } - ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError()); + ok(svc_handle != NULL, "Could not open the service : %ld\n", GetLastError()); } else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED)) { @@ -1828,8 +2087,8 @@ static void test_sequence(void) } else { - ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError()); - if ((svc_handle != NULL) && (pGetSecurityInfo != NULL)) + ok(svc_handle != NULL, "Could not create the service : %ld\n", GetLastError()); + if (svc_handle != NULL) { PSID sidOwner, sidGroup; PACL dacl, sacl; @@ -1839,26 +2098,26 @@ static void test_sequence(void) BOOL bret; /* Test using GetSecurityInfo to obtain security information */ - retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, &sidOwner, + retval = GetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, &sidOwner, &sidGroup, &dacl, &sacl, &pSD); LocalFree(pSD); - ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); - retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, + ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %ld\n", retval); + retval = GetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); LocalFree(pSD); - ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); + ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %ld\n", retval); if (!is_nt4) { - retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, + retval = GetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &pSD); - ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); + ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %ld\n", retval); LocalFree(pSD); SetLastError(0xdeadbeef); - retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, + retval = GetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, NULL); error = GetLastError(); - ok(retval == ERROR_INVALID_PARAMETER, "Expected GetSecurityInfo to fail: result %d\n", retval); - ok(error == 0xdeadbeef, "Unexpected last error %d\n", error); + ok(retval == ERROR_INVALID_PARAMETER, "Expected GetSecurityInfo to fail: result %ld\n", retval); + ok(error == 0xdeadbeef, "Unexpected last error %ld\n", error); } else win_skip("A NULL security descriptor in GetSecurityInfo results in an exception on NT4.\n"); @@ -1870,7 +2129,7 @@ static void test_sequence(void) ok(!bret, "Expected QueryServiceObjectSecurity to fail: result %d\n", bret); ok(error == ERROR_INSUFFICIENT_BUFFER || broken(error == ERROR_INVALID_ADDRESS) || broken(error == ERROR_INVALID_PARAMETER), - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", error); + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", error); if (error != ERROR_INSUFFICIENT_BUFFER) n1 = 1024; pSD = LocalAlloc(0, n1); bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, pSD, n1, &n2); @@ -1893,23 +2152,23 @@ static void test_sequence(void) SetLastError(0xdeadbeef); ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed); ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); - config = HeapAlloc(GetProcessHeap(), 0, needed); + config = malloc(needed); given = needed; SetLastError(0xdeadbeef); ret = QueryServiceConfigA(svc_handle, config, given, &needed); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName && config->lpDisplayName, "Expected all string struct members to be non-NULL\n"); ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS), - "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType); - ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType); - ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl); + "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %ld\n", config->dwServiceType); + ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %ld\n", config->dwStartType); + ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %ld\n", config->dwErrorControl); ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName); ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup); - ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId); + ok(config->dwTagId == 0, "Expected 0, got %ld\n", config->dwTagId); /* TODO: Show the double 0 terminated string */ todo_wine { @@ -1920,33 +2179,29 @@ static void test_sequence(void) ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2); - ok(ret, "ChangeServiceConfig failed (err=%d)\n", GetLastError()); + ok(ret, "ChangeServiceConfig failed (err=%ld)\n", GetLastError()); QueryServiceConfigA(svc_handle, NULL, 0, &needed); - config = HeapReAlloc(GetProcessHeap(), 0, config, needed); + config = realloc(config, needed); ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n"); ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName && config->lpDisplayName, "Expected all string struct members to be non-NULL\n"); ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS), - "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType); - ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType); - ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl); + "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %ld\n", config->dwServiceType); + ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %ld\n", config->dwStartType); + ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %ld\n", config->dwErrorControl); ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName); ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup); - ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId); + ok(config->dwTagId == 0, "Expected 0, got %ld\n", config->dwTagId); ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName); ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName); SetLastError(0xdeadbeef); ret = DeleteService(svc_handle); - ok(ret, "Expected success, got error %u\n", GetLastError()); + ok(ret, "Expected success, got error %lu\n", GetLastError()); CloseServiceHandle(svc_handle); - - /* Wait a while. The following test does a CreateService again */ - Sleep(1000); - CloseServiceHandle(scm_handle); - HeapFree(GetProcessHeap(), 0, config); + free(config); } static void test_queryconfig2(void) @@ -1958,7 +2213,8 @@ static void test_queryconfig2(void) LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer; LPSERVICE_DESCRIPTIONW pConfigW = (LPSERVICE_DESCRIPTIONW)buffer; SERVICE_PRESHUTDOWN_INFO preshutdown_info; - static const CHAR servicename [] = "Winetest"; + SERVICE_DELAYED_AUTO_START_INFO auto_start_info; + static const CHAR servicename [] = "winetest_query_config2"; static const CHAR displayname [] = "Winetest dummy service"; static const CHAR pathname [] = "we_dont_care.exe"; static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0"; @@ -1982,7 +2238,7 @@ static void test_queryconfig2(void) if(GetLastError() == ERROR_ACCESS_DENIED) skip("Not enough rights to get a handle to the manager\n"); else - ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError()); + ok(FALSE, "Could not get a handle to the manager: %ld\n", GetLastError()); return; } @@ -2007,7 +2263,7 @@ static void test_queryconfig2(void) if(GetLastError() == ERROR_ACCESS_DENIED) skip("Not enough rights to open the service\n"); else - ok(FALSE, "Could not open the service : %d\n", GetLastError()); + ok(FALSE, "Could not open the service : %ld\n", GetLastError()); CloseServiceHandle(scm_handle); return; } @@ -2018,7 +2274,7 @@ static void test_queryconfig2(void) CloseServiceHandle(scm_handle); return; } - ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError()); + ok(svc_handle != NULL, "Could not create the service : %ld\n", GetLastError()); if (!svc_handle) { CloseServiceHandle(scm_handle); @@ -2028,49 +2284,49 @@ static void test_queryconfig2(void) SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError()); + ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError()); + ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError()); + ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed); ok(!ret, "expected QueryServiceConfig2A to fail\n"); ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()), - "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError()); + ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %ld\n", GetLastError()); needed = 0; SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %ld\n", needed); needed = 0; pConfig->lpDescription = (LPSTR)0xdeadbeef; ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed); ok(ret, "expected QueryServiceConfig2A to succeed\n"); - ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed); + ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %ld\n", needed); ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription); SetLastError(0xdeadbeef); needed = 0; ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %ld\n", needed); if(!pChangeServiceConfig2A) { @@ -2090,13 +2346,13 @@ static void test_queryconfig2(void) expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */ ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(needed == expected, "expected needed to be %ld, got %ld\n", expected, needed); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed); ok(!ret, "expected QueryServiceConfig2A to fail\n"); - ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed); @@ -2120,8 +2376,8 @@ static void test_queryconfig2(void) expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description); ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed); ok(!ret, "expected QueryServiceConfig2W to fail\n"); - ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed); + ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(needed == expected, "expected needed to be %ld, got %ld\n", expected, needed); SetLastError(0xdeadbeef); ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed); @@ -2188,6 +2444,7 @@ static void test_queryconfig2(void) "expected lpDescription to be null, got %s\n", wine_dbgstr_w(pConfigW->lpDescription)); SetLastError(0xdeadbeef); + needed = 0; ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed); if(!ret && GetLastError()==ERROR_INVALID_LEVEL) @@ -2196,32 +2453,59 @@ static void test_queryconfig2(void) win_skip("SERVICE_CONFIG_PRESHUTDOWN_INFO not supported\n"); goto cleanup; } - ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError()); - ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed); - ok(preshutdown_info.dwPreshutdownTimeout == 180000, "Default PreshutdownTimeout = %d\n", - preshutdown_info.dwPreshutdownTimeout); + ok(ret, "expected QueryServiceConfig2W to succeed (%ld)\n", GetLastError()); + ok(needed == sizeof(preshutdown_info), "needed = %ld\n", needed); + ok(preshutdown_info.dwPreshutdownTimeout == 180000 + || preshutdown_info.dwPreshutdownTimeout == 10000 /* Win10 1709+ */, + "Default PreshutdownTimeout = %ld\n", preshutdown_info.dwPreshutdownTimeout); SetLastError(0xdeadbeef); preshutdown_info.dwPreshutdownTimeout = -1; ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, (LPVOID)&preshutdown_info); - ok(ret, "expected ChangeServiceConfig2A to succeed (%d)\n", GetLastError()); + ok(ret, "expected ChangeServiceConfig2A to succeed (%ld)\n", GetLastError()); ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed); - ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError()); - ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed); - ok(preshutdown_info.dwPreshutdownTimeout == -1, "New PreshutdownTimeout = %d\n", + ok(ret, "expected QueryServiceConfig2W to succeed (%ld)\n", GetLastError()); + ok(needed == sizeof(preshutdown_info), "needed = %ld\n", needed); + ok(preshutdown_info.dwPreshutdownTimeout == -1, "New PreshutdownTimeout = %ld\n", preshutdown_info.dwPreshutdownTimeout); + SetLastError(0xdeadbeef); + needed = 0; + auto_start_info.fDelayedAutostart = 0xdeadbeef; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, + (LPBYTE)&auto_start_info, sizeof(auto_start_info), &needed); + ok(ret, "expected QueryServiceConfig2W to succeed (%ld)\n", GetLastError()); + ok(needed == sizeof(auto_start_info), "needed = %ld\n", needed); + ok(auto_start_info.fDelayedAutostart == 0, "fDelayedAutostart = %d\n", auto_start_info.fDelayedAutostart); + + SetLastError(0xdeadbeef); + auto_start_info.fDelayedAutostart = 3; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, + (LPBYTE)&auto_start_info); + ok(!ret, "expected ChangeServiceConfig2A to fail\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %ld\n", GetLastError()); + + SetLastError(0xdeadbeef); + auto_start_info.fDelayedAutostart = 1; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, + (LPBYTE)&auto_start_info); + ok(ret, "expected ChangeServiceConfig2A to succeed (%ld)\n", GetLastError()); + + SetLastError(0xdeadbeef); + needed = 0; + auto_start_info.fDelayedAutostart = 0xdeadbeef; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, + (LPBYTE)&auto_start_info, sizeof(auto_start_info), &needed); + ok(ret, "expected QueryServiceConfig2W to succeed (%ld)\n", GetLastError()); + ok(needed == sizeof(auto_start_info), "needed = %ld\n", needed); + ok(auto_start_info.fDelayedAutostart == 1, "fDelayedAutostart = %d\n", auto_start_info.fDelayedAutostart); + cleanup: DeleteService(svc_handle); - CloseServiceHandle(svc_handle); - - /* Wait a while. The following test does a CreateService again */ - Sleep(1000); - CloseServiceHandle(scm_handle); } @@ -2231,9 +2515,6 @@ static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, DWORD is_nt4 DWORD le1, le2; SERVICE_STATUS status; -#ifdef __REACTOS__ - fprintf(stdout, "ROSTESTS-56: Hello sysreg, I am awake\n"); -#endif ret = StartServiceA(svc_handle, 0, NULL); le1 = GetLastError(); ok(!ret, "%s: StartServiceA() should have failed\n", name); @@ -2244,24 +2525,24 @@ static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, DWORD is_nt4 SERVICE_STATUS_PROCESS statusproc; ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)&statusproc, sizeof(statusproc), &needed); - ok(ret, "%s: QueryServiceStatusEx() failed le=%u\n", name, GetLastError()); - ok(statusproc.dwCurrentState == SERVICE_STOPPED, "%s: should be stopped state=%x\n", name, statusproc.dwCurrentState); - ok(statusproc.dwProcessId == 0, "%s: ProcessId should be 0 instead of %x\n", name, statusproc.dwProcessId); + ok(ret, "%s: QueryServiceStatusEx() failed le=%lu\n", name, GetLastError()); + ok(statusproc.dwCurrentState == SERVICE_STOPPED, "%s: should be stopped state=%lx\n", name, statusproc.dwCurrentState); + ok(statusproc.dwProcessId == 0, "%s: ProcessId should be 0 instead of %lx\n", name, statusproc.dwProcessId); } ret = StartServiceA(svc_handle, 0, NULL); le2 = GetLastError(); ok(!ret, "%s: StartServiceA() should have failed\n", name); - ok(le2 == le1, "%s: the second try should yield the same error: %u != %u\n", name, le1, le2); + ok(le2 == le1, "%s: the second try should yield the same error: %lu != %lu\n", name, le1, le2); status.dwCurrentState = 0xdeadbeef; ret = ControlService(svc_handle, SERVICE_CONTROL_STOP, &status); le2 = GetLastError(); ok(!ret, "%s: ControlService() should have failed\n", name); - ok(le2 == ERROR_SERVICE_NOT_ACTIVE, "%s: %d != ERROR_SERVICE_NOT_ACTIVE\n", name, le2); + ok(le2 == ERROR_SERVICE_NOT_ACTIVE, "%s: %ld != ERROR_SERVICE_NOT_ACTIVE\n", name, le2); ok(status.dwCurrentState == SERVICE_STOPPED || broken(is_nt4), /* NT4 returns a random value */ - "%s: should be stopped state=%x\n", name, status.dwCurrentState); + "%s: should be stopped state=%lx\n", name, status.dwCurrentState); return le1; } @@ -2283,20 +2564,20 @@ static void CALLBACK notify_cb(void *user) { case PHASE_STOPPED: ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, - "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); + "Got wrong notification status: %lu\n", data->notify.dwNotificationStatus); ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_STOPPED, - "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); + "Got wrong service state: 0x%lx\n", data->notify.ServiceStatus.dwCurrentState); ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_STOPPED, - "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); + "Got wrong notification triggered: 0x%lx\n", data->notify.dwNotificationTriggered); break; case PHASE_RUNNING: ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, - "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); + "Got wrong notification status: %lu\n", data->notify.dwNotificationStatus); ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_RUNNING, - "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); + "Got wrong service state: 0x%lx\n", data->notify.ServiceStatus.dwCurrentState); ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_RUNNING, - "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); + "Got wrong notification triggered: 0x%lx\n", data->notify.dwNotificationTriggered); break; } @@ -2333,56 +2614,77 @@ static void test_servicenotify(SC_HANDLE scm_handle, const char *servicename) data.was_called = FALSE; dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); - ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); + ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %lu\n", dr); dr = SleepEx(100, TRUE); - ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); + ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %lu\n", dr); ok(data.was_called == TRUE, "APC wasn't called\n"); br = StartServiceA(svc, 0, NULL); - ok(br, "StartService failed: %u\n", GetLastError()); + ok(br, "StartService failed: %lu\n", GetLastError()); /* receive running notification */ data.phase = PHASE_RUNNING; data.was_called = FALSE; dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); - ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); + ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %lu\n", dr); dr = SleepEx(100, TRUE); - ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); + ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %lu\n", dr); ok(data.was_called == TRUE, "APC wasn't called\n"); - /* cannot register two notifications */ + /* cannot register two notifications on the same handle */ data.phase = PHASE_STOPPED; data.was_called = FALSE; dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); - ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); + ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %lu\n", dr); memset(&data2.notify, 0, sizeof(data2.notify)); data2.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; data2.notify.pfnNotifyCallback = ¬ify_cb; data2.notify.pContext = &data2; + data2.phase = PHASE_RUNNING; + data2.was_called = FALSE; dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data2.notify); - ok(dr == ERROR_SUCCESS || /* win8+ */ - dr == ERROR_ALREADY_REGISTERED, "NotifyServiceStatusChangeW gave wrong result: %u\n", dr); - - /* should receive no notification because status has not changed. - * on win8+, SleepEx quits early but the callback is still not invoked. */ - dr2 = SleepEx(100, TRUE); - ok((dr == ERROR_SUCCESS && dr2 == WAIT_IO_COMPLETION) || /* win8+ */ - (dr == ERROR_ALREADY_REGISTERED && dr2 == 0), "Got wrong SleepEx result: %u\n", dr); + ok(dr == ERROR_ALREADY_REGISTERED || !dr /* Win8+ */, "wrong error %lu\n", dr); + if (!dr) + { + dr = SleepEx(100, TRUE); + ok(dr == WAIT_IO_COMPLETION, "got %lu\n", dr); + ok(data2.was_called, "APC was not called\n"); + } + else + { + dr = SleepEx(100, TRUE); + ok(!dr, "got %lu\n", dr); + ok(!data2.was_called, "APC should not have been called\n"); + } ok(data.was_called == FALSE, "APC should not have been called\n"); + memset(&data2.notify, 0, sizeof(data2.notify)); + data2.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; + data2.notify.pfnNotifyCallback = ¬ify_cb; + data2.notify.pContext = &data; + data2.svc = svc2; + data2.phase = PHASE_STOPPED; + data2.was_called = FALSE; + + /* it's possible to have multiple notifications using different service handles */ + dr = pNotifyServiceStatusChangeW(svc2, SERVICE_NOTIFY_STOPPED, &data2.notify); + ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW gave wrong result: %lu\n", dr); + /* stop service and receive notifiction */ br = ControlService(svc, SERVICE_CONTROL_STOP, &status); - ok(br, "ControlService failed: %u\n", GetLastError()); + ok(br, "ControlService failed: %lu\n", GetLastError()); dr = SleepEx(100, TRUE); - ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); + dr2 = SleepEx(100, TRUE); + ok(dr == WAIT_IO_COMPLETION || dr2 == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %lu\n", dr); ok(data.was_called == TRUE, "APC wasn't called\n"); + ok(data2.was_called == TRUE, "APC wasn't called\n"); /* test cancelation: create notify on svc that will block until service * start; close svc; start service on svc2; verify that notification does @@ -2391,19 +2693,19 @@ static void test_servicenotify(SC_HANDLE scm_handle, const char *servicename) data.phase = PHASE_RUNNING; data.was_called = FALSE; dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); - ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); + ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %lu\n", dr); CloseServiceHandle(svc); br = StartServiceA(svc2, 0, NULL); - ok(br, "StartService failed: %u\n", GetLastError()); + ok(br, "StartService failed: %lu\n", GetLastError()); dr = SleepEx(100, TRUE); - ok(dr == 0, "Got wrong SleepEx result: %u\n", dr); + ok(dr == 0, "Got wrong SleepEx result: %lu\n", dr); ok(data.was_called == FALSE, "APC should not have been called\n"); br = ControlService(svc2, SERVICE_CONTROL_STOP, &status); - ok(br, "ControlService failed: %u\n", GetLastError()); + ok(br, "ControlService failed: %lu\n", GetLastError()); CloseServiceHandle(svc2); } @@ -2413,7 +2715,7 @@ static void test_start_stop(void) BOOL ret; SC_HANDLE scm_handle, svc_handle; DWORD le, is_nt4; - static const char servicename[] = "Winetest"; + static const char servicename[] = "winetest_start_stop"; char cmd[MAX_PATH+20]; const char* displayname; @@ -2424,7 +2726,7 @@ static void test_start_stop(void) if(GetLastError() == ERROR_ACCESS_DENIED) skip("Not enough rights to get a handle to the manager\n"); else - ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError()); + ok(FALSE, "Could not get a handle to the manager: %ld\n", GetLastError()); return; } @@ -2452,16 +2754,16 @@ static void test_start_stop(void) if(GetLastError() == ERROR_ACCESS_DENIED) skip("Not enough rights to create the service\n"); else - ok(FALSE, "Could not create the service: %d\n", GetLastError()); + ok(FALSE, "Could not create the service: %ld\n", GetLastError()); goto cleanup; } le = try_start_stop(svc_handle, displayname, is_nt4); - ok(le == ERROR_SERVICE_DISABLED, "%d != ERROR_SERVICE_DISABLED\n", le); + ok(le == ERROR_SERVICE_DISABLED, "%ld != ERROR_SERVICE_DISABLED\n", le); /* Then one with a bad path */ displayname = "Winetest Bad Path"; ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, "c:\\no_such_file.exe", NULL, NULL, NULL, NULL, NULL, displayname); - ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError()); + ok(ret, "ChangeServiceConfig() failed le=%lu\n", GetLastError()); try_start_stop(svc_handle, displayname, is_nt4); if (is_nt4) @@ -2473,24 +2775,18 @@ static void test_start_stop(void) goto cleanup; } - if (!winetest_interactive) - { - skip("ROSTESTS-151: Skipping service start timeout tests because they take too long. This is not a bug!\n"); - goto cleanup; - } - /* Again with a process that exits right away */ displayname = "Winetest Exit Service"; ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname); - ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError()); + ok(ret, "ChangeServiceConfig() failed le=%lu\n", GetLastError()); le = try_start_stop(svc_handle, displayname, is_nt4); - ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le); + ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%ld != ERROR_SERVICE_REQUEST_TIMEOUT\n", le); /* create a real service and test notifications */ sprintf(cmd, "%s service serve", selfname); displayname = "Winetest Service"; ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname); - ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError()); + ok(ret, "ChangeServiceConfig() failed le=%lu\n", GetLastError()); test_servicenotify(scm_handle, servicename); cleanup: @@ -2499,17 +2795,13 @@ cleanup: DeleteService(svc_handle); CloseServiceHandle(svc_handle); } - - /* Wait a while. The following test does a CreateService again */ - Sleep(1000); - CloseServiceHandle(scm_handle); } static void test_refcount(void) { SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5; - static const CHAR servicename [] = "Winetest"; + static const CHAR servicename [] = "winetest_refcount"; static const CHAR pathname [] = "we_dont_care.exe"; BOOL ret; @@ -2526,31 +2818,31 @@ static void test_refcount(void) svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError()); + ok(svc_handle1 != NULL, "Expected success, got error %lu\n", GetLastError()); /* Get a handle to this new service */ svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ); - ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError()); + ok(svc_handle2 != NULL, "Expected success, got error %lu\n", GetLastError()); /* Get another handle to this new service */ svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ); - ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError()); + ok(svc_handle3 != NULL, "Expected success, got error %lu\n", GetLastError()); /* Check if we can close the handle to the Service Control Manager */ ret = CloseServiceHandle(scm_handle); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); /* Get a new handle to the Service Control Manager */ scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); - ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); + ok(scm_handle != NULL, "Expected success, got error %lu\n", GetLastError()); /* Get a handle to this new service */ svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL); - ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError()); + ok(svc_handle4 != NULL, "Expected success, got error %lu\n", GetLastError()); /* Delete the service */ ret = DeleteService(svc_handle4); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); /* We cannot create the same service again as it's still marked as 'being deleted'. * The reason is that we still have 4 open handles to this service even though we @@ -2562,17 +2854,17 @@ static void test_refcount(void) SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); ok(!svc_handle5, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE, - "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError()); + "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %ld\n", GetLastError()); /* Close all the handles to the service and try again */ ret = CloseServiceHandle(svc_handle4); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); ret = CloseServiceHandle(svc_handle3); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); ret = CloseServiceHandle(svc_handle2); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); ret = CloseServiceHandle(svc_handle1); - ok(ret, "Expected success (err=%d)\n", GetLastError()); + ok(ret, "Expected success (err=%ld)\n", GetLastError()); /* Wait a while. Doing a CreateService too soon will result again * in an ERROR_SERVICE_MARKED_FOR_DELETE error. @@ -2583,19 +2875,108 @@ static void test_refcount(void) svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError()); + ok(svc_handle5 != NULL, "Expected success, got error %lu\n", GetLastError()); /* Delete the service */ ret = DeleteService(svc_handle5); - ok(ret, "Expected success (err=%d)\n", GetLastError()); - - /* Wait a while. Just in case one of the following tests does a CreateService again */ - Sleep(1000); - + ok(ret, "Expected success (err=%ld)\n", GetLastError()); CloseServiceHandle(svc_handle5); CloseServiceHandle(scm_handle); } +static BOOL is_lang_english(void) +{ + static HMODULE hkernel32 = NULL; + static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL; + static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL; + + if (!hkernel32) + { + hkernel32 = GetModuleHandleA("kernel32.dll"); + pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage"); + pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage"); + } + if (pGetThreadUILanguage) + return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH; + if (pGetUserDefaultUILanguage) + return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH; + + return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH; +} + +static void test_EventLog(void) +{ + SC_HANDLE scm_handle, svc_handle; + DWORD size; + BOOL ret; + QUERY_SERVICE_CONFIGA *config; + SERVICE_STATUS_PROCESS status; + + scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_READ); + ok(scm_handle != NULL, "OpenSCManager error %lu\n", GetLastError()); + + svc_handle = OpenServiceA(scm_handle, "EventLog", GENERIC_READ); + ok(svc_handle != NULL, "OpenService error %lu\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = QueryServiceConfigA(svc_handle, NULL, 0, &size); + ok(!ret, "QueryServiceConfig should fail\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError()); + + config = malloc(size); + ret = QueryServiceConfigA(svc_handle, config, size, &size); + ok(ret, "QueryServiceConfig error %lu\n", GetLastError()); + + ok(config->dwServiceType == SERVICE_WIN32_SHARE_PROCESS, "got %#lx\n", config->dwServiceType); + ok(config->dwStartType == SERVICE_AUTO_START, "got %lu\n", config->dwStartType); + ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "got %lu\n", config->dwErrorControl); + ok(!strcmpi(config->lpBinaryPathName, "C:\\windows\\system32\\services.exe") /* XP */ || + !strcmpi(config->lpBinaryPathName, "C:\\windows\\system32\\svchost.exe -k LocalServiceNetworkRestricted") /* Vista+ */ || + !strcmpi(config->lpBinaryPathName, "C:\\windows\\system32\\svchost.exe -k LocalServiceNetworkRestricted -p") /* Win10 */, + "got %s\n", config->lpBinaryPathName); + todo_wine + ok(!strcmpi(config->lpLoadOrderGroup, "Event Log"), "got %s\n", config->lpLoadOrderGroup); + ok(config->dwTagId == 0, "Expected 0, got %ld\n", config->dwTagId); + ok(!config->lpDependencies[0], "lpDependencies is not empty\n"); + ok(!strcmp(config->lpServiceStartName, "LocalSystem") /* XP */ || + !strcmp(config->lpServiceStartName, "NT AUTHORITY\\LocalService"), + "got %s\n", config->lpServiceStartName); + ok(!is_lang_english() || /* DisplayName is often translated */ + !strcmp(config->lpDisplayName, "Event Log") /* XP */ || + !strcmp(config->lpDisplayName, "Windows Event Log") /* Vista+ */, "got %s\n", config->lpDisplayName); + + free(config); + + memset(&status, 0, sizeof(status)); + size = sizeof(status); + ret = QueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE *)&status, size, &size); + ok(ret, "QueryServiceStatusEx error %lu\n", GetLastError()); + ok(status.dwServiceType == SERVICE_WIN32_SHARE_PROCESS || + status.dwServiceType == (SERVICE_WIN32_SHARE_PROCESS | SERVICE_WIN32_OWN_PROCESS) /* Win10 */, + "got %#lx\n", status.dwServiceType); + ok(status.dwServiceSpecificExitCode == 0, "got %#lx\n", status.dwServiceSpecificExitCode); + ok(status.dwCheckPoint == 0, "got %#lx\n", status.dwCheckPoint); + ok(status.dwWaitHint == 0, "got %#lx\n", status.dwWaitHint); + ok(status.dwServiceFlags == 0 || status.dwServiceFlags == SERVICE_RUNS_IN_SYSTEM_PROCESS /* XP */, + "got %#lx\n", status.dwServiceFlags); + if (status.dwCurrentState == SERVICE_STOPPED && + status.dwWin32ExitCode == ERROR_PROCESS_ABORTED) + win_skip("EventLog crashed!\n"); + else + { + ok(status.dwCurrentState == SERVICE_RUNNING, "got %#lx\n", status.dwCurrentState); + ok(status.dwControlsAccepted == SERVICE_ACCEPT_SHUTDOWN /* XP */ || + status.dwControlsAccepted == (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN) /* 2008 */ || + status.dwControlsAccepted == (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_TIMECHANGE | SERVICE_ACCEPT_SHUTDOWN), + "got %#lx\n", status.dwControlsAccepted); + ok(status.dwWin32ExitCode == 0, "got %#lx\n", status.dwWin32ExitCode); + ok(status.dwProcessId != 0, "got %#lx\n", status.dwProcessId); + } + + CloseServiceHandle(svc_handle); + CloseServiceHandle(scm_handle); +} + static DWORD WINAPI ctrl_handler(DWORD ctl, DWORD type, void *data, void *user) { HANDLE evt = user; @@ -2652,6 +3033,7 @@ START_TEST(service) SC_HANDLE scm_handle; int myARGC; char** myARGV; + int attempt; myARGC = winetest_get_mainargs(&myARGV); GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL); @@ -2682,8 +3064,17 @@ START_TEST(service) test_get_displayname(); test_get_servicekeyname(); test_query_svc(); - test_enum_svc(); + + /* Services may start or stop between enumeration calls, leading to + * inconsistencies and failures. So we may need a couple attempts. + */ + for (attempt = 2; attempt >= 0; attempt--) + if (test_enum_svc(attempt)) break; + for (attempt = 2; attempt >= 0; attempt--) + if (test_enum_svc_ex(attempt)) break; + test_close(); + test_wow64(); /* Test the creation, querying and deletion of a service */ test_sequence(); test_queryconfig2(); @@ -2692,4 +3083,5 @@ START_TEST(service) * and what the rules are */ test_refcount(); + test_EventLog(); }