/*++ Copyright (c) 1997 Microsoft Corporation Module Name: enumfile.c Abstract: File enumater, given a root direcory, it will enumerates all file under this directory. Author: Xiaofeng Zang (xiaoz) 08-Oct-2001 Created Revision History: --*/ #include "StdAfx.h" #include "clmt.h" BOOL EnumBranch ( HANDLE hFile, LPWIN32_FIND_DATA pfd, LPTSTR szCurDir, LPTSTR szExt, FILEENUMPROC lpEnumProc ) { TCHAR *p; BOOL bDone; TCHAR szSubDir[3*MAX_PATH+3],*lpSubDir; HANDLE hFileSub; TCHAR szFullPath[3*MAX_PATH+3],*lpFullPath; HRESULT hr; size_t cchSubDirLen,cchFullPathLen; BOOL bExit; BOOL bReturn = TRUE; if (!pfd || !szCurDir) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } bExit = FALSE; do { if(pfd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(0 == lstrcmp(pfd->cFileName , TEXT("."))) { continue; } if(0 == lstrcmp(pfd->cFileName , TEXT(".."))) { continue; } //we statically allocated szSubDir 3*MAX_PATH //but limit the len use to 2*MAX_PATH, so that //later on ConcatenatePaths a file name will not fail hr = StringCchCopy(szSubDir, 2*(MAX_PATH+1),szCurDir); if (SUCCEEDED(hr)) { cchSubDirLen = 3*(MAX_PATH+1); lpSubDir = szSubDir; } else { if (HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER) { cchSubDirLen = lstrlen(szCurDir)+1 + MAX_PATH + 1; lpSubDir = malloc(cchSubDirLen * sizeof(TCHAR)); if (!lpSubDir) { bExit = TRUE; SetLastError(ERROR_NOT_ENOUGH_MEMORY); bReturn = FALSE; goto Exit1; } if (FAILED(StringCchCopy(lpSubDir, cchSubDirLen,szCurDir))) { bExit = TRUE; SetLastError(ERROR_NOT_ENOUGH_MEMORY); bReturn = FALSE; goto Exit1; } } else { bExit = TRUE; goto Exit1; } } ConcatenatePaths(lpSubDir, pfd->cFileName ,cchSubDirLen); p = lpSubDir + lstrlen(lpSubDir); ConcatenatePaths(lpSubDir, TEXT("*.*"),cchSubDirLen); hFileSub = FindFirstFile(lpSubDir, pfd); if(INVALID_HANDLE_VALUE == hFileSub) { continue; } *p = TEXT('\0'); if (!EnumBranch(hFileSub, pfd, lpSubDir,szExt,lpEnumProc)) { bReturn = FALSE; bExit = TRUE; } FindClose(hFileSub); Exit1: if (lpSubDir && (lpSubDir != szSubDir)) { free(lpSubDir); lpSubDir = NULL; } } else if(pfd->cFileName) { if (lstrlen(pfd->cFileName) > lstrlen(szExt)) { p = pfd->cFileName + (lstrlen(pfd->cFileName) - lstrlen(szExt)); if (!MyStrCmpI(p,szExt)) { hr = StringCchCopy(szFullPath, 2*(MAX_PATH+1),szCurDir); if (SUCCEEDED(hr)) { cchFullPathLen = 3*(MAX_PATH+1); lpFullPath = szFullPath; } else { if (HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER) { cchFullPathLen = lstrlen(szCurDir)+1 + MAX_PATH + 1; lpFullPath = malloc(cchFullPathLen * sizeof(TCHAR)); if (!lpFullPath) { bExit = TRUE; SetLastError(ERROR_NOT_ENOUGH_MEMORY); bReturn = FALSE; goto Exit2; } if (FAILED(StringCchCopy(lpFullPath, cchFullPathLen,szCurDir))) { bExit = TRUE; SetLastError(ERROR_NOT_ENOUGH_MEMORY); bReturn = FALSE; goto Exit2; } } else { bExit = TRUE; goto Exit2; } } ConcatenatePaths(lpFullPath, pfd->cFileName,cchFullPathLen); if (!lpEnumProc(szFullPath)) { bReturn = FALSE; bExit = TRUE; } Exit2: if (lpFullPath && (lpFullPath != szFullPath)) { free(lpFullPath); lpFullPath = NULL; } } } } } while(FindNextFile( hFile, pfd) && !bExit); return (bReturn); } BOOL MyEnumFiles ( LPTSTR szRoot, LPTSTR szExt, FILEENUMPROC lpEnumProc ) { HANDLE hFile; WIN32_FIND_DATA fd; TCHAR *szSubDir; TCHAR *p; size_t cbRoot; BOOL bRet = FALSE; if (!szRoot || !lpEnumProc) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } cbRoot = lstrlen(szRoot); szSubDir = malloc( (cbRoot+MAX_PATH) * sizeof(TCHAR)); if (!szSubDir) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto Cleanup; } if (FAILED(StringCchCopy(szSubDir, cbRoot+MAX_PATH, szRoot))) { SetLastError(ERROR_INVALID_PARAMETER); goto Cleanup; } p = szSubDir + lstrlen(szSubDir); ConcatenatePaths(szSubDir, TEXT("\\*.*"),cbRoot+MAX_PATH); hFile = FindFirstFile(szSubDir, &fd); if(INVALID_HANDLE_VALUE == hFile) { goto Cleanup; } *p = TEXT('\0'); EnumBranch(hFile, &fd, szSubDir,szExt, lpEnumProc); FindClose(hFile); bRet = TRUE; Cleanup: if (szSubDir) { free(szSubDir); } return bRet; }