22 #include <winpr/config.h>
24 #include <winpr/crt.h>
25 #include <winpr/platform.h>
26 #include <winpr/error.h>
27 #include <winpr/file.h>
28 #include <winpr/string.h>
30 #include <winpr/environment.h>
36 #ifdef WINPR_HAVE_UNISTD_H
42 #elif defined(__MACOSX__)
43 #include <crt_externs.h>
44 #define environ (*_NSGetEnviron())
47 DWORD GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
56 char* tmp = realloc(cwd, length);
64 ccwd = getcwd(cwd, length);
65 }
while (!ccwd && (errno == ERANGE));
73 length = strnlen(cwd, length);
75 if ((nBufferLength == 0) && (lpBuffer == NULL))
88 if ((length + 1) > nBufferLength)
91 return (DWORD)(length + 1);
94 memcpy(lpBuffer, cwd, length + 1);
100 DWORD GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
105 BOOL SetCurrentDirectoryA(LPCSTR lpPathName)
110 BOOL SetCurrentDirectoryW(LPCWSTR lpPathName)
115 DWORD SearchPathA(LPCSTR lpPath, LPCSTR lpFileName, LPCSTR lpExtension, DWORD nBufferLength,
116 LPSTR lpBuffer, LPSTR* lpFilePart)
121 DWORD SearchPathW(LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension, DWORD nBufferLength,
122 LPWSTR lpBuffer, LPWSTR* lpFilePart)
127 LPSTR GetCommandLineA(VOID)
132 LPWSTR GetCommandLineW(VOID)
137 BOOL NeedCurrentDirectoryForExePathA(LPCSTR ExeName)
142 BOOL NeedCurrentDirectoryForExePathW(LPCWSTR ExeName)
149 #if !defined(_WIN32) || defined(_UWP)
151 DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
157 env = getenv(lpName);
161 SetLastError(ERROR_ENVVAR_NOT_FOUND);
165 length = strlen(env);
167 if ((length + 1 > nSize) || (!lpBuffer))
168 return (DWORD)length + 1;
170 CopyMemory(lpBuffer, env, length);
171 lpBuffer[length] =
'\0';
173 return (DWORD)length;
175 SetLastError(ERROR_ENVVAR_NOT_FOUND);
180 DWORD GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize)
182 SetLastError(ERROR_ENVVAR_NOT_FOUND);
186 BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
194 if (0 != setenv(lpName, lpValue, 1))
199 if (0 != unsetenv(lpName))
209 BOOL SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
230 extern char** environ;
232 LPCH GetEnvironmentStringsA(VOID)
239 DWORD cchEnvironmentBlock = 0;
240 LPCH lpszEnvironmentBlock = NULL;
245 cchEnvironmentBlock = 128;
246 lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock,
sizeof(CHAR));
247 if (!lpszEnvironmentBlock)
252 length = strlen(*envp);
254 while ((offset + length + 8) > cchEnvironmentBlock)
259 new_size = cchEnvironmentBlock * 2;
260 new_blk = (LPCH)realloc(lpszEnvironmentBlock, new_size *
sizeof(CHAR));
263 free(lpszEnvironmentBlock);
267 lpszEnvironmentBlock = new_blk;
268 cchEnvironmentBlock = new_size;
271 p = &(lpszEnvironmentBlock[offset]);
273 CopyMemory(p, *envp, length *
sizeof(CHAR));
276 offset += (length + 1);
280 lpszEnvironmentBlock[offset] =
'\0';
282 return lpszEnvironmentBlock;
288 LPWCH GetEnvironmentStringsW(VOID)
293 BOOL SetEnvironmentStringsA(LPCH NewEnvironment)
298 BOOL SetEnvironmentStringsW(LPWCH NewEnvironment)
303 DWORD ExpandEnvironmentStringsA(LPCSTR lpSrc, LPSTR lpDst, DWORD nSize)
308 DWORD ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
313 BOOL FreeEnvironmentStringsA(LPCH lpszEnvironmentBlock)
315 free(lpszEnvironmentBlock);
320 BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock)
322 free(lpszEnvironmentBlock);
329 LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge)
331 const char* cp = NULL;
335 const char* envp = NULL;
336 DWORD cchEnvironmentBlock = 0;
337 LPCH lpszEnvironmentBlock = NULL;
338 const char** mergeStrings = NULL;
339 size_t mergeStringLength = 0;
340 size_t mergeArraySize = 128;
341 size_t mergeLength = 0;
342 size_t foundMerge = 0;
343 char* foundEquals = NULL;
345 mergeStrings = (LPCSTR*)calloc(mergeArraySize,
sizeof(
char*));
350 mergeStringLength = 0;
354 while (*cp && *(cp + 1))
358 if (mergeStringLength == mergeArraySize)
360 const char** new_str = NULL;
362 mergeArraySize += 128;
363 new_str = (
const char**)realloc((
void*)mergeStrings, mergeArraySize *
sizeof(
char*));
367 free((
void*)mergeStrings);
370 mergeStrings = new_str;
373 mergeStrings[mergeStringLength] = cp;
380 cchEnvironmentBlock = 128;
381 lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock,
sizeof(CHAR));
383 if (!lpszEnvironmentBlock)
385 free((
void*)mergeStrings);
391 while ((original != NULL) && (*envp && *(envp + 1)))
393 size_t old_offset = offset;
394 length = strlen(envp);
396 while ((offset + length + 8) > cchEnvironmentBlock)
398 cchEnvironmentBlock *= 2;
399 LPCH tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
403 free((
void*)lpszEnvironmentBlock);
404 free((
void*)mergeStrings);
407 lpszEnvironmentBlock = tmp;
410 p = &(lpszEnvironmentBlock[offset]);
414 for (
size_t run = 0; run < mergeStringLength; run++)
416 if (!mergeStrings[run])
419 mergeLength = strlen(mergeStrings[run]);
420 foundEquals = strstr(mergeStrings[run],
"=");
425 if (strncmp(envp, mergeStrings[run], foundEquals - mergeStrings[run] + 1) == 0)
428 if (*(foundEquals + 1) ==
'\0')
435 while ((offset + mergeLength + 8) > cchEnvironmentBlock)
437 cchEnvironmentBlock *= 2;
439 (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
443 free((
void*)lpszEnvironmentBlock);
444 free((
void*)mergeStrings);
447 lpszEnvironmentBlock = tmp;
448 p = &(lpszEnvironmentBlock[old_offset]);
452 CopyMemory(p, mergeStrings[run], mergeLength);
453 mergeStrings[run] = NULL;
454 p[mergeLength] =
'\0';
455 offset += (mergeLength + 1);
462 CopyMemory(p, envp, length *
sizeof(CHAR));
464 offset += (length + 1);
467 envp += (length + 1);
471 for (
size_t run = 0; run < mergeStringLength; run++)
473 if (!mergeStrings[run])
476 mergeLength = strlen(mergeStrings[run]);
478 while ((offset + mergeLength + 8) > cchEnvironmentBlock)
480 cchEnvironmentBlock *= 2;
481 LPCH tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
485 free((
void*)lpszEnvironmentBlock);
486 free((
void*)mergeStrings);
490 lpszEnvironmentBlock = tmp;
493 p = &(lpszEnvironmentBlock[offset]);
495 CopyMemory(p, mergeStrings[run], mergeLength);
496 mergeStrings[run] = NULL;
497 p[mergeLength] =
'\0';
498 offset += (mergeLength + 1);
501 lpszEnvironmentBlock[offset] =
'\0';
503 free((
void*)mergeStrings);
505 return lpszEnvironmentBlock;
508 DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
512 char* foundEquals = NULL;
513 const char* penvb = envBlock;
516 size_t lpNameLength = 0;
518 if (!lpName || NULL == envBlock)
521 lpNameLength = strlen(lpName);
523 if (lpNameLength < 1)
526 while (*penvb && *(penvb + 1))
528 fLength = strlen(penvb);
529 foundEquals = strstr(penvb,
"=");
537 nLength = (foundEquals - penvb);
539 if (nLength != lpNameLength)
541 penvb += (fLength + 1);
545 if (strncmp(penvb, lpName, nLength) == 0)
547 env = foundEquals + 1;
551 penvb += (fLength + 1);
557 vLength = strlen(env);
558 if (vLength >= UINT32_MAX)
561 if ((vLength + 1 > nSize) || (!lpBuffer))
562 return (DWORD)vLength + 1;
564 CopyMemory(lpBuffer, env, vLength + 1);
566 return (DWORD)vLength;
569 BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue)
580 length = (strlen(lpName) + strlen(lpValue) + 2);
581 envstr = (
char*)malloc(length + 1);
586 (void)sprintf_s(envstr, length,
"%s=%s", lpName, lpValue);
590 length = strlen(lpName) + 2;
591 envstr = (
char*)malloc(length + 1);
596 (void)sprintf_s(envstr, length,
"%s=", lpName);
599 envstr[length] =
'\0';
601 newEB = MergeEnvironmentStrings((LPCSTR)*envBlock, envstr);
611 char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock)
620 if (!lpszEnvironmentBlock)
623 p = (
char*)lpszEnvironmentBlock;
633 p = (
char*)lpszEnvironmentBlock;
635 envp = (
char**)calloc(count + 1,
sizeof(
char*));
643 envp[index] = _strdup(p);
646 for (index -= 1; index >= 0; --index)
663 #define WINPR_MAX_ENVIRONMENT_LENGTH 2048
665 DWORD GetEnvironmentVariableX(
const char* lpName,
char* lpBuffer, DWORD nSize)
669 LPWSTR lpNameW = NULL;
670 LPWSTR lpBufferW = NULL;
671 LPSTR lpBufferA = lpBuffer;
673 lpNameW = ConvertUtf8ToWCharAlloc(lpName, NULL);
679 char lpBufferMaxA[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 };
680 WCHAR lpBufferMaxW[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 };
681 LPSTR lpTmpBuffer = lpBufferMaxA;
683 nSizeW = ARRAYSIZE(lpBufferMaxW);
685 result = GetEnvironmentVariableW(lpNameW, lpBufferMaxW, nSizeW);
688 ConvertWCharNToUtf8(lpBufferMaxW, nSizeW, lpTmpBuffer, ARRAYSIZE(lpBufferMaxA));
689 if ((rc < 0) || (rc >= UINT32_MAX))
692 result = (DWORD)rc + 1;
697 lpBufferW = calloc(nSizeW + 1,
sizeof(WCHAR));
702 result = GetEnvironmentVariableW(lpNameW, lpBufferW, nSizeW);
707 SSIZE_T rc = ConvertWCharNToUtf8(lpBufferW, nSizeW, lpBufferA, nSize);
708 if ((rc < 0) || (rc > UINT32_MAX))
723 DWORD GetEnvironmentVariableX(
const char* lpName,
char* lpBuffer, DWORD nSize)
725 return GetEnvironmentVariableA(lpName, lpBuffer, nSize);