def parse_stream_header(h, ctxt, data): stream_type, stream_attributes, stream_size, stream_name_size = struct.unpack( win32_stream_id_format, data) print( "\nType:", stream_type, stream_types[stream_type], "Attributes:", stream_attributes, "Size:", stream_size, "Name len:", stream_name_size, ) if stream_name_size > 0: ## ??? sdk says this size is in characters, but it appears to be number of bytes ??? bytes_read, stream_name_buf, ctxt = win32file.BackupRead( h, stream_name_size, None, False, True, ctxt) stream_name = pywintypes.UnicodeFromRaw(stream_name_buf[:]) else: stream_name = "Unnamed" print("Name:" + stream_name) return ( ctxt, stream_type, stream_attributes, stream_size, stream_name_size, stream_name, )
h = win32file.CreateFile(tempfile, win32con.GENERIC_ALL, win32con.FILE_SHARE_READ, sa, win32con.OPEN_EXISTING, win32file.FILE_FLAG_BACKUP_SEMANTICS, None) outh = win32file.CreateFile( outfile, win32con.GENERIC_ALL, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, sa, win32con.OPEN_EXISTING, win32file.FILE_FLAG_BACKUP_SEMANTICS, None) ctxt = 0 outctxt = 0 buf = None readsize = 100 while 1: bytes_read, buf, ctxt = win32file.BackupRead(h, readsize, buf, False, True, ctxt) if bytes_read == 0: break bytes_written, outctxt = win32file.BackupWrite(outh, bytes_read, buf, False, True, outctxt) print('Written:', bytes_written, 'Context:', outctxt) win32file.BackupRead(h, 0, buf, True, True, ctxt) win32file.BackupWrite(outh, 0, str2bytes(''), True, True, outctxt) win32file.CloseHandle(h) win32file.CloseHandle(outh) assert open(tempfile).read() == open(outfile).read(), "File contents differ !" assert open(tempfile + ':streamdata').read() == open( outfile + ':streamdata').read(), "streamdata contents differ !" assert open(tempfile + ':anotherstream').read() == open( outfile + ':anotherstream').read(), "anotherstream contents differ !"
win32_stream_id_format="LLQL" win32_stream_id_size=struct.calcsize(win32_stream_id_format) def parse_stream_header(h,ctxt,data): stream_type, stream_attributes, stream_size, stream_name_size=struct.unpack(win32_stream_id_format,data) print('\nType:',stream_type,stream_types[stream_type], 'Attributes:', stream_attributes, 'Size:', stream_size, 'Name len:',stream_name_size) if stream_name_size>0: ## ??? sdk says this size is in characters, but it appears to be number of bytes ??? bytes_read, stream_name_buf, ctxt=win32file.BackupRead(h, stream_name_size, None, False, True, ctxt) stream_name=pywintypes.UnicodeFromRaw(stream_name_buf[:]) else: stream_name='Unnamed' print('Name:'+stream_name) return ctxt, stream_type, stream_attributes, stream_size, stream_name_size, stream_name ctxt=0 win32_stream_id_buf=None ## gets rebound to a writable buffer on first call and reused while 1: bytes_read, win32_stream_id_buf, ctxt=win32file.BackupRead(h, win32_stream_id_size, win32_stream_id_buf, False, True, ctxt) if bytes_read==0: break ctxt, stream_type, stream_attributes, stream_size, stream_name_size, stream_name=\ parse_stream_header(h, ctxt, win32_stream_id_buf[:]) if stream_size>0: bytes_moved=win32file.BackupSeek(h, stream_size, ctxt) print('Moved: ',bytes_moved) win32file.BackupRead(h, win32_stream_id_size, win32_stream_id_buf, True, True, ctxt) win32file.CloseHandle(h)