Sebastian Lackner : shell32: Return NULL-terminated list of arguments in CommandLineToArgvW.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Jul 9 14:35:20 CDT 2014
Module: wine
Branch: master
Commit: d892239f5ab913b1418bff63652c09528bac936e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d892239f5ab913b1418bff63652c09528bac936e
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Mon Jul 7 22:43:01 2014 +0200
shell32: Return NULL-terminated list of arguments in CommandLineToArgvW.
---
dlls/shell32/shell32_main.c | 15 +++++++++------
dlls/shell32/tests/shlexec.c | 4 ++++
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index 679ebec..3bf442e 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -101,11 +101,11 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
/* Return the path to the executable */
DWORD len, deslen=MAX_PATH, size;
- size = sizeof(LPWSTR) + deslen*sizeof(WCHAR) + sizeof(LPWSTR);
+ size = sizeof(LPWSTR)*2 + deslen*sizeof(WCHAR);
for (;;)
{
if (!(argv = LocalAlloc(LMEM_FIXED, size))) return NULL;
- len = GetModuleFileNameW(0, (LPWSTR)(argv+1), deslen);
+ len = GetModuleFileNameW(0, (LPWSTR)(argv+2), deslen);
if (!len)
{
LocalFree(argv);
@@ -113,10 +113,11 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
}
if (len < deslen) break;
deslen*=2;
- size = sizeof(LPWSTR) + deslen*sizeof(WCHAR) + sizeof(LPWSTR);
+ size = sizeof(LPWSTR)*2 + deslen*sizeof(WCHAR);
LocalFree( argv );
}
- argv[0]=(LPWSTR)(argv+1);
+ argv[0]=(LPWSTR)(argv+2);
+ argv[1]=NULL;
*numargs=1;
return argv;
@@ -194,10 +195,10 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
* with it. This way the caller can make a single LocalFree() call to free
* both, as per MSDN.
*/
- argv=LocalAlloc(LMEM_FIXED, argc*sizeof(LPWSTR)+(strlenW(lpCmdline)+1)*sizeof(WCHAR));
+ argv=LocalAlloc(LMEM_FIXED, (argc+1)*sizeof(LPWSTR)+(strlenW(lpCmdline)+1)*sizeof(WCHAR));
if (!argv)
return NULL;
- cmdline=(LPWSTR)(argv+argc);
+ cmdline=(LPWSTR)(argv+argc+1);
strcpyW(cmdline, lpCmdline);
/* --- Then split and copy the arguments */
@@ -235,6 +236,7 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
if (!*s)
{
/* There are no parameters so we are all done */
+ argv[argc]=NULL;
*numargs=argc;
return argv;
}
@@ -306,6 +308,7 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
}
}
*d='\0';
+ argv[argc]=NULL;
*numargs=argc;
return argv;
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index 7f07c70..f81794e 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -1159,6 +1159,8 @@ static BOOL test_one_cmdline(const cmdline_tests_t* test)
win_skip("CommandLineToArgvW not implemented, skipping\n");
return FALSE;
}
+ ok(!argsW[cl2a_count] || broken(argsW[cl2a_count] != NULL) /* before Vista */,
+ "expected NULL-terminated list of commandline arguments\n");
count = 0;
while (test->args[count])
@@ -1218,6 +1220,8 @@ static void test_commandline2argv(void)
*strW = 0;
args = CommandLineToArgvW(strW, &numargs);
ok(numargs == 1, "expected 1 args, got %d\n", numargs);
+ ok(!args || (!args[numargs] || broken(args[numargs] != NULL) /* before Vista */),
+ "expected NULL-terminated list of commandline arguments\n");
if (numargs == 1)
{
GetModuleFileNameW(NULL, strW, sizeof(strW)/sizeof(*strW));
More information about the wine-cvs
mailing list