BackupRead_BackupWrite.py 3.5 KB

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