ReactOS  0.4.14-dev-342-gdc047f9
alias.c
Go to the documentation of this file.
1 /*
2  * LICENSE: GPL - See COPYING in the top level directory
3  * PROJECT: ReactOS Console Server DLL
4  * FILE: win32ss/user/winsrv/consrv_new/alias.c
5  * PURPOSE: Alias support functions
6  * PROGRAMMERS: Christoph Wittich
7  * Johannes Anderwald
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include "consrv.h"
13 #include "console.h"
14 #include "include/conio.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 
20 /* TYPES **********************************************************************/
21 
22 typedef struct _ALIAS_ENTRY
23 {
26  struct _ALIAS_ENTRY* Next;
28 
29 typedef struct _ALIAS_HEADER
30 {
33  struct _ALIAS_HEADER* Next;
35 
36 
37 /* PRIVATE FUNCTIONS **********************************************************/
38 
39 static
42 {
43  while (RootHeader)
44  {
45  INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
46  if (!diff) return RootHeader;
47  if (diff > 0) break;
48 
49  RootHeader = RootHeader->Next;
50  }
51  return NULL;
52 }
53 
56 {
59 
60  Entry = ConsoleAllocHeap(0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength);
61  if (!Entry) return Entry;
62 
63  Entry->lpExeName = (LPCWSTR)(Entry + 1);
64  wcscpy((PWCHAR)Entry->lpExeName, lpExeName);
65  Entry->Data = NULL;
66  Entry->Next = NULL;
67  return Entry;
68 }
69 
70 VOID
72 {
73  PALIAS_HEADER CurrentHeader;
74  PALIAS_HEADER *LastLink = RootHeader;
75 
76  while ((CurrentHeader = *LastLink) != NULL)
77  {
78  INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName);
79  if (Diff < 0) break;
80 
81  LastLink = &CurrentHeader->Next;
82  }
83 
84  *LastLink = NewHeader;
85  NewHeader->Next = CurrentHeader;
86 }
87 
90 {
91  PALIAS_ENTRY RootHeader;
92 
93  if (Header == NULL) return NULL;
94 
95  RootHeader = Header->Data;
96  while (RootHeader)
97  {
98  INT diff;
99  DPRINT("IntGetAliasEntry->lpSource %S\n", RootHeader->lpSource);
100  diff = _wcsicmp(RootHeader->lpSource, lpSrcName);
101  if (!diff) return RootHeader;
102  if (diff > 0) break;
103 
104  RootHeader = RootHeader->Next;
105  }
106  return NULL;
107 }
108 
109 VOID
111 {
112  PALIAS_ENTRY CurrentEntry;
113  PALIAS_ENTRY *LastLink = &Header->Data;
114 
115  while ((CurrentEntry = *LastLink) != NULL)
116  {
117  INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource);
118  if (Diff < 0) break;
119 
120  LastLink = &CurrentEntry->Next;
121  }
122 
123  *LastLink = NewEntry;
124  NewEntry->Next = CurrentEntry;
125 }
126 
129 {
130  UINT dwSource;
131  UINT dwTarget;
133 
134  dwSource = wcslen(lpSource) + 1;
135  dwTarget = wcslen(lpTarget) + 1;
136 
137  Entry = ConsoleAllocHeap(0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget));
138  if (!Entry) return Entry;
139 
140  Entry->lpSource = (LPCWSTR)(Entry + 1);
141  wcscpy((LPWSTR)Entry->lpSource, lpSource);
142  Entry->lpTarget = Entry->lpSource + dwSource;
143  wcscpy((LPWSTR)Entry->lpTarget, lpTarget);
144  Entry->Next = NULL;
145 
146  return Entry;
147 }
148 
149 UINT
151 {
152  UINT length = 0;
153 
154  while (RootHeader)
155  {
156  length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
157  RootHeader = RootHeader->Next;
158  }
159  if (length)
160  length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes
161 
162  return length;
163 }
164 
165 UINT
166 IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT TargetBufferSize)
167 {
168  UINT Offset = 0;
169  UINT Length;
170 
171  TargetBufferSize /= sizeof(WCHAR);
172  while (RootHeader)
173  {
174  Length = wcslen(RootHeader->lpExeName) + 1;
175  if (TargetBufferSize > Offset + Length)
176  {
177  wcscpy(&TargetBuffer[Offset], RootHeader->lpExeName);
178  Offset += Length;
179  }
180  else
181  {
182  break;
183  }
184  RootHeader = RootHeader->Next;
185  }
186  Length = min(Offset+1, TargetBufferSize);
187  TargetBuffer[Length] = L'\0';
188  return Length * sizeof(WCHAR);
189 }
190 
191 UINT
193 {
194  UINT Length = 0;
195  PALIAS_ENTRY CurEntry = Header->Data;
196 
197  while (CurEntry)
198  {
199  Length += wcslen(CurEntry->lpSource);
200  Length += wcslen(CurEntry->lpTarget);
201  Length += 2; // zero byte and '='
202  CurEntry = CurEntry->Next;
203  }
204 
205  if (Length)
206  {
207  return (Length+1) * sizeof(WCHAR);
208  }
209  return 0;
210 }
211 
212 UINT
213 IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength)
214 {
215  PALIAS_ENTRY CurEntry = Header->Data;
216  UINT Offset = 0;
217  UINT SrcLength, TargetLength;
218 
219  TargetBufferLength /= sizeof(WCHAR);
220  while (CurEntry)
221  {
222  SrcLength = wcslen(CurEntry->lpSource) + 1;
223  TargetLength = wcslen(CurEntry->lpTarget) + 1;
224  if (Offset + TargetLength + SrcLength >= TargetBufferLength)
225  break;
226 
227  wcscpy(&TargetBuffer[Offset], CurEntry->lpSource);
228  Offset += SrcLength;
229  TargetBuffer[Offset] = L'=';
230  wcscpy(&TargetBuffer[Offset], CurEntry->lpTarget);
231  Offset += TargetLength;
232 
233  CurEntry = CurEntry->Next;
234  }
235  TargetBuffer[Offset] = L'\0';
236  return Offset * sizeof(WCHAR);
237 }
238 
239 VOID
241 {
242  PALIAS_ENTRY *LastLink = &Header->Data;
243  PALIAS_ENTRY CurEntry;
244 
245  while ((CurEntry = *LastLink) != NULL)
246  {
247  if (CurEntry == Entry)
248  {
249  *LastLink = Entry->Next;
251  return;
252  }
253  LastLink = &CurEntry->Next;
254  }
255 }
256 
257 VOID
259 {
260  PALIAS_HEADER Header, NextHeader;
261  PALIAS_ENTRY Entry, NextEntry;
262 
263  for (Header = Console->Aliases; Header; Header = NextHeader)
264  {
265  NextHeader = Header->Next;
266  for (Entry = Header->Data; Entry; Entry = NextEntry)
267  {
268  NextEntry = Entry->Next;
270  }
272  }
273 }
274 
275 
276 /* PUBLIC SERVER APIS *********************************************************/
277 
278 CSR_API(SrvAddConsoleAlias)
279 {
280  PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleAliasRequest;
284  LPWSTR lpSource, lpTarget, lpExeName;
285 
286  DPRINT("SrvAddConsoleAlias entered ApiMessage %p\n", ApiMessage);
287 
288  if ( !CsrValidateMessageBuffer(ApiMessage,
289  (PVOID*)&ConsoleAliasRequest->Source,
290  ConsoleAliasRequest->SourceLength,
291  sizeof(BYTE)) ||
292  !CsrValidateMessageBuffer(ApiMessage,
293  (PVOID*)&ConsoleAliasRequest->Target,
294  ConsoleAliasRequest->TargetLength,
295  sizeof(BYTE)) ||
296  !CsrValidateMessageBuffer(ApiMessage,
297  (PVOID*)&ConsoleAliasRequest->Exe,
298  ConsoleAliasRequest->ExeLength,
299  sizeof(BYTE)) )
300  {
302  }
303 
304  lpSource = ConsoleAliasRequest->Source;
305  lpTarget = (ConsoleAliasRequest->TargetLength != 0 ? ConsoleAliasRequest->Target : NULL);
306  lpExeName = ConsoleAliasRequest->Exe;
307 
308  DPRINT("SrvAddConsoleAlias lpSource %p lpExeName %p lpTarget %p\n", lpSource, lpExeName, lpTarget);
309 
310  if (lpExeName == NULL || lpSource == NULL)
311  {
313  }
314 
316  if (!NT_SUCCESS(ApiMessage->Status))
317  {
318  return ApiMessage->Status;
319  }
320 
322  if (!Header && lpTarget != NULL)
323  {
325  if (!Header)
326  {
329  }
330  IntInsertAliasHeader(&Console->Aliases, Header);
331  }
332 
333  if (lpTarget == NULL) // Delete the entry
334  {
335  Entry = IntGetAliasEntry(Header, lpSource);
336  if (Entry)
337  {
339  ApiMessage->Status = STATUS_SUCCESS;
340  }
341  else
342  {
343  ApiMessage->Status = STATUS_INVALID_PARAMETER;
344  }
346  return ApiMessage->Status;
347  }
348 
349  Entry = IntCreateAliasEntry(lpSource, lpTarget);
350 
351  if (!Entry)
352  {
355  }
356 
359  return STATUS_SUCCESS;
360 }
361 
362 CSR_API(SrvGetConsoleAlias)
363 {
364  PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleAliasRequest;
368  UINT Length;
369  LPWSTR lpSource, lpTarget, lpExeName;
370 
371  DPRINT("SrvGetConsoleAlias entered ApiMessage %p\n", ApiMessage);
372 
373  if ( !CsrValidateMessageBuffer(ApiMessage,
374  (PVOID*)&ConsoleAliasRequest->Source,
375  ConsoleAliasRequest->SourceLength,
376  sizeof(BYTE)) ||
377  !CsrValidateMessageBuffer(ApiMessage,
378  (PVOID*)&ConsoleAliasRequest->Target,
379  ConsoleAliasRequest->TargetLength,
380  sizeof(BYTE)) ||
381  !CsrValidateMessageBuffer(ApiMessage,
382  (PVOID*)&ConsoleAliasRequest->Exe,
383  ConsoleAliasRequest->ExeLength,
384  sizeof(BYTE)) )
385  {
387  }
388 
389  lpSource = ConsoleAliasRequest->Source;
390  lpTarget = ConsoleAliasRequest->Target;
391  lpExeName = ConsoleAliasRequest->Exe;
392 
393  DPRINT("SrvGetConsoleAlias lpExeName %p lpSource %p TargetBuffer %p TargetLength %u\n",
394  lpExeName, lpSource, lpTarget, ConsoleAliasRequest->TargetLength);
395 
396  if (ConsoleAliasRequest->ExeLength == 0 || lpTarget == NULL ||
397  ConsoleAliasRequest->TargetLength == 0 || ConsoleAliasRequest->SourceLength == 0)
398  {
400  }
401 
403  if (!NT_SUCCESS(ApiMessage->Status))
404  {
405  return ApiMessage->Status;
406  }
407 
409  if (!Header)
410  {
413  }
414 
415  Entry = IntGetAliasEntry(Header, lpSource);
416  if (!Entry)
417  {
420  }
421 
422  Length = (wcslen(Entry->lpTarget) + 1) * sizeof(WCHAR);
423  if (Length > ConsoleAliasRequest->TargetLength)
424  {
427  }
428 
429  wcscpy(lpTarget, Entry->lpTarget);
430  ConsoleAliasRequest->TargetLength = Length;
432  return STATUS_SUCCESS;
433 }
434 
435 CSR_API(SrvGetConsoleAliases)
436 {
437  PCONSOLE_GETALLALIASES GetAllAliasesRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAllAliasesRequest;
441 
442  if ( !CsrValidateMessageBuffer(ApiMessage,
443  (PVOID)&GetAllAliasesRequest->ExeName,
444  GetAllAliasesRequest->ExeLength,
445  sizeof(BYTE)) ||
446  !CsrValidateMessageBuffer(ApiMessage,
447  (PVOID)&GetAllAliasesRequest->AliasesBuffer,
448  GetAllAliasesRequest->AliasesBufferLength,
449  sizeof(BYTE)) )
450  {
452  }
453 
454  if (GetAllAliasesRequest->ExeName == NULL)
455  {
457  }
458 
460  if (!NT_SUCCESS(ApiMessage->Status))
461  {
462  return ApiMessage->Status;
463  }
464 
465  Header = IntFindAliasHeader(Console->Aliases, GetAllAliasesRequest->ExeName);
466  if (!Header)
467  {
470  }
471 
472  if (IntGetAllConsoleAliasesLength(Header) > GetAllAliasesRequest->AliasesBufferLength)
473  {
475  return STATUS_BUFFER_OVERFLOW;
476  }
477 
479  GetAllAliasesRequest->AliasesBuffer,
480  GetAllAliasesRequest->AliasesBufferLength);
481 
482  GetAllAliasesRequest->AliasesBufferLength = BytesWritten;
484  return STATUS_SUCCESS;
485 }
486 
487 CSR_API(SrvGetConsoleAliasesLength)
488 {
489  PCONSOLE_GETALLALIASESLENGTH GetAllAliasesLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAllAliasesLengthRequest;
492  UINT Length;
493 
494  if (!CsrValidateMessageBuffer(ApiMessage,
495  (PVOID)&GetAllAliasesLengthRequest->ExeName,
496  GetAllAliasesLengthRequest->ExeLength,
497  sizeof(BYTE)))
498  {
500  }
501 
502  if (GetAllAliasesLengthRequest->ExeName == NULL)
503  {
505  }
506 
508  if (!NT_SUCCESS(ApiMessage->Status))
509  {
510  return ApiMessage->Status;
511  }
512 
513  Header = IntFindAliasHeader(Console->Aliases, GetAllAliasesLengthRequest->ExeName);
514  if (!Header)
515  {
518  }
519 
521  GetAllAliasesLengthRequest->Length = Length;
523  return STATUS_SUCCESS;
524 }
525 
526 CSR_API(SrvGetConsoleAliasExes)
527 {
528  PCONSOLE_GETALIASESEXES GetAliasesExesRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAliasesExesRequest;
531  UINT ExesLength;
532 
533  DPRINT("SrvGetConsoleAliasExes entered\n");
534 
535  if (!CsrValidateMessageBuffer(ApiMessage,
536  (PVOID)&GetAliasesExesRequest->ExeNames,
537  GetAliasesExesRequest->Length,
538  sizeof(BYTE)))
539  {
541  }
542 
544  if (!NT_SUCCESS(ApiMessage->Status))
545  {
546  return ApiMessage->Status;
547  }
548 
549  ExesLength = IntGetConsoleAliasesExesLength(Console->Aliases);
550 
551  if (ExesLength > GetAliasesExesRequest->Length)
552  {
554  return STATUS_BUFFER_OVERFLOW;
555  }
556 
557  if (GetAliasesExesRequest->ExeNames == NULL)
558  {
561  }
562 
564  GetAliasesExesRequest->ExeNames,
565  GetAliasesExesRequest->Length);
566 
567  GetAliasesExesRequest->Length = BytesWritten;
569  return STATUS_SUCCESS;
570 }
571 
572 CSR_API(SrvGetConsoleAliasExesLength)
573 {
574  PCONSOLE_GETALIASESEXESLENGTH GetAliasesExesLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetAliasesExesLengthRequest;
576  DPRINT("SrvGetConsoleAliasExesLength entered\n");
577 
579  if (NT_SUCCESS(ApiMessage->Status))
580  {
581  GetAliasesExesLengthRequest->Length = IntGetConsoleAliasesExesLength(Console->Aliases);
583  }
584  return ApiMessage->Status;
585 }
586 
587 /* EOF */
UINT IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader)
Definition: alias.c:150
UINT IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT TargetBufferSize)
Definition: alias.c:166
NTSTATUS ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData, OUT PCONSRV_CONSOLE *Console, IN BOOLEAN LockConsole)
Definition: console.c:271
#define CsrGetClientThread()
Definition: csrsrv.h:77
VOID IntDeleteAllAliases(PCONSRV_CONSOLE Console)
Definition: alias.c:428
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
#define TRUE
Definition: types.h:120
CSR_API(SrvAddConsoleAlias)
Definition: alias.c:448
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _Entry Entry
Definition: kefuncs.h:640
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
UINT IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength)
Definition: alias.c:213
LPCWSTR lpExeName
Definition: alias.c:31
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LPCWSTR lpTarget
Definition: alias.c:25
struct _CONSOLE_API_MESSAGE * PCONSOLE_API_MESSAGE
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1315
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
struct _ALIAS_ENTRY * PALIAS_ENTRY
uint16_t * PWCHAR
Definition: typedefs.h:54
VOID ConSrvReleaseConsole(IN PCONSRV_CONSOLE Console, IN BOOLEAN IsConsoleLocked)
Definition: console.c:296
int32_t INT
Definition: typedefs.h:56
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
struct _ALIAS_HEADER ALIAS_HEADER
PALIAS_ENTRY Data
Definition: alias.c:30
static DWORD LPSTR lpExeName
Definition: process.c:72
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
Definition: Header.h:8
VOID IntDeleteAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY Entry)
Definition: alias.c:240
UINT IntGetAllConsoleAliasesLength(PALIAS_HEADER Header)
Definition: alias.c:192
ULONG AliasesBufferLength
Definition: conmsg.h:748
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PALIAS_ENTRY IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName)
Definition: alias.c:89
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD DWORD * dwLength
Definition: fusion.c:85
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ConsoleGetPerProcessData(Process)
Definition: consrv.h:37
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
USHORT SourceLength
Definition: conmsg.h:731
static PALIAS_HEADER IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
Definition: alias.c:41
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct _ALIAS_HEADER * PALIAS_HEADER
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: mem.h:68
PALIAS_HEADER IntCreateAliasHeader(LPCWSTR lpExeName)
Definition: alias.c:55
VOID IntInsertAliasHeader(PALIAS_HEADER *RootHeader, PALIAS_HEADER NewHeader)
Definition: alias.c:71
Definition: alias.c:19
struct _ALIAS_ENTRY * Next
Definition: alias.c:21
VOID IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry)
Definition: alias.c:110
struct _ALIAS_HEADER * Next
Definition: alias.c:28
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
CConsole Console
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
LPCWSTR lpSource
Definition: alias.c:24
unsigned int ULONG
Definition: retypes.h:1
USHORT TargetLength
Definition: conmsg.h:732
PALIAS_ENTRY IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget)
Definition: alias.c:128
WCHAR * LPWSTR
Definition: xmlstorage.h:184
return STATUS_SUCCESS
Definition: btrfs.c:2938
struct _ALIAS_ENTRY ALIAS_ENTRY
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
base of all file and directory entries
Definition: entries.h:82
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)