获取可执行的服务路径

时间:2015-01-06 14:15:26

标签: c++ winapi

考虑下图。

Path to Executable

我编写了以下代码,该代码应该获取服务的路径路径,如图所示。基本上我在下面给出的代码片段将写在另一个生成 lpa.exe 的cpp文件中,并且应该作为服务运行。我尝试了 GetModuleFileName ,如果可执行文件(lpa.exe)正常运行(不作为服务),函数会找到正确的路径。但是一旦它作为服务运行,它就没有给出正确的路径并指向 system32 /...。为了解决这个问题,我相信以下代码片段可能就是解决方案:

#include <Windows.h>
#include <iostream>

int main()
{
    SC_HANDLE sHandle;
    LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
    DWORD cbBufSize = 100;
    LPDWORD bytesNeeded = NULL;
    sHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    sHandle = OpenService(sHandle, "LogPointAgent",SERVICE_ALL_ACCESS);
    QueryServiceConfig(sHandle,lpServiceConfig,cbBufSize,bytesNeeded);
    std::cout << lpServiceConfig->lpBinaryPathName << std::endl;
}

代码编译但我得到异常在LearningCpp.exe中0x00ad1103处的未处理异常:0xC0000005:访问冲突读取位置0x0000000c。这意味着我遇到与指针有关的问题。我上面给出的代码有什么问题?

1 个答案:

答案 0 :(得分:2)

如果使用第三个参数指定大小,

QueryServiceConfig需要一个指向已分配内存的指针作为第二个参数。您指定大小,但指针为NULL,这会导致崩溃。

  

lpServiceConfig [out,optional]

     

指向接收服务配置信息的缓冲区的指针。数据的格式是QUERY_SERVICE_CONFIG结构。

     

此数组的最大大小为8K字节。要确定所需的大小,请为此参数指定NULL,为cbBufSize参数指定0。该函数将失败,GetLastError将返回ERROR_INSUFFICIENT_BUFFER。 pcbBytesNeeded参数将获得所需的大小。*

您必须为lpServiceConfig参数分配内存。

这是一个官方的例子:

Querying a Service's Configuration

//
// Purpose: 
//   Retrieves and displays the current service configuration.
//
// Parameters:
//   None
// 
// Return value:
//   None
//
VOID __stdcall DoQuerySvc()
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    LPQUERY_SERVICE_CONFIG lpsc; 
    LPSERVICE_DESCRIPTION lpsd;
    DWORD dwBytesNeeded, cbBufSize, dwError; 

    // Get a handle to the SCM database. 

    schSCManager = OpenSCManager( 
        NULL,                    // local computer
        NULL,                    // ServicesActive database 
        SC_MANAGER_ALL_ACCESS);  // full access rights 

    if (NULL == schSCManager) 
    {
        printf("OpenSCManager failed (%d)\n", GetLastError());
        return;
    }

    // Get a handle to the service.

    schService = OpenService( 
        schSCManager,          // SCM database 
        szSvcName,             // name of service 
        SERVICE_QUERY_CONFIG); // need query config access 

    if (schService == NULL)
    { 
        printf("OpenService failed (%d)\n", GetLastError()); 
        CloseServiceHandle(schSCManager);
        return;
    }

    // Get the configuration information.

    if( !QueryServiceConfig( 
        schService, 
        NULL, 
        0, 
        &dwBytesNeeded))
    {
        dwError = GetLastError();
        if( ERROR_INSUFFICIENT_BUFFER == dwError )
        {
            cbBufSize = dwBytesNeeded;
            lpsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize);
        }
        else
        {
            printf("QueryServiceConfig failed (%d)", dwError);
            goto cleanup; 
        }
    }

    if( !QueryServiceConfig( 
        schService, 
        lpsc, 
        cbBufSize, 
        &dwBytesNeeded) ) 
    {
        printf("QueryServiceConfig failed (%d)", GetLastError());
        goto cleanup;
    }

    if( !QueryServiceConfig2( 
        schService, 
        SERVICE_CONFIG_DESCRIPTION,
        NULL, 
        0, 
        &dwBytesNeeded))
    {
        dwError = GetLastError();
        if( ERROR_INSUFFICIENT_BUFFER == dwError )
        {
            cbBufSize = dwBytesNeeded;
            lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize);
        }
        else
        {
            printf("QueryServiceConfig2 failed (%d)", dwError);
            goto cleanup; 
        }
    }

    if (! QueryServiceConfig2( 
        schService, 
        SERVICE_CONFIG_DESCRIPTION,
        (LPBYTE) lpsd, 
        cbBufSize, 
        &dwBytesNeeded) ) 
    {
        printf("QueryServiceConfig2 failed (%d)", GetLastError());
        goto cleanup;
    }

    // Print the configuration information.

    _tprintf(TEXT("%s configuration: \n"), szSvcName);
    _tprintf(TEXT("  Type: 0x%x\n"), lpsc->dwServiceType);
    _tprintf(TEXT("  Start Type: 0x%x\n"), lpsc->dwStartType);
    _tprintf(TEXT("  Error Control: 0x%x\n"), lpsc->dwErrorControl);
    _tprintf(TEXT("  Binary path: %s\n"), lpsc->lpBinaryPathName);
    _tprintf(TEXT("  Account: %s\n"), lpsc->lpServiceStartName);

    if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
        _tprintf(TEXT("  Description: %s\n"), lpsd->lpDescription);
    if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0)
        _tprintf(TEXT("  Load order group: %s\n"), lpsc->lpLoadOrderGroup);
    if (lpsc->dwTagId != 0)
        _tprintf(TEXT("  Tag ID: %d\n"), lpsc->dwTagId);
    if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
        _tprintf(TEXT("  Dependencies: %s\n"), lpsc->lpDependencies);

    LocalFree(lpsc); 
    LocalFree(lpsd);

cleanup:
    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager);
}