Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenext2init.c
Go to the documentation of this file.
00001 /************************************************************************* 00002 * 00003 * File: ext2init.c 00004 * 00005 * Module: Ext2 File System Driver (Kernel mode execution only) 00006 * 00007 * Description: 00008 * This file contains the initialization code for the kernel mode 00009 * Ext2 FSD module. The DriverEntry() routine is called by the I/O 00010 * sub-system to initialize the FSD. 00011 * 00012 * Author: Manoj Paul Joseph 00013 * 00014 *************************************************************************/ 00015 00016 00017 #include "ext2fsd.h" 00018 00019 // define the file specific bug-check id 00020 #define EXT2_BUG_CHECK_ID EXT2_FILE_INIT 00021 #define DEBUG_LEVEL (DEBUG_TRACE_INIT) 00022 00023 #define EXT2_FS_NAME L"\\ext2" 00024 00025 // global variables are declared here 00026 Ext2Data Ext2GlobalData; 00027 00028 00029 /************************************************************************* 00030 * 00031 * Function: DriverEntry() 00032 * 00033 * Description: 00034 * This routine is the standard entry point for all kernel mode drivers. 00035 * The routine is invoked at IRQL PASSIVE_LEVEL in the context of a 00036 * system worker thread. 00037 * All FSD specific data structures etc. are initialized here. 00038 * 00039 * Expected Interrupt Level (for execution) : 00040 * 00041 * IRQL_PASSIVE_LEVEL 00042 * 00043 * Return Value: STATUS_SUCCESS/Error (will cause driver to be unloaded). 00044 * 00045 *************************************************************************/ 00046 NTSTATUS NTAPI DriverEntry( 00047 PDRIVER_OBJECT DriverObject, // created by the I/O sub-system 00048 PUNICODE_STRING RegistryPath) // path to the registry key 00049 { 00050 NTSTATUS RC = STATUS_SUCCESS; 00051 UNICODE_STRING DriverDeviceName; 00052 00053 #if 0 00054 Ext2BreakPoint(); 00055 #endif 00056 00057 try 00058 { 00059 try 00060 { 00061 00062 DebugTrace(DEBUG_TRACE_IRP_ENTRY, "Ext2 File System Driver Entry <<<<<<<", 0); 00063 // initialize the global data structure 00064 RtlZeroMemory(&Ext2GlobalData, sizeof(Ext2GlobalData)); 00065 00066 // initialize some required fields 00067 Ext2GlobalData.NodeIdentifier.NodeType = EXT2_NODE_TYPE_GLOBAL_DATA; 00068 Ext2GlobalData.NodeIdentifier.NodeSize = sizeof(Ext2GlobalData); 00069 00070 // initialize the global data resource and remember the fact that 00071 // the resource has been initialized 00072 RC = ExInitializeResourceLite(&(Ext2GlobalData.GlobalDataResource)); 00073 ASSERT(NT_SUCCESS(RC)); 00074 Ext2SetFlag(Ext2GlobalData.Ext2Flags, EXT2_DATA_FLAGS_RESOURCE_INITIALIZED); 00075 00076 // keep a ptr to the driver object sent to us by the I/O Mgr 00077 Ext2GlobalData.Ext2DriverObject = DriverObject; 00078 00079 // initialize the mounted logical volume list head 00080 InitializeListHead( &( Ext2GlobalData.NextVCB ) ); 00081 00082 // before we proceed with any more initialization, read in 00083 // user supplied configurable values ... 00084 // if (!NT_SUCCESS(RC = Ext2ObtainRegistryValues(RegistryPath))) { 00085 // in your commercial driver implementation, it would be 00086 // advisable for your driver to print an appropriate error 00087 // message to the system error log before leaving 00088 // try_return(); 00089 // } 00090 00091 // we should have the registry data (if any), allocate zone memory ... 00092 // This is an example of when FSD implementations try to pre-allocate 00093 // some fixed amount of memory to avoid internal fragmentation and/or waiting 00094 // later during run-time ... 00095 00096 #ifdef USE_ZONES 00097 00098 if (!NT_SUCCESS(RC = Ext2InitializeZones())) 00099 { 00100 // we failed, print a message and leave ... 00101 try_return(); 00102 } 00103 #endif 00104 00105 // 00106 // Initialize the Thread queue structure... 00107 // 00108 KeInitializeEvent( 00109 &Ext2GlobalData.ThreadQueue.QueueEvent, 00110 SynchronizationEvent, 00111 FALSE 00112 ); 00113 KeInitializeSpinLock( &Ext2GlobalData.ThreadQueue.SpinLock ); 00114 InitializeListHead( &Ext2GlobalData.ThreadQueue.ThreadQueueListHead ); 00115 00116 // 00117 // Done Initializing... 00118 // Now Creating a worker thread to handle Worker threads... 00119 // 00120 PsCreateSystemThread( 00121 &Ext2GlobalData.ThreadQueue.QueueHandlerThread, (ACCESS_MASK) 0L, 00122 NULL, NULL, NULL, Ext2QueueHandlerThread, NULL ); 00123 00124 // initialize the IRP major function table, and the fast I/O table 00125 Ext2FsdInitializeFunctionPointers(DriverObject); 00126 00127 // create a device object representing the driver itself 00128 // so that requests can be targeted to the driver ... 00129 // e.g. for a disk-based FSD, "mount" requests will be sent to 00130 // this device object by the I/O Manager. 00131 // For a redirector/server, you may have applications 00132 // send "special" IOCTL's using this device object ... 00133 RtlInitUnicodeString(&DriverDeviceName, EXT2_FS_NAME); 00134 if (!NT_SUCCESS(RC = IoCreateDevice( 00135 DriverObject, // our driver object 00136 0, // don't need an extension for this object 00137 &DriverDeviceName,// name - can be used to "open" the driver 00138 // see the book for alternate choices 00139 FILE_DEVICE_DISK_FILE_SYSTEM, 00140 0, // no special characteristics 00141 // do not want this as an exclusive device, though you might 00142 FALSE, 00143 &(Ext2GlobalData.Ext2DeviceObject)))) 00144 { 00145 // failed to create a device object, leave ... 00146 try_return(); 00147 } 00148 00149 00150 00151 // register the driver with the I/O Manager, pretend as if this is 00152 // a physical disk based FSD (or in order words, this FSD manages 00153 // logical volumes residing on physical disk drives) 00154 IoRegisterFileSystem(Ext2GlobalData.Ext2DeviceObject); 00155 00156 { 00157 TIME_FIELDS TimeFields; 00158 00159 TimeFields.Day = 1; 00160 TimeFields.Hour = 0; 00161 TimeFields.Milliseconds = 0; 00162 TimeFields.Minute = 0; 00163 TimeFields.Month = 1; 00164 TimeFields.Second = 0; 00165 TimeFields.Weekday = 0; 00166 TimeFields.Year = 1970; 00167 RtlTimeFieldsToTime( &TimeFields, &Ext2GlobalData.TimeDiff ); 00168 00169 /* 00170 Ext2GlobalData.TimeDiff.QuadPart = 0; 00171 RtlTimeToTimeFields( &Ext2GlobalData.TimeDiff,&TimeFields ); 00172 TimeFields.Year = 2002; 00173 RtlTimeFieldsToTime( &TimeFields, &Ext2GlobalData.TimeDiff ); 00174 */ 00175 00176 } 00177 } 00178 except (EXCEPTION_EXECUTE_HANDLER) 00179 { 00180 // we encountered an exception somewhere, eat it up 00181 RC = GetExceptionCode(); 00182 } 00183 00184 try_exit: NOTHING; 00185 } 00186 finally 00187 { 00188 // start unwinding if we were unsuccessful 00189 if (!NT_SUCCESS(RC)) 00190 { 00191 00192 // Now, delete any device objects, etc. we may have created 00193 if (Ext2GlobalData.Ext2DeviceObject) 00194 { 00195 IoDeleteDevice(Ext2GlobalData.Ext2DeviceObject); 00196 Ext2GlobalData.Ext2DeviceObject = NULL; 00197 } 00198 00199 // free up any memory we might have reserved for zones/lookaside 00200 // lists 00201 if (Ext2GlobalData.Ext2Flags & EXT2_DATA_FLAGS_ZONES_INITIALIZED) 00202 { 00203 Ext2DestroyZones(); 00204 } 00205 00206 // delete the resource we may have initialized 00207 if (Ext2GlobalData.Ext2Flags & EXT2_DATA_FLAGS_RESOURCE_INITIALIZED) 00208 { 00209 // un-initialize this resource 00210 ExDeleteResourceLite(&(Ext2GlobalData.GlobalDataResource)); 00211 Ext2ClearFlag(Ext2GlobalData.Ext2Flags, EXT2_DATA_FLAGS_RESOURCE_INITIALIZED); 00212 } 00213 } 00214 } 00215 00216 return(RC); 00217 } 00218 00219 /************************************************************************* 00220 * 00221 * Function: Ext2FsdInitializeFunctionPointers() 00222 * 00223 * Description: 00224 * Initialize the IRP... function pointer array in the driver object 00225 * structure. Also initialize the fast-io function ptr array ... 00226 * 00227 * Expected Interrupt Level (for execution) : 00228 * 00229 * IRQL_PASSIVE_LEVEL 00230 * 00231 * Return Value: None 00232 * 00233 *************************************************************************/ 00234 void NTAPI Ext2FsdInitializeFunctionPointers( 00235 PDRIVER_OBJECT DriverObject) // created by the I/O sub-system 00236 { 00237 PFAST_IO_DISPATCH PtrFastIoDispatch = NULL; 00238 00239 // initialize the function pointers for the IRP major 00240 // functions that this FSD is prepared to handle ... 00241 // NT Version 4.0 has 28 possible functions that a 00242 // kernel mode driver can handle. 00243 // NT Version 3.51 and before has only 22 such functions, 00244 // of which 18 are typically interesting to most FSD's. 00245 00246 // The only interesting new functions that a FSD might 00247 // want to respond to beginning with Version 4.0 are the 00248 // IRP_MJ_QUERY_QUOTA and the IRP_MJ_SET_QUOTA requests. 00249 00250 // The code below does not handle quota manipulation, neither 00251 // does the NT Version 4.0 operating system (or I/O Manager). 00252 // However, you should be on the lookout for any such new 00253 // functionality that your FSD might have to implement in 00254 // the near future. 00255 00256 DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create; 00257 DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close; 00258 DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read; 00259 DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write; 00260 00261 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = Ext2FileInfo; 00262 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2FileInfo; 00263 00264 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2Flush; 00265 // To implement support for querying and modifying volume attributes 00266 // (volume information query/set operations), enable initialization 00267 // of the following two function pointers and then implement the supporting 00268 // functions. Use Chapter 11 in the text to assist you in your efforts. 00269 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = Ext2QueryVolInfo; 00270 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = Ext2SetVolInfo; 00271 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = Ext2DirControl; 00272 // To implement support for file system IOCTL calls, enable initialization 00273 // of the following function pointer and implement appropriate support. Use 00274 // Chapter 11 in the text to assist you in your efforts. 00275 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = Ext2FileSystemControl; 00276 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ext2DeviceControl; 00277 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2Shutdown; 00278 // For byte-range lock support, enable initialization of the following 00279 // function pointer and implement appropriate support. Use Chapter 10 00280 // in the text to assist you in your efforts. 00281 // DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = Ext2LockControl; 00282 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2Cleanup; 00283 // If your FSD supports security attributes, you should provide appropriate 00284 // dispatch entry points and initialize the function pointers as given below. 00285 // DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = Ext2Security; 00286 // DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = Ext2Security; 00287 // If you support extended attributes, you should provide appropriate 00288 // dispatch entry points and initialize the function pointers as given below. 00289 // DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = Ext2ExtendedAttr; 00290 // DriverObject->MajorFunction[IRP_MJ_SET_EA] = Ext2ExtendedAttr; 00291 00292 // Now, it is time to initialize the fast-io stuff ... 00293 /* 00294 DriverObject->FastIoDispatch = NULL; 00295 00296 */ 00297 PtrFastIoDispatch = DriverObject->FastIoDispatch = &(Ext2GlobalData.Ext2FastIoDispatch); 00298 00299 // initialize the global fast-io structure 00300 // NOTE: The fast-io structure has undergone a substantial revision 00301 // in Windows NT Version 4.0. The structure has been extensively expanded. 00302 // Therefore, if your driver needs to work on both V3.51 and V4.0+, 00303 // you will have to be able to distinguish between the two versions at compile time. 00304 PtrFastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); 00305 PtrFastIoDispatch->FastIoCheckIfPossible = Ext2FastIoCheckIfPossible; 00306 PtrFastIoDispatch->FastIoRead = Ext2FastIoRead; 00307 PtrFastIoDispatch->FastIoWrite = Ext2FastIoWrite; 00308 PtrFastIoDispatch->FastIoQueryBasicInfo = Ext2FastIoQueryBasicInfo; 00309 PtrFastIoDispatch->FastIoQueryStandardInfo = Ext2FastIoQueryStdInfo; 00310 PtrFastIoDispatch->FastIoLock = Ext2FastIoLock; 00311 PtrFastIoDispatch->FastIoUnlockSingle = Ext2FastIoUnlockSingle; 00312 PtrFastIoDispatch->FastIoUnlockAll = Ext2FastIoUnlockAll; 00313 PtrFastIoDispatch->FastIoUnlockAllByKey = Ext2FastIoUnlockAllByKey; 00314 PtrFastIoDispatch->AcquireFileForNtCreateSection = Ext2FastIoAcqCreateSec; 00315 PtrFastIoDispatch->ReleaseFileForNtCreateSection = Ext2FastIoRelCreateSec; 00316 00317 // the remaining are only valid under NT Version 4.0 and later 00318 #if(_WIN32_WINNT >= 0x0400) 00319 PtrFastIoDispatch->FastIoQueryNetworkOpenInfo = Ext2FastIoQueryNetInfo; 00320 PtrFastIoDispatch->AcquireForModWrite = Ext2FastIoAcqModWrite; 00321 PtrFastIoDispatch->ReleaseForModWrite = Ext2FastIoRelModWrite; 00322 PtrFastIoDispatch->AcquireForCcFlush = Ext2FastIoAcqCcFlush; 00323 PtrFastIoDispatch->ReleaseForCcFlush = Ext2FastIoRelCcFlush; 00324 00325 // MDL functionality 00326 PtrFastIoDispatch->MdlRead = Ext2FastIoMdlRead; 00327 PtrFastIoDispatch->MdlReadComplete = Ext2FastIoMdlReadComplete; 00328 PtrFastIoDispatch->PrepareMdlWrite = Ext2FastIoPrepareMdlWrite; 00329 PtrFastIoDispatch->MdlWriteComplete = Ext2FastIoMdlWriteComplete; 00330 00331 // although this FSD does not support compressed read/write functionality, 00332 // NTFS does, and if you design a FSD that can provide such functionality, 00333 // you should consider initializing the fast io entry points for reading 00334 // and/or writing compressed data ... 00335 #endif // (_WIN32_WINNT >= 0x0400) 00336 00337 00338 // last but not least, initialize the Cache Manager callback functions 00339 // which are used in CcInitializeCacheMap() 00340 Ext2GlobalData.CacheMgrCallBacks.AcquireForLazyWrite = Ext2AcqLazyWrite; 00341 Ext2GlobalData.CacheMgrCallBacks.ReleaseFromLazyWrite = Ext2RelLazyWrite; 00342 Ext2GlobalData.CacheMgrCallBacks.AcquireForReadAhead = Ext2AcqReadAhead; 00343 Ext2GlobalData.CacheMgrCallBacks.ReleaseFromReadAhead = Ext2RelReadAhead; 00344 00345 return; 00346 } 00347 00348 00349 VOID NTAPI Ext2QueueHandlerThread( 00350 IN PVOID StartContext ) 00351 { 00352 00353 DebugTrace(DEBUG_TRACE_MISC, "Ext2QueueHandlerThread!!!", 0); 00354 00355 while( 1 ) 00356 { 00357 KeWaitForSingleObject( &Ext2GlobalData.ThreadQueue.QueueEvent, 00358 Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL ); 00359 00360 DebugTrace(DEBUG_TRACE_MISC, "Ext2QueueHandlerThread Alerted!!!", 0); 00361 00362 while( !IsListEmpty( &Ext2GlobalData.ThreadQueue.ThreadQueueListHead ) ) 00363 { 00364 HANDLE ThreadHandle; 00365 PLIST_ENTRY PtrEntry = NULL; 00366 PtrExt2IrpContext PtrIrpContext = NULL; 00367 00368 00369 PtrEntry = ExInterlockedRemoveHeadList( 00370 &Ext2GlobalData.ThreadQueue.ThreadQueueListHead, 00371 &Ext2GlobalData.ThreadQueue.SpinLock ); 00372 ASSERT( PtrEntry ); 00373 PtrIrpContext = CONTAINING_RECORD( PtrEntry, Ext2IrpContext, ThreadQueueListEntry ); 00374 00375 PsCreateSystemThread( 00376 &ThreadHandle, (ACCESS_MASK) 0L, 00377 NULL, NULL, NULL, Ext2CommonDispatch, PtrIrpContext ); 00378 } 00379 } 00380 } Generated on Mon May 28 2012 04:27:23 for ReactOS by
1.7.6.1
|