Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hoptoad!tim From: tim@hoptoad.uucp (Tim Maroney) Newsgroups: comp.sys.mac.programmer Subject: Re: Moving resources into the system file Message-ID: <8065@hoptoad.uucp> Date: 19 Jul 89 23:03:44 GMT References: <1230@uvm-gen.UUCP> Reply-To: tim@hoptoad.UUCP (Tim Maroney) Distribution: na Organization: Eclectic Software, San Francisco Lines: 91 Yum, this was a meaty one. In article <1230@uvm-gen.UUCP> chaffee@uvm-gen.UUCP (Alex D. Chaffee,231 Votey,,6581273) writes: >I "pack" a resource from another file into the (open) System file. Using my >"Get info" command assures me that it is intact. I quit the program and >immediately restart it. I open the System file again, do a get info, and >bang! The resource is corrupt. The name and ID are fine, but >SizeResource() returns -113. Yes, negative 113, or -111, or some >arbitrarily huge number. ResEdit doesn't like it either. But if I open >ResEdit after "packing" but before quitting (I'm using MultiFinder) and open >the resource, it looks fine; then if I quit both and rerun Valet, _the >resource _is_ fine_. Apparently ResEdit knows how to save the resource, but >I don't. > >This only happens under MultiFinder. Under Finder, packing, quitting and >restarting works perfectly. First, I want to thank you for describing your system configuration and development system, an important step that most people omit. >The program flow of "Packing" consists of: >for ( [every resource] ) >{ [check if it exists] > UseResFile(fileToPack); > SetResLoad(TRUE); > LoadResource(theItem->H); if (ResError()) ... > DetachResource(theItem->H); if (ResError()) ... > HNoPurge(theItem->H); > UseResFile(masterFile); > AddResource(theItem->H, theItem->species, newID, newName); > if (ResError()) ... > WriteResource(theItem->H); if (ResError()) ... >} >[erase internal data structure, without touching the resource handles] >CloseResFile(fileToPack); >UpdateResFile(masterFile); OK, I think I see the problem. Do a ReleaseResource after the WriteResource. What seems to be happening is that under MultiFinder, ExitToShell is not releasing application-specific copies of the system file resources. Therefore, when you quit, the resources are trashed, being in an invalid heap. (Actually, the trashing probably happens the next time you launch a program.) Since you have already done the WriteResource, there should not be a problem from the ReleaseResource, and it should cause the resource to be re-fetched from the system file when someone else wants to use it. ExitToShell *should* be releasing application-heap copies of the system file resources under MultiFinder. I know it does under UniFinder. However, if you think about it, there must be some sort of weird special casing involved. There's a dearth of internal information on MultiFinder, but a little poking with MacsBug reveals that different applications each have their own copy of the system resource map. So one would think that changes made to the system file from one application would invalidate other maps, and they'd have to be automatically refreshed somehow. If they weren't refreshed, their file indices would be bad, for one thing. So suppose this refreshing happens on your AddResource or WriteResource -- then when the other maps get refreshed, something has to fill in the new resource slots in their resource maps. If this is just the copy of the resource in your application heap, then everybody gets a handle into your app. heap inserted in their system resource map. When that heap dies, then their copies are trashed. ReleaseResource might work if it goes and changes everyone's copy, but not otherwise. I notice that if you close the window with ResEdit, then the resource saves OK -- note that ResEdit does do a ReleaseResource when it closes a resource window, so that would seem to indicate that doing your own ReleaseResource will do the trick. This is all out in outer space as far as degree of speculation goes, but it seems to be consistent with your symptoms. The upshot seems to be that you shouldn't make any changes to the system resource file from your application, because the undocumented nature of all this stuff makes whatever you do likely to break. There's no really good reason for anyone but the Font/DA Mover and ResEdit to make system file changes, so why don't you just have Valet refuse to mess with the system file? PS. Your AddResource will add a duplicate if the resource already exists in the target file. You should check for its existence first, then remove it if it exists. (You could also resize it and copy the source resource into the resized handle, but that wouldn't fit the way you've coded this very well.) -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com "Everything that gives us pleasure gives us pain to measure it by." -- The Residents, GOD IN THREE PERSONS