1 /* $Id: init.c 31400 2007-12-22 17:18:32Z fireball $
2 * PROJECT: ReactOS CSRSS
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: subsystems/win32/csrss/api/alias.c
5 * PURPOSE: CSRSS alias support functions
6 * COPYRIGHT: Christoph Wittich
12 /* INCLUDES ******************************************************************/
18 typedef struct tagALIAS_ENTRY
22 struct tagALIAS_ENTRY
* Next
;
23 } ALIAS_ENTRY
, *PALIAS_ENTRY
;
26 typedef struct tagALIAS_HEADER
30 struct tagALIAS_HEADER
* Next
;
32 } ALIAS_HEADER
, *PALIAS_HEADER
;
34 /* Ensure that a buffer is contained within the process's shared memory section. */
36 ValidateBuffer(PCSRSS_PROCESS_DATA ProcessData
, PVOID Buffer
, ULONG Size
)
38 ULONG Offset
= (BYTE
*)Buffer
- (BYTE
*)ProcessData
->CsrSectionViewBase
;
39 if (Offset
>= ProcessData
->CsrSectionViewSize
40 || Size
> (ProcessData
->CsrSectionViewSize
- Offset
))
42 DPRINT1("Invalid buffer %p %d; not within %p %d\n",
43 Buffer
, Size
, ProcessData
->CsrSectionViewBase
, ProcessData
->CsrSectionViewSize
);
51 IntFindAliasHeader(PALIAS_HEADER RootHeader
, LPCWSTR lpExeName
)
55 INT diff
= _wcsicmp(RootHeader
->lpExeName
, lpExeName
);
62 RootHeader
= RootHeader
->Next
;
68 IntCreateAliasHeader(LPCWSTR lpExeName
)
71 UINT dwLength
= wcslen(lpExeName
) + 1;
73 Entry
= RtlAllocateHeap(Win32CsrApiHeap
, 0, sizeof(ALIAS_HEADER
) + sizeof(WCHAR
) * dwLength
);
77 Entry
->lpExeName
= (LPCWSTR
)(Entry
+ 1);
78 wcscpy((WCHAR
*)Entry
->lpExeName
, lpExeName
);
85 IntInsertAliasHeader(PALIAS_HEADER
* RootHeader
, PALIAS_HEADER NewHeader
)
87 PALIAS_HEADER CurrentHeader
;
88 PALIAS_HEADER
*LastLink
= RootHeader
;
90 while ((CurrentHeader
= *LastLink
) != NULL
)
92 INT Diff
= _wcsicmp(NewHeader
->lpExeName
, CurrentHeader
->lpExeName
);
97 LastLink
= &CurrentHeader
->Next
;
100 *LastLink
= NewHeader
;
101 NewHeader
->Next
= CurrentHeader
;
105 IntGetAliasEntry(PALIAS_HEADER Header
, LPCWSTR lpSrcName
)
107 PALIAS_ENTRY RootHeader
;
112 RootHeader
= Header
->Data
;
116 DPRINT("IntGetAliasEntry>lpSource %S\n", RootHeader
->lpSource
);
117 diff
= _wcsicmp(RootHeader
->lpSource
, lpSrcName
);
124 RootHeader
= RootHeader
->Next
;
131 IntInsertAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY NewEntry
)
133 PALIAS_ENTRY CurrentEntry
;
134 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
136 while ((CurrentEntry
= *LastLink
) != NULL
)
138 INT Diff
= _wcsicmp(NewEntry
->lpSource
, CurrentEntry
->lpSource
);
143 LastLink
= &CurrentEntry
->Next
;
146 *LastLink
= NewEntry
;
147 NewEntry
->Next
= CurrentEntry
;
151 IntCreateAliasEntry(LPCWSTR lpSource
, LPCWSTR lpTarget
)
157 dwSource
= wcslen(lpSource
) + 1;
158 dwTarget
= wcslen(lpTarget
) + 1;
160 Entry
= RtlAllocateHeap(Win32CsrApiHeap
, 0, sizeof(ALIAS_ENTRY
) + sizeof(WCHAR
) * (dwSource
+ dwTarget
));
164 Entry
->lpSource
= (LPCWSTR
)(Entry
+ 1);
165 wcscpy((LPWSTR
)Entry
->lpSource
, lpSource
);
166 Entry
->lpTarget
= Entry
->lpSource
+ dwSource
;
167 wcscpy((LPWSTR
)Entry
->lpTarget
, lpTarget
);
174 IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader
)
180 length
+= (wcslen(RootHeader
->lpExeName
) + 1) * sizeof(WCHAR
);
181 RootHeader
= RootHeader
->Next
;
184 length
+= sizeof(WCHAR
); // last entry entry is terminated with 2 zero bytes
190 IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader
, LPWSTR TargetBuffer
, UINT TargetBufferSize
)
195 TargetBufferSize
/= sizeof(WCHAR
);
198 Length
= wcslen(RootHeader
->lpExeName
) + 1;
199 if (TargetBufferSize
> Offset
+ Length
)
201 wcscpy(&TargetBuffer
[Offset
], RootHeader
->lpExeName
);
208 RootHeader
= RootHeader
->Next
;
210 Length
= min(Offset
+1, TargetBufferSize
);
211 TargetBuffer
[Length
] = L
'\0';
212 return Length
* sizeof(WCHAR
);
216 IntGetAllConsoleAliasesLength(PALIAS_HEADER Header
)
219 PALIAS_ENTRY CurEntry
= Header
->Data
;
223 Length
+= wcslen(CurEntry
->lpSource
);
224 Length
+= wcslen(CurEntry
->lpTarget
);
225 Length
+= 2; // zero byte and '='
226 CurEntry
= CurEntry
->Next
;
231 return (Length
+1) * sizeof(WCHAR
);
236 IntGetAllConsoleAliases(PALIAS_HEADER Header
, LPWSTR TargetBuffer
, UINT TargetBufferLength
)
238 PALIAS_ENTRY CurEntry
= Header
->Data
;
240 UINT SrcLength
, TargetLength
;
242 TargetBufferLength
/= sizeof(WCHAR
);
245 SrcLength
= wcslen(CurEntry
->lpSource
) + 1;
246 TargetLength
= wcslen(CurEntry
->lpTarget
) + 1;
247 if (Offset
+ TargetLength
+ SrcLength
>= TargetBufferLength
)
250 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpSource
);
252 TargetBuffer
[Offset
] = L
'=';
253 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpTarget
);
254 Offset
+= TargetLength
;
256 CurEntry
= CurEntry
->Next
;
258 TargetBuffer
[Offset
] = L
'\0';
259 return Offset
* sizeof(WCHAR
);
262 IntDeleteAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY Entry
)
264 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
265 PALIAS_ENTRY CurEntry
;
267 while ((CurEntry
= *LastLink
) != NULL
)
269 if (CurEntry
== Entry
)
271 *LastLink
= Entry
->Next
;
272 RtlFreeHeap(Win32CsrApiHeap
, 0, Entry
);
275 LastLink
= &CurEntry
->Next
;
279 IntDeleteAllAliases(PALIAS_HEADER RootHeader
)
281 PALIAS_HEADER Header
, NextHeader
;
282 PALIAS_ENTRY Entry
, NextEntry
;
283 for (Header
= RootHeader
; Header
; Header
= NextHeader
)
285 NextHeader
= Header
->Next
;
286 for (Entry
= Header
->Data
; Entry
; Entry
= NextEntry
)
288 NextEntry
= Entry
->Next
;
289 RtlFreeHeap(Win32CsrApiHeap
, 0, Entry
);
291 RtlFreeHeap(Win32CsrApiHeap
, 0, Header
);
295 CSR_API(CsrAddConsoleAlias
)
297 PCSRSS_CONSOLE Console
;
298 PALIAS_HEADER Header
;
306 TotalLength
= Request
->Data
.AddConsoleAlias
.SourceLength
+ Request
->Data
.AddConsoleAlias
.ExeLength
+ Request
->Data
.AddConsoleAlias
.TargetLength
;
307 Ptr
= (WCHAR
*)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
));
309 lpSource
= (WCHAR
*)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
));
310 lpExeName
= (WCHAR
*)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
) + Request
->Data
.AddConsoleAlias
.SourceLength
* sizeof(WCHAR
));
311 lpTarget
= (Request
->Data
.AddConsoleAlias
.TargetLength
!= 0 ? lpExeName
+ Request
->Data
.AddConsoleAlias
.ExeLength
: NULL
);
313 DPRINT("CsrAddConsoleAlias entered Request %p lpSource %p lpExeName %p lpTarget %p\n", Request
, lpSource
, lpExeName
, lpTarget
);
315 if (lpExeName
== NULL
|| lpSource
== NULL
)
317 return STATUS_INVALID_PARAMETER
;
320 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
321 if (!NT_SUCCESS(Request
->Status
))
323 return Request
->Status
;
326 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
327 if (!Header
&& lpTarget
!= NULL
)
329 Header
= IntCreateAliasHeader(lpExeName
);
332 ConioUnlockConsole(Console
);
333 return STATUS_INSUFFICIENT_RESOURCES
;
335 IntInsertAliasHeader(&Console
->Aliases
, Header
);
338 if (lpTarget
== NULL
) // delete the entry
340 Entry
= IntGetAliasEntry(Header
, lpSource
);
343 IntDeleteAliasEntry(Header
, Entry
);
344 Request
->Status
= STATUS_SUCCESS
;
348 Request
->Status
= STATUS_INVALID_PARAMETER
;
350 ConioUnlockConsole(Console
);
351 return Request
->Status
;
354 Entry
= IntCreateAliasEntry(lpSource
, lpTarget
);
358 ConioUnlockConsole(Console
);
359 return STATUS_INSUFFICIENT_RESOURCES
;
362 IntInsertAliasEntry(Header
, Entry
);
363 ConioUnlockConsole(Console
);
364 return STATUS_SUCCESS
;
367 CSR_API(CsrGetConsoleAlias
)
369 PCSRSS_CONSOLE Console
;
370 PALIAS_HEADER Header
;
377 lpSource
= (LPWSTR
)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
));
378 lpExeName
= lpSource
+ Request
->Data
.GetConsoleAlias
.SourceLength
;
379 lpTarget
= Request
->Data
.GetConsoleAlias
.TargetBuffer
;
382 DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n",
383 lpExeName
, lpSource
, lpTarget
, Request
->Data
.GetConsoleAlias
.TargetBufferLength
);
385 if (Request
->Data
.GetConsoleAlias
.ExeLength
== 0 || lpTarget
== NULL
||
386 Request
->Data
.GetConsoleAlias
.TargetBufferLength
== 0 || Request
->Data
.GetConsoleAlias
.SourceLength
== 0)
388 return STATUS_INVALID_PARAMETER
;
391 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
392 if (!NT_SUCCESS(Request
->Status
))
394 return Request
->Status
;
397 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
400 ConioUnlockConsole(Console
);
401 return STATUS_INVALID_PARAMETER
;
404 Entry
= IntGetAliasEntry(Header
, lpSource
);
407 ConioUnlockConsole(Console
);
408 return STATUS_INVALID_PARAMETER
;
411 Length
= (wcslen(Entry
->lpTarget
)+1) * sizeof(WCHAR
);
412 if (Length
> Request
->Data
.GetConsoleAlias
.TargetBufferLength
)
414 ConioUnlockConsole(Console
);
415 return STATUS_BUFFER_TOO_SMALL
;
418 if (!ValidateBuffer(ProcessData
, lpTarget
, Request
->Data
.GetConsoleAlias
.TargetBufferLength
))
420 ConioUnlockConsole(Console
);
421 return STATUS_ACCESS_VIOLATION
;
424 wcscpy(lpTarget
, Entry
->lpTarget
);
425 Request
->Data
.GetConsoleAlias
.BytesWritten
= Length
;
426 ConioUnlockConsole(Console
);
427 return STATUS_SUCCESS
;
430 CSR_API(CsrGetAllConsoleAliases
)
432 PCSRSS_CONSOLE Console
;
434 PALIAS_HEADER Header
;
436 if (Request
->Data
.GetAllConsoleAlias
.lpExeName
== NULL
)
438 return STATUS_INVALID_PARAMETER
;
441 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
442 if (!NT_SUCCESS(Request
->Status
))
444 return Request
->Status
;
447 Header
= IntFindAliasHeader(Console
->Aliases
, Request
->Data
.GetAllConsoleAlias
.lpExeName
);
450 ConioUnlockConsole(Console
);
451 return STATUS_INVALID_PARAMETER
;
454 if (IntGetAllConsoleAliasesLength(Header
) > Request
->Data
.GetAllConsoleAlias
.AliasBufferLength
)
456 ConioUnlockConsole(Console
);
457 return STATUS_BUFFER_OVERFLOW
;
460 if (!ValidateBuffer(ProcessData
,
461 Request
->Data
.GetAllConsoleAlias
.AliasBuffer
,
462 Request
->Data
.GetAllConsoleAlias
.AliasBufferLength
))
464 ConioUnlockConsole(Console
);
465 return STATUS_ACCESS_VIOLATION
;
468 BytesWritten
= IntGetAllConsoleAliases(Header
,
469 Request
->Data
.GetAllConsoleAlias
.AliasBuffer
,
470 Request
->Data
.GetAllConsoleAlias
.AliasBufferLength
);
472 Request
->Data
.GetAllConsoleAlias
.BytesWritten
= BytesWritten
;
473 ConioUnlockConsole(Console
);
474 return STATUS_SUCCESS
;
477 CSR_API(CsrGetAllConsoleAliasesLength
)
479 PCSRSS_CONSOLE Console
;
480 PALIAS_HEADER Header
;
483 if (Request
->Data
.GetAllConsoleAliasesLength
.lpExeName
== NULL
)
485 return STATUS_INVALID_PARAMETER
;
488 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
489 if (!NT_SUCCESS(Request
->Status
))
491 return Request
->Status
;
494 Header
= IntFindAliasHeader(Console
->Aliases
, Request
->Data
.GetAllConsoleAliasesLength
.lpExeName
);
497 ConioUnlockConsole(Console
);
498 return STATUS_INVALID_PARAMETER
;
501 Length
= IntGetAllConsoleAliasesLength(Header
);
502 Request
->Data
.GetAllConsoleAliasesLength
.Length
= Length
;
503 ConioUnlockConsole(Console
);
504 return STATUS_SUCCESS
;
507 CSR_API(CsrGetConsoleAliasesExes
)
509 PCSRSS_CONSOLE Console
;
513 DPRINT("CsrGetConsoleAliasesExes entered\n");
515 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
516 if (!NT_SUCCESS(Request
->Status
))
518 return Request
->Status
;
521 ExesLength
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
523 if (ExesLength
> Request
->Data
.GetConsoleAliasesExes
.Length
)
525 ConioUnlockConsole(Console
);
526 return STATUS_BUFFER_OVERFLOW
;
529 if (Request
->Data
.GetConsoleAliasesExes
.ExeNames
== NULL
)
531 ConioUnlockConsole(Console
);
532 return STATUS_INVALID_PARAMETER
;
535 if (!ValidateBuffer(ProcessData
,
536 Request
->Data
.GetConsoleAliasesExes
.ExeNames
,
537 Request
->Data
.GetConsoleAliasesExes
.Length
))
539 ConioUnlockConsole(Console
);
540 return STATUS_ACCESS_VIOLATION
;
543 BytesWritten
= IntGetConsoleAliasesExes(Console
->Aliases
,
544 Request
->Data
.GetConsoleAliasesExes
.ExeNames
,
545 Request
->Data
.GetConsoleAliasesExes
.Length
);
547 Request
->Data
.GetConsoleAliasesExes
.BytesWritten
= BytesWritten
;
548 ConioUnlockConsole(Console
);
549 return STATUS_SUCCESS
;
552 CSR_API(CsrGetConsoleAliasesExesLength
)
554 PCSRSS_CONSOLE Console
;
555 DPRINT("CsrGetConsoleAliasesExesLength entered\n");
557 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
558 if (NT_SUCCESS(Request
->Status
))
560 Request
->Data
.GetConsoleAliasesExesLength
.Length
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
561 ConioUnlockConsole(Console
);
563 return Request
->Status
;