Index: base/system/services/database.c =================================================================== --- base/system/services/database.c (révision 56787) +++ base/system/services/database.c (copie de travail) @@ -29,13 +29,29 @@ */ // #define USE_ASYNCHRONOUS_IO +#include + /* GLOBALS *******************************************************************/ +/* + * Structure describing a user database lock. + */ +#define LOCK_TAG 0x4C697041 /* 'ApiL' */ + +typedef struct _SC_LOCK_STRUCT +{ + DWORD Tag; /* Must be LOCK_TAG */ + DWORD TimeWhenLocked; /* Number of seconds since 1970 */ + PSID LockOwnerSid; /* It is NULL if SC Manager grabbed the lock */ +} SC_LOCK_STRUCT, *PSC_LOCK_STRUCT; + + LIST_ENTRY ImageListHead; LIST_ENTRY ServiceListHead; static RTL_RESOURCE DatabaseLock; +static PSC_LOCK_STRUCT SCActiveDatabaseLock = NULL; static DWORD dwResumeCount = 1; static CRITICAL_SECTION ControlServiceCriticalSection; @@ -44,6 +60,171 @@ /* FUNCTIONS *****************************************************************/ +DWORD +ScmLockDatabase(IN BOOL IsServiceController, /* TRUE if locked by the Service Control Manager, FALSE otherwise */ + OUT LPSC_RPC_LOCK lpLock) +{ + DWORD dwRequiredSize = 0; + DWORD dwError = ERROR_SUCCESS; + + *lpLock = NULL; + + /* Lock the whole SC manager exclusively */ + ScmDatabaseLockExclusive(); + + if (SCActiveDatabaseLock != NULL) + { + dwError = ERROR_SERVICE_DATABASE_LOCKED; + goto Done; + } + + /* + * Allocate a new lock for the database. + */ + dwRequiredSize = sizeof(SC_LOCK_STRUCT); + + if (!IsServiceController) + { + /* FIXME: dwRequiredSize += RtlLengthSid(UserSid <-- to be retrieved); */ + } + + SCActiveDatabaseLock = (PSC_LOCK_STRUCT)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwRequiredSize); + if (SCActiveDatabaseLock == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto Done; + } + + SCActiveDatabaseLock->Tag = LOCK_TAG; + SCActiveDatabaseLock->TimeWhenLocked = (DWORD)time(NULL); + /* FIXME: Retrieve the owner SID. Use IsServiceController. */ + SCActiveDatabaseLock->LockOwnerSid = (PSID)NULL; + + *lpLock = SCActiveDatabaseLock; + + dwError = ERROR_SUCCESS; + +Done: + /* Unlock the whole SC manager */ + ScmDatabaseUnlock(); + + return dwError; +} + + +DWORD +ScmUnlockDatabase(IN OUT LPSC_RPC_LOCK lpLock) +{ + PSC_LOCK_STRUCT apiLock; + DWORD dwError = ERROR_SUCCESS; + + if (lpLock == NULL) + return ERROR_INVALID_SERVICE_LOCK; + + apiLock = *(PSC_LOCK_STRUCT*)lpLock; + + if (apiLock->Tag != LOCK_TAG) + return ERROR_INVALID_SERVICE_LOCK; + + /* Lock the whole SC manager exclusively */ + ScmDatabaseLockExclusive(); + + /* Release the lock handle */ + if ( (apiLock == SCActiveDatabaseLock) && + (SCActiveDatabaseLock != NULL) ) + { + HeapFree(GetProcessHeap(), 0, SCActiveDatabaseLock); + SCActiveDatabaseLock = NULL; + *lpLock = NULL; + + dwError = ERROR_SUCCESS; + } + else + { + dwError = ERROR_INVALID_SERVICE_LOCK; + } + + /* Unlock the whole SC manager */ + ScmDatabaseUnlock(); + + return dwError; +} + + +/* + * Helper functions for RQueryServiceLockStatusW() and + * RQueryServiceLockStatusA(). + * We suppose that lpLockStatus points to a valid + * well-sized memory zone. + * + * Put here in order to keep SCActiveDatabaseLock + * visible only in this file. + */ +VOID +ScmQueryServiceLockStatusW(OUT LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus) +{ + /* Lock the whole SC manager shared */ + ScmDatabaseLockShared(); + + if (SCActiveDatabaseLock) + { + lpLockStatus->fIsLocked = TRUE; + + /* FIXME: Retrieve the owner name. */ + lpLockStatus->lpLockOwner = NULL; + + lpLockStatus->dwLockDuration = (DWORD)time(NULL) - SCActiveDatabaseLock->TimeWhenLocked; + } + else + { + lpLockStatus->fIsLocked = FALSE; + + wcscpy((LPWSTR)(lpLockStatus + 1), L""); + lpLockStatus->lpLockOwner = (LPWSTR)(ULONG_PTR)sizeof(QUERY_SERVICE_LOCK_STATUSW); + + lpLockStatus->dwLockDuration = 0; + } + + /* Unlock the whole SC manager */ + ScmDatabaseUnlock(); + + return; +} + +VOID +ScmQueryServiceLockStatusA(OUT LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus) +{ + /* Lock the whole SC manager shared */ + ScmDatabaseLockShared(); + + if (SCActiveDatabaseLock) + { + lpLockStatus->fIsLocked = TRUE; + + /* FIXME: Retrieve the owner name. */ + lpLockStatus->lpLockOwner = NULL; + + lpLockStatus->dwLockDuration = (DWORD)time(NULL) - SCActiveDatabaseLock->TimeWhenLocked; + } + else + { + lpLockStatus->fIsLocked = FALSE; + + strcpy((LPSTR)(lpLockStatus + 1), ""); + lpLockStatus->lpLockOwner = (LPSTR)(ULONG_PTR)sizeof(QUERY_SERVICE_LOCK_STATUSA); + + lpLockStatus->dwLockDuration = 0; + } + + /* Unlock the whole SC manager */ + ScmDatabaseUnlock(); + + return; +} + + static DWORD ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage) { @@ -1862,7 +2043,7 @@ DPRINT("ScmAutoShutdownServices() called\n"); /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); ServiceEntry = ServiceListHead.Flink; while (ServiceEntry != &ServiceListHead) @@ -1881,28 +2062,28 @@ } /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("ScmAutoShutdownServices() done\n"); } BOOL -ScmLockDatabaseExclusive(VOID) +ScmDatabaseLockExclusive(VOID) { return RtlAcquireResourceExclusive(&DatabaseLock, TRUE); } BOOL -ScmLockDatabaseShared(VOID) +ScmDatabaseLockShared(VOID) { return RtlAcquireResourceShared(&DatabaseLock, TRUE); } VOID -ScmUnlockDatabase(VOID) +ScmDatabaseUnlock(VOID) { RtlReleaseResource(&DatabaseLock); } Index: base/system/services/rpcserver.c =================================================================== --- base/system/services/rpcserver.c (révision 56787) +++ base/system/services/rpcserver.c (copie de travail) @@ -979,7 +979,7 @@ DPRINT("Found service handle\n"); /* Lock the service database exlusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); /* Get the pointer to the service record */ lpService = hService->ServiceEntry; @@ -1010,7 +1010,7 @@ if (dwError != ERROR_SUCCESS) { DPRINT("Failed to open services key\n"); - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return dwError; } @@ -1027,7 +1027,7 @@ { DPRINT("Deletion failed due to running dependencies.\n"); RegCloseKey(hServicesKey); - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return ERROR_SUCCESS; } @@ -1043,7 +1043,7 @@ if (dwError != ERROR_SUCCESS) { DPRINT("Failed to Delete the Service Registry key\n"); - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return dwError; } @@ -1052,7 +1052,7 @@ } } - ScmUnlockDatabase(); + ScmDatabaseUnlock(); *hSCObject = NULL; @@ -1274,7 +1274,7 @@ } /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); if (lpService->bDeleted) { @@ -1290,7 +1290,7 @@ Done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("RDeleteService() done\n"); @@ -1307,7 +1307,8 @@ DPRINT("RLockServiceDatabase() called\n"); - *lpLock = 0; + // assert(lpLock); + *lpLock = NULL; hMgr = ScmGetServiceManagerFromHandle(hSCManager); if (hMgr == NULL) @@ -1320,12 +1321,9 @@ SC_MANAGER_LOCK)) return ERROR_ACCESS_DENIED; -// return ScmLockDatabase(0, hMgr->0xC, hLock); + DPRINT("RLockServiceDatabase() done\n"); - /* FIXME: Lock the database */ - *lpLock = (SC_RPC_LOCK)0x12345678; /* Dummy! */ - - return ERROR_SUCCESS; + return ScmLockDatabase(FALSE, lpLock); } @@ -1379,7 +1377,7 @@ } /* Lock the service database */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); /* hack */ @@ -1392,7 +1390,7 @@ &dwBytesNeeded); /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (NT_SUCCESS(Status)) { @@ -1497,7 +1495,7 @@ #endif /* Lock the service database exclusive */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); #if 0 Status = RtlSetSecurityObject(dwSecurityInformation, @@ -1534,7 +1532,7 @@ #endif /* Unlock service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("RSetServiceObjectSecurity() done (Error %lu)\n", dwError); @@ -1577,7 +1575,7 @@ } /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); /* Return service status information */ RtlCopyMemory(lpServiceStatus, @@ -1585,7 +1583,7 @@ sizeof(SERVICE_STATUS)); /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return ERROR_SUCCESS; } @@ -1667,7 +1665,7 @@ } /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); /* Save the current service state */ dwPreviousState = lpService->Status.dwCurrentState; @@ -1677,7 +1675,7 @@ sizeof(SERVICE_STATUS)); /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); /* Log a failed service stop */ if ((lpServiceStatus->dwCurrentState == SERVICE_STOPPED) && @@ -1706,8 +1704,9 @@ DWORD RUnlockServiceDatabase( LPSC_RPC_LOCK Lock) { - UNIMPLEMENTED; - return ERROR_SUCCESS; + DPRINT("RUnlockServiceDatabase() called\n"); + DPRINT("RUnlockServiceDatabase() done\n"); + return ScmUnlockDatabase(Lock); } @@ -1793,7 +1792,7 @@ } /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); if (lpService->bDeleted) { @@ -1966,7 +1965,7 @@ RegCloseKey(hServiceKey); /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError); @@ -2084,13 +2083,13 @@ } /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); lpService = ScmGetServiceEntryByName(lpServiceName); if (lpService) { /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); /* Check if it is marked for deletion */ if (lpService->bDeleted) @@ -2104,7 +2103,7 @@ ScmGetServiceEntryByDisplayName(lpDisplayName) != NULL) { /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return ERROR_DUPLICATE_SERVICE_NAME; } @@ -2123,7 +2122,7 @@ dwStartType == SERVICE_SYSTEM_START) { /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return ERROR_INVALID_PARAMETER; } @@ -2314,7 +2313,7 @@ done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -2599,7 +2598,7 @@ return ERROR_INVALID_ADDRESS; /* Lock the service database exclusive */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); /* Get service database entry */ lpService = ScmGetServiceEntryByName(lpServiceName); @@ -2637,7 +2636,7 @@ Done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("ROpenServiceW() done\n"); @@ -2693,7 +2692,7 @@ } /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); dwError = ScmOpenServiceKey(lpService->lpServiceName, KEY_READ, @@ -2834,7 +2833,7 @@ Done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (lpImagePath != NULL) HeapFree(GetProcessHeap(), 0, lpImagePath); @@ -2857,12 +2856,41 @@ /* Function 18 */ DWORD RQueryServiceLockStatusW( SC_RPC_HANDLE hSCManager, - LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, + LPBYTE lpBuf, // LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, DWORD cbBufSize, LPBOUNDED_DWORD_4K pcbBytesNeeded) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus = (LPQUERY_SERVICE_LOCK_STATUSW)lpBuf; + PMANAGER_HANDLE hMgr; + DWORD dwRequiredSize; + + if (!lpLockStatus || !pcbBytesNeeded) + return ERROR_INVALID_PARAMETER; + + hMgr = ScmGetServiceManagerFromHandle(hSCManager); + if (hMgr == NULL) + { + DPRINT1("Invalid service manager handle!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess, + SC_MANAGER_QUERY_LOCK_STATUS)) + { + DPRINT("Insufficient access rights! 0x%lx\n", hMgr->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + /* HACK: we need to compute instead the real length of the owner name */ + dwRequiredSize = sizeof(QUERY_SERVICE_LOCK_STATUSW) + sizeof(WCHAR); + *pcbBytesNeeded = dwRequiredSize; + + if (cbBufSize < dwRequiredSize) + return ERROR_INSUFFICIENT_BUFFER; + + ScmQueryServiceLockStatusW(lpLockStatus); + + return ERROR_SUCCESS; } @@ -2875,6 +2903,7 @@ DWORD dwError = ERROR_SUCCESS; PSERVICE_HANDLE hSvc; PSERVICE lpService = NULL; + SC_RPC_LOCK Lock = NULL; DWORD i; DPRINT("RStartServiceW(%p %lu %p) called\n", hService, argc, argv); @@ -2917,9 +2946,17 @@ if (lpService->bDeleted) return ERROR_SERVICE_MARKED_FOR_DELETE; + /* Lock the SCM active database until start is complete */ + dwError = ScmLockDatabase(TRUE, &Lock); + if (dwError != ERROR_SUCCESS) + return dwError; + /* Start the service */ dwError = ScmStartService(lpService, argc, (LPWSTR*)argv); + /* Unlock the SCM active database */ + ScmUnlockDatabase(&Lock); + return dwError; } @@ -3134,7 +3171,7 @@ } /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); if (lpService->bDeleted) { @@ -3367,7 +3404,7 @@ done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (hServiceKey != NULL) RegCloseKey(hServiceKey); @@ -3893,7 +3930,7 @@ } /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); dwError = ScmOpenServiceKey(lpService->lpServiceName, KEY_READ, @@ -4067,7 +4104,7 @@ Done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (lpImagePath != NULL) HeapFree(GetProcessHeap(), 0, lpImagePath); @@ -4090,12 +4127,41 @@ /* Function 30 */ DWORD RQueryServiceLockStatusA( SC_RPC_HANDLE hSCManager, - LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, + LPBYTE lpBuf, // LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, DWORD cbBufSize, LPBOUNDED_DWORD_4K pcbBytesNeeded) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus = (LPQUERY_SERVICE_LOCK_STATUSA)lpBuf; + PMANAGER_HANDLE hMgr; + DWORD dwRequiredSize; + + if (!lpLockStatus || !pcbBytesNeeded) + return ERROR_INVALID_PARAMETER; + + hMgr = ScmGetServiceManagerFromHandle(hSCManager); + if (hMgr == NULL) + { + DPRINT1("Invalid service manager handle!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess, + SC_MANAGER_QUERY_LOCK_STATUS)) + { + DPRINT("Insufficient access rights! 0x%lx\n", hMgr->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + /* HACK: we need to compute instead the real length of the owner name */ + dwRequiredSize = sizeof(QUERY_SERVICE_LOCK_STATUSA) + sizeof(CHAR); + *pcbBytesNeeded = dwRequiredSize; + + if (cbBufSize < dwRequiredSize) + return ERROR_INSUFFICIENT_BUFFER; + + ScmQueryServiceLockStatusA(lpLockStatus); + + return ERROR_SUCCESS; } @@ -4108,6 +4174,7 @@ DWORD dwError = ERROR_SUCCESS; PSERVICE_HANDLE hSvc; PSERVICE lpService = NULL; + SC_RPC_LOCK Lock = NULL; LPWSTR *lpVector = NULL; DWORD i; DWORD dwLength; @@ -4180,9 +4247,17 @@ } } - /* Start the service */ - dwError = ScmStartService(lpService, argc, lpVector); + /* Lock the SCM active database until start is complete */ + dwError = ScmLockDatabase(TRUE, &Lock); + if (dwError == ERROR_SUCCESS) + { + /* Start the service */ + dwError = ScmStartService(lpService, argc, lpVector); + /* Unlock the SCM active database */ + ScmUnlockDatabase(&Lock); + } + done: /* Free the Unicode argument vector */ if (lpVector != NULL) @@ -4461,7 +4536,7 @@ dwLastResumeCount = *lpResumeIndex; /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount); if (lpService == NULL) @@ -4645,7 +4720,7 @@ Done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("REnumServiceGroupW() done (Error %lu)\n", dwError); @@ -5072,7 +5147,7 @@ } /* Lock the service database exclusively */ - ScmLockDatabaseExclusive(); + ScmDatabaseLockExclusive(); if (lpService->bDeleted) { @@ -5134,7 +5209,7 @@ RegCloseKey(hServiceKey); /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError); @@ -5191,7 +5266,7 @@ } /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); dwError = ScmOpenServiceKey(lpService->lpServiceName, KEY_READ, @@ -5359,7 +5434,7 @@ done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (lpDescriptionW != NULL) HeapFree(GetProcessHeap(), 0, lpDescriptionW); @@ -5427,7 +5502,7 @@ } /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); dwError = ScmOpenServiceKey(lpService->lpServiceName, KEY_READ, @@ -5573,7 +5648,7 @@ done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); if (lpDescription != NULL) HeapFree(GetProcessHeap(), 0, lpDescription); @@ -5640,7 +5715,7 @@ } /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); lpStatus = (LPSERVICE_STATUS_PROCESS)lpBuffer; @@ -5653,7 +5728,7 @@ lpStatus->dwServiceFlags = 0; /* FIXME */ /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); return ERROR_SUCCESS; } @@ -5858,7 +5933,7 @@ dwLastResumeCount = *lpResumeIndex; /* Lock the service database shared */ - ScmLockDatabaseShared(); + ScmDatabaseLockShared(); lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount); if (lpService == NULL) @@ -6062,7 +6137,7 @@ Done: /* Unlock the service database */ - ScmUnlockDatabase(); + ScmDatabaseUnlock(); DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError); Index: base/system/services/services.c =================================================================== --- base/system/services/services.c (révision 56787) +++ base/system/services/services.c (copie de travail) @@ -377,6 +377,7 @@ int nShowCmd) { HANDLE hScmStartEvent; + SC_RPC_LOCK Lock = NULL; DWORD dwError; DPRINT("SERVICES: Service Control Manager\n"); @@ -400,13 +401,20 @@ if (dwError != ERROR_SUCCESS) { DPRINT1("SERVICES: failed to create SCM database (Error %lu)\n", dwError); - CloseHandle(hScmStartEvent); - ExitThread(0); + goto CleanExit; } /* Update service database */ ScmGetBootAndSystemDriverState(); + /* Lock the SCM active database until autostart is complete */ + dwError = ScmLockDatabase(TRUE, &Lock); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("SERVICES: failed to lock the SCM database (Error %lu)\n", dwError); + goto CleanExit; + } + /* Start the RPC server */ ScmStartRpcServer(); @@ -432,6 +440,9 @@ /* Start auto-start services */ ScmAutoStartServices(); + /* Unlock the SCM active database */ + ScmUnlockDatabase(&Lock); + /* FIXME: more to do ? */ @@ -447,6 +458,9 @@ /* Close the shutdown event */ CloseHandle(hScmShutdownEvent); + +CleanExit: + /* Close the start event */ CloseHandle(hScmStartEvent); Index: base/system/services/services.h =================================================================== --- base/system/services/services.h (révision 56787) +++ base/system/services/services.h (copie de travail) @@ -106,6 +106,11 @@ /* database.c */ +DWORD ScmLockDatabase(IN BOOL IsServiceController, + OUT LPSC_RPC_LOCK lpLock); +DWORD ScmUnlockDatabase(IN OUT LPSC_RPC_LOCK lpLock); +VOID ScmQueryServiceLockStatusW(OUT LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus); +VOID ScmQueryServiceLockStatusA(OUT LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus); DWORD ScmCreateServiceDatabase(VOID); VOID ScmShutdownServiceDatabase(VOID); VOID ScmGetBootAndSystemDriverState(VOID); @@ -126,9 +131,9 @@ DWORD ScmControlService(PSERVICE Service, DWORD dwControl); -BOOL ScmLockDatabaseExclusive(VOID); -BOOL ScmLockDatabaseShared(VOID); -VOID ScmUnlockDatabase(VOID); +BOOL ScmDatabaseLockExclusive(VOID); +BOOL ScmDatabaseLockShared(VOID); +VOID ScmDatabaseUnlock(VOID); VOID ScmInitNamedPipeCriticalSection(VOID); VOID ScmDeleteNamedPipeCriticalSection(VOID); Index: dll/win32/advapi32/service/scm.c =================================================================== --- dll/win32/advapi32/service/scm.c (révision 56787) +++ dll/win32/advapi32/service/scm.c (copie de travail) @@ -2286,7 +2286,7 @@ { /* Call to services.exe using RPC */ dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager, - lpStatusPtr, + (LPBYTE)lpStatusPtr, dwBufferSize, pcbBytesNeeded); } @@ -2348,7 +2348,7 @@ { /* Call to services.exe using RPC */ dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager, - lpStatusPtr, + (LPBYTE)lpStatusPtr, dwBufferSize, pcbBytesNeeded); } Index: include/reactos/idl/svcctl.idl =================================================================== --- include/reactos/idl/svcctl.idl (révision 56787) +++ include/reactos/idl/svcctl.idl (copie de travail) @@ -443,7 +443,8 @@ /* Function 18 */ DWORD RQueryServiceLockStatusW( [in] SC_RPC_HANDLE hSCManager, - [out] LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, + [out, size_is(cbBufSize)] LPBYTE lpLockStatus, + /* FIXME: should be [out] LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus, */ [in, range(0, 1024*4)] DWORD cbBufSize, [out] LPBOUNDED_DWORD_4K pcbBytesNeeded); @@ -555,7 +556,8 @@ /* Function 30 */ DWORD RQueryServiceLockStatusA( [in] SC_RPC_HANDLE hSCManager, - [out] LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, + [out, size_is(cbBufSize)] LPBYTE lpLockStatus, + /* FIXME: should be [out] LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus, */ [in, range(0, 1024*4)] DWORD cbBufSize, [out] LPBOUNDED_DWORD_4K pcbBytesNeeded);