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
00023
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
00024
#pragma alloc_text(PAGE,RtlIntegerToChar)
00025
#pragma alloc_text(PAGE,RtlCharToInteger)
00026
#pragma alloc_text(PAGE,RtlUnicodeStringToInteger)
00027
#pragma alloc_text(PAGE,RtlIntegerToUnicodeString)
00028
#pragma alloc_text(PAGE,RtlLargeIntegerToChar)
00029
#pragma alloc_text(PAGE,RtlInt64ToUnicodeString)
00030
#endif
00031
00032 CHAR RtlpIntegerChars[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
00033
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
00034
00035 WCHAR
RtlpIntegerWChars[] = {
L'0',
L'1',
L'2',
L'3',
L'4',
L'5',
00036
L'6',
L'7',
L'8',
L'9',
L'A',
L'B',
00037
L'C',
L'D',
L'E',
L'F' };
00038
00039
NTSTATUS
00040 RtlIntegerToChar (
00041 IN ULONG Value,
00042 IN ULONG Base OPTIONAL,
00043 IN LONG OutputLength,
00044 OUT PSZ String
00045 )
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 {
00058
CHAR Result[ 33 ], *s;
00059 ULONG Shift, Mask, Digit, Length;
00060
00061 Shift = 0;
00062
switch( Base ) {
00063
case 16: Shift = 4;
break;
00064
case 8: Shift = 3;
break;
00065
case 2: Shift = 1;
break;
00066
00067
case 0: Base = 10;
00068
case 10: Shift = 0;
break;
00069
default:
return( STATUS_INVALID_PARAMETER );
00070 }
00071
00072
if (Shift != 0) {
00073 Mask = 0xF >> (4 - Shift);
00074 }
00075
00076 s = &Result[ 32 ];
00077 *s =
'\0';
00078
do {
00079
if (Shift != 0) {
00080 Digit = Value & Mask;
00081 Value >>= Shift;
00082 }
00083
else {
00084 Digit = Value % Base;
00085 Value = Value / Base;
00086 }
00087
00088 *--s =
RtlpIntegerChars[ Digit ];
00089 }
while (Value != 0);
00090
00091 Length = (ULONG) (&Result[ 32 ] - s);
00092
if (OutputLength < 0) {
00093 OutputLength = -OutputLength;
00094
while ((LONG)Length < OutputLength) {
00095 *--s =
'0';
00096 Length++;
00097 }
00098 }
00099
00100
if ((LONG)Length > OutputLength) {
00101
return( STATUS_BUFFER_OVERFLOW );
00102 }
00103
else {
00104
try {
00105 RtlMoveMemory(
String, s, Length );
00106
00107
if ((LONG)Length < OutputLength) {
00108
String[ Length ] =
'\0';
00109 }
00110 }
00111 except(
EXCEPTION_EXECUTE_HANDLER ) {
00112
return( GetExceptionCode() );
00113 }
00114
00115
return( STATUS_SUCCESS );
00116 }
00117 }
00118
00119
00120
NTSTATUS
00121 RtlCharToInteger (
00122 IN PCSZ String,
00123 IN ULONG Base OPTIONAL,
00124 OUT PULONG Value
00125 )
00126 {
00127
CHAR c, Sign;
00128 ULONG Result, Digit, Shift;
00129
00130
while ((Sign = *
String++) <=
' ') {
00131
if (!*
String) {
00132
String--;
00133
break;
00134 }
00135 }
00136
00137
c = Sign;
00138
if (
c ==
'-' ||
c ==
'+') {
00139
c = *
String++;
00140 }
00141
00142
if (!ARGUMENT_PRESENT( (ULONG_PTR)(Base) )) {
00143 Base = 10;
00144 Shift = 0;
00145
if (
c ==
'0') {
00146
c = *
String++;
00147
if (
c ==
'x') {
00148 Base = 16;
00149 Shift = 4;
00150 }
00151
else
00152
if (
c ==
'o') {
00153 Base = 8;
00154 Shift = 3;
00155 }
00156
else
00157
if (
c ==
'b') {
00158 Base = 2;
00159 Shift = 1;
00160 }
00161
else {
00162
String--;
00163 }
00164
00165
c = *
String++;
00166 }
00167 }
00168
else {
00169
switch( Base ) {
00170
case 16: Shift = 4;
break;
00171
case 8: Shift = 3;
break;
00172
case 2: Shift = 1;
break;
00173
case 10: Shift = 0;
break;
00174
default:
return( STATUS_INVALID_PARAMETER );
00175 }
00176 }
00177
00178 Result = 0;
00179
while (
c) {
00180
if (
c >=
'0' &&
c <=
'9') {
00181 Digit =
c -
'0';
00182 }
00183
else
00184
if (
c >=
'A' &&
c <=
'F') {
00185 Digit =
c -
'A' + 10;
00186 }
00187
else
00188
if (
c >=
'a' &&
c <=
'f') {
00189 Digit =
c -
'a' + 10;
00190 }
00191
else {
00192
break;
00193 }
00194
00195
if (Digit >= Base) {
00196
break;
00197 }
00198
00199
if (Shift == 0) {
00200 Result = (Base * Result) + Digit;
00201 }
00202
else {
00203 Result = (Result << Shift) | Digit;
00204 }
00205
00206
c = *
String++;
00207 }
00208
00209
if (Sign ==
'-') {
00210 Result = (ULONG)(-(LONG)Result);
00211 }
00212
00213
try {
00214 *Value = Result;
00215 }
00216 except(
EXCEPTION_EXECUTE_HANDLER ) {
00217
return( GetExceptionCode() );
00218 }
00219
00220
return( STATUS_SUCCESS );
00221 }
00222
00223
00224
NTSTATUS
00225 RtlUnicodeStringToInteger (
00226 IN PUNICODE_STRING String,
00227 IN ULONG Base OPTIONAL,
00228 OUT PULONG Value
00229 )
00230 {
00231 PCWSTR s;
00232 WCHAR
c, Sign;
00233 ULONG nChars, Result, Digit, Shift;
00234
00235 s =
String->Buffer;
00236 nChars =
String->Length /
sizeof( WCHAR );
00237
while (nChars-- && (Sign = *s++) <=
' ') {
00238
if (!nChars) {
00239 Sign = UNICODE_NULL;
00240
break;
00241 }
00242 }
00243
00244
c = Sign;
00245
if (
c ==
L'-' ||
c ==
L'+') {
00246
if (nChars) {
00247 nChars--;
00248
c = *s++;
00249 }
00250
else {
00251
c = UNICODE_NULL;
00252 }
00253 }
00254
00255
if (!ARGUMENT_PRESENT( (ULONG_PTR)Base )) {
00256 Base = 10;
00257 Shift = 0;
00258
if (
c ==
L'0') {
00259
if (nChars) {
00260 nChars--;
00261
c = *s++;
00262
if (
c ==
L'x') {
00263 Base = 16;
00264 Shift = 4;
00265 }
00266
else
00267
if (
c ==
L'o') {
00268 Base = 8;
00269 Shift = 3;
00270 }
00271
else
00272
if (
c ==
L'b') {
00273 Base = 2;
00274 Shift = 1;
00275 }
00276
else {
00277 nChars++;
00278 s--;
00279 }
00280 }
00281
00282
if (nChars) {
00283 nChars--;
00284
c = *s++;
00285 }
00286
else {
00287
c = UNICODE_NULL;
00288 }
00289 }
00290 }
00291
else {
00292
switch( Base ) {
00293
case 16: Shift = 4;
break;
00294
case 8: Shift = 3;
break;
00295
case 2: Shift = 1;
break;
00296
case 10: Shift = 0;
break;
00297
default:
return( STATUS_INVALID_PARAMETER );
00298 }
00299 }
00300
00301 Result = 0;
00302
while (
c != UNICODE_NULL) {
00303
if (
c >=
L'0' &&
c <=
L'9') {
00304 Digit =
c -
L'0';
00305 }
00306
else
00307
if (
c >=
L'A' &&
c <=
L'F') {
00308 Digit =
c -
L'A' + 10;
00309 }
00310
else
00311
if (
c >=
L'a' &&
c <=
L'f') {
00312 Digit =
c -
L'a' + 10;
00313 }
00314
else {
00315
break;
00316 }
00317
00318
if (Digit >= Base) {
00319
break;
00320 }
00321
00322
if (Shift == 0) {
00323 Result = (Base * Result) + Digit;
00324 }
00325
else {
00326 Result = (Result << Shift) | Digit;
00327 }
00328
00329
if (!nChars) {
00330
break;
00331 }
00332 nChars--;
00333
c = *s++;
00334 }
00335
00336
if (Sign ==
L'-') {
00337 Result = (ULONG)(-(LONG)Result);
00338 }
00339
00340
try {
00341 *Value = Result;
00342 }
00343 except(
EXCEPTION_EXECUTE_HANDLER ) {
00344
return( GetExceptionCode() );
00345 }
00346
00347
return( STATUS_SUCCESS );
00348 }
00349
00350
00351
NTSTATUS
00352 RtlIntegerToUnicode (
00353 IN ULONG Value,
00354 IN ULONG Base OPTIONAL,
00355 IN LONG OutputLength,
00356 OUT PWSTR String
00357 )
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 {
00370 WCHAR Result[ 33 ], *s;
00371 ULONG Shift, Mask, Digit, Length;
00372
00373 Shift = 0;
00374
switch( Base ) {
00375
case 16: Shift = 4;
break;
00376
case 8: Shift = 3;
break;
00377
case 2: Shift = 1;
break;
00378
00379
case 0: Base = 10;
00380
case 10: Shift = 0;
break;
00381
default:
return( STATUS_INVALID_PARAMETER );
00382 }
00383
00384
if (Shift != 0) {
00385 Mask = 0xF >> (4 - Shift);
00386 }
00387
00388 s = &Result[ 32 ];
00389 *s =
L'\0';
00390
do {
00391
if (Shift != 0) {
00392 Digit = Value & Mask;
00393 Value >>= Shift;
00394 }
00395
else {
00396 Digit = Value % Base;
00397 Value = Value / Base;
00398 }
00399
00400 *--s =
RtlpIntegerWChars[ Digit ];
00401 }
while (Value != 0);
00402
00403 Length = (ULONG) (&Result[ 32 ] - s);
00404
if (OutputLength < 0) {
00405 OutputLength = -OutputLength;
00406
while ((LONG)Length < OutputLength) {
00407 *--s =
L'0';
00408 Length++;
00409 }
00410 }
00411
00412
if ((LONG)Length > OutputLength) {
00413
return( STATUS_BUFFER_OVERFLOW );
00414 }
00415
else {
00416
try {
00417 RtlMoveMemory(
String, s, Length *
sizeof( WCHAR ));
00418
00419
if ((LONG)Length < OutputLength) {
00420
String[ Length ] =
L'\0';
00421 }
00422 }
00423 except(
EXCEPTION_EXECUTE_HANDLER ) {
00424
return( GetExceptionCode() );
00425 }
00426
00427
return( STATUS_SUCCESS );
00428 }
00429 }
00430
00431
00432
NTSTATUS
00433 RtlIntegerToUnicodeString (
00434 IN ULONG Value,
00435 IN ULONG Base OPTIONAL,
00436 IN OUT PUNICODE_STRING String
00437 )
00438 {
00439
NTSTATUS Status;
00440 UCHAR ResultBuffer[ 16 ];
00441 ANSI_STRING AnsiString;
00442
00443
Status =
RtlIntegerToChar( Value, Base,
sizeof( ResultBuffer ), ResultBuffer );
00444
if (
NT_SUCCESS(
Status )) {
00445 AnsiString.Buffer = ResultBuffer;
00446 AnsiString.MaximumLength =
sizeof( ResultBuffer );
00447 AnsiString.Length = (
USHORT)
strlen( ResultBuffer );
00448
Status =
RtlAnsiStringToUnicodeString(
String, &AnsiString,
FALSE );
00449 }
00450
00451
return(
Status );
00452 }
00453
00454
00455
NTSTATUS
00456 RtlLargeIntegerToChar (
00457 IN PLARGE_INTEGER Value,
00458 IN ULONG Base OPTIONAL,
00459 IN LONG OutputLength,
00460 OUT PSZ String
00461 )
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 {
00474
CHAR Result[ 100 ], *s;
00475 ULONG Shift, Mask, Digit, Length;
00476
00477 Shift = 0;
00478
switch( Base ) {
00479
case 16: Shift = 4;
break;
00480
case 8: Shift = 3;
break;
00481
case 2: Shift = 1;
break;
00482
00483
case 0:
00484
case 10: Shift = 0;
break;
00485
default:
return( STATUS_INVALID_PARAMETER );
00486 }
00487
00488
if (Shift != 0) {
00489 Mask = 0xF >> (4 - Shift);
00490 }
00491
00492 s = &Result[ 99 ];
00493 *s =
'\0';
00494
if (Shift != 0) {
00495 ULONG LowValue,HighValue,HighShift,HighMask;
00496
00497 LowValue = Value->LowPart;
00498 HighValue = Value->HighPart;
00499 HighShift = Shift - (
sizeof(ULONG) % Shift);
00500 HighMask = 0xF >> (4 - HighShift);
00501
do {
00502 Digit = LowValue & Mask;
00503 LowValue = (LowValue >> Shift) | ((HighValue & HighMask) << (
sizeof(ULONG) - HighShift));
00504 HighValue = HighValue >> HighShift;
00505 *--s =
RtlpIntegerChars[ Digit ];
00506 }
while ((LowValue | HighValue) != 0);
00507 }
else {
00508 LARGE_INTEGER TempValue=*Value;
00509
do {
00510 TempValue =
RtlExtendedLargeIntegerDivide(TempValue,Base,&Digit);
00511 *--s =
RtlpIntegerChars[ Digit ];
00512 }
while (TempValue.HighPart != 0 || TempValue.LowPart != 0);
00513 }
00514
00515 Length = (ULONG)(&Result[ 99 ] - s);
00516
if (OutputLength < 0) {
00517 OutputLength = -OutputLength;
00518
while ((LONG)Length < OutputLength) {
00519 *--s =
'0';
00520 Length++;
00521 }
00522 }
00523
00524
if ((LONG)Length > OutputLength) {
00525
return( STATUS_BUFFER_OVERFLOW );
00526 }
00527
else {
00528
try {
00529 RtlMoveMemory(
String, s, Length );
00530
00531
if ((LONG)Length < OutputLength) {
00532
String[ Length ] =
'\0';
00533 }
00534 }
00535 except(
EXCEPTION_EXECUTE_HANDLER ) {
00536
return( GetExceptionCode() );
00537 }
00538
00539
return( STATUS_SUCCESS );
00540 }
00541 }
00542
00543
NTSTATUS
00544 RtlLargeIntegerToUnicode (
00545 IN PLARGE_INTEGER Value,
00546 IN ULONG Base OPTIONAL,
00547 IN LONG OutputLength,
00548 OUT PWSTR String
00549 )
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 {
00562 WCHAR Result[ 100 ], *s;
00563 ULONG Shift, Mask, Digit, Length;
00564
00565 Shift = 0;
00566
switch( Base ) {
00567
case 16: Shift = 4;
break;
00568
case 8: Shift = 3;
break;
00569
case 2: Shift = 1;
break;
00570
00571
case 0:
00572
case 10: Shift = 0;
break;
00573
default:
return( STATUS_INVALID_PARAMETER );
00574 }
00575
00576
if (Shift != 0) {
00577 Mask = 0xF >> (4 - Shift);
00578 }
00579
00580 s = &Result[ 99 ];
00581 *s =
L'\0';
00582
if (Shift != 0) {
00583 ULONG LowValue,HighValue,HighShift,HighMask;
00584
00585 LowValue = Value->LowPart;
00586 HighValue = Value->HighPart;
00587 HighShift = Shift - (
sizeof(ULONG) % Shift);
00588 HighMask = 0xF >> (4 - HighShift);
00589
do {
00590 Digit = LowValue & Mask;
00591 LowValue = (LowValue >> Shift) | ((HighValue & HighMask) << (
sizeof(ULONG) - HighShift));
00592 HighValue = HighValue >> HighShift;
00593 *--s =
RtlpIntegerWChars[ Digit ];
00594 }
while ((LowValue | HighValue) != 0);
00595 }
else {
00596 LARGE_INTEGER TempValue=*Value;
00597
do {
00598 TempValue =
RtlExtendedLargeIntegerDivide(TempValue,Base,&Digit);
00599 *--s =
RtlpIntegerWChars[ Digit ];
00600 }
while (TempValue.HighPart != 0 || TempValue.LowPart != 0);
00601 }
00602
00603 Length = (ULONG)(&Result[ 99 ] - s);
00604
if (OutputLength < 0) {
00605 OutputLength = -OutputLength;
00606
while ((LONG)Length < OutputLength) {
00607 *--s =
L'0';
00608 Length++;
00609 }
00610 }
00611
00612
if ((LONG)Length > OutputLength) {
00613
return( STATUS_BUFFER_OVERFLOW );
00614 }
00615
else {
00616
try {
00617 RtlMoveMemory(
String, s, Length *
sizeof( WCHAR ));
00618
00619
if ((LONG)Length < OutputLength) {
00620
String[ Length ] =
L'\0';
00621 }
00622 }
00623 except(
EXCEPTION_EXECUTE_HANDLER ) {
00624
return( GetExceptionCode() );
00625 }
00626
00627
return( STATUS_SUCCESS );
00628 }
00629 }
00630
00631
NTSTATUS
00632 RtlInt64ToUnicodeString (
00633 IN ULONGLONG Value,
00634 IN ULONG Base OPTIONAL,
00635 IN OUT PUNICODE_STRING String
00636 )
00637
00638 {
00639
00640
NTSTATUS Status;
00641 UCHAR ResultBuffer[32];
00642 ANSI_STRING AnsiString;
00643 LARGE_INTEGER Temp;
00644
00645 Temp.QuadPart = Value;
00646
Status =
RtlLargeIntegerToChar(&Temp,
00647 Base,
00648
sizeof(ResultBuffer),
00649 ResultBuffer);
00650
00651
if (
NT_SUCCESS(
Status)) {
00652 AnsiString.Buffer = ResultBuffer;
00653 AnsiString.MaximumLength =
sizeof(ResultBuffer);
00654 AnsiString.Length = (
USHORT)
strlen(ResultBuffer);
00655
Status =
RtlAnsiStringToUnicodeString(
String, &AnsiString,
FALSE);
00656 }
00657
00658
return Status;
00659 }