コード例 #1
0
DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
{
    /*
     * Convert the IPRT priority type to NT priority.
     *
     * The NT priority is in the range 0..32, with realtime starting
     * at 16 and the default for user processes at 8. (Should try find
     * the appropriate #defines for some of this...)
     */
    KPRIORITY Priority;
    switch (enmType)
    {
        case RTTHREADTYPE_INFREQUENT_POLLER:    Priority = 6; break;
        case RTTHREADTYPE_EMULATION:            Priority = 7; break;
        case RTTHREADTYPE_DEFAULT:              Priority = 8; break;
        case RTTHREADTYPE_MSG_PUMP:             Priority = 9; break;
        case RTTHREADTYPE_IO:                   Priority = LOW_REALTIME_PRIORITY; break;
        case RTTHREADTYPE_TIMER:                Priority = MAXIMUM_PRIORITY; break;

        default:
            AssertMsgFailed(("enmType=%d\n", enmType));
            return VERR_INVALID_PARAMETER;
    }

    /*
     * Do the actual modification.
     */
    /*KPRIORITY oldPririty = */KeSetPriorityThread((PKTHREAD)pThread->Core.Key, Priority);
    return VINF_SUCCESS;
}
コード例 #2
0
ファイル: HotKeyKrnl.c プロジェクト: gokutek/HotkeyDriver
VOID 
HotKeyKrnlUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{ 
	PDEVICE_OBJECT  DeviceObject; 
	LARGE_INTEGER   lDelay;
	KdPrint(("[shadow] Enter HotKeyKrnlUnload...\n"));
	KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
	
    // Delete device we have created
	DeviceObject = DriverObject->DeviceObject;
	while (DeviceObject)
	{
		if (((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDeviceObject)
			HotKeyKrnlDetach(DeviceObject);
		else
			IoDeleteDevice(DeviceObject);
		DeviceObject = DeviceObject->NextDevice;
	}
	if (gKeyCount > 0 && PendingIrp)
	{
		if (!CancelKeyboardIrp(PendingIrp))
			KdPrint(("[shadow] Cancel irp failed\n"));
	}

    lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
    while (gKeyCount) {
		KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
    }
	KdPrint(("[shadow] Exit HotKeyKrnlUnload...\n"));
}
コード例 #3
0
ファイル: ioctl.c プロジェクト: arielscarpinelli/ntpad
// *****************************************************************************
NTSTATUS INTERNAL
    HGM_ActivateDevice
    (
    PDEVICE_OBJECT  DeviceObject
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;

    PDEVICE_EXTENSION   DeviceExtension;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE Thread;
    PVOID pkThread;
    PAGED_CODE();
    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    if(!DeviceExtension->ScanThread)
//    if(!Global.ThreadIniciado)
    {
//      Global.ThreadIniciado = 1;
      InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL)
      KeInitializeEvent(&(DeviceExtension->FinishThread), NotificationEvent, FALSE);
      KeInitializeEvent(&(DeviceExtension->DoScan), SynchronizationEvent, FALSE);
      KeInitializeEvent(&(DeviceExtension->ScanReady), SynchronizationEvent, FALSE);
      ntStatus = PsCreateSystemThread(&Thread, THREAD_ALL_ACCESS,
                                       &ObjectAttributes, NULL, NULL, ScaningThread, (PVOID) DeviceObject);
      ObReferenceObjectByHandle(Thread, THREAD_ALL_ACCESS, NULL, KernelMode, &pkThread,NULL);
      KeSetPriorityThread(pkThread, LOW_REALTIME_PRIORITY - 1);
      DeviceExtension->ScanThread = (PKTHREAD) pkThread;
    };
    return ntStatus;
} /* HGM_GetAttributes */
コード例 #4
0
ファイル: stackovf.c プロジェクト: BillTheBest/WinNT4
VOID
FsRtlWorkerThread(
    IN PVOID StartContext
)

{
    PLIST_ENTRY Entry;
    PWORK_QUEUE_ITEM WorkItem;
    ULONG PagingFile = (ULONG)StartContext;

    //
    //  Set our priority to low realtime, or +1 for PagingFile.
    //

    (PVOID)KeSetPriorityThread( &PsGetCurrentThread()->Tcb,
                                LOW_REALTIME_PRIORITY + PagingFile );

    //
    // Loop forever waiting for a work queue item, calling the processing
    // routine, and then waiting for another work queue item.
    //

    do {

        //
        // Wait until something is put in the queue.
        //
        // By specifying a wait mode of KernelMode, the thread's kernel stack is
        // NOT swappable
        //

        Entry = KeRemoveQueue(&FsRtlWorkerQueues[PagingFile], KernelMode, NULL);
        WorkItem = CONTAINING_RECORD(Entry, WORK_QUEUE_ITEM, List);

        //
        // Execute the specified routine.
        //

        (WorkItem->WorkerRoutine)(WorkItem->Parameter);
        if (KeGetCurrentIrql() != 0) {
            KeBugCheckEx(
                IRQL_NOT_LESS_OR_EQUAL,
                (ULONG)WorkItem->WorkerRoutine,
                (ULONG)KeGetCurrentIrql(),
                (ULONG)WorkItem->WorkerRoutine,
                (ULONG)WorkItem
            );
        }

    } while(TRUE);
}
コード例 #5
0
ファイル: EncryptedIoQueue.c プロジェクト: BitMerc/veracrypt
static VOID CompletionThreadProc (PVOID threadArg)
{
	EncryptedIoQueue *queue = (EncryptedIoQueue *) threadArg;
	PLIST_ENTRY listEntry;
	EncryptedIoRequest *request;
	UINT64_STRUCT dataUnit;

	if (IsEncryptionThreadPoolRunning())
		KeSetPriorityThread (KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

	while (!queue->ThreadExitRequested)
	{
		if (!NT_SUCCESS (KeWaitForSingleObject (&queue->CompletionThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL)))
			continue;

		if (queue->ThreadExitRequested)
			break;

		while ((listEntry = ExInterlockedRemoveHeadList (&queue->CompletionThreadQueue, &queue->CompletionThreadQueueLock)))
		{
			request = CONTAINING_RECORD (listEntry, EncryptedIoRequest, CompletionListEntry);

			if (request->EncryptedLength > 0 && NT_SUCCESS (request->Item->Status))
			{
				ASSERT (request->EncryptedOffset + request->EncryptedLength <= request->Offset.QuadPart + request->Length);
				dataUnit.Value = (request->Offset.QuadPart + request->EncryptedOffset) / ENCRYPTION_DATA_UNIT_SIZE;

				if (queue->CryptoInfo->bPartitionInInactiveSysEncScope)
					dataUnit.Value += queue->CryptoInfo->FirstDataUnitNo.Value;
				else if (queue->RemapEncryptedArea)
					dataUnit.Value += queue->RemappedAreaDataUnitOffset;

				DecryptDataUnits (request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
			}

			if (request->CompleteOriginalIrp)
			{
				CompleteOriginalIrp (request->Item, request->Item->Status,
					NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0);
			}

			ReleasePoolBuffer (queue, request);
		}
	}

	PsTerminateSystemThread (STATUS_SUCCESS);
}
コード例 #6
0
VOID KBFDriverUnload(IN PDRIVER_OBJECT aDriverObject)
{
    PAGED_CODE();

    PDEVICE_OBJECT deviceObject = NULL;
    PDEVICE_OBJECT oldDeviceObject = NULL;
    PDEVICE_EXTENSION deviceExtension = NULL;

    LARGE_INTEGER lDelay;
    PRKTHREAD currentThread = NULL;

    if (g_filterStart == TRUE)
    {
        // delay some time
        lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
        currentThread = KeGetCurrentThread();

        // 将当前线程设置为低实时模式,以便让它的运行尽量少影响其他程序
        KeSetPriorityThread(currentThread, LOW_REALTIME_PRIORITY);

        UNREFERENCED_PARAMETER(aDriverObject);
        DbgPrint("wykbflt.sys : DriverEntry unloading .\n");

        // 遍历所有设备并一律解除绑定
        deviceObject = aDriverObject->DeviceObject;
        while (deviceObject)
        {
            KBFDetach(deviceObject);
            deviceObject = deviceObject->NextDevice;
        }

        ASSERT(NULL == aDriverObject->DeviceObject);

        while (gC2pKeyCount)
        {
            KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
        }
    }

    DbgPrint("wykbflt.sys : DriverEntry unload ok .\n");
    return ;
}
//------------------------------------------------------------------------------
static void eventThread(void* pArg)
{
    INT         timeout = 50;
    PKTHREAD    thread;
    BOOL        fRet = FALSE;

    UNUSED_PARAMETER(pArg);

    // increase the priority of the thread
    thread = KeGetCurrentThread();
    KeSetPriorityThread(thread, HIGH_PRIORITY);

    instance_l.fThreadIsRunning = TRUE;

    while (!instance_l.fStopThread)
    {
        fRet = NdisWaitEvent(&instance_l.kernelWaitEvent, timeout);
        if (fRet && (instance_l.kernelEventCount == 0))
        {
            // Timeout occurred, continue to wait.
            NdisResetEvent(&instance_l.kernelWaitEvent);
            continue;
        }

        NdisResetEvent(&instance_l.kernelWaitEvent);

        /* first handle all kernel internal events --> higher priority! */
        while (eventkcal_getEventCountCircbuf(kEventQueueKInt) > 0)
        {
            eventkcal_processEventCircbuf(kEventQueueKInt);
            NdisInterlockedDecrement(&instance_l.kernelEventCount);
        }

        if (eventkcal_getEventCountCircbuf(kEventQueueU2K) > 0)
        {
            eventkcal_processEventCircbuf(kEventQueueU2K);
            NdisInterlockedDecrement(&instance_l.kernelEventCount);
        }
    }

    instance_l.fThreadIsRunning = FALSE;
}
コード例 #8
0
ファイル: thread.c プロジェクト: Flaviowebit/openCBM
/*! \brief Start the worker thread

 This function start the worker thread.

 \param Pdx
   Pointer to a DEVICE_EXTENSION structure. 

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. 
   Otherwise, it return one of the error status values.
*/
NTSTATUS
cbm_start_thread(IN PDEVICE_EXTENSION Pdx)
{
    NTSTATUS ntStatus;
    PDEVICE_OBJECT fdo;

    FUNC_ENTER();

    DBG_ASSERT(Pdx != NULL);

    // get the FDO out of the PDX

    fdo = Pdx->Fdo;

    DBG_ASSERT(fdo != NULL);

    // The ThreadHandle as well as the thread object pointer should be
    // 0. If not, it means that the thread has already been started.

    DBG_ASSERT(Pdx->ThreadHandle == 0);
    DBG_ASSERT(Pdx->Thread == 0);

    PERF_EVENT_THREAD_START_SCHED();

    // The thread should not be quit yet.
    //! \todo Replace Pdx->QuitThread with a event for quitting

    Pdx->QuitThread = FALSE;

    // Create the thread that will execute our IRPs

    DBG_IRQL( == PASSIVE_LEVEL);
    ntStatus = PsCreateSystemThread(&Pdx->ThreadHandle,
        THREAD_ALL_ACCESS, // Desired access
        NULL,              // No object attributes
        NULL,              // which process should the thread belong to?
        NULL,              // Client ID
        cbm_thread,        // the routine to be started
        Pdx);              // context value for the thread

    if (!NT_SUCCESS(ntStatus))
    {
        // The thread could not been started, make sure this is logged

        DBG_ERROR((DBG_PREFIX "Creation of system thread FAILED, deleting device"));
        LogErrorString(fdo, CBM_START_FAILED, L"creation of the system thread.", NULL);
    }
    else
    {
        // Find out the thread object pointer, which is needed
        // for setting the thread priority. Furthermore, as we have
        // referenced the object, the driver will refuse to be unloaded
        // until the object is dereferenced.

        DBG_IRQL( == PASSIVE_LEVEL);
        ObReferenceObjectByHandle(Pdx->ThreadHandle,
            THREAD_ALL_ACCESS, NULL, KernelMode, &Pdx->Thread, NULL);

        DBG_ASSERT(Pdx->Thread);

        if (Pdx->Thread)
        {
            // Set the priority of the thread to a realtime priority.

            DBG_IRQL( == PASSIVE_LEVEL);
            KeSetPriorityThread(Pdx->Thread, LOW_REALTIME_PRIORITY);
        }
    }
コード例 #9
0
ファイル: WBThread.c プロジェクト: maodapeng/WDUtils
VOID DF_WriteBackThread(PVOID Context)
{
    PUCHAR                  Data;
    PDF_DEVICE_EXTENSION    DevExt;
    PCACHE_BLOCK            pBlock;
    LARGE_INTEGER           Offset;
    ULONG                   Accumulate;
    LONGLONG                LastIndex;

    DevExt = (PDF_DEVICE_EXTENSION)Context;
    Data = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, CONSECUTIVE_BUF_SIZE << 20, 'tmpb');
    ASSERT(Data);
    // set thread priority.
    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
    KdPrint(("%u-%u: Write Back Thread Start...\n", DevExt->DiskNumber, DevExt->PartitionNumber));
    for (;;)
    {
        KeWaitForSingleObject(&DevExt->CachePool.WbThreadStartEvent,
                               Executive, KernelMode, FALSE, NULL);

        // Write Back Strategy
        if (DevExt->bTerminalWbThread == FALSE &&
            DevExt->CachePool.WbFlushAll == FALSE &&
            DevExt->CachePool.WbQueue.Used < DevExt->CachePool.WbQueue.Size)
            continue;

    #ifdef _DEBUG
        DbgPrint("%s: Flush Start\n", __FUNCTION__);
    #endif
        // Flush Back All Data
        Offset.QuadPart = -1;
        Accumulate = 0;
        LastIndex = -1;
        LOCK_WB_QUEUE(&DevExt->CachePool.WbQueueLock);
        while (NULL != (pBlock = QueueRemove(&DevExt->CachePool.WbQueue)))
    #ifndef MERGE_CONSECUTIVE
        {
            Offset.QuadPart = pBlock->Index * BLOCK_SIZE;
            StoragePoolRead(&DevExt->CachePool.Storage,
                             Data + 0,
                             pBlock->StorageIndex, 0, BLOCK_SIZE);
            IoDoRWRequestSync (
                IRP_MJ_WRITE,
                DevExt->LowerDeviceObject,
                Data,
                BLOCK_SIZE,
                &Offset,
                2
            );
            pBlock->Modified = FALSE;
        }
    #else
        // Merge Consecutive Writes
        {
            if (Accumulate == 0)
            {
                Offset.QuadPart = pBlock->Index * BLOCK_SIZE;
                StoragePoolRead(&DevExt->CachePool.Storage,
                                 Data + 0,
                                 pBlock->StorageIndex, 0, BLOCK_SIZE);
                Accumulate++;
                LastIndex = pBlock->Index;
            }
            else if (pBlock->Index == LastIndex + 1 && Accumulate < NUM_CONSECUTIVE_BLOCK)
            {
                StoragePoolRead(&DevExt->CachePool.Storage,
                                 Data + Accumulate*BLOCK_SIZE,
                                 pBlock->StorageIndex, 0, BLOCK_SIZE);
                Accumulate++;
                LastIndex++;
            }
            else
            {
                IoDoRWRequestSync (
                    IRP_MJ_WRITE,
                    DevExt->LowerDeviceObject,
                    Data,
                    Accumulate * BLOCK_SIZE,
                    &Offset,
                    2
                );
                // Restart
                StoragePoolRead(&DevExt->CachePool.Storage,
                                Data + 0,
                                pBlock->StorageIndex, 0, BLOCK_SIZE);
                Offset.QuadPart = pBlock->Index * BLOCK_SIZE;
                Accumulate = 1;
                LastIndex = pBlock->Index;
            }
            pBlock->Modified = FALSE;
        }
        if (Accumulate)
        {
            IoDoRWRequestSync (
                IRP_MJ_WRITE,
                DevExt->LowerDeviceObject,
                Data,
                Accumulate * BLOCK_SIZE,
                &Offset,
                2
            );
        }
    #endif
        UNLOCK_WB_QUEUE(&DevExt->CachePool.WbQueueLock);
        KeSetEvent(&DevExt->CachePool.WbThreadFinishEvent, IO_NO_INCREMENT, FALSE);
    #ifdef _DEBUG
        DbgPrint("%s: Flush Finished\n", __FUNCTION__);
    #endif
        if (DevExt->bTerminalWbThread)
        {
            ExFreePoolWithTag(Data, 'tmpb');
            KdPrint(("%u-%u: Write Back Thread Exit...\n", DevExt->DiskNumber, DevExt->PartitionNumber));
            PsTerminateSystemThread(STATUS_SUCCESS);
            return;
        }
    } // forever loop
}
コード例 #10
0
ファイル: zeropage.c プロジェクト: BillTheBest/WinNT4
VOID
MmZeroPageThread (
    VOID
    )

/*++

Routine Description:

    Implements the NT zeroing page thread.  This thread runs
    at priority zero and removes a page from the free list,
    zeroes it, and places it on the zeroed page list.

Arguments:

    StartContext - not used.

Return Value:

    None.

Environment:

    Kernel mode.

--*/

{
    PVOID EndVa;
    KIRQL OldIrql;
    ULONG PageFrame;
    PMMPFN Pfn1;
    PVOID StartVa;
    PKTHREAD Thread;
    PVOID ZeroBase;
    ULONG i;

    //
    // Before this becomes the zero page thread, free the kernel
    // initialization code.
    //

    MiFindInitializationCode (&StartVa, &EndVa);
    if (StartVa != NULL) {
        MiFreeInitializationCode (StartVa, EndVa);
    }

    //
    // The following code sets the current thread's base priority to zero
    // and then sets its current priority to zero. This ensures that the
    // thread always runs at a priority of zero.
    //

    Thread = KeGetCurrentThread();
    Thread->BasePriority = 0;
    KeSetPriorityThread (Thread, 0);

    //
    // Loop forever zeroing pages.
    //

    do {

        //
        // Wait until there are at least MmZeroPageMinimum pages
        // on the free list.
        //

        KeWaitForSingleObject (&MmZeroingPageEvent,
                               WrFreePage,
                               KernelMode,
                               FALSE,
                               (PLARGE_INTEGER)NULL);

        LOCK_PFN_WITH_TRY (OldIrql);
        do {
            if ((volatile)MmFreePageListHead.Total == 0) {

                //
                // No pages on the free list at this time, wait for
                // some more.
                //

                MmZeroingPageThreadActive = FALSE;
                UNLOCK_PFN (OldIrql);
                break;

            } else {

#if MM_MAXIMUM_NUMBER_OF_COLORS > 1
                for (i = 0; i < MM_MAXIMUM_NUMBER_OF_COLORS; i++) {
                    PageFrame = MmFreePagesByPrimaryColor[FreePageList][i].Flink;
                    if (PageFrame != MM_EMPTY_LIST) {
                        break;
                    }
                }
#else  //MM_MAXIMUM_NUMBER_OF_COLORS > 1
                PageFrame = MmFreePageListHead.Flink;
#endif //MM_MAXIMUM_NUMBER_OF_COLORS > 1
                Pfn1 = MI_PFN_ELEMENT(PageFrame);

                ASSERT (PageFrame != MM_EMPTY_LIST);
                Pfn1 = MI_PFN_ELEMENT(PageFrame);
                MiRemoveAnyPage (MI_GET_SECONDARY_COLOR (PageFrame, Pfn1));

                //
                // Zero the page using the last color used to map the page.
                //

#if defined(_X86_)

                ZeroBase = MiMapPageToZeroInHyperSpace (PageFrame);
                UNLOCK_PFN (OldIrql);
                RtlZeroMemory (ZeroBase, PAGE_SIZE);

#elif defined(_PPC_)

                UNLOCK_PFN (OldIrql);
                KeZeroPage(PageFrame);

#else

                ZeroBase = (PVOID)(Pfn1->u3.e1.PageColor << PAGE_SHIFT);
                UNLOCK_PFN (OldIrql);
                HalZeroPage(ZeroBase, ZeroBase, PageFrame);

#endif //X86

                LOCK_PFN_WITH_TRY (OldIrql);
                MiInsertPageInList (MmPageLocationList[ZeroedPageList],
                                    PageFrame);
            }
        } while(TRUE);
    } while (TRUE);
}
コード例 #11
0
ファイル: lspkrnl.c プロジェクト: JanD1943/ndas4windows
VOID
LspPollingThread(
    IN PVOID Context
    )
/*++

Routine Description:

    This is the main thread that removes IRP from the queue
    and peforms I/O on it.

Arguments:

    Context     -- pointer to the device object

--*/
{
    PDEVICE_OBJECT DeviceObject = Context;  
    PDEVICE_EXTENSION DevExtension =  DeviceObject->DeviceExtension;
    PIRP Irp;
    NTSTATUS    Status;
    
    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY );

    //
    // Now enter the main IRP-processing loop
    //
    while( TRUE )
    {
        //
        // Wait indefinitely for an IRP to appear in the work queue or for
        // the Unload routine to stop the thread. Every successful return 
        // from the wait decrements the semaphore count by 1.
        //
        KeWaitForSingleObject(
			&DevExtension->IrpQueueSemaphore,
            Executive,
            KernelMode,
            FALSE,
            NULL );

        //
        // See if thread was awakened because driver is unloading itself...
        //
        
        if( DevExtension->ThreadShouldStop ) 
		{
            PsTerminateSystemThread( STATUS_SUCCESS );
        }

        //
        // Remove a pending IRP from the queue.
        //
        Irp = IoCsqRemoveNextIrp(&DevExtension->CancelSafeQueue, NULL);

        if(!Irp) 
		{
            LSP_KDPRINT(("Oops, a queued irp got cancelled\n"));
            continue; // go back to waiting
        }
        
        while(TRUE) 
		{ 
            //
            // Perform I/O
            //
            Status = LspPollDevice(DeviceObject, Irp);
            if(Status == STATUS_PENDING) 
			{
                // 
                // Device is not ready, so sleep for a while and try again.
                //
                KeDelayExecutionThread(
					KernelMode, 
					FALSE,
                    &DevExtension->PollingInterval);
                
            }
			else 
			{
                //
                // I/O is successful, so complete the Irp.
                //
                Irp->IoStatus.Status = Status;
                IoCompleteRequest (Irp, IO_NO_INCREMENT);
                break; 
            }

        }
        //
        // Go back to the top of the loop to see if there's another request waiting.
        //
    } // end of while-loop
}
コード例 #12
0
ファイル: HookNdis.c プロジェクト: geemion/HookNdis
VOID
OnUnload (
	IN PDRIVER_OBJECT DriverObject
	)
/*++

Routine Description:

	Diver exit point. Releases resources and unhooks NDIS routines.


Arguments:

	DriverObject - A pointer to this driver, provided by system.


Return Value:

	None.


Author:

	xiaonie

	2012/07/12


--*/
{
	PLIST_ENTRY pEntry;
	PNDIS_HOOK_LIST_NODE pNdisHookListNode;
	PNDIS_OPEN_BLOCK pOpenBlock;
	LARGE_INTEGER interval;

	// unhook NDIS routines
	while (TRUE) {
		pEntry = ExInterlockedRemoveHeadList(&g_linkListHead, &g_lock);
		if (pEntry == NULL)
			break;
		pNdisHookListNode = CONTAINING_RECORD(pEntry, NDIS_HOOK_LIST_NODE, ListEntry);

		pOpenBlock = pNdisHookListNode->pOpenBlock;

		InterlockedExchange((PLONG)&pOpenBlock->ReceiveHandler, (LONG)pNdisHookListNode->ulRealReceiveHandler);
		// InterlockedExchange((PLONG)&pOpenBlock->WanReceiveHandler, (LONG)pNdisHookListNode->ulRealWanReceivePacketHandler);
		InterlockedExchange((PLONG)&pOpenBlock->ReceivePacketHandler, (LONG)pNdisHookListNode->ulRealProtocolReceiveHandler);
		InterlockedExchange((PLONG)&pOpenBlock->TransferDataCompleteHandler, (LONG)pNdisHookListNode->ulRealTransferDataCompleteHandler);

		// release memory
		ExFreePoolWithTag(pNdisHookListNode, '!nmN');
	}

	// wait 5 sec, reduce the possibility of BSOD.
	KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
	interval.QuadPart = - 5L * 10L * 1000L * 1000L;
	KeDelayExecutionThread(KernelMode, FALSE, &interval);

	NdisFreeBufferPool(g_BufferPool);
	NdisFreePacketPool(g_PacketPool);

	DbgPrint("NDIS Hook ------ end!\r\n");
}
コード例 #13
0
ファイル: waitsup.c プロジェクト: conioh/os-design
VOID
KeBoostCurrentThread(
    VOID
    )

/*++

Routine Description:

    This function boosts the priority of the current thread for one quantum,
    then reduce the thread priority to the base priority of the thread.

Arguments:

    None.

Return Value:

    None.

--*/

{

    KIRQL OldIrql;
    PKTHREAD Thread;

    //
    // Get current thread address, raise IRQL to synchronization level, and
    // lock the dispatcher database
    //

    Thread = KeGetCurrentThread();

redoboost:
    KiLockDispatcherDatabase(&OldIrql);

    //
    // If a priority boost is not already active for the current thread
    // and the thread priority is less than 14, then boost the thread
    // priority to 14 and give the thread a large quantum. Otherwise,
    // if a priority boost is active, then decrement the round trip
    // count. If the count goes to zero, then release the dispatcher
    // database lock, lower the thread priority to the base priority,
    // and then attempt to boost the priority again. This will give
    // other threads a chance to run. If the count does not reach zero,
    // then give the thread another large qunatum.
    //
    // If the thread priority is above 14, then no boost is applied.
    //

    if ((Thread->PriorityDecrement == 0) && (Thread->Priority < 14)) {
        Thread->PriorityDecrement = 14 - Thread->BasePriority;
        Thread->DecrementCount = ROUND_TRIP_DECREMENT_COUNT;
        Thread->Priority = 14;
        Thread->Quantum = Thread->ApcState.Process->ThreadQuantum * 2;

    } else if (Thread->PriorityDecrement != 0) {
        Thread->DecrementCount -= 1;
        if (Thread->DecrementCount == 0) {
            KiUnlockDispatcherDatabase(OldIrql);
            KeSetPriorityThread(Thread, Thread->BasePriority);
            goto redoboost;

        } else {
            Thread->Quantum = Thread->ApcState.Process->ThreadQuantum * 2;
        }
    }

    KiUnlockDispatcherDatabase(OldIrql);
    return;
}
コード例 #14
0
ファイル: input.c プロジェクト: RPG-7/reactos
/*
 * RawInputThreadMain
 *
 * Reads data from input devices and supports win32 timers
 */
VOID NTAPI
RawInputThreadMain()
{
    NTSTATUS MouStatus = STATUS_UNSUCCESSFUL, KbdStatus = STATUS_UNSUCCESSFUL, Status;
    IO_STATUS_BLOCK MouIosb, KbdIosb;
    PFILE_OBJECT pKbdDevice = NULL, pMouDevice = NULL;
    LARGE_INTEGER ByteOffset;
    //LARGE_INTEGER WaitTimeout;
    PVOID WaitObjects[3], pSignaledObject = NULL;
    ULONG cWaitObjects = 0, cMaxWaitObjects = 1;
    MOUSE_INPUT_DATA MouseInput;
    KEYBOARD_INPUT_DATA KeyInput;

    ByteOffset.QuadPart = (LONGLONG)0;
    //WaitTimeout.QuadPart = (LONGLONG)(-10000000);

    ptiRawInput = GetW32ThreadInfo();
    ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
    ptiRawInput->pClientInfo->dwTIFlags = ptiRawInput->TIF_flags;

    TRACE("Raw Input Thread %p\n", ptiRawInput);

    KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
                        LOW_REALTIME_PRIORITY + 3);

    UserEnterExclusive();
    StartTheTimers();
    UserLeave();

    for (;;)
    {
        if (!ghMouseDevice)
        {
            /* Check if mouse device already exists */
            Status = OpenInputDevice(&ghMouseDevice, &pMouDevice, L"\\Device\\PointerClass0" );
            if (NT_SUCCESS(Status))
            {
                ++cMaxWaitObjects;
                TRACE("Mouse connected!\n");
            }
        }
        if (!ghKeyboardDevice)
        {
            /* Check if keyboard device already exists */
            Status = OpenInputDevice(&ghKeyboardDevice, &pKbdDevice, L"\\Device\\KeyboardClass0");
            if (NT_SUCCESS(Status))
            {
                ++cMaxWaitObjects;
                TRACE("Keyboard connected!\n");
                // Get and load keyboard attributes.
                UserInitKeyboard(ghKeyboardDevice);
                UserEnterExclusive();
                // Register the Window hotkey.
                UserRegisterHotKey(PWND_BOTTOM, IDHK_WINKEY, MOD_WIN, 0);
                // Register the debug hotkeys.
                StartDebugHotKeys();
                UserLeave();
            }
        }

        /* Reset WaitHandles array */
        cWaitObjects = 0;
        WaitObjects[cWaitObjects++] = MasterTimer;

        if (ghMouseDevice)
        {
            /* Try to read from mouse if previous reading is not pending */
            if (MouStatus != STATUS_PENDING)
            {
                MouStatus = ZwReadFile(ghMouseDevice,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &MouIosb,
                                       &MouseInput,
                                       sizeof(MOUSE_INPUT_DATA),
                                       &ByteOffset,
                                       NULL);
            }

            if (MouStatus == STATUS_PENDING)
                WaitObjects[cWaitObjects++] = &pMouDevice->Event;
        }

        if (ghKeyboardDevice)
        {
            /* Try to read from keyboard if previous reading is not pending */
            if (KbdStatus != STATUS_PENDING)
            {
                KbdStatus = ZwReadFile(ghKeyboardDevice,
                                       NULL,
                                       NULL,
                                       NULL,
                                       &KbdIosb,
                                       &KeyInput,
                                       sizeof(KEYBOARD_INPUT_DATA),
                                       &ByteOffset,
                                       NULL);

            }
            if (KbdStatus == STATUS_PENDING)
                WaitObjects[cWaitObjects++] = &pKbdDevice->Event;
        }

        /* If all objects are pending, wait for them */
        if (cWaitObjects == cMaxWaitObjects)
        {
            Status = KeWaitForMultipleObjects(cWaitObjects,
                                              WaitObjects,
                                              WaitAny,
                                              UserRequest,
                                              KernelMode,
                                              TRUE,
                                              NULL,//&WaitTimeout,
                                              NULL);

            if ((Status >= STATUS_WAIT_0) &&
                (Status < (STATUS_WAIT_0 + (LONG)cWaitObjects)))
            {
                /* Some device has finished reading */
                pSignaledObject = WaitObjects[Status - STATUS_WAIT_0];

                /* Check if it is mouse or keyboard and update status */
                if (pSignaledObject == &pMouDevice->Event)
                    MouStatus = MouIosb.Status;
                else if (pSignaledObject == &pKbdDevice->Event)
                    KbdStatus = KbdIosb.Status;
                else if (pSignaledObject == MasterTimer)
                {
                    ProcessTimers();
                }
                else ASSERT(FALSE);
            }
        }

        /* Have we successed reading from mouse? */
        if (NT_SUCCESS(MouStatus) && MouStatus != STATUS_PENDING)
        {
            TRACE("MouseEvent\n");

            /* Set LastInputTick */
            IntLastInputTick(TRUE);

            /* Process data */
            UserEnterExclusive();
            UserProcessMouseInput(&MouseInput);
            UserLeave();
        }
        else if (MouStatus != STATUS_PENDING)
            ERR("Failed to read from mouse: %x.\n", MouStatus);

        /* Have we successed reading from keyboard? */
        if (NT_SUCCESS(KbdStatus) && KbdStatus != STATUS_PENDING)
        {
            TRACE("KeyboardEvent: %s %04x\n",
                  (KeyInput.Flags & KEY_BREAK) ? "up" : "down",
                  KeyInput.MakeCode);

            /* Set LastInputTick */
            IntLastInputTick(TRUE);

            /* Process data */
            UserEnterExclusive();
            UserProcessKeyboardInput(&KeyInput);
            UserLeave();
        }
        else if (KbdStatus != STATUS_PENDING)
            ERR("Failed to read from keyboard: %x.\n", KbdStatus);
    }
    ERR("Raw Input Thread Exit!\n");
}
コード例 #15
0
ファイル: EncryptedIoQueue.c プロジェクト: BitMerc/veracrypt
static VOID MainThreadProc (PVOID threadArg)
{
	EncryptedIoQueue *queue = (EncryptedIoQueue *) threadArg;
	PLIST_ENTRY listEntry;
	EncryptedIoQueueItem *item;

	LARGE_INTEGER fragmentOffset;
	ULONG dataRemaining;
	PUCHAR activeFragmentBuffer = queue->FragmentBufferA;
	PUCHAR dataBuffer;
	EncryptedIoRequest *request;
	uint64 intersectStart;
	uint32 intersectLength;
	ULONGLONG addResult;
	HRESULT hResult;

	if (IsEncryptionThreadPoolRunning())
		KeSetPriorityThread (KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

	while (!queue->ThreadExitRequested)
	{
		if (!NT_SUCCESS (KeWaitForSingleObject (&queue->MainThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL)))
			continue;

		while ((listEntry = ExInterlockedRemoveHeadList (&queue->MainThreadQueue, &queue->MainThreadQueueLock)))
		{
			PIRP irp = CONTAINING_RECORD (listEntry, IRP, Tail.Overlay.ListEntry);
			PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (irp);
			
			if (queue->Suspended)
				KeWaitForSingleObject (&queue->QueueResumedEvent, Executive, KernelMode, FALSE, NULL);

			item = GetPoolBuffer (queue, sizeof (EncryptedIoQueueItem));
			if (!item)
			{
				TCCompleteDiskIrp (irp, STATUS_INSUFFICIENT_RESOURCES, 0);
				DecrementOutstandingIoCount (queue);
				IoReleaseRemoveLock (&queue->RemoveLock, irp);

				continue;
			}

			item->Queue = queue;
			item->OriginalIrp = irp;
			item->Status = STATUS_SUCCESS;

			IoSetCancelRoutine (irp, NULL);
			if (irp->Cancel)
			{
				CompleteOriginalIrp (item, STATUS_CANCELLED, 0);
				continue;
			}

			switch (irpSp->MajorFunction)
			{
			case IRP_MJ_READ:
				item->Write = FALSE;
				item->OriginalOffset = irpSp->Parameters.Read.ByteOffset;
				item->OriginalLength = irpSp->Parameters.Read.Length;
				break;

			case IRP_MJ_WRITE:
				item->Write = TRUE;
				item->OriginalOffset = irpSp->Parameters.Write.ByteOffset;
				item->OriginalLength = irpSp->Parameters.Write.Length;
				break;

			default:
				CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0);
				continue;
			}

#ifdef TC_TRACE_IO_QUEUE
			item->OriginalIrpOffset = item->OriginalOffset;
#endif

			// Handle misaligned read operations to work around a bug in Windows System Assessment Tool which does not follow FILE_FLAG_NO_BUFFERING requirements when benchmarking disk devices
			if (queue->IsFilterDevice
				&& !item->Write
				&& item->OriginalLength > 0
				&& (item->OriginalLength & (ENCRYPTION_DATA_UNIT_SIZE - 1)) == 0
				&& (item->OriginalOffset.QuadPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0)
			{
				byte *buffer;
				ULONG alignedLength;
				LARGE_INTEGER alignedOffset;
				hResult = ULongAdd(item->OriginalLength, ENCRYPTION_DATA_UNIT_SIZE, &alignedLength);
				if (hResult != S_OK)
				{
					CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0);
					continue;
				}

				alignedOffset.QuadPart = item->OriginalOffset.QuadPart & ~((LONGLONG) ENCRYPTION_DATA_UNIT_SIZE - 1);

				buffer = TCalloc (alignedLength);
				if (!buffer)
				{
					CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0);
					continue;
				}

				item->Status = TCReadDevice (queue->LowerDeviceObject, buffer, alignedOffset, alignedLength);

				if (NT_SUCCESS (item->Status))
				{
					UINT64_STRUCT dataUnit;

					dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority);
					if (!dataBuffer)
					{
						TCfree (buffer);
						CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0);
						continue;
					}

					if (queue->EncryptedAreaStart != -1 && queue->EncryptedAreaEnd != -1)
					{
						GetIntersection (alignedOffset.QuadPart, alignedLength, queue->EncryptedAreaStart, queue->EncryptedAreaEnd, &intersectStart, &intersectLength);
						if (intersectLength > 0)
						{
							dataUnit.Value = intersectStart / ENCRYPTION_DATA_UNIT_SIZE;
							DecryptDataUnits (buffer + (intersectStart - alignedOffset.QuadPart), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
						}
					}

					memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength);
				}

				TCfree (buffer);
				CompleteOriginalIrp (item, item->Status, NT_SUCCESS (item->Status) ? item->OriginalLength : 0);
				continue;
			}

			// Validate offset and length
			if (item->OriginalLength == 0
				|| (item->OriginalLength & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0
				|| (item->OriginalOffset.QuadPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0
				|| (	!queue->IsFilterDevice && 
						(	(S_OK != ULongLongAdd(item->OriginalOffset.QuadPart, item->OriginalLength, &addResult))
							||	(addResult > (ULONGLONG) queue->VirtualDeviceLength)
						)
					)
				)
			{
				CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0);
				continue;
			}

#ifdef TC_TRACE_IO_QUEUE
			Dump ("Q  %I64d [%I64d] %c len=%d\n", item->OriginalOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), item->Write ? 'W' : 'R', item->OriginalLength);
#endif

			if (!queue->IsFilterDevice)
			{
				// Adjust the offset for host file or device
				if (queue->CryptoInfo->hiddenVolume)
					hResult = ULongLongAdd(item->OriginalOffset.QuadPart, queue->CryptoInfo->hiddenVolumeOffset, &addResult);
				else
					hResult = ULongLongAdd(item->OriginalOffset.QuadPart, queue->CryptoInfo->volDataAreaOffset, &addResult); 

				if (hResult != S_OK)
				{
					CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0);
					continue;
				}
				else
					item->OriginalOffset.QuadPart = addResult;

				// Hidden volume protection
				if (item->Write && queue->CryptoInfo->bProtectHiddenVolume)
				{
					// If there has already been a write operation denied in order to protect the
					// hidden volume (since the volume mount time)
					if (queue->CryptoInfo->bHiddenVolProtectionAction)	
					{
						// Do not allow writing to this volume anymore. This is to fake a complete volume
						// or system failure (otherwise certain kinds of inconsistency within the file
						// system could indicate that this volume has used hidden volume protection).
						CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0);
						continue;
					}

					// Verify that no byte is going to be written to the hidden volume area
					if (RegionsOverlap ((unsigned __int64) item->OriginalOffset.QuadPart,
						(unsigned __int64) item->OriginalOffset.QuadPart + item->OriginalLength - 1,
						queue->CryptoInfo->hiddenVolumeOffset,
						(unsigned __int64) queue->CryptoInfo->hiddenVolumeOffset + queue->CryptoInfo->hiddenVolumeProtectedSize - 1))
					{
						Dump ("Hidden volume protection triggered: write %I64d-%I64d (protected %I64d-%I64d)\n", item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, queue->CryptoInfo->hiddenVolumeOffset, queue->CryptoInfo->hiddenVolumeOffset + queue->CryptoInfo->hiddenVolumeProtectedSize - 1);
						queue->CryptoInfo->bHiddenVolProtectionAction = TRUE;

						// Deny this write operation to prevent the hidden volume from being overwritten
						CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0);
						continue;
					}
				}
			}
			else if (item->Write
				&& RegionsOverlap (item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET + TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE - 1))
			{
				// Prevent inappropriately designed software from damaging important data that may be out of sync with the backup on the Rescue Disk (such as the end of the encrypted area).
				Dump ("Preventing write to the system encryption key data area\n");
				CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0);
				continue;
			}
			else if (item->Write && IsHiddenSystemRunning()
				&& (RegionsOverlap (item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, TC_SECTOR_SIZE_BIOS, TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS - 1)
				 || RegionsOverlap (item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, GetBootDriveLength(), _I64_MAX)))
			{
				Dump ("Preventing write to boot loader or host protected area\n");
				CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0);
				continue;
			}

			dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority);

			if (dataBuffer == NULL)
			{
				CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0);
				continue;
			}

			// Divide data block to fragments to enable efficient overlapping of encryption and IO operations

			dataRemaining = item->OriginalLength;
			fragmentOffset = item->OriginalOffset;

			while (dataRemaining > 0)
			{
				BOOL isLastFragment = dataRemaining <= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
				
				ULONG dataFragmentLength = isLastFragment ? dataRemaining : TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
				activeFragmentBuffer = (activeFragmentBuffer == queue->FragmentBufferA ? queue->FragmentBufferB : queue->FragmentBufferA);

				InterlockedIncrement (&queue->IoThreadPendingRequestCount);

				// Create IO request
				request = GetPoolBuffer (queue, sizeof (EncryptedIoRequest));
				if (!request)
				{
					CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0);
					break;
				}
				request->Item = item;
				request->CompleteOriginalIrp = isLastFragment;
				request->Offset = fragmentOffset;
				request->Data = activeFragmentBuffer;
				request->OrigDataBufferFragment = dataBuffer;
				request->Length = dataFragmentLength;

				if (queue->IsFilterDevice)
				{
					if (queue->EncryptedAreaStart == -1 || queue->EncryptedAreaEnd == -1)
					{
						request->EncryptedLength = 0;
					}
					else
					{
						// Get intersection of data fragment with encrypted area
						GetIntersection (fragmentOffset.QuadPart, dataFragmentLength, queue->EncryptedAreaStart, queue->EncryptedAreaEnd, &intersectStart, &intersectLength);

						request->EncryptedOffset = intersectStart - fragmentOffset.QuadPart;
						request->EncryptedLength = intersectLength;
					}
				}
				else
				{
					request->EncryptedOffset = 0;
					request->EncryptedLength = dataFragmentLength;
				}

				AcquireFragmentBuffer (queue, activeFragmentBuffer);

				if (item->Write)
				{
					// Encrypt data
					memcpy (activeFragmentBuffer, dataBuffer, dataFragmentLength);

					if (request->EncryptedLength > 0)
					{
						UINT64_STRUCT dataUnit;
						ASSERT (request->EncryptedOffset + request->EncryptedLength <= request->Offset.QuadPart + request->Length);

						dataUnit.Value = (request->Offset.QuadPart + request->EncryptedOffset) / ENCRYPTION_DATA_UNIT_SIZE;

						if (queue->CryptoInfo->bPartitionInInactiveSysEncScope)
							dataUnit.Value += queue->CryptoInfo->FirstDataUnitNo.Value;
						else if (queue->RemapEncryptedArea)
							dataUnit.Value += queue->RemappedAreaDataUnitOffset;
								
						EncryptDataUnits (activeFragmentBuffer + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
					}
				}

				// Queue IO request
				ExInterlockedInsertTailList (&queue->IoThreadQueue, &request->ListEntry, &queue->IoThreadQueueLock);
				KeSetEvent (&queue->IoThreadQueueNotEmptyEvent, IO_DISK_INCREMENT, FALSE);

				if (isLastFragment)
					break;

				dataRemaining -= TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
				dataBuffer += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
				fragmentOffset.QuadPart += TC_ENC_IO_QUEUE_MAX_FRAGMENT_SIZE;
			}
		}
	}

	PsTerminateSystemThread (STATUS_SUCCESS);
}
コード例 #16
0
ファイル: filedisk.c プロジェクト: ren22342411/seewhatIwrite
//前面说到为每一个磁盘设备对象生成了一个系统线程,用来处理Irp
VOID
FileDiskThread (
    IN PVOID Context
    )
{
    PDEVICE_OBJECT      device_object;
    PDEVICE_EXTENSION   device_extension;
    PLIST_ENTRY         request;
    PIRP                irp;
    PIO_STACK_LOCATION  io_stack;
    PUCHAR              system_buffer;
    PUCHAR              buffer;

    ASSERT(Context != NULL);

    device_object = (PDEVICE_OBJECT) Context;

    device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;

    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

    for (;;)
    {
        KeWaitForSingleObject(
            &device_extension->request_event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        if (device_extension->terminate_thread)
        {
            PsTerminateSystemThread(STATUS_SUCCESS);
        }

        while (request = ExInterlockedRemoveHeadList(
            &device_extension->list_head,
            &device_extension->list_lock
            ))
        {
            irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);

            io_stack = IoGetCurrentIrpStackLocation(irp);

            switch (io_stack->MajorFunction)
            {
            case IRP_MJ_READ:
                system_buffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
                if (system_buffer == NULL)
                {
                    irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    irp->IoStatus.Information = 0;
                    break;
                }
                buffer = (PUCHAR) ExAllocatePool(PagedPool, io_stack->Parameters.Read.Length);
                if (buffer == NULL)
                {
                    irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    irp->IoStatus.Information = 0;
                    break;
                }
                ZwReadFile(
                    device_extension->file_handle,
                    NULL,
                    NULL,
                    NULL,
                    &irp->IoStatus,
                    buffer,
                    io_stack->Parameters.Read.Length,
                    &io_stack->Parameters.Read.ByteOffset,
                    NULL
                    );
                RtlCopyMemory(system_buffer, buffer, io_stack->Parameters.Read.Length);
                ExFreePool(buffer);
                break;

            case IRP_MJ_WRITE:
                if ((io_stack->Parameters.Write.ByteOffset.QuadPart +
                     io_stack->Parameters.Write.Length) >
                     device_extension->file_size.QuadPart)
                {
                    irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    irp->IoStatus.Information = 0;
                }
                ZwWriteFile(
                    device_extension->file_handle,
                    NULL,
                    NULL,
                    NULL,
                    &irp->IoStatus,
                    MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
                    io_stack->Parameters.Write.Length,
                    &io_stack->Parameters.Write.ByteOffset,
                    NULL
                    );
                break;

            case IRP_MJ_DEVICE_CONTROL:
                switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
                {
                case IOCTL_FILE_DISK_OPEN_FILE:

                    SeImpersonateClient(device_extension->security_client_context, NULL);

                    irp->IoStatus.Status = FileDiskOpenFile(device_object, irp);

                    PsRevertToSelf();

                    break;

                case IOCTL_FILE_DISK_CLOSE_FILE:
                    irp->IoStatus.Status = FileDiskCloseFile(device_object, irp);
                    break;

                default:
                    irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                }
                break;

            default:
                irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
            }

            IoCompleteRequest(
                irp,
                (CCHAR) (NT_SUCCESS(irp->IoStatus.Status) ?
                IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );
        }
    }
}
コード例 #17
0
VOID
ImScsiWorkerThread(__in PVOID Context)
{
    pHW_LU_EXTENSION            pLUExt = (pHW_LU_EXTENSION)Context;
    pMP_WorkRtnParms            pWkRtnParms = NULL;
    PLIST_ENTRY                 request_list = NULL;
    PKSPIN_LOCK                 request_list_lock = NULL;
    PKEVENT                     wait_objects[2] = { NULL };

    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

    if (pLUExt != NULL)
    {
        KdPrint(("PhDskMnt::ImScsiWorkerThread: Device worker thread start. pLUExt = 0x%p\n",
            pLUExt));

        request_list = &pLUExt->RequestList;
        request_list_lock = &pLUExt->RequestListLock;
        wait_objects[0] = &pLUExt->RequestEvent;

        // If this is a VM backed disk that should be pre-loaded with an image file
        // we have to load the contents of that file now before entering the service
        // loop.
        if (pLUExt->VMDisk && (pLUExt->ImageFile != NULL))
            if (!ImScsiFillMemoryDisk(pLUExt))
                KeSetEvent(&pLUExt->StopThread, (KPRIORITY)0, FALSE);
    }
    else
    {
        KdPrint(("PhDskMnt::ImScsiWorkerThread: Global worker thread start. pLUExt=%p\n",
            pLUExt));

        request_list = &pMPDrvInfoGlobal->RequestList;
        request_list_lock = &pMPDrvInfoGlobal->RequestListLock;
        wait_objects[0] = &pMPDrvInfoGlobal->RequestEvent;
    }
    wait_objects[1] = &pMPDrvInfoGlobal->StopWorker;

    for (;;)
    {
        PLIST_ENTRY                 request;
        KLOCK_QUEUE_HANDLE          lock_handle;
        KIRQL                       lowest_assumed_irql = PASSIVE_LEVEL;

#ifdef USE_SCSIPORT

        NTSTATUS                    status = STATUS_SUCCESS;
        PIRP                        irp = NULL;

        ImScsiGetControllerObject();

        if (pMPDrvInfoGlobal->ControllerObject != NULL)
        {
            KdPrint2(("PhDskMnt::ImScsiWorkerThread: Pre-building IRP for next SMB_IMSCSI_CHECK.\n"));

            irp = ImScsiBuildCompletionIrp();
        }
#endif

        for (;;)
        {
            ImScsiAcquireLock(request_list_lock, &lock_handle, lowest_assumed_irql);

            request = RemoveHeadList(request_list);

            ImScsiReleaseLock(&lock_handle, &lowest_assumed_irql);

            if (request != request_list)
            {
                break;
            }

            if (KeReadStateEvent(&pMPDrvInfoGlobal->StopWorker) ||
                ((pLUExt != NULL) && (KeReadStateEvent(&pLUExt->StopThread))))
            {
                KdPrint(("PhDskMnt::ImScsiWorkerThread shutting down.\n"));

                if (pLUExt != NULL)
                {
                    KIRQL lowest_assumed_irql = PASSIVE_LEVEL;
                    ImScsiCleanupLU(pLUExt, &lowest_assumed_irql);
                }

#ifdef USE_SCSIPORT
                // One last SMB_IMSCSI_CHECK call to flush response queue and free allocated IRP
                if (irp != NULL)
                {
                    IoCallDriver(pMPDrvInfoGlobal->ControllerObject, irp);
                }
#endif

                PsTerminateSystemThread(STATUS_SUCCESS);
                return;
            }

            KdPrint2(("PhDskMnt::ImScsiWorkerThread idle, waiting for request.\n"));

            KeWaitForMultipleObjects(2, (PVOID*)wait_objects, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
        }

        pWkRtnParms = CONTAINING_RECORD(request, MP_WorkRtnParms, RequestListEntry);

        KdPrint2(("PhDskMnt::ImScsiWorkerThread got request. pWkRtnParms = 0x%p\n",
            pWkRtnParms));

        // Request to wait for LU worker thread to terminate
        if (pWkRtnParms->pSrb == NULL)
        {
            KdPrint(("PhDskMnt::ImScsiWorkerThread: Request to wait for LU worker thread to exit. pLUExt=%p\n",
                pWkRtnParms->pLUExt));

            if (pWkRtnParms->pLUExt->WorkerThread != NULL)
            {
                KeWaitForSingleObject(
                    pWkRtnParms->pLUExt->WorkerThread,
                    Executive,
                    KernelMode,
                    FALSE,
                    NULL);

                ObDereferenceObject(pWkRtnParms->pLUExt->WorkerThread);
                pWkRtnParms->pLUExt->WorkerThread = NULL;

                KdPrint(("PhDskMnt::ImScsiWorkerThread: Worker thread exit. Ready to free LUExt.\n"));
            }
            else
            {
                KdPrint(("PhDskMnt::ImScsiWorkerThread: Worker not started. Ready to free LUExt.\n"));
            }
            
            ExFreePoolWithTag(pWkRtnParms->pLUExt, MP_TAG_GENERAL);

            ExFreePoolWithTag(pWkRtnParms, MP_TAG_GENERAL);

            continue;
        }

        ImScsiDispatchWork(pWkRtnParms);

#ifdef USE_SCSIPORT

        KdPrint2(("PhDskMnt::ImScsiWorkerThread: Calling SMB_IMSCSI_CHECK for work: 0x%p.\n", pWkRtnParms));

        status = ImScsiCallForCompletion(irp, pWkRtnParms, &lowest_assumed_irql);

        if (!NT_SUCCESS(status))
            DbgPrint("PhDskMnt::ImScsiWorkerThread: IoCallDriver failed: 0x%X for work 0x%p\n", status, pWkRtnParms);
        else
            KdPrint2(("PhDskMnt::ImScsiWorkerThread: Finished SMB_IMSCSI_CHECK for work: 0x%p.\n", pWkRtnParms));

#endif

#ifdef USE_STORPORT

        KdPrint2(("PhDskMnt::ImScsiWorkerThread: Sending 'RequestComplete' to StorPort for work: 0x%p.\n", pWkRtnParms));

        StorPortNotification(RequestComplete, pWkRtnParms->pHBAExt, pWkRtnParms->pSrb);

        ExFreePoolWithTag(pWkRtnParms, MP_TAG_GENERAL);

        KdPrint2(("PhDskMnt::ImScsiWorkerThread: Finished work: 0x%p.\n", pWkRtnParms));

#endif

    }
}
コード例 #18
0
// =========================================================================
// This is the main thread that removes IRP from the queue
// and processes (peforms I/O on) it.
// Context - this is set to the device object
VOID
FreeOTFEThread(
    IN PVOID Context
    )
{
    NTSTATUS status;
    PDEVICE_OBJECT devObj;
    PDEVICE_EXTENSION devExt;
    PIRP Irp;
    PIO_STACK_LOCATION irpSp;
    
        
    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("FreeOTFEThread\n"));
    
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Setting threads priority...\n"));
    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

    devObj = (PDEVICE_OBJECT)Context;
    devExt = (PDEVICE_EXTENSION)devObj->DeviceExtension;

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Entering endless loop for queued event signals...\n"));
    while (TRUE)
        {
        // Wait until signalled that there is one or more IRP queued...
        status = KeWaitForSingleObject(
            &devExt->IRPQueueSemaphore,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );
        
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Queued event signalled.\n"));
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Thread is for device: %ls\n", devExt->zzDeviceName.Buffer));
            
        // If we're supposed to terminate the thread, bail out...
        if (devExt->TerminateThread) 
           {
           DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Thread has been requested to terminate!.\n"));
           break;  // Thread terminates after this loop terminates
           }
           
           
        // Remove a pending IRP from the queue.
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Thread getting next queued IRP.\n"));
        Irp = IoCsqRemoveNextIrp(&devExt->CancelSafeQueue, NULL);

        if (!Irp)
            {
            DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Queued IRP was cancelled; next.\n"));
            continue; // go back to waiting
            }
            
            
        // Default...
        status = STATUS_NOT_IMPLEMENTED;
        Irp->IoStatus.Information = 0;


        irpSp = IoGetCurrentIrpStackLocation(Irp);

        switch (irpSp->MajorFunction)
            {
            case IRP_MJ_DEVICE_CONTROL:
                {
                DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("THREAD: IRP_MJ_DEVICE_CONTROL\n"));
                switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
                    {
                    case IOCTL_FREEOTFEHASH_HASHDATA:
                        {
                        status = IOCTL_FreeOTFEHashIOCTL_Hash(devObj, Irp);
                        break;
                        }
                        
                    default:
                        {
                        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("THREAD: Unrecognised IRP_MJ_DEVICE_CONTROL IRP.\n"));
                        }
                        
                    }   // switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
                break;
                }   // case IRP_MJ_DEVICE_CONTROL:
                
                default:
                    {
                    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("THREAD: Unrecognised IRP MajorFunction.\n"));
                    }
                        
            }   // switch (irpSp->MajorFunction)

                
        
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Thread completing IRP (%d).\n", status));
        if (!(NT_SUCCESS(status)))
            {
            DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Thread setting IoStatus.Information = 0\n"));
            Irp->IoStatus.Information = 0;
            }                
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);           
        }   // while (TRUE)
        
        
    // This part will only be reached if the thread has been signalled to
    // terminate
    devExt = NULL;
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Terminating thread...\n"));
    status = PsTerminateSystemThread(STATUS_SUCCESS);
    if (!NT_SUCCESS(status))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Thread did NOT terminate OK\n"));
        }        
        
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Thread dropping out.\n"));           

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("FreeOTFEThread\n"));
}
コード例 #19
0
ファイル: Iomon.C プロジェクト: xfxf123444/japan
VOID
Thread (
    IN PVOID Context
    )
{
    PDEVICE_OBJECT      DeviceObject;
    PDEVICE_EXTENSION   deviceExtension;
    PLIST_ENTRY         request;
    PIRP                Irp;
    PIO_STACK_LOCATION  currentIrpStack;
    PIO_STACK_LOCATION  nextIrpStack;
	DWORD				dwStartSec;
	DWORD				dwLength;
	PVOID				pBuffer;
	NTSTATUS			status;
	DWORD				dwRetVal;
	BOOL				bReadSys;
	PBLK_MOVER_PARAM	pParam;
    DIOC_REGISTERS		*pRegs;
	PREAD_WRITE_BUFFER	pReadWriteBuffer;
	KIRQL				Irql;
//  PAGED_CODE();
    ASSERT(Context != NULL);

    DeviceObject = (PDEVICE_OBJECT) Context;

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    KeSetPriorityThread(KeGetCurrentThread(),HIGH_PRIORITY);//LOW_REALTIME_PRIORITY);// HIGH_PRIORITY);

    while(TRUE)
    {
        KeWaitForSingleObject(
            &deviceExtension->request_event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

		ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
        if (deviceExtension->terminate_thread)
        {
            PsTerminateSystemThread(STATUS_SUCCESS);
        }

        while (request = ExInterlockedRemoveHeadList(
            &deviceExtension->list_head,
            &deviceExtension->list_lock
            ))
        {
            Irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);

            currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
			nextIrpStack = IoGetNextIrpStackLocation(Irp);
			
			ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
            switch (currentIrpStack->MajorFunction)
            {
            case IRP_MJ_READ:
            case IRP_MJ_WRITE:
				pBuffer		= MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
				dwLength	= currentIrpStack->Parameters.Read.Length/SECTOR_SIZE;
				dwStartSec	= (DWORD)(currentIrpStack->Parameters.Read.ByteOffset.QuadPart/SECTOR_SIZE);

				status = BlkMoverRelocateReadWrite(DeviceObject,currentIrpStack->MajorFunction,dwStartSec,dwLength,pBuffer);

				//ASSERT(status == STATUS_SUCCESS);
				Irp->IoStatus.Status	  = status;
				Irp->IoStatus.Information = dwLength*SECTOR_SIZE;
				break;
            case IRP_MJ_DEVICE_CONTROL:
                switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode)
                {
				case IOCTL_YG_BLOCK_MOVER_FLUSH_BUFFER:
					pRegs = (DIOC_REGISTERS *)Irp->AssociatedIrp.SystemBuffer;
					pRegs->reg_EAX = TRUE;
					
					status = FlushBuf(g_pMoverData->DeviceObject);
			        Irp->IoStatus.Status	  = status;
					Irp->IoStatus.Information = sizeof(DIOC_REGISTERS);
                    break;
                case IOCTL_YG_BLOCK_MOVING_GROUP_CURRENT:
					pRegs = (DIOC_REGISTERS *)Irp->AssociatedIrp.SystemBuffer;

					g_MovingGroup.bFront		= pRegs->reg_EAX;
					g_MovingGroup.dwSStart		= pRegs->reg_EBX;
					g_MovingGroup.dwTStart		= pRegs->reg_ECX;
					g_MovingGroup.dwSize		= pRegs->reg_EDX;
					g_MovingGroup.dwMovedSize	= 0;
					g_dwMovedRecNum				= pRegs->reg_EDI;
					g_pMoverData->bWorking		= TRUE;

					pRegs->reg_EAX				= TRUE;

			        Irp->IoStatus.Status	  = STATUS_SUCCESS;
					Irp->IoStatus.Information = sizeof(DIOC_REGISTERS);
                    break;
				case IOCTL_YG_GET_MOVED_SECTORS:
					pRegs = (DIOC_REGISTERS *)Irp->AssociatedIrp.SystemBuffer;
					pRegs->reg_EAX = g_dwMovedSecs;

			        Irp->IoStatus.Status	  = STATUS_SUCCESS;
					Irp->IoStatus.Information = sizeof(DIOC_REGISTERS);
                    break;
				case IOCTL_YG_READ:
					pReadWriteBuffer = (PREAD_WRITE_BUFFER)Irp->AssociatedIrp.SystemBuffer;
					dwLength		 = pReadWriteBuffer->dwLength;
					pBuffer			 = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
					dwStartSec		 = pReadWriteBuffer->dwStartSec;

					if (pReadWriteBuffer->dwMovedRecNum == YGBLK_READ_WRITE)
					{
						status = BlkMoverRelocateReadWrite(DeviceObject,IRP_MJ_READ,dwStartSec,dwLength,pBuffer);
					}
					else
					{
						status = SyncReadWriteSec(DeviceObject,dwStartSec,dwLength ,pBuffer ,IRP_MJ_READ);
					}
					MmUnlockPages(Irp->MdlAddress);
					IoFreeMdl(Irp->MdlAddress);
					Irp->MdlAddress = NULL;
			        Irp->IoStatus.Status	  = STATUS_SUCCESS;
					Irp->IoStatus.Information = sizeof(READ_WRITE_BUFFER);
                    break;
				case IOCTL_YG_WRITE:
					pReadWriteBuffer = (PREAD_WRITE_BUFFER)Irp->AssociatedIrp.SystemBuffer;
					dwLength		 = pReadWriteBuffer->dwLength;
					pBuffer			 = MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
					dwStartSec		 = pReadWriteBuffer->dwStartSec;

					if (pReadWriteBuffer->dwMovedRecNum == YGBLK_READ_WRITE)
					{
						status = BlkMoverRelocateReadWrite(DeviceObject,IRP_MJ_WRITE,dwStartSec,dwLength,pBuffer);
					}
					else
					{
						status = SyncReadWriteSec(DeviceObject,dwStartSec,dwLength ,pBuffer ,IRP_MJ_WRITE);
					}
					MmUnlockPages(Irp->MdlAddress);
					IoFreeMdl(Irp->MdlAddress);
					Irp->MdlAddress = NULL;

					if (pReadWriteBuffer->dwMovedRecNum != YGBLK_READ_WRITE)
					{
						if(!pReadWriteBuffer->bSys && g_dwDataRecNum)
						{
							//g_dwMovedRecNum = pReadWriteBuffer->dwMovedRecNum;
							g_MovingGroup.dwMovedSize += dwLength;
						}

						if(g_bReLocate && pReadWriteBuffer->bSys) 
							g_dwRePointer = pReadWriteBuffer->dwStartSec + dwLength;
					}

			        Irp->IoStatus.Status	  = STATUS_SUCCESS;
					Irp->IoStatus.Information = sizeof(READ_WRITE_BUFFER);
                    break;
                default:
                    Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                    Irp->IoStatus.Information = 0;
                }
                break;
            default:
                DbgPrint("BlkMover:Thread default conditions.");

                Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                Irp->IoStatus.Information = 0;
            }
			IoCompleteRequest(Irp,
							(CCHAR) (NT_SUCCESS(Irp->IoStatus.Status) ?
							IO_DISK_INCREMENT : IO_NO_INCREMENT));
        }
    }
}
コード例 #20
0
ファイル: EncryptedIoQueue.c プロジェクト: BitMerc/veracrypt
static VOID IoThreadProc (PVOID threadArg)
{
	EncryptedIoQueue *queue = (EncryptedIoQueue *) threadArg;
	PLIST_ENTRY listEntry;
	EncryptedIoRequest *request;

	KeSetPriorityThread (KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

	if (!queue->IsFilterDevice && queue->SecurityClientContext)
	{
#ifdef DEBUG
		NTSTATUS status =
#endif
		SeImpersonateClientEx (queue->SecurityClientContext, NULL);
		ASSERT (NT_SUCCESS (status));
	}

	while (!queue->ThreadExitRequested)
	{
		if (!NT_SUCCESS (KeWaitForSingleObject (&queue->IoThreadQueueNotEmptyEvent, Executive, KernelMode, FALSE, NULL)))
			continue;

		if (queue->ThreadExitRequested)
			break;

		while ((listEntry = ExInterlockedRemoveHeadList (&queue->IoThreadQueue, &queue->IoThreadQueueLock)))
		{
			InterlockedDecrement (&queue->IoThreadPendingRequestCount);
			request = CONTAINING_RECORD (listEntry, EncryptedIoRequest, ListEntry);
			
#ifdef TC_TRACE_IO_QUEUE
			Dump ("%c   %I64d [%I64d] roff=%I64d rlen=%d\n", request->Item->Write ? 'W' : 'R', request->Item->OriginalIrpOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), request->Offset.QuadPart, request->Length);
#endif

			// Perform IO request if no preceding request of the item failed
			if (NT_SUCCESS (request->Item->Status))
			{
				if (queue->IsFilterDevice)
				{
					if (queue->RemapEncryptedArea && request->EncryptedLength > 0)
					{
						if (request->EncryptedLength != request->Length)
						{
							// Up to three subfragments may be required to handle a partially remapped fragment
							int subFragment;
							byte *subFragmentData = request->Data;

							for (subFragment = 0 ; subFragment < 3; ++subFragment)
							{
								LARGE_INTEGER subFragmentOffset;
								ULONG subFragmentLength;
								subFragmentOffset.QuadPart = request->Offset.QuadPart;

								switch (subFragment)
								{
								case 0:
									subFragmentLength = (ULONG) request->EncryptedOffset;
									break;

								case 1:
									subFragmentOffset.QuadPart += request->EncryptedOffset + queue->RemappedAreaOffset;
									subFragmentLength = request->EncryptedLength;
									break;

								case 2:
									subFragmentOffset.QuadPart += request->EncryptedOffset + request->EncryptedLength;
									subFragmentLength = (ULONG) (request->Length - (request->EncryptedOffset + request->EncryptedLength));
									break;
								}

								if (subFragmentLength > 0)
								{
									if (request->Item->Write)
										request->Item->Status = TCWriteDevice (queue->LowerDeviceObject, subFragmentData, subFragmentOffset, subFragmentLength);
									else
										request->Item->Status = TCCachedRead (queue, NULL, subFragmentData, subFragmentOffset, subFragmentLength);

									subFragmentData += subFragmentLength;
								}
							}
						}
						else
						{
							// Remap the fragment
							LARGE_INTEGER remappedOffset;
							remappedOffset.QuadPart = request->Offset.QuadPart + queue->RemappedAreaOffset;

							if (request->Item->Write)
								request->Item->Status = TCWriteDevice (queue->LowerDeviceObject, request->Data, remappedOffset, request->Length);
							else
								request->Item->Status = TCCachedRead (queue, NULL, request->Data, remappedOffset, request->Length);
						}
					}
					else
					{
						if (request->Item->Write)
							request->Item->Status = TCWriteDevice (queue->LowerDeviceObject, request->Data, request->Offset, request->Length);
						else
							request->Item->Status = TCCachedRead (queue, NULL, request->Data, request->Offset, request->Length);
					}
				}
				else
				{
					IO_STATUS_BLOCK ioStatus;

					if (request->Item->Write)
						request->Item->Status = ZwWriteFile (queue->HostFileHandle, NULL, NULL, NULL, &ioStatus, request->Data, request->Length, &request->Offset, NULL);
					else
						request->Item->Status = TCCachedRead (queue, &ioStatus, request->Data, request->Offset, request->Length);

					if (NT_SUCCESS (request->Item->Status) && ioStatus.Information != request->Length)
						request->Item->Status = STATUS_END_OF_FILE;
				}
			}

			if (request->Item->Write)
			{
				queue->ReadAheadBufferValid = FALSE;

				ReleaseFragmentBuffer (queue, request->Data);

				if (request->CompleteOriginalIrp)
				{
					CompleteOriginalIrp (request->Item, request->Item->Status,
						NT_SUCCESS (request->Item->Status) ? request->Item->OriginalLength : 0);
				}

				ReleasePoolBuffer (queue, request);
			}
			else
			{
				BOOL readAhead = FALSE;

				if (NT_SUCCESS (request->Item->Status))
					memcpy (request->OrigDataBufferFragment, request->Data, request->Length);

				ReleaseFragmentBuffer (queue, request->Data);
				request->Data = request->OrigDataBufferFragment;

				if (request->CompleteOriginalIrp
					&& queue->LastReadLength > 0
					&& NT_SUCCESS (request->Item->Status)
					&& InterlockedExchangeAdd (&queue->IoThreadPendingRequestCount, 0) == 0)
				{
					readAhead = TRUE;
					InterlockedIncrement (&queue->OutstandingIoCount);
				}

				ExInterlockedInsertTailList (&queue->CompletionThreadQueue, &request->CompletionListEntry, &queue->CompletionThreadQueueLock);
				KeSetEvent (&queue->CompletionThreadQueueNotEmptyEvent, IO_DISK_INCREMENT, FALSE);

				if (readAhead)
				{
					queue->ReadAheadBufferValid = FALSE;
					queue->ReadAheadOffset.QuadPart = queue->LastReadOffset.QuadPart + queue->LastReadLength;
					queue->ReadAheadLength = queue->LastReadLength;

					if (queue->ReadAheadOffset.QuadPart + queue->ReadAheadLength <= queue->MaxReadAheadOffset.QuadPart)
					{
#ifdef TC_TRACE_IO_QUEUE
						Dump ("A   %I64d [%I64d] roff=%I64d rlen=%d\n", request->Item->OriginalIrpOffset.QuadPart, GetElapsedTime (&queue->LastPerformanceCounter), queue->ReadAheadOffset, queue->ReadAheadLength);
#endif
						if (queue->IsFilterDevice)
						{
							queue->ReadAheadBufferValid = NT_SUCCESS (TCReadDevice (queue->LowerDeviceObject, queue->ReadAheadBuffer, queue->ReadAheadOffset, queue->ReadAheadLength));
						}
						else
						{
							IO_STATUS_BLOCK ioStatus;
							queue->ReadAheadBufferValid = NT_SUCCESS (ZwReadFile (queue->HostFileHandle, NULL, NULL, NULL, &ioStatus, queue->ReadAheadBuffer, queue->ReadAheadLength, &queue->ReadAheadOffset, NULL));
							queue->ReadAheadLength = (ULONG) ioStatus.Information;
						}
					}

					DecrementOutstandingIoCount (queue);
				}
			}
		}
	}

	PsTerminateSystemThread (STATUS_SUCCESS);
}
コード例 #21
0
ファイル: kiinit.c プロジェクト: mutoso-mirrors/reactos
VOID
NTAPI
INIT_FUNCTION
KiInitializeKernel(IN PKPROCESS InitProcess,
                   IN PKTHREAD InitThread,
                   IN PVOID IdleStack,
                   IN PKPRCB Prcb,
                   IN CCHAR Number,
                   IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    BOOLEAN NpxPresent;
    ULONG FeatureBits;
    ULONG PageDirectory[2];
    PVOID DpcStack;
    ULONG Vendor[3];

    /* Detect and set the CPU Type */
    KiSetProcessorType();

    /* Check if an FPU is present */
    NpxPresent = KiIsNpxPresent();

    /* Initialize the Power Management Support for this PRCB */
    PoInitializePrcb(Prcb);

    /* Bugcheck if this is a 386 CPU */
    if (Prcb->CpuType == 3) KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x386, 0, 0, 0);

    /* Get the processor features for the CPU */
    FeatureBits = KiGetFeatureBits();

    /* Set the default NX policy (opt-in) */
    SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN;

    /* Check if NPX is always on */
    if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON"))
    {
        /* Set it always on */
        SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON;
        FeatureBits |= KF_NX_ENABLED;
    }
    else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT"))
    {
        /* Set it in opt-out mode */
        SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT;
        FeatureBits |= KF_NX_ENABLED;
    }
    else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) ||
             (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE")))
    {
        /* Set the feature bits */
        FeatureBits |= KF_NX_ENABLED;
    }
    else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) ||
             (strstr(KeLoaderBlock->LoadOptions, "EXECUTE")))
    {
        /* Set disabled mode */
        SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF;
        FeatureBits |= KF_NX_DISABLED;
    }

    /* Save feature bits */
    Prcb->FeatureBits = FeatureBits;

    /* Save CPU state */
    KiSaveProcessorControlState(&Prcb->ProcessorState);

    /* Get cache line information for this CPU */
    KiGetCacheInformation();

    /* Initialize spinlocks and DPC data */
    KiInitSpinLocks(Prcb, Number);

    /* Check if this is the Boot CPU */
    if (!Number)
    {
        /* Set Node Data */
        KeNodeBlock[0] = &KiNode0;
        Prcb->ParentNode = KeNodeBlock[0];
        KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;

        /* Set boot-level flags */
        KeI386NpxPresent = NpxPresent;
        KeI386CpuType = Prcb->CpuType;
        KeI386CpuStep = Prcb->CpuStep;
        KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
        KeProcessorLevel = (USHORT)Prcb->CpuType;
        if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
        KeFeatureBits = FeatureBits;
        KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
        KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? TRUE : FALSE;

        /* Detect 8-byte compare exchange support */
        if (!(KeFeatureBits & KF_CMPXCHG8B))
        {
            /* Copy the vendor string */
            RtlCopyMemory(Vendor, Prcb->VendorString, sizeof(Vendor));

            /* Bugcheck the system. Windows *requires* this */
            KeBugCheckEx(UNSUPPORTED_PROCESSOR,
                         (1 << 24 ) | (Prcb->CpuType << 16) | Prcb->CpuStep,
                         Vendor[0],
                         Vendor[1],
                         Vendor[2]);
        }

        /* Set the current MP Master KPRCB to the Boot PRCB */
        Prcb->MultiThreadSetMaster = Prcb;

        /* Lower to APC_LEVEL */
        KeLowerIrql(APC_LEVEL);

        /* Initialize some spinlocks */
        KeInitializeSpinLock(&KiFreezeExecutionLock);
        KeInitializeSpinLock(&Ki486CompatibilityLock);

        /* Initialize portable parts of the OS */
        KiInitSystem();

        /* Initialize the Idle Process and the Process Listhead */
        InitializeListHead(&KiProcessListHead);
        PageDirectory[0] = 0;
        PageDirectory[1] = 0;
        KeInitializeProcess(InitProcess,
                            0,
                            0xFFFFFFFF,
                            PageDirectory,
                            FALSE);
        InitProcess->QuantumReset = MAXCHAR;
    }
    else
    {
        /* FIXME */
        DPRINT1("SMP Boot support not yet present\n");
    }

    /* Setup the Idle Thread */
    KeInitializeThread(InitProcess,
                       InitThread,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       IdleStack);
    InitThread->NextProcessor = Number;
    InitThread->Priority = HIGH_PRIORITY;
    InitThread->State = Running;
    InitThread->Affinity = 1 << Number;
    InitThread->WaitIrql = DISPATCH_LEVEL;
    InitProcess->ActiveProcessors = 1 << Number;

    /* HACK for MmUpdatePageDir */
    ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;

    /* Set basic CPU Features that user mode can read */
    SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
        (KeFeatureBits & KF_MMX) ? TRUE: FALSE;
    SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
        (KeFeatureBits & KF_CMPXCHG8B) ? TRUE: FALSE;
    SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
        ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI)) ? TRUE: FALSE;
    SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
        ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI64)) ? TRUE: FALSE;
    SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
        (KeFeatureBits & KF_3DNOW) ? TRUE: FALSE;
    SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
        (KeFeatureBits & KF_RDTSC) ? TRUE: FALSE;

    /* Set up the thread-related fields in the PRCB */
    Prcb->CurrentThread = InitThread;
    Prcb->NextThread = NULL;
    Prcb->IdleThread = InitThread;

    /* Initialize the Kernel Executive */
    ExpInitializeExecutive(Number, LoaderBlock);

    /* Only do this on the boot CPU */
    if (!Number)
    {
        /* Calculate the time reciprocal */
        KiTimeIncrementReciprocal =
            KiComputeReciprocal(KeMaximumIncrement,
                                &KiTimeIncrementShiftCount);

        /* Update DPC Values in case they got updated by the executive */
        Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
        Prcb->MinimumDpcRate = KiMinimumDpcRate;
        Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;

        /* Allocate the DPC Stack */
        DpcStack = MmCreateKernelStack(FALSE, 0);
        if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
        Prcb->DpcStack = DpcStack;

        /* Allocate the IOPM save area. */
        Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
                                                  PAGE_SIZE * 2,
                                                  '  eK');
        if (!Ki386IopmSaveArea)
        {
            /* Bugcheck. We need this for V86/VDM support. */
            KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0);
        }
    }

    /* Raise to Dispatch */
    KfRaiseIrql(DISPATCH_LEVEL);

    /* Set the Idle Priority to 0. This will jump into Phase 1 */
    KeSetPriorityThread(InitThread, 0);

    /* If there's no thread scheduled, put this CPU in the Idle summary */
    KiAcquirePrcbLock(Prcb);
    if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
    KiReleasePrcbLock(Prcb);

    /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
    KfRaiseIrql(HIGH_LEVEL);
    LoaderBlock->Prcb = 0;
}
コード例 #22
0
ファイル: zeropage.c プロジェクト: GYGit/reactos
VOID
NTAPI
MmZeroPageThread(VOID)
{
    PKTHREAD Thread = KeGetCurrentThread();
    PVOID StartAddress, EndAddress;
    PVOID WaitObjects[2];
    KIRQL OldIrql;
    PVOID ZeroAddress;
    PFN_NUMBER PageIndex, FreePage;
    PMMPFN Pfn1;

    /* Get the discardable sections to free them */
    MiFindInitializationCode(&StartAddress, &EndAddress);
    if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
    DPRINT("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);

    /* Set our priority to 0 */
    Thread->BasePriority = 0;
    KeSetPriorityThread(Thread, 0);

    /* Setup the wait objects */
    WaitObjects[0] = &MmZeroingPageEvent;
//    WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer

    while (TRUE)
    {
        KeWaitForMultipleObjects(1, // 2
                                 WaitObjects,
                                 WaitAny,
                                 WrFreePage,
                                 KernelMode,
                                 FALSE,
                                 NULL,
                                 NULL);
        OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
        while (TRUE)
        {
            if (!MmFreePageListHead.Total)
            {
                MmZeroingPageThreadActive = FALSE;
                KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
                break;
            }

            PageIndex = MmFreePageListHead.Flink;
            ASSERT(PageIndex != LIST_HEAD);
            Pfn1 = MiGetPfnEntry(PageIndex);
            MI_SET_USAGE(MI_USAGE_ZERO_LOOP);
            MI_SET_PROCESS2("Kernel 0 Loop");
            FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));

            /* The first global free page should also be the first on its own list */
            if (FreePage != PageIndex)
            {
                KeBugCheckEx(PFN_LIST_CORRUPT,
                             0x8F,
                             FreePage,
                             PageIndex,
                             0);
            }

            Pfn1->u1.Flink = LIST_HEAD;
            KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);

            ZeroAddress = MiMapPagesInZeroSpace(Pfn1, 1);
            ASSERT(ZeroAddress);
            RtlZeroMemory(ZeroAddress, PAGE_SIZE);
            MiUnmapPagesInZeroSpace(ZeroAddress, 1);

            OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);

            MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
        }
    }
}
コード例 #23
0
ファイル: Packet.c プロジェクト: jiangxilong/TDI
void DebugPrintSystemThread(IN PVOID Context)
{
	UNICODE_STRING DebugPrintName;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatus;
	HANDLE DebugPrintDeviceHandle;
	LARGE_INTEGER OneSecondTimeout;
	PDEBUGPRINT_EVENT pEvent;
	PLIST_ENTRY pListEntry;
	ULONG EventDataLen;
	NTSTATUS status;
	//LARGE_INTEGER ByteOffset;

	KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY);

	//创建文件
	
	RtlInitUnicodeString(&DebugPrintName,L"\\Device\\PHDDebugPrint");
	
	InitializeObjectAttributes(&ObjectAttributes,&DebugPrintName,OBJ_CASE_INSENSITIVE,NULL,NULL);
	
	DebugPrintDeviceHandle=NULL;
	status=ZwCreateFile(&DebugPrintDeviceHandle,
		GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
		&ObjectAttributes,
		&IoStatus,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);
	if(!NT_SUCCESS(status)||DebugPrintDeviceHandle==NULL)
		goto exit1;

	//线程主循环代码,写文件

	DBGPRINT(("XIAN CHENG KAI SHI"));
	
	OneSecondTimeout.QuadPart=-1i64*1000000i64;

	DebugPrintStarted=TRUE;

	while(TRUE)
	{
		KeWaitForSingleObject(&ThreadEvent,Executive,KernelMode,FALSE,&OneSecondTimeout);
		
		while(TRUE)
		{
			pListEntry=ExInterlockedRemoveHeadList(&EventList,&EventListLock);
			if(pListEntry==NULL)
			{
				//DBGPRINT(("WOKAOHAIMEILIANSHANG"));
				break;
			}
			else
			{
				DBGPRINT(("YOU QING KUANG"));
			}

			pEvent=
				CONTAINING_RECORD(pListEntry,DEBUGPRINT_EVENT,ListEntry);
			EventDataLen=pEvent->Len;

			status=ZwWriteFile(DebugPrintDeviceHandle,NULL,NULL,NULL,
				&IoStatus,pEvent->EventData,EventDataLen,NULL,NULL);

			if(!NT_SUCCESS(status))
			{
				DBGPRINT("MEI FA XIE A");
			}
			else
			{
				DBGPRINT("WO XIE!");
			}
			ExFreePool(pEvent);
		}

	if(ExitNow)
		break;
	}
