zhzdll
驱动牛犊
驱动牛犊
  • 注册日期2003-02-12
  • 最后登录2005-01-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2554回复:15

请问,NDIS的下两层驱动能不能直接与外部应用程序通信??

楼主#
更多 发布于:2003-04-28 11:31
不是通过协议驱动层。而是直接通过中间驱动或者微端口驱动。
谢谢赐教!

最新喜欢:

WY.lslrtWY.lsl... riririririri txysptxysp
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-04-28 13:27
当然可以了,很多帖子讨论这个问题,你找一下看看就知道了
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
zhzdll
驱动牛犊
驱动牛犊
  • 注册日期2003-02-12
  • 最后登录2005-01-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-04-28 17:09
我想做的东西是这样,协议层仍然是TCP/IP,在中间层(或者微端口层)申请一片缓存区,友它接受或发送外部程序的数据包,比如来自串口应用程序的数据包。问题是一个处于核心态,一个处在用户态,其数据交互的接口函数是什么,还是CreateFile、WriteFile、ReadFile吗?
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-04-28 17:19
解决你的问题有两个方法:一是你看看驱动开发的书,估计那本都会讲应用程序和驱动程序通信的问题;二是你可以在这个版上查找以前的帖子,有很多人问过这个问题了。
如果这两种方式你都不想,那我也没有办法了。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
dana_wx
驱动牛犊
驱动牛犊
  • 注册日期2002-11-08
  • 最后登录2003-07-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-04-29 10:53
Mikeluo : 由应用层发消息到驱动 我知道用IoControl 可以的 但是我由驱动向 应用层发消息 使用事件莱完成 我在应用层里面等待 在驱动里面设置信号 应用层根本获得不了这个信号 求教了 能解答一下么
zhzdll
驱动牛犊
驱动牛犊
  • 注册日期2003-02-12
  • 最后登录2005-01-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-04-29 16:32
无论如何,非常感谢你的帮助。
我打算最近全心研究驱动,具体问题希望能再向你咨询,再次感谢你热心的帮助和建议。
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
6楼#
发布于:2003-04-29 16:48
www.codeguru.com上面有个一个guidevice的例子,去抄吧。
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-04-29 17:08
Mikeluo : 由应用层发消息到驱动 我知道用IoControl 可以的 但是我由驱动向 应用层发消息 使用事件莱完成 我在应用层里面等待 在驱动里面设置信号 应用层根本获得不了这个信号 求教了 能解答一下么


看fracker说的那个例子就ok了:)
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
dana_wx
驱动牛犊
驱动牛犊
  • 注册日期2002-11-08
  • 最后登录2003-07-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-04-30 15:07

mikeluo

看fracker说的那个例子就ok了:)

那个codeguru 网址是英文的么 我怎么都看不懂 是不是那个
没找到呜呜
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-04-30 16:21
就是这个例子。
附件名称/大小 下载次数 最后更新
2003-04-30_GUIDevice.zip (25KB)  135
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
sword3i
驱动牛犊
驱动牛犊
  • 注册日期2003-07-25
  • 最后登录2013-01-07
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望112点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-07-27 13:46
学习 :D
随风奔跑自由是方向 追逐雷和闪电的力量 把浩瀚的海洋装进我胸膛 即使再小的帆也能远航 随风飞翔有梦作翅膀 敢爱敢做勇敢闯一闯 哪怕遇见再大的风险再大的浪 也会有默契的目光 努力蹭分! ..................
king229
驱动中牛
驱动中牛
  • 注册日期2003-04-29
  • 最后登录2012-04-10
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-07-27 13:53
该成立个精华区了 现在问题重复的好多
鬼啊~~~~~~~~
sword3i
驱动牛犊
驱动牛犊
  • 注册日期2003-07-25
  • 最后登录2013-01-07
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望112点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-07-27 15:07
说的good,这也方便我等菜鸟更快入门 :D
随风奔跑自由是方向 追逐雷和闪电的力量 把浩瀚的海洋装进我胸膛 即使再小的帆也能远航 随风飞翔有梦作翅膀 敢爱敢做勇敢闯一闯 哪怕遇见再大的风险再大的浪 也会有默契的目光 努力蹭分! ..................
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-07-27 18:56
这是最easy的:
1.通讯
在NDIS IMD中用NdisMRegisterDevice,注册一个设备。然后可以通过
DeviceIoControl和应用层通讯
2。当你在APP调用API比如CreateFile ,等等时系统将你的请求转化为IRP转入KENEL中
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就可以看到内核态和用户态的交互情况。

祝你好运!



 

____________________

“今天心情好,中午刚刚吃了顿饱饭,吃得我坐在草地上喘了
半个小时的气还没有缓过劲来,其实也就是双份蛋炒饭,不过
感觉很爽。”----Huyg
学习,学习,再学习
 
放弃瘟草,现吃李草
samneg
驱动牛犊
驱动牛犊
  • 注册日期2007-09-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望10点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-10-01 14:30
NDIS_STATUS  PtRegisterDevice(   VOID    )
NTSTATUS  PtDispatch(    IN PDEVICE_OBJECT    DeviceObject,    IN PIRP       Irp    )
NDIS_STATUS  PtDeregisterDevice(    VOID    )
VOID PtUnload(    IN PDRIVER_OBJECT        DriverObject    )
楼上的意思这几个函数是为了和应用层程序通讯而设立的 ?
可以帮忙解释下NTSTATUS  PtDispatch 这个函数的作用吗?
牛犊
RED_spring
驱动中牛
驱动中牛
  • 注册日期2002-07-28
  • 最后登录2016-11-06
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望19点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
  • 社区居民
15楼#
发布于:2007-10-11 23:40
ddk里有专门的例子。
游客

返回顶部