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 /* TYPES **********************************************************************/
21 typedef struct _ALIAS_ENTRY
25 struct _ALIAS_ENTRY
* Next
;
26 } ALIAS_ENTRY
, *PALIAS_ENTRY
;
28 typedef struct _ALIAS_HEADER
32 struct _ALIAS_HEADER
* Next
;
33 } ALIAS_HEADER
, *PALIAS_HEADER
;
36 /* PRIVATE FUNCTIONS **********************************************************/
40 IntFindAliasHeader(PALIAS_HEADER RootHeader
, LPCWSTR lpExeName
)
44 INT diff
= _wcsicmp(RootHeader
->lpExeName
, lpExeName
);
51 RootHeader
= RootHeader
->Next
;
57 IntCreateAliasHeader(LPCWSTR lpExeName
)
60 UINT dwLength
= wcslen(lpExeName
) + 1;
62 Entry
= RtlAllocateHeap(ConSrvHeap
, 0, sizeof(ALIAS_HEADER
) + sizeof(WCHAR
) * dwLength
);
66 Entry
->lpExeName
= (LPCWSTR
)(Entry
+ 1);
67 wcscpy((WCHAR
*)Entry
->lpExeName
, lpExeName
);
74 IntInsertAliasHeader(PALIAS_HEADER
* RootHeader
, PALIAS_HEADER NewHeader
)
76 PALIAS_HEADER CurrentHeader
;
77 PALIAS_HEADER
*LastLink
= RootHeader
;
79 while ((CurrentHeader
= *LastLink
) != NULL
)
81 INT Diff
= _wcsicmp(NewHeader
->lpExeName
, CurrentHeader
->lpExeName
);
86 LastLink
= &CurrentHeader
->Next
;
89 *LastLink
= NewHeader
;
90 NewHeader
->Next
= CurrentHeader
;
94 IntGetAliasEntry(PALIAS_HEADER Header
, LPCWSTR lpSrcName
)
96 PALIAS_ENTRY RootHeader
;
101 RootHeader
= Header
->Data
;
105 DPRINT("IntGetAliasEntry->lpSource %S\n", RootHeader
->lpSource
);
106 diff
= _wcsicmp(RootHeader
->lpSource
, lpSrcName
);
113 RootHeader
= RootHeader
->Next
;
119 IntInsertAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY NewEntry
)
121 PALIAS_ENTRY CurrentEntry
;
122 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
124 while ((CurrentEntry
= *LastLink
) != NULL
)
126 INT Diff
= _wcsicmp(NewEntry
->lpSource
, CurrentEntry
->lpSource
);
131 LastLink
= &CurrentEntry
->Next
;
134 *LastLink
= NewEntry
;
135 NewEntry
->Next
= CurrentEntry
;
139 IntCreateAliasEntry(LPCWSTR lpSource
, LPCWSTR lpTarget
)
145 dwSource
= wcslen(lpSource
) + 1;
146 dwTarget
= wcslen(lpTarget
) + 1;
148 Entry
= RtlAllocateHeap(ConSrvHeap
, 0, sizeof(ALIAS_ENTRY
) + sizeof(WCHAR
) * (dwSource
+ dwTarget
));
152 Entry
->lpSource
= (LPCWSTR
)(Entry
+ 1);
153 wcscpy((LPWSTR
)Entry
->lpSource
, lpSource
);
154 Entry
->lpTarget
= Entry
->lpSource
+ dwSource
;
155 wcscpy((LPWSTR
)Entry
->lpTarget
, lpTarget
);
162 IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader
)
168 length
+= (wcslen(RootHeader
->lpExeName
) + 1) * sizeof(WCHAR
);
169 RootHeader
= RootHeader
->Next
;
172 length
+= sizeof(WCHAR
); // last entry entry is terminated with 2 zero bytes
178 IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader
, LPWSTR TargetBuffer
, UINT TargetBufferSize
)
183 TargetBufferSize
/= sizeof(WCHAR
);
186 Length
= wcslen(RootHeader
->lpExeName
) + 1;
187 if (TargetBufferSize
> Offset
+ Length
)
189 wcscpy(&TargetBuffer
[Offset
], RootHeader
->lpExeName
);
196 RootHeader
= RootHeader
->Next
;
198 Length
= min(Offset
+1, TargetBufferSize
);
199 TargetBuffer
[Length
] = L
'\0';
200 return Length
* sizeof(WCHAR
);
204 IntGetAllConsoleAliasesLength(PALIAS_HEADER Header
)
207 PALIAS_ENTRY CurEntry
= Header
->Data
;
211 Length
+= wcslen(CurEntry
->lpSource
);
212 Length
+= wcslen(CurEntry
->lpTarget
);
213 Length
+= 2; // zero byte and '='
214 CurEntry
= CurEntry
->Next
;
219 return (Length
+1) * sizeof(WCHAR
);
225 IntGetAllConsoleAliases(PALIAS_HEADER Header
, LPWSTR TargetBuffer
, UINT TargetBufferLength
)
227 PALIAS_ENTRY CurEntry
= Header
->Data
;
229 UINT SrcLength
, TargetLength
;
231 TargetBufferLength
/= sizeof(WCHAR
);
234 SrcLength
= wcslen(CurEntry
->lpSource
) + 1;
235 TargetLength
= wcslen(CurEntry
->lpTarget
) + 1;
236 if (Offset
+ TargetLength
+ SrcLength
>= TargetBufferLength
)
239 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpSource
);
241 TargetBuffer
[Offset
] = L
'=';
242 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpTarget
);
243 Offset
+= TargetLength
;
245 CurEntry
= CurEntry
->Next
;
247 TargetBuffer
[Offset
] = L
'\0';
248 return Offset
* sizeof(WCHAR
);
252 IntDeleteAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY Entry
)
254 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
255 PALIAS_ENTRY CurEntry
;
257 while ((CurEntry
= *LastLink
) != NULL
)
259 if (CurEntry
== Entry
)
261 *LastLink
= Entry
->Next
;
262 RtlFreeHeap(ConSrvHeap
, 0, Entry
);
265 LastLink
= &CurEntry
->Next
;
270 IntDeleteAllAliases(PALIAS_HEADER RootHeader
)
272 PALIAS_HEADER Header
, NextHeader
;
273 PALIAS_ENTRY Entry
, NextEntry
;
275 for (Header
= RootHeader
; Header
; Header
= NextHeader
)
277 NextHeader
= Header
->Next
;
278 for (Entry
= Header
->Data
; Entry
; Entry
= NextEntry
)
280 NextEntry
= Entry
->Next
;
281 RtlFreeHeap(ConSrvHeap
, 0, Entry
);
283 RtlFreeHeap(ConSrvHeap
, 0, Header
);
288 /* PUBLIC SERVER APIS *********************************************************/
290 CSR_API(SrvAddConsoleAlias
)
292 PCONSOLE_ADDGETALIAS ConsoleAliasRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleAliasRequest
;
294 PALIAS_HEADER Header
;
296 LPWSTR lpSource
, lpTarget
, lpExeName
;
298 DPRINT("SrvAddConsoleAlias entered ApiMessage %p\n", ApiMessage
);
300 if ( !CsrValidateMessageBuffer(ApiMessage
,
301 (PVOID
*)&ConsoleAliasRequest
->Source
,
302 ConsoleAliasRequest
->SourceLength
,
304 !CsrValidateMessageBuffer(ApiMessage
,
305 (PVOID
*)&ConsoleAliasRequest
->Target
,
306 ConsoleAliasRequest
->TargetLength
,
308 !CsrValidateMessageBuffer(ApiMessage
,
309 (PVOID
*)&ConsoleAliasRequest
->Exe
,
310 ConsoleAliasRequest
->ExeLength
,
313 return STATUS_INVALID_PARAMETER
;
316 lpSource
= ConsoleAliasRequest
->Source
;
317 lpTarget
= (ConsoleAliasRequest
->TargetLength
!= 0 ? ConsoleAliasRequest
->Target
: NULL
);
318 lpExeName
= ConsoleAliasRequest
->Exe
;
320 DPRINT("SrvAddConsoleAlias lpSource %p lpExeName %p lpTarget %p\n", lpSource
, lpExeName
, lpTarget
);
322 if (lpExeName
== NULL
|| lpSource
== NULL
)
324 return STATUS_INVALID_PARAMETER
;
327 ApiMessage
->Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
328 if (!NT_SUCCESS(ApiMessage
->Status
))
330 return ApiMessage
->Status
;
333 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
334 if (!Header
&& lpTarget
!= NULL
)
336 Header
= IntCreateAliasHeader(lpExeName
);
339 ConioUnlockConsole(Console
);
340 return STATUS_INSUFFICIENT_RESOURCES
;
342 IntInsertAliasHeader(&Console
->Aliases
, Header
);
345 if (lpTarget
== NULL
) // Delete the entry
347 Entry
= IntGetAliasEntry(Header
, lpSource
);
350 IntDeleteAliasEntry(Header
, Entry
);
351 ApiMessage
->Status
= STATUS_SUCCESS
;
355 ApiMessage
->Status
= STATUS_INVALID_PARAMETER
;
357 ConioUnlockConsole(Console
);
358 return ApiMessage
->Status
;
361 Entry
= IntCreateAliasEntry(lpSource
, lpTarget
);
365 ConioUnlockConsole(Console
);
366 return STATUS_INSUFFICIENT_RESOURCES
;
369 IntInsertAliasEntry(Header
, Entry
);
370 ConioUnlockConsole(Console
);
371 return STATUS_SUCCESS
;
374 CSR_API(SrvGetConsoleAlias
)
376 PCONSOLE_ADDGETALIAS ConsoleAliasRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.ConsoleAliasRequest
;
378 PALIAS_HEADER Header
;
381 LPWSTR lpSource
, lpTarget
, lpExeName
;
383 DPRINT("SrvGetConsoleAlias entered ApiMessage %p\n", ApiMessage
);
385 if ( !CsrValidateMessageBuffer(ApiMessage
,
386 (PVOID
*)&ConsoleAliasRequest
->Source
,
387 ConsoleAliasRequest
->SourceLength
,
389 !CsrValidateMessageBuffer(ApiMessage
,
390 (PVOID
*)&ConsoleAliasRequest
->Target
,
391 ConsoleAliasRequest
->TargetLength
,
393 !CsrValidateMessageBuffer(ApiMessage
,
394 (PVOID
*)&ConsoleAliasRequest
->Exe
,
395 ConsoleAliasRequest
->ExeLength
,
398 return STATUS_INVALID_PARAMETER
;
401 lpSource
= ConsoleAliasRequest
->Source
;
402 lpTarget
= ConsoleAliasRequest
->Target
;
403 lpExeName
= ConsoleAliasRequest
->Exe
;
405 DPRINT("SrvGetConsoleAlias lpExeName %p lpSource %p TargetBuffer %p TargetLength %u\n",
406 lpExeName
, lpSource
, lpTarget
, ConsoleAliasRequest
->TargetLength
);
408 if (ConsoleAliasRequest
->ExeLength
== 0 || lpTarget
== NULL
||
409 ConsoleAliasRequest
->TargetLength
== 0 || ConsoleAliasRequest
->SourceLength
== 0)
411 return STATUS_INVALID_PARAMETER
;
414 ApiMessage
->Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
415 if (!NT_SUCCESS(ApiMessage
->Status
))
417 return ApiMessage
->Status
;
420 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
423 ConioUnlockConsole(Console
);
424 return STATUS_INVALID_PARAMETER
;
427 Entry
= IntGetAliasEntry(Header
, lpSource
);
430 ConioUnlockConsole(Console
);
431 return STATUS_INVALID_PARAMETER
;
434 Length
= (wcslen(Entry
->lpTarget
) + 1) * sizeof(WCHAR
);
435 if (Length
> ConsoleAliasRequest
->TargetLength
)
437 ConioUnlockConsole(Console
);
438 return STATUS_BUFFER_TOO_SMALL
;
441 wcscpy(lpTarget
, Entry
->lpTarget
);
442 ConsoleAliasRequest
->TargetLength
= Length
;
443 ConioUnlockConsole(Console
);
444 return STATUS_SUCCESS
;
447 CSR_API(SrvGetConsoleAliases
)
449 PCONSOLE_GETALLALIASES GetAllAliasesRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetAllAliasesRequest
;
452 PALIAS_HEADER Header
;
454 if ( !CsrValidateMessageBuffer(ApiMessage
,
455 (PVOID
)&GetAllAliasesRequest
->ExeName
,
456 GetAllAliasesRequest
->ExeLength
,
458 !CsrValidateMessageBuffer(ApiMessage
,
459 (PVOID
)&GetAllAliasesRequest
->AliasesBuffer
,
460 GetAllAliasesRequest
->AliasesBufferLength
,
463 return STATUS_INVALID_PARAMETER
;
466 if (GetAllAliasesRequest
->ExeName
== NULL
)
468 return STATUS_INVALID_PARAMETER
;
471 ApiMessage
->Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
472 if (!NT_SUCCESS(ApiMessage
->Status
))
474 return ApiMessage
->Status
;
477 Header
= IntFindAliasHeader(Console
->Aliases
, GetAllAliasesRequest
->ExeName
);
480 ConioUnlockConsole(Console
);
481 return STATUS_INVALID_PARAMETER
;
484 if (IntGetAllConsoleAliasesLength(Header
) > GetAllAliasesRequest
->AliasesBufferLength
)
486 ConioUnlockConsole(Console
);
487 return STATUS_BUFFER_OVERFLOW
;
490 BytesWritten
= IntGetAllConsoleAliases(Header
,
491 GetAllAliasesRequest
->AliasesBuffer
,
492 GetAllAliasesRequest
->AliasesBufferLength
);
494 GetAllAliasesRequest
->AliasesBufferLength
= BytesWritten
;
495 ConioUnlockConsole(Console
);
496 return STATUS_SUCCESS
;
499 CSR_API(SrvGetConsoleAliasesLength
)
501 PCONSOLE_GETALLALIASESLENGTH GetAllAliasesLengthRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetAllAliasesLengthRequest
;
503 PALIAS_HEADER Header
;
506 if (!CsrValidateMessageBuffer(ApiMessage
,
507 (PVOID
)&GetAllAliasesLengthRequest
->ExeName
,
508 GetAllAliasesLengthRequest
->ExeLength
,
511 return STATUS_INVALID_PARAMETER
;
514 if (GetAllAliasesLengthRequest
->ExeName
== NULL
)
516 return STATUS_INVALID_PARAMETER
;
519 ApiMessage
->Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
520 if (!NT_SUCCESS(ApiMessage
->Status
))
522 return ApiMessage
->Status
;
525 Header
= IntFindAliasHeader(Console
->Aliases
, GetAllAliasesLengthRequest
->ExeName
);
528 ConioUnlockConsole(Console
);
529 return STATUS_INVALID_PARAMETER
;
532 Length
= IntGetAllConsoleAliasesLength(Header
);
533 GetAllAliasesLengthRequest
->Length
= Length
;
534 ConioUnlockConsole(Console
);
535 return STATUS_SUCCESS
;
538 CSR_API(SrvGetConsoleAliasExes
)
540 PCONSOLE_GETALIASESEXES GetAliasesExesRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetAliasesExesRequest
;
545 DPRINT("SrvGetConsoleAliasExes entered\n");
547 if (!CsrValidateMessageBuffer(ApiMessage
,
548 (PVOID
)&GetAliasesExesRequest
->ExeNames
,
549 GetAliasesExesRequest
->Length
,
552 return STATUS_INVALID_PARAMETER
;
555 ApiMessage
->Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
556 if (!NT_SUCCESS(ApiMessage
->Status
))
558 return ApiMessage
->Status
;
561 ExesLength
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
563 if (ExesLength
> GetAliasesExesRequest
->Length
)
565 ConioUnlockConsole(Console
);
566 return STATUS_BUFFER_OVERFLOW
;
569 if (GetAliasesExesRequest
->ExeNames
== NULL
)
571 ConioUnlockConsole(Console
);
572 return STATUS_INVALID_PARAMETER
;
575 BytesWritten
= IntGetConsoleAliasesExes(Console
->Aliases
,
576 GetAliasesExesRequest
->ExeNames
,
577 GetAliasesExesRequest
->Length
);
579 GetAliasesExesRequest
->Length
= BytesWritten
;
580 ConioUnlockConsole(Console
);
581 return STATUS_SUCCESS
;
584 CSR_API(SrvGetConsoleAliasExesLength
)
586 PCONSOLE_GETALIASESEXESLENGTH GetAliasesExesLengthRequest
= &((PCONSOLE_API_MESSAGE
)ApiMessage
)->Data
.GetAliasesExesLengthRequest
;
588 DPRINT("SrvGetConsoleAliasExesLength entered\n");
590 ApiMessage
->Status
= ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process
), &Console
);
591 if (NT_SUCCESS(ApiMessage
->Status
))
593 GetAliasesExesLengthRequest
->Length
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
594 ConioUnlockConsole(Console
);
596 return ApiMessage
->Status
;