ReactOS 0.4.15-dev-7842-g558ab78
console.c File Reference
#include "consrv.h"
#include <shlobj.h>
#include "../concfg/font.h"
#include <alias.h>
#include <history.h>
#include "procinit.h"
#include <debug.h>
Include dependency graph for console.c:

Go to the source code of this file.

Macros

#define COBJMACROS
 
#define NDEBUG
 
#define ConSrvLockConsoleListExclusive()    RtlAcquireResourceExclusive(&ListLock, TRUE)
 
#define ConSrvLockConsoleListShared()    RtlAcquireResourceShared(&ListLock, TRUE)
 
#define ConSrvUnlockConsoleList()    RtlReleaseResource(&ListLock)
 
#define CONSOLE_HANDLES_INCREMENT   2 * 3
 
#define PATH_SEPARATOR   L'\\'
 
#define CONSOLE_VALID_CONTROL_MODES
 

Functions

static NTSTATUS InsertConsole (OUT PHANDLE Handle, IN PCONSRV_CONSOLE Console)
 
static NTSTATUS RemoveConsoleByPointer (IN PCONSRV_CONSOLE Console)
 
static BOOLEAN ConsoleCreateUnicodeString (IN OUT PUNICODE_STRING UniDest, IN PCWSTR Source)
 
static VOID ConsoleFreeUnicodeString (IN PUNICODE_STRING UnicodeString)
 
BOOLEAN NTAPI ConSrvValidateConsole (OUT PCONSRV_CONSOLE *Console, IN HANDLE ConsoleHandle, IN CONSOLE_STATE ExpectedState, IN BOOLEAN LockConsole)
 
NTSTATUS ConSrvGetConsole (IN PCONSOLE_PROCESS_DATA ProcessData, OUT PCONSRV_CONSOLE *Console, IN BOOLEAN LockConsole)
 
VOID ConSrvReleaseConsole (IN PCONSRV_CONSOLE Console, IN BOOLEAN IsConsoleLocked)
 
VOID NTAPI ConSrvInitConsoleSupport (VOID)
 
NTSTATUS NTAPI ConSrvInitTerminal (IN OUT PTERMINAL Terminal, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
 
NTSTATUS NTAPI ConSrvDeinitTerminal (IN OUT PTERMINAL Terminal)
 
static BOOL LoadShellLinkConsoleInfo (IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
 
NTSTATUS NTAPI ConSrvInitConsole (OUT PHANDLE NewConsoleHandle, OUT PCONSRV_CONSOLE *NewConsole, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN PCSR_PROCESS ConsoleLeaderProcess)
 
VOID NTAPI ConSrvDeleteConsole (PCONSRV_CONSOLE Console)
 
VOID ConioPause (PCONSRV_CONSOLE Console, UCHAR Flags)
 
VOID ConioUnpause (PCONSRV_CONSOLE Console, UCHAR Flags)
 
static NTSTATUS ConSrvInitProcessHandles (IN OUT PCONSOLE_PROCESS_DATA ProcessData, IN PCONSRV_CONSOLE Console, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle)
 
NTSTATUS ConSrvAllocateConsole (IN OUT PCONSOLE_PROCESS_DATA ProcessData, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
 
NTSTATUS ConSrvInheritConsole (IN OUT PCONSOLE_PROCESS_DATA ProcessData, IN HANDLE ConsoleHandle, IN BOOLEAN CreateNewHandleTable, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle, IN OUT PCONSOLE_START_INFO ConsoleStartInfo)
 
NTSTATUS ConSrvRemoveConsole (IN OUT PCONSOLE_PROCESS_DATA ProcessData)
 
NTSTATUS ConSrvConsoleCtrlEventTimeout (IN ULONG CtrlEvent, IN PCONSOLE_PROCESS_DATA ProcessData, IN ULONG Timeout)
 
NTSTATUS ConSrvConsoleCtrlEvent (IN ULONG CtrlEvent, IN PCONSOLE_PROCESS_DATA ProcessData)
 
PCONSOLE_PROCESS_DATA NTAPI ConSrvGetConsoleLeaderProcess (IN PCONSRV_CONSOLE Console)
 
NTSTATUS NTAPI ConSrvGetConsoleProcessList (IN PCONSRV_CONSOLE Console, IN OUT PULONG ProcessIdsList, IN ULONG MaxIdListItems, OUT PULONG ProcessIdsTotal)
 
NTSTATUS NTAPI ConSrvConsoleProcessCtrlEvent (IN PCONSRV_CONSOLE Console, IN ULONG ProcessGroupId, IN ULONG CtrlEvent)
 
VOID ConSrvSetProcessFocus (IN PCSR_PROCESS CsrProcess, IN BOOLEAN SetForeground)
 
NTSTATUS NTAPI ConSrvSetConsoleProcessFocus (IN PCONSRV_CONSOLE Console, IN BOOLEAN SetForeground)
 
 CON_API_NOCONSOLE (SrvAllocConsole, CONSOLE_ALLOCCONSOLE, AllocConsoleRequest)
 
 CON_API_NOCONSOLE (SrvAttachConsole, CONSOLE_ATTACHCONSOLE, AttachConsoleRequest)
 
 CON_API_NOCONSOLE (SrvFreeConsole, CONSOLE_FREECONSOLE, FreeConsoleRequest)
 
NTSTATUS NTAPI ConDrvGetConsoleMode (IN PCONSOLE Console, IN PCONSOLE_IO_OBJECT Object, OUT PULONG ConsoleMode)
 
 CON_API (SrvGetConsoleMode, CONSOLE_GETSETCONSOLEMODE, ConsoleModeRequest)
 
NTSTATUS NTAPI ConDrvSetConsoleMode (IN PCONSOLE Console, IN PCONSOLE_IO_OBJECT Object, IN ULONG ConsoleMode)
 
 CON_API (SrvSetConsoleMode, CONSOLE_GETSETCONSOLEMODE, ConsoleModeRequest)
 
 CON_API (SrvGetConsoleTitle, CONSOLE_GETSETCONSOLETITLE, TitleRequest)
 
 CON_API (SrvSetConsoleTitle, CONSOLE_GETSETCONSOLETITLE, TitleRequest)
 
NTSTATUS NTAPI ConDrvGetConsoleCP (IN PCONSOLE Console, OUT PUINT CodePage, IN BOOLEAN OutputCP)
 
 CON_API (SrvGetConsoleCP, CONSOLE_GETINPUTOUTPUTCP, GetConsoleCPRequest)
 
NTSTATUS NTAPI ConDrvSetConsoleCP (IN PCONSOLE Console, IN UINT CodePage, IN BOOLEAN OutputCP)
 
 CON_API (SrvSetConsoleCP, CONSOLE_SETINPUTOUTPUTCP, SetConsoleCPRequest)
 
 CON_API (SrvGetConsoleProcessList, CONSOLE_GETPROCESSLIST, GetProcessListRequest)
 
 CON_API (SrvGenerateConsoleCtrlEvent, CONSOLE_GENERATECTRLEVENT, GenerateCtrlEventRequest)
 
 CON_API (SrvConsoleNotifyLastClose, CONSOLE_NOTIFYLASTCLOSE, NotifyLastCloseRequest)
 
 CON_API (SrvGetConsoleMouseInfo, CONSOLE_GETMOUSEINFO, GetMouseInfoRequest)
 
 CSR_API (SrvSetConsoleKeyShortcuts)
 
 CON_API (SrvGetConsoleKeyboardLayoutName, CONSOLE_GETKBDLAYOUTNAME, GetKbdLayoutNameRequest)
 
 CSR_API (SrvGetConsoleCharType)
 
 CSR_API (SrvSetConsoleLocalEUDC)
 
 CSR_API (SrvSetConsoleCursorMode)
 
 CSR_API (SrvGetConsoleCursorMode)
 
 CSR_API (SrvGetConsoleNlsMode)
 
 CSR_API (SrvSetConsoleNlsMode)
 
 CON_API (SrvGetConsoleLangId, CONSOLE_GETLANGID, LangIdRequest)
 

Variables

static ULONG ConsoleListSize
 
static PCONSRV_CONSOLEConsoleList
 
static RTL_RESOURCE ListLock
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 16 of file console.c.

◆ CONSOLE_HANDLES_INCREMENT

#define CONSOLE_HANDLES_INCREMENT   2 * 3

◆ CONSOLE_VALID_CONTROL_MODES

#define CONSOLE_VALID_CONTROL_MODES
Value:
#define ENABLE_QUICK_EDIT_MODE
Definition: wincon.h:84
#define ENABLE_EXTENDED_FLAGS
Definition: wincon.h:85
#define ENABLE_INSERT_MODE
Definition: wincon.h:83

◆ ConSrvLockConsoleListExclusive

#define ConSrvLockConsoleListExclusive ( )     RtlAcquireResourceExclusive(&ListLock, TRUE)

Definition at line 38 of file console.c.

◆ ConSrvLockConsoleListShared

#define ConSrvLockConsoleListShared ( )     RtlAcquireResourceShared(&ListLock, TRUE)

Definition at line 41 of file console.c.

◆ ConSrvUnlockConsoleList

#define ConSrvUnlockConsoleList ( )     RtlReleaseResource(&ListLock)

Definition at line 44 of file console.c.

◆ NDEBUG

#define NDEBUG

Definition at line 24 of file console.c.

◆ PATH_SEPARATOR

#define PATH_SEPARATOR   L'\\'

Function Documentation

◆ CON_API() [1/12]

CON_API ( SrvConsoleNotifyLastClose  ,
CONSOLE_NOTIFYLASTCLOSE  ,
NotifyLastCloseRequest   
)

Definition at line 1933 of file console.c.

1935{
1936 /* Only one process is allowed to be registered for last close notification */
1937 if (Console->NotifyLastClose)
1938 return STATUS_ACCESS_DENIED;
1939
1940 Console->NotifyLastClose = TRUE;
1941 Console->NotifiedLastCloseProcess = ProcessData;
1942 return STATUS_SUCCESS;
1943}
CConsole Console
#define TRUE
Definition: types.h:120
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

◆ CON_API() [2/12]

CON_API ( SrvGenerateConsoleCtrlEvent  ,
CONSOLE_GENERATECTRLEVENT  ,
GenerateCtrlEventRequest   
)

Definition at line 1924 of file console.c.

1926{
1928 GenerateCtrlEventRequest->ProcessGroupId,
1929 GenerateCtrlEventRequest->CtrlEvent);
1930}
NTSTATUS NTAPI ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console, IN ULONG ProcessGroupId, IN ULONG CtrlEvent)
Definition: console.c:1402

◆ CON_API() [3/12]

CON_API ( SrvGetConsoleCP  ,
CONSOLE_GETINPUTOUTPUTCP  ,
GetConsoleCPRequest   
)

Definition at line 1878 of file console.c.

1880{
1881 DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
1882 GetConsoleCPRequest->OutputCP ? "Output" : "Input");
1883
1885 &GetConsoleCPRequest->CodePage,
1886 GetConsoleCPRequest->OutputCP);
1887}
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI ConDrvGetConsoleCP(IN PCONSOLE Console, OUT PUINT CodePage, IN BOOLEAN OutputCP)
Definition: console.c:411

◆ CON_API() [4/12]

CON_API ( SrvGetConsoleKeyboardLayoutName  ,
CONSOLE_GETKBDLAYOUTNAME  ,
GetKbdLayoutNameRequest   
)

Definition at line 1962 of file console.c.

