程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi研究之驅動開發篇(七)--利用共享內存與用戶模式程序通訊(上)

Delphi研究之驅動開發篇(七)--利用共享內存與用戶模式程序通訊(上)

編輯:Delphi

作 者: mickeylan
時 間: 2008-06-16,11:33
鏈 接: http://bbs.pediy.com/showthread.php?t=66661

上篇教程我們學習了通過Section在用戶進程和內核驅動程序之間共享信息的方法,但是這種方法有一個缺點,就是驅動程序被硬性限制在具體進程的地址上下文中,即驅動程序所使用的虛擬地址位於此進程的地址空間中。我們在本例中使用的方法將沒有這個缺點。對於驅動程序來說,這種方法更為自然些。
首先來看看驅動程序。

代碼:unit SharingMemory;

interface

uses
     nt_status, ntoskrnl, native, winioctl, fcall, macros;

function _DriverEntry(pDriverObject:PDRIVER_OBJECT; pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;

implementation

uses
     seh;

var
     g_pSharedMemory: PVOID;
     g_pMdl: PVOID;
     g_pUserAddress: PVOID;
     g_fTimerStarted: boolean;
     g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;

{更新系統時間到共享內存}
procedure UpdateTime; stdcall;
var
     SysTime:LARGE_INTEGER;
begin
     KeQuerySystemTime(@SysTime);
     ExSystemTimeToLocalTime(@SysTime, g_pSharedMemory);
end;

procedure TimerRoutine(pDeviceObject:PDEVICE_OBJECT; pContext:PVOID); stdcall;
begin
     UpdateTime;
end;

{清理過程--釋放資源}
procedure Cleanup(pDeviceObject:PDEVICE_OBJECT); stdcall;
begin
     if g_fTimerStarted then
     begin
       IoStopTimer(pDeviceObject);
       DbgPrint(SharingMemory: Timer stopped#13#10);
     end;

     if (g_pUserAddress <> nil) and (g_pMdl <> nil) then
     begin
       MmUnmapLockedPages(g_pUserAddress, g_pMdl);
       DbgPrint(SharingMemory: Memory at address %08X unmapped#13#10,
                g_pUserAddress);
       g_pUserAddress := nil;
     end;

     if g_pMdl <> nil then
     begin
       IoFreeMdl(g_pMdl);
       DbgPrint(SharingMemory: MDL at address %08X freed#13#10,
                g_pMdl);
       g_pMdl := nil;
     end;

     if g_pSharedMemory <> nil then
     begin
       ExFreePool(g_pSharedMemory);
       DbgPrint(SharingMemory: Memory at address %08X released#13#10,
                g_pSharedMemory);
       g_pSharedMemory := nil;
     end;
end;

function DispatchCleanup(pDeviceObject:PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
begin
     DbgPrint(#13#10SharingMemory: Entering DispatchCleanup#13#10);
     Cleanup(pDeviceObject);

     p_Irp^.IoStatus.Status := STATUS_SUCCESS;
     p_Irp^.IoStatus.Information := 0;
     IofCompleteRequest(p_Irp, IO_NO_INCREMENT);

     DbgPrint(SharingMemory: Leaving DispatchCleanup#13#10);
     result := STATUS_SUCCESS;
end;

function DispatchCreateClose(p_DeviceObject:PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
begin
     p_Irp^.IoStatus.Status := STATUS_SUCCESS;
     p_Irp^.IoStatus.Information := 0;

     IofCompleteRequest(p_Irp, IO_NO_INCREMENT);

     result := STATUS_SUCCESS;
end;

function DispatchControl(p_DeviceObject: PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
label
     SafePlace;
var
     dwContext:DWORD;
     psl:PIO_STACK_LOCATION;
     IOCTL_GIVE_ME_YOUR_MEMORY: DWORD;
     pSystemBuffer: PVOID;
begin
     DbgPrint(#13#10SharingMemory: Entering DispatchControl#13#10);
     IOCTL_GIVE_ME_YOUR_MEMORY := CTL_CODE(FILE_DEVICE_UNKNOWN,
                                           $800, METHOD_BUFFERED,
                                           FILE_READ_ACCESS);
     p_Irp^.IoStatus.Status := STATUS_UNSUCCESSFUL;
     p_Irp^.IoStatus.Information := 0;
     psl := IoGetCurrentIrpStackLocation(p_Irp); {取IRP的stack location的指針}
     if psl^.Parameters.DeviceIoControl.IoControlCode = IOCTL_GIVE_ME_YOUR_MEMORY then
     begin
       {是我們控制碼就開始處理}
       if psl^.Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PVOID) then
       begin
         g_pSharedMemory := ExAllocatePool(NonPagedPool, PAGE_SIZE);
         if g_pSharedMemory <> nil then
         begin
           DbgPrint(SharingMemory: %X bytes of nonpaged memory allocated at address %08X#13#10,
                    PAGE_SIZE, g_pSharedMemory);
           g_pMdl := IoAllocateMdl(g_pSharedMemory, PAGE_SIZE,
                                   false, false, nil);
           if g_pMdl <> nil then
           begin
             DbgPrint(SharingMemory: MDL allocated at address %08X#13#10,
                      g_pMdl);
             MmBuildMdlForNonPagedPool(g_pMdl);
             {安裝SEH}
             asm
               push offset DefaultExceptionHandler
               push fs:[0]
               mov fs:[

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved