Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / sal / osl / w32 / security.c
blob84d01bb72f189cfdea2ad09f65c70a874720c80c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "system.h"
23 #include <osl/security.h>
24 #include <osl/diagnose.h>
25 #include <osl/thread.h>
26 #include <osl/file.h>
27 #include <systools/win32/uwinapi.h>
28 #include <sal/macros.h>
29 #include "secimpl.h"
31 /*****************************************************************************/
32 /* Data Type Definition */
33 /*****************************************************************************/
36 /* Data for use in (un)LoadProfile Functions */
37 /* Declarations based on USERENV.H for Windows 2000 Beta 2 */
38 #define PI_NOUI 0x00000001 // Prevents displaying of messages
40 typedef struct _PROFILEINFOW {
41 DWORD dwSize; // Must be set to sizeof(PROFILEINFO)
42 DWORD dwFlags; // See flags above
43 LPWSTR lpUserName; // User name (required)
44 LPWSTR lpProfilePath; // Roaming profile path
45 LPWSTR lpDefaultPath; // Default user profile path
46 LPWSTR lpServerName; // Validating DC name in netbios format
47 LPWSTR lpPolicyPath; // Path to the NT4 style policy file
48 HANDLE hProfile; // Registry key handle - filled by function
49 } PROFILEINFOW, FAR * LPPROFILEINFOW;
51 /* Typedefs for function pointers in USERENV.DLL */
52 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
53 HANDLE hToken,
54 LPPROFILEINFOW lpProfileInfo
57 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
58 HANDLE hToken,
59 HANDLE hProfile
62 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
63 HANDLE hToken,
64 LPTSTR lpProfileDir,
65 LPDWORD lpcchSize
68 /* To get an impersonation token we need to create an impersonation
69 duplicate so every access token has to be created with duplicate
70 access rights */
72 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
74 /*****************************************************************************/
75 /* Static Module Function Declarations */
76 /*****************************************************************************/
78 static sal_Bool GetSpecialFolder(rtl_uString **strPath,int nFolder);
79 static BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable);
80 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain);
82 /*****************************************************************************/
83 /* Exported Module Functions */
84 /*****************************************************************************/
86 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
88 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
90 pSecImpl->m_pNetResource = NULL;
91 pSecImpl->m_User[0] = '\0';
92 pSecImpl->m_hToken = NULL;
93 pSecImpl->m_hProfile = NULL;
95 return ((oslSecurity)pSecImpl);
98 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
100 oslSecurityError ret;
102 sal_Unicode* strUser;
103 sal_Unicode* strDomain = _wcsdup(rtl_uString_getStr(strUserName));
104 HANDLE hUserToken;
106 #if OSL_DEBUG_LEVEL > 0
107 LUID luid;
108 #endif
110 if (NULL != (strUser = wcschr(strDomain, L'/')))
111 *strUser++ = L'\0';
112 else
114 strUser = strDomain;
115 strDomain = NULL;
118 // this process must have the right: 'act as a part of operatingsystem'
119 OSL_ASSERT(LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid));
121 if (LogonUserW(strUser, strDomain ? strDomain : L"", rtl_uString_getStr(strPasswd),
122 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
123 &hUserToken))
125 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
127 pSecImpl->m_pNetResource = NULL;
128 pSecImpl->m_hToken = hUserToken;
129 pSecImpl->m_hProfile = NULL;
130 wcscpy(pSecImpl->m_User, strUser);
132 *pSecurity = (oslSecurity)pSecImpl;
133 ret = osl_Security_E_None;
135 else
136 ret = osl_Security_E_UserUnknown;
138 if (strDomain)
139 free(strDomain);
140 else
141 free(strUser);
143 return ret;
146 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
147 rtl_uString *strPasswd,
148 rtl_uString *strFileServer,
149 oslSecurity *pSecurity)
151 oslSecurityError ret;
152 DWORD err;
153 NETRESOURCEW netResource;
154 sal_Unicode* remoteName;
155 sal_Unicode* userName;
157 remoteName = malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4) * sizeof(sal_Unicode));
158 userName = malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2) * sizeof(sal_Unicode));
160 wcscpy(remoteName, L"\\\\");
161 wcscat(remoteName, rtl_uString_getStr(strFileServer));
162 wcscat(remoteName, L"\\");
163 wcscat(remoteName, rtl_uString_getStr(strUserName));
165 wcscpy(userName, rtl_uString_getStr(strFileServer));
166 wcscat(userName, L"\\");
167 wcscat(userName, rtl_uString_getStr(strUserName));
169 netResource.dwScope = RESOURCE_GLOBALNET;
170 netResource.dwType = RESOURCETYPE_DISK;
171 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
172 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
173 netResource.lpLocalName = NULL;
174 netResource.lpRemoteName = remoteName;
175 netResource.lpComment = NULL;
176 netResource.lpProvider = NULL;
178 err = WNetAddConnection2W(&netResource, rtl_uString_getStr(strPasswd), userName, 0);
180 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
182 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
184 pSecImpl->m_pNetResource = malloc(sizeof(NETRESOURCE));
185 *pSecImpl->m_pNetResource = netResource;
187 pSecImpl->m_hToken = NULL;
188 pSecImpl->m_hProfile = NULL;
189 wcscpy(pSecImpl->m_User, rtl_uString_getStr(strUserName));
191 *pSecurity = (oslSecurity)pSecImpl;
193 ret = osl_Security_E_None;
195 else
196 ret = osl_Security_E_UserUnknown;
198 free(remoteName);
199 free(userName);
201 return ret;
205 static BOOL WINAPI CheckTokenMembership_Stub( HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember )
207 typedef BOOL (WINAPI *CheckTokenMembership_PROC)( HANDLE, PSID, PBOOL );
209 static HMODULE hModule = NULL;
210 static CheckTokenMembership_PROC pCheckTokenMembership = NULL;
212 if ( !hModule )
214 /* SAL is always linked against ADVAPI32 so we can rely on that it is already mapped */
216 hModule = GetModuleHandleA( "ADVAPI32.DLL" );
218 pCheckTokenMembership = (CheckTokenMembership_PROC)GetProcAddress( hModule, "CheckTokenMembership" );
221 if ( pCheckTokenMembership )
222 return pCheckTokenMembership( TokenHandle, SidToCheck, IsMember );
223 else
225 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
226 return FALSE;
232 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
234 if (Security != NULL)
236 HANDLE hImpersonationToken = NULL;
237 PSID psidAdministrators;
238 SID_IDENTIFIER_AUTHORITY siaNtAuthority = { SECURITY_NT_AUTHORITY };
239 sal_Bool bSuccess = sal_False;
242 /* If Security contains an access token we need to duplicate it to an impersonation
243 access token. NULL works with CheckTokenMembership() as the current effective
244 impersonation token
247 if ( ((oslSecurityImpl*)Security)->m_hToken )
249 if ( !DuplicateToken (((oslSecurityImpl*)Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
250 return sal_False;
253 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
254 and also works on Vista to retrieve the effective user rights. Just checking for
255 membership of Administrators group is not enough on Vista this would require additional
256 complicated checks as described in KB arcticle Q118626: http://support.microsoft.com/kb/118626/en-us
259 if (AllocateAndInitializeSid(&siaNtAuthority,
261 SECURITY_BUILTIN_DOMAIN_RID,
262 DOMAIN_ALIAS_RID_ADMINS,
263 0, 0, 0, 0, 0, 0,
264 &psidAdministrators))
266 BOOL fSuccess = FALSE;
268 if ( CheckTokenMembership_Stub( hImpersonationToken, psidAdministrators, &fSuccess ) && fSuccess )
269 bSuccess = sal_True;
271 FreeSid(psidAdministrators);
274 if ( hImpersonationToken )
275 CloseHandle( hImpersonationToken );
277 return (bSuccess);
279 else
280 return (sal_False);
284 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
286 if (Security)
288 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
290 if (pSecImpl->m_pNetResource != NULL)
292 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, sal_True);
294 free(pSecImpl->m_pNetResource->lpRemoteName);
295 free(pSecImpl->m_pNetResource);
298 if (pSecImpl->m_hToken)
299 CloseHandle(pSecImpl->m_hToken);
301 if ( pSecImpl->m_hProfile )
302 CloseHandle(pSecImpl->m_hProfile);
304 free (pSecImpl);
309 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
311 if (Security != NULL)
313 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
315 HANDLE hAccessToken = pSecImpl->m_hToken;
317 if (hAccessToken == NULL)
318 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
320 if (hAccessToken)
322 sal_Char *Ident;
323 DWORD nInfoBuffer = 512;
324 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
327 while (!GetTokenInformation(hAccessToken, TokenUser,
328 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
330 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
331 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
332 else
334 free(pInfoBuffer);
335 pInfoBuffer = NULL;
336 break;
340 if (pSecImpl->m_hToken == NULL)
341 CloseHandle(hAccessToken);
343 if (pInfoBuffer)
345 PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid;
346 PSID_IDENTIFIER_AUTHORITY psia;
347 DWORD dwSubAuthorities;
348 DWORD dwSidRev=SID_REVISION;
349 DWORD dwCounter;
350 DWORD dwSidSize;
351 PUCHAR pSSACount;
353 /* obtain SidIdentifierAuthority */
354 psia=GetSidIdentifierAuthority(pSid);
356 /* obtain sidsubauthority count */
357 pSSACount = GetSidSubAuthorityCount(pSid);
358 dwSubAuthorities = (*pSSACount < 5) ? *pSSACount : 5;
360 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
361 Ident=malloc(88*sizeof(sal_Char));
363 /* prepare S-SID_REVISION- */
364 dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
366 /* prepare SidIdentifierAuthority */
367 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
369 dwSidSize+=wsprintf(Ident + strlen(Ident),
370 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
371 (USHORT)psia->Value[0],
372 (USHORT)psia->Value[1],
373 (USHORT)psia->Value[2],
374 (USHORT)psia->Value[3],
375 (USHORT)psia->Value[4],
376 (USHORT)psia->Value[5]);
378 else
380 dwSidSize+=wsprintf(Ident + strlen(Ident),
381 TEXT("%lu"),
382 (ULONG)(psia->Value[5] ) +
383 (ULONG)(psia->Value[4] << 8) +
384 (ULONG)(psia->Value[3] << 16) +
385 (ULONG)(psia->Value[2] << 24) );
388 /* loop through SidSubAuthorities */
389 for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
391 dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
392 *GetSidSubAuthority(pSid, dwCounter) );
395 rtl_uString_newFromAscii( strIdent, Ident );
397 free(pInfoBuffer);
398 free(Ident);
400 return (sal_True);
403 else
405 DWORD needed=0;
406 sal_Unicode *Ident;
408 WNetGetUserA(NULL, NULL, &needed);
409 if (needed < 16)
411 needed = 16;
413 Ident=malloc(needed*sizeof(sal_Unicode));
415 if (WNetGetUserW(NULL, Ident, &needed) != NO_ERROR)
417 wcscpy(Ident, L"unknown");
418 Ident[7] = L'\0';
421 rtl_uString_newFromStr( strIdent, Ident);
423 free(Ident);
425 return sal_True;
429 return sal_False;
434 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
436 return getUserNameImpl(Security, strName, sal_True);
440 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
442 rtl_uString *ustrSysDir = NULL;
443 sal_Bool bSuccess = sal_False;
445 if (Security != NULL)
447 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
449 if (pSecImpl->m_pNetResource != NULL)
451 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
453 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory ));
455 else
457 bSuccess = (sal_Bool)(GetSpecialFolder(&ustrSysDir, CSIDL_PERSONAL) &&
458 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory)));
462 if ( ustrSysDir )
463 rtl_uString_release( ustrSysDir );
465 return bSuccess;
468 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
470 sal_Bool bSuccess = sal_False;
472 if (Security != NULL)
474 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
476 if (pSecImpl->m_pNetResource != NULL)
478 rtl_uString *ustrSysDir = NULL;
480 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
481 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory));
483 if ( ustrSysDir )
484 rtl_uString_release( ustrSysDir );
486 else
488 if (pSecImpl->m_hToken)
490 /* not implemented */
491 OSL_ASSERT(sal_False);
493 else
495 rtl_uString *ustrFile = NULL;
496 sal_Unicode sFile[_MAX_PATH];
498 if ( !GetSpecialFolder( &ustrFile, CSIDL_APPDATA) )
500 OSL_VERIFY(GetWindowsDirectoryW(sFile, _MAX_DIR) > 0);
502 rtl_uString_newFromStr( &ustrFile, sFile);
505 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory));
507 if ( ustrFile )
508 rtl_uString_release( ustrFile );
513 return bSuccess;
517 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
519 /* CreateProcessAsUser does not load the specified user's profile
520 into the HKEY_USERS registry key. This means that access to information
521 in the HKEY_CURRENT_USER registry key may not produce results consistent
522 with a normal interactive logon.
523 It is your responsibility to load the user's registry hive into HKEY_USERS
524 with the LoadUserProfile function before calling CreateProcessAsUser.
526 BOOL bOk = FALSE;
528 RegCloseKey(HKEY_CURRENT_USER);
530 if (Privilege(SE_RESTORE_NAME, TRUE))
532 HMODULE hUserEnvLib = NULL;
533 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
534 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
535 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
537 /* try to create user profile */
538 if ( !hAccessToken )
540 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
542 HANDLE hProcess = GetCurrentProcess();
544 if (hProcess != NULL)
546 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
547 CloseHandle(hProcess);
551 hUserEnvLib = LoadLibraryA("userenv.dll");
553 if (hUserEnvLib)
555 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileW");
556 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
558 if (fLoadUserProfile && fUnloadUserProfile)
560 rtl_uString *buffer = 0;
561 PROFILEINFOW pi;
563 getUserNameImpl(Security, &buffer, sal_False);
565 ZeroMemory( &pi, sizeof(pi) );
566 pi.dwSize = sizeof(pi);
567 pi.lpUserName = rtl_uString_getStr(buffer);
568 pi.dwFlags = PI_NOUI;
570 if (fLoadUserProfile(hAccessToken, &pi))
572 fUnloadUserProfile(hAccessToken, pi.hProfile);
574 bOk = TRUE;
577 rtl_uString_release(buffer);
580 FreeLibrary(hUserEnvLib);
583 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
584 CloseHandle(hAccessToken);
587 return (sal_Bool)bOk;
591 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
593 if ( ((oslSecurityImpl*)Security)->m_hProfile != NULL )
595 HMODULE hUserEnvLib = NULL;
596 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
597 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
598 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
600 if ( !hAccessToken )
602 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
604 HANDLE hProcess = GetCurrentProcess();
606 if (hProcess != NULL)
608 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
609 CloseHandle(hProcess);
613 hUserEnvLib = LoadLibrary("userenv.dll");
615 if (hUserEnvLib)
617 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileA");
618 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
620 if (fLoadUserProfile && fUnloadUserProfile)
622 /* unloading the user profile */
623 if (fLoadUserProfile && fUnloadUserProfile)
624 fUnloadUserProfile(hAccessToken, ((oslSecurityImpl*)Security)->m_hProfile);
626 if (hUserEnvLib)
627 FreeLibrary(hUserEnvLib);
631 ((oslSecurityImpl*)Security)->m_hProfile = NULL;
633 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
635 CloseHandle(hAccessToken);
640 /*****************************************************************************/
641 /* Static Module Functions */
642 /*****************************************************************************/
645 static sal_Bool GetSpecialFolder(rtl_uString **strPath, int nFolder)
647 sal_Bool bRet = sal_False;
648 HINSTANCE hLibrary;
649 sal_Char PathA[_MAX_PATH];
650 sal_Unicode PathW[_MAX_PATH];
652 if ((hLibrary = LoadLibrary("shell32.dll")) != NULL)
654 BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
655 BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
657 pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathA");
658 pSHGetSpecialFolderPathW = (BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathW");
660 if (pSHGetSpecialFolderPathA)
662 if (pSHGetSpecialFolderPathA(GetActiveWindow(), PathA, nFolder, TRUE))
664 rtl_string2UString( strPath, PathA, (sal_Int32) strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
665 OSL_ASSERT(*strPath != NULL);
666 bRet = sal_True;
669 else if (pSHGetSpecialFolderPathW)
671 if (pSHGetSpecialFolderPathW(GetActiveWindow(), PathW, nFolder, TRUE))
673 rtl_uString_newFromStr( strPath, PathW);
674 bRet = sal_True;
677 else
679 HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *) = (HRESULT (WINAPI *)(HWND, int, LPITEMIDLIST *))GetProcAddress(hLibrary, "SHGetSpecialFolderLocation");
680 BOOL (WINAPI *pSHGetPathFromIDListA)(LPCITEMIDLIST, LPSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListA");
681 BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPWSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListW");
682 HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *) = (HRESULT (WINAPI *)(LPMALLOC *))GetProcAddress(hLibrary, "SHGetMalloc");
685 if (pSHGetSpecialFolderLocation && (pSHGetPathFromIDListA || pSHGetPathFromIDListW ) && pSHGetMalloc )
687 LPITEMIDLIST pidl;
688 LPMALLOC pMalloc;
689 HRESULT hr;
691 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
693 /* Get SHGetSpecialFolderLocation fails if directory does not exists. */
694 /* If it fails we try to create the directory and redo the call */
695 if (! SUCCEEDED(hr))
697 HKEY hRegKey;
699 if (RegOpenKey(HKEY_CURRENT_USER,
700 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
701 &hRegKey) == ERROR_SUCCESS)
703 LONG lRet;
704 DWORD lSize = SAL_N_ELEMENTS(PathA);
705 DWORD Type = REG_SZ;
707 switch (nFolder)
709 case CSIDL_APPDATA:
710 lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, (LPBYTE)PathA, &lSize);
711 break;
713 case CSIDL_PERSONAL:
714 lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, (LPBYTE)PathA, &lSize);
715 break;
717 default:
718 lRet = -1l;
721 if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ))
723 if (_access(PathA, 0) < 0)
724 CreateDirectory(PathA, NULL);
726 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
729 RegCloseKey(hRegKey);
733 if (SUCCEEDED(hr))
735 if (pSHGetPathFromIDListW && pSHGetPathFromIDListW(pidl, PathW))
737 /* if directory does not exist, create it */
738 if (_waccess(PathW, 0) < 0)
739 CreateDirectoryW(PathW, NULL);
741 rtl_uString_newFromStr( strPath, PathW);
742 bRet = sal_True;
744 else if (pSHGetPathFromIDListA && pSHGetPathFromIDListA(pidl, PathA))
746 /* if directory does not exist, create it */
747 if (_access(PathA, 0) < 0)
748 CreateDirectoryA(PathA, NULL);
750 rtl_string2UString( strPath, PathA, (sal_Int32) strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
751 OSL_ASSERT(*strPath != NULL);
752 bRet = sal_True;
756 if (SUCCEEDED(pSHGetMalloc(&pMalloc)))
758 pMalloc->lpVtbl->Free(pMalloc, pidl);
759 pMalloc->lpVtbl->Release(pMalloc);
765 FreeLibrary(hLibrary);
767 return (bRet);
771 static BOOL Privilege(LPTSTR strPrivilege, BOOL bEnable)
773 HANDLE hToken;
774 TOKEN_PRIVILEGES tp;
777 obtain the processes token
779 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
780 return FALSE;
783 get the luid
785 if (!LookupPrivilegeValue(NULL, strPrivilege, &tp.Privileges[0].Luid))
786 return FALSE;
788 tp.PrivilegeCount = 1;
790 if (bEnable)
791 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
792 else
793 tp.Privileges[0].Attributes = 0;
796 enable or disable the privilege
798 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
799 return FALSE;
801 if (!CloseHandle(hToken))
802 return FALSE;
804 return TRUE;
807 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain)
809 if (Security != NULL)
811 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
813 HANDLE hAccessToken = pSecImpl->m_hToken;
815 if (hAccessToken == NULL)
816 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
818 if (hAccessToken)
820 DWORD nInfoBuffer = 512;
821 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
823 while (!GetTokenInformation(hAccessToken, TokenUser,
824 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
826 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
827 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
828 else
830 free(pInfoBuffer);
831 pInfoBuffer = NULL;
832 break;
836 if (pSecImpl->m_hToken == NULL)
837 CloseHandle(hAccessToken);
839 if (pInfoBuffer)
841 sal_Unicode UserName[128];
842 sal_Unicode DomainName[128];
843 sal_Unicode Name[257];
844 DWORD nUserName = sizeof(UserName);
845 DWORD nDomainName = sizeof(DomainName);
846 SID_NAME_USE sUse;
848 if (LookupAccountSidW(NULL, ((PTOKEN_USER)pInfoBuffer)->User.Sid,
849 UserName, &nUserName,
850 DomainName, &nDomainName, &sUse))
852 if (bIncludeDomain)
854 wcscpy(Name, DomainName);
855 wcscat(Name, L"/");
856 wcscat(Name, UserName);
858 else
860 wcscpy(Name, UserName);
863 rtl_uString_newFromStr( strName, Name);
865 free(pInfoBuffer);
867 return (sal_True);
870 else
872 DWORD needed=0;
873 sal_Unicode *pNameW=NULL;
875 WNetGetUserW(NULL, NULL, &needed);
876 pNameW = malloc (needed*sizeof(sal_Unicode));
878 if (WNetGetUserW(NULL, pNameW, &needed) == NO_ERROR)
880 rtl_uString_newFromStr( strName, pNameW);
882 if (pNameW)
883 free(pNameW);
884 return (sal_True);
886 else
887 if (wcslen(pSecImpl->m_User) > 0)
889 rtl_uString_newFromStr( strName, pSecImpl->m_pNetResource->lpRemoteName);
891 if (pNameW)
892 free(pNameW);
894 return (sal_True);
897 if (pNameW)
898 free(pNameW);
902 return sal_False;
905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */