if ((dwError == ERROR_SUCCESS) && (pcbBytesNeeded))
dwError = ERROR_DEPENDENT_SERVICES_RUNNING;
+ if (dwError == ERROR_SUCCESS &&
+ dwControl == SERVICE_CONTROL_STOP &&
+ lpServiceStatus->dwCurrentState == SERVICE_STOPPED)
+ {
+ lpService->ProcessId = 0; /* FIXME */
+ lpService->ThreadId = 0;
+ }
+
/* Return service status information */
RtlCopyMemory(lpServiceStatus,
&lpService->Status,
(wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
if (dwError != ERROR_SUCCESS)
goto done;
- /* FIXME: Update lpService->lpServiceGroup */
+
+ dwError = ScmSetServiceGroup(lpService,
+ lpLoadOrderGroup);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
}
if (lpdwTagId != NULL)
SC_HANDLE hServiceHandle = NULL;
LPWSTR lpImagePath = NULL;
HKEY hServiceKey = NULL;
+ LPWSTR lpObjectName;
DPRINT("RCreateServiceW() called\n");
DPRINT("lpServiceName = %S\n", lpServiceName);
goto done;
}
- /* If a non driver and NULL for lpServiceName, write ObjectName as LocalSystem */
- if ((dwServiceType & SERVICE_WIN32) && (!lpServiceName))
+ /* Write service start name */
+ if (dwServiceType & SERVICE_WIN32)
{
+ lpObjectName = (lpServiceStartName != NULL) ? (LPWSTR)lpServiceStartName : L"LocalSystem";
dwError = RegSetValueExW(hServiceKey,
L"ObjectName",
0,
REG_SZ,
- (LPBYTE)L"LocalSystem",
- 24);
+ (LPBYTE)lpObjectName,
+ (wcslen(lpObjectName) + 1) * sizeof(WCHAR));
if (dwError != ERROR_SUCCESS)
goto done;
}
return ERROR_ACCESS_DENIED;
}
- if (lpResumeHandle) dwLastResumeCount = *lpResumeHandle;
+ if (lpResumeHandle)
+ dwLastResumeCount = *lpResumeHandle;
/* FIXME: Lock the service list shared */
DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
- if (lpResumeHandle) *lpResumeHandle = dwLastResumeCount;
+ if (lpResumeHandle)
+ *lpResumeHandle = dwLastResumeCount;
+
*lpServicesReturned = dwServiceCount;
*pcbBytesNeeded = dwRequiredSize;
HKEY hServiceKey = NULL;
LPWSTR lpImagePath = NULL;
LPWSTR lpServiceStartName = NULL;
+ LPWSTR lpDependencies = NULL;
+ DWORD dwDependenciesLength = 0;
DWORD dwRequiredSize;
LPQUERY_SERVICE_CONFIGW lpConfig = NULL;
WCHAR lpEmptyString[] = {0,0};
if (dwError != ERROR_SUCCESS)
goto Done;
+ /* Read the image path */
dwError = ScmReadString(hServiceKey,
L"ImagePath",
&lpImagePath);
if (dwError != ERROR_SUCCESS)
goto Done;
+ /* Read the service start name */
ScmReadString(hServiceKey,
L"ObjectName",
&lpServiceStartName);
+ /* Read the dependencies */
+ ScmReadDependencies(hServiceKey,
+ &lpDependencies,
+ &dwDependenciesLength);
+
dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
if (lpImagePath != NULL)
else
dwRequiredSize += 2 * sizeof(WCHAR);
- /* FIXME: Add Dependencies length*/
+ if (lpDependencies != NULL)
+ dwRequiredSize += dwDependenciesLength * sizeof(WCHAR);
+ else
+ dwRequiredSize += 2 * sizeof(WCHAR);
if (lpServiceStartName != NULL)
dwRequiredSize += ((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR));
lpStr = (LPWSTR)(lpConfig + 1);
+ /* Append the image path */
if (lpImagePath != NULL)
{
wcscpy(lpStr, lpImagePath);
lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
lpStr += (wcslen(lpStr) + 1);
+ /* Append the group name */
if (lpService->lpGroup != NULL)
{
wcscpy(lpStr, lpService->lpGroup->lpGroupName);
lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
lpStr += (wcslen(lpStr) + 1);
- /* FIXME: Append Dependencies */
- wcscpy(lpStr, lpEmptyString);
+ /* Append Dependencies */
+ if (lpDependencies != NULL)
+ {
+ memcpy(lpStr,
+ lpDependencies,
+ dwDependenciesLength * sizeof(WCHAR));
+ }
+ else
+ {
+ wcscpy(lpStr, lpEmptyString);
+ }
- lpStr += (wcslen(lpStr) + 1);
lpConfig->lpDependencies = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ if (lpDependencies != NULL)
+ lpStr += dwDependenciesLength * sizeof(WCHAR);
+ else
+ lpStr += (wcslen(lpStr) + 1);
+ /* Append the service start name */
if (lpServiceStartName != NULL)
{
wcscpy(lpStr, lpServiceStartName);
lpConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
lpStr += (wcslen(lpStr) + 1);
+ /* Append the display name */
if (lpService->lpDisplayName != NULL)
{
wcscpy(lpStr, lpService->lpDisplayName);
if (lpServiceStartName != NULL)
HeapFree(GetProcessHeap(), 0, lpServiceStartName);
+ if (lpDependencies != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependencies);
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
{
lpBinaryPathNameW=HeapAlloc(GetProcessHeap(),0, (strlen(lpBinaryPathName)+1) * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, wcslen(lpBinaryPathNameW)+1);
+ MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, strlen(lpBinaryPathName)+1);
dwError = RegSetValueExW(hServiceKey,
L"ImagePath",
0,
{
lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(),
0,
- (strlen(lpLoadOrderGroup)+1) * sizeof(WCHAR));
+ (strlen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
if (lpLoadOrderGroupW == NULL)
{
dwError = ERROR_NOT_ENOUGH_MEMORY;
lpLoadOrderGroup,
-1,
lpLoadOrderGroupW,
- wcslen(lpLoadOrderGroupW) + 1);
+ strlen(lpLoadOrderGroup) + 1);
dwError = RegSetValueExW(hServiceKey,
L"Group",
(LPBYTE)lpLoadOrderGroupW,
(wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR));
if (dwError != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
goto done;
+ }
- /* FIXME: Update lpService->lpServiceGroup */
+ dwError = ScmSetServiceGroup(lpService,
+ lpLoadOrderGroupW);
HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
+
+ if (dwError != ERROR_SUCCESS)
+ goto done;
}
if (lpdwTagId != NULL)
{
lpDependenciesW = HeapAlloc(GetProcessHeap(),
0,
- (strlen(lpDependencies)+1) * sizeof(WCHAR));
+ (strlen(lpDependencies) + 1) * sizeof(WCHAR));
if (lpDependenciesW == NULL)
{
dwError = ERROR_NOT_ENOUGH_MEMORY;
lpDependencies,
dwDependSize,
lpDependenciesW,
- wcslen(lpDependenciesW)+1);
+ strlen(lpDependencies) + 1);
dwError = ScmWriteDependencies(hServiceKey,
(LPWSTR)lpDependenciesW,
DWORD dwPwSize,
LPSC_RPC_HANDLE lpServiceHandle)
{
- UNIMPLEMENTED;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ DWORD dwError = ERROR_SUCCESS;
+ LPWSTR lpServiceNameW = NULL;
+ LPWSTR lpDisplayNameW = NULL;
+ LPWSTR lpBinaryPathNameW = NULL;
+ LPWSTR lpLoadOrderGroupW = NULL;
+ LPWSTR lpDependenciesW = NULL;
+ LPWSTR lpServiceStartNameW = NULL;
+ DWORD dwDependenciesLength = 0;
+ DWORD dwLength;
+ int len;
+ LPSTR lpStr;
+
+ if (lpServiceName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
+ lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpServiceNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
+ }
+
+ if (lpDisplayName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
+ lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpDisplayNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
+ }
+
+ if (lpBinaryPathName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
+ lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpBinaryPathNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
+ }
+
+ if (lpLoadOrderGroup)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
+ lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpLoadOrderGroupW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
+ }
+
+ if (lpDependencies)
+ {
+ lpStr = (LPSTR)lpDependencies;
+ while (*lpStr)
+ {
+ dwLength = strlen(lpStr) + 1;
+ dwDependenciesLength += dwLength;
+ lpStr = lpStr + dwLength;
+ }
+ dwDependenciesLength++;
+
+ lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
+ if (!lpDependenciesW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
+ }
+
+ if (lpServiceStartName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
+ lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpServiceStartNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
+ }
+
+ dwError = RCreateServiceW(hSCManager,
+ lpServiceNameW,
+ lpDisplayNameW,
+ dwDesiredAccess,
+ dwServiceType,
+ dwStartType,
+ dwErrorControl,
+ lpBinaryPathNameW,
+ lpLoadOrderGroupW,
+ lpdwTagId,
+ (LPBYTE)lpDependenciesW,
+ dwDependenciesLength,
+ lpServiceStartNameW,
+ lpPassword,
+ dwPwSize,
+ lpServiceHandle);
+
+cleanup:
+ if (lpServiceNameW !=NULL)
+ HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+
+ if (lpDisplayNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
+
+ if (lpBinaryPathNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
+
+ if (lpLoadOrderGroupW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
+
+ if (lpDependenciesW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependenciesW);
+
+ if (lpServiceStartNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
+
+ return dwError;
}
KEY_READ,
&hServicesKey);
- if (dwError != ERROR_SUCCESS) return dwError;
+ if (dwError != ERROR_SUCCESS)
+ return dwError;
/* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for
both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded
}
}
- dwError = REnumServicesStatusW(//BindingHandle,
- hSCManager,
+ dwError = REnumServicesStatusW(hSCManager,
dwServiceType,
dwServiceState,
(LPBYTE)lpStatusPtrW,
lpResumeHandle);
/* if no services were returned then we are Done */
- if (*lpServicesReturned == 0) goto Done;
+ if (*lpServicesReturned == 0)
+ goto Done;
lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
}
Done:;
- if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
+ if (lpStatusPtrW)
+ HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
RtlCreateUnicodeStringFromAsciiz(&DatabaseName,
lpDatabaseName);
- dwError = ROpenSCManagerW(//BindingHandle,
- lpMachineName ? MachineName.Buffer : NULL,
+ dwError = ROpenSCManagerW(lpMachineName ? MachineName.Buffer : NULL,
lpDatabaseName ? DatabaseName.Buffer : NULL,
dwDesiredAccess,
lpScHandle);
RtlCreateUnicodeStringFromAsciiz(&ServiceName,
lpServiceName);
- dwError = ROpenServiceW(//BindingHandle,
- hSCManager,
+ dwError = ROpenServiceW(hSCManager,
lpServiceName ? ServiceName.Buffer : NULL,
dwDesiredAccess,
lpServiceHandle);
HKEY hServiceKey = NULL;
LPWSTR lpImagePath = NULL;
LPWSTR lpServiceStartName = NULL;
+ LPWSTR lpDependencies = NULL;
+ DWORD dwDependenciesLength = 0;
DWORD dwRequiredSize;
LPQUERY_SERVICE_CONFIGA lpConfig = NULL;
CHAR lpEmptyString[]={0,0};
if (dwError != ERROR_SUCCESS)
goto Done;
+ /* Read the image path */
dwError = ScmReadString(hServiceKey,
L"ImagePath",
&lpImagePath);
if (dwError != ERROR_SUCCESS)
goto Done;
+ /* Read the service start name */
ScmReadString(hServiceKey,
L"ObjectName",
&lpServiceStartName);
+ /* Read the dependencies */
+ ScmReadDependencies(hServiceKey,
+ &lpDependencies,
+ &dwDependenciesLength);
+
dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
if (lpImagePath != NULL)
else
dwRequiredSize += 2;
- /* FIXME: Add Dependencies length*/
- dwRequiredSize += 2;
+ /* Add Dependencies length */
+ if (lpDependencies != NULL)
+ dwRequiredSize += dwDependenciesLength;
+ else
+ dwRequiredSize += 2;
if (lpServiceStartName != NULL)
dwRequiredSize += wcslen(lpServiceStartName) + 1;
lpImagePath,
-1,
lpStr,
- wcslen(lpImagePath)+1,
+ wcslen(lpImagePath) + 1,
0,
0);
}
lpService->lpGroup->lpGroupName,
-1,
lpStr,
- wcslen(lpService->lpGroup->lpGroupName)+1,
+ wcslen(lpService->lpGroup->lpGroupName) + 1,
0,
0);
}
lpConfig->lpLoadOrderGroup = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
lpStr += (strlen(lpStr) + 1);
- /* FIXME: Append Dependencies */
- strcpy(lpStr, lpEmptyString);
+ /* Append Dependencies */
+ if (lpDependencies)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpDependencies,
+ dwDependenciesLength,
+ lpStr,
+ dwDependenciesLength,
+ 0,
+ 0);
+ }
+ else
+ {
+ strcpy(lpStr, lpEmptyString);
+ }
lpConfig->lpDependencies = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
- lpStr += (strlen(lpStr) + 1);
+ if (lpDependencies)
+ lpStr += dwDependenciesLength;
+ else
+ lpStr += (strlen(lpStr) + 1);
if (lpServiceStartName)
{
lpServiceStartName,
-1,
lpStr,
- wcslen(lpServiceStartName)+1,
+ wcslen(lpServiceStartName) + 1,
0,
0);
}
lpService->lpDisplayName,
-1,
lpStr,
- wcslen(lpService->lpDisplayName)+1,
+ wcslen(lpService->lpDisplayName) + 1,
0,
0);
}
if (lpServiceStartName != NULL)
HeapFree(GetProcessHeap(), 0, lpServiceStartName);
+ if (lpDependencies != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependencies);
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
LPWSTR lpDescriptionW = NULL;
LPSTR lpDescription = NULL;
- DPRINT1("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
+ DPRINT1("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",
+ hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
if (!lpBuffer)
return ERROR_INVALID_ADDRESS;
if (dwError != ERROR_SUCCESS)
goto done;
- if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
+ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
{
LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer;
LPSTR lpStr;
if (dwError != ERROR_SUCCESS)
goto done;
- if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
+ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
{
LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)lpBuffer;
LPWSTR lpStr;
wcscpy(lpStr, lpDescription);
lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
}
- else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
+ else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
{
LPWSTR lpStr;
LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
DPRINT1("Failed to allocate buffer!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
+
MultiByteToWideChar(CP_ACP,
0,
pszGroupName,
pszGroupNameW);
/* if no services were returned then we are Done */
- if (*lpServicesReturned == 0) goto Done;
+ if (*lpServicesReturned == 0)
+ goto Done;
lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
}
Done:;
- if (pszGroupNameW) HeapFree(GetProcessHeap(), 0, pszGroupNameW);
+ if (pszGroupNameW)
+ HeapFree(GetProcessHeap(), 0, pszGroupNameW);
- if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
+ if (lpStatusPtrW)
+ HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
- if (lpResumeIndex) *lpResumeIndex = dwLastResumeCount;
+ if (lpResumeIndex)
+ *lpResumeIndex = dwLastResumeCount;
+
*lpServicesReturned = dwServiceCount;
*pcbBytesNeeded = dwRequiredSize;
if (dwError == 0)
{
*pcbBytesNeeded = 0;
- if (lpResumeIndex) *lpResumeIndex = 0;
+ if (lpResumeIndex)
+ *lpResumeIndex = 0;
}
Done:;