CreateFileTransacted_MiniVersion.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. """
  2. This demonstrates the creation of miniversions of a file during a transaction.
  3. The FSCTL_TXFS_CREATE_MINIVERSION control code saves any changes to a new
  4. miniversion (effectively a savepoint within a transaction).
  5. """
  6. import win32file, win32api, win32transaction, winerror
  7. import win32con, winioctlcon
  8. import struct
  9. import os
  10. from pywin32_testutil import str2bytes # py3k-friendly helper
  11. def demo():
  12. """
  13. Definition of buffer used with FSCTL_TXFS_CREATE_MINIVERSION:
  14. typedef struct _TXFS_CREATE_MINIVERSION_INFO{
  15. USHORT StructureVersion;
  16. USHORT StructureLength;
  17. ULONG BaseVersion;
  18. USHORT MiniVersion;}
  19. """
  20. buf_fmt='HHLH0L' ## buffer size must include struct padding
  21. buf_size=struct.calcsize(buf_fmt)
  22. tempdir=win32api.GetTempPath()
  23. tempfile=win32api.GetTempFileName(tempdir,'cft')[0]
  24. print("Demonstrating transactions on tempfile", tempfile)
  25. f=open(tempfile,'w')
  26. f.write('This is original file.\n')
  27. f.close()
  28. trans=win32transaction.CreateTransaction(Description='Test creating miniversions of a file')
  29. hfile=win32file.CreateFileW(tempfile, win32con.GENERIC_READ|win32con.GENERIC_WRITE,
  30. win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
  31. None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans)
  32. win32file.WriteFile(hfile, str2bytes('This is first miniversion.\n'))
  33. buf=win32file.DeviceIoControl(hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION,None,buf_size,None)
  34. struct_ver, struct_len, base_ver, ver_1=struct.unpack(buf_fmt, buf)
  35. win32file.SetFilePointer(hfile, 0, win32con.FILE_BEGIN)
  36. win32file.WriteFile(hfile, str2bytes('This is second miniversion!\n'))
  37. buf=win32file.DeviceIoControl(hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION,None,buf_size,None)
  38. struct_ver, struct_len, base_ver, ver_2=struct.unpack(buf_fmt, buf)
  39. hfile.Close()
  40. ## miniversions can't be opened with write access
  41. hfile_0=win32file.CreateFileW(tempfile, win32con.GENERIC_READ,
  42. win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
  43. None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans, MiniVersion=base_ver)
  44. print('version:',base_ver,win32file.ReadFile(hfile_0, 100))
  45. hfile_0.Close()
  46. hfile_1=win32file.CreateFileW(tempfile, win32con.GENERIC_READ,
  47. win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
  48. None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans, MiniVersion=ver_1)
  49. print('version:',ver_1,win32file.ReadFile(hfile_1, 100))
  50. hfile_1.Close()
  51. hfile_2=win32file.CreateFileW(tempfile, win32con.GENERIC_READ,
  52. win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
  53. None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans, MiniVersion=ver_2)
  54. print('version:',ver_2,win32file.ReadFile(hfile_2, 100))
  55. hfile_2.Close()
  56. ## MiniVersions are destroyed when transaction is committed or rolled back
  57. win32transaction.CommitTransaction(trans)
  58. os.unlink(tempfile)
  59. if __name__ == "__main__":
  60. # When run on CI, this fails with NOT_SUPPORTED, so don't have that cause "failure"
  61. try:
  62. demo()
  63. except win32file.error as e:
  64. if e.winerror == winerror.ERROR_NOT_SUPPORTED:
  65. print("These features are not supported by this filesystem.")
  66. else:
  67. raise