1964{
1965 /* Retrieve the keyboard layout name of the system */
1966 if (GetKbdLayoutNameRequest->Ansi)
1967 GetKeyboardLayoutNameA((PCHAR)GetKbdLayoutNameRequest->LayoutBuffer);
1968 else
1969 GetKeyboardLayoutNameW((PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer);
1970
1971 return STATUS_SUCCESS;
1972}
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
BOOL WINAPI GetKeyboardLayoutNameW(_Out_writes_(KL_NAMELENGTH) LPWSTR)
BOOL WINAPI GetKeyboardLayoutNameA(_Out_writes_(KL_NAMELENGTH) LPSTR)

◆ CON_API() [5/12]

CON_API ( SrvGetConsoleLangId  ,
CONSOLE_GETLANGID  ,
LangIdRequest   
)

ReactOS-specific: do nothing if the code page is UTF-8. This will allow programs to naturally output in whatever current language they are.

End ReactOS-specific

Definition at line 2017 of file console.c.

2019{
2020 /*
2021 * Quoting MS Terminal, see function GetConsoleLangId() at
2022 * https://github.com/microsoft/terminal/blob/main/src/host/srvinit.cpp#L655
2023 * "Only attempt to return the Lang ID if the Windows ACP on console
2024 * launch was an East Asian Code Page."
2025 *
2026 * The underlying logic is as follows:
2027 *
2028 * - When the current user's UI language is *not* CJK, the user expects
2029 * to not see any CJK output to the console by default, even if its
2030 * output has been set to a CJK code page (this is possible when CJK
2031 * fonts are installed on the system). That is, of course, unless if
2032 * the attached console program chooses to actually output CJK text.
2033 * Whatever current language of the running program's thread should
2034 * be kept: STATUS_NOT_SUPPORTED is returned.
2035 *
2036 * - When the current user's UI language *is* CJK, the user expects to
2037 * see CJK output to the console by default when its code page is CJK.
2038 * A valid LangId is returned in this case to ensure this.
2039 * However, if the console code page is not CJK, then it is evident
2040 * that CJK text will not be able to be correctly shown, and therefore
2041 * we should fall back to a standard language that can be shown, namely
2042 * en-US english, instead of keeping the current language.
2043 */
2044
2045 BYTE UserCharSet = CodePageToCharSet(GetACP());
2046 if (!IsCJKCharSet(UserCharSet))
2047 return STATUS_NOT_SUPPORTED;
2048
2049 /* Return a "best-suited" language ID corresponding
2050 * to the active console output code page. */
2051 switch (Console->OutputCodePage)
2052 {
2055 case CP_UTF8:
2056 return STATUS_NOT_SUPPORTED;
2058 case CP_JAPANESE:
2059 LangIdRequest->LangId = MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT);
2060 break;
2061 case CP_KOREAN:
2062 LangIdRequest->LangId = MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
2063 break;
2065 LangIdRequest->LangId = MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
2066 break;
2068 LangIdRequest->LangId = MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
2069 break;
2070 default:
2071 /* Default to en-US english otherwise */
2072 LangIdRequest->LangId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
2073 break;
2074 }
2075
2076 return STATUS_SUCCESS;
2077}
#define IsCJKCharSet(CharSet)
Definition: cjkcode.h:44
#define CP_CHINESE_SIMPLIFIED
Definition: cjkcode.h:23
#define CP_JAPANESE
Definition: cjkcode.h:21
#define CP_CHINESE_TRADITIONAL
Definition: cjkcode.h:24
#define CP_KOREAN
Definition: cjkcode.h:22
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_ENGLISH
Definition: nls.h:52
#define SUBLANG_CHINESE_TRADITIONAL
Definition: nls.h:208
#define SUBLANG_CHINESE_SIMPLIFIED
Definition: nls.h:209
#define SUBLANG_DEFAULT
Definition: nls.h:168
#define LANG_CHINESE
Definition: nls.h:42
#define CP_UTF8
Definition: nls.h:20
#define LANG_JAPANESE
Definition: nls.h:76
#define LANG_KOREAN
Definition: nls.h:84
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
#define SUBLANG_KOREAN
Definition: nls.h:280
BYTE CodePageToCharSet(_In_ UINT CodePage)
Retrieves the character set associated with a given code page.
Definition: font.c:51
UINT WINAPI GetACP(void)
Definition: nls.c:2307
unsigned char BYTE
Definition: xxhash.c:193

◆ CON_API() [6/12]

CON_API ( SrvGetConsoleMode  ,
CONSOLE_GETSETCONSOLEMODE  ,
ConsoleModeRequest   
)

Definition at line 1660 of file console.c.

1662{
1665 PULONG ConsoleMode = &ConsoleModeRequest->Mode;
1666
1667 Status = ConSrvGetObject(ProcessData,
1668 ConsoleModeRequest->Handle,
1669 &Object, NULL, GENERIC_READ, TRUE, 0);
1670 if (!NT_SUCCESS(Status))
1671 return Status;
1672
1673 ASSERT((PCONSOLE)Console == Object->Console);
1674
1675 /* Get the standard console modes */
1677 if (NT_SUCCESS(Status))
1678 {
1679 /*
1680 * If getting the console modes succeeds, then retrieve
1681 * the extended CONSRV-specific input modes.
1682 */
1683 if (INPUT_BUFFER == Object->Type)
1684 {
1685 if (Console->InsertMode || Console->QuickEdit)
1686 {
1687 /* Windows also adds ENABLE_EXTENDED_FLAGS, even if it's not documented on MSDN */
1688 *ConsoleMode |= ENABLE_EXTENDED_FLAGS;
1689
1690 if (Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE;
1691 if (Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE;
1692 }
1693 }
1694 }
1695
1697 return Status;
1698}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define GENERIC_READ
Definition: compat.h:135
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
NTSTATUS NTAPI ConDrvGetConsoleMode(IN PCONSOLE Console, IN PCONSOLE_IO_OBJECT Object, OUT PULONG ConsoleMode)
Definition: console.c:324
NTSTATUS ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData, IN HANDLE Handle, OUT PCONSOLE_IO_OBJECT *Object, OUT PVOID *Entry OPTIONAL, IN ULONG Access, IN BOOLEAN LockConsole, IN CONSOLE_IO_OBJECT_TYPE Type)
Definition: handle.c:318
VOID ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object, IN BOOLEAN IsConsoleLocked)
Definition: handle.c:382
@ INPUT_BUFFER
Definition: conio.h:28

◆ CON_API() [7/12]

CON_API ( SrvGetConsoleMouseInfo  ,
CONSOLE_GETMOUSEINFO  ,
GetMouseInfoRequest   
)

Definition at line 1946 of file console.c.

1948{
1949 /* Just retrieve the number of buttons of the mouse attached to this console */
1950 GetMouseInfoRequest->NumButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
1951 return STATUS_SUCCESS;
1952}
#define SM_CMOUSEBUTTONS
Definition: winuser.h:1006
int WINAPI GetSystemMetrics(_In_ int)

◆ CON_API() [8/12]

CON_API ( SrvGetConsoleProcessList  ,
CONSOLE_GETPROCESSLIST  ,
GetProcessListRequest   
)

Definition at line 1906 of file console.c.

1908{
1909 if (!CsrValidateMessageBuffer(ApiMessage,
1910 (PVOID)&GetProcessListRequest->ProcessIdsList,
1911 GetProcessListRequest->ProcessCount,
1912 sizeof(DWORD)))
1913 {
1915 }
1916
1918 GetProcessListRequest->ProcessIdsList,
1919 GetProcessListRequest->ProcessCount,
1920 &GetProcessListRequest->ProcessCount);
1921}
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI ConSrvGetConsoleProcessList(IN PCONSRV_CONSOLE Console, IN OUT PULONG ProcessIdsList, IN ULONG MaxIdListItems, OUT PULONG ProcessIdsTotal)
Definition: console.c:1373

◆ CON_API() [9/12]

CON_API ( SrvGetConsoleTitle  ,
CONSOLE_GETSETCONSOLETITLE  ,
TitleRequest   
)

Definition at line 1761 of file console.c.

1763{
1764 ULONG Length;
1765
1766 if (!CsrValidateMessageBuffer(ApiMessage,
1767 (PVOID)&TitleRequest->Title,
1768 TitleRequest->Length,
1769 sizeof(BYTE)))
1770 {
1772 }
1773
1774 /* Copy title of the console to the user title buffer */
1775 if (TitleRequest->Unicode)
1776 {
1777 if (TitleRequest->Length >= sizeof(WCHAR))
1778 {
1779 Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
1780 RtlCopyMemory(TitleRequest->Title, Console->Title.Buffer, Length);
1781 ((PWCHAR)TitleRequest->Title)[Length / sizeof(WCHAR)] = UNICODE_NULL;
1782 TitleRequest->Length = Length;
1783 }
1784 else
1785 {
1786 TitleRequest->Length = Console->Title.Length;
1787 }
1788 }
1789 else
1790 {
1791 if (TitleRequest->Length >= sizeof(CHAR))
1792 {
1793 Length = min(TitleRequest->Length - sizeof(CHAR), Console->Title.Length / sizeof(WCHAR));
1794 Length = WideCharToMultiByte(Console->InputCodePage, 0,
1795 Console->Title.Buffer, Length,
1796 TitleRequest->Title, Length,
1797 NULL, NULL);
1798 ((PCHAR)TitleRequest->Title)[Length] = ANSI_NULL;
1799 TitleRequest->Length = Length;
1800 }
1801 else
1802 {
1803 TitleRequest->Length = Console->Title.Length / sizeof(WCHAR);
1804 }
1805 }
1806
1807 return STATUS_SUCCESS;
1808}
#define WideCharToMultiByte
Definition: compat.h:111
#define PCHAR
Definition: match.c:90
#define min(a, b)
Definition: monoChain.cc:55
#define UNICODE_NULL
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175

◆ CON_API() [10/12]

CON_API ( SrvSetConsoleCP  ,
CONSOLE_SETINPUTOUTPUTCP  ,
SetConsoleCPRequest   
)

Definition at line 1894 of file console.c.

1896{
1897 DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
1898 SetConsoleCPRequest->OutputCP ? "Output" : "Input");
1899
1901 SetConsoleCPRequest->CodePage,
1902 SetConsoleCPRequest->OutputCP);
1903}
NTSTATUS NTAPI ConDrvSetConsoleCP(IN PCONSOLE Console, IN UINT CodePage, IN BOOLEAN OutputCP)
Definition: console.c:424

◆ CON_API() [11/12]

CON_API ( SrvSetConsoleMode  ,
CONSOLE_GETSETCONSOLEMODE  ,
ConsoleModeRequest   
)

Definition at line 1705 of file console.c.

1707{
1708#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | \
1709 ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE )
1710// NOTE: Vista+ ENABLE_AUTO_POSITION is also a control mode.
1711
1714 ULONG ConsoleMode = ConsoleModeRequest->Mode;
1715
1716 Status = ConSrvGetObject(ProcessData,
1717 ConsoleModeRequest->Handle,
1718 &Object, NULL, GENERIC_WRITE, TRUE, 0);
1719 if (!NT_SUCCESS(Status))
1720 return Status;
1721
1722 ASSERT((PCONSOLE)Console == Object->Console);
1723
1724 /* Set the standard console modes (without the CONSRV-specific input modes) */
1725 ConsoleMode &= ~CONSOLE_VALID_CONTROL_MODES; // Remove CONSRV-specific input modes.
1727 if (NT_SUCCESS(Status))
1728 {
1729 /*
1730 * If setting the console modes succeeds, then set
1731 * the extended CONSRV-specific input modes.
1732 */
1733 if (INPUT_BUFFER == Object->Type)
1734 {
1735 ConsoleMode = ConsoleModeRequest->Mode;
1736
1737 if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES)
1738 {
1739 /*
1740 * If we use control mode flags without ENABLE_EXTENDED_FLAGS,
1741 * then consider the flags invalid.
1742 */
1743 if ((ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0)
1744 {
1746 }
1747 else
1748 {
1749 Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE);
1750 Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE);
1751 }
1752 }
1753 }
1754 }
1755
1757 return Status;
1758}
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSTATUS NTAPI ConDrvSetConsoleMode(IN PCONSOLE Console, IN PCONSOLE_IO_OBJECT Object, IN ULONG ConsoleMode)
Definition: console.c:357
#define CONSOLE_VALID_CONTROL_MODES

◆ CON_API() [12/12]

CON_API ( SrvSetConsoleTitle  ,
CONSOLE_GETSETCONSOLETITLE  ,
TitleRequest   
)

Definition at line 1811 of file console.c.