exit1:
	if(ThreadObjectPointer!=NULL)
	{
		ObDereferenceObject(&ThreadObjectPointer);
		ThreadObjectPointer=NULL;
	}

	/////////////////////////////////////
	//有待商榷
	DebugPrintStarted=FALSE;
	
	ZwClose(DebugPrintDeviceHandle);
	/////////////////////////////////////

	KeSetEvent(&ThreadExiting,0,FALSE);
	
	PsTerminateSystemThread(STATUS_SUCCESS);	
}
コード例 #24
0
ファイル: DPMain.c プロジェクト: jinyongjie/jyj_github
VOID
DPReadWriteThread (
	IN PVOID Context
	)
{
	//NTSTATUS类型的函数返回值
	NTSTATUS					ntStatus = STATUS_SUCCESS;
	//用来指向过滤设备的设备扩展的指针
	PDP_FILTER_DEV_EXTENSION	DevExt = (PDP_FILTER_DEV_EXTENSION)Context;
	//请求队列的入口
	PLIST_ENTRY			ReqEntry = NULL;
	//irp指针
	PIRP				Irp = NULL;
	//irp stack指针
	PIO_STACK_LOCATION	Irpsp = NULL;
	//irp中包括的数据地址
	PBYTE				sysBuf = NULL;
	//irp中的数据长度
	ULONG				length = 0;
	//irp要处理的偏移量
	LARGE_INTEGER		offset = { 0 };
	//文件缓冲指针
	PBYTE				fileBuf = NULL;
	//设备缓冲指针
	PBYTE				devBuf = NULL;
	//io操作状态
	IO_STATUS_BLOCK		ios;

	//设置这个线程的优先级
	KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
	//下面是线程的实现部分,这个循环永不退出
	for (;;)
	{	
		//先等待请求队列同步事件,如果队列中没有irp需要处理,我们的线程就等待在这里,让出cpu时间给其它线程
		KeWaitForSingleObject(
			&DevExt->ReqEvent,
			Executive,
			KernelMode,
			FALSE,
			NULL
			);
		//如果有了线程结束标志,那么就在线程内部自己结束自己
		if (DevExt->ThreadTermFlag)
		{
			//这是线程的唯一退出地点
			PsTerminateSystemThread(STATUS_SUCCESS);
			return;
		}
		//从请求队列的首部拿出一个请求来准备处理,这里使用了自旋锁机制,所以不会有冲突
		while (ReqEntry = ExInterlockedRemoveHeadList(
			&DevExt->ReqList,
			&DevExt->ReqLock
			))
		{
			//从队列的入口里找到实际的irp的地址
			Irp = CONTAINING_RECORD(ReqEntry, IRP, Tail.Overlay.ListEntry);
			//取得irp stack
			Irpsp = IoGetCurrentIrpStackLocation(Irp);
			//获取这个irp其中包含的缓存地址,这个地址可能来自mdl,也可能就是直接的缓冲,这取决于我们当前设备的io方式是buffer还是direct方式
			if (NULL == Irp->MdlAddress)
				sysBuf = (PBYTE)Irp->UserBuffer;
			else
				sysBuf = (PBYTE)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

			if (IRP_MJ_READ == Irpsp->MajorFunction)
			{
				//如果是读的irp请求,我们在irp stack中取得相应的参数作为offset和length
				offset = Irpsp->Parameters.Read.ByteOffset;
				length = Irpsp->Parameters.Read.Length;
			}
			else if (IRP_MJ_WRITE == Irpsp->MajorFunction)
			{
				//如果是写的irp请求,我们在irp stack中取得相应的参数作为offset和length
				offset = Irpsp->Parameters.Write.ByteOffset;
				length = Irpsp->Parameters.Write.Length;
			}
			else
			{
				//除此之外,offset和length都是0
				offset.QuadPart = 0;
				length = 0;
			}
			if (NULL == sysBuf || 0 == length)
			{
				//如果传下来的irp没有系统缓冲或者缓冲的长度是0,那么我们就没有必要处理这个irp,直接下发给下层设备就行了
				goto ERRNEXT;
			}
			//下面是转储的过程了
			if (IRP_MJ_READ == Irpsp->MajorFunction)
			{
				//这里是读的处理
				//首先根据bitmap来判断这次读操作读取的范围是全部为转储空间,还是全部为未转储空间,或者兼而有之
				long tstResult = DPBitmapTest(DevExt->Bitmap, offset, length);
				switch (tstResult)
				{
				case BITMAP_RANGE_CLEAR: 
					//这说明这次读取的操作全部是读取未转储的空间,也就是真正的磁盘上的内容,我们直接发给下层设备去处理
					goto ERRNEXT;
				case BITMAP_RANGE_SET: 
					//这说明这次读取的操作全部是读取已经转储的空间,也就是缓冲文件上的内容,我们从文件中读取出来,然后直接完成这个irp
					//分配一个缓冲区用来从缓冲文件中读取
					if (NULL == (fileBuf = (PBYTE)ExAllocatePoolWithTag(NonPagedPool, length, 'xypD')))
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					RtlZeroMemory(fileBuf,length);
					ntStatus = ZwReadFile(
						DevExt->TempFile,
						NULL,
						NULL,
						NULL,
						&ios,
						fileBuf,
						length,
						&offset,
						NULL);
					if (NT_SUCCESS(ntStatus))
					{
						Irp->IoStatus.Information = length;
						RtlCopyMemory(sysBuf,fileBuf,Irp->IoStatus.Information);
						goto ERRCMPLT;
					}
					else
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					break;

				case BITMAP_RANGE_BLEND:
					//这说明这次读取的操作是混合的,我们也需要从下层设备中读出,同时从文件中读出,然后混合并返回
					//分配一个缓冲区用来从缓冲文件中读取
					if (NULL == (fileBuf = (PBYTE)ExAllocatePoolWithTag(NonPagedPool, length, 'xypD')))
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					RtlZeroMemory(fileBuf,length);
					//分配一个缓冲区用来从下层设备中读取
					if (NULL == (devBuf = (PBYTE)ExAllocatePoolWithTag(NonPagedPool, length, 'xypD')))
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					RtlZeroMemory(devBuf,length);
					ntStatus = ZwReadFile(
						DevExt->TempFile,
						NULL,
						NULL,
						NULL,
						&ios,
						fileBuf,
						length,
						&offset,
						NULL);
					if (!NT_SUCCESS(ntStatus))
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					//把这个irp发给下层设备去获取需要从设备上读取的信息
					ntStatus = DPForwardIrpSync(DevExt->LowerDevObj,Irp);
					if (!NT_SUCCESS(ntStatus))
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					//将从下层设备获取到的数据存储到devBuf中
					memcpy(devBuf, sysBuf, Irp->IoStatus.Information);
					//把从文件获取到的数据和从设备获取到的数据根据相应的bitmap值来进行合并,合并的结果放在devBuf中
					ntStatus = DPBitmapGet(
						DevExt->Bitmap,
						offset,
						length,
						devBuf,
						fileBuf
						);
					if (!NT_SUCCESS(ntStatus))
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						Irp->IoStatus.Information = 0;
						goto ERRERR;
					}
					//把合并完的数据存入系统缓冲并完成irp
					memcpy(sysBuf, devBuf, Irp->IoStatus.Information);
					goto ERRCMPLT;
				default:
					ntStatus = STATUS_INSUFFICIENT_RESOURCES;
					goto ERRERR;
				}
			}
			else
			{
				//这里是写的过程
				//对于写,我们直接写缓冲文件,而不会写磁盘数据,这就是所谓的转储,但是转储之后需要在bitmap中做相应的标记
				ntStatus = ZwWriteFile(
					DevExt->TempFile,
					NULL,
					NULL,
					NULL,
					&ios,
					sysBuf,
					length,
					&offset,
					NULL);
				if(!NT_SUCCESS(ntStatus))
				{
					ntStatus = STATUS_INSUFFICIENT_RESOURCES;
					goto ERRERR;
				}
				else
				{
					if (NT_SUCCESS(ntStatus = DPBitmapSet(DevExt->Bitmap, offset, length)))
					{
						goto ERRCMPLT;
					}
					else
					{
						ntStatus = STATUS_INSUFFICIENT_RESOURCES;
						goto ERRERR;
					}
				}
			}
ERRERR:
			if (NULL != fileBuf)
			{
				ExFreePool(fileBuf);
				fileBuf = NULL;
			}
			if (NULL != devBuf)
			{
				ExFreePool(devBuf);
				devBuf = NULL;
			}
			DPCompleteRequest(
				Irp,
				ntStatus,
				IO_NO_INCREMENT
				);
			continue;
ERRNEXT:
			if (NULL != fileBuf)
			{
				ExFreePool(fileBuf);
				fileBuf = NULL;
			}
			if (NULL != devBuf)
			{
				ExFreePool(devBuf);
				devBuf = NULL;
			}	
			DPSendToNextDriver(
				DevExt->LowerDevObj,
				Irp);
			continue;
ERRCMPLT:
			if (NULL != fileBuf)
			{
				ExFreePool(fileBuf);
				fileBuf = NULL;
			}
			if (NULL != devBuf)
			{
				ExFreePool(devBuf);
				devBuf = NULL;
			}
			DPCompleteRequest(
				Irp,
				STATUS_SUCCESS,
				IO_DISK_INCREMENT
				);
			continue;
			
		}
	}

}
コード例 #25
-1
ファイル: stackovf.c プロジェクト: hoangduit/reactos
/*
 * @implemented
 */
