Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: More Macintosh Toolbox /
Chapter 1 - Resource Manager / Resource Manager Reference
Resource Manager Routines / Opening Resource Forks


You can use the FSpOpenResFile function to open a file's resource fork using a file system specification (FSSpec) record.

FUNCTION FSpOpenResFile (spec: FSSpec; 
                         permission: SignedByte): Integer;
A file system specification record specifying the name and location of the file whose resource fork is to be opened.
A value that specifies a read/write permission combination.
The FSpOpenResFile function opens the resource fork of the file identified by the spec parameter. It also makes this file the current resource file.

This function is available only in System 7 and later versions of system software. If FSpOpenResFile is not available to your application, you can use HOpenResFile, OpenRFPerm, or OpenResFile instead.

The spec parameter is a file system specification record, which is a standard format in System 7 and later versions for identifying a file or directory. The file system specification record for files and directories is defined by the FSSpec data type.

TYPE FSSpec = {file system specification}
      vRefNum: Integer;    {volume reference number}
      parID:   LongInt;    {directory ID of parent directory}
      name:    Str63;      {filename or directory name}
You can specify the access path permission for the resource fork by setting the permission parameter to one of these constants:

   fsCurPerm   = 0; {whatever is currently allowed}
   fsRdPerm    = 1; {read-only permission}
   fsWrPerm    = 2; {write permission}
   fsRdWrPerm  = 3; {exclusive read/write permission}
   fsRdWrShPerm= 4; {shared read/write permission}
Use fsCurPerm to request whatever permission is currently allowed. If write access is unavailable (because the file is locked or because the resource fork is already open with write access), then read permission is granted. Otherwise, read/write permission is granted.

Use fsRdPerm to request permission to read the file, and fsWrPerm to write to it. If write permission is granted, no other access paths are granted write permission. Because the File Manager doesn't support write-only access to a file, fsWrPerm is synonymous with fsRdWrShPerm.

Use fsRdWrPerm and fsRdWrShPerm to request exclusive or shared read/write permission, respectively. If your application is granted exclusive read/write permission, no users are granted permission to write to the file; other users may, however, be granted permission to read the file. Shared read/write permission allows multiple access paths for writing and reading.

The Resource Manager reads the resource map from the specified file's resource fork into memory. It also reads into memory every resource in the resource fork whose resPreload attribute is set.

The FSpOpenResFile function returns a file reference number for the resource fork. You can use this reference number to refer to the resource fork in other Resource Manager routines.

If you attempt to use FSpOpenResFile to open a resource fork that is already open, FSpOpenResFile returns the existing file reference number or a new one, depending on the access permission for the existing access path. For example, your application receives a new file reference number after a successful request for read-only access to a file previously opened with write access, whereas it receives the same file reference number in response to a second request for write access to the same file. In this case, FSpOpenResFile doesn't make that file the current resource file.

If the FSpOpenResFile function fails to open the specified file's resource fork (for instance, because there's no file with the given file system specification record or because there are permission problems), it returns -1 as the file reference number. Use the ResError function to determine what kind of error occurred.

You don't have to call FSpOpenResFile to open the System file's resource fork or an application file's resource fork. These resource forks are opened automatically when the system and the application start up, respectively. To get the file reference number for your application, call the CurResFile function after your application starts up and before you open any other resource forks.

The FSpOpenResFile function checks that the information in the resource map is internally consistent. If it isn't, ResError returns the result code mapReadErr.

To open a resource fork just for block-level operations, such as copying files without reading the resource map into memory, use the File Manager function OpenRF.

The FSpOpenResFile function may move or purge memory blocks in the application heap. Your application should not call this function at interrupt time.

It's possible to create multiple, unique, read-only access paths to a resource fork using FSpOpenResFile; however, you should avoid doing so. If a resource fork is opened twice--once with read/write permission and once with read-only permission--two copies of the resource map exist in memory. If you change one of the resources in memory using one of the resource maps, the two resource maps become inconsistent and the file will appear damaged to the second resource map.

If you must use this technique for read-only access, call FSpOpenResFile immediately before your application reads information from the file and close the file immediately afterward. Otherwise, your application may get unexpected results.

If an application attempts to open a second access path with write access and the application is different from the one that originally opened the resource fork, FSpOpenResFile returns -1, and the ResError function returns the result code opWrErr.

If you want to open the resource fork for another application (or any resource fork other than your application's that includes 'CODE' resources), you must bracket your calls to FSpOpenResFile with calls to SetResLoad with the load parameter set to FALSE and then to TRUE. You must also avoid making intersegment calls while the other application's resource fork is open. If you don't do this, the Segment Loader Manager treats any preloaded 'CODE' resources as your code resources when you make an intersegment call that triggers a call to LoadSeg while the other application is first in the resource chain. In this case, your application can begin executing the other application's code, and severe problems will ensue. If you need to get 'CODE' resources from the other application's resource fork, you can still prevent the Segment Loader Manager problem by calling UseResFile with your application's file reference number to make your application the current resource file.

A handle to the resource map for the most recently opened resource fork is stored in the global variable TopMapHndl. The trap macro and routine selector for the FSpOpenResFile are
Trap macroSelector

noErr0No error
nsvErr-35No such volume
ioErr-36I/O error
bdNamErr-37Bad filename or volume name (perhaps zero length)
eofErr-39End of file
tmfoErr-42Too many files open
fnfErr-43File not found
opWrErr-49File already open with write permission
permErr-54Permissions error (on file open)
extFSErr-58Volume belongs to an external file system
memFullErr-108Not enough room in heap zone
dirNFErr-120Directory not found
mapReadErr-199Map inconsistent with operation
To check for errors, call the ResError function as described on page 1-47. For information about using the Gestalt function to determine whether the FSpOpenResFile procedure is available, see "Using the Resource Manager" beginning on page 1-11. For an example of the use of FSpOpenResFile to open a resource fork, see Listing 1-7 on page 1-21.

For information about the CurResFile and UseResFile routines, see page 1-64 and page 1-65, respectively.

For more information about permission parameter constants or the OpenRF function, see Inside Macintosh: Files.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
6 JUL 1996