UnicodeString基本操作(Ring3)

   1 // Unicode_String_Ring3.cpp : 定义控制台应用程序的入口点。
   2 //
   3 
   4 #include "stdafx.h"
   5 #include "Unicode_String_Ring3.h"
   6 
   7 /*
   8 所有带Ums_前缀的函数都是自己根据windows2000源码实现的
   9 
  10 因为Ring3不能直接定义UnicodeString 
  11 所以根据微软的源代码来实现
  12 
  13 */
  14 
  15 int main()
  16 {
  17     Test();
  18     return 0;
  19 }
  20 
  21 void Test()
  22 {
  23     //初始化
  24     //StringInitTest();
  25 
  26     //拷贝操作
  27     //StringCopyTest();
  28     
  29     //字符串比较
  30     //StringCompareTest();
  31     
  32     //字符串变大写***
  33     StringToUpperTest();
  34     
  35     //字符串与整型相互转化
  36     //StringToIntegerTest();
  37     
  38     
  39     //ANSI_STRING字符串与UNICODE_STRING字符串相互转换
  40     //StringConverTest();
  41     //最后未释放内存,bug
  42 
  43 
  44 
  45     printf("Input AnyKey To Exit\r\n");
  46     getchar();
  47 }
  48 
  49 //初始化
  50 void StringInitTest()
  51 {
  52     Sub_1();
  53     //Sub_2();
  54     //Sub_3();
  55 }
  56 
  57 void Sub_1()
  58 {
  59     UNICODE_STRING v1;
  60 
  61     Ums_RtlInitUnicodeString(&v1, L"HelloWorld");
  62 
  63     printf("%Z\r\n", &v1);
  64 
  65 
  66 
  67 }
  68 VOID
  69 Ums_RtlInitUnicodeString(
  70     OUT PUNICODE_STRING DestinationString,
  71     IN PCWSTR SourceString OPTIONAL
  72     )
  73 {
  74     USHORT Length = 0;
  75     DestinationString->Length = 0;
  76     DestinationString->Buffer = (PWSTR)SourceString;
  77     if (SourceString != NULL) 
  78     {
  79         while (*SourceString++) 
  80         {
  81             Length += sizeof(*SourceString);
  82         }
  83 
  84         DestinationString->Length = Length;
  85 
  86         DestinationString->MaximumLength = Length+(USHORT)sizeof(UNICODE_NULL);
  87     }
  88     else 
  89     {
  90         DestinationString->MaximumLength = 0;
  91     }
  92 }
  93 void Sub_2()
  94 {
  95     UNICODE_STRING v1;
  96     WCHAR BufferData[] = L"HelloWorld";
  97     v1.Buffer = BufferData;
  98     v1.Length = wcslen(BufferData) * sizeof(WCHAR);
  99     v1.MaximumLength = (wcslen(BufferData) + 1) * sizeof(WCHAR);
 100     printf("%Z\r\n", &v1);
 101 }
 102 
 103 void Sub_3()
 104 {
 105     UNICODE_STRING v1;
 106     WCHAR BufferData[] = L"HelloWorld";
 107 
 108     v1.Length = wcslen(BufferData) * sizeof(WCHAR);
 109     v1.MaximumLength = (wcslen(BufferData) + 1) * sizeof(WCHAR);
 110     v1.Buffer = (WCHAR*)malloc(v1.MaximumLength);
 111     RtlZeroMemory(v1.Buffer, v1.MaximumLength);
 112     RtlCopyMemory(v1.Buffer, BufferData, v1.Length);
 113 
 114     printf("%Z\r\n", &v1);
 115     if (v1.Buffer != NULL)
 116     {
 117         free(v1.Buffer);
 118         v1.Buffer = NULL;
 119         v1.Length = v1.MaximumLength = 0;
 120     }
 121 }
 122 
 123 //拷贝操作
 124 void StringCopyTest()
 125 {
 126     UNICODE_STRING SourceString;
 127     Ums_RtlInitUnicodeString(&SourceString, L"HelloWorld");
 128 
 129     UNICODE_STRING DestinationString = { 0 };
 130     DestinationString.Buffer = (PWSTR)malloc(BUFFER_SIZE);
 131     DestinationString.MaximumLength = BUFFER_SIZE;
 132 
 133     Ums_RtlCopyUnicodeString(&DestinationString, &SourceString);
 134 
 135     printf("SourceString:%wZ\r\n", &SourceString);
 136     printf("DestinationString:%wZ\n", &DestinationString);
 137 
 138     Ums_RtlFreeUnicodeString(&DestinationString);
 139 }
 140 
 141 VOID
 142 Ums_RtlCopyUnicodeString(
 143     OUT PUNICODE_STRING DestinationString,
 144     IN PUNICODE_STRING SourceString OPTIONAL
 145     )
 146 {
 147     UNALIGNED WCHAR *Source, *Dest;
 148     ULONG n;
 149 
 150     if (SourceString!=NULL) 
 151     {
 152         Dest = DestinationString->Buffer;
 153         Source = SourceString->Buffer;
 154         n = SourceString->Length;
 155         if ((USHORT)n > DestinationString->MaximumLength) 
 156         {
 157             n = DestinationString->MaximumLength;
 158         }
 159 
 160         DestinationString->Length = (USHORT)n;
 161         RtlCopyMemory(Dest, Source, n);
 162         if (DestinationString->Length < DestinationString->MaximumLength) 
 163         {
 164             Dest[n / sizeof(WCHAR)] = UNICODE_NULL;
 165         }
 166 
 167     } 
 168     else 
 169     {
 170         DestinationString->Length = 0;
 171     }
 172 
 173     return;
 174 }
 175 VOID
 176 Ums_RtlFreeUnicodeString(
 177     IN OUT PUNICODE_STRING UnicodeString
 178     )
 179 {
 180     if (UnicodeString->Buffer) 
 181     {
 182         //free(UnicodeString->Buffer);
 183         
 184         memset( UnicodeString, 0, sizeof( *UnicodeString ) );
 185     }
 186 }
 187 
 188 
 189 
 190 
 191 //字符串比较
 192 void StringCompareTest()
 193 {
 194     //初始化UnicodeString1
 195     UNICODE_STRING UnicodeString1;
 196     Ums_RtlInitUnicodeString(&UnicodeString1,L"HELLOWORLD");
 197 
 198     //初始化UnicodeString2
 199     UNICODE_STRING UnicodeString2;
 200     //Ums_RtlInitUnicodeString(&UnicodeString2, L"Hello");
 201     //Ums_RtlInitUnicodeString(&UnicodeString2, L"HELLOWORLD");
 202     Ums_RtlInitUnicodeString(&UnicodeString2, L"helloworld");
 203 
 204     if (Ums_RtlEqualUnicodeString(
 205         &UnicodeString1, 
 206         &UnicodeString2, 
 207         TRUE
 208         //If TRUE, 
 209         //case should be ignored when doing the comparison.
 210     )
 211         )
 212     {
 213         printf("UnicodeString1 and UnicodeString2 are equal\n");
 214     }
 215     else
 216     {
 217         printf("UnicodeString1 and UnicodeString2 are NOT equal\n");
 218     }
 219 }
 220 BOOLEAN
 221 Ums_RtlEqualUnicodeString(
 222     IN const PUNICODE_STRING String1,
 223     IN const PUNICODE_STRING String2,
 224     IN BOOLEAN CaseInSensitive
 225     )
 226 {
 227     UNALIGNED WCHAR *s1, *s2;
 228     USHORT n1, n2;
 229     WCHAR c1, c2;
 230 
 231     s1 = String1->Buffer;
 232     s2 = String2->Buffer;
 233     n1 = (USHORT )(String1->Length / sizeof(WCHAR));
 234     n2 = (USHORT )(String2->Length / sizeof(WCHAR));
 235 
 236     if ( n1 != n2 ) 
 237     {
 238         return FALSE;
 239     }
 240 
 241     if (CaseInSensitive) 
 242     {
 243         while ( n1 ) 
 244         {
 245             if ( *s1++ != *s2++ ) 
 246             {
 247                 c1 = upcase(*(s1-1));
 248                 c2 = upcase(*(s2-1));
 249                 if (c1 != c2) 
 250                 {
 251                     return( FALSE );
 252                 }
 253             }
 254             n1--;
 255         }
 256     }
 257     else 
 258     {
 259         while ( n1 ) 
 260         {
 261 
 262             if (*s1++ != *s2++) 
 263             {
 264                 return( FALSE );
 265             }
 266 
 267             n1--;
 268         }
 269     }
 270     return TRUE;
 271 }
 272 
 273 
 274 
 275 
 276 
 277 //字符串变大写
 278 void StringToUpperTest()
 279 {
 280     UNICODE_STRING SourceString;
 281     Ums_RtlInitUnicodeString(&SourceString, L"Hello World");
 282 
 283     UNICODE_STRING DestinationString;
 284     DestinationString.Buffer = (PWSTR)malloc(BUFFER_SIZE);
 285     DestinationString.MaximumLength = BUFFER_SIZE;
 286     
 287     //变化前
 288     printf("变化前:%wZ\n", &SourceString);
 289     //变大写
 290     Ums_RtlUpcaseUnicodeString(
 291         &DestinationString, //DestinationString
 292         &SourceString, //SourceString
 293         FALSE//Specifies if RtlUpcaseUnicodeString is to allocate the buffer space for the DestinationString. 
 294              //If it does, the buffer must be deallocated by calling RtlFreeUnicodeString.
 295     );
 296 
 297     //变化后
 298     printf("变化后:%wZ\n", &DestinationString);
 299 
 300     Ums_RtlFreeUnicodeString(&DestinationString);
 301 }
 302 
 303 
 304 
 305 
 306 BOOL
 307 Ums_RtlUpcaseUnicodeString(
 308     OUT PUNICODE_STRING DestinationString,
 309     IN PCUNICODE_STRING SourceString,
 310     IN BOOLEAN AllocateDestinationString
 311     )
 312 {
 313     ULONG Index;
 314     ULONG StopIndex;
 315 
 316     
 317 
 318     if ( AllocateDestinationString ) 
 319     {
 320         DestinationString->MaximumLength = SourceString->Length;
 321         //DestinationString->Buffer = (Ums_RtlAllocateStringRoutine)((ULONG)DestinationString->MaximumLength);
 322         
 323         DestinationString->Buffer = (PWSTR)malloc((ULONG)DestinationString->MaximumLength);
 324 
 325         if ( !DestinationString->Buffer ) 
 326         {
 327             return FALSE;
 328         }
 329     }
 330     else 
 331     {
 332         if ( SourceString->Length > DestinationString->MaximumLength ) 
 333         {
 334             return FALSE;
 335         }
 336     }
 337 
 338     StopIndex = ((ULONG)SourceString->Length) / sizeof( WCHAR );
 339 
 340     for (Index = 0; Index < StopIndex; Index++) 
 341     {
 342         DestinationString->Buffer[Index] = (WCHAR)NLS_UPCASE(SourceString->Buffer[Index]);
 343     }
 344 
 345     DestinationString->Length = SourceString->Length;
 346 
 347     return TRUE;
 348 }
 349 
 350 
 351 //字符串与整型相互转化
 352 void StringToIntegerTest()
 353 {
 354     //(1)字符串转换成数字
 355     UNICODE_STRING UnicodeString1;
 356     Ums_RtlInitUnicodeString(&UnicodeString1, L"-100");
 357     
 358     ULONG lNumber;
 359     NTSTATUS Status = 
 360         Ums_RtlUnicodeStringToInteger(//第二个参数Base
 361             &UnicodeString1, 
 362             //10,//-100是10进制 //输出-100
 363             //16,//-100是16进制  //输出-256
 364             8,   //-100是8进制 //输出-64
 365             &lNumber
 366         );
 367 
 368     if (NT_SUCCESS(Status))
 369     {
 370         printf("Conver to integer succussfully!\n");
 371         printf("Result:%d\n", lNumber);
 372     }
 373     else
 374     {
 375         printf("Conver to integer unsuccessfully!\n");
 376     }
 377     //(2)数字转换成字符串
 378     UNICODE_STRING UnicodeString2 = { 0 };
 379     UnicodeString2.Buffer = (PWSTR)malloc(BUFFER_SIZE);
 380     UnicodeString2.MaximumLength = BUFFER_SIZE;
 381 
 382     Status = Ums_RtlIntegerToUnicodeString(//同上 第二参数是Base
 383         200, 
 384         //10, //输出200
 385         //8,  //输出310
 386         16,   //输出  C8
 387         &UnicodeString2
 388     );
 389 
 390     /*
 391     HEX C8
 392     DEC 200
 393     OCT 310
 394     
 395     */
 396     if (NT_SUCCESS(Status))
 397     {
 398         printf("Conver to string succussfully!\n");
 399         printf("Result:%wZ\n", &UnicodeString2);
 400     }
 401     else
 402     {
 403         printf("Conver to string unsuccessfully!\n");
 404     }
 405 
 406     //销毁UnicodeString2
 407     //注意!!UnicodeString1不用销毁
 408     Ums_RtlFreeUnicodeString(&UnicodeString2);
 409 
 410 
 411 }
 412 BOOL
 413 Ums_RtlUnicodeStringToInteger(
 414     IN PUNICODE_STRING String,
 415     IN ULONG Base OPTIONAL,
 416     OUT PULONG Value
 417 )
 418 {
 419     PCWSTR s;
 420     WCHAR c, Sign;
 421     ULONG nChars, Result, Digit, Shift;
 422 
 423     s = String->Buffer;
 424     nChars = String->Length / sizeof(WCHAR);
 425     while (nChars-- && (Sign = *s++) <= ' ') {
 426         if (!nChars) {
 427             Sign = UNICODE_NULL;
 428             break;
 429         }
 430     }
 431 
 432     c = Sign;
 433     if (c == L'-' || c == L'+') {
 434         if (nChars) {
 435             nChars--;
 436             c = *s++;
 437         }
 438         else {
 439             c = UNICODE_NULL;
 440         }
 441     }
 442 
 443     if (((ULONG_PTR)Base)!=NULL) {
 444         Base = 10;
 445         Shift = 0;
 446         if (c == L'0') {
 447             if (nChars) {
 448                 nChars--;
 449                 c = *s++;
 450                 if (c == L'x') {
 451                     Base = 16;
 452                     Shift = 4;
 453                 }
 454                 else
 455                     if (c == L'o') {
 456                         Base = 8;
 457                         Shift = 3;
 458                     }
 459                     else
 460                         if (c == L'b') {
 461                             Base = 2;
 462                             Shift = 1;
 463                         }
 464                         else {
 465                             nChars++;
 466                             s--;
 467                         }
 468             }
 469 
 470             if (nChars) {
 471                 nChars--;
 472                 c = *s++;
 473             }
 474             else {
 475                 c = UNICODE_NULL;
 476             }
 477         }
 478     }
 479     else {
 480         switch (Base) {
 481         case 16:    Shift = 4;  break;
 482         case  8:    Shift = 3;  break;
 483         case  2:    Shift = 1;  break;
 484         case 10:    Shift = 0;  break;
 485         default:    return(FALSE);
 486         }
 487     }
 488 
 489     Result = 0;
 490     while (c != UNICODE_NULL) {
 491         if (c >= L'0' && c <= L'9') {
 492             Digit = c - L'0';
 493         }
 494         else
 495             if (c >= L'A' && c <= L'F') {
 496                 Digit = c - L'A' + 10;
 497             }
 498             else
 499                 if (c >= L'a' && c <= L'f') {
 500                     Digit = c - L'a' + 10;
 501                 }
 502                 else {
 503                     break;
 504                 }
 505 
 506                 if (Digit >= Base) {
 507                     break;
 508                 }
 509 
 510                 if (Shift == 0) {
 511                     Result = (Base * Result) + Digit;
 512                 }
 513                 else {
 514                     Result = (Result << Shift) | Digit;
 515                 }
 516 
 517                 if (!nChars) {
 518                     break;
 519                 }
 520                 nChars--;
 521                 c = *s++;
 522     }
 523 
 524     if (Sign == L'-') {
 525         Result = (ULONG)(-(LONG)Result);
 526     }
 527 
 528     __try 
 529     {
 530         *Value = Result;
 531     }
 532     __except(EXCEPTION_EXECUTE_HANDLER) {
 533         return(GetExceptionCode());
 534     }
 535 
 536     return(TRUE);
 537 }
 538 
 539 BOOL
 540 Ums_RtlIntegerToUnicodeString(
 541     IN ULONG Value,
 542     IN ULONG Base OPTIONAL,
 543     IN OUT PUNICODE_STRING String
 544 )
 545 {
 546     BOOL IsOk;
 547     char ResultBuffer[16];
 548     ANSI_STRING AnsiString;
 549 
 550     IsOk = Ums_RtlIntegerToChar(Value, Base, sizeof(ResultBuffer), ResultBuffer);
 551     if (IsOk) 
 552     {
 553         AnsiString.Buffer = ResultBuffer;
 554         AnsiString.MaximumLength = sizeof(ResultBuffer);
 555         AnsiString.Length = (USHORT)strlen(ResultBuffer);
 556         IsOk = Ums_RtlAnsiStringToUnicodeString(String, &AnsiString, FALSE);
 557     }
 558 
 559     return(IsOk);
 560 }
 561 
 562 BOOL
 563 Ums_RtlAnsiStringToUnicodeString(
 564     OUT PUNICODE_STRING DestinationString,
 565     IN PANSI_STRING SourceString,
 566     IN BOOLEAN AllocateDestinationString
 567 )
 568 {
 569     ULONG UnicodeLength;
 570     ULONG Index;
 571     NTSTATUS st;
 572 
 573     UnicodeLength = (SourceString->Length << 1) + sizeof(UNICODE_NULL);
 574 
 575     if (UnicodeLength > MAXUSHORT) {
 576         return FALSE;
 577     }
 578 
 579     DestinationString->Length = (USHORT)(UnicodeLength - sizeof(UNICODE_NULL));
 580     
 581     /*
 582     if (AllocateDestinationString) {
 583         return FALSE;
 584     }
 585     else {
 586         if (DestinationString->Length >= DestinationString->MaximumLength) {
 587             return FALSE;
 588         }
 589     }
 590     */
 591     //DestinationString->buffer没有申请内存 所以 我们这里仿造上一个函数的申请
 592     DestinationString->Buffer = (PWCHAR)malloc(UnicodeLength);
 593 
 594     Index = 0;
 595     while (Index < DestinationString->Length) 
 596     {
 597         DestinationString->Buffer[Index] = (WCHAR)SourceString->Buffer[Index];
 598         Index++;
 599     }
 600     DestinationString->Buffer[Index] = UNICODE_NULL;
 601 
 602     return TRUE;
 603 }
 604 
 605 
 606 BOOL
 607 Ums_RtlIntegerToChar(
 608     IN ULONG Value,
 609     IN ULONG Base OPTIONAL,
 610     IN LONG OutputLength,
 611     OUT char* String
 612 )
 613 {
 614     CHAR Result[33], *s;
 615     ULONG Shift, Mask, Digit, Length;
 616 
 617     Shift = 0;
 618     switch (Base) {
 619     case 16:    Shift = 4;  break;
 620     case  8:    Shift = 3;  break;
 621     case  2:    Shift = 1;  break;
 622 
 623     case  0:    Base = 10;
 624     case 10:    Shift = 0;  break;
 625     default:    return(FALSE);
 626     }
 627 
 628     if (Shift != 0) {
 629         Mask = 0xF >> (4 - Shift);
 630     }
 631 
 632     s = &Result[32];
 633     *s = '\0';
 634     do {
 635         if (Shift != 0) {
 636             Digit = Value & Mask;
 637             Value >>= Shift;
 638         }
 639         else {
 640             Digit = Value % Base;
 641             Value = Value / Base;
 642         }
 643 
 644         *--s = RtlpIntegerChars[Digit];
 645     } while (Value != 0);
 646 
 647     Length = (ULONG)(&Result[32] - s);
 648     if (OutputLength < 0) {
 649         OutputLength = -OutputLength;
 650         while ((LONG)Length < OutputLength) {
 651             *--s = '0';
 652             Length++;
 653         }
 654     }
 655 
 656     if ((LONG)Length > OutputLength) 
 657     {
 658         return(FALSE);
 659     }
 660     else {
 661         __try {
 662             RtlMoveMemory(String, s, Length);
 663 
 664             if ((LONG)Length < OutputLength) {
 665                 String[Length] = '\0';
 666             }
 667         }
 668         
 669         __except(EXCEPTION_EXECUTE_HANDLER) 
 670         {
 671             return(GetExceptionCode());
 672         }
 673         
 674         return(TRUE);
 675     }
 676 }
 677 
 678 
 679 
 680 
 681 
 682 
 683 
 684 
 685 
 686 
 687 //ANSI_STRING字符串与UNICODE_STRING字符串相互
 688 void StringConverTest()
 689 {
 690     //(1)将UNICODE_STRING字符串转换成ANSI_STRING字符串
 691     //初始化UnicodeString1
 692     UNICODE_STRING UnicodeString1;
 693     Ums_RtlInitUnicodeString(&UnicodeString1, L"HelloWorld");
 694 
 695     ANSI_STRING AnsiString1;
 696     NTSTATUS Status = Ums_RtlUnicodeStringToAnsiString(
 697         &AnsiString1, 
 698         &UnicodeString1, 
 699         TRUE
 700         //TRUE if this routine is to allocate the buffer space for the DestinationString. 
 701         //If it does, the buffer must be deallocated by calling RtlFreeAnsiString.
 702     );
 703 
 704     if (NT_SUCCESS(Status))
 705     {
 706         printf("Conver succussfully!\n");
 707         //printf("Result:%Z\n", &AnsiString1);
 708         //printf("Result:%Z\n", AnsiString1.Buffer);
 709         printf("Result:%s\n", AnsiString1.Buffer);
 710     }
 711     else
 712     {
 713         printf("Conver unsuccessfully!\n");
 714     }
 715 
 716     //销毁AnsiString1
 717     Ums_RtlFreeAnsiString(&AnsiString1);
 718 
 719     /******************************************/
 720 
 721     //(2)将ANSI_STRING字符串转换成UNICODE_STRING字符串
 722 
 723     ANSI_STRING AnsiString2;
 724     Ums_RtlInitString(&AnsiString2, "HelloWorld");
 725 
 726     UNICODE_STRING UnicodeString2;
 727     Status = Ums_RtlAnsiStringToUnicodeString(
 728         &UnicodeString2, 
 729         &AnsiString2, 
 730         TRUE
 731         //Specifies if this routine should allocate the buffer space for the destination string. 
 732         //If it does, the caller must deallocate the buffer by calling RtlFreeUnicodeString.
 733         
 734 
 735     );
 736 
 737     if (NT_SUCCESS(Status))
 738     {
 739         printf("Conver succussfully!\n");
 740         //printf("Result:%wZ\n", &UnicodeString2);
 741         //printf("Result:%wZ\n", UnicodeString2.Buffer);
 742         printf("Result:%S\n", UnicodeString2.Buffer);
 743     }
 744     else
 745     {
 746         printf("Conver unsuccessfully!\n");
 747     }
 748 
 749     //销毁UnicodeString2
 750     Ums_RtlFreeUnicodeString(&UnicodeString2);
 751 }
 752 
 753 VOID
 754 Ums_RtlFreeAnsiString(
 755     IN OUT PANSI_STRING AnsiString
 756 )
 757 {
 758     if (AnsiString->Buffer) {
 759         free(AnsiString->Buffer);
 760         memset(AnsiString, 0, sizeof(*AnsiString));
 761     }
 762 }
 763 VOID
 764 Ums_RtlInitString(
 765     OUT PSTRING DestinationString,
 766     IN char* SourceString OPTIONAL
 767     )
 768 {
 769     DestinationString->Length = 0;
 770     DestinationString->Buffer = (PCHAR)SourceString;
 771     if ( SourceString !=NULL ) {
 772         while (*SourceString++) {
 773             DestinationString->Length++;
 774             }
 775 
 776         DestinationString->MaximumLength = (SHORT)(DestinationString->Length+1);
 777         }
 778     else {
 779         DestinationString->MaximumLength = 0;
 780         }
 781 }
 782 
 783 BOOL 
 784 Ums_RtlUnicodeStringToAnsiString(
 785     OUT PANSI_STRING DestinationString,
 786     IN PUNICODE_STRING SourceString,
 787     IN BOOLEAN AllocateDestinationString
 788     )
 789 {
 790     ULONG AnsiLength;
 791     ULONG Index;
 792     NTSTATUS st;
 793     BOOL ReturnStatus = TRUE;
 794 
 795     
 796 
 797     AnsiLength = Ums_RtlxUnicodeStringToAnsiSize(SourceString);
 798     if ( AnsiLength > MAXUSHORT ) {
 799         return FALSE;
 800         }
 801 
 802     DestinationString->Length = (USHORT)(AnsiLength - 1);
 803     if ( AllocateDestinationString ) 
 804     {
 805         DestinationString->MaximumLength = (USHORT)AnsiLength;
 806         //DestinationString->Buffer = (RtlAllocateStringRoutine)(AnsiLength);
 807         DestinationString->Buffer = (PCHAR)malloc(AnsiLength);
 808 
 809         
 810         if ( !DestinationString->Buffer ) {
 811             return FALSE;
 812             }
 813         }
 814     else {
 815         if ( DestinationString->Length >= DestinationString->MaximumLength ) {
 816             /*
 817              * Return STATUS_BUFFER_OVERFLOW, but translate as much as
 818              * will fit into the buffer first.  This is the expected
 819              * behavior for routines such as GetProfileStringA.
 820              * Set the length of the buffer to one less than the maximum
 821              * (so that the trail byte of a double byte char is not
 822              * overwritten by doing DestinationString->Buffer[Index] = '\0').
 823              * RtlUnicodeToMultiByteN is careful not to truncate a
 824              * multibyte character.
 825              */
 826             if (!DestinationString->MaximumLength) {
 827                 return FALSE;
 828             }
 829             ReturnStatus = FALSE;
 830             DestinationString->Length = DestinationString->MaximumLength - 1;
 831             }
 832         }
 833 
 834     st = Ums_RtlUnicodeToMultiByteN(
 835              DestinationString->Buffer,
 836              DestinationString->Length,
 837              &Index,
 838              SourceString->Buffer,
 839              SourceString->Length
 840              );
 841 
 842     if (!NT_SUCCESS(st)) {
 843         if ( AllocateDestinationString ) {
 844             free(DestinationString->Buffer);
 845             DestinationString->Buffer = NULL;
 846         }
 847 
 848         return st;
 849     }
 850 
 851     DestinationString->Buffer[Index] = '\0';
 852 
 853     return ReturnStatus;
 854 }
 855 
 856 BOOL
 857 Ums_RtlUnicodeToMultiByteN(
 858     OUT PCH MultiByteString,
 859     IN ULONG MaxBytesInMultiByteString,
 860     OUT PULONG BytesInMultiByteString OPTIONAL,
 861     IN PWCH UnicodeString,
 862     IN ULONG BytesInUnicodeString
 863 )
 864 {
 865     ULONG TmpCount;
 866     ULONG LoopCount;
 867     ULONG CharsInUnicodeString;
 868     UCHAR SbChar;
 869     WCHAR UnicodeChar;
 870     ULONG i;
 871 
 872     //
 873     // Convert Unicode byte count to character count. Byte count of
 874     // multibyte string is equivalent to character count.
 875     //
 876     CharsInUnicodeString = BytesInUnicodeString / sizeof(WCHAR);
 877 
 878     LoopCount = (CharsInUnicodeString < MaxBytesInMultiByteString) ?
 879         CharsInUnicodeString : MaxBytesInMultiByteString;
 880 
 881     if ((BytesInMultiByteString) != NULL)
 882         *BytesInMultiByteString = LoopCount;
 883 
 884 
 885     for (i = 0; i < LoopCount; i++) {
 886         MultiByteString[i] = (CHAR)UnicodeString[i];
 887     }
 888 
 889     return TRUE;
 890 
 891 }
 892 ULONG
 893 Ums_RtlxUnicodeStringToAnsiSize(
 894     IN PUNICODE_STRING UnicodeString
 895 )
 896 {
 897     ULONG  cbMultiByteString;
 898 
 899     
 900 
 901     //
 902     // Get the size of the string - this call handles DBCS.
 903     //
 904     Ums_RtlUnicodeToMultiByteSize( &cbMultiByteString,
 905                                UnicodeString->Buffer,
 906                                UnicodeString->Length );
 907 
 908     //
 909     // Return the size in bytes.
 910     //
 911     return (cbMultiByteString + 1);
 912 }
 913 BOOL 
 914 Ums_RtlUnicodeToMultiByteSize(
 915     OUT PULONG BytesInMultiByteString,
 916     IN PWCH UnicodeString,
 917     IN ULONG BytesInUnicodeString)
 918 {
 919     ULONG cbMultiByte = 0;
 920     ULONG CharsInUnicodeString;
 921 
 922     /*
 923      * convert from bytes to chars for easier loop handling.
 924      */
 925     CharsInUnicodeString = BytesInUnicodeString / sizeof(WCHAR);
 926 
 927     if (NlsMbCodePageTag) {
 928         USHORT MbChar;
 929 
 930         while (CharsInUnicodeString--) {
 931             MbChar = NlsUnicodeToMbAnsiData[ *UnicodeString++ ];
 932             if (HIBYTE(MbChar) == 0) {
 933                 cbMultiByte++ ;
 934             } else {
 935                 cbMultiByte += 2;
 936             }
 937         }
 938         *BytesInMultiByteString = cbMultiByte;
 939     }
 940     else {
 941         *BytesInMultiByteString = CharsInUnicodeString;
 942     }
 943 
 944     return TRUE;
 945 }
 946 
 947 ULONG
 948 Ums_RtlxAnsiStringToUnicodeSize(
 949     IN PANSI_STRING AnsiString
 950     )
 951 
 952 
 953 {
 954     ULONG cbConverted;
 955 
 956 
 957     //
 958     // Get the size of the string - this call handles DBCS.
 959     //
 960     Ums_RtlMultiByteToUnicodeSize( &cbConverted ,
 961                                AnsiString->Buffer,
 962                                AnsiString->Length );
 963 
 964     //
 965     // Return the size in bytes.
 966     //
 967     return ( cbConverted + sizeof(UNICODE_NULL) );
 968 }
 969 BOOL 
 970 Ums_RtlMultiByteToUnicodeSize(
 971     OUT PULONG BytesInUnicodeString,
 972     IN PCH MultiByteString,
 973     IN ULONG BytesInMultiByteString
 974 )
 975 {
 976     ULONG cbUnicode = 0;
 977     if (NlsMbCodePageTag) {
 978         //
 979         // The ACP is a multibyte code page.  Check each character
 980         // to see if it is a lead byte before doing the translation.
 981         //
 982         while (BytesInMultiByteString--) {
 983             if (NlsLeadByteInfo[*(PUCHAR)MultiByteString++]) {
 984                 //
 985                 // Lead byte - translate the trail byte using the table
 986                 // that corresponds to this lead byte.  NOTE: make sure
 987                 // we have a trail byte to convert.
 988                 //
 989                 if (BytesInMultiByteString == 0) {
 990                     //
 991                     // RtlMultibyteToUnicodeN() uses the unicode
 992                     // default character if the last multibyte
 993                     // character is a lead byte.
 994                     //
 995                     cbUnicode += sizeof(WCHAR);
 996                     break;
 997                 } else {
 998                     BytesInMultiByteString--;
 999                     MultiByteString++;
1000                 }
1001             }
1002             cbUnicode += sizeof(WCHAR);
1003         }
1004         *BytesInUnicodeString = cbUnicode;
1005     } else {
1006         //
1007         // The ACP is a single byte code page.
1008         //
1009         *BytesInUnicodeString = BytesInMultiByteString * sizeof(WCHAR);
1010     }
1011 
1012     return TRUE;
1013 }
  1 #pragma once
  2 #include <windows.h>
  3 #include <iostream>
  4 
  5 using namespace std;
  6 
  7 #define BUFFER_SIZE 0x400
  8 #define DBCS_TABLE_SIZE 256
  9 #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 
 10 
 11 //拷贝
 12 #define upcase(C) \
 13 (WCHAR )(((C) >= 'a' && (C) <= 'z' ? (C) - ('a' - 'A') : (C)))
 14 
 15 
 16 //字符串变大写
 17 #define LOBYTE(w)           ((UCHAR)((w)))
 18 #define HIBYTE(w)           ((UCHAR)(((USHORT)((w)) >> 8) & 0xFF))
 19 #define GET8(w)             ((ULONG)(((w) >> 8) & 0xff))
 20 #define GETHI4(w)           ((ULONG)(((w) >> 4) & 0xf))
 21 #define GETLO4(w)           ((ULONG)((w) & 0xf))
 22 #define TRAVERSE844W(pTable, wch)                                               \
 23     ( (pTable)[(pTable)[(pTable)[GET8((wch))] + GETHI4((wch))] + GETLO4((wch))] )
 24 
 25 PUSHORT Nls844UnicodeUpcaseTable;
 26 extern PUSHORT Nls844UnicodeUpcaseTable;
 27 
 28 #define NLS_UPCASE(wch) (                                                   \
 29     ((wch) < 'a' ?                                                          \
 30         (wch)                                                               \
 31     :                                                                       \
 32         ((wch) <= 'z' ?                                                     \
 33             (wch) - ('a'-'A')                                               \
 34         :                                                                   \
 35             ((WCHAR)((wch) + TRAVERSE844W(Nls844UnicodeUpcaseTable,(wch)))) \
 36         )                                                                   \
 37     )                                                                       \
 38 )
 39 #define MAXUSHORT   USHRT_MAX
 40 
 41 typedef char *PSZ;
 42 
 43 typedef struct _UNICODE_STRING
 44 {
 45     USHORT Length;
 46     USHORT MaximumLength;
 47     PWCHAR Buffer;
 48 }UNICODE_STRING, *PUNICODE_STRING;
 49 
 50 typedef const UNICODE_STRING *PCUNICODE_STRING;
 51 
 52 typedef struct _STRING {
 53     USHORT Length;
 54     USHORT MaximumLength;
 55 #ifdef MIDL_PASS
 56     [size_is(MaximumLength), length_is(Length)]
 57 #endif // MIDL_PASS
 58     _Field_size_bytes_part_opt_(MaximumLength, Length) PCHAR Buffer;
 59 } STRING;
 60 typedef STRING *PSTRING;
 61 typedef STRING ANSI_STRING;
 62 typedef PSTRING PANSI_STRING;
 63 
 64 
 65 CHAR RtlpIntegerChars[] = { '0', '1', '2', '3', '4', '5', '6', '7',
 66                            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
 67 
 68 
 69 
 70 
 71 
 72 BOOLEAN  NlsMbCodePageTag = FALSE;         // TRUE -> Multibyte ACP, FALSE -> Singlebyte ACP
 73 USHORT   NlsLeadByteInfoTable[DBCS_TABLE_SIZE]; // Lead byte info. for ACP
 74 PUSHORT  NlsLeadByteInfo = NlsLeadByteInfoTable;
 75 PUSHORT  NlsUnicodeToMbAnsiData;           // Unicode to Multibyte Ansi CP translation table
 76 
 77 
 78 
 79 void Test();
 80 
 81 //初始化
 82 void StringInitTest();
 83 
 84 void Sub_1();
 85 VOID
 86 Ums_RtlInitUnicodeString(
 87     OUT PUNICODE_STRING DestinationString,
 88     IN PCWSTR SourceString OPTIONAL
 89 );
 90 
 91 void Sub_2();
 92 void Sub_3();
 93 
 94 
 95 
 96 //拷贝操作
 97 void StringCopyTest();
 98 VOID
 99 Ums_RtlCopyUnicodeString(
100     OUT PUNICODE_STRING DestinationString,
101     IN PUNICODE_STRING SourceString OPTIONAL
102 );
103 VOID
104 Ums_RtlFreeUnicodeString(
105     IN OUT PUNICODE_STRING UnicodeString
106 );
107 
108 
109 
110 //字符串比较
111 void StringCompareTest();
112 BOOLEAN
113 Ums_RtlEqualUnicodeString(
114     IN const PUNICODE_STRING String1,
115     IN const PUNICODE_STRING String2,
116     IN BOOLEAN CaseInSensitive
117 );
118 
119 
120 
121 //字符串变大写
122 void StringToUpperTest();
123 BOOL
124 Ums_RtlUpcaseUnicodeString(
125     OUT PUNICODE_STRING DestinationString,
126     IN PCUNICODE_STRING SourceString,
127     IN BOOLEAN AllocateDestinationString
128 );
129 
130 
131 
132 
133 //字符串与整型相互转化
134 void StringToIntegerTest();
135 
136 BOOL
137 Ums_RtlUnicodeStringToInteger(
138     IN PUNICODE_STRING String,
139     IN ULONG Base OPTIONAL,
140     OUT PULONG Value
141 );
142 BOOL
143 Ums_RtlIntegerToUnicodeString(
144     IN ULONG Value,
145     IN ULONG Base OPTIONAL,
146     IN OUT PUNICODE_STRING String
147 );
148 BOOL
149 Ums_RtlIntegerToChar(
150     IN ULONG Value,
151     IN ULONG Base OPTIONAL,
152     IN LONG OutputLength,
153     OUT PSZ String
154 );
155 BOOL
156 Ums_RtlAnsiStringToUnicodeString(
157     OUT PUNICODE_STRING DestinationString,
158     IN PANSI_STRING SourceString,
159     IN BOOLEAN AllocateDestinationString
160 );
161 
162 
163 //ANSI_STRING字符串与UNICODE_STRING字符串相互
164 void StringConverTest();
165 
166 VOID
167 Ums_RtlFreeAnsiString(
168     IN OUT PANSI_STRING AnsiString
169 );
170 
171 VOID
172 Ums_RtlInitString(
173     OUT PSTRING DestinationString,
174     IN char* SourceString OPTIONAL
175 );
176 BOOL
177 Ums_RtlUnicodeStringToAnsiString(
178     OUT PANSI_STRING DestinationString,
179     IN PUNICODE_STRING SourceString,
180     IN BOOLEAN AllocateDestinationString
181 );
182 ULONG
183 Ums_RtlxAnsiStringToUnicodeSize(
184     IN PANSI_STRING AnsiString
185 );
186 BOOL
187 Ums_RtlMultiByteToUnicodeSize(
188     OUT PULONG BytesInUnicodeString,
189     IN PCH MultiByteString,
190     IN ULONG BytesInMultiByteString
191 );
192 ULONG
193 Ums_RtlxUnicodeStringToAnsiSize(
194     IN PUNICODE_STRING UnicodeString
195 );
196 BOOL
197 Ums_RtlUnicodeToMultiByteSize(
198     OUT PULONG BytesInMultiByteString,
199     IN PWCH UnicodeString,
200     IN ULONG BytesInUnicodeString
201 );
202 BOOL
203 Ums_RtlUnicodeToMultiByteN(
204     OUT PCH MultiByteString,
205     IN ULONG MaxBytesInMultiByteString,
206     OUT PULONG BytesInMultiByteString OPTIONAL,
207     IN PWCH UnicodeString,
208     IN ULONG BytesInUnicodeString
209 );

 

转载于:https://www.cnblogs.com/1228073191Blog/p/7375972.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值