[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:
Hermès Bélusca-Maïto 2014-09-10 00:08:04 +00:00
commit e393b80e07
71 changed files with 4178 additions and 2881 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 =

View file

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

View file

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

View file

@ -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,

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

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

View file

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

View file

@ -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"

View file

@ -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)

View file

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

View file

@ -38,6 +38,7 @@ typedef struct _GUI_CONSOLE_DATA
CRITICAL_SECTION Lock;
BOOL WindowSizeLock;
HANDLE hGuiInitEvent;
HANDLE hGuiTermEvent;
POINT OldCursor;

View file

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

View file

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

View file

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

View file

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

View file

@ -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"

View file

@ -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"

View file

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

View file

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

View file

@ -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"

View file

@ -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))
{

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

View 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);

View file

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

View file

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

View file

@ -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
{

View file

@ -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) \

View file

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

View file

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

View file

@ -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,

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

View 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);

View file

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

View file

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