[CDFS_NEW] Bugfix for f88fe43: don't delete devices twice on shutdown.
[reactos.git] / drivers / filesystems / cdfs_new / cdinit.c
1 /*++
2
3 Copyright (c) 1989-2000 Microsoft Corporation
4
5 Module Name:
6
7 CdInit.c
8
9 Abstract:
10
11 This module implements the DRIVER_INITIALIZATION routine for Cdfs
12
13
14 --*/
15
16 #include "cdprocs.h"
17
18 //
19 // The Bug check file id for this module
20 //
21
22 #define BugCheckFileId (CDFS_BUG_CHECK_CDINIT)
23
24 NTSTATUS
25 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
26 DriverEntry(
27 IN PDRIVER_OBJECT DriverObject,
28 IN PUNICODE_STRING RegistryPath
29 );
30
31 VOID
32 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
33 CdUnload(
34 IN PDRIVER_OBJECT DriverObject
35 );
36
37 NTSTATUS
38 CdInitializeGlobalData (
39 IN PDRIVER_OBJECT DriverObject,
40 IN PDEVICE_OBJECT FileSystemDeviceObject
41 #ifdef __REACTOS__
42 ,
43 IN PDEVICE_OBJECT HddFileSystemDeviceObject
44 #endif
45 );
46
47 NTSTATUS
48 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
49 CdShutdown (
50 IN PDEVICE_OBJECT DeviceObject,
51 IN PIRP Irp
52 );
53
54 #ifdef ALLOC_PRAGMA
55 #pragma alloc_text(INIT, DriverEntry)
56 #pragma alloc_text(PAGE, CdUnload)
57 #pragma alloc_text(PAGE, CdShutdown)
58 #pragma alloc_text(INIT, CdInitializeGlobalData)
59 #endif
60
61 \f
62 //
63 // Local support routine
64 //
65
66 NTSTATUS
67 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
68 DriverEntry(
69 IN PDRIVER_OBJECT DriverObject,
70 IN PUNICODE_STRING RegistryPath
71 )
72
73 /*++
74
75 Routine Description:
76
77 This is the initialization routine for the Cdrom file system
78 device driver. This routine creates the device object for the FileSystem
79 device and performs all other driver initialization.
80
81 Arguments:
82
83 DriverObject - Pointer to driver object created by the system.
84
85 Return Value:
86
87 NTSTATUS - The function value is the final status from the initialization
88 operation.
89
90 --*/
91
92 {
93 NTSTATUS Status;
94 UNICODE_STRING UnicodeString;
95 PDEVICE_OBJECT CdfsFileSystemDeviceObject;
96 #ifdef __REACTOS__
97 PDEVICE_OBJECT HddFileSystemDeviceObject;
98 #endif
99
100 //
101 // Create the device object.
102 //
103
104 RtlInitUnicodeString( &UnicodeString, L"\\Cdfs" );
105
106 Status = IoCreateDevice( DriverObject,
107 0,
108 &UnicodeString,
109 FILE_DEVICE_CD_ROM_FILE_SYSTEM,
110 0,
111 FALSE,
112 &CdfsFileSystemDeviceObject );
113
114 if (!NT_SUCCESS( Status )) {
115 return Status;
116 }
117
118 #ifdef __REACTOS__
119 //
120 // Create the HDD device object.
121 //
122
123 RtlInitUnicodeString( &UnicodeString, L"\\CdfsHdd" );
124
125 Status = IoCreateDevice( DriverObject,
126 0,
127 &UnicodeString,
128 FILE_DEVICE_DISK_FILE_SYSTEM,
129 0,
130 FALSE,
131 &HddFileSystemDeviceObject );
132
133 if (!NT_SUCCESS( Status )) {
134 IoDeleteDevice (CdfsFileSystemDeviceObject);
135 return Status;
136 }
137 #endif
138 DriverObject->DriverUnload = CdUnload;
139 //
140 // Note that because of the way data caching is done, we set neither
141 // the Direct I/O or Buffered I/O bit in DeviceObject->Flags. If
142 // data is not in the cache, or the request is not buffered, we may,
143 // set up for Direct I/O by hand.
144 //
145
146 //
147 // Initialize the driver object with this driver's entry points.
148 //
149 // NOTE - Each entry in the dispatch table must have an entry in
150 // the Fsp/Fsd dispatch switch statements.
151 //
152
153 DriverObject->MajorFunction[IRP_MJ_CREATE] =
154 DriverObject->MajorFunction[IRP_MJ_CLOSE] =
155 DriverObject->MajorFunction[IRP_MJ_READ] =
156 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
157 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
158 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]=
159 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
160 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
161 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
162 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] =
163 DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
164 DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH) CdFsdDispatch;
165 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = CdShutdown;
166
167 DriverObject->FastIoDispatch = &CdFastIoDispatch;
168
169 Status = IoRegisterShutdownNotification (CdfsFileSystemDeviceObject);
170 if (!NT_SUCCESS (Status)) {
171 IoDeleteDevice (CdfsFileSystemDeviceObject);
172 #ifdef __REACTOS__
173 IoDeleteDevice (HddFileSystemDeviceObject);
174 #endif
175 return Status;
176 }
177
178 //
179 // Initialize the global data structures
180 //
181
182 #ifndef __REACTOS__
183 Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject );
184 #else
185 Status = CdInitializeGlobalData( DriverObject, CdfsFileSystemDeviceObject, HddFileSystemDeviceObject );
186 #endif
187 if (!NT_SUCCESS (Status)) {
188 IoDeleteDevice (CdfsFileSystemDeviceObject);
189 #ifdef __REACTOS__
190 IoDeleteDevice (HddFileSystemDeviceObject);
191 #endif
192 return Status;
193 }
194
195 //
196 // Register the file system as low priority with the I/O system. This will cause
197 // CDFS to receive mount requests after a) other filesystems currently registered
198 // and b) other normal priority filesystems that may be registered later.
199 //
200
201 CdfsFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM;
202 #ifdef __REACTOS__
203 HddFileSystemDeviceObject->Flags |= DO_LOW_PRIORITY_FILESYSTEM;
204 #endif
205
206 IoRegisterFileSystem( CdfsFileSystemDeviceObject );
207 ObReferenceObject (CdfsFileSystemDeviceObject);
208 #ifdef __REACTOS__
209 IoRegisterFileSystem( HddFileSystemDeviceObject );
210 ObReferenceObject (HddFileSystemDeviceObject);
211 #endif
212
213 //
214 // And return to our caller
215 //
216
217 return( STATUS_SUCCESS );
218 }
219
220 NTSTATUS
221 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
222 CdShutdown (
223 IN PDEVICE_OBJECT DeviceObject,
224 IN PIRP Irp
225 )
226 /*++
227
228 Routine Description:
229
230 This routine is the shutdown handler for CDFS.
231
232 Arguments:
233
234 DeviceObject - Supplies the registered device object for CDFS.
235 Irp - Shutdown IRP
236
237
238 Return Value:
239
240 None.
241
242 --*/
243 {
244 #ifdef __REACTOS__
245 ASSERT(DeviceObject == CdData.FileSystemDeviceObject ||
246 DeviceObject == CdData.HddFileSystemDeviceObject);
247 #endif
248
249 IoUnregisterFileSystem (DeviceObject);
250 #ifndef __REACTOS__
251 IoDeleteDevice (CdData.FileSystemDeviceObject);
252 #else
253 IoDeleteDevice (DeviceObject);
254 #endif
255
256 CdCompleteRequest( NULL, Irp, STATUS_SUCCESS );
257 return STATUS_SUCCESS;
258 }
259
260
261 VOID
262 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
263 CdUnload(
264 IN PDRIVER_OBJECT DriverObject
265 )
266 /*++
267
268 Routine Description:
269
270 This routine unload routine for CDFS.
271
272 Arguments:
273
274 DriverObject - Supplies the driver object for CDFS.
275
276 Return Value:
277
278 None.
279
280 --*/
281 {
282 PIRP_CONTEXT IrpContext;
283
284 //
285 // Free any IRP contexts
286 //
287 while (1) {
288 IrpContext = (PIRP_CONTEXT) PopEntryList( &CdData.IrpContextList) ;
289 if (IrpContext == NULL) {
290 break;
291 }
292 CdFreePool(&IrpContext);
293 }
294
295 IoFreeWorkItem (CdData.CloseItem);
296 ExDeleteResourceLite( &CdData.DataResource );
297 ObDereferenceObject (CdData.FileSystemDeviceObject);
298 #ifdef __REACTOS__
299 ObDereferenceObject (CdData.HddFileSystemDeviceObject);
300 #endif
301 }
302 \f
303 //
304 // Local support routine
305 //
306
307 NTSTATUS
308 CdInitializeGlobalData (
309 IN PDRIVER_OBJECT DriverObject,
310 IN PDEVICE_OBJECT FileSystemDeviceObject
311 #ifdef __REACTOS__
312 ,
313 IN PDEVICE_OBJECT HddFileSystemDeviceObject
314 #endif
315 )
316
317 /*++
318
319 Routine Description:
320
321 This routine initializes the global cdfs data structures.
322
323 Arguments:
324
325 DriverObject - Supplies the driver object for CDFS.
326
327 FileSystemDeviceObject - Supplies the device object for CDFS.
328
329 Return Value:
330
331 None.
332
333 --*/
334
335 {
336 //
337 // Start by initializing the FastIoDispatch Table.
338 //
339
340 RtlZeroMemory( &CdFastIoDispatch, sizeof( FAST_IO_DISPATCH ));
341
342 CdFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
343 CdFastIoDispatch.FastIoCheckIfPossible = CdFastIoCheckIfPossible; // CheckForFastIo
344 CdFastIoDispatch.FastIoRead = FsRtlCopyRead; // Read
345 CdFastIoDispatch.FastIoQueryBasicInfo = CdFastQueryBasicInfo; // QueryBasicInfo
346 CdFastIoDispatch.FastIoQueryStandardInfo = CdFastQueryStdInfo; // QueryStandardInfo
347 CdFastIoDispatch.FastIoLock = CdFastLock; // Lock
348 CdFastIoDispatch.FastIoUnlockSingle = CdFastUnlockSingle; // UnlockSingle
349 CdFastIoDispatch.FastIoUnlockAll = CdFastUnlockAll; // UnlockAll
350 CdFastIoDispatch.FastIoUnlockAllByKey = CdFastUnlockAllByKey; // UnlockAllByKey
351 CdFastIoDispatch.AcquireFileForNtCreateSection = CdAcquireForCreateSection;
352 CdFastIoDispatch.ReleaseFileForNtCreateSection = CdReleaseForCreateSection;
353 CdFastIoDispatch.FastIoQueryNetworkOpenInfo = CdFastQueryNetworkInfo; // QueryNetworkInfo
354
355 CdFastIoDispatch.MdlRead = FsRtlMdlReadDev;
356 CdFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev;
357 CdFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
358 CdFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev;
359
360 //
361 // Initialize the CdData structure.
362 //
363
364 RtlZeroMemory( &CdData, sizeof( CD_DATA ));
365
366 CdData.NodeTypeCode = CDFS_NTC_DATA_HEADER;
367 CdData.NodeByteSize = sizeof( CD_DATA );
368
369 CdData.DriverObject = DriverObject;
370 CdData.FileSystemDeviceObject = FileSystemDeviceObject;
371 #ifdef __REACTOS__
372 CdData.HddFileSystemDeviceObject = HddFileSystemDeviceObject;
373 #endif
374
375 InitializeListHead( &CdData.VcbQueue );
376
377 ExInitializeResourceLite( &CdData.DataResource );
378
379 //
380 // Initialize the cache manager callback routines
381 //
382
383 CdData.CacheManagerCallbacks.AcquireForLazyWrite = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
384 CdData.CacheManagerCallbacks.ReleaseFromLazyWrite = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
385 CdData.CacheManagerCallbacks.AcquireForReadAhead = (PVOID)&CdAcquireForCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
386 CdData.CacheManagerCallbacks.ReleaseFromReadAhead = (PVOID)&CdReleaseFromCache;/* ReactOS Change: GCC "assignment from incompatible pointer type" */
387
388 CdData.CacheManagerVolumeCallbacks.AcquireForLazyWrite = &CdNoopAcquire;
389 CdData.CacheManagerVolumeCallbacks.ReleaseFromLazyWrite = &CdNoopRelease;
390 CdData.CacheManagerVolumeCallbacks.AcquireForReadAhead = &CdNoopAcquire;
391 CdData.CacheManagerVolumeCallbacks.ReleaseFromReadAhead = &CdNoopRelease;
392
393 //
394 // Initialize the lock mutex and the async and delay close queues.
395 //
396
397 ExInitializeFastMutex( &CdData.CdDataMutex );
398 InitializeListHead( &CdData.AsyncCloseQueue );
399 InitializeListHead( &CdData.DelayedCloseQueue );
400
401 CdData.CloseItem = IoAllocateWorkItem (FileSystemDeviceObject);
402 if (CdData.CloseItem == NULL) {
403
404 ExDeleteResourceLite( &CdData.DataResource );
405 return STATUS_INSUFFICIENT_RESOURCES;
406 }
407 //
408 // Do the initialization based on the system size.
409 //
410
411 switch (MmQuerySystemSize()) {
412
413 case MmSmallSystem:
414
415 CdData.IrpContextMaxDepth = 4;
416 CdData.MaxDelayedCloseCount = 8;
417 CdData.MinDelayedCloseCount = 2;
418 break;
419
420 case MmMediumSystem:
421
422 CdData.IrpContextMaxDepth = 8;
423 CdData.MaxDelayedCloseCount = 24;
424 CdData.MinDelayedCloseCount = 6;
425 break;
426
427 case MmLargeSystem:
428
429 CdData.IrpContextMaxDepth = 32;
430 CdData.MaxDelayedCloseCount = 72;
431 CdData.MinDelayedCloseCount = 18;
432 break;
433 }
434 return STATUS_SUCCESS;
435 }
436