Improvements to ScmrCreateServiceW:

- Allocate a service record for the new service.
- Fix registry value types and sizes.
- Fail if the new service already exists.

svn path=/trunk/; revision=18693
This commit is contained in:
Eric Kohl 2005-10-23 06:19:15 +00:00
parent 00fb63ba19
commit f86f34bda5
3 changed files with 101 additions and 22 deletions

View file

@ -186,11 +186,10 @@ static NTSTATUS STDCALL
CreateServiceListEntry(LPWSTR lpServiceName) CreateServiceListEntry(LPWSTR lpServiceName)
{ {
RTL_QUERY_REGISTRY_TABLE QueryTable[6]; RTL_QUERY_REGISTRY_TABLE QueryTable[6];
UNICODE_STRING ServiceName;
PSERVICE Service = NULL; PSERVICE Service = NULL;
NTSTATUS Status; NTSTATUS Status;
DPRINT("Service: '%wZ'\n", ServiceName); DPRINT("Service: '%S'\n", lpServiceName);
/* Allocate service entry */ /* Allocate service entry */
@ -265,6 +264,42 @@ CreateServiceListEntry(LPWSTR lpServiceName)
} }
DWORD
ScmCreateNewServiceRecord(LPWSTR lpServiceName,
PSERVICE *lpServiceRecord)
{
PSERVICE lpService = NULL;
DPRINT("Service: '%S'\n", lpServiceName);
/* Allocate service entry */
lpService = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(SERVICE) + ((wcslen(lpServiceName) + 1) * sizeof(WCHAR)));
if (lpService == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
*lpServiceRecord = lpService;
/* Copy service name */
wcscpy(lpService->szServiceName, lpServiceName);
lpService->lpServiceName = lpService->szServiceName;
/* Append service entry */
InsertTailList(&ServiceListHead,
&lpService->ServiceListEntry);
lpService->Status.dwCurrentState = SERVICE_STOPPED;
lpService->Status.dwControlsAccepted = 0;
lpService->Status.dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED;
lpService->Status.dwServiceSpecificExitCode = 0;
lpService->Status.dwCheckPoint = 0;
lpService->Status.dwWaitHint = 2000; /* 2 seconds */
return ERROR_SUCCESS;
}
NTSTATUS NTSTATUS
ScmCreateServiceDataBase(VOID) ScmCreateServiceDataBase(VOID)
{ {

View file

@ -493,9 +493,9 @@ ScmrChangeServiceConfigW([in] handle_t BiningHandle,
#endif #endif
#if 0
static DWORD static DWORD
CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey) CreateServiceKey(LPWSTR lpServiceName,
PHKEY phKey)
{ {
HKEY hServicesKey = NULL; HKEY hServicesKey = NULL;
DWORD dwDisposition; DWORD dwDisposition;
@ -520,6 +520,7 @@ CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey)
NULL, NULL,
phKey, phKey,
&dwDisposition); &dwDisposition);
#if 0
if ((dwError == ERROR_SUCCESS) && if ((dwError == ERROR_SUCCESS) &&
(dwDisposition == REG_OPENED_EXISTING_KEY)) (dwDisposition == REG_OPENED_EXISTING_KEY))
{ {
@ -527,12 +528,12 @@ CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey)
*phKey = NULL; *phKey = NULL;
dwError = ERROR_SERVICE_EXISTS; dwError = ERROR_SERVICE_EXISTS;
} }
#endif
RegCloseKey(hServicesKey); RegCloseKey(hServicesKey);
return dwError; return dwError;
} }
#endif
/* Function 12 */ /* Function 12 */
@ -557,10 +558,10 @@ ScmrCreateServiceW(handle_t BindingHandle,
{ {
PMANAGER_HANDLE hManager; PMANAGER_HANDLE hManager;
DWORD dwError = ERROR_SUCCESS; DWORD dwError = ERROR_SUCCESS;
#if 0 PSERVICE lpService = NULL;
HKEY hServiceKey = NULL; SC_HANDLE hServiceHandle = NULL;
LPWSTR lpImagePath = NULL; LPWSTR lpImagePath = NULL;
#endif HKEY hServiceKey = NULL;
DPRINT1("ScmrCreateServiceW() called\n"); DPRINT1("ScmrCreateServiceW() called\n");
DPRINT1("lpServiceName = %S\n", lpServiceName); DPRINT1("lpServiceName = %S\n", lpServiceName);
@ -588,15 +589,16 @@ ScmrCreateServiceW(handle_t BindingHandle,
return ERROR_ACCESS_DENIED; return ERROR_ACCESS_DENIED;
} }
/* FIXME: Fail if the service already exists! */ /* Fail if the service already exists! */
if (ScmGetServiceEntryByName(lpServiceName) != NULL)
return ERROR_SERVICE_EXISTS;
#if 0
if (dwServiceType & SERVICE_DRIVER) if (dwServiceType & SERVICE_DRIVER)
{ {
/* FIXME: Adjust the image path */ /* FIXME: Adjust the image path */
lpImagePath = HeapAlloc(GetProcessHeap(), lpImagePath = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
wcslen(lpBinaryPathName) + sizeof(WCHAR)); (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
if (lpImagePath == NULL) if (lpImagePath == NULL)
{ {
dwError = ERROR_NOT_ENOUGH_MEMORY; dwError = ERROR_NOT_ENOUGH_MEMORY;
@ -605,14 +607,18 @@ ScmrCreateServiceW(handle_t BindingHandle,
wcscpy(lpImagePath, lpBinaryPathName); wcscpy(lpImagePath, lpBinaryPathName);
} }
/* FIXME: Allocate and fill a service entry */ /* Allocate a new service entry */
// dwError = CreateNewServiceListEntry(lpServiceName, dwError = ScmCreateNewServiceRecord(lpServiceName,
// &lpServiceEntry) &lpService);
if (dwError != ERROR_SUCCESS)
goto done;
// if (lpdwTagId != NULL) /* Fill the new service entry */
// *lpdwTagId = 0; lpService->Status.dwServiceType = dwServiceType;
lpService->dwStartType = dwStartType;
lpService->dwErrorControl = dwErrorControl;
// *hService = 0; /* FIXME: set lpLoadOrderGroup, lpDependencies etc. */
/* Write service data to the registry */ /* Write service data to the registry */
@ -621,6 +627,7 @@ ScmrCreateServiceW(handle_t BindingHandle,
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
goto done; goto done;
/* Set the display name */
if (lpDisplayName != NULL && *lpDisplayName != 0) if (lpDisplayName != NULL && *lpDisplayName != 0)
{ {
RegSetValueExW(hServiceKey, RegSetValueExW(hServiceKey,
@ -667,7 +674,7 @@ ScmrCreateServiceW(handle_t BindingHandle,
dwError = RegSetValueExW(hServiceKey, dwError = RegSetValueExW(hServiceKey,
L"ImagePath", L"ImagePath",
0, 0,
REG_SZ, REG_EXPAND_SZ,
(LPBYTE)lpBinaryPathName, (LPBYTE)lpBinaryPathName,
(wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)); (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
@ -675,13 +682,12 @@ ScmrCreateServiceW(handle_t BindingHandle,
} }
else if (dwServiceType & SERVICE_DRIVER) else if (dwServiceType & SERVICE_DRIVER)
{ {
/* FIXME: Adjust the path name */
dwError = RegSetValueExW(hServiceKey, dwError = RegSetValueExW(hServiceKey,
L"ImagePath", L"ImagePath",
0, 0,
REG_SZ, REG_EXPAND_SZ,
(LPBYTE)lpImagePath, (LPBYTE)lpImagePath,
(wcslen(lpImagePath) + 1) *sizeof(WCHAR)); (wcslen(lpImagePath) + 1) *sizeof(WCHAR));
if (dwError != ERROR_SUCCESS) if (dwError != ERROR_SUCCESS)
goto done; goto done;
} }
@ -699,6 +705,11 @@ ScmrCreateServiceW(handle_t BindingHandle,
goto done; goto done;
} }
if (lpdwTagId != NULL)
{
/* FIXME: Write tag */
}
if (lpDependencies != NULL && *lpDependencies != 0) if (lpDependencies != NULL && *lpDependencies != 0)
{ {
/* FIXME: Write dependencies */ /* FIXME: Write dependencies */
@ -709,13 +720,44 @@ ScmrCreateServiceW(handle_t BindingHandle,
/* FIXME: Write password */ /* FIXME: Write password */
} }
dwError = ScmCreateServiceHandle(lpService,
&hServiceHandle);
if (dwError != ERROR_SUCCESS)
goto done;
dwError = ScmCheckAccess(hServiceHandle,
dwDesiredAccess);
if (dwError != ERROR_SUCCESS)
goto done;
done:; done:;
if (hServiceKey != NULL) if (hServiceKey != NULL)
RegCloseKey(hServiceKey); RegCloseKey(hServiceKey);
if (dwError == ERROR_SUCCESS)
{
DPRINT1("hService %lx\n", hServiceHandle);
*hService = (unsigned int)hServiceHandle;
if (lpdwTagId != NULL)
*lpdwTagId = 0; /* FIXME */
}
else
{
if (hServiceHandle != NULL)
{
/* Remove the service handle */
HeapFree(GetProcessHeap(), 0, hServiceHandle);
}
if (lpService != NULL)
{
/* FIXME: remove the service entry */
}
}
if (lpImagePath != NULL) if (lpImagePath != NULL)
HeapFree(GetProcessHeap(), 0, lpImagePath); HeapFree(GetProcessHeap(), 0, lpImagePath);
#endif
DPRINT1("ScmrCreateServiceW() done (Error %lu)\n", dwError); DPRINT1("ScmrCreateServiceW() done (Error %lu)\n", dwError);

View file

@ -44,6 +44,8 @@ VOID ScmGetBootAndSystemDriverState(VOID);
VOID ScmAutoStartServices(VOID); VOID ScmAutoStartServices(VOID);
PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName); PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName);
DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName,
PSERVICE *lpServiceRecord);
DWORD ScmMarkServiceForDelete(PSERVICE pService); DWORD ScmMarkServiceForDelete(PSERVICE pService);