bool FLDR::FProcess() { bool fStat; char szPath[MAX_PATH]; char szName[MAX_PATH]; char szMsg[cchLogMsgMax]; HANDLE hfind; WIN32_FIND_DATA ffdt; fStat = fFalse; if (CchOfSz(szPathSrc) == 0) { apst.SetErrLast(errAppNoSrcPath); return fStat; } if (CchOfSz(szPathDst) == 0) { apst.SetErrLast(errAppNoDstPath); return fStat; } /* Determine whether we are walking the source tree or the destinaton tree, ** and initialize szPath appropriately. */ if (apst.FUpdateDst()) { /* If we are performing an update operation, we need to walk the ** source tree. */ SzCopy(szPath, szPathSrc); } else if (apst.FTrimDst()) { /* When deleting files from the destination tree that aren't in the ** source tree, we need to walk the destination tree. */ SzCopy(szPath, szPathDst); } else if (apst.FExtractDst()) { /* When performing an extract operation, we need to walk the ** destination tree. */ SzCopy(szPath, szPathDst); } else { /* Internal error. We shouldn't be able to get here without one ** of the above conditions being true. */ apst.SetErrLast(errInternalError); return fStat; } if ((CchOfSz(szPath)+CchOfSz(szFindAll)) > MAX_PATH) { /* The path name is too long to process. */ apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\n", szPath); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); return fStat; } //SzAppendPathSeparator(SzEnd(szPath)); SzAppend(szPath, szFindAll); if ((hfind = FindFirstFile(szPath, &ffdt)) == INVALID_HANDLE_VALUE) { apst.SetErrLast(errFileSystem); if (apst.ErrLast() == ERROR_PATH_NOT_FOUND) { sprintf_s(szMsg, cchLogMsgMax, "Path not found: %s\n", szPath); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); } return fStat; } fldrmg.BeginDirectory(); do { /* Check for system files, and only process them if the parameter ** was set on the command line. */ if ((ffdt.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) { if (!apst.FDoSystem()) { continue; } } /* Check for hidden files and only process them if the parameter ** was set on the command line. */ if ((ffdt.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) { if (!apst.FDoHidden()) { continue; } } /* Check if this is a directory. */ if ((ffdt.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { /* Is thie folder being excluded. */ if (fldrmg.FMatchXclDir(ffdt.cFileName)) { if (apst.FPrintXclDir() || apst.FLogXclDir()) { SzCopy(szName, szPathSrc); SzAppendPathSeparator(SzEnd(szName)); if (CchOfSz(szName)+CchOfSz(ffdt.cFileName) > MAX_PATH) { apst.SetStProg(stPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, ffdt.cFileName); app.PrintMessage(idMsgSkipDir, szMsg); cmdx.LogMessage(idMsgSkipDir, szMsg); continue; } SzAppend(szName, ffdt.cFileName); sprintf_s(szMsg, cchLogMsgMax, "Skipping: %s\n", szName); app.PrintMessage(idMsgSkipDir, szMsg); cmdx.LogMessage(idMsgSkipDir, szMsg); } fldrmg.DirExcluded(); continue; } /* Add it to the list of folders to be processed. */ if (!FProcessDirectory(ffdt.cFileName)) { break; } } else { /* Process the file */ if (fldrmg.FMatchXclExt(SzExtOfName(ffdt.cFileName)) || fldrmg.FMatchXclFile(ffdt.cFileName)) { if (apst.FPrintXclFile()|| apst.FLogXclFile()) { SzCopy(szName, szPathSrc); SzAppendPathSeparator(SzEnd(szName)); if (CchOfSz(szName)+CchOfSz(ffdt.cFileName) > MAX_PATH) { apst.SetStProg(stPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, ffdt.cFileName); app.PrintMessage(idMsgSkipDir, szMsg); cmdx.LogMessage(idMsgSkipDir, szMsg); continue; } SzAppend(szName, ffdt.cFileName); sprintf_s(szMsg, cchLogMsgMax, "Excluding: %s\n", szName); app.PrintMessage(idMsgExclFile, szMsg); cmdx.LogMessage(idMsgExclFile, szMsg); } fldrmg.FileExcluded(); continue; } if (!FProcessFile(ffdt.cFileName)) { break; } } } while (FindNextFile(hfind, &ffdt) != 0); fldrmg.EndDirectory(); if (GetLastError() == ERROR_NO_MORE_FILES) { fStat = fTrue; } FindClose(hfind); return fStat; }
bool FLDT::FProcessFile(char * szFile) { bool fStat; char szSrc[MAX_PATH]; char szDst[MAX_PATH]; char szMsg[cchLogMsgMax]; HANDLE hfindSrc; HANDLE hfindDst; WIN32_FIND_DATA ffdtSrc; WIN32_FIND_DATA ffdtDst; DWORD err; fStat = fFalse; fldrmg.FileProcessed(); /* Set up the path and file name for the source file. */ if ((CchOfSz(szPathSrc)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szSrc, szPathSrc); SzAppendPathSeparator(SzEnd(szSrc)); SzAppend(szSrc, szFile); /* Set up the path and file name for the destination file. */ if ((CchOfSz(szPathDst)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetStProg(stPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathDst, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szDst, szPathDst); SzAppendPathSeparator(SzEnd(szDst)); SzAppend(szDst, szFile); /* Tell the FLDRMG about these path strings to it can keep ** track of the longest. */ fldrmg.SetCchPath(CchOfSz(szSrc)); fldrmg.SetCchPath(CchOfSz(szDst)); /* Get information about the files to determine which is newer. */ hfindDst = FindFirstFile(szDst, &ffdtDst); FindClose(hfindDst); hfindSrc = FindFirstFile(szSrc, &ffdtSrc); if (hfindSrc == INVALID_HANDLE_VALUE) { err = GetLastError(); if (err == ERROR_FILE_NOT_FOUND) { /* The file doesn't exist in the source tree, delete it. */ goto lDeleteFile; } else if (err = ERROR_PATH_NOT_FOUND) { /* The folder that this file is in doesn't exist in the ** source tree, so we should delete it. Ideally, we would ** also delete the folder. */ goto lDeleteFile; } else { /* Some other error is a real error. */ goto lErrorExit; } } FindClose(hfindDst); /* We get here if both files exist. Since we're only deleting files ** in the destination tree that don't exist in the source tree, we ** don't need to do anything with this file. */ goto lNoDelete; /* We haven't come up with a reason not to copy this file, so ** the destination file needs to be copied to the extraction tree. */ lDeleteFile: if (apst.FPrintFile() || apst.FLogFile()) { sprintf_s(szMsg, cchLogMsgMax, "Deleting: %s\n", szDst); app.PrintMessage(idMsgDelFile, szMsg); cmdx.LogMessage(idMsgDelFile, szMsg); } if (!apst.FNoCopyFile()) { fldrmg.FileDeleted(); if (DeleteFile(szDst) == 0) { if (GetLastError() == ERROR_ACCESS_DENIED) { if (apst.FPrintFile() || apst.FLogFile()) { sprintf_s(szMsg, cchLogMsgMax, "Access Denied!\n"); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); } } else { apst.SetErrLast(errFileSystem); sprintf_s(szMsg, cchLogMsgMax, "Error copying file: %s\n", szDst); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } } } lNoDelete: fStat = fTrue; lErrorExit: apst.FSetSzFileCur(szFile); return fStat; }
bool FLDT::FProcessDirectory(char * szDir) { bool fStat; FLDT * pfldt; char szSrc[MAX_PATH]; char szDst[MAX_PATH]; char szMsg[cchLogMsgMax]; fStat = fFalse; /* Don't add the '.' and '..' directories to the list. */ if ((CompareSz(szDir, ".") == 0) || (CompareSz(szDir, "..") == 0)) { return fTrue; } /* Set up the destination path string. */ if ((CchOfSz(szPathDst)+CchOfSz(szDir)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathDst, szDir); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szDst, szPathDst); SzAppendPathSeparator(SzEnd(szDst)); SzAppend(szDst, szDir); /* Check if this directory is one that is being excluded. */ if (fldrmg.FMatchXclPath(szDst)) { if (apst.FPrintXclDir()) { sprintf_s(szMsg, cchLogMsgMax, "Skipping: %s\n", szDst); app.PrintMessage(idMsgExclFile, szDst); cmdx.LogMessage(idMsgExclFile, szDst); } fldrmg.DirExcluded(); return fTrue; } /* Set the source path string */ if ((CchOfSz(szPathSrc)+CchOfSz(szDir)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathSrc, szDir); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szSrc, szPathSrc); SzAppendPathSeparator(SzEnd(szSrc)); SzAppend(szSrc, szDir); /* Create the new folder object. */ pfldt = new FLDT; if (pfldt == NULL) { apst.SetErrLast(errOutOfMemory); goto lErrorExit; } /* Set the path names into the FLDR object and add it to the list ** of directories to be processed. */ pfldt->SetPathSrc(szSrc); pfldt->SetPathDst(szDst); fldrmg.AddPfldr(pfldt); fStat = fTrue; lErrorExit: return fStat; }
bool FLDX::FProcessFile(char * szFile) { bool fStat; char szSrc[MAX_PATH]; char szDst[MAX_PATH]; char szXtr[MAX_PATH]; char szMsg[cchLogMsgMax]; HANDLE hfindSrc; HANDLE hfindDst; WIN32_FIND_DATA ffdtSrc; WIN32_FIND_DATA ffdtDst; FSIG fsig; bool fSameSize; bool fSameTime; int dftTime; DWORD sigSrc; DWORD sigDst; DWORD err; fStat = fFalse; fldrmg.FileProcessed(); /* Set up the path and file name for the source file. */ if ((CchOfSz(szPathSrc)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathSrc, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szSrc, szPathSrc); SzAppendPathSeparator(SzEnd(szSrc)); SzAppend(szSrc, szFile); /* Set up the path and file name for the destination file. */ if ((CchOfSz(szPathDst)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathDst, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szDst, szPathDst); SzAppendPathSeparator(SzEnd(szDst)); SzAppend(szDst, szFile); /* Tell the FLDRMG about these path strings to it can keep ** track of the longest. */ fldrmg.SetCchPath(CchOfSz(szSrc)); fldrmg.SetCchPath(CchOfSz(szDst)); /* Get information about the files to determine which is newer. */ hfindDst = FindFirstFile(szDst, &ffdtDst); FindClose(hfindDst); hfindSrc = FindFirstFile(szSrc, &ffdtSrc); if (hfindSrc == INVALID_HANDLE_VALUE) { err = GetLastError(); if ((err == ERROR_FILE_NOT_FOUND) || (err = ERROR_PATH_NOT_FOUND)) { if (apst.FExtractUnique()) { /* The file doesn't exist in the source tree. If we are ** extracting unique files, we need to copy this one. */ goto lCopy; } else { /* If we're not extracting unique files, there's nothing ** to do. */ goto lNoCopy; } } else { /* Some other error is a real error. */ goto lErrorExit; } } FindClose(hfindDst); /* We get here if both files exist. If we're not doing extract ** files that differ, then get we shouldn't be copying the file. */ if (!apst.FExtractDiff()) { goto lNoCopy; } /* Compare the file sizes. */ if ((ffdtSrc.nFileSizeHigh == ffdtDst.nFileSizeHigh) && (ffdtSrc.nFileSizeLow == ffdtDst.nFileSizeLow)) { fSameSize = fTrue; } else { fSameSize = fFalse; } /* Check if there is a FAT file system involved. */ if (apst.FSrcFsFat() || apst.FDstFsFat()) { /* Either the source or destination are on a FAT file system. ** modify the times so that they will compare. the NTFS keeps ** last write time at 10ms resolution, the FAT file system keeps ** last write time as 2s resolution. */ ffdtSrc.ftLastWriteTime.dwLowDateTime &= 0xFE000000; ffdtDst.ftLastWriteTime.dwLowDateTime &= 0xFE000000; } /* Compare the file times ** dftTime has the following meaning: ** -1 source file older than destination ** 0 source file and destination file have same times ** 1 source file newer than destination */ dftTime = CompareFileTime(&(ffdtSrc.ftLastWriteTime), &(ffdtDst.ftLastWriteTime)); if (dftTime == 0) { fSameTime = fTrue; } else { fSameTime = fFalse; } /* Determine if we need to copy the source file over the destination file. */ if (apst.FUseSignatures()) { if (fSameSize) { /* When using file signatures: ** If they are the same size and have the same last write time, ** they are identical, so don't extract this file. */ if (fSameTime) { goto lNoCopy; } /* When the files are the same size, but have different times, ** check the signatures to see if they are identical. */ fsig.FInit(szSrc, fldrmg.CbSigBuf(), fldrmg.PbSigBuf()); fsig.FGenerate(&sigSrc); fsig.Terminate(); fsig.FInit(szDst, fldrmg.CbSigBuf(), fldrmg.PbSigBuf()); fsig.FGenerate(&sigDst); fsig.Terminate(); if (sigSrc == sigDst) { /* They have the same content, so don't extract the file. */ goto lNoCopy; } } } else { /* When not using file signatures: ** Files that are the same size and have the same date and time ** don't get copied. ** If they are different size or have a different date and time, ** copy the destination file to the extraction tree. */ if (fSameTime & fSameSize) { goto lNoCopy; } } /* We haven't come up with a reason not to copy this file, so ** the destination file needs to be copied to the extraction tree. */ lCopy: /* Make sure that this directory path exists. */ if (!apst.FNoCopyDir()) { fldrmg.DirCreated(); if (!FCreatePath(szPathXtr)) { apst.SetErrLast(errFileSystem); sprintf_s(szMsg, cchLogMsgMax, "Error creating folder: %s\n", szPathXtr); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } } /* Set up the path and file name for the extracted file. */ if ((CchOfSz(szPathXtr)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s%s\n", szPathXtr, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szXtr, szPathXtr); SzAppendPathSeparator(SzEnd(szXtr)); SzAppend(szXtr, szFile); fldrmg.SetCchPath(CchOfSz(szXtr)); if (apst.FPrintFile() || apst.FLogFile()) { sprintf_s(szMsg, cchLogMsgMax, "Extracting: %s\n", szDst); app.PrintMessage(idMsgExtrFile, szMsg); cmdx.LogMessage(idMsgExtrFile, szMsg); } if (!apst.FNoCopyFile()) { fldrmg.FileCopied(); if (CopyFile(szDst, szXtr, fFalse) == 0) { apst.SetErrLast(errFileSystem); sprintf_s(szMsg, cchLogMsgMax, "Error copying file: %s\n", szSrc); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } } lNoCopy: fStat = fTrue; lErrorExit: apst.FSetSzFileCur(szFile); return fStat; }
bool FLDS::FProcessFile(char * szFile) { bool fStat; char szSrc[MAX_PATH]; char szDst[MAX_PATH]; char szMsg[cchLogMsgMax]; HANDLE hfindSrc; HANDLE hfindDst; HANDLE fhDst; WIN32_FIND_DATA ffdtSrc; WIN32_FIND_DATA ffdtDst; FSIG fsig; bool fSameSize; bool fSameTime; int dftTime; DWORD sigSrc; DWORD sigDst; DWORD err; fStat = fFalse; fldrmg.FileProcessed(); /* Set up the source file name. */ if ((CchOfSz(szPathSrc)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathSrc, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szSrc, szPathSrc); SzAppendPathSeparator(SzEnd(szSrc)); SzAppend(szSrc, szFile); /* Set up the destination file name */ if ((CchOfSz(szPathDst)+CchOfSz(szFile)+1) >= MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathDst, szFile); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szDst, szPathDst); SzAppendPathSeparator(SzEnd(szDst)); SzAppend(szDst, szFile); /* Accumulate the maximum path length. */ fldrmg.SetCchPath(CchOfSz(szSrc)); fldrmg.SetCchPath(CchOfSz(szDst)); /* Get information about the files to determine which is newer. */ hfindSrc = FindFirstFile(szSrc, &ffdtSrc); FindClose(hfindSrc); hfindDst = FindFirstFile(szDst, &ffdtDst); if (hfindDst == INVALID_HANDLE_VALUE) { err = GetLastError(); if (err == ERROR_FILE_NOT_FOUND) { goto lCopy; } else if (apst.FNoCopyDir() && (err == ERROR_PATH_NOT_FOUND)) { goto lNoCopy; } else { apst.SetErrLast(errFileSystem); goto lErrorExit; } } FindClose(hfindDst); /* Compare the file sizes. */ if ((ffdtSrc.nFileSizeHigh == ffdtDst.nFileSizeHigh) && (ffdtSrc.nFileSizeLow == ffdtDst.nFileSizeLow)) { fSameSize = fTrue; } else { fSameSize = fFalse; } /* Check if there is a FAT file system involved. */ if (apst.FSrcFsFat() || apst.FDstFsFat()) { /* Either the source or destination are on a FAT file system. ** modify the times so that they will compare. the NTFS keeps ** last write time at 10ms resolution, the FAT file system keeps ** last write time as 2s resolution. */ ffdtSrc.ftLastWriteTime.dwLowDateTime &= 0xFE000000; ffdtDst.ftLastWriteTime.dwLowDateTime &= 0xFE000000; } /* Compare the file times ** dftTime has the following meaning: ** -1 source file older than destination ** 0 source file and destination file have same times ** 1 source file newer than destination */ dftTime = CompareFileTime(&(ffdtSrc.ftLastWriteTime), &(ffdtDst.ftLastWriteTime)); if (dftTime == 0) { fSameTime = fTrue; } else { fSameTime = fFalse; } /* Determine if we need to copy the source file over the destination file. */ if (apst.FUseSignatures()) { if (fSameSize) { /* When using file signatures: ** If they are the same size and have the same last write time, ** they are identical, so don't copy. */ if (fSameTime) { goto lNoCopy; } /* When the files are the same size, but have different times, ** check the signatures to see if they are identical. */ fsig.FInit(szSrc, fldrmg.CbSigBuf(), fldrmg.PbSigBuf()); fsig.FGenerate(&sigSrc); fsig.Terminate(); fsig.FInit(szDst, fldrmg.CbSigBuf(), fldrmg.PbSigBuf()); fsig.FGenerate(&sigDst); fsig.Terminate(); if (sigSrc == sigDst) { /* They have the same content. Update the destination file ** to have the same times as the source file. */ goto lSetTime; } /* They don't have the same content, so check the last write ** times to see whether or not to copy the source file. */ if (dftTime <= 0) { goto lNoCopy; } } } else { /* When not using file signatures: ** Files that are the same size and have the same date and time ** don't get copied. ** If they are different size or have a different date and time, ** copy the source file if it is newer. */ if (fSameTime & !fSameSize) { /* This shouldn't happen. The files have the same name and same ** time, but are different size. */ printf("** Files have same modification data and time, but are different size:\n"); printf(" %s\n", szSrc); printf(" %s\n", szDst); goto lNoCopy; } if (fSameTime & fSameSize) { goto lNoCopy; } if (dftTime <= 0) { goto lNoCopy; } } /* We haven't come up with a reason not to copy this file, so ** the source file needs to be copied over the destination file. */ goto lCopy; /* The files are identical, but have different times. ** Set the Creation Time and Last Write Time of the ** destination file to match the source file. */ lSetTime: if (apst.FPrintFile() || apst.FLogFile()) { sprintf_s(szMsg, cchLogMsgMax, "Setting time: %s\n", szDst); app.PrintMessage(idMsgCopyFile, szMsg); cmdx.LogMessage(idMsgCopyFile, szMsg); } if (!apst.FNoCopyFile()) { fhDst = CreateFile(szDst, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); SetFileTime(fhDst, &(ffdtSrc.ftCreationTime), NULL, &(ffdtSrc.ftLastWriteTime)); CloseHandle(fhDst); } goto lNoCopy; /* Copy the source file to the destination. */ lCopy: if (apst.FPrintFile() || apst.FLogFile()) { sprintf_s(szMsg, cchLogMsgMax, "Copying: %s\n", szSrc); app.PrintMessage(idMsgCopyFile, szMsg); cmdx.LogMessage(idMsgCopyFile, szMsg); } if (!apst.FNoCopyFile()) { fldrmg.FileCopied(); if (CopyFile(szSrc, szDst, fFalse) == 0) { apst.SetErrLast(errFileSystem); sprintf_s(szMsg, cchLogMsgMax, "Error copying file: %s\n", szSrc); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } } lNoCopy: fStat = fTrue; lErrorExit: apst.FSetSzFileCur(szFile); return fStat; }
bool FLDS::FProcessDirectory(char * szDir) { bool fStat; FLDS * pflds; HANDLE fh; char szSrc[MAX_PATH]; char szDst[MAX_PATH]; char szMsg[cchLogMsgMax]; DWORD err; fStat = fFalse; /* Don't add the '.' and '..' directories to the list. */ if ((CompareSz(szDir, ".") == 0) || (CompareSz(szDir, "..") == 0)) { return fTrue; } /* Set the source path string */ if ((CchOfSz(szPathSrc)+CchOfSz(szDir)+1) > MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathSrc, szDir); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szSrc, szPathSrc); SzAppendPathSeparator(SzEnd(szSrc)); SzAppend(szSrc, szDir); /* Set up the destination path string. */ if ((CchOfSz(szPathDst)+CchOfSz(szDir)+1) > MAX_PATH) { apst.SetErrLast(errPathLength); sprintf_s(szMsg, cchLogMsgMax, "Path name too long: %s\\%s\n", szPathDst, szDir); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } SzCopy(szDst, szPathDst); SzAppendPathSeparator(SzEnd(szDst)); SzAppend(szDst, szDir); /* Check if this directory is one that is being excluded. */ if (fldrmg.FMatchXclPath(szSrc)) { if (apst.FPrintXclDir() || apst.FLogXclDir()) { sprintf_s(szMsg, cchLogMsgMax, "Skipping: %s\n", szSrc); app.PrintMessage(idMsgSkipDir, szMsg); cmdx.LogMessage(idMsgSkipDir, szMsg); } fldrmg.DirExcluded(); return fTrue; } /* Check that the destination directory exists, and create it if ** it doesn't */ fh = CreateFile(szDst, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_BACKUP_SEMANTICS, NULL); if (fh == INVALID_HANDLE_VALUE) { err = GetLastError(); if ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND)) { apst.SetStProg(stFileSystemError); goto lErrorExit; } if (apst.FPrintDir() || apst.FLogDir()) { sprintf_s(szMsg, cchLogMsgMax, "Creating: %s\n", szDst); app.PrintMessage(idMsgCreateDir, szMsg); cmdx.LogMessage(idMsgCreateDir, szMsg); } if (!apst.FNoCopyDir()) { fldrmg.DirCreated(); if (!FCreatePath(szDst)) { apst.SetErrLast(errFileSystem); sprintf_s(szMsg, cchLogMsgMax, "Error creating directory: %s", szDst); app.PrintMessage(idMsgError, szMsg); cmdx.LogMessage(idMsgError, szMsg); goto lErrorExit; } } } else { CloseHandle(fh); } /* Create the new folder object. */ pflds = new FLDS; if (pflds == NULL) { apst.SetErrLast(errOutOfMemory); goto lErrorExit; } /* Set the path names into the FLDR object and add it to the list ** of directories to be processed. */ pflds->SetPathSrc(szSrc); pflds->SetPathDst(szDst); fldrmg.AddPfldr(pflds); fStat = fTrue; lErrorExit: return fStat; }