Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filebeat does not harvest rotating files in case of network drive located files #1361

Closed
BellBiker opened this issue Apr 8, 2016 · 26 comments
Labels

Comments

@BellBiker
Copy link

The following ELK stack is used

      elasticsearch-2.1.1
      kibana-4.3.1-windows
      Logstash-2.2.1
      filebeat-1.1.1-windows

We are using a JBOSS installation with a log rotation (based on log4j) and I recognized that filebeat-1.1.1-windows stops harvesting log files after rotating. If I run the JBOSS locally and the log files are stored either on the local machine or an usb drive the files are harvested without stopping at rotation.

Reading the file information with the windows api function GetFileInformationByHandle I recognized that the file information filebeat is harvesting does not longer change after file rotation. Additionally the file information of the rotated file are the same (all file attributes) for the file and its first rotation. If this file reaches the last rotation the rotation stops and the file, filebeat seems to harvest, is not longer rotated and grows unlimited.

File information after first rotation

!Path:          \morwhv002\Software\OAS\server\log\server.log
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:47:58
!Modified:      04/08/2016 15:50:48
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63668595851264
!Path:          \morwhv002\Software\OAS\server\log\server.log.1
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:47:58
!Modified:      04/08/2016 15:50:48
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63668595851264

As you can see the whole file information of server.log and server.log.1 is the same.

File information after second rotation (server.log and server.log.2 are the same)

!Path:          \morwhv002\Software\OAS\server\log\server.log
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:47:58
!Modified:      04/08/2016 15:50:48
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63668595851264
!Path:          \morwhv002\Software\OAS\server\log\server.log.1
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:50:48
!Modified:      04/08/2016 15:51:57
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            66550519103488
!Path:          \morwhv002\Software\OAS\server\log\server.log.2
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:47:58
!Modified:      04/08/2016 15:50:48
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63668595851264

File rotation after the fifth rotation

!Path:          \morwhv002\Software\OAS\server\log\server.log
!Attributes:    0x00000080
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:47:58
!Modified:      04/08/2016 15:50:48
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63668595851264
!Path:          \morwhv002\Software\OAS\server\log\server.log.1
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:54:25
!Modified:      04/08/2016 15:55:39
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63432372977664
!Path:          \morwhv002\Software\OAS\server\log\server.log.2
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:53:10
!Modified:      04/08/2016 15:54:25
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63428077944832
!Path:          \morwhv002\Software\OAS\server\log\server.log.3
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:51:57
!Modified:      04/08/2016 15:53:10
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63415193108480
!Path:          \morwhv002\Software\OAS\server\log\server.log.4
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:50:48
!Modified:      04/08/2016 15:51:57
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            66550519103488

The reported ID of the server.log the same as at creation time and there is a server.log.5 in the windows explorer which is not recognized trying to get the file information.

The log file of filebeat provides the following information which fits to my observation (x times)

            2016-04-08T16:00:38+02:00 DBG  Start next scan
            2016-04-08T16:00:38+02:00 DBG  scan path //morwhv002/Software/OAS/server/log/server.log
           2016-04-08T16:00:38+02:00 DBG  Check file for harvesting: //morwhv002/Software/OAS/server/log/server.log
          2016-04-08T16:00:38+02:00 DBG  Update existing file for harvesting: //morwhv002/Software/OAS/server/log/server.log
          2016-04-08T16:00:38+02:00 DBG  Not harvesting, file didn't change: //morwhv002/Software/OAS/server/log/server.log

In the moment I stop filebeat the file information of the files recovers and the rotation took place (server.log.1 has now the size of more than 4000 kb and server.log.5 is recognized).

!Path:          \morwhv002\Software\OAS\server\log\server.log
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 16:00:39
!Modified:      04/08/2016 16:00:48
!Volume serial: 2688798611
!Size (KB):     130
!Links:         1
!ID:            63458143174656
!Path:          \morwhv002\Software\OAS\server\log\server.log.1
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:55:39
!Modified:      04/08/2016 16:00:39
!Volume serial: 2688798611
!Size (KB):     4128
!Links:         1
!ID:            63410898862080
!Path:          \morwhv002\Software\OAS\server\log\server.log.2
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:54:25
!Modified:      04/08/2016 15:55:39
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63432372977664
!Path:          \morwhv002\Software\OAS\server\log\server.log.3
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:53:10
!Modified:      04/08/2016 15:54:25
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63428077944832
!Path:          \morwhv002\Software\OAS\server\log\server.log.4
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:51:57
!Modified:      04/08/2016 15:53:10
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            63415193108480
!Path:          \morwhv002\Software\OAS\server\log\server.log.5
!Attributes:    0x00000020
!Created:       04/08/2016 15:47:58
!Accessed:      04/08/2016 15:50:48
!Modified:      04/08/2016 15:51:57
!Volume serial: 2688798611
!Size (KB):     1024
!Links:         1
!ID:            66550519103488

Based on this observation I updated only filebeat to filebeat 1.2.1 the result is the same as described above.

@ruflin ruflin added the Filebeat Filebeat label Apr 8, 2016
@ruflin
Copy link
Member

ruflin commented Apr 11, 2016

@BellBiker Thanks for the report. Will have a look. I reformatted the post to make it better readable. Please also be aware of https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-network-volumes.html

@ruflin
Copy link
Member

ruflin commented Apr 12, 2016

@BellBiker Can you have a look at #1375 This could potentially fix your problem.

@ruflin ruflin added the bug label Apr 12, 2016
@BellBiker
Copy link
Author

@ruflin #1375 explains that the bug is caused if multiple files are rotated at the same time.

So I am not sure whether this describes the conditions of the above. In my example there is only one file harvested from filebeat (server.log) and the first rotation causes the problem that the file information for the file itsself and the rotated file server.log.1, which is not harvested, retrieves the same file information, which I read with an independent application.

From the solution I guess that the file information is stored outside the registrar. Maybe this storing algorithm interferes with reading file information using the windows api function and therefore causes the problem.

Based on this guess work the solution might also solve the reported scenario.

@ruflin
Copy link
Member

ruflin commented Apr 13, 2016

The behaviour above is quite strange. It looks like some information is actually cached and does not represent the actual values. Perhaps @andrewkroh has an idea here. I remember @urso also had mentioned some caching issues on remote drives?

Under windows the files are identified based on volume, IdxHi, IdxLo (https://github.com/elastic/beats/blob/master/filebeat/input/file_windows.go#L34). As far as I know two different files are never allowed to have the same values. Unfortunately these do not appear in your printout above.

@BellBiker
Copy link
Author

Hello,
unfortunately the program (AutoIt) to read the file information does not provide a function that provides the identifier idxHi and idxLo due to the fact that the return value is not a struct but an string array.

But as explained here https://msdn.microsoft.com/en-us/library/aa363788%28v=vs.85%29.aspx the "The identifier that is stored in the nFileIndexHigh and nFileIndexLow members is called the file ID."

The ! ID within my print outs is a compilation of idxHi (DWORD) and idxLo (DWORD) using (as I found now within the delivered include files) the WinAPI function MakeQWord. Hopefully this information is sufficient to understand the print out.

@ruflin
Copy link
Member

ruflin commented Apr 15, 2016

@BellBiker Thanks for the additional details.

@ruflin
Copy link
Member

ruflin commented Apr 22, 2016

I had once again a look at the posts above. The part I really can't understand is how the id and volume id of two files can be the same. Filebeat reads the same information and gets obviously confused. My current assumption is that the Id is in reality not the same, but the value delivered by the WinAPI is cached. I remember @urso found once a command to disable or flush this cache? Besides that I'm not sure how this problem could be solved as Filebeat does not get the accurate information from the system.

One potential future solution for the problem above is using fingerprints to compare files instead of the identifiers. Some work and discussions have started here in Logstash: jordansissel/ruby-filewatch#79

@driskell
Copy link

Can you provide the AutoIt source you used to generate that information? It might help shed some light on the internals and make things more clear to everyone.

I do know one issue in Golang is that for a File "information status" it does not use GetFileInformation until you need the IDs (such as when comparing if one status is the same as another). So let's say rotation happens. Then you compare - is it same? Let's say the rotated file status refers to the original path still, and the new status refers to same path of course. So both same name. We ask Golang to compare so it needs to load IDs. But it loads the IDs from the same path... So we get back yes same file when it is not.

I can't remember but in courier I call "os.Samefile" at start of harvesting to check that it harvests the same file the prospector discovered, and I remember doing this explicitly to ensure the stat structure has IDs loaded from the start ready for rotation check. Though I don't remember exactly why :-) Maybe it will help explain some of this?

The AutoIt source would definitely be interesting though - maybe it hits the same issue?

@ruflin
Copy link
Member

ruflin commented Apr 25, 2016

@driskell Thanks for the details. I actually hit the exact same problem some time ago and also solve it using os.SameFile: https://github.com/elastic/beats/blob/master/filebeat/input/file_windows.go#L21 (could have been inspired by log-courier ;-) ). So FB "should" not hit this issue.

@driskell
Copy link

Sweet :) It would be good to see the AutoIt bits then. I've not seen anything like this before. If you have any findings on the GetFileInfo caching it'll be good to link it here I think as that's something I never encountered before

@ruflin
Copy link
Member

ruflin commented Apr 25, 2016

@urso I think In remember you saw / found something like this for shared volumes?

@BellBiker
Copy link
Author

Hello together,
as requested I send you the sources of my autoIT files to read the file information. First of all there is the source to read the information. Instead of the installation version WinAPIFiles.au3 I included an adapted MyWinAPIFiles.au3 (find code below) to print also the idxHi and idxLo on the console output.

So please save the following code snippet as files with a name as you want and the extension "au3" and open it with autoIT.

#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <WinAPISys.au3>
#include <Security.au3>
#include <ProcessConstants.au3>
#include <SecurityConstants.au3>
#include <WinAPIProc.au3>
#include <WinAPI.au3>
#include <Date.au3>
#include <AutoItConstants.au3>
#include <File.au3>
#include <WindowsConstants.au3>
#include <MyWinAPIFiles.au3>
#include <AutoItConstants.au3>

Global Const $VK_NUMLOCK = 0x90
Global Const $VK_SCROLL = 0x91
Global Const $VK_CAPITAL = 0x14
Func ReadFileInfo (ByRef $fileaddresstotest, $bWriteFile)
   Local $dSystem
   Local $j=0
   Local $servertest=$fileaddresstotest
   Local $hServerFileOpen
   Local $aInfo
   Local $hFileHandle
   Local $strFile = @TempDir&"\FileInfo.txt"
   If $bWriteFile Then
      $dSystem = _Date_Time_GetSystemTime()
      $hFileHandle=FileOpen($strFile, $FO_APPEND)
      ConsoleWrite("!To File "&$strFile&@CRLF)
      FileWrite($hFileHandle,"-------------------------------------------------------------------------------------------------"&@CRLF)
      FileWrite($hFileHandle,"------------ at "&_Date_Time_SystemTimeToDateTimeStr($dSystem)&" -------------------------------------------------------------"&@CRLF)
   EndIf
   While $j<6
      $hServerFileOpen = _WinAPI_CreateFile($servertest, 2, 0, 6)
      $aInfo = _WinAPI_GetFileInformationByHandle($hServerFileOpen)
      If IsArray($aInfo) Then
       For $i = 1 To 3
        If IsDllStruct($aInfo[$i]) Then
            Local $tFILETIME = _Date_Time_FileTimeToLocalFileTime($aInfo[$i])
            $aInfo[$i] = _Date_Time_FileTimeToSystemTime($tFILETIME)
            $aInfo[$i] = _Date_Time_SystemTimeToDateTimeStr($aInfo[$i])
        Else
            $aInfo[$i] = 'Unknown'
        EndIf
       Next
       ConsoleWrite('!Path:          ' & _WinAPI_GetFinalPathNameByHandle($hServerFileOpen) & @CRLF)
       ConsoleWrite('!Attributes:    0x' & Hex($aInfo[0], 8) & @CRLF)
       ConsoleWrite('!Created:       ' & $aInfo[1] & @CRLF)
       ConsoleWrite('!Accessed:      ' & $aInfo[2] & @CRLF)
       ConsoleWrite('!Modified:      ' & $aInfo[3] & @CRLF)
       ConsoleWrite('!Volume serial: ' & $aInfo[4] & @CRLF)
       ConsoleWrite('!Size (KB):     ' & Round($aInfo[5]/1024) & @CRLF)
       ConsoleWrite('!Links:         ' & $aInfo[6] & @CRLF)
       ConsoleWrite('!ID:            ' & $aInfo[7] & @CRLF)
       If $bWriteFile Then
          FileWrite($hFileHandle,'!Path:          ' & _WinAPI_GetFinalPathNameByHandle($hServerFileOpen) & @CRLF)
          FileWrite($hFileHandle,'!Attributes:    0x' & Hex($aInfo[0], 8) & @CRLF)
          FileWrite($hFileHandle,'!Created:       ' & $aInfo[1] & @CRLF)
          FileWrite($hFileHandle,'!Accessed:      ' & $aInfo[2] & @CRLF)
          FileWrite($hFileHandle,'!Modified:      ' & $aInfo[3] & @CRLF)
          FileWrite($hFileHandle,'!Volume serial: ' & $aInfo[4] & @CRLF)
          FileWrite($hFileHandle,'!Size (KB):     ' & Round($aInfo[5]/1024) & @CRLF)
          FileWrite($hFileHandle,'!Links:         ' & $aInfo[6] & @CRLF)
          FileWrite($hFileHandle,'!ID:            ' & $aInfo[7] & @CRLF)
       EndIf
      EndIf
      _WinAPI_CloseHandle($hServerFileOpen)
      $j=$j+1
      $servertest=$fileaddresstotest&"."&$j
   WEnd
   If $bWriteFile Then
      FileWrite($hFileHandle,"---------------------------------- END ----------------------------------------------------------"&@CRLF)
      FileWrite($hFileHandle,@CRLF)
      FileClose($hFileHandle)
   EndIf
EndFunc
Local $bWriteToFile=0
ReadFileInfo("c:\temp\server.log", $bWriteToFile)

The following code has to be stored as MyWinAPIFiles.au3 ( If you change the name you have to change the include in the above example). The code changes for printing idxHi and idxLo are inside the function _WinAPI_GetFileInformationByHandle($hFile)

#include-once

#include "APIFilesConstants.au3"
#include "FileConstants.au3"
#include "WinAPIMisc.au3"
#include "WinAPIShPath.au3"

; #INDEX# =======================================================================================================================
; Title .........: WinAPI Extended UDF Library for AutoIt3
; AutoIt Version : 3.3.14.2
; Description ...: Additional variables, constants and functions for the WinAPIFiles.au3
; Author(s) .....: Yashied, jpm
; ===============================================================================================================================

#Region Global Variables and Constants

; #VARIABLES# ===================================================================================================================
Global $__g_iHeapSize = 8388608
; ===============================================================================================================================

; #CONSTANTS# ===================================================================================================================
Global Const $tagDEVMODE = 'wchar DeviceName[32];ushort SpecVersion;ushort DriverVersion;ushort Size;ushort DriverExtra;dword Fields;short Orientation;short PaperSize;short PaperLength;short PaperWidth;short Scale;short Copies;short DefaultSource;short PrintQuality;short Color;short Duplex;short YResolution;short TTOption;short Collate;wchar FormName[32];ushort Unused1;dword Unused2[3];dword Nup;dword Unused3;dword ICMMethod;dword ICMIntent;dword MediaType;dword DitherType;dword Reserved1;dword Reserved2;dword PanningWidth;dword PanningHeight'
Global Const $tagDEVNAMES = 'ushort DriverOffset;ushort DeviceOffset;ushort OutputOffset;ushort Default'
Global Const $tagFILEINFO = 'uint64 CreationTime;uint64 LastAccessTime;uint64 LastWriteTime;uint64 ChangeTime;dword Attributes'
Global Const $tagFILE_ID_DESCRIPTOR = 'dword Size;uint Type;' & $tagGUID
Global Const $tagWIN32_FIND_STREAM_DATA = 'int64 StreamSize;wchar StreamName[296]'
Global Const $tagWIN32_STREAM_ID = 'dword StreamId;dword StreamAttributes;int64 Size;dword StreamNameSize;wchar StreamName[1]'
; ===============================================================================================================================
#EndRegion Global Variables and Constants

#Region Functions list

; #CURRENT# =====================================================================================================================
; _WinAPI_BackupRead
; _WinAPI_BackupReadAbort
; _WinAPI_BackupSeek
; _WinAPI_BackupWrite
; _WinAPI_BackupWriteAbort
; _WinAPI_CopyFileEx
; _WinAPI_CreateDirectory
; _WinAPI_CreateDirectoryEx
; _WinAPI_CreateFileEx
; _WinAPI_CreateFileMapping
; _WinAPI_CreateHardLink
; _WinAPI_CreateObjectID
; _WinAPI_CreateSymbolicLink
; _WinAPI_DecryptFile
; _WinAPI_DefineDosDevice
; _WinAPI_DeleteFile
; _WinAPI_DeleteObjectID
; _WinAPI_DeleteVolumeMountPoint
; _WinAPI_DeviceIoControl
; _WinAPI_DuplicateEncryptionInfoFile
; _WinAPI_EjectMedia
; _WinAPI_EncryptFile
; _WinAPI_EncryptionDisable
; _WinAPI_EnumFiles
; _WinAPI_EnumFileStreams
; _WinAPI_EnumHardLinks
; _WinAPI_FileEncryptionStatus
; _WinAPI_FileExists
; _WinAPI_FileInUse
; _WinAPI_FindClose
; _WinAPI_FindCloseChangeNotification
; _WinAPI_FindFirstChangeNotification
; _WinAPI_FindFirstFile
; _WinAPI_FindFirstFileName
; _WinAPI_FindFirstStream
; _WinAPI_FindNextChangeNotification
; _WinAPI_FindNextFile
; _WinAPI_FindNextFileName
; _WinAPI_FindNextStream
; _WinAPI_FlushViewOfFile
; _WinAPI_GetBinaryType
; _WinAPI_GetCDType
; _WinAPI_GetCompressedFileSize
; _WinAPI_GetCompression
; _WinAPI_GetCurrentDirectory
; _WinAPI_GetDiskFreeSpaceEx
; _WinAPI_GetDriveBusType
; _WinAPI_GetDriveGeometryEx
; _WinAPI_GetDriveNumber
; _WinAPI_GetDriveType
; _WinAPI_GetFileAttributes
; _WinAPI_GetFileID
; _WinAPI_GetFileInformationByHandle
; _WinAPI_GetFileInformationByHandleEx
; _WinAPI_GetFilePointerEx
; _WinAPI_GetFileSizeOnDisk
; _WinAPI_GetFileTitle
; _WinAPI_GetFileType
; _WinAPI_GetFinalPathNameByHandle
; _WinAPI_GetFinalPathNameByHandleEx
; _WinAPI_GetFullPathName
; _WinAPI_GetLogicalDrives
; _WinAPI_GetObjectID
; _WinAPI_GetPEType
; _WinAPI_GetProfilesDirectory
; _WinAPI_GetTempFileName
; _WinAPI_GetVolumeInformation
; _WinAPI_GetVolumeInformationByHandle
; _WinAPI_GetVolumeNameForVolumeMountPoint
; _WinAPI_IOCTL
; _WinAPI_IsDoorOpen
; _WinAPI_IsPathShared
; _WinAPI_IsWritable
; _WinAPI_LoadMedia
; _WinAPI_LockDevice
; _WinAPI_LockFile
; _WinAPI_MapViewOfFile
; _WinAPI_MoveFileEx
; _WinAPI_OpenFileById
; _WinAPI_OpenFileMapping
; _WinAPI_PathIsDirectory
; _WinAPI_PathIsDirectoryEmpty
; _WinAPI_QueryDosDevice
; _WinAPI_ReadDirectoryChanges
; _WinAPI_RemoveDirectory
; _WinAPI_ReOpenFile
; _WinAPI_ReplaceFile
; _WinAPI_SearchPath
; _WinAPI_SetCompression
; _WinAPI_SetCurrentDirectory
; _WinAPI_SetFileAttributes
; _WinAPI_SetFileInformationByHandleEx
; _WinAPI_SetFilePointerEx
; _WinAPI_SetFileShortName
; _WinAPI_SetFileValidData
; _WinAPI_SetSearchPathMode
; _WinAPI_SetVolumeMountPoint
; _WinAPI_SfcIsFileProtected
; _WinAPI_UnlockFile
; _WinAPI_UnmapViewOfFile
; _WinAPI_Wow64EnableWow64FsRedirection
; ===============================================================================================================================
#EndRegion Functions list

#Region Public Functions

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_BackupRead($hFile, $pBuffer, $iLength, ByRef $iBytes, ByRef $pContext, $bSecurity = False)
    $iBytes = 0

    Local $aRet = DllCall('kernel32.dll', 'bool', 'BackupRead', 'handle', $hFile, 'struct*', $pBuffer, 'dword', $iLength, _
            'dword*', 0, 'bool', 0, 'bool', $bSecurity, 'ptr*', $pContext)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    $iBytes = $aRet[4]
    $pContext = $aRet[7]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_BackupRead

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_BackupReadAbort(ByRef $pContext)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'BackupRead', 'handle', 0, 'ptr', 0, 'dword', 0, 'dword*', 0, 'bool', 1, _
            'bool', 0, 'ptr*', $pContext)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    $pContext = $aRet[7]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_BackupReadAbort

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_BackupSeek($hFile, $iSeek, ByRef $iBytes, ByRef $pContext)
    $iBytes = 0

    Local $aRet = DllCall('kernel32.dll', 'bool', 'BackupSeek', 'handle', $hFile, 'dword', _WinAPI_LoDWord($iSeek), _
            'dword', _WinAPI_HiDWord($iSeek), 'dword*', 0, 'dword*', 0, 'ptr*', $pContext)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    $iBytes = __WinAPI_MakeQWord($aRet[4], $aRet[5])
    $pContext = $aRet[6]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_BackupSeek

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_BackupWrite($hFile, $pBuffer, $iLength, ByRef $iBytes, ByRef $pContext, $bSecurity = False)
    $iBytes = 0

    Local $aRet = DllCall('kernel32.dll', 'bool', 'BackupWrite', 'handle', $hFile, 'struct*', $pBuffer, 'dword', $iLength, _
            'dword*', 0, 'bool', 0, 'bool', $bSecurity, 'ptr*', $pContext)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    $iBytes = $aRet[4]
    $pContext = $aRet[7]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_BackupWrite

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_BackupWriteAbort(ByRef $pContext)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'BackupWrite', 'handle', 0, 'ptr', 0, 'dword', 0, 'dword*', 0, 'bool', 1, _
            'bool', 0, 'ptr*', $pContext)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    $pContext = $aRet[7]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_BackupWriteAbort

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_CopyFileEx($sExistingFile, $sNewFile, $iFlags = 0, $pProgressProc = 0, $pData = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'CopyFileExW', 'wstr', $sExistingFile, 'wstr', $sNewFile, _
            'ptr', $pProgressProc, 'struct*', $pData, 'bool*', 0, 'dword', $iFlags)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CopyFileEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_CreateDirectory($sDir, $tSecurity = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'CreateDirectoryW', 'wstr', $sDir, 'struct*', $tSecurity)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CreateDirectory

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_CreateDirectoryEx($sNewDir, $sTemplateDir, $tSecurity = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'CreateDirectoryExW', 'wstr', $sTemplateDir, 'wstr', $sNewDir, 'struct*', $tSecurity)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CreateDirectoryEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_CreateFileEx($sFilePath, $iCreation, $iAccess = 0, $iShare = 0, $iFlagsAndAttributes = 0, $tSecurity = 0, $hTemplate = 0)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileW', 'wstr', $sFilePath, 'dword', $iAccess, 'dword', $iShare, _
            'struct*', $tSecurity, 'dword', $iCreation, 'dword', $iFlagsAndAttributes, 'handle', $hTemplate)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] = Ptr(-1) Then Return SetError(10, _WinAPI_GetLastError(), 0) ; $INVALID_HANDLE_VALUE

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CreateFileEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: JPM
; ===============================================================================================================================
Func _WinAPI_CreateFileMapping($hFile, $iSize = 0, $sName = '', $iProtect = 0x0004, $tSecurity = 0)
    Local $sTypeOfName = 'wstr'
    If Not StringStripWS($sName, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfName = 'ptr'
        $sName = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'handle', 'CreateFileMappingW', 'handle', $hFile, 'struct*', $tSecurity, _
            'dword', $iProtect, 'dword', _WinAPI_HiDWord($iSize), 'dword', _WinAPI_LoDWord($iSize), _
            $sTypeOfName, $sName)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return SetExtended(_WinAPI_GetLastError(), $aRet[0]) ; ERROR_ALREADY_EXISTS
EndFunc   ;==>_WinAPI_CreateFileMapping

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_CreateHardLink($sNewFile, $sExistingFile)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'CreateHardLinkW', 'wstr', $sNewFile, 'wstr', $sExistingFile, 'ptr', 0)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CreateHardLink

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_CreateObjectID($sFilePath)
    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $tFOID = DllStructCreate('byte[16];byte[48]')
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x000900C0, 'ptr', 0, _
            'dword', 0, 'struct*', $tFOID, 'dword', DllStructGetSize($tFOID), 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Local $tGUID = DllStructCreate($tagGUID)
    _WinAPI_MoveMemory($tGUID, $tFOID, 16)
    ; Return SetError(3, 0, 0) ; cannot really occur
    ; EndIf
    Return $tGUID
EndFunc   ;==>_WinAPI_CreateObjectID

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: JPM
; ===============================================================================================================================
Func _WinAPI_CreateSymbolicLink($sSymlink, $sTarget, $bDirectory = False)
    If $bDirectory Then
        $bDirectory = 1
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'boolean', 'CreateSymbolicLinkW', 'wstr', $sSymlink, 'wstr', $sTarget, 'dword', $bDirectory)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_CreateSymbolicLink

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_DecryptFile($sFilePath)
    Local $aRet = DllCall('advapi32.dll', 'bool', 'DecryptFileW', 'wstr', $sFilePath, 'dword', 0)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_DecryptFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_DefineDosDevice($sDevice, $iFlags, $sFilePath = '')
    Local $sTypeOfPath = 'wstr'
    If Not StringStripWS($sFilePath, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfPath = 'ptr'
        $sFilePath = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DefineDosDeviceW', 'dword', $iFlags, 'wstr', $sDevice, $sTypeOfPath, $sFilePath)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_DefineDosDevice

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_DeleteFile($sFilePath)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeleteFileW', 'wstr', $sFilePath)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_DeleteFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_DeleteObjectID($sFilePath)
    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_WRITE, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x000900A0, 'ptr', 0, _
            'dword', 0, 'ptr', 0, 'dword', 0, 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Return 1
EndFunc   ;==>_WinAPI_DeleteObjectID

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_DeleteVolumeMountPoint($sMountedPath)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeleteVolumeMountPointW', 'wstr', $sMountedPath)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_DeleteVolumeMountPoint

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_DeviceIoControl($hDevice, $iControlCode, $pInBuffer = 0, $iInBufferSize = 0, $pOutBuffer = 0, $iOutBufferSize = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hDevice, 'dword', $iControlCode, _
            'struct*', $pInBuffer, 'dword', $iInBufferSize, 'struct*', $pOutBuffer, 'dword', $iOutBufferSize, _
            'dword*', 0, 'ptr', 0)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return SetExtended($aRet[7], $aRet[0])
EndFunc   ;==>_WinAPI_DeviceIoControl

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_DuplicateEncryptionInfoFile($sSrcFilePath, $sDestFilePath, $iCreation = 2, $iAttributes = 0, $tSecurity = 0)
    Local $aRet = DllCall('advapi32.dll', 'dword', 'DuplicateEncryptionInfoFile', 'wstr', $sSrcFilePath, 'wstr', $sDestFilePath, _
            'dword', $iCreation, 'dword', $iAttributes, 'struct*', $tSecurity)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] Then Return SetError(10, $aRet[0], 0)

    Return 1
EndFunc   ;==>_WinAPI_DuplicateEncryptionInfoFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_EjectMedia($sDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, $GENERIC_READ, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D4808, 'ptr', 0, _
            'dword', 0, 'ptr', 0, 'dword', 0, 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Return 1
EndFunc   ;==>_WinAPI_EjectMedia

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_EncryptFile($sFilePath)
    Local $aRet = DllCall('advapi32.dll', 'bool', 'EncryptFileW', 'wstr', $sFilePath)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_EncryptFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_EncryptionDisable($sDir, $bDisable)
    Local $aRet = DllCall('advapi32.dll', 'bool', 'EncryptionDisable', 'wstr', $sDir, 'bool', $bDisable)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_EncryptionDisable

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_EnumFiles($sDir, $iFlag = 0, $sTemplate = '', $bExclude = False)
    Local $aRet = 0, $iError = 0
    Local $aData[501][7] = [[0]]

    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hDir = _WinAPI_CreateFileEx($sDir, $OPEN_EXISTING, 0x00000001, $FILE_SHARE_ANY, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $pBuffer = __HeapAlloc($__g_iHeapSize)
    If @error Then
        $iError = @error
    Else
        Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
        $aRet = DllCall('ntdll.dll', 'uint', 'ZwQueryDirectoryFile', 'handle', $hDir, 'ptr', 0, 'ptr', 0, 'ptr', 0, _
                'struct*', $tIOSB, 'struct*', $pBuffer, 'ulong', 8388608, 'uint', 1, 'boolean', 0, 'ptr', 0, 'boolean', 1)
        If @error Or $aRet[0] Then
            $iError = @error + 40
        EndIf
    EndIf
    DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hDir)
    If $iError Then
        __HeapFree($pBuffer, 1)
        If IsArray($aRet) Then
            Return SetError(10, $aRet[0], 0)
        Else
            Return SetError($iError, 0, 0)
        EndIf
    EndIf

    Local $tFDI, $iAttrib, $sTarget, $iLength = 0, $iOffset = 0
    Do
        $iLength += $iOffset
        $tFDI = DllStructCreate('ulong;ulong;int64;int64;int64;int64;int64;int64;ulong;ulong;wchar[' & (DllStructGetData(DllStructCreate('ulong', $pBuffer + $iLength + 60), 1) / 2) & ']', $pBuffer + $iLength)
        $sTarget = DllStructGetData($tFDI, 11)
        $iAttrib = DllStructGetData($tFDI, 9)
        $iOffset = DllStructGetData($tFDI, 1)
        Switch $sTarget
            Case '.', '..'
                ContinueLoop
            Case Else
                Switch $iFlag
                    Case 1, 2
                        If BitAND($iAttrib, 0x00000010) Then
                            If $iFlag = 1 Then
                                ContinueLoop
                            EndIf
                        Else
                            If $iFlag = 2 Then
                                ContinueLoop
                            EndIf
                        EndIf
                EndSwitch
                If $sTemplate Then
                    $aRet = DllCall('shlwapi.dll', 'int', 'PathMatchSpecW', 'wstr', $sTarget, 'wstr', $sTemplate)
                    If @error Or ($aRet[0] And $bExclude) Or (Not $aRet[0] And Not $bExclude) Then
                        ContinueLoop
                    EndIf
                EndIf
        EndSwitch
        __Inc($aData, 500)
        $aData[$aData[0][0]][0] = $sTarget
        $aData[$aData[0][0]][1] = DllStructGetData($tFDI, 3)
        $aData[$aData[0][0]][2] = DllStructGetData($tFDI, 4)
        $aData[$aData[0][0]][3] = DllStructGetData($tFDI, 5)
        $aData[$aData[0][0]][4] = DllStructGetData($tFDI, 7)
        $aData[$aData[0][0]][5] = DllStructGetData($tFDI, 8)
        $aData[$aData[0][0]][6] = $iAttrib
    Until Not $iOffset
    __HeapFree($pBuffer)
    __Inc($aData, -1)
    Return $aData
EndFunc   ;==>_WinAPI_EnumFiles

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_EnumFileStreams($sFilePath)
    Local $tData = DllStructCreate('byte[32768]')
    Local $pData = DllStructGetPtr($tData)
    Local $aData[101][2] = [[0]]

    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $iError = 0; JPM: ????
    Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwQueryInformationFile', 'handle', $hFile, 'struct*', $tIOSB, 'ptr', $pData, _
            'ulong', 32768, 'uint', 22)
    If @error Then $iError = @error
    DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hFile)
    If $iError Then Return SetError($iError, 0, 0)
    If $aRet[0] Then Return SetError(10, $aRet[0], 0)

    Local $tFSI, $iLength = 0, $iOffset = 0
    Do
        $iLength += $iOffset
        $tFSI = DllStructCreate('ulong;ulong;int64;int64;wchar[' & (DllStructGetData(DllStructCreate('ulong', $pData + $iLength + 4), 1) / 2) & ']', $pData + $iLength)
        __Inc($aData)
        $aData[$aData[0][0]][0] = DllStructGetData($tFSI, 5)
        $aData[$aData[0][0]][1] = DllStructGetData($tFSI, 3)
        $iOffset = DllStructGetData($tFSI, 1)
    Until Not $iOffset
    __Inc($aData, -1)
    Return $aData
EndFunc   ;==>_WinAPI_EnumFileStreams

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_EnumHardLinks($sFilePath)
    Local $tData = DllStructCreate('byte[32768]')
    Local $pData = DllStructGetPtr($tData)

    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $iError = 0
    Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwQueryInformationFile', 'handle', $hFile, 'struct*', $tIOSB, 'ptr', $pData, _
            'ulong', 32768, 'uint', 46)
    If @error Or $aRet[0] Then
        $iError = @error + 10
        DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hFile)
        If $aRet Then Return SetError($iError, 0, 0)
        If $aRet[0] Then Return SetError(10, $iError, 0)
    EndIf

    Local $iCount = DllStructGetData(DllStructCreate('ulong;ulong', $pData), 2)
    Local $aData[$iCount + 1] = [$iCount]
    Local $tFLEI, $hPath, $sPath, $iLength = 8
    For $i = 1 To $iCount
        $tFLEI = DllStructCreate('ulong;int64;ulong;wchar[' & (DllStructGetData(DllStructCreate('ulong', $pData + $iLength + 16), 1)) & ']', $pData + $iLength)
        $iError = 0
        Do
            $hPath = _WinAPI_OpenFileById($hFile, DllStructGetData($tFLEI, 2), 0x00100080, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
            If @error Then
                $iError = @error + 100
                ExitLoop
            EndIf
            $sPath = _WinAPI_GetFinalPathNameByHandleEx($hPath)
            If @error Then
                $iError = @error + 200
                ExitLoop
            EndIf
        Until 1
        If $hPath Then
            DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hPath)
        EndIf
        If $iError Then ExitLoop

        $aData[$i] = _WinAPI_PathAppend($sPath, DllStructGetData($tFLEI, 4))
        $iLength += DllStructGetData($tFLEI, 1)
    Next
    DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hFile)
    If $iError Then Return SetError($iError, 0, 0)

    Return $aData
EndFunc   ;==>_WinAPI_EnumHardLinks

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FileEncryptionStatus($sFilePath)
    Local $aRet = DllCall('advapi32.dll', 'bool', 'FileEncryptionStatusW', 'wstr', $sFilePath, 'dword*', 0)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, -1)

    Return $aRet[2]
EndFunc   ;==>_WinAPI_FileEncryptionStatus

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FileExists($sFilePath)
    If Not FileExists($sFilePath) Then Return 0
    If _WinAPI_PathIsDirectory($sFilePath) Then Return SetExtended(1, 0)

    Return 1
EndFunc   ;==>_WinAPI_FileExists

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FileInUse($sFilePath)
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_READ)
    If @error Then
        If @extended = 32 Then Return 1 ; ERROR_SHARING_VIOLATION
        Return SetError(@error, @extended, 0)
    EndIf
    DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hFile)
    Return 0
EndFunc   ;==>_WinAPI_FileInUse

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_FindClose($hSearch)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'FindClose', 'handle', $hSearch)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindClose

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_FindCloseChangeNotification($hChange)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'FindCloseChangeNotification', 'handle', $hChange)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindCloseChangeNotification

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindFirstChangeNotification($sDirectory, $iFlags, $bSubtree = False)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'FindFirstChangeNotificationW', 'wstr', $sDirectory, 'bool', $bSubtree, _
            'dword', $iFlags)
    If @error Or ($aRet[0] = Ptr(-1)) Then Return SetError(@error + 10, @extended, 0) ; $INVALID_HANDLE_VALUE

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindFirstChangeNotification

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindFirstFile($sFilePath, $tData)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'FindFirstFileW', 'wstr', $sFilePath, 'struct*', $tData)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] = Ptr(-1) Then Return SetError(10, _WinAPI_GetLastError(), 0); $INVALID_HANDLE_VALUE

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindFirstFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindFirstFileName($sFilePath, ByRef $sLink)
    $sLink = ''

    Local $aRet = DllCall('kernel32.dll', 'handle', 'FindFirstFileNameW', 'wstr', $sFilePath, 'dword', 0, 'dword*', 4096, 'wstr', '')
    If @error Or ($aRet[0] = Ptr(-1)) Then Return SetError(@error + 10, @extended, 0) ; $INVALID_HANDLE_VALUE

    $sLink = $aRet[4]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindFirstFileName

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindFirstStream($sFilePath, $tData)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'FindFirstStreamW', 'wstr', $sFilePath, 'uint', 0, 'struct*', $tData, 'dword', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] = Ptr(-1) Then Return SetError(10, _WinAPI_GetLastError(), 0) ; $INVALID_HANDLE_VALUE

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindFirstStream

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_FindNextChangeNotification($hChange)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'FindNextChangeNotification', 'handle', $hChange)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindNextChangeNotification

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindNextFile($hSearch, $tData)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'FindNextFileW', 'handle', $hSearch, 'struct*', $tData)
    If @error Then Return SetError(@error, @extended, False)
    If Not $aRet[0] Then Return SetError(10, _WinAPI_GetLastError(), 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindNextFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindNextFileName($hSearch, ByRef $sLink)
    $sLink = ''

    Local $aRet = DllCall('kernel32.dll', 'bool', 'FindNextFileNameW', 'handle', $hSearch, 'dword*', 4096, 'wstr', '')
    If @error Then Return SetError(@error, @extended, False)
    If Not $aRet[0] Then Return SetError(10, _WinAPI_GetLastError(), 0)

    $sLink = $aRet[3]
    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindNextFileName

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_FindNextStream($hSearch, $tData)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'FindNextStreamW', 'handle', $hSearch, 'struct*', $tData)
    If @error Then Return SetError(@error, @extended, False)
    If Not $aRet[0] Then Return SetError(10, _WinAPI_GetLastError(), 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FindNextStream

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_FlushViewOfFile($pAddress, $iBytes = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'FlushViewOfFile', 'struct*', $pAddress, 'dword', $iBytes)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_FlushViewOfFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetBinaryType($sFilePath)
    Local $aRet = DllCall('kernel32.dll', 'int', 'GetBinaryTypeW', 'wstr', $sFilePath, 'dword*', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If Not $aRet[0] Then $aRet[2] = 0

    Return SetExtended($aRet[2], $aRet[0])
EndFunc   ;==>_WinAPI_GetBinaryType

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetCDType($sDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, $GENERIC_READWRITE, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $tagSCSI_PASS_THROUGH = 'struct;ushort Length;byte ScsiStatus;byte PathId;byte TargetId;byte Lun;byte CdbLength;byte SenseInfoLength;byte DataIn;ulong DataTransferLength;ulong TimeOutValue;ulong_ptr DataBufferOffset;ulong SenseInfoOffset;byte Cdb[16];endstruct'
    Local $tSPT = DllStructCreate($tagSCSI_PASS_THROUGH & ';byte Hdr[8]')
    Local $tCDB = DllStructCreate('byte;byte;byte[2];byte[3];byte[2];byte;byte[2];byte[4]', DllStructGetPtr($tSPT, 'Cdb'))
    Local $tHDR = DllStructCreate('byte[4];byte;byte;byte[2]', DllStructGetPtr($tSPT, 'Hdr'))
    Local $iSize = DllStructGetPtr($tSPT, 'Hdr') - DllStructGetPtr($tSPT)

    DllStructSetData($tSPT, 'Length', $iSize)
    DllStructSetData($tSPT, 'ScsiStatus', 0)
    DllStructSetData($tSPT, 'PathId', 0)
    DllStructSetData($tSPT, 'TargetId', 0)
    DllStructSetData($tSPT, 'Lun', 0)
    DllStructSetData($tSPT, 'CdbLength', 12)
    DllStructSetData($tSPT, 'SenseInfoLength', 0)
    DllStructSetData($tSPT, 'DataIn', 1)
    DllStructSetData($tSPT, 'DataTransferLength', 8)
    DllStructSetData($tSPT, 'TimeOutValue', 86400)
    DllStructSetData($tSPT, 'DataBufferOffset', $iSize)
    DllStructSetData($tSPT, 'SenseInfoOffset', 0)

    DllStructSetData($tCDB, 1, 0x46)
    DllStructSetData($tCDB, 2, 0)
    DllStructSetData($tCDB, 3, 0, 1)
    DllStructSetData($tCDB, 3, 0, 2)
    DllStructSetData($tCDB, 5, 0, 1)
    DllStructSetData($tCDB, 5, 8, 2)
    DllStructSetData($tCDB, 6, 0)
    DllStructSetData($tCDB, 7, 0, 1)
    DllStructSetData($tCDB, 7, 0, 2)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x0004D004, 'struct*', $tSPT, _
            'dword', $iSize, 'struct*', $tSPT, 'dword', DllStructGetSize($tSPT), 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Return BitOR(BitShift(DllStructGetData($tHDR, 4, 1), -8), DllStructGetData($tHDR, 4, 2))
EndFunc   ;==>_WinAPI_GetCDType

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetCompressedFileSize($sFilePath)
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetCompressedFileSizeW', 'wstr', $sFilePath, 'dword*', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] = -1 Then
        Local $iLastError = _WinAPI_GetLastError()
        If $aRet[2] = 0 Then Return SetError(10, $iLastError, 0)
        If $iLastError Then Return SetError(11, $iLastError, 0)
    EndIf

    Return __WinAPI_MakeQWord($aRet[0], $aRet[2])
EndFunc   ;==>_WinAPI_GetCompressedFileSize

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetCompression($sFilePath)
    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_READ, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x0009003C, 'ptr', 0, 'dword', 0, _
            'ushort*', 0, 'dword', 2, 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, -1)

    Return $aRet[5]
EndFunc   ;==>_WinAPI_GetCompression

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetCurrentDirectory()
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetCurrentDirectoryW', 'dword', 4096, 'wstr', '')
    If @error Then Return SetError(@error, @extended, '')
    ; If Not $aRet[0] Then Return SetError(1000, 0,'')

    Return SetExtended($aRet[0], $aRet[2])
EndFunc   ;==>_WinAPI_GetCurrentDirectory

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetDiskFreeSpaceEx($sDrive)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetDiskFreeSpaceEx', 'str', $sDrive, 'int64*', 0, 'int64*', 0, 'int64*', 0)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

    Local $aResult[3]
    For $i = 0 To 2
        $aResult[$i] = $aRet[$i + 2]
    Next
    Return $aResult
EndFunc   ;==>_WinAPI_GetDiskFreeSpaceEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetDriveBusType($sDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, -1)

    Local $tagSTORAGE_PROPERTY_QUERY = 'ulong PropertyId;ulong QueryType;byte AdditionalParameters[1]'
    Local $tSPQ = DllStructCreate($tagSTORAGE_PROPERTY_QUERY)
    Local $tSDD = DllStructCreate('ulong Version;ulong Size;byte DeviceType;byte DeviceTypeModifier;byte RemovableMedia;byte CommandQueueing;ulong VendorIdOffset;ulong ProductIdOffset;ulong ProductRevisionOffset;ulong SerialNumberOffset;ulong BusType;ulong RawPropertiesLength;byte RawDeviceProperties[1]')

    DllStructSetData($tSPQ, 'PropertyId', 0)
    DllStructSetData($tSPQ, 'QueryType', 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D1400, 'struct*', $tSPQ, _
            'dword', DllStructGetSize($tSPQ), 'struct*', $tSDD, 'dword', DllStructGetSize($tSDD), _
            'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, -1)

    Return DllStructGetData($tSDD, 'BusType')
EndFunc   ;==>_WinAPI_GetDriveBusType

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetDriveGeometryEx($iDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\PhysicalDrive' & $iDrive, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $tDGEX = DllStructCreate('uint64;dword;dword;dword;dword;uint64')
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x000700A0, 'ptr', 0, _
            'dword', 0, 'struct*', $tDGEX, 'dword', DllStructGetSize($tDGEX), 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Local $aResult[6]
    For $i = 0 To 5
        $aResult[$i] = DllStructGetData($tDGEX, $i + 1)
    Next
    Return $aResult
EndFunc   ;==>_WinAPI_GetDriveGeometryEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetDriveNumber($sDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $tSDN = DllStructCreate('dword;ulong;ulong')
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D1080, 'ptr', 0, _
            'dword', 0, 'struct*', $tSDN, 'dword', DllStructGetSize($tSDN), 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Local $aResult[3]
    For $i = 0 To 2
        $aResult[$i] = DllStructGetData($tSDN, $i + 1)
    Next
    Return $aResult
EndFunc   ;==>_WinAPI_GetDriveNumber

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetDriveType($sDrive = '')
    Local $iTypeOfDrive = 'str'
    If Not StringStripWS($sDrive, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $iTypeOfDrive = 'ptr'
        $sDrive = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'uint', 'GetDriveType', $iTypeOfDrive, $sDrive)
    If @error Then Return SetError(@error, @extended, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_GetDriveType

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetFileAttributes($sFilePath)
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetFileAttributesW', 'wstr', $sFilePath)
    If @error Or ($aRet[0] = 4294967295) Then Return SetError(@error, @extended, 0)
    ; If $aRet[0] = 4294967295Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_GetFileAttributes

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetFileID($hFile)
    Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwQueryInformationFile', 'handle', $hFile, 'struct*', $tIOSB, 'int64*', 0, _
            'ulong', 8, 'uint', 6)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] Then Return SetError(10, $aRet[0], 0)

    Return $aRet[3]
EndFunc   ;==>_WinAPI_GetFileID

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetFileInformationByHandle($hFile)
    Local $tBHFI = DllStructCreate('dword;dword[2];dword[2];dword[2];dword;dword;dword;dword;dword;dword')
    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetFileInformationByHandle', 'handle', $hFile, 'struct*', $tBHFI)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

    Local $aResult[8]
    $aResult[0] = DllStructGetData($tBHFI, 1)
    For $i = 1 To 3
        If DllStructGetData($tBHFI, $i + 1) Then
            $aResult[$i] = DllStructCreate($tagFILETIME)
            _WinAPI_MoveMemory($aResult[$i], DllStructGetPtr($tBHFI, $i + 1), 8)
            ; Return SetError(@error + 10, @extended, 0) ; cannot really occur
            ; EndIf
        Else
            $aResult[$i] = 0
        EndIf
    Next
    $aResult[4] = DllStructGetData($tBHFI, 5)
    $aResult[5] = __WinAPI_MakeQWord(DllStructGetData($tBHFI, 7), DllStructGetData($tBHFI, 6))
    $aResult[6] = DllStructGetData($tBHFI, 8)
    $aResult[7] = __WinAPI_MakeQWord(DllStructGetData($tBHFI, 9), DllStructGetData($tBHFI, 10))
    ConsoleWrite('! idxHi: ' & DllStructGetData($tBHFI, 10) & @CRLF & '! idxLo: ' & DllStructGetData($tBHFI, 9)& @CRLF)
    ConsoleWrite('! Qword: ' & __WinAPI_MakeQWord(DllStructGetData($tBHFI, 9), DllStructGetData($tBHFI, 10)) & @CRLF)
    ConsoleWrite('! idxHi: ' & _WinAPI_HiDWord(__WinAPI_MakeQWord(DllStructGetData($tBHFI, 9), DllStructGetData($tBHFI, 10))))
    ConsoleWrite(' ! idxLo: ' & _WinAPI_LoDWord(__WinAPI_MakeQWord(DllStructGetData($tBHFI, 9), DllStructGetData($tBHFI, 10))) & @CRLF)


    Return $aResult
EndFunc   ;==>_WinAPI_GetFileInformationByHandle

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetFileInformationByHandleEx($hFile)
    Local $tFI = DllStructCreate($tagFILEINFO)
    Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwQueryInformationFile', 'handle', $hFile, 'struct*', $tIOSB, 'struct*', $tFI, _
            'ulong', DllStructGetSize($tFI), 'uint', 4)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] Then Return SetError(10, $aRet[0], 0)

    Return $tFI
EndFunc   ;==>_WinAPI_GetFileInformationByHandleEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetFilePointerEx($hFile)
    Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwQueryInformationFile', 'handle', $hFile, 'struct*', $tIOSB, 'int64*', 0, _
            'ulong', 8, 'uint', 14)
    If @error Then Return SetError(@error, @extended, '')
    If $aRet[0] Then Return SetError(10, $aRet[0], '')

    Return $aRet[3]
EndFunc   ;==>_WinAPI_GetFilePointerEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetFileSizeOnDisk($sFilePath)
    Local $iSize = FileGetSize($sFilePath)
    If @error Then Return SetError(@error + 10, @extended, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetDiskFreeSpaceW', _
            'wstr', _WinAPI_PathStripToRoot(_WinAPI_GetFullPathName($sFilePath)), 'dword*', 0, 'dword*', 0, _
            'dword*', 0, 'dword*', 0)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return Ceiling($iSize / ($aRet[2] * $aRet[3])) * ($aRet[2] * $aRet[3])
EndFunc   ;==>_WinAPI_GetFileSizeOnDisk

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetFileTitle($sFilePath)
    Local $aRet = DllCall('comdlg32.dll', 'short', 'GetFileTitleW', 'wstr', $sFilePath, 'wstr', '', 'word', 4096)
    If @error Or $aRet[0] Then Return SetError(@error, @extended, '')
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[2]
EndFunc   ;==>_WinAPI_GetFileTitle

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetFileType($hFile)
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetFileType', 'handle', $hFile)
    If @error Then Return SetError(@error, @extended, -1)
    Local $iLastError = _WinAPI_GetLastError()
    If Not $aRet[0] And $iLastError Then Return SetError(10, $iLastError, -1)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_GetFileType

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetFinalPathNameByHandle($hFile)
    Local $tFNI = DllStructCreate('ulong;wchar[4096]')
    Local $tIOSB = DllStructCreate('ptr;ulong_ptr')
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwQueryInformationFile', 'handle', $hFile, 'struct*', $tIOSB, 'struct*', $tFNI, _
            'ulong', DllStructGetSize($tFNI), 'uint', 9)
    If @error Then Return SetError(@error, @extended, '')
    If $aRet[0] Then Return SetError(10, $aRet[0], '')
    Local $iLength = DllStructGetData($tFNI, 1)
    If Not $iLength Then Return SetError(12, 0, '')

    Return DllStructGetData(DllStructCreate('wchar[' & ($iLength / 2) & ']', DllStructGetPtr($tFNI, 2)), 1)
EndFunc   ;==>_WinAPI_GetFinalPathNameByHandle

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetFinalPathNameByHandleEx($hFile, $iFlags = 0)
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetFinalPathNameByHandleW', 'handle', $hFile, 'wstr', '', 'dword', 4096, _
            'dword', $iFlags)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, '')

    Return $aRet[2]
EndFunc   ;==>_WinAPI_GetFinalPathNameByHandleEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetFullPathName($sFilePath)
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetFullPathNameW', 'wstr', $sFilePath, 'dword', 4096, 'wstr', '', 'ptr', 0)
    If @error Or Not $aRet[0] Then Return SetError(@error, @extended, '')
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[3]
EndFunc   ;==>_WinAPI_GetFullPathName

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetLogicalDrives()
    Local $aRet = DllCall('kernel32.dll', 'dword', 'GetLogicalDrives')
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_GetLogicalDrives

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetObjectID($sFilePath)
    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $tFOID = DllStructCreate('byte[16];byte[48]')
    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x0009009C, 'ptr', 0, _
            'dword', 0, 'struct*', $tFOID, 'dword', DllStructGetSize($tFOID), 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Local $tGUID = DllStructCreate($tagGUID)
    _WinAPI_MoveMemory($tGUID, $tFOID, 16)
    ; Return SetError(3, 0, 0) ; cannot really occur
    ; EndIf
    Return $tGUID
EndFunc   ;==>_WinAPI_GetObjectID

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetPEType($sFilePath)
    Local $tData = DllStructCreate('ushort[2]')
    Local $tUInt = DllStructCreate('uint', DllStructGetPtr($tData))

    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_READ, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $iError = 0, $iVal
    Do
        Local $aRet = DllCall('kernel32.dll', 'bool', 'ReadFile', 'handle', $hFile, 'struct*', $tData, 'dword', 2, 'dword*', 0, 'ptr', 0)
        If @error Or (Not $aRet[0]) Or ($aRet[4] <> 2) Then
            $iError = @error + 30
            ExitLoop
        EndIf
        $iVal = DllStructGetData($tData, 1, 1)
        If $iVal <> 0x00005A4D Then
            $iError = 3
            ExitLoop
        EndIf
        If Not _WinAPI_SetFilePointerEx($hFile, 0x0000003C) Then
            $iError = @error + 40
            ExitLoop
        EndIf
        $aRet = DllCall('kernel32.dll', 'bool', 'ReadFile', 'handle', $hFile, 'struct*', $tData, 'dword', 4, 'dword*', 0, 'ptr', 0)
        If @error Or (Not $aRet[0]) Or ($aRet[4] <> 4) Then
            $iError = @error + 50
            ExitLoop
        EndIf
        If Not _WinAPI_SetFilePointerEx($hFile, DllStructGetData($tUInt, 1)) Then
            $iError = @error + 60
            ExitLoop
        EndIf
        $aRet = DllCall('kernel32.dll', 'bool', 'ReadFile', 'handle', $hFile, 'struct*', $tData, 'dword', 4, 'dword*', 0, 'ptr', 0)
        If @error Or (Not $aRet[0]) Or ($aRet[4] <> 4) Then
            $iError = @error + 70
            ExitLoop
        EndIf
        $iVal = DllStructGetData($tUInt, 1)
        If $iVal <> 0x00004550 Then
            $iError = 4
            ExitLoop
        EndIf
        $aRet = DllCall('kernel32.dll', 'bool', 'ReadFile', 'handle', $hFile, 'struct*', $tData, 'dword', 2, 'dword*', 0, 'ptr', 0)
        If @error Or (Not $aRet[0]) Or ($aRet[4] <> 2) Then
            $iError = @error + 80
            ExitLoop
        EndIf
        $iVal = DllStructGetData($tData, 1, 1)
    Until 1
    DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hFile)
    If $iError Then Return SetError($iError, 0, 0)

    Return $iVal
EndFunc   ;==>_WinAPI_GetPEType

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetProfilesDirectory()
    Local $aRet = DllCall('userenv.dll', 'bool', 'GetProfilesDirectoryW', 'wstr', '', 'dword*', 4096)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, '')

    Return $aRet[1]
EndFunc   ;==>_WinAPI_GetProfilesDirectory

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetTempFileName($sFilePath, $sPrefix = '')
    Local $aRet = DllCall('kernel32.dll', 'uint', 'GetTempFileNameW', 'wstr', $sFilePath, 'wstr', $sPrefix, 'uint', 0, 'wstr', '')
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, '')

    Return $aRet[4]
EndFunc   ;==>_WinAPI_GetTempFileName

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetVolumeInformation($sRoot = '')
    Local $sTypeOfRoot = 'wstr'
    If Not StringStripWS($sRoot, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfRoot = 'ptr'
        $sRoot = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetVolumeInformationW', $sTypeOfRoot, $sRoot, 'wstr', '', 'dword', 4096, _
            'dword*', 0, 'dword*', 0, 'dword*', 0, 'wstr', '', 'dword', 4096)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

    Local $aResult[5]
    For $i = 0 To 4
        Switch $i
            Case 0
                $aResult[$i] = $aRet[2]
            Case Else
                $aResult[$i] = $aRet[$i + 3]
        EndSwitch
    Next
    Return $aResult
EndFunc   ;==>_WinAPI_GetVolumeInformation

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_GetVolumeInformationByHandle($hFile)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetVolumeInformationByHandleW', 'handle', $hFile, 'wstr', '', 'dword', 4096, _
            'dword*', 0, 'dword*', 0, 'dword*', 0, 'wstr', '', 'dword', 4096)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

    Local $aResult[5]
    For $i = 0 To 4
        Switch $i
            Case 0
                $aResult[$i] = $aRet[2]
            Case Else
                $aResult[$i] = $aRet[$i + 3]
        EndSwitch
    Next
    Return $aResult
EndFunc   ;==>_WinAPI_GetVolumeInformationByHandle

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_GetVolumeNameForVolumeMountPoint($sMountedPath)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'GetVolumeNameForVolumeMountPointW', 'wstr', $sMountedPath, 'wstr', '', 'dword', 80)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, '')

    Return $aRet[2]
EndFunc   ;==>_WinAPI_GetVolumeNameForVolumeMountPoint

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......:
; ===============================================================================================================================
Func _WinAPI_IOCTL($iDeviceType, $iFunction, $iMethod, $iAccess)
    Return BitOR(BitShift($iDeviceType, -16), BitShift($iAccess, -14), BitShift($iFunction, -2), $iMethod)
EndFunc   ;==>_WinAPI_IOCTL

; #FUNCTION# ====================================================================================================================
; Author.........: G.Sandler (CreatoR)
; Modified.......: Yashied, jpm
; ===============================================================================================================================
Func _WinAPI_IsDoorOpen($sDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, $GENERIC_READWRITE, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, False)

    Local $tSPT = DllStructCreate('ushort Length;byte ScsiStatus;byte PathId;byte TargetId;byte Lun;byte CdbLength;byte SenseInfoLength;byte DataIn;byte Alignment[3];ulong DataTransferLength;ulong TimeOutValue;ulong_ptr DataBufferOffset;ulong SenseInfoOffset;byte Cdb[16]' & __Iif(@AutoItX64, ';byte[4]', '') & ';byte Hdr[8]')
    Local $tCDB = DllStructCreate('byte;byte;byte[6];byte[2];byte;byte;byte[4]', DllStructGetPtr($tSPT, 'Cdb'))
    Local $tHDR = DllStructCreate('byte;byte;byte[3];byte;byte[2]', DllStructGetPtr($tSPT, 'Hdr'))
    Local $iSize = DllStructGetPtr($tSPT, 'Hdr') - DllStructGetPtr($tSPT)

    DllStructSetData($tSPT, 'Length', $iSize)
    DllStructSetData($tSPT, 'ScsiStatus', 0)
    DllStructSetData($tSPT, 'PathId', 0)
    DllStructSetData($tSPT, 'TargetId', 0)
    DllStructSetData($tSPT, 'Lun', 0)
    DllStructSetData($tSPT, 'CdbLength', 12)
    DllStructSetData($tSPT, 'SenseInfoLength', 0)
    DllStructSetData($tSPT, 'DataIn', 1)
    DllStructSetData($tSPT, 'DataTransferLength', 8)
    DllStructSetData($tSPT, 'TimeOutValue', 86400)
    DllStructSetData($tSPT, 'DataBufferOffset', $iSize)
    DllStructSetData($tSPT, 'SenseInfoOffset', 0)

    DllStructSetData($tCDB, 1, 0xBD)
    DllStructSetData($tCDB, 2, 0)
    DllStructSetData($tCDB, 4, 0, 1)
    DllStructSetData($tCDB, 4, 8, 2)
    DllStructSetData($tCDB, 5, 0)
    DllStructSetData($tCDB, 6, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x0004D004, 'struct*', $tSPT, _
            'dword', $iSize, 'struct*', $tSPT, 'dword', DllStructGetSize($tSPT), 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, False)

    Return (BitAND(DllStructGetData($tHDR, 2), 0x10) = 0x10)
EndFunc   ;==>_WinAPI_IsDoorOpen

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_IsPathShared($sFilePath)
    If Not __DLL('ntshrui.dll') Then Return SetError(103, 0, 0)

    Local $aRet = DllCall('ntshrui.dll', 'bool', 'IsPathSharedW', 'wstr', _WinAPI_PathRemoveBackslash($sFilePath), 'int', 1)
    If @error Then Return SetError(@error, @extended, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_IsPathShared

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: JPM
; ===============================================================================================================================
Func _WinAPI_IsWritable($sDrive)
    ; to check if the Drive is Ready
    DriveGetFileSystem($sDrive)
    If @error Then Return SetError(40 + @error, _WinAPI_GetLastError(), 0)

    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x00070024, 'ptr', 0, 'dword', 0, _
            'ptr', 0, 'dword', 0, 'dword*', 0, 'ptr', 0)
    Local Const $ERROR_WRITE_PROTECT = 19 ; The media is write protected.
    If __CheckErrorCloseHandle($aRet, $hFile, 1) <> 10 And @extended = $ERROR_WRITE_PROTECT Then Return SetError(@error, @extended, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_IsWritable

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_LoadMedia($sDrive)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, $GENERIC_READ, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, False)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D480C, 'ptr', 0, 'dword', 0, _
            'ptr', 0, 'dword', 0, 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, False)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_LoadMedia

; #FUNCTION# ====================================================================================================================
; Author.........: Psandu.ro
; Modified.......: Yashied, jpm
; ===============================================================================================================================
Func _WinAPI_LockDevice($sDrive, $bLock)
    Local $hFile = _WinAPI_CreateFileEx('\\.\' & $sDrive, $OPEN_EXISTING, $GENERIC_READWRITE, $FILE_SHARE_READWRITE)
    If @error Then Return SetError(@error + 20, @extended, False)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x002D4804, 'boolean*', $bLock, _
            'dword', 1, 'ptr', 0, 'dword', 0, 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, False)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_LockDevice

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_LockFile($hFile, $iOffset, $iLength)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'LockFile', 'handle', $hFile, _
            'dword', _WinAPI_LoDWord($iOffset), 'dword', _WinAPI_HiDWord($iOffset), _
            'dword', _WinAPI_LoDWord($iLength), 'dword', _WinAPI_HiDWord($iLength))
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_LockFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_MapViewOfFile($hMapping, $iOffset = 0, $iBytes = 0, $iAccess = 0x0006)
    Local $aRet = DllCall('kernel32.dll', 'ptr', 'MapViewOfFile', 'handle', $hMapping, 'dword', $iAccess, _
            'dword', _WinAPI_HiDWord($iOffset), 'dword', _WinAPI_LoDWord($iOffset), 'ulong_ptr', $iBytes)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_MapViewOfFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_MoveFileEx($sExistingFile, $sNewFile, $iFlags = 0, $pProgressProc = 0, $pData = 0)
    Local $sTypeOfNewFile = 'wstr'
    If Not StringStripWS($sNewFile, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfNewFile = 'ptr'
        $sNewFile = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'bool', 'MoveFileWithProgressW', 'wstr', $sExistingFile, $sTypeOfNewFile, $sNewFile, _
            'ptr', $pProgressProc, 'ptr', $pData, 'dword', $iFlags)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_MoveFileEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_OpenFileById($hFile, $vID, $iAccess = 0, $iShare = 0, $iFlags = 0)
    Local $tFIDD = DllStructCreate('dword;uint;int64;int64')
    Local $hObj, $aRet, $iType, $iError = 0

    Select
        Case IsString($vID)
            $aRet = DllCall('ole32.dll', 'long', 'CLSIDFromString', 'wstr', $vID, 'ptr', DllStructGetPtr($tFIDD, 3))
            If @error Or $aRet[0] Then
                Return SetError(@error + 30, 0, 0)
            EndIf
            $iType = 1
        Case IsDllStruct($vID)
            If Not _WinAPI_MoveMemory(DllStructGetPtr($tFIDD, 3), DllStructGetPtr($vID), 16) Then
                Return SetError(@error + 40, 0, 0)
            EndIf
            $iType = 1
        Case Else
            DllStructSetData($tFIDD, 3, $vID)
            $iType = 0
    EndSelect
    DllStructSetData($tFIDD, 1, DllStructGetSize($tFIDD))
    DllStructSetData($tFIDD, 2, $iType)
    If IsString($hFile) Then
        ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
        $hObj = _WinAPI_CreateFileEx($hFile, $OPEN_EXISTING, 0, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
        If @error Then Return SetError(@error + 20, @extended, 0)
    Else
        $hObj = $hFile
    EndIf
    $aRet = DllCall('kernel32.dll', 'handle', 'OpenFileById', 'handle', $hObj, 'struct*', $tFIDD, 'dword', $iAccess, _
            'dword', $iShare, 'ptr', 0, 'dword', $iFlags)
    If @error Or ($aRet[0] = Ptr(-1)) Then $iError = @error + 10 ; $INVALID_HANDLE_VALUE
    If IsString($hFile) Then
        DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hObj)
    EndIf
    If $iError Then Return SetError($iError, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_OpenFileById

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_OpenFileMapping($sName, $iAccess = 0x0006, $bInherit = False)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'OpenFileMappingW', 'dword', $iAccess, 'bool', $bInherit, 'wstr', $sName)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_OpenFileMapping

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_PathIsDirectoryEmpty($sFilePath)
    Local $aRet = DllCall('shlwapi.dll', 'bool', 'PathIsDirectoryEmptyW', 'wstr', $sFilePath)
    If @error Then Return SetError(@error, @extended, False)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_PathIsDirectoryEmpty

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_QueryDosDevice($sDevice)
    Local $sTypeOfDevice = 'wstr'
    If Not StringStripWS($sDevice, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfDevice = 'ptr'
        $sDevice = 0
    EndIf

    Local $tData = DllStructCreate('wchar[16384]')
    Local $aRet = DllCall('kernel32.dll', 'dword', 'QueryDosDeviceW', $sTypeOfDevice, $sDevice, 'struct*', $tData, 'dword', 16384)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, '')

    Local $aResult = _WinAPI_StructToArray($tData)
    If IsString($sDevice) Then
        $aResult = $aResult[1]
    EndIf
    Return $aResult
EndFunc   ;==>_WinAPI_QueryDosDevice

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_ReadDirectoryChanges($hDirectory, $iFilter, $pBuffer, $iLength, $bSubtree = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'ReadDirectoryChangesW', 'handle', $hDirectory, 'struct*', $pBuffer, _
            'dword', $iLength - Mod($iLength, 4), 'bool', $bSubtree, 'dword', $iFilter, 'dword*', 0, 'ptr', 0, 'ptr', 0)
    If @error Or Not $aRet[0] Or (Not $aRet[6]) Then Return SetError(@error + 10, @extended, 0)

    $pBuffer = $aRet[2] ; if updated by the DllCall in case of not word align
    Local $aData[101][2] = [[0]]
    Local $tFNI, $iBuffer = 0, $iOffset = 0

    Do
        $iBuffer += $iOffset
        $tFNI = DllStructCreate('dword NextEntryOffset;dword Action;dword FileNameLength;wchar FileName[' & (DllStructGetData(DllStructCreate('dword FileNameLength', $pBuffer + $iBuffer + 8), 1) / 2) & ']', $pBuffer + $iBuffer)
        __Inc($aData)
        $aData[$aData[0][0]][0] = DllStructGetData($tFNI, "FileName")
        $aData[$aData[0][0]][1] = DllStructGetData($tFNI, "Action")
        $iOffset = DllStructGetData($tFNI, "NextEntryOffset")
    Until Not $iOffset
    __Inc($aData, -1)
    Return $aData
EndFunc   ;==>_WinAPI_ReadDirectoryChanges

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_RemoveDirectory($sDirPath)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'RemoveDirectoryW', 'wstr', $sDirPath)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_RemoveDirectory

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_ReOpenFile($hFile, $iAccess, $iShare, $iFlags = 0)
    Local $aRet = DllCall('kernel32.dll', 'handle', 'ReOpenFile', 'handle', $hFile, 'dword', $iAccess, 'dword', $iShare, 'dword', $iFlags)
    If @error Or ($aRet[0] = Ptr(-1)) Then Return SetError(@error, @extended, 0) ; $INVALID_HANDLE_VALUE
    ; If $aRet[0] = Ptr(-1) Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_ReOpenFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_ReplaceFile($sReplacedFile, $sReplacementFile, $sBackupFile = '', $iFlags = 0)
    Local $sTypeOfBackupFile = 'wstr'
    If Not StringStripWS($sBackupFile, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfBackupFile = 'ptr'
        $sBackupFile = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'bool', 'ReplaceFileW', 'wstr', $sReplacedFile, 'wstr', $sReplacementFile, _
            $sTypeOfBackupFile, $sBackupFile, 'dword', $iFlags, 'ptr', 0, 'ptr', 0)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_ReplaceFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SearchPath($sFilePath, $sSearchPath = '')
    Local $sTypeOfPath = 'wstr'
    If Not StringStripWS($sSearchPath, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTypeOfPath = 'ptr'
        $sSearchPath = 0
    EndIf

    Local $aRet = DllCall('kernel32.dll', 'dword', 'SearchPathW', $sTypeOfPath, $sSearchPath, 'wstr', $sFilePath, 'ptr', 0, 'dword', 4096, 'wstr', '', 'ptr', 0)
    If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, '')
    ; If Not $aRet[0] Then Return SetError(1000, 0, '')

    Return $aRet[5]
EndFunc   ;==>_WinAPI_SearchPath

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_SetCompression($sFilePath, $iCompression)
    ; Local Const $FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
    Local $hFile = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_READWRITE, $FILE_SHARE_READWRITE, $FILE_FLAG_BACKUP_SEMANTICS)
    If @error Then Return SetError(@error + 20, @extended, 0)

    Local $aRet = DllCall('kernel32.dll', 'bool', 'DeviceIoControl', 'handle', $hFile, 'dword', 0x0009C040, _
            'ushort*', $iCompression, 'dword', 2, 'ptr', 0, 'dword', 0, 'dword*', 0, 'ptr', 0)
    If __CheckErrorCloseHandle($aRet, $hFile) Then Return SetError(@error, @extended, 0)

    Return 1
EndFunc   ;==>_WinAPI_SetCompression

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetCurrentDirectory($sDir)
    Local $aRet = DllCall('kernel32.dll', 'int', 'SetCurrentDirectoryW', 'wstr', $sDir)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetCurrentDirectory

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetFileAttributes($sFilePath, $iAttributes)
    Local $aRet = DllCall('kernel32.dll', 'int', 'SetFileAttributesW', 'wstr', $sFilePath, 'dword', $iAttributes)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetFileAttributes

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_SetFileInformationByHandleEx($hFile, $tFILEINFO)
    Local $aRet = DllCall('ntdll.dll', 'long', 'ZwSetInformationFile', 'handle', $hFile, 'struct*', $tFILEINFO, _
            'struct*', $tFILEINFO, 'ulong', DllStructGetSize($tFILEINFO), 'uint', 4)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRet[0] Then Return SetError(10, $aRet[0], 0)

    Return 1
EndFunc   ;==>_WinAPI_SetFileInformationByHandleEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetFilePointerEx($hFile, $iPos, $iMethod = 0)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'SetFilePointerEx', 'handle', $hFile, 'int64', $iPos, 'int64*', 0, 'dword', $iMethod)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetFilePointerEx

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetFileShortName($hFile, $sShortName)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'SetFileShortNameW', 'handle', $hFile, 'wstr', $sShortName)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetFileShortName

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetFileValidData($hFile, $iLength)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'SetFileValidData', 'handle', $hFile, 'int64', $iLength)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetFileValidData

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetSearchPathMode($iFlags)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'SetSearchPathMode', 'dword', $iFlags)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetSearchPathMode

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_SetVolumeMountPoint($sFilePath, $sGUID)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'SetVolumeMountPointW', 'wstr', $sFilePath, 'wstr', $sGUID)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SetVolumeMountPoint

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm
; ===============================================================================================================================
Func _WinAPI_SfcIsFileProtected($sFilePath)
    If Not __DLL('sfc.dll') Then Return SetError(103, 0, False)

    Local $aRet = DllCall('sfc.dll', 'bool', 'SfcIsFileProtected', 'handle', 0, 'wstr', $sFilePath)
    If @error Then Return SetError(@error, @extended, False)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_SfcIsFileProtected

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_UnlockFile($hFile, $iOffset, $iLength)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'UnlockFile', 'handle', $hFile, _
            'dword', _WinAPI_LoDWord($iOffset), 'dword', _WinAPI_HiDWord($iOffset), _
            'dword', _WinAPI_LoDWord($iLength), 'dword', _WinAPI_HiDWord($iLength))
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_UnlockFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_UnmapViewOfFile($pAddress)
    Local $aRet = DllCall('kernel32.dll', 'bool', 'UnmapViewOfFile', 'ptr', $pAddress)
    If @error Then Return SetError(@error, @extended, False)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_UnmapViewOfFile

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: Jpm
; ===============================================================================================================================
Func _WinAPI_Wow64EnableWow64FsRedirection($bEnable)
    Local $aRet = DllCall('kernel32.dll', 'boolean', 'Wow64EnableWow64FsRedirection', 'boolean', $bEnable)
    If @error Then Return SetError(@error, @extended, 0)
    ; If Not $aRet[0] Then Return SetError(1000, 0, 0)

    Return $aRet[0]
EndFunc   ;==>_WinAPI_Wow64EnableWow64FsRedirection

#EndRegion Public Functions

#Region Internal Functions

Func __WinAPI_MakeQWord($iLoDWORD, $iHiDWORD)
    Local $tInt64 = DllStructCreate("uint64")
    Local $tDwords = DllStructCreate("dword;dword", DllStructGetPtr($tInt64))
    DllStructSetData($tDwords, 1, $iLoDWORD)
    DllStructSetData($tDwords, 2, $iHiDWORD)

    Return DllStructGetData($tInt64, 1)
EndFunc   ;==>__WinAPI_MakeQWord

#EndRegion Internal Functions

@ruflin
Copy link
Member

ruflin commented Jun 13, 2016

@BellBiker Any chance to test this again with 5.0.0-alpha3 of filebeat? https://www.elastic.co/downloads/beats/filebeat Quite a bit of refactoring happened in the file crawling and the handling of modified time, which makes me think this could be fixed?

@BellBiker
Copy link
Author

Hello,
I did several attempts. First of all I tried it running JBOSS and filebeat 1.1.1 and 5.0.0.. against a local machine and everything works as expected fine.

But running the JBOSS on a different machine than the filebeat causes the same result whether I am running the filebeat 1.1.1 or the filebeat 5.0.0.. After the first rotation filebeat stops harvesting logs and I got the same trouble with the file information as described above. The rotated file and the new log file both provide the same file information regarding idxLo and idxHi and if the rotated file reaches the max number of rotated files the rotation stops and the log file, which has to be rotated, increases unlimited until I stop filebeat.

Sorry for this bad news. Only to be clear. I only exchanged filebeat. The remaining ELK stack stays on the old versions.

@ruflin
Copy link
Member

ruflin commented Jun 16, 2016

Thanks for testing. By 5.0.0 I assume you mean alpha3 or the nightly snapshot? As it works locally, there seem to be really some more challenges with the shared volumes. If the file system does only deliver cached information to filebeat, I'm not sure how could work around this. Filebeat could try to invalidate the cache but I don't think that should be the job of filebeat.

The good news for me is that it works as expected on the same machine as that is where we think filebeat should be. Is there in your case something blocking you from installing it on the same machine?

@BellBiker
Copy link
Author

My tests are based on 5.0.0_alpha3.

The important point from my view is, that filebeat seems to be the root cause that the file information is wrong. As long as filebeat does not run the file information is changed immediately during the rotation.

As a result of the problem I have installed filebeat as a service on those machines. It causes some additional work, but this is feasible. And meanwhile I have learned that I am able to start and stop the service after installation remotely without an rdp-session. So for the moment its ok for me.

But if it comes to the point that we want to run filebeat against more test installations the overhead increases. In this case it would be fine to have this issue fixed to manage the whole stack from one location without any filebeat distribution.

@ruflin
Copy link
Member

ruflin commented Jun 16, 2016

The important point from my view is, that filebeat seems to be the root cause that the file information is wrong. As long as filebeat does not run the file information is changed immediately during the rotation.

I think that is a critical point I somehow have missed so far. Did you ever try to use force_close_files: https://www.elastic.co/guide/en/beats/filebeat/1.2/configuration-filebeat-options.html#_force_close_files ?

@BellBiker
Copy link
Author

Based on the comment provide to this property within the yaml-template file I always changed this property to the value true.

@ruflin
Copy link
Member

ruflin commented Jun 17, 2016

@BellBiker Ok, that seems like no luck here. TBH I'm still not 100% sure what happens here. If filebeat reaches the end of a file and force_close_files was enabled, filebeat should close the file handler. That means also afterwards updating the file should work again as expected as filebeat does not keep it open.

@ruflin
Copy link
Member

ruflin commented Jul 18, 2016

@BellBiker Several new config options to close a harvester were introduced in the nightly builds: #1600 (comment) It would be interesting to hear if one of these options help in your case. Also in #2020 we fix a bug that could lead in some special cases to some open file handlers which could potentially explain your problem. Any chance to test the nightly builds on your side as soon as #2020 is merged?

@BellBiker
Copy link
Author

@ruflin Sorry, due to other tasks and my vacation I cannot try this before end of August. I will create an reminder to myself.

@ruflin
Copy link
Member

ruflin commented Jul 19, 2016

@BellBiker Thanks. Enjoy your vacations. We will keep investigating. I will post here in case we find some more issues.

@ruflin
Copy link
Member

ruflin commented Aug 31, 2016

@BellBiker Any updates on this?

@BellBiker
Copy link
Author

@ruflin Except the fact that I can confirm that the problem further persists I am fully packed with other work. Therefore I have to apologize that I can't dig into this problem within the next weeks.

@ruflin
Copy link
Member

ruflin commented Sep 7, 2016

@BellBiker Thans for the quick update. No worries, will keep digging here. Thanks for all the help so far. By still exists, which version are you referring to?

@ruflin
Copy link
Member

ruflin commented May 23, 2017

I'm closing this issue as since the 5.0 GA release the only "similar" cases we have seen to this is with network drives and in the end it always came down to wiered caching or even null values coming from the network drive which cannot be really fixed in filebeat. One of the ides to fix this can be found in this issue here: #3501

@BellBiker I really appreciate all the effort you put into this. I would love to be all bug reports so detailed. I'm strongly recommending that you install filebeat on each node if possible which should resolve this issue.

@ruflin ruflin closed this as completed May 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants