merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / w32 / security.c
blob237ea67dc949ebf1a361acc523e548f772cd4f83
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
29 #include "system.h"
31 #include <osl/security.h>
32 #include <osl/diagnose.h>
33 #include <osl/thread.h>
34 #include <osl/file.h>
35 #include <systools/win32/uwinapi.h>
36 #include "secimpl.h"
38 /*****************************************************************************/
39 /* Data Type Definition */
40 /*****************************************************************************/
43 /* Data for use in (un)LoadProfile Functions */
44 /* Declarations based on USERENV.H for Windows 2000 Beta 2 */
45 #define PI_NOUI 0x00000001 // Prevents displaying of messages
46 #define PI_APPLYPOLICY 0x00000002 // Apply NT4 style policy
48 typedef struct _PROFILEINFOW {
49 DWORD dwSize; // Must be set to sizeof(PROFILEINFO)
50 DWORD dwFlags; // See flags above
51 LPWSTR lpUserName; // User name (required)
52 LPWSTR lpProfilePath; // Roaming profile path
53 LPWSTR lpDefaultPath; // Default user profile path
54 LPWSTR lpServerName; // Validating DC name in netbios format
55 LPWSTR lpPolicyPath; // Path to the NT4 style policy file
56 HANDLE hProfile; // Registry key handle - filled by function
57 } PROFILEINFOW, FAR * LPPROFILEINFOW;
59 /* Typedefs for function pointers in USERENV.DLL */
60 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
61 HANDLE hToken,
62 LPPROFILEINFOW lpProfileInfo
65 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
66 HANDLE hToken,
67 HANDLE hProfile
70 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
71 HANDLE hToken,
72 LPTSTR lpProfileDir,
73 LPDWORD lpcchSize
76 /* To get an impersonation token we need to create an impersonation
77 duplicate so every access token has to be created with duplicate
78 access rights */
80 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
82 /*****************************************************************************/
83 /* Static Module Function Declarations */
84 /*****************************************************************************/
86 static sal_Bool isWNT(void);
87 static sal_Bool GetSpecialFolder(rtl_uString **strPath,int nFolder);
88 static BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable);
89 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain);
91 /*****************************************************************************/
92 /* Exported Module Functions */
93 /*****************************************************************************/
95 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
97 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
99 pSecImpl->m_pNetResource = NULL;
100 pSecImpl->m_User[0] = '\0';
101 pSecImpl->m_hToken = NULL;
102 pSecImpl->m_hProfile = NULL;
104 return ((oslSecurity)pSecImpl);
107 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
109 oslSecurityError ret;
111 if (!isWNT())
113 *pSecurity = osl_getCurrentSecurity();
114 ret = osl_Security_E_None;
116 else
118 sal_Unicode* strUser;
119 sal_Unicode* strDomain = _wcsdup(rtl_uString_getStr(strUserName));
120 HANDLE hUserToken;
122 #if OSL_DEBUG_LEVEL > 0
123 LUID luid;
124 #endif
126 if (NULL != (strUser = wcschr(strDomain, L'/')))
127 *strUser++ = L'\0';
128 else
130 strUser = strDomain;
131 strDomain = NULL;
134 // this process must have the right: 'act as a part of operatingsystem'
135 OSL_ASSERT(LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid));
137 if (LogonUserW(strUser, strDomain ? strDomain : L"", rtl_uString_getStr(strPasswd),
138 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
139 &hUserToken))
141 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
143 pSecImpl->m_pNetResource = NULL;
144 pSecImpl->m_hToken = hUserToken;
145 pSecImpl->m_hProfile = NULL;
146 wcscpy(pSecImpl->m_User, strUser);
148 *pSecurity = (oslSecurity)pSecImpl;
149 ret = osl_Security_E_None;
151 else
152 ret = osl_Security_E_UserUnknown;
154 if (strDomain)
155 free(strDomain);
156 else
157 free(strUser);
160 return ret;
163 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
164 rtl_uString *strPasswd,
165 rtl_uString *strFileServer,
166 oslSecurity *pSecurity)
168 oslSecurityError ret;
169 DWORD err;
170 NETRESOURCEW netResource;
171 sal_Unicode* remoteName;
172 sal_Unicode* userName;
174 remoteName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4);
175 userName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2);
177 wcscpy(remoteName, L"\\\\");
178 wcscat(remoteName, rtl_uString_getStr(strFileServer));
179 wcscat(remoteName, L"\\");
180 wcscat(remoteName, rtl_uString_getStr(strUserName));
182 wcscpy(userName, rtl_uString_getStr(strFileServer));
183 wcscat(userName, L"\\");
184 wcscat(userName, rtl_uString_getStr(strUserName));
186 netResource.dwScope = RESOURCE_GLOBALNET;
187 netResource.dwType = RESOURCETYPE_DISK;
188 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
189 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
190 netResource.lpLocalName = NULL;
191 netResource.lpRemoteName = remoteName;
192 netResource.lpComment = NULL;
193 netResource.lpProvider = NULL;
195 err = WNetAddConnection2W(&netResource, rtl_uString_getStr(strPasswd), userName, 0);
197 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
199 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
201 pSecImpl->m_pNetResource = malloc(sizeof(NETRESOURCE));
202 *pSecImpl->m_pNetResource = netResource;
204 pSecImpl->m_hToken = NULL;
205 pSecImpl->m_hProfile = NULL;
206 wcscpy(pSecImpl->m_User, rtl_uString_getStr(strUserName));
208 *pSecurity = (oslSecurity)pSecImpl;
210 ret = osl_Security_E_None;
212 else
213 ret = osl_Security_E_UserUnknown;
215 free(remoteName);
216 free(userName);
218 return ret;
222 static BOOL WINAPI CheckTokenMembership_Stub( HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember )
224 typedef BOOL (WINAPI *CheckTokenMembership_PROC)( HANDLE, PSID, PBOOL );
226 static HMODULE hModule = NULL;
227 static CheckTokenMembership_PROC pCheckTokenMembership = NULL;
229 if ( !hModule )
231 /* SAL is always linked against ADVAPI32 so we can rely on that it is already mapped */
233 hModule = GetModuleHandleA( "ADVAPI32.DLL" );
235 pCheckTokenMembership = (CheckTokenMembership_PROC)GetProcAddress( hModule, "CheckTokenMembership" );
238 if ( pCheckTokenMembership )
239 return pCheckTokenMembership( TokenHandle, SidToCheck, IsMember );
240 else
242 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
243 return FALSE;
249 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
251 if (Security != NULL)
253 /* ts: on Window 95 systems any user seems to be an adminstrator */
254 if (!isWNT())
256 return(sal_True);
258 else
260 HANDLE hImpersonationToken = NULL;
261 PSID psidAdministrators;
262 SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
263 sal_Bool bSuccess = sal_False;
266 /* If Security contains an access token we need to duplicate it to an impersonation
267 access token. NULL works with CheckTokenMembership() as the current effective
268 impersonation token
271 if ( ((oslSecurityImpl*)Security)->m_hToken )
273 if ( !DuplicateToken (((oslSecurityImpl*)Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
274 return sal_False;
277 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
278 and also works on Vista to retrieve the effective user rights. Just checking for
279 membership of Administrators group is not enough on Vista this would require additional
280 complicated checks as described in KB arcticle Q118626: http://support.microsoft.com/kb/118626/en-us
283 if (AllocateAndInitializeSid(&siaNtAuthority,
285 SECURITY_BUILTIN_DOMAIN_RID,
286 DOMAIN_ALIAS_RID_ADMINS,
287 0, 0, 0, 0, 0, 0,
288 &psidAdministrators))
290 BOOL fSuccess = FALSE;
292 if ( CheckTokenMembership_Stub( hImpersonationToken, psidAdministrators, &fSuccess ) && fSuccess )
293 bSuccess = sal_True;
295 FreeSid(psidAdministrators);
298 if ( hImpersonationToken )
299 CloseHandle( hImpersonationToken );
301 return (bSuccess);
304 else
305 return (sal_False);
309 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
311 if (Security)
313 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
315 if (pSecImpl->m_pNetResource != NULL)
317 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, sal_True);
319 free(pSecImpl->m_pNetResource->lpRemoteName);
320 free(pSecImpl->m_pNetResource);
323 if (pSecImpl->m_hToken)
324 CloseHandle(pSecImpl->m_hToken);
326 if ( pSecImpl->m_hProfile )
327 CloseHandle(pSecImpl->m_hProfile);
329 free (pSecImpl);
334 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
336 if (Security != NULL)
338 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
340 HANDLE hAccessToken = pSecImpl->m_hToken;
342 if (hAccessToken == NULL)
343 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
345 if (hAccessToken)
347 sal_Char *Ident;
348 DWORD nInfoBuffer = 512;
349 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
352 while (!GetTokenInformation(hAccessToken, TokenUser,
353 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
355 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
356 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
357 else
359 free(pInfoBuffer);
360 pInfoBuffer = NULL;
361 break;
365 if (pSecImpl->m_hToken == NULL)
366 CloseHandle(hAccessToken);
368 if (pInfoBuffer)
370 PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid;
371 PSID_IDENTIFIER_AUTHORITY psia;
372 DWORD dwSubAuthorities;
373 DWORD dwSidRev=SID_REVISION;
374 DWORD dwCounter;
375 DWORD dwSidSize;
377 /* obtain SidIdentifierAuthority */
378 psia=GetSidIdentifierAuthority(pSid);
380 /* obtain sidsubauthority count */
381 dwSubAuthorities=min(*GetSidSubAuthorityCount(pSid), 5);
383 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
384 Ident=malloc(88*sizeof(sal_Char));
386 /* prepare S-SID_REVISION- */
387 dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
389 /* prepare SidIdentifierAuthority */
390 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
392 dwSidSize+=wsprintf(Ident + strlen(Ident),
393 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
394 (USHORT)psia->Value[0],
395 (USHORT)psia->Value[1],
396 (USHORT)psia->Value[2],
397 (USHORT)psia->Value[3],
398 (USHORT)psia->Value[4],
399 (USHORT)psia->Value[5]);
401 else
403 dwSidSize+=wsprintf(Ident + strlen(Ident),
404 TEXT("%lu"),
405 (ULONG)(psia->Value[5] ) +
406 (ULONG)(psia->Value[4] << 8) +
407 (ULONG)(psia->Value[3] << 16) +
408 (ULONG)(psia->Value[2] << 24) );
411 /* loop through SidSubAuthorities */
412 for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
414 dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
415 *GetSidSubAuthority(pSid, dwCounter) );
418 rtl_uString_newFromAscii( strIdent, Ident );
420 free(pInfoBuffer);
421 free(Ident);
423 return (sal_True);
426 else
428 DWORD needed=0;
429 sal_Unicode *Ident;
431 WNetGetUserA(NULL, NULL, &needed);
432 needed = max( 16 , needed );
433 Ident=malloc(needed*sizeof(sal_Unicode));
435 if (WNetGetUserW(NULL, Ident, &needed) != NO_ERROR)
437 wcscpy(Ident, L"unknown");
438 Ident[7] = L'\0';
441 rtl_uString_newFromStr( strIdent, Ident);
443 free(Ident);
445 return sal_True;
449 return sal_False;
454 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
456 return getUserNameImpl(Security, strName, sal_True);
460 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
462 rtl_uString *ustrSysDir = NULL;
463 sal_Bool bSuccess = sal_False;
465 if (Security != NULL)
467 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
469 if (pSecImpl->m_pNetResource != NULL)
471 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
473 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory ));
475 else
477 #if 0
478 if (pSecImpl->m_hToken)
480 DWORD nInfoBuffer = 512;
481 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
483 while (!GetTokenInformation(pSecImpl->m_hToken, TokenUser,
484 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
486 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
487 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
488 else
490 free(pInfoBuffer);
491 pInfoBuffer = NULL;
492 break;
496 /* not implemented */
497 OSL_ASSERT(sal_False);
499 if (pInfoBuffer)
501 /* if (EqualSid() ... */
505 else
506 #endif
508 bSuccess = (sal_Bool)(GetSpecialFolder(&ustrSysDir, CSIDL_PERSONAL) &&
509 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory)));
513 if ( ustrSysDir )
514 rtl_uString_release( ustrSysDir );
516 return bSuccess;
519 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
521 sal_Bool bSuccess = sal_False;
523 if (Security != NULL)
525 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
527 if (pSecImpl->m_pNetResource != NULL)
529 rtl_uString *ustrSysDir = NULL;
531 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
532 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory));
534 if ( ustrSysDir )
535 rtl_uString_release( ustrSysDir );
537 else
539 if (pSecImpl->m_hToken)
541 /* not implemented */
542 OSL_ASSERT(sal_False);
544 else
546 rtl_uString *ustrFile = NULL;
547 sal_Unicode sFile[_MAX_PATH];
549 if ( !GetSpecialFolder( &ustrFile, CSIDL_APPDATA) )
551 OSL_VERIFY(GetWindowsDirectoryW(sFile, _MAX_DIR) > 0);
553 rtl_uString_newFromStr( &ustrFile, sFile);
556 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory));
558 if ( ustrFile )
559 rtl_uString_release( ustrFile );
564 return bSuccess;
568 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
570 /* CreateProcessAsUser does not load the specified user's profile
571 into the HKEY_USERS registry key. This means that access to information
572 in the HKEY_CURRENT_USER registry key may not produce results consistent
573 with a normal interactive logon.
574 It is your responsibility to load the user's registry hive into HKEY_USERS
575 with the LoadUserProfile function before calling CreateProcessAsUser.
577 BOOL bOk = FALSE;
579 RegCloseKey(HKEY_CURRENT_USER);
581 if (Privilege(SE_RESTORE_NAME, TRUE))
583 HMODULE hUserEnvLib = NULL;
584 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
585 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
586 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
587 DWORD nError = 0;
589 /* try to create user profile */
590 if ( !hAccessToken )
592 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
594 HANDLE hProcess = GetCurrentProcess();
596 if (hProcess != NULL)
598 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
599 CloseHandle(hProcess);
603 hUserEnvLib = LoadLibraryA("userenv.dll");
605 if (hUserEnvLib)
607 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileW");
608 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
610 if (fLoadUserProfile && fUnloadUserProfile)
612 rtl_uString *buffer = 0;
613 PROFILEINFOW pi;
615 getUserNameImpl(Security, &buffer, sal_False);
617 ZeroMemory( &pi, sizeof(pi) );
618 pi.dwSize = sizeof(pi);
619 pi.lpUserName = rtl_uString_getStr(buffer);
620 pi.dwFlags = PI_NOUI;
622 if (fLoadUserProfile(hAccessToken, &pi))
624 fUnloadUserProfile(hAccessToken, pi.hProfile);
626 bOk = TRUE;
628 else
629 nError = GetLastError();
631 rtl_uString_release(buffer);
634 FreeLibrary(hUserEnvLib);
637 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
638 CloseHandle(hAccessToken);
641 return (sal_Bool)bOk;
645 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
647 if ( ((oslSecurityImpl*)Security)->m_hProfile != NULL )
649 HMODULE hUserEnvLib = NULL;
650 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
651 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
652 BOOL bOk = FALSE;
653 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
655 if ( !hAccessToken )
657 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
659 HANDLE hProcess = GetCurrentProcess();
661 if (hProcess != NULL)
663 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
664 CloseHandle(hProcess);
668 hUserEnvLib = LoadLibrary("userenv.dll");
670 if (hUserEnvLib)
672 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileA");
673 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
675 if (fLoadUserProfile && fUnloadUserProfile)
677 /* unloading the user profile */
678 if (fLoadUserProfile && fUnloadUserProfile)
679 bOk = fUnloadUserProfile(hAccessToken, ((oslSecurityImpl*)Security)->m_hProfile);
681 if (hUserEnvLib)
682 FreeLibrary(hUserEnvLib);
686 ((oslSecurityImpl*)Security)->m_hProfile;
688 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
690 CloseHandle(hAccessToken);
695 /*****************************************************************************/
696 /* Static Module Functions */
697 /*****************************************************************************/
700 static sal_Bool GetSpecialFolder(rtl_uString **strPath, int nFolder)
702 sal_Bool bRet = sal_False;
703 HINSTANCE hLibrary;
704 sal_Char PathA[_MAX_PATH];
705 sal_Unicode PathW[_MAX_PATH];
707 if ((hLibrary = LoadLibrary("shell32.dll")) != NULL)
709 BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
710 BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
712 pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathA");
713 pSHGetSpecialFolderPathW = (BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathW");
715 if (pSHGetSpecialFolderPathA)
717 if (pSHGetSpecialFolderPathA(GetActiveWindow(), PathA, nFolder, TRUE))
719 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
720 OSL_ASSERT(*strPath != NULL);
721 bRet = sal_True;
724 else if (pSHGetSpecialFolderPathW)
726 if (pSHGetSpecialFolderPathW(GetActiveWindow(), PathW, nFolder, TRUE))
728 rtl_uString_newFromStr( strPath, PathW);
729 bRet = sal_True;
732 else
734 HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *) = (HRESULT (WINAPI *)(HWND, int, LPITEMIDLIST *))GetProcAddress(hLibrary, "SHGetSpecialFolderLocation");
735 BOOL (WINAPI *pSHGetPathFromIDListA)(LPCITEMIDLIST, LPSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListA");
736 BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPWSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListW");
737 HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *) = (HRESULT (WINAPI *)(LPMALLOC *))GetProcAddress(hLibrary, "SHGetMalloc");
740 if (pSHGetSpecialFolderLocation && (pSHGetPathFromIDListA || pSHGetPathFromIDListW ) && pSHGetMalloc )
742 LPITEMIDLIST pidl;
743 LPMALLOC pMalloc;
744 HRESULT hr;
746 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
748 /* Get SHGetSpecialFolderLocation fails if directory does not exists. */
749 /* If it fails we try to create the directory and redo the call */
750 if (! SUCCEEDED(hr))
752 HKEY hRegKey;
754 if (RegOpenKey(HKEY_CURRENT_USER,
755 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
756 &hRegKey) == ERROR_SUCCESS)
758 LONG lRet;
759 DWORD lSize = elementsof(PathA);
760 DWORD Type = REG_SZ;
762 switch (nFolder)
764 case CSIDL_APPDATA:
765 lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, (LPBYTE)PathA, &lSize);
766 break;
768 case CSIDL_PERSONAL:
769 lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, (LPBYTE)PathA, &lSize);
770 break;
772 default:
773 lRet = -1l;
776 if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ))
778 if (_access(PathA, 0) < 0)
779 CreateDirectory(PathA, NULL);
781 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
784 RegCloseKey(hRegKey);
788 if (SUCCEEDED(hr))
790 if (pSHGetPathFromIDListW && pSHGetPathFromIDListW(pidl, PathW))
792 /* if directory does not exist, create it */
793 if (_waccess(PathW, 0) < 0)
794 CreateDirectoryW(PathW, NULL);
796 rtl_uString_newFromStr( strPath, PathW);
797 bRet = sal_True;
799 else if (pSHGetPathFromIDListA && pSHGetPathFromIDListA(pidl, PathA))
801 /* if directory does not exist, create it */
802 if (_access(PathA, 0) < 0)
803 CreateDirectoryA(PathA, NULL);
805 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
806 OSL_ASSERT(*strPath != NULL);
807 bRet = sal_True;
811 if (SUCCEEDED(pSHGetMalloc(&pMalloc)))
813 pMalloc->lpVtbl->Free(pMalloc, pidl);
814 pMalloc->lpVtbl->Release(pMalloc);
820 FreeLibrary(hLibrary);
822 return (bRet);
826 static sal_Bool isWNT(void)
828 static sal_Bool isInit = sal_False;
829 static sal_Bool isWNT = sal_False;
831 if (!isInit)
833 OSVERSIONINFO VersionInformation =
836 sizeof(OSVERSIONINFO),
844 if (
845 GetVersionEx(&VersionInformation) &&
846 (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT)
849 isWNT = sal_True;
852 isInit = sal_True;
855 return(isWNT);
858 static BOOL Privilege(LPTSTR strPrivilege, BOOL bEnable)
860 HANDLE hToken;
861 TOKEN_PRIVILEGES tp;
864 obtain the processes token
866 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
867 return FALSE;
870 get the luid
872 if (!LookupPrivilegeValue(NULL, strPrivilege, &tp.Privileges[0].Luid))
873 return FALSE;
875 tp.PrivilegeCount = 1;
877 if (bEnable)
878 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
879 else
880 tp.Privileges[0].Attributes = 0;
883 enable or disable the privilege
885 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
886 return FALSE;
888 if (!CloseHandle(hToken))
889 return FALSE;
891 return TRUE;
894 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain)
896 if (Security != NULL)
898 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
900 HANDLE hAccessToken = pSecImpl->m_hToken;
902 if (hAccessToken == NULL)
903 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
905 if (hAccessToken)
907 DWORD nInfoBuffer = 512;
908 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
910 while (!GetTokenInformation(hAccessToken, TokenUser,
911 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
913 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
914 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
915 else
917 free(pInfoBuffer);
918 pInfoBuffer = NULL;
919 break;
923 if (pSecImpl->m_hToken == NULL)
924 CloseHandle(hAccessToken);
926 if (pInfoBuffer)
928 sal_Unicode UserName[128];
929 sal_Unicode DomainName[128];
930 sal_Unicode Name[257];
931 DWORD nUserName = sizeof(UserName);
932 DWORD nDomainName = sizeof(DomainName);
933 SID_NAME_USE sUse;
935 if (LookupAccountSidW(NULL, ((PTOKEN_USER)pInfoBuffer)->User.Sid,
936 UserName, &nUserName,
937 DomainName, &nDomainName, &sUse))
939 if (bIncludeDomain)
941 wcscpy(Name, DomainName);
942 wcscat(Name, L"/");
943 wcscat(Name, UserName);
945 else
947 wcscpy(Name, UserName);
950 rtl_uString_newFromStr( strName, Name);
952 free(pInfoBuffer);
954 return (sal_True);
957 else
959 DWORD needed=0;
960 sal_Unicode *pNameW=NULL;
962 WNetGetUserW(NULL, NULL, &needed);
963 pNameW = malloc (needed*sizeof(sal_Unicode));
965 if (WNetGetUserW(NULL, pNameW, &needed) == NO_ERROR)
967 rtl_uString_newFromStr( strName, pNameW);
969 if (pNameW)
970 free(pNameW);
971 return (sal_True);
973 else
974 if (wcslen(pSecImpl->m_User) > 0)
976 rtl_uString_newFromStr( strName, pSecImpl->m_pNetResource->lpRemoteName);
978 if (pNameW)
979 free(pNameW);
981 return (sal_True);
984 if (pNameW)
985 free(pNameW);
989 return sal_False;