學習任務管理器中進程管理部分發現問題.
可以使用進程枚舉出所有進程,但是處理進程的時候總是出現問題,無法操作進程,包括訪問,結束.代碼如下:
HANDLE hProcess=INVALID_HANDLE_VALUE;
HANDLE hSnapshot=INVALID_HANDLE_VALUE;
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 pe;
Process32First(hSnapshot,&pe);
do
{
// do what you want
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe.th32ProcessID);
if(hProcess==NULL) {
_stprintf(szTemp,"OpenProcess() fail\n %d\n%s",GetLastError(),pe.szExeFile);
wsprintf(szExePath,_T("%s"),"not get Process handle OpenProcess()");
}else if(0==GetModuleFileNameEx((HINSTANCE)hProcess,NULL,szExePath,MAX_PATH))
{
_stprintf(szTemp,"GetModuleFileName() fail %d\n%s\n%s",GetLastError(),pe.szExeFile,szExePath);
wsprintf(szExePath,_T("%s"),"not get Process handle GetModuleFileName()");
}
}
while(Process32Next(hSnapshot,&pe));
CloseHandle(hSnapshot);
OpenProcess() 錯誤ERROR CODE 5:拒絕訪問.需要取得相應的權限.
OpenProcessToken函數的功能是打開一個與一進程相聯系的訪問令牌(access token),它的原型如下:
BOOL OpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle
);
如同MSDN上所說,對于Windows XP Professional,如果一臺計算機加入到一個工作組中,而且"Force network logons using local accounts to authenticate as Guest"的限制被激活的話,此函數會失敗。
另外,如果在調用的時候使用了TOKEN_ALL_ACCESS請求,函數也可能會失敗。這是因為TOKEN_ALL_ACCESS可能包含了TOKEN_ADJUST_SESSIONID(在Winnt.h中被定義)。TOKEN_ADJUST_SESSIONID是一個新的訪問mask,是在Windows 2000和Windows XP中新增的。在Windows NT 4.0中,訪問令牌的訪問控制列表中是沒有這個值的。所以,如果一個應用程序是使用新的Platform SDK中的Winnt.h但卻在Windows NT 4.0下運行的話,在調用OpenProcessToken()或者OpenThreadToken時指定了TOKEN_ALL_ACCESS的話,函數也會失敗(使用GetLastError()返回的是ERROR_ACCESS_DENIED)。
typedef struct _TOKEN_PRIVILEGES {
DWORD PrivilegeCount;
LUID_AND_ATTRIBUTES PrivilegeCount;
LUID_AND_ATTRIBUTES Privileges[]; } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, // handle to token
BOOL TokenHandle, // handle to token
BOOL DisableAllPrivileges, // disabling option
PTOKEN_PRIVILEGES NewState, // privilege information
DWORD NewState, // privilege information
DWORD BufferLength, // size of buffer
PTOKEN_PRIVILEGES PreviousState, // original state buffer
PDWORD PreviousState, // original state buffer
PDWORD ReturnLength // required buffer size
);
在枚舉所有進程之前獲取操作權限,就可以避免出錯的問題,當然參數要設置為Enable.
BOOL ProcessPrivilege(BOOL bEnable)
{
BOOL bResult = TRUE;
HANDLE hToken=INVALID_HANDLE_VALUE;
TOKEN_PRIVILEGES TokenPrivileges;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken) == 0)
{
printf("OpenProcessToken Error: %d\n",GetLastError());
bResult = FALSE;
}
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&TokenPrivileges.Privileges[0].Luid);
AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
if(GetLastError() != ERROR_SUCCESS)
{
bResult = FALSE;
}
CloseHandle(hToken);
return bResult;
}
THAT'S ALL.