Implement getenv_s() via WinAPI GetEnvironmentVariableA() function.

WinAPI function GetEnvironmentVariableA() is available in:
Windows 8 API Sets - 
https://web.archive.org/web/20131207081913/http://msdn.microsoft.com/en-us/library/windows/desktop/dn505783(v=vs.85).aspx
Windows 8.1 API Sets - 
https://web.archive.org/web/20161005133126/http://msdn.microsoft.com/library/windows/desktop/dn933214.aspx
Windows 10 UWP - https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis
---
 .../winstorecompat/Makefile.am                |  1 +
 .../winstorecompat/src/getenv_s.c             | 73 +++++++++++++++++++
 2 files changed, 74 insertions(+)
 create mode 100644 mingw-w64-libraries/winstorecompat/src/getenv_s.c

diff --git a/mingw-w64-libraries/winstorecompat/Makefile.am 
b/mingw-w64-libraries/winstorecompat/Makefile.am
index 55fb4584111c..fc8e1ec65ece 100644
--- a/mingw-w64-libraries/winstorecompat/Makefile.am
+++ b/mingw-w64-libraries/winstorecompat/Makefile.am
@@ -25,6 +25,7 @@ libwinstorecompat_a_SOURCES = \
   src/GetACP.c \
   src/VirtualProtect.c \
   src/getenv.c \
+  src/getenv_s.c \
   src/LocalAlloc.c \
   src/LocalFree.c \
   src/Sleep.c \
diff --git a/mingw-w64-libraries/winstorecompat/src/getenv_s.c 
b/mingw-w64-libraries/winstorecompat/src/getenv_s.c
new file mode 100644
index 000000000000..d520ce303317
--- /dev/null
+++ b/mingw-w64-libraries/winstorecompat/src/getenv_s.c
@@ -0,0 +1,73 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <windows.h>
+
+errno_t __cdecl getenv_s(size_t *pReturnValue, char *dstBuf, rsize_t dstSize, 
const char *varName)
+{
+    DWORD ret;
+
+    /* Only below parameter validation sets errno to EINVAL. */
+
+    if (!pReturnValue)
+        return errno = EINVAL;
+
+    if ((!dstBuf && dstSize > 0) || (dstBuf && !dstSize)) {
+        *pReturnValue = 0;
+        return errno = EINVAL;
+    }
+
+    if (!varName) {
+        *pReturnValue = 0;
+        if (dstBuf)
+            dstBuf[0] = '\0';
+        return errno = EINVAL;
+    }
+
+    /* After passing parameter validation, the errno is not changed. */
+
+    /*
+     * Function GetEnvironmentVariableA() is documented on:
+     * 
https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-getenvironmentvariablea
+     */
+    ret = GetEnvironmentVariableA(varName, dstBuf, dstSize);
+    if (ret == 0) {
+        /* If the function fails, the return value is zero (e.g. specified
+         * environment variable was not found).
+         * Zero value is returned also when function passes, environment
+         * variable exists but has zero length value.
+         */
+        ret = GetLastError();
+        *pReturnValue = ret == ERROR_SUCCESS ? 1 : 0;
+        if (dstBuf)
+            dstBuf[0] = '\0';
+        if (ret == ERROR_SUCCESS || ret == ERROR_ENVVAR_NOT_FOUND)
+            return 0;
+        else if (ret == ERROR_NOT_ENOUGH_MEMORY)
+            return ENOMEM;
+        else
+            return EINVAL;
+    } else if (dstSize > 0 && ret > dstSize) {
+        /* If buffer is not large enough to hold the data, the return value is
+         * the buffer size, in characters, required to hold the string and its
+         * terminating null character and the contents of buffer are undefined.
+         */
+        *pReturnValue = ret;
+        if (dstBuf)
+            dstBuf[0] = '\0';
+        return ERANGE;
+    } else {
+        /* If the GetEnvironmentVariable succeeds, the return value is the
+         * number of characters stored in the buffer, not including the
+         * terminating null character.
+         */
+        *pReturnValue = ret+1;
+        return 0;
+    }
+}
+errno_t (__cdecl *__MINGW_IMP_SYMBOL(getenv_s))(size_t *, char *, rsize_t, 
const char *) = getenv_s;
-- 
2.20.1



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to