我正在尝试设置PROCESS_TERMINATE的安全性。这是代码:
CreateProcess("C:\\ADP\\SQLBase\\dbntsrv.exe", NULL, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, "C:\\ADP\\SQLBase", &si, &pi);
if(SetSecurityInfo(pi.hProcess, SE_KERNEL_OBJECT, PROCESS_TERMINATE, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
MessageBox(NULL, "process_terminate granted", NULL, MB_OK);
}
else
{
MessageBox(NULL, "process_terminate not granted", NULL, MB_OK);
}
//--------------------- Permission to query for info to use GetExitCode -------------------------
if(SetSecurityInfo(pi.hProcess, SE_KERNEL_OBJECT, PROCESS_QUERY_INFORMATION, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
MessageBox(NULL, "process_query_information granted", NULL, MB_OK);
}
else
{
MessageBox(NULL, "process_query_information not granted", NULL, MB_OK);
}
LPDWORD lpExitCode;
GetExitCodeProcess(pi.hProcess, lpExitCode);
这里为PROCESS_TERMINATE的SetSecurityInfo失败,我得到了Unhandled Exception..(KERNEL32.dll):Access Violation
GetExitCodeProcess(pi.hProcess, lpExitCode);
为什么会这样?谢谢
答案 0 :(得分:4)
访问冲突是因为此代码:
LPDWORD lpExitCode;
GetExitCodeProcess(pi.hProcess, lpExitCode);
这里你声明lpExitCode
是一个指针,但是你没有指出任何东西。当GetExitCodeProcess
尝试写入*lpExitCode
时,会导致访问冲突。
正确的方法是这样的:
DWORD ExitCode;
GetExitCodeProcess(pi.hProcess, &ExitCode);
我也不相信你需要打电话给SetSecurityInfo
。 CreateProcess
返回的进程句柄应该具有足够的权限。
您需要等待生成的进程终止,然后才能获得退出代码。这是因为GetExitCodeProcess
是异步的。你可以这样等: p>
WaitForSingleObject(pi.hProcess);
//now you can call GetExitCodeProcess and expect an answer.
请务必检查所有API调用是否有错误。
答案 1 :(得分:3)
除了对GetExitCodeProcess
的通话电话外,您对SetSecurityInfo
的通话也不正确。 PROCESS_TERMINATE
不是第三个参数的有效值。根据{{3}},第三个参数的有效值为
OWNER_SECURITY_INFORMATION:包括所有者。
GROUP_SECURITY_INFORMATION:包括主要群组。
DACL_SECURITY_INFORMATION:包含自主访问控制列表(DACL)。
SACL_SECURITY_INFORMATION:包括系统访问控制列表(SACL)。
LABEL_SECURITY_INFORMATION:包含强制完整性标签访问控制条目(ACE)。
ATTRIBUTE_SECURITY_INFORMATION:包含SACL的属性信息。
SCOPE_SECURITY_INFORMATION:包括SACL的中央访问策略(CAP)标识符。
您PROCESS_TERMINATE
的值恰好在数字上等于OWNER_SECURITY_INFORMATION
,因此您的调用实际上是在尝试更改进程所有者(但这是错误的,这就是调用失败的原因)。