Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

message.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 message.c 00008 00009 Abstract: 00010 00011 Message table resource accessing functions 00012 00013 Author: 00014 00015 Steve Wood (stevewo) 10-Sep-1991 00016 00017 Revision History: 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

Generated on Sat May 15 19:40:47 2004 for test by doxygen 1.3.7