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 }