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

Question:

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()?

Asked By: Kelble

||

Answers:

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:

  • Lack of nNumberOfBytesToWrite: in C, data is passed via a (void*) pointer whose size is unknown, that’s why the argument is needed, while in Python, the buffer (char* – or bytes) size is already known (embedded into it if you will), so the argument would simply be redundant

  • Lack of lpNumberOfBytesWritten: in C, the return value is the function result status (success / failure) and the written bytes count is placed in an (output) argument, while in Python both of those values are returned by the function

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 textn"
    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:WorkDevStackOverflowq072945994]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> dir /b
code00.py

[prompt]> "e:WorkDevVEnvspy_pc064_03.09_test0Scriptspython.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
Answered By: CristiFati
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.