[python-win32] USB access using win32file.deviceIOcontrol

Tim Roberts timr at probo.com
Wed Dec 12 22:20:33 CET 2007


Sebastian Friebe wrote:
> That's exactly my problem.
> I know there are some pointers in the C++ structure pointing to the
> data inside the structure. But I don't have an idea at all, how to
> port it to Python.
>
> Could you give me an example of a very basic SCSI command, like the
> TEST_UNIT_READY ?
>   

I'm afraid I can't.  I write Windows drivers for a living, so I do an
awful lot of DeviceIoControl calls, but so far we have managed to avoid
working the disk arena.

> I didn't know if it would work, so I
> started with a very strait forward approach.
> I extracted the content of the SCSI_PASS_THROUGH in my C++ example
> into a array of bytes.
> I included the byte stream I found into my byte_list.
> e.g.
>     SCSI_TEST_UNIT_READY=[0x2C,0x00,0x00,0x00,0x01,0x00,0x06,0x18,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
>                           0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
>                           0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
>                           0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
>                           0x00,0x00,0x00,0x00]
>   

The length says 0x2C, which is 44 decimal, but unless I have miscounted,
there are 0x44 bytes of data there, which is 64 decimal.

>     byte_list = SCSI_TEST_UNIT_READY
>
> If the basic functionality is proven, I planned to go for a more
> object oriented approach like:
>
>  class SCSI_PASS_THROUGH_DIRECT(object):
>     def __init__(self, cdbLength = 16, transfer_length, transfer_direction):
>         self.Length             =   0                      #    USHORT Length;
>         self.ScsiStatus         =   0                      #    UCHAR ScsiStatus;
>   

I'm afraid that you will end up battling against the language here.  I
have three possible suggestions for you.

1. Consider using ctypes.

ctypes includes mechanisms where you can build up C structures in a
Pythonic way, almost exactly like you have done here.

2. Consider using SWIG.

Swig will allow you to build a C or C++ DLL that can be called directly
from Python.  You could hide the pointer ugliness inside the C code, and
still wrap it with a Python class.  Swig is extraordinarily powerful,
although there is a bit of a learning curve if you need to do anything
unusual.  There are lots of good example, however.

3. Consider using boost.python.

If you know C++, the Boost libraries include a very good set of template
classes that let you build Python object in C++ in a more natural way. 
Like option 2, this would let you put the sticky parts in C++ and the
fun parts in Python.

-- 
Tim Roberts, timr at probo.com
Providenza & Boekelheide, Inc.



More information about the python-win32 mailing list