windows Win32 等价于 getuid()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1594746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Win32 equivalent of getuid()
提问by StevieG
I'm in the process of porting a C++ library from Linux to Windows, and am having problems with getuid(), which is not supported in Windows.
我正在将 C++ 库从 Linux 移植到 Windows,并且在使用 Windows 不支持的 getuid() 时遇到问题。
Any ideas what I can use in its place?
我可以用什么来代替它的任何想法?
回答by KeatsPeeks
You can retrieves the name of the user associated with the current thread with GetUserName:
您可以使用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);
}
回答by ReinstateMonica Larry Osterman
The Windows equivilent is actually the user's SID. You can get this by using the "GetTokenInformation" call and querying for the TokenUser information class.
Windows 等效项实际上是用户的 SID。您可以通过使用“ GetTokenInformation”调用并查询 TokenUser 信息类来获取此信息。
To call GetTokenInformation, you need a handle to the users token, which you can get by calling OpenProcessToken (or OpenThreadToken if you're impersonating someone).
要调用 GetTokenInformation,您需要一个用户令牌的句柄,您可以通过调用 OpenProcessToken(或 OpenThreadToken,如果您要冒充某人)来获取该句柄。
回答by Jerry Coffin
Windows' closest equivalent of a UID is (probably) a SID. GetUserName
followed by LookupAccountName
should get you the user's SID.
Windows 最接近的 UID 等价物(可能)是 SID。GetUserName
其次LookupAccountName
应该为您提供用户的 SID。
回答by Ben Key
This is what I came up with.
这就是我想出的。
#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;
}
Note that the answer given by Larry Ostermanwas very helpful. It got me started in the correct direction.
请注意,拉里·奥斯特曼( Larry Osterman)给出的答案非常有帮助。它让我朝着正确的方向开始。
回答by Epsilon Prime
Check out Microsoft's recommendations on porting with the Interix (also known as Services for UNIX 3.0)library. Overkill for what you want though.
查看 Microsoft 关于移植Interix(也称为 UNIX 3.0 服务)库的建议。不过,你想要的东西太过分了。
回答by Dani
in DotNet - Environment.UserName
在 DotNet 中 - Environment.UserName
回答by marcus
The right api is SHGetUID(), exported from Shell
正确的api是SHGetUID(),从Shell导出