1 /* 2 * LICENSE: GPL - See COPYING in the top level directory 3 * PROJECT: ReactOS Console Server DLL 4 * FILE: win32ss/user/winsrv/consrv/alias.c 5 * PURPOSE: Alias support functions 6 * PROGRAMMERS: Christoph Wittich 7 * Johannes Anderwald 8 */ 9 10 /* INCLUDES *******************************************************************/ 11 12 #include "consrv.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 /* TYPES **********************************************************************/ 18 19 typedef struct _ALIAS_ENTRY 20 { 21 struct _ALIAS_ENTRY* Next; 22 UNICODE_STRING Source; 23 UNICODE_STRING Target; 24 } ALIAS_ENTRY, *PALIAS_ENTRY; 25 26 typedef struct _ALIAS_HEADER 27 { 28 struct _ALIAS_HEADER* Next; 29 UNICODE_STRING ExeName; 30 PALIAS_ENTRY Data; 31 } ALIAS_HEADER, *PALIAS_HEADER; 32 33 34 35 36 BOOLEAN 37 ConvertInputAnsiToUnicode(PCONSRV_CONSOLE Console, 38 PVOID Source, 39 USHORT SourceLength, 40 // BOOLEAN IsUnicode, 41 PWCHAR* Target, 42 PUSHORT TargetLength) 43 { 44 ASSERT(Source && Target && TargetLength); 45 46 /* Use the console input CP for the conversion */ 47 *TargetLength = MultiByteToWideChar(Console->InputCodePage, 0, 48 Source, SourceLength, 49 NULL, 0); 50 *Target = ConsoleAllocHeap(0, *TargetLength * sizeof(WCHAR)); 51 if (*Target == NULL) return FALSE; 52 53 MultiByteToWideChar(Console->InputCodePage, 0, 54 Source, SourceLength, 55 *Target, *TargetLength); 56 57 /* The returned Length was in number of WCHARs, convert it in bytes */ 58 *TargetLength *= sizeof(WCHAR); 59 60 return TRUE; 61 } 62 63 BOOLEAN 64 ConvertInputUnicodeToAnsi(PCONSRV_CONSOLE Console, 65 PVOID Source, 66 USHORT SourceLength, 67 // BOOLEAN IsAnsi, 68 PCHAR/* * */ Target, 69 /*P*/USHORT TargetLength) 70 { 71 ASSERT(Source && Target && TargetLength); 72 73 /* 74 * From MSDN: 75 * "The lpMultiByteStr and lpWideCharStr pointers must not be the same. 76 * If they are the same, the function fails, and GetLastError returns 77 * ERROR_INVALID_PARAMETER." 78 */ 79 ASSERT((ULONG_PTR)Source != (ULONG_PTR)Target); 80 81 /* Use the console input CP for the conversion */ 82 // *TargetLength = WideCharToMultiByte(Console->InputCodePage, 0, 83 // Source, SourceLength, 84 // NULL, 0, NULL, NULL); 85 // *Target = ConsoleAllocHeap(0, *TargetLength * sizeof(WCHAR)); 86 // if (*Target == NULL) return FALSE; 87 88 WideCharToMultiByte(Console->InputCodePage, 0, 89 Source, SourceLength, 90 /* * */Target, /* * */TargetLength, 91 NULL, NULL); 92 93 // /* The returned Length was in number of WCHARs, convert it in bytes */ 94 // *TargetLength *= sizeof(WCHAR); 95 96 return TRUE; 97 } 98 99 100 101 102 /* PRIVATE FUNCTIONS **********************************************************/ 103 104 static PALIAS_HEADER 105 IntFindAliasHeader(PCONSRV_CONSOLE Console, 106 PVOID ExeName, 107 USHORT ExeLength, 108 BOOLEAN UnicodeExe) 109 { 110 UNICODE_STRING ExeNameU; 111 112 PALIAS_HEADER RootHeader = Console->Aliases; 113 INT Diff; 114 115 if (ExeName == NULL) return NULL; 116 117 if (UnicodeExe) 118 { 119 ExeNameU.Buffer = ExeName; 120 /* Length is in bytes */ 121 ExeNameU.MaximumLength = ExeLength; 122 } 123 else 124 { 125 if (!ConvertInputAnsiToUnicode(Console, 126 ExeName, ExeLength, 127 &ExeNameU.Buffer, &ExeNameU.MaximumLength)) 128 { 129 return NULL; 130 } 131 } 132 ExeNameU.Length = ExeNameU.MaximumLength; 133 134 while (RootHeader) 135 { 136 Diff = RtlCompareUnicodeString(&RootHeader->ExeName, &ExeNameU, TRUE); 137 if (!Diff) 138 { 139 if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); 140 return RootHeader; 141 } 142 if (Diff > 0) break; 143 144 RootHeader = RootHeader->Next; 145 } 146 147 if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); 148 return NULL; 149 } 150 151 static PALIAS_HEADER 152 IntCreateAliasHeader(PCONSRV_CONSOLE Console, 153 PVOID ExeName, 154 USHORT ExeLength, 155 BOOLEAN UnicodeExe) 156 { 157 UNICODE_STRING ExeNameU; 158 159 PALIAS_HEADER Entry; 160 161 if (ExeName == NULL) return NULL; 162 163 if (UnicodeExe) 164 { 165 ExeNameU.Buffer = ExeName; 166 /* Length is in bytes */ 167 ExeNameU.MaximumLength = ExeLength; 168 } 169 else 170 { 171 if (!ConvertInputAnsiToUnicode(Console, 172 ExeName, ExeLength, 173 &ExeNameU.Buffer, &ExeNameU.MaximumLength)) 174 { 175 return NULL; 176 } 177 } 178 ExeNameU.Length = ExeNameU.MaximumLength; 179 180 Entry = ConsoleAllocHeap(0, sizeof(ALIAS_HEADER) + ExeNameU.Length); 181 if (!Entry) 182 { 183 if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); 184 return Entry; 185 } 186 187 Entry->ExeName.Buffer = (PWSTR)(Entry + 1); 188 Entry->ExeName.Length = 0; 189 Entry->ExeName.MaximumLength = ExeNameU.Length; 190 RtlCopyUnicodeString(&Entry->ExeName, &ExeNameU); 191 192 Entry->Data = NULL; 193 Entry->Next = NULL; 194 195 if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer); 196 return Entry; 197 } 198 199 static VOID 200 IntInsertAliasHeader(PALIAS_HEADER* RootHeader, 201 PALIAS_HEADER NewHeader) 202 { 203 PALIAS_HEADER CurrentHeader; 204 PALIAS_HEADER *LastLink = RootHeader; 205 INT Diff; 206 207 while ((CurrentHeader = *LastLink) != NULL) 208 { 209 Diff = RtlCompareUnicodeString(&NewHeader->ExeName, &CurrentHeader->ExeName, TRUE); 210 if (Diff < 0) break; 211 212 LastLink = &CurrentHeader->Next; 213 } 214 215 *LastLink = NewHeader; 216 NewHeader->Next = CurrentHeader; 217 } 218 219 static PALIAS_ENTRY 220 IntGetAliasEntry(PCONSRV_CONSOLE Console, 221 PALIAS_HEADER Header, 222 PVOID Source, 223 USHORT SourceLength, 224 BOOLEAN Unicode) 225 { 226 UNICODE_STRING SourceU; 227 228 PALIAS_ENTRY Entry; 229 INT Diff; 230 231 if (Header == NULL || Source == NULL) return NULL; 232 233 if (Unicode) 234 { 235 SourceU.Buffer = Source; 236 /* Length is in bytes */ 237 SourceU.MaximumLength = SourceLength; 238 } 239 else 240 { 241 if (!ConvertInputAnsiToUnicode(Console, 242 Source, SourceLength, 243 &SourceU.Buffer, &SourceU.MaximumLength)) 244 { 245 return NULL; 246 } 247 } 248 SourceU.Length = SourceU.MaximumLength; 249 250 Entry = Header->Data; 251 while (Entry) 252 { 253 Diff = RtlCompareUnicodeString(&Entry->Source, &SourceU, TRUE); 254 if (!Diff) 255 { 256 if (!Unicode) ConsoleFreeHeap(SourceU.Buffer); 257 return Entry; 258 } 259 if (Diff > 0) break; 260 261 Entry = Entry->Next; 262 } 263 264 if (!Unicode) ConsoleFreeHeap(SourceU.Buffer); 265 return NULL; 266 } 267 268 static PALIAS_ENTRY 269 IntCreateAliasEntry(PCONSRV_CONSOLE Console, 270 PVOID Source, 271 USHORT SourceLength, 272 PVOID Target, 273 USHORT TargetLength, 274 BOOLEAN Unicode) 275 { 276 UNICODE_STRING SourceU; 277 UNICODE_STRING TargetU; 278 279 PALIAS_ENTRY Entry; 280 281 if (Unicode) 282 { 283 SourceU.Buffer = Source; 284 TargetU.Buffer = Target; 285 /* Length is in bytes */ 286 SourceU.MaximumLength = SourceLength; 287 TargetU.MaximumLength = TargetLength; 288 } 289 else 290 { 291 if (!ConvertInputAnsiToUnicode(Console, 292 Source, SourceLength, 293 &SourceU.Buffer, &SourceU.MaximumLength)) 294 { 295 return NULL; 296 } 297 298 if (!ConvertInputAnsiToUnicode(Console, 299 Target, TargetLength, 300 &TargetU.Buffer, &TargetU.MaximumLength)) 301 { 302 ConsoleFreeHeap(SourceU.Buffer); 303 return NULL; 304 } 305 } 306 SourceU.Length = SourceU.MaximumLength; 307 TargetU.Length = TargetU.MaximumLength; 308 309 Entry = ConsoleAllocHeap(0, sizeof(ALIAS_ENTRY) + 310 SourceU.Length + TargetU.Length); 311 if (!Entry) 312 { 313 if (!Unicode) 314 { 315 ConsoleFreeHeap(TargetU.Buffer); 316 ConsoleFreeHeap(SourceU.Buffer); 317 } 318 return Entry; 319 } 320 321 Entry->Source.Buffer = (PWSTR)(Entry + 1); 322 Entry->Source.Length = 0; 323 Entry->Source.MaximumLength = SourceU.Length; 324 RtlCopyUnicodeString(&Entry->Source, &SourceU); 325 326 Entry->Target.Buffer = (PWSTR)((ULONG_PTR)Entry->Source.Buffer + Entry->Source.MaximumLength); 327 Entry->Target.Length = 0; 328 Entry->Target.MaximumLength = TargetU.Length; 329 RtlCopyUnicodeString(&Entry->Target, &TargetU); 330 331 Entry->Next = NULL; 332 333 if (!Unicode) 334 { 335 ConsoleFreeHeap(TargetU.Buffer); 336 ConsoleFreeHeap(SourceU.Buffer); 337 } 338 return Entry; 339 } 340 341 static VOID 342 IntInsertAliasEntry(PALIAS_HEADER Header, 343 PALIAS_ENTRY NewEntry) 344 { 345 PALIAS_ENTRY CurrentEntry; 346 PALIAS_ENTRY *LastLink = &Header->Data; 347 INT Diff; 348 349 while ((CurrentEntry = *LastLink) != NULL) 350 { 351 Diff = RtlCompareUnicodeString(&NewEntry->Source, &CurrentEntry->Source, TRUE); 352 if (Diff < 0) break; 353 354 LastLink = &CurrentEntry->Next; 355 } 356 357 *LastLink = NewEntry; 358 NewEntry->Next = CurrentEntry; 359 } 360 361 static VOID 362 IntDeleteAliasEntry(PALIAS_HEADER Header, 363 PALIAS_ENTRY Entry) 364 { 365 PALIAS_ENTRY *LastLink = &Header->Data; 366 PALIAS_ENTRY CurEntry; 367 368 while ((CurEntry = *LastLink) != NULL) 369 { 370 if (CurEntry == Entry) 371 { 372 *LastLink = Entry->Next; 373 ConsoleFreeHeap(Entry); 374 return; 375 } 376 LastLink = &CurEntry->Next; 377 } 378 } 379 380 static UINT 381 IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader, 382 BOOLEAN IsUnicode) 383 { 384 UINT Length = 0; 385 386 while (RootHeader) 387 { 388 Length += RootHeader->ExeName.Length + sizeof(WCHAR); // NULL-termination 389 RootHeader = RootHeader->Next; 390 } 391 392 /* 393 * Quick and dirty way of getting the number of bytes of the 394 * corresponding ANSI string from the one in UNICODE. 395 */ 396 if (!IsUnicode) 397 Length /= sizeof(WCHAR); 398 399 return Length; 400 } 401 402 static UINT 403 IntGetAllConsoleAliasesLength(PALIAS_HEADER Header, 404 BOOLEAN IsUnicode) 405 { 406 UINT Length = 0; 407 PALIAS_ENTRY CurEntry = Header->Data; 408 409 while (CurEntry) 410 { 411 Length += CurEntry->Source.Length; 412 Length += CurEntry->Target.Length; 413 Length += 2 * sizeof(WCHAR); // '=' and NULL-termination 414 CurEntry = CurEntry->Next; 415 } 416 417 /* 418 * Quick and dirty way of getting the number of bytes of the 419 * corresponding ANSI string from the one in UNICODE. 420 */ 421 if (!IsUnicode) 422 Length /= sizeof(WCHAR); 423 424 return Length; 425 } 426 427 VOID 428 IntDeleteAllAliases(PCONSRV_CONSOLE Console) 429 { 430 PALIAS_HEADER Header, NextHeader; 431 PALIAS_ENTRY Entry, NextEntry; 432 433 for (Header = Console->Aliases; Header; Header = NextHeader) 434 { 435 NextHeader = Header->Next; 436 for (Entry = Header->Data; Entry; Entry = NextEntry) 437 { 438 NextEntry = Entry->Next; 439 ConsoleFreeHeap(Entry); 440 } 441 ConsoleFreeHeap(Header); 442 } 443 } 444 445 446 /* PUBLIC SERVER APIS *********************************************************/ 447 448 /* API_NUMBER: ConsolepAddAlias */ 449 CON_API(SrvAddConsoleAlias, 450 CONSOLE_ADDGETALIAS, ConsoleAliasRequest) 451 { 452 PALIAS_HEADER Header; 453 PALIAS_ENTRY Entry; 454 PVOID lpTarget; 455 456 if ( !CsrValidateMessageBuffer(ApiMessage, 457 (PVOID*)&ConsoleAliasRequest->Source, 458 ConsoleAliasRequest->SourceLength, 459 sizeof(BYTE)) || 460 !CsrValidateMessageBuffer(ApiMessage, 461 (PVOID*)&ConsoleAliasRequest->Target, 462 ConsoleAliasRequest->TargetLength, 463 sizeof(BYTE)) || 464 !CsrValidateMessageBuffer(ApiMessage, 465 (PVOID*)&ConsoleAliasRequest->ExeName, 466 ConsoleAliasRequest->ExeLength, 467 sizeof(BYTE)) ) 468 { 469 return STATUS_INVALID_PARAMETER; 470 } 471 472 lpTarget = (ConsoleAliasRequest->TargetLength != 0 ? ConsoleAliasRequest->Target : NULL); 473 474 Header = IntFindAliasHeader(Console, 475 ConsoleAliasRequest->ExeName, 476 ConsoleAliasRequest->ExeLength, 477 ConsoleAliasRequest->Unicode2); 478 if (!Header && lpTarget != NULL) 479 { 480 Header = IntCreateAliasHeader(Console, 481 ConsoleAliasRequest->ExeName, 482 ConsoleAliasRequest->ExeLength, 483 ConsoleAliasRequest->Unicode2); 484 if (!Header) 485 return STATUS_NO_MEMORY; 486 487 IntInsertAliasHeader(&Console->Aliases, Header); 488 } 489 490 if (lpTarget == NULL) // Delete the entry 491 { 492 Entry = IntGetAliasEntry(Console, Header, 493 ConsoleAliasRequest->Source, 494 ConsoleAliasRequest->SourceLength, 495 ConsoleAliasRequest->Unicode); 496 if (!Entry) 497 return STATUS_UNSUCCESSFUL; 498 499 IntDeleteAliasEntry(Header, Entry); 500 } 501 else // Add the entry 502 { 503 Entry = IntCreateAliasEntry(Console, 504 ConsoleAliasRequest->Source, 505 ConsoleAliasRequest->SourceLength, 506 ConsoleAliasRequest->Target, 507 ConsoleAliasRequest->TargetLength, 508 ConsoleAliasRequest->Unicode); 509 if (!Entry) 510 return STATUS_NO_MEMORY; 511 512 IntInsertAliasEntry(Header, Entry); 513 } 514 515 return STATUS_SUCCESS; 516 } 517 518 /* API_NUMBER: ConsolepGetAlias */ 519 CON_API(SrvGetConsoleAlias, 520 CONSOLE_ADDGETALIAS, ConsoleAliasRequest) 521 { 522 PALIAS_HEADER Header; 523 PALIAS_ENTRY Entry; 524 UINT Length; 525 PVOID lpTarget; 526 527 if ( !CsrValidateMessageBuffer(ApiMessage, 528 (PVOID*)&ConsoleAliasRequest->Source, 529 ConsoleAliasRequest->SourceLength, 530 sizeof(BYTE)) || 531 !CsrValidateMessageBuffer(ApiMessage, 532 (PVOID*)&ConsoleAliasRequest->Target, 533 ConsoleAliasRequest->TargetLength, 534 sizeof(BYTE)) || 535 !CsrValidateMessageBuffer(ApiMessage, 536 (PVOID*)&ConsoleAliasRequest->ExeName, 537 ConsoleAliasRequest->ExeLength, 538 sizeof(BYTE)) ) 539 { 540 return STATUS_INVALID_PARAMETER; 541 } 542 543 lpTarget = ConsoleAliasRequest->Target; 544 545 if (ConsoleAliasRequest->ExeLength == 0 || lpTarget == NULL || 546 ConsoleAliasRequest->TargetLength == 0 || ConsoleAliasRequest->SourceLength == 0) 547 { 548 return STATUS_INVALID_PARAMETER; 549 } 550 551 Header = IntFindAliasHeader(Console, 552 ConsoleAliasRequest->ExeName, 553 ConsoleAliasRequest->ExeLength, 554 ConsoleAliasRequest->Unicode2); 555 if (!Header) 556 return STATUS_UNSUCCESSFUL; 557 558 Entry = IntGetAliasEntry(Console, Header, 559 ConsoleAliasRequest->Source, 560 ConsoleAliasRequest->SourceLength, 561 ConsoleAliasRequest->Unicode); 562 if (!Entry) 563 return STATUS_UNSUCCESSFUL; 564 565 if (ConsoleAliasRequest->Unicode) 566 { 567 Length = Entry->Target.Length + sizeof(WCHAR); 568 if (Length > ConsoleAliasRequest->TargetLength) // FIXME: Refine computation. 569 { 570 return STATUS_BUFFER_TOO_SMALL; 571 } 572 573 RtlCopyMemory(lpTarget, Entry->Target.Buffer, Entry->Target.Length); 574 ConsoleAliasRequest->TargetLength = Length; 575 } 576 else 577 { 578 Length = (Entry->Target.Length + sizeof(WCHAR)) / sizeof(WCHAR); 579 if (Length > ConsoleAliasRequest->TargetLength) // FIXME: Refine computation. 580 { 581 return STATUS_BUFFER_TOO_SMALL; 582 } 583 584 ConvertInputUnicodeToAnsi(Console, 585 Entry->Target.Buffer, Entry->Target.Length, 586 lpTarget, Entry->Target.Length / sizeof(WCHAR)); 587 ConsoleAliasRequest->TargetLength = Length; 588 } 589 590 return STATUS_SUCCESS; 591 } 592 593 /* API_NUMBER: ConsolepGetAliases */ 594 CON_API(SrvGetConsoleAliases, 595 CONSOLE_GETALLALIASES, GetAllAliasesRequest) 596 { 597 NTSTATUS Status; 598 ULONG BytesWritten = 0; 599 PALIAS_HEADER Header; 600 601 if ( !CsrValidateMessageBuffer(ApiMessage, 602 (PVOID)&GetAllAliasesRequest->ExeName, 603 GetAllAliasesRequest->ExeLength, 604 sizeof(BYTE)) || 605 !CsrValidateMessageBuffer(ApiMessage, 606 (PVOID)&GetAllAliasesRequest->AliasesBuffer, 607 GetAllAliasesRequest->AliasesBufferLength, 608 sizeof(BYTE)) ) 609 { 610 return STATUS_INVALID_PARAMETER; 611 } 612 613 Header = IntFindAliasHeader(Console, 614 GetAllAliasesRequest->ExeName, 615 GetAllAliasesRequest->ExeLength, 616 GetAllAliasesRequest->Unicode2); 617 if (!Header) 618 { 619 Status = STATUS_UNSUCCESSFUL; 620 goto Quit; 621 } 622 623 if (IntGetAllConsoleAliasesLength(Header, GetAllAliasesRequest->Unicode) > GetAllAliasesRequest->AliasesBufferLength) 624 { 625 Status = STATUS_BUFFER_OVERFLOW; 626 goto Quit; 627 } 628 629 { 630 LPSTR TargetBufferA; 631 LPWSTR TargetBufferW; 632 UINT TargetBufferLength = GetAllAliasesRequest->AliasesBufferLength; 633 634 PALIAS_ENTRY CurEntry = Header->Data; 635 UINT Offset = 0; 636 UINT SourceLength, TargetLength; 637 638 if (GetAllAliasesRequest->Unicode) 639 { 640 TargetBufferW = GetAllAliasesRequest->AliasesBuffer; 641 TargetBufferLength /= sizeof(WCHAR); 642 } 643 else 644 { 645 TargetBufferA = GetAllAliasesRequest->AliasesBuffer; 646 } 647 648 while (CurEntry) 649 { 650 SourceLength = CurEntry->Source.Length / sizeof(WCHAR); 651 TargetLength = CurEntry->Target.Length / sizeof(WCHAR); 652 if (Offset + TargetLength + SourceLength + 2 > TargetBufferLength) 653 { 654 Status = STATUS_BUFFER_OVERFLOW; 655 break; 656 } 657 658 if (GetAllAliasesRequest->Unicode) 659 { 660 RtlCopyMemory(&TargetBufferW[Offset], CurEntry->Source.Buffer, SourceLength * sizeof(WCHAR)); 661 Offset += SourceLength; 662 TargetBufferW[Offset++] = L'='; 663 RtlCopyMemory(&TargetBufferW[Offset], CurEntry->Target.Buffer, TargetLength * sizeof(WCHAR)); 664 Offset += TargetLength; 665 TargetBufferW[Offset++] = L'\0'; 666 } 667 else 668 { 669 ConvertInputUnicodeToAnsi(Console, 670 CurEntry->Source.Buffer, SourceLength * sizeof(WCHAR), 671 &TargetBufferA[Offset], SourceLength); 672 Offset += SourceLength; 673 TargetBufferA[Offset++] = '='; 674 ConvertInputUnicodeToAnsi(Console, 675 CurEntry->Target.Buffer, TargetLength * sizeof(WCHAR), 676 &TargetBufferA[Offset], TargetLength); 677 Offset += TargetLength; 678 TargetBufferA[Offset++] = '\0'; 679 } 680 681 CurEntry = CurEntry->Next; 682 } 683 684 if (GetAllAliasesRequest->Unicode) 685 BytesWritten = Offset * sizeof(WCHAR); 686 else 687 BytesWritten = Offset; 688 } 689 690 Quit: 691 GetAllAliasesRequest->AliasesBufferLength = BytesWritten; 692 693 return Status; 694 } 695 696 /* API_NUMBER: ConsolepGetAliasesLength */ 697 CON_API(SrvGetConsoleAliasesLength, 698 CONSOLE_GETALLALIASESLENGTH, GetAllAliasesLengthRequest) 699 { 700 NTSTATUS Status; 701 PALIAS_HEADER Header; 702 703 if (!CsrValidateMessageBuffer(ApiMessage, 704 (PVOID)&GetAllAliasesLengthRequest->ExeName, 705 GetAllAliasesLengthRequest->ExeLength, 706 sizeof(BYTE))) 707 { 708 return STATUS_INVALID_PARAMETER; 709 } 710 711 Header = IntFindAliasHeader(Console, 712 GetAllAliasesLengthRequest->ExeName, 713 GetAllAliasesLengthRequest->ExeLength, 714 GetAllAliasesLengthRequest->Unicode2); 715 if (Header) 716 { 717 GetAllAliasesLengthRequest->Length = 718 IntGetAllConsoleAliasesLength(Header, 719 GetAllAliasesLengthRequest->Unicode); 720 Status = STATUS_SUCCESS; 721 } 722 else 723 { 724 GetAllAliasesLengthRequest->Length = 0; 725 } 726 727 return Status; 728 } 729 730 /* API_NUMBER: ConsolepGetAliasExes */ 731 CON_API(SrvGetConsoleAliasExes, 732 CONSOLE_GETALIASESEXES, GetAliasesExesRequest) 733 { 734 NTSTATUS Status; 735 UINT BytesWritten = 0; 736 737 if (!CsrValidateMessageBuffer(ApiMessage, 738 (PVOID*)&GetAliasesExesRequest->ExeNames, 739 GetAliasesExesRequest->Length, 740 sizeof(BYTE))) 741 { 742 return STATUS_INVALID_PARAMETER; 743 } 744 745 if (IntGetConsoleAliasesExesLength(Console->Aliases, GetAliasesExesRequest->Unicode) > GetAliasesExesRequest->Length) 746 { 747 Status = STATUS_BUFFER_OVERFLOW; 748 goto Quit; 749 } 750 751 { 752 PALIAS_HEADER RootHeader = Console->Aliases; 753 754 LPSTR TargetBufferA; 755 LPWSTR TargetBufferW; 756 UINT TargetBufferSize = GetAliasesExesRequest->Length; 757 758 UINT Offset = 0; 759 UINT Length; 760 761 if (GetAliasesExesRequest->Unicode) 762 { 763 TargetBufferW = GetAliasesExesRequest->ExeNames; 764 TargetBufferSize /= sizeof(WCHAR); 765 } 766 else 767 { 768 TargetBufferA = GetAliasesExesRequest->ExeNames; 769 } 770 771 while (RootHeader) 772 { 773 Length = RootHeader->ExeName.Length / sizeof(WCHAR); 774 if (Offset + Length + 1 > TargetBufferSize) 775 { 776 Status = STATUS_BUFFER_OVERFLOW; 777 break; 778 } 779 780 if (GetAliasesExesRequest->Unicode) 781 { 782 RtlCopyMemory(&TargetBufferW[Offset], RootHeader->ExeName.Buffer, Length * sizeof(WCHAR)); 783 Offset += Length; 784 TargetBufferW[Offset++] = L'\0'; 785 } 786 else 787 { 788 ConvertInputUnicodeToAnsi(Console, 789 RootHeader->ExeName.Buffer, Length * sizeof(WCHAR), 790 &TargetBufferA[Offset], Length); 791 Offset += Length; 792 TargetBufferA[Offset++] = '\0'; 793 } 794 795 RootHeader = RootHeader->Next; 796 } 797 798 if (GetAliasesExesRequest->Unicode) 799 BytesWritten = Offset * sizeof(WCHAR); 800 else 801 BytesWritten = Offset; 802 } 803 804 Quit: 805 GetAliasesExesRequest->Length = BytesWritten; 806 807 return Status; 808 } 809 810 /* API_NUMBER: ConsolepGetAliasExesLength */ 811 CON_API(SrvGetConsoleAliasExesLength, 812 CONSOLE_GETALIASESEXESLENGTH, GetAliasesExesLengthRequest) 813 { 814 GetAliasesExesLengthRequest->Length = 815 IntGetConsoleAliasesExesLength(Console->Aliases, 816 GetAliasesExesLengthRequest->Unicode); 817 818 return STATUS_SUCCESS; 819 } 820 821 /* EOF */ 822