summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qfilesystemengine_win.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2012-01-12 15:43:07 +0200
committerQt by Nokia <qt-info@nokia.com>2012-01-13 11:30:43 +0100
commit49c5c3e5c530dd40f3ac3e3254a3237b0745daea (patch)
treec20de0ff1453e581d7699bb276016d6cadac0208 /src/corelib/io/qfilesystemengine_win.cpp
parent2fab348c81130a0c81eea92cc155c278e260b25c (diff)
Windows: Fix qt_ntfs_permission_lookup
Specifying qt_ntfs_permission_lookup++ in application code didn't make qfilesystemengine_win.cpp respect Windows ACL as it was supposed to. This was because GetTokenInformation for TokenUser failed always in resolveLibs() function, because the TOKEN_USER struct that was given to it wasn't large enough to contain both TOKEN_USER and SID structs that GetTokenInformation wants to return in this case. Fixed by calling GetTokenInformation twice, first to determine the required size, and then another time to get the actual token info. Additionally, the SID returned as part of the token info needs to be stored for the lifetime of the application, as the TRUSTEE_W struct has a pointer to it (currentUserTrusteeW). The worldTrusteeW initialization also required a change to properly store the SID. Note: The dynamic resolution of FreeSid and other SID manipulating functions doesn't appear to be necessary, as they are found on the same ifdef level (in winbase.h) as the GetTokenInformation, which already isn't dynamically resolved. Task-number: QTBUG-247 Change-Id: I0294c85ea903c86d03c2fcd3d801502b378dc0e5 Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
Diffstat (limited to 'src/corelib/io/qfilesystemengine_win.cpp')
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 80f5448d40..d724429f6b 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -160,6 +160,31 @@ typedef DWORD (WINAPI *PtrGetEffectiveRightsFromAclW)(PACL, PTRUSTEE_W, OUT PACC
static PtrGetEffectiveRightsFromAclW ptrGetEffectiveRightsFromAclW = 0;
static TRUSTEE_W currentUserTrusteeW;
static TRUSTEE_W worldTrusteeW;
+static PSID currentUserSID = 0;
+static PSID worldSID = 0;
+
+/*
+ Deletes the allocated SIDs during global static cleanup
+*/
+class SidCleanup
+{
+public:
+ ~SidCleanup();
+};
+
+SidCleanup::~SidCleanup()
+{
+ qFree(currentUserSID);
+ currentUserSID = 0;
+
+ // worldSID was allocated with AllocateAndInitializeSid so it needs to be freed with FreeSid
+ if (worldSID) {
+ ::FreeSid(worldSID);
+ worldSID = 0;
+ }
+}
+
+Q_GLOBAL_STATIC(SidCleanup, initSidCleanup)
typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD);
static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0;
@@ -199,25 +224,35 @@ static void resolveLibs()
// Create TRUSTEE for current user
HANDLE hnd = ::GetCurrentProcess();
HANDLE token = 0;
+ initSidCleanup();
if (::OpenProcessToken(hnd, TOKEN_QUERY, &token)) {
- TOKEN_USER tu;
- DWORD retsize;
- if (::GetTokenInformation(token, TokenUser, &tu, sizeof(tu), &retsize))
- ptrBuildTrusteeWithSidW(&currentUserTrusteeW, tu.User.Sid);
+ DWORD retsize = 0;
+ // GetTokenInformation requires a buffer big enough for the TOKEN_USER struct and
+ // the SID struct. Since the SID struct can have variable number of subauthorities
+ // tacked at the end, its size is variable. Obtain the required size by first
+ // doing a dummy GetTokenInformation call.
+ ::GetTokenInformation(token, TokenUser, 0, 0, &retsize);
+ if (retsize) {
+ void *tokenBuffer = qMalloc(retsize);
+ if (::GetTokenInformation(token, TokenUser, tokenBuffer, retsize, &retsize)) {
+ PSID tokenSid = reinterpret_cast<PTOKEN_USER>(tokenBuffer)->User.Sid;
+ DWORD sidLen = ::GetLengthSid(tokenSid);
+ currentUserSID = reinterpret_cast<PSID>(qMalloc(sidLen));
+ if (::CopySid(sidLen, currentUserSID, tokenSid))
+ ptrBuildTrusteeWithSidW(&currentUserTrusteeW, currentUserSID);
+ }
+ qFree(tokenBuffer);
+ }
::CloseHandle(token);
}
typedef BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*);
PtrAllocateAndInitializeSid ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid");
- typedef PVOID (WINAPI *PtrFreeSid)(PSID);
- PtrFreeSid ptrFreeSid = (PtrFreeSid)GetProcAddress(advapiHnd, "FreeSid");
- if (ptrAllocateAndInitializeSid && ptrFreeSid) {
+ if (ptrAllocateAndInitializeSid) {
// Create TRUSTEE for Everyone (World)
SID_IDENTIFIER_AUTHORITY worldAuth = { SECURITY_WORLD_SID_AUTHORITY };
- PSID pWorld = 0;
- if (ptrAllocateAndInitializeSid(&worldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pWorld))
- ptrBuildTrusteeWithSidW(&worldTrusteeW, pWorld);
- ptrFreeSid(pWorld);
+ if (ptrAllocateAndInitializeSid(&worldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &worldSID))
+ ptrBuildTrusteeWithSidW(&worldTrusteeW, worldSID);
}
}
HINSTANCE userenvHnd = QSystemLibrary::load(L"userenv");