// 纯粹做个记录,微软源码
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 "); 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 ", &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 ", &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 ", &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 ", &SourceString); 136 printf("DestinationString:%wZ ", &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 "); 214 } 215 else 216 { 217 printf("UnicodeString1 and UnicodeString2 are NOT equal "); 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 ", &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 ", &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! "); 371 printf("Result:%d ", lNumber); 372 } 373 else 374 { 375 printf("Conver to integer unsuccessfully! "); 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! "); 399 printf("Result:%wZ ", &UnicodeString2); 400 } 401 else 402 { 403 printf("Conver to string unsuccessfully! "); 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 = '