diff --git a/reactos/subsystems/win32/csrss/api/alias.c b/reactos/subsystems/win32/csrss/api/alias.c new file mode 100644 index 00000000000..e4002c4d05d --- /dev/null +++ b/reactos/subsystems/win32/csrss/api/alias.c @@ -0,0 +1,475 @@ +/* $Id: init.c 31400 2007-12-22 17:18:32Z fireball $ + * PROJECT: ReactOS CSRSS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: subsystems/win32/csrss/api/alias.c + * PURPOSE: CSRSS alias support functions + * COPYRIGHT: Christoph Wittich + * Johannes Anderwald + * + */ + + +/* INCLUDES ******************************************************************/ + +#include + +#define NDEBUG +#include + +typedef struct tagALIAS_ENTRY +{ + LPCWSTR lpSource; + LPCWSTR lpTarget; + struct tagALIAS_ENTRY * Next; +}ALIAS_ENTRY, *PALIAS_ENTRY; + + +typedef struct tagALIAS_HEADER +{ + LPCWSTR lpExeName; + PALIAS_ENTRY Data; + struct tagALIAS_HEADER * Next; + +}ALIAS_HEADER, *PALIAS_HEADER; + +static PALIAS_HEADER RootHeader = NULL; + +static +PALIAS_HEADER +IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName) +{ + while(RootHeader) + { + INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName); + if (!diff) + return RootHeader; + + if (diff < 0) + break; + + RootHeader = RootHeader->Next; + } + return NULL; +} + +PALIAS_HEADER +IntCreateAliasHeader(LPCWSTR lpExeName) +{ + PALIAS_HEADER Entry; + UINT dwLength = wcslen(lpExeName) + 1; + + Entry = RtlAllocateHeap(CsrssApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength); + if (!Entry) + return Entry; + + Entry->lpExeName = (LPCWSTR)(Entry + sizeof(ALIAS_HEADER)); + wcscpy((WCHAR*)Entry->lpExeName, lpExeName); + Entry->Next = NULL; + return Entry; +} + +VOID +IntInsertAliasHeader(PALIAS_HEADER * RootHeader, PALIAS_HEADER NewHeader) +{ + PALIAS_HEADER CurrentHeader; + PALIAS_HEADER LastHeader = NULL; + + if (*RootHeader == 0) + { + *RootHeader = NewHeader; + return; + } + + CurrentHeader = *RootHeader; + + while(CurrentHeader) + { + INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName); + if (Diff < 0) + { + if (!LastHeader) + *RootHeader = NewHeader; + else + LastHeader->Next = NewHeader; + + NewHeader->Next = CurrentHeader; + return; + } + LastHeader = CurrentHeader; + CurrentHeader = CurrentHeader->Next; + } + + LastHeader->Next = NewHeader; + NewHeader->Next = NULL; +} + +PALIAS_ENTRY +IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName) +{ + PALIAS_ENTRY RootHeader = Header->Data; + while(RootHeader) + { + INT diff = _wcsicmp(RootHeader->lpSource, lpSrcName); + if (!diff) + return RootHeader; + + if (diff < 0) + break; + + RootHeader = RootHeader->Next; + } + return NULL; +} + + +VOID +IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry) +{ + PALIAS_ENTRY CurrentEntry; + PALIAS_ENTRY LastEntry = NULL; + + CurrentEntry = Header->Data; + + if (!CurrentEntry) + { + Header->Data = NewEntry; + return; + } + + while(CurrentEntry) + { + INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource); + if (Diff < 0) + { + if (!LastEntry) + Header->Data = NewEntry; + else + LastEntry->Next = NewEntry; + NewEntry->Next = CurrentEntry; + return; + } + LastEntry = CurrentEntry; + CurrentEntry = CurrentEntry->Next; + } + + LastEntry->Next = NewEntry; + NewEntry->Next = NULL; +} + +PALIAS_ENTRY +IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget) +{ + UINT dwSource; + UINT dwTarget; + PALIAS_ENTRY Entry; + + dwSource = wcslen(lpSource) + 1; + dwTarget = wcslen(lpTarget) + 1; + + Entry = RtlAllocateHeap(CsrssApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget)); + if (!Entry) + return Entry; + + Entry->lpSource = (LPCWSTR)(Entry + sizeof(ALIAS_ENTRY)); + wcscpy((LPWSTR)Entry->lpSource, lpSource); + Entry->lpTarget = Entry->lpSource + dwSource; + wcscpy((LPWSTR)Entry->lpTarget, lpTarget); + Entry->Next = NULL; + + return Entry; +} + +UINT +IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader) +{ + UINT length = 0; + + while(RootHeader) + { + length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR); + } + if (length) + length++; // last entry entry is terminated with 2 zero bytes + + return length; +} + +UINT +IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT TargetBufferSize) +{ + UINT Offset = 0; + UINT Length; + + TargetBufferSize /= sizeof(WCHAR); + while(RootHeader) + { + Length = wcslen(RootHeader->lpExeName) + 1; + if (TargetBufferSize > Offset + Length) + { + wcscpy(&TargetBuffer[Offset], RootHeader->lpExeName); + Offset += Length; + } + else + { + break; + } + RootHeader = RootHeader->Next; + } + Length = min(Offset+1, TargetBufferSize); + TargetBuffer[Length] = L'\0'; + return Length * sizeof(WCHAR); +} + +UINT +IntGetAllConsoleAliasesLength(PALIAS_HEADER Header) +{ + UINT Length = 0; + PALIAS_ENTRY CurEntry = Header->Data; + + while(CurEntry) + { + Length += wcslen(CurEntry->lpSource); + Length += wcslen(CurEntry->lpTarget); + Length += 2; // zero byte and '=' + } + if (Length) + Length++; // extra zero + + return sizeof(WCHAR) * Length; +} +UINT +IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength) +{ + PALIAS_ENTRY CurEntry = Header->Data; + UINT Offset = 0; + UINT SrcLength, TargetLength; + + TargetBufferLength /= sizeof(WCHAR); + while(CurEntry) + { + SrcLength = wcslen(CurEntry->lpSource) + 1; + TargetLength = wcslen(CurEntry->lpTarget) + 1; + if (Offset + TargetLength + SrcLength >= TargetBufferLength) + break; + + wcscpy(&TargetBuffer[Offset], CurEntry->lpSource); + Offset += SrcLength; + TargetBuffer[Offset] = L'='; + wcscpy(&TargetBuffer[Offset], CurEntry->lpTarget); + Offset += TargetLength; + + CurEntry = CurEntry->Next; + } + TargetBuffer[Offset] = L'\0'; + return Offset * sizeof(WCHAR); +} +VOID +IntDeleteAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY Entry) +{ + PALIAS_ENTRY LastEntry; + PALIAS_ENTRY CurEntry; + + if (Header->Data == Entry) + { + Header->Data = Entry->Next; + RtlFreeHeap(CsrssApiHeap, 0, Entry); + return; + } + LastEntry = Header->Data; + CurEntry = LastEntry->Next; + + while(CurEntry) + { + if (CurEntry == Entry) + { + LastEntry->Next = Entry->Next; + RtlFreeHeap(CsrssApiHeap, 0, Entry); + return; + } + LastEntry = CurEntry; + CurEntry = CurEntry->Next; + } +} + +CSR_API(CsrAddConsoleAlias) +{ + PALIAS_HEADER Header; + PALIAS_ENTRY Entry; + + if (Request->Data.AddConsoleAlias.lpExeName == NULL || Request->Data.AddConsoleAlias.lpSource == NULL) + { + Request->Status = STATUS_INVALID_PARAMETER; + return Request->Status; + } + + Header = IntFindAliasHeader(RootHeader, Request->Data.AddConsoleAlias.lpExeName); + if (!Header) + { + Header = IntCreateAliasHeader(Request->Data.AddConsoleAlias.lpExeName); + if (!Header) + { + Request->Status = STATUS_INSUFFICIENT_RESOURCES; + return STATUS_INSUFFICIENT_RESOURCES; + } + } + + if (Request->Data.AddConsoleAlias.lpTarget == NULL) // delete the entry + { + Entry = IntGetAliasEntry(Header, Request->Data.AddConsoleAlias.lpSource); + if (Entry) + { + IntDeleteAliasEntry(Header, Entry); + Request->Status = STATUS_SUCCESS; + } + else + { + Request->Status = STATUS_INVALID_PARAMETER; + } + + return Request->Status; + } + + Entry = IntCreateAliasEntry(Request->Data.AddConsoleAlias.lpSource, + Request->Data.AddConsoleAlias.lpTarget); + + if (!Entry) + { + Request->Status = STATUS_INSUFFICIENT_RESOURCES; + return STATUS_INSUFFICIENT_RESOURCES; + } + + IntInsertAliasEntry(Header, Entry); + + Request->Status = STATUS_SUCCESS; + return Request->Status; +} + +CSR_API(CsrGetConsoleAlias) +{ + PALIAS_HEADER Header; + PALIAS_ENTRY Entry; + UINT Length; + + if (Request->Data.GetConsoleAlias.lpExeName == NULL || Request->Data.GetConsoleAlias.TargetBuffer == NULL || + Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.lpSource == NULL) + { + Request->Status = STATUS_INVALID_PARAMETER; + return Request->Status; + } + + Header = IntFindAliasHeader(RootHeader, Request->Data.GetAllConsoleAlias.lpExeName); + if (!Header) + { + Request->Status = ERROR_NO_DATA; // FIXME + return ERROR_NO_DATA; + } + + Entry = IntGetAliasEntry(Header, Request->Data.GetConsoleAlias.lpSource); + if (!Entry) + { + Request->Status = ERROR_NO_DATA; // FIXME + return ERROR_NO_DATA; + } + + Length = (wcslen(Entry->lpTarget)+1) * sizeof(WCHAR); + if (Length > Request->Data.GetConsoleAlias.TargetBufferLength) + { + Request->Status = ERROR_INSUFFICIENT_BUFFER; + return ERROR_INSUFFICIENT_BUFFER; + } + wcscpy(Request->Data.GetConsoleAlias.TargetBuffer, Entry->lpTarget); + Request->Data.GetConsoleAlias.BytesWritten = Length; + Request->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} + +CSR_API(CsrGetAllConsoleAliases) +{ + ULONG BytesWritten; + PALIAS_HEADER Header; + + if (Request->Data.GetAllConsoleAlias.lpExeName == NULL) + { + Request->Status = STATUS_INVALID_PARAMETER; + return Request->Status; + } + + Header = IntFindAliasHeader(RootHeader, Request->Data.GetAllConsoleAlias.lpExeName); + if (!Header) + { + Request->Status = ERROR_NO_DATA; // FIXME + return ERROR_NO_DATA; + } + + if (IntGetAllConsoleAliasesLength(Header) > Request->Data.GetAllConsoleAlias.AliasBufferLength) + { + Request->Status = ERROR_INSUFFICIENT_BUFFER; + return ERROR_INSUFFICIENT_BUFFER; + } + + BytesWritten = IntGetAllConsoleAliases(Header, + Request->Data.GetAllConsoleAlias.AliasBuffer, + Request->Data.GetAllConsoleAlias.AliasBufferLength); + + Request->Data.GetAllConsoleAlias.BytesWritten = BytesWritten; + Request->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} + +CSR_API(CsrGetAllConsoleAliasesLength) +{ + PALIAS_HEADER Header; + UINT Length; + + if (Request->Data.GetAllConsoleAliasesLength.lpExeName == NULL) + { + Request->Status = STATUS_INVALID_PARAMETER; + return Request->Status; + } + + Header = IntFindAliasHeader(RootHeader, Request->Data.GetAllConsoleAliasesLength.lpExeName); + if (!Header) + { + Request->Status = ERROR_NO_DATA; // FIXME + return ERROR_NO_DATA; + } + + Length = IntGetAllConsoleAliasesLength(Header); + Request->Data.GetAllConsoleAliasesLength.Length = Length; + Request->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; + +} + +CSR_API(CsrGetConsoleAliasesExes) +{ + UINT BytesWritten; + UINT ExesLength = IntGetConsoleAliasesExesLength(RootHeader); + + if (ExesLength > Request->Data.GetConsoleAliasesExes.Length) + { + Request->Status = ERROR_INSUFFICIENT_BUFFER; + return ERROR_INSUFFICIENT_BUFFER; + } + + if (Request->Data.GetConsoleAliasesExes.ExeNames == NULL) + { + Request->Status = STATUS_INVALID_PARAMETER; + return Request->Status; + } + + BytesWritten = IntGetConsoleAliasesExes(RootHeader, + Request->Data.GetConsoleAliasesExes.ExeNames, + Request->Data.GetConsoleAliasesExes.Length); + + Request->Data.GetConsoleAliasesExes.BytesWritten = BytesWritten; + Request->Status = STATUS_SUCCESS; + return Request->Status; +} + +CSR_API(CsrGetConsoleAliasesExesLength) +{ + Request->Status = STATUS_SUCCESS; + Request->Data.GetConsoleAliasesExesLength.Length = IntGetConsoleAliasesExesLength(RootHeader); + return STATUS_SUCCESS; +} diff --git a/reactos/subsystems/win32/csrss/csrss.rbuild b/reactos/subsystems/win32/csrss/csrss.rbuild index dd09e4d5d9b..26c1426f32e 100644 --- a/reactos/subsystems/win32/csrss/csrss.rbuild +++ b/reactos/subsystems/win32/csrss/csrss.rbuild @@ -11,11 +11,13 @@ nt ntdll smdll + msvcrt handle.c process.c user.c wapi.c + alias.c csrss.h csrss.c diff --git a/reactos/subsystems/win32/csrss/include/api.h b/reactos/subsystems/win32/csrss/include/api.h index 581e0670e15..344d17742cc 100644 --- a/reactos/subsystems/win32/csrss/include/api.h +++ b/reactos/subsystems/win32/csrss/include/api.h @@ -149,6 +149,14 @@ CSR_API(CsrSetShutdownParameters); CSR_API(CsrSetLogonNotifyWindow); CSR_API(CsrRegisterLogonProcess); +CSR_API(CsrAddConsoleAlias); +CSR_API(CsrGetConsoleAlias); +CSR_API(CsrGetAllConsoleAliases); +CSR_API(CsrGetAllConsoleAliasesLength); +CSR_API(CsrGetConsoleAliasesExes); +CSR_API(CsrGetConsoleAliasesExesLength); + + #endif /* ndef API_H_INCLUDED */ /* EOF */ diff --git a/reactos/subsystems/win32/csrss/init.c b/reactos/subsystems/win32/csrss/init.c index c0b8ca2eb3b..2a8689be72d 100644 --- a/reactos/subsystems/win32/csrss/init.c +++ b/reactos/subsystems/win32/csrss/init.c @@ -293,6 +293,12 @@ CSRSS_API_DEFINITION NativeDefinitions[] = CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle), CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle), CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle), + CSRSS_DEFINE_API(ADD_CONSOLE_ALIAS, CsrAddConsoleAlias), + CSRSS_DEFINE_API(GET_CONSOLE_ALIAS, CsrGetConsoleAlias), + CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES, CsrGetAllConsoleAliases), + CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CsrGetAllConsoleAliasesLength), + CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES, CsrGetConsoleAliasesExes), + CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength), { 0, 0, NULL } };