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