AIM-PIbd-32-Kurbanova-A-A/aimenv/Lib/site-packages/win32/Demos/CreateFileTransacted_MiniVersion.py
2024-10-02 22:15:59 +04:00

124 lines
3.6 KiB
Python

"""
This demonstrates the creation of miniversions of a file during a transaction.
The FSCTL_TXFS_CREATE_MINIVERSION control code saves any changes to a new
miniversion (effectively a savepoint within a transaction).
"""
import os
import struct
import win32api
import win32con
import win32file
import win32transaction
import winerror
import winioctlcon
from pywin32_testutil import str2bytes # py3k-friendly helper
def demo():
"""
Definition of buffer used with FSCTL_TXFS_CREATE_MINIVERSION:
typedef struct _TXFS_CREATE_MINIVERSION_INFO{
USHORT StructureVersion;
USHORT StructureLength;
ULONG BaseVersion;
USHORT MiniVersion;}
"""
buf_fmt = "HHLH0L" ## buffer size must include struct padding
buf_size = struct.calcsize(buf_fmt)
tempdir = win32api.GetTempPath()
tempfile = win32api.GetTempFileName(tempdir, "cft")[0]
print("Demonstrating transactions on tempfile", tempfile)
f = open(tempfile, "w")
f.write("This is original file.\n")
f.close()
trans = win32transaction.CreateTransaction(
Description="Test creating miniversions of a file"
)
hfile = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ | win32con.GENERIC_WRITE,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
)
win32file.WriteFile(hfile, str2bytes("This is first miniversion.\n"))
buf = win32file.DeviceIoControl(
hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION, None, buf_size, None
)
struct_ver, struct_len, base_ver, ver_1 = struct.unpack(buf_fmt, buf)
win32file.SetFilePointer(hfile, 0, win32con.FILE_BEGIN)
win32file.WriteFile(hfile, str2bytes("This is second miniversion!\n"))
buf = win32file.DeviceIoControl(
hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION, None, buf_size, None
)
struct_ver, struct_len, base_ver, ver_2 = struct.unpack(buf_fmt, buf)
hfile.Close()
## miniversions can't be opened with write access
hfile_0 = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
MiniVersion=base_ver,
)
print("version:", base_ver, win32file.ReadFile(hfile_0, 100))
hfile_0.Close()
hfile_1 = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
MiniVersion=ver_1,
)
print("version:", ver_1, win32file.ReadFile(hfile_1, 100))
hfile_1.Close()
hfile_2 = win32file.CreateFileW(
tempfile,
win32con.GENERIC_READ,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
None,
win32con.OPEN_EXISTING,
0,
None,
Transaction=trans,
MiniVersion=ver_2,
)
print("version:", ver_2, win32file.ReadFile(hfile_2, 100))
hfile_2.Close()
## MiniVersions are destroyed when transaction is committed or rolled back
win32transaction.CommitTransaction(trans)
os.unlink(tempfile)
if __name__ == "__main__":
# When run on CI, this fails with NOT_SUPPORTED, so don't have that cause "failure"
try:
demo()
except win32file.error as e:
if e.winerror == winerror.ERROR_NOT_SUPPORTED:
print("These features are not supported by this filesystem.")
else:
raise