2 * LICENSE: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/consrv/alias.c
5 * PURPOSE: Alias support functions
6 * PROGRAMMERS: Christoph Wittich
10 /* INCLUDES ******************************************************************/
19 typedef struct tagALIAS_ENTRY
23 struct tagALIAS_ENTRY
* Next
;
24 } ALIAS_ENTRY
, *PALIAS_ENTRY
;
26 typedef struct tagALIAS_HEADER
30 struct tagALIAS_HEADER
* Next
;
32 } ALIAS_HEADER
, *PALIAS_HEADER
;
37 IntFindAliasHeader(PALIAS_HEADER RootHeader
, LPCWSTR lpExeName
)
41 INT diff
= _wcsicmp(RootHeader
->lpExeName
, lpExeName
);
48 RootHeader
= RootHeader
->Next
;
54 IntCreateAliasHeader(LPCWSTR lpExeName
)
57 UINT dwLength
= wcslen(lpExeName
) + 1;
59 Entry
= RtlAllocateHeap(ConSrvHeap
, 0, sizeof(ALIAS_HEADER
) + sizeof(WCHAR
) * dwLength
);
63 Entry
->lpExeName
= (LPCWSTR
)(Entry
+ 1);
64 wcscpy((WCHAR
*)Entry
->lpExeName
, lpExeName
);
71 IntInsertAliasHeader(PALIAS_HEADER
* RootHeader
, PALIAS_HEADER NewHeader
)
73 PALIAS_HEADER CurrentHeader
;
74 PALIAS_HEADER
*LastLink
= RootHeader
;
76 while ((CurrentHeader
= *LastLink
) != NULL
)
78 INT Diff
= _wcsicmp(NewHeader
->lpExeName
, CurrentHeader
->lpExeName
);
83 LastLink
= &CurrentHeader
->Next
;
86 *LastLink
= NewHeader
;
87 NewHeader
->Next
= CurrentHeader
;
91 IntGetAliasEntry(PALIAS_HEADER Header
, LPCWSTR lpSrcName
)
93 PALIAS_ENTRY RootHeader
;
98 RootHeader
= Header
->Data
;
102 DPRINT("IntGetAliasEntry>lpSource %S\n", RootHeader
->lpSource
);
103 diff
= _wcsicmp(RootHeader
->lpSource
, lpSrcName
);
110 RootHeader
= RootHeader
->Next
;
117 IntInsertAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY NewEntry
)
119 PALIAS_ENTRY CurrentEntry
;
120 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
122 while ((CurrentEntry
= *LastLink
) != NULL
)
124 INT Diff
= _wcsicmp(NewEntry
->lpSource
, CurrentEntry
->lpSource
);
129 LastLink
= &CurrentEntry
->Next
;
132 *LastLink
= NewEntry
;
133 NewEntry
->Next
= CurrentEntry
;
137 IntCreateAliasEntry(LPCWSTR lpSource
, LPCWSTR lpTarget
)
143 dwSource
= wcslen(lpSource
) + 1;
144 dwTarget
= wcslen(lpTarget
) + 1;
146 Entry
= RtlAllocateHeap(ConSrvHeap
, 0, sizeof(ALIAS_ENTRY
) + sizeof(WCHAR
) * (dwSource
+ dwTarget
));
150 Entry
->lpSource
= (LPCWSTR
)(Entry
+ 1);
151 wcscpy((LPWSTR
)Entry
->lpSource
, lpSource
);
152 Entry
->lpTarget
= Entry
->lpSource
+ dwSource
;
153 wcscpy((LPWSTR
)Entry
->lpTarget
, lpTarget
);
160 IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader
)
166 length
+= (wcslen(RootHeader
->lpExeName
) + 1) * sizeof(WCHAR
);
167 RootHeader
= RootHeader
->Next
;
170 length
+= sizeof(WCHAR
); // last entry entry is terminated with 2 zero bytes
176 IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader
, LPWSTR TargetBuffer
, UINT TargetBufferSize
)
181 TargetBufferSize
/= sizeof(WCHAR
);
184 Length
= wcslen(RootHeader
->lpExeName
) + 1;
185 if (TargetBufferSize
> Offset
+ Length
)
187 wcscpy(&TargetBuffer
[Offset
], RootHeader
->lpExeName
);
194 RootHeader
= RootHeader
->Next
;
196 Length
= min(Offset
+1, TargetBufferSize
);
197 TargetBuffer
[Length
] = L
'\0';
198 return Length
* sizeof(WCHAR
);
202 IntGetAllConsoleAliasesLength(PALIAS_HEADER Header
)
205 PALIAS_ENTRY CurEntry
= Header
->Data
;
209 Length
+= wcslen(CurEntry
->lpSource
);
210 Length
+= wcslen(CurEntry
->lpTarget
);
211 Length
+= 2; // zero byte and '='
212 CurEntry
= CurEntry
->Next
;
217 return (Length
+1) * sizeof(WCHAR
);
222 IntGetAllConsoleAliases(PALIAS_HEADER Header
, LPWSTR TargetBuffer
, UINT TargetBufferLength
)
224 PALIAS_ENTRY CurEntry
= Header
->Data
;
226 UINT SrcLength
, TargetLength
;
228 TargetBufferLength
/= sizeof(WCHAR
);
231 SrcLength
= wcslen(CurEntry
->lpSource
) + 1;
232 TargetLength
= wcslen(CurEntry
->lpTarget
) + 1;
233 if (Offset
+ TargetLength
+ SrcLength
>= TargetBufferLength
)
236 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpSource
);
238 TargetBuffer
[Offset
] = L
'=';
239 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpTarget
);
240 Offset
+= TargetLength
;
242 CurEntry
= CurEntry
->Next
;
244 TargetBuffer
[Offset
] = L
'\0';
245 return Offset
* sizeof(WCHAR
);
248 IntDeleteAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY Entry
)
250 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
251 PALIAS_ENTRY CurEntry
;
253 while ((CurEntry
= *LastLink
) != NULL
)
255 if (CurEntry
== Entry
)
257 *LastLink
= Entry
->Next
;
258 RtlFreeHeap(ConSrvHeap
, 0, Entry
);
261 LastLink
= &CurEntry
->Next
;
265 IntDeleteAllAliases(PALIAS_HEADER RootHeader
)
267 PALIAS_HEADER Header
, NextHeader
;
268 PALIAS_ENTRY Entry
, NextEntry
;
269 for (Header
= RootHeader
; Header
; Header
= NextHeader
)
271 NextHeader
= Header
->Next
;
272 for (Entry
= Header
->Data
; Entry
; Entry
= NextEntry
)
274 NextEntry
= Entry
->Next
;
275 RtlFreeHeap(ConSrvHeap
, 0, Entry
);
277 RtlFreeHeap(ConSrvHeap
, 0, Header
);
281 CSR_API(SrvAddConsoleAlias
)
283 PCSRSS_ADD_CONSOLE_ALIAS AddConsoleAlias
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.AddConsoleAlias
;
284 PCSRSS_CONSOLE Console
;
285 PALIAS_HEADER Header
;
293 //TotalLength = AddConsoleAlias->SourceLength + AddConsoleAlias->ExeLength + AddConsoleAlias->TargetLength;
294 //Ptr = (WCHAR*)((ULONG_PTR)ApiMessage + sizeof(CSR_API_MESSAGE));
296 lpSource
= (WCHAR
*)((ULONG_PTR
)ApiMessage
+ sizeof(CSR_API_MESSAGE
));
297 lpExeName
= (WCHAR
*)((ULONG_PTR
)ApiMessage
+ sizeof(CSR_API_MESSAGE
) + AddConsoleAlias
->SourceLength
* sizeof(WCHAR
));
298 lpTarget
= (AddConsoleAlias
->TargetLength
!= 0 ? lpExeName
+ AddConsoleAlias
->ExeLength
: NULL
);
300 DPRINT("SrvAddConsoleAlias entered ApiMessage %p lpSource %p lpExeName %p lpTarget %p\n", ApiMessage
, lpSource
, lpExeName
, lpTarget
);
302 if (lpExeName
== NULL
|| lpSource
== NULL
)
304 return STATUS_INVALID_PARAMETER
;
307 ApiMessage
->Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
308 if (!NT_SUCCESS(ApiMessage
->Status
))
310 return ApiMessage
->Status
;
313 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
314 if (!Header
&& lpTarget
!= NULL
)
316 Header
= IntCreateAliasHeader(lpExeName
);
319 ConioUnlockConsole(Console
);
320 return STATUS_INSUFFICIENT_RESOURCES
;
322 IntInsertAliasHeader(&Console
->Aliases
, Header
);
325 if (lpTarget
== NULL
) // delete the entry
327 Entry
= IntGetAliasEntry(Header
, lpSource
);
330 IntDeleteAliasEntry(Header
, Entry
);
331 ApiMessage
->Status
= STATUS_SUCCESS
;
335 ApiMessage
->Status
= STATUS_INVALID_PARAMETER
;
337 ConioUnlockConsole(Console
);
338 return ApiMessage
->Status
;
341 Entry
= IntCreateAliasEntry(lpSource
, lpTarget
);
345 ConioUnlockConsole(Console
);
346 return STATUS_INSUFFICIENT_RESOURCES
;
349 IntInsertAliasEntry(Header
, Entry
);
350 ConioUnlockConsole(Console
);
351 return STATUS_SUCCESS
;
354 CSR_API(SrvGetConsoleAlias
)
356 PCSRSS_GET_CONSOLE_ALIAS GetConsoleAlias
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleAlias
;
357 PCSRSS_CONSOLE Console
;
358 PALIAS_HEADER Header
;
365 lpSource
= (LPWSTR
)((ULONG_PTR
)ApiMessage
+ sizeof(CSR_API_MESSAGE
));
366 lpExeName
= lpSource
+ GetConsoleAlias
->SourceLength
;
367 lpTarget
= GetConsoleAlias
->TargetBuffer
;
370 DPRINT("SrvGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n",
371 lpExeName
, lpSource
, lpTarget
, GetConsoleAlias
->TargetBufferLength
);
373 if (GetConsoleAlias
->ExeLength
== 0 || lpTarget
== NULL
||
374 GetConsoleAlias
->TargetBufferLength
== 0 || GetConsoleAlias
->SourceLength
== 0)
376 return STATUS_INVALID_PARAMETER
;
379 ApiMessage
->Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
380 if (!NT_SUCCESS(ApiMessage
->Status
))
382 return ApiMessage
->Status
;
385 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
388 ConioUnlockConsole(Console
);
389 return STATUS_INVALID_PARAMETER
;
392 Entry
= IntGetAliasEntry(Header
, lpSource
);
395 ConioUnlockConsole(Console
);
396 return STATUS_INVALID_PARAMETER
;
399 Length
= (wcslen(Entry
->lpTarget
)+1) * sizeof(WCHAR
);
400 if (Length
> GetConsoleAlias
->TargetBufferLength
)
402 ConioUnlockConsole(Console
);
403 return STATUS_BUFFER_TOO_SMALL
;
406 if (!Win32CsrValidateBuffer(CsrGetClientThread()->Process
, lpTarget
,
407 GetConsoleAlias
->TargetBufferLength
, 1))
409 ConioUnlockConsole(Console
);
410 return STATUS_ACCESS_VIOLATION
;
413 wcscpy(lpTarget
, Entry
->lpTarget
);
414 GetConsoleAlias
->BytesWritten
= Length
;
415 ConioUnlockConsole(Console
);
416 return STATUS_SUCCESS
;
419 CSR_API(SrvGetConsoleAliases
)
421 PCSRSS_GET_ALL_CONSOLE_ALIASES GetAllConsoleAlias
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetAllConsoleAlias
;
422 PCSRSS_CONSOLE Console
;
424 PALIAS_HEADER Header
;
426 if (GetAllConsoleAlias
->lpExeName
== NULL
)
428 return STATUS_INVALID_PARAMETER
;
431 ApiMessage
->Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
432 if (!NT_SUCCESS(ApiMessage
->Status
))
434 return ApiMessage
->Status
;
437 Header
= IntFindAliasHeader(Console
->Aliases
, GetAllConsoleAlias
->lpExeName
);
440 ConioUnlockConsole(Console
);
441 return STATUS_INVALID_PARAMETER
;
444 if (IntGetAllConsoleAliasesLength(Header
) > GetAllConsoleAlias
->AliasBufferLength
)
446 ConioUnlockConsole(Console
);
447 return STATUS_BUFFER_OVERFLOW
;
450 if (!Win32CsrValidateBuffer(CsrGetClientThread()->Process
,
451 GetAllConsoleAlias
->AliasBuffer
,
452 GetAllConsoleAlias
->AliasBufferLength
,
455 ConioUnlockConsole(Console
);
456 return STATUS_ACCESS_VIOLATION
;
459 BytesWritten
= IntGetAllConsoleAliases(Header
,
460 GetAllConsoleAlias
->AliasBuffer
,
461 GetAllConsoleAlias
->AliasBufferLength
);
463 GetAllConsoleAlias
->BytesWritten
= BytesWritten
;
464 ConioUnlockConsole(Console
);
465 return STATUS_SUCCESS
;
468 CSR_API(SrvGetConsoleAliasesLength
)
470 PCSRSS_GET_ALL_CONSOLE_ALIASES_LENGTH GetAllConsoleAliasesLength
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetAllConsoleAliasesLength
;
471 PCSRSS_CONSOLE Console
;
472 PALIAS_HEADER Header
;
475 if (GetAllConsoleAliasesLength
->lpExeName
== NULL
)
477 return STATUS_INVALID_PARAMETER
;
480 ApiMessage
->Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
481 if (!NT_SUCCESS(ApiMessage
->Status
))
483 return ApiMessage
->Status
;
486 Header
= IntFindAliasHeader(Console
->Aliases
, GetAllConsoleAliasesLength
->lpExeName
);
489 ConioUnlockConsole(Console
);
490 return STATUS_INVALID_PARAMETER
;
493 Length
= IntGetAllConsoleAliasesLength(Header
);
494 GetAllConsoleAliasesLength
->Length
= Length
;
495 ConioUnlockConsole(Console
);
496 return STATUS_SUCCESS
;
499 CSR_API(SrvGetConsoleAliasExes
)
501 PCSRSS_GET_CONSOLE_ALIASES_EXES GetConsoleAliasesExes
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleAliasesExes
;
502 PCSRSS_CONSOLE Console
;
506 DPRINT("SrvGetConsoleAliasExes entered\n");
508 ApiMessage
->Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
509 if (!NT_SUCCESS(ApiMessage
->Status
))
511 return ApiMessage
->Status
;
514 ExesLength
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
516 if (ExesLength
> GetConsoleAliasesExes
->Length
)
518 ConioUnlockConsole(Console
);
519 return STATUS_BUFFER_OVERFLOW
;
522 if (GetConsoleAliasesExes
->ExeNames
== NULL
)
524 ConioUnlockConsole(Console
);
525 return STATUS_INVALID_PARAMETER
;
528 if (!Win32CsrValidateBuffer(CsrGetClientThread()->Process
,
529 GetConsoleAliasesExes
->ExeNames
,
530 GetConsoleAliasesExes
->Length
,
533 ConioUnlockConsole(Console
);
534 return STATUS_ACCESS_VIOLATION
;
537 BytesWritten
= IntGetConsoleAliasesExes(Console
->Aliases
,
538 GetConsoleAliasesExes
->ExeNames
,
539 GetConsoleAliasesExes
->Length
);
541 GetConsoleAliasesExes
->BytesWritten
= BytesWritten
;
542 ConioUnlockConsole(Console
);
543 return STATUS_SUCCESS
;
546 CSR_API(SrvGetConsoleAliasExesLength
)
548 PCSRSS_GET_CONSOLE_ALIASES_EXES_LENGTH GetConsoleAliasesExesLength
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetConsoleAliasesExesLength
;
549 PCSRSS_CONSOLE Console
;
550 DPRINT("SrvGetConsoleAliasExesLength entered\n");
552 ApiMessage
->Status
= ConioConsoleFromProcessData(CsrGetClientThread()->Process
, &Console
);
553 if (NT_SUCCESS(ApiMessage
->Status
))
555 GetConsoleAliasesExesLength
->Length
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
556 ConioUnlockConsole(Console
);
558 return ApiMessage
->Status
;