[CONSOLE.DLL-KERNEL32-CONSRV]

Fix the console properties dialog, when launching and transmitting console properties. Before, the properties dialog was directly launched by the console server (consrv), running with CSRSS (System) privileges, what constituted a security hole. Now, I create a remote thread in the running process owning the console for launching the properties dialog (thus it has only user privileges, and not System ones anymore). For that purpose, I basically took the technique described in the following paper (Cesar Cerrudo, "Story of a dumb patch", http://www.argeniss.com/research/MSBugPaper.pdf or http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf), where basically the console server shares the console properties via a shared memory section with the console properties dialog dll. The address of the thread which launches the dialog in the context of the console app is given to the console server the same way as we do for the control handler (called e.g. when you press Ctrl-C, etc...)
Of course this is quite hackish, because you have the GUI interface split between the console server and the console properties dialog dll. Something far more elegant would be to put all the GUI thingie into a dedicated dll or exe, running with the same privileges as the console program itself (a kind of console -- or terminal -- emulator).

[CONSOLE.DLL]
Fix retriving / setting colors.c and other things.

[CONSRV.DLL]
- Fix retrieving / setting console properties from the registry (via the HKCU\Console\* keys), via the shell shortcuts (not totally done at the moment, because somebody has to implement properly that thing : http://msdn.microsoft.com/en-us/library/windows/desktop/bb773359(v=vs.85).aspx (NT_CONSOLE_PROPS structure stored as a shortcut data block) (at application launching time), and via the console properties dialog.
- Few DPRINTs removed.

svn path=/branches/ros-csrss/; revision=58415
This commit is contained in:
Hermès Bélusca-Maïto 2013-03-03 15:35:12 +00:00
parent bf70c71586
commit 28842d99ad
27 changed files with 2701 additions and 2112 deletions

View file

@ -1,4 +1,5 @@
include_directories(${REACTOS_SOURCE_DIR}/win32ss/user/consrv)
spec2def(console.dll console.spec)

View file

@ -8,64 +8,64 @@
#include "console.h"
static
BOOL
PaintStaticControls(HWND hwndDlg, PConsoleInfo pConInfo, LPDRAWITEMSTRUCT drawItem)
static BOOL
PaintStaticControls(HWND hwndDlg,
PCONSOLE_PROPS pConInfo,
LPDRAWITEMSTRUCT drawItem)
{
HBRUSH hBrush;
DWORD index;
HBRUSH hBrush;
DWORD index;
index = drawItem->CtlID - IDC_STATIC_COLOR1;
hBrush = CreateSolidBrush(pConInfo->Colors[index]);
if (!hBrush)
{
return FALSE;
}
index = min(drawItem->CtlID - IDC_STATIC_COLOR1,
sizeof(pConInfo->ci.Colors) / sizeof(pConInfo->ci.Colors[0]) - 1);
hBrush = CreateSolidBrush(pConInfo->ci.Colors[index]);
if (!hBrush)
{
return FALSE;
}
FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
DeleteObject((HGDIOBJ)hBrush);
if (pConInfo->ActiveStaticControl == index)
{
DrawFocusRect(drawItem->hDC, &drawItem->rcItem);
}
return TRUE;
if (pConInfo->ActiveStaticControl == index)
{
DrawFocusRect(drawItem->hDC, &drawItem->rcItem);
}
return TRUE;
}
INT_PTR
CALLBACK
ColorsProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
INT_PTR CALLBACK
ColorsProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PConsoleInfo pConInfo;
LPNMUPDOWN lpnmud;
LPPSHNOTIFY lppsn;
PCONSOLE_PROPS pConInfo;
LPDRAWITEMSTRUCT drawItem;
DWORD red = MAXDWORD;
DWORD green = MAXDWORD;
DWORD blue = MAXDWORD;
DWORD colorIndex;
COLORREF color;
pConInfo = (PConsoleInfo) GetWindowLongPtr(hwndDlg, DWLP_USER);
pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch(uMsg)
switch (uMsg)
{
case WM_INITDIALOG:
{
pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam;
pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
SendMessage(GetDlgItem(hwndDlg, IDC_RADIO_SCREEN_BACKGROUND), BM_SETCHECK, BST_CHECKED, 0);
/* Set the valid range of the colour indicators */
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_RED), UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0));
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_GREEN), UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0));
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_BLUE), UDM_SETRANGE, 0, (LPARAM)MAKELONG(255, 0));
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->ScreenBackground), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->ScreenBackground), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->ScreenBackground), FALSE);
/* Select by default the screen background option */
CheckRadioButton(hwndDlg, IDC_RADIO_SCREEN_TEXT, IDC_RADIO_POPUP_BACKGROUND, IDC_RADIO_SCREEN_BACKGROUND);
SendMessage(hwndDlg, WM_COMMAND, IDC_RADIO_SCREEN_BACKGROUND, 0);
return TRUE;
}
case WM_DRAWITEM:
{
drawItem = (LPDRAWITEMSTRUCT)lParam;
@ -78,159 +78,198 @@ ColorsProc(
PaintText(drawItem, pConInfo);
return TRUE;
}
break;
}
case WM_NOTIFY:
{
lpnmud = (LPNMUPDOWN) lParam;
lppsn = (LPPSHNOTIFY) lParam;
switch (((LPNMHDR)lParam)->code)
{
case PSN_APPLY:
{
// LPPSHNOTIFY lppsn;
if (!pConInfo->AppliedConfig)
{
return ApplyConsoleInfo(hwndDlg, pConInfo);
}
else
{
/* Options have already been applied */
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
return TRUE;
}
break;
}
if (lppsn->hdr.code == PSN_APPLY)
{
if (!pConInfo->AppliedConfig)
{
ApplyConsoleInfo(hwndDlg, pConInfo);
}
else
{
/* Options have already been applied */
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
return TRUE;
}
return TRUE;
}
case UDN_DELTAPOS:
{
LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_RED)
{
red = lpnmud->iPos;
}
else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_GREEN)
{
green = lpnmud->iPos;
}
else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_BLUE)
{
blue = lpnmud->iPos;
}
else
{
break;
}
/* Get the current color */
colorIndex = pConInfo->ActiveStaticControl;
color = pConInfo->ci.Colors[colorIndex];
if (red == MAXDWORD)
{
red = SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_RED), UDM_GETPOS, 0, 0);
if (HIWORD(red))
{
// TODO: Handle error
break;
}
red = LOBYTE(red);
}
if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_RED)
{
if (lpnmud->iPos < 0) lpnmud->iPos = 0;
else if (lpnmud->iPos > 255) lpnmud->iPos = 255;
if (green == MAXDWORD)
{
green = SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_GREEN), UDM_GETPOS, 0, 0);
if (HIWORD(green))
{
// TODO: Handle error
break;
}
green = LOBYTE(green);
}
color = RGB(lpnmud->iPos, GetGValue(color), GetBValue(color));
}
else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_GREEN)
{
if (lpnmud->iPos < 0) lpnmud->iPos = 0;
else if (lpnmud->iPos > 255) lpnmud->iPos = 255;
color = RGB(GetRValue(color), lpnmud->iPos, GetBValue(color));
}
else if (lpnmud->hdr.idFrom == IDC_UPDOWN_COLOR_BLUE)
{
if (lpnmud->iPos < 0) lpnmud->iPos = 0;
else if (lpnmud->iPos > 255) lpnmud->iPos = 255;
color = RGB(GetRValue(color), GetGValue(color), lpnmud->iPos);
}
else
{
break;
}
pConInfo->ci.Colors[colorIndex] = color;
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + colorIndex), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
}
if (blue == MAXDWORD)
{
blue = SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_COLOR_BLUE), UDM_GETPOS, 0, 0);
if (HIWORD(blue))
{
// TODO: Handle error
break;
}
blue = LOBYTE(blue);
}
pConInfo->Colors[pConInfo->ActiveStaticControl] = RGB(red, green, blue);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
switch (LOWORD(wParam))
{
case IDC_RADIO_SCREEN_TEXT:
{
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->ScreenText), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->ScreenText), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->ScreenText), FALSE);
/* Get the color of the screen foreground */
colorIndex = TextAttribFromAttrib(pConInfo->ci.ScreenAttrib);
color = pConInfo->ci.Colors[colorIndex];
/* Set the values of the colour indicators */
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
pConInfo->ActiveStaticControl = colorIndex;
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
break;
}
case IDC_RADIO_SCREEN_BACKGROUND:
{
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->ScreenBackground), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->ScreenBackground), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->ScreenBackground), FALSE);
/* Get the color of the screen background */
colorIndex = BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib);
color = pConInfo->ci.Colors[colorIndex];
/* Set the values of the colour indicators */
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
pConInfo->ActiveStaticControl = colorIndex;
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
break;
}
case IDC_RADIO_POPUP_TEXT:
{
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->PopupText), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->PopupText), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->PopupText), FALSE);
/* Get the color of the popup foreground */
colorIndex = TextAttribFromAttrib(pConInfo->ci.PopupAttrib);
color = pConInfo->ci.Colors[colorIndex];
/* Set the values of the colour indicators */
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
pConInfo->ActiveStaticControl = colorIndex;
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
break;
}
case IDC_RADIO_POPUP_BACKGROUND:
{
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->PopupBackground), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->PopupBackground), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->PopupBackground), FALSE);
/* Get the color of the popup background */
colorIndex = BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib);
color = pConInfo->ci.Colors[colorIndex];
/* Set the values of the colour indicators */
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
pConInfo->ActiveStaticControl = colorIndex;
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
break;
}
}
if (HIWORD(wParam) == STN_CLICKED && LOWORD(wParam) >= IDC_STATIC_COLOR1 && LOWORD(wParam) <= IDC_STATIC_COLOR16)
{
DWORD index = LOWORD(wParam) - IDC_STATIC_COLOR1;
if (index == pConInfo->ActiveStaticControl)
if ( HIWORD(wParam) == STN_CLICKED &&
IDC_STATIC_COLOR1 <= LOWORD(wParam) && LOWORD(wParam) <= IDC_STATIC_COLOR16 )
{
colorIndex = LOWORD(wParam) - IDC_STATIC_COLOR1;
if (colorIndex == pConInfo->ActiveStaticControl)
{
/* Same static control was re-clicked */
break;
}
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(pConInfo->Colors[index]), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(pConInfo->Colors[index]), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(pConInfo->Colors[index]), FALSE);
color = pConInfo->ci.Colors[colorIndex];
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_RED, GetRValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_GREEN, GetGValue(color), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_COLOR_BLUE, GetBValue(color), FALSE);
/* Update global struct */
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SCREEN_TEXT))
{
pConInfo->ScreenText = pConInfo->Colors[index];
pConInfo->ci.ScreenAttrib = MakeAttrib(colorIndex, BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib));
}
else if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SCREEN_BACKGROUND))
{
pConInfo->ScreenBackground = pConInfo->Colors[index];
pConInfo->ci.ScreenAttrib = MakeAttrib(TextAttribFromAttrib(pConInfo->ci.ScreenAttrib), colorIndex);
}
else if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_POPUP_TEXT))
{
pConInfo->PopupText = pConInfo->Colors[index];
pConInfo->ci.PopupAttrib = MakeAttrib(colorIndex, BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib));
}
else if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_POPUP_BACKGROUND))
{
pConInfo->PopupBackground = pConInfo->Colors[index];
pConInfo->ci.PopupAttrib = MakeAttrib(TextAttribFromAttrib(pConInfo->ci.PopupAttrib), colorIndex);
}
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
pConInfo->ActiveStaticControl = colorIndex;
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + pConInfo->ActiveStaticControl), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_COLOR1 + index), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SCREEN_COLOR), NULL, TRUE);
InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_POPUP_COLOR), NULL, TRUE);
pConInfo->ActiveStaticControl = index;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}

View file

