📄 hxdir.cpp
字号:
int nSpecPos = nextFSpec.name[0] - nCompareLen + 1; if (0 != strncasecmp((char*)&nextFSpec.name[nSpecPos], &m_pPattern[patternOffset+1], nCompareLen)) bContinue = FALSE; } } else { if ((patlen != nextFSpec.name[0]) || (0 != strncasecmp((char*)&nextFSpec.name[1], szPattern, patlen))) bContinue = FALSE; } } } if (bContinue) { strncpy(m_pNextFileName, (char*)&nextFSpec.name[1], len); /* Flawfinder: ignore */ m_pNextFileName[len] = 0; tempStr = m_strPath; if (m_strPath.GetLength()) { if (tempStr[tempStr.GetLength()-1] != ':') tempStr += ":"; } tempStr += m_pNextFileName; SafeStrCpy(szPath, (const char*)tempStr, nSize); if (IsFolder(&nextFSpec)) return FSOBJ_DIRECTORY; else return FSOBJ_FILE; } } RetVal = FindNext(szPath, nSize); } return RetVal;}/* Continues enumeration process. */CHXDirectory::FSOBJ CHXDirectory::FindNext(char* szPath, UINT16 nSize){ FSOBJ RetVal = FSOBJ_NOTVALID; CHXString tempStr; FSSpec nextFSpec; BOOL bContinue; if (m_pNextFileName) { SafeStrCpy(m_pCurrentFileName, m_pNextFileName, nSize); } else { if (m_pCurrentFileName) { delete [] m_pCurrentFileName; m_pCurrentFileName = NULL; } }/* tempStr = szPath; ::FSMakeFSSpec(0,0,*((Str255*)tempStr),&nextFSpec); if (IsFolder(&nextFSpec, 1)) { strcpy(szPath, (const char*)tempStr); return FSOBJ_DIRECTORY; }*/ if (m_pNextFileName) { INT16 len = 0; char* patternStart; CInfoPBRec pb; OSErr err=noErr; memset(&pb,0,sizeof(pb)); pb.hFileInfo.ioVRefNum=m_fileSpec.vRefNum; pb.hFileInfo.ioFDirIndex=0; pb.hFileInfo.ioNamePtr=m_fileSpec.name; pb.hFileInfo.ioDirID=m_fileSpec.parID; err = PBGetCatInfoSync(&pb); UINT16 dirItems = pb.dirInfo.ioDrNmFls; if (dirItems < m_nDirItems) // items have been deleted { m_nIndex -= (m_nDirItems - dirItems); m_nDirItems = dirItems; } while (::FSpIterateDirectory(&m_fileSpec, ++m_nIndex, &nextFSpec)) { bContinue = TRUE; if (m_pPattern) { INT16 patlen = strlen(m_pPattern); if ( 0 == strcmp("*.*", m_pPattern) || // *.* ((m_pPattern[0] == '*') && (strlen(m_pPattern) == 1)) ) // * bContinue = TRUE; else { if (m_pPattern[0] == '*') //eg. *.dll { if (0 != strncasecmp((char*)&nextFSpec.name[len-2], &m_pPattern[strlen(m_pPattern)-3], 3)) bContinue = FALSE; } else if ((patternStart = strchr(m_pPattern, '*')) != 0) //eg. pncrt*.dll { INT16 patternOffset = patternStart-m_pPattern; if (0 != strncasecmp((char*)&nextFSpec.name[1], m_pPattern, patternOffset)) bContinue = FALSE; if (bContinue && (patternOffset < patlen)) { int nCompareLen = (patlen > nextFSpec.name[0]) ? nextFSpec.name[0] - patternOffset : patlen - patternOffset - 1; int nSpecPos = nextFSpec.name[0] - nCompareLen + 1; if (0 != strncasecmp((char*)&nextFSpec.name[nSpecPos], &m_pPattern[patternOffset+1], nCompareLen)) bContinue = FALSE; } } else // eg. pncrtd.dll { if (0 != strncasecmp((char*)&nextFSpec.name[1], m_pPattern, patlen)) bContinue = FALSE; } } } if (bContinue) { len = nextFSpec.name[0]; strncpy(m_pNextFileName, (char*)&nextFSpec.name[1], len); /* Flawfinder: ignore */ m_pNextFileName[len] = 0; tempStr = m_strPath; if (m_strPath.GetLength()) { if (tempStr[tempStr.GetLength()-1] != ':') tempStr += ":"; } tempStr += m_pNextFileName; SafeStrCpy(szPath, (const char*)tempStr, nSize); if (IsFolder(&nextFSpec)) return FSOBJ_DIRECTORY; else return FSOBJ_FILE; } } if (RetVal != FSOBJ_FILE) { delete [] m_pNextFileName; m_pNextFileName = 0; } } return RetVal;}OSErr CHXDirectory::GetDirID(long& dirID){ FSSpec dirSpec; CInfoPBRec cinfo; OSErr err; Boolean dirFlag; if (EnsureValidPathSpec()) { dirSpec = m_dirSpec; // call GetCatInfo to get it's dirID cinfo.dirInfo.ioNamePtr = dirSpec.name; cinfo.dirInfo.ioVRefNum = dirSpec.vRefNum; cinfo.dirInfo.ioDrDirID = dirSpec.parID; cinfo.dirInfo.ioFDirIndex = 0; // use name and dirID err = PBGetCatInfoSync(&cinfo); // be sure it's really a directory if (err == noErr) { dirFlag = ((cinfo.dirInfo.ioFlAttrib & ioDirMask) != 0); if (!dirFlag) err = dirNFErr; } if (err == noErr) { dirID = cinfo.dirInfo.ioDrDirID; } } else { // invalid path err = fnfErr; } return err;}BOOL CHXDirectory::DeleteFile(const char* szRelPath){ CHXString relativeStr(szRelPath); CHXString fullFileStr; FSSpec fileSpec; OSErr err; // make a full pathname to the file if we don't have a // directory set (since some callers use a null dir // just to delete files) if (IsPartialMacPath(relativeStr) && (m_strPath.GetLength() > 0)) { // we're deleting for a partial path from the current obj directory fullFileStr = m_strPath; // add seperator if needed if ((fullFileStr.GetLength() > 0) && (fullFileStr[fullFileStr.GetLength()-1] != ':')) fullFileStr += ':'; fullFileStr += relativeStr; } else { HX_ASSERT(IsFullMacPath(relativeStr)); // object's dir not set, so this works only for full paths fullFileStr = relativeStr; } // delete the file fileSpec = fullFileStr; err = FSpDelete(&fileSpec); // we really should return an error // this gets called frequently if the file doesn't exist - not an error // so return error only if file is busy return (err != fBsyErr);}/* Sets itself to current directory. */BOOL CHXDirectory::SetCurrentDir(){ // This was never implemented, doesn't work reliably on // Macs, and since it's a bad idea, it's not worth implementing. long dirID; short vRefNum; OSErr err = ::HGetVol(NULL, &vRefNum, &dirID); err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &m_dirSpec); if (noErr == err) { m_strPath = m_dirSpec; m_strPath = m_strPath.Left(m_strPath.GetLength()-1); return TRUE; } return FALSE;}/* Makes itself a current directory. */BOOL CHXDirectory::MakeCurrentDir(){ // Relying on a global current default directory is a bad // idea, so never call this. // // Also beware that calling GetVol() won't work properly // after this, anyway. See ch. 2 of Inside Mac: Files // (under Manipulating the Default Volume and Directory) // for an explanation of why. // // SetVol, GetVol, and everything using // WDRefNums has been obsolete since 1987. // Use FSSpecs (or full pathnames, if necessary) instead. OSErr err; long dirID; err = GetDirID(dirID); if (err == noErr) { err = HSetVol(NULL, m_dirSpec.vRefNum, dirID); } return (err == noErr);}UINT32 CHXDirectory::Rename(const char* szOldName, const char* szNewName){ UINT32 err; // Unfortunately, the semantics of the parameters for this call aren't clear // // presumably, szOldName is a full path, or a partial path in the current directory // presumably, szNewName is a full path, or just a name CHXString oldFileStr(szOldName); CHXString newFileStr(szNewName); StringPtr newNamePtr; FSSpec oldFileSpec; FSSpec newFileSpec; FSSpec destDirSpec; (void) EnsureValidPathSpec(); oldFileSpec.vRefNum = 0; if (oldFileStr.Find(':') >= 0) { // the old name has a colon; convert it to a file spec oldFileSpec = oldFileStr; } if (oldFileSpec.vRefNum == 0) { // we couldn't get a valid FSSpec for the old name, // so assume it's relative to the current directory, // and make a file spec for it oldFileStr = m_dirSpec; oldFileStr += ":"; oldFileStr += szOldName; oldFileSpec = oldFileStr; } require_action(oldFileSpec.vRefNum != 0, CantGetSourceForRename, err = fnfErr); newFileSpec.vRefNum = 0; if (newFileStr.Find(':') >= 0) { // the new name has a colon; try to convert it to a file spec newFileSpec = newFileStr; } // make a filespec for the destination folder // // use the directory of the new file if it was specified, otherwise use // the directory of the old file err = FSMakeFSSpec(newFileSpec.vRefNum, (newFileSpec.vRefNum == 0 ? oldFileSpec.parID : newFileSpec.parID), "\p", &destDirSpec); check_noerr(err); // make sure we're not trying to move to another volume require_action(destDirSpec.vRefNum == oldFileSpec.vRefNum, CantChangeVolumes, err = HXR_FAILED); // they're on the same drive; possibly in different folders // use the name from the new file spec, if we have one, or else from the parameter newNamePtr = (newFileSpec.vRefNum ? newFileSpec.name : newFileStr); // use morefiles' Move/Rename call err = FSpMoveRenameCompat(&oldFileSpec, &destDirSpec, newNamePtr); if (err == dupFNErr) { err = FSpDelete(&newFileSpec); if (err == noErr) { err = FSpMoveRenameCompat(&oldFileSpec, &destDirSpec, newNamePtr); } } CantChangeVolumes:CantGetSourceForRename: if (err == noErr) err = HXR_OK; else err = HXR_FAILED; return err;}// this moves or copies and renames a fileBOOLCHXDirectory::MoveRename(const char* szSrcName, const char* szDestName, BOOL bMove){ OSErr err; FSSpec srcSpec, destSpec, deleteSpec; CHXString strSourcePath(szSrcName); srcSpec = strSourcePath; CHXString strDestFilePath(szDestName); CHXString strDestFile; strDestFile = (strrchr(szDestName, OS_SEPARATOR_CHAR)+1); CHXString strDestPath(szDestName); strDestPath = strDestPath.Left(strDestPath.ReverseFind(OS_SEPARATOR_CHAR)); destSpec = strDestPath; if (noErr == FSSpecFromPathName(strDestFilePath, &deleteSpec)) { err = ::FSpDelete(&deleteSpec); //delete existing file } // Note, FSpMoveRenameCompat doesn't move across volumes, // so copy, then delete original (below) if a move has to be done?? if (bMove) { err = FSpMoveRenameCompat(&srcSpec, &destSpec, *((Str255*)strDestFile)); } if (!bMove || (diffVolErr == err)) { char* buffer = new char[0x40000]; err = FSpFileCopy(&srcSpec,&destSpec, (ConstStr255Param)strDestFile, buffer, 0x40000, FALSE); delete buffer; } return (err == noErr); }/* Checks if directory is on CD or removable drive. */ BOOL CHXDirectory::IsRemovable(){#ifdef _CARBON if (EnsureValidPathSpec()) { return CHXFileSpecUtils::IsDiskEjectable(m_dirSpec); } return FALSE;#else OSErr err; HParamBlockRec hpb; DrvQElPtr queueElPtr; QHdrPtr queueHeader; Ptr p; if (EnsureValidPathSpec()) { hpb.volumeParam.ioVRefNum = m_dirSpec.vRefNum; hpb.volumeParam.ioNamePtr = NULL; hpb.volumeParam.ioVolIndex = 0; // use vRefNum only err = PBHGetVInfoSync(&hpb); check_noerr(err); if (err != noErr) return false; // check the flag bits in the drive queue (from Technote FL 530) queueHeader = GetDrvQHdr(); queueElPtr = (DrvQElPtr) queueHeader->qHead; while (queueElPtr != nil) { if (queueElPtr->dQDrive == hpb.volumeParam.ioVDrvInfo) { p = (Ptr) queueElPtr; p -= 3; /* to get to the byte with eject info */ if ((*p) & 8) return false; // non-ejectable else return true; // ejectable } queueElPtr = (DrvQElPtr) queueElPtr->qLink; } } return false; // we can't find this drive#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -