[PATCH v3 03/10] reg: Add system error printing function
Hugh McMaster
hugh.mcmaster at outlook.com
Mon Nov 10 21:30:01 CST 2014
On Monday, 10 Nov 2014 14:46:49 +0100, Jonathan Vollebregt wrote:
> I'd still have to use reg_print_error as is because it's there to get
> the error string from standard error codes like ERROR_INVALID_DATA not
> to actually format the output string (FORMAT_MESSAGE_FROM_SYSTEM vs
> FORMAT_MESSAGE_FROM_STRING)
>
> Giving reg_message extra arguments is a good idea, but I'm not sure if
> we're supposed to have format specifiers in LoadString resources.
>
> I'm not sure whether having output_vprintf is really an advantage over
> just calling reg_printf since it uses different format specifiers than
> printf and basically does the same thing (Minus the variable size issue
> of course)
Format specifiers are perfectly valid in resource strings. See programs/regsvr32/regsvr32.rc as one example.
Not having to deal with variable memory allocation is the obvious advantage of using output_vprintf(). My personal choice would be to convert static const WCHAR nonnumber[] and static const WCHAR unhandled[] to resource strings and using reg_message(). These messages really should be translated anyway.
That leaves the three static const WCHAR stubW[] arrays to consider. Personally, I would remove them. They serve no real purpose and native reg doesn't have anything like them.
As to the getting the error message from the system table, I came up with two possibilities.
static void __cdecl reg_printfW(const WCHAR* msg, ...)
{
__ms_va_list va_args;
__ms_va_start(va_args, msg);
output_vprintf(msg, va_args);
__ms_va_end(va_args);
}
static void reg_print_error(LSTATUS error_code)
{
WCHAR *str, *buffer;
int len, extra_char = 8;
static const WCHAR error_string1[] = {'%','1','!','*','.','*','d','!',':',' ','%','3',0};
static const WCHAR error_string2[] = {'%','0','5','d',':',' ','%','s',0};
len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, error_code, 0, (LPWSTR)&str, 0, NULL);
if (len == 0 && GetLastError() != NO_ERROR)
{
WINE_FIXME("Could not format system string: le=%u\n", GetLastError());
return;
}
reg_printfW(error_string1, 0, 5, error_code, str); /* Option 1 - fully automated */
/* Option 2 */
buffer = HeapAlloc(GetProcessHeap(), 0, (len + extra_char) * sizeof(WCHAR));
if (buffer)
{
sprintfW(buffer, error_string2, error_code, str);
output_write(buffer, strlenW(buffer));
HeapFree(GetProcessHeap(), 0, buffer);
}
LocalFree(str);
}
More information about the wine-devel
mailing list