Fixed missing 'DriverEntry_RegistryPath' registry path for W32 filesystem
[captive.git] / src / libcaptive / client / init.c
1 /* $Id$
2  * Init and cleanup code of libcaptive to be called by client application
3  * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
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
8  * 
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.
13  * 
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
17  */
18
19
20 #include "config.h"
21
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 */
32 #include <fcntl.h>
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
39
40 /* Are we initialized? */
41 static gboolean active;
42
43 /* Module of fs module itself loaded by captive_init(fs_path) */
44 static PMODULE_OBJECT ModuleObject;
45
46 /* Driver in fs module loaded by captive_init(fs_path) */
47 static DRIVER_OBJECT DriverObject;
48
49 /* Handle for the root directory of the mounted volume */
50 static HANDLE root_Handle;
51
52 /**
53  * captive_init:
54  * @fs_path: #utf8 pathname to %.sys filesystem module file
55  *
56  * Initializes %libcaptive and loads the specified filesystem.
57  *
58  * Returns: %TRUE if successfuly loaded.
59  */
60 gboolean captive_init(const gchar *fs_path)
61 {
62 NTSTATUS err;
63 OBJECT_ATTRIBUTES root_ObjectAttributes;
64 IO_STATUS_BLOCK root_IoStatusBlock;
65
66 #ifdef MAINTAINER_MODE
67         g_log_set_always_fatal(~(0
68                         |G_LOG_LEVEL_MESSAGE
69                         |G_LOG_LEVEL_INFO
70                         |G_LOG_LEVEL_DEBUG
71                         ));
72 #endif
73
74         g_return_val_if_fail(fs_path!=NULL,FALSE);
75         g_return_val_if_fail(active==FALSE,FALSE);
76
77         /* Part of reactos/ntoskrnl/ke/main.c/KiSystemStartup() begins. */
78         /* ExpInitializeExecutive(); */
79                 /* Part of reactos/ntoskrnl/ke/main.c/ExpInitializeExecutive() begins
80                  * here as the rest of the function does a lot of hardware initializations.
81                  */
82                 /* LdrInit1(); */
83                         /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInit1() begins. */
84                         InitializeListHead(&ModuleTextListHead);
85                         /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInit1() ends. */
86                 /*...*/
87                 /* create default nls tables */
88                 RtlpInitNlsTables();
89                 /*...*/
90                 ObInit();
91                 /*...*/
92                 /* PiInitProcessManager(); */
93                         /* Part of reactos/ntoskrnl/ps/psmgr.c/PiInitProcessManager() begins. */
94                         PsInitProcessManagment();
95                         PsInitThreadManagment();
96                         /* Part of reactos/ntoskrnl/ps/psmgr.c/PiInitProcessManager() ends. */
97                 /*...*/
98                 IoInit();
99                 /*...*/
100                 /* LdrInitModuleManagement(); */
101                         /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInitModuleManagement() begins
102                          * here as the rest "Create module object for {NTOSKRNL,HAL}"
103                          * is dependent on {NTOSKRNL,HAL} PE image headers not provided by libcaptive.
104                          */
105                         /* Initialize the module list and spinlock */
106                         InitializeListHead(&ModuleListHead);
107                         KeInitializeSpinLock(&ModuleListLock);
108                         /* Part of reactos/ntoskrnl/ldr/loader.c/LdrInitModuleManagement ends. */
109                 /* Part of reactos/ntoskrnl/ke/main.c/ExpInitializeExecutive() ends. */
110         /* Part of reactos/ntoskrnl/ke/main.c/KiSystemStartup() ends. */
111
112         /* Simulate our PE headers and export the symbols of {NTOSKRNL,HAL} */
113         captive_kernel_exports();
114
115         err=captive_LdrpLoadAndCallImage(
116                         &ModuleObject,  /* ModuleObjectp */
117                         captive_utf8_to_UnicodeString_alloca(fs_path),  /* ModuleName */
118                         &DriverObject,  /* DriverEntry_DriverObject */
119                         captive_utf8_to_UnicodeString_alloca("\\captive\\filesystem")); /* DriverEntry_RegistryPath */
120         g_return_val_if_fail(NT_SUCCESS(err),FALSE);
121         
122         /* Do not supply plain "\\Cdfs" as 'ObjectName' as
123          * IoCreateFile()->ObCreateObject()->ObFindObject()
124          * would leave 'ObCreateObject::RemainingPath' as NULL
125          * and later IopCreateFile() would consider it FO_DIRECT_DEVICE_OPEN (w/o mount)
126          */
127         InitializeObjectAttributes(
128                         &root_ObjectAttributes, /* InitializedAttributes */
129                         captive_utf8_to_UnicodeString_alloca("\\Cdfs\\."),      /* ObjectName */
130                         0,      /* Attributes; I hope no OBJ_KERNEL_HANDLE as we are 'system process' */
131                         NULL,   /* RootDirectory */
132                         NULL);  /* SecurityDescriptor; ignored */
133
134         /* wanted: * IoCreateFile()->ObCreateObject(,,,IoFileObjectType)->
135          * ->(IoFileObjectType->Create==IopCreateFile)()->IoMountVolume()
136          */
137         err=IoCreateFile(
138                         &root_Handle,   /* FileHandle */
139                         FILE_LIST_DIRECTORY,    /* DesiredAccess */
140                         &root_ObjectAttributes, /* ObjectAttributes */
141                         &root_IoStatusBlock,    /* IoStatusBlock */
142                         NULL,   /* AllocationSize; ignored for open */
143                         FILE_ATTRIBUTE_NORMAL,  /* FileAttributes; ignored for open */
144                         0,      /* ShareAccess; 0 means exclusive */
145                         FILE_OPEN,      /* CreateDisposition */
146                         FILE_DIRECTORY_FILE,    /* CreateOptions */
147                         NULL,   /* EaBuffer */
148                         0,      /* EaLength */
149                         CreateFileTypeNone,     /* CreateFileType */
150                         NULL,   /* ExtraCreateParameters */
151                         0);     /* Options */
152         g_return_val_if_fail(NT_SUCCESS(err),FALSE);
153         g_return_val_if_fail(NT_SUCCESS(root_IoStatusBlock.Status),FALSE);
154         g_return_val_if_fail(root_IoStatusBlock.Information==FILE_OPENED,FALSE);
155
156
157         active=TRUE;
158         return TRUE;
159 }
160
161
162 /**
163  * captive_cleanup:
164  *
165  * Closes #libcaptive. Frees any used system resources. You are forbidden
166  * to touch any #libcaptive data or funtions before a new captive_init()
167  * is done. Forbidden to call it before successful captive_init() is done.
168  *
169  * Currently this function IS NOT IMPLEMENTED.
170  *
171  * Returns: %TRUE if the successful resource cleanup was done during the call.
172  */
173 gboolean captive_cleanup(void)
174 {
175 NTSTATUS err;
176
177         g_return_val_if_fail(active==TRUE,FALSE);
178
179         err=LdrUnloadModule(ModuleObject);
180         g_assert(NT_SUCCESS(err));
181
182         /* captive_cleanup() NOT IMPLEMENTED */
183         g_return_val_if_reached(FALSE);
184
185         active=FALSE;
186         return TRUE;
187 }