ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ext2init.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.