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)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[6];
UNICODE_STRING ServiceName;
PSERVICE Service = NULL;
NTSTATUS Status;
DPRINT("Service: '%wZ'\n", ServiceName);
DPRINT("Service: '%S'\n", lpServiceName);
/* 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
ScmCreateServiceDataBase(VOID)
{

View file

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

View file

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