Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BackupSeek_streamheaders.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. ## demonstrates using BackupSeek to enumerate data streams for a file
  2. import struct
  3. import pythoncom
  4. import pywintypes
  5. import win32api
  6. import win32con
  7. import win32file
  8. from win32com import storagecon
  9. stream_types = {
  10. win32con.BACKUP_DATA: "Standard data",
  11. win32con.BACKUP_EA_DATA: "Extended attribute data",
  12. win32con.BACKUP_SECURITY_DATA: "Security descriptor data",
  13. win32con.BACKUP_ALTERNATE_DATA: "Alternative data streams",
  14. win32con.BACKUP_LINK: "Hard link information",
  15. win32con.BACKUP_PROPERTY_DATA: "Property data",
  16. win32con.BACKUP_OBJECT_ID: "Objects identifiers",
  17. win32con.BACKUP_REPARSE_DATA: "Reparse points",
  18. win32con.BACKUP_SPARSE_BLOCK: "Sparse file",
  19. }
  20. tempdir = win32api.GetTempPath()
  21. tempfile = win32api.GetTempFileName(tempdir, "bkr")[0]
  22. print("Filename:", tempfile)
  23. f = open(tempfile, "w")
  24. f.write("some random junk" + "x" * 100)
  25. f.close()
  26. f = open(tempfile + ":streamdata", "w")
  27. f.write("data written to alternate stream" + "y" * 100)
  28. f.close()
  29. f = open(tempfile + ":anotherstream", "w")
  30. f.write("z" * 200)
  31. f.close()
  32. ## add Summary Information, which is stored as a separate stream
  33. m = storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE | storagecon.STGM_DIRECT
  34. pss = pythoncom.StgOpenStorageEx(
  35. tempfile, m, storagecon.STGFMT_FILE, 0, pythoncom.IID_IPropertySetStorage, None
  36. )
  37. ps = pss.Create(
  38. pythoncom.FMTID_SummaryInformation,
  39. pythoncom.IID_IPropertyStorage,
  40. 0,
  41. storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE,
  42. )
  43. ps.WriteMultiple(
  44. (storagecon.PIDSI_KEYWORDS, storagecon.PIDSI_COMMENTS), ("keywords", "comments")
  45. )
  46. ps = None
  47. pss = None
  48. sa = pywintypes.SECURITY_ATTRIBUTES()
  49. sa.bInheritHandle = False
  50. h = win32file.CreateFile(
  51. tempfile,
  52. win32con.GENERIC_ALL,
  53. win32con.FILE_SHARE_READ,
  54. sa,
  55. win32con.OPEN_EXISTING,
  56. win32file.FILE_FLAG_BACKUP_SEMANTICS,
  57. None,
  58. )
  59. """ stream header:
  60. typedef struct _WIN32_STREAM_ID {
  61. DWORD dwStreamId; DWORD dwStreamAttributes; LARGE_INTEGER Size;
  62. DWORD dwStreamNameSize; WCHAR cStreamName[ANYSIZE_ARRAY];
  63. }
  64. """
  65. win32_stream_id_format = "LLQL"
  66. win32_stream_id_size = struct.calcsize(win32_stream_id_format)
  67. def parse_stream_header(h, ctxt, data):
  68. stream_type, stream_attributes, stream_size, stream_name_size = struct.unpack(
  69. win32_stream_id_format, data
  70. )
  71. print(
  72. "\nType:",
  73. stream_type,
  74. stream_types[stream_type],
  75. "Attributes:",
  76. stream_attributes,
  77. "Size:",
  78. stream_size,
  79. "Name len:",
  80. stream_name_size,
  81. )
  82. if stream_name_size > 0:
  83. ## ??? sdk says this size is in characters, but it appears to be number of bytes ???
  84. bytes_read, stream_name_buf, ctxt = win32file.BackupRead(
  85. h, stream_name_size, None, False, True, ctxt
  86. )
  87. stream_name = pywintypes.UnicodeFromRaw(stream_name_buf[:])
  88. else:
  89. stream_name = "Unnamed"
  90. print("Name:" + stream_name)
  91. return (
  92. ctxt,
  93. stream_type,
  94. stream_attributes,
  95. stream_size,
  96. stream_name_size,
  97. stream_name,
  98. )
  99. ctxt = 0
  100. win32_stream_id_buf = (
  101. None ## gets rebound to a writable buffer on first call and reused
  102. )
  103. while 1:
  104. bytes_read, win32_stream_id_buf, ctxt = win32file.BackupRead(
  105. h, win32_stream_id_size, win32_stream_id_buf, False, True, ctxt
  106. )
  107. if bytes_read == 0:
  108. break
  109. (
  110. ctxt,
  111. stream_type,
  112. stream_attributes,
  113. stream_size,
  114. stream_name_size,
  115. stream_name,
  116. ) = parse_stream_header(h, ctxt, win32_stream_id_buf[:])
  117. if stream_size > 0:
  118. bytes_moved = win32file.BackupSeek(h, stream_size, ctxt)
  119. print("Moved: ", bytes_moved)
  120. win32file.BackupRead(h, win32_stream_id_size, win32_stream_id_buf, True, True, ctxt)
  121. win32file.CloseHandle(h)