mirror of
https://github.com/reactos/reactos.git
synced 2025-06-20 07:36:05 +00:00
242 lines
6 KiB
C
242 lines
6 KiB
C
/*
|
|
* COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
|
|
* PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
|
|
* FILE: dispatch.c
|
|
* PURPOSE:
|
|
* PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
|
|
* HOMEPAGE:
|
|
* UPDATE HISTORY:
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "rfsd.h"
|
|
|
|
/* GLOBALS ***************************************************************/
|
|
|
|
extern PRFSD_GLOBAL RfsdGlobal;
|
|
|
|
/* DEFINITIONS *************************************************************/
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, RfsdQueueRequest)
|
|
#pragma alloc_text(PAGE, RfsdDeQueueRequest)
|
|
#pragma alloc_text(PAGE, RfsdDispatchRequest)
|
|
#pragma alloc_text(PAGE, RfsdBuildRequest)
|
|
#endif
|
|
|
|
NTSTATUS
|
|
RfsdQueueRequest (IN PRFSD_IRP_CONTEXT IrpContext)
|
|
{
|
|
PAGED_CODE();
|
|
|
|
ASSERT(IrpContext);
|
|
|
|
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
|
|
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
|
|
|
|
// IsSynchronous means we can block (so we don't requeue it)
|
|
IrpContext->IsSynchronous = TRUE;
|
|
|
|
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
|
|
|
|
IoMarkIrpPending(IrpContext->Irp);
|
|
|
|
ExInitializeWorkItem(
|
|
&IrpContext->WorkQueueItem,
|
|
RfsdDeQueueRequest,
|
|
IrpContext );
|
|
|
|
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
|
|
|
|
return STATUS_PENDING;
|
|
}
|
|
|
|
VOID NTAPI
|
|
RfsdDeQueueRequest (IN PVOID Context)
|
|
{
|
|
PRFSD_IRP_CONTEXT IrpContext;
|
|
|
|
PAGED_CODE();
|
|
|
|
IrpContext = (PRFSD_IRP_CONTEXT) Context;
|
|
|
|
ASSERT(IrpContext);
|
|
|
|
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
|
|
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
|
|
|
|
_SEH2_TRY {
|
|
|
|
_SEH2_TRY {
|
|
|
|
FsRtlEnterFileSystem();
|
|
|
|
if (!IrpContext->IsTopLevel) {
|
|
|
|
IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
|
|
}
|
|
|
|
RfsdDispatchRequest(IrpContext);
|
|
|
|
} _SEH2_EXCEPT (RfsdExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
|
|
|
|
RfsdExceptionHandler(IrpContext);
|
|
} _SEH2_END;
|
|
|
|
} _SEH2_FINALLY {
|
|
|
|
IoSetTopLevelIrp(NULL);
|
|
|
|
FsRtlExitFileSystem();
|
|
} _SEH2_END;
|
|
}
|
|
|
|
__drv_mustHoldCriticalRegion
|
|
NTSTATUS
|
|
RfsdDispatchRequest (IN PRFSD_IRP_CONTEXT IrpContext)
|
|
{
|
|
PAGED_CODE();
|
|
|
|
ASSERT(IrpContext);
|
|
|
|
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
|
|
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
|
|
|
|
switch (IrpContext->MajorFunction) {
|
|
|
|
case IRP_MJ_CREATE:
|
|
return RfsdCreate(IrpContext);
|
|
|
|
case IRP_MJ_CLOSE:
|
|
return RfsdClose(IrpContext);
|
|
|
|
case IRP_MJ_READ:
|
|
return RfsdRead(IrpContext);
|
|
|
|
#if !RFSD_READ_ONLY
|
|
case IRP_MJ_WRITE:
|
|
return RfsdWrite(IrpContext);
|
|
#endif // !RFSD_READ_ONLY
|
|
|
|
case IRP_MJ_FLUSH_BUFFERS:
|
|
return RfsdFlush(IrpContext);
|
|
|
|
case IRP_MJ_QUERY_INFORMATION:
|
|
return RfsdQueryInformation(IrpContext);
|
|
|
|
case IRP_MJ_SET_INFORMATION:
|
|
return RfsdSetInformation(IrpContext);
|
|
|
|
case IRP_MJ_QUERY_VOLUME_INFORMATION:
|
|
return RfsdQueryVolumeInformation(IrpContext);
|
|
|
|
#if !RFSD_READ_ONLY
|
|
case IRP_MJ_SET_VOLUME_INFORMATION:
|
|
return RfsdSetVolumeInformation(IrpContext);
|
|
#endif // !RFSD_READ_ONLY
|
|
|
|
case IRP_MJ_DIRECTORY_CONTROL:
|
|
return RfsdDirectoryControl(IrpContext);
|
|
|
|
case IRP_MJ_FILE_SYSTEM_CONTROL:
|
|
return RfsdFileSystemControl(IrpContext);
|
|
|
|
case IRP_MJ_DEVICE_CONTROL:
|
|
return RfsdDeviceControl(IrpContext);
|
|
|
|
case IRP_MJ_LOCK_CONTROL:
|
|
return RfsdLockControl(IrpContext);
|
|
|
|
case IRP_MJ_CLEANUP:
|
|
return RfsdCleanup(IrpContext);
|
|
|
|
case IRP_MJ_SHUTDOWN:
|
|
return RfsdShutDown(IrpContext);
|
|
|
|
#if (_WIN32_WINNT >= 0x0500)
|
|
case IRP_MJ_PNP:
|
|
return RfsdPnp(IrpContext);
|
|
#endif //(_WIN32_WINNT >= 0x0500)
|
|
default:
|
|
{
|
|
NTSTATUS DefaultRC = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
RfsdPrint((DBG_ERROR, "RfsdDispatchRequest: Unexpected major function: %xh\n",
|
|
IrpContext->MajorFunction));
|
|
|
|
RfsdCompleteIrpContext(IrpContext, DefaultRC);
|
|
|
|
return DefaultRC;
|
|
}
|
|
}
|
|
}
|
|
|
|
NTSTATUS NTAPI
|
|
RfsdBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|
{
|
|
BOOLEAN AtIrqlPassiveLevel = FALSE;
|
|
BOOLEAN IsTopLevelIrp = FALSE;
|
|
PRFSD_IRP_CONTEXT IrpContext = NULL;
|
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
|
|
|
PAGED_CODE();
|
|
|
|
_SEH2_TRY {
|
|
|
|
_SEH2_TRY {
|
|
|
|
#if DBG
|
|
RfsdDbgPrintCall(DeviceObject, Irp);
|
|
#endif
|
|
|
|
AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
|
|
|
if (AtIrqlPassiveLevel) {
|
|
|
|
FsRtlEnterFileSystem();
|
|
}
|
|
|
|
if (!IoGetTopLevelIrp()) {
|
|
|
|
IsTopLevelIrp = TRUE;
|
|
IoSetTopLevelIrp(Irp);
|
|
}
|
|
|
|
IrpContext = RfsdAllocateIrpContext(DeviceObject, Irp);
|
|
|
|
if (!IrpContext) {
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
Irp->IoStatus.Status = Status;
|
|
|
|
RfsdCompleteRequest(Irp, TRUE, IO_NO_INCREMENT);
|
|
|
|
} else {
|
|
|
|
if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
|
|
!AtIrqlPassiveLevel) {
|
|
|
|
DbgBreak();
|
|
}
|
|
|
|
Status = RfsdDispatchRequest(IrpContext);
|
|
}
|
|
} _SEH2_EXCEPT (RfsdExceptionFilter(IrpContext, _SEH2_GetExceptionInformation())) {
|
|
|
|
Status = RfsdExceptionHandler(IrpContext);
|
|
} _SEH2_END;
|
|
|
|
} _SEH2_FINALLY {
|
|
|
|
if (IsTopLevelIrp) {
|
|
IoSetTopLevelIrp(NULL);
|
|
}
|
|
|
|
if (AtIrqlPassiveLevel) {
|
|
FsRtlExitFileSystem();
|
|
}
|
|
} _SEH2_END;
|
|
|
|
return Status;
|
|
}
|