1813{
1814 PWCHAR Buffer;
1815 ULONG Length;
1816
1817 if (!CsrValidateMessageBuffer(ApiMessage,
1818 (PVOID)&TitleRequest->Title,
1819 TitleRequest->Length,
1820 sizeof(BYTE)))
1821 {
1823 }
1824
1825 if (TitleRequest->Unicode)
1826 {
1827 /* Length is in bytes */
1828 Length = TitleRequest->Length;
1829 }
1830 else
1831 {
1832 /* Use the console input CP for the conversion */
1833 Length = MultiByteToWideChar(Console->InputCodePage, 0,
1834 TitleRequest->Title, TitleRequest->Length,
1835 NULL, 0);
1836 /* The returned Length was in number of wchars, convert it in bytes */
1837 Length *= sizeof(WCHAR);
1838 }
1839
1840 /* Allocate a new buffer to hold the new title (NULL-terminated) */
1842 if (!Buffer)
1843 return STATUS_NO_MEMORY;
1844
1845 /* Free the old title */
1847
1848 /* Copy title to console */
1849 Console->Title.Buffer = Buffer;
1850 Console->Title.Length = Length;
1851 Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR);
1852
1853 if (TitleRequest->Unicode)
1854 {
1855 RtlCopyMemory(Console->Title.Buffer, TitleRequest->Title, Console->Title.Length);
1856 }
1857 else
1858 {
1859 MultiByteToWideChar(Console->InputCodePage, 0,
1860 TitleRequest->Title, TitleRequest->Length,
1861 Console->Title.Buffer,
1862 Console->Title.Length / sizeof(WCHAR));
1863 }
1864
1865 /* NULL-terminate */
1866 Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = UNICODE_NULL;
1867
1869
1870 return STATUS_SUCCESS;
1871}
Definition: bufpool.h:45
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define TermChangeTitle(Console)
Definition: term.h:48
static VOID ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
Definition: console.c:234
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14

◆ CON_API_NOCONSOLE() [1/3]

CON_API_NOCONSOLE ( SrvAllocConsole  ,
CONSOLE_ALLOCCONSOLE  ,
AllocConsoleRequest   
)

Definition at line 1483 of file console.c.

1485{
1487 CONSOLE_INIT_INFO ConsoleInitInfo;
1488
1489 if (ProcessData->ConsoleHandle != NULL)
1490 {
1491 DPRINT1("Process already has a console\n");
1492 return STATUS_ACCESS_DENIED;
1493 }
1494
1495 if ( !CsrValidateMessageBuffer(ApiMessage,
1496 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo,
1497 1,
1498 sizeof(CONSOLE_START_INFO)) ||
1499 !CsrValidateMessageBuffer(ApiMessage,
1500 (PVOID*)&AllocConsoleRequest->ConsoleTitle,
1501 AllocConsoleRequest->TitleLength,
1502 sizeof(BYTE)) ||
1503 !CsrValidateMessageBuffer(ApiMessage,
1504 (PVOID*)&AllocConsoleRequest->Desktop,
1505 AllocConsoleRequest->DesktopLength,
1506 sizeof(BYTE)) ||
1507 !CsrValidateMessageBuffer(ApiMessage,
1508 (PVOID*)&AllocConsoleRequest->CurDir,
1509 AllocConsoleRequest->CurDirLength,
1510 sizeof(BYTE)) ||
1511 !CsrValidateMessageBuffer(ApiMessage,
1512 (PVOID*)&AllocConsoleRequest->AppName,
1513 AllocConsoleRequest->AppNameLength,
1514 sizeof(BYTE)) )
1515 {
1517 }
1518
1519 /* Initialize the console initialization info structure */
1520 ConsoleInitInfo.ConsoleStartInfo = AllocConsoleRequest->ConsoleStartInfo;
1521 ConsoleInitInfo.IsWindowVisible = TRUE; // The console window is always visible.
1522 ConsoleInitInfo.TitleLength = AllocConsoleRequest->TitleLength;
1523 ConsoleInitInfo.ConsoleTitle = AllocConsoleRequest->ConsoleTitle;
1524 ConsoleInitInfo.DesktopLength = AllocConsoleRequest->DesktopLength;
1525 ConsoleInitInfo.Desktop = AllocConsoleRequest->Desktop;
1526 ConsoleInitInfo.AppNameLength = AllocConsoleRequest->AppNameLength;
1527 ConsoleInitInfo.AppName = AllocConsoleRequest->AppName;
1528 ConsoleInitInfo.CurDirLength = AllocConsoleRequest->CurDirLength;
1529 ConsoleInitInfo.CurDir = AllocConsoleRequest->CurDir;
1530
1531 /* Initialize a new Console owned by the Console Leader Process */
1532 Status = ConSrvAllocateConsole(ProcessData,
1533 &AllocConsoleRequest->ConsoleStartInfo->InputHandle,
1534 &AllocConsoleRequest->ConsoleStartInfo->OutputHandle,
1535 &AllocConsoleRequest->ConsoleStartInfo->ErrorHandle,
1536 &ConsoleInitInfo);
1537 if (!NT_SUCCESS(Status))
1538 {
1539 DPRINT1("Console allocation failed\n");
1540 return Status;
1541 }
1542
1543 /* Set the Property-Dialog and Control-Dispatcher handlers */
1544 ProcessData->PropRoutine = AllocConsoleRequest->PropRoutine;
1545 ProcessData->CtrlRoutine = AllocConsoleRequest->CtrlRoutine;
1546
1547 return STATUS_SUCCESS;
1548}
#define DPRINT1
Definition: precomp.h:8
ULONG CurDirLength
Definition: console.h:22
ULONG DesktopLength
Definition: console.h:18
ULONG TitleLength
Definition: console.h:16
PCONSOLE_START_INFO ConsoleStartInfo
Definition: console.h:13
BOOLEAN IsWindowVisible
Definition: console.h:14
PWCHAR ConsoleTitle
Definition: console.h:17
ULONG AppNameLength
Definition: console.h:20
PWCHAR Desktop
Definition: console.h:19
PWCHAR AppName
Definition: console.h:21
NTSTATUS ConSrvAllocateConsole(IN OUT PCONSOLE_PROCESS_DATA ProcessData, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
Definition: console.c:968

◆ CON_API_NOCONSOLE() [2/3]

CON_API_NOCONSOLE ( SrvAttachConsole  ,
CONSOLE_ATTACHCONSOLE  ,
AttachConsoleRequest   
)

Definition at line 1551 of file console.c.

1553{
1555 PCSR_PROCESS SourceProcess = NULL; // The parent process.
1556 PCSR_PROCESS TargetProcess = CsrGetClientThread()->Process; // Ourselves.
1557 HANDLE ProcessId = ULongToHandle(AttachConsoleRequest->ProcessId);
1558 PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData;
1559
1560 TargetProcessData = ConsoleGetPerProcessData(TargetProcess);
1561
1562 if (TargetProcessData->ConsoleHandle != NULL)
1563 {
1564 DPRINT1("Process already has a console\n");
1565 return STATUS_ACCESS_DENIED;
1566 }
1567
1568 if (!CsrValidateMessageBuffer(ApiMessage,
1569 (PVOID*)&AttachConsoleRequest->ConsoleStartInfo,
1570 1,
1571 sizeof(CONSOLE_START_INFO)))
1572 {
1574 }
1575
1576 /* Check whether we try to attach to the parent's console */
1578 {
1579 PROCESS_BASIC_INFORMATION ProcessInfo;
1580 ULONG Length = sizeof(ProcessInfo);
1581
1582 /* Get the real parent's PID */
1583
1586 &ProcessInfo,
1587 Length, &Length);
1588 if (!NT_SUCCESS(Status))
1589 {
1590 DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = 0x%08lx\n", Status);
1591 return Status;
1592 }
1593
1595 }
1596
1597 /* Lock the source process via its PID */
1598 Status = CsrLockProcessByClientId(ProcessId, &SourceProcess);
1599 if (!NT_SUCCESS(Status)) return Status;
1600
1601 SourceProcessData = ConsoleGetPerProcessData(SourceProcess);
1602
1603 if (SourceProcessData->ConsoleHandle == NULL)
1604 {
1606 goto Quit;
1607 }
1608
1609 /*
1610 * Inherit the console from the parent,
1611 * if any, otherwise return an error.
1612 */
1613 Status = ConSrvInheritConsole(TargetProcessData,
1614 SourceProcessData->ConsoleHandle,
1615 TRUE,
1616 &AttachConsoleRequest->ConsoleStartInfo->InputHandle,
1617 &AttachConsoleRequest->ConsoleStartInfo->OutputHandle,
1618 &AttachConsoleRequest->ConsoleStartInfo->ErrorHandle,
1619 AttachConsoleRequest->ConsoleStartInfo);
1620 if (!NT_SUCCESS(Status))
1621 {
1622 DPRINT1("Console inheritance failed\n");
1623 goto Quit;
1624 }
1625
1626 /* Set the Property-Dialog and Control-Dispatcher handlers */
1627 TargetProcessData->PropRoutine = AttachConsoleRequest->PropRoutine;
1628 TargetProcessData->CtrlRoutine = AttachConsoleRequest->CtrlRoutine;
1629
1631
1632Quit:
1633 /* Unlock the "source" process and exit */
1634 CsrUnlockProcess(SourceProcess);
1635 return Status;
1636}
#define ULongToHandle(h)
Definition: basetsd.h:81
#define ConsoleGetPerProcessData(Process)
Definition: consrv.h:37
NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:1410
#define CsrGetClientThread()
Definition: csrsrv.h:77
NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSR_PROCESS *CsrProcess OPTIONAL)
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2711
@ ProcessBasicInformation
Definition: winternl.h:394
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
HANDLE ConsoleHandle
Definition: consrv.h:45
LPTHREAD_START_ROUTINE CtrlRoutine
Definition: consrv.h:52
LPTHREAD_START_ROUTINE PropRoutine
Definition: consrv.h:53
HANDLE ProcessHandle
Definition: csrsrv.h:46
ULONG_PTR InheritedFromUniqueProcessId
Definition: pstypes.h:340
NTSTATUS ConSrvInheritConsole(IN OUT PCONSOLE_PROCESS_DATA ProcessData, IN HANDLE ConsoleHandle, IN BOOLEAN CreateNewHandleTable, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle, IN OUT PCONSOLE_START_INFO ConsoleStartInfo)
Definition: console.c:1096
#define ATTACH_PARENT_PROCESS
Definition: wincon.h:21

◆ CON_API_NOCONSOLE() [3/3]

CON_API_NOCONSOLE ( SrvFreeConsole  ,
CONSOLE_FREECONSOLE  ,
FreeConsoleRequest   
)

Definition at line 1639 of file console.c.

1641{
1642 /*
1643 * If this process doesn't have a console handle, bail out immediately.
1644 * Also the passed console handle should be the same as the process' one.
1645 */
1646 if ((FreeConsoleRequest->ConsoleHandle == NULL) ||
1647 (FreeConsoleRequest->ConsoleHandle != ProcessData->ConsoleHandle))
1648 {
1649 return STATUS_INVALID_HANDLE; // STATUS_ACCESS_DENIED;
1650 }
1651
1652 return ConSrvRemoveConsole(ProcessData);
1653}
NTSTATUS ConSrvRemoveConsole(IN OUT PCONSOLE_PROCESS_DATA ProcessData)
Definition: console.c:1227

◆ ConDrvGetConsoleCP()

NTSTATUS NTAPI ConDrvGetConsoleCP ( IN PCONSOLE  Console,
OUT PUINT  CodePage,
IN BOOLEAN  OutputCP 
)

Definition at line 411 of file console.c.

414{
415 if (Console == NULL || CodePage == NULL)
417
418 *CodePage = (OutputCP ? Console->OutputCodePage : Console->InputCodePage);
419
420 return STATUS_SUCCESS;
421}

Referenced by CON_API().

◆ ConDrvGetConsoleMode()

NTSTATUS NTAPI ConDrvGetConsoleMode ( IN PCONSOLE  Console,
IN PCONSOLE_IO_OBJECT  Object,
OUT PULONG  ConsoleMode 
)

Definition at line 324 of file console.c.

327{
329
330 if (Console == NULL || Object == NULL || ConsoleMode == NULL)
332
333 /* Validity check */
334 ASSERT(Console == Object->Console);
335
336 /*** FIXME: */ *ConsoleMode = 0; /***/
337
338 if (INPUT_BUFFER == Object->Type)
339 {
341 *ConsoleMode = InputBuffer->Mode;
342 }
343 else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
344 {
346 *ConsoleMode = Buffer->Mode;
347 }
348 else
349 {
351 }
352
353 return Status;
354}
#define TEXTMODE_BUFFER
Definition: pccons.c:21
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
struct _CONSOLE_INPUT_BUFFER * PCONSOLE_INPUT_BUFFER
@ GRAPHICS_BUFFER
Definition: conio.h:26
struct _CONSOLE_SCREEN_BUFFER * PCONSOLE_SCREEN_BUFFER

Referenced by CON_API().

◆ ConDrvSetConsoleCP()

NTSTATUS NTAPI ConDrvSetConsoleCP ( IN PCONSOLE  Console,
IN UINT  CodePage,
IN BOOLEAN  OutputCP 
)

Definition at line 424 of file console.c.

427{
428 if (Console == NULL || !IsValidCodePage(CodePage))
430
431 if (OutputCP)
432 {
433 /* Request the terminal to change its code page support */
434 if (!TermSetCodePage(Console, CodePage))
435 return STATUS_UNSUCCESSFUL;
436
437 /* All is fine, actually set the output code page */
438 CON_SET_OUTPUT_CP(Console, CodePage);
439 return STATUS_SUCCESS;
440 }
441 else
442 {
443 Console->InputCodePage = CodePage;
444 return STATUS_SUCCESS;
445 }
446}
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
#define TermSetCodePage(Console, CodePage)
Definition: term.h:38
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define CON_SET_OUTPUT_CP(Console, CodePage)
Definition: conio.h:323

Referenced by CON_API().

◆ ConDrvSetConsoleMode()

NTSTATUS NTAPI ConDrvSetConsoleMode ( IN PCONSOLE  Console,
IN PCONSOLE_IO_OBJECT  Object,
IN ULONG  ConsoleMode 
)

Definition at line 357 of file console.c.

360{
361#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \
362 ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \
363 ENABLE_MOUSE_INPUT )
364#define CONSOLE_VALID_OUTPUT_MODES ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT )
365
367
368 if (Console == NULL || Object == NULL)
370
371 /* Validity check */
372 ASSERT(Console == Object->Console);
373
374 if (INPUT_BUFFER == Object->Type)
375 {
377
378 /* Only the presence of valid mode flags is allowed */
379 if (ConsoleMode & ~CONSOLE_VALID_INPUT_MODES)
380 {
382 }
383 else
384 {
385 InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
386 }
387 }
388 else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
389 {
391
392 /* Only the presence of valid mode flags is allowed */
393 if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES)
394 {
396 }
397 else
398 {
399 Buffer->Mode = (ConsoleMode & CONSOLE_VALID_OUTPUT_MODES);
400 }
401 }
402 else
403 {
405 }
406
407 return Status;
408}
#define CONSOLE_VALID_INPUT_MODES
#define CONSOLE_VALID_OUTPUT_MODES

Referenced by CON_API().

◆ ConioPause()

VOID ConioPause ( PCONSRV_CONSOLE  Console,
UCHAR  Flags 
)

Definition at line 859 of file console.c.

860{
861 Console->PauseFlags |= Flags;
863}
VOID NTAPI ConDrvPause(PCONSOLE Console)
Definition: console.c:304
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by OnScroll(), PreprocessInput(), and UpdateSelection().

◆ ConioUnpause()

VOID ConioUnpause ( PCONSRV_CONSOLE  Console,
UCHAR  Flags 
)

Definition at line 866 of file console.c.

867{
868 Console->PauseFlags &= ~Flags;
869
870 // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0)
871 if (Console->PauseFlags == 0)
872 {
874
875 CsrNotifyWait(&Console->WriteWaitQueue,
876 TRUE,
877 NULL,
878 NULL);
879 if (!IsListEmpty(&Console->WriteWaitQueue))
880 {
881 CsrDereferenceWait(&Console->WriteWaitQueue);
882 }
883 }
884}
VOID NTAPI CsrDereferenceWait(IN PLIST_ENTRY WaitList)
Definition: wait.c:266
BOOLEAN NTAPI CsrNotifyWait(IN PLIST_ENTRY WaitList, IN BOOLEAN NotifyAll, IN PVOID WaitArgument1, IN PVOID WaitArgument2)
Definition: wait.c:388
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
VOID NTAPI ConDrvUnpause(PCONSOLE Console)
Definition: console.c:314

Referenced by OnScroll(), PreprocessInput(), and UpdateSelection().

◆ ConsoleCreateUnicodeString()

static BOOLEAN ConsoleCreateUnicodeString ( IN OUT PUNICODE_STRING  UniDest,
IN PCWSTR  Source 
)
static

Definition at line 216 of file console.c.

218{
219 SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR);
220 if (Size > MAXUSHORT) return FALSE;
221
222 UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size);
223 if (UniDest->Buffer == NULL) return FALSE;
224
225 RtlCopyMemory(UniDest->Buffer, Source, Size);
226 UniDest->MaximumLength = (USHORT)Size;
227 UniDest->Length = (USHORT)Size - sizeof(WCHAR);
228
229 return TRUE;
230}
#define FALSE
Definition: types.h:117
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
unsigned short USHORT
Definition: pedump.c:61
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAXUSHORT
Definition: typedefs.h:83
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by ConSrvInitConsole().

◆ ConsoleFreeUnicodeString()

static VOID ConsoleFreeUnicodeString ( IN PUNICODE_STRING  UnicodeString)
static

Definition at line 234 of file console.c.

235{
236 if (UnicodeString->Buffer)
237 {
240 }
241}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15

Referenced by CON_API(), and ConSrvDeleteConsole().

◆ ConSrvAllocateConsole()

NTSTATUS ConSrvAllocateConsole ( IN OUT PCONSOLE_PROCESS_DATA  ProcessData,
OUT PHANDLE  pInputHandle,
OUT PHANDLE  pOutputHandle,
OUT PHANDLE  pErrorHandle,
IN OUT PCONSOLE_INIT_INFO  ConsoleInitInfo 
)

Definition at line 968 of file console.c.

974{
976 HANDLE ConsoleHandle;
978
979 /*
980 * We are about to create a new console. However when ConSrvNewProcess()
981 * was called, we didn't know that we wanted to create a new console and
982 * therefore, we by default inherited the handle table from our parent
983 * process. It's only now that we notice that in fact we do not need
984 * them, because we've created a new console and thus we must use it.
985 *
986 * Therefore, free the handle table so that we can recreate
987 * a new one later on.
988 */
989 ConSrvFreeHandlesTable(ProcessData);
990
991 /* Initialize a new Console owned by this process */
992 Status = ConSrvInitConsole(&ConsoleHandle,
993 &Console,
994 ConsoleInitInfo,
995 ProcessData->Process);
996 if (!NT_SUCCESS(Status))
997 {
998 DPRINT1("Console initialization failed\n");
999 return Status;
1000 }
1001
1002 /* Assign the new console handle */
1003 ProcessData->ConsoleHandle = ConsoleHandle;
1004
1005 /* Initialize the process handles */
1006 Status = ConSrvInitProcessHandles(ProcessData,
1007 Console,
1008 pInputHandle,
1009 pOutputHandle,
1010 pErrorHandle);
1011 if (!NT_SUCCESS(Status))
1012 {
1013 DPRINT1("Failed to initialize the process handles\n");
1015 ProcessData->ConsoleHandle = NULL;
1016 return Status;
1017 }
1018
1019 /* Duplicate the Initialization Events */
1021 Console->InitEvents[INIT_SUCCESS],
1022 ProcessData->Process->ProcessHandle,
1023 &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
1024 EVENT_ALL_ACCESS, 0, 0);
1025 if (!NT_SUCCESS(Status))
1026 {
1027 DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
1028 ConSrvFreeHandlesTable(ProcessData);
1030 ProcessData->ConsoleHandle = NULL;
1031 return Status;
1032 }
1033
1035 Console->InitEvents[INIT_FAILURE],
1036 ProcessData->Process->ProcessHandle,
1037 &ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
1038 EVENT_ALL_ACCESS, 0, 0);
1039 if (!NT_SUCCESS(Status))
1040 {
1041 DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
1042 NtDuplicateObject(ProcessData->Process->ProcessHandle,
1043 ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
1045 ConSrvFreeHandlesTable(ProcessData);
1047 ProcessData->ConsoleHandle = NULL;
1048 return Status;
1049 }
1050
1051 /* Duplicate the Input Event */
1053 Console->InputBuffer.ActiveEvent,
1054 ProcessData->Process->ProcessHandle,
1055 &ConsoleInitInfo->ConsoleStartInfo->InputWaitHandle,
1056 EVENT_ALL_ACCESS, 0, 0);
1057 if (!NT_SUCCESS(Status))
1058 {
1059 DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
1060 NtDuplicateObject(ProcessData->Process->ProcessHandle,
1061 ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_FAILURE],
1063 NtDuplicateObject(ProcessData->Process->ProcessHandle,
1064 ConsoleInitInfo->ConsoleStartInfo->InitEvents[INIT_SUCCESS],
1066 ConSrvFreeHandlesTable(ProcessData);
1068 ProcessData->ConsoleHandle = NULL;
1069 return Status;
1070 }
1071
1072 /* Mark the process as having a console */
1073 ProcessData->ConsoleApp = TRUE;
1074 ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
1075
1076 /* Return the console handle to the caller */
1077 ConsoleInitInfo->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
1078
1079 /*
1080 * Insert the process into the processes list of the console,
1081 * and set its foreground priority.
1082 */
1083 InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
1084 ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
1085
1086 /* Add a reference count because the process is tied to the console */
1087 _InterlockedIncrement(&Console->ReferenceCount);
1088
1089 /* Update the internal info of the terminal */
1091
1092 return STATUS_SUCCESS;
1093}
@ INIT_SUCCESS
Definition: conmsg.h:163
@ INIT_FAILURE
Definition: conmsg.h:164
@ CsrProcessIsConsoleApp
Definition: csrsrv.h:94
#define InsertHeadList(ListHead, Entry)
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
#define TermRefreshInternalInfo(Console)
Definition: term.h:46
VOID ConSrvSetProcessFocus(IN PCSR_PROCESS CsrProcess, IN BOOLEAN SetForeground)
Definition: console.c:1440
NTSTATUS NTAPI ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, OUT PCONSRV_CONSOLE *NewConsole, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN PCSR_PROCESS ConsoleLeaderProcess)
Definition: console.c:532
static NTSTATUS ConSrvInitProcessHandles(IN OUT PCONSOLE_PROCESS_DATA ProcessData, IN PCONSRV_CONSOLE Console, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle)
Definition: console.c:890
VOID NTAPI ConSrvDeleteConsole(PCONSRV_CONSOLE Console)
Definition: console.c:822
VOID ConSrvFreeHandlesTable(IN PCONSOLE_PROCESS_DATA ProcessData)
Definition: handle.c:172
#define DUPLICATE_CLOSE_SOURCE

Referenced by CON_API_NOCONSOLE(), and ConSrvConnect().

◆ ConSrvConsoleCtrlEvent()

NTSTATUS ConSrvConsoleCtrlEvent ( IN ULONG  CtrlEvent,
IN PCONSOLE_PROCESS_DATA  ProcessData 
)

Definition at line 1356 of file console.c.

1358{
1359 return ConSrvConsoleCtrlEventTimeout(CtrlEvent, ProcessData, 0);
1360}
NTSTATUS ConSrvConsoleCtrlEventTimeout(IN ULONG CtrlEvent, IN PCONSOLE_PROCESS_DATA ProcessData, IN ULONG Timeout)
Definition: console.c:1305

Referenced by ConSrvConsoleProcessCtrlEvent(), and ConSrvRemoveConsole().

◆ ConSrvConsoleCtrlEventTimeout()

NTSTATUS ConSrvConsoleCtrlEventTimeout ( IN ULONG  CtrlEvent,
IN PCONSOLE_PROCESS_DATA  ProcessData,
IN ULONG  Timeout 
)

Definition at line 1305 of file console.c.

