Example #1
0
static OSErr FSSetFInfo(const FSRef* ref, FInfo *fInfo) {
  FSCatalogInfo cinfo;
  *(FInfo*)cinfo.finderInfo = *fInfo;

  OSErr err = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &cinfo);
  return err;
}
Example #2
0
int dir_SetMacFileTypeAndCreator(char *filename, sqInt filenameSize, char *fType, char *fCreator) {
	/* Set the Macintosh type and creator of the given file. */
	/* Note: On other platforms, this is just a noop. */

    FSCatalogInfo catInfo;
	FInfo	finderInfo;
    OSErr	err;
    FSRef	theFSRef;
	char	fileNameBuffer[DOCUMENT_NAME_SIZE+1];
	int		bytes;
	
 	bytes = ioFilenamefromStringofLengthresolveAliasesRetry(fileNameBuffer,filename, filenameSize, true, true);
	if (bytes == 0) 
		return false;
    if (getFInfo(fileNameBuffer,&catInfo,kCFStringEncodingUTF8) != noErr)
        return false;
	memcpy(&finderInfo,&catInfo.finderInfo,16);
	finderInfo.fdType = CFSwapInt32HostToBig(*((int *) fType));
	finderInfo.fdCreator = CFSwapInt32HostToBig(*((int *) fCreator));
	memcpy(&catInfo.finderInfo,&finderInfo,16);
	
	err =  getFSRef(fileNameBuffer,&theFSRef,kCFStringEncodingUTF8);
	if (err != 0)
		return err;
   err = FSSetCatalogInfo (&theFSRef,kFSCatInfoFinderInfo,&catInfo);

    return true;
}
int main(int argc, char **argv) {
	if (argc < 2) {
		printf("Usage: %s <save file>\n", argv[0]);
		printf("Applies the creator and type codes so the save can be used\n");
		printf("by the original interpreter.\n");
		return 0;
	}

	uint32 creator, type;

	// First, let's open our file to make sure it's a pegasus save
	// Also, we're going to extract what type we need to set (for the correct disc)
	try {
		Common::File file(argv[1], "rb");

		// Let's make sure the user already gunzip'd the file
		uint16 gzipTest = file.readUint16BE();
		if (gzipTest == 0x1F8B) {
			printf("Please gunzip the save file first\n");
			return 1;
		}

		creator = (gzipTest << 16) | file.readUint16BE(); // Too lazy to seek back :P
		type = file.readUint32BE();

		if (creator != kPegasusCreator) {
			printf("Failed to find pegasus creator in save file\n");
			return 1;
		}

		if (type != kPegasusDisc1 && type != kPegasusDisc2 && type != kPegasusDisc3 && type != kPegasusDisc4) {
			printf("Invalid pegasus save type in save file\n");
			return 1;
		}
	} catch (Common::FileException e) {
		printf("File error: '%s'\n", e.what());
		return 1;
	}

	FSCatalogInfo catInfo;
	FSRef ref;

	if (!FSPathMakeRef((const UInt8 *)argv[1], &ref, false)) {
		FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catInfo, 0, 0, 0);
		FileInfo *info = (FileInfo *)catInfo.finderInfo;
		info->fileCreator = creator;
		info->fileType = type;
		FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catInfo);
	} else {
		printf("Failed to use File Manager to open the file\n");
		return 1;
	}

	printf("Success!\n");
	return 0;
}
Example #4
0
void	HLFileSystemObject::SetCreator(UInt32 inCreator)
{
	//	get the current Finder info from the catalog
	FSCatalogInfo theInfo;
	OSStatus theError = FSGetCatalogInfo(&mFSRef, kFSCatInfoFinderInfo, &theInfo, NULL, NULL, NULL);
	ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetType: couldn't get the catalog information");
	
	//	update just the creator
	FInfo* theFinderInfo = reinterpret_cast<FInfo*>(&theInfo.finderInfo);
	theFinderInfo->fdCreator = inCreator;

	//	write it back out
	theError = FSSetCatalogInfo(&mFSRef, kFSCatInfoFinderInfo, &theInfo);
	ThrowIfError(theError, CAException(theError), "HLFileSystemObject::SetType: couldn't set the catalog information");
}
Example #5
0
void ChangeTypeAndCreator (const char *path, OSType type, OSType creator)
{
	OSStatus	err;
	FSRef		ref;

	err = FSPathMakeRef((unsigned char *) path, &ref, NULL);
	if (err == noErr)
	{
		FSCatalogInfo	catinfo;

		err = FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catinfo, NULL, NULL, NULL);
		if (err == noErr)
		{
			((FileInfo *) &catinfo.finderInfo)->fileCreator = creator;
			((FileInfo *) &catinfo.finderInfo)->fileType    = type;

			err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catinfo);
		}
	}
}
Example #6
0
/**
 * Sets the @c OSType of a given file to @c 'Midi', but only if it's not
 * already set.
 *
 * @param *ref A @c FSSpec structure referencing a file.
 */
