xinghaiyun
驱动牛犊
驱动牛犊
  • 注册日期2002-03-13
  • 最后登录2004-06-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1429回复:5

版主,你答应的源码(异步读写驱动)还没贴? 劳驾

楼主#
更多 发布于:2002-06-24 09:46
rt

最新喜欢:

wujiajunwujiaj...
Dragon2008
驱动中牛
驱动中牛
  • 注册日期2002-04-01
  • 最后登录2006-03-13
  • 粉丝0
  • 关注0
  • 积分31分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-24 15:21
快帖出来吧,我也想学一学
我姓龙,我属龙,我叫龙。。。
wuqix
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2008-06-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-28 05:04
呵呵,这几天忙,没来,见谅见谅。
整个框架结构很简单,但是要实现具体功能就要看你怎么组织这个框架了。你要实现的似乎是个普通的wdm,我手头写好的是个ndis-wdm结构的程序,中间对ndis packet的处理占了一大部分,想来对你也没什么用,针对我以前项目的内容我全部删去,我也懒得大改了,根据你的描述,简单动了动。
//开线程这么开
NTSTATUS
StartThread(
PUSB_STRUCT TheUsb//你随便吧,我觉得这里给个设备扩展不错
)
{
NTSTATUS status;
HANDLE hthread;
KeInitializeEvent( &(TheUsb->WriteQueueEvent),
NotificationEvent,
FALSE
);

status = PsCreateSystemThread(
&hthread,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE)WriteThreadRoutine,
(PVOID)TheUsb
);
if(!NT_SUCCESS(status))
return status;

status = ObReferenceObjectByHandle(
hthread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*) &TheUsb->WriteThread,
NULL
);

ZwClose(hthread);
return STATUS_SUCCESS;
}


VOID
StopThread(
PVOID UsbStru//和上一个给的应该一样,为的就是线程句柄而已,若你选择了一个与众不同的位置,比如把这个句柄放在全局的位置,这里什么都没有也行
)
{
PUSB_STRUCT TheUsb=(PUSB_STRUCT)UsbStru;
if(TheUsb->WriteThread){
KeWaitForSingleObject(
TheUsb->WriteThread,
Executive,
KernelMode,
FALSE,
NULL
);
ObDereferenceObject(TheUsb->WriteThread);
TheUsb->WriteThread=NULL;
}
}


VOID
WriteRoutine(
PVOID UsbStru//同上
)
{
NTSTATUS status;
PUSB_STRUCT TheUsb=(PUSB_STRUCT)UsbStru;
while(TRUE){
status = KeWaitForSingleObject(
&(TheUsb->WriteQueueEvent),
Executive,
KernelMode,
FALSE,
NULL
);
if(!NT_SUCCESS(status)){//error waiting
break;
}//error waiting
if(TheUsb->ExitWriteThread)
break;
//这里放实际的调用usb总线驱动发数据的函数,你自己写吧,呵呵,
//我的这个函数干的全是和网络层有关的事情,涉及到一些东西,公开了有点对不起我以前的老板:)
KeClearEvent(&(TheUsb->WriteQueueEvent));
} //这个线程其实就是死循环,但卸载是没有问题的
PsTerminateSystemThread(STATUS_SUCCESS);
}

VOID
SignalThread(
PVOID UsbStru
)
{
PUSB_STRUCT TheUsb=(PUSB_STRUCT)UsbStru;
KeSetEvent(&(TheUsb->WriteQueueEvent),0,FALSE);
TheUsb->GoOut=TRUE;
}

NTSTATUS
Mo_USB_DeviceControl(IN PDEVICE_OBJECT fdo,IN PIRP Irp){
.......
//这里你的工作就比较辛苦了,呵呵
//主要工作是入队,不过要做好与自己开的线程的同步
//比较麻烦,我前面贴的4个函数里有几个和event有关的
//都是在做这件事

//首先看看你有没有抢占低优先级发送线程,
//然后分情况处理。
PQueuePacket Head =(PQueuePacket)(Adapter->SenPacketsHead);
PQueuePacket Tail =(PQueuePacket)(Adapter->SenPacketsTail);
PQueuePacket Insert;// = Tail->Next;
NDIS_STATUS Status;
NdisAcquireSpinLock(&(Adapter->SenSpinLock));
if(!SendInProgress){
//这个中间的代码太多,对你用处似乎不大,所以我删了
//核心思想是直接入队,然后通知线程
}else{//SendInProgress
//入队,但不通知线程
}
NdisReleaseSpinLock(&(Adapter->SenSpinLock));
.......
}
注:此招对于ndis的某些问题,比如发包时中断级过高有奇效,但对一般wdm程序来说,dispatch例程压根不会在dpc级被调用,所以多少有点於余,你自己组织的时候可以改进一下。
wuqix
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2008-06-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-28 05:08
贴完了才发现,以前程序组织的很差,哎,真郁闷……
xinghaiyun
驱动牛犊
驱动牛犊
  • 注册日期2002-03-13
  • 最后登录2004-06-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-06-28 08:09
非常感谢wuqix大侠的回答!
很对不起,发贴时忘了给分,在别处给你分.
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-07-01 12:24
你在异步传输时使用了事件Event,不知你是怎么传进驱动中的。
常用的作法是用DeviceIoCtrl,但实际在WriteFile, ReadFile, DeviceIoControl 中都可以有一个LPOVERLAPPED,但不知在驱动中的IRP中怎么取到这个结构中包含的Event
游客

返回顶部