[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
This commit is contained in:
Hermès Bélusca-Maïto 2013-02-10 12:36:57 +00:00
parent 8cf2fce7be
commit f4d53fbd91
15 changed files with 603 additions and 272 deletions

View file

@ -211,7 +211,7 @@ GetConsoleAliasW(LPWSTR lpSource,
ConsoleAliasRequest->Target,
ConsoleAliasRequest->TargetLength);
/* Release the capture buffer and exits */
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return ConsoleAliasRequest->TargetLength;
@ -347,7 +347,7 @@ GetConsoleAliasesW(LPWSTR AliasBuffer,
GetAllAliasesRequest->AliasesBuffer,
GetAllAliasesRequest->AliasesBufferLength);
/* Release the capture buffer and exits */
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAllAliasesRequest->AliasesBufferLength; // / sizeof(WCHAR); (original code)
@ -514,7 +514,7 @@ GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
GetAliasesExesRequest->ExeNames,
GetAliasesExesRequest->Length);
/* Release the capture buffer and exits */
/* Release the capture buffer and exit */
CsrFreeCaptureBuffer(CaptureBuffer);
return GetAliasesExesRequest->Length;

View file

@ -5,10 +5,6 @@
* PURPOSE: Win32 server console functions
* PROGRAMMER: James Tabor
* <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
* UPDATE HISTORY:
* 199901?? ?? Created
* 19990204 EA SetConsoleTitleA
* 19990306 EA Stubs
*/
/* INCLUDES *******************************************************************/
@ -194,6 +190,49 @@ InitConsoleCtrlHandling(VOID)
/* FUNCTIONS ******************************************************************/
VOID
InitConsoleProps(IN OUT PCONSOLE_PROPS ConsoleProps)
{
STARTUPINFOW si;
GetStartupInfoW(&si);
ConsoleProps->dwStartupFlags = si.dwFlags;
if (si.dwFlags & STARTF_USEFILLATTRIBUTE)
{
ConsoleProps->FillAttribute = si.dwFillAttribute;
}
if (si.dwFlags & STARTF_USECOUNTCHARS)
{
ConsoleProps->ScreenBufferSize.X = (SHORT)(si.dwXCountChars);
ConsoleProps->ScreenBufferSize.Y = (SHORT)(si.dwYCountChars);
}
if (si.dwFlags & STARTF_USESHOWWINDOW)
{
ConsoleProps->ShowWindow = si.wShowWindow;
}
if (si.dwFlags & STARTF_USEPOSITION)
{
ConsoleProps->ConsoleWindowOrigin.x = (LONG)(si.dwX);
ConsoleProps->ConsoleWindowOrigin.y = (LONG)(si.dwY);
}
if (si.dwFlags & STARTF_USESIZE)
{
ConsoleProps->ConsoleWindowSize.cx = (LONG)(si.dwXSize);
ConsoleProps->ConsoleWindowSize.cy = (LONG)(si.dwYSize);
}
if (si.lpTitle)
{
wcsncpy(ConsoleProps->ConsoleTitle, si.lpTitle, MAX_PATH + 1);
}
else
{
ConsoleProps->ConsoleTitle[0] = L'\0';
}
}
LPCWSTR
IntCheckForConsoleFileName(IN LPCWSTR pszName,
IN DWORD dwDesiredAccess)
@ -764,9 +803,8 @@ GetStdHandle(DWORD nStdHandle)
* of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
*/
{
PRTL_USER_PROCESS_PARAMETERS Ppb;
PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
Ppb = NtCurrentPeb()->ProcessParameters;
switch (nStdHandle)
{
case STD_INPUT_HANDLE:
@ -802,12 +840,10 @@ SetStdHandle(DWORD nStdHandle,
* RETURNS: TRUE if the function succeeds, FALSE otherwise.
*/
{
PRTL_USER_PROCESS_PARAMETERS Ppb;
PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
/* no need to check if hHandle == INVALID_HANDLE_VALUE */
Ppb = NtCurrentPeb()->ProcessParameters;
switch (nStdHandle)
{
case STD_INPUT_HANDLE:
@ -823,7 +859,7 @@ SetStdHandle(DWORD nStdHandle,
return TRUE;
}
/* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
/* Windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
@ -839,36 +875,63 @@ WINAPI
AllocConsole(VOID)
{
NTSTATUS Status;
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
STARTUPINFO si;
PCSR_CAPTURE_BUFFER CaptureBuffer;
SIZE_T Length = 0;
DPRINT1("AllocConsole called !!!!\n");
DPRINT1("AllocConsole\n");
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
if (Parameters->ConsoleHandle)
{
DPRINT1("AllocConsole: Allocate duplicate console to the same Process\n");
DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
GetStartupInfo(&si);
CaptureBuffer = CsrAllocateCaptureBuffer(2, sizeof(CONSOLE_PROPS) +
(MAX_PATH + 1) * sizeof(WCHAR));
if (CaptureBuffer == NULL)
{
DPRINT1("CsrAllocateCaptureBuffer failed!\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
CsrAllocateMessagePointer(CaptureBuffer,
sizeof(CONSOLE_PROPS),
(PVOID*)&AllocConsoleRequest->ConsoleProps);
CsrAllocateMessagePointer(CaptureBuffer,
(MAX_PATH + 1) * sizeof(WCHAR),
(PVOID*)&AllocConsoleRequest->AppPath);
/** Copied from BasepInitConsole **********************************************/
InitConsoleProps(AllocConsoleRequest->ConsoleProps);
Length = min(MAX_PATH + 1, Parameters->ImagePathName.Length / sizeof(WCHAR));
wcsncpy(AllocConsoleRequest->AppPath, Parameters->ImagePathName.Buffer, Length);
AllocConsoleRequest->AppPath[Length] = L'\0';
/******************************************************************************/
AllocConsoleRequest->ShowCmd = si.wShowWindow;
AllocConsoleRequest->Console = NULL;
AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
sizeof(CONSOLE_ALLOCCONSOLE));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
Parameters->ConsoleHandle = AllocConsoleRequest->Console;
SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
@ -1685,16 +1748,20 @@ BOOL
WINAPI
SetConsoleTitleA(LPCSTR lpConsoleTitle)
{
ULONG Length = strlen(lpConsoleTitle) + 1;
BOOL Ret;
ULONG Length = strlen(lpConsoleTitle) + 1;
LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
BOOL Ret;
if (!WideTitle)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
Ret = SetConsoleTitleW(WideTitle);
HeapFree(GetProcessHeap(), 0, WideTitle);
return Ret;
}
@ -1963,12 +2030,13 @@ WINAPI
AttachConsole(DWORD dwProcessId)
{
NTSTATUS Status;
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
DPRINT1("AttachConsole(%lu)\n", dwProcessId);
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
if (Parameters->ConsoleHandle)
{
DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
SetLastError(ERROR_ACCESS_DENIED);
@ -1988,7 +2056,7 @@ AttachConsole(DWORD dwProcessId)
return FALSE;
}
NtCurrentPeb()->ProcessParameters->ConsoleHandle = AttachConsoleRequest->Console;
Parameters->ConsoleHandle = AttachConsoleRequest->Console;
SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
@ -2070,9 +2138,9 @@ SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
{
int lenName;
if (!lpInputExeName
|| (lenName = lstrlenW(lpInputExeName)) == 0
|| lenName > INPUTEXENAME_BUFLEN - 1)
if ( !lpInputExeName ||
(lenName = lstrlenW(lpInputExeName)) == 0 ||
lenName > INPUTEXENAME_BUFLEN - 1 )
{
/* Fail if string is empty or too long */
SetLastError(ERROR_INVALID_PARAMETER);
@ -2111,12 +2179,11 @@ SetConsoleInputExeNameA(LPCSTR lpInputExeName)
ANSI_STRING InputExeNameA;
UNICODE_STRING InputExeNameU;
NTSTATUS Status;
BOOL Ret;
RtlInitAnsiString(&InputExeNameA, lpInputExeName);
if(InputExeNameA.Length == 0 ||
InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
if ( InputExeNameA.Length == 0 ||
InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
{
/* Fail if string is empty or too long */
SetLastError(ERROR_INVALID_PARAMETER);
@ -2126,18 +2193,15 @@ SetConsoleInputExeNameA(LPCSTR lpInputExeName)
InputExeNameU.Buffer = Buffer;
InputExeNameU.MaximumLength = sizeof(Buffer);
InputExeNameU.Length = 0;
Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
if(NT_SUCCESS(Status))
{
Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
}
else
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
Ret = FALSE;
return FALSE;
}
return Ret;
return SetConsoleInputExeNameW(InputExeNameU.Buffer);
}
@ -2164,7 +2228,7 @@ GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
return lenName + 1;
}
if(lenName + 1 > nBufferLength)
if (lenName + 1 > nBufferLength)
{
/* Buffer is not large enough! */
SetLastError(ERROR_BUFFER_OVERFLOW);
@ -2219,7 +2283,7 @@ GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
/* Error handling */
if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
{
SetLastError(ERROR_BUFFER_OVERFLOW);
return 2;

View file

@ -5,8 +5,6 @@
* PURPOSE: Initialization
* PROGRAMMERS: Ariadne (ariadne@xs4all.nl)
* Aleksey Bragin (aleksey@reactos.org)
* UPDATE HISTORY:
* Created 01/11/98
*/
/* INCLUDES ******************************************************************/
@ -53,8 +51,6 @@ BasepInitConsole(VOID)
{
NTSTATUS Status;
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
LPCWSTR ExeName;
STARTUPINFO si;
WCHAR SessionDir[256];
ULONG SessionId = NtCurrentPeb()->SessionId;
BOOLEAN InServer;
@ -62,9 +58,7 @@ BasepInitConsole(VOID)
CONSOLE_CONNECTION_INFO ConnectInfo;
ULONG ConnectInfoSize = sizeof(ConnectInfo);
WCHAR lpTest[MAX_PATH];
GetModuleFileNameW(NULL, lpTest, MAX_PATH);
DPRINT("BasepInitConsole for : %S\n", lpTest);
DPRINT("BasepInitConsole for : %wZ\n", &Parameters->ImagePathName);
DPRINT("Our current console handles are: %lx, %lx, %lx %lx\n",
Parameters->ConsoleHandle, Parameters->StandardInput,
Parameters->StandardOutput, Parameters->StandardError);
@ -74,20 +68,35 @@ BasepInitConsole(VOID)
if (!NT_SUCCESS(Status)) return FALSE;
ConsoleInitialized = TRUE;
/* We have nothing to do if this isn't a console app... */
/* Do nothing if this isn't a console app... */
if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem !=
IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
DPRINT("Image is not a console application\n");
Parameters->ConsoleHandle = NULL;
ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app.
ConnectInfo.ConsoleProps.ConsoleTitle[0] = L'\0';
ConnectInfo.AppPath[0] = L'\0';
}
else
{
SIZE_T Length = 0;
LPCWSTR ExeName;
InitConsoleProps(&ConnectInfo.ConsoleProps);
Length = min(sizeof(ConnectInfo.AppPath) / sizeof(ConnectInfo.AppPath[0]),
Parameters->ImagePathName.Length / sizeof(WCHAR));
wcsncpy(ConnectInfo.AppPath, Parameters->ImagePathName.Buffer, Length);
ConnectInfo.AppPath[Length] = L'\0';
/* Initialize Input EXE name */
ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\');
if (ExeName) SetConsoleInputExeNameW(ExeName + 1);
/* Assume one is needed */
GetStartupInfo(&si);
ConnectInfo.ConsoleNeeded = TRUE;
ConnectInfo.ShowCmd = si.wShowWindow;
/* Handle the special flags given to us by BasePushProcessParameters */
if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
@ -108,7 +117,7 @@ BasepInitConsole(VOID)
/* We'll get the real one soon */
DPRINT("Creating new invisible console\n");
Parameters->ConsoleHandle = NULL;
ConnectInfo.ShowCmd = SW_HIDE;
ConnectInfo.ConsoleProps.ShowWindow = SW_HIDE;
}
else
{
@ -123,14 +132,10 @@ BasepInitConsole(VOID)
/* Now use the proper console handle */
ConnectInfo.Console = Parameters->ConsoleHandle;
/* Initialize Console Ctrl Handler and input EXE name */
/* Initialize Console Ctrl Handler */
InitConsoleCtrlHandling();
ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher;
ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\');
if (ExeName)
SetConsoleInputExeNameW(ExeName + 1);
/* Setup the right Object Directory path */
if (!SessionId)
{

View file

@ -196,6 +196,9 @@ BOOL WINAPI CloseConsoleHandle(HANDLE Handle);
HANDLE WINAPI
GetConsoleInputWaitHandle(VOID);
VOID
InitConsoleProps(IN OUT PCONSOLE_PROPS ConsoleProps);
LPCWSTR
IntCheckForConsoleFileName(IN LPCWSTR pszName,
IN DWORD dwDesiredAccess);

View file

@ -112,12 +112,26 @@ typedef enum _CONSRV_API_NUMBER
} CONSRV_API_NUMBER, *PCONSRV_API_NUMBER;
typedef struct _CONSOLE_PROPS
{
DWORD dwStartupFlags;
DWORD FillAttribute;
COORD ScreenBufferSize;
WORD ShowWindow;
POINT ConsoleWindowOrigin;
SIZE ConsoleWindowSize;
// UNICODE_STRING ConsoleTitle;
WCHAR ConsoleTitle[MAX_PATH + 1];
} CONSOLE_PROPS, *PCONSOLE_PROPS;
typedef struct _CONSOLE_CONNECTION_INFO
{
BOOL ConsoleNeeded; // Used for GUI apps only.
/* Copied from CONSOLE_ALLOCCONSOLE */
INT ShowCmd;
/* Adapted from CONSOLE_ALLOCCONSOLE */
CONSOLE_PROPS ConsoleProps;
WCHAR AppPath[MAX_PATH + 1];
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
HANDLE InputHandle;
HANDLE OutputHandle;
@ -168,7 +182,9 @@ typedef struct
typedef struct
{
INT ShowCmd;
PCONSOLE_PROPS ConsoleProps;
LPWSTR AppPath;
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
HANDLE InputHandle;
HANDLE OutputHandle;

View file

@ -21,12 +21,12 @@ list(APPEND SOURCE
add_library(consrv SHARED ${SOURCE})
target_link_libraries(consrv win32ksys ${PSEH_LIB}) # win32ksys because of NtUser...()
target_link_libraries(consrv win32ksys ${PSEH_LIB} uuid) # win32ksys because of NtUser...()
set_module_type(consrv win32dll UNICODE)
add_importlibs(consrv psapi msvcrt kernel32 ntdll csrsrv)
add_delay_importlibs(consrv user32 gdi32 advapi32)
add_delay_importlibs(consrv user32 gdi32 advapi32 ole32)
add_dependencies(consrv bugcodes)
add_cd_file(TARGET consrv DESTINATION reactos/system32 FOR all)

View file

@ -15,9 +15,10 @@
#ifndef WM_APP
#define WM_APP 0x8000
#endif
#define PM_CREATE_CONSOLE (WM_APP + 1)
#define PM_DESTROY_CONSOLE (WM_APP + 2)
#define PM_CONSOLE_BEEP (WM_APP + 3)
#define PM_CREATE_CONSOLE (WM_APP + 1)
#define PM_DESTROY_CONSOLE (WM_APP + 2)
#define PM_CONSOLE_BEEP (WM_APP + 3)
#define PM_CONSOLE_SET_TITLE (WM_APP + 4)
/************************************************************************
@ -113,8 +114,10 @@ typedef struct _CONSOLE
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
/****************************** GUI-related data ******************************/
UNICODE_STRING Title; /* Title of console */
HWND hWindow;
UNICODE_STRING Title; /* Title of console. It is always NULL-terminated */
HWND hWindow; /* Handle to the console's window */
HICON hIcon; /* Handle to its icon (used when freeing) */
HICON hIconSm;
COORD Size;
PVOID GuiData;
@ -135,7 +138,6 @@ do { \
typedef struct _CONSOLE_VTBL
{
VOID (WINAPI *InitScreenBuffer)(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer);
VOID (WINAPI *WriteStream)(PCONSOLE Console, SMALL_RECT* Block, LONG CursorStartX, LONG CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length);
VOID (WINAPI *DrawRegion)(PCONSOLE Console, SMALL_RECT* Region);
@ -143,7 +145,7 @@ typedef struct _CONSOLE_VTBL
BOOL (WINAPI *SetScreenInfo)(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer,
UINT OldCursorX, UINT OldCursorY);
BOOL (WINAPI *UpdateScreenInfo)(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer);
BOOL (WINAPI *ChangeTitle)(PCONSOLE Console);
VOID (WINAPI *ChangeTitle)(PCONSOLE Console);
VOID (WINAPI *CleanupConsole)(PCONSOLE Console);
BOOL (WINAPI *ChangeIcon)(PCONSOLE Console, HICON hWindowIcon);
NTSTATUS (WINAPI *ResizeBuffer)(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size);
@ -163,7 +165,6 @@ typedef struct _CONSOLE_VTBL
#define PAUSED_FROM_SCROLLBAR 0x2
#define PAUSED_FROM_SELECTION 0x4
#define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff))
#define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region))
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
(Console)->Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
@ -181,7 +182,10 @@ typedef struct _CONSOLE_VTBL
/* console.c */
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
VOID WINAPI ConSrvInitConsoleSupport(VOID);
NTSTATUS WINAPI ConSrvInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderProcess);
NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole,
IN LPCWSTR AppPath,
IN OUT PCONSOLE_PROPS ConsoleProps,
IN PCSR_PROCESS ConsoleLeaderProcess);
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
VOID FASTCALL ConSrvConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData);

View file

@ -63,7 +63,7 @@ NTSTATUS FASTCALL
ConSrvInitConsoleScreenBuffer(PCONSOLE Console,
PCONSOLE_SCREEN_BUFFER Buffer)
{
DPRINT("ConSrvInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
DPRINT1("ConSrvInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
Buffer->Header.Console = Console;
@ -74,9 +74,10 @@ ConSrvInitConsoleScreenBuffer(PCONSOLE Console,
Buffer->Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2);
if (NULL == Buffer->Buffer)
{
DPRINT1("ConSrvInitConsoleScreenBuffer - D'oh!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
ConioInitScreenBuffer(Console, Buffer);
Buffer->DefaultAttrib = DEFAULT_ATTRIB;
/* initialize buffer to be empty with default attributes */
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
{
@ -376,6 +377,7 @@ VOID WINAPI
ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
{
PCONSOLE Console = Buffer->Header.Console;
DPRINT1("ConioDeleteScreenBuffer(Buffer = 0x%p, Buffer->Buffer = 0x%p) ; Console = 0x%p\n", Buffer, Buffer->Buffer, Console);
RemoveEntryList(&Buffer->ListEntry);
if (Buffer == Console->ActiveBuffer)
@ -384,6 +386,7 @@ ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
Console->ActiveBuffer = NULL;
if (!IsListEmpty(&Console->BufferList))
{
DPRINT1("ConioDeleteScreenBuffer - Bang !!!!!!!!\n");
Console->ActiveBuffer = CONTAINING_RECORD(Console->BufferList.Flink, CONSOLE_SCREEN_BUFFER, ListEntry);
ConioDrawConsole(Console);
}
@ -423,7 +426,7 @@ ConioComputeUpdateRect(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOO
UpdateRect->Right = Start->X + Length - 1;
}
UpdateRect->Top = Start->Y;
UpdateRect->Bottom = Start->Y+ (Start->X + Length - 1) / Buff->MaxX;
UpdateRect->Bottom = Start->Y + (Start->X + Length - 1) / Buff->MaxX;
if (Buff->MaxY <= UpdateRect->Bottom)
{
UpdateRect->Bottom = Buff->MaxY - 1;

View file

@ -8,10 +8,16 @@
/* INCLUDES ******************************************************************/
#define COBJMACROS
#define NONAMELESSUNION
#include "consrv.h"
#include "guiconsole.h"
#include "tuiconsole.h"
#include <shlwapi.h>
#include <shlobj.h>
//#define NDEBUG
#include <debug.h>
@ -95,15 +101,117 @@ ConioUnpause(PCONSOLE Console, UINT Flags)
}
}
static BOOL
LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
OUT LPWSTR IconPath,
IN SIZE_T IconPathLength,
OUT PINT piIcon)
{
#define PATH_SEPARATOR L'\\'
LPWSTR LinkName = NULL;
SIZE_T Length = 0;
if ((ConsoleProps->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
return FALSE;
if (IconPath == NULL || piIcon == NULL)
return FALSE;
IconPath[0] = L'\0';
*piIcon = 0;
/* 1- Find the last path separator if any */
LinkName = wcsrchr(ConsoleProps->ConsoleTitle, PATH_SEPARATOR);
if (LinkName == NULL)
{
LinkName = ConsoleProps->ConsoleTitle;
}
else
{
/* Skip the path separator */
++LinkName;
}
/* 2- Check for the link extension. The name ".lnk" is considered invalid. */
Length = wcslen(LinkName);
if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) )
return FALSE;
/* 3- It may be a link. Try to retrieve some properties */
HRESULT hRes = CoInitialize(NULL);
if (SUCCEEDED(hRes))
{
// Get a pointer to the IShellLink interface.
IShellLinkW* pshl = NULL;
hRes = CoCreateInstance(&CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLinkW,
(LPVOID*)&pshl);
if (SUCCEEDED(hRes))
{
// Get a pointer to the IPersistFile interface.
IPersistFile* ppf = NULL;
hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hRes))
{
// Load the shortcut.
hRes = IPersistFile_Load(ppf, ConsoleProps->ConsoleTitle, STGM_READ);
if (SUCCEEDED(hRes))
{
/*
* Finally we can get the properties !
* Update the old ones if needed.
*/
INT ShowCmd = 0;
// WORD HotKey = 0;
// Get the name of the shortcut.
Length = min(Length - 4,
sizeof(ConsoleProps->ConsoleTitle) / sizeof(ConsoleProps->ConsoleTitle[0]));
wcsncpy(ConsoleProps->ConsoleTitle, LinkName, Length);
ConsoleProps->ConsoleTitle[Length] = L'\0';
// Get the window showing command.
hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd);
if (SUCCEEDED(hRes)) ConsoleProps->ShowWindow = (WORD)ShowCmd;
// Get the hotkey.
// hRes = pshl->GetHotkey(&ShowCmd);
// if (SUCCEEDED(hRes)) ConsoleProps->HotKey = HotKey;
// Get the icon location, if any.
hRes = IShellLinkW_GetIconLocation(pshl, IconPath, IconPathLength, piIcon);
if (!SUCCEEDED(hRes))
{
IconPath[0] = L'\0';
}
}
IPersistFile_Release(ppf);
}
IShellLinkW_Release(pshl);
}
}
CoUninitialize();
return TRUE;
}
NTSTATUS WINAPI
ConSrvInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderProcess)
ConSrvInitConsole(OUT PCONSOLE* NewConsole,
IN LPCWSTR AppPath,
IN OUT PCONSOLE_PROPS ConsoleProps,
IN PCSR_PROCESS ConsoleLeaderProcess)
{
NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes;
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER NewBuffer;
BOOL GuiMode;
WCHAR Title[255];
WCHAR Title[128];
WCHAR IconPath[MAX_PATH + 1] = L"";
INT iIcon = 0;
if (NewConsole == NULL) return STATUS_INVALID_PARAMETER;
@ -117,19 +225,21 @@ ConSrvInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderP
return STATUS_NO_MEMORY;
}
/*
* Check whether the process creating the console
* was launched via a shell-link.
*/
if (ConsoleProps->dwStartupFlags & STARTF_TITLEISLINKNAME)
{
LoadShellLinkInfo(ConsoleProps,
IconPath,
MAX_PATH,
&iIcon);
ConsoleProps->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
}
/* Initialize the console */
Console->Title.MaximumLength = Console->Title.Length = 0;
Console->Title.Buffer = NULL;
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, Title, sizeof(Title) / sizeof(Title[0])))
{
RtlCreateUnicodeString(&Console->Title, Title);
}
else
{
RtlCreateUnicodeString(&Console->Title, L"ReactOS Console");
}
InitializeCriticalSection(&Console->Lock);
Console->ReferenceCount = 0;
Console->LineBuffer = NULL;
@ -150,6 +260,7 @@ ConSrvInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderP
Console->CodePage = GetOEMCP();
Console->OutputCodePage = GetOEMCP();
Console->GuiData = NULL;
Console->hIcon = Console->hIconSm = NULL;
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.lpSecurityDescriptor = NULL;
@ -158,35 +269,65 @@ ConSrvInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderP
Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
if (NULL == Console->InputBuffer.ActiveEvent)
{
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
RtlFreeHeap(ConSrvHeap, 0, Console);
return STATUS_UNSUCCESSFUL;
}
GuiMode = DtbgIsDesktopVisible();
/* allocate console screen buffer */
/* Allocate console screen buffer */
NewBuffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER));
if (NULL == NewBuffer)
{
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->InputBuffer.ActiveEvent);
RtlFreeHeap(ConSrvHeap, 0, Console);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* init screen buffer with defaults */
/* Init screen buffer with defaults */
NewBuffer->CursorInfo.bVisible = TRUE;
NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
/* make console active, and insert into console list */
Console->ActiveBuffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
/* Make console active, and insert into console list */
Console->ActiveBuffer = NewBuffer;
/** Finish to initialize the screen buffer **
** Fix problems with MaxX == 0 and MaxY == 0
**
Status = ConSrvInitConsoleScreenBuffer(Console, NewBuffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("ConSrvInitConsoleScreenBuffer: failed\n");
RtlFreeHeap(ConSrvHeap, 0, NewBuffer);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->InputBuffer.ActiveEvent);
RtlFreeHeap(ConSrvHeap, 0, Console);
return Status;
}
**/
/* Initialize the console title */
Console->Title.MaximumLength = Console->Title.Length = 0;
Console->Title.Buffer = NULL;
if (ConsoleProps->ConsoleTitle[0] == L'\0')
{
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, Title, sizeof(Title) / sizeof(Title[0])))
{
RtlCreateUnicodeString(&Console->Title, Title);
}
else
{
RtlCreateUnicodeString(&Console->Title, L"ReactOS Console");
}
}
else
{
RtlCreateUnicodeString(&Console->Title, ConsoleProps->ConsoleTitle);
}
/*
* If we are not in GUI-mode, start the text-mode console. If we fail,
* try to start the GUI-mode console (win32k will automatically switch
* to graphical mode, therefore no additional code is needed).
* If we are not in GUI-mode, start the text-mode console.
* If we fail, try to start the GUI-mode console.
*/
GuiMode = DtbgIsDesktopVisible();
if (!GuiMode)
{
DPRINT1("CONSRV: Opening text-mode console\n");
@ -204,33 +345,41 @@ ConSrvInitConsole(PCONSOLE* NewConsole, int ShowCmd, PCSR_PROCESS ConsoleLeaderP
* failed and we start GUI-mode console.
* - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
* succeeded BUT we failed at starting text-mode console. Then GuiMode
* was switched to TRUE in order to try to open the console in GUI-mode.
* was switched to TRUE in order to try to open the console in GUI-mode
* (win32k will automatically switch to graphical mode, therefore
* no additional code is needed).
*/
if (GuiMode)
{
DPRINT1("CONSRV: Opening GUI-mode console\n");
Status = GuiInitConsole(Console, ShowCmd);
Status = GuiInitConsole(Console,
AppPath,
ConsoleProps->ShowWindow,
IconPath,
iIcon);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ConSrvHeap,0, NewBuffer);
DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->InputBuffer.ActiveEvent);
DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
RtlFreeHeap(ConSrvHeap, 0, NewBuffer);
/// ConioDeleteScreenBuffer(NewBuffer);
RtlFreeHeap(ConSrvHeap, 0, Console);
return Status;
}
}
// TODO: Move this call before initializing Tui/Gui console. But before fix freeing Buffer->Buffer !!
Status = ConSrvInitConsoleScreenBuffer(Console, NewBuffer);
if (!NT_SUCCESS(Status))
{
DPRINT1("ConSrvInitConsoleScreenBuffer: failed\n");
ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->InputBuffer.ActiveEvent);
RtlFreeHeap(ConSrvHeap, 0, NewBuffer);
DPRINT1("ConSrvInitConsoleScreenBuffer: failed\n");
RtlFreeHeap(ConSrvHeap, 0, Console);
return Status;
}
@ -282,6 +431,7 @@ ConSrvDeleteConsole(PCONSOLE Console)
CloseHandle(Console->InputBuffer.ActiveEvent);
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->Title);
IntDeleteAllAliases(Console->Aliases);
RtlFreeHeap(ConSrvHeap, 0, Console);
@ -353,8 +503,8 @@ CSR_API(SrvAllocConsole)
{
NTSTATUS Status = STATUS_SUCCESS;
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
PCSR_PROCESS ConsoleLeader = CsrGetClientThread()->Process;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(ConsoleLeader);
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
DPRINT("SrvAllocConsole\n");
@ -364,6 +514,18 @@ CSR_API(SrvAllocConsole)
return STATUS_ACCESS_DENIED;
}
if ( !CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&AllocConsoleRequest->ConsoleProps,
1,
sizeof(CONSOLE_PROPS)) ||
!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&AllocConsoleRequest->AppPath,
MAX_PATH + 1,
sizeof(WCHAR)) )
{
return STATUS_INVALID_PARAMETER;
}
/*
* We are about to create a new console. However when ConSrvNewProcess
* was called, we didn't know that we wanted to create a new console and
@ -379,11 +541,11 @@ CSR_API(SrvAllocConsole)
/* Initialize a new Console owned by the Console Leader Process */
Status = ConSrvAllocateConsole(ProcessData,
AllocConsoleRequest->AppPath,
&AllocConsoleRequest->InputHandle,
&AllocConsoleRequest->OutputHandle,
&AllocConsoleRequest->ErrorHandle,
AllocConsoleRequest->ShowCmd,
ConsoleLeader);
AllocConsoleRequest->ConsoleProps);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console allocation failed\n");
@ -602,34 +764,37 @@ CSR_API(SrvSetConsoleTitle)
}
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
if(NT_SUCCESS(Status))
if (!NT_SUCCESS(Status))
{
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest->Length);
if (Buffer)
{
/* Copy title to console */
RtlFreeUnicodeString(&Console->Title);
Console->Title.Buffer = Buffer;
Console->Title.Length = Console->Title.MaximumLength = TitleRequest->Length;
memcpy(Console->Title.Buffer, TitleRequest->Title, Console->Title.Length);
if (!ConioChangeTitle(Console))
{
Status = STATUS_UNSUCCESSFUL;
}
else
{
Status = STATUS_SUCCESS;
}
}
else
{
Status = STATUS_NO_MEMORY;
}
ConSrvReleaseConsole(Console, TRUE);
DPRINT1("Can't get console\n");
return Status;
}
/* Allocate a new buffer to hold the new title (NULL-terminated) */
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest->Length + sizeof(WCHAR));
if (Buffer)
{
/* Free the old title */
RtlFreeUnicodeString(&Console->Title);
/* Copy title to console */
Console->Title.Buffer = Buffer;
Console->Title.Length = TitleRequest->Length;
Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
RtlCopyMemory(Console->Title.Buffer,
TitleRequest->Title,
Console->Title.Length);
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
ConioChangeTitle(Console);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_NO_MEMORY;
}
ConSrvReleaseConsole(Console, TRUE);
return Status;
}

View file

@ -178,11 +178,11 @@ NTSTATUS FASTCALL ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
VOID FASTCALL ConSrvReleaseObject(Object_t *Object,
BOOL IsConsoleLocked);
NTSTATUS FASTCALL ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
LPCWSTR AppPath,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
int ShowCmd,
PCSR_PROCESS CsrProcess);
PCONSOLE_PROPS ConsoleProps);
NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
struct _CONSOLE* Console,
BOOL CreateNewHandlesTable,

View file

@ -39,34 +39,39 @@ PrivateCsrssManualGuiCheck(LONG Check)
typedef struct _GUI_CONSOLE_DATA
{
HFONT Font;
unsigned CharWidth;
unsigned CharHeight;
BOOL CursorBlinkOn;
BOOL ForceCursorOff;
/* GUI-specific */ HFONT Font;
/* GUI-specific */ WCHAR FontName[LF_FACESIZE];
/* GUI-specific */ DWORD FontSize;
/* GUI-specific */ DWORD FontWeight;
/* GUI-specific */ UINT CharWidth;
/* GUI-specific */ UINT CharHeight;
/* non-specific */ BOOL CursorBlinkOn;
/* non-specific */ BOOL ForceCursorOff;
CRITICAL_SECTION Lock;
HMODULE ConsoleLibrary;
HANDLE hGuiInitEvent;
WCHAR FontName[LF_FACESIZE];
DWORD FontSize;
DWORD FontWeight;
DWORD FullScreen;
DWORD QuickEdit;
DWORD InsertMode;
DWORD WindowPosition;
DWORD UseRasterFonts;
COLORREF ScreenText;
COLORREF ScreenBackground;
COLORREF PopupBackground;
COLORREF PopupText;
COLORREF Colors[16];
/* GUI-specific */ DWORD FullScreen;
/* non-specific */ DWORD QuickEdit;
/* non-specific */ DWORD InsertMode;
/* GUI-specific */ DWORD WindowPosition;
/* GUI-specific */ DWORD UseRasterFonts;
/* non-specific */ COLORREF ScreenText;
/* non-specific */ COLORREF ScreenBackground;
/* non-specific */ COLORREF PopupBackground;
/* non-specific */ COLORREF PopupText;
/* non-specific */ COLORREF Colors[16];
WCHAR szProcessName[MAX_PATH];
BOOL WindowSizeLock;
POINT OldCursor;
} GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
static BOOL ConsInitialized = FALSE;
static HWND NotifyWnd;
static BOOL ConsInitialized = FALSE;
static HICON ghDefaultIcon = NULL;
static HICON ghDefaultIconSm = NULL;
static HCURSOR ghDefaultCursor = NULL;
static HWND NotifyWnd = NULL;
typedef struct _GUICONSOLE_MENUITEM
{
@ -195,6 +200,12 @@ GuiGetWindowConsole(HWND hWnd)
return (PCONSOLE)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
}
/*******************************************************************************
** The following functions may be available for both GUI and CUI
******************************************************************************/
static BOOL
GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired)
{
@ -615,35 +626,40 @@ GuiConsoleUseDefaults(PCONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCONSOLE_SCRE
* init guidata with default properties
*/
wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
GuiData->FontSize = 0x0008000C; // font is 8x12
GuiData->FontWeight = FW_NORMAL;
GuiData->FullScreen = FALSE;
GuiData->QuickEdit = FALSE;
GuiData->InsertMode = TRUE;
GuiData->ScreenText = RGB(192, 192, 192);
GuiData->ScreenBackground = RGB(0, 0, 0);
GuiData->PopupText = RGB(128, 0, 128);
GuiData->PopupBackground = RGB(255, 255, 255);
/* GUI-specific */ wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
/* GUI-specific */ GuiData->FontSize = 0x0008000C; // font is 8x12
/* GUI-specific */ GuiData->FontWeight = FW_NORMAL;
/* GUI-specific */ GuiData->FullScreen = FALSE;
/* non-specific */ GuiData->QuickEdit = FALSE;
/* non-specific */ GuiData->InsertMode = TRUE;
/* non-specific */ GuiData->ScreenText = RGB(192, 192, 192);
/* non-specific */ GuiData->ScreenBackground = RGB(0, 0, 0);
/* non-specific */ GuiData->PopupText = RGB(128, 0, 128);
/* non-specific */ GuiData->PopupBackground = RGB(255, 255, 255);
GuiData->WindowPosition = UINT_MAX;
GuiData->UseRasterFonts = TRUE;
memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
/* GUI-specific */ GuiData->UseRasterFonts = TRUE;
/* non-specific */ memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
Console->HistoryBufferSize = 50;
Console->NumberOfHistoryBuffers = 5;
Console->HistoryNoDup = FALSE;
Console->Size.X = 80;
Console->Size.Y = 25;
/* non-specific */ Console->HistoryBufferSize = 50;
/* non-specific */ Console->NumberOfHistoryBuffers = 5;
/* non-specific */ Console->HistoryNoDup = FALSE;
/* XUI-specific */ Console->Size.X = 80;
/* XUI-specific */ Console->Size.Y = 25;
if (Buffer)
{
Buffer->MaxX = 80;
Buffer->MaxY = 300;
Buffer->CursorInfo.bVisible = TRUE;
Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
/* XUI-specific */ Buffer->MaxX = 80;
/* XUI-specific */ Buffer->MaxY = 300;
/* XUI-specific */ Buffer->CursorInfo.bVisible = TRUE;
/* XUI-specific */ Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
}
}
/*******************************************************************************
******************************************************************************/
VOID
FASTCALL
GuiConsoleInitScrollbar(PCONSOLE Console, HWND hwnd)
@ -2061,6 +2077,10 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Beep(800, 200);
break;
case PM_CONSOLE_SET_TITLE:
SetWindowText(hWnd, Console->Title.Buffer);
break;
default:
Result = DefWindowProcW(hWnd, msg, wParam, lParam);
break;
@ -2078,8 +2098,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
HWND NewWindow;
LONG WindowCount;
MSG Msg;
PWCHAR Buffer, Title;
PCONSOLE Console = (PCONSOLE) lParam;
PCONSOLE Console = (PCONSOLE)lParam;
switch (msg)
{
@ -2087,21 +2106,9 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
SetWindowLongW(hWnd, GWL_USERDATA, 0);
return 0;
case PM_CREATE_CONSOLE:
Buffer = RtlAllocateHeap(ConSrvHeap, 0,
Console->Title.Length + sizeof(WCHAR));
if (NULL != Buffer)
{
memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
Title = Buffer;
}
else
{
Title = L"";
}
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
GUI_CONSOLE_WINDOW_CLASS,
Title,
Console->Title.Buffer,
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
@ -2109,16 +2116,29 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
CW_USEDEFAULT,
NULL,
NULL,
(HINSTANCE)GetModuleHandleW(NULL),
ConSrvDllInstance,
(PVOID)Console);
if (NULL != Buffer)
{
RtlFreeHeap(ConSrvHeap, 0, Buffer);
}
if (NULL != NewWindow)
{
DPRINT1("CreateWindowExW succeeded\n");
SetConsoleWndConsoleLeaderCID(Console);
SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
DPRINT1("Set icons via PM_CREATE_CONSOLE\n");
if (Console->hIcon == NULL)
{
DPRINT1("Not really...\n");
Console->hIcon = ghDefaultIcon;
Console->hIconSm = ghDefaultIconSm;
}
else if (Console->hIcon != ghDefaultIcon)
{
DPRINT1("Yes !\n");
SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)Console->hIcon);
SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)Console->hIconSm);
}
DPRINT1("Show window\n");
ShowWindow(NewWindow, (int)wParam);
}
return (LRESULT)NewWindow;
@ -2164,7 +2184,7 @@ GuiConsoleGuiThread(PVOID Data)
CW_USEDEFAULT,
NULL,
NULL,
(HINSTANCE) GetModuleHandleW(NULL),
ConSrvDllInstance,
NULL);
if (NULL == NotifyWnd)
{
@ -2195,38 +2215,45 @@ GuiInit(VOID)
PrivateCsrssManualGuiCheck(+1);
}
/* Initialize the notification window class */
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"ConSrvCreateNotify";
wc.lpfnWndProc = GuiConsoleNotifyWndProc;
wc.style = 0;
wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL);
wc.hInstance = ConSrvDllInstance;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIconSm = NULL;
if (RegisterClassExW(&wc) == 0)
{
DPRINT1("Failed to register GUI notify wndproc\n");
return FALSE;
}
/* Initialize the console window class */
ghDefaultIcon = LoadImageW(ConSrvDllInstance, MAKEINTRESOURCEW(IDI_CONSOLE), IMAGE_ICON,
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
LR_SHARED);
ghDefaultIconSm = LoadImageW(ConSrvDllInstance, MAKEINTRESOURCEW(IDI_CONSOLE), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
LR_SHARED);
ghDefaultCursor = LoadCursorW(NULL, IDC_ARROW);
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = GUI_CONSOLE_WINDOW_CLASS;
wc.lpfnWndProc = GuiConsoleWndProc;
wc.style = 0;
wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL);
wc.hIcon = LoadIconW(ConSrvDllInstance, MAKEINTRESOURCEW(1));
wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW);
wc.hInstance = ConSrvDllInstance;
wc.hIcon = ghDefaultIcon;
wc.hIconSm = ghDefaultIconSm;
wc.hCursor = ghDefaultCursor;
wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
wc.hIconSm = LoadImageW(ConSrvDllInstance, MAKEINTRESOURCEW(1), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
LR_SHARED);
ConsoleClassAtom = RegisterClassExW(&wc);
if (ConsoleClassAtom == 0)
@ -2243,44 +2270,50 @@ GuiInit(VOID)
}
static VOID WINAPI
GuiInitScreenBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buffer)
{
Buffer->DefaultAttrib = DEFAULT_ATTRIB;
}
static BOOL WINAPI
GuiChangeTitle(PCONSOLE Console)
{
PWCHAR Buffer, Title;
Buffer = RtlAllocateHeap(ConSrvHeap, 0,
Console->Title.Length + sizeof(WCHAR));
if (NULL != Buffer)
{
memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
Title = Buffer;
}
else
{
Title = L"";
}
PostMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM)Title);
if (NULL != Buffer)
{
RtlFreeHeap(ConSrvHeap, 0, Buffer);
}
return TRUE;
PostMessageW(Console->hWindow, PM_CONSOLE_SET_TITLE, 0, 0);
}
static BOOL WINAPI
GuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
{
PostMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon);
PostMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon);
HICON hIcon, hIconSm;
if (hWindowIcon == NULL)
{
hIcon = ghDefaultIcon;
hIconSm = ghDefaultIconSm;
}
else
{
hIcon = CopyIcon(hWindowIcon);
hIconSm = CopyIcon(hWindowIcon);
}
if (hIcon == NULL)
{
return FALSE;
}
if (hIcon != Console->hIcon)
{
if (Console->hIcon != NULL && Console->hIcon != ghDefaultIcon)
{
DestroyIcon(Console->hIcon);
}
if (Console->hIconSm != NULL && Console->hIconSm != ghDefaultIconSm)
{
DestroyIcon(Console->hIconSm);
}
Console->hIcon = hIcon;
Console->hIconSm = hIconSm;
DPRINT1("Set icons in GuiChangeIcon\n");
PostMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)Console->hIcon);
PostMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)Console->hIconSm);
}
return TRUE;
}
@ -2289,11 +2322,23 @@ static VOID WINAPI
GuiCleanupConsole(PCONSOLE Console)
{
SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM)Console);
DPRINT1("Destroying icons !! - Console->hIcon = 0x%p ; ghDefaultIcon = 0x%p ; Console->hIconSm = 0x%p ; ghDefaultIconSm = 0x%p\n",
Console->hIcon, ghDefaultIcon, Console->hIconSm, ghDefaultIconSm);
if (Console->hIcon != NULL && Console->hIcon != ghDefaultIcon)
{
DPRINT1("Destroy hIcon\n");
DestroyIcon(Console->hIcon);
}
if (Console->hIconSm != NULL && Console->hIconSm != ghDefaultIconSm)
{
DPRINT1("Destroy hIconSm\n");
DestroyIcon(Console->hIconSm);
}
}
static CONSOLE_VTBL GuiVtbl =
{
GuiInitScreenBuffer,
GuiWriteStream,
GuiDrawRegion,
GuiSetCursorInfo,
@ -2306,12 +2351,17 @@ static CONSOLE_VTBL GuiVtbl =
};
NTSTATUS FASTCALL
GuiInitConsole(PCONSOLE Console, int ShowCmd)
GuiInitConsole(PCONSOLE Console,
LPCWSTR AppPath,
WORD ShowWindow,
LPCWSTR IconPath,
INT IconIndex)
{
HANDLE GraphicsStartupEvent;
HANDLE ThreadHandle;
PGUI_CONSOLE_DATA GuiData;
/* Initialize the GUI */
if (!ConsInitialized)
{
ConsInitialized = TRUE;
@ -2322,8 +2372,10 @@ GuiInitConsole(PCONSOLE Console, int ShowCmd)
}
}
/* Finish to initialize the console */
Console->Vtbl = &GuiVtbl;
Console->hWindow = NULL;
if (NULL == NotifyWnd)
{
GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
@ -2356,6 +2408,7 @@ GuiInitConsole(PCONSOLE Console, int ShowCmd)
return STATUS_UNSUCCESSFUL;
}
}
GuiData = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY,
sizeof(GUI_CONSOLE_DATA));
if (!GuiData)
@ -2363,22 +2416,51 @@ GuiInitConsole(PCONSOLE Console, int ShowCmd)
DPRINT1("CONSRV: Failed to create GUI_CONSOLE_DATA\n");
return STATUS_UNSUCCESSFUL;
}
Console->GuiData = (PVOID)GuiData;
/* Initialize the icon handles to their default values */
Console->hIcon = ghDefaultIcon;
Console->hIconSm = ghDefaultIconSm;
/* Get the associated icon, if any */
if (IconPath == NULL || *IconPath == L'\0')
{
IconPath = AppPath;
IconIndex = 0;
}
DPRINT1("IconPath = %S ; IconIndex = %lu\n", (IconPath ? IconPath : L"n/a"), IconIndex);
if (IconPath)
{
HICON hIcon = NULL, hIconSm = NULL;
DPRINT1("Extracting icons\n");
PrivateExtractIconExW(IconPath,
IconIndex,
&hIcon,
&hIconSm,
1);
DPRINT1("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
if (hIcon != NULL)
{
DPRINT1("Effectively set the icons\n");
Console->hIcon = hIcon;
Console->hIconSm = hIconSm;
}
}
/*
* we need to wait until the GUI has been fully initialized
* to retrieve custom settings i.e. WindowSize etc..
* We need to wait until the GUI has been fully initialized
* to retrieve custom settings i.e. WindowSize etc...
* Ideally we could use SendNotifyMessage for this but its not
* yet implemented.
*
*/
GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
/* create console */
PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowCmd, (LPARAM)Console);
/* wait until initialization has finished */
/* Create the GUI console */
PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowWindow, (LPARAM)Console);
/* Wait until initialization has finished */
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->GuiData, Console->Size.X, Console->Size.Y);
DPRINT("Received event Console %p GuiData %p X %d Y %d\n", Console, Console->GuiData, Console->Size.X, Console->Size.Y);
CloseHandle(GuiData->hGuiInitEvent);
GuiData->hGuiInitEvent = NULL;

View file

@ -13,7 +13,11 @@
#define CONGUI_UPDATE_TIME 0
#define CONGUI_UPDATE_TIMER 1
NTSTATUS FASTCALL GuiInitConsole(PCONSOLE Console, BOOL Visible);
NTSTATUS FASTCALL GuiInitConsole(PCONSOLE Console,
LPCWSTR AppPath,
WORD ShowWindow,
LPCWSTR IconPath,
INT IconIndex);
VOID FASTCALL GuiConsoleHandleScrollbarMenu(VOID);
/*EOF*/

View file

@ -73,7 +73,6 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
WaitAll,
NULL,
(PVOID)Entry);
if (!IsListEmpty(&InputBuffer->ReadWaitQueue))
{
CsrDereferenceWait(&InputBuffer->ReadWaitQueue);
@ -402,16 +401,16 @@ ConSrvReleaseObject(Object_t *Object,
NTSTATUS
FASTCALL
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
LPCWSTR AppPath,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
int ShowCmd,
PCSR_PROCESS CsrProcess)
PCONSOLE_PROPS ConsoleProps)
{
NTSTATUS Status = STATUS_SUCCESS;
/* Initialize a new Console owned by the Console Leader Process */
Status = ConSrvInitConsole(&ProcessData->Console, ShowCmd, CsrProcess);
/* Initialize a new Console owned by this process */
Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleProps, ProcessData->Process);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
@ -601,7 +600,6 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
DPRINT1("ConSrvNewProcess - OK\n");
TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
DPRINT1("TargetProcessData = 0x%p\n", TargetProcessData);
/**** HACK !!!! ****/ RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
@ -623,7 +621,6 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
return STATUS_SUCCESS;
SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
DPRINT1("SourceProcessData = 0x%p\n", SourceProcessData);
/*
* If both of the processes (parent and new child) are console applications,
@ -699,11 +696,11 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
/* Initialize a new Console owned by the Console Leader Process */
Status = ConSrvAllocateConsole(ProcessData,
ConnectInfo->AppPath,
&ConnectInfo->InputHandle,
&ConnectInfo->OutputHandle,
&ConnectInfo->ErrorHandle,
ConnectInfo->ShowCmd,
CsrProcess);
&ConnectInfo->ConsoleProps);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console allocation failed\n");

View file

@ -465,6 +465,8 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization)
LoadedServerDll->NewProcessCallback = ConSrvNewProcess;
// LoadedServerDll->HardErrorCallback = ConSrvHardError;
ConSrvDllInstance = LoadedServerDll->ServerHandle;
/* All done */
return STATUS_SUCCESS;
}
@ -477,12 +479,6 @@ DllMain(IN HINSTANCE hInstanceDll,
{
UNREFERENCED_PARAMETER(dwReason);
UNREFERENCED_PARAMETER(lpReserved);
if (DLL_PROCESS_ATTACH == dwReason)
{
ConSrvDllInstance = hInstanceDll;
}
return TRUE;
}

View file

@ -198,7 +198,7 @@ TuiInit(DWORD OemCP)
wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
wc.lpfnWndProc = TuiConsoleWndProc;
wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
wc.hInstance = (HINSTANCE)GetModuleHandleW(NULL);
wc.hInstance = ConSrvDllInstance;
ConsoleClassAtom = RegisterClassExW(&wc);
if (ConsoleClassAtom == 0)
@ -214,12 +214,6 @@ TuiInit(DWORD OemCP)
return TRUE;
}
static VOID WINAPI
TuiInitScreenBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buffer)
{
Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
}
static void FASTCALL
TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
@ -358,10 +352,9 @@ TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
return TRUE;
}
static BOOL WINAPI
static VOID WINAPI
TuiChangeTitle(PCONSOLE Console)
{
return TRUE;
}
static VOID WINAPI
@ -415,7 +408,7 @@ TuiConsoleThread(PVOID Data)
0,
-32000, -32000, 0, 0,
NULL, NULL,
(HINSTANCE)GetModuleHandleW(NULL),
ConSrvDllInstance,
(PVOID)Console);
if (NULL == NewWindow)
{
@ -446,7 +439,6 @@ TuiConsoleThread(PVOID Data)
static CONSOLE_VTBL TuiVtbl =
{
TuiInitScreenBuffer,
TuiWriteStream,
TuiDrawRegion,
TuiSetCursorInfo,