1308{
1310
1311 DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
1312
1313 /*
1314 * Be sure we effectively have a control routine. It resides in kernel32.dll (client).
1315 */
1316 if (ProcessData->CtrlRoutine == NULL) return Status;
1317
1318 _SEH2_TRY
1319 {
1320 HANDLE Thread = NULL;
1321
1322 _SEH2_TRY
1323 {
1324 Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
1325 ProcessData->CtrlRoutine,
1326 UlongToPtr(CtrlEvent), 0, NULL);
1327 if (NULL == Thread)
1328 {
1330 DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status);
1331 }
1332 else
1333 {
1334 DPRINT("ProcessData->CtrlRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
1335 ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
1337 }
1338 }
1340 {
1342 }
1343 _SEH2_END;
1344 }
1346 {
1348 DPRINT1("ConSrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status);
1349 }
1350 _SEH2_END;
1351
1352 return Status;
1353}
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI CreateRemoteThread(IN HANDLE hProcess, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:159
#define UlongToPtr(u)
Definition: config.h:106
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI NTSTATUS WINAPI RtlGetLastNtStatus(void)
Definition: error.c:114
static ULONG Timeout
Definition: ping.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82

Referenced by ConSrvConsoleCtrlEvent(), and NotifyConsoleProcessForShutdown().

◆ ConSrvConsoleProcessCtrlEvent()

NTSTATUS NTAPI ConSrvConsoleProcessCtrlEvent ( IN PCONSRV_CONSOLE  Console,
IN ULONG  ProcessGroupId,
IN ULONG  CtrlEvent 
)

Definition at line 1402 of file console.c.

1405{
1407 PLIST_ENTRY current_entry;
1409
1410 /* If the console is already being destroyed, just return */
1412 return STATUS_UNSUCCESSFUL;
1413
1414 /*
1415 * Loop through the process list, from the most recent process
1416 * (the active one) to the oldest one (the first created, i.e.
1417 * the console leader process), and for each, send an event
1418 * (new processes are inserted at the head of the console process list).
1419 */
1420 current_entry = Console->ProcessList.Flink;
1421 while (current_entry != &Console->ProcessList)
1422 {
1423 current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
1424 current_entry = current_entry->Flink;
1425
1426 /*
1427 * Only processes belonging to the same process group are signaled.
1428 * If the process group ID is zero, then all the processes are signaled.
1429 */
1430 if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId)
1431 {
1433 }
1434 }
1435
1436 return Status;
1437}
struct task_struct * current
Definition: linux.c:32
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
BOOLEAN NTAPI ConDrvValidateConsoleState(IN PCONSOLE Console, IN CONSOLE_STATE ExpectedState)
Definition: console.c:24
NTSTATUS ConSrvConsoleCtrlEvent(IN ULONG CtrlEvent, IN PCONSOLE_PROCESS_DATA ProcessData)
Definition: console.c:1356
@ CONSOLE_RUNNING
Definition: conio.h:283

Referenced by CON_API(), ConioProcessInputEvent(), and OnClose().

◆ ConSrvDeinitTerminal()

NTSTATUS NTAPI ConSrvDeinitTerminal ( IN OUT PTERMINAL  Terminal)

Definition at line 237 of file terminal.c.

238{
240 PFRONTEND FrontEnd = Terminal->Context;
241
242 /* Reset the ConSrv terminal */
243 Terminal->Context = NULL;
244 Terminal->Vtbl = NULL;
245
246 /* Unload the frontend */
247 if (FrontEnd != NULL)
248 {
249 Status = ConSrvUnloadFrontEnd(FrontEnd);
250 ConsoleFreeHeap(FrontEnd);
251 }
252
253 return Status;
254}
PVOID Context
Definition: conio_winsrv.h:104
static NTSTATUS ConSrvUnloadFrontEnd(IN PFRONTEND FrontEnd)
Definition: terminal.c:193

Referenced by ConSrvInitConsole().

◆ ConSrvDeleteConsole()

VOID NTAPI ConSrvDeleteConsole ( PCONSRV_CONSOLE  Console)

Definition at line 822 of file console.c.

823{
824 DPRINT("ConSrvDeleteConsole\n");
825
826 // FIXME: Send a terminate message to all the processes owning this console.
827 // NOTE: In principle there should be none, because such processes would
828 // have a reference to the console and thus this function would not have
829 // been called in the first place.
830
831 /* Remove the console from the list */
833
834 /* Destroy the Initialization Events */
835 NtClose(Console->InitEvents[INIT_FAILURE]);
836 NtClose(Console->InitEvents[INIT_SUCCESS]);
837
838 /* Clean the Input Line Discipline */
839 if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer);
840
841 /* Clean aliases and history */
844
845 /* Free the console title */
846 ConsoleFreeUnicodeString(&Console->OriginalTitle);
848
849 /* Now, call the driver. ConDrvDetachTerminal is called on-demand. */
851
852 /* Deinit the ConSrv terminal */
853 // FIXME!!
854 // ConSrvDeinitTerminal(&Terminal);
855}
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
VOID IntDeleteAllAliases(PCONSRV_CONSOLE Console)
Definition: alias.c:428
VOID NTAPI ConDrvDeleteConsole(IN PCONSOLE Console)
Definition: console.c:218
static NTSTATUS RemoveConsoleByPointer(IN PCONSRV_CONSOLE Console)
Definition: console.c:168
VOID HistoryDeleteBuffers(PCONSRV_CONSOLE Console)
Definition: history.c:357

Referenced by ConSrvAllocateConsole(), and ConSrvReleaseConsole().

◆ ConSrvGetConsole()

NTSTATUS ConSrvGetConsole ( IN PCONSOLE_PROCESS_DATA  ProcessData,
OUT PCONSRV_CONSOLE Console,
IN BOOLEAN  LockConsole 
)

Definition at line 291 of file console.c.

294{
296 PCONSRV_CONSOLE GrabConsole;
297
298 // if (Console == NULL) return STATUS_INVALID_PARAMETER;
300 *Console = NULL;
301
302 if (ConSrvValidateConsole(&GrabConsole,
303 ProcessData->ConsoleHandle,
305 LockConsole))
306 {
307 _InterlockedIncrement(&GrabConsole->ReferenceCount);
308 *Console = GrabConsole;
310 }
311
312 return Status;
313}
BOOLEAN NTAPI ConSrvValidateConsole(OUT PCONSRV_CONSOLE *Console, IN HANDLE ConsoleHandle, IN CONSOLE_STATE ExpectedState, IN BOOLEAN LockConsole)
Definition: console.c:247

Referenced by CON_API_NOCONSOLE(), and GetThreadConsoleDesktop().

◆ ConSrvGetConsoleLeaderProcess()

PCONSOLE_PROCESS_DATA NTAPI ConSrvGetConsoleLeaderProcess ( IN PCONSRV_CONSOLE  Console)

Definition at line 1363 of file console.c.

1364{
1365 if (Console == NULL) return NULL;
1366
1367 return CONTAINING_RECORD(Console->ProcessList.Blink,
1369 ConsoleLink);
1370}

Referenced by ConSrvRemoveConsole(), GuiApplyUserSettings(), GuiConsoleShowConsoleProperties(), and SetConWndConsoleLeaderCID().

◆ ConSrvGetConsoleProcessList()

NTSTATUS NTAPI ConSrvGetConsoleProcessList ( IN PCONSRV_CONSOLE  Console,
IN OUT PULONG  ProcessIdsList,
IN ULONG  MaxIdListItems,
OUT PULONG  ProcessIdsTotal 
)

Definition at line 1373 of file console.c.

1377{
1379 PLIST_ENTRY current_entry;
1380
1381 if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL)
1383
1384 *ProcessIdsTotal = 0;
1385
1386 for (current_entry = Console->ProcessList.Flink;
1387 current_entry != &Console->ProcessList;
1388 current_entry = current_entry->Flink)
1389 {
1390 current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
1391 if (++(*ProcessIdsTotal) <= MaxIdListItems)
1392 {
1393 *ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
1394 }
1395 }
1396
1397 return STATUS_SUCCESS;
1398}
#define HandleToUlong(h)
Definition: basetsd.h:79

Referenced by CON_API().

◆ ConSrvInheritConsole()

NTSTATUS ConSrvInheritConsole ( IN OUT PCONSOLE_PROCESS_DATA  ProcessData,
IN HANDLE  ConsoleHandle,
IN BOOLEAN  CreateNewHandleTable,
OUT PHANDLE  pInputHandle,
OUT PHANDLE  pOutputHandle,
OUT PHANDLE  pErrorHandle,
IN OUT PCONSOLE_START_INFO  ConsoleStartInfo 
)

Definition at line 1096 of file console.c.

