- implement GetConsoleAlias* AddConsoleAlias function in csrss

- 

svn path=/trunk/; revision=32117
This commit is contained in:
Johannes Anderwald 2008-02-04 18:57:19 +00:00
parent 8b88c6aa50
commit 188cc187b1
4 changed files with 491 additions and 0 deletions

View file

@ -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 <csrss.h>
#define NDEBUG
#include <debug.h>
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;
}

View file

@ -11,11 +11,13 @@
<library>nt</library>
<library>ntdll</library>
<library>smdll</library>
<library>msvcrt</library>
<directory name="api">
<file>handle.c</file>
<file>process.c</file>
<file>user.c</file>
<file>wapi.c</file>
<file>alias.c</file>
</directory>
<pch>csrss.h</pch>
<file>csrss.c</file>

View file

@ -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 */

View file

@ -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 }
};