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