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