阅读:1387回复:2
HuYuguang看过来
你在一篇回复中提到bind 到NdisWan 的方法是bind到它导出的一个ethernet miniport,请问哪里有介绍的详细点的资料啊,我找遍DDK都不见,而PCAUSA的例子似乎说这是可以的,只是要交几百$,我可没钱买!所以希望大侠指点一二。
小弟谢过先! |
|
沙发#
发布于:2002-11-20 19:47
兄弟,关于NDISWAN的问题以前有很多帖子,你找找吧!很简单的!!好运1!
|
|
|
板凳#
发布于:2002-11-21 10:40
你指的很简单的方法莫非是修改imd driver inf,添加wan,然后再接受ndisMediaTypeWan类型的绑定?
该方法我试过,确实能使passthru多绑定了好多块Adapter,可是通过注册表看,似乎都是Wan miniport,而且从理论上讲,该方法也不大可能绑定到NdisWan,因为DDK上介绍,NdisWan就是把802.3接口的数据包装换为ppp帧,所以Ndiswan提供给上层的设备应该是802.3类型的,而非Wan类型。 不知我说的对不对? 另外:Ndiswan的注册表linkage下export项的确有好多device,但是看名字似乎都是针对每一个Wan miniport导出一个device,这与DDK中提到为上层提供同一接口的概念不符合,但是察看Tcpip或者NetBt等被NdisWan支持的协议的注册表项发现,他们的确只和Ndiswan有一个接口,就是\\device\\ndiswanip,\\device\\ndiswanNtxx(忘记了),这说明Ndiswan正规绑定并非我们想的那样,因为imd driver 没有这样的对应设备。 我的结论是,microsoft的别有用心的技术封闭究竟目的何在实在令我这样的傻程序员无法领会,而为了突破技术封闭好多天才程序员(比如发现Ndis Hook的诸位)绞尽脑汁用尽了非法手段,实在是一种莫大的牺牲,我感觉不是在与天斗,而是在与人斗,这种浪费太不值得了。 另外附上一篇我读不懂的文章,也是讲这个的,不知哪位好心人可以解释一下,这一连串的疑问? Implementing a intermediate driver that works with RAS under NT Unfortunately, because of the \"open\" architecture of Windows NT it is absolutely impossible to implement intermediate drivers using the information provided in DDK. Many aspects of the problem are completely uncovered there; and thanks God there are several examples of intermediate drivers which you can use as a starting point for an intermediate driver. Unfortunately again, those examples work only for network cards such as Ethernet, Fddi and Token-Ring; trying to use them for NdisWan (this is microsoft\'s acronym for RAS pseudo-\"network cards\") fails. The main reason for this is that RAS uses a proprietary interface (aside of the \"standard\" NDIS interface). The following instructions are how to make an intermediate driver that will accomplish this proprietary interface; however the following was tested only with NetBIOS transport, but TCP/IP transport should work this way too. Here are the instructions how to adapt a intermediate driver that works with network cards to make it work with RAS: First, RAS architecture is designed to use a separate \"network card\" for each protocol that is routed through the modem; and also a separate \"network card\" for receiving calls and for dialing out. For example, if you set-up RAS to \"Receive calls only\" and select the TCP/IP and NetBEUI protocols to be routed through RAS you will end up with two NdisWan pseudo-network cards (in fact, you will end up with FOUR network cards but two of them are created regardless of RAS setup - one is the AsyncMac adapter and other is called somewhat jerky \"BloodHound adapter\"). If you set up RAS to receive dial in calls and dial out using TCP/IP, NetBEUI and IPX protocols you will end up with SIX NdisWan adapters (aside from those \"special\" two I mentioned above). To intercept a specific protocol you should insert your driver between a protocol and one of NdisWan drivers. The installation instructions follows: NdisWan adapters have a specific \"service name\" string. The RASMAN (the top-level RAS manager that works with adapters) checks for \"NdisWan\" string to be part of service name - otherwise the network card is not considered an RAS adapter. So, you should name your adapter XXXXNdisWanXXXX where XXX stands for any text. RASMAN checks for NdisWanDialin and NdisWanDialout strings to be part of service name to determine which adapters are used for dialing out and which for receiving calls. So, more specifically, your adapters should have ServiceName equal to XXXXNdisWanDialinXXXX or XXXXNdisWanDialoutXXXX service names. Your intermediate protocol should bind to the NdisWan \"network cards\". To do this, you should add the binding rule for your protocol that tells NCPA to bind it to the NdisWanAdapterXXXs; this can look like this: {\"IntermediateTransport ndisWanAdapterDialIn non non 100\", + \"IntermediateTransport ndisWanAdapterDialOut non non 100\", + \"IntermediateTransport ndisWanAdapterDialInIP non non 100\", + \"IntermediateTransport ndisWanAdapterDialOutIP non non 100\"} Medium type. Some people tried to report NdisMediumEthernet instead of NdisMediumWan in their MiniportInitialize() function. However, this is WRONG. Doing so just temporarily resolves some of the problems that arise. If you do so you will later encounter other problems. So, if the underlying NIC reports NdisMediumWan NdisWAN is a NDIS3 miniport. DON\'T implement any NDIS4-specific features for your adapter. For example, the IMSAMPLE intermediate driver sample that can be downloaded from microsoft\'s Web site implements MiniportSendPackets() function instead of NDIS3 MiniportSend() - this leads to a LOCKUP during netowork initialization because NDIS.SYS assumes that if driver reports its medium as NdisMediumWan it IS a NDIS3 adapter; when a protocols tries to send some initial broadcasts through your adapter NDIS.SYS queues the packets, then it sees that MiniportSend function is NULL and finally it loops until the send queue becomes empty. Obviously this will never happen. RASMAN opens the \\Device\\NdisWan device and talks with that device using a microsoft proprietary API. Of course I don\'t know that API but under a debugger can be well seen that during connection phase RASMAN sends an IRP down to NdisWan requiring a specific adapter to enable (and send an ProtocolIndicateStatus with LINEUP indication) a specific WAN adapter; this IRP contains the name of YOUR intermediate driver but NdisWAN doesn\'t know that adapter, so it indicates error. To overcome this, you should intercept all IRPs sent to NdisWAN (fortunately this is possible by using IoAttachDevice () kernel-mode call). After this you should do the following: NTSTATUS NdisWanIoctl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { // If this is a request for \\Device\\NdisWan, process it if (DeviceObject != NdisWanHookDevice) return -1; PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp); // copy the IRP into the stack location for next driver *nextIrpStack = *IrpStack; if (IrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) { // Get the pointer to the input/output buffer and it\'s length PVOID inputBuffer = Irp->AssociatedIrp.SystemBuffer; PVOID outputBuffer = Irp->UserBuffer; ULONG inputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; ULONG outputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; ULONG IoCode = (IrpStack->Parameters.DeviceIoControl.IoControlCode & 0x3ffc) >> 2; ULONG IoId = IrpStack->Parameters.DeviceIoControl.IoControlCode >> 16; if (IoId == 0x30) switch (IoCode) { case 3: // ActivateRoute { struct ActivateRoute { ULONG Unknown1; // 0x00000001 USHORT Protocol; // 0x80d5 USHORT DeviceNameLength; // 0x0010 K_CHAR DeviceName [100]; // \"\\DEVICE\\NDISWAN4\" } *Parm = (ActivateRoute *)inputBuffer; // If device name is specified, replace it by underlying MP if (Parm->DeviceNameLength != 0xffff) { K_STRING Name = { Parm->DeviceNameLength * 2, Parm->DeviceNameLength * 2, Parm->DeviceName }; // Look through NdisWan intermediate drivers NdisAcquireSpinLock (&NdisWanAdapterChainLock); AdapterControlBlock *cur = NdisWanAdapterChain; while (cur) { if (!RtlCompareUnicodeString (&Name, &cur->IMDeviceName, TRUE)) { // Copy the underlaying MP device name into buffer RtlMoveMemory (&Parm->DeviceName, cur->MPDeviceName.Buffer, cur->MPDeviceName.Length); Name.Length = Name.MaximumLength = cur->MPDeviceName.Length; Parm->DeviceNameLength = cur->MPDeviceName.Length / 2; RtlUpcaseUnicodeString (&Name, &Name, FALSE); break; } cur = cur->NextNdisWan; } NdisReleaseSpinLock (&NdisWanAdapterChainLock); } break; } } } return IoCallDriver (NdisWanDevice, Irp); } That\'s it. Questions/comments: Andrew Zabolotny <bit@eltech.ru> |
|