static void SetMIDITypeIfNeeded(const FSRef *ref)
{
	FSCatalogInfo catalogInfo;

	assert(ref);

	if (noErr != FSGetCatalogInfo(ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL)) return;
	if (!(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) {
		FileInfo * const info = (FileInfo *) catalogInfo.finderInfo;
		if (info->fileType != MIDI_TYPE && !(info->finderFlags & kIsAlias)) {
			OSErr e;
			info->fileType = MIDI_TYPE;
			e = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
			if (e == noErr) {
				DEBUG(driver, 3, "qtmidi: changed filetype to 'Midi'");
			} else {
				DEBUG(driver, 0, "qtmidi: changing filetype to 'Midi' failed - error %d", e);
			}
		}
	}
}
Example #7
0
void filecontainer_doopen(t_filecontainer *x, t_symbol *arg)
{
    t_atom			a[4];
    int				err = 0;
    char			filename[256];
    short			path;
    t_fourcc		outtype = 0;
    t_fourcc		type = 'cO0p';
#ifdef MAC_VERSION
    char			*temppath;
    FSRef			ref;
    Boolean			isDir;
    FSCatalogInfo	catalogInfo;
#else // WIN_VERSION
    char			temppath[512];
#endif
    char			fullpath[512];
    t_object		*result = NULL;
    t_object		*result2 = NULL;
    char			**record = NULL;		// sqlite records
    char			**record2 = NULL;		// sqlite records
    t_filehandle	file_handle;
    t_ptr_size		len = 0;
    char			*blob;
    char			sql[512];

    if(!arg || !arg->s_name[0]) {
        if(open_dialog(filename, &path, &outtype, NULL, -1))			// Returns 0 if successful
            return;
    }
    else {
        t_fourcc typelist[1];
        typelist[0] = 'cO0p';
        strcpy(filename, arg->s_name);
        path = 0;
        locatefile_extended(filename, &path, &type, typelist, 0);
    }
    path_topotentialname(path, filename, fullpath, 0);
#ifdef MAC_VERSION
    temppath = strchr(fullpath, ':');
    temppath += 1;
#else // WIN_VERSION
    path_nameconform(fullpath, temppath, PATH_STYLE_NATIVE_WIN, PATH_TYPE_ABSOLUTE);
#endif
    x->name = gensym(temppath);

    // Create our temp folder for extracted files
    filecontainer_gettemppath(x);

    // Create the SQLite instance
    atom_setsym(&a[0], gensym("@rambased"));
    atom_setlong(&a[1], 0);
    atom_setsym(&a[2], gensym("@db"));
    atom_setsym(&a[3], x->name);
    x->sqlite = object_new_typed(CLASS_NOBOX, _sym_sqlite, 4, a);

    // Operate on the open DB
    if(x->sqlite) {
        object_method(x->sqlite, ps_starttransaction);
        object_method(x->sqlite, _sym_execstring, TABLEDEF_FILES, NULL);
        object_method(x->sqlite, _sym_execstring, TABLEDEF_ATTRS, NULL);

        object_method(x->sqlite, _sym_execstring, "UPDATE files SET valid = 1", NULL);
        object_method(x->sqlite, _sym_execstring, "SELECT file_id, filename, moddate FROM files", &result);
        while(record = (char **)object_method(result, _sym_nextrecord)) {
            // Here we check for the optional 'platform' attr for this file.
            // If a flag exists for the other platform, but not for the current platform, then we ignore this file.
#ifdef MAC_VERSION
            sprintf(sql, "SELECT file_id_ext FROM attrs \
							WHERE attr_name = 'platform' AND attr_value = 'windows' AND file_id_ext = %s ", record[0]);
            object_method(x->sqlite, _sym_execstring, sql, &result2);
            record2 = (char **)object_method(result2, _sym_nextrecord);
            if(record2) {
                sprintf(sql, "SELECT file_id_ext FROM attrs \
								WHERE attr_name = 'platform' AND attr_value = 'mac' AND file_id_ext = %s ", record[0]);
                object_method(x->sqlite, _sym_execstring, sql, &result2);
                record2 = (char **)object_method(result2, _sym_nextrecord);
                if(!record2) {
                    sprintf(sql, "UPDATE files SET valid = 0 WHERE file_id = %s ", record[0]);
                    object_method(x->sqlite, _sym_execstring, sql, NULL);
                    continue;
                }
            }
#else // WIN_VERSION
            snprintf(sql, 512, "SELECT file_id_ext FROM attrs \
							WHERE attr_name = 'platform' AND attr_value = 'mac' AND file_id_ext = %s ", record[0]);
            object_method(x->sqlite, _sym_execstring, sql, &result2);
            record2 = (char **)object_method(result2, _sym_nextrecord);
            if(record2) {
                snprintf(sql, 512, "SELECT file_id_ext FROM attrs \
								WHERE attr_name = 'platform' AND attr_value = 'windows' AND file_id_ext = %s ", record[0]);
                object_method(x->sqlite, _sym_execstring, sql, &result2);
                record2 = (char **)object_method(result2, _sym_nextrecord);
                if(!record2) {
                    snprintf(sql, 512, "UPDATE files SET valid = 0 WHERE file_id = %s ", record[0]);
                    object_method(x->sqlite, _sym_execstring, sql, NULL);
                    continue;
                }
            }
#endif
            // At this point we have a file (record[0]), and we have determined that it is indeed a file we want to cache
            // So cache it to a new file in our temp path
            err = path_createsysfile(record[1], x->temp_path, type, &file_handle);
            if(err) {																// Handle any errors that occur
                object_error((t_object *)x, "%s - error %d creating file", filename, err);
            }
            else {
                snprintf(sql, 512, "SELECT content FROM files WHERE file_id = %s", record[0]);
                object_method(x->sqlite, ps_getblob, sql, &blob, &len);
                err = sysfile_write(file_handle, &len, blob);
                if(err) {
                    object_error((t_object *)x, "sysfile_write error (%d)", err);
                }
            }
            err = sysfile_seteof(file_handle, len);
            if(err) {
                object_error((t_object *)x, "%s - error %d setting EOF", filename, err);
            }
            sysfile_close(file_handle);		// close file reference
            sysmem_freeptr(blob);
            blob = NULL;

            // Set the moddate
#ifdef MAC_VERSION
//			FSCatalogInfo		catalogInfo;
//			Boolean             status;
            CFGregorianDate     gdate;
            CFAbsoluteTime      abstime;
            CFTimeZoneRef		tz;
            UTCDateTime			utc;

            sscanf(record[2], "%4ld-%02hd-%02hd %02hd:%02hd:%02lf", &gdate.year, (signed short*)&gdate.month, (signed short*)&gdate.day,
                   (signed short*)&gdate.hour, (signed short*)&gdate.minute, &gdate.second);
            tz = CFTimeZoneCopySystem();
            abstime = CFGregorianDateGetAbsoluteTime(gdate, tz);
            UCConvertCFAbsoluteTimeToUTCDateTime(abstime, &utc);
            catalogInfo.contentModDate = utc;

            strcpy(s_tempstr, x->temp_fullpath->s_name);
            temppath = strchr(s_tempstr, ':');
            temppath++;
            strcat(temppath, "/");
            strcat(temppath, record[1]);
            FSPathMakeRef((UInt8*)temppath, &ref, &isDir);
            err = FSSetCatalogInfo(&ref, kFSCatInfoContentMod, &catalogInfo);

#else // WIN_VERSION
            char				winpath[512];
            HANDLE				hFile;
            FILETIME			fileTime;
            SYSTEMTIME			systemTime;

            sscanf(record[2], "%4lu-%02lu-%02lu %02lu:%02lu:%02lu", &systemTime.wYear, &systemTime.wMonth, &systemTime.wDay,
                   &systemTime.wHour, &systemTime.wMinute, &systemTime.wSecond);
            err = SystemTimeToFileTime(&systemTime, &fileTime);

            strcpy(s_tempstr, x->temp_fullpath->s_name);
            path_nameconform(s_tempstr, winpath, PATH_STYLE_NATIVE_WIN, PATH_TYPE_ABSOLUTE);
            strcat(winpath, "\\");
            strcat(winpath, record[1]);
            hFile = CreateFile((LPCSTR)winpath , GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
            if(hFile == INVALID_HANDLE_VALUE) {
                object_error((t_object *)x, "invalid handle value");
                goto out;
            }
            err = SetFileTime(hFile, &fileTime, &fileTime, &fileTime);
            if(err == 0) {
                err = GetLastError();
                object_error((t_object *)x, "Error setting date: %i", err);
            }
            CloseHandle(hFile);
out:
            ;
#endif
        }
        object_method(x->sqlite, ps_endtransaction);
    }
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 void AddFolderIcon (FSRef *fref, const char *folderName)
{
	OSStatus			err;
	FSCatalogInfo		fcat, icat;
	FSRef				bref, iref;
	CFStringRef			str;
	CFURLRef			url;
	IconFamilyHandle	family;
	IconRef				icon;
	HFSUniStr255		fork;
	Boolean				r;
	SInt16				resf;
	char				name[64];
	UniChar				iconName[5] = { 'I', 'c', 'o', 'n', '\r' };

	strcpy(name, "folder_");
	strcat(name, folderName);

	str = CFStringCreateWithCString(kCFAllocatorDefault, name, CFStringGetSystemEncoding());
	if (str)
	{
		url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), str, CFSTR("icns"), NULL);
		if (url)
		{
			r = CFURLGetFSRef(url, &bref);
			if (r)
			{
				err = RegisterIconRefFromFSRef('~9X~', 'TEMP', &bref, &icon);
				if (err == noErr)
				{
					err = FSGetResourceForkName(&fork);
					if (err == noErr)
					{
						err = FSCreateResourceFile(fref, 5, iconName, kFSCatInfoNone, NULL, fork.length, fork.unicode, &iref, NULL);
						if (err == noErr)
						{
							err = FSOpenResourceFile(&iref, fork.length, fork.unicode, fsWrPerm, &resf);
							if (err == noErr)
							{
								err = IconRefToIconFamily(icon, kSelectorAllAvailableData, &family);
								if (err == noErr)
								{
									AddResource((Handle) family, 'icns', -16455, "\p");
									WriteResource((Handle) family);
									ReleaseResource((Handle) family);

									err = FSGetCatalogInfo(&iref, kFSCatInfoFinderInfo, &icat, NULL, NULL, NULL);
									((FileInfo *) &icat.finderInfo)->finderFlags |= kIsInvisible;
									((FileInfo *) &icat.finderInfo)->fileCreator = 'MACS';
									((FileInfo *) &icat.finderInfo)->fileType    = 'icon';
									err = FSSetCatalogInfo(&iref, kFSCatInfoFinderInfo, &icat);

									err = FSGetCatalogInfo(fref, kFSCatInfoFinderInfo, &fcat, NULL, NULL, NULL);
									((FolderInfo *) &fcat.finderInfo)->finderFlags |=  kHasCustomIcon;
									((FolderInfo *) &fcat.finderInfo)->finderFlags &= ~kHasBeenInited;
									err = FSSetCatalogInfo(fref, kFSCatInfoFinderInfo, &fcat);
								}

								CloseResFile(resf);
							}
						}
					}
static PyObject *
MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
{
    ResType creator, type;
    FSRef ref;
    FileInfo* finfo;
    OSErr err;
    FSCatalogInfo       cataloginfo;

    if (!PyArg_ParseTuple(args, "O&O&O&",
                    PyMac_GetFSRef, &ref, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) {
#ifndef __LP64__
        /* Try to handle FSSpec arguments, for backward compatibility */
        FSSpec fss;
        FInfo info;

        if (!PyArg_ParseTuple(args, "O&O&O&",
            PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
            return NULL;

        if ((err = FSpGetFInfo(&fss, &info)) != noErr)
            return PyErr_Mac(MacOS_Error, err);

        info.fdCreator = creator;
        info.fdType = type;

        if ((err = FSpSetFInfo(&fss, &info)) != noErr)
            return PyErr_Mac(MacOS_Error, err);
        Py_INCREF(Py_None);
        return Py_None;
#else /* __LP64__ */
        return NULL;
#endif /* __LP64__ */
    }

    err = FSGetCatalogInfo(&ref,
                    kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
                    NULL, NULL, NULL);
    if (err != noErr) {
        PyErr_Mac(MacOS_Error, err);
        return NULL;
    }

    if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
        /* Directory: doesn't have type/creator info.
         *
         * The specific error code is for backward compatibility with
         * earlier versions.
         */
        PyErr_Mac(MacOS_Error, fnfErr);
        return NULL;

    }
    finfo = (FileInfo*)&(cataloginfo.finderInfo);
    finfo->fileCreator = creator;
    finfo->fileType = type;

    err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &cataloginfo);
    if (err != noErr) {
        PyErr_Mac(MacOS_Error, fnfErr);
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}
Example #11
0
OSErr FSExchangeObjectsEmulate(const FSRef *sourceRef, const FSRef *destRef, FSRef *newSourceRef, FSRef *newDestRef) {

	enum {
		/* get all settable info except for mod dates, plus the volume refNum and parent directory ID */
		kGetCatInformationMask = (kFSCatInfoSettableInfo |
								  kFSCatInfoVolume |
								  kFSCatInfoParentDirID) &
		~(kFSCatInfoContentMod | kFSCatInfoAttrMod),
		/* set everything possible except for mod dates */
		kSetCatinformationMask = kFSCatInfoSettableInfo &
		~(kFSCatInfoContentMod | kFSCatInfoAttrMod)
	};

	OSErr          result;
	FSCatalogInfo      sourceCatalogInfo;  /* source file's catalog information */
	FSCatalogInfo      destCatalogInfo;  /* destination file's catalog information */
	HFSUniStr255      sourceName;      /* source file's Unicode name */
	HFSUniStr255      destName;      /* destination file's Unicode name */
	FSRef          sourceCurrentRef;  /* FSRef to current location of source file throughout this function */
	FSRef          destCurrentRef;    /* FSRef to current location of destination file throughout this function */
	FSRef          sourceParentRef;  /* FSRef to parent directory of source file */
	FSRef          destParentRef;    /* FSRef to parent directory of destination file */
	HFSUniStr255      sourceUniqueName;  /* unique name given to source file while exchanging it with destination */
	HFSUniStr255      destUniqueName;    /* unique name given to destination file while exchanging it with source */
	long          theSeed;      /* the seed for generating unique names */
	Boolean          sameParentDirs;    /* true if source and destinatin parent directory is the same */

	/* check parameters */
	require_action((NULL != newSourceRef) && (NULL != newDestRef), BadParameter, result = paramErr);

	/* output refs and current refs = input refs to start with */
	memcpy(newSourceRef, sourceRef, sizeof(FSRef));
	memcpy(&sourceCurrentRef, sourceRef, sizeof(FSRef));

	memcpy(newDestRef, destRef, sizeof(FSRef));
	memcpy(&destCurrentRef, destRef, sizeof(FSRef));

	/* Note: The compatibility case won't work for files with *Btree control blocks. */
	/* Right now the only *Btree files are created by the system. */

	/* get all catalog information and Unicode names for each file */
	result = FSGetCatalogInfo(&sourceCurrentRef, kGetCatInformationMask, &sourceCatalogInfo, &sourceName, NULL, &sourceParentRef);
	require_noerr(result, SourceFSGetCatalogInfoFailed);

	result = FSGetCatalogInfo(&destCurrentRef, kGetCatInformationMask, &destCatalogInfo, &destName, NULL, &destParentRef);
	require_noerr(result, DestFSGetCatalogInfoFailed);

	/* make sure source and destination are on same volume */
	require_action(sourceCatalogInfo.volume == destCatalogInfo.volume, NotSameVolume, result = diffVolErr);

	/* make sure both files are *really* files */
	require_action((0 == (sourceCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) &&
				   (0 == (destCatalogInfo.nodeFlags & kFSNodeIsDirectoryMask)), NotAFile, result = notAFileErr);

	/* generate 2 names that are unique in both directories */
	theSeed = 0x4a696d4c;  /* a fine unlikely filename */

	result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &sourceUniqueName);
	require_noerr(result, GenerateUniqueHFSUniStr1Failed);

	result = GenerateUniqueHFSUniStr(&theSeed, &sourceParentRef, &destParentRef, &destUniqueName);
	require_noerr(result, GenerateUniqueHFSUniStr2Failed);

	/* rename sourceCurrentRef to sourceUniqueName */
	result = FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef);
	require_noerr(result, FSRenameUnicode1Failed);
	memcpy(&sourceCurrentRef, newSourceRef, sizeof(FSRef));

	/* rename destCurrentRef to destUniqueName */
	result = FSRenameUnicode(&destCurrentRef, destUniqueName.length, destUniqueName.unicode, kTextEncodingUnknown, newDestRef);
	require_noerr(result, FSRenameUnicode2Failed);
	memcpy(&destCurrentRef, newDestRef, sizeof(FSRef));

	/* are the source and destination parent directories the same? */
	sameParentDirs = ( sourceCatalogInfo.parentDirID == destCatalogInfo.parentDirID );
	if ( !sameParentDirs )
	{
		/* move source file to dest parent directory */
		result = FSMoveObject(&sourceCurrentRef, &destParentRef, newSourceRef);
		require_noerr(result, FSMoveObject1Failed);
		memcpy(&sourceCurrentRef, newSourceRef, sizeof(FSRef));

		/* move dest file to source parent directory */
		result = FSMoveObject(&destCurrentRef, &sourceParentRef, newDestRef);
		require_noerr(result, FSMoveObject2Failed);
		memcpy(&destCurrentRef, newDestRef, sizeof(FSRef));
	}

	/* At this point, the files are in their new locations (if they were moved). */
	/* The source file is named sourceUniqueName and is in the directory referred to */
	/* by destParentRef. The destination file is named destUniqueName and is in the */
	/* directory referred to by sourceParentRef. */

	/* give source file the dest file's catalog information except for mod dates */
	result = FSSetCatalogInfo(&sourceCurrentRef, kSetCatinformationMask, &destCatalogInfo);
	require_noerr(result, FSSetCatalogInfo1Failed);

	/* give dest file the source file's catalog information except for mod dates */
	result = FSSetCatalogInfo(&destCurrentRef, kSetCatinformationMask, &sourceCatalogInfo);
	require_noerr(result, FSSetCatalogInfo2Failed);

	/* rename source file with dest file's name */
	result = FSRenameUnicode(&sourceCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newSourceRef);
	require_noerr(result, FSRenameUnicode3Failed);
	memcpy(&sourceCurrentRef, newSourceRef, sizeof(FSRef));

	/* rename dest file with source file's name */
	result = FSRenameUnicode(&destCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newDestRef);
	require_noerr(result, FSRenameUnicode4Failed);

	/* we're done with no errors, so swap newSourceRef and newDestRef */
	memcpy(newSourceRef, newDestRef, sizeof(FSRef));
	memcpy(newDestRef, &sourceCurrentRef, sizeof(FSRef));

	return ( result );

	/**********************/

	/* If there are any failures while emulating FSExchangeObjects, attempt to reverse any steps */
	/* already taken. In any case, newSourceRef and newDestRef will refer to the files in whatever */
	/* state and location they ended up in so that both files can be found by the calling code. */

FSRenameUnicode4Failed:

		/* attempt to rename source file to sourceUniqueName */
		if ( noErr == FSRenameUnicode(&sourceCurrentRef, sourceUniqueName.length, sourceUniqueName.unicode, kTextEncodingUnknown, newSourceRef) )
		{
			memcpy(&sourceCurrentRef, newSourceRef, sizeof(FSRef));
		}

FSRenameUnicode3Failed:

		/* attempt to restore dest file's catalog information */
		verify_noerr(FSSetCatalogInfo(&destCurrentRef, kFSCatInfoSettableInfo, &destCatalogInfo));

FSSetCatalogInfo2Failed:

		/* attempt to restore source file's catalog information */
		verify_noerr(FSSetCatalogInfo(&sourceCurrentRef, kFSCatInfoSettableInfo, &sourceCatalogInfo));

FSSetCatalogInfo1Failed:

		if ( !sameParentDirs )
		{
			/* attempt to move dest file back to dest directory */
			if ( noErr == FSMoveObject(&destCurrentRef, &destParentRef, newDestRef) )
			{
				memcpy(&destCurrentRef, newDestRef, sizeof(FSRef));
			}
		}

FSMoveObject2Failed:

		if ( !sameParentDirs )
		{
			/* attempt to move source file back to source directory */
			if ( noErr == FSMoveObject(&sourceCurrentRef, &sourceParentRef, newSourceRef) )
			{
				memcpy(&sourceCurrentRef, newSourceRef, sizeof(FSRef));
			}
		}

FSMoveObject1Failed:

		/* attempt to rename dest file to original name */
		verify_noerr(FSRenameUnicode(&destCurrentRef, destName.length, destName.unicode, destCatalogInfo.textEncodingHint, newDestRef));

FSRenameUnicode2Failed:

		/* attempt to rename source file to original name */
		verify_noerr(FSRenameUnicode(&sourceCurrentRef, sourceName.length, sourceName.unicode, sourceCatalogInfo.textEncodingHint, newSourceRef));

FSRenameUnicode1Failed:
GenerateUniqueHFSUniStr2Failed:
GenerateUniqueHFSUniStr1Failed:
NotAFile:
NotSameVolume:
DestFSGetCatalogInfoFailed:
SourceFSGetCatalogInfoFailed:
BadParameter:

		return ( result );
}