1104{
1107
1108 /* Validate and lock the console */
1110 ConsoleHandle,
1112 {
1113 // FIXME: Find another status code
1114 return STATUS_UNSUCCESSFUL;
1115 }
1116
1117 /* Inherit the console */
1118 ProcessData->ConsoleHandle = ConsoleHandle;
1119
1120 if (CreateNewHandleTable)
1121 {
1122 /*
1123 * We are about to create a new console. However when ConSrvNewProcess()
1124 * was called, we didn't know that we wanted to create a new console and
1125 * therefore, we by default inherited the handle table from our parent
1126 * process. It's only now that we notice that in fact we do not need
1127 * them, because we've created a new console and thus we must use it.
1128 *
1129 * Therefore, free the handle table so that we can recreate
1130 * a new one later on.
1131 */
1132 ConSrvFreeHandlesTable(ProcessData);
1133
1134 /* Initialize the process handles */
1135 Status = ConSrvInitProcessHandles(ProcessData,
1136 Console,
1137 pInputHandle,
1138 pOutputHandle,
1139 pErrorHandle);
1140 if (!NT_SUCCESS(Status))
1141 {
1142 DPRINT1("Failed to initialize the process handles\n");
1143 ProcessData->ConsoleHandle = NULL;
1144 goto Quit;
1145 }
1146 }
1147
1148 /* Duplicate the Initialization Events */
1150 Console->InitEvents[INIT_SUCCESS],
1151 ProcessData->Process->ProcessHandle,
1152 &ConsoleStartInfo->InitEvents[INIT_SUCCESS],
1153 EVENT_ALL_ACCESS, 0, 0);
1154 if (!NT_SUCCESS(Status))
1155 {
1156 DPRINT1("NtDuplicateObject(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
1157 ConSrvFreeHandlesTable(ProcessData);
1158 ProcessData->ConsoleHandle = NULL;
1159 goto Quit;
1160 }
1161
1163 Console->InitEvents[INIT_FAILURE],
1164 ProcessData->Process->ProcessHandle,
1165 &ConsoleStartInfo->InitEvents[INIT_FAILURE],
1166 EVENT_ALL_ACCESS, 0, 0);
1167 if (!NT_SUCCESS(Status))
1168 {
1169 DPRINT1("NtDuplicateObject(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
1170 NtDuplicateObject(ProcessData->Process->ProcessHandle,
1171 ConsoleStartInfo->InitEvents[INIT_SUCCESS],
1173 ConSrvFreeHandlesTable(ProcessData);
1174 ProcessData->ConsoleHandle = NULL;
1175 goto Quit;
1176 }
1177
1178 /* Duplicate the Input Event */
1180 Console->InputBuffer.ActiveEvent,
1181 ProcessData->Process->ProcessHandle,
1182 &ConsoleStartInfo->InputWaitHandle,
1183 EVENT_ALL_ACCESS, 0, 0);
1184 if (!NT_SUCCESS(Status))
1185 {
1186 DPRINT1("NtDuplicateObject(InputWaitHandle) failed: %lu\n", Status);
1187 NtDuplicateObject(ProcessData->Process->ProcessHandle,
1188 ConsoleStartInfo->InitEvents[INIT_FAILURE],
1190 NtDuplicateObject(ProcessData->Process->ProcessHandle,
1191 ConsoleStartInfo->InitEvents[INIT_SUCCESS],
1193 ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handle table.
1194 ProcessData->ConsoleHandle = NULL;
1195 goto Quit;
1196 }
1197
1198 /* Mark the process as having a console */
1199 ProcessData->ConsoleApp = TRUE;
1200 ProcessData->Process->Flags |= CsrProcessIsConsoleApp;
1201
1202 /* Return the console handle to the caller */
1203 ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle;
1204
1205 /*
1206 * Insert the process into the processes list of the console,
1207 * and set its foreground priority.
1208 */
1209 InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
1210 ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus);
1211
1212 /* Add a reference count because the process is tied to the console */
1213 _InterlockedIncrement(&Console->ReferenceCount);
1214
1215 /* Update the internal info of the terminal */
1217
1219
1220Quit:
1221 /* Unlock the console and return */
1223 return Status;
1224}
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

Referenced by CON_API_NOCONSOLE(), and ConSrvConnect().

◆ ConSrvInitConsole()

NTSTATUS NTAPI ConSrvInitConsole ( OUT PHANDLE  NewConsoleHandle,
OUT PCONSRV_CONSOLE NewConsole,
IN OUT PCONSOLE_INIT_INFO  ConsoleInitInfo,
IN PCSR_PROCESS  ConsoleLeaderProcess 
)

Definition at line 532 of file console.c.

536{
538 HANDLE ConsoleHandle;
540
541 BYTE ConsoleInfoBuffer[sizeof(CONSOLE_STATE_INFO) + MAX_PATH * sizeof(WCHAR)]; // CONSRV console information
543 CONSOLE_INFO DrvConsoleInfo; // Console information for CONDRV
544
545 SIZE_T Length = 0;
546
547 TERMINAL Terminal; /* The ConSrv terminal for this console */
548
549 if (NewConsole == NULL || ConsoleInitInfo == NULL)
551
552 *NewConsole = NULL;
553
554 DPRINT("Initialization of console '%S' for process '%S' on desktop '%S'\n",
555 ConsoleInitInfo->ConsoleTitle ? ConsoleInitInfo->ConsoleTitle : L"n/a",
556 ConsoleInitInfo->AppName ? ConsoleInitInfo->AppName : L"n/a",
557 ConsoleInitInfo->Desktop ? ConsoleInitInfo->Desktop : L"n/a");
558
559 /*
560 * Load the console settings
561 */
562 RtlZeroMemory(ConsoleInfo, sizeof(ConsoleInfoBuffer));
563 ConsoleInfo->cbSize = sizeof(ConsoleInfoBuffer);
564
565 /* 1. Get the title of the console (initialize ConsoleInfo->ConsoleTitle) */
566 Length = min(ConsoleInitInfo->TitleLength,
567 (ConsoleInfo->cbSize - FIELD_OFFSET(CONSOLE_STATE_INFO, ConsoleTitle) - sizeof(UNICODE_NULL)) / sizeof(WCHAR));
568 wcsncpy(ConsoleInfo->ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length);
569 ConsoleInfo->ConsoleTitle[Length] = UNICODE_NULL; // NULL-terminate it.
570
571 /* 2. Impersonate the caller in order to retrieve settings in its context */
574
575 /* 3. Load the default settings */
577
578 /*
579 * 4. Load per-application terminal settings.
580 *
581 * Check whether the process creating the console was launched via
582 * a shell-link. ConsoleInfo->ConsoleTitle may be updated with the
583 * name of the shortcut, and ConsoleStartInfo->Icon[Path|Index] too.
584 */
585 // if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) // FIXME!! (for icon loading)
586 {
587 if (!LoadShellLinkConsoleInfo(ConsoleInfo, ConsoleInitInfo))
588 {
589 ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME;
590 }
591 }
592
593 /*
594 * 5. Load the remaining console settings via the registry.
595 */
596 if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
597 {
598 /*
599 * Either we weren't created by an app launched via a shell-link,
600 * or we failed to load shell-link console properties.
601 * Therefore, load the console infos for the application from the registry.
602 */
604
605 /*
606 * Now, update them with the properties the user might gave to us
607 * via the STARTUPINFO structure before calling CreateProcess
608 * (and which was transmitted via the ConsoleStartInfo structure).
609 * We therefore overwrite the values read in the registry.
610 */
611 if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE)
612 {
613 ConsoleInfo->ScreenAttributes = (USHORT)ConsoleInitInfo->ConsoleStartInfo->wFillAttribute;
614 }
615 if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS)
616 {
617 ConsoleInfo->ScreenBufferSize = ConsoleInitInfo->ConsoleStartInfo->dwScreenBufferSize;
618 }
619 if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE)
620 {
621 ConsoleInfo->WindowSize = ConsoleInitInfo->ConsoleStartInfo->dwWindowSize;
622 }
623
624#if 0
625 /*
626 * Now, update them with the properties the user might gave to us
627 * via the STARTUPINFO structure before calling CreateProcess
628 * (and which was transmitted via the ConsoleStartInfo structure).
629 * We therefore overwrite the values read in the registry.
630 */
631 if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION)
632 {
633 ConsoleInfo->AutoPosition = FALSE;
634 ConsoleInfo->WindowPosition.x = ConsoleInitInfo->ConsoleStartInfo->dwWindowOrigin.X;
635 ConsoleInfo->WindowPosition.y = ConsoleInitInfo->ConsoleStartInfo->dwWindowOrigin.Y;
636 }
637 if (ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN)
638 {
639 ConsoleInfo->FullScreen = TRUE;
640 }
641#endif
642 }
643
644 /* 6. Revert impersonation */
646
647 /* Set-up the code page */
648 ConsoleInfo->CodePage = GetOEMCP();
649
650 /*
651 * Initialize the ConSrv terminal and give it a chance to load
652 * its own settings and override the console settings.
653 */
654 Status = ConSrvInitTerminal(&Terminal,
656 ConsoleInitInfo,
657 ConsoleLeaderProcess->ProcessHandle);
658 if (!NT_SUCCESS(Status))
659 {
660 DPRINT1("CONSRV: Failed to initialize a terminal, Status = 0x%08lx\n", Status);
661 return Status;
662 }
663 DPRINT("CONSRV: Terminal initialized\n");
664
665 /* Initialize a new console via the driver */
666 // DrvConsoleInfo.InputBufferSize = 0;
667 DrvConsoleInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;
668 DrvConsoleInfo.ConsoleSize = ConsoleInfo->WindowSize;
669 DrvConsoleInfo.CursorSize = ConsoleInfo->CursorSize;
670 // DrvConsoleInfo.CursorBlinkOn = ConsoleInfo->CursorBlinkOn;
671 DrvConsoleInfo.ScreenAttrib = ConsoleInfo->ScreenAttributes;
672 DrvConsoleInfo.PopupAttrib = ConsoleInfo->PopupAttributes;
673 DrvConsoleInfo.CodePage = ConsoleInfo->CodePage;
674
675 /*
676 * Allocate a new console
677 */
679 if (Console == NULL)
680 {
681 DPRINT1("Not enough memory for console creation.\n");
682 ConSrvDeinitTerminal(&Terminal);
683 return STATUS_NO_MEMORY;
684 }
685
686 Status = ConDrvInitConsole((PCONSOLE)Console, &DrvConsoleInfo);
687 if (!NT_SUCCESS(Status))
688 {
689 DPRINT1("Creating a new console failed, Status = 0x%08lx\n", Status);
691 ConSrvDeinitTerminal(&Terminal);
692 return Status;
693 }
694
695 DPRINT("Console initialized\n");
696
697 /*** Register ConSrv features ***/
698
699 /* Initialize the console title */
700#if 0
701 WCHAR DefaultTitle[128];
702#endif
703 ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle);
704#if 0
705 if (ConsoleInfo->ConsoleTitle[0] == UNICODE_NULL)
706 {
707 if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0])))
708 {
709 ConsoleCreateUnicodeString(&Console->Title, DefaultTitle);
710 }
711 else
712 {
713 ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console");
714 }
715 }
716 else
717 {
718#endif
719 ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle);
720#if 0
721 }
722#endif
723
724 /* Initialize process support */
725 // InitProcessSupport(Console);
726 InitializeListHead(&Console->ProcessList);
727 Console->NotifiedLastCloseProcess = NULL;
728 Console->NotifyLastClose = FALSE;
729 Console->HasFocus = FALSE;
730
731 /* Initialize pausing support */
732 Console->PauseFlags = 0;
733 InitializeListHead(&Console->ReadWaitQueue);
734 InitializeListHead(&Console->WriteWaitQueue);
735
736 /* Initialize the alias and history buffers */
737 // InitAliasesHistory(Console);
738 Console->Aliases = NULL;
739 InitializeListHead(&Console->HistoryBuffers);
740 Console->NumberOfHistoryBuffers = 0;
741 Console->MaxNumberOfHistoryBuffers = ConsoleInfo->NumberOfHistoryBuffers;
742 Console->HistoryBufferSize = ConsoleInfo->HistoryBufferSize;
743 Console->HistoryNoDup = ConsoleInfo->HistoryNoDup;
744
745 /* Initialize the Input Line Discipline */
746 // InitLineInput(Console);
747 Console->LineBuffer = NULL;
748 Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
749 Console->LineComplete = Console->LineUpPressed = FALSE;
750 // LineWakeupMask
751 Console->LineInsertToggle =
752 Console->InsertMode = ConsoleInfo->InsertMode;
753 Console->QuickEdit = ConsoleInfo->QuickEdit;
754
755 /* Popup windows */
756 InitializeListHead(&Console->PopupWindows);
757
758 /* Colour table */
759 RtlCopyMemory(Console->Colors, ConsoleInfo->ColorTable,
760 sizeof(ConsoleInfo->ColorTable));
761
762 /* Create the Initialization Events */
765 if (!NT_SUCCESS(Status))
766 {
767 DPRINT1("NtCreateEvent(InitEvents[INIT_SUCCESS]) failed: %lu\n", Status);
769 ConSrvDeinitTerminal(&Terminal);
770 return Status;
771 }
774 if (!NT_SUCCESS(Status))
775 {
776 DPRINT1("NtCreateEvent(InitEvents[INIT_FAILURE]) failed: %lu\n", Status);
777 NtClose(Console->InitEvents[INIT_SUCCESS]);
779 ConSrvDeinitTerminal(&Terminal);
780 return Status;
781 }
782
783 /*
784 * Attach the ConSrv terminal to the console.
785 * This call makes a copy of our local Terminal variable.
786 */
788 if (!NT_SUCCESS(Status))
789 {
790 DPRINT1("Failed to register terminal to the given console, Status = 0x%08lx\n", Status);
791 NtClose(Console->InitEvents[INIT_FAILURE]);
792 NtClose(Console->InitEvents[INIT_SUCCESS]);
794 ConSrvDeinitTerminal(&Terminal);
795 return Status;
796 }
797 DPRINT("Terminal attached\n");
798
799 /* All went right, so add the console to the list */
800#if 0
801 Status = ConDrvInsertConsole((PCONSOLE)Console);
802 if (!NT_SUCCESS(Status))
803 {
804 /* Fail */
806 return Status;
807 }
808#endif
809 Status = InsertConsole(&ConsoleHandle, Console);
810
811 // FIXME! We do not support at all asynchronous console creation!
812 NtSetEvent(Console->InitEvents[INIT_SUCCESS], NULL);
813 // NtSetEvent(Console->InitEvents[INIT_FAILURE], NULL);
814
815 /* Return the newly created console to the caller and a success code too */
816 *NewConsoleHandle = ConsoleHandle;
817 *NewConsole = Console;
818 return STATUS_SUCCESS;
819}
HINSTANCE ConSrvDllInstance
Definition: init.c:21
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
#define MAX_PATH
Definition: compat.h:34
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ NotificationEvent
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
USHORT ScreenAttrib
Definition: conio.h:189
ULONG CodePage
Definition: conio.h:192
COORD ScreenBufferSize
Definition: conio.h:182
USHORT PopupAttrib
Definition: conio.h:190
ULONG CursorSize
Definition: conio.h:185
COORD ConsoleSize
Definition: conio.h:183
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
Definition: video.c:47
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
VOID ConCfgGetDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo)
Definition: settings.c:491
BOOLEAN ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN BOOLEAN DefaultSettings)
Definition: settings.c:167
struct _CONSOLE_STATE_INFO * PCONSOLE_STATE_INFO
struct _CONSOLE_STATE_INFO CONSOLE_STATE_INFO
NTSTATUS NTAPI ConDrvAttachTerminal(IN PCONSOLE Console, IN PTERMINAL Terminal)
Definition: console.c:160
NTSTATUS NTAPI ConDrvInitConsole(IN OUT PCONSOLE Console, IN PCONSOLE_INFO ConsoleInfo)
Definition: console.c:69
static BOOL LoadShellLinkConsoleInfo(IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo)
Definition: console.c:370
NTSTATUS NTAPI ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal)
Definition: terminal.c:237
NTSTATUS NTAPI ConSrvInitTerminal(IN OUT PTERMINAL Terminal, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
Definition: terminal.c:204
static BOOLEAN ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCWSTR Source)
Definition: console.c:216
static NTSTATUS InsertConsole(OUT PHANDLE Handle, IN PCONSRV_CONSOLE Console)
Definition: console.c:72
#define IDS_CONSOLE_TITLE
Definition: resource.h:10
#define STARTF_USEPOSITION
Definition: winbase.h:493
#define STARTF_USECOUNTCHARS
Definition: winbase.h:494
#define STARTF_USEFILLATTRIBUTE
Definition: winbase.h:495
#define STARTF_RUNFULLSCREEN
Definition: winbase.h:496
#define STARTF_USESIZE
Definition: winbase.h:492
UINT WINAPI GetOEMCP(void)
Definition: nls.c:2322
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)

