📄 rpcserver.c
字号:
if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
SC_MANAGER_ENUMERATE_SERVICE))
{
DPRINT1("Insufficient access rights! 0x%lx\n",
hManager->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
*pcbBytesNeeded = 0;
*lpServicesReturned = 0;
dwLastResumeCount = *lpResumeHandle;
/* FIXME: Lock the service list shared */
lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
if (lpService == NULL)
{
dwError = ERROR_SUCCESS;
goto Done;
}
dwRequiredSize = 0;
dwServiceCount = 0;
for (ServiceEntry = &lpService->ServiceListEntry;
ServiceEntry != &ServiceListHead;
ServiceEntry = ServiceEntry->Flink)
{
CurrentService = CONTAINING_RECORD(ServiceEntry,
SERVICE,
ServiceListEntry);
if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
continue;
dwState = SERVICE_ACTIVE;
if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
dwState = SERVICE_INACTIVE;
if ((dwState & dwServiceState) == 0)
continue;
dwSize = sizeof(ENUM_SERVICE_STATUSW) +
((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
if (dwRequiredSize + dwSize <= dwBufSize)
{
DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
dwRequiredSize += dwSize;
dwServiceCount++;
dwLastResumeCount = CurrentService->dwResumeCount;
}
else
{
DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
break;
}
}
DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
DPRINT("dwServiceCount: %lu\n", dwServiceCount);
for (;
ServiceEntry != &ServiceListHead;
ServiceEntry = ServiceEntry->Flink)
{
CurrentService = CONTAINING_RECORD(ServiceEntry,
SERVICE,
ServiceListEntry);
if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
continue;
dwState = SERVICE_ACTIVE;
if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
dwState = SERVICE_INACTIVE;
if ((dwState & dwServiceState) == 0)
continue;
dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
dwError = ERROR_MORE_DATA;
}
DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
*lpResumeHandle = dwLastResumeCount;
*lpServicesReturned = dwServiceCount;
*pcbBytesNeeded = dwRequiredSize;
lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices +
dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
dwRequiredSize = 0;
for (ServiceEntry = &lpService->ServiceListEntry;
ServiceEntry != &ServiceListHead;
ServiceEntry = ServiceEntry->Flink)
{
CurrentService = CONTAINING_RECORD(ServiceEntry,
SERVICE,
ServiceListEntry);
if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
continue;
dwState = SERVICE_ACTIVE;
if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
dwState = SERVICE_INACTIVE;
if ((dwState & dwServiceState) == 0)
continue;
dwSize = sizeof(ENUM_SERVICE_STATUSW) +
((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
if (dwRequiredSize + dwSize <= dwBufSize)
{
/* Copy the service name */
wcscpy(lpStringPtr,
CurrentService->lpServiceName);
lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
/* Copy the display name */
wcscpy(lpStringPtr,
CurrentService->lpDisplayName);
lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
/* Copy the status information */
memcpy(&lpStatusPtr->ServiceStatus,
&CurrentService->Status,
sizeof(SERVICE_STATUS));
lpStatusPtr++;
dwRequiredSize += dwSize;
}
else
{
break;
}
}
Done:;
/* FIXME: Unlock the service list */
DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError);
return dwError;
}
/* Function 15 */
unsigned long
ScmrOpenSCManagerW(handle_t BindingHandle,
wchar_t *lpMachineName,
wchar_t *lpDatabaseName,
unsigned long dwDesiredAccess,
unsigned int *hScm)
{
DWORD dwError;
SC_HANDLE hHandle;
DPRINT("ScmrOpenSCManagerW() called\n");
DPRINT("lpMachineName = %p\n", lpMachineName);
DPRINT("lpMachineName: %S\n", lpMachineName);
DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
DPRINT("lpDataBaseName: %S\n", lpDatabaseName);
DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
dwError = ScmCreateManagerHandle(lpDatabaseName,
&hHandle);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
return dwError;
}
/* Check the desired access */
dwError = ScmCheckAccess(hHandle,
dwDesiredAccess | SC_MANAGER_CONNECT);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
HeapFree(GetProcessHeap(), 0, hHandle);
return dwError;
}
*hScm = (unsigned int)hHandle;
DPRINT("*hScm = %x\n", *hScm);
DPRINT("ScmrOpenSCManagerW() done\n");
return ERROR_SUCCESS;
}
/* Function 16 */
unsigned long
ScmrOpenServiceW(handle_t BindingHandle,
unsigned int hSCManager,
wchar_t *lpServiceName,
unsigned long dwDesiredAccess,
unsigned int *hService)
{
PSERVICE lpService;
PMANAGER_HANDLE hManager;
SC_HANDLE hHandle;
DWORD dwError;
DPRINT("ScmrOpenServiceW() called\n");
DPRINT("hSCManager = %x\n", hSCManager);
DPRINT("lpServiceName = %p\n", lpServiceName);
DPRINT("lpServiceName: %S\n", lpServiceName);
DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
hManager = (PMANAGER_HANDLE)hSCManager;
if (hManager->Handle.Tag != MANAGER_TAG)
{
DPRINT1("Invalid manager handle!\n");
return ERROR_INVALID_HANDLE;
}
/* FIXME: Lock the service list */
/* Get service database entry */
lpService = ScmGetServiceEntryByName(lpServiceName);
if (lpService == NULL)
{
DPRINT("Could not find a service!\n");
return ERROR_SERVICE_DOES_NOT_EXIST;
}
/* Create a service handle */
dwError = ScmCreateServiceHandle(lpService,
&hHandle);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
return dwError;
}
/* Check the desired access */
dwError = ScmCheckAccess(hHandle,
dwDesiredAccess);
if (dwError != ERROR_SUCCESS)
{
DPRINT1("ScmCheckAccess() failed (Error %lu)\n", dwError);
HeapFree(GetProcessHeap(), 0, hHandle);
return dwError;
}
*hService = (unsigned int)hHandle;
DPRINT("*hService = %x\n", *hService);
DPRINT("ScmrOpenServiceW() done\n");
return ERROR_SUCCESS;
}
/* Function 17 */
unsigned long
ScmrQueryServiceConfigW(handle_t BindingHandle,
unsigned int hService,
unsigned char *lpServiceConfig,
unsigned long cbBufSize,
unsigned long *pcbBytesNeeded)
{
DWORD dwError = ERROR_SUCCESS;
PSERVICE_HANDLE hSvc;
PSERVICE lpService = NULL;
HKEY hServiceKey = NULL;
LPWSTR lpImagePath = NULL;
DWORD dwRequiredSize;
LPQUERY_SERVICE_CONFIGW lpConfig;
LPWSTR lpStr;
DPRINT("ScmrQueryServiceConfigW() called\n");
if (ScmShutdown)
return ERROR_SHUTDOWN_IN_PROGRESS;
hSvc = (PSERVICE_HANDLE)hService;
if (hSvc->Handle.Tag != SERVICE_TAG)
{
DPRINT1("Invalid handle tag!\n");
return ERROR_INVALID_HANDLE;
}
if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
SERVICE_QUERY_CONFIG))
{
DPRINT1("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
return ERROR_ACCESS_DENIED;
}
lpService = hSvc->ServiceEntry;
if (lpService == NULL)
{
DPRINT1("lpService == NULL!\n");
return ERROR_INVALID_HANDLE;
}
/* FIXME: Lock the service database shared */
dwError = ScmOpenServiceKey(lpService->lpServiceName,
KEY_READ,
&hServiceKey);
if (dwError != ERROR_SUCCESS)
goto Done;
dwError = ScmReadString(hServiceKey,
L"ImagePath",
&lpImagePath);
if (dwError != ERROR_SUCCESS)
goto Done;
dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
if (lpImagePath != NULL)
dwRequiredSize += ((wcslen(lpImagePath) + 1) * sizeof(WCHAR));
if (lpService->lpGroup != NULL)
dwRequiredSize += ((wcslen(lpService->lpGroup->lpGroupName) + 1) * sizeof(WCHAR));
/* FIXME: Add Dependencies length*/
/* FIXME: Add ServiceStartName length*/
if (lpService->lpDisplayName != NULL)
dwRequiredSize += ((wcslen(lpService->lpDisplayName) + 1) * sizeof(WCHAR));
if (lpServiceConfig == NULL || cbBufSize < dwRequiredSize)
{
dwError = ERROR_INSUFFICIENT_BUFFER;
}
else
{
lpConfig = (LPQUERY_SERVICE_CONFIGW)lpServiceConfig;
lpConfig->dwServiceType = lpService->Status.dwServiceType;
lpConfig->dwStartType = lpService->dwStartType;
lpConfig->dwErrorControl = lpService->dwErrorControl;
lpConfig->dwTagId = lpService->dwTag;
lpStr = (LPWSTR)(lpConfig + 1);
if (lpImagePath != NULL)
{
wcscpy(lpStr, lpImagePath);
lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
lpStr += (wcslen(lpImagePath) + 1);
}
else
{
lpConfig->lpBinaryPathName = NULL;
}
if (lpService->lpGroup != NULL)
{
wcscpy(lpStr, lpService->lpGroup->lpGroupName);
lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
lpStr += (wcslen(lpService->lpGroup->lpGroupName) + 1);
}
else
{
lpConfig->lpLoadOrderGroup = NULL;
}
/* FIXME: Append Dependencies */
lpConfig->lpDependencies = NULL;
/* FIXME: Append ServiceStartName */
lpConfig->lpServiceStartName = NULL;
if (lpService->lpDisplayName != NULL)
{
wcscpy(lpStr, lpService->lpDisplayName);
lpConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
}
else
{
lpConfig->lpDisplayName = NULL;
}
}
if (pcbBytesNeeded != NULL)
*pcbBytesNeeded = dwRequiredSize;
Done:;
if (lpImagePath != NULL)
HeapFree(GetProcessHeap(), 0, lpImagePath);
if (hServiceKey != NULL)
RegCloseKey(hServiceKey);
/* FIXME: Unlock the service database */
DPRINT("ScmrQueryServiceConfigW() done\n");
return dwError;
}
/* Function 18 */
unsigned long
ScmrQueryServiceLockStatusW(handle_t BindingHandle,
unsigned int hSCManager,
unsigned char *lpLockStatus, /* [out, unique, size_is(cbBufSize)] */
unsigned long cbBufSize, /* [in] */
unsigned long *pcbBytesNeeded) /* [out] */
{
DPRINT1("ScmrQueryServiceLockStatusW() called\n");
return ERROR_CALL_NOT_IMPLEMENTED;
}
/* Function 19 */
unsigned long
ScmrStartServiceW(handle_t BindingHandle,
unsigned int hService,
unsigned long dwNumServiceArgs,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -