作者:陆麟
转载请征得作者同意.
1999.12.24
/*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;
}