Background: I need to create an NDIS filter intermediate driver. This driver will pass all traffic while collecting metadata (primarily timing information). The driver will export this information to a user application by inserting its own packets containing the metadata and passing them up the stack.
My question is regarding NDIS versions. Eventually, I will have to write a driver for both Windows XP and 7. However at the moment, I will only be implementing one of these as a proof of concept/prototype. I know that in NDIS 6 they split the filter functionality out from generic intermediate drivers into a separate driver type (lightweight filter) in order to simplify the creation of filter drivers. Microsoft provides examples of passthrough filter drivers in the DDK for both NDIS 5 and 6. I've been looking at these examples and the NDIS 6 LWF only looks somewhat simpler (although admittedly, I'm still new to Windows driver development).
All other things equal, it would be better to support Win XP first (larger installed base, easier access to test machines, etc). However, if NDIS 6 lightweight filters would make for faster/easier development, I might be better off implementing the Win 7 driver first.
In short: In your experience has NDIS 6 noticeably simplified filter driver development compared to NDIS 5?
Thanks for any input.
If you just want to modify the WDK sample drivers, then perhaps the NDIS 5 IM is not too much work. I'm not familiar with NDIS 6 LWF drivers so can't comment.
Alternatively use a user-mode package such as WinDivert or WinPktFilter to create a proof-of-concept prototype. This might be easier than driver development. Disclosure: I authored WinDivert
Yes, from the implementation aspect, NDIS 6.0 filter driver is easier then NDIS 5.x IM driver, but not much.
The major differences are the hook interfaces and data encapsulation: NDIS_PACKET vs NET_BUFFER_LIST. But it is not difficult to convert them to your private network data descriptor. You can use the WDK sample code(passthru and filter) for the hook part, then design your internal common interface to handle the private network data descriptor for both IM and LWF driver.
Related
As cross signing is now deprecated, we are trying to pass the HCK and HLK test in order for our NDIS LWF to install on 7+ machines, and our LWF uses NDIS 6.0.
My questions are:
When we select our driver in HCK, there are 0 tests available, even tho our LWF is clearly installed, Is this normal?
When we run HLK 1607, there are only the two basic tests, which are the TDI and Hyper-V readiness test, but there is no NDIS 6.5 LWF Logo test. Do we only need to pass these two tests?
Should we add the folder that contains our driver + its inf in the package tab, before creating the package? Or our driver automatically gets bundled in the hlkx file that gets generated?
Note that we are not using any playlist, although i am still not sure what's the deal with these playlists and whether or not we need to use a playlist or just use the default one?
Regarding the first couple questions, yes that sounds normal. We (the NDIS team at Microsoft) honestly don't know how to test an arbitrary NDIS LWF. LWFs can just do so many different things, that any generic test we could try to make would probably cause a false negative for some filter driver. For example, a test that verifies various types of network traffic pass through the LWF would likely fail on a firewall driver, whose very job is to drop suspicious traffic. And in many cases, LWFs do nothing at all until some 3rd party usermode application sets up some configuration for them. For example, a QoS filter probably operates in a no-op mode until some usermode application pushes down QoS policies; any generic test we build would just be exercising the no-op mode, and we'd completely miss the interesting part of the driver.
So for now, you're largely on the honor system that you've implemented NDIS contract correctly and done your due diligence in testing its functionality.
We reserve the right to add more tests in the future, of course, if it becomes clear that this would benefit our mutual customers.
Note that Driver Verifier (DV) includes an "NDIS/WIFI" flag: if you enable that mode, NDIS will automatically verify many of its programming contracts. So if you're looking for some assurance that you've done things correctly, make sure you exercise your LWF's various scenarios with DV + NDIS/WIFI enabled. In general, DV gets a bit better with each OS release, so testing on the latest OS version will catch the most bugs, even if your LWF is targeted towards an older OS.
As to your third question: I don't know. (Ironically, I don't have access to the driver submission pipeline myself, so I have never actually tried things from your point of view.)
I really want to capture the packet on Windows 7
but i'm beginner of windows programming so I have no idea, how can I solve the
problem.
I know I can capture the packet by using DNIS but my computer is windows7 but
on the webpage there are only for windows 10 or windows 8.1
is there anyone let me know the information?
I know I can capture the packet by using DNIS
(Presumably "using NDIS".)
Yes, NDIS is the operating system mechanism that provides hooks for packet capture.
As you're asking on Stack Overflow, presumably you want to write a program to capture packets, rather than using an existing program.
You could write your own code to use NDIS (which works at least as far back as Windows NT 4.0, and probably earlier and, with different code, Windows 9x as well), but that's code that would run in the kernel, and that's a bit more difficult.
However, WinPcap and Npcap already have that kernel code, and a library that runs in user mode, providing the same API as libpcap on UN*X; the easiest way would probably be to install WinPcap or Npcap on your machine, along with the Software Development Kit for WinPcap or Npcap, and use that.
If you're programming in C or C++, you can use the API directly. In other languages, including .NET languages, there are wrappers for libpcap/WinPcap - see this list of wrappers, for example.
everyone. I am doing some improvements for WinPcap. Now I have ported the npf.sys driver from NDIS5.0 to NDIS6.0. Is there still improvement space for this driver, like porting it to LWF (Light-Weight Filter) or WFP (Windows Filter Platform)? We just want to make sure to use a newer and better framework.
Here're some other questions:
It seems that LWF is a product in the Vista time, and now it's not much mentioned by Microsoft, is this true?
Can a LWF or a WFP driver do things that a NDIS protocol driver can do?
Does LWF or WFP have relation with WDF (Windows Driver Framework), or compatible with both WDF and WDM framework?
If this is viable to port, how about the difficulty, I have developed some NDIS Intermediate drivers before, does LWF or WFP harder or easier than that?
Thanks!
Congratulations on porting WinPcap to NDIS 6.x. I'm impressed. I hope you can convince upstream to take your changes :-)
Regarding LWFs
LWFs are still quite supported by Microsoft. We don't talk about them much, simply because there is limited interest in them. Most people really want to work at layer-3 or layer-4, where they are better served by WFP than by a LWF. However, a low-level packet capturing toolkit is a perfect example of what LWFs are good for.
We are happy to see people write new LWFs, WFP callouts, NDIS miniports, or NDIS protocols. These are all supported and current technologies. (Assuming NDIS 6.x for the miniport & protocol).
Comparing LWFs, NDIS protocols, and WFP callouts
A LWF can do almost anything that an NDIS protocol driver can do. There are a few small corner cases, but generally you'll find that LWFs are powerful.
WFP callouts operate at a different layer, and so have rather different strengths and weaknesses than an NDIS protocol or LWF. For example, a WFP callout cannot interact with media-connect state, hardware offloads, or power management. But unlike NDIS LWFs, a WFP callout can peer into the plaintext of an IPsec-protected packet, query the identity of the user/application that originally sent a packet, intercept loopback IP traffic, and authorize the creation of a socket itself (before any traffic is sent).
You should sit down and ask yourself: "Which layer of the network stack am I really interested in?" If the answer is layer-2, then go ahead with an NDIS driver. If it's layer-3 or layer-4 of the IPv4/6 stack, then you'll want a WFP callout. (Some people start with an NDIS driver because they're most familiar with NDIS, but then run into difficulties because they're actually trying to solve a problem at the TCP layer.)
Using WDF with NDIS or WFP
WDF is largely orthogonal to NDIS or WFP. You can choose to use either WDF or WDM or a mix of both in your NDIS driver or WFP callout. Microsoft, the NDIS team and I officially encourage you to use WDF as much as possible, since it will save you time and make your driver higher-quality.
Generally if your LWF or NDIS protocol is just a basic "hello world" driver, WDF will work fine, but won't be terribly useful. WDF doesn't help much with the part of your driver that interacts with NDIS. But as soon as you add an IOCTL to usermode (or any other non-NDIS trick), WDF can spare you a lot of time and bugs.
Difficulty of LWFs and WFP callouts
I think you'll find that NDIS LWFs and WFP callouts are some of the easiest network drivers to write. A LWF is easier than an NDIS protocol driver, and much easier than an NDIS IM driver. A complete do-nothing LWF driver is only about 20 lines of code. WFP callouts are no more difficult to write than an LWF.
When creating a Windows Driver project in Visual Studio 2012, you have many different options to choose from.
There's a page on MSDN that helps you with choosing the correct driver model for your device. It however doesn't clearly explain the exact differences between the WDM, KMDF and UMDF driver types, and when to choose which model.
I'm looking for an explanation on the differences between the WDM, KMDF and UMDF driver models, so it's easy for beginning Windows driver developers to choose the correct model.
In a nutshell:
WDM stands for Windows Driver Model. Every Kernel driver is essentially a WDM driver.
KMDF stands for Kernel Mode Driver Framework. This is a framework that encapsulates and hides many of the OS programming aspects that driver developer must relate to even if it has nothing to do with the business logic of his driver. Some functionality doesn't exist in KMDF framework and will require native Kernel calls without using the framework (but in most situations it's not the case).
UMDF stands for User Mode Driver Framework. It's a complementary framework to KMDF and together they comprise WDF (Windows Driver Frameworks). UMDF allows to create a driver in user mode, having all the benefits of User mode programming vs Kernel mode. Naturally, UMDF driver have limitations compared to KMDF/WDM drivers and in most situations it will require a Kernel counterpart with at least some functionality.
The page you've referenced is pretty comprehensive. You should dwell into it for deeper understanding.
I like articel from MSDN : Differences Between WDM and KMDF
WDM is the driver model since pnp device drivers (>=Win2k). In this model you have to handle functions not relevant to your functionality. Walter Oney (Programming the Microsoft Windows Driver Model) outsourced such functions to external device driver libraries for reusing.
WDF/kmdf tries to simplify the development of device drivers. Functions can be overwritten or default handler is used. The administration of memory and queues has been greatly simplified and secured.
UMDF tried to use similar function calls in user mode as function calls in kernel mode.
Hopefully not too late. Question date first seen when I had finished writing!
How would I go about creating a "gamepad" which appears to DirectInput applications as a normal game controller but the state of its controls is actually defined by software?
Write a device driver to pretend to be one.
Specifically, Windows device drivers handle what are called Interrupt Requests via the Interrupt Request Protocol - which boils down to a wrapped up structure and a set of buffers internally in the driver.
Now the next thing you need to know is that many drivers are actually layered, or stacked, or whichever name you want to use. So for example to write a disk driver, you might interface with the driver above it (as a disk class) but use a driver below it (scsi port, for example) to actually send commands to your devices.
That's how real devices work. Fake devices need to conform to the top level interface requirements, e.g. a disk, or a controller, or a mouse, or whatever it is. However, underneath they can do anything they like - return whatever values they like.
This opens up the possibility of controlling a driver via a user-mode application and pretending to "be" a device. To send a driver messages, you can DeviceIoControl to it; then to actually get those messages you can either:
Stuff them in the Irp that makes up that DeviceIoControl.
Have the driver read them out of your process' memory space.
Drivers can also access \\Registry\\Machine and various other, non-user-specific non-explorer registry areas, so it is possible to communicate that way.
Finally, there's no saying you can't filter existing IO, rather than make it all up via a new device. There are a great many options and ways you can go about doing this.
If you're going to do this, you'll need:
VirtualKD or an expensive debugger cable and two PCs.
You probably also want to start with the references on this blog post. You'll find that there are essentially a bazillion different names for driver code, so I'll interpret some of them:
WDM = Windows Driver Model, basically the NT driver model mixed with (some of) Windows 9x.
KMDF = Kernel mode driver framework - drivers of the above type use this, plus additionally WDF (Windows Driver Foundation) which is a set of libraries on top of WDM to make it quicker to use.
UMDF = User mode driver framework - write a driver without the danger of kernel mode. If you can, use this, as kernel mode drivers that go wrong will bluescreen (in driver parlance, bugcheck) your system.
Edit: I'm not massively knowledgeable on DirectInput - there may be a way to override the various API controls in use via DLL redirection and the like, which may be simpler than the way I've described.
There is vJoy opensource project: http://sourceforge.net/projects/vjoystick/ - can be worth looking at.
The easiest solution may be to emulate an XInput device (Xbox 360 and One). These are supported in most modern games and the set up is very simple. Here is a C++ project here that provides this without any installed drivers or external dependencies: https://github.com/shauleiz/vXboxInterface/
I know it is an old question but for anyone which is interested in this topic it is also worth looking at this project called ViGEm.
You can emulate some well known gamepads like Microsoft Xbox 360 Controller, Sony DualShock 4 Controller and Microsoft Xbox One Controller. The project offers also some API to interact with these virtual controllers. E.g. the C# API can be found here
The simplest solution I found was using vJoy and its C# wrapper.
You need to download the vJoy driver from here.
You can use the vJoy SDK for implementing a feeder program: https://github.com/njz3/vJoy/tree/master/SDK/c%23
Use the C# starter project for this, or simply add the two .dll-s to your existing project as references from the x86 or x64 folder.
You can find instructions on how to use the api in the readme.odt file.