20 #include <winpr/config.h>
22 #include <winpr/shell.h>
33 #include <winpr/crt.h>
35 #ifdef WINPR_HAVE_UNISTD_H
42 #include "../handle/handle.h"
44 #include "../security/security.h"
46 BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize)
48 struct passwd pwd = { 0 };
49 struct passwd* pw = NULL;
50 WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)hToken;
52 if (!AccessTokenIsValid(hToken))
57 SetLastError(ERROR_INVALID_PARAMETER);
61 long buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
65 const size_t s = 1ULL + (size_t)buflen;
66 char* buf = calloc(s,
sizeof(
char));
71 const int status = getpwnam_r(token->Username, &pwd, buf, buflen, &pw);
73 if ((status != 0) || !pw)
75 SetLastError(ERROR_INVALID_PARAMETER);
80 const size_t cchDirSize = strlen(pw->pw_dir) + 1;
81 if (cchDirSize > UINT32_MAX)
83 SetLastError(ERROR_INVALID_PARAMETER);
88 if (!lpProfileDir || (*lpcchSize < cchDirSize))
90 *lpcchSize = (UINT32)cchDirSize;
91 SetLastError(ERROR_INSUFFICIENT_BUFFER);
96 ZeroMemory(lpProfileDir, *lpcchSize);
97 (void)sprintf_s(lpProfileDir, *lpcchSize,
"%s", pw->pw_dir);
98 *lpcchSize = (UINT32)cchDirSize;
103 BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize)
107 LPSTR lpProfileDirA = NULL;
111 SetLastError(ERROR_INVALID_PARAMETER);
115 cchSizeA = *lpcchSize;
116 lpProfileDirA = NULL;
120 lpProfileDirA = (LPSTR)malloc(cchSizeA);
122 if (lpProfileDirA == NULL)
124 SetLastError(ERROR_OUTOFMEMORY);
129 bStatus = GetUserProfileDirectoryA(hToken, lpProfileDirA, &cchSizeA);
133 SSIZE_T size = ConvertUtf8NToWChar(lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize);
142 *lpcchSize = cchSizeA;