def query_volume_information(file_or_handle, volume_info_class): if not isinstance(file_or_handle, windows.pycompat.int_types): file_or_handle = get_handle_from_file(file_or_handle) handle = file_or_handle io_status = gdef.IO_STATUS_BLOCK() info = ntqueryvolumeinformationfile_info_structs[volume_info_class]() # Do helper for 'is_pointer' / get pointed_size & co ? (useful for winproxy) pinfo = ctypes.pointer(info) try: windows.winproxy.NtQueryVolumeInformationFile(handle, io_status, pinfo, ctypes.sizeof(info), FsInformationClass=volume_info_class) except WindowsError as e: # import pdb;pdb.set_trace() if not (e.winerror & 0xffffffff) == gdef.STATUS_BUFFER_OVERFLOW: raise if volume_info_class == gdef.FileFsAttributeInformation: file_name_length = pinfo[0].FileSystemNameLength elif volume_info_class == gdef.FileFsVolumeInformation: file_name_length = pinfo[0].VolumeLabelLength + 0x8 # I have seen cases where the VolumeLabelLength is not even enough.. else: raise full_size = ctypes.sizeof(info) + file_name_length # We add a little too much size for the sake of simplicity buffer = ctypes.c_buffer(full_size) windows.winproxy.NtQueryVolumeInformationFile(handle, io_status, buffer, full_size, FsInformationClass=volume_info_class) pinfo = ctypes.cast(buffer, ctypes.POINTER(ntqueryvolumeinformationfile_info_structs[volume_info_class])) info = pinfo[0] return info return info
def query_file_information(file_or_handle, file_info_class): if not isinstance(file_or_handle, windows.pycompat.int_types): file_or_handle = windows.utils.get_handle_from_file(file_or_handle) handle = file_or_handle io_status = gdef.IO_STATUS_BLOCK() info = ntqueryinformationfile_info_structs[file_info_class]() # Do helper for 'is_pointer' / get pointed_size & co ? (useful for winproxy) pinfo = ctypes.pointer(info) try: windows.winproxy.NtQueryInformationFile(handle, io_status, pinfo, ctypes.sizeof(info), FileInformationClass=file_info_class) except Exception as e: if not (e.winerror & 0xffffffff) == gdef.STATUS_BUFFER_OVERFLOW: raise # STATUS_BUFFER_OVERFLOW -> Guess we have a FILE_NAME_INFORMATION somewhere that need a bigger buffer if file_info_class == gdef.FileNameInformation: file_name_length = pinfo[0].FileNameLength elif file_info_class == gdef.FileAllInformation: file_name_length = pinfo[0].NameInformation.FileNameLength elif file_info_class == gdef.FileStreamInformation: file_name_length = 0x10000 else: raise full_size = ctypes.sizeof(info) + file_name_length # We add a little too much size for the sake of simplicity buffer = ctypes.c_buffer(full_size) windows.winproxy.NtQueryInformationFile(handle, io_status, buffer, full_size, FileInformationClass=file_info_class) pinfo = ctypes.cast(buffer, ctypes.POINTER(ntqueryinformationfile_info_structs[file_info_class])) info = pinfo[0] # return list of ADS if FileStreamInformation ? return info
def query_extended_attributes(file_or_handle): if isinstance(file_or_handle, file): file_or_handle = windows.utils.get_handle_from_file(file_or_handle) # Check EaSize x = windows.utils.query_file_information(file_or_handle, gdef.FileEaInformation) if not x.EaSize: return io_status = gdef.IO_STATUS_BLOCK() # Handle Win10 / Win7 # Saw on Win10 -> EaSize > MAXIMUM_EA_SIZE # Saw on Win7 -> EaSize not enought (STATUS_BUFFER_OVERFLOW) buffsize = max(MAXIMUM_EA_SIZE, x.EaSize) buffer = windows.utils.BUFFER(EAInfo)(size=buffsize) windows.winproxy.NtQueryEaFile(file_or_handle, io_status, buffer, buffsize, False, None, 0, None, True) return buffer[0]