typedef struct _SCMGR_HANDLE
{
DWORD Tag;
- DWORD RefCount;
DWORD DesiredAccess;
} SCMGR_HANDLE;
typedef struct _MANAGER_HANDLE
{
SCMGR_HANDLE Handle;
-
- /* FIXME: Insert more data here */
-
WCHAR DatabaseName[1];
} MANAGER_HANDLE, *PMANAGER_HANDLE;
typedef struct _SERVICE_HANDLE
{
SCMGR_HANDLE Handle;
-
- DWORD DesiredAccess;
PSERVICE ServiceEntry;
-
- /* FIXME: Insert more data here */
-
} SERVICE_HANDLE, *PSERVICE_HANDLE;
if (lpDatabaseName == NULL)
lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
- if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0)
+ if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0)
{
- DPRINT1("Database %S, does not exist\n",lpDatabaseName);
+ DPRINT("Database %S, does not exist\n",lpDatabaseName);
return ERROR_DATABASE_DOES_NOT_EXIST;
}
else if (_wcsicmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
{
- DPRINT1("Invalid Database name %S.\n",lpDatabaseName);
+ DPRINT("Invalid Database name %S.\n",lpDatabaseName);
return ERROR_INVALID_NAME;
}
return ERROR_NOT_ENOUGH_MEMORY;
Ptr->Handle.Tag = MANAGER_TAG;
- Ptr->Handle.RefCount = 1;
-
- /* FIXME: initialize more data here */
wcscpy(Ptr->DatabaseName, lpDatabaseName);
return ERROR_NOT_ENOUGH_MEMORY;
Ptr->Handle.Tag = SERVICE_TAG;
- Ptr->Handle.RefCount = 1;
- /* FIXME: initialize more data here */
Ptr->ServiceEntry = lpServiceEntry;
*Handle = (SC_HANDLE)Ptr;
}
+static PMANAGER_HANDLE
+ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
+{
+ PMANAGER_HANDLE pManager = NULL;
+
+ _SEH2_TRY
+ {
+ if (((PMANAGER_HANDLE)Handle)->Handle.Tag == MANAGER_TAG)
+ pManager = (PMANAGER_HANDLE)Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception: Invalid Service Manager handle!\n");
+ }
+ _SEH2_END;
+
+ return pManager;
+}
+
+
+static PSERVICE_HANDLE
+ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
+{
+ PSERVICE_HANDLE pService = NULL;
+
+ _SEH2_TRY
+ {
+ if (((PSERVICE_HANDLE)Handle)->Handle.Tag == SERVICE_TAG)
+ pService = (PSERVICE_HANDLE)Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception: Invalid Service handle!\n");
+ }
+ _SEH2_END;
+
+ return pService;
+}
+
+
static DWORD
ScmCheckAccess(SC_HANDLE Handle,
DWORD dwDesiredAccess)
NULL);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ERROR! Unable to get number of services keys.\n");
+ DPRINT("ERROR! Unable to get number of services keys.\n");
return dwError;
}
if (!lpCurrentService)
{
/* This should never happen! */
- DPRINT1("This should not happen at this point, report to Developer\n");
+ DPRINT("This should not happen at this point, report to Developer\n");
return ERROR_NOT_FOUND;
}
if (*hSCObject == 0)
return ERROR_INVALID_HANDLE;
- hManager = (PMANAGER_HANDLE)*hSCObject;
- hService = (PSERVICE_HANDLE)*hSCObject;
- if (hManager->Handle.Tag == MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(*hSCObject);
+ hService = ScmGetServiceFromHandle(*hSCObject);
+
+ if (hManager != NULL)
{
DPRINT("Found manager handle\n");
- hManager->Handle.RefCount--;
- if (hManager->Handle.RefCount == 0)
- {
- /* FIXME: add handle cleanup code */
+ /* FIXME: add handle cleanup code */
- HeapFree(GetProcessHeap(), 0, hManager);
- hManager = NULL;
- }
+ HeapFree(GetProcessHeap(), 0, hManager);
+ hManager = NULL;
+
+ *hSCObject = NULL;
DPRINT("RCloseServiceHandle() done\n");
return ERROR_SUCCESS;
}
- else if (hService->Handle.Tag == SERVICE_TAG)
+ else if (hService != NULL)
{
DPRINT("Found service handle\n");
+ /* Lock the service database exlusively */
+ ScmLockDatabaseExclusive();
+
/* Get the pointer to the service record */
lpService = hService->ServiceEntry;
- ASSERT(hService->Handle.RefCount > 0);
-
- hService->Handle.RefCount--;
- if (hService->Handle.RefCount == 0)
- {
- /* FIXME: add handle cleanup code */
+ /* FIXME: add handle cleanup code */
- /* Free the handle */
- HeapFree(GetProcessHeap(), 0, hService);
- hService = NULL;
- }
+ /* Free the handle */
+ HeapFree(GetProcessHeap(), 0, hService);
+ hService = NULL;
ASSERT(lpService->dwRefCount > 0);
&hServicesKey);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("Failed to open services key\n");
+ DPRINT("Failed to open services key\n");
+ ScmUnlockDatabase();
return dwError;
}
/* if pcbBytesNeeded returned a value then there are services running that are dependent on this service*/
if (pcbBytesNeeded)
{
- DPRINT1("Deletion failed due to running dependencies.\n");
+ DPRINT("Deletion failed due to running dependencies.\n");
RegCloseKey(hServicesKey);
+ ScmUnlockDatabase();
return ERROR_SUCCESS;
}
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("Failed to Delete the Service Registry key\n");
+ DPRINT("Failed to Delete the Service Registry key\n");
+ ScmUnlockDatabase();
return dwError;
}
}
}
+ ScmUnlockDatabase();
+
+ *hSCObject = NULL;
+
DPRINT("RCloseServiceHandle() done\n");
return ERROR_SUCCESS;
}
- DPRINT1("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
+ DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
return ERROR_INVALID_HANDLE;
}
DWORD dwError = ERROR_SUCCESS;
DWORD pcbBytesNeeded = 0;
DWORD dwServicesReturned = 0;
+ DWORD dwControlsAccepted;
+ DWORD dwCurrentState;
HKEY hServicesKey = NULL;
DPRINT("RControlService() called\n");
return ERROR_SHUTDOWN_IN_PROGRESS;
/* Check the service handle */
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
+
/* Check the service entry point */
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
&hServicesKey);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("Failed to open services key\n");
+ DPRINT("Failed to open services key\n");
return dwError;
}
}
else
{
+ dwControlsAccepted = lpService->Status.dwControlsAccepted;
+ dwCurrentState = lpService->Status.dwCurrentState;
+
+ /* Check the current state before sending a control request */
+ switch (dwCurrentState)
+ {
+ case SERVICE_STOP_PENDING:
+ case SERVICE_STOPPED:
+ return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+
+ case SERVICE_START_PENDING:
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ RtlCopyMemory(lpServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+ return ERROR_SUCCESS;
+
+ default:
+ return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+ }
+ break;
+ }
+
+ /* Check if the control code is acceptable to the service */
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
+ return ERROR_INVALID_SERVICE_CONTROL;
+ break;
+
+ case SERVICE_CONTROL_PAUSE:
+ case SERVICE_CONTROL_CONTINUE:
+ if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
+ return ERROR_INVALID_SERVICE_CONTROL;
+ break;
+ }
+
/* Send control code to the service */
dwError = ScmControlService(lpService,
- dwControl,
- lpServiceStatus);
+ dwControl);
+
+ /* Return service status information */
+ RtlCopyMemory(lpServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
}
if ((dwError == ERROR_SUCCESS) && (pcbBytesNeeded))
dwError = ERROR_DEPENDENT_SERVICES_RUNNING;
- /* Return service status information */
- RtlCopyMemory(lpServiceStatus,
- &lpService->Status,
- sizeof(SERVICE_STATUS));
+ if (dwError == ERROR_SUCCESS &&
+ dwControl == SERVICE_CONTROL_STOP &&
+ lpServiceStatus->dwCurrentState == SERVICE_STOPPED)
+ {
+ lpService->ProcessId = 0; /* FIXME */
+ lpService->ThreadId = 0;
+ }
+
return dwError;
}
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
+ }
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
DELETE))
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Acquire service database lock exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- DPRINT1("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ DPRINT("The service has already been marked for delete!\n");
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto Done;
}
/* Mark service for delete */
dwError = ScmMarkServiceForDelete(lpService);
- /* FIXME: Release service database lock */
+Done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
DPRINT("RDeleteService() done\n");
*lpLock = 0;
- hMgr = (PMANAGER_HANDLE)hSCManager;
- if (!hMgr || hMgr->Handle.Tag != MANAGER_TAG)
+ hMgr = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hMgr == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
+ }
if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
SC_MANAGER_LOCK))
DPRINT("RQueryServiceObjectSecurity() called\n");
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
- if (dwSecurityInformation & (DACL_SECURITY_INFORMATION ||
- GROUP_SECURITY_INFORMATION ||
+ if (dwSecurityInformation & (DACL_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
OWNER_SECURITY_INFORMATION))
DesiredAccess |= READ_CONTROL;
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
DesiredAccess))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
/* NTSTATUS Status; */
DWORD dwError;
- DPRINT1("RSetServiceObjectSecurity() called\n");
+ DPRINT("RSetServiceObjectSecurity() called\n");
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
DesiredAccess))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_STATUS))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
+ /* Lock the srevice database shared */
+ ScmLockDatabaseShared();
+
/* Return service status information */
RtlCopyMemory(lpServiceStatus,
&lpService->Status,
sizeof(SERVICE_STATUS));
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
return ERROR_SUCCESS;
}
if (hServiceStatus == 0)
{
- DPRINT1("hServiceStatus == NULL!\n");
+ DPRINT("hServiceStatus == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- lpService = ScmGetServiceEntryByClientHandle((HANDLE)hServiceStatus);
+ lpService = (PSERVICE)hServiceStatus;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
/* Check current state */
if (!ScmIsValidServiceState(lpServiceStatus->dwCurrentState))
{
- DPRINT1("Invalid service state!\n");
+ DPRINT("Invalid service state!\n");
return ERROR_INVALID_DATA;
}
if (!(lpServiceStatus->dwServiceType & SERVICE_WIN32) &&
(lpServiceStatus->dwServiceType & SERVICE_DRIVER))
{
- DPRINT1("Invalid service type!\n");
+ DPRINT("Invalid service type!\n");
return ERROR_INVALID_DATA;
}
/* Check accepted controls */
if (lpServiceStatus->dwControlsAccepted & ~0xFF)
{
- DPRINT1("Invalid controls accepted!\n");
+ DPRINT("Invalid controls accepted!\n");
return ERROR_INVALID_DATA;
}
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
RtlCopyMemory(&lpService->Status,
lpServiceStatus,
sizeof(SERVICE_STATUS));
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
DPRINT("Set %S to %lu\n", lpService->lpDisplayName, lpService->Status.dwCurrentState);
DPRINT("RSetServiceStatus() done\n");
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_CHANGE_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock database exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- /* FIXME: Unlock database */
- DPRINT1("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ DPRINT("The service has already been marked for delete!\n");
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto done;
}
/* Open the service key */
(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)
/* FIXME: Write password */
}
- /* FIXME: Unlock database */
-
done:
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError);
return dwError;
*RelativeName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
if (*RelativeName == NULL)
{
- DPRINT1("Error allocating memory for boot driver name!\n");
+ DPRINT("Error allocating memory for boot driver name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
/* Copy it */
wcscpy(*RelativeName, CanonName);
- DPRINT1("Bootdriver name %S\n", *RelativeName);
+ DPRINT("Bootdriver name %S\n", *RelativeName);
return ERROR_SUCCESS;
}
if (*RelativeName == NULL)
{
- DPRINT1("Error allocating memory for boot driver name!\n");
+ DPRINT("Error allocating memory for boot driver name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
wcscpy(*RelativeName, L"\\SystemRoot\\");
wcscat(*RelativeName, CanonName + 13);
- DPRINT1("Bootdriver name %S\n", *RelativeName);
+ DPRINT("Bootdriver name %S\n", *RelativeName);
return ERROR_SUCCESS;
}
if (BufferSize <= 1)
{
- DPRINT1("Error during a call to ExpandEnvironmentStringsW()\n");
+ DPRINT("Error during a call to ExpandEnvironmentStringsW()\n");
return ERROR_INVALID_ENVIRONMENT;
}
Expanded = LocalAlloc(LMEM_ZEROINIT, BufferSize * sizeof(WCHAR) + sizeof(WCHAR));
if (!Expanded)
{
- DPRINT1("Error allocating memory for boot driver name!\n");
+ DPRINT("Error allocating memory for boot driver name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
if (ExpandEnvironmentStringsW(L"%SystemRoot%\\", Expanded, BufferSize) >
BufferSize)
{
- DPRINT1("Error during a call to ExpandEnvironmentStringsW()\n");
+ DPRINT("Error during a call to ExpandEnvironmentStringsW()\n");
LocalFree(Expanded);
return ERROR_NOT_ENOUGH_MEMORY;
}
/* Convert to NY-style path */
if (!RtlDosPathNameToNtPathName_U(Expanded, &NtPathName, NULL, NULL))
{
- DPRINT1("Error during a call to RtlDosPathNameToNtPathName_U()\n");
+ DPRINT("Error during a call to RtlDosPathNameToNtPathName_U()\n");
return ERROR_INVALID_ENVIRONMENT;
}
Expanded = LocalAlloc(LMEM_ZEROINIT, NtPathName.Length + sizeof(WCHAR));
if (!Expanded)
{
- DPRINT1("Error allocating memory for boot driver name!\n");
+ DPRINT("Error allocating memory for boot driver name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
(ServiceNameLen - ExpandedLen) * sizeof(WCHAR) + 13*sizeof(WCHAR));
if (*RelativeName == NULL)
{
- DPRINT1("Error allocating memory for boot driver name!\n");
+ DPRINT("Error allocating memory for boot driver name!\n");
LocalFree(Expanded);
return ERROR_NOT_ENOUGH_MEMORY;
}
/* Check if required buffer size is sane */
if (BufferSize > 0xFFFD)
{
- DPRINT1("Too large buffer required\n");
+ DPRINT("Too large buffer required\n");
*RelativeName = 0;
if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
LinkTarget.Buffer = LocalAlloc(LMEM_ZEROINIT, BufferSize + sizeof(WCHAR));
if (!LinkTarget.Buffer)
{
- DPRINT1("Unable to alloc buffer\n");
+ DPRINT("Unable to alloc buffer\n");
if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
LocalFree(Expanded);
return ERROR_NOT_ENOUGH_MEMORY;
if (*RelativeName == NULL)
{
- DPRINT1("Unable to alloc buffer\n");
+ DPRINT("Unable to alloc buffer\n");
if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
LocalFree(Expanded);
RtlFreeUnicodeString(&NtPathName);
}
else
{
- DPRINT1("Error, Status = %08X\n", Status);
+ DPRINT("Error, Status = %08X\n", Status);
if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
LocalFree(Expanded);
RtlFreeUnicodeString(&NtPathName);
}
else
{
- DPRINT1("Error, Status = %08X\n", Status);
+ DPRINT("Error, Status = %08X\n", Status);
if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
LocalFree(Expanded);
RtlFreeUnicodeString(&NtPathName);
}
else
{
- DPRINT1("Error, Status = %08X\n", Status);
+ DPRINT("Error, Status = %08X\n", Status);
LocalFree(Expanded);
return ERROR_INVALID_PARAMETER;
}
if (*lpCanonName == NULL)
{
- DPRINT1("Error allocating memory for canonized service name!\n");
+ DPRINT("Error allocating memory for canonized service name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
if (*lpCanonName == NULL)
{
- DPRINT1("Error allocating memory for canonized service name!\n");
+ DPRINT("Error allocating memory for canonized service name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
if (*lpCanonName == NULL)
{
- DPRINT1("Error allocating memory for canonized service name!\n");
+ DPRINT("Error allocating memory for canonized service name!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
/* It seems to be a DOS path, convert it */
if (!RtlDosPathNameToNtPathName_U(lpServiceName, &NtServiceName, NULL, NULL))
{
- DPRINT1("RtlDosPathNameToNtPathName_U() failed!\n");
+ DPRINT("RtlDosPathNameToNtPathName_U() failed!\n");
return ERROR_INVALID_PARAMETER;
}
if (*lpCanonName == NULL)
{
- DPRINT1("Error allocating memory for canonized service name!\n");
+ DPRINT("Error allocating memory for canonized service name!\n");
RtlFreeUnicodeString(&NtServiceName);
return ERROR_NOT_ENOUGH_MEMORY;
}
{
/* There is a problem, free name and return */
LocalFree(*lpCanonName);
- DPRINT1("Error converting named!\n");
+ DPRINT("Error converting named!\n");
return Result;
}
SC_HANDLE hServiceHandle = NULL;
LPWSTR lpImagePath = NULL;
HKEY hServiceKey = NULL;
+ LPWSTR lpObjectName;
DPRINT("RCreateServiceW() called\n");
DPRINT("lpServiceName = %S\n", lpServiceName);
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT1("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
SC_MANAGER_CREATE_SERVICE))
{
- DPRINT1("Insufficient access rights! 0x%lx\n",
- hManager->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hManager->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
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;
}
DWORD dwServicesReturned = 0;
DWORD dwServiceCount;
HKEY hServicesKey = NULL;
- LPSC_RPC_HANDLE hSCObject;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
PSERVICE *lpServicesArray = NULL;
DPRINT("REnumDependentServicesW() called\n");
- hSCObject = &hService;
- hSvc = (PSERVICE_HANDLE) *hSCObject;
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
lpService = hSvc->ServiceEntry;
/* Check access rights */
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SC_MANAGER_ENUMERATE_SERVICE))
{
- DPRINT1("Insufficient access rights! 0x%lx\n",
- hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
(dwServicesReturned + 1) * sizeof(PSERVICE));
if (!lpServicesArray)
{
- DPRINT1("Could not allocate a buffer!!\n");
+ DPRINT("Could not allocate a buffer!!\n");
dwError = ERROR_NOT_ENOUGH_MEMORY;
goto Done;
}
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT1("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
+
*pcbBytesNeeded = 0;
*lpServicesReturned = 0;
if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
SC_MANAGER_ENUMERATE_SERVICE))
{
- DPRINT1("Insufficient access rights! 0x%lx\n",
+ DPRINT("Insufficient access rights! 0x%lx\n",
hManager->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
- if (lpResumeHandle) dwLastResumeCount = *lpResumeHandle;
+ if (lpResumeHandle)
+ dwLastResumeCount = *lpResumeHandle;
- /* FIXME: Lock the service list shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
if (lpService == NULL)
DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
- if (lpResumeHandle) *lpResumeHandle = dwLastResumeCount;
+ if (lpResumeHandle)
+ *lpResumeHandle = dwLastResumeCount;
+
*lpServicesReturned = dwServiceCount;
*pcbBytesNeeded = dwRequiredSize;
}
Done:;
- /* FIXME: Unlock the service list */
+ /* Unlock the service database */
+ ScmUnlockDatabase();
DPRINT("REnumServicesStatusW() done (Error %lu)\n", dwError);
&hHandle);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
+ DPRINT("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
return dwError;
}
dwDesiredAccess | SC_MANAGER_CONNECT);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
+ DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
HeapFree(GetProcessHeap(), 0, hHandle);
return dwError;
}
PSERVICE lpService;
PMANAGER_HANDLE hManager;
SC_HANDLE hHandle;
- DWORD dwError;
+ DWORD dwError = ERROR_SUCCESS;
DPRINT("ROpenServiceW() called\n");
DPRINT("hSCManager = %p\n", hSCManager);
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT1("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!lpServiceName)
return ERROR_INVALID_ADDRESS;
- /* FIXME: Lock the service list */
+ /* Lock the service database exclusive */
+ ScmLockDatabaseExclusive();
/* Get service database entry */
lpService = ScmGetServiceEntryByName(lpServiceName);
if (lpService == NULL)
{
DPRINT("Could not find a service!\n");
- return ERROR_SERVICE_DOES_NOT_EXIST;
+ dwError = ERROR_SERVICE_DOES_NOT_EXIST;
+ goto Done;
}
/* Create a service handle */
&hHandle);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
- return dwError;
+ DPRINT("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
+ goto Done;
}
/* Check the desired access */
dwDesiredAccess);
if (dwError != ERROR_SUCCESS)
{
- DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
+ DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
HeapFree(GetProcessHeap(), 0, hHandle);
- return dwError;
+ goto Done;
}
lpService->dwRefCount++;
*lpServiceHandle = (SC_RPC_HANDLE)hHandle;
DPRINT("*hService = %p\n", *lpServiceHandle);
+Done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
DPRINT("ROpenServiceW() done\n");
- return ERROR_SUCCESS;
+ return dwError;
}
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 (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
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);
*pcbBytesNeeded = dwRequiredSize;
Done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (lpImagePath != NULL)
HeapFree(GetProcessHeap(), 0, lpImagePath);
if (lpServiceStartName != NULL)
HeapFree(GetProcessHeap(), 0, lpServiceStartName);
+ if (lpDependencies != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependencies);
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
- /* FIXME: Unlock the service database */
-
DPRINT("RQueryServiceConfigW() done\n");
return dwError;
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_START))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
// hManager = (PMANAGER_HANDLE)hSCManager;
// if (hManager->Handle.Tag != MANAGER_TAG)
// {
-// DPRINT1("Invalid manager handle!\n");
+// DPRINT("Invalid manager handle!\n");
// return ERROR_INVALID_HANDLE;
// }
lpService = ScmGetServiceEntryByName(lpServiceName);
if (lpService == NULL)
{
- DPRINT1("Could not find a service!\n");
+ DPRINT("Could not find a service!\n");
/* If the service could not be found and lpcchBuffer is less than 2, windows
puts null in lpDisplayName and puts 2 in lpcchBuffer */
// hManager = (PMANAGER_HANDLE)hSCManager;
// if (hManager->Handle.Tag != MANAGER_TAG)
// {
-// DPRINT1("Invalid manager handle!\n");
+// DPRINT("Invalid manager handle!\n");
// return ERROR_INVALID_HANDLE;
// }
lpService = ScmGetServiceEntryByDisplayName(lpDisplayName);
if (lpService == NULL)
{
- DPRINT1("Could not find a service!\n");
+ DPRINT("Could not find a service!\n");
/* If the service could not be found and lpcchBuffer is less than 2, windows
puts null in lpDisplayName and puts 2 in lpcchBuffer */
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_CHANGE_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock database exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- /* FIXME: Unlock database */
- DPRINT1("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ DPRINT("The service has already been marked for delete!\n");
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto done;
}
/* Open the service key */
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,
/* FIXME: Write password */
}
- /* FIXME: Unlock database */
-
done:
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
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;
}
DWORD dwServicesReturned = 0;
DWORD dwServiceCount;
HKEY hServicesKey = NULL;
- LPSC_RPC_HANDLE hSCObject;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
PSERVICE *lpServicesArray = NULL;
DPRINT("REnumDependentServicesA() called\n");
- hSCObject = &hService;
- hSvc = (PSERVICE_HANDLE) *hSCObject;
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
lpService = hSvc->ServiceEntry;
/* Check access rights */
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SC_MANAGER_ENUMERATE_SERVICE))
{
- DPRINT1("Insufficient access rights! 0x%lx\n",
- hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
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
(dwServicesReturned + 1) * sizeof(PSERVICE));
if (!lpServicesArray)
{
- DPRINT1("Could not allocate a buffer!!\n");
+ DPRINT("Could not allocate a buffer!!\n");
dwError = ERROR_NOT_ENOUGH_MEMORY;
goto Done;
}
lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
if (!lpStatusPtrW)
{
- DPRINT1("Failed to allocate buffer!\n");
+ DPRINT("Failed to allocate buffer!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
}
- 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 (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
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);
}
*pcbBytesNeeded = dwRequiredSize;
Done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (lpImagePath != NULL)
HeapFree(GetProcessHeap(), 0, lpImagePath);
if (lpServiceStartName != NULL)
HeapFree(GetProcessHeap(), 0, lpServiceStartName);
+ if (lpDependencies != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependencies);
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
- /* FIXME: Unlock the service database */
-
DPRINT("RQueryServiceConfigA() done\n");
return dwError;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
- DPRINT1("RStartServiceA() called\n");
+ DPRINT("RStartServiceA() called\n");
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_START))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
// hManager = (PMANAGER_HANDLE)hSCManager;
// if (hManager->Handle.Tag != MANAGER_TAG)
// {
-// DPRINT1("Invalid manager handle!\n");
+// DPRINT("Invalid manager handle!\n");
// return ERROR_INVALID_HANDLE;
// }
if (lpService == NULL)
{
- DPRINT1("Could not find a service!\n");
+ DPRINT("Could not find a service!\n");
/* If the service could not be found and lpcchBuffer is 0, windows
puts null in lpDisplayName and puts 1 in lpcchBuffer */
if (lpService == NULL)
{
- DPRINT1("Could not find the service!\n");
+ DPRINT("Could not find the service!\n");
/* If the service could not be found and lpcchBuffer is 0,
put null in lpDisplayName and puts 1 in lpcchBuffer, verified WINXP. */
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_CHANGE_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock database exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- /* FIXME: Unlock database */
- DPRINT1("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ DPRINT("The service has already been marked for delete!\n");
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto done;
}
/* Open the service key */
if (lpServiceDescription != NULL &&
lpServiceDescription->lpDescription != NULL)
{
- DPRINT1("Setting value %S\n", lpServiceDescription->lpDescription);
- RegSetValueExW(hServiceKey,
- L"Description",
- 0,
- REG_SZ,
- (LPBYTE)lpServiceDescription->lpDescription,
- (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
-
+ DPRINT("Setting value %S\n", lpServiceDescription->lpDescription);
+ dwError = RegSetValueExW(hServiceKey,
+ L"Description",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpServiceDescription->lpDescription,
+ (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
if (dwError != ERROR_SUCCESS)
goto done;
}
}
done:
- /* FIXME: Unlock database */
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
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);
+ DPRINT("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 (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
if (dwError != ERROR_SUCCESS)
goto done;
- if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
+ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
{
LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer;
LPSTR lpStr;
- *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
-
dwError = ScmReadString(hServiceKey,
L"Description",
&lpDescriptionW);
+ if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
+ goto done;
+
+ *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
if (dwError == ERROR_SUCCESS)
- {
*pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
- }
- if (cbBufSize >= *pcbBytesNeeded)
+ if (cbBufSize < *pcbBytesNeeded)
{
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ goto done;
+ }
- if (dwError == ERROR_SUCCESS)
- {
- lpStr = (LPSTR)(lpServiceDescription + 1);
+ if (dwError == ERROR_SUCCESS)
+ {
+ lpStr = (LPSTR)(lpServiceDescription + 1);
- WideCharToMultiByte(CP_ACP,
- 0,
- lpDescriptionW,
- -1,
- lpStr,
- wcslen(lpDescriptionW),
- NULL,
- NULL);
- lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
- }
- else
- {
- lpServiceDescription->lpDescription = NULL;
- goto done;
- }
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpDescriptionW,
+ -1,
+ lpStr,
+ wcslen(lpDescriptionW),
+ NULL,
+ NULL);
+ lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
}
else
{
- dwError = ERROR_INSUFFICIENT_BUFFER;
+ lpServiceDescription->lpDescription = NULL;
+ dwError = ERROR_SUCCESS;
goto done;
}
}
}
done:
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (lpDescription != NULL)
HeapFree(GetProcessHeap(), 0, lpDescription);
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
- /* FIXME: Unlock database */
-
DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
return dwError;
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_CONFIG))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
if (dwError != ERROR_SUCCESS)
goto done;
- if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
+ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
{
LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)lpBuffer;
LPWSTR lpStr;
dwError = ScmReadString(hServiceKey,
L"Description",
&lpDescription);
- if (dwError != ERROR_SUCCESS)
+ if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
goto done;
- dwRequiredSize = sizeof(SERVICE_DESCRIPTIONW) + ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
+ *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONW);
+ if (dwError == ERROR_SUCCESS)
+ *pcbBytesNeeded += ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
- if (cbBufSize < dwRequiredSize)
+ if (cbBufSize < *pcbBytesNeeded)
{
- *pcbBytesNeeded = dwRequiredSize;
dwError = ERROR_INSUFFICIENT_BUFFER;
goto done;
}
- lpStr = (LPWSTR)(lpServiceDescription + 1);
- wcscpy(lpStr, lpDescription);
- lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+ if (dwError == ERROR_SUCCESS)
+ {
+ lpStr = (LPWSTR)(lpServiceDescription + 1);
+ wcscpy(lpStr, lpDescription);
+ lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+ }
+ else
+ {
+ lpServiceDescription->lpDescription = NULL;
+ dwError = ERROR_SUCCESS;
+ }
}
- else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
+ else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
{
LPWSTR lpStr;
LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
}
done:
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (lpDescription != NULL)
HeapFree(GetProcessHeap(), 0, lpDescription);
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
- /* FIXME: Unlock database */
-
DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
return dwError;
if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
return ERROR_INSUFFICIENT_BUFFER;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT1("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_STATUS))
{
- DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT1("lpService == NULL!\n");
+ DPRINT("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
+
lpStatus = (LPSERVICE_STATUS_PROCESS)lpBuffer;
/* Return service status information */
lpStatus->dwProcessId = lpService->ProcessId; /* FIXME */
lpStatus->dwServiceFlags = 0; /* FIXME */
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
return ERROR_SUCCESS;
}
pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
if (!pszGroupNameW)
{
- DPRINT1("Failed to allocate buffer!\n");
+ DPRINT("Failed to allocate buffer!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
+
MultiByteToWideChar(CP_ACP,
0,
pszGroupName,
lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBufSize);
if (!lpStatusPtrW)
{
- DPRINT1("Failed to allocate buffer!\n");
+ DPRINT("Failed to allocate buffer!\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
}
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);
if (InfoLevel != SC_ENUM_PROCESS_INFO)
return ERROR_INVALID_LEVEL;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT1("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
if ((dwServiceType!=SERVICE_DRIVER) && (dwServiceType!=SERVICE_WIN32))
{
- DPRINT1("Not a valid Service Type!\n");
+ DPRINT("Not a valid Service Type!\n");
return ERROR_INVALID_PARAMETER;
}
if ((dwServiceState<SERVICE_ACTIVE) || (dwServiceState>SERVICE_STATE_ALL))
{
- DPRINT1("Not a valid Service State!\n");
+ DPRINT("Not a valid Service State!\n");
return ERROR_INVALID_PARAMETER;
}
if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
SC_MANAGER_ENUMERATE_SERVICE))
{
- DPRINT1("Insufficient access rights! 0x%lx\n",
- hManager->Handle.DesiredAccess);
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hManager->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
- if (lpResumeIndex) dwLastResumeCount = *lpResumeIndex;
+ if (lpResumeIndex)
+ dwLastResumeCount = *lpResumeIndex;
- /* Lock the service list shared */
+ /* FIXME: Lock the service list shared */
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
if (lpService == NULL)
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:;
- /* Unlock the service list */
+ /* FIXME: Unlock the service list */
DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);