阅读:1262回复:3
Driver如何给App发消息的问题
参照 http://bbs.driverdevelop.com/htm_data/45/0307/47706.html,客户端程序改造如下:
我想让驱动回传一个字符放在 TCHAR testdata[1];中。 驱动端怎么写??上面的例子中给出的驱动端的程序看不明白,哪位指点一下啊 另外我把 // while (TRUE) // if (_getche() == 0xd) // break; // // CloseHandle(hEvent); // CloseHandle(h); 这段代码屏蔽掉了,我想给驱动端发一个消息后,不结束等待线程,可以多次接受驱动端返回的数据,这个想法可行吗??? #include "stdafx.h" #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <winioctl.h> #include <string.h> #include <crtdbg.h> #define CD_DEVICE_NAME TEXT("\\\\.\\CryptionDirectory") #define IOCTL_GET_TEST_DATA (ULONG) CTL_CODE( FILE_DEVICE_DISK_FILE_SYSTEM, 0x00, METHOD_NEITHER, FILE_READ_ACCESS ) #define IOCTL_SET_TEST_DATA_EVENT (ULONG) CTL_CODE( FILE_DEVICE_DISK_FILE_SYSTEM, 0x00, METHOD_NEITHER, FILE_WRITE_ACCESS ) TCHAR testdata[1]; HANDLE h, hEvent; ///////////////////////////////////////////////////////////////// // ServiceThread // // This thread is awakened by the driver to tell the app to come // and get the interrupt records // DWORD WINAPI ServiceThread(PVOID hEvent) { ULONG nBytesRead; while (TRUE) { WaitForSingleObject(hEvent, INFINITE); printf("New event:\n"); if (!DeviceIoControl( h, IOCTL_GET_TEST_DATA, NULL, 0, testdata, sizeof(testdata), &nBytesRead, NULL) ) { printf("DeviceIoControl failed %x\n", GetLastError()); exit(1); } printf("%c", testdata[0]); } return 0; } ///////////////////////////////////////////////////////////////// // // Main // void __cdecl main(int ac, char* av[]) { DWORD Tid; ULONG error; ULONG nRet; // Open the device h = CreateFile(CD_DEVICE_NAME, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) { error=GetLastError(); fprintf(stderr, "Cannot open device, error %d (0x%x)\n", error, error); exit(1); } // Create an event for notification hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (! DeviceIoControl( h, IOCTL_SET_TEST_DATA_EVENT, &hEvent, sizeof(hEvent), NULL, 0, &nRet, NULL ) ) { printf("Ioctl failed: %x\n", GetLastError()); exit(1); } // Create the thread that waits for the event CreateThread(0, 0x1000, ServiceThread, (PVOID)hEvent, 0, &Tid); // printf("press return to exit . . .\n"); // Look for a key to terminate // while (TRUE) // if (_getche() == 0xd) // break; // // CloseHandle(hEvent); // CloseHandle(h); } |
|
沙发#
发布于:2007-08-28 17:37
我的理解(不一定对)
驱动一般运行在pass_level与dispatch_level两层软多pass_level就是你上层的api来访问所解发的, 它是一个被动态, 你可以在应用程序层 来请求资料,下面贴下代码,不知道对你有没有用,^_^ |
|
|
板凳#
发布于:2007-08-28 17:39
与驱动通信
应用程序与内核通信应用程序: 1. #define DEVICE_HELLO_INDEX 0x860 // IOCTL宏 #define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN, DEVICE_HELLO_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) 2.载入驱动并启动 LoadDeviceDriver("HelloWorld", "C:\\hel\\objchk_wnet_x86\\i386\\helloword.sys", &hDrv, &dwError ); 3, DeviceIoControl(hDrv, //设备名柄 START_HELLPWORLD, //传入的控制码. ";c:\\test\\abc\\1.doc;;", //输入的BUFFER strlen(";c:\\test\\abc\\1.doc; "), //输入BUFFER的大小 buf, //输出BUFFER 128, //输出BUFFER的大小 &nb, //返回的实际字节数 NULL ) ) // 4, printf("%s\r\n%d\r\n", buf, nb); 驱动: 1. #define DEVICE_HELLO_INDEX 0x860 // IOCTL宏 #define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN, DEVICE_HELLO_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) 2, //设置IRP派遣例程和卸载例程 DriverObject->MajorFunction[IRP_MJ_CREATE]= //未控制 DriverObject->MajorFunction[IRP_MJ_CLOSE]= //未控制 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=HelloWorldDispatch; DriverObject->DriverUnload=HelloWorldUnLoad; 3, NTSTATUS HelloWorldDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp) { NTSTATUS ntStatus=STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack=NULL; //IRP堆栈 ULONG IoControlCodes=0; //I/O控制代码 UCHAR *in_buffer,*out_buffer; in_buffer = out_buffer = pIrp->AssociatedIrp.SystemBuffer; //设置IRP状态 pIrp->IoStatus.Status=STATUS_SUCCESS; pIrp->IoStatus.Information=0; //取得I/O控制代码 IoControlCodes = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (IoControlCodes) { //启动 case START_HELLPWORLD: { DbgPrint("%s", in_buffer); RtlCopyBytes(out_buffer, "hi ,this is from the kernel",30); pIrp->IoStatus.Information = 30; //Irp->IOstAtus.InformAtion 表示要返回多少字节,当=0 //时,user-mode的returnsize=0,buffer中也没有数据返回 } break; case STOP_HELLPWORLD: DbgPrint("this is Stoping \"Hello World\"\n"); break; default: pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER; break; } default: break; } ntStatus=pIrp->IoStatus.Status; IoCompleteRequest(pIrp,IO_NO_INCREMENT); } //这个complete很重要,,没加这个的时候,user-mode程序不返回,驱动也卸载不下来,用这个函数来returning the given IRP to the I/O Manager,这样就完成了一个完整的irp,,现在应该弄清IRP和IO_STACK_LOCATION的关系,在《windows 操作系统原理》上找到,“任何内核模式程序在创建一个IRP时,同时还创建一个与之关联的I/O堆栈,堆栈中的I/O堆栈单元由IO_STACK_LOCATION结构定义,每个堆栈单元都对应一个将处理该IRP的驱动程序。为了在一个给定的IRP中确定当前IRP I/O堆栈单元,驱动程序可以调用IoGetCurrentStAckLOcAtion函数,该函数返回指向当前I/O堆栈单元的指针。” return ntStatus; } |
|
|
地板#
发布于:2007-08-28 17:40
大
filemon是定时请求的,你可以参考一下 |
|
|