2 * Init and cleanup code of libcaptive to be called by client application
3 * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "captive/client.h" /* self */
23 #include "captive/ldr.h"
24 #include "captive/ldr_exports.h"
25 #include "captive/unicode.h"
26 #include "captive/file.h"
27 #include <glib/gtypes.h>
28 #include <glib/gmessages.h>
29 #include "reactos/internal/ldr.h"
30 #include "reactos/napi/types.h"
31 #include "reactos/internal/kd.h" /* for KDB_LOADDRIVER_HOOK */
33 #include <sys/mman.h> /* for PROT_READ, MAP_SHARED */
34 #include "reactos/ddk/kefuncs.h" /* for KeInitializeSpinLock() */
35 #include "reactos/internal/ntoskrnl.h" /* for RtlpInitNlsTables() and IoInit() */
36 #include "reactos/internal/ps.h" /* for PsInitProcessManagment() and PsInitThreadManagment() */
37 #include "reactos/ddk/iofuncs.h" /* for IoCreateFile() */
38 #include "captive/storage.h"
39 #include "captive/signal.h" /* for captive_signal_init() */
40 #include "reactos/ddk/psfuncs.h" /* for PsGetCurrentThread() */
43 /* Are we initialized? */
44 static gboolean active;
46 /* Module of fs module itself loaded by captive_init(fs_path) */
47 static PMODULE_OBJECT ModuleObject;
49 /* Driver in fs module loaded by captive_init(fs_path) */
50 static DRIVER_OBJECT DriverObject;
52 /* Handle for the root directory of the mounted volume */
53 static HANDLE root_Handle;
55 /* Structure holding the pointer to the toplevel IRP */
56 static TOP_LEVEL_IRP TopLevelIrp; /* TODO:thread */
61 * @fs_path: Host OS file #utf8 pathname of the filesystem module to load.
62 * %NULL value is forbidden.
63 * @image_pathname: Host OS file #utf8 pathname of the disk image to mount.
64 * %NULL value is forbidden.
66 * Initializes %libcaptive and loads the specified filesystem.
68 * Returns: %TRUE if successfuly loaded.
70 gboolean captive_init(const gchar *fs_path,const gchar *image_pathname)
74 OBJECT_ATTRIBUTES root_ObjectAttributes;
75 IO_STATUS_BLOCK root_IoStatusBlock;
77 FILE_ID_BOTH_DIR_INFORMATION *FileIdBothDirInformation;
79 char QueryDirectory_buf[0x10000];
81 #ifdef MAINTAINER_MODE
82 g_log_set_always_fatal(~(0
89 g_return_val_if_fail(fs_path!=NULL,FALSE);
90 g_return_val_if_fail(image_pathname!=NULL,FALSE);
91 g_return_val_if_fail(active==FALSE,FALSE);
93 /* Part of reactos/ntoskrnl/ke/main.c/KiSystemStartup() begins. */
94 /* ExpInitializeExecutive(); */
95 /* Part of reactos/ntoskrnl/ke/main.c/ExpInitializeExecutive() begins
96 * here as the rest of the function does a lot of hardware initializations.
99 /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInit1() begins. */
100 InitializeListHead(&ModuleTextListHead);
101 /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInit1() ends. */
103 /* create default nls tables */
108 /* PiInitProcessManager(); */
109 /* Part of reactos/ntoskrnl/ps/psmgr.c/PiInitProcessManager() begins. */
110 PsInitProcessManagment();
111 PsInitThreadManagment();
112 /* Part of reactos/ntoskrnl/ps/psmgr.c/PiInitProcessManager() ends. */
116 /* LdrInitModuleManagement(); */
117 /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInitModuleManagement() begins
118 * here as the rest "Create module object for {NTOSKRNL,HAL}"
119 * is dependent on {NTOSKRNL,HAL} PE image headers not provided by libcaptive.
121 /* Initialize the module list and spinlock */
122 InitializeListHead(&ModuleListHead);
123 KeInitializeSpinLock(&ModuleListLock);
124 /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInitModuleManagement ends. */
125 /* Part of reactos/ntoskrnl/ke/main.c/ExpInitializeExecutive() ends. */
126 /* Part of reactos/ntoskrnl/ke/main.c/KiSystemStartup() ends. */
128 /* Simulate our PE headers and export the symbols of {NTOSKRNL,HAL} */
129 captive_kernel_exports();
131 errbool=captive_cdrom_init(image_pathname);
132 g_return_val_if_fail(errbool==TRUE,FALSE);
134 err=captive_LdrpLoadAndCallImage(
135 &ModuleObject, /* ModuleObjectp */
136 captive_utf8_to_UnicodeString_alloca(fs_path), /* ModuleName */
137 &DriverObject, /* DriverEntry_DriverObject */
138 captive_utf8_to_UnicodeString_alloca("\\captive\\filesystem")); /* DriverEntry_RegistryPath */
139 g_return_val_if_fail(NT_SUCCESS(err),FALSE);
141 /* set TopLevelIrp() - FIXME: where is it set by native reactos? */
142 PsGetCurrentThread()->TopLevelIrp=&TopLevelIrp; /* otherwise Io{Get,Set}TopLevelIrp() would SIGSEGV */
144 /* Begin possible handling of foreign W32 binary code here */
145 /* If you want to disable SIGSEGV handler if not needed:
146 * if (ModuleObject->Flags & MODULE_FLAG_PE)
148 captive_signal_init();
150 /* Do not open "\Cdfs"(anything) as it is just the filesystem implementation.
151 * ntoskrnl/io/fs.c/IoMountVolume() will map
152 * FILE_DEVICE_CD_ROM -> FILE_DEVICE_CD_ROM_FILE_SYSTEM
153 * for us automatically when opening the device itself.
154 * Also you must put some trailing content there as otherwise
155 * IoCreateFile()->ObCreateObject()->ObFindObject()
156 * would leave 'ObCreateObject::RemainingPath' as NULL
157 * and later IopCreateFile() would consider it FO_DIRECT_DEVICE_OPEN (e.g. w/o any mount!)
159 InitializeObjectAttributes(
160 &root_ObjectAttributes, /* InitializedAttributes */
161 captive_utf8_to_UnicodeString_alloca("\\Device\\CdRom0\\."), /* ObjectName */
162 0, /* Attributes; I hope no OBJ_KERNEL_HANDLE as we are 'system process' */
163 NULL, /* RootDirectory */
164 NULL); /* SecurityDescriptor; ignored */
166 /* wanted: * IoCreateFile()->ObCreateObject(,,,IoFileObjectType)->
167 * ->(IoFileObjectType->Create==IopCreateFile)()->IoMountVolume()
170 &root_Handle, /* FileHandle */
171 FILE_LIST_DIRECTORY, /* DesiredAccess */
172 &root_ObjectAttributes, /* ObjectAttributes */
173 &root_IoStatusBlock, /* IoStatusBlock */
174 NULL, /* AllocationSize; ignored for open */
175 FILE_ATTRIBUTE_NORMAL, /* FileAttributes; ignored for open */
176 0, /* ShareAccess; 0 means exclusive */
177 FILE_OPEN, /* CreateDisposition */
178 /* FILE_SYNCHRONOUS_IO_{,NON}ALERT: We need to allow W32 filesystem
179 * any waits to not to let it return STATUS_CANT_WAIT us.
180 * Alertability should have only effect on asynchronous events
181 * from KeWaitForSingleObject() by setting/clearing its parameter 'Alertable'.
183 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_ALERT, /* CreateOptions */
186 CreateFileTypeNone, /* CreateFileType */
187 NULL, /* ExtraCreateParameters */
189 g_return_val_if_fail(NT_SUCCESS(err),FALSE);
190 g_return_val_if_fail(NT_SUCCESS(root_IoStatusBlock.Status),FALSE);
191 g_return_val_if_fail(root_IoStatusBlock.Information==FILE_OPENED,FALSE);
194 err=NtQueryDirectoryFile(
195 root_Handle, /* FileHandle */
196 NULL, /* PEvent; completion signalling; optional */
197 NULL, /* ApcRoutine; optional */
198 NULL, /* ApcContext; optional */
199 &root_IoStatusBlock, /* IoStatusBlock */
200 (gpointer)QueryDirectory_buf, /* FileInformation */
201 sizeof(QueryDirectory_buf), /* Length */
202 FileIdBothDirectoryInformation, /* FileInformationClass; =>FILE_ID_BOTH_DIR_INFORMATION */
203 FALSE, /* ReturnSingleEntry */
204 NULL, /* FileName; wildcards possible; optional */
205 TRUE); /* RestartScan */
206 g_return_val_if_fail(NT_SUCCESS(err),FALSE);
207 g_return_val_if_fail(NT_SUCCESS(root_IoStatusBlock.Status),FALSE);
218 * Closes #libcaptive. Frees any used system resources. You are forbidden
219 * to touch any #libcaptive data or funtions before a new captive_init()
220 * is done. Forbidden to call it before successful captive_init() is done.
222 * Currently this function IS NOT IMPLEMENTED.
224 * Returns: %TRUE if the successful resource cleanup was done during the call.
226 gboolean captive_cleanup(void)
230 g_return_val_if_fail(active==TRUE,FALSE);
232 err=LdrUnloadModule(ModuleObject);
233 g_assert(NT_SUCCESS(err));
235 /* captive_cleanup() NOT IMPLEMENTED */
236 g_return_val_if_reached(FALSE);