Example #1
0
static OSStatus CFCreateDirectory(FSRef	*parentRef, CFStringRef name, FSRef *newRef)
{
	OSStatus		result = noErr;
	HFSUniStr255	uniStr;
	
	uniStr.length = CFStringGetLength(name);
	CFStringGetCharacters(name, CFRangeMake(0, uniStr.length), uniStr.unicode);
	result = FSMakeFSRefUnicode(parentRef, uniStr.length, uniStr.unicode, kTextEncodingMacRoman, newRef);
	if (result != noErr)
	{
		result = FSCreateDirectoryUnicode(parentRef, uniStr.length, uniStr.unicode, 0, NULL, newRef, NULL, NULL);
	}

	return result;
}
Example #2
0
void myCreateFolder(t_mkdir, t_symbol *newfoldername) 
// short CreateFolder(const FSRef parentFolder, const CFStringRef folderName) 
{
	OSErr myerr;
	long len;
	short path;
	char name[256];
	char inname[2048];
	char name[2048];
	char parentname[2048];
	FSSpec fs;
	CFStringRef str;
	CFURLRef url;
	HFSUniStr255 folderNameU;


	path_nameconform(inname, newfoldername->s_name, PATH_STYLE_NATIVE, PATH_TYPE_ABSOLUTE);	
	len = strlen(inname);
	strrchr();
	filename = strrchr(name, '/') + 1;

	if (!path_topathname(path, "", inname)) { // check if path alreay exists
	
		path_nameconform(outname, natname, PATH_STYLE_NATIVE, PATH_TYPE_ABSOLUTE);
		
		path_tospec(0, natname, &fs);
	
		str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
		
		folderNameU.length = (UInt16) CFStringGetLength(str);
		
		CFStringGetCharacters(folderName, CFRangeMake(0, folderNameU.length), folderNameU.unicode);

		// see if it already exists?
		myerr = FSMakeFSRefUnicode(&parentname, folderNameU.length,folderNameU.unicode,
							kTextEncodingUnicodeDefault, NULL);
		// should now verify that is, in fact, a folder.
	
		if (myerr != noErr) { // no, so try to create it.		
			myerr = FSCreateDirectoryUnicode(&parentFolder, folderNameU.length, folderNameU.unicode,
				kFSCatInfoNone, NULL, NULL, NULL, NULL);
		}
		return myerr;	
	}
}
Example #3
0
static OSErr FindSNESFolder(FSRef *folderRef, char *folderPath, const char *folderName)
{
	OSStatus	err;
	CFURLRef	burl, purl;
	CFStringRef	fstr;
	FSRef		pref;
	UniChar		buffer[PATH_MAX + 1];
	Boolean		r;

	fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding());
	CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer);

	burl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
	purl = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, burl);
	r    = CFURLGetFSRef(purl, &pref);

	err = FSMakeFSRefUnicode(&pref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef);
 	if (err == dirNFErr || err == fnfErr)
	{
		err = FSCreateDirectoryUnicode(&pref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, nil, folderRef, nil, nil);
		if (err == noErr)
			AddFolderIcon(folderRef, folderName);
	}

	if (err != noErr && !folderWarning)
	{
		AppearanceAlert(kAlertCautionAlert, kFolderFail, kFolderHint);
		folderWarning = true;
	}
	else
		err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX);

	CFRelease(purl);
	CFRelease(burl);
	CFRelease(fstr);

	return err;
}
static bool _q_isMacHidden(const QString &path)
{
    OSErr err = noErr;

    FSRef fsRef;

#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
        err = FSPathMakeRefWithOptions(reinterpret_cast<const UInt8 *>(QFile::encodeName(QDir::cleanPath(path)).constData()),
                                        kFSPathMakeRefDoNotFollowLeafSymlink, &fsRef, 0);
    } else
#endif
    {
        QFileInfo fi(path);
        FSRef parentRef;
        err = FSPathMakeRef(reinterpret_cast<const UInt8 *>(fi.absoluteDir().absolutePath().toUtf8().constData()),
                            &parentRef, 0);
        if (err == noErr) {
            QString fileName = fi.fileName();
            err = FSMakeFSRefUnicode(&parentRef, fileName.length(),
                                     reinterpret_cast<const UniChar *>(fileName.unicode()),
                                     kTextEncodingUnknown, &fsRef);
        }
    }
    if (err != noErr)
        return false;

    FSCatalogInfo catInfo;
    err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL);
    if (err != noErr)
        return false;

    FileInfo * const fileInfo = reinterpret_cast<FileInfo*>(&catInfo.finderInfo);
    bool result = (fileInfo->finderFlags & kIsInvisible);
    return result;
}
Example #5
0
static OSStatus FindCustomFolder (FSRef *folderRef, char *folderPath, const char *folderName)
{
	OSStatus	err;
	CFStringRef	fstr;
	FSRef		pref;
	UniChar		buffer[PATH_MAX + 1];
	char		s[PATH_MAX + 1];

	if (saveFolderPath == NULL)
		return (-1);

	err = CFStringGetCString(saveFolderPath, s, PATH_MAX, kCFStringEncodingUTF8) ? noErr : -1;
	if (err == noErr)
		err = FSPathMakeRef((unsigned char *) s, &pref, NULL);

	if (err)
		return (err);

	fstr = CFStringCreateWithCString(kCFAllocatorDefault, folderName, CFStringGetSystemEncoding());
	CFStringGetCharacters(fstr, CFRangeMake(0, CFStringGetLength(fstr)), buffer);

	err = FSMakeFSRefUnicode(&pref, CFStringGetLength(fstr), buffer, kTextEncodingUnicodeDefault, folderRef);
	if (err == dirNFErr || err == fnfErr)
	{
		err = FSCreateDirectoryUnicode(&pref, CFStringGetLength(fstr), buffer, kFSCatInfoNone, NULL, folderRef, NULL, NULL);
		if (err == noErr)
			AddFolderIcon(folderRef, folderName);
	}

	if (err == noErr)
		err = FSRefMakePath(folderRef, (unsigned char *) folderPath, PATH_MAX);

	CFRelease(fstr);

	return (err);
}
Example #6
0
int doItTheHardWay(unsigned char *pathString,FSSpec *spec,Boolean noDrillDown) {
    char *token;
    Str255 lookup;
    UniChar   buffer[1024];
    Boolean firstTime=true;
    OSErr   err;
    long    parentDirectory,tokenLength;
    FSRef   parentFSRef,childFSRef;
    CFStringRef aLevel;
    FSSpec	fix;
    
    token = strtok((char*) pathString,":");
    if (token == 0) return -1;
    while (token) 
    {
        tokenLength = strlen(token);
        if (firstTime) {// Mmm will crash if volume name is 255 characters, unlikely
            strncpy((char*) lookup+1,(char*) token,tokenLength);
            lookup[0] = tokenLength+1;
            lookup[lookup[0]] = ':';
            firstTime = false;
            err = FSMakeFSSpecCompat(spec->vRefNum,spec->parID, lookup, spec);
            if (err != noErr)
                return err;
            err = FSpMakeFSRef(spec,&parentFSRef);
            if (err != noErr)
                return err;
        } else {
            fix = *spec;
            fix.name[0] = 0;
            err = FSpMakeFSRef(&fix,&parentFSRef);
            if (err != noErr)
                return err;
           aLevel = CFStringCreateWithCString(kCFAllocatorDefault,token,gCurrentVMEncoding);
           if (aLevel == nil) 
                return -1000;
           tokenLength = CFStringGetLength(aLevel);
           CFStringGetCharacters(aLevel,CFRangeMake(0,tokenLength),buffer);
           err = FSMakeFSRefUnicode(&parentFSRef,tokenLength,buffer,gCurrentVMEncoding,&childFSRef);
           if (err != noErr) {
                CFStringGetPascalString(aLevel,spec->name,64,gCurrentVMEncoding);
                CFRelease(aLevel);
				token = strtok(nil,":"); 
				if (token == nil)
					return err;
				else
					return -1001;
            }
           CFRelease(aLevel);
           parentFSRef = childFSRef;
           err = FSGetCatalogInfo (&parentFSRef,kFSCatInfoNone,nil,nil,spec,nil);
            if (err != noErr)
                return err;
        }
        fetchFileSpec(spec,spec->name,&parentDirectory);
        token = strtok(nil,":"); 
    }
   if (noDrillDown) 
       spec->parID = parentDirectory;
     return noErr;
}
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;
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
//---------------------------------------------------------------------
// 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;
}
Example #11
0
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);
}
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;
}