0

我正在使用 Windows 的 ChangeServiceConfig2 API 来更改服务描述。由于 windows 98 不支持相同的 api,所以我使用 LoadLibraray 和 GetProcAddress 来防止 exe 中的 API 的静态链接。详情请参考代码:

typedef BOOL  (*ChgSvcDesc) (SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo);

eBool ServiceConfigNT::Install(IN tServiceDesc * pServiceDesc){


    SC_HANDLE           hservice;
    SC_HANDLE           hservicemgr;
    SERVICE_DESCRIPTION desc;
    ULong             starttype;
    HMODULE           hmod;
    ChgSvcDesc        fpsvcdesc;

// Opens the Service Control Manager
hservicemgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!hservicemgr){
    vPrepareError(_TEXT("Failed to open service control manager!!"));
    goto err;
}

// Set start method of service.
starttype   = (pServiceDesc->uAutoStart  == TRUE)? SERVICE_AUTO_START : SERVICE_DEMAND_START;

// Create the service
hservice =  CreateService(hservicemgr, vServiceName, pServiceDesc->uDisplayName, SERVICE_ALL_ACCESS, 
                pServiceDesc->uServiceType, starttype, SERVICE_ERROR_NORMAL,pServiceDesc->uExePath,
                NULL, NULL, NULL, NULL, NULL);

if(!hservice) {
    vPrepareError(_TEXT("Failed to create service.!!"));
    goto err;        
}

// Set the description string
if(pServiceDesc->uServiceDescription && *pServiceDesc->uServiceDescription) {     
    desc.lpDescription = pServiceDesc->uServiceDescription;
    // This cannot be executed since it is not supported in Win98 and ME OS
    //(Void)ChangeServiceConfig2 (hservice, SERVICE_CONFIG_DESCRIPTION, &desc);
    hmod = LoadLibrary(_TEXT("Advapi32.dll"));
    if(hmod) {
          // _UNICODE macro is set, hence im using the "W" version of the api
          fpsvcdesc = (ChgSvcDesc)GetProcAddress(hmod, "ChangeServiceConfig2W");      
          if(fpsvcdesc)
               // On execution of the below statement, I get the error handle is invalid
               fpsvcdesc(hservice, SERVICE_CONFIG_DESCRIPTION, &desc);
}

CloseServiceHandle(hservice);
CloseServiceHandle(hservicemgr);    
return TRUE;

err:
    if(hservicemgr) 
       CloseServiceHandle(hservicemgr);
return FALSE;
}

我多次调试代码以找出为什么我得到句柄无效错误?在直接调用 API 时,服务的描述正在改变,但使用函数指针会给出错误。

我认为 API 正在向 SCM 的服务句柄写入一些东西,但我不知道为什么?

有人可以帮我吗?

4

1 回答 1

2

您的函数指针是在未指定调用约定的情况下声明的。默认调用约定是__cdecl. 但 Windows API 函数是__stdcall. 您需要将调用约定添加到函数指针类型。

typedef BOOL (__stdcall *ChgSvcDesc) (SC_HANDLE hService, 
    DWORD dwInfoLevel, LPVOID lpInfo);
于 2012-12-20T09:09:30.513 回答