[KERNEL32]

Fix support for CONIN$ and CONOUT$, and add support for CON special file
(now, writing to C:\CON or C:\somepath\CONIN$ or C:\anotherpath\CONOUT$ works).

svn path=/branches/ros-csrss/; revision=58182
This commit is contained in:
Hermès Bélusca-Maïto 2013-01-16 00:16:06 +00:00
parent 91e34202c7
commit 573e7edb6f
4 changed files with 79 additions and 23 deletions

View file

@ -24,6 +24,11 @@ extern BOOL WINAPI IsDebuggerPresent(VOID);
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
/* Console reserved "file" names */
static LPCWSTR BaseConFileName = CONSOLE_FILE_NAME;
static LPCWSTR BaseConInputFileName = CONSOLE_INPUT_FILE_NAME;
static LPCWSTR BaseConOutputFileName = CONSOLE_OUTPUT_FILE_NAME;
PHANDLER_ROUTINE InitialHandler[1]; PHANDLER_ROUTINE InitialHandler[1];
PHANDLER_ROUTINE* CtrlHandlers; PHANDLER_ROUTINE* CtrlHandlers;
ULONG NrCtrlHandlers; ULONG NrCtrlHandlers;
@ -189,6 +194,51 @@ InitConsoleCtrlHandling(VOID)
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
LPCWSTR
IntCheckForConsoleFileName(IN LPCWSTR pszName,
IN DWORD dwDesiredAccess)
{
LPCWSTR ConsoleName = pszName;
ULONG DeviceNameInfo;
/*
* Check whether we deal with a DOS device, and if so,
* strip the path till the file name.
* Therefore, things like \\.\CON or C:\some_path\CONIN$
* are transformed into CON or CONIN$, for example.
*/
DeviceNameInfo = RtlIsDosDeviceName_U(pszName);
if (DeviceNameInfo != 0)
{
ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + (ULONG_PTR)((DeviceNameInfo >> 16) & 0xFFFF));
}
/* Return a standard console "file" name according to what we passed in parameters */
if (_wcsicmp(ConsoleName, BaseConInputFileName) == 0)
{
return BaseConInputFileName;
}
else if (_wcsicmp(ConsoleName, BaseConOutputFileName) == 0)
{
return BaseConOutputFileName;
}
else if (_wcsicmp(ConsoleName, BaseConFileName) == 0)
{
if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_READ)
{
return BaseConInputFileName;
}
else if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_WRITE)
{
return BaseConOutputFileName;
}
}
/* If we are there, that means that either the file name or the desired access are wrong */
return NULL;
}
/* /*
* @unimplemented (Undocumented) * @unimplemented (Undocumented)
*/ */
@ -411,11 +461,11 @@ OpenConsoleW(LPCWSTR wsName,
PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest; PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest;
CONSOLE_HANDLE_TYPE HandleType; CONSOLE_HANDLE_TYPE HandleType;
if (wsName && 0 == _wcsicmp(wsName, L"CONIN$")) if (wsName && 0 == _wcsicmp(wsName, BaseConInputFileName))
{ {
HandleType = HANDLE_INPUT; HandleType = HANDLE_INPUT;
} }
else if (wsName && 0 == _wcsicmp(wsName, L"CONOUT$")) else if (wsName && 0 == _wcsicmp(wsName, BaseConOutputFileName))
{ {
HandleType = HANDLE_OUTPUT; HandleType = HANDLE_OUTPUT;
} }
@ -425,13 +475,8 @@ OpenConsoleW(LPCWSTR wsName,
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
{ (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) )
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
if (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE))
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;

View file

@ -99,6 +99,7 @@ HANDLE WINAPI CreateFileW (LPCWSTR lpFileName,
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING NtPathU; UNICODE_STRING NtPathU;
LPCWSTR pszConsoleFileName;
HANDLE FileHandle; HANDLE FileHandle;
NTSTATUS Status; NTSTATUS Status;
ULONG FileAttributes, Flags = 0; ULONG FileAttributes, Flags = 0;
@ -142,10 +143,10 @@ HANDLE WINAPI CreateFileW (LPCWSTR lpFileName,
} }
/* check for console input/output */ /* check for console input/output */
if (0 == _wcsicmp(L"CONOUT$", lpFileName) pszConsoleFileName = IntCheckForConsoleFileName(lpFileName, dwDesiredAccess);
|| 0 == _wcsicmp(L"CONIN$", lpFileName)) if (pszConsoleFileName)
{ {
return OpenConsoleW(lpFileName, return OpenConsoleW(pszConsoleFileName,
dwDesiredAccess, dwDesiredAccess,
lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE, lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE,
FILE_SHARE_READ | FILE_SHARE_WRITE); FILE_SHARE_READ | FILE_SHARE_WRITE);

View file

@ -106,19 +106,20 @@ typedef enum _VDM_ENTRY_CODE
typedef struct _CODEPAGE_ENTRY typedef struct _CODEPAGE_ENTRY
{ {
LIST_ENTRY Entry; LIST_ENTRY Entry;
UINT CodePage; UINT CodePage;
HANDLE SectionHandle; HANDLE SectionHandle;
PBYTE SectionMapping; PBYTE SectionMapping;
CPTABLEINFO CodePageTable; CPTABLEINFO CodePageTable;
} CODEPAGE_ENTRY, *PCODEPAGE_ENTRY; } CODEPAGE_ENTRY, *PCODEPAGE_ENTRY;
typedef struct tagLOADPARMS32 { typedef struct tagLOADPARMS32
LPSTR lpEnvAddress; {
LPSTR lpCmdLine; LPSTR lpEnvAddress;
WORD wMagicValue; LPSTR lpCmdLine;
WORD wCmdShow; WORD wMagicValue;
DWORD dwReserved; WORD wCmdShow;
DWORD dwReserved;
} LOADPARMS32; } LOADPARMS32;
typedef enum _BASE_SEARCH_PATH_TYPE typedef enum _BASE_SEARCH_PATH_TYPE
@ -195,6 +196,10 @@ BOOL WINAPI CloseConsoleHandle(HANDLE Handle);
HANDLE WINAPI HANDLE WINAPI
GetConsoleInputWaitHandle(VOID); GetConsoleInputWaitHandle(VOID);
LPCWSTR
IntCheckForConsoleFileName(IN LPCWSTR pszName,
IN DWORD dwDesiredAccess);
HANDLE WINAPI OpenConsoleW(LPCWSTR wsName, HANDLE WINAPI OpenConsoleW(LPCWSTR wsName,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
BOOL bInheritHandle, BOOL bInheritHandle,

View file

@ -14,6 +14,11 @@
#define IsConsoleHandle(h) \ #define IsConsoleHandle(h) \
(((ULONG_PTR)(h) & 0x10000003) == 0x3) (((ULONG_PTR)(h) & 0x10000003) == 0x3)
/* Console reserved "file" names */
#define CONSOLE_FILE_NAME L"CON"
#define CONSOLE_INPUT_FILE_NAME L"CONIN$"
#define CONSOLE_OUTPUT_FILE_NAME L"CONOUT$"
#endif // _CONSOLE_H #endif // _CONSOLE_H
/* EOF */ /* EOF */