BackupRead_BackupWrite.py SampleΒΆ

  1## demonstrates using BackupRead and BackupWrite to copy all of a file's data streams
  2
  3import win32file, win32api, win32con, win32security, ntsecuritycon
  4from win32com import storagecon
  5import pythoncom, pywintypes
  6import struct, traceback
  7from pywin32_testutil import str2bytes, ob2memory
  8
  9all_sd_info = (
 10    win32security.DACL_SECURITY_INFORMATION
 11    | win32security.DACL_SECURITY_INFORMATION
 12    | win32security.OWNER_SECURITY_INFORMATION
 13    | win32security.GROUP_SECURITY_INFORMATION
 14)
 15
 16tempdir = win32api.GetTempPath()
 17tempfile = win32api.GetTempFileName(tempdir, "bkr")[0]
 18outfile = win32api.GetTempFileName(tempdir, "out")[0]
 19print("Filename:", tempfile, "Output file:", outfile)
 20
 21f = open(tempfile, "w")
 22f.write("some random junk" + "x" * 100)
 23f.close()
 24
 25## add a couple of alternate data streams
 26f = open(tempfile + ":streamdata", "w")
 27f.write("data written to alternate stream" + "y" * 100)
 28f.close()
 29
 30f = open(tempfile + ":anotherstream", "w")
 31f.write("z" * 100)
 32f.close()
 33
 34## add Summary Information, which is stored as a separate stream
 35m = storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE | storagecon.STGM_DIRECT
 36pss = pythoncom.StgOpenStorageEx(
 37    tempfile, m, storagecon.STGFMT_FILE, 0, pythoncom.IID_IPropertySetStorage, None
 38)
 39ps = pss.Create(
 40    pythoncom.FMTID_SummaryInformation,
 41    pythoncom.IID_IPropertyStorage,
 42    0,
 43    storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE,
 44)
 45ps.WriteMultiple(
 46    (storagecon.PIDSI_KEYWORDS, storagecon.PIDSI_COMMENTS), ("keywords", "comments")
 47)
 48ps = None
 49pss = None
 50
 51## add a custom security descriptor to make sure we don't
 52##   get a default that would always be the same for both files in temp dir
 53new_sd = pywintypes.SECURITY_DESCRIPTOR()
 54sid = win32security.LookupAccountName("", "EveryOne")[0]
 55acl = pywintypes.ACL()
 56acl.AddAccessAllowedAce(1, win32con.GENERIC_READ, sid)
 57acl.AddAccessAllowedAce(1, ntsecuritycon.FILE_APPEND_DATA, sid)
 58acl.AddAccessAllowedAce(1, win32con.GENERIC_WRITE, sid)
 59acl.AddAccessAllowedAce(1, ntsecuritycon.FILE_ALL_ACCESS, sid)
 60
 61new_sd.SetSecurityDescriptorDacl(True, acl, False)
 62win32security.SetFileSecurity(tempfile, win32security.DACL_SECURITY_INFORMATION, new_sd)
 63
 64
 65sa = pywintypes.SECURITY_ATTRIBUTES()
 66sa.bInheritHandle = True
 67h = win32file.CreateFile(
 68    tempfile,
 69    win32con.GENERIC_ALL,
 70    win32con.FILE_SHARE_READ,
 71    sa,
 72    win32con.OPEN_EXISTING,
 73    win32file.FILE_FLAG_BACKUP_SEMANTICS,
 74    None,
 75)
 76
 77outh = win32file.CreateFile(
 78    outfile,
 79    win32con.GENERIC_ALL,
 80    win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
 81    sa,
 82    win32con.OPEN_EXISTING,
 83    win32file.FILE_FLAG_BACKUP_SEMANTICS,
 84    None,
 85)
 86
 87ctxt = 0
 88outctxt = 0
 89buf = None
 90readsize = 100
 91
 92while 1:
 93    bytes_read, buf, ctxt = win32file.BackupRead(h, readsize, buf, False, True, ctxt)
 94    if bytes_read == 0:
 95        break
 96    bytes_written, outctxt = win32file.BackupWrite(
 97        outh, bytes_read, buf, False, True, outctxt
 98    )
 99    print("Written:", bytes_written, "Context:", outctxt)
100win32file.BackupRead(h, 0, buf, True, True, ctxt)
101win32file.BackupWrite(outh, 0, str2bytes(""), True, True, outctxt)
102win32file.CloseHandle(h)
103win32file.CloseHandle(outh)
104
105assert open(tempfile).read() == open(outfile).read(), "File contents differ !"
106assert (
107    open(tempfile + ":streamdata").read() == open(outfile + ":streamdata").read()
108), "streamdata contents differ !"
109assert (
110    open(tempfile + ":anotherstream").read() == open(outfile + ":anotherstream").read()
111), "anotherstream contents differ !"
112assert (
113    ob2memory(win32security.GetFileSecurity(tempfile, all_sd_info))[:]
114    == ob2memory(win32security.GetFileSecurity(outfile, all_sd_info))[:]
115), "Security descriptors are different !"
116## also should check Summary Info programatically