2007-12-22 17:18:32 +00:00
/*
2003-12-02 11:38:47 +00:00
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS system libraries
* FILE : subsys / csrss / win32csr / dllmain . c
2005-05-08 04:07:56 +00:00
* PURPOSE : Initialization
2007-12-22 17:18:32 +00:00
* PROGRAMMERS : Dmitry Philippov ( shedon @ mail . ru )
2003-12-02 11:38:47 +00:00
*/
/* INCLUDES ******************************************************************/
# define NDEBUG
2009-01-28 16:30:19 +00:00
# include "w32csr.h"
2003-12-02 11:38:47 +00:00
# include <debug.h>
2003-12-07 23:02:57 +00:00
/* Not defined in any header file */
2008-11-29 22:48:58 +00:00
extern VOID WINAPI PrivateCsrssManualGuiCheck ( LONG Check ) ;
extern VOID WINAPI PrivateCsrssInitialized ( ) ;
extern VOID WINAPI InitializeAppSwitchHook ( ) ;
2003-12-07 23:02:57 +00:00
2003-12-02 11:38:47 +00:00
/* GLOBALS *******************************************************************/
HANDLE Win32CsrApiHeap ;
2006-07-04 13:36:57 +00:00
HINSTANCE Win32CsrDllHandle = NULL ;
2003-12-02 11:38:47 +00:00
static CSRSS_EXPORTED_FUNCS CsrExports ;
static CSRSS_API_DEFINITION Win32CsrApiDefinitions [ ] =
{
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
CSRSS_DEFINE_API ( WRITE_CONSOLE , CsrWriteConsole ) ,
CSRSS_DEFINE_API ( READ_CONSOLE , CsrReadConsole ) ,
CSRSS_DEFINE_API ( ALLOC_CONSOLE , CsrAllocConsole ) ,
CSRSS_DEFINE_API ( FREE_CONSOLE , CsrFreeConsole ) ,
CSRSS_DEFINE_API ( SCREEN_BUFFER_INFO , CsrGetScreenBufferInfo ) ,
CSRSS_DEFINE_API ( SET_CURSOR , CsrSetCursor ) ,
CSRSS_DEFINE_API ( FILL_OUTPUT , CsrFillOutputChar ) ,
CSRSS_DEFINE_API ( READ_INPUT , CsrReadInputEvent ) ,
CSRSS_DEFINE_API ( WRITE_CONSOLE_OUTPUT_CHAR , CsrWriteConsoleOutputChar ) ,
CSRSS_DEFINE_API ( WRITE_CONSOLE_OUTPUT_ATTRIB , CsrWriteConsoleOutputAttrib ) ,
CSRSS_DEFINE_API ( FILL_OUTPUT_ATTRIB , CsrFillOutputAttrib ) ,
CSRSS_DEFINE_API ( GET_CURSOR_INFO , CsrGetCursorInfo ) ,
CSRSS_DEFINE_API ( SET_CURSOR_INFO , CsrSetCursorInfo ) ,
CSRSS_DEFINE_API ( SET_ATTRIB , CsrSetTextAttrib ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_MODE , CsrGetConsoleMode ) ,
CSRSS_DEFINE_API ( SET_CONSOLE_MODE , CsrSetConsoleMode ) ,
CSRSS_DEFINE_API ( CREATE_SCREEN_BUFFER , CsrCreateScreenBuffer ) ,
CSRSS_DEFINE_API ( SET_SCREEN_BUFFER , CsrSetScreenBuffer ) ,
CSRSS_DEFINE_API ( SET_TITLE , CsrSetTitle ) ,
CSRSS_DEFINE_API ( GET_TITLE , CsrGetTitle ) ,
CSRSS_DEFINE_API ( WRITE_CONSOLE_OUTPUT , CsrWriteConsoleOutput ) ,
CSRSS_DEFINE_API ( FLUSH_INPUT_BUFFER , CsrFlushInputBuffer ) ,
CSRSS_DEFINE_API ( SCROLL_CONSOLE_SCREEN_BUFFER , CsrScrollConsoleScreenBuffer ) ,
CSRSS_DEFINE_API ( READ_CONSOLE_OUTPUT_CHAR , CsrReadConsoleOutputChar ) ,
CSRSS_DEFINE_API ( READ_CONSOLE_OUTPUT_ATTRIB , CsrReadConsoleOutputAttrib ) ,
CSRSS_DEFINE_API ( GET_NUM_INPUT_EVENTS , CsrGetNumberOfConsoleInputEvents ) ,
CSRSS_DEFINE_API ( EXIT_REACTOS , CsrExitReactos ) ,
CSRSS_DEFINE_API ( PEEK_CONSOLE_INPUT , CsrPeekConsoleInput ) ,
CSRSS_DEFINE_API ( READ_CONSOLE_OUTPUT , CsrReadConsoleOutput ) ,
CSRSS_DEFINE_API ( WRITE_CONSOLE_INPUT , CsrWriteConsoleInput ) ,
CSRSS_DEFINE_API ( SETGET_CONSOLE_HW_STATE , CsrHardwareStateProperty ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_WINDOW , CsrGetConsoleWindow ) ,
CSRSS_DEFINE_API ( CREATE_DESKTOP , CsrCreateDesktop ) ,
CSRSS_DEFINE_API ( SHOW_DESKTOP , CsrShowDesktop ) ,
CSRSS_DEFINE_API ( HIDE_DESKTOP , CsrHideDesktop ) ,
CSRSS_DEFINE_API ( SET_CONSOLE_ICON , CsrSetConsoleIcon ) ,
CSRSS_DEFINE_API ( SET_LOGON_NOTIFY_WINDOW , CsrSetLogonNotifyWindow ) ,
CSRSS_DEFINE_API ( REGISTER_LOGON_PROCESS , CsrRegisterLogonProcess ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_CP , CsrGetConsoleCodePage ) ,
CSRSS_DEFINE_API ( SET_CONSOLE_CP , CsrSetConsoleCodePage ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_OUTPUT_CP , CsrGetConsoleOutputCodePage ) ,
CSRSS_DEFINE_API ( SET_CONSOLE_OUTPUT_CP , CsrSetConsoleOutputCodePage ) ,
CSRSS_DEFINE_API ( GET_PROCESS_LIST , CsrGetProcessList ) ,
2008-07-27 00:41:45 +00:00
CSRSS_DEFINE_API ( ADD_CONSOLE_ALIAS , CsrAddConsoleAlias ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_ALIAS , CsrGetConsoleAlias ) ,
CSRSS_DEFINE_API ( GET_ALL_CONSOLE_ALIASES , CsrGetAllConsoleAliases ) ,
CSRSS_DEFINE_API ( GET_ALL_CONSOLE_ALIASES_LENGTH , CsrGetAllConsoleAliasesLength ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_ALIASES_EXES , CsrGetConsoleAliasesExes ) ,
CSRSS_DEFINE_API ( GET_CONSOLE_ALIASES_EXES_LENGTH , CsrGetConsoleAliasesExesLength ) ,
2008-08-02 17:01:22 +00:00
CSRSS_DEFINE_API ( GENERATE_CTRL_EVENT , CsrGenerateCtrlEvent ) ,
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
{ 0 , 0 , NULL }
2003-12-02 11:38:47 +00:00
} ;
static CSRSS_OBJECT_DEFINITION Win32CsrObjectDefinitions [ ] =
{
{ CONIO_CONSOLE_MAGIC , ConioDeleteConsole } ,
{ CONIO_SCREEN_BUFFER_MAGIC , ConioDeleteScreenBuffer } ,
{ 0 , NULL }
} ;
/* FUNCTIONS *****************************************************************/
2008-11-29 22:48:58 +00:00
BOOL WINAPI
2003-12-02 11:38:47 +00:00
DllMain ( HANDLE hDll ,
DWORD dwReason ,
LPVOID lpReserved )
{
2004-01-19 20:14:28 +00:00
if ( DLL_PROCESS_ATTACH = = dwReason )
{
Win32CsrDllHandle = hDll ;
2008-08-02 23:49:02 +00:00
InitializeAppSwitchHook ( ) ;
2004-01-19 20:14:28 +00:00
}
2003-12-02 11:38:47 +00:00
return TRUE ;
}
NTSTATUS FASTCALL
Win32CsrInsertObject ( PCSRSS_PROCESS_DATA ProcessData ,
2007-06-14 16:41:55 +00:00
PHANDLE Handle ,
2008-07-22 17:37:13 +00:00
Object_t * Object ,
DWORD Access ,
BOOL Inheritable )
2007-06-14 16:41:55 +00:00
{
2008-07-22 17:37:13 +00:00
return ( CsrExports . CsrInsertObjectProc ) ( ProcessData , Handle , Object , Access , Inheritable ) ;
2007-06-14 16:41:55 +00:00
}
2003-12-02 11:38:47 +00:00
NTSTATUS FASTCALL
Win32CsrGetObject ( PCSRSS_PROCESS_DATA ProcessData ,
HANDLE Handle ,
2008-07-23 16:21:46 +00:00
Object_t * * Object ,
DWORD Access )
2003-12-02 11:38:47 +00:00
{
2008-07-23 16:21:46 +00:00
return ( CsrExports . CsrGetObjectProc ) ( ProcessData , Handle , Object , Access ) ;
2003-12-02 11:38:47 +00:00
}
2004-01-11 17:31:16 +00:00
NTSTATUS FASTCALL
Win32CsrLockObject ( PCSRSS_PROCESS_DATA ProcessData ,
HANDLE Handle ,
Object_t * * Object ,
2008-07-23 16:21:46 +00:00
DWORD Access ,
2004-01-11 17:31:16 +00:00
LONG Type )
{
NTSTATUS Status ;
2008-07-23 16:21:46 +00:00
Status = ( CsrExports . CsrGetObjectProc ) ( ProcessData , Handle , Object , Access ) ;
2004-01-11 17:31:16 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
return Status ;
}
if ( ( * Object ) - > Type ! = Type )
{
2008-07-22 00:33:42 +00:00
( CsrExports . CsrReleaseObjectByPointerProc ) ( * Object ) ;
2004-01-11 17:31:16 +00:00
return STATUS_INVALID_HANDLE ;
}
EnterCriticalSection ( & ( ( * Object ) - > Lock ) ) ;
return STATUS_SUCCESS ;
}
VOID FASTCALL
Win32CsrUnlockObject ( Object_t * Object )
{
LeaveCriticalSection ( & ( Object - > Lock ) ) ;
2008-07-22 00:33:42 +00:00
( CsrExports . CsrReleaseObjectByPointerProc ) ( Object ) ;
}
NTSTATUS FASTCALL
Win32CsrReleaseObjectByPointer ( Object_t * Object )
{
return ( CsrExports . CsrReleaseObjectByPointerProc ) ( Object ) ;
2004-01-11 17:31:16 +00:00
}
2003-12-02 11:38:47 +00:00
NTSTATUS FASTCALL
Win32CsrReleaseObject ( PCSRSS_PROCESS_DATA ProcessData ,
2005-12-01 22:29:57 +00:00
HANDLE Object )
2003-12-02 11:38:47 +00:00
{
return ( CsrExports . CsrReleaseObjectProc ) ( ProcessData , Object ) ;
}
2005-12-01 22:29:57 +00:00
NTSTATUS FASTCALL
Win32CsrEnumProcesses ( CSRSS_ENUM_PROCESS_PROC EnumProc ,
PVOID Context )
{
return ( CsrExports . CsrEnumProcessesProc ) ( EnumProc , Context ) ;
}
2008-11-29 22:48:58 +00:00
static BOOL WINAPI
2004-05-28 21:33:41 +00:00
Win32CsrInitComplete ( void )
{
PrivateCsrssInitialized ( ) ;
return TRUE ;
}
2003-12-02 11:38:47 +00:00
2008-11-29 22:48:58 +00:00
static BOOL WINAPI
2007-12-22 17:18:32 +00:00
Win32CsrHardError ( IN PCSRSS_PROCESS_DATA ProcessData ,
IN PHARDERROR_MSG HardErrorMessage )
2006-10-30 14:20:45 +00:00
{
2007-12-22 17:18:32 +00:00
UINT responce = MB_OK ;
NTSTATUS Status ;
HANDLE hProcess ;
OBJECT_ATTRIBUTES ObjectAttributes ;
ULONG nParam = 0 ;
PRTL_MESSAGE_RESOURCE_ENTRY MessageResource ;
2009-06-20 12:40:11 +00:00
ULONG_PTR ParameterList [ MAXIMUM_HARDERROR_PARAMETERS ] ;
2007-12-22 17:18:32 +00:00
LPSTR CaptionText , MessageBody ;
LPWSTR szxCaptionText , szxMessageBody ;
DWORD SizeOfAllUnicodeStrings = 0 ;
PROCESS_BASIC_INFORMATION ClientBasicInfo ;
UNICODE_STRING ClientFileNameU ;
UNICODE_STRING TempStringU ;
UNICODE_STRING ParameterStringU ;
ANSI_STRING ParamStringA ;
ULONG UnicodeStringParameterMask = HardErrorMessage - > UnicodeStringParameterMask ;
int MessageBoxResponse ;
HardErrorMessage - > Response = ResponseNotHandled ;
2008-06-07 20:44:57 +00:00
DPRINT ( " NumberOfParameters = %d \n " , HardErrorMessage - > NumberOfParameters ) ;
DPRINT ( " Status = %lx \n " , HardErrorMessage - > Status ) ;
2007-12-22 17:18:32 +00:00
// open client process
InitializeObjectAttributes ( & ObjectAttributes , NULL , 0 , NULL , NULL ) ;
Status = NtOpenProcess ( & hProcess , PROCESS_VM_READ | PROCESS_QUERY_INFORMATION , & ObjectAttributes , & HardErrorMessage - > h . ClientId ) ;
if ( ! NT_SUCCESS ( Status ) ) {
DPRINT1 ( " NtOpenProcess failed with code: %lx \n " , Status ) ;
return FALSE ;
}
// let's get a name of the client process to display it in the caption of a message box
ClientFileNameU . MaximumLength = 0 ;
ClientFileNameU . Length = 0 ;
ClientFileNameU . Buffer = NULL ;
Status = NtQueryInformationProcess ( hProcess ,
ProcessBasicInformation ,
& ClientBasicInfo ,
sizeof ( ClientBasicInfo ) ,
NULL ) ;
if ( NT_SUCCESS ( Status ) ) {
PLIST_ENTRY ModuleListHead ;
PLIST_ENTRY Entry ;
PLDR_DATA_TABLE_ENTRY Module ;
PPEB_LDR_DATA Ldr ;
PPEB Peb = ClientBasicInfo . PebBaseAddress ;
if ( Peb )
{
Status = NtReadVirtualMemory ( hProcess , & Peb - > Ldr , & Ldr , sizeof ( Ldr ) , NULL ) ;
if ( NT_SUCCESS ( Status ) ) {
ModuleListHead = & Ldr - > InLoadOrderModuleList ;
Status = NtReadVirtualMemory (
hProcess ,
& ModuleListHead - > Flink ,
& Entry ,
sizeof ( Entry ) ,
NULL
) ;
if ( NT_SUCCESS ( Status ) )
{
if ( Entry ! = ModuleListHead )
{
LDR_DATA_TABLE_ENTRY ModuleData ;
Module = CONTAINING_RECORD ( Entry , LDR_DATA_TABLE_ENTRY , InLoadOrderLinks ) ;
Status = NtReadVirtualMemory ( hProcess , Module , & ModuleData , sizeof ( ModuleData ) , NULL ) ;
if ( NT_SUCCESS ( Status ) ) {
PVOID ClientDllBase ;
Status = NtReadVirtualMemory (
hProcess ,
& Peb - > ImageBaseAddress ,
& ClientDllBase ,
sizeof ( ClientDllBase ) ,
NULL
) ;
if ( NT_SUCCESS ( Status ) & & ( ClientDllBase = = ModuleData . DllBase ) ) {
ClientFileNameU . MaximumLength = ModuleData . BaseDllName . MaximumLength ;
ClientFileNameU . Buffer = RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , ClientFileNameU . MaximumLength ) ;
Status = NtReadVirtualMemory (
hProcess ,
ModuleData . BaseDllName . Buffer ,
ClientFileNameU . Buffer ,
ClientFileNameU . MaximumLength ,
NULL
) ;
if ( NT_SUCCESS ( Status ) ) {
ClientFileNameU . Length = wcslen ( ClientFileNameU . Buffer ) * sizeof ( wchar_t ) ;
}
else {
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , ClientFileNameU . Buffer ) ;
ClientFileNameU . Buffer = NULL ;
}
DPRINT ( " ClientFileNameU= \' %wZ \' \n " , & ClientFileNameU ) ;
}
}
}
}
}
}
}
// read all unicode strings from client space
for ( nParam = 0 ; nParam < HardErrorMessage - > NumberOfParameters ; nParam + + , UnicodeStringParameterMask > > = 1 )
{
if ( UnicodeStringParameterMask & 0x01 ) {
Status = NtReadVirtualMemory ( hProcess ,
( PVOID ) HardErrorMessage - > Parameters [ nParam ] ,
( PVOID ) & TempStringU ,
sizeof ( TempStringU ) ,
NULL ) ;
if ( NT_SUCCESS ( Status ) ) {
ParameterStringU . Buffer = ( PWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , TempStringU . MaximumLength ) ;
if ( ! ParameterStringU . Buffer ) {
DPRINT1 ( " Cannot allocate memory %d \n " , TempStringU . MaximumLength ) ;
NtClose ( hProcess ) ;
if ( ClientFileNameU . Buffer ) {
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , ClientFileNameU . Buffer ) ;
}
return FALSE ;
}
Status = NtReadVirtualMemory ( hProcess ,
( PVOID ) TempStringU . Buffer ,
( PVOID ) ParameterStringU . Buffer ,
TempStringU . MaximumLength ,
NULL ) ;
if ( ! NT_SUCCESS ( Status ) ) {
DPRINT1 ( " NtReadVirtualMemory failed with code: %lx \n " , Status ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , ParameterStringU . Buffer ) ;
if ( ClientFileNameU . Buffer ) {
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , ClientFileNameU . Buffer ) ;
}
NtClose ( hProcess ) ;
return FALSE ;
}
ParameterStringU . Length = TempStringU . Length ;
ParameterStringU . MaximumLength = TempStringU . MaximumLength ;
DPRINT ( " ParameterStringU= \' %wZ \' \n " , & ParameterStringU ) ;
RtlUnicodeStringToAnsiString ( & ParamStringA , & ParameterStringU , TRUE ) ;
2009-06-20 12:40:11 +00:00
ParameterList [ nParam ] = ( ULONG_PTR ) ParamStringA . Buffer ;
2007-12-22 17:18:32 +00:00
SizeOfAllUnicodeStrings + = ParamStringA . MaximumLength ;
}
}
else {
// it's not a unicode string
ParameterList [ nParam ] = HardErrorMessage - > Parameters [ nParam ] ;
}
}
NtClose ( hProcess ) ;
// get text string of the error code
Status = RtlFindMessage (
( PVOID ) GetModuleHandle ( TEXT ( " ntdll " ) ) ,
2009-06-20 12:40:11 +00:00
( ULONG_PTR ) RT_MESSAGETABLE ,
2007-12-22 17:18:32 +00:00
LANG_NEUTRAL ,
HardErrorMessage - > Status ,
& MessageResource ) ;
if ( ! NT_SUCCESS ( Status ) ) {
// WE HAVE TO DISPLAY HERE: "Unknown hard error"
if ( ClientFileNameU . Buffer ) {
szxCaptionText = ( LPWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , ClientFileNameU . MaximumLength + 64 ) ;
wsprintfW ( szxCaptionText , L " %s - %hs " , ClientFileNameU . Buffer , " Application Error " ) ;
} else {
szxCaptionText = ( LPWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , 64 ) ;
wsprintfW ( szxCaptionText , L " System - Application Error " ) ;
}
MessageBody = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , 38 ) ;
wsprintfA ( MessageBody , " Unknown hard error " ) ;
}
else {
LPSTR NtStatusString ;
UNICODE_STRING MessageU ;
ANSI_STRING MessageA ;
2008-05-18 09:34:31 +00:00
USHORT CaptionSize = 0 ;
2007-12-22 17:18:32 +00:00
2008-01-11 11:16:02 +00:00
if ( ! MessageResource - > Flags ) {
/* we've got an ansi string */
DPRINT ( " MessageResource->Text=%s \n " , ( PSTR ) MessageResource - > Text ) ;
RtlInitAnsiString ( & MessageA , MessageResource - > Text ) ;
}
else {
/* we've got a unicode string */
DPRINT ( " MessageResource->Text=%S \n " , ( PWSTR ) MessageResource - > Text ) ;
RtlInitUnicodeString ( & MessageU , ( PWSTR ) MessageResource - > Text ) ;
RtlUnicodeStringToAnsiString ( & MessageA , & MessageU , TRUE ) ;
}
2007-12-22 17:18:32 +00:00
// check whether a caption exists
if ( * MessageA . Buffer = = ' { ' ) {
// get size of the caption
for ( CaptionSize = 0 ; ( CaptionSize < MessageA . Length ) & & ( ' } ' ! = MessageA . Buffer [ CaptionSize ] ) ; CaptionSize + + ) ;
CaptionText = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , CaptionSize ) ;
RtlCopyMemory ( CaptionText , MessageA . Buffer + 1 , CaptionSize - 1 ) ;
2009-09-19 22:17:25 +00:00
CaptionSize + = 2 ; // "}\r\n" - 3
2007-12-22 17:18:32 +00:00
szxCaptionText = ( LPWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( wchar_t ) * CaptionSize + ClientFileNameU . MaximumLength + 128 ) ;
if ( ClientFileNameU . Buffer ) {
wsprintfW ( szxCaptionText , L " %s - %hs " , ClientFileNameU . Buffer , CaptionText ) ;
} else {
wsprintfW ( szxCaptionText , L " System - %hs " , CaptionText ) ;
}
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , CaptionText ) ;
}
else {
if ( ClientFileNameU . Buffer ) {
szxCaptionText = ( LPWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , ClientFileNameU . MaximumLength ) ;
wsprintfW ( szxCaptionText , L " %s " , ClientFileNameU . Buffer ) ;
} else {
szxCaptionText = ( LPWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , 14 ) ; // 14 - "System\0\0"
wsprintfW ( szxCaptionText , L " System " ) ;
}
}
2008-01-11 11:16:02 +00:00
DPRINT ( " ParameterList[0]=0x%lx \n " , ParameterList [ 0 ] ) ;
2007-12-22 17:18:32 +00:00
if ( STATUS_UNHANDLED_EXCEPTION = = HardErrorMessage - > Status )
{
PRTL_MESSAGE_RESOURCE_ENTRY MsgResException ;
MessageBody = NULL ;
Status = RtlFindMessage (
( PVOID ) GetModuleHandle ( TEXT ( " ntdll " ) ) ,
2009-06-20 12:40:11 +00:00
( ULONG_PTR ) RT_MESSAGETABLE ,
2007-12-22 17:18:32 +00:00
LANG_NEUTRAL ,
ParameterList [ 0 ] ,
& MsgResException ) ;
if ( NT_SUCCESS ( Status ) )
{
UNICODE_STRING ExcMessageU ;
ANSI_STRING ExcMessageA ;
2008-01-11 11:16:02 +00:00
if ( ! MsgResException - > Flags ) {
/* we've got an ansi string */
DPRINT ( " MsgResException->Text=%s \n " , ( PSTR ) MsgResException - > Text ) ;
RtlInitAnsiString ( & ExcMessageA , MsgResException - > Text ) ;
}
else {
/* we've got a unicode string */
DPRINT ( " MsgResException->Text=%S \n " , ( PWSTR ) MsgResException - > Text ) ;
RtlInitUnicodeString ( & ExcMessageU , ( PWSTR ) MsgResException - > Text ) ;
RtlUnicodeStringToAnsiString ( & ExcMessageA , & ExcMessageU , TRUE ) ;
}
2007-12-22 17:18:32 +00:00
MessageBody = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , MsgResException - > Length + SizeOfAllUnicodeStrings + 1024 ) ; // 1024 is a magic number I think it should be enough
if ( STATUS_ACCESS_VIOLATION = = ParameterList [ 0 ] ) {
LPSTR pOperationType ;
if ( ParameterList [ 2 ] ) pOperationType = " written " ;
else pOperationType = " read " ;
wsprintfA ( MessageBody , ExcMessageA . Buffer , ParameterList [ 1 ] , ParameterList [ 3 ] , pOperationType ) ;
}
else if ( STATUS_IN_PAGE_ERROR = = ParameterList [ 0 ] ) {
wsprintfA ( MessageBody , ExcMessageA . Buffer , ParameterList [ 1 ] , ParameterList [ 3 ] , ParameterList [ 2 ] ) ;
}
}
if ( ! MessageBody ) {
NtStatusString = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , MessageResource - > Length - CaptionSize ) ;
RtlCopyMemory ( NtStatusString , MessageA . Buffer + CaptionSize , ( MessageResource - > Length - CaptionSize ) - 1 ) ;
MessageBody = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , MessageResource - > Length + SizeOfAllUnicodeStrings + 1024 ) ; // 1024 is a magic number I think it should be enough
wsprintfA ( MessageBody , NtStatusString ,
L " Unknown software exception " ,
ParameterList [ 0 ] ,
ParameterList [ 1 ] ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , NtStatusString ) ;
}
}
else
{
NtStatusString = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , MessageResource - > Length - CaptionSize ) ;
RtlCopyMemory ( NtStatusString , MessageA . Buffer + CaptionSize , ( MessageResource - > Length - CaptionSize ) - 1 ) ;
MessageBody = ( LPSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , MessageResource - > Length + SizeOfAllUnicodeStrings + 1024 ) ; // 1024 is a magic number I think it should be enough
wsprintfA ( MessageBody , NtStatusString ,
ParameterList [ 0 ] ,
ParameterList [ 1 ] ,
ParameterList [ 2 ] ,
ParameterList [ 3 ] ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , NtStatusString ) ;
}
2008-05-18 09:34:31 +00:00
if ( MessageResource - > Flags ) {
/* we've got a unicode string */
RtlFreeAnsiString ( & MessageA ) ;
}
2007-12-22 17:18:32 +00:00
}
if ( ClientFileNameU . Buffer ) {
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , ClientFileNameU . Buffer ) ;
}
szxMessageBody = ( LPWSTR ) RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( wchar_t ) * ( strlen ( MessageBody ) + 1 ) ) ;
wsprintfW ( szxMessageBody , L " %hs " , MessageBody ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , MessageBody ) ;
switch ( HardErrorMessage - > ValidResponseOptions )
{
case OptionAbortRetryIgnore :
responce = MB_ABORTRETRYIGNORE ;
break ;
case OptionOk :
responce = MB_OK ;
break ;
case OptionOkCancel :
responce = MB_OKCANCEL ;
break ;
case OptionRetryCancel :
responce = MB_RETRYCANCEL ;
break ;
case OptionYesNo :
responce = MB_YESNO ;
break ;
case OptionYesNoCancel :
responce = MB_YESNOCANCEL ;
break ;
case OptionShutdownSystem :
// XZ??
break ;
default :
DPRINT1 ( " Wrong option: ValidResponseOptions = %d \n " , HardErrorMessage - > ValidResponseOptions ) ;
ASSERT ( FALSE ) ;
break ;
}
// FIXME: We should not use MessageBox !!!!
2008-06-07 20:44:57 +00:00
DPRINT1 ( " %S \n " , szxMessageBody ) ;
2007-12-22 17:18:32 +00:00
MessageBoxResponse = MessageBoxW ( 0 , szxMessageBody , szxCaptionText , responce | MB_ICONERROR | MB_SYSTEMMODAL | MB_SETFOREGROUND ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , szxMessageBody ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , szxCaptionText ) ;
switch ( MessageBoxResponse )
{
case IDOK :
HardErrorMessage - > Response = ResponseOk ;
break ;
case IDCANCEL :
HardErrorMessage - > Response = ResponseCancel ;
break ;
case IDYES :
HardErrorMessage - > Response = ResponseYes ;
break ;
case IDNO :
HardErrorMessage - > Response = ResponseNo ;
break ;
case IDABORT :
HardErrorMessage - > Response = ResponseAbort ;
break ;
case IDIGNORE :
HardErrorMessage - > Response = ResponseIgnore ;
break ;
case IDRETRY :
HardErrorMessage - > Response = ResponseRetry ;
break ;
case 10 : //IDTRYAGAIN:
HardErrorMessage - > Response = ResponseTryAgain ;
break ;
case 11 : //IDCONTINUE:
HardErrorMessage - > Response = ResponseContinue ;
break ;
default :
ASSERT ( FALSE ) ;
break ;
}
2006-10-30 14:20:45 +00:00
return TRUE ;
}
2008-11-29 22:48:58 +00:00
BOOL WINAPI
2003-12-02 11:38:47 +00:00
Win32CsrInitialization ( PCSRSS_API_DEFINITION * ApiDefinitions ,
PCSRSS_OBJECT_DEFINITION * ObjectDefinitions ,
2004-05-28 21:33:41 +00:00
CSRPLUGIN_INIT_COMPLETE_PROC * InitComplete ,
2006-10-30 14:20:45 +00:00
CSRPLUGIN_HARDERROR_PROC * HardError ,
2003-12-02 11:38:47 +00:00
PCSRSS_EXPORTED_FUNCS Exports ,
HANDLE CsrssApiHeap )
{
2008-11-01 14:31:54 +00:00
NTSTATUS Status ;
2003-12-02 11:38:47 +00:00
CsrExports = * Exports ;
Win32CsrApiHeap = CsrssApiHeap ;
2008-11-01 14:31:54 +00:00
Status = NtUserInitialize ( 0 , NULL , NULL ) ;
2003-12-07 23:02:57 +00:00
PrivateCsrssManualGuiCheck ( 0 ) ;
2003-12-02 11:38:47 +00:00
CsrInitConsoleSupport ( ) ;
* ApiDefinitions = Win32CsrApiDefinitions ;
* ObjectDefinitions = Win32CsrObjectDefinitions ;
2004-05-28 21:33:41 +00:00
* InitComplete = Win32CsrInitComplete ;
2006-10-30 14:20:45 +00:00
* HardError = Win32CsrHardError ;
2003-12-02 11:38:47 +00:00
return TRUE ;
}
/* EOF */