[PATCH v2] kernelbase: Add SetEnvironmentStringsW().
Frank Uhlig
uhlig.frank at gmail.com
Wed May 6 14:50:17 CDT 2020
Signed-off-by: Frank Uhlig <uhlig.frank at gmail.com>
---
...ms-win-core-processenvironment-l1-1-0.spec | 2 +-
...ms-win-core-processenvironment-l1-2-0.spec | 2 +-
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernel32/tests/environ.c | 82 +++++++++++++++++++
dlls/kernelbase/kernelbase.spec | 2 +-
dlls/kernelbase/process.c | 50 +++++++++++
include/winbase.h | 1 +
7 files changed, 137 insertions(+), 4 deletions(-)
diff --git a/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec b/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec
index e3698d6efd..7a62b74390 100644
--- a/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec
+++ b/dlls/api-ms-win-core-processenvironment-l1-1-0/api-ms-win-core-processenvironment-l1-1-0.spec
@@ -15,7 +15,7 @@
@ stdcall SearchPathW(wstr wstr wstr long ptr ptr) kernel32.SearchPathW
@ stdcall SetCurrentDirectoryA(str) kernel32.SetCurrentDirectoryA
@ stdcall SetCurrentDirectoryW(wstr) kernel32.SetCurrentDirectoryW
-@ stub SetEnvironmentStringsW
+@ stdcall SetEnvironmentStringsW(ptr) kernel32.SetEnvironmentStringsW
@ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA
@ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW
@ stdcall SetStdHandle(long long) kernel32.SetStdHandle
diff --git a/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec b/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec
index 2c25ee1a07..c93d221c5e 100644
--- a/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec
+++ b/dlls/api-ms-win-core-processenvironment-l1-2-0/api-ms-win-core-processenvironment-l1-2-0.spec
@@ -17,7 +17,7 @@
@ stdcall SearchPathW(wstr wstr wstr long ptr ptr) kernel32.SearchPathW
@ stdcall SetCurrentDirectoryA(str) kernel32.SetCurrentDirectoryA
@ stdcall SetCurrentDirectoryW(wstr) kernel32.SetCurrentDirectoryW
-@ stub SetEnvironmentStringsW
+@ stdcall SetEnvironmentStringsW(ptr) kernel32.SetEnvironmentStringsW
@ stdcall SetEnvironmentVariableA(str str) kernel32.SetEnvironmentVariableA
@ stdcall SetEnvironmentVariableW(wstr wstr) kernel32.SetEnvironmentVariableW
@ stdcall SetStdHandle(long long) kernel32.SetStdHandle
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 0dd3813987..a27098fa42 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1389,7 +1389,7 @@
# @ stub SetDynamicTimeZoneInformation
@ stdcall -import SetEndOfFile(long)
# @ stub SetEnvironmentStringsA
-# @ stub SetEnvironmentStringsW
+@ stdcall -import SetEnvironmentStringsW (ptr)
@ stdcall -import SetEnvironmentVariableA(str str)
@ stdcall -import SetEnvironmentVariableW(wstr wstr)
@ stdcall -import SetErrorMode(long)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c
index 128a5fdbe5..fff31cd80e 100644
--- a/dlls/kernel32/tests/environ.c
+++ b/dlls/kernel32/tests/environ.c
@@ -602,6 +602,87 @@ static void test_GetEnvironmentStringsW(void)
FreeEnvironmentStringsW(env2);
}
+static void test_SetEnvironmentStringsW(void)
+{
+ DWORD buf_len;
+ BOOL ret;
+ DWORD ret_size;
+
+ WCHAR buf[256];
+
+ WCHAR name[] = {'N','a','m','e',0};
+ WCHAR value[] = {'V','a','l','u','e',0};
+ WCHAR env[] = {'N','a','m','e','=','V','a','l','u','e',0,0};
+
+ WCHAR eman[] = {'e','m','a','N',0};
+ WCHAR eulav[] = {'e','u','l','a','V',0};
+ WCHAR vne[] = {'e','m','a','N','=','e','u','l','a','V',0,0};
+
+ WCHAR var[] = {'V','a','r',0};
+ WCHAR val[] = {'V','a','l',0};
+ WCHAR rav[] = {'r','a','V',0};
+ WCHAR lav[] = {'l','a','V',0};
+ WCHAR mul[] = {'V','a','r','=','V','a','l',0,'r','a','V','=','l','a','V',0,0};
+
+ WCHAR empty[] = {'V','a','r','=',0,0};
+
+ WCHAR fwlt1[] = {'V','a','r',0,0};
+ WCHAR fwlt2[] = {'=','V','a','l',0,0};
+ WCHAR fwlt3[] = {'V','a','r','=','V','a','l',0,'r','a','V',0,0};
+
+ buf_len = ARRAY_SIZE(buf);
+
+ ret = SetEnvironmentStringsW(env);
+ ok( ret, "Setting environment strings failed with ret=%d\n", ret );
+
+ ret_size = GetEnvironmentVariableW(name, buf, buf_len);
+ ok( ret_size && ((ARRAY_SIZE(value)-1 == ret_size) && (0 == wcscmp(buf, value))),
+ "Difference in env, expected (%s) gotten (%s)\n",
+ debugstr_w(value), debugstr_w(buf));
+ memset(buf, 0, buf_len * sizeof(WCHAR));
+
+ ret = SetEnvironmentStringsW(vne);
+ ok( ret, "Setting environment strings failed with ret=%d\n", ret );
+
+ ret_size = GetEnvironmentVariableW(eman, buf, buf_len);
+ ok( ret_size && ((ARRAY_SIZE(eulav)-1 == ret_size) && (0 == wcscmp(buf, eulav))),
+ "Difference in env, expected (%s) gotten (%s)\n",
+ debugstr_w(eulav), debugstr_w(buf));
+ memset(buf, 0, buf_len * sizeof(WCHAR));
+
+ ret = SetEnvironmentStringsW(mul);
+ ok( ret, "Setting environment strings failed with ret=%d\n", ret);
+
+ ret_size = GetEnvironmentVariableW(var, buf, buf_len);
+ ok( ret_size && ((ARRAY_SIZE(val)-1 == ret_size) && (0 == wcscmp(buf, val))),
+ "Difference in env, expected (%s) gotten (%s)\n",
+ debugstr_w(val), debugstr_w(buf));
+ memset(buf, 0, buf_len * sizeof(WCHAR));
+
+ ret_size = GetEnvironmentVariableW(rav, buf, buf_len);
+ ok( ret_size && ((ARRAY_SIZE(lav)-1 == ret_size) && (0 == wcscmp(buf, lav))),
+ "Difference in env, expected (%s) gotten (%s)\n",
+ debugstr_w(lav), debugstr_w(buf));
+ memset(buf, 0, buf_len * sizeof(WCHAR));
+
+ ret = SetEnvironmentStringsW(empty);
+ ok( ret, "Setting empty environment failed with ret=%d\n", ret);
+
+ ret_size = GetEnvironmentVariableW(var, buf, buf_len);
+ ok( (0 == ret_size),
+ "Difference in env, should have been null, is (%s)\n", debugstr_w(buf));
+ memset(buf, 0, buf_len * sizeof(WCHAR));
+
+ ret = SetEnvironmentStringsW(fwlt1);
+ ok( FALSE == ret, "Non-environment string did not fail as expected, ret=%d\n", ret);
+
+ ret = SetEnvironmentStringsW(fwlt2);
+ ok( FALSE == ret, "Non-environment string did not fail as expected, ret=%d\n", ret);
+
+ ret = SetEnvironmentStringsW(fwlt3);
+ ok( FALSE == ret, "Non-environment string did not fail as expected, ret=%d\n", ret);
+}
+
START_TEST(environ)
{
init_functionpointers();
@@ -614,4 +695,5 @@ START_TEST(environ)
test_GetComputerNameExA();
test_GetComputerNameExW();
test_GetEnvironmentStringsW();
+ test_SetEnvironmentStringsW();
}
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index e73682af0f..c252d1ebd4 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -1422,7 +1422,7 @@
@ stdcall SetDefaultDllDirectories(long)
# @ stub SetDynamicTimeZoneInformation
@ stdcall SetEndOfFile(long)
-@ stub SetEnvironmentStringsW
+@ stdcall SetEnvironmentStringsW(ptr)
@ stdcall SetEnvironmentVariableA(str str)
@ stdcall SetEnvironmentVariableW(wstr wstr)
@ stdcall SetErrorMode(long)
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index acef2c55a1..7e9b44aa15 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -1392,6 +1392,56 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW( LPCWSTR name, LPCWSTR val
}
+/***********************************************************************
+ * SetEnvironmentStringsW (kernelbase.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentStringsW( WCHAR *env )
+{
+ BOOL rc = FALSE;
+ WCHAR *var, *val, *buff, *end, *tmp, *cur;
+ size_t bufflen = 0, len;
+
+ TRACE( "(%p)\n", env);
+
+ if (!env)
+ return rc;
+
+ RtlAcquirePebLock();
+ len = get_env_length( NtCurrentTeb()->Peb->ProcessParameters->Environment ) * sizeof(WCHAR);
+ if ((cur = HeapAlloc( GetProcessHeap(), 0, len )))
+ memset( NtCurrentTeb()->Peb->ProcessParameters->Environment, 0, len );
+ RtlReleasePebLock();
+
+ if ( !(bufflen = get_env_length(env)) )
+ return rc;
+
+ if (NULL == (buff = HeapAlloc(GetProcessHeap(), 0, bufflen * sizeof(WCHAR))))
+ return rc;
+
+ memcpy(buff, env, bufflen * sizeof(WCHAR));
+ end = buff +bufflen -1;
+ var = buff;
+
+ while (var < end) {
+ if (NULL == (val = wcschr(var, L'=')))
+ return FALSE;
+ *val++ = L'\0';
+
+ if ( !(rc = SetEnvironmentVariableW(var, val)) )
+ return rc;
+
+ if (NULL == (var = wcschr(val, L'\0')))
+ return FALSE;
+
+ ++var;
+ }
+
+ HeapFree(GetProcessHeap(), 0, buff);
+
+ return rc;
+}
+
+
/***********************************************************************
* Process/thread attribute lists
***********************************************************************/
diff --git a/include/winbase.h b/include/winbase.h
index f92d864c78..043bd3269f 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2622,6 +2622,7 @@ WINBASEAPI BOOL WINAPI SetEndOfFile(HANDLE);
WINBASEAPI BOOL WINAPI SetEnvironmentVariableA(LPCSTR,LPCSTR);
WINBASEAPI BOOL WINAPI SetEnvironmentVariableW(LPCWSTR,LPCWSTR);
#define SetEnvironmentVariable WINELIB_NAME_AW(SetEnvironmentVariable)
+WINBASEAPI BOOL WINAPI SetEnvironmentStringsW(WCHAR *);
WINBASEAPI UINT WINAPI SetErrorMode(UINT);
WINBASEAPI BOOL WINAPI SetEvent(HANDLE);
WINBASEAPI VOID WINAPI SetFileApisToANSI(void);
--
2.26.2
More information about the wine-devel
mailing list