https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3c1b7834e15b652076c21d...
commit 3c1b7834e15b652076c21d2d4ed8232d522b971a Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Sun Apr 1 13:19:24 2018 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Sun Apr 1 13:19:24 2018 +0100
[ADVAPI32_WINETEST] Sync with Wine Staging 3.3. CORE-14434 --- modules/rostests/winetests/advapi32/cred.c | 9 +- modules/rostests/winetests/advapi32/crypt.c | 10 +- modules/rostests/winetests/advapi32/crypt_lmhash.c | 9 +- modules/rostests/winetests/advapi32/crypt_md4.c | 10 +- modules/rostests/winetests/advapi32/crypt_md5.c | 7 +- modules/rostests/winetests/advapi32/crypt_sha.c | 8 +- modules/rostests/winetests/advapi32/eventlog.c | 18 +- modules/rostests/winetests/advapi32/lsa.c | 216 ++++++++++---------- modules/rostests/winetests/advapi32/precomp.h | 11 +- modules/rostests/winetests/advapi32/registry.c | 20 +- modules/rostests/winetests/advapi32/security.c | 138 ++++++++++++- modules/rostests/winetests/advapi32/service.c | 219 +++++++++++++++++---- 12 files changed, 496 insertions(+), 179 deletions(-)
diff --git a/modules/rostests/winetests/advapi32/cred.c b/modules/rostests/winetests/advapi32/cred.c index 38b23bc667..bb5fb4eace 100644 --- a/modules/rostests/winetests/advapi32/cred.c +++ b/modules/rostests/winetests/advapi32/cred.c @@ -18,9 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdarg.h> +#include <stdio.h>
-#include <wincred.h> +#include "windef.h" +#include "winbase.h" +#include "wincred.h" + +#include "wine/test.h"
static BOOL (WINAPI *pCredDeleteA)(LPCSTR,DWORD,DWORD); static BOOL (WINAPI *pCredEnumerateA)(LPCSTR,DWORD,DWORD *,PCREDENTIALA **); diff --git a/modules/rostests/winetests/advapi32/crypt.c b/modules/rostests/winetests/advapi32/crypt.c index 4e05a8a15f..13671eb0c2 100644 --- a/modules/rostests/winetests/advapi32/crypt.c +++ b/modules/rostests/winetests/advapi32/crypt.c @@ -18,9 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdarg.h>
-#include <wincrypt.h> +#include "windef.h" +#include "winbase.h" +#include "wincrypt.h" +#include "winerror.h" +#include "winreg.h" + +#include "wine/test.h"
static const char szRsaBaseProv[] = MS_DEF_PROV_A; static const char szNonExistentProv[] = "Wine Nonexistent Cryptographic Provider v11.2"; diff --git a/modules/rostests/winetests/advapi32/crypt_lmhash.c b/modules/rostests/winetests/advapi32/crypt_lmhash.c index 4a5ca15dde..a6e812e54a 100644 --- a/modules/rostests/winetests/advapi32/crypt_lmhash.c +++ b/modules/rostests/winetests/advapi32/crypt_lmhash.c @@ -19,7 +19,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdio.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winternl.h"
struct ustring { DWORD Length; diff --git a/modules/rostests/winetests/advapi32/crypt_md4.c b/modules/rostests/winetests/advapi32/crypt_md4.c index 2b9d2412d3..e67becb1f0 100644 --- a/modules/rostests/winetests/advapi32/crypt_md4.c +++ b/modules/rostests/winetests/advapi32/crypt_md4.c @@ -18,7 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdio.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winternl.h"
typedef struct { diff --git a/modules/rostests/winetests/advapi32/crypt_md5.c b/modules/rostests/winetests/advapi32/crypt_md5.c index cae4fc5229..4cf88688ea 100644 --- a/modules/rostests/winetests/advapi32/crypt_md5.c +++ b/modules/rostests/winetests/advapi32/crypt_md5.c @@ -18,7 +18,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdio.h> + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h"
typedef struct { diff --git a/modules/rostests/winetests/advapi32/crypt_sha.c b/modules/rostests/winetests/advapi32/crypt_sha.c index f0350204b6..2737ee7c0c 100644 --- a/modules/rostests/winetests/advapi32/crypt_sha.c +++ b/modules/rostests/winetests/advapi32/crypt_sha.c @@ -18,7 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" + +#include "wine/test.h"
typedef struct { ULONG Unknown[6]; diff --git a/modules/rostests/winetests/advapi32/eventlog.c b/modules/rostests/winetests/advapi32/eventlog.c index 0b8484f17c..e6b2de5edb 100644 --- a/modules/rostests/winetests/advapi32/eventlog.c +++ b/modules/rostests/winetests/advapi32/eventlog.c @@ -18,11 +18,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdarg.h>
-#include <wmistr.h> -#include <initguid.h> -#include <evntrace.h> +#include "initguid.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winnt.h" +#include "winreg.h" +#include "sddl.h" +#include "wmistr.h" +#include "evntrace.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); @@ -1149,7 +1157,7 @@ static void test_start_trace(void) LONG ret;
buffersize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(sessionname) + sizeof(filepath); - properties = (EVENT_TRACE_PROPERTIES *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize); + properties = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize); properties->Wnode.BufferSize = buffersize; properties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; properties->LogFileMode = EVENT_TRACE_FILE_MODE_NONE; diff --git a/modules/rostests/winetests/advapi32/lsa.c b/modules/rostests/winetests/advapi32/lsa.c index 0ce93c678d..dcdcdc8b1e 100644 --- a/modules/rostests/winetests/advapi32/lsa.c +++ b/modules/rostests/winetests/advapi32/lsa.c @@ -18,47 +18,30 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" - -#include <winnls.h> -#include <objbase.h> -#include <initguid.h> +#include <stdarg.h> +#include <stdio.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#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 <ntsecapi.h> +#endif +#include "ntlsa.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
-static HMODULE hadvapi32; -static NTSTATUS (WINAPI *pLsaClose)(LSA_HANDLE); -static NTSTATUS (WINAPI *pLsaEnumerateAccountRights)(LSA_HANDLE,PSID,PLSA_UNICODE_STRING*,PULONG); -static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID); -static NTSTATUS (WINAPI *pLsaOpenPolicy)(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE); -static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*); -static BOOL (WINAPI *pConvertSidToStringSidA)(PSID,LPSTR*); -static BOOL (WINAPI *pConvertStringSidToSidA)(LPCSTR,PSID*); -static NTSTATUS (WINAPI *pLsaLookupNames2)(LSA_HANDLE,ULONG,ULONG,PLSA_UNICODE_STRING,PLSA_REFERENCED_DOMAIN_LIST*,PLSA_TRANSLATED_SID2*); -static NTSTATUS (WINAPI *pLsaLookupSids)(LSA_HANDLE,ULONG,PSID*,LSA_REFERENCED_DOMAIN_LIST**,LSA_TRANSLATED_NAME**); -static PVOID (WINAPI *pFreeSid)(PSID); - -static BOOL init(void) -{ - hadvapi32 = GetModuleHandleA("advapi32.dll"); - - pLsaClose = (void*)GetProcAddress(hadvapi32, "LsaClose"); - pLsaEnumerateAccountRights = (void*)GetProcAddress(hadvapi32, "LsaEnumerateAccountRights"); - pLsaFreeMemory = (void*)GetProcAddress(hadvapi32, "LsaFreeMemory"); - pLsaOpenPolicy = (void*)GetProcAddress(hadvapi32, "LsaOpenPolicy"); - pLsaQueryInformationPolicy = (void*)GetProcAddress(hadvapi32, "LsaQueryInformationPolicy"); - pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA"); - pConvertStringSidToSidA = (void*)GetProcAddress(hadvapi32, "ConvertStringSidToSidA"); - pLsaLookupNames2 = (void*)GetProcAddress(hadvapi32, "LsaLookupNames2"); - pLsaLookupSids = (void*)GetProcAddress(hadvapi32, "LsaLookupSids"); - pFreeSid = (void*)GetProcAddress(hadvapi32, "FreeSid"); - - if (pLsaClose && pLsaEnumerateAccountRights && pLsaFreeMemory && pLsaOpenPolicy && pLsaQueryInformationPolicy && pConvertSidToStringSidA && pConvertStringSidToSidA && pFreeSid) - return TRUE; - - return FALSE; -} - static void test_lsa(void) { static WCHAR machineW[] = {'W','i','n','e','N','o','M','a','c','h','i','n','e',0}; @@ -74,18 +57,18 @@ static void test_lsa(void) machine.Length = sizeof(machineW) - 2; machine.MaximumLength = sizeof(machineW);
- status = pLsaOpenPolicy( &machine, &object_attributes, POLICY_LOOKUP_NAMES, &handle); + 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 = pLsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle); + 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);
/* 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 = pLsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES, &handle); + 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); }
@@ -97,21 +80,20 @@ static void test_lsa(void) HANDLE token; BOOL ret;
- status = pLsaQueryInformationPolicy(handle, PolicyAuditEventsInformation, (PVOID*)&audit_events_info); + status = LsaQueryInformationPolicy(handle, PolicyAuditEventsInformation, (void **)&audit_events_info); 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); - if (status == STATUS_SUCCESS) { - pLsaFreeMemory((LPVOID)audit_events_info); - } + if (status == STATUS_SUCCESS) + LsaFreeMemory(audit_events_info);
- status = pLsaQueryInformationPolicy(handle, PolicyPrimaryDomainInformation, (PVOID*)&primary_domain_info); + status = LsaQueryInformationPolicy(handle, PolicyPrimaryDomainInformation, (void **)&primary_domain_info); ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyPrimaryDomainInformation) failed, returned 0x%08x\n", status); if (status == STATUS_SUCCESS) { if (primary_domain_info->Sid) { LPSTR strsid; - if (pConvertSidToStringSidA(primary_domain_info->Sid, &strsid)) + if (ConvertSidToStringSidA(primary_domain_info->Sid, &strsid)) { if (primary_domain_info->Name.Buffer) { LPSTR name = NULL; @@ -130,17 +112,16 @@ static void test_lsa(void) } else trace("Running on a standalone system.\n"); - pLsaFreeMemory((LPVOID)primary_domain_info); + LsaFreeMemory(primary_domain_info); }
- status = pLsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&account_domain_info); + status = LsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (void **)&account_domain_info); ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) failed, returned 0x%08x\n", status); - if (status == STATUS_SUCCESS) { - pLsaFreeMemory((LPVOID)account_domain_info); - } + if (status == STATUS_SUCCESS) + LsaFreeMemory(account_domain_info);
/* This isn't supported in NT4 */ - status = pLsaQueryInformationPolicy(handle, PolicyDnsDomainInformation, (PVOID*)&dns_domain_info); + status = LsaQueryInformationPolicy(handle, PolicyDnsDomainInformation, (void **)&dns_domain_info); ok(status == STATUS_SUCCESS || status == STATUS_INVALID_PARAMETER, "LsaQueryInformationPolicy(PolicyDnsDomainInformation) failed, returned 0x%08x\n", status); if (status == STATUS_SUCCESS) { @@ -153,7 +134,7 @@ static void test_lsa(void) WCHAR guidstrW[64]; UINT len; guidstrW[0] = '\0'; - pConvertSidToStringSidA(dns_domain_info->Sid, &strsid); + 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 ); @@ -184,7 +165,7 @@ static void test_lsa(void) } else trace("Running on a standalone system.\n"); - pLsaFreeMemory((LPVOID)dns_domain_info); + LsaFreeMemory(dns_domain_info); }
/* We need a valid SID to pass to LsaEnumerateAccountRights */ @@ -208,10 +189,10 @@ static void test_lsa(void) ULONG rights_count; rights = (PLSA_UNICODE_STRING) 0xdeadbeaf; rights_count = 0xcafecafe; - status = pLsaEnumerateAccountRights(handle, token_user->User.Sid, &rights, &rights_count); + 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); if (status == STATUS_SUCCESS) - pLsaFreeMemory( rights ); + LsaFreeMemory( rights ); else ok(rights == NULL && rights_count == 0, "Expected rights and rights_count to be set to 0 on failure\n"); } @@ -220,7 +201,7 @@ static void test_lsa(void) CloseHandle( token ); }
- status = pLsaClose(handle); + status = LsaClose(handle); ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); } } @@ -254,12 +235,6 @@ static void test_LsaLookupNames2(void) LSA_UNICODE_STRING name[3]; LPSTR account, sid_dom;
- if (!pLsaLookupNames2) - { - win_skip("LsaLookupNames2 not available\n"); - return; - } - if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) || (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)) { @@ -270,7 +245,7 @@ static void test_LsaLookupNames2(void) memset(&attrs, 0, sizeof(attrs)); attrs.Length = sizeof(attrs);
- status = pLsaOpenPolicy(NULL, &attrs, POLICY_ALL_ACCESS, &handle); + 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);
@@ -278,7 +253,7 @@ static void test_LsaLookupNames2(void) if (status == STATUS_ACCESS_DENIED) { trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n"); - status = pLsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &handle); + status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &handle); ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status); } if (status != STATUS_SUCCESS) @@ -302,7 +277,7 @@ static void test_LsaLookupNames2(void) /* account name only */ sids = NULL; domains = NULL; - status = pLsaLookupNames2(handle, 0, 1, &name[0], &domains, &sids); + status = LsaLookupNames2(handle, 0, 1, &name[0], &domains, &sids); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\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); @@ -310,24 +285,24 @@ static void test_LsaLookupNames2(void) 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); - pLsaFreeMemory(sids); - pLsaFreeMemory(domains); + LsaFreeMemory(sids); + LsaFreeMemory(domains);
/* unknown account name */ sids = NULL; domains = NULL; - status = pLsaLookupNames2(handle, 0, 1, &name[1], &domains, &sids); + status = LsaLookupNames2(handle, 0, 1, &name[1], &domains, &sids); ok(status == STATUS_NONE_MAPPED, "expected STATUS_NONE_MAPPED, got %x)\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); - pLsaFreeMemory(sids); - pLsaFreeMemory(domains); + LsaFreeMemory(sids); + LsaFreeMemory(domains);
/* account + domain */ sids = NULL; domains = NULL; - status = pLsaLookupNames2(handle, 0, 1, &name[2], &domains, &sids); + status = LsaLookupNames2(handle, 0, 1, &name[2], &domains, &sids); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\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); @@ -335,27 +310,27 @@ static void test_LsaLookupNames2(void) 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); - pLsaFreeMemory(sids); - pLsaFreeMemory(domains); + LsaFreeMemory(sids); + LsaFreeMemory(domains);
/* all three */ sids = NULL; domains = NULL; - status = pLsaLookupNames2(handle, 0, 3, name, &domains, &sids); + status = LsaLookupNames2(handle, 0, 3, name, &domains, &sids); ok(status == STATUS_SOME_NOT_MAPPED, "expected STATUS_SOME_NOT_MAPPED, got %x)\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); - pLsaFreeMemory(sids); - pLsaFreeMemory(domains); + LsaFreeMemory(sids); + LsaFreeMemory(domains);
HeapFree(GetProcessHeap(), 0, name[0].Buffer); HeapFree(GetProcessHeap(), 0, name[1].Buffer); HeapFree(GetProcessHeap(), 0, name[2].Buffer);
- status = pLsaClose(handle); + status = LsaClose(handle); ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); }
@@ -370,11 +345,12 @@ static void test_LsaLookupSids(void) HANDLE token; DWORD size; BOOL ret; + PSID sid;
memset(&attrs, 0, sizeof(attrs)); attrs.Length = sizeof(attrs);
- status = pLsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); + status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); @@ -387,7 +363,7 @@ static void test_LsaLookupSids(void) ret = GetTokenInformation(token, TokenUser, user, size, &size); ok(ret, "got %d\n", ret);
- status = pLsaLookupSids(policy, 1, &user->User.Sid, &list, &names); + status = LsaLookupSids(policy, 1, &user->User.Sid, &list, &names); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
ok(list->Entries > 0, "got %d\n", list->Entries); @@ -399,37 +375,17 @@ static void test_LsaLookupSids(void) list->Domains[0].Name.Length); }
- pLsaFreeMemory(names); - pLsaFreeMemory(list); + LsaFreeMemory(names); + LsaFreeMemory(list);
HeapFree(GetProcessHeap(), 0, user);
CloseHandle(token);
- status = pLsaClose(policy); - ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); -} + ret = ConvertStringSidToSidA("S-1-1-0", &sid); + ok(ret == TRUE, "ConvertStringSidToSidA returned false\n");
-static void test_LsaLookupSids_NullBuffers(void) -{ - LSA_REFERENCED_DOMAIN_LIST *list; - LSA_OBJECT_ATTRIBUTES attrs; - LSA_TRANSLATED_NAME *names; - LSA_HANDLE policy; - NTSTATUS status; - BOOL ret; - PSID sid; - - memset(&attrs, 0, sizeof(attrs)); - attrs.Length = sizeof(attrs); - - status = pLsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); - ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); - - ret = pConvertStringSidToSidA("S-1-1-0", &sid); - ok(ret == TRUE, "pConvertStringSidToSidA returned false\n"); - - status = pLsaLookupSids(policy, 1, &sid, &list, &names); + status = LsaLookupSids(policy, 1, &sid, &list, &names); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
ok(list->Entries > 0, "got %d\n", list->Entries); @@ -443,24 +399,52 @@ static void test_LsaLookupSids_NullBuffers(void) ok(list->Domains[0].Name.Buffer != NULL, "domain[0] name buffer is null\n"); }
- pLsaFreeMemory(names); - pLsaFreeMemory(list); + LsaFreeMemory(names); + LsaFreeMemory(list);
- pFreeSid(sid); + FreeSid(sid);
- status = pLsaClose(policy); + status = LsaClose(policy); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); }
-START_TEST(lsa) +static void test_LsaLookupPrivilegeName(void) { - if (!init()) { - win_skip("Needed functions are not available\n"); - return; - } + LSA_OBJECT_ATTRIBUTES attrs; + LSA_UNICODE_STRING *name; + LSA_HANDLE policy; + NTSTATUS status; + LUID luid; + + memset(&attrs, 0, sizeof(attrs)); + attrs.Length = sizeof(attrs); + + status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); + ok(status == STATUS_SUCCESS, "Failed to open policy, %#x.\n", status); + + name = (void *)0xdeadbeef; + status = LsaLookupPrivilegeName(policy, NULL, &name); + ok(status != STATUS_SUCCESS, "Unexpected status %#x.\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(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); + LsaFreeMemory(name); +}
+START_TEST(lsa) +{ test_lsa(); test_LsaLookupNames2(); test_LsaLookupSids(); - test_LsaLookupSids_NullBuffers(); + test_LsaLookupPrivilegeName(); } diff --git a/modules/rostests/winetests/advapi32/precomp.h b/modules/rostests/winetests/advapi32/precomp.h index 21bf46d9f3..18f6d38e97 100644 --- a/modules/rostests/winetests/advapi32/precomp.h +++ b/modules/rostests/winetests/advapi32/precomp.h @@ -1,12 +1,16 @@ + #ifndef _ADVAPI32_WINETEST_PRECOMP_H_ #define _ADVAPI32_WINETEST_PRECOMP_H_
#include <stdio.h> -#include <ntstatus.h> -#define WIN32_NO_STATUS + #define WIN32_LEAN_AND_MEAN #define _INC_WINDOWS #define COM_NO_WINDOWS_H + +#include <ntstatus.h> +#define WIN32_NO_STATUS + #include <wine/test.h> #include <winreg.h> #include <wine/winternl.h> @@ -15,5 +19,4 @@ #include <lmcons.h> #include <aclapi.h>
- -#endif /* !_ADVAPI32_WINETEST_PRECOMP_H_ */ \ No newline at end of file +#endif /* !_ADVAPI32_WINETEST_PRECOMP_H_ */ diff --git a/modules/rostests/winetests/advapi32/registry.c b/modules/rostests/winetests/advapi32/registry.c index 4b99099b65..716edac42e 100644 --- a/modules/rostests/winetests/advapi32/registry.c +++ b/modules/rostests/winetests/advapi32/registry.c @@ -19,10 +19,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" - #include <assert.h> -#include <winperf.h> +#include <stdarg.h> +#include <stdio.h> +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winreg.h" +#include "winperf.h" +#include "winsvc.h" +#include "winerror.h" +#include "aclapi.h"
#define IS_HKCR(hk) ((UINT_PTR)hk > 0 && ((UINT_PTR)hk & 3) == 2)
@@ -2506,6 +2514,12 @@ static void test_redirection(void) } }
+ if (limited_user) + { + skip("not enough privileges to modify HKLM\n"); + return; + } + 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 ); diff --git a/modules/rostests/winetests/advapi32/security.c b/modules/rostests/winetests/advapi32/security.c index c64b1d99e9..fdd657d6a0 100644 --- a/modules/rostests/winetests/advapi32/security.c +++ b/modules/rostests/winetests/advapi32/security.c @@ -19,7 +19,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdarg.h> +#include <stdio.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winternl.h" +#include "aclapi.h" +#include "winnt.h" +#include "sddl.h" +#include "ntsecapi.h" +#include "lmcons.h" + +#include "wine/test.h"
/* FIXME: Inspect */ #define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3) @@ -1872,6 +1887,36 @@ static void test_token_attr(void) LocalFree(SidString); HeapFree(GetProcessHeap(), 0, User);
+ /* logon */ + ret = GetTokenInformation(Token, TokenLogonSid, NULL, 0, &Size); + if (!ret && (GetLastError() == ERROR_INVALID_PARAMETER)) + todo_wine win_skip("TokenLogonSid not supported. Skipping tests\n"); + else + { + ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), + "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError()); + Groups = HeapAlloc(GetProcessHeap(), 0, Size); + ret = GetTokenInformation(Token, TokenLogonSid, Groups, Size, &Size); + ok(ret, + "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError()); + if (ret) + { + ok(Groups->GroupCount == 1, "got %d\n", Groups->GroupCount); + if(Groups->GroupCount == 1) + { + ConvertSidToStringSidA(Groups->Groups[0].Sid, &SidString); + trace("TokenLogon: %s\n", SidString); + LocalFree(SidString); + + /* S-1-5-5-0-XXXXXX */ + ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid); + ok(ret, "Unknown SID\n"); + } + } + + HeapFree(GetProcessHeap(), 0, Groups); + } + /* privileges */ ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size); ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), @@ -2541,7 +2586,7 @@ static void test_LookupAccountName(void) "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); ok(sid_size != 0, "Expected non-zero sid size\n"); ok(domain_size != 0, "Expected non-zero domain size\n"); - ok(sid_use == 0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); + ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
sid_save = sid_size; domain_save = domain_size; @@ -2628,7 +2673,7 @@ static void test_LookupAccountName(void) "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); ok(sid_size != 0, "Expected non-zero sid size\n"); ok(domain_size != 0, "Expected non-zero domain size\n"); - ok(sid_use == 0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); + 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); @@ -2736,12 +2781,12 @@ static void test_LookupAccountName(void)
static void test_security_descriptor(void) { - SECURITY_DESCRIPTOR sd; + SECURITY_DESCRIPTOR sd, *sd_rel, *sd_rel2, *sd_abs; char buf[8192]; - DWORD size; + DWORD size, size_dacl, size_sacl, size_owner, size_group; BOOL isDefault, isPresent, ret; - PACL pacl; - PSID psid; + PACL pacl, dacl, sacl; + PSID psid, owner, group;
SetLastError(0xdeadbeef); ret = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); @@ -2779,6 +2824,46 @@ static void test_security_descriptor(void) expect_eq(psid, NULL, PSID, "%p"); expect_eq(isDefault, FALSE, BOOL, "%d"); } + + ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( + "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()); + + size = 0; + ret = MakeSelfRelativeSD(sd_rel, NULL, &size); + todo_wine ok(!ret && GetLastError() == ERROR_BAD_DESCRIPTOR_FORMAT, "got %u\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()); + + sd_abs = HeapAlloc(GetProcessHeap(), 0, 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()); + + 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); + + size += 4; + sd_rel2 = HeapAlloc(GetProcessHeap(), 0, size); + ret = MakeSelfRelativeSD(sd_abs, sd_rel2, &size); + ok(ret, "got %u\n", GetLastError()); + ok(size == 188, "got %u\n", size); + + HeapFree(GetProcessHeap(), 0, sd_abs); + HeapFree(GetProcessHeap(), 0, sd_rel2); + LocalFree(sd_rel); }
#define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,0,__LINE__) @@ -3582,7 +3667,7 @@ static void test_CreateDirectoryA(void) sa.bInheritHandle = TRUE; InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); - pDacl = HeapAlloc(GetProcessHeap(), 0, 100); + pDacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 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, @@ -3732,7 +3817,6 @@ static void test_CreateDirectoryA(void) 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); @@ -3743,6 +3827,7 @@ static void test_CreateDirectoryA(void) 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); @@ -4298,6 +4383,8 @@ static void test_ConvertStringSecurityDescriptor(void) PSECURITY_DESCRIPTOR pSD; static const WCHAR Blank[] = { 0 }; unsigned int i; + ULONG size; + ACL *acl; static const struct { const char *sidstring; @@ -4408,6 +4495,33 @@ static void test_ConvertStringSecurityDescriptor(void) ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %u\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); + 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); + ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize); + ok(!acl->AceCount, "got %u\n", acl->AceCount); + ok(!acl->Sbz2, "got %u\n", acl->Sbz2); + LocalFree(pSD); + + /* 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); + 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); + ok(!acl->AceCount, "got %u\n", acl->AceCount); + ok(!acl->Sbz2, "got %u\n", acl->Sbz2); + LocalFree(pSD); }
static void test_ConvertSecurityDescriptorToString(void) @@ -6594,6 +6708,7 @@ static void test_AddMandatoryAce(void) HeapFree(GetProcessHeap(), 0, sd2); CloseHandle(handle);
+ memset(buffer_acl, 0, sizeof(buffer_acl)); ret = InitializeAcl(acl, 256, ACL_REVISION); ok(ret, "InitializeAcl failed with %u\n", GetLastError());
@@ -6858,6 +6973,8 @@ static void test_system_security_access(void) /* 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 ); + if (err == ERROR_SUCCESS) + LocalFree( sd );
priv.PrivilegeCount = 1; priv.Privileges[0].Luid = luid; @@ -7080,6 +7197,7 @@ static void test_maximum_allowed(void)
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError()); + memset(buffer_acl, 0, sizeof(buffer_acl)); ret = InitializeAcl(acl, 256, ACL_REVISION); ok(ret, "InitializeAcl failed with %u\n", GetLastError()); ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE); @@ -7215,6 +7333,7 @@ static void test_token_security_descriptor(void) ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
+ memset(buffer_acl, 0, sizeof(buffer_acl)); ret = InitializeAcl(acl, 256, ACL_REVISION); ok(ret, "InitializeAcl failed with error %u\n", GetLastError());
@@ -7638,6 +7757,7 @@ static void test_token_security_descriptor(void) CloseHandle(info.hThread);
LocalFree(acl_child); + HeapFree(GetProcessHeap(), 0, sd2); LocalFree(psid);
CloseHandle(token3); diff --git a/modules/rostests/winetests/advapi32/service.c b/modules/rostests/winetests/advapi32/service.c index 7d62a08359..8c13fbb2c6 100644 --- a/modules/rostests/winetests/advapi32/service.c +++ b/modules/rostests/winetests/advapi32/service.c @@ -18,12 +18,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "precomp.h" +#include <stdarg.h> +#include <stdio.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" +#include "winsvc.h" +#include "winnls.h" +#include "lmcons.h" +#include "aclapi.h" + +#include "wine/test.h"
static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */ static CHAR selfname[MAX_PATH];
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, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD, LPDWORD, LPCSTR); @@ -45,6 +58,7 @@ static void init_function_pointers(void) HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A"); + pChangeServiceConfig2W = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2W"); pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA"); pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW"); pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo"); @@ -1942,6 +1956,7 @@ static void test_queryconfig2(void) DWORD expected, needed; BYTE buffer[MAX_PATH]; LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer; + LPSERVICE_DESCRIPTIONW pConfigW = (LPSERVICE_DESCRIPTIONW)buffer; SERVICE_PRESHUTDOWN_INFO preshutdown_info; static const CHAR servicename [] = "Winetest"; static const CHAR displayname [] = "Winetest dummy service"; @@ -1949,6 +1964,9 @@ static void test_queryconfig2(void) static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0"; static const CHAR password [] = ""; static const CHAR description [] = "Description"; + static const CHAR description_empty[] = ""; + static const WCHAR descriptionW [] = {'D','e','s','c','r','i','p','t','i','o','n','W',0}; + static const WCHAR descriptionW_empty[] = {0};
if(!pQueryServiceConfig2A) { @@ -2109,6 +2127,66 @@ static void test_queryconfig2(void) ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed); ok(ret, "expected QueryServiceConfig2W to succeed\n");
+ pConfig->lpDescription = (LPSTR)description; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2A to succeed\n"); + + pConfig->lpDescription = NULL; + ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfig->lpDescription && !strcmp(description, pConfig->lpDescription), + "expected lpDescription to be %s, got %s\n", description, pConfig->lpDescription); + + pConfig->lpDescription = NULL; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2A to succeed\n"); + + pConfig->lpDescription = NULL; + ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfig->lpDescription && !strcmp(description, pConfig->lpDescription), + "expected lpDescription to be %s, got %s\n", description, pConfig->lpDescription); + + pConfig->lpDescription = (LPSTR)description_empty; + ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2A to succeed\n"); + + pConfig->lpDescription = (void*)0xdeadbeef; + ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(!pConfig->lpDescription, + "expected lpDescription to be null, got %s\n", pConfig->lpDescription); + + pConfigW->lpDescription = (LPWSTR)descriptionW; + ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2W to succeed\n"); + + pConfigW->lpDescription = NULL; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfigW->lpDescription && !lstrcmpW(descriptionW, pConfigW->lpDescription), + "expected lpDescription to be %s, got %s\n", wine_dbgstr_w(descriptionW), wine_dbgstr_w(pConfigW->lpDescription)); + + pConfigW->lpDescription = NULL; + ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2W to succeed\n"); + + pConfigW->lpDescription = NULL; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(pConfigW->lpDescription && !lstrcmpW(descriptionW, pConfigW->lpDescription), + "expected lpDescription to be %s, got %s\n", wine_dbgstr_w(descriptionW), wine_dbgstr_w(pConfigW->lpDescription)); + + pConfigW->lpDescription = (LPWSTR)descriptionW_empty; + ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); + ok(ret, "expected ChangeServiceConfig2W to succeed\n"); + + pConfigW->lpDescription = (void*)0xdeadbeef; + ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); + ok(ret, "expected QueryServiceConfig2A to succeed\n"); + ok(!pConfigW->lpDescription, + "expected lpDescription to be null, got %s\n", wine_dbgstr_w(pConfigW->lpDescription)); + SetLastError(0xdeadbeef); ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed); @@ -2188,73 +2266,146 @@ static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, DWORD is_nt4 return le1; }
+#define PHASE_STOPPED 1 +#define PHASE_RUNNING 2 + struct notify_data { SERVICE_NOTIFYW notify; SC_HANDLE svc; + BOOL was_called; + DWORD phase; };
-static void CALLBACK cb_stopped(void *user) +static void CALLBACK notify_cb(void *user) { struct notify_data *data = user; - BOOL br; + switch (data->phase) + { + case PHASE_STOPPED: + ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, + "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); + ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_STOPPED, + "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); + ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_STOPPED, + "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); + break;
- ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, - "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); - ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_STOPPED, - "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); - ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_STOPPED, - "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); + case PHASE_RUNNING: + ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, + "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); + ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_RUNNING, + "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); + ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_RUNNING, + "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); + break; + }
- br = StartServiceA(data->svc, 0, NULL); - ok(br, "StartService failed: %u\n", GetLastError()); + data->was_called = TRUE; }
-static void CALLBACK cb_running(void *user) +static void test_servicenotify(SC_HANDLE scm_handle, const char *servicename) { - struct notify_data *data = user; + DWORD dr, dr2; + struct notify_data data; + struct notify_data data2; BOOL br; SERVICE_STATUS status; - - ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, - "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); - ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_RUNNING, - "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); - ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_RUNNING, - "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); - - br = ControlService(data->svc, SERVICE_CONTROL_STOP, &status); - ok(br, "ControlService failed: %u\n", GetLastError()); -} - -static void test_servicenotify(SC_HANDLE svc) -{ - DWORD dr; - struct notify_data data; + HANDLE svc, svc2;
if(!pNotifyServiceStatusChangeW){ win_skip("No NotifyServiceStatusChangeW\n"); return; }
+ svc = OpenServiceA(scm_handle, servicename, GENERIC_ALL); + svc2 = OpenServiceA(scm_handle, servicename, GENERIC_ALL); + ok(svc != NULL && svc2 != NULL, "Failed to open service\n"); + if(!svc || !svc2) + return; + + /* receive stopped notification, then start service */ memset(&data.notify, 0, sizeof(data.notify)); data.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; - data.notify.pfnNotifyCallback = &cb_stopped; + data.notify.pfnNotifyCallback = ¬ify_cb; data.notify.pContext = &data; data.svc = svc; + 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);
dr = SleepEx(100, TRUE); - ok(dr == WAIT_IO_COMPLETION, "APC wasn't called\n"); + ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); + ok(data.was_called == TRUE, "APC wasn't called\n"); + + br = StartServiceA(svc, 0, NULL); + ok(br, "StartService failed: %u\n", GetLastError());
- data.notify.pfnNotifyCallback = &cb_running; + /* 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);
dr = SleepEx(100, TRUE); - ok(dr == WAIT_IO_COMPLETION, "APC wasn't called\n"); + ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); + ok(data.was_called == TRUE, "APC wasn't called\n"); + + /* cannot register two notifications */ + 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); + + memset(&data2.notify, 0, sizeof(data2.notify)); + data2.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; + data2.notify.pfnNotifyCallback = ¬ify_cb; + data2.notify.pContext = &data2; + + 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(data.was_called == FALSE, "APC should not have been called\n"); + + /* stop service and receive notifiction */ + br = ControlService(svc, SERVICE_CONTROL_STOP, &status); + ok(br, "ControlService failed: %u\n", GetLastError()); + + dr = SleepEx(100, TRUE); + ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); + ok(data.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 + * not happen */ + + 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); + + CloseServiceHandle(svc); + + br = StartServiceA(svc2, 0, NULL); + ok(br, "StartService failed: %u\n", GetLastError()); + + dr = SleepEx(100, TRUE); + ok(dr == 0, "Got wrong SleepEx result: %u\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()); + + CloseServiceHandle(svc2); }
static void test_start_stop(void) @@ -2340,7 +2491,7 @@ static void test_start_stop(void) 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()); - test_servicenotify(svc_handle); + test_servicenotify(scm_handle, servicename);
cleanup: if (svc_handle)