From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Newsgroups: comp.sys.mac.programmer
Subject: Re: Is a resource fork already open?
Date: 8 Sep 92 15:35:20 +1200
Organization: University of Waikato, Hamilton, New Zealand

In article <39464@imag.imag.fr>, cinquin@imag.fr ( Philippe Cinquin) writes:
> Sorry if this is a stupid question, but how do you know if the resource fork of
> a file is already open?

If a file is already open by somebody else, you'll get an error if you try
opening it in a mode that's incompatible with the other person's open mode.

But I suspect you're really asking what happens when you open a resource file
twice from the same application. The answer is, you will get the same file
refnum back the second time. So how do you tell that this is happened? It can
be done, without too much low-level messing about.

The Resource Manager maintains a chain of currently-open resource files.
It loads the "resource map" structure from each file into memory, and fills
in a link field to chain all the resource maps together. There are two
important low-memory globals that are used for this:

	TopMapHndl -- handle to the first resource map in the chain
	CurMap -- refnum of the "current" resource file (returned by
	    CurResFile, can be changed with UseResFile to point anywhere
	    along the chain).

Supposing the state of your resource chain is like this:

	TopMapHndl --> map for res file 2 --> map for res file 1
	CurMap -- don't care

And you open resource file 3, which wasn't previously open. The resource
chain now becomes this:

	TopMapHndl --> map for res file 3 --> map for res file 2 -->
					      map for res file 1
	CurMap -- iorefnum for res file 3

If, on the other hand, you try reopening res file 2, you get this
situation:

	TopMapHndl --> map for res file 2 --> map for res file 1
	CurMap -- iorefnum for res file 2

And if you try reopening res file 1, you get this:

	TopMapHndl --> map for res file 2 --> map for res file 1
	CurMap -- iorefnum for res file 1

In summary:

    * If you open a resource file that wasn't previously open, its
      resource map gets prepended to the top of the chain, and TopMapHndl
      is set to point to it.
    * If you reopen a resource file that was already open, TopMapHndl
      is unchanged.
    * Every time you open a resource file, whether it was previously open
      or not, CurMap is updated to hold the iorefnum of that resource file.

So here's how to tell, when you open a resource file, whether you really
opened it or not. First, some useful definitions (this is all in Modula-2,
by the way):

    TYPE
	IORefNum = INTEGER;

    PROCEDURE GetTopMapHndl() : (*Handle*) ADDRESS;
     (* returns the current value of TopMapHndl global. *)

	CODE
	    02EB8H, 00A50H; (* move.l TopMapHndl, (sp) *)

    PROCEDURE GetTopMap() : IORefNum;
      (* returns the reference number of the last-opened resource file. *)

	VAR
	    TempHandle : Handle;
	    TempPtr : POINTER TO IORefNum;

    BEGIN
	TempHandle := GetTopMapHndl();
	TempPtr := TempHandle^ + 20;
	RETURN
	    TempPtr^
    END GetTopMap;

Now here's an example code fragment that opens a resource file:

      (* get information about current state of resource chain *)
	PreviousResFile := CurResFile();
	PreviousTop := GetTopMap();

      (* open resource file with OpenResFile, OpenRFPerm or whatever, e g *)
	TheResFile := OpenRFPerm(FileName, VRefNum, Permission);

	ReallyOpened :=
		(TheResFile = GetTopMap())
	    AND
		(TheResFile <> PreviousTop)

And to close the resource file (but only if it was really opened by you) and
leave things the way they were before:

	IF ReallyOpened THEN
	    CloseResFile(TheResFile)
	END (*IF*);
	UseResFile(PreviousResFile)

I have successfully used this code to do things to my running system file.
And I haven't had a crash yet. crash yet. crash yet.

Lawrence D'Oliveiro                       fone: +64-7-856-2889
Computer Services Dept                     fax: +64-7-838-4066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
"Well, perhaps that is because Apple has not yet released any future versions
of the System software." -- Amanda Walker