Skip to content

Commit

Permalink
Add CommandLineToArgv().
Browse files Browse the repository at this point in the history
  • Loading branch information
nmlgc committed Aug 21, 2015
1 parent f0db87b commit a9204f1
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ In addition, this library also adds new useful functionality to some original Wi

* `PathRemoveFileSpecU()` correctly works as intended for paths containing forward slashes

#### UTF-8 versions of functions that originally only have UTF-16 versions

* `LPSTR* WINAPI CommandLineToArgvU(LPCWSTR lpCmdLine, int* pNumArgs)`

Splits a UTF-16 command-line string (returned by e.g.`GetCommandLineW()`) into an UTF-8 `argv` array, and returns the number of arguments (`argc`) in `pNumArgs`. The caller has to free the returned array using LocalFree()`.

### OS compatibility
win32_utf8 it meant to require at least Windows XP - that is, it statically references only Windows functions that were available on XP. Wrappers for functions that were introduced in later Windows versions load their original functions dynamically using GetProcAddress().

Expand Down
38 changes: 38 additions & 0 deletions src/shell32_dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,44 @@ const w32u8_pair_t shell32_pairs[] = {
NULL
};

LPSTR* WINAPI CommandLineToArgvU(
LPCWSTR lpCmdLine,
int* pNumArgs
)
{
int cmd_line_pos; // Array "index" of the actual command line string
WCSLEN_DEC(lpCmdLine);
char **argv_u;

wchar_t **argv_w = CommandLineToArgvW(lpCmdLine, pNumArgs);
if(!argv_w) {
return NULL;
}
cmd_line_pos = *pNumArgs + 1;

// argv is indeed terminated with an additional sentinel NULL pointer.
argv_u = LocalAlloc(
LMEM_FIXED, cmd_line_pos * sizeof(char*) + lpCmdLine_len
);
if(argv_u) {
int i;
char *cur_arg_u = (char*)&argv_u[cmd_line_pos];
for(i = 0; i < *pNumArgs; i++) {
size_t cur_arg_u_len;
argv_u[i] = cur_arg_u;
cur_arg_u_len = StringToUTF8(
cur_arg_u, argv_w[i], lpCmdLine_len
) + 1;
cur_arg_u += cur_arg_u_len;
lpCmdLine_len -= cur_arg_u_len;
}
argv_u[i] = NULL;
}

LocalFree(argv_w);
return argv_u;
}

UINT WINAPI DragQueryFileU(
HANDLE hDrop,
UINT iFile,
Expand Down
5 changes: 5 additions & 0 deletions src/shell32_dll.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

#pragma once

LPSTR* WINAPI CommandLineToArgvU(
LPCWSTR lpCmdLine,
int* pNumArgs
);

UINT WINAPI DragQueryFileU(
HANDLE hDrop,
UINT iFile,
Expand Down
1 change: 1 addition & 0 deletions win32_utf8.def
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ EXPORTS

; shell32.dll
; -----------
CommandLineToArgvU
DragQueryFileU
ExtractIconU
ExtractIconExU
Expand Down

0 comments on commit a9204f1

Please sign in to comment.