00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "ntrtlp.h"
00022
#include "string.h"
00023
#include "stdio.h"
00024
00025
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
00026
#pragma alloc_text(PAGE,RtlFindMessage)
00027
#endif
00028
00029
NTSTATUS
00030 RtlFindMessage(
00031 IN PVOID DllHandle,
00032 IN ULONG MessageTableId,
00033 IN ULONG MessageLanguageId,
00034 IN ULONG MessageId,
00035 OUT PMESSAGE_RESOURCE_ENTRY *MessageEntry
00036 )
00037 {
00038
NTSTATUS Status;
00039 ULONG NumberOfBlocks;
00040 ULONG EntryIndex;
00041 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
00042 PMESSAGE_RESOURCE_DATA MessageData;
00043 PMESSAGE_RESOURCE_BLOCK MessageBlock;
00044 PCHAR s;
00045 ULONG_PTR ResourceIdPath[ 3 ];
00046
00047
RTL_PAGED_CODE();
00048
00049 ResourceIdPath[ 0 ] = MessageTableId;
00050 ResourceIdPath[ 1 ] = 1;
00051 ResourceIdPath[ 2 ] = MessageLanguageId;
00052
00053
Status =
LdrpSearchResourceSection_U( DllHandle,
00054 ResourceIdPath,
00055 3,
00056
FALSE,
00057
FALSE,
00058 (PVOID *)&ResourceDataEntry
00059 );
00060
if (!
NT_SUCCESS(
Status )) {
00061
return(
Status );
00062 }
00063
00064
Status =
LdrpAccessResourceData( DllHandle,
00065 ResourceDataEntry,
00066 (PVOID *)&MessageData,
00067
NULL
00068 );
00069
if (!
NT_SUCCESS(
Status )) {
00070
return(
Status );
00071 }
00072
00073 NumberOfBlocks = MessageData->NumberOfBlocks;
00074 MessageBlock = &MessageData->Blocks[ 0 ];
00075
while (NumberOfBlocks--) {
00076
if (MessageId >= MessageBlock->LowId &&
00077 MessageId <= MessageBlock->HighId
00078 ) {
00079 s = (PCHAR)MessageData + MessageBlock->OffsetToEntries;
00080 EntryIndex = MessageId - MessageBlock->LowId;
00081
while (EntryIndex--) {
00082 s += ((PMESSAGE_RESOURCE_ENTRY)s)->Length;
00083 }
00084
00085 *MessageEntry = (PMESSAGE_RESOURCE_ENTRY)s;
00086
return( STATUS_SUCCESS );
00087 }
00088
00089 MessageBlock++;
00090 }
00091
00092
return( STATUS_MESSAGE_NOT_FOUND );
00093 }
00094
00095
#ifndef NTOS_KERNEL_RUNTIME
00096
00097 #define MAX_INSERTS 200
00098
00099
NTSTATUS
00100 RtlFormatMessage(
00101 IN PWSTR MessageFormat,
00102 IN ULONG MaximumWidth OPTIONAL,
00103 IN BOOLEAN IgnoreInserts,
00104 IN BOOLEAN ArgumentsAreAnsi,
00105 IN BOOLEAN ArgumentsAreAnArray,
00106 IN va_list *Arguments,
00107 OUT PWSTR Buffer,
00108 IN ULONG Length,
00109 OUT PULONG ReturnLength OPTIONAL
00110 )
00111 {
00112 ULONG Column;
00113
int cchRemaining, cchWritten;
00114 PULONG_PTR ArgumentsArray = (PULONG_PTR)Arguments;
00115 ULONG_PTR rgInserts[
MAX_INSERTS ];
00116 ULONG cSpaces;
00117 ULONG MaxInsert, CurInsert;
00118 ULONG PrintParameterCount;
00119 ULONG_PTR PrintParameter1;
00120 ULONG_PTR PrintParameter2;
00121 WCHAR PrintFormatString[ 32 ];
00122 BOOLEAN DefaultedFormatString;
00123 WCHAR
c;
00124 PWSTR s, s1;
00125 PWSTR lpDst, lpDstBeg, lpDstLastSpace;
00126
00127 cchRemaining = Length /
sizeof( WCHAR );
00128 lpDst =
Buffer;
00129 MaxInsert = 0;
00130 lpDstLastSpace =
NULL;
00131 Column = 0;
00132 s = MessageFormat;
00133
while (*s != UNICODE_NULL) {
00134
if (*s ==
L'%') {
00135 s++;
00136 lpDstBeg = lpDst;
00137
if (*s >=
L'1' && *s <=
L'9') {
00138 CurInsert = *s++ -
L'0';
00139
if (*s >=
L'0' && *s <=
L'9') {
00140 CurInsert = (CurInsert * 10) + (*s++ -
L'0');
00141
if (*s >=
L'0' && *s <=
L'9') {
00142 CurInsert = (CurInsert * 10) + (*s++ -
L'0');
00143
if (*s >=
L'0' && *s <=
L'9') {
00144
return( STATUS_INVALID_PARAMETER );
00145 }
00146 }
00147 }
00148 CurInsert -= 1;
00149
00150 PrintParameterCount = 0;
00151
if (*s ==
L'!') {
00152 DefaultedFormatString =
FALSE;
00153 s1 = PrintFormatString;
00154 *s1++ =
L'%';
00155 s++;
00156
while (*s !=
L'!') {
00157
if (*s != UNICODE_NULL) {
00158
if (s1 >= &PrintFormatString[ 31 ]) {
00159
return( STATUS_INVALID_PARAMETER );
00160 }
00161
00162
if (*s ==
L'*') {
00163
if (PrintParameterCount++ > 1) {
00164
return( STATUS_INVALID_PARAMETER );
00165 }
00166 }
00167
00168 *s1++ = *s++;
00169 }
00170
else {
00171
return( STATUS_INVALID_PARAMETER );
00172 }
00173 }
00174
00175 s++;
00176 *s1 = UNICODE_NULL;
00177 }
00178
else {
00179 DefaultedFormatString =
TRUE;
00180 wcscpy( PrintFormatString,
L"%s" );
00181 s1 = PrintFormatString + wcslen( PrintFormatString );
00182 }
00183
00184
if (IgnoreInserts) {
00185
if (!wcscmp( PrintFormatString,
L"%s" )) {
00186 cchWritten = _snwprintf( lpDst,
00187 cchRemaining,
00188
L"%%%u",
00189 CurInsert+1
00190 );
00191 }
00192
else {
00193 cchWritten = _snwprintf( lpDst,
00194 cchRemaining,
00195
L"%%%u!%s!",
00196 CurInsert+1,
00197 &PrintFormatString[ 1 ]
00198 );
00199 }
00200
00201
if (cchWritten == -1) {
00202
return(STATUS_BUFFER_OVERFLOW);
00203 }
00204 }
00205
else
00206
if (ARGUMENT_PRESENT( Arguments )) {
00207
if ((CurInsert+PrintParameterCount) >=
MAX_INSERTS) {
00208
return( STATUS_INVALID_PARAMETER );
00209 }
00210
00211
if (ArgumentsAreAnsi) {
00212
if (s1[ -1 ] ==
L'c' && s1[ -2 ] !=
L'h'
00213 && s1[ -2 ] !=
L'w' && s1[ -2 ] !=
L'l') {
00214 wcscpy( &s1[ -1 ],
L"hc" );
00215 }
00216
else
00217
if (s1[ -1 ] ==
L's' && s1[ -2 ] !=
L'h'
00218 && s1[ -2 ] !=
L'w' && s1[ -2 ] !=
L'l') {
00219 wcscpy( &s1[ -1 ],
L"hs" );
00220 }
00221
else if (s1[ -1 ] ==
L'S') {
00222 s1[ -1 ] =
L's';
00223 }
00224
else if (s1[ -1 ] ==
L'C') {
00225 s1[ -1 ] =
L'c';
00226 }
00227 }
00228
00229
while (CurInsert >= MaxInsert) {
00230
if (ArgumentsAreAnArray) {
00231 rgInserts[ MaxInsert++ ] = *((PULONG_PTR)Arguments)++;
00232 }
00233
else {
00234 rgInserts[ MaxInsert++ ] = va_arg(*Arguments, ULONG_PTR);
00235 }
00236 }
00237
00238 s1 = (PWSTR)rgInserts[ CurInsert ];
00239 PrintParameter1 = 0;
00240 PrintParameter2 = 0;
00241
if (PrintParameterCount > 0) {
00242
if (ArgumentsAreAnArray) {
00243 PrintParameter1 = rgInserts[ MaxInsert++ ] = *((PULONG_PTR)Arguments)++;
00244 }
00245
else {
00246 PrintParameter1 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR );
00247 }
00248
00249
if (PrintParameterCount > 1) {
00250
if (ArgumentsAreAnArray) {
00251 PrintParameter2 = rgInserts[ MaxInsert++ ] = *((PULONG_PTR)Arguments)++;
00252 }
00253
else {
00254 PrintParameter2 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG_PTR );
00255 }
00256 }
00257 }
00258
00259 cchWritten = _snwprintf( lpDst,
00260 cchRemaining,
00261 PrintFormatString,
00262 s1,
00263 PrintParameter1,
00264 PrintParameter2
00265 );
00266
if (cchWritten == -1) {
00267
return(STATUS_BUFFER_OVERFLOW);
00268 }
00269 }
00270
else {
00271
return( STATUS_INVALID_PARAMETER );
00272 }
00273
00274
if ((cchRemaining -= cchWritten) <= 0) {
00275
return STATUS_BUFFER_OVERFLOW;
00276 }
00277
00278 lpDst += cchWritten;
00279 }
00280
else
00281
if (*s ==
L'0') {
00282
break;
00283 }
00284
else
00285
if (!*s) {
00286
return( STATUS_INVALID_PARAMETER );
00287 }
00288
else
00289
if (*s ==
L'r') {
00290
if ((cchRemaining -= 1) <= 0) {
00291
return STATUS_BUFFER_OVERFLOW;
00292 }
00293
00294 *lpDst++ =
L'\r';
00295 s++;
00296 lpDstBeg =
NULL;
00297 }
00298
else
00299
if (*s ==
L'n') {
00300
if ((cchRemaining -= 2) <= 0) {
00301
return STATUS_BUFFER_OVERFLOW;
00302 }
00303
00304 *lpDst++ =
L'\r';
00305 *lpDst++ =
L'\n';
00306 s++;
00307 lpDstBeg =
NULL;
00308 }
00309
else
00310
if (*s ==
L't') {
00311
if ((cchRemaining -= 1) <= 0) {
00312
return STATUS_BUFFER_OVERFLOW;
00313 }
00314
00315
if (Column % 8) {
00316 Column = (Column + 7) & ~7;
00317 }
00318
else {
00319 Column += 8;
00320 }
00321
00322 lpDstLastSpace = lpDst;
00323 *lpDst++ =
L'\t';
00324 s++;
00325 }
00326
else
00327
if (*s ==
L'b') {
00328
if ((cchRemaining -= 1) <= 0) {
00329
return STATUS_BUFFER_OVERFLOW;
00330 }
00331
00332 lpDstLastSpace = lpDst;
00333 *lpDst++ =
L' ';
00334 s++;
00335 }
00336
else
00337
if (IgnoreInserts) {
00338
if ((cchRemaining -= 2) <= 0) {
00339
return STATUS_BUFFER_OVERFLOW;
00340 }
00341
00342 *lpDst++ =
L'%';
00343 *lpDst++ = *s++;
00344 }
00345
else {
00346
if ((cchRemaining -= 1) <= 0) {
00347
return STATUS_BUFFER_OVERFLOW;
00348 }
00349
00350 *lpDst++ = *s++;
00351 }
00352
00353
if (lpDstBeg ==
NULL) {
00354 lpDstLastSpace =
NULL;
00355 Column = 0;
00356 }
00357
else {
00358 Column += (ULONG)(lpDst - lpDstBeg);
00359 }
00360 }
00361
else {
00362
c = *s++;
00363
if (
c ==
L'\r' ||
c ==
L'\n') {
00364
if ((
c ==
L'\n' && *s ==
L'\r') ||
00365 (
c ==
L'\r' && *s ==
L'\n')
00366 ) {
00367 s++;
00368 }
00369
00370
if (MaximumWidth != 0) {
00371 lpDstLastSpace = lpDst;
00372
c =
L' ';
00373 }
00374
else {
00375
c =
L'\n';
00376 }
00377 }
00378
00379
00380
if (
c ==
L'\n') {
00381
if ((cchRemaining -= 2) <= 0) {
00382
return STATUS_BUFFER_OVERFLOW;
00383 }
00384
00385 *lpDst++ =
L'\r';
00386 *lpDst++ =
L'\n';
00387 lpDstLastSpace =
NULL;
00388 Column = 0;
00389 }
00390
else {
00391
if ((cchRemaining -= 1) <= 0) {
00392
return STATUS_BUFFER_OVERFLOW;
00393 }
00394
00395
if (
c ==
L' ') {
00396 lpDstLastSpace = lpDst;
00397 }
00398
00399 *lpDst++ =
c;
00400 Column += 1;
00401 }
00402 }
00403
00404
if (MaximumWidth != 0 &&
00405 MaximumWidth != 0xFFFFFFFF &&
00406 Column >= MaximumWidth
00407 ) {
00408
if (lpDstLastSpace !=
NULL) {
00409 lpDstBeg = lpDstLastSpace;
00410
while (*lpDstBeg ==
L' ' || *lpDstBeg ==
L'\t') {
00411 lpDstBeg += 1;
00412
if (lpDstBeg == lpDst) {
00413
break;
00414 }
00415 }
00416
while (lpDstLastSpace >
Buffer) {
00417
if (lpDstLastSpace[ -1 ] ==
L' ' || lpDstLastSpace[ -1 ] ==
L'\t') {
00418 lpDstLastSpace -= 1;
00419 }
00420
else {
00421
break;
00422 }
00423 }
00424
00425 cSpaces = (ULONG)(lpDstBeg - lpDstLastSpace);
00426
if (cSpaces == 1) {
00427
if ((cchRemaining -= 1) <= 0) {
00428
return STATUS_BUFFER_OVERFLOW;
00429 }
00430 }
00431
else
00432
if (cSpaces > 2) {
00433 cchRemaining += (cSpaces - 2);
00434 }
00435
00436 memmove( lpDstLastSpace + 2,
00437 lpDstBeg,
00438 (ULONG) ((lpDst - lpDstBeg) *
sizeof( WCHAR ))
00439 );
00440 *lpDstLastSpace++ =
L'\r';
00441 *lpDstLastSpace++ =
L'\n';
00442 Column = (ULONG)(lpDst - lpDstBeg);
00443 lpDst = lpDstLastSpace + Column;
00444 lpDstLastSpace =
NULL;
00445 }
00446
else {
00447
if ((cchRemaining -= 2) <= 0) {
00448
return STATUS_BUFFER_OVERFLOW;
00449 }
00450
00451 *lpDst++ =
L'\r';
00452 *lpDst++ =
L'\n';
00453 lpDstLastSpace =
NULL;
00454 Column = 0;
00455 }
00456 }
00457 }
00458
00459
if ((cchRemaining -= 1) <= 0) {
00460
return STATUS_BUFFER_OVERFLOW;
00461 }
00462
00463 *lpDst++ =
'\0';
00464
if ( ARGUMENT_PRESENT(ReturnLength) ) {
00465 *ReturnLength = (ULONG)(lpDst -
Buffer) *
sizeof( WCHAR );
00466 }
00467
return( STATUS_SUCCESS );
00468 }
00469
#endif
00470