阅读:2444回复:7
驱动程序如何主动与应用程序通信?
1、驱动程序如何主动与应用程序通信?
2、IRP包如何传递自己的数据? 3、IPHeader里,IP address 如何表示?我想比较两个地址是否一致。 很初级的三个问题,请各位指点。 |
|
最新喜欢:baoyib... |
沙发#
发布于:2003-06-16 21:06
1.通讯
在NDIS IMD中用NdisMRegisterDevice,注册一个设备。然后可以通过 DeviceIoControl和应用层通讯 2。当你在APP调用API比如CreateFile ,等等时系统将你的请求转化为IRP转入KENEL中 3。IP地址是个无符号的长整形。ULONG IP都的定义如下: /*the internet paket header */ typedef struct{ u_char vandhl; /*contain the version and the internet packet header length*/ u_char tos; /* type of server */ u_short iplen; /* the internet length=internet header length+data */ u_short id; /* datagram id use to caption the only datagram */ u_short flags; /*commonly is zero */ u_char ttl; /* time to live */ u_char ipp; /* the next pocotol is udp or tcp */ u_short cksum; /* Internet header checksum */ u_long saddr; /* the source ip address */ u_long daddr; /* detination addresss */ }iphdr; /////////////////////////////////////////////////////////// w2k下的PassThru和用户态交互修改说明 一.参考资料为winXP DDK下的PassThru。如果熟悉的话就不要浪费时间看我的修改过程(太简陋了,怕大家笑话),很容易搞定的。 二.内核态的修改过程: 1.在Passthru.c中增加如下的变量定义 #define LINKNAME_STRING L\"\\\\DosDevices\\\\Passthru\" #define NTDEVICE_STRING L\"\\\\Device\\\\Passthru\" NDIS_HANDLE NdisDeviceHandle = NULL; PDEVICE_OBJECT ControlDeviceObject = NULL; enum _DEVICE_STATE { PS_DEVICE_STATE_READY = 0, // ready for create/delete PS_DEVICE_STATE_CREATING, // create operation in progress PS_DEVICE_STATE_DELETING // delete operation in progress } ControlDeviceState = PS_DEVICE_STATE_READY; /////////////////////////////////////////////////////////////////////////////////////// 2.在Passthru.c增加如下函数 NDIS_STATUS PtRegisterDevice( VOID ) /*++ Routine Description: Register an ioctl interface - a device object to be used for this purpose is created by NDIS when we call NdisMRegisterDevice. This routine is called whenever a new miniport instance is initialized. However, we only create one global device object, when the first miniport instance is initialized. This routine handles potential race conditions with PtDeregisterDevice via the ControlDeviceState and MiniportCount variables. NOTE: do not call this from DriverEntry; it will prevent the driver from being unloaded (e.g. on uninstall). Arguments: None Return Value: NDIS_STATUS_SUCCESS if we successfully register a device object. --*/ { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; UNICODE_STRING DeviceName; UNICODE_STRING DeviceLinkUnicodeString; PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION]; UINT i; DBGPRINT((\"==>PtRegisterDevice\\n\")); NdisAcquireSpinLock(&GlobalLock); ++MiniportCount; if (1 == MiniportCount) { ASSERT(ControlDeviceState != PS_DEVICE_STATE_CREATING); // // Another thread could be running PtDeregisterDevice on // behalf of another miniport instance. If so, wait for // it to exit. // while (ControlDeviceState != PS_DEVICE_STATE_READY) { NdisReleaseSpinLock(&GlobalLock); NdisMSleep(1); NdisAcquireSpinLock(&GlobalLock); } ControlDeviceState = PS_DEVICE_STATE_CREATING; NdisReleaseSpinLock(&GlobalLock); for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { DispatchTable = PtDispatch; } NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING); NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING); // // Create a device object and register our dispatch handlers // Status = NdisMRegisterDevice( NdisWrapperHandle, &DeviceName, &DeviceLinkUnicodeString, &DispatchTable[0], &ControlDeviceObject, &NdisDeviceHandle ); NdisAcquireSpinLock(&GlobalLock); ControlDeviceState = PS_DEVICE_STATE_READY; } NdisReleaseSpinLock(&GlobalLock); //DBGPRINT((\"<==PtRegisterDevice: %x\\n\", Status)); DBGPRINT(\"<==PtRegisterDevice\"); return (Status); } NTSTATUS PtDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: Process IRPs sent to this device. Arguments: DeviceObject - pointer to a device object Irp - pointer to an I/O Request Packet Return Value: NTSTATUS - STATUS_SUCCESS always - change this when adding real code to handle ioctls. --*/ { PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_SUCCESS; DBGPRINT((\"==>Pt Dispatch\\n\")); irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: break; case IRP_MJ_CLOSE: break; case IRP_MJ_DEVICE_CONTROL: // // Add code here to handle ioctl commands sent to passthru. // break; default: break; } Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); DBGPRINT((\"<== Pt Dispatch\\n\")); return status; } NDIS_STATUS PtDeregisterDevice( VOID ) /*++ Routine Description: Deregister the ioctl interface. This is called whenever a miniport instance is halted. When the last miniport instance is halted, we request NDIS to delete the device object Arguments: NdisDeviceHandle - Handle returned by NdisMRegisterDevice Return Value: NDIS_STATUS_SUCCESS if everything worked ok --*/ { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; DBGPRINT((\"==>PassthruDeregisterDevice\\n\")); NdisAcquireSpinLock(&GlobalLock); ASSERT(MiniportCount > 0); --MiniportCount; if (0 == MiniportCount) { // // All miniport instances have been halted. Deregister // the control device. // ASSERT(ControlDeviceState == PS_DEVICE_STATE_READY); // // Block PtRegisterDevice() while we release the control // device lock and deregister the device. // ControlDeviceState = PS_DEVICE_STATE_DELETING; NdisReleaseSpinLock(&GlobalLock); if (NdisDeviceHandle != NULL) { Status = NdisMDeregisterDevice(NdisDeviceHandle); NdisDeviceHandle = NULL; } NdisAcquireSpinLock(&GlobalLock); ControlDeviceState = PS_DEVICE_STATE_READY; } NdisReleaseSpinLock(&GlobalLock); //DBGPRINT((\"<== PassthruDeregisterDevice: %x\\n\", Status)); DBGPRINT(\"<== PassthruDeregisterDevice\"); return Status; } VOID PtUnloadProtocol( VOID ) { NDIS_STATUS Status; if (ProtHandle != NULL) { NdisDeregisterProtocol(&Status, ProtHandle); ProtHandle = NULL; } DBGPRINT((\"PtUnloadProtocol: done!\\n\")); } /////////////////////////////////////////////////////////////////////////////////////// 3.在passthru.h文件中增加上述函数的声明 NTSTATUS PtDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NDIS_STATUS PtRegisterDevice( VOID ); NDIS_STATUS PtDeregisterDevice( VOID ); VOID PtUnloadProtocol( VOID ); ///////////////////////////////////////////////////////////////////////////////////// 4.在precomp.h文件的第一行增加如下定义 #define NDIS_WDM 1 ///////////////////////////////////////////////////////////////////////////////////// 5.把passthru.c文件中的函数DriverEntry中的PChars.UnloadHandler = NULL;改为 PChars.UnloadHandler = PtUnloadProtocol; ///////////////////////////////////////////////////////////////////////////////////// 6.在miniport.h文件中的函数MPInitialize的代码:Status = NDIS_STATUS_SUCCESS;前增加 // // Create an ioctl interface // (VOID)PtRegisterDevice(); ///////////////////////////////////////////////////////////////////////////////////// 7.在miniport.h文件中的函数MPHalt的代码:if (pAdapt->BindingHandle != NULL)前增加 NdisReleaseSpinLock(&GlobalLock); // // Delete the ioctl interface that was created when the miniport // was created. // (VOID)PtDeregisterDevice(); ///////////////////////////////////////////////////////////////////////////////////// 8.把protocol.c文件中的函数PtUnload的内容改为如下: DBGPRINT((\"PtUnload: entered\\n\")); PtUnloadProtocol(); DBGPRINT((\"PtUnload: done!\\n\")); ///////////////////////////////////////////////////////////////////////////////////// 9.把passthru.c文件中的函数DriverEntry的变量定义的后面加上如下代码: NdisAllocateSpinLock(&GlobalLock); ///////////////////////////////////////////////////////////////////////////////////// 10.修改完毕后编译装载并重起机器就可以了. 三.用户态的代码很简单如下: #include \"stdafx.h\" #include <windows.h> #include <stdio.h> int main(int argc, char* argv[]) { HANDLE hdevice = CreateFile(\"\\\\\\\\.\\\\Passthru\", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hdevice == INVALID_HANDLE_VALUE) { printf(\"Unable to open PassThru device - error %d\\n\", GetLastError()); return 1; } CloseHandle(hdevice); return 0; } 运行用户态程序,用DebugView就可以看到内核态和用户态的交互情况。 祝你好运! |
|
|
板凳#
发布于:2003-06-16 22:03
真是很大方,谢了!
|
|
|
地板#
发布于:2003-06-16 22:28
真是很大方,谢了! 学习雷锋好榜样! 乐于助人快乐! |
|
|
地下室#
发布于:2003-06-17 10:50
太感谢了,一定仔细拜读。
|
|
5楼#
发布于:2003-06-17 15:58
他好像强调了主动吧?楼上的代码应该只能被动通信
谁有主动通信的代码,我也想看看 |
|
6楼#
发布于:2003-06-17 21:40
他好像强调了主动吧?楼上的代码应该只能被动通信 是啊,我也想知道啊,有PASSTHRU主动发信息到APP,很有意思啊 |
|
|
7楼#
发布于:2003-07-07 11:19
驱动程序用命名事件发触发应用程序,然后由应用程序去读取
这样算主动? |
|