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 #define CSR_BASE_DLL 0 // <- This should be 1 when CSR gets committed
21 /* GLOBALS *******************************************************************/
23 extern UNICODE_STRING SystemDirectory
;
24 extern UNICODE_STRING WindowsDirectory
;
26 HANDLE hProcessHeap
= NULL
;
27 HMODULE hCurrentModule
= NULL
;
28 HANDLE hBaseDir
= NULL
;
30 static BOOL DllInitialized
= FALSE
;
31 static BOOL ConsoleInitialized
= FALSE
;
38 /* Critical section for various kernel32 data structures */
39 RTL_CRITICAL_SECTION DllLock
;
40 RTL_CRITICAL_SECTION ConsoleLock
;
42 extern BOOL WINAPI
DefaultConsoleCtrlHandler(DWORD Event
);
43 extern __declspec(noreturn
) VOID CALLBACK
ConsoleControlDispatcher(DWORD CodeAndFlag
);
45 extern BOOL FASTCALL
NlsInit();
46 extern VOID FASTCALL
NlsUninit();
50 DuplicateConsoleHandle(HANDLE hConsole
,
51 DWORD dwDesiredAccess
,
55 /* FUNCTIONS *****************************************************************/
58 OpenBaseDirectory(PHANDLE DirHandle
)
60 OBJECT_ATTRIBUTES ObjectAttributes
;
61 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"\\BaseNamedObjects");
64 InitializeObjectAttributes(&ObjectAttributes
,
66 OBJ_CASE_INSENSITIVE
|OBJ_PERMANENT
,
70 Status
= NtOpenDirectoryObject(DirHandle
,
73 if (!NT_SUCCESS(Status
))
75 Status
= NtCreateDirectoryObject(DirHandle
,
78 if (!NT_SUCCESS(Status
))
80 DbgPrint("NtCreateDirectoryObject() failed\n");
86 return STATUS_SUCCESS
;
91 BasepInitConsole(VOID
)
93 CSR_API_MESSAGE Request
;
96 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
98 WCHAR lpTest
[MAX_PATH
];
99 GetModuleFileNameW(NULL
, lpTest
, MAX_PATH
);
100 DPRINT("BasepInitConsole for : %S\n", lpTest
);
101 DPRINT("Our current console handles are: %lx, %lx, %lx %lx\n",
102 Parameters
->ConsoleHandle
, Parameters
->StandardInput
,
103 Parameters
->StandardOutput
, Parameters
->StandardError
);
105 /* We have nothing to do if this isn't a console app... */
106 if (RtlImageNtHeader(GetModuleHandle(NULL
))->OptionalHeader
.Subsystem
!=
107 IMAGE_SUBSYSTEM_WINDOWS_CUI
)
109 DPRINT("Image is not a console application\n");
110 Parameters
->ConsoleHandle
= NULL
;
114 /* Assume one is needed */
115 Request
.Data
.AllocConsoleRequest
.ConsoleNeeded
= TRUE
;
117 /* Handle the special flags given to us by BasepInitializeEnvironment */
118 if (Parameters
->ConsoleHandle
== HANDLE_DETACHED_PROCESS
)
120 /* No console to create */
121 DPRINT("No console to create\n");
122 Parameters
->ConsoleHandle
= NULL
;
123 Request
.Data
.AllocConsoleRequest
.ConsoleNeeded
= FALSE
;
125 else if (Parameters
->ConsoleHandle
== HANDLE_CREATE_NEW_CONSOLE
)
127 /* We'll get the real one soon */
128 DPRINT("Creating new console\n");
129 Parameters
->ConsoleHandle
= NULL
;
131 else if (Parameters
->ConsoleHandle
== HANDLE_CREATE_NO_WINDOW
)
133 /* We'll get the real one soon */
134 DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n");
135 Parameters
->ConsoleHandle
= NULL
;
139 if (Parameters
->ConsoleHandle
== INVALID_HANDLE_VALUE
)
141 Parameters
->ConsoleHandle
= 0;
143 DPRINT("Using existing console: %x\n", Parameters
->ConsoleHandle
);
146 /* Initialize Console Ctrl Handler */
147 ConsoleInitialized
= TRUE
;
148 RtlInitializeCriticalSection(&ConsoleLock
);
149 SetConsoleCtrlHandler(DefaultConsoleCtrlHandler
, TRUE
);
151 /* Now use the proper console handle */
152 Request
.Data
.AllocConsoleRequest
.Console
= Parameters
->ConsoleHandle
;
155 * Normally, we should be connecting to the Console CSR Server...
156 * but we don't have one yet, so we will instead simply send a create
157 * console message to the Base Server. When we finally have a Console
158 * Server, this code should be changed to send connection data instead.
160 * Also note that this connection should be made for any console app, even
161 * in the case above where -we- return.
163 CsrRequest
= MAKE_CSR_API(ALLOC_CONSOLE
, CSR_CONSOLE
);
164 Request
.Data
.AllocConsoleRequest
.CtrlDispatcher
= ConsoleControlDispatcher
;
165 Status
= CsrClientCallServer(&Request
,
168 sizeof(CSR_API_MESSAGE
));
169 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
171 DPRINT1("CSR Failed to give us a console\n");
172 /* We're lying here, so at least the process can load... */
176 /* We got the handles, let's set them */
177 if ((Parameters
->ConsoleHandle
= Request
.Data
.AllocConsoleRequest
.Console
))
179 /* If we already had some, don't use the new ones */
180 if (!Parameters
->StandardInput
)
182 Parameters
->StandardInput
= Request
.Data
.AllocConsoleRequest
.InputHandle
;
184 if (!Parameters
->StandardOutput
)
186 Parameters
->StandardOutput
= Request
.Data
.AllocConsoleRequest
.OutputHandle
;
188 if (!Parameters
->StandardError
)
190 Parameters
->StandardError
= Request
.Data
.AllocConsoleRequest
.OutputHandle
;
194 DPRINT("Console setup: %lx, %lx, %lx, %lx\n",
195 Parameters
->ConsoleHandle
,
196 Parameters
->StandardInput
,
197 Parameters
->StandardOutput
,
198 Parameters
->StandardError
);
212 ULONG DummySize
= sizeof(Dummy
);
214 DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
219 case DLL_PROCESS_ATTACH
:
221 /* Don't bother us for each thread */
222 LdrDisableThreadCalloutsForDll((PVOID
)hDll
);
224 /* Connect to the base server */
225 Status
= CsrClientConnectToServer(L
"\\Windows", // <- FIXME: SessionDir
230 if (!NT_SUCCESS(Status
))
232 DPRINT1("Failed to connect to CSR (Status %lx)\n", Status
);
233 ZwTerminateProcess(NtCurrentProcess(), Status
);
237 /* Check if we are running a CSR Server */
240 /* Set the termination port for the thread */
244 hProcessHeap
= RtlGetProcessHeap();
245 hCurrentModule
= hDll
;
248 * Initialize WindowsDirectory and SystemDirectory
250 DPRINT("NtSystemRoot: %S\n",
251 SharedUserData
->NtSystemRoot
);
252 RtlCreateUnicodeString (&WindowsDirectory
,
253 SharedUserData
->NtSystemRoot
);
254 SystemDirectory
.MaximumLength
= WindowsDirectory
.MaximumLength
+ 18;
255 SystemDirectory
.Length
= WindowsDirectory
.Length
+ 18;
256 SystemDirectory
.Buffer
= RtlAllocateHeap (hProcessHeap
,
258 SystemDirectory
.MaximumLength
);
259 wcscpy (SystemDirectory
.Buffer
, WindowsDirectory
.Buffer
);
260 wcscat (SystemDirectory
.Buffer
, L
"\\System32");
262 /* Open object base directory */
263 Status
= OpenBaseDirectory(&hBaseDir
);
264 if (!NT_SUCCESS(Status
))
266 DbgPrint("Failed to open object base directory (Status %lx)\n",
271 /* Initialize the DLL critical section */
272 RtlInitializeCriticalSection(&DllLock
);
274 /* Initialize the National Language Support routines */
280 /* Initialize Console Support */
281 if (!BasepInitConsole())
283 DPRINT1("Failure to set up console\n");
287 /* Insert more dll attach stuff here! */
289 DllInitialized
= TRUE
;
292 case DLL_PROCESS_DETACH
:
293 DPRINT("DLL_PROCESS_DETACH\n");
294 if (DllInitialized
== TRUE
)
296 /* Insert more dll detach stuff here! */
300 /* Delete DLL critical section */
301 if (ConsoleInitialized
== TRUE
)
303 RtlDeleteCriticalSection (&ConsoleLock
);
305 RtlDeleteCriticalSection (&DllLock
);
307 /* Close object base directory */
310 RtlFreeUnicodeString (&SystemDirectory
);
311 RtlFreeUnicodeString (&WindowsDirectory
);