#winapi #rust
#winapi #Ржавчина
Вопрос:
Я пытаюсь получить пользователя, который связан с PID в Windows.
Я смотрю на источник для NTop https://github.com/gsass1/NTop в качестве примера.
Я могу создавать и отлаживать исходный код NTop на Clion, и следующий код работает правильно.
HANDLE ProcessTokenHandle;
if(OpenProcessToken(Process.Handle, TOKEN_READ, amp;ProcessTokenHandle)) {
DWORD ReturnLength;
GetTokenInformation(ProcessTokenHandle, TokenUser, 0, 0, amp;ReturnLength);
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
PTOKEN_USER TokenUserStruct = xmalloc(ReturnLength);
if(GetTokenInformation(ProcessTokenHandle, TokenUser, TokenUserStruct, ReturnLength, amp;ReturnLength)) {
SID_NAME_USE NameUse;
DWORD NameLength = UNLEN;
TCHAR DomainName[MAX_PATH];
DWORD DomainLength = MAX_PATH;
LookupAccountSid(0, TokenUserStruct->User.Sid, Process.UserName, amp;NameLength, DomainName, amp;DomainLength, amp;NameUse);
// FIXME: we cut user name here for display purposes because something like %9.9s does not work with MS's vsprintf function?
Process.UserName[9] = 0;
}
free(TokenUserStruct);
}
CloseHandle(ProcessTokenHandle);
}
При попытке сделать то же самое с помощью rust winapi я получаю ERROR_NOACCESS
каждый раз, что бы я ни делал.
Вот несколько примеров кода, который возвращается 0
в качестве кода ответа из OpenProcessToken, и GetLastError будет ERROR_NOACCESS
. Не имеет значения, запускаю ли я программу от имени администратора или нет.
let pid: u32 = 8664; // process that is owned by me but can be any process, it will never work
let process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid);
let mut process_token_handle: PHANDLE = null_mut();
let s = OpenProcessToken(process_handle, TOKEN_READ, process_token_handle);
let last_error = GetLastError();
У кого-нибудь есть идеи, почему этот код будет работать в NTop с использованием C api и не будет работать с использованием rust winapi?
Комментарии:
1. В документах
OpenProcessToken
говорится: «Процесс должен иметь разрешение доступа PROCESS_QUERY_INFORMATION». Однако вы открыли процесс сPROCESS_QUERY_LIMITED_INFORMATION
помощью , который, как следует из названия, более ограничен. ПопробуйтеPROCESS_QUERY_INFORMATION
вместо этого?2. Как только это будет исправлено, вам нужно будет перечитать документацию для OpenProcessToken . Последний аргумент ожидает (действительный) указатель на a
HANDLE
. Вместо этого вы передаете нулевой указатель.process_token_handle
должно быть типаHANDLE
. Возможно , здесь также можно использовать uninit, поскольку это указатель out. В любом случае, вы должны передать его адрес вOpenProcessToken
так же, как это делает реализация C.3. Похоже, эти предложения были правильными. Ключ должен был использовать HANDLE вместо PHANDLE и передать ссылку на него.