|
|
/*++
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:
<alias> <date> <comments>
--*/
#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; }
|