mirror of
https://github.com/reactos/reactos.git
synced 2024-08-15 16:07:07 +00:00
688875e411
The main motivation to switch to that newer driver is, that our old one simply can not read all isos. Especially complex ones made trouble and were only shown as empty in explorer. It is still possible to build and use the old driver when needed, only thing that needs to be done for that is to revert 0.4.8-dev-164-gec6b3ecbe4
Porting back the state up to 0.4.8-release-100-g8f947b5 implies: Fixing the following JIRA-IDs (or avoid introducing them): CORE-18029 "Mute noisy DPRINT 'SectionObject has ImageSection'" CORE-17405 "Fix a macro-copy-paste and shrink the binary size" CORE-15659 "Unable to build the gcc Release version in Windows using RosBE 2.1.6 (module cdfs fails)" CORE-14315 "CDFS_NEW assertion during first stage setup due to new CcPerformReadAhead" CORE-14128 "Avast! Free Antivirus 7.0 hangs the system when trying to detect a newly created virus" CORE-14067 "CDFS_NEW assertions and exceptions" CORE-14003 "Shutting down LiveCD asserts since introduction of MS PL CDFS_NEW" CORE-13184 "Restore ability to install from disk-image" by picking the following commits: 0.4.8-release-100-g8f947b5322
[NTOSKRNL] Mute noisy DPRINT 'SectionObject has ImageSection' CORE-18029 0.4.8-release-80-geb1ea19588
[CDFS_NEW] == 0.4.15-dev-1456-g889eab7
CORE-17405 0.4.8-release-62-g8c07aad4a8
[CDFS_NEW/XDK] == 0.4.11-dev-39-ga2f9762
+ 0.4.11-dev-40-g6d7ec8c
CORE-14067 0.4.8-release-3-g5d976d04e8
[CDFS_NEW] == 0.4.12-dev-431-gbccad87f3c
+ 0.4.12-dev-432-g3463b2db9f
CORE-15659 0.4.8-RC-3-g51f9494d48
[CDFS_NEW] superseded later by the proper fix 0.4.8-release-62-g8c07aad4a8
CORE-14067 0.4.8-dev-1069-ga5e89014dc
[CDFS_NEW] CORE-14315 0.4.8-dev-475-ga59d4674de
[NTOSKRNL] io/iomgr/device.c (forgotten assert) CORE-14128 0.4.8-dev-221-g9d67a24799
[CDFS_NEW] 0.4.8-dev-220-g67a7e45e35
[CDFS_NEW/DOC] 0.4.8-dev-219-g6a3bbf24e0
[CDFS_NEW] 0.4.8-dev-218-gec26cde4a1
[CDFS_NEW] 0.4.8-dev-217-gbc2378a356
[CDFS_NEW] 0.4.8-dev-216-g5429771b99
[CDFS_NEW] 0.4.8-dev-215-gfd34548263
[CDFS_NEW] Sync with MS-PL driver 0.4.8-dev-164-gec6b3ecbe4
[FILESYSTEMS] switch from CDFS to CDFS_NEW in CMakeLists.txt 0.4.8-dev-160-g2b217e4ecf
[NTOSKRNL] Mute spam CcSetReadAheadGranularity() 0.4.8-dev-159-g64cb138a67
[NTOSKRNL] Mute spam CcPurgeCacheSection() 0.4.8-dev-150-gf723d230a0
[CDFS_NEW] 0.4.8-dev-133-gfaee3753ea
[CDFS_NEW] CORE-14003 0.4.8-dev-132-g1d777ffab5
[NTOSKRNL] iofunc.c CORE-14003 0.4.8-dev-131-gc3d5a3f2bd
[NTOSKRNL] iofunc.c CORE-14003 0.4.8-dev-130-g3b64f7f8fb
[NTOSKRNL] ob/obref.c & co CORE-14003 0.4.8-dev-129-g7eefe70294
[NTOSKRNL] io/iomgr.c & co CORE-14003 0.4.8-dev-127-g5f255827d3
[CDFS_NEW] 0.4.8-dev-126-g1bef48796e
[NTOSKRNL] just a comment, superseded later 0.4.8-dev-125-gcbf0430b56
[CDFS_NEW] 0.4.8-dev-123-gf88fe43abd
[NTOSKRNL] io/iomgr/device.c (forbidden DPRINT) 0.4.8-dev-122-g6c73385625
[CDFS_NEW] CORE-13184 0.4.8-dev-97-g94298313c0
[CDFS_NEW] 0.4.8-dev-95-ge88eeb21af
[CDFS_NEW/NTOSKRNL] CcWaitForCurrentLazyWriterActivity() stub return Success 0.4.8-dev-94-g03d5be6437
[CDFS_NEW] 0.4.8-dev-93-gfa1c60db50
[CDFS_NEW] 0.4.8-dev-92-g8b2fd60829
[CDFS_NEW] 0.4.8-dev-91-ge4da7ecc50
[CDFS_NEW] 0.4.8-dev-90-g7b19676e2b
[CDFS_NEW] 0.4.8-dev-89-g3d4b8783fd
[CDFS_NEW] 0.4.8-dev-88-g818025ecc8
[CDFS_NEW] 0.4.8-dev-87-g2639dd6736
[CDFS_NEW] 0.4.8-dev-86-g755bdb5d0b
[CDFS_NEW] 0.4.8-dev-85-g3cbcb1bade
[CDFS_NEW] and mute spam in opcode INSTEAD of picking: 0.4.8-dev-165-g2284a457a3
[NTOSKRNL] oplock.c Fixup 0.4.8-dev-163-gd3d5853956
[NTOSKRNL] oplock.c Implement oplock-support 0.4.12-dev-232-gf488102c86
[CDFS] was also left out for now I am aware, that the backport introduces white-space-glitches within CDFS_NEW. I decided to live with them in favor of better sync to master and newer releases.
423 lines
9 KiB
C
Executable file
423 lines
9 KiB
C
Executable file
/*++
|
||
|
||
Copyright (c) 1989-2000 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
WorkQue.c
|
||
|
||
Abstract:
|
||
|
||
This module implements the Work queue routines for the Cdfs File
|
||
system.
|
||
|
||
|
||
--*/
|
||
|
||
#include "cdprocs.h"
|
||
|
||
//
|
||
// The Bug check file id for this module
|
||
//
|
||
|
||
#define BugCheckFileId (CDFS_BUG_CHECK_WORKQUE)
|
||
|
||
//
|
||
// The following constant is the maximum number of ExWorkerThreads that we
|
||
// will allow to be servicing a particular target device at any one time.
|
||
//
|
||
|
||
#define FSP_PER_DEVICE_THRESHOLD (2)
|
||
|
||
//
|
||
// Local support routines
|
||
//
|
||
|
||
VOID
|
||
CdAddToWorkque (
|
||
_Inout_ PIRP_CONTEXT IrpContext,
|
||
_Inout_ PIRP Irp
|
||
);
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE, CdFsdPostRequest)
|
||
#pragma alloc_text(PAGE, CdOplockComplete)
|
||
#pragma alloc_text(PAGE, CdPrePostIrp)
|
||
#endif
|
||
|
||
|
||
_Requires_lock_held_(_Global_critical_region_)
|
||
NTSTATUS
|
||
CdFsdPostRequest (
|
||
_Inout_ PIRP_CONTEXT IrpContext,
|
||
_Inout_ PIRP Irp
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine enqueues the request packet specified by IrpContext to the
|
||
work queue associated with the FileSystemDeviceObject. This is a FSD
|
||
routine.
|
||
|
||
Arguments:
|
||
|
||
IrpContext - Pointer to the IrpContext to be queued to the Fsp.
|
||
|
||
Irp - I/O Request Packet.
|
||
|
||
Return Value:
|
||
|
||
STATUS_PENDING
|
||
|
||
--*/
|
||
|
||
{
|
||
PAGED_CODE();
|
||
|
||
ASSERT_IRP_CONTEXT( IrpContext );
|
||
ASSERT_IRP( Irp );
|
||
|
||
//
|
||
// Posting is a three step operation. First lock down any buffers
|
||
// in the Irp. Next cleanup the IrpContext for the post and finally
|
||
// add this to a workque.
|
||
//
|
||
|
||
CdPrePostIrp( IrpContext, Irp );
|
||
|
||
CdAddToWorkque( IrpContext, Irp );
|
||
|
||
//
|
||
// And return to our caller
|
||
//
|
||
|
||
return STATUS_PENDING;
|
||
}
|
||
|
||
|
||
|
||
_Requires_lock_held_(_Global_critical_region_)
|
||
VOID
|
||
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
|
||
CdPrePostIrp (
|
||
_Inout_ PIRP_CONTEXT IrpContext,
|
||
_Inout_ PIRP Irp
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine performs any neccessary work before STATUS_PENDING is
|
||
returned with the Fsd thread. This routine is called within the
|
||
filesystem and by the oplock package.
|
||
|
||
Arguments:
|
||
|
||
Context - Pointer to the IrpContext to be queued to the Fsp
|
||
|
||
Irp - I/O Request Packet.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
||
BOOLEAN RemovedFcb;
|
||
|
||
PAGED_CODE();
|
||
|
||
ASSERT_IRP_CONTEXT( IrpContext );
|
||
ASSERT_IRP( Irp );
|
||
|
||
//
|
||
// Case on the type of the operation.
|
||
//
|
||
|
||
switch (IrpContext->MajorFunction) {
|
||
|
||
case IRP_MJ_CREATE :
|
||
|
||
//
|
||
// If called from the oplock package then there is an
|
||
// Fcb to possibly teardown. We will call the teardown
|
||
// routine and release the Fcb if still present. The cleanup
|
||
// code in create will know not to release this Fcb because
|
||
// we will clear the pointer.
|
||
//
|
||
|
||
if ((IrpContext->TeardownFcb != NULL) &&
|
||
*(IrpContext->TeardownFcb) != NULL) {
|
||
|
||
CdTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), &RemovedFcb );
|
||
|
||
if (!RemovedFcb) {
|
||
|
||
_Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
|
||
CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
|
||
}
|
||
|
||
*(IrpContext->TeardownFcb) = NULL;
|
||
IrpContext->TeardownFcb = NULL;
|
||
}
|
||
|
||
break;
|
||
|
||
//
|
||
// We need to lock the user's buffer, unless this is an MDL read/write,
|
||
// in which case there is no user buffer.
|
||
//
|
||
|
||
case IRP_MJ_READ :
|
||
|
||
if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
|
||
|
||
CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoWriteAccess );
|
||
}
|
||
|
||
break;
|
||
|
||
case IRP_MJ_WRITE :
|
||
|
||
if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
|
||
|
||
CdLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length, IoReadAccess );
|
||
}
|
||
|
||
break;
|
||
|
||
//
|
||
// We also need to check whether this is a query file operation.
|
||
//
|
||
|
||
case IRP_MJ_DIRECTORY_CONTROL :
|
||
|
||
if (IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
|
||
|
||
CdLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length, IoWriteAccess );
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Cleanup the IrpContext for the post.
|
||
//
|
||
|
||
SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
|
||
CdCleanupIrpContext( IrpContext, TRUE );
|
||
|
||
//
|
||
// Mark the Irp to show that we've already returned pending to the user.
|
||
//
|
||
|
||
IoMarkIrpPending( Irp );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
_Requires_lock_held_(_Global_critical_region_)
|
||
VOID
|
||
NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
|
||
CdOplockComplete (
|
||
_Inout_ PIRP_CONTEXT IrpContext,
|
||
_Inout_ PIRP Irp
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by the oplock package when an oplock break has
|
||
completed, allowing an Irp to resume execution. If the status in
|
||
the Irp is STATUS_SUCCESS, then we queue the Irp to the Fsp queue.
|
||
Otherwise we complete the Irp with the status in the Irp.
|
||
|
||
If we are completing due to an error then check if there is any
|
||
cleanup to do.
|
||
|
||
Arguments:
|
||
|
||
Irp - I/O Request Packet.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOLEAN RemovedFcb;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Check on the return value in the Irp. If success then we
|
||
// are to post this request.
|
||
//
|
||
|
||
if (Irp->IoStatus.Status == STATUS_SUCCESS) {
|
||
|
||
//
|
||
// Check if there is any cleanup work to do.
|
||
//
|
||
|
||
switch (IrpContext->MajorFunction) {
|
||
|
||
case IRP_MJ_CREATE :
|
||
|
||
//
|
||
// If called from the oplock package then there is an
|
||
// Fcb to possibly teardown. We will call the teardown
|
||
// routine and release the Fcb if still present. The cleanup
|
||
// code in create will know not to release this Fcb because
|
||
// we will clear the pointer.
|
||
//
|
||
|
||
if (IrpContext->TeardownFcb != NULL) {
|
||
|
||
CdTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), &RemovedFcb );
|
||
|
||
if (!RemovedFcb) {
|
||
|
||
_Analysis_assume_lock_held_((*IrpContext->TeardownFcb)->FcbNonpaged->FcbResource);
|
||
CdReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) );
|
||
}
|
||
|
||
*(IrpContext->TeardownFcb) = NULL;
|
||
IrpContext->TeardownFcb = NULL;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Insert the Irp context in the workqueue.
|
||
//
|
||
|
||
CdAddToWorkque( IrpContext, Irp );
|
||
|
||
//
|
||
// Otherwise complete the request.
|
||
//
|
||
|
||
} else {
|
||
|
||
CdCompleteRequest( IrpContext, Irp, Irp->IoStatus.Status );
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
//
|
||
// Local support routine
|
||
//
|
||
|
||
VOID
|
||
CdAddToWorkque (
|
||
_Inout_ PIRP_CONTEXT IrpContext,
|
||
_Inout_ PIRP Irp
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called to acually store the posted Irp to the Fsp
|
||
workque.
|
||
|
||
Arguments:
|
||
|
||
IrpContext - Pointer to the IrpContext to be queued to the Fsp
|
||
|
||
Irp - I/O Request Packet.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
PVOLUME_DEVICE_OBJECT Vdo;
|
||
KIRQL SavedIrql;
|
||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
||
|
||
//
|
||
// Check if this request has an associated file object, and thus volume
|
||
// device object.
|
||
//
|
||
|
||
if (IrpSp->FileObject != NULL) {
|
||
|
||
|
||
Vdo = CONTAINING_RECORD( IrpSp->DeviceObject,
|
||
VOLUME_DEVICE_OBJECT,
|
||
DeviceObject );
|
||
|
||
//
|
||
// Check to see if this request should be sent to the overflow
|
||
// queue. If not, then send it off to an exworker thread.
|
||
//
|
||
|
||
KeAcquireSpinLock( &Vdo->OverflowQueueSpinLock, &SavedIrql );
|
||
|
||
if (Vdo->PostedRequestCount > FSP_PER_DEVICE_THRESHOLD) {
|
||
|
||
//
|
||
// We cannot currently respond to this IRP so we'll just enqueue it
|
||
// to the overflow queue on the volume.
|
||
//
|
||
|
||
InsertTailList( &Vdo->OverflowQueue,
|
||
&IrpContext->WorkQueueItem.List );
|
||
|
||
Vdo->OverflowQueueCount += 1;
|
||
|
||
KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql );
|
||
|
||
return;
|
||
|
||
} else {
|
||
|
||
//
|
||
// We are going to send this Irp to an ex worker thread so up
|
||
// the count.
|
||
//
|
||
|
||
Vdo->PostedRequestCount += 1;
|
||
|
||
KeReleaseSpinLock( &Vdo->OverflowQueueSpinLock, SavedIrql );
|
||
}
|
||
}
|
||
|
||
//
|
||
// Send it off.....
|
||
//
|
||
|
||
#ifdef _MSC_VER
|
||
#pragma prefast(suppress:28155, "the function prototype is correct")
|
||
#endif
|
||
ExInitializeWorkItem( &IrpContext->WorkQueueItem,
|
||
(PVOID)CdFspDispatch,/* ReactOS Change: GCC "assignment from incompatible pointer type" */
|
||
IrpContext );
|
||
|
||
#ifdef _MSC_VER
|
||
#pragma prefast(suppress: 28159, "prefast believes this routine is obsolete, but it is ok for CDFS to continue using it")
|
||
#endif
|
||
ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|