@ -8,9 +8,7 @@
#include "console.h"
#define NUM_APPLETS (1)
#define WM_SETCONSOLE (WM_USER+10)
#define NUM_APPLETS 1
LONG APIENTRY InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK OptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -23,286 +21,334 @@ HINSTANCE hApplet = 0;
/* Applets */
APPLET Applets[NUM_APPLETS] =
{
{IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet}
{IDC_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet}
};
static COLORREF s_Colors[] =
/*
* Default 16-color palette for foreground and background
* (corresponding flags in comments).
*/
const COLORREF s_Colors[16] =
{
RGB(0, 0, 0),
RGB(0, 0, 128),
RGB(0, 128, 0),
RGB(0, 128, 128),
RGB(128, 0, 0),
RGB(128, 0, 128),
RGB(128, 128, 0),
RGB(192, 192, 192),
RGB(128, 128, 128),
RGB(0, 0, 255),
RGB(0, 255, 0),
RGB(0, 255, 255),
RGB(255, 0, 0),
RGB(255, 0, 255),
RGB(255, 255, 0),
RGB(255, 255, 255)
};
RGB(0, 0, 0), // (Black)
RGB(0, 0, 128), // BLUE
RGB(0, 128, 0), // GREEN
RGB(0, 128, 128), // BLUE | GREEN
RGB(128, 0, 0), // RED
RGB(128, 0, 128), // BLUE | RED
RGB(128, 128, 0), // GREEN | RED
RGB(192, 192, 192), // BLUE | GREEN | RED
static void
InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc, LPARAM lParam)
RGB(128, 128, 128), // (Grey) INTENSITY
RGB(0, 0, 255), // BLUE | INTENSITY
RGB(0, 255, 0), // GREEN | INTENSITY
RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
RGB(255, 0, 0), // RED | INTENSITY
RGB(255, 0, 255), // BLUE | RED | INTENSITY
RGB(255, 255, 0), // GREEN | RED | INTENSITY
RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
};
/* Default attributes */
#define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \
BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
static VOID
InitPropSheetPage(PROPSHEETPAGE *psp,
WORD idDlg,
DLGPROC DlgProc,
LPARAM lParam)
{
ZeroMemory(psp, sizeof(PROPSHEETPAGE));
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = PSP_DEFAULT;
psp->hInstance = hApplet;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pfnDlgProc = DlgProc;
psp->lParam = lParam;
ZeroMemory(psp, sizeof(PROPSHEETPAGE));
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = PSP_DEFAULT;
psp->hInstance = hApplet;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pfnDlgProc = DlgProc;
psp->lParam = lParam;
}
PConsoleInfo
PCONSOLE_PROPS
AllocConsoleInfo()
{
PConsoleInfo pConInfo;
pConInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ConsoleInfo));
return pConInfo;
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONSOLE_PROPS));
}
void
InitConsoleDefaults(PConsoleInfo pConInfo)
VOID
InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
{
/* Initialize struct */
pConInfo->InsertMode = TRUE;
pConInfo->HistoryBufferSize = 50;
pConInfo->NumberOfHistoryBuffers = 5;
pConInfo->ScreenText = RGB(192, 192, 192);
pConInfo->ScreenBackground = RGB(0, 0, 0);
pConInfo->PopupText = RGB(128, 0, 128);
pConInfo->PopupBackground = RGB(255, 255, 255);
pConInfo->WindowSize = (DWORD)MAKELONG(80, 25);
pConInfo->WindowPosition = UINT_MAX;
pConInfo->ScreenBuffer = MAKELONG(80, 300);
pConInfo->UseRasterFonts = TRUE;
pConInfo->FontSize = (DWORD)MAKELONG(8, 12);
pConInfo->FontWeight = FW_NORMAL;
memcpy(pConInfo->Colors, s_Colors, sizeof(s_Colors));
}
/* Initialize the default properties */
pConInfo->ci.HistoryBufferSize = 50;
pConInfo->ci.NumberOfHistoryBuffers = 4;
pConInfo->ci.HistoryNoDup = FALSE;
pConInfo->ci.FullScreen = FALSE;
pConInfo->ci.QuickEdit = FALSE;
pConInfo->ci.InsertMode = TRUE;
pConInfo->ci.InputBufferSize;
pConInfo->ci.ScreenBufferSize = (COORD){80, 300};
pConInfo->ci.ConsoleSize = (COORD){80, 25};
pConInfo->ci.CursorBlinkOn = TRUE;
pConInfo->ci.ForceCursorOff = FALSE;
pConInfo->ci.CursorSize = 0;
pConInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
pConInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB;
pConInfo->ci.CodePage = 0;
pConInfo->ci.ConsoleTitle[0] = L'\0';
pConInfo->ci.u.GuiInfo.FaceName[0] = L'\0';
pConInfo->ci.u.GuiInfo.FontFamily = FF_DONTCARE;
pConInfo->ci.u.GuiInfo.FontSize = 0;
pConInfo->ci.u.GuiInfo.FontWeight = FW_DONTCARE;
pConInfo->ci.u.GuiInfo.UseRasterFonts = TRUE;
pConInfo->ci.u.GuiInfo.AutoPosition = TRUE;
pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){0, 0};
memcpy(pConInfo->ci.Colors, s_Colors, sizeof(s_Colors));
}
INT_PTR
CALLBACK
ApplyProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
ApplyProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
HWND hDlgCtrl;
HWND hDlgCtrl;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(lParam);
switch(uMsg)
{
case WM_INITDIALOG:
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
return TRUE;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == IDOK)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
if ( SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED )
EndDialog(hwndDlg, IDC_RADIO_APPLY_CURRENT);
else
EndDialog(hwndDlg, IDC_RADIO_APPLY_ALL);
}
else if (LOWORD(wParam) == IDCANCEL)
{
EndDialog(hwndDlg, IDCANCEL);
}
break;
}
default:
break;
}
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
return TRUE;
}
case WM_COMMAND:
{
if (LOWORD(wParam) == IDOK)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_APPLY_CURRENT);
if (SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
EndDialog(hwndDlg, IDC_RADIO_APPLY_CURRENT);
else
EndDialog(hwndDlg, IDC_RADIO_APPLY_ALL);
}
else if (LOWORD(wParam) == IDCANCEL)
{
EndDialog(hwndDlg, IDCANCEL);
}
break;
}
default:
break;
}
return FALSE;
}
void
ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo)
BOOL
ApplyConsoleInfo(HWND hwndDlg,
PCONSOLE_PROPS pConInfo)
{
INT_PTR res = 0;
INT_PTR res = 0;
res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
res = DialogBox(hApplet, MAKEINTRESOURCE(IDD_APPLYOPTIONS), hwndDlg, ApplyProc);
if (res == IDCANCEL)
{
/* Don't destroy when user presses cancel */
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
return TRUE;
}
else if (res == IDC_RADIO_APPLY_ALL || res == IDC_RADIO_APPLY_CURRENT)
{
HANDLE hSection;
PCONSOLE_PROPS pSharedInfo;
if (res == IDCANCEL)
{
/* Don't destroy when user presses cancel */
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
}
else if ( res == IDC_RADIO_APPLY_ALL )
{
pConInfo->AppliedConfig = TRUE;
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
SendMessage(pConInfo->hConsoleWindow, PM_APPLY_CONSOLE_INFO, (WPARAM)pConInfo, (LPARAM)TRUE);
}
else if ( res == IDC_RADIO_APPLY_CURRENT )
{
pConInfo->AppliedConfig = TRUE;
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
SendMessage(pConInfo->hConsoleWindow, PM_APPLY_CONSOLE_INFO, (WPARAM)pConInfo, (LPARAM)TRUE);
}
/* Create a memory section to share with the server, and map it */
hSection = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof(CONSOLE_PROPS),
NULL);
if (!hSection)
{
// DPRINT1("Error when creating file mapping, error = %d\n", GetLastError());
return FALSE;
}
pSharedInfo = MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (!pSharedInfo)
{
// DPRINT1("Error when mapping view of file, error = %d\n", GetLastError());
CloseHandle(hSection);
return FALSE;
}
/* We are applying the chosen configuration */
pConInfo->AppliedConfig = TRUE;
/* Copy the console info into the section */
RtlCopyMemory(pSharedInfo, pConInfo, sizeof(CONSOLE_PROPS));
/* Unmap it */
UnmapViewOfFile(pSharedInfo);
/* Signal to the console server that it can apply the new configuration */
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
SendMessage(pConInfo->hConsoleWindow,
PM_APPLY_CONSOLE_INFO,
(WPARAM)hSection,
(LPARAM)(res == IDC_RADIO_APPLY_ALL));
/* Close the section and return */
CloseHandle(hSection);
return TRUE;
}
return TRUE;
}
/* First Applet */
LONG APIENTRY
InitApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
InitApplet(HWND hWnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
{
PROPSHEETPAGE psp[4];
PROPSHEETHEADER psh;
INT i=0;
PConsoleInfo pConInfo;
WCHAR szTitle[100];
PConsoleInfo pSharedInfo = (PConsoleInfo)wParam;
HANDLE hSection = (HANDLE)wParam;
PCONSOLE_PROPS pSharedInfo;
PCONSOLE_PROPS pConInfo;
WCHAR szTitle[MAX_PATH + 1];
PROPSHEETPAGE psp[4];
PROPSHEETHEADER psh;
INT i = 0;
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(uMsg);
/*
* console.dll shares information with win32csr with wParam, lParam
*
* wParam is a pointer to a ConsoleInfo struct
* lParam is a boolean parameter which specifies whether defaults should be shown
*/
/*
* CONSOLE.DLL shares information with CONSRV with wParam:
* wParam is a handle to a shared section holding a CONSOLE_PROPS struct.
*
* NOTE: lParam is not used.
*/
pConInfo = AllocConsoleInfo();
if (!pConInfo)
{
return 0;
}
/* Allocate a local buffer to hold console information */
pConInfo = AllocConsoleInfo();
if (!pConInfo) return 0;
if (lParam)
{
/* Use defaults */
InitConsoleDefaults(pConInfo);
}
else
{
if (IsBadReadPtr((const void *)pSharedInfo, sizeof(ConsoleInfo)))
{
/* Use defaults */
InitConsoleDefaults(pConInfo);
}
else
{
pConInfo->InsertMode = pSharedInfo->InsertMode;
pConInfo->HistoryBufferSize = pSharedInfo->HistoryBufferSize;
pConInfo->NumberOfHistoryBuffers = pSharedInfo->NumberOfHistoryBuffers;
pConInfo->ScreenText = pSharedInfo->ScreenText;
pConInfo->ScreenBackground = pSharedInfo->ScreenBackground;
pConInfo->PopupText = pSharedInfo->PopupText;
pConInfo->PopupBackground = pSharedInfo->PopupBackground;
pConInfo->WindowSize = pSharedInfo->WindowSize;
pConInfo->WindowPosition = pSharedInfo->WindowPosition;
pConInfo->ScreenBuffer = pSharedInfo->ScreenBuffer;
pConInfo->UseRasterFonts = pSharedInfo->UseRasterFonts;
pConInfo->FontSize = pSharedInfo->FontSize;
pConInfo->FontWeight = pSharedInfo->FontWeight;
memcpy(pConInfo->Colors, pSharedInfo->Colors, sizeof(s_Colors));
}
}
/* Map the shared section */
pSharedInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
if (pSharedInfo == NULL)
{
HeapFree(GetProcessHeap(), 0, pConInfo);
return 0;
}
/* console window -> is notified on a property change event */
pConInfo->hConsoleWindow = hwnd;
// if (IsBadReadPtr((PVOID)pSharedInfo, sizeof(CONSOLE_PROPS)))
// {
// }
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
if(_tcslen(pConInfo->szProcessName))
{
psh.dwFlags |= PSH_PROPTITLE;
psh.pszCaption = pConInfo->szProcessName;
}
else
{
if (!GetConsoleTitleW(szTitle, sizeof(szTitle)/sizeof(WCHAR)))
{
_tcscpy(szTitle, _T("cmd.exe"));
}
szTitle[(sizeof(szTitle)/sizeof(WCHAR))-1] = _T('\0');
psh.pszCaption = szTitle;
}
/* Find the console window and whether we must use default parameters */
pConInfo->hConsoleWindow = pSharedInfo->hConsoleWindow;
pConInfo->ShowDefaultParams = pSharedInfo->ShowDefaultParams;
psh.hwndParent = hwnd;
psh.hInstance = hApplet;
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON));
psh.nPages = 4;
psh.nStartPage = 0;
psh.ppsp = psp;
if (pConInfo->ShowDefaultParams)
{
/* Use defaults */
InitConsoleDefaults(pConInfo);
}
else
{
/* Copy the shared data into our allocated buffer */
RtlCopyMemory(pConInfo, pSharedInfo, sizeof(CONSOLE_PROPS));
}
InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, (DLGPROC) OptionsProc, (LPARAM)pConInfo);
InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT, (DLGPROC) FontProc, (LPARAM)pConInfo);
InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT, (DLGPROC) LayoutProc, (LPARAM)pConInfo);
InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS, (DLGPROC) ColorsProc, (LPARAM)pConInfo);
/* Close the section */
UnmapViewOfFile(pSharedInfo);
CloseHandle(hSection);
return (PropertySheet(&psh) != -1);
/* Initialize the property sheet structure */
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | /* PSH_USEHICON */ PSH_USEICONID | PSH_NOAPPLYNOW;
if (pConInfo->ci.ConsoleTitle[0] != L'\0')
{
wcsncpy(szTitle, L"\"", sizeof(szTitle) / sizeof(szTitle[0]));
wcsncat(szTitle, pConInfo->ci.ConsoleTitle, sizeof(szTitle) / sizeof(szTitle[0]));
wcsncat(szTitle, L"\"", sizeof(szTitle) / sizeof(szTitle[0]));
}
else
{
wcscpy(szTitle, L"ReactOS Console");
}
psh.pszCaption = szTitle;
psh.hwndParent = pConInfo->hConsoleWindow;
psh.hInstance = hApplet;
// psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON));
psh.pszIcon = MAKEINTRESOURCE(IDC_CPLICON);
psh.nPages = 4;
psh.nStartPage = 0;
psh.ppsp = psp;
InitPropSheetPage(&psp[i++], IDD_PROPPAGEOPTIONS, (DLGPROC) OptionsProc, (LPARAM)pConInfo);
InitPropSheetPage(&psp[i++], IDD_PROPPAGEFONT, (DLGPROC) FontProc, (LPARAM)pConInfo);
InitPropSheetPage(&psp[i++], IDD_PROPPAGELAYOUT, (DLGPROC) LayoutProc, (LPARAM)pConInfo);
InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS, (DLGPROC) ColorsProc, (LPARAM)pConInfo);
return (PropertySheet(&psh) != -1);
}
/* Control Panel Callback */
LONG CALLBACK
CPlApplet(
HWND hwndCPl,
UINT uMsg,
LPARAM lParam1,
LPARAM lParam2)
CPlApplet(HWND hwndCPl,
UINT uMsg,
LPARAM lParam1,
LPARAM lParam2)
{
switch(uMsg)
{
case CPL_INIT:
switch (uMsg)
{
return TRUE;
case CPL_INIT:
return TRUE;
case CPL_GETCOUNT:
return NUM_APPLETS;
case CPL_INQUIRE:
{
CPLINFO *CPlInfo = (CPLINFO*)lParam2;
CPlInfo->idIcon = Applets[0].idIcon;
CPlInfo->idName = Applets[0].idName;
CPlInfo->idInfo = Applets[0].idDescription;
break;
}
case CPL_DBLCLK:
InitApplet(hwndCPl, uMsg, lParam1, lParam2);
break;
}
case CPL_GETCOUNT:
{
return NUM_APPLETS;
}
case CPL_INQUIRE:
{
CPLINFO *CPlInfo = (CPLINFO*)lParam2;
CPlInfo->idIcon = Applets[0].idIcon;
CPlInfo->idName = Applets[0].idName;
CPlInfo->idInfo = Applets[0].idDescription;
break;
}
case CPL_DBLCLK:
{
InitApplet(hwndCPl, uMsg, lParam1, lParam2);
break;
}
}
return FALSE;
return FALSE;
}
INT
WINAPI
DllMain(
HINSTANCE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved)
DllMain(HINSTANCE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
UNREFERENCED_PARAMETER(lpvReserved);
UNREFERENCED_PARAMETER(lpvReserved);
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
hApplet = hinstDLL;
break;
}
return TRUE;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
hApplet = hinstDLL;
break;
}
return TRUE;
}

View file

@ -2,7 +2,9 @@
#define CONSOLE_H__
#define WIN32_NO_STATUS
#include <stdarg.h>
#include <limits.h> // just for UINT_MAX in layout.c
#include <tchar.h>
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
@ -10,51 +12,23 @@
#include <wincon.h>
#include <commctrl.h>
#include <cpl.h>
#include <tchar.h>
#include <limits.h>
#include "resource.h"
/* Shared header with consrv.dll */
#include "settings.h"
typedef struct
{
int idIcon;
int idName;
int idDescription;
APPLET_PROC AppletProc;
int idIcon;
int idName;
int idDescription;
APPLET_PROC AppletProc;
} APPLET, *PAPPLET;
typedef struct TAGConsoleInfo
{
HWND hConsoleWindow;
WCHAR szProcessName[MAX_PATH];
BOOLEAN AppliedConfig;
DWORD UseRasterFonts;
DWORD FontSize;
DWORD FontWeight;
FONTSIGNATURE FontSignature;
DWORD CursorSize;
DWORD NumberOfHistoryBuffers;
DWORD HistoryBufferSize;
DWORD HistoryNoDup;
DWORD FullScreen;
DWORD QuickEdit;
DWORD InsertMode;
DWORD ScreenBuffer;
DWORD WindowSize;
DWORD WindowPosition;
DWORD ActiveStaticControl;
COLORREF ScreenText;
COLORREF ScreenBackground;
COLORREF PopupText;
COLORREF PopupBackground;
COLORREF Colors[16];
} ConsoleInfo, *PConsoleInfo;
void ApplyConsoleInfo(HWND hwndDlg, PConsoleInfo pConInfo);
void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo);
void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo);
#define PM_APPLY_CONSOLE_INFO (WM_APP + 100)
BOOL ApplyConsoleInfo(HWND hwndDlg, PCONSOLE_PROPS pConInfo);
VOID PaintConsole(LPDRAWITEMSTRUCT drawItem, PCONSOLE_PROPS pConInfo);
VOID PaintText(LPDRAWITEMSTRUCT drawItem, PCONSOLE_PROPS pConInfo);
// Globals
extern HINSTANCE hApplet;

View file

@ -6,51 +6,47 @@
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald@student.tugraz.at)
*/
#include "console.h"
INT_PTR
CALLBACK
FontProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
FontProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LPDRAWITEMSTRUCT drawItem;
PConsoleInfo pConInfo = (PConsoleInfo)GetWindowLongPtr(hwndDlg, DWLP_USER);
LPDRAWITEMSTRUCT drawItem;
PCONSOLE_PROPS pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
UNREFERENCED_PARAMETER(hwndDlg);
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(hwndDlg);
UNREFERENCED_PARAMETER(wParam);
switch (uMsg)
{
case WM_INITDIALOG:
{
pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
return TRUE;
}
case WM_DRAWITEM:
{
drawItem = (LPDRAWITEMSTRUCT)lParam;
if (drawItem->CtlID == IDC_STATIC_FONT_WINDOW_PREVIEW)
{
PaintConsole(drawItem, pConInfo);
}
else if (drawItem->CtlID == IDC_STATIC_SELECT_FONT_PREVIEW)
{
PaintText(drawItem, pConInfo);
}
return TRUE;
}
default:
{
break;
}
}
switch(uMsg)
{
case WM_INITDIALOG:
{
pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
return TRUE;
}
case WM_DRAWITEM:
{
drawItem = (LPDRAWITEMSTRUCT)lParam;
if (drawItem->CtlID == IDC_STATIC_FONT_WINDOW_PREVIEW)
{
PaintConsole(drawItem, pConInfo);
}
else if (drawItem->CtlID == IDC_STATIC_SELECT_FONT_PREVIEW)
{
PaintText(drawItem, pConInfo);
}
return TRUE;
}
default:
{
break;
}
}
return FALSE;
return FALSE;
}

View file

@ -70,8 +70,8 @@ BEGIN
EDITTEXT IDC_EDIT_SCREEN_BUFFER_HEIGHT, 203, 42, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP
CONTROL "", IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 42, 13, 14
GROUPBOX "Taille de la fenêtre", -1, 130, 65, 115, 47
LTEXT "&L&argeur :", -1, 140, 78, 39, 10
LTEXT "&H&auteur :", -1, 140, 95, 37, 10
LTEXT "L&argeur :", -1, 140, 78, 39, 10
LTEXT "Ha&uteur :", -1, 140, 95, 37, 10
EDITTEXT IDC_EDIT_WINDOW_SIZE_WIDTH, 203, 75, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP
CONTROL "", IDC_UPDOWN_WINDOW_SIZE_WIDTH, UPDOWN_CLASS, UDS_NOTHOUSANDS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | WS_GROUP, 238, 75, 13, 14
EDITTEXT IDC_EDIT_WINDOW_SIZE_HEIGHT, 203, 92, 35, 14, ES_RIGHT | ES_NUMBER | WS_GROUP

View file

@ -8,8 +8,36 @@
#include "console.h"
// TODO: Use ReactOS output
const TCHAR szPreviewText[] = \
_T("C:\\ReactOS> dir \n") \
_T("SYSTEM <DIR> 10-01-99 5:00a\n") \
_T("SYSTEM32 <DIR> 10-01-99 5:00a\n") \
_T("README TXT 26926 10-01-99 5:00a\n") \
_T("WINDOWS BMP 46080 10-01-99 5:00a\n") \
_T("NOTEPAD EXE 337232 10-01-99 5:00a\n") \
_T("CLOCK AVI 39594 10-01-99 5:00p\n") \
_T("WIN INI 7005 10-01-99 5:00a\n");
/*
const TCHAR szPreviewText[] = \
_T("C:\\ReactOS> dir \n") \
_T("02-18-13 05:00a <DIR> system \n") \
_T("02-18-13 05:00a <DIR> system32 \n") \
_T("02-18-13 05:00a 26926 readme.txt \n") \
_T("02-18-13 05:00a 3321856 explorer.exe\n") \
_T("02-18-13 05:00a 256 setuplog. \n") \
_T("02-18-13 05:00a 18736 vgafonts.cab\n") \
_T("02-18-13 05:00a 256 win.ini \n") \
_T("README TXT 26926 10-01-99 5:00a\n") \
_T("CLOCK AVI 39594 10-01-99 5:00p\n") \
_T("WIN INI 7005 10-01-99 5:00a\n");
*/
// IDS_SCREEN_TEXT "C:\\ReactOS> dir\nSYSTEM <DIR> 10-01-99 5:00\nSYSTEM32 <DIR> 10-01-99 5:00"
void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo)
VOID
PaintConsole(LPDRAWITEMSTRUCT drawItem,
PCONSOLE_PROPS pConInfo)
{
HBRUSH hBrush;
RECT cRect, fRect;
@ -22,7 +50,8 @@ void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo)
sizex = drawItem->rcItem.right - drawItem->rcItem.left;
sizey = drawItem->rcItem.bottom - drawItem->rcItem.top;
if (pConInfo->WindowPosition == UINT_MAX)
if ( pConInfo->ci.u.GuiInfo.WindowOrigin.x == MAXDWORD &&
pConInfo->ci.u.GuiInfo.WindowOrigin.y == MAXDWORD )
{
startx = sizex / 3;
starty = sizey / 3;
@ -69,33 +98,30 @@ void PaintConsole(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo)
FillRect(drawItem->hDC, &fRect, GetSysColorBrush(COLOR_SCROLLBAR));
/* Draw console background */
hBrush = CreateSolidBrush(pConInfo->ScreenBackground);
hBrush = CreateSolidBrush(pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)]);
SetRect(&fRect, startx + 3, starty + 6, cRect.right - 6, cRect.bottom - 3);
FillRect(drawItem->hDC, &fRect, hBrush);
DeleteObject((HGDIOBJ)hBrush);
}
void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo)
VOID PaintText(LPDRAWITEMSTRUCT drawItem,
PCONSOLE_PROPS pConInfo)
{
COLORREF pbkColor, ptColor;
COLORREF nbkColor, ntColor;
HBRUSH hBrush = NULL;
TCHAR szText[1024];
ZeroMemory(szText, sizeof(szText));
LoadString(hApplet, IDS_SCREEN_TEXT, szText, sizeof(szText) / sizeof(TCHAR));
if (drawItem->CtlID == IDC_STATIC_SCREEN_COLOR)
{
nbkColor = pConInfo->ScreenBackground;
nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)];
hBrush = CreateSolidBrush(nbkColor);
ntColor = pConInfo->ScreenText;
ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.ScreenAttrib)];
}
else if (drawItem->CtlID == IDC_STATIC_POPUP_COLOR)
{
nbkColor = pConInfo->PopupBackground;
nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib)];
hBrush = CreateSolidBrush(nbkColor);
ntColor = pConInfo->PopupText;
ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.PopupAttrib)];
}
if (!hBrush)
@ -104,15 +130,10 @@ void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo)
}
FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
if (ntColor == nbkColor)
{
/* Text has same color -> invisible */
return;
}
ptColor = SetTextColor(drawItem->hDC, ntColor);
pbkColor = SetBkColor(drawItem->hDC, nbkColor);
DrawText(drawItem->hDC, szText, _tcslen(szText), &drawItem->rcItem, 0);
DrawText(drawItem->hDC, szPreviewText, _tcslen(szPreviewText), &drawItem->rcItem, 0);
SetTextColor(drawItem->hDC, ptColor);
SetBkColor(drawItem->hDC, pbkColor);
DeleteObject((HGDIOBJ)hBrush);
@ -121,47 +142,48 @@ void PaintText(LPDRAWITEMSTRUCT drawItem, PConsoleInfo pConInfo)
INT_PTR
CALLBACK
LayoutProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
LayoutProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LPNMUPDOWN lpnmud;
LPPSHNOTIFY lppsn;
PConsoleInfo pConInfo = (PConsoleInfo)GetWindowLongPtr(hwndDlg, DWLP_USER);
PCONSOLE_PROPS pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
UNREFERENCED_PARAMETER(hwndDlg);
UNREFERENCED_PARAMETER(wParam);
switch(uMsg)
switch (uMsg)
{
case WM_INITDIALOG:
{
DWORD xres, yres;
HDC hDC;
pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam;
pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, HIWORD(pConInfo->ScreenBuffer), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, LOWORD(pConInfo->ScreenBuffer), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, HIWORD(pConInfo->WindowSize), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, LOWORD(pConInfo->WindowSize), FALSE);
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, pConInfo->ci.ScreenBufferSize.Y, FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, pConInfo->ci.ScreenBufferSize.X, FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, pConInfo->ci.ConsoleSize.Y, FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, pConInfo->ci.ConsoleSize.X, FALSE);
hDC = GetDC(NULL);
xres = GetDeviceCaps(hDC, HORZRES);
yres = GetDeviceCaps(hDC, VERTRES);
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(xres, 0));
SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), UDM_SETRANGE, 0, (LPARAM)MAKELONG(yres, 0));
if (pConInfo->WindowPosition != MAXDWORD)
if ( pConInfo->ci.u.GuiInfo.WindowOrigin.x != MAXDWORD &&
pConInfo->ci.u.GuiInfo.WindowOrigin.y != MAXDWORD )
{
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, LOWORD(pConInfo->WindowPosition), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, HIWORD(pConInfo->WindowPosition), FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, pConInfo->ci.u.GuiInfo.WindowOrigin.x, FALSE);
SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, pConInfo->ci.u.GuiInfo.WindowOrigin.y, FALSE);
}
else
{
@ -281,16 +303,16 @@ LayoutProc(
}
}
pConInfo->ScreenBuffer = MAKELONG(swidth, sheight);
pConInfo->WindowSize = MAKELONG(wwidth, wheight);
pConInfo->WindowPosition = MAKELONG(left, top);
pConInfo->ci.ScreenBufferSize = (COORD){swidth, sheight};
pConInfo->ci.ConsoleSize = (COORD){wwidth, wheight};
pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){left, top};
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
switch (LOWORD(wParam))
{
case IDC_EDIT_SCREEN_BUFFER_WIDTH:
case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
@ -328,11 +350,9 @@ LayoutProc(
wheight = sheight;
}
pConInfo->ScreenBuffer = MAKELONG(swidth, sheight);
pConInfo->WindowSize = MAKELONG(wwidth, wheight);
pConInfo->WindowPosition = MAKELONG(left, top);
pConInfo->ci.ScreenBufferSize = (COORD){swidth, sheight};
pConInfo->ci.ConsoleSize = (COORD){wwidth, wheight};
pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){left, top};
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
@ -347,7 +367,7 @@ LayoutProc(
left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
pConInfo->WindowPosition = MAKELONG(left, top);
pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){left, top};
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), TRUE);
@ -356,7 +376,7 @@ LayoutProc(
}
else if (res == BST_UNCHECKED)
{
pConInfo->WindowPosition = UINT_MAX;
pConInfo->ci.u.GuiInfo.WindowOrigin = (POINT){UINT_MAX, UINT_MAX};
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE);

View file

@ -10,29 +10,27 @@
static
void
UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo);
UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo);
INT_PTR
CALLBACK
OptionsProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
OptionsProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PConsoleInfo pConInfo;
PCONSOLE_PROPS pConInfo;
LRESULT lResult;
HWND hDlgCtrl;
LPPSHNOTIFY lppsn;
pConInfo = (PConsoleInfo) GetWindowLongPtr(hwndDlg, DWLP_USER);
pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch(uMsg)
switch (uMsg)
{
case WM_INITDIALOG:
{
pConInfo = (PConsoleInfo) ((LPPROPSHEETPAGE)lParam)->lParam;
pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
UpdateDialogElements(hwndDlg, pConInfo);
return TRUE;
@ -47,25 +45,24 @@ OptionsProc(
if (lppsn->hdr.code == UDN_DELTAPOS)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_BUFFER_SIZE);
pConInfo->HistoryBufferSize = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0));
pConInfo->ci.HistoryBufferSize = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0));
hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_NUM_BUFFER);
pConInfo->NumberOfHistoryBuffers = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0));
pConInfo->ci.NumberOfHistoryBuffers = LOWORD(SendMessage(hDlgCtrl, UDM_GETPOS, 0, 0));
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
else if (lppsn->hdr.code == PSN_APPLY)
{
if (!pConInfo->AppliedConfig)
{
ApplyConsoleInfo(hwndDlg, pConInfo);
return ApplyConsoleInfo(hwndDlg, pConInfo);
}
else
{
/* Options have already been applied */
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
return TRUE;
}
return TRUE;
}
break;
}
@ -75,35 +72,35 @@ OptionsProc(
{
break;
}
switch(LOWORD(wParam))
switch (LOWORD(wParam))
{
case IDC_RADIO_SMALL_CURSOR:
{
pConInfo->CursorSize = 0x0;
pConInfo->ci.CursorSize = 0;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_RADIO_MEDIUM_CURSOR:
{
pConInfo->CursorSize = 0x32;
pConInfo->ci.CursorSize = 50;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_RADIO_LARGE_CURSOR:
{
pConInfo->CursorSize = 0x64;
pConInfo->ci.CursorSize = 100;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_RADIO_DISPLAY_WINDOW:
{
pConInfo->FullScreen = FALSE;
pConInfo->ci.FullScreen = FALSE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_RADIO_DISPLAY_FULL:
{
pConInfo->FullScreen = TRUE;
pConInfo->ci.FullScreen = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
@ -112,12 +109,12 @@ OptionsProc(
lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
if (lResult == BST_CHECKED)
{
pConInfo->QuickEdit = FALSE;
pConInfo->ci.QuickEdit = FALSE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
}
else if (lResult == BST_UNCHECKED)
{
pConInfo->QuickEdit = TRUE;
pConInfo->ci.QuickEdit = TRUE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
}
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
@ -128,12 +125,12 @@ OptionsProc(
lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
if (lResult == BST_CHECKED)
{
pConInfo->InsertMode = FALSE;
pConInfo->ci.InsertMode = FALSE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
}
else if (lResult == BST_UNCHECKED)
{
pConInfo->InsertMode = TRUE;
pConInfo->ci.InsertMode = TRUE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
}
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
@ -144,12 +141,12 @@ OptionsProc(
lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
if (lResult == BST_CHECKED)
{
pConInfo->HistoryNoDup = FALSE;
pConInfo->ci.HistoryNoDup = FALSE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
}
else if (lResult == BST_UNCHECKED)
{
pConInfo->HistoryNoDup = TRUE;
pConInfo->ci.HistoryNoDup = TRUE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
}
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
@ -169,13 +166,13 @@ OptionsProc(
static
void
UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo)
UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo)
{
HWND hDlgCtrl;
TCHAR szBuffer[MAX_PATH];
/* Update cursor size */
if ( pConInfo->CursorSize == 0)
if (pConInfo->ci.CursorSize == 0)
{
/* Small cursor */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
@ -186,7 +183,7 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo)
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else if ( pConInfo->CursorSize == 0x32 )
else if (pConInfo->ci.CursorSize == 50)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
@ -196,7 +193,7 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo)
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else if ( pConInfo->CursorSize == 0x64 )
else if (pConInfo->ci.CursorSize == 100)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
@ -211,27 +208,25 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo)
hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_NUM_BUFFER);
SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG((short)999, (short)1));
hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_NUM_BUFFER);
_stprintf(szBuffer, _T("%d"), pConInfo->NumberOfHistoryBuffers);
_stprintf(szBuffer, _T("%d"), pConInfo->ci.NumberOfHistoryBuffers);
SendMessage(hDlgCtrl, WM_SETTEXT, 0, (LPARAM)szBuffer);
/* Update buffer size */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_BUFFER_SIZE);
SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG((short)999, (short)1));
hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_BUFFER_SIZE);
_stprintf(szBuffer, _T("%d"), pConInfo->HistoryBufferSize);
_stprintf(szBuffer, _T("%d"), pConInfo->ci.HistoryBufferSize);
SendMessage(hDlgCtrl, WM_SETTEXT, 0, (LPARAM)szBuffer);
/* Update discard duplicates */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_DISCARD_DUPLICATES);
if ( pConInfo->HistoryNoDup )
if (pConInfo->ci.HistoryNoDup)
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
else
SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0);
/* Update full/window screen */
if ( pConInfo->FullScreen )
if (pConInfo->ci.FullScreen)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
@ -250,14 +245,14 @@ UpdateDialogElements(HWND hwndDlg, PConsoleInfo pConInfo)
/* Update quick edit */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_QUICK_EDIT);
if ( pConInfo->QuickEdit )
if (pConInfo->ci.QuickEdit)
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
else
SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0);
/* Update insert mode */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_INSERT_MODE);
if ( pConInfo->InsertMode )
if (pConInfo->ci.InsertMode)
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
else
SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0);

View file

@ -849,7 +849,7 @@ AllocConsole(VOID)
return FALSE;
}
CaptureBuffer = CsrAllocateCaptureBuffer(2, sizeof(CONSOLE_PROPS) +
CaptureBuffer = CsrAllocateCaptureBuffer(2, sizeof(CONSOLE_START_INFO) +
(MAX_PATH + 1) * sizeof(WCHAR));
if (CaptureBuffer == NULL)
{
@ -859,23 +859,24 @@ AllocConsole(VOID)
}
CsrAllocateMessagePointer(CaptureBuffer,
sizeof(CONSOLE_PROPS),
(PVOID*)&AllocConsoleRequest->ConsoleProps);
sizeof(CONSOLE_START_INFO),
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
CsrAllocateMessagePointer(CaptureBuffer,
(MAX_PATH + 1) * sizeof(WCHAR),
(PVOID*)&AllocConsoleRequest->AppPath);
/** Copied from BasepInitConsole **********************************************/
InitConsoleProps(AllocConsoleRequest->ConsoleProps);
InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo);
Length = min(MAX_PATH + 1, Parameters->ImagePathName.Length / sizeof(WCHAR));
Length = min(MAX_PATH, Parameters->ImagePathName.Length / sizeof(WCHAR));
wcsncpy(AllocConsoleRequest->AppPath, Parameters->ImagePathName.Buffer, Length);
AllocConsoleRequest->AppPath[Length] = L'\0';
/******************************************************************************/
AllocConsoleRequest->Console = NULL;
AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
AllocConsoleRequest->PropDispatcher = PropDialogHandler;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
CaptureBuffer,
@ -2004,6 +2005,7 @@ AttachConsole(DWORD dwProcessId)
AttachConsoleRequest->ProcessId = dwProcessId;
AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
AttachConsoleRequest->PropDispatcher = PropDialogHandler;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,

View file

@ -10,6 +10,9 @@
#include <k32.h>
// For Control Panel Applet
#include <cpl.h>
#define NDEBUG
#include <debug.h>
@ -19,54 +22,133 @@
RTL_CRITICAL_SECTION ConsoleLock;
BOOL ConsoleInitialized = FALSE;
extern DWORD WINAPI ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
extern HANDLE InputWaitHandle;
static HMODULE ConsoleLibrary = NULL;
static BOOL AlreadyDisplayingProps = FALSE;
#define WIN_OBJ_DIR L"\\Windows"
#define SESSION_DIR L"\\Sessions"
/* FUNCTIONS ******************************************************************/
DWORD
WINAPI
PropDialogHandler(IN LPVOID lpThreadParameter)
{
// NOTE: lpThreadParameter corresponds to the client shared section handle.
APPLET_PROC CPLFunc;
/*
* Do not launch more than once the console property dialog applet,
* or (albeit less probable), if we are not initialized.
*/
if (!ConsoleInitialized || AlreadyDisplayingProps)
{
/* Close the associated client shared section handle if needed */
if (lpThreadParameter)
{
CloseHandle((HANDLE)lpThreadParameter);
}
return STATUS_UNSUCCESSFUL;
}
AlreadyDisplayingProps = TRUE;
/* Load the Control Applet if needed */
if (ConsoleLibrary == NULL)
{
WCHAR szBuffer[MAX_PATH];
GetWindowsDirectoryW(szBuffer, MAX_PATH);
wcscat(szBuffer, L"\\system32\\console.dll");
ConsoleLibrary = LoadLibraryW(szBuffer);
if (ConsoleLibrary == NULL)
{
DPRINT1("Failed to load console.dll");
AlreadyDisplayingProps = FALSE;
return STATUS_UNSUCCESSFUL;
}
}
/* Load its main function */
CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleLibrary, "CPlApplet");
if (CPLFunc == NULL)
{
DPRINT("Error: Console.dll misses CPlApplet export\n");
AlreadyDisplayingProps = FALSE;
return STATUS_UNSUCCESSFUL;
}
if (CPLFunc(NULL, CPL_INIT, 0, 0) == FALSE)
{
DPRINT("Error: failed to initialize console.dll\n");
AlreadyDisplayingProps = FALSE;
return STATUS_UNSUCCESSFUL;
}
if (CPLFunc(NULL, CPL_GETCOUNT, 0, 0) != 1)
{
DPRINT("Error: console.dll returned unexpected CPL count\n");
AlreadyDisplayingProps = FALSE;
return STATUS_UNSUCCESSFUL;
}
CPLFunc(NULL, CPL_DBLCLK, (LPARAM)lpThreadParameter, 0);
CPLFunc(NULL, CPL_EXIT , 0, 0);
AlreadyDisplayingProps = FALSE;
return STATUS_SUCCESS;
}
VOID
InitConsoleProps(IN OUT PCONSOLE_PROPS ConsoleProps)
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo)
{
STARTUPINFOW si;
GetStartupInfoW(&si);
ConsoleProps->dwStartupFlags = si.dwFlags;
ConsoleStartInfo->dwStartupFlags = si.dwFlags;
if (si.dwFlags & STARTF_USEFILLATTRIBUTE)
{
ConsoleProps->FillAttribute = si.dwFillAttribute;
ConsoleStartInfo->FillAttribute = si.dwFillAttribute;
}
if (si.dwFlags & STARTF_USECOUNTCHARS)
{
ConsoleProps->ScreenBufferSize.X = (SHORT)(si.dwXCountChars);
ConsoleProps->ScreenBufferSize.Y = (SHORT)(si.dwYCountChars);
ConsoleStartInfo->ScreenBufferSize.X = (SHORT)(si.dwXCountChars);
ConsoleStartInfo->ScreenBufferSize.Y = (SHORT)(si.dwYCountChars);
}
if (si.dwFlags & STARTF_USESHOWWINDOW)
{
ConsoleProps->ShowWindow = si.wShowWindow;
ConsoleStartInfo->ShowWindow = si.wShowWindow;
}
if (si.dwFlags & STARTF_USEPOSITION)
{
ConsoleProps->ConsoleWindowOrigin.x = (LONG)(si.dwX);
ConsoleProps->ConsoleWindowOrigin.y = (LONG)(si.dwY);
ConsoleStartInfo->ConsoleWindowOrigin.x = (LONG)(si.dwX);
ConsoleStartInfo->ConsoleWindowOrigin.y = (LONG)(si.dwY);
}
if (si.dwFlags & STARTF_USESIZE)
{
ConsoleProps->ConsoleWindowSize.cx = (LONG)(si.dwXSize);
ConsoleProps->ConsoleWindowSize.cy = (LONG)(si.dwYSize);
ConsoleStartInfo->ConsoleWindowSize.cx = (LONG)(si.dwXSize);
ConsoleStartInfo->ConsoleWindowSize.cy = (LONG)(si.dwYSize);
}
/*
if (si.dwFlags & STARTF_RUNFULLSCREEN)
{
}
*/
if (si.lpTitle)
{
wcsncpy(ConsoleProps->ConsoleTitle, si.lpTitle, MAX_PATH + 1);
wcsncpy(ConsoleStartInfo->ConsoleTitle, si.lpTitle, MAX_PATH + 1);
}
else
{
ConsoleProps->ConsoleTitle[0] = L'\0';
ConsoleStartInfo->ConsoleTitle[0] = L'\0';
}
}
@ -102,7 +184,7 @@ BasepInitConsole(VOID)
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.ConsoleStartInfo.ConsoleTitle[0] = L'\0';
ConnectInfo.AppPath[0] = L'\0';
}
else
@ -110,9 +192,9 @@ BasepInitConsole(VOID)
SIZE_T Length = 0;
LPCWSTR ExeName;
InitConsoleProps(&ConnectInfo.ConsoleProps);
InitConsoleInfo(&ConnectInfo.ConsoleStartInfo);
Length = min(sizeof(ConnectInfo.AppPath) / sizeof(ConnectInfo.AppPath[0]),
Length = min(sizeof(ConnectInfo.AppPath) / sizeof(ConnectInfo.AppPath[0]) - 1,
Parameters->ImagePathName.Length / sizeof(WCHAR));
wcsncpy(ConnectInfo.AppPath, Parameters->ImagePathName.Buffer, Length);
ConnectInfo.AppPath[Length] = L'\0';
@ -143,7 +225,7 @@ BasepInitConsole(VOID)
/* We'll get the real one soon */
DPRINT("Creating new invisible console\n");
Parameters->ConsoleHandle = NULL;
ConnectInfo.ConsoleProps.ShowWindow = SW_HIDE;
ConnectInfo.ConsoleStartInfo.ShowWindow = SW_HIDE;
}
else
{
@ -158,10 +240,13 @@ BasepInitConsole(VOID)
/* Now use the proper console handle */
ConnectInfo.Console = Parameters->ConsoleHandle;
/* Initialize Console Ctrl Handler */
/* Initialize the Console Ctrl Handler */
InitConsoleCtrlHandling();
ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher;
/* Initialize the Property Dialog Handler */
ConnectInfo.PropDispatcher = PropDialogHandler;
/* Setup the right Object Directory path */
if (!SessionId)
{
@ -233,6 +318,8 @@ BasepUninitConsole(VOID)
/* Delete our critical section if we were initialized */
if (ConsoleInitialized == TRUE)
{
if (ConsoleLibrary) FreeLibrary(ConsoleLibrary);
ConsoleInitialized = FALSE;
RtlDeleteCriticalSection(&ConsoleLock);
}

View file

@ -26,6 +26,12 @@ BasepUninitConsole(VOID);
VOID WINAPI
InitConsoleCtrlHandling(VOID);
DWORD WINAPI
ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
DWORD WINAPI
PropDialogHandler(IN LPVOID lpThreadParameter);
HANDLE WINAPI
DuplicateConsoleHandle(HANDLE hConsole,
DWORD dwDesiredAccess,
@ -45,7 +51,7 @@ HANDLE FASTCALL
TranslateStdHandle(HANDLE hHandle);
VOID
InitConsoleProps(IN OUT PCONSOLE_PROPS ConsoleProps);
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo);
LPCWSTR
IntCheckForConsoleFileName(IN LPCWSTR pszName,

View file

@ -112,7 +112,7 @@ typedef enum _CONSRV_API_NUMBER
} CONSRV_API_NUMBER, *PCONSRV_API_NUMBER;
typedef struct _CONSOLE_PROPS
typedef struct _CONSOLE_START_INFO
{
DWORD dwStartupFlags;
DWORD FillAttribute;
@ -122,14 +122,14 @@ typedef struct _CONSOLE_PROPS
SIZE ConsoleWindowSize;
// UNICODE_STRING ConsoleTitle;
WCHAR ConsoleTitle[MAX_PATH + 1];
} CONSOLE_PROPS, *PCONSOLE_PROPS;
} CONSOLE_START_INFO, *PCONSOLE_START_INFO;
typedef struct _CONSOLE_CONNECTION_INFO
{
BOOL ConsoleNeeded; // Used for GUI apps only.
/* Adapted from CONSOLE_ALLOCCONSOLE */
CONSOLE_PROPS ConsoleProps;
CONSOLE_START_INFO ConsoleStartInfo;
WCHAR AppPath[MAX_PATH + 1];
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
@ -138,13 +138,10 @@ typedef struct _CONSOLE_CONNECTION_INFO
HANDLE ErrorHandle;
HANDLE InputWaitHandle;
LPTHREAD_START_ROUTINE CtrlDispatcher;
LPTHREAD_START_ROUTINE PropDispatcher;
} CONSOLE_CONNECTION_INFO, *PCONSOLE_CONNECTION_INFO;
#define CONSOLE_INPUT_MODE_VALID 0x0f
#define CONSOLE_OUTPUT_MODE_VALID 0x03
typedef struct
{
USHORT nMaxIds;
@ -182,8 +179,8 @@ typedef struct
typedef struct
{
PCONSOLE_PROPS ConsoleProps;
LPWSTR AppPath;
PCONSOLE_START_INFO ConsoleStartInfo;
LPWSTR AppPath; // Length: MAX_PATH + 1
HANDLE Console; // ConsoleHandle // In fact, it is a PCSRSS_CONSOLE <-- correct that !!
HANDLE InputHandle;
@ -191,6 +188,7 @@ typedef struct
HANDLE ErrorHandle;
HANDLE InputWaitHandle;
LPTHREAD_START_ROUTINE CtrlDispatcher;
LPTHREAD_START_ROUTINE PropDispatcher;
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
typedef struct
@ -202,6 +200,7 @@ typedef struct
HANDLE ErrorHandle;
HANDLE InputWaitHandle;
LPTHREAD_START_ROUTINE CtrlDispatcher;
LPTHREAD_START_ROUTINE PropDispatcher;
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
typedef struct

View file

@ -1,8 +1,7 @@
include_directories(
${REACTOS_SOURCE_DIR}/include/reactos/subsys
${REACTOS_SOURCE_DIR}/win32ss/include
${REACTOS_SOURCE_DIR}/dll/cpl/console)
${REACTOS_SOURCE_DIR}/win32ss/include)
spec2def(consrv.dll consrv.spec)
@ -15,6 +14,7 @@ list(APPEND SOURCE
handle.c
init.c
lineinput.c
settings.c
tuiconsole.c
consrv.rc
${CMAKE_CURRENT_BINARY_DIR}/consrv.def)

View file

@ -10,7 +10,6 @@
#include "consrv.h"
#include "conio.h"
#include "tuiconsole.h"
#define NDEBUG
#include <debug.h>
@ -132,7 +131,7 @@ ConioGetShiftState(PBYTE KeyState)
}
VOID WINAPI
ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
ConioProcessKey(PCONSOLE Console, MSG* msg)
{
static BYTE KeyState[256] = { 0 };
/* MSDN mentions that you should use the last virtual key code received
@ -149,6 +148,12 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
BOOLEAN Fake; // synthesized, not a real event
BOOLEAN NotChar; // message should not be used to return a character
if (NULL == Console)
{
DPRINT1("No Active Console!\n");
return;
}
RepeatCount = 1;
VirtualScanCode = (msg->lParam >> 16) & 0xff;
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
@ -186,39 +191,13 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
if (TextMode)
if (ConioProcessKeyCallback(Console,
msg,
KeyState[VK_MENU],
ShiftState,
VirtualKeyCode,
Down))
{
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
&& VK_TAB == VirtualKeyCode)
{
if (Down)
{
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
}
return;
}
else if (VK_MENU == VirtualKeyCode && ! Down)
{
if (TuiSwapConsole(0))
{
return;
}
}
}
else
{
if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyState[VK_MENU] & 0x80) &&
(VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE))
{
DefWindowProcW(msg->hwnd, msg->message, msg->wParam, msg->lParam);
return;
}
}
if (NULL == Console)
{
DPRINT1("No Active Console!\n");
return;
}
@ -226,8 +205,7 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
if (NotChar)
LastVirtualKey = msg->wParam;
if (NotChar) LastVirtualKey = msg->wParam;
DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n",
Down ? "down" : "up ",
@ -240,8 +218,7 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
(UnicodeChar >= L' ') ? UnicodeChar : L'.',
ShiftState);
if (Fake)
return;
if (Fake) return;
/* process Ctrl-C and Ctrl-Break */
if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
@ -282,22 +259,22 @@ ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode)
if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
{
/* only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1)
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->MaxY - 1) %
Console->ActiveBuffer->MaxY;
Console->ActiveBuffer->CurrentY++;
Console->ActiveBuffer->ScreenBufferSize.Y - 1) %
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y++;
}
}
else
{
/* only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CurrentY != 0)
if (Console->ActiveBuffer->CursorPosition.Y != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->MaxY;
Console->ActiveBuffer->CurrentY--;
Console->ActiveBuffer->ScreenBufferSize.Y;
Console->ActiveBuffer->CursorPosition.Y--;
}
}
ConioDrawConsole(Console);

View file

@ -10,7 +10,11 @@
#define CSR_DEFAULT_CURSOR_SIZE 25
#define CURSOR_BLINK_TIME 500
#define DEFAULT_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
/* Default attributes */
#define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \
BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
#ifndef WM_APP
#define WM_APP 0x8000
@ -42,14 +46,21 @@ typedef struct _CONSOLE_SCREEN_BUFFER
Object_t Header; /* Object header */
LIST_ENTRY ListEntry; /* Entry in console's list of buffers */
BYTE *Buffer; /* Pointer to screen buffer */
USHORT MaxX, MaxY; /* Size of the entire scrollback buffer */
BYTE *Buffer; /* CHAR_INFO */ /* Pointer to screen buffer */
COORD ScreenBufferSize; /* Size of this screen buffer */
COORD CursorPosition; /* Current cursor position */
USHORT ShowX, ShowY; /* Beginning offset for the actual display area */
ULONG CurrentX; /* Current X cursor position */
ULONG CurrentY; /* Current Y cursor position */
WORD DefaultAttrib; /* Default char attribute */
USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */
CONSOLE_CURSOR_INFO CursorInfo;
BOOLEAN CursorBlinkOn;
BOOLEAN ForceCursorOff;
ULONG CursorSize;
CONSOLE_CURSOR_INFO CursorInfo; // FIXME: Keep this member or not ??
WORD ScreenDefaultAttrib; /* Default screen char attribute */
WORD PopupDefaultAttrib; /* Default popup char attribute */
USHORT Mode;
} CONSOLE_SCREEN_BUFFER, *PCONSOLE_SCREEN_BUFFER;
@ -57,10 +68,12 @@ typedef struct _CONSOLE_INPUT_BUFFER
{
Object_t Header; /* Object header */
ULONG InputBufferSize; /* Size of this input buffer */
LIST_ENTRY InputEvents; /* List head for input event queue */
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */
WORD Mode; /* Console Input Buffer mode flags */
USHORT Mode; /* Console Input Buffer mode flags */
} CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
typedef struct ConsoleInput_t
@ -92,6 +105,8 @@ typedef struct _CONSOLE
BOOLEAN LineInsertToggle; /* Replace character over cursor instead of inserting */
ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */
BOOLEAN QuickEdit;
BOOLEAN InsertMode;
UINT CodePage;
UINT OutputCodePage;
@ -105,21 +120,27 @@ typedef struct _CONSOLE
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */
/* BOOLEAN */ ULONG FullScreen; // Give the type of console: GUI (windowed) or TUI (fullscreen)
/**************************** Aliases and Histories ***************************/
struct _ALIAS_HEADER *Aliases;
LIST_ENTRY HistoryBuffers;
UINT HistoryBufferSize; /* Size for newly created history buffers */
UINT NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */
ULONG HistoryBufferSize; /* Size for newly created history buffers */
ULONG NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
/****************************** GUI-related data ******************************/
/******************************* Common UI data *******************************/
UNICODE_STRING OriginalTitle; /* Original title of console, the one when the console leader is launched. It is always NULL-terminated */
UNICODE_STRING Title; /* Title of console. It is always NULL-terminated */
COORD Size; /* Size of the console (different of the size of the screen buffer */
COLORREF Colors[16]; /* Colour palette */
/****************************** GUI-related data ******************************/
HWND hWindow; /* Handle to the console's window */
HICON hIcon; /* Handle to its icon (used when freeing) */
HICON hIconSm;
COORD Size;
PVOID GuiData;
PVOID GuiData; /* PGUI_CONSOLE_DATA */
} CONSOLE, *PCONSOLE;
@ -149,6 +170,7 @@ typedef struct _CONSOLE_VTBL
VOID (WINAPI *CleanupConsole)(PCONSOLE Console);
BOOL (WINAPI *ChangeIcon)(PCONSOLE Console, HICON hWindowIcon);
NTSTATUS (WINAPI *ResizeBuffer)(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size);
BOOL (WINAPI *ProcessKeyCallback)(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down);
} CONSOLE_VTBL, *PCONSOLE_VTBL;
/* CONSOLE_SELECTION_INFO dwFlags values */
@ -178,13 +200,14 @@ typedef struct _CONSOLE_VTBL
#define ConioCleanupConsole(Console) (Console)->Vtbl->CleanupConsole(Console)
#define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon((Console), (hWindowIcon))
#define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer((Console), (Buff), (Size))
#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) (Console)->Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
/* console.c */
VOID WINAPI ConSrvDeleteConsole(PCONSOLE Console);
VOID WINAPI ConSrvInitConsoleSupport(VOID);
NTSTATUS WINAPI ConSrvInitConsole(OUT PCONSOLE* NewConsole,
IN LPCWSTR AppPath,
IN OUT PCONSOLE_PROPS ConsoleProps,
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
IN PCSR_PROCESS ConsoleLeaderProcess);
VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags);
@ -202,7 +225,7 @@ VOID FASTCALL ConSrvConsoleCtrlEventTimeout(DWORD Event,
(Access), (LockConsole), CONIO_INPUT_BUFFER_MAGIC)
#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \
ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
void WINAPI ConioProcessKey(MSG *msg, PCONSOLE Console, BOOL TextMode);
VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg);
/* conoutput.c */
#define ConioRectHeight(Rect) \
@ -221,7 +244,11 @@ PBYTE FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buf, ULONG X, ULONG Y)
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
NTSTATUS FASTCALL ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
CHAR *Buffer, DWORD Length, BOOL Attrib);
NTSTATUS FASTCALL ConSrvInitConsoleScreenBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buffer);
NTSTATUS FASTCALL ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console,
OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN COORD ScreenBufferSize,
IN USHORT ScreenAttrib,
IN USHORT PopupAttrib);
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console, DWORD Scale);

View file

@ -42,52 +42,72 @@ do { \
PBYTE FASTCALL
ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
{
return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->MaxY) * Buff->MaxX + X)];
return &Buff->Buffer[2 * (((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X)];
}
static VOID FASTCALL
ClearLineBuffer(PCONSOLE_SCREEN_BUFFER Buff)
{
PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CurrentY);
PBYTE Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
UINT Pos;
for (Pos = 0; Pos < Buff->MaxX; Pos++)
for (Pos = 0; Pos < Buff->ScreenBufferSize.X; Pos++)
{
/* Fill the cell */
*Ptr++ = ' ';
*Ptr++ = Buff->DefaultAttrib;
*Ptr++ = Buff->ScreenDefaultAttrib;
}
}
NTSTATUS FASTCALL
ConSrvInitConsoleScreenBuffer(PCONSOLE Console,
PCONSOLE_SCREEN_BUFFER Buffer)
ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console,
OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN COORD ScreenBufferSize,
IN USHORT ScreenAttrib,
IN USHORT PopupAttrib)
{
DPRINT1("ConSrvInitConsoleScreenBuffer Size X %d Size Y %d\n", Buffer->MaxX, Buffer->MaxY);
DPRINT("ConSrvCreateScreenBuffer\n");
Buffer->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
Buffer->Header.Console = Console;
Buffer->Header.HandleCount = 0;
Buffer->ShowX = 0;
Buffer->ShowY = 0;
Buffer->VirtualY = 0;
Buffer->Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, Buffer->MaxX * Buffer->MaxY * 2);
if (NULL == Buffer->Buffer)
if (Console == NULL || Buffer == NULL)
return STATUS_INVALID_PARAMETER;
*Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER));
if (NULL == *Buffer)
{
DPRINT1("ConSrvInitConsoleScreenBuffer - D'oh!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
Buffer->DefaultAttrib = DEFAULT_ATTRIB;
/* initialize buffer to be empty with default attributes */
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
{
ClearLineBuffer(Buffer);
}
Buffer->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
Buffer->CurrentX = 0;
Buffer->CurrentY = 0;
InsertHeadList(&Console->BufferList, &Buffer->ListEntry);
(*Buffer)->Header.Type = CONIO_SCREEN_BUFFER_MAGIC;
(*Buffer)->Header.Console = Console;
(*Buffer)->Header.HandleCount = 0;
(*Buffer)->ScreenBufferSize = ScreenBufferSize;
(*Buffer)->Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, (*Buffer)->ScreenBufferSize.X * (*Buffer)->ScreenBufferSize.Y * 2);
if (NULL == (*Buffer)->Buffer)
{
RtlFreeHeap(ConSrvHeap, 0, *Buffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
(*Buffer)->ShowX = 0;
(*Buffer)->ShowY = 0;
(*Buffer)->VirtualY = 0;
// FIXME: !!
(*Buffer)->CursorInfo.bVisible = TRUE;
// (*Buffer)->CursorInfo.dwSize = ConsoleInfo->CursorSize;
(*Buffer)->ScreenDefaultAttrib = ScreenAttrib;
(*Buffer)->PopupDefaultAttrib = PopupAttrib;
/* initialize buffer to be empty with default attributes */
for ((*Buffer)->CursorPosition.Y = 0 ; (*Buffer)->CursorPosition.Y < (*Buffer)->ScreenBufferSize.Y; (*Buffer)->CursorPosition.Y++)
{
ClearLineBuffer(*Buffer);
}
(*Buffer)->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
(*Buffer)->CursorPosition = (COORD){0, 0};
InsertHeadList(&Console->BufferList, &(*Buffer)->ListEntry);
return STATUS_SUCCESS;
}
@ -95,10 +115,10 @@ static VOID FASTCALL
ConioNextLine(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *ScrolledLines)
{
/* If we hit bottom, slide the viewable screen */
if (++Buff->CurrentY == Buff->MaxY)
if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
{
Buff->CurrentY--;
if (++Buff->VirtualY == Buff->MaxY)
Buff->CursorPosition.Y--;
if (++Buff->VirtualY == Buff->ScreenBufferSize.Y)
{
Buff->VirtualY = 0;
}
@ -110,8 +130,8 @@ ConioNextLine(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *Scrolle
}
}
UpdateRect->Left = 0;
UpdateRect->Right = Buff->MaxX - 1;
UpdateRect->Bottom = Buff->CurrentY;
UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
UpdateRect->Bottom = Buff->CursorPosition.Y;
}
NTSTATUS FASTCALL
@ -124,12 +144,12 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
LONG CursorStartX, CursorStartY;
UINT ScrolledLines;
CursorStartX = Buff->CurrentX;
CursorStartY = Buff->CurrentY;
UpdateRect.Left = Buff->MaxX;
UpdateRect.Top = Buff->CurrentY;
CursorStartX = Buff->CursorPosition.X;
CursorStartY = Buff->CursorPosition.Y;
UpdateRect.Left = Buff->ScreenBufferSize.X;
UpdateRect.Top = Buff->CursorPosition.Y;
UpdateRect.Right = -1;
UpdateRect.Bottom = Buff->CurrentY;
UpdateRect.Bottom = Buff->CursorPosition.Y;
ScrolledLines = 0;
for (i = 0; i < Length; i++)
@ -143,15 +163,15 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
/* --- CR --- */
if (Buffer[i] == '\r')
{
Buff->CurrentX = 0;
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX);
Buff->CursorPosition.X = 0;
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X);
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X);
continue;
}
/* --- LF --- */
else if (Buffer[i] == '\n')
{
Buff->CurrentX = 0;
Buff->CursorPosition.X = 0;
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
continue;
}
@ -159,24 +179,24 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
else if (Buffer[i] == '\b')
{
/* Only handle BS if we're not on the first pos of the first line */
if (0 != Buff->CurrentX || 0 != Buff->CurrentY)
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
{
if (0 == Buff->CurrentX)
if (0 == Buff->CursorPosition.X)
{
/* slide virtual position up */
Buff->CurrentX = Buff->MaxX - 1;
Buff->CurrentY--;
UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CurrentY);
Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1;
Buff->CursorPosition.Y--;
UpdateRect.Top = min(UpdateRect.Top, (LONG)Buff->CursorPosition.Y);
}
else
{
Buff->CurrentX--;
Buff->CursorPosition.X--;
}
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
Ptr[0] = ' ';
Ptr[1] = Buff->DefaultAttrib;
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX);
Ptr[1] = Buff->ScreenDefaultAttrib;
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X);
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X);
}
continue;
}
@ -185,27 +205,27 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
{
UINT EndX;
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
EndX = (Buff->CurrentX + TAB_WIDTH) & ~(TAB_WIDTH - 1);
EndX = min(EndX, Buff->MaxX);
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
while (Buff->CurrentX < EndX)
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X);
EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1);
EndX = min(EndX, Buff->ScreenBufferSize.X);
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
while (Buff->CursorPosition.X < EndX)
{
*Ptr++ = ' ';
*Ptr++ = Buff->DefaultAttrib;
Buff->CurrentX++;
*Ptr++ = Buff->ScreenDefaultAttrib;
Buff->CursorPosition.X++;
}
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX - 1);
if (Buff->CurrentX == Buff->MaxX)
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X - 1);
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
{
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
{
Buff->CurrentX = 0;
Buff->CursorPosition.X = 0;
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
}
else
{
Buff->CurrentX--;
Buff->CursorPosition.X--;
}
}
continue;
@ -218,25 +238,25 @@ ConioWriteConsole(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff,
continue;
}
}
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CurrentX);
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CurrentX);
Ptr = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY);
UpdateRect.Left = min(UpdateRect.Left, (LONG)Buff->CursorPosition.X);
UpdateRect.Right = max(UpdateRect.Right, (LONG)Buff->CursorPosition.X);
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
Ptr[0] = Buffer[i];
if (Attrib)
{
Ptr[1] = Buff->DefaultAttrib;
Ptr[1] = Buff->ScreenDefaultAttrib;
}
Buff->CurrentX++;
if (Buff->CurrentX == Buff->MaxX)
Buff->CursorPosition.X++;
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
{
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
{
Buff->CurrentX = 0;
Buff->CursorPosition.X = 0;
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
}
else
{
Buff->CurrentX = CursorStartX;
Buff->CursorPosition.X = CursorStartX;
}
}
}
@ -377,7 +397,6 @@ 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)
@ -386,7 +405,6 @@ 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);
}
@ -402,14 +420,13 @@ ConioDrawConsole(PCONSOLE Console)
SMALL_RECT Region;
ConioInitRect(&Region, 0, 0, Console->Size.Y - 1, Console->Size.X - 1);
ConioDrawRegion(Console, &Region);
}
static VOID FASTCALL
ConioComputeUpdateRect(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOORD Start, UINT Length)
{
if (Buff->MaxX <= Start->X + Length)
if (Buff->ScreenBufferSize.X <= Start->X + Length)
{
UpdateRect->Left = 0;
}
@ -417,19 +434,19 @@ ConioComputeUpdateRect(PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOO
{
UpdateRect->Left = Start->X;
}
if (Buff->MaxX <= Start->X + Length)
if (Buff->ScreenBufferSize.X <= Start->X + Length)
{
UpdateRect->Right = Buff->MaxX - 1;
UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
}
else
{
UpdateRect->Right = Start->X + Length - 1;
}
UpdateRect->Top = Start->Y;
UpdateRect->Bottom = Start->Y + (Start->X + Length - 1) / Buff->MaxX;
if (Buff->MaxY <= UpdateRect->Bottom)
UpdateRect->Bottom = Start->Y + (Start->X + Length - 1) / Buff->ScreenBufferSize.X;
if (Buff->ScreenBufferSize.Y <= UpdateRect->Bottom)
{
UpdateRect->Bottom = Buff->MaxY - 1;
UpdateRect->Bottom = Buff->ScreenBufferSize.Y - 1;
}
}
@ -622,7 +639,7 @@ CSR_API(SrvReadConsoleOutput)
ReadRegion.Bottom = ReadRegion.Top + SizeY;
ReadRegion.Right = ReadRegion.Left + SizeX;
ConioInitRect(&ScreenRect, 0, 0, Buff->MaxY, Buff->MaxX);
ConioInitRect(&ScreenRect, 0, 0, Buff->ScreenBufferSize.Y, Buff->ScreenBufferSize.X);
if (!ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion))
{
ConSrvReleaseScreenBuffer(Buff, TRUE);
@ -734,7 +751,7 @@ CSR_API(SrvWriteConsoleOutput)
WriteRegion.Right = WriteRegion.Left + SizeX - 1;
/* Make sure WriteRegion is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion))
{
ConSrvReleaseScreenBuffer(Buff, TRUE);
@ -826,7 +843,7 @@ CSR_API(SrvReadConsoleOutputString)
ReadBuffer = ReadOutputCodeRequest->pCode.pCode;
Xpos = ReadOutputCodeRequest->ReadCoord.X;
Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->MaxY;
Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
/*
* MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) :
@ -843,7 +860,7 @@ CSR_API(SrvReadConsoleOutputString)
*/
for (i = 0; i < ReadOutputCodeRequest->NumCodesToRead; ++i)
{
Code = Buff->Buffer[2 * (Xpos + Ypos * Buff->MaxX) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
Code = Buff->Buffer[2 * (Xpos + Ypos * Buff->ScreenBufferSize.X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
switch (CodeType)
{
@ -863,12 +880,12 @@ CSR_API(SrvReadConsoleOutputString)
Xpos++;
if (Xpos == Buff->MaxX)
if (Xpos == Buff->ScreenBufferSize.X)
{
Xpos = 0;
Ypos++;
if (Ypos == Buff->MaxY)
if (Ypos == Buff->ScreenBufferSize.Y)
{
Ypos = 0;
}
@ -891,7 +908,7 @@ CSR_API(SrvReadConsoleOutputString)
// }
ReadOutputCodeRequest->EndCoord.X = Xpos;
ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->MaxY) % Buff->MaxY;
ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y;
ConSrvReleaseScreenBuffer(Buff, TRUE);
@ -990,9 +1007,9 @@ CSR_API(SrvWriteConsoleOutputString)
if (String && NT_SUCCESS(Status))
{
X = WriteOutputCodeRequest->Coord.X;
Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY;
Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = WriteOutputCodeRequest->Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
while (Length--)
{
@ -1001,9 +1018,9 @@ CSR_API(SrvWriteConsoleOutputString)
String = (PCHAR)((ULONG_PTR)String + CodeSize);
// Written++;
Buffer += 2;
if (++X == Buff->MaxX)
if (++X == Buff->ScreenBufferSize.X)
{
if (++Y == Buff->MaxY)
if (++Y == Buff->ScreenBufferSize.Y)
{
Y = 0;
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0);
@ -1020,7 +1037,7 @@ CSR_API(SrvWriteConsoleOutputString)
}
WriteOutputCodeRequest->EndCoord.X = X;
WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->MaxY - Buff->VirtualY) % Buff->MaxY;
WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y;
}
if (tmpString)
@ -1056,9 +1073,9 @@ CSR_API(SrvFillConsoleOutput)
CodeType = FillOutputRequest->CodeType;
X = FillOutputRequest->Coord.X;
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->MaxY;
Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y;
Length = FillOutputRequest->Length;
Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
Buffer = &Buff->Buffer[2 * (Y * Buff->ScreenBufferSize.X + X) + (CodeType == CODE_ATTRIBUTE ? 1 : 0)];
switch (CodeType)
{
@ -1084,9 +1101,9 @@ CSR_API(SrvFillConsoleOutput)
*Buffer = Code;
Buffer += 2;
// Written++;
if (++X == Buff->MaxX)
if (++X == Buff->ScreenBufferSize.X)
{
if (++Y == Buff->MaxY)
if (++Y == Buff->ScreenBufferSize.Y)
{
Y = 0;
Buffer = Buff->Buffer + (CodeType == CODE_ATTRIBUTE ? 1 : 0);
@ -1192,16 +1209,16 @@ CSR_API(SrvSetConsoleCursorPosition)
NewCursorX = SetCursorPositionRequest->Position.X;
NewCursorY = SetCursorPositionRequest->Position.Y;
if ( NewCursorX < 0 || NewCursorX >= Buff->MaxX ||
NewCursorY < 0 || NewCursorY >= Buff->MaxY )
if ( NewCursorX < 0 || NewCursorX >= Buff->ScreenBufferSize.X ||
NewCursorY < 0 || NewCursorY >= Buff->ScreenBufferSize.Y )
{
ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_INVALID_PARAMETER;
}
OldCursorX = Buff->CurrentX;
OldCursorY = Buff->CurrentY;
Buff->CurrentX = NewCursorX;
Buff->CurrentY = NewCursorY;
OldCursorX = Buff->CursorPosition.X;
OldCursorY = Buff->CursorPosition.Y;
Buff->CursorPosition.X = NewCursorX;
Buff->CursorPosition.Y = NewCursorY;
if (Buff == Console->ActiveBuffer)
{
if (!ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY))
@ -1230,7 +1247,7 @@ CSR_API(SrvSetConsoleTextAttribute)
Console = Buff->Header.Console;
Buff->DefaultAttrib = SetTextAttribRequest->Attrib;
Buff->ScreenDefaultAttrib = SetTextAttribRequest->Attrib;
if (Buff == Console->ActiveBuffer)
{
if (!ConioUpdateScreenInfo(Console, Buff))
@ -1253,6 +1270,10 @@ CSR_API(SrvCreateConsoleScreenBuffer)
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER Buff;
COORD ScreenBufferSize = (COORD){80, 25};
USHORT ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
USHORT PopupAttrib = DEFAULT_POPUP_ATTRIB;
DPRINT("SrvCreateConsoleScreenBuffer\n");
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
@ -1264,46 +1285,36 @@ CSR_API(SrvCreateConsoleScreenBuffer)
return Status;
}
Buff = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER));
if (Buff != NULL)
if (Console->ActiveBuffer)
{
if (Console->ActiveBuffer)
{
Buff->MaxX = Console->ActiveBuffer->MaxX;
Buff->MaxY = Console->ActiveBuffer->MaxY;
Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible;
Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize;
}
else
{
Buff->CursorInfo.bVisible = TRUE;
Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
}
ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
if (ScreenBufferSize.X == 0) ScreenBufferSize.X = 80;
if (ScreenBufferSize.Y == 0) ScreenBufferSize.Y = 25;
if (Buff->MaxX == 0)
{
Buff->MaxX = 80;
}
if (Buff->MaxY == 0)
{
Buff->MaxY = 25;
}
Status = ConSrvInitConsoleScreenBuffer(Console, Buff);
if (NT_SUCCESS(Status))
{
Status = ConSrvInsertObject(ProcessData,
&CreateScreenBufferRequest->OutputHandle,
&Buff->Header,
CreateScreenBufferRequest->Access,
CreateScreenBufferRequest->Inheritable,
CreateScreenBufferRequest->ShareMode);
}
ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib;
PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib;
// Buff->CursorInfo.bVisible = Console->ActiveBuffer->CursorInfo.bVisible;
// Buff->CursorInfo.dwSize = Console->ActiveBuffer->CursorInfo.dwSize;
}
else
// else
// {
// Buff->CursorInfo.bVisible = TRUE;
// Buff->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
// }
Status = ConSrvCreateScreenBuffer(Console,
&Buff,
ScreenBufferSize,
ScreenAttrib,
PopupAttrib);
if (NT_SUCCESS(Status))
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Status = ConSrvInsertObject(ProcessData,
&CreateScreenBufferRequest->OutputHandle,
&Buff->Header,
CreateScreenBufferRequest->Access,
CreateScreenBufferRequest->Inheritable,
CreateScreenBufferRequest->ShareMode);
}
ConSrvReleaseConsole(Console, TRUE);
@ -1328,17 +1339,14 @@ CSR_API(SrvGetConsoleScreenBufferInfo)
Console = Buff->Header.Console;
pInfo->dwSize.X = Buff->MaxX;
pInfo->dwSize.Y = Buff->MaxY;
pInfo->dwCursorPosition.X = Buff->CurrentX;
pInfo->dwCursorPosition.Y = Buff->CurrentY;
pInfo->wAttributes = Buff->DefaultAttrib;
pInfo->dwSize = Buff->ScreenBufferSize;
pInfo->dwCursorPosition = Buff->CursorPosition;
pInfo->wAttributes = Buff->ScreenDefaultAttrib;
pInfo->srWindow.Left = Buff->ShowX;
pInfo->srWindow.Right = Buff->ShowX + Console->Size.X - 1;
pInfo->srWindow.Top = Buff->ShowY;
pInfo->srWindow.Bottom = Buff->ShowY + Console->Size.Y - 1;
pInfo->dwMaximumWindowSize.X = Buff->MaxX;
pInfo->dwMaximumWindowSize.Y = Buff->MaxY;
pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize;
ConSrvReleaseScreenBuffer(Buff, TRUE);
@ -1415,7 +1423,7 @@ CSR_API(SrvScrollConsoleScreenBuffer)
ScrollRectangle = ScrollScreenBufferRequest->ScrollRectangle;
/* Make sure source rectangle is inside the screen buffer */
ConioInitRect(&ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1);
if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle))
{
ConSrvReleaseScreenBuffer(Buff, TRUE);

View file

@ -12,6 +12,7 @@
#define NONAMELESSUNION
#include "consrv.h"
#include "settings.h"
#include "guiconsole.h"
#include "tuiconsole.h"
@ -102,17 +103,19 @@ ConioUnpause(PCONSOLE Console, UINT Flags)
}
static BOOL
LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
OUT LPWSTR IconPath,
IN SIZE_T IconPathLength,
OUT PINT piIcon)
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
OUT PCONSOLE_INFO ConsoleInfo,
OUT LPWSTR IconPath,
IN SIZE_T IconPathLength,
OUT PINT piIcon)
{
#define PATH_SEPARATOR L'\\'
BOOL RetVal = FALSE;
LPWSTR LinkName = NULL;
SIZE_T Length = 0;
if ((ConsoleProps->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
return FALSE;
if (IconPath == NULL || piIcon == NULL)
@ -122,10 +125,10 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
*piIcon = 0;
/* 1- Find the last path separator if any */
LinkName = wcsrchr(ConsoleProps->ConsoleTitle, PATH_SEPARATOR);
LinkName = wcsrchr(ConsoleStartInfo->ConsoleTitle, PATH_SEPARATOR);
if (LinkName == NULL)
{
LinkName = ConsoleProps->ConsoleTitle;
LinkName = ConsoleStartInfo->ConsoleTitle;
}
else
{
@ -142,7 +145,7 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
HRESULT hRes = CoInitialize(NULL);
if (SUCCEEDED(hRes))
{
// Get a pointer to the IShellLink interface.
/* Get a pointer to the IShellLink interface */
IShellLinkW* pshl = NULL;
hRes = CoCreateInstance(&CLSID_ShellLink,
NULL,
@ -151,13 +154,13 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
(LPVOID*)&pshl);
if (SUCCEEDED(hRes))
{
// Get a pointer to the IPersistFile interface.
/* 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);
/* Load the shortcut */
hRes = IPersistFile_Load(ppf, ConsoleStartInfo->ConsoleTitle, STGM_READ);
if (SUCCEEDED(hRes))
{
/*
@ -167,26 +170,36 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
INT ShowCmd = 0;
// WORD HotKey = 0;
// Get the name of the shortcut.
/* 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';
sizeof(ConsoleStartInfo->ConsoleTitle) / sizeof(ConsoleStartInfo->ConsoleTitle[0]) - 1);
wcsncpy(ConsoleStartInfo->ConsoleTitle, LinkName, Length);
ConsoleStartInfo->ConsoleTitle[Length] = L'\0';
// Get the window showing command.
// HACK: Copy also the name of the shortcut
Length = min(Length,
sizeof(ConsoleInfo->ConsoleTitle) / sizeof(ConsoleInfo->ConsoleTitle[0]) - 1);
wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length);
ConsoleInfo->ConsoleTitle[Length] = L'\0';
/* Get the window showing command */
hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd);
if (SUCCEEDED(hRes)) ConsoleProps->ShowWindow = (WORD)ShowCmd;
if (SUCCEEDED(hRes)) ConsoleStartInfo->ShowWindow = (WORD)ShowCmd;
// Get the hotkey.
/* Get the hotkey */
// hRes = pshl->GetHotkey(&ShowCmd);
// if (SUCCEEDED(hRes)) ConsoleProps->HotKey = HotKey;
// if (SUCCEEDED(hRes)) ConsoleStartInfo->HotKey = HotKey;
// Get the icon location, if any.
/* Get the icon location, if any */
hRes = IShellLinkW_GetIconLocation(pshl, IconPath, IconPathLength, piIcon);
if (!SUCCEEDED(hRes))
{
IconPath[0] = L'\0';
}
// FIXME: Since we still don't load console properties from the shortcut,
// return false. When this will be done, we will return true instead.
RetVal = FALSE;
}
IPersistFile_Release(ppf);
}
@ -195,17 +208,20 @@ LoadShellLinkInfo(IN OUT PCONSOLE_PROPS ConsoleProps,
}
CoUninitialize();
return TRUE;
return RetVal;
}
NTSTATUS WINAPI
ConSrvInitConsole(OUT PCONSOLE* NewConsole,
IN LPCWSTR AppPath,
IN OUT PCONSOLE_PROPS ConsoleProps,
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
IN PCSR_PROCESS ConsoleLeaderProcess)
{
NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes;
CONSOLE_INFO ConsoleInfo;
SIZE_T Length = 0;
DWORD ProcessId = HandleToUlong(ConsoleLeaderProcess->ClientId.UniqueProcess);
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER NewBuffer;
BOOL GuiMode;
@ -214,10 +230,11 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
INT iIcon = 0;
if (NewConsole == NULL) return STATUS_INVALID_PARAMETER;
*NewConsole = NULL;
/* Allocate a console structure */
/*
* Allocate a console structure
*/
Console = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE));
if (NULL == Console)
{
@ -226,46 +243,101 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
}
/*
* Check whether the process creating the console
* was launched via a shell-link.
* Load the console settings
*/
if (ConsoleProps->dwStartupFlags & STARTF_TITLEISLINKNAME)
{
LoadShellLinkInfo(ConsoleProps,
IconPath,
MAX_PATH,
&iIcon);
ConsoleProps->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
/* 1. Load the default settings */
ConSrvGetDefaultSettings(&ConsoleInfo, ProcessId);
/* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
ConsoleInfo.ConsoleTitle[Length] = L'\0';
/*
* 3. Check whether the process creating the
* console was launched via a shell-link
* (ConsoleInfo.ConsoleTitle may be updated).
*/
if (ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME)
{
if (!LoadShellLinkConsoleInfo(ConsoleStartInfo,
&ConsoleInfo,
IconPath,
MAX_PATH,
&iIcon))
{
ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
}
}
/* Initialize the console */
/*
* 4. Load the remaining console settings via the registry.
*/
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
{
/*
* Either we weren't created by an app launched via a shell-link,
* or we failed to load shell-link console properties.
* Therefore, load the console infos for the application from the registry.
*/
ConSrvReadUserSettings(&ConsoleInfo, ProcessId);
/*
* Now, update them with the properties the user might gave to us
* via the STARTUPINFO structure before calling CreateProcess
* (and which was transmitted via the ConsoleStartInfo structure).
*/
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
{
ConsoleInfo.ScreenAttrib = ConsoleStartInfo->FillAttribute;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
{
ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESHOWWINDOW)
{
ConsoleInfo.u.GuiInfo.ShowWindow = ConsoleStartInfo->ShowWindow;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION)
{
ConsoleInfo.u.GuiInfo.AutoPosition = FALSE;
ConsoleInfo.u.GuiInfo.WindowOrigin = ConsoleStartInfo->ConsoleWindowOrigin;
}
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
{
// ConsoleInfo.ConsoleSize = ConsoleStartInfo->ConsoleWindowSize;
ConsoleInfo.ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx;
ConsoleInfo.ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy;
}
/*
if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN)
{
}
*/
}
/*
* Initialize the console
*/
InitializeCriticalSection(&Console->Lock);
Console->ReferenceCount = 0;
Console->LineBuffer = NULL;
Console->ConsoleLeaderCID = ConsoleLeaderProcess->ClientId;
InitializeListHead(&Console->ProcessList);
InitializeListHead(&Console->BufferList);
Console->ActiveBuffer = NULL;
memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors));
Console->Size = ConsoleInfo.ConsoleSize;
/* Initialize the input buffer */
/*
* Initialize the input buffer
*/
Console->InputBuffer.Header.Type = CONIO_INPUT_BUFFER_MAGIC;
Console->InputBuffer.Header.Console = Console;
Console->InputBuffer.Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
InitializeListHead(&Console->InputBuffer.ReadWaitQueue);
InitializeListHead(&Console->InputBuffer.InputEvents);
InitializeListHead(&Console->WriteWaitQueue);
InitializeListHead(&Console->HistoryBuffers);
Console->CodePage = GetOEMCP();
Console->OutputCodePage = GetOEMCP();
Console->GuiData = NULL;
Console->hIcon = Console->hIconSm = NULL;
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = TRUE;
Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
if (NULL == Console->InputBuffer.ActiveEvent)
{
@ -274,39 +346,52 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
return STATUS_UNSUCCESSFUL;
}
/* Allocate console screen buffer */
NewBuffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CONSOLE_SCREEN_BUFFER));
if (NULL == NewBuffer)
{
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->InputBuffer.ActiveEvent);
RtlFreeHeap(ConSrvHeap, 0, Console);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* 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 = NewBuffer;
/** Finish to initialize the screen buffer **
** Fix problems with MaxX == 0 and MaxY == 0
**
Status = ConSrvInitConsoleScreenBuffer(Console, NewBuffer);
// TODO: Use the values from ConsoleInfo.
Console->InputBuffer.Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
Console->QuickEdit = ConsoleInfo.QuickEdit;
Console->InsertMode = ConsoleInfo.InsertMode;
InitializeListHead(&Console->InputBuffer.ReadWaitQueue);
InitializeListHead(&Console->InputBuffer.InputEvents);
Console->LineBuffer = NULL;
Console->CodePage = GetOEMCP();
Console->OutputCodePage = GetOEMCP();
/* Initialize a new screen buffer with default settings */
InitializeListHead(&Console->BufferList);
Status = ConSrvCreateScreenBuffer(Console,
&NewBuffer,
ConsoleInfo.ScreenBufferSize,
ConsoleInfo.ScreenAttrib,
ConsoleInfo.PopupAttrib);
if (!NT_SUCCESS(Status))
{
DPRINT1("ConSrvInitConsoleScreenBuffer: failed\n");
RtlFreeHeap(ConSrvHeap, 0, NewBuffer);
DeleteCriticalSection(&Console->Lock);
DPRINT1("ConSrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
CloseHandle(Console->InputBuffer.ActiveEvent);
DeleteCriticalSection(&Console->Lock);
RtlFreeHeap(ConSrvHeap, 0, Console);
return Status;
}
**/
/* Make the new screen buffer active */
Console->ActiveBuffer = NewBuffer;
Console->FullScreen = ConsoleInfo.FullScreen;
InitializeListHead(&Console->WriteWaitQueue);
/*
* Initialize the history buffers
*/
InitializeListHead(&Console->HistoryBuffers);
Console->HistoryBufferSize = ConsoleInfo.HistoryBufferSize;
Console->NumberOfHistoryBuffers = ConsoleInfo.NumberOfHistoryBuffers;
Console->HistoryNoDup = ConsoleInfo.HistoryNoDup;
/* Finish initialization */
Console->GuiData = NULL;
Console->hIcon = Console->hIconSm = NULL;
/* Initialize the console title */
Console->Title.MaximumLength = Console->Title.Length = 0;
Console->Title.Buffer = NULL;
if (ConsoleProps->ConsoleTitle[0] == L'\0')
RtlCreateUnicodeString(&Console->OriginalTitle, ConsoleStartInfo->ConsoleTitle);
if (ConsoleStartInfo->ConsoleTitle[0] == L'\0')
{
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, Title, sizeof(Title) / sizeof(Title[0])))
{
@ -319,7 +404,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
}
else
{
RtlCreateUnicodeString(&Console->Title, ConsoleProps->ConsoleTitle);
RtlCreateUnicodeString(&Console->Title, ConsoleStartInfo->ConsoleTitle);
}
/*
@ -331,7 +416,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
if (!GuiMode)
{
DPRINT1("CONSRV: Opening text-mode console\n");
Status = TuiInitConsole(Console);
Status = TuiInitConsole(Console, &ConsoleInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status);
@ -354,41 +439,27 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
DPRINT1("CONSRV: Opening GUI-mode console\n");
Status = GuiInitConsole(Console,
AppPath,
ConsoleProps->ShowWindow,
&ConsoleInfo,
IconPath,
iIcon);
if (!NT_SUCCESS(Status))
{
DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->OriginalTitle);
ConioDeleteScreenBuffer(NewBuffer);
CloseHandle(Console->InputBuffer.ActiveEvent);
RtlFreeHeap(ConSrvHeap, 0, NewBuffer);
/// ConioDeleteScreenBuffer(NewBuffer);
DeleteCriticalSection(&Console->Lock);
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);
RtlFreeHeap(ConSrvHeap, 0, Console);
return Status;
}
/* Copy buffer contents to screen */
ConioDrawConsole(Console);
/* Return the newly created console to the caller and a success code too */
*NewConsole = Console;
return STATUS_SUCCESS;
}
@ -432,6 +503,7 @@ ConSrvDeleteConsole(PCONSOLE Console)
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->OriginalTitle);
RtlFreeUnicodeString(&Console->Title);
IntDeleteAllAliases(Console->Aliases);
RtlFreeHeap(ConSrvHeap, 0, Console);
@ -484,11 +556,11 @@ CSR_API(SrvOpenConsole)
else
{
Status = ConSrvInsertObject(ProcessData,
&OpenConsoleRequest->ConsoleHandle,
Object,
DesiredAccess,
OpenConsoleRequest->Inheritable,
ShareMode);
&OpenConsoleRequest->ConsoleHandle,
Object,
DesiredAccess,
OpenConsoleRequest->Inheritable,
ShareMode);
}
LeaveCriticalSection(&Console->Lock);
@ -515,9 +587,9 @@ CSR_API(SrvAllocConsole)
}
if ( !CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&AllocConsoleRequest->ConsoleProps,
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
1,
sizeof(CONSOLE_PROPS)) ||
sizeof(CONSOLE_START_INFO)) ||
!CsrValidateMessageBuffer(ApiMessage,
(PVOID*)&AllocConsoleRequest->AppPath,
MAX_PATH + 1,
@ -545,7 +617,7 @@ CSR_API(SrvAllocConsole)
&AllocConsoleRequest->InputHandle,
&AllocConsoleRequest->OutputHandle,
&AllocConsoleRequest->ErrorHandle,
AllocConsoleRequest->ConsoleProps);
AllocConsoleRequest->ConsoleStartInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console allocation failed\n");
@ -558,6 +630,10 @@ CSR_API(SrvAllocConsole)
/* Input Wait Handle */
AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent;
/* Set the Property Dialog Handler */
ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher;
DPRINT("CONSRV: PropDispatcher address: %x\n", ProcessData->PropDispatcher);
/* Set the Ctrl Dispatcher */
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
@ -656,6 +732,10 @@ CSR_API(SrvAttachConsole)
/* Input Wait Handle */
AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent;
/* Set the Property Dialog Handler */
TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher;
DPRINT("CONSRV: PropDispatcher address: %x\n", TargetProcessData->PropDispatcher);
/* Set the Ctrl Dispatcher */
TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
DPRINT("CONSRV: CtrlDispatcher address: %x\n", TargetProcessData->CtrlDispatcher);
@ -677,6 +757,12 @@ CSR_API(SrvFreeConsole)
CSR_API(SrvSetConsoleMode)
{
#define CONSOLE_INPUT_MODE_VALID ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \
ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \
ENABLE_MOUSE_INPUT | \
ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS )
#define CONSOLE_OUTPUT_MODE_VALID ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT )
NTSTATUS Status;
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
Object_t* Object = NULL;

View file

@ -25,6 +25,7 @@
#include <winuser.h>
#define NTOS_MODE_USER
#include <ndk/iofuncs.h>
#include <ndk/mmfuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/psfuncs.h>
#include <ndk/setypes.h>
@ -42,9 +43,6 @@
#include "resource.h"
/* Shared header with console.dll */
#include "console.h"
extern HINSTANCE ConSrvDllInstance;
extern HANDLE ConSrvHeap;
@ -93,6 +91,7 @@ typedef struct _CONSOLE_PROCESS_DATA
PCONSOLE_IO_HANDLE HandleTable; // Length-varying table
LPTHREAD_START_ROUTINE CtrlDispatcher;
LPTHREAD_START_ROUTINE PropDispatcher; // We hold the property dialog handler there, till all the GUI thingie moves out from CSRSS.
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
@ -182,7 +181,7 @@ NTSTATUS FASTCALL ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
PCONSOLE_PROPS ConsoleProps);
PCONSOLE_START_INFO ConsoleStartInfo);
NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
struct _CONSOLE* Console,
BOOL CreateNewHandlesTable,

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/guiconsole.h
* PURPOSE: Interface to gui-mode consoles
* PURPOSE: Interface to GUI-mode consoles
* PROGRAMMERS:
*/
@ -15,7 +15,7 @@
NTSTATUS FASTCALL GuiInitConsole(PCONSOLE Console,
LPCWSTR AppPath,
WORD ShowWindow,
PCONSOLE_INFO ConsoleInfo,
LPCWSTR IconPath,
INT IconIndex);
VOID FASTCALL GuiConsoleHandleScrollbarMenu(VOID);

View file

@ -129,11 +129,11 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
/* Insert the Input handle */
Status = ConSrvInsertObject(ProcessData,
&InputHandle,
&ProcessData->Console->InputBuffer.Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
&InputHandle,
&ProcessData->Console->InputBuffer.Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the input handle\n");
@ -144,11 +144,11 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
/* Insert the Output handle */
Status = ConSrvInsertObject(ProcessData,
&OutputHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
&OutputHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the output handle\n");
@ -159,11 +159,11 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData,
/* Insert the Error handle */
Status = ConSrvInsertObject(ProcessData,
&ErrorHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
&ErrorHandle,
&ProcessData->Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert the error handle\n");
@ -405,12 +405,12 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
PHANDLE pInputHandle,
PHANDLE pOutputHandle,
PHANDLE pErrorHandle,
PCONSOLE_PROPS ConsoleProps)
PCONSOLE_START_INFO ConsoleStartInfo)
{
NTSTATUS Status = STATUS_SUCCESS;
/* Initialize a new Console owned by this process */
Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleProps, ProcessData->Process);
Status = ConSrvInitConsole(&ProcessData->Console, AppPath, ConsoleStartInfo, ProcessData->Process);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console initialization failed\n");
@ -511,6 +511,7 @@ FASTCALL
ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
{
PCONSOLE Console;
PCONSOLE_PROCESS_DATA NewProcessData;
DPRINT1("ConSrvRemoveConsole\n");
@ -523,9 +524,21 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData)
{
DPRINT1("ConSrvRemoveConsole - Console->ReferenceCount = %lu - We are going to decrement it !\n", Console->ReferenceCount);
ProcessData->Console = NULL;
EnterCriticalSection(&Console->Lock);
DPRINT1("ConSrvRemoveConsole - Locking OK\n");
/* Remove ourselves from the console's list of processes */
RemoveEntryList(&ProcessData->ConsoleLink);
/* Update the console leader process */
NewProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
CONSOLE_PROCESS_DATA,
ConsoleLink);
Console->ConsoleLeaderCID = NewProcessData->Process->ClientId;
SetConsoleWndConsoleLeaderCID(Console);
/* Release the console */
ConSrvReleaseConsole(Console, TRUE);
//CloseHandle(ProcessData->ConsoleEvent);
//ProcessData->ConsoleEvent = NULL;
@ -613,7 +626,6 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
TargetProcessData->HandleTableSize = 0;
TargetProcessData->HandleTable = NULL;
/**** HACK !!!! ****/ RtlZeroMemory(&TargetProcessData->HandleTableLock, sizeof(RTL_CRITICAL_SECTION));
RtlInitializeCriticalSection(&TargetProcessData->HandleTableLock);
/* Do nothing if the source process is NULL */
@ -700,7 +712,7 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
&ConnectInfo->InputHandle,
&ConnectInfo->OutputHandle,
&ConnectInfo->ErrorHandle,
&ConnectInfo->ConsoleProps);
&ConnectInfo->ConsoleStartInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console allocation failed\n");
@ -731,6 +743,10 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
/* Input Wait Handle */
ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent;
/* Set the Property Dialog Handler */
ProcessData->PropDispatcher = ConnectInfo->PropDispatcher;
DPRINT("CONSRV: PropDispatcher address: %x\n", ProcessData->PropDispatcher);
/* Set the Ctrl Dispatcher */
ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher;
DPRINT("CONSRV: CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
@ -831,11 +847,11 @@ CSR_API(SrvDuplicateHandle)
}
ApiMessage->Status = ConSrvInsertObject(ProcessData,
&DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
Entry->Object,
DesiredAccess,
DuplicateHandleRequest->Inheritable,
Entry->ShareMode);
&DuplicateHandleRequest->ConsoleHandle, // Use the new handle value!
Entry->Object,
DesiredAccess,
DuplicateHandleRequest->Inheritable,
Entry->ShareMode);
if (NT_SUCCESS(ApiMessage->Status) &&
DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE)
{

View file

@ -116,47 +116,47 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber] =
BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] =
{
TRUE /* FALSE */, // SrvOpenConsole,
TRUE /* FALSE */, // SrvGetConsoleInput,
TRUE /* FALSE */, // SrvWriteConsoleInput,
TRUE /* FALSE */, // SrvReadConsoleOutput,
TRUE /* FALSE */, // SrvWriteConsoleOutput,
TRUE /* FALSE */, // SrvReadConsoleOutputString,
TRUE /* FALSE */, // SrvWriteConsoleOutputString,
TRUE /* FALSE */, // SrvFillConsoleOutput,
TRUE /* FALSE */, // SrvGetConsoleMode,
FALSE, // SrvOpenConsole,
FALSE, // SrvGetConsoleInput,
FALSE, // SrvWriteConsoleInput,
FALSE, // SrvReadConsoleOutput,
FALSE, // SrvWriteConsoleOutput,
FALSE, // SrvReadConsoleOutputString,
FALSE, // SrvWriteConsoleOutputString,
FALSE, // SrvFillConsoleOutput,
FALSE, // SrvGetConsoleMode,
// FALSE, // SrvGetConsoleNumberOfFonts,
TRUE /* FALSE */, // SrvGetConsoleNumberOfInputEvents,
TRUE /* FALSE */, // SrvGetConsoleScreenBufferInfo,
TRUE /* FALSE */, // SrvGetConsoleCursorInfo,
FALSE, // SrvGetConsoleNumberOfInputEvents,
FALSE, // SrvGetConsoleScreenBufferInfo,
FALSE, // SrvGetConsoleCursorInfo,
// FALSE, // SrvGetConsoleMouseInfo,
// FALSE, // SrvGetConsoleFontInfo,
// FALSE, // SrvGetConsoleFontSize,
// FALSE, // SrvGetConsoleCurrentFont,
TRUE /* FALSE */, // SrvSetConsoleMode,
TRUE /* FALSE */, // SrvSetConsoleActiveScreenBuffer,
TRUE /* FALSE */, // SrvFlushConsoleInputBuffer,
FALSE, // SrvSetConsoleMode,
FALSE, // SrvSetConsoleActiveScreenBuffer,
FALSE, // SrvFlushConsoleInputBuffer,
// FALSE, // SrvGetLargestConsoleWindowSize,
TRUE /* FALSE */, // SrvSetConsoleScreenBufferSize,
TRUE /* FALSE */, // SrvSetConsoleCursorPosition,
TRUE /* FALSE */, // SrvSetConsoleCursorInfo,
FALSE, // SrvSetConsoleScreenBufferSize,
FALSE, // SrvSetConsoleCursorPosition,
FALSE, // SrvSetConsoleCursorInfo,
// FALSE, // SrvSetConsoleWindowInfo,
TRUE /* FALSE */, // SrvScrollConsoleScreenBuffer,
TRUE /* FALSE */, // SrvSetConsoleTextAttribute,
FALSE, // SrvScrollConsoleScreenBuffer,
FALSE, // SrvSetConsoleTextAttribute,
// FALSE, // SrvSetConsoleFont,
TRUE /* FALSE */, // SrvSetConsoleIcon,
TRUE /* FALSE */, // SrvReadConsole,
TRUE /* FALSE */, // SrvWriteConsole,
TRUE /* FALSE */, // SrvDuplicateHandle,
FALSE, // SrvSetConsoleIcon,
FALSE, // SrvReadConsole,
FALSE, // SrvWriteConsole,
FALSE, // SrvDuplicateHandle,
// FALSE, // SrvGetHandleInformation,
// FALSE, // SrvSetHandleInformation,
TRUE /* FALSE */, // SrvCloseHandle,
TRUE /* FALSE */, // SrvVerifyConsoleIoHandle,
TRUE /* FALSE */, // SrvAllocConsole,
TRUE /* FALSE */, // SrvFreeConsole,
TRUE /* FALSE */, // SrvGetConsoleTitle,
TRUE /* FALSE */, // SrvSetConsoleTitle,
TRUE /* FALSE */, // SrvCreateConsoleScreenBuffer,
FALSE, // SrvCloseHandle,
FALSE, // SrvVerifyConsoleIoHandle,
FALSE, // SrvAllocConsole,
FALSE, // SrvFreeConsole,
FALSE, // SrvGetConsoleTitle,
FALSE, // SrvSetConsoleTitle,
FALSE, // SrvCreateConsoleScreenBuffer,
// FALSE, // SrvInvalidateBitMapRect,
// FALSE, // SrvVDMConsoleOperation,
// FALSE, // SrvSetConsoleCursor,
@ -165,28 +165,28 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] =
// FALSE, // SrvSetConsolePalette,
// FALSE, // SrvSetConsoleDisplayMode,
// FALSE, // SrvRegisterConsoleVDM,
TRUE /* FALSE */, // SrvGetConsoleHardwareState,
TRUE /* FALSE */, // SrvSetConsoleHardwareState,
FALSE, // SrvGetConsoleHardwareState,
FALSE, // SrvSetConsoleHardwareState,
// TRUE, // SrvGetConsoleDisplayMode,
TRUE /* FALSE */, // SrvAddConsoleAlias,
TRUE /* FALSE */, // SrvGetConsoleAlias,
TRUE /* FALSE */, // SrvGetConsoleAliasesLength,
TRUE /* FALSE */, // SrvGetConsoleAliasExesLength,
TRUE /* FALSE */, // SrvGetConsoleAliases,
TRUE /* FALSE */, // SrvGetConsoleAliasExes,
TRUE /* FALSE */, // SrvExpungeConsoleCommandHistory,
TRUE /* FALSE */, // SrvSetConsoleNumberOfCommands,
TRUE /* FALSE */, // SrvGetConsoleCommandHistoryLength,
TRUE /* FALSE */, // SrvGetConsoleCommandHistory,
FALSE, // SrvAddConsoleAlias,
FALSE, // SrvGetConsoleAlias,
FALSE, // SrvGetConsoleAliasesLength,
FALSE, // SrvGetConsoleAliasExesLength,
FALSE, // SrvGetConsoleAliases,
FALSE, // SrvGetConsoleAliasExes,
FALSE, // SrvExpungeConsoleCommandHistory,
FALSE, // SrvSetConsoleNumberOfCommands,
FALSE, // SrvGetConsoleCommandHistoryLength,
FALSE, // SrvGetConsoleCommandHistory,
// FALSE, // SrvSetConsoleCommandHistoryMode,
TRUE /* FALSE */, // SrvGetConsoleCP,
TRUE /* FALSE */, // SrvSetConsoleCP,
FALSE, // SrvGetConsoleCP,
FALSE, // SrvSetConsoleCP,
// FALSE, // SrvSetConsoleKeyShortcuts,
// FALSE, // SrvSetConsoleMenuClose,
// FALSE, // SrvConsoleNotifyLastClose,
TRUE /* FALSE */, // SrvGenerateConsoleCtrlEvent,
FALSE, // SrvGenerateConsoleCtrlEvent,
// FALSE, // SrvGetConsoleKeyboardLayoutName,
TRUE /* FALSE */, // SrvGetConsoleWindow,
FALSE, // SrvGetConsoleWindow,
// FALSE, // SrvGetConsoleCharType,
// FALSE, // SrvSetConsoleLocalEUDC,
// FALSE, // SrvSetConsoleCursorMode,
@ -198,11 +198,11 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber] =
// FALSE, // SrvRegisterConsoleIME,
// FALSE, // SrvUnregisterConsoleIME,
// FALSE, // SrvGetConsoleLangId,
TRUE /* FALSE */, // SrvAttachConsole,
TRUE /* FALSE */, // SrvGetConsoleSelectionInfo,
TRUE /* FALSE */, // SrvGetConsoleProcessList,
TRUE /* FALSE */, // SrvGetConsoleHistory,
TRUE /* FALSE */, // SrvSetConsoleHistory
FALSE, // SrvAttachConsole,
FALSE, // SrvGetConsoleSelectionInfo,
FALSE, // SrvGetConsoleProcessList,
FALSE, // SrvGetConsoleHistory,
FALSE, // SrvSetConsoleHistory
// FALSE
};

View file

@ -1,7 +1,7 @@
/*
* LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/tuiconsole.c
* FILE: win32ss/user/consrv/lineinput.c
* PURPOSE: Console line input functions
* PROGRAMMERS: Jeffrey Morlan
*/
@ -343,18 +343,18 @@ LineInputSetPos(PCONSOLE Console, UINT Pos)
if (Pos != Console->LinePos && Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
{
PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
UINT OldCursorX = Buffer->CurrentX;
UINT OldCursorY = Buffer->CurrentY;
INT XY = OldCursorY * Buffer->MaxX + OldCursorX;
UINT OldCursorX = Buffer->CursorPosition.X;
UINT OldCursorY = Buffer->CursorPosition.Y;
INT XY = OldCursorY * Buffer->ScreenBufferSize.X + OldCursorX;
XY += (Pos - Console->LinePos);
if (XY < 0)
XY = 0;
else if (XY >= Buffer->MaxY * Buffer->MaxX)
XY = Buffer->MaxY * Buffer->MaxX - 1;
else if (XY >= Buffer->ScreenBufferSize.Y * Buffer->ScreenBufferSize.X)
XY = Buffer->ScreenBufferSize.Y * Buffer->ScreenBufferSize.X - 1;
Buffer->CurrentX = XY % Buffer->MaxX;
Buffer->CurrentY = XY / Buffer->MaxX;
Buffer->CursorPosition.X = XY % Buffer->ScreenBufferSize.X;
Buffer->CursorPosition.Y = XY / Buffer->ScreenBufferSize.X;
ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY);
}

View file

@ -0,0 +1,498 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/settings.c
* PURPOSE: Consoles settings management
* PROGRAMMERS: Hermes Belusca - Maito
*
* NOTE: Adapted from existing code.
*/
/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "conio.h"
#include "settings.h"
#include <stdio.h> // for swprintf
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
extern const COLORREF s_Colors[16];
/* FUNCTIONS ******************************************************************/
static VOID
TranslateConsoleName(OUT LPWSTR DestString,
IN LPCWSTR ConsoleName,
IN UINT MaxStrLen)
{
#define PATH_SEPARATOR L'\\'
UINT wLength;
if ( DestString == NULL || ConsoleName == NULL ||
*ConsoleName == L'\0' || MaxStrLen == 0 )
{
return;
}
wLength = GetWindowsDirectoryW(DestString, MaxStrLen);
if ((wLength > 0) && (_wcsnicmp(ConsoleName, DestString, wLength) == 0))
{
wcsncpy(DestString, L"%SystemRoot%", MaxStrLen);
// FIXME: Fix possible buffer overflows there !!!!!
wcsncat(DestString, ConsoleName + wLength, MaxStrLen);
}
else
{
wcsncpy(DestString, ConsoleName, MaxStrLen);
}
/* Replace path separators (backslashes) by underscores */
while ((DestString = wcschr(DestString, PATH_SEPARATOR))) *DestString = L'_';
}
static BOOL
OpenUserRegistryPathPerProcessId(DWORD ProcessId,
PHKEY hResult,
REGSAM samDesired)
{
BOOL bRet = TRUE;
HANDLE hProcessToken = NULL;
HANDLE hProcess;
BYTE Buffer[256];
DWORD Length = 0;
UNICODE_STRING SidName;
PTOKEN_USER TokUser;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId);
if (!hProcess)
{
DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError());
return FALSE;
}
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
{
DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length))
{
DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError());
CloseHandle(hProcessToken);
CloseHandle(hProcess);
return FALSE;
}
TokUser = ((PTOKEN_USER)Buffer)->User.Sid;
if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE)))
{
DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError());
CloseHandle(hProcessToken);
CloseHandle(hProcess);
return FALSE;
}
bRet = (RegOpenKeyExW(HKEY_USERS,
SidName.Buffer,
0,
samDesired,
hResult) == ERROR_SUCCESS);
RtlFreeUnicodeString(&SidName);
CloseHandle(hProcessToken);
CloseHandle(hProcess);
return bRet;
}
BOOL
ConSrvOpenUserSettings(DWORD ProcessId,
LPCWSTR ConsoleTitle,
PHKEY hSubKey,
REGSAM samDesired,
BOOL bCreate)
{
BOOL bRet = TRUE;
WCHAR szBuffer[MAX_PATH] = L"Console\\";
WCHAR szBuffer2[MAX_PATH] = L"";
HKEY hKey;
/*
* Console properties are stored under the HKCU\Console\* key.
*
* We use the original console title as the subkey name for storing
* console properties. We need to distinguish whether we were launched
* via the console application directly or via a shortcut.
*
* If the title of the console corresponds to a path (more precisely,
* if the title is of the form: C:\ReactOS\<some_path>\<some_app.exe>),
* then use the corresponding unexpanded path and with the backslashes
* replaced by underscores, to make the registry happy,
* i.e. %SystemRoot%_<some_path>_<some_app.exe>
*/
DPRINT1("ConSrvOpenUserSettings entered\n");
/* Open the registry key where we saved the console properties */
if (!OpenUserRegistryPathPerProcessId(ProcessId, &hKey, samDesired))
{
DPRINT1("OpenUserRegistryPathPerProcessId failed\n");
return FALSE;
}
/*
* Try to open properties via the console title:
* to make the registry happy, replace all the
* backslashes by underscores.
*/
TranslateConsoleName(szBuffer2, ConsoleTitle, MAX_PATH);
/* Create the registry path */
wcsncat(szBuffer, szBuffer2, MAX_PATH);
/* Create or open the registry key */
if (bCreate)
{
/* Create the key */
bRet = (RegCreateKeyExW(hKey,
szBuffer,
0, NULL,
REG_OPTION_NON_VOLATILE,
samDesired,
NULL,
hSubKey,
NULL) == ERROR_SUCCESS);
}
else
{
/* Open the key */
bRet = (RegOpenKeyExW(hKey,
szBuffer,
0,
samDesired,
hSubKey) == ERROR_SUCCESS);
}
/* Close the parent key and return success or not */
RegCloseKey(hKey);
return bRet;
}
BOOL
ConSrvReadUserSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
IN DWORD ProcessId)
{
HKEY hKey;
DWORD dwNumSubKeys = 0;
DWORD dwIndex;
DWORD dwValueName;
DWORD dwValue;
DWORD dwColorIndex = 0;
DWORD dwType;
WCHAR szValueName[MAX_PATH];
WCHAR szValue[LF_FACESIZE] = L"\0";
DWORD Value;
if (!ConSrvOpenUserSettings(ProcessId,
ConsoleInfo->ConsoleTitle,
&hKey, KEY_READ,
FALSE))
{
DPRINT1("ConSrvOpenUserSettings failed\n");
return FALSE;
}
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
&dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
DPRINT("ConSrvReadUserSettings: RegQueryInfoKey failed\n");
RegCloseKey(hKey);
return FALSE;
}
DPRINT("ConSrvReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
{
dwValue = sizeof(Value);
dwValueName = MAX_PATH;
if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
{
if (dwType == REG_SZ)
{
/*
* Retry in case of string value
*/
dwValue = sizeof(szValue);
dwValueName = LF_FACESIZE;
if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
break;
}
else
{
break;
}
}
if (!wcsncmp(szValueName, L"ColorTable", wcslen(L"ColorTable")))
{
dwColorIndex = 0;
swscanf(szValueName, L"ColorTable%2d", &dwColorIndex);
if (dwColorIndex < sizeof(ConsoleInfo->Colors)/sizeof(ConsoleInfo->Colors[0]))
{
ConsoleInfo->Colors[dwColorIndex] = Value;
}
}
else if (!wcscmp(szValueName, L"HistoryBufferSize"))
{
ConsoleInfo->HistoryBufferSize = Value;
}
else if (!wcscmp(szValueName, L"NumberOfHistoryBuffers"))
{
ConsoleInfo->NumberOfHistoryBuffers = Value;
}
else if (!wcscmp(szValueName, L"HistoryNoDup"))
{
ConsoleInfo->HistoryNoDup = Value;
}
else if (!wcscmp(szValueName, L"FullScreen"))
{
ConsoleInfo->FullScreen = Value;
}
else if (!wcscmp(szValueName, L"QuickEdit"))
{
ConsoleInfo->QuickEdit = Value;
}
else if (!wcscmp(szValueName, L"InsertMode"))
{
ConsoleInfo->InsertMode = Value;
}
else if (!wcscmp(szValueName, L"ScreenBufferSize"))
{
ConsoleInfo->ScreenBufferSize.X = LOWORD(Value);
ConsoleInfo->ScreenBufferSize.Y = HIWORD(Value);
}
else if (!wcscmp(szValueName, L"WindowSize"))
{
ConsoleInfo->ConsoleSize.X = LOWORD(Value);
ConsoleInfo->ConsoleSize.Y = HIWORD(Value);
}
else if (!wcscmp(szValueName, L"CursorSize"))
{
if ( (Value == 0) || (Value == 50) || (Value == 100) )
{
ConsoleInfo->CursorSize = Value;
}
}
else if (!wcscmp(szValueName, L"ScreenColors"))
{
ConsoleInfo->ScreenAttrib = Value;
}
else if (!wcscmp(szValueName, L"PopupColors"))
{
ConsoleInfo->PopupAttrib = Value;
}
else if (!wcscmp(szValueName, L"FaceName"))
{
wcsncpy(ConsoleInfo->u.GuiInfo.FaceName, szValue, LF_FACESIZE);
}
else if (!wcscmp(szValueName, L"FontFamily"))
{
ConsoleInfo->u.GuiInfo.FontFamily = Value;
}
else if (!wcscmp(szValueName, L"FontSize"))
{
ConsoleInfo->u.GuiInfo.FontSize = Value;
}
else if (!wcscmp(szValueName, L"FontWeight"))
{
ConsoleInfo->u.GuiInfo.FontWeight = Value;
}
else if (!wcscmp(szValueName, L"WindowPosition"))
{
ConsoleInfo->u.GuiInfo.AutoPosition = FALSE;
ConsoleInfo->u.GuiInfo.WindowOrigin.x = LOWORD(Value);
ConsoleInfo->u.GuiInfo.WindowOrigin.y = HIWORD(Value);
}
}
RegCloseKey(hKey);
return TRUE;
}
BOOL
ConSrvWriteUserSettings(IN PCONSOLE_INFO ConsoleInfo,
IN DWORD ProcessId)
{
BOOL GlobalSettings = (ConsoleInfo->ConsoleTitle[0] == L'\0');
HKEY hKey;
DWORD Storage = 0;
#define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue) \
do { \
if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue)))) \
{ \
RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \
} \
else \
{ \
RegDeleteValue(hKey, (SettingName)); \
} \
} while (0)
WCHAR szValueName[15];
UINT i;
if (!ConSrvOpenUserSettings(ProcessId,
ConsoleInfo->ConsoleTitle,
&hKey, KEY_WRITE,
TRUE))
{
return FALSE;
}
for (i = 0 ; i < sizeof(ConsoleInfo->Colors)/sizeof(ConsoleInfo->Colors[0]) ; ++i)
{
/*
* Write only the new value if we are saving the global settings
* or we are saving settings for a particular console, which differs
* from the default ones.
*/
swprintf(szValueName, L"ColorTable%02d", i);
SetConsoleSetting(szValueName, REG_DWORD, sizeof(DWORD), &ConsoleInfo->Colors[i], s_Colors[i]);
}
SetConsoleSetting(L"HistoryBufferSize", REG_DWORD, sizeof(DWORD), &ConsoleInfo->HistoryBufferSize, 50);
SetConsoleSetting(L"NumberOfHistoryBuffers", REG_DWORD, sizeof(DWORD), &ConsoleInfo->NumberOfHistoryBuffers, 4);
Storage = ConsoleInfo->HistoryNoDup;
SetConsoleSetting(L"HistoryNoDup", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
Storage = ConsoleInfo->FullScreen;
SetConsoleSetting(L"FullScreen", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
Storage = ConsoleInfo->QuickEdit;
SetConsoleSetting(L"QuickEdit", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
Storage = ConsoleInfo->InsertMode;
SetConsoleSetting(L"InsertMode", REG_DWORD, sizeof(DWORD), &Storage, TRUE);
Storage = MAKELONG(ConsoleInfo->ScreenBufferSize.X, ConsoleInfo->ScreenBufferSize.Y);
SetConsoleSetting(L"ScreenBufferSize", REG_DWORD, sizeof(DWORD), &Storage, MAKELONG(80, 300));
Storage = MAKELONG(ConsoleInfo->ConsoleSize.X, ConsoleInfo->ConsoleSize.Y);
SetConsoleSetting(L"WindowSize", REG_DWORD, sizeof(DWORD), &Storage, MAKELONG(80, 25));
SetConsoleSetting(L"CursorSize", REG_DWORD, sizeof(DWORD), &ConsoleInfo->CursorSize, CSR_DEFAULT_CURSOR_SIZE);
Storage = ConsoleInfo->ScreenAttrib;
SetConsoleSetting(L"ScreenColors", REG_DWORD, sizeof(DWORD), &Storage, DEFAULT_SCREEN_ATTRIB);
Storage = ConsoleInfo->PopupAttrib;
SetConsoleSetting(L"PopupColors", REG_DWORD, sizeof(DWORD), &Storage, DEFAULT_POPUP_ATTRIB);
SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(ConsoleInfo->u.GuiInfo.FaceName) + 1) * sizeof(WCHAR), ConsoleInfo->u.GuiInfo.FaceName, L'\0');
SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &ConsoleInfo->u.GuiInfo.FontFamily, FF_DONTCARE);
SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &ConsoleInfo->u.GuiInfo.FontSize, 0);
SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &ConsoleInfo->u.GuiInfo.FontWeight, FW_DONTCARE);
if (ConsoleInfo->u.GuiInfo.AutoPosition == FALSE)
{
Storage = MAKELONG(ConsoleInfo->u.GuiInfo.WindowOrigin.x, ConsoleInfo->u.GuiInfo.WindowOrigin.y);
RegSetValueExW(hKey, L"WindowPosition", 0, REG_DWORD, (PBYTE)&ConsoleInfo->u.GuiInfo.WindowOrigin, sizeof(DWORD));
}
else
{
RegDeleteValue(hKey, L"WindowPosition");
}
RegCloseKey(hKey);
return TRUE;
}
VOID
ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
IN DWORD ProcessId)
{
DPRINT1("ConSrvGetDefaultSettings(0x%p)\n", ConsoleInfo);
if (ConsoleInfo == NULL) return;
/// HKCU,"Console","LoadConIme",0x00010003,1
/*
* 1. Load the default values
*/
// #define DEFAULT_HISTORY_COMMANDS_NUMBER 50
// #define DEFAULT_HISTORY_BUFFERS_NUMBER 4
ConsoleInfo->HistoryBufferSize = 50;
ConsoleInfo->NumberOfHistoryBuffers = 4;
ConsoleInfo->HistoryNoDup = FALSE;
ConsoleInfo->FullScreen = FALSE;
ConsoleInfo->QuickEdit = FALSE;
ConsoleInfo->InsertMode = TRUE;
// ConsoleInfo->InputBufferSize;
ConsoleInfo->ScreenBufferSize = (COORD){80, 300};
ConsoleInfo->ConsoleSize = (COORD){80, 25 };
ConsoleInfo->CursorBlinkOn;
ConsoleInfo->ForceCursorOff;
ConsoleInfo->CursorSize = CSR_DEFAULT_CURSOR_SIZE; // 0; #define SMALL_SIZE 25 // large enough to be one pixel on a six pixel font
ConsoleInfo->ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
ConsoleInfo->PopupAttrib = DEFAULT_POPUP_ATTRIB;
memcpy(ConsoleInfo->Colors, s_Colors, sizeof(s_Colors));
// ConsoleInfo->CodePage;
ConsoleInfo->ConsoleTitle[0] = L'\0';
// wcsncpy(ConsoleInfo->u.GuiInfo.FaceName, L"DejaVu Sans Mono", LF_FACESIZE);
// ConsoleInfo->u.GuiInfo.FontSize = MAKELONG(12, 8); // 0x0008000C; // font is 8x12
// ConsoleInfo->u.GuiInfo.FontSize = MAKELONG(16, 16); // font is 16x16
// ConsoleInfo->u.GuiInfo.FontWeight = FW_NORMAL;
wcsncpy(ConsoleInfo->u.GuiInfo.FaceName, L"Fixedsys", LF_FACESIZE); // HACK: !!
// ConsoleInfo->u.GuiInfo.FaceName[0] = L'\0';
ConsoleInfo->u.GuiInfo.FontFamily = FF_DONTCARE;
ConsoleInfo->u.GuiInfo.FontSize = 0;
ConsoleInfo->u.GuiInfo.FontWeight = FW_DONTCARE;
ConsoleInfo->u.GuiInfo.UseRasterFonts = TRUE;
ConsoleInfo->u.GuiInfo.ShowWindow = SW_SHOWNORMAL;
ConsoleInfo->u.GuiInfo.AutoPosition = TRUE;
ConsoleInfo->u.GuiInfo.WindowOrigin = (POINT){0, 0};
// if (Console->ActiveBuffer)
// {
// Console->ActiveBuffer->ScreenBufferSize.X = 80;
// Console->ActiveBuffer->ScreenBufferSize.Y = 300;
// Console->ActiveBuffer->CursorInfo.bVisible = TRUE;
// }
/*
* 2. Overwrite them with the ones stored in HKCU\Console.
* If the HKCU\Console key doesn't exist, create it
* and store the default values inside.
*/
if (!ConSrvReadUserSettings(ConsoleInfo, ProcessId))
{
ConSrvWriteUserSettings(ConsoleInfo, ProcessId);
}
}
/* EOF */

View file

@ -0,0 +1,91 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/settings.h
* PURPOSE: Consoles settings management
* PROGRAMMERS: Hermes Belusca - Maito
*
* NOTE: Adapted from existing code.
*/
#define PM_APPLY_CONSOLE_INFO (WM_APP + 100)
/* STRUCTURES *****************************************************************/
typedef struct _GUI_CONSOLE_INFO
{
// FONTSIGNATURE FontSignature;
WCHAR FaceName[LF_FACESIZE];
UINT FontFamily;
DWORD FontSize;
DWORD FontWeight;
BOOL UseRasterFonts;
WORD ShowWindow;
BOOL AutoPosition;
POINT WindowOrigin;
} GUI_CONSOLE_INFO, *PGUI_CONSOLE_INFO;
typedef struct _CONSOLE_INFO
{
ULONG HistoryBufferSize;
ULONG NumberOfHistoryBuffers;
BOOLEAN HistoryNoDup;
/* BOOLEAN */ ULONG FullScreen; // Give the type of console: GUI (windowed) or TUI (fullscreen)
BOOLEAN QuickEdit;
BOOLEAN InsertMode;
ULONG InputBufferSize;
COORD ScreenBufferSize;
/* SIZE */ COORD ConsoleSize; // This is really the size of the console at screen.
BOOLEAN CursorBlinkOn;
BOOLEAN ForceCursorOff;
ULONG CursorSize;
USHORT ScreenAttrib; // CHAR_INFO ScreenFillAttrib
USHORT PopupAttrib;
// Color palette
COLORREF Colors[16];
ULONG CodePage;
WCHAR ConsoleTitle[MAX_PATH + 1];
union
{
GUI_CONSOLE_INFO GuiInfo;
// TUI_CONSOLE_INFO TuiInfo;
} u;
} CONSOLE_INFO, *PCONSOLE_INFO;
#define RGBFromAttrib(Console, Attribute) ((Console)->Colors[(Attribute) & 0xF])
#define TextAttribFromAttrib(Attribute) ((Attribute) & 0xF)
#define BkgdAttribFromAttrib(Attribute) (((Attribute) >> 4) & 0xF)
#define MakeAttrib(TextAttrib, BkgdAttrib) (DWORD)((((BkgdAttrib) & 0xF) << 4) | ((TextAttrib) & 0xF))
/* Used to communicate with console.dll */
typedef struct _CONSOLE_PROPS
{
HWND hConsoleWindow;
BOOL ShowDefaultParams;
BOOLEAN AppliedConfig;
DWORD ActiveStaticControl;
CONSOLE_INFO ci;
} CONSOLE_PROPS, *PCONSOLE_PROPS;
/* FUNCTIONS ******************************************************************/
BOOL ConSrvReadUserSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
IN DWORD ProcessId);
BOOL ConSrvWriteUserSettings(IN PCONSOLE_INFO ConsoleInfo,
IN DWORD ProcessId);
VOID ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
IN DWORD ProcessId);
/* EOF */

View file

@ -7,6 +7,7 @@
*/
#include "consrv.h"
#include "settings.h"
#include "tuiconsole.h"
#include <drivers/blue/ntddblue.h>
@ -150,366 +151,6 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
static BOOL FASTCALL
TuiInit(DWORD OemCP)
{
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
DWORD BytesReturned;
WNDCLASSEXW wc;
ATOM ConsoleClassAtom;
USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
ScmLoadDriver(L"Blue");
ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
{
DPRINT1("Failed to open BlueScreen.\n");
return FALSE;
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
&OemCP, sizeof(OemCP), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
/* Let's suppose the font is good enough to continue */
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
&TextAttribute, sizeof(TextAttribute), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to set text attribute\n");
}
ActiveConsole = NULL;
InitializeCriticalSection(&ActiveConsoleLock);
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
{
DPRINT1("Failed to get console info\n");
return FALSE;
}
PhysicalConsoleSize = ScrInfo.dwSize;
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
wc.lpfnWndProc = TuiConsoleWndProc;
wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
wc.hInstance = ConSrvDllInstance;
ConsoleClassAtom = RegisterClassExW(&wc);
if (ConsoleClassAtom == 0)
{
DPRINT1("Failed to register TUI console wndproc\n");
return FALSE;
}
else
{
NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
}
return TRUE;
}
static void FASTCALL
TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
UINT SrcDelta, DestDelta;
LONG i;
PBYTE Src, SrcEnd;
Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
SrcDelta = Buff->MaxX * 2;
SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2;
DestDelta = ConioRectWidth(Region) * 2;
for (i = Region->Top; i <= Region->Bottom; i++)
{
memcpy(Dest, Src, DestDelta);
Src += SrcDelta;
if (SrcEnd <= Src)
{
Src -= Buff->MaxY * Buff->MaxX * 2;
}
Dest += DestDelta;
}
}
static VOID WINAPI
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
{
DWORD BytesReturned;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
PCONSOLE_DRAW ConsoleDraw;
UINT ConsoleDrawSize;
if (ActiveConsole != Console)
{
return;
}
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
ConsoleDraw = RtlAllocateHeap(ConSrvHeap, 0, ConsoleDrawSize);
if (NULL == ConsoleDraw)
{
DPRINT1("RtlAllocateHeap failed\n");
return;
}
ConsoleDraw->X = Region->Left;
ConsoleDraw->Y = Region->Top;
ConsoleDraw->SizeX = ConioRectWidth(Region);
ConsoleDraw->SizeY = ConioRectHeight(Region);
ConsoleDraw->CursorX = Buff->CurrentX;
ConsoleDraw->CursorY = Buff->CurrentY;
TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
{
DPRINT1("Failed to draw console\n");
RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw);
return;
}
RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw);
}
static VOID WINAPI
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
{
DWORD BytesWritten;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
if (ActiveConsole->ActiveBuffer != Buff)
{
return;
}
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
{
DPRINT1("Error writing to BlueScreen\n");
}
}
static BOOL WINAPI
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
{
CONSOLE_CURSOR_INFO Info;
DWORD BytesReturned;
if (ActiveConsole->ActiveBuffer != Buff)
{
return TRUE;
}
Info.dwSize = ConioEffectiveCursorSize(Console, 100);
Info.bVisible = Buff->CursorInfo.bVisible;
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
&Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
{
DPRINT1( "Failed to set cursor info\n" );
return FALSE;
}
return TRUE;
}
static BOOL WINAPI
TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
{
CONSOLE_SCREEN_BUFFER_INFO Info;
DWORD BytesReturned;
if (ActiveConsole->ActiveBuffer != Buff)
{
return TRUE;
}
Info.dwCursorPosition.X = Buff->CurrentX;
Info.dwCursorPosition.Y = Buff->CurrentY;
Info.wAttributes = Buff->DefaultAttrib;
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
&Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1( "Failed to set cursor position\n" );
return FALSE;
}
return TRUE;
}
static BOOL WINAPI
TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
{
return TRUE;
}
static VOID WINAPI
TuiChangeTitle(PCONSOLE Console)
{
}
static VOID WINAPI
TuiCleanupConsole(PCONSOLE Console)
{
DestroyWindow(Console->hWindow);
EnterCriticalSection(&ActiveConsoleLock);
/* Switch to next console */
if (ActiveConsole == Console)
{
ActiveConsole = Console->Next != Console ? Console->Next : NULL;
}
if (Console->Next != Console)
{
Console->Prev->Next = Console->Next;
Console->Next->Prev = Console->Prev;
}
LeaveCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{
ConioDrawConsole(ActiveConsole);
}
}
static BOOL WINAPI
TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
{
return TRUE;
}
static NTSTATUS WINAPI
TuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
DWORD WINAPI
TuiConsoleThread(PVOID Data)
{
PCONSOLE Console = (PCONSOLE) Data;
HWND NewWindow;
MSG msg;
NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS,
Console->Title.Buffer,
0,
-32000, -32000, 0, 0,
NULL, NULL,
ConSrvDllInstance,
(PVOID)Console);
if (NULL == NewWindow)
{
DPRINT1("CONSRV: Unable to create console window\n");
return 1;
}
Console->hWindow = NewWindow;
SetConsoleWndConsoleLeaderCID(Console);
SetForegroundWindow(Console->hWindow);
while (TRUE)
{
GetMessageW(&msg, 0, 0, 0);
DispatchMessage(&msg);
TranslateMessage(&msg);
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
{
ConioProcessKey(&msg, Console, TRUE);
}
}
return 0;
}
static CONSOLE_VTBL TuiVtbl =
{
TuiWriteStream,
TuiDrawRegion,
TuiSetCursorInfo,
TuiSetScreenInfo,
TuiUpdateScreenInfo,
TuiChangeTitle,
TuiCleanupConsole,
TuiChangeIcon,
TuiResizeBuffer,
};
NTSTATUS FASTCALL
TuiInitConsole(PCONSOLE Console)
{
HANDLE ThreadHandle;
if (!ConsInitialized)
{
ConsInitialized = TRUE;
if (!TuiInit(Console->CodePage))
{
ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL;
}
}
Console->Vtbl = &TuiVtbl;
Console->hWindow = NULL;
Console->Size = PhysicalConsoleSize;
Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
ThreadHandle = CreateThread(NULL,
0,
TuiConsoleThread,
(PVOID)Console,
0,
NULL);
if (NULL == ThreadHandle)
{
DPRINT1("CONSRV: Unable to create console thread\n");
return STATUS_UNSUCCESSFUL;
}
CloseHandle(ThreadHandle);
EnterCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{
Console->Prev = ActiveConsole;
Console->Next = ActiveConsole->Next;
ActiveConsole->Next->Prev = Console;
ActiveConsole->Next = Console;
}
else
{
Console->Prev = Console;
Console->Next = Console;
}
ActiveConsole = Console;
LeaveCriticalSection(&ActiveConsoleLock);
return STATUS_SUCCESS;
}
PCONSOLE FASTCALL
TuiGetFocusConsole(VOID)
{
return ActiveConsole;
}
BOOL FASTCALL
TuiSwapConsole(INT Next)
{
static PCONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */
@ -579,4 +220,385 @@ TuiSwapConsole(INT Next)
}
}
static BOOL WINAPI
TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down)
{
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) &&
VK_TAB == VirtualKeyCode)
{
if (Down)
{
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
}
return TRUE;
}
else if (VK_MENU == VirtualKeyCode && !Down)
{
return TuiSwapConsole(0);
}
return FALSE;
}
static BOOL FASTCALL
TuiInit(DWORD OemCP)
{
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
DWORD BytesReturned;
WNDCLASSEXW wc;
ATOM ConsoleClassAtom;
USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
ScmLoadDriver(L"Blue");
ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
{
DPRINT1("Failed to open BlueScreen.\n");
return FALSE;
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
&OemCP, sizeof(OemCP), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
/* Let's suppose the font is good enough to continue */
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
&TextAttribute, sizeof(TextAttribute), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to set text attribute\n");
}
ActiveConsole = NULL;
InitializeCriticalSection(&ActiveConsoleLock);
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
{
DPRINT1("Failed to get console info\n");
return FALSE;
}
PhysicalConsoleSize = ScrInfo.dwSize;
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = TUI_CONSOLE_WINDOW_CLASS;
wc.lpfnWndProc = TuiConsoleWndProc;
wc.cbWndExtra = GWLP_CONSOLEWND_ALLOC;
wc.hInstance = ConSrvDllInstance;
ConsoleClassAtom = RegisterClassExW(&wc);
if (ConsoleClassAtom == 0)
{
DPRINT1("Failed to register TUI console wndproc\n");
return FALSE;
}
else
{
NtUserConsoleControl(TuiConsoleWndClassAtom, &ConsoleClassAtom, sizeof(ATOM));
}
return TRUE;
}
static VOID FASTCALL
TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
UINT SrcDelta, DestDelta;
LONG i;
PBYTE Src, SrcEnd;
Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
SrcDelta = Buff->ScreenBufferSize.X * 2;
SrcEnd = Buff->Buffer + Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
DestDelta = ConioRectWidth(Region) * 2;
for (i = Region->Top; i <= Region->Bottom; i++)
{
memcpy(Dest, Src, DestDelta);
Src += SrcDelta;
if (SrcEnd <= Src)
{
Src -= Buff->ScreenBufferSize.Y * Buff->ScreenBufferSize.X * 2;
}
Dest += DestDelta;
}
}
static VOID WINAPI
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
{
DWORD BytesReturned;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
PCONSOLE_DRAW ConsoleDraw;
UINT ConsoleDrawSize;
if (ActiveConsole != Console)
{
return;
}
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
ConsoleDraw = RtlAllocateHeap(ConSrvHeap, 0, ConsoleDrawSize);
if (NULL == ConsoleDraw)
{
DPRINT1("RtlAllocateHeap failed\n");
return;
}
ConsoleDraw->X = Region->Left;
ConsoleDraw->Y = Region->Top;
ConsoleDraw->SizeX = ConioRectWidth(Region);
ConsoleDraw->SizeY = ConioRectHeight(Region);
ConsoleDraw->CursorX = Buff->CursorPosition.X;
ConsoleDraw->CursorY = Buff->CursorPosition.Y;
TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
{
DPRINT1("Failed to draw console\n");
RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw);
return;
}
RtlFreeHeap(ConSrvHeap, 0, ConsoleDraw);
}
static VOID WINAPI
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, LONG CursorStartX, LONG CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
{
DWORD BytesWritten;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
if (ActiveConsole->ActiveBuffer != Buff)
{
return;
}
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
{
DPRINT1("Error writing to BlueScreen\n");
}
}
static BOOL WINAPI
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
{
CONSOLE_CURSOR_INFO Info;
DWORD BytesReturned;
if (ActiveConsole->ActiveBuffer != Buff)
{
return TRUE;
}
Info.dwSize = ConioEffectiveCursorSize(Console, 100);
Info.bVisible = Buff->CursorInfo.bVisible;
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
&Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
{
DPRINT1( "Failed to set cursor info\n" );
return FALSE;
}
return TRUE;
}
static BOOL WINAPI
TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
{
CONSOLE_SCREEN_BUFFER_INFO Info;
DWORD BytesReturned;
if (ActiveConsole->ActiveBuffer != Buff)
{
return TRUE;
}
Info.dwCursorPosition = Buff->CursorPosition;
Info.wAttributes = Buff->ScreenDefaultAttrib;
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
&Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1( "Failed to set cursor position\n" );
return FALSE;
}
return TRUE;
}
static BOOL WINAPI
TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
{
return TRUE;
}
static VOID WINAPI
TuiChangeTitle(PCONSOLE Console)
{
}
static VOID WINAPI
TuiCleanupConsole(PCONSOLE Console)
{
DestroyWindow(Console->hWindow);
EnterCriticalSection(&ActiveConsoleLock);
/* Switch to next console */
if (ActiveConsole == Console)
{
ActiveConsole = Console->Next != Console ? Console->Next : NULL;
}
if (Console->Next != Console)
{
Console->Prev->Next = Console->Next;
Console->Next->Prev = Console->Prev;
}
LeaveCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{
ConioDrawConsole(ActiveConsole);
}
}
static BOOL WINAPI
TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon)
{
return TRUE;
}
static NTSTATUS WINAPI
TuiResizeBuffer(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER ScreenBuffer, COORD Size)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
static DWORD WINAPI
TuiConsoleThread(PVOID Data)
{
PCONSOLE Console = (PCONSOLE) Data;
HWND NewWindow;
MSG msg;
NewWindow = CreateWindowW(TUI_CONSOLE_WINDOW_CLASS,
Console->Title.Buffer,
0,
-32000, -32000, 0, 0,
NULL, NULL,
ConSrvDllInstance,
(PVOID)Console);
if (NULL == NewWindow)
{
DPRINT1("CONSRV: Unable to create console window\n");
return 1;
}
Console->hWindow = NewWindow;
SetConsoleWndConsoleLeaderCID(Console);
SetForegroundWindow(Console->hWindow);
while (TRUE)
{
GetMessageW(&msg, 0, 0, 0);
DispatchMessage(&msg);
TranslateMessage(&msg);
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN ||
msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP)
{
ConioProcessKey(Console, &msg);
}
}
return 0;
}
static CONSOLE_VTBL TuiVtbl =
{
TuiWriteStream,
TuiDrawRegion,
TuiSetCursorInfo,
TuiSetScreenInfo,
TuiUpdateScreenInfo,
TuiChangeTitle,
TuiCleanupConsole,
TuiChangeIcon,
TuiResizeBuffer,
TuiProcessKeyCallback
};
NTSTATUS FASTCALL
TuiInitConsole(PCONSOLE Console,
PCONSOLE_INFO ConsoleInfo)
{
HANDLE ThreadHandle;
if (!ConsInitialized)
{
ConsInitialized = TRUE;
if (!TuiInit(Console->CodePage))
{
ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL;
}
}
Console->Vtbl = &TuiVtbl;
Console->hWindow = NULL;
Console->Size = PhysicalConsoleSize;
Console->ActiveBuffer->ScreenBufferSize = PhysicalConsoleSize;
ThreadHandle = CreateThread(NULL,
0,
TuiConsoleThread,
(PVOID)Console,
0,
NULL);
if (NULL == ThreadHandle)
{
DPRINT1("CONSRV: Unable to create console thread\n");
return STATUS_UNSUCCESSFUL;
}
CloseHandle(ThreadHandle);
EnterCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{
Console->Prev = ActiveConsole;
Console->Next = ActiveConsole->Next;
ActiveConsole->Next->Prev = Console;
ActiveConsole->Next = Console;
}
else
{
Console->Prev = Console;
Console->Next = Console;
}
ActiveConsole = Console;
LeaveCriticalSection(&ActiveConsoleLock);
return STATUS_SUCCESS;
}
PCONSOLE FASTCALL
TuiGetFocusConsole(VOID)
{
return ActiveConsole;
}
/* EOF */

View file

@ -8,8 +8,8 @@
#include "conio.h"
extern NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console);
extern PCONSOLE FASTCALL TuiGetFocusConsole(VOID);
extern BOOL FASTCALL TuiSwapConsole(INT Next);
NTSTATUS FASTCALL TuiInitConsole(PCONSOLE Console,
PCONSOLE_INFO ConsoleInfo);
PCONSOLE FASTCALL TuiGetFocusConsole(VOID);
/* EOF */