The names, they are a changin' (and some code is changin' too!).
Another topic of discussion floating around regarding the WDF Hybrid 1394 Virtual Device Driver sample has been what changes were made to the test executable, WIN1394.exe. Well first thing, I changed the name for the EXE included with my sample. There was some naming confusion because the WinUSB component is so widely used in UMDF samples (and other drivers) and some people were equating Win1394 with WinUSB which isn't the case at all. So voila, WDF1394.exe is born.
Next up was to make the changes to some actual code. The WDM sample executable uses exported functions within a DLL (1394api.dll). That DLL then manages submitting and receiving results from the resulting DeviceIoControl call.
For a quick compare and contrast, the current sample executable (win1394.exe) will submit requests by calling the exported function from 1394api.dll,
dwRet = AsyncRead( hWnd,
szDeviceName,
&asyncRead,
TRUE
);
where the function in 1394api.dll handles the actual submission of the request.
hDevice = OpenDevice(hWnd, szDeviceName, FALSE);
if (hDevice != INVALID_HANDLE_VALUE) {
dwRet = DeviceIoControl( hDevice,
IOCTL_ASYNC_READ,
pAsyncRead,
ulBufferSize,
pAsyncRead,
ulBufferSize,
&dwBytesRet,
NULL
);
if (!dwRet) {
dwRet = GetLastError();
TRACE(TL_ERROR, (hWnd, "Error = 0x%x\r\n", dwRet));
}
As a result, there is essentially a function exported from 1394api.dll for every IOCTL in the WDM 1394vdev sample.
For the WDF Hybrid Sample, we can change around quite a bit of this code. Yes there are still the same number of binaries comprising the full sample. And there is still a DLL in the package, but the functionality of that DLL has changed significantly, it's a driver now, and we can treat it as such. Now the resulting executible doesn't have to include libraries or worry about DLL location or...you get the picture. ;)
So to replicate the above sequence in the WDF Hybrid Sample, the executable becomes the sole controller of its own requests. It will call a simple utility routine within WDF1394.exe that then manages the DeviceIoControl call.
dwRet = SendRequest (
IOCTL_ASYNC_READ,
asyncRead,
ulBufferSize,
asyncRead,
ulBufferSize,
&bytesTransferred);
if (ERROR_SUCCESS != dwRet)
{
TRACE (TL_WARNING, (hWnd, "Failed SendRequest %d\n", dwRet));
}
Here the SendRequest function simply calls DeviceIoControl w/ the supplied parameters. I'm also going to use a globally held file handle for the driver stack which was opened at the time the user selected a driver to test against.
DWORD
SendRequest (
IN DWORD Ioctl,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT ULONG OutputBufferSize,
IN OUT LPDWORD bytesReturned)
{
if (!DeviceIoControl (
g_hTestDevice,
Ioctl,
InputBuffer,
InputBufferSize,
OutputBuffer,
OutputBufferSize,
bytesReturned,
NULL))
{
return GetLastError();
}
return ERROR_SUCCESS;
}
Hurrah! Now the request is submitted directly to the driver stack from the executable. And at the top of that driver stack is a UMDF driver, umdf1394vdev.dll. And that driver not only replaces 1394api.dll it includes some functionality migrated out of the kernel mode driver.
So while it may not look like a great deal of earth shattering code changes here, underneath the bonnet UMDF has allowed all that traditional DLL usage infrastructure to disappear, which I like. But that's just how I am... ;)
As always, feel free to fire off any questions, comments or complaints.
*Currently Playing - Beethoven, Symphony No. 7 in A Major