//************************************************************************ //*** FileSystem - Binary file operations For VDF15+. //************************************************************************ //*** Based on original package: akefs.pkg //*** Version: 4.0 //*** (C) NordTeam Gruppen, NOVAX A/S //*** //*** Author......: Allan Kim Eriksen //*** Created.....: 23/08 2001 //*** //*** Rev History.: 31/08 2018 Nils Svedmyr. Added Functions from Akefs.pkg //*** to get/set file date/time and procedure SetFileLastWriteTime. //*** Refactored functions FileSize & FileDate to only have one Function_Return, //*** and changed a couple of While loops to end with a "loop" word instead of "End". //*** //************************************************************************ // cFilesystem class with functions and procedures to access binary files. // Filenumbers are not limited to 10 but only to system resources. // Also windows API calls For file copy, file move ect. // This class is For vdf 15 and up. // This class is not limited to 2 GB but can handle filesizes up $7FFFFFFFFFFFFFFF (9 exabyte) //************************************************************************ // Be aware that argument_size has to be larger // than the requested amount of bytes read in the buffer for // BytesFromBinaryFile. //************************************************************************ //************************************************************************ // Constants used For the external functions. //************************************************************************ // fsCreatefile. #IFNDEF GENERIC_READ Define GENERIC_READ for |CI$80000000 #ENDIF #IFNDEF GENERIC_WRITE Define GENERIC_WRITE for |CI$40000000 #ENDIF #IFNDEF GENERIC_RANDOM Define GENERIC_RANDOM for (GENERIC_READ + GENERIC_WRITE) #ENDIF #IFNDEF CREATE_NEW Define CREATE_NEW for |CI$00000001 #ENDIF #IFNDEF CREATE_ALWAYS Define CREATE_ALWAYS for |CI$00000002 #ENDIF #IFNDEF OPEN_EXISTING Define OPEN_EXISTING for |CI$00000003 #ENDIF #IFNDEF OPEN_ALWAYS Define OPEN_ALWAYS for |CI$00000004 #ENDIF #IFNDEF TRUNCATE_EXISTING Define TRUNCATE_EXISTING for |CI$00000005 #ENDIF #IFNDEF FILE_ATTRIBUTE_NORMAL Define FILE_ATTRIBUTE_NORMAL for |CI$00000080 #ENDIF #IFNDEF FILE_SHARE_READ Define FILE_SHARE_READ for |CI$1 #ENDIF #IFNDEF FILE_SHARE_WRITE Define FILE_SHARE_WRITE for |CI$2 #ENDIF #IFNDEF FILE_SHARE_RANDOM Define FILE_SHARE_RANDOM for (FILE_SHARE_READ + FILE_SHARE_WRITE) #ENDIF // Generel. Define FNULL For |CI$0 // FormatString. #IFNDEF FORMAT_MESSAGE_ALLOCATE_BUFFER Define FORMAT_MESSAGE_ALLOCATE_BUFFER For |CI$0100 Define FORMAT_MESSAGE_IGNORE_INSERTS For |CI$0200 Define FORMAT_MESSAGE_FROM_STRING For |CI$0400 Define FORMAT_MESSAGE_FROM_HMODULE For |CI$0800 Define FORMAT_MESSAGE_FROM_SYSTEM For |CI$1000 Define FORMAT_MESSAGE_ARGUMENT_ARRAY For |CI$2000 Define FORMAT_MESSAGE_MAX_WIDTH_MASK For |CI$00FF #ENDIF // SetFilePosition. #IFNDEF FILE_BEGIN Define FILE_BEGIN For 0 Define FILE_CURRENT For 1 Define FILE_END For 2 Define INVALID_SET_FILE_POINTER For |CI$FFFFFFFF #ENDIF // FindFile. #IFNDEF INVALID_HANDLE_VALUE Define INVALID_HANDLE_VALUE For |CI-1 Define INVALID_FILE_SIZE For |CI$FFFFFFFF #ENDIF #IFNDEF ERROR_NO_MORE_FILES Define ERROR_NO_MORE_FILES For |CI18 Define ERROR_MOD_NOT_FOUND For |CI126 #ENDIF #IFNDEF MAX_PATH Define MAX_PATH For 260 #ENDIF #IFNDEF FILE_ATTRIBUTE_READONLY Define FILE_ATTRIBUTE_READONLY For |CI$01 #ENDIF #IFNDEF FILE_ATTRIBUTE_HIDDEN Define FILE_ATTRIBUTE_HIDDEN For |CI$02 #ENDIF #IFNDEF FILE_ATTRIBUTE_SYSTEM Define FILE_ATTRIBUTE_SYSTEM For |CI$04 #ENDIF #IFNDEF FILE_ATTRIBUTE_DIRECTORY Define FILE_ATTRIBUTE_DIRECTORY For |CI$10 #ENDIF #IFNDEF FILE_ATTRIBUTE_ARCHIVE Define FILE_ATTRIBUTE_ARCHIVE For |CI$20 #ENDIF #IFNDEF FILE_ATTRIBUTE_NORMAL Define FILE_ATTRIBUTE_NORMAL For |CI$80 #ENDIF #IFNDEF FILE_ATTRIBUTE_TEMPORARY Define FILE_ATTRIBUTE_TEMPORARY For |CI$100 #ENDIF #IFNDEF FILE_ATTRIBUTE_SPARSE_FILE Define FILE_ATTRIBUTE_SPARSE_FILE For |CI$200 #ENDIF #IFNDEF FILE_ATTRIBUTE_REPARSE_POINT Define FILE_ATTRIBUTE_REPARSE_POINT For |CI$400 #ENDIF #IFNDEF FILE_ATTRIBUTE_COMPRESSED Define FILE_ATTRIBUTE_COMPRESSED For |CI$800 #ENDIF #IFNDEF FILE_ATTRIBUTE_OFFLINE Define FILE_ATTRIBUTE_OFFLINE For |CI$1000 #ENDIF #IFNDEF FILE_ATTRIBUTE_NOT_CONTENT_INDEXED Define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED For |CI$2000 #ENDIF #IFNDEF FILE_ATTRIBUTE_ENCRYPTED Define FILE_ATTRIBUTE_ENCRYPTED For |CI$4000 #ENDIF // Flags For tsVS_FIXEDFILEINFO.dwFileFlags. #IFNDEF VS_FF_DEBUG Define VS_FF_DEBUG For |CI$01 Define VS_FF_INFOINFERRED For |CI$10 Define VS_FF_PATCHED For |CI$04 Define VS_FF_PRERELEASE For |CI$02 Define VS_FF_PRIVATEBUILD For |CI$08 Define VS_FF_SPECIALBUILD For |CI$20 #ENDIF // Flags For tsVS_FIXEDFILEINFO.dwFileOS. #IFNDEF VOS_DOS Define VOS_DOS For |CI$10000 Define VOS_NT For |CI$40000 Define VOS_WINDOWS16 For |CI$00001 Define VOS_WINDOWS32 For |CI$00004 Define VOS_OS216 For |CI$20000 Define VOS_OS232 For |CI$30000 Define VOS_PM16 For |CI$00002 Define VOS_PM32 For |CI$00003 Define VOS_UNKNOWN For |CI$00000 #ENDIF // Flags For tsVS_FIXEDFILEINFO.dwFileType. #IFNDEF VFT_APP Define VFT_APP For |CI$01 Define VFT_DLL For |CI$02 Define VFT_DRV For |CI$03 Define VFT_FONT For |CI$04 Define VFT_STATIC_LIB For |CI$07 Define VFT_UNKNOWN For |CI$00 Define VFT_VXD For |CI$05 #ENDIF // Flags For tsVS_FIXEDFILEINFO.dwFileSubtype if tsVS_FIXEDFILEINFO.dwFileType = VFT_DRV. #IFNDEF VFT2_DRV_COMM Define VFT2_DRV_COMM For |CI$0A Define VFT2_DRV_DISPLAY For |CI$04 Define VFT2_DRV_INSTALLABLE For |CI$08 Define VFT2_DRV_KEYBOARD For |CI$02 Define VFT2_DRV_LANGUAGE For |CI$03 Define VFT2_DRV_MOUSE For |CI$05 Define VFT2_DRV_NETWORK For |CI$06 Define VFT2_DRV_PRINTER For |CI$01 Define VFT2_DRV_SOUND For |CI$09 Define VFT2_DRV_SYSTEM For |CI$07 Define VFT2_DRV_VERSIONED_PRINTER For |CI$0C #ENDIF // Flags For tsVS_FIXEDFILEINFO.dwFileSubtype if tsVS_FIXEDFILEINFO.dwFileType = VFT_FONT. #IFNDEF VFT2_FONT_RASTER Define VFT2_FONT_RASTER For |CI$01 Define VFT2_FONT_TRUETYPE For |CI$03 Define VFT2_FONT_VECTOR For |CI$02 #ENDIF #IFNDEF VFT2_UNKNOWN Define VFT2_UNKNOWN For |CI$00 #ENDIF Define FS_FILEHANDLEMISSING For "The filehandle does not exists For the current filenumber." // Filesearch Enum_List Define DIRMODE_FILES_ONLY For 1 Define DIRMODE_DIRECTORIES_ONLY Define DIRMODE_FILES_AND_DIRECTORIES End_Enum_List //************************************************************************ // Declarations of external functions. // Functions that needs variables For output are made global stings or // integers, and can be found on top of the declaration. //************************************************************************ #IF (!@ < 200) External_Function fsCreatefile "CreateFileA" kernel32.dll ; String sFile ; //filename DWord dwDesAccess ; // access mode DWord dwShare ; // share mode Pointer lpSecAtt ; // SD DWord dwCrDisp ; // how to create DWord dwFlags ; // file attributes Handle hTempFile ; // handle to template fil Returns Integer //Returns handle that can be used to access the object #ELSE External_Function fsCreatefile "CreateFileW" kernel32.dll ; WString wFile ; //filename DWord dwDesAccess ; // access mode DWord dwShare ; // share mode Pointer lpSecAtt ; // SD DWord dwCrDisp ; // how to create DWord dwFlags ; // file attributes Handle hTempFile ; // handle to template fil Returns Integer //Returns handle that can be used to access the object #ENDIF External_Function fsGetLastError "GetLastError" kernel32.dll Returns Integer #IF (!@ < 200) External_Function fsFormatMessage "FormatMessageA" kernel32.dll ; DWord dwFlags ; // source and processing options Pointer lpSrc ; // message source DWord dwMsgId ; // message identifier DWord dwLngId ; // language identifier Pointer lpBuf ; // message buffer DWord nSize ; // maximum size of message buffer Pointer Arg ; // array of message inserts Returns Integer #ELSE External_Function fsFormatMessage "FormatMessageW" kernel32.dll ; DWord dwFlags ; // source and processing options Pointer lpSrc ; // message source DWord dwMsgId ; // message identifier DWord dwLngId ; // language identifier Pointer lpBuf ; // message buffer DWord nSize ; // maximum size of message buffer Pointer Arg ; // array of message inserts Returns Integer #ENDIF External_Function fsLocalFree "LocalFree" kernel32.dll ; Handle hMem ; // A handle to the local memory object. Returns Integer External_Function fsCloseHandle "CloseHandle" kernel32.dll ; Handle hObject ; // handle to object Returns Integer External_Function fsReadFile "ReadFile" kernel32.dll ; Handle hFile ; // handle to file Pointer lpBuffer ; // data buffer DWord nBytesToRead ; // number of bytes to read Pointer lpBytesRead ; // number of bytes read Pointer lpOverlapped ; // overlapped buffer Returns Integer External_Function fsWriteFile "WriteFile" kernel32.dll ; Handle hFile ; // handle to file Pointer lpBuf ; // data buffer DWord nNumBytesWrt ; // number of bytes to write Pointer lpNumBytesWritten ; // number of bytes written Pointer lpOverlapped ; // overlapped buffer Returns Integer External_Function fsGetFileSizeEx "GetFileSizeEx" kernel32.dll ; Handle hFile ; // handle to file Pointer lpFileSizeHigh ; // A pointer to a LARGE_INTEGER structure that receives the file size, in bytes. Returns Integer External_Function fsSetFilePointer "SetFilePointer" kernel32.dll ; Handle hFile ; // handle to file UInteger lDistanceToMove ; // The low order 32-bits of a signed value that specifies the number of bytes to move the file pointer. Pointer lpDistanceToMoveHigh ; // A pointer to the high order 32-bits of the signed 64-bit distance to move. DWord dwMoveMethod ; // The starting point For the file pointer move. Returns UInteger External_Function fsSetEndOfFile "SetEndOfFile" kernel32.dll ; Handle hFile ; // handle to the file to have its EOF position moved. Returns Integer // nonzero if success #IF (!@ < 200) External_Function fsDeleteFile "DeleteFileA" Kernel32.Dll ; String sFileName ; // Pointer to a null-terminated string that specifies the file to be deleted. Returns Integer External_Function fsMoveFile "MoveFileA" Kernel32.Dll ; String sExistingFileName ; // Pointer to a null-terminated string that names an existing file or directory. String sNewFileName ; // Pointer to a null-terminated string that specifies the new name of a file or directory. Returns Integer // The new name must Not already exist. A new File may be on A different File system Or drive. A new directory must be on the same drive. External_Function fsCopyFile "CopyFileA" Kernel32.Dll ; String sExistingFileName ; // Pointer to a null-terminated string that specifies the name of an existing file. String sNewFileName ; // Pointer to a null-terminated string that specifies the name of the new file. Boolean bFailIfExists ; // If bFailIfExists is TRUE and the new file specified by lpNewFileName already exists, the function fails. Returns Integer // If bFailIfExists is FALSE and the new file already exists, the function overwrites the existing file and succeeds. External_Function fsFindFirstFile "FindFirstFileA" Kernel32.Dll ; String sFileName ; // Pointer to a null-terminated string that specifies a valid directory or path and file name, which can contain wildcard characters (* and ?). Pointer lpWin32_Find_Data ; // Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. Returns Integer External_Function fsFindNextFile "FindNextFileA" Kernel32.Dll ; Handle hFindFile ; // handle returned by a previous call to the FindFirstFile function. Pointer lpWin32_Find_Data ; // Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. Returns Integer #ELSE External_Function fsDeleteFile "DeleteFileW" Kernel32.Dll ; WString wFileName ; // Pointer to a null-terminated string that specifies the file to be deleted. Returns Integer External_Function fsMoveFile "MoveFileW" Kernel32.Dll ; WString sExistingFileName ; // Pointer to a null-terminated string that names an existing file or directory. WString sNewFileName ; // Pointer to a null-terminated string that specifies the new name of a file or directory. Returns Integer // The new name must Not already exist. A new File may be on A different File system Or drive. A new directory must be on the same drive. External_Function fsCopyFile "CopyFileW" Kernel32.Dll ; WString sExistingFileName ; // Pointer to a null-terminated string that specifies the name of an existing file. WString sNewFileName ; // Pointer to a null-terminated string that specifies the name of the new file. Boolean bFailIfExists ; // If bFailIfExists is TRUE and the new file specified by lpNewFileName already exists, the function fails. Returns Integer // If bFailIfExists is FALSE and the new file already exists, the function overwrites the existing file and succeeds. External_Function fsFindFirstFile "FindFirstFileW" Kernel32.Dll ; WString wFileName ; // Pointer to a null-terminated string that specifies a valid directory or path and file name, which can contain wildcard characters (* and ?). Pointer lpWin32_Find_Data ; // Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. Returns Integer External_Function fsFindNextFile "FindNextFileW" Kernel32.Dll ; Handle hFindFile ; // handle returned by a previous call to the FindFirstFile function. Pointer lpWin32_Find_Data ; // Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. Returns Integer #ENDIF External_Function fsFindClose "FindClose" Kernel32.dll ; Handle hFindFile ; // File search handle. This handle must have been previously opened by the FindFirstFile function. Returns Integer #IFNDEF get_fsGetFileTime External_Function fsGetFileTime "GetFileTime" Kernel32.dll ; Handle hFile ; // Handle For a file from createfile with read access Pointer lpCreationtime ; // Pointer to a FILETIME structure containing the file creation time Pointer lpLastAccesstime ; // Pointer to a FILETIME structure containing the file last access time Pointer lpLastWritetime ; // Pointer to a FILETIME structure containing the file last write time Returns Integer #ENDIF #IFNDEF get_fsSetFileTime External_Function fsSetFileTime "SetFileTime" Kernel32.dll ; Handle hFile ; // Handle For a file from createfile with write access Pointer lpCreationtime ; // Pointer to a FILETIME structure containing the file creation time Pointer lpLastAccesstime ; // Pointer to a FILETIME structure containing the file last access time Pointer lpLastWritetime ; // Pointer to a FILETIME structure containing the file last write time Returns Integer #ENDIF External_function fsGetSystemTimeAsFileTime "GetSystemTimeAsFileTime" Kernel32.dll ; Pointer lpSystemTimeAsFileTime ; // Pointer to a FILETIME structure containing the current system time in filetimme format Returns Integer External_Function fsFileTimeToSystemTime "FileTimeToSystemTime" Kernel32.dll ; Pointer lpFiletime ; // Pointer to a FILETIME structure containing the file time to convert to system date and time format. Pointer lpSystemtime ; // Pointer to a SYSTEMTIME structure to receive the converted file time. Returns Integer External_Function fsSystemTimeToTzSpecificLocalTime "SystemTimeToTzSpecificLocalTime" Kernel32.dll ; Pointer lpTimeZone ; // A pointer to a TIME_ZONE_INFORMATION structure that specifies the time zone of interest. Pointer lpUniversalTime ; // A pointer to a SYSTEMTIME structure that specifies a time, in UTC. Pointer lpLocalTime ; // A pointer to a SYSTEMTIME structure that receives the local time. Returns Integer #IF (!@ < 200) External_Function fsGetTempFileName "GetTempFileNameA" kernel32.dll ; String sPathname ; String sPrefixString ; Integer iUnique ; Pointer sTempFileName ; Returns Integer External_Function fsGetTempPath "GetTempPathA" Kernel32.Dll ; Integer nBufferLength ; Pointer lpBuffer ; Returns Integer External_Function fsCreateDirectory "CreateDirectoryA" Kernel32.dll ; String sDirName ; // Pointer to a null-terminated string that specifies the path of the directory to be created. Pointer lpSecAttributes ; // Pointer to a SECURITY_ATTRIBUTES structure. Returns Integer External_Function fsRemoveDirectory "RemoveDirectoryA" Kernel32.dll ; String sDirName ; // Pointer to a null-terminated string that specifies the path of the directory to be removed. Returns Integer External_Function fsExtractAssociatedIcon "ExtractAssociatedIconA" shell32.dll ; Handle hInst ; Pointer lpIconPath ; Integer lpiIcon ; Returns Handle #ELSE External_Function fsGetTempFileName "GetTempFileNameW" kernel32.dll ; WString sPathname ; WString sPrefixString ; Integer iUnique ; Pointer sTempFileName ; Returns Integer External_Function fsGetTempPath "GetTempPathW" Kernel32.Dll ; Integer nBufferLength ; Pointer lpBuffer ; Returns Integer External_Function fsCreateDirectory "CreateDirectoryW" Kernel32.dll ; WString sDirName ; // Pointer to a null-terminated string that specifies the path of the directory to be created. Pointer lpSecAttributes ; // Pointer to a SECURITY_ATTRIBUTES structure. Returns Integer External_Function fsRemoveDirectory "RemoveDirectoryW" Kernel32.dll ; WString sDirName ; // Pointer to a null-terminated string that specifies the path of the directory to be removed. Returns Integer External_Function fsExtractAssociatedIcon "ExtractAssociatedIconW" shell32.dll ; Handle hInst ; Pointer lpIconPath ; Integer lpiIcon ; Returns Handle #ENDIF External_Function fsDestroyIcon "DestroyIcon" User32.dll ; Handle hIcon ; Returns Integer #IF (!@ < 200) External_Function fsGetFileVersionInfoSize "GetFileVersionInfoSizeA" Version.dll ; String sFilename ; // The name of the file of interest. The function uses the search sequence specified by the LoadLibrary function. Pointer lpHandle ; // A pointer to a variable that the function sets to zero. Returns UInteger External_Function fsGetFileVersionInfo "GetFileVersionInfoA" Version.dll ; String sFilename ; // The name of the file. If a full path is not specified, the function uses the search sequence specified by the LoadLibrary function. DWord dwHandle ; // This parameter is ignored. DWord dwLen ; // The size, in bytes, of the buffer pointed to by the lpData parameter. Pointer lpData ; // Pointer to a buffer that receives the file-version information. Returns Boolean External_Function fsVerQueryValue "VerQueryValueA" Version.dll ; Pointer lpBlock ; // The version-information resource returned by the GetFileVersionInfo function. String sSubBlock ; // The version-information value to be retrieved. Pointer lplpBuffer ; // When this method returns, contains the address of a pointer to the requested version information in the buffer pointed to by lpBlock. Pointer lpLen ; // When this method returns, contains a pointer to the size of the requested data pointed to by lpBuffer. Returns Boolean #ELSE External_Function fsGetFileVersionInfoSize "GetFileVersionInfoSizeW" Version.dll ; WString sFilename ; // The name of the file of interest. The function uses the search sequence specified by the LoadLibrary function. Pointer lpHandle ; // A pointer to a variable that the function sets to zero. Returns UInteger External_Function fsGetFileVersionInfo "GetFileVersionInfoW" Version.dll ; WString sFilename ; // The name of the file. If a full path is not specified, the function uses the search sequence specified by the LoadLibrary function. DWord dwHandle ; // This parameter is ignored. DWord dwLen ; // The size, in bytes, of the buffer pointed to by the lpData parameter. Pointer lpData ; // Pointer to a buffer that receives the file-version information. Returns Boolean External_Function fsVerQueryValue "VerQueryValueW" Version.dll ; Pointer lpBlock ; // The version-information resource returned by the GetFileVersionInfo function. WString sSubBlock ; // The version-information value to be retrieved. Pointer lplpBuffer ; // When this method returns, contains the address of a pointer to the requested version information in the buffer pointed to by lpBlock. Pointer lpLen ; // When this method returns, contains a pointer to the size of the requested data pointed to by lpBuffer. Returns Boolean #ENDIF //************************************************************************ // Structures //************************************************************************ // Nils 2018-08-30 Added For the SourceCodeTools project // so we don't need to use both Akefs.pkg and this package. #IFNDEF _struct_tFileTime // A 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). Struct tFileTime DWord dwLowDateTime // Low-order part of the file time. DWord dwHighDateTime // High-order part of the file time. End_Struct #ENDIF Struct structWFD // Used by FindFirstFile DWord dwFileAttributes UBigInt ftCreationDateTime UBigInt ftLastAccessDateTime UBigInt ftLastWriteDateTime UInteger nFileSizeHigh UInteger nFileSizeLow DWord dares DWord dbres #IF (!@ < 200) UChar[MAX_PATH] cFileName UChar[14] cAlternateFileName #ELSE Short[MAX_PATH] cFileName Short[14] cAlternateFileName #ENDIF End_Struct Struct structSystemTime UShort wYear UShort wMonth UShort wDayOfWeek UShort wDay UShort wHour UShort wMinute UShort wSecond UShort wMillieseconds End_Struct Struct structFile Handle hFilehandle String sFilename // Assigned filename in OEM format. Boolean bEndOfFile // True then the end of the binary file had been read. End_Struct Struct structFileBufferPointer Integer iBufferPointer Integer iBufferSize BigInt biFromFilePosition End_Struct Struct tsSearchResult String sFilename String sAlternateFileName // 8.3 format DateTime dtCreationDateTime DateTime dtLastAccessDateTime DateTime dtLastWriteDateTime BigInt biFileSize Integer iFileAttributes End_Struct Struct tsVS_FIXEDFILEINFO DWord dwSignature DWord dwStrucVersion DWord dwFileVersionMS DWord dwFileVersionLS DWord dwProductVersionMS DWord dwProductVersionLS DWord dwFileFlagsMask DWord dwFileFlags DWord dwFileOS DWord dwFileType DWord dwFileSubtype // DWord dwFileDateMS // DWord dwFileDateLS UBigInt ubiFileDate End_Struct Struct tsFileVersionInfo tsVS_FIXEDFILEINFO lsFIXEDFILEINFO Short[] siFileVersion Short[] siProductVersion DateTime dtCreationDateTime String sComments String sCompanyName String sFileDescription String sFileVersion String sInternalName String sLegalCopyright String sLegalTrademarks String sOriginalFilename String sProductName String sProductVersion String sPrivateBuild String sSpecialBuild End_Struct Struct tsLandAndCodePage UShort wLanguage UShort wCodePage End_Struct Register_Function FileErrorText Integer iFilenumber Returns String //************************************************************************ // The filesystem class //************************************************************************ Class cFilesystem is a cObject Procedure Construct_Object Forward Send Construct_Object // True then the end of the binary file had been read - not when $1A (EOF) is met. // Legacy property. Use the BinaryFileEndOfFile function instead. Property Boolean pbEOF False // True if any error has occured during fileoprerations. Property Boolean pbError False // If errormessages should be called with dataflex error command set this to true Property Boolean pbErrorAsVDFError False // Keeps assigned handles and filenames For each filenumber. // private Property structFile[] plsFile // Keeps read cached buffers For each filenumer. Used For BinaryReadChcheu // private Property String[] psaCachedBuffer // Pointers For cached buffers. // private Property structFileBufferPointer[] plsCachedPointer End_Procedure // Returns the next available filenumber For a binary file. Function BinaryFileNextFilenumber Returns Integer structFile[] lsFile Integer iMaxFiles iCurrentFile iNextFileNumber Get plsFile to lsFile Move (SizeOfArray(lsFile)) to iMaxFiles Move -1 to iNextFileNumber Move 0 to iCurrentFile While (iCurrentFile < iMaxFiles and iNextFileNumber = -1) If (lsFile[iCurrentFile].hFilehandle = 0) Begin Move iCurrentFile to iNextFileNumber End Else Begin Increment iCurrentFile End Loop If (iNextFileNumber = -1) Begin Move iMaxFiles to iNextFileNumber End Function_Return iNextFileNumber End_Function // Opens a binary file. // If bShared is false or not pharsed the file is opened in exclusive. // If bShared is True the file is opened with both read and write shared mode // If bCreate is True the file is created if it does not exist already. // If bReadOnly is True the file is opened with only read access (and only read shared mode if bShared is also true). // Returns true if the file was opened or created without error. Function BinaryFileOpen Integer iFilenumber String sFilename Boolean bShared Boolean bCreate Boolean bReadOnly Returns Boolean Integer iReturnValue iErrornumber DWord dwSharedMode dwCreateMode dwAccessMode structFile[] lsFile String sFilenameANSI Boolean bOk bFilehandleOK Get plsFile to lsFile If (iFilenumber < SizeOfArray(lsFile)) Begin If (lsFile[iFilenumber].hFilehandle = 0) Begin Move True to bFilehandleOK End End Else Begin Move True to bFilehandleOK End If bFilehandleOK Begin Move sFilename to lsFile[iFilenumber].sFilename #IF (!@ < 200) Move (ToAnsi(sFilename)) To sFilenameANSI #ELSE Move sFilename to sFilenameANSI #ENDIF Set pbError to False Move False to bOk Move GENERIC_RANDOM to dwAccessMode Move FNULL to dwSharedMode If (num_arguments > 2) Begin If (bShared = True) Begin Move FILE_SHARE_RANDOM to dwSharedMode End End Move OPEN_EXISTING to dwCreateMode If (num_arguments > 3) Begin If (bCreate = True) Begin Move OPEN_ALWAYS to dwCreateMode End End If (num_arguments > 4) Begin If (bReadOnly = True) Begin Move GENERIC_READ to dwAccessMode If (bShared = True) Begin Move FILE_SHARE_READ to dwSharedMode End End End Append sFilenameANSI (Character(0)) (Character(0)) Move (fsCreatefile(sFilenameANSI, dwAccessMode, dwSharedMode, FNULL, dwCreateMode, FILE_ATTRIBUTE_NORMAL, FNULL)) to iReturnValue If (iReturnValue = INVALID_HANDLE_VALUE) Begin Move (fsGetLastError()) to iErrornumber If iErrornumber Begin Send DoShowError iErrornumber ("File: "+ sFilename) End End Else Begin Move iReturnValue to lsFile[iFilenumber].hFilehandle Move False to lsFile[iFilenumber].bEndOfFile Set plsFile to lsFile Set pbEOF to False Move True to bOk End End Else Begin Send warning_box "The filenumber is already used." End Function_Return bOk End_Function // Closing a binary file // Returns true if the file could be closed. Function BinaryFileClose Integer iFilenumber Returns Boolean Integer iRetVal iErrorNumber Handle hHandle structFile[] lsFile structFileBufferPointer[] lsFileBufferPointer String[] saCachedBuffer Boolean bOk Get BinaryFileHandle iFilenumber to hHandle Set pbError to False Move False to bOk If hHandle Begin Move (fsCloseHandle(hHandle)) to iRetVal If (iRetVal = 0) Begin // Could not close Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End End Else Begin Get plsFile to lsFile Get plsCachedPointer to lsFileBufferPointer Get psaCachedBuffer to saCachedBuffer Move 0 to lsFile[iFilenumber].hFilehandle Move "" to saCachedBuffer[iFilenumber] Move 1 to lsFileBufferPointer[iFilenumber].iBufferPointer Move 0 to lsFileBufferPointer[iFilenumber].iBufferSize Move 0 to lsFileBufferPointer[iFilenumber].biFromFilePosition Set plsFile to lsFile Set plsCachedPointer to lsFileBufferPointer Set psaCachedBuffer to saCachedBuffer Move True to bOk End End Function_Return bOk End_Function // Reading from a binary file. // The data read from the file is placed in sReadBuffer and the function returns the number of bytes read. // Then the function returns 0 the end of file has been reached (pbEOF will then be true) or an error has occured (pbError will then be true). // No errors occures if you try to read past end of file. // To speed up reading process you should read in a block of data at a time (i.e. iNumberOfBytes = 2000) instead of // reading one byte at a time. No errors occures if you try to read past end // of file. Note that iNumberOfBytes must not exceed the argument size. Function BinaryFileRead Integer iFilenumber Integer iNumberOfBytes String ByRef sReadBuffer Returns Integer Handle hFileHandle Integer iBytesRead iMaxBuffer iErrorNumber Boolean bOk structFile[] lsFile Set pbError to False Move 0 to iBytesRead Get_Argument_Size to iMaxBuffer If (iNumberOfBytes > iMaxBuffer) Begin Send warning_box "Blocksize to read exceeds argument size!" Function_Return iBytesRead End If (iNumberOfBytes < 1) Begin Send warning_box "Number of bytes to read can not be less than one." Function_Return iBytesRead End Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Move (ZeroString(iNumberOfBytes)) to sReadBuffer Move (fsReadFile(hFileHandle, AddressOf(sReadBuffer), iNumberOfBytes, (AddressOf(iBytesRead)), FNULL)) to bOk If (bOk = False) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End End Else Begin If (iBytesRead = 0 or iBytesRead <> iNumberOfBytes) Begin Get plsFile to lsFile Move True to lsFile[iFilenumber].bEndOfFile Set plsFile to lsFile Set pbEOF to True Move (Left(sReadBuffer, iBytesRead)) to sReadBuffer End End End Else Begin Send warning_box FS_FILEHANDLEMISSING End Function_Return iBytesRead End_Function // Reading from a binary file until a string of bytes are matched. // The data read from the file is placed in the sReturnBuffer and the function returns the number of bytes read until the match is read including the match. // Then the function returns 0 the end of file has been reached (pbEOF will then be true) or an error has occured (pbError will then be true). // The return string buffer would also be empty. // No errors occures if you try to read past end of file. // To speed up reading process the buffer will be read in sizes of the current argument_size. Function BinaryFileReadCachedUntilMatch Integer iFilenumber String sMatchString String ByRef sReturnBuffer Boolean ByRef bEndOfFile Returns Integer Handle hFileHandle Integer iBuffersize iMatchPos iLengthMatch String sByte structFile[] lsFile structFileBufferPointer[] lsFileBufferPointer String[] saCachedBuffer Get plsFile to lsFile Move "" to sReturnBuffer Move 1 to iMatchPos If (iFilenumber < SizeOfArray(lsFile)) Begin Move lsFile[iFilenumber].hFilehandle to hFileHandle If (hFileHandle <> 0) Begin Move (Length(sMatchString)) to iLengthMatch Get plsCachedPointer to lsFileBufferPointer Get psaCachedBuffer to saCachedBuffer If (iFilenumber >= SizeOfArray(lsFileBufferPointer)) Begin Move 1 to lsFileBufferPointer[iFilenumber].iBufferPointer Move "" to saCachedBuffer[iFilenumber] End Repeat If (lsFileBufferPointer[iFilenumber].iBufferPointer > lsFileBufferPointer[iFilenumber].iBufferSize) Begin Get_Argument_Size to iBuffersize Get BinaryFilePosition iFilenumber to lsFileBufferPointer[iFilenumber].biFromFilePosition Get BinaryFileRead iFilenumber iBuffersize (&saCachedBuffer[iFilenumber]) to lsFileBufferPointer[iFilenumber].iBufferSize Move 1 to lsFileBufferPointer[iFilenumber].iBufferPointer Set psaCachedBuffer to saCachedBuffer End If (lsFileBufferPointer[iFilenumber].iBufferPointer =< lsFileBufferPointer[iFilenumber].iBufferSize) Begin Move (Mid(saCachedBuffer[iFilenumber], 1, lsFileBufferPointer[iFilenumber].iBufferPointer)) to sByte Increment lsFileBufferPointer[iFilenumber].iBufferPointer Move (sReturnBuffer + sByte) to sReturnBuffer If (sByte = Mid(sMatchString, 1, iMatchPos)) Begin Increment iMatchPos End Else Begin Move 1 to iMatchPos End End Until (iMatchPos > iLengthMatch or lsFileBufferPointer[iFilenumber].iBufferSize = 0) Set plsCachedPointer to lsFileBufferPointer If (lsFileBufferPointer[iFilenumber].iBufferSize = 0) Begin Move lsFile[iFilenumber].bEndOfFile to bEndOfFile End End Else Begin Send warning_box FS_FILEHANDLEMISSING End End Function_Return (Length(sReturnBuffer)) End_Function // Reading from a binary file as CSV file For next text field. // The data read from the file is placed in the sReturnBuffer excluding the separator and the function returns true. // Then the function returns false the end of file has been reached (pbEOF will then be true) or an error has occured (pbError will then be true). // When the end of row data has been read the bEndOfRow is set true. // The end of row is indicated with sCharEOL. If that is not applied the charactersequence character(13) + character(10) is used. // The return string buffer would also be empty. // No errors occures if you try to read past end of file. // To speed up reading process the buffer will be read in sizes of the current argument_size. Function BinaryFileReadCachedCSV Integer iFilenumber String sFieldseparator String sTextQualification String ByRef sReturnBuffer Boolean ByRef bEndOfRow Boolean ByRef bEndOfFile String sCharEOL Returns Integer Handle hFileHandle Integer iLengthSeparator iLengthTextQualification iEOLLength iTestLength String sByte sEOL sTestBuffer structFile[] lsFile structFileBufferPointer[] lsFileBufferPointer String[] saCachedBuffer Boolean bInTextFieldMode bTextFieldReady bFieldSeparator bTextQualificator bEscapeTextQualificatorTest bByteOk BigInt biAfterTextQualificator Get plsFile to lsFile If (num_arguments > 6) Begin Move sCharEOL to sEOL End Else Begin Move ((Character(13))+(Character(10))) to sEOL End Move (Length(sEOL)) to iEOLLength Move "" to sReturnBuffer Move "" to sByte Move False to bInTextFieldMode Move False to bTextFieldReady Move False to bEndOfRow Move False to bTextQualificator If (iFilenumber < SizeOfArray(lsFile)) Begin Move lsFile[iFilenumber].hFilehandle to hFileHandle If (hFileHandle <> 0) Begin Move (Length(sFieldseparator)) to iLengthSeparator Move (Length(sTextQualification)) to iLengthTextQualification Get plsCachedPointer to lsFileBufferPointer Get psaCachedBuffer to saCachedBuffer If (iFilenumber >= SizeOfArray(lsFileBufferPointer)) Begin Move 1 to lsFileBufferPointer[iFilenumber].iBufferPointer Move "" to saCachedBuffer[iFilenumber] End Repeat Get NextByteCSV (&iFilenumber) (&lsFileBufferPointer[iFilenumber]) (&saCachedBuffer) (&sByte) to bByteOk If bByteOk Begin Move (sReturnBuffer + sByte) to sReturnBuffer Move (Right(sReturnBuffer, iLengthSeparator) = sFieldseparator) to bFieldSeparator If bFieldSeparator Begin Move (Left(sReturnBuffer, (Length(sReturnBuffer) - iLengthSeparator))) to sReturnBuffer Move True to bTextFieldReady Move False to bEscapeTextQualificatorTest End If (not(bTextFieldReady)) Begin Move (Right(sReturnBuffer, iEOLLength) = sEOL) to bEndOfRow If bEndOfRow Begin Move (Left(sReturnBuffer, (Length(sReturnBuffer) - iEOLLength))) to sReturnBuffer Move True to bTextFieldReady End End If (not(bTextFieldReady)) Begin Move (Right(sReturnBuffer, iLengthTextQualification) = sTextQualification) to bTextQualificator If bTextQualificator Begin // Read until end of text field. Place filepointer after text field. Move True to bInTextFieldMode Move (Left(sReturnBuffer, (Length(sReturnBuffer) - iLengthTextQualification))) to sReturnBuffer Repeat Get NextByteCSV (&iFilenumber) (&lsFileBufferPointer[iFilenumber]) (&saCachedBuffer) (&sByte) to bByteOk If bByteOk Begin Move (sReturnBuffer + sByte) to sReturnBuffer Move (Right(sReturnBuffer, iLengthTextQualification) = sTextQualification) to bTextQualificator If bTextQualificator Begin // Either it is the end of the text field or the escape text qualificator has been read. // Read ahead to a new buffer to see if the next bytes are the text qualificator. // If it is, add the new buffer to the return buffer. // If not, restore the filebuffer to this position and mark the text field ended. Move (Left(sReturnBuffer, (Length(sReturnBuffer) - iLengthTextQualification))) to sReturnBuffer Set plsCachedPointer to lsFileBufferPointer Get BinaryFileCachedPosition iFilenumber to biAfterTextQualificator Move "" to sTestBuffer Move 0 to iTestLength Move True to bEscapeTextQualificatorTest Repeat Get NextByteCSV (&iFilenumber) (&lsFileBufferPointer[iFilenumber]) (&saCachedBuffer) (&sByte) to bByteOk If bByteOk Begin Move (sTestBuffer + sByte) to sTestBuffer Increment iTestLength If (Left(sTextQualification, iTestLength) = sTestBuffer) Begin If (iTestLength = iLengthTextQualification) Begin Move (sReturnBuffer + sTestBuffer) to sReturnBuffer Move False to bEscapeTextQualificatorTest End End Else Begin Set BinaryFileChachedPosition iFilenumber to biAfterTextQualificator Get plsCachedPointer to lsFileBufferPointer Move False to bEscapeTextQualificatorTest Move False to bInTextFieldMode End End Until (bEscapeTextQualificatorTest = False or lsFileBufferPointer[iFilenumber].iBufferSize = 0 or bByteOk = False) End End Until (bInTextFieldMode = False or lsFileBufferPointer[iFilenumber].iBufferSize = 0 or bByteOk = False) End End End Until (bTextFieldReady = True or lsFileBufferPointer[iFilenumber].iBufferSize = 0 or bByteOk = False) Set plsCachedPointer to lsFileBufferPointer If (lsFileBufferPointer[iFilenumber].iBufferSize = 0) Begin Move lsFile[iFilenumber].bEndOfFile to bEndOfFile If (bEndOfFile = True) Begin Move True to bTextFieldReady Move True to bEndOfRow End End End Else Begin Send warning_box FS_FILEHANDLEMISSING End End Function_Return bTextFieldReady End_Function {Visibility = Private} Function NextByteCSV Integer ByRef iFilenumber structFileBufferPointer ByRef lsFileBufferPointer String[] ByRef saCachedBuffer String ByRef sByte Returns String Integer iBufferSize Boolean bOk If (lsFileBufferPointer.iBufferPointer > lsFileBufferPointer.iBufferSize) Begin Get_Argument_Size to iBufferSize Get BinaryFilePosition iFilenumber to lsFileBufferPointer.biFromFilePosition Get BinaryFileRead iFilenumber iBufferSize (&saCachedBuffer[iFilenumber]) to lsFileBufferPointer.iBufferSize Move 1 to lsFileBufferPointer.iBufferPointer Set psaCachedBuffer to saCachedBuffer End If (lsFileBufferPointer.iBufferPointer <= lsFileBufferPointer.iBufferSize) Begin Move (Mid(saCachedBuffer[iFilenumber], 1, lsFileBufferPointer.iBufferPointer)) to sByte Increment lsFileBufferPointer.iBufferPointer Move True to bOk End Function_Return bOk End_Function // Shortcut to read a binary file as lines from a textfile. // Reads from cached file until sCharEOL are recieved. // Data is returned without the ending sCharEOL // If sCharEOL is not applied the charactersequence character(13) + character(10) is used. // Returns True when the line has been read. Function BinaryFileReadCachedLN Integer iFilenumber String ByRef sLine Boolean ByRef bEndOfFile String sCharEOL Returns Boolean Boolean bEndOfRow Integer iBytesRead iEOLLength String sEOL If (num_arguments > 3) Begin Move sCharEOL to sEOL End Else Begin Move ((Character(13))+(Character(10))) to sEOL End Move (Length(sEOL)) to iEOLLength Get BinaryFileReadCachedUntilMatch iFilenumber sEOL (&sLine) (&bEndOfFile) to iBytesRead If (iBytesRead > 0) Begin If (Right(sLine, iEOLLength) = sEOL) Begin Move (Left(sLine, (Length(sLine) - iEOLLength))) to sLine Move True to bEndOfRow End End Function_Return bEndOfRow End_Function // Writing to a binary file. // Returns true if the data was written to the file without error. Function BinaryFileWrite Integer iFilenumber String ByRef sWriteData Returns Boolean Integer iBytesWritten iBytesToWrite iErrorNumber Handle hFileHandle Boolean bOk Set pbError to False Move False to bOk Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Move 0 to iBytesWritten Move (Length(sWriteData)) to iBytesToWrite Move (fsWriteFile(hFileHandle, AddressOf(sWriteData), iBytesToWrite, AddressOf(iBytesWritten), FNULL)) to bOk If (bOk = False) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End End If (iBytesToWrite <> iBytesWritten) Begin Send Warning_box "Not all data could be written!" Move False to bOk End End Else Begin Send Warning_Box FS_FILEHANDLEMISSING End Function_Return bOk End_Function // Write HEX values to a binary file as bytes. // HEX values in sWriteHEX are first coverted to bytes and then written // to the binary file. // Returns true if the HEX data was written to the file without error. Function BinaryFileWriteHex Integer iFilenumer String ByRef sWriteHex Returns Boolean String sData Integer iLength iCount iByte Boolean bOk Move (Length(sWritehex)) to iLength Move 1 to iCount While (iCount < iLength) Move ("$"+Mid(sWriteHex, 2, iCount)) to iByte Move (iCount + 2) to iCount Move (sData + Character(iByte)) to sData Loop Get BinaryFileWrite iFilenumer (&sData) to bOk Function_Return bOk End_Function // Retrives the file size from a binary file. Function BinaryFileSize Integer iFilenumber Returns BigInt BigInt biFilesize Handle hFileHandle Boolean bOk Integer iErrorNumber Set pbError to False Move -1 to biFilesize Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin // The LARGE_INTEGER structure has the same structure as a BigInt. Move (fsGetFileSizeEx(hFileHandle, AddressOf(biFilesize))) to bOk If (bOk = -False) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End End End Else Begin Send warning_box FS_FILEHANDLEMISSING End Function_Return biFilesize End_Function // Retrives the file position from a binary file. // Returns -1 if an error occured. Function BinaryFilePosition Integer iFilenumber Returns BigInt BigInt biFilePosition biBigHi Handle hFileHandle Boolean bOk Integer iErrorNumber iLo iHi UInteger iNewPos Set pbError to False Move -1 to biFilePosition Move 0 to iHi Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Move (2^32) to biBigHi Move (fsSetFilePointer(hFileHandle, ilo, AddressOf(iHi), FILE_CURRENT)) to iNewPos If (iNewPos = (biBigHi - 1)) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End Else Begin Move True to bOk End End Else Begin Move True to bOk End If bOk Begin Move ((iHi * biBigHi) + iNewPos) to biFilePosition End End Else Begin Send warning_box FS_FILEHANDLEMISSING End Function_Return biFilePosition End_Function // Sets the file position from a binary file to a new position. Procedure Set BinaryFilePosition Integer iFilenumber BigInt biPosition Handle hFileHandle Integer iHi iErrorNumber UInteger iLo iNewPos Boolean bOk BigInt biFileSize biBigHi structFile[] lsFile Set pbError to False Move False to bOk Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Move (2^32) to biBigHi Move (biPosition / biBigHi) to iHi Move (biPosition - (iHi * biBigHi)) to iLo Move (fsSetFilePointer(hFileHandle, iLo, AddressOf(iHi), FILE_BEGIN)) to iNewPos If (iNewPos = (biBigHi - 1)) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End Else Begin Move True to bOk End End Else Begin Move True to bOk End If bOk Begin Get BinaryFileSize iFilenumber to biFileSize Get plsFile to lsFile If (biFileSize > biPosition) Begin Move False to lsFile[iFilenumber].bEndOfFile Set pbEOF to False End Else Begin Move True to lsFile[iFilenumber].bEndOfFile Set pbEOF to True End Set plsFile to lsFile End End Else Begin Send warning_box FS_FILEHANDLEMISSING End Set pbError to (not(bOk)) End_Procedure // Returns -1 if an error occured. Function BinaryFileCachedPosition Integer iFileNumber Returns BigInt BigInt biPosition structFileBufferPointer[] lsFileBufferPointer Handle hFileHandle Move -1 to biPosition Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Get plsCachedPointer to lsFileBufferPointer If (iFilenumber < SizeOfArray(lsFileBufferPointer)) Begin If (lsFileBufferPointer[iFileNumber].iBufferSize > 0) Begin Move (lsFileBufferPointer[iFileNumber].biFromFilePosition + lsFileBufferPointer[iFileNumber].iBufferPointer - 1) to biPosition End Else Begin Get BinaryFilePosition iFileNumber to biPosition End End Else Begin Get BinaryFilePosition iFileNumber to biPosition End End Else Begin Send Warning_Box FS_FILEHANDLEMISSING End Function_Return biPosition End_Function // Sets the pointer For the current file cache. Procedure Set BinaryFileChachedPosition Integer iFileNumber BigInt biNewPosition Handle hFileHandle structFileBufferPointer[] lsFileBufferPointer String[] saCachedBuffer Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Get plsCachedPointer to lsFileBufferPointer If (lsFileBufferPointer[iFileNumber].biFromFilePosition > biNewPosition) Begin Move 1 to lsFileBufferPointer[iFileNumber].iBufferPointer Move 0 to lsFileBufferPointer[iFileNumber].iBufferSize Set plsCachedPointer to lsFileBufferPointer Set BinaryFilePosition iFileNumber to biNewPosition Get psaCachedBuffer to saCachedBuffer Move "" to saCachedBuffer[iFileNumber] Set psaCachedBuffer to saCachedBuffer End Else If ((lsFileBufferPointer[iFileNumber].biFromFilePosition + lsFileBufferPointer[iFileNumber].iBufferSize) < biNewPosition) Begin Move 1 to lsFileBufferPointer[iFileNumber].iBufferPointer Move 0 to lsFileBufferPointer[iFileNumber].iBufferSize Set plsCachedPointer to lsFileBufferPointer Set BinaryFilePosition iFileNumber to biNewPosition Get psaCachedBuffer to saCachedBuffer Move "" to saCachedBuffer[iFileNumber] Set psaCachedBuffer to saCachedBuffer End Else Begin Move (biNewPosition - lsFileBufferPointer[iFileNumber].biFromFilePosition + 1) to lsFileBufferPointer[iFileNumber].iBufferPointer Set plsCachedPointer to lsFileBufferPointer End End Else Begin Send warning_box FS_FILEHANDLEMISSING End End_Procedure // Truncate or extend a binary file to the specified file position // by setting the binary file End Of File position. // If biPosition is -1 the current file position is used as EOF position. Procedure Set BinaryFileEndOfFile Integer iFilenumber BigInt biPosition Handle hFileHandle Boolean bError bOk Integer iErrorNumber structFile[] lsFile Set pbError to False Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin If (biPosition > -1) Begin Set BinaryFilePosition iFilenumber to biPosition End Get pbError to bError If (bError = False) Begin Move (fsSetEndOfFile(hFileHandle)) to bOk If (bOk = False) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber (FileErrorText(Self, iFilenumber)) End End Else Begin Get plsFile to lsFile Move True to lsFile[iFilenumber].bEndOfFile Set plsFile to lsFile Set pbEOF to True End End End Else Begin Send warning_box FS_FILEHANDLEMISSING End Set pbError to (not(bOk)) End_Procedure // Returns true if the last read from the binary file had reached the end. Function BinaryFileEndOfFile Integer iFilenumber Returns Boolean structFile[] lsFile Handle hFileHandle Boolean bEndOfFile Move True to bEndOfFile Set pbError to False Get BinaryFileHandle iFilenumber to hFileHandle If hFileHandle Begin Get plsFile to lsFile Move lsFile[iFilenumber].bEndOfFile to bEndOfFile End Else Begin Send warning_box FS_FILEHANDLEMISSING End Function_Return bEndOfFile End_Function // Returns the filehandle from the filenumber. // Returns 0 if the filenumber is not used. Function BinaryFileHandle Integer iFilenumber Returns Handle Handle hFileHandle structFile[] lsFile Get plsFile to lsFile If (iFilenumber < SizeOfArray(lsFile)) Begin Move lsFile[iFilenumber].hFilehandle to hFileHandle End Function_Return hFileHandle End_Function // Searches For a file // iMode = DIRMODE_FILES_ONLY (default) // iMode = DIRMODE_DIRECTORIES_ONLY // iMode = DIRMODE_FILES_AND_DIRECTORIES // Returns True if found Function FileExists String sFilePathMask Integer iFileDirMode Returns Boolean Integer iMode Boolean bFound tsSearchResult[] lsResult Move False to bFound Set pbError to False If (num_arguments < 2) Begin Move DIRMODE_FILES_ONLY to iMode End Else Begin Move iFileDirMode to iMode End Get FileSearch sFilePathMask iMode True to lsResult If (SizeOfArray(lsResult) > 0) Begin Move True to bFound End Function_Return bFound End_Function // Deletes a file. // Returns True if succeeds. Function FileDelete String sFilename Integer iRetryAttempts Returns Boolean Boolean bFound bDeleted Integer iErrorNumber iRetryLeft Set pbError to False If (num_arguments > 1) Begin Move iRetryAttempts to iRetryLeft End Else Begin Move 0 to iRetryLeft End Get FileExists sFilename to bFound If bFound Begin Repeat #IF (!@ < 200) Move (ToAnsi(sFilename)) To sFilename #ENDIF Move (sFilename+(Character(0))) to sFilename Move (fsDeleteFile(sFilename)) to bDeleted If (bDeleted = False) Begin Decrement iRetryLeft If (iRetryLeft <= 0) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber ("Tried to delete file: "+sFilename) End End Else Begin Sleep 1 End End Until (bDeleted = True or iRetryLeft <= 0) End Function_Return bDeleted End_Function // Moves a file or directory. // Returns True if succeeds. Function FileMove String sExistingFileName String sNewFileName Integer iRetryAttempts Returns Boolean Boolean bMoved Integer iErrorNumber iRetryLeft Set pbError to False If (num_arguments > 2) Begin Move iRetryAttempts to iRetryLeft End Else Begin Move 0 to iRetryLeft End #IF (!@ < 200) Move (ToAnsi(sExistingFileName)) to sExistingFileName Move (ToAnsi(sNewFileName)) to sNewFileName #ENDIF Move (sExistingFilename+(Character(0))) to sExistingFilename Move (sNewFileName+(Character(0))) to sNewFileName Repeat Move (fsMoveFile(sExistingFilename, sNewFileName)) to bMoved If (bMoved = False) Begin Decrement iRetryLeft If (iRetryLeft <= 0) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber ("Tried to move/rename file: "+sExistingFileName+" to "+sNewFileName) End End Else Begin Sleep 1 End End Until (bMoved = True or iRetryLeft <= 0) Function_Return bMoved End_Function // Copies a file. Overwriting an existing file by default. // Returns True if succeeds. Function FileCopy String sExistingFileName String sNewFileName Boolean bFailIfExists Integer iRetryAttempts Returns Boolean Boolean bCopied Boolean bDoNotOverwrite Integer iErrorNumber iRetryLeft Set pbError to False #IF (!@ < 200) Move (ToAnsi(sExistingFileName)) to sExistingFileName Move (ToAnsi(sNewFileName)) to sNewFileName #ENDIF Move (sExistingFileName+(Character(0))) to sExistingFileName Move (sNewFileName+(Character(0))) to sNewFileName If (Num_Arguments > 2) Begin Move bFailIfExists to bDoNotOverwrite End Else Begin Move False to bDoNotOverwrite End If (num_arguments > 3) Begin Move iRetryAttempts to iRetryLeft End Else Begin Move 0 to iRetryLeft End Repeat Move (fsCopyFile(sExistingFileName, sNewFileName, bDoNotOverwrite)) to bCopied If (bCopied = False) Begin Decrement iRetryLeft If (iRetryLeft <= 0) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber ("Tried to copy file: "+sExistingFileName+" to "+sNewFileName) End End Else Begin Sleep 1 End End Until (bCopied = True or iRetryLeft <= 0) Function_Return bCopied End_Function // Renames a file or directory. // Returns True if succeeds. Function FileRename String sExistingFileName String sNewFileName Integer iRetryAttempts Returns Boolean Boolean bRenamed If (num_arguments > 2) Begin Get FileMove sExistingFileName sNewFileName iRetryAttempts to bRenamed End Else Begin Get FileMove sExistingFileName sNewFileName to bRenamed End Function_Return bRenamed End_Function // Returns the file size of a file. // Returns -1 if an error occured. // Use *this* instead of FileSize as it works for both 32 bit as well as 64 bit and can // always return filesizes over 2GB. Function FileSizeEx String sFilename Returns Bigint tsSearchResult[] lsSearchResult BigInt iRetval Get FileSearch sFilename DIRMODE_FILES_ONLY to lsSearchResult If (SizeOfArray(lsSearchResult) > 0) Begin Move lsSearchResult[0].biFileSize to iRetval End Else Begin Move -1 to iRetval End Function_Return iRetval End_Function // // Check your source code to see if it uses the filesize function and if it does, change it to FileSizeEx // Once you verified that you are no longer using filesize, then add the following line to your code. // // // Source is not using obsolete filesize function // Define no_cFileSystem_filesize_here // // and the warning is resolved. #IFNDEF no_cFileSystem_filesize_here // Returns the file size of a file. // Returns -1 if an error occured. // ** Don't USE THIS, but FileSizeEx above as this only works correctly for 64 bit. Function FileSize String sFilename Returns Longptr BigInt biSize #warning 12234 "FileSize is now obsolete, check your code and set no_cFileSystem_filesize_here compiler directive to remove" Get FileSizeEx sFilename to biSize Function_Return biSize End_Function #ENDIF // Returns the last write date of a file. // Returns 0 if an error occured. Function FileDate String sFilename Returns Date tsSearchResult[] lsSearchResult Date dDate Move 0 to dDate Get FileSearch sFilename DIRMODE_FILES_ONLY to lsSearchResult If (SizeOfArray(lsSearchResult) > 0) Begin Move lsSearchResult[0].dtLastWriteDateTime to dDate End Function_Return dDate End_Function // Returns the fileversion info. // Returns false if an error occured. Function FileVersion String sFilename tsFileVersionInfo ByRef lsFileVersionInfo Returns Boolean Boolean bOk Integer iErrorNumber iStatus Get _FileVersion sFilename (&lsFileVersionInfo) to iStatus If (iStatus = -1) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber ("Tried to get fileversion info from file: "+sFilename) End End Move (iStatus = 0) to bOk Function_Return bOk End_Function {Visibility = Private} Function _FileVersion String sFilename tsFileVersionInfo ByRef lsFileVersionInfo Returns Integer tsVS_FIXEDFILEINFO lsFIXEDFILEINFO UInteger iBytesNeeded Address aBuffer Boolean bOk String sSubBlock DWord dwBufferLen dwBufferPointer tsLandAndCodePage lsLandAndCodePage #IF (!@ < 200) Move (ToANSI(sFilename)) To sFilename #ENDIF Move (sFilename + (Character(0))) to sFilename Move 0 to iBytesNeeded Move 0 to aBuffer Move 0 to lsFIXEDFILEINFO.dwStrucVersion // Initialize the variable. Move 0 to lsLandAndCodePage.wCodePage Move (fsGetFileVersionInfoSize(sFilename, 0)) to iBytesNeeded If (iBytesNeeded = 0) Begin Function_Return False End Move False to bOk Move (Alloc(iBytesNeeded)) to aBuffer Move (MemSet(aBuffer, 0, iBytesNeeded)) to bOk Move (fsGetFileVersionInfo(sFilename, 0, iBytesNeeded, aBuffer)) to bOk If (not(bOk)) Begin Move (Free(aBuffer)) to bOk Function_Return -1 End Move "\" to sSubBlock Move (sSubBlock + (Character(0))) to sSubBlock Move 0 to dwBufferLen Move 0 to dwBufferPointer Move (fsVerQueryValue(aBuffer, sSubBlock, AddressOf(dwBufferPointer), AddressOf(dwBufferLen))) to bOk If (not(bOk)) Begin Move (Free(aBuffer)) to bOk Function_Return -1 End If (dwBufferLen <> 52) Begin Send warning_box (SFormat("Length of bufferdata For VS_FIXEDFILEINFO struct are not in the expected size.\nLength is %1 and should have been 52.", dwBufferLen)) Move (Free(aBuffer)) to bOk Function_Return -2 End Move (MemCopy(AddressOf(lsFIXEDFILEINFO), dwBufferPointer, dwBufferLen)) to bOk If (not(bOk)) Begin Move (Free(aBuffer)) to bOk Function_Return -1 End Move lsFIXEDFILEINFO to lsFileVersionInfo.lsFIXEDFILEINFO Get ConvertFileTimeToLocalDateTime lsFIXEDFILEINFO.ubiFileDate to lsFileVersionInfo.dtCreationDateTime Move (Hi(lsFIXEDFILEINFO.dwFileVersionMS)) to lsFileVersionInfo.siFileVersion[0] Move (Low(lsFIXEDFILEINFO.dwFileVersionMS)) to lsFileVersionInfo.siFileVersion[1] Move (Hi(lsFIXEDFILEINFO.dwFileVersionLS)) to lsFileVersionInfo.siFileVersion[2] Move (Low(lsFIXEDFILEINFO.dwFileVersionLS)) to lsFileVersionInfo.siFileVersion[3] Move (Hi(lsFIXEDFILEINFO.dwProductVersionMS)) to lsFileVersionInfo.siProductVersion[0] Move (Low(lsFIXEDFILEINFO.dwProductVersionMS)) to lsFileVersionInfo.siProductVersion[1] Move (Hi(lsFIXEDFILEINFO.dwProductVersionLS)) to lsFileVersionInfo.siProductVersion[2] Move (Low(lsFIXEDFILEINFO.dwProductVersionLS)) to lsFileVersionInfo.siProductVersion[3] Move "\VarFileInfo\Translation" to sSubBlock Move (sSubBlock + (Character(0))) to sSubBlock Move 0 to dwBufferLen Move 0 to dwBufferPointer Move (fsVerQueryValue(aBuffer, sSubBlock, AddressOf(dwBufferPointer), AddressOf(dwBufferLen))) to bOk If (not(bOk)) Begin Move (Free(aBuffer)) to bOk Function_Return -1 End If (dwBufferLen <> 4) Begin Send warning_box (SFormat("Length of bufferdata For land and codepage numbers are not in the expected size.\nLength is %1 and should have been 4.", dwBufferLen)) Move (Free(aBuffer)) to bOk Function_Return -2 End Move (MemCopy(AddressOf(lsLandAndCodePage), dwBufferPointer, dwBufferLen)) to bOk Get VerQueryValueStringFileInfo aBuffer "Comments" lsLandAndCodePage to lsFileVersionInfo.sComments Get VerQueryValueStringFileInfo aBuffer "CompanyName" lsLandAndCodePage to lsFileVersionInfo.sCompanyName Get VerQueryValueStringFileInfo aBuffer "FileDescription" lsLandAndCodePage to lsFileVersionInfo.sFileDescription Get VerQueryValueStringFileInfo aBuffer "FileVersion" lsLandAndCodePage to lsFileVersionInfo.sFileVersion Get VerQueryValueStringFileInfo aBuffer "InternalName" lsLandAndCodePage to lsFileVersionInfo.sInternalName Get VerQueryValueStringFileInfo aBuffer "LegalCopyright" lsLandAndCodePage to lsFileVersionInfo.sLegalCopyright Get VerQueryValueStringFileInfo aBuffer "LegalTrademarks" lsLandAndCodePage to lsFileVersionInfo.sLegalTrademarks Get VerQueryValueStringFileInfo aBuffer "OriginalFilename" lsLandAndCodePage to lsFileVersionInfo.sOriginalFilename Get VerQueryValueStringFileInfo aBuffer "ProductName" lsLandAndCodePage to lsFileVersionInfo.sProductName Get VerQueryValueStringFileInfo aBuffer "ProductVersion" lsLandAndCodePage to lsFileVersionInfo.sProductVersion Get VerQueryValueStringFileInfo aBuffer "PrivateBuild" lsLandAndCodePage to lsFileVersionInfo.sPrivateBuild Get VerQueryValueStringFileInfo aBuffer "SpecialBuild" lsLandAndCodePage to lsFileVersionInfo.sSpecialBuild Move (Free(aBuffer)) to bOk Function_Return 0 End_Function // Convert an short integer to a 4-character hex string. Function ShortToHex Short siValue Returns String String sHex Move "" to sHex Repeat Move (Mid ("0123456789ABCDEF", 1, ((siValue iand |CI$0F) + 1)) + sHex) to sHex Move (siValue / |CI$10) to siValue Until (siValue = 0) Move (Right("0000" + sHex, 4)) to sHex Function_Return sHex End_Function {Visibility = Private} Function VerQueryValueStringFileInfo Address aBuffer String sInfoName tsLandAndCodePage lsLandAndCodePage Returns String String sSubBlock String sValue DWord dwBufferLen dwBufferPointer Boolean bOk #IF (!@ >= 200) WString wValue #ENDIF Move (SFormat("\StringFileInfo\%1%2\%3", ShortToHex(Self, lsLandAndCodePage.wLanguage), ShortToHex(Self, lsLandAndCodePage.wCodePage), sInfoName)) to sSubBlock Move (sSubBlock + (Character(0))) to sSubBlock Move 0 to dwBufferLen Move 0 to dwBufferPointer Move (fsVerQueryValue(aBuffer, sSubBlock, AddressOf(dwBufferPointer), AddressOf(dwBufferLen))) to bOk If (not(bOk)) Begin Function_Return "" End #IF (!@ < 200) Move (ZeroString(dwBufferLen)) to sValue Move (MemCopy(AddressOf(sValue), dwBufferPointer, dwBufferLen)) to bOk Move (ToOEM(CString(sValue))) To sValue #ELSE Move (ZeroString(dwBufferLen)) to wValue // size is in bytes, so we are reserving too much space Move (MemCopy(AddressOf(wValue), dwBufferPointer, dwBufferLen)) to bOk // memcopy copies the correct amount though Move (CString(wValue)) To sValue #ENDIF Function_Return sValue End_Function // Returns the file extention without the leading "." // Example sFile = "x:\text.txt". The function returns "txt". Function FileExtention String sFilename Returns String String sExtention Integer iPos Move (RightPos(".", sFilename)) to iPos If (iPos > 0) Begin Move (Right(sFilename, (Length(sFilename) - iPos))) to sExtention If (sExtention contains "\" or sExtention contains " ") Begin Move "" to sExtention End End Function_Return sExtention End_Function // Gets a handle to an icon stored as a resource in a file or an icon // stored in a file's associated executable file. // When the icon handle is no longer needed, close it by using the DestroyFileIcon procedure. Function FileIcon String sFilename Returns Handle Handle hIcon Integer iIcon Address aFilename #IF (!@ < 200) Move (ToANSI(sFilename)) To sFilename Move (Pad(sFilename, MAX_PATH)) to sFilename Move (AddressOf(sFileName)) To aFileName #ELSE WString wFileName Move (Pad(sFilename, MAX_PATH)) to wFilename Move (AddressOf(wFileName)) To aFileName #ENDIF Move 0 to iIcon Move (fsExtractAssociatedIcon(0, aFilename, AddressOf(iIcon))) to hIcon Function_Return hIcon End_Function // Destroy hIcon, created from FileIcon. Procedure DestroyFileIcon Handle hIcon Integer iResult If (hIcon <> 0) Begin Move (fsDestroyIcon(hIcon)) to iResult End End_Procedure // Search a directory For the files with normal windows mask-signs // Returns an array of matching files and directories // iMode = DIRMODE_FILES_ONLY // iMode = DIRMODE_DIRECTORIES_ONLY // iMode = DIRMODE_FILES_AND_DIRECTORIES (default) // If bReturnOnlyOne is true only one search result item is returned. // If bReturnOnlyOne is true and no items where found no error is shown. Function FileSearch String sFilePathMask Integer iFileDirMode Boolean bReturnOnlyOne Returns tsSearchResult[] tsSearchResult[] lsSearchResult Integer iSearchResultCount iMode iErrorNumber structWFD lsFindData Handle hFindFile Boolean bError bStop bFound bOk bOnlyOne BigInt biBigHi Address aFileName If (num_arguments < 2) Begin Move DIRMODE_FILES_AND_DIRECTORIES to iMode End Else Begin Move iFileDirMode to iMode End If (num_arguments < 3) Begin Move False to bOnlyOne End Else Begin Move bReturnOnlyOne to bOnlyOne End #IF (!@ < 200) Move (ToAnsi(sFilePathMask)) To sFilePathMask #ENDIF Move (sFilePathMask+Character(0)) To sFilePathMask Move 0 To lsFindData.dwFileAttributes // Initialize lsFindData Move (fsFindFirstFile(sFilePathMask, AddressOf(lsFindData))) to hFindFile If (hFindFile <> INVALID_HANDLE_VALUE) Begin Move False to bError Move False to bStop Move (2^32) to biBigHi Set pbError to bError While (bError = False and bStop = False) Move False to bFound Case Begin Case (iMode = DIRMODE_FILES_ONLY) If (lsFindData.dwFileAttributes iand FILE_ATTRIBUTE_DIRECTORY = 0) Begin Move True to bFound End Case Break Case (iMode = DIRMODE_DIRECTORIES_ONLY) If (lsFindData.dwFileAttributes iand FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY) Begin Move True to bFound End Case Break Case Else Move True to bFound Case Break Case End If bFound Begin #IF (!@ < 200) Move (AddressOf(lsFindData.cFileName)) to aFilename Move aFilename to lsSearchResult[iSearchResultCount].sFilename Move (ToOEM(lsSearchResult[iSearchResultCount].sFilename)) to lsSearchResult[iSearchResultCount].sFilename Move (AddressOf(lsFindData.cAlternateFileName)) to aFilename Move aFilename to lsSearchResult[iSearchResultCount].sAlternateFileName Move (ToOEM(lsSearchResult[iSearchResultCount].sAlternateFileName)) To lsSearchResult[iSearchResultCount].sAlternateFileName #ELSE Move (AddressOf(lsFindData.cFileName)) to aFilename Move (PointerToWString(aFilename)) to lsSearchResult[iSearchResultCount].sFilename Move (AddressOf(lsFindData.cAlternateFileName)) to aFilename Move (PointerToWString(aFilename)) to lsSearchResult[iSearchResultCount].sAlternateFileName #ENDIF Move lsFindData.dwFileAttributes to lsSearchResult[iSearchResultCount].iFileAttributes Get ConvertFileTimeToLocalDateTime lsFindData.ftCreationDateTime to lsSearchResult[iSearchResultCount].dtCreationDateTime Get ConvertFileTimeToLocalDateTime lsFindData.ftLastAccessDateTime to lsSearchResult[iSearchResultCount].dtLastAccessDateTime Get ConvertFileTimeToLocalDateTime lsFindData.ftLastWriteDateTime to lsSearchResult[iSearchResultCount].dtLastWriteDateTime Move ((lsFindData.nFileSizeHigh * biBigHi) + lsFindData.nFileSizeLow) to lsSearchResult[iSearchResultCount].biFileSize Increment iSearchResultCount If bOnlyOne Begin Move True to bStop End End If (bStop = False) Begin Move (fsFindNextFile(hFindFile, AddressOf(lsFindData))) to bOk End If (bOk = False) Begin Move True to bStop If (bOnlyOne = False) Begin Move (fsGetLastError()) to iErrorNumber If (iErrorNumber <> ERROR_NO_MORE_FILES and iErrorNumber <> ERROR_MOD_NOT_FOUND and iErrorNumber <> 0) Begin Send DoShowError iErrorNumber ("Search path: "+sFilePathMask) End End End Get pbError to bError Loop Move (fsFindClose(hFindFile)) to bOk End Function_Return lsSearchResult End_Function // Search a directory and all subdirectories For the files with normal windows mask-signs. // lsResult[?].sFileName contains full path and filename. // iMode = DIRMODE_FILES_ONLY // iMode = DIRMODE_DIRECTORIES_ONLY // iMode = DIRMODE_FILES_AND_DIRECTORIES (default) Function FileSearchRecursive String sFilePathMask Integer iFileDirMode Boolean bReturnOnlyOne Returns tsSearchResult[] Integer iMode Boolean bOnlyOne tsSearchResult[] lsFinalResult lsSearchResult If (num_arguments < 2) Begin Move DIRMODE_FILES_AND_DIRECTORIES to iMode End Else Begin Move iFileDirMode to iMode End If (num_arguments < 3) Begin Move False to bOnlyOne End Else Begin Move bReturnOnlyOne to bOnlyOne End Get FileSearchRecursivePriv sFilePathMask iMode bOnlyOne (&lsFinalResult) to lsSearchResult Function_Return lsFinalResult End_Function // Private {Visibility = Private} Function FileSearchRecursivePriv String sFilePathMask Integer iFileDirMode Boolean bReturnOnlyOne tsSearchResult[] ByRef lsFinalResult Returns tsSearchResult[] tsSearchResult[] lsSearchResultDir lsSearchResult Integer iMax iCnt iLast iFinalMax String sSearchInDir sFileMask Boolean bStop Move False to bStop Move (RightPos("\", sFilePathMask)) to iLast If (iLast > 0) Begin Move (Left(sFilePathMask, iLast - 1)) to sSearchInDir Move (Mid(sFilePathMask, Length(sFilePathMask), iLast + 1)) to sFileMask End Get FileSearch (sSearchInDir + "\*.*") DIRMODE_DIRECTORIES_ONLY to lsSearchResultDir Move (SizeOfArray(lsSearchResultDir)) to iMax Move 0 to iCnt While (iCnt < iMax and bStop = False) If (lsSearchResultDir[iCnt].sFilename <> "." and lsSearchResultDir[iCnt].sFilename <> "..") Begin Get FileSearchRecursivePriv (sSearchInDir + "\" + lsSearchResultDir[iCnt].sFilename + "\" + sFileMask) iFileDirMode bReturnOnlyOne (&lsFinalResult) to lsSearchResult End Increment iCnt If (bReturnOnlyOne = True) Begin If (SizeOfArray(lsFinalResult) > 0) Begin Move True to bStop End End Loop If (bStop = False) Begin Get FileSearch sFilePathMask iFileDirMode to lsSearchResult Move (SizeOfArray(lsSearchResult)) to iMax Move (SizeOfArray(lsFinalResult)) to iFinalMax Move 0 to iCnt While (iCnt < iMax and bStop = False) Move lsSearchResult[iCnt] to lsFinalResult[iFinalMax] Move (sSearchInDir + "\" + lsSearchResult[iCnt].sFilename) to lsFinalResult[iFinalMax].sFilename Increment iFinalMax Increment iCnt If (bReturnOnlyOne = True) Begin If (SizeOfArray(lsFinalResult) > 0) Begin Move True to bStop End End Loop End Function_Return lsSearchResult End_Function // Finds a list of files. // sSearchFiles is a list of files to search For separated by semicolon (;). // sSearchFiles may not contain paths but may contain wildcards. // sSearchPaths may only contain paths. // Returns a string array with the files // Returns only files with full path. // Use: // Get ListOfFiles "path1;path2" "*.txt;*.asc" // This will return all the .txt and .asc files with full path that exists in path1 and path2. Function ListOfFiles String sSearchPaths String sSearchFiles Returns String[] String[] saFileList Integer iFilelistCount iSearchFilesCount iCurSearchFile Integer iSearchPathsCount iCurSearchPath iFilesFound iCurFileFound String sCurSearchFile sCurSearchPath tsSearchResult[] lsSearchResult Get CountOfFields sSearchPaths to iSearchPathsCount Get CountOfFields sSearchFiles to iSearchFilesCount If (iSearchFilesCount > 0 and iSearchPathsCount > 0) Begin For iCurSearchFile from 1 to iSearchFilesCount Get FieldAtIndex sSearchFiles iCurSearchFile to sCurSearchFile Move (Trim(sCurSearchFile)) to sCurSearchFile If (sCurSearchFile <> "") Begin For iCurSearchPath from 1 to iSearchPathsCount Get FieldAtIndex sSearchPaths iCurSearchPath to sCurSearchPath If (Right(sCurSearchPath, 1) <> "\") Begin Move (sCurSearchPath + "\") to sCurSearchPath End Get FileSearch (sCurSearchPath + sCurSearchFile) DIRMODE_FILES_ONLY to lsSearchResult Move (SizeOfArray(lsSearchResult)) to iFilesFound Decrement iFilesFound For iCurFileFound from 0 to iFilesFound Move (sCurSearchPath + lsSearchResult[iCurFileFound].sFilename) to saFileList[iFilelistCount] Increment iFilelistCount Loop Loop End Loop End Function_Return saFileList End_Function // Get Windows Temp path Function FileTempPath Returns String Integer iRetVal String sTempPath #IF (!@ < 200) Move (ZeroString(MAX_PATH)) to sTempPath Move (fsGetTempPath(MAX_PATH, AddressOf(sTempPath))) to iRetVal If (iRetVal > MAX_PATH) Begin Move (ZeroString(iRetval)) to sTempPath Move (fsGetTempPath(iRetVal, AddressOf(sTempPath))) to iRetVal End Move (ToOEM(sTempPath)) To sTempPath #ELSE WString wTempPath Move (ZeroString(MAX_PATH)) to wTempPath Move (fsGetTempPath(MAX_PATH, AddressOf(wTempPath))) to iRetVal If (iRetVal > MAX_PATH) Begin Move (ZeroString(iRetval)) to wTempPath Move (fsGetTempPath(iRetVal, AddressOf(wTempPath))) to iRetVal End Move wTempPath To sTempPath #ENDIF Move (CString(sTempPath)) to sTempPath Function_Return sTempPath End_Function // Generates a temporary file. // Returns full path and filename or blank if no file could be created. // sPathName is the place where the temporary file is generated. If it is // not argumented the TEMP enviroment variable is used. If that is also not // available the current directory is used. // You can prefix the first 3 letters of the filename with sPrefix. Function FileTempFileName String sPathName String sPrefix Returns String Address aTempFileName String sPathNameTmp sPrefixTmp sTempFileName Boolean bOk #IF (!@ >= 200) WString wTempFileName #ENDIF Set pbError to False If (num_arguments > 0) Begin Move sPathName to sPathNameTmp End Else Begin Move "" to sPathNameTmp End If (num_arguments > 1) Begin Move sPrefix to sPrefixTmp End Else Begin Move "" to sPrefixTmp End Move (Trim(sPathNameTmp)) to sPathNameTmp If (sPathNameTmp = "") Begin Get FileTempPath to sPathNameTmp If (sPathNameTmp = "") Begin Move "." to sPathNameTmp End End #IF (!@ < 200) Move (ZeroString(MAX_PATH)) To sTempFilename Move (AddressOf(sTempFileName)) To aTempFileName Move (ToANSI(sPathNameTmp)) to sPathNameTmp Move (ToANSI(sPrefixTmp)) To sPrefixTmp #ELSE Move (ZeroString(MAX_PATH)) To wTempFilename Move (AddressOf(wTempFileName)) To aTempFileName #ENDIF Move (fsGetTempFileName(sPathNameTmp, sPrefixTmp, 0, aTempFileName)) to bOk If bOk Begin #IF (!@ < 200) Move (ToOEM(sTempFileName)) To sTempFileName #ELSE Move wTempFileName To sTempFileName #ENDIF Move (CString(sTempFileName)) to sTempFileName End Function_Return sTempFileName End_Function // Creates a new directory. // Returns True if succeeds. Function DirectoryCreate String sDirectoryName Returns Boolean Boolean bFound bOk Integer iErrorNumber Move False to bOk Set pbError to False Get FileExists sDirectoryName DIRMODE_DIRECTORIES_ONLY to bFound If (not(bFound)) Begin #IF (!@ < 200) Move (toAnsi(sDirectoryName)) To sDirectoryname #ENDIF Move (sDirectoryname+(Character(0))) to sDirectoryname Move (fsCreateDirectory(sDirectoryname, FNULL)) to bOk If (bOk = False) Begin // Could not create Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber ("Tried to create directory: "+sDirectoryname) End End End Function_Return bOk End_Function // Removes an existing empty directory. // Returns True if succeeds. Function DirectoryRemove String sDirectoryName Returns Boolean Boolean bFound bOk Integer iErrorNumber Move False to bOk Set pbError to False Get FileExists sDirectoryName DIRMODE_DIRECTORIES_ONLY to bFound If bFound Begin #IF (!@ < 200) Move (toAnsi(sDirectoryName)) To sDirectoryname #ENDIF Move (sDirectoryname+(Character(0))) to sDirectoryname Move (fsRemoveDirectory(sDirectoryname)) to bOk If (bOk = False) Begin // Could not delete Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber ("Tried to remove directory: "+sDirectoryName) End End End Function_Return bOk End_Function // Removes a directory and all its contents. // Returns true on succes. Function DirectoryRemoveRecursive String sDirectoryName Returns Boolean tsSearchResult[] alsSearchResults Integer iIndex Boolean bOk If (Right(sDirectoryName, 1) = "\") Begin Move (Left(sDirectoryName, Length(sDirectoryName) - 1)) to sDirectoryName End Get FileSearch (sDirectoryName + "\*") DIRMODE_DIRECTORIES_ONLY to alsSearchResults For iIndex from 2 to (SizeOfArray(alsSearchResults) - 1) Get DirectoryRemoveRecursive (sDirectoryName + "\" + alsSearchResults[iIndex].sFilename) to bOk If (not(bOk)) Begin Function_Return False End Loop Get FileSearch (sDirectoryName + "\*") DIRMODE_FILES_ONLY to alsSearchResults For iIndex from 0 to (SizeOfArray(alsSearchResults) - 1) Get FileDelete (sDirectoryName + "\" + alsSearchResults[iIndex].sFilename) to bOk If (not(bOk)) Begin Function_Return False End Loop Get DirectoryRemove sDirectoryName to bOk Function_Return bOk End_Function // Converts the filetime in UTC and returns a datetime in local time. // private Function ConvertFileTimeToLocalDateTime UBigInt ubiFileTime Returns DateTime Boolean bOk UBigInt ubiZero structSystemTime lsSystemTime lsLocalTime DateTime dtLocalTime Move 0 to lsSystemTime.wDay Move 0 to lsLocalTime.wDay Move 0 to ubiZero If (ubiFileTime <> ubiZero) Begin Move (fsFileTimeToSystemTime(AddressOf(ubiFileTime), AddressOf(lsSystemTime))) to bOk If bOk Begin Move (fsSystemTimeToTzSpecificLocalTime(FNULL, AddressOf(lsSystemTime), AddressOf(lsLocalTime))) to bOk If bOk Begin Move (DateSetYear(dtLocalTime, lsLocalTime.wYear)) to dtLocalTime Move (DateSetMonth(dtLocalTime, lsLocalTime.wMonth)) to dtLocalTime Move (DateSetDay(dtLocalTime, lsLocalTime.wDay)) to dtLocalTime Move (DateSetHour(dtLocalTime, lsLocalTime.wHour)) to dtLocalTime Move (DateSetMinute(dtLocalTime, lsLocalTime.wMinute)) to dtLocalTime Move (DateSetSecond(dtLocalTime, lsLocalTime.wSecond)) to dtLocalTime Move (DateSetMillisecond(dtLocalTime, lsLocalTime.wMillieseconds)) to dtLocalTime End End End Function_Return dtLocalTime End_Function // Returns the filename with full path where the casing is preserved from windows. Function FilePreservedFilename String sFilename Returns String Integer iNumOfDirectories iCurrentDirectory String sPreservedFilename sCurDir sSearchName tsSearchResult[] lsSearchResult Get CountOfFields sFilename "\" to iNumOfDirectories For iCurrentDirectory from 1 to (iNumOfDirectories - 1) Get FieldAtIndex sFilename iCurrentDirectory "\" to sCurDir If (sCurDir <> "") Begin If (Right(sCurDir, 1) <> ":") Begin Move (sPreservedFilename + sCurDir) to sSearchName Get FileSearch sSearchName DIRMODE_DIRECTORIES_ONLY to lsSearchResult If (SizeOfArray(lsSearchResult) > 0) Begin Move (sPreservedFilename + lsSearchResult[0].sFilename + "\") to sPreservedFilename End Else Begin Move (sPreservedFilename + sCurDir + "\") to sPreservedFilename End End Else Begin Move (sPreservedFilename + sCurDir + "\") to sPreservedFilename End End Else Begin Move (sPreservedFilename + "\") to sPreservedFilename End Loop Get FileSearch sFilename DIRMODE_FILES_AND_DIRECTORIES to lsSearchResult If (SizeOfArray(lsSearchResult) > 0) Begin Move (sPreservedFilename + lsSearchResult[0].sFilename) to sPreservedFilename End Else Begin Function_Return "" End Function_Return sPreservedFilename End_Function // Returns the number of fields present in a string of fields seperated by a delimiter. // If sDelimiter is not applied the ";" will be used. Function CountOfFields String sFields String sDelimiter Returns Integer Integer iChar icChar iField String sDlm If (sFields ="") Begin Function_Return 0 End If (num_arguments > 1) Begin Move sDelimiter to sDlm End Else Begin Move ";" to sDlm End Move (Length(sFields) -1) to icChar For iChar from 1 to icChar If (Mid(sFields, 1, iChar) = sDlm) Begin Increment iField End Loop Function_Return (iField +1) End_Function // Returns a field from a string containing multiple delimited fields. // Index is 1-based. Function FieldAtIndex String sFields Integer iIndex String sDelimiter Returns String Integer iField iPos String sField sDlm If (num_arguments > 2) Begin Move sDelimiter to sDlm End Else Begin Move ";" to sDlm End Move (sFields + sDlm) to sFields For iField from 1 to iIndex Move (Pos(sDlm, sFields)) to iPos If iPos Begin Move (Left(sFields, iPos -1)) to sField Move (Right(sFields, Length(sFields) -iPos)) to sFields End Else Begin Function_Return "" End Loop Function_Return sField End_Function // Removes the file extention from the sFile string and returns the extention including "." // Example sFile = "x:\text.txt". The function returns ".txt" and sFile = "x:\text". Function RemoveExtention String ByRef sFilename Returns String String sExtention Integer iLengthExtention Get FileExtention sFilename to sExtention Move (Length(sExtention)) to iLengthExtention If (iLengthExtention > 0) Begin Move (Left(sFilename, (Length(sFilename) - iLengthExtention - 1))) to sFilename End Function_Return sExtention End_Function // Add a directory separator if it is not present. // Example sFoldername = "x:\FolderA". The function returns "x:\FolderA\" Function AddFolderSeperator String sFolderName Returns String String sDirSep Move (SysConf(SYSCONF_DIR_SEPARATOR)) to sDirSep Move (Trim(sFolderName)) to sFolderName If (Right(sFolderName, 1) <> sDirSep) Begin Move (sFolderName + sDirSep) to sFolderName End Function_Return sFolderName End_Function // Removes a directory separator if it is present. // Example sFoldername = "x:\FolderA\". The function returns "x:\FolderA" Function RemoveFolderSeperator String sFolderName Returns String String sDirSep Move (SysConf(SYSCONF_DIR_SEPARATOR)) to sDirSep Move (Trim(sFolderName)) to sFolderName If (Right(sFolderName, 1) = sDirSep) Begin Move (Left(sFolderName, Length(sFolderName) - 1)) to sFolderName End Function_Return sFolderName End_Function Function FileLastWriteTime String sFileName Returns tFileTime DWord dwAccess DWord dwShared DWord dwCreate Handle hFile Integer iRetval iErrorNumber tFileTime ftLastWrite // Append sFilename (Character(0)) (Character(0)) Move (GENERIC_READ iOr GENERIC_WRITE) To dwAccess Move FILE_SHARE_RANDOM To dwShared Move OPEN_EXISTING To dwCreate Move (fsCreatefile(sFilename, dwAccess, dwShared, FNULL, dwCreate, FILE_ATTRIBUTE_NORMAL, FNULL)) To hFile If (hFile = INVALID_HANDLE_VALUE) Begin Move (fsGetLastError()) To iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber sFileName End Procedure_Return End Else Begin Move 0 To ftLastWrite.dwLowDateTime Move (fsGetFileTime(hFile,FNULL,FNULL,AddressOf(ftLastWrite))) To iRetval If (iRetVal = 0) Begin //Could not close Move (fsGetLastError()) To iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber sFileName End End Move (fsCloseHandle(hFile)) To iRetVal If (iRetVal = 0) Begin //Could not close Move (fsGetLastError()) To iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber sFileName End End End Function_Return ftLastWrite End_Function Function CurrentSystemTimeAsFileTime Returns tFileTime Integer iRetVal Integer iErrorNumber String sFileName tFileTime ftCurrentTime Move 0 to ftCurrentTime.dwLowDateTime Move (fsGetSystemTimeAsFileTime(AddressOf(ftCurrentTime))) to iRetVal If (iRetVal = 0) Begin Move (fsGetLastError()) to iErrorNumber If iErrorNumber Begin Send DoShowError iErrorNumber sFileName End End Function_Return ftCurrentTime End_Function // Nils 2018-08-30 Added this message from Akefs.pkg as we need it For the // SourceCodeTools project Procedure Set FileLastWriteTime String sFileName tFileTime ftLastWrite DWord dwAccess dwShared dwCreate Handle hFile Integer iRetval iErrorNumber Append sFilename (Character(0)) (Character(0)) Move (GENERIC_READ ior GENERIC_WRITE) to dwAccess Move FILE_SHARE_RANDOM to dwShared Move OPEN_EXISTING to dwCreate Move (fsCreatefile(sFilename, dwAccess, dwShared, FNULL, dwCreate, FILE_ATTRIBUTE_NORMAL, FNULL)) to hFile If (hFile = INVALID_HANDLE_VALUE) Begin Move (fsGetLastError()) to iErrorNumber If (iErrorNumber <> 0) Begin Send DoShowError iErrorNumber sFileName End Procedure_Return End Else Begin Move (fsSetFileTime(hFile,FNULL,FNULL,AddressOf(ftLastWrite))) to iRetval If (iRetVal = 0) Begin //Could not close Move (fsGetLastError()) to iErrorNumber If (iErrorNumber <> 0) Begin Send DoShowError iErrorNumber sFileName End End Move (fsCloseHandle(hFile)) to iRetVal If (iRetVal = 0) Begin //Could not close Move (fsGetLastError()) to iErrorNumber If (iErrorNumber <> 0) Begin Send DoShowError iErrorNumber sFileName End End End End_Procedure // Fetch the error message from the system message table using the default language. // If not in unicode then the variable sAppendErrorText is in ANSI Procedure DoShowError Integer iErrorNumber String sAppendErrorText Pointer lpOut Integer iRetChars iRetVal String sMsg Boolean bOk #IF (!@ >= 200) WString wMsg #ENDIF Move 0 to lpOut Move (fsFormatMessage((FORMAT_MESSAGE_FROM_SYSTEM+FORMAT_MESSAGE_IGNORE_INSERTS+FORMAT_MESSAGE_ALLOCATE_BUFFER), FNULL, iErrorNumber, FNULL, AddressOf(lpOut), 0, FNULL)) to iRetChars If (iRetChars > 0) Begin #IF (!@ < 200) Move (ZeroString(iRetChars)) to sMsg Move (MemCopy(AddressOf(sMsg), lpOut, iRetChars)) to bOk Move (fsLocalFree(lpOut)) to iRetVal Move (ToOEM(sMsg)) To sMsg Move (ToOEM(sAppendErrorText)) To sAppendErrorText #ELSE Move (ZeroString(iRetChars*2)) to wMsg Move (MemCopy(AddressOf(wMsg), lpOut, iRetChars*2)) to bOk Move (fsLocalFree(lpOut)) to iRetVal Move wMsg To sMsg #ENDIF If (num_arguments > 0) Begin Move (Trim(sAppendErrorText)) to sAppendErrorText If (sAppendErrorText <> "") Begin Append sMsg "\n" sAppendErrorText End End Send warning_box sMsg End End_Procedure // Shows a warning message to user with OK button and a exclamation icon. // private Procedure Warning_Box String sWngMsg Integer iVoid Boolean bSendVdfError Set pbError to True Get pbErrorAsVDFError to bSendVdfError If (bSendVdfError = False) Begin Get Message_Box sWngMsg "Filesystem Error" MB_OK MB_ICONEXCLAMATION to iVoid End Else Begin Error DFERR_PROGRAM sWngMsg End End_Procedure // Fetch the filename from the list of filenames associated with a filenumber. // This function is used For reporting filenames during an error. // private Function FileErrorText Integer iFilenumber Returns String String sErrorText structFile[] lsFile Get plsFile to lsFile If (iFilenumber < SizeOfArray(lsFile)) Begin Move ("File: "+lsFile[iFilenumber].sFilename) to sErrorText End Function_Return sErrorText End_Function End_Class