3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/dllmain.c
6 * PURPOSE: Initialization
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
12 /* INCLUDES ******************************************************************/
17 #include "../include/debug.h"
19 /* GLOBALS *******************************************************************/
21 extern UNICODE_STRING SystemDirectory
;
22 extern UNICODE_STRING WindowsDirectory
;
24 HANDLE hProcessHeap
= NULL
;
25 HMODULE hCurrentModule
= NULL
;
26 HANDLE hBaseDir
= NULL
;
28 static BOOL DllInitialized
= FALSE
;
35 /* Critical section for various kernel32 data structures */
36 RTL_CRITICAL_SECTION DllLock
;
37 RTL_CRITICAL_SECTION ConsoleLock
;
39 extern BOOL WINAPI
DefaultConsoleCtrlHandler(DWORD Event
);
40 extern __declspec(noreturn
) VOID CALLBACK
ConsoleControlDispatcher(DWORD CodeAndFlag
);
42 extern BOOL FASTCALL
NlsInit();
43 extern VOID FASTCALL
NlsUninit();
47 DuplicateConsoleHandle(HANDLE hConsole
,
48 DWORD dwDesiredAccess
,
52 /* FUNCTIONS *****************************************************************/
55 OpenBaseDirectory(PHANDLE DirHandle
)
57 OBJECT_ATTRIBUTES ObjectAttributes
;
58 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"\\BaseNamedObjects");
61 InitializeObjectAttributes(&ObjectAttributes
,
67 Status
= NtOpenDirectoryObject(DirHandle
,
70 if (!NT_SUCCESS(Status
))
72 Status
= NtCreateDirectoryObject(DirHandle
,
75 if (!NT_SUCCESS(Status
))
77 DbgPrint("NtCreateDirectoryObject() failed\n");
83 return STATUS_SUCCESS
;
88 BasepInitConsole(VOID
)
90 CSR_API_MESSAGE Request
;
93 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
95 WCHAR lpTest
[MAX_PATH
];
96 GetModuleFileNameW(NULL
, lpTest
, MAX_PATH
);
97 DPRINT1("BasepInitConsole for : %S\n", lpTest
);
98 DPRINT1("Our current console handles are: %lx, %lx, %lx\n",
99 Parameters
->ConsoleHandle
, Parameters
->StandardInput
,
100 Parameters
->StandardOutput
);
102 /* We have nothing to do if this isn't a console app... */
103 if (RtlImageNtHeader(GetModuleHandle(NULL
))->OptionalHeader
.Subsystem
!=
104 IMAGE_SUBSYSTEM_WINDOWS_CUI
)
106 DPRINT1("Image is not a console application\n");
107 Parameters
->ConsoleHandle
= NULL
;
111 /* Assume one is needed */
112 Request
.Data
.AllocConsoleRequest
.ConsoleNeeded
= TRUE
;
114 /* Handle the special flags given to us by BasepInitializeEnvironment */
115 if (Parameters
->ConsoleHandle
== HANDLE_DETACHED_PROCESS
)
117 /* No console to create */
118 DPRINT1("No console to create\n");
119 Parameters
->ConsoleHandle
= NULL
;
120 Request
.Data
.AllocConsoleRequest
.ConsoleNeeded
= FALSE
;
122 else if (Parameters
->ConsoleHandle
== HANDLE_CREATE_NEW_CONSOLE
)
124 /* We'll get the real one soon */
125 DPRINT1("Creating new console\n");
126 Parameters
->ConsoleHandle
= NULL
;
128 else if (Parameters
->ConsoleHandle
== HANDLE_CREATE_NO_WINDOW
)
130 /* We'll get the real one soon */
131 DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n");
132 Parameters
->ConsoleHandle
= NULL
;
136 DPRINT1("Using existing console: %x\n", Parameters
->ConsoleHandle
);
139 /* Initialize Console Ctrl Handler */
140 RtlInitializeCriticalSection(&ConsoleLock
);
141 SetConsoleCtrlHandler(DefaultConsoleCtrlHandler
, TRUE
);
143 /* Now use the proper console handle */
144 Request
.Data
.AllocConsoleRequest
.Console
= Parameters
->ConsoleHandle
;
147 * Normally, we should be connecting to the Console CSR Server...
148 * but we don't have one yet, so we will instead simply send a create
149 * console message to the Base Server. When we finally have a Console
150 * Server, this code should be changed to send connection data instead.
152 * Also note that this connection should be made for any console app, even
153 * in the case above where -we- return.
155 CsrRequest
= MAKE_CSR_API(ALLOC_CONSOLE
, CSR_CONSOLE
);
156 Request
.Data
.AllocConsoleRequest
.CtrlDispatcher
= ConsoleControlDispatcher
;
157 Status
= CsrClientCallServer(&Request
,
160 sizeof(CSR_API_MESSAGE
));
161 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
163 DPRINT1("CSR Failed to give us a console\n");
164 /* We're lying here, so at least the process can load... */
168 /* We got the handles, let's set them */
169 Parameters
->ConsoleHandle
= Request
.Data
.AllocConsoleRequest
.Console
;
171 /* If we already had some, don't use the new ones */
172 if (!Parameters
->StandardInput
)
174 Parameters
->StandardInput
= Request
.Data
.AllocConsoleRequest
.InputHandle
;
176 if (!Parameters
->StandardOutput
)
178 Parameters
->StandardOutput
= Request
.Data
.AllocConsoleRequest
.OutputHandle
;
180 if (!Parameters
->StandardError
)
182 Parameters
->StandardError
= DuplicateConsoleHandle(Request
.Data
.AllocConsoleRequest
.OutputHandle
,
185 DUPLICATE_SAME_ACCESS
);
188 DPRINT1("Console setup: %lx, %lx, %lx\n",
189 Parameters
->ConsoleHandle
,
190 Parameters
->StandardInput
,
191 Parameters
->StandardOutput
);
205 DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
210 case DLL_PROCESS_ATTACH
:
211 DPRINT("DLL_PROCESS_ATTACH\n");
213 LdrDisableThreadCalloutsForDll ((PVOID
)hDll
);
216 * Connect to the csrss server
218 Status
= CsrClientConnectToServer(NULL
,
224 if (!NT_SUCCESS(Status
))
226 DbgPrint("Failed to connect to csrss.exe (Status %lx)\n",
228 ZwTerminateProcess(NtCurrentProcess(), Status
);
232 hProcessHeap
= RtlGetProcessHeap();
233 hCurrentModule
= hDll
;
236 * Initialize WindowsDirectory and SystemDirectory
238 DPRINT("NtSystemRoot: %S\n",
239 SharedUserData
->NtSystemRoot
);
240 RtlCreateUnicodeString (&WindowsDirectory
,
241 SharedUserData
->NtSystemRoot
);
242 SystemDirectory
.MaximumLength
= WindowsDirectory
.MaximumLength
+ 18;
243 SystemDirectory
.Length
= WindowsDirectory
.Length
+ 18;
244 SystemDirectory
.Buffer
= RtlAllocateHeap (hProcessHeap
,
246 SystemDirectory
.MaximumLength
);
247 wcscpy (SystemDirectory
.Buffer
, WindowsDirectory
.Buffer
);
248 wcscat (SystemDirectory
.Buffer
, L
"\\System32");
250 /* Open object base directory */
251 Status
= OpenBaseDirectory(&hBaseDir
);
252 if (!NT_SUCCESS(Status
))
254 DbgPrint("Failed to open object base directory (Status %lx)\n",
259 /* Initialize the DLL critical section */
260 RtlInitializeCriticalSection(&DllLock
);
262 /* Initialize the National Language Support routines */
268 /* Initialize Console Support */
269 if (!BasepInitConsole())
271 DPRINT1("Failure to set up console\n");
275 /* Insert more dll attach stuff here! */
277 DllInitialized
= TRUE
;
280 case DLL_PROCESS_DETACH
:
281 DPRINT("DLL_PROCESS_DETACH\n");
282 if (DllInitialized
== TRUE
)
284 /* Insert more dll detach stuff here! */
288 /* Delete DLL critical section */
289 RtlDeleteCriticalSection (&ConsoleLock
);
290 RtlDeleteCriticalSection (&DllLock
);
292 /* Close object base directory */
295 RtlFreeUnicodeString (&SystemDirectory
);
296 RtlFreeUnicodeString (&WindowsDirectory
);