VOID
NTAPI
FsRtlWorkerThread(IN PVOID StartContext)
{
    KIRQL Irql;
    PLIST_ENTRY Entry;
    PWORK_QUEUE_ITEM WorkItem;
    ULONG QueueId = (ULONG)StartContext;

    /* Set our priority according to the queue we're dealing with */
    KeSetPriorityThread(&PsGetCurrentThread()->Tcb, LOW_REALTIME_PRIORITY + QueueId);

    /* Loop for events */
    for (;;)
    {
        /* Look for next event */
        Entry = KeRemoveQueue(&FsRtlWorkerQueues[QueueId], KernelMode, NULL);
        WorkItem = CONTAINING_RECORD(Entry, WORK_QUEUE_ITEM, List);

        /* Call its routine (here: FsRtlStackOverflowRead) */
        WorkItem->WorkerRoutine(WorkItem->Parameter);

        /* Check we're still at passive level or bugcheck */
        Irql = KeGetCurrentIrql();
        if (Irql != PASSIVE_LEVEL)
        {
            KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL, (ULONG_PTR)WorkItem->WorkerRoutine,   
                         (ULONG_PTR)Irql, (ULONG_PTR)WorkItem->WorkerRoutine,
                         (ULONG_PTR)WorkItem);
        }
    }
}