Referenced by ConSrvAllocateConsole().

◆ ConSrvInitConsoleSupport()

VOID NTAPI ConSrvInitConsoleSupport ( VOID  )

Definition at line 347 of file console.c.

348{
349 DPRINT("CONSRV: ConSrvInitConsoleSupport()\n");
350
351 /* Initialize the console list and its lock */
352 ConsoleListSize = 0;
354 // InitializeListHead(&ConDrvConsoleList);
356
357 /* Should call LoadKeyboardLayout */
358}
NTSYSAPI VOID NTAPI RtlInitializeResource(_In_ PRTL_RESOURCE Resource)
static PCONSRV_CONSOLE * ConsoleList
Definition: console.c:34
static RTL_RESOURCE ListLock
Definition: console.c:36
static ULONG ConsoleListSize
Definition: console.c:33

Referenced by CSR_SERVER_DLL_INIT().

◆ ConSrvInitProcessHandles()

static NTSTATUS ConSrvInitProcessHandles ( IN OUT PCONSOLE_PROCESS_DATA  ProcessData,
IN PCONSRV_CONSOLE  Console,
OUT PHANDLE  pInputHandle,
OUT PHANDLE  pOutputHandle,
OUT PHANDLE  pErrorHandle 
)
static

Definition at line 890 of file console.c.

896{
900 ErrorHandle = INVALID_HANDLE_VALUE;
901
902 /*
903 * Initialize the process handles. Use temporary variables to store
904 * the handles values in such a way that, if we fail, we don't
905 * return to the caller invalid handle values.
906 *
907 * Insert the IO handles.
908 */
909
910 RtlEnterCriticalSection(&ProcessData->HandleTableLock);
911
912 /* Insert the Input handle */
913 Status = ConSrvInsertObject(ProcessData,
915 &Console->InputBuffer.Header,
917 TRUE,
919 if (!NT_SUCCESS(Status))
920 {
921 DPRINT1("Failed to insert the input handle\n");
922 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
923 ConSrvFreeHandlesTable(ProcessData);
924 return Status;
925 }
926
927 /* Insert the Output handle */
928 Status = ConSrvInsertObject(ProcessData,
930 &Console->ActiveBuffer->Header,
932 TRUE,
934 if (!NT_SUCCESS(Status))
935 {
936 DPRINT1("Failed to insert the output handle\n");
937 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
938 ConSrvFreeHandlesTable(ProcessData);
939 return Status;
940 }
941
942 /* Insert the Error handle */
943 Status = ConSrvInsertObject(ProcessData,
944 &ErrorHandle,
945 &Console->ActiveBuffer->Header,
947 TRUE,
949 if (!NT_SUCCESS(Status))
950 {
951 DPRINT1("Failed to insert the error handle\n");
952 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
953 ConSrvFreeHandlesTable(ProcessData);
954 return Status;
955 }
956
957 RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
958
959 /* Return the newly created handles */
960 *pInputHandle = InputHandle;
961 *pOutputHandle = OutputHandle;
962 *pErrorHandle = ErrorHandle;
963
964 return STATUS_SUCCESS;
965}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FILE_SHARE_READ
Definition: compat.h:136
HANDLE InputHandle
Definition: apc.c:9
HANDLE OutputHandle
Definition: apc.c:8
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSTATUS ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData, OUT PHANDLE Handle, IN PCONSOLE_IO_OBJECT Object, IN ULONG Access, IN BOOLEAN Inheritable, IN ULONG ShareMode)
Definition: handle.c:227

Referenced by ConSrvAllocateConsole(), and ConSrvInheritConsole().

◆ ConSrvInitTerminal()

NTSTATUS NTAPI ConSrvInitTerminal ( IN OUT PTERMINAL  Terminal,
IN OUT PCONSOLE_STATE_INFO  ConsoleInfo,
IN OUT PCONSOLE_INIT_INFO  ConsoleInitInfo,
IN HANDLE  ConsoleLeaderProcessHandle 
)

Definition at line 204 of file terminal.c.

208{
210 PFRONTEND FrontEnd;
211
212 /* Load a suitable frontend for the ConSrv terminal */
213 FrontEnd = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*FrontEnd));
214 if (!FrontEnd) return STATUS_NO_MEMORY;
215
216 Status = ConSrvLoadFrontEnd(FrontEnd,
218 ConsoleInitInfo,
219 ConsoleLeaderProcessHandle);
220 if (!NT_SUCCESS(Status))
221 {
222 DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status);
223 ConsoleFreeHeap(FrontEnd);
224 return Status;
225 }
226 DPRINT("CONSRV: Frontend initialized\n");
227
228 /* Initialize the ConSrv terminal */
229 Terminal->Vtbl = &ConSrvTermVtbl;
230 // Terminal->Console will be initialized by ConDrvAttachTerminal
231 Terminal->Context = FrontEnd; /* We store the frontend pointer in the terminal private context */
232
233 return STATUS_SUCCESS;
234}
static NTSTATUS ConSrvLoadFrontEnd(IN OUT PFRONTEND FrontEnd, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
Definition: terminal.c:154
static TERMINAL_VTBL ConSrvTermVtbl
Definition: terminal.c:201

Referenced by ConSrvInitConsole().

◆ ConSrvReleaseConsole()

VOID ConSrvReleaseConsole ( IN PCONSRV_CONSOLE  Console,
IN BOOLEAN  IsConsoleLocked 
)

Definition at line 316 of file console.c.

318{
319 LONG RefCount = 0;
320
321 if (!Console) return;
322 // if (Console->ReferenceCount == 0) return; // This shouldn't happen
323 ASSERT(Console->ReferenceCount > 0);
324
325 /* The console must be locked */
326 // ASSERT(Console_locked);
327
328 /*
329 * Decrement the reference count. Save the new value too,
330 * because Console->ReferenceCount might be modified after
331 * the console gets unlocked but before we check whether we
332 * can destroy it.
333 */
334 RefCount = _InterlockedDecrement(&Console->ReferenceCount);
335
336 /* Unlock the console if needed */
337 if (IsConsoleLocked) LeaveCriticalSection(&Console->Lock);
338
339 /* Delete the console if needed */
340 if (RefCount <= 0) ConSrvDeleteConsole(Console);
341}
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
long LONG
Definition: pedump.c:60

Referenced by CON_API_NOCONSOLE(), ConSrvReleaseObject(), ConSrvRemoveConsole(), and GetThreadConsoleDesktop().

◆ ConSrvRemoveConsole()

NTSTATUS ConSrvRemoveConsole ( IN OUT PCONSOLE_PROCESS_DATA  ProcessData)

Definition at line 1227 of file console.c.

1229{
1231 PCONSOLE_PROCESS_DATA ConsoleLeaderProcess;
1232
1233 DPRINT("ConSrvRemoveConsole\n");
1234
1235 /* Mark the process as not having a console anymore */
1236 ProcessData->ConsoleApp = FALSE;
1237 ProcessData->Process->Flags &= ~CsrProcessIsConsoleApp;
1238
1239 /* Validate and lock the console */
1241 ProcessData->ConsoleHandle,
1243 {
1244 // FIXME: Find another status code
1245 return STATUS_UNSUCCESSFUL;
1246 }
1247
1248 DPRINT("ConSrvRemoveConsole - Locking OK\n");
1249
1250 /* Retrieve the console leader process */
1251 ConsoleLeaderProcess = ConSrvGetConsoleLeaderProcess(Console);
1252
1253 /* Close all console handles and free the handle table */
1254 ConSrvFreeHandlesTable(ProcessData);
1255
1256 /* Detach the process from the console */
1257 ProcessData->ConsoleHandle = NULL;
1258
1259 /* Remove the process from the console's list of processes */
1260 RemoveEntryList(&ProcessData->ConsoleLink);
1261
1262 /* Check whether the console should send a last close notification */
1263 if (Console->NotifyLastClose)
1264 {
1265 /* If we are removing the process which wants the last close notification... */
1266 if (ProcessData == Console->NotifiedLastCloseProcess)
1267 {
1268 /* ... just reset the flag and the pointer... */
1269 Console->NotifyLastClose = FALSE;
1270 Console->NotifiedLastCloseProcess = NULL;
1271 }
1272 /*
1273 * ... otherwise, if we are removing the console leader process
1274 * (that cannot be the process wanting the notification, because
1275 * the previous case already dealt with it)...
1276 */
1277 else if (ProcessData == ConsoleLeaderProcess)
1278 {
1279 /*
1280 * ... reset the flag first (so that we avoid multiple notifications)
1281 * and then send the last close notification.
1282 */
1283 Console->NotifyLastClose = FALSE;
1284 ConSrvConsoleCtrlEvent(CTRL_LAST_CLOSE_EVENT, Console->NotifiedLastCloseProcess);
1285
1286 /* Only now, reset the pointer */
1287 Console->NotifiedLastCloseProcess = NULL;
1288 }
1289 }
1290
1291 /* Update the internal info of the terminal */
1293
1294 /* Release the console */
1295 DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount);
1297
1298 return STATUS_SUCCESS;
1299}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
PCONSOLE_PROCESS_DATA NTAPI ConSrvGetConsoleLeaderProcess(IN PCONSRV_CONSOLE Console)
Definition: console.c:1363
VOID ConSrvReleaseConsole(IN PCONSRV_CONSOLE Console, IN BOOLEAN IsConsoleLocked)
Definition: console.c:316
#define CTRL_LAST_CLOSE_EVENT
Definition: wincon.h:71

Referenced by CON_API_NOCONSOLE(), and ConSrvDisconnect().

◆ ConSrvSetConsoleProcessFocus()

NTSTATUS NTAPI ConSrvSetConsoleProcessFocus ( IN PCONSRV_CONSOLE  Console,
IN BOOLEAN  SetForeground 
)

Definition at line 1453 of file console.c.

1455{
1456 PLIST_ENTRY current_entry;
1458
1459 /* If the console is already being destroyed, just return */
1461 return STATUS_UNSUCCESSFUL;
1462
1463 /*
1464 * Loop through the process list, from the most recent process
1465 * to the oldest one, and for each, set its foreground priority.
1466 */
1467 current_entry = Console->ProcessList.Flink;
1468 while (current_entry != &Console->ProcessList)
1469 {
1470 current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
1471 current_entry = current_entry->Flink;
1472
1473 ConSrvSetProcessFocus(current->Process, SetForeground);
1474 }
1475
1476 return STATUS_SUCCESS;
1477}

Referenced by OnFocus().

◆ ConSrvSetProcessFocus()

VOID ConSrvSetProcessFocus ( IN PCSR_PROCESS  CsrProcess,
IN BOOLEAN  SetForeground 
)

Definition at line 1440 of file console.c.

1442{
1443 // FIXME: Call NtUserSetInformationProcess (currently unimplemented!)
1444 // for setting Win32 foreground/background flags.
1445
1446 if (SetForeground)
1448 else
1450}
VOID NTAPI CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:1138
VOID NTAPI CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
Definition: procsup.c:1107
PKPROCESS CsrProcess
Definition: videoprt.c:39

Referenced by ConSrvAllocateConsole(), ConSrvInheritConsole(), and ConSrvSetConsoleProcessFocus().

◆ ConSrvValidateConsole()

BOOLEAN NTAPI ConSrvValidateConsole ( OUT PCONSRV_CONSOLE Console,
IN HANDLE  ConsoleHandle,
IN CONSOLE_STATE  ExpectedState,
IN BOOLEAN  LockConsole 
)

Definition at line 247 of file console.c.

