Quantcast
Channel: AutoIt v3 - General Help and Support
Viewing all articles
Browse latest Browse all 12506

Difficult Question - ReadFileScatter / FILE_SEGMENT_ELEMENT definition

$
0
0
HiHo Forum :),

I'm currently trying to create a working example for ReadFileScatter.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365469(v=vs.85).aspx
http://en.wikipedia.org/wiki/Vectored_I/O

The code is based on my example "Overlapped (Asynchronous) & UnBuffered ReadFile Example"
http://www.autoitscript.com/forum/topic/134645-overlapped-asynchronous-unbuffered-readfile-example/

What should the example do? Extract 3 * 16 KB from @AutoItExe and show it in a MsgBox(), first 16KB, 16KB from the middle of the file and the last 16KB of the file.

The problem seems to be in my definition of the FILE_SEGMENT_ELEMENT structure, the function returns "998 Invalid access to memory location".


typedef union _FILE_SEGMENT_ELEMENT {
    PVOID64 Buffer;
    ULONGLONG Alignment;
}FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT;

How to translate this into a tag for a DllStructCreate() call?

[ autoit ]         
#region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <StructureConstants.au3> #include <..\WinAPIEx_3.8_3380\WinAPIEx.au3> #include <Memory.au3> #include <array.au3> Global $nBytes, $hFile Global Const $ERROR_IO_INCOMPLETE = 996 ; Overlapped I/O event is not in a signaled state Global Const $ERROR_IO_PENDING = 997 ; Overlapped I/O operation is in progress Global Const $FILE_FLAG_OVERLAPPED = 0x40000000 Global Const $FILE_FLAG_NO_BUFFERING = 0x20000000 $sFile = @AutoItExe $aDrive = _WinAPI_GetDriveNumber(StringLeft($sFile, 2)) $aGeometry = _WinAPI_GetDriveGeometryEx($aDrive[1]) ; 'Bytes per Sector' = $aGeometry[4] ConsoleWrite(_WinAPI_GetLastErrorMessage() & @TAB & @error & @CRLF) ; FILE_FLAG_NO_BUFFERING ; File access sizes, including the optional file offset in the OVERLAPPED structure, if specified, ; must be for a number of bytes that is an integer multiple of the volume sector size $iBytesToRead_Total = 16384 ;  16KB per Block / 3 blocks total $iBytesToRead_Segment_Size = $aGeometry[4] $iBytesToRead_Segments = $iBytesToRead_Total / $iBytesToRead_Segment_Size ConsoleWrite("$iBytesToRead_Total " & $iBytesToRead_Total & @CRLF) ConsoleWrite("$iBytesToRead_Segment_Size " & $iBytesToRead_Segment_Size & @CRLF) ConsoleWrite("$iBytesToRead_Segments " & $iBytesToRead_Segments & @CRLF) ; The array must contain enough elements to store nNumberOfBytesToRead bytes of data, plus one element for the terminating NULL. ; For example, if there are 40 KB to be read and the page size is 4 KB, the array must have 11 elements that includes 10 for the data and one for the NULL. Local $tag_FILE_SEGMENT_ELEMENT Local $t_FILE_SEGMENT_ELEMENT_array[3] Local $p_FILE_SEGMENT_ELEMENT_array[3] For $y = 0 To 2 $tag_FILE_SEGMENT_ELEMENT = "" For $i = 1 To $iBytesToRead_Segments + 1 $tag_FILE_SEGMENT_ELEMENT &= "UINT64;ULONGLONG;" Next $t_FILE_SEGMENT_ELEMENT_array[$y] = DllStructCreate($tag_FILE_SEGMENT_ELEMENT) For $i = 0 To $iBytesToRead_Segments DllStructSetData($t_FILE_SEGMENT_ELEMENT_array[$y], ($i * 2) + 1, DllStructGetPtr(DllStructCreate("byte[" & $iBytesToRead_Segment_Size & "]", _MemVirtualAlloc(0, $iBytesToRead_Segment_Size, $MEM_COMMIT, $PAGE_READWRITE)))) Next $p_FILE_SEGMENT_ELEMENT_array[$y] = DllStructGetPtr($t_FILE_SEGMENT_ELEMENT_array[$y]) Next $iTimer = TimerInit() $hFile = _WinAPI_CreateFileEx($sFile, 3, $GENERIC_READ, 7, BitOR($FILE_ATTRIBUTE_NORMAL, $FILE_FLAG_OVERLAPPED, $FILE_FLAG_NO_BUFFERING)) $iFileGetSize = _WinAPI_GetFileSizeEx($hFile) ConsoleWrite(@CRLF & "+ Filesize " & $iFileGetSize & @CRLF & @CRLF) $iTimer_0 = TimerDiff($iTimer) ; Global Const $tagOVERLAPPED = "int Internal;int InternalHigh;int Offset;int OffsetHigh;int hEvent" $tOverlapped1 = DllStructCreate($tagOVERLAPPED) $pOverlapped1 = DllStructGetPtr($tOverlapped1) ConsoleWrite("_ReadFileScatter #1" & @TAB & _ReadFileScatter($hFile, $p_FILE_SEGMENT_ELEMENT_array[0], $iBytesToRead_Total, $pOverlapped1) & @CRLF) Func _ReadFileScatter($hFile, $FILE_SEGMENT_ELEMENT_array, $nNumberOfBytesToRead, $pOverlapped) ; ReadFileScatter ; http://msdn.microsoft.com/en-us/library/windows/desktop/aa365469(v=vs.85).aspx #cs BOOL WINAPI ReadFileScatter( _In_        HANDLE hFile, _In_        FILE_SEGMENT_ELEMENT aSegmentArray[], _In_        DWORD nNumberOfBytesToRead, _Reserved_  LPDWORD lpReserved, _Inout_     LPOVERLAPPED lpOverlapped ); #ce ConsoleWrite("_ReadFileScatter START" & @CRLF) Local $iRes = DllCall("kernel32.dll", "bool", "ReadFileScatter", "ptr", $hFile, "ptr", $FILE_SEGMENT_ELEMENT_array, "dword", $nNumberOfBytesToRead, "ptr", 0, "ptr", $pOverlapped) ConsoleWrite("_ReadFileScatter END" & @CRLF) ConsoleWrite(_WinAPI_GetLastError() & @TAB & _WinAPI_GetLastErrorMessage() & @CRLF) Return $iRes[0] EndFunc   ;==>_ReadFileScatter $iTimer_1 = TimerDiff($iTimer) $sTimer_1 = _WinAPI_GetLastError() $tOverlapped2 = DllStructCreate($tagOVERLAPPED) $pOverlapped2 = DllStructGetPtr($tOverlapped2) $iOffset = Int(($iFileGetSize / 2) - ($iBytesToRead_Total / 2 + 1)) $iOffset = (Floor($iOffset / $iBytesToRead_Segment_Size)) * $iBytesToRead_Segment_Size DllStructSetData($tOverlapped2, "Offset", _WinAPI_LoDWord($iOffset)) ; Setting "Filepointer" to the middle of the file (SetFilePointer is not valid for overlapped operations) DllStructSetData($tOverlapped2, "OffsetHigh", _WinAPI_HiDWord($iOffset)) ConsoleWrite("_ReadFileScatter #2" & @TAB & _ReadFileScatter($hFile, $p_FILE_SEGMENT_ELEMENT_array[1], $iBytesToRead_Total, $pOverlapped2) & @CRLF) $iTimer_2 = TimerDiff($iTimer) $sTimer_2 = _WinAPI_GetLastError() $tOverlapped3 = DllStructCreate($tagOVERLAPPED) $pOverlapped3 = DllStructGetPtr($tOverlapped3) $iOffset = $iFileGetSize - $iBytesToRead_Total $iOffset = (Floor($iOffset / $iBytesToRead_Segment_Size)) * $iBytesToRead_Segment_Size DllStructSetData($tOverlapped3, "Offset", _WinAPI_LoDWord($iOffset)) ; Setting "Filepointer" to the end of the file (SetFilePointer is not valid for overlapped operations) DllStructSetData($tOverlapped3, "OffsetHigh", _WinAPI_HiDWord($iOffset)) ConsoleWrite("_ReadFileScatter #3" & @TAB & _ReadFileScatter($hFile, $p_FILE_SEGMENT_ELEMENT_array[2], $iBytesToRead_Total, $pOverlapped3) & @CRLF) $iTimer_3 = TimerDiff($iTimer) $sTimer_3 = _WinAPI_GetLastError() $sRes1 = _WinAPI_GetOverlappedResult($hFile, $pOverlapped1, $nBytes) $sRes1 = $sRes1 & @TAB & $nBytes $iTimer_4 = TimerDiff($iTimer) $sTimer_4 = _WinAPI_GetLastError() $sRes2 = _WinAPI_GetOverlappedResult($hFile, $pOverlapped2, $nBytes) $sRes2 = $sRes2 & @TAB & $nBytes $iTimer_5 = TimerDiff($iTimer) $sTimer_5 = _WinAPI_GetLastError() $sRes3 = _WinAPI_GetOverlappedResult($hFile, $pOverlapped3, $nBytes) $sRes3 = $sRes3 & @TAB & $nBytes $iTimer_6 = TimerDiff($iTimer) $sTimer_6 = _WinAPI_GetLastError() _WinAPI_CloseHandle($hFile) $iTimer_7 = TimerDiff($iTimer) $sTimer_7 = _WinAPI_GetLastError() $sRes4 = _WinAPI_GetOverlappedResult($hFile, $pOverlapped1, $nBytes) $sRes4 = $sRes4 & @TAB & $nBytes $sRes5 = _WinAPI_GetOverlappedResult($hFile, $pOverlapped2, $nBytes) $sRes5 = $sRes5 & @TAB & $nBytes $sRes6 = _WinAPI_GetOverlappedResult($hFile, $pOverlapped3, $nBytes) $sRes6 = $sRes6 & @TAB & $nBytes $iTimer = TimerInit() $t_ReadFile_Standard = _ReadFile_Standard($sFile, $iFileGetSize) ConsoleWrite("_WinAPI_CloseHandle - Before " & $sRes1 & @TAB & $sRes2 & @TAB & $sRes3 & @CRLF) ConsoleWrite("_WinAPI_CloseHandle - After " & $sRes4 & @TAB & $sRes5 & @TAB & $sRes6 & @CRLF & @CRLF) ConsoleWrite($iTimer_0 & @CRLF & $iTimer_1 & @CRLF & $iTimer_2 & @CRLF & $iTimer_3 & @CRLF & $iTimer_4 & @CRLF & $iTimer_5 & @CRLF & $iTimer_6 & @CRLF & $iTimer_7 & @CRLF & @CRLF & TimerDiff($iTimer) & @CRLF & @CRLF) ConsoleWrite($sTimer_1 & @CRLF & $sTimer_2 & @CRLF & $sTimer_3 & @CRLF & $sTimer_4 & @CRLF & $sTimer_5 & @CRLF & $sTimer_6 & @CRLF & $sTimer_7 & @CRLF) MsgBox(0, "", "ReadFileScatter" & @CRLF & StringLeft(DllStructGetData(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[0], 1), 1), 5) & StringRight(DllStructGetData(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[0], 32), 1), 5) & @CRLF _ & StringLeft(DllStructGetData(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[1], 1), 1), 5) & StringRight(DllStructGetData(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[1], 32), 1), 5) & @CRLF _ & StringLeft(DllStructGetData(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[2], 1), 1), 5) & StringRight(DllStructGetData(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[2], 32), 1), 5) & @CRLF _ & @CRLF & @CRLF & "ReadFile Standard" & @CRLF _ & StringLeft(DllStructGetData($t_ReadFile_Standard, 1), 5) & StringRight(DllStructGetData($t_ReadFile_Standard, 1), 5) & @CRLF _ & StringLeft(DllStructGetData($t_ReadFile_Standard, 2), 5) & StringRight(DllStructGetData($t_ReadFile_Standard, 2), 5) & @CRLF _ & StringLeft(DllStructGetData($t_ReadFile_Standard, 3), 5) & StringRight(DllStructGetData($t_ReadFile_Standard, 3), 5)) For $y = 0 To 2 For $i = 1 To $iBytesToRead_Segments + 1 ConsoleWrite($y & @TAB & $i & @TAB & _MemVirtualFree(DllStructGetData($t_FILE_SEGMENT_ELEMENT_array[$y], $i), 0, $MEM_RELEASE) & @CRLF) Next Next Func _ReadFile_Standard($sFile, $iFileGetSize, $iFlag = 0) Local $hFile = _WinAPI_CreateFileEx($sFile, 3, $GENERIC_READ, 7, $iFlag), $nBytes If $hFile = 0 Then Return SetError(4) ;"File was locked and could not be analyzed..." Local $tBuffer = DllStructCreate("byte[" & $iBytesToRead_Total & "];byte[" & $iBytesToRead_Total & "];byte[" & $iBytesToRead_Total & "]") _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer, 1), $iBytesToRead_Total, $nBytes) $iOffset = Int(($iFileGetSize / 2) - ($iBytesToRead_Total / 2 + 1)) $iOffset = (Floor($iOffset / $iBytesToRead_Segment_Size)) * $iBytesToRead_Segment_Size _WinAPI_SetFilePointerEx($hFile, $iOffset) _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer, 2), $iBytesToRead_Total, $nBytes) $iOffset = $iFileGetSize - $iBytesToRead_Total $iOffset = (Floor($iOffset / $iBytesToRead_Segment_Size)) * $iBytesToRead_Segment_Size _WinAPI_SetFilePointerEx($hFile, $iOffset) ; $iBytesToRead/2 +1 _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer, 3), $iBytesToRead_Total, $nBytes) _WinAPI_CloseHandle($hFile) Return $tBuffer EndFunc   ;==>_ReadFile_Standard

Best Regards

Viewing all articles
Browse latest Browse all 12506

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>