- Implement GetServiceDisplayNameW (untested). - SCM must store a services display name. - Some SCM-Calls must fail while the SCM is shutting down. Modified: trunk/reactos/include/idl/svcctl.idl Modified: trunk/reactos/lib/advapi32/service/scm.c Modified: trunk/reactos/subsys/system/services/database.c Modified: trunk/reactos/subsys/system/services/rpcserver.c Modified: trunk/reactos/subsys/system/services/services.c Modified: trunk/reactos/subsys/system/services/services.h _____
Modified: trunk/reactos/include/idl/svcctl.idl --- trunk/reactos/include/idl/svcctl.idl 2005-10-30 12:53:32 UTC (rev 18879) +++ trunk/reactos/include/idl/svcctl.idl 2005-10-30 13:13:53 UTC (rev 18880) @@ -9,7 +9,9 @@
#define BOOL unsigned long #define SC_HANDLE unsigned int #define SC_LOCK unsigned int +#define LPSTR char* #define LPCSTR char* +#define LPWSTR wchar_t* #define LPCWSTR wchar_t* #define LPDWORD unsigned long*
@@ -127,6 +129,14 @@ [out] SC_HANDLE *hScm);
+ /* Function 20 */ + DWORD ScmrGetServiceDisplayNameW([in] handle_t BindingHandle, + [in] SC_HANDLE hSCManager, + [in, string, ref] LPCWSTR lpServiceName, + [out, size_is(*lpcchBuffer), unique] LPWSTR lpDisplayName, + [in, out, ref] LPDWORD lpcchBuffer); + + /* Function 27 */ DWORD ScmrOpenSCManagerA([in] handle_t BindingHandle, [in, string, unique] LPCSTR lpMachineName, _____
Modified: trunk/reactos/lib/advapi32/service/scm.c --- trunk/reactos/lib/advapi32/service/scm.c 2005-10-30 12:53:32 UTC (rev 18879) +++ trunk/reactos/lib/advapi32/service/scm.c 2005-10-30 13:13:53 UTC (rev 18880) @@ -566,19 +566,33 @@
/********************************************************************** * GetServiceDisplayNameW * - * @unimplemented + * @implemented */ -BOOL -STDCALL -GetServiceDisplayNameW( - SC_HANDLE hSCManager, - LPCWSTR lpServiceName, - LPWSTR lpDisplayName, - LPDWORD lpcchBuffer) +BOOL STDCALL +GetServiceDisplayNameW(SC_HANDLE hSCManager, + LPCWSTR lpServiceName, + LPWSTR lpDisplayName, + LPDWORD lpcchBuffer) { - DPRINT1("GetServiceDisplayNameW is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + + DPRINT("GetServiceDisplayNameW() called\n"); + + HandleBind(); + + dwError = ScmrGetServiceDisplayNameW(BindingHandle, + (unsigned int)hSCManager, + (LPWSTR)lpServiceName, + lpDisplayName, + lpcchBuffer); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; }
@@ -606,14 +620,33 @@ * * @unimplemented */ -BOOL -STDCALL -GetServiceKeyNameW( - SC_HANDLE hSCManager, - LPCWSTR lpDisplayName, - LPWSTR lpServiceName, - LPDWORD lpcchBuffer) +BOOL STDCALL +GetServiceKeyNameW(SC_HANDLE hSCManager, + LPCWSTR lpDisplayName, + LPWSTR lpServiceName, + LPDWORD lpcchBuffer) { +#if 0 + DWORD dwError; + + DPRINT("GetServiceKeyNameW() called\n"); + + HandleBind(); + + dwError = ScmrGetServiceKeyNameW(BindingHandle, + (unsigned int)hSCManager, + (LPWSTR)lpDisplayName, + lpServiceName, + lpcchBuffer); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; +#endif DPRINT1("GetServiceKeyNameW is unimplemented\n"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; _____
Modified: trunk/reactos/subsys/system/services/database.c --- trunk/reactos/subsys/system/services/database.c 2005-10-30 12:53:32 UTC (rev 18879) +++ trunk/reactos/subsys/system/services/database.c 2005-10-30 13:13:53 UTC (rev 18880) @@ -84,6 +84,35 @@
}
+PSERVICE +ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName) +{ + PLIST_ENTRY ServiceEntry; + PSERVICE CurrentService; + + DPRINT("ScmGetServiceEntryByDisplayName() called\n"); + + ServiceEntry = ServiceListHead.Flink; + while (ServiceEntry != &ServiceListHead) + { + CurrentService = CONTAINING_RECORD(ServiceEntry, + SERVICE, + ServiceListEntry); + if (_wcsicmp(CurrentService->lpDisplayName, lpDisplayName) == 0) + { + DPRINT("Found service: '%S'\n", CurrentService->lpDisplayName); + return CurrentService; + } + + ServiceEntry = ServiceEntry->Flink; + } + + DPRINT("Couldn't find a matching service\n"); + + return NULL; +} + + static NTSTATUS STDCALL CreateGroupOrderListRoutine(PWSTR ValueName, ULONG ValueType, @@ -204,6 +233,7 @@ /* Copy service name */ wcscpy(Service->szServiceName, lpServiceName); Service->lpServiceName = Service->szServiceName; + Service->lpDisplayName = Service->lpServiceName;
/* Get service data */ RtlZeroMemory(&QueryTable, @@ -284,6 +314,7 @@ /* Copy service name */ wcscpy(lpService->szServiceName, lpServiceName); lpService->lpServiceName = lpService->szServiceName; + lpService->lpDisplayName = lpService->lpServiceName;
/* Append service entry */ InsertTailList(&ServiceListHead, _____
Modified: trunk/reactos/subsys/system/services/rpcserver.c --- trunk/reactos/subsys/system/services/rpcserver.c 2005-10-30 12:53:32 UTC (rev 18879) +++ trunk/reactos/subsys/system/services/rpcserver.c 2005-10-30 13:13:53 UTC (rev 18880) @@ -283,6 +283,9 @@
DPRINT1("ScmrControlService() called\n");
+ if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + hSvc = (PSERVICE_HANDLE)hService; if (hSvc->Handle.Tag != SERVICE_TAG) { @@ -325,6 +328,9 @@
DPRINT1("ScmrDeleteService() called\n");
+ if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + hSvc = (PSERVICE_HANDLE)hService; if (hSvc->Handle.Tag != SERVICE_TAG) return ERROR_INVALID_HANDLE; @@ -409,6 +415,9 @@
DPRINT("ScmrQueryServiceStatus() called\n");
+ if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + hSvc = (PSERVICE_HANDLE)hService; if (hSvc->Handle.Tag != SERVICE_TAG) { @@ -488,6 +497,10 @@ unsigned long dwPasswordLength, wchar_t *lpDisplayName) { + DWORD dwError = ERROR_SUCCESS; + PSERVICE_HANDLE hSvc; + PSERVICE lpService = NULL; + DPRINT1("ScmrChangeServiceConfigW() called\n"); DPRINT1("dwServiceType = %lu\n", dwServiceType); DPRINT1("dwStartType = %lu\n", dwStartType); @@ -496,7 +509,35 @@ DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup); DPRINT1("lpDisplayName = %S\n", lpDisplayName);
- return ERROR_SUCCESS; + if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + + hSvc = (PSERVICE_HANDLE)hService; + if (hSvc->Handle.Tag != SERVICE_TAG) + { + DPRINT1("Invalid handle tag!\n"); + return ERROR_INVALID_HANDLE; + } + + if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess, + SERVICE_CHANGE_CONFIG)) + { + DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess); + return ERROR_ACCESS_DENIED; + } + + lpService = hSvc->ServiceEntry; + if (lpService == NULL) + { + DPRINT1("lpService == NULL!\n"); + return ERROR_INVALID_HANDLE; + } + + /* FIXME: ... */ + + DPRINT1("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError); + + return dwError; }
@@ -580,6 +621,9 @@ DPRINT1("lpBinaryPathName = %S\n", lpBinaryPathName); DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
+ if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + hManager = (PMANAGER_HANDLE)hSCManager; if (hManager->Handle.Tag != MANAGER_TAG) { @@ -625,6 +669,23 @@ lpService->dwStartType = dwStartType; lpService->dwErrorControl = dwErrorControl;
+ /* Fill the display name */ + if (lpDisplayName != NULL && + *lpDisplayName != 0 && + wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0) + { + lpService->lpDisplayName = HeapAlloc(GetProcessHeap, 0, + (wcslen(lpDisplayName) + 1) * sizeof(WCHAR)); + if (lpService->lpDisplayName == NULL) + { + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + wcscpy(lpService->lpDisplayName, lpDisplayName); + } + + + /* FIXME: set lpLoadOrderGroup, lpDependencies etc. */
@@ -756,6 +817,10 @@ } else { + /* Release the display name buffer */ + if (lpService->lpServiceName != lpService->lpDisplayName) + HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName); + if (hServiceHandle != NULL) { /* Remove the service handle */ @@ -795,6 +860,9 @@ DPRINT("lpDataBaseName: %S\n", lpDatabaseName); DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
+ if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + dwError = ScmCreateManagerHandle(lpDatabaseName, &hHandle); if (dwError != ERROR_SUCCESS) @@ -841,6 +909,9 @@ DPRINT("lpServiceName: %S\n", lpServiceName); DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
+ if (ScmShutdown) + return ERROR_SHUTDOWN_IN_PROGRESS; + hManager = (PMANAGER_HANDLE)hSCManager; if (hManager->Handle.Tag != MANAGER_TAG) { @@ -886,7 +957,56 @@ }
+/* Function 20 */ +unsigned long +ScmrGetServiceDisplayNameW(handle_t BindingHandle, + unsigned int hSCManager, + wchar_t *lpServiceName, + wchar_t *lpDisplayName, /* [out, unique] */ + unsigned long *lpcchBuffer) +{ +// PMANAGER_HANDLE hManager; + PSERVICE lpService; + DWORD dwLength; + DWORD dwError;
+ DPRINT1("ScmrGetServiceDisplayNameW() called\n"); + DPRINT1("hSCManager = %x\n", hSCManager); + DPRINT1("lpServiceName: %S\n", lpServiceName); + DPRINT1("lpDisplayName: %p\n", lpDisplayName); + 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 = ScmGetServiceEntryByName(lpServiceName); + if (lpService == NULL) + { + DPRINT1("Could not find a service!\n"); + return ERROR_SERVICE_DOES_NOT_EXIST; + } + + dwLength = wcslen(lpService->lpDisplayName); + + if (lpDisplayName != NULL && + *lpcchBuffer > dwLength) + { + wcscpy(lpDisplayName, lpService->lpDisplayName); + } + + dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; + + *lpcchBuffer = dwLength; + + return dwError; +} + + /* Function 27 */ unsigned long ScmrOpenSCManagerA(handle_t BindingHandle, _____
Modified: trunk/reactos/subsys/system/services/services.c --- trunk/reactos/subsys/system/services/services.c 2005-10-30 12:53:32 UTC (rev 18879) +++ trunk/reactos/subsys/system/services/services.c 2005-10-30 13:13:53 UTC (rev 18880) @@ -40,7 +40,9 @@
#define PIPE_BUFSIZE 1024 #define PIPE_TIMEOUT 1000
+BOOL ScmShutdown = FALSE;
+ /* FUNCTIONS *****************************************************************/
VOID @@ -286,6 +288,23 @@ }
+BOOL WINAPI +ShutdownHandlerRoutine(DWORD dwCtrlType) +{ + DPRINT1("ShutdownHandlerRoutine() called\n"); + + if (dwCtrlType == CTRL_SHUTDOWN_EVENT) + { + DPRINT1("Shutdown event received!\n"); + ScmShutdown = TRUE; + + /* FIXME: Shut all services down */ + } + + return TRUE; +} + + int STDCALL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -330,17 +349,15 @@ ScmStartRpcServer();
/* Register service process with CSRSS */ -// RegisterServicesProcess(GetCurrentProcessId()); + RegisterServicesProcess(GetCurrentProcessId());
DPRINT("SERVICES: Initialized.\n");
/* Signal start event */ SetEvent(hScmStartEvent);
-#if 0 - /* FIXME: register event handler (used for system shutdown) */ - SetConsoleCtrlHandler(...); -#endif + /* Register event handler (used for system shutdown) */ + SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
/* Start auto-start services */ ScmAutoStartServices(); _____
Modified: trunk/reactos/subsys/system/services/services.h --- trunk/reactos/subsys/system/services/services.h 2005-10-30 12:53:32 UTC (rev 18879) +++ trunk/reactos/subsys/system/services/services.h 2005-10-30 13:13:53 UTC (rev 18880) @@ -13,6 +13,7 @@
{ LIST_ENTRY ServiceListEntry; LPWSTR lpServiceName; + LPWSTR lpDisplayName; UNICODE_STRING ServiceGroup;
SERVICE_STATUS Status; @@ -32,6 +33,13 @@ } SERVICE, *PSERVICE;
+/* VARIABLES ***************************************************************/ + +extern BOOL ScmShutdown; + + +/* FUNCTIONS ***************************************************************/ + /* config.c */
DWORD ScmWriteDependencies(HKEY hServiceKey, @@ -46,6 +54,7 @@ VOID ScmAutoStartServices(VOID);
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName); +PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName); DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName, PSERVICE *lpServiceRecord); DWORD ScmMarkServiceForDelete(PSERVICE pService);