From: Micah N Gorrell mgorrell@codeweavers.com
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/advapi32/advapi32_misc.h | 3 -- dlls/advapi32/security.c | 70 ++++++++++++++++------------------- dlls/advapi32/service.c | 6 +-- 3 files changed, 35 insertions(+), 44 deletions(-)
diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h index 4ced1e8a648..77b56420ba3 100644 --- a/dlls/advapi32/advapi32_misc.h +++ b/dlls/advapi32/advapi32_misc.h @@ -32,9 +32,6 @@ BOOL ADVAPI_GetComputerSid(PSID sid) DECLSPEC_HIDDEN; BOOL lookup_local_wellknown_name(const LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*) DECLSPEC_HIDDEN; BOOL lookup_local_user_name(const LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*) DECLSPEC_HIDDEN; WCHAR *SERV_dup(const char *str) DECLSPEC_HIDDEN; -DWORD SERV_OpenSCManagerW(LPCWSTR, LPCWSTR, DWORD, SC_HANDLE*) DECLSPEC_HIDDEN; -DWORD SERV_OpenServiceW(SC_HANDLE, LPCWSTR, DWORD, SC_HANDLE*) DECLSPEC_HIDDEN; -NTSTATUS SERV_QueryServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD) DECLSPEC_HIDDEN; const WCHAR *get_wellknown_privilege_name(const LUID *) DECLSPEC_HIDDEN;
/* memory allocation functions */ diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 4bea26d1557..7315f9b51a9 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -415,16 +415,15 @@ static inline DWORD get_security_file( LPCWSTR full_file_name, DWORD access, HAN /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */ static inline DWORD get_security_service( LPWSTR full_service_name, DWORD access, HANDLE *service ) { - SC_HANDLE manager = 0; - DWORD err; - - err = SERV_OpenSCManagerW( NULL, NULL, access, (SC_HANDLE *)&manager ); - if (err == ERROR_SUCCESS) + SC_HANDLE manager = OpenSCManagerW( NULL, NULL, access ); + if (manager) { - err = SERV_OpenServiceW( manager, full_service_name, access, (SC_HANDLE *)service ); + *service = OpenServiceW( manager, full_service_name, access); CloseServiceHandle( manager ); + if (*service) + return ERROR_SUCCESS; } - return err; + return GetLastError(); }
/* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */ @@ -1779,16 +1778,13 @@ BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceNa * RETURNS * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise. */ -DWORD WINAPI GetSecurityInfo( - HANDLE hObject, SE_OBJECT_TYPE ObjectType, - SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner, - PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl, - PSECURITY_DESCRIPTOR *ppSecurityDescriptor -) +DWORD WINAPI GetSecurityInfo( HANDLE handle, SE_OBJECT_TYPE type, SECURITY_INFORMATION SecurityInfo, + PSID *ppsidOwner, PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl, + PSECURITY_DESCRIPTOR *ppSecurityDescriptor ) { PSECURITY_DESCRIPTOR sd; NTSTATUS status; - ULONG n1, n2; + ULONG size; BOOL present, defaulted;
/* A NULL descriptor is allowed if any one of the other pointers is not NULL */ @@ -1802,35 +1798,33 @@ DWORD WINAPI GetSecurityInfo( || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) )) return ERROR_INVALID_PARAMETER;
- switch (ObjectType) + if (type == SE_SERVICE) { - case SE_SERVICE: - status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1); - break; - default: - status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1); - break; - } - if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS) - return RtlNtStatusToDosError(status); + if (!QueryServiceObjectSecurity( handle, SecurityInfo, NULL, 0, &size ) + && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return GetLastError();
- sd = LocalAlloc(0, n1); - if (!sd) - return ERROR_NOT_ENOUGH_MEMORY; + if (!(sd = LocalAlloc( 0, size ))) return ERROR_NOT_ENOUGH_MEMORY;
- switch (ObjectType) - { - case SE_SERVICE: - status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2); - break; - default: - status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2); - break; + if (!QueryServiceObjectSecurity( handle, SecurityInfo, sd, size, &size )) + { + LocalFree(sd); + return GetLastError(); + } } - if (status != STATUS_SUCCESS) + else { - LocalFree(sd); - return RtlNtStatusToDosError(status); + status = NtQuerySecurityObject( handle, SecurityInfo, NULL, 0, &size ); + if (status != STATUS_SUCCESS && status != STATUS_BUFFER_TOO_SMALL) + return RtlNtStatusToDosError( status ); + + if (!(sd = LocalAlloc( 0, size ))) return ERROR_NOT_ENOUGH_MEMORY; + + if ((status = NtQuerySecurityObject( handle, SecurityInfo, sd, size, &size ))) + { + LocalFree(sd); + return RtlNtStatusToDosError( status ); + } }
if (ppsidOwner) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 231f0267e98..2781a128239 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -897,7 +897,7 @@ SC_HANDLE WINAPI OpenSCManagerA( LPCSTR lpMachineName, LPCSTR lpDatabaseName, * * See OpenSCManagerA. */ -DWORD SERV_OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, +static DWORD SERV_OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess, SC_HANDLE *handle ) { DWORD r; @@ -1049,7 +1049,7 @@ SC_HANDLE WINAPI OpenServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName, * * See OpenServiceA. */ -DWORD SERV_OpenServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, +static DWORD SERV_OpenServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess, SC_HANDLE *handle ) { DWORD err; @@ -2484,7 +2484,7 @@ BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel, return err == ERROR_SUCCESS; }
-NTSTATUS SERV_QueryServiceObjectSecurity(SC_HANDLE hService, +static NTSTATUS SERV_QueryServiceObjectSecurity(SC_HANDLE hService, SECURITY_INFORMATION dwSecurityInformation, PSECURITY_DESCRIPTOR lpSecurityDescriptor, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
From: Micah N Gorrell mgorrell@codeweavers.com
Signed-off-by: Micah N Gorrell mgorrell@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/advapi32/advapi32_misc.h | 1 - dlls/advapi32/eventlog.c | 12 +++---- dlls/advapi32/security.c | 22 ++++++------- dlls/advapi32/service.c | 60 ++++++++++++----------------------- 4 files changed, 38 insertions(+), 57 deletions(-)
diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h index 77b56420ba3..65bd8aa8529 100644 --- a/dlls/advapi32/advapi32_misc.h +++ b/dlls/advapi32/advapi32_misc.h @@ -31,7 +31,6 @@ BOOL ADVAPI_GetComputerSid(PSID sid) DECLSPEC_HIDDEN;
BOOL lookup_local_wellknown_name(const LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*) DECLSPEC_HIDDEN; BOOL lookup_local_user_name(const LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*) DECLSPEC_HIDDEN; -WCHAR *SERV_dup(const char *str) DECLSPEC_HIDDEN; const WCHAR *get_wellknown_privilege_name(const LUID *) DECLSPEC_HIDDEN;
/* memory allocation functions */ diff --git a/dlls/advapi32/eventlog.c b/dlls/advapi32/eventlog.c index 11561b21271..c81df3ee29f 100644 --- a/dlls/advapi32/eventlog.c +++ b/dlls/advapi32/eventlog.c @@ -57,7 +57,7 @@ BOOL WINAPI BackupEventLogA( HANDLE hEventLog, LPCSTR lpBackupFileName ) LPWSTR backupW; BOOL ret;
- backupW = SERV_dup(lpBackupFileName); + backupW = strdupAW(lpBackupFileName); ret = BackupEventLogW(hEventLog, backupW); heap_free(backupW);
@@ -114,7 +114,7 @@ BOOL WINAPI ClearEventLogA( HANDLE hEventLog, LPCSTR lpBackupFileName ) LPWSTR backupW; BOOL ret;
- backupW = SERV_dup(lpBackupFileName); + backupW = strdupAW(lpBackupFileName); ret = ClearEventLogW(hEventLog, backupW); heap_free(backupW);
@@ -392,8 +392,8 @@ HANDLE WINAPI OpenBackupEventLogA( LPCSTR lpUNCServerName, LPCSTR lpFileName ) LPWSTR uncnameW, filenameW; HANDLE handle;
- uncnameW = SERV_dup(lpUNCServerName); - filenameW = SERV_dup(lpFileName); + uncnameW = strdupAW(lpUNCServerName); + filenameW = strdupAW(lpFileName); handle = OpenBackupEventLogW(uncnameW, filenameW); heap_free(uncnameW); heap_free(filenameW); @@ -451,8 +451,8 @@ HANDLE WINAPI OpenEventLogA( LPCSTR uncname, LPCSTR source ) LPWSTR uncnameW, sourceW; HANDLE handle;
- uncnameW = SERV_dup(uncname); - sourceW = SERV_dup(source); + uncnameW = strdupAW(uncname); + sourceW = strdupAW(source); handle = OpenEventLogW(uncnameW, sourceW); heap_free(uncnameW); heap_free(sourceW); diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 7315f9b51a9..d3c9a6c1e29 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -1015,7 +1015,7 @@ GetFileSecurityA( LPCSTR lpFileName, BOOL r; LPWSTR name;
- name = SERV_dup(lpFileName); + name = strdupAW(lpFileName); r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor, nLength, lpnLengthNeeded ); heap_free( name ); @@ -1044,7 +1044,7 @@ LookupAccountSidA( DWORD accountSizeW = *accountSize; DWORD domainSizeW = *domainSize;
- systemW = SERV_dup(system); + systemW = strdupAW(system); if (account) accountW = heap_alloc( accountSizeW * sizeof(WCHAR) ); if (domain) @@ -1299,7 +1299,7 @@ BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName, BOOL r; LPWSTR name;
- name = SERV_dup(lpFileName); + name = strdupAW(lpFileName); r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor ); heap_free( name );
@@ -2228,7 +2228,7 @@ static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR * { case TRUSTEE_IS_NAME: { - *ptrustee_nameW = SERV_dup(trustee_nameA); + *ptrustee_nameW = strdupAW(trustee_nameA); return ERROR_SUCCESS; } case TRUSTEE_IS_OBJECTS_AND_NAME: @@ -2243,9 +2243,9 @@ static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR *
objW->ObjectsPresent = objA->ObjectsPresent; objW->ObjectType = objA->ObjectType; - objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName); - objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName); - objW->ptstrName = SERV_dup(objA->ptstrName); + objW->ObjectTypeName = strdupAW(objA->ObjectTypeName); + objW->InheritedObjectTypeName = strdupAW(objA->InheritedObjectTypeName); + objW->ptstrName = strdupAW(objA->ptstrName); }
*ptrustee_nameW = (WCHAR *)objW; @@ -2625,7 +2625,7 @@ DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName, TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
- wstr = SERV_dup(pObjectName); + wstr = strdupAW(pObjectName); r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
@@ -3300,7 +3300,7 @@ BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA( if(!StringSecurityDescriptor) return FALSE;
- StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor); + StringSecurityDescriptorW = strdupAW(StringSecurityDescriptor); ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, StringSDRevision, SecurityDescriptor, SecurityDescriptorSize); @@ -3841,7 +3841,7 @@ BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid) SetLastError(ERROR_INVALID_PARAMETER); else { - WCHAR *wStringSid = SERV_dup(StringSid); + WCHAR *wStringSid = strdupAW(StringSid); bret = ConvertStringSidToSidW(wStringSid, Sid); heap_free(wStringSid); } @@ -4104,7 +4104,7 @@ DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName, TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
- wstr = SERV_dup(pObjectName); + wstr = strdupAW(pObjectName); r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 2781a128239..3bf6fdfd47f 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -113,24 +113,6 @@ static BOOL stop_service;
extern HANDLE CDECL __wine_make_process_system(void);
-/****************************************************************************** - * String management functions (same behaviour as strdup) - * NOTE: the caller of those functions is responsible for calling HeapFree - * in order to release the memory allocated by those functions. - */ -LPWSTR SERV_dup( LPCSTR str ) -{ - UINT len; - LPWSTR wstr; - - if( !str ) - return NULL; - len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); - wstr = heap_alloc( len*sizeof (WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len ); - return wstr; -} - static inline LPWSTR SERV_dupmulti(LPCSTR str) { UINT len = 0, n = 0; @@ -884,8 +866,8 @@ SC_HANDLE WINAPI OpenSCManagerA( LPCSTR lpMachineName, LPCSTR lpDatabaseName, LPWSTR machineW, databaseW; SC_HANDLE ret;
- machineW = SERV_dup(lpMachineName); - databaseW = SERV_dup(lpDatabaseName); + machineW = strdupAW(lpMachineName); + databaseW = strdupAW(lpDatabaseName); ret = OpenSCManagerW(machineW, databaseW, dwDesiredAccess); heap_free(databaseW); heap_free(machineW); @@ -1037,7 +1019,7 @@ SC_HANDLE WINAPI OpenServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
TRACE("%p %s 0x%08x\n", hSCManager, debugstr_a(lpServiceName), dwDesiredAccess);
- lpServiceNameW = SERV_dup(lpServiceName); + lpServiceNameW = strdupAW(lpServiceName); ret = OpenServiceW( hSCManager, lpServiceNameW, dwDesiredAccess); heap_free(lpServiceNameW); return ret; @@ -1171,13 +1153,13 @@ CreateServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName, TRACE("%p %s %s\n", hSCManager, debugstr_a(lpServiceName), debugstr_a(lpDisplayName));
- lpServiceNameW = SERV_dup( lpServiceName ); - lpDisplayNameW = SERV_dup( lpDisplayName ); - lpBinaryPathNameW = SERV_dup( lpBinaryPathName ); - lpLoadOrderGroupW = SERV_dup( lpLoadOrderGroup ); + lpServiceNameW = strdupAW( lpServiceName ); + lpDisplayNameW = strdupAW( lpDisplayName ); + lpBinaryPathNameW = strdupAW( lpBinaryPathName ); + lpLoadOrderGroupW = strdupAW( lpLoadOrderGroup ); lpDependenciesW = SERV_dupmulti( lpDependencies ); - lpServiceStartNameW = SERV_dup( lpServiceStartName ); - lpPasswordW = SERV_dup( lpPassword ); + lpServiceStartNameW = strdupAW( lpServiceStartName ); + lpPasswordW = strdupAW( lpPassword );
r = CreateServiceW( hSCManager, lpServiceNameW, lpDisplayNameW, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, @@ -1269,7 +1251,7 @@ BOOL WINAPI StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs, lpwstr = heap_alloc( dwNumServiceArgs*sizeof(LPWSTR) );
for(i=0; i<dwNumServiceArgs; i++) - lpwstr[i]=SERV_dup(lpServiceArgVectors[i]); + lpwstr[i]=strdupAW(lpServiceArgVectors[i]);
r = StartServiceW(hService, dwNumServiceArgs, (LPCWSTR *)lpwstr);
@@ -2108,7 +2090,7 @@ BOOL WINAPI GetServiceKeyNameA( SC_HANDLE hSCManager, LPCSTR lpDisplayName, TRACE("%p %s %p %p\n", hSCManager, debugstr_a(lpDisplayName), lpServiceName, lpcchBuffer);
- lpDisplayNameW = SERV_dup(lpDisplayName); + lpDisplayNameW = strdupAW(lpDisplayName); if (lpServiceName) lpServiceNameW = heap_alloc(*lpcchBuffer * sizeof(WCHAR)); else @@ -2231,7 +2213,7 @@ BOOL WINAPI GetServiceDisplayNameA( SC_HANDLE hSCManager, LPCSTR lpServiceName, TRACE("%p %s %p %p\n", hSCManager, debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer);
- lpServiceNameW = SERV_dup(lpServiceName); + lpServiceNameW = strdupAW(lpServiceName); if (lpDisplayName) lpDisplayNameW = heap_alloc(*lpcchBuffer * sizeof(WCHAR)); else @@ -2374,12 +2356,12 @@ BOOL WINAPI ChangeServiceConfigA( SC_HANDLE hService, DWORD dwServiceType, lpdwTagId, lpDependencies, debugstr_a(lpServiceStartName), debugstr_a(lpPassword), debugstr_a(lpDisplayName) );
- wBinaryPathName = SERV_dup( lpBinaryPathName ); - wLoadOrderGroup = SERV_dup( lpLoadOrderGroup ); + wBinaryPathName = strdupAW( lpBinaryPathName ); + wLoadOrderGroup = strdupAW( lpLoadOrderGroup ); wDependencies = SERV_dupmulti( lpDependencies ); - wServiceStartName = SERV_dup( lpServiceStartName ); - wPassword = SERV_dup( lpPassword ); - wDisplayName = SERV_dup( lpDisplayName ); + wServiceStartName = strdupAW( lpServiceStartName ); + wPassword = strdupAW( lpPassword ); + wDisplayName = strdupAW( lpDisplayName );
r = ChangeServiceConfigW( hService, dwServiceType, dwStartType, dwErrorControl, wBinaryPathName, @@ -2411,7 +2393,7 @@ BOOL WINAPI ChangeServiceConfig2A( SC_HANDLE hService, DWORD dwInfoLevel, LPSERVICE_DESCRIPTIONA sd = lpInfo; SERVICE_DESCRIPTIONW sdw;
- sdw.lpDescription = SERV_dup( sd->lpDescription ); + sdw.lpDescription = strdupAW( sd->lpDescription );
r = ChangeServiceConfig2W( hService, dwInfoLevel, &sdw );
@@ -2423,8 +2405,8 @@ BOOL WINAPI ChangeServiceConfig2A( SC_HANDLE hService, DWORD dwInfoLevel, SERVICE_FAILURE_ACTIONSW faw;
faw.dwResetPeriod = fa->dwResetPeriod; - faw.lpRebootMsg = SERV_dup( fa->lpRebootMsg ); - faw.lpCommand = SERV_dup( fa->lpCommand ); + faw.lpRebootMsg = strdupAW( fa->lpRebootMsg ); + faw.lpCommand = strdupAW( fa->lpCommand ); faw.cActions = fa->cActions; faw.lpsaActions = fa->lpsaActions;
@@ -2589,7 +2571,7 @@ SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA( LPCSTR name, LPHANDL LPWSTR nameW; SERVICE_STATUS_HANDLE ret;
- nameW = SERV_dup(name); + nameW = strdupAW(name); ret = RegisterServiceCtrlHandlerExW( nameW, handler, context ); heap_free( nameW ); return ret;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/advapi32/service.c | 48 ++++++----------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-)
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 3bf6fdfd47f..4d32b44eefd 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -741,54 +741,20 @@ BOOL WINAPI StartServiceCtrlDispatcherW( const SERVICE_TABLE_ENTRYW *servent ) /****************************************************************************** * LockServiceDatabase [ADVAPI32.@] */ -SC_LOCK WINAPI LockServiceDatabase (SC_HANDLE hSCManager) +SC_LOCK WINAPI LockServiceDatabase( SC_HANDLE manager ) { - SC_RPC_LOCK hLock = NULL; - DWORD err; - - TRACE("%p\n",hSCManager); - - __TRY - { - err = svcctl_LockServiceDatabase(hSCManager, &hLock); - } - __EXCEPT(rpc_filter) - { - err = map_exception_code(GetExceptionCode()); - } - __ENDTRY - if (err != ERROR_SUCCESS) - { - SetLastError(err); - return NULL; - } - return hLock; + /* this function is a no-op in Vista and above */ + TRACE("%p\n", manager); + return (SC_LOCK)0xdeadbeef; }
/****************************************************************************** * UnlockServiceDatabase [ADVAPI32.@] */ -BOOL WINAPI UnlockServiceDatabase (SC_LOCK ScLock) +BOOL WINAPI UnlockServiceDatabase( SC_LOCK lock ) { - DWORD err; - SC_RPC_LOCK hRpcLock = ScLock; - - TRACE("%p\n",ScLock); - - __TRY - { - err = svcctl_UnlockServiceDatabase(&hRpcLock); - } - __EXCEPT(rpc_filter) - { - err = map_exception_code(GetExceptionCode()); - } - __ENDTRY - if (err != ERROR_SUCCESS) - { - SetLastError(err); - return FALSE; - } + /* this function is a no-op in Vista and above */ + TRACE("%p\n", lock); return TRUE; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- programs/services/rpc.c | 44 ++++++----------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-)
diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 0f2c1440c23..d0f85024191 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -1365,55 +1365,23 @@ DWORD __cdecl svcctl_CloseServiceHandle( return ERROR_SUCCESS; }
-static void SC_RPC_LOCK_destroy(SC_RPC_LOCK hLock) -{ - struct sc_lock *lock = hLock; - scmdatabase_unlock_startup(lock->db); - HeapFree(GetProcessHeap(), 0, lock); -} - void __RPC_USER SC_RPC_LOCK_rundown(SC_RPC_LOCK hLock) { - SC_RPC_LOCK_destroy(hLock); }
-DWORD __cdecl svcctl_LockServiceDatabase( - SC_RPC_HANDLE hSCManager, - SC_RPC_LOCK *phLock) +DWORD __cdecl svcctl_LockServiceDatabase(SC_RPC_HANDLE manager, SC_RPC_LOCK *lock) { - struct sc_manager_handle *manager; - struct sc_lock *lock; - DWORD err; - - WINE_TRACE("(%p, %p)\n", hSCManager, phLock); - - if ((err = validate_scm_handle(hSCManager, SC_MANAGER_LOCK, &manager)) != ERROR_SUCCESS) - return err; - - if (!scmdatabase_lock_startup(manager->db, 0)) - return ERROR_SERVICE_DATABASE_LOCKED; - - lock = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sc_lock)); - if (!lock) - { - scmdatabase_unlock_startup(manager->db); - return ERROR_NOT_ENOUGH_SERVER_MEMORY; - } - - lock->db = manager->db; - *phLock = lock; + TRACE("(%p, %p)\n", manager, lock);
+ *lock = (SC_RPC_LOCK)0xdeadbeef; return ERROR_SUCCESS; }
-DWORD __cdecl svcctl_UnlockServiceDatabase( - SC_RPC_LOCK *phLock) +DWORD __cdecl svcctl_UnlockServiceDatabase(SC_RPC_LOCK *lock) { - WINE_TRACE("(&%p)\n", *phLock); - - SC_RPC_LOCK_destroy(*phLock); - *phLock = NULL; + TRACE("(&%p)\n", *lock);
+ *lock = NULL; return ERROR_SUCCESS; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- This introduces a test failure, which is fundamentally due to a missing implementation of the "resume_handle" parameter. The test previously passed because we returned 0 services if the buffer was too short, but as the ANSI tests show, that behaviour is incorrect—we should return as many services as we have room for. This patch corrects that behaviour.
dlls/advapi32/service.c | 124 +++++++++++++++------------------- dlls/advapi32/tests/service.c | 2 +- 2 files changed, 54 insertions(+), 72 deletions(-)
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 4d32b44eefd..eb195d84d05 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -1749,109 +1749,91 @@ done: * EnumServicesStatusW [ADVAPI32.@] */ BOOL WINAPI -EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_STATUSW - services, DWORD size, LPDWORD needed, LPDWORD returned, - LPDWORD resume_handle ) +EnumServicesStatusW( SC_HANDLE manager, DWORD type, DWORD state, ENUM_SERVICE_STATUSW *status, + DWORD size, DWORD *ret_size, DWORD *ret_count, DWORD *resume_handle ) { - DWORD err, i, offset, buflen, count, total_size = 0; - struct enum_service_status *entry; - const WCHAR *str; - BYTE *buf; + ENUM_SERVICE_STATUS_PROCESSW *status_ex; + DWORD alloc_size, count, i; + WCHAR *p;
- TRACE("%p 0x%x 0x%x %p %u %p %p %p\n", hmngr, type, state, services, size, needed, - returned, resume_handle); + TRACE("%p 0x%x 0x%x %p %u %p %p %p\n", manager, type, state, status, size, + ret_size, ret_count, resume_handle);
- if (!hmngr) + if (!manager) { SetLastError( ERROR_INVALID_HANDLE ); return FALSE; } - if (!needed || !returned) + + if (!ret_size || !ret_count) { - SetLastError( ERROR_INVALID_ADDRESS ); + SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
- /* make sure we pass a valid pointer */ - buflen = max( size, sizeof(*services) ); - if (!(buf = heap_alloc( buflen ))) + *ret_size = 0; + *ret_count = 0; + if (!EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, type, state, + NULL, 0, &alloc_size, &count, resume_handle, NULL ) + && GetLastError() != ERROR_MORE_DATA) + return FALSE; + + if (!(status_ex = heap_alloc( alloc_size ))) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return FALSE; }
- __TRY + if (!EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, type, state, (BYTE *)status_ex, + alloc_size, &alloc_size, &count, resume_handle, NULL ) + && GetLastError() != ERROR_MORE_DATA) { - err = svcctl_EnumServicesStatusW( hmngr, type, state, buf, buflen, needed, &count, resume_handle ); - } - __EXCEPT(rpc_filter) - { - err = map_exception_code( GetExceptionCode() ); + heap_free( status_ex ); + return FALSE; } - __ENDTRY
- *returned = 0; - if (err != ERROR_SUCCESS) + for (i = 0; i < count; i++) { - /* double the needed size to fit the potentially larger ENUM_SERVICE_STATUSW */ - if (err == ERROR_MORE_DATA) *needed *= 2; - heap_free( buf ); - SetLastError( err ); - return FALSE; + *ret_size += sizeof(ENUM_SERVICE_STATUSW); + *ret_size += (strlenW( status_ex[i].lpServiceName ) + 1) * sizeof(WCHAR); + if (status_ex[i].lpDisplayName) + *ret_size += (strlenW( status_ex[i].lpDisplayName ) + 1) * sizeof(WCHAR); + + if (*ret_size <= size) + ++*ret_count; }
- entry = (struct enum_service_status *)buf; - for (i = 0; i < count; i++) + p = (WCHAR *)(status + *ret_count); + for (i = 0; i < *ret_count; i++) { - total_size += sizeof(*services); - if (entry->service_name) - { - str = (const WCHAR *)(buf + entry->service_name); - total_size += (strlenW( str ) + 1) * sizeof(WCHAR); - } - if (entry->display_name) + strcpyW( p, status_ex[i].lpServiceName ); + status[i].lpServiceName = (WCHAR *)p; + p += strlenW( p ) + 1; + if (status_ex[i].lpDisplayName) { - str = (const WCHAR *)(buf + entry->display_name); - total_size += (strlenW( str ) + 1) * sizeof(WCHAR); + strcpyW( p, status_ex[i].lpDisplayName ); + status[i].lpDisplayName = (WCHAR *)p; + p += strlenW( p ) + 1; } - entry++; + else status[i].lpDisplayName = NULL; + + status[i].ServiceStatus.dwServiceType = status_ex[i].ServiceStatusProcess.dwServiceType; + status[i].ServiceStatus.dwCurrentState = status_ex[i].ServiceStatusProcess.dwCurrentState; + status[i].ServiceStatus.dwControlsAccepted = status_ex[i].ServiceStatusProcess.dwControlsAccepted; + status[i].ServiceStatus.dwWin32ExitCode = status_ex[i].ServiceStatusProcess.dwWin32ExitCode; + status[i].ServiceStatus.dwServiceSpecificExitCode = status_ex[i].ServiceStatusProcess.dwServiceSpecificExitCode; + status[i].ServiceStatus.dwCheckPoint = status_ex[i].ServiceStatusProcess.dwCheckPoint; + status[i].ServiceStatus.dwWaitHint = status_ex[i].ServiceStatusProcess.dwWaitHint; }
- if (total_size > size) + heap_free( status_ex ); + if (*ret_size > size) { - heap_free( buf ); - *needed = total_size; SetLastError( ERROR_MORE_DATA ); return FALSE; }
- offset = count * sizeof(*services); - entry = (struct enum_service_status *)buf; - for (i = 0; i < count; i++) - { - DWORD str_size; - str = (const WCHAR *)(buf + entry->service_name); - str_size = (strlenW( str ) + 1) * sizeof(WCHAR); - services[i].lpServiceName = (WCHAR *)((char *)services + offset); - memcpy( services[i].lpServiceName, str, str_size ); - offset += str_size; - - if (!entry->display_name) services[i].lpDisplayName = NULL; - else - { - str = (const WCHAR *)(buf + entry->display_name); - str_size = (strlenW( str ) + 1) * sizeof(WCHAR); - services[i].lpDisplayName = (WCHAR *)((char *)services + offset); - memcpy( services[i].lpDisplayName, str, str_size ); - offset += str_size; - } - services[i].ServiceStatus = entry->service_status; - entry++; - } - - heap_free( buf ); - *needed = 0; - *returned = count; + *ret_size = 0; return TRUE; }
diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index 4bf9f4c34b3..7048e5a09ab 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -1339,7 +1339,7 @@ static void test_enum_svc(void) 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); + todo_wine ok(returned == missing, "Expected %u services to be returned\n", missing); ok(resume == 0, "Expected the resume handle to be 0\n"); HeapFree(GetProcessHeap(), 0, services);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70719
Your paranoid android.
=== w8 (32 bit report) ===
advapi32: service.c:1342: Test failed: Expected 108 services to be returned