首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows 核心編程:使用 DPC 與 WorkItem 實現定時寫入文件

     編輯:關於C語言

背景問題

在 DISPATCH_LEVEL (DPC) 無法直接調用文件 I/O 函數(需 PASSIVE_LEVEL),否則導致 IRQL_NOT_LESS_OR_EQUAL 藍屏。

解決架構

  1. 系統線程:創建一個系統線程,初始化 KTIMER 與 KDPC。
  2. DPC 例程:到期時在 DISPATCH_LEVEL 運行,僅負責分配 IO_WORKITEM 並 IoQueueWorkItem 入隊。
  3. WorkItem 例程:在 PASSIVE_LEVEL 執行,安全調用 ZwCreateFile/ZwWriteFile 寫入日誌。
  4. 循環定時:WorkItem 完成後,DPC 重新設置定時器,實現周期性寫入。

關鍵代碼片段

// 系統線程啟動
VOID ThreadStart(PVOID ctx) {
    KeInitializeTimer(&Timer);
    KeInitializeDpc(&Dpc, CustomDpc, myInfo);
    KeSetTimer(&Timer, DueTime, &Dpc);
    KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, NULL);
}

// DPC 例程(DISPATCH_LEVEL)
VOID CustomDpc(KDPC*, PVOID ctx, PVOID, PVOID) {
    pIoWorkItem = IoAllocateWorkItem(DeviceObject);
    if (pIoWorkItem)
        IoQueueWorkItem(pIoWorkItem, TestFile, DelayedWorkQueue, ctx);
    KeSetTimer(&Timer, DueTime, &Dpc); // 重新定時
}

// WorkItem 例程(PASSIVE_LEVEL)
VOID TestFile(PDEVICE_OBJECT, PVOID ctx) {
    // 獲取時間、打開文件、寫入、關閉
    ZwCreateFile(...);
    ZwWriteFile(...);
    ZwClose(hFile);
}

清理

VOID Unload(PDRIVER_OBJECT drv) {
    KeCancelTimer(&Timer);
    IoFreeWorkItem(pIoWorkItem);
    IoDeleteDevice(drv->DeviceObject);
}

優勢

  • 嚴格遵守 IRQL 規則,避免藍屏。
  • WorkItem 自動在系統工作隊列執行,無需自建線程。
  • 代碼結構清晰,易於維護擴展。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved