16 static CCSTR ANY_FNAME = _T(
"*.*");
62 if (pItem1 && pItem2) {
63 rc = _tcsicmp( pItem1->
Name, pItem2->Name );
65 if (pItem1) rc = -1;
else if (pItem2) rc = 1;
71 #if _DEBUG // Debugging utility callbacks 78 #if 0 // Show full file pathname 79 TCHAR pathname[ MAX_PATH ];
93 #if 1 // Show full directory path 94 TCHAR path[ MAX_PATH ];
129 #if USE_FILE_ENTRY_SIZEATTR 138 : Name( NULL ), Ext( NULL )
145 : Name( NULL ), Ext( NULL )
147 _init( pfd->cFileName, dir );
148 #if USE_FILE_ENTRY_SIZEATTR 149 Attr = pfd->dwFileAttributes;
150 ULARGE_INTEGER ul = {{ pfd->nFileSizeLow, pfd->nFileSizeHigh }};
152 Time = pfd->ftLastWriteTime;
167 if (pFile)
delete pFile;
190 return (pEntry != NULL);
200 _tcscpy_s( &Buff[len], BufLen-len,
Name );
201 len += (UINT)_tcslen(
Name );
204 len = (UINT)_tcslen(
Name );
205 _tcscpy_s( Buff, BufLen,
Name );
212 TCHAR fullName[ MAX_PATH ];
233 #if USE_FILE_ENTRY_SIZEATTR 240 _init( name, parent );
246 _init( pfd->cFileName, parent );
247 #if USE_FILE_ENTRY_SIZEATTR 248 Attr = pfd->dwFileAttributes;
284 #if (FILEDIR_VER == 1) 300 WIN32_FIND_DATA fd = {0};
307 #if 1 // Sort the first level of the tree 309 pDir->
SubDir->QuickSort( __sort_DirEntry, NULL );
314 if (pCount) *pCount = nFiles;
317 #else // v2++ : Per-thread current directory 319 #define DISABLE_FS_REDIR 0 320 #elif !defined( DISABLE_FS_REDIR ) 321 #if _WIN32_WINNT >= 0x0501 || defined(WINBASE_DECLARE_GET_SYSTEM_WOW64_DIRECTORY) 322 #define DISABLE_FS_REDIR 1 324 #define DISABLE_FS_REDIR 0 344 IF_DEBUG( memset( &fd, 0,
sizeof(fd) ));
364 #if 1 // Sort the first level of the tree 366 pDir->
SubDir->QuickSort( __sort_DirEntry, NULL );
370 if (pCount) *pCount = nFiles;
388 WIN32_FIND_DATA fd = {0};
398 #if 1 // Sort the first level of the tree 400 pDir->
SubDir->QuickSort( __sort_DirEntry, NULL );
413 if (pCount) *pCount = nFiles;
423 DWORD err = GetLastError();
434 *
pCtx->PathEnd = _T(
'*');
470 if (ccRemain < ((
long)_tcslen( dirName ) + 4 ))
472 TRACE(
DP_ERROR,
_F(
"Concatenated path too long: %s + %s\\*.*\n"),
pCtx->CurrentDir, dirName );
477 _tcsncpyz(
pCtx->PathEnd, ANY_FNAME, ccRemain - _tcslen( dirName ));
483 LogScanError(_T(
"[DirEntry::Scan] FindFirstFile"), NULL,
pCtx );
513 Files->Append( pFile );
530 pCtx->PathEnd = pathEnd;
545 if (pName) pName++;
else pName =
Name;
550 if (!pName) pName =
Name;
575 UINT N = (UINT)_tcslen(
pDir->
Name );
576 if ((remain -= N) < 0)
return 0;
587 if (!Buffer || !BufLen) {
588 SetLastError( ERROR_INVALID_PARAMETER );
596 INT remain = BufLen-1;
597 TSTR pDst = Buffer + remain;
602 if (!_add_DirEntryToPath(
this, pDst, remain ))
611 if (!_add_DirEntryToPath( pPrev, pDst, remain ))
616 _tcscpy( Buffer, pDst );
618 return (UINT)_tcslen( Buffer );
622 SetLastError( ERROR_INSUFFICIENT_BUFFER );
630 static bool __stdcall __count_Dirs(
PLIST_ENTRY Entry,
void* pData )
645 __count_Dirs(
this, &nDirs );
649 static bool __stdcall __count_Files(
PLIST_ENTRY Entry,
void* pData )
660 pDir->
SubDir->ForEach( __count_Files, pData );
667 __count_Files(
this, &nFiles );
671 static bool __stdcall __accumulate_FileSize(
PLIST_ENTRY Entry,
void* pData )
674 *(
PUINT64)pData += pFile->Size;
680 if (
Files)
Files->ForEach( __accumulate_FileSize, &size );
684 static bool __stdcall __accumulate_DirSize(
PLIST_ENTRY Entry,
void* pData )
695 __accumulate_DirSize(
this, &size );
703 memset( &fd, 0,
sizeof(fd) );
705 _tcscpy_s( fd.cFileName,
dimof(fd.cFileName), pzDir );
706 fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
723 Files->Append( Entry );
734 if (!ok) SetLastError( ERROR_INVALID_BLOCK );
744 static CSTR nextPathSep(
CSTR Path )
747 if (!pzEnd) pzEnd = _tcschr( Path,
SLASH );
748 if (!pzEnd) pzEnd = _tcschr( Path, 0 );
758 static TCHAR szBuf[ MAX_PATH ];
760 CSTR pzPath1, pzPath2, pzEnd1, pzEnd2;
761 UINT ccPath1, ccPath2;
764 pzPath1 = pzEnd1 = PathName1;
765 pzPath2 = pzEnd2 = PathName2;
769 pzEnd1 = nextPathSep( pzEnd1 );
770 pzEnd2 = nextPathSep( pzEnd2 );
771 ccPath1 = (UINT)
CharIndex( pzPath1, pzEnd1 );
772 ccPath2 = (UINT)
CharIndex( pzPath2, pzEnd2 );
774 if ((ccPath1 != ccPath2) || !ccPath1 || !ccPath2)
break;
775 if (_tcsnicmp( pzPath1, pzPath2, ccPath1 ) != 0)
break;
778 pzPath1 = pzEnd1;
if (*pzEnd1) pzEnd1++;
779 pzPath2 = pzEnd2;
if (*pzEnd2) pzEnd2++;
782 memset( szBuf, 0,
sizeof(szBuf) );
786 if (ccMatch >=
dimof(szBuf)) SetLastError( ERROR_BUFFER_OVERFLOW );
787 else if (!ccMatch) SetLastError( ERROR_NOT_FOUND );
788 else _tcsncpyz( szBuf, PathName1, ccMatch+1 );
#define HAVE_BITS(var, mask)
HANDLE CheckHandle(HANDLE Hnd)
PDirEntry __stdcall __new_DirEntry(LPWIN32_FIND_DATA pfd, PDirEntry pDir, PScanDirCtx pCtx)
bool(__stdcall * PFnDirAddAction)(PDirEntry pDir, LPWIN32_FIND_DATA pFD, PScanDirCtx pCtx)
TCHAR CurrentDir[MAX_PATH]
CSTR WithoutBackslash(CSTR PathName)
CSTR WithBackslash(CSTR PathName)
UINT Scan(PScanDirCtx pCtx)
UINT GetFullPath(TSTR Buff, UINT BufLen)
CSTR Rename(CSTR newName)
#define BEGIN_STRSAFE_OVERRIDE
DirEntry(LPWIN32_FIND_DATA pFd, PDirEntry pParent=NULL, PScanDirCtx pCtx=NULL)
bool IsSubdirName(CSTR Dir)
void __cdecl DPrint(int Level, CSTR Fmt,...)
CSTR DoneDirectory(CSTR prevDir)
struct _LIST_ENTRY * PLIST_ENTRY
bool(__stdcall * PFnFileAddAction)(PFileEntry pFile, LPWIN32_FIND_DATA pFD, PScanDirCtx pCtx)
static PFnFileAction DelAction
static bool __stdcall _delete(PLIST_ENTRY Entry, void *pData)
static bool __stdcall _dump(PLIST_ENTRY Entry, void *pData)
PDirEntry AddSubDir(CSTR pzDir, PScanDirCtx pCtx)
bool(__stdcall * PFnDirAction)(PDirEntry pDir, PScanDirCtx pCtx)
static PDirEntry ScanDir(CSTR BaseDir, UINT Depth=0, PDirEntry Parent=NULL, PUINT pCount=NULL, PScanDirCtx pCtx=NULL)
bool(__stdcall * PFnAbortScan)(PDirEntry pDir, PScanDirCtx pCtx)
PFileEntry(__stdcall *NewFileEntry)(LPWIN32_FIND_DATA pfd
CSTR SysErrorMsg(DWORD Err=0, TSTR Buf=NULL, UINT Length=0)
static bool __stdcall _delete(PLIST_ENTRY This, PVOID Ctx)
static bool __stdcall _delete(PLIST_ENTRY Entry, void *pData)
bool IsDir(LPWIN32_FIND_DATA pFd)
PDirEntry(__stdcall *NewDirEntry)(LPWIN32_FIND_DATA pfd
PFileEntry __stdcall NewFileEntry(LPWIN32_FIND_DATA pfd, PDirEntry pDir, PScanDirCtx pCtx)
bool(__stdcall * PFnFileAction)(PFileEntry pFile, PScanDirCtx pCtx)
static PFnAbortScan Abort
Debug and error handling support.
CSTR LongestCommonPath(CSTR PathName1, CSTR PathName2)
INT_PTR CharIndex(const chrType *Buffer, const chrType *Inside)
PDirEntry PScanDirCtx pCtx
FileEntry(LPWIN32_FIND_DATA pFd, PDirEntry Dir, PScanDirCtx pCtx=NULL)
bool GetWin32FileData(CSTR PathName, LPWIN32_FIND_DATA pFd)
FILETIME Now(eTimeType Domain)
#define InitializeListEntry(E)
UINT GetPathName(TSTR Buffer, UINT BufLen)
PDirEntry __stdcall NewDirEntry(LPWIN32_FIND_DATA pfd, PDirEntry pDir, PScanDirCtx pCtx)
PFileEntry AddFile(LPWIN32_FIND_DATA pFd, PScanDirCtx pCtx)
bool FindMoreFiles(HANDLE hFind, WIN32_FIND_DATA *Found, OPTIN BYTE nTries=1, OPTIN BYTE msWait=50)
unsigned __int64 * PUINT64
static PFnDirAction DelAction
bool GetFindData(LPWIN32_FIND_DATA pData)
#define END_STRSAFE_OVERRIDE
PFileEntry __stdcall __new_FileEntry(LPWIN32_FIND_DATA pfd, PDirEntry pDir, PScanDirCtx pCtx)
static bool __stdcall _dump(PLIST_ENTRY Entry, void *pData)
#define MAX_DIRECTORY_DEPTH
CSTR ChangeDirectory(CSTR Dir)
static PFnFileAddAction AddAction
static PFnDirAddAction AddAction