test: nlsboot.c Source File

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

# nlsboot.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1992  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     nlsboot.c
    00008
    00009 Abstract:
    00010
    00011     This module contains NLS routines for use by the OS Loader.  Before
    00012     the NLS tables are loaded, they convert between ANSI and Unicode by
    00013     zero-extending.
    00014
    00015 Author:
    00016
    00017     John Vert (jvert) 11-Nov-1992
    00018
    00019 Revision History:
    00020
    00021     John Vert (jvert) 11-Nov-1992
    00022         created - mostly copied from old RTL routines
    00023
    00024 --*/
    00025
    00026 #include "precomp.h"
    00027 #pragma hdrstop
    00028
    00029 //
    00030 // Hack-o-rama string routines to use before tables are loaded
    00031 //
    00032
    00033 #define upcase(C) (WCHAR )(((C) >= 'a' && (C) <= 'z' ? (C) - ('a' - 'A') : (C)))
    00034
    00035
    00036 NTSTATUS
    00037 RtlAnsiStringToUnicodeString(
    00038     OUT PUNICODE_STRING DestinationString,
    00039     IN PANSI_STRING SourceString,
    00040     IN BOOLEAN AllocateDestinationString
    00041     )
    00042
    00043 {
    00044     ULONG UnicodeLength;
    00045     ULONG Index;
    00046     NTSTATUS st;
    00047
    00048     UnicodeLength = (SourceString->Length << 1) + sizeof(UNICODE_NULL);
    00049
    00050     if ( UnicodeLength > MAXUSHORT ) {
    00051         return STATUS_INVALID_PARAMETER_2;
    00052         }
    00053
    00054     DestinationString->Length = (USHORT)(UnicodeLength - sizeof(UNICODE_NULL));
    00055     if ( AllocateDestinationString ) {
    00056         return STATUS_NO_MEMORY;
    00057         }
    00058     else {
    00059         if ( DestinationString->Length >= DestinationString->MaximumLength ) {
    00060             return STATUS_BUFFER_OVERFLOW;
    00061             }
    00062         }
    00063
    00064     Index = 0;
    00065     while(Index < DestinationString->Length ) {
    00066         DestinationString->Buffer[Index] = (WCHAR)SourceString->Buffer[Index];
    00067         Index++;
    00068         }
    00069     DestinationString->Buffer[Index] = UNICODE_NULL;
    00070
    00071     return STATUS_SUCCESS;
    00072 }
    00073
    00074 LONG
    00075 RtlCompareUnicodeString(
    00076     IN PUNICODE_STRING String1,
    00077     IN PUNICODE_STRING String2,
    00078     IN BOOLEAN CaseInSensitive
    00079     )
    00080
    00081 /*++
    00082
    00083 Routine Description:
    00084
    00085     The RtlCompareUnicodeString function compares two counted strings.  The
    00086     return value indicates if the strings are equal or String1 is less than
    00087     String2 or String1 is greater than String2.
    00088
    00089     The CaseInSensitive parameter specifies if case is to be ignored when
    00090     doing the comparison.
    00091
    00092 Arguments:
    00093
    00094     String1 - Pointer to the first string.
    00095
    00096     String2 - Pointer to the second string.
    00097
    00098     CaseInsensitive - TRUE if case should be ignored when doing the
    00099         comparison.
    00100
    00101 Return Value:
    00102
    00103     Signed value that gives the results of the comparison:
    00104
    00105         Zero - String1 equals String2
    00106
    00107         < Zero - String1 less than String2
    00108
    00109         > Zero - String1 greater than String2
    00110
    00111
    00112 --*/
    00113
    00114 {
    00115
    00116     UNALIGNED WCHAR *s1, *s2;
    00117     USHORT n1, n2;
    00118     WCHAR c1, c2;
    00119     LONG cDiff;
    00120
    00121     s1 = String1->Buffer;
    00122     s2 = String2->Buffer;
    00123     n1 = (USHORT )(String1->Length / sizeof(WCHAR));
    00124     n2 = (USHORT )(String2->Length / sizeof(WCHAR));
    00125     while (n1 && n2) {
    00126         c1 = *s1++;
    00127         c2 = *s2++;
    00128
    00129         if (CaseInSensitive) {
    00130             //
    00131             // Note that this needs to reference the translation table !
    00132             //
    00133             c1 = upcase(c1);
    00134             c2 = upcase(c2);
    00135         }
    00136
    00137         if ((cDiff = ((LONG)c1 - (LONG)c2)) != 0) {
    00138             return( cDiff );
    00139             }
    00140
    00141         n1--;
    00142         n2--;
    00143         }
    00144
    00145     return( n1 - n2 );
    00146 }
    00147
    00148 BOOLEAN
    00149 RtlEqualUnicodeString(
    00150     IN const PUNICODE_STRING String1,
    00151     IN const PUNICODE_STRING String2,
    00152     IN BOOLEAN CaseInSensitive
    00153     )
    00154
    00155 /*++
    00156
    00157 Routine Description:
    00158
    00159     The RtlEqualUnicodeString function compares two counted unicode strings for
    00160     equality.
    00161
    00162     The CaseInSensitive parameter specifies if case is to be ignored when
    00163     doing the comparison.
    00164
    00165 Arguments:
    00166
    00167     String1 - Pointer to the first string.
    00168
    00169     String2 - Pointer to the second string.
    00170
    00171     CaseInsensitive - TRUE if case should be ignored when doing the
    00172         comparison.
    00173
    00174 Return Value:
    00175
    00176     Boolean value that is TRUE if String1 equals String2 and FALSE otherwise.
    00177
    00178 --*/
    00179
    00180 {
    00181     UNALIGNED WCHAR *s1, *s2;
    00182     USHORT n1, n2;
    00183     WCHAR c1, c2;
    00184
    00185     s1 = String1->Buffer;
    00186     s2 = String2->Buffer;
    00187     n1 = (USHORT )(String1->Length / sizeof(WCHAR));
    00188     n2 = (USHORT )(String2->Length / sizeof(WCHAR));
    00189
    00190     if ( n1 != n2 ) {
    00191         return FALSE;
    00192         }
    00193
    00194     if (CaseInSensitive) {
    00195
    00196         while ( n1 ) {
    00197
    00198             if ( *s1++ != *s2++ ) {
    00199                 c1 = upcase(*(s1-1));
    00200                 c2 = upcase(*(s2-1));
    00201                 if (c1 != c2) {
    00202                     return( FALSE );
    00203                     }
    00204                 }
    00205             n1--;
    00206             }
    00207         }
    00208     else {
    00209
    00210         while ( n1 ) {
    00211
    00212             if (*s1++ != *s2++) {
    00213                 return( FALSE );
    00214                 }
    00215
    00216             n1--;
    00217             }
    00218         }
    00219
    00220     return TRUE;
    00221 }
    00222
    00223
    00224 VOID
    00225 RtlInitString(
    00226     OUT PSTRING DestinationString,
    00227     IN PCSZ SourceString OPTIONAL
    00228     )
    00229
    00230 /*++
    00231
    00232 Routine Description:
    00233
    00234     The RtlInitString function initializes an NT counted string.
    00235     The DestinationString is initialized to point to the SourceString
    00236     and the Length and MaximumLength fields of DestinationString are
    00237     initialized to the length of the SourceString, which is zero if
    00238     SourceString is not specified.
    00239
    00240 Arguments:
    00241
    00242     DestinationString - Pointer to the counted string to initialize
    00243
    00244     SourceString - Optional pointer to a null terminated string that
    00245         the counted string is to point to.
    00246
    00247
    00248 Return Value:
    00249
    00250     None.
    00251
    00252 --*/
    00253
    00254 {
    00255     DestinationString->Length = 0;
    00256     DestinationString->Buffer = (PCHAR)SourceString;
    00257     if (ARGUMENT_PRESENT( SourceString )) {
    00258         while (*SourceString++) {
    00259             DestinationString->Length++;
    00260             }
    00261
    00262         DestinationString->MaximumLength = (SHORT)(DestinationString->Length+1);
    00263         }
    00264     else {
    00265         DestinationString->MaximumLength = 0;
    00266         }
    00267 }
    00268
    00269
    00270 VOID
    00271 RtlInitUnicodeString(
    00272     OUT PUNICODE_STRING DestinationString,
    00273     IN PCWSTR SourceString OPTIONAL
    00274     )
    00275
    00276 /*++
    00277
    00278 Routine Description:
    00279
    00280     The RtlInitUnicodeString function initializes an NT counted
    00281     unicode string.  The DestinationString is initialized to point to
    00282     the SourceString and the Length and MaximumLength fields of
    00283     DestinationString are initialized to the length of the SourceString,
    00284     which is zero if SourceString is not specified.
    00285
    00286 Arguments:
    00287
    00288     DestinationString - Pointer to the counted string to initialize
    00289
    00290     SourceString - Optional pointer to a null terminated unicode string that
    00291         the counted string is to point to.
    00292
    00293
    00294 Return Value:
    00295
    00296     None.
    00297
    00298 --*/
    00299
    00300 {
    00301     USHORT Length = 0;
    00302     DestinationString->Length = 0;
    00303     DestinationString->Buffer = (PWSTR)SourceString;
    00304     if (ARGUMENT_PRESENT( SourceString )) {
    00305         while (*SourceString++) {
    00306             Length += sizeof(*SourceString);
    00307             }
    00308
    00309         DestinationString->Length = Length;
    00310
    00311         DestinationString->MaximumLength = Length+(USHORT)sizeof(UNICODE_NULL);
    00312         }
    00313     else {
    00314         DestinationString->MaximumLength = 0;
    00315         }
    00316 }
    00317
    00318
    00319 NTSTATUS
    00320 RtlAppendUnicodeStringToString (
    00321     IN PUNICODE_STRING Destination,
    00322     IN PUNICODE_STRING Source
    00323     )
    00324
    00325 /*++
    00326
    00327 Routine Description:
    00328
    00329     This routine will concatinate two PSTRINGs together.  It will copy
    00330     bytes from the source up to the MaximumLength of the destination.
    00331
    00332 Arguments:
    00333
    00334     IN PSTRING Destination, - Supplies the destination string
    00335     IN PSTRING Source - Supplies the source for the string copy
    00336
    00337 Return Value:
    00338
    00339     STATUS_SUCCESS - The source string was successfully appended to the
    00340         destination counted string.
    00341
    00342     STATUS_BUFFER_TOO_SMALL - The destination string length was not big
    00343         enough to allow the source string to be appended.  The Destination
    00344         string length is not updated.
    00345
    00346 --*/
    00347
    00348 {
    00349     USHORT n = Source->Length;
    00350     UNALIGNED WCHAR *dst;
    00351
    00352     if (n) {
    00353         if ((n + Destination->Length) > Destination->MaximumLength) {
    00354             return( STATUS_BUFFER_TOO_SMALL );
    00355             }
    00356
    00357         dst = &Destination->Buffer[ (Destination->Length / sizeof( WCHAR )) ];
    00358         RtlMoveMemory( dst, Source->Buffer, n );
    00359
    00360         Destination->Length += n;
    00361
    00362         if (Destination->Length < Destination->MaximumLength) {
    00363             dst[ n / sizeof( WCHAR ) ] = UNICODE_NULL;
    00364             }
    00365         }
    00366
    00367     return( STATUS_SUCCESS );
    00368 }
    00369
    00370
    00371 NTSTATUS
    00372 RtlAppendUnicodeToString (
    00373     IN PUNICODE_STRING Destination,
    00374     IN PCWSTR Source OPTIONAL
    00375     )
    00376
    00377 /*++
    00378
    00379 Routine Description:
    00380
    00381     This routine appends the supplied UNICODE string to an existing
    00382     PUNICODE_STRING.
    00383
    00384     It will copy bytes from the Source PSZ to the destination PSTRING up to
    00385     the destinations PUNICODE_STRING->MaximumLength field.
    00386
    00387 Arguments:
    00388
    00389     IN PUNICODE_STRING Destination, - Supplies a pointer to the destination
    00390                             string
    00391     IN PWSTR Source - Supplies the string to append to the destination
    00392
    00393 Return Value:
    00394
    00395     STATUS_SUCCESS - The source string was successfully appended to the
    00396         destination counted string.
    00397
    00398     STATUS_BUFFER_TOO_SMALL - The destination string length was not big
    00399         enough to allow the source string to be appended.  The Destination
    00400         string length is not updated.
    00401
    00402 --*/
    00403
    00404 {
    00405     USHORT n;
    00406     UNALIGNED WCHAR *dst;
    00407
    00408     if (ARGUMENT_PRESENT( Source )) {
    00409         UNICODE_STRING UniSource;
    00410
    00411         RtlInitUnicodeString(&UniSource, Source);
    00412
    00413         n = UniSource.Length;
    00414
    00415         if ((n + Destination->Length) > Destination->MaximumLength) {
    00416             return( STATUS_BUFFER_TOO_SMALL );
    00417             }
    00418
    00419         dst = &Destination->Buffer[ (Destination->Length / sizeof( WCHAR )) ];
    00420         RtlMoveMemory( dst, Source, n );
    00421
    00422         Destination->Length += n;
    00423
    00424         if (Destination->Length < Destination->MaximumLength) {
    00425             dst[ n / sizeof( WCHAR ) ] = UNICODE_NULL;
    00426             }
    00427         }
    00428
    00429     return( STATUS_SUCCESS );
    00430 }
    00431
    00432 WCHAR
    00433 RtlUpcaseUnicodeChar(
    00434     IN WCHAR SourceCharacter
    00435     )
    00436
    00437 /*++
    00438
    00439 Routine Description:
    00440
    00441     This function translates the specified unicode character to its
    00442     equivalent upcased unicode chararacter.  The purpose for this routine
    00443     is to allow for character by character upcase translation.  The
    00444     translation is done with respect to the current system locale
    00445     information.
    00446
    00447
    00448 Arguments:
    00449
    00450     SourceCharacter - Supplies the unicode character to be upcased.
    00451
    00452 Return Value:
    00453
    00454     Returns the upcased unicode equivalent of the specified input character.
    00455
    00456 --*/
    00457
    00458 {
    00459
    00460     return (upcase(SourceCharacter));
    00461 }
    00462
    00463 WCHAR
    00464 RtlAnsiCharToUnicodeChar(
    00465     IN OUT PUCHAR *SourceCharacter
    00466     )
    00467
    00468 /*++
    00469
    00470 Routine Description:
    00471
    00472     This function translates the specified ansi character to unicode and
    00473     returns the unicode value.  The purpose for this routine is to allow
    00474     for character by character ansi to unicode translation.  The
    00475     translation is done with respect to the current system locale
    00476     information.
    00477
    00478
    00479 Arguments:
    00480
    00481     SourceCharacter - Supplies a pointer to an ansi character pointer.
    00482         Through two levels of indirection, this supplies an ansi
    00483         character that is to be translated to unicode.  After
    00484         translation, the ansi character pointer is modified to point to
    00485         the next character to be converted.  This is done to allow for
    00486         dbcs ansi characters.
    00487
    00488 Return Value:
    00489
    00490     Returns the unicode equivalent of the specified ansi character.
    00491
    00492 --*/
    00493
    00494 {
    00495     WCHAR UnicodeCharacter;
    00496     ULONG cbCharSize;
    00497     NTSTATUS st;
    00498
    00499
    00500     UnicodeCharacter = (WCHAR)**SourceCharacter;
    00501     (*SourceCharacter)++;
    00502     return(UnicodeCharacter);
    00503 }
    00504
    00505 NTSTATUS
    00506 RtlUpcaseUnicodeToMultiByteN(
    00507     OUT PCH MultiByteString,
    00508     IN ULONG MaxBytesInMultiByteString,
    00509     OUT PULONG BytesInMultiByteString OPTIONAL,
    00510     IN PWCH UnicodeString,
    00511     IN ULONG BytesInUnicodeString)
    00512
    00513 /*++
    00514
    00515 Routine Description:
    00516
    00517     This functions upper cases the specified unicode source string and
    00518     converts it into an ansi string. The translation is done with respect
    00519     to the ANSI Code Page (ACP) loaded at boot time.
    00520
    00521 Arguments:
    00522
    00523     MultiByteString - Returns an ansi string that is equivalent to the
    00524         upper case of the unicode source string.  If the translation can
    00525         not be done, an error is returned.
    00526
    00527     MaxBytesInMultiByteString - Supplies the maximum number of bytes to be
    00528         written to MultiByteString.  If this causes MultiByteString to be a
    00529         truncated equivalent of UnicodeString, no error condition results.
    00530
    00531     BytesInMultiByteString - Returns the number of bytes in the returned
    00532         ansi string pointed to by MultiByteString.
    00533
    00534     UnicodeString - Supplies the unicode source string that is to be
    00535         converted to ansi.
    00536
    00537     BytesInUnicodeString - The number of bytes in the the string pointed to by
    00538         UnicodeString.
    00539
    00540 Return Value:
    00541
    00542     SUCCESS - The conversion was successful
    00543
    00544 --*/
    00545
    00546 {
    00547     ULONG TmpCount;
    00548     ULONG LoopCount;
    00549     ULONG CharsInUnicodeString;
    00550     UCHAR SbChar;
    00551     WCHAR UnicodeChar;
    00552     ULONG i;
    00553
    00554     //
    00555     // Convert Unicode byte count to character count. Byte count of
    00556     // multibyte string is equivalent to character count.
    00557     //
    00558     CharsInUnicodeString = BytesInUnicodeString / sizeof(WCHAR);
    00559
    00560     LoopCount = (CharsInUnicodeString < MaxBytesInMultiByteString) ?
    00561                  CharsInUnicodeString : MaxBytesInMultiByteString;
    00562
    00563     if (ARGUMENT_PRESENT(BytesInMultiByteString))
    00564         *BytesInMultiByteString = LoopCount;
    00565
    00566
    00567     for (i=0;i<LoopCount;i++) {
    00568
    00569         MultiByteString[i] = (UCHAR)RtlUpcaseUnicodeChar((UCHAR)(UnicodeString[i]));
    00570     }
    00571
    00572     return STATUS_SUCCESS;
    00573 }
    00574
    00575 NTSTATUS
    00576 RtlMultiByteToUnicodeN(
    00577     OUT PWCH UnicodeString,
    00578     IN ULONG MaxBytesInUnicodeString,
    00579     OUT PULONG BytesInUnicodeString OPTIONAL,
    00580     IN PCH MultiByteString,
    00581     IN ULONG BytesInMultiByteString)
    00582
    00583 /*++
    00584
    00585 Routine Description:
    00586
    00587     This functions converts the specified ansi source string into a
    00588     Unicode string. The translation is done with respect to the
    00589     ANSI Code Page (ACP) installed at boot time.  Single byte characters
    00590     in the range 0x00 - 0x7f are simply zero extended as a performance
    00591     enhancement.  In some far eastern code pages 0x5c is defined as the
    00592     Yen sign.  For system translation we always want to consider 0x5c
    00593     to be the backslash character.  We get this for free by zero extending.
    00594
    00595     NOTE: This routine only supports precomposed Unicode characters.
    00596
    00597 Arguments:
    00598
    00599     UnicodeString - Returns a unicode string that is equivalent to
    00600         the ansi source string.
    00601
    00602     MaxBytesInUnicodeString - Supplies the maximum number of bytes to be
    00603         written to UnicodeString.  If this causes UnicodeString to be a
    00604         truncated equivalent of MultiByteString, no error condition results.
    00605
    00606     BytesInUnicodeString - Returns the number of bytes in the returned
    00607         unicode string pointed to by UnicodeString.
    00608
    00609     MultiByteString - Supplies the ansi source string that is to be
    00610         converted to unicode.
    00611
    00612     BytesInMultiByteString - The number of bytes in the string pointed to
    00613         by MultiByteString.
    00614
    00615 Return Value:
    00616
    00617     SUCCESS - The conversion was successful.
    00618
    00619
    00620 --*/
    00621
    00622 {
    00623     ULONG LoopCount;
    00624     PUSHORT TranslateTable;
    00625     ULONG MaxCharsInUnicodeString;
    00626     ULONG i;
    00627
    00628     MaxCharsInUnicodeString = MaxBytesInUnicodeString / sizeof(WCHAR);
    00629
    00630     LoopCount = (MaxCharsInUnicodeString < BytesInMultiByteString) ?
    00631                  MaxCharsInUnicodeString : BytesInMultiByteString;
    00632
    00633     if (ARGUMENT_PRESENT(BytesInUnicodeString))
    00634         *BytesInUnicodeString = LoopCount * sizeof(WCHAR);
    00635
    00636     for (i=0;i<LoopCount;i++) {
    00637         UnicodeString[i] = (WCHAR)((UCHAR)(MultiByteString[i]));
    00638     }
    00639
    00640     return(STATUS_SUCCESS);
    00641 }
    00642
    00643 NTSTATUS
    00644 RtlUnicodeToMultiByteN(
    00645     OUT PCH MultiByteString,
    00646     IN ULONG MaxBytesInMultiByteString,
    00647     OUT PULONG BytesInMultiByteString OPTIONAL,
    00648     IN PWCH UnicodeString,
    00649     IN ULONG BytesInUnicodeString)
    00650
    00651 /*++
    00652
    00653 Routine Description:
    00654
    00655     This functions converts the specified unicode source string into an
    00656     ansi string. The translation is done with respect to the
    00657     ANSI Code Page (ACP) loaded at boot time.
    00658
    00659 Arguments:
    00660
    00661     MultiByteString - Returns an ansi string that is equivalent to the
    00662         unicode source string.  If the translation can not be done,
    00663         an error is returned.
    00664
    00665     MaxBytesInMultiByteString - Supplies the maximum number of bytes to be
    00666         written to MultiByteString.  If this causes MultiByteString to be a
    00667         truncated equivalent of UnicodeString, no error condition results.
    00668
    00669     BytesInMultiByteString - Returns the number of bytes in the returned
    00670         ansi string pointed to by MultiByteString.
    00671
    00672     UnicodeString - Supplies the unicode source string that is to be
    00673         converted to ansi.
    00674
    00675     BytesInUnicodeString - The number of bytes in the the string pointed to by
    00676         UnicodeString.
    00677
    00678 Return Value:
    00679
    00680     SUCCESS - The conversion was successful
    00681
    00682 --*/
    00683
    00684 {
    00685     ULONG TmpCount;
    00686     ULONG LoopCount;
    00687     ULONG CharsInUnicodeString;
    00688     UCHAR SbChar;
    00689     WCHAR UnicodeChar;
    00690     ULONG i;
    00691
    00692     //
    00693     // Convert Unicode byte count to character count. Byte count of
    00694     // multibyte string is equivalent to character count.
    00695     //
    00696     CharsInUnicodeString = BytesInUnicodeString / sizeof(WCHAR);
    00697
    00698     LoopCount = (CharsInUnicodeString < MaxBytesInMultiByteString) ?
    00699                  CharsInUnicodeString : MaxBytesInMultiByteString;
    00700
    00701     if (ARGUMENT_PRESENT(BytesInMultiByteString))
    00702         *BytesInMultiByteString = LoopCount;
    00703
    00704
    00705     for (i=0;i<LoopCount;i++) {
    00706         MultiByteString[i] = (CHAR)UnicodeString[i];
    00707     }
    00708
    00709     return STATUS_SUCCESS;
    00710
    00711 }