All Documents By ID

All Documents By ID

ID Subject Product Version
1 What is WinDriver? WinDriver
2 Enabling legacy PCI configuration space read/write for identifying PCI
devices on Windows
WinDriver 10.3.1 and above
3 Preallocating contiguous DMA buffers on Windows WinDriver 11.1.0 and above
4 What operating systems and their respective versions does WinDriver support? WinDriver
5 Building WinDriver with custom version information WinDriver 11.1.0 and below
6 Using WinDriver to develop a graphical Win32 or MFC application WinDriver
7 WinDriver for Windows NT 4.0 — supported service pack WinDriver 8.0.2 and below
8 When trying to install WinDriver v5.2.0 on my PC, using the Linux
RedHat 7.2 distribution, I gotunresolved symbol errors pertaining to alloc_kiovec() and free_kiovec(). How can I resolve these errors?
WinDriver 5.2.X
9 What are the limitations of the WinDriver evaluation kits? WinDriver
10 Does WinDriver support development in C#? WinDriver 7.0.0 and above
11 Can WinDriver be used to develop for the Windows Embedded CE 6.0 operating system? WinDriver
12 What is the wddebug_gui Debug Monitor utility and how can I use it? WinDriver
13 What is the wddebug Debug Monitor utility and how can I use it? WinDriver
14 How do I use the Debug Monitor utility on VxWorks? DriverBuilder 5.4 and below
15 What is the pci_dump utility and how do I run it? WinDriver
16 Can WinDriver handle multiple devices, of different or similar types, at the same time? WinDriver
17 How can I improve my driver’s performance with WinDriver? WinDriver
18 Can WinDriver group I/O and memory transfers? WinDriver
19 Debugging your driver code with WinDriver WinDriver
20 Can I run two different device drivers, both developed with WinDriver, on the same machine? WinDriver
21 What is the significance of marking a resource as ‘shared’ with WinDriver, and how can I verify the ‘shared’ status of a specific resource on my card? WinDriver
22 Does WinDriver support the Real Time Linux operating system? WinDriver
23 Can I use WinDriver to access AGP devices? WinDriver
24 If a variable requires a pointer to be assigned to it, as in
pBuffer = &dwVal, how do I do it in
Visual basic (which does not support pointers)?
WinDriver 11.1.0 and below
25 I am trying to install WinDriver v5.0.5 on a machine running Linux SuSE 8.0, which uses the 2.4.18-4 Linux kernel. But the ‘make install’ command fails with this error:

unresolved symbol kmap_pagetable

WinDriver 5.2.0 and below
26 Can I use WinDriver to define additional serial/parallel ports, using a PLX card? WinDriver 6.2.3 and below
27 How do I detect the location of my USB device on my Windows PC? WinDriver 6.2.0 and above
28 What is the Kernel PlugIn for WinDriver? WinDriver
29 Is the Kernel PlugIn available for all operating systems? WinDriver
30 What is the development process for the Kernel PlugIn? WinDriver
31 When trying to build my Kernel PlugIn project I get the following errorkptest.obj : error LNK2001: unresolved external symbol __chkstkHow can I resolve this? WinDriver
32 I would like to execute in the kernel some pieces of code written in Delphi or in Visual Basic, using the Kernel PlugIn. Is it possible? WinDriver 11.1.0 and below
33 Using DebugView to monitor debug output WinDriver
34 How do I allocate locked memory in the kernel that can be used inside the interrupt handler? WinDriver
35 When trying to build my WinDriver application from MS Visual Studio, I get the following error:int_io.obj : error LNK2001: unresolved external symbol __beginthreadexHow can I resolve this? WinDriver
36 How can I use WinDriver to generate a diagnostics driver code for
Borland C++ Builder 6.0?
WinDriver 11.1.0 and below
37 What is pIntContext in the Kernel PlugIn interrupt functions? WinDriver
38 I need to call WD_Transfer() and
WD_UsbTransfer() in the Kernel PlugIn. From where do I get hWD to pass to these functions?
WinDriver
39 A restriction in KP_IntAtIrql is to use only non-pageable
memory. What does this mean?
WinDriver
40 How do I call WD_Transfer() in the Kernel PlugIn interrupt handler? WinDriver
41 How do I share a memory buffer between Kernel PlugIn and user-mode projects for DMA or other purposes? WinDriver
42 How do I send a GET_DESCRIPTOR request to my device, using WinDriver? WinDriver
43 Developing 32-bit Applications for 64-bit Architectures WinDriver 9.2.1 and above
44 Sending debug information from WinDriver’s kernel module to a kernel debugger WinDriver 5.0.4 and above
45 What are the COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros and when should they be used? WinDriver
46 Why does my WD_KernelPlugInOpen() call fail? WinDriver
47 Does WinDriver support Scatter/Gather DMA on Linux? WinDriver 5.2.0 and above
48 What is the interrupt latency of WinDriver? WinDriver
49 Replacing the driver for PCI/USB devices on Windows 2000: I tried to
install new INF files for my Plug-and-Play devices on Windows 2000, using
wdreg, but the OS keeps installing the old INF files from a
previous WinDriver version. How can I resolve this?
WinDriver 6.0.2–10.3.0
50 WinDriver Operating Systems Support — Versions Overview WinDriver
51 How do I port a DOS driver, which uses inp() and
outp() calls to access the card, into a Windows driver?
WinDriver
52 How many I/O and memory spaces does WinDriver support on a single board? WinDriver
53 How do I reset my USB device using version 5.2.2 of WinDriver? WinDriver 5.0.4–5.2.2
54 Sample InstallShield procedure for installing the driver on a Windows machine WinDriver 5.2.2 and below
55 Buffer Overrun Error: WDU_Transfer() sometimes returns the
0xC000000C error code. What does this error code mean?
How do I solve this problem?
WinDriver 6.0.0 and above
56 Windows XP crashes (BSOD) when I listen to an isochronous pipe on my USB device. WinDriver
57 Driver installation on Plug-and-Play systems (Windows 98/Me/2000/XP) — WinDriver version 5.0.5 and earlier WinDriver 5.0.5 and below
58 My attempt to allocate and lock a 1GB DMA buffer with WinDriver, on
Windows, fails. Is this a limitation of the operating system?
WinDriver
59 I have run into a problem accessing 32MB of memory on a PCI card.
WD_CardRegister() fails to map the memory.The problem does not occur if I try to access 16MB of memory on my card.
WinDriver
60 Can WinDriver be used in order to develop a network driver for Windows CE? WinDriver
61 I am trying to install WinDriver on my Linux machine, but when I insert the WinDriver module (windrvr6.o) into the kernel I get errors regarding kernel version mismatch or unresolved symbols. How can I resolve this? WinDriver
62 Kernel PlugIn Driver Installation — General Guidelines WinDriver
63 When compiling the WinDriver module on Linux machine, I get the following error:usr/include/linux/modversions.h:1:2: #error Modules should never usekernel-headers system headers, but headers from an appropriate kernel-source WinDriver 6.2.2 and below
64 Linux contiguous-buffer DMA allocations — 128KB limitation WinDriver 8.0.1 and below
65 WinDriver For Solaris — 32-bit Architecture Support WinDriver 9.0.1 and below
66 WinDriver for Solaris SPARC — 33Mhz * 33MB PCI Bus Support WinDriver 9.0.1 and below
67 Can I use DriverBuilder to develop an Ethernet network driver for VxWorks? DriverBuilder 5.4 and below
68 I am trying to use DriveBuilder for VxWorks, but I fail downloading
windrvr.o to the target. I get a message that the following symbols were unresolvedpciConfigInlong,
pciConfigOutLong.
DriverBuilder 5.4 and below
69 I am using DriverBuilder for VxWorks. I loaded pci_diag.out and ran
 pci_diag_main, but if failed with the following error message:
Error loading driver
DriverBuilder 5.4 and below
70 What are the names of the entry points routines for your various DriverBuilder
VxWorks sample programs: wddebug.out, pci_dump.out,
etc.?
DriverBuilder 5.4 and below
71 When running the PCI diagnostics application on a VxWorks machine, I get
the following error message when trying to open the board:
Card does not have all items expected for MyDrive.
DriverBuilder 5.4 and below
72 I run pci_dump.out on a VxWorks machine and it shows my card
having all zeros in the BARs. But when I plug the card into a Windows PC,
the BARs have values.
DriverBuilder
73 WD_CardRegister() failed to lock a 32MB memory range on my PCI
card. The following messages appeared in the Debug Monitor log:
Map_physical_mem_krnl: MmMapIoSpace failed …
WinDriver
74 How do I access the memory on my PCI card using WinDriver? WinDriver
75 How do I handle PCI Interrupts from a user-mode WinDriver application? WinDriver
76 How do I perform PCI DMA Writes from system memory to my card, using WinDriver? WinDriver
77 How do I perform Direct Block transfers from one PCI card to another? WinDriver
78 Using WinDriver on Linux, I find that I need to reload the driver module (windrvr6.o) after each reboot. How can I set up dynamic loading of windrvr6.o? WinDriver
79 Does WinDriver support 64-bit data transfers? WinDriver 5.2.0 and above
80 I have a PLX 9050 card, but I cannot access the card’s memory with WinDriver’s PLX 9050 diagnostics utility. I am using the P9050_Read/WriteXXX() functions. WinDriver 6.2.3 and below
81 The values of all the registers on my PLX 9050 card are zero. What could be the reason? WinDriver 6.2.3 and below
82 How can I use the PLX burst mode to increase the read speed? WinDriver
83 When using multiple PLX 9050 cards I occasionally get the error Do_card_lock failed: item already in use, and pci_dump indicates a memory resource overlap in BAR0. I can sometimes resolve this by moving cards to other PCI slots. WinDriver
84 Upgrading your WinDriver version WinDriver 8.1.1 and above
85 How do I extract the string descriptors contained in the Device and Configuration descriptor tables? WinDriver 6.2.2 and above
86 How do I detect that a USB device has been plugged in or disconnected? WinDriver
87 How do I setup the transfer buffer to send a null data packet through the control pipe? WinDriver
88 Can I write a driver for a USB hub or a USB Host Controller card using WinDriver? WinDriver
89 WinDriver driver distribution to a target Windows machine — versions 4.2.0–5.0.5b WinDriver 4.2.0–5.0.5b
90 Installing an INF file for PCI/USB devices on Windows Plug and Play systems in WinDriver versions 4.20–5.05 WinDriver 4.2.0–5.0.5
91 Does WinDriver USB support isochronous streaming mode? WinDriver 9.0.0 and above
92 I used the DriverWizard to listen to the floppy disk interrupt (IRQ 6) successfully on my Windows machine. But when I try to listen to the mouse interrupt (IRQ 12) or to the keyboard interrupt (IRQ 1), I get the following error message: Cannot enable interrupt — might be in use by another device WinDriver
93 WinDriver installation on Linux RedHat 7.3 kernel version 2.4.18-4 gives this error: linux_wrappers.c:405: too few arguments to function ‘do_munmap_Rd007fc14’   make:*** [LINUX.2.4.18-3/linux_wrappers.o] WinDriver 5.2.1 and below
94 Does WinDriver support development of drivers for CardBus devices? WinDriver
95 Does WinDriver support development for PCMCIA devices? WinDriver 6.2.2 and above
96 Is it possible to write my own parallel port driver using WinDriver? WinDriver
97 Can WinDriver share the Parallel/Serial port with Windows’ drivers? WinDriver
98 Can I access the same device, simultaneously, from several WinDriver applications? WinDriver
99 Programming the Serial Port — a brief introduction WinDriver
100 The card I want to drive currently has an interrupt service routine in DOS/16-bit. How do I create a 32-bit interrupt routine for my card? WinDriver
101 I need to be able to count the number of interrupts occurring and possibly call a routine every time an interrupt occurs. Is this possible with WinDriver? WinDriver
102 Does WinDriver poll the interrupt (Busy Wait)? WinDriver
103 Can I write to disk files during an interrupt routine? WinDriver
104 How can I read the value of the PCI interrupt status register from my WinDriver ISR, in order to determine, for example, which card generated the interrupt when the IRQ is shared between several devices? WinDriver
105 Listening to PCI interrupts with the DriverWizard WinDriver
106 How do I perform system or slave DMA using WinDriver? WinDriver
107 When performing data transfers with WD_UsbTransfer(), what is the significance of the USB_SHORT_TRANSFERand USB_FULL_TRANSFER flags (versions 5.0.4–5.2.2)? WinDriver 5.0.4–5.2.2
108 Performing large PCI memory data transfers WinDriver
109 I fail to use windrvr.vxd from WinDriver v5.0.5 on Windows 98; the Debug Monitor has this message: USB is not implemented on this OS.
The windrvr.sys driver works well.
WinDriver 6.0.3 and below
110 When installing WinDriver v5.0.5 on my Linux machine, I get the following warning:
Warning:loading /lib/modules/misc/windriver.o will taint the kernel:
no license
WinDriver 5.0.5 and below
111 Distributing your WinDriver v5.2.x based driver to a target Windows machine WinDriver 5.2.X
112 Porting a Kernel PlugIn project developed prior to version 10.3.0, to support working with a 32-bit user-mode application and a 64-bit Kernel PlugIn driver WinDriver
113 Distributing your KernelDriver based driver to a target Windows machine (versions 5.2.x–6.1.x)
the BARs have values.
KernelDriver 5.2.2–6.1.x
114 KernelDriver USB for Windows NT 4.0 (version 5.1.x) — Distributing Your Driver KernelDriver 5.1.X
115 How can I improve the rate of the interrupt handling when using DriverBuilder for VxWorks? WinDriver 5.2.2–5.4
116 WinDriver PCI/ISA API Version Changes WinDriver
117 WinDriver USB API Version Changes WinDriver
118 I tried to generate Delphi code for my USB device with the DriverWizard from version 6.0.0 of WinDriver, but it seems that not all the relevant files are generated? WinDriver 6.0.0–6.0.1
119 I used the DriverWizard from version 6.0.0 of WinDriver to generate Visual Basic code for my USB device, but while WDU_Transfer() works correctly, the specific transfer functions — WDU_TransferBulk(), etc. — are not working as expected WinDriver 6.0.0
120 Distributing your WinDriver-based driver to a target Windows PC — WinDriver Version 8.1.x–11.8.0 WinDriver 8.1.x–11.8.0
121 What to do in case of of an OS crash on Windows when using WinDriver WinDriver
122 PCI Transfers WinDriver
123 Parallel ports on Windows XP WinDriver
124 When trying to intsall WinDriver on my Windows PC I got the following error:
16-bit MS-DOS Subsystem path to the program that you are trying to start or installC:\Winnt\System32\autoexec.nt
The system file is not suitable for running MS-DOS and Microsoft Windows applications.
WinDriver 6.2.3 and below
125 Handling shared PCI interrupts in the Kernel PlugIn WinDriver
126 Does WinDriver support the PCI Express (PCIe) bus? WinDriver
127 WinDriver Upgrade: Version 6.2.x -> Version 7.x and above WinDriver 6.2.x and above
128 Does WinDriver support development of drivers for the .NET framework? WinDriver 7.0.1 and above
129 Reserving and locking physical memory on Windows and Linux WinDriver
130 Distributing your WinDriver-based driver to a target Windows PC — WinDriver version 8.0.x WinDriver 8.0.x
131 Upgrading from WinDriver version 7.x–8.1.0 to a newer version WinDriver 11.9.0 and above
132 Distributing your WinDriver-based driver to a target Windows PC WinDriver 11.9.0 and above
133 Technical Document #133: WinDriver Server API WinDriver 11.9.0 and above
134 The XDMA sample code WinDriver 12.3.0 and above
135 Temporary disabling digital signature enforcement in Windows 10 WinDriver

 

 

Back To Top

Bus

Technical Document #1: What is WinDriver?

The WinDriver toolkit is ideal for PCI/cPCI/CardBus/PCMCIA/PCI-X/PCI Express/ISA/ISA PnP/EISA and USB device-driver development. (References to “PCI” in this document should be taken to refer also to the cPCI, CardBus, PCMCIA (Windows), PCI-X and PCI Express buses).

WinDriver supports I/O operations, access to memory mapped cards, hardware interrupts handling, DMA transfers, read/writes from USB pipes, Plug and Play and power management events handling and multi-board handling.

The code you develop with WinDriver will be cross-platform compatibleacross all the supported operating systems for the version that you are using. For a list of the supported operating systems for each version, please refer to Technical Documents #4 and #50.

WinDriver supports development for ALL PCI chip-sets and USB devices. In addition, it features enhanced support for major PCI chip vendors (such as PLX, Altera, and Xilinx), and earlier versions also include enhanced support for major USB development board manufacturers (such as Cypress), thereby hiding most of the intrinsic bus details from the user and allowing you to concentrate on your device-specific logic. For more information regarding this enhanced support, refer to the WinDriverproduct page and to the WinDriver User’s Manuals for your version of WinDriver.

You can use WinDriver’s powerful graphical DriverWizard utility to easily detect/define the hardware’s resources and debug your hardware, by transferring data to/from the hardware, listening to interrupts, etc., without writing a single line of code.

You can also use the DriverWizard to generate skeletal diagnostics code for your device, which will provide you with convenient wrapper functions that utilize WinDriver’s API to communicate with your specific device. Furthermore, you can review the various samples provided with WinDriver to see if there is a sample that may serve as a skeletal basis for your driver application.

WinDriver enables all development to be done in the user mode and frees you of the need for any kernel and/or OS-specific driver development knowledge, such as familiarity with the Windows Driver Kit (WDK). For a description of WinDriver’s basic architecture, refer to the WinDriver User’s Manual.

For PCI/ISA development, after you develop your application in the user mode, you will also be able to use WinDriver’s special Kernel PlugInfeature (described in the WinDriver User’s Manual) to simply move performance-critical parts of your code from your application or DLL (in Ring 3) to the kernel level (Ring 0) for optimal performance.

To help you in your initial steps with WinDriver, visit the WinDriver Support page for online tours and quick-start guides as well as other useful information, which can facilitate your development process.

Back To Top

Technical Document #2: Enabling legacy PCI configuration space read/write for identifying PCI devices on Windows

In version 6.2.0 of WinDriver, the PCI configuration space read/write method on Windows was upgraded to a more advanced method. On rare occasions, this method fails to identify some PCI devices. To resolve this problem, beginning with version 10.3.1 of WinDriver you can revert to the legacy PCI configuration space read/write method by doing the following:

    1. Set the PciCfgRwCompat registry key flag in the WinDriver driver INF file — default: windrvr<version>.inf (e.g.,windrvr1200.inf) / windrvr6.inf in earlier versions — to 1:
      <span style="color: #a020f0;">HKR, Parameters, PciCfgRwCompat, <span style="color: magenta;">0x00010001, <span style="color: magenta;">1Beginning with version 11.1.0 of WinDriver, the driver INF file contains a similar line, which sets the PciCfgRwCompat flag to 0 (default), so you only need to modify the value of the flag in the existing line to 1.

 

  1. Open a command-line prompt and reinstall the driver by running the following commands from the WinDriver\util\wdreg directory (where “WinDriver” is the path to your WinDriver installation directory):
    $ wdreg -inf <path to your device INF file> uninstall
    $ wdreg -inf <path to the driver INF file> uninstall
    $ wdreg -inf <path to the driver INF file> install
    $ wdreg -inf <path to your device INF file> install

Back To Top

Technical Document #3: Preallocating contiguous DMA buffers on Windows

The WinDriver DMA APIs do not limit the size of allocated DMA buffers. However, the success of the DMA allocation is dependent on the amount of available system resources at the time of the allocation. Therefore, the earlier you try to allocate the buffer, the better your chances of succeeding.
Beginning with version 11.1.0 of WinDriver for Windows, you can configure your device INF file to preallocate at boot time contiguous host-to-device and/or device-to-host DMA buffers, thus increasing the odds that the allocation(s) will succeed.
Up to version 12.3.0 (including) up to two DMA buffers are supported, one for each direction.
Beginning with version 12.4.0 of WinDriver for Windows, you can preallocate a maximum of 512 buffers (256 device-to-host and 256 host-to-device).
To preallocate contiguous DMA buffers on Windows, follow these steps:

  1. Add the required configuration under the [UpdateRegistryDevice] registry key in your device INF file, as shown below. To preallocate eight unidirectional buffers, add these lines:
; Host-to-device DMA buffer:
HKR,, "DmaToDeviceCount",0x00010001,0x04       ; Number of preallocated DMA_TO_DEVICE buffers 
HKR,, "DmaToDeviceBytes",0x00010001,0x100000   ; Buffer size, in bytes
HKR,, "DmaToDeviceOptions",0x00010001,0x41     ; DMA flags (0x40=DMA_TO_DEVICE
                                               ; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
                
; Device-to-host DMA buffer:
HKR,, "DmaFromDeviceCount",0x00010001,0x04     ; Number of preallocated DMA_FROM_DEVICE buffers 
HKR,, "DmaFromDeviceBytes",0x00010001,0x100000 ; Buffer size, in bytes
HKR,, "DmaFromDeviceOptions",0x00010001,0x21   ; DMA flags (0x20=DMA_FROM_DEVICE
                                               ; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
NOTE
  • "DmaFromDeviceCount" and "DmaFromDeviceCount" values are supported from version 12.4.0. If those values aren’t set value of 1 will be assumed.
    In older WinDriver versions those values are ignored and a single buffer will be pre-allocated.
  • The wizard-generated and relevant sample WinDriver device INF files already contain the unidirectional buffers configuration lines, so you only need to remove the comment indicator (‘;’) at the start of each line.
  • The examples are for configuring preallocation of 8 DMA buffers (4 for each direction), but you may, of-course, select to preallocate just one buffer (or none at all, by leaving the above code commented out).

2. Edit the buffer sizes and add flags to the options masks in the INF file, as needed. Note, however, that the direction flags and the DMA_KERNEL_BUFFER_ALLOC flag must be set as shown in Step 1.

NOTE
The supported WinDriver DMA flags are documented in the WinDriver PCI User’s Manual. To locate the relevant flag values to set in the INF file, look for the flag definitions in the<WinDriver directory>\include\windrvr.h file; (look for the enum that contains the DMA_KERNEL_BUFFER_ALLOC flag).

 

3. In your code, the first call or the first two calls (if you configured the INF file to preallocate two DMA buffers) to the contiguous-DMA-lock function — WDC_DMAContigBufLock() or the low-level WD_DMALock() function — should set parameter values that match the buffer configurations in the INF file:

  • For a device-to-host buffer, the DMA-options mask parameter (dwOptions / pDma->dwOptions) should contain the same DMA flags set in the DmaFromDeviceOptions registry key value, and the buffer-size parameter (dwDMABufSize / pDma->dwBytes) should be set to the value of the DmaFromDeviceBytes registry key value.
  • For a host-to-device buffer, the DMA-options mask parameter (dwOptions / pDma->dwOptions) should contain the same flags set in the DmaToDeviceOptions registry key value, and the buffer-size parameter (dwDMABufSize / pDma->dwBytes) should be set to the value of the DmaToDeviceBytes registry key value.

NOTE

  • In calls to WDC_DMAContigBufLock(), the DMA configuration information is provided via dedicated function parameters — dwDMABufSize and dwOptions.
    In calls to WD_DMALock(), the information is provided within the fields of the WD_DMA struct pointed to by the pDma parameter — pDma->dwBytes and pDma->dwOptions.
  • When using WDC_DMAContigBufLock(), the DMA_KERNEL_BUFFER_ALLOC flag is automatically set by the function, so you do not need to set it explicitly in the DMA-options mask parameter (as you do when using the low-level WD_DMALock() function), even though it is set in the INF-file configuration.
  • If the buffer preallocation fails due to insufficient resources, you may need to increase the size of the non-paged pool (from which the memory is allocated), as explained in Technical Document #58.

Back To Top

Technical Document #4: What operating systems and their respective versions does WinDriver support?

This document outlines the operating systems support in the latest WinDriver versions.

NOTE
OS-specific support is provided only for operating systems with official vendor support.

PCI/ISA

WinDriver PCI supports the following operating systems:

  • Windows:
    Windows 10/8.1/8/7/Server 2016/Server 2012 R2/Server 2012/Server 2008 R2/Server 2008
  • Linux:
    Any x86 32-bit or 64-bit (x86_64) processor, with a 2.6.x or higher Linux kernel.

USB

WinDriver USB supports the following operating systems:

  • Windows:
    Windows 10/8.1/8/7/Server 2016/Server 2012 R2/Server 2012/Server 2008 R2/Server 2008
  • Linux:
    Any x86 32-bit or 64-bit (x86_64) processor, with a 2.6.x or higher Linux kernel.

 
NOTE: Jungo Connectivity strives to support new Linux kernel versions as close as possible to their release. To find out the latest supported kernel version, refer to the latest WinDriver release notes.

For more information relating to when the support for each operating system and the related service packs was introduced, please review Technical Document #50.

Back To Top

Technical Document #10: Does WinDriver support development in C#?

Yes. Beginning with version 7.0.0 WinDriver provides specific support for development of .NET drivers, including development in C#.
For information on WinDriver’s general support for the .NET framework, refer to Technical Document #128.

The WinDriver .NET API DLLwdapi<version>_dotnet.dll (e.g.,wdapi800_dotnet.dll in WinDriver v8.0.0) provides a .NET version of the high-level WinDriver APIs, implemented using managed extensions for C++. This DLL can be used to develop a driver in any .NET language, including C#. The DLL file is found under the WinDriver\lib\<CPU>\<.NET version> directory (e.g., WinDriver\lib\x86\v1.1.4322) and its source code is found under the relevant WinDriver\src\wdapi.net directory.

v7.0.x Note: In v8.0.0 of WinDriver we added both versioning and 64-bit support to the DLL, which resulted in a different DLL name and new locations for the related files. In versions 7.0.1 and 7.0.2 of WinDriver the name of the DLL was wdapi_dotnet and in v7.0.0 its name waswdnetlib.dll. In all 7.0.x versions the DLL could be found both under theWinDriver\lib and WinDriver\redist directories and its source code was found under the WinDriver\wdapi.net directory.

Beginning with v8.0.0 of WinDriver you can use WinDriver’s DriverWizard utility to generate C# driver code for both USB and PCI devices.

WinDriver also includes the following .NET C# samples, which utilize the WinDriver .NET API DLL:

  • USB:
    • The WinDriver\csharp.net\usb_sample directory contains a C# USB library (usb_lib_dotnet.dll) and a sample C# USB diagnostics application (csharp_usb_sample.exe).
  • PCI:
    • The WinDriver\csharp.net\pci_sample directory contains a C# PCI library (pci_lib.dll) and a sample C# PCI diagnostics application (pci_sample.exe).
    • The WinDriver\plx\dotnet directory contains a C# library (plx_lib_dotnet.dll) and a sample C# diagnostics application (PLX_Sample.exe), designed specifically for handling PLX devices.

To develop a C# driver with WinDriver, either use DriverWizard to generate a diagnostics C# driver application for your device, or use the WinDriver C# sample that most matches your design, and then modify the generated/sample code in accordance with your hardware specification and desired driver functionality. Alternatively, you can use the generated/sample code as a reference for writing your own WinDriver C# driver.

Back To Top

Technical Document#15: What is the pci_dump utility and how do I run it?

pci_dump is a sample utility program that is provided with the WinDriver tool-kit and enables you to dump the contents of the PCI configuration registers into a readable format. It can be found in the WinDriver/utildirectory.

The source code of this utility is provided as well and can be found at:WinDriver/samples/pci_dump/pci_dump.c.

By default, the program’s output will be presented in a console window.

To log the pci_dump output into a file (dump.txt), do the following:

1. Open a command prompt window.

 

2. Run pci_dump as pci_dump > dump.txt.

 

3. Hit ENTER continuously, until the program’s execution is completed.

At the end of this process you wil have a dump.txt file in theWinDriver/util directory (from which pci_dump was run).

Back To Top

Technical Document #16: Can WinDriver handle multiple devices, of different or similar types, at the same time?

Yes. Each device receives a unique handle when callingWD_CardRegister() (for PCI/PCMCIA/ISA) or WDU_Init() (for USB with v6.0 of WinDriver) / WD_UsbDeviceRegister() (for USB with v5.2.2 and earlier of WinDriver).

This enables different devices to be handled from a single device driver application.

This also enables device drivers written with WinDriver for different devices, to coexist simultaneously on the same machine.

Starting from WinDriver 6.2.0, the usb_diag sample and the generated DriverWizard code have basic support for multiple devices.

Back To Top

Technical Document #17: How can I improve my driver’s performance with WinDriver?

The performance of the driver you develop and the data-transfer rate are dependent on the specific OS, the hardware, and the driver design.
Following are some suggestions for improving your driver’s performance with WinDriver:

For PCI/PCIe/CardBus/PCMCIA/ISA

NOTE

  • “PCI” references below include PCI Express (PCIe), PCMCIA. and CardBus.
  • For detailed information on how to access PCI and ISA addresses and improve your performance with WinDriver, and for a full WinDriver PCI/ISA API reference, refer to the WinDriver PCI User’s Manual.
    For a description of the low-level WD_xxx APIs, refer to the WinDriver PCI Low-Level API Reference.

For PCI devices, use memory rather than I/O mapped ranges in your hardware design, as it is much faster to access memory than I/O.

In general, it’s faster to access memory addresses directly. You can use the WinDriver WDC_MEM_DIRECT_ADDR macro to receive the relevant direct memory region mapping for a card previously registered usingWDC_PciDeviceOpen() / WDC_PcmciaDeviceOpen() / WDC_IsaDeviceOpen()(depending on your hardware), and then access the memory directly by passing this address to one of the WDC_ReadMemXXX or WDC_WriteMemXXXmacros, or to one of the WDC_ReadAddrXXX() or WDC_WriteAddrXXX()functions (not including WDC_ReadAddrBlock() / WDC_WriteAddrBlock() — see later below).
(When using the low-level WinDriver API, use the direct user-mode memory-range mapping returned by WD_CardRegister() incardReg.Card.Item[i].I.Mem.pUserDirectAddr / dwUserDirectAddr before v11.8.0.)

When accessing I/O addresses, or when transferring a large amount of data from/to memory, you might improve the performance by implementing block (string) transfers, using WDC_ReadAddrBlock() orWDC_WriteAddrBlock() (or the low-level WD_Transfer() function with a string command), and/or by grouping several transfers into a single function call using WDC_MultiTransfer() (or the low-levelWD_MultiTransfer() function); (for small memory data transfers, direct memory access is generally more efficient).
The block transfers translate to assembler string instructions, which may further improve the performance by initiating PCI burst mode, if supported by the hardware.
If you need to transfer more than 64 bits of data in a single burst, you may be able to improve the performance using 64-bit transfers, which can be implemented with WinDriver using QWORD string (block) transfers. This can be especially useful on 32-bit host platforms. Note, however, that the ability to perform actual 64-bit transfers is dependent on the hardware components involved in the transfer, as explained in the WinDriver PCI User’s Manual.
For more information on PCI block transfers (including PCI burst and64-bit transfers), refer to Technical Document #108.

When performing large memory transfers it’s preferable to use PCI bus-master direct memory access (DMA), when possible, as it is generally faster than PCI target access (such as that used in the other memory-access methods described above); see also Technical Document #108. For detailed instructions on how to use the WinDriver APIs (namely, theWDC_DMAxxx() or low-level WD_DMAxxx() functions) to implement DMA for PCI devices capable of acting as bus masters, refer to the WinDriver PCI User’s Manual.

To further improve the driver’s performance, you can use WinDriver’sKernel PlugIn feature to move performance-critical sections of your code from the user mode to the kernel, thereby improving the overall performance of your driver. This feature will allow you, for example, to handle interrupts directly in the kernel (see also Technical Document #48 regarding the Kernel PlugIn interrupt latency). A detailed description of the Kernel PlugIn feature can be found in the WinDriver User’s Manual.
The Kernel PlugIn is not supported on Windows CE and VxWorks, since these operating systems do not distinguish between user and kernel mode. On VxWorks (last supported in WinDriver v5.2.2) you can improve the interrupt handling rate by using the windrvr_isr callback function, as explained in the manual and in Technical Document #115.

For USB

NOTE
For detailed information on how to perform USB transfers and improve your performance with WinDriver, and for a full WinDriver USB API reference, refer to the WinDriver USB User’s Manual.

To increase the data transfer rate you can try replacing several data transfers, which use relatively small data buffers, with a single transfer that uses a big data buffer, thereby eliminating some of the function-call overhead and reducing the context switches between the user and kernel mode.
(The size of the data buffer is set in the dwBufferSize parameter of theWDU_Transfer() function.)
NOTE: The size of the buffer used in the calls to WDU_Transfer() is not limited to the maximum packet size for the device, although we recommend that you use buffer sizes that are multiples of the maximum packet size.

You might also be able to improve the transfer rate by modifying the device’s firmware (for example, by increasing the maximum packet size for the hardware).

Back To Top

Technical Document #18: Can WinDriver group I/O and memory transfers?

Yes. Using WinDriver, you can group I/O and memory transfers by callingWD_MultiTransfer(), which can perform multiple transfers in one call.

Note that you can also access the memory directly from your user-mode application using the virtual user-mode mapping of the physical address, which is returned by WD_CardRegister() incardReg.Card.Item[i].I.Mem.pUserDirectAddr (or dwUserDirectAddrbefore v11.8.0), where ‘i’ is the index item of the relevant memory item in the WD_ITEMSItem‘ array.

For suggestions on how to improve the performance of your driver with WinDriver, refer to Technical Document #17.

Back To Top

Technical Document #20: Can I run two different device drivers, both developed with WinDriver, on the same machine?

Yes. You can run several WinDriver-based applications simultaneously on the same machine. (With regard to accessing the same hardware from several applications, please refer to Technical Document #98.)

Until version 11.5.0, code developed with an earlier version of WinDriver could run with the drivers from a newer version as well (provided the code wasn’t recompiled with newer header files using the old license). At most, you may have needed to update the INF files for PCI/USB devices when upgrading the driver on a Plug-and-Play OS.
Staring from version 11.5.0, code developed with an earlier version needs to be recompiled with a new license that matches the version of the newer WinDriver driver with which you want to use the code. See additional information in Technical Document #84,

Note that code developed with a newer version of WinDriver was never guaranteed to work with an older driver file. You should, therefore, take care, when distributing your driver, that the installation process does not overwrite a newer version of the WinDriver module —windrvr.sys/.o/.ko/.dll (orwindrvr6.sys/.o/.ko/.dll/.vxd / windrvr.sys/.vxd/.o, in earlier versions of WinDriver), or a renamed version of the driver — with an older version of the driver file. This is also true for the WinDriver USB Linux GPL driver — windrvr_usb.o/.ko (previouslywindrvr6_usb.o/.ko; from WinDriver v10.0.0 and above).

NOTE
In version 6.0 of WinDriver we renamed the WinDriver kernel module from windrvr to windrvr6. In version 11.9.0 we renamed the default kernel module to windrvr (e.g.,windrvr1200). WinDriver kernel modules with different names can be used simultaneously on the same machine.

Back To Top

Technical Document #21: What is the significance of marking a resource as ‘shared’ with WinDriver, and how can I verify the ‘shared’ status of a specific resource on my card?

The “shared” status determines whether the resource is locked for exclusive use.
When a memory, I/O, or interrupt item is defined as non-sharable, the device registration function — WDC_PciDeviceOpen() /WDC_PcmiaDeviceOpen() / WDC_IsaDeviceOpen(), or the low-levelWD_Card_Register() function — checks whether the resource is already locked for exclusive use: If it is, the registration fails; otherwise, the resource is locked exclusively, and any subsequent attempt to lock the resource — either from within the same application, or from another WinDriver application — will fail, until the resource is released usingWDC_PciDeviceClose() / WDC_PcmiaDeviceClose() / WDC_IsaDeviceClose(), or the low-level WD_Card_Unregister() function.
(Device registers cannot be defined as shared.)

Note that PCI resources, and specifically interrupts, should generally be defined as sharable.
For memory and I/O, the share status defined with WinDriver affects only WinDriver-based applications.
However, for interrupts there is further significance to the share status, since it also determines whether other drivers (not necessarily WinDriver drivers) can lock the same interrupt. For an explanation of how to read the value of the PCI interrupt status register, refer toTechnical Document #104.

Use one of the following methods to check whether a resource is defined as sharable:

    1. From your code, print the value of thefNotSharable flag for the memory/IO/interrupt item that you wish to check —deviceInfo.Card.Item[i].fNotSharable when using the WDC API, or cardReg.Card.Item[i].fNotSharable when using the low-level WinDriver API.
      A value of 1 indicates that the resources is not sharable.
      A value of 0 indicates that the resource is sharable.
  1. If you have used the DriverWizard to generate your code, you can run the DriverWizard, open the *.wdp DriverWizard project file, which served as the basis for your application, select the ‘Memory’, ‘I/O’, or ‘Interrupt’ tab (respectively) and click on ‘Edit’. Then look to see if the ‘Shared’ box in the Resource Information window is checked, to signify that the resource is defined as shared for this device.
    Note that this test is only relevant when using the original *.wdpproject file for your application code, and assuming your code does not modify the ‘shared’ status — since any changes made in the*.wdp file, via the DriverWizard, will only affect subsequent code generation, and will not affect the existing application code. Therefore, checking the “shared” values from the code is more accurate.

As a general guideline, avoid locking the same resource twice. It is always recommend to release a previously locked resource before trying to lock it again (either from the same application, or from different applications).
If you need to access the resources from several applications, you can share the handle received from a single call to the device registration function — WDC_PciDeviceOpen() / WDC_PcmiaDeviceOpen() /WDC_IsaDeviceOpen(), or the low-level WD_Card_Register() function — as explained in Technical Document #98.

Back To Top

Technical Document #22: Does WinDriver support the Real Time Linux operating system?

WinDriver’s Linux kernel drivers — windrvr<version>.o/.ko andwindrvr<version>_usb.o/.ko (windrvr6.o/.ko andwindrvr6_usb.o/.ko / windrvr.o in earlier versions) — are written as generic tools and are not targeted at a specific Linux distribution. Therefore, you should generally be able to use these drivers with different distributions, including Real Time Linux. However, since we did not conduct extensive tests with the Real Time Linux OS, we do not officially support this operating system. You are welcome to download a full-featured evaluation version of WinDriver for Linux and try it with your Real Time Linux distribution to see if it suits your development needs. Please feel free to contact us at any time during your evaluation via our support center, so we might try to assist you in your development efforts.

To find out how to install WinDriver on your Linux machine, please refer to the WinDriver Linux installation instructions.

Back To Top

Technical Document #23: Can I use WinDriver to access AGP devices?

Yes. AGP is a PCI bus, just 4 times faster than the standard PCI bus. It is used for display/video cards, but from a software point of view it looks just like PCI. AGP cards appear as PCI cards to WinDriver, and you are able to perform all operations on them. However, please note that this does not necessarily mean that you will be able to utilize the advanced features of this bus (such as the increased transfer rates) when using WinDriver, since these tools do not currently include any special support for this bus.

Back To Top

Technical Document #26: Can I use WinDriver to define additional serial/parallel ports, using a PLX card?

Yes. You can plug-in the serial/parallel port or modem ISA device to a PLX card, then use WinDriver to write a driver application that loads before Windows’ standard serial/parallel port driver, detects your PCI hardware and its resources, and writes the resources back to the port’s Registry. Then, when the port driver loads, it will install itself also on your serial/parallel port.

A working sample for a serial port driver for Windows NT 4.0, based on the PLX 9050 hardware, can be found in the WinDriver/plx/9050/serial/directory.

Back To Top

Technical Document #27: How do I detect the location of my USB device on my Windows PC?

The USB device location is represented by the device’s HUB identifier and the port in the HUB: Z&ZZZZZZZ&Z&A. Z&ZZZZZZZ&Z is the HUB identifier or PrefixID, and A is the port/address in the HUB (1 to 8).
In order to retrieve the device location ID, you must first retrieve the device instance ID, represented by the device type, Vendor ID, Product ID, HUB ID and port ID: USB\VID_XXXX&PID_YYYY\Z&ZZZZZZZ&Z&A.
DeviceInstanceId is returned by SetupDiGetDeviceInstanceId().

In order to detect the USB device location, do the following:

    1. Get the DriverKeyName by calling WinDriver’sWDU_GetDeviceRegistryProperty() function (orWD_GetDeviceProperty() — for v8.1.2 and below) with theWdDevicePropertyDriverKeyName registry property.

 

    1. Get the ClassGUID, by calling WDU_GetDeviceRegistryProperty() (orWD_GetDeviceProperty()) — in v8.1.2 and below) with theWdDevicePropertyClassGuid property.

 

    1. By using GetDeviceInstanceId() (see later) with the retrievedDriverKeyName and ClassGUID, get the DeviceInstanceId.

 

  1. From the retrieved DeviceInstanceId, get the USB device location, Z&ZZZZZZZ&Z&A.

—————————————————————————————
<span style="color: #0000ff;">/*
 szDriverKeyName is returned by
 WDU_GetDeviceRegistryProperty() /
 WD_GetDeviceProperty().
 It looks like:
  {C671678C-82C1-43F3-D700-0049433E9A4B}\\0017
 szClassGUID is returned by WDU_GetDeviceProperty.
 It looks like:
 {C671678C-82C1-43F3-D700-0049433E9A4B}

 GetDeviceInstanceId() creates a list of the device
 information for all devices of the specified class.
 The function then searches the list for the
 WinDriver device and retrieves the device instance
 ID (*pszDeviceInstanceId).
*/

<span style="color: #cc66ff;">#include <span style="color: #ff00ff;"><windows.h>
#include <setupapi.h>
#include <string.h>

 

BOOL GetDeviceInstanceId(LPCTSTR szClassGUID, LPCTSTR
 szDriverKeyName, PTCHAR *pszDeviceInstanceId)
{
 <span style=”color: #0000ff;”>/* Build class GUID from szClassGUID */
 GUID guid;
 DWORD dwMemberIndex=<span style=”color: #ff00ff;”>0;
 SP_DEVINFO_DATA DeviceInfoData;
 BOOL bResult;
 DWORD dwError;
 DWORD dwPropertyBufferSize;
 PTCHAR pbPropertyBuffer;
 DWORD dwRequiredSize;
 DWORD dwPropertyRegDataType;
 HDEVINFO hDeviceInfoSet;

 StringToGUID(szClassGUID,&guid);

 *pszDeviceInstanceId = <span style=”color: #ff00ff;”>NULL;

 <span style=”color: #0000ff;”>/* Create a list of the device information for all
 devices of the specified class */
 hDeviceInfoSet = SetupDiGetClassDevs(&guid,;
 <span style=”color: #ff00ff;”>NULL, <span style=”color: #ff00ff;”>NULL, DIGCF_PRESENT);

 <span style=”color: #993300;”>if (INVALID_HANDLE_VALUE == hDeviceInfoSet)
 {
 <span style=”color: #0000ff;”>/* Set error */
 <span style=”color: #0000ff;”>/* ……….. */
 <span style=”color: #993300;”>return FALSE;
 }

 <span style=”color: #0000ff;”>/* Search the device information list for
 the WinDriver device */

 DeviceInfoData.cbSize = <span style=”color: #993300;”>sizeof(SP_DEVINFO_DATA);
 <span style=”color: #993300;”>do {
 <span style=”color: #0000ff;”>/* Get the next device in the list */
 bResult =
 SetupDiEnumDeviceInfo(hDeviceInfoSet,
 dwMemberIndex, &DeviceInfoData);

 <span style=”color: #993300;”>if (bResult)
 {
 dwRequiredSize = <span style=”color: #ff00ff;”>0;
 <span style=”color: #0000ff;”>/* Check if there is a driver reg path for this device */

 <span style=”color: #0000ff;”>/* First get the size only */
 bResult = SetupDiGetDeviceRegistryProperty
 (hDeviceInfoSet,
 &DeviceInfoData,
 SPDRP_DRIVER,
 &dwPropertyRegDataType,
 <span style=”color: #ff00ff;”>NULL,
 <span style=”color: #ff00ff;”>0,
 &dwRequiredSize);

 <span style=”color: #993300;”>if (bResult && dwRequiredSize > <span style=”color: #ff00ff;”>0)
 {
 dwPropertyBufferSize =
 dwRequiredSize + 1;

 pbPropertyBuffer =
 (TCHAR *)malloc(sizeof(TCHAR) *
 dwPropertyBufferSize);

 ASSERT(pbPropertyBuffer != <span style=”color: #ff00ff;”>NULL);

 <span style=”color: #0000ff;”>/* Then get this driver’s actual registry path */
 <span style=”color: #993300;”>if (SetupDiGetDeviceRegistryProperty
 (hDeviceInfoSet,
 &DeviceInfoData,
 SPDRP_DRIVER,
 &dwPropertyRegDataType,
 (PBYTE)pbPropertyBuffer,
 dwPropertyBufferSize,
 &dwRequiredSize))
 {
 <span style=”color: #0000ff;”>/* Check if the reg path is the same as in WinDriver */
 <span style=”color: #008000;”>int iResult = _tcscmp(
 pbPropertyBuffer,
 szDriverKeyName);

 <span style=”color: #993300;”>if (iResult == <span style=”color: #ff00ff;”>0)
 {
 <span style=”color: #0000ff;”>/* This is the device we are working with
 using WinDriver */

 /* Get the device’s instance ID */

 /* First get the size only */
 dwRequiredSize = <span style=”color: #ff00ff;”>0;

 bResult =
 SetupDiGetDeviceInstanceId
 (hDeviceInfoSet,
 &DeviceInfoData,
 <span style=”color: #ff00ff;”>NULL,
 0,
 &dwRequiredSize);

 <span style=”color: #993300;”>if (bResult && dwRequiredSize)
 {
 *pszDeviceInstanceId ==
 (TCHAR *)malloc(
 sizeof(TCHAR) *
 (dwRequiredSize + 1));

 ASSERT(*pszDeviceInstanceId
 != <span style=”color: #ff00ff;”>NULL);

 <span style=”color: #0000ff;”>/* Then get the actual device instance id */
 <span style=”color: #993300;”>if (
 !SetupDiGetDeviceInstanceId
 (hDeviceInfoSet,
 &DeviceInfoData,
 *pszDeviceInstanceId,
 dwRequiredSize + <span style=”color: #ff00ff;”>1,
 <span style=”color: #ff00ff;”>NULL))
 {
 dwError =
 GetLastError();
 <span style=”color: #0000ff;”>/* ….. */
 }
 }
 }
 }
 <span style=”color: #993300;”>else
 delete pbPropertyBuffer;             }
 }

 dwMemberIndex++;

 } <span style=”color: #993300;”>while(bResult && !*pszDeviceInstanceId);

 SetupDiDestroyDeviceInfoList(hDeviceInfoSet);

 <span style=”color: #993300;”>return FALSE;
}

Back To Top

Technical Document #30: What is the development process for the Kernel PlugIn?

First, use WinDriver to develop and debug your driver in the user mode. After everything is working, see if there are performance problems related to user-mode overhead. Normally, the problems arise with interrupt handling and accessing I/O-mapped (not memory-mapped) cards (since memory can be accessed directly from the user model, which is very efficient — see Technical Document #74).

Now, follow the instructions in the WinDriver PCI User’s Manual for creating a Kernel PlugIn project and driving it from the user-mode application.
Generally, you have three main options for developing your Kernel PlugIn project (and the corresponding user-mode application that controls it):

    • Use the DriverWizard to generate a skeletal Kernel PlugIn project and user-mode application for your specific device (and then modify it as required). This option is available beginning with version 5.2.0 of WinDriver.

 

    • Use the source code of the sample WinDriver Kernel PlugIn driver (KP_PCI found in the v7.0.0+ WinDriver/samples/pci_diag/kp_pcidirectory; or KPTEST from the WinDriver/kerplug/kptest directory — for older versions of WinDriver) as a skeleton for your kernel project; move code from your user-mode driver to yourKernel PlugIn project; and add calls to your Kernel PlugIn driver from your user-mode application.

 

  • Write your own Kernel PlugIn project “from scratch” (and modify your user- mode application to driver it).

Back To Top

Technical Document #31: When trying to build my Kernel PlugIn project I get the following error: kptest.obj : error LNK2001: unresolved external symbol __chkstk How can I resolve this?

This error is most probably a result of a failed attempt to allocate a relatively big data structure on the stack, within your Kernel PlugIn project, due to the limited size of the kernel stack. To overcome this problem, try allocating the relevant structure dynamically (using malloc()— which is implemented by WinDriver to be used correctly from within the kernel as well), instead of allocating the structure locally on the stack.

Back To Top

Technical Document #32: I would like to execute in the kernel some pieces of code written in Delphi or in Visual Basic, using the Kernel PlugIn. Is it possible?

NOTE
Beginning with version 11.2.0 of WinDriver, Delphi and Visual Basic 6.0 are no longer supported.

WinDriver does not support implementing a Kernel PlugIn project in Delphi or in Visual Basic (VB), since these programming languages should not generally be used for kernel mode development. However, while the Kernel PlugIn application must be written in C, it is possible to write a user mode application in Delphi/VB, which communicates with the C Kernel PlugIn application. If you select to implement such a design, in order to ensure the correct interaction between the user mode and Kernel PlugIn applications, you will need to implement a Delphi *.pas file or a VB*.bas file that contains common definitions for the Kernel PlugIn and user mode applications — as done in the library header files of the sample and DriverWizard generated Kernel PlugIn C projects (e.g.,WinDriver\pci_diag\pci_lib.h, used by the sample KP_PCI driver / or in earlier versions — WinDriver\kerplug\kptest_com.h, used by the sampleKPTEST driver).
You can refer to the implementation of the WinDriver\include\windrvr.h C header file and the corresponding WinDriver\delphi\include\windrvr.pasand WinDriver\vb\include\windrvr.cls files for an example of implementing the same code both in C and in Delphi/Visual Basic (respectively).

Back To Top

Technical Document #37: What is pIntContext in the Kernel PlugIn interrupt functions?

pIntContext is private context data that is passed from KP_IntEnable to the Kernel PlugIn interrupt handler functions — KP_IntAtIrql andKP_IntAtDpc.

Back To Top

Tech Doc #38: I need to call WD_Transfer() and WD_UsbTransfer() in the Kernel PlugIn. From where do I get hWD to pass to these functions?

NOTE
This document refers to low-level WinDriver API. When using the latest versions, you should use the high-level WDC (PCI) or WDU (USB) API.
Note that the Kernel PlugIn feature is not supported for USB in the latest versions.

To obtain the handle to WinDriver’s kernel module (hWD) from the Kernel PlugIn, you can do one of the following:

    • Call WD_Open() directly from the Kernel PlugIn.NOTE: WD_UsbTransfer() is part of WinDriver’s old USB API, which was used until (and including) version 5.2.2. The USB API from version 6.0.0 and above cannot be used from the Kernel PlugIn. When calling one of the old WinDriver USB APIs — such asWD_UsbTransfer() — from the Kernel PlugIn, you must use this option — i.e., call WD_Open() directly in the kernel — in order to get a handle to WinDriver that can be used in the Kernel PlugIn. You cannot use the handle that is passed from the user mode (as suggested in the second option below) with the WinDriver USB functions.

 

  • For PCI/PCMCIA/ISA, you can also use the hWD handle, which is passed from the user mode via WD_KernelPlugInOpen(), and received as the second argument of the Kernel PlugIn callback function KP_Open().Alternatively, you can also pass the handle from the user mode to the Kernel PlugIn using the pData field of theWD_KERNEL_PLUGIN_CALL struct, which is used in the call toWD_KernelPlugInCall() in the user mode and results in a callback to KP_Call() in the Kernel PlugIn.

After obtaining the handle to WinDriver, the call to WD_Transfer() /WD_UsbTransfer() (or any other WinDriver API that receives a handle to WinDriver as a parameter) is the same as in the user mode.

Back To Top

Technical Document #39: A restriction in KP_IntAtIrql is to use only non-pageable memory. What does this mean?

Variables defined in the Kernel PlugIn project (such as global and local variables) are non paged. WinDriver also implements malloc() to allocate non-paged memory when used from within the kernel (see also Technical Document #34). If you are using a pointer to the memory in the user mode from within the Kernel PlugIn, you need to make a copy of it’s contents (allocate memory and copy the data to the non-paged memory) in order to access it from your KP_IntAtIrql function, in order to ensure safe access to the data at all times.

Back To Top

Technical Document #40: How do I call WD_Transfer() in the Kernel PlugIn interrupt handler?

You can call WD_Transfer() from within the KP_IntAtIrql or KP_IntAtDpcfunctions (replace “KP” in the function names with your Kernel PlugIn driver name — e.g., “KP_PCI”) in order to access the hardware (see below).

Please note that you can also access the memory or I/O directly from within the Kernel PlugIn interrupt functions. (For direct memory access, use the kernel mapping of the memory, returned from WD_CardRegister()in cardReg.Card.Item[i].I.Mem.pTransAddr / dwTransAddr before v11.8.0.)

When calling WD_Transfer() you will need to pass as the first argument a handle to WinDriver (hWD). You can refer to Technical Document #38 to find out how to obtain a handle to WinDriver from within the Kernel PlugIn.

As specified in the aforementioned Technical Document, you can store the handle to WinDriver in a global Kernel PlugIn variable (recommended), or pass it from one function to another. Below is an example of passing a handle to WinDriver from KP_Open() to KP_IntAtIrql:

Add the following line to KP_Open():

*ppDrvContext = (PVOID) hWD;

Add the following line to KP_IntEnable():

*ppIntContext = pDrvContext;

You can now use WD_Transfer() to access memory/IO from withinKP_IntAtIrql. For example (IO access):

HANDLE hWD = (HANDLE) pIntContext;
WD_TRANSFER trans;
BZERO(trans);
trans.cmdTrans = WP_BYTE;
trans.pPort = 0x378;
trans.Data.Byte = 0x65;
WD_Transfer(hWD, &trans);

This will write 0x65 to port 0x378 upon interrupt. The hWD handle is passed from KP_Open() to KP_IntEnable() to KP_IntAtIrql via the context. (Note: The pPort field was renamed from dwPort in v11.8.0 of WinDriver.)

Beginning with version 5.2.0 of WinDriver you can also view the generated DriverWizard Kernel PlugIn code for an example of callingWD_MultiTransfer() from KP_IntAtIrql, provided you have used the DriverWizard to define and assign the register/s for the interrupt acknowledgment before generating the code.

Back To Top

Technical Document #41: How do I share a memory buffer between Kernel PlugIn and user-mode projects for DMA or other purposes?

Beginning with v9.2.1 of WinDriver, you can use the WDC_SharedBufferAlloc() function to allocated a shared memory buffer, which can be used both from a user-mode application and a Kernel PlugIn driver — refer to the documentation of this function in the WinDriver PCI User’s Manual.

Following is an explanation of how to share memory between the user mode and theKernel PlugIn in earlier versions of WinDriver, using a common buffer that is allocated in the kernel mode and mapped to the user mode.

NOTE
The following refers to low-level WinDriver APIs. When using a newer version of WinDriver, which supports the WDC API, use the relevant high-level WDC APIs instead. For versions 9.2.1 and above of WinDriver, simply use the WDC_SharedBufferAlloc()function, as indicated above.

Call WD_DMALock() from the user mode to allocate a buffer in the kernel. To allocate a contiguous kernel buffer, set the DMA_KERNEL_BUFFER_ALLOC flag in the dwOptions field of theWD_DMA structure. WD_DMALock() returns a mapping of the physical address of the allocated buffer to both the kernel and user-mode address space.

Note: Beginning with version 6.0.0 of WinDriver, for contiguous-buffer DMA allocationWD_DMALock() also returns the kernel mapping of the allocated buffer — withindma.pKernelAddr.
In previous versions of WinDriver, the kernel address was not obtainable via WD_DMALock()and there was need in an additional step, calling WD_CardRegister().

You can access the allocated memory from your user mode application using the returned user mode mapped address (dma.pUserAddr) as if it was the result of a malloc() call.

To access the shared memory buffer from the Kernel PlugIn application, you need to pass the kernel mapping of the allocated buffer to the Kernel PlugIn. This address is returned byWD_DMALock() in dma.pKernelAddr.

(Do not try to access the kernel mapped address directly in the user mode. Since this is a kernel mode address, you will generate a protection violation exception if you try to access it from the user mode. For direct user mode access, use the user mode mapping —dma.pUserAddr.)

Now you should pass the kernel virtual address to the Kernel PlugIn.
In order to do this, create a WD_KERNEL_PLUGIN_CALL structure and set the pData field to hold the virtual kernel address — dma.pKernelAddr.

You can then pass this structure to the Kernel PlugIn in one of the following ways:

1.A call to WD_KernelPlugInCall(). In this case you will be able to access the kernel virtual address address from within the KP_Call callback function in the Kernel PlugIn.

 

2. A call to WD_IntEnable() / InterruptEnable() (or InterruptThreadEnable() — in version 5.2.2 and below). In this case, in the user mode you will store theWD_KERNEL_PLUGIN_CALL structure in the kpCall field of the WD_INTERRUPT structure that is passed to the function. You will then be able to access the kernel virtual address from within the KP_IntEnable callback function in the Kernel PlugIn.

After retrieving the kernel virtual buffer address in the Kernel PlugIn, store it in the Kernel PlugIn module (in a global variable or an allocated memory location). Now, you can access the same memory buffer in both kernel mode and user mode.

Note: The access to the common buffer is not synchronized by WinDriver. You may add access synchronization.

 
  *********************************************************************

  /* Sample user mode code: */

  HANDLE hWD;
  WD_DMA dma;
  WD_KERNEL_PLUGIN kerPlug;
  WD_KERNEL_PLUGIN_CALL kpCall;
  WD_CARD_REGISTER cardReg; /* For version 5.2.2 or below */
  
  hWD = WD_Open();

  BZERO(dma);
  dma.pUserAddr = NULL;
  dma.dwBytes = 0x10000; /* allocate 16K */
  dma.dwOptions = DMA_KERNEL_BUFFER_ALLOC; /* kernel contiguous buffer */
  WD_DMALock(hWD, &dma);
  if (!dma.hDma)
  {
     printf("failed allocating dma buffer\n");
     /* exit*/
  }
  
  /* At this point, dma.pUserAddr holds the 
      user mode mapping of the allocated memory, 
      dma.pKernelAddr holds the kernel mapping of  
      the memory. */
  /* ////////////////////////////////////////////////////////// */

  /* Pass the kernel address to the Kernel PlugIn: */
  

  BZERO (kerPlug);
  kerPlug.pcDriverName = KP_DRIVER_NAME;
  WD_KernelPlugInOpen(hWD, &kerPlug);
  if (!kerPlug.hKernelPlugIn)
  {
      printf("failed opening a handle to the Kernel PlugIn\n");
      /* exit */
  }

  BZERO (kpCall);
  kpCall.hKernelPlugIn = kerPlug.hKernelPlugIn;
  kpCall.dwMessage = YOUR_MESSAGE;
  kpCall.pData = dma.pKernelAddr;  
  WD_KernelPlugInCall(hWD, &kpCall);
  
  *********************************************************************
 

For a detailed description of the WinDriver APIs used above, refer to the Function Reference section in the WinDriver PCI Low-Level API Reference (or in the main WinDriver User’s Manual, in earlier versions of WinDriver).
For further clarifications regarding DMA allocation with WinDriver, refer to the relevant section in the WinDriver PCI User’s Manual, under “Advanced Issues”.

Back To Top

Technical Document #42: How do I send a GET_DESCRIPTOR request to my device, using WinDriver?

You can use WinDriver to perform control transfers and send and receive setup packets to/from your device. You can use the control transfers, for example, to send a GET_DESCRIPTOR request to the device.

Please review the USB Control Transfers sections of the WinDriver USB User’s Manual for a detailed explanation on how to perform control transfers with WinDriver and a sample of sending aGET_DESCRIPTOR request to the device, both from the DriverWizard and from a WinDriver application. (Note specifically the endian scheme when setting up the packets.)

Back To Top

Tech Doc #43: Developing 32-bit Applications for 64-bit Architectures

WinDriver supports driver development for the following 64-bitarchitectures:

  • Windows AMD64 or Intel EM64T (x64)
  • Linux AMD64 or Intel EM64T (x86_64) or64-bit PowerPC (ppc64)

By default, applications created using the 64-bit versions of WinDriver are64-bit applications. Such applications are more efficient than 32-bitapplications. However, you can also use the 64-bit versions of WinDriver to create 32-bit applications that will run on the supported 64-bitplatforms. This document outlines two methods for creating such applications:

NOTE

In the following documentation

    • <WD64> signifies the path to a 64-bit WinDriver installation directory for your target operating system (e.g.,C:\WinDriver64), and <WD32> signifies the path to a32-bit WinDriver installation directory for the same operating system (e.g., C:\WinDriver).
  • <ver> signifies the version of the WinDriver installation that you are using — for example, 1200 for version 12.0.0.

Developing a 32-Bit WinDriver Application for 64-Bit Platforms

To create a 32-bit WinDriver application for 64-bit platforms, using a64-bit WinDriver installation, do the following:

    1. Create a WinDriver application, as outlined in the WinDriver User’s Manual — for example, by generating code with DriverWizard, or using one of the WinDriver samples.

 

  1. Build the application with an appropriate 32-bit compiler for your target operating system, using the following configuration:
      • Add the KERNEL_64BIT preprocessor definition.
        NOTE
        In the makefiles, the definition is added using the -Dflag: -DKERNEL_64BIT.

        The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects, in the64-bit WinDriver toolkit, already add this definition.

    • Link the application with the specific version of the WinDriver-API library/shared object for 32-bit applications executed on 64-bit platforms —<WD64>\lib\amd64\x86\wdapi<ver>.lib on Windows (e.g.,C:\WinDriver64\lib\amd64\x86\wdapi1200.lib) /<WD64>/lib/libwdapi<ver>_32.so on Linux (e.g.,~/WinDriver64/lib/libwdapi1200_32.so).The sample and wizard-generated project and make files for32-bit applications in the 64-bit WinDriver toolkit already link to the correct library:
      On Windows, the MS Visual Studio project files and Windows GCC makefiles are defined to link with<WD64>\lib\amd64\x86\wdapi1200.lib.
      On Linux, the installation of the 64-bit WinDriver toolkit on the development machine creates a libwdapi<ver>.sosymbolic link in the /usr/lib directory — which links to<WD64>/lib/libwdapi<ver>_32.so — and in the/usr/lib64 directory — which links to<WD64>/lib/libwdapi<ver>_32.so (the 64-bit version of this shared object).
      The sample and wizard-generated WinDriver makefiles rely on these symbolic links to link with the appropriate shared object, depending on whether the code is compiled using a32-bit or 64-bit compiler.

NOTE

  • When distributing your application to target 64-bit platforms, you need to provide with it the WinDriver-API DLL/shared object for 32-bit applications executed on 64-bit platforms —<WD64>\redist\wdapi<ver>_32.dll on Windows (e.g.,C:\WinDriver64\redist\wdapi1200_32.dll) /<WD64>/lib/libwdapi<ver>_32.so on Linux (e.g.,~/WinDriver64/lib/libwdapi1200_32.so).
    Before distributing this file, rename the copy of the file in your distribution package by removing the _32 portion. The installation on the target should copy the renamed DLL/shared object to the relevant OS directory —%windir%\sysWOW64 on Windows or /usr/lib on Linux. All other distribution files are the same as for any other 64-bitWinDriver driver distribution, as detailed in the WinDriver distribution instructions in the manuals.
  • An application created using this method will not work on32-bit platforms. A WinDriver application for 32-bit platforms needs to be compiled without the KERNEL_64BIT definition; it needs to be linked with the standard 32-bit version of the WinDriver-API library/shared object from the 32-bit WinDriver installation (<WD32>\lib\x86\wdapi<ver>.lib on Windows / <WD32>/lib/libwdapi<ver>.so on Linux); and it should be distributed with the standard 32-bit WinDriver-API DLL/shared object (<WD32>\redist\wdapi<ver>.dllon Windows / <WD32>/lib/libwdapi<ver>.so on Linux) and any other required 32-bit distribution file, as outlined in the WinDriver distribution instructions in the manuals.

Developing a 32-Bit Application for Both 32-Bit and 64-Bit Platforms

If you have both 64-bit and 32-bit WinDriver installations, you can also create a single 32-bit application that can be executed on both 32-bit and64-bit platforms. This can be done using the following method:

    1. Create a DLL (on Windows) or a shared object (on Linux) that concentrates the calls to the WinDriver APIs.
      If you created a WinDriver application using the generated DriverWizard code or one of the WinDriver samples, convert this application to a DLL/shared object.

      NOTE
      When using DriverWizard to generate PCI driver code for Windows MS Visual Studio, you have the option to generate the library code as a DLL (for both 32-bit and 64-bitenvironments).

 

    1. Compile two versions of your DLL/shared object:
      • A version for 32-bit platforms: This version should be compiled using a 32-bit compiler, without the KERNEL_64BITdefinition, and linked with the standard 32-bit WinDriver-API library/shared object from the 32-bit WinDriver installation — <WD32>\lib\x86\wdapi<ver>.lib on Windows (e.g.,C:\WinDriver\lib\x86\wdapi1200.lib) /<WD32>/lib/libwdapi<ver>.so on Linux (e.g.,~/WinDriver/lib/libwdapi1200.so).
      • A version for 64-bit platforms: This version should be compiled using a 32-bit compiler, with the KERNEL_64BITdefinition, and linked with the standard 32-bit WinDriver-API library/shared object from the 64-bit WinDriver installation — <WD64>\lib\amd64\x86\wdapi<ver>_32.lib on Windows (e.g.,C:\WinDriver64\lib\x86\wdapi1200.lib) /<WD64>/lib/libwdapi<ver>_32.so on Linux (e.g.,~/WinDriver64/lib/libwdapi1200_32.so) (see details above regarding compilation of 32-bit applications for 64-bitplatforms).

 

  1. Write a 32-bit application that communicates with WinDriver via the DLL/shared object that you created; the application should be implemented to load the relevant version of the DLL/shared object — 32-bit or 64-bit — depending on the platform on which it is run.
    Note: This application should be compiled using an appropriate32-bit compiler, without the KERNEL_64BIT definition.

NOTE

When distributing a driver that was developed using this method, be sure to distribute the relevant files for each target platform:

  • For 32-bit platforms, distribute the application together with the 32-bit version of your WinDriver-wrapper DLL/shared object, and with the standard 32-bit files from the 32-bitWinDriver installation, including the 32-bit WinDriver DLL/shared object (<WD32>\redist\wdapi<ver>.dll on Windows / <WD32>/lib/libwdapi<ver>.so on Linux).
  • For 64-bit platforms, distribute the application together with the 64-bit version of your WinDriver-wrapper DLL/shared object, and with the standard 64-bit files from the 64-bitWinDriver installation, including the 64-bit WinDriver DLL/shared object (<WD64>\redist\wdapi<ver>.dll on Windows / <WD64>/lib/libwdapi<ver>.so on Linux).

For detailed distribution instructions, refer to the WinDriver User’s Manual.

Back To Top

Technical Document #45: What are the COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros and when should they be used?

The COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros are used for copying data (when necessary) to/from user-mode memory addresses (respectively), when accessing such addresses from within the Kernel PlugIn. Copying the data ensures that the user-mode address can be used correctly, even if the context of the user-mode process changes in the midst of the I/O operation. This is particularly relevant for long operations, during which the context of the user-mode process might change. The use of macros to perform the copy provides a generic cross-platform solution for all supported operating systems.

Note that if you wish to access the user-mode data from within theKP_IntAtIrql or KP_IntAtDpc functions, you should copy the data into a Kernel PlugIn variable before the execution of these routines.

The COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros are defined in the WinDriver/include/kpstdlib.h header file.

For an example of using the COPY_TO_USER_OR_KERNEL macro, see the implementation of the KP_Call() function in the generated DriverWizard Kernel PlugIn code (see kp_xxx.c) and in WinDriver’s Kernel PlugIn sample (KP_PCI (v7.0.0+) —WinDriver/samples/pci_diag/kp_pci/kp_pci.c / KP_TEST (v6.2.3-) —WinDriver/kerplug/kermode/kptest.c).

To share a data buffer between the user-mode and Kernel PlugIn routines (e.g., KpIntAtIrql and KpIntAtDpc), consider using the technique outlined in Technical Document #41.

Back To Top

Technical Document #46: Why does my WD_KernelPlugInOpen() call fail?

NOTE
WDKernelPlugInOpen() is also called from the high-levelWDC_KernelPlugInOpen() function, and from theWDC_xxxxDeviceOpen() functions — when they are called with the name of a Kernel PlugIn driver.

There are several reasons why the call to WD_KernelPlugInOpen() might fail:

  • You did not set up the parameters correctly in the call toWD_KernelPlugInOpen(). Please check this carefully.

 

  • You did not set up the driver name correctly in all locations in the code: Please verify that you are using the correct Kernel PlugIn driver name in all the relevant locations in the code. Look specifically at the Kernel PlugIn KP_Init() implementation and atkernelPlugIn.pcDriverName in the user mode project. [Please indicate the driver name in capital letters and without the file extension (*.sys/.vxd/.kext/.o/.ko)].

 

  • You did not install the driver properly: Make sure you copied the driver file that was created to the correct location (e.g.,%windir%\system32\drivers — to install a SYS Kernel PlugIn driver on Windows) and that you installed the Kernel PlugIn kernel module correctly, as explained in the WinDriver PCI User’s Manual. For general guidelines on how to install your Kernel PlugIn driver, refer to Technical Document #62. For Windows, for example, make sure to use the correct wdreg/wdreg_gui/wdreg16installation syntax: For SYS drivers:
    wdreg -name <your KP driver name> install.
    For VxD drivers (supported in earlier versions of WinDriver):
    wdreg -vxd -name <KP driver name> install.
    (Note: On Windows 98/Me you need to reboot the OS in order to complete the installation.)

 

  • For registered users: You did not call WD_License() before callingWD_KernelPlugInOpen().
    If you are using a registered version of WinDriver, remember to callWD_License() (or a registration function, which calls WD_License()) before calling WD_KernelPlugInOpen().

Back To Top

Technical Document #47: Does WinDriver support Scatter/Gather DMA on Linux?

Yes. Beginning with version 5.2.0 of WinDriver you can use WD_DMALock() to perform Scatter/Gather DMA on Linux as well.
This support is currently afforded for the supported 2.4.x and newer kernels. The 2.2.x kernels do not support Scatter/Gather DMA. You might be able to implement Scatter/Gather DMA with WinDriver with these kernels as well, if you obtain a patch that adds Scatter/Gather DMA support to the 2.2.x Linux kernels, however please note that we have not tested this and will not, therefore, be able to provide support for any matters related to the use of such patches.

In earlier versions of WinDriver only contiguous buffer DMA was supported on Linux, due to the previous lack of support for Scatter/Gather DMA in the Linux kernels.

Back To Top

Technical Document #48: What is the interrupt latency of WinDriver?

The interrupt latency can be divided into two parts:

    1. Kernel latency: the time from the occurrence of the interrupt until the OS calls the interrupt handler. This is OS dependent.
    2. The transfer from the kernel mode to the user mode: the time from the call to the kernel until the release of the user-mode thread.

This latency depends on specific factors of your machine and software. You need to experiment with your software to test its speed.

WinDriver’s Kernel PlugIn feature (available from version 4.0) enables you to implement the crucial parts of your code (such as the interrupt handlers) in the kernel mode, thereby improving the overall performance of your driver. For the list of operating systems for which the Kernel PlugIn feature is available, refer to Technical Document #29.

Using the Kernel PlugIn you can expect to handle over 100,000 interrupts per second (see also www.jungo.com/st/support/windriver/windriver_faqs/#HMI).

For more information about the Kernel PlugIn feature, refer to the WinDriver PCI User’s Manual.

Back To Top

Technical Document #51: How do I port a DOS driver, which uses inp() and outp() calls to access the card, into a Windows driver?

Simple! Include the sample basic_io.c source code (found under theWinDriver/samples/basic_io/ directory) in your code.
Define the I/O range your card uses in MY_IO_BASE and MY_IO_SIZE.
(For example: To use range 0x378-0x37a, define MY_IO_BASE=0x378 andMY_IO_SIZE=3.)
Call IO_init() at the beginning of the driver, and IO_end() before exit.
Replace any inp() and outp() calls in your code with IO_inp() andIO_outp(), respectively.
Compile and run!

Back To Top

Technical Document #52: How many I/O and memory spaces does WinDriver support on a single board?

The number of I/O and memory spaces is not really limited.
Each card can have up to 20 elements (i.e., I/O, memory and interrupt elements), but if you need more, you can simply register another card (see also the following FAQ:www.jungo.com/st/support/windriver/windriver_faqs/#lfc15).

Back To Top

Technical Document #53: How do I reset my USB device using version 5.2.2 of WinDriver?

WinDriver provides you with an API for resetting your USB device:WD_UsbResetDevice() and WD_UsbResetDeviceEx() (added in version 5.0.4 of WinDriver). These functions cause the hub driver to reinitialize the device, while preserving the existing configuration.

WD_UsbResetDeviceEx() — added in version 5.0.4 — enables you to distinguish between performing a soft reset — which is similar to the reset performed with the WD_UsbResetDevice() function, used in previous versions; Or a hard reset.

The differences between a soft reset and a hard reset, performed withWD_UsbResetDeviceEx(), are as follows:

    • Soft reset: The reset request will be issued only if the device is in a disabled state (as done by Microsoft’s driver).

 

  • Hard reset: The reset request will always be issued — regardless if the device is in the disabled or enabled state.

To use the hard reset option, set the WD_USB_HARD_RESET flag in thedwOptions field of the WD_USB_RESET_DEVICE structure, which is passed toWD_UsbResetDeviceEx(). By default, when the dwOptions field is set to 0, the function will perform a soft reset — i.e., the reset request will be issued only if the device is currently disabled.

Following is an an example of using WD_UsbResetEx() to perform a hard reset:

    WD_USB_RESET_DEVICE reset;
    BZERO(resest);
    reset.hDevice = hDevice; // The handle received from
         // WD_UsbDeviceRegister()
    reset.dwOptions = WD_USB_HARD_RESET;
    WD_UsbResetDeviceEx(hWD, &reset);

NOTE: To prevent a system crash when performing hard reset, it is recommended to do the following: immediately after callingWD_UsbResetDeviceEx(), un-register the device (by callingWD_UsbDeviceUnregister()), scan for it (by calling WD_UsbScanDevice()) and then register it again (by calling WD_UsbDeviceRegister()). This will ensure that Windows will allocate all the resources for the device and will eliminate possible conflicts later on.

Back To Top

Technical Document #55: Buffer Overrun Error: WDU_Transfer() sometimes returns the 0xC000000C error code. What does this error code mean? How do I solve this problem?

The 0xC000000C error code, is defined in windrvr.h as WD_USBD_STATUS_BUFFER_OVERRUN.

The WD_USBD_XXX status codes returned by WinDriver (see windrvr.h) comply with the URB status codes returned by the low-level USB stack driver (e.g., URB code 0XC000000CL — WD_USBD_STATUS_BUFFER_OVERRUN).
You can refer to the Debug Monitor log to see the URB and IRP values returned from the stack drivers.

For Windows, the URB and IRP codes can be found in the Windows Driver Kit (WDK) under the inc\ directory. The URB status codes can be found in the usbdi.h file or the usb.h file (depending on th e OS). The IRP status codes can be found in the ntstatus.h file. Similar Microsoft documentation exists for Windows CE (a.k.a. Windows Embedded Compact).
For Linux, WinDriver translates the error codes returned from the stack driver into equivalent USBD errors.

For information regarding the specific error you received and when it might occur, review the operating system’s documentation.

The USBD_STATUS_BUFFER_OVERRUN error code (0xC000000C) is set by the USB stack drivers when the device transfers more data than requested by the host.

There are two possible solutions for this buffer overrun problem:

  1. Try setting the buffer sizes in the calls to WDU_Transfer in your code to multiples of the maximum packet size. For example, if the maximum packet size is 64 bytes, use buffer sizes that are multiples of 64 (64 bytes, 128 bytes, etc.).
  2. Define a protocol between the device and device driver, making sure that the device does not transfer more data than requested. When you have access to the device firmware code, this solution is recommended.

Notes:

  1. Recheck your firmware and the hardware specification to verify that you are implementing the communication with the device correctly.
  2. It is also recommended to use a USB bus analyzer to determine what is happening on the bus.

Back To Top

Technical Document #56: Windows XP crashes (BSOD) when I listen to an isochronous pipe on my USB device.

Currently, when performing repeated USB read transfers from an isochronous pipe (“listening” to the pipe) on Windows XP, the OS may eventually crash (resulting in the Blue Screen of Death — BSOD).
This happens when using a high-speed USB device that is not configured as a high-bandwidth device, and setting the device’s bInterval descriptor field to 0x1 or 0x2 (an interval of 1 or 2 microframes) and itswMaxPacketSize descriptor field to 0x0400 (maximum packet siz e of 1KB). When listening to an isochronous pipe of a device with this configuration, on Windows XP, the DMA operation performed by Microsoft’susbport.sys driver, as part of handling the isochronous read transfers, may cause the OS to crash.

A possible work-around for this problem is to set the value of the device’sbInterval descriptor field to 0x4, instead of 0x1 or 0x2.

Back To Top

Technical Document #57: Driver installation on Plug-and-Play systems (Windows 98/Me/2000/XP) — WinDriver version 5.0.5 and earlier

When installing a driver for Plug-and-Play (PnP) hardware (PCI/USB) on a PnP system (such as Windows 98/Me/2000/XP), using version 5.0.5 of WinDriver or earlier, you should install the wdpnp.sys PnP driver (formerly wdusb.sys) as the driver for your device, using an INF file.
You can use WinDriver’s DriverWizard to create the INF file for your device, and the install it according to the directions that will be displayed in the DriverWizard (and are also found in the WinDriver User’s Manual).

In addition, you need to have the WinDriver service running for hardware access. (This is required for all operating systems, not just PnP.) This service is supported by the windrvr.sys driver.
The program wdreg.exe is supplied for installing this service.

In version 5.2 of WinDriver, the windrvr.sys and wdpnp.sys files were combined into a single windrvr.sys driver file, which is installed on PnP systems via the installation of an INF file. Please refer to the Driver Distribution chapter of the updated WinDriver User’s Manual for more details regarding the current driver distribution process.

You can arrange to have wdreg.exe run earlier through an Install Shield or similar application packager, before the driver is installed (see Technical Document #54 for more information on this).

However, for Microsoft Windows certification (WHQL), you may need to have the entire installation performed through an INF file. In that case you can arrange to have one of your custom installation programs launched by your INF file by using the RUN ONCE key as shown below. [Please note that the following is true for version 5.0.5 or earlier of WinDriver].

 [Foobar.AddReg.NT]
HKLM,%RUNONCEKEYNAME%,,,"mycustom.exe"
.........
RUNONCEKEYNAME = "software\microsoft\windows\ currentversion\runonce\setup"

mycustom.exe is your custom program that incorporates the code ofwdreg.exe to install and start the WinDriver service.
For more information on wdreg.exe, see the “Dynamically Loading Your Driver” and the “Driver Distribution” chapters in the WinDriver User’s Manual.

You can also choose to use a co-installer program on Windows 2000 (see the MSDN WEB site for more information on co-installers).

If you do not wish to run an application program in this way, you can set up your INF file to copy windrvr.sys to the system32\drivers directory, and make the WinDriver service Registry entries.
This is demonstrated below for Windows 2000:

  [Foobar.AddReg.NT]
HKR,,FriendlyName,,%Foobar.SvcDesc% ; Human readable name
HKLM,System\CurrentControlSet\Services\WinDriver,,,
HKLM,System\CurrentControlSet\Services\WinDriver,
"Start",0x10001,0x02 ;2= on boot, 3= on demand
HKLM,System\CurrentControlSet\Services\WinDriver,
"Type",0x10001,0x01
HKLM,System\CurrentControlSet\Services\WinDriver,
"ErrorControl",0x10001,0x01
HKLM,System\CurrentControlSet\Services\WinDriver,
"ImagePath", ,"\SystemRoot\System32\drivers\windrvr.sys"
HKLM,System\CurrentControlSet\Services\WinDriver,
"DisplayName",,WinDriver

[Foobar.CopyFiles.NT] ; Files to copy
windrvr.sys,,,2 ; 2= user can’t skip this file

Note that the WinDriver service will only be started after a reboot.
For Windows 2000/XP/98/Me you can force a reboot by adding the Reboot or Restart directive to your INF file in the Install section.

 [InstallFoobar.NT]
CopyFiles=Foobar.CopyFiles.NT
AddReg=Foobar.AddReg.NT
Reboot

If you wish to avoid the reboot, you need to adopt one of the aforementioned methods (co-installer, SETUP\RUNONCE key, application installer).

Back To Top

Technical Document #58: My attempt to allocate and lock a 1GB DMA buffer with WinDriver, on Windows, fails. Is this a limitation of the operating system?

WinDriver does not impose any inherent limitation on the size of the DMA buffer that can be allocated using its DMA APIs. However, the success of the DMA allocation is dependent of the amount of available system resources at the time of the attempted allocation. Therefore, the earlier your try to allocate the buffer, the better your chances of succeeding.

For contiguous-buffer DMA allocation, there must be enough contiguous physical memory for the allocation. Technical Document #3 explains how you can preallocate contiguous DMA buffers at boot time, on Windows, with version 11.1.0 and above of WinDriver.
When allocating a Scatter/Gather DMA buffer that is larger than 1MB, using the low-level WinDriver API, be sure to set the DMA_LARGE_BUFFER flag in the dwOptions field of the WD_DMA structure that is passed to WD_DMALock(). (When using the high-level WDC_DMASGBufLock() function, this flag is already handled internally by the function.)

The DMA buffer allocated by WinDriver uses page-locked memory, to ensure a safe DMA operation. This memory is allocated from Windows’ non-paged kernel pool of memory. The size of this pool is fixed at boot time by a Registry setting. You can increase the allocated memory by increasing the value of the NonPagedPoolSize Registry entry, found under HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Control\Session Manager\Memory Management.

Sometimes, there is enough contiguous memory, but there are not enough page table entries to map the memory — refer to Technical Document #59 for more information.

Even after increasing the value of the relevant Registry entries, the memory allocation might still fail, specifically when trying to allocate a very large buffer (such as 1GB). The solution in this case is to try decreasing the size of the buffer you are trying to lock, until you succeed.

Please note that the WinDriver DMA allocation APIs ((WDC_DMAContigBufLock() / WDC_DMASGBufLock() / WD_DMALock()) also map the physical memory of the allocated buffer into virtual user mode space. Therefore, there must also be enough free virtual memory to enable the mapping of the entire buffer into the user space.

Back To Top

Technical Document #59: I have run into a problem accessing 32MB of memory on a PCI card. WD_CardRegister() fails to map the memory. The problem does not occur if I try to access 16MB of memory on my card.

WD_CardRegister() attempts to map physical memory address ranges to both virtual user-mode and kernel-mode address space, by calling the relevant OS functions. If either of these mappings fail, e.g., because there is not enough user/kernel virtual memory to enable the mapping of the entire memory range, WD_CardRegister() will fail and a relevant error message will be printed to the Debug Monitor log, indicating which OS-mapping function failed (see example in Technical Document #73).

You may also encounter the same problem when using theWDC_PciDeviceOpen()/WDC_PcmciaDeviceOpen()/WDC_IsaDeviceOpen() convenience wrappers (v7.0.0+), which call WD_CardRegister().

Solutions:

To resolve this problem, you have the following options:

NOTE
There may be some differences between the API in your version of WinDriver and that used in the following solutions (such as differences in enumeration names and field names and/or types).
  • On NT 4.0 and higher, the number of page table entries for the virtual memory tables is set in the registry. To enable the mapping of a large memory range, you may need toincrease the number of page table entries in the registry, and thus increase the amount of available virtual memory.
    To do this, increase the value of the SystemPages registry entry, found under:
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\SystemPages
    (Run regedit.exe to open the registry.
    At the end, reboot in order for the changes to take place.)The value to set should be roughly calculated as
    <available memory> / 4K + <enough pages for the rest of the applications>Try setting the number of page table entries to 0x100000. It should be sufficient for most uses.

 

  • When the memory mapping fails, it is most often as a result of insufficient kernel-modevirtual address space. In version 7.x+ of WinDriver, you have the option to prevent this problem by mapping the memory only to the user-mode virtual address space:If the card’s registration function (WDC_XXXDeviceOpen() / WD_CardRegister()) fails to map all the memory on the card to the kernel-mode virtual address space, you can use theWD_ITEM_MEM_DO_NOT_MAP_KERNEL flag to instruct WinDriver to attempt mapping the physical memory only to the user-mode virtual address space, and not to the kernel address space: Modify the WD_CARD structure that you defined (ISA) or received fromWDC_XXXGetDeviceInfo()/ WD_XXXGetCardInfo() (PCI/PCMCIA), and set this flag in theI.Mem.dwOptions field of the card’s relevant memory WD_ITEMS structure. Then pass the modified card structure to WDC_xxxDeviceOpen()/WD_CardRegister() (see Code Examplesbelow).NOTE that if you select to set the WD_ITEM_MEM_DO_NOT_MAP_KERNEL flag, the registration function will not return a kernel-mode mapping of the selected memory item (as usually returned in pDeviceInfo->pAddrDesc[i].pAddr / pCardReg->Card.Item[i].I.Mem.pTransAddr), and you will therefore not be able to rely on this mapping in calls to WinDriver’s APIs or to access the memory directly memory from a Kernel PlugIn driver.

 

  • Another approach is to map a smaller amount of memory. You can modify the qwBytesfield of the relevant memory item, stored in the card’s WD_CARD structure (card.Item[i].I.Mem), before calling WDC_xxxDeviceOpen() or WD_CardRegister(), in order to map a smaller portion of the memory.
    You can also modify the memory item’s pPhysicalAddr field in order to begin the mapping at a different offset in the address space.
    (For PCI/PCMCIA, the card structure is returned byWDC_PciGetDeviceInfo()/WDC_PcmciaGetDeviceInfo() in pDeviceInfo->Card, or by the lower-level WD_PciGetCardInfo()/ WD_PcmciaGetCardInfo() function in pCard->Card).
    For a better understanding, refer to the Code Examples below.NOTE: When using this method, take care not to access any memory addresses on the card that have not been mapped.

Code Examples:

The following code examples demonstrate how to set the WD_ITEM_MEM_DO_NOT_MAP_KERNEL flag, or lock less memory, using the different WinDriver APIs.

NOTE: For the purpose of this example we assume that the information for the relevant memory item is stored in the second item of the card’s items array (i.e., index 1). However, this will not necessarily be the case. For PCI/PCMCIA you should write your code to iterate through the items array, returned by WDC_xxxGetDeviceInfo()/ WD_xxxGetCardInfo(), in order to find the index of the memory item that you wish to modify (card.Item[i].item should be of type ITEM_MEMORY andcardItem.Item[i].pPhysicalAddr should match the physical address of your target memory range).
===========================================================

Example 1: WDC PCI/PCMCIA API

NOTE: For PCMCIA, just replace any “PCI”/”Pci” references below with “PCMCIA”/”Pcmcia”.
    WD_PCI_CARD_INFO cardInfo;
...
WDC_PciGetDeviceInfo(&cardInfo);
    cardInfo.Card.Item[1].I.Mem.dwOptions |=
WD_ITEM_MEM_DO_NOT_MAP_KERNEL;
    /* Alternatively, modify cardInfo.Item[1].I.Mem.qwBytes,
and perhaps also cardInfo.Item[1].I.Mem.pPhysicalAddr,
in order to map only a selected portion of the memory.
For example, to lock 1,000 bytes, beginning with
offset 0x10 of the address space, set:
       cardInfo.Item[1].I.Mem.qwBytes = 1000;
cardInfo.Item[1].I.Mem.pPhysicalAddr += 0x10;
*/
    ...
WDC_PciDeviceOpen(&hDev, &cardInfo, ...);

===========================================================

Example 2: WDC ISA API

    WD_CARD card;
...
    card.Item[1].I.Mem.dwOptions |= WD_ITEM_MEM_DO_NOT_MAP_KERNEL;
    /* Alternatively, modify card.Item[1].I.Mem.qwBytes,
and perhaps also card.Item[1].I.Mem.pPhysicalAddr,
in order to map only a selected portion of the memory.
For example, to lock 1,000 bytes, beginning with
offset 0x10 of the address space, set:
       card.Item[1].I.Mem.qwBytes = 1000;
card.Item[1].I.Mem.pPhysicalAddr += 0x10;
*/
...
WDC_IsaDeviceOpen(&hDev, &card, ...);

===========================================================

Example 3: WD_xxx PCI/PCMCIA API

NOTE: For PCMCIA, just replace any ‘PCI’/’Pci’ references below with ‘PCMCIA’/’Pcmcia’.

    WD_PCI_CARD_INFO cardInfo;
WD_CARD_REGISTER cardReg;
...
WD_PciGetCardInfo(hWD, &cardInfo);
    cardInfo.Card.Item[1].I.Mem.dwOptions |=
WD_ITEM_MEM_DO_NOT_MAP_KERNEL;
    /* Alternatively, modify cardInfo.Item[1].I.Mem.qwBytes,
and perhaps also cardInfo.Item[1].I.Mem.pPhysicalAddr,
in order to map only a selected portion of the memory.
For example, to lock 1,000 bytes, beginning with
offset 0x10 of the address space, set:
       cardInfo.Item[1].I.Mem.qwBytes = 1000;
cardInfo.Item[1].I.Mem.pPhysicalAddr += 0x10;
*/
cardReg.Card = cardInfo.Card;
...
WD_CardRegister(hWD, &cardReg);

===========================================================

Example 4: WD_xxx ISA API

    WD_CARD_REGISTER cardReg;
...
    cardReg.Card.Item[1].I.Mem.dwOptions |=
WD_ITEM_MEM_DO_NOT_MAP_KERNEL;
    /* Alternatively, modify cardReg.Item[1].I.Mem.qwBytes,
and perhaps also cardReg.Item[1].I.Mem.pPhysicalAddr,
in order to map only a selected portion of the memory.
For example, to lock 1,000 bytes, beginning with
offset 0x10 of the address space, set:
       cardReg.Item[1].I.Mem.qwBytes = 1000;
cardReg.Item[1].I.Mem.pPhysicalAddr += 0x10;
*/
...
WD_CardRegister(hWD, &cardReg);

Back To Top

Technical Document #62: Kernel PlugIn Driver Installation — General Guidelines

When using WinDriver’s Kernel PlugIn feature you are creating your own driver file, which is used in addition to the generic WinDriver kernel driver— windrvr<version>.sys/.o/.ko in the newer versions (e.g.,windrvr1200.sys/.o/.ko).

Please be sure to diligently follow the instructions in the WinDriver User’s Manual for building and installing your Kernel PlugIndriver.

You should specifically pay attention to the following points:

    • If you have used WinDriver’s Kernel PlugIn sample driver (KP_PCI/ KPTEST in v6.2.3-) as the basis for your Kernel PlugInapplication, be sure to replace the driver name (“KP_PCI” / “KPTEST”) in all locations in the sample files with your chosen driver name.The driver name should be indicated in the code in Capital Letters and without the sys/vxd/kext/o/ko extension.In v7.0.0+ of WinDriver, verify specifically that you have specified the driver name correctly in the definition of KP_PCI_DRIVER_NAME in the equivalent of the sample’s pci_lib.h file.For earlier versions of WinDriver (v6.2.3-), modify the equivalent of the following line in KP_Init():
        strcpy(kpInit->cDriverName, "KPTEST");
      and change the assignment to the pcDriverName member of theWD_KERNEL_PLUGIN structure, which is passed toWD_KernelPlugInOpen() in the user-mode project.

 

    • When developing a SYS driver for Windows (Windows 98 and higher), remember to install Microsoft’s driver development kit for your OS (WDK / DDK) and set the BASEDIR environment variable to the location of your WDK/DDK directory before attempting to build your Kernel PlugIn SYS driver (as explained in the manual). (For version 5.0.5 of WinDriver and earlier, it is recommended to build your code with the Windows NT DDK. For Windows NT 4.0 — in WinDriver versions that support this OS — you also need to install the NT SDK.)
      For earlier versions of WinDriver (v6.0x-), which supported development of VxD drivers on Windows 95/98/Me, when developing a VxD driver you do not need to install the WDK/DDK (unless you added your own DDK function calls to theKernel PlugIn code). When using the compile.bat file from the KPTEST sample to compile your VxD driver, comment-out or remove the following line:
         nmake %1 /f kptest.mak
      leaving only the line:
         nmake %1 /f kptest.mak WIN95=1Beginning with v5.2.0 of WinDriver, the DriverWizard can also be used to generate Kernel PlugIn code and a compatible user-mode application for your device, including the required project or makefiles for building the code (depending on the target OS).
      For Windows, you can build the generated MS Visual Studio (Visual C++) project into a SYS driver on a Windows NT and higher machine, by simply opening the generated workspace/solution file — xxx.dsw/sln — and building the code, after setting the Active Build Configuration according to the OS for which you are developing. (SYS drivers for Windows 98/Me — supported in earlier versions of WinDriver — should be built on a Windows NT or higher machine.)
      Beginning with v11.0.0 of WinDriver, you can also use the generated Windows GCC makefile to build the generatedKernel PlugIn code in your selected environment Windows GCC environment (MinGW/Cygwin).Note: When building a kernel project with MS Visual Studio, the project path must not contain any spaces.

 

    • Verify that the WinDriver kernel module is installed: Before installing your Kernel PlugIn driver, verify that the WinDriver driver — windrvr<version>.sys/.o/.ko in the newer WinDriver versions (e.g., windrvr1200.sys/.o/.ko) — is installed, since theKernel PlugIn module depends on the WinDriver module for its successful operation. (You can run the Debug Monitor to verify that WinDriver is loaded).

 

  • Install your Kernel PlugIn driver:
      • Remember to copy your Kernel PlugIn driver (my_kp/.sys/.vxd/.kext/.o/.ko) to the operating system’s drivers/modules directory before attempting to install the driver. On Linux, beginning with v6.2.3 of WinDriver you do not need to copy the driver file, since the driver installation (make install) will handle this for you.
    • Don’t forget to install your Kernel PlugIn driver before running your application:On Windows: Use the wdreg installation utility (orwdreg_gui/wdreg16 — depending on the WinDriver version and OS that you are using) to install the driver:To install a my_kp.sys driver, run this command:
          wdreg -name MY_KP install

      To install a my_kp.vxd driver (in the WinDriver versions that support this driver type), use the -vxd flag:
           wdreg -name -vxd MY_KP installOn Linux: For v6.2.3+ of WinDriver, from the kermode/Kernel PlugIn directory run this command:
          make install
      For earlier versions of WinDriver, use insmod to install the driver module.

      On Solaris: Use add_drv to install the driver.

NOTE
The Kernel PlugIn is not backward compatible. Therefore, when switching to a different version of WinDriver, you need to rebuild your Kernel PlugIn driver using the new version.

Back To Top

Technical Document #64: Linux contiguous-buffer DMA allocations — 128KB limitation

NOTE
Beginning with version 8.0.2 you can use WinDriver to allocate contiguous DMA buffers of more than 128KB on Linux. The following information is relevant for versions 8.01 and below of WinDriver.

By default you can allocate a contiguous DMA kernel buffer of no more than 128KB on Linux. (With regard to the possibility of performing Scatter/Gather DMA on Linux — see Technical Document #47.)

It is possible to recompile the kernel to get larger sizes.
You can look for the bigphysarea patch, which enables DMA allocation of buffers that are larger than 128KB.
You can also download the code for Linux kernels (the relevant file is/usr/src/linux/mm/slab.c ; look for cache_sizes struct) and study the code to understand how to do this, or join Linux-kernel discussion groups on Usenet to get more information on this.
Please note, however, that we have not tested the aforementioned patch and that we will not be able to provide support for any matters related to attempts to increase the maximum DMA buffer allocation size.

If you do recompile the kernel to enable allocation of DMA buffers that are larger than 128KB, you will also need to change the implementation ofLINUX_kmalloc() in linux_wrappers.c. The current implementation returns NULL if the requested allocation size is bigger than 128KB. If you use the bigphysarea patch, you will need to call the relevant functions from the patch in LINUX_kmalloc().

Back To Top

Technical Document #66: WinDriver for Solaris SPARC — 33Mhz * 33MB PCI Bus Support

On Solaris SPARC there are two PCI buses from the root hub.
WinDriver v9.0.1 and below supports only the 33Mhz * 33MB PCI bus.

Therefore, if you encounter problems when trying to use WinDriver to detect and access your PCI card on a Solaris SPARC machine, please verify that your card is inserted into a PCI slot on the 33Mhz*33MB PCI bus.

Back To Top

Technical Document #68: I am trying to use DriveBuilder for VxWorks, but I fail downloading windrvr.o to the target. I get a message that the following symbols were unresolved: pciConfigInlong, pciConfigOutLong.

This error points to a failure to enable PCI support in your VxWorks OS image. You need to check your VxWorks project settings and make some changes to config.h before rebuilding the VxWorks image. These changes are OS and platform specific.
Please contact WindRiver systems’ technical support for more information.

Back To Top

Technical Document #69: I am using DriverBuilder for VxWorks. I loaded pci_diag.out and ran pci_diag_main, but if failed with the following error message: Error loading driver

Please verify that you have followed all the steps in the WinDriver VxWorks Installation Instructions in the User’s Manual of the WinDriver version that you’re using.
Did you forget to run the drvInit() function?
This function call initializes the driver module windrvr.o that is provided by WinDriver.

Back To Top

Technical Document #70: What are the names of the entry points routines for your various DriverBuilder VxWorks sample programs: wddebug.out, pci_dump.out, etc.?

Just add "_main" after the base name of the program.
For example, the entry point routine for wddebug.out is wddebug_main and the entry point routine for pci_dump.out ispci_dump_main.

Back To Top

Technical Document #71: When running the PCI diagnostics application on a VxWorks machine, I get the following error message when trying to open the board: Card does not have all items expected for MyDrive.

This message is issued by the diagnostics XXX_Open() function if theXXX_DetectCardElemets() function fails (see xxx_lib.c for the functions implementation) — where XXX is your driver’s name.

The reason for this error may be that your PCI card has not been configured.
Intel X86 PCs normally host PCI BIOSs, which will configure the card on bootup. Your target computer may not have such a BIOS.
Some VxWorks BSPs have PCI auto configuration support, which you can build into your image so that when the target boots the image, the PCI cards will get auto-configured. The steps required are OS and platform specific. Please contact WindRiver systems’ technical support for more information.

Back To Top

Technical Document #72: I run pci_dump.out on a VxWorks machine and it shows my card having all zeros in the BARs. But when I plug the card into a Windows PC, the BARs have values.

Refer to Technical Document #71 regarding the need to configure your PCI card.

Back To Top

Technical Document #73: WD_CardRegister() failed to lock a 32MB memory range on my PCI card. The following messages appeared in the Debug Monitor log: Map_physical_mem_krnl: MmMapIoSpace failed … Map_physical_mem_krnl: Try increasing the value of SystemPages …

The debug log indicates that Windows could not map the relevant memory address range to the kernel-mode virtual address space. As indicated in the log, a possible solution for this is to increase the value of the SystemPages registry entry, in order to increase the number of page table entries in Windows’ non-paged pool table. For more information and for other methods for resolving failures to map large memory ranges, refer to Technical Document #59.

Back To Top

Technical Document #74: How do I access the memory on my PCI card using WinDriver?

First, locate the slot to which your card is connected, usingWD_PciScanCards().

Then get the card’s information by calling WD_PciGetCardInfo().
This information includes the memory range chosen for the card by the Plug and Play system.

Now call WD_CardRegister() to install the memory range and map it into both kernel and user mode virtual address spaces.

You can then either access the memory directly from your user mode application (more efficient), by using the user mode mapping of the physical address — returned by WD_CardRegister() incardReg.Card.Item[i].I.Mem.pUserDirectAddr (where ‘i’ is the index number of the memory range in the Item array) — or pass the kernel mode mapping of the memory — returned by WD_CardRegister() incardReg.Card.Item[i].I.Mem.pTransAddr — to WD_Transfer() (/WD_MultiTransfer()), in order to access the memory in the kernel.

This is demonstrated, for example, in the sample code found in theWinDriver/samples/pci_diag directory, and in the diagnostics DriverWizard code that you can generate for your PCI card.
Please also refer to the description of the WinDriver PCI API in the WinDriver PCI Low-Level API Reference (available under theWinDriver/doc/ directory) or in the Function Reference chapter of the WinDriver User’s Manual (in earlier versions) for a better understanding of these functions and the related structures.

NOTE: To access memory directly in the kernel, from within aKernel PlugIn project, you must use the kernel mode mapping of the physical memory address — returned by WD_CardRegister() incardReg.Card.Item[i].I.Mem.pTransAddr — and not the user mode mapping that is used to access the memory directly from your user-mode application.

Version Notes
The API references in this document may not match the API in earlier versions of WinDriver. In version 11.8.0 the followingWD_ITEMS I.Mem field name and type changes were made:
DWORD dwTransAddr –> KPTR pTransAddr
UPTR dwUserDirectAddr –> UPTR pUserDirectAddr

Back To Top

Technical Document #75: How do I handle PCI Interrupts from a user-mode WinDriver application?

First, locate the slot to which your card is connected, using WD_PciScanCards(). Then get the card’s information by calling WD_PciGetCardInfo(). This information includes the IRQ chosen for the card by the Plug and Play system. Now call WD_CardRegister() to install the interrupt.

Since PCI interrupts are level sensitive, you should verify that the INTERRUPT_LEVEL_SENSITIVE flag is set in cardReg.Card.Item[i].I.Int.dwOptions — where ‘i’ is the index number of the Interrupt item in the Item array. You would normally not need to set this flag explicitly in your code, since WD_PciGetCardInfo() automatically sets this flag for PCI cards and you can normaly pass the same WD_CARD structure, which was returned from WD_PciGetCardInfo(), to WD_CardRegister() (in cardReg.Card).

Level sensitive interrupts must be acknowledged (i.e., cleared) in the kernel immediately when they are received. To enable this acknowledgment of the interrupts, call InterruptEnable() (/ InterruptThreadEnable() — in versions 4.30–5.22), or the lower level WD_IntEnable() function (which is called by InterruptEnable() (/ InterruptThreadEnable())), passing to it a WD_INTERRUPT structure that holds the interrupt handle returned by the previous call to WD_CardRegister() and the relevant information for clearing the interrupt in the kernel. You should set up this information (i.e., the location of the interrupt status register that needs to be written to/read, the acknowledgment command to be performed — of type enum WD_TRANSFER_COMMAND, defined in windrvr.h — and a buffer with the data to be written\read to\from the register) in the array of WD_TRANSFER structures, which is pointed at by the Cmd member of the WD_INTERRUPT structure. Please note that the information for acknowledging and clearing the interrupt is hardware specific.

NOTE: You can use the DriverWizard to define the relevant register/s for the interrupt acknowledgment (from the “Registers” tab select “New” and define the register) and then assign the register/s to the interrupt (in the ‘Interrupt” tab), before generating the code. (Beginning with version 5.2.1 you can assign more than one register to the interrupt.) The generated code would then include transfer commands for acknowledging the interrupt, which comply with the information you have defined in your DriverWizard project.

After passing the interrupt acknowledgment information to WinDriver, you need to physically enable the interrupts. You can do this from your code by writing the relevant information to the interrupt register (this information is also hardware specific).

InterruptEnable() (/ InterruptThreadEnable() — in versions 4.30–5.22) enables the interrupts by calling WD_IntEnable(), and then creates and runs an interrupt handler thread. The interrupt thread calls WD_IntWait() to wait on the interrupt and then activates your interrupt handler routine when the interrupt occurs and WD_IntWait() returns. You can refer to the WinDriver\src\windrvr_int_thread.c file to view the implementation of InterruptEnable() (For version 4.3.0–5.22, refer to the implementation of InterruptThreadEnable() in WinDriver\include\windrvr_int_thread.h). (If you select to use the lower-level WD_IntEnable() and WD_IntWait() functions directly from your code, instead of using the InterruptEnable() (/ InterruptThreadEnable) convenience function, you will need to spawn the thread that calls WD_IntWait() yourself.) When an interrupt occurs, the interrupt acknowledgment commands that you have set up in the WD_INTERRUPT structure, before enabling the interrupts, will be executed by WinDriver at the kernel level, before WD_IntWait() returns and your handler routine is activated.

At the end, remember to call InterruptDisable() (/ InterruptThreadDisable() — in versions 4.30–5.22), or the lower-level WD_IntDisable() function (depending on how you enabled the interrupts), in order to disable the interrupts

Please note that the int.Cmd array can include more than a single WD_TRANSFER command. You can set int.Cmd to point to an array of as many WD_TRANSFER structures as you wish. You can set, for example, the first WD_TRANSFER structure in the array with a read transfer command, in order to read from the relevant register in the kernel before acknowledging the interrupt. The read result will be stored in the Data union field of the WD_TRANSFER structure, and you will be able to access it later from your user mode interrupt handler routine (e.g.: DWORD data = int.Cmd[0].Data.Dword).
It is important to note, that in order to save the data that has been read in the kernel, before acknowledging the interrupt, you will need to set the INTERRUPT_CMD_COPY flag in the dwOptions field of the WD_INTERRUPT structure (int.dwOptions |= INTERRUPT_CMD_COPY;).

The generated DriverWizard code for your card will already implement the relevant WinDriver API calls for scanning the PCI bus, registering your card’s resources (including the interrupt) and enabling and handling the interrupt. However, since the interrupt acknowledgment mechanism is hardware specific, you will need to modify the code somewhat, according to the guidelines above, in order to set up the correct acknowledgment information for the interrupt (in accordance with your hardware’s specification) and to implement your desired interrupt handler routine.

You can also refer to the WinDriver special library functions for specific PCI chip-sets (such as PLX, Altera, etc.) for examples of specific WinDriver interrupt handling code for these chips. Please note that the interrupt acknowledgment commands in the samples disable all further interrupts. You should therefore re-enable the interrupts from your interrupt handler routine. (You can do this by adding at the end of your XXX_IntHandler() or XXX_IntHandlerRoutine() routine a similar line to that used for enabling the interrupts from XXX_IntEnable()).

For a detailed explanation of the WinDriver interrupt handling mechanism and relevant code samples, please refer to the “Handling Interrupts” section of the WinDriver PCI User’s Manual (see specifically the sub-section regarding PCI Interrupts). Please also refer to the function reference in the manual for a better understanding of the relevant functions and structures and their usage.

To increase the flexibility of your interrupt code and improve the interrupt handler rate, consider using WinDriver’s Kernel PlugIn feature to acknowledge and handle the interrupts directly in the kernel.

Back To Top

Technical Document #76: How do I perform PCI DMA Writes from system memory to my card, using WinDriver?

Your device needs to be PCI DMA Master Capable.
After locating and registering your PCI card (using WD_PciScanCards(), WD_PciGetCardInfo() and WD_CardRegister()), you need to lock a memory buffer. To do this, call WD_DMALock() to lock a memory buffer in the kernel and receive an array of pages (dma.dwPages) representing the physical address/es of your buffer.
(For contiguous-buffer DMA the array will contain a single page.)

NOTE
For more information regarding DMA handling and the related APIs, refer to the WinDriver PCI User’s Manual.
The newer versions of WinDriver use the high-level WDC APIs, and document the low-level WD_XXX APIs in the WinDriver PCI Low-Level API Reference.
The manuals for your version are available in the docs/ directory of your WinDriver installation.
Now it is up to you to program your bus-master device with the page list and send a command for your card to start the transfer.
Programming a PCI device for DMA transfer is device specific.
Examples of DMA functions, using our API, can be found in the special WinDriver libraries for the enhanced WinDriver supported PCI chip sets for major PCI chip vendors, such as PLX, Altera, and Xilinx; (see the WinDriver PCI User’s Manual for more information regarding this enhanced support).

At the end of the transfer you should call WD_DMAUnlock() to release the buffer’s locked physical memory.

Back To Top

Technical Document #77: How do I perform Direct Block transfers from one PCI card to another?

Locate and register both cards (using WD_PciScanCards(), WD_PciGetCardInfo() and WD_CardRegister()).
At least one of the cards must be PCI DMA Master Capable.
Program it with the physical address of the Slave card. Obtaining this address is possible by using pciCard.Card.Item[i].I.Mem.pPhysicalAddr (or dwPhysicalAddr before v11.8.0), set by WD_PciGetCardInfo() for the slave card.

(Refer to the WinDriver User’s Manual for more information regarding DMA handling and the related APIs. In newer versions of WinDriver, WD_DMALock() is described in the WinDriver PCI Low Level API Reference.)

A sample of programming the DMA can be found, for example, in the WinDriver PLX library and the samples that use it.

Back To Top

Technical Document #79: Does WinDriver support 64-bit data transfers?

Yes. Beginning with version 5.2.0, WinDriver supports 64-bit data transfers. Please refer to the WinDriver PCI User’s Manual for detailed information regarding this support. The usage of WinDriver’s 64-bit API is demonstrated in the special library functions for the PLX 9656 chip (available under the WinDriver/plx/9656/ directory).

Please note that even with earlier versions of WinDriver, once you have mapped the memory on your card (using WinDriver), you could directly access the memory in a 64-bit access pattern. You would, however, need to use a 64-bit compiler to generate code that has this capability. WinDriver itself (until version 5.2.0) does not assist you in this, because it has no knowledge of 64-bit code, but with a good 64-bit compiler and some experimentation, you can probably enjoy the 64-bit performance with earlier versions of WinDriver as well.

Back To Top

Technical Document #80: I have a PLX 9050 card, but I cannot access the card’s memory with WinDriver’s PLX 9050 diagnostics utility. I am using the P9050_Read/WriteXXX() functions.

When using WinDriver’s sample P9050_Read/WriteXXX() functions, you must set the values of the re-map register in the p9050_lib.c file (this depends on your hardware). The card may hang if the wait-states are not set correctly.

Since many developers are not aware of this feature, and they prefer to set the re-map register in the EEPROM init (when the computer is turned on), beginning with version 3.0.3 of WinDriver we have added new functions to the PLX 9050 library, which access the PLX 9050 card’s address ranges without changing the re-map register. These functions areP9050_ReadSpaceByte() and friends. When using a WinDriver version 3.0.3 and higher, you can use these functions by selecting to “Access address spaces on the board” instead of selecting to “Access local address ranges on the board” from the main menu of the WinDriver PLX 9050 diagnostics utility.
This option uses P9050_ReadSpaceByte() and the similar Read/Write Space functions, instead of the “regular” P9050_ReadByte() (and similar) functions. The “regular” P9050 Read/Write function first set the re-map register, then call the relevant Read/Write Space function (e.g.,P9050_ReadByte() calls P9050_ReadSpaceByte()).

If you do not want WinDriver to set the re-map register, but prefer a low-level access (like DriverWizard and PLX-MON do), call the Read/Write Space functions (like P9050_ReadSpaceByte()).

Back To Top

Technical Document #81: The values of all the registers on my PLX 9050 card are zero. What could be the reason?

This may be the result of a problem connected with the BIT7 errata on the PLX 9050 chip. This is a hardware problem, which was solved by PLX in the PLX 9052 chip. For more detailed information on this problem and possible solutions, refer to Technical Document #83.

Back To Top

Technical Document #82: How can I use the PLX burst mode to increase the read speed?

First, please make sure that the burst enable bit is set in the PLX registers (You can read/write the PLX registers by using P9050_ReadReg() andP9050_WriteReg(), or similar functions from the WinDriver special library functions for other PLX boards).

In order to perform burst transfers you need to read/write from consecutive addresses. The Block transfer functions in the special WinDriver PLX API already implement this.

Most of today’s PCI chipsets detect the writes and transform them into a burst.
We have had customers who reported reaching 60MB/S this way.
However, many PCI chipsets today do not detect reads, and you will therefore not be able to perform burst reads with these chips.

The transfer rate you can achieve with the PLX 9050 chip is 8-10 MB/S.
There are some PLX9050 settings you can set (pre-fetching) that will allow you to reach 20MB/S on read. More information regarding setting the pre-fetching option can be found on the PLX website. However, please remember that pre-fetching is not good for reading information from a FIFO buffer, since in this mode the PLX 9050 reads MORE data than it really needs.

Back To Top

Technical Document #83: When using multiple PLX 9050 cards I occasionally get the error Do_card_lock failed: item already in use, and pci_dump indicates a memory resource overlap in BAR0. I can sometimes resolve this by moving cards to other PCI slots.

The change in the BARs is due to the PLX 9050 BIT 7 errata.
The PLX 9050 chip has a problem of accessing the card address spaces if the BAR0 register was given the value 1 in its BIT 7 (by the BIOS).
Our attempted fix (in WinDriver\plx\9050\lib\p9050_lib.c) is to zero this bit and then continue to work with the card. In your particular case, this caused a resource overlap.

To resolve the overlap, you can do one of the following:

    • Replace your cards with PLX 9052 based cards (recommended).
      The PLX 9052 chip resolved the bug of the PLX 9050 chip.

 

    • Reprogram the BARs yourself or relocate the PCI cards so that BAR0 does not have the 7th BIT set.

 

  • Add the P9050_OPEN_FIX_BIT7 option in your call toP9050_Open():
    In the file p9050_lib.c change:  if(P9050_Open(&hPlx, dwVendorID, dwDeviceID,
    my_card − 1, 0 /* P9050_OPEN_USE_INT |
    P9050_OPEN_FIX_BIT7 */
    ))

    to:

      if(P9050_Open(&hPlx, dwVendorID, dwDeviceID,
    my_card − 1, 0 P9050_OPEN_FIX_BIT7))

    Recompile and run.

    However, please note that you might not be able to access the memory spaces on the cards if you select this option.

More information on this subject can be found on the PLX website.

Back To Top

Technical Document #84: Upgrading your WinDriver version

This document outlines the steps for upgrading from version 8.1.1 or newer to the latest WinDriver version. For upgrade instructions from an earlier version of WinDriver and/or to an earlier version, refer to Technical Document #131.

 

Upgrade Steps

  1. Install the new version
  2. Acquire a New WinDriver License (Registered Users)
  3. Upgrade Your Driver Project
  4. Upgrade Your Device INF File (Windows)
  5. Digitally Sign Your Driver Files (Windows)
  6. Upgrade Your Driver Distribution/Installation Package

 

  • Install the new version

Download and install a new version of WinDriver that matches your development platform and the operating systems and CPU configurations of the target platforms on which you intend the driver to be used.

  • Acquire a New WinDriver License (Registered Users)

If you are using a registered version of WinDriver, contact Jungo Connectivity at [email protected] to acquire a WinDriver license registration string for the new version. Then register the new license from DriverWizard (File | Register WinDriver) and from your code.

Note that if you have a valid Support and Upgrade plan you are are entitled to receive a new license free of charge.
If you do not have such a plan, contact [email protected] to request a temporary license that will allow you to evaluate the new version.

  • Upgrade Your Driver Project
      • Register Your New License (Registered Users): Modify the driver code to register your new license — i.e., replace the license string in the call to WDU_Init() (USB) /WDC_DriverOpen() (PCI/ISA — WDC API) / WD_License()(low-level API) from your code.PCI users — if you created a Kernel PlugIn driver, make sure to also update the license string in your Kernel PlugIncode.
      • PCI/ISA users upgrading from v11.7.0 or below — refer to Technical Document #116 for information on API changes done in v11.8.0 of WinDriver, and edit your code accordingly.

 

      • 64-bit OS upgrade (Windows and Linux)
          • When developing a driver for a 64-bit platform, your project or makefile must include the KERNEL_64BITpreprocessor definition. In the makefiles, the definition is added using the -D flag: -DKERNEL_64BIT. The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects in the 64-bit WinDriver toolkit already add this definition.
        • PCI Kernel PlugIn upgrade from v10.2.1- — to support execution of 32-bit applications with a 64-bitKernel PlugIn driver, follow the instructions in Technical Document #112.

 

      • Rename your driver (Windows and Linux) — To avoid conflicts with other WinDriver-based drivers on the target platforms, we highly recommend that you rename the default WinDriver driver module — windrvr<version>.sys(e.g., windrvr1200.sys) on Windows /windrvr<version>.o/.ko (e.g., windrvr1200.o/.ko) onLinux (or windrvr6.sys / windrvr6.o/.ko in v11.8.0 and older) — to a unique name, by following the instructions in the new WinDriver User’s Manual. The renaming procedure is simple and quick.
        The Linux USB GPL driverwindrvr<version>_usb.o/.ko (or windrvr6_usb.o/.koin v11.8.0 and older) is automatically renamed when renaming the main WinDriver Linux driver.
        When creating a PCI Kernel PlugIn driver, select a unique name as well.

 

      • Ensure that your code uses the correct driver module— Verify that the call to WD_DriverName() in your driver code (if exists) uses the new driver-module name —windrvr<version> or your renamed version of this driver.
        In version 11.9.0 of WinDriver the default WinDriver driver-module name changed from windrvr6 towindrvr<version> (e.g., windrvr1200 in v12.0.0). Consequently, when using the default driver-module name old projects need to be updated to use the default name from the newer version. If you use the generated DriverWizard code or one of the samples from the new WinDriver version, the code will already use the default driver name from the new version. Also, if your code is based on generated/sample code from an earlier version of WinDriver, rebuilding the code with windrvr.h from the new version is sufficient to update the code to use the new default driver-module name (due to the use of theWD_DEFAULT_DRIVER_NAME_BASE definition).
        If you elect to rename the WinDriver driver module, ensure that your code calls WD_DriverName() with your custom driver name. If you rename the driver from the new version to a name already used in your old project, you do not need to modify your code.

        NOTE
        To apply a driver name change — whether using the default driver name or a custom name — your user-mode driver project must be built with theWD_DRIVER_NAME_CHANGE preprocessor flag (e.g., -DWD_DRIVER_NAME_CHANGE), as explained in the WinDriver WinDriver User’s Manuals and demonstrated in the sample and generated DriverWizard WinDriver projects/makefiles.

 

      • Rebuild your updated driver project with the source files from the new version.PCI users who created a Kernel PlugIn driver must rebuild it with the files from the new version as well.

  • Upgrade Your Device INF File (Windows)

On Windows, if you have created a driver for a Plug-and-Play device (USB/PCI/CardBus/PCMCIA), we recommend that you create and install a new INF file for your device, which registers it with the driver module from the new version —windrvr<version>.sys (e.g., windrvr1200.sys) /windrvr6.sys in v11.8.0 and older — or your renamed version of this driver (in v9.x and newer). You can use DriverWizard from the new version to generate the new INF file, or change the driver version in your old INF file.

  • Digitally Sign Your Driver Files (Windows)

On 64-bit versions of Windows Vista and higher

      , Microsoft requires that kernel drivers be digitally signed. Therefore, if you use any of the following driver files you must digitally sign them: A

renamed

      version of the WinDriver kernel driver (the default WinDriver driver —

windrvr<version>.sys

      /

windrvr6.sys

      in v11.8.0 and older — is already digitally signed), a

Plug-and-Play device INF file

      , and/or a

PCI Kernel PlugIn driver

      . You can bypass this restriction during the development stage (e.g., on Windows 7, by pressing

F8

      at boot time and selecting the relevant option), but the driver files must be signed before distribution. There are also advantages to signing your driver

on other Windows OSs

      . For more information, refer to

Micorsoft’s Driver Signing Policy

      and to the

Windows Digital Driver Signing and Certification

      section of the

WinDriver User’s Manuals

      .

You can obtain digital signatures from third-party companies such as DigiCert or Symantec, or use Jungo Connectivity’s digital driver signing service. Jungo Connectivity can also assist you in preparing your driver for Microsoft’s Windows cetification.

  • Upgrade Your Driver Distribution/Installation Package

Create a new driver installation package that contains the relevant files from the new WinDriver distribution, depending on your hardware and target OS:

      • The WinDriver driver module —windrvr<version>.sys/.o/.ko/.dll (e.g.,windrvr1200.sys/.o/.ko/.dll) in the newer WinDriver versions, or a renamed version of this driver
      • The WinDriver Linux USB GPL driverwindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) in the newer WinDriver versions, or a renamed version of this driver
      • Your rebuilt PCI Kernel PlugIn driver —<KP_driver_name>.sys (if created)
      • Any other files required for installing or using your driver — such as wdapi<new_version>.dll/.so,wdreg[.exe]/wdreg_gui.exe (and difxapi.dll on Windows), and Windows INF and catalog files
      • An installation program that installs the new driver

Hardware- and OS-specific driver distribution instructions can be found in the Distributing Your Driver chapter of the new WinDriver User’s Manuals. The instructions for Windows are also summarized in Technical Document #132.

Version-Specific Installation Upgrade Notes:

    • Linux USB v9.2.1- to v10.0.0+ upgrade — the WinDriver USB Linux GPL driver: Beginning with v10.0.0, the WinDriver Linux USB driver was split into two modules, which are used together to provide the full driver functionality:
      • windrvr6.o/.ko, renamed in v11.9.0 towindrvr<version>.o/.ko (e.g.,windrvr1200.o/.ko) — the traditional WinDriver driver module, which includes the product license.
      • windrvr6_usb.o/.ko, renamed in v11.9.0 towindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) — this driver implements Linux-specific USB driver functionality, and contains a GNU General Public License (GPL).

Back To Top

Technical Document #85: How do I extract the string descriptors contained in the Device and Configuration descriptor tables?

You can use WinDriver’s WDU_GetStringDesc() function to get the desired string descriptors. For detailed information regarding this function, refer to the WinDriver USB User’s Manual.

Back To Top

Technical Document #86: How do I detect that a USB device has been plugged in or disconnected?

If you are using version 5.2.0 or later of WinDriver, you can use WinDriver’s API to register to listen to specific Plug-and-Play and/or power management notifications from the OS, including notifications of device insertion/removal, and implement a relevant callback in your application to handle such situations. When using version 6.0 and above, useWDU_Init() to register to listen for the notifications you are interested in.In versions 5.2.0–5.2.2, use event_register(). Please refer to the WinDriver User’s Manual for the WinDriver version that you are using for a detailed description of the relevant APIs.

In earlier versions of WinDriver — version 5.0.5b or below — WinDriver did not provide specific API support for Plug-and-Play and power management events. In these versions, WD_UsbScanDevice() detects the devices which are connected to the computer at the time of the function call. If another device is later connected to the computer, or a device is disconnected, these changes will not automatically be detected.WD_UsbScanDevice() must be called again in order to detect the changes. However, since WinDriver USB drivers are user mode WIN32 applications, they can get a notification of insertion/removal. Windows sends all applications a WM_DEVICECHANGE message. Once the application receives this message it should call WD_UsbScanDevice() to check if the device was inserted/removed (this is only good for Windows). You should therefore be able to implement PnP device insertion/removal support with earlier versions of WinDriver as well, using the Win32 API. You can also send aGET_DESCRIPTOR request to the device (using WD_UsbTransfer() to verify if the device is connected. Please note that in order to handle the device after it has been disconnected, you must first callWD_UsbDeviceUnregister() to free the previous handle to the device, then re-scan the USB bus to locate the device (using WD_UsbDeviceScan()), get the device’s configuration information (by callingWD_UsbGetConfiguration() and re-register the device by callingWD_UsbDeviceRegister().

Back To Top

Technical Document #87: How do I setup the transfer buffer to send a null data packet through the control pipe?

You should set the pBuffer parameter of the WDU_Transfer() function toNULL and set the dwBufferSize parameter to 0.

In version 5.2.2 and earlier, set the pBuffer field of the WD_USB_TRANSFERstructure, used in the call to WD_UsbTransfer(), to NULL, and set thedwBytes field of this structure to 0.

Back To Top

Technical Document #88: Can I write a driver for a USB hub or a USB Host Controller card using WinDriver?

No. Windriver USB is designed for writing drivers for USB devices (USB client drivers). It cannot be used to write a USB hub or a USB Host Controller driver.

Back To Top

Technical Document #89: WinDriver driver distribution to a target Windows machine — versions 4.2.0–5.0.5b

In order to distribute your WinDriver-based driver to a target Windows machine (which does not have the WinDriver software installed), when using version 4.2.0–5.0.5b of WinDriver, please follow the instructions below.

1. Copy the windrvr.sys or windrvr.vxd driver file (depending on your OS) and your Kernel PlugIn SYS/VxD driver (if you have created such a driver) to the target computer’s drivers’ directory (e.g., WINNT\system32\drivers) and then install the driver/s using WinDriver’s WDREG.EXE utility program (found in theWinDriver\util directory on the development machine) — as explained in the “Distributing Your Driver Chapter” of the manual.

To install windrvr.sys or windrvr.vxd (on Windows 95) simply type:
    wdreg install.
To install windrvr.vxd on Windows 98/Me type:
    wdreg -vxd install
(since by default wdreg.exe installs windrvr.sys).

(windrvr.sys and windrvr.vxd are found, on the development machine, in the WinDriver\redist\register directory — for registered users, or in the WinDriver\redist\eval directory — for evaluation users.)

If you have created a Kernel PlugIn driver, install it using thewdreg.exe utility:

  • To install a SYS driver type:
        wdreg -name <KP driver name> install

 

  • To install a VxD driver, use the -vxd flag:
        wdreg -vxd -name <KP driver name> install

NOTE: The driver name should be indicated without the*.sys/*.vxd extension.

(You can also use the -startup flag to determine the driver’s startup option: boot/system/automatic/manual (on demand).)

For more information regarding the wdreg.exe utility, please refer to the “Dynamically Loading Your Driver” chapter of the manual.

2. Copy your WinDriver executable/DLL file, which implements the driver functionality, to the target.

3. For Plug & Play devices (such as PCI and USB), if you are installing the driver on a target machine running a PnP operating system (e.g., Windows 98/Me/2000/XP), you will also need to copy the PnP driver file — wdpnp.sys (found in the WinDriver\redist directory on the development machine) — and an INF file to the target machine, and install the INF file on the target — as explained in the relevant section of the Driver Distribution chapter of the manual and in the installation instructions that will be displayed when you select to generate an INF file for your device with the DriverWizard. (wdpnp.sys replaced the wdusb.sys driver that was used in earlier versions of WinDriver.)

The default INF file that is generated by the DriverWizard copieswdpnp.sys to Windows’ drivers’ directory.
(You can also use this file to copy windrvr.sys to the drivers’ directory, by removing the comment (;) at the beginning of the following line in the generated INF file: ;windrvr.sys.)

The installation of the INF file should direct Windows’ Plug & Play Manager to wdpnp.sys as the driver for your device.
You can verify this at the end of the installation by locating your device in the Device Manager and selecting ‘Properties’ –> ‘Driver’ –> ‘Driver Details…’.

 

 

Back To Top

Technical Document #90: Installing an INF file for PCI/USB devices on Windows Plug and Play systems in WinDriver versions 4.20–5.05

When using version 4.2.0–5.0.5 of WinDriver to install a PCI/USB driver on a Plug and Play (PnP) system (Windows 98/Me/2000/XP), two driver files are required for the installation:

  1. windrvr.sys/vxd, found in the WinDriver\redist\register /WinDriver\redist\eval directory. This driver implements WinDriver’s kernel module and should be installed using the wdreg.exeinstallation utility. [windrvr.sys (or windrvr.vxd — on Win95) is automatically installed on the development machine when installing the WinDriver tool-kit].
  2. wdpnp.sys (or wdusb.sys — in versions 4.2.0–4.3.2), which is located in the WinDriver\redist directory. This driver should be installed via the installation of an INF file.

You can use the DriverWizard to generate an INF file for your device.
After generating the INF file, you need to update the driver for the device, using Windows’ Device Manager or the “Found New Hardware” wizard — as explained in the dialog box that pops up when you finish generating the INF file with the DriverWizard and in the Driver Distribution chapter in the manual forversions 4.2.0–5.0.5.

To install the INF file from the Device Manager, follow these steps:

  1. Open Window’s Device Manager and locate your device (from the Menu select ‘View’ –> ‘Devices by connection’, and look for your device under the PCI bus / PCI bus -> USB Host Controller -> USB Root Hub). For USB devices, please be sure to select the node for your device that appears directly under the USB hub.
  2. Right-click the mouse on the device’s node and select'Properties', then select the ‘Driver’ tab and click on‘Update driver…’.
  3. In the ‘Upgrade Device Driver Wizard’ first installation window select ‘Next’, then choose ‘Search for a suitable driver for my device’ from the 'Install Hardware Device Drivers' window and click ‘Next’.
  4. In the 'Locate Driver Files' window choose ‘Specify a location’ then click ‘Next’.
  5. In the ‘Upgrade Device Driver Wizard’ window that will be displayed, specify the location of the .INF file (you can use the ‘Browse…’ option to locate the file) then click ‘Next’. If asked to specify the driver for the device, point to the location of the wdpnp.sys file.
    At the end, click ‘Finish’.
  6. Reboot (not always required).

To somewhat automate the installation you can copy both the generated INF file and wdpnp.sys to Windows’ inf‘ directory, when the device is disconnected, then plug-in the device.
At this point, the OS should automatically identify the INF file for your device and install it. However, you may still be prompted to direct the OS to the location of the wdpnp.sys driver file.

At the end of the installation, verify that wdpnp.sys has been installed successfully by locating your device in the Device Manager and selecting ‘Properties’ –> ‘Driver’ –> Driver Details…’.

If wdpnp.sys is not indicated as the driver after the installation of the INF file, please erase all oem*.inf and corresponding *.pnf files from Windows’ ‘inf‘ directory (for Windows 98/Me, look underinf\other), and then attempt to reinstall the INF file — in order to ensure that Windows is not inadvertently installing the wrong INF file for your device, by , and then try to reinstall the INF file.

Back To Top

Technical Document #91: Does WinDriver USB support isochronous streaming mode?

Yes. WinDriver provides WDU_StreamXXX() functions for peforming streaming USB data transfers on Windows 2000 and higher (WinDriver v9.0.0+) and Windows CE (WinDriver v10.0.1+).
For more information, refer to the WinDriver USB User’s Manual.

Back To Top

Technical Document #94: Does WinDriver support development of drivers for CardBus devices?

Yes. From a software point of view, CardBus behaves like PCI. Therefore, WinDriver supports CardBus in the same manner that it supports the PCI bus, and you can use the WinDriver PCI toolkit and its API to develop a CardBus device driver as well.

Back To Top

Technical Document #95: Does WinDriver support development for PCMCIA devices?

Starting with version 6.2.2, WinDriver supports PCMCIA on Windows.
The latest WinDriver Windows version (v12.0.0) supports PCMCIA on Windows 10/8.1/Server 2012 R2/8/Server 2012/7/Server 2008 R2/Vista/Server 2008/Server 2003/XP.

In earlier versions, you can use WinDriver to develop a driver for a PCMCIA card by defining the card’s resources manually and handling the card as a regular ISA card. (Plug and Play detection of the card’s resources is not supported for PCMCIA, in v5.0.4–v6.2.1 of WinDriver).
Alternatively, consider replacing your PCMCIA hardware with a CardBus card (recommended) — see Technical Document #94 for information regarding WinDriver’s support for CardBus.

Back To Top

Technical Document #97: Can WinDriver share the Parallel/Serial port with Windows’ drivers?

Windows does not allow sharing the port. Therefore, if you choose to use WinDriver to access the parallel/serial port, you may first need to disable Windows’ parallel/serial port driver, then do your own I/O.

Note that you cannot use WinDriver to implement a standard serial port driver that replaces the Windows serial port driver.

Back To Top

Technical Document #98: Can I access the same device, simultaneously, from several WinDriver applications?

It is possible to create several WinDriver-based driver processes that will access the same card, although we do not recommend this and it should not generally be required.

Should you decide to implement such a design, consider the synchronization issues carefully. To bypass the synchronization problems, we recommend you use only one point of access to your hardware. Use a single process to directly access your hardware, while the other processes should access the hardware only via this process. The advantage of this design is that only one point requires synchronization.

Please note, however, that we will not be able to provide technical support relating specifically to the implementation of such designs and related problems (such as synchronization problems that might occur) and you should therefore carefully consider if this is indeed the desired design in your case.

For USB, note that while multiple calls to WDU_Init() for the same device may succeed, after the first attach callback accepts control of the device no other attach notifications will be received until WDU_Uninit() is called for the relevant WDU_Init() call. Using a single process to perform a singleWDU_Init() call with a single attach callback function, as suggested above, will eliminate problems resulting from multiple WDU_Init() calls.
For PCI/PCMCIA/ISA, refer to Technical Document #21 for further information regarding the significance of multiple calls to theWD_CardRegister function.

Back To Top

Technical Document #99: Programming the Serial Port — a brief introduction

The serial port hardware has several registers to cater to different functionalities. Some of the useful registers are:

Line control register       LCR
     For configuring the serial port. (Address: comport + 3)
Receiver buffer register    RBR
     Holds the data received via the serial port. (comport + 0)
Transmitter Buffer register TBR
     Holds the data to be transmitted.(comport + 0)
Line status register        LSR 
     Holds the info regarding the line status.(comport + 5)

where comport should be replaced with your COM1 or COM2 address.

Following are some basic guidelines for programming the serial port:

  1. To program the serial port you must first initialize the Line Control register of your port with the required baud rate, number of data bit, desired Parity etc. The initialization value is 0x03 for a no parity, 1 stop bit and 8 data bit configuration.
  2. Then you must read the LSR to see if any data is received.
  3. If data is received then you must read the data from the RBR.
  4. For writing data, you must check the LSR to see if the port is ready to send data.
  5. Then you must write the data to the TBR to send data via the port.

This is just a very brief introduction and you need to pick up more to go into serial programming.

Back To Top

Technical Document #100: The card I want to drive currently has an interrupt service routine in DOS/16-bit. How do I create a 32-bit interrupt routine for my card?

Run the DriverWizard: WinDriver/DriverWizard/wdwizard; on Windows you can also run the wizard using the related Desktop shortcut icon, or from the Start menu: Start –> Programs –> WinDriver –> DriverWizard. Select to create a new driver project and then choose the “ISA Card” option from the dialog that appears. Define your card’s interrupt and select to generate code for the card. From the code generation dialog, select the code language and compiler/IDE for which the code should be generated. Now, build the generated code using your selected 32-bitcompiler.
You have just created a program that installs an interrupt handler routine on your interrupt and a sample diagnostics application that prints on the screen each incoming interrupt.

Back To Top

Technical Document #101: I need to be able to count the number of interrupts occurring and possibly call a routine every time an interrupt occurs. Is this possible with WinDriver?

Yes. You can use the DriverWizard to generate a diagnostics code for your device, which includes a skeletal interrupt handling mechanism that also monitors the number of interrupts received. (You may need to modify the code slightly to suit your hardware’s specification with regard to interrupt handling).

You can also refer to the int_io sample, which is available under theWinDriver/samples/int_io/ directory, for an example of handling ISA interrupts with WinDriver.

Both the sample and the generated code will install an interrupt and spawn a thread that waits on it. The number of interrupts received is returned in the dwCounter field of the WD_INTERRUPT structure.

Back To Top

Technical Document #102: Does WinDriver poll the interrupt (Busy Wait)?

No. When calling WD_IntWait() (which is called from the high-levelWDC_IntEnable() and InterruptEnable() APIs) the calling thread is put to sleep. CPU cycles are not wasted on waiting. When an interrupt occurs the thread is awaken and you can perform your interrupt handling.

Back To Top

Technical Document #103: Can I write to disk files during an interrupt routine?

Yes. WinDriver enables you to implement your interrupt service routine (ISR) in the user mode, thereby allowing you to perform all library function calls from within your ISR. Just remember to keep it short, so you don’t miss the next interrupt.

If you select to implement your ISR in the kernel, using WinDriver’sKernel PlugIn feature (described in the WinDriver User’s Manual), you will not be able to use the standard user mode file I/O functions. You can either leave the file I/O handling in the user-mode ISR, and implement your interrupt code so that the user-mode interrupt routine is executed only once every several interrupts. (You can refer to the generated DriverWizard Kernel PlugIn code and/or to the generic WinDriver Kernel PlugIn sample — WinDriver/samples/pci_diag/kp_pci/kp_pci.c (v7.0.0 and above) / WinDriver/kerplug/kermode/kptest.c (v6.2.3 and below) — for an example of monitoring the interrupt count); or replace the user-mode file I/O code with calls to OS-specific functions, which can be called at the kernel level (for example, the WDK ZwCreateFile(), ZwWriteFile()and ZwReadFile() functions). Please note, however, that this will diminish your driver’s cross-platform portability.

Back To Top

Technical Document #104: How can I read the value of the PCI interrupt status register from my WinDriver ISR, in order to determine, for example, which card generated the interrupt when the IRQ is shared between several devices?

When handling the interrupts from the user mode you must acknowledge (clear) the interrupt on the card whether your card generated the interrupt or not (in case of shared IRQs). However, this does not necessarily present a problem. To determine which card generated the interrupt, and activate your ISR only in case the interrupt was generated by your card, you can set up the transfer commands of the WD_INTERRUPT structure, which is passed to InterruptEnable() (/InterruptThreadEnable() — in versions 4.30–5.22), or to the lower levelWD_IntEnable() function — int.Cmds — to include a command to read from the interrupt register before clearing the interrupt. The register will then be read in the kernel, immediately when an interrupt is received and before it is cleared, and you will be able to access the read value from your user mode interrupt handler routine when it is activated. Please notethat in order to save the read value you must set the INTERRUPT_CMD_COPYflag in the dwOptions field of the WD_INTERRUPT structure (int.dwOptions |= INTERRUPT_CMD_COPY). For more information — see the WinDriver User’s Manual and Technical Document #75, which describes the user mode interrupt handling with WinDriver.

When using WinDriver’s Kernel PlugIn feature to handle the interrupts directly in the kernel, you can read the value of the interrupt status register on your card directly when an interrupt is received, from within your KP_IntAtIrql() routine, and proceed to acknowledge (clear) the interrupt and execute your ISR only if the value of the status register indicates that the interrupt was indeed generated by your card. For more information on how to handle shared PCI interrupts from the Kernel PlugIn, refer to Technical Document #125.

Back To Top

Technical Document #105:

PCI uses level sensitive interrupts, which must be acknowledged and cleared in the kernel immediately when they are received. Therefore, WinDriver requires you to define an interrupt-status register that will be read/written in order to clear the interrupt. This is a precautionary measurement, because a level sensitive interrupt that is not acknowledged can hang your PC.

To listen to PCI interrupts with the DriverWizard, follow these steps:

  • Define the interrupt-status register: In the DriverWizard’sRegisters tab, select New and define a new register. You should specify the register’s name, location (i.e., offset into one of the BARs), size, and access mode (read/write).
    The interrupt-acknowledgment information is hardware specific. You should therefore review your hardware’s specification for the relevant data to set for your specific device.

 

  • Assign the interrupt-status register to your card’s interrupt: After defining the interrupt-status register, go back to theInterrupts tab and assign the interrupt that you have defined to the card’s interrupt:
    Select your interrupt and click on the Edit button to display theInterrupt Information dialog box. Select the register you have defined from the drop-down list in the Access Register box. and fill-in the additional information required for acknowledging the interrupt — i.e., read/write mode and the data (if any) to be written to the status register in order to acknowledge and clear the interrupt. Beginning with version 5.2.0 of WinDriver, you can define several commands for execution upon an interrupt, by simply clicking the More button in the Interrupt Informationwindow.
    You should also verify that the interrupt is defined as Level Sensitive and that the Shared box is checked (PCI interrupts should generally be shared).

(This issue is also explained when clicking the Help button in theInterrupt Information dialog box.)

You can now try to listen to the interrupts on your card with the DriverWizard, by clicking the Listen to Interrupts button in theInterrupts tab, and then generating interrupts in the hardware. The interrupts that will be received will be logged in the Log window. To stop listening to the interrupts, click the Stop Listen to Interrupts button in the Interrupts tab.

For a detailed explanation regarding handling PCI interrupts with WinDriver, refer to the WinDriver PCI User’s Manual.

Back To Top

Technical Document #106: How do I perform system or slave DMA using WinDriver?

WinDriver supports the implementation of interrupt service routines and locking down DMA buffers into memory, giving you the physical addresses and lengths of the kernel DMA buffer.
Assuming you want to implement slave DMA for an ISA card, you will need to write the code to program the DMA controller yourself (please refer to http://support.microsoft.com/kb/q179489/ for more details). There is no specific API to program the system DMAC on PCs, but you can use the generic WinDriver API for direct hardware access and DMA allocation from your application (see specifically WDC_ContigBufLock(),WDC_SGBufLock, and the WDC_Read/WriteXXX APIs (v7.0.0+) ; or the lower-level WD_DMALock() and WD_Transfer() APIs).

Back To Top

Technical Document #107: When performing data transfers with WD_UsbTransfer(), what is the significance of the USB_SHORT_TRANSFER and USB_FULL_TRANSFER flags (versions 5.0.4–5.2.2)?

These flags are available beginning with version 5.0.4 of WinDriver.

When the USB_SHORT_TRANSFER flag is set, then WD_UsbTransfer() will return on one of two occasions:

  1. A short packet (i.e., less than the maximum packet size) was transferred or the device transferred a zero (0) packet, to indicate a short transfer. In this case fOk will be TRUE.
  2. The time-out period (specified in usbTrans.dwTimeout) expired before a short packet was transferred (or a zero packet was received). In this case fOk will be FALSE.

When the USB_FULL_TRANSFER flag is set, then WD_UsbTransfer() will return on one of the following two occasions:

  1. The entire buffer (usbTrans.dwBytes) was filled/written. In this casefOk will be TRUE.
  2. The time-out period expired before the buffer was entirely filled/written. In this case fOk will be FALSE (although some data may very well have been transferred).

By default, the USB_SHORT_TRANSFER flag is set for bulk and interrupttransfers and the USB_FULL_TRANSFER flag is set for isochronous transfers.Control transfers are always short transfers.

In former versions of WinDriver (until, and including, v5.0.3),WD_UsbTransfer() behaved (for all types of transfers) as described above for the USB_SHORT_TRANSFER flag in v5.0.4 and above — i.e., the function always returned on one of two occasions:

  1. A short packet (i.e., less than the maximum packet size) was transferred or the device transferred a zero (0) packet, to indicate a short transfer — in which case fOK would have been TRUE (even if the buffer was not entirely filled/written).
  2. The time-out expired without any such transfer — in which casefOK would be FALSE.

Back To Top

Technical Document #108: Performing large PCI memory data transfers

The main methods for transferring large amounts of data between PCI-device memory addresses and a host machine’s random-access memory (RAM) are block transfers (which may or may not result in PCI burst transfers), and bus-master DMA.
Block transfers are easier to implement, but DMA is much more effective and reliable for transferring large amounts of data, as explained in this document.

NOTE
For general information on how to improve your driver’s performance with WinDriver, refer to Technical Document #17.

Block Transfers

You can use the WinDriver WDC_ReadAddrBlock() andWDC_WriteAddrBlock() functions (or the low-level WD_Transfer() function with a string command) to perform block (string) transfers — i.e., transfer blocks of data from the device memory (read) or to the device memory (write); you can use also WDC_MultiTransfer() (or the low-levelWD_MultiTransfer() function) to group multiple block transfers into a single function call. This is more efficient than performing multiple single transfers.
The WinDriver block-transfer functions use assembler string instructions (such as REP MOVSD, or a 64-bit MMX instruction for 64-bit transfers) to move a block of memory between PCI-mapped memory on the device and the host’s RAM. From a software perspective, this is the most that can be done to attempt to initiate PCI burst transfers.

Burst Transfers

The hardware uses PCI burst mode to perform burst transfers — i.e., transfer the data in “bursts” of block reads/writes, resulting in a small performance improvement compared to the alternative of single WORD transfers. Some host controllers implement burst transfers by grouping access to successive PCI addresses into PCI bursts.

The host-side software has no way to control whether a target PCI transfer is issued as a burst transfer. The most the host can do is initiate transfers using assembler string instructions — as done by the WinDriver block-transfer APIs — but there’s no guarantee that this will translate into burst transfers, as this is entirely up to the hardware. Most PCI host controllers support PCI burst mode for write transfers. It is generally less common to find similar burst-mode support for PCI readtransfers.

64-Bit Transfers

WinDriver supports performing 64-bit transfers, using QWORD string (block) transfers, on both 64-bit and 32-bit platforms (see the WinDriver PCI User’s Manual for the supported platforms). If you have64-bit PCI hardware (card and bus), you may be able to improve the transfer rate by using 64-bit transfers, even if your host platform is only32-bit. However, note that

  • The ability to perform actual 64-bit transfers requires that such transfers be supported by the hardware — including the CPU, the PCI card, the PCI host controller, and the PCI bridge — and it can be affected by any of these components or their specific combination.
  • The conventional wisdom among hardware engineers is that performing two 32-bit DWORD transfers is more efficient than performing a single 64-bit QWORD transfer; the reason is that the64-bit transfer requires an additional CPU cycle to negotiate a64-bit transfer mode, and this cycle can be used, instead, to perform a second 32-bit transfer. Therefore, performing 64-bittransfers is generally more advisable if you wish to transfer more than 64 bits of data in a single burst.

DMA

The best way to improve the performance of large PCI memory data transfers is by using bus-master direct memory access (DMA), and not by performing block transfers (which as explained above, may or may not result in PCI burst transfers).

Most PCI architectures today provide DMA capability, which enables data to be transferred directly between memory-mapped addresses on the PCI device and the host’s RAM, freeing the CPU from involvement in the data transfer and thus improving the host’s performance. DMA data-buffer sizes are limited only by the size of the host’s RAM and the available memory.

For detailed information on DMA and how to implement it with WinDriver, refer to the WinDriver PCI User’s Manual. (The low-level WinDriver DMA APIs are documented in the WinDriver PCI Low-Level API Reference.)
In addition, see the WinDriver DMA Technical Documents.

Back To Top

Technical Document #109: I fail to use windrvr.vxd from WinDriver v5.0.5 on Windows 98; the Debug Monitor has this message: USB is not implemented on this OS. The windrvr.sys driver works well.

A USB device can only use a SYS driver. It cannot use a VxD driver. The reason for this is that USB devices must use WDM (Windows Driver Model) drivers, and WDM drivers should be implemented as SYS drivers. Therefore, windrvr6.vxd (or windrvr.vxd — in version 5.2.2 and earlier) does not support USB, and you should use the windrvr6.sysdriver file instead (windrvr.sys in version 5.2.2 and earlier).

NOTE: Beginning with version 6.2.0 of WinDriver, VxD drivers are no longer supported for any of the buses supported by WinDriver (including PCI/ISA).

Back To Top

Technical Document #111: Distributing your WinDriver v5.2.x based driver to a target Windows machine

To distribute your WinDriver based driver to a target Windows machine (which does not have the WinDriver software installed), when usingversion 5.2.x of WinDriver, follow the instructions below and in the version 5.2.2 manual.

NOTE
For updated distribution instructions refer to Technical Document #132 and to the distribution chapter in the current WinDriver User’s Manual.
  1. Copy the windrvr.sys or windrvr.vxd driver file (depending on your OS) and your Kernel PlugIn driver (if you have created such a driver) to the target computer’s drivers directory — %windir%\system32\drivers — for SYS (e.g.,WINNT\system32\drivers); %windir%\system\vmm32 — for VxD. When copying the file/s, take care not to overwrite a newer version of the file with an older one. windrvr.sys and windrvr.vxd are found under theWinDriver\redist directory on the development machine.To install windrvr.sys on Windows 98/Me/2000/XP, also copywd_virtual.inf (found under the WinDriver\redist directory on the development machine) to the target machine. It is recommended to copy this file to the <WINDIR>\inf directory (WINNT\inf — on Windows 2k; Windows\inf — on Windows 98/Me/XP) to enable Windows to find and load this file automatically.
  2. Copy wdreg.exe or wdreg_gui.exe from the WinDriver\utildirectory on the development machine to the target machine.wdreg_gui.exe and wdreg.exe provide the same functionality. The difference is in the way the installation messages are displayed — graphical message boxes (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference towdreg.exe in the following instructions with wdreg_gui.exe if you wish.
  3. Install windrvr.sys/windrvr.vxd and wd_virtual.inf (on Windows 95/98/Me/2000/XP) using wdreg.exe:
  • To install windrvr.sys on Windows NT 4.0 or to installwindrvr.vxd on Windows 95/98/Me, use the installcommand:
        wdreg.exe install

On Windows 98/Me, add the -vxd flag:
         wdreg.exe -vxd install

It is recommended to run wdreg.exe with the removecommand before installing the new driver, in order to remove the existing WinDriver service (if it exists).

 

  • To install windrvr.sys on Windows 98/Me/2000/XP, use the reload command — which removes the current WinDriver service (if it exists), installs windrvr.sys and loads wd_virtual.inf:
        wdreg.exe -inf <full path to wd_virtual.inf> reloadFor example, if wd_virtual.inf has been copied toc:\WINNT\inf/:
        wdreg.exe -inf c:\WINNT\inf\wd_virtual.inf reloadNOTE: When upgrading from a previous version of WinDriver, if there are currently PCI/USB devices registered to work with WinDriver, when wdreg.exe is run on Win2k/XP, it will display a message instructing the user to either uninstall all devices registered to work with WinDriver and select Retry, or select Cancel and reboot, in order to complete the installation. Therefore, before installing the new driver it is recommended to uninstall (from the Device Manager) any PCI/USB devices that are currently registered to work with WinDriver (via an INF file).
    Alternatively, to avoid this message you can run wdreg.exewith the loadinf command, instead of the “reload” command, in order to install the new windrvr.sys andwd_virtual.inf files:
        wdreg.exe -inf <full path to wd_virtual.inf>loadinf
    Please note, however, that this will require a reboot in order to complete the installation.To complete the installation of windrvr.sys (andwd_virtual.inf) on Windows 98/Me you must alwaysreboot the PC, since dynamic loading of SYS drivers is not supported on Windows 98/Me.

4. If you have created your own Kernel PlugIn SYS/VxD driver, install your Kernel PlugIn driver using the wdreg.exe utility:
    wdreg.exe -name <Driver Name> install

If you have created a VxD Kernel PlugIn driver, add the -vxd flag to the installation command:
    wdreg.exe -vxd -name <Driver Name> install

NOTE

  1. Specify the driver name without the *.sys/*.vxdextension. For example, to install my_kp.sys on Windows 2000 run
        wdreg.exe -name my_kp install
  2. You must first install windrvr.sys/vxd (andwd_virtual.inf — when installing windrvr.sys on Windows 98/Me/2000/XP) before attempting to install your Kernel PlugIn driver.

5. For Plug-and-Play (PnP) devices — PCI/USB — if you are installing windrvr.sys on a target machine running a PnP operating system — Windows 98/Me/2000/XP — you      must also install the specific INF file for your device (generated with the DriverWizard on the development machine) in order to register your device to work with windrvr.sys.

On Windows 2000/XP you can use the loadinf option of thewdreg.exe utility in order to automatically install the INF file:
    wdreg.exe -inf <full path to INF file> loadinf

On Windows Me/98 you need to manually install the INF file from the Device Manager (using the Upgrade Device Driver Wizard:Properties –> Driver –> Upgrade Driver) or from Windows Add New Hardware Wizard — as explained in the “Distributing Your Driver” chapter of the WinDriver User’s Manual.

NOTE

  1. When upgrading from a previous version of WinDriver, before installing the new INF file, it is recommended to erase all backup INF files for any PCI/USB device that was previously registered to work with WinDriver, before installing the new INF file, in order to ensure that Windows does not install an old INF file your device, instead of the new file. (On Windows 2000/XP, look for the backup files in the%windir%/inf directory. On Windows 98/Me, look in the Windows\inf\other directory. Look for files containing the string “Jungo” and/or the vendor/device ID of your device/s and delete them. On Windows 2000/XP the files may be called “oem*.inf” (there will also be corresponding *.pnf files that you can erase or leave, as you wish). On Windows 98/Me the file names may begin with the string “Jungo”.)
  2. In previous versions of WinDriver (before v5.2.0) a separate driver file was used as the PnP driver (in addition to windrvr.sys) — wdpnp.sys and previously wdusb.sys. These drivers have become obsolete beginning with version 5.2.0 of WinDriver.

6. Copy your WinDriver executable/DLL file, which implements the driver functionality, to the directory of you choice on the target machine and run it.

Back To Top

Technical Document #112: Porting a Kernel PlugIn project developed prior to version 10.3.0, to support working with a 32-bit user-mode application and a 64-bit Kernel PlugIn driver

NOTE
For a detailed description of the Kernel PlugIn feature, and the related development process and APIs, refer to the WinDriver PCI User’s Manual.

Beginning with version 10.3.0 of WinDriver, you can communicate with a 64-bit Kernel PlugIn driver from a 32-bit user-mode application. To support such a configuration, you need to keep in mind the following points:

  • The application must open a handle to the Kernel PlugIn driver using WDC_KernelPlugInOpen() (or the low-levelWD_KernelPlugInOpen() function, if you are not using the WDC library).
    The handle cannot be opened using one of the WDC device-open functions (e.g., WDC_PciDeviceOpen()) by calling it with the name of a Kernel PlugIn driver.
    (In all Kernel PlugIn configurations, except for a 64-bit driver that interacts with a 32-bit application, either of these methods can be used to open a handle to the Kernel PlugIn from the application.)

 

  • The Kernel PlugIn driver must implement a KP_Open callback that correctly translates the 32-bit data received from the user mode, into 64-bit kernel data.
    The Kernel PlugIn driver’s KP_Init() function must set this callback in the funcOpen_32_64 field of the KP_INITstructure that it initializes. (This field was added in version 10.3.0 of WinDriver.)

    NOTE
    The callback set in the KP_INIT funcOpen_32_64 field, is called by WinDriver when a 32-bit application opens a handle to a Kernel PlugIn driver. This callback will hereby be referred to as the funcOpen_32_64 callback.
    The callback set in the KP_INIT funcOpen field is the standard KP_Open callback, which is called by WinDriver whenever an application opens a Kernel PlugIn handle, except for the specific configuration in which thefuncOpen_32_64 callback is used. This callback will hereby be referred to as the funcOpen callback.
    When writing your Kernel PlugIn driver, you can select whether to provide both of these callback types or just one of them — depending on how you plan to build the driver and how you expect it to be used. For example, if you are not planning to use the driver on a 64-bit operating system, you do not need to implement and set funcOpen_32_64.

In version 10.3.0 and above of WinDriver, the generated DriverWizard Kernel PlugIn projects, and the sample PCI Kernel PlugIn project (kp_pci), are written so as to support all types of user-mode and Kernel PlugIn configurations, including using a 32-bit application with a 64-bit Kernel PlugIn.

To modify code developed with earlier versions of WinDriver to afford the same support, follow these steps:

    1. In the user-mode code, do the following:

1. Separate the steps of opening a handle to the device and opening a handle to the Kernel PlugIn. In version 10.2.1 and below of WinDriver, the sample and generated code used the WDC_xxxDeviceOpen() functions (e.g., WDC_PciDeviceOpen()) to open both of these handles. As explained above, this method cannot be used if you also wish to work with a 32-bit application and a 64-bit Kernel PlugIn driver. If your code uses this method, modify the call to WDC_xxxDeviceOpen() so that you pass NULL for the last two parameters —pcKPDriverName and pKPOpenData.

2.  Use WDC_KernelPlugInOpen() to open the handle to the Kernel PlugIn driver.

For the function’s hDev parameter, pass the same handle whose address was passed as the phDevparameter of the device-open function. (Note that here you are passing hDevWDC_DEVICE_HANDLE — and not &hDevWDC_DEVICE_HANDLE* — like in the first parameter of WDC_xxxDeviceOpen().)

For the pcKPDriverName parameter, pass the name of your Kernel PlugIn driver (as previously done for the equivalent device-open function parameter, if you used it to also open the Kernel PlugIn handle).

For the pKPOpenData parameter, pass the data you wish to pass down from the application to the Kernel PlugIn (similar to the device-open function parameter of the same name).
In the older WinDriver sample and generated code, the device handle was passed as the open-data. However, to reduce the work that would need to be done in the Kernel PlugIn to convert the 32-bit data to64-bit, the newer code now passes only the necessary information to the Kernel PlugIn; we recommend that you do the same:

  1. Define the following types, to be used both by the user-mode and Kernel PlugIn code; (in the sample and generated code, these types are defined in the xxx_lib.h file):
    /* Device address description struct */
    typedef struct {
        DWORD dwNumAddrSpaces;    /* Total number of device address spaces */
        WDC_ADDR_DESC *pAddrDesc; /* Array of device address spaces information */
    } PCI_DEV_ADDR_DESC;
    
  2. Allocate a variable of type PCI_DEV_ADDR_DESC and set its fields according to the information returned by the previous call to the WDC_xxxDeviceOpen() function.
    In the sample and generated code, this is done in the xxx_lib.c file as shown below:

    PCI_DEV_ADDR_DESC devAddrDesc;
    PWDC_DEVICE pDev; 
    
    ...
    
    dwStatus = WDC_PciDeviceOpen(&hDev, pDeviceInfo, pDevCtx, NULL, NULL, NULL);
    ...
    pDev = hDev;
    devAddrDesc.dwNumAddrSpaces = pDev->dwNumAddrSpaces;
    devAddrDesc.pAddrDesc = pDev->pAddrDesc;
    
    WDC_KernelPlugInOpen(hDev, KP_PCI_DRIVER_NAME, &devAddrDesc);
    

 

  1. In the Kernel PlugIn driver code, do the following:

1. Modify your funcOpen callback: If you have changed the type of the open-data that is passed from the user mode to the driver, you need to adjust the implementation of your open-callback accordingly.

If your existing code was based on the sample or generated Kernel PlugIn code in earlier versions of WinDriver, and you have selected to pass the address of a PCI_DEV_ADDR_DESC struct as your Kernel PlugIn open-data — as recommended in Step I.2 — modify your funcOpen callback as follows:

  • Replace the PWDC_DEVICE hDev; definition with PCI_DEV_ADDR_DESC *pDevAddrDesc;, and replace instances of WDC_DEVICE and pDev in the function with PCI_DEV_ADDR_DESC and pDevAddrDesc, respectively.
  • Remove the temp variable definition, and replace the two COPY_FROM_USER calls (which use the tempvariable) with the following call: COPY_FROM_USER(pDevAddrDesc, pOpenData, dwSize);
  • As an additional unrelated fix to previous sample and generated WinDriver funcOpenimplementations, move the call to the library initialization function (PCI_LibInit() in the PCI sample / XXX_LibInit in the generated DriverWizard code — where XXX is the name of your driver project) to the beginning of the function — right after the variable declarations and before the first call to the Kernel PlugIn trace messages function (KP_PCI_Trace() in the PCI sample /KP_XXX_Trace() in the wizard-generated code).

2. Create your funcOpen_32_64 callback: Copy your funcOpen callback function, and rename it. The renamed function will be modified to implement your funcOpen_32_64 callback — for opening a handle to a64-bit Kernel PlugIn driver from a 32-bit application.
In the <WinDriver>/samples/pci_diag/kp_pci/kp_pci.c sample, the funcOpen function is namedKP_PCI_Open, and the funcOpen_32_64 function is named KP_PCI_Open_32_64. The generated DriverWizard Kernel PlugIn open functions are named in a similar manner, except that “PCI” is replaced with your selected driver project name.

NOTE
If you only plan to support a 32-bit application and 64-bit Kernel PlugIn configuration, you can skip this step, and in the next step modify your KP_Open callback to use it as your funcOpen_32_64callback; then assign this callback to the KP_INIT funcOpen_32_64 field, instead of to the funcOpenfield. However, to keep your code portable, it’s best to implement both types of callbacks.

3. Edit your Kernel PlugIn code to handle the translation of the 32-bit data passed from the user mode, into 64-bit kernel data:

  1. Add a 32-bit definition of the Kernel PlugIn open-data type.
  2. In your funcOpen_32_64 callback, translate the 32-bit open-date received from the user mode, into the equivalent 64-bit type.

For example, if your original code was based on the sample or generated Kernel PlugIn code in earlier versions of WinDriver, and you have selected to pass the address of a PCI_DEV_ADDR_DESC struct as your Kernel PlugIn open-data — as recommended in Step I.2 — modify the code as follows:

  1. Add the following definitions at the beginning of the file:
    #define PTR32 DWORD
      	 
    typedef struct WDC_DEV_ADDR_DESC_32B {
        DWORD dwNumAddrSpaces; /* Total number of device address spaces */
        PTR32 pAddrDesc;       /* Array of device address spaces information */
    } WDC_DEV_ADDR_DESC_32B, *PWDC_DEV_ADDR_DESC_32B;
    
  2. Modify your funcOpen_32_64 callback as follows:
    • Add the following definition:
      WDC_DEV_ADDR_DESC_32B devAddrDesc_32;
      
    • Add the following lines after the kpOpenCall field assignments, in order to copy to the kernel mode the 32-bit data that was received from the user mode:
      /* Copy device information sent from a 32-bit user application */
      COPY_FROM_USER(&devAddrDesc_32, pOpenData, sizeof(PCI_DEV_ADDR_DESC_32B));
      
    • Replace the following line — COPY_FROM_USER(pDevAddrDesc, pOpenData, dwSize); — with these lines, in order to copy the 32-bit data into a 64-bit structure:
      /* Copy the 32-bit data to a 64-bit struct */
      pDevAddrDesc->dwNumAddrSpaces = devAddrDesc_32.dwNumAddrSpaces;
      
    • Replace the second COPY_FROM_USER call — COPY_FROM_USER(pAddrDesc, pDevAddrDesc->pAddrDesc, dwSize); — with the following:
      COPY_FROM_USER(pAddrDesc, (PVOID)(KPTR)devAddrDesc_32.pAddrDesc, dwSize);
      
      1. <res_desc=”‘br’ not=”” used=”” here=”” on=”” purpose.”=””>

4. Update your KP_Init() function: Notify WinDriver of your funcOpen_32_64 callback, by assigning yourfuncOpen_32_64 callback to the funcOpen_32_64 field of the KP_INIT struct that is initialized in KP_Init():

kpInit->funcOpen_32_64 = <Your funcOpen_32_64 callback >;

For example, this is the assignment line from the updated kp_pci.c sample:

kpInit->funcOpen_32_64 = KP_PCI_Open_32_64;
NOTE
If you select to only implement a funcOpen_32_64 callback, and not to implement a standard funcOpencallback, remove the assignment to the KP_INIT funcOpen field in KP_Init().

5. Edit all remaining device-open type handling: If you have changed the type of the open-data that is passed from the user mode to the driver, you need to edit the related type handling in your Kernel PlugIn code. For example, if you previously passed PWDC_DEVICE as the open-data type, and you now passPCI_DEV_ADDR_DESC* (as recommended in Step I.2), and your code was previously developed using the a WinDriver sample or wizard-generated Kernel PlugIn driver, you would need to make the following additional changes:

  • In KP_Close, replace this line — free(((PWDC_DEVICE)pDrvContext)->pAddrDesc); — with the following, to free the correct type:
    if (((PCI_DEV_ADDR_DESC *)pDrvContext)->pAddrDesc)
        free(((PCI_DEV_ADDR_DESC *)pDrvContext)->pAddrDesc);
    
  • In KP_IntAtIrql, replace this line — PWDC_DEVICE pDev = (PWDC_DEVICE)pIntContext; — with the following:
    PCI_DEV_ADDR_DESC *pDevAddrDesc = (PCI_DEV_ADDR_DESC *)pIntContext;
    

    and edit any remaining pDev instances in the function; for example, replace this line —pAddrDesc = &pDev->pAddrDesc[INTCSR_ADDR_SPACE]; — with the following:

    pAddrDesc = &pDevAddrDesc->pAddrDesc[INTCSR_ADDR_SPACE];

Back To Top

Technical Document #113 Distributing your KernelDriver based driver to a target Windows machine (versions 5.2.x–6.1.x)

This technical document includes instructions on how to distribute your KernelDriver based driver to a target Windows machine.

NOTE
Distribution instructions for KernelDriver version 5.1.x — for USB on Windows NT 4.0 — can be found in Technical Document #114.

KernelDriver Version 6.1

Installing on Windows Target Computers — PCI/USB

This section refers to Windows 98/Me and Windows 2000/XP/Server 2003

The user must have administrative privileges on the target computer in order to install your driver.

  • Uninstalling old devices:
    To successfully disable/uninstall your driver, you must first close any open handles to <driver_file _name>.sys.
  • Installing your driver:
  1. Make sure your <your_driver>.sys and the specific INF file for your device driver are under the same directory.
  2. On Windows 2000/XP/Server 2003:
    Use the utility wdreg to install your driver on the target computer. From the command line type:
    \> wdreg -inf <full path to your driver's INF file> install

For example, if <your_driver>.inf is in the d:\MyDevice\directory on the target computer, the command should be:
\> wdreg -inf d:\MyDevice\<your_driver>.inf

You can find the executable of wdreg in the KernelDriver package under the \KernelDriver\util directory. For a general description of this utility and its usage, please refer to the KernelDriver User’s Manual.

3. On Windows 98/Me:
Install the INF file manually using the Windows Add New Hardware Wizard or Upgrade Device Driver Wizard, as outlined in detail in the Kernel Driver User’s Manual.

NOTE

  1. You must type the full path to the INF file when usingwdreg (even if wdreg is located in the same directory as the INF file).
  2. wdreg is an interactive utility. If it fails, it will display a message instructing the user how to overcome the problem. In some cases the user may be asked to reboot the computer.
  3. Remember: On Windows 98/Me/2000/XP/Server 2003, if you wish to upgrade your driver for PCI/USB devices, we recommend that you first delete any INF file(s) for these devices from Windows INF directory. See the KernelDriver User’s Manual for further explanations.

Installing on Windows Target Computers — ISA

This section refers to Windows 98/Me and Windows 2000/XP/Server 2003.

NOTE
The user must have administrative privileges on the target computer in order to install your driver.
  1. Copy the file <your_driver>.sys to the Windows installation directory on the target computer located at \<Windows Directory>\system32\drivers.
  2. Use the utility wdreg to add <your_driver>.sys to the list of device drivers Windows loads on boot. Use the following installation command:

\> wdreg -name <my_driver_name> install

You can find the executable of wdreg in the KernelDriver package under the \KernelDriver\util directory. For a general description of this utility and its usage, please refer to the KernelDriver User’s Manual.

Installing on Windows NT 4.0 Target Computers

NOTE
The user must have administrative privileges on the target computer in order to install your driver.
  1. Copy the file <your_driver>.sys to the Windows installation directory on the target computer located at \<Windows Directory>\system32\drivers.

2. Use the utility wdreg to add <your_driver>.sys to the list of device drivers Windows loads on boot. Use the following installation command:

   \> wdreg -name <my_driver_name> install

You can find the executable of wdreg in the KernelDriver package under the \KernelDriver\util directory. For a general description of this utility and its usage, please refer to the KernelDriver User’s Manual.

KernelDriver Version 5.2.x

    1. Copy the windrvr.sys or windrvr.vxd driver file (depending on your OS) and your SYS/VxD kernel driver to the target computer’s drivers directory — %windir%\system32\drivers for SYS (e.g., WINNT\system32\drivers); Windows\system\vmm32 for VxD.When copying the files, take care not to overwrite a newer version of the file with an older one.windrvr.sys and windrvr.vxd are found under theKernelDriver\redist directory on the development machine.When distributing the driver to a target Windows 98/Me/2000/XP machine, also copy wd_virtual.inf (found under the KernelDriver\redist directory on the development machine) and the INF file for your device (which you have created with the DriverWizard on the development machine) to the target machine. It is recommended to copy the files to the <WINDIR>\inf directory (WINNT\inf — on Windows 2k; Windows\inf — on Windows 98/Me/XP) to enable Windows to find and load the files automatically.
    2. Copy wdreg.exe or wdreg_gui.exe from the KernelDriver\utildirectory on the development machine to the target machine.wdreg_gui.exe and wdreg.exe provide the same functionality. The difference is in the way the installation messages are displayed graphical message boxes (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exein the following instructions with wdreg_gui.exe if you wish.
    3. If there is already another kernel driver installed for your device, first uninstall the current driver. If the existing driver was developed with version 5.0.5b or earlier of KernelDriver, or if it was developed with WinDriver’s Kernel PlugIn feature (described in the WinDriver User’s Manual), use the wdreg.exe utility with the “remove” command to stop and delete the existing service:
          wdreg.exe -name <driver name> remove
      (When removing a VxD driver, add the -vxd flag before the -nameflag.)
    4. Remove the existing windrvr.sys/windrvr.vxd service (if it exists) and install the new windrvr.sys/windrvr.vxd driver andwd_virtual.inf (on Windows 98/Me/2000/XP), using wdreg.exe:
  • To install windrvr.sys on Windows NT 4.0 orwindrvr.vxd on Windows 95/98/Me, use the removecommand to uninstall the existing service (if it exists) and then use the install command to install the new driver:
        wdreg.exe remove
    wdreg.exe install

On Windows 98/Me, add the -vxd flag (this flag is set automatically on Windows 95):
         wdreg.exe vxd remove
wdreg.exe vxd install

  • To install windrvr.sys on Windows 98/Me/2000/XP, use the reload command — which removes the current WinDriver service (if it exists), installs windrvr.sys and loadswd_virtual.inf:
        wdreg.exe -inf <full path to wd_virtual.inf> reloadFor example, if wd_virtual.inf has been copied toc:\WINNT\inf:
        wdreg.exe -inf c:\WINNT\inf\wd_virtual.inf reloadNOTE: When upgrading from a previous version of KernelDriver/WinDriver, if there are currently PCI/USB devices registered to work with windrvr.sys orwdpnp.sys/wdusb.sys (which were used in previous versions), when wdreg.exe is run on Win2k/XP, it will display a message instructing the user to either uninstall all devices registered to work with WinDriver and select Retry, or select Cancel and reboot, in order to complete the installation. Therefore, before installing the new driver it is recommended to uninstall (from the Device Manager) any PCI/USB devices that are currently registered to work with WinDriver (via an INF file).
    Alternatively, to avoid this message you can run wdreg.exewith the loadinf command, instead of the “reload” command, in order to install the new windrvr.sys andwd_virtual.inf files:
        wdreg.exe -inf <full path to wd_virtual.inf> loadinf Please note, however, that this will require a reboot in order to complete the installation.To complete the installation of windrvr.sys (andwd_virtual.inf) on Windows 98/Me you must alwaysreboot the PC, since dynamic loading of SYS drivers is not supported on Windows 98/Me.

5. Install your own SYS/VxD kernel driver (my_kd.sys/vxd):

  • To install my_kd.sys on Windows NT 4.0 or my_kd.vxdon Windows 95/98/Me, use the wdreg.exe utility:
        wdreg.exe -name <my_kd> install

When installing a VxD driver, add the vxd flag to the installation command (this flag is set automatically on Windows 95):
         wdreg.exe -vxd name <my_kd> install

NOTE: Specify the driver name without the *.sys/*.vxdextension.

  • To install my_kd.sys on Windows 98/Me/2000/XP, install the specific INF file for your device (generated with the DriverWizard on the development machine).On Windows 2000/XP you can use the loadinf option of the wdreg.exe utility in order to automatically install the INF file:
        wdreg.exe -inf <full path to INF file> loadinfOn Windows Me/98 you need to manually install the INF file from the Device Manager (using the Upgrade Device Driver Wizard: Properties --> Driver --> Upgrade Driver) or from Windows Add New Hardware Wizard, as explained in the driver distribution chapter of the KernelDriver User’s Manual.

    NOTE

  1. When upgrading from a previous version of KernelDriver/WinDriver, before installing the new INF file, it is recommended to erase all backup INF files for any PCI/USB device that was previously registered to work with WinDriver, before installing the new INF file, in order to ensure that Windows does not install an old INF file your device, instead of the new file. (On Windows 2000/XP, look for the backup files in the %windir%/inf directory. On Windows 98/Me, look in the Windows\inf\other directory. Look for files containing the string “Jungo” and/or the vendor/device ID of your device/s and delete them. On Windows 2000/XP the files may be called oem*.inf (there will also be corresponding *.pnf files that you can erase or leave, as you wish). On Windows 98/Me the file names may begin with the string “Jungo”.)
  2. In previous versions of KernelDriver/WinDriver (before v5.2.0) a separate driver file was used as the PnP driver (in addition to windrvr.sys) —wdpnp.sys and previously wdusb.sys. These drivers have become obsolete beginning with version 5.2.0 of KernelDriver/WinDriver.
NOTE
You must first install windrvr.sys/vxd (and wd_virtual.inf — when installing windrvr.sys on Windows 98/Me/2000/XP) before attempting to install your own kernel driver.

6. Copy your user mode executable/DLL file (if you have created one) to the directory of you choice on the target machine and run it.

Back To Top

Technical Document #114 KernelDriver USB for Windows NT 4.0 (version 5.1.x) — Distributing Your Driver

In order to distribute your KernelDriver based driver to a target Windows machine (which does not have the KernelDriver software installed), when using version 5.1.x of KernelDriver (which supports the USB bus on Windows NT 4.0), follow the instructions below:

    • Copy windrvr.sys, wdusbd.sys and your own SYS/VxD kernel driver — my_kd.sys/vxd — to the target computer’s drivers directory — WINNT\system32\drivers.
      When copying the files, take care not to overwrite a newer version of the file with an older one.windrvr.sys is found under the KernelDriver\redist\registerdirectory on the development machine (registered driver).wdusbd.sys is found under the KernelDriver\redist directory.
    • Copy wdreg.exe from the KernelDriver\util directory on the development machine to the target machine.
    • Uninstall the existing driver for the device (if such a driver exists).
      If the existing driver was developed with WinDriver/KernelDriver:
  1. If the driver was developed with KernelDriver or using WinDriver’s Kernel PlugIn feature (described in the WinDriver User’s Manual), first stop and delete the kernel driver service using wdreg.exe:
        wdreg.exe -name <driver name> remove
  2. Remove the current windrvr.sys and wdusbd.sys services using wdreg.exe:
        wdreg.exe -name wdusbd remove
    wdreg.exe remove
    • Install windrvr.sys using wdreg.exe by running
          wdreg.exe install
    • Install wdusbd.sys using wdreg.exe by running
          wdreg.exe -name wdusbd install
  • Install your own kernel driver — my_kd.sys — using wdreg.exe:
        wdreg.exe -name <my_kd> installNOTES:

    1. Specify the driver name without the *.sys extension.
    2. You must first install windrvr.sys and wdusbd.sys before attempting to install your own kernel driver.
  • Copy your user mode executable/DLL file (if you have created one) to the directory of you choice on the target machine and run it.

Back To Top

Technical Document #115: How can I improve the rate of the interrupt handling when using DriverBuilder for VxWorks?

Beginning with version 5.2.2, WinDriver for VxWorks (a.k.a. DriverBuilder) implements a callback routine — windrvr_isr — which, if set by the user, is executed immediately when an interrupt is received, thus enabling you to speed up interrupt acknowledgment and processing.

WinDriver includes the following declaration of windrvr_isr:
int (__cdecl *windrvr_isr)(void);

To use the windrvr_isr callback routine, do the following:

  • Implement your interrupt handler routine:
    int __cdecl my_isr(void)
    {
    /* implenet your ISR */
    return TRUE; /* If TRUE, continue regular */
    /* WinDriver handling; */
    /* If FALSE, exit ISR. */
    }

 

  • Include the following declaration in your code:
    extern int (__cdecl *windrvr_isr)(void);

 

  • Set windrvr_isr to point to your interrupt handler routine, after calling drvrInit():
    windrvr_isr = my_isr;

Back To Top

Technical Document #116: WinDriver PCI/ISA API Version Changes

In general, we strive to keep the WinDriver API backward compatible, in the sense that code developed with an earlier version can be ported to a newer version by simply rebuilding the code with the new header files and a new license string. In most cases old code should work without changes (except for the license string update) with the headers and driver from a newer version. However, in some cases we decided there are compelling reasons that justify changes to existing APIs. This document outlines such changes to the WinDriver PCI APIs made in different versions of WinDriver, and guides you in porting your old code to use the updated APIs.

NOTE

  • Generic “PCI” references in this document include also PCI-Express, PCMCIA, and ISA.
  • This document is specific to the WinDriver PCI APIs. For WinDriver USB APIs upgrade information, refer to Technical Document #117.
  • This document is specific to required code updates in light changes to older API versions.
    We strongly recommend that you make additional code updates to utilize relevant API additions and enhancements that may have been made in the newer versions of WinDriver, as outlined in the WinDriver release notes and documented in the WinDriver PCI User’s Manual of the new version.
    For full instructions on how to upgrade to a newer WinDriver version, refer to Technical Document #84.

Read the API changes information for all WinDriver versions that are newer from your current version:

WinDriver v11.8.0 PCI API Changes

In v11.8.0 we made the following changes to the WinDriver WDC PCI API and to the low-level WinDriver PCI API that it uses; the main purpose of these changes was to improve the support for 64-bit PCI addresses:

    • include/wdc_defs.h WDC type changes —
      • WDC_ADDR_DESC struct —
        • The kptAddr field was renamed to pAddr.
        • The dwBytes field was renamed to qwBytes, and its type changed from DWORD to UINT64.
        • The dwUserDirectMemAddress field was renamed topUserDirectMemAddr.

 

  • include/windrvr.h low-level WinDriver type changes —
    • WD_TRANSFER struct changes —
      NOTE
      The WD API references this type, as well as theWD_INTERRUPT struct type — which has a Cmd field of type WD_TRANSFER*.
      • The dwPort field was renamed to pPort.

 

    • WD_ITEMS struct changes —
      NOTE
      The WDC API references the WD_CARD struct — which has an Item field that is an array of WD_ITEMS structs — and the WD_CARD_REGISTER struct — which has a Cardfield of type WD_CARD.
        • The dwOptions field was replaced with anI.Mem.dwOptions field.
        • I.Mem union struct field changes —
          • The dwPhysicalAddr field was renamed topPhysicalAddr, and its type changed fromDWORD to PHYS_ADDR.
          • The dwBytes field was renamed to qwBytes, and its type changed from DWORD to UINT64.
          • The dwTransAddr field was renamed topTransAddr.
          • The dwUserDirectAddress field was renamed topUserDirectAddr.
          • The reserved dwCpuPhysicalAddr field wasremoved.
          • A new pReserved field was added.
        • The I.Mem64 union struct field was removed.
        • I.IO union struct field changes —
          • The dwAddr field was renamed to pAddr.
        • I.Int union struct field changes —
          • New dwReserved1 and pReserved2 fields were added.
      • The I.Val union struct field was removed.

 

    • WD_ITEM_OPTIONS enum — the type was renamed toWD_ITEM_MEM_OPTIONS, and its WD_ITEM_XXX enum values were renamed to WD_ITEM_MEM_XXX.
      NOTE
      The WD_ITEMS struct’s I.Mem.dwOptionsfield (previously the dwOptions field) receives values of this enum type.

 

  • The ITEM_TYPE enum’s ITEM_MEMORY_64BIT enum value wasremoved.

Back To Top

Technical Document #117: WinDriver USB API Version Changes

In general, we strive to keep the WinDriver API backward compatible, in the sense that code developed with an earlier version can be ported to a newer version by simply rebuilding the code with the new header files and a new license string. In most cases old code should work without changes (except for the license string update) with the headers and driver from a newer version. However, in some cases we decided there are compelling reasons that justify changes to existing APIs. This document outlines such changes to the WinDriver USB APIs made in different versions of WinDriver, and guides you in porting your old code to use the updated APIs.

NOTE

  • This document is specific to the WinDriver USB API. For WinDriver PCI/ISA API upgrade information, refer to Technical Document #116.
  • This document is specific to required code updates in light changes to older API versions.
    We strongly recommend that you make additional code updates to utilize relevant API additions and enhancements that may have been made in the newer versions of WinDriver, as outlined in the WinDriver release notes and documented in the WinDriver User’s Manual of the new version.
    For full instructions on how to upgrade to a newer WinDriver version, refer to Technical Document #84.

Read the API changes information for all WinDriver versions that are newer from your current version:

WinDriver v6.0.0 USB API Changes

In v6.0.0 we completely replaced the WD_xxx WinDriver USB API with a new WDU_xxx API, in order to support event-driven transfers between your user-mode USB application and USB devices (in contrast to earlier versions, in which USB devices were initialized and controlled using a specific sequence of function calls).
When upgrading from v5.2.2 or earlier of WinDriver, you will need to change your code to use the WDU APIs. Refer to the updated API reference in the WinDriver USB User’s Manual of the new version.

Back To Top

Technical Document #118: I tried to generate Delphi code for my USB device with the DriverWizard from version 6.0.0 of WinDriver, but it seems that not all the relevant files are generated?

In version 6.0.0 of WinDriver we have modified the USB API in order to improve the support for this bus. The DriverWizard from versions 6.0.0 and 6.0.1 does not support code generation in Delphi (Pascal) for the new USB API. Due to a bug in the wizard from v6.0.0, the Delphi code generation option for USB was not disabled. This was fixed in v6.0.1 of WinDriver.
Note that the old USB API, for which you could generate Delphi code with older versions of WinDriver, is still supported by the driver of the newer versions, for backward compatibility.
Beginning with v6.0.2 of WinDriver, DriverWizard can be used to generate Delphi code that utilizes the new USB API.

Back To Top

Technical Document #119: I used the DriverWizard from version 6.0.0 of WinDriver to generate Visual Basic code for my USB device, but while WDU_Transfer() works correctly, the specific transfer functions — WDU_TransferBulk(), etc. — are not working as expected.

There was a mistake in the Visual Basic (VB) function declarations for the specific WDU_TransferXXX() functions in WinDriver\vb\include\wd_utils.cls, which explains the problem that you encountered. In addition, this file contained two redundant function declarations (WDU_GetDescriptor — which does not exist, and WDU_GetDeviceData — which is a lower level function that is not implemented for VB, and is not generally required).
To resolve these problems, either upgrade to version 6.0.1 (or newer) of WinDriver or download the following modified file from v6.0.1 of WinDriver: wd_utils.cls and copy it to the WinDriver\vb\include directory in place of the file from the original v6.0.0 distribution.

Back To Top

Technical Document #120: Distributing your WinDriver-based driver to a target Windows PC — WinDriver Version 8.1.x–11.8.0

This document outlines the basic steps for installing a driver developed with versions 8.1.x–11.8.0 of WinDriver on a target Windows PC. Detailed driver distribution instructions can be found in the WinDriver User’s Manual for your WinDriver version.

The Windows driver distribution steps for version 11.9.0 and newer of WinDriver are outlined in Technical Document #132.
The Windows driver distribution steps for version 8.0.x of WinDriver are outlined in Technical Document #130.

This document includes

Documentation Notes:

  • All OS references in this document are applicable only to WinDriver versions that officially support these operating systems (refer to Technical Document #4 for the list of operating systems supported by the latest WinDriver version).

For example, references to Windows 98/Me (and the relatedwdreg16.exe utility) are applicable only to version 9.2.0 and below of WinDriver.

 

  • The windrvr6.sys, windrvr6.inf, and wd<version>.cat files, mentioned in this document, can be found in the WinDriver\redistdirectory on the development PC. wdreg.exe / wdreg_gui.exe / wdreg16.exe and difxapi.dll (v8.1.1+) can be found in theWinDriver\util directory. (The source code of the wdreg utility is found in the WinDriver\samples\wdreg directory.)

 

  • Beginning with version 8.0.0 of WinDriver you can rename the WinDriver driver module (windrvr6.sys) and the related INF file (windrvr6.inf). You can also submit the driver for Windows certification or have it Authenticode signed yourself, using your own WinDriver catalog file (xxx.cat), as explained in the WinDriver User’s Manual. If you have selected to rename any of the provided WinDriver files, replace the references to these files in the present document with the names of your new files.

 

  • The wdreg.exe and wdreg_gui.exe utilities provide the same functionality. The difference is in the way the installation messages are displayed — graphical messages (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exe in the following instructions with wdreg_gui.exe.
    When installing windrvr6.sys on Windows 98/Me, you instructions with wdreg_gui.exe.
    Beginning with version 8.1.1 of WinDriver, the wdreg utility is dependent on the difxapi.dll DLL.

Installation Notes:

  • You must have administrative privileges in order to install drivers on Windows.

 

  • When distributing your driver, take care not to overwrite a newer version of the driver file — windrvr6.sys or a renamed driver — with an older version of this file.
    The provided windrvr6.inf file uses theCOPYFLG_NO_VERSION_DIALOG directive, which is designed to avoid overwriting a file in the destination directory with the source file if the existing file is newer than the source file. There is also a similarCOPYFLG_OVERWRITE_OLDER_ONLY INF directive that is designed to ensure that the source file is copied to the destination directory only if the destination file is superseded by a newer version. Note, however, that both of these INF directives are irrelevant to digitally signed drivers. As explained in the Microsoft INF CopyFiles Directive documentation, if a driver package is digitally signed, Windows installs the package as a whole and does not selectively omit files in the package based on other versions already present on the computer. The windrvr6.sys driver in the newer WinDriver versions is digitally signed with an Authenticode signature (refer to the WinDriver User’s Manual for more information on driver signature and certification).

 

  • If you wish to distribute drivers for both 32-bit and 64-bit target platforms, you must prepare a separate driver installation package for each platform.

 

  • When upgrading the driver from a previous version of WinDriver that also uses the windrvr6.sys driver module (v6.0.0 and above), make sure that there are no open handles to the old WinDriver service (windrvr6.sys or your renamed driver), and that there are no connected and enabled Plug-and-Play devices that are registered with this service. This includes closing any applications that may be using the driver; uninstalling your oldKernel PlugIn driver (if you had created such a driver):
    \> wdreg -name OLD_KP uninstall
    and either disabling, uninstalling, or physically disconnecting any device that is registered to work with the WinDriver service.

 

  • On Windows 2000, remove any INF file(s) previously installed for your Plug-and-Play device (such as files created with an earlier version of WinDriver) from the %windir%\inf directory, before installing the new INF file that you created for the device. This will prevent Windows from automatically detecting and installing an obsolete file. You can search the INF directory for the device’s vendor ID and device/product ID to locate the file(s) associated with the device (see Technical Document #49 for additional information).

Installation Steps:

NOTE: For Windows 98/Me, replace the references to wdreg.exebelow with wdreg16.exe.

1.Copy windrvr6.sys, windrvr6.inf, and wd<version>.cat to the same directory.

NOTE:

  • If you select to copy wd<version>.cat to a different location you will need to modify the CatalogFile entry in the windrvr6.inf file to point to the location of the catalog file.
  • You can also select not to distribute the wd<version>.catcatalog file, in which case you need to remove or comment-out the CatalogFile line in the windrvr6.inf file. However, note that if you do so the installation will not utilize the driver’s Authenticode digital signature (see the WinDriver User’s Manual for more information).

 

2. Use the utility wdreg.exe to install WinDriver’s kernel module on the target computer:
\> wdreg -inf <path to windrvr6.inf> install

NOTE: Remember that wdreg requires the difxapi.dll DLL (v8.1.1+).

TIP: If you copy wdreg.exe and difxapi.dll to the same directory as windrvr6.sys and windrvr6.inf, you can simply run the following command from your installation directory in order to install the driver:
install_dir:] wdreg -inf windrvr6.inf install

    1. If you have created a Kernel PlugIn driver (e.g., my_kp.sys), copy this driver to Windows drivers directory —%windir%\system32\drivers — and install it using the wdreg.exeutility:
      \> wdreg -name MY_KP install
      NOTE: The driver name is indicated without the *.sys extension.

 

3. On Windows 98/Me, reboot the PC to complete the driver installation.

 

4. For Plug-and-Play devices (PCI/USB): install the device INF file, which registers your device to work with the windrvr6.sys service (normally this file is created using WinDriver’s DriverWizard utility).

On Windows 2000 and higher, you can use the wdreg.exe utility with the install command to automatically install the INF file:
\> wdreg -inf <path to device.inf> install
You can also use the preinstall wdreg.exe command to pre-install an INF file for a device that is not currently connected to the PC:
\> wdreg -inf <path to device.inf> preinstall

On Windows 98/Me, install the device INF file manually, using Windows’ Update Driver wizard (from the Device Manager) or New Hardware Wizard, as explained in the instructions that will be displayed when generating the file with DriverWizard, and in the WinDriver User’s Manual for the relevant WinDriver version. Alternatively, copy the INF file to Windows’ INF directory
(%windir%\inf) and reboot to let Windows locate and install the file.

 

5. If your project uses the wdapi<version>.lib library (for examplewdapi900.lib) — as is the case for the sample and generated DriverWizard projects — you need to distribute the wdapi DLL:

  • When distributing 32-bit applications/DLLs to 32-bit targetsOR when distributing 64-bit applications/DLLs to 64-bit targets: Copy WinDriver\redist\wdapi<version>.dll (e.g.,wdapi900.dll) to the target’s %windir%\system32directory.

NOTE: If you attempt to copy the 64-bit DLL to the %windir%\system32 directory using a 32-bit installation program, you may find that the DLL file is actually copied to the 32-bit %windir%\sysWOW64 directory. The reason for this is that Windows x64 platforms translate references to 64-bit directories from 32-bit commands into references to 32-bit directories. You can avoid the problem by using 64-bit commands to perform the necessary installation steps from your 32-bit installation program. The system64.exeprogram, provided in the WinDriver\redist directory of the Windows x64 WinDriver distributions, enables you to do this.

 

  • When distributing 32-bit applications to 64-bit targets: Rename the file WinDriver\redist\wdapi<version>_32.dllto wdapi<version>.dll (for example, renamewdapi900_32.dll to wdapi900.dll) and copy the renamed file to the target’s %windir%\sysWOW64 directory.

 

6. Copy your hardware-control application/DLL to the target and run it!

Back To Top

Technical Document #122: PCI Transfers

There are two PCI transfer options: reading/writing to FIFO (string transfers), or reading/writing to different memory blocks.

In the case of reading/writing to memory blocks, the data is transferred to/from a memory address in the PC from/to a memory address in the card, and then both the card’s memory address and the PC’s memory address are incremented for the next transfer. This way, the data is transferred between the address in the PC and the same relative address in the card.

.

In the case of reading/writing to FIFO, the data is transferred to/from a memory address in the PC from/to a single address in the card, and then only the PC’s memory address is incremented for the next transfer. This way the data is transferred between incremented memory addresses in the PC and the same FIFO in the card’s memory.

.

The WD_TRANSFER structure includes an automatic increment flag, calledfAutoinc. When defined as TRUE, the I/O or memory address is incremented for transfer to/from FIFO (string transfers), when defined as FALSE, all data is transferred to the same port/address.

For more information on PCI transfers, please refer to the description of WinDriver’s WD_Transfer() function, which executes a read/write instruction to an I/O port or to a memory address.

Back To Top

Technical Document #125: Handling shared PCI interrupts in the Kernel PlugIn

PCI interrupts are normally handled at the kernel level. Therefore, the best way to handle PCI interrupts with WinDriver is using the Kernel PlugIn feature, which lets you implement code directly at the kernel level. This is specifically true when handling interrupts that are shared between different hardware devices — a very common phenomenon in the case of PCI interrupts, which are by definition sharable. (For information on how to set the sharable state of the interrupt with WinDriver, see Technical Document #21.)

The Kernel PlugIn consists of two interrupt handler functions:

NOTE
Replace “KP_” in the function names below with the name of your Kernel PlugIn driver. For example, the Kernel PlugIn interrupt handler functions for the sample KP_PCI driver areKP_PCI_IntAtIrql and KP_PCI_IntAtDpc.

1. KP_IntAtIrql — This function is executed in the kernel at high IRQ (Interrupt Request) level immediately upon the detection of an interrupt. The function should contain the write/read commands for clearing the source of the interrupt (acknowledging the interrupt) and any additional high-priority interrupt-handling code. If additional deferred kernel- or user-mode interrupt processing is required, KP_IntAtIrql should return TRUE, in which case the deferred KP_IntAtDpc routine (see below) will be executed once the high-level processing is completed. Otherwise, the function should return FALSE andKP_IntAtDpc (as well as any existing user-mode interrupt-handler routine) will not be executed. The generated and sample WinDriver Kernel PlugIn projects, for example, schedule deferred interrupt processing once every five interrupts by implementing code that returns TRUE only for every fifth KP_IntAtIrql call.

 

2. KP_IntAtDpc — This function is executed in the kernel at raised execution level, providedKP_IntAtIrql returned TRUE (see above), and should contain any lower-priority kernel interrupt handling that you wish to perform.
The return value of this function determines how many times, if at all, the user-mode interrupt-handler routine (which can be set in the call to InterruptEnable() from the user-mode) will be executed once the control returns to the user mode.

To handle shared PCI interrupts with WinDriver, perform the following steps:

1. Generate a Kernel PlugIn project using WinDriver’s DriverWizard utility. (When generating C code with the wizard, you will be given the option to generate Kernel PlugIn code — simply check the relevant check-box and proceed to generate the code.) Alternatively, you can also use the generic WinDriver Kernel PlugIn sample — KP_PCI(WinDriver/pci_diag/kp_pci/kp_pci.c) in v7.0.0 and above / KPTEST(WinDriver/kerplug/kermode/kptest.c) in v6.2.3 and below — as the basis for yourKernel PlugIn project. If you are developing a driver for a Xilinx PCI Express card with Bus Master DMA (BMD) design, you can use the sample Kernel PlugIn driver for this design —KP_BMD (xilinx/bmd_design/kp/kp_bmd.c) in v10.3.1 and above / KP_VRTX for Virtex 5 cards (xilinx/virtex5/bmd/kp/kp_vrtx.c) in v10.3.0 and below — or select to generate customized DriverWizard code for this design, including Kernel Plugin code (beginning with v11.3.0).

The advantage of using the wizard is that the generated code will utilize the specific device configuration information detected for your device, as well as any hardware-specific information that you define with the wizard. When generating Kernel PlugIn code for handling PCI interrupts, in the wizard’s Registers tab define the registers that you wish to access upon the detection of an interrupt, and then in the Interrupts tab assign the registers read/write commands that you wish to perform at high IRQ level (inKP_IntAtIrql) to the interrupt. The exact commands for acknowledging the interrupt are hardware-specific and you should therefore consult your hardware specification to determine the correct commands to set.
For more information on how to define the registers and interrupt commands in the wizard, see Technical Document #105.

 

2. The correct way to handle PCI interrupts with the Kernel PlugIn, and shared interrupts in particular, is to include a command in KP_IntAtIrql that reads information from the hardware (normally you would read from the interrupt status register — INTCSR) in order to determine if your hardware generated the interrupt. (You can define a relevant read command in the DriverWizard before generating your Kernel PlugIn code — refer to step #1 above — or manually modify the generated/sample code to add such a command.) If the interrupt was indeed generated by your hardware, the function can set the value of the fIsMyInterrupt parameter to TRUE in order to accept control of the interrupt, and then proceed to write/read the relevant hardware register(s) in order to acknowledge the interrupt, and either return TRUE to perform additional deferred processing or return FALSEif no such processing is required (see above); If, however, you determine that the interrupt was not generated by your hardware, fIsMyInterrupt should be set to FALSE, in order to ensure that the interrupt will be passed on to other drivers in the system, andKP_IntAtIrql should return FALSE. (Note that there is no real harm in settingfIsMyInterrupt to FALSE even if the interrupt belongs to you, as done by default in the generated and sample WinDriver code, since other drivers in the system, assuming they were implemented correctly, should not attempt to handle the interrupt if it was not generated by their hardware.)

The portion of the code that performs the check whether your hardware generated the interrupt is based on hardware-specific logic that cannot be defined in the wizard. You will therefore need to modify the generated/sample KP_IntAtIrql implementation and add a relevant “if” clause to ensure that you do not accept control of an interrupt that was not generated by your hardware and do not attempt to clear the source of such an interrupt in the hardware.

Following is a sample KP_IntAtIrql implementation, based on the v6.2.3 generated WinDriver Kernel PlugIn code. The code reads the INTCSR memory register (defined elsewhere in the code) and only proceeds to accept control of the interrupt and acknowledge it if the value read from the INTCSR is 0xFF (which serves as an indication in this sample that our hardware generated the interrupt). The interrupt in this sample is acknowledged by writing back to the INTCSR the value that was read from it.

NOTE
Some of the APIs used in the following code were modified in newer versions of WinDriver. For example, in v11.8.0 of WinDriver the WD_ITEMS I.Mem.dwTransAddrfield was renamed to pTransAddr and its type changed from DWORD to KPTR.

BOOL __cdecl KP_XXX_IntAtIrql(PVOID pIntContext, BOOL *pfIsMyInterrupt)
{
    XXX_HANDLE hXXX = (XXX_HANDLE) pIntContext;
    DWORD data = 0;
    PVOID pData = NULL;
    DWORD addrSpace;
    WD_ITEMS *pItem;

    addrSpace = XXX_INTCSR_SPACE;
    pItem = &hXXX->cardReg.Card.Item[hXXX->addrDesc[addrSpace].index];
    pData = (DWORD*)pItem->I.Mem.dwTransAddr;
    (DWORD)pData += XXX_INTCSR_OFFSET; 
    data = dtoh32(*((DWORD*)pData));

    if (data == 0xFF)
        /* The interrupt was generated by our hardware */
    
    {
        /* Write 0x0 to INTCSR to acknowledge the interrupt */
        *((DWORD*)pData) = dtoh32(data);
        
        /* Accept control of the interrupt */
        *pfIsMyInterrupt = TRUE; 
        
        /* Schedule deferred interrupt processing (XXX_IntAtDpc) */
        return TRUE;
     }
    else
    {
        /* (Do not acknowledge the interrupt) */

        /* Do not accept control of the interrupt */    
        *pfIsMyInterrupt = FALSE;
        
        /* Do not schedule deferred interrupt processing */
        return FALSE;
    }
}

Back To Top

Technical Document #126: Does WinDriver support the PCI Express (PCIe) bus?

WinDriver fully supports backward compatibility with the standard PCI features on PCI Express boards. The wide support provided by WinDriver for the standard PCI bus — including a rich set of APIs, code samples and the graphical DriverWizard for hardware debugging and driver code generation — is also applicable to PCI Express devices, which by design are backward compatible with the legacy PCI bus.

You can also use WinDriver’s PCI API to easily communicate with PCI devices connected to the PC via PCI Express-to-PCI bridges and switches (e.g., the PLX 8111/8114 bridges or the PLX 8532 switch, respectively).

In addition, WinDriver provides you with a set of APIs for easy access to the PCI Express extended configuration space — see the description of theWDC_PciReadCfgXXX() and WDC_PciWriteCfgXXX() functions, or the lower-level WD_PciConfigDump() function, in the WinDriver PCI User’s Manual. Access to the PCI Express extended configuration space is supported beginning with v7.0.0 of WinDriver and is available on target platforms that support such access (e.g., Windows and Linux).

On Linux and Windows Vista and higher, beginning with version 9.1.0 the WinDriver interrupt handling APIs also support Message-Signaled Interrupts (MSI) and Extended Message-Signaled Interrupts (MSI-X), as detailed in the WinDriver User’s Manual.
WinDriver also features enhanced support for PCI Express cards with the Xilinx Bus Master DMA (BMD) design, in the form of a specific sample, found under the WinDriver/xilinx/bmd_design/ directory, and customized DriverWizard code generation (available beginning with v11.3.0). (In versions 9.1.0–10.3.0 there was only a specific sample for Virtex 5, found under the WinDriver/virtex5/bmd/ directory.) The sample and customized generated code include library APIs and a sample application for communicating with the card using the WinDriver APIs, including DMA and MSI handling.

Back To Top

Technical Document #127: WinDriver Upgrade: Version 6.2.x -> Version 7.x and above

This document outlines the steps for upgrading from version 6.2.x to version 7.x or newer of WinDriver.
If you are upgrading from version 8.1.1 or newer, refer to Technical Document #84 instead.
If you are upgrading from version 7.x, refer to Technical Document #131.

 

Upgrade Steps

  1. Install the new version
  2. Acquire a New WinDriver License (Registered Users)
  3. Upgrade Your Driver Project
  4. Upgrade Your Device INF File (Windows)
  5. Digitally Sign Your Driver Files (Windows)
  6. Upgrade Your Driver Distribution/Installation Package

 

  • Install the new version

Download and install a new version of WinDriver that matches your development platform and the operating systems and CPU configurations of the target platforms on which you intend the driver to be used.

  • Acquire a New WinDriver License (Registered Users)

If you are using a registered version of WinDriver, contact Jungo Connectivity at [email protected] to acquire a WinDriver license registration string for the new version. Then register the new license from DriverWizard (File | Register WinDriver) and from your code.

Note that if you have a valid Support and Upgrade plan you are are entitled to receive a new license free of charge.
If you do not have such a plan, contact [email protected] to request a temporary license that will allow you to evaluate the new version.

  • Upgrade Your Driver Project
      • Register Your New License (Registered Users): Modify the driver code to register your new license — i.e., replace the license string in the call to WDU_Init() (USB) /WDC_DriverOpen() (PCI/ISA — WDC API) / WD_License()(low-level API) from your code.PCI users — if you created a Kernel PlugIn driver, make sure to also update the license string in your Kernel PlugIncode.
      • PCI/ISA users — refer to Technical Document #116 for information on API changes done in v11.8.0 of WinDriver, and edit your code accordingly.

 

      • WinDriver-API DLL/shared object upgrade — Linking your projects with the high-level WinDriver-API DLL/shared object — wdapi<version> (v8.x+) / wd_utils (v7.x) — frees you of the need to include the source files from theWinDriver/src/wdapi directory (v8.x+) / WinDriver/srcdirectory (v7.x) in your project (see also note below).In v8.0.0 the name of the DLL/shared object module was changed from wd_utils to wdapi<version> (e.g.,wdapi800 in v8.0.0) as part of the addition of versioning support to this module. This enables you to upgrade your driver, including the DLL/shared object, without worrying about the possible effects on other drivers, developed with earlier versions of WinDriver, which may be using the same module.On Windows and Windows CE, in v8.x and newer, you can use the WDAPI DLL — wdapi<version>.dll (found in the WinDriver\redist directory) by linking your project with the WinDriver\lib\<CPU>\wdapi<version>.lib library (e.g.,WinDriver\lib\x86\wdapi800.lib) — for MS Visual Studio(Visual C++) projects; or with theWinDriver\lib\<CPU>\wdapi_borland<version>.lib library (e.g., WinDriver\lib\x86\wdapi_borland800.lib) — for Windows Borland C++ Builder projects (in v11.1.0 and below).On Linux and Solaris (Solaris was supported until 9.0.1), in v8.x and newer you can use libwdapi<version>.so by linking your driver project withWinDriver/lib/libwdapi<version>.so (e.g.,libwdapi800.so in WinDriver v8.0.0).
        To link your Linux project with this shared object, addwdapi<version> to the makefile’s link flag (LFLAGS += -l wdapi<version>; e.g., LFLAGS += -l wdap800), instead of listing all the source files from theWinDriver/src/wdapi directory (previously WinDriver/src/ — see below) in the makefile (under the SRCS flag).On all platforms, the sample and generated DriverWizard projects demonstrate how to correctly link the project with the relevant DLL/shared object for your WinDriver version and target OS.Note that if your code uses the high-level WinDriver-API DLL / shared object, you will need to distributewdapi<version>.dll (v8.x+) / wd_utils.dll (v7.x) — for Windows and Windows CE, or wdapi<version>.so (v8.x+) / libwd_utils.so (v7.x) — for Linux and Solaris, with your driver, as explained in the driver distribution instructions of the new WinDriver User’s Manual.
      • WinDriver source files location changes — In v8.0.0the WinDriver C source files were moved from theWinDriver/src directory to the WinDriver/src/wdapi/directory. The .NET source files were moved from theWinDriver/wdapi.net/ directory to theWinDriver/src/wdapi.net/ directory.
        If you have selected to upgrade your v6.2.x project to use the wdapi (v8.x+) or wd_utils (v7.x) DLL/shared object (see above), this should not normally affect you. However, if your project directly includes WinDriver source files, you may need to modify your project/make file to point to the new source files location.

 

      • Update your project’s files search paths: Beginning with v7.0.1, the include path in the WinDriver project/make files contains the path to the WinDriver/ andWinDriver/include/ directories, and the #include statements in the WinDriver source files and generated DriverWizard code were consequently modified to indicate only the name of the header file to include, instead of the full/relative path to the file (as done in earlier versions).In light of these changes, when rebuilding a driver project from v7.0.0 or earlier of WinDriver with the source files from v7.0.1 or newer, you may need to modify your project/make file and add the path to the WinDriver/ andWinDriver/include/ directories to the project’s include path in order to successfully build the project.
      • For USB, beginning with v7.0.0 of WinDriver, if you have created a console driver application/DLL/shared object that calls functions implemented inWinDriver/samples/shared/usb_diag_lib.c (as is the case for the sample and generated WinDriver USB diagnostic driver projects), to build your project with theusb_diag_lib.c file from the new version you must add the new WinDriver/samples/shared/diag_lib.c file to your project.

 

      • For PCI/ISA users, beginning with v7.0.0 WinDriver features the new WDC library, which provides convenient wrapper APIs to the standard WinDriver PCI/ISA APIs. (This library is part of the wdapi<version> (v8.x+) / wd_utils(v7.x) DLL / shared object (see above; the source files are found under the WinDriver/src/wdapi directory (v8.x+) /WinDriver/src directory (v7.x) (see note above).The WDC APIs are documented in the v7.x+ WinDriver PCI User’s Manual. The generated DriverWizard v7.x+ projects use the WDC APIs instead of the low-level WD_xxx APIs. The WDC APIs are also used from the v7.x+ pci_diag,pcmcia_diag, pci_dump and PLX samples.Since WDC mainly provides wrappers to the standard WinDriver APIs, which are still supported, you do not need to modify your old code to use the new WDC library. Should you select to upgrade your code to use the WDC APIs, you can examine the new samples and generated code and compare them to those from your old WinDriver version for a better understanding of how to use the new APIs.Note that to use the WDC APIs you will need to either include the relevant wdc_xxx.c source files from theWinDriver/src/wdapi directory (v8.x+) / WinDriver/srcdirectory (v7.x) in your project/makefile; or link your project with the wdapi<version> (v8.x+) / wd_utils (v7.x)WinDriver high-level API DLL/shared object.
      • 64-bit OS upgrade (Windows and Linux)
          • When developing a driver for a 64-bit platform, your project or makefile must include the KERNEL_64BITpreprocessor definition. In the makefiles, the definition is added using the -D flag: -DKERNEL_64BIT. The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects in the 64-bit WinDriver toolkit already add this definition.
        • PCI Kernel PlugIn upgrade from v10.2.1- — to support execution of 32-bit applications with a 64-bitKernel PlugIn driver, follow the instructions inTechnical Document #112.

 

      • Rename your driver (Windows and Linux) — To avoid conflicts with other WinDriver-based drivers on the target platforms, we highly recommend that you rename the default WinDriver driver module — windrvr<version>.sys(e.g., windrvr1200.sys) on Windows /windrvr<version>.o/.ko (e.g., windrvr1200.o/.ko) onLinux (or windrvr6.sys / windrvr6.o/.ko in v11.8.0 and older) — to a unique name, by following the instructions in the new WinDriver User’s Manual. The renaming procedure is simple and quick.
        The Linux USB GPL driverwindrvr<version>_usb.o/.ko (or windrvr6_usb.o/.koin v11.8.0 and older) is automatically renamed when renaming the main WinDriver Linux driver.
        When creating a PCI Kernel PlugIn driver, select a unique name as well.

 

      • Ensure that your code uses the correct driver module— Verify that the call to WD_DriverName() in your driver code (if exists) uses the new driver-module name —windrvr<version> (or windrvr6 in v11.8.0 and below) or your renamed version of this driver.
        In version 11.9.0 of WinDriver the default WinDriver driver-module name changed from windrvr6 towindrvr<version> (e.g., windrvr1200 in v12.0.0). Consequently, when using the default driver-module name old projects need to be updated to use the default name from the newer version. If you use the generated DriverWizard code or one of the samples from the new WinDriver version, the code will already use the default driver name from the new version. Also, if your code is based on generated/sample code from an earlier version of WinDriver, rebuilding the code with windrvr.h from the new version is sufficient to update the code to use the new default driver-module name (due to the use of theWD_DEFAULT_DRIVER_NAME_BASE definition).
        If you elect to rename the WinDriver driver module, ensure that your code calls WD_DriverName() with your custom driver name. If you rename the driver from the new version to a name already used in your old project, you do not need to modify your code.

        NOTE
        To apply a driver name change — whether using the default driver name or a custom name — your user-mode driver project must be built with theWD_DRIVER_NAME_CHANGE preprocessor flag (e.g., -DWD_DRIVER_NAME_CHANGE), as explained in the WinDriver WinDriver User’s Manuals and demonstrated in the sample and generated DriverWizard WinDriver projects/makefiles.

 

      • Rebuild your updated driver project with the source files from the new version.PCI users who created a Kernel PlugIn driver must rebuild it with the files from the new version as well.

  • Upgrade Your Device INF File (Windows)

On Windows, if you have created a driver for a Plug-and-Play device (USB/PCI/CardBus/PCMCIA), we recommend that you create and install a new INF file for your device, which registers it with the driver module from the new version —windrvr<version>.sys (e.g., windrvr1200.sys) /windrvr6.sys in v11.8.0 and older — or your renamed version of this driver (in v9.x and newer). You can use DriverWizard from the new version to generate the new INF file, or change the driver version in your old INF file.

  • Digitally Sign Your Driver Files (Windows)
    1. Digitally Sign Your Driver Files (Windows) On 64-bit versions ofWindows Vista and higher, Microsoft requires that kernel drivers be digitally signed. Therefore, if you use any of the following driver files you must digitally sign them: A renamed version of the WinDriver kernel driver (the default WinDriver driver —windrvr<version>.sys / windrvr6.sys in v11.8.0 and older — is already digitally signed), a Plug-and-Play device INF file, and/or a PCI Kernel PlugIn driver. You can bypass this restriction during the development stage (e.g., on Windows 7, by pressing F8 at boot time and selecting the relevant option), but the driver files must be signed before distribution. There are also advantages to signing your driver on other Windows OSs. For more information, refer to Micorsoft’s Driver Signing Policy and to the Windows Digital Driver Signing and Certification section of the WinDriver User’s Manuals.You can obtain digital signatures from third-party companies such as DigiCert or Symantec, or use Jungo Connectivity’s digital driver signing service. Jungo Connectivity can also assist you in preparing your driver for Microsoft’s Windows cetification.

  • Upgrade Your Driver Distribution/Installation Package

Create a new driver installation package, which contains the following files from the new WinDriver distribution:

      • The WinDriver driver module —windrvr<version>.sys/.o/.ko/.dll (e.g.,windrvr1200.sys/.o/.ko/.dll) in the newer WinDriver versions, or a renamed version of this driver
      • The WinDriver Linux USB GPL driverwindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) in the newer WinDriver versions, or a renamed version of this driver
      • Your rebuilt PCI Kernel PlugIn driver —<KP_driver_name>.sys (if created)
      • Any other files required for installing or using your driver — such as wdapi<new_version>.dll/.so,wdreg[.exe]/wdreg_gui.exe (and difxapi.dll on Windows), and Windows INF and catalog files
      • An installation program that installs the new driver

Hardware- and OS-specific driver distribution instructions can be found in the Distributing Your Driver chapter of the user manuals from the new version. The instructions for Windows are also summarized in Technical Document #132 (v8.1.x and newer) /Technical Document #130 (v8.0.x).

Version-Specific Installation Upgrade Notes:

      • Linux USB upgrade to v10.0.0+ — the WinDriver USB Linux GPL driver: Beginning with v10.0.0, the WinDriver Linux USB driver was split into two modules, which are used together to provide the full driver functionality:
        • windrvr6.o/.ko, renamed in v11.9.0 towindrvr<version>.o/.ko (e.g.,windrvr1200.o/.ko) — the traditional WinDriver driver module, which includes the product license.
        • windrvr6_usb.o/.ko, renamed in v11.9.0 towindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) — this driver implements Linux-specific USB driver functionality, and contains a GNU General Public License (GPL).

 

      • Windows upgrade to v8.1.1+ — WDREG difxapi.dlldependency: Beginning with v8.1.1, the wdreginstallation utility uses the Driver Install Frameworks API (DIFxAPI) to perform driver installation and uninstallation. As a result, the wdreg utility in v8.1.1 and newer is dependent on the difxapi.dll DLL, which is provided under the WinDriver\util directory. This DLL must therefore be inwdreg‘s search path when using the utility to install /

 

    • Windows upgrade to v8.1.0+ — the wd<version>.catWinDriver catalog file: Beginning with v8.1.0, the WinDriver driver (windrvr<version>.sys / windrvr6.sysin v11.8.0 and older) has an Authenticode digital signature. To enjoy the advantages of this signature thewd<version>.cat catalog file, provided under theWinDriver\redist directory, needs to be distributed together with the related INF file (windrvr<version>.inf /windrvr6.inf in v11.8.0 and older), which is used to install the driver. For more information, refer to the WinDriver User’s Manuals of the new WinDriver version and to Technical Document #132.

Back To Top

Technical Document #128: Does WinDriver support development of drivers for the .NET framework?

Yes. WinDriver can be used to develop .NET Windows drivers in your preferred .NET development language.

The WinDriver .NET API DLLwdapi<version>_dotnet.dll (e.g.,wdapi800_dotnet.dll in WinDriver v8.0.0) provides a .NET version of the high-level WinDriver APIs, implemented using managed extensions for C++. This DLL is found under the WinDriver\lib\<CPU>\<.NET version> directory (e.g., WinDriver\lib\x86\v1.1.4322) and its source code is found under the relevant WinDriver\src\wdapi.net directory.

v7.0.x Note: In v8.0.0 of WinDriver we added both versioning and 64-bit support to the DLL, which resulted in a different DLL name and new locations for the related files. In versions 7.0.1 and 7.0.2 of WinDriver the name of the DLL was wdapi_dotnet and it could be found both under the WinDriver\lib and WinDriver\redist directories. The DLL source code in these versions was found under the WinDriver\wdapi.net directory.

Beginning with v8.0.0 of WinDriver you can use WinDriver’s DriverWizard utility to generate driver code in C# (USB and PCI) and VB.NET (USB).

WinDriver also includes .NET samples that use the WinDriver .NET API DLL:

  • USB:
    • The WinDriver\csharp.net\usb_sample directory contains a .NET USB library (usb_lib_dotnet.dll) and a sample USB diagnostics application (csharp_usb_sample.exe), both implemented in C#.
    • The WinDriver\vb.net\usb_sample directory contains a sample .NET USB diagnostics application (vb_usb_sample.exe), implemented in VB.NET. This sample is similar to the sample C# USB diagnostics application and also uses the sample C# USB library (usb_lib_dotnet.dll).
  • PCI:
      • The WinDriver\csharp.net\pci_sample directory contains a .NET PCI library (pci_lib.dll) and a sample PCI diagnostics application (pci_sample.exe), both implemented in C#.
      • The WinDriver\plx\dotnet directory contains a C# library (plx_lib_dotnet.dll) and sample diagnostics application (PLX_Sample.exe), designed specifically for handling PLXdevices.

To develop a .NET driver with WinDriver, either use DriverWizard to generate a diagnostics .NET driver application for your device, or use the WinDriver .NET sample that most matches your design, and then modify the generated/sample code in accordance with your hardware specification and desired driver functionality. Alternatively, you can use the generated/sample code as a reference for writing your own WinDriver .NET driver.

Back To Top

Technical Document #130: Distributing your WinDriver-based driver to a target Windows PC — WinDriver version 8.0.x

This document outlines the basic steps for installing a driver developed with version 8.0.x of WinDriver on a target Plug-and-Play Windows operating system. Detailed driver distribution instructions can be found in the WinDriver User’s Manual for your WinDriver version.

The Windows driver distribution steps for version 11.9.0 and newer of WinDriver are outlined in Technical Document #132.
The Windows driver distribution steps for versions 8.1.x–11.8.0 of WinDriver are outlined in Technical Document #120.

 

Documentation Notes:

  • The windrvr6.sys and windrvr6.inf files, mentioned in this document, can be found in the WinDriver\redist directory on the development PC. wdreg.exe / wdreg_gui.exe / wdreg16.execan be found in the WinDriver\util directory (the source code is found in the WinDriver\samples\wdreg directory).

 

  • The wdreg.exe and wdreg_gui.exe utilities provide the same functionality. The difference is in the way the installation messages are displayed — graphical messages (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exe in the following instructions with wdreg_gui.exe.
    When installing windrvr6.sys on Windows 98/Me, you should use the wdreg16.exe utility.

Installation Notes:

  • You must have administrative privileges in order to install drivers on Windows.

 

  • When distributing your driver, take care not to overwrite a newer version of windrvr6.sys with an older version of this driver.

 

  • When upgrading the driver from a previous version of WinDriver, which also uses the windrvr6.sys driver module (v6.0.0 and above):
    • If you have also created a Kernel PlugIn driver (e.g.,old_kp.sys), remove this driver before proceeding with the installation:To remove old_kp.sys, run:
      \> wdreg -name OLD_KP uninstall
    • For a reboot-free installation of the new driver, verify that there are no open handles to the windrvr6.sys service. This includes verifying that there are no open applications that use this service and that there are no connected Plug-and-Play (PCI/USB) devices that are registered to work with it via an INF file (on Windows 98/Me/2000/XP/Server 2003). Otherwise, the installation might instruct the user to either uninstall all devices currently registered to work with WinDriver and Retry, or Cancel and reboot the PC in order to successfully complete the installation of the new driver.

 

 

  • On Windows 2000 it is recommended that you remove any INF file(s) previously installed for your Plug-and-Play device(PCI/USB), such as files created with an earlier version of WinDriver, from the %windir%\inf directory. This will ensure that Windows will not automatically detect and install an old INF file for your device.
    You can search the INF directory for the devices vendor ID and device/product ID to locate the file(s) associated with the device.
    For more information regarding the Windows 2000 INF selection algorithm, refer to Technical Document #49.

Windows 98/Me/2000/XP/Server 2003 Installation Steps:

NOTE: For Windows 98/Me, replace the references to wdreg.exebelow with wdreg16.exe.

1.Copy windrvr6.sys and windrvr6.inf to the same directory.

 

2. Use the utility wdreg.exe to install WinDriver’s kernel module on the target computer:
\> wdreg -inf <path to windrvr6.inf> install

TIP: If you copy wdreg.exe to the same directory aswindrvr6.sys and windrvr6.inf, you can simply run the following command from your installation directory in order to install the driver:
install_dir:] wdreg -inf windrvr6.inf install

 

3. If you have created a Kernel PlugIn (e.g., my_kp.sys), copy this driver to Windows drivers directory — %windir%\system32\drivers— and install it using the wdreg.exe utility:
\> wdreg -name MY_KP install

NOTE: The driver name is indicated without the *.sys extension.

 

4. On Windows 98/Me, reboot the PC to complete the driver installation.

 

5. For Plug-and-Play devices (PCI/USB): install the device INF file, which registers your device to work with the windrvr6.sys service (normally this file is created using WinDriver’s DriverWizard utility).

On Windows 2000/XP/Server 2003, you can use the wdreg.exeutility with the install command to automatically install the INF file:
\> wdreg -inf <path to device.inf> install

On Windows 98/Me, install the device INF file manually, using Windows’ Update Driver wizard (from the Device Manager) or New Hardware Wizard, as explained in the instructions that will be displayed when generating the file with DriverWizard, and in the WinDriver User’s Manual for the relevant WinDriver version. Alternatively, copy the INF file to Windows’ INF directory
(%windir%\inf) and reboot to let Windows locate and install the file.

 

6. If your project uses the wdapi<version>.lib library (for examplewdapi800.lib) — as is the case for the sample and generated DriverWizard projects — you need to distribute the wdapi DLL:

  • When distributing 32-bit applications/DLLs to 32-bit targetsOR when distributing 64-bit applications/DLLs to 64-bit targets: Copy WinDriver\redist\wdapi<version>.dll (e.g.,wdapi800.dll) to the target’s %windir%\system32directory.

NOTE: If you attempt to copy the 64-bit DLL to the
%windir%\system32 directory using a 32-bit installation program, you may find that the DLL file is actually copied to the 32-bit %windir%\sysWOW64 directory. The reason for this is that Windows x64 platforms translate references to 64-bit directories from 32-bit commands into references to 32-bit directories. You can avoid the problem by using 64-bit commands to perform the necessary installation steps from your 32-bit installation program. The system64.exeprogram, provided in the WinDriver\redist directory of the Windows x64 WinDriver distributions, enables you to do this.

 

  • When distributing 32-bit applications to 64-bit targets: CopyWinDriver\redist\wdapi<version>_32.dll (for examplewdapi800_32.dll) to the target’s %windir%\sysWOW64directory and rename the file to wdapi<version>.dll.

 

6. Copy your driver application/DLL to the target and run it!

 

Back To Top

Technical Document #131: Upgrading from WinDriver version 7.x–8.1.0 to a newer version

This document outlines the steps for upgrading from version 7.x–8.1.0 to a newer version of WinDriver.
If you are upgrading from version 8.1.1 or newer, refer to Technical Document #84 instead.
If you are upgrading from version 6.2.x, refer to Technical Document #127.

 

Upgrade Steps

  1. Install the new version
  2. Acquire a New WinDriver License (Registered Users)
  3. Upgrade Your Driver Project
  4. Upgrade Your Device INF File (Windows)
  5. Digitally Sign Your Driver Files (Windows)
  6. Upgrade Your Driver Distribution/Installation Package

 

  • Install the new version

Download and install a new version of WinDriver that matches your development platform and the operating systems and CPU configurations of the target platforms on which you intend the driver to be used.

  • Acquire a New WinDriver License (Registered Users)

If you are using a registered version of WinDriver, contact Jungo Connectivity at [email protected] to acquire a WinDriver license registration string for the new version. Then register the new license from DriverWizard (File | Register WinDriver) and from your code.

Note that if you have a valid Support and Upgrade plan you are are entitled to receive a new license free of charge.
If you do not have such a plan, contact [email protected] to request a temporary license that will allow you to evaluate the new version.

  • Upgrade Your Driver Project
      • Register Your New License (Registered Users): Modify the driver code to register your new license — i.e., replace the license string in the call to WDU_Init() (USB) /WDC_DriverOpen() (PCI/ISA — WDC API) / WD_License()(low-level API) from your code.PCI users — if you created a Kernel PlugIn driver, make sure to also update the license string in your Kernel PlugIncode.
      • PCI/ISA users upgrading from v11.7.0 or below — refer to Technical Document #116 for information on API changes done in v11.8.0 of WinDriver, and edit your code accordingly.

 

      • When upgrading from v7.x to v8.x+, you should also be aware of the following issues:
          • WinDriver-API DLL/shared object upgrade — In v8.0.0 we implemented versioning of the high-level WinDriver-API DLL/shared object. Consequently, the name of this module has changed from wd_utilsto wdapi<version> (e.g., wdapi800 for WinDriver v8.0.0). This enables you to upgrade your driver, including the DLL/shared object, without worrying about the possible effects on other drivers, developed with earlier versions of WinDriver, which may be using the same module.To use the new WinDriver-API DLL/shared object, simply build your code with the new version’s library module —WinDriver\lib\<CPU>\wdapi<new_version>.lib(Windows — MS Visual Studio, Windows CE) /WinDriver\lib\<CPU>\wdapi_borland<new_version>.lib (Windows — Borland C++ Builder — in WinDriver v11.1.0 and below) / WinDriver/lib/libwdapi<new_version>.so(Linux, Solaris — supported until 9.0.1) — as demonstrated in the sample and generated DriverWizard projects from v8.x and newer.)Similarly, the name of the WinDriver .NET API DLL changed in v8.0.0 from wdapi_dotnet.dll towdapi<version>_dotnet.dll (e.g.,wdapi800_dotnet.dll in v8.0.0) and the DLL was moved to the WinDriver\lib\<CPU>\<.NET version>\directory (e.g., WinDriver\lib\x86\v1.1.4322\).Note that if your code uses the wdapi DLL/shared object, you will need to distributewdapi<version>.dll (Windows, Windows CE) /libwdapi<version>.so (Linux, Solaris) with your driver. Windows .NET users should also distributewdapi<version>_dotnet.dll.
          • WinDriver source files location changes — Inv8.0.0 the WinDriver C source files were moved from the WinDriver/src directory to theWinDriver/src/wdapi/ directory. The .NET source files were moved from the WinDriver/wdapi.net/ directory to the WinDriver/src/wdapi.net/ directory.
            If your project uses the wdapi (previously wd_utils) DLL/shared object (see above), this should not normally affect you. However, if you have included any WinDriver source files directly in your project you may need to modify your project/make file to point to the new source files location.
        • When upgrading from v7.0.0 — update your project’s files search paths: Beginning withv7.0.1, the include path in the WinDriver project/make files contains the path to theWinDriver/ and WinDriver/include/ directories, and the #include statements in the WinDriver source files and generated DriverWizard code were consequently modified to indicate only the name of the header file to include, instead of the full/relative path to the file (as done in earlier versions).
          In light of these changes, when rebuilding a driver project from v7.0.0 or earlier of WinDriver with the source files from v7.0.1 or newer, you may need to modify your project/make file and add the path to theWinDriver/ and WinDriver/include/ directories to the project’s include path in order to successfully build the project.

 

      • 64-bit OS upgrade (Windows and Linux)
          • When developing a driver for a 64-bit platform, your project or makefile must include the KERNEL_64BITpreprocessor definition. In the makefiles, the definition is added using the -D flag: -DKERNEL_64BIT. The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects in the 64-bit WinDriver toolkit already add this definition.
        • PCI Kernel PlugIn upgrade from v10.2.1- — to support execution of 32-bit applications with a 64-bitKernel PlugIn driver, follow the instructions inTechnical Document #112.

 

      • Rename your driver (Windows and Linux) — To avoid conflicts with other WinDriver-based drivers on the target platforms, we highly recommend that you rename the default WinDriver driver module — windrvr<version>.sys(e.g., windrvr1200.sys) on Windows /windrvr<version>.o/.ko (e.g., windrvr1200.o/.ko) onLinux (or windrvr6.sys / windrvr6.o/.ko in v11.8.0 and older) — to a unique name, by following the instructions in the new WinDriver User’s Manual. The renaming procedure is simple and quick.
        The Linux USB GPL driverwindrvr<version>_usb.o/.ko (or windrvr6_usb.o/.koin v11.8.0 and older) is automatically renamed when renaming the main WinDriver Linux driver.
        When creating a PCI Kernel PlugIn driver, select a unique name as well.

 

      • Ensure that your code uses the correct driver module— Verify that the call to WD_DriverName() in your driver code (if exists) uses the new driver-module name —windrvr<version> (or windrvr6 in v11.8.0 and below) or your renamed version of this driver.
        In version 11.9.0 of WinDriver the default WinDriver driver-module name changed from windrvr6 towindrvr<version> (e.g., windrvr1200 in v12.0.0). Consequently, when using the default driver-module name old projects need to be updated to use the default name from the newer version. If you use the generated DriverWizard code or one of the samples from the new WinDriver version, the code will already use the default driver name from the new version. Also, if your code is based on generated/sample code from an earlier version of WinDriver, rebuilding the code with windrvr.h from the new version is sufficient to update the code to use the new default driver-module name (due to the use of theWD_DEFAULT_DRIVER_NAME_BASE definition).
        If you elect to rename the WinDriver driver module, ensure that your code calls WD_DriverName() with your custom driver name. If you rename the driver from the new version to a name already used in your old project, you do not need to modify your code.

        NOTE
        To apply a driver name change — whether using the default driver name or a custom name — your user-mode driver project must be built with theWD_DRIVER_NAME_CHANGE preprocessor flag (e.g., -DWD_DRIVER_NAME_CHANGE), as explained in the WinDriver WinDriver User’s Manuals and demonstrated in the sample and generated DriverWizard WinDriver projects/makefiles.

 

      • Rebuild your updated driver project with the source files from the new version.PCI users who created a Kernel PlugIn driver must rebuild it with the files from the new version as well.

  • Upgrade Your Device INF File (Windows)

On Windows, if you have created a driver for a Plug-and-Play device (USB/PCI/CardBus/PCMCIA), we recommend that you create and install a new INF file for your device, which registers it with the driver module from the new version —windrvr<version>.sys (e.g., windrvr1200.sys) /windrvr6.sys in v11.8.0 and older — or your renamed version of this driver (in v9.x and newer). You can use DriverWizard from the new version to generate the new INF file, or change the driver version in your old INF file.

  • Digitally Sign Your Driver Files (Windows)

On 64-bit versions of Windows Vista and higher

      , Microsoft requires that kernel drivers be digitally signed. Therefore, if you use any of the following driver files you must digitally sign them: A

renamed

      version of the WinDriver kernel driver (the default WinDriver driver —

windrvr<version>.sys

      /

windrvr6.sys

      in v11.8.0 and older — is already digitally signed), a

Plug-and-Play device INF file

      , and/or a

PCI Kernel PlugIn driver

      . You can bypass this restriction during the development stage (e.g., on Windows 7, by pressing

F8

      at boot time and selecting the relevant option), but the driver files must be signed before distribution. There are also advantages to signing your driver

on other Windows OSs

      . For more information, refer to

Micorsoft’s Driver Signing Policy

      and to the

Windows Digital Driver Signing and Certification

      section of the

WinDriver User’s Manuals

      .

You can obtain digital signatures from third-party companies such as DigiCert or Symantec, or use Jungo Connectivity’s digital driver signing service. Jungo Connectivity can also assist you in preparing your driver for Microsoft’s Windows cetification.

  • Upgrade Your Driver Distribution/Installation Package

Create a new driver installation package, which contains the following files from the new WinDriver distribution:

      • The WinDriver driver module —windrvr<version>.sys/.o/.ko/.dll (e.g.,windrvr1200.sys/.o/.ko/.dll) in the newer WinDriver versions, or a renamed version of this driver
      • The WinDriver Linux USB GPL driverwindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) in the newer WinDriver versions, or a renamed version of this driver
      • Your rebuilt PCI Kernel PlugIn driver —<KP_driver_name>.sys (if created)
      • Any other files required for installing or using your driver — such as wdapi<new_version>.dll/.so,wdreg[.exe]/wdreg_gui.exe (and difxapi.dll on Windows), and Windows INF and catalog files
      • An installation program that installs the new driver

Hardware- and OS-specific driver distribution instructions can be found in the Distributing Your Driver chapter of the user manuals from the new version. The instructions for Windows are also summarized in Technical Document #132 (v8.1.x and newer) / Technical Document #130 (v8.0.x).

Version-Specific Installation Upgrade Notes:

    • Linux USB v9.2.1- to v10.0.0+ upgrade — the WinDriver USB Linux GPL driver: Beginning with v10.0.0, the WinDriver Linux USB driver was split into two modules, which are used together to provide the full driver functionality:
        • windrvr6.o/.ko, renamed in v11.9.0 towindrvr<version>.o/.ko (e.g.,windrvr1200.o/.ko) — the traditional WinDriver driver module, which includes the product license.
        • windrvr6_usb.o/.ko, renamed in v11.9.0 towindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) — this driver implements Linux-specific USB driver functionality, and contains a GNU General Public License (GPL).
        • Windows v8.1.0- to v8.1.1+ upgrade — WDREGdifxapi.dll dependency: Beginning with v8.1.1, thewdreg installation utility uses the Driver Install Frameworks API (DIFxAPI) to perform driver installation and uninstallation. As a result, the wdregutility in v8.1.1 and newer is dependent on thedifxapi.dll DLL, which is provided under theWinDriver\util directory. This DLL must therefore be in wdreg‘s search path when using the utility to install / WDREG difxapi.dll Dependency:
      • Windows v7.x- to v8.1.0+ upgrade — thewd<version>.cat WinDriver catalog file:Beginning with v8.1.0, the WinDriver driver (windrvr<version>.sys / windrvr6.sys in v11.8.0 and older) has an Authenticode digital signature. To enjoy the advantages of this signature thewd<version>.cat catalog file, provided under theWinDriver\redist directory, needs to be distributed together with the related INF file (windrvr<version>.inf / windrvr6.inf in v11.8.0 and older), which is used to install the driver. For more information, refer to the WinDriver User’s Manuals of the new WinDriver version and to Technical Document #132.

Back To Top

Technical Document #132: Distributing your WinDriver-based driver to a target Windows PC

This document outlines the basic steps for installing a driver developed with version 11.9.0 or newer of WinDriver on a target Windows PC. Detailed driver distribution instructions can be found in the WinDriver User’s Manual for your WinDriver version.

The Windows driver distribution steps for versions 8.1.x–11.8.0 of WinDriver are outlined in Technical Document #120.
The Windows driver distribution steps for version 8.0.x of WinDriver are outlined in Technical Document #130.

This document includes

Documentation Notes:

  • All OS references in this document are applicable only to WinDriver versions that officially support these operating systems (refer toTechnical Document #4 for the list of operating systems supported by the latest WinDriver version).

 

  • The windrvr<version>.sys, windrvr<version>.inf, andwd<version>.cat files, mentioned in this document, can be found in the WinDriver\redist directory on the development PC.wdreg.exe / wdreg_gui.exe and difxapi.dll can be found in theWinDriver\util directory. (The source code of the wdreg utility is found in the WinDriver\samples\wdreg directory.)

 

  • You can rename the WinDriver Windows driver module —windrvr<version>.sys (e.g., windrvr1200.sys) — and the related INF file — windrvr<version>.inf (e.g.,windrvr1200.inf). You can also submit the driver for Windows certification or have it Authenticode signed yourself, using your own WinDriver catalog file (xxx.cat), as explained in the WinDriver User’s Manual. If you have selected to rename any of the provided WinDriver files, replace the references to these files in the present document with the names of your new files.

 

  • The wdreg.exe and wdreg_gui.exe utilities provide the same functionality. The difference is in the way the installation messages are displayed — graphical messages (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exe in the following instructions with wdreg_gui.exe.
    The wdreg utility is dependent on the difxapi.dll DLL.

Installation Notes:

  • You must have administrative privileges in order to install drivers on Windows.

 

  • When distributing your driver, take care not to overwrite a newer version of the driver file — windrvr<version>.sys or a renamed driver — with an older version of this file.
    The provided INF file — windrvr<version>.inf (e.g.,windrvr1200.inf) — uses the COPYFLG_NO_VERSION_DIALOGdirective, which is designed to avoid overwriting a file in the destination directory with the source file if the existing file is newer than the source file. There is also a similarCOPYFLG_OVERWRITE_OLDER_ONLY INF directive that is designed to ensure that the source file is copied to the destination directory only if the destination file is superseded by a newer version. Note, however, that both of these INF directives are irrelevant to digitally signed drivers. As explained in the Microsoft INF CopyFiles Directive documentation, if a driver package is digitally signed, Windows installs the package as a whole and does not selectively omit files in the package based on other versions already present on the computer. The WinDriver driver — windrvr<version>.sys — is digitally signed with an Authenticode signature (refer to the WinDriver User’s Manual for more information on driver signature and certification).
NOTE
Since v11.9.0 of WinDriver, the default driver module name includes the WinDriver version (e.g., windrvr1200.sys for version 12.0.0), so if you do not rename the driver to a previously-used name there should not be conflicts with older drivers.

 

  • If you wish to distribute drivers for both 32-bit and 64-bit target platforms, you must prepare a separate driver installation package for each platform.

 

  • When upgrading the driver from a previous version of WinDriver, if your are using the same renamed driver, make sure that there are no open handles to the old WinDriver service, and that there are no connected and enabled Plug-and-Play devices that are registered with this service. This includes closing any applications that may be using the driver; uninstalling your old Kernel PlugIndriver (if you had created such a driver):
    \> wdreg -name OLD_KP uninstall
    and either disabling, uninstalling, or physically disconnecting any device that is registered to work with the WinDriver service.

Installation Steps:

1.Copy windrvr<version>.sys, windrvr<version>.inf, andwd<version>.cat (for the current version — windrvr1200.sys,windrvr1200.inf, and wd1200.cat) to the same directory.

NOTE:

  • If you select to copy wd<version>.cat to a different location you will need to modify the CatalogFile entry in the windrvr<version>.inf file to point to the location of the catalog file.
  • You can also select not to distribute the wd<version>.catcatalog file, in which case you need to remove or comment-out the CatalogFile line in the windrvr<version>.inf file. However, note that if you do so the installation will not utilize the driver’s Authenticode digital signature (see the WinDriver User’s Manual for more information).

 

2. Use the utility wdreg.exe to install WinDriver’s kernel module on the target computer:
\> wdreg -inf <path to windrvr<version>.inf> install

NOTE: Remember that wdreg requires the difxapi.dll DLL.

TIP: If you copy wdreg.exe and difxapi.dll to the same directory as windrvr<version>.sys and windrvr<version>.inf, you can simply run the following command from your installation directory in order to install the driver:
install_dir:] wdreg -inf windrvr<version>.inf install

3. If you have created a Kernel PlugIn driver (e.g., my_kp.sys), copy this driver to Windows drivers directory —%windir%\system32\drivers — and install it using the wdreg.exeutility:
\> wdreg -name MY_KP install

NOTE: The driver name is indicated without the *.sys extension.

 

4. For Plug-and-Play devices (PCI/USB): install the device INF file, which registers your device to work with thewindrvr<version>.sys service (normally this file is created using WinDriver’s DriverWizard utility).

You can use the wdreg.exe utility with the install command to automatically install the INF file:
\> wdreg -inf <path to device.inf> install
You can also use the preinstall wdreg.exe command to pre-install an INF file for a device that is not currently connected to the PC:
\> wdreg -inf <path to device.inf> preinstall

 

5. If your project uses the wdapi<version>.lib library (for examplewdapi900.lib) — as is the case for the sample and generated DriverWizard projects — you need to distribute the wdapi DLL:

  • When distributing 32-bit applications/DLLs to 32-bit targetsOR when distributing 64-bit applications/DLLs to 64-bit targets: Copy WinDriver\redist\wdapi<version>.dll (e.g.,wdapi900.dll) to the target’s %windir%\system32directory.

NOTE: If you attempt to copy the 64-bit DLL to the
%windir%\system32 directory using a 32-bit installation program, you may find that the DLL file is actually copied to the 32-bit %windir%\sysWOW64 directory. The reason for this is that Windows x64 platforms translate references to 64-bit directories from 32-bit commands into references to 32-bit directories. You can avoid the problem by using 64-bit commands to perform the necessary installation steps from your 32-bit installation program. The system64.exeprogram, provided in the WinDriver\redist directory of the Windows x64 WinDriver distributions, enables you to do this.

 

  • When distributing 32-bit applications to 64-bit targets: Rename the file WinDriver\redist\wdapi<version>_32.dllto wdapi<version>.dll (for example, renamewdapi900_32.dll to wdapi900.dll) and copy the renamed file to the target’s %windir%\sysWOW64 directory.

 

6. Copy your hardware-control application/DLL to the target and run it!

Back To Top

Kernel PlugIn

Technical Document #28: What is the Kernel PlugIn for WinDriver?

This is a feature of the WinDriver tool-kit that allows you to develop a kernel-mode driver and move performance-critical sections of your code (such as interrupts acknowledgment and handling) from the user mode to the kernel mode.
For detailed information about the Kernel PlugIn feature, refer to the WinDriver PCI User’s Manual.

NOTE
Beginning with version 6.0 of WinDriver, the Kernel PlugIn does not support the USB API. However, USB development does not generally require this feature.

Back To Top

Technical Document #29: Is the Kernel PlugIn available for all operating systems?

The Kernel PlugIn is available for Windows and Linux.
(In previous versions of WinDriver for Mac OS X and Solaris, it was also supported for this operating systems.)

Note: On Windows CE and VxWorks there is no distinction between user and kernel mode.

Back To Top

Technical Document #30: What is the development process for the Kernel PlugIn?

First, use WinDriver to develop and debug your driver in the user mode. After everything is working, see if there are performance problems related to user-mode overhead. Normally, the problems arise with interrupt handling and accessing I/O-mapped (not memory-mapped) cards (since memory can be accessed directly from the user model, which is very efficient — see Technical Document #74).

Now, follow the instructions in the WinDriver PCI User’s Manual for creating a Kernel PlugIn project and driving it from the user-mode application.
Generally, you have three main options for developing your Kernel PlugIn project (and the corresponding user-mode application that controls it):

    • Use the DriverWizard to generate a skeletal Kernel PlugIn project and user-mode application for your specific device (and then modify it as required). This option is available beginning with version 5.2.0 of WinDriver.

 

    • Use the source code of the sample WinDriver Kernel PlugIn driver (KP_PCI found in the v7.0.0+ WinDriver/samples/pci_diag/kp_pcidirectory; or KPTEST from the WinDriver/kerplug/kptest directory — for older versions of WinDriver) as a skeleton for your kernel project; move code from your user-mode driver to yourKernel PlugIn project; and add calls to your Kernel PlugIn driver from your user-mode application.

 

  • Write your own Kernel PlugIn project “from scratch” (and modify your user- mode application to driver it).

Back To Top

Technical Document #31: When trying to build my Kernel PlugIn project I get the following error: kptest.obj : error LNK2001: unresolved external symbol __chkstk How can I resolve this?

This error is most probably a result of a failed attempt to allocate a relatively big data structure on the stack, within your Kernel PlugIn project, due to the limited size of the kernel stack. To overcome this problem, try allocating the relevant structure dynamically (using malloc()— which is implemented by WinDriver to be used correctly from within the kernel as well), instead of allocating the structure locally on the stack.

Back To Top

Technical Document #34: How do I allocate locked memory in the kernel that can be used inside the interrupt handler?

WinDriver implements malloc() and free() in its Kernel PlugIn library (kp_nt.lib ; previously also kp_95.lib), to which your Kernel PlugIn code is linked. These functions are implemented to allocate locked memory when called from the kernel mode, so you can use that memory in your interrupt handler as well.

Back To Top

Technical Document #37: What is pIntContext in the Kernel PlugIn interrupt functions?

pIntContext is private context data that is passed from KP_IntEnable to the Kernel PlugIn interrupt handler functions — KP_IntAtIrql andKP_IntAtDpc.

Back To Top

Tech Doc #38: I need to call WD_Transfer() and WD_UsbTransfer() in the Kernel PlugIn. From where do I get hWD to pass to these functions?

NOTE
This document refers to low-level WinDriver API. When using the latest versions, you should use the high-level WDC (PCI) or WDU (USB) API.
Note that the Kernel PlugIn feature is not supported for USB in the latest versions.

To obtain the handle to WinDriver’s kernel module (hWD) from the Kernel PlugIn, you can do one of the following:

    • Call WD_Open() directly from the Kernel PlugIn.NOTE: WD_UsbTransfer() is part of WinDriver’s old USB API, which was used until (and including) version 5.2.2. The USB API from version 6.0.0 and above cannot be used from the Kernel PlugIn. When calling one of the old WinDriver USB APIs — such asWD_UsbTransfer() — from the Kernel PlugIn, you must use this option — i.e., call WD_Open() directly in the kernel — in order to get a handle to WinDriver that can be used in the Kernel PlugIn. You cannot use the handle that is passed from the user mode (as suggested in the second option below) with the WinDriver USB functions.

 

  • For PCI/PCMCIA/ISA, you can also use the hWD handle, which is passed from the user mode via WD_KernelPlugInOpen(), and received as the second argument of the Kernel PlugIn callback function KP_Open().Alternatively, you can also pass the handle from the user mode to the Kernel PlugIn using the pData field of theWD_KERNEL_PLUGIN_CALL struct, which is used in the call toWD_KernelPlugInCall() in the user mode and results in a callback to KP_Call() in the Kernel PlugIn.

After obtaining the handle to WinDriver, the call to WD_Transfer() /WD_UsbTransfer() (or any other WinDriver API that receives a handle to WinDriver as a parameter) is the same as in the user mode.

Back To Top

Technical Document #45: What are the COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros and when should they be used?

The COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros are used for copying data (when necessary) to/from user-mode memory addresses (respectively), when accessing such addresses from within the Kernel PlugIn. Copying the data ensures that the user-mode address can be used correctly, even if the context of the user-mode process changes in the midst of the I/O operation. This is particularly relevant for long operations, during which the context of the user-mode process might change. The use of macros to perform the copy provides a generic cross-platform solution for all supported operating systems.

Note that if you wish to access the user-mode data from within theKP_IntAtIrql or KP_IntAtDpc functions, you should copy the data into a Kernel PlugIn variable before the execution of these routines.

The COPY_TO_USER_OR_KERNEL and COPY_FROM_USER_OR_KERNEL macros are defined in the WinDriver/include/kpstdlib.h header file.

For an example of using the COPY_TO_USER_OR_KERNEL macro, see the implementation of the KP_Call() function in the generated DriverWizard Kernel PlugIn code (see kp_xxx.c) and in WinDriver’s Kernel PlugIn sample (KP_PCI (v7.0.0+) —WinDriver/samples/pci_diag/kp_pci/kp_pci.c / KP_TEST (v6.2.3-) —WinDriver/kerplug/kermode/kptest.c).

To share a data buffer between the user-mode and Kernel PlugIn routines (e.g., KpIntAtIrql and KpIntAtDpc), consider using the technique outlined in Technical Document #41.

Back To Top

Licensing And Distribution

Technical Document #5: Building WinDriver with custom version information

WinDriver for Windows allows building your driver with custom version information (Provider, Date, Version, etc…). This information can be seen upon entering the Device Properties of your device in the Device Manager or by right-clicking the driver binary and selecting the “Details” tab.

Driver File Details

 

How to build WinDriver with custom version information:

Building with WDK 8 and above:

  1. Install your WDK version. Note that before installing WDK you must install an appropriate Visual Studio version. For more info regarding WDK installation see Download the Windows Driver Kit (WDK) in MSDN.
  2. Create a new Windows Driver project under Visual C++ projects. Select Empty WDM Driver. Make sure that the Visual Studio project name matches your WinDriver project name (generated by the DriverWizard).
  3. Remove the .inf file from the project (under Driver Files).
  4. Edit the .rc file (located in <YOUR_DRIVER_NAME>_installation\sys folder) to have your custom version information.
  5. Add  the .rc file to the project by selecting Project -> Add Existing Item.
  6. In Project-> Properties make sure that the platform matches your version of WinDriver (x86 or x64)
  7. In Project-> Properties-> VC++ Directories -> Include Directories add C:\WinDriver\include 
  8. In Project ->Properties-> Linker -> Input -> Additonal Dependencies add C:\WinDriver\lib\windrvr1240.lib ; %(DDK_LIB_PATH)usbd.lib
  9. Select Windows 7 as Target OS. Note that the selection differs between various Visual Studio versions. For example, in WDK 8 with Visual Studio 2012, the OS version is specified as a configuration option, while in WDK 10 with Visual Studio 2015 it is under Project -> Properties -> Driver Settings.
  10. Build the project.
  11. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

Building with WDK 7.1.0 and lower:

  1. Install WDK 7.1.0
  2. Open a command prompt. Change directory to the <YOUR_DRIVER_NAME>_installation\sys folder.
  3. Run set BASEDIR=<YOUR_WDK_7.1.0_DIRECTORY> (e.g. set BASEDIR=C:\WinDDK\7600.16385.1)
  4. Run ddk_make.bat <PLATFORM> <BUILD_TYPE> (Listing of possible parameters is available by running ddk_make.bat without arguments.
  5. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

 

NOTE:

If build fails due to a “non-existing paths” error, it may be possible to solve this by editing the Path environment variable from Control Panel -> System and Security -> System -> Advanced system settings -> Advanced -> Environment Variables -> System Variables and removing non existing paths from it.

Back To Top

Operating System

Technical Document #4: What operating systems and their respective versions does WinDriver support?

This document outlines the operating systems support in the latest WinDriver versions.

NOTE
OS-specific support is provided only for operating systems with official vendor support.

PCI/ISA

WinDriver PCI supports the following operating systems:

  • Windows:
    Windows 10/8.1/8/7/Server 2016/Server 2012 R2/Server 2012/Server 2008 R2/Server 2008
  • Linux:
    Any x86 32-bit or 64-bit (x86_64) processor, with a 2.6.x or higher Linux kernel.

USB

WinDriver USB supports the following operating systems:

  • Windows:
    Windows 10/8.1/8/7/Server 2016/Server 2012 R2/Server 2012/Server 2008 R2/Server 2008
  • Linux:
    Any x86 32-bit or 64-bit (x86_64) processor, with a 2.6.x or higher Linux kernel.

 
NOTE: Jungo Connectivity strives to support new Linux kernel versions as close as possible to their release. To find out the latest supported kernel version, refer to the latest WinDriver release notes.

For more information relating to when the support for each operating system and the related service packs was introduced, please review Technical Document #50.

Back To Top

Technical Document #5: Building WinDriver with custom version information

WinDriver for Windows allows building your driver with custom version information (Provider, Date, Version, etc…). This information can be seen upon entering the Device Properties of your device in the Device Manager or by right-clicking the driver binary and selecting the “Details” tab.

Driver File Details

 

How to build WinDriver with custom version information:

Building with WDK 8 and above:

  1. Install your WDK version. Note that before installing WDK you must install an appropriate Visual Studio version. For more info regarding WDK installation see Download the Windows Driver Kit (WDK) in MSDN.
  2. Create a new Windows Driver project under Visual C++ projects. Select Empty WDM Driver. Make sure that the Visual Studio project name matches your WinDriver project name (generated by the DriverWizard).
  3. Remove the .inf file from the project (under Driver Files).
  4. Edit the .rc file (located in <YOUR_DRIVER_NAME>_installation\sys folder) to have your custom version information.
  5. Add  the .rc file to the project by selecting Project -> Add Existing Item.
  6. In Project-> Properties make sure that the platform matches your version of WinDriver (x86 or x64)
  7. In Project-> Properties-> VC++ Directories -> Include Directories add C:\WinDriver\include 
  8. In Project ->Properties-> Linker -> Input -> Additonal Dependencies add C:\WinDriver\lib\windrvr1240.lib ; %(DDK_LIB_PATH)usbd.lib
  9. Select Windows 7 as Target OS. Note that the selection differs between various Visual Studio versions. For example, in WDK 8 with Visual Studio 2012, the OS version is specified as a configuration option, while in WDK 10 with Visual Studio 2015 it is under Project -> Properties -> Driver Settings.
  10. Build the project.
  11. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

Building with WDK 7.1.0 and lower:

  1. Install WDK 7.1.0
  2. Open a command prompt. Change directory to the <YOUR_DRIVER_NAME>_installation\sys folder.
  3. Run set BASEDIR=<YOUR_WDK_7.1.0_DIRECTORY> (e.g. set BASEDIR=C:\WinDDK\7600.16385.1)
  4. Run ddk_make.bat <PLATFORM> <BUILD_TYPE> (Listing of possible parameters is available by running ddk_make.bat without arguments.
  5. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

 

NOTE:

If build fails due to a “non-existing paths” error, it may be possible to solve this by editing the Path environment variable from Control Panel -> System and Security -> System -> Advanced system settings -> Advanced -> Environment Variables -> System Variables and removing non existing paths from it.

Back To Top

Technical Document #11: Can WinDriver be used to develop for the Windows Embedded CE 6.0 operating system?

Yes. Windows Embedded CE 6.0 is supported beginning with version 9.0.0 of WinDriver. Additional versions of the Windows CE (a.k.a. Windows Embedded Compact) operating system are also supported, as outlined in technical documents #4 and #50 and in the WinDriver User’s Manuals.

Back To Top

Technical Document #47: Does WinDriver support Scatter/Gather DMA on Linux?

Yes. Beginning with version 5.2.0 of WinDriver you can use WD_DMALock() to perform Scatter/Gather DMA on Linux as well.
This support is currently afforded for the supported 2.4.x and newer kernels. The 2.2.x kernels do not support Scatter/Gather DMA. You might be able to implement Scatter/Gather DMA with WinDriver with these kernels as well, if you obtain a patch that adds Scatter/Gather DMA support to the 2.2.x Linux kernels, however please note that we have not tested this and will not, therefore, be able to provide support for any matters related to the use of such patches.

In earlier versions of WinDriver only contiguous buffer DMA was supported on Linux, due to the previous lack of support for Scatter/Gather DMA in the Linux kernels.

Back To Top

Technical Document #50: WinDriver Operating Systems Support — Versions Overview

Windows 10 Windows Server 2016 Windows Server 2012 Windows Server 2008
Windows 8.1 Windows 7 Windows Server 2003 Linux
Windows Server 2012 R2 Windows Server 2008 R2 Windows XP Solaris
Windows 8 Windows Vista Windows CE Mac OS X

NOTE

  • All version information in this document relates to both WinDriver for PCI/ISA and WinDriver for USB, unless otherwise specified.
  • USB 2.0 is supported only beginning with version 5.0.4.
  • OS-specific support is provided only for operating systems with official vendor support.

Windows Server 2016
Windows Server 2016 is supported from version 12.0.0

Windows 10
Windows 10 x32 and x64 are supported from version 12.0.0.
Windows 10 Technical Preview build 10162 was supported in version 11.9.0.

Windows 8.1
Windows 8.1 x32 and x64 are supported from version 11.4.0.

Windows Server 2012 R2
Windows Server 2012 x32 and x64 are supported from version 11.4.0.

Windows 8
Windows 8 x32 and x64 are supported from version 11.0.0.

Windows Server 2012
Windows Server 2012 x32 and x64 are supported from version 11.0.0.

Windows 7
Windows 7 x32 and x64 are supported from version 10.1.0.
Windows 7 Service Pack 1 is supported from version 10.3.1.

Windows Server 2008 R2
Windows Server 2008 R2 x32 and x64 are supported from version 10.1.0.
Windows Server 2008 R2 Service Pack 1 is supported from version 10.3.1.

Windows Vista
Windows Vista x32 and x64 are supported from version 8.1.0 to version 12.2.1.
Windows Vista Service Pack 1 is supported from version 10.0.0 to version 12.2.1.

Windows Server 2008
Windows Server 2008 x32 and x64 are supported from version 10.0.0.

Windows Server 2003
Windows Server 2003 x64 is supported from version 8.0.0 to version 12.2.1.
Windows Server 2003 x32 is supported from version 6.0.2 to version 12.2.1.

Windows XP
Windows XP x64 is supported from version 8.0.0 to version 12.2.1.
Windows XP Service Pack 3 is supported from version 10.0.0 to version 12.2.1.

Windows CE (a.k.a. Windows Embedded Compact)
Windows Embedded Compact 2013 (a.k.a. Windows CE 8, WEC2013 or Windows CE 2013) is supported on x86 and ARM platforms from version 11.7.0 to version 12.3.0.
Windows Embedded Compact 7 (a.k.a. WEC7 or Windows CE 7) is supported from version 10.4.0 to version 12.3.0.
Windows Embedded CE 6.0 is supported from version 9.0.0 to version 12.3.0.
Windows CE 5.0 is supported from version 6.2.2 to version 12.3.0.
Windows CE 4.x is supported from version 6.0.0 to 12.3.0.
Windows CE 2.x–3.x is supported for PCI/ISA from version 4.1.2 to 6.0.3.

Mac OS X (PCI)
Mac OS X is supported for PCI from version 10.2.0 to version 10.4.0.

Linux
PCI/ISA — Linux is supported from version 4.1.2.
USB — Linux is supported from version 6.0.0.

Solaris (PCI/ISA)
Solaris is supported for PCI/ISA from version 4.1.4 to version 9.0.1.

Back To Top

Technical Document #129: Reserving and locking physical memory on Windows and Linux

This document explains how to reserve a segment of the physical memory (RAM) for exclusive use, and then access it using WinDriver, on Windows or Linux.

NOTE

    • In most cases, there is no need to resort to this method in order to reserve segments of memory for exclusive use. Normally, you can lock a safe Direct Memory Access (DMA) buffer (e.g., using WinDriver’s DMA APIs) and then access the buffer from your driver. The method described in this document should be used only in rare cases of “memory-intensive” driver projects and only when the required memory block cannot be locked using standard methods, such as allocation of a contiguous DMA buffer.
  • When using this method, take special care not to write to the wrong memory addresses, so as to avoid system crashes, etc.
  1. Reserve the desired amount of RAM on Windows or Linux
  2. Windows: Calculate the base address of the reserved memory
  3. Access the memory using WinDriver

    1. Reserve the desired amount of RAM by following the instructions for your OS:
      • On Windows
        On Windows Vista and newer, set the removememory boot entry option to the desired memory amount, using the BCDEdit utility:
           BCDEdit /set removememory <size_in_MB> 
        For example:
        BCDEdit /set removememory 100
        On Windows Server 2003 and earlier, modify the boot.ini file on your PC to add a burnmemory parameter, to the relevant Windows configuration:
        /burnmemory=<size_in_MB>.
        For example, on Windows XP:
          multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows XP, Enterprise"
        /fastdetect /NoExecute=OptIn /burnmemory=100
        This instructs Windows to refrain from using the specified amount of memory in the highest area of the PC’s physical memory (RAM).NOTE: When selecting the amount of memory to reserve, take care not to exceed or to take up too much of the memory allocated by default to the operating system’s highest address space (see Step 2). If the size of the reserved memory segment is too big, this might result in degraded OS performance.
      • On Linux
          1. Run the following command to view a list of the physical memory ranges on your machine: dmesg | grep BIOS
            This produces entries as in the following sample output; “usable” identifies memory sections that are used by Linux:
              [ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
            [ 0.000000] BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
            [ 0.000000] BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
            [ 0.000000] BIOS-e820: 0000000000100000 - 000000007dce0000 (usable)
            [ 0.000000] BIOS-e820: 000000007dce0000 - 000000007dce3000 (ACPI NVS)
            [ 0.000000] BIOS-e820: 000000007dce3000 - 000000007dcf0000 (ACPI data)
            [ 0.000000] BIOS-e820: 000000007dcf0000 - 000000007dd00000 (reserved)
            [ 0.000000] BIOS-e820: 00000000c0000000 - 00000000d0000000 (reserved)
            [ 0.000000] BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)
          1. Edit the boot-loader command line to instruct the Linux kernel to boot with less memory in the desired address range.
            For example, the following line from the sample dmesg output shown above
            [ 0.000000] BIOS-e820: 0000000000100000 - 000000007dce0000 (usable) 
            indicates that there is a ~1.95GB address range, starting at address 0x100000, that is used by Linux. To reserve ~150MB of memory at the end of this range for DMA, on a machine with a GRUB boot loader, add the following to the grub file: GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} mem=1800M [email protected]"
            This instructs Linux to boot with ~1,800MB (“mem=1800M“) starting at address 0x100000 (“@1M“). Reconfigure GRUB to apply the changes — e.g.:
            sudo grub-mkconfig -o /boot/grub/grub.cfg
          1. Reboot Linux.
        1. Run `dmesg | grep BIOS\|user` to see the available physical memory ranges. The output should include a BIOS-provided physical RAM mappings section with the “BIOS...” lines from the original dmesg output, and a new user-defined RAM mappings section with “user...” lines indicating the actual available physical memory ranges (based on user definitions).
          The user entry for the memory range you modified in the previous steps should be missing the portion you reserved. For example, for the original BIOS mappings and boot-loader changes examples provided in the previous steps, the new output should look like similar to this:
            [ 0.000000] BIOS-provided physical RAM map:
          [ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
          [ 0.000000] BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
          [ 0.000000] BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
          [ 0.000000] BIOS-e820: 0000000000100000 - 000000007dce0000 (usable)
          [ 0.000000] BIOS-e820: 000000007dce0000 - 000000007dce3000 (ACPI NVS)
          [ 0.000000] BIOS-e820: 000000007dce3000 - 000000007dcf0000 (ACPI data)
          [ 0.000000] BIOS-e820: 000000007dcf0000 - 000000007dd00000 (reserved)
          [ 0.000000] BIOS-e820: 00000000c0000000 - 00000000d0000000 (reserved)
          [ 0.000000] BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved)   [ 0.000000] user-defined physical RAM map:
          [ 0.000000] user: 0000000000000000 - 000000000009f800 (usable)
          [ 0.000000] user: 000000000009f800 - 00000000000a0000 (reserved)
          [ 0.000000] user: 00000000000f0000 - 0000000000100000 (reserved)
          [ 0.000000] user: 0000000000100000 - 0000000070900000 (usable)
          [ 0.000000] user: 000000007dce0000 - 000000007dce3000 (ACPI NVS)
          [ 0.000000] user: 000000007dce3000 - 000000007dcf0000 (ACPI data)
          [ 0.000000] user: 000000007dcf0000 - 000000007dd00000 (reserved)
          [ 0.000000] user: 00000000c0000000 - 00000000d0000000 (reserved)

          Comparing the following line from the BIOS-provided mapping section:
          [ 0.000000] BIOS-e820: 0000000000100000 - 000000007dce0000 (usable) 
          with the following line from the user-defined mapping section
          [ 0.000000] user: 0000000000100000 - 0000000070900000 (usable) 
          shows that the original ~1.95GB memory range — 0x100000–0x7dce0000 — was reduced to a ~1.75GB range — 0x100000–0x70900000. The memory in address range 0x70900000–0x7dce0000 is no longer available because it has been reserved in the previous steps, allowing you to use this range for DMA, as demonstrated in Step 3 of this document.

    1. Windows: Calculate the base address of the reserved memoryTo acquire the base address of the reserved memory segment on Windows, you must first determine the physical memory mapping on your PC and retrieve the base address and length (in bytes) of the highest address space used by the operating system. Then add the length of this address space to its base address to receive the base address of your reserved memory segment:<reserved memory base address> =
      <highest OS physical memory base address> +
      <length of the highest OS memory address space>
      NOTE: To verify the size of your reserved memory block, compare the length of the highest OS address space, before and after modifying boot configuration to reserve the memory (as outlined in Step 1.You can use the following method to determine the highest physical memory base address: Open the registry (Start –> Run –> regedit.exe) and navigate to theHKEY_LOCAL_MACHINE\HARDWARE\RESOURCEMAP\System Resources\Physical Memory\.Translatedregistry key. This key is of type REG_RESOURCE_LIST and holds information regarding the physical memory mapping on your PC. To view a parsed version of the mapped addresses, double-click on the .Translated key, select the relevant resource from the Resource Listsdialog, and double-click on the resource (or select Display...) in order to display theResources dialog, which contains a list of all memory address ranges for the selected resource. The base address for your reserved physical memory block is calculated by locating the highest base address in the list and adding to it the length of the relevant address space.
      For example, for the following Resources dialog, the highest base address is 0x1000000 and the length of the address space that begins at this address is 0x1eff0000, so the base address of the reserved memory is 0x1fff0000:
          <reserved memory base address> = 0x1000000 + 0x1eff0000 = 0x1fff0000 

      USB HID

  1. Access the memory using WinDriverOnce you acquire the physical base address of the memory segment that you reserved, you can easily access it using WinDriver, as you would any memory on an ISA card.You can use WinDriver’s DriverWizard to test the access to the memory you reserved: Use the wizard to create a new ISA project, define the new memory item according to the information you acquired in the previous step(s), then proceed to access the memory with the wizard. You can also use DriverWizard to generate a sample diagnostics application that demonstrates how to lock and access the reserved memory region using WinDriver’s API.The following code segment demonstrates how you can define and lock the physical memory using WinDriver’s WDC API. The handle returned by the sample LockReservedMemory()function can be used to access the memory using WinDriver’s WDC memory access APIs, defined in the WinDriver/include/wdc_lib.h header file:
    NOTE
    There may be some differences between the API in your version of WinDriver and that used in the following example (such as differences in field names and/or types).


    /* LockReservedMemory: Returns a WDC handle for accessing
    the reserved memory block.
    Parameters:
    pReservedRegionBase: The physical base address of
    the reserved memory region (as calculated in the
    previous step)
    qwReservedRegionLength: The length (in bytes) of the
    reserved memory region, i.e.,:
    (as configured in Step 1) * 0x100000
    Note:
    The function uses the high-level WDC APIs.
    You can implement similar code using the low-level
    WD_CardRegister() API — see the WinDriver User's
    Manual for details.
    */
    WDC_DEVICE_HANDLE LockReservedMemory(PHYS_ADDR pReservedRegionBase,
    UINT64 qwReservedRegionLength)
    {
    DWORD dwStatus;
    WDC_DEVICE_HANDLE hDev = NULL;
    WD_CARD deviceInfo;

    /* Set the reserved memory’s resources information */
    BZERO(deviceInfo);
    SetMemoryItem(&deviceInfo, pReservedRegionBase,
    qwReservedRegionLength);

    /* Get a handle to the reserved memory block */
    dwStatus = WDC_IsaDeviceOpen(&hDev, &deviceInfo, NULL,
    NULL, NULL, NULL);

    if (WD_STATUS_SUCCESS != dwStatus)
    {
    printf( “Failed opening a WDC device handle.
    Error 0x%lx — %s\n”, dwStatus,
    Stat2Str(dwStatus));
    return NULL;
    }

    /* Return the handle to the reserved memory */
    return hDev;
    }

    /* SetMemoryItem: Initializes a WDC device information
    structure for a specified memory region.
    Parameters:
    pDeviceInfo: Pointer to a resources information structure
    pPhysAddr: The memory region’s physical base address
    qwBytes: The memory region’s length, in bytes
    */
    void SetMemoryItem(WD_CARD *pDeviceInfo, PHYS_ADDR pPhysAddr, UINT64 qwBytes)
    {
    WD_ITEMS *pItem = pDeviceInfo->Item;

    pDeviceInfo->dwItems = 2;

    /* 1st item: Bus */
    pItem[0].item = ITEM_BUS;
    pItem[0].I.Bus.dwBusType = WD_BUS_ISA;

    /* 2nd item: Memory */
    pItem[1].item = ITEM_MEMORY;
    /* Lock the memory for exclusive use */
    pItem[1].fNotSharable = 1;
    /* Set the reserved memory’s base address */
    pItem[1].I.Mem.pPhysicalAddr = pPhysAddr;
    /* Set the reserved memory’s size */
    pItem[1].I.Mem.qwBytes = qwBytes;
    /* Set the reserved memory’s address space */
    pItem[1].I.Mem.dwBar = 0;
    /* Map physical memory as cached (applicable only to RAM).
    (This option is supported on Windows NT+ and CE
    beginning with version 7.0.2 of WinDriver.) */
    pItem[1].I.Mem.dwOptions = WD_ITEM_MEM_ALLOW_CACHE;
    }

Back To Top

Compiler and Code Language

Technical Document #5: Building WinDriver with custom version information

WinDriver for Windows allows building your driver with custom version information (Provider, Date, Version, etc…). This information can be seen upon entering the Device Properties of your device in the Device Manager or by right-clicking the driver binary and selecting the “Details” tab.

Driver File Details

 

How to build WinDriver with custom version information:

Building with WDK 8 and above:

  1. Install your WDK version. Note that before installing WDK you must install an appropriate Visual Studio version. For more info regarding WDK installation see Download the Windows Driver Kit (WDK) in MSDN.
  2. Create a new Windows Driver project under Visual C++ projects. Select Empty WDM Driver. Make sure that the Visual Studio project name matches your WinDriver project name (generated by the DriverWizard).
  3. Remove the .inf file from the project (under Driver Files).
  4. Edit the .rc file (located in <YOUR_DRIVER_NAME>_installation\sys folder) to have your custom version information.
  5. Add  the .rc file to the project by selecting Project -> Add Existing Item.
  6. In Project-> Properties make sure that the platform matches your version of WinDriver (x86 or x64)
  7. In Project-> Properties-> VC++ Directories -> Include Directories add C:\WinDriver\include 
  8. In Project ->Properties-> Linker -> Input -> Additonal Dependencies add C:\WinDriver\lib\windrvr1240.lib ; %(DDK_LIB_PATH)usbd.lib
  9. Select Windows 7 as Target OS. Note that the selection differs between various Visual Studio versions. For example, in WDK 8 with Visual Studio 2012, the OS version is specified as a configuration option, while in WDK 10 with Visual Studio 2015 it is under Project -> Properties -> Driver Settings.
  10. Build the project.
  11. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

Building with WDK 7.1.0 and lower:

  1. Install WDK 7.1.0
  2. Open a command prompt. Change directory to the <YOUR_DRIVER_NAME>_installation\sys folder.
  3. Run set BASEDIR=<YOUR_WDK_7.1.0_DIRECTORY> (e.g. set BASEDIR=C:\WinDDK\7600.16385.1)
  4. Run ddk_make.bat <PLATFORM> <BUILD_TYPE> (Listing of possible parameters is available by running ddk_make.bat without arguments.
  5. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

 

NOTE:

If build fails due to a “non-existing paths” error, it may be possible to solve this by editing the Path environment variable from Control Panel -> System and Security -> System -> Advanced system settings -> Advanced -> Environment Variables -> System Variables and removing non existing paths from it.

Back To Top

Technical Document #6: Using WinDriver to develop a graphical Win32 or MFC application

You can easily use WinDriver to develop a graphical Win32 or MFC application.

While the diagnostics generated DriverWizard code and the WinDriver samples are provided in the form of console mode applications, the sample and generated library files are designed to be used from both console and graphical Windows applications, and therefore do not include any console specific function calls (such as printf(), etc.) and do not need to be modified in order to be used from within a graphical Windows application. You should, therefore, be able to add the generated or sample WinDriver C files to a graphical Win32 application or MFC project and use the WinDriver API from within your application, and we have in fact had customers who have done so successfully.

NOTE: To avoid possible build errors, you may need to do one of the following:

    • Add #include "stdafx.h" as the first line of code in each file you add to your project.
  • Do not use the pre-compiled headers option (Project –> Settings –> C/C++ –> ‘Precompiled Headers’ category –> choose ‘Not using precompiled headers’).

Back To Top

Technical Document #10: Does WinDriver support development in C#?

Yes. Beginning with version 7.0.0 WinDriver provides specific support for development of .NET drivers, including development in C#.
For information on WinDriver’s general support for the .NET framework, refer to Technical Document #128.

The WinDriver .NET API DLLwdapi<version>_dotnet.dll (e.g.,wdapi800_dotnet.dll in WinDriver v8.0.0) provides a .NET version of the high-level WinDriver APIs, implemented using managed extensions for C++. This DLL can be used to develop a driver in any .NET language, including C#. The DLL file is found under the WinDriver\lib\<CPU>\<.NET version> directory (e.g., WinDriver\lib\x86\v1.1.4322) and its source code is found under the relevant WinDriver\src\wdapi.net directory.

v7.0.x Note: In v8.0.0 of WinDriver we added both versioning and 64-bit support to the DLL, which resulted in a different DLL name and new locations for the related files. In versions 7.0.1 and 7.0.2 of WinDriver the name of the DLL was wdapi_dotnet and in v7.0.0 its name waswdnetlib.dll. In all 7.0.x versions the DLL could be found both under theWinDriver\lib and WinDriver\redist directories and its source code was found under the WinDriver\wdapi.net directory.

Beginning with v8.0.0 of WinDriver you can use WinDriver’s DriverWizard utility to generate C# driver code for both USB and PCI devices.

WinDriver also includes the following .NET C# samples, which utilize the WinDriver .NET API DLL:

  • USB:
    • The WinDriver\csharp.net\usb_sample directory contains a C# USB library (usb_lib_dotnet.dll) and a sample C# USB diagnostics application (csharp_usb_sample.exe).
  • PCI:
    • The WinDriver\csharp.net\pci_sample directory contains a C# PCI library (pci_lib.dll) and a sample C# PCI diagnostics application (pci_sample.exe).
    • The WinDriver\plx\dotnet directory contains a C# library (plx_lib_dotnet.dll) and a sample C# diagnostics application (PLX_Sample.exe), designed specifically for handling PLX devices.

To develop a C# driver with WinDriver, either use DriverWizard to generate a diagnostics C# driver application for your device, or use the WinDriver C# sample that most matches your design, and then modify the generated/sample code in accordance with your hardware specification and desired driver functionality. Alternatively, you can use the generated/sample code as a reference for writing your own WinDriver C# driver.

Back To Top

Tech Doc #35: When trying to build my WinDriver application from MS Visual Studio, I get the following error: int_io.obj : error LNK2001: unresolved external symbol __beginthreadex How can I resolve this?

You should enable multi-threading from your project, by adding the relevant flag to the project settings.

The Microsoft flag, when compiling with MS Visual Studio (Visual C++) is -MT. Therefore, be sure to add: /MT to the Project Settings. (Add this option in ‘Project’ –> ‘Settings…’, under the ‘C/C++’ tab, ‘Category: General’, in the ‘Project Options’ box.)

For other compilers, verify that the compiler-specific multi-threading flag is used. For example, the Borland C++ Builder flag is -tWM.

NOTE that the -MT and -tWM flags are already part of the WinDriver samples and generated DriverWizard projects for MS Visual Studio andBorland C++ Builder (respectively).

In addition, beginning with v6.0.0 of WinDriver, in order to use WinDriver’s thread functions (ThreadStart() and ThreadStop() — implemented in WinDriver/src/utils.c) from a C/C++ application, you should verify that your project includes an _MT precompiler definition. This definition is also an integrated part of the WinDriver samples and generated code.
For MS Visual Studio 5.0 and above, this definition is part of the samples/generated code beginning with v6.0.0 of WinDriver; forMS Visual Studio 4.0, beginning with v6.0.2.
For Borland C++ Builder (4.0–6.0) this definition is part of the samples/generated code beginning with version 6.0.3 of WinDriver.

NOTE
MS Visual Studio 4.0–6.0 and Borland C++ Builder were supported until version 11.1.0 of WinDriver.

When creating your own project or when using a version of WinDriver that doesn’t, add the definition for your IDE, you can add it to the project yourself:

In MS Visual Studio, do either of the following:

    • Open the project in the MS Visual Studio IDE, select Project –> Settings … –> C/C++, and add _MT in the Preprocessor Definitionstext box, under either the Preprocessor or General Category.

 

  • Modify the project file (*.vcproj/*.dsp) or makefile (inMS Visual Studio 4.0) by adding /D "_MT" under the # ADD CPPsection.

In Borland C++ Builder do either of the following:

    • Add the _MT precompiler definition from within theBorland C++ Builder IDE:
      Project –> Options … –> Directories/Conditionals –> Conditionals –> Conditional Defines

 

  • Modify your project (*.bpr) file directly and set the USDERDEFINESsection to the following:
    <USERDEFINES value="_MT"/>     (for Borland C++ Builder5.0.0–6.00).
    OR
    USERDEFINES = _MT (for Borland C++ Builder 4.0).

Back To Top

Version

Technical Document #5: Building WinDriver with custom version information

WinDriver for Windows allows building your driver with custom version information (Provider, Date, Version, etc…). This information can be seen upon entering the Device Properties of your device in the Device Manager or by right-clicking the driver binary and selecting the “Details” tab.

Driver File Details

 

How to build WinDriver with custom version information:

Building with WDK 8 and above:

  1. Install your WDK version. Note that before installing WDK you must install an appropriate Visual Studio version. For more info regarding WDK installation see Download the Windows Driver Kit (WDK) in MSDN.
  2. Create a new Windows Driver project under Visual C++ projects. Select Empty WDM Driver. Make sure that the Visual Studio project name matches your WinDriver project name (generated by the DriverWizard).
  3. Remove the .inf file from the project (under Driver Files).
  4. Edit the .rc file (located in <YOUR_DRIVER_NAME>_installation\sys folder) to have your custom version information.
  5. Add  the .rc file to the project by selecting Project -> Add Existing Item.
  6. In Project-> Properties make sure that the platform matches your version of WinDriver (x86 or x64)
  7. In Project-> Properties-> VC++ Directories -> Include Directories add C:\WinDriver\include 
  8. In Project ->Properties-> Linker -> Input -> Additonal Dependencies add C:\WinDriver\lib\windrvr1240.lib ; %(DDK_LIB_PATH)usbd.lib
  9. Select Windows 7 as Target OS. Note that the selection differs between various Visual Studio versions. For example, in WDK 8 with Visual Studio 2012, the OS version is specified as a configuration option, while in WDK 10 with Visual Studio 2015 it is under Project -> Properties -> Driver Settings.
  10. Build the project.
  11. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

Building with WDK 7.1.0 and lower:

  1. Install WDK 7.1.0
  2. Open a command prompt. Change directory to the <YOUR_DRIVER_NAME>_installation\sys folder.
  3. Run set BASEDIR=<YOUR_WDK_7.1.0_DIRECTORY> (e.g. set BASEDIR=C:\WinDDK\7600.16385.1)
  4. Run ddk_make.bat <PLATFORM> <BUILD_TYPE> (Listing of possible parameters is available by running ddk_make.bat without arguments.
  5. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

 

NOTE:

If build fails due to a “non-existing paths” error, it may be possible to solve this by editing the Path environment variable from Control Panel -> System and Security -> System -> Advanced system settings -> Advanced -> Environment Variables -> System Variables and removing non existing paths from it.

Back To Top

Technical Document #7: WinDriver for Windows NT 4.0 — supported service pack

WinDriver PCI v8.0.2 and below supports the Windows NT 4.0 operating system beginning with service pack 3. Windows NT 4.0 was a very unstable OS before service pack 3. It is recommended, however, to always use the latest service pack — currently, service pack 6.

 

Back To Top

Technical Document #8: When trying to install WinDriver v5.2.0 on my PC, using the Linux RedHat 7.2 distribution, I got unresolved symbol errors pertaining to alloc_kiovec() and free_kiovec(). How can I resolve these errors?

These errors are due to a change in the alloc_kiovec() andfree_kiovec() functions in the Linux RedHat 7.2 distribution.
In version 5.2.2 of WinDriver we have modified the WinDriver Linux makefile (WinDriver/redist/makefile) in order to eliminate this error, by setting the value of KIOBUF_WITH_SIZE in the makefile according to the Linux distribution that is being used. When using version 5.2.0 or 5.2.1 of WinDriver, you can resolve this error by changing the value of KIOBUF_WITH_SIZE in the makefile (WinDriver/redist/makefile) from 0 to 1 and then rebuild the code (as documented in the makefile itself — Ln28):

# Change KIOBUF_WITH_SIZE value to 1 if in the file
# /usr/src/linux/include/linux/iobuf.h the following function is defined:
# int alloc_kiovec_sz(int nr, struct kiobuf **, int *);
KIOBUF_WITH_SIZE=0

The above is also true for the following build error:
    >> /lib/modules/misc/windrvr.o :
unresolved symbol unmap_kiobuf_Rsmp_e3e9865e

Back To Top

Technical Document #24: If a variable requires a pointer to be assigned to it, as in pBuffer = &dwVal, how do I do it in Visual basic (which does not support pointers)?

NOTE

  • This document refers to development in Visual Basic 6.0.
    For information regarding WinDriver’s support forVisual Basic .NET, refer to Technical Document #128.
  • Beginning with version 11.2.0 of WinDriver, Visual Basic 6.0 is no longer supported.

WinDriver provides you with the function WD_VB_GetAddress() for getting a pointer to a variable — i.e., its address. To obtain the pointer to a variable the function must be called as

   pBuffer = WD_VB_GetAddress (test, 1, 1)
   ' where "test" is the variable whose pointer is required.
' The other two parameters must always be one.

You can also use Visual Basic’s VarPtr() function to get the pointer to a variable (i.e., it’s address).

You can refer to the WinDriver Visual Basic samples and generated DriverWizard code for examples of using both WD_VB_GetAddress() andVarPtr() to acquire a pointer to a variable in Visual Basic.

Back To Top

Technical Document #25: I am trying to install WinDriver v5.0.5 on a machine running Linux SuSE 8.0, which uses the 2.4.18-4 Linux kernel. But the ‘make install’ command fails with this error: unresolved symbol kmap_pagetable

Including <linux/highmem.h> in linux_wrappers.c should resolve the problem.

This error should not occur when using version 5.2.1 or newer of WinDriver.

Back To Top

Technical Document #27: How do I detect the location of my USB device on my Windows PC?

The USB device location is represented by the device’s HUB identifier and the port in the HUB: Z&ZZZZZZZ&Z&A. Z&ZZZZZZZ&Z is the HUB identifier or PrefixID, and A is the port/address in the HUB (1 to 8).
In order to retrieve the device location ID, you must first retrieve the device instance ID, represented by the device type, Vendor ID, Product ID, HUB ID and port ID: USB\VID_XXXX&PID_YYYY\Z&ZZZZZZZ&Z&A.
DeviceInstanceId is returned by SetupDiGetDeviceInstanceId().

In order to detect the USB device location, do the following:

    1. Get the DriverKeyName by calling WinDriver’sWDU_GetDeviceRegistryProperty() function (orWD_GetDeviceProperty() — for v8.1.2 and below) with theWdDevicePropertyDriverKeyName registry property.

 

    1. Get the ClassGUID, by calling WDU_GetDeviceRegistryProperty() (orWD_GetDeviceProperty()) — in v8.1.2 and below) with theWdDevicePropertyClassGuid property.

 

    1. By using GetDeviceInstanceId() (see later) with the retrievedDriverKeyName and ClassGUID, get the DeviceInstanceId.

 

  1. From the retrieved DeviceInstanceId, get the USB device location, Z&ZZZZZZZ&Z&A.

—————————————————————————————
<span style="color: #0000ff;">/*
 szDriverKeyName is returned by
 WDU_GetDeviceRegistryProperty() /
 WD_GetDeviceProperty().
 It looks like:
  {C671678C-82C1-43F3-D700-0049433E9A4B}\\0017
 szClassGUID is returned by WDU_GetDeviceProperty.
 It looks like:
 {C671678C-82C1-43F3-D700-0049433E9A4B}

 GetDeviceInstanceId() creates a list of the device
 information for all devices of the specified class.
 The function then searches the list for the
 WinDriver device and retrieves the device instance
 ID (*pszDeviceInstanceId).
*/

<span style="color: #cc66ff;">#include <span style="color: #ff00ff;"><windows.h>
#include <setupapi.h>
#include <string.h>

 

BOOL GetDeviceInstanceId(LPCTSTR szClassGUID, LPCTSTR
 szDriverKeyName, PTCHAR *pszDeviceInstanceId)
{
 <span style=”color: #0000ff;”>/* Build class GUID from szClassGUID */
 GUID guid;
 DWORD dwMemberIndex=<span style=”color: #ff00ff;”>0;
 SP_DEVINFO_DATA DeviceInfoData;
 BOOL bResult;
 DWORD dwError;
 DWORD dwPropertyBufferSize;
 PTCHAR pbPropertyBuffer;
 DWORD dwRequiredSize;
 DWORD dwPropertyRegDataType;
 HDEVINFO hDeviceInfoSet;

 StringToGUID(szClassGUID,&guid);

 *pszDeviceInstanceId = <span style=”color: #ff00ff;”>NULL;

 <span style=”color: #0000ff;”>/* Create a list of the device information for all
 devices of the specified class */
 hDeviceInfoSet = SetupDiGetClassDevs(&guid,;
 <span style=”color: #ff00ff;”>NULL, <span style=”color: #ff00ff;”>NULL, DIGCF_PRESENT);

 <span style=”color: #993300;”>if (INVALID_HANDLE_VALUE == hDeviceInfoSet)
 {
 <span style=”color: #0000ff;”>/* Set error */
 <span style=”color: #0000ff;”>/* ……….. */
 <span style=”color: #993300;”>return FALSE;
 }

 <span style=”color: #0000ff;”>/* Search the device information list for
 the WinDriver device */

 DeviceInfoData.cbSize = <span style=”color: #993300;”>sizeof(SP_DEVINFO_DATA);
 <span style=”color: #993300;”>do {
 <span style=”color: #0000ff;”>/* Get the next device in the list */
 bResult =
 SetupDiEnumDeviceInfo(hDeviceInfoSet,
 dwMemberIndex, &DeviceInfoData);

 <span style=”color: #993300;”>if (bResult)
 {
 dwRequiredSize = <span style=”color: #ff00ff;”>0;
 <span style=”color: #0000ff;”>/* Check if there is a driver reg path for this device */

 <span style=”color: #0000ff;”>/* First get the size only */
 bResult = SetupDiGetDeviceRegistryProperty
 (hDeviceInfoSet,
 &DeviceInfoData,
 SPDRP_DRIVER,
 &dwPropertyRegDataType,
 <span style=”color: #ff00ff;”>NULL,
 <span style=”color: #ff00ff;”>0,
 &dwRequiredSize);

 <span style=”color: #993300;”>if (bResult && dwRequiredSize > <span style=”color: #ff00ff;”>0)
 {
 dwPropertyBufferSize =
 dwRequiredSize + 1;

 pbPropertyBuffer =
 (TCHAR *)malloc(sizeof(TCHAR) *
 dwPropertyBufferSize);

 ASSERT(pbPropertyBuffer != <span style=”color: #ff00ff;”>NULL);

 <span style=”color: #0000ff;”>/* Then get this driver’s actual registry path */
 <span style=”color: #993300;”>if (SetupDiGetDeviceRegistryProperty
 (hDeviceInfoSet,
 &DeviceInfoData,
 SPDRP_DRIVER,
 &dwPropertyRegDataType,
 (PBYTE)pbPropertyBuffer,
 dwPropertyBufferSize,
 &dwRequiredSize))
 {
 <span style=”color: #0000ff;”>/* Check if the reg path is the same as in WinDriver */
 <span style=”color: #008000;”>int iResult = _tcscmp(
 pbPropertyBuffer,
 szDriverKeyName);

 <span style=”color: #993300;”>if (iResult == <span style=”color: #ff00ff;”>0)
 {
 <span style=”color: #0000ff;”>/* This is the device we are working with
 using WinDriver */

 /* Get the device’s instance ID */

 /* First get the size only */
 dwRequiredSize = <span style=”color: #ff00ff;”>0;

 bResult =
 SetupDiGetDeviceInstanceId
 (hDeviceInfoSet,
 &DeviceInfoData,
 <span style=”color: #ff00ff;”>NULL,
 0,
 &dwRequiredSize);

 <span style=”color: #993300;”>if (bResult && dwRequiredSize)
 {
 *pszDeviceInstanceId ==
 (TCHAR *)malloc(
 sizeof(TCHAR) *
 (dwRequiredSize + 1));

 ASSERT(*pszDeviceInstanceId
 != <span style=”color: #ff00ff;”>NULL);

 <span style=”color: #0000ff;”>/* Then get the actual device instance id */
 <span style=”color: #993300;”>if (
 !SetupDiGetDeviceInstanceId
 (hDeviceInfoSet,
 &DeviceInfoData,
 *pszDeviceInstanceId,
 dwRequiredSize + <span style=”color: #ff00ff;”>1,
 <span style=”color: #ff00ff;”>NULL))
 {
 dwError =
 GetLastError();
 <span style=”color: #0000ff;”>/* ….. */
 }
 }
 }
 }
 <span style=”color: #993300;”>else
 delete pbPropertyBuffer;             }
 }

 dwMemberIndex++;

 } <span style=”color: #993300;”>while(bResult && !*pszDeviceInstanceId);

 SetupDiDestroyDeviceInfoList(hDeviceInfoSet);

 <span style=”color: #993300;”>return FALSE;
}

Back To Top

Technical Document #32: I would like to execute in the kernel some pieces of code written in Delphi or in Visual Basic, using the Kernel PlugIn. Is it possible?

NOTE
Beginning with version 11.2.0 of WinDriver, Delphi and Visual Basic 6.0 are no longer supported.

WinDriver does not support implementing a Kernel PlugIn project in Delphi or in Visual Basic (VB), since these programming languages should not generally be used for kernel mode development. However, while the Kernel PlugIn application must be written in C, it is possible to write a user mode application in Delphi/VB, which communicates with the C Kernel PlugIn application. If you select to implement such a design, in order to ensure the correct interaction between the user mode and Kernel PlugIn applications, you will need to implement a Delphi *.pas file or a VB*.bas file that contains common definitions for the Kernel PlugIn and user mode applications — as done in the library header files of the sample and DriverWizard generated Kernel PlugIn C projects (e.g.,WinDriver\pci_diag\pci_lib.h, used by the sample KP_PCI driver / or in earlier versions — WinDriver\kerplug\kptest_com.h, used by the sampleKPTEST driver).
You can refer to the implementation of the WinDriver\include\windrvr.h C header file and the corresponding WinDriver\delphi\include\windrvr.pasand WinDriver\vb\include\windrvr.cls files for an example of implementing the same code both in C and in Delphi/Visual Basic (respectively).

Back To Top

Technical Document #36: How can I use WinDriver to generate a diagnostics driver code for Borland C++ Builder 6.0?

NOTE
Beginning with version 11.2.0 of WinDriver, Borland C++ Builder is no longer supported.

Beginning with version 5.0.5 of WinDriver, the DriverWizard includes specific code generation options for Borland C++ Builder 3.0–6.0, so you can simply select this option from the Wizard’s code generation window to create all the relevant project files, build the generated code and run it.

If you are using an earlier version of WinDriver, you can select to generate code with the DriverWizard for Borland C++ Builder 4, and then do one of the following to build a Borland C++ 6.0 project:

    • Open the generated project file from the Borland 6.0 environment and press ‘OK’ when notified of the upgrade to version 6.0.
      From the Project menu, select ‘Options’ –> ‘Directory/Conditionals’, and in the ‘Library Path’ text box, leave only the following text:
      $(BCB)\lib ” (instead of the entire file path that would be indicated in this box).

 

  • Alternatively, in the Borland C++ Builder 6.0 compiler:
    1. From the menu choose ‘Project’ –> ‘Add New Project’ .
    2. Pick the ‘Console Wizard’. A configuration window will pop up. Check the “C”, “Multi Threaded”, and”Console Application” options and press ‘OK’.
    3. From the menu choose: ‘Project’ –> ‘Add to project’ and add the following files from among the files WinDriver had generated for you: xxx_lib.c and xxx_diag.c (where XXX is your driver’s name).
    4. Add, the following files to the project: pci_diag_lib.c andprint_struct.c — for PCI cards, or usb_diag_lib.c — for USB devices, both found in the WinDriver\samples\shareddirectory.
    5. From the menu select ‘Project’ –> ‘Remove from Project’and remove any other file from the project (leaving only the files mentioned above).

 

Back To Top

Technical Document #49 : Replacing the driver for PCI/USB devices on Windows 2000: I tried to install new INF files for my Plug-and-Play devices on Windows 2000, using wdreg, but the OS keeps installing the old INF files from a previous WinDriver version. How can I resolve this?

The behavior your encountered is due to Windows 2000’s INF selection algorithm and can be resolved by deleting the old INF file(s) for your device from the %windir%\inf directory before installing the new file, as explained below.

When installing an INF file that registers your Plug-and-Play device to work with WinDriver, a copy of this device-INF file is placed in the%windir%\inf directory. In v5.2.2 (and earlier) of WinDriver, this copy is automatically named oem*.inf (unless you installed the INF file directly from the %windir%\inf directory). In newer versions of WinDriver, when installing the INF file with the wdreg utility (also used in the DriverWizard INF file installation) the copy of the INF file will have the same name as the original file.

When installing a new INF file for your device (e.g., the INF file created with v6.0.3 of WinDriver — in your case), a copy of the new device-INF file is placed in the %windir%\inf directory (in v6.x+ of WinDriver the name of this copy will be identical to that of the new INF file; in earlier versions the copy will be named oem*.inf). Then the devices are re-enumerated and Windows 2000 selects the older INF file (from version 5.2.2 — in your case) and installs it. The reason for this is that on Windows 2000, Setup selects the driver with the most recent date only if the driver package is signed. Otherwise, Setup uses a default date of 00/00/0000. In this case, the older INF file is selected, because the drivers are unsigned (see www.jungo.com/st/support/windriver/windriver_faqs/#win5).

To solve this problem, before installing a new INF file for a device on Windows 2000, you should first delete from the %windir%\inf directory any previous INF files for the device, to prevent Windows from installing an old INF file in place of the new file that you created. Look for files containing your device’s vendor and device IDs and delete them.

Note that this issue is not specifically related to the upgrade from v5.2.2 to v6.0.3 of WinDriver, nor to the use of WinDriver in general. The same applies any time you attempt to load a new INF file that installs an unsigned driver for a Plug-and-Play device on Windows 2000.

For a detailed explanation on how Windows Setup selects drivers, refer to the MSDN How Setup Selects Drivers page.

For detailed WinDriver version upgrade instructions, refer to Technical Document #84.

Note that it is recommended to remove old INF files from the%windir%\inf directory before upgrading the driver for a device on other Plug-and-Play Windows operating systems as well.

Back To Top

Technical Document #53: How do I reset my USB device using version 5.2.2 of WinDriver?

WinDriver provides you with an API for resetting your USB device:WD_UsbResetDevice() and WD_UsbResetDeviceEx() (added in version 5.0.4 of WinDriver). These functions cause the hub driver to reinitialize the device, while preserving the existing configuration.

WD_UsbResetDeviceEx() — added in version 5.0.4 — enables you to distinguish between performing a soft reset — which is similar to the reset performed with the WD_UsbResetDevice() function, used in previous versions; Or a hard reset.

The differences between a soft reset and a hard reset, performed withWD_UsbResetDeviceEx(), are as follows:

    • Soft reset: The reset request will be issued only if the device is in a disabled state (as done by Microsoft’s driver).

 

  • Hard reset: The reset request will always be issued — regardless if the device is in the disabled or enabled state.

To use the hard reset option, set the WD_USB_HARD_RESET flag in thedwOptions field of the WD_USB_RESET_DEVICE structure, which is passed toWD_UsbResetDeviceEx(). By default, when the dwOptions field is set to 0, the function will perform a soft reset — i.e., the reset request will be issued only if the device is currently disabled.

Following is an an example of using WD_UsbResetEx() to perform a hard reset:

    WD_USB_RESET_DEVICE reset;
    BZERO(resest);
    reset.hDevice = hDevice; // The handle received from
         // WD_UsbDeviceRegister()
    reset.dwOptions = WD_USB_HARD_RESET;
    WD_UsbResetDeviceEx(hWD, &reset);

NOTE: To prevent a system crash when performing hard reset, it is recommended to do the following: immediately after callingWD_UsbResetDeviceEx(), un-register the device (by callingWD_UsbDeviceUnregister()), scan for it (by calling WD_UsbScanDevice()) and then register it again (by calling WD_UsbDeviceRegister()). This will ensure that Windows will allocate all the resources for the device and will eliminate possible conflicts later on.

Back To Top

Technical Document #54: Sample InstallShield procedure for installing the driver on a Windows machine

NOTE: In the following sample, “WinNT” relates to Windows NT 4.0, Windows 2000 and Windows XP; “Win98” relates to Windows 98, Windows 98 Second Edition and Windows Me; And “Win95” relates to Windows 95.

Sample InstallShield procedure —

  number nvResult, nMajor, nMinor;
  STRING svResult;
  BOOL  bWinNT;
  BOOL  bWin98;
  BOOL  bWin95;
  
  bWinNT = FALSE;
  bWin98 = FALSE;
  bWin95 = FALSE;

  GetSystemInfo(OS, nvResult, svResult);
  if (nvResult  = IS_WINDOWSNT) then
      bWinNT = TRUE;
  else
      if (nvResult = IS_WINDOWS95) then
          GetSystemInfo(OSMAJOR, nMajor, svResult);
          GetSystemInfo(OSMINOR, nMinor, svResult);
          if (((nMajor > 4) || ((nMajor = 4) && (nMinor > 0)))) then
             BWin98 = TRUE;
          else
             bWin95 = TRUE;
          endif;
      endif;
  endif;

  if ((bWinNT = TRUE) || (bWin98 = TRUE)) then
      if (bWinNT = TRUE) then
          TARGETDIR = WINSYSDIR^"drivers";
      else
          TARGETDIR = WINSYSDIR^"..\\system32\\drivers";
      endif;
    
      CompressGet(COMPRESSED_FILE, "windrvr.sys",COMP_NORMAL);
  
  endif;
 
  if (bWin95) then   
       TARGETDIR = WINSYSDIR^"vmm32";
       CompressGet(COMPRESSED_FILE, "windrvr.vxd",COMP_NORMAL);
  endif;

To load WinDriver’s kernel and add it to the Registry:

For WinDriver version 5.2 and above:
  LaunchAppAndWait("wdreg_gui",
"-inf <full path to wd_virtual.inf> reload", WAIT);
LaunchAppAndWait("wdreg_gui",
"-inf <full path to your INF file> loadinf", WAIT);

For example:
  LaunchAppAndWait("wdreg_gui",
"-inf c:\tmp\wd_virtual.inf reload", WAIT);
LaunchAppAndWait("wdreg_gui",
"-inf %windir%\inf\my_device.inf loadinf", WAIT);

For WinDriver version 5.0.5b and below:
  LaunchAppAndWait("wdreg", "install", WAIT);

wdreg_gui.exe and wdreg.exe are found in the WinDriver\util directory.
In version 5.0.5b and earlier you can find the source code of the wdreg.exe utility in the WinDriver\samples\wdreg directory.

Note that wdreg install/wdreg_gui install adds WinDriver to the Registry, therefore WinDriver will be loaded on the next boot, and it also loads WinDriver immediately, so you can run your application without rebooting (except for *.sys drivers on Win98/Me).

Back To Top

Technical Document #57: Driver installation on Plug-and-Play systems (Windows 98/Me/2000/XP) — WinDriver version 5.0.5 and earlier

When installing a driver for Plug-and-Play (PnP) hardware (PCI/USB) on a PnP system (such as Windows 98/Me/2000/XP), using version 5.0.5 of WinDriver or earlier, you should install the wdpnp.sys PnP driver (formerly wdusb.sys) as the driver for your device, using an INF file.
You can use WinDriver’s DriverWizard to create the INF file for your device, and the install it according to the directions that will be displayed in the DriverWizard (and are also found in the WinDriver User’s Manual).

In addition, you need to have the WinDriver service running for hardware access. (This is required for all operating systems, not just PnP.) This service is supported by the windrvr.sys driver.
The program wdreg.exe is supplied for installing this service.

In version 5.2 of WinDriver, the windrvr.sys and wdpnp.sys files were combined into a single windrvr.sys driver file, which is installed on PnP systems via the installation of an INF file. Please refer to the Driver Distribution chapter of the updated WinDriver User’s Manual for more details regarding the current driver distribution process.

You can arrange to have wdreg.exe run earlier through an Install Shield or similar application packager, before the driver is installed (see Technical Document #54 for more information on this).

However, for Microsoft Windows certification (WHQL), you may need to have the entire installation performed through an INF file. In that case you can arrange to have one of your custom installation programs launched by your INF file by using the RUN ONCE key as shown below. [Please note that the following is true for version 5.0.5 or earlier of WinDriver].

 [Foobar.AddReg.NT]
HKLM,%RUNONCEKEYNAME%,,,"mycustom.exe"
.........
RUNONCEKEYNAME = "software\microsoft\windows\ currentversion\runonce\setup"

mycustom.exe is your custom program that incorporates the code ofwdreg.exe to install and start the WinDriver service.
For more information on wdreg.exe, see the “Dynamically Loading Your Driver” and the “Driver Distribution” chapters in the WinDriver User’s Manual.

You can also choose to use a co-installer program on Windows 2000 (see the MSDN WEB site for more information on co-installers).

If you do not wish to run an application program in this way, you can set up your INF file to copy windrvr.sys to the system32\drivers directory, and make the WinDriver service Registry entries.
This is demonstrated below for Windows 2000:

  [Foobar.AddReg.NT]
HKR,,FriendlyName,,%Foobar.SvcDesc% ; Human readable name
HKLM,System\CurrentControlSet\Services\WinDriver,,,
HKLM,System\CurrentControlSet\Services\WinDriver,
"Start",0x10001,0x02 ;2= on boot, 3= on demand
HKLM,System\CurrentControlSet\Services\WinDriver,
"Type",0x10001,0x01
HKLM,System\CurrentControlSet\Services\WinDriver,
"ErrorControl",0x10001,0x01
HKLM,System\CurrentControlSet\Services\WinDriver,
"ImagePath", ,"\SystemRoot\System32\drivers\windrvr.sys"
HKLM,System\CurrentControlSet\Services\WinDriver,
"DisplayName",,WinDriver

[Foobar.CopyFiles.NT] ; Files to copy
windrvr.sys,,,2 ; 2= user can’t skip this file

Note that the WinDriver service will only be started after a reboot.
For Windows 2000/XP/98/Me you can force a reboot by adding the Reboot or Restart directive to your INF file in the Install section.

 [InstallFoobar.NT]
CopyFiles=Foobar.CopyFiles.NT
AddReg=Foobar.AddReg.NT
Reboot

If you wish to avoid the reboot, you need to adopt one of the aforementioned methods (co-installer, SETUP\RUNONCE key, application installer).

Back To Top

Technical Document #62: Kernel PlugIn Driver Installation — General Guidelines

When using WinDriver’s Kernel PlugIn feature you are creating your own driver file, which is used in addition to the generic WinDriver kernel driver— windrvr<version>.sys/.o/.ko in the newer versions (e.g.,windrvr1200.sys/.o/.ko).

Please be sure to diligently follow the instructions in the WinDriver User’s Manual for building and installing your Kernel PlugIndriver.

You should specifically pay attention to the following points:

    • If you have used WinDriver’s Kernel PlugIn sample driver (KP_PCI/ KPTEST in v6.2.3-) as the basis for your Kernel PlugInapplication, be sure to replace the driver name (“KP_PCI” / “KPTEST”) in all locations in the sample files with your chosen driver name.The driver name should be indicated in the code in Capital Letters and without the sys/vxd/kext/o/ko extension.In v7.0.0+ of WinDriver, verify specifically that you have specified the driver name correctly in the definition of KP_PCI_DRIVER_NAME in the equivalent of the sample’s pci_lib.h file.For earlier versions of WinDriver (v6.2.3-), modify the equivalent of the following line in KP_Init():
        strcpy(kpInit->cDriverName, "KPTEST");
      and change the assignment to the pcDriverName member of theWD_KERNEL_PLUGIN structure, which is passed toWD_KernelPlugInOpen() in the user-mode project.

 

    • When developing a SYS driver for Windows (Windows 98 and higher), remember to install Microsoft’s driver development kit for your OS (WDK / DDK) and set the BASEDIR environment variable to the location of your WDK/DDK directory before attempting to build your Kernel PlugIn SYS driver (as explained in the manual). (For version 5.0.5 of WinDriver and earlier, it is recommended to build your code with the Windows NT DDK. For Windows NT 4.0 — in WinDriver versions that support this OS — you also need to install the NT SDK.)
      For earlier versions of WinDriver (v6.0x-), which supported development of VxD drivers on Windows 95/98/Me, when developing a VxD driver you do not need to install the WDK/DDK (unless you added your own DDK function calls to theKernel PlugIn code). When using the compile.bat file from the KPTEST sample to compile your VxD driver, comment-out or remove the following line:
         nmake %1 /f kptest.mak
      leaving only the line:
         nmake %1 /f kptest.mak WIN95=1Beginning with v5.2.0 of WinDriver, the DriverWizard can also be used to generate Kernel PlugIn code and a compatible user-mode application for your device, including the required project or makefiles for building the code (depending on the target OS).
      For Windows, you can build the generated MS Visual Studio (Visual C++) project into a SYS driver on a Windows NT and higher machine, by simply opening the generated workspace/solution file — xxx.dsw/sln — and building the code, after setting the Active Build Configuration according to the OS for which you are developing. (SYS drivers for Windows 98/Me — supported in earlier versions of WinDriver — should be built on a Windows NT or higher machine.)
      Beginning with v11.0.0 of WinDriver, you can also use the generated Windows GCC makefile to build the generatedKernel PlugIn code in your selected environment Windows GCC environment (MinGW/Cygwin).Note: When building a kernel project with MS Visual Studio, the project path must not contain any spaces.

 

    • Verify that the WinDriver kernel module is installed: Before installing your Kernel PlugIn driver, verify that the WinDriver driver — windrvr<version>.sys/.o/.ko in the newer WinDriver versions (e.g., windrvr1200.sys/.o/.ko) — is installed, since theKernel PlugIn module depends on the WinDriver module for its successful operation. (You can run the Debug Monitor to verify that WinDriver is loaded).

 

  • Install your Kernel PlugIn driver:
      • Remember to copy your Kernel PlugIn driver (my_kp/.sys/.vxd/.kext/.o/.ko) to the operating system’s drivers/modules directory before attempting to install the driver. On Linux, beginning with v6.2.3 of WinDriver you do not need to copy the driver file, since the driver installation (make install) will handle this for you.
    • Don’t forget to install your Kernel PlugIn driver before running your application:On Windows: Use the wdreg installation utility (orwdreg_gui/wdreg16 — depending on the WinDriver version and OS that you are using) to install the driver:To install a my_kp.sys driver, run this command:
          wdreg -name MY_KP install

      To install a my_kp.vxd driver (in the WinDriver versions that support this driver type), use the -vxd flag:
           wdreg -name -vxd MY_KP installOn Linux: For v6.2.3+ of WinDriver, from the kermode/Kernel PlugIn directory run this command:
          make install
      For earlier versions of WinDriver, use insmod to install the driver module.

      On Solaris: Use add_drv to install the driver.

NOTE
The Kernel PlugIn is not backward compatible. Therefore, when switching to a different version of WinDriver, you need to rebuild your Kernel PlugIn driver using the new version.

Back To Top

Technical Document #63: When compiling the WinDriver module on Linux machine, I get the following error: usr/include/linux/modversions.h:1:2: #error Modules should never use kernel-headers system headers, but headers from an appropriate kernel-source

There are two possible reasons for this error:

  1. There is no Linux kernel source in the /usr/src directory.

    To fix this:

      • Download the exact kernel version you are working on from one of the mirrors (for example: http://www.linuxhq.com/or http://www.kernel.org) and run ‘uname -a‘ to get the version of the running Linux kernel.
      • Install the kernel package from your Linux distribution disk.
  2. You neglected to create a ‘linux’ symbolic link (/usr/src/linux), or you created a symbolic link that is pointing to the wrong Linux kernel version. (For example, you are compiling for Linux kernel 2.2 and the symbolic link points to Linux kernel 2.4 source tree.)

    To fix this:
    Become super user: $su ;
    Change directory to: /usr/src/: # cd /usr/src/ ;
    Delete the previous link you created (if any): # rm linux ;
    And create a new symbolic: # ln -s linux-2.2 linux)

For further information, refer to the “Installation And Setup” chapter of the WinDriver User’s Manual for your WinDriver version.

Beginning with version 6.2.3, WinDriver uses a different installation mechanism on Linux, which should prevent this error from occurring.

Back To Top

Technical Document #64: Linux contiguous-buffer DMA allocations — 128KB limitation

NOTE
Beginning with version 8.0.2 you can use WinDriver to allocate contiguous DMA buffers of more than 128KB on Linux. The following information is relevant for versions 8.01 and below of WinDriver.

By default you can allocate a contiguous DMA kernel buffer of no more than 128KB on Linux. (With regard to the possibility of performing Scatter/Gather DMA on Linux — see Technical Document #47.)

It is possible to recompile the kernel to get larger sizes.
You can look for the bigphysarea patch, which enables DMA allocation of buffers that are larger than 128KB.
You can also download the code for Linux kernels (the relevant file is/usr/src/linux/mm/slab.c ; look for cache_sizes struct) and study the code to understand how to do this, or join Linux-kernel discussion groups on Usenet to get more information on this.
Please note, however, that we have not tested the aforementioned patch and that we will not be able to provide support for any matters related to attempts to increase the maximum DMA buffer allocation size.

If you do recompile the kernel to enable allocation of DMA buffers that are larger than 128KB, you will also need to change the implementation ofLINUX_kmalloc() in linux_wrappers.c. The current implementation returns NULL if the requested allocation size is bigger than 128KB. If you use the bigphysarea patch, you will need to call the relevant functions from the patch in LINUX_kmalloc().

Back To Top

Technical Document #65: WinDriver For Solaris — 32-bit Architecture Support

The Solaris kernel supports both a 32-bit and a 64-bit architecture.
WinDriver version 9.0.1 and below supports Solaris versions 8, 9, 10, and OpenSolaris, using 64-bit architecture on SPARC platforms (Solaris 10 and OpenSolaris are supported from v8.0.0). Earlier versions (v5.2.2 and earlier) of WinDriver support only Solaris 2.6/7.0/8.0 using 32-bit architecture, on SPARC and x86 platforms,

Beginning with Solaris 8.0, the default Solaris installation uses the 64-bit architecture. If you are encountering problems in installing WinDriver on your Solaris machine, it may be because you are trying to use WinDriver with the Solaris 64-bit architecture. In order to find out which architecture you are currently using, run: ‘isainfo -v‘, so you can install the correct WinDriver version.

Back To Top

Technical Document #66: WinDriver for Solaris SPARC — 33Mhz * 33MB PCI Bus Support

On Solaris SPARC there are two PCI buses from the root hub.
WinDriver v9.0.1 and below supports only the 33Mhz * 33MB PCI bus.

Therefore, if you encounter problems when trying to use WinDriver to detect and access your PCI card on a Solaris SPARC machine, please verify that your card is inserted into a PCI slot on the 33Mhz*33MB PCI bus.

Back To Top

Technical Document #67: Can I use DriverBuilder to develop an Ethernet network driver for VxWorks?

Ethernet drivers normally fit into a standard architecture. For VxWorks, this would be VxWorks specific, but it resembles other Unix network driver models. Apart from interfacing with the network stack (which you would need to implement yourself), the driver needs to “talk” to the NIC hardware. You can use DriverBuilder’s generic hardware access routines to access the NIC hardware. The main advantage in this case would be that you can reuse the hardware handling code on Linux, Windows or any other OS that WinDriver supports.

Back To Top

Technical Document #68: I am trying to use DriveBuilder for VxWorks, but I fail downloading windrvr.o to the target. I get a message that the following symbols were unresolved: pciConfigInlong, pciConfigOutLong.

This error points to a failure to enable PCI support in your VxWorks OS image. You need to check your VxWorks project settings and make some changes to config.h before rebuilding the VxWorks image. These changes are OS and platform specific.
Please contact WindRiver systems’ technical support for more information.

Back To Top

Technical Document #69: I am using DriverBuilder for VxWorks. I loaded pci_diag.out and ran pci_diag_main, but if failed with the following error message: Error loading driver

Please verify that you have followed all the steps in the WinDriver VxWorks Installation Instructions in the User’s Manual of the WinDriver version that you’re using.
Did you forget to run the drvInit() function?
This function call initializes the driver module windrvr.o that is provided by WinDriver.

Back To Top

Technical Document #70: What are the names of the entry points routines for your various DriverBuilder VxWorks sample programs: wddebug.out, pci_dump.out, etc.?

Just add "_main" after the base name of the program.
For example, the entry point routine for wddebug.out is wddebug_main and the entry point routine for pci_dump.out ispci_dump_main.

Back To Top

Technical Document #71: When running the PCI diagnostics application on a VxWorks machine, I get the following error message when trying to open the board: Card does not have all items expected for MyDrive.

This message is issued by the diagnostics XXX_Open() function if theXXX_DetectCardElemets() function fails (see xxx_lib.c for the functions implementation) — where XXX is your driver’s name.

The reason for this error may be that your PCI card has not been configured.
Intel X86 PCs normally host PCI BIOSs, which will configure the card on bootup. Your target computer may not have such a BIOS.
Some VxWorks BSPs have PCI auto configuration support, which you can build into your image so that when the target boots the image, the PCI cards will get auto-configured. The steps required are OS and platform specific. Please contact WindRiver systems’ technical support for more information.

Back To Top

Technical Document #79: Does WinDriver support 64-bit data transfers?

Yes. Beginning with version 5.2.0, WinDriver supports 64-bit data transfers. Please refer to the WinDriver PCI User’s Manual for detailed information regarding this support. The usage of WinDriver’s 64-bit API is demonstrated in the special library functions for the PLX 9656 chip (available under the WinDriver/plx/9656/ directory).

Please note that even with earlier versions of WinDriver, once you have mapped the memory on your card (using WinDriver), you could directly access the memory in a 64-bit access pattern. You would, however, need to use a 64-bit compiler to generate code that has this capability. WinDriver itself (until version 5.2.0) does not assist you in this, because it has no knowledge of 64-bit code, but with a good 64-bit compiler and some experimentation, you can probably enjoy the 64-bit performance with earlier versions of WinDriver as well.

Back To Top

Technical Document #80: I have a PLX 9050 card, but I cannot access the card’s memory with WinDriver’s PLX 9050 diagnostics utility. I am using the P9050_Read/WriteXXX() functions.

When using WinDriver’s sample P9050_Read/WriteXXX() functions, you must set the values of the re-map register in the p9050_lib.c file (this depends on your hardware). The card may hang if the wait-states are not set correctly.

Since many developers are not aware of this feature, and they prefer to set the re-map register in the EEPROM init (when the computer is turned on), beginning with version 3.0.3 of WinDriver we have added new functions to the PLX 9050 library, which access the PLX 9050 card’s address ranges without changing the re-map register. These functions areP9050_ReadSpaceByte() and friends. When using a WinDriver version 3.0.3 and higher, you can use these functions by selecting to “Access address spaces on the board” instead of selecting to “Access local address ranges on the board” from the main menu of the WinDriver PLX 9050 diagnostics utility.
This option uses P9050_ReadSpaceByte() and the similar Read/Write Space functions, instead of the “regular” P9050_ReadByte() (and similar) functions. The “regular” P9050 Read/Write function first set the re-map register, then call the relevant Read/Write Space function (e.g.,P9050_ReadByte() calls P9050_ReadSpaceByte()).

If you do not want WinDriver to set the re-map register, but prefer a low-level access (like DriverWizard and PLX-MON do), call the Read/Write Space functions (like P9050_ReadSpaceByte()).

Back To Top

Technical Document #83: When using multiple PLX 9050 cards I occasionally get the error Do_card_lock failed: item already in use, and pci_dump indicates a memory resource overlap in BAR0. I can sometimes resolve this by moving cards to other PCI slots.

The change in the BARs is due to the PLX 9050 BIT 7 errata.
The PLX 9050 chip has a problem of accessing the card address spaces if the BAR0 register was given the value 1 in its BIT 7 (by the BIOS).
Our attempted fix (in WinDriver\plx\9050\lib\p9050_lib.c) is to zero this bit and then continue to work with the card. In your particular case, this caused a resource overlap.

To resolve the overlap, you can do one of the following:

    • Replace your cards with PLX 9052 based cards (recommended).
      The PLX 9052 chip resolved the bug of the PLX 9050 chip.

 

    • Reprogram the BARs yourself or relocate the PCI cards so that BAR0 does not have the 7th BIT set.

 

  • Add the P9050_OPEN_FIX_BIT7 option in your call toP9050_Open():
    In the file p9050_lib.c change:  if(P9050_Open(&hPlx, dwVendorID, dwDeviceID,
    my_card − 1, 0 /* P9050_OPEN_USE_INT |
    P9050_OPEN_FIX_BIT7 */
    ))

    to:

      if(P9050_Open(&hPlx, dwVendorID, dwDeviceID,
    my_card − 1, 0 P9050_OPEN_FIX_BIT7))

    Recompile and run.

    However, please note that you might not be able to access the memory spaces on the cards if you select this option.

More information on this subject can be found on the PLX website.

Back To Top

Technical Document #84: Upgrading your WinDriver version

This document outlines the steps for upgrading from version 8.1.1 or newer to the latest WinDriver version. For upgrade instructions from an earlier version of WinDriver and/or to an earlier version, refer to Technical Document #131.

 

Upgrade Steps

  1. Install the new version
  2. Acquire a New WinDriver License (Registered Users)
  3. Upgrade Your Driver Project
  4. Upgrade Your Device INF File (Windows)
  5. Digitally Sign Your Driver Files (Windows)
  6. Upgrade Your Driver Distribution/Installation Package

 

  • Install the new version

Download and install a new version of WinDriver that matches your development platform and the operating systems and CPU configurations of the target platforms on which you intend the driver to be used.

  • Acquire a New WinDriver License (Registered Users)

If you are using a registered version of WinDriver, contact Jungo Connectivity at [email protected] to acquire a WinDriver license registration string for the new version. Then register the new license from DriverWizard (File | Register WinDriver) and from your code.

Note that if you have a valid Support and Upgrade plan you are are entitled to receive a new license free of charge.
If you do not have such a plan, contact [email protected] to request a temporary license that will allow you to evaluate the new version.

  • Upgrade Your Driver Project
      • Register Your New License (Registered Users): Modify the driver code to register your new license — i.e., replace the license string in the call to WDU_Init() (USB) /WDC_DriverOpen() (PCI/ISA — WDC API) / WD_License()(low-level API) from your code.PCI users — if you created a Kernel PlugIn driver, make sure to also update the license string in your Kernel PlugIncode.
      • PCI/ISA users upgrading from v11.7.0 or below — refer to Technical Document #116 for information on API changes done in v11.8.0 of WinDriver, and edit your code accordingly.

 

      • 64-bit OS upgrade (Windows and Linux)
          • When developing a driver for a 64-bit platform, your project or makefile must include the KERNEL_64BITpreprocessor definition. In the makefiles, the definition is added using the -D flag: -DKERNEL_64BIT. The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects in the 64-bit WinDriver toolkit already add this definition.
        • PCI Kernel PlugIn upgrade from v10.2.1- — to support execution of 32-bit applications with a 64-bitKernel PlugIn driver, follow the instructions in Technical Document #112.

 

      • Rename your driver (Windows and Linux) — To avoid conflicts with other WinDriver-based drivers on the target platforms, we highly recommend that you rename the default WinDriver driver module — windrvr<version>.sys(e.g., windrvr1200.sys) on Windows /windrvr<version>.o/.ko (e.g., windrvr1200.o/.ko) onLinux (or windrvr6.sys / windrvr6.o/.ko in v11.8.0 and older) — to a unique name, by following the instructions in the new WinDriver User’s Manual. The renaming procedure is simple and quick.
        The Linux USB GPL driverwindrvr<version>_usb.o/.ko (or windrvr6_usb.o/.koin v11.8.0 and older) is automatically renamed when renaming the main WinDriver Linux driver.
        When creating a PCI Kernel PlugIn driver, select a unique name as well.

 

      • Ensure that your code uses the correct driver module— Verify that the call to WD_DriverName() in your driver code (if exists) uses the new driver-module name —windrvr<version> or your renamed version of this driver.
        In version 11.9.0 of WinDriver the default WinDriver driver-module name changed from windrvr6 towindrvr<version> (e.g., windrvr1200 in v12.0.0). Consequently, when using the default driver-module name old projects need to be updated to use the default name from the newer version. If you use the generated DriverWizard code or one of the samples from the new WinDriver version, the code will already use the default driver name from the new version. Also, if your code is based on generated/sample code from an earlier version of WinDriver, rebuilding the code with windrvr.h from the new version is sufficient to update the code to use the new default driver-module name (due to the use of theWD_DEFAULT_DRIVER_NAME_BASE definition).
        If you elect to rename the WinDriver driver module, ensure that your code calls WD_DriverName() with your custom driver name. If you rename the driver from the new version to a name already used in your old project, you do not need to modify your code.

        NOTE
        To apply a driver name change — whether using the default driver name or a custom name — your user-mode driver project must be built with theWD_DRIVER_NAME_CHANGE preprocessor flag (e.g., -DWD_DRIVER_NAME_CHANGE), as explained in the WinDriver WinDriver User’s Manuals and demonstrated in the sample and generated DriverWizard WinDriver projects/makefiles.

 

      • Rebuild your updated driver project with the source files from the new version.PCI users who created a Kernel PlugIn driver must rebuild it with the files from the new version as well.

  • Upgrade Your Device INF File (Windows)

On Windows, if you have created a driver for a Plug-and-Play device (USB/PCI/CardBus/PCMCIA), we recommend that you create and install a new INF file for your device, which registers it with the driver module from the new version —windrvr<version>.sys (e.g., windrvr1200.sys) /windrvr6.sys in v11.8.0 and older — or your renamed version of this driver (in v9.x and newer). You can use DriverWizard from the new version to generate the new INF file, or change the driver version in your old INF file.

  • Digitally Sign Your Driver Files (Windows)

On 64-bit versions of Windows Vista and higher

      , Microsoft requires that kernel drivers be digitally signed. Therefore, if you use any of the following driver files you must digitally sign them: A

renamed

      version of the WinDriver kernel driver (the default WinDriver driver —

windrvr<version>.sys

      /

windrvr6.sys

      in v11.8.0 and older — is already digitally signed), a

Plug-and-Play device INF file

      , and/or a

PCI Kernel PlugIn driver

      . You can bypass this restriction during the development stage (e.g., on Windows 7, by pressing

F8

      at boot time and selecting the relevant option), but the driver files must be signed before distribution. There are also advantages to signing your driver

on other Windows OSs

      . For more information, refer to

Micorsoft’s Driver Signing Policy

      and to the

Windows Digital Driver Signing and Certification

      section of the

WinDriver User’s Manuals

      .

You can obtain digital signatures from third-party companies such as DigiCert or Symantec, or use Jungo Connectivity’s digital driver signing service. Jungo Connectivity can also assist you in preparing your driver for Microsoft’s Windows cetification.

  • Upgrade Your Driver Distribution/Installation Package

Create a new driver installation package that contains the relevant files from the new WinDriver distribution, depending on your hardware and target OS:

      • The WinDriver driver module —windrvr<version>.sys/.o/.ko/.dll (e.g.,windrvr1200.sys/.o/.ko/.dll) in the newer WinDriver versions, or a renamed version of this driver
      • The WinDriver Linux USB GPL driverwindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) in the newer WinDriver versions, or a renamed version of this driver
      • Your rebuilt PCI Kernel PlugIn driver —<KP_driver_name>.sys (if created)
      • Any other files required for installing or using your driver — such as wdapi<new_version>.dll/.so,wdreg[.exe]/wdreg_gui.exe (and difxapi.dll on Windows), and Windows INF and catalog files
      • An installation program that installs the new driver

Hardware- and OS-specific driver distribution instructions can be found in the Distributing Your Driver chapter of the new WinDriver User’s Manuals. The instructions for Windows are also summarized in Technical Document #132.

Version-Specific Installation Upgrade Notes:

    • Linux USB v9.2.1- to v10.0.0+ upgrade — the WinDriver USB Linux GPL driver: Beginning with v10.0.0, the WinDriver Linux USB driver was split into two modules, which are used together to provide the full driver functionality:
      • windrvr6.o/.ko, renamed in v11.9.0 towindrvr<version>.o/.ko (e.g.,windrvr1200.o/.ko) — the traditional WinDriver driver module, which includes the product license.
      • windrvr6_usb.o/.ko, renamed in v11.9.0 towindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) — this driver implements Linux-specific USB driver functionality, and contains a GNU General Public License (GPL).

Back To Top

Technical Document #85: How do I extract the string descriptors contained in the Device and Configuration descriptor tables?

You can use WinDriver’s WDU_GetStringDesc() function to get the desired string descriptors. For detailed information regarding this function, refer to the WinDriver USB User’s Manual.

Back To Top

Technical Document #86: How do I detect that a USB device has been plugged in or disconnected?

If you are using version 5.2.0 or later of WinDriver, you can use WinDriver’s API to register to listen to specific Plug-and-Play and/or power management notifications from the OS, including notifications of device insertion/removal, and implement a relevant callback in your application to handle such situations. When using version 6.0 and above, useWDU_Init() to register to listen for the notifications you are interested in.In versions 5.2.0–5.2.2, use event_register(). Please refer to the WinDriver User’s Manual for the WinDriver version that you are using for a detailed description of the relevant APIs.

In earlier versions of WinDriver — version 5.0.5b or below — WinDriver did not provide specific API support for Plug-and-Play and power management events. In these versions, WD_UsbScanDevice() detects the devices which are connected to the computer at the time of the function call. If another device is later connected to the computer, or a device is disconnected, these changes will not automatically be detected.WD_UsbScanDevice() must be called again in order to detect the changes. However, since WinDriver USB drivers are user mode WIN32 applications, they can get a notification of insertion/removal. Windows sends all applications a WM_DEVICECHANGE message. Once the application receives this message it should call WD_UsbScanDevice() to check if the device was inserted/removed (this is only good for Windows). You should therefore be able to implement PnP device insertion/removal support with earlier versions of WinDriver as well, using the Win32 API. You can also send aGET_DESCRIPTOR request to the device (using WD_UsbTransfer() to verify if the device is connected. Please note that in order to handle the device after it has been disconnected, you must first callWD_UsbDeviceUnregister() to free the previous handle to the device, then re-scan the USB bus to locate the device (using WD_UsbDeviceScan()), get the device’s configuration information (by callingWD_UsbGetConfiguration() and re-register the device by callingWD_UsbDeviceRegister().

Back To Top

Technical Document #87: How do I setup the transfer buffer to send a null data packet through the control pipe?

You should set the pBuffer parameter of the WDU_Transfer() function toNULL and set the dwBufferSize parameter to 0.

In version 5.2.2 and earlier, set the pBuffer field of the WD_USB_TRANSFERstructure, used in the call to WD_UsbTransfer(), to NULL, and set thedwBytes field of this structure to 0.

Back To Top

Technical Document #89: WinDriver driver distribution to a target Windows machine — versions 4.2.0–5.0.5b

In order to distribute your WinDriver-based driver to a target Windows machine (which does not have the WinDriver software installed), when using version 4.2.0–5.0.5b of WinDriver, please follow the instructions below.

1. Copy the windrvr.sys or windrvr.vxd driver file (depending on your OS) and your Kernel PlugIn SYS/VxD driver (if you have created such a driver) to the target computer’s drivers’ directory (e.g., WINNT\system32\drivers) and then install the driver/s using WinDriver’s WDREG.EXE utility program (found in theWinDriver\util directory on the development machine) — as explained in the “Distributing Your Driver Chapter” of the manual.

To install windrvr.sys or windrvr.vxd (on Windows 95) simply type:
    wdreg install.
To install windrvr.vxd on Windows 98/Me type:
    wdreg -vxd install
(since by default wdreg.exe installs windrvr.sys).

(windrvr.sys and windrvr.vxd are found, on the development machine, in the WinDriver\redist\register directory — for registered users, or in the WinDriver\redist\eval directory — for evaluation users.)

If you have created a Kernel PlugIn driver, install it using thewdreg.exe utility:

  • To install a SYS driver type:
        wdreg -name <KP driver name> install

 

  • To install a VxD driver, use the -vxd flag:
        wdreg -vxd -name <KP driver name> install

NOTE: The driver name should be indicated without the*.sys/*.vxd extension.

(You can also use the -startup flag to determine the driver’s startup option: boot/system/automatic/manual (on demand).)

For more information regarding the wdreg.exe utility, please refer to the “Dynamically Loading Your Driver” chapter of the manual.

2. Copy your WinDriver executable/DLL file, which implements the driver functionality, to the target.

3. For Plug & Play devices (such as PCI and USB), if you are installing the driver on a target machine running a PnP operating system (e.g., Windows 98/Me/2000/XP), you will also need to copy the PnP driver file — wdpnp.sys (found in the WinDriver\redist directory on the development machine) — and an INF file to the target machine, and install the INF file on the target — as explained in the relevant section of the Driver Distribution chapter of the manual and in the installation instructions that will be displayed when you select to generate an INF file for your device with the DriverWizard. (wdpnp.sys replaced the wdusb.sys driver that was used in earlier versions of WinDriver.)

The default INF file that is generated by the DriverWizard copieswdpnp.sys to Windows’ drivers’ directory.
(You can also use this file to copy windrvr.sys to the drivers’ directory, by removing the comment (;) at the beginning of the following line in the generated INF file: ;windrvr.sys.)

The installation of the INF file should direct Windows’ Plug & Play Manager to wdpnp.sys as the driver for your device.
You can verify this at the end of the installation by locating your device in the Device Manager and selecting ‘Properties’ –> ‘Driver’ –> ‘Driver Details…’.

 

 

Back To Top

Technical Document #90: Installing an INF file for PCI/USB devices on Windows Plug and Play systems in WinDriver versions 4.20–5.05

When using version 4.2.0–5.0.5 of WinDriver to install a PCI/USB driver on a Plug and Play (PnP) system (Windows 98/Me/2000/XP), two driver files are required for the installation:

  1. windrvr.sys/vxd, found in the WinDriver\redist\register /WinDriver\redist\eval directory. This driver implements WinDriver’s kernel module and should be installed using the wdreg.exeinstallation utility. [windrvr.sys (or windrvr.vxd — on Win95) is automatically installed on the development machine when installing the WinDriver tool-kit].
  2. wdpnp.sys (or wdusb.sys — in versions 4.2.0–4.3.2), which is located in the WinDriver\redist directory. This driver should be installed via the installation of an INF file.

You can use the DriverWizard to generate an INF file for your device.
After generating the INF file, you need to update the driver for the device, using Windows’ Device Manager or the “Found New Hardware” wizard — as explained in the dialog box that pops up when you finish generating the INF file with the DriverWizard and in the Driver Distribution chapter in the manual forversions 4.2.0–5.0.5.

To install the INF file from the Device Manager, follow these steps:

  1. Open Window’s Device Manager and locate your device (from the Menu select ‘View’ –> ‘Devices by connection’, and look for your device under the PCI bus / PCI bus -> USB Host Controller -> USB Root Hub). For USB devices, please be sure to select the node for your device that appears directly under the USB hub.
  2. Right-click the mouse on the device’s node and select'Properties', then select the ‘Driver’ tab and click on‘Update driver…’.
  3. In the ‘Upgrade Device Driver Wizard’ first installation window select ‘Next’, then choose ‘Search for a suitable driver for my device’ from the 'Install Hardware Device Drivers' window and click ‘Next’.
  4. In the 'Locate Driver Files' window choose ‘Specify a location’ then click ‘Next’.
  5. In the ‘Upgrade Device Driver Wizard’ window that will be displayed, specify the location of the .INF file (you can use the ‘Browse…’ option to locate the file) then click ‘Next’. If asked to specify the driver for the device, point to the location of the wdpnp.sys file.
    At the end, click ‘Finish’.
  6. Reboot (not always required).

To somewhat automate the installation you can copy both the generated INF file and wdpnp.sys to Windows’ inf‘ directory, when the device is disconnected, then plug-in the device.
At this point, the OS should automatically identify the INF file for your device and install it. However, you may still be prompted to direct the OS to the location of the wdpnp.sys driver file.

At the end of the installation, verify that wdpnp.sys has been installed successfully by locating your device in the Device Manager and selecting ‘Properties’ –> ‘Driver’ –> Driver Details…’.

If wdpnp.sys is not indicated as the driver after the installation of the INF file, please erase all oem*.inf and corresponding *.pnf files from Windows’ ‘inf‘ directory (for Windows 98/Me, look underinf\other), and then attempt to reinstall the INF file — in order to ensure that Windows is not inadvertently installing the wrong INF file for your device, by , and then try to reinstall the INF file.

Back To Top

Technical Document #91: Does WinDriver USB support isochronous streaming mode?

Yes. WinDriver provides WDU_StreamXXX() functions for peforming streaming USB data transfers on Windows 2000 and higher (WinDriver v9.0.0+) and Windows CE (WinDriver v10.0.1+).
For more information, refer to the WinDriver USB User’s Manual.

Back To Top

Technical Document #92: I used the DriverWizard to listen to the floppy disk interrupt (IRQ 6) successfully on my Windows machine. But when I try to listen to the mouse interrupt (IRQ 12) or to the keyboard interrupt (IRQ 1), I get the following error message: Cannot enable interrupt — might be in use by another device

In some cases, the operating system locks the interrupts exclusively, thereby preventing you from listening to these interrupts.
Windows 2000 does this for the mouse and keyboard interrupts.

In versions 11.1.0 and below of WinDriver, you can refer to WinDriver’s VB interrupt sample program (found in theWinDriver\vb\samples\interrupt directory and available also from Windows’ start-up menu) for a list of the common IRQs (floppy disk, mouse and keyboard) and their availability on different operating systems.
As indicated in this list, the mouse and keyboard interrupts cannot be used on Windows 2000.
You can also use this sample to listen to ISA interrupts, which are not exclusively locked by the OS.

Back To Top

Technical Document #93: WinDriver installation on Linux RedHat 7.3 kernel version 2.4.18-4 gives this error: linux_wrappers.c:405: too few arguments to function ‘do_munmap_Rd007fc14’ make:*** [LINUX.2.4.18-3/linux_wrappers.o]

In RedHat Linux 7.3 an additional parameter was added to the functiondo_munmap().

If you are using WinDriver version 5.0.5 or earlier, you can download http://www.jungo.com/st/support/download/do_munmap_505.tgz and use the files to resolve this problem. (The files should be copied to theWinDriver/redist directory, instead of the corresponding files from the version which you are currently using.)

If you are using WinDriver version 5.0.5b–5.2.1, please use the makefile and linux_wrappers files from the WinDriver installation, and simply change the makefile to assign 1 instead of 0 to DO_MUNMAP_API_CHANGE, as explained in the makefile itself:

    # Change DO_MUNMAP_API_CHANGE value to 1 if in the
      file
    # /usr/src/linux/include/linux/mm.h the following
      function is defined:
    # extern int do_munmap(struct mm_struct *,
      unsigned long, size_t, int acct);
    # instead of extern int do_munmap
      (struct mm_struct *, unsigned long, size_t);
    DO_MUNMAP_API_CHANGE=0

For general WinDriver installation instructions for Linux, refer to the WinDriver User’s Manual of your WinDriver version. (Updated instructions for the latest version are also found online.)

Beginning with version 5.2.2 of WinDriver this is internally handled by the makefile, so you do not need to make any modifications yourself.

Back To Top

Technical Document #95: Does WinDriver support development for PCMCIA devices?

Starting with version 6.2.2, WinDriver supports PCMCIA on Windows.
The latest WinDriver Windows version (v12.0.0) supports PCMCIA on Windows 10/8.1/Server 2012 R2/8/Server 2012/7/Server 2008 R2/Vista/Server 2008/Server 2003/XP.

In earlier versions, you can use WinDriver to develop a driver for a PCMCIA card by defining the card’s resources manually and handling the card as a regular ISA card. (Plug and Play detection of the card’s resources is not supported for PCMCIA, in v5.0.4–v6.2.1 of WinDriver).
Alternatively, consider replacing your PCMCIA hardware with a CardBus card (recommended) — see Technical Document #94 for information regarding WinDriver’s support for CardBus.

Back To Top

Technical Document #96: Is it possible to write my own parallel port driver using WinDriver?

WinDriver regards the Parallel port as if it were an ISA card (with I/O addresses 0x378-0x37f). You can therefore select to create a driver for the PC’s parallel port by selecting the “Parallel port” option from the DriverWizard’s “Card Information” window. You will then be able to read/write the I/O addresses of the parallel port, view the relevant registers and listen to the parallel port interrupt. You will also be able to edit the resources definitions, as with any other ISA card. In addition, you can use the DriverWizard to generate a skeletal diagnostics code, which utilizes WinDriver’s API to access the parallel port’s I/O addresses and register to listen to the parallel port’s interrupt.

In v11.1.0 and below of WinDriver for Windows, you can refer to the sample Visual Basic parallel port WinDriver application (including source code), in the WinDriver\vb\samples\parallel directory.

Please note that WinDriver does not handle possible conflicts with the operating system’s parallel port driver, and you may need to disable this driver when using WinDriver to access the parallel port.

Back To Top

Technical Document #105:

PCI uses level sensitive interrupts, which must be acknowledged and cleared in the kernel immediately when they are received. Therefore, WinDriver requires you to define an interrupt-status register that will be read/written in order to clear the interrupt. This is a precautionary measurement, because a level sensitive interrupt that is not acknowledged can hang your PC.

To listen to PCI interrupts with the DriverWizard, follow these steps:

  • Define the interrupt-status register: In the DriverWizard’sRegisters tab, select New and define a new register. You should specify the register’s name, location (i.e., offset into one of the BARs), size, and access mode (read/write).
    The interrupt-acknowledgment information is hardware specific. You should therefore review your hardware’s specification for the relevant data to set for your specific device.

 

  • Assign the interrupt-status register to your card’s interrupt: After defining the interrupt-status register, go back to theInterrupts tab and assign the interrupt that you have defined to the card’s interrupt:
    Select your interrupt and click on the Edit button to display theInterrupt Information dialog box. Select the register you have defined from the drop-down list in the Access Register box. and fill-in the additional information required for acknowledging the interrupt — i.e., read/write mode and the data (if any) to be written to the status register in order to acknowledge and clear the interrupt. Beginning with version 5.2.0 of WinDriver, you can define several commands for execution upon an interrupt, by simply clicking the More button in the Interrupt Informationwindow.
    You should also verify that the interrupt is defined as Level Sensitive and that the Shared box is checked (PCI interrupts should generally be shared).

(This issue is also explained when clicking the Help button in theInterrupt Information dialog box.)

You can now try to listen to the interrupts on your card with the DriverWizard, by clicking the Listen to Interrupts button in theInterrupts tab, and then generating interrupts in the hardware. The interrupts that will be received will be logged in the Log window. To stop listening to the interrupts, click the Stop Listen to Interrupts button in the Interrupts tab.

For a detailed explanation regarding handling PCI interrupts with WinDriver, refer to the WinDriver PCI User’s Manual.

Back To Top

Technical Document #107: When performing data transfers with WD_UsbTransfer(), what is the significance of the USB_SHORT_TRANSFER and USB_FULL_TRANSFER flags (versions 5.0.4–5.2.2)?

These flags are available beginning with version 5.0.4 of WinDriver.

When the USB_SHORT_TRANSFER flag is set, then WD_UsbTransfer() will return on one of two occasions:

  1. A short packet (i.e., less than the maximum packet size) was transferred or the device transferred a zero (0) packet, to indicate a short transfer. In this case fOk will be TRUE.
  2. The time-out period (specified in usbTrans.dwTimeout) expired before a short packet was transferred (or a zero packet was received). In this case fOk will be FALSE.

When the USB_FULL_TRANSFER flag is set, then WD_UsbTransfer() will return on one of the following two occasions:

  1. The entire buffer (usbTrans.dwBytes) was filled/written. In this casefOk will be TRUE.
  2. The time-out period expired before the buffer was entirely filled/written. In this case fOk will be FALSE (although some data may very well have been transferred).

By default, the USB_SHORT_TRANSFER flag is set for bulk and interrupttransfers and the USB_FULL_TRANSFER flag is set for isochronous transfers.Control transfers are always short transfers.

In former versions of WinDriver (until, and including, v5.0.3),WD_UsbTransfer() behaved (for all types of transfers) as described above for the USB_SHORT_TRANSFER flag in v5.0.4 and above — i.e., the function always returned on one of two occasions:

  1. A short packet (i.e., less than the maximum packet size) was transferred or the device transferred a zero (0) packet, to indicate a short transfer — in which case fOK would have been TRUE (even if the buffer was not entirely filled/written).
  2. The time-out expired without any such transfer — in which casefOK would be FALSE.

Back To Top

Technical Document #109: I fail to use windrvr.vxd from WinDriver v5.0.5 on Windows 98; the Debug Monitor has this message: USB is not implemented on this OS. The windrvr.sys driver works well.

A USB device can only use a SYS driver. It cannot use a VxD driver. The reason for this is that USB devices must use WDM (Windows Driver Model) drivers, and WDM drivers should be implemented as SYS drivers. Therefore, windrvr6.vxd (or windrvr.vxd — in version 5.2.2 and earlier) does not support USB, and you should use the windrvr6.sysdriver file instead (windrvr.sys in version 5.2.2 and earlier).

NOTE: Beginning with version 6.2.0 of WinDriver, VxD drivers are no longer supported for any of the buses supported by WinDriver (including PCI/ISA).

Back To Top

Technical Document #110: When installing WinDriver v5.0.5 on my Linux machine, I get the following warning: Warning:loading /lib/modules/misc/windriver.o will taint the kernel: no license

This warning is due to a modification that now requires module authors to specify the Linux license under which the module was released. Beginning with version 5.2.0 WinDriver is registered as a propriety Linux driver. However, you might still receive a similar warning message. (You can take a look at http://lwn.net/2001/1025/a/module-license.php3 for more information). This message is not an indication of any actual error and you can therefore simply ignore it.

Back To Top

Technical Document #111: Distributing your WinDriver v5.2.x based driver to a target Windows machine

To distribute your WinDriver based driver to a target Windows machine (which does not have the WinDriver software installed), when usingversion 5.2.x of WinDriver, follow the instructions below and in the version 5.2.2 manual.

NOTE
For updated distribution instructions refer to Technical Document #132 and to the distribution chapter in the current WinDriver User’s Manual.
  1. Copy the windrvr.sys or windrvr.vxd driver file (depending on your OS) and your Kernel PlugIn driver (if you have created such a driver) to the target computer’s drivers directory — %windir%\system32\drivers — for SYS (e.g.,WINNT\system32\drivers); %windir%\system\vmm32 — for VxD. When copying the file/s, take care not to overwrite a newer version of the file with an older one. windrvr.sys and windrvr.vxd are found under theWinDriver\redist directory on the development machine.To install windrvr.sys on Windows 98/Me/2000/XP, also copywd_virtual.inf (found under the WinDriver\redist directory on the development machine) to the target machine. It is recommended to copy this file to the <WINDIR>\inf directory (WINNT\inf — on Windows 2k; Windows\inf — on Windows 98/Me/XP) to enable Windows to find and load this file automatically.
  2. Copy wdreg.exe or wdreg_gui.exe from the WinDriver\utildirectory on the development machine to the target machine.wdreg_gui.exe and wdreg.exe provide the same functionality. The difference is in the way the installation messages are displayed — graphical message boxes (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference towdreg.exe in the following instructions with wdreg_gui.exe if you wish.
  3. Install windrvr.sys/windrvr.vxd and wd_virtual.inf (on Windows 95/98/Me/2000/XP) using wdreg.exe:
  • To install windrvr.sys on Windows NT 4.0 or to installwindrvr.vxd on Windows 95/98/Me, use the installcommand:
        wdreg.exe install

On Windows 98/Me, add the -vxd flag:
         wdreg.exe -vxd install

It is recommended to run wdreg.exe with the removecommand before installing the new driver, in order to remove the existing WinDriver service (if it exists).

 

  • To install windrvr.sys on Windows 98/Me/2000/XP, use the reload command — which removes the current WinDriver service (if it exists), installs windrvr.sys and loads wd_virtual.inf:
        wdreg.exe -inf <full path to wd_virtual.inf> reloadFor example, if wd_virtual.inf has been copied toc:\WINNT\inf/:
        wdreg.exe -inf c:\WINNT\inf\wd_virtual.inf reloadNOTE: When upgrading from a previous version of WinDriver, if there are currently PCI/USB devices registered to work with WinDriver, when wdreg.exe is run on Win2k/XP, it will display a message instructing the user to either uninstall all devices registered to work with WinDriver and select Retry, or select Cancel and reboot, in order to complete the installation. Therefore, before installing the new driver it is recommended to uninstall (from the Device Manager) any PCI/USB devices that are currently registered to work with WinDriver (via an INF file).
    Alternatively, to avoid this message you can run wdreg.exewith the loadinf command, instead of the “reload” command, in order to install the new windrvr.sys andwd_virtual.inf files:
        wdreg.exe -inf <full path to wd_virtual.inf>loadinf
    Please note, however, that this will require a reboot in order to complete the installation.To complete the installation of windrvr.sys (andwd_virtual.inf) on Windows 98/Me you must alwaysreboot the PC, since dynamic loading of SYS drivers is not supported on Windows 98/Me.

4. If you have created your own Kernel PlugIn SYS/VxD driver, install your Kernel PlugIn driver using the wdreg.exe utility:
    wdreg.exe -name <Driver Name> install

If you have created a VxD Kernel PlugIn driver, add the -vxd flag to the installation command:
    wdreg.exe -vxd -name <Driver Name> install

NOTE

  1. Specify the driver name without the *.sys/*.vxdextension. For example, to install my_kp.sys on Windows 2000 run
        wdreg.exe -name my_kp install
  2. You must first install windrvr.sys/vxd (andwd_virtual.inf — when installing windrvr.sys on Windows 98/Me/2000/XP) before attempting to install your Kernel PlugIn driver.

5. For Plug-and-Play (PnP) devices — PCI/USB — if you are installing windrvr.sys on a target machine running a PnP operating system — Windows 98/Me/2000/XP — you      must also install the specific INF file for your device (generated with the DriverWizard on the development machine) in order to register your device to work with windrvr.sys.

On Windows 2000/XP you can use the loadinf option of thewdreg.exe utility in order to automatically install the INF file:
    wdreg.exe -inf <full path to INF file> loadinf

On Windows Me/98 you need to manually install the INF file from the Device Manager (using the Upgrade Device Driver Wizard:Properties –> Driver –> Upgrade Driver) or from Windows Add New Hardware Wizard — as explained in the “Distributing Your Driver” chapter of the WinDriver User’s Manual.

NOTE

  1. When upgrading from a previous version of WinDriver, before installing the new INF file, it is recommended to erase all backup INF files for any PCI/USB device that was previously registered to work with WinDriver, before installing the new INF file, in order to ensure that Windows does not install an old INF file your device, instead of the new file. (On Windows 2000/XP, look for the backup files in the%windir%/inf directory. On Windows 98/Me, look in the Windows\inf\other directory. Look for files containing the string “Jungo” and/or the vendor/device ID of your device/s and delete them. On Windows 2000/XP the files may be called “oem*.inf” (there will also be corresponding *.pnf files that you can erase or leave, as you wish). On Windows 98/Me the file names may begin with the string “Jungo”.)
  2. In previous versions of WinDriver (before v5.2.0) a separate driver file was used as the PnP driver (in addition to windrvr.sys) — wdpnp.sys and previously wdusb.sys. These drivers have become obsolete beginning with version 5.2.0 of WinDriver.

6. Copy your WinDriver executable/DLL file, which implements the driver functionality, to the directory of you choice on the target machine and run it.

Back To Top

Technical Document #113 Distributing your KernelDriver based driver to a target Windows machine (versions 5.2.x–6.1.x)

This technical document includes instructions on how to distribute your KernelDriver based driver to a target Windows machine.

NOTE
Distribution instructions for KernelDriver version 5.1.x — for USB on Windows NT 4.0 — can be found in Technical Document #114.

KernelDriver Version 6.1

Installing on Windows Target Computers — PCI/USB

This section refers to Windows 98/Me and Windows 2000/XP/Server 2003

The user must have administrative privileges on the target computer in order to install your driver.

  • Uninstalling old devices:
    To successfully disable/uninstall your driver, you must first close any open handles to <driver_file _name>.sys.
  • Installing your driver:
  1. Make sure your <your_driver>.sys and the specific INF file for your device driver are under the same directory.
  2. On Windows 2000/XP/Server 2003:
    Use the utility wdreg to install your driver on the target computer. From the command line type:
    \> wdreg -inf <full path to your driver's INF file> install

For example, if <your_driver>.inf is in the d:\MyDevice\directory on the target computer, the command should be:
\> wdreg -inf d:\MyDevice\<your_driver>.inf

You can find the executable of wdreg in the KernelDriver package under the \KernelDriver\util directory. For a general description of this utility and its usage, please refer to the KernelDriver User’s Manual.

3. On Windows 98/Me:
Install the INF file manually using the Windows Add New Hardware Wizard or Upgrade Device Driver Wizard, as outlined in detail in the Kernel Driver User’s Manual.

NOTE

  1. You must type the full path to the INF file when usingwdreg (even if wdreg is located in the same directory as the INF file).
  2. wdreg is an interactive utility. If it fails, it will display a message instructing the user how to overcome the problem. In some cases the user may be asked to reboot the computer.
  3. Remember: On Windows 98/Me/2000/XP/Server 2003, if you wish to upgrade your driver for PCI/USB devices, we recommend that you first delete any INF file(s) for these devices from Windows INF directory. See the KernelDriver User’s Manual for further explanations.

Installing on Windows Target Computers — ISA

This section refers to Windows 98/Me and Windows 2000/XP/Server 2003.

NOTE
The user must have administrative privileges on the target computer in order to install your driver.
  1. Copy the file <your_driver>.sys to the Windows installation directory on the target computer located at \<Windows Directory>\system32\drivers.
  2. Use the utility wdreg to add <your_driver>.sys to the list of device drivers Windows loads on boot. Use the following installation command:

\> wdreg -name <my_driver_name> install

You can find the executable of wdreg in the KernelDriver package under the \KernelDriver\util directory. For a general description of this utility and its usage, please refer to the KernelDriver User’s Manual.

Installing on Windows NT 4.0 Target Computers

NOTE
The user must have administrative privileges on the target computer in order to install your driver.
  1. Copy the file <your_driver>.sys to the Windows installation directory on the target computer located at \<Windows Directory>\system32\drivers.

2. Use the utility wdreg to add <your_driver>.sys to the list of device drivers Windows loads on boot. Use the following installation command:

   \> wdreg -name <my_driver_name> install

You can find the executable of wdreg in the KernelDriver package under the \KernelDriver\util directory. For a general description of this utility and its usage, please refer to the KernelDriver User’s Manual.

KernelDriver Version 5.2.x

    1. Copy the windrvr.sys or windrvr.vxd driver file (depending on your OS) and your SYS/VxD kernel driver to the target computer’s drivers directory — %windir%\system32\drivers for SYS (e.g., WINNT\system32\drivers); Windows\system\vmm32 for VxD.When copying the files, take care not to overwrite a newer version of the file with an older one.windrvr.sys and windrvr.vxd are found under theKernelDriver\redist directory on the development machine.When distributing the driver to a target Windows 98/Me/2000/XP machine, also copy wd_virtual.inf (found under the KernelDriver\redist directory on the development machine) and the INF file for your device (which you have created with the DriverWizard on the development machine) to the target machine. It is recommended to copy the files to the <WINDIR>\inf directory (WINNT\inf — on Windows 2k; Windows\inf — on Windows 98/Me/XP) to enable Windows to find and load the files automatically.
    2. Copy wdreg.exe or wdreg_gui.exe from the KernelDriver\utildirectory on the development machine to the target machine.wdreg_gui.exe and wdreg.exe provide the same functionality. The difference is in the way the installation messages are displayed graphical message boxes (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exein the following instructions with wdreg_gui.exe if you wish.
    3. If there is already another kernel driver installed for your device, first uninstall the current driver. If the existing driver was developed with version 5.0.5b or earlier of KernelDriver, or if it was developed with WinDriver’s Kernel PlugIn feature (described in the WinDriver User’s Manual), use the wdreg.exe utility with the “remove” command to stop and delete the existing service:
          wdreg.exe -name <driver name> remove
      (When removing a VxD driver, add the -vxd flag before the -nameflag.)
    4. Remove the existing windrvr.sys/windrvr.vxd service (if it exists) and install the new windrvr.sys/windrvr.vxd driver andwd_virtual.inf (on Windows 98/Me/2000/XP), using wdreg.exe:
  • To install windrvr.sys on Windows NT 4.0 orwindrvr.vxd on Windows 95/98/Me, use the removecommand to uninstall the existing service (if it exists) and then use the install command to install the new driver:
        wdreg.exe remove
    wdreg.exe install

On Windows 98/Me, add the -vxd flag (this flag is set automatically on Windows 95):
         wdreg.exe vxd remove
wdreg.exe vxd install

  • To install windrvr.sys on Windows 98/Me/2000/XP, use the reload command — which removes the current WinDriver service (if it exists), installs windrvr.sys and loadswd_virtual.inf:
        wdreg.exe -inf <full path to wd_virtual.inf> reloadFor example, if wd_virtual.inf has been copied toc:\WINNT\inf:
        wdreg.exe -inf c:\WINNT\inf\wd_virtual.inf reloadNOTE: When upgrading from a previous version of KernelDriver/WinDriver, if there are currently PCI/USB devices registered to work with windrvr.sys orwdpnp.sys/wdusb.sys (which were used in previous versions), when wdreg.exe is run on Win2k/XP, it will display a message instructing the user to either uninstall all devices registered to work with WinDriver and select Retry, or select Cancel and reboot, in order to complete the installation. Therefore, before installing the new driver it is recommended to uninstall (from the Device Manager) any PCI/USB devices that are currently registered to work with WinDriver (via an INF file).
    Alternatively, to avoid this message you can run wdreg.exewith the loadinf command, instead of the “reload” command, in order to install the new windrvr.sys andwd_virtual.inf files:
        wdreg.exe -inf <full path to wd_virtual.inf> loadinf Please note, however, that this will require a reboot in order to complete the installation.To complete the installation of windrvr.sys (andwd_virtual.inf) on Windows 98/Me you must alwaysreboot the PC, since dynamic loading of SYS drivers is not supported on Windows 98/Me.

5. Install your own SYS/VxD kernel driver (my_kd.sys/vxd):

  • To install my_kd.sys on Windows NT 4.0 or my_kd.vxdon Windows 95/98/Me, use the wdreg.exe utility:
        wdreg.exe -name <my_kd> install

When installing a VxD driver, add the vxd flag to the installation command (this flag is set automatically on Windows 95):
         wdreg.exe -vxd name <my_kd> install

NOTE: Specify the driver name without the *.sys/*.vxdextension.

  • To install my_kd.sys on Windows 98/Me/2000/XP, install the specific INF file for your device (generated with the DriverWizard on the development machine).On Windows 2000/XP you can use the loadinf option of the wdreg.exe utility in order to automatically install the INF file:
        wdreg.exe -inf <full path to INF file> loadinfOn Windows Me/98 you need to manually install the INF file from the Device Manager (using the Upgrade Device Driver Wizard: Properties --> Driver --> Upgrade Driver) or from Windows Add New Hardware Wizard, as explained in the driver distribution chapter of the KernelDriver User’s Manual.

    NOTE

  1. When upgrading from a previous version of KernelDriver/WinDriver, before installing the new INF file, it is recommended to erase all backup INF files for any PCI/USB device that was previously registered to work with WinDriver, before installing the new INF file, in order to ensure that Windows does not install an old INF file your device, instead of the new file. (On Windows 2000/XP, look for the backup files in the %windir%/inf directory. On Windows 98/Me, look in the Windows\inf\other directory. Look for files containing the string “Jungo” and/or the vendor/device ID of your device/s and delete them. On Windows 2000/XP the files may be called oem*.inf (there will also be corresponding *.pnf files that you can erase or leave, as you wish). On Windows 98/Me the file names may begin with the string “Jungo”.)
  2. In previous versions of KernelDriver/WinDriver (before v5.2.0) a separate driver file was used as the PnP driver (in addition to windrvr.sys) —wdpnp.sys and previously wdusb.sys. These drivers have become obsolete beginning with version 5.2.0 of KernelDriver/WinDriver.
NOTE
You must first install windrvr.sys/vxd (and wd_virtual.inf — when installing windrvr.sys on Windows 98/Me/2000/XP) before attempting to install your own kernel driver.

6. Copy your user mode executable/DLL file (if you have created one) to the directory of you choice on the target machine and run it.

Back To Top

Technical Document #115: How can I improve the rate of the interrupt handling when using DriverBuilder for VxWorks?

Beginning with version 5.2.2, WinDriver for VxWorks (a.k.a. DriverBuilder) implements a callback routine — windrvr_isr — which, if set by the user, is executed immediately when an interrupt is received, thus enabling you to speed up interrupt acknowledgment and processing.

WinDriver includes the following declaration of windrvr_isr:
int (__cdecl *windrvr_isr)(void);

To use the windrvr_isr callback routine, do the following:

  • Implement your interrupt handler routine:
    int __cdecl my_isr(void)
    {
    /* implenet your ISR */
    return TRUE; /* If TRUE, continue regular */
    /* WinDriver handling; */
    /* If FALSE, exit ISR. */
    }

 

  • Include the following declaration in your code:
    extern int (__cdecl *windrvr_isr)(void);

 

  • Set windrvr_isr to point to your interrupt handler routine, after calling drvrInit():
    windrvr_isr = my_isr;

Back To Top

Technical Document #116: WinDriver PCI/ISA API Version Changes

In general, we strive to keep the WinDriver API backward compatible, in the sense that code developed with an earlier version can be ported to a newer version by simply rebuilding the code with the new header files and a new license string. In most cases old code should work without changes (except for the license string update) with the headers and driver from a newer version. However, in some cases we decided there are compelling reasons that justify changes to existing APIs. This document outlines such changes to the WinDriver PCI APIs made in different versions of WinDriver, and guides you in porting your old code to use the updated APIs.

NOTE

  • Generic “PCI” references in this document include also PCI-Express, PCMCIA, and ISA.
  • This document is specific to the WinDriver PCI APIs. For WinDriver USB APIs upgrade information, refer to Technical Document #117.
  • This document is specific to required code updates in light changes to older API versions.
    We strongly recommend that you make additional code updates to utilize relevant API additions and enhancements that may have been made in the newer versions of WinDriver, as outlined in the WinDriver release notes and documented in the WinDriver PCI User’s Manual of the new version.
    For full instructions on how to upgrade to a newer WinDriver version, refer to Technical Document #84.

Read the API changes information for all WinDriver versions that are newer from your current version:

WinDriver v11.8.0 PCI API Changes

In v11.8.0 we made the following changes to the WinDriver WDC PCI API and to the low-level WinDriver PCI API that it uses; the main purpose of these changes was to improve the support for 64-bit PCI addresses:

    • include/wdc_defs.h WDC type changes —
      • WDC_ADDR_DESC struct —
        • The kptAddr field was renamed to pAddr.
        • The dwBytes field was renamed to qwBytes, and its type changed from DWORD to UINT64.
        • The dwUserDirectMemAddress field was renamed topUserDirectMemAddr.

 

  • include/windrvr.h low-level WinDriver type changes —
    • WD_TRANSFER struct changes —
      NOTE
      The WD API references this type, as well as theWD_INTERRUPT struct type — which has a Cmd field of type WD_TRANSFER*.
      • The dwPort field was renamed to pPort.

 

    • WD_ITEMS struct changes —
      NOTE
      The WDC API references the WD_CARD struct — which has an Item field that is an array of WD_ITEMS structs — and the WD_CARD_REGISTER struct — which has a Cardfield of type WD_CARD.
        • The dwOptions field was replaced with anI.Mem.dwOptions field.
        • I.Mem union struct field changes —
          • The dwPhysicalAddr field was renamed topPhysicalAddr, and its type changed fromDWORD to PHYS_ADDR.
          • The dwBytes field was renamed to qwBytes, and its type changed from DWORD to UINT64.
          • The dwTransAddr field was renamed topTransAddr.
          • The dwUserDirectAddress field was renamed topUserDirectAddr.
          • The reserved dwCpuPhysicalAddr field wasremoved.
          • A new pReserved field was added.
        • The I.Mem64 union struct field was removed.
        • I.IO union struct field changes —
          • The dwAddr field was renamed to pAddr.
        • I.Int union struct field changes —
          • New dwReserved1 and pReserved2 fields were added.
      • The I.Val union struct field was removed.

 

    • WD_ITEM_OPTIONS enum — the type was renamed toWD_ITEM_MEM_OPTIONS, and its WD_ITEM_XXX enum values were renamed to WD_ITEM_MEM_XXX.
      NOTE
      The WD_ITEMS struct’s I.Mem.dwOptionsfield (previously the dwOptions field) receives values of this enum type.

 

  • The ITEM_TYPE enum’s ITEM_MEMORY_64BIT enum value wasremoved.

Back To Top

Technical Document #117: WinDriver USB API Version Changes

In general, we strive to keep the WinDriver API backward compatible, in the sense that code developed with an earlier version can be ported to a newer version by simply rebuilding the code with the new header files and a new license string. In most cases old code should work without changes (except for the license string update) with the headers and driver from a newer version. However, in some cases we decided there are compelling reasons that justify changes to existing APIs. This document outlines such changes to the WinDriver USB APIs made in different versions of WinDriver, and guides you in porting your old code to use the updated APIs.

NOTE

  • This document is specific to the WinDriver USB API. For WinDriver PCI/ISA API upgrade information, refer to Technical Document #116.
  • This document is specific to required code updates in light changes to older API versions.
    We strongly recommend that you make additional code updates to utilize relevant API additions and enhancements that may have been made in the newer versions of WinDriver, as outlined in the WinDriver release notes and documented in the WinDriver User’s Manual of the new version.
    For full instructions on how to upgrade to a newer WinDriver version, refer to Technical Document #84.

Read the API changes information for all WinDriver versions that are newer from your current version:

WinDriver v6.0.0 USB API Changes

In v6.0.0 we completely replaced the WD_xxx WinDriver USB API with a new WDU_xxx API, in order to support event-driven transfers between your user-mode USB application and USB devices (in contrast to earlier versions, in which USB devices were initialized and controlled using a specific sequence of function calls).
When upgrading from v5.2.2 or earlier of WinDriver, you will need to change your code to use the WDU APIs. Refer to the updated API reference in the WinDriver USB User’s Manual of the new version.

Back To Top

Technical Document #118: I tried to generate Delphi code for my USB device with the DriverWizard from version 6.0.0 of WinDriver, but it seems that not all the relevant files are generated?

In version 6.0.0 of WinDriver we have modified the USB API in order to improve the support for this bus. The DriverWizard from versions 6.0.0 and 6.0.1 does not support code generation in Delphi (Pascal) for the new USB API. Due to a bug in the wizard from v6.0.0, the Delphi code generation option for USB was not disabled. This was fixed in v6.0.1 of WinDriver.
Note that the old USB API, for which you could generate Delphi code with older versions of WinDriver, is still supported by the driver of the newer versions, for backward compatibility.
Beginning with v6.0.2 of WinDriver, DriverWizard can be used to generate Delphi code that utilizes the new USB API.

Back To Top

Technical Document #119: I used the DriverWizard from version 6.0.0 of WinDriver to generate Visual Basic code for my USB device, but while WDU_Transfer() works correctly, the specific transfer functions — WDU_TransferBulk(), etc. — are not working as expected.

There was a mistake in the Visual Basic (VB) function declarations for the specific WDU_TransferXXX() functions in WinDriver\vb\include\wd_utils.cls, which explains the problem that you encountered. In addition, this file contained two redundant function declarations (WDU_GetDescriptor — which does not exist, and WDU_GetDeviceData — which is a lower level function that is not implemented for VB, and is not generally required).
To resolve these problems, either upgrade to version 6.0.1 (or newer) of WinDriver or download the following modified file from v6.0.1 of WinDriver: wd_utils.cls and copy it to the WinDriver\vb\include directory in place of the file from the original v6.0.0 distribution.

Back To Top

Technical Document #120: Distributing your WinDriver-based driver to a target Windows PC — WinDriver Version 8.1.x–11.8.0

This document outlines the basic steps for installing a driver developed with versions 8.1.x–11.8.0 of WinDriver on a target Windows PC. Detailed driver distribution instructions can be found in the WinDriver User’s Manual for your WinDriver version.

The Windows driver distribution steps for version 11.9.0 and newer of WinDriver are outlined in Technical Document #132.
The Windows driver distribution steps for version 8.0.x of WinDriver are outlined in Technical Document #130.

This document includes

Documentation Notes:

  • All OS references in this document are applicable only to WinDriver versions that officially support these operating systems (refer to Technical Document #4 for the list of operating systems supported by the latest WinDriver version).

For example, references to Windows 98/Me (and the relatedwdreg16.exe utility) are applicable only to version 9.2.0 and below of WinDriver.

 

  • The windrvr6.sys, windrvr6.inf, and wd<version>.cat files, mentioned in this document, can be found in the WinDriver\redistdirectory on the development PC. wdreg.exe / wdreg_gui.exe / wdreg16.exe and difxapi.dll (v8.1.1+) can be found in theWinDriver\util directory. (The source code of the wdreg utility is found in the WinDriver\samples\wdreg directory.)

 

  • Beginning with version 8.0.0 of WinDriver you can rename the WinDriver driver module (windrvr6.sys) and the related INF file (windrvr6.inf). You can also submit the driver for Windows certification or have it Authenticode signed yourself, using your own WinDriver catalog file (xxx.cat), as explained in the WinDriver User’s Manual. If you have selected to rename any of the provided WinDriver files, replace the references to these files in the present document with the names of your new files.

 

  • The wdreg.exe and wdreg_gui.exe utilities provide the same functionality. The difference is in the way the installation messages are displayed — graphical messages (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exe in the following instructions with wdreg_gui.exe.
    When installing windrvr6.sys on Windows 98/Me, you instructions with wdreg_gui.exe.
    Beginning with version 8.1.1 of WinDriver, the wdreg utility is dependent on the difxapi.dll DLL.

Installation Notes:

  • You must have administrative privileges in order to install drivers on Windows.

 

  • When distributing your driver, take care not to overwrite a newer version of the driver file — windrvr6.sys or a renamed driver — with an older version of this file.
    The provided windrvr6.inf file uses theCOPYFLG_NO_VERSION_DIALOG directive, which is designed to avoid overwriting a file in the destination directory with the source file if the existing file is newer than the source file. There is also a similarCOPYFLG_OVERWRITE_OLDER_ONLY INF directive that is designed to ensure that the source file is copied to the destination directory only if the destination file is superseded by a newer version. Note, however, that both of these INF directives are irrelevant to digitally signed drivers. As explained in the Microsoft INF CopyFiles Directive documentation, if a driver package is digitally signed, Windows installs the package as a whole and does not selectively omit files in the package based on other versions already present on the computer. The windrvr6.sys driver in the newer WinDriver versions is digitally signed with an Authenticode signature (refer to the WinDriver User’s Manual for more information on driver signature and certification).

 

  • If you wish to distribute drivers for both 32-bit and 64-bit target platforms, you must prepare a separate driver installation package for each platform.

 

  • When upgrading the driver from a previous version of WinDriver that also uses the windrvr6.sys driver module (v6.0.0 and above), make sure that there are no open handles to the old WinDriver service (windrvr6.sys or your renamed driver), and that there are no connected and enabled Plug-and-Play devices that are registered with this service. This includes closing any applications that may be using the driver; uninstalling your oldKernel PlugIn driver (if you had created such a driver):
    \> wdreg -name OLD_KP uninstall
    and either disabling, uninstalling, or physically disconnecting any device that is registered to work with the WinDriver service.

 

  • On Windows 2000, remove any INF file(s) previously installed for your Plug-and-Play device (such as files created with an earlier version of WinDriver) from the %windir%\inf directory, before installing the new INF file that you created for the device. This will prevent Windows from automatically detecting and installing an obsolete file. You can search the INF directory for the device’s vendor ID and device/product ID to locate the file(s) associated with the device (see Technical Document #49 for additional information).

Installation Steps:

NOTE: For Windows 98/Me, replace the references to wdreg.exebelow with wdreg16.exe.

1.Copy windrvr6.sys, windrvr6.inf, and wd<version>.cat to the same directory.

NOTE:

  • If you select to copy wd<version>.cat to a different location you will need to modify the CatalogFile entry in the windrvr6.inf file to point to the location of the catalog file.
  • You can also select not to distribute the wd<version>.catcatalog file, in which case you need to remove or comment-out the CatalogFile line in the windrvr6.inf file. However, note that if you do so the installation will not utilize the driver’s Authenticode digital signature (see the WinDriver User’s Manual for more information).

 

2. Use the utility wdreg.exe to install WinDriver’s kernel module on the target computer:
\> wdreg -inf <path to windrvr6.inf> install

NOTE: Remember that wdreg requires the difxapi.dll DLL (v8.1.1+).

TIP: If you copy wdreg.exe and difxapi.dll to the same directory as windrvr6.sys and windrvr6.inf, you can simply run the following command from your installation directory in order to install the driver:
install_dir:] wdreg -inf windrvr6.inf install

    1. If you have created a Kernel PlugIn driver (e.g., my_kp.sys), copy this driver to Windows drivers directory —%windir%\system32\drivers — and install it using the wdreg.exeutility:
      \> wdreg -name MY_KP install
      NOTE: The driver name is indicated without the *.sys extension.

 

3. On Windows 98/Me, reboot the PC to complete the driver installation.

 

4. For Plug-and-Play devices (PCI/USB): install the device INF file, which registers your device to work with the windrvr6.sys service (normally this file is created using WinDriver’s DriverWizard utility).

On Windows 2000 and higher, you can use the wdreg.exe utility with the install command to automatically install the INF file:
\> wdreg -inf <path to device.inf> install
You can also use the preinstall wdreg.exe command to pre-install an INF file for a device that is not currently connected to the PC:
\> wdreg -inf <path to device.inf> preinstall

On Windows 98/Me, install the device INF file manually, using Windows’ Update Driver wizard (from the Device Manager) or New Hardware Wizard, as explained in the instructions that will be displayed when generating the file with DriverWizard, and in the WinDriver User’s Manual for the relevant WinDriver version. Alternatively, copy the INF file to Windows’ INF directory
(%windir%\inf) and reboot to let Windows locate and install the file.

 

5. If your project uses the wdapi<version>.lib library (for examplewdapi900.lib) — as is the case for the sample and generated DriverWizard projects — you need to distribute the wdapi DLL:

  • When distributing 32-bit applications/DLLs to 32-bit targetsOR when distributing 64-bit applications/DLLs to 64-bit targets: Copy WinDriver\redist\wdapi<version>.dll (e.g.,wdapi900.dll) to the target’s %windir%\system32directory.

NOTE: If you attempt to copy the 64-bit DLL to the %windir%\system32 directory using a 32-bit installation program, you may find that the DLL file is actually copied to the 32-bit %windir%\sysWOW64 directory. The reason for this is that Windows x64 platforms translate references to 64-bit directories from 32-bit commands into references to 32-bit directories. You can avoid the problem by using 64-bit commands to perform the necessary installation steps from your 32-bit installation program. The system64.exeprogram, provided in the WinDriver\redist directory of the Windows x64 WinDriver distributions, enables you to do this.

 

  • When distributing 32-bit applications to 64-bit targets: Rename the file WinDriver\redist\wdapi<version>_32.dllto wdapi<version>.dll (for example, renamewdapi900_32.dll to wdapi900.dll) and copy the renamed file to the target’s %windir%\sysWOW64 directory.

 

6. Copy your hardware-control application/DLL to the target and run it!

Back To Top

Technical Document #124: When trying to intsall WinDriver on my Windows PC I got the following error: 16-bit MS-DOS Subsystem path to the program that you are trying to start or install C:\Winnt\System32\autoexec.nt The system file is not suitable for running MS-DOS and Microsoft Windows applications.

Follow the instructions at http://support.microsoft.com/default.aspx?scid=kb;en-us;324767 to acquire/repair autoexec.nt. Note that instead of expanding the file from the OS installation CD, you can also copy it from the %windir%\repairdirectory.

This error should not occur with newer versions of WinDriver (later than v6.2.3). If you encounter this problem with such newer versions, notify Jungo Connectivity’s support. .

Back To Top

Technical Document #127: WinDriver Upgrade: Version 6.2.x -> Version 7.x and above

This document outlines the steps for upgrading from version 6.2.x to version 7.x or newer of WinDriver.
If you are upgrading from version 8.1.1 or newer, refer to Technical Document #84 instead.
If you are upgrading from version 7.x, refer to Technical Document #131.

 

Upgrade Steps

  1. Install the new version
  2. Acquire a New WinDriver License (Registered Users)
  3. Upgrade Your Driver Project
  4. Upgrade Your Device INF File (Windows)
  5. Digitally Sign Your Driver Files (Windows)
  6. Upgrade Your Driver Distribution/Installation Package

 

  • Install the new version

Download and install a new version of WinDriver that matches your development platform and the operating systems and CPU configurations of the target platforms on which you intend the driver to be used.

  • Acquire a New WinDriver License (Registered Users)

If you are using a registered version of WinDriver, contact Jungo Connectivity at [email protected] to acquire a WinDriver license registration string for the new version. Then register the new license from DriverWizard (File | Register WinDriver) and from your code.

Note that if you have a valid Support and Upgrade plan you are are entitled to receive a new license free of charge.
If you do not have such a plan, contact [email protected] to request a temporary license that will allow you to evaluate the new version.

  • Upgrade Your Driver Project
      • Register Your New License (Registered Users): Modify the driver code to register your new license — i.e., replace the license string in the call to WDU_Init() (USB) /WDC_DriverOpen() (PCI/ISA — WDC API) / WD_License()(low-level API) from your code.PCI users — if you created a Kernel PlugIn driver, make sure to also update the license string in your Kernel PlugIncode.
      • PCI/ISA users — refer to Technical Document #116 for information on API changes done in v11.8.0 of WinDriver, and edit your code accordingly.

 

      • WinDriver-API DLL/shared object upgrade — Linking your projects with the high-level WinDriver-API DLL/shared object — wdapi<version> (v8.x+) / wd_utils (v7.x) — frees you of the need to include the source files from theWinDriver/src/wdapi directory (v8.x+) / WinDriver/srcdirectory (v7.x) in your project (see also note below).In v8.0.0 the name of the DLL/shared object module was changed from wd_utils to wdapi<version> (e.g.,wdapi800 in v8.0.0) as part of the addition of versioning support to this module. This enables you to upgrade your driver, including the DLL/shared object, without worrying about the possible effects on other drivers, developed with earlier versions of WinDriver, which may be using the same module.On Windows and Windows CE, in v8.x and newer, you can use the WDAPI DLL — wdapi<version>.dll (found in the WinDriver\redist directory) by linking your project with the WinDriver\lib\<CPU>\wdapi<version>.lib library (e.g.,WinDriver\lib\x86\wdapi800.lib) — for MS Visual Studio(Visual C++) projects; or with theWinDriver\lib\<CPU>\wdapi_borland<version>.lib library (e.g., WinDriver\lib\x86\wdapi_borland800.lib) — for Windows Borland C++ Builder projects (in v11.1.0 and below).On Linux and Solaris (Solaris was supported until 9.0.1), in v8.x and newer you can use libwdapi<version>.so by linking your driver project withWinDriver/lib/libwdapi<version>.so (e.g.,libwdapi800.so in WinDriver v8.0.0).
        To link your Linux project with this shared object, addwdapi<version> to the makefile’s link flag (LFLAGS += -l wdapi<version>; e.g., LFLAGS += -l wdap800), instead of listing all the source files from theWinDriver/src/wdapi directory (previously WinDriver/src/ — see below) in the makefile (under the SRCS flag).On all platforms, the sample and generated DriverWizard projects demonstrate how to correctly link the project with the relevant DLL/shared object for your WinDriver version and target OS.Note that if your code uses the high-level WinDriver-API DLL / shared object, you will need to distributewdapi<version>.dll (v8.x+) / wd_utils.dll (v7.x) — for Windows and Windows CE, or wdapi<version>.so (v8.x+) / libwd_utils.so (v7.x) — for Linux and Solaris, with your driver, as explained in the driver distribution instructions of the new WinDriver User’s Manual.
      • WinDriver source files location changes — In v8.0.0the WinDriver C source files were moved from theWinDriver/src directory to the WinDriver/src/wdapi/directory. The .NET source files were moved from theWinDriver/wdapi.net/ directory to theWinDriver/src/wdapi.net/ directory.
        If you have selected to upgrade your v6.2.x project to use the wdapi (v8.x+) or wd_utils (v7.x) DLL/shared object (see above), this should not normally affect you. However, if your project directly includes WinDriver source files, you may need to modify your project/make file to point to the new source files location.

 

      • Update your project’s files search paths: Beginning with v7.0.1, the include path in the WinDriver project/make files contains the path to the WinDriver/ andWinDriver/include/ directories, and the #include statements in the WinDriver source files and generated DriverWizard code were consequently modified to indicate only the name of the header file to include, instead of the full/relative path to the file (as done in earlier versions).In light of these changes, when rebuilding a driver project from v7.0.0 or earlier of WinDriver with the source files from v7.0.1 or newer, you may need to modify your project/make file and add the path to the WinDriver/ andWinDriver/include/ directories to the project’s include path in order to successfully build the project.
      • For USB, beginning with v7.0.0 of WinDriver, if you have created a console driver application/DLL/shared object that calls functions implemented inWinDriver/samples/shared/usb_diag_lib.c (as is the case for the sample and generated WinDriver USB diagnostic driver projects), to build your project with theusb_diag_lib.c file from the new version you must add the new WinDriver/samples/shared/diag_lib.c file to your project.

 

      • For PCI/ISA users, beginning with v7.0.0 WinDriver features the new WDC library, which provides convenient wrapper APIs to the standard WinDriver PCI/ISA APIs. (This library is part of the wdapi<version> (v8.x+) / wd_utils(v7.x) DLL / shared object (see above; the source files are found under the WinDriver/src/wdapi directory (v8.x+) /WinDriver/src directory (v7.x) (see note above).The WDC APIs are documented in the v7.x+ WinDriver PCI User’s Manual. The generated DriverWizard v7.x+ projects use the WDC APIs instead of the low-level WD_xxx APIs. The WDC APIs are also used from the v7.x+ pci_diag,pcmcia_diag, pci_dump and PLX samples.Since WDC mainly provides wrappers to the standard WinDriver APIs, which are still supported, you do not need to modify your old code to use the new WDC library. Should you select to upgrade your code to use the WDC APIs, you can examine the new samples and generated code and compare them to those from your old WinDriver version for a better understanding of how to use the new APIs.Note that to use the WDC APIs you will need to either include the relevant wdc_xxx.c source files from theWinDriver/src/wdapi directory (v8.x+) / WinDriver/srcdirectory (v7.x) in your project/makefile; or link your project with the wdapi<version> (v8.x+) / wd_utils (v7.x)WinDriver high-level API DLL/shared object.
      • 64-bit OS upgrade (Windows and Linux)
          • When developing a driver for a 64-bit platform, your project or makefile must include the KERNEL_64BITpreprocessor definition. In the makefiles, the definition is added using the -D flag: -DKERNEL_64BIT. The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects in the 64-bit WinDriver toolkit already add this definition.
        • PCI Kernel PlugIn upgrade from v10.2.1- — to support execution of 32-bit applications with a 64-bitKernel PlugIn driver, follow the instructions inTechnical Document #112.

 

      • Rename your driver (Windows and Linux) — To avoid conflicts with other WinDriver-based drivers on the target platforms, we highly recommend that you rename the default WinDriver driver module — windrvr<version>.sys(e.g., windrvr1200.sys) on Windows /windrvr<version>.o/.ko (e.g., windrvr1200.o/.ko) onLinux (or windrvr6.sys / windrvr6.o/.ko in v11.8.0 and older) — to a unique name, by following the instructions in the new WinDriver User’s Manual. The renaming procedure is simple and quick.
        The Linux USB GPL driverwindrvr<version>_usb.o/.ko (or windrvr6_usb.o/.koin v11.8.0 and older) is automatically renamed when renaming the main WinDriver Linux driver.
        When creating a PCI Kernel PlugIn driver, select a unique name as well.

 

      • Ensure that your code uses the correct driver module— Verify that the call to WD_DriverName() in your driver code (if exists) uses the new driver-module name —windrvr<version> (or windrvr6 in v11.8.0 and below) or your renamed version of this driver.
        In version 11.9.0 of WinDriver the default WinDriver driver-module name changed from windrvr6 towindrvr<version> (e.g., windrvr1200 in v12.0.0). Consequently, when using the default driver-module name old projects need to be updated to use the default name from the newer version. If you use the generated DriverWizard code or one of the samples from the new WinDriver version, the code will already use the default driver name from the new version. Also, if your code is based on generated/sample code from an earlier version of WinDriver, rebuilding the code with windrvr.h from the new version is sufficient to update the code to use the new default driver-module name (due to the use of theWD_DEFAULT_DRIVER_NAME_BASE definition).
        If you elect to rename the WinDriver driver module, ensure that your code calls WD_DriverName() with your custom driver name. If you rename the driver from the new version to a name already used in your old project, you do not need to modify your code.

        NOTE
        To apply a driver name change — whether using the default driver name or a custom name — your user-mode driver project must be built with theWD_DRIVER_NAME_CHANGE preprocessor flag (e.g., -DWD_DRIVER_NAME_CHANGE), as explained in the WinDriver WinDriver User’s Manuals and demonstrated in the sample and generated DriverWizard WinDriver projects/makefiles.

 

      • Rebuild your updated driver project with the source files from the new version.PCI users who created a Kernel PlugIn driver must rebuild it with the files from the new version as well.

  • Upgrade Your Device INF File (Windows)

On Windows, if you have created a driver for a Plug-and-Play device (USB/PCI/CardBus/PCMCIA), we recommend that you create and install a new INF file for your device, which registers it with the driver module from the new version —windrvr<version>.sys (e.g., windrvr1200.sys) /windrvr6.sys in v11.8.0 and older — or your renamed version of this driver (in v9.x and newer). You can use DriverWizard from the new version to generate the new INF file, or change the driver version in your old INF file.

  • Digitally Sign Your Driver Files (Windows)
    1. Digitally Sign Your Driver Files (Windows) On 64-bit versions ofWindows Vista and higher, Microsoft requires that kernel drivers be digitally signed. Therefore, if you use any of the following driver files you must digitally sign them: A renamed version of the WinDriver kernel driver (the default WinDriver driver —windrvr<version>.sys / windrvr6.sys in v11.8.0 and older — is already digitally signed), a Plug-and-Play device INF file, and/or a PCI Kernel PlugIn driver. You can bypass this restriction during the development stage (e.g., on Windows 7, by pressing F8 at boot time and selecting the relevant option), but the driver files must be signed before distribution. There are also advantages to signing your driver on other Windows OSs. For more information, refer to Micorsoft’s Driver Signing Policy and to the Windows Digital Driver Signing and Certification section of the WinDriver User’s Manuals.You can obtain digital signatures from third-party companies such as DigiCert or Symantec, or use Jungo Connectivity’s digital driver signing service. Jungo Connectivity can also assist you in preparing your driver for Microsoft’s Windows cetification.

  • Upgrade Your Driver Distribution/Installation Package

Create a new driver installation package, which contains the following files from the new WinDriver distribution:

      • The WinDriver driver module —windrvr<version>.sys/.o/.ko/.dll (e.g.,windrvr1200.sys/.o/.ko/.dll) in the newer WinDriver versions, or a renamed version of this driver
      • The WinDriver Linux USB GPL driverwindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) in the newer WinDriver versions, or a renamed version of this driver
      • Your rebuilt PCI Kernel PlugIn driver —<KP_driver_name>.sys (if created)
      • Any other files required for installing or using your driver — such as wdapi<new_version>.dll/.so,wdreg[.exe]/wdreg_gui.exe (and difxapi.dll on Windows), and Windows INF and catalog files
      • An installation program that installs the new driver

Hardware- and OS-specific driver distribution instructions can be found in the Distributing Your Driver chapter of the user manuals from the new version. The instructions for Windows are also summarized in Technical Document #132 (v8.1.x and newer) /Technical Document #130 (v8.0.x).

Version-Specific Installation Upgrade Notes:

      • Linux USB upgrade to v10.0.0+ — the WinDriver USB Linux GPL driver: Beginning with v10.0.0, the WinDriver Linux USB driver was split into two modules, which are used together to provide the full driver functionality:
        • windrvr6.o/.ko, renamed in v11.9.0 towindrvr<version>.o/.ko (e.g.,windrvr1200.o/.ko) — the traditional WinDriver driver module, which includes the product license.
        • windrvr6_usb.o/.ko, renamed in v11.9.0 towindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) — this driver implements Linux-specific USB driver functionality, and contains a GNU General Public License (GPL).

 

      • Windows upgrade to v8.1.1+ — WDREG difxapi.dlldependency: Beginning with v8.1.1, the wdreginstallation utility uses the Driver Install Frameworks API (DIFxAPI) to perform driver installation and uninstallation. As a result, the wdreg utility in v8.1.1 and newer is dependent on the difxapi.dll DLL, which is provided under the WinDriver\util directory. This DLL must therefore be inwdreg‘s search path when using the utility to install /

 

    • Windows upgrade to v8.1.0+ — the wd<version>.catWinDriver catalog file: Beginning with v8.1.0, the WinDriver driver (windrvr<version>.sys / windrvr6.sysin v11.8.0 and older) has an Authenticode digital signature. To enjoy the advantages of this signature thewd<version>.cat catalog file, provided under theWinDriver\redist directory, needs to be distributed together with the related INF file (windrvr<version>.inf /windrvr6.inf in v11.8.0 and older), which is used to install the driver. For more information, refer to the WinDriver User’s Manuals of the new WinDriver version and to Technical Document #132.

Back To Top

Technical Document #128: Does WinDriver support development of drivers for the .NET framework?

Yes. WinDriver can be used to develop .NET Windows drivers in your preferred .NET development language.

The WinDriver .NET API DLLwdapi<version>_dotnet.dll (e.g.,wdapi800_dotnet.dll in WinDriver v8.0.0) provides a .NET version of the high-level WinDriver APIs, implemented using managed extensions for C++. This DLL is found under the WinDriver\lib\<CPU>\<.NET version> directory (e.g., WinDriver\lib\x86\v1.1.4322) and its source code is found under the relevant WinDriver\src\wdapi.net directory.

v7.0.x Note: In v8.0.0 of WinDriver we added both versioning and 64-bit support to the DLL, which resulted in a different DLL name and new locations for the related files. In versions 7.0.1 and 7.0.2 of WinDriver the name of the DLL was wdapi_dotnet and it could be found both under the WinDriver\lib and WinDriver\redist directories. The DLL source code in these versions was found under the WinDriver\wdapi.net directory.

Beginning with v8.0.0 of WinDriver you can use WinDriver’s DriverWizard utility to generate driver code in C# (USB and PCI) and VB.NET (USB).

WinDriver also includes .NET samples that use the WinDriver .NET API DLL:

  • USB:
    • The WinDriver\csharp.net\usb_sample directory contains a .NET USB library (usb_lib_dotnet.dll) and a sample USB diagnostics application (csharp_usb_sample.exe), both implemented in C#.
    • The WinDriver\vb.net\usb_sample directory contains a sample .NET USB diagnostics application (vb_usb_sample.exe), implemented in VB.NET. This sample is similar to the sample C# USB diagnostics application and also uses the sample C# USB library (usb_lib_dotnet.dll).
  • PCI:
      • The WinDriver\csharp.net\pci_sample directory contains a .NET PCI library (pci_lib.dll) and a sample PCI diagnostics application (pci_sample.exe), both implemented in C#.
      • The WinDriver\plx\dotnet directory contains a C# library (plx_lib_dotnet.dll) and sample diagnostics application (PLX_Sample.exe), designed specifically for handling PLXdevices.

To develop a .NET driver with WinDriver, either use DriverWizard to generate a diagnostics .NET driver application for your device, or use the WinDriver .NET sample that most matches your design, and then modify the generated/sample code in accordance with your hardware specification and desired driver functionality. Alternatively, you can use the generated/sample code as a reference for writing your own WinDriver .NET driver.

Back To Top

Technical Document #130: Distributing your WinDriver-based driver to a target Windows PC — WinDriver version 8.0.x

This document outlines the basic steps for installing a driver developed with version 8.0.x of WinDriver on a target Plug-and-Play Windows operating system. Detailed driver distribution instructions can be found in the WinDriver User’s Manual for your WinDriver version.

The Windows driver distribution steps for version 11.9.0 and newer of WinDriver are outlined in Technical Document #132.
The Windows driver distribution steps for versions 8.1.x–11.8.0 of WinDriver are outlined in Technical Document #120.

 

Documentation Notes:

  • The windrvr6.sys and windrvr6.inf files, mentioned in this document, can be found in the WinDriver\redist directory on the development PC. wdreg.exe / wdreg_gui.exe / wdreg16.execan be found in the WinDriver\util directory (the source code is found in the WinDriver\samples\wdreg directory).

 

  • The wdreg.exe and wdreg_gui.exe utilities provide the same functionality. The difference is in the way the installation messages are displayed — graphical messages (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exe in the following instructions with wdreg_gui.exe.
    When installing windrvr6.sys on Windows 98/Me, you should use the wdreg16.exe utility.

Installation Notes:

  • You must have administrative privileges in order to install drivers on Windows.

 

  • When distributing your driver, take care not to overwrite a newer version of windrvr6.sys with an older version of this driver.

 

  • When upgrading the driver from a previous version of WinDriver, which also uses the windrvr6.sys driver module (v6.0.0 and above):
    • If you have also created a Kernel PlugIn driver (e.g.,old_kp.sys), remove this driver before proceeding with the installation:To remove old_kp.sys, run:
      \> wdreg -name OLD_KP uninstall
    • For a reboot-free installation of the new driver, verify that there are no open handles to the windrvr6.sys service. This includes verifying that there are no open applications that use this service and that there are no connected Plug-and-Play (PCI/USB) devices that are registered to work with it via an INF file (on Windows 98/Me/2000/XP/Server 2003). Otherwise, the installation might instruct the user to either uninstall all devices currently registered to work with WinDriver and Retry, or Cancel and reboot the PC in order to successfully complete the installation of the new driver.

 

 

  • On Windows 2000 it is recommended that you remove any INF file(s) previously installed for your Plug-and-Play device(PCI/USB), such as files created with an earlier version of WinDriver, from the %windir%\inf directory. This will ensure that Windows will not automatically detect and install an old INF file for your device.
    You can search the INF directory for the devices vendor ID and device/product ID to locate the file(s) associated with the device.
    For more information regarding the Windows 2000 INF selection algorithm, refer to Technical Document #49.

Windows 98/Me/2000/XP/Server 2003 Installation Steps:

NOTE: For Windows 98/Me, replace the references to wdreg.exebelow with wdreg16.exe.

1.Copy windrvr6.sys and windrvr6.inf to the same directory.

 

2. Use the utility wdreg.exe to install WinDriver’s kernel module on the target computer:
\> wdreg -inf <path to windrvr6.inf> install

TIP: If you copy wdreg.exe to the same directory aswindrvr6.sys and windrvr6.inf, you can simply run the following command from your installation directory in order to install the driver:
install_dir:] wdreg -inf windrvr6.inf install

 

3. If you have created a Kernel PlugIn (e.g., my_kp.sys), copy this driver to Windows drivers directory — %windir%\system32\drivers— and install it using the wdreg.exe utility:
\> wdreg -name MY_KP install

NOTE: The driver name is indicated without the *.sys extension.

 

4. On Windows 98/Me, reboot the PC to complete the driver installation.

 

5. For Plug-and-Play devices (PCI/USB): install the device INF file, which registers your device to work with the windrvr6.sys service (normally this file is created using WinDriver’s DriverWizard utility).

On Windows 2000/XP/Server 2003, you can use the wdreg.exeutility with the install command to automatically install the INF file:
\> wdreg -inf <path to device.inf> install

On Windows 98/Me, install the device INF file manually, using Windows’ Update Driver wizard (from the Device Manager) or New Hardware Wizard, as explained in the instructions that will be displayed when generating the file with DriverWizard, and in the WinDriver User’s Manual for the relevant WinDriver version. Alternatively, copy the INF file to Windows’ INF directory
(%windir%\inf) and reboot to let Windows locate and install the file.

 

6. If your project uses the wdapi<version>.lib library (for examplewdapi800.lib) — as is the case for the sample and generated DriverWizard projects — you need to distribute the wdapi DLL:

  • When distributing 32-bit applications/DLLs to 32-bit targetsOR when distributing 64-bit applications/DLLs to 64-bit targets: Copy WinDriver\redist\wdapi<version>.dll (e.g.,wdapi800.dll) to the target’s %windir%\system32directory.

NOTE: If you attempt to copy the 64-bit DLL to the
%windir%\system32 directory using a 32-bit installation program, you may find that the DLL file is actually copied to the 32-bit %windir%\sysWOW64 directory. The reason for this is that Windows x64 platforms translate references to 64-bit directories from 32-bit commands into references to 32-bit directories. You can avoid the problem by using 64-bit commands to perform the necessary installation steps from your 32-bit installation program. The system64.exeprogram, provided in the WinDriver\redist directory of the Windows x64 WinDriver distributions, enables you to do this.

 

  • When distributing 32-bit applications to 64-bit targets: CopyWinDriver\redist\wdapi<version>_32.dll (for examplewdapi800_32.dll) to the target’s %windir%\sysWOW64directory and rename the file to wdapi<version>.dll.

 

6. Copy your driver application/DLL to the target and run it!

 

Back To Top

Technical Document #131: Upgrading from WinDriver version 7.x–8.1.0 to a newer version

This document outlines the steps for upgrading from version 7.x–8.1.0 to a newer version of WinDriver.
If you are upgrading from version 8.1.1 or newer, refer to Technical Document #84 instead.
If you are upgrading from version 6.2.x, refer to Technical Document #127.

 

Upgrade Steps

  1. Install the new version
  2. Acquire a New WinDriver License (Registered Users)
  3. Upgrade Your Driver Project
  4. Upgrade Your Device INF File (Windows)
  5. Digitally Sign Your Driver Files (Windows)
  6. Upgrade Your Driver Distribution/Installation Package

 

  • Install the new version

Download and install a new version of WinDriver that matches your development platform and the operating systems and CPU configurations of the target platforms on which you intend the driver to be used.

  • Acquire a New WinDriver License (Registered Users)

If you are using a registered version of WinDriver, contact Jungo Connectivity at [email protected] to acquire a WinDriver license registration string for the new version. Then register the new license from DriverWizard (File | Register WinDriver) and from your code.

Note that if you have a valid Support and Upgrade plan you are are entitled to receive a new license free of charge.
If you do not have such a plan, contact [email protected] to request a temporary license that will allow you to evaluate the new version.

  • Upgrade Your Driver Project
      • Register Your New License (Registered Users): Modify the driver code to register your new license — i.e., replace the license string in the call to WDU_Init() (USB) /WDC_DriverOpen() (PCI/ISA — WDC API) / WD_License()(low-level API) from your code.PCI users — if you created a Kernel PlugIn driver, make sure to also update the license string in your Kernel PlugIncode.
      • PCI/ISA users upgrading from v11.7.0 or below — refer to Technical Document #116 for information on API changes done in v11.8.0 of WinDriver, and edit your code accordingly.

 

      • When upgrading from v7.x to v8.x+, you should also be aware of the following issues:
          • WinDriver-API DLL/shared object upgrade — In v8.0.0 we implemented versioning of the high-level WinDriver-API DLL/shared object. Consequently, the name of this module has changed from wd_utilsto wdapi<version> (e.g., wdapi800 for WinDriver v8.0.0). This enables you to upgrade your driver, including the DLL/shared object, without worrying about the possible effects on other drivers, developed with earlier versions of WinDriver, which may be using the same module.To use the new WinDriver-API DLL/shared object, simply build your code with the new version’s library module —WinDriver\lib\<CPU>\wdapi<new_version>.lib(Windows — MS Visual Studio, Windows CE) /WinDriver\lib\<CPU>\wdapi_borland<new_version>.lib (Windows — Borland C++ Builder — in WinDriver v11.1.0 and below) / WinDriver/lib/libwdapi<new_version>.so(Linux, Solaris — supported until 9.0.1) — as demonstrated in the sample and generated DriverWizard projects from v8.x and newer.)Similarly, the name of the WinDriver .NET API DLL changed in v8.0.0 from wdapi_dotnet.dll towdapi<version>_dotnet.dll (e.g.,wdapi800_dotnet.dll in v8.0.0) and the DLL was moved to the WinDriver\lib\<CPU>\<.NET version>\directory (e.g., WinDriver\lib\x86\v1.1.4322\).Note that if your code uses the wdapi DLL/shared object, you will need to distributewdapi<version>.dll (Windows, Windows CE) /libwdapi<version>.so (Linux, Solaris) with your driver. Windows .NET users should also distributewdapi<version>_dotnet.dll.
          • WinDriver source files location changes — Inv8.0.0 the WinDriver C source files were moved from the WinDriver/src directory to theWinDriver/src/wdapi/ directory. The .NET source files were moved from the WinDriver/wdapi.net/ directory to the WinDriver/src/wdapi.net/ directory.
            If your project uses the wdapi (previously wd_utils) DLL/shared object (see above), this should not normally affect you. However, if you have included any WinDriver source files directly in your project you may need to modify your project/make file to point to the new source files location.
        • When upgrading from v7.0.0 — update your project’s files search paths: Beginning withv7.0.1, the include path in the WinDriver project/make files contains the path to theWinDriver/ and WinDriver/include/ directories, and the #include statements in the WinDriver source files and generated DriverWizard code were consequently modified to indicate only the name of the header file to include, instead of the full/relative path to the file (as done in earlier versions).
          In light of these changes, when rebuilding a driver project from v7.0.0 or earlier of WinDriver with the source files from v7.0.1 or newer, you may need to modify your project/make file and add the path to theWinDriver/ and WinDriver/include/ directories to the project’s include path in order to successfully build the project.

 

      • 64-bit OS upgrade (Windows and Linux)
          • When developing a driver for a 64-bit platform, your project or makefile must include the KERNEL_64BITpreprocessor definition. In the makefiles, the definition is added using the -D flag: -DKERNEL_64BIT. The sample and wizard-generated Linux and Windows GCC makefiles and Windows MS Visual Studio projects in the 64-bit WinDriver toolkit already add this definition.
        • PCI Kernel PlugIn upgrade from v10.2.1- — to support execution of 32-bit applications with a 64-bitKernel PlugIn driver, follow the instructions inTechnical Document #112.

 

      • Rename your driver (Windows and Linux) — To avoid conflicts with other WinDriver-based drivers on the target platforms, we highly recommend that you rename the default WinDriver driver module — windrvr<version>.sys(e.g., windrvr1200.sys) on Windows /windrvr<version>.o/.ko (e.g., windrvr1200.o/.ko) onLinux (or windrvr6.sys / windrvr6.o/.ko in v11.8.0 and older) — to a unique name, by following the instructions in the new WinDriver User’s Manual. The renaming procedure is simple and quick.
        The Linux USB GPL driverwindrvr<version>_usb.o/.ko (or windrvr6_usb.o/.koin v11.8.0 and older) is automatically renamed when renaming the main WinDriver Linux driver.
        When creating a PCI Kernel PlugIn driver, select a unique name as well.

 

      • Ensure that your code uses the correct driver module— Verify that the call to WD_DriverName() in your driver code (if exists) uses the new driver-module name —windrvr<version> (or windrvr6 in v11.8.0 and below) or your renamed version of this driver.
        In version 11.9.0 of WinDriver the default WinDriver driver-module name changed from windrvr6 towindrvr<version> (e.g., windrvr1200 in v12.0.0). Consequently, when using the default driver-module name old projects need to be updated to use the default name from the newer version. If you use the generated DriverWizard code or one of the samples from the new WinDriver version, the code will already use the default driver name from the new version. Also, if your code is based on generated/sample code from an earlier version of WinDriver, rebuilding the code with windrvr.h from the new version is sufficient to update the code to use the new default driver-module name (due to the use of theWD_DEFAULT_DRIVER_NAME_BASE definition).
        If you elect to rename the WinDriver driver module, ensure that your code calls WD_DriverName() with your custom driver name. If you rename the driver from the new version to a name already used in your old project, you do not need to modify your code.

        NOTE
        To apply a driver name change — whether using the default driver name or a custom name — your user-mode driver project must be built with theWD_DRIVER_NAME_CHANGE preprocessor flag (e.g., -DWD_DRIVER_NAME_CHANGE), as explained in the WinDriver WinDriver User’s Manuals and demonstrated in the sample and generated DriverWizard WinDriver projects/makefiles.

 

      • Rebuild your updated driver project with the source files from the new version.PCI users who created a Kernel PlugIn driver must rebuild it with the files from the new version as well.

  • Upgrade Your Device INF File (Windows)

On Windows, if you have created a driver for a Plug-and-Play device (USB/PCI/CardBus/PCMCIA), we recommend that you create and install a new INF file for your device, which registers it with the driver module from the new version —windrvr<version>.sys (e.g., windrvr1200.sys) /windrvr6.sys in v11.8.0 and older — or your renamed version of this driver (in v9.x and newer). You can use DriverWizard from the new version to generate the new INF file, or change the driver version in your old INF file.

  • Digitally Sign Your Driver Files (Windows)

On 64-bit versions of Windows Vista and higher

      , Microsoft requires that kernel drivers be digitally signed. Therefore, if you use any of the following driver files you must digitally sign them: A

renamed

      version of the WinDriver kernel driver (the default WinDriver driver —

windrvr<version>.sys

      /

windrvr6.sys

      in v11.8.0 and older — is already digitally signed), a

Plug-and-Play device INF file

      , and/or a

PCI Kernel PlugIn driver

      . You can bypass this restriction during the development stage (e.g., on Windows 7, by pressing

F8

      at boot time and selecting the relevant option), but the driver files must be signed before distribution. There are also advantages to signing your driver

on other Windows OSs

      . For more information, refer to

Micorsoft’s Driver Signing Policy

      and to the

Windows Digital Driver Signing and Certification

      section of the

WinDriver User’s Manuals

      .

You can obtain digital signatures from third-party companies such as DigiCert or Symantec, or use Jungo Connectivity’s digital driver signing service. Jungo Connectivity can also assist you in preparing your driver for Microsoft’s Windows cetification.

  • Upgrade Your Driver Distribution/Installation Package

Create a new driver installation package, which contains the following files from the new WinDriver distribution:

      • The WinDriver driver module —windrvr<version>.sys/.o/.ko/.dll (e.g.,windrvr1200.sys/.o/.ko/.dll) in the newer WinDriver versions, or a renamed version of this driver
      • The WinDriver Linux USB GPL driverwindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) in the newer WinDriver versions, or a renamed version of this driver
      • Your rebuilt PCI Kernel PlugIn driver —<KP_driver_name>.sys (if created)
      • Any other files required for installing or using your driver — such as wdapi<new_version>.dll/.so,wdreg[.exe]/wdreg_gui.exe (and difxapi.dll on Windows), and Windows INF and catalog files
      • An installation program that installs the new driver

Hardware- and OS-specific driver distribution instructions can be found in the Distributing Your Driver chapter of the user manuals from the new version. The instructions for Windows are also summarized in Technical Document #132 (v8.1.x and newer) / Technical Document #130 (v8.0.x).

Version-Specific Installation Upgrade Notes:

    • Linux USB v9.2.1- to v10.0.0+ upgrade — the WinDriver USB Linux GPL driver: Beginning with v10.0.0, the WinDriver Linux USB driver was split into two modules, which are used together to provide the full driver functionality:
        • windrvr6.o/.ko, renamed in v11.9.0 towindrvr<version>.o/.ko (e.g.,windrvr1200.o/.ko) — the traditional WinDriver driver module, which includes the product license.
        • windrvr6_usb.o/.ko, renamed in v11.9.0 towindrvr<version>_usb.o/.ko (e.g.,windrvr1200_usb.o/.ko) — this driver implements Linux-specific USB driver functionality, and contains a GNU General Public License (GPL).
        • Windows v8.1.0- to v8.1.1+ upgrade — WDREGdifxapi.dll dependency: Beginning with v8.1.1, thewdreg installation utility uses the Driver Install Frameworks API (DIFxAPI) to perform driver installation and uninstallation. As a result, the wdregutility in v8.1.1 and newer is dependent on thedifxapi.dll DLL, which is provided under theWinDriver\util directory. This DLL must therefore be in wdreg‘s search path when using the utility to install / WDREG difxapi.dll Dependency:
      • Windows v7.x- to v8.1.0+ upgrade — thewd<version>.cat WinDriver catalog file:Beginning with v8.1.0, the WinDriver driver (windrvr<version>.sys / windrvr6.sys in v11.8.0 and older) has an Authenticode digital signature. To enjoy the advantages of this signature thewd<version>.cat catalog file, provided under theWinDriver\redist directory, needs to be distributed together with the related INF file (windrvr<version>.inf / windrvr6.inf in v11.8.0 and older), which is used to install the driver. For more information, refer to the WinDriver User’s Manuals of the new WinDriver version and to Technical Document #132.

Back To Top

Technical Document #132: Distributing your WinDriver-based driver to a target Windows PC

This document outlines the basic steps for installing a driver developed with version 11.9.0 or newer of WinDriver on a target Windows PC. Detailed driver distribution instructions can be found in the WinDriver User’s Manual for your WinDriver version.

The Windows driver distribution steps for versions 8.1.x–11.8.0 of WinDriver are outlined in Technical Document #120.
The Windows driver distribution steps for version 8.0.x of WinDriver are outlined in Technical Document #130.

This document includes

Documentation Notes:

  • All OS references in this document are applicable only to WinDriver versions that officially support these operating systems (refer toTechnical Document #4 for the list of operating systems supported by the latest WinDriver version).

 

  • The windrvr<version>.sys, windrvr<version>.inf, andwd<version>.cat files, mentioned in this document, can be found in the WinDriver\redist directory on the development PC.wdreg.exe / wdreg_gui.exe and difxapi.dll can be found in theWinDriver\util directory. (The source code of the wdreg utility is found in the WinDriver\samples\wdreg directory.)

 

  • You can rename the WinDriver Windows driver module —windrvr<version>.sys (e.g., windrvr1200.sys) — and the related INF file — windrvr<version>.inf (e.g.,windrvr1200.inf). You can also submit the driver for Windows certification or have it Authenticode signed yourself, using your own WinDriver catalog file (xxx.cat), as explained in the WinDriver User’s Manual. If you have selected to rename any of the provided WinDriver files, replace the references to these files in the present document with the names of your new files.

 

  • The wdreg.exe and wdreg_gui.exe utilities provide the same functionality. The difference is in the way the installation messages are displayed — graphical messages (wdreg_gui.exe) or console messages (wdreg.exe). You can therefore replace any reference to wdreg.exe in the following instructions with wdreg_gui.exe.
    The wdreg utility is dependent on the difxapi.dll DLL.

Installation Notes:

  • You must have administrative privileges in order to install drivers on Windows.

 

  • When distributing your driver, take care not to overwrite a newer version of the driver file — windrvr<version>.sys or a renamed driver — with an older version of this file.
    The provided INF file — windrvr<version>.inf (e.g.,windrvr1200.inf) — uses the COPYFLG_NO_VERSION_DIALOGdirective, which is designed to avoid overwriting a file in the destination directory with the source file if the existing file is newer than the source file. There is also a similarCOPYFLG_OVERWRITE_OLDER_ONLY INF directive that is designed to ensure that the source file is copied to the destination directory only if the destination file is superseded by a newer version. Note, however, that both of these INF directives are irrelevant to digitally signed drivers. As explained in the Microsoft INF CopyFiles Directive documentation, if a driver package is digitally signed, Windows installs the package as a whole and does not selectively omit files in the package based on other versions already present on the computer. The WinDriver driver — windrvr<version>.sys — is digitally signed with an Authenticode signature (refer to the WinDriver User’s Manual for more information on driver signature and certification).
NOTE
Since v11.9.0 of WinDriver, the default driver module name includes the WinDriver version (e.g., windrvr1200.sys for version 12.0.0), so if you do not rename the driver to a previously-used name there should not be conflicts with older drivers.

 

  • If you wish to distribute drivers for both 32-bit and 64-bit target platforms, you must prepare a separate driver installation package for each platform.

 

  • When upgrading the driver from a previous version of WinDriver, if your are using the same renamed driver, make sure that there are no open handles to the old WinDriver service, and that there are no connected and enabled Plug-and-Play devices that are registered with this service. This includes closing any applications that may be using the driver; uninstalling your old Kernel PlugIndriver (if you had created such a driver):
    \> wdreg -name OLD_KP uninstall
    and either disabling, uninstalling, or physically disconnecting any device that is registered to work with the WinDriver service.

Installation Steps:

1.Copy windrvr<version>.sys, windrvr<version>.inf, andwd<version>.cat (for the current version — windrvr1200.sys,windrvr1200.inf, and wd1200.cat) to the same directory.

NOTE:

  • If you select to copy wd<version>.cat to a different location you will need to modify the CatalogFile entry in the windrvr<version>.inf file to point to the location of the catalog file.
  • You can also select not to distribute the wd<version>.catcatalog file, in which case you need to remove or comment-out the CatalogFile line in the windrvr<version>.inf file. However, note that if you do so the installation will not utilize the driver’s Authenticode digital signature (see the WinDriver User’s Manual for more information).

 

2. Use the utility wdreg.exe to install WinDriver’s kernel module on the target computer:
\> wdreg -inf <path to windrvr<version>.inf> install

NOTE: Remember that wdreg requires the difxapi.dll DLL.

TIP: If you copy wdreg.exe and difxapi.dll to the same directory as windrvr<version>.sys and windrvr<version>.inf, you can simply run the following command from your installation directory in order to install the driver:
install_dir:] wdreg -inf windrvr<version>.inf install

3. If you have created a Kernel PlugIn driver (e.g., my_kp.sys), copy this driver to Windows drivers directory —%windir%\system32\drivers — and install it using the wdreg.exeutility:
\> wdreg -name MY_KP install

NOTE: The driver name is indicated without the *.sys extension.

 

4. For Plug-and-Play devices (PCI/USB): install the device INF file, which registers your device to work with thewindrvr<version>.sys service (normally this file is created using WinDriver’s DriverWizard utility).

You can use the wdreg.exe utility with the install command to automatically install the INF file:
\> wdreg -inf <path to device.inf> install
You can also use the preinstall wdreg.exe command to pre-install an INF file for a device that is not currently connected to the PC:
\> wdreg -inf <path to device.inf> preinstall

 

5. If your project uses the wdapi<version>.lib library (for examplewdapi900.lib) — as is the case for the sample and generated DriverWizard projects — you need to distribute the wdapi DLL:

  • When distributing 32-bit applications/DLLs to 32-bit targetsOR when distributing 64-bit applications/DLLs to 64-bit targets: Copy WinDriver\redist\wdapi<version>.dll (e.g.,wdapi900.dll) to the target’s %windir%\system32directory.

NOTE: If you attempt to copy the 64-bit DLL to the
%windir%\system32 directory using a 32-bit installation program, you may find that the DLL file is actually copied to the 32-bit %windir%\sysWOW64 directory. The reason for this is that Windows x64 platforms translate references to 64-bit directories from 32-bit commands into references to 32-bit directories. You can avoid the problem by using 64-bit commands to perform the necessary installation steps from your 32-bit installation program. The system64.exeprogram, provided in the WinDriver\redist directory of the Windows x64 WinDriver distributions, enables you to do this.

 

  • When distributing 32-bit applications to 64-bit targets: Rename the file WinDriver\redist\wdapi<version>_32.dllto wdapi<version>.dll (for example, renamewdapi900_32.dll to wdapi900.dll) and copy the renamed file to the target’s %windir%\sysWOW64 directory.

 

6. Copy your hardware-control application/DLL to the target and run it!

Back To Top

Debugging

Technical Document #12: What is the wddebug_gui Debug Monitor utility and how can I use it?

WinDriver’s Debug Monitor is an application program that logs detailed debugging information from the WinDriver kernel.
wddebug_gui (found at WinDriver/util, or at /Applications on Mac OS X— in the WinDriver versions that support this OS) is a fully GUI version of this utility, for Windows, Mac OS X, and Linux.
The Debug Monitor has an additional version — wddebug — which supports console-mode usage on Windows, Windows CE, and Linux, (and in earlier WinDriver versions — on Mac OS X, Solaris, and VxWorks as well), and also supports GUI execution on Windows CE. For a description of wddebug refer to Technical Document #13 — for Windows, Windows CE, Mac OS X, Linux, and Solaris — or to Technical Document #14 — for VxWorks.
A detailed description of both versions of the Debug Monitor utility can be found in the WinDriver User’s Manuals. This document describes how to use wddebug_gui in the latest WinDriver version.
References to the Debug Monitor in the following text should be taken to refer to the wddebug_gui version of this utility.

To start the Debug Monitor, do one of the following:

  • Run wddebug_gui from the WinDriver/util directory (or from/Applications on Mac OS X — in WinDriver versions that support this OS).
  • From the DriverWizard, select Tools –> Debug Monitor.
  • On Windows platforms, you can run the program from the Startmenu: Start –> Programs –> WinDriver &ndsah;> Debug Monitor(or Monitor Debug Messages — in version 5.0.5b or earlier of WinDriver).

When the Debug Monitor starts, it prints a message specifying the program version and OS information.

The debug messages follow after this whenever you perform an operation with WinDriver. When sending the debug messages to the Jungo Connectivity support personnel, do not delete the initial driver and system information from the Debug Monitor window.

The Debug Options menu, which is available from the Debug Monitor’sView menu, allows you to set the debug level and sections for which to receive debug messages. Additional configurations can be made via other Debug Monitor menu options and via the toolbar.

When reporting a problem, run the Debug Monitor, set the debug level toTrace (which implies that the maximum level of debugging information will be logged), leave the debug window open, run your application, reproduce the problem, and then send us the entire output of the debug log.
Note that you can add custom messages to the debug log during execution (beginning with v11.7.0 of WinDriver) via the Debug Monitor’sEdit –> Add Custom Message... menu option.
Please observe the lines in the Debug Monitor around where your problem occurs, and insert a remark there for our support personnel.

You can also use the Debug Monitor to debug problems on a target machine on which only the WinDriver driver(s) and your application were installed, and not the entire WinDriver tool-kit: Just copy thewddebug_gui program to this machine, and run it directly on the target.

You can use the WD_DebugAdd() function to send your own debug messages from the code to the debug log. This function is available beginning with v5.0.3 of WinDriver, and is described in the function reference section of the WinDriver User’s Manual. Please note that this function can be called from both a user-mode and a kernel-modeapplication, and can even be called from within the Kernel PlugInKP_IntAtIrql() function, which is executed at HIGH IRQL.

For an explanation on how to send debug messages from the Debug Monitor to a kernel debugger, refer to Technical Document #44.

Back To Top

Technical Document #13: What is the wddebug Debug Monitor utility and how can I use it?

WinDriver’s Debug Monitor is an application program that logs detailed debugging information from the WinDriver kernel. wddebug (found in the WinDriver/util directory) is a console-mode version of this utility, for Windows, Windows CE (a.k.a. Windows Embedded Compact), and Linux, (and in earlier WinDriver versions — for Mac OS X, Solaris, and VxWorks as well). wddebug also supports GUI execution on Windows CE.
The Debug Monitor has an additional version — wddebug_gui — which is a fully GUI version for Windows and Linux (and in earlier WinDriver versions — for Mac OS X as well). For a description of wddebug_gui refer to Technical Document #12 and to the WinDriver User’s Manuals.

wddebug CLI usage

wddebug is normally executed from a command-line interface (CLI):
wddebug [<driver_name>] [<command>] [<level>] [<sections>]

For full usage instructions, run wddebug help (or wddebug without arguments — on Windows and Linux).
For more detailed information, refer to the WinDriver User’s Manuals.

wddebug Windows CE GUI usage

To enable debug logging on Windows CE platforms that do not have a command-line prompt, beginning with version 10.0.1 of WinDriverwddebug also has a GUI version: If you double-click the wddebugexecutable, or run it from a command-line prompt without any arguments, a GUI message box informs you that the debug messages will be stored in a predetermined log file — wdlog.txt in the root Windows CE directory. If you select to continue, debug logging is turned on with trace level TRACE and debug sections ALL, and the Debug Monitor begins dumping debug messages to the wdlog.txt log file. You can stop the logging and turn off debug logging, at any time, via a dedicated GUI message box.

Back To Top

Technical Document #14: How do I use the Debug Monitor utility on VxWorks?

On VxWorks you should use the wddebug.out utility. Its usage is similar to the wddebug command-line utility used on the other supported WinDriver operating systems in similar WinDriver versions.
There is no GUI version of the Debug Monitor for VxWorks.

To use wddebug.out on VxWorks, do the following:

1. Load the program wddebug.out into your memory.
2. Call wddebug_main. This will give you usage instructions.
3. Call wddebug_main with parameters wddebug_main “on” “trace” “all”
This activates the Debug Monitor.
4. Call wddebug_main dump.
Now the program will continuously dump debug messages, until you press ENTER. You won’t get the shell prompt back (until you press ENTER) so you need to start a new shell to work with your target.

The source code for wddebug.out is found in DriverBuilder/samples/wddebug/wddebug.c.

To ensure the correct usage of the debug utility, you can either add the source code to your application (changing, of-course, the name of the main() function in the source code); or preferably, add the following two function definitions to your code and call them from main(), in order to activate the debug utility:

int debug_start()
/* Call this function after the call to
drvrInit(), in order to instruct the
kernel to start sending debug messages: */
{
WD_DEBUG debug;
HANDLE hWD = WD_Open();
if(hWD==INVALID_HANDLE_VALUE)
return -1;

BZERO(debug);

debug.dwCmd = DEBUG_SET_FILTER;
debug.dwLevel = D_TRACE;
debug.dwSection = (DWORD)S_ALL;

WD_Debug(hWD, &debug);

return 0;
}

int debug_dump()
/* Call this function at the end of main(),
after the system as booted and you get
your shell. This function causes the debug
messages that have been sent to be displayed
of in the debug log: */
{
WD_DEBUG_DUMP debugDump;
char buf[2048];
HANDLE hWD = WD_Open();

if(hWD==INVALID_HANDLE_VALUE)
return -1;

BZERO(debugDump);
debugDump.pcBuffer = buf;
debugDump.dwSize = sizeof (buf);

WD_DebugDump(hWD, &debugDump);

printf(“%s”, debugDump.pcBuffer);

return 0;
}

Back To Top

Technical Document #19: Debugging your driver code with WinDriver

When using the WinDriver tool-kit, you are developing in the user mode, and you can therefore use the regular user-mode debugging tools, such as the compiler’s debugger.

The WinDriver tool-kit includes the Debug Monitor utility (a.k.a. Monitor Debug Messages, in earlier versions) to help you in the debugging process. This utility comes both in a GUI format — WinDriver/util/wddebug_gui(or /Applications/wddebug_gui.app on Mac OS X — in the WinDriver versions that support this OS) — and a console (CLI) format —WinDriver/util/wddebug.
For a detailed description of this utility, please refer to the WinDriver User’s Manuals and to Technical Documents #12(wddebug_gui), #13 (wddebug), and #14 (for VxWorks — last supported in WinDriver v5.2.2).

WinDriver also provides you with the WD_DebugAdd() API (available beginning with v5.0.3), which enables you to send your own debug messages from the code to the Debug Monitor log. For a description of this API, refer to the function reference in the WinDriver User’s Manuals.
Note that this function can be called from both user-mode and kernel-mode code (created using WinDriver’s Kernel PlugIn feature) and can also be called from within functions running at HIGH IRQL, such as the Kernel PlugIn KP_IntAtIrql() function.

You can also select to send the debug messages to a kernel debugger, instead of to the Debug Monitor log, as explained in Technical Document #44. This can enable you, for example, to log the debug message on another PC in case the system crashes or hangs on the development PC.

Beginning with version 6.0, most of the WinDriver functions have areturn value to indicate success or a relevant error code, which can assist you in the debugging process. For USB, beginning with version 5.2.0 of WinDriver, the USB API also returns additional status information, which can help in determining the reason for a failed operation. This information is returned in the dwStatus field that was added to the USB structures. The return status codes are defined in theWD_USB_ERROR_CODES enum in WinDriver/include/windrvr.h).

When developing code in the kernel (using the Kernel PlugIn, you can also use any kernel debugger in the debugging process (e.g., WinDbg — which is distributed with the Windows Driver Kit (WDK) and is part of the Debugging Tools for Windows package, distributed via the Microsoft web site). As mentioned above, you can also select to direct the debug message from the Debug Monitor to a kernel debugger of your choice.

For more information regarding the debugging process with WinDriver, review the debugging chapters in the WinDriver User’s Manuals.

Back To Top

Technical Document #33: Using DebugView to monitor debug output

DebugView is a Windows application that lets you monitor debug output on your local system, or any computer on the network that you can reach via TCP/IP. It can display both kernel-mode and Win32 debug output generated by standard debug print APIs.

DebugView can be downloaded from
http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx.

When using the Debug Monitor, you can select to send all the debug information that is received by the Debug Monitor to an external kernel debugger (e.g., DebugView), by selecting the Send debug messages to the operating system kernel debugger option from the wddebug_gui debug-options menu, or by running wddebug with the dbg_on command.
The debug information can be of two major types: messages sent to the Debug Monitor automatically from WinDriver’s kernel module, or messages sent from the code to the Debug Monitor usingWD_DebugAdd().
After selecting this option, run your application, reproduce the problem, and view the debug information in the external kernel debugger’s log (in DebugView).
For more information about this option, refer to Technical Document #44

Back To Top

Technical Document #44: Sending debug information from WinDriver’s kernel module to a kernel debugger

Beginning with version 5.0.4 of WinDriver, you can send the debug information that is received from WinDriver’s kernel module and calls toWD_DebugAdd() or PrintDbgMessage() in your code, to a kernel debugger. This option enables you to direct the debug information to a kernel debugger of your choice.

To direct the debug messages to a kernel debugger, follow these steps:

    1. Open your selected kernel debugger.

 

    1. Run the Debug Monitor and select to direct the WinDriver debug messages to a kernel debugger, using either of the following methods:
      • Open the GUI version of the Debug Monitor —wddebug_gui (available on Windows, Linux, and Mac OS X— supported until v10.4.0), check the “Send debug messages to the operating system kernel debugger”option in the Debug Options window, and press ‘OK’.
      • Run the console-mode version of the Debug Monitor —wddebug (available on all the supported operating systems) — with the dbg_on command:
        WDDEBUG [<driver_name>] dbg_on [<level>] \
           [<sections>]

 

    1. On Windows Vista and higher, the first time that you enable this option you will need to restart your PC to apply it.

 

  1. Run your application, reproduce the problem, and view the debug information in the kernel-debugger log.

Windows users can use Microsoft’s WinDbg tool, for example; this tool is distributed with the Windows Driver Kit (WDK) and is part of the Debugging Tools for Windows package, distributed via the Microsoft web site.
Windows users can also use DebugView to monitor debug output.
For more information regarding DebugView, see Technical Document #33.

Back To Top

Technical Document #55: Buffer Overrun Error: WDU_Transfer() sometimes returns the 0xC000000C error code. What does this error code mean? How do I solve this problem?

The 0xC000000C error code, is defined in windrvr.h as WD_USBD_STATUS_BUFFER_OVERRUN.

The WD_USBD_XXX status codes returned by WinDriver (see windrvr.h) comply with the URB status codes returned by the low-level USB stack driver (e.g., URB code 0XC000000CL — WD_USBD_STATUS_BUFFER_OVERRUN).
You can refer to the Debug Monitor log to see the URB and IRP values returned from the stack drivers.

For Windows, the URB and IRP codes can be found in the Windows Driver Kit (WDK) under the inc\ directory. The URB status codes can be found in the usbdi.h file or the usb.h file (depending on th e OS). The IRP status codes can be found in the ntstatus.h file. Similar Microsoft documentation exists for Windows CE (a.k.a. Windows Embedded Compact).
For Linux, WinDriver translates the error codes returned from the stack driver into equivalent USBD errors.

For information regarding the specific error you received and when it might occur, review the operating system’s documentation.

The USBD_STATUS_BUFFER_OVERRUN error code (0xC000000C) is set by the USB stack drivers when the device transfers more data than requested by the host.

There are two possible solutions for this buffer overrun problem:

  1. Try setting the buffer sizes in the calls to WDU_Transfer in your code to multiples of the maximum packet size. For example, if the maximum packet size is 64 bytes, use buffer sizes that are multiples of 64 (64 bytes, 128 bytes, etc.).
  2. Define a protocol between the device and device driver, making sure that the device does not transfer more data than requested. When you have access to the device firmware code, this solution is recommended.

Notes:

  1. Recheck your firmware and the hardware specification to verify that you are implementing the communication with the device correctly.
  2. It is also recommended to use a USB bus analyzer to determine what is happening on the bus.

Back To Top

DriverWizard

Technical Document #5: Building WinDriver with custom version information

WinDriver for Windows allows building your driver with custom version information (Provider, Date, Version, etc…). This information can be seen upon entering the Device Properties of your device in the Device Manager or by right-clicking the driver binary and selecting the “Details” tab.

Driver File Details

 

How to build WinDriver with custom version information:

Building with WDK 8 and above:

  1. Install your WDK version. Note that before installing WDK you must install an appropriate Visual Studio version. For more info regarding WDK installation see Download the Windows Driver Kit (WDK) in MSDN.
  2. Create a new Windows Driver project under Visual C++ projects. Select Empty WDM Driver. Make sure that the Visual Studio project name matches your WinDriver project name (generated by the DriverWizard).
  3. Remove the .inf file from the project (under Driver Files).
  4. Edit the .rc file (located in <YOUR_DRIVER_NAME>_installation\sys folder) to have your custom version information.
  5. Add  the .rc file to the project by selecting Project -> Add Existing Item.
  6. In Project-> Properties make sure that the platform matches your version of WinDriver (x86 or x64)
  7. In Project-> Properties-> VC++ Directories -> Include Directories add C:\WinDriver\include 
  8. In Project ->Properties-> Linker -> Input -> Additonal Dependencies add C:\WinDriver\lib\windrvr1240.lib ; %(DDK_LIB_PATH)usbd.lib
  9. Select Windows 7 as Target OS. Note that the selection differs between various Visual Studio versions. For example, in WDK 8 with Visual Studio 2012, the OS version is specified as a configuration option, while in WDK 10 with Visual Studio 2015 it is under Project -> Properties -> Driver Settings.
  10. Build the project.
  11. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

Building with WDK 7.1.0 and lower:

  1. Install WDK 7.1.0
  2. Open a command prompt. Change directory to the <YOUR_DRIVER_NAME>_installation\sys folder.
  3. Run set BASEDIR=<YOUR_WDK_7.1.0_DIRECTORY> (e.g. set BASEDIR=C:\WinDDK\7600.16385.1)
  4. Run ddk_make.bat <PLATFORM> <BUILD_TYPE> (Listing of possible parameters is available by running ddk_make.bat without arguments.
  5. Place the newly compiled .sys file and your INF file (located in your DriverWizard project’s redist sub-directory) in the same directory. Now you may install the driver using the wdreg utility as described in the WinDriver tutorial, Section 14.2. Windows Driver Distribution.

 

NOTE:

If build fails due to a “non-existing paths” error, it may be possible to solve this by editing the Path environment variable from Control Panel -> System and Security -> System -> Advanced system settings -> Advanced -> Environment Variables -> System Variables and removing non existing paths from it.

Back To Top

General Starters

Technical Document #1: What is WinDriver?

The WinDriver toolkit is ideal for PCI/cPCI/CardBus/PCMCIA/PCI-X/PCI Express/ISA/ISA PnP/EISA and USB device-driver development. (References to “PCI” in this document should be taken to refer also to the cPCI, CardBus, PCMCIA (Windows), PCI-X and PCI Express buses).

WinDriver supports I/O operations, access to memory mapped cards, hardware interrupts handling, DMA transfers, read/writes from USB pipes, Plug and Play and power management events handling and multi-board handling.

The code you develop with WinDriver will be cross-platform compatibleacross all the supported operating systems for the version that you are using. For a list of the supported operating systems for each version, please refer to Technical Documents #4 and #50.

WinDriver supports development for ALL PCI chip-sets and USB devices. In addition, it features enhanced support for major PCI chip vendors (such as PLX, Altera, and Xilinx), and earlier versions also include enhanced support for major USB development board manufacturers (such as Cypress), thereby hiding most of the intrinsic bus details from the user and allowing you to concentrate on your device-specific logic. For more information regarding this enhanced support, refer to the WinDriverproduct page and to the WinDriver User’s Manuals for your version of WinDriver.

You can use WinDriver’s powerful graphical DriverWizard utility to easily detect/define the hardware’s resources and debug your hardware, by transferring data to/from the hardware, listening to interrupts, etc., without writing a single line of code.

You can also use the DriverWizard to generate skeletal diagnostics code for your device, which will provide you with convenient wrapper functions that utilize WinDriver’s API to communicate with your specific device. Furthermore, you can review the various samples provided with WinDriver to see if there is a sample that may serve as a skeletal basis for your driver application.

WinDriver enables all development to be done in the user mode and frees you of the need for any kernel and/or OS-specific driver development knowledge, such as familiarity with the Windows Driver Kit (WDK). For a description of WinDriver’s basic architecture, refer to the WinDriver User’s Manual.

For PCI/ISA development, after you develop your application in the user mode, you will also be able to use WinDriver’s special Kernel PlugInfeature (described in the WinDriver User’s Manual) to simply move performance-critical parts of your code from your application or DLL (in Ring 3) to the kernel level (Ring 0) for optimal performance.

To help you in your initial steps with WinDriver, visit the WinDriver Support page for online tours and quick-start guides as well as other useful information, which can facilitate your development process.

Back To Top

Technical Document #4: What operating systems and their respective versions does WinDriver support?

This document outlines the operating systems support in the latest WinDriver versions.

NOTE
OS-specific support is provided only for operating systems with official vendor support.

PCI/ISA

WinDriver PCI supports the following operating systems:

  • Windows:
    Windows 10/8.1/8/7/Server 2016/Server 2012 R2/Server 2012/Server 2008 R2/Server 2008
  • Linux:
    Any x86 32-bit or 64-bit (x86_64) processor, with a 2.6.x or higher Linux kernel.

USB

WinDriver USB supports the following operating systems:

  • Windows:
    Windows 10/8.1/8/7/Server 2016/Server 2012 R2/Server 2012/Server 2008 R2/Server 2008
  • Linux:
    Any x86 32-bit or 64-bit (x86_64) processor, with a 2.6.x or higher Linux kernel.

 
NOTE: Jungo Connectivity strives to support new Linux kernel versions as close as possible to their release. To find out the latest supported kernel version, refer to the latest WinDriver release notes.

For more information relating to when the support for each operating system and the related service packs was introduced, please review Technical Document #50.

Back To Top

Technical Document #9: What are the limitations of the WinDriver evaluation kits?

The WinDriver evaluation versions are full-featured, without any reduced features or degraded performance.

The only differences from the registered version are as follows:

    • Each time WinDriver is activated, an evaluation message will appear. When using the DriverWizard, an evaluation message will also pop-up occasionally.

 

    • On Windows — The evaluation version has a 30 days time limit.

 

    • On Windows — The evaluation message will appear every two hours (provided you have used the WinDriver kernel module — i.e., called one of the WinDriver APIs, either directly from your code or through one of the WinDriver utilities).

 

  • On Linux and Windows CE (and in previous versions also onMac OS X, Solaris, and VxWorks) — The evaluation version has a 60 minutes development session limit (this time was shorter in previous versions of WinDriver). To continue using WinDriver after a 60 minutes session, you need to do the following:
      • On Mac OS X, Linux, and Solaris — The driver has to be reloaded — i.e., perform unload and then reload, as detailed below.
        NOTE
        Before removing the WinDriver kernel module (windrvr6/WinDriver/windrvr — depending on the OS), make sure that there are no open handles to this module.

        On Linux:
        Unload:
        /sbin/modprobe -r windrvr6
        Load:
        <path to wdreg>/wdreg windrvr6

        Note: The commands must be executed with root privileges.

        On Mac OS X (supported until v10.4.0):
        Unload:
        sudo kextunload \
        /System/Library/Extensions/WinDriver.kext

        Load:
        sudo <path to wdreg>/wdreg WinDriver

        Note: The commands must be executed with root privileges.

        On Solaris (supported until v9.0.1):
        Unload:
        /usr/sbin/rem_drv windrvr6
        Load:
        /usr/sbin/add_drv windrvr6

      • On Windows CE — Try performing a warm reset, according to the following instructions: Restart your HPC. The WinDriver CE kernel will automatically be loaded. You will have to do a warm reset, rather than just Suspend/Resume. You should look for a button labeled “RESET” on your HPC. On the HP 3xx/6xx series, this button can be found under the reserve battery cover. If this does not help, you will need to reload the OS Image with WinDriver (as was done for the initial installation of WinDriver — see the WinDriver Windows CE installation instructions).
    • On VxWorks (supported until v5.2.2) — The whole system must be restarted (i.e., reboot) after a 60 minutes session.

The limitations of the evaluation version are also outlined in the WinDriver User’s Manual.

Back To Top

Technical Document #13: What is the wddebug Debug Monitor utility and how can I use it?

WinDriver’s Debug Monitor is an application program that logs detailed debugging information from the WinDriver kernel. wddebug (found in the WinDriver/util directory) is a console-mode version of this utility, for Windows, Windows CE (a.k.a. Windows Embedded Compact), and Linux, (and in earlier WinDriver versions — for Mac OS X, Solaris, and VxWorks as well). wddebug also supports GUI execution on Windows CE.
The Debug Monitor has an additional version — wddebug_gui — which is a fully GUI version for Windows and Linux (and in earlier WinDriver versions — for Mac OS X as well). For a description of wddebug_gui refer to Technical Document #12 and to the WinDriver User’s Manuals.

wddebug CLI usage

wddebug is normally executed from a command-line interface (CLI):
wddebug [<driver_name>] [<command>] [<level>] [<sections>]

For full usage instructions, run wddebug help (or wddebug without arguments — on Windows and Linux).
For more detailed information, refer to the WinDriver User’s Manuals.

wddebug Windows CE GUI usage

To enable debug logging on Windows CE platforms that do not have a command-line prompt, beginning with version 10.0.1 of WinDriverwddebug also has a GUI version: If you double-click the wddebugexecutable, or run it from a command-line prompt without any arguments, a GUI message box informs you that the debug messages will be stored in a predetermined log file — wdlog.txt in the root Windows CE directory. If you select to continue, debug logging is turned on with trace level TRACE and debug sections ALL, and the Debug Monitor begins dumping debug messages to the wdlog.txt log file. You can stop the logging and turn off debug logging, at any time, via a dedicated GUI message box.

Back To Top

Technical Document #20: Can I run two different device drivers, both developed with WinDriver, on the same machine?

Yes. You can run several WinDriver-based applications simultaneously on the same machine. (With regard to accessing the same hardware from several applications, please refer to Technical Document #98.)

Until version 11.5.0, code developed with an earlier version of WinDriver could run with the drivers from a newer version as well (provided the code wasn’t recompiled with newer header files using the old license). At most, you may have needed to update the INF files for PCI/USB devices when upgrading the driver on a Plug-and-Play OS.
Staring from version 11.5.0, code developed with an earlier version needs to be recompiled with a new license that matches the version of the newer WinDriver driver with which you want to use the code. See additional information in Technical Document #84,

Note that code developed with a newer version of WinDriver was never guaranteed to work with an older driver file. You should, therefore, take care, when distributing your driver, that the installation process does not overwrite a newer version of the WinDriver module —windrvr.sys/.o/.ko/.dll (orwindrvr6.sys/.o/.ko/.dll/.vxd / windrvr.sys/.vxd/.o, in earlier versions of WinDriver), or a renamed version of the driver — with an older version of the driver file. This is also true for the WinDriver USB Linux GPL driver — windrvr_usb.o/.ko (previouslywindrvr6_usb.o/.ko; from WinDriver v10.0.0 and above).

NOTE
In version 6.0 of WinDriver we renamed the WinDriver kernel module from windrvr to windrvr6. In version 11.9.0 we renamed the default kernel module to windrvr (e.g.,windrvr1200). WinDriver kernel modules with different names can be used simultaneously on the same machine.

Back To Top

DMA

Technical Document #3: Preallocating contiguous DMA buffers on Windows

The WinDriver DMA APIs do not limit the size of allocated DMA buffers. However, the success of the DMA allocation is dependent on the amount of available system resources at the time of the allocation. Therefore, the earlier you try to allocate the buffer, the better your chances of succeeding.
Beginning with version 11.1.0 of WinDriver for Windows, you can configure your device INF file to preallocate at boot time contiguous host-to-device and/or device-to-host DMA buffers, thus increasing the odds that the allocation(s) will succeed.
Up to version 12.3.0 (including) up to two DMA buffers are supported, one for each direction.
Beginning with version 12.4.0 of WinDriver for Windows, you can preallocate a maximum of 512 buffers (256 device-to-host and 256 host-to-device).
To preallocate contiguous DMA buffers on Windows, follow these steps:

  1. Add the required configuration under the [UpdateRegistryDevice] registry key in your device INF file, as shown below. To preallocate eight unidirectional buffers, add these lines:
; Host-to-device DMA buffer:
HKR,, "DmaToDeviceCount",0x00010001,0x04       ; Number of preallocated DMA_TO_DEVICE buffers 
HKR,, "DmaToDeviceBytes",0x00010001,0x100000   ; Buffer size, in bytes
HKR,, "DmaToDeviceOptions",0x00010001,0x41     ; DMA flags (0x40=DMA_TO_DEVICE
                                               ; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
                
; Device-to-host DMA buffer:
HKR,, "DmaFromDeviceCount",0x00010001,0x04     ; Number of preallocated DMA_FROM_DEVICE buffers 
HKR,, "DmaFromDeviceBytes",0x00010001,0x100000 ; Buffer size, in bytes
HKR,, "DmaFromDeviceOptions",0x00010001,0x21   ; DMA flags (0x20=DMA_FROM_DEVICE
                                               ; + 0x1=DMA_KERNEL_BUFFER_ALLOC)
NOTE
  • "DmaFromDeviceCount" and "DmaFromDeviceCount" values are supported from version 12.4.0. If those values aren’t set value of 1 will be assumed.
    In older WinDriver versions those values are ignored and a single buffer will be pre-allocated.
  • The wizard-generated and relevant sample WinDriver device INF files already contain the unidirectional buffers configuration lines, so you only need to remove the comment indicator (‘;’) at the start of each line.
  • The examples are for configuring preallocation of 8 DMA buffers (4 for each direction), but you may, of-course, select to preallocate just one buffer (or none at all, by leaving the above code commented out).

2. Edit the buffer sizes and add flags to the options masks in the INF file, as needed. Note, however, that the direction flags and the DMA_KERNEL_BUFFER_ALLOC flag must be set as shown in Step 1.

NOTE
The supported WinDriver DMA flags are documented in the WinDriver PCI User’s Manual. To locate the relevant flag values to set in the INF file, look for the flag definitions in the<WinDriver directory>\include\windrvr.h file; (look for the enum that contains the DMA_KERNEL_BUFFER_ALLOC flag).

 

3. In your code, the first call or the first two calls (if you configured the INF file to preallocate two DMA buffers) to the contiguous-DMA-lock function — WDC_DMAContigBufLock() or the low-level WD_DMALock() function — should set parameter values that match the buffer configurations in the INF file:

  • For a device-to-host buffer, the DMA-options mask parameter (dwOptions / pDma->dwOptions) should contain the same DMA flags set in the DmaFromDeviceOptions registry key value, and the buffer-size parameter (dwDMABufSize / pDma->dwBytes) should be set to the value of the DmaFromDeviceBytes registry key value.
  • For a host-to-device buffer, the DMA-options mask parameter (dwOptions / pDma->dwOptions) should contain the same flags set in the DmaToDeviceOptions registry key value, and the buffer-size parameter (dwDMABufSize / pDma->dwBytes) should be set to the value of the DmaToDeviceBytes registry key value.

NOTE

  • In calls to WDC_DMAContigBufLock(), the DMA configuration information is provided via dedicated function parameters — dwDMABufSize and dwOptions.
    In calls to WD_DMALock(), the information is provided within the fields of the WD_DMA struct pointed to by the pDma parameter — pDma->dwBytes and pDma->dwOptions.
  • When using WDC_DMAContigBufLock(), the DMA_KERNEL_BUFFER_ALLOC flag is automatically set by the function, so you do not need to set it explicitly in the DMA-options mask parameter (as you do when using the low-level WD_DMALock() function), even though it is set in the INF-file configuration.
  • If the buffer preallocation fails due to insufficient resources, you may need to increase the size of the non-paged pool (from which the memory is allocated), as explained in Technical Document #58.

Back To Top

Technical Document #47: Does WinDriver support Scatter/Gather DMA on Linux?

Yes. Beginning with version 5.2.0 of WinDriver you can use WD_DMALock() to perform Scatter/Gather DMA on Linux as well.
This support is currently afforded for the supported 2.4.x and newer kernels. The 2.2.x kernels do not support Scatter/Gather DMA. You might be able to implement Scatter/Gather DMA with WinDriver with these kernels as well,