上次轉載的一片博客已經介紹了驅動層主動發送數據給應用層的方法,下面介紹的一種方法有點差異之處,上次的是在應用層創建事件對象,在驅動層創建MDL(內存描述符)來實現同步通信,而這次則是在應用層創建虛擬內存,驅動程序將虛擬地址轉換成物理地址,然後再轉成驅動程序能訪問的虛擬地址,同樣能達到內存共享的目的。
驅動層部分代碼
switch (ioControlCode)
{
case 2001: //傳入共享內存
{
buff = (UCHAR *)Irp->AssociatedIrp.SystemBuffer ;
memmove(&a,&buff[4],4);
output=(char*)MmMapIoSpace(MmGetPhysicalAddress((void*)a),256,0);
break;
}
case 2002: //獲取信號燈
{
buff = (UCHAR *)Irp->AssociatedIrp.SystemBuffer ;
memmove(&Appevent,&buff[0],4);
memmove(&Sysevent,&buff[4],4);
ObReferenceObjectByHandle(Appevent,GENERIC_ALL,NULL,KernelMode,&AppeventObject,NULL);
ObReferenceObjectByHandle(Sysevent,GENERIC_ALL,NULL,KernelMode,&SyseventObject,NULL);
break;
}
...
}
以上是應用層通過相應控制碼傳入事件和共享內存,接下來驅動層要主動放鬆內容給應用層
memmove(&output[0],&a,4);
KeSetEvent((PRKEVENT)AppeventObject,0,0);
KeWaitForSingleObject((PRKEVENT)SyseventObject,Executive,KernelMode,0,0);
KeResetEvent((PRKEVENT)SyseventObject);
memmove(&a,&output[4],4);