123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- /**
- * WinPR: Windows Portable Runtime
- * Process Environment Functions
- *
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
- * Copyright 2013 Thincast Technologies GmbH
- * Copyright 2013 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <winpr/crt.h>
- #include <winpr/platform.h>
- #include <winpr/error.h>
- #include <winpr/environment.h>
- #ifndef _WIN32
- #define stricmp strcasecmp
- #define strnicmp strncasecmp
- #include <winpr/crt.h>
- #include <winpr/platform.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #if defined(__IOS__)
- #elif defined(__MACOSX__)
- #include <crt_externs.h>
- #define environ (*_NSGetEnviron())
- #endif
- DWORD GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
- {
- char* cwd;
- size_t length;
- cwd = getcwd(NULL, 0);
- if (!cwd)
- return 0;
- length = strlen(cwd);
- if ((nBufferLength == 0) && (lpBuffer == NULL))
- {
- free(cwd);
- return (DWORD)length;
- }
- else
- {
- if (lpBuffer == NULL)
- {
- free(cwd);
- return 0;
- }
- if ((length + 1) > nBufferLength)
- {
- free(cwd);
- return (DWORD)(length + 1);
- }
- memcpy(lpBuffer, cwd, length + 1);
- free(cwd);
- return length;
- }
- return 0;
- }
- DWORD GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
- }
- // implement it [3/18/2020 18:36 Gifur]
- BOOL SetCurrentDirectoryA(LPCSTR lpPathName)
- {
- if (chdir(lpPathName) == -1) {
- fprintf(stderr, "chdir failed: %s\n", strerror(errno));
- return FALSE;
- }
- return TRUE;
- }
- BOOL SetCurrentDirectoryW(LPCWSTR lpPathName)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- }
- DWORD SearchPathA(LPCSTR lpPath, LPCSTR lpFileName, LPCSTR lpExtension, DWORD nBufferLength,
- LPSTR lpBuffer, LPSTR* lpFilePart)
- {
- return 0;
- }
- DWORD SearchPathW(LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension, DWORD nBufferLength,
- LPWSTR lpBuffer, LPWSTR* lpFilePart)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
- }
- LPSTR GetCommandLineA(VOID)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
- }
- LPWSTR GetCommandLineW(VOID)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
- }
- BOOL NeedCurrentDirectoryForExePathA(LPCSTR ExeName)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return TRUE;
- }
- BOOL NeedCurrentDirectoryForExePathW(LPCWSTR ExeName)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return TRUE;
- }
- #endif
- #if !defined(_WIN32) || defined(_UWP)
- DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
- {
- #if !defined(_UWP)
- size_t length;
- char* env = NULL;
- env = getenv(lpName);
- if (!env)
- {
- SetLastError(ERROR_ENVVAR_NOT_FOUND);
- return 0;
- }
- length = strlen(env);
- if ((length + 1 > nSize) || (!lpBuffer))
- return length + 1;
- CopyMemory(lpBuffer, env, length);
- lpBuffer[length] = '\0';
- return length;
- #else
- SetLastError(ERROR_ENVVAR_NOT_FOUND);
- return 0;
- #endif
- }
- DWORD GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize)
- {
- SetLastError(ERROR_ENVVAR_NOT_FOUND);
- return 0;
- }
- BOOL SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
- {
- #if !defined(_UWP)
- if (!lpName)
- return FALSE;
- if (lpValue)
- {
- if (0 != setenv(lpName, lpValue, 1))
- return FALSE;
- }
- else
- {
- if (0 != unsetenv(lpName))
- return FALSE;
- }
- return TRUE;
- #else
- return FALSE;
- #endif
- }
- BOOL SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
- {
- return FALSE;
- }
- /**
- * GetEnvironmentStrings function:
- * http://msdn.microsoft.com/en-us/library/windows/desktop/ms683187/
- *
- * The GetEnvironmentStrings function returns a pointer to a block of memory
- * that contains the environment variables of the calling process (both the
- * system and the user environment variables). Each environment block contains
- * the environment variables in the following format:
- *
- * Var1=Value1\0
- * Var2=Value2\0
- * Var3=Value3\0
- * ...
- * VarN=ValueN\0\0
- */
- extern char** environ;
- LPCH GetEnvironmentStringsA(VOID)
- {
- #if !defined(_UWP)
- char* p;
- size_t offset;
- size_t length;
- char** envp;
- DWORD cchEnvironmentBlock;
- LPCH lpszEnvironmentBlock;
- offset = 0;
- envp = environ;
- cchEnvironmentBlock = 128;
- lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock, sizeof(CHAR));
- if (!lpszEnvironmentBlock)
- return NULL;
- while (*envp)
- {
- length = strlen(*envp);
- while ((offset + length + 8) > cchEnvironmentBlock)
- {
- DWORD new_size;
- LPCH new_blk;
- new_size = cchEnvironmentBlock * 2;
- new_blk = (LPCH)realloc(lpszEnvironmentBlock, new_size * sizeof(CHAR));
- if (!new_blk)
- {
- free(lpszEnvironmentBlock);
- return NULL;
- }
- lpszEnvironmentBlock = new_blk;
- cchEnvironmentBlock = new_size;
- }
- p = &(lpszEnvironmentBlock[offset]);
- CopyMemory(p, *envp, length * sizeof(CHAR));
- p[length] = '\0';
- offset += (length + 1);
- envp++;
- }
- lpszEnvironmentBlock[offset] = '\0';
- return lpszEnvironmentBlock;
- #else
- return NULL;
- #endif
- }
- LPWCH GetEnvironmentStringsW(VOID)
- {
- return NULL;
- }
- BOOL SetEnvironmentStringsA(LPCH NewEnvironment)
- {
- return TRUE;
- }
- BOOL SetEnvironmentStringsW(LPWCH NewEnvironment)
- {
- return TRUE;
- }
- DWORD ExpandEnvironmentStringsA(LPCSTR lpSrc, LPSTR lpDst, DWORD nSize)
- {
- return 0;
- }
- DWORD ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize)
- {
- return 0;
- }
- BOOL FreeEnvironmentStringsA(LPCH lpszEnvironmentBlock)
- {
- free(lpszEnvironmentBlock);
- return TRUE;
- }
- BOOL FreeEnvironmentStringsW(LPWCH lpszEnvironmentBlock)
- {
- return TRUE;
- }
- #endif
- LPCH MergeEnvironmentStrings(PCSTR original, PCSTR merge)
- {
- const char* cp;
- char* p;
- size_t offset;
- size_t length;
- const char* envp;
- DWORD cchEnvironmentBlock;
- LPCH lpszEnvironmentBlock;
- const char** mergeStrings;
- size_t mergeStringLength;
- size_t mergeArraySize = 128;
- size_t run;
- size_t mergeLength;
- size_t foundMerge;
- char* foundEquals;
- mergeStrings = (LPCSTR*)calloc(mergeArraySize, sizeof(char*));
- if (!mergeStrings)
- return NULL;
- mergeStringLength = 0;
- cp = merge;
- while (*cp && *(cp + 1))
- {
- length = strlen(cp);
- if (mergeStringLength == mergeArraySize)
- {
- const char** new_str;
- mergeArraySize += 128;
- new_str = (const char**)realloc((void*)mergeStrings, mergeArraySize * sizeof(char*));
- if (!new_str)
- {
- free((void*)mergeStrings);
- return NULL;
- }
- mergeStrings = new_str;
- }
- mergeStrings[mergeStringLength] = cp;
- cp += length + 1;
- mergeStringLength++;
- }
- offset = 0;
- cchEnvironmentBlock = 128;
- lpszEnvironmentBlock = (LPCH)calloc(cchEnvironmentBlock, sizeof(CHAR));
- if (!lpszEnvironmentBlock)
- {
- free((void*)mergeStrings);
- return NULL;
- }
- envp = original;
- while ((original != NULL) && (*envp && *(envp + 1)))
- {
- size_t old_offset = offset;
- length = strlen(envp);
- while ((offset + length + 8) > cchEnvironmentBlock)
- {
- LPCH tmp;
- cchEnvironmentBlock *= 2;
- tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
- if (!tmp)
- {
- free((void*)lpszEnvironmentBlock);
- free((void*)mergeStrings);
- return NULL;
- }
- lpszEnvironmentBlock = tmp;
- }
- p = &(lpszEnvironmentBlock[offset]);
- // check if this value is in the mergeStrings
- foundMerge = 0;
- for (run = 0; run < mergeStringLength; run++)
- {
- if (!mergeStrings[run])
- continue;
- mergeLength = strlen(mergeStrings[run]);
- foundEquals = strstr(mergeStrings[run], "=");
- if (!foundEquals)
- continue;
- if (strncmp(envp, mergeStrings[run], foundEquals - mergeStrings[run] + 1) == 0)
- {
- // found variable in merge list ... use this ....
- if (*(foundEquals + 1) == '\0')
- {
- // check if the argument is set ... if not remove variable ...
- foundMerge = 1;
- }
- else
- {
- while ((offset + mergeLength + 8) > cchEnvironmentBlock)
- {
- LPCH tmp;
- cchEnvironmentBlock *= 2;
- tmp =
- (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
- if (!tmp)
- {
- free((void*)lpszEnvironmentBlock);
- free((void*)mergeStrings);
- return NULL;
- }
- lpszEnvironmentBlock = tmp;
- p = &(lpszEnvironmentBlock[old_offset]);
- }
- foundMerge = 1;
- CopyMemory(p, mergeStrings[run], mergeLength);
- mergeStrings[run] = NULL;
- p[mergeLength] = '\0';
- offset += (mergeLength + 1);
- }
- }
- }
- if (foundMerge == 0)
- {
- CopyMemory(p, envp, length * sizeof(CHAR));
- p[length] = '\0';
- offset += (length + 1);
- }
- envp += (length + 1);
- }
- // now merge the not already merged env
- for (run = 0; run < mergeStringLength; run++)
- {
- if (!mergeStrings[run])
- continue;
- mergeLength = strlen(mergeStrings[run]);
- while ((offset + mergeLength + 8) > cchEnvironmentBlock)
- {
- LPCH tmp;
- cchEnvironmentBlock *= 2;
- tmp = (LPCH)realloc(lpszEnvironmentBlock, cchEnvironmentBlock * sizeof(CHAR));
- if (!tmp)
- {
- free((void*)lpszEnvironmentBlock);
- free((void*)mergeStrings);
- return NULL;
- }
- lpszEnvironmentBlock = tmp;
- }
- p = &(lpszEnvironmentBlock[offset]);
- CopyMemory(p, mergeStrings[run], mergeLength);
- mergeStrings[run] = NULL;
- p[mergeLength] = '\0';
- offset += (mergeLength + 1);
- }
- lpszEnvironmentBlock[offset] = '\0';
- free((void*)mergeStrings);
- return lpszEnvironmentBlock;
- }
- DWORD GetEnvironmentVariableEBA(LPCSTR envBlock, LPCSTR lpName, LPSTR lpBuffer, DWORD nSize)
- {
- size_t vLength = 0;
- char* env = NULL;
- char* foundEquals;
- const char* penvb = envBlock;
- size_t nLength, fLength, lpNameLength;
- if (!lpName || NULL == envBlock)
- return 0;
- lpNameLength = strlen(lpName);
- if (lpNameLength < 1)
- return 0;
- while (*penvb && *(penvb + 1))
- {
- fLength = strlen(penvb);
- foundEquals = strstr(penvb, "=");
- if (!foundEquals)
- {
- /* if no = sign is found the envBlock is broken */
- return 0;
- }
- nLength = (foundEquals - penvb);
- if (nLength != lpNameLength)
- {
- penvb += (fLength + 1);
- continue;
- }
- if (strncmp(penvb, lpName, nLength) == 0)
- {
- env = foundEquals + 1;
- break;
- }
- penvb += (fLength + 1);
- }
- if (!env)
- return 0;
- vLength = strlen(env);
- if ((vLength + 1 > nSize) || (!lpBuffer))
- return vLength + 1;
- CopyMemory(lpBuffer, env, vLength + 1);
- return vLength;
- }
- BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue)
- {
- int length;
- char* envstr;
- char* newEB;
- if (!lpName)
- return FALSE;
- if (lpValue)
- {
- length = (int)(strlen(lpName) + strlen(lpValue) + 2); /* +2 because of = and \0 */
- envstr = (char*)malloc(length + 1); /* +1 because of closing \0 */
- if (!envstr)
- return FALSE;
- sprintf_s(envstr, length, "%s=%s", lpName, lpValue);
- }
- else
- {
- length = (int)strlen(lpName) + 2; /* +2 because of = and \0 */
- envstr = (char*)malloc(length + 1); /* +1 because of closing \0 */
- if (!envstr)
- return FALSE;
- sprintf_s(envstr, length, "%s=", lpName);
- }
- envstr[length] = '\0';
- newEB = MergeEnvironmentStrings((LPCSTR)*envBlock, envstr);
- free(envstr);
- free(*envBlock);
- *envBlock = newEB;
- return TRUE;
- }
- char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock)
- {
- char* p;
- SSIZE_T index;
- size_t count;
- size_t length;
- char** envp = NULL;
- count = 0;
- if (!lpszEnvironmentBlock)
- return NULL;
- p = (char*)lpszEnvironmentBlock;
- while (p[0] && p[1])
- {
- length = strlen(p);
- p += (length + 1);
- count++;
- }
- index = 0;
- p = (char*)lpszEnvironmentBlock;
- envp = (char**)calloc(count + 1, sizeof(char*));
- if (!envp)
- return NULL;
- envp[count] = NULL;
- while (p[0] && p[1])
- {
- length = strlen(p);
- envp[index] = _strdup(p);
- if (!envp[index])
- {
- for (index -= 1; index >= 0; --index)
- {
- free(envp[index]);
- }
- free(envp);
- return NULL;
- }
- p += (length + 1);
- index++;
- }
- return envp;
- }
|