diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:24:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:24:41 +0000 |
commit | a9bcc81f821d7c66f623779fa5147e728eb3c388 (patch) | |
tree | 98676963bcdd537ae5908a067a8eb110b93486a6 /winpr/libwinpr/environment | |
parent | Initial commit. (diff) | |
download | freerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.tar.xz freerdp3-a9bcc81f821d7c66f623779fa5147e728eb3c388.zip |
Adding upstream version 3.3.0+dfsg1.upstream/3.3.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'winpr/libwinpr/environment')
8 files changed, 1054 insertions, 0 deletions
diff --git a/winpr/libwinpr/environment/CMakeLists.txt b/winpr/libwinpr/environment/CMakeLists.txt new file mode 100644 index 0000000..53c2818 --- /dev/null +++ b/winpr/libwinpr/environment/CMakeLists.txt @@ -0,0 +1,22 @@ +# WinPR: Windows Portable Runtime +# libwinpr-environment cmake build script +# +# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.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. + +winpr_module_add(environment.c) + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/environment/ModuleOptions.cmake b/winpr/libwinpr/environment/ModuleOptions.cmake new file mode 100644 index 0000000..d7b39ae --- /dev/null +++ b/winpr/libwinpr/environment/ModuleOptions.cmake @@ -0,0 +1,9 @@ + +set(MINWIN_LAYER "1") +set(MINWIN_GROUP "core") +set(MINWIN_MAJOR_VERSION "2") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "processenvironment") +set(MINWIN_LONG_NAME "Process Environment Functions") +set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}") + diff --git a/winpr/libwinpr/environment/environment.c b/winpr/libwinpr/environment/environment.c new file mode 100644 index 0000000..c6df6bd --- /dev/null +++ b/winpr/libwinpr/environment/environment.c @@ -0,0 +1,708 @@ +/** + * 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. + */ + +#include <winpr/config.h> + +#include <winpr/crt.h> +#include <winpr/platform.h> +#include <winpr/error.h> +#include <winpr/string.h> + +#include <winpr/environment.h> + +#ifndef _WIN32 + +#ifdef WINPR_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 = NULL; + size_t length = 0; + + 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 (DWORD)length; + } +} + +DWORD GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer) +{ + return 0; +} + +BOOL SetCurrentDirectoryA(LPCSTR lpPathName) +{ + return TRUE; +} + +BOOL SetCurrentDirectoryW(LPCWSTR lpPathName) +{ + return TRUE; +} + +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) +{ + return 0; +} + +LPSTR GetCommandLineA(VOID) +{ + return NULL; +} + +LPWSTR GetCommandLineW(VOID) +{ + return NULL; +} + +BOOL NeedCurrentDirectoryForExePathA(LPCSTR ExeName) +{ + return TRUE; +} + +BOOL NeedCurrentDirectoryForExePathW(LPCWSTR ExeName) +{ + return TRUE; +} + +#endif + +#if !defined(_WIN32) || defined(_UWP) + +DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSize) +{ +#if !defined(_UWP) + size_t length = 0; + char* env = NULL; + + env = getenv(lpName); + + if (!env) + { + SetLastError(ERROR_ENVVAR_NOT_FOUND); + return 0; + } + + length = strlen(env); + + if ((length + 1 > nSize) || (!lpBuffer)) + return (DWORD)length + 1; + + CopyMemory(lpBuffer, env, length); + lpBuffer[length] = '\0'; + + return (DWORD)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 = NULL; + size_t offset = 0; + size_t length = 0; + char** envp = NULL; + DWORD cchEnvironmentBlock = 0; + LPCH lpszEnvironmentBlock = NULL; + + 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 = 0; + LPCH new_blk = NULL; + + 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 = NULL; + char* p = NULL; + size_t offset = 0; + size_t length = 0; + const char* envp = NULL; + DWORD cchEnvironmentBlock = 0; + LPCH lpszEnvironmentBlock = NULL; + const char** mergeStrings = NULL; + size_t mergeStringLength = 0; + size_t mergeArraySize = 128; + size_t mergeLength = 0; + size_t foundMerge = 0; + char* foundEquals = NULL; + + 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 = NULL; + + 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) + { + cchEnvironmentBlock *= 2; + LPCH 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 (size_t 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) + { + cchEnvironmentBlock *= 2; + LPCH 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 (size_t run = 0; run < mergeStringLength; run++) + { + if (!mergeStrings[run]) + continue; + + mergeLength = strlen(mergeStrings[run]); + + while ((offset + mergeLength + 8) > cchEnvironmentBlock) + { + cchEnvironmentBlock *= 2; + LPCH 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 = NULL; + const char* penvb = envBlock; + size_t nLength = 0; + size_t fLength = 0; + size_t lpNameLength = 0; + + 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 >= UINT32_MAX) + return 0; + + if ((vLength + 1 > nSize) || (!lpBuffer)) + return (DWORD)vLength + 1; + + CopyMemory(lpBuffer, env, vLength + 1); + + return (DWORD)vLength; +} + +BOOL SetEnvironmentVariableEBA(LPSTR* envBlock, LPCSTR lpName, LPCSTR lpValue) +{ + size_t length = 0; + char* envstr = NULL; + char* newEB = NULL; + + if (!lpName) + return FALSE; + + if (lpValue) + { + length = (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 = 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 = NULL; + SSIZE_T index = 0; + size_t count = 0; + size_t length = 0; + 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; +} + +#ifdef _WIN32 + +// https://devblogs.microsoft.com/oldnewthing/20100203-00/?p=15083 +#define WINPR_MAX_ENVIRONMENT_LENGTH 2048 + +DWORD GetEnvironmentVariableX(const char* lpName, char* lpBuffer, DWORD nSize) +{ + DWORD result = 0; + DWORD nSizeW = 0; + LPWSTR lpNameW = NULL; + LPWSTR lpBufferW = NULL; + LPSTR lpBufferA = lpBuffer; + + lpNameW = ConvertUtf8ToWCharAlloc(lpName, NULL); + if (!lpNameW) + goto cleanup; + + if (!lpBuffer) + { + char lpBufferMaxA[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 }; + WCHAR lpBufferMaxW[WINPR_MAX_ENVIRONMENT_LENGTH] = { 0 }; + LPSTR lpTmpBuffer = lpBufferMaxA; + + nSizeW = ARRAYSIZE(lpBufferMaxW); + + result = GetEnvironmentVariableW(lpNameW, lpBufferMaxW, nSizeW); + + SSIZE_T rc = + ConvertWCharNToUtf8(lpBufferMaxW, nSizeW, lpTmpBuffer, ARRAYSIZE(lpBufferMaxA)); + if ((rc < 0) || (rc >= UINT32_MAX)) + goto cleanup; + + result = (DWORD)rc + 1; + } + else + { + nSizeW = nSize; + lpBufferW = calloc(nSizeW + 1, sizeof(WCHAR)); + + if (!lpBufferW) + goto cleanup; + + result = GetEnvironmentVariableW(lpNameW, lpBufferW, nSizeW); + + if (result == 0) + goto cleanup; + + SSIZE_T rc = ConvertWCharNToUtf8(lpBufferW, nSizeW, lpBufferA, nSize); + if ((rc < 0) || (rc > UINT32_MAX)) + goto cleanup; + + result = (DWORD)rc; + } + +cleanup: + free(lpBufferW); + free(lpNameW); + + return result; +} + +#else + +DWORD GetEnvironmentVariableX(const char* lpName, char* lpBuffer, DWORD nSize) +{ + return GetEnvironmentVariableA(lpName, lpBuffer, nSize); +} + +#endif diff --git a/winpr/libwinpr/environment/test/CMakeLists.txt b/winpr/libwinpr/environment/test/CMakeLists.txt new file mode 100644 index 0000000..459d425 --- /dev/null +++ b/winpr/libwinpr/environment/test/CMakeLists.txt @@ -0,0 +1,28 @@ + +set(MODULE_NAME "TestEnvironment") +set(MODULE_PREFIX "TEST_ENVIRONMENT") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestEnvironmentGetEnvironmentStrings.c + TestEnvironmentSetEnvironmentVariable.c + TestEnvironmentMergeEnvironmentStrings.c + TestEnvironmentGetSetEB.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} winpr) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c b/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c new file mode 100644 index 0000000..c596399 --- /dev/null +++ b/winpr/libwinpr/environment/test/TestEnvironmentGetEnvironmentStrings.c @@ -0,0 +1,43 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/tchar.h> +#include <winpr/environment.h> + +int TestEnvironmentGetEnvironmentStrings(int argc, char* argv[]) +{ + int r = -1; + TCHAR* p = NULL; + size_t length = 0; + LPTCH lpszEnvironmentBlock = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + lpszEnvironmentBlock = GetEnvironmentStrings(); + + p = lpszEnvironmentBlock; + + while (p[0] && p[1]) + { + const int rc = _sntprintf(NULL, 0, _T("%s\n"), p); + if (rc < 1) + { + _tprintf(_T("test failed: return %d\n"), rc); + goto fail; + } + length = _tcslen(p); + if (length != (size_t)(rc - 1)) + { + _tprintf(_T("test failed: length %") _T(PRIuz) _T(" != %d [%s]\n"), length, rc - 1, p); + goto fail; + } + p += (length + 1); + } + + r = 0; +fail: + FreeEnvironmentStrings(lpszEnvironmentBlock); + + return r; +} diff --git a/winpr/libwinpr/environment/test/TestEnvironmentGetSetEB.c b/winpr/libwinpr/environment/test/TestEnvironmentGetSetEB.c new file mode 100644 index 0000000..603b4c2 --- /dev/null +++ b/winpr/libwinpr/environment/test/TestEnvironmentGetSetEB.c @@ -0,0 +1,138 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/tchar.h> +#include <winpr/environment.h> + +int TestEnvironmentGetSetEB(int argc, char* argv[]) +{ + int rc = 0; +#ifndef _WIN32 + char test[1024]; + TCHAR* p = NULL; + DWORD length = 0; + LPTCH lpszEnvironmentBlock = "SHELL=123\0test=1\0test1=2\0DISPLAY=WINPR_TEST_VALUE\0\0"; + LPTCH lpszEnvironmentBlockNew = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + rc = -1; + /* Get length of an variable */ + length = GetEnvironmentVariableEBA(lpszEnvironmentBlock, "DISPLAY", NULL, 0); + + if (0 == length) + return -1; + + /* Get the variable itself */ + p = (LPSTR)malloc(length); + + if (!p) + goto fail; + + if (GetEnvironmentVariableEBA(lpszEnvironmentBlock, "DISPLAY", p, length) != length - 1) + goto fail; + + printf("GetEnvironmentVariableA(WINPR_TEST_VARIABLE) = %s\n", p); + + if (strcmp(p, "WINPR_TEST_VALUE") != 0) + goto fail; + + /* Get length of an non-existing variable */ + length = GetEnvironmentVariableEBA(lpszEnvironmentBlock, "BLA", NULL, 0); + + if (0 != length) + { + printf("Unset variable returned\n"); + goto fail; + } + + /* Get length of an similar called variables */ + length = GetEnvironmentVariableEBA(lpszEnvironmentBlock, "XDISPLAY", NULL, 0); + + if (0 != length) + { + printf("Similar named variable returned (XDISPLAY, length %d)\n", length); + goto fail; + } + + length = GetEnvironmentVariableEBA(lpszEnvironmentBlock, "DISPLAYX", NULL, 0); + + if (0 != length) + { + printf("Similar named variable returned (DISPLAYX, length %d)\n", length); + goto fail; + } + + length = GetEnvironmentVariableEBA(lpszEnvironmentBlock, "DISPLA", NULL, 0); + + if (0 != length) + { + printf("Similar named variable returned (DISPLA, length %d)\n", length); + goto fail; + } + + length = GetEnvironmentVariableEBA(lpszEnvironmentBlock, "ISPLAY", NULL, 0); + + if (0 != length) + { + printf("Similar named variable returned (ISPLAY, length %d)\n", length); + goto fail; + } + + /* Set variable in empty environment block */ + if (SetEnvironmentVariableEBA(&lpszEnvironmentBlockNew, "test", "5")) + { + if (GetEnvironmentVariableEBA(lpszEnvironmentBlockNew, "test", test, 1023)) + { + if (strcmp(test, "5") != 0) + goto fail; + } + else + goto fail; + } + + /* Clear variable */ + if (SetEnvironmentVariableEBA(&lpszEnvironmentBlockNew, "test", NULL)) + { + if (GetEnvironmentVariableEBA(lpszEnvironmentBlockNew, "test", test, 1023)) + goto fail; + else + { + // not found .. this is expected + } + } + + free(lpszEnvironmentBlockNew); + lpszEnvironmentBlockNew = (LPTCH)calloc(1024, sizeof(TCHAR)); + + if (!lpszEnvironmentBlockNew) + goto fail; + + memcpy(lpszEnvironmentBlockNew, lpszEnvironmentBlock, length); + + /* Set variable in empty environment block */ + if (SetEnvironmentVariableEBA(&lpszEnvironmentBlockNew, "test", "5")) + { + if (0 != GetEnvironmentVariableEBA(lpszEnvironmentBlockNew, "testr", test, 1023)) + { + printf("GetEnvironmentVariableEBA returned unset variable\n"); + goto fail; + } + + if (GetEnvironmentVariableEBA(lpszEnvironmentBlockNew, "test", test, 1023)) + { + if (strcmp(test, "5") != 0) + goto fail; + } + else + goto fail; + } + + rc = 0; +fail: + free(p); + free(lpszEnvironmentBlockNew); +#endif + return rc; +} diff --git a/winpr/libwinpr/environment/test/TestEnvironmentMergeEnvironmentStrings.c b/winpr/libwinpr/environment/test/TestEnvironmentMergeEnvironmentStrings.c new file mode 100644 index 0000000..428418d --- /dev/null +++ b/winpr/libwinpr/environment/test/TestEnvironmentMergeEnvironmentStrings.c @@ -0,0 +1,34 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/tchar.h> +#include <winpr/environment.h> + +int TestEnvironmentMergeEnvironmentStrings(int argc, char* argv[]) +{ +#ifndef _WIN32 + TCHAR* p = NULL; + size_t length = 0; + LPTCH lpszEnvironmentBlock = NULL; + LPTCH lpsz2Merge = "SHELL=123\0test=1\0test1=2\0DISPLAY=:77\0\0"; + LPTCH lpszMergedEnvironmentBlock = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + lpszEnvironmentBlock = GetEnvironmentStrings(); + lpszMergedEnvironmentBlock = MergeEnvironmentStrings(lpszEnvironmentBlock, lpsz2Merge); + p = (TCHAR*)lpszMergedEnvironmentBlock; + + while (p[0] && p[1]) + { + printf("%s\n", p); + length = strlen(p); + p += (length + 1); + } + + FreeEnvironmentStrings(lpszMergedEnvironmentBlock); + FreeEnvironmentStrings(lpszEnvironmentBlock); +#endif + return 0; +} diff --git a/winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c b/winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c new file mode 100644 index 0000000..04b7064 --- /dev/null +++ b/winpr/libwinpr/environment/test/TestEnvironmentSetEnvironmentVariable.c @@ -0,0 +1,72 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/tchar.h> +#include <winpr/environment.h> +#include <winpr/error.h> + +#define TEST_NAME "WINPR_TEST_VARIABLE" +#define TEST_VALUE "WINPR_TEST_VALUE" +int TestEnvironmentSetEnvironmentVariable(int argc, char* argv[]) +{ + int rc = -1; + DWORD nSize = 0; + LPSTR lpBuffer = NULL; + DWORD error = 0; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + SetEnvironmentVariableA(TEST_NAME, TEST_VALUE); + nSize = GetEnvironmentVariableA(TEST_NAME, NULL, 0); + + /* check if value returned is len + 1 ) */ + if (nSize != strnlen(TEST_VALUE, sizeof(TEST_VALUE)) + 1) + { + printf("GetEnvironmentVariableA not found error\n"); + return -1; + } + + lpBuffer = (LPSTR)malloc(nSize); + + if (!lpBuffer) + return -1; + + nSize = GetEnvironmentVariableA(TEST_NAME, lpBuffer, nSize); + + if (nSize != strnlen(TEST_VALUE, sizeof(TEST_VALUE))) + { + printf("GetEnvironmentVariableA wrong size returned\n"); + goto fail; + } + + if (strcmp(lpBuffer, TEST_VALUE) != 0) + { + printf("GetEnvironmentVariableA returned value doesn't match\n"); + goto fail; + } + + nSize = GetEnvironmentVariableA("__xx__notset_", lpBuffer, nSize); + error = GetLastError(); + + if (0 != nSize || ERROR_ENVVAR_NOT_FOUND != error) + { + printf("GetEnvironmentVariableA not found error\n"); + goto fail; + } + + /* clear variable */ + SetEnvironmentVariableA(TEST_NAME, NULL); + nSize = GetEnvironmentVariableA(TEST_VALUE, NULL, 0); + + if (0 != nSize) + { + printf("SetEnvironmentVariableA failed to clear variable\n"); + goto fail; + } + + rc = 0; +fail: + free(lpBuffer); + return rc; +} |