|
|
/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
efistrutil.cxx
--*/ #include "efiwintypes.hxx"
#include "pch.cxx"
void *memmove( void *dest, const void *src, size_t count ) { // quick workaround for lack of memmove in EFI library
VOID * temp = AllocatePool(count); memcpy( temp, src, count); memcpy( dest, temp, count); FreePool(temp); return dest; }
char *strcpy( char *strDestination, const char *strSource ) {
INT32 i;
i=0; while(strSource[i] != NULL) { strDestination[i] = strSource[i]; i++; } strDestination[i] = NULL; // null terminate.
return strDestination; }
int iswspace( WCHAR c ) { // BUGBUG this isn't a proper wide char test
// but will do for now.
if( ((0x09 <= c) && (c <= 0x0d)) || (c == 0x20) ) { return TRUE; } else { return FALSE; } }
int isspace( CHAR c ) { // BUGBUG this isn't a proper wide char test
// but will do for now.
if( ((0x09 <= c) && (c <= 0x0d)) || (c == 0x20) ) { return TRUE; } else { return FALSE; } }
int isdigit( int c ) { // BUGBUG again, this isn't a proper wide char test
// but it will do for now.
if( c >= '0' && c <= '9' ) { return TRUE; } else { return FALSE; }
}
int towupper( WCHAR c ) { // BUGBUG, this is wrong too, but for now it must do.
return c; }
int wcsncmp( const WCHAR *string1, const WCHAR *string2, size_t count ) { for( unsigned int i=0; i<count; i++ ) {
if(string1[i] != string2[i] || string1[i] == UNICODE_NULL || string2[i] == UNICODE_NULL) { break; } } return string2[i]-string1[i]; }
long atol(const char *nptr) { int c; /* current char */ long total; /* current total */ int sign; /* if '-', then negative, otherwise positive */ while (isspace((int)(unsigned char)*nptr)) nptr++; c = (int)(unsigned char)*nptr++; sign = c; /* save sign indication */ if (c == '-' || c == '+') c = (int)(unsigned char)*nptr++; /* skip sign */ total = 0; while ((c >= '0') && (c <= '9')) { total = 10 * total + (c - '0'); /* accumulate digit */ c = (int)(unsigned char)*nptr++; /* get next char */ } if (sign == '-') return -total; else return total; }
int atoi(const char *nptr) { return (int)atol(nptr); }
STATIC char *sprintf_buf; STATIC count;
VOID bzero(char *cp, int len) { while (len--) { *(cp + len) = 0; } }
VOID __cdecl putbuf(char c) { *sprintf_buf++ = c; count++; }
VOID __cdecl doprnt(VOID (*func)(char c), const char *fmt, va_list args);
//
// BUGBUG this is a semi-sprintf hacked together just to get it to work
//
int __cdecl sprintf(char *buf, const char *fmt, ...) { va_list args;
sprintf_buf = buf; va_start(args, fmt); doprnt(putbuf, fmt, args); va_end(args); putbuf('\0'); return count--; }
void __cdecl printbase(VOID (*func)(char), ULONG x, int base, int width) { static char itoa[] = "0123456789abcdef"; ULONG j; LONG k; char buf[32], *s = buf;
bzero(buf, 16); while (x) { j = x % base; *s++ = itoa[j]; x -= j; x /= base; }
if( s-buf < width ) { for( k = 0; k < width - (s-buf); k++ ) { func('0'); } } for (--s; s >= buf; --s) { func(*s); } }
void __cdecl doprnt(VOID (*func)( char c), const char *fmt, va_list args) { ULONG x; LONG l; LONG width; char c, *s;
count = 0;
while (c = *fmt++) { if (c != '%') { func(c); continue; }
width=0; c=*fmt++;
if(c == '0') { while( c = *fmt++) {
if (!isdigit(c)) { break; }
width = width*10; width = width+(c-48);
} } fmt--; // back it up one char
switch (c = *fmt++) { case 'x': x = va_arg(args, ULONG); printbase(func, x, 16, width); break; case 'o': x = va_arg(args, ULONG); printbase(func, x, 8, width); break; case 'd': l = va_arg(args, LONG); if (l < 0) { func('-'); l = -l; } printbase(func, (ULONG) l, 10, width); break; case 'u': l = va_arg(args, ULONG); printbase(func, (ULONG) l, 10, width); break; case 'c': c = va_arg(args, char); func(c); break; case 's': s = va_arg(args, char *); while (*s) { func(*s++); } break; default: func(c); break; } } }
#define MAX_INSERTS 200
NTSTATUS RtlFormatMessage( IN PWSTR MessageFormat, IN ULONG MaximumWidth OPTIONAL, IN BOOLEAN IgnoreInserts, IN BOOLEAN ArgumentsAreAnsi, IN BOOLEAN ArgumentsAreAnArray, IN va_list *Arguments, OUT PWSTR Buffer, IN ULONG Length, OUT PULONG ReturnLength OPTIONAL ) { ULONG Column; int cchRemaining, cchWritten; PULONG_PTR ArgumentsArray = (PULONG_PTR)Arguments; ULONG_PTR rgInserts[ MAX_INSERTS ]; ULONG cSpaces; ULONG MaxInsert, CurInsert; ULONG PrintParameterCount; ULONG_PTR PrintParameter1; ULONG_PTR PrintParameter2; WCHAR PrintFormatString[ 32 ]; BOOLEAN DefaultedFormatString; WCHAR c; PWSTR s, s1; PWSTR lpDst, lpDstBeg, lpDstLastSpace;
cchRemaining = Length / sizeof( WCHAR ); lpDst = Buffer; MaxInsert = 0; lpDstLastSpace = NULL; Column = 0; s = MessageFormat; while (*s != UNICODE_NULL) { if (*s == L'%') { s++; lpDstBeg = lpDst; if (*s >= L'1' && *s <= L'9') { CurInsert = *s++ - L'0'; if (*s >= L'0' && *s <= L'9') { CurInsert = (CurInsert * 10) + (*s++ - L'0'); if (*s >= L'0' && *s <= L'9') { CurInsert = (CurInsert * 10) + (*s++ - L'0'); if (*s >= L'0' && *s <= L'9') { return( STATUS_INVALID_PARAMETER ); } } } CurInsert -= 1;
PrintParameterCount = 0; if (*s == L'!') { DefaultedFormatString = FALSE; s1 = PrintFormatString; *s1++ = L'%'; s++; while (*s != L'!') { if (*s != UNICODE_NULL) { if (s1 >= &PrintFormatString[ 31 ]) { return( STATUS_INVALID_PARAMETER ); }
if (*s == L'*') { if (PrintParameterCount++ > 1) { return( STATUS_INVALID_PARAMETER ); } }
*s1++ = *s++; } else { return( STATUS_INVALID_PARAMETER ); } }
s++; *s1 = UNICODE_NULL; } else { DefaultedFormatString = TRUE; wcscpy( PrintFormatString, TEXT("%s") ); s1 = PrintFormatString + wcslen( PrintFormatString ); }
if (IgnoreInserts) { if (!wcscmp( PrintFormatString, TEXT("%s") )) { cchWritten = (int)SPrint( lpDst, cchRemaining, TEXT("%%%u"), CurInsert+1 ); } else { cchWritten = (int)SPrint( lpDst, cchRemaining, TEXT("%%%u!%s!"), CurInsert+1, &PrintFormatString[ 1 ] ); }
if (cchWritten == -1) { return(STATUS_BUFFER_OVERFLOW); } } else if (ARGUMENT_PRESENT( Arguments )) { if ((CurInsert+PrintParameterCount) >= MAX_INSERTS) { return( STATUS_INVALID_PARAMETER ); }
if (ArgumentsAreAnsi) { if (s1[ -1 ] == L'c' && s1[ -2 ] != L'h' && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') { wcscpy( &s1[ -1 ], TEXT("hc") ); } else if (s1[ -1 ] == L's' && s1[ -2 ] != L'h' && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') { wcscpy( &s1[ -1 ], TEXT("hs") ); } else if (s1[ -1 ] == L'S') { s1[ -1 ] = L's'; } else if (s1[ -1 ] == L'C') { s1[ -1 ] = L'c'; } }
while (CurInsert >= MaxInsert) { if (ArgumentsAreAnArray) { PULONG_PTR aaa; aaa = (PULONG_PTR)Arguments++; PrintParameter2 = rgInserts[ MaxInsert++ ] = *(aaa); } else { rgInserts[ MaxInsert++ ] = va_arg(*Arguments, ULONG_PTR); } }
s1 = (PWSTR)rgInserts[ CurInsert ]; PrintParameter1 = 0; PrintParameter2 = 0; if (PrintParameterCount > 0) { if (ArgumentsAreAnArray) { PULONG_PTR aaa; aaa = (PULONG_PTR)Arguments; PrintParameter2 = rgInserts[ MaxInsert++ ] = *(aaa)++; } else { PrintParameter1 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR ); }
if (PrintParameterCount > 1) { if (ArgumentsAreAnArray) { PULONG_PTR aaa; aaa = (PULONG_PTR)Arguments; PrintParameter2 = rgInserts[ MaxInsert++ ] = *(aaa)++; } else { PrintParameter2 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR ); } } }
cchWritten = (int)SPrint( lpDst, cchRemaining, PrintFormatString, s1, PrintParameter1, PrintParameter2 );
if (cchWritten == -1) { return(STATUS_BUFFER_OVERFLOW); } } else { return( STATUS_INVALID_PARAMETER ); }
if ((cchRemaining -= cchWritten) <= 0) { return STATUS_BUFFER_OVERFLOW; }
lpDst += cchWritten; } else if (*s == L'0') { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = L'\0';
break; } else if (!*s) { return( STATUS_INVALID_PARAMETER ); } else if (*s == L'r') { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = L'\r'; s++; lpDstBeg = NULL; } else if (*s == L'n') { if ((cchRemaining -= 2) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = L'\r'; *lpDst++ = L'\n'; s++; lpDstBeg = NULL; } else if (*s == L't') { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
if (Column % 8) { Column = (Column + 7) & ~7; } else { Column += 8; }
lpDstLastSpace = lpDst; *lpDst++ = L'\t'; s++; } else if (*s == L'b') { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
lpDstLastSpace = lpDst; *lpDst++ = L' '; s++; } else if (IgnoreInserts) { if ((cchRemaining -= 2) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = L'%'; *lpDst++ = *s++; } else { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = *s++; }
if (lpDstBeg == NULL) { lpDstLastSpace = NULL; Column = 0; } else { Column += (ULONG)(lpDst - lpDstBeg); } } else { c = *s++; if (c == L'\r' || c == L'\n') { if ((c == L'\n' && *s == L'\r') || (c == L'\r' && *s == L'\n') ) { s++; }
if (MaximumWidth != 0) { lpDstLastSpace = lpDst; c = L' '; } else { c = L'\n'; } }
if (c == L'\n') { if ((cchRemaining -= 2) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = L'\r'; *lpDst++ = L'\n'; lpDstLastSpace = NULL; Column = 0; } else { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
if (c == L' ') { lpDstLastSpace = lpDst; }
*lpDst++ = c; Column += 1; } }
if (MaximumWidth != 0 && MaximumWidth != 0xFFFFFFFF && Column >= MaximumWidth ) { if (lpDstLastSpace != NULL) { lpDstBeg = lpDstLastSpace; while (*lpDstBeg == L' ' || *lpDstBeg == L'\t') { lpDstBeg += 1; if (lpDstBeg == lpDst) { break; } } while (lpDstLastSpace > Buffer) { if (lpDstLastSpace[ -1 ] == L' ' || lpDstLastSpace[ -1 ] == L'\t') { lpDstLastSpace -= 1; } else { break; } }
cSpaces = (ULONG)(lpDstBeg - lpDstLastSpace); if (cSpaces == 1) { if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; } } else if (cSpaces > 2) { cchRemaining += (cSpaces - 2); }
memmove( lpDstLastSpace + 2, lpDstBeg, (ULONG) ((lpDst - lpDstBeg) * sizeof( WCHAR )) ); *lpDstLastSpace++ = L'\r'; *lpDstLastSpace++ = L'\n'; Column = (ULONG)(lpDst - lpDstBeg); lpDst = lpDstLastSpace + Column; lpDstLastSpace = NULL; } else { if ((cchRemaining -= 2) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = L'\r'; *lpDst++ = L'\n'; lpDstLastSpace = NULL; Column = 0; } } }
if ((cchRemaining -= 2) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = '\r'; *lpDst++ = '\n';
if ((cchRemaining -= 1) <= 0) { return STATUS_BUFFER_OVERFLOW; }
*lpDst++ = '\0'; if ( ARGUMENT_PRESENT(ReturnLength) ) { *ReturnLength = (ULONG)(lpDst - Buffer) * sizeof( WCHAR ); }
return( STATUS_SUCCESS ); }
|