On 16/03/2023 17:18, Kevin Connor Arpe wrote:
Hello,
This is my first time posting to this mailing list. (This email is a bit long... sorry!) I am a developer writing Win32 code using Wine on Debian Linux. I tried to use the Win32 API function GetTempPath2W(), but my Wine version does not support it. I checked out the Wine source code and found GetTempPathW() here: dlls/kernelbase/file.c ... but did not find GetTempPath2W().
First, if this function is already in the pipeline (another feature branch, etc.), please let me know... and ignore the rest of this email! :-)
From GetTempPathW() docs: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gette... "Note: Apps should call GetTempPath2 instead of GetTempPath."
From GetTempPath2W() docs: "When calling this function from a process running as SYSTEM it will return the path C:\Windows\SystemTemp"
The implementation looks rather straightforward except this part: "process running as SYSTEM". How to detect this? I found a good blog post from (the legend) Raymond Chen: https://devblogs.microsoft.com/oldnewthing/20210106-00/?p=104669
Sample code looks like this: << #include <wil/token_helpers.h>
bool DoesTokenRepresentSid(HANDLE token, WELL_KNOWN_SID_TYPE type) { // maps to GetTokenInformation(token, TokenUser, ...); auto user = wil::get_token_information<TOKEN_USER>(token); return !!IsWellKnownSid(user->User.Sid, type); }
bool IsCurrentProcessRunningAsSystem() { return DoesTokenRepresentSid(GetCurrentProcessToken(), WinLocalSystemSid); }
bool IsCurrentThreadRunningAsSystem() { return DoesTokenRepresentSid(GetCurrentThreadEffectiveToken(), WinLocalSystemSid); }
Reading the WIL source code on GitHub, I understand the required Win32 calls. In short, I plan to re-write the above same code using pure Win32 code (remove the WIL requirement).
My questions:
- Do you agree with Raymond Chen's technique for Wine source code? (Or: Is there a better way to do it for Wine source code?)
- Should my SYSTEM account test use IsCurrentProcessRunningAsSystem() or IsCurrentThreadRunningAsSystem()? If I read the official docs literally, I think "process" not "thread". Please advise.
- Reading the WIL code: TOKEN_INFORMATION_CLASS TokenUser appears to require this pattern: 1. Call GetTokenInformation() to get required buffer size 2. malloc buffer 3. Call GetTokenInformation() again with buffer 4. Check: WinLocalSystemSid == ((TOKEN_USER *) buffer)->User.Sid 5. free buffer
- Is there a way to avoid the above steps? malloc+free seems like overkill to decide if the current user is SYSTEM!
- Do I misunderstand the WIL code? Reading the Wine code for: GetTokenInformation() -> NtQueryInformationToken(): TOKEN_USER appears to be fixed size. Why does WIL think TOKEN_USER is not fixed size? I am confused! :-)
Kind regards, Kevin Connor ARPE Tokyo, Japan
Why not something like:
TOKEN_USER user_token; DWORD len;
if (!GetTokenInformation(GetCurrentProcessToken(), TokenUser, &user_token, sizeof(user_token), &len)) return FALSE;
return IsWellKnownSid(user_token.User.Sid, WinLocalSystemSid);
I'm not familiar with the APIs, nor do I know if Wine implements them properly, but there shouldn't be any need for malloc/free.