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
;
29 static BOOL ConsoleInitialized
= FALSE
;
36 /* Critical section for various kernel32 data structures */
37 RTL_CRITICAL_SECTION DllLock
;
38 RTL_CRITICAL_SECTION ConsoleLock
;
40 extern BOOL WINAPI
DefaultConsoleCtrlHandler(DWORD Event
);
41 extern __declspec(noreturn
) VOID CALLBACK
ConsoleControlDispatcher(DWORD CodeAndFlag
);
43 extern BOOL FASTCALL
NlsInit();
44 extern VOID FASTCALL
NlsUninit();
48 DuplicateConsoleHandle(HANDLE hConsole
,
49 DWORD dwDesiredAccess
,
53 /* FUNCTIONS *****************************************************************/
56 OpenBaseDirectory(PHANDLE DirHandle
)
58 OBJECT_ATTRIBUTES ObjectAttributes
;
59 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"\\BaseNamedObjects");
62 InitializeObjectAttributes(&ObjectAttributes
,
64 OBJ_CASE_INSENSITIVE
|OBJ_PERMANENT
,
68 Status
= NtOpenDirectoryObject(DirHandle
,
71 if (!NT_SUCCESS(Status
))
73 Status
= NtCreateDirectoryObject(DirHandle
,
76 if (!NT_SUCCESS(Status
))
78 DbgPrint("NtCreateDirectoryObject() failed\n");
84 return STATUS_SUCCESS
;
89 BasepInitConsole(VOID
)
91 CSR_API_MESSAGE Request
;
94 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
96 WCHAR lpTest
[MAX_PATH
];
97 GetModuleFileNameW(NULL
, lpTest
, MAX_PATH
);
98 DPRINT("BasepInitConsole for : %S\n", lpTest
);
99 DPRINT("Our current console handles are: %lx, %lx, %lx %lx\n",
100 Parameters
->ConsoleHandle
, Parameters
->StandardInput
,
101 Parameters
->StandardOutput
, Parameters
->StandardError
);
103 /* We have nothing to do if this isn't a console app... */
104 if (RtlImageNtHeader(GetModuleHandle(NULL
))->OptionalHeader
.Subsystem
!=
105 IMAGE_SUBSYSTEM_WINDOWS_CUI
)
107 DPRINT("Image is not a console application\n");
108 Parameters
->ConsoleHandle
= NULL
;
112 /* Assume one is needed */
113 Request
.Data
.AllocConsoleRequest
.ConsoleNeeded
= TRUE
;
115 /* Handle the special flags given to us by BasepInitializeEnvironment */
116 if (Parameters
->ConsoleHandle
== HANDLE_DETACHED_PROCESS
)
118 /* No console to create */
119 DPRINT("No console to create\n");
120 Parameters
->ConsoleHandle
= NULL
;
121 Request
.Data
.AllocConsoleRequest
.ConsoleNeeded
= FALSE
;
123 else if (Parameters
->ConsoleHandle
== HANDLE_CREATE_NEW_CONSOLE
)
125 /* We'll get the real one soon */
126 DPRINT("Creating new console\n");
127 Parameters
->ConsoleHandle
= NULL
;
129 else if (Parameters
->ConsoleHandle
== HANDLE_CREATE_NO_WINDOW
)
131 /* We'll get the real one soon */
132 DPRINT1("NOT SUPPORTED: HANDLE_CREATE_NO_WINDOW\n");
133 Parameters
->ConsoleHandle
= NULL
;
137 if (Parameters
->ConsoleHandle
== INVALID_HANDLE_VALUE
)
139 Parameters
->ConsoleHandle
= 0;
141 DPRINT("Using existing console: %x\n", Parameters
->ConsoleHandle
);
144 /* Initialize Console Ctrl Handler */
145 ConsoleInitialized
= TRUE
;
146 RtlInitializeCriticalSection(&ConsoleLock
);
147 SetConsoleCtrlHandler(DefaultConsoleCtrlHandler
, TRUE
);
149 /* Now use the proper console handle */
150 Request
.Data
.AllocConsoleRequest
.Console
= Parameters
->ConsoleHandle
;
153 * Normally, we should be connecting to the Console CSR Server...
154 * but we don't have one yet, so we will instead simply send a create
155 * console message to the Base Server. When we finally have a Console
156 * Server, this code should be changed to send connection data instead.
158 * Also note that this connection should be made for any console app, even
159 * in the case above where -we- return.
161 CsrRequest
= MAKE_CSR_API(ALLOC_CONSOLE
, CSR_CONSOLE
);
162 Request
.Data
.AllocConsoleRequest
.CtrlDispatcher
= ConsoleControlDispatcher
;
163 Status
= CsrClientCallServer(&Request
,
166 sizeof(CSR_API_MESSAGE
));
167 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
169 DPRINT1("CSR Failed to give us a console\n");
170 /* We're lying here, so at least the process can load... */
174 /* We got the handles, let's set them */
175 if ((Parameters
->ConsoleHandle
= Request
.Data
.AllocConsoleRequest
.Console
))
177 /* If we already had some, don't use the new ones */
178 if (!Parameters
->StandardInput
)
180 Parameters
->StandardInput
= Request
.Data
.AllocConsoleRequest
.InputHandle
;
182 if (!Parameters
->StandardOutput
)
184 Parameters
->StandardOutput
= Request
.Data
.AllocConsoleRequest
.OutputHandle
;
186 if (!Parameters
->StandardError
)
188 Parameters
->StandardError
= Request
.Data
.AllocConsoleRequest
.OutputHandle
;
192 DPRINT("Console setup: %lx, %lx, %lx, %lx\n",
193 Parameters
->ConsoleHandle
,
194 Parameters
->StandardInput
,
195 Parameters
->StandardOutput
,
196 Parameters
->StandardError
);
210 DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
215 case DLL_PROCESS_ATTACH
:
216 DPRINT("DLL_PROCESS_ATTACH\n");
218 LdrDisableThreadCalloutsForDll ((PVOID
)hDll
);
221 * Connect to the csrss server
223 Status
= CsrClientConnectToServer(L
"\\Windows\\ApiPort",
229 if (!NT_SUCCESS(Status
))
231 DbgPrint("Failed to connect to csrss.exe (Status %lx)\n",
233 ZwTerminateProcess(NtCurrentProcess(), Status
);
237 hProcessHeap
= RtlGetProcessHeap();
238 hCurrentModule
= hDll
;
241 * Initialize WindowsDirectory and SystemDirectory
243 DPRINT("NtSystemRoot: %S\n",
244 SharedUserData
->NtSystemRoot
);
245 RtlCreateUnicodeString (&WindowsDirectory
,
246 SharedUserData
->NtSystemRoot
);
247 SystemDirectory
.MaximumLength
= WindowsDirectory
.MaximumLength
+ 18;
248 SystemDirectory
.Length
= WindowsDirectory
.Length
+ 18;
249 SystemDirectory
.Buffer
= RtlAllocateHeap (hProcessHeap
,
251 SystemDirectory
.MaximumLength
);
252 wcscpy (SystemDirectory
.Buffer
, WindowsDirectory
.Buffer
);
253 wcscat (SystemDirectory
.Buffer
, L
"\\System32");
255 /* Open object base directory */
256 Status
= OpenBaseDirectory(&hBaseDir
);
257 if (!NT_SUCCESS(Status
))
259 DbgPrint("Failed to open object base directory (Status %lx)\n",
264 /* Initialize the DLL critical section */
265 RtlInitializeCriticalSection(&DllLock
);
267 /* Initialize the National Language Support routines */
273 /* Initialize Console Support */
274 if (!BasepInitConsole())
276 DPRINT1("Failure to set up console\n");
280 /* Insert more dll attach stuff here! */
282 DllInitialized
= TRUE
;
285 case DLL_PROCESS_DETACH
:
286 DPRINT("DLL_PROCESS_DETACH\n");
287 if (DllInitialized
== TRUE
)
289 /* Insert more dll detach stuff here! */
293 /* Delete DLL critical section */
294 if (ConsoleInitialized
== TRUE
)
296 RtlDeleteCriticalSection (&ConsoleLock
);
298 RtlDeleteCriticalSection (&DllLock
);
300 /* Close object base directory */
303 RtlFreeUnicodeString (&SystemDirectory
);
304 RtlFreeUnicodeString (&WindowsDirectory
);