阅读:1237回复:5
一个有关访问IO的driver,在访问Com口时总是不能得到值
Hi ,各位驱动开发网的朋友:
小弟现在有一个问题想请教大家。我写了一个driver是专门用来访问IO端口的。我全部用的是DDK中提供的函数,没有用Undocument的API。这个driver可以正常的访问打印口,扬声器的端口。但是在读取COM口数据时得到的数据总是0xff.一般系统提供给Com的IO端口为0x3f8~0x3ff, 或0x2f8~0x2ff等。但当我去读这些端口时,得到的数据总为0xff,写也写不进去。我不知道是什么原因,难道是体统屏蔽了这个端口,还是怎么的。而且我用那三个没有公开的API直接打开IO掩码,得到的结果是一样的,这就使我感到很奇怪了,如果我的driver有问题的话,那他应该连其他端口也不能访问,但是我试了其他端口可以读出正确的值,就是Com口如果直接的去读写的话,好像不能得到正确的值,独到的值总为0xff,写也写不进去。请各位帮忙,看看是什么原因,谢谢! |
|
沙发#
发布于:2003-09-23 22:17
这种驱动还用自己去写吗?
http://www.internals.com/ |
|
板凳#
发布于:2003-09-24 08:17
这位老兄:
谢谢你的回复,这个WinIO2.0我这里也有,而且我看到他是用微软没有公开的几个API来做的。这种方法虽然简单,但是还是有不好之处。我现在是自己全部用系统提供的API来写的,已经可以了。不过就是不能正常的读写COM口的值,而且我也用WinIO2.0也试了一下,好像他读到道的值也全为0xff.不知老兄试过没有。我不知是什么原因。 |
|
地板#
发布于:2003-09-24 08:58
修改IO位图看看.
驱动:WssIo.c #include \"ntddk.h\" #include \"string.h\" #ifndef DWORD #define DWORD unsigned int #endif #ifndef WORD #define WORD unsigned short #endif #define NOT_BUSY 9 #define DEFAULT_TSS_LIMIT 0x20ab //缺省的 TSS 段界限 #define NEW_TSS_LIMIT 0x2fab static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject); #pragma pack(push,1) typedef struct tagGDTR{ WORD wLimit; DWORD *dwBase; }GDTR, *PGDTR; typedef struct tagGDTENTRY{ DWORD dwLimit : 16; DWORD dwBaselo : 16; DWORD dwBasemid : 8; DWORD dwType : 4; DWORD dwSystem : 1; DWORD dwDpl : 2; DWORD dwPresent : 1; DWORD dwLimithi : 4; DWORD dwAvailable : 1; DWORD dwZero : 1; DWORD dwSize : 1; DWORD dwGranularity : 1; DWORD dwBasehi : 8; } GDTENTRY, *PGDTENTRY; #pragma pack(pop) VOID SetAllPorcIO( int iTrue ) { GDTR gdtr; PGDTENTRY TssInGdt; WORD TSSseg; __asm { cli // 屏蔽中断 sgdt gdtr // 得到 GDT 基地址与段界限 str TSSseg // 得到 TSS 选择子 movzx esi,TSSseg // 扩展到 ESI 中以便计算 add esi,gdtr.dwBase // 得到 TSS 在 GDT 中描述符 mov TssInGdt,esi } if ( iTrue == 1 ) { TssInGdt->dwLimit = NEW_TSS_LIMIT; // 设置新的 TSS 段界限 } else { TssInGdt->dwLimit = DEFAULT_TSS_LIMIT; } TssInGdt->dwType = NOT_BUSY; //必须设置为NOTBUSY状态(9),BUSY is 0Bh __asm { ltr TSSseg // 将设置好的 TSS 重新装入 sti // 开中断 } } // 驱动入口 NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { UNICODE_STRING nameString, linkString; PDEVICE_OBJECT deviceObject; NTSTATUS status; HANDLE hHandle; int i; //卸载驱动 DriverObject->DriverUnload = DriverUnload; //建立设备 RtlInitUnicodeString( &nameString, L\"\\\\Device\\\\WssIo\" ); status = IoCreateDevice( DriverObject, 0, &nameString, FILE_DEVICE_UNKNOWN, 0, TRUE, &deviceObject ); if (!NT_SUCCESS( status )) return status; RtlInitUnicodeString( &linkString, L\"\\\\DosDevices\\\\WssIo\" ); status = IoCreateSymbolicLink (&linkString, &nameString); if (!NT_SUCCESS( status )) { IoDeleteDevice (DriverObject->DeviceObject); return status; } SetAllPorcIO(1); for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction = MydrvDispatch; } DriverObject->DriverUnload = DriverUnload; return STATUS_SUCCESS; } //处理设备对象操作 static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0L; IoCompleteRequest( Irp, 0 ); return Irp->IoStatus.Status; } VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject) { UNICODE_STRING nameString; SetAllPorcIO(0); RtlInitUnicodeString( &nameString, L\"\\\\DosDevices\\\\WssIo\" ); IoDeleteSymbolicLink(&nameString); IoDeleteDevice(pDriverObject->DeviceObject); return; } //应用层测试程序 #include\"stdio.h\" #include <windows.h> SERVICE_STATUS_HANDLE ssh; SERVICE_STATUS ss; void WINAPI StartupService(); void WINAPI InstallService() { SC_HANDLE scm; SC_HANDLE svc; scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); svc=CreateService( scm, \"WinIo\", \"WinIo\", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, \"C:\\\\WINDOWS\\\\SYSTEM32\\\\DRIVERS\\\\WinIo.sys\", NULL, NULL, NULL, NULL, NULL ); if(svc!=NULL) { CloseServiceHandle(svc); CloseServiceHandle(scm); } } void WINAPI DelService() { SC_HANDLE scm; SC_HANDLE svc; BOOL ret; SERVICE_STATUS ServiceStatus; scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if(scm!=NULL) { svc=OpenService(scm,\"WinIo\",SERVICE_ALL_ACCESS); if (svc == NULL) { MessageBox(NULL,\"svcERROR!\",NULL,MB_OK); return ; } ret = ControlService(svc,SERVICE_CONTROL_STOP,&ServiceStatus); if (ret == FALSE) { MessageBox(NULL,\"error\",NULL,MB_OK); } svc=OpenService(scm,\"WinIo\",SERVICE_ALL_ACCESS); DeleteService(svc); CloseServiceHandle(svc); MessageBox(NULL,\"驱动已卸载 \",\"删除\",MB_OK); CloseServiceHandle(scm); } else MessageBox(NULL,\"cuo\",NULL,MB_OK); } void WINAPI StartupService() { SC_HANDLE scm; SC_HANDLE svc; scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if(scm!=NULL) { svc=OpenService(scm,\"WinIo\",SERVICE_ALL_ACCESS); if(svc!=NULL) { StartService(svc,0,NULL); CloseServiceHandle(svc); MessageBox(NULL,\"驱动已安装\",\"启动\",MB_OK); } else CloseServiceHandle(scm); } else MessageBox(NULL,\"安装驱动失败\",NULL,MB_OK); } void WINAPI InitService() { InstallService(); StartupService(); } void main() { TCHAR szDir[MAX_PATH]; TCHAR szsysDir[MAX_PATH]; int i = 0; GetCurrentDirectory(sizeof(szDir),szDir); lstrcat(szDir,\"\\\\winio.sys\"); GetSystemDirectory(szsysDir,sizeof(szsysDir)); lstrcat(szsysDir,\"\\\\drivers\\\\winio.sys\"); CopyFile(szDir,szsysDir,FALSE); InitService(); __asm { mov al,0a0h mov dx,03f8h out dx,al mov dx,03f8h in al,dx mov byte ptr i,al } printf(\"%d\\n\",i); DelService(); } |
|
|
地下室#
发布于:2003-09-24 09:28
Hi, wowocock:
我刚才在ddk环境下build你的WssIo.c怎么出现了102个错误呀。请问你是如何build的呀。谢谢你了,你能帮小弟实试试吗?谢了! |
|
5楼#
发布于:2003-09-24 11:37
不会吧,我用XPDDK编译没问题的啊
|
|
|