Skip to content

Instantly share code, notes, and snippets.

@PQCraft
Last active July 23, 2022 04:35
Show Gist options
  • Save PQCraft/717de0071d8a9a5f282e536155652771 to your computer and use it in GitHub Desktop.
Save PQCraft/717de0071d8a9a5f282e536155652771 to your computer and use it in GitHub Desktop.
CommandLineToArgvA implementation ported from WINE CommandLineToArgvW in a reduced and easier to read format
LPSTR* WINAPI CommandLineToArgvA(LPSTR lpCmdline, int* numargs) {
DWORD argc;
LPSTR* argv;
LPSTR s;
LPSTR d;
LPSTR cmdline;
int qcount, bcount;
if (!numargs || !*lpCmdline) {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
argc = 1;
s = lpCmdline;
if (*s == '"') {
++s;
while (*s) {
if (*s++ == '"') break;
}
} else {
while (*s && *s != ' ' && *s != '\t') ++s;
}
while (*s == ' ' || *s == '\t') ++s;
if (*s) ++argc;
qcount = 0;
bcount = 0;
while (*s) {
if ((*s == ' ' || *s == '\t') && !qcount) {
while (*s == ' ' || *s == '\t') ++s;
if (*s) ++argc;
bcount = 0;
} else if (*s == '\\') {
++bcount;
++s;
} else if (*s == '"') {
if (!(bcount & 1)) ++qcount;
++s;
bcount = 0;
while (*s == '"') {
++qcount;
++s;
}
qcount = qcount % 3;
if (qcount == 2) qcount = 0;
} else {
bcount = 0;
++s;
}
}
argv = LocalAlloc(LMEM_FIXED, (argc + 1) * sizeof(LPSTR) + (strlen(lpCmdline) + 1) * sizeof(char));
if (!argv) return NULL;
cmdline = (LPSTR)(argv + argc + 1);
strcpy(cmdline, lpCmdline);
argv[0] = d = cmdline;
argc = 1;
if (*d == '"') {
s = d + 1;
while (*s) {
if (*s == '"') {
++s;
break;
}
*d++ = *s++;
}
} else {
while (*d && *d != ' ' && *d != '\t') ++d;
s = d;
if (*s) ++s;
}
*d++ = 0;
while (*s == ' ' || *s == '\t') ++s;
if (!*s) {
argv[argc] = NULL;
*numargs = argc;
return argv;
}
argv[argc++] = d;
qcount = 0;
bcount = 0;
while (*s) {
if ((*s == ' ' || *s == '\t') && !qcount) {
*d++ = 0;
bcount = 0;
do {
++s;
} while (*s == ' ' || *s == '\t');
if (*s) argv[argc++] = d;
} else if (*s=='\\') {
*d++ = *s++;
++bcount;
} else if (*s == '"') {
if (!(bcount & 1)) {
d -= bcount / 2;
++qcount;
} else {
d = d - bcount / 2 - 1;
*d++ = '"';
}
++s;
bcount = 0;
while (*s == '"') {
if (++qcount == 3) {
*d++ = '"';
qcount = 0;
}
++s;
}
if (qcount == 2) qcount = 0;
} else {
*d++ = *s++;
bcount = 0;
}
}
*d = '\0';
argv[argc] = NULL;
*numargs = argc;
return argv;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment