- Implement GetServiceDisplayNameW (untested).

- SCM must store a services display name.
- Some SCM-Calls must fail while the SCM is shutting down.

svn path=/trunk/; revision=18880
This commit is contained in:
Eric Kohl 2005-10-30 13:13:53 +00:00
parent b6bfd30b73
commit 9be78e0815
6 changed files with 244 additions and 24 deletions

View file

@ -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 @@ cpp_quote("#endif")
[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,

View file

@ -566,19 +566,33 @@ GetServiceDisplayNameA(
/**********************************************************************
* 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 @@ GetServiceKeyNameA(
*
* @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;

View file

@ -84,6 +84,35 @@ ScmGetServiceEntryByName(LPWSTR lpServiceName)
}
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 @@ CreateServiceListEntry(LPWSTR lpServiceName)
/* Copy service name */
wcscpy(Service->szServiceName, lpServiceName);
Service->lpServiceName = Service->szServiceName;
Service->lpDisplayName = Service->lpServiceName;
/* Get service data */
RtlZeroMemory(&QueryTable,
@ -284,6 +314,7 @@ ScmCreateNewServiceRecord(LPWSTR lpServiceName,
/* Copy service name */
wcscpy(lpService->szServiceName, lpServiceName);
lpService->lpServiceName = lpService->szServiceName;
lpService->lpDisplayName = lpService->lpServiceName;
/* Append service entry */
InsertTailList(&ServiceListHead,

View file

@ -283,6 +283,9 @@ ScmrControlService(handle_t BindingHandle,
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 @@ ScmrDeleteService(handle_t BindingHandle,
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 @@ ScmrQueryServiceStatus(handle_t BindingHandle,
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 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
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 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
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 @@ ScmrCreateServiceW(handle_t BindingHandle,
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 @@ ScmrCreateServiceW(handle_t BindingHandle,
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 @@ done:;
}
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 @@ ScmrOpenSCManagerW(handle_t BindingHandle,
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 @@ ScmrOpenServiceW(handle_t BindingHandle,
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,6 +957,55 @@ ScmrOpenServiceW(handle_t BindingHandle,
}
/* 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

View file

@ -40,6 +40,8 @@ int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
#define PIPE_BUFSIZE 1024
#define PIPE_TIMEOUT 1000
BOOL ScmShutdown = FALSE;
/* FUNCTIONS *****************************************************************/
@ -286,6 +288,23 @@ AcquireLoadDriverPrivilege(VOID)
}
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 @@ WinMain(HINSTANCE hInstance,
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();

View file

@ -13,6 +13,7 @@ typedef struct _SERVICE
{
LIST_ENTRY ServiceListEntry;
LPWSTR lpServiceName;
LPWSTR lpDisplayName;
UNICODE_STRING ServiceGroup;
SERVICE_STATUS Status;
@ -32,6 +33,13 @@ typedef struct _SERVICE
} SERVICE, *PSERVICE;
/* VARIABLES ***************************************************************/
extern BOOL ScmShutdown;
/* FUNCTIONS ***************************************************************/
/* config.c */
DWORD ScmWriteDependencies(HKEY hServiceKey,
@ -46,6 +54,7 @@ VOID ScmGetBootAndSystemDriverState(VOID);
VOID ScmAutoStartServices(VOID);
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
PSERVICE ScmGetServiceEntryByDisplayName(LPWSTR lpDisplayName);
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
PSERVICE *lpServiceRecord);
DWORD ScmMarkServiceForDelete(PSERVICE pService);