[CONSRV]
[reactos.git] / win32ss / user / winsrv / consrv / alias.c
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 UNICODE_STRING Source;
22 UNICODE_STRING Target;
23 struct _ALIAS_ENTRY* Next;
24 } ALIAS_ENTRY, *PALIAS_ENTRY;
25
26 typedef struct _ALIAS_HEADER
27 {
28 UNICODE_STRING ExeName;
29 PALIAS_ENTRY Data;
30 struct _ALIAS_HEADER* Next;
31 } ALIAS_HEADER, *PALIAS_HEADER;
32
33
34
35
36 BOOLEAN
37 ConvertInputAnsiToUnicode(PCONSOLE 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(PCONSOLE 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(PCONSOLE 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(PCONSOLE 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(PCONSOLE 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(PCONSOLE 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(PCONSOLE 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 CSR_API(SrvAddConsoleAlias)
449 {
450 NTSTATUS Status;
451 PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleAliasRequest;
452 PCONSOLE Console;
453 PALIAS_HEADER Header;
454 PALIAS_ENTRY Entry;
455 PVOID lpTarget;
456
457 DPRINT1("SrvAddConsoleAlias entered ApiMessage %p\n", ApiMessage);
458
459 if ( !CsrValidateMessageBuffer(ApiMessage,
460 (PVOID*)&ConsoleAliasRequest->Source,
461 ConsoleAliasRequest->SourceLength,
462 sizeof(BYTE)) ||
463 !CsrValidateMessageBuffer(ApiMessage,
464 (PVOID*)&ConsoleAliasRequest->Target,
465 ConsoleAliasRequest->TargetLength,
466 sizeof(BYTE)) ||
467 !CsrValidateMessageBuffer(ApiMessage,
468 (PVOID*)&ConsoleAliasRequest->ExeName,
469 ConsoleAliasRequest->ExeLength,
470 sizeof(BYTE)) )
471 {
472 return STATUS_INVALID_PARAMETER;
473 }
474
475 lpTarget = (ConsoleAliasRequest->TargetLength != 0 ? ConsoleAliasRequest->Target : NULL);
476
477 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
478 if (!NT_SUCCESS(Status)) return Status;
479
480 Status = STATUS_SUCCESS;
481
482 Header = IntFindAliasHeader(Console,
483 ConsoleAliasRequest->ExeName,
484 ConsoleAliasRequest->ExeLength,
485 ConsoleAliasRequest->Unicode2);
486 if (!Header && lpTarget != NULL)
487 {
488 Header = IntCreateAliasHeader(Console,
489 ConsoleAliasRequest->ExeName,
490 ConsoleAliasRequest->ExeLength,
491 ConsoleAliasRequest->Unicode2);
492 if (!Header)
493 {
494 Status = STATUS_NO_MEMORY;
495 goto Quit;
496 }
497
498 IntInsertAliasHeader(&Console->Aliases, Header);
499 }
500
501 if (lpTarget == NULL) // Delete the entry
502 {
503 Entry = IntGetAliasEntry(Console, Header,
504 ConsoleAliasRequest->Source,
505 ConsoleAliasRequest->SourceLength,
506 ConsoleAliasRequest->Unicode);
507 if (!Entry)
508 {
509 Status = STATUS_UNSUCCESSFUL;
510 goto Quit;
511 }
512
513 IntDeleteAliasEntry(Header, Entry);
514 }
515 else // Add the entry
516 {
517 Entry = IntCreateAliasEntry(Console,
518 ConsoleAliasRequest->Source,
519 ConsoleAliasRequest->SourceLength,
520 ConsoleAliasRequest->Target,
521 ConsoleAliasRequest->TargetLength,
522 ConsoleAliasRequest->Unicode);
523 if (!Entry)
524 {
525 Status = STATUS_NO_MEMORY;
526 goto Quit;
527 }
528
529 IntInsertAliasEntry(Header, Entry);
530 }
531
532 Quit:
533 ConSrvReleaseConsole(Console, TRUE);
534 return Status;
535 }
536
537 CSR_API(SrvGetConsoleAlias)
538 {
539 NTSTATUS Status;
540 PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleAliasRequest;
541 PCONSOLE Console;
542 PALIAS_HEADER Header;
543 PALIAS_ENTRY Entry;
544 UINT Length;
545 PVOID lpTarget;
546
547 DPRINT1("SrvGetConsoleAlias entered ApiMessage %p\n", ApiMessage);
548
549 if ( !CsrValidateMessageBuffer(ApiMessage,
550 (PVOID*)&ConsoleAliasRequest->Source,
551 ConsoleAliasRequest->SourceLength,
552 sizeof(BYTE)) ||
553 !CsrValidateMessageBuffer(ApiMessage,
554 (PVOID*)&ConsoleAliasRequest->Target,
555 ConsoleAliasRequest->TargetLength,
556 sizeof(BYTE)) ||
557 !CsrValidateMessageBuffer(ApiMessage,
558 (PVOID*)&ConsoleAliasRequest->ExeName,
559 ConsoleAliasRequest->ExeLength,
560 sizeof(BYTE)) )
561 {
562 return STATUS_INVALID_PARAMETER;
563 }
564
565 lpTarget = ConsoleAliasRequest->Target;
566
567 if (ConsoleAliasRequest->ExeLength == 0 || lpTarget == NULL ||
568 ConsoleAliasRequest->TargetLength == 0 || ConsoleAliasRequest->SourceLength == 0)
569 {
570 return STATUS_INVALID_PARAMETER;
571 }
572
573 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
574 if (!NT_SUCCESS(Status)) return Status;
575
576 Header = IntFindAliasHeader(Console,
577 ConsoleAliasRequest->ExeName,
578 ConsoleAliasRequest->ExeLength,
579 ConsoleAliasRequest->Unicode2);
580 if (!Header)
581 {
582 Status = STATUS_UNSUCCESSFUL;
583 goto Quit;
584 }
585
586 Entry = IntGetAliasEntry(Console, Header,
587 ConsoleAliasRequest->Source,
588 ConsoleAliasRequest->SourceLength,
589 ConsoleAliasRequest->Unicode);
590 if (!Entry)
591 {
592 Status = STATUS_UNSUCCESSFUL;
593 goto Quit;
594 }
595
596 if (ConsoleAliasRequest->Unicode)
597 {
598 Length = Entry->Target.Length + sizeof(WCHAR);
599 if (Length > ConsoleAliasRequest->TargetLength) // FIXME: Refine computation.
600 {
601 Status = STATUS_BUFFER_TOO_SMALL;
602 goto Quit;
603 }
604
605 RtlCopyMemory(lpTarget, Entry->Target.Buffer, Entry->Target.Length);
606 ConsoleAliasRequest->TargetLength = Length;
607 }
608 else
609 {
610 Length = (Entry->Target.Length + sizeof(WCHAR)) / sizeof(WCHAR);
611 if (Length > ConsoleAliasRequest->TargetLength) // FIXME: Refine computation.
612 {
613 Status = STATUS_BUFFER_TOO_SMALL;
614 goto Quit;
615 }
616
617 ConvertInputUnicodeToAnsi(Console,
618 Entry->Target.Buffer, Entry->Target.Length,
619 lpTarget, Entry->Target.Length / sizeof(WCHAR));
620 ConsoleAliasRequest->TargetLength = Length;
621 }
622
623 Quit:
624 ConSrvReleaseConsole(Console, TRUE);
625 return Status;
626 }
627
628 CSR_API(SrvGetConsoleAliases)
629 {
630 NTSTATUS Status;
631 PCONSOLE_GETALLALIASES GetAllAliasesRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAllAliasesRequest;
632 PCONSOLE Console;
633 ULONG BytesWritten = 0;
634 PALIAS_HEADER Header;
635
636 DPRINT1("SrvGetConsoleAliases entered ApiMessage %p\n", ApiMessage);
637
638 if ( !CsrValidateMessageBuffer(ApiMessage,
639 (PVOID)&GetAllAliasesRequest->ExeName,
640 GetAllAliasesRequest->ExeLength,
641 sizeof(BYTE)) ||
642 !CsrValidateMessageBuffer(ApiMessage,
643 (PVOID)&GetAllAliasesRequest->AliasesBuffer,
644 GetAllAliasesRequest->AliasesBufferLength,
645 sizeof(BYTE)) )
646 {
647 return STATUS_INVALID_PARAMETER;
648 }
649
650 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
651 if (!NT_SUCCESS(Status)) return Status;
652
653 Header = IntFindAliasHeader(Console,
654 GetAllAliasesRequest->ExeName,
655 GetAllAliasesRequest->ExeLength,
656 GetAllAliasesRequest->Unicode2);
657 if (!Header) goto Quit;
658
659 if (IntGetAllConsoleAliasesLength(Header, GetAllAliasesRequest->Unicode) > GetAllAliasesRequest->AliasesBufferLength)
660 {
661 Status = STATUS_BUFFER_OVERFLOW;
662 goto Quit;
663 }
664
665 {
666 LPSTR TargetBufferA;
667 LPWSTR TargetBufferW;
668 UINT TargetBufferLength = GetAllAliasesRequest->AliasesBufferLength;
669
670 PALIAS_ENTRY CurEntry = Header->Data;
671 UINT Offset = 0;
672 UINT SourceLength, TargetLength;
673
674 if (GetAllAliasesRequest->Unicode)
675 {
676 TargetBufferW = GetAllAliasesRequest->AliasesBuffer;
677 TargetBufferLength /= sizeof(WCHAR);
678 }
679 else
680 {
681 TargetBufferA = GetAllAliasesRequest->AliasesBuffer;
682 }
683
684 while (CurEntry)
685 {
686 SourceLength = CurEntry->Source.Length / sizeof(WCHAR);
687 TargetLength = CurEntry->Target.Length / sizeof(WCHAR);
688 if (Offset + TargetLength + SourceLength + 2 > TargetBufferLength)
689 {
690 Status = STATUS_BUFFER_OVERFLOW;
691 break;
692 }
693
694 if (GetAllAliasesRequest->Unicode)
695 {
696 RtlCopyMemory(&TargetBufferW[Offset], CurEntry->Source.Buffer, SourceLength * sizeof(WCHAR));
697 Offset += SourceLength;
698 TargetBufferW[Offset++] = L'=';
699 RtlCopyMemory(&TargetBufferW[Offset], CurEntry->Target.Buffer, TargetLength * sizeof(WCHAR));
700 Offset += TargetLength;
701 TargetBufferW[Offset++] = L'\0';
702 }
703 else
704 {
705 ConvertInputUnicodeToAnsi(Console,
706 CurEntry->Source.Buffer, SourceLength * sizeof(WCHAR),
707 &TargetBufferA[Offset], SourceLength);
708 Offset += SourceLength;
709 TargetBufferA[Offset++] = '=';
710 ConvertInputUnicodeToAnsi(Console,
711 CurEntry->Target.Buffer, TargetLength * sizeof(WCHAR),
712 &TargetBufferA[Offset], TargetLength);
713 Offset += TargetLength;
714 TargetBufferA[Offset++] = '\0';
715 }
716
717 CurEntry = CurEntry->Next;
718 }
719
720 if (GetAllAliasesRequest->Unicode)
721 BytesWritten = Offset * sizeof(WCHAR);
722 else
723 BytesWritten = Offset;
724 }
725
726 Quit:
727 GetAllAliasesRequest->AliasesBufferLength = BytesWritten;
728
729 ConSrvReleaseConsole(Console, TRUE);
730 return Status;
731 }
732
733 CSR_API(SrvGetConsoleAliasesLength)
734 {
735 NTSTATUS Status;
736 PCONSOLE_GETALLALIASESLENGTH GetAllAliasesLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAllAliasesLengthRequest;
737 PCONSOLE Console;
738 PALIAS_HEADER Header;
739
740 DPRINT1("SrvGetConsoleAliasesLength entered ApiMessage %p\n", ApiMessage);
741
742 if (!CsrValidateMessageBuffer(ApiMessage,
743 (PVOID)&GetAllAliasesLengthRequest->ExeName,
744 GetAllAliasesLengthRequest->ExeLength,
745 sizeof(BYTE)))
746 {
747 return STATUS_INVALID_PARAMETER;
748 }
749
750 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
751 if (!NT_SUCCESS(Status)) return Status;
752
753 Header = IntFindAliasHeader(Console,
754 GetAllAliasesLengthRequest->ExeName,
755 GetAllAliasesLengthRequest->ExeLength,
756 GetAllAliasesLengthRequest->Unicode2);
757 if (Header)
758 {
759 GetAllAliasesLengthRequest->Length =
760 IntGetAllConsoleAliasesLength(Header,
761 GetAllAliasesLengthRequest->Unicode);
762 Status = STATUS_SUCCESS;
763 }
764 else
765 {
766 GetAllAliasesLengthRequest->Length = 0;
767 }
768
769 ConSrvReleaseConsole(Console, TRUE);
770 return Status;
771 }
772
773 CSR_API(SrvGetConsoleAliasExes)
774 {
775 NTSTATUS Status;
776 PCONSOLE_GETALIASESEXES GetAliasesExesRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAliasesExesRequest;
777 PCONSOLE Console;
778 UINT BytesWritten = 0;
779
780 DPRINT1("SrvGetConsoleAliasExes entered\n");
781
782 if (!CsrValidateMessageBuffer(ApiMessage,
783 (PVOID*)&GetAliasesExesRequest->ExeNames,
784 GetAliasesExesRequest->Length,
785 sizeof(BYTE)))
786 {
787 return STATUS_INVALID_PARAMETER;
788 }
789
790 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
791 if (!NT_SUCCESS(Status)) return Status;
792
793 if (IntGetConsoleAliasesExesLength(Console->Aliases, GetAliasesExesRequest->Unicode) > GetAliasesExesRequest->Length)
794 {
795 Status = STATUS_BUFFER_OVERFLOW;
796 goto Quit;
797 }
798
799 {
800 PALIAS_HEADER RootHeader = Console->Aliases;
801
802 LPSTR TargetBufferA;
803 LPWSTR TargetBufferW;
804 UINT TargetBufferSize = GetAliasesExesRequest->Length;
805
806 UINT Offset = 0;
807 UINT Length;
808
809 if (GetAliasesExesRequest->Unicode)
810 {
811 TargetBufferW = GetAliasesExesRequest->ExeNames;
812 TargetBufferSize /= sizeof(WCHAR);
813 }
814 else
815 {
816 TargetBufferA = GetAliasesExesRequest->ExeNames;
817 }
818
819 while (RootHeader)
820 {
821 Length = RootHeader->ExeName.Length / sizeof(WCHAR);
822 if (Offset + Length + 1 > TargetBufferSize)
823 {
824 Status = STATUS_BUFFER_OVERFLOW;
825 break;
826 }
827
828 if (GetAliasesExesRequest->Unicode)
829 {
830 RtlCopyMemory(&TargetBufferW[Offset], RootHeader->ExeName.Buffer, Length * sizeof(WCHAR));
831 Offset += Length;
832 TargetBufferW[Offset++] = L'\0';
833 }
834 else
835 {
836 ConvertInputUnicodeToAnsi(Console,
837 RootHeader->ExeName.Buffer, Length * sizeof(WCHAR),
838 &TargetBufferA[Offset], Length);
839 Offset += Length;
840 TargetBufferA[Offset++] = '\0';
841 }
842
843 RootHeader = RootHeader->Next;
844 }
845
846 if (GetAliasesExesRequest->Unicode)
847 BytesWritten = Offset * sizeof(WCHAR);
848 else
849 BytesWritten = Offset;
850 }
851
852 Quit:
853 GetAliasesExesRequest->Length = BytesWritten;
854
855 ConSrvReleaseConsole(Console, TRUE);
856 return Status;
857 }
858
859 CSR_API(SrvGetConsoleAliasExesLength)
860 {
861 NTSTATUS Status;
862 PCONSOLE_GETALIASESEXESLENGTH GetAliasesExesLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAliasesExesLengthRequest;
863 PCONSOLE Console;
864
865 DPRINT1("SrvGetConsoleAliasExesLength entered ApiMessage %p\n", ApiMessage);
866
867 Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
868 if (!NT_SUCCESS(Status)) return Status;
869
870 GetAliasesExesLengthRequest->Length =
871 IntGetConsoleAliasesExesLength(Console->Aliases,
872 GetAliasesExesLengthRequest->Unicode);
873
874 ConSrvReleaseConsole(Console, TRUE);
875 return Status;
876 }
877
878 /* EOF */