22#include <winpr/config.h>
25#include <winpr/platform.h>
26#include <winpr/error.h>
27#include <winpr/file.h>
28#include <winpr/string.h>
29#include <winpr/wlog.h>
31#include <winpr/environment.h>
37#ifdef WINPR_HAVE_UNISTD_H
43#elif defined(__MACOSX__)
44#include <crt_externs.h>
45#define environ (*_NSGetEnviron())
48DWORD GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
57 char* tmp = realloc(cwd, length);
65 ccwd = getcwd(cwd, length);
66 }
while (!ccwd && (errno == ERANGE));
74 length = strnlen(cwd, length);
76 if ((nBufferLength == 0) && (lpBuffer == NULL))
89 if ((length + 1) > nBufferLength)
92 return (DWORD)(length + 1);
95 memcpy(lpBuffer, cwd, length + 1);
101DWORD GetCurrentDirectoryW(WINPR_ATTR_UNUSED DWORD nBufferLength, WINPR_ATTR_UNUSED LPWSTR lpBuffer)
103 WLog_ERR(
"TODO",
"TODO: not implemented");
107BOOL SetCurrentDirectoryA(WINPR_ATTR_UNUSED LPCSTR lpPathName)
109 WLog_ERR(
"TODO",
"TODO: not implemented");
113BOOL SetCurrentDirectoryW(WINPR_ATTR_UNUSED LPCWSTR lpPathName)
115 WLog_ERR(
"TODO",
"TODO: not implemented");
119DWORD SearchPathA(WINPR_ATTR_UNUSED LPCSTR lpPath, WINPR_ATTR_UNUSED LPCSTR lpFileName,
120 WINPR_ATTR_UNUSED LPCSTR lpExtension, WINPR_ATTR_UNUSED DWORD nBufferLength,
121 WINPR_ATTR_UNUSED LPSTR lpBuffer, WINPR_ATTR_UNUSED LPSTR* lpFilePart)
123 WLog_ERR(
"TODO",
"TODO: not implemented");
127DWORD SearchPathW(WINPR_ATTR_UNUSED LPCWSTR lpPath, WINPR_ATTR_UNUSED LPCWSTR lpFileName,
128 WINPR_ATTR_UNUSED LPCWSTR lpExtension, WINPR_ATTR_UNUSED DWORD nBufferLength,
129 WINPR_ATTR_UNUSED LPWSTR lpBuffer, WINPR_ATTR_UNUSED LPWSTR* lpFilePart)
131 WLog_ERR(
"TODO",
"TODO: not implemented");
135LPSTR GetCommandLineA(VOID)
137 WLog_ERR(
"TODO",
"TODO: not implemented");
141LPWSTR GetCommandLineW(VOID)
143 WLog_ERR(
"TODO",
"TODO: not implemented");
147BOOL NeedCurrentDirectoryForExePathA(WINPR_ATTR_UNUSED LPCSTR ExeName)
149 WLog_ERR(
"TODO",
"TODO: not implemented");
153BOOL NeedCurrentDirectoryForExePathW(WINPR_ATTR_UNUSED LPCWSTR ExeName)
155 WLog_ERR(
"TODO",
"TODO: not implemented");
161#if !defined(_WIN32) || defined(_UWP)
163DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
169 char* env = getenv(lpName);
173 SetLastError(ERROR_ENVVAR_NOT_FOUND);
177 length = strlen(env);
179 if ((length + 1 > nSize) || (!lpBuffer))
180 return (DWORD)length + 1;
182 CopyMemory(lpBuffer, env, length);
183 lpBuffer[length] =
'\0';
185 return (DWORD)length;
187 SetLastError(ERROR_ENVVAR_NOT_FOUND);
192DWORD GetEnvironmentVariableW(WINPR_ATTR_UNUSED LPCWSTR lpName, WINPR_ATTR_UNUSED LPWSTR lpBuffer,
193 WINPR_ATTR_UNUSED DWORD nSize)
195 WLog_ERR(
"TODO",
"TODO: not implemented");
196 SetLastError(ERROR_ENVVAR_NOT_FOUND);
200BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
209 if (0 != setenv(lpName, lpValue, 1))
215 if (0 != unsetenv(lpName))
225BOOL SetEnvironmentVariableW(WINPR_ATTR_UNUSED LPCWSTR lpName, WINPR_ATTR_UNUSED LPCWSTR lpValue)
227 WLog_ERR(
"TODO",
"TODO: not implemented");
247extern char** environ;
249LPCH GetEnvironmentStringsA(VOID)
256 DWORD cchEnvironmentBlock = 0;
257 LPCH lpszEnvironmentBlock = NULL;
262 cchEnvironmentBlock = 128;
263 lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock,
sizeof(CHAR));
264 if (!lpszEnvironmentBlock)
269 length = strlen(*envp);
271 while ((offset + length + 8) > cchEnvironmentBlock)
276 new_size = cchEnvironmentBlock * 2;
277 new_blk = (LPCH)realloc(lpszEnvironmentBlock, new_size *
sizeof(CHAR));
280 free(lpszEnvironmentBlock);
284 lpszEnvironmentBlock = new_blk;
285 cchEnvironmentBlock = new_size;
288 p = &(lpszEnvironmentBlock[offset]);
290 CopyMemory(p, *envp, length *
sizeof(CHAR));
293 offset += (length + 1);
297 lpszEnvironmentBlock[offset] =
'\0';
299 return lpszEnvironmentBlock;
305LPWCH GetEnvironmentStringsW(VOID)
307 WLog_ERR(
"TODO",
"TODO: not implemented");
311BOOL SetEnvironmentStringsA(WINPR_ATTR_UNUSED LPCH NewEnvironment)
313 WLog_ERR(
"TODO",
"TODO: not implemented");
317BOOL SetEnvironmentStringsW(WINPR_ATTR_UNUSED LPWCH NewEnvironment)
319 WLog_ERR(
"TODO",
"TODO: not implemented");
323DWORD ExpandEnvironmentStringsA(WINPR_ATTR_UNUSED LPCSTR lpSrc, WINPR_ATTR_UNUSED LPSTR lpDst,
324 WINPR_ATTR_UNUSED DWORD nSize)
326 WLog_ERR(
"TODO",
"TODO: not implemented");
330DWORD ExpandEnvironmentStringsW(WINPR_ATTR_UNUSED LPCWSTR lpSrc, WINPR_ATTR_UNUSED LPWSTR lpDst,
331 WINPR_ATTR_UNUSED DWORD nSize)
333 WLog_ERR(
"TODO",
"TODO: not implemented");
337BOOL FreeEnvironmentStringsA(LPCH lpszEnvironmentBlock)
339 free(lpszEnvironmentBlock);
344BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock)
346 free(lpszEnvironmentBlock);
353LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge)
355 const char* cp = NULL;
359 const char* envp = NULL;
360 DWORD cchEnvironmentBlock = 0;
361 LPCH lpszEnvironmentBlock = NULL;
362 const char** mergeStrings = NULL;
363 size_t mergeStringLength = 0;
364 size_t mergeArraySize = 128;
365 size_t mergeLength = 0;
366 size_t foundMerge = 0;
367 char* foundEquals = NULL;
369 mergeStrings = (LPCSTR*)calloc(mergeArraySize,
sizeof(
char*));
374 mergeStringLength = 0;
378 while (*cp && *(cp + 1))
382 if (mergeStringLength == mergeArraySize)
384 const char** new_str = NULL;
386 mergeArraySize += 128;
387 new_str = (
const char**)realloc((
void*)mergeStrings, mergeArraySize *
sizeof(
char*));
391 free((
void*)mergeStrings);
394 mergeStrings = new_str;
397 mergeStrings[mergeStringLength] = cp;
404 cchEnvironmentBlock = 128;
405 lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock,
sizeof(CHAR));
407 if (!lpszEnvironmentBlock)
409 free((
void*)mergeStrings);
415 while ((original != NULL) && (*envp && *(envp + 1)))
417 size_t old_offset = offset;
418 length = strlen(envp);
420 while ((offset + length + 8) > cchEnvironmentBlock)
422 cchEnvironmentBlock *= 2;
423 LPCH tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
427 free((
void*)lpszEnvironmentBlock);
428 free((
void*)mergeStrings);
431 lpszEnvironmentBlock = tmp;
434 p = &(lpszEnvironmentBlock[offset]);
438 for (
size_t run = 0; run < mergeStringLength; run++)
440 if (!mergeStrings[run])
443 mergeLength = strlen(mergeStrings[run]);
444 foundEquals = strstr(mergeStrings[run],
"=");
449 const intptr_t len = foundEquals - mergeStrings[run] + 1;
450 if (strncmp(envp, mergeStrings[run], WINPR_ASSERTING_INT_CAST(
size_t, len)) == 0)
453 if (*(foundEquals + 1) ==
'\0')
460 while ((offset + mergeLength + 8) > cchEnvironmentBlock)
462 cchEnvironmentBlock *= 2;
464 (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
468 free((
void*)lpszEnvironmentBlock);
469 free((
void*)mergeStrings);
472 lpszEnvironmentBlock = tmp;
473 p = &(lpszEnvironmentBlock[old_offset]);
477 CopyMemory(p, mergeStrings[run], mergeLength);
478 mergeStrings[run] = NULL;
479 p[mergeLength] =
'\0';
480 offset += (mergeLength + 1);
487 CopyMemory(p, envp, length *
sizeof(CHAR));
489 offset += (length + 1);
492 envp += (length + 1);
496 for (
size_t run = 0; run < mergeStringLength; run++)
498 if (!mergeStrings[run])
501 mergeLength = strlen(mergeStrings[run]);
503 while ((offset + mergeLength + 8) > cchEnvironmentBlock)
505 cchEnvironmentBlock *= 2;
506 LPCH tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock *
sizeof(CHAR));
510 free((
void*)lpszEnvironmentBlock);
511 free((
void*)mergeStrings);
515 lpszEnvironmentBlock = tmp;
518 p = &(lpszEnvironmentBlock[offset]);
520 CopyMemory(p, mergeStrings[run], mergeLength);
521 mergeStrings[run] = NULL;
522 p[mergeLength] =
'\0';
523 offset += (mergeLength + 1);
526 lpszEnvironmentBlock[offset] =
'\0';
528 free((
void*)mergeStrings);
530 return lpszEnvironmentBlock;
533DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
537 char* foundEquals = NULL;
538 const char* penvb = envBlock;
541 size_t lpNameLength = 0;
543 if (!lpName || NULL == envBlock)
546 lpNameLength = strlen(lpName);
548 if (lpNameLength < 1)
551 while (*penvb && *(penvb + 1))
553 fLength = strlen(penvb);
554 foundEquals = strstr(penvb,
"=");
562 nLength = WINPR_ASSERTING_INT_CAST(
size_t, (foundEquals - penvb));
564 if (nLength != lpNameLength)
566 penvb += (fLength + 1);
570 if (strncmp(penvb, lpName, nLength) == 0)
572 env = foundEquals + 1;
576 penvb += (fLength + 1);
582 vLength = strlen(env);
583 if (vLength >= UINT32_MAX)
586 if ((vLength + 1 > nSize) || (!lpBuffer))
587 return (DWORD)vLength + 1;
589 CopyMemory(lpBuffer, env, vLength + 1);
591 return (DWORD)vLength;
594BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue)
605 length = (strlen(lpName) + strlen(lpValue) + 2);
606 envstr = (
char*)malloc(length + 1);
611 (void)sprintf_s(envstr, length,
"%s=%s", lpName, lpValue);
615 length = strlen(lpName) + 2;
616 envstr = (
char*)malloc(length + 1);
621 (void)sprintf_s(envstr, length,
"%s=", lpName);
624 envstr[length] =
'\0';
626 newEB = MergeEnvironmentStrings((LPCSTR)*envBlock, envstr);
636char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock)
645 if (!lpszEnvironmentBlock)
648 p = (
char*)lpszEnvironmentBlock;
658 p = (
char*)lpszEnvironmentBlock;
660 envp = (
char**)calloc(count + 1,
sizeof(
char*));
668 envp[index] = _strdup(p);
671 for (index -= 1; index >= 0; --index)
688#define WINPR_MAX_ENVIRONMENT_LENGTH 2048
690DWORD GetEnvironmentVariableX(
const char* lpName,
char* lpBuffer, DWORD nSize)
694 LPWSTR lpNameW = NULL;
695 LPWSTR lpBufferW = NULL;
696 LPSTR lpBufferA = lpBuffer;
698 lpNameW = ConvertUtf8ToWCharAlloc(lpName, NULL);
704 char lpBufferMaxA[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 };
705 WCHAR lpBufferMaxW[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 };
706 LPSTR lpTmpBuffer = lpBufferMaxA;
708 nSizeW = ARRAYSIZE(lpBufferMaxW);
710 result = GetEnvironmentVariableW(lpNameW, lpBufferMaxW, nSizeW);
713 ConvertWCharNToUtf8(lpBufferMaxW, nSizeW, lpTmpBuffer, ARRAYSIZE(lpBufferMaxA));
714 if ((rc < 0) || (rc >= UINT32_MAX))
717 result = (DWORD)rc + 1;
722 lpBufferW = calloc(nSizeW + 1,
sizeof(WCHAR));
727 result = GetEnvironmentVariableW(lpNameW, lpBufferW, nSizeW);
732 SSIZE_T rc = ConvertWCharNToUtf8(lpBufferW, nSizeW, lpBufferA, nSize);
733 if ((rc < 0) || (rc > UINT32_MAX))
748DWORD GetEnvironmentVariableX(
const char* lpName,
char* lpBuffer, DWORD nSize)
750 return GetEnvironmentVariableA(lpName, lpBuffer, nSize);