windows-nt/Source/XPSP1/NT/base/efiutil/efilib/efisrc/basesys.cxx

238 lines
6.8 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1991-2000 Microsoft Corporation
Module Name:
basesys.cxx
--*/
#include <pch.cxx>
#define _ULIB_MEMBER_
#include "ulib.hxx"
#include "basesys.hxx"
ULIB_EXPORT
BOOLEAN
BASE_SYSTEM::QueryResourceString(
OUT PWSTRING ResourceString,
IN MSGID MsgId,
IN PCSTR Format ...
)
/*++
Routine Description:
This routine computes the resource string identified by the resource
identifier 'MsgId'. In addition to the 'printf' format strings
supported, 'QueryResourceString' supports :
1. '%W' - Expects a pointer to a WSTRING.
Arguments:
ResourceString - Returns the resource string.
MsgId - Supplies the message id of the resource string.
Format - Supplies a 'printf' style format descriptor for the
arguments to the resource string.
... - Supplies the arguments to the resource string.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
va_list ap;
BOOLEAN r;
va_start(ap, Format);
r = QueryResourceStringV(ResourceString, MsgId, Format, ap);
va_end(ap);
return r;
}
ULIB_EXPORT
BOOLEAN
BASE_SYSTEM::QueryResourceStringV(
OUT PWSTRING ResourceString,
IN MSGID MsgId,
IN PCSTR Format,
IN va_list VarPointer
)
/*++
Routine Description:
This is a 'varargs' implementation of 'QueryResourceString'.
Arguments:
ResourceString - Returns the resource string.
MsgId - Supplies the message id of the resource string.
Format - Supplies a 'printf' style format descriptor for the
arguments to the resource string.
VarPointer - Supplies a varargs pointer to the arguments of the
resource string.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
#define NUMBER_OF_ARGS 20
STATIC HANDLE lib_handle = 0;
PWSTR args[NUMBER_OF_ARGS];
WSTR fmt[20];
INT i, j;
PWSTR p;
PWSTRING gstring;
DSTRING UnicodeFormat;
WSTR display_buffer[4096];
BOOL found;
NTSTATUS Status;
ULONG Result;
for (i = 0; i < NUMBER_OF_ARGS; i++) {
args[i] = NULL;
}
if (!UnicodeFormat.Initialize(Format)) {
return FALSE;
}
// convert args into an array for RtlFormatMessage.
i = 0;
for (p = (PWSTR) UnicodeFormat.GetWSTR(); *p; p++) {
// if we have a %
if (*p == '%') {
// perform W substitutions
if (*(p + 1) == 'W') {
p++;
gstring = va_arg(VarPointer, PWSTRING);
gstring->QueryWSTR(0, TO_END, display_buffer, 4096);
} else {
// convert other substutitions as appropriate by building a fmt string
j = 0;
// copy the %
fmt[j++] = *p++;
// copy the next character as long at its not a % and not NULL
while (*p && *p != '%') {
if ((*p == 's') && *(p - 1) != 'w') {
//if its an ANSI string
fmt[j++] = L'a';
p++;
continue;
} else if ((*p == 'c') && *(p - 1) != 'w') {
// if its an ANSI character
fmt[j++] = L'c'; // BUGBUG hack for now
p++;
continue;
} else if ((*p == 'w' ) && *(p + 1) == 's') {
// if its a wide string (%ws->%s)
fmt[j++] = L's';
p++;
p++; // skip the second char
continue;
} else if ((*p == 'w' ) && *(p + 1) == 'c') {
// if its a wide char (%wc->%c)
fmt[j++] = L'c';
p++;
p++; // skip the second char
continue;
} else if ((*p == 'u' )) {
// BUGBUG sprint doesn't seem to work with %u, replace with %d
fmt[j++] = L'd';
p++;
} else if (isdigit(*p)) {
// BUGBUG: HACK we skip digit format stuff since Sprint doesn't seem to like em.
p++;
} else {
// otherwise just copy the format indicator
fmt[j++] = *p++;
}
}
p--;
fmt[j] = 0;
if (wcsncmp(fmt, TEXT("%I64"), 4) == 0) {
// if its a 64 bit integer
// do some special stuff to handle LARGE_INTEGERS before telling SPrint to do its thing.
ULONGLONG t = (va_arg(VarPointer,LARGE_INTEGER)).QuadPart;
fmt[0]='%';
fmt[1]='l';
fmt[2]='d';
fmt[3]=NULL;
// Print(L"QueryResourceStringV: fmt: %s\n",fmt);
SPrint(display_buffer, 4096, fmt, t);
} else {
// otherwise tell SPrint to do its thing
PVOID voidptr = va_arg(VarPointer, PVOID);
// Print(L"QueryResourceStringV: fmt: %s\n",fmt);
SPrint(display_buffer, 4096,fmt,voidptr );
}
}
// allocate a buffer and copy the converted string into it.
args[i] = (PWSTR)MALLOC(wcslen(display_buffer) * sizeof(WCHAR) + sizeof(WCHAR));
if (NULL == args[i]) {
return FALSE;
}
wcscpy( args[i], display_buffer);
// Print(L"QueryResourceStringV: args[%d]: %s\n",i,args[i]);
i++;
}
}
found = FALSE;
// locate the right message in our table
for(i=0;i<EFI_MESSAGE_COUNT;i++) {
if(MessageTable[i].msgId == MsgId ){
found = TRUE;
break;
}
}
if (found == FALSE) {
return FALSE;
}
WCHAR *MessageFormat = MessageTable[i].string;
// shove it through RtlFormatMessage.
Status = RtlFormatMessage( MessageFormat,
0,
FALSE,
FALSE,
TRUE,
(va_list *)args,
(PWSTR)display_buffer,
sizeof( display_buffer ),
&Result
);
for (i = 0; i < NUMBER_OF_ARGS; i++) {
FREE(args[i]);
}
if (!NT_SUCCESS( Status )) {
return FALSE;
}
return ResourceString->Initialize(display_buffer);
}