SMACsdec::SMACsdec(ComponentInstance inSelf) : mSelf(inSelf), mSourceComponent(NULL), mDecoder(NULL), mSourceID(0), mSourceData(NULL), mPacketFrameSize(0), mFloatBuffer(NULL), mOutputBuffer(NULL) #if CaptureDataToFile ,mOutputFileRefNum(-1) #endif { memset(&mOutputData, 0, sizeof(SoundComponentData)); mOutputData.format = k16BitNativeEndianFormat; mOutputData.sampleSize = 16; #if TARGET_API_MAC_OSX && TARGET_CPU_PPC mHasAltiVec = SMACSCDUtility::HasAltiVec(); #else mHasAltiVec = false; #endif #if TARGET_API_MAC_OSX mThreadStateMutex = new CAMutex("SMACsdec::mThreadStateMutex"); #endif #if CaptureDataToFile FSRef theFSRef; FSRef theParentRef; UniChar theFileName[] = { 'o', 'u', 't', 'p', 'u', 't', '.', 's', 'd', '2' }; OSStatus theError = FSPathMakeRef((const UInt8*)"/Volumes/Annex/Users/moorf/output.sd2", &theFSRef, NULL); if(theError != fnfErr) { FSDeleteObject(&theFSRef); } theError = FSPathMakeRef((const UInt8*)"/Volumes/Annex/Users/moorf", &theParentRef, NULL); theError = FSCreateFileUnicode(&theParentRef, 10, theFileName, kFSCatInfoNone, NULL, &theFSRef, NULL); theError = FSOpenFork(&theFSRef, 0, NULL, fsRdWrPerm, &mOutputFileRefNum); if(theError != 0) { mOutputFileRefNum = -1; } #endif }
extern char* vr_findVerRegName() { OSErr err; FSRef foundRef; err = FSFindFolder(kLocalDomain, kDomainLibraryFolderType, kDontCreateFolder, &foundRef); if (err == noErr) { FSRef parentRef; err = FSMakeFSRefUnicode(&foundRef, UNICHAR_ARRAY_LEN(kOSXRegParentName), kOSXRegParentName, kTextEncodingUnknown, &parentRef); if (err == fnfErr) { err = FSCreateDirectoryUnicode(&foundRef, UNICHAR_ARRAY_LEN(kOSXRegParentName), kOSXRegParentName, kFSCatInfoNone, NULL, &parentRef, NULL, NULL); } if (err == noErr) { FSRef regRef; err = FSMakeFSRefUnicode(&parentRef, UNICHAR_ARRAY_LEN(kOSXVersRegName), kOSXVersRegName, kTextEncodingUnknown, ®Ref); if (err == fnfErr) { FSCatalogInfo catalogInfo; FileInfo fileInfo = { 'REGS', 'MOSS', 0, { 0, 0 }, 0 }; memmove(&(catalogInfo.finderInfo), &fileInfo, sizeof(FileInfo)); err = FSCreateFileUnicode(&parentRef, UNICHAR_ARRAY_LEN(kOSXVersRegName), kOSXVersRegName, kFSCatInfoFinderInfo, &catalogInfo, ®Ref, NULL); } if (err == noErr) { UInt8 pathBuf[PATH_MAX]; err = FSRefMakePath(®Ref, pathBuf, sizeof(pathBuf)); if (err == noErr) verRegName = XP_STRDUP((const char*)pathBuf); } } } return verRegName; }
int __open_file(const char * name, __file_modes mode, __file_handle * handle) { FSSpec spec; OSErr ioResult; HParamBlockRec pb; ioResult = __path2fss(name, &spec); if (ioResult) gSqueakFileLastError = ioResult; if (__system7present()) /* mm 980424 */ { /* mm 980424 */ Boolean targetIsFolder, wasAliased; /* mm 980424 */ ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); /* mm 980424 */ } /* mm 980424 */ if (ioResult && (ioResult != fnfErr || mode.open_mode == __must_exist)) return(__io_error); #if TARGET_API_MAC_CARBON if (ioResult) { CFStringRef filePath; CFURLRef sillyThing, sillyThing2; FSRef parentFSRef; short int fileRefNum; OSErr err; UniChar buffer[1024]; long tokenLength; filePath = CFStringCreateWithBytes(kCFAllocatorDefault,(UInt8 *)name,strlen(name),gCurrentVMEncoding,false); if (filePath == nil) return __io_error; sillyThing = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,filePath,kCFURLHFSPathStyle,false); CFRelease(filePath); sillyThing2 = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault,sillyThing); err = CFURLGetFSRef(sillyThing2,&parentFSRef); if (err == 0) { CFRelease(sillyThing); CFRelease(sillyThing2); return fnfErr; } filePath = CFURLCopyLastPathComponent(sillyThing); tokenLength = CFStringGetLength(filePath); if (tokenLength > 1024) { CFRelease(filePath); CFRelease(sillyThing); CFRelease(sillyThing2); return(__io_error); } CFStringGetCharacters(filePath,CFRangeMake(0,tokenLength),buffer); CFRelease(filePath); CFRelease(sillyThing); CFRelease(sillyThing2); ioResult = FSCreateFileUnicode(&parentFSRef,tokenLength,buffer,kFSCatInfoNone,NULL,NULL,&spec); if (ioResult) gSqueakFileLastError = ioResult; if (ioResult) return(__io_error); pb.ioParam.ioNamePtr = spec.name; pb.ioParam.ioVRefNum = spec.vRefNum; pb.ioParam.ioPermssn = (mode.io_mode == __read) ? fsRdPerm : fsRdWrPerm; pb.ioParam.ioMisc = 0; pb.fileParam.ioFVersNum = 0; pb.fileParam.ioDirID = spec.parID; set_file_type(&spec, mode.binary_io); ioResult = PBHOpenDFSync(&pb); /* HH 10/25/97 was PBHOpenSync */ if (ioResult) return(__io_error); *handle = pb.ioParam.ioRefNum; return(__no_io_error); } #endif pb.ioParam.ioNamePtr = spec.name; pb.ioParam.ioVRefNum = spec.vRefNum; pb.ioParam.ioPermssn = (mode.io_mode == __read) ? fsRdPerm : fsRdWrPerm; pb.ioParam.ioMisc = 0; pb.fileParam.ioFVersNum = 0; pb.fileParam.ioDirID = spec.parID; if (ioResult) { if (!(ioResult = PBHCreateSync(&pb))) { if (ioResult) gSqueakFileLastError = ioResult; set_file_type(&spec, mode.binary_io); ioResult = PBHOpenDFSync(&pb); /* HH 10/25/97 was PBHOpenSync */ if (ioResult) gSqueakFileLastError = ioResult; } } else { if (!(ioResult = PBHOpenDFSync(&pb)) && mode.open_mode == __create_or_truncate) /* HH 10/25/97 was PBHOpenSync */ { pb.ioParam.ioMisc = 0; ioResult = PBSetEOFSync((ParmBlkPtr) &pb); if (ioResult) gSqueakFileLastError = ioResult; if (ioResult) PBCloseSync((ParmBlkPtr) &pb); } else { if (ioResult) gSqueakFileLastError = ioResult; } } if (ioResult) return(__io_error); *handle = pb.ioParam.ioRefNum; return(__no_io_error); }
CFURLRef GetSaveDialogForUser(char* title, char* message) { NavDialogCreationOptions dialogOptions; FSRef output_file; CFURLRef fileAsCFURLRef = NULL; OSStatus status; CFAllocatorRef alloc_default = kCFAllocatorDefault; AEKeyword keyword; DescType actual_type; Size actual_size; FSRef output_dir; NavReplyRecord reply; CFIndex len; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions( &dialogOptions ); require_noerr( status, CantGetNavOptions ); dialogOptions.optionFlags = kNavNoTypePopup + kNavSupportPackages + kNavAllowOpenPackages; // = NULL; if (title != NULL) { CFStringRef cftitle = CFStringCreateWithCString(alloc_default,title,kCFStringEncodingMacRoman); dialogOptions.windowTitle = cftitle; } if (message != NULL) { CFStringRef cfmessage = CFStringCreateWithCString(alloc_default,message,kCFStringEncodingMacRoman); dialogOptions.message = cfmessage; } // Make the window app-wide modal dialogOptions.modality = kWindowModalityAppModal; NavDialogRef dialog; status = NavCreatePutFileDialog ( &dialogOptions, NULL, NULL, NULL, NULL, &dialog); require_noerr( status, CantCreateDialog ); status = NavDialogRun(dialog); require_noerr( status, CantRunDialog ); // get dialog reply status = NavDialogGetReply(dialog, &reply); require( ((status == noErr) || (status == userCanceledErr)), CantGetReply ); //get file directory status = AEGetNthPtr(&(reply.selection), 1, typeFSRef, &keyword, &actual_type, &output_dir, sizeof(output_file), &actual_size); require_noerr( status, CantExtractFSRef ); UInt8 output_dir_name[1024]; FSRefMakePath(&output_dir, output_dir_name, 1024 ); // now get filename len = CFStringGetLength(reply.saveFileName); if (len > 255) len = 255; UniChar output_filename[255]; CFStringGetCharacters(reply.saveFileName, CFRangeMake(0, len), output_filename); // need to unlink the old file if ( reply.replacing ) { FSRef oldfile; status = FSMakeFSRefUnicode(&output_dir, len, output_filename, kTextEncodingUnicodeDefault, &oldfile); if (status == noErr) status = FSDeleteObject(&oldfile); //overwrite failed! require_noerr( status, UserCanceled ); } //create fsref again to new file (NOTE: this actually makes a file...) status = FSCreateFileUnicode( &output_dir, len, output_filename, kFSCatInfoNone, NULL, &output_file, NULL ); require_noerr( status, CantExtractFSRef ); // Convert it to a CFURL fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &output_file); CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&reply) ); CantGetReply: CantRunDialog: // cleanup dialog NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return fileAsCFURLRef; }
OSErr SplitFileIfNeeded(FSRef * inFileReference,FSRef * inParentReference,FSCatalogInfo * inFileCatalogInfo,HFSUniStr255 * inFileName) { OSErr tErr; Boolean splitNeeded=FALSE; SInt16 tForkRefNum; UInt32 tResourceForkSize=0; static HFSUniStr255 sResourceForkName={0,{}}; Boolean hasResourceFork=FALSE; static UInt8 tPOSIXPath[PATH_MAX*2+1]; static UInt32 tPOSIXPathMaxLength=PATH_MAX*2; struct stat tFileStat; SInt16 tNewFileRefNum; if (sResourceForkName.length==0) { tErr=FSGetResourceForkName(&sResourceForkName); if (tErr!=noErr) { logerror("An error occurred when obtaining the ResourceFork name\n"); return -1; } } // 1. Check for the presence of a resource fork tErr=FSOpenFork(inFileReference,sResourceForkName.length,sResourceForkName.unicode,fsRdPerm,&tForkRefNum); if (tErr==noErr) { SInt64 tForkSize; // Get the size of the resource fork tErr=FSGetForkSize(tForkRefNum,&tForkSize); if (tErr!=noErr) { logerror("An error occurred on getting the resource fork size of a file or director\n"); FSCloseFork(tForkRefNum); return -1; } if (tForkSize>0xFFFFFFFF) { FSCloseFork(tForkRefNum); // AppleDouble File format does not support forks bigger than 2GB logerror("AppleDouble file format does not support forks bigger than 2 GB\n"); return -1; } tResourceForkSize=tForkSize; if (tForkSize>0) { hasResourceFork=TRUE; splitNeeded=TRUE; } else { FSCloseFork(tForkRefNum); } } else { switch(tErr) { case errFSForkNotFound: case eofErr: // No resource Fork tErr=noErr; break; default: logerror("Unable to open fork\n"); return -1; break; } } // 2. Check for the presence of FinderInfo or ExtFinderInfo if (splitNeeded==FALSE) { UInt32 * tUnsignedInt32Ptr; int i; // 1. We need to save the Folder(Ext) Info in the ._ file if there are any folder/finder or extend folder/finder info tUnsignedInt32Ptr= (UInt32 *) inFileCatalogInfo->finderInfo; for(i=0;i<4;i++) { if (tUnsignedInt32Ptr[i]!=0) { // We need to create a ._file splitNeeded=TRUE; break; } } if (splitNeeded==TRUE) // 01/02/07: Symbolic link looks like this { UInt32 tSymbolicLink; tSymbolicLink='s'; tSymbolicLink='l'+(tSymbolicLink<<8); tSymbolicLink='n'+(tSymbolicLink<<8); tSymbolicLink='k'+(tSymbolicLink<<8); if (tUnsignedInt32Ptr[0]==tSymbolicLink) { splitNeeded=FALSE; } } else { tUnsignedInt32Ptr= (UInt32 *) inFileCatalogInfo->extFinderInfo; for(i=0;i<4;i++) { if (tUnsignedInt32Ptr[i]!=0) { // We need to create a ._file splitNeeded=TRUE; break; } } } } // 3. Split if needed if (splitNeeded==TRUE) { FSRef tNewFileReference; HFSUniStr255 tNewFileName; // Get the absolute Posix Path Name tErr=FSRefMakePath(inFileReference,tPOSIXPath,tPOSIXPathMaxLength); if (tErr==noErr) { if (lstat((char *) tPOSIXPath,&tFileStat)==-1) { switch(errno) { case ENOENT: // A COMPLETER break; default: // A COMPLETER break; } tErr=-1; goto byebye; } } else { logerror("An error occurred when trying to get the absolute path of a file or directory\n"); tErr=-1; goto byebye; } if (gVerboseMode==TRUE) { printf(" splitting %s...\n",tPOSIXPath); } // Check that we do not explode the current limit for file names if (inFileName->length>gMaxFileNameLength) { // We do not have enough space to add the ._ prefix // The file name is too long // Write the error logerror("File name is too long. The maximum length allowed is %ld characters\n",gMaxFileNameLength+2); return -1; } tNewFileName.length=inFileName->length+2; tNewFileName.unicode[0]='.'; tNewFileName.unicode[1]='_'; BlockMoveData(inFileName->unicode,tNewFileName.unicode+2,inFileName->length*sizeof(UniChar)); // We need to create a ._file tryagain: tErr=FSCreateFileUnicode(inParentReference,tNewFileName.length,tNewFileName.unicode,0,NULL,&tNewFileReference,NULL); if (tErr!=noErr) { switch(tErr) { case bdNamErr: case fsmBadFFSNameErr: case errFSNameTooLong: // The file name is too long // Write the error logerror("File name is too long. The maximum length allowed is %ld characters\n",gMaxFileNameLength+2); break; case dskFulErr: logerror("Disk is full\n"); break; case errFSQuotaExceeded: logerror("Your quota are exceeded\n"); break; case dupFNErr: // The file already exists, we need to try to delete it before recreating it tErr=FSMakeFSRefUnicode(inParentReference,tNewFileName.length,tNewFileName.unicode,kTextEncodingDefaultFormat,&tNewFileReference); if (tErr==noErr) { // Delete the current ._file tErr=FSDeleteObject(&tNewFileReference); if (tErr==noErr) { goto tryagain; } else { // A COMPLETER } } else { // A COMPLETER } break; case afpVolLocked: // A COMPLETER break; default: // A COMPLETER break; } return -1; } tErr=FSOpenFork(&tNewFileReference,0,NULL,fsWrPerm,&tNewFileRefNum); if (tErr==noErr) { unsigned char tAppleDoubleMagicNumber[4]= {0x00,0x05,0x16,0x07}; unsigned char tAppleDoubleVersionNumber[4]={0x00,0x02,0x00,0x00}; unsigned char tAppleDoubleFiller[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; ByteCount tRequestCount; UInt16 tNumberOfEntries; UInt16 tSwappedNumberOfEntries; UInt32 tEntryID; UInt32 tEntryOffset; UInt32 tEntryLength; // Write the Magic Number tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,tAppleDoubleMagicNumber,NULL); if (tErr!=noErr) { goto writebail; } // Write the Version Number tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,tAppleDoubleVersionNumber,NULL); if (tErr!=noErr) { goto writebail; } // Write the Filler tRequestCount=16; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,tAppleDoubleFiller,NULL); if (tErr!=noErr) { goto writebail; } // Compute the Number of Entries tNumberOfEntries=0x0002; tSwappedNumberOfEntries=tNumberOfEntries; #ifdef __LITTLE_ENDIAN__ // Swap for Intel processor tSwappedNumberOfEntries=CFSwapInt16(tSwappedNumberOfEntries); #endif tRequestCount=2; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tSwappedNumberOfEntries,NULL); if (tErr!=noErr) { goto writebail; } // Write the Entries Descriptor // **** Finder Info tEntryID=0x00000009; // Finder Info ID tEntryOffset=0x0000001A+tNumberOfEntries*12; tEntryLength=0x00000020; // 32 bytes #ifdef __LITTLE_ENDIAN__ // Swap for Intel processor tEntryID=CFSwapInt32(tEntryID); tEntryOffset=CFSwapInt32(tEntryOffset); tEntryLength=CFSwapInt32(tEntryLength); #endif tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryID,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryOffset,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryLength,NULL); if (tErr!=noErr) { goto writebail; } tEntryID=0x00000002; // Resource Fork ID tEntryOffset=0x00000052; if (hasResourceFork==TRUE) { // **** Finder Info tEntryLength=tResourceForkSize; // As you can see the AppleDouble format file is not ready for forks bigger than 2 GB } else { tEntryLength=0; } #ifdef __LITTLE_ENDIAN__ // Swap for Intel processor tEntryID=CFSwapInt32(tEntryID); tEntryOffset=CFSwapInt32(tEntryOffset); tEntryLength=CFSwapInt32(tEntryLength); #endif tRequestCount=4; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryID,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryOffset,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,&tEntryLength,NULL); if (tErr!=noErr) { goto writebail; } // Write the Entries // **** Write Finder Info #ifdef __LITTLE_ENDIAN__ // Intel Processors // Even though it's referenced as a bytes field in the File API, this is actually a structure we need to swap... if (inFileCatalogInfo->nodeFlags & kFSNodeIsDirectoryMask) { // It's a fragging folder FolderInfo * tFolderInfoStruct; ExtendedFolderInfo * tExtendedFolderInfoStruct; // Swap FolderInfo Structure tFolderInfoStruct=(FolderInfo *) inFileCatalogInfo->finderInfo; SWAP_RECT(tFolderInfoStruct->windowBounds); tFolderInfoStruct->finderFlags=CFSwapInt16(tFolderInfoStruct->finderFlags); SWAP_POINT(tFolderInfoStruct->location); tFolderInfoStruct->reservedField=CFSwapInt16(tFolderInfoStruct->reservedField); // Swap ExtendedFolderInfo Info Structure tExtendedFolderInfoStruct=(ExtendedFolderInfo *) inFileCatalogInfo->extFinderInfo; SWAP_POINT(tExtendedFolderInfoStruct->scrollPosition); tExtendedFolderInfoStruct->reserved1=CFSwapInt32(tExtendedFolderInfoStruct->reserved1); tExtendedFolderInfoStruct->extendedFinderFlags=CFSwapInt16(tExtendedFolderInfoStruct->extendedFinderFlags); tExtendedFolderInfoStruct->reserved2=CFSwapInt16(tExtendedFolderInfoStruct->reserved2); tExtendedFolderInfoStruct->putAwayFolderID=CFSwapInt32(tExtendedFolderInfoStruct->putAwayFolderID); } else { // I'm just a file, you know FileInfo * tFileInfoStruct; ExtendedFileInfo * tExtendedFileInfoStruct; // Swap FileInfo Structure tFileInfoStruct=(FileInfo *) inFileCatalogInfo->finderInfo; tFileInfoStruct->fileType=CFSwapInt32(tFileInfoStruct->fileType); tFileInfoStruct->fileCreator=CFSwapInt32(tFileInfoStruct->fileCreator); tFileInfoStruct->finderFlags=CFSwapInt16(tFileInfoStruct->finderFlags); SWAP_POINT(tFileInfoStruct->location); tFileInfoStruct->reservedField=CFSwapInt16(tFileInfoStruct->reservedField); // Swap ExtendedFileInfo Structure tExtendedFileInfoStruct=(ExtendedFileInfo *) inFileCatalogInfo->extFinderInfo; tExtendedFileInfoStruct->reserved1[0]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[0]); tExtendedFileInfoStruct->reserved1[1]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[1]); tExtendedFileInfoStruct->reserved1[2]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[2]); tExtendedFileInfoStruct->reserved1[3]=CFSwapInt16(tExtendedFileInfoStruct->reserved1[3]); tExtendedFileInfoStruct->extendedFinderFlags=CFSwapInt16(tExtendedFileInfoStruct->extendedFinderFlags); tExtendedFileInfoStruct->reserved2=CFSwapInt16(tExtendedFileInfoStruct->reserved2); tExtendedFileInfoStruct->putAwayFolderID=CFSwapInt32(tExtendedFileInfoStruct->putAwayFolderID); } #endif tRequestCount=16; tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,inFileCatalogInfo->finderInfo,NULL); if (tErr!=noErr) { goto writebail; } tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tRequestCount,inFileCatalogInfo->extFinderInfo,NULL); if (tErr!=noErr) { goto writebail; } // **** Write Resource Fork? if (hasResourceFork==TRUE) { // We need to be clever and copy the Resource Fork by chunks to avoid using too much memory static UInt8 * tBuffer=NULL; static ByteCount tReadRequestCount=0; ByteCount tReadActualCount; OSErr tReadErr; #define GOLDIN_BUFFER_ONE_MEGABYTE_SIZE 1048576 if (tBuffer==NULL) { tReadRequestCount=GOLDIN_BUFFER_ONE_MEGABYTE_SIZE; do { tBuffer=(UInt8 *) malloc(tReadRequestCount*sizeof(UInt8)); tReadRequestCount/=2; } while (tBuffer==NULL && tReadRequestCount>1); if (tBuffer!=NULL && tReadRequestCount>1) { tReadRequestCount*=2; } else { // A COMPLETER } } do { tReadErr=FSReadFork(tForkRefNum, fsAtMark,0, tReadRequestCount, tBuffer, &tReadActualCount); if (tReadErr==noErr || tReadErr==eofErr) { tErr=FSWriteFork(tNewFileRefNum,fsAtMark,0,tReadActualCount,tBuffer,NULL); if (tErr!=noErr) { break; } } else { break; } } while (tReadErr!=eofErr); if (tReadErr!=eofErr) { // A problem occurred while reading the Resource Fork goto writebail; } else if (tErr!=noErr) { // A problem occurred while writing the Resource Fork Data to the AppleDouble file goto writebail; } } tErr=FSCloseFork(tNewFileRefNum); tErr=noErr; // Set the owner tErr=FSSetCatalogInfo(&tNewFileReference,kFSCatInfoPermissions,inFileCatalogInfo); if (tErr!=noErr) { //logerror("Permissions, owner and group could not be set for the AppleDouble file of %s\n",tPOSIXPath); tErr=-1; goto byebye; } } else { // A COMPLETER } // Close the Resource Fork if needed if (hasResourceFork==TRUE) { tErr=FSCloseFork(tForkRefNum); if (gStripResourceForks==TRUE && tErr==noErr) { // Strip the resource fork tErr=FSDeleteFork(inFileReference,sResourceForkName.length,sResourceForkName.unicode); if (tErr!=noErr) { switch(tErr) { case errFSForkNotFound: // This is not important tErr=noErr; break; default: // A COMPLETER break; } } } else { if (gStripResourceForks==TRUE && tErr!=noErr) { logerror("Resource Fork could not be stripped from %s\n",tPOSIXPath); // A COMPLETER } } } } return tErr; writebail: switch(tErr) { case dskFulErr: logerror("Disk is full\n"); break; case errFSQuotaExceeded: logerror("Your quota are exceeded\n"); break; default: logerror("An unknown error occurred while writing the AppleDouble file of %s\n",tPOSIXPath); break; } FSCloseFork(tNewFileRefNum); byebye: if (hasResourceFork==TRUE) { FSCloseFork(tForkRefNum); } return tErr; }
static OSStatus DoFSRefSave(const OurSaveDialogData *dialogDataP, NavReplyRecord* reply, AEDesc *actualDescP) { OSStatus err = noErr; FSRef fileRefParent; if ((err = AEGetDescData( actualDescP, &fileRefParent, sizeof( FSRef ) )) == noErr ) { // get the name data and its length: HFSUniStr255 nameBuffer; UniCharCount sourceLength = 0; sourceLength = (UniCharCount)CFStringGetLength( reply->saveFileName ); CFStringGetCharacters( reply->saveFileName, CFRangeMake( 0, sourceLength ), (UniChar*)&nameBuffer.unicode ); if ( sourceLength > 0 ) { if ( reply->replacing ) { // delete the file we are replacing: FSRef fileToDelete; if ((err = FSMakeFSRefUnicode( &fileRefParent, sourceLength, nameBuffer.unicode, kTextEncodingUnicodeDefault, &fileToDelete )) == noErr ) { err = FSDeleteObject( &fileToDelete ); if ( err == fBsyErr ){ DoErrorAlert(fBsyErr, kMyDeleteErrorFormatStrKey); } } } if ( err == noErr ) { // create the file based on Unicode, but we can write the file's data with an FSSpec: FSSpec newFileSpec; // get the FSSpec back so we can write the file's data if ((err = FSCreateFileUnicode( &fileRefParent, sourceLength, nameBuffer.unicode, kFSCatInfoNone, NULL, NULL, &newFileSpec)) == noErr) { FInfo fileInfo; fileInfo.fdType = kFileTypePDF; fileInfo.fdCreator = kFileCreator; err = FSpSetFInfo( &newFileSpec, &fileInfo ); // now that we have the FSSpec, we can proceed with the save operation: if(!err){ FSRef fsRef; err = FSpMakeFSRef(&newFileSpec, &fsRef); // make an FSRef if(!err){ CFURLRef saveURL = CFURLCreateFromFSRef(NULL, &fsRef); if(saveURL){ // delete the file we just made for making the FSRef err = FSpDelete(&newFileSpec); if(!err) err = MakePDFDocument(dialogDataP->parentWindow, dialogDataP->documentDataP, saveURL); if(!err) err = NavCompleteSave( reply, kNavTranslateInPlace ); if(err){ // an error ocurred saving the file, so delete the copy // left over: (void)FSpDelete( &newFileSpec ); DoErrorAlert(err, kMyWriteErrorFormatStrKey); } CFRelease(saveURL); }else{ // delete the file we just made for making the FSRe (void)FSpDelete(&newFileSpec); err = kCantCreateSaveURL; DoErrorAlert(err, kMyCreateURLErrorFormatStrKey); } } } } } } } return err; }
//--------------------------------------------------------------------- // Gets a file to save from the user. Caller must release the CFURLRef. // CFURLRef GetSaveFileFromUser(WindowRef window) { CFURLRef previousFile; CFStringRef saveFileName; UniChar *chars = NULL; CFIndex length; NavDialogCreationOptions dialogOptions; NavDialogRef dialog; NavReplyRecord replyRecord; CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; FSRef parentDirectory; OSStatus status; if ( window == NULL ) return NULL; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions(&dialogOptions); require_noerr( status, CantGetNavOptions ); // Change a few things (app-wide modal, show the extension) dialogOptions.modality = kWindowModalityAppModal; dialogOptions.parentWindow = window; dialogOptions.optionFlags = kNavDefaultNavDlogOptions | kNavPreserveSaveFileExtension; // Set up the default save name previousFile = GetWindowProxyFileCFURL(window); if (previousFile == NULL) dialogOptions.saveFileName = CFStringCreateWithCString(NULL, "Untitled.rtf", kCFStringEncodingASCII); else dialogOptions.saveFileName = CFURLCopyLastPathComponent(previousFile); // Create the dialog status = NavCreatePutFileDialog(&dialogOptions, kUnknownType, kUnknownType, NULL, NULL, &dialog); require_noerr( status, CantCreateDialog ); // Show it status = NavDialogRun(dialog); require_noerr( status, CantRunDialog ); // Get the reply status = NavDialogGetReply(dialog, &replyRecord); require( ((status == noErr) || (status == userCanceledErr)), CantGetReply ); // If the user clicked "Cancel", just bail if ( status == userCanceledErr ) goto UserCanceled; // Get the file's location and name status = AEGetNthPtr(&(replyRecord.selection), 1, typeFSRef, NULL, NULL, &parentDirectory, sizeof(FSRef), NULL); require_noerr( status, CantExtractFSRef ); saveFileName = replyRecord.saveFileName; length = CFStringGetLength(saveFileName); chars = malloc(length * sizeof(UniChar)); CFStringGetCharacters(saveFileName, CFRangeMake(0, length), chars); // If we are replacing a file, erase the previous one if ( replyRecord.replacing ) { status = FSMakeFSRefUnicode(&parentDirectory, length, chars, kTextEncodingUnknown, &fileAsFSRef); require_noerr( status, CantMakeFSRef ); status = FSDeleteObject(&fileAsFSRef); require_noerr( status, CantDeletePreviousFile ); } // Create the file status = FSCreateFileUnicode(&parentDirectory, length, chars, kFSCatInfoNone, NULL, &fileAsFSRef, NULL); require_noerr( status, CantCreateSaveFile ); // Convert the reference to the file to a CFURL fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef); // Cleanup CantCreateSaveFile: CantDeletePreviousFile: CantMakeFSRef: if ( chars != NULL ) free(chars); CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: if (previousFile) CFRelease(previousFile); CFRelease(dialogOptions.saveFileName); CantGetNavOptions: return fileAsCFURLRef; }
/******************************************************************** * CreateFile * ulMode: GENERIC_READ | GENERIC_WRITE * ulSharing: FILE_SHARE_READ * pSecAttrib: NULL * ulCreation: OPEN_EXISTING, OPEN_ALWAYS, CREATE_NEW * ulFlags: 0 * hFile: NULL ********************************************************************/ HANDLE CreateFile( const char *sFileName, /* file name */ DWORD ulMode, /* access mode */ DWORD ulSharing, /* share mode */ void *pSecAttrib, /* SD */ DWORD ulCreation, /* how to create */ DWORD ulFlags, /* file attributes */ HANDLE hFile ) /* handle to template file */ { #pragma unused (ulSharing, pSecAttrib, ulFlags, hFile) OSErr theErr; FSRef theFileRef; FSRef theParentRef; short fileRef; char permission; theErr = FSPathMakeRef((const UInt8 *)sFileName, &theFileRef, NULL); if (theErr == fnfErr) { // Create the FSRef for the parent directory. memset(&theFileRef, 0, sizeof(FSRef)); UInt8 folderName[MAX_PATH]; CFStringRef folderPathCFString = CFStringCreateWithCString(NULL, sFileName, kCFStringEncodingUTF8); CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, folderPathCFString, kCFURLPOSIXPathStyle, FALSE); CFURLRef folderURL = CFURLCreateCopyDeletingLastPathComponent(NULL, fileURL); CFURLGetFileSystemRepresentation(folderURL, TRUE, folderName, MAX_PATH); theErr = FSPathMakeRef(folderName, &theParentRef, NULL); CFRelease(fileURL); CFRelease(folderURL); CFRelease(folderPathCFString); } if (theErr != noErr) { SetLastError(theErr); if (ulCreation == OPEN_EXISTING || theErr != fnfErr) return INVALID_HANDLE_VALUE; } if (ulCreation != OPEN_EXISTING) { /* We create the file */ UniChar unicodeFileName[256]; CFStringRef filePathCFString = CFStringCreateWithCString(NULL, sFileName, kCFStringEncodingUTF8); CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, filePathCFString, kCFURLPOSIXPathStyle, FALSE); CFStringRef fileNameCFString = CFURLCopyLastPathComponent(fileURL); CFStringGetCharacters(fileNameCFString, CFRangeMake(0, CFStringGetLength(fileNameCFString)), unicodeFileName); theErr = FSCreateFileUnicode(&theParentRef, CFStringGetLength(fileNameCFString), unicodeFileName, kFSCatInfoNone, NULL, &theFileRef, NULL); CFRelease(fileNameCFString); CFRelease(filePathCFString); CFRelease(fileURL); if (theErr != noErr) { SetLastError(theErr); return INVALID_HANDLE_VALUE; } } if (ulMode == GENERIC_READ) { permission = fsRdPerm; } else { if (ulMode == GENERIC_WRITE) { permission = fsWrPerm; } else { permission = fsRdWrPerm; } } theErr = FSOpenDFCompat(&theFileRef, permission, &fileRef); SetLastError(theErr); if (theErr == noErr) { return (HANDLE)(int)fileRef; } else { return INVALID_HANDLE_VALUE; } }
Boolean GetFileFromObjectAndKey(const AEDescList* desc, AEKeyword keyword, FSRef* file, Boolean create) { DescType data_desc; MacSize data_size; OSErr err; err = AESizeOfKeyDesc(desc, keyword, &data_desc, &data_size); if (err == noErr) { if (data_desc == typeObjectSpecifier) { // file object... AEDesc fileObject; err = AEGetKeyDesc(desc, keyword, typeObjectSpecifier, &fileObject); if (err == noErr) { Boolean ok = GetFileFromObjectAndKey(&fileObject, keyAEKeyData, file, create); AEDisposeDesc(&fileObject); return ok; } } else if (data_desc == typeChar && data_size <= 255) { // file path... FSRef spec; Str255 path; err = AEGetKeyPtr(desc, keyword, typeChar, &data_desc, &path[1], 255, &data_size); path[0] = data_size; if (err == noErr) { FSRef folderRef; OpString unicode_path; unicode_path.SetL((const char*)path); err = FSFindFolder(kLocalDomain, kVolumeRootFolderType, kDontCreateFolder, &folderRef); // FIXME: ismailp - test rhoroughly err = FSMakeFSRefUnicode(&folderRef, unicode_path.Length(), (const UniChar*)unicode_path.CStr(), kTextEncodingUnknown, &spec); //FSMakeFSSpec(0, 0, path, &spec); if (create && (err == noErr || err == fnfErr)) { if (noErr == err) { FSDeleteObject(&spec); } err = FSCreateFileUnicode(&spec, 0, NULL, kFSCatInfoNone, NULL, file, NULL); } } } else if (data_desc == typeAlias) { // file alias... Handle alias = NewHandle(data_size); FSRef spec; HLock(alias); err = AEGetKeyPtr(desc, keyword, typeAlias, &data_desc, *alias, data_size, &data_size); if (err == noErr) { Boolean changed; err = FSResolveAlias(NULL, (AliasHandle)alias, &spec, &changed); if (create && (err == noErr || err == fnfErr)) { if (noErr == err) { FSDeleteObject(&spec); } err = FSCreateFileUnicode(&spec, 0, NULL, kFSCatInfoNone, NULL, file, NULL); //FSpCreate(&spec, '\?\?\?\?', '\?\?\?\?', NULL); } } DisposeHandle(alias); } else { err = paramErr; } } return (err == noErr); }
void XMLMacCarbonFile::create(const XMLCh* const filePath) { OSErr err = noErr; // Split path into directory and filename components int posSlash = XMLString::lastIndexOf(filePath, '/', XMLString::stringLen(filePath) - 1); int posName = (posSlash == -1) ? 0 : posSlash+1; const XMLCh* namePtr = filePath + posName; int nameLen = XMLString::stringLen(namePtr); // Make a temporary string of the directory ArrayJanitor<XMLCh> dirPath(new XMLCh[namePtr - filePath + 1]); XMLString::subString(dirPath.get(), filePath, 0, posName); // Create the file as appropriate for API set if (gHasHFSPlusAPIs) { // HFS+ FSRef ref; // If we find an existing file, delete it if (XMLParsePathToFSRef(filePath, ref)) FSDeleteObject(&ref); // Get a ref to the parent directory if (!XMLParsePathToFSRef(dirPath.get(), ref)) err = fnfErr; // Create a new file using the unicode name if (err == noErr) { UniChar uniName[256]; err = FSCreateFileUnicode( &ref, nameLen, CopyXMLChsToUniChars(namePtr, uniName, nameLen, sizeof(uniName)), 0, NULL, NULL, NULL); } } else { // HFS FSSpec spec; // If we find an existing file, delete it if (XMLParsePathToFSSpec(filePath, spec)) FSpDelete(&spec); // Get a spec to the parent directory if (!XMLParsePathToFSSpec(dirPath.get(), spec)) err = fnfErr; // Check that the new name is not too long for HFS if (err == noErr && nameLen > 31) err = errFSNameTooLong; if (err == noErr) { // Transcode the unicode name to native encoding ArrayJanitor<const char> nativeName(XMLString::transcode(namePtr)); // Make a partial pathname from our current spec (parent directory) to the new file unsigned char name[31 * 2 + 1 * 2 + 1]; unsigned char* partial = &name[1]; *partial++ = ':'; // Partial leads with : const unsigned char* specName = spec.name; // Copy in spec name for (int specCnt = *specName++; specCnt > 0; --specCnt) *partial++ = *specName++; *partial++ = ':'; // Path component separator char c; for (const char* p = nativeName.get(); (c = *p++) != 0; ) // Copy in new element *partial++ = (c == ':') ? '/' : c; // Convert : to / name[0] = partial - &name[1]; // Set the pascal string name length // Update the spec: this will probably return fnfErr // (since we just deleted any existing file) err = FSMakeFSSpec(spec.vRefNum, spec.parID, name, &spec); // Create the file from the spec err = FSpCreate(&spec, '??\??', 'TEXT', smSystemScript); } } // Fail if we didn't create the file if (err != noErr) { ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile); //ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile); } }
OSStatus BeginSave( NavDialogRef inDialog, NavReplyRecord* outReply, FSRef* outFileRef ) { OSStatus status = paramErr; AEDesc dirDesc; AEKeyword keyword; CFIndex len; require( outReply, Return ); require( outFileRef, Return ); status = NavDialogGetReply( inDialog, outReply ); nrequire( status, Return ); status = AEGetNthDesc( &outReply->selection, 1, typeWildCard, &keyword, &dirDesc ); nrequire( status, DisposeReply ); len = CFStringGetLength( outReply->saveFileName ); if ( dirDesc.descriptorType == typeFSRef ) { const UInt32 kMaxNameLen = 255; FSRef dirRef; UniChar name[ kMaxNameLen ]; if ( len > kMaxNameLen ) { len = kMaxNameLen; } status = AEGetDescData( &dirDesc, &dirRef, sizeof( dirRef )); nrequire( status, DisposeDesc ); CFStringGetCharacters( outReply->saveFileName, CFRangeMake( 0, len ), &name[0] ); status = FSMakeFSRefUnicode( &dirRef, len, &name[0], GetApplicationTextEncoding(), outFileRef ); if (status == fnfErr ) { // file is not there yet - create it and return FSRef status = FSCreateFileUnicode( &dirRef, len, &name[0], 0, NULL, outFileRef, NULL ); } else { // looks like file is there. Just make sure there is no error nrequire( status, DisposeDesc ); } } else if ( dirDesc.descriptorType == typeFSS ) { FSSpec theSpec; status = AEGetDescData( &dirDesc, &theSpec, sizeof( FSSpec )); nrequire( status, DisposeDesc ); if ( CFStringGetPascalString( outReply->saveFileName, &(theSpec.name[0]), sizeof( StrFileName ), GetApplicationTextEncoding())) { status = FSpMakeFSRef(&theSpec, outFileRef); nrequire( status, DisposeDesc ); status = FSpCreate( &theSpec, 0, 0, smSystemScript ); nrequire( status, DisposeDesc ); } else { status = bdNamErr; nrequire( status, DisposeDesc ); } } DisposeDesc: AEDisposeDesc( &dirDesc ); DisposeReply: if ( status != noErr ) { NavDisposeReply( outReply ); } Return: return status; }