EnumDirectory

개발/연구 / / 2013. 9. 2. 14:32
typedef BOOL (CALLBACK* ENUMDIRPROC)
	( LPCTSTR pszCurrentPath
	, LPCTSTR pszTarget
	, LPWIN32_FIND_DATA lpWinFindData
	, LPVOID lpContext
	, BOOL bIsChangedFolder );

typedef struct _ENUMDIRINFO
{
	BOOL bNotifyDirChange;
	TCHAR szRootDir[MAX_PATH];
	TCHAR *szExtFilter;
	DWORD dwItemCount;
	LPVOID lpUserContext;
	ENUMDIRPROC pCbFEnumProc;
	
	_ENUMDIRINFO() 
	{ 
		memset(this, 0, sizeof(*this)); 
	}

} ENUMDIRINFO, *LPENUMDIRINFO;

BOOL WINAPI EnumDirectory(LPENUMDIRINFO pContext)
{
	BOOL bRet = TRUE;
	TCHAR szCurrentFolder[MAX_PATH];
	TCHAR szFindFirstFile[MAX_PATH];
	HANDLE hFindFirstFile = INVALID_HANDLE_VALUE;
	WIN32_FIND_DATA WinFindData;

	if ( pContext == NULL )
		return ERROR_INVALID_PARAMETER;

	if ( pContext->szRootDir == NULL )
		return ERROR_INVALID_PARAMETER;

	StringCchCopy(szCurrentFolder, MAX_PATH, pContext->szRootDir);

	if ( szCurrentFolder[_tcslen(szCurrentFolder)-1] != _T('\\') )
		StringCchCat(szCurrentFolder, MAX_PATH, _T("\\"));

	StringCchCopy(szFindFirstFile, MAX_PATH, szCurrentFolder);
	StringCchCat(szFindFirstFile, MAX_PATH, _T("*.*"));

	hFindFirstFile = FindFirstFile( szFindFirstFile, &WinFindData);
	if ( hFindFirstFile != INVALID_HANDLE_VALUE )
	{
		if ( pContext->bNotifyDirChange )
		{
			if ( pContext->pCbFEnumProc != NULL )
			{
				bRet = pContext->pCbFEnumProc( szCurrentFolder, szCurrentFolder, &WinFindData, pContext->lpUserContext, TRUE );
				if ( !bRet )
					return FALSE;
			}
		}

		do
		{
			if ( WinFindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY )
			{
				if ( _tcscmp(WinFindData.cFileName, _T(".")) == 0 || _tcscmp(WinFindData.cFileName, _T("..")) == 0)
				{
					continue;
				}
				else
				{
					ENUMDIRINFO tfnf = *pContext;
					tfnf.dwItemCount = 0;
					StringCchPrintf(tfnf.szRootDir, MAX_PATH, _T("%s%s"), szCurrentFolder, WinFindData.cFileName);
					bRet = EnumDirectory(&tfnf);
					pContext->dwItemCount += tfnf.dwItemCount;

					if ( !bRet )
						break;
				}
			}
			else
			{
				BOOL bBypass = FALSE;

				if ( pContext->szExtFilter != NULL )
				{
					TCHAR szExt[MAX_PATH];
					TCHAR szFilter[MAX_PATH];
					TCHAR* pszExt = _tcsrchr(WinFindData.cFileName, _T('.'));

					if ( pszExt++ != NULL )
					{
						StringCchCopy(szExt, MAX_PATH, pszExt);
						StringCchCopy(szFilter, MAX_PATH, pContext->szExtFilter);

						TCHAR* pszCurrentToken = szFilter;
						TCHAR* pszDelimiter = _tcschr(pszCurrentToken, _T('|'));
						size_t nSize = 0;

						_tcslwr(szExt);
						_tcslwr(szFilter);
						
						if ( pszDelimiter == NULL )
						{
							if ( _tcscmp(szExt, szFilter) == 0 )
								{}
							else
								continue;
						} 
						else do
						{
							if ( pszDelimiter == NULL )
								nSize = _tcslen(pszCurrentToken);
							else
								nSize = pszDelimiter - pszCurrentToken;

							if ( _tcsncmp(pszCurrentToken, szExt, nSize) == 0 )
								break;
							
							if ( pszDelimiter == NULL )
							{
								bBypass = TRUE;
								break;
							}
							else
							{
								pszCurrentToken = ++pszDelimiter;
								pszDelimiter = _tcschr(pszCurrentToken, _T('|'));
							}

						} while ( TRUE );
					}
					else
						continue;
				}

				if ( !bBypass )
				{
					TCHAR szFile[MAX_PATH];
					StringCchPrintf(szFile, MAX_PATH, _T("%s%s"), szCurrentFolder, WinFindData.cFileName);
					pContext->dwItemCount++;
					if  ( pContext->pCbFEnumProc != NULL )
					{
						bRet = pContext->pCbFEnumProc(szCurrentFolder, szFile , &WinFindData, pContext->lpUserContext, FALSE );
						if ( !bRet )
							break;
					}
				}
			}
		}
		while  ( FindNextFile(hFindFirstFile, &WinFindData) && bRet );
		FindClose(hFindFirstFile);
		return bRet;
	}
	else
	{
		// if enum failed (ex. access denied), print you want.
		// printf("Enum Failed %S LE:%d\n", szFindFirstFile, GetLastError());
		return TRUE;
	}
}
예제
BOOL CALLBACK SampleFunction(LPCTSTR pszCurrentPath
							, LPCTSTR pszTarget
							, LPWIN32_FIND_DATA lpWinFindData
							, LPVOID lpContext
							, BOOL bIsChangedFolder )
{
 	if ( bIsChangedFolder )
 		printf("Changed Folder : %S\n", pszCurrentPath);
 	else
	{
//		printf("Enum FullPathFile : %S\n", pszTarget);
//		printf("Enum FullPath : %S\n", pszCurrentPath);
		printf("Enum File : %S\n", lpWinFindData->cFileName);
	}

	if ( 0 )
		return FALSE;	// if stop enum, return FALSE
	else
		return TRUE;	// if continue enum, return TRUE
}

int _tmain(int argc, _TCHAR* argv[])
{
	setlocale(LC_ALL, "korean");

	ENUMDIRINFO m;
	m.bNotifyDirChange = FALSE;			// Not notify changes directories.
	m.pCbFEnumProc = SampleFunction;	// callback
	m.lpUserContext = NULL;				// user context addr
	m.szExtFilter = _T("png|jpg|bmp");			// filtering extentions.

	StringCchCopy(m.szRootDir, MAX_PATH, _T("C:\\"));	// set root directory for enum
	EnumDirectory(&m);									// call!

	printf("Total : %d\n", m.dwItemCount);
	return 0;
}
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기