update dev300-m57
[ooovba.git] / sal / osl / w32 / security.c
blobadf1b988a750dd8cf1aa4589d726ae0069ef444f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: security.c,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #include "system.h"
34 #include <osl/security.h>
35 #include <osl/diagnose.h>
36 #include <osl/thread.h>
37 #include <osl/file.h>
38 #include <systools/win32/uwinapi.h>
39 #include "secimpl.h"
41 /*****************************************************************************/
42 /* Data Type Definition */
43 /*****************************************************************************/
46 /* Data for use in (un)LoadProfile Functions */
47 /* Declarations based on USERENV.H for Windows 2000 Beta 2 */
48 #define PI_NOUI 0x00000001 // Prevents displaying of messages
49 #define PI_APPLYPOLICY 0x00000002 // Apply NT4 style policy
51 typedef struct _PROFILEINFOW {
52 DWORD dwSize; // Must be set to sizeof(PROFILEINFO)
53 DWORD dwFlags; // See flags above
54 LPWSTR lpUserName; // User name (required)
55 LPWSTR lpProfilePath; // Roaming profile path
56 LPWSTR lpDefaultPath; // Default user profile path
57 LPWSTR lpServerName; // Validating DC name in netbios format
58 LPWSTR lpPolicyPath; // Path to the NT4 style policy file
59 HANDLE hProfile; // Registry key handle - filled by function
60 } PROFILEINFOW, FAR * LPPROFILEINFOW;
62 /* Typedefs for function pointers in USERENV.DLL */
63 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
64 HANDLE hToken,
65 LPPROFILEINFOW lpProfileInfo
68 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
69 HANDLE hToken,
70 HANDLE hProfile
73 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
74 HANDLE hToken,
75 LPTSTR lpProfileDir,
76 LPDWORD lpcchSize
79 /* To get an impersonation token we need to create an impersonation
80 duplicate so every access token has to be created with duplicate
81 access rights */
83 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
85 /*****************************************************************************/
86 /* Static Module Function Declarations */
87 /*****************************************************************************/
89 static sal_Bool isWNT(void);
90 static sal_Bool GetSpecialFolder(rtl_uString **strPath,int nFolder);
91 static BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable);
92 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain);
94 /*****************************************************************************/
95 /* Exported Module Functions */
96 /*****************************************************************************/
98 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
100 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
102 pSecImpl->m_pNetResource = NULL;
103 pSecImpl->m_User[0] = '\0';
104 pSecImpl->m_hToken = NULL;
105 pSecImpl->m_hProfile = NULL;
107 return ((oslSecurity)pSecImpl);
110 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
112 oslSecurityError ret;
114 if (!isWNT())
116 *pSecurity = osl_getCurrentSecurity();
117 ret = osl_Security_E_None;
119 else
121 sal_Unicode* strUser;
122 sal_Unicode* strDomain = _wcsdup(rtl_uString_getStr(strUserName));
123 HANDLE hUserToken;
125 #if OSL_DEBUG_LEVEL > 0
126 LUID luid;
127 #endif
129 if (NULL != (strUser = wcschr(strDomain, L'/')))
130 *strUser++ = L'\0';
131 else
133 strUser = strDomain;
134 strDomain = NULL;
137 // this process must have the right: 'act as a part of operatingsystem'
138 OSL_ASSERT(LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid));
140 if (LogonUserW(strUser, strDomain ? strDomain : L"", rtl_uString_getStr(strPasswd),
141 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
142 &hUserToken))
144 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
146 pSecImpl->m_pNetResource = NULL;
147 pSecImpl->m_hToken = hUserToken;
148 pSecImpl->m_hProfile = NULL;
149 wcscpy(pSecImpl->m_User, strUser);
151 *pSecurity = (oslSecurity)pSecImpl;
152 ret = osl_Security_E_None;
154 else
155 ret = osl_Security_E_UserUnknown;
157 if (strDomain)
158 free(strDomain);
159 else
160 free(strUser);
163 return ret;
166 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
167 rtl_uString *strPasswd,
168 rtl_uString *strFileServer,
169 oslSecurity *pSecurity)
171 oslSecurityError ret;
172 DWORD err;
173 NETRESOURCEW netResource;
174 sal_Unicode* remoteName;
175 sal_Unicode* userName;
177 remoteName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4);
178 userName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2);
180 wcscpy(remoteName, L"\\\\");
181 wcscat(remoteName, rtl_uString_getStr(strFileServer));
182 wcscat(remoteName, L"\\");
183 wcscat(remoteName, rtl_uString_getStr(strUserName));
185 wcscpy(userName, rtl_uString_getStr(strFileServer));
186 wcscat(userName, L"\\");
187 wcscat(userName, rtl_uString_getStr(strUserName));
189 netResource.dwScope = RESOURCE_GLOBALNET;
190 netResource.dwType = RESOURCETYPE_DISK;
191 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
192 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
193 netResource.lpLocalName = NULL;
194 netResource.lpRemoteName = remoteName;
195 netResource.lpComment = NULL;
196 netResource.lpProvider = NULL;
198 err = WNetAddConnection2W(&netResource, rtl_uString_getStr(strPasswd), userName, 0);
200 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
202 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
204 pSecImpl->m_pNetResource = malloc(sizeof(NETRESOURCE));
205 *pSecImpl->m_pNetResource = netResource;
207 pSecImpl->m_hToken = NULL;
208 pSecImpl->m_hProfile = NULL;
209 wcscpy(pSecImpl->m_User, rtl_uString_getStr(strUserName));
211 *pSecurity = (oslSecurity)pSecImpl;
213 ret = osl_Security_E_None;
215 else
216 ret = osl_Security_E_UserUnknown;
218 free(remoteName);
219 free(userName);
221 return ret;
225 static BOOL WINAPI CheckTokenMembership_Stub( HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember )
227 typedef BOOL (WINAPI *CheckTokenMembership_PROC)( HANDLE, PSID, PBOOL );
229 static HMODULE hModule = NULL;
230 static CheckTokenMembership_PROC pCheckTokenMembership = NULL;
232 if ( !hModule )
234 /* SAL is always linked against ADVAPI32 so we can rely on that it is already mapped */
236 hModule = GetModuleHandleA( "ADVAPI32.DLL" );
238 pCheckTokenMembership = (CheckTokenMembership_PROC)GetProcAddress( hModule, "CheckTokenMembership" );
241 if ( pCheckTokenMembership )
242 return pCheckTokenMembership( TokenHandle, SidToCheck, IsMember );
243 else
245 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
246 return FALSE;
252 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
254 if (Security != NULL)
256 /* ts: on Window 95 systems any user seems to be an adminstrator */
257 if (!isWNT())
259 return(sal_True);
261 else
263 HANDLE hImpersonationToken = NULL;
264 PSID psidAdministrators;
265 SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
266 sal_Bool bSuccess = sal_False;
269 /* If Security contains an access token we need to duplicate it to an impersonation
270 access token. NULL works with CheckTokenMembership() as the current effective
271 impersonation token
274 if ( ((oslSecurityImpl*)Security)->m_hToken )
276 if ( !DuplicateToken (((oslSecurityImpl*)Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
277 return sal_False;
280 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
281 and also works on Vista to retrieve the effective user rights. Just checking for
282 membership of Administrators group is not enough on Vista this would require additional
283 complicated checks as described in KB arcticle Q118626: http://support.microsoft.com/kb/118626/en-us
286 if (AllocateAndInitializeSid(&siaNtAuthority,
288 SECURITY_BUILTIN_DOMAIN_RID,
289 DOMAIN_ALIAS_RID_ADMINS,
290 0, 0, 0, 0, 0, 0,
291 &psidAdministrators))
293 BOOL fSuccess = FALSE;
295 if ( CheckTokenMembership_Stub( hImpersonationToken, psidAdministrators, &fSuccess ) && fSuccess )
296 bSuccess = sal_True;
298 FreeSid(psidAdministrators);
301 if ( hImpersonationToken )
302 CloseHandle( hImpersonationToken );
304 return (bSuccess);
307 else
308 return (sal_False);
312 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
314 if (Security)
316 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
318 if (pSecImpl->m_pNetResource != NULL)
320 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, sal_True);
322 free(pSecImpl->m_pNetResource->lpRemoteName);
323 free(pSecImpl->m_pNetResource);
326 if (pSecImpl->m_hToken)
327 CloseHandle(pSecImpl->m_hToken);
329 if ( pSecImpl->m_hProfile )
330 CloseHandle(pSecImpl->m_hProfile);
332 free (pSecImpl);
337 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
339 if (Security != NULL)
341 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
343 HANDLE hAccessToken = pSecImpl->m_hToken;
345 if (hAccessToken == NULL)
346 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
348 if (hAccessToken)
350 sal_Char *Ident;
351 DWORD nInfoBuffer = 512;
352 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
355 while (!GetTokenInformation(hAccessToken, TokenUser,
356 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
358 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
359 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
360 else
362 free(pInfoBuffer);
363 pInfoBuffer = NULL;
364 break;
368 if (pSecImpl->m_hToken == NULL)
369 CloseHandle(hAccessToken);
371 if (pInfoBuffer)
373 PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid;
374 PSID_IDENTIFIER_AUTHORITY psia;
375 DWORD dwSubAuthorities;
376 DWORD dwSidRev=SID_REVISION;
377 DWORD dwCounter;
378 DWORD dwSidSize;
380 /* obtain SidIdentifierAuthority */
381 psia=GetSidIdentifierAuthority(pSid);
383 /* obtain sidsubauthority count */
384 dwSubAuthorities=min(*GetSidSubAuthorityCount(pSid), 5);
386 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
387 Ident=malloc(88*sizeof(sal_Char));
389 /* prepare S-SID_REVISION- */
390 dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
392 /* prepare SidIdentifierAuthority */
393 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
395 dwSidSize+=wsprintf(Ident + strlen(Ident),
396 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
397 (USHORT)psia->Value[0],
398 (USHORT)psia->Value[1],
399 (USHORT)psia->Value[2],
400 (USHORT)psia->Value[3],
401 (USHORT)psia->Value[4],
402 (USHORT)psia->Value[5]);
404 else
406 dwSidSize+=wsprintf(Ident + strlen(Ident),
407 TEXT("%lu"),
408 (ULONG)(psia->Value[5] ) +
409 (ULONG)(psia->Value[4] << 8) +
410 (ULONG)(psia->Value[3] << 16) +
411 (ULONG)(psia->Value[2] << 24) );
414 /* loop through SidSubAuthorities */
415 for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
417 dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
418 *GetSidSubAuthority(pSid, dwCounter) );
421 rtl_uString_newFromAscii( strIdent, Ident );
423 free(pInfoBuffer);
424 free(Ident);
426 return (sal_True);
429 else
431 DWORD needed=0;
432 sal_Unicode *Ident;
434 WNetGetUserA(NULL, NULL, &needed);
435 needed = max( 16 , needed );
436 Ident=malloc(needed*sizeof(sal_Unicode));
438 if (WNetGetUserW(NULL, Ident, &needed) != NO_ERROR)
440 wcscpy(Ident, L"unknown");
441 Ident[7] = L'\0';
444 rtl_uString_newFromStr( strIdent, Ident);
446 free(Ident);
448 return sal_True;
452 return sal_False;
457 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
459 return getUserNameImpl(Security, strName, sal_True);
463 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
465 rtl_uString *ustrSysDir = NULL;
466 sal_Bool bSuccess = sal_False;
468 if (Security != NULL)
470 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
472 if (pSecImpl->m_pNetResource != NULL)
474 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
476 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory ));
478 else
480 #if 0
481 if (pSecImpl->m_hToken)
483 DWORD nInfoBuffer = 512;
484 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
486 while (!GetTokenInformation(pSecImpl->m_hToken, TokenUser,
487 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
489 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
490 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
491 else
493 free(pInfoBuffer);
494 pInfoBuffer = NULL;
495 break;
499 /* not implemented */
500 OSL_ASSERT(sal_False);
502 if (pInfoBuffer)
504 /* if (EqualSid() ... */
508 else
509 #endif
511 bSuccess = (sal_Bool)(GetSpecialFolder(&ustrSysDir, CSIDL_PERSONAL) &&
512 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory)));
516 if ( ustrSysDir )
517 rtl_uString_release( ustrSysDir );
519 return bSuccess;
522 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
524 sal_Bool bSuccess = sal_False;
526 if (Security != NULL)
528 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
530 if (pSecImpl->m_pNetResource != NULL)
532 rtl_uString *ustrSysDir = NULL;
534 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
535 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory));
537 if ( ustrSysDir )
538 rtl_uString_release( ustrSysDir );
540 else
542 if (pSecImpl->m_hToken)
544 /* not implemented */
545 OSL_ASSERT(sal_False);
547 else
549 rtl_uString *ustrFile = NULL;
550 sal_Unicode sFile[_MAX_PATH];
552 if ( !GetSpecialFolder( &ustrFile, CSIDL_APPDATA) )
554 OSL_VERIFY(GetWindowsDirectoryW(sFile, _MAX_DIR) > 0);
556 rtl_uString_newFromStr( &ustrFile, sFile);
559 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory));
561 if ( ustrFile )
562 rtl_uString_release( ustrFile );
567 return bSuccess;
571 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
573 /* CreateProcessAsUser does not load the specified user's profile
574 into the HKEY_USERS registry key. This means that access to information
575 in the HKEY_CURRENT_USER registry key may not produce results consistent
576 with a normal interactive logon.
577 It is your responsibility to load the user's registry hive into HKEY_USERS
578 with the LoadUserProfile function before calling CreateProcessAsUser.
580 BOOL bOk = FALSE;
582 RegCloseKey(HKEY_CURRENT_USER);
584 if (Privilege(SE_RESTORE_NAME, TRUE))
586 HMODULE hUserEnvLib = NULL;
587 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
588 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
589 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
590 DWORD nError = 0;
592 /* try to create user profile */
593 if ( !hAccessToken )
595 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
597 HANDLE hProcess = GetCurrentProcess();
599 if (hProcess != NULL)
601 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
602 CloseHandle(hProcess);
606 hUserEnvLib = LoadLibraryA("userenv.dll");
608 if (hUserEnvLib)
610 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileW");
611 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
613 if (fLoadUserProfile && fUnloadUserProfile)
615 rtl_uString *buffer = 0;
616 PROFILEINFOW pi;
618 getUserNameImpl(Security, &buffer, sal_False);
620 ZeroMemory( &pi, sizeof(pi) );
621 pi.dwSize = sizeof(pi);
622 pi.lpUserName = rtl_uString_getStr(buffer);
623 pi.dwFlags = PI_NOUI;
625 if (fLoadUserProfile(hAccessToken, &pi))
627 fUnloadUserProfile(hAccessToken, pi.hProfile);
629 bOk = TRUE;
631 else
632 nError = GetLastError();
634 rtl_uString_release(buffer);
637 FreeLibrary(hUserEnvLib);
640 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
641 CloseHandle(hAccessToken);
644 return (sal_Bool)bOk;
648 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
650 if ( ((oslSecurityImpl*)Security)->m_hProfile != NULL )
652 HMODULE hUserEnvLib = NULL;
653 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
654 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
655 BOOL bOk = FALSE;
656 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
658 if ( !hAccessToken )
660 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
662 HANDLE hProcess = GetCurrentProcess();
664 if (hProcess != NULL)
666 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
667 CloseHandle(hProcess);
671 hUserEnvLib = LoadLibrary("userenv.dll");
673 if (hUserEnvLib)
675 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileA");
676 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
678 if (fLoadUserProfile && fUnloadUserProfile)
680 /* unloading the user profile */
681 if (fLoadUserProfile && fUnloadUserProfile)
682 bOk = fUnloadUserProfile(hAccessToken, ((oslSecurityImpl*)Security)->m_hProfile);
684 if (hUserEnvLib)
685 FreeLibrary(hUserEnvLib);
689 ((oslSecurityImpl*)Security)->m_hProfile;
691 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
693 CloseHandle(hAccessToken);
698 /*****************************************************************************/
699 /* Static Module Functions */
700 /*****************************************************************************/
703 static sal_Bool GetSpecialFolder(rtl_uString **strPath, int nFolder)
705 sal_Bool bRet = sal_False;
706 HINSTANCE hLibrary;
707 sal_Char PathA[_MAX_PATH];
708 sal_Unicode PathW[_MAX_PATH];
710 if ((hLibrary = LoadLibrary("shell32.dll")) != NULL)
712 BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
713 BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
715 pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathA");
716 pSHGetSpecialFolderPathW = (BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathW");
718 if (pSHGetSpecialFolderPathA)
720 if (pSHGetSpecialFolderPathA(GetActiveWindow(), PathA, nFolder, TRUE))
722 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
723 OSL_ASSERT(*strPath != NULL);
724 bRet = sal_True;
727 else if (pSHGetSpecialFolderPathW)
729 if (pSHGetSpecialFolderPathW(GetActiveWindow(), PathW, nFolder, TRUE))
731 rtl_uString_newFromStr( strPath, PathW);
732 bRet = sal_True;
735 else
737 HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *) = (HRESULT (WINAPI *)(HWND, int, LPITEMIDLIST *))GetProcAddress(hLibrary, "SHGetSpecialFolderLocation");
738 BOOL (WINAPI *pSHGetPathFromIDListA)(LPCITEMIDLIST, LPSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListA");
739 BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPWSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListW");
740 HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *) = (HRESULT (WINAPI *)(LPMALLOC *))GetProcAddress(hLibrary, "SHGetMalloc");
743 if (pSHGetSpecialFolderLocation && (pSHGetPathFromIDListA || pSHGetPathFromIDListW ) && pSHGetMalloc )
745 LPITEMIDLIST pidl;
746 LPMALLOC pMalloc;
747 HRESULT hr;
749 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
751 /* Get SHGetSpecialFolderLocation fails if directory does not exists. */
752 /* If it fails we try to create the directory and redo the call */
753 if (! SUCCEEDED(hr))
755 HKEY hRegKey;
757 if (RegOpenKey(HKEY_CURRENT_USER,
758 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
759 &hRegKey) == ERROR_SUCCESS)
761 LONG lRet;
762 DWORD lSize = elementsof(PathA);
763 DWORD Type = REG_SZ;
765 switch (nFolder)
767 case CSIDL_APPDATA:
768 lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, (LPBYTE)PathA, &lSize);
769 break;
771 case CSIDL_PERSONAL:
772 lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, (LPBYTE)PathA, &lSize);
773 break;
775 default:
776 lRet = -1l;
779 if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ))
781 if (_access(PathA, 0) < 0)
782 CreateDirectory(PathA, NULL);
784 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
787 RegCloseKey(hRegKey);
791 if (SUCCEEDED(hr))
793 if (pSHGetPathFromIDListW && pSHGetPathFromIDListW(pidl, PathW))
795 /* if directory does not exist, create it */
796 if (_waccess(PathW, 0) < 0)
797 CreateDirectoryW(PathW, NULL);
799 rtl_uString_newFromStr( strPath, PathW);
800 bRet = sal_True;
802 else if (pSHGetPathFromIDListA && pSHGetPathFromIDListA(pidl, PathA))
804 /* if directory does not exist, create it */
805 if (_access(PathA, 0) < 0)
806 CreateDirectoryA(PathA, NULL);
808 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
809 OSL_ASSERT(*strPath != NULL);
810 bRet = sal_True;
814 if (SUCCEEDED(pSHGetMalloc(&pMalloc)))
816 pMalloc->lpVtbl->Free(pMalloc, pidl);
817 pMalloc->lpVtbl->Release(pMalloc);
823 FreeLibrary(hLibrary);
825 return (bRet);
829 static sal_Bool isWNT(void)
831 static sal_Bool isInit = sal_False;
832 static sal_Bool isWNT = sal_False;
834 if (!isInit)
836 OSVERSIONINFO VersionInformation =
839 sizeof(OSVERSIONINFO),
847 if (
848 GetVersionEx(&VersionInformation) &&
849 (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT)
852 isWNT = sal_True;
855 isInit = sal_True;
858 return(isWNT);
861 static BOOL Privilege(LPTSTR strPrivilege, BOOL bEnable)
863 HANDLE hToken;
864 TOKEN_PRIVILEGES tp;
867 obtain the processes token
869 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
870 return FALSE;
873 get the luid
875 if (!LookupPrivilegeValue(NULL, strPrivilege, &tp.Privileges[0].Luid))
876 return FALSE;
878 tp.PrivilegeCount = 1;
880 if (bEnable)
881 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
882 else
883 tp.Privileges[0].Attributes = 0;
886 enable or disable the privilege
888 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
889 return FALSE;
891 if (!CloseHandle(hToken))
892 return FALSE;
894 return TRUE;
897 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain)
899 if (Security != NULL)
901 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
903 HANDLE hAccessToken = pSecImpl->m_hToken;
905 if (hAccessToken == NULL)
906 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
908 if (hAccessToken)
910 DWORD nInfoBuffer = 512;
911 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
913 while (!GetTokenInformation(hAccessToken, TokenUser,
914 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
916 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
917 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
918 else
920 free(pInfoBuffer);
921 pInfoBuffer = NULL;
922 break;
926 if (pSecImpl->m_hToken == NULL)
927 CloseHandle(hAccessToken);
929 if (pInfoBuffer)
931 sal_Unicode UserName[128];
932 sal_Unicode DomainName[128];
933 sal_Unicode Name[257];
934 DWORD nUserName = sizeof(UserName);
935 DWORD nDomainName = sizeof(DomainName);
936 SID_NAME_USE sUse;
938 if (LookupAccountSidW(NULL, ((PTOKEN_USER)pInfoBuffer)->User.Sid,
939 UserName, &nUserName,
940 DomainName, &nDomainName, &sUse))
942 if (bIncludeDomain)
944 wcscpy(Name, DomainName);
945 wcscat(Name, L"/");
946 wcscat(Name, UserName);
948 else
950 wcscpy(Name, UserName);
953 rtl_uString_newFromStr( strName, Name);
955 free(pInfoBuffer);
957 return (sal_True);
960 else
962 DWORD needed=0;
963 sal_Unicode *pNameW=NULL;
965 WNetGetUserW(NULL, NULL, &needed);
966 pNameW = malloc (needed*sizeof(sal_Unicode));
968 if (WNetGetUserW(NULL, pNameW, &needed) == NO_ERROR)
970 rtl_uString_newFromStr( strName, pNameW);
972 if (pNameW)
973 free(pNameW);
974 return (sal_True);
976 else
977 if (wcslen(pSecImpl->m_User) > 0)
979 rtl_uString_newFromStr( strName, pSecImpl->m_pNetResource->lpRemoteName);
981 if (pNameW)
982 free(pNameW);
984 return (sal_True);
987 if (pNameW)
988 free(pNameW);
992 return sal_False;