From: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- programs/services/rpc.c | 57 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 6fef374402d..99a25ed4a5a 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -59,6 +59,7 @@ typedef enum SC_HTYPE_DONT_CARE = 0, SC_HTYPE_MANAGER, SC_HTYPE_SERVICE, + SC_HTYPE_LOCK, SC_HTYPE_NOTIFY } SC_HANDLE_TYPE; @@ -92,6 +93,11 @@ struct sc_service_handle /* service handle */ struct sc_notify_handle *notify; }; +struct sc_lock_handle +{ + struct sc_handle hdr; +}; + static void sc_notify_retain(struct sc_notify_handle *notify) { InterlockedIncrement(¬ify->ref); @@ -265,6 +271,17 @@ static DWORD validate_notify_handle(SC_RPC_HANDLE handle, DWORD needed_access, s return err; } +static DWORD validate_lock_handle(SC_RPC_HANDLE handle, struct sc_lock_handle **lock) +{ + struct sc_handle *hdr = handle; + + if (hdr->type != SC_HTYPE_LOCK) + return ERROR_INVALID_SERVICE_LOCK; + + *lock = (struct sc_lock_handle *)hdr; + return ERROR_SUCCESS; +} + DWORD __cdecl svcctl_OpenSCManagerW( MACHINE_HANDLEW MachineName, /* Note: this parameter is ignored */ LPCWSTR DatabaseName, @@ -324,6 +341,12 @@ static void SC_RPC_HANDLE_destroy(SC_RPC_HANDLE handle) free(service); break; } + case SC_HTYPE_LOCK: + { + struct sc_lock_handle *lock = (struct sc_lock_handle *)hdr; + free(lock); + break; + } default: WINE_ERR("invalid handle type %d\n", hdr->type); RpcRaiseException(ERROR_INVALID_HANDLE); @@ -1408,19 +1431,41 @@ void __RPC_USER SC_RPC_LOCK_rundown(SC_RPC_LOCK hLock) { } -DWORD __cdecl svcctl_LockServiceDatabase(SC_RPC_HANDLE manager, SC_RPC_LOCK *lock) +DWORD __cdecl svcctl_LockServiceDatabase(SC_RPC_HANDLE hmngr, SC_RPC_LOCK *handle) { - TRACE("(%p, %p)\n", manager, lock); + DWORD err; + struct sc_manager_handle *manager; + struct sc_lock_handle *lock; + + TRACE("(%p, %p)\n", hmngr, handle); + + if ((err = validate_scm_handle(hmngr, SC_MANAGER_LOCK, &manager)) != ERROR_SUCCESS) + return err; + + if (!(lock = malloc(sizeof(*lock)))) + return ERROR_NOT_ENOUGH_SERVER_MEMORY; + + lock->hdr.type = SC_HTYPE_LOCK; + lock->hdr.access = 0; + + *handle = &lock->hdr; - *lock = (SC_RPC_LOCK)0xdeadbeef; return ERROR_SUCCESS; } -DWORD __cdecl svcctl_UnlockServiceDatabase(SC_RPC_LOCK *lock) +DWORD __cdecl svcctl_UnlockServiceDatabase(SC_RPC_LOCK *handle) { - TRACE("(&%p)\n", *lock); + DWORD err; + struct sc_lock_handle *lock; + + TRACE("(&%p)\n", *handle); + + if ((err = validate_lock_handle(*handle, &lock)) != ERROR_SUCCESS) + return err; + + SC_RPC_HANDLE_destroy(*handle); + *handle = NULL; - *lock = NULL; return ERROR_SUCCESS; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10150