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 const intptr_t len = foundEquals - mergeStrings[run] + 1;
426 if (strncmp(envp, mergeStrings[run], WINPR_ASSERTING_INT_CAST(
size_t, len)) == 0)
429 if (*(foundEquals + 1) ==
'\0')
436 while ((offset + mergeLength + 8) > cchEnvironmentBlock)
438 cchEnvironmentBlock *= 2;
440 (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
444 free((
void*)lpszEnvironmentBlock);
445 free((
void*)mergeStrings);
448 lpszEnvironmentBlock = tmp;
449 p = &(lpszEnvironmentBlock[old_offset]);
453 CopyMemory(p, mergeStrings[run], mergeLength);
454 mergeStrings[run] = NULL;
455 p[mergeLength] =
'\0';
456 offset += (mergeLength + 1);
463 CopyMemory(p, envp, length *
sizeof(CHAR));
465 offset += (length + 1);
468 envp += (length + 1);
472 for (
size_t run = 0; run < mergeStringLength; run++)
474 if (!mergeStrings[run])
477 mergeLength = strlen(mergeStrings[run]);
479 while ((offset + mergeLength + 8) > cchEnvironmentBlock)
481 cchEnvironmentBlock *= 2;
482 LPCH tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
486 free((
void*)lpszEnvironmentBlock);
487 free((
void*)mergeStrings);
491 lpszEnvironmentBlock = tmp;
494 p = &(lpszEnvironmentBlock[offset]);
496 CopyMemory(p, mergeStrings[run], mergeLength);
497 mergeStrings[run] = NULL;
498 p[mergeLength] =
'\0';
499 offset += (mergeLength + 1);
502 lpszEnvironmentBlock[offset] =
'\0';
504 free((
void*)mergeStrings);
506 return lpszEnvironmentBlock;
509 DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
513 char* foundEquals = NULL;
514 const char* penvb = envBlock;
517 size_t lpNameLength = 0;
519 if (!lpName || NULL == envBlock)
522 lpNameLength = strlen(lpName);
524 if (lpNameLength < 1)
527 while (*penvb && *(penvb + 1))
529 fLength = strlen(penvb);
530 foundEquals = strstr(penvb,
"=");
538 nLength = WINPR_ASSERTING_INT_CAST(
size_t, (foundEquals - penvb));
540 if (nLength != lpNameLength)
542 penvb += (fLength + 1);
546 if (strncmp(penvb, lpName, nLength) == 0)
548 env = foundEquals + 1;
552 penvb += (fLength + 1);
558 vLength = strlen(env);
559 if (vLength >= UINT32_MAX)
562 if ((vLength + 1 > nSize) || (!lpBuffer))
563 return (DWORD)vLength + 1;
565 CopyMemory(lpBuffer, env, vLength + 1);
567 return (DWORD)vLength;
570 BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue)
581 length = (strlen(lpName) + strlen(lpValue) + 2);
582 envstr = (
char*)malloc(length + 1);
587 (void)sprintf_s(envstr, length,
"%s=%s", lpName, lpValue);
591 length = strlen(lpName) + 2;
592 envstr = (
char*)malloc(length + 1);
597 (void)sprintf_s(envstr, length,
"%s=", lpName);
600 envstr[length] =
'\0';
602 newEB = MergeEnvironmentStrings((LPCSTR)*envBlock, envstr);
612 char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock)
621 if (!lpszEnvironmentBlock)
624 p = (
char*)lpszEnvironmentBlock;
634 p = (
char*)lpszEnvironmentBlock;
636 envp = (
char**)calloc(count + 1,
sizeof(
char*));
644 envp[index] = _strdup(p);
647 for (index -= 1; index >= 0; --index)
664 #define WINPR_MAX_ENVIRONMENT_LENGTH 2048
666 DWORD GetEnvironmentVariableX(
const char* lpName,
char* lpBuffer, DWORD nSize)
670 LPWSTR lpNameW = NULL;
671 LPWSTR lpBufferW = NULL;
672 LPSTR lpBufferA = lpBuffer;
674 lpNameW = ConvertUtf8ToWCharAlloc(lpName, NULL);
680 char lpBufferMaxA[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 };
681 WCHAR lpBufferMaxW[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 };
682 LPSTR lpTmpBuffer = lpBufferMaxA;
684 nSizeW = ARRAYSIZE(lpBufferMaxW);
686 result = GetEnvironmentVariableW(lpNameW, lpBufferMaxW, nSizeW);
689 ConvertWCharNToUtf8(lpBufferMaxW, nSizeW, lpTmpBuffer, ARRAYSIZE(lpBufferMaxA));
690 if ((rc < 0) || (rc >= UINT32_MAX))
693 result = (DWORD)rc + 1;
698 lpBufferW = calloc(nSizeW + 1,
sizeof(WCHAR));
703 result = GetEnvironmentVariableW(lpNameW, lpBufferW, nSizeW);
708 SSIZE_T rc = ConvertWCharNToUtf8(lpBufferW, nSizeW, lpBufferA, nSize);
709 if ((rc < 0) || (rc > UINT32_MAX))
724 DWORD GetEnvironmentVariableX(
const char* lpName,
char* lpBuffer, DWORD nSize)
726 return GetEnvironmentVariableA(lpName, lpBuffer, nSize);