xref: /reactos/win32ss/user/winsrv/consrv/alias.c (revision d8c6ef5e)
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