filealias.c

Go to the documentation of this file.
00001 
00002 /*  $Id: filealias.c 1209 2006-04-05 23:59:59Z karstenw $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 /******************************************************************************
00029 **
00030 **  Project Name:   LDRProjects
00031 **     File Name:   MAF.c
00032 **
00033 **   Description:   New C routine for creating alias files given source &
00034 **                  destination FSSpecs
00035 **
00036 *******************************************************************************
00037 **                       A U T H O R   I D E N T I T Y
00038 *******************************************************************************
00039 **
00040 **  Initials    Name
00041 **  --------    -----------------------------------------------
00042 **  LDR         Leonard Rosenthol
00043 **  LSR         Larry Rosenstein
00044 **
00045 *******************************************************************************
00046 **                      R E V I S I O N   H I S T O R Y
00047 *******************************************************************************
00048 **
00049 **    Date      Time    Author  Description
00050 **  --------    -----   ------  ---------------------------------------------
00051 **  09/03/91    21:01   LDR     Installed latest version from LSR
00052 **  09/02/91    20:36   LDR     Moved into separate file
00053 **                      LSR     Original version
00054 **
00055 ******************************************************************************/
00056 
00057 #include "frontier.h"
00058 #include "standard.h"
00059 
00060 #include "filealias.h"
00061 #include "error.h"
00062 #include "resources.h"
00063 #include "file.h"
00064 #include "filesystem7.h"
00065 
00066 
00067 typedef struct {
00068     OSType      folderType;
00069     OSType      aliasType;
00070 } MappingEntry;
00071 
00072 
00073 #define kNumIconTypes 6
00074 #define kNumFolders 9
00075 
00076 
00077     // Resource ID used for alias file's icon (when needed)
00078     
00079 #define kCustomAliasIconID -16496
00080 
00081 
00082     // Forward declarations
00083     
00084 static Boolean FSpIsVolume(const FSSpec* fsSpec);
00085 static Boolean FSpIsFolder(const FSSpec* fsSpec, long* dirID, unsigned short* fdFlags);
00086 static Boolean CopyCustomIcons(const FSSpec* source, short sourceID,
00087                             short destRefnum, short destID);
00088 static Boolean CopyDriverIcon(const FSSpec* volSpec, short destRefnum, short destID);
00089 static OSErr DetermineAliasInfo(const FSSpec* fsSpec, OSType* creator, OSType* fType,
00090                             Boolean* gotCustom, FSSpec* iconSpec, short* rsrcID, unsigned short* fdFlags);
00091 
00092 
00093 #if 0
00094     todo:
00095         different kinds of disks (servers, floppies, ...)
00096         filesharing?
00097 #endif
00098 
00099 
00100 static pascal OSErr CreateAliasFile(const FSSpec* targetFile, const FSSpec* aliasFile) {
00101     
00102     /*
00103     3.0.2b1 dmb: grab target's finfo flags and carry over label index
00104     */
00105     
00106     OSType          fileCreator, fileType;
00107     FSSpec          iconSpec;
00108     Boolean         gotCustom;
00109     short           rsrcID;
00110     short           aliasRefnum;
00111     AliasHandle     alias;
00112     unsigned short  targetflags;
00113     FInfo           finf;
00114     
00115         // Get type/creator for alias file & custom icon file spec
00116     OSErr err = DetermineAliasInfo(targetFile, &fileCreator, &fileType, 
00117                                             &gotCustom, &iconSpec, &rsrcID, &targetflags);
00118     if (err != noErr) return err;
00119     
00120         // Create the alias file (it must not exist already)
00121     FSpCreateResFile(aliasFile, fileCreator, fileType, 0);
00122     err = ResError();
00123     if (err != noErr) return err;
00124 
00125         // Create the alias handle
00126     err = NewAlias(aliasFile, targetFile, &alias);
00127     if (err != noErr || alias == NULL) return err;
00128     
00129     aliasRefnum = FSpOpenResFile(aliasFile, fsRdWrPerm);
00130     // should exist because it was just created
00131     
00132         // Add the alias handle to alias file
00133     AddResource((Handle)alias, rAliasType, 0, "\p");
00134     err = ResError();
00135     
00136         // Copy custom icons (if necessary)
00137     if (gotCustom)
00138         gotCustom = CopyCustomIcons(&iconSpec, rsrcID, aliasRefnum, kCustomAliasIconID);
00139         
00140     if (!gotCustom && FSpIsVolume(targetFile))  // must get icon from disk driver
00141         gotCustom = CopyDriverIcon(targetFile, aliasRefnum, kCustomAliasIconID);
00142         
00143     CloseResFile(aliasRefnum);
00144 
00145     FSpGetFInfo(aliasFile, &finf);
00146     
00147     finf.fdCreator = fileCreator;
00148     finf.fdType = fileType;
00149     finf.fdFlags |= 0x8000;     // set alias bit
00150     if (gotCustom)
00151         finf.fdFlags |= 0x0400; // set custom icon bit
00152     finf.fdFlags &= (~0x0100);  // clear inited
00153     
00154     finf.fdFlags |= (targetflags & 0x000E); //grab label index
00155     
00156     FSpSetFInfo(aliasFile, &finf);
00157 
00158     return noErr;
00159 }
00160 
00161 
00162     // Returns true if fsSpec refers to a volume
00163     
00164 static Boolean FSpIsVolume(const FSSpec* fsSpec)
00165 {
00166     return fsSpec->parID == 1;
00167 }
00168 
00169     // Returns true if fsSpec refers to a folder; also returns folder's dirID & finder flags
00170     
00171 static Boolean FSpIsFolder(const FSSpec* fsSpec, long* dirID, unsigned short* fdFlags)
00172 {
00173     CInfoPBRec pb;
00174 
00175     if (FSpIsVolume(fsSpec)) return false;
00176     
00177     pb.dirInfo.ioNamePtr = (StringPtr)&fsSpec->name;
00178     pb.dirInfo.ioVRefNum = fsSpec->vRefNum;
00179     pb.dirInfo.ioFDirIndex = 0;
00180     pb.dirInfo.ioDrDirID = fsSpec->parID;
00181     
00182     if (PBGetCatInfoSync(&pb) != noErr) return false;
00183     
00184     *dirID = pb.dirInfo.ioDrDirID;
00185     *fdFlags = pb.dirInfo.ioDrUsrWds.frFlags;
00186     
00187     return (pb.dirInfo.ioFlAttrib & 0x10) != 0;
00188 }
00189 
00190 
00191     // Copies all icon resources from indicated source file (using indicated rsrc ID to (already
00192     // opened) destination file (using destID).  source->vRefNum == 0 implies system resource file
00193     // Returns true if an icon was added to the destination.
00194     // (Doesn't work if source == destination.)
00195     
00196 static Boolean CopyCustomIcons(const FSSpec* source, short sourceID,
00197                             short destRefnum, short destID)
00198 {
00199     short       iconRefnum;
00200     char*       table = "ICN#icl4icl8ics#ics4ics8";
00201     OSType*     p;
00202     Boolean     copiedSomething = false;
00203     int         i;
00204     OSErr       err;
00205     
00206     if (source->vRefNum != 0)
00207         iconRefnum = FSpOpenResFile(source, fsRdPerm);
00208     else
00209         iconRefnum = 0; // system resource file
00210         
00211     if (iconRefnum != -1) {
00212         for (i = 0, p = (OSType*)table; i < kNumIconTypes; i++, p++)
00213         {
00214             Handle h;
00215             
00216             UseResFile(iconRefnum);
00217             h = Get1Resource(*p, sourceID);
00218             
00219             if (h != NULL) {
00220                 DetachResource(h);
00221                 
00222                 UseResFile(destRefnum);
00223                 AddResource(h, *p, destID, "\p");
00224                 err = ResError();
00225 
00226                 if (err != noErr)
00227                     DisposeHandle(h);
00228                 else
00229                     copiedSomething = true;
00230             }
00231         }
00232         
00233         if (iconRefnum != 0)
00234             CloseResFile(iconRefnum);
00235     }
00236     
00237     return copiedSomething;
00238 }
00239 
00240 
00241     // Copies all icon resources from indicated source file (using indicated rsrc ID to (already
00242     // opened) destination file (using destID).  source->vRefNum == 0 implies system resource file
00243     // Returns true if an icon was added to the destination.
00244     // (Doesn't work if source == destination.)
00245     
00246 static Boolean CopyDriverIcon(const FSSpec* volSpec, short destRefnum, short destID)
00247 {
00248     
00249     //Code change by Timothy Paustian Monday, June 19, 2000 10:36:34 PM
00250     //I am getting rid of this routine. We will see if it is called - This does get called
00251     //by the file verb, make alias. We could use a script to do this, there has to be a better way.
00252     //check call. I think this is just not going to be implemented in the carbon version.
00253     //not a big deal IMHO.
00254     #if TARGET_API_MAC_CARBON == 1
00255     #pragma unused(volSpec)
00256     #pragma unused(destRefnum)
00257     #pragma unused(destID)
00258     return false;
00259     #else
00260         
00261     HParamBlockRec  pb;
00262     ParamBlockRec   cpb;
00263     OSErr           err;
00264     Handle          h;
00265 
00266     if (!FSpIsVolume(volSpec))
00267         return false;
00268 
00269     pb.volumeParam.ioNamePtr = NULL;
00270     pb.volumeParam.ioVRefNum = volSpec->vRefNum;
00271     pb.volumeParam.ioVolIndex = 0;
00272 
00273     err = PBHGetVInfoSync(&pb);
00274 
00275     if (err != noErr)
00276         return false;
00277 
00278     // set up for Control call
00279     cpb.cntrlParam.ioCRefNum = pb.volumeParam.ioVDRefNum;
00280     cpb.cntrlParam.ioVRefNum = pb.volumeParam.ioVDrvInfo;
00281     
00282         // first try csCode 22
00283     cpb.cntrlParam.csCode = 22;
00284     
00285     err = PBControlSync (&cpb);
00286     
00287     if (err != noErr) {
00288             // try csCode 21;
00289         cpb.cntrlParam.csCode = 21;
00290         err = PBControlSync(&cpb);
00291     }
00292     
00293     if (err != noErr) return false;
00294 
00295     h = NewHandle(kLargeIconSize);      // size of ICN#
00296     if (h == NULL) return false;
00297     
00298         // copy ICN# into handle
00299     BlockMove(*(Ptr*)&cpb.cntrlParam.csParam, *h, kLargeIconSize);
00300 
00301     UseResFile(destRefnum);
00302     AddResource(h, large1BitMask, destID, "\p");
00303     err = ResError();
00304     
00305     if (err != noErr)
00306         DisposeHandle(h);
00307         
00308     return err == noErr;
00309     #endif
00310         
00311 }
00312 
00313 
00314     // Figures out information about an alias for the indicated file (fsSpec)
00315     // Returns type & creator of file; whether the target has a custom icon (and
00316     //      the file from which to get it, and the resource ID of those icons)
00317     
00318 static OSErr DetermineAliasInfo(const FSSpec* fsSpec, OSType* creator, OSType* fType,
00319                             Boolean* gotCustom, FSSpec* iconSpec, short* rsrcID, unsigned short* fdFlags) {
00320     
00321     /*
00322     3.0.2b1 dmb: return the fdFlags of the target. to minimize code changes, 
00323     we're not dealing with volumes
00324     */
00325     
00326     OSErr err;
00327     long dirID;
00328     FInfo finderStuff;
00329     
00330     *gotCustom = false;
00331     *rsrcID = kCustomIconResource;  // default value
00332     
00333     if (FSpIsVolume(fsSpec)) {
00334             // temporarily, all volumes are given the same type
00335         
00336         *fdFlags = 0; /*lazy -- will lose label info*/
00337         
00338         *creator = 'MACS';
00339         *fType = kContainerHardDiskAliasType; 
00340 
00341         err = FSMakeFSSpec(fsSpec->vRefNum, 2, "\pIcon\015", iconSpec);
00342         
00343         if (err == noErr) // volume has a custom icon file (maybe)
00344             *gotCustom = true;
00345     }
00346     
00347     else {
00348         
00349         if (FSpIsFolder(fsSpec, &dirID, fdFlags)) {
00350             // table mapping special folder ID to alias file type
00351             MappingEntry table[kNumFolders] =
00352             {   { kAppleMenuFolderType,         kAppleMenuFolderAliasType },
00353                 { kControlPanelFolderType,      kControlPanelFolderAliasType },
00354                 { kExtensionFolderType,         kExtensionFolderAliasType },
00355                 { kPreferencesFolderType,       kPreferencesFolderAliasType },
00356                 { kPrintMonitorDocsFolderType,  kPrintMonitorDocsFolderAliasType },
00357                 { kWhereToEmptyTrashFolderType, kContainerTrashAliasType },
00358                 { kTrashFolderType,             kContainerTrashAliasType },
00359                 { kStartupFolderType,           kStartupFolderAliasType },
00360                 { kSystemFolderType,            kSystemFolderAliasType }
00361             };
00362             MappingEntry* p;
00363             int i;
00364             
00365                 // see if original folder has a custom icon
00366             *gotCustom = (*fdFlags & 0x0400) != 0;
00367             if (*gotCustom)
00368                 FSMakeFSSpec(fsSpec->vRefNum, dirID, "\pIcon\015", iconSpec);
00369             
00370             *creator = 'MACS';
00371             *fType = kContainerFolderAliasType;         // default file type for alias file
00372             
00373                     // see if the folder is one of the special ones; if so, modify the file type
00374             for (i=1, p = table; i<=kNumFolders; i++, p++) {
00375                 short foundVRefnum;
00376                 long foundDirID;
00377                 
00378                 err = FindFolder(fsSpec->vRefNum, p->folderType, false, &foundVRefnum, &foundDirID);
00379                 if (err == noErr && foundDirID == dirID) {
00380                     *fType = p->aliasType;
00381                     break;
00382                     }
00383                 }
00384             }
00385         else {  // alias to a file
00386             err = FSpGetFInfo(fsSpec, &finderStuff);
00387             
00388             *fdFlags = finderStuff.fdFlags;
00389             
00390             if (err != noErr) return noErr;
00391             
00392             *creator = finderStuff.fdCreator;
00393             *fType = finderStuff.fdType;
00394             
00395             if (*fType == 'APPL')
00396                 *fType = kApplicationAliasType;     // special case for aliases to applications
00397                 
00398             *gotCustom = (finderStuff.fdFlags & 0x0400) != 0;
00399             if (*gotCustom)
00400                 FSMakeFSSpec(fsSpec->vRefNum, fsSpec->parID, fsSpec->name, iconSpec);
00401             }
00402         }
00403     
00404     return noErr;
00405     }
00406 
00407 
00408 boolean MakeAliasFile (const FSSpec *srcFile, const FSSpec *destFile) {
00409     
00410     
00411     //Code change by Timothy Paustian Tuesday, June 20, 2000 1:41:43 PM
00412     //We don't do no stinking alias in Carbon.
00413     //#if TARGET_API_MAC_CARBON == 1
00414     //#pragma unused(srcFile)
00415     //#pragma unused(destFile)
00416     //return false;
00417     //#else
00418         
00419     long result;
00420     
00421     OSErr err = Gestalt (gestaltAliasMgrAttr, &result);
00422     
00423     if ((err != noErr) || (result == 0))
00424         return (false);
00425     
00426     return (!oserror (CreateAliasFile(srcFile, destFile)));
00427     //#endif
00428         
00429 }
00430 
00431 
00432 

Generated on Wed May 31 18:19:46 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6