diff --git a/reactos/include/idl/svcctl.idl b/reactos/include/idl/svcctl.idl index 105d2f019c8..bfdaa0f66ef 100644 --- a/reactos/include/idl/svcctl.idl +++ b/reactos/include/idl/svcctl.idl @@ -136,6 +136,13 @@ cpp_quote("#endif") [out, size_is(*lpcchBuffer), unique] LPWSTR lpDisplayName, [in, out, ref] LPDWORD lpcchBuffer); + /* Function 21 */ + DWORD ScmrGetServiceKeyNameW([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string, ref] LPCWSTR lpDisplayName, + [out, size_is(*lpcchBuffer), unique] LPWSTR lpServiceName, + [in, out, ref] LPDWORD lpcchBuffer); + /* Function 27 */ DWORD ScmrOpenSCManagerA([in] handle_t BindingHandle, diff --git a/reactos/lib/advapi32/service/scm.c b/reactos/lib/advapi32/service/scm.c index 5de26b7ba97..f429ef67daf 100644 --- a/reactos/lib/advapi32/service/scm.c +++ b/reactos/lib/advapi32/service/scm.c @@ -618,7 +618,7 @@ GetServiceKeyNameA( /********************************************************************** * GetServiceKeyNameW * - * @unimplemented + * @implemented */ BOOL STDCALL GetServiceKeyNameW(SC_HANDLE hSCManager, @@ -626,7 +626,6 @@ GetServiceKeyNameW(SC_HANDLE hSCManager, LPWSTR lpServiceName, LPDWORD lpcchBuffer) { -#if 0 DWORD dwError; DPRINT("GetServiceKeyNameW() called\n"); @@ -646,10 +645,6 @@ GetServiceKeyNameW(SC_HANDLE hSCManager, } return TRUE; -#endif - DPRINT1("GetServiceKeyNameW is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; } diff --git a/reactos/subsys/system/services/rpcserver.c b/reactos/subsys/system/services/rpcserver.c index 27b04060163..d7e0f79ef58 100644 --- a/reactos/subsys/system/services/rpcserver.c +++ b/reactos/subsys/system/services/rpcserver.c @@ -348,7 +348,15 @@ ScmrDeleteService(handle_t BindingHandle, /* FIXME: Acquire service database lock exclusively */ + if (lpService->bDeleted) + { + DPRINT1("The service has already been marked for delete!\n"); + return ERROR_SERVICE_MARKED_FOR_DELETE; + } + /* Mark service for delete */ + lpService->bDeleted = TRUE; + dwError = ScmMarkServiceForDelete(lpService); /* FIXME: Release service database lock */ @@ -533,8 +541,19 @@ ScmrChangeServiceConfigW(handle_t BiningHandle, return ERROR_INVALID_HANDLE; } + /* FIXME: Lock database exclusively */ + + if (lpService->bDeleted) + { + /* FIXME: Unlock database */ + DPRINT1("The service has already been marked for delete!\n"); + return ERROR_SERVICE_MARKED_FOR_DELETE; + } + /* FIXME: ... */ + /* FIXME: Unlock database */ + DPRINT1("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError); return dwError; @@ -1007,6 +1026,56 @@ ScmrGetServiceDisplayNameW(handle_t BindingHandle, } +/* Function 21 */ +unsigned long +ScmrGetServiceKeyNameW(handle_t BindingHandle, + unsigned int hSCManager, + wchar_t *lpDisplayName, + wchar_t *lpServiceName, /* [out, unique] */ + unsigned long *lpcchBuffer) +{ +// PMANAGER_HANDLE hManager; + PSERVICE lpService; + DWORD dwLength; + DWORD dwError; + + DPRINT1("ScmrGetServiceKeyNameW() called\n"); + DPRINT1("hSCManager = %x\n", hSCManager); + DPRINT1("lpDisplayName: %S\n", lpDisplayName); + DPRINT1("lpServiceName: %p\n", lpServiceName); + DPRINT1("*lpcchBuffer: %lu\n", *lpcchBuffer); + +// hManager = (PMANAGER_HANDLE)hSCManager; +// if (hManager->Handle.Tag != MANAGER_TAG) +// { +// DPRINT1("Invalid manager handle!\n"); +// return ERROR_INVALID_HANDLE; +// } + + /* Get service database entry */ + lpService = ScmGetServiceEntryByDisplayName(lpDisplayName); + if (lpService == NULL) + { + DPRINT1("Could not find a service!\n"); + return ERROR_SERVICE_DOES_NOT_EXIST; + } + + dwLength = wcslen(lpService->lpServiceName); + + if (lpServiceName != NULL && + *lpcchBuffer > dwLength) + { + wcscpy(lpServiceName, lpService->lpServiceName); + } + + dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; + + *lpcchBuffer = dwLength; + + return dwError; +} + + /* Function 27 */ unsigned long ScmrOpenSCManagerA(handle_t BindingHandle, diff --git a/reactos/subsys/system/services/services.h b/reactos/subsys/system/services/services.h index cb38b3f36bb..2e65d890274 100644 --- a/reactos/subsys/system/services/services.h +++ b/reactos/subsys/system/services/services.h @@ -15,6 +15,7 @@ typedef struct _SERVICE LPWSTR lpServiceName; LPWSTR lpDisplayName; UNICODE_STRING ServiceGroup; + BOOL bDeleted; SERVICE_STATUS Status; DWORD dwStartType;