reactos/dll/win32/kernel32/client/console/alias.c

606 lines
18 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: dll/win32/kernel32/client/console/alias.c
* PURPOSE: Win32 Console Client Alias support functions
* PROGRAMMERS: David Welch (welch@cwcom.net) (welch@mcmail.com)
* Christoph von Wittich (christoph_vw@reactos.org)
* Johannes Anderwald (johannes.anderwald@reactos.org)
*/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ******************************************************************/
static BOOL
IntAddConsoleAlias(LPCVOID Source,
USHORT SourceBufferLength,
LPCVOID Target,
USHORT TargetBufferLength,
LPCVOID lpExeName,
BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &ApiMessage.Data.ConsoleAliasRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
ULONG CapturedStrings;
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ConsoleAliasRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Determine the needed sizes */
ConsoleAliasRequest->SourceLength = SourceBufferLength;
ConsoleAliasRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
ConsoleAliasRequest->Unicode =
ConsoleAliasRequest->Unicode2 = bUnicode;
CapturedStrings = 2;
if (Target) /* The target can be optional */
{
ConsoleAliasRequest->TargetLength = TargetBufferLength;
CapturedStrings++;
}
else
{
ConsoleAliasRequest->TargetLength = 0;
}
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(CapturedStrings,
ConsoleAliasRequest->SourceLength +
ConsoleAliasRequest->ExeLength +
ConsoleAliasRequest->TargetLength);
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Capture the strings */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)Source,
ConsoleAliasRequest->SourceLength,
(PVOID*)&ConsoleAliasRequest->Source);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
ConsoleAliasRequest->ExeLength,
(PVOID*)&ConsoleAliasRequest->ExeName);
if (Target) /* The target can be optional */
{
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)Target,
ConsoleAliasRequest->TargetLength,
(PVOID*)&ConsoleAliasRequest->Target);
}
else
{
ConsoleAliasRequest->Target = NULL;
}
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAddAlias),
sizeof(*ConsoleAliasRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
AddConsoleAliasW(LPCWSTR lpSource,
LPCWSTR lpTarget,
LPCWSTR lpExeName)
{
USHORT SourceBufferLength = (USHORT)wcslen(lpSource) * sizeof(WCHAR);
USHORT TargetBufferLength = (USHORT)(lpTarget ? wcslen(lpTarget) * sizeof(WCHAR) : 0);
DPRINT("AddConsoleAliasW entered with lpSource '%S' lpTarget '%S' lpExeName '%S'\n",
lpSource, lpTarget, lpExeName);
return IntAddConsoleAlias(lpSource,
SourceBufferLength,
lpTarget,
TargetBufferLength,
lpExeName,
TRUE);
}
/*
* @implemented
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
AddConsoleAliasA(LPCSTR lpSource,
LPCSTR lpTarget,
LPCSTR lpExeName)
{
USHORT SourceBufferLength = (USHORT)strlen(lpSource) * sizeof(CHAR);
USHORT TargetBufferLength = (USHORT)(lpTarget ? strlen(lpTarget) * sizeof(CHAR) : 0);
DPRINT("AddConsoleAliasA entered with lpSource '%s' lpTarget '%s' lpExeName '%s'\n",
lpSource, lpTarget, lpExeName);
return IntAddConsoleAlias(lpSource,
SourceBufferLength,
lpTarget,
TargetBufferLength,
lpExeName,
FALSE);
}
static DWORD
IntGetConsoleAlias(LPVOID Source,
USHORT SourceBufferLength,
LPVOID Target,
USHORT TargetBufferLength,
LPVOID lpExeName,
BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_ADDGETALIAS ConsoleAliasRequest = &ApiMessage.Data.ConsoleAliasRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (Source == NULL || Target == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
ConsoleAliasRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Determine the needed sizes */
ConsoleAliasRequest->SourceLength = SourceBufferLength;
ConsoleAliasRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
ConsoleAliasRequest->Unicode =
ConsoleAliasRequest->Unicode2 = bUnicode;
ConsoleAliasRequest->TargetLength = TargetBufferLength;
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(3, ConsoleAliasRequest->SourceLength +
ConsoleAliasRequest->ExeLength +
ConsoleAliasRequest->TargetLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
/* Capture the strings */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)Source,
ConsoleAliasRequest->SourceLength,
(PVOID*)&ConsoleAliasRequest->Source);
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
ConsoleAliasRequest->ExeLength,
(PVOID*)&ConsoleAliasRequest->ExeName);
/* Allocate space for the target buffer */
CsrAllocateMessagePointer(CaptureBuffer,
ConsoleAliasRequest->TargetLength,
(PVOID*)&ConsoleAliasRequest->Target);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAlias),
sizeof(*ConsoleAliasRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(ApiMessage.Status);
if (ApiMessage.Status == STATUS_BUFFER_TOO_SMALL)
return ConsoleAliasRequest->TargetLength;
else
return 0;
}
/* Copy the returned target string into the user buffer */
RtlCopyMemory(Target,
ConsoleAliasRequest->Target,
ConsoleAliasRequest->TargetLength);
[KERNEL32-CONSRV] - Introduce a CONSOLE_PROPS structure to hold console properties such as its title or startup attributes it should have. Initialized at console application launch time. I have to see how could it be possible to merge this structure with some parts of the GUI_CONSOLE_DATA structure and of the ConsoleInfo structure from console.dll (in /dll/cpl). - Use a helper function to initialize the CONSOLE_PROPS structure in kernel32, at console app start or when calling AllocConsole. - In BasepInitConsole, do initialization of CONSOLE_PROPS and related only if we are about to launch a console app. [CONSRV] - Adapt CONSOLE_CONNECTION_INFO and CONSOLE_ALLOCCONSOLE structures to take into account CONSOLE_PROPS. - Fix the way we are setting console titles. - Add experimental support for loading console properties and title and icon from shell links, thanks to the helper LoadShellLinkInfo. However I'm using there Shell COM facility to extract link properties (I could do it "the RAW way", however I would then know the format of link files, that I don't know and that I don't want to mix up with the console code). Therefore I must add dependencies to uuid and ole32 libraries. Note that icons are used in GUI consoles only (use the PrivateExtractIconExW function to retrieve both handles to the big and small icons at the same time). Part 1/2 [CONSRV] - Remove an unuseful xxxInitScreenBuffer function in the virtual functions console table. - In GUI_CONSOLE_DATA structure and related functions, temporarily explicitely mark which members may be used for both GUI and TUI consoles (for a future simplification). - Add temporary debug prints when we are setting console icon, to see the flow of calls (will be removed just before merging back to trunk). - Add temporary debug prints in ConSrvInitConsoleScreenBuffer and ConioDeleteScreenBuffer, to figure out how SBs are initialized. svn path=/branches/ros-csrss/; revision=58305
2013-02-10 12:36:57 +00:00
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return ConsoleAliasRequest->TargetLength;
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasW(LPWSTR lpSource,
LPWSTR lpTargetBuffer,
DWORD TargetBufferLength,
LPWSTR lpExeName)
{
DPRINT("GetConsoleAliasW entered with lpSource '%S' lpExeName '%S'\n",
lpSource, lpExeName);
return IntGetConsoleAlias(lpSource,
(USHORT)wcslen(lpSource) * sizeof(WCHAR),
lpTargetBuffer,
TargetBufferLength,
lpExeName,
TRUE);
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasA(LPSTR lpSource,
LPSTR lpTargetBuffer,
DWORD TargetBufferLength,
LPSTR lpExeName)
{
DPRINT("GetConsoleAliasA entered with lpSource '%s' lpExeName '%s'\n",
lpSource, lpExeName);
return IntGetConsoleAlias(lpSource,
(USHORT)strlen(lpSource) * sizeof(CHAR),
lpTargetBuffer,
TargetBufferLength,
lpExeName,
FALSE);
}
static DWORD
IntGetConsoleAliases(LPVOID AliasBuffer,
DWORD AliasBufferLength,
LPVOID lpExeName,
BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALLALIASES GetAllAliasesRequest = &ApiMessage.Data.GetAllAliasesRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
GetAllAliasesRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Determine the needed sizes */
GetAllAliasesRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
GetAllAliasesRequest->Unicode =
GetAllAliasesRequest->Unicode2 = bUnicode;
GetAllAliasesRequest->AliasesBufferLength = AliasBufferLength;
/* Allocate a Capture Buffer */
CaptureBuffer = CsrAllocateCaptureBuffer(2, GetAllAliasesRequest->ExeLength +
GetAllAliasesRequest->AliasesBufferLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
/* Capture the exe name and allocate space for the aliases buffer */
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
GetAllAliasesRequest->ExeLength,
(PVOID*)&GetAllAliasesRequest->ExeName);
CsrAllocateMessagePointer(CaptureBuffer,
GetAllAliasesRequest->AliasesBufferLength,
(PVOID*)&GetAllAliasesRequest->AliasesBuffer);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliases),
sizeof(*GetAllAliasesRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
/* Copy the returned aliases string into the user buffer */
RtlCopyMemory(AliasBuffer,
GetAllAliasesRequest->AliasesBuffer,
GetAllAliasesRequest->AliasesBufferLength);
[KERNEL32-CONSRV] - Introduce a CONSOLE_PROPS structure to hold console properties such as its title or startup attributes it should have. Initialized at console application launch time. I have to see how could it be possible to merge this structure with some parts of the GUI_CONSOLE_DATA structure and of the ConsoleInfo structure from console.dll (in /dll/cpl). - Use a helper function to initialize the CONSOLE_PROPS structure in kernel32, at console app start or when calling AllocConsole. - In BasepInitConsole, do initialization of CONSOLE_PROPS and related only if we are about to launch a console app. [CONSRV] - Adapt CONSOLE_CONNECTION_INFO and CONSOLE_ALLOCCONSOLE structures to take into account CONSOLE_PROPS. - Fix the way we are setting console titles. - Add experimental support for loading console properties and title and icon from shell links, thanks to the helper LoadShellLinkInfo. However I'm using there Shell COM facility to extract link properties (I could do it "the RAW way", however I would then know the format of link files, that I don't know and that I don't want to mix up with the console code). Therefore I must add dependencies to uuid and ole32 libraries. Note that icons are used in GUI consoles only (use the PrivateExtractIconExW function to retrieve both handles to the big and small icons at the same time). Part 1/2 [CONSRV] - Remove an unuseful xxxInitScreenBuffer function in the virtual functions console table. - In GUI_CONSOLE_DATA structure and related functions, temporarily explicitely mark which members may be used for both GUI and TUI consoles (for a future simplification). - Add temporary debug prints when we are setting console icon, to see the flow of calls (will be removed just before merging back to trunk). - Add temporary debug prints in ConSrvInitConsoleScreenBuffer and ConioDeleteScreenBuffer, to figure out how SBs are initialized. svn path=/branches/ros-csrss/; revision=58305
2013-02-10 12:36:57 +00:00
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAllAliasesRequest->AliasesBufferLength;
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasesW(LPWSTR AliasBuffer,
DWORD AliasBufferLength,
LPWSTR ExeName)
{
DPRINT("GetConsoleAliasesW entered with lpExeName '%S'\n",
ExeName);
return IntGetConsoleAliases(AliasBuffer,
AliasBufferLength,
ExeName,
TRUE);
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasesA(LPSTR AliasBuffer,
DWORD AliasBufferLength,
LPSTR ExeName)
{
DPRINT("GetConsoleAliasesA entered with lpExeName '%s'\n",
ExeName);
return IntGetConsoleAliases(AliasBuffer,
AliasBufferLength,
ExeName,
FALSE);
}
static DWORD
IntGetConsoleAliasesLength(LPVOID lpExeName, BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALLALIASESLENGTH GetAllAliasesLengthRequest = &ApiMessage.Data.GetAllAliasesLengthRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
USHORT NumChars = (USHORT)(lpExeName ? (bUnicode ? wcslen(lpExeName) : strlen(lpExeName)) : 0);
if (lpExeName == NULL || NumChars == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
GetAllAliasesLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetAllAliasesLengthRequest->ExeLength = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
GetAllAliasesLengthRequest->Unicode =
GetAllAliasesLengthRequest->Unicode2 = bUnicode;
CaptureBuffer = CsrAllocateCaptureBuffer(1, GetAllAliasesLengthRequest->ExeLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)lpExeName,
GetAllAliasesLengthRequest->ExeLength,
(PVOID)&GetAllAliasesLengthRequest->ExeName);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasesLength),
sizeof(*GetAllAliasesLengthRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
return GetAllAliasesLengthRequest->Length;
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasesLengthW(LPWSTR lpExeName)
{
return IntGetConsoleAliasesLength(lpExeName, TRUE);
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasesLengthA(LPSTR lpExeName)
{
return IntGetConsoleAliasesLength(lpExeName, FALSE);
}
static DWORD
IntGetConsoleAliasExes(PVOID lpExeNameBuffer,
DWORD ExeNameBufferLength,
BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALIASESEXES GetAliasesExesRequest = &ApiMessage.Data.GetAliasesExesRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer;
GetAliasesExesRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetAliasesExesRequest->Length = ExeNameBufferLength;
GetAliasesExesRequest->Unicode = bUnicode;
CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
if (!CaptureBuffer)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
CsrAllocateMessagePointer(CaptureBuffer,
ExeNameBufferLength,
(PVOID*)&GetAliasesExesRequest->ExeNames);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasExes),
sizeof(*GetAliasesExesRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
CsrFreeCaptureBuffer(CaptureBuffer);
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
RtlCopyMemory(lpExeNameBuffer,
GetAliasesExesRequest->ExeNames,
GetAliasesExesRequest->Length);
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAliasesExesRequest->Length;
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
DWORD ExeNameBufferLength)
{
DPRINT("GetConsoleAliasExesW called\n");
return IntGetConsoleAliasExes(lpExeNameBuffer, ExeNameBufferLength, TRUE);
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasExesA(LPSTR lpExeNameBuffer,
DWORD ExeNameBufferLength)
{
DPRINT("GetConsoleAliasExesA called\n");
return IntGetConsoleAliasExes(lpExeNameBuffer, ExeNameBufferLength, FALSE);
}
static DWORD
IntGetConsoleAliasExesLength(BOOLEAN bUnicode)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETALIASESEXESLENGTH GetAliasesExesLengthRequest = &ApiMessage.Data.GetAliasesExesLengthRequest;
GetAliasesExesLengthRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetAliasesExesLengthRequest->Unicode = bUnicode;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetAliasExesLength),
sizeof(*GetAliasesExesLengthRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return 0;
}
return GetAliasesExesLengthRequest->Length;
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasExesLengthW(VOID)
{
DPRINT("GetConsoleAliasExesLengthW called\n");
return IntGetConsoleAliasExesLength(TRUE);
}
/*
* @implemented
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetConsoleAliasExesLengthA(VOID)
{
DPRINT("GetConsoleAliasExesLengthA called\n");
return IntGetConsoleAliasExesLength(FALSE);
}
/* EOF */