2009-10-20 30 views

回答

4

可以檢索與當前線程與GetUserName相關聯的用戶名:

// ANSI version  
string GetWindowsUserNameA() 
    { 
     char buffer[UNLEN + 1] = {0}; 
     DWORD buffer_len = UNLEN + 1; 
     if (!::GetUserNameA(buffer, & buffer_len)) 
     { 
      // error handling 
     } 

     return string(buffer); 
    } 
+1

GetUserName()在Windows上運行的每一個版本,你不能相信在MSDN – Anders 2009-10-20 20:29:21

+0

@Anders上市最少的版本,你是對的,我已經編輯,謝謝。 – KeatsPeeks 2009-10-20 21:11:00

+0

@Anders你是否確實可以在Win32平臺上工作? – user877329 2014-12-31 13:39:29

0
在DOTNET的

- Environment.UserName

+0

這個問題指定了C++。除非OP願意移動到C++/CLI,否則這沒有幫助。 – ephemient 2009-10-20 18:10:23

2

Windows的最接近一個UID當量爲(可能是)一個SID。 GetUserName,然後LookupAccountName應該讓你的用戶的SID。

4

在Windows equivilent實際上是用戶的SID。您可以通過使用「GetTokenInformation」調用並查詢TokenUser信息類來獲得此信息。

要調用GetTokenInformation,你需要一個句柄用戶令牌,您可以通過調用OpenProcessToken(或OpenThreadToken如果你是假冒他人)獲得。

+0

我相信這會得到有關用於運行進程的SID的信息,所以它基本上等同於'geteuid()'而不是'getuid()'。 – 2009-10-20 14:30:56

0

合適的API是SHGetUID(),從殼牌

0

出口這是我想出了。

#include <stdint.h> 
#include <stdlib.h> 
#include <Windows.h> 
#include <sddl.h> 

#include <iostream> 
#include <iomanip> 
#include <memory> 

struct heap_delete 
{ 
    typedef LPVOID pointer; 
    void operator()(LPVOID p) 
    { 
     ::HeapFree(::GetProcessHeap(), 0, p); 
    } 
}; 
typedef std::unique_ptr<LPVOID, heap_delete> heap_unique_ptr; 

struct handle_delete 
{ 
    typedef HANDLE pointer; 
    void operator()(HANDLE p) 
    { 
     ::CloseHandle(p); 
    } 
}; 
typedef std::unique_ptr<HANDLE, handle_delete> handle_unique_ptr; 

typedef uint32_t uid_t; 

BOOL GetUserSID(HANDLE token, PSID* sid) 
{ 
    if (
     token == nullptr || token == INVALID_HANDLE_VALUE 
     || sid == nullptr 
     ) 
    { 
     SetLastError(ERROR_INVALID_PARAMETER); 
     return FALSE; 
    } 
    DWORD tokenInformationLength = 0; 
    ::GetTokenInformation(
     token, TokenUser, nullptr, 0, &tokenInformationLength); 
    if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
    { 
     return FALSE; 
    } 
    heap_unique_ptr data(
     ::HeapAlloc(
      ::GetProcessHeap(), HEAP_ZERO_MEMORY,  
      tokenInformationLength)); 
    if (data.get() == nullptr) 
    { 
     return FALSE; 
    } 
    BOOL getTokenInfo = ::GetTokenInformation(
     token, TokenUser, data.get(), 
     tokenInformationLength, &tokenInformationLength); 
    if (! getTokenInfo) 
    { 
     return FALSE; 
    } 
    PTOKEN_USER pTokenUser = (PTOKEN_USER)(data.get()); 
    DWORD sidLength = ::GetLengthSid(pTokenUser->User.Sid); 
    heap_unique_ptr sidPtr(
     ::HeapAlloc(
      GetProcessHeap(), HEAP_ZERO_MEMORY, sidLength)); 
    PSID sidL = (PSID)(sidPtr.get()); 
    if (sidL == nullptr) 
    { 
     return FALSE; 
    } 
    BOOL copySid = ::CopySid(sidLength, sidL, pTokenUser->User.Sid); 
    if (! copySid) 
    { 
     return FALSE; 
    } 
    if (!IsValidSid(sidL)) 
    { 
     return FALSE; 
    } 
    *sid = sidL; 
    sidPtr.release(); 
    return TRUE; 
} 

uid_t GetUID(HANDLE token) 
{ 
    PSID sid = nullptr; 
    BOOL getSID = GetUserSID(token, &sid); 
    if (! getSID || ! sid) 
    { 
     return -1; 
    } 
    heap_unique_ptr sidPtr((LPVOID)(sid)); 
    LPWSTR stringSid = nullptr; 
    BOOL convertSid = ::ConvertSidToStringSidW(
     sid, &stringSid); 
    if (! convertSid) 
    { 
     return -1; 
    } 
    uid_t ret = -1; 
    LPCWSTR p = ::wcsrchr(stringSid, L'-'); 
    if (p && ::iswdigit(p[1])) 
    { 
     ++p; 
     ret = ::_wtoi(p); 
    } 
    ::LocalFree(stringSid); 
    return ret; 
} 

uid_t getuid() 
{ 
    HANDLE process = ::GetCurrentProcess(); 
    handle_unique_ptr processPtr(process); 
    HANDLE token = nullptr; 
    BOOL openToken = ::OpenProcessToken(
     process, TOKEN_READ|TOKEN_QUERY_SOURCE, &token); 
    if (! openToken) 
    { 
     return -1; 
    } 
    handle_unique_ptr tokenPtr(token); 
    uid_t ret = GetUID(token); 
    return ret; 
} 

uid_t geteuid() 
{ 
    HANDLE process = ::GetCurrentProcess(); 
    HANDLE thread = ::GetCurrentThread(); 
    HANDLE token = nullptr; 
    BOOL openToken = ::OpenThreadToken(
     thread, TOKEN_READ|TOKEN_QUERY_SOURCE, FALSE, &token); 
    if (! openToken && ::GetLastError() == ERROR_NO_TOKEN) 
    { 
     openToken = ::OpenThreadToken(
      thread, TOKEN_READ|TOKEN_QUERY_SOURCE, TRUE, &token); 
     if (! openToken && ::GetLastError() == ERROR_NO_TOKEN) 
     { 
      openToken = ::OpenProcessToken(
       process, TOKEN_READ|TOKEN_QUERY_SOURCE, &token); 
     } 
    } 
    if (! openToken) 
    { 
     return -1; 
    } 
    handle_unique_ptr tokenPtr(token); 
    uid_t ret = GetUID(token); 
    return ret; 
} 

int main() 
{ 
    uid_t uid = getuid(); 
    uid_t euid = geteuid(); 
    std::cout 
     << "uid: " << std::setbase(10) << uid << std::endl 
     << "euid: " << std::setbase(10) << euid << std::endl 
     << std::endl; 
    return EXIT_SUCCESS; 
} 

請注意,由Larry Osterman給出的答案是非常有幫助的。這讓我開始了正確的方向。