CommandLineToArgvW fix
Francois Gouget
fgouget at free.fr
Wed Oct 10 03:05:58 CDT 2001
Here's another version that uses GlobalLock...
I also retested in Windows and I believe the comment about spaces was
wrong.
--
Francois Gouget fgouget at free.fr http://fgouget.free.fr/
It really galls me that most of the computer power in the world
is wasted on screen savers.
Chris Caldwell from the GIMPS project
http://www.mersenne.org/prime.htm
-------------- next part --------------
Index: dlls/shell32/shell32_main.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.c,v
retrieving revision 1.85
diff -u -r1.85 shell32_main.c
--- dlls/shell32/shell32_main.c 2001/10/03 18:42:16 1.85
+++ dlls/shell32/shell32_main.c 2001/10/10 04:00:28
@@ -64,24 +64,25 @@
LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
{
DWORD argc;
+ HGLOBAL hargv;
LPWSTR *argv;
+ LPCWSTR cs;
LPWSTR arg,s,d;
LPWSTR cmdline;
int in_quotes,bcount;
- /* FIXME: same thing if we only have spaces */
if (*lpCmdline==0) {
/* Return the path to the executable */
DWORD size;
- argv=HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPWSTR));
- argv[0]=NULL;
+ hargv=0;
size=16;
do {
size*=2;
- argv[0]=HeapReAlloc(GetProcessHeap(), 0, argv[0], size);
- } while (GetModuleFileNameW((HMODULE)0, argv[0], size) == 0);
- argv[1]=NULL;
+ hargv=GlobalReAlloc(hargv, size, 0);
+ argv=GlobalLock(hargv);
+ } while (GetModuleFileNameW((HMODULE)0, (LPWSTR)(argv+1), size-sizeof(LPWSTR)) == 0);
+ argv[0]=(LPWSTR)(argv+1);
if (numargs)
*numargs=2;
@@ -89,30 +90,26 @@
}
/* to get a writeable copy */
- cmdline = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpCmdline)+1) * sizeof(WCHAR));
- if (!cmdline)
- return NULL;
- strcpyW(cmdline, lpCmdline);
argc=0;
bcount=0;
in_quotes=0;
- s=cmdline;
+ cs=lpCmdline;
while (1) {
- if (*s==0 || ((*s==0x0009 || *s==0x0020) && !in_quotes)) {
+ if (*cs==0 || ((*cs==0x0009 || *cs==0x0020) && !in_quotes)) {
/* space */
argc++;
/* skip the remaining spaces */
- while (*s==0x0009 || *s==0x0020) {
- s++;
+ while (*cs==0x0009 || *cs==0x0020) {
+ cs++;
}
- if (*s==0)
+ if (*cs==0)
break;
bcount=0;
continue;
- } else if (*s==0x005c) {
+ } else if (*cs==0x005c) {
/* '\', count them */
bcount++;
- } else if ((*s==0x0022) && ((bcount & 1)==0)) {
+ } else if ((*cs==0x0022) && ((bcount & 1)==0)) {
/* unescaped '"' */
in_quotes=!in_quotes;
bcount=0;
@@ -120,9 +117,17 @@
/* a regular character */
bcount=0;
}
- s++;
+ cs++;
}
- argv=HeapAlloc(GetProcessHeap(), 0, (argc+1)*sizeof(LPWSTR));
+ /* Allocate in a single lump, the string array, and the strings that go with it.
+ * This way the caller can make a single GlobalFree call to free both, as per MSDN.
+ */
+ hargv=GlobalAlloc(0, argc*sizeof(LPWSTR)+(strlenW(lpCmdline)+1)*sizeof(WCHAR));
+ argv=GlobalLock(hargv);
+ if (!argv)
+ return NULL;
+ cmdline=(LPWSTR)(argv+argc);
+ strcpyW(cmdline, lpCmdline);
argc=0;
bcount=0;
@@ -172,13 +177,11 @@
}
if (*arg) {
*d='\0';
- argv[argc++]=arg;
+ argv[argc]=arg;
}
- argv[argc]=NULL;
if (numargs)
*numargs=argc;
- HeapFree(GetProcessHeap(), 0, cmdline);
return argv;
}
More information about the wine-patches
mailing list