找到文件

作者:陆麟
转载请征得作者同意.
1999.12.24



很就以前的东西了.感觉幼稚.但是当时到是贴到了CFIDO上当作递归算法在WIN32里的一个用法.这是个DLL的版本.纯SDK版.

/*FindFile.cpp Written by Lu Lin.Feb.28.1999
 *The function seachs all HDDs,CDROMs(if available)
 *to find the file given.
 *Entry: FindFile(IN LPSTR name,OUT LPSTR buffer);
 *name:
 * a pointer to the filename you want to find
 *buffer:
 * a pointer to the buffer to retrive full path
 * of the file.
 *Return True if find file successfuly and fulfill
 *buffer with full path to the file.
 *
 *Modify1:Feb.28.1999
 *Added check for name already with full path name.
 *
 *Modify2:Mar.1.1999
 *Multithread Version using Critical Section technology.
 *
 *Modify3:Mar.11.1999
 *Max re-entering check added for dead circulate avoiding.
 *
 *Modify4:May.16.1999
 *Shell API "PathAddBackslash()" used instead of phrase "if{}"
*/
#include <windows.h>
#include <string.h>
#include <Shlwapi.h>
CRITICAL_SECTION critical;
static int enter_count=0;
static int err_flag=0;
BOOL FindFile1(LPSTR name,LPSTR buffer)
{
 BOOL find=false;
 HANDLE find_handle=0;
 char current_dir[MAX_PATH]={0};
 char set_dir[MAX_PATH]={0};
 WIN32_FIND_DATA result;
 ZeroMemory(&result,sizeof(result));
 if (++enter_count>260)
 {
  err_flag=1;
  return false;
 }
 find_handle=FindFirstFile("*.*",&result);
 if (find_handle==INVALID_HANDLE_VALUE)
 {
  enter_count--;
  return false;
 };
 if ((result.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)&&
  strcmp(result.cFileName,".")&&strcmp(result.cFileName,".."))
 {
  GetCurrentDirectory(MAX_PATH,current_dir);
  PathAddBackslash(current_dir);
  strcpy(set_dir,current_dir);
  strcat(set_dir,result.cFileName);
  SetCurrentDirectory(set_dir);
  if (FindFile1(name,buffer))
  {
   FindClose(find_handle);
   return true;
  }
  SetCurrentDirectory(current_dir);
  if (err_flag) return false;
 }
 if (stricmp(name,result.cFileName)==0)
 {
  GetCurrentDirectory(MAX_PATH,buffer);
  PathAddBackslash(buffer);
  strcat(buffer,result.cFileName);
  FindClose(find_handle);
  enter_count=0;
  return true;
 }
 while (FindNextFile(find_handle,&result))
 {
  if ((result.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)&&
   strcmp(result.cFileName,".")&&strcmp(result.cFileName,".."))
  {
   GetCurrentDirectory(MAX_PATH,current_dir);
   PathAddBackslash(current_dir);
   strcpy(set_dir,current_dir);
   strcat(set_dir,result.cFileName);
   SetCurrentDirectory(set_dir);
   if (FindFile1(name,buffer)) {
    FindClose(find_handle);
    return true;
   }
   SetCurrentDirectory(current_dir);
   if (err_flag) return false;
  }
  if (stricmp(name,result.cFileName)==0)
  {
   GetCurrentDirectory(MAX_PATH,buffer);
   PathAddBackslash(buffer);
   strcat(buffer,result.cFileName);
   FindClose(find_handle);
   enter_count=0;
   return true;
  }
 }
 FindClose(find_handle);
 --enter_count;
 return false;
}

BOOL _declspec(dllexport) _stdcall FindFile(LPSTR name,LPSTR buffer)
{
 BOOL find=false;
 char drive[256];
 char current_path[MAX_PATH];
 char *p=drive;
 WIN32_FIND_DATA result;
 if (FindFirstFile(name,&result)!=INVALID_HANDLE_VALUE)
 {
  strcpy(buffer,name);
  return true;
 };
 ZeroMemory(drive,256);
 GetLogicalDriveStrings(256,drive);
 EnterCriticalSection(&critical);
 GetCurrentDirectory(MAX_PATH,current_path);
 while ((!*p==NULL)&&(!find))
 {
  if ((*p=='a')||(*p=='b'))
  {
   p+=strlen(p)+sizeof(TCHAR);
  }
  enter_count=0;
  err_flag=0;
  SetCurrentDirectory(p);
  if (FindFile1(name,buffer))
  {
   SetCurrentDirectory(current_path);
   LeaveCriticalSection(&critical);
   return true;
  }
  p+=strlen(p)+sizeof(TCHAR);
 }
 SetCurrentDirectory(current_path);
 LeaveCriticalSection(&critical);
 return false;
}
BOOL WINAPI DllMain(HANDLE,DWORD reason,LPVOID)
{
 switch (reason)
 {
 case DLL_PROCESS_ATTACH:
  InitializeCriticalSection(&critical);
  break;
 case DLL_THREAD_ATTACH:
  break;
 case DLL_THREAD_DETACH:
  break;
 case DLL_PROCESS_DETACH:
  break;
 }
 return true;
}