Delphi研究之驱动开发篇(七)--利用共享内存与用户模式程序通讯(上)
作 者: mickeylan
时 间: 2008-06-16,11:33
链 接: http://bbs.pediy.com/showthread.php?t=66661上篇教程我们学习了通过Section在用户进程和内核驱动程序之间共享信息的方法,但是这种方法有一个缺点,就是驱动程序被硬性限制在具体进程的地址上下文中,即驱动程序所使用的虚拟地址位于此进程的地址空间中。我们在本例中使用的方法将没有这个缺点。对于驱动程序来说,这种方法更为自然些。
首先来看看驱动程序。代码:unit SharingMemory;
inte易做图ce
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:[
补充:软件开发 , Delphi ,