pythonpywin32deviceiocontrol

How do you use win32.WriteFile() the same way as Windows WriteFile API in python?


I have a PCI card that uses a pipeline handle and in order to write to its buffers I need to write to its location. I am unfortunately not a software guy but instead have the code given to me in Tcl which my team asked me to convert into Python. The Tcl scripts uses WriteFile as

BOOL WriteFile(
  HANDLE hFile,                    // handle to file to write to
  LPCVOID lpBuffer,                // pointer to data to write to file
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // pointer to number of bytes written
  LPOVERLAPPED lpOverlapped        // pointer to structure for overlapped I/O
);

While win32.WriteFile only has WriteFile(Handler, Data, Overlap).

How do I create the structure in windows WriteFile in order to use win32.WriteFile()?


Solution

  • Listing:

    1. [MS.Learn]: WriteFile function (fileapi.h)

      BOOL WriteFile(
        [in]                HANDLE       hFile,
        [in]                LPCVOID      lpBuffer,
        [in]                DWORD        nNumberOfBytesToWrite,
        [out, optional]     LPDWORD      lpNumberOfBytesWritten,
        [in, out, optional] LPOVERLAPPED lpOverlapped
      );
      
    2. [GitHub.MHammond]: win32file.WriteFile

      int, int = WriteFile(hFile, data , ol)
      

    2nd variant is a wrapper over the 1st.

    2 differences between wrapped and wrapper:

    So, the 2 functions are practically equivalent, the latter is simplified as it takes advantage of Python language features.

    Here's a trivial example.

    code00.py:

    #!/usr/bin/env python
    
    import sys
    
    import win32con as wcon
    import win32file as wfile
    
    
    def main(*argv):
        data = b"dummy text\n"
        print("Data length:", len(data))
    
        hf = wfile.CreateFile("out.txt", wcon.GENERIC_WRITE, 0, None, wcon.CREATE_ALWAYS, 0, None)
        print("Handle:", hf)
        rc, bwr = wfile.WriteFile(hf, data, None)
        print("Return code: {:d}\nBytes Written: {:d}".format(rc, bwr))
        wfile.CloseHandle(hf)
    
    
    if __name__ == "__main__":
        print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                       64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        rc = main(*sys.argv[1:])
        print("\nDone.\n")
        sys.exit(rc)
    

    Output:

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q072945994]> sopr.bat
    ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###
    
    [prompt]> dir /b
    code00.py
    
    [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" ./code00.py
    Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32
    
    Data length: 11
    Handle: <PyHANDLE:580>
    Return code: 0
    Bytes Written: 11
    
    Done.
    
    
    [prompt]> dir /b
    code00.py
    out.txt
    
    [prompt]> type out.txt
    dummy text