def testFilePointer(self): # via [ 979270 ] SetFilePointer fails with negative offset # Create a file in the %TEMP% directory. filename = os.path.join(win32api.GetTempPath(), "win32filetest.dat") f = win32file.CreateFile( filename, win32file.GENERIC_READ | win32file.GENERIC_WRITE, 0, None, win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, 0) try: #Write some data data = str2bytes('Some data') (res, written) = win32file.WriteFile(f, data) self.failIf(res) self.assertEqual(written, len(data)) #Move at the beginning and read the data win32file.SetFilePointer(f, 0, win32file.FILE_BEGIN) (res, s) = win32file.ReadFile(f, len(data)) self.failIf(res) self.assertEqual(s, data) #Move at the end and read the data win32file.SetFilePointer(f, -len(data), win32file.FILE_END) (res, s) = win32file.ReadFile(f, len(data)) self.failIf(res) self.failUnlessEqual(s, data) finally: f.Close() os.unlink(filename)
def _sparse_magic(handle, length=0): win32file.DeviceIoControl(handle, FSCTL_SET_SPARSE, '', 0, None) win32file.SetFilePointer(handle, length, win32file.FILE_BEGIN) win32file.SetEndOfFile(handle) win32file.SetFilePointer(handle, 0, win32file.FILE_BEGIN)
def testMoreFiles(self): # Create a file in the %TEMP% directory. testName = os.path.join(win32api.GetTempPath(), "win32filetest.dat") desiredAccess = win32file.GENERIC_READ | win32file.GENERIC_WRITE # Set a flag to delete the file automatically when it is closed. fileFlags = win32file.FILE_FLAG_DELETE_ON_CLOSE h = win32file.CreateFile(testName, desiredAccess, win32file.FILE_SHARE_READ, None, win32file.CREATE_ALWAYS, fileFlags, 0) # Write a known number of bytes to the file. data = "z" * 1025 win32file.WriteFile(h, data) self.failUnless( win32file.GetFileSize(h) == len(data), "WARNING: Written file does not have the same size as the length of the data in it!" ) # Ensure we can read the data back. win32file.SetFilePointer(h, 0, win32file.FILE_BEGIN) hr, read_data = win32file.ReadFile(h, len(data) + 10) # + 10 to get anything extra self.failUnless(hr == 0, "Readfile returned %d" % hr) self.failUnless(read_data == data, "Read data is not what we wrote!") # Now truncate the file at 1/2 its existing size. newSize = len(data) / 2 win32file.SetFilePointer(h, newSize, win32file.FILE_BEGIN) win32file.SetEndOfFile(h) self.failUnless( win32file.GetFileSize(h) == newSize, "Truncated file does not have the expected size!") # GetFileAttributesEx/GetFileAttributesExW tests. self.failUnless( win32file.GetFileAttributesEx( testName) == win32file.GetFileAttributesExW(testName), "ERROR: Expected GetFileAttributesEx and GetFileAttributesExW to return the same data" ) attr, ct, at, wt, size = win32file.GetFileAttributesEx(testName) self.failUnless( size == newSize, "Expected GetFileAttributesEx to return the same size as GetFileSize()" ) self.failUnless( attr == win32file.GetFileAttributes(testName), "Expected GetFileAttributesEx to return the same attributes as GetFileAttributes" ) h = None # Close the file by removing the last reference to the handle! self.failUnless(not os.path.isfile(testName), "After closing the file, it still exists!")
def _WriteRemains(self): ''' write buffer remains data ''' win32file.SetFilePointer(self._file, 0x400, win32file.FILE_BEGIN) data = win32file.ReadFile(self._file, 512, None) remains = len(self._data) if (remains == 0): return buffer = bytearray(self._blockSize) win32file.SetFilePointer(self._file, self._position, win32file.FILE_BEGIN) result = win32file.ReadFile(self._file, buffer, None) win32file.SetFilePointer(self._file, self._position, win32file.FILE_BEGIN) buffer[0:remains] = self._data[0:len(self._data)] win32file.WriteFile(self._file, buffer, None)
def may_send_newlines(self): self.raise_if_notarget() self.ldebug("may_send_newlines") # skip if no newlines file_pos = self.get_file_pos() sent_pos = self.get_sent_pos() self.ldebug("file_pos {}, sent_pos {}".format(file_pos, sent_pos)) if sent_pos >= file_pos: if sent_pos > file_pos: self.lerror("sent_pos {} > file_pos {}. pos" " mismatch".format(sent_pos, file_pos)) if self.elatest: raise LatestFileChanged() return 0 # move to last sent pos with OpenNoLock(self.target_path) as fh: win32file.SetFilePointer(fh, sent_pos, win32file.FILE_BEGIN) # read file to the end lines, rbytes = self._read_target_to_end(fh) scnt = 0 self.ldebug(1, "sent_pos {} file_pos {} rbytes " "{}".format(sent_pos, file_pos, rbytes)) if rbytes > 0: scnt = self._may_send_newlines(lines, rbytes, scnt, file_path=self.target_path) self.save_sent_pos(sent_pos + rbytes) return scnt
def copy_path_to(self, path, dest): import win32file handle = None for p, h in iteritems(self.handle_map): if samefile_windows(path, p): handle = h break if handle is None: if os.path.exists(path): raise ValueError('The file %r did not exist when this move' ' operation was started'%path) else: raise ValueError('The file %r does not exist'%path) try: windows_hardlink(path, dest) return except: pass win32file.SetFilePointer(handle, 0, win32file.FILE_BEGIN) with lopen(dest, 'wb') as f: while True: hr, raw = win32file.ReadFile(handle, 1024*1024) if hr != 0: raise IOError(hr, 'Error while reading from %r'%path) if not raw: break f.write(raw)
def truncate(self, pos=0): try: win32file.SetFilePointer(self.handle, int(pos), win32file.FILE_BEGIN) win32file.SetEndOfFile(self.handle) except pywintypes.error, err: raise WinIOError(err)
def _tell(self): # type: () -> int """Get current real position.""" if not self.handle: self.handle = self.get_handle() return win32file.SetFilePointer(self.handle, 0, win32file.FILE_CURRENT) # type: ignore
def read(self, size): if size < 512: size = 512 pos = win32file.SetFilePointer(self.handle, 0, win32file.FILE_CURRENT) if pos + size > self.size: size = self.size - pos return win32file.ReadFile(self.handle, size)[1]
def __getMFT(self, index=0): fd = self.config['fd'] bss = self.config['bss'] mft_offset = bss.bytes_per_sector() * bss.sectors_per_cluster( ) * bss.start_c_mft() win32file.SetFilePointer(fd, mft_offset + (index * 0x400), win32file.FILE_BEGIN) buf = win32file.ReadFile(fd, 0x400)[1] record = MFTRecord(buf, 0, None) ret = {} attribute = record.data_attribute() cnt = 0 for offset, length in attribute.runlist().runs(): if length > 16 and (length % 16) > 0: if offset == 0: # may be sparse section at end of Compression Signature ret[cnt] = (offset, length % 16) length -= length % 16 cnt += 1 else: #may be compressed data section at start of Compression Signature ret[cnt] = (offset, length - length % 16) offset += length - length % 16 length = length % 16 cnt += 1 #just normal or sparse data ret[cnt] = (offset, length) cnt += 1 return ret
def DumpWithRead(self, output_filename): """Read the image and write all the data to a raw file.""" with open(output_filename, "wb") as outfd: offset = 0 for start, length in self.runs: if start > offset: print "\nPadding from 0x%X to 0x%X\n" % (offset, start) self.PadWithNulls(outfd, start - offset) offset = start end = start + length while offset < end: to_read = min(self.buffer_size, end - offset) win32file.SetFilePointer(self.fd, offset, 0) _, data = win32file.ReadFile(self.fd, to_read) outfd.write(data) offset += to_read offset_in_mb = offset / 1024 / 1024 if not offset_in_mb % 50: sys.stdout.write("\n%04dMB\t" % offset_in_mb) sys.stdout.write(".") sys.stdout.flush()
def write_data(self, new_xml_data): if not self.check_file_handler_status(): return False win32file.SetFilePointer(self.file_handler, 0, win32file.FILE_BEGIN) win32file.SetEndOfFile(self.file_handler) errCode, nBytesWritten = win32file.WriteFile(self.file_handler, new_xml_data) return nBytesWritten == len(new_xml_data)
def seek(self, amt, frm=0): import win32file as w if frm not in (0, 1, 2): raise ValueError('Invalid from for seek: %s' % frm) frm = {0: w.FILE_BEGIN, 1: w.FILE_CURRENT, 2: w.FILE_END}[frm] if frm is w.FILE_END: amt = 0 - amt w.SetFilePointer(self._handle, amt, frm)
def read(self, offset, length): try: win32file.SetFilePointer(self.fhandle, offset, 0) _, data = win32file.ReadFile(self.fhandle, length) except Exception: return addrspace.ZEROER.GetZeros(length) return data
def demo(): """ Definition of buffer used with FSCTL_TXFS_CREATE_MINIVERSION: typedef struct _TXFS_CREATE_MINIVERSION_INFO{ USHORT StructureVersion; USHORT StructureLength; ULONG BaseVersion; USHORT MiniVersion;} """ buf_fmt='HHLH0L' ## buffer size must include struct padding buf_size=struct.calcsize(buf_fmt) tempdir=win32api.GetTempPath() tempfile=win32api.GetTempFileName(tempdir,'cft')[0] print("Demonstrating transactions on tempfile", tempfile) f=open(tempfile,'w') f.write('This is original file.\n') f.close() trans=win32transaction.CreateTransaction(Description='Test creating miniversions of a file') hfile=win32file.CreateFileW(tempfile, win32con.GENERIC_READ|win32con.GENERIC_WRITE, win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE, None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans) win32file.WriteFile(hfile, str2bytes('This is first miniversion.\n')) buf=win32file.DeviceIoControl(hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION,None,buf_size,None) struct_ver, struct_len, base_ver, ver_1=struct.unpack(buf_fmt, buf) win32file.SetFilePointer(hfile, 0, win32con.FILE_BEGIN) win32file.WriteFile(hfile, str2bytes('This is second miniversion!\n')) buf=win32file.DeviceIoControl(hfile, winioctlcon.FSCTL_TXFS_CREATE_MINIVERSION,None,buf_size,None) struct_ver, struct_len, base_ver, ver_2=struct.unpack(buf_fmt, buf) hfile.Close() ## miniversions can't be opened with write access hfile_0=win32file.CreateFileW(tempfile, win32con.GENERIC_READ, win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE, None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans, MiniVersion=base_ver) print('version:',base_ver,win32file.ReadFile(hfile_0, 100)) hfile_0.Close() hfile_1=win32file.CreateFileW(tempfile, win32con.GENERIC_READ, win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE, None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans, MiniVersion=ver_1) print('version:',ver_1,win32file.ReadFile(hfile_1, 100)) hfile_1.Close() hfile_2=win32file.CreateFileW(tempfile, win32con.GENERIC_READ, win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE, None, win32con.OPEN_EXISTING, 0 , None, Transaction=trans, MiniVersion=ver_2) print('version:',ver_2,win32file.ReadFile(hfile_2, 100)) hfile_2.Close() ## MiniVersions are destroyed when transaction is committed or rolled back win32transaction.CommitTransaction(trans) os.unlink(tempfile)
def __getFile(self, mft_file_object): fd = self.config['fd'] bpc = self.config['bss'].bytes_per_cluster buf = self.__calcOffset(mft_file_object[0]) if buf == None: raise Exception("Failed to process mft_offset") try: record = MFTRecord(buf, 0, None) for attribute in record.attributes(): if attribute.type() == ATTR_TYPE.DATA: fullpath = self.config['outputdir'] + self.config[ 'current_file'] if self.config['is_dir'] == True: fullpath += os.sep + mft_file_object[1] logging.debug("GetFile:: fullpath %s" % fullpath) logging.debug("GetFile:: attributes %s" % attribute.get_all_string()) path = '\\'.join(fullpath.split('\\')[:-1]) if not os.path.isdir(path): os.makedirs(path) fd2 = open(fullpath, 'wb') logging.debug("non_resident %r" % attribute.non_resident()) if attribute.non_resident() == 0: fd2.write(attribute.value()) else: cnt = 0 padd = False for cluster_offset, length in attribute.runlist().runs( ): # logging.debug("GetFile:: cluster_offset( %08x ) lenght( %08x ) " % ( cluster_offset, length)) read_sz = length * bpc # logging.debug("readsize %08x cnt %08x init_sz %08x" % ( read_sz, cnt, attribute.initialized_size())) if read_sz + cnt > attribute.initialized_size(): read_sz = attribute.initialized_size() - cnt padd = True # logging.debug("readsize %08x cnt %08x init_sz %08x" % ( read_sz, cnt, attribute.initialized_size())) offset = cluster_offset * bpc win32file.SetFilePointer(fd, offset, win32file.FILE_BEGIN) buf = win32file.ReadFile(fd, read_sz)[1] if attribute.data_size() < cnt + read_sz: read_sz = attribute.data_size() - cnt # cnt += length * bpc cnt += read_sz fd2.write(buf[:read_sz]) if padd == True: padd_sz = attribute.data_size( ) - attribute.initialized_size() fd2.write('\x00' * padd_sz) cnt += padd_sz fd2.close() except: logging.error('Failed to get file %s\n%s' % (mft_file_object, traceback.format_exc()))
def write(self, offset, data): win32file.SetFilePointer(self.fhandle, offset, 0) # The WinPmem driver returns bytes_written == 0 always. This is probably # a bug in its write routine, so we ignore it here. If the operation was # successful we assume all bytes were written. err, _bytes_written = win32file.WriteFile(self.fhandle, data) if err == 0: return len(data) return 0
def ReadPipe(pipe): win32file.SetFilePointer(pipe, 0, win32file.FILE_BEGIN) result, data = win32file.ReadFile(pipe, bufferSize, None) buf = data while len(data) == bufferSize: result, data = win32file.ReadFile(pipe, bufferSize, None) buf += data return buf
def _WriteBlock(self, data): self._data.extend(data) while (len(self._data) >= self._blockSize): toWrite = self._data[0:self._blockSize] win32file.SetFilePointer(self._file, self._position, win32file.FILE_BEGIN) win32file.WriteFile(self._file, toWrite, None) self._position += self._blockSize self._data = self._data[self._blockSize:]
def allocate_file(path, size): handle = win32file.CreateFile( path, win32file.GENERIC_WRITE, win32file.FILE_SHARE_WRITE, None, win32file.CREATE_ALWAYS, 0, None) win32file.SetFilePointer(handle, size, win32file.FILE_BEGIN) win32file.SetEndOfFile(handle) win32api.CloseHandle(handle)
def _read_chunk(self, addr, length): offset, available_length = self._get_available_buffer(addr, length) if offset is None: return "\x00" * min(length, available_length) win32file.SetFilePointer(self.fhandle, offset, 0) _, data = win32file.ReadFile( self.fhandle, min(length, available_length)) return data
def write(self, data): try: if 'a' in self.mode: win32file.SetFilePointer(self.handle, 0, win32file.FILE_END) nwrit = 0 while nwrit < len(data): val, nwrit = win32file.WriteFile(self.handle, data) data = data[nwrit:] except pywintypes.error, err: raise WinIOError(err)
def seek(self, offset, moveMethod=0): if moveMethod == 0: position = win32file.FILE_BEGIN elif moveMethod == 1: position = win32file.FILE_CURRENT elif moveMethod == 2: position = win32file.FILE_END else: raise ValueError('Invalid move method') win32file.SetFilePointer(self.handle, offset, position)
def __getChildIndex(self, index): fd = self.config['fd'] bss = self.config['bss'] bpc = bss.bytes_per_cluster buf = self.__calcOffset(index) if buf == None: raise Exception("Failed to process mft_offset") record = MFTRecord(buf, 0, None) if not record.is_directory(): return [] ret = [] for attribute in record.attributes(): if attribute.type() == ATTR_TYPE.INDEX_ROOT: for entry in INDEX_ROOT(attribute.value(), 0).index().entries(): ret.append((entry.header().mft_reference() & 0xfffffffff, entry.filename_information().filename())) if attribute.type() == ATTR_TYPE.INDEX_ALLOCATION: for cluster_offset, length in attribute.runlist().runs(): offset = cluster_offset * bpc win32file.SetFilePointer(fd, offset, win32file.FILE_BEGIN) buf = win32file.ReadFile(fd, length * bpc)[1] for cnt in range(length): idx_buf = buf[cnt * bpc:(cnt + 2) * bpc] # logging.debug("BEGIN"+"*"*80) # logging.debug(hex_dump(idx_buf)) ind = INDX(idx_buf, 0) idx_buf = ind.update_seq_arr(idx_buf) # logging.debug("*"*80) # logging.debug(hex_dump(idx_buf)) # logging.debug("END"+"*"*80) entry_offset = ind.index_entries_offset() + 0x18 i = 0 last_i = i # logging.debug( 'index_entries_sz %04x' % ind.index_entries_sz() ) while i < ind.index_entries_sz(): try: entry = INDX_ENTRY(idx_buf, entry_offset) ret.append( (entry.mft_recordnum(), entry.filename().replace('\x00', ''))) # logging.debug('i %04x seq_num %016x Filename: %s' % (i,entry.mft_recordnum()&0xffffffff, entry.filename().replace('\x00',''))) except INDXException: break except: # traceback.print_exc() logging.error(traceback.format_exc()) pass entry_offset += entry.entry_sz() i += entry.entry_sz() if entry.entry_sz() == 0: break return ret
def seek(self, offset, whence = 0): if whence == 0: whence = win32file.FILE_BEGIN elif whence == 1: whence = win32file.FILE_CURRENT elif whence == 2: whence = win32file.FILE_END else: raise ValueError("invalid whence value %r" % (whence,)) self.flush() win32file.SetFilePointer(self.handle, offset, whence)
def _read_chunk(self, addr, length): offset, available_length = self._get_available_buffer(addr, length) # Offset is pointing into invalid range, pad until the next range. if offset is None: return "\x00" * min(length, available_length) win32file.SetFilePointer(self.fhandle, offset, 0) _, data = win32file.ReadFile( self.fhandle, min(length, available_length)) return data
def write(self, addr, data): length = len(data) offset, available_length = self._get_available_buffer(addr, length) if offset is None: return to_write = min(len(data), available_length) win32file.SetFilePointer(self.fhandle, offset, 0) win32file.WriteFile(self.fhandle, data[:to_write]) return to_write
def _read(self, addr, length, pad=False): offset = self.translate(addr) if offset == None: if pad: return "\x00" * length else: return None win32file.SetFilePointer(self.fhandle, offset, 0) data = win32file.ReadFile(self.fhandle, length)[1] return data
def write(self, addr, data): if not self._config.WRITE: return False length = len(data) offset, available_length = self._get_available_buffer(addr, length) if offset is None: # Do not allow writing to reserved areas. return to_write = min(len(data), available_length) win32file.SetFilePointer(self.fhandle, offset, 0) win32file.WriteFile(self.fhandle, data[:to_write]) return True
def read(self, size=None): """ Reads from file some quantity of data and returns it as a string Args: n: bytes size to read Returns: string """ if not size: size = self.full_size win32file.SetFilePointer(self.handler, 0, win32file.FILE_BEGIN) data = win32file.ReadFile(self.handler, size, None)[1] return data