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
--- 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,
--- 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;
--- 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,
--- 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,
--- 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();
--- 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);