Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

927 lines
28 KiB

#include "cmd.h"
extern TCHAR CurDrvDir[] ;
extern TCHAR *SaveDir ;
extern DWORD DosErr ;
extern BOOL CtrlCSeen;
PTCHAR SetWildCards( PTCHAR, BOOLEAN );
BOOLEAN IsFATDrive( PTCHAR );
VOID FreeStr( PTCHAR );
VOID SortFileList( PFS, PSORTDESC, ULONG);
BOOLEAN FindFirstNt( PTCHAR, PWIN32_FIND_DATA, PHANDLE );
BOOLEAN FindNextNt ( PWIN32_FIND_DATA, HANDLE );
STATUS SetSearchPath ( PFS, PPATDSC, PTCHAR, ULONG);
STATUS
BuildFSFromPatterns (
IN PDRP pdpr,
IN BOOLEAN fAddWild,
OUT PFS * ppfs
)
{
struct cpyinfo * pcisFile;
TCHAR szCurDir[MAX_PATH + 2];
TCHAR szFilePattern[MAX_PATH + 2];
PTCHAR pszPatternCur;
PPATDSC ppatdscCur;
PFS pfsFirst;
PFS pfsCur;
ULONG cbPath;
BOOLEAN fFatDrive;
ULONG i;
PTCHAR pszT;
//
// determine FAT drive from original pattern.
// Used in several places to control name format etc.
//
DosErr = 0;
//
// Run through each pattern making all sorts of FAT etc. specific
// changes to it and creating the directory list for it. Then
// combine groups of patterns into common directories and recurse
// for each directory group.
//
*ppfs = pfsFirst = (PFS)gmkstr(sizeof(FS));
pfsFirst->pfsNext = NULL;
pfsFirst->pszDir = NULL;
pfsCur = pfsFirst;
pfsCur->cpatdsc = 1;
for(i = 1, ppatdscCur = &(pdpr->patdscFirst);
i <= pdpr->cpatdsc;
i++, ppatdscCur = ppatdscCur->ppatdscNext) {
pszPatternCur = ppatdscCur->pszPattern;
if (!(fFatDrive = IsFATDrive(pszPatternCur)) && DosErr) {
//
// Error in determining file system type so get out.
//
PutStdErr(DosErr, NOARGS);
return( FAILURE );
}
ppatdscCur->fIsFat = fFatDrive;
//
// Do any alterations that require wild cards for searching
// such as change .xxx to *.xxx for FAT file system requests
//
// Note that if the return values is a different buffer then
// the input the input will be freed when we are done with the
// Dir command.
//
//
// Note that though SetWildCards will allocate heap for the
// modified pattern this will get freed when FreeStack is
// called at the end of the Dir call.
//
// An out of memory is the only reason to fail and we would not
// return from that but go through the abort call in gmstr
//
if (fAddWild) {
pszT = SetWildCards(pszPatternCur, fFatDrive);
FreeStr(pszPatternCur);
pszPatternCur = pszT;
}
//
// Convert the current pattern into a path and file part
//
// Save the current directory in SaveDir, change to new directory
// and parse pattern into a copy information structure. This also
// converts pszPatternCur into the current directory which also produces
// a fully qualified name.
//
DosErr = 0;
DEBUG((ICGRP, DILVL, "PrintPattern pattern `%ws'", pszPatternCur));
if ((pcisFile = SetFsSetSaveDir(pszPatternCur)) == (struct cpyinfo *) FAILURE) {
//
// DosErr is set in SetFs.. from GetLastError
//
// BUGBUG map to DIR error code
//
PutStdErr(DosErr, NOARGS);
return( FAILURE );
}
DEBUG((ICGRP, DILVL, "PrintPattern fullname `%ws'", pcisFile->fnptr));
//
// CurDrvDir ends in '\' (old code also and a DOT but I do not
// understand where this would come from I will leave it in for now.
// Remove the final '\' from a copy of the current directory and
// print that version out.
//
mystrcpy(szCurDir,CurDrvDir);
//
// SetFsSetSaveDir changes directories as a side effect. Since all
// work will be in fully qualified paths we do not need this. Also
// since we will change directories for each pattern that is examined
// we will force the directory back to the original each time.
//
// This can not be done until after all use of the current directory
// is made.
//
if (SaveDir) {
mystrcpy(CurDrvDir,SaveDir);
SaveDir = NULL;
}
DEBUG((ICGRP, DILVL, "PrintPattern Current Drive `%ws'", szCurDir));
cbPath = mystrlen(szCurDir);
//
// BUGBUG this is BS. it will not work for
// dbcs. It is assuming character widths.
//
if (cbPath > 3) {
if (fFatDrive && *penulc(szCurDir) == DOT) {
szCurDir[cbPath-2] = NULLC;
} else {
szCurDir[cbPath-1] = NULLC;
}
}
//
// If no room for filename then return
//
if (cbPath >= MAX_PATH -1) {
PutStdErr(ERROR_FILE_NOT_FOUND, NOARGS);
return(FAILURE);
}
//
// Add filename and possibly ext to szSearchPath
// if no filename or ext, use "*"
//
// If pattern was just extension the SetWildCard had already
// added * to front of extension.
//
if (*(pcisFile->fnptr) == NULLC) {
mystrcpy(szFilePattern, TEXT("*"));
} else {
mystrcpy(szFilePattern, pcisFile->fnptr);
}
DEBUG((ICGRP, DILVL, "DIR:PrintPattern Pattern to search for `%ws'", szFilePattern));
//
// Is name too long
//
if ((cbPath + mystrlen(szFilePattern) + 1) > MAX_PATH ) {
PutStdErr(ERROR_BUFFER_OVERFLOW, NOARGS);
return( FAILURE );
} else {
//
// If this is a FAT drive and there was a filename with
// no extension then add '.*' (and there is room)
//
if (*pcisFile->fnptr && (!pcisFile->extptr || !*pcisFile->extptr) &&
((mystrlen(szFilePattern) + 2) < MAX_PATH) && fFatDrive && fAddWild) {
mystrcat(szFilePattern, TEXT(".*")) ;
}
}
//
// ppatdscCur->pszPattern will be freed at end of command when everything
// else is freed.
//
ppatdscCur->pszPattern = (PTCHAR)gmkstr(_tcslen(szFilePattern)*sizeof(TCHAR) + sizeof(TCHAR));
mystrcpy(ppatdscCur->pszPattern, szFilePattern);
ppatdscCur->pszDir = (PTCHAR)gmkstr(_tcslen(szCurDir)*sizeof(TCHAR) + sizeof(TCHAR));
mystrcpy(ppatdscCur->pszDir, szCurDir);
if (pfsCur->pszDir) {
//
// changing directories so change directory grouping.
//
if (_tcsicmp(pfsCur->pszDir, ppatdscCur->pszDir)) {
pfsCur->pfsNext = (PFS)gmkstr(sizeof(FS));
pfsCur = pfsCur->pfsNext;
pfsCur->pszDir = (PTCHAR)gmkstr(_tcslen(ppatdscCur->pszDir)*sizeof(TCHAR) + sizeof(TCHAR));
mystrcpy(pfsCur->pszDir, ppatdscCur->pszDir);
pfsCur->pfsNext = NULL;
pfsCur->fIsFat = ppatdscCur->fIsFat;
pfsCur->ppatdsc = ppatdscCur;
pfsCur->cpatdsc = 1;
} else {
pfsCur->cpatdsc++;
}
} else {
//
// Have not filled in current fs descriptor yet.
//
pfsCur->pszDir = (PTCHAR)gmkstr(_tcslen(ppatdscCur->pszDir)*sizeof(TCHAR) + 2*sizeof(TCHAR));
mystrcpy(pfsCur->pszDir, ppatdscCur->pszDir);
pfsCur->fIsFat = ppatdscCur->fIsFat;
pfsCur->ppatdsc = ppatdscCur;
}
} // while for running through pattern list
return( SUCCESS );
}
STATUS
DirWalkAndProcess(
IN STATUS (* pfctProcessFiles) ( PSCREEN, PULONG, PLARGE_INTEGER, ULONG, ULONG, PFS ),
IN STATUS (* pfctProcessDir) (PFS, PULONG),
IN PSCREEN pscr,
OUT PULONG pcffTotal,
OUT PLARGE_INTEGER pcbFileTotal,
IN PFS pfsFiles,
IN PDRP pdpr,
IN BOOLEAN fMustExist,
IN BOOLEAN (*pfctPrintErr) (STATUS, PTCHAR)
)
/*++
Routine Description:
Arguments:
Return Value:
Return:
--*/
{
FS fsDirs;
FS fsFilesNext;
ULONG irgpffDirsCur;
TCHAR szDirNew[MAX_PATH + 2];
PTCHAR pszDirName;
BOOLEAN fFatDrive;
BOOLEAN fRecurse;
STATUS rc;
STATUS (* pfctProcessFilesForGetFS) ( PSCREEN, ULONG, ULONG, PLARGE_INTEGER, PFS, PFF );
//
// Turn the file name pattern into a list of files pointed to
// by fsnode. The list of files will be qualified by rgfAttribs
// which come from the attribute switch on the command line.
//
// After getting the file list then sort it and finally print
// it out in the specified format.
//
// Last free the file list since we don't need it.
//
// Keep the directory since we have to use it to get the
// file list.
//
// Check if there are more directories.
//
if (CtrlCSeen) {
return( FAILURE );
}
fFatDrive = pfsFiles->fIsFat;
fRecurse = (BOOLEAN)(pdpr->rgfSwitchs & RECURSESWITCH);
//
// Even though there may be no function to process file list
// still fetch to determine of any patterns qualify. In the case
// of rmdir we are not to process of there is no pattern match
// at the top level.
//
pfctProcessFilesForGetFS = NULL;
if ((pdpr->rgfSwitchs & DELPROCESSEARLY)) {
pfctProcessFilesForGetFS = EraseFile;
}
else
if (!(pdpr->rgfSwitchs & (RECURSESWITCH | WIDEFORMATSWITCH | SORTDOWNFORMATSWITCH | SORTSWITCH)))
pfctProcessFilesForGetFS = DisplayFile;
rc = GetFS(pfsFiles,
pdpr->rgfSwitchs,
pdpr->rgfAttribs,
pdpr->rgfAttribsOnOff,
pdpr->dwTimeType,
pscr,
pfctPrintErr,
pfctProcessFilesForGetFS
);
if (pfctProcessFilesForGetFS) {
*pcffTotal += pfsFiles->cffDisplayed;
}
if (rc != SUCCESS) {
if ((rc != ERROR_FILE_NOT_FOUND) && (rc != ERROR_NO_MORE_FILES)) {
// PutStdErr(rc, NOARGS);
// pfctPrintErr(rc, NULL);
return( rc );
}
//
// GetFS returns this only if not files were found
// at all.
//
if (rc == ERROR_FILE_NOT_FOUND) {
//
// If we are not recursing then do not report error and
// continue down tree. If not report error back to caller.
// If are recursing and files must exist at top level then
// removing all printing for cases where we do not
// continue down tree.
//
if ((!fRecurse) || (fMustExist) ) {
return( rc );
}
}
}
//
// Do not bother to sort if no function to process list
//
if (pfctProcessFiles) {
SortFileList(pfsFiles, pdpr->rgsrtdsc, pdpr->dwTimeType);
if ((rc == SUCCESS) || !fRecurse) {
CHECKSTATUS(pfctProcessFiles(pscr,
pcffTotal,
pcbFileTotal,
pdpr->rgfSwitchs,
pdpr->dwTimeType,
pfsFiles));
}
}
//
// Free up buffer holding files since we no longer need these.
// Move on to determine if we needed to go to another directory
//
FreeStr((PTCHAR)(pfsFiles->pff));
pfsFiles->pff = NULL;
if (CtrlCSeen) {
return( FAILURE );
}
if (fRecurse) {
fsDirs.pszDir = (PTCHAR)gmkstr(_tcslen(pfsFiles->pszDir)*sizeof(TCHAR) + sizeof(TCHAR));
mystrcpy(fsDirs.pszDir, pfsFiles->pszDir);
fsDirs.ppatdsc = (PPATDSC)gmkstr( sizeof( PATDSC ) );
fsDirs.cpatdsc = 1;
fsDirs.fIsFat = pfsFiles->fIsFat;
fsDirs.pfsNext = NULL;
if (fFatDrive) {
fsDirs.ppatdsc->pszPattern = TEXT("*.*");
} else {
fsDirs.ppatdsc->pszPattern = TEXT("*");
}
fsDirs.ppatdsc->pszDir = (PTCHAR)gmkstr(_tcslen(fsDirs.pszDir)*sizeof(TCHAR) + sizeof(TCHAR));
mystrcpy(fsDirs.ppatdsc->pszDir, fsDirs.pszDir);
fsDirs.fIsFat = fsDirs.fIsFat;
fsDirs.ppatdsc->ppatdscNext = NULL;
if (GetFS(&fsDirs,
pdpr->rgfSwitchs,
FILE_ATTRIBUTE_DIRECTORY,
FILE_ATTRIBUTE_DIRECTORY,
pdpr->dwTimeType,
pscr,
NULL,
NULL
) != SUCCESS) {
//
// No directory below
//
fsDirs.cff = 0;
}
//
// Check for CtrlC again after calling GetFS because
// GetFS may have returned failure because CtrlC was hit
// inside the GetFS function call
//
if (CtrlCSeen) {
return( FAILURE );
}
//
// Increment though the list of directories processing each one
//
for (irgpffDirsCur = 0;irgpffDirsCur < fsDirs.cff;irgpffDirsCur++) {
//
// Do not recurse on .. since that will send you up the tree
//
pszDirName = (PTCHAR)((fsDirs.prgpff[irgpffDirsCur])->data.cFileName);
if (_tcscmp(TEXT(".."),pszDirName) && _tcscmp(TEXT("."),pszDirName)) {
//
// If name is too big then blow it all away
//
if ((_tcslen(pfsFiles->pszDir) + _tcslen(pszDirName) + 2) >= MAX_PATH) {
return( ERROR_BUFFER_OVERFLOW );
}
mystrcpy(szDirNew, pfsFiles->pszDir);
//
// check if it needs a trailing path char
//
if (*lastc(szDirNew) != BSLASH) {
DEBUG((ICGRP, DILVL, "\t New Directory `%ws'",szDirNew));
mystrcat(szDirNew, TEXT("\\"));
}
mystrcat(szDirNew,pszDirName);
DEBUG((ICGRP, DILVL, "\t New Directory `%ws'",szDirNew));
fsFilesNext.pszDir = (PTCHAR)gmkstr(_tcslen(szDirNew)*sizeof(TCHAR) + sizeof(TCHAR));
mystrcpy(fsFilesNext.pszDir, szDirNew);
fsFilesNext.ppatdsc = pfsFiles->ppatdsc;
fsFilesNext.cpatdsc = pfsFiles->cpatdsc;
fsFilesNext.fIsFat = pfsFiles->fIsFat;
fsFilesNext.pfsNext = NULL;
rc = DirWalkAndProcess( pfctProcessFiles,
pfctProcessDir,
pscr, pcffTotal, pcbFileTotal,
&fsFilesNext, pdpr, FALSE, pfctPrintErr);
//
// BUGBUG Should this error code be paid attention to
// and what should it be?
//
//
// BUGBUG merge the GetFs with the code above in a seperate
// routine
//
if (pfctProcessDir) {
rc = GetFS(&fsFilesNext,
pdpr->rgfSwitchs,
pdpr->rgfAttribs,
pdpr->rgfAttribsOnOff,
pdpr->dwTimeType,
pscr,
pfctPrintErr,
NULL
);
if (rc != SUCCESS) {
if ((rc != ERROR_FILE_NOT_FOUND) && (rc != ERROR_NO_MORE_FILES)) {
// PutStdErr(rc, NOARGS);
return( rc );
}
}
pfctProcessDir(&fsFilesNext, pcffTotal);
FreeStr((PTCHAR)(fsFilesNext.pff));
FreeStr((PTCHAR)(fsFilesNext.prgpff));
fsFilesNext.pff = NULL;
fsFilesNext.prgpff = NULL;
}
FreeStr(fsFilesNext.pszDir);
}
}
//
// At bottom of directory tree, free buffer holding
// list of directories.
//
FreeStr((PTCHAR)(fsDirs.pszDir));
FreeStr((PTCHAR)(fsDirs.pff));
FreeStr((PTCHAR)(fsDirs.prgpff));
}
return(rc);
}
/*++
Routine Description:
Arguments:
Return Value:
Return:
--*/
STATUS
GetFS(
IN PFS pfsCur,
IN ULONG rgfSwitchs,
IN ULONG rgfAttribs,
IN ULONG rgfAttribsOnOff,
IN ULONG dwTimeType,
IN PSCREEN pscr,
IN BOOLEAN (*pfctPrintPatternErr) (STATUS, PTCHAR),
IN STATUS (* pfctProcessFileEarly) ( PSCREEN, ULONG, ULONG, PLARGE_INTEGER, PFS, PFF )
)
{
HANDLE hndFirst;
PFF pffCur;
ULONG cff = 0;
ULONG cbfsLim;
ULONG cbfsCur = 0;
ULONG irgpffCur;
ULONG cbT;
PPATDSC ppatdscCur;
ULONG i, rc;
USHORT cbFileName, cbAlternateFileName;
BOOLEAN bPrintedErr;
TCHAR szSearchPath[MAX_PATH + 2];
UNREFERENCED_PARAMETER( rgfSwitchs );
DosErr = 0;
pfsCur->pff = pffCur = (PFF)gmkstr( cbfsLim = CBFILEINC);
pfsCur->cff = 0;
pfsCur->cffDisplayed = 0;
pfsCur->cbFileTotal.QuadPart = 0;
bPrintedErr = FALSE;
for(i = 1, ppatdscCur = pfsCur->ppatdsc;
i <= pfsCur->cpatdsc;
i++, ppatdscCur = ppatdscCur->ppatdscNext ) {
//
// Check immediately if a control-c was hit before
// doing file I/O (which may take a long time on a slow link)
//
if (CtrlCSeen) {
return(FAILURE);
}
if (mystrlen(pfsCur->pszDir) > (MAX_PATH + 2) ) {
return( ERROR_BUFFER_OVERFLOW );
}
mystrcpy(szSearchPath, pfsCur->pszDir);
/* don't append '\' if we have a current dir is D:\ */
if (mystrlen(pfsCur->pszDir) != mystrlen(TEXT("D:\\")) ||
szSearchPath[1] != COLON) {
if ( (mystrlen(szSearchPath) + mystrlen(TEXT("\\") ) )
> (MAX_PATH + 2) ) {
return( ERROR_BUFFER_OVERFLOW );
}
mystrcat(szSearchPath, TEXT("\\"));
}
//DbgPrint("GetFS: searching for %s in %s\n",ppatdscCur->pszPattern,szSearchPath);
if ( (mystrlen(szSearchPath) + mystrlen(ppatdscCur->pszPattern) )
> (MAX_PATH + 2) ) {
return( ERROR_BUFFER_OVERFLOW );
}
mystrcat(szSearchPath, ppatdscCur->pszPattern);
if (SetSearchPath(pfsCur, ppatdscCur, szSearchPath, MAX_PATH + 2) != SUCCESS) {
return( ERROR_BUFFER_OVERFLOW );
}
if (pfctProcessFileEarly) {
//
// Setting tabs to 0 forces single line output
//
if (pscr)
SetTab(pscr, 0);
if (!(rgfSwitchs & (BAREFORMATSWITCH|DELPROCESSEARLY))) {
//
// if it is not the bare format or del calling (no header, no tail)
// then display which directory, volume etc.
//
CHECKSTATUS(DisplayFileListHeader(pscr, rgfSwitchs, pfsCur->pszDir ));
}
}
//
// Fetch all files since we may looking for a file with a attribute that
// is not set (a non-directory etc.
//
if (!FindFirstNt(szSearchPath, &(pffCur->data), &hndFirst)) {
if (DosErr) {
if ((DosErr != ERROR_FILE_NOT_FOUND) &&
(DosErr != ERROR_NO_MORE_FILES)) {
return( DosErr );
}
//
if (pfctPrintPatternErr) {
bPrintedErr = TRUE;
pfctPrintPatternErr(DosErr, szSearchPath);
}
// If doing multiple file list then keep loop till out of
// patterns
//
if (pfsCur->cpatdsc > 1) {
// if pfctPrintPatternErr is != NULL, we've been
// called by del, so print an error. otherwise, we've
// been called by dir.
//if (pfctPrintPatternErr) {
// PutStdErr(MSG_NOT_FOUND, ONEARG, szSearchPath);
//}
continue;
} else {
//if (pfctPrintPatternErr) {
// PutStdErr(MSG_NOT_FOUND, ONEARG, szSearchPath);
//}
return( DosErr );
}
}
} else {
do {
//
// Check immediately if a control-c was hit before
// doing file I/O (which may take a long time on a slow link)
//
if (CtrlCSeen) {
findclose( hndFirst );
return(FAILURE);
}
//
// Before allowing this entry to be put in the list check it
// for the proper attribs
//
// rgfAttribs is a bit mask of attribs we care to look at
// rgfAttribsOnOff is the state these selected bits must be in
// for them to be selected.
//
// IMPORTANT: both of these must be in the same bit order
//
//
DEBUG((ICGRP, DILVL, " found %ws", pffCur->data.cFileName)) ;
DEBUG((ICGRP, DILVL, " attribs %x", pffCur->data.dwFileAttributes)) ;
if (!((pffCur->data.dwFileAttributes & rgfAttribs) ==
(rgfAttribs & rgfAttribsOnOff) )) {
continue;
}
//
// Compute the true size of the ff entry and don't forget the zero
// and the DWORD alignment factor.
// Note that pffCur->cb is a USHORT to save space. The
// assumption is that MAX_PATH is quite a bit less then 32k
//
// To compute remove the size of the filename field since it is at MAX_PATH.
// also take out the size of the alternative name field
// then add back in the actual size of the field plus 1 byte termination
//
cbFileName = (USHORT)_tcslen((pffCur->data).cFileName);
cbAlternateFileName = (USHORT)_tcslen((pffCur->data).cAlternateFileName);
pffCur->cb = (USHORT)((sizeof(FF) - (MAX_PATH + 14*sizeof(TCHAR))) + cbFileName + sizeof(TCHAR) );
if (cbAlternateFileName) {
//
// cbAlternateFileName + 1 to account for zero termination
//
pffCur->cb += cbAlternateFileName + sizeof(TCHAR);
pffCur->obAlternate = (USHORT)(cbFileName + sizeof(TCHAR));
memmove(&((pffCur->data).cFileName[cbFileName + sizeof(TCHAR)]),
&((pffCur->data).cAlternateFileName),
(cbAlternateFileName + 1) * sizeof(TCHAR));
} else {
pffCur->obAlternate = 0;
}
//
// Adjust count to align on DWORD boundaries for mips and risc
// machines
//
pffCur->cb = (USHORT)(((pffCur->cb + sizeof(DWORD)) / sizeof(DWORD)) * sizeof(DWORD));
//
// Here we print out the filenames early if a 'dir'
// was executed and we don't need to sort them or print
// them out in any wide format.
//
if (pfctProcessFileEarly) {
rc = (pfctProcessFileEarly)(pscr,
rgfSwitchs,
dwTimeType,
&pfsCur->cbFileTotal,
pfsCur,
pffCur
);
if (rc == (FAILURE+1)) {
findclose( hndFirst );
return FAILURE;
} else
if (rc == FAILURE)
bPrintedErr = TRUE;
}
if (!pfctProcessFileEarly || (pffCur->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
cff++;
//
// Update the accounting information for file buffer info.
//
cbfsCur += pffCur->cb;
(char*)(pffCur) += pffCur->cb;
//
// make sure we can handle the next entry.
//
if ((sizeof( FF ) + sizeof(DWORD) + cbfsCur) > cbfsLim) {
// cbT = cbfsCur + CBFILEINC;
//
// BUGBUG change this inline to a #define later.
// I do not want to make a change to the .h file this
// close to beta.
// the 64k value is here to avoid heavy heap
// fragmentation
//
cbT = cbfsCur + (64 * 1024);
DEBUG((ICGRP, DILVL, "\t size of new pff %d", cbT ));
if ((pffCur = pfsCur->pff = (PFF)resize(pfsCur->pff, cbT)) == NULL) {
DEBUG((ICGRP, DILVL, "\t Could not resize pff" ));
return( MSG_NO_MEMORY );
}
DEBUG((ICGRP, DILVL, "\t resized pffCur new value %lx", (ULONG)(pffCur))) ;
//
// recompute the currency of the ff pointer
//
pffCur = (PFF)((char*)(pfsCur->pff) + cbfsCur);
//
// reset the buffer size
//
cbfsLim = cbT;
}
}
} while (FindNextNt(&(pffCur->data), hndFirst));
findclose( hndFirst );
//
// BUGBUG may need to check for error on Find. here
//
}
} // FOR
//
// DosErr is set in the FindNext code.
// Check if we term. loop for something other then end of
// file list.
//
if ((DosErr) && (DosErr != ERROR_NO_MORE_FILES)) {
//
// If not doing multiple file list then error
// If multiple have failed but still have files from previous pattern
//
if (pfsCur->cpatdsc <= 1) {
return( DosErr );
}
}
//
// if no files then do not create pointers
//
if (cff || pfsCur->cffDisplayed) {
if (!pfctProcessFileEarly) {
pfsCur->prgpff = (PPFF)gmkstr( sizeof(PFF) * (cff));
pfsCur->cff = cff;
pffCur = pfsCur->pff;
for (irgpffCur = 0; irgpffCur < cff; irgpffCur++ ) {
pfsCur->prgpff[irgpffCur] = pffCur;
(char*)(pffCur) += pffCur->cb;
}
}
return( SUCCESS);
}
if (!bPrintedErr) {
DosErr = ERROR_FILE_NOT_FOUND;
if (pfctPrintPatternErr) {
pfctPrintPatternErr(DosErr, szSearchPath);
}
}
return( DosErr );
}
STATUS
SetSearchPath (
IN PFS pfsCur,
IN PPATDSC ppatdscCur,
IN PTCHAR pszSearchPath,
IN ULONG cSearchPath
) {
if ((mystrlen(pfsCur->pszDir) +
mystrlen(TEXT("\\")) +
mystrlen(ppatdscCur->pszPattern) + 1) > cSearchPath) {
return(ERROR_BUFFER_OVERFLOW);
}
mystrcpy(pszSearchPath, pfsCur->pszDir);
/* don't append '\' if we have a current dir is D:\ */
if (mystrlen(pfsCur->pszDir) != mystrlen(TEXT("D:\\")) ||
pszSearchPath[1] != COLON) {
mystrcat(pszSearchPath, TEXT("\\"));
}
mystrcat(pszSearchPath, ppatdscCur->pszPattern);
return( SUCCESS );
}