251{
252 BOOLEAN RetVal = FALSE;
253 PCONSRV_CONSOLE ValidatedConsole;
254
255 BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3);
256 ULONG Index = HandleToULong(ConsoleHandle) >> 2;
257
258 if (!ValidHandle) return FALSE;
259
260 if (!Console) return FALSE;
261 *Console = NULL;
262
263 /*
264 * Forbid creation or deletion of consoles when
265 * checking for the existence of a console.
266 */
268
269 if (Index >= ConsoleListSize ||
270 (ValidatedConsole = ConsoleList[Index]) == NULL)
271 {
272 /* Unlock the console list and return */
274 return FALSE;
275 }
276
277 ValidatedConsole = ConsoleList[Index];
278
279 /* Unlock the console list */
281
282 RetVal = ConDrvValidateConsoleUnsafe((PCONSOLE)ValidatedConsole,
283 ExpectedState,
284 LockConsole);
285 if (RetVal) *Console = ValidatedConsole;
286
287 return RetVal;
288}
unsigned char BOOLEAN
#define HandleToULong(h)
Definition: basetsd.h:95
_In_ WDFCOLLECTION _In_ ULONG Index
BOOLEAN NTAPI ConDrvValidateConsoleUnsafe(IN PCONSOLE Console, IN CONSOLE_STATE ExpectedState, IN BOOLEAN LockConsole)
Definition: console.c:36
#define ConSrvUnlockConsoleList()
Definition: console.c:44
#define ConSrvLockConsoleListShared()
Definition: console.c:41

Referenced by ConSrvGetConsole(), ConSrvInheritConsole(), ConSrvNewProcess(), and ConSrvRemoveConsole().

◆ CSR_API() [1/7]

CSR_API ( SrvGetConsoleCharType  )

Definition at line 1975 of file console.c.

1976{
1977 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1979}
#define __FUNCTION__
Definition: types.h:116
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ CSR_API() [2/7]

CSR_API ( SrvGetConsoleCursorMode  )

Definition at line 1996 of file console.c.

1997{
1998 DPRINT1("%s not yet implemented\n", __FUNCTION__);
2000}

◆ CSR_API() [3/7]

CSR_API ( SrvGetConsoleNlsMode  )

Definition at line 2003 of file console.c.

2004{
2005 DPRINT1("%s not yet implemented\n", __FUNCTION__);
2007}

◆ CSR_API() [4/7]

CSR_API ( SrvSetConsoleCursorMode  )

Definition at line 1989 of file console.c.

1990{
1991 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1993}

◆ CSR_API() [5/7]

CSR_API ( SrvSetConsoleKeyShortcuts  )

Definition at line 1955 of file console.c.

1956{
1957 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1959}

◆ CSR_API() [6/7]

CSR_API ( SrvSetConsoleLocalEUDC  )

Definition at line 1982 of file console.c.

1983{
1984 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1986}

◆ CSR_API() [7/7]

CSR_API ( SrvSetConsoleNlsMode  )

Definition at line 2010 of file console.c.

2011{
2012 DPRINT1("%s not yet implemented\n", __FUNCTION__);
2014}

◆ InsertConsole()

static NTSTATUS InsertConsole ( OUT PHANDLE  Handle,
IN PCONSRV_CONSOLE  Console 
)
static

Definition at line 72 of file console.c.

75{
76#define CONSOLE_HANDLES_INCREMENT 2 * 3
77
79 ULONG i = 0;
80 PCONSRV_CONSOLE* Block;
81
82 ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
83 (ConsoleList != NULL && ConsoleListSize != 0) );
84
85 /* All went right, so add the console to the list */
87 DPRINT("Insert in the list\n");
88
89 if (ConsoleList)
90 {
91 for (i = 0; i < ConsoleListSize; i++)
92 {
93 if (ConsoleList[i] == NULL) break;
94 }
95 }
96
97 if (i >= ConsoleListSize)
98 {
99 DPRINT("Creation of a new handles table\n");
100 /* Allocate a new handles table */
104 if (Block == NULL)
105 {
107 goto Quit;
108 }
109
110 /* If we previously had a handles table, free it and use the new one */
111 if (ConsoleList)
112 {
113 /* Copy the handles from the old table to the new one */
114 RtlCopyMemory(Block,
118 }
119 ConsoleList = Block;
121 }
122
124 *Handle = ULongToHandle((i << 2) | 0x3);
125
126Quit:
127 /* Unlock the console list and return status */
129 return Status;
130}
ULONG Handle
Definition: gdb_input.c:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ConSrvLockConsoleListExclusive()
Definition: console.c:38
#define CONSOLE_HANDLES_INCREMENT

Referenced by ConSrvInitConsole().

◆ LoadShellLinkConsoleInfo()

static BOOL LoadShellLinkConsoleInfo ( IN OUT PCONSOLE_STATE_INFO  ConsoleInfo,
IN OUT PCONSOLE_INIT_INFO  ConsoleInitInfo 
)
static

Definition at line 370 of file console.c.

372{
373#define PATH_SEPARATOR L'\\'
374
375 BOOL RetVal = FALSE;
376 HRESULT hRes = S_OK;
377 SIZE_T Length = 0;
378 LPWSTR LinkName = NULL;
380 WCHAR Buffer[MAX_PATH + 1];
381
382 ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
383
384 if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0)
385 {
386 // return FALSE; // FIXME!! (for icon loading)
387 RetVal = TRUE;
388 goto Finish;
389 }
390
391 /* 1- Find the last path separator if any */
392 LinkName = wcsrchr(ConsoleInfo->ConsoleTitle, PATH_SEPARATOR);
393 if (LinkName == NULL)
394 LinkName = ConsoleInfo->ConsoleTitle;
395 else
396 ++LinkName; // Skip the path separator
397
398 /* 2- Check for the link extension. The name ".lnk" is considered invalid. */
399 Length = wcslen(LinkName);
400 if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) )
401 return FALSE;
402
403 /* 3- It may be a link. Try to retrieve some properties */
404 hRes = CoInitialize(NULL);
405 if (SUCCEEDED(hRes))
406 {
407 /* Get a pointer to the IShellLink interface */
408 IShellLinkW* pshl = NULL;
409 hRes = CoCreateInstance(&CLSID_ShellLink,
410 NULL,
411 CLSCTX_INPROC_SERVER,
412 &IID_IShellLinkW,
413 (LPVOID*)&pshl);
414 if (SUCCEEDED(hRes))
415 {
416 /* Get a pointer to the IPersistFile interface */
417 IPersistFile* ppf = NULL;
418 hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf);
419 if (SUCCEEDED(hRes))
420 {
421 /* Load the shortcut */
422 hRes = IPersistFile_Load(ppf, ConsoleInfo->ConsoleTitle, STGM_READ);
423 if (SUCCEEDED(hRes))
424 {
425 /*
426 * Finally we can get the properties !
427 * Update the old ones if needed.
428 */
429 INT ShowCmd = 0;
430 // WORD HotKey = 0;
431
432 /* Reset the name of the console with the name of the shortcut */
433 Length = min(/*Length*/ Length - 4, // 4 == len(".lnk")
434 (ConsoleInfo->cbSize - FIELD_OFFSET(CONSOLE_STATE_INFO, ConsoleTitle) - sizeof(UNICODE_NULL)) / sizeof(WCHAR));
435 wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length);
436 ConsoleInfo->ConsoleTitle[Length] = UNICODE_NULL;
437
438 /* Get the window showing command */
439 hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd);
440 if (SUCCEEDED(hRes)) ConsoleInitInfo->ConsoleStartInfo->wShowWindow = (WORD)ShowCmd;
441
442 /* Get the hotkey */
443 // hRes = pshl->GetHotkey(&ShowCmd);
444 // if (SUCCEEDED(hRes)) ConsoleInitInfo->ConsoleStartInfo->HotKey = HotKey;
445
446 /* Get the icon location, if any */
447 hRes = IShellLinkW_GetIconLocation(pshl,
448 Buffer,
449 sizeof(Buffer)/sizeof(Buffer[0]) - 1, // == MAX_PATH
450 &ConsoleInitInfo->ConsoleStartInfo->IconIndex);
451 if (!SUCCEEDED(hRes))
452 {
453 ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
454 }
455 else
456 {
458 }
459
460 // FIXME: Since we still don't load console properties from the shortcut,
461 // return false. When this will be done, we will return true instead.
462 RetVal = TRUE; // FALSE;
463 }
464 IPersistFile_Release(ppf);
465 }
466 IShellLinkW_Release(pshl);
467 }
469 }
470
471Finish:
472
473 if (RetVal)
474 {
475 /* Get the associated icon, if any */
476 if (IconPath == NULL)
477 {
478 // Question: How to retrieve the full path name
479 // of the app we are going to run??
480 Length = RtlDosSearchPath_U(ConsoleInitInfo->CurDir,
481 ConsoleInitInfo->AppName,
482 NULL,
483 sizeof(Buffer),
484 Buffer,
485 NULL);
486 if (Length > 0 && Length < sizeof(Buffer))
488 else
489 IconPath = ConsoleInitInfo->AppName;
490
491 // ConsoleInitInfo->ConsoleStartInfo->IconIndex = 0;
492 }
493 DPRINT("IconPath = '%S' ; IconIndex = %lu\n",
494 IconPath, ConsoleInitInfo->ConsoleStartInfo->IconIndex);
495 if (IconPath && *IconPath)
496 {
498 /*
499 * FIXME!! Because of a strange bug we have in PrivateExtractIconExW
500 * (see r65683 for more details), we cannot use this API to extract
501 * at the same time the large and small icons from the app.
502 * Instead we just use PrivateExtractIconsW.
503 *
504 PrivateExtractIconExW(IconPath,
505 ConsoleInitInfo->ConsoleStartInfo->IconIndex,
506 &hIcon,
507 &hIconSm,
508 1);
509 */
511 ConsoleInitInfo->ConsoleStartInfo->IconIndex,
512 32, 32,
515 ConsoleInitInfo->ConsoleStartInfo->IconIndex,
516 16, 16,
518
519 DPRINT("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm);
520 if (hIcon != NULL) ConsoleInitInfo->ConsoleStartInfo->hIcon = hIcon;
521 if (hIconSm != NULL) ConsoleInitInfo->ConsoleStartInfo->hIconSm = hIconSm;
522 }
523 }
524
525 // FIXME: See the previous FIXME above.
526 RetVal = FALSE;
527
528 return RetVal;
529}
#define wcsrchr
Definition: compat.h:16
#define wcsicmp
Definition: compat.h:15
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
static const WCHAR IconPath[]
Definition: install.c:51
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static HICON
Definition: imagelist.c:84
HICON hIcon
Definition: msconfig.c:44
HICON hIconSm
Definition: msconfig.c:44
NTSYSAPI ULONG NTAPI RtlDosSearchPath_U(_In_ PCWSTR Path, _In_ PCWSTR FileName, _In_ PCWSTR Extension, _In_ ULONG BufferSize, _Out_ PWSTR Buffer, _Out_ PWSTR *PartName)
#define STGM_READ
Definition: objbase.h:917
const GUID IID_IPersistFile
int32_t INT
Definition: typedefs.h:58
#define PATH_SEPARATOR
UINT WINAPI PrivateExtractIconsW(_In_reads_(MAX_PATH) LPCWSTR szFileName, _In_ int nIconIndex, _In_ int cxIcon, _In_ int cyIcon, _Out_writes_opt_(nIcons) HICON *phicon, _Out_writes_opt_(nIcons) UINT *piconid, _In_ UINT nIcons, _In_ UINT flags)
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1099
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by ConSrvInitConsole().

◆ RemoveConsoleByPointer()

static NTSTATUS RemoveConsoleByPointer ( IN PCONSRV_CONSOLE  Console)
static

Definition at line 168 of file console.c.

169{
170 ULONG i = 0;
171
173
174 ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
175 (ConsoleList != NULL && ConsoleListSize != 0) );
176
177 /* Remove the console from the list */
179
180 if (ConsoleList)
181 {
182 for (i = 0; i < ConsoleListSize; i++)
183 {
185 }
186 }
187
188 /* Unlock the console list and return */
190 return STATUS_SUCCESS;
191}

Referenced by ConSrvDeleteConsole().

Variable Documentation

◆ ConsoleList

PCONSRV_CONSOLE* ConsoleList
static

◆ ConsoleListSize

ULONG ConsoleListSize
static

◆ ListLock

RTL_RESOURCE ListLock
static

Definition at line 36 of file console.c.

Referenced by ConSrvInitConsoleSupport().