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
)
110 PALIAS_ENTRY RootHeader
= Header
->Data
;
113 DPRINT("IntGetAliasEntry>lpSource %S\n", RootHeader
->lpSource
);
114 INT diff
= _wcsicmp(RootHeader
->lpSource
, lpSrcName
);
121 RootHeader
= RootHeader
->Next
;
128 IntInsertAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY NewEntry
)
130 PALIAS_ENTRY CurrentEntry
;
131 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
133 while ((CurrentEntry
= *LastLink
) != NULL
)
135 INT Diff
= _wcsicmp(NewEntry
->lpSource
, CurrentEntry
->lpSource
);
140 LastLink
= &CurrentEntry
->Next
;
143 *LastLink
= NewEntry
;
144 NewEntry
->Next
= CurrentEntry
;
148 IntCreateAliasEntry(LPCWSTR lpSource
, LPCWSTR lpTarget
)
154 dwSource
= wcslen(lpSource
) + 1;
155 dwTarget
= wcslen(lpTarget
) + 1;
157 Entry
= RtlAllocateHeap(Win32CsrApiHeap
, 0, sizeof(ALIAS_ENTRY
) + sizeof(WCHAR
) * (dwSource
+ dwTarget
));
161 Entry
->lpSource
= (LPCWSTR
)(Entry
+ 1);
162 wcscpy((LPWSTR
)Entry
->lpSource
, lpSource
);
163 Entry
->lpTarget
= Entry
->lpSource
+ dwSource
;
164 wcscpy((LPWSTR
)Entry
->lpTarget
, lpTarget
);
171 IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader
)
177 length
+= (wcslen(RootHeader
->lpExeName
) + 1) * sizeof(WCHAR
);
178 RootHeader
= RootHeader
->Next
;
181 length
+= sizeof(WCHAR
); // last entry entry is terminated with 2 zero bytes
187 IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader
, LPWSTR TargetBuffer
, UINT TargetBufferSize
)
192 TargetBufferSize
/= sizeof(WCHAR
);
195 Length
= wcslen(RootHeader
->lpExeName
) + 1;
196 if (TargetBufferSize
> Offset
+ Length
)
198 wcscpy(&TargetBuffer
[Offset
], RootHeader
->lpExeName
);
205 RootHeader
= RootHeader
->Next
;
207 Length
= min(Offset
+1, TargetBufferSize
);
208 TargetBuffer
[Length
] = L
'\0';
209 return Length
* sizeof(WCHAR
);
213 IntGetAllConsoleAliasesLength(PALIAS_HEADER Header
)
216 PALIAS_ENTRY CurEntry
= Header
->Data
;
220 Length
+= wcslen(CurEntry
->lpSource
);
221 Length
+= wcslen(CurEntry
->lpTarget
);
222 Length
+= 2; // zero byte and '='
223 CurEntry
= CurEntry
->Next
;
228 return (Length
+1) * sizeof(WCHAR
);
233 IntGetAllConsoleAliases(PALIAS_HEADER Header
, LPWSTR TargetBuffer
, UINT TargetBufferLength
)
235 PALIAS_ENTRY CurEntry
= Header
->Data
;
237 UINT SrcLength
, TargetLength
;
239 TargetBufferLength
/= sizeof(WCHAR
);
242 SrcLength
= wcslen(CurEntry
->lpSource
) + 1;
243 TargetLength
= wcslen(CurEntry
->lpTarget
) + 1;
244 if (Offset
+ TargetLength
+ SrcLength
>= TargetBufferLength
)
247 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpSource
);
249 TargetBuffer
[Offset
] = L
'=';
250 wcscpy(&TargetBuffer
[Offset
], CurEntry
->lpTarget
);
251 Offset
+= TargetLength
;
253 CurEntry
= CurEntry
->Next
;
255 TargetBuffer
[Offset
] = L
'\0';
256 return Offset
* sizeof(WCHAR
);
259 IntDeleteAliasEntry(PALIAS_HEADER Header
, PALIAS_ENTRY Entry
)
261 PALIAS_ENTRY
*LastLink
= &Header
->Data
;
262 PALIAS_ENTRY CurEntry
;
264 while ((CurEntry
= *LastLink
) != NULL
)
266 if (CurEntry
== Entry
)
268 *LastLink
= Entry
->Next
;
269 RtlFreeHeap(Win32CsrApiHeap
, 0, Entry
);
272 LastLink
= &CurEntry
->Next
;
276 IntDeleteAllAliases(PALIAS_HEADER RootHeader
)
278 PALIAS_HEADER Header
, NextHeader
;
279 PALIAS_ENTRY Entry
, NextEntry
;
280 for (Header
= RootHeader
; Header
; Header
= NextHeader
)
282 NextHeader
= Header
->Next
;
283 for (Entry
= Header
->Data
; Entry
; Entry
= NextEntry
)
285 NextEntry
= Entry
->Next
;
286 RtlFreeHeap(Win32CsrApiHeap
, 0, Entry
);
288 RtlFreeHeap(Win32CsrApiHeap
, 0, Header
);
292 CSR_API(CsrAddConsoleAlias
)
294 PCSRSS_CONSOLE Console
;
295 PALIAS_HEADER Header
;
303 TotalLength
= Request
->Data
.AddConsoleAlias
.SourceLength
+ Request
->Data
.AddConsoleAlias
.ExeLength
+ Request
->Data
.AddConsoleAlias
.TargetLength
;
304 Ptr
= (WCHAR
*)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
));
306 lpSource
= (WCHAR
*)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
));
307 lpExeName
= (WCHAR
*)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
) + Request
->Data
.AddConsoleAlias
.SourceLength
* sizeof(WCHAR
));
308 lpTarget
= (Request
->Data
.AddConsoleAlias
.TargetLength
!= 0 ? lpExeName
+ Request
->Data
.AddConsoleAlias
.ExeLength
: NULL
);
310 DPRINT("CsrAddConsoleAlias entered Request %p lpSource %p lpExeName %p lpTarget %p\n", Request
, lpSource
, lpExeName
, lpTarget
);
312 if (lpExeName
== NULL
|| lpSource
== NULL
)
314 return STATUS_INVALID_PARAMETER
;
317 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
318 if (!NT_SUCCESS(Request
->Status
))
320 return Request
->Status
;
323 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
324 if (!Header
&& lpTarget
!= NULL
)
326 Header
= IntCreateAliasHeader(lpExeName
);
329 ConioUnlockConsole(Console
);
330 return STATUS_INSUFFICIENT_RESOURCES
;
332 IntInsertAliasHeader(&Console
->Aliases
, Header
);
335 if (lpTarget
== NULL
) // delete the entry
337 Entry
= IntGetAliasEntry(Header
, lpSource
);
340 IntDeleteAliasEntry(Header
, Entry
);
341 Request
->Status
= STATUS_SUCCESS
;
345 Request
->Status
= STATUS_INVALID_PARAMETER
;
347 ConioUnlockConsole(Console
);
348 return Request
->Status
;
351 Entry
= IntCreateAliasEntry(lpSource
, lpTarget
);
355 ConioUnlockConsole(Console
);
356 return STATUS_INSUFFICIENT_RESOURCES
;
359 IntInsertAliasEntry(Header
, Entry
);
360 ConioUnlockConsole(Console
);
361 return STATUS_SUCCESS
;
364 CSR_API(CsrGetConsoleAlias
)
366 PCSRSS_CONSOLE Console
;
367 PALIAS_HEADER Header
;
374 lpSource
= (LPWSTR
)((ULONG_PTR
)Request
+ sizeof(CSR_API_MESSAGE
));
375 lpExeName
= lpSource
+ Request
->Data
.GetConsoleAlias
.SourceLength
;
376 lpTarget
= Request
->Data
.GetConsoleAlias
.TargetBuffer
;
379 DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n",
380 lpExeName
, lpSource
, lpTarget
, Request
->Data
.GetConsoleAlias
.TargetBufferLength
);
382 if (Request
->Data
.GetConsoleAlias
.ExeLength
== 0 || lpTarget
== NULL
||
383 Request
->Data
.GetConsoleAlias
.TargetBufferLength
== 0 || Request
->Data
.GetConsoleAlias
.SourceLength
== 0)
385 return STATUS_INVALID_PARAMETER
;
388 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
389 if (!NT_SUCCESS(Request
->Status
))
391 return Request
->Status
;
394 Header
= IntFindAliasHeader(Console
->Aliases
, lpExeName
);
397 ConioUnlockConsole(Console
);
398 return STATUS_INVALID_PARAMETER
;
401 Entry
= IntGetAliasEntry(Header
, lpSource
);
404 ConioUnlockConsole(Console
);
405 return STATUS_INVALID_PARAMETER
;
408 Length
= (wcslen(Entry
->lpTarget
)+1) * sizeof(WCHAR
);
409 if (Length
> Request
->Data
.GetConsoleAlias
.TargetBufferLength
)
411 ConioUnlockConsole(Console
);
412 return STATUS_BUFFER_TOO_SMALL
;
415 if (!ValidateBuffer(ProcessData
, lpTarget
, Request
->Data
.GetConsoleAlias
.TargetBufferLength
))
417 ConioUnlockConsole(Console
);
418 return STATUS_ACCESS_VIOLATION
;
421 wcscpy(lpTarget
, Entry
->lpTarget
);
422 Request
->Data
.GetConsoleAlias
.BytesWritten
= Length
;
423 ConioUnlockConsole(Console
);
424 return STATUS_SUCCESS
;
427 CSR_API(CsrGetAllConsoleAliases
)
429 PCSRSS_CONSOLE Console
;
431 PALIAS_HEADER Header
;
433 if (Request
->Data
.GetAllConsoleAlias
.lpExeName
== NULL
)
435 return STATUS_INVALID_PARAMETER
;
438 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
439 if (!NT_SUCCESS(Request
->Status
))
441 return Request
->Status
;
444 Header
= IntFindAliasHeader(Console
->Aliases
, Request
->Data
.GetAllConsoleAlias
.lpExeName
);
447 ConioUnlockConsole(Console
);
448 return STATUS_INVALID_PARAMETER
;
451 if (IntGetAllConsoleAliasesLength(Header
) > Request
->Data
.GetAllConsoleAlias
.AliasBufferLength
)
453 ConioUnlockConsole(Console
);
454 return STATUS_BUFFER_OVERFLOW
;
457 if (!ValidateBuffer(ProcessData
,
458 Request
->Data
.GetAllConsoleAlias
.AliasBuffer
,
459 Request
->Data
.GetAllConsoleAlias
.AliasBufferLength
))
461 ConioUnlockConsole(Console
);
462 return STATUS_ACCESS_VIOLATION
;
465 BytesWritten
= IntGetAllConsoleAliases(Header
,
466 Request
->Data
.GetAllConsoleAlias
.AliasBuffer
,
467 Request
->Data
.GetAllConsoleAlias
.AliasBufferLength
);
469 Request
->Data
.GetAllConsoleAlias
.BytesWritten
= BytesWritten
;
470 ConioUnlockConsole(Console
);
471 return STATUS_SUCCESS
;
474 CSR_API(CsrGetAllConsoleAliasesLength
)
476 PCSRSS_CONSOLE Console
;
477 PALIAS_HEADER Header
;
480 if (Request
->Data
.GetAllConsoleAliasesLength
.lpExeName
== NULL
)
482 return STATUS_INVALID_PARAMETER
;
485 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
486 if (!NT_SUCCESS(Request
->Status
))
488 return Request
->Status
;
491 Header
= IntFindAliasHeader(Console
->Aliases
, Request
->Data
.GetAllConsoleAliasesLength
.lpExeName
);
494 ConioUnlockConsole(Console
);
495 return STATUS_INVALID_PARAMETER
;
498 Length
= IntGetAllConsoleAliasesLength(Header
);
499 Request
->Data
.GetAllConsoleAliasesLength
.Length
= Length
;
500 ConioUnlockConsole(Console
);
501 return STATUS_SUCCESS
;
504 CSR_API(CsrGetConsoleAliasesExes
)
506 PCSRSS_CONSOLE Console
;
510 DPRINT("CsrGetConsoleAliasesExes entered\n");
512 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
513 if (!NT_SUCCESS(Request
->Status
))
515 return Request
->Status
;
518 ExesLength
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
520 if (ExesLength
> Request
->Data
.GetConsoleAliasesExes
.Length
)
522 ConioUnlockConsole(Console
);
523 return STATUS_BUFFER_OVERFLOW
;
526 if (Request
->Data
.GetConsoleAliasesExes
.ExeNames
== NULL
)
528 ConioUnlockConsole(Console
);
529 return STATUS_INVALID_PARAMETER
;
532 if (!ValidateBuffer(ProcessData
,
533 Request
->Data
.GetConsoleAliasesExes
.ExeNames
,
534 Request
->Data
.GetConsoleAliasesExes
.Length
))
536 ConioUnlockConsole(Console
);
537 return STATUS_ACCESS_VIOLATION
;
540 BytesWritten
= IntGetConsoleAliasesExes(Console
->Aliases
,
541 Request
->Data
.GetConsoleAliasesExes
.ExeNames
,
542 Request
->Data
.GetConsoleAliasesExes
.Length
);
544 Request
->Data
.GetConsoleAliasesExes
.BytesWritten
= BytesWritten
;
545 ConioUnlockConsole(Console
);
546 return STATUS_SUCCESS
;
549 CSR_API(CsrGetConsoleAliasesExesLength
)
551 PCSRSS_CONSOLE Console
;
552 DPRINT("CsrGetConsoleAliasesExesLength entered\n");
554 Request
->Status
= ConioConsoleFromProcessData(ProcessData
, &Console
);
555 if (NT_SUCCESS(Request
->Status
))
557 Request
->Data
.GetConsoleAliasesExesLength
.Length
= IntGetConsoleAliasesExesLength(Console
->Aliases
);
558 ConioUnlockConsole(Console
);
560 return Request
->Status
;