services: Move LockServiceDatabase and UnlockServiceDatabase from advapi32.dll to services.exe.
This commit is contained in:
parent
b48714b148
commit
7afd9a977a
|
@ -954,21 +954,26 @@ BOOL WINAPI StartServiceCtrlDispatcherW( const SERVICE_TABLE_ENTRYW *servent )
|
||||||
*/
|
*/
|
||||||
SC_LOCK WINAPI LockServiceDatabase (SC_HANDLE hSCManager)
|
SC_LOCK WINAPI LockServiceDatabase (SC_HANDLE hSCManager)
|
||||||
{
|
{
|
||||||
HANDLE ret;
|
struct sc_manager *hscm;
|
||||||
|
SC_RPC_LOCK hLock;
|
||||||
|
DWORD err;
|
||||||
|
|
||||||
TRACE("%p\n",hSCManager);
|
TRACE("%p\n",hSCManager);
|
||||||
|
|
||||||
ret = CreateSemaphoreW( NULL, 1, 1, szSCMLock );
|
hscm = sc_handle_get_handle_data( hSCManager, SC_HTYPE_MANAGER );
|
||||||
if( ret && GetLastError() == ERROR_ALREADY_EXISTS )
|
if (!hscm)
|
||||||
{
|
{
|
||||||
CloseHandle( ret );
|
SetLastError( ERROR_INVALID_HANDLE );
|
||||||
ret = NULL;
|
return NULL;
|
||||||
SetLastError( ERROR_SERVICE_DATABASE_LOCKED );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("returning %p\n", ret);
|
err = svcctl_LockServiceDatabase(hscm->hdr.server_handle, &hLock);
|
||||||
|
if (err != ERROR_SUCCESS)
|
||||||
return ret;
|
{
|
||||||
|
SetLastError(err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return hLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -976,9 +981,18 @@ SC_LOCK WINAPI LockServiceDatabase (SC_HANDLE hSCManager)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI UnlockServiceDatabase (SC_LOCK ScLock)
|
BOOL WINAPI UnlockServiceDatabase (SC_LOCK ScLock)
|
||||||
{
|
{
|
||||||
|
DWORD err;
|
||||||
|
SC_RPC_LOCK hRpcLock = ScLock;
|
||||||
|
|
||||||
TRACE("%p\n",ScLock);
|
TRACE("%p\n",ScLock);
|
||||||
|
|
||||||
return CloseHandle( ScLock );
|
err = svcctl_UnlockServiceDatabase(&hRpcLock);
|
||||||
|
if (err != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(err);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -43,6 +43,7 @@ interface svcctl
|
||||||
/* handle types */
|
/* handle types */
|
||||||
typedef [handle] LPCWSTR MACHINE_HANDLEW;
|
typedef [handle] LPCWSTR MACHINE_HANDLEW;
|
||||||
typedef [context_handle] void *SC_RPC_HANDLE;
|
typedef [context_handle] void *SC_RPC_HANDLE;
|
||||||
|
typedef [context_handle] void *SC_RPC_LOCK;
|
||||||
|
|
||||||
/* undocumented access rights */
|
/* undocumented access rights */
|
||||||
cpp_quote("#define SERVICE_SET_STATUS 0x8000")
|
cpp_quote("#define SERVICE_SET_STATUS 0x8000")
|
||||||
|
@ -86,12 +87,23 @@ cpp_quote("#endif")
|
||||||
[in] SC_RPC_HANDLE hService
|
[in] SC_RPC_HANDLE hService
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Compatible with Windows function 0x03 */
|
||||||
|
DWORD svcctl_LockServiceDatabase(
|
||||||
|
[in] SC_RPC_HANDLE hSCManager,
|
||||||
|
[out] SC_RPC_LOCK *phLock
|
||||||
|
);
|
||||||
|
|
||||||
/* Compatible with Windows function 0x07 */
|
/* Compatible with Windows function 0x07 */
|
||||||
DWORD svcctl_SetServiceStatus(
|
DWORD svcctl_SetServiceStatus(
|
||||||
[in] SC_RPC_HANDLE hServiceStatus,
|
[in] SC_RPC_HANDLE hServiceStatus,
|
||||||
[in] LPSERVICE_STATUS lpServiceStatus
|
[in] LPSERVICE_STATUS lpServiceStatus
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Compatible with Windows function 0x08 */
|
||||||
|
DWORD svcctl_UnlockServiceDatabase(
|
||||||
|
[in,out] SC_RPC_LOCK *phLock
|
||||||
|
);
|
||||||
|
|
||||||
/* Compatible with Windows function 0x0b */
|
/* Compatible with Windows function 0x0b */
|
||||||
DWORD svcctl_ChangeServiceConfigW(
|
DWORD svcctl_ChangeServiceConfigW(
|
||||||
[in] SC_RPC_HANDLE hService,
|
[in] SC_RPC_HANDLE hService,
|
||||||
|
|
|
@ -88,6 +88,11 @@ struct sc_service /* service handle */
|
||||||
struct service_entry *service_entry;
|
struct service_entry *service_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sc_lock
|
||||||
|
{
|
||||||
|
char dummy; /* no state currently used */
|
||||||
|
};
|
||||||
|
|
||||||
/* Check if the given handle is of the required type and allows the requested access. */
|
/* Check if the given handle is of the required type and allows the requested access. */
|
||||||
static DWORD validate_context_handle(SC_RPC_HANDLE handle, DWORD type, DWORD needed_access, struct sc_handle **out_hdr)
|
static DWORD validate_context_handle(SC_RPC_HANDLE handle, DWORD type, DWORD needed_access, struct sc_handle **out_hdr)
|
||||||
{
|
{
|
||||||
|
@ -654,6 +659,51 @@ DWORD svcctl_CloseServiceHandle(
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SC_RPC_LOCK_destroy(SC_RPC_LOCK hLock)
|
||||||
|
{
|
||||||
|
unlock_service_database();
|
||||||
|
HeapFree(GetProcessHeap(), 0, hLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __RPC_USER SC_RPC_LOCK_rundown(SC_RPC_LOCK hLock)
|
||||||
|
{
|
||||||
|
SC_RPC_LOCK_destroy(hLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD svcctl_LockServiceDatabase(
|
||||||
|
SC_RPC_HANDLE hSCManager,
|
||||||
|
SC_RPC_LOCK *phLock)
|
||||||
|
{
|
||||||
|
struct sc_manager *manager;
|
||||||
|
DWORD err;
|
||||||
|
|
||||||
|
WINE_TRACE("(%p, %p)\n", hSCManager, phLock);
|
||||||
|
|
||||||
|
if ((err = validate_scm_handle(hSCManager, SC_MANAGER_LOCK, &manager)) != ERROR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = lock_service_database();
|
||||||
|
if (err != ERROR_SUCCESS)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
*phLock = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sc_lock));
|
||||||
|
if (!*phLock)
|
||||||
|
return ERROR_NOT_ENOUGH_SERVER_MEMORY;
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD svcctl_UnlockServiceDatabase(
|
||||||
|
SC_RPC_LOCK *phLock)
|
||||||
|
{
|
||||||
|
WINE_TRACE("(&%p)\n", *phLock);
|
||||||
|
|
||||||
|
SC_RPC_LOCK_destroy(*phLock);
|
||||||
|
*phLock = NULL;
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD RPC_MainLoop(void)
|
DWORD RPC_MainLoop(void)
|
||||||
{
|
{
|
||||||
WCHAR transport[] = SVCCTL_TRANSPORT;
|
WCHAR transport[] = SVCCTL_TRANSPORT;
|
||||||
|
|
|
@ -274,6 +274,20 @@ BOOL validate_service_config(struct service_entry *entry)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LONG service_lock = FALSE;
|
||||||
|
|
||||||
|
DWORD lock_service_database(void)
|
||||||
|
{
|
||||||
|
if (InterlockedCompareExchange(&service_lock, TRUE, FALSE))
|
||||||
|
return ERROR_SERVICE_DATABASE_LOCKED;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock_service_database(void)
|
||||||
|
{
|
||||||
|
InterlockedCompareExchange(&service_lock, FALSE, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
void lock_services(void)
|
void lock_services(void)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&services_list_cs);
|
EnterCriticalSection(&services_list_cs);
|
||||||
|
|
|
@ -45,6 +45,9 @@ DWORD save_service_config(struct service_entry *entry);
|
||||||
void free_service_entry(struct service_entry *entry);
|
void free_service_entry(struct service_entry *entry);
|
||||||
void release_service(struct service_entry *service);
|
void release_service(struct service_entry *service);
|
||||||
|
|
||||||
|
DWORD lock_service_database(void);
|
||||||
|
void unlock_service_database(void);
|
||||||
|
|
||||||
void lock_services(void);
|
void lock_services(void);
|
||||||
void unlock_services(void);
|
void unlock_services(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue