You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
608 lines
19 KiB
608 lines
19 KiB
|
|
//+------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1993, Microsoft Corporation.
|
|
//
|
|
// File: FileEnum.cxx
|
|
//
|
|
// Contents: class encapsulating file enumeration, including a deep option
|
|
//
|
|
// Classes: CFileEnumeration
|
|
//
|
|
// History: Nov-93 DaveMont Created.
|
|
// Feb-98 BrunoSc CFileEnumerate::Init changed to avoid problems with
|
|
// files with german Umlaute.
|
|
//
|
|
//-------------------------------------------------------------------
|
|
#include "pch.h"
|
|
#include "t2.hxx"
|
|
#include "FileEnum.hxx"
|
|
#include <locale.h>
|
|
#include <wchar.h>
|
|
#if DBG
|
|
extern ULONG Debug;
|
|
#endif
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::CFileEnumerate, public
|
|
//
|
|
// Synopsis: initializes data members, constructor will not throw
|
|
//
|
|
// Arguments: IN [fdeep] - TRUE = go into sub-directories
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CFileEnumerate::CFileEnumerate(BOOL fdeep)
|
|
: _fdeep(fdeep),
|
|
_findeep(FALSE),
|
|
_froot(FALSE),
|
|
_fcannotaccess(FALSE),
|
|
_pcfe(NULL),
|
|
_pwfileposition(NULL),
|
|
_handle(INVALID_HANDLE_VALUE)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"CFileEnumerate ctor\n"))
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: Dtor, public
|
|
//
|
|
// Synopsis: closes handles
|
|
//
|
|
// Arguments: none
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
CFileEnumerate::~CFileEnumerate()
|
|
{
|
|
if (_handle != INVALID_HANDLE_VALUE)
|
|
FindClose(_handle);
|
|
ENUMERATE_RETURNS((stderr, L"CFileEnumerate dtor (%ws)\n", _wpath))
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::Init, public
|
|
//
|
|
// Synopsis: Init must be called before any other methods - this
|
|
// is not enforced. converts a ASCII file/path to a UNICODE
|
|
// file/path, and gets the first file in the enumeration
|
|
//
|
|
// Arguments: IN [filename] - the path/file to enumerate
|
|
// OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
/*
|
|
ULONG CFileEnumerate::Init(LPCWSTR filename, LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
// Initialize the file name
|
|
int iError = 0;
|
|
|
|
if (filename && (wcslen(filename) < MAX_PATH))
|
|
{
|
|
// make it wchar
|
|
WCHAR winfilename[MAX_PATH];
|
|
|
|
iError = MultiByteToWideChar( CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
(LPTSTR) filename,
|
|
-1,
|
|
winfilename,
|
|
wcslen( filename ) * 2
|
|
);
|
|
if (!iError)
|
|
{ // error has occured during translation
|
|
return( iError = GetLastError());
|
|
}
|
|
|
|
_pwfileposition = NULL;
|
|
|
|
|
|
// finish initialization
|
|
|
|
return(_ialize(winfilename, wfilename, fdir));
|
|
}
|
|
ENUMERATE_FAIL((stderr, "Init bad file name: %ld\n",ERROR_INVALID_NAME))
|
|
return(ERROR_INVALID_NAME);
|
|
}
|
|
*/
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::Init, public
|
|
//
|
|
// Synopsis: Same as previous, except takes UNICODE file/path as input
|
|
//
|
|
// Arguments: IN [filename] - the path/file to enumerate
|
|
// OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::Init(LPCWSTR filename, LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
// Initialize the file name
|
|
|
|
if (filename && (wcslen(filename) < MAX_PATH))
|
|
{
|
|
return(_ialize(filename, wfilename, fdir));
|
|
}
|
|
ENUMERATE_FAIL((stderr, L"Init bad file name: %ld\n",ERROR_INVALID_NAME))
|
|
return(ERROR_INVALID_NAME);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::_ialize, private
|
|
//
|
|
// Synopsis: finishes initialization and starts search for first file in
|
|
// the enumeration
|
|
//
|
|
// Arguments: OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::_ialize(LPCWSTR winfilename, LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"Init start, path = %ws\n", winfilename))
|
|
ULONG ret = ERROR_SUCCESS;
|
|
|
|
ENUMERATE_STAT((stderr, L"start path = %ws\n",winfilename))
|
|
|
|
// save the location of the filename or wildcards
|
|
|
|
ULONG cwcharcount;
|
|
|
|
if (!(cwcharcount = GetFullPathName((LPCTSTR)winfilename,
|
|
MAX_PATH,
|
|
(LPTSTR)_wpath,
|
|
(LPTSTR*)&_pwfileposition)))
|
|
{
|
|
return(ERROR_INVALID_NAME);
|
|
}
|
|
|
|
ENUMERATE_STAT((stderr, L"got full path name = %ws, filename = (%ws), total chars = %d\n",_wpath, _pwfileposition, cwcharcount))
|
|
|
|
// if the filepart (_pwfileposition) is NULL, then the name must end in a slash.
|
|
// add a *
|
|
|
|
if (NULL == _pwfileposition)
|
|
{
|
|
_pwfileposition = (LPWSTR) Add2Ptr(_wpath,wcslen(_wpath)*sizeof(WCHAR));
|
|
}
|
|
|
|
// save the filename/wildcards
|
|
|
|
wcscpy(_wwildcards, _pwfileposition);
|
|
|
|
ENUMERATE_EXTRA((stderr, L"wild cards = %ws\n",_wwildcards))
|
|
|
|
// if we are at a root (path ends in :\)
|
|
if ( (_wpath[wcslen(_wpath) - 1] == L'\\') &&
|
|
(wcslen(_wpath) > 1) &&
|
|
(_wpath[wcslen(_wpath) - 2] == L':') )
|
|
{
|
|
_wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
|
_wfd.cFileName[0] = L'\0';
|
|
*wfilename = _wpath;
|
|
*fdir = TRUE;
|
|
_froot = TRUE;
|
|
} else
|
|
{
|
|
// check to see if we can iterate through files
|
|
if ( (INVALID_HANDLE_VALUE == ( _handle = FindFirstFile((LPCTSTR)_wpath, &_wfd ) ) ) )
|
|
{
|
|
ret = GetLastError();
|
|
_fcannotaccess = (ERROR_ACCESS_DENIED == ret);
|
|
|
|
ENUMERATE_FAIL((stderr, L"find first returned: %ld\n",ret))
|
|
}
|
|
if (ERROR_SUCCESS == ret)
|
|
{ // reject . & .. filenames (go on to next file )
|
|
|
|
if ( (0 == _wcsicmp(_wfd.cFileName, L".")) ||
|
|
(0 == _wcsicmp(_wfd.cFileName, L"..")) )
|
|
{
|
|
ret = _NextLocal(wfilename,fdir);
|
|
} else
|
|
{
|
|
// return the current directory
|
|
|
|
if (_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
*fdir = TRUE;
|
|
else
|
|
*fdir = FALSE;
|
|
|
|
// add the filename to the path so the whole thing is returned
|
|
//_pwfileposition is pointer to postion of file in _wpath. _wpath is
|
|
//MAX_PATH long. MAX_PATH - (_pwfileposition - _wpath) is the length of
|
|
//buffer _pwfileposition
|
|
//
|
|
HRESULT hr = StringCchCopy((LPWSTR)_pwfileposition,MAX_PATH - (_pwfileposition- _wpath), (LPCWSTR )_wfd.cFileName);
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
*wfilename = _wpath;
|
|
}
|
|
}
|
|
|
|
ENUMERATE_STAT((stderr, L"next filename = %ws\n", *wfilename))
|
|
}
|
|
|
|
// if we are going deep and we did not find a file yet:
|
|
|
|
if ( _fdeep && ( ( ERROR_NO_MORE_FILES == ret ) ||
|
|
( ERROR_FILE_NOT_FOUND == ret ) ) )
|
|
{
|
|
if (_handle != INVALID_HANDLE_VALUE)
|
|
{
|
|
FindClose(_handle);
|
|
_handle = INVALID_HANDLE_VALUE;
|
|
}
|
|
ret = _InitDir(wfilename, fdir);
|
|
}
|
|
|
|
ENUMERATE_RETURNS((stderr, L"Init returning = %ws(%ld)\n\n", *wfilename, ret))
|
|
return(ret);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::Next, public
|
|
//
|
|
// Synopsis: finds the next file in the enumeration
|
|
//
|
|
// Arguments: OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::Next(LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"Next start, path = %ws\n", _wpath))
|
|
ULONG ret = ERROR_NO_MORE_FILES;
|
|
|
|
// if we failed to initialize with an ERROR_ACCESS_DENIED, then exit
|
|
if (_fcannotaccess)
|
|
return(ERROR_NO_MORE_FILES);
|
|
|
|
// if we are not in deep
|
|
|
|
if (!_findeep)
|
|
{
|
|
if (!_froot)
|
|
ret = _NextLocal(wfilename, fdir);
|
|
|
|
// if we ran out of files and we are going deep:
|
|
|
|
if ( _fdeep &&
|
|
( ( ERROR_NO_MORE_FILES == ret ) ||
|
|
( ERROR_FILE_NOT_FOUND == ret ) || _froot ) )
|
|
{
|
|
if (_handle != INVALID_HANDLE_VALUE)
|
|
{
|
|
FindClose(_handle);
|
|
_handle = INVALID_HANDLE_VALUE;
|
|
}
|
|
ret = _InitDir(wfilename, fdir);
|
|
_froot = FALSE; // (we are past the root now)
|
|
}
|
|
|
|
} else
|
|
{
|
|
// if we are already down a directory (and in deep)
|
|
|
|
if (_pcfe)
|
|
{
|
|
if (ERROR_SUCCESS != (ret = _pcfe->Next(wfilename, fdir)))
|
|
{
|
|
if (ERROR_ACCESS_DENIED != ret)
|
|
{
|
|
delete _pcfe;
|
|
_pcfe = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// we need to go to the next directory in the current dir
|
|
|
|
if (ERROR_NO_MORE_FILES == ret)
|
|
{
|
|
ret = _NextDir(wfilename, fdir);
|
|
}
|
|
}
|
|
ENUMERATE_RETURNS((stderr, L"Next returning = %ws(%ld)\n\n", *wfilename, ret))
|
|
return(ret);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::_NextLocal, private
|
|
//
|
|
// Synopsis: searchs for the next file in the current directory
|
|
//
|
|
// Arguments: OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::_NextLocal(LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"_NextLocal start, path = %ws\n", _wpath))
|
|
ULONG ret = ERROR_SUCCESS;
|
|
|
|
// ensure that we have a valid handle for a findnextfile
|
|
|
|
if (INVALID_HANDLE_VALUE == _handle)
|
|
{
|
|
ret = ERROR_INVALID_HANDLE;
|
|
} else
|
|
{
|
|
do
|
|
{
|
|
if (!FindNextFile(_handle, &_wfd))
|
|
{
|
|
ret = GetLastError();
|
|
ENUMERATE_FAIL((stderr, L"find next returned: %ld\n",ret))
|
|
} else
|
|
ret = ERROR_SUCCESS;
|
|
}
|
|
while ( (ERROR_SUCCESS == ret) &&
|
|
( (0 == _wcsicmp(_wfd.cFileName, L".")) ||
|
|
(0 == _wcsicmp(_wfd.cFileName, L"..")) ) );
|
|
|
|
|
|
// if we found a file
|
|
|
|
if (ERROR_SUCCESS == ret)
|
|
{
|
|
// return the directory attrib.
|
|
|
|
if (_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
*fdir = TRUE;
|
|
else
|
|
*fdir = FALSE;
|
|
|
|
//_pwfileposition is pointer to postion of file in _wpath. _wpath is
|
|
//MAX_PATH long. MAX_PATH - (_pwfileposition - _wpath) is the length of
|
|
//buffer _pwfileposition
|
|
//
|
|
HRESULT hr = StringCchCopy((LPWSTR)_pwfileposition,
|
|
MAX_PATH - (_pwfileposition- _wpath),
|
|
(const wchar_t*)_wfd.cFileName);
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
|
|
*wfilename = _wpath;
|
|
|
|
ENUMERATE_STAT((stderr, L"next filename = %ws\n", *wfilename))
|
|
}
|
|
}
|
|
ENUMERATE_RETURNS((stderr, L"_NextLocal returning = %ws(%ld)\n", *wfilename, ret))
|
|
|
|
return(ret);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::_InitDir, private
|
|
//
|
|
// Synopsis: (only called if going deep)
|
|
// goes down a directory (and thus causing a new CFileEnumerator
|
|
// to be created, or re-initializies
|
|
//
|
|
// Arguments: OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::_InitDir(LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"_InitDir start, path = %ws\n", _wpath))
|
|
ULONG ret = ERROR_SUCCESS;
|
|
|
|
// check and see if a directory was entered as the filename
|
|
|
|
if ( (0 == _wcsicmp( _wwildcards, _wfd.cFileName)) &&
|
|
(_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
|
|
{
|
|
ENUMERATE_EXTRA((stderr, L"first file matched directory = %ws\n", _wpath))
|
|
_pwfileposition += wcslen((LPWSTR)_wfd.cFileName);
|
|
|
|
//_pwfileposition is pointer to postion of file in _wpath. _wpath is
|
|
//MAX_PATH long. MAX_PATH - (_pwfileposition - _wpath) is the length of
|
|
//buffer _pwfileposition
|
|
//
|
|
HRESULT hr = StringCchCopy((LPWSTR)_pwfileposition,
|
|
MAX_PATH - (_pwfileposition- _wpath),
|
|
L"\\*.*");
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
_pwfileposition++;
|
|
wcscpy(_wwildcards, L"*.*");
|
|
ENUMERATE_EXTRA((stderr, L" path = %ws\n",_wpath))
|
|
ENUMERATE_EXTRA((stderr, L"wild cards = %ws\n",_wwildcards))
|
|
|
|
WCHAR winfilename[MAX_PATH] = L"";
|
|
hr = StringCchCopy((LPWSTR)winfilename,
|
|
MAX_PATH,
|
|
_wpath);
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
|
|
ret = _ialize(winfilename, wfilename, fdir);
|
|
} else
|
|
{
|
|
|
|
// we are in deep
|
|
|
|
_findeep = TRUE;
|
|
|
|
// search thru all directories
|
|
//_pwfileposition is pointer to postion of file in _wpath. _wpath is
|
|
//MAX_PATH long. MAX_PATH - (_pwfileposition - _wpath) is the length of
|
|
//buffer _pwfileposition
|
|
//
|
|
HRESULT hr = StringCchCopy((LPWSTR)_pwfileposition,
|
|
MAX_PATH - (_pwfileposition- _wpath),
|
|
L"*.*");
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
if (INVALID_HANDLE_VALUE == ( _handle = FindFirstFile((LPCTSTR)_wpath, &_wfd) ))
|
|
{
|
|
ret = GetLastError();
|
|
ENUMERATE_FAIL((stderr, L"find first (dir) returned: %ld\n",ret))
|
|
} else
|
|
{
|
|
if ( !(_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
|
(0 == wcscmp(( LPCWSTR)_wfd.cFileName, L".")) ||
|
|
(0 == wcscmp(( LPCWSTR)_wfd.cFileName, L"..")) )
|
|
{
|
|
ret = _NextDir(wfilename, fdir);
|
|
} else
|
|
{
|
|
// if we have a sub directory, go down it
|
|
|
|
ret = _DownDir(wfilename, fdir);
|
|
|
|
// if we found nothing in that first sub directory, go the the next one
|
|
|
|
if ( (ERROR_NO_MORE_FILES == ret ) ||
|
|
(ERROR_FILE_NOT_FOUND == ret ) )
|
|
{
|
|
ret = _NextDir(wfilename, fdir);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ENUMERATE_RETURNS((stderr, L"_InitDir returning = %ws(%ld)\n", *wfilename, ret))
|
|
|
|
return(ret);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::_NextDir, private
|
|
//
|
|
// Synopsis: (only called if going deep)
|
|
// finds the next sub-directory from the current directory,
|
|
// and then goes down into that directory
|
|
//
|
|
// Arguments: OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::_NextDir(LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"_NextDir start, path = %ws\n", _wpath))
|
|
ULONG ret = ERROR_SUCCESS;
|
|
|
|
// skip the . & .. & files we cannot access
|
|
|
|
if (INVALID_HANDLE_VALUE == _handle)
|
|
{
|
|
ret = ERROR_INVALID_HANDLE;
|
|
} else
|
|
{
|
|
do
|
|
{
|
|
do
|
|
{
|
|
if (!FindNextFile(_handle, &_wfd))
|
|
{
|
|
ret = GetLastError();
|
|
ENUMERATE_FAIL((stderr, L"find next returned: %ld\n",ret))
|
|
} else
|
|
ret = ERROR_SUCCESS;
|
|
}
|
|
while ( (ERROR_SUCCESS == ret) &&
|
|
( !(_wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
|
(0 == wcscmp(( LPCWSTR )_wfd.cFileName, L".")) ||
|
|
(0 == wcscmp(( LPCWSTR )_wfd.cFileName, L"..")) ) );
|
|
|
|
// if we found a directory
|
|
|
|
if (ERROR_SUCCESS == ret)
|
|
{
|
|
ret = _DownDir(wfilename, fdir);
|
|
} else
|
|
{
|
|
// out of subdirectories to search, break out of the loop
|
|
break;
|
|
}
|
|
}
|
|
while (( ERROR_NO_MORE_FILES == ret) || (ERROR_FILE_NOT_FOUND == ret));
|
|
}
|
|
ENUMERATE_RETURNS((stderr, L"_NextDir returning = %ws(%ld)\n", *wfilename, ret))
|
|
|
|
return(ret);
|
|
}
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CFileEnumerate::_DownDir, private
|
|
//
|
|
// Synopsis: (only called if going deep)
|
|
// creates a new CFileEnumerator for a sub-directory
|
|
//
|
|
// Arguments: OUT [wfilename] - first file in the enumeration
|
|
// OUT [fdir] - TRUE = returned file is a directory
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ULONG CFileEnumerate::_DownDir(LPWSTR *wfilename, BOOL *fdir)
|
|
{
|
|
ENUMERATE_RETURNS((stderr, L"_DownDir start, path = %ws\n", _wpath))
|
|
ULONG ret;
|
|
|
|
// make a new file enumerator class (this one) We should only go down
|
|
// 8 directories at most.
|
|
|
|
_pcfe = new CFileEnumerate(_fdeep);
|
|
if ( NULL == _pcfe )
|
|
{
|
|
ret = GetLastError () ;
|
|
ENUMERATE_RETURNS((stderr, L"_DownDir returning = %ws(%ld)\n", *wfilename, ret ))
|
|
return(ret);
|
|
}
|
|
|
|
// add the wildcards to the end of the directory we are going down
|
|
|
|
//_pwfileposition is pointer to postion of file in _wpath. _wpath is
|
|
//MAX_PATH long. MAX_PATH - (_pwfileposition - _wpath) is the length of
|
|
//buffer _pwfileposition
|
|
//
|
|
HRESULT hr = StringCchCopy((LPWSTR)_pwfileposition,
|
|
MAX_PATH - (_pwfileposition- _wpath),
|
|
( const wchar_t *)_wfd.cFileName);
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
hr = StringCchCat(_wpath,MAX_PATH,L"\\");
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
hr = StringCchCat(_wpath,MAX_PATH, _wwildcards);
|
|
if(FAILED(hr))
|
|
{
|
|
return HRESULT_CODE(hr);
|
|
}
|
|
|
|
// start it up and see if we find a match
|
|
|
|
if (ERROR_SUCCESS != (ret = _pcfe->Init(_wpath, wfilename, fdir)))
|
|
{
|
|
if (ERROR_ACCESS_DENIED != ret)
|
|
{
|
|
delete _pcfe;
|
|
_pcfe = NULL;
|
|
}
|
|
}
|
|
ENUMERATE_RETURNS((stderr, L"_DownDir returning = %ws(%ld)\n", *wfilename, ret))
|
|
return(ret);
|
|
}
|
|
|