/* INCLUDES ****************************************************************/
#include "services.h"
-#include "svcctl_s.h"
#define NDEBUG
#include <debug.h>
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;
ScmServiceMapping = {SERVICE_READ,
SERVICE_WRITE,
SERVICE_EXECUTE,
- SC_MANAGER_ALL_ACCESS};
+ SERVICE_ALL_ACCESS};
/* FUNCTIONS ***************************************************************/
if (lpDatabaseName == NULL)
lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
- if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0)
+ if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0)
{
DPRINT("Database %S, does not exist\n",lpDatabaseName);
return ERROR_DATABASE_DOES_NOT_EXIST;
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)
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);
if (dwError != ERROR_SUCCESS)
{
DPRINT("Failed to open services key\n");
+ ScmUnlockDatabase();
return dwError;
}
{
DPRINT("Deletion failed due to running dependencies.\n");
RegCloseKey(hServicesKey);
+ ScmUnlockDatabase();
return ERROR_SUCCESS;
}
if (dwError != ERROR_SUCCESS)
{
DPRINT("Failed to Delete the Service Registry key\n");
+ ScmUnlockDatabase();
return dwError;
}
}
}
+ ScmUnlockDatabase();
+
+ *hSCObject = NULL;
+
DPRINT("RCloseServiceHandle() done\n");
return ERROR_SUCCESS;
}
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)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
+
/* Check the service entry point */
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
- DPRINT("lpService == NULL!\n");
+ DPRINT1("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
}
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);
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 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))
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Acquire service database lock exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
DPRINT("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ 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)
{
- DPRINT("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;
DPRINT("RSetServiceObjectSecurity() called\n");
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
TRUE,
&hToken);
if (!NT_SUCCESS(Status))
- return RtlNtStatusToDosError(Status);
+ return RtlNtStatusToDosError(Status);
RpcRevertToSelf();
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
+ /* Lock the srevice database shared */
ScmLockDatabaseShared();
/* Return service status information */
&lpService->Status,
sizeof(SERVICE_STATUS));
+ /* Unlock the service database */
ScmUnlockDatabase();
return ERROR_SUCCESS;
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);
SVCCTL_HANDLEW lpMachineName,
DWORD BootAcceptable)
{
- UNIMPLEMENTED;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ DPRINT1("RNotifyBootConfigStatus(%p %lu) called\n", lpMachineName, BootAcceptable);
+ return ERROR_SUCCESS;
+
+// UNIMPLEMENTED;
+// return ERROR_CALL_NOT_IMPLEMENTED;
}
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock database exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- /* FIXME: Unlock database */
DPRINT("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto done;
}
/* Open the service key */
/* 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;
}
/* Do a real query now */
- LinkTarget.Length = BufferSize;
+ LinkTarget.Length = (USHORT)BufferSize;
LinkTarget.MaximumLength = LinkTarget.Length + sizeof(WCHAR);
Status = NtQuerySymbolicLinkObject(SymbolicLinkHandle, &LinkTarget, &BufferSize);
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_PARAMETER;
}
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
+
lpService = ScmGetServiceEntryByName(lpServiceName);
if (lpService)
{
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
/* check if it is marked for deletion */
if (lpService->bDeleted)
return ERROR_SERVICE_MARKED_FOR_DELETE;
if (lpDisplayName != NULL &&
ScmGetServiceEntryByDisplayName(lpDisplayName) != NULL)
+ {
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
return ERROR_DUPLICATE_SERVICE_NAME;
+ }
if (dwServiceType & SERVICE_DRIVER)
{
if (dwStartType == SERVICE_BOOT_START ||
dwStartType == SERVICE_SYSTEM_START)
{
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
return ERROR_INVALID_PARAMETER;
}
}
DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
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 (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hManager = (PMANAGER_HANDLE)hSCManager;
- if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
+
*pcbBytesNeeded = 0;
*lpServicesReturned = 0;
if (lpResumeHandle)
dwLastResumeCount = *lpResumeHandle;
- /* FIXME: Lock the service list shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
if (lpService == NULL)
dwRequiredSize += dwSize;
}
- if (dwError == 0)
+ if (dwError == 0)
{
*pcbBytesNeeded = 0;
if (lpResumeHandle) *lpResumeHandle = 0;
}
Done:;
- /* FIXME: Unlock the service list */
+ /* Unlock the service database */
+ ScmUnlockDatabase();
DPRINT("REnumServicesStatusW() done (Error %lu)\n", 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)
{
- DPRINT("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 */
if (dwError != ERROR_SUCCESS)
{
DPRINT("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
- return dwError;
+ goto Done;
}
/* Check the desired access */
{
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;
}
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
*pcbBytesNeeded = dwRequiredSize;
Done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (lpImagePath != NULL)
HeapFree(GetProcessHeap(), 0, lpImagePath);
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
- /* FIXME: Unlock the service database */
-
DPRINT("RQueryServiceConfigW() done\n");
return dwError;
DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
+ DWORD i;
- DPRINT("RStartServiceW() called\n");
+ DPRINT("RStartServiceW(%p %lu %p) called\n", hService, argc, argv);
+ DPRINT(" argc: %lu\n", argc);
+ if (argv != NULL)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ DPRINT(" argv[%lu]: %S\n", i, argv[i]);
+ }
+ }
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (lpService->bDeleted)
return ERROR_SERVICE_MARKED_FOR_DELETE;
- if (argv) {
- UNIMPLEMENTED;
- argv = NULL;
- }
-
/* Start the service */
- dwError = ScmStartService(lpService, argc, (LPWSTR *)argv);
+ dwError = ScmStartService(lpService, argc, (LPWSTR*)argv);
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)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock database exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- /* FIXME: Unlock database */
DPRINT("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto done;
}
/* Open the service key */
/* FIXME: Write password */
}
- /* FIXME: Unlock database */
-
done:
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
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 */
lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
- lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
+ lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
*pcbBytesNeeded = dwRequiredSize;
Done:;
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
if (lpImagePath != NULL)
HeapFree(GetProcessHeap(), 0, lpImagePath);
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
- /* FIXME: Unlock the service database */
-
DPRINT("RQueryServiceConfigA() done\n");
return dwError;
DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
+ LPWSTR *lpVector = NULL;
+ DWORD i;
+ DWORD dwLength;
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)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
if (lpService->bDeleted)
return ERROR_SERVICE_MARKED_FOR_DELETE;
- /* FIXME: Convert argument vector to Unicode */
+ /* Build a Unicode argument vector */
+ if (argc > 0)
+ {
+ lpVector = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ argc * sizeof(LPWSTR));
+ if (lpVector == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ for (i = 0; i < argc; i++)
+ {
+ dwLength = MultiByteToWideChar(CP_ACP,
+ 0,
+ ((LPSTR*)argv)[i],
+ -1,
+ NULL,
+ 0);
+
+ lpVector[i] = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ dwLength * sizeof(WCHAR));
+ if (lpVector[i] == NULL)
+ {
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ ((LPSTR*)argv)[i],
+ -1,
+ lpVector[i],
+ dwLength);
+ }
+ }
/* Start the service */
- dwError = ScmStartService(lpService, 0, NULL);
+ dwError = ScmStartService(lpService, argc, lpVector);
- /* FIXME: Free argument vector */
+done:
+ /* Free the Unicode argument vector */
+ if (lpVector != NULL)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ if (lpVector[i] != NULL)
+ HeapFree(GetProcessHeap(), 0, lpVector[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, lpVector);
+ }
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)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock database exclusively */
+ /* Lock the service database exclusively */
+ ScmLockDatabaseExclusive();
if (lpService->bDeleted)
{
- /* FIXME: Unlock database */
DPRINT("The service has already been marked for delete!\n");
- return ERROR_SERVICE_MARKED_FOR_DELETE;
+ dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
+ goto done;
}
/* Open the service key */
lpServiceDescription->lpDescription != NULL)
{
DPRINT("Setting value %S\n", lpServiceDescription->lpDescription);
- RegSetValueExW(hServiceKey,
- L"Description",
- 0,
- REG_SZ,
- (LPBYTE)lpServiceDescription->lpDescription,
- (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
-
+ 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);
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
- hSvc = (PSERVICE_HANDLE)hService;
- if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
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)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
- /* FIXME: Lock the service database shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
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)
{
goto done;
}
- lpFailureActions->cActions = 0;
+ lpFailureActions->cActions = 0;
lpFailureActions->dwResetPeriod = 0;
lpFailureActions->lpCommand = NULL;
lpFailureActions->lpRebootMsg = NULL;
}
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)
{
- DPRINT("Invalid handle tag!\n");
+ DPRINT1("Invalid service handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_INVALID_HANDLE;
}
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
+
lpStatus = (LPSERVICE_STATUS_PROCESS)lpBuffer;
/* Return service status information */
&lpService->Status,
sizeof(SERVICE_STATUS));
- lpStatus->dwProcessId = lpService->ProcessId; /* FIXME */
+ lpStatus->dwProcessId = (lpService->lpImage != NULL) ? lpService->lpImage->dwProcessId : 0; /* FIXME */
lpStatus->dwServiceFlags = 0; /* FIXME */
+ /* Unlock the service database */
+ ScmUnlockDatabase();
+
return ERROR_SUCCESS;
}
lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
- lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
+ lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
*lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
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)
{
- DPRINT("Invalid manager handle!\n");
+ DPRINT1("Invalid service manager handle!\n");
return ERROR_INVALID_HANDLE;
}
return ERROR_ACCESS_DENIED;
}
- if (lpResumeIndex) dwLastResumeCount = *lpResumeIndex;
+ if (lpResumeIndex)
+ dwLastResumeCount = *lpResumeIndex;
- /* Lock the service list shared */
+ /* Lock the service database shared */
+ ScmLockDatabaseShared();
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
if (lpService == NULL)
memcpy(&lpStatusPtr->ServiceStatusProcess,
&CurrentService->Status,
sizeof(SERVICE_STATUS));
- lpStatusPtr->ServiceStatusProcess.dwProcessId = CurrentService->ProcessId; /* FIXME */
+ lpStatusPtr->ServiceStatusProcess.dwProcessId =
+ (CurrentService->lpImage != NULL) ? CurrentService->lpImage->dwProcessId : 0; /* FIXME */
lpStatusPtr->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
lpStatusPtr++;
}
}
- if (dwError == 0)
+ if (dwError == 0)
{
*pcbBytesNeeded = 0;
if (lpResumeIndex)
}
Done:;
- /* Unlock the service list */
+ /* Unlock the service database */
+ ScmUnlockDatabase();
DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);