`
Windows API: Loop through all files on drive with unicode support 2006-11-21 -- Menno De Ruiter I thought I post a post which loops / enumerates all files and dirs on the hd, I had the problem first of the 260 path limitation, but the unicode api's can handle path > 32k length, The routine does not include parse situations, but is okay for general use etc. It also converts the file time into your local time thus UTC + bias SystemTimeToTzSpecificLocalTime etc. TheRoutine routine data TIME_ZONE_INFORMATION Group,pre() TZI:Bias Long TZI:StandardName String(32) TZI:STYear USHORT TZI:STMonth USHORT TZI:STDayOfWeek USHORT TZI:STDay USHORT TZI:STHour USHORT TZI:STMinute USHORT TZI:STSecond USHORT TZI:STMilliseconds USHORT TZI:StandardBias Long TZI:DaylightName String(32) TZI:DDYear USHORT TZI:DDMonth USHORT TZI:DDDayOfWeek USHORT TZI:DDDay USHORT TZI:DDHour USHORT TZI:DDMinute USHORT TZI:DDSecond USHORT TZI:DDMilliseconds USHORT TZI:DaylightBias LONG TZI:Extra String(1024) End FileTime Group,pre() LowDateTime ULong HighDateTime ULong End IFileTime Group,pre() ILowDateTime ULong IHighDateTime ULong End ReturnVal Long GSYSTEMTIME GROUP,PRE() GST:wYear USHORT GST:wMonth USHORT GST:wDayOfWeek USHORT GST:wDay USHORT GST:wHour USHORT GST:wMinute USHORT GST:wSecond USHORT GST:wMilliseconds USHORT END OGSYSTEMTIME GROUP,PRE() OGST:wYear USHORT OGST:wMonth USHORT OGST:wDayOfWeek USHORT OGST:wDay USHORT OGST:wHour USHORT OGST:wMinute USHORT OGST:wSecond USHORT OGST:wMilliseconds USHORT END WIFindData Group,pre() WIFD:FileAttrib Ulong WIFD:CreateTimeLow ulong WIFD:CreateTimeHigh ulong WIFD:LastAccessTimeLow ulong WIFD:LastAccessTimeHigh ulong WIFD:LastWriteTimeLow ulong WIFD:LastWriteTimeHigh ulong WIFD:FileSizeHigh ULong WIFD:FileSizeLow ULong WIFD:Reserved0 ULong WIFD:Reserved1 ULong WIFD:FileName String(65536) WIFD:AlternateFileName String(14) End WOFindData Group,pre() WOFD:FileAttrib Ulong WOFD:CreateTimeLow ulong WOFD:CreateTimeHigh ulong WOFD:LastAccessTimeLow ulong WOFD:LastAccessTimeHigh ulong WOFD:LastWriteTimeLow ulong WOFD:LastWriteTimeHigh ulong WOFD:FileSizeHigh ULong WOFD:FileSizeLow ULong WOFD:Reserved0 ULong WOFD:Reserved1 ULong WOFD:FileName String(65536) WOFD:AlternateFileName String(14) End WWLocalFile String(65536) AIFindData Group,pre() AIFD:FileAttrib Ulong AIFD:CreateTimeLow ulong AIFD:CreateTimeHigh ulong AIFD:LastAccessTimeLow ulong AIFD:LastAccessTimeHigh ulong AIFD:LastWriteTimeLow ulong AIFD:LastWriteTimeHigh ulong AIFD:FileSizeHigh ULong AIFD:FileSizeLow ULong AIFD:Reserved0 ULong AIFD:Reserved1 ULong AIFD:FileName String(260) AIFD:AlternateFileName String(14) End AOFindData Group,pre() AOFD:FileAttrib Ulong AOFD:CreateTimeLow ulong AOFD:CreateTimeHigh ulong AOFD:LastAccessTimeLow ulong AOFD:LastAccessTimeHigh ulong AOFD:LastWriteTimeLow ulong AOFD:LastWriteTimeHigh ulong AOFD:FileSizeHigh ULong AOFD:FileSizeLow ULong AOFD:Reserved0 ULong AOFD:Reserved1 ULong AOFD:FileName String(260) AOFD:AlternateFileName String(14) End ALocalFile String(260) ERROR_FILE_NOT_FOUND Equate(2) ERROR_ACCESS_DENIED Equate(5) TIME_ZONE_ID_INVALID Equate(0FFFFFFFFh) TIME_ZONE_ID_UNKNOWN Equate(0h) TIME_ZONE_ID_STANDARD Equate(1h) TIME_ZONE_ID_DAYLIGHT Equate(2h) !GetTimeZoneInformation(long),long,raw,pascal ZoneInformation long ERROR_NO_MORE_FILES equate(18) LocalFileHandleNew long CurrentQTDirsToDoPosition ULong CurrentQTDirsPosition Ulong code ZoneInformation = GetTimeZoneInformation(Address(TIME_ZONE_INFORMATION)) !! Case ZoneInformation !! Of TIME_ZONE_ID_UNKNOWN !! !Message('TIME_ZONE_ID_UNKNOWN') !! Of TIME_ZONE_ID_STANDARD !! !Message('TIME_ZONE_ID_STANDARD') !! Of TIME_ZONE_ID_DAYLIGHT !! !Message('TIME_ZONE_ID_DAYLIGHT') !! End CurrentQTDirsPosition = 0 LocalRootDir = 'c:\' LocalCurrentPath = Clip(LocalRootDir) LocalRootDir = Clip(LocalRootDir) & '*.*' ALocalFile = '\\?\' & Clip(LocalRootDir) & Chr(0) Clear(AIFindData) Clear(AOFindData) Clear(WIFindData) Clear(WOFindData) Clear(WWLocalFile) L# = MultiByteToWideChar(CP_THREAD_ACP,0,Address(ALocalFile),Len(Clip(ALocalFile)),Address(WWLocalFile),0) R# = MultiByteToWideChar(CP_THREAD_ACP,0,Address(ALocalFile),Len(Clip(ALocalFile)),Address(WWLocalFile),L#) LocalFileHandle = FindFirstFileExW(Address(WWLocalFile),0,Address(WOFindData),0,0,0) Case LocalFileHandle Of -1 R# = GetLastError() Message('error ' & R#) Case R# Of ERROR_FILE_NOT_FOUND Message('ERROR_FILE_NOT_FOUND') Of ERROR_ACCESS_DENIED Message('ERROR_ACCESS_DENIED') Else Message('error unknown ' & R#) End End R# = WideCharToMultiByte(CP_ACP,0,Address(WOFD:FileName),Size(WOFD:FileName),Address(ALocalFile),Size(ALocalFile),0,0) !Message(WOFD:FileAttrib) QTFiles:Number = QTFiles:Number + 1 QTFiles:Name = Clip(ALocalFile) QTFiles:QTDirsNumber = 0 QTFiles:FILE_ATTRIBUTE_READONLY = 0 QTFiles:FILE_ATTRIBUTE_HIDDEN = 0 QTFiles:FILE_ATTRIBUTE_SYSTEM = 0 QTFiles:FILE_ATTRIBUTE_DIRECTORY = 0 QTFiles:FILE_ATTRIBUTE_ARCHIVE = 0 QTFiles:FILE_ATTRIBUTE_DEVICE = 0 QTFiles:FILE_ATTRIBUTE_UNKNOWNXXX0 = 0 QTFiles:FILE_ATTRIBUTE_NORMAL = 0 QTFiles:FILE_ATTRIBUTE_TEMPORARY = 0 QTFiles:FILE_ATTRIBUTE_SPARSE_FILE = 0 QTFiles:FILE_ATTRIBUTE_REPARSE_POINT = 0 QTFiles:FILE_ATTRIBUTE_COMPRESSED = 0 QTFiles:FILE_ATTRIBUTE_OFFLINE = 0 QTFiles:FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0 QTFiles:FILE_ATTRIBUTE_ENCRYPTED = 0 If Band(WOFD:FileAttrib,01h) > 0 QTFiles:FILE_ATTRIBUTE_READONLY = True End If Band(WOFD:FileAttrib,02h) > 0 QTFiles:FILE_ATTRIBUTE_HIDDEN = True End If Band(WOFD:FileAttrib,04h) > 0 QTFiles:FILE_ATTRIBUTE_SYSTEM = True End If Band(WOFD:FileAttrib,010h) > 0 QTFiles:FILE_ATTRIBUTE_DIRECTORY = True End If Band(WOFD:FileAttrib,020h) > 0 QTFiles:FILE_ATTRIBUTE_ARCHIVE = True End If Band(WOFD:FileAttrib,040h) > 0 QTFiles:FILE_ATTRIBUTE_DEVICE = True End If Band(WOFD:FileAttrib,060h) > 0 QTFiles:FILE_ATTRIBUTE_UNKNOWNXXX0 = True End If Band(WOFD:FileAttrib,080h) > 0 QTFiles:FILE_ATTRIBUTE_NORMAL = True End If Band(WOFD:FileAttrib,0100h) > 0 QTFiles:FILE_ATTRIBUTE_TEMPORARY = True End If Band(WOFD:FileAttrib,0200h) > 0 QTFiles:FILE_ATTRIBUTE_SPARSE_FILE = True End If Band(WOFD:FileAttrib,0400h) > 0 QTFiles:FILE_ATTRIBUTE_REPARSE_POINT = True End If Band(WOFD:FileAttrib,0800h) > 0 QTFiles:FILE_ATTRIBUTE_COMPRESSED = True End If Band(WOFD:FileAttrib,01000h) > 0 QTFiles:FILE_ATTRIBUTE_OFFLINE = True End If Band(WOFD:FileAttrib,02000h) > 0 QTFiles:FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = True End If Band(WOFD:FileAttrib,04000h) > 0 QTFiles:FILE_ATTRIBUTE_ENCRYPTED = True End QTFiles:CreationTimeString8 = 0 QTFiles:CreationTimeReal = 0 QTFiles:CreationTimeLow = WOFD:CreateTimeLow QTFiles:CreationTimeHigh = WOFD:CreateTimeHigh IFileTime.ILowDateTime = WOFD:CreateTimeLow IFileTime.IHighDateTime = WOFD:CreateTimeHigh ReturnVal = FileTimeToSystemTime(Address(IFileTime),Address(OGSYSTEMTIME)) ReturnVal = SystemTimeToTzSpecificLocalTime(Address(TIME_ZONE_INFORMATION),Address(OGSYSTEMTIME),Address(GSYSTEMTIME)) QTFiles:CreationTimeDate = Deformat(Format(GSYSTEMTIME.GST:wYear,@N04)&Format(GSYSTEMTIME.GST:wMonth,@N02)&Format(GSYSTEMTIME.GST:wDay,@N02),@D12) QTFiles:CreationTimeTime = ((GSYSTEMTIME.GST:wHour * 60 * 60 * 100)+1) + ((GSYSTEMTIME.GST:wMinute * 60 * 100)) + ((GSYSTEMTIME.GST:wSecond * 100)) + (GST:wMilliseconds/100) QTFiles:LastAccessTimeString8 = 0 QTFiles:LastAccessTimeReal = 0 QTFiles:LastAccessTimeLow = WOFD:LastAccessTimeLow QTFiles:LastAccessTimeHigh = WOFD:LastAccessTimeHigh IFileTime.ILowDateTime = WOFD:LastAccessTimeLow IFileTime.IHighDateTime = WOFD:LastAccessTimeHigh ReturnVal = FileTimeToSystemTime(Address(IFileTime),Address(OGSYSTEMTIME)) ReturnVal = SystemTimeToTzSpecificLocalTime(Address(TIME_ZONE_INFORMATION),Address(OGSYSTEMTIME),Address(GSYSTEMTIME)) QTFiles:LastAccessTimeDate = Deformat(Format(GSYSTEMTIME.GST:wYear,@N04)&Format(GSYSTEMTIME.GST:wMonth,@N02)&Format(GSYSTEMTIME.GST:wDay,@N02),@D12) QTFiles:LastAccessTimeTime = ((GSYSTEMTIME.GST:wHour * 60 * 60 * 100)+1) + ((GSYSTEMTIME.GST:wMinute * 60 * 100)) + ((GSYSTEMTIME.GST:wSecond * 100)) + (GST:wMilliseconds/100) QTFiles:LastWriteTimeString8 = 0 QTFiles:LastWriteTimeReal = 0 QTFiles:LastWriteTimeLow = WOFD:LastWriteTimeLow QTFiles:LastWriteTimeHigh = WOFD:LastWriteTimeHigh IFileTime.ILowDateTime = WOFD:LastAccessTimeLow IFileTime.IHighDateTime = WOFD:LastAccessTimeHigh ReturnVal = FileTimeToSystemTime(Address(IFileTime),Address(OGSYSTEMTIME)) ReturnVal = SystemTimeToTzSpecificLocalTime(Address(TIME_ZONE_INFORMATION),Address(OGSYSTEMTIME),Address(GSYSTEMTIME)) QTFiles:LastWriteTimeDate = Deformat(Format(GSYSTEMTIME.GST:wYear,@N04)&Format(GSYSTEMTIME.GST:wMonth,@N02)&Format(GSYSTEMTIME.GST:wDay,@N02),@D12) QTFiles:LastWriteTimeTime = ((GSYSTEMTIME.GST:wHour * 60 * 60 * 100)+1) + ((GSYSTEMTIME.GST:wMinute * 60 * 100)) + ((GSYSTEMTIME.GST:wSecond * 100)) + (GST:wMilliseconds/100) QTFiles:FileSizeString8 = 0 QTFiles:FileSizeLow = WOFD:FileSizeLow QTFiles:FileSizeHigh = WOFD:FileSizeHigh QTFiles:FileSizeReal = (WOFD:FileSizeHigh*256) + WOFD:FileSizeLow QTFiles:DosFileName = WOFD:AlternateFileName If QTFiles:FILE_ATTRIBUTE_DIRECTORY = True QTDirs:Number = QTDirs:Number + 1 QTDirs:QTFilesNumber = QTFiles:Number QTDirs:Name = Clip(LocalCurrentPath) & Clip(QTFiles:Name) QTDirs:QTFilesPosition = Pointer(QTFiles) + 1 Add(QTDirs) QTFiles:QTDirsNumber = QTDirs:Number Else QTFiles:QTDirsNumber = 0 End Add(QTFiles) X# = 1 l1 Loop !5000 Times X# = X# + 1 D# = D# + 1 If D# > 1000 Display D# = 0 End ALocalFile = '\\?\' & Clip(LocalRootDir) & Chr(0) Clear(WOFindData) L# = MultiByteToWideChar(CP_THREAD_ACP,0,Address(ALocalFile),Len(Clip(ALocalFile)),Address(WWLocalFile),0) R# = MultiByteToWideChar(CP_THREAD_ACP,0,Address(ALocalFile),Len(Clip(ALocalFile)),Address(WWLocalFile),L#) R# = FindNextFileW(LocalFileHandle,Address(WOFindData)) If R# < 1 R# = GetLastError() Case R# Of ERROR_FILE_NOT_FOUND Message('ERROR_FILE_NOT_FOUND') Break Of ERROR_ACCESS_DENIED Message('ERROR_ACCESS_DENIED') Break Of ERROR_NO_MORE_FILES Loop 1000 Times CurrentQTDirsPosition = CurrentQTDirsPosition + 1 If CurrentQTDirsPosition > TotalQTDirs break l1 End Get(QTDirs,CurrentQTDirsPosition) N# = Instring(Chr(0),QTDirs:Name,1,1) If N# > 1 QTDirs:Name = QTDirs:Name[1 : N#-1] End LocalCurrentPath = Clip(QTDirs:Name) & '\' LocalRootDir = Clip(QTDirs:Name) & '\*.*' ALocalFile = '\\?\' & Clip(LocalRootDir) & Chr(0) Clear(WOFindData) L# = MultiByteToWideChar(CP_THREAD_ACP,0,Address(ALocalFile),Len(Clip(ALocalFile)),Address(WWLocalFile),0) R# = MultiByteToWideChar(CP_THREAD_ACP,0,Address(ALocalFile),Len(Clip(ALocalFile)),Address(WWLocalFile),L#) LocalFileHandle = FindFirstFileExW(Address(WWLocalFile),0,Address(WOFindData),0,0,0) If LocalFileHandle < 1 Cycle Else Break End End Else !Message('error unknown ' & R#) Break End End Clear(ALocalFile) R# = WideCharToMultiByte(CP_ACP,0,Address(WOFD:FileName),Size(WOFD:FileName),Address(ALocalFile),Size(ALocalFile),0,0) N# = Instring(Chr(0),ALocalFile,1,1) If N# > 1 ALocalFile = ALocalFile[1 : N#-1] End Case Clip(ALocalFile) Of '.' OrOf '..' Cycle End QTFiles:NumberHIGH = QTFiles:NumberHIGH + 1 QTFiles:Number = QTFiles:NumberHIGH QTFiles:Name = Clip(ALocalFile) QTFiles:QTDirsNumber = 0 QTFiles:FILE_ATTRIBUTE_READONLY = 0 QTFiles:FILE_ATTRIBUTE_HIDDEN = 0 QTFiles:FILE_ATTRIBUTE_SYSTEM = 0 QTFiles:FILE_ATTRIBUTE_DIRECTORY = 0 QTFiles:FILE_ATTRIBUTE_ARCHIVE = 0 QTFiles:FILE_ATTRIBUTE_DEVICE = 0 QTFiles:FILE_ATTRIBUTE_UNKNOWNXXX0 = 0 QTFiles:FILE_ATTRIBUTE_NORMAL = 0 QTFiles:FILE_ATTRIBUTE_TEMPORARY = 0 QTFiles:FILE_ATTRIBUTE_SPARSE_FILE = 0 QTFiles:FILE_ATTRIBUTE_REPARSE_POINT = 0 QTFiles:FILE_ATTRIBUTE_COMPRESSED = 0 QTFiles:FILE_ATTRIBUTE_OFFLINE = 0 QTFiles:FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0 QTFiles:FILE_ATTRIBUTE_ENCRYPTED = 0 If Band(WOFD:FileAttrib,01h) > 0 QTFiles:FILE_ATTRIBUTE_READONLY = True End If Band(WOFD:FileAttrib,02h) > 0 QTFiles:FILE_ATTRIBUTE_HIDDEN = True End If Band(WOFD:FileAttrib,04h) > 0 QTFiles:FILE_ATTRIBUTE_SYSTEM = True End If Band(WOFD:FileAttrib,010h) > 0 QTFiles:FILE_ATTRIBUTE_DIRECTORY = True End If Band(WOFD:FileAttrib,020h) > 0 QTFiles:FILE_ATTRIBUTE_ARCHIVE = True End If Band(WOFD:FileAttrib,040h) > 0 QTFiles:FILE_ATTRIBUTE_DEVICE = True End If Band(WOFD:FileAttrib,060h) > 0 QTFiles:FILE_ATTRIBUTE_UNKNOWNXXX0 = True End If Band(WOFD:FileAttrib,080h) > 0 QTFiles:FILE_ATTRIBUTE_NORMAL = True End If Band(WOFD:FileAttrib,0100h) > 0 QTFiles:FILE_ATTRIBUTE_TEMPORARY = True End If Band(WOFD:FileAttrib,0200h) > 0 QTFiles:FILE_ATTRIBUTE_SPARSE_FILE = True End If Band(WOFD:FileAttrib,0400h) > 0 QTFiles:FILE_ATTRIBUTE_REPARSE_POINT = True End If Band(WOFD:FileAttrib,0800h) > 0 QTFiles:FILE_ATTRIBUTE_COMPRESSED = True End If Band(WOFD:FileAttrib,01000h) > 0 QTFiles:FILE_ATTRIBUTE_OFFLINE = True End If Band(WOFD:FileAttrib,02000h) > 0 QTFiles:FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = True End If Band(WOFD:FileAttrib,04000h) > 0 QTFiles:FILE_ATTRIBUTE_ENCRYPTED = True End QTFiles:CreationTimeString8 = 0 QTFiles:CreationTimeReal = 0 QTFiles:CreationTimeLow = WOFD:CreateTimeLow QTFiles:CreationTimeHigh = WOFD:CreateTimeHigh IFileTime.ILowDateTime = WOFD:CreateTimeLow IFileTime.IHighDateTime = WOFD:CreateTimeHigh ReturnVal = FileTimeToSystemTime(Address(IFileTime),Address(OGSYSTEMTIME)) ReturnVal = SystemTimeToTzSpecificLocalTime(Address(TIME_ZONE_INFORMATION),Address(OGSYSTEMTIME),Address(GSYSTEMTIME)) QTFiles:CreationTimeDate = Deformat(Format(GSYSTEMTIME.GST:wYear,@N04)&Format(GSYSTEMTIME.GST:wMonth,@N02)&Format(GSYSTEMTIME.GST:wDay,@N02),@D12) QTFiles:CreationTimeTime = ((GSYSTEMTIME.GST:wHour * 60 * 60 * 100)+1) + ((GSYSTEMTIME.GST:wMinute * 60 * 100)) + ((GSYSTEMTIME.GST:wSecond * 100)) + (GST:wMilliseconds/100) QTFiles:LastAccessTimeString8 = 0 QTFiles:LastAccessTimeReal = 0 QTFiles:LastAccessTimeLow = WOFD:LastAccessTimeLow QTFiles:LastAccessTimeHigh = WOFD:LastAccessTimeHigh IFileTime.ILowDateTime = WOFD:LastAccessTimeLow IFileTime.IHighDateTime = WOFD:LastAccessTimeHigh ReturnVal = FileTimeToSystemTime(Address(IFileTime),Address(OGSYSTEMTIME)) ReturnVal = SystemTimeToTzSpecificLocalTime(Address(TIME_ZONE_INFORMATION),Address(OGSYSTEMTIME),Address(GSYSTEMTIME)) QTFiles:LastAccessTimeDate = Deformat(Format(GSYSTEMTIME.GST:wYear,@N04)&Format(GSYSTEMTIME.GST:wMonth,@N02)&Format(GSYSTEMTIME.GST:wDay,@N02),@D12) QTFiles:LastAccessTimeTime = ((GSYSTEMTIME.GST:wHour * 60 * 60 * 100)+1) + ((GSYSTEMTIME.GST:wMinute * 60 * 100)) + ((GSYSTEMTIME.GST:wSecond * 100)) + (GST:wMilliseconds/100) QTFiles:LastWriteTimeString8 = 0 QTFiles:LastWriteTimeReal = 0 QTFiles:LastWriteTimeLow = WOFD:LastWriteTimeLow QTFiles:LastWriteTimeHigh = WOFD:LastWriteTimeHigh IFileTime.ILowDateTime = WOFD:LastAccessTimeLow IFileTime.IHighDateTime = WOFD:LastAccessTimeHigh ReturnVal = FileTimeToSystemTime(Address(IFileTime),Address(OGSYSTEMTIME)) ReturnVal = SystemTimeToTzSpecificLocalTime(Address(TIME_ZONE_INFORMATION),Address(OGSYSTEMTIME),Address(GSYSTEMTIME)) QTFiles:LastWriteTimeDate = Deformat(Format(GSYSTEMTIME.GST:wYear,@N04)&Format(GSYSTEMTIME.GST:wMonth,@N02)&Format(GSYSTEMTIME.GST:wDay,@N02),@D12) QTFiles:LastWriteTimeTime = ((GSYSTEMTIME.GST:wHour * 60 * 60 * 100)+1) + ((GSYSTEMTIME.GST:wMinute * 60 * 100)) + ((GSYSTEMTIME.GST:wSecond * 100)) + (GST:wMilliseconds/100) QTFiles:FileSizeString8 = 0 QTFiles:FileSizeLow = WOFD:FileSizeLow QTFiles:FileSizeHigh = WOFD:FileSizeHigh QTFiles:FileSizeReal = (WOFD:FileSizeHigh*256) + WOFD:FileSizeLow QTFiles:DosFileName = WOFD:AlternateFileName If QTFiles:FILE_ATTRIBUTE_DIRECTORY = True QTDirs:NumberHIGH = QTDirs:NumberHIGH + 1 QTDirs:Number = QTDirs:NumberHIGH QTDirs:QTFilesNumber = QTFiles:Number QTDirs:Name = Clip(LocalCurrentPath) & Clip(QTFiles:Name) QTDirs:QTFilesPosition = Pointer(QTFiles) + 1 Add(QTDirs) TotalQTDirs = TotalQTDirs + 1 QTFiles:QTDirsNumber = QTDirs:Number Else QTFiles:QTDirsNumber = 0 End Add(QTFiles) End Printed December 3, 2024, 11:52 am This article has been viewed/printed 35237 times. Google search has resulted in 126 hits on this article since January 25, 2004. |