mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[REACTOS]
Merge back condrv_restructure branch with everything up to revision 64079 (and up for maintenance), that made console kernel32 & winsrv CSR structures Win2k3 compliant. CORE-7931 #comment Merged back to trunk in revision 64102. CORE-7481 #comment kernel32 / winsrv console CSR structures are Win2k3-compliant in trunk since revision 64102 (and since revision 64079 in the condrv_restructure branch, see CORE-7931 for more details). svn path=/trunk/; revision=64102
This commit is contained in:
commit
e393b80e07
71 changed files with 4178 additions and 2881 deletions
|
@ -72,7 +72,7 @@
|
|||
GuiData->CharWidth = Metrics.tmMaxCharWidth;
|
||||
GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
|
||||
|
||||
/* Measure real char width more precisely if possible. */
|
||||
/* Measure real char width more precisely if possible */
|
||||
if (GetTextExtentPoint32W(drawItem->hDC, L"R", 1, &CharSize))
|
||||
GuiData->CharWidth = CharSize.cx;
|
||||
}
|
||||
|
@ -102,12 +102,9 @@ EnumFontNamesProc(PLOGFONTW lplf,
|
|||
HWND hwndCombo = (HWND)lParam;
|
||||
LPWSTR pszName = lplf->lfFaceName;
|
||||
|
||||
BOOL fFixed;
|
||||
BOOL fTrueType;
|
||||
|
||||
/* Record the font's attributes (Fixedwidth and Truetype) */
|
||||
fFixed = ((lplf->lfPitchAndFamily & 0x03) == FIXED_PITCH);
|
||||
fTrueType = (lplf->lfOutPrecision == OUT_STROKE_PRECIS) ? TRUE : FALSE;
|
||||
// BOOL fFixed = ((lplf->lfPitchAndFamily & 0x03) == FIXED_PITCH);
|
||||
// BOOL fTrueType = (lplf->lfOutPrecision == OUT_STROKE_PRECIS);
|
||||
|
||||
/*
|
||||
* According to: http://support.microsoft.com/kb/247815
|
||||
|
@ -158,7 +155,8 @@ EnumFontNamesProc(PLOGFONTW lplf,
|
|||
/* Reject TrueType fonts that are not FF_MODERN */
|
||||
if ((FontType == TRUETYPE_FONTTYPE) && ((lplf->lfPitchAndFamily & 0xF0) != FF_MODERN))
|
||||
{
|
||||
DPRINT1("TrueType font '%S' rejected because it's not FF_MODERN (lfPitchAndFamily = %d)\n", pszName, lplf->lfPitchAndFamily);
|
||||
DPRINT1("TrueType font '%S' rejected because it's not FF_MODERN (lfPitchAndFamily = %d)\n",
|
||||
pszName, lplf->lfPitchAndFamily);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -166,14 +164,16 @@ EnumFontNamesProc(PLOGFONTW lplf,
|
|||
#if 0
|
||||
if ((FontType != TRUETYPE_FONTTYPE) && (lplf->lfCharSet != OEM_CHARSET))
|
||||
{
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not OEM_CHARSET %d\n", pszName, lplf->lfCharSet);
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not OEM_CHARSET %d\n",
|
||||
pszName, lplf->lfCharSet);
|
||||
return TRUE;
|
||||
}
|
||||
#else // Improved criterium
|
||||
if ((FontType != TRUETYPE_FONTTYPE) &&
|
||||
((lplf->lfCharSet != ANSI_CHARSET) && (lplf->lfCharSet != DEFAULT_CHARSET) && (lplf->lfCharSet != OEM_CHARSET)))
|
||||
{
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not ANSI_CHARSET or DEFAULT_CHARSET or OEM_CHARSET (lfCharSet = %d)\n", pszName, lplf->lfCharSet);
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not ANSI_CHARSET or DEFAULT_CHARSET or OEM_CHARSET (lfCharSet = %d)\n",
|
||||
pszName, lplf->lfCharSet);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
@ -205,7 +205,8 @@ EnumFontNamesProc(PLOGFONTW lplf,
|
|||
DPRINT1("Add font '%S' (lfPitchAndFamily = %d)\n", pszName, lplf->lfPitchAndFamily);
|
||||
|
||||
/* Store this information in the list-item's userdata area */
|
||||
SendMessageW(hwndCombo, LB_SETITEMDATA, idx, MAKEWPARAM(fFixed, fTrueType));
|
||||
// SendMessageW(hwndCombo, LB_SETITEMDATA, idx, MAKEWPARAM(fFixed, fTrueType));
|
||||
SendMessageW(hwndCombo, LB_SETITEMDATA, idx, (WPARAM)FontType);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -247,7 +248,7 @@ EnumFontSizesProc(PLOGFONTW lplf,
|
|||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
ULONG i;
|
||||
for (i = 0; i < sizeof(TrueTypePoints) / sizeof(TrueTypePoints[0]); ++i)
|
||||
{
|
||||
swprintf(FontSize, L"%2d", TrueTypePoints[i]);
|
||||
|
@ -273,7 +274,6 @@ EnumFontSizesProc(PLOGFONTW lplf,
|
|||
}
|
||||
|
||||
|
||||
|
||||
static VOID
|
||||
FontSizeChange(HWND hwndDlg,
|
||||
PGUI_CONSOLE_INFO GuiInfo);
|
||||
|
|
|
@ -35,10 +35,10 @@ BEGIN
|
|||
LTEXT "Прозоречен преглед:", -1, 10, 10, 94, 10
|
||||
LTEXT "Размер:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Шрифт:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Получери шрифтове", IDC_CHECK_BOLD_FONTS, 38, 105, 85, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Всеки знак е:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -41,10 +41,10 @@ BEGIN
|
|||
LTEXT "Náhled okna:", -1, 10, 10, 94, 10
|
||||
LTEXT "Velikost:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Písmo:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Tučná písma", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Každý znak je:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Fenstervorschau", -1, 10, 7, 65, 10
|
||||
LTEXT "Größe", -1, 130, 10, 30, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Schrift", -1, 10, 105, 35, 10
|
||||
CHECKBOX "&Fette Schriften", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 10, 155, 200, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 15, 165, 95, 35
|
||||
LTEXT "Jedes Zeichen ist:", -1, 130, 165, 75, 10
|
||||
|
|
|
@ -35,10 +35,10 @@ BEGIN
|
|||
LTEXT "Window Preview:", -1, 10, 10, 94, 10
|
||||
LTEXT "Size:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Font:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Bold fonts", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Each character is:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Ventana de Previsualización", -1, 10, 7, 65, 10
|
||||
LTEXT "Tamaño", -1, 130, 10, 30, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Fuente", -1, 10, 105, 35, 10
|
||||
CHECKBOX "&Negrita", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 10, 155, 200, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 15, 165, 95, 35
|
||||
LTEXT "Cada caracter es:", -1, 130, 165, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Fenêtre de Prévisualisation :", -1, 10, 10, 94, 10
|
||||
LTEXT "Taille :", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Police :", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Gras", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Chaque caractère utilise :", -1, 124, 166, 85, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "תצוגה מקדימה:", -1, 10, 10, 94, 10
|
||||
LTEXT "גודל:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "גופן:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "גופנים מודגשים", IDC_CHECK_BOLD_FONTS, 41, 105, 33, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Each character is:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Tinjauan Jendela", -1, 10, 7, 65, 10
|
||||
LTEXT "Ukuran", -1, 130, 10, 30, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Font", -1, 10, 105, 35, 10
|
||||
CHECKBOX "Font &tebal", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 10, 155, 200, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 15, 165, 95, 35
|
||||
LTEXT "Setiap karakter adalah:", -1, 130, 165, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Anteprima", -1, 10, 7, 65, 10
|
||||
LTEXT "Dimansione", -1, 130, 10, 30, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Font", -1, 10, 105, 35, 10
|
||||
CHECKBOX "&Grassetto fonts", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 10, 155, 200, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 15, 165, 95, 35
|
||||
LTEXT "Ogni carattere è:", -1, 130, 165, 75, 10
|
||||
|
|
|
@ -35,10 +35,10 @@ BEGIN
|
|||
LTEXT "Vindu forhåndsvisning:", -1, 10, 10, 94, 10
|
||||
LTEXT "Størrelse:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Skrift:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Fet skrift", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Hver tegn er:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -42,10 +42,10 @@ BEGIN
|
|||
LTEXT "Okno podglądu", -1, 10, 7, 65, 10
|
||||
LTEXT "Rozmiar", -1, 130, 10, 30, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Czcionka", -1, 10, 105, 35, 10
|
||||
CHECKBOX "&Pogrubiona czcionka", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 10, 155, 200, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 15, 165, 95, 35
|
||||
LTEXT "Pogrubiona czcionka:", -1, 130, 165, 75, 10
|
||||
|
|
|
@ -44,10 +44,10 @@ BEGIN
|
|||
LTEXT "Previzionare:", -1, 10, 10, 94, 10
|
||||
LTEXT "&Mărime:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "F&ont:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Aldin", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Fiecare caracter are:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Окно предпросмотра:", -1, 10, 10, 94, 10
|
||||
LTEXT "Размер:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Шрифт:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Жирный", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Каждый символ:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -39,10 +39,10 @@ BEGIN
|
|||
LTEXT "Ukážka okna:", -1, 10, 10, 94, 10
|
||||
LTEXT "Veľkosť:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Písmo:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Tučné písma", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Každý znak je:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -39,10 +39,10 @@ BEGIN
|
|||
LTEXT "Dritare Preview:", -1, 10, 10, 94, 10
|
||||
LTEXT "Masë:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Font:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Bold fonts", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Çdo krarakter është:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Pencere Ön İzlemesi:", -1, 10, 10, 94, 10
|
||||
LTEXT "&Boyutlar:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Yazı Tipi:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Kalın Yazı Tipleri", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Tüm damgalar:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "Зразок вікна", -1, 10, 10, 94, 10
|
||||
LTEXT "Size:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&Шрифт:", -1, 10, 105, 33, 10
|
||||
CHECKBOX "&Жирні", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "Кожен символ:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -37,10 +37,10 @@ BEGIN
|
|||
LTEXT "窗口预览:", -1, 10, 10, 94, 10
|
||||
LTEXT "大小:", -1, 180, 10, 36, 10
|
||||
CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
LTEXT "&字体(&F):", -1, 10, 105, 33, 10
|
||||
CHECKBOX "粗体(&B)", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL
|
||||
LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | WS_VSCROLL
|
||||
GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50
|
||||
CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35
|
||||
LTEXT "每个字符为:", -1, 124, 166, 75, 10
|
||||
|
|
|
@ -107,6 +107,8 @@ PaintText(LPDRAWITEMSTRUCT drawItem,
|
|||
HBRUSH hBrush;
|
||||
HFONT Font, OldFont;
|
||||
|
||||
COORD FontSize = GuiInfo->FontSize;
|
||||
|
||||
if (TextMode == Screen)
|
||||
CurrentAttrib = pConInfo->ci.ScreenAttrib;
|
||||
else if (TextMode == Popup)
|
||||
|
@ -120,8 +122,11 @@ PaintText(LPDRAWITEMSTRUCT drawItem,
|
|||
hBrush = CreateSolidBrush(nbkColor);
|
||||
if (!hBrush) return FALSE;
|
||||
|
||||
Font = CreateFontW(GuiInfo->FontSize.Y,
|
||||
GuiInfo->FontSize.X,
|
||||
FontSize.Y = FontSize.Y > 0 ? -MulDiv(FontSize.Y, GetDeviceCaps(drawItem->hDC, LOGPIXELSY), 72)
|
||||
: FontSize.Y;
|
||||
|
||||
Font = CreateFontW(FontSize.Y,
|
||||
FontSize.X,
|
||||
0,
|
||||
TA_BASELINE,
|
||||
GuiInfo->FontWeight,
|
||||
|
@ -131,7 +136,7 @@ PaintText(LPDRAWITEMSTRUCT drawItem,
|
|||
OEM_CHARSET,
|
||||
OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY, // NONANTIALIASED_QUALITY ; ANTIALIASED_QUALITY
|
||||
DEFAULT_QUALITY,
|
||||
FIXED_PITCH | GuiInfo->FontFamily,
|
||||
GuiInfo->FaceName);
|
||||
if (Font == NULL)
|
||||
|
@ -154,7 +159,7 @@ PaintText(LPDRAWITEMSTRUCT drawItem,
|
|||
DrawTextW(drawItem->hDC, szPreviewText, wcslen(szPreviewText), &drawItem->rcItem, 0);
|
||||
SetTextColor(drawItem->hDC, ptColor);
|
||||
SetBkColor(drawItem->hDC, pbkColor);
|
||||
DeleteObject((HGDIOBJ)hBrush);
|
||||
DeleteObject(hBrush);
|
||||
|
||||
SelectObject(drawItem->hDC, OldFont);
|
||||
DeleteObject(Font);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,30 +25,6 @@ IntStringSize(LPCVOID String,
|
|||
ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR);
|
||||
return (Size + 3) & ~3;
|
||||
}
|
||||
|
||||
|
||||
/* Copy a string to a capture buffer */
|
||||
static VOID
|
||||
IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
|
||||
LPCVOID String,
|
||||
BOOL Unicode,
|
||||
PUNICODE_STRING RequestString)
|
||||
{
|
||||
ULONG Size;
|
||||
if (Unicode)
|
||||
{
|
||||
Size = wcslen(String) * sizeof(WCHAR);
|
||||
CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)String, Size, (PVOID *)&RequestString->Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Size = strlen(String);
|
||||
CsrAllocateMessagePointer(CaptureBuffer, Size * sizeof(WCHAR), (PVOID *)&RequestString->Buffer);
|
||||
Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR))
|
||||
* sizeof(WCHAR);
|
||||
}
|
||||
RequestString->Length = RequestString->MaximumLength = (USHORT)Size;
|
||||
}
|
||||
#endif
|
||||
|
||||
static VOID
|
||||
|
@ -80,8 +56,6 @@ IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOLEAN bUnicode)
|
|||
return;
|
||||
}
|
||||
|
||||
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
|
||||
// &ExpungeCommandHistoryRequest->ExeName);
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
(PVOID)lpExeName,
|
||||
ExpungeCommandHistoryRequest->ExeLength,
|
||||
|
@ -131,14 +105,11 @@ IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName
|
|||
return 0;
|
||||
}
|
||||
|
||||
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
|
||||
// &GetCommandHistoryRequest->ExeName);
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
(PVOID)lpExeName,
|
||||
GetCommandHistoryRequest->ExeLength,
|
||||
(PVOID)&GetCommandHistoryRequest->ExeName);
|
||||
|
||||
// CsrAllocateMessagePointer(CaptureBuffer, HistoryLength,
|
||||
CsrAllocateMessagePointer(CaptureBuffer, GetCommandHistoryRequest->HistoryLength,
|
||||
(PVOID*)&GetCommandHistoryRequest->History);
|
||||
|
||||
|
@ -192,8 +163,6 @@ IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
|
||||
// &GetCommandHistoryLengthRequest->ExeName);
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
(PVOID)lpExeName,
|
||||
GetCommandHistoryLengthRequest->ExeLength,
|
||||
|
@ -248,8 +217,6 @@ IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
|
||||
// &SetHistoryNumberCommandsRequest->ExeName);
|
||||
CsrCaptureMessageBuffer(CaptureBuffer,
|
||||
(PVOID)lpExeName,
|
||||
SetHistoryNumberCommandsRequest->ExeLength,
|
||||
|
|
|
@ -22,15 +22,14 @@
|
|||
/* GLOBALS ********************************************************************/
|
||||
|
||||
RTL_CRITICAL_SECTION ConsoleLock;
|
||||
BOOL ConsoleInitialized = FALSE;
|
||||
BOOLEAN ConsoleInitialized = FALSE;
|
||||
|
||||
extern HANDLE InputWaitHandle;
|
||||
|
||||
static HMODULE ConsoleLibrary = NULL;
|
||||
static HMODULE ConsoleApplet = NULL;
|
||||
static BOOL AlreadyDisplayingProps = FALSE;
|
||||
|
||||
#define WIN_OBJ_DIR L"\\Windows"
|
||||
#define SESSION_DIR L"\\Sessions"
|
||||
static const PWSTR DefaultConsoleTitle = L"ReactOS Console";
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -41,6 +40,7 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
|||
{
|
||||
// NOTE: lpThreadParameter corresponds to the client shared section handle.
|
||||
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
APPLET_PROC CPLFunc;
|
||||
|
||||
/*
|
||||
|
@ -60,223 +60,242 @@ PropDialogHandler(IN LPVOID lpThreadParameter)
|
|||
AlreadyDisplayingProps = TRUE;
|
||||
|
||||
/* Load the Control Applet if needed */
|
||||
if (ConsoleLibrary == NULL)
|
||||
if (ConsoleApplet == NULL)
|
||||
{
|
||||
WCHAR szBuffer[MAX_PATH];
|
||||
|
||||
GetSystemDirectoryW(szBuffer, MAX_PATH);
|
||||
wcscat(szBuffer, L"\\console.dll");
|
||||
ConsoleLibrary = LoadLibraryW(szBuffer);
|
||||
|
||||
if (ConsoleLibrary == NULL)
|
||||
ConsoleApplet = LoadLibraryW(szBuffer);
|
||||
if (ConsoleApplet == NULL)
|
||||
{
|
||||
DPRINT1("Failed to load console.dll\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load its main function */
|
||||
CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleLibrary, "CPlApplet");
|
||||
CPLFunc = (APPLET_PROC)GetProcAddress(ConsoleApplet, "CPlApplet");
|
||||
if (CPLFunc == NULL)
|
||||
{
|
||||
DPRINT("Error: Console.dll misses CPlApplet export\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT1("Error: Console.dll misses CPlApplet export\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
if (CPLFunc(NULL, CPL_INIT, 0, 0) == FALSE)
|
||||
{
|
||||
DPRINT("Error: failed to initialize console.dll\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT1("Error: failed to initialize console.dll\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
if (CPLFunc(NULL, CPL_GETCOUNT, 0, 0) != 1)
|
||||
{
|
||||
DPRINT("Error: console.dll returned unexpected CPL count\n");
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT1("Error: console.dll returned unexpected CPL count\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
CPLFunc(NULL, CPL_DBLCLK, (LPARAM)lpThreadParameter, 0);
|
||||
CPLFunc(NULL, CPL_EXIT , 0, 0);
|
||||
|
||||
Quit:
|
||||
AlreadyDisplayingProps = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static INT
|
||||
ParseShellInfo(LPCWSTR lpszShellInfo,
|
||||
LPCWSTR lpszKeyword)
|
||||
{
|
||||
DPRINT1("ParseShellInfo is UNIMPLEMENTED\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* The "LPDWORD Length" parameters point on input to the maximum size of
|
||||
* the buffers that can hold data (if != 0), and on output they hold the
|
||||
* real size of the data. If "Length" are == 0 on input, then on output
|
||||
* they receive the full size of the data.
|
||||
* The "LPWSTR* lpTitle" parameter has a double meaning:
|
||||
* - when "CaptureTitle" is TRUE, data is copied to the buffer pointed
|
||||
* by the pointer (*lpTitle).
|
||||
* - when "CaptureTitle" is FALSE, "*lpTitle" is set to the address of
|
||||
* the source data.
|
||||
*/
|
||||
VOID
|
||||
SetUpConsoleInfo(IN BOOLEAN CaptureTitle,
|
||||
IN OUT LPDWORD pTitleLength,
|
||||
IN OUT LPWSTR* lpTitle OPTIONAL,
|
||||
IN OUT LPDWORD pDesktopLength,
|
||||
IN OUT LPWSTR* lpDesktop OPTIONAL,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo)
|
||||
{
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
DWORD Length;
|
||||
|
||||
/* Initialize the fields */
|
||||
|
||||
ConsoleStartInfo->IconIndex = 0;
|
||||
ConsoleStartInfo->hIcon = NULL;
|
||||
ConsoleStartInfo->hIconSm = NULL;
|
||||
ConsoleStartInfo->dwStartupFlags = Parameters->WindowFlags;
|
||||
ConsoleStartInfo->nFont = 0;
|
||||
ConsoleStartInfo->nInputBufferSize = 0;
|
||||
ConsoleStartInfo->uCodePage = GetOEMCP();
|
||||
|
||||
if (lpTitle)
|
||||
{
|
||||
LPWSTR Title;
|
||||
|
||||
/* If we don't have any title, use the default one */
|
||||
if (Parameters->WindowTitle.Buffer == NULL)
|
||||
{
|
||||
Title = DefaultConsoleTitle;
|
||||
Length = lstrlenW(DefaultConsoleTitle) * sizeof(WCHAR); // sizeof(DefaultConsoleTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
Title = Parameters->WindowTitle.Buffer;
|
||||
Length = Parameters->WindowTitle.Length;
|
||||
}
|
||||
|
||||
/* Retrieve the needed buffer size */
|
||||
Length += sizeof(WCHAR);
|
||||
if (*pTitleLength > 0) Length = min(Length, *pTitleLength);
|
||||
*pTitleLength = Length;
|
||||
|
||||
/* Capture the data if needed, or, return a pointer to it */
|
||||
if (CaptureTitle)
|
||||
{
|
||||
/*
|
||||
* Length is always >= sizeof(WCHAR). Copy everything but the
|
||||
* possible trailing NULL character, and then NULL-terminate.
|
||||
*/
|
||||
Length -= sizeof(WCHAR);
|
||||
RtlCopyMemory(*lpTitle, Title, Length);
|
||||
(*lpTitle)[Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*lpTitle = Title;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pTitleLength = 0;
|
||||
}
|
||||
|
||||
if (lpDesktop && Parameters->DesktopInfo.Buffer && *Parameters->DesktopInfo.Buffer)
|
||||
{
|
||||
/* Retrieve the needed buffer size */
|
||||
Length = Parameters->DesktopInfo.Length + sizeof(WCHAR);
|
||||
if (*pDesktopLength > 0) Length = min(Length, *pDesktopLength);
|
||||
*pDesktopLength = Length;
|
||||
|
||||
/* Return a pointer to the data */
|
||||
*lpDesktop = Parameters->DesktopInfo.Buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pDesktopLength = 0;
|
||||
if (lpDesktop) *lpDesktop = NULL;
|
||||
}
|
||||
|
||||
if (Parameters->WindowFlags & STARTF_USEFILLATTRIBUTE)
|
||||
{
|
||||
ConsoleStartInfo->wFillAttribute = (WORD)Parameters->FillAttribute;
|
||||
}
|
||||
if (Parameters->WindowFlags & STARTF_USECOUNTCHARS)
|
||||
{
|
||||
ConsoleStartInfo->dwScreenBufferSize.X = (SHORT)Parameters->CountCharsX;
|
||||
ConsoleStartInfo->dwScreenBufferSize.Y = (SHORT)Parameters->CountCharsY;
|
||||
}
|
||||
if (Parameters->WindowFlags & STARTF_USESHOWWINDOW)
|
||||
{
|
||||
ConsoleStartInfo->wShowWindow = (WORD)Parameters->ShowWindowFlags;
|
||||
}
|
||||
if (Parameters->WindowFlags & STARTF_USEPOSITION)
|
||||
{
|
||||
ConsoleStartInfo->dwWindowOrigin.X = (SHORT)Parameters->StartingX;
|
||||
ConsoleStartInfo->dwWindowOrigin.Y = (SHORT)Parameters->StartingY;
|
||||
}
|
||||
if (Parameters->WindowFlags & STARTF_USESIZE)
|
||||
{
|
||||
ConsoleStartInfo->dwWindowSize.X = (SHORT)Parameters->CountX;
|
||||
ConsoleStartInfo->dwWindowSize.Y = (SHORT)Parameters->CountY;
|
||||
}
|
||||
|
||||
/* Get shell information (ShellInfo.Buffer is NULL-terminated) */
|
||||
if (Parameters->ShellInfo.Buffer != NULL)
|
||||
{
|
||||
ConsoleStartInfo->IconIndex = ParseShellInfo(Parameters->ShellInfo.Buffer, L"dde.");
|
||||
|
||||
if ((Parameters->WindowFlags & STARTF_USEHOTKEY) == 0)
|
||||
ConsoleStartInfo->dwHotKey = ParseShellInfo(Parameters->ShellInfo.Buffer, L"hotkey.");
|
||||
else
|
||||
ConsoleStartInfo->dwHotKey = HandleToUlong(Parameters->StandardInput);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN PUNICODE_STRING ImagePathName)
|
||||
SetUpHandles(IN PCONSOLE_START_INFO ConsoleStartInfo)
|
||||
{
|
||||
STARTUPINFOW si;
|
||||
SIZE_T Length;
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
|
||||
/* Get the startup information */
|
||||
GetStartupInfoW(&si);
|
||||
|
||||
/* Initialize the fields */
|
||||
ConsoleStartInfo->dwStartupFlags = si.dwFlags;
|
||||
if (si.dwFlags & STARTF_USEFILLATTRIBUTE)
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEHOTKEY)
|
||||
{
|
||||
ConsoleStartInfo->wFillAttribute = (WORD)si.dwFillAttribute;
|
||||
Parameters->WindowFlags &= ~STARTF_USEHOTKEY;
|
||||
}
|
||||
if (si.dwFlags & STARTF_USECOUNTCHARS)
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_SHELLPRIVATE)
|
||||
{
|
||||
ConsoleStartInfo->dwScreenBufferSize.X = (SHORT)(si.dwXCountChars);
|
||||
ConsoleStartInfo->dwScreenBufferSize.Y = (SHORT)(si.dwYCountChars);
|
||||
}
|
||||
if (si.dwFlags & STARTF_USESHOWWINDOW)
|
||||
{
|
||||
ConsoleStartInfo->wShowWindow = si.wShowWindow;
|
||||
}
|
||||
if (si.dwFlags & STARTF_USEPOSITION)
|
||||
{
|
||||
ConsoleStartInfo->dwWindowOrigin.X = (SHORT)(si.dwX);
|
||||
ConsoleStartInfo->dwWindowOrigin.Y = (SHORT)(si.dwY);
|
||||
}
|
||||
if (si.dwFlags & STARTF_USESIZE)
|
||||
{
|
||||
ConsoleStartInfo->dwWindowSize.X = (SHORT)(si.dwXSize);
|
||||
ConsoleStartInfo->dwWindowSize.Y = (SHORT)(si.dwYSize);
|
||||
Parameters->WindowFlags &= ~STARTF_SHELLPRIVATE;
|
||||
}
|
||||
|
||||
/* Set up the title for the console */
|
||||
if (si.lpTitle)
|
||||
{
|
||||
wcsncpy(ConsoleStartInfo->ConsoleTitle, si.lpTitle, MAX_PATH + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleStartInfo->ConsoleTitle[0] = L'\0';
|
||||
}
|
||||
/* We got the handles, let's set them */
|
||||
Parameters->ConsoleHandle = ConsoleStartInfo->ConsoleHandle;
|
||||
|
||||
/* Retrieve the application path name */
|
||||
Length = min(sizeof(ConsoleStartInfo->AppPath) / sizeof(ConsoleStartInfo->AppPath[0]) - 1,
|
||||
ImagePathName->Length / sizeof(WCHAR));
|
||||
wcsncpy(ConsoleStartInfo->AppPath, ImagePathName->Buffer, Length);
|
||||
ConsoleStartInfo->AppPath[Length] = L'\0';
|
||||
|
||||
/* The Console Server will use these fields to set up the console icon */
|
||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
||||
ConsoleStartInfo->IconIndex = 0;
|
||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_USESTDHANDLES) == 0)
|
||||
{
|
||||
Parameters->StandardInput = ConsoleStartInfo->InputHandle;
|
||||
Parameters->StandardOutput = ConsoleStartInfo->OutputHandle;
|
||||
Parameters->StandardError = ConsoleStartInfo->ErrorHandle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
BasepInitConsole(VOID)
|
||||
static BOOLEAN
|
||||
IsConsoleApp(VOID)
|
||||
{
|
||||
PIMAGE_NT_HEADERS ImageNtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
|
||||
return (ImageNtHeader && (ImageNtHeader->OptionalHeader.Subsystem ==
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CUI));
|
||||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
ConnectConsole(IN PWSTR SessionDir,
|
||||
IN PCONSRV_API_CONNECTINFO ConnectInfo,
|
||||
OUT PBOOLEAN IsServerProcess)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
WCHAR SessionDir[256];
|
||||
ULONG SessionId = NtCurrentPeb()->SessionId;
|
||||
BOOLEAN InServer;
|
||||
ULONG ConnectInfoSize = sizeof(*ConnectInfo);
|
||||
|
||||
CONSRV_API_CONNECTINFO ConnectInfo;
|
||||
ULONG ConnectInfoSize = sizeof(ConnectInfo);
|
||||
|
||||
DPRINT("BasepInitConsole for : %wZ\n", &Parameters->ImagePathName);
|
||||
DPRINT("Our current console handles are: %p, %p, %p %p\n",
|
||||
Parameters->ConsoleHandle, Parameters->StandardInput,
|
||||
Parameters->StandardOutput, Parameters->StandardError);
|
||||
|
||||
/* Initialize our global console DLL lock */
|
||||
Status = RtlInitializeCriticalSection(&ConsoleLock);
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
ConsoleInitialized = TRUE;
|
||||
|
||||
/* Do nothing if this isn't a console app... */
|
||||
if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem !=
|
||||
IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
||||
{
|
||||
DPRINT("Image is not a console application\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
ConnectInfo.ConsoleStartInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app.
|
||||
|
||||
ConnectInfo.ConsoleStartInfo.ConsoleTitle[0] = L'\0';
|
||||
ConnectInfo.ConsoleStartInfo.AppPath[0] = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
LPCWSTR ExeName;
|
||||
|
||||
InitConsoleInfo(&ConnectInfo.ConsoleStartInfo,
|
||||
&Parameters->ImagePathName);
|
||||
|
||||
/* Initialize Input EXE name */
|
||||
ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\');
|
||||
if (ExeName) SetConsoleInputExeNameW(ExeName + 1);
|
||||
|
||||
/* Assume one is needed */
|
||||
ConnectInfo.ConsoleStartInfo.ConsoleNeeded = TRUE;
|
||||
|
||||
/* Handle the special flags given to us by BasePushProcessParameters */
|
||||
if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
|
||||
{
|
||||
/* No console to create */
|
||||
DPRINT("No console to create\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
ConnectInfo.ConsoleStartInfo.ConsoleNeeded = FALSE;
|
||||
}
|
||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE)
|
||||
{
|
||||
/* We'll get the real one soon */
|
||||
DPRINT("Creating new console\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
}
|
||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW)
|
||||
{
|
||||
/* We'll get the real one soon */
|
||||
DPRINT("Creating new invisible console\n");
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
ConnectInfo.ConsoleStartInfo.wShowWindow = SW_HIDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
}
|
||||
DPRINT("Using existing console: %p\n", Parameters->ConsoleHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now use the proper console handle */
|
||||
ConnectInfo.ConsoleHandle = Parameters->ConsoleHandle;
|
||||
|
||||
/* Initialize the Console Ctrl Handler */
|
||||
InitConsoleCtrlHandling();
|
||||
ConnectInfo.ConsoleStartInfo.CtrlDispatcher = ConsoleControlDispatcher;
|
||||
|
||||
/* Initialize the Property Dialog Handler */
|
||||
ConnectInfo.ConsoleStartInfo.PropDispatcher = PropDialogHandler;
|
||||
|
||||
/* Setup the right Object Directory path */
|
||||
if (!SessionId)
|
||||
{
|
||||
/* Use the raw path */
|
||||
wcscpy(SessionDir, WIN_OBJ_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the session path */
|
||||
swprintf(SessionDir,
|
||||
L"%ws\\%ld%ws",
|
||||
SESSION_DIR,
|
||||
SessionId,
|
||||
WIN_OBJ_DIR);
|
||||
}
|
||||
ASSERT(SessionDir);
|
||||
|
||||
/* Connect to the Console Server */
|
||||
DPRINT("Connecting to the Console Server in BasepInitConsole...\n");
|
||||
DPRINT("Connecting to the Console Server...\n");
|
||||
Status = CsrClientConnectToServer(SessionDir,
|
||||
CONSRV_SERVERDLL_INDEX,
|
||||
&ConnectInfo,
|
||||
ConnectInfo,
|
||||
&ConnectInfoSize,
|
||||
&InServer);
|
||||
IsServerProcess);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
|
||||
|
@ -284,52 +303,237 @@ BasepInitConsole(VOID)
|
|||
}
|
||||
|
||||
/* Nothing to do for server-to-server */
|
||||
if (InServer) return TRUE;
|
||||
if (*IsServerProcess) return TRUE;
|
||||
|
||||
/* Nothing to do if not a console app */
|
||||
if (!ConnectInfo.ConsoleStartInfo.ConsoleNeeded) return TRUE;
|
||||
/* Nothing to do if this is not a console app */
|
||||
if (!ConnectInfo->IsConsoleApp) return TRUE;
|
||||
|
||||
/* We got the handles, let's set them */
|
||||
if ((Parameters->ConsoleHandle = ConnectInfo.ConsoleHandle))
|
||||
#ifdef USE_CONSOLE_INIT_HANDLES
|
||||
/* Wait for the connection to finish */
|
||||
Status = NtWaitForMultipleObjects(2, ConnectInfo->ConsoleStartInfo.Events,
|
||||
WaitAny, FALSE, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* If we already had some, don't use the new ones */
|
||||
if (!Parameters->StandardInput)
|
||||
{
|
||||
Parameters->StandardInput = ConnectInfo.InputHandle;
|
||||
}
|
||||
if (!Parameters->StandardOutput)
|
||||
{
|
||||
Parameters->StandardOutput = ConnectInfo.OutputHandle;
|
||||
}
|
||||
if (!Parameters->StandardError)
|
||||
{
|
||||
Parameters->StandardError = ConnectInfo.ErrorHandle;
|
||||
}
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
InputWaitHandle = ConnectInfo.InputWaitHandle;
|
||||
NtClose(ConnectInfo->ConsoleStartInfo.Events[0]);
|
||||
NtClose(ConnectInfo->ConsoleStartInfo.Events[1]);
|
||||
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
DPRINT("Console setup: %p, %p, %p, %p\n",
|
||||
Parameters->ConsoleHandle,
|
||||
Parameters->StandardInput,
|
||||
Parameters->StandardOutput,
|
||||
Parameters->StandardError);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
BOOLEAN
|
||||
WINAPI
|
||||
BasepUninitConsole(VOID)
|
||||
ConDllInitialize(IN ULONG Reason,
|
||||
IN PWSTR SessionDir)
|
||||
{
|
||||
/* Delete our critical section if we were initialized */
|
||||
if (ConsoleInitialized == TRUE)
|
||||
{
|
||||
if (ConsoleLibrary) FreeLibrary(ConsoleLibrary);
|
||||
NTSTATUS Status;
|
||||
PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
|
||||
BOOLEAN IsServerProcess;
|
||||
CONSRV_API_CONNECTINFO ConnectInfo;
|
||||
LCID lcid;
|
||||
|
||||
ConsoleInitialized = FALSE;
|
||||
RtlDeleteCriticalSection(&ConsoleLock);
|
||||
if (Reason != DLL_PROCESS_ATTACH)
|
||||
{
|
||||
if ((Reason == DLL_THREAD_ATTACH) && IsConsoleApp())
|
||||
{
|
||||
/* Sets the current console locale for the new thread */
|
||||
SetTEBLangID(lcid);
|
||||
}
|
||||
else if (Reason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
/* Free our resources */
|
||||
if (ConsoleInitialized == TRUE)
|
||||
{
|
||||
if (ConsoleApplet) FreeLibrary(ConsoleApplet);
|
||||
|
||||
ConsoleInitialized = FALSE;
|
||||
RtlDeleteCriticalSection(&ConsoleLock);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DPRINT("ConDllInitialize for: %wZ\n"
|
||||
"Our current console handles are: 0x%p, 0x%p, 0x%p 0x%p\n",
|
||||
&Parameters->ImagePathName,
|
||||
Parameters->ConsoleHandle,
|
||||
Parameters->StandardInput,
|
||||
Parameters->StandardOutput,
|
||||
Parameters->StandardError);
|
||||
|
||||
/* Initialize our global console DLL lock */
|
||||
Status = RtlInitializeCriticalSection(&ConsoleLock);
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
ConsoleInitialized = TRUE;
|
||||
|
||||
/* Show by default the console window when applicable */
|
||||
ConnectInfo.IsWindowVisible = TRUE;
|
||||
/* If this is a console app, a console will be created/opened */
|
||||
ConnectInfo.IsConsoleApp = IsConsoleApp();
|
||||
|
||||
/* Do nothing if this is not a console app... */
|
||||
if (!ConnectInfo.IsConsoleApp)
|
||||
{
|
||||
DPRINT("Image is not a console application\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the special flags given to us by BasePushProcessParameters.
|
||||
*/
|
||||
if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS)
|
||||
{
|
||||
/* No console to create */
|
||||
DPRINT("No console to create\n");
|
||||
/*
|
||||
* The new process does not inherit its parent's console and cannot
|
||||
* attach to the console of its parent. The new process can call the
|
||||
* AllocConsole function at a later time to create a console.
|
||||
*/
|
||||
Parameters->ConsoleHandle = NULL; // Do not inherit the parent's console.
|
||||
ConnectInfo.IsConsoleApp = FALSE; // Do not create any console.
|
||||
}
|
||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE)
|
||||
{
|
||||
/* We'll get the real one soon */
|
||||
DPRINT("Creating a new separate console\n");
|
||||
/*
|
||||
* The new process has a new console, instead of inheriting
|
||||
* its parent's console.
|
||||
*/
|
||||
Parameters->ConsoleHandle = NULL; // Do not inherit the parent's console.
|
||||
}
|
||||
else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW)
|
||||
{
|
||||
/* We'll get the real one soon */
|
||||
DPRINT("Creating a new invisible console\n");
|
||||
/*
|
||||
* The process is a console application that is being run
|
||||
* without a console window. Therefore, the console handle
|
||||
* for the application is not set.
|
||||
*/
|
||||
Parameters->ConsoleHandle = NULL; // Do not inherit the parent's console.
|
||||
ConnectInfo.IsWindowVisible = FALSE; // A console is created but is not shown to the user.
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Using existing console: 0x%p\n", Parameters->ConsoleHandle);
|
||||
}
|
||||
|
||||
/* Do nothing if this is not a console app... */
|
||||
if (!ConnectInfo.IsConsoleApp)
|
||||
{
|
||||
/* Do not inherit the parent's console if we are not a console app */
|
||||
Parameters->ConsoleHandle = NULL;
|
||||
}
|
||||
|
||||
/* Now use the proper console handle */
|
||||
ConnectInfo.ConsoleStartInfo.ConsoleHandle = Parameters->ConsoleHandle;
|
||||
|
||||
/* Initialize the console dispatchers */
|
||||
ConnectInfo.CtrlRoutine = ConsoleControlDispatcher;
|
||||
ConnectInfo.PropRoutine = PropDialogHandler;
|
||||
// ConnectInfo.ImeRoutine = ImeRoutine;
|
||||
|
||||
/* Set up the console properties */
|
||||
if (ConnectInfo.IsConsoleApp && Parameters->ConsoleHandle == NULL)
|
||||
{
|
||||
/*
|
||||
* We can set up the console properties only if we create a new one
|
||||
* (we do not inherit it from our parent).
|
||||
*/
|
||||
|
||||
LPWSTR ConsoleTitle = ConnectInfo.ConsoleTitle;
|
||||
|
||||
ConnectInfo.TitleLength = sizeof(ConnectInfo.ConsoleTitle);
|
||||
ConnectInfo.DesktopLength = 0; // SetUpConsoleInfo will give us the real length.
|
||||
|
||||
SetUpConsoleInfo(TRUE,
|
||||
&ConnectInfo.TitleLength,
|
||||
&ConsoleTitle,
|
||||
&ConnectInfo.DesktopLength,
|
||||
&ConnectInfo.Desktop,
|
||||
&ConnectInfo.ConsoleStartInfo);
|
||||
DPRINT("ConsoleTitle = '%S' - Desktop = '%S'\n",
|
||||
ConsoleTitle, ConnectInfo.Desktop);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectInfo.TitleLength = 0;
|
||||
ConnectInfo.DesktopLength = 0;
|
||||
}
|
||||
|
||||
/* Initialize the Input EXE name */
|
||||
if (ConnectInfo.IsConsoleApp)
|
||||
{
|
||||
LPWSTR CurDir = ConnectInfo.CurDir;
|
||||
LPWSTR AppName = ConnectInfo.AppName;
|
||||
|
||||
InitExeName();
|
||||
|
||||
ConnectInfo.CurDirLength = sizeof(ConnectInfo.CurDir);
|
||||
ConnectInfo.AppNameLength = sizeof(ConnectInfo.AppName);
|
||||
|
||||
SetUpAppName(TRUE,
|
||||
&ConnectInfo.CurDirLength,
|
||||
&CurDir,
|
||||
&ConnectInfo.AppNameLength,
|
||||
&AppName);
|
||||
DPRINT("CurDir = '%S' - AppName = '%S'\n",
|
||||
CurDir, AppName);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectInfo.CurDirLength = 0;
|
||||
ConnectInfo.AppNameLength = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize Console Ctrl Handling, that needs to be supported by
|
||||
* all applications, especially because it is used at shutdown.
|
||||
*/
|
||||
InitializeCtrlHandling();
|
||||
|
||||
/* Connect to the Console Server */
|
||||
if (!ConnectConsole(SessionDir,
|
||||
&ConnectInfo,
|
||||
&IsServerProcess))
|
||||
{
|
||||
// DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we are not doing server-to-server init and if this is a console app... */
|
||||
if (!IsServerProcess && ConnectInfo.IsConsoleApp)
|
||||
{
|
||||
/* ... set the handles that we got */
|
||||
if (Parameters->ConsoleHandle == NULL)
|
||||
SetUpHandles(&ConnectInfo.ConsoleStartInfo);
|
||||
|
||||
InputWaitHandle = ConnectInfo.ConsoleStartInfo.InputWaitHandle;
|
||||
|
||||
/* Sets the current console locale for this thread */
|
||||
SetTEBLangID(lcid);
|
||||
}
|
||||
|
||||
DPRINT("Console setup: 0x%p, 0x%p, 0x%p, 0x%p\n",
|
||||
Parameters->ConsoleHandle,
|
||||
Parameters->StandardInput,
|
||||
Parameters->StandardOutput,
|
||||
Parameters->StandardError);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
* Read functions *
|
||||
******************/
|
||||
|
||||
DWORD
|
||||
WINAPI
|
||||
GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer);
|
||||
|
||||
static
|
||||
BOOL
|
||||
IntReadConsole(IN HANDLE hConsoleInput,
|
||||
|
@ -58,26 +54,12 @@ IntReadConsole(IN HANDLE hConsoleInput,
|
|||
ReadConsoleRequest->Unicode = bUnicode;
|
||||
|
||||
/*
|
||||
* Retrieve the current console executable name string and length (always
|
||||
* in UNICODE format).
|
||||
* FIXME: Do not use GetConsoleInputExeNameW but use something else...
|
||||
* Retrieve the (current) Input EXE name string and length,
|
||||
* not NULL-terminated (always in UNICODE format).
|
||||
*/
|
||||
// 1- Get the exe name length in characters, including NULL character.
|
||||
ReadConsoleRequest->ExeLength =
|
||||
(USHORT)GetConsoleInputExeNameW(0, (PWCHAR)ReadConsoleRequest->StaticBuffer);
|
||||
// 2- Get the exe name (GetConsoleInputExeNameW returns 1 in case of success).
|
||||
if (GetConsoleInputExeNameW(ReadConsoleRequest->ExeLength,
|
||||
(PWCHAR)ReadConsoleRequest->StaticBuffer) != 1)
|
||||
{
|
||||
// Nothing
|
||||
ReadConsoleRequest->ExeLength = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the NULL character, and convert in number of bytes.
|
||||
ReadConsoleRequest->ExeLength--;
|
||||
ReadConsoleRequest->ExeLength *= sizeof(WCHAR);
|
||||
}
|
||||
GetCurrentExeName((PWCHAR)ReadConsoleRequest->StaticBuffer,
|
||||
sizeof(ReadConsoleRequest->StaticBuffer));
|
||||
|
||||
/*** For DEBUGGING purposes ***/
|
||||
{
|
||||
|
@ -181,7 +163,7 @@ IntReadConsole(IN HANDLE hConsoleInput,
|
|||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Check for sanity */
|
||||
/* FIXME: Check for sanity */
|
||||
/*
|
||||
if (!NT_SUCCESS(Status) && pInputControl)
|
||||
{
|
||||
|
@ -1185,9 +1167,7 @@ IntFillConsoleOutputCode(IN HANDLE hConsoleOutput,
|
|||
* Read functions *
|
||||
******************/
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1207,9 +1187,7 @@ ReadConsoleW(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1229,9 +1207,7 @@ ReadConsoleA(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* PeekConsoleInputW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1250,9 +1226,7 @@ PeekConsoleInputW(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* PeekConsoleInputA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1271,9 +1245,7 @@ PeekConsoleInputA(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleInputW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1292,9 +1264,7 @@ ReadConsoleInputW(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleInputA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1313,9 +1283,7 @@ ReadConsoleInputA(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleInputExW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1335,9 +1303,7 @@ ReadConsoleInputExW(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleInputExA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1357,9 +1323,7 @@ ReadConsoleInputExA(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleOutputW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1379,9 +1343,7 @@ ReadConsoleOutputW(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleOutputA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1401,9 +1363,7 @@ ReadConsoleOutputA(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleOutputCharacterW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1423,9 +1383,7 @@ ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleOutputCharacterA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1445,9 +1403,7 @@ ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* ReadConsoleOutputAttribute
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1471,9 +1427,7 @@ ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput,
|
|||
* Write functions *
|
||||
*******************/
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1493,9 +1447,7 @@ WriteConsoleW(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1515,9 +1467,7 @@ WriteConsoleA(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleInputW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1536,9 +1486,7 @@ WriteConsoleInputW(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleInputA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1557,9 +1505,7 @@ WriteConsoleInputA(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleInputVDMW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1578,9 +1524,7 @@ WriteConsoleInputVDMW(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleInputVDMA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1599,9 +1543,7 @@ WriteConsoleInputVDMA(IN HANDLE hConsoleInput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleOutputW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1621,9 +1563,7 @@ WriteConsoleOutputW(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleOutputA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1643,9 +1583,7 @@ WriteConsoleOutputA(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleOutputCharacterW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1665,9 +1603,7 @@ WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleOutputCharacterA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1687,9 +1623,7 @@ WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* WriteConsoleOutputAttribute
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1709,9 +1643,7 @@ WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* FillConsoleOutputCharacterW
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1733,9 +1665,7 @@ FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* FillConsoleOutputCharacterA
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -1757,9 +1687,7 @@ FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* FillConsoleOutputAttribute
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
|
||||
#if _WIN32_WINNT >= 0x600
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* GetConsoleHistoryInfo
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -55,9 +53,7 @@ GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* SetConsoleHistoryInfo
|
||||
*
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -92,9 +88,7 @@ SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* GetConsoleOriginalTitleW
|
||||
*
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
|
@ -108,9 +102,7 @@ GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* GetConsoleOriginalTitleA
|
||||
*
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
|
@ -124,9 +116,7 @@ GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* GetConsoleScreenBufferInfoEx
|
||||
*
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -140,9 +130,7 @@ GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* SetConsoleScreenBufferInfoEx
|
||||
*
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
|
@ -156,9 +144,7 @@ SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
|
|||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* GetCurrentConsoleFontEx
|
||||
*
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
|
|
|
@ -200,7 +200,7 @@ DllMain(HANDLE hDll,
|
|||
}
|
||||
|
||||
/* Initialize Console Support */
|
||||
if (!BasepInitConsole())
|
||||
if (!ConDllInitialize(dwReason, SessionDir))
|
||||
{
|
||||
DPRINT1("Failed to set up console\n");
|
||||
return FALSE;
|
||||
|
@ -219,18 +219,24 @@ DllMain(HANDLE hDll,
|
|||
{
|
||||
if (DllInitialized == TRUE)
|
||||
{
|
||||
/* Uninitialize console support */
|
||||
ConDllInitialize(dwReason, NULL);
|
||||
|
||||
/* Insert more dll detach stuff here! */
|
||||
NlsUninit();
|
||||
|
||||
/* Uninitialize console support */
|
||||
BasepUninitConsole();
|
||||
|
||||
/* Delete DLL critical section */
|
||||
RtlDeleteCriticalSection(&BaseDllDirectoryLock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
{
|
||||
/* ConDllInitialize sets the current console locale for the new thread */
|
||||
return ConDllInitialize(dwReason, NULL);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -726,7 +726,7 @@ BasePushProcessParameters(IN ULONG ParameterFlags,
|
|||
ProcessParameters->StandardError = StartupInfo->hStdError;
|
||||
}
|
||||
|
||||
/* Use Special Flags for BasepInitConsole in Kernel32 */
|
||||
/* Use Special Flags for ConDllInitialize in Kernel32 */
|
||||
if (CreationFlags & DETACHED_PROCESS)
|
||||
{
|
||||
ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
|
||||
|
|
|
@ -10,26 +10,31 @@
|
|||
|
||||
/* CONSTANTS ******************************************************************/
|
||||
|
||||
#define HANDLE_DETACHED_PROCESS (HANDLE)-2
|
||||
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-3
|
||||
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-4
|
||||
#define HANDLE_DETACHED_PROCESS (HANDLE)-1
|
||||
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-2
|
||||
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-3
|
||||
|
||||
// Enable (and then get rid of) this define when support for
|
||||
// console initialization handles is implemented in CONSRV.
|
||||
// #define USE_CONSOLE_INIT_HANDLES
|
||||
|
||||
|
||||
/* FUNCTION PROTOTYPES ********************************************************/
|
||||
|
||||
BOOL WINAPI
|
||||
BasepInitConsole(VOID);
|
||||
BOOLEAN
|
||||
WINAPI
|
||||
ConDllInitialize(IN ULONG Reason,
|
||||
IN PWSTR SessionDir);
|
||||
|
||||
VOID WINAPI
|
||||
BasepUninitConsole(VOID);
|
||||
VOID
|
||||
InitializeCtrlHandling(VOID);
|
||||
|
||||
VOID WINAPI
|
||||
InitConsoleCtrlHandling(VOID);
|
||||
|
||||
DWORD WINAPI
|
||||
DWORD
|
||||
WINAPI
|
||||
ConsoleControlDispatcher(IN LPVOID lpThreadParameter);
|
||||
|
||||
DWORD WINAPI
|
||||
DWORD
|
||||
WINAPI
|
||||
PropDialogHandler(IN LPVOID lpThreadParameter);
|
||||
|
||||
HANDLE WINAPI
|
||||
|
@ -59,9 +64,32 @@ GetConsoleInputWaitHandle(VOID);
|
|||
HANDLE
|
||||
TranslateStdHandle(HANDLE hHandle);
|
||||
|
||||
#define SetTEBLangID(p) (p)
|
||||
|
||||
VOID
|
||||
InitConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN PUNICODE_STRING ImagePathName);
|
||||
SetUpConsoleInfo(IN BOOLEAN CaptureTitle,
|
||||
IN OUT LPDWORD pTitleLength,
|
||||
IN OUT LPWSTR* lpTitle OPTIONAL,
|
||||
IN OUT LPDWORD pDesktopLength,
|
||||
IN OUT LPWSTR* lpDesktop OPTIONAL,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo);
|
||||
|
||||
VOID
|
||||
SetUpHandles(IN PCONSOLE_START_INFO ConsoleStartInfo);
|
||||
|
||||
VOID
|
||||
InitExeName(VOID);
|
||||
|
||||
VOID
|
||||
SetUpAppName(IN BOOLEAN CaptureStrings,
|
||||
IN OUT LPDWORD CurDirLength,
|
||||
IN OUT LPWSTR* CurDir,
|
||||
IN OUT LPDWORD AppNameLength,
|
||||
IN OUT LPWSTR* AppName);
|
||||
|
||||
USHORT
|
||||
GetCurrentExeName(OUT PWCHAR ExeName,
|
||||
IN USHORT BufferSize);
|
||||
|
||||
LPCWSTR
|
||||
IntCheckForConsoleFileName(IN LPCWSTR pszName,
|
||||
|
@ -73,7 +101,4 @@ OpenConsoleW(LPCWSTR wsName,
|
|||
BOOL bInheritHandle,
|
||||
DWORD dwShareMode);
|
||||
|
||||
BOOL WINAPI
|
||||
SetConsoleInputExeNameW(LPCWSTR lpInputExeName);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -27,9 +27,6 @@ extern "C" {
|
|||
// These codes are answered by GetConsoleDisplayMode
|
||||
#define CONSOLE_WINDOWED 0
|
||||
#define CONSOLE_FULLSCREEN 1
|
||||
#if (_WIN32_WINNT >= 0x0600)
|
||||
#define CONSOLE_OVERSTRIKE 1
|
||||
#endif
|
||||
#define CONSOLE_FULLSCREEN_HARDWARE 2
|
||||
|
||||
// These codes should be given to SetConsoleDisplayMode
|
||||
|
@ -103,12 +100,16 @@ extern "C" {
|
|||
#define CONSOLE_MOUSE_DOWN 0x0008
|
||||
|
||||
/*
|
||||
* History duplicate flags
|
||||
* History information and mode flags
|
||||
*/
|
||||
#if (_WIN32_WINNT >= 0x0600)
|
||||
// For Get/SetConsoleHistoryInfo
|
||||
#define HISTORY_NO_DUP_FLAG 0x0001
|
||||
// For SetConsoleCommandHistoryMode
|
||||
#define CONSOLE_OVERSTRIKE 0x0001
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Read input flags
|
||||
*/
|
||||
|
|
|
@ -86,7 +86,7 @@ typedef struct _BASE_SXS_CREATEPROCESS_MSG
|
|||
UNICODE_STRING AssemblyName;
|
||||
} BASE_SXS_CREATEPROCESS_MSG, *PBASE_SXS_CREATEPROCESS_MSG;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_CREATE_PROCESS
|
||||
{
|
||||
//
|
||||
// NT-type structure (BASE_CREATEPROCESS_MSG)
|
||||
|
@ -104,23 +104,23 @@ typedef struct
|
|||
USHORT ProcessorArchitecture;
|
||||
} BASE_CREATE_PROCESS, *PBASE_CREATE_PROCESS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_CREATE_THREAD
|
||||
{
|
||||
HANDLE ThreadHandle;
|
||||
CLIENT_ID ClientId;
|
||||
} BASE_CREATE_THREAD, *PBASE_CREATE_THREAD;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_GET_TEMP_FILE
|
||||
{
|
||||
UINT UniqueID;
|
||||
} BASE_GET_TEMP_FILE, *PBASE_GET_TEMP_FILE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_EXIT_PROCESS
|
||||
{
|
||||
UINT uExitCode;
|
||||
} BASE_EXIT_PROCESS, *PBASE_EXIT_PROCESS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_CHECK_VDM
|
||||
{
|
||||
ULONG iTask;
|
||||
HANDLE ConsoleHandle;
|
||||
|
@ -152,7 +152,7 @@ typedef struct
|
|||
USHORT VDMState;
|
||||
} BASE_CHECK_VDM, *PBASE_CHECK_VDM;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_UPDATE_VDM_ENTRY
|
||||
{
|
||||
ULONG iTask;
|
||||
ULONG BinaryType;
|
||||
|
@ -163,7 +163,7 @@ typedef struct
|
|||
USHORT VDMCreationState;
|
||||
} BASE_UPDATE_VDM_ENTRY, *PBASE_UPDATE_VDM_ENTRY;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_GET_NEXT_VDM_COMMAND
|
||||
{
|
||||
ULONG iTask;
|
||||
HANDLE ConsoleHandle;
|
||||
|
@ -196,80 +196,80 @@ typedef struct
|
|||
ULONG fComingFromBat;
|
||||
} BASE_GET_NEXT_VDM_COMMAND, *PBASE_GET_NEXT_VDM_COMMAND;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_EXIT_VDM
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG iWowTask;
|
||||
HANDLE WaitObjectForVDM;
|
||||
} BASE_EXIT_VDM, *PBASE_EXIT_VDM;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_IS_FIRST_VDM
|
||||
{
|
||||
ULONG FirstVDM;
|
||||
} BASE_IS_FIRST_VDM, *PBASE_IS_FIRST_VDM;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_GET_VDM_EXIT_CODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE hParent;
|
||||
ULONG ExitCode;
|
||||
} BASE_GET_VDM_EXIT_CODE, *PBASE_GET_VDM_EXIT_CODE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_SET_REENTER_COUNT
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG fIncDec;
|
||||
} BASE_SET_REENTER_COUNT, *PBASE_SET_REENTER_COUNT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_GETSET_PROCESS_SHUTDOWN_PARAMS
|
||||
{
|
||||
ULONG ShutdownLevel;
|
||||
ULONG ShutdownFlags;
|
||||
} BASE_GETSET_PROCESS_SHUTDOWN_PARAMS, *PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_GETSET_VDM_CURDIRS
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
PCHAR lpszzCurDirs;
|
||||
ULONG cchCurDirs;
|
||||
} BASE_GETSET_VDM_CURDIRS, *PBASE_GETSET_VDM_CURDIRS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_BAT_NOTIFICATION
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG fBeginEnd;
|
||||
} BASE_BAT_NOTIFICATION, *PBASE_BAT_NOTIFICATION;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_REGISTER_WOWEXEC
|
||||
{
|
||||
HANDLE hwndWowExec;
|
||||
} BASE_REGISTER_WOWEXEC, *PBASE_REGISTER_WOWEXEC;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_SOUND_SENTRY
|
||||
{
|
||||
ULONG VideoMode;
|
||||
} BASE_SOUND_SENTRY, *PBASE_SOUND_SENTRY;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_REFRESH_INIFILE_MAPPING
|
||||
{
|
||||
UNICODE_STRING IniFileName;
|
||||
} BASE_REFRESH_INIFILE_MAPPING, *PBASE_REFRESH_INIFILE_MAPPING;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_DEFINE_DOS_DEVICE
|
||||
{
|
||||
ULONG Flags;
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING TargetPath;
|
||||
} BASE_DEFINE_DOS_DEVICE, *PBASE_DEFINE_DOS_DEVICE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_NLS_CREATE_SECTION
|
||||
{
|
||||
HANDLE SectionHandle;
|
||||
ULONG Type;
|
||||
ULONG LocaleId;
|
||||
} BASE_NLS_CREATE_SECTION, *PBASE_NLS_CREATE_SECTION;
|
||||
|
||||
typedef struct
|
||||
typedef struct _BASE_NLS_GET_USER_INFO
|
||||
{
|
||||
PVOID /*PNLS_USER_INFO*/ NlsUserInfo;
|
||||
ULONG Size;
|
||||
|
|
|
@ -119,6 +119,13 @@ typedef enum _CONSRV_API_NUMBER
|
|||
//
|
||||
typedef struct _CONSOLE_PROPERTIES
|
||||
{
|
||||
INT IconIndex;
|
||||
HICON hIcon;
|
||||
HICON hIconSm;
|
||||
DWORD dwHotKey;
|
||||
DWORD dwStartupFlags;
|
||||
|
||||
// NT_CONSOLE_PROPS
|
||||
WORD wFillAttribute;
|
||||
WORD wPopupFillAttribute;
|
||||
|
||||
|
@ -134,90 +141,88 @@ typedef struct _CONSOLE_PROPERTIES
|
|||
DWORD nFont;
|
||||
DWORD nInputBufferSize;
|
||||
COORD dwFontSize;
|
||||
UINT uFontFamily;
|
||||
UINT uFontWeight;
|
||||
UINT uFontFamily;
|
||||
UINT uFontWeight;
|
||||
WCHAR FaceName[LF_FACESIZE];
|
||||
UINT uCursorSize;
|
||||
BOOL bFullScreen;
|
||||
BOOL bQuickEdit;
|
||||
BOOL bInsertMode;
|
||||
BOOL bAutoPosition;
|
||||
UINT uHistoryBufferSize;
|
||||
UINT uNumberOfHistoryBuffers;
|
||||
BOOL bHistoryNoDup;
|
||||
UINT uCursorSize;
|
||||
BOOL bFullScreen;
|
||||
BOOL bQuickEdit;
|
||||
BOOL bInsertMode;
|
||||
BOOL bAutoPosition;
|
||||
UINT uHistoryBufferSize;
|
||||
UINT uNumberOfHistoryBuffers;
|
||||
BOOL bHistoryNoDup;
|
||||
COLORREF ColorTable[16];
|
||||
|
||||
//NT_FE_CONSOLE_PROPS
|
||||
// NT_FE_CONSOLE_PROPS
|
||||
UINT uCodePage;
|
||||
} CONSOLE_PROPERTIES;
|
||||
|
||||
//
|
||||
// To minimize code changes, some fields were put here even though they really only belong in
|
||||
// CONSRV_API_CONNECTINFO. Do not change the ordering however, as it's required for Windows
|
||||
// compatibility.
|
||||
//
|
||||
typedef struct _CONSOLE_START_INFO
|
||||
{
|
||||
INT IconIndex;
|
||||
HICON IconHandle1;
|
||||
HICON IconHandle2;
|
||||
DWORD dwHotKey;
|
||||
DWORD dwStartupFlags;
|
||||
CONSOLE_PROPERTIES;
|
||||
|
||||
BOOLEAN ConsoleNeeded; // Used for GUI apps only.
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
LPTHREAD_START_ROUTINE ImeDispatcher;
|
||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
||||
ULONG TitleLength;
|
||||
WCHAR ConsoleTitle[MAX_PATH + 1]; // Console title or full path to the startup shortcut
|
||||
ULONG DesktopLength;
|
||||
PWCHAR DesktopPath;
|
||||
ULONG AppNameLength;
|
||||
WCHAR AppPath[128]; // Full path of the launched app
|
||||
ULONG IconPathLength;
|
||||
WCHAR IconPath[MAX_PATH + 1]; // Path to the file containing the icon
|
||||
} CONSOLE_START_INFO, *PCONSOLE_START_INFO;
|
||||
|
||||
typedef struct _CONSRV_API_CONNECTINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE Event1;
|
||||
HANDLE Event2;
|
||||
/* Adapted from CONSOLE_ALLOCCONSOLE */
|
||||
HANDLE Events[2];
|
||||
|
||||
CONSOLE_PROPERTIES;
|
||||
} CONSOLE_START_INFO, *PCONSOLE_START_INFO;
|
||||
|
||||
#if defined(_M_IX86)
|
||||
C_ASSERT(sizeof(CONSOLE_START_INFO) == 0xFC);
|
||||
#endif
|
||||
|
||||
typedef struct _CONSRV_API_CONNECTINFO
|
||||
{
|
||||
CONSOLE_START_INFO ConsoleStartInfo;
|
||||
|
||||
BOOLEAN IsConsoleApp;
|
||||
BOOLEAN IsWindowVisible;
|
||||
|
||||
// USHORT Padding;
|
||||
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
LPTHREAD_START_ROUTINE PropRoutine;
|
||||
LPTHREAD_START_ROUTINE ImeRoutine;
|
||||
|
||||
ULONG TitleLength;
|
||||
WCHAR ConsoleTitle[MAX_PATH + 1]; // Console title or full path to the startup shortcut
|
||||
ULONG DesktopLength;
|
||||
PWCHAR Desktop;
|
||||
ULONG AppNameLength;
|
||||
WCHAR AppName[128]; // Full path of the launched app
|
||||
ULONG CurDirLength;
|
||||
WCHAR CurDir[MAX_PATH + 1];
|
||||
} CONSRV_API_CONNECTINFO, *PCONSRV_API_CONNECTINFO;
|
||||
|
||||
#if defined(_M_IX86)
|
||||
C_ASSERT(sizeof(CONSRV_API_CONNECTINFO) == 0x638);
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETPROCESSLIST
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG ProcessCount;
|
||||
PDWORD ProcessIdsList;
|
||||
} CONSOLE_GETPROCESSLIST, *PCONSOLE_GETPROCESSLIST;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GENERATECTRLEVENT
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
DWORD CtrlEvent;
|
||||
DWORD ProcessGroupId;
|
||||
} CONSOLE_GENERATECTRLEVENT, *PCONSOLE_GENERATECTRLEVENT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_NOTIFYLASTCLOSE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
} CONSOLE_NOTIFYLASTCLOSE, *PCONSOLE_NOTIFYLASTCLOSE;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_WRITECONSOLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -236,7 +241,7 @@ typedef struct
|
|||
CHAR Reserved2[6];
|
||||
} CONSOLE_WRITECONSOLE, *PCONSOLE_WRITECONSOLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_READCONSOLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
|
@ -255,37 +260,43 @@ typedef struct
|
|||
BOOLEAN Unicode;
|
||||
} CONSOLE_READCONSOLE, *PCONSOLE_READCONSOLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_ALLOCCONSOLE
|
||||
{
|
||||
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
||||
ULONG TitleLength;
|
||||
PWCHAR ConsoleTitle; // Console title or full path to the startup shortcut
|
||||
ULONG DesktopLength;
|
||||
PWCHAR Desktop;
|
||||
ULONG AppNameLength;
|
||||
PWCHAR AppName; // Full path of the launched app
|
||||
ULONG CurDirLength;
|
||||
PWCHAR CurDir;
|
||||
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
LPTHREAD_START_ROUTINE PropRoutine;
|
||||
} CONSOLE_ALLOCCONSOLE, *PCONSOLE_ALLOCCONSOLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_ATTACHCONSOLE
|
||||
{
|
||||
DWORD ProcessId; // If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach the current process to its parent process console.
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
HANDLE OutputHandle;
|
||||
HANDLE ErrorHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
LPTHREAD_START_ROUTINE CtrlDispatcher;
|
||||
LPTHREAD_START_ROUTINE PropDispatcher;
|
||||
/*
|
||||
* If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach
|
||||
* the current process to its parent process console.
|
||||
*/
|
||||
DWORD ProcessId;
|
||||
|
||||
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
LPTHREAD_START_ROUTINE PropRoutine;
|
||||
} CONSOLE_ATTACHCONSOLE, *PCONSOLE_ATTACHCONSOLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_FREECONSOLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
} CONSOLE_FREECONSOLE, *PCONSOLE_FREECONSOLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSCREENBUFFERINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -297,14 +308,14 @@ typedef struct
|
|||
COORD MaximumViewSize;
|
||||
} CONSOLE_GETSCREENBUFFERINFO, *PCONSOLE_GETSCREENBUFFERINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETCURSORPOSITION
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
COORD Position;
|
||||
} CONSOLE_SETCURSORPOSITION, *PCONSOLE_SETCURSORPOSITION;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SHOWCURSOR
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -312,14 +323,14 @@ typedef struct
|
|||
INT RefCount;
|
||||
} CONSOLE_SHOWCURSOR, *PCONSOLE_SHOWCURSOR;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETCURSOR
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
HCURSOR CursorHandle;
|
||||
} CONSOLE_SETCURSOR, *PCONSOLE_SETCURSOR;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSETCURSORINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -330,33 +341,33 @@ typedef struct
|
|||
*/
|
||||
} CONSOLE_GETSETCURSORINFO, *PCONSOLE_GETSETCURSORINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETMOUSEINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG NumButtons;
|
||||
} CONSOLE_GETMOUSEINFO, *PCONSOLE_GETMOUSEINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETTEXTATTRIB
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
WORD Attributes;
|
||||
} CONSOLE_SETTEXTATTRIB, *PCONSOLE_SETTEXTATTRIB;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSETCONSOLEMODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE Handle;
|
||||
DWORD Mode;
|
||||
} CONSOLE_GETSETCONSOLEMODE, *PCONSOLE_GETSETCONSOLEMODE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETDISPLAYMODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
DWORD DisplayMode; // ModeFlags
|
||||
} CONSOLE_GETDISPLAYMODE, *PCONSOLE_GETDISPLAYMODE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETDISPLAYMODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -371,7 +382,7 @@ typedef struct
|
|||
#define CONSOLE_HARDWARE_STATE_GDI_MANAGED 0
|
||||
#define CONSOLE_HARDWARE_STATE_DIRECT 1
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSETHWSTATE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -381,7 +392,7 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_CREATESCREENBUFFER
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
DWORD DesiredAccess;
|
||||
|
@ -399,20 +410,20 @@ typedef struct
|
|||
HANDLE OutputHandle; /* Handle to newly created screen buffer */
|
||||
} CONSOLE_CREATESCREENBUFFER, *PCONSOLE_CREATESCREENBUFFER;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETACTIVESCREENBUFFER
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle; /* Handle to screen buffer to switch to */
|
||||
} CONSOLE_SETACTIVESCREENBUFFER, *PCONSOLE_SETACTIVESCREENBUFFER;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_INVALIDATEDIBITS
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
SMALL_RECT Region;
|
||||
} CONSOLE_INVALIDATEDIBITS, *PCONSOLE_INVALIDATEDIBITS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETPALETTE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -420,7 +431,7 @@ typedef struct
|
|||
UINT Usage;
|
||||
} CONSOLE_SETPALETTE, *PCONSOLE_SETPALETTE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSETCONSOLETITLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Length;
|
||||
|
@ -428,13 +439,13 @@ typedef struct
|
|||
BOOLEAN Unicode;
|
||||
} CONSOLE_GETSETCONSOLETITLE, *PCONSOLE_GETSETCONSOLETITLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_FLUSHINPUTBUFFER
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
} CONSOLE_FLUSHINPUTBUFFER, *PCONSOLE_FLUSHINPUTBUFFER;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SCROLLSCREENBUFFER
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -466,7 +477,7 @@ typedef union _CODE_ELEMENT
|
|||
WORD Attribute;
|
||||
} CODE_ELEMENT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_OUTPUTCODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -487,7 +498,7 @@ typedef struct
|
|||
} CONSOLE_READOUTPUTCODE , *PCONSOLE_READOUTPUTCODE,
|
||||
CONSOLE_WRITEOUTPUTCODE, *PCONSOLE_WRITEOUTPUTCODE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_FILLOUTPUTCODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -499,7 +510,7 @@ typedef struct
|
|||
ULONG NumCodes;
|
||||
} CONSOLE_FILLOUTPUTCODE, *PCONSOLE_FILLOUTPUTCODE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETINPUT
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
|
@ -510,7 +521,7 @@ typedef struct
|
|||
BOOLEAN Unicode;
|
||||
} CONSOLE_GETINPUT, *PCONSOLE_GETINPUT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_WRITEINPUT
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
|
@ -521,7 +532,7 @@ typedef struct
|
|||
BOOLEAN AppendToEnd;
|
||||
} CONSOLE_WRITEINPUT, *PCONSOLE_WRITEINPUT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_READOUTPUT
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -533,7 +544,7 @@ typedef struct
|
|||
BOOLEAN Unicode;
|
||||
} CONSOLE_READOUTPUT, *PCONSOLE_READOUTPUT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_WRITEOUTPUT
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -552,7 +563,7 @@ typedef struct
|
|||
BOOLEAN UseVirtualMemory;
|
||||
} CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETNUMINPUTEVENTS
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE InputHandle;
|
||||
|
@ -561,20 +572,20 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_CLOSEHANDLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE Handle;
|
||||
} CONSOLE_CLOSEHANDLE, *PCONSOLE_CLOSEHANDLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_VERIFYHANDLE
|
||||
{
|
||||
BOOL IsValid;
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE Handle;
|
||||
} CONSOLE_VERIFYHANDLE, *PCONSOLE_VERIFYHANDLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_DUPLICATEHANDLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE SourceHandle;
|
||||
|
@ -584,14 +595,14 @@ typedef struct
|
|||
HANDLE TargetHandle;
|
||||
} CONSOLE_DUPLICATEHANDLE, *PCONSOLE_DUPLICATEHANDLE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETHANDLEINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE Handle;
|
||||
DWORD Flags;
|
||||
} CONSOLE_GETHANDLEINFO, *PCONSOLE_GETHANDLEINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETHANDLEINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE Handle;
|
||||
|
@ -608,7 +619,7 @@ typedef enum _CONSOLE_HANDLE_TYPE
|
|||
HANDLE_OUTPUT = 0x02
|
||||
} CONSOLE_HANDLE_TYPE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_OPENCONSOLE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
CONSOLE_HANDLE_TYPE HandleType;
|
||||
|
@ -620,14 +631,14 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETLARGESTWINDOWSIZE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
COORD Size;
|
||||
} CONSOLE_GETLARGESTWINDOWSIZE, *PCONSOLE_GETLARGESTWINDOWSIZE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_MENUCONTROL
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -636,13 +647,13 @@ typedef struct
|
|||
HMENU MenuHandle;
|
||||
} CONSOLE_MENUCONTROL, *PCONSOLE_MENUCONTROL;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETMENUCLOSE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
BOOL Enable;
|
||||
} CONSOLE_SETMENUCLOSE, *PCONSOLE_SETMENUCLOSE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETWINDOWINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
|
@ -651,13 +662,13 @@ typedef struct
|
|||
// or in the old window position frame (Absolute == FALSE).
|
||||
} CONSOLE_SETWINDOWINFO, *PCONSOLE_SETWINDOWINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETWINDOW
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HWND WindowHandle;
|
||||
} CONSOLE_GETWINDOW, *PCONSOLE_GETWINDOW;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETICON
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HICON IconHandle;
|
||||
|
@ -665,7 +676,7 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_ADDGETALIAS
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
USHORT SourceLength;
|
||||
|
@ -678,7 +689,7 @@ typedef struct
|
|||
BOOLEAN Unicode2;
|
||||
} CONSOLE_ADDGETALIAS, *PCONSOLE_ADDGETALIAS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETALLALIASES
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
USHORT ExeLength;
|
||||
|
@ -689,7 +700,7 @@ typedef struct
|
|||
PVOID AliasesBuffer;
|
||||
} CONSOLE_GETALLALIASES, *PCONSOLE_GETALLALIASES;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETALLALIASESLENGTH
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
USHORT ExeLength;
|
||||
|
@ -699,7 +710,7 @@ typedef struct
|
|||
BOOLEAN Unicode2;
|
||||
} CONSOLE_GETALLALIASESLENGTH, *PCONSOLE_GETALLALIASESLENGTH;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETALIASESEXES
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Length ; // ExeLength; // ExesLength
|
||||
|
@ -707,7 +718,7 @@ typedef struct
|
|||
BOOLEAN Unicode;
|
||||
} CONSOLE_GETALIASESEXES, *PCONSOLE_GETALIASESEXES;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETALIASESEXESLENGTH
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Length;
|
||||
|
@ -716,7 +727,7 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETCOMMANDHISTORY
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG HistoryLength;
|
||||
|
@ -727,7 +738,7 @@ typedef struct
|
|||
BOOLEAN Unicode2;
|
||||
} CONSOLE_GETCOMMANDHISTORY, *PCONSOLE_GETCOMMANDHISTORY;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETCOMMANDHISTORYLENGTH
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG HistoryLength;
|
||||
|
@ -737,7 +748,7 @@ typedef struct
|
|||
BOOLEAN Unicode2;
|
||||
} CONSOLE_GETCOMMANDHISTORYLENGTH, *PCONSOLE_GETCOMMANDHISTORYLENGTH;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_EXPUNGECOMMANDHISTORY
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
USHORT ExeLength;
|
||||
|
@ -746,14 +757,14 @@ typedef struct
|
|||
BOOLEAN Unicode2;
|
||||
} CONSOLE_EXPUNGECOMMANDHISTORY, *PCONSOLE_EXPUNGECOMMANDHISTORY;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSETHISTORYINFO
|
||||
{
|
||||
UINT HistoryBufferSize;
|
||||
UINT NumberOfHistoryBuffers;
|
||||
DWORD dwFlags;
|
||||
} CONSOLE_GETSETHISTORYINFO, *PCONSOLE_GETSETHISTORYINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETHISTORYNUMBERCOMMANDS
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG NumCommands;
|
||||
|
@ -763,7 +774,7 @@ typedef struct
|
|||
BOOLEAN Unicode2;
|
||||
} CONSOLE_SETHISTORYNUMBERCOMMANDS, *PCONSOLE_SETHISTORYNUMBERCOMMANDS;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETHISTORYMODE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG Mode;
|
||||
|
@ -771,27 +782,27 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETSCREENBUFFERSIZE
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE OutputHandle;
|
||||
COORD Size;
|
||||
} CONSOLE_SETSCREENBUFFERSIZE, *PCONSOLE_SETSCREENBUFFERSIZE;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETSELECTIONINFO
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
CONSOLE_SELECTION_INFO Info;
|
||||
} CONSOLE_GETSELECTIONINFO, *PCONSOLE_GETSELECTIONINFO;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETINPUTOUTPUTCP
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
UINT CodePage;
|
||||
BOOL OutputCP; // TRUE : Output Code Page ; FALSE : Input Code Page
|
||||
} CONSOLE_GETINPUTOUTPUTCP, *PCONSOLE_GETINPUTOUTPUTCP;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_SETINPUTOUTPUTCP
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
UINT CodePage;
|
||||
|
@ -799,14 +810,14 @@ typedef struct
|
|||
HANDLE EventHandle;
|
||||
} CONSOLE_SETINPUTOUTPUTCP, *PCONSOLE_SETINPUTOUTPUTCP;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_GETKBDLAYOUTNAME
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
CHAR LayoutBuffer[KL_NAMELENGTH * sizeof(WCHAR)]; // Can hold up to 9 wchars
|
||||
BOOL Ansi;
|
||||
} CONSOLE_GETKBDLAYOUTNAME, *PCONSOLE_GETKBDLAYOUTNAME;
|
||||
|
||||
typedef struct
|
||||
typedef struct _CONSOLE_REGISTERVDM
|
||||
{
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG RegisterFlags;
|
||||
|
|
|
@ -11,8 +11,10 @@ list(APPEND CONSRV_SOURCE
|
|||
consrv/console.c
|
||||
consrv/frontendctl.c
|
||||
consrv/handle.c
|
||||
consrv/history.c
|
||||
consrv/init.c
|
||||
consrv/lineinput.c
|
||||
consrv/popup.c
|
||||
consrv/settings.c
|
||||
consrv/subsysreg.c
|
||||
consrv/condrv/coninput.c
|
||||
|
|
|
@ -18,23 +18,23 @@
|
|||
|
||||
typedef struct _ALIAS_ENTRY
|
||||
{
|
||||
struct _ALIAS_ENTRY* Next;
|
||||
UNICODE_STRING Source;
|
||||
UNICODE_STRING Target;
|
||||
struct _ALIAS_ENTRY* Next;
|
||||
} ALIAS_ENTRY, *PALIAS_ENTRY;
|
||||
|
||||
typedef struct _ALIAS_HEADER
|
||||
{
|
||||
struct _ALIAS_HEADER* Next;
|
||||
UNICODE_STRING ExeName;
|
||||
PALIAS_ENTRY Data;
|
||||
struct _ALIAS_HEADER* Next;
|
||||
} ALIAS_HEADER, *PALIAS_HEADER;
|
||||
|
||||
|
||||
|
||||
|
||||
BOOLEAN
|
||||
ConvertInputAnsiToUnicode(PCONSOLE Console,
|
||||
ConvertInputAnsiToUnicode(PCONSRV_CONSOLE Console,
|
||||
PVOID Source,
|
||||
USHORT SourceLength,
|
||||
// BOOLEAN IsUnicode,
|
||||
|
@ -61,7 +61,7 @@ ConvertInputAnsiToUnicode(PCONSOLE Console,
|
|||
}
|
||||
|
||||
BOOLEAN
|
||||
ConvertInputUnicodeToAnsi(PCONSOLE Console,
|
||||
ConvertInputUnicodeToAnsi(PCONSRV_CONSOLE Console,
|
||||
PVOID Source,
|
||||
USHORT SourceLength,
|
||||
// BOOLEAN IsAnsi,
|
||||
|
@ -474,7 +474,8 @@ CSR_API(SrvAddConsoleAlias)
|
|||
|
||||
lpTarget = (ConsoleAliasRequest->TargetLength != 0 ? ConsoleAliasRequest->Target : NULL);
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -570,7 +571,8 @@ CSR_API(SrvGetConsoleAlias)
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Header = IntFindAliasHeader(Console,
|
||||
|
@ -647,7 +649,8 @@ CSR_API(SrvGetConsoleAliases)
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Header = IntFindAliasHeader(Console,
|
||||
|
@ -747,7 +750,8 @@ CSR_API(SrvGetConsoleAliasesLength)
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Header = IntFindAliasHeader(Console,
|
||||
|
@ -787,7 +791,8 @@ CSR_API(SrvGetConsoleAliasExes)
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
if (IntGetConsoleAliasesExesLength(Console->Aliases, GetAliasesExesRequest->Unicode) > GetAliasesExesRequest->Length)
|
||||
|
@ -864,7 +869,8 @@ CSR_API(SrvGetConsoleAliasExesLength)
|
|||
|
||||
DPRINT1("SrvGetConsoleAliasExesLength entered ApiMessage %p\n", ApiMessage);
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
GetAliasesExesLengthRequest->Length =
|
||||
|
|
|
@ -16,20 +16,6 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/*
|
||||
* From MSDN:
|
||||
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||
* If they are the same, the function fails, and GetLastError returns
|
||||
* ERROR_INVALID_PARAMETER."
|
||||
*/
|
||||
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
||||
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||
WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
||||
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
|
||||
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||
MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||
|
||||
typedef struct ConsoleInput_t
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
|
@ -39,39 +25,13 @@ typedef struct ConsoleInput_t
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static VOID
|
||||
ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||
{
|
||||
if (InputEvent->EventType == KEY_EVENT)
|
||||
{
|
||||
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
|
||||
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
|
||||
ConsoleInputUnicodeCharToAnsiChar(Console,
|
||||
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
|
||||
&UnicodeChar);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||
{
|
||||
if (InputEvent->EventType == KEY_EVENT)
|
||||
{
|
||||
CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
|
||||
InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
|
||||
ConsoleInputAnsiCharToUnicodeChar(Console,
|
||||
&InputEvent->Event.KeyEvent.uChar.UnicodeChar,
|
||||
&AsciiChar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ConDrvAddInputEvents(PCONSOLE Console,
|
||||
PINPUT_RECORD InputRecords, // InputEvent
|
||||
ULONG NumEventsToWrite,
|
||||
PULONG NumEventsWritten,
|
||||
BOOLEAN AppendToEnd)
|
||||
// ConDrvAddInputEvents
|
||||
static NTSTATUS
|
||||
AddInputEvents(PCONSOLE Console,
|
||||
PINPUT_RECORD InputRecords, // InputEvent
|
||||
ULONG NumEventsToWrite,
|
||||
PULONG NumEventsWritten,
|
||||
BOOLEAN AppendToEnd)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG i = 0;
|
||||
|
@ -218,61 +178,7 @@ Done:
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
PreprocessInput(PCONSOLE Console,
|
||||
PINPUT_RECORD InputEvent,
|
||||
ULONG NumEventsToWrite);
|
||||
VOID
|
||||
PostprocessInput(PCONSOLE Console);
|
||||
|
||||
NTSTATUS
|
||||
ConioAddInputEvents(PCONSOLE Console,
|
||||
PINPUT_RECORD InputRecords, // InputEvent
|
||||
ULONG NumEventsToWrite,
|
||||
PULONG NumEventsWritten,
|
||||
BOOLEAN AppendToEnd)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
if (NumEventsWritten) *NumEventsWritten = 0;
|
||||
|
||||
/*
|
||||
* This pre-processing code MUST be IN consrv ONLY!!
|
||||
*/
|
||||
NumEventsToWrite = PreprocessInput(Console, InputRecords, NumEventsToWrite);
|
||||
if (NumEventsToWrite == 0) return STATUS_SUCCESS;
|
||||
|
||||
Status = ConDrvAddInputEvents(Console,
|
||||
InputRecords,
|
||||
NumEventsToWrite,
|
||||
NumEventsWritten,
|
||||
AppendToEnd);
|
||||
|
||||
/*
|
||||
* This post-processing code MUST be IN consrv ONLY!!
|
||||
*/
|
||||
// if (NT_SUCCESS(Status))
|
||||
if (Status == STATUS_SUCCESS) PostprocessInput(Console);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Move elsewhere...*/
|
||||
NTSTATUS
|
||||
ConioProcessInputEvent(PCONSOLE Console,
|
||||
PINPUT_RECORD InputEvent)
|
||||
{
|
||||
ULONG NumEventsWritten;
|
||||
return ConioAddInputEvents(Console,
|
||||
InputEvent,
|
||||
1,
|
||||
&NumEventsWritten,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
static VOID
|
||||
PurgeInputBuffer(PCONSOLE Console)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
|
@ -285,6 +191,36 @@ PurgeInputBuffer(PCONSOLE Console)
|
|||
ConsoleFreeHeap(Event);
|
||||
}
|
||||
|
||||
// CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvInitInputBuffer(IN PCONSOLE Console,
|
||||
IN ULONG InputBufferSize)
|
||||
{
|
||||
SECURITY_ATTRIBUTES SecurityAttributes;
|
||||
|
||||
ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console);
|
||||
|
||||
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
SecurityAttributes.lpSecurityDescriptor = NULL;
|
||||
SecurityAttributes.bInheritHandle = TRUE;
|
||||
|
||||
Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
|
||||
if (Console->InputBuffer.ActiveEvent == NULL) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
Console->InputBuffer.InputBufferSize = InputBufferSize;
|
||||
InitializeListHead(&Console->InputBuffer.InputEvents);
|
||||
Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
|
||||
ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
ConDrvDeinitInputBuffer(IN PCONSOLE Console)
|
||||
{
|
||||
PurgeInputBuffer(Console);
|
||||
CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||
}
|
||||
|
||||
|
@ -302,10 +238,7 @@ ConDrvReadConsole(IN PCONSOLE Console,
|
|||
OUT PULONG NumCharsRead OPTIONAL)
|
||||
{
|
||||
// STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
|
||||
NTSTATUS Status = STATUS_PENDING;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
ConsoleInput *Input;
|
||||
ULONG i;
|
||||
// NTSTATUS Status; = STATUS_PENDING;
|
||||
|
||||
if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */
|
||||
ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL))
|
||||
|
@ -317,128 +250,14 @@ ConDrvReadConsole(IN PCONSOLE Console,
|
|||
ASSERT(Console == InputBuffer->Header.Console);
|
||||
ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
|
||||
|
||||
/* We haven't read anything (yet) */
|
||||
|
||||
i = ReadControl->nInitialChars;
|
||||
|
||||
if (InputBuffer->Mode & ENABLE_LINE_INPUT)
|
||||
{
|
||||
if (Console->LineBuffer == NULL)
|
||||
{
|
||||
/* Starting a new line */
|
||||
Console->LineMaxSize = max(256, NumCharsToRead);
|
||||
|
||||
Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
|
||||
if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
|
||||
|
||||
Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
|
||||
Console->LineComplete = Console->LineUpPressed = FALSE;
|
||||
Console->LineInsertToggle = Console->InsertMode;
|
||||
Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
|
||||
|
||||
/*
|
||||
* Pre-filling the buffer is only allowed in the Unicode API,
|
||||
* so we don't need to worry about ANSI <-> Unicode conversion.
|
||||
*/
|
||||
memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
|
||||
if (Console->LineSize == Console->LineMaxSize)
|
||||
{
|
||||
Console->LineComplete = TRUE;
|
||||
Console->LinePos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have a complete line yet, process the pending input */
|
||||
while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
/* Remove input event from queue */
|
||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
ResetEvent(InputBuffer->ActiveEvent);
|
||||
}
|
||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||
|
||||
/* Only pay attention to key down */
|
||||
if (Input->InputEvent.EventType == KEY_EVENT &&
|
||||
Input->InputEvent.Event.KeyEvent.bKeyDown)
|
||||
{
|
||||
LineInputKeyDown(Console, ExeName,
|
||||
&Input->InputEvent.Event.KeyEvent);
|
||||
ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
|
||||
}
|
||||
ConsoleFreeHeap(Input);
|
||||
}
|
||||
|
||||
/* Check if we have a complete line to read from */
|
||||
if (Console->LineComplete)
|
||||
{
|
||||
while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
|
||||
{
|
||||
WCHAR Char = Console->LineBuffer[Console->LinePos++];
|
||||
|
||||
if (Unicode)
|
||||
{
|
||||
((PWCHAR)Buffer)[i] = Char;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (Console->LinePos == Console->LineSize)
|
||||
{
|
||||
/* Entire line has been read */
|
||||
ConsoleFreeHeap(Console->LineBuffer);
|
||||
Console->LineBuffer = NULL;
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Character input */
|
||||
while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
/* Remove input event from queue */
|
||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
ResetEvent(InputBuffer->ActiveEvent);
|
||||
}
|
||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||
|
||||
/* Only pay attention to valid ASCII chars, on key down */
|
||||
if (Input->InputEvent.EventType == KEY_EVENT &&
|
||||
Input->InputEvent.Event.KeyEvent.bKeyDown &&
|
||||
Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
|
||||
{
|
||||
WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
|
||||
|
||||
if (Unicode)
|
||||
{
|
||||
((PWCHAR)Buffer)[i] = Char;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
||||
}
|
||||
++i;
|
||||
|
||||
/* Did read something */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
ConsoleFreeHeap(Input);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Only set if Status == STATUS_SUCCESS ???
|
||||
if (NumCharsRead) *NumCharsRead = i;
|
||||
|
||||
return Status;
|
||||
/* Call the line-discipline */
|
||||
return TermReadStream(Console,
|
||||
ExeName,
|
||||
Unicode,
|
||||
Buffer,
|
||||
ReadControl,
|
||||
NumCharsToRead,
|
||||
NumCharsRead);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
|
@ -446,7 +265,6 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
|
|||
IN PCONSOLE_INPUT_BUFFER InputBuffer,
|
||||
IN BOOLEAN KeepEvents,
|
||||
IN BOOLEAN WaitForMoreEvents,
|
||||
IN BOOLEAN Unicode,
|
||||
OUT PINPUT_RECORD InputRecord,
|
||||
IN ULONG NumEventsToRead,
|
||||
OUT PULONG NumEventsRead OPTIONAL)
|
||||
|
@ -496,20 +314,13 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
|
|||
|
||||
if (NumEventsRead) *NumEventsRead = i;
|
||||
|
||||
/* Now translate everything to ANSI */
|
||||
if (!Unicode)
|
||||
{
|
||||
for (; i > 0; --i)
|
||||
{
|
||||
ConioInputEventToAnsi(InputBuffer->Header.Console, --InputRecord);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
ResetEvent(InputBuffer->ActiveEvent);
|
||||
}
|
||||
|
||||
// FIXME: If we add back UNICODE support, it's here that we need to do the translation.
|
||||
|
||||
/* We read all the inputs available, we return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -517,15 +328,11 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
|
|||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleInput(IN PCONSOLE Console,
|
||||
IN PCONSOLE_INPUT_BUFFER InputBuffer,
|
||||
IN BOOLEAN Unicode,
|
||||
IN BOOLEAN AppendToEnd,
|
||||
IN PINPUT_RECORD InputRecord,
|
||||
IN ULONG NumEventsToWrite,
|
||||
OUT PULONG NumEventsWritten OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG i;
|
||||
|
||||
if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
|
@ -533,26 +340,16 @@ ConDrvWriteConsoleInput(IN PCONSOLE Console,
|
|||
ASSERT(Console == InputBuffer->Header.Console);
|
||||
ASSERT((InputRecord != NULL) || (InputRecord == NULL && NumEventsToWrite == 0));
|
||||
|
||||
/* First translate everything to UNICODE */
|
||||
if (!Unicode)
|
||||
{
|
||||
for (i = 0; i < NumEventsToWrite; ++i)
|
||||
{
|
||||
ConioInputEventToUnicode(Console, &InputRecord[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, add the events */
|
||||
// if (NumEventsWritten) *NumEventsWritten = 0;
|
||||
// ConDrvAddInputEvents
|
||||
Status = ConioAddInputEvents(Console,
|
||||
InputRecord,
|
||||
NumEventsToWrite,
|
||||
NumEventsWritten,
|
||||
AppendToEnd);
|
||||
// if (NumEventsWritten) *NumEventsWritten = i;
|
||||
if (NumEventsWritten) *NumEventsWritten = 0;
|
||||
|
||||
return Status;
|
||||
// FIXME: If we add back UNICODE support, it's here that we need to do the translation.
|
||||
|
||||
return AddInputEvents(Console,
|
||||
InputRecord,
|
||||
NumEventsToWrite,
|
||||
NumEventsWritten,
|
||||
AppendToEnd);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
|
|
|
@ -115,7 +115,7 @@ static VOID
|
|||
ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
|
||||
VOID NTAPI
|
||||
ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
||||
ConDrvDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer)
|
||||
{
|
||||
PCONSOLE Console = Buffer->Header.Console;
|
||||
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
||||
|
@ -190,7 +190,7 @@ ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console,
|
|||
/* If old buffer has no handles, it's now unreferenced */
|
||||
if (Console->ActiveBuffer->Header.ReferenceCount == 0)
|
||||
{
|
||||
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
||||
ConDrvDeleteScreenBuffer(Console->ActiveBuffer);
|
||||
}
|
||||
|
||||
/* Tie console to new buffer and signal the change to the frontend */
|
||||
|
|
|
@ -76,35 +76,6 @@ RemoveConsole(IN PCONSOLE Console)
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180
|
||||
static BOOLEAN
|
||||
ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest,
|
||||
IN PCWSTR Source)
|
||||
{
|
||||
SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR);
|
||||
if (Size > MAXUSHORT) return FALSE;
|
||||
|
||||
UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
|
||||
if (UniDest->Buffer == NULL) return FALSE;
|
||||
|
||||
RtlCopyMemory(UniDest->Buffer, Source, Size);
|
||||
UniDest->MaximumLength = (USHORT)Size;
|
||||
UniDest->Length = (USHORT)Size - sizeof(WCHAR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431
|
||||
static VOID
|
||||
ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
|
||||
{
|
||||
if (UnicodeString->Buffer)
|
||||
{
|
||||
ConsoleFreeHeap(UnicodeString->Buffer);
|
||||
RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
|
||||
}
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
ConDrvPause(PCONSOLE Console)
|
||||
{
|
||||
|
@ -190,14 +161,10 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
IN PCONSOLE_INFO ConsoleInfo)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
SECURITY_ATTRIBUTES SecurityAttributes;
|
||||
// CONSOLE_INFO CapturedConsoleInfo;
|
||||
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
|
||||
PCONSOLE Console;
|
||||
PCONSOLE_SCREEN_BUFFER NewBuffer;
|
||||
#if 0
|
||||
WCHAR DefaultTitle[128];
|
||||
#endif
|
||||
|
||||
if (NewConsole == NULL || ConsoleInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -236,34 +203,16 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
Console->ConsoleSize = ConsoleInfo->ConsoleSize;
|
||||
Console->FixedSize = FALSE; // Value by default; is reseted by the terminals if needed.
|
||||
|
||||
/*
|
||||
* Initialize the input buffer
|
||||
*/
|
||||
ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console);
|
||||
|
||||
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
SecurityAttributes.lpSecurityDescriptor = NULL;
|
||||
SecurityAttributes.bInheritHandle = TRUE;
|
||||
Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
|
||||
if (NULL == Console->InputBuffer.ActiveEvent)
|
||||
/* Initialize the input buffer */
|
||||
Status = ConDrvInitInputBuffer(Console, 0 /* ConsoleInfo->InputBufferSize */);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("ConDrvInitInputBuffer: failed, Status = 0x%08lx\n", Status);
|
||||
DeleteCriticalSection(&Console->Lock);
|
||||
ConsoleFreeHeap(Console);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Console->InputBuffer.InputBufferSize = 0; // FIXME!
|
||||
InitializeListHead(&Console->InputBuffer.InputEvents);
|
||||
Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
|
||||
ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
|
||||
|
||||
Console->InsertMode = ConsoleInfo->InsertMode;
|
||||
Console->LineBuffer = NULL;
|
||||
Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
|
||||
Console->LineComplete = Console->LineUpPressed = FALSE;
|
||||
Console->LineInsertToggle = Console->InsertMode;
|
||||
// LineWakeupMask
|
||||
|
||||
/* Set-up the code page */
|
||||
Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
|
||||
|
||||
|
@ -282,7 +231,7 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("ConDrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
|
||||
CloseHandle(Console->InputBuffer.ActiveEvent);
|
||||
ConDrvDeinitInputBuffer(Console);
|
||||
DeleteCriticalSection(&Console->Lock);
|
||||
ConsoleFreeHeap(Console);
|
||||
return Status;
|
||||
|
@ -291,28 +240,6 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
|
|||
Console->ActiveBuffer = NewBuffer;
|
||||
Console->UnpauseEvent = NULL;
|
||||
|
||||
/* Initialize the console title */
|
||||
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
|
||||
#if 0
|
||||
if (ConsoleInfo.ConsoleTitle[0] == L'\0')
|
||||
{
|
||||
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
|
||||
{
|
||||
ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
DPRINT("Console initialized\n");
|
||||
|
||||
/* All went right, so add the console to the list */
|
||||
|
@ -437,10 +364,10 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
|
|||
|
||||
/* FIXME: Send a terminate message to all the processes owning this console */
|
||||
|
||||
/* Cleanup the UI-oriented part */
|
||||
DPRINT("Deregister console\n");
|
||||
/* Deregister the terminal */
|
||||
DPRINT("Deregister terminal\n");
|
||||
ConDrvDeregisterTerminal(Console);
|
||||
DPRINT("Console deregistered\n");
|
||||
DPRINT("Terminal deregistered\n");
|
||||
|
||||
/***
|
||||
* Check that the console is in terminating state before continuing
|
||||
|
@ -465,24 +392,19 @@ ConDrvDeleteConsole(IN PCONSOLE Console)
|
|||
/* Remove the console from the list */
|
||||
RemoveConsole(Console);
|
||||
|
||||
/* Discard all entries in the input event queue */
|
||||
PurgeInputBuffer(Console);
|
||||
if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
|
||||
|
||||
/* Delete the last screen buffer */
|
||||
ConioDeleteScreenBuffer(Console->ActiveBuffer);
|
||||
ConDrvDeleteScreenBuffer(Console->ActiveBuffer);
|
||||
Console->ActiveBuffer = NULL;
|
||||
if (!IsListEmpty(&Console->BufferList))
|
||||
{
|
||||
DPRINT1("BUG: screen buffer list not empty\n");
|
||||
ASSERT(FALSE);
|
||||
/***ConDrvUnlockConsoleList();***/
|
||||
ASSERTMSG("BUGBUGBUG!! screen buffer list not empty\n", FALSE);
|
||||
}
|
||||
|
||||
/**/ CloseHandle(Console->InputBuffer.ActiveEvent); /**/
|
||||
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
||||
/* Deinitialize the input buffer */
|
||||
ConDrvDeinitInputBuffer(Console);
|
||||
|
||||
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
|
||||
|
||||
DPRINT("ConDrvDeleteConsole - Unlocking\n");
|
||||
LeaveCriticalSection(&Console->Lock);
|
||||
|
@ -518,17 +440,7 @@ ConDrvGetConsoleMode(IN PCONSOLE Console,
|
|||
if (INPUT_BUFFER == Object->Type)
|
||||
{
|
||||
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
|
||||
|
||||
*ConsoleMode = InputBuffer->Mode;
|
||||
|
||||
if (Console->QuickEdit || Console->InsertMode)
|
||||
{
|
||||
// Windows does this, even if it's not documented on MSDN
|
||||
*ConsoleMode |= ENABLE_EXTENDED_FLAGS;
|
||||
|
||||
if (Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
|
||||
if (Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
|
||||
}
|
||||
}
|
||||
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
|
||||
{
|
||||
|
@ -548,8 +460,6 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
|
|||
IN PCONSOLE_IO_OBJECT Object,
|
||||
IN ULONG ConsoleMode)
|
||||
{
|
||||
#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | \
|
||||
ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
|
||||
#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \
|
||||
ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \
|
||||
ENABLE_MOUSE_INPUT )
|
||||
|
@ -567,45 +477,21 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
|
|||
{
|
||||
PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object;
|
||||
|
||||
DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode);
|
||||
|
||||
/*
|
||||
* 1. Only the presence of valid mode flags is allowed.
|
||||
*/
|
||||
if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES | CONSOLE_VALID_CONTROL_MODES))
|
||||
/* Only the presence of valid mode flags is allowed */
|
||||
if (ConsoleMode & ~CONSOLE_VALID_INPUT_MODES)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS,
|
||||
* then consider the flags invalid.
|
||||
*
|
||||
if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) &&
|
||||
(ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 )
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Quit;
|
||||
InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* 3. Now we can continue.
|
||||
*/
|
||||
if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
|
||||
{
|
||||
Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
|
||||
Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
|
||||
}
|
||||
InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
|
||||
}
|
||||
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
|
||||
|
||||
DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode);
|
||||
|
||||
/* Only the presence of valid mode flags is allowed */
|
||||
if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
@ -620,115 +506,9 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
|
|||
Status = STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
Quit:
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvGetConsoleTitle(IN PCONSOLE Console,
|
||||
IN BOOLEAN Unicode,
|
||||
IN OUT PVOID TitleBuffer,
|
||||
IN OUT PULONG BufLength)
|
||||
{
|
||||
ULONG Length;
|
||||
|
||||
if (Console == NULL || TitleBuffer == NULL || BufLength == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Copy title of the console to the user title buffer */
|
||||
if (Unicode)
|
||||
{
|
||||
if (*BufLength >= sizeof(WCHAR))
|
||||
{
|
||||
Length = min(*BufLength - sizeof(WCHAR), Console->Title.Length);
|
||||
RtlCopyMemory(TitleBuffer, Console->Title.Buffer, Length);
|
||||
((PWCHAR)TitleBuffer)[Length / sizeof(WCHAR)] = L'\0';
|
||||
*BufLength = Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*BufLength = Console->Title.Length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*BufLength >= sizeof(CHAR))
|
||||
{
|
||||
Length = min(*BufLength - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
|
||||
Length = WideCharToMultiByte(Console->InputCodePage, 0,
|
||||
Console->Title.Buffer, Length,
|
||||
TitleBuffer, Length,
|
||||
NULL, NULL);
|
||||
((PCHAR)TitleBuffer)[Length] = '\0';
|
||||
*BufLength = Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
*BufLength = Console->Title.Length / sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvSetConsoleTitle(IN PCONSOLE Console,
|
||||
IN BOOLEAN Unicode,
|
||||
IN PVOID TitleBuffer,
|
||||
IN ULONG BufLength)
|
||||
{
|
||||
PWCHAR Buffer;
|
||||
ULONG Length;
|
||||
|
||||
if (Console == NULL || TitleBuffer == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (Unicode)
|
||||
{
|
||||
/* Length is in bytes */
|
||||
Length = BufLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the console input CP for the conversion */
|
||||
Length = MultiByteToWideChar(Console->InputCodePage, 0,
|
||||
TitleBuffer, BufLength,
|
||||
NULL, 0);
|
||||
/* The returned Length was in number of wchars, convert it in bytes */
|
||||
Length *= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Allocate a new buffer to hold the new title (NULL-terminated) */
|
||||
Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Length + sizeof(WCHAR));
|
||||
if (!Buffer) return STATUS_NO_MEMORY;
|
||||
|
||||
/* Free the old title */
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
|
||||
/* Copy title to console */
|
||||
Console->Title.Buffer = Buffer;
|
||||
Console->Title.Length = Length;
|
||||
Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
|
||||
|
||||
if (Unicode)
|
||||
{
|
||||
RtlCopyMemory(Console->Title.Buffer, TitleBuffer, Console->Title.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
MultiByteToWideChar(Console->InputCodePage, 0,
|
||||
TitleBuffer, BufLength,
|
||||
Console->Title.Buffer,
|
||||
Console->Title.Length / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
/* NULL-terminate */
|
||||
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
// TermChangeTitle(Console);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvGetConsoleCP(IN PCONSOLE Console,
|
||||
OUT PUINT CodePage,
|
||||
|
|
|
@ -25,23 +25,57 @@ DummyDeinitTerminal(IN OUT PTERMINAL This)
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************ Line discipline ***************/
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
DummyReadStream(IN OUT PTERMINAL This,
|
||||
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
|
||||
IN BOOLEAN Unicode,
|
||||
/**PWCHAR Buffer,**/
|
||||
OUT PVOID Buffer,
|
||||
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
|
||||
IN ULONG NumCharsToRead,
|
||||
OUT PULONG NumCharsRead OPTIONAL)
|
||||
{
|
||||
/*
|
||||
* We were called because the console was in cooked mode.
|
||||
* There is nothing to read, wait until a real terminal
|
||||
* is plugged into the console.
|
||||
*/
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
DummyWriteStream(IN OUT PTERMINAL This,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib)
|
||||
{
|
||||
/*
|
||||
* We were called because the console was in cooked mode.
|
||||
* There is nothing to write, wait until a real terminal
|
||||
* is plugged into the console.
|
||||
*/
|
||||
|
||||
// /* Stop here if the console is paused */
|
||||
// if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
|
||||
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
/************ Line discipline ***************/
|
||||
|
||||
|
||||
|
||||
static VOID NTAPI
|
||||
DummyDrawRegion(IN OUT PTERMINAL This,
|
||||
SMALL_RECT* Region)
|
||||
{
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
DummyWriteStream(IN OUT PTERMINAL This,
|
||||
SMALL_RECT* Region,
|
||||
SHORT CursorStartX,
|
||||
SHORT CursorStartY,
|
||||
UINT ScrolledLines,
|
||||
PWCHAR Buffer,
|
||||
UINT Length)
|
||||
{
|
||||
}
|
||||
|
||||
static BOOL NTAPI
|
||||
DummySetCursorInfo(IN OUT PTERMINAL This,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
|
||||
|
@ -74,26 +108,12 @@ DummyReleaseScreenBuffer(IN OUT PTERMINAL This,
|
|||
{
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
DummyChangeTitle(IN OUT PTERMINAL This)
|
||||
{
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
DummyGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
||||
PCOORD pSize)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
static BOOL NTAPI
|
||||
DummyGetSelectionInfo(IN OUT PTERMINAL This,
|
||||
PCONSOLE_SELECTION_INFO pSelectionInfo)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
static BOOL NTAPI
|
||||
DummySetPalette(IN OUT PTERMINAL This,
|
||||
HPALETTE PaletteHandle,
|
||||
|
@ -113,16 +133,17 @@ static TERMINAL_VTBL DummyVtbl =
|
|||
{
|
||||
DummyInitTerminal,
|
||||
DummyDeinitTerminal,
|
||||
DummyDrawRegion,
|
||||
|
||||
DummyReadStream,
|
||||
DummyWriteStream,
|
||||
|
||||
DummyDrawRegion,
|
||||
DummySetCursorInfo,
|
||||
DummySetScreenInfo,
|
||||
DummyResizeTerminal,
|
||||
DummySetActiveScreenBuffer,
|
||||
DummyReleaseScreenBuffer,
|
||||
DummyChangeTitle,
|
||||
DummyGetLargestConsoleWindowSize,
|
||||
// DummyGetSelectionInfo,
|
||||
DummySetPalette,
|
||||
DummyShowMouseCursor,
|
||||
};
|
||||
|
|
|
@ -16,7 +16,19 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
/*
|
||||
* From MSDN:
|
||||
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||
* If they are the same, the function fails, and GetLastError returns
|
||||
* ERROR_INVALID_PARAMETER."
|
||||
*/
|
||||
#define ConsoleOutputUnicodeToAnsiChar(Console, dChar, sWChar) \
|
||||
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
||||
#define ConsoleOutputAnsiToUnicodeChar(Console, dWChar, sChar) \
|
||||
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
|
@ -33,7 +45,7 @@ static CONSOLE_SCREEN_BUFFER_VTBL TextVtbl =
|
|||
};
|
||||
|
||||
|
||||
static VOID
|
||||
/*static*/ VOID
|
||||
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff);
|
||||
|
||||
|
||||
|
@ -127,7 +139,7 @@ ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
|
|||
return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X];
|
||||
}
|
||||
|
||||
static VOID
|
||||
/*static*/ VOID
|
||||
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
|
||||
{
|
||||
PCHAR_INFO Ptr = ConioCoordToPointer(Buff, 0, Buff->CursorPosition.Y);
|
||||
|
@ -235,6 +247,15 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME!
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleInput(IN PCONSOLE Console,
|
||||
IN PCONSOLE_INPUT_BUFFER InputBuffer,
|
||||
IN BOOLEAN AppendToEnd,
|
||||
IN PINPUT_RECORD InputRecord,
|
||||
IN ULONG NumEventsToWrite,
|
||||
OUT PULONG NumEventsWritten OPTIONAL);
|
||||
|
||||
NTSTATUS
|
||||
ConioResizeBuffer(PCONSOLE Console,
|
||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||
|
@ -343,175 +364,19 @@ ConioResizeBuffer(PCONSOLE Console,
|
|||
*/
|
||||
if (Console->InputBuffer.Mode & ENABLE_WINDOW_INPUT)
|
||||
{
|
||||
ULONG NumEventsWritten;
|
||||
INPUT_RECORD er;
|
||||
|
||||
er.EventType = WINDOW_BUFFER_SIZE_EVENT;
|
||||
er.Event.WindowBufferSizeEvent.dwSize = ScreenBuffer->ScreenBufferSize;
|
||||
|
||||
ConioProcessInputEvent(Console, &er);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID
|
||||
ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
|
||||
{
|
||||
/* If we hit bottom, slide the viewable screen */
|
||||
if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
|
||||
{
|
||||
Buff->CursorPosition.Y--;
|
||||
if (++Buff->VirtualY == Buff->ScreenBufferSize.Y)
|
||||
{
|
||||
Buff->VirtualY = 0;
|
||||
}
|
||||
(*ScrolledLines)++;
|
||||
ClearLineBuffer(Buff);
|
||||
if (UpdateRect->Top != 0)
|
||||
{
|
||||
UpdateRect->Top--;
|
||||
}
|
||||
}
|
||||
UpdateRect->Left = 0;
|
||||
UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
|
||||
UpdateRect->Bottom = Buff->CursorPosition.Y;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConioWriteConsole(PCONSOLE Console,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib)
|
||||
{
|
||||
UINT i;
|
||||
PCHAR_INFO Ptr;
|
||||
SMALL_RECT UpdateRect;
|
||||
SHORT CursorStartX, CursorStartY;
|
||||
UINT ScrolledLines;
|
||||
|
||||
CursorStartX = Buff->CursorPosition.X;
|
||||
CursorStartY = Buff->CursorPosition.Y;
|
||||
UpdateRect.Left = Buff->ScreenBufferSize.X;
|
||||
UpdateRect.Top = Buff->CursorPosition.Y;
|
||||
UpdateRect.Right = -1;
|
||||
UpdateRect.Bottom = Buff->CursorPosition.Y;
|
||||
ScrolledLines = 0;
|
||||
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
/*
|
||||
* If we are in processed mode, interpret special characters and
|
||||
* display them correctly. Otherwise, just put them into the buffer.
|
||||
*/
|
||||
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
||||
{
|
||||
/* --- CR --- */
|
||||
if (Buffer[i] == L'\r')
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||
continue;
|
||||
}
|
||||
/* --- LF --- */
|
||||
else if (Buffer[i] == L'\n')
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||
continue;
|
||||
}
|
||||
/* --- BS --- */
|
||||
else if (Buffer[i] == L'\b')
|
||||
{
|
||||
/* Only handle BS if we're not on the first pos of the first line */
|
||||
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
|
||||
{
|
||||
if (0 == Buff->CursorPosition.X)
|
||||
{
|
||||
/* slide virtual position up */
|
||||
Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1;
|
||||
Buff->CursorPosition.Y--;
|
||||
UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buff->CursorPosition.X--;
|
||||
}
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
Ptr->Char.UnicodeChar = L' ';
|
||||
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* --- TAB --- */
|
||||
else if (Buffer[i] == L'\t')
|
||||
{
|
||||
UINT EndX;
|
||||
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1);
|
||||
EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X);
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
while (Buff->CursorPosition.X < EndX)
|
||||
{
|
||||
Ptr->Char.UnicodeChar = L' ';
|
||||
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||
++Ptr;
|
||||
Buff->CursorPosition.X++;
|
||||
}
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
|
||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
||||
{
|
||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buff->CursorPosition.X--;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// /* --- BEL ---*/
|
||||
// else if (Buffer[i] == L'\a')
|
||||
// {
|
||||
// // FIXME: This MUST BE moved to the terminal emulator frontend!!
|
||||
// DPRINT1("Bell\n");
|
||||
// // SendNotifyMessage(Console->hWindow, PM_CONSOLE_BEEP, 0, 0);
|
||||
// continue;
|
||||
// }
|
||||
}
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
Ptr->Char.UnicodeChar = Buffer[i];
|
||||
if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||
|
||||
Buff->CursorPosition.X++;
|
||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
||||
{
|
||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buff->CursorPosition.X = CursorStartX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
|
||||
{
|
||||
TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY,
|
||||
ScrolledLines, Buffer, Length);
|
||||
// ConioProcessInputEvent(Console, &er);
|
||||
ConDrvWriteConsoleInput(Console,
|
||||
&Console->InputBuffer,
|
||||
TRUE,
|
||||
&er,
|
||||
1,
|
||||
&NumEventsWritten);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -528,7 +393,7 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
|
|||
|
||||
COORD TopLeft = {0};
|
||||
ULONG NumCodesToWrite;
|
||||
USHORT OldScreenAttrib;
|
||||
USHORT OldScreenAttrib, OldPopupAttrib;
|
||||
|
||||
if (Console == NULL || Buffer == NULL)
|
||||
{
|
||||
|
@ -540,6 +405,7 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
|
|||
|
||||
NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y;
|
||||
OldScreenAttrib = Buffer->ScreenDefaultAttrib;
|
||||
OldPopupAttrib = Buffer->PopupDefaultAttrib;
|
||||
|
||||
X = TopLeft.X;
|
||||
Y = (TopLeft.Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
|
||||
|
@ -560,10 +426,14 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
|
|||
/* Foreground color */
|
||||
if ((Ptr->Attributes & 0x0F) == (OldScreenAttrib & 0x0F))
|
||||
Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewScreenAttrib & 0x0F);
|
||||
if ((Ptr->Attributes & 0x0F) == (OldPopupAttrib & 0x0F))
|
||||
Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewPopupAttrib & 0x0F);
|
||||
|
||||
/* Background color */
|
||||
if ((Ptr->Attributes & 0xF0) == (OldScreenAttrib & 0xF0))
|
||||
Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewScreenAttrib & 0xF0);
|
||||
if ((Ptr->Attributes & 0xF0) == (OldPopupAttrib & 0xF0))
|
||||
Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewPopupAttrib & 0xF0);
|
||||
|
||||
// ++Ptr;
|
||||
|
||||
|
@ -644,7 +514,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console,
|
|||
}
|
||||
else
|
||||
{
|
||||
// ConsoleUnicodeCharToAnsiChar(Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
|
||||
// ConsoleOutputUnicodeToAnsiChar(Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar);
|
||||
WideCharToMultiByte(Console->OutputCodePage, 0, &Ptr->Char.UnicodeChar, 1,
|
||||
&CurCharInfo->Char.AsciiChar, 1, NULL, NULL);
|
||||
}
|
||||
|
@ -707,7 +577,7 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console,
|
|||
}
|
||||
else
|
||||
{
|
||||
ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar);
|
||||
ConsoleOutputAnsiToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar);
|
||||
}
|
||||
Ptr->Attributes = CurCharInfo->Attributes;
|
||||
++Ptr;
|
||||
|
@ -770,7 +640,7 @@ ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console,
|
|||
Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y);
|
||||
for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X)
|
||||
{
|
||||
ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char);
|
||||
ConsoleOutputAnsiToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char);
|
||||
Ptr->Attributes = CurCharInfo->Attributes;
|
||||
++Ptr;
|
||||
++CurCharInfo;
|
||||
|
@ -807,6 +677,7 @@ ConDrvWriteConsole(IN PCONSOLE Console,
|
|||
/* Stop here if the console is paused */
|
||||
if (Console->UnpauseEvent != NULL) return STATUS_PENDING;
|
||||
|
||||
/* Convert the string to UNICODE */
|
||||
if (Unicode)
|
||||
{
|
||||
Buffer = StringBuffer;
|
||||
|
@ -831,15 +702,16 @@ ConDrvWriteConsole(IN PCONSOLE Console,
|
|||
}
|
||||
}
|
||||
|
||||
/* Send it */
|
||||
if (Buffer)
|
||||
{
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = ConioWriteConsole(Console,
|
||||
ScreenBuffer,
|
||||
Buffer,
|
||||
NumCharsToWrite,
|
||||
TRUE);
|
||||
Status = TermWriteStream(Console,
|
||||
ScreenBuffer,
|
||||
Buffer,
|
||||
NumCharsToWrite,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Written = NumCharsToWrite;
|
||||
|
@ -879,6 +751,10 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
|
|||
ASSERT(Console == Buffer->Header.Console);
|
||||
ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0));
|
||||
|
||||
//
|
||||
// FIXME: Make overflow checks on ReadCoord !!!!!!
|
||||
//
|
||||
|
||||
if (NumCodesRead) *NumCodesRead = 0;
|
||||
|
||||
switch (CodeType)
|
||||
|
@ -925,7 +801,7 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console,
|
|||
switch (CodeType)
|
||||
{
|
||||
case CODE_ASCII:
|
||||
ConsoleUnicodeCharToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar);
|
||||
ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar);
|
||||
break;
|
||||
|
||||
case CODE_UNICODE:
|
||||
|
@ -989,6 +865,10 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
|
|||
ASSERT(Console == Buffer->Header.Console);
|
||||
ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite == 0));
|
||||
|
||||
//
|
||||
// FIXME: Make overflow checks on WriteCoord !!!!!!
|
||||
//
|
||||
|
||||
if (NumCodesWritten) *NumCodesWritten = 0;
|
||||
|
||||
switch (CodeType)
|
||||
|
@ -1117,13 +997,17 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
|
|||
/* Validity check */
|
||||
ASSERT(Console == Buffer->Header.Console);
|
||||
|
||||
//
|
||||
// FIXME: Make overflow checks on WriteCoord !!!!!!
|
||||
//
|
||||
|
||||
if (NumCodesWritten) *NumCodesWritten = 0;
|
||||
|
||||
if (CodeType == CODE_ASCII)
|
||||
{
|
||||
/* Conversion from the ASCII char to the UNICODE char */
|
||||
CODE_ELEMENT tmp;
|
||||
ConsoleAnsiCharToUnicodeChar(Console, &tmp.UnicodeChar, &Code.AsciiChar);
|
||||
ConsoleOutputAnsiToUnicodeChar(Console, &tmp.UnicodeChar, &Code.AsciiChar);
|
||||
Code = tmp;
|
||||
}
|
||||
|
||||
|
@ -1308,7 +1192,7 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console,
|
|||
if (!Unicode)
|
||||
{
|
||||
WCHAR tmp;
|
||||
ConsoleAnsiCharToUnicodeChar(Console, &tmp, &FillChar.Char.AsciiChar);
|
||||
ConsoleOutputAnsiToUnicodeChar(Console, &tmp, &FillChar.Char.AsciiChar);
|
||||
FillChar.Char.UnicodeChar = tmp;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,21 @@
|
|||
ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
|
||||
|
||||
|
||||
/*
|
||||
* From MSDN:
|
||||
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||
* If they are the same, the function fails, and GetLastError returns
|
||||
* ERROR_INVALID_PARAMETER."
|
||||
*/
|
||||
#define ConsoleInputUnicodeToAnsiChar(Console, dChar, sWChar) \
|
||||
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||
WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
||||
#define ConsoleInputAnsiToUnicodeChar(Console, dWChar, sChar) \
|
||||
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||
MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||
|
||||
|
||||
typedef struct _GET_INPUT_INFO
|
||||
{
|
||||
PCSR_THREAD CallingThread; // The thread which called the input API.
|
||||
|
@ -36,10 +51,33 @@ typedef struct _GET_INPUT_INFO
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
/*
|
||||
* This pre-processing code MUST be IN consrv ONLY
|
||||
*/
|
||||
/* static */ ULONG
|
||||
static VOID
|
||||
ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||
{
|
||||
if (InputEvent->EventType == KEY_EVENT)
|
||||
{
|
||||
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
|
||||
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
|
||||
ConsoleInputUnicodeToAnsiChar(Console,
|
||||
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
|
||||
&UnicodeChar);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||
{
|
||||
if (InputEvent->EventType == KEY_EVENT)
|
||||
{
|
||||
CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
|
||||
InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
|
||||
ConsoleInputAnsiToUnicodeChar(Console,
|
||||
&InputEvent->Event.KeyEvent.uChar.UnicodeChar,
|
||||
&AsciiChar);
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG
|
||||
PreprocessInput(PCONSRV_CONSOLE Console,
|
||||
PINPUT_RECORD InputEvent,
|
||||
ULONG NumEventsToWrite)
|
||||
|
@ -98,10 +136,7 @@ PreprocessInput(PCONSRV_CONSOLE Console,
|
|||
return NumEventsToWrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* This post-processing code MUST be IN consrv ONLY
|
||||
*/
|
||||
/* static */ VOID
|
||||
static VOID
|
||||
PostprocessInput(PCONSRV_CONSOLE Console)
|
||||
{
|
||||
CsrNotifyWait(&Console->ReadWaitQueue,
|
||||
|
@ -115,7 +150,58 @@ PostprocessInput(PCONSRV_CONSOLE Console)
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleInput(IN PCONSOLE Console,
|
||||
IN PCONSOLE_INPUT_BUFFER InputBuffer,
|
||||
IN BOOLEAN AppendToEnd,
|
||||
IN PINPUT_RECORD InputRecord,
|
||||
IN ULONG NumEventsToWrite,
|
||||
OUT PULONG NumEventsWritten OPTIONAL);
|
||||
static NTSTATUS
|
||||
ConioAddInputEvents(PCONSRV_CONSOLE Console,
|
||||
PINPUT_RECORD InputRecords, // InputEvent
|
||||
ULONG NumEventsToWrite,
|
||||
PULONG NumEventsWritten,
|
||||
BOOLEAN AppendToEnd)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
if (NumEventsWritten) *NumEventsWritten = 0;
|
||||
|
||||
NumEventsToWrite = PreprocessInput(Console, InputRecords, NumEventsToWrite);
|
||||
if (NumEventsToWrite == 0) return STATUS_SUCCESS;
|
||||
|
||||
// Status = ConDrvAddInputEvents(Console,
|
||||
// InputRecords,
|
||||
// NumEventsToWrite,
|
||||
// NumEventsWritten,
|
||||
// AppendToEnd);
|
||||
|
||||
Status = ConDrvWriteConsoleInput((PCONSOLE)Console,
|
||||
&Console->InputBuffer,
|
||||
AppendToEnd,
|
||||
InputRecords,
|
||||
NumEventsToWrite,
|
||||
NumEventsWritten);
|
||||
|
||||
// if (NT_SUCCESS(Status))
|
||||
if (Status == STATUS_SUCCESS) PostprocessInput(Console);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* FIXME: This function can be called by CONDRV, in ConioResizeBuffer() in text.c */
|
||||
NTSTATUS
|
||||
ConioProcessInputEvent(PCONSRV_CONSOLE Console,
|
||||
PINPUT_RECORD InputEvent)
|
||||
{
|
||||
ULONG NumEventsWritten;
|
||||
return ConioAddInputEvents(Console,
|
||||
InputEvent,
|
||||
1,
|
||||
&NumEventsWritten,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
|
@ -127,13 +213,14 @@ WaitBeforeReading(IN PGET_INPUT_INFO InputInfo,
|
|||
if (CreateWaitBlock)
|
||||
{
|
||||
PGET_INPUT_INFO CapturedInputInfo;
|
||||
PCONSRV_CONSOLE Console = (PCONSRV_CONSOLE)InputInfo->InputBuffer->Header.Console;
|
||||
|
||||
CapturedInputInfo = ConsoleAllocHeap(0, sizeof(GET_INPUT_INFO));
|
||||
if (!CapturedInputInfo) return STATUS_NO_MEMORY;
|
||||
|
||||
RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO));
|
||||
|
||||
if (!CsrCreateWait(&InputInfo->InputBuffer->Header.Console->ReadWaitQueue,
|
||||
if (!CsrCreateWait(&Console->ReadWaitQueue,
|
||||
WaitFunction,
|
||||
InputInfo->CallingThread,
|
||||
ApiMessage,
|
||||
|
@ -381,7 +468,6 @@ ConDrvGetConsoleInput(IN PCONSOLE Console,
|
|||
IN PCONSOLE_INPUT_BUFFER InputBuffer,
|
||||
IN BOOLEAN KeepEvents,
|
||||
IN BOOLEAN WaitForMoreEvents,
|
||||
IN BOOLEAN Unicode,
|
||||
OUT PINPUT_RECORD InputRecord,
|
||||
IN ULONG NumEventsToRead,
|
||||
OUT PULONG NumEventsRead OPTIONAL);
|
||||
|
@ -422,7 +508,6 @@ ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
|
|||
InputBuffer,
|
||||
(GetInputRequest->Flags & CONSOLE_READ_KEEPEVENT) != 0,
|
||||
(GetInputRequest->Flags & CONSOLE_READ_CONTINUE ) == 0,
|
||||
GetInputRequest->Unicode,
|
||||
InputRecord,
|
||||
GetInputRequest->NumRecords,
|
||||
&NumEventsRead);
|
||||
|
@ -443,6 +528,18 @@ ReadInputBuffer(IN PGET_INPUT_INFO InputInfo,
|
|||
*/
|
||||
GetInputRequest->NumRecords = NumEventsRead;
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Now translate everything to ANSI */
|
||||
if (!GetInputRequest->Unicode)
|
||||
{
|
||||
for (; NumEventsRead > 0; --NumEventsRead)
|
||||
{
|
||||
ConioInputEventToAnsi(InputBuffer->Header.Console, --InputRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
// return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -563,14 +660,15 @@ CSR_API(SrvGetConsoleInput)
|
|||
return Status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleInput(IN PCONSOLE Console,
|
||||
IN PCONSOLE_INPUT_BUFFER InputBuffer,
|
||||
IN BOOLEAN Unicode,
|
||||
IN BOOLEAN AppendToEnd,
|
||||
IN PINPUT_RECORD InputRecord,
|
||||
IN ULONG NumEventsToWrite,
|
||||
OUT PULONG NumEventsWritten OPTIONAL);
|
||||
#endif
|
||||
CSR_API(SrvWriteConsoleInput)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
@ -619,14 +717,32 @@ CSR_API(SrvWriteConsoleInput)
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* First translate everything to UNICODE */
|
||||
if (!WriteInputRequest->Unicode)
|
||||
{
|
||||
ULONG i;
|
||||
for (i = 0; i < WriteInputRequest->NumRecords; ++i)
|
||||
{
|
||||
ConioInputEventToUnicode(InputBuffer->Header.Console, &InputRecord[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, add the events */
|
||||
NumEventsWritten = 0;
|
||||
Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console,
|
||||
InputBuffer,
|
||||
WriteInputRequest->Unicode,
|
||||
WriteInputRequest->AppendToEnd,
|
||||
InputRecord,
|
||||
WriteInputRequest->NumRecords,
|
||||
&NumEventsWritten);
|
||||
Status = ConioAddInputEvents((PCONSRV_CONSOLE)InputBuffer->Header.Console,
|
||||
// InputBuffer,
|
||||
InputRecord,
|
||||
WriteInputRequest->NumRecords,
|
||||
&NumEventsWritten,
|
||||
WriteInputRequest->AppendToEnd);
|
||||
|
||||
// Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console,
|
||||
// InputBuffer,
|
||||
// WriteInputRequest->AppendToEnd,
|
||||
// InputRecord,
|
||||
// WriteInputRequest->NumRecords,
|
||||
// &NumEventsWritten);
|
||||
|
||||
WriteInputRequest->NumRecords = NumEventsWritten;
|
||||
|
||||
ConSrvReleaseInputBuffer(InputBuffer, TRUE);
|
||||
|
|
|
@ -9,4 +9,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
VOID PurgeInputBuffer(PCONSOLE Console);
|
||||
NTSTATUS NTAPI
|
||||
ConDrvInitInputBuffer(IN PCONSOLE Console,
|
||||
IN ULONG InputBufferSize);
|
||||
VOID NTAPI
|
||||
ConDrvDeinitInputBuffer(IN PCONSOLE Console);
|
||||
|
|
|
@ -252,7 +252,7 @@ CSR_API(SrvCreateConsoleScreenBuffer)
|
|||
}
|
||||
|
||||
Status = ConDrvCreateScreenBuffer(&Buff,
|
||||
Console,
|
||||
(PCONSOLE)Console,
|
||||
CreateScreenBufferRequest->ScreenBufferType,
|
||||
ScreenBufferInfo);
|
||||
if (!NT_SUCCESS(Status)) goto Quit;
|
||||
|
@ -417,7 +417,9 @@ DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage,
|
|||
{
|
||||
if (CreateWaitBlock)
|
||||
{
|
||||
if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue,
|
||||
PCONSRV_CONSOLE Console = (PCONSRV_CONSOLE)ScreenBuffer->Header.Console;
|
||||
|
||||
if (!CsrCreateWait(&Console->WriteWaitQueue,
|
||||
WriteConsoleThread,
|
||||
ClientThread,
|
||||
ApiMessage,
|
||||
|
|
|
@ -37,7 +37,7 @@ NTSTATUS ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
|
|||
IN OUT PCONSOLE Console,
|
||||
IN ULONG BufferType,
|
||||
IN PVOID ScreenBufferInfo);
|
||||
VOID NTAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
VOID NTAPI ConDrvDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
// VOID ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
|
||||
|
||||
PCONSOLE_SCREEN_BUFFER
|
||||
|
|
|
@ -14,7 +14,13 @@
|
|||
|
||||
#include <ndk/psfuncs.h>
|
||||
|
||||
/* This is for COM usage */
|
||||
#define COBJMACROS
|
||||
#include <shlobj.h>
|
||||
|
||||
|
||||
#include <alias.h>
|
||||
#include <history.h>
|
||||
#include "procinit.h"
|
||||
|
||||
#define NDEBUG
|
||||
|
@ -25,8 +31,9 @@ NTSTATUS NTAPI RtlGetLastNtStatus(VOID);
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/* The list of the ConSrv consoles */
|
||||
static ULONG ConsoleListSize;
|
||||
static PCONSRV_CONSOLE* ConsoleList; /* The list of the ConSrv consoles */
|
||||
static PCONSRV_CONSOLE* ConsoleList;
|
||||
static RTL_RESOURCE ListLock;
|
||||
|
||||
#define ConSrvLockConsoleListExclusive() \
|
||||
|
@ -155,9 +162,8 @@ RemoveConsoleByPointer(IN PCONSRV_CONSOLE Console)
|
|||
}
|
||||
}
|
||||
|
||||
/* Unlock the console list */
|
||||
/* Unlock the console list and return */
|
||||
ConSrvUnlockConsoleList();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -187,9 +193,8 @@ ConSrvValidateConsole(OUT PCONSRV_CONSOLE* Console,
|
|||
if (Index >= ConsoleListSize ||
|
||||
(ValidatedConsole = ConsoleList[Index]) == NULL)
|
||||
{
|
||||
/* Unlock the console list */
|
||||
/* Unlock the console list and return */
|
||||
ConSrvUnlockConsoleList();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -198,7 +203,7 @@ ConSrvValidateConsole(OUT PCONSRV_CONSOLE* Console,
|
|||
/* Unlock the console list and return */
|
||||
ConSrvUnlockConsoleList();
|
||||
|
||||
RetVal = ConDrvValidateConsoleUnsafe(ValidatedConsole,
|
||||
RetVal = ConDrvValidateConsoleUnsafe((PCONSOLE)ValidatedConsole,
|
||||
ExpectedState,
|
||||
LockConsole);
|
||||
if (RetVal) *Console = ValidatedConsole;
|
||||
|
@ -209,11 +214,40 @@ ConSrvValidateConsole(OUT PCONSRV_CONSOLE* Console,
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180
|
||||
static BOOLEAN
|
||||
ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest,
|
||||
IN PCWSTR Source)
|
||||
{
|
||||
SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR);
|
||||
if (Size > MAXUSHORT) return FALSE;
|
||||
|
||||
UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
|
||||
if (UniDest->Buffer == NULL) return FALSE;
|
||||
|
||||
RtlCopyMemory(UniDest->Buffer, Source, Size);
|
||||
UniDest->MaximumLength = (USHORT)Size;
|
||||
UniDest->Length = (USHORT)Size - sizeof(WCHAR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431
|
||||
static VOID
|
||||
ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
|
||||
{
|
||||
if (UnicodeString->Buffer)
|
||||
{
|
||||
ConsoleFreeHeap(UnicodeString->Buffer);
|
||||
RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
ConioPause(PCONSRV_CONSOLE Console, UINT Flags)
|
||||
{
|
||||
Console->PauseFlags |= Flags;
|
||||
ConDrvPause(Console);
|
||||
ConDrvPause((PCONSOLE)Console);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -224,7 +258,7 @@ ConioUnpause(PCONSRV_CONSOLE Console, UINT Flags)
|
|||
// if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
|
||||
if (Console->PauseFlags == 0)
|
||||
{
|
||||
ConDrvUnpause(Console);
|
||||
ConDrvUnpause((PCONSOLE)Console);
|
||||
|
||||
CsrNotifyWait(&Console->WriteWaitQueue,
|
||||
TRUE,
|
||||
|
@ -317,10 +351,157 @@ ConSrvInitTerminal(IN OUT PTERMINAL Terminal,
|
|||
NTSTATUS NTAPI
|
||||
ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal);
|
||||
|
||||
|
||||
static BOOL
|
||||
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
|
||||
{
|
||||
#define PATH_SEPARATOR L'\\'
|
||||
|
||||
BOOL RetVal = FALSE;
|
||||
HRESULT hRes = S_OK;
|
||||
SIZE_T Length = 0;
|
||||
LPWSTR LinkName = NULL;
|
||||
LPWSTR IconPath = NULL;
|
||||
WCHAR Buffer[MAX_PATH + 1];
|
||||
|
||||
ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
|
||||
|
||||
if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||
{
|
||||
// return FALSE; // FIXME!! (for icon loading)
|
||||
RetVal = TRUE;
|
||||
goto Finish;
|
||||
}
|
||||
|
||||
/* 1- Find the last path separator if any */
|
||||
LinkName = wcsrchr(ConsoleInfo->ConsoleTitle, PATH_SEPARATOR);
|
||||
if (LinkName == NULL)
|
||||
LinkName = ConsoleInfo->ConsoleTitle;
|
||||
else
|
||||
++LinkName; // Skip the path separator
|
||||
|
||||
/* 2- Check for the link extension. The name ".lnk" is considered invalid. */
|
||||
Length = wcslen(LinkName);
|
||||
if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) )
|
||||
return FALSE;
|
||||
|
||||
/* 3- It may be a link. Try to retrieve some properties */
|
||||
hRes = CoInitialize(NULL);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/* Get a pointer to the IShellLink interface */
|
||||
IShellLinkW* pshl = NULL;
|
||||
hRes = CoCreateInstance(&CLSID_ShellLink,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLinkW,
|
||||
(LPVOID*)&pshl);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/* Get a pointer to the IPersistFile interface */
|
||||
IPersistFile* ppf = NULL;
|
||||
hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/* Load the shortcut */
|
||||
hRes = IPersistFile_Load(ppf, ConsoleInfo->ConsoleTitle, STGM_READ);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/*
|
||||
* Finally we can get the properties !
|
||||
* Update the old ones if needed.
|
||||
*/
|
||||
INT ShowCmd = 0;
|
||||
// WORD HotKey = 0;
|
||||
|
||||
/* Reset the name of the console with the name of the shortcut */
|
||||
Length = min(/*Length*/ Length - 4, // 4 == len(".lnk")
|
||||
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)) ConsoleInitInfo->ConsoleStartInfo->wShowWindow = (WORD)ShowCmd;
|
||||
|
||||
/* Get the hotkey */
|
||||
// hRes = pshl->GetHotkey(&ShowCmd);
|
||||
// if (SUCCEEDED(hRes)) ConsoleInitInfo->ConsoleStartInfo->HotKey = HotKey;
|
||||
|
||||
/* Get the icon location, if any */
|
||||
hRes = IShellLinkW_GetIconLocation(pshl,
|
||||
Buffer,
|
||||
sizeof(Buffer)/sizeof(Buffer[0]) - 1, // == MAX_PATH
|
||||
&ConsoleInitInfo->ConsoleStartInfo->IconIndex);
|
||||
if (!SUCCEEDED(hRes))
|
||||
{
|
||||
ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
IconPath = Buffer;
|
||||
}
|
||||
|
||||
// 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 = TRUE; // FALSE;
|
||||
}
|
||||
IPersistFile_Release(ppf);
|
||||
}
|
||||
IShellLinkW_Release(pshl);
|
||||
}
|
||||
}
|
||||
CoUninitialize();
|
||||
|
||||
Finish:
|
||||
|
||||
if (RetVal)
|
||||
{
|
||||
/* Get the associated icon, if any */
|
||||
if (IconPath == NULL)
|
||||
{
|
||||
// Question: How to retrieve the full path name
|
||||
// of the app we are going to run??
|
||||
Length = RtlDosSearchPath_U(ConsoleInitInfo->CurDir,
|
||||
ConsoleInitInfo->AppName,
|
||||
NULL,
|
||||
sizeof(Buffer),
|
||||
Buffer,
|
||||
NULL);
|
||||
if (Length > 0 && Length < sizeof(Buffer))
|
||||
IconPath = Buffer;
|
||||
else
|
||||
IconPath = ConsoleInitInfo->AppName;
|
||||
|
||||
// ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
|
||||
}
|
||||
DPRINT1("IconPath = '%S' ; IconIndex = %lu\n",
|
||||
IconPath, ConsoleInitInfo->ConsoleStartInfo->IconIndex);
|
||||
if (IconPath && *IconPath)
|
||||
{
|
||||
HICON hIcon = NULL, hIconSm = NULL;
|
||||
PrivateExtractIconExW(IconPath,
|
||||
ConsoleInitInfo->ConsoleStartInfo->IconIndex,
|
||||
&hIcon,
|
||||
&hIconSm,
|
||||
1);
|
||||
DPRINT1("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
|
||||
if (hIcon != NULL) ConsoleInitInfo->ConsoleStartInfo->hIcon = hIcon;
|
||||
if (hIconSm != NULL) ConsoleInitInfo->ConsoleStartInfo->hIconSm = hIconSm;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: See the previous FIXME above.
|
||||
RetVal = FALSE;
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||
OUT PCONSRV_CONSOLE* NewConsole,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
||||
IN ULONG ConsoleLeaderProcessId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
@ -331,7 +512,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
|
||||
TERMINAL Terminal; /* The ConSrv terminal for this console */
|
||||
|
||||
if (NewConsole == NULL || ConsoleStartInfo == NULL)
|
||||
if (NewConsole == NULL || ConsoleInitInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
*NewConsole = NULL;
|
||||
|
@ -344,15 +525,15 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
ConSrvGetDefaultSettings(&ConsoleInfo, ConsoleLeaderProcessId);
|
||||
|
||||
/* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */
|
||||
Length = min(wcslen(ConsoleStartInfo->ConsoleTitle),
|
||||
Length = min(ConsoleInitInfo->TitleLength,
|
||||
sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1);
|
||||
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length);
|
||||
ConsoleInfo.ConsoleTitle[Length] = L'\0';
|
||||
wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length);
|
||||
ConsoleInfo.ConsoleTitle[Length] = L'\0'; // NULL-terminate it.
|
||||
|
||||
/* 3. Initialize the ConSrv terminal */
|
||||
Status = ConSrvInitTerminal(&Terminal,
|
||||
&ConsoleInfo,
|
||||
ConsoleStartInfo,
|
||||
ConsoleInitInfo,
|
||||
ConsoleLeaderProcessId);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -361,10 +542,25 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
}
|
||||
DPRINT("CONSRV: Terminal initialized\n");
|
||||
|
||||
/*
|
||||
* Load per-application terminal settings.
|
||||
*
|
||||
* Check whether the process creating the console was launched via
|
||||
* a shell-link. ConsoleInfo->ConsoleTitle may be updated with the
|
||||
* name of the shortcut, and ConsoleStartInfo->Icon[Path|Index] too.
|
||||
*/
|
||||
// if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) // FIXME!! (for icon loading)
|
||||
{
|
||||
if (!LoadShellLinkConsoleInfo(&ConsoleInfo, ConsoleInitInfo))
|
||||
{
|
||||
ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 4. Load the remaining console settings via the registry.
|
||||
*/
|
||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||
if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||
{
|
||||
/*
|
||||
* Either we weren't created by an app launched via a shell-link,
|
||||
|
@ -379,17 +575,17 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
* (and which was transmitted via the ConsoleStartInfo structure).
|
||||
* We therefore overwrite the values read in the registry.
|
||||
*/
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
|
||||
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
|
||||
{
|
||||
ConsoleInfo.ScreenAttrib = (USHORT)ConsoleStartInfo->wFillAttribute;
|
||||
ConsoleInfo.ScreenAttrib = (USHORT)ConsoleInitInfo->ConsoleStartInfo->wFillAttribute;
|
||||
}
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
|
||||
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
|
||||
{
|
||||
ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->dwScreenBufferSize;
|
||||
ConsoleInfo.ScreenBufferSize = ConsoleInitInfo->ConsoleStartInfo->dwScreenBufferSize;
|
||||
}
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
|
||||
if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
|
||||
{
|
||||
ConsoleInfo.ConsoleSize = ConsoleStartInfo->dwWindowSize;
|
||||
ConsoleInfo.ConsoleSize = ConsoleInitInfo->ConsoleStartInfo->dwWindowSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,6 +606,31 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
|
||||
/*** Register ConSrv features ***/
|
||||
|
||||
/* Initialize the console title */
|
||||
#if 0
|
||||
WCHAR DefaultTitle[128];
|
||||
#endif
|
||||
ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo.ConsoleTitle);
|
||||
#if 0
|
||||
if (ConsoleInfo.ConsoleTitle[0] == L'\0')
|
||||
{
|
||||
if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
|
||||
{
|
||||
ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle);
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize process support */
|
||||
InitializeListHead(&Console->ProcessList);
|
||||
Console->NotifiedLastCloseProcess = NULL;
|
||||
|
@ -427,12 +648,25 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
|||
Console->NumberOfHistoryBuffers = ConsoleInfo.NumberOfHistoryBuffers;
|
||||
Console->HistoryNoDup = ConsoleInfo.HistoryNoDup;
|
||||
|
||||
Console->QuickEdit = ConsoleInfo.QuickEdit;
|
||||
/* Initialize the Input Line Discipline */
|
||||
Console->LineBuffer = NULL;
|
||||
Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
|
||||
Console->LineComplete = Console->LineUpPressed = FALSE;
|
||||
// LineWakeupMask
|
||||
Console->LineInsertToggle =
|
||||
Console->InsertMode = ConsoleInfo.InsertMode;
|
||||
Console->QuickEdit = ConsoleInfo.QuickEdit;
|
||||
|
||||
/* Popup windows */
|
||||
InitializeListHead(&Console->PopupWindows);
|
||||
|
||||
/* Colour table */
|
||||
memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors));
|
||||
|
||||
/* Attach the ConSrv terminal to the console */
|
||||
/*
|
||||
* Attach the ConSrv terminal to the console.
|
||||
* This call makes a copy of our local Terminal variable.
|
||||
*/
|
||||
Status = ConDrvRegisterTerminal(Console, &Terminal);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -462,12 +696,23 @@ ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
|
|||
/* Remove the console from the list */
|
||||
RemoveConsoleByPointer(Console);
|
||||
|
||||
/* Clean the Input Line Discipline */
|
||||
if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
|
||||
|
||||
/* Clean aliases and history */
|
||||
IntDeleteAllAliases(Console);
|
||||
HistoryDeleteBuffers(Console);
|
||||
|
||||
/* Free the console title */
|
||||
ConsoleFreeUnicodeString(&Console->OriginalTitle);
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
|
||||
/* Now, call the driver. ConDrvDeregisterTerminal is called on-demand. */
|
||||
ConDrvDeleteConsole(Console);
|
||||
ConDrvDeleteConsole((PCONSOLE)Console);
|
||||
|
||||
/* Deinit the ConSrv terminal */
|
||||
// FIXME!!
|
||||
// ConSrvDeinitTerminal(&Terminal); // &ConSrvConsole->Console->TermIFace
|
||||
}
|
||||
|
||||
|
||||
|
@ -484,7 +729,7 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|||
|
||||
DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
|
||||
|
||||
if (ProcessData->CtrlDispatcher)
|
||||
if (ProcessData->CtrlRoutine)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -493,7 +738,7 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|||
_SEH2_TRY
|
||||
{
|
||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||
ProcessData->CtrlDispatcher,
|
||||
ProcessData->CtrlRoutine,
|
||||
UlongToPtr(CtrlEvent), 0, NULL);
|
||||
if (NULL == Thread)
|
||||
{
|
||||
|
@ -502,7 +747,8 @@ ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent,
|
|||
}
|
||||
else
|
||||
{
|
||||
DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||
DPRINT("ProcessData->CtrlRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
|
||||
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||
WaitForSingleObject(Thread, Timeout);
|
||||
}
|
||||
}
|
||||
|
@ -579,7 +825,7 @@ ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console,
|
|||
PCONSOLE_PROCESS_DATA current;
|
||||
|
||||
/* If the console is already being destroyed, just return */
|
||||
if (!ConDrvValidateConsoleState(Console, CONSOLE_RUNNING))
|
||||
if (!ConDrvValidateConsoleState((PCONSOLE)Console, CONSOLE_RUNNING))
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/*
|
||||
|
@ -608,9 +854,6 @@ ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console,
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* PUBLIC SERVER APIS *********************************************************/
|
||||
|
||||
CSR_API(SrvAllocConsole)
|
||||
|
@ -619,6 +862,7 @@ CSR_API(SrvAllocConsole)
|
|||
PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
|
||||
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
CONSOLE_INIT_INFO ConsoleInitInfo;
|
||||
|
||||
if (ProcessData->ConsoleHandle != NULL)
|
||||
{
|
||||
|
@ -626,33 +870,64 @@ CSR_API(SrvAllocConsole)
|
|||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
||||
1,
|
||||
sizeof(CONSOLE_START_INFO)))
|
||||
if ( !CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
|
||||
1,
|
||||
sizeof(CONSOLE_START_INFO)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->ConsoleTitle,
|
||||
AllocConsoleRequest->TitleLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->Desktop,
|
||||
AllocConsoleRequest->DesktopLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->CurDir,
|
||||
AllocConsoleRequest->CurDirLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AllocConsoleRequest->AppName,
|
||||
AllocConsoleRequest->AppNameLength,
|
||||
sizeof(BYTE)) )
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Initialize the console initialization info structure */
|
||||
ConsoleInitInfo.ConsoleStartInfo = AllocConsoleRequest->ConsoleStartInfo;
|
||||
ConsoleInitInfo.TitleLength = AllocConsoleRequest->TitleLength;
|
||||
ConsoleInitInfo.ConsoleTitle = AllocConsoleRequest->ConsoleTitle;
|
||||
ConsoleInitInfo.DesktopLength = AllocConsoleRequest->DesktopLength;
|
||||
ConsoleInitInfo.Desktop = AllocConsoleRequest->Desktop;
|
||||
ConsoleInitInfo.AppNameLength = AllocConsoleRequest->AppNameLength;
|
||||
ConsoleInitInfo.AppName = AllocConsoleRequest->AppName;
|
||||
ConsoleInitInfo.CurDirLength = AllocConsoleRequest->CurDirLength;
|
||||
ConsoleInitInfo.CurDir = AllocConsoleRequest->CurDir;
|
||||
|
||||
/* Initialize a new Console owned by the Console Leader Process */
|
||||
Status = ConSrvAllocateConsole(ProcessData,
|
||||
&AllocConsoleRequest->InputHandle,
|
||||
&AllocConsoleRequest->OutputHandle,
|
||||
&AllocConsoleRequest->ErrorHandle,
|
||||
AllocConsoleRequest->ConsoleStartInfo);
|
||||
&AllocConsoleRequest->ConsoleStartInfo->InputHandle,
|
||||
&AllocConsoleRequest->ConsoleStartInfo->OutputHandle,
|
||||
&AllocConsoleRequest->ConsoleStartInfo->ErrorHandle,
|
||||
&ConsoleInitInfo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console allocation failed\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Mark the process as having a console */
|
||||
ProcessData->ConsoleApp = TRUE;
|
||||
CsrProcess->Flags |= CsrProcessIsConsoleApp;
|
||||
|
||||
/* Return the console handle and the input wait handle to the caller */
|
||||
AllocConsoleRequest->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
AllocConsoleRequest->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
AllocConsoleRequest->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
AllocConsoleRequest->ConsoleStartInfo->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
|
||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||
ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher;
|
||||
ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
|
||||
ProcessData->PropRoutine = AllocConsoleRequest->PropRoutine;
|
||||
ProcessData->CtrlRoutine = AllocConsoleRequest->CtrlRoutine;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -674,6 +949,14 @@ CSR_API(SrvAttachConsole)
|
|||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&AttachConsoleRequest->ConsoleStartInfo,
|
||||
1,
|
||||
sizeof(CONSOLE_START_INFO)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Check whether we try to attach to the parent's console */
|
||||
if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS))
|
||||
{
|
||||
|
@ -714,22 +997,26 @@ CSR_API(SrvAttachConsole)
|
|||
Status = ConSrvInheritConsole(TargetProcessData,
|
||||
SourceProcessData->ConsoleHandle,
|
||||
TRUE,
|
||||
&AttachConsoleRequest->InputHandle,
|
||||
&AttachConsoleRequest->OutputHandle,
|
||||
&AttachConsoleRequest->ErrorHandle);
|
||||
&AttachConsoleRequest->ConsoleStartInfo->InputHandle,
|
||||
&AttachConsoleRequest->ConsoleStartInfo->OutputHandle,
|
||||
&AttachConsoleRequest->ConsoleStartInfo->ErrorHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console inheritance failed\n");
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Mark the process as having a console */
|
||||
TargetProcessData->ConsoleApp = TRUE;
|
||||
TargetProcess->Flags |= CsrProcessIsConsoleApp;
|
||||
|
||||
/* Return the console handle and the input wait handle to the caller */
|
||||
AttachConsoleRequest->ConsoleHandle = TargetProcessData->ConsoleHandle;
|
||||
AttachConsoleRequest->InputWaitHandle = TargetProcessData->InputWaitHandle;
|
||||
AttachConsoleRequest->ConsoleStartInfo->ConsoleHandle = TargetProcessData->ConsoleHandle;
|
||||
AttachConsoleRequest->ConsoleStartInfo->InputWaitHandle = TargetProcessData->InputWaitHandle;
|
||||
|
||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||
TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher;
|
||||
TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher;
|
||||
TargetProcessData->PropRoutine = AttachConsoleRequest->PropRoutine;
|
||||
TargetProcessData->CtrlRoutine = AttachConsoleRequest->CtrlRoutine;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
|
@ -741,7 +1028,15 @@ Quit:
|
|||
|
||||
CSR_API(SrvFreeConsole)
|
||||
{
|
||||
PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
|
||||
ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process));
|
||||
|
||||
/* Mark the process as not having a console anymore */
|
||||
ProcessData->ConsoleApp = FALSE;
|
||||
CsrProcess->Flags &= ~CsrProcessIsConsoleApp;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -755,13 +1050,34 @@ CSR_API(SrvGetConsoleMode)
|
|||
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
|
||||
PCONSOLE_IO_OBJECT Object;
|
||||
|
||||
PULONG ConsoleMode = &ConsoleModeRequest->Mode;
|
||||
|
||||
Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
ConsoleModeRequest->Handle,
|
||||
&Object, NULL, GENERIC_READ, TRUE, 0);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Get the standard console modes */
|
||||
Status = ConDrvGetConsoleMode(Object->Console, Object,
|
||||
&ConsoleModeRequest->Mode);
|
||||
ConsoleMode);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/*
|
||||
* If getting the console modes succeeds, then retrieve
|
||||
* the extended CONSRV-specific input modes.
|
||||
*/
|
||||
if (INPUT_BUFFER == Object->Type)
|
||||
{
|
||||
if (Object->Console->InsertMode || Object->Console->QuickEdit)
|
||||
{
|
||||
/* Windows also adds ENABLE_EXTENDED_FLAGS, even if it's not documented on MSDN */
|
||||
*ConsoleMode |= ENABLE_EXTENDED_FLAGS;
|
||||
|
||||
if (Object->Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
|
||||
if (Object->Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConSrvReleaseObject(Object, TRUE);
|
||||
return Status;
|
||||
|
@ -773,32 +1089,63 @@ ConDrvSetConsoleMode(IN PCONSOLE Console,
|
|||
IN ULONG ConsoleMode);
|
||||
CSR_API(SrvSetConsoleMode)
|
||||
{
|
||||
#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | \
|
||||
ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
|
||||
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
|
||||
PCONSOLE_IO_OBJECT Object;
|
||||
|
||||
ULONG ConsoleMode = ConsoleModeRequest->Mode;
|
||||
|
||||
Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
ConsoleModeRequest->Handle,
|
||||
&Object, NULL, GENERIC_WRITE, TRUE, 0);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Set the standard console modes (without the CONSRV-specific input modes) */
|
||||
ConsoleMode &= ~CONSOLE_VALID_CONTROL_MODES; // Remove CONSRV-specific input modes.
|
||||
Status = ConDrvSetConsoleMode(Object->Console, Object,
|
||||
ConsoleModeRequest->Mode);
|
||||
ConsoleMode);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/*
|
||||
* If setting the console modes succeeds, then set
|
||||
* the extended CONSRV-specific input modes.
|
||||
*/
|
||||
if (INPUT_BUFFER == Object->Type)
|
||||
{
|
||||
ConsoleMode = ConsoleModeRequest->Mode;
|
||||
|
||||
if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
|
||||
{
|
||||
/*
|
||||
* If we use control mode flags without ENABLE_EXTENDED_FLAGS,
|
||||
* then consider the flags invalid.
|
||||
*/
|
||||
if ((ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
Object->Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
|
||||
Object->Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConSrvReleaseObject(Object, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvGetConsoleTitle(IN PCONSOLE Console,
|
||||
IN BOOLEAN Unicode,
|
||||
IN OUT PVOID TitleBuffer,
|
||||
IN OUT PULONG BufLength);
|
||||
CSR_API(SrvGetConsoleTitle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
ULONG Length;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID)&TitleRequest->Title,
|
||||
|
@ -815,26 +1162,52 @@ CSR_API(SrvGetConsoleTitle)
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ConDrvGetConsoleTitle(Console,
|
||||
TitleRequest->Unicode,
|
||||
TitleRequest->Title,
|
||||
&TitleRequest->Length);
|
||||
/* Copy title of the console to the user title buffer */
|
||||
if (TitleRequest->Unicode)
|
||||
{
|
||||
if (TitleRequest->Length >= sizeof(WCHAR))
|
||||
{
|
||||
Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
|
||||
RtlCopyMemory(TitleRequest->Title, Console->Title.Buffer, Length);
|
||||
((PWCHAR)TitleRequest->Title)[Length / sizeof(WCHAR)] = L'\0';
|
||||
TitleRequest->Length = Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
TitleRequest->Length = Console->Title.Length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TitleRequest->Length >= sizeof(CHAR))
|
||||
{
|
||||
Length = min(TitleRequest->Length - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
|
||||
Length = WideCharToMultiByte(Console->InputCodePage, 0,
|
||||
Console->Title.Buffer, Length,
|
||||
TitleRequest->Title, Length,
|
||||
NULL, NULL);
|
||||
((PCHAR)TitleRequest->Title)[Length] = '\0';
|
||||
TitleRequest->Length = Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
TitleRequest->Length = Console->Title.Length / sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvSetConsoleTitle(IN PCONSOLE Console,
|
||||
IN BOOLEAN Unicode,
|
||||
IN PVOID TitleBuffer,
|
||||
IN ULONG BufLength);
|
||||
CSR_API(SrvSetConsoleTitle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
PWCHAR Buffer;
|
||||
ULONG Length;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID)&TitleRequest->Title,
|
||||
TitleRequest->Length,
|
||||
|
@ -850,12 +1223,56 @@ CSR_API(SrvSetConsoleTitle)
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ConDrvSetConsoleTitle(Console,
|
||||
TitleRequest->Unicode,
|
||||
TitleRequest->Title,
|
||||
TitleRequest->Length);
|
||||
if (NT_SUCCESS(Status)) TermChangeTitle(Console);
|
||||
if (TitleRequest->Unicode)
|
||||
{
|
||||
/* Length is in bytes */
|
||||
Length = TitleRequest->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the console input CP for the conversion */
|
||||
Length = MultiByteToWideChar(Console->InputCodePage, 0,
|
||||
TitleRequest->Title, TitleRequest->Length,
|
||||
NULL, 0);
|
||||
/* The returned Length was in number of wchars, convert it in bytes */
|
||||
Length *= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/* Allocate a new buffer to hold the new title (NULL-terminated) */
|
||||
Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Length + sizeof(WCHAR));
|
||||
if (!Buffer)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Free the old title */
|
||||
ConsoleFreeUnicodeString(&Console->Title);
|
||||
|
||||
/* Copy title to console */
|
||||
Console->Title.Buffer = Buffer;
|
||||
Console->Title.Length = Length;
|
||||
Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
|
||||
|
||||
if (TitleRequest->Unicode)
|
||||
{
|
||||
RtlCopyMemory(Console->Title.Buffer, TitleRequest->Title, Console->Title.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
MultiByteToWideChar(Console->InputCodePage, 0,
|
||||
TitleRequest->Title, TitleRequest->Length,
|
||||
Console->Title.Buffer,
|
||||
Console->Title.Length / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
/* NULL-terminate */
|
||||
Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
TermChangeTitle(Console);
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Quit:
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -8,27 +8,41 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
typedef struct _CONSOLE_INIT_INFO
|
||||
{
|
||||
PCONSOLE_START_INFO ConsoleStartInfo;
|
||||
|
||||
ULONG TitleLength;
|
||||
PWCHAR ConsoleTitle;
|
||||
ULONG DesktopLength;
|
||||
PWCHAR Desktop;
|
||||
ULONG AppNameLength;
|
||||
PWCHAR AppName;
|
||||
ULONG CurDirLength;
|
||||
PWCHAR CurDir;
|
||||
} CONSOLE_INIT_INFO, *PCONSOLE_INIT_INFO;
|
||||
|
||||
VOID NTAPI
|
||||
ConSrvInitConsoleSupport(VOID);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConSrvInitConsole(OUT PHANDLE NewConsoleHandle,
|
||||
OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole,
|
||||
IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ NewConsole,
|
||||
IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
|
||||
IN ULONG ConsoleLeaderProcessId);
|
||||
VOID NTAPI ConSrvDeleteConsole(struct _CONSOLE* /* PCONSOLE */ Console);
|
||||
VOID NTAPI ConSrvDeleteConsole(struct _CONSRV_CONSOLE* /* PCONSRV_CONSOLE */ Console);
|
||||
|
||||
NTSTATUS
|
||||
ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData,
|
||||
OUT struct _CONSOLE** /* PCONSOLE* */ Console,
|
||||
OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ Console,
|
||||
IN BOOLEAN LockConsole);
|
||||
VOID
|
||||
ConSrvReleaseConsole(IN struct _CONSOLE* /* PCONSOLE */ Console,
|
||||
ConSrvReleaseConsole(IN struct _CONSRV_CONSOLE* /* PCONSRV_CONSOLE */ Console,
|
||||
IN BOOLEAN WasConsoleLocked);
|
||||
|
||||
|
||||
BOOLEAN NTAPI
|
||||
ConSrvValidateConsole(OUT struct _CONSOLE** /* PCONSOLE* */ Console,
|
||||
ConSrvValidateConsole(OUT struct _CONSRV_CONSOLE** /* PCONSRV_CONSOLE* */ Console,
|
||||
IN HANDLE ConsoleHandle,
|
||||
IN CONSOLE_STATE ExpectedState,
|
||||
IN BOOLEAN LockConsole);
|
||||
|
|
|
@ -51,10 +51,9 @@ typedef struct _CONSOLE_PROCESS_DATA
|
|||
{
|
||||
LIST_ENTRY ConsoleLink;
|
||||
PCSR_PROCESS Process; // Process owning this structure.
|
||||
HANDLE InputWaitHandle;
|
||||
|
||||
HANDLE ConsoleHandle;
|
||||
HANDLE ParentConsoleHandle;
|
||||
HANDLE InputWaitHandle;
|
||||
|
||||
BOOLEAN ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise.
|
||||
|
||||
|
@ -62,12 +61,21 @@ typedef struct _CONSOLE_PROCESS_DATA
|
|||
ULONG HandleTableSize;
|
||||
struct _CONSOLE_IO_HANDLE* /* 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.
|
||||
LPTHREAD_START_ROUTINE CtrlRoutine;
|
||||
LPTHREAD_START_ROUTINE PropRoutine; // We hold the property dialog handler there, till all the GUI thingie moves out from CSRSS.
|
||||
// LPTHREAD_START_ROUTINE ImeRoutine;
|
||||
} CONSOLE_PROCESS_DATA, *PCONSOLE_PROCESS_DATA;
|
||||
|
||||
|
||||
// Helper for code refactoring
|
||||
// #define USE_NEW_CONSOLE_WAY
|
||||
|
||||
#ifndef USE_NEW_CONSOLE_WAY
|
||||
#include "include/conio.h"
|
||||
// #include "include/conio_winsrv.h"
|
||||
#else
|
||||
#include "include/conio_winsrv.h"
|
||||
#endif
|
||||
|
||||
#include "include/console.h"
|
||||
#include "include/settings.h"
|
||||
#include "include/term.h"
|
||||
|
|
|
@ -143,7 +143,7 @@ CSR_API(SrvSetConsoleDisplayMode)
|
|||
TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Console = Buff->Header.Console;
|
||||
Console = (PCONSRV_CONSOLE)Buff->Header.Console;
|
||||
|
||||
if (TermSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode))
|
||||
{
|
||||
|
@ -163,14 +163,14 @@ CSR_API(SrvGetLargestConsoleWindowSize)
|
|||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetLargestWindowSizeRequest;
|
||||
PCONSOLE /*PCONSRV_CONSOLE*/ Console;
|
||||
PCONSOLE_SCREEN_BUFFER Buff;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
GetLargestWindowSizeRequest->OutputHandle,
|
||||
&Buff,
|
||||
GENERIC_READ,
|
||||
TRUE);
|
||||
GetLargestWindowSizeRequest->OutputHandle,
|
||||
&Buff,
|
||||
GENERIC_READ,
|
||||
TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Console = Buff->Header.Console;
|
||||
|
@ -184,7 +184,7 @@ CSR_API(SrvShowConsoleCursor)
|
|||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_SHOWCURSOR ShowCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ShowCursorRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PCONSOLE /*PCONSRV_CONSOLE*/ Console;
|
||||
PCONSOLE_SCREEN_BUFFER Buff;
|
||||
|
||||
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
|
@ -220,7 +220,7 @@ CSR_API(SrvSetConsoleCursor)
|
|||
TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Console = Buff->Header.Console;
|
||||
Console = (PCONSRV_CONSOLE)Buff->Header.Console;
|
||||
|
||||
Success = TermSetMouseCursor(Console, SetCursorRequest->CursorHandle);
|
||||
|
||||
|
@ -242,7 +242,7 @@ CSR_API(SrvConsoleMenuControl)
|
|||
TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Console = Buff->Header.Console;
|
||||
Console = (PCONSRV_CONSOLE)Buff->Header.Console;
|
||||
|
||||
MenuControlRequest->MenuHandle = TermMenuControl(Console,
|
||||
MenuControlRequest->CmdIdLow,
|
||||
|
@ -275,7 +275,8 @@ CSR_API(SrvGetConsoleWindow)
|
|||
PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
GetWindowRequest->WindowHandle = TermGetConsoleWindowHandle(Console);
|
||||
|
@ -290,7 +291,8 @@ CSR_API(SrvSetConsoleIcon)
|
|||
PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Status = (TermChangeIcon(Console, SetIconRequest->IconHandle)
|
||||
|
@ -307,7 +309,8 @@ CSR_API(SrvGetConsoleSelectionInfo)
|
|||
PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Status = (TermGetSelectionInfo(Console, &GetSelectionInfoRequest->Info)
|
||||
|
|
|
@ -539,10 +539,15 @@ InitFonts(PGUI_CONSOLE_DATA GuiData,
|
|||
TEXTMETRICW Metrics;
|
||||
SIZE CharSize;
|
||||
|
||||
hDC = GetDC(GuiData->hWindow);
|
||||
|
||||
/*
|
||||
* Initialize a new NORMAL font and get its metrics.
|
||||
*/
|
||||
|
||||
FontSize.Y = FontSize.Y > 0 ? -MulDiv(FontSize.Y, GetDeviceCaps(hDC, LOGPIXELSY), 72)
|
||||
: FontSize.Y;
|
||||
|
||||
NewFont = CreateFontW(FontSize.Y,
|
||||
FontSize.X,
|
||||
0,
|
||||
|
@ -554,20 +559,13 @@ InitFonts(PGUI_CONSOLE_DATA GuiData,
|
|||
OEM_CHARSET,
|
||||
OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY, // NONANTIALIASED_QUALITY ; ANTIALIASED_QUALITY
|
||||
DEFAULT_QUALITY,
|
||||
FIXED_PITCH | FontFamily,
|
||||
FaceName);
|
||||
if (NewFont == NULL)
|
||||
{
|
||||
DPRINT1("InitFonts: CreateFontW failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hDC = GetDC(GuiData->hWindow);
|
||||
if (hDC == NULL)
|
||||
{
|
||||
DPRINT1("InitFonts: GetDC failed\n");
|
||||
DeleteObject(NewFont);
|
||||
ReleaseDC(GuiData->hWindow, hDC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -591,7 +589,7 @@ InitFonts(PGUI_CONSOLE_DATA GuiData,
|
|||
GuiData->CharWidth = Metrics.tmMaxCharWidth;
|
||||
GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
|
||||
|
||||
/* Measure real char width more precisely if possible. */
|
||||
/* Measure real char width more precisely if possible */
|
||||
if (GetTextExtentPoint32W(hDC, L"R", 1, &CharSize))
|
||||
GuiData->CharWidth = CharSize.cx;
|
||||
|
||||
|
@ -2437,7 +2435,7 @@ ConWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
case PM_CONSOLE_BEEP:
|
||||
DPRINT1("Beep !!\n");
|
||||
DPRINT1("Beep\n");
|
||||
Beep(800, 200);
|
||||
break;
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef struct _GUI_CONSOLE_DATA
|
|||
CRITICAL_SECTION Lock;
|
||||
BOOL WindowSizeLock;
|
||||
HANDLE hGuiInitEvent;
|
||||
HANDLE hGuiTermEvent;
|
||||
|
||||
POINT OldCursor;
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
|
||||
pSharedInfo->ci.QuickEdit = Console->QuickEdit;
|
||||
pSharedInfo->ci.InsertMode = Console->InsertMode;
|
||||
pSharedInfo->ci.InputBufferSize = 0;
|
||||
/////////////pSharedInfo->ci.InputBufferSize = 0;
|
||||
pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
|
||||
pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
|
||||
pSharedInfo->ci.CursorBlinkOn;
|
||||
|
@ -372,7 +372,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
}
|
||||
|
||||
/* Start the properties dialog */
|
||||
if (ProcessData->PropDispatcher)
|
||||
if (ProcessData->PropRoutine)
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
@ -381,7 +381,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
_SEH2_TRY
|
||||
{
|
||||
Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
|
||||
ProcessData->PropDispatcher,
|
||||
ProcessData->PropRoutine,
|
||||
(PVOID)hClientSection, 0, NULL);
|
||||
if (NULL == Thread)
|
||||
{
|
||||
|
@ -389,7 +389,8 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|||
}
|
||||
else
|
||||
{
|
||||
DPRINT("ProcessData->PropDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||
DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
|
||||
ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
|
||||
/// WaitForSingleObject(Thread, INFINITE);
|
||||
}
|
||||
}
|
||||
|
@ -643,7 +644,6 @@ GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
|
|||
Console->OriginalTitle.Length / sizeof(WCHAR));
|
||||
wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
|
||||
#endif
|
||||
// ULONG ConInfo.InputBufferSize = pConInfo->
|
||||
// BOOLEAN ConInfo.CursorBlinkOn = pConInfo->
|
||||
// BOOLEAN ConInfo.ForceCursorOff = pConInfo->
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef struct _CONSOLE_STATE_INFO
|
|||
COLORREF ColorTable[16];
|
||||
|
||||
ULONG CodePage;
|
||||
HWND HWnd;
|
||||
HWND hWnd;
|
||||
|
||||
WCHAR ConsoleTitle[256];
|
||||
} CONSOLE_STATE_INFO, *PCONSOLE_STATE_INFO;
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
#include <consrv.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#include <shlobj.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -45,7 +42,8 @@ typedef struct _GUI_INIT_INFO
|
|||
} GUI_INIT_INFO, *PGUI_INIT_INFO;
|
||||
|
||||
static BOOL ConsInitialized = FALSE;
|
||||
static HWND NotifyWnd = NULL;
|
||||
static HANDLE hInputThread = NULL;
|
||||
static DWORD dwInputThreadId = 0;
|
||||
|
||||
extern HICON ghDefaultIcon;
|
||||
extern HICON ghDefaultIconSm;
|
||||
|
@ -142,48 +140,59 @@ VOID
|
|||
SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen);
|
||||
VOID
|
||||
CreateSysMenu(HWND hWnd);
|
||||
static LRESULT CALLBACK
|
||||
GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
static DWORD NTAPI
|
||||
GuiConsoleInputThread(PVOID Data)
|
||||
{
|
||||
HWND NewWindow;
|
||||
LONG WindowCount;
|
||||
MSG Msg;
|
||||
PHANDLE GraphicsStartupEvent = (PHANDLE)Data;
|
||||
LONG WindowCount = 0;
|
||||
MSG msg;
|
||||
|
||||
switch (msg)
|
||||
/*
|
||||
* This thread dispatches all the console notifications to the notify window.
|
||||
* It is common for all the console windows.
|
||||
*/
|
||||
|
||||
/* The thread has been initialized, set the event */
|
||||
SetEvent(*GraphicsStartupEvent);
|
||||
|
||||
while (GetMessageW(&msg, NULL, 0, 0))
|
||||
{
|
||||
case WM_CREATE:
|
||||
switch (msg.message)
|
||||
{
|
||||
SetWindowLongW(hWnd, GWL_USERDATA, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case PM_CREATE_CONSOLE:
|
||||
{
|
||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
|
||||
PCONSRV_CONSOLE Console = GuiData->Console;
|
||||
RECT rcWnd;
|
||||
|
||||
DPRINT("PM_CREATE_CONSOLE -- creating window\n");
|
||||
|
||||
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
|
||||
GUI_CONWND_CLASS,
|
||||
Console->Title.Buffer,
|
||||
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
ConSrvDllInstance,
|
||||
(PVOID)GuiData);
|
||||
if (NULL != NewWindow)
|
||||
case PM_CREATE_CONSOLE:
|
||||
{
|
||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)msg.lParam;
|
||||
PCONSRV_CONSOLE Console = GuiData->Console;
|
||||
HWND NewWindow;
|
||||
RECT rcWnd;
|
||||
|
||||
DPRINT("PM_CREATE_CONSOLE -- creating window\n");
|
||||
|
||||
PrivateCsrssManualGuiCheck(-1); // co_AddGuiApp
|
||||
|
||||
NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
|
||||
GUI_CONWND_CLASS,
|
||||
Console->Title.Buffer,
|
||||
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
ConSrvDllInstance,
|
||||
(PVOID)GuiData);
|
||||
if (NewWindow == NULL)
|
||||
{
|
||||
DPRINT1("Failed to create a new console window\n");
|
||||
PrivateCsrssManualGuiCheck(+1); // RemoveGuiApp
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT(NewWindow == GuiData->hWindow);
|
||||
|
||||
WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
|
||||
WindowCount++;
|
||||
SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
|
||||
InterlockedIncrement(&WindowCount);
|
||||
|
||||
//
|
||||
// FIXME: TODO: Move everything there into conwnd.c!OnNcCreate()
|
||||
|
@ -208,99 +217,60 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if (GuiData->GuiInfo.FullScreen) SwitchFullScreen(GuiData, TRUE);
|
||||
|
||||
DPRINT("PM_CREATE_CONSOLE -- showing window\n");
|
||||
// ShowWindow(NewWindow, (int)wParam);
|
||||
ShowWindowAsync(NewWindow, (int)wParam);
|
||||
// ShowWindow(NewWindow, (int)GuiData->GuiInfo.ShowWindow);
|
||||
ShowWindowAsync(NewWindow, (int)GuiData->GuiInfo.ShowWindow);
|
||||
DPRINT("Window showed\n");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return (LRESULT)NewWindow;
|
||||
}
|
||||
|
||||
case PM_DESTROY_CONSOLE:
|
||||
{
|
||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)lParam;
|
||||
|
||||
/* Exit the full screen mode if it was already set */
|
||||
// LeaveFullScreen(GuiData);
|
||||
|
||||
/*
|
||||
* Window creation is done using a PostMessage(), so it's possible
|
||||
* that the window that we want to destroy doesn't exist yet.
|
||||
* So first empty the message queue.
|
||||
*/
|
||||
/*
|
||||
while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
|
||||
case PM_DESTROY_CONSOLE:
|
||||
{
|
||||
TranslateMessage(&Msg);
|
||||
DispatchMessageW(&Msg);
|
||||
}*/
|
||||
while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) ;
|
||||
PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)msg.lParam;
|
||||
MSG TempMsg;
|
||||
|
||||
if (GuiData->hWindow != NULL) /* && DestroyWindow(GuiData->hWindow) */
|
||||
{
|
||||
DestroyWindow(GuiData->hWindow);
|
||||
/* Exit the full screen mode if it was already set */
|
||||
// LeaveFullScreen(GuiData);
|
||||
|
||||
WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
|
||||
WindowCount--;
|
||||
SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
|
||||
if (0 == WindowCount)
|
||||
/*
|
||||
* Window creation is done using a PostMessage(), so it's possible
|
||||
* that the window that we want to destroy doesn't exist yet.
|
||||
* So first empty the message queue.
|
||||
*/
|
||||
/*
|
||||
while (PeekMessageW(&TempMsg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
NotifyWnd = NULL;
|
||||
DestroyWindow(hWnd);
|
||||
DPRINT("CONSRV: Going to quit the Gui Thread!!\n");
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
}
|
||||
TranslateMessage(&TempMsg);
|
||||
DispatchMessageW(&TempMsg);
|
||||
}*/
|
||||
while (PeekMessageW(&TempMsg, NULL, 0, 0, PM_REMOVE)) ;
|
||||
|
||||
return 0;
|
||||
if (GuiData->hWindow == NULL) continue;
|
||||
|
||||
DestroyWindow(GuiData->hWindow);
|
||||
PrivateCsrssManualGuiCheck(+1); // RemoveGuiApp
|
||||
|
||||
SetEvent(GuiData->hGuiTermEvent);
|
||||
|
||||
if (InterlockedDecrement(&WindowCount) == 0)
|
||||
{
|
||||
DPRINT("CONSRV: Going to quit the Input Thread!!\n");
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD NTAPI
|
||||
GuiConsoleGuiThread(PVOID Data)
|
||||
{
|
||||
MSG msg;
|
||||
PHANDLE GraphicsStartupEvent = (PHANDLE)Data;
|
||||
|
||||
/*
|
||||
* This thread dispatches all the console notifications to the notify window.
|
||||
* It is common for all the console windows.
|
||||
*/
|
||||
|
||||
PrivateCsrssManualGuiCheck(+1);
|
||||
|
||||
NotifyWnd = CreateWindowW(L"ConSrvCreateNotify",
|
||||
L"",
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
NULL,
|
||||
NULL,
|
||||
ConSrvDllInstance,
|
||||
NULL);
|
||||
if (NULL == NotifyWnd)
|
||||
{
|
||||
PrivateCsrssManualGuiCheck(-1);
|
||||
SetEvent(*GraphicsStartupEvent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
SetEvent(*GraphicsStartupEvent);
|
||||
|
||||
while (GetMessageW(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
DPRINT("CONSRV: Quit the Gui Thread!!\n");
|
||||
PrivateCsrssManualGuiCheck(-1);
|
||||
Quit:
|
||||
DPRINT("CONSRV: Quit the Input Thread!!\n");
|
||||
|
||||
hInputThread = NULL;
|
||||
dwInputThreadId = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -308,76 +278,43 @@ GuiConsoleGuiThread(PVOID Data)
|
|||
static BOOL
|
||||
GuiInit(VOID)
|
||||
{
|
||||
WNDCLASSEXW wc;
|
||||
|
||||
/* Exit if we were already initialized */
|
||||
// if (ConsInitialized) return TRUE;
|
||||
|
||||
/*
|
||||
* Initialize and register the different window classes, if needed.
|
||||
* Initialize and register the console window class, if needed.
|
||||
*/
|
||||
if (!ConsInitialized)
|
||||
{
|
||||
/* Initialize the notification window class */
|
||||
wc.cbSize = sizeof(WNDCLASSEXW);
|
||||
wc.lpszClassName = L"ConSrvCreateNotify";
|
||||
wc.lpfnWndProc = GuiConsoleNotifyWndProc;
|
||||
wc.style = 0;
|
||||
wc.hInstance = ConSrvDllInstance;
|
||||
wc.hIcon = NULL;
|
||||
wc.hIconSm = NULL;
|
||||
wc.hCursor = NULL;
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
if (RegisterClassExW(&wc) == 0)
|
||||
{
|
||||
DPRINT1("Failed to register GUI notify wndproc\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize the console window class */
|
||||
if (!RegisterConWndClass(ConSrvDllInstance))
|
||||
return FALSE;
|
||||
|
||||
if (!RegisterConWndClass(ConSrvDllInstance)) return FALSE;
|
||||
ConsInitialized = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set-up the notification window
|
||||
* Set-up the console input thread
|
||||
*/
|
||||
if (NULL == NotifyWnd)
|
||||
if (hInputThread == NULL)
|
||||
{
|
||||
HANDLE ThreadHandle;
|
||||
HANDLE GraphicsStartupEvent;
|
||||
HANDLE GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (GraphicsStartupEvent == NULL) return FALSE;
|
||||
|
||||
GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (NULL == GraphicsStartupEvent) return FALSE;
|
||||
|
||||
ThreadHandle = CreateThread(NULL,
|
||||
hInputThread = CreateThread(NULL,
|
||||
0,
|
||||
GuiConsoleGuiThread,
|
||||
GuiConsoleInputThread,
|
||||
(PVOID)&GraphicsStartupEvent,
|
||||
0,
|
||||
NULL);
|
||||
if (NULL == ThreadHandle)
|
||||
&dwInputThreadId);
|
||||
if (hInputThread == NULL)
|
||||
{
|
||||
CloseHandle(GraphicsStartupEvent);
|
||||
DPRINT1("CONSRV: Failed to create graphics console thread. Expect problems\n");
|
||||
DPRINT1("CONSRV: Failed to create graphics console thread.\n");
|
||||
return FALSE;
|
||||
}
|
||||
SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
|
||||
CloseHandle(ThreadHandle);
|
||||
SetThreadPriority(hInputThread, THREAD_PRIORITY_HIGHEST);
|
||||
CloseHandle(hInputThread);
|
||||
|
||||
WaitForSingleObject(GraphicsStartupEvent, INFINITE);
|
||||
CloseHandle(GraphicsStartupEvent);
|
||||
|
||||
if (NULL == NotifyWnd)
|
||||
{
|
||||
DPRINT1("CONSRV: Failed to create notification window.\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// ConsInitialized = TRUE;
|
||||
|
@ -386,7 +323,6 @@ GuiInit(VOID)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GUI Console Driver *
|
||||
******************************************************************************/
|
||||
|
@ -405,9 +341,7 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
PGUI_CONSOLE_DATA GuiData;
|
||||
GUI_CONSOLE_INFO TermInfo;
|
||||
|
||||
SIZE_T Length = 0;
|
||||
LPWSTR IconPath = NULL;
|
||||
INT IconIndex = 0;
|
||||
SIZE_T Length = 0;
|
||||
|
||||
if (This == NULL || Console == NULL || This->OldData == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@ -422,10 +356,6 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
ConsoleInfo = GuiInitInfo->ConsoleInfo;
|
||||
ConsoleStartInfo = GuiInitInfo->ConsoleStartInfo;
|
||||
|
||||
IconPath = ConsoleStartInfo->IconPath;
|
||||
IconIndex = ConsoleStartInfo->IconIndex;
|
||||
|
||||
|
||||
/* Terminal data allocation */
|
||||
GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA));
|
||||
if (!GuiData)
|
||||
|
@ -451,10 +381,10 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
/* 1. Load the default settings */
|
||||
GuiConsoleGetDefaultSettings(&TermInfo, GuiInitInfo->ProcessId);
|
||||
|
||||
/* 3. Load the remaining console settings via the registry. */
|
||||
/* 3. Load the remaining console settings via the registry */
|
||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||
{
|
||||
/* Load the terminal infos from the registry. */
|
||||
/* Load the terminal infos from the registry */
|
||||
GuiConsoleReadUserSettings(&TermInfo,
|
||||
ConsoleInfo->ConsoleTitle,
|
||||
GuiInitInfo->ProcessId);
|
||||
|
@ -500,29 +430,17 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition;
|
||||
GuiData->GuiInfo.WindowOrigin = TermInfo.WindowOrigin;
|
||||
|
||||
/* Initialize the icon handles to their default values */
|
||||
GuiData->hIcon = ghDefaultIcon;
|
||||
GuiData->hIconSm = ghDefaultIconSm;
|
||||
/* Initialize the icon handles */
|
||||
if (ConsoleStartInfo->hIcon != NULL)
|
||||
GuiData->hIcon = ConsoleStartInfo->hIcon;
|
||||
else
|
||||
GuiData->hIcon = ghDefaultIcon;
|
||||
|
||||
if (ConsoleStartInfo->hIconSm != NULL)
|
||||
GuiData->hIconSm = ConsoleStartInfo->hIconSm;
|
||||
else
|
||||
GuiData->hIconSm = ghDefaultIconSm;
|
||||
|
||||
/* Get the associated icon, if any */
|
||||
if (IconPath == NULL || IconPath[0] == L'\0')
|
||||
{
|
||||
IconPath = ConsoleStartInfo->AppPath;
|
||||
IconIndex = 0;
|
||||
}
|
||||
DPRINT("IconPath = %S ; IconIndex = %lu\n", (IconPath ? IconPath : L"n/a"), IconIndex);
|
||||
if (IconPath && IconPath[0] != L'\0')
|
||||
{
|
||||
HICON hIcon = NULL, hIconSm = NULL;
|
||||
PrivateExtractIconExW(IconPath,
|
||||
IconIndex,
|
||||
&hIcon,
|
||||
&hIconSm,
|
||||
1);
|
||||
DPRINT("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
|
||||
if (hIcon != NULL) GuiData->hIcon = hIcon;
|
||||
if (hIconSm != NULL) GuiData->hIconSm = hIconSm;
|
||||
}
|
||||
ASSERT(GuiData->hIcon && GuiData->hIconSm);
|
||||
|
||||
/* Mouse is shown by default with its default cursor shape */
|
||||
|
@ -545,6 +463,11 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
GuiData->LineSelection = FALSE; // Default to block selection
|
||||
// TODO: Retrieve the selection mode via the registry.
|
||||
|
||||
/* Finally, finish to initialize the frontend structure */
|
||||
This->Data = GuiData;
|
||||
if (This->OldData) ConsoleFreeHeap(This->OldData);
|
||||
This->OldData = NULL;
|
||||
|
||||
/*
|
||||
* We need to wait until the GUI has been fully initialized
|
||||
* to retrieve custom settings i.e. WindowSize etc...
|
||||
|
@ -552,11 +475,12 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
* yet implemented.
|
||||
*/
|
||||
GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
GuiData->hGuiTermEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
DPRINT("GUI - Checkpoint\n");
|
||||
|
||||
/* Create the terminal window */
|
||||
PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, GuiData->GuiInfo.ShowWindow, (LPARAM)GuiData);
|
||||
PostThreadMessageW(dwInputThreadId, PM_CREATE_CONSOLE, 0, (LPARAM)GuiData);
|
||||
|
||||
/* Wait until initialization has finished */
|
||||
WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
|
||||
|
@ -572,11 +496,6 @@ GuiInitFrontEnd(IN OUT PFRONTEND This,
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Finally, finish to initialize the frontend structure */
|
||||
This->Data = GuiData;
|
||||
if (This->OldData) ConsoleFreeHeap(This->OldData);
|
||||
This->OldData = NULL;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -585,7 +504,12 @@ GuiDeinitFrontEnd(IN OUT PFRONTEND This)
|
|||
{
|
||||
PGUI_CONSOLE_DATA GuiData = This->Data;
|
||||
|
||||
SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM)GuiData);
|
||||
DPRINT("Send PM_DESTROY_CONSOLE message and wait on hGuiTermEvent...\n");
|
||||
PostThreadMessageW(dwInputThreadId, PM_DESTROY_CONSOLE, 0, (LPARAM)GuiData);
|
||||
WaitForSingleObject(GuiData->hGuiTermEvent, INFINITE);
|
||||
DPRINT("hGuiTermEvent set\n");
|
||||
CloseHandle(GuiData->hGuiTermEvent);
|
||||
GuiData->hGuiTermEvent = NULL;
|
||||
|
||||
DPRINT("Destroying icons !! - GuiData->hIcon = 0x%p ; ghDefaultIcon = 0x%p ; GuiData->hIconSm = 0x%p ; ghDefaultIconSm = 0x%p\n",
|
||||
GuiData->hIcon, ghDefaultIcon, GuiData->hIconSm, ghDefaultIconSm);
|
||||
|
@ -675,6 +599,15 @@ GuiWriteStream(IN OUT PFRONTEND This,
|
|||
SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
|
||||
}
|
||||
|
||||
/* static */ VOID NTAPI
|
||||
GuiRingBell(IN OUT PFRONTEND This)
|
||||
{
|
||||
PGUI_CONSOLE_DATA GuiData = This->Data;
|
||||
|
||||
/* Emit an error beep sound */
|
||||
SendNotifyMessage(GuiData->hWindow, PM_CONSOLE_BEEP, 0, 0);
|
||||
}
|
||||
|
||||
static BOOL NTAPI
|
||||
GuiSetCursorInfo(IN OUT PFRONTEND This,
|
||||
PCONSOLE_SCREEN_BUFFER Buff)
|
||||
|
@ -1083,6 +1016,7 @@ static FRONTEND_VTBL GuiVtbl =
|
|||
GuiDeinitFrontEnd,
|
||||
GuiDrawRegion,
|
||||
GuiWriteStream,
|
||||
GuiRingBell,
|
||||
GuiSetCursorInfo,
|
||||
GuiSetScreenInfo,
|
||||
GuiResizeTerminal,
|
||||
|
@ -1104,139 +1038,21 @@ static FRONTEND_VTBL GuiVtbl =
|
|||
};
|
||||
|
||||
|
||||
static BOOL
|
||||
LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
IN OUT PCONSOLE_INFO ConsoleInfo)
|
||||
{
|
||||
#define PATH_SEPARATOR L'\\'
|
||||
|
||||
BOOL RetVal = FALSE;
|
||||
HRESULT hRes = S_OK;
|
||||
LPWSTR LinkName = NULL;
|
||||
SIZE_T Length = 0;
|
||||
|
||||
if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
|
||||
return FALSE;
|
||||
|
||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
||||
ConsoleStartInfo->IconIndex = 0;
|
||||
|
||||
/* 1- Find the last path separator if any */
|
||||
LinkName = wcsrchr(ConsoleStartInfo->ConsoleTitle, PATH_SEPARATOR);
|
||||
if (LinkName == NULL)
|
||||
{
|
||||
LinkName = ConsoleStartInfo->ConsoleTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip the path separator */
|
||||
++LinkName;
|
||||
}
|
||||
|
||||
/* 2- Check for the link extension. The name ".lnk" is considered invalid. */
|
||||
Length = wcslen(LinkName);
|
||||
if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) )
|
||||
return FALSE;
|
||||
|
||||
/* 3- It may be a link. Try to retrieve some properties */
|
||||
hRes = CoInitialize(NULL);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/* Get a pointer to the IShellLink interface */
|
||||
IShellLinkW* pshl = NULL;
|
||||
hRes = CoCreateInstance(&CLSID_ShellLink,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLinkW,
|
||||
(LPVOID*)&pshl);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/* Get a pointer to the IPersistFile interface */
|
||||
IPersistFile* ppf = NULL;
|
||||
hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/* Load the shortcut */
|
||||
hRes = IPersistFile_Load(ppf, ConsoleStartInfo->ConsoleTitle, STGM_READ);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
/*
|
||||
* Finally we can get the properties !
|
||||
* Update the old ones if needed.
|
||||
*/
|
||||
INT ShowCmd = 0;
|
||||
// WORD HotKey = 0;
|
||||
|
||||
/* Reset the name of the console with the name of the shortcut */
|
||||
Length = min(/*Length*/ Length - 4, // 4 == len(".lnk")
|
||||
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)) ConsoleStartInfo->wShowWindow = (WORD)ShowCmd;
|
||||
|
||||
/* Get the hotkey */
|
||||
// hRes = pshl->GetHotkey(&ShowCmd);
|
||||
// if (SUCCEEDED(hRes)) ConsoleStartInfo->HotKey = HotKey;
|
||||
|
||||
/* Get the icon location, if any */
|
||||
|
||||
hRes = IShellLinkW_GetIconLocation(pshl,
|
||||
ConsoleStartInfo->IconPath,
|
||||
sizeof(ConsoleStartInfo->IconPath)/sizeof(ConsoleStartInfo->IconPath[0]) - 1, // == MAX_PATH
|
||||
&ConsoleStartInfo->IconIndex);
|
||||
if (!SUCCEEDED(hRes))
|
||||
{
|
||||
ConsoleStartInfo->IconPath[0] = L'\0';
|
||||
ConsoleStartInfo->IconIndex = 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);
|
||||
}
|
||||
IShellLinkW_Release(pshl);
|
||||
}
|
||||
}
|
||||
CoUninitialize();
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
||||
IN OUT PCONSOLE_INFO ConsoleInfo,
|
||||
IN OUT PVOID ExtraConsoleInfo,
|
||||
IN ULONG ProcessId)
|
||||
{
|
||||
PCONSOLE_START_INFO ConsoleStartInfo = ExtraConsoleInfo;
|
||||
PCONSOLE_INIT_INFO ConsoleInitInfo = ExtraConsoleInfo;
|
||||
PGUI_INIT_INFO GuiInitInfo;
|
||||
|
||||
if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleStartInfo == NULL)
|
||||
if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleInitInfo == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Initialize GUI terminal emulator common functionalities */
|
||||
if (!GuiInit()) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/*
|
||||
* Load per-application terminal settings.
|
||||
*
|
||||
* Check whether the process creating the console was launched via
|
||||
* a shell-link. ConsoleInfo->ConsoleTitle may be updated with the
|
||||
* name of the shortcut, and ConsoleStartInfo->Icon[Path|Index] too.
|
||||
*/
|
||||
if (ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME)
|
||||
{
|
||||
if (!LoadShellLinkConsoleInfo(ConsoleStartInfo, ConsoleInfo))
|
||||
{
|
||||
ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a private initialization info structure for later use.
|
||||
* It must be freed by a call to GuiUnloadFrontEnd or GuiInitFrontEnd.
|
||||
|
@ -1245,8 +1061,9 @@ GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
|
|||
if (GuiInitInfo == NULL) return STATUS_NO_MEMORY;
|
||||
|
||||
// HACK: We suppose that the pointers will be valid in GuiInitFrontEnd...
|
||||
// If not, then copy exactly what we need in GuiInitInfo.
|
||||
GuiInitInfo->ConsoleInfo = ConsoleInfo;
|
||||
GuiInitInfo->ConsoleStartInfo = ConsoleStartInfo;
|
||||
GuiInitInfo->ConsoleStartInfo = ConsoleInitInfo->ConsoleStartInfo;
|
||||
GuiInitInfo->ProcessId = ProcessId;
|
||||
|
||||
/* Finally, initialize the frontend structure */
|
||||
|
|
|
@ -14,13 +14,6 @@
|
|||
#include "guisettings.h"
|
||||
#include "conwnd.h"
|
||||
|
||||
NTSTATUS GuiInitConsole(PCONSOLE Console,
|
||||
/*IN*/ PCONSOLE_START_INFO ConsoleStartInfo,
|
||||
PCONSOLE_INFO ConsoleInfo,
|
||||
DWORD ProcessId,
|
||||
LPCWSTR IconPath,
|
||||
INT IconIndex);
|
||||
|
||||
VOID
|
||||
GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
|
||||
|
||||
|
|
|
@ -2,15 +2,15 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_EDIT "Edit"
|
||||
IDS_EDIT "&Edit"
|
||||
IDS_MARK "Mark"
|
||||
IDS_COPY "Copy\tEnter"
|
||||
IDS_PASTE "Paste"
|
||||
IDS_SELECTALL "Select All"
|
||||
IDS_SCROLL "Scroll"
|
||||
IDS_FIND "Find..."
|
||||
IDS_DEFAULTS "Defaults"
|
||||
IDS_PROPERTIES "Properties"
|
||||
IDS_DEFAULTS "&Defaults"
|
||||
IDS_PROPERTIES "&Properties"
|
||||
/*
|
||||
IDS_SCROLLHERE "Scroll here"
|
||||
IDS_SCROLLTOP "Scroll top"
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
|
||||
|
||||
/* Fixme : Translation could be really improved, with context
|
||||
La traduction pourrait réellement être améliorée grâce au contexte */
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_EDIT "Éditer"
|
||||
IDS_MARK "Marquer"
|
||||
IDS_COPY "Copier\tEntrée"
|
||||
IDS_PASTE "Coller"
|
||||
IDS_SELECTALL "Tout sélectionner"
|
||||
IDS_SCROLL "Défiler"
|
||||
IDS_FIND "Trouver..."
|
||||
IDS_DEFAULTS "Défauts"
|
||||
IDS_PROPERTIES "Propriétés"
|
||||
IDS_EDIT "Éd&ition"
|
||||
IDS_MARK "&Marquer"
|
||||
IDS_COPY "&Copier\tEntrée"
|
||||
IDS_PASTE "C&oller"
|
||||
IDS_SELECTALL "Sélectionner &tout"
|
||||
IDS_SCROLL "&Défiler"
|
||||
IDS_FIND "&Rechercher..."
|
||||
IDS_DEFAULTS "&Défauts"
|
||||
IDS_PROPERTIES "&Propriétés"
|
||||
/*
|
||||
IDS_SCROLLHERE "Défiler ici"
|
||||
IDS_SCROLLTOP "Défiler tout en haut"
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "consrv.h"
|
||||
#include "include/conio.h"
|
||||
#include "include/term.h"
|
||||
#include "coninput.h"
|
||||
|
||||
|
@ -20,77 +19,6 @@
|
|||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static VOID
|
||||
ConDrvProcessKey(IN PCONSOLE Console,
|
||||
IN BOOLEAN Down,
|
||||
IN UINT VirtualKeyCode,
|
||||
IN UINT VirtualScanCode,
|
||||
IN WCHAR UnicodeChar,
|
||||
IN ULONG ShiftState,
|
||||
IN BYTE KeyStateCtrl)
|
||||
{
|
||||
INPUT_RECORD er;
|
||||
|
||||
/* process Ctrl-C and Ctrl-Break */
|
||||
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
||||
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
|
||||
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) )
|
||||
{
|
||||
DPRINT1("Console_Api Ctrl-C\n");
|
||||
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
|
||||
|
||||
if (Console->LineBuffer && !Console->LineComplete)
|
||||
{
|
||||
/* Line input is in progress; end it */
|
||||
Console->LinePos = Console->LineSize = 0;
|
||||
Console->LineComplete = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
|
||||
(VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) )
|
||||
{
|
||||
if (!Down) return;
|
||||
|
||||
/* scroll up or down */
|
||||
if (VK_UP == VirtualKeyCode)
|
||||
{
|
||||
/* only scroll up if there is room to scroll up into */
|
||||
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
|
||||
{
|
||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
||||
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->CursorPosition.Y != 0)
|
||||
{
|
||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
|
||||
Console->ActiveBuffer->ScreenBufferSize.Y;
|
||||
Console->ActiveBuffer->CursorPosition.Y--;
|
||||
}
|
||||
}
|
||||
|
||||
ConioDrawConsole(Console);
|
||||
return;
|
||||
}
|
||||
|
||||
er.EventType = KEY_EVENT;
|
||||
er.Event.KeyEvent.bKeyDown = Down;
|
||||
er.Event.KeyEvent.wRepeatCount = 1;
|
||||
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
|
||||
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
|
||||
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
|
||||
er.Event.KeyEvent.dwControlKeyState = ShiftState;
|
||||
|
||||
ConioProcessInputEvent(Console, &er);
|
||||
}
|
||||
|
||||
static DWORD
|
||||
ConioGetShiftState(PBYTE KeyState, LPARAM lParam)
|
||||
{
|
||||
|
@ -138,8 +66,10 @@ ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
|
|||
UINT VirtualKeyCode;
|
||||
UINT VirtualScanCode;
|
||||
BOOL Down = FALSE;
|
||||
BOOLEAN Fake; // synthesized, not a real event
|
||||
BOOLEAN NotChar; // message should not be used to return a character
|
||||
BOOLEAN Fake; // Synthesized, not a real event
|
||||
BOOLEAN NotChar; // Message should not be used to return a character
|
||||
|
||||
INPUT_RECORD er;
|
||||
|
||||
if (NULL == Console)
|
||||
{
|
||||
|
@ -172,7 +102,7 @@ ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
|
|||
2,
|
||||
0,
|
||||
NULL);
|
||||
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
|
||||
UnicodeChar = (RetChars == 1 ? Chars[0] : 0);
|
||||
}
|
||||
|
||||
Fake = UnicodeChar &&
|
||||
|
@ -194,14 +124,66 @@ ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg)
|
|||
|
||||
if (Fake) return;
|
||||
|
||||
/* Process Ctrl-C and Ctrl-Break */
|
||||
if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
||||
Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') &&
|
||||
(ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80) )
|
||||
{
|
||||
DPRINT1("Console_Api Ctrl-C\n");
|
||||
ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT);
|
||||
|
||||
if (Console->LineBuffer && !Console->LineComplete)
|
||||
{
|
||||
/* Line input is in progress; end it */
|
||||
Console->LinePos = Console->LineSize = 0;
|
||||
Console->LineComplete = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 &&
|
||||
(VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) )
|
||||
{
|
||||
if (!Down) return;
|
||||
|
||||
/* Scroll up or down */
|
||||
if (VirtualKeyCode == VK_UP)
|
||||
{
|
||||
/* Only scroll up if there is room to scroll up into */
|
||||
if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1)
|
||||
{
|
||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
|
||||
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->CursorPosition.Y != 0)
|
||||
{
|
||||
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
|
||||
Console->ActiveBuffer->ScreenBufferSize.Y;
|
||||
Console->ActiveBuffer->CursorPosition.Y--;
|
||||
}
|
||||
}
|
||||
|
||||
ConioDrawConsole((PCONSOLE)Console);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send the key press to the console driver */
|
||||
ConDrvProcessKey(Console,
|
||||
Down,
|
||||
VirtualKeyCode,
|
||||
VirtualScanCode,
|
||||
UnicodeChar,
|
||||
ShiftState,
|
||||
KeyState[VK_CONTROL]);
|
||||
|
||||
er.EventType = KEY_EVENT;
|
||||
er.Event.KeyEvent.bKeyDown = Down;
|
||||
er.Event.KeyEvent.wRepeatCount = 1;
|
||||
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
|
||||
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
|
||||
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
|
||||
er.Event.KeyEvent.dwControlKeyState = ShiftState;
|
||||
|
||||
ConioProcessInputEvent(Console, &er);
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
|
|
@ -18,6 +18,76 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/********** HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK ************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/*
|
||||
* From MSDN:
|
||||
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||
* If they are the same, the function fails, and GetLastError returns
|
||||
* ERROR_INVALID_PARAMETER."
|
||||
*/
|
||||
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
||||
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||
WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
||||
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
|
||||
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||
MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||
|
||||
typedef struct ConsoleInput_t
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
INPUT_RECORD InputEvent;
|
||||
} ConsoleInput;
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
static VOID
|
||||
ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||
{
|
||||
if (InputEvent->EventType == KEY_EVENT)
|
||||
{
|
||||
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
|
||||
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
|
||||
ConsoleInputUnicodeCharToAnsiChar(Console,
|
||||
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
|
||||
&UnicodeChar);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
|
||||
{
|
||||
if (InputEvent->EventType == KEY_EVENT)
|
||||
{
|
||||
CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
|
||||
InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
|
||||
ConsoleInputAnsiCharToUnicodeChar(Console,
|
||||
&InputEvent->Event.KeyEvent.uChar.UnicodeChar,
|
||||
&AsciiChar);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/********** HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK ************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* CONSRV TERMINAL FRONTENDS INTERFACE ****************************************/
|
||||
|
||||
/***************/
|
||||
|
@ -67,7 +137,7 @@ NTSTATUS (NTAPI *FRONTEND_UNLOAD)(IN OUT PFRONTEND FrontEnd);
|
|||
* NOTE: Each entry of the table should be retrieved when loading a front-end
|
||||
* (examples of the CSR servers which register some data for CSRSS).
|
||||
*/
|
||||
struct
|
||||
static struct
|
||||
{
|
||||
CHAR FrontEndName[80];
|
||||
FRONTEND_LOAD FrontEndLoad;
|
||||
|
@ -190,7 +260,7 @@ ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal)
|
|||
|
||||
static NTSTATUS NTAPI
|
||||
ConSrvTermInitTerminal(IN OUT PTERMINAL This,
|
||||
IN PCONSOLE Console)
|
||||
IN PCONSOLE Console)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
|
@ -203,6 +273,8 @@ ConSrvTermInitTerminal(IN OUT PTERMINAL This,
|
|||
Console->FrontEndIFace = *FrontEnd;
|
||||
|
||||
Status = FrontEnd->Vtbl->InitFrontEnd(FrontEnd, FrontEnd->Console);
|
||||
if (!NT_SUCCESS(Status))
|
||||
DPRINT1("InitFrontEnd failed, Status = 0x%08lx\n", Status);
|
||||
|
||||
/** HACK HACK!! Be sure FrontEndIFace is correctly updated in the console!! **/
|
||||
DPRINT1("Using FrontEndIFace HACK(2), should be removed after proper implementation!\n");
|
||||
|
@ -218,6 +290,364 @@ ConSrvTermDeinitTerminal(IN OUT PTERMINAL This)
|
|||
FrontEnd->Vtbl->DeinitFrontEnd(FrontEnd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************ Line discipline ***************/
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
ConSrvTermReadStream(IN OUT PTERMINAL This,
|
||||
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
|
||||
IN BOOLEAN Unicode,
|
||||
/**PWCHAR Buffer,**/
|
||||
OUT PVOID Buffer,
|
||||
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
|
||||
IN ULONG NumCharsToRead,
|
||||
OUT PULONG NumCharsRead OPTIONAL)
|
||||
{
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
PCONSRV_CONSOLE Console = FrontEnd->Console;
|
||||
PCONSOLE_INPUT_BUFFER InputBuffer = &Console->InputBuffer;
|
||||
|
||||
// STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
|
||||
NTSTATUS Status = STATUS_PENDING;
|
||||
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
ConsoleInput *Input;
|
||||
ULONG i;
|
||||
|
||||
/* Validity checks */
|
||||
// ASSERT(Console == InputBuffer->Header.Console);
|
||||
ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
|
||||
|
||||
/* We haven't read anything (yet) */
|
||||
i = ReadControl->nInitialChars;
|
||||
|
||||
if (InputBuffer->Mode & ENABLE_LINE_INPUT)
|
||||
{
|
||||
/* COOKED mode, call the line discipline */
|
||||
|
||||
if (Console->LineBuffer == NULL)
|
||||
{
|
||||
/* Starting a new line */
|
||||
Console->LineMaxSize = max(256, NumCharsToRead);
|
||||
|
||||
Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
|
||||
if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
|
||||
|
||||
Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
|
||||
Console->LineComplete = Console->LineUpPressed = FALSE;
|
||||
Console->LineInsertToggle = Console->InsertMode;
|
||||
Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
|
||||
|
||||
/*
|
||||
* Pre-filling the buffer is only allowed in the Unicode API,
|
||||
* so we don't need to worry about ANSI <-> Unicode conversion.
|
||||
*/
|
||||
memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
|
||||
if (Console->LineSize == Console->LineMaxSize)
|
||||
{
|
||||
Console->LineComplete = TRUE;
|
||||
Console->LinePos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have a complete line yet, process the pending input */
|
||||
while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
/* Remove input event from queue */
|
||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
ResetEvent(InputBuffer->ActiveEvent);
|
||||
}
|
||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||
|
||||
/* Only pay attention to key down */
|
||||
if (Input->InputEvent.EventType == KEY_EVENT &&
|
||||
Input->InputEvent.Event.KeyEvent.bKeyDown)
|
||||
{
|
||||
LineInputKeyDown(Console, ExeName,
|
||||
&Input->InputEvent.Event.KeyEvent);
|
||||
ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
|
||||
}
|
||||
ConsoleFreeHeap(Input);
|
||||
}
|
||||
|
||||
/* Check if we have a complete line to read from */
|
||||
if (Console->LineComplete)
|
||||
{
|
||||
while (i < NumCharsToRead && Console->LinePos != Console->LineSize)
|
||||
{
|
||||
WCHAR Char = Console->LineBuffer[Console->LinePos++];
|
||||
|
||||
if (Unicode)
|
||||
{
|
||||
((PWCHAR)Buffer)[i] = Char;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (Console->LinePos == Console->LineSize)
|
||||
{
|
||||
/* Entire line has been read */
|
||||
ConsoleFreeHeap(Console->LineBuffer);
|
||||
Console->LineBuffer = NULL;
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RAW mode */
|
||||
|
||||
/* Character input */
|
||||
while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
/* Remove input event from queue */
|
||||
CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
|
||||
if (IsListEmpty(&InputBuffer->InputEvents))
|
||||
{
|
||||
ResetEvent(InputBuffer->ActiveEvent);
|
||||
}
|
||||
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
|
||||
|
||||
/* Only pay attention to valid characters, on key down */
|
||||
if (Input->InputEvent.EventType == KEY_EVENT &&
|
||||
Input->InputEvent.Event.KeyEvent.bKeyDown &&
|
||||
Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
|
||||
{
|
||||
WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
|
||||
|
||||
if (Unicode)
|
||||
{
|
||||
((PWCHAR)Buffer)[i] = Char;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char);
|
||||
}
|
||||
++i;
|
||||
|
||||
/* Did read something */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
ConsoleFreeHeap(Input);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Only set if Status == STATUS_SUCCESS ???
|
||||
if (NumCharsRead) *NumCharsRead = i;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
|
||||
// See condrv/text.c
|
||||
/*static*/ VOID
|
||||
ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff);
|
||||
|
||||
static VOID
|
||||
ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
|
||||
{
|
||||
/* If we hit bottom, slide the viewable screen */
|
||||
if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
|
||||
{
|
||||
Buff->CursorPosition.Y--;
|
||||
if (++Buff->VirtualY == Buff->ScreenBufferSize.Y)
|
||||
{
|
||||
Buff->VirtualY = 0;
|
||||
}
|
||||
(*ScrolledLines)++;
|
||||
ClearLineBuffer(Buff);
|
||||
if (UpdateRect->Top != 0)
|
||||
{
|
||||
UpdateRect->Top--;
|
||||
}
|
||||
}
|
||||
UpdateRect->Left = 0;
|
||||
UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
|
||||
UpdateRect->Bottom = Buff->CursorPosition.Y;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
ConioWriteConsole(PFRONTEND FrontEnd,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib)
|
||||
{
|
||||
PCONSRV_CONSOLE Console = FrontEnd->Console;
|
||||
|
||||
UINT i;
|
||||
PCHAR_INFO Ptr;
|
||||
SMALL_RECT UpdateRect;
|
||||
SHORT CursorStartX, CursorStartY;
|
||||
UINT ScrolledLines;
|
||||
|
||||
CursorStartX = Buff->CursorPosition.X;
|
||||
CursorStartY = Buff->CursorPosition.Y;
|
||||
UpdateRect.Left = Buff->ScreenBufferSize.X;
|
||||
UpdateRect.Top = Buff->CursorPosition.Y;
|
||||
UpdateRect.Right = -1;
|
||||
UpdateRect.Bottom = Buff->CursorPosition.Y;
|
||||
ScrolledLines = 0;
|
||||
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
/*
|
||||
* If we are in processed mode, interpret special characters and
|
||||
* display them correctly. Otherwise, just put them into the buffer.
|
||||
*/
|
||||
if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
|
||||
{
|
||||
/* --- CR --- */
|
||||
if (Buffer[i] == L'\r')
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||
continue;
|
||||
}
|
||||
/* --- LF --- */
|
||||
else if (Buffer[i] == L'\n')
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||
continue;
|
||||
}
|
||||
/* --- BS --- */
|
||||
else if (Buffer[i] == L'\b')
|
||||
{
|
||||
/* Only handle BS if we're not on the first pos of the first line */
|
||||
if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
|
||||
{
|
||||
if (0 == Buff->CursorPosition.X)
|
||||
{
|
||||
/* slide virtual position up */
|
||||
Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1;
|
||||
Buff->CursorPosition.Y--;
|
||||
UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buff->CursorPosition.X--;
|
||||
}
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
Ptr->Char.UnicodeChar = L' ';
|
||||
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* --- TAB --- */
|
||||
else if (Buffer[i] == L'\t')
|
||||
{
|
||||
UINT EndX;
|
||||
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1);
|
||||
EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X);
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
while (Buff->CursorPosition.X < EndX)
|
||||
{
|
||||
Ptr->Char.UnicodeChar = L' ';
|
||||
Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||
++Ptr;
|
||||
Buff->CursorPosition.X++;
|
||||
}
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
|
||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
||||
{
|
||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buff->CursorPosition.X--;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* --- BEL ---*/
|
||||
else if (Buffer[i] == L'\a')
|
||||
{
|
||||
FrontEnd->Vtbl->RingBell(FrontEnd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
|
||||
UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
|
||||
|
||||
Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
|
||||
Ptr->Char.UnicodeChar = Buffer[i];
|
||||
if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib;
|
||||
|
||||
Buff->CursorPosition.X++;
|
||||
if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
|
||||
{
|
||||
if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
|
||||
{
|
||||
Buff->CursorPosition.X = 0;
|
||||
ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buff->CursorPosition.X = CursorStartX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
|
||||
{
|
||||
// TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY,
|
||||
// ScrolledLines, Buffer, Length);
|
||||
FrontEnd->Vtbl->WriteStream(FrontEnd,
|
||||
&UpdateRect,
|
||||
CursorStartX,
|
||||
CursorStartY,
|
||||
ScrolledLines,
|
||||
Buffer,
|
||||
Length);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
ConSrvTermWriteStream(IN OUT PTERMINAL This,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib)
|
||||
{
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
return ConioWriteConsole(FrontEnd,
|
||||
Buff,
|
||||
Buffer,
|
||||
Length,
|
||||
Attrib);
|
||||
}
|
||||
|
||||
/************ Line discipline ***************/
|
||||
|
||||
|
||||
|
||||
static VOID NTAPI
|
||||
ConSrvTermDrawRegion(IN OUT PTERMINAL This,
|
||||
SMALL_RECT* Region)
|
||||
|
@ -226,25 +656,6 @@ ConSrvTermDrawRegion(IN OUT PTERMINAL This,
|
|||
FrontEnd->Vtbl->DrawRegion(FrontEnd, Region);
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
ConSrvTermWriteStream(IN OUT PTERMINAL This,
|
||||
SMALL_RECT* Region,
|
||||
SHORT CursorStartX,
|
||||
SHORT CursorStartY,
|
||||
UINT ScrolledLines,
|
||||
PWCHAR Buffer,
|
||||
UINT Length)
|
||||
{
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
FrontEnd->Vtbl->WriteStream(FrontEnd,
|
||||
Region,
|
||||
CursorStartX,
|
||||
CursorStartY,
|
||||
ScrolledLines,
|
||||
Buffer,
|
||||
Length);
|
||||
}
|
||||
|
||||
static BOOL NTAPI
|
||||
ConSrvTermSetCursorInfo(IN OUT PTERMINAL This,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer)
|
||||
|
@ -288,13 +699,6 @@ ConSrvTermReleaseScreenBuffer(IN OUT PTERMINAL This,
|
|||
FrontEnd->Vtbl->ReleaseScreenBuffer(FrontEnd, ScreenBuffer);
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
ConSrvTermChangeTitle(IN OUT PTERMINAL This)
|
||||
{
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
FrontEnd->Vtbl->ChangeTitle(FrontEnd);
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
||||
PCOORD pSize)
|
||||
|
@ -303,16 +707,6 @@ ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This,
|
|||
FrontEnd->Vtbl->GetLargestConsoleWindowSize(FrontEnd, pSize);
|
||||
}
|
||||
|
||||
/*
|
||||
static BOOL NTAPI
|
||||
ConSrvTermGetSelectionInfo(IN OUT PTERMINAL This,
|
||||
PCONSOLE_SELECTION_INFO pSelectionInfo)
|
||||
{
|
||||
PFRONTEND FrontEnd = This->Data;
|
||||
return FrontEnd->Vtbl->GetSelectionInfo(FrontEnd, pSelectionInfo);
|
||||
}
|
||||
*/
|
||||
|
||||
static BOOL NTAPI
|
||||
ConSrvTermSetPalette(IN OUT PTERMINAL This,
|
||||
HPALETTE PaletteHandle,
|
||||
|
@ -334,16 +728,17 @@ static TERMINAL_VTBL ConSrvTermVtbl =
|
|||
{
|
||||
ConSrvTermInitTerminal,
|
||||
ConSrvTermDeinitTerminal,
|
||||
ConSrvTermDrawRegion,
|
||||
|
||||
ConSrvTermReadStream,
|
||||
ConSrvTermWriteStream,
|
||||
|
||||
ConSrvTermDrawRegion,
|
||||
ConSrvTermSetCursorInfo,
|
||||
ConSrvTermSetScreenInfo,
|
||||
ConSrvTermResizeTerminal,
|
||||
ConSrvTermSetActiveScreenBuffer,
|
||||
ConSrvTermReleaseScreenBuffer,
|
||||
ConSrvTermChangeTitle,
|
||||
ConSrvTermGetLargestConsoleWindowSize,
|
||||
// ConSrvTermGetSelectionInfo,
|
||||
ConSrvTermSetPalette,
|
||||
ConSrvTermShowMouseCursor,
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifdef TUITERM_COMPILE
|
||||
|
||||
#include "consrv.h"
|
||||
#include "include/conio.h"
|
||||
// #include "include/conio.h"
|
||||
#include "include/console.h"
|
||||
#include "include/settings.h"
|
||||
#include "tuiterm.h"
|
||||
|
|
|
@ -96,7 +96,7 @@ ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle)
|
|||
* even of the last buffer, but having to deal with a lack of
|
||||
* any active buffer might be error-prone. */
|
||||
if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
|
||||
ConioDeleteScreenBuffer(Buffer);
|
||||
ConDrvDeleteScreenBuffer(Buffer);
|
||||
}
|
||||
else if (Object->Type == INPUT_BUFFER)
|
||||
{
|
||||
|
@ -470,15 +470,12 @@ ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object,
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle,
|
||||
PCONSOLE_START_INFO ConsoleStartInfo)
|
||||
PCONSOLE_INIT_INFO ConsoleInitInfo)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
HANDLE ConsoleHandle;
|
||||
|
@ -499,7 +496,7 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
/* Initialize a new Console owned by this process */
|
||||
Status = ConSrvInitConsole(&ConsoleHandle,
|
||||
&Console,
|
||||
ConsoleStartInfo,
|
||||
ConsoleInitInfo,
|
||||
HandleToUlong(ProcessData->Process->ClientId.UniqueProcess));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
603
reactos/win32ss/user/winsrv/consrv/history.c
Normal file
603
reactos/win32ss/user/winsrv/consrv/history.c
Normal file
|
@ -0,0 +1,603 @@
|
|||
/*
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Server DLL
|
||||
* FILE: win32ss/user/winsrv/consrv/history.c
|
||||
* PURPOSE: Console line input functions
|
||||
* PROGRAMMERS: Jeffrey Morlan
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "consrv.h"
|
||||
#include "popup.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct _HISTORY_BUFFER
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG Position;
|
||||
ULONG MaxEntries;
|
||||
ULONG NumEntries;
|
||||
UNICODE_STRING ExeName;
|
||||
PUNICODE_STRING Entries;
|
||||
} HISTORY_BUFFER, *PHISTORY_BUFFER;
|
||||
|
||||
|
||||
BOOLEAN
|
||||
ConvertInputAnsiToUnicode(PCONSRV_CONSOLE Console,
|
||||
PVOID Source,
|
||||
USHORT SourceLength,
|
||||
// BOOLEAN IsUnicode,
|
||||
PWCHAR* Target,
|
||||
PUSHORT TargetLength);
|
||||
BOOLEAN
|
||||
ConvertInputUnicodeToAnsi(PCONSRV_CONSOLE Console,
|
||||
PVOID Source,
|
||||
USHORT SourceLength,
|
||||
// BOOLEAN IsAnsi,
|
||||
PCHAR/* * */ Target,
|
||||
/*P*/USHORT TargetLength);
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static PHISTORY_BUFFER
|
||||
HistoryCurrentBuffer(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName)
|
||||
{
|
||||
PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
|
||||
{
|
||||
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
|
||||
if (RtlEqualUnicodeString(ExeName, &Hist->ExeName, FALSE))
|
||||
return Hist;
|
||||
}
|
||||
|
||||
/* Couldn't find the buffer, create a new one */
|
||||
Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName->Length);
|
||||
if (!Hist) return NULL;
|
||||
Hist->MaxEntries = Console->HistoryBufferSize;
|
||||
Hist->NumEntries = 0;
|
||||
Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries * sizeof(UNICODE_STRING));
|
||||
if (!Hist->Entries)
|
||||
{
|
||||
ConsoleFreeHeap(Hist);
|
||||
return NULL;
|
||||
}
|
||||
Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName->Length;
|
||||
Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
|
||||
memcpy(Hist->ExeName.Buffer, ExeName->Buffer, ExeName->Length);
|
||||
InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
|
||||
return Hist;
|
||||
}
|
||||
|
||||
static PHISTORY_BUFFER
|
||||
HistoryFindBuffer(PCONSRV_CONSOLE Console,
|
||||
PVOID ExeName,
|
||||
USHORT ExeLength,
|
||||
BOOLEAN UnicodeExe)
|
||||
{
|
||||
UNICODE_STRING ExeNameU;
|
||||
|
||||
PLIST_ENTRY Entry;
|
||||
PHISTORY_BUFFER Hist = NULL;
|
||||
|
||||
if (ExeName == NULL) return NULL;
|
||||
|
||||
if (UnicodeExe)
|
||||
{
|
||||
ExeNameU.Buffer = ExeName;
|
||||
/* Length is in bytes */
|
||||
ExeNameU.MaximumLength = ExeLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ConvertInputAnsiToUnicode(Console,
|
||||
ExeName, ExeLength,
|
||||
&ExeNameU.Buffer, &ExeNameU.MaximumLength))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ExeNameU.Length = ExeNameU.MaximumLength;
|
||||
|
||||
Entry = Console->HistoryBuffers.Flink;
|
||||
while (Entry != &Console->HistoryBuffers)
|
||||
{
|
||||
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
|
||||
|
||||
/* For the history APIs, the caller is allowed to give only part of the name */
|
||||
if (RtlPrefixUnicodeString(&ExeNameU, &Hist->ExeName, TRUE))
|
||||
{
|
||||
if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
|
||||
return Hist;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static VOID
|
||||
HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
|
||||
{
|
||||
if (!Hist) return;
|
||||
|
||||
while (Hist->NumEntries != 0)
|
||||
RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
|
||||
|
||||
ConsoleFreeHeap(Hist->Entries);
|
||||
RemoveEntryList(&Hist->ListEntry);
|
||||
ConsoleFreeHeap(Hist);
|
||||
}
|
||||
|
||||
VOID
|
||||
HistoryAddEntry(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
PUNICODE_STRING Entry)
|
||||
{
|
||||
// UNICODE_STRING NewEntry;
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
|
||||
if (!Hist) return;
|
||||
|
||||
// NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
|
||||
// NewEntry.Buffer = Console->LineBuffer;
|
||||
|
||||
/* Don't add blank or duplicate entries */
|
||||
if (Entry->Length == 0 || Hist->MaxEntries == 0 ||
|
||||
(Hist->NumEntries > 0 &&
|
||||
RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], Entry, FALSE)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Console->HistoryNoDup)
|
||||
{
|
||||
INT i;
|
||||
|
||||
/* Check if this line has been entered before */
|
||||
for (i = Hist->NumEntries - 1; i >= 0; i--)
|
||||
{
|
||||
if (RtlEqualUnicodeString(&Hist->Entries[i], Entry, FALSE))
|
||||
{
|
||||
UNICODE_STRING NewEntry;
|
||||
|
||||
/* Just rotate the list to bring this entry to the end */
|
||||
NewEntry = Hist->Entries[i];
|
||||
memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
|
||||
(Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
|
||||
Hist->Entries[Hist->NumEntries - 1] = NewEntry;
|
||||
Hist->Position = Hist->NumEntries - 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Hist->NumEntries == Hist->MaxEntries)
|
||||
{
|
||||
/* List is full, remove oldest entry */
|
||||
RtlFreeUnicodeString(&Hist->Entries[0]);
|
||||
memmove(&Hist->Entries[0], &Hist->Entries[1],
|
||||
--Hist->NumEntries * sizeof(UNICODE_STRING));
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(RtlDuplicateUnicodeString(0, Entry, &Hist->Entries[Hist->NumEntries])))
|
||||
Hist->NumEntries++;
|
||||
Hist->Position = Hist->NumEntries - 1;
|
||||
}
|
||||
|
||||
VOID
|
||||
HistoryGetCurrentEntry(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
PUNICODE_STRING Entry)
|
||||
{
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
|
||||
if (!Hist || Hist->NumEntries == 0)
|
||||
Entry->Length = 0;
|
||||
else
|
||||
*Entry = Hist->Entries[Hist->Position];
|
||||
}
|
||||
|
||||
BOOL
|
||||
HistoryRecallHistory(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
INT Offset,
|
||||
PUNICODE_STRING Entry)
|
||||
{
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
ULONG Position = 0;
|
||||
|
||||
if (!Hist || Hist->NumEntries == 0) return FALSE;
|
||||
|
||||
Position = Hist->Position + Offset;
|
||||
Position = min(max(Position, 0), Hist->NumEntries - 1);
|
||||
Hist->Position = Position;
|
||||
|
||||
*Entry = Hist->Entries[Hist->Position];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
PUNICODE_STRING Prefix,
|
||||
PUNICODE_STRING Entry)
|
||||
{
|
||||
INT HistPos;
|
||||
|
||||
/* Search for history entries starting with input. */
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
if (!Hist || Hist->NumEntries == 0) return FALSE;
|
||||
|
||||
/*
|
||||
* Like Up/F5, on first time start from current (usually last) entry,
|
||||
* but on subsequent times start at previous entry.
|
||||
*/
|
||||
if (Console->LineUpPressed)
|
||||
Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
|
||||
Console->LineUpPressed = TRUE;
|
||||
|
||||
// Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
|
||||
// Entry.Buffer = Console->LineBuffer;
|
||||
|
||||
/*
|
||||
* Keep going backwards, even wrapping around to the end,
|
||||
* until we get back to starting point.
|
||||
*/
|
||||
HistPos = Hist->Position;
|
||||
do
|
||||
{
|
||||
if (RtlPrefixUnicodeString(Prefix, &Hist->Entries[HistPos], FALSE))
|
||||
{
|
||||
Hist->Position = HistPos;
|
||||
*Entry = Hist->Entries[HistPos];
|
||||
return TRUE;
|
||||
}
|
||||
if (--HistPos < 0) HistPos += Hist->NumEntries;
|
||||
} while (HistPos != Hist->Position);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PPOPUP_WINDOW
|
||||
HistoryDisplayCurrentHistory(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName)
|
||||
{
|
||||
PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
|
||||
PPOPUP_WINDOW Popup;
|
||||
|
||||
SHORT xLeft, yTop;
|
||||
SHORT Width, Height;
|
||||
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
|
||||
if (!Hist) return NULL;
|
||||
if (Hist->NumEntries == 0) return NULL;
|
||||
|
||||
if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) return NULL;
|
||||
ActiveBuffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer;
|
||||
|
||||
Width = 40;
|
||||
Height = 10;
|
||||
|
||||
/* Center the popup window on the screen */
|
||||
xLeft = ActiveBuffer->ViewOrigin.X + (ActiveBuffer->ViewSize.X - Width ) / 2;
|
||||
yTop = ActiveBuffer->ViewOrigin.Y + (ActiveBuffer->ViewSize.Y - Height) / 2;
|
||||
|
||||
/* Create the popup */
|
||||
Popup = CreatePopupWindow(Console, ActiveBuffer,
|
||||
xLeft, yTop, Width, Height);
|
||||
if (Popup == NULL) return NULL;
|
||||
|
||||
Popup->PopupInputRoutine = NULL;
|
||||
|
||||
return Popup;
|
||||
}
|
||||
|
||||
VOID
|
||||
HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName)
|
||||
{
|
||||
HistoryDeleteBuffer(HistoryCurrentBuffer(Console, ExeName));
|
||||
}
|
||||
|
||||
VOID
|
||||
HistoryDeleteBuffers(PCONSRV_CONSOLE Console)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PHISTORY_BUFFER HistoryBuffer;
|
||||
|
||||
while (!IsListEmpty(&Console->HistoryBuffers))
|
||||
{
|
||||
CurrentEntry = RemoveHeadList(&Console->HistoryBuffers);
|
||||
HistoryBuffer = CONTAINING_RECORD(CurrentEntry, HISTORY_BUFFER, ListEntry);
|
||||
HistoryDeleteBuffer(HistoryBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* PUBLIC SERVER APIS *********************************************************/
|
||||
|
||||
CSR_API(SrvGetConsoleCommandHistory)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
ULONG BytesWritten = 0;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
DPRINT1("SrvGetConsoleCommandHistory entered\n");
|
||||
|
||||
if ( !CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&GetCommandHistoryRequest->History,
|
||||
GetCommandHistoryRequest->HistoryLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&GetCommandHistoryRequest->ExeName,
|
||||
GetCommandHistoryRequest->ExeLength,
|
||||
sizeof(BYTE)) )
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
GetCommandHistoryRequest->ExeName,
|
||||
GetCommandHistoryRequest->ExeLength,
|
||||
GetCommandHistoryRequest->Unicode2);
|
||||
if (Hist)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
LPSTR TargetBufferA;
|
||||
LPWSTR TargetBufferW;
|
||||
ULONG BufferSize = GetCommandHistoryRequest->HistoryLength;
|
||||
|
||||
ULONG Offset = 0;
|
||||
ULONG SourceLength;
|
||||
|
||||
if (GetCommandHistoryRequest->Unicode)
|
||||
{
|
||||
TargetBufferW = GetCommandHistoryRequest->History;
|
||||
BufferSize /= sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetBufferA = GetCommandHistoryRequest->History;
|
||||
}
|
||||
|
||||
for (i = 0; i < Hist->NumEntries; i++)
|
||||
{
|
||||
SourceLength = Hist->Entries[i].Length / sizeof(WCHAR);
|
||||
if (Offset + SourceLength + 1 > BufferSize)
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetCommandHistoryRequest->Unicode)
|
||||
{
|
||||
RtlCopyMemory(&TargetBufferW[Offset], Hist->Entries[i].Buffer, SourceLength * sizeof(WCHAR));
|
||||
Offset += SourceLength;
|
||||
TargetBufferW[Offset++] = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertInputUnicodeToAnsi(Console,
|
||||
Hist->Entries[i].Buffer, SourceLength * sizeof(WCHAR),
|
||||
&TargetBufferA[Offset], SourceLength);
|
||||
Offset += SourceLength;
|
||||
TargetBufferA[Offset++] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCommandHistoryRequest->Unicode)
|
||||
BytesWritten = Offset * sizeof(WCHAR);
|
||||
else
|
||||
BytesWritten = Offset;
|
||||
}
|
||||
|
||||
// GetCommandHistoryRequest->HistoryLength = TargetBuffer - (PBYTE)GetCommandHistoryRequest->History;
|
||||
GetCommandHistoryRequest->HistoryLength = BytesWritten;
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvGetConsoleCommandHistoryLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PHISTORY_BUFFER Hist;
|
||||
ULONG Length = 0;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&GetCommandHistoryLengthRequest->ExeName,
|
||||
GetCommandHistoryLengthRequest->ExeLength,
|
||||
sizeof(BYTE)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
GetCommandHistoryLengthRequest->ExeName,
|
||||
GetCommandHistoryLengthRequest->ExeLength,
|
||||
GetCommandHistoryLengthRequest->Unicode2);
|
||||
if (Hist)
|
||||
{
|
||||
ULONG i;
|
||||
for (i = 0; i < Hist->NumEntries; i++)
|
||||
Length += Hist->Entries[i].Length + sizeof(WCHAR); // Each entry is returned NULL-terminated
|
||||
}
|
||||
/*
|
||||
* Quick and dirty way of getting the number of bytes of the
|
||||
* corresponding ANSI string from the one in UNICODE.
|
||||
*/
|
||||
if (!GetCommandHistoryLengthRequest->Unicode)
|
||||
Length /= sizeof(WCHAR);
|
||||
|
||||
GetCommandHistoryLengthRequest->HistoryLength = Length;
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvExpungeConsoleCommandHistory)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ExpungeCommandHistoryRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&ExpungeCommandHistoryRequest->ExeName,
|
||||
ExpungeCommandHistoryRequest->ExeLength,
|
||||
sizeof(BYTE)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
ExpungeCommandHistoryRequest->ExeName,
|
||||
ExpungeCommandHistoryRequest->ExeLength,
|
||||
ExpungeCommandHistoryRequest->Unicode2);
|
||||
HistoryDeleteBuffer(Hist);
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvSetConsoleNumberOfCommands)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryNumberCommandsRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&SetHistoryNumberCommandsRequest->ExeName,
|
||||
SetHistoryNumberCommandsRequest->ExeLength,
|
||||
sizeof(BYTE)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
SetHistoryNumberCommandsRequest->ExeName,
|
||||
SetHistoryNumberCommandsRequest->ExeLength,
|
||||
SetHistoryNumberCommandsRequest->Unicode2);
|
||||
if (Hist)
|
||||
{
|
||||
ULONG MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
|
||||
PUNICODE_STRING OldEntryList = Hist->Entries;
|
||||
PUNICODE_STRING NewEntryList = ConsoleAllocHeap(0, MaxEntries * sizeof(UNICODE_STRING));
|
||||
if (!NewEntryList)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If necessary, shrink by removing oldest entries */
|
||||
for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
|
||||
{
|
||||
RtlFreeUnicodeString(Hist->Entries++);
|
||||
Hist->Position += (Hist->Position == 0);
|
||||
}
|
||||
|
||||
Hist->MaxEntries = MaxEntries;
|
||||
Hist->Entries = memcpy(NewEntryList, Hist->Entries,
|
||||
Hist->NumEntries * sizeof(UNICODE_STRING));
|
||||
ConsoleFreeHeap(OldEntryList);
|
||||
}
|
||||
}
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvGetConsoleHistory)
|
||||
{
|
||||
#if 0 // Vista+
|
||||
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
HistoryInfoRequest->HistoryBufferSize = Console->HistoryBufferSize;
|
||||
HistoryInfoRequest->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
|
||||
HistoryInfoRequest->dwFlags = (Console->HistoryNoDup ? HISTORY_NO_DUP_FLAG : 0);
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
}
|
||||
return Status;
|
||||
#else
|
||||
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
CSR_API(SrvSetConsoleHistory)
|
||||
{
|
||||
#if 0 // Vista+
|
||||
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Console->HistoryBufferSize = HistoryInfoRequest->HistoryBufferSize;
|
||||
Console->NumberOfHistoryBuffers = HistoryInfoRequest->NumberOfHistoryBuffers;
|
||||
Console->HistoryNoDup = !!(HistoryInfoRequest->dwFlags & HISTORY_NO_DUP_FLAG);
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
}
|
||||
return Status;
|
||||
#else
|
||||
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
CSR_API(SrvSetConsoleCommandHistoryMode)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryModeRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
DPRINT1("SrvSetConsoleCommandHistoryMode(Mode = %d) is not yet implemented\n",
|
||||
SetHistoryModeRequest->Mode);
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
|
||||
&Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Console->InsertMode = !!(SetHistoryModeRequest->Mode & CONSOLE_OVERSTRIKE);
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
11
reactos/win32ss/user/winsrv/consrv/history.h
Normal file
11
reactos/win32ss/user/winsrv/consrv/history.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Server DLL
|
||||
* FILE: win32ss/user/winsrv/consrv/history.h
|
||||
* PURPOSE: Console line input functions
|
||||
* PROGRAMMERS: Jeffrey Morlan
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
VOID HistoryDeleteBuffers(PCONSRV_CONSOLE Console);
|
|
@ -12,6 +12,22 @@
|
|||
|
||||
#include "rect.h"
|
||||
|
||||
// This is ALMOST a HACK!!!!!!!
|
||||
// Helpers for code refactoring
|
||||
#ifdef USE_NEW_CONSOLE_WAY
|
||||
|
||||
#define _CONSRV_CONSOLE _WINSRV_CONSOLE
|
||||
#define CONSRV_CONSOLE WINSRV_CONSOLE
|
||||
#define PCONSRV_CONSOLE PWINSRV_CONSOLE
|
||||
|
||||
#else
|
||||
|
||||
#define _CONSRV_CONSOLE _CONSOLE
|
||||
#define CONSRV_CONSOLE CONSOLE
|
||||
#define PCONSRV_CONSOLE PCONSOLE
|
||||
|
||||
#endif
|
||||
|
||||
/* Default attributes */
|
||||
#define DEFAULT_SCREEN_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
|
||||
#define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \
|
||||
|
@ -175,7 +191,7 @@ typedef struct _CONSOLE_INPUT_BUFFER
|
|||
{
|
||||
CONSOLE_IO_OBJECT Header; /* Object header - MUST BE IN FIRST PLACE */
|
||||
|
||||
ULONG InputBufferSize; /* Size of this input buffer */
|
||||
ULONG InputBufferSize; /* Size of this input buffer -- UNUSED!! */
|
||||
LIST_ENTRY InputEvents; /* List head for input event queue */
|
||||
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
|
||||
|
||||
|
@ -194,17 +210,33 @@ typedef struct _TERMINAL_VTBL
|
|||
IN struct _CONSOLE* Console);
|
||||
VOID (NTAPI *DeinitTerminal)(IN OUT PTERMINAL This);
|
||||
|
||||
|
||||
|
||||
/************ Line discipline ***************/
|
||||
|
||||
/* Interface used only for text-mode screen buffers */
|
||||
|
||||
NTSTATUS (NTAPI *ReadStream)(IN OUT PTERMINAL This,
|
||||
/**/IN PUNICODE_STRING ExeName /**/OPTIONAL/**/,/**/
|
||||
IN BOOLEAN Unicode,
|
||||
/**PWCHAR Buffer,**/
|
||||
OUT PVOID Buffer,
|
||||
IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
|
||||
IN ULONG NumCharsToRead,
|
||||
OUT PULONG NumCharsRead OPTIONAL);
|
||||
NTSTATUS (NTAPI *WriteStream)(IN OUT PTERMINAL This,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib);
|
||||
|
||||
/************ Line discipline ***************/
|
||||
|
||||
|
||||
|
||||
/* Interface used for both text-mode and graphics screen buffers */
|
||||
VOID (NTAPI *DrawRegion)(IN OUT PTERMINAL This,
|
||||
SMALL_RECT* Region);
|
||||
/* Interface used only for text-mode screen buffers */
|
||||
VOID (NTAPI *WriteStream)(IN OUT PTERMINAL This,
|
||||
SMALL_RECT* Region,
|
||||
SHORT CursorStartX,
|
||||
SHORT CursorStartY,
|
||||
UINT ScrolledLines,
|
||||
PWCHAR Buffer,
|
||||
UINT Length);
|
||||
BOOL (NTAPI *SetCursorInfo)(IN OUT PTERMINAL This,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||
BOOL (NTAPI *SetScreenInfo)(IN OUT PTERMINAL This,
|
||||
|
@ -219,11 +251,8 @@ typedef struct _TERMINAL_VTBL
|
|||
/*
|
||||
* External interface (functions corresponding to the Console API)
|
||||
*/
|
||||
VOID (NTAPI *ChangeTitle)(IN OUT PTERMINAL This);
|
||||
VOID (NTAPI *GetLargestConsoleWindowSize)(IN OUT PTERMINAL This,
|
||||
PCOORD pSize);
|
||||
// BOOL (NTAPI *GetSelectionInfo)(IN OUT PTERMINAL This,
|
||||
// PCONSOLE_SELECTION_INFO pSelectionInfo);
|
||||
BOOL (NTAPI *SetPalette)(IN OUT PTERMINAL This,
|
||||
HPALETTE PaletteHandle,
|
||||
UINT PaletteUsage);
|
||||
|
@ -263,51 +292,39 @@ typedef enum _CONSOLE_STATE
|
|||
// HACK!!
|
||||
struct _CONSOLE;
|
||||
/* HACK: */ typedef struct _CONSOLE *PCONSOLE;
|
||||
#ifndef USE_NEW_CONSOLE_WAY
|
||||
#include "conio_winsrv.h"
|
||||
#endif
|
||||
|
||||
typedef struct _CONSOLE
|
||||
{
|
||||
/******************************* Console Set-up *******************************/
|
||||
|
||||
#ifndef USE_NEW_CONSOLE_WAY
|
||||
WINSRV_CONSOLE; // HACK HACK!!
|
||||
#endif
|
||||
|
||||
LONG ReferenceCount; /* Is incremented each time a handle to something in the console (a screen-buffer or the input buffer of this console) gets referenced */
|
||||
CRITICAL_SECTION Lock;
|
||||
|
||||
/**/WINSRV_CONSOLE;/**/ // HACK HACK!!
|
||||
|
||||
CONSOLE_STATE State; /* State of the console */
|
||||
TERMINAL TermIFace; /* Frontend-specific interface */
|
||||
|
||||
ULONG ConsoleID; /* The ID of the console */
|
||||
LIST_ENTRY ListEntry; /* Entry in the list of consoles */
|
||||
|
||||
/**************************** Input buffer and data ***************************/
|
||||
HANDLE UnpauseEvent; /* When != NULL, event for pausing the console */
|
||||
|
||||
/******************************** Input buffer ********************************/
|
||||
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
|
||||
UINT InputCodePage;
|
||||
|
||||
/** Put those things in CONSOLE_INPUT_BUFFER in PWINSRV_CONSOLE ?? **/
|
||||
PWCHAR LineBuffer; /* Current line being input, in line buffered mode */
|
||||
ULONG LineMaxSize; /* Maximum size of line in characters (including CR+LF) */
|
||||
ULONG LineSize; /* Current size of line */
|
||||
ULONG LinePos; /* Current position within line */
|
||||
BOOLEAN LineComplete; /* User pressed enter, ready to send back to client */
|
||||
BOOLEAN LineUpPressed;
|
||||
BOOLEAN LineInsertToggle; /* Replace character over cursor instead of inserting */
|
||||
ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */
|
||||
|
||||
/** In PWINSRV_CONSOLE ?? **/
|
||||
BOOLEAN InsertMode;
|
||||
/*************************************************/
|
||||
|
||||
/******************************* Screen buffers *******************************/
|
||||
LIST_ENTRY BufferList; /* List of all screen buffers for this console */
|
||||
PCONSOLE_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
|
||||
UINT OutputCodePage;
|
||||
|
||||
/****************************** Other properties ******************************/
|
||||
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */
|
||||
UNICODE_STRING Title; /* Title of console. Always NULL-terminated */
|
||||
|
||||
HANDLE UnpauseEvent; /* When != NULL, event for pausing the console */
|
||||
|
||||
COORD ConsoleSize; /* The current size of the console, for text-mode only */
|
||||
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
|
||||
|
||||
|
@ -323,42 +340,16 @@ NTSTATUS
|
|||
ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent,
|
||||
IN PCONSOLE_PROCESS_DATA ProcessData);
|
||||
|
||||
/* coninput.c */
|
||||
NTSTATUS
|
||||
ConioAddInputEvents(PCONSOLE Console,
|
||||
PINPUT_RECORD InputRecords,
|
||||
ULONG NumEventsToWrite,
|
||||
PULONG NumEventsWritten,
|
||||
BOOLEAN AppendToEnd);
|
||||
NTSTATUS
|
||||
ConioProcessInputEvent(PCONSOLE Console,
|
||||
PINPUT_RECORD InputEvent);
|
||||
|
||||
#define GetConsoleInputBufferMode(Console) \
|
||||
(Console)->InputBuffer.Mode
|
||||
|
||||
|
||||
/* conoutput.c */
|
||||
|
||||
/*
|
||||
* From MSDN:
|
||||
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||
* If they are the same, the function fails, and GetLastError returns
|
||||
* ERROR_INVALID_PARAMETER."
|
||||
*/
|
||||
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
||||
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
||||
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
|
||||
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||
|
||||
PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
|
||||
VOID ConioDrawConsole(PCONSOLE Console);
|
||||
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
|
||||
VOID ConioDrawConsole(PCONSOLE /*PCONSRV_CONSOLE*/ Console);
|
||||
NTSTATUS ConioResizeBuffer(PCONSOLE /*PCONSRV_CONSOLE*/ Console,
|
||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||
COORD Size);
|
||||
NTSTATUS ConioWriteConsole(PCONSOLE Console,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -14,14 +14,19 @@
|
|||
|
||||
// This is ALMOST a HACK!!!!!!!
|
||||
// Helpers for code refactoring
|
||||
#ifdef USE_NEW_CONSOLE_WAY
|
||||
|
||||
#define _CONSRV_CONSOLE _WINSRV_CONSOLE
|
||||
#define CONSRV_CONSOLE WINSRV_CONSOLE
|
||||
#define PCONSRV_CONSOLE PWINSRV_CONSOLE
|
||||
|
||||
#else
|
||||
|
||||
#define _CONSRV_CONSOLE _CONSOLE
|
||||
#define CONSRV_CONSOLE CONSOLE
|
||||
#define PCONSRV_CONSOLE PCONSOLE
|
||||
|
||||
// #define _CONSRV_CONSOLE _WINSRV_CONSOLE
|
||||
// #define CONSRV_CONSOLE WINSRV_CONSOLE
|
||||
// #define PCONSRV_CONSOLE PWINSRV_CONSOLE
|
||||
|
||||
#endif
|
||||
|
||||
#define CSR_DEFAULT_CURSOR_SIZE 25
|
||||
|
||||
|
@ -33,6 +38,12 @@ typedef struct _CHAR_CELL
|
|||
} CHAR_CELL, *PCHAR_CELL;
|
||||
C_ASSERT(sizeof(CHAR_CELL) == 2);
|
||||
|
||||
// HACK!!
|
||||
struct _WINSRV_CONSOLE;
|
||||
/* HACK: */ typedef struct _WINSRV_CONSOLE *PWINSRV_CONSOLE;
|
||||
#ifdef USE_NEW_CONSOLE_WAY
|
||||
#include "conio.h"
|
||||
#endif
|
||||
|
||||
typedef struct _FRONTEND FRONTEND, *PFRONTEND;
|
||||
/* HACK: */ typedef struct _CONSOLE_INFO *PCONSOLE_INFO;
|
||||
|
@ -58,6 +69,7 @@ typedef struct _FRONTEND_VTBL
|
|||
UINT ScrolledLines,
|
||||
PWCHAR Buffer,
|
||||
UINT Length);
|
||||
VOID (NTAPI *RingBell)(IN OUT PFRONTEND This);
|
||||
BOOL (NTAPI *SetCursorInfo)(IN OUT PFRONTEND This,
|
||||
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
|
||||
BOOL (NTAPI *SetScreenInfo)(IN OUT PFRONTEND This,
|
||||
|
@ -117,8 +129,11 @@ typedef struct _WINSRV_CONSOLE
|
|||
{
|
||||
/******************************* Console Set-up *******************************/
|
||||
/* This **MUST** be FIRST!! */
|
||||
// CONSOLE;
|
||||
// PCONSOLE Console;
|
||||
#ifdef USE_NEW_CONSOLE_WAY
|
||||
CONSOLE;
|
||||
// CONSOLE Console;
|
||||
// // PCONSOLE Console;
|
||||
#endif
|
||||
|
||||
// LONG ReferenceCount; /* Is incremented each time a handle to something in the console (a screen-buffer or the input buffer of this console) gets referenced */
|
||||
// CRITICAL_SECTION Lock;
|
||||
|
@ -131,8 +146,6 @@ typedef struct _WINSRV_CONSOLE
|
|||
PCONSOLE_PROCESS_DATA NotifiedLastCloseProcess; /* Pointer to the unique process that needs to be notified when the console leader process is killed */
|
||||
BOOLEAN NotifyLastClose; /* TRUE if the console should send a control event when the console leader process is killed */
|
||||
|
||||
BOOLEAN QuickEdit;
|
||||
|
||||
/******************************* Pausing support ******************************/
|
||||
BYTE PauseFlags;
|
||||
LIST_ENTRY ReadWaitQueue; /* List head for the queue of unique input buffer read wait blocks */
|
||||
|
@ -145,6 +158,19 @@ typedef struct _WINSRV_CONSOLE
|
|||
ULONG NumberOfHistoryBuffers; /* Maximum number of history buffers allowed */
|
||||
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
|
||||
|
||||
/**************************** Input Line Discipline ***************************/
|
||||
PWCHAR LineBuffer; /* Current line being input, in line buffered mode */
|
||||
ULONG LineMaxSize; /* Maximum size of line in characters (including CR+LF) */
|
||||
ULONG LineSize; /* Current size of line */
|
||||
ULONG LinePos; /* Current position within line */
|
||||
BOOLEAN LineComplete; /* User pressed enter, ready to send back to client */
|
||||
BOOLEAN LineUpPressed;
|
||||
BOOLEAN LineInsertToggle; /* Replace character over cursor instead of inserting */
|
||||
ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */
|
||||
|
||||
BOOLEAN InsertMode;
|
||||
BOOLEAN QuickEdit;
|
||||
|
||||
/************************ Virtual DOS Machine support *************************/
|
||||
COORD VDMBufferSize; /* Real size of the VDM buffer, in units of ??? */
|
||||
HANDLE VDMBufferSection; /* Handle to the memory shared section for the VDM buffer */
|
||||
|
@ -157,9 +183,12 @@ typedef struct _WINSRV_CONSOLE
|
|||
HANDLE ErrorHardwareEvent;
|
||||
|
||||
/****************************** Other properties ******************************/
|
||||
COLORREF Colors[16]; /* Colour palette */
|
||||
LIST_ENTRY PopupWindows; /* List of popup windows */
|
||||
UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */
|
||||
UNICODE_STRING Title; /* Title of console. Always NULL-terminated */
|
||||
COLORREF Colors[16]; /* Colour palette */
|
||||
|
||||
} WINSRV_CONSOLE, *PWINSRV_CONSOLE;
|
||||
} WINSRV_CONSOLE; // , *PWINSRV_CONSOLE;
|
||||
|
||||
/* console.c */
|
||||
VOID ConioPause(PCONSRV_CONSOLE Console, UINT Flags);
|
||||
|
@ -181,40 +210,14 @@ DWORD ConioEffectiveCursorSize(PCONSRV_CONSOLE Console,
|
|||
DWORD Scale);
|
||||
|
||||
NTSTATUS
|
||||
ConioAddInputEvents(PCONSRV_CONSOLE Console,
|
||||
PINPUT_RECORD InputRecords,
|
||||
ULONG NumEventsToWrite,
|
||||
PULONG NumEventsWritten,
|
||||
BOOLEAN AppendToEnd);
|
||||
NTSTATUS
|
||||
ConioProcessInputEvent(PCONSRV_CONSOLE Console,
|
||||
PINPUT_RECORD InputEvent);
|
||||
|
||||
/* conoutput.c */
|
||||
|
||||
/*
|
||||
* From MSDN:
|
||||
* "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
|
||||
* If they are the same, the function fails, and GetLastError returns
|
||||
* ERROR_INVALID_PARAMETER."
|
||||
*/
|
||||
#define ConsoleUnicodeCharToAnsiChar(Console, dChar, sWChar) \
|
||||
ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
|
||||
WideCharToMultiByte((Console)->OutputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
|
||||
|
||||
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
|
||||
ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
|
||||
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
|
||||
|
||||
PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
|
||||
VOID ConioDrawConsole(PCONSRV_CONSOLE Console);
|
||||
NTSTATUS ConioResizeBuffer(PCONSRV_CONSOLE Console,
|
||||
VOID ConioDrawConsole(PCONSOLE /*PCONSRV_CONSOLE*/ Console);
|
||||
NTSTATUS ConioResizeBuffer(PCONSOLE /*PCONSRV_CONSOLE*/ Console,
|
||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
|
||||
COORD Size);
|
||||
NTSTATUS ConioWriteConsole(PCONSRV_CONSOLE Console,
|
||||
PTEXTMODE_SCREEN_BUFFER Buff,
|
||||
PWCHAR Buffer,
|
||||
DWORD Length,
|
||||
BOOL Attrib);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -62,6 +62,9 @@ typedef struct _CONSOLE_INFO
|
|||
|
||||
/*
|
||||
* Structure used to communicate with console.dll
|
||||
*
|
||||
* FIXME: It should overlap with the Windows' CONSOLE_STATE_INFO structure
|
||||
* for GUI terminals!!
|
||||
*/
|
||||
typedef struct _CONSOLE_PROPS
|
||||
{
|
||||
|
|
|
@ -8,13 +8,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
||||
/* Macros used to call functions in the TERMINAL_VTBL virtual table */
|
||||
|
||||
#define TermReadStream(Console, ExeName, /**/ Unicode, /**/ Buffer, ReadControl, NumCharsToRead, NumCharsRead) \
|
||||
(Console)->TermIFace.Vtbl->ReadStream(&(Console)->TermIFace, (ExeName), /**/ (Unicode), /**/ \
|
||||
(Buffer), (ReadControl), (NumCharsToRead), (NumCharsRead))
|
||||
|
||||
#define TermWriteStream(Console, ScreenBuffer, Buffer, Length, Attrib) \
|
||||
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (ScreenBuffer), (Buffer), \
|
||||
(Length), (Attrib))
|
||||
|
||||
|
||||
#define TermDrawRegion(Console, Region) \
|
||||
(Console)->TermIFace.Vtbl->DrawRegion(&(Console)->TermIFace, (Region))
|
||||
#define TermWriteStream(Console, Region, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
|
||||
(Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Region), (CurStartX), (CurStartY), \
|
||||
(ScrolledLines), (Buffer), (Length))
|
||||
#define TermSetCursorInfo(Console, ScreenBuffer) \
|
||||
(Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (ScreenBuffer))
|
||||
#define TermSetScreenInfo(Console, ScreenBuffer, OldCursorX, OldCursorY) \
|
||||
|
@ -25,27 +31,30 @@
|
|||
(Console)->TermIFace.Vtbl->SetActiveScreenBuffer(&(Console)->TermIFace)
|
||||
#define TermReleaseScreenBuffer(Console, ScreenBuffer) \
|
||||
(Console)->TermIFace.Vtbl->ReleaseScreenBuffer(&(Console)->TermIFace, (ScreenBuffer))
|
||||
#define TermGetLargestConsoleWindowSize(Console, pSize) \
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
||||
#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
|
||||
(Console)->TermIFace.Vtbl->SetPalette(&(Console)->TermIFace, (PaletteHandle), (PaletteUsage))
|
||||
#define TermShowMouseCursor(Console, Show) \
|
||||
(Console)->TermIFace.Vtbl->ShowMouseCursor(&(Console)->TermIFace, (Show))
|
||||
|
||||
|
||||
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
|
||||
|
||||
#define TermRefreshInternalInfo(Console) \
|
||||
(Console)->FrontEndIFace.Vtbl->RefreshInternalInfo(&(Console)->FrontEndIFace)
|
||||
|
||||
#define TermChangeTitle(Console) \
|
||||
(Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace)
|
||||
(Console)->FrontEndIFace.Vtbl->ChangeTitle(&(Console)->FrontEndIFace)
|
||||
#define TermChangeIcon(Console, IconHandle) \
|
||||
(Console)->FrontEndIFace.Vtbl->ChangeIcon(&(Console)->FrontEndIFace, (IconHandle))
|
||||
#define TermGetConsoleWindowHandle(Console) \
|
||||
(Console)->FrontEndIFace.Vtbl->GetConsoleWindowHandle(&(Console)->FrontEndIFace)
|
||||
#define TermGetLargestConsoleWindowSize(Console, pSize) \
|
||||
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize))
|
||||
#define TermGetSelectionInfo(Console, pSelectionInfo) \
|
||||
(Console)->FrontEndIFace.Vtbl->GetSelectionInfo(&(Console)->FrontEndIFace, (pSelectionInfo))
|
||||
#define TermSetPalette(Console, PaletteHandle, PaletteUsage) \
|
||||
(Console)->TermIFace.Vtbl->SetPalette(&(Console)->TermIFace, (PaletteHandle), (PaletteUsage))
|
||||
#define TermGetDisplayMode(Console) \
|
||||
(Console)->FrontEndIFace.Vtbl->GetDisplayMode(&(Console)->FrontEndIFace)
|
||||
#define TermSetDisplayMode(Console, NewMode) \
|
||||
(Console)->FrontEndIFace.Vtbl->SetDisplayMode(&(Console)->FrontEndIFace, (NewMode))
|
||||
#define TermShowMouseCursor(Console, Show) \
|
||||
(Console)->TermIFace.Vtbl->ShowMouseCursor(&(Console)->TermIFace, (Show))
|
||||
#define TermSetMouseCursor(Console, CursorHandle) \
|
||||
(Console)->FrontEndIFace.Vtbl->SetMouseCursor(&(Console)->FrontEndIFace, (CursorHandle))
|
||||
#define TermMenuControl(Console, CmdIdLow, CmdIdHigh) \
|
||||
|
|
|
@ -354,8 +354,8 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|||
RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData));
|
||||
TargetProcessData->Process = TargetProcess;
|
||||
TargetProcessData->InputWaitHandle = NULL;
|
||||
TargetProcessData->ConsoleHandle = TargetProcessData->ParentConsoleHandle = NULL;
|
||||
TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE);
|
||||
TargetProcessData->ConsoleHandle = NULL;
|
||||
TargetProcessData->ConsoleApp = FALSE;
|
||||
|
||||
/*
|
||||
* The handles table gets initialized either when inheriting from
|
||||
|
@ -377,10 +377,10 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|||
* handles table: this can happen if it is a GUI application having called
|
||||
* AllocConsole), then try to inherit handles from the parent process.
|
||||
*/
|
||||
if (TargetProcessData->ConsoleApp /* && SourceProcessData->ConsoleApp */)
|
||||
if (TargetProcess->Flags & CsrProcessIsConsoleApp /* && SourceProcessData->ConsoleHandle != NULL */)
|
||||
{
|
||||
PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
|
||||
PCONSOLE SourceConsole;
|
||||
PCONSRV_CONSOLE SourceConsole;
|
||||
|
||||
/* Validate and lock the parent's console */
|
||||
if (ConSrvValidateConsole(&SourceConsole,
|
||||
|
@ -389,10 +389,9 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess,
|
|||
{
|
||||
/* Inherit the parent's handles table */
|
||||
Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData);
|
||||
if (NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Temporary save the parent's console too */
|
||||
TargetProcessData->ParentConsoleHandle = SourceProcessData->ConsoleHandle;
|
||||
DPRINT1("Inheriting handles table failed\n");
|
||||
}
|
||||
|
||||
/* Unlock the parent's console */
|
||||
|
@ -416,28 +415,37 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PCONSRV_API_CONNECTINFO ConnectInfo = (PCONSRV_API_CONNECTINFO)ConnectionInfo;
|
||||
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess);
|
||||
CONSOLE_INIT_INFO ConsoleInitInfo;
|
||||
|
||||
if ( ConnectionInfo == NULL ||
|
||||
ConnectionInfoLength == NULL ||
|
||||
*ConnectionInfoLength != sizeof(CONSRV_API_CONNECTINFO) )
|
||||
*ConnectionInfoLength != sizeof(*ConnectInfo) )
|
||||
{
|
||||
DPRINT1("CONSRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), wanted %lu\n",
|
||||
ConnectionInfo,
|
||||
ConnectionInfoLength,
|
||||
ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
|
||||
sizeof(CONSRV_API_CONNECTINFO));
|
||||
sizeof(*ConnectInfo));
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* If we don't need a console, then get out of here */
|
||||
if (!ConnectInfo->ConsoleStartInfo.ConsoleNeeded || !ProcessData->ConsoleApp) // In fact, it is for GUI apps.
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
DPRINT("ConnectInfo->IsConsoleApp = %s\n", ConnectInfo->IsConsoleApp ? "True" : "False");
|
||||
if (!ConnectInfo->IsConsoleApp) return STATUS_SUCCESS;
|
||||
|
||||
/* If we don't have a console, then create a new one... */
|
||||
if (!ConnectInfo->ConsoleHandle ||
|
||||
ConnectInfo->ConsoleHandle != ProcessData->ParentConsoleHandle)
|
||||
/* Initialize the console initialization info structure */
|
||||
ConsoleInitInfo.ConsoleStartInfo = &ConnectInfo->ConsoleStartInfo;
|
||||
ConsoleInitInfo.TitleLength = ConnectInfo->TitleLength;
|
||||
ConsoleInitInfo.ConsoleTitle = ConnectInfo->ConsoleTitle;
|
||||
ConsoleInitInfo.DesktopLength = ConnectInfo->DesktopLength;
|
||||
ConsoleInitInfo.Desktop = ConnectInfo->Desktop;
|
||||
ConsoleInitInfo.AppNameLength = ConnectInfo->AppNameLength;
|
||||
ConsoleInitInfo.AppName = ConnectInfo->AppName;
|
||||
ConsoleInitInfo.CurDirLength = ConnectInfo->CurDirLength;
|
||||
ConsoleInitInfo.CurDir = ConnectInfo->CurDir;
|
||||
|
||||
/* If we don't inherit from an existing console, then create a new one... */
|
||||
if (ConnectInfo->ConsoleStartInfo.ConsoleHandle == NULL)
|
||||
{
|
||||
DPRINT("ConSrvConnect - Allocate a new console\n");
|
||||
|
||||
|
@ -454,10 +462,10 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
|
||||
/* Initialize a new Console owned by the Console Leader Process */
|
||||
Status = ConSrvAllocateConsole(ProcessData,
|
||||
&ConnectInfo->InputHandle,
|
||||
&ConnectInfo->OutputHandle,
|
||||
&ConnectInfo->ErrorHandle,
|
||||
&ConnectInfo->ConsoleStartInfo);
|
||||
&ConnectInfo->ConsoleStartInfo.InputHandle,
|
||||
&ConnectInfo->ConsoleStartInfo.OutputHandle,
|
||||
&ConnectInfo->ConsoleStartInfo.ErrorHandle,
|
||||
&ConsoleInitInfo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console allocation failed\n");
|
||||
|
@ -470,11 +478,11 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
|
||||
/* Reuse our current console */
|
||||
Status = ConSrvInheritConsole(ProcessData,
|
||||
ConnectInfo->ConsoleHandle,
|
||||
ConnectInfo->ConsoleStartInfo.ConsoleHandle,
|
||||
FALSE,
|
||||
NULL, // &ConnectInfo->InputHandle,
|
||||
NULL, // &ConnectInfo->OutputHandle,
|
||||
NULL); // &ConnectInfo->ErrorHandle);
|
||||
NULL, // &ConnectInfo->ConsoleStartInfo.InputHandle,
|
||||
NULL, // &ConnectInfo->ConsoleStartInfo.OutputHandle,
|
||||
NULL); // &ConnectInfo->ConsoleStartInfo.ErrorHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Console inheritance failed\n");
|
||||
|
@ -482,13 +490,17 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess,
|
|||
}
|
||||
}
|
||||
|
||||
/* Mark the process as having a console */
|
||||
ProcessData->ConsoleApp = TRUE;
|
||||
// ProcessData->Flags |= CsrProcessIsConsoleApp;
|
||||
|
||||
/* Return the console handle and the input wait handle to the caller */
|
||||
ConnectInfo->ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
ConnectInfo->InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
ConnectInfo->ConsoleStartInfo.ConsoleHandle = ProcessData->ConsoleHandle;
|
||||
ConnectInfo->ConsoleStartInfo.InputWaitHandle = ProcessData->InputWaitHandle;
|
||||
|
||||
/* Set the Property-Dialog and Control-Dispatcher handlers */
|
||||
ProcessData->PropDispatcher = ConnectInfo->ConsoleStartInfo.PropDispatcher;
|
||||
ProcessData->CtrlDispatcher = ConnectInfo->ConsoleStartInfo.CtrlDispatcher;
|
||||
ProcessData->PropRoutine = ConnectInfo->PropRoutine;
|
||||
ProcessData->CtrlRoutine = ConnectInfo->CtrlRoutine;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -508,6 +520,10 @@ ConSrvDisconnect(PCSR_PROCESS Process)
|
|||
{
|
||||
DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n");
|
||||
ConSrvRemoveConsole(ProcessData);
|
||||
|
||||
/* Mark the process as not having a console anymore */
|
||||
ProcessData->ConsoleApp = FALSE;
|
||||
Process->Flags &= ~CsrProcessIsConsoleApp;
|
||||
}
|
||||
|
||||
RtlDeleteCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
|
|
@ -9,30 +9,21 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "consrv.h"
|
||||
#include "popup.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct _HISTORY_BUFFER
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
UINT Position;
|
||||
UINT MaxEntries;
|
||||
UINT NumEntries;
|
||||
UNICODE_STRING ExeName;
|
||||
PUNICODE_STRING Entries;
|
||||
} HISTORY_BUFFER, *PHISTORY_BUFFER;
|
||||
|
||||
|
||||
BOOLEAN
|
||||
ConvertInputAnsiToUnicode(PCONSOLE Console,
|
||||
ConvertInputAnsiToUnicode(PCONSRV_CONSOLE Console,
|
||||
PVOID Source,
|
||||
USHORT SourceLength,
|
||||
// BOOLEAN IsUnicode,
|
||||
PWCHAR* Target,
|
||||
PUSHORT TargetLength);
|
||||
BOOLEAN
|
||||
ConvertInputUnicodeToAnsi(PCONSOLE Console,
|
||||
ConvertInputUnicodeToAnsi(PCONSRV_CONSOLE Console,
|
||||
PVOID Source,
|
||||
USHORT SourceLength,
|
||||
// BOOLEAN IsAnsi,
|
||||
|
@ -40,185 +31,36 @@ ConvertInputUnicodeToAnsi(PCONSOLE Console,
|
|||
/*P*/USHORT TargetLength);
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static PHISTORY_BUFFER
|
||||
HistoryCurrentBuffer(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName)
|
||||
{
|
||||
PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
|
||||
{
|
||||
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
|
||||
if (RtlEqualUnicodeString(ExeName, &Hist->ExeName, FALSE))
|
||||
return Hist;
|
||||
}
|
||||
|
||||
/* Couldn't find the buffer, create a new one */
|
||||
Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName->Length);
|
||||
if (!Hist) return NULL;
|
||||
Hist->MaxEntries = Console->HistoryBufferSize;
|
||||
Hist->NumEntries = 0;
|
||||
Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries * sizeof(UNICODE_STRING));
|
||||
if (!Hist->Entries)
|
||||
{
|
||||
ConsoleFreeHeap(Hist);
|
||||
return NULL;
|
||||
}
|
||||
Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName->Length;
|
||||
Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
|
||||
memcpy(Hist->ExeName.Buffer, ExeName->Buffer, ExeName->Length);
|
||||
InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
|
||||
return Hist;
|
||||
}
|
||||
|
||||
static VOID
|
||||
VOID
|
||||
HistoryAddEntry(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName)
|
||||
{
|
||||
UNICODE_STRING NewEntry;
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
INT i;
|
||||
|
||||
if (!Hist) return;
|
||||
|
||||
NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
|
||||
NewEntry.Buffer = Console->LineBuffer;
|
||||
|
||||
/* Don't add blank or duplicate entries */
|
||||
if (NewEntry.Length == 0 || Hist->MaxEntries == 0 ||
|
||||
(Hist->NumEntries > 0 &&
|
||||
RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Console->HistoryNoDup)
|
||||
{
|
||||
/* Check if this line has been entered before */
|
||||
for (i = Hist->NumEntries - 1; i >= 0; i--)
|
||||
{
|
||||
if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE))
|
||||
{
|
||||
/* Just rotate the list to bring this entry to the end */
|
||||
NewEntry = Hist->Entries[i];
|
||||
memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
|
||||
(Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
|
||||
Hist->Entries[Hist->NumEntries - 1] = NewEntry;
|
||||
Hist->Position = Hist->NumEntries - 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Hist->NumEntries == Hist->MaxEntries)
|
||||
{
|
||||
/* List is full, remove oldest entry */
|
||||
RtlFreeUnicodeString(&Hist->Entries[0]);
|
||||
memmove(&Hist->Entries[0], &Hist->Entries[1],
|
||||
--Hist->NumEntries * sizeof(UNICODE_STRING));
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries])))
|
||||
Hist->NumEntries++;
|
||||
Hist->Position = Hist->NumEntries - 1;
|
||||
}
|
||||
|
||||
static VOID
|
||||
PUNICODE_STRING ExeName,
|
||||
PUNICODE_STRING Entry);
|
||||
BOOL
|
||||
HistoryRecallHistory(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
INT Offset,
|
||||
PUNICODE_STRING Entry);
|
||||
VOID
|
||||
HistoryGetCurrentEntry(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
PUNICODE_STRING Entry)
|
||||
{
|
||||
PHISTORY_BUFFER Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
|
||||
if (!Hist || Hist->NumEntries == 0)
|
||||
Entry->Length = 0;
|
||||
else
|
||||
*Entry = Hist->Entries[Hist->Position];
|
||||
}
|
||||
|
||||
static PHISTORY_BUFFER
|
||||
HistoryFindBuffer(PCONSRV_CONSOLE Console,
|
||||
PVOID ExeName,
|
||||
USHORT ExeLength,
|
||||
BOOLEAN UnicodeExe)
|
||||
{
|
||||
UNICODE_STRING ExeNameU;
|
||||
|
||||
PLIST_ENTRY Entry;
|
||||
PHISTORY_BUFFER Hist = NULL;
|
||||
|
||||
if (ExeName == NULL) return NULL;
|
||||
|
||||
if (UnicodeExe)
|
||||
{
|
||||
ExeNameU.Buffer = ExeName;
|
||||
/* Length is in bytes */
|
||||
ExeNameU.MaximumLength = ExeLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ConvertInputAnsiToUnicode(Console,
|
||||
ExeName, ExeLength,
|
||||
&ExeNameU.Buffer, &ExeNameU.MaximumLength))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ExeNameU.Length = ExeNameU.MaximumLength;
|
||||
|
||||
Entry = Console->HistoryBuffers.Flink;
|
||||
while (Entry != &Console->HistoryBuffers)
|
||||
{
|
||||
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
|
||||
|
||||
/* For the history APIs, the caller is allowed to give only part of the name */
|
||||
if (RtlPrefixUnicodeString(&ExeNameU, &Hist->ExeName, TRUE))
|
||||
{
|
||||
if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
|
||||
return Hist;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
if (!UnicodeExe) ConsoleFreeHeap(ExeNameU.Buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static VOID
|
||||
HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
|
||||
{
|
||||
if (!Hist) return;
|
||||
|
||||
while (Hist->NumEntries != 0)
|
||||
RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
|
||||
|
||||
ConsoleFreeHeap(Hist->Entries);
|
||||
RemoveEntryList(&Hist->ListEntry);
|
||||
ConsoleFreeHeap(Hist);
|
||||
}
|
||||
|
||||
PUNICODE_STRING Entry);
|
||||
VOID
|
||||
HistoryDeleteBuffers(PCONSRV_CONSOLE Console)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PHISTORY_BUFFER HistoryBuffer;
|
||||
HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName);
|
||||
BOOL
|
||||
HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
PUNICODE_STRING Prefix,
|
||||
PUNICODE_STRING Entry);
|
||||
|
||||
while (!IsListEmpty(&Console->HistoryBuffers))
|
||||
{
|
||||
CurrentEntry = RemoveHeadList(&Console->HistoryBuffers);
|
||||
HistoryBuffer = CONTAINING_RECORD(CurrentEntry, HISTORY_BUFFER, ListEntry);
|
||||
HistoryDeleteBuffer(HistoryBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
static VOID
|
||||
LineInputSetPos(PCONSRV_CONSOLE Console, UINT Pos)
|
||||
LineInputSetPos(PCONSRV_CONSOLE Console,
|
||||
UINT Pos)
|
||||
{
|
||||
if (Pos != Console->LinePos && Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
|
||||
if (Pos != Console->LinePos && GetConsoleInputBufferMode(Console) & ENABLE_ECHO_INPUT)
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
|
||||
SHORT OldCursorX = Buffer->CursorPosition.X;
|
||||
|
@ -240,7 +82,10 @@ LineInputSetPos(PCONSRV_CONSOLE Console, UINT Pos)
|
|||
}
|
||||
|
||||
static VOID
|
||||
LineInputEdit(PCONSRV_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHAR Insertion)
|
||||
LineInputEdit(PCONSRV_CONSOLE Console,
|
||||
UINT NumToDelete,
|
||||
UINT NumToInsert,
|
||||
PWCHAR Insertion)
|
||||
{
|
||||
PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
|
||||
UINT Pos = Console->LinePos;
|
||||
|
@ -259,15 +104,15 @@ LineInputEdit(PCONSRV_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHA
|
|||
(Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR));
|
||||
memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR));
|
||||
|
||||
if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
|
||||
if (GetConsoleInputBufferMode(Console) & ENABLE_ECHO_INPUT)
|
||||
{
|
||||
for (i = Pos; i < NewSize; i++)
|
||||
{
|
||||
ConioWriteConsole(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
|
||||
TermWriteStream(Console, ActiveBuffer, &Console->LineBuffer[i], 1, TRUE);
|
||||
}
|
||||
for (; i < Console->LineSize; i++)
|
||||
{
|
||||
ConioWriteConsole(Console, ActiveBuffer, L" ", 1, TRUE);
|
||||
TermWriteStream(Console, ActiveBuffer, L" ", 1, TRUE);
|
||||
}
|
||||
Console->LinePos = i;
|
||||
}
|
||||
|
@ -276,6 +121,7 @@ LineInputEdit(PCONSRV_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHA
|
|||
LineInputSetPos(Console, Pos + NumToInsert);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static VOID
|
||||
LineInputRecallHistory(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
|
@ -295,6 +141,30 @@ LineInputRecallHistory(PCONSRV_CONSOLE Console,
|
|||
Hist->Entries[Hist->Position].Length / sizeof(WCHAR),
|
||||
Hist->Entries[Hist->Position].Buffer);
|
||||
}
|
||||
#else
|
||||
static VOID
|
||||
LineInputRecallHistory(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
INT Offset)
|
||||
{
|
||||
UNICODE_STRING Entry;
|
||||
|
||||
if (!HistoryRecallHistory(Console, ExeName, Offset, &Entry)) return;
|
||||
|
||||
LineInputSetPos(Console, 0);
|
||||
LineInputEdit(Console, Console->LineSize,
|
||||
Entry.Length / sizeof(WCHAR),
|
||||
Entry.Buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// TESTS!!
|
||||
PPOPUP_WINDOW Popup = NULL;
|
||||
|
||||
PPOPUP_WINDOW
|
||||
HistoryDisplayCurrentHistory(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName);
|
||||
|
||||
VOID
|
||||
LineInputKeyDown(PCONSRV_CONSOLE Console,
|
||||
|
@ -302,145 +172,238 @@ LineInputKeyDown(PCONSRV_CONSOLE Console,
|
|||
KEY_EVENT_RECORD *KeyEvent)
|
||||
{
|
||||
UINT Pos = Console->LinePos;
|
||||
PHISTORY_BUFFER Hist;
|
||||
UNICODE_STRING Entry;
|
||||
INT HistPos;
|
||||
|
||||
/*
|
||||
* First, deal with control keys...
|
||||
*/
|
||||
|
||||
switch (KeyEvent->wVirtualKeyCode)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
/* Clear entire line */
|
||||
LineInputSetPos(Console, 0);
|
||||
LineInputEdit(Console, Console->LineSize, 0, NULL);
|
||||
return;
|
||||
case VK_HOME:
|
||||
/* Move to start of line. With ctrl, erase everything left of cursor */
|
||||
LineInputSetPos(Console, 0);
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
LineInputEdit(Console, Pos, 0, NULL);
|
||||
return;
|
||||
case VK_END:
|
||||
/* Move to end of line. With ctrl, erase everything right of cursor */
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
|
||||
else
|
||||
LineInputSetPos(Console, Console->LineSize);
|
||||
return;
|
||||
case VK_LEFT:
|
||||
/* Move left. With ctrl, move to beginning of previous word */
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
case VK_ESCAPE:
|
||||
{
|
||||
while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
|
||||
while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
|
||||
/* Clear entire line */
|
||||
LineInputSetPos(Console, 0);
|
||||
LineInputEdit(Console, Console->LineSize, 0, NULL);
|
||||
|
||||
// TESTS!!
|
||||
if (Popup)
|
||||
{
|
||||
DestroyPopupWindow(Popup);
|
||||
Popup = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
case VK_HOME:
|
||||
{
|
||||
Pos -= (Pos > 0);
|
||||
/* Move to start of line. With CTRL, erase everything left of cursor */
|
||||
LineInputSetPos(Console, 0);
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
LineInputEdit(Console, Pos, 0, NULL);
|
||||
return;
|
||||
}
|
||||
LineInputSetPos(Console, Pos);
|
||||
return;
|
||||
case VK_RIGHT:
|
||||
case VK_F1:
|
||||
/* Move right. With ctrl, move to beginning of next word */
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
|
||||
case VK_END:
|
||||
{
|
||||
while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
|
||||
while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
|
||||
/* Move to end of line. With CTRL, erase everything right of cursor */
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
|
||||
else
|
||||
LineInputSetPos(Console, Console->LineSize);
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_LEFT:
|
||||
{
|
||||
/* Move left. With CTRL, move to beginning of previous word */
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
{
|
||||
while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
|
||||
while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pos -= (Pos > 0);
|
||||
}
|
||||
LineInputSetPos(Console, Pos);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Recall one character (but don't overwrite current line) */
|
||||
HistoryGetCurrentEntry(Console, ExeName, &Entry);
|
||||
if (Pos < Console->LineSize)
|
||||
LineInputSetPos(Console, Pos + 1);
|
||||
else if (Pos * sizeof(WCHAR) < Entry.Length)
|
||||
LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
|
||||
}
|
||||
return;
|
||||
case VK_INSERT:
|
||||
/* Toggle between insert and overstrike */
|
||||
Console->LineInsertToggle = !Console->LineInsertToggle;
|
||||
TermSetCursorInfo(Console, Console->ActiveBuffer);
|
||||
return;
|
||||
case VK_DELETE:
|
||||
/* Remove character to right of cursor */
|
||||
if (Pos != Console->LineSize)
|
||||
LineInputEdit(Console, 1, 0, NULL);
|
||||
return;
|
||||
case VK_PRIOR:
|
||||
/* Recall first history entry */
|
||||
LineInputRecallHistory(Console, ExeName, -((WORD)-1));
|
||||
return;
|
||||
case VK_NEXT:
|
||||
/* Recall last history entry */
|
||||
LineInputRecallHistory(Console, ExeName, +((WORD)-1));
|
||||
return;
|
||||
case VK_UP:
|
||||
case VK_F5:
|
||||
/* Recall previous history entry. On first time, actually recall the
|
||||
* current (usually last) entry; on subsequent times go back. */
|
||||
LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
|
||||
Console->LineUpPressed = TRUE;
|
||||
return;
|
||||
case VK_DOWN:
|
||||
/* Recall next history entry */
|
||||
LineInputRecallHistory(Console, ExeName, +1);
|
||||
return;
|
||||
case VK_F3:
|
||||
/* Recall remainder of current history entry */
|
||||
HistoryGetCurrentEntry(Console, ExeName, &Entry);
|
||||
if (Pos * sizeof(WCHAR) < Entry.Length)
|
||||
{
|
||||
UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
|
||||
UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
|
||||
LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
|
||||
}
|
||||
return;
|
||||
case VK_F6:
|
||||
/* Insert a ^Z character */
|
||||
KeyEvent->uChar.UnicodeChar = 26;
|
||||
break;
|
||||
case VK_F7:
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
|
||||
HistoryDeleteBuffer(HistoryCurrentBuffer(Console, ExeName));
|
||||
return;
|
||||
case VK_F8:
|
||||
/* Search for history entries starting with input. */
|
||||
Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
if (!Hist || Hist->NumEntries == 0) return;
|
||||
|
||||
/* Like Up/F5, on first time start from current (usually last) entry,
|
||||
* but on subsequent times start at previous entry. */
|
||||
if (Console->LineUpPressed)
|
||||
Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
|
||||
Console->LineUpPressed = TRUE;
|
||||
|
||||
Entry.Length = Console->LinePos * sizeof(WCHAR);
|
||||
Entry.Buffer = Console->LineBuffer;
|
||||
|
||||
/* Keep going backwards, even wrapping around to the end,
|
||||
* until we get back to starting point */
|
||||
HistPos = Hist->Position;
|
||||
do
|
||||
case VK_RIGHT:
|
||||
case VK_F1:
|
||||
{
|
||||
if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
|
||||
/* Move right. With CTRL, move to beginning of next word */
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
|
||||
{
|
||||
while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
|
||||
while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
|
||||
LineInputSetPos(Console, Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Recall one character (but don't overwrite current line) */
|
||||
HistoryGetCurrentEntry(Console, ExeName, &Entry);
|
||||
if (Pos < Console->LineSize)
|
||||
LineInputSetPos(Console, Pos + 1);
|
||||
else if (Pos * sizeof(WCHAR) < Entry.Length)
|
||||
LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_INSERT:
|
||||
{
|
||||
/* Toggle between insert and overstrike */
|
||||
Console->LineInsertToggle = !Console->LineInsertToggle;
|
||||
TermSetCursorInfo(Console, Console->ActiveBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_DELETE:
|
||||
{
|
||||
/* Remove character to right of cursor */
|
||||
if (Pos != Console->LineSize)
|
||||
LineInputEdit(Console, 1, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_PRIOR:
|
||||
{
|
||||
/* Recall first history entry */
|
||||
LineInputRecallHistory(Console, ExeName, -((WORD)-1));
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_NEXT:
|
||||
{
|
||||
/* Recall last history entry */
|
||||
LineInputRecallHistory(Console, ExeName, +((WORD)-1));
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_UP:
|
||||
case VK_F5:
|
||||
{
|
||||
/*
|
||||
* Recall previous history entry. On first time, actually recall the
|
||||
* current (usually last) entry; on subsequent times go back.
|
||||
*/
|
||||
LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
|
||||
Console->LineUpPressed = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_DOWN:
|
||||
{
|
||||
/* Recall next history entry */
|
||||
LineInputRecallHistory(Console, ExeName, +1);
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_F3:
|
||||
{
|
||||
/* Recall remainder of current history entry */
|
||||
HistoryGetCurrentEntry(Console, ExeName, &Entry);
|
||||
if (Pos * sizeof(WCHAR) < Entry.Length)
|
||||
{
|
||||
UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
|
||||
UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
|
||||
LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_F6:
|
||||
{
|
||||
/* Insert a ^Z character */
|
||||
KeyEvent->uChar.UnicodeChar = 26;
|
||||
break;
|
||||
}
|
||||
|
||||
case VK_F7:
|
||||
{
|
||||
if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
|
||||
HistoryDeleteCurrentBuffer(Console, ExeName);
|
||||
else
|
||||
{
|
||||
if (Popup) DestroyPopupWindow(Popup);
|
||||
Popup = HistoryDisplayCurrentHistory(Console, ExeName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case VK_F8:
|
||||
{
|
||||
UNICODE_STRING EntryFound;
|
||||
|
||||
Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
|
||||
Entry.Buffer = Console->LineBuffer;
|
||||
|
||||
if (HistoryFindEntryByPrefix(Console, ExeName, &Entry, &EntryFound))
|
||||
{
|
||||
Hist->Position = HistPos;
|
||||
LineInputEdit(Console, Console->LineSize - Pos,
|
||||
Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
|
||||
&Hist->Entries[HistPos].Buffer[Pos]);
|
||||
EntryFound.Length / sizeof(WCHAR) - Pos,
|
||||
&EntryFound.Buffer[Pos]);
|
||||
/* Cursor stays where it was */
|
||||
LineInputSetPos(Console, Pos);
|
||||
return;
|
||||
}
|
||||
if (--HistPos < 0) HistPos += Hist->NumEntries;
|
||||
} while (HistPos != Hist->Position);
|
||||
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
PHISTORY_BUFFER Hist;
|
||||
INT HistPos;
|
||||
|
||||
/* Search for history entries starting with input. */
|
||||
Hist = HistoryCurrentBuffer(Console, ExeName);
|
||||
if (!Hist || Hist->NumEntries == 0) return;
|
||||
|
||||
/*
|
||||
* Like Up/F5, on first time start from current (usually last) entry,
|
||||
* but on subsequent times start at previous entry.
|
||||
*/
|
||||
if (Console->LineUpPressed)
|
||||
Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
|
||||
Console->LineUpPressed = TRUE;
|
||||
|
||||
Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
|
||||
Entry.Buffer = Console->LineBuffer;
|
||||
|
||||
/*
|
||||
* Keep going backwards, even wrapping around to the end,
|
||||
* until we get back to starting point.
|
||||
*/
|
||||
HistPos = Hist->Position;
|
||||
do
|
||||
{
|
||||
if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
|
||||
{
|
||||
Hist->Position = HistPos;
|
||||
LineInputEdit(Console, Console->LineSize - Pos,
|
||||
Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
|
||||
&Hist->Entries[HistPos].Buffer[Pos]);
|
||||
/* Cursor stays where it was */
|
||||
LineInputSetPos(Console, Pos);
|
||||
return;
|
||||
}
|
||||
if (--HistPos < 0) HistPos += Hist->NumEntries;
|
||||
} while (HistPos != Hist->Position);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT)
|
||||
|
||||
/*
|
||||
* OK, we deal with normal keys, we can continue...
|
||||
*/
|
||||
|
||||
if (KeyEvent->uChar.UnicodeChar == L'\b' && GetConsoleInputBufferMode(Console) & ENABLE_PROCESSED_INPUT)
|
||||
{
|
||||
/* backspace handling - if processed input enabled then we handle it here
|
||||
* otherwise we treat it like a normal char. */
|
||||
|
@ -452,32 +415,37 @@ LineInputKeyDown(PCONSRV_CONSOLE Console,
|
|||
}
|
||||
else if (KeyEvent->uChar.UnicodeChar == L'\r')
|
||||
{
|
||||
HistoryAddEntry(Console, ExeName);
|
||||
Entry.Length = Entry.MaximumLength = Console->LineSize * sizeof(WCHAR);
|
||||
Entry.Buffer = Console->LineBuffer;
|
||||
HistoryAddEntry(Console, ExeName, &Entry);
|
||||
|
||||
/* TODO: Expand aliases */
|
||||
DPRINT1("TODO: Expand aliases\n");
|
||||
|
||||
LineInputSetPos(Console, Console->LineSize);
|
||||
Console->LineBuffer[Console->LineSize++] = L'\r';
|
||||
if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
|
||||
if (GetConsoleInputBufferMode(Console) & ENABLE_ECHO_INPUT)
|
||||
{
|
||||
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
||||
{
|
||||
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
|
||||
TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add \n if processed input. There should usually be room for it,
|
||||
/*
|
||||
* Add \n if processed input. There should usually be room for it,
|
||||
* but an exception to the rule exists: the buffer could have been
|
||||
* pre-filled with LineMaxSize - 1 characters. */
|
||||
if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT &&
|
||||
* pre-filled with LineMaxSize - 1 characters.
|
||||
*/
|
||||
if (GetConsoleInputBufferMode(Console) & ENABLE_PROCESSED_INPUT &&
|
||||
Console->LineSize < Console->LineMaxSize)
|
||||
{
|
||||
Console->LineBuffer[Console->LineSize++] = L'\n';
|
||||
if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
|
||||
if (GetConsoleInputBufferMode(Console) & ENABLE_ECHO_INPUT)
|
||||
{
|
||||
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
|
||||
{
|
||||
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
|
||||
TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,6 +467,7 @@ LineInputKeyDown(PCONSRV_CONSOLE Console,
|
|||
{
|
||||
/* Normal character */
|
||||
BOOL Overstrike = !Console->LineInsertToggle && (Console->LinePos != Console->LineSize);
|
||||
DPRINT("Overstrike = %s\n", Overstrike ? "true" : "false");
|
||||
LineInputEdit(Console, (Overstrike ? 1 : 0), 1, &KeyEvent->uChar.UnicodeChar);
|
||||
}
|
||||
}
|
||||
|
@ -507,272 +476,4 @@ LineInputKeyDown(PCONSRV_CONSOLE Console,
|
|||
|
||||
/* PUBLIC SERVER APIS *********************************************************/
|
||||
|
||||
CSR_API(SrvGetConsoleCommandHistory)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETCOMMANDHISTORY GetCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
ULONG BytesWritten = 0;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
DPRINT1("SrvGetConsoleCommandHistory entered\n");
|
||||
|
||||
if ( !CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&GetCommandHistoryRequest->History,
|
||||
GetCommandHistoryRequest->HistoryLength,
|
||||
sizeof(BYTE)) ||
|
||||
!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&GetCommandHistoryRequest->ExeName,
|
||||
GetCommandHistoryRequest->ExeLength,
|
||||
sizeof(BYTE)) )
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
GetCommandHistoryRequest->ExeName,
|
||||
GetCommandHistoryRequest->ExeLength,
|
||||
GetCommandHistoryRequest->Unicode2);
|
||||
if (Hist)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
LPSTR TargetBufferA;
|
||||
LPWSTR TargetBufferW;
|
||||
ULONG BufferSize = GetCommandHistoryRequest->HistoryLength;
|
||||
|
||||
UINT Offset = 0;
|
||||
UINT SourceLength;
|
||||
|
||||
if (GetCommandHistoryRequest->Unicode)
|
||||
{
|
||||
TargetBufferW = GetCommandHistoryRequest->History;
|
||||
BufferSize /= sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetBufferA = GetCommandHistoryRequest->History;
|
||||
}
|
||||
|
||||
for (i = 0; i < Hist->NumEntries; i++)
|
||||
{
|
||||
SourceLength = Hist->Entries[i].Length / sizeof(WCHAR);
|
||||
if (Offset + SourceLength + 1 > BufferSize)
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetCommandHistoryRequest->Unicode)
|
||||
{
|
||||
RtlCopyMemory(&TargetBufferW[Offset], Hist->Entries[i].Buffer, SourceLength * sizeof(WCHAR));
|
||||
Offset += SourceLength;
|
||||
TargetBufferW[Offset++] = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertInputUnicodeToAnsi(Console,
|
||||
Hist->Entries[i].Buffer, SourceLength * sizeof(WCHAR),
|
||||
&TargetBufferA[Offset], SourceLength);
|
||||
Offset += SourceLength;
|
||||
TargetBufferA[Offset++] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCommandHistoryRequest->Unicode)
|
||||
BytesWritten = Offset * sizeof(WCHAR);
|
||||
else
|
||||
BytesWritten = Offset;
|
||||
}
|
||||
|
||||
// GetCommandHistoryRequest->HistoryLength = TargetBuffer - (PBYTE)GetCommandHistoryRequest->History;
|
||||
GetCommandHistoryRequest->HistoryLength = BytesWritten;
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvGetConsoleCommandHistoryLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_GETCOMMANDHISTORYLENGTH GetCommandHistoryLengthRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetCommandHistoryLengthRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PHISTORY_BUFFER Hist;
|
||||
ULONG Length = 0;
|
||||
UINT i;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&GetCommandHistoryLengthRequest->ExeName,
|
||||
GetCommandHistoryLengthRequest->ExeLength,
|
||||
sizeof(BYTE)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
GetCommandHistoryLengthRequest->ExeName,
|
||||
GetCommandHistoryLengthRequest->ExeLength,
|
||||
GetCommandHistoryLengthRequest->Unicode2);
|
||||
if (Hist)
|
||||
{
|
||||
for (i = 0; i < Hist->NumEntries; i++)
|
||||
Length += Hist->Entries[i].Length + sizeof(WCHAR); // Each entry is returned NULL-terminated
|
||||
}
|
||||
/*
|
||||
* Quick and dirty way of getting the number of bytes of the
|
||||
* corresponding ANSI string from the one in UNICODE.
|
||||
*/
|
||||
if (!GetCommandHistoryLengthRequest->Unicode)
|
||||
Length /= sizeof(WCHAR);
|
||||
|
||||
GetCommandHistoryLengthRequest->HistoryLength = Length;
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvExpungeConsoleCommandHistory)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_EXPUNGECOMMANDHISTORY ExpungeCommandHistoryRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ExpungeCommandHistoryRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&ExpungeCommandHistoryRequest->ExeName,
|
||||
ExpungeCommandHistoryRequest->ExeLength,
|
||||
sizeof(BYTE)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
ExpungeCommandHistoryRequest->ExeName,
|
||||
ExpungeCommandHistoryRequest->ExeLength,
|
||||
ExpungeCommandHistoryRequest->Unicode2);
|
||||
HistoryDeleteBuffer(Hist);
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvSetConsoleNumberOfCommands)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryNumberCommandsRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
PHISTORY_BUFFER Hist;
|
||||
|
||||
if (!CsrValidateMessageBuffer(ApiMessage,
|
||||
(PVOID*)&SetHistoryNumberCommandsRequest->ExeName,
|
||||
SetHistoryNumberCommandsRequest->ExeLength,
|
||||
sizeof(BYTE)))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
Hist = HistoryFindBuffer(Console,
|
||||
SetHistoryNumberCommandsRequest->ExeName,
|
||||
SetHistoryNumberCommandsRequest->ExeLength,
|
||||
SetHistoryNumberCommandsRequest->Unicode2);
|
||||
if (Hist)
|
||||
{
|
||||
UINT MaxEntries = SetHistoryNumberCommandsRequest->NumCommands;
|
||||
PUNICODE_STRING OldEntryList = Hist->Entries;
|
||||
PUNICODE_STRING NewEntryList = ConsoleAllocHeap(0, MaxEntries * sizeof(UNICODE_STRING));
|
||||
if (!NewEntryList)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If necessary, shrink by removing oldest entries */
|
||||
for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
|
||||
{
|
||||
RtlFreeUnicodeString(Hist->Entries++);
|
||||
Hist->Position += (Hist->Position == 0);
|
||||
}
|
||||
|
||||
Hist->MaxEntries = MaxEntries;
|
||||
Hist->Entries = memcpy(NewEntryList, Hist->Entries,
|
||||
Hist->NumEntries * sizeof(UNICODE_STRING));
|
||||
ConsoleFreeHeap(OldEntryList);
|
||||
}
|
||||
}
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
CSR_API(SrvGetConsoleHistory)
|
||||
{
|
||||
#if 0 // Vista+
|
||||
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
HistoryInfoRequest->HistoryBufferSize = Console->HistoryBufferSize;
|
||||
HistoryInfoRequest->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
|
||||
HistoryInfoRequest->dwFlags = Console->HistoryNoDup;
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
}
|
||||
return Status;
|
||||
#else
|
||||
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
CSR_API(SrvSetConsoleHistory)
|
||||
{
|
||||
#if 0 // Vista+
|
||||
PCONSOLE_GETSETHISTORYINFO HistoryInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HistoryInfoRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
NTSTATUS Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Console->HistoryBufferSize = HistoryInfoRequest->HistoryBufferSize;
|
||||
Console->NumberOfHistoryBuffers = HistoryInfoRequest->NumberOfHistoryBuffers;
|
||||
Console->HistoryNoDup = HistoryInfoRequest->dwFlags & HISTORY_NO_DUP_FLAG;
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
}
|
||||
return Status;
|
||||
#else
|
||||
DPRINT1("%s not yet implemented\n", __FUNCTION__);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
CSR_API(SrvSetConsoleCommandHistoryMode)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PCONSOLE_SETHISTORYMODE SetHistoryModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHistoryModeRequest;
|
||||
PCONSRV_CONSOLE Console;
|
||||
|
||||
DPRINT1("SrvSetConsoleCommandHistoryMode(Mode = %d) is not yet implemented\n",
|
||||
SetHistoryModeRequest->Mode);
|
||||
|
||||
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* This API is not yet implemented */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
ConSrvReleaseConsole(Console, TRUE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
/*
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Server DLL
|
||||
* FILE: win32ss/user/winsrv/consrv/lineinput.c
|
||||
* FILE: win32ss/user/winsrv/consrv/lineinput.h
|
||||
* PURPOSE: Console line input functions
|
||||
* PROGRAMMERS: Jeffrey Morlan
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
VOID HistoryDeleteBuffers(PCONSRV_CONSOLE Console);
|
||||
|
||||
VOID
|
||||
LineInputKeyDown(PCONSRV_CONSOLE Console,
|
||||
PUNICODE_STRING ExeName,
|
||||
|
|
251
reactos/win32ss/user/winsrv/consrv/popup.c
Normal file
251
reactos/win32ss/user/winsrv/consrv/popup.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Server DLL
|
||||
* FILE: win32ss/user/winsrv/consrv/popup.c
|
||||
* PURPOSE: Console popup windows
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*
|
||||
* NOTE: Strongly inspired by the DrawBox function
|
||||
* from base/setup/usetup/interface/usetup.c, written by:
|
||||
* Eric Kohl (revision 3753)
|
||||
* Hervé Poussineau (revision 24718)
|
||||
* and *UiDisplayMenu from FreeLdr.
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include "consrv.h"
|
||||
#include "popup.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ConDrvFillConsoleOutput(IN PCONSOLE Console,
|
||||
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
IN CODE_TYPE CodeType,
|
||||
IN CODE_ELEMENT Code,
|
||||
IN ULONG NumCodesToWrite,
|
||||
IN PCOORD WriteCoord,
|
||||
OUT PULONG NumCodesWritten OPTIONAL);
|
||||
NTSTATUS NTAPI
|
||||
ConDrvReadConsoleOutput(IN PCONSOLE Console,
|
||||
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
IN BOOLEAN Unicode,
|
||||
OUT PCHAR_INFO CharInfo/*Buffer*/,
|
||||
IN OUT PSMALL_RECT ReadRegion);
|
||||
NTSTATUS NTAPI
|
||||
ConDrvWriteConsoleOutput(IN PCONSOLE Console,
|
||||
IN PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
IN BOOLEAN Unicode,
|
||||
IN PCHAR_INFO CharInfo/*Buffer*/,
|
||||
IN OUT PSMALL_RECT WriteRegion);
|
||||
|
||||
|
||||
static VOID
|
||||
DrawBox(PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
IN SHORT xLeft,
|
||||
IN SHORT yTop,
|
||||
IN SHORT Width,
|
||||
IN SHORT Height)
|
||||
{
|
||||
COORD coPos;
|
||||
DWORD Written;
|
||||
|
||||
/* Set screen attributes */
|
||||
coPos.X = xLeft;
|
||||
for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
|
||||
{
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ATTRIBUTE,
|
||||
(CODE_ELEMENT)(WORD)Buffer->PopupDefaultAttrib,
|
||||
Width,
|
||||
&coPos,
|
||||
&Written);
|
||||
}
|
||||
|
||||
/* draw upper left corner */
|
||||
coPos.X = xLeft;
|
||||
coPos.Y = yTop;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xDA, // '+',
|
||||
1,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
/* draw upper edge */
|
||||
coPos.X = xLeft + 1;
|
||||
coPos.Y = yTop;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xC4, // '-',
|
||||
Width - 2,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
/* draw upper right corner */
|
||||
coPos.X = xLeft + Width - 1;
|
||||
coPos.Y = yTop;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xBF, // '+',
|
||||
1,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
/* Draw right edge, inner space and left edge */
|
||||
for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
|
||||
{
|
||||
coPos.X = xLeft;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xB3, // '|',
|
||||
1,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
coPos.X = xLeft + 1;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)' ',
|
||||
Width - 2,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
coPos.X = xLeft + Width - 1;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xB3, // '|',
|
||||
1,
|
||||
&coPos,
|
||||
&Written);
|
||||
}
|
||||
|
||||
/* draw lower left corner */
|
||||
coPos.X = xLeft;
|
||||
coPos.Y = yTop + Height - 1;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xC0, // '+',
|
||||
1,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
/* draw lower edge */
|
||||
coPos.X = xLeft + 1;
|
||||
coPos.Y = yTop + Height - 1;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xC4, // '-',
|
||||
Width - 2,
|
||||
&coPos,
|
||||
&Written);
|
||||
|
||||
/* draw lower right corner */
|
||||
coPos.X = xLeft + Width - 1;
|
||||
coPos.Y = yTop + Height - 1;
|
||||
ConDrvFillConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
CODE_ASCII,
|
||||
(CODE_ELEMENT)(CHAR)0xD9, // '+',
|
||||
1,
|
||||
&coPos,
|
||||
&Written);
|
||||
}
|
||||
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
PPOPUP_WINDOW
|
||||
CreatePopupWindow(PCONSRV_CONSOLE Console,
|
||||
PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
SHORT xLeft,
|
||||
SHORT yTop,
|
||||
SHORT Width,
|
||||
SHORT Height)
|
||||
{
|
||||
PPOPUP_WINDOW Popup;
|
||||
SMALL_RECT Region;
|
||||
|
||||
ASSERT((PCONSOLE)Console == Buffer->Header.Console);
|
||||
|
||||
/* Create the popup window */
|
||||
Popup = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Popup));
|
||||
if (Popup == NULL) return NULL;
|
||||
|
||||
Popup->ScreenBuffer = Buffer;
|
||||
Popup->Origin.X = xLeft;
|
||||
Popup->Origin.Y = yTop;
|
||||
Popup->Size.X = Width;
|
||||
Popup->Size.Y = Height;
|
||||
|
||||
/* Save old contents */
|
||||
Popup->OldContents = ConsoleAllocHeap(HEAP_ZERO_MEMORY,
|
||||
Popup->Size.X * Popup->Size.Y *
|
||||
sizeof(*Popup->OldContents));
|
||||
if (Popup->OldContents == NULL)
|
||||
{
|
||||
ConsoleFreeHeap(Popup);
|
||||
return NULL;
|
||||
}
|
||||
Region.Left = Popup->Origin.X;
|
||||
Region.Top = Popup->Origin.Y;
|
||||
Region.Right = Popup->Origin.X + Popup->Size.X - 1;
|
||||
Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1;
|
||||
ConDrvReadConsoleOutput(Buffer->Header.Console,
|
||||
Buffer,
|
||||
TRUE,
|
||||
Popup->OldContents,
|
||||
&Region);
|
||||
|
||||
/* Draw it */
|
||||
DrawBox(Buffer,
|
||||
xLeft, yTop,
|
||||
Width, Height);
|
||||
|
||||
/* Add it into the list of popups */
|
||||
InsertTailList(&Console->PopupWindows, &Popup->ListEntry);
|
||||
|
||||
return Popup;
|
||||
}
|
||||
|
||||
VOID
|
||||
DestroyPopupWindow(PPOPUP_WINDOW Popup)
|
||||
{
|
||||
SMALL_RECT Region;
|
||||
|
||||
if (Popup == NULL) return;
|
||||
|
||||
/* Remove it from the list of popups */
|
||||
RemoveEntryList(&Popup->ListEntry);
|
||||
|
||||
/* Restore the old screen-buffer contents */
|
||||
Region.Left = Popup->Origin.X;
|
||||
Region.Top = Popup->Origin.Y;
|
||||
Region.Right = Popup->Origin.X + Popup->Size.X - 1;
|
||||
Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1;
|
||||
ConDrvWriteConsoleOutput(Popup->ScreenBuffer->Header.Console,
|
||||
Popup->ScreenBuffer,
|
||||
TRUE,
|
||||
Popup->OldContents,
|
||||
&Region);
|
||||
|
||||
/* Free memory */
|
||||
ConsoleFreeHeap(Popup->OldContents);
|
||||
ConsoleFreeHeap(Popup);
|
||||
}
|
||||
|
||||
/* EOF */
|
37
reactos/win32ss/user/winsrv/consrv/popup.h
Normal file
37
reactos/win32ss/user/winsrv/consrv/popup.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Server DLL
|
||||
* FILE: win32ss/user/winsrv/consrv/popup.h
|
||||
* PURPOSE: Console popup windows
|
||||
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI *PPOPUP_INPUT_ROUTINE)(VOID);
|
||||
|
||||
typedef struct _POPUP_WINDOW
|
||||
{
|
||||
LIST_ENTRY ListEntry; /* Entry in console's list of popups */
|
||||
PTEXTMODE_SCREEN_BUFFER ScreenBuffer; /* Associated screen-buffer */
|
||||
|
||||
// SMALL_RECT Region; /* The region the popup occupies */
|
||||
COORD Origin; /* Origin of the popup window */
|
||||
COORD Size; /* Size of the popup window */
|
||||
|
||||
PCHAR_INFO OldContents; /* The data under the popup window */
|
||||
PPOPUP_INPUT_ROUTINE PopupInputRoutine; /* Routine called when input is received */
|
||||
} POPUP_WINDOW, *PPOPUP_WINDOW;
|
||||
|
||||
|
||||
PPOPUP_WINDOW
|
||||
CreatePopupWindow(PCONSRV_CONSOLE Console,
|
||||
PTEXTMODE_SCREEN_BUFFER Buffer,
|
||||
SHORT xLeft,
|
||||
SHORT yTop,
|
||||
SHORT Width,
|
||||
SHORT Height);
|
||||
VOID
|
||||
DestroyPopupWindow(PPOPUP_WINDOW Popup);
|
|
@ -9,14 +9,14 @@
|
|||
#pragma once
|
||||
|
||||
NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle,
|
||||
PCONSOLE_START_INFO ConsoleStartInfo);
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle,
|
||||
PCONSOLE_INIT_INFO ConsoleInitInfo);
|
||||
NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData,
|
||||
HANDLE ConsoleHandle,
|
||||
BOOLEAN CreateNewHandlesTable,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle);
|
||||
HANDLE ConsoleHandle,
|
||||
BOOLEAN CreateNewHandlesTable,
|
||||
PHANDLE pInputHandle,
|
||||
PHANDLE pOutputHandle,
|
||||
PHANDLE pErrorHandle);
|
||||
VOID ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData);
|
||||
|
|
|
@ -404,7 +404,7 @@ ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
|
|||
|
||||
ConsoleInfo->QuickEdit = FALSE;
|
||||
ConsoleInfo->InsertMode = TRUE;
|
||||
// ConsoleInfo->InputBufferSize;
|
||||
// ConsoleInfo->InputBufferSize = 0;
|
||||
|
||||
// Rule: ScreenBufferSize >= ConsoleSize
|
||||
ConsoleInfo->ScreenBufferSize.X = 80;
|
||||
|
|
Loading…
Reference in a new issue