[comp.sys.mac.programmer] Interesting problem whe GetResource

mjohnson@Apple.COM (Mark B. Johnson) (11/16/89)

The following is an original posting and followups to it concerning a
problem with GetResource.  It is long, so press 'n' now if you aren't
interested.  Posted on behalf of Jim Reekes, MacDTS Ethics Officer...

==========================
mac.external/other.nets #104, from lloeb, 5463 chars, Mon Nov 13 09:56:23 1989
--------------------------
From: dolf@fwi.uva.nl (Dolf Starreveld)
Subject: Interesting problem with GetResource('dctb', id)
Message-ID: <232@fwi.uva.nl>
Date: 5 Nov 89 21:03:22 GMT
Sender: news@fwi.uva.nl
Reply-To: dolf@fwi.uva.nl (Dolf Starreveld)
Organization: FWI, University of Amsterdam
Lines: 46
I am currently working on a program that needs to copy a 'dctb' resource
from one file to another. Since the program must also copy other resources
I have written a general purpose "CopyResource" routine. The routine itself
was extensively tested and seemed to work, but .....
The copying of the 'dctb' resource was only recently added and things
started to go wrong. After lots of debugging I found out that after executing
the following statement:
        inHandle = GetResource('dctb', 10000);
"inHandle" contains a valid handle, but not a handle to a resource. I entered
TMON to find out more and:
1)      Just before executing the statement the 'dctb' resource is not
        loaded in the heap.
2)      Just after the statement, the 'dctb' resource is loaded, but
        immediately following it, the heap contains another relocatable
        block of exactly the same size of the resource (48 bytes).
3)      The GetResource call returns a handle to this last block instead
        of to the actually loaded resource.

Since my program continues to do a GetResInfo call on the handle returned,
I get into problems. The handle is not a handle to a resource and the
call sets ResError != 0. Furthermore, the &resID is set to -1 and the
&resType is set to four zero bytes. This is what finally causes another
program using the copied resource file to crash.

I moved the GetResource call to very early in my program (just after ToolBox
initialization), just to be sure the heap was not already corrupt. I also
tried using other values for the ID (100 instead of 10000). The net result
was the same in all cases: two blocks appear on the heap and the wrong
handle is returned to me.

Is this a bug in the system software? Am I doing something wrong?
Any suggestions?

BTW. For those who think it is important, I am using THINK C 4.0 on an
8Mb Mac IIcx, system 6.0.4b15.
Before you start screaming about using 6.0.4b15, you should know that
the problems were already there when I still used 6.0.3. I have not tested
with other versions.

--dolf

Dolf Starreveld  Phone: +31 20 592 5056/+31 20 592 5022, TELEX: 10262 HEF NL
EMAIL:           dolf@fwi.uva.nl (dolf%fwi.uva.nl@hp4nl.nluug.nl)
SNAIL:           Dept. of Math. and Computing Science, University of Amsterdam,
                 Kruislaan 409, NL-1098 SJ  Amsterdam, The Netherlands

From: han@apple.COM (Byron Han, Project Scapegoat)
Subject: Re: Interesting problem with GetResource('dctb', id)
Message-ID: <5058@internal.Apple.COM>
Date: 6 Nov 89 17:32:18 GMT
References: <232@fwi.uva.nl>
Sender: usenet@Apple.COM
Organization: Apple Computer, Inc. - N&C
Lines: 46
In article <232@fwi.uva.nl> dolf@fwi.uva.nl (Dolf Starreveld) writes:
> I have written a general purpose "CopyResource" routine. The routine
itself
> was extensively tested and seemed to work, but .....
>
> <deleted>
>
> Is this a bug in the system software? Am I doing something wrong?
> Any suggestions?

Well, this is kind of a strange quirk in the operating system.

Do this instead:
SetResLoad(FALSE);
hDCTB := GetResource('dctb', foobar);
SetResLoad(TRUE);
LoadResource(hDCTB);

This should work in place of a simple GetResource.

+-------------------------------------------------------------------------+
| Disclaimer: Apple has no connection with my postings.                   |
+-------------------------------------------------------------------------+
Byron Han, CommToolbox Scapegoat    "DeAnza 3 - R.I.P. - 10/17/89 5:04PM"
Apple Computer, Inc.
--------------------------------
20525 Mariani Ave, MS 69L         Internet: han@apple.COM
Cupertino, CA 95014               UUCP:{sun,voder,nsc,decwrl}!apple!han
--------------------------------  GENIE:BYRONHAN   CompuServe:72167,1664
ATTnet: 408-974-6450              Applelink:HAN1   HAN1@applelink.apple.COM
---------------------------------------------------------------------------

From: alan@Apple.COM (Alan Mimms)
Subject: Re: Interesting problem with GetResource('dctb', id)
Message-ID: <5065@internal.Apple.COM>
Date: 6 Nov 89 19:10:18 GMT
References: <232@fwi.uva.nl>
Organization: Apple Computer Inc, Cupertino, CA
Lines: 72
Keywords: ResourceManager 'dctb'/'actb' SpecialCase

In article <232@fwi.uva.nl> dolf@fwi.uva.nl (Dolf Starreveld) writes:
>
>deleted
SOME version of the system software introduced a "feature" in which
'dctb' and 'actb' resources are CLONED when they're retrieved by GetResource
and related calls.  A colleague of mine discovered this recently.  You
MAY be able to get around this with either Get1Resource calls or with
the sequence

        SetResLoad (false);
        GetResource (...);
        SetResLoad (true);
        LoadResource (...);

Anyone in System Software care to comment?

Also, please note that you really SHOULD go ahead an upgrade to 6.0.4
final since there were a few bugs fixed in the last few versions of
6.0.4 after b15 (I THINK).

Hope this helps.
--

Alan Mimms                                      My opinions are generally
Communications Product Development Group        pretty worthless, but
Apple Computer                                  they *are* my own...
"The company has new jobs and Jobs has a new company" -- Harry Anderson



- - - - - - - - - - - - - - - - - - - - - - - - - - -

dolf,

Unfortunately, you've run across a patch to _GetResource that is there
to solve a Dialog Manager problem.  The dctb and actb are color tables
for windows.  This color table resource handle cannot be purged from
memory, but all other Dialog Manager resources are supposed to be
purged.  Normally such resource DITLs, DLOGs, etc. are copied by the
Dialog Manager.  The problem is that the Dialog Manager didn't copy
the dctb or actb, and this lead to dialog window's color table being
purged.

So, a patched to _GetResource was put into place.  When a 'dctb' or
'actb' is fetched, the Resource Manager performs a _HandToHand and
returns this copy.  This is bad because the Resource Manager has
returned a valid handle that is not a resource, and calling
_GetResInfo will fail with resNotFound!  The work around suggested
below works, but I do not recommend it.

SetResLoad(FALSE);
hDCTB := GetResource('dctb', foobar); { <-- this is bad, due to patch}
SetResLoad(TRUE);
LoadResource(hDCTB);

Setting ResLoad to false will not load the resource data but returns a
valid handle that is empty.  (The handle's master pointer is NIL.)
When the patch code is called to perform the _HandToHand, the routine
fails.  The Memory Manager will set D0 to nilHandleErr when
_HandToHand is passed an empty handle.

If you followed _GetResource with _MemError, you will get the result
nilHandleErr.  (BTW The Resource Manager isn't too consistent in
returning errors, and if you called _ResError you would get noErr.)
Therefore, the above code does do what you wanted.  It even looks as
if there's nothing wrong, but it is not a good idea.  It will cause
the Resource Manager patch to pass an empty handle to _HandToHand, and
calling _MemError will verify this.

What I recommend is to use _Get1Resource instead of _GetResource.  The
former does NOT have the patch code mentioned above.  This is because
the Dialog Manager doesn't call _Get1Resource and _Get1Resource
doesn't call _GetResource.  So, the Dialog Manager patch code
containing _HandToHand will not be called if you use _Get1Resource.
This patch is contained in Macs with color and applies to the dctb and
actb only.  I believe this patch was introduced in System 6.0x.

Jim Reekes E.O., Macintosh Developer Technical Support
Wednesday, November 15, 1989  7:16 PM

"I think I'm getting a headache."

-- 
Mark B. Johnson                                            AppleLink: mjohnson
Developer Technical Support                         domain: mjohnson@Apple.com
Apple Computer, Inc.         UUCP:  {amdahl,decwrl,sun,unisoft}!apple!mjohnson

"You gave your life to become the person you are right now.  Was it worth it?"
                                                         - Richard Bach, _One_

amanda@intercon.com (Amanda Walker) (11/16/89)

In article <36530@apple.Apple.COM>, mjohnson@Apple.COM (Mark B. Johnson)
writes:
> Unfortunately, you've run across a patch to _GetResource that is there
> to solve a Dialog Manager problem.

Bleah.  The least you folks could have done is to make it a come-from
patch, so it only compensated for the Dialog Manager, and not the rest
of us :-)...

Amanda Walker <amanda@intercon.com>
--