Subject: General Question - support for Windows DDKs, specifically SPTI
From: Jack Woychowski <[email-masked]>
To: "[email-masked]'" <[email-masked]>
Cc: Jack Woychowski <[email-masked]>, "[email-masked]'" <[email-masked]>
Date: Fri, 4 Oct 2002 16:05:10 -0700

Hi folks - hope I'm not wasting anybody's bandwith here, but
I've spent quite some time trapsing through docs and archives and
source code and haven't come up with a lot of answers and just
a little insight. (If yer busy, you may want to skip to the
end - between here and there simply lies a verbose description 
of why I'm asking those questions - or perhaps it's a bit of 
venting. :-)

My goal is to make use of the SCSI Pass-thru Interface on Windows
(SPTI) from programs compiled in and running within the Cygwin 
environment. (I'm a U*x-type programmer, and this stuff will be
ported to many different OSs - Solaris, Linux, Digital Unix, as 
well as Windows NT, 2k and XP (and who knows what others :-). So,
I wanted to use cygwin to "protect" my fairly simple source code
from the, um, "intricacies" of having common code betwixt Windows
and Unix.) My initial take was to (somehow) recreate the appropriate
structures and values and simply call ioctl() after opening
the SCSI device. Needless to say, after seeing what ioctl actually
boiled down to in this case (in fhandler.cc), I saw this approach wasn't 
going to work well.

(That actually makes sence to me - ioctl() doesn't map very well to
DeviceIoControl, with things appearantly being bi-direction in the
Windows side.)

So, my next take was to actually use CreateDevice() and DeviceIoControl()
within my code; and, lo and behold, it actually compiled and ran. (Whee!)
However, once I established that fact, I went on to try and include
the SPTI structure and ioctl definitions, which seeming are not covered
in the cygwin headers (or, at least, not completely ...) This got me
into the Windows DDK mess - who knows which ones (NT DDK, Win2k DDK, MEDDK,
ack!) are supported on which platform, and they disagree is a lot of places,
and they're all turning into the "Windows DDK" this month, anyway 
(which purportedly works for all platforms; I'm thinking it's more 
like moving all the problems under one include directory, but what do 
I know. :-)

In any case, the amount of success I have depends entirely on which 
headers I include from which DDK on whatever plaform I happen to be
on at the moment. I had managed to craft things such that I could 
#include files for the IOCTL_SCSI_GET_ADDRESS ioctl to work on NT 
4.0 (using the NT DDK) and on WinXP (sing the Win2K DDK). (This feat 
worked 'cuz all that's needed are NTDDSCSI.H - from the DDK - and 
winioctl.h, from cygwin.)

I then moved on to try the IOCTL_GET_DEVICE_NUMBER - not so good.
On NT, the fault lies with the NT DDK - the STORAGE_DEVICE_NUMBER
structure isn't defined anywhere. After I crafted my own, it seemed 
to work (or at least compile.) On WinXP/W2KDDK, I ran into a 
different problem: including NTDDSTOR.H, where the 
STORAGE_DEVICE_NUMBER is defined, causes a redefinition of the
PREVENT_MEDIA_REMOVAL structure, which I was surprised to find was 
defined in a cygwin header! (/usr/include/w32api/winioctl.h, to be 
precise.)

It is now pretty clear to me that there is some very limited support
in cygwin for "standard" Windows device interfaces like the SPTI 
(although the word "standard" doesn't belong anywhere near Windows -
their different DDKs don't support or define the same things!) Now,
I'm quite sure I can get this all to work by crafting my own headers,
essentially translating what I need from whichever DDK seems to be
working at the time; heck, I could even try to write a script to
do it. (That leaves me a bit at the mercy of changes in the
DDK headers; every time it changes, I have to recraft my headers.
Not that cygwin would be in a different boat ...) But this (finally!)
leads to my questions: 

(1) To what extent does the cygwin environment intend to support 
    interfaces like SPTI, if at all, within it's own compilation 
    environment? Having PREVENT_MEDIA_REMOVAL in there implies some 
    kind of support for DDK interfaces, but was it done to the end 
    of supporting a larger interface definition, or simply to get 
    "what's needed now" into cygwin?

(2) Is my use of DeviceIoControl() and CreateDevice() "the right way 
    to do it"? The ease by which I could do it (besides the SPTI and 
    structure mess) seemed to imply to me such use of (some) Windows 
    API functions mixed in with my other "pure unix" code is supported,
    though there's not a lot said in the documentation about it... or 
    is it "more correct" to (for example) have a different kind of 
    filehandler that supports the ioctl() interface more completely? 
    (But, if so, does that mean recreating all the SPTI headers when 
    this handler is built?) This is more philosophical than practical,
    I guess, but I'm interested in understanding the "larger intent"
    in these kind of areas.

Thanks, in advance, for any light that can be shed on the topic ...

-- Woof

+------------------------------------------------------------+ 
| Jack Woychowski       \_\        /Virtualization Architect |
| Nishan Systems, Inc     \\      //                         |
| [email-masked]   \\//\\//oof!                      |
+---------------------------\/--\/---------------------------+
| Yow!-Zippy-Says: Are we CONSING yet?                       |
+------------------------------------------------------------+

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/