Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: dispatch.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
/* INCLUDES *****************************************************************/
#include "ext2fs.h"
/* GLOBALS ***************************************************************/
extern PEXT2_GLOBAL Ext2Global;
/* DEFINITIONS *************************************************************/
#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, Ext2QueueRequest)#pragma alloc_text(PAGE, Ext2DeQueueRequest)#endif
/* * Ext2OplockComplete * * callback routine of FsRtlCheckOplock when an oplock break has * completed, allowing an Irp to resume execution. * * Arguments: * * Context: the IrpContext to be queued * Irp: the I/O request packet * * Return Value: * N/A */
#ifdef __REACTOS__VOID NTAPI#elseVOID#endifExt2OplockComplete ( IN PVOID Context, IN PIRP Irp){ // // Check on the return value in the Irp. //
if (Irp->IoStatus.Status == STATUS_SUCCESS) {
// // queue the Irp context in the workqueue. //
Ext2QueueRequest((PEXT2_IRP_CONTEXT)Context);
} else {
// // complete the request in case of failure //
Ext2CompleteIrpContext( (PEXT2_IRP_CONTEXT) Context, Irp->IoStatus.Status ); }
return;}
/* * Ext2LockIrp * * performs buffer locking if we need pend the process of the Irp * * Arguments: * Context: the irp context * Irp: the I/O request packet. * * Return Value: * N/A */
#ifdef __REACTOS__VOID NTAPI#elseVOID#endifExt2LockIrp ( IN PVOID Context, IN PIRP Irp){ PIO_STACK_LOCATION IrpSp; PEXT2_IRP_CONTEXT IrpContext;
if (Irp == NULL) { return; }
IrpSp = IoGetCurrentIrpStackLocation(Irp);
IrpContext = (PEXT2_IRP_CONTEXT) Context;
if ( IrpContext->MajorFunction == IRP_MJ_READ || IrpContext->MajorFunction == IRP_MJ_WRITE ) {
// // lock the user's buffer to MDL, if the I/O is bufferred //
if (!IsFlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
Ext2LockUserBuffer( Irp, IrpSp->Parameters.Write.Length, (IrpContext->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess ); }
} else if (IrpContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL && IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.QueryDirectory.Length; Ext2LockUserBuffer(Irp, Length, IoWriteAccess);
} else if (IrpContext->MajorFunction == IRP_MJ_QUERY_EA) {
ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.QueryEa.Length; Ext2LockUserBuffer(Irp, Length, IoWriteAccess);
} else if (IrpContext->MajorFunction == IRP_MJ_SET_EA) { ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.SetEa.Length; Ext2LockUserBuffer(Irp, Length, IoReadAccess);
} else if ( (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) && (IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST) ) { PEXTENDED_IO_STACK_LOCATION EIrpSp = (PEXTENDED_IO_STACK_LOCATION)IrpSp; if ( (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_VOLUME_BITMAP) || (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_RETRIEVAL_POINTERS) || (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_RETRIEVAL_POINTER_BASE) ) { ULONG Length = EIrpSp->Parameters.FileSystemControl.OutputBufferLength; Ext2LockUserBuffer(Irp, Length, IoWriteAccess); } }
// Mark the request as pending status
IoMarkIrpPending( Irp );
return;}
NTSTATUSExt2QueueRequest (IN PEXT2_IRP_CONTEXT IrpContext){ ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
/* set the flags of "can wait" and "queued" */ SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT); SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
/* make sure the buffer is kept valid in system context */ Ext2LockIrp(IrpContext, IrpContext->Irp);
/* initialize workite*/ ExInitializeWorkItem( &IrpContext->WorkQueueItem, Ext2DeQueueRequest, IrpContext );
/* dispatch it */ ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
return STATUS_PENDING;}
#ifdef __REACTOS__VOID NTAPI#elseVOID#endifExt2DeQueueRequest (IN PVOID Context){ PEXT2_IRP_CONTEXT IrpContext;
IrpContext = (PEXT2_IRP_CONTEXT) Context;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
_SEH2_TRY {
_SEH2_TRY {
FsRtlEnterFileSystem();
if (!IrpContext->IsTopLevel) { IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP); }
Ext2DispatchRequest(IrpContext);
} _SEH2_EXCEPT (Ext2ExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
Ext2ExceptionHandler(IrpContext); } _SEH2_END;
} _SEH2_FINALLY {
IoSetTopLevelIrp(NULL);
FsRtlExitFileSystem(); } _SEH2_END;}
NTSTATUSExt2DispatchRequest (IN PEXT2_IRP_CONTEXT IrpContext){ ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
switch (IrpContext->MajorFunction) {
case IRP_MJ_CREATE: return Ext2Create(IrpContext);
case IRP_MJ_CLOSE: return Ext2Close(IrpContext);
case IRP_MJ_READ: return Ext2Read(IrpContext);
case IRP_MJ_WRITE: return Ext2Write(IrpContext);
case IRP_MJ_FLUSH_BUFFERS: return Ext2Flush(IrpContext);
case IRP_MJ_QUERY_INFORMATION: return Ext2QueryFileInformation(IrpContext);
case IRP_MJ_SET_INFORMATION: return Ext2SetFileInformation(IrpContext);
case IRP_MJ_QUERY_VOLUME_INFORMATION: return Ext2QueryVolumeInformation(IrpContext);
case IRP_MJ_SET_VOLUME_INFORMATION: return Ext2SetVolumeInformation(IrpContext);
case IRP_MJ_DIRECTORY_CONTROL: return Ext2DirectoryControl(IrpContext);
case IRP_MJ_FILE_SYSTEM_CONTROL: return Ext2FileSystemControl(IrpContext);
case IRP_MJ_DEVICE_CONTROL: return Ext2DeviceControl(IrpContext);
case IRP_MJ_LOCK_CONTROL: return Ext2LockControl(IrpContext);
case IRP_MJ_CLEANUP: return Ext2Cleanup(IrpContext);
case IRP_MJ_SHUTDOWN: return Ext2ShutDown(IrpContext);
case IRP_MJ_QUERY_EA: return Ext2QueryEa(IrpContext);
case IRP_MJ_SET_EA: return Ext2SetEa(IrpContext);
#if (_WIN32_WINNT >= 0x0500) case IRP_MJ_PNP: return Ext2Pnp(IrpContext);#endif //(_WIN32_WINNT >= 0x0500) default: DEBUG(DL_ERR, ( "Ext2DispatchRequest: Unexpected major function: %xh\n", IrpContext->MajorFunction));
Ext2CompleteIrpContext(IrpContext, STATUS_DRIVER_INTERNAL_ERROR);
return STATUS_DRIVER_INTERNAL_ERROR; }}
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifExt2BuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp){ BOOLEAN AtIrqlPassiveLevel = FALSE; BOOLEAN IsTopLevelIrp = FALSE; PEXT2_IRP_CONTEXT IrpContext = NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL;
_SEH2_TRY {
_SEH2_TRY {
#if EXT2_DEBUG Ext2DbgPrintCall(DeviceObject, Irp);#endif
AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);
if (AtIrqlPassiveLevel) { FsRtlEnterFileSystem(); }
if (!IoGetTopLevelIrp()) { IsTopLevelIrp = TRUE; IoSetTopLevelIrp(Irp); }
IrpContext = Ext2AllocateIrpContext(DeviceObject, Irp);
if (!IrpContext) {
Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Status = Status;
Ext2CompleteRequest(Irp, TRUE, IO_NO_INCREMENT);
} else {
if ((IrpContext->MajorFunction == IRP_MJ_CREATE) && !AtIrqlPassiveLevel) {
DbgBreak(); }
Status = Ext2DispatchRequest(IrpContext); } } _SEH2_EXCEPT (Ext2ExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
Status = Ext2ExceptionHandler(IrpContext); } _SEH2_END;
} _SEH2_FINALLY {
if (IsTopLevelIrp) { IoSetTopLevelIrp(NULL); }
if (AtIrqlPassiveLevel) { FsRtlExitFileSystem(); } } _SEH2_END;
return Status;}