Version:
~ [ 10.0 ] ~
** Warning: Cannot open xref database.
1
2 /* $Id: filealias.c,v 1.4 2005/01/11 22:48:05 andreradke Exp $ */
3
4 /******************************************************************************
5
6 UserLand Frontier(tm) -- High performance Web content management,
7 object database, system-level and Internet scripting environment,
8 including source code editing and debugging.
9
10 Copyright (C) 1992-2004 UserLand Software, Inc.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 ******************************************************************************/
27
28 /******************************************************************************
29 **
30 ** Project Name: LDRProjects
31 ** File Name: MAF.c
32 **
33 ** Description: New C routine for creating alias files given source &
34 ** destination FSSpecs
35 **
36 *******************************************************************************
37 ** A U T H O R I D E N T I T Y
38 *******************************************************************************
39 **
40 ** Initials Name
41 ** -------- -----------------------------------------------
42 ** LDR Leonard Rosenthol
43 ** LSR Larry Rosenstein
44 **
45 *******************************************************************************
46 ** R E V I S I O N H I S T O R Y
47 *******************************************************************************
48 **
49 ** Date Time Author Description
50 ** -------- ----- ------ ---------------------------------------------
51 ** 09/03/91 21:01 LDR Installed latest version from LSR
52 ** 09/02/91 20:36 LDR Moved into separate file
53 ** LSR Original version
54 **
55 ******************************************************************************/
56
57 #include "frontier.h"
58 #include "standard.h"
59
60 #include "filealias.h"
61 #include "error.h"
62 #include "resources.h"
63 #include "file.h"
64 #include "filesystem7.h"
65
66
67 typedef struct {
68 OSType folderType;
69 OSType aliasType;
70 } MappingEntry;
71
72
73 #define kNumIconTypes 6
74 #define kNumFolders 9
75
76
77 // Resource ID used for alias file's icon (when needed)
78
79 #define kCustomAliasIconID -16496
80
81
82 // Forward declarations
83
84 static Boolean FSpIsVolume(const FSSpec* fsSpec);
85 static Boolean FSpIsFolder(const FSSpec* fsSpec, long* dirID, unsigned short* fdFlags);
86 static Boolean CopyCustomIcons(const FSSpec* source, short sourceID,
87 short destRefnum, short destID);
88 static Boolean CopyDriverIcon(const FSSpec* volSpec, short destRefnum, short destID);
89 static OSErr DetermineAliasInfo(const FSSpec* fsSpec, OSType* creator, OSType* fType,
90 Boolean* gotCustom, FSSpec* iconSpec, short* rsrcID, unsigned short* fdFlags);
91
92
93 #if 0
94 todo:
95 different kinds of disks (servers, floppies, ...)
96 filesharing?
97 #endif
98
99
100 static pascal OSErr CreateAliasFile(const FSSpec* targetFile, const FSSpec* aliasFile) {
101
102 /*
103 3.0.2b1 dmb: grab target's finfo flags and carry over label index
104 */
105
106 OSType fileCreator, fileType;
107 FSSpec iconSpec;
108 Boolean gotCustom;
109 short rsrcID;
110 short aliasRefnum;
111 AliasHandle alias;
112 unsigned short targetflags;
113 FInfo finf;
114
115 // Get type/creator for alias file & custom icon file spec
116 OSErr err = DetermineAliasInfo(targetFile, &fileCreator, &fileType,
117 &gotCustom, &iconSpec, &rsrcID, &targetflags);
118 if (err != noErr) return err;
119
120 // Create the alias file (it must not exist already)
121 FSpCreateResFile(aliasFile, fileCreator, fileType, 0);
122 err = ResError();
123 if (err != noErr) return err;
124
125 // Create the alias handle
126 err = NewAlias(aliasFile, targetFile, &alias);
127 if (err != noErr || alias == NULL) return err;
128
129 aliasRefnum = FSpOpenResFile(aliasFile, fsRdWrPerm);
130 // should exist because it was just created
131
132 // Add the alias handle to alias file
133 AddResource((Handle)alias, rAliasType, 0, "\p");
134 err = ResError();
135
136 // Copy custom icons (if necessary)
137 if (gotCustom)
138 gotCustom = CopyCustomIcons(&iconSpec, rsrcID, aliasRefnum, kCustomAliasIconID);
139
140 if (!gotCustom && FSpIsVolume(targetFile)) // must get icon from disk driver
141 gotCustom = CopyDriverIcon(targetFile, aliasRefnum, kCustomAliasIconID);
142
143 CloseResFile(aliasRefnum);
144
145 FSpGetFInfo(aliasFile, &finf);
146
147 finf.fdCreator = fileCreator;
148 finf.fdType = fileType;
149 finf.fdFlags |= 0x8000; // set alias bit
150 if (gotCustom)
151 finf.fdFlags |= 0x0400; // set custom icon bit
152 finf.fdFlags &= (~0x0100); // clear inited
153
154 finf.fdFlags |= (targetflags & 0x000E); //grab label index
155
156 FSpSetFInfo(aliasFile, &finf);
157
158 return noErr;
159 }
160
161
162 // Returns true if fsSpec refers to a volume
163
164 static Boolean FSpIsVolume(const FSSpec* fsSpec)
165 {
166 return fsSpec->parID == 1;
167 }
168
169 // Returns true if fsSpec refers to a folder; also returns folder's dirID & finder flags
170
171 static Boolean FSpIsFolder(const FSSpec* fsSpec, long* dirID, unsigned short* fdFlags)
172 {
173 CInfoPBRec pb;
174
175 if (FSpIsVolume(fsSpec)) return false;
176
177 pb.dirInfo.ioNamePtr = (StringPtr)&fsSpec->name;
178 pb.dirInfo.ioVRefNum = fsSpec->vRefNum;
179 pb.dirInfo.ioFDirIndex = 0;
180 pb.dirInfo.ioDrDirID = fsSpec->parID;
181
182 if (PBGetCatInfoSync(&pb) != noErr) return false;
183
184 *dirID = pb.dirInfo.ioDrDirID;
185 *fdFlags = pb.dirInfo.ioDrUsrWds.frFlags;
186
187 return (pb.dirInfo.ioFlAttrib & 0x10) != 0;
188 }
189
190
191 // Copies all icon resources from indicated source file (using indicated rsrc ID to (already
192 // opened) destination file (using destID). source->vRefNum == 0 implies system resource file
193 // Returns true if an icon was added to the destination.
194 // (Doesn't work if source == destination.)
195
196 static Boolean CopyCustomIcons(const FSSpec* source, short sourceID,
197 short destRefnum, short destID)
198 {
199 short iconRefnum;
200 char* table = "ICN#icl4icl8ics#ics4ics8";
201 OSType* p;
202 Boolean copiedSomething = false;
203 int i;
204 OSErr err;
205
206 if (source->vRefNum != 0)
207 iconRefnum = FSpOpenResFile(source, fsRdPerm);
208 else
209 iconRefnum = 0; // system resource file
210
211 if (iconRefnum != -1) {
212 for (i = 0, p = (OSType*)table; i < kNumIconTypes; i++, p++)
213 {
214 Handle h;
215
216 UseResFile(iconRefnum);
217 h = Get1Resource(*p, sourceID);
218
219 if (h != NULL) {
220 DetachResource(h);
221
222 UseResFile(destRefnum);
223 AddResource(h, *p, destID, "\p");
224 err = ResError();
225
226 if (err != noErr)
227 DisposeHandle(h);
228 else
229 copiedSomething = true;
230 }
231 }
232
233 if (iconRefnum != 0)
234 CloseResFile(iconRefnum);
235 }
236
237 return copiedSomething;
238 }
239
240
241 // Copies all icon resources from indicated source file (using indicated rsrc ID to (already
242 // opened) destination file (using destID). source->vRefNum == 0 implies system resource file
243 // Returns true if an icon was added to the destination.
244 // (Doesn't work if source == destination.)
245
246 static Boolean CopyDriverIcon(const FSSpec* volSpec, short destRefnum, short destID)
247 {
248
249 //Code change by Timothy Paustian Monday, June 19, 2000 10:36:34 PM
250 //I am getting rid of this routine. We will see if it is called - This does get called
251 //by the file verb, make alias. We could use a script to do this, there has to be a better way.
252 //check call. I think this is just not going to be implemented in the carbon version.
253 //not a big deal IMHO.
254 #if TARGET_API_MAC_CARBON == 1
255 #pragma unused(volSpec)
256 #pragma unused(destRefnum)
257 #pragma unused(destID)
258 return false;
259 #else
260
261 HParamBlockRec pb;
262 ParamBlockRec cpb;
263 OSErr err;
264 Handle h;
265
266 if (!FSpIsVolume(volSpec)) return false;
267
268 pb.volumeParam.ioNamePtr = NULL;
269 pb.volumeParam.ioVRefNum = volSpec->vRefNum;
270 pb.volumeParam.ioVolIndex = 0;
271
272 err = PBHGetVInfoSync(&pb);
273 if (err != noErr) return false;
274
275 // set up for Control call
276 cpb.cntrlParam.ioCRefNum = pb.volumeParam.ioVDRefNum;
277 cpb.cntrlParam.ioVRefNum = pb.volumeParam.ioVDrvInfo;
278
279 // first try csCode 22
280 cpb.cntrlParam.csCode = 22;
281
282 err = PBControlSync (&cpb);
283
284 if (err != noErr) {
285 // try csCode 21;
286 cpb.cntrlParam.csCode = 21;
287 err = PBControlSync(&cpb);
288 }
289
290 if (err != noErr) return false;
291
292 h = NewHandle(kLargeIconSize); // size of ICN#
293 if (h == NULL) return false;
294
295 // copy ICN# into handle
296 BlockMove(*(Ptr*)&cpb.cntrlParam.csParam, *h, kLargeIconSize);
297
298 UseResFile(destRefnum);
299 AddResource(h, large1BitMask, destID, "\p");
300 err = ResError();
301
302 if (err != noErr)
303 DisposeHandle(h);
304
305 return err == noErr;
306 #endif
307
308 }
309
310
311 // Figures out information about an alias for the indicated file (fsSpec)
312 // Returns type & creator of file; whether the target has a custom icon (and
313 // the file from which to get it, and the resource ID of those icons)
314
315 static OSErr DetermineAliasInfo(const FSSpec* fsSpec, OSType* creator, OSType* fType,
316 Boolean* gotCustom, FSSpec* iconSpec, short* rsrcID, unsigned short* fdFlags) {
317
318 /*
319 3.0.2b1 dmb: return the fdFlags of the target. to minimize code changes,
320 we're not dealing with volumes
321 */
322
323 OSErr err;
324 long dirID;
325 FInfo finderStuff;
326
327 *gotCustom = false;
328 *rsrcID = kCustomIconResource; // default value
329
330 if (FSpIsVolume(fsSpec)) {
331 // temporarily, all volumes are given the same type
332
333 *fdFlags = 0; /*lazy -- will lose label info*/
334
335 *creator = 'MACS';
336 *fType = kContainerHardDiskAliasType; //// need more work here
337
338 err = FSMakeFSSpec(fsSpec->vRefNum, 2, "\pIcon\015", iconSpec);
339
340 if (err == noErr) // volume has a custom icon file (maybe)
341 *gotCustom = true;
342 }
343
344 else {
345
346 if (FSpIsFolder(fsSpec, &dirID, fdFlags)) {
347 // table mapping special folder ID to alias file type
348 MappingEntry table[kNumFolders] =
349 { { kAppleMenuFolderType, kAppleMenuFolderAliasType },
350 { kControlPanelFolderType, kControlPanelFolderAliasType },
351 { kExtensionFolderType, kExtensionFolderAliasType },
352 { kPreferencesFolderType, kPreferencesFolderAliasType },
353 { kPrintMonitorDocsFolderType, kPrintMonitorDocsFolderAliasType },
354 { kWhereToEmptyTrashFolderType, kContainerTrashAliasType },
355 { kTrashFolderType, kContainerTrashAliasType },
356 { kStartupFolderType, kStartupFolderAliasType },
357 { kSystemFolderType, kSystemFolderAliasType }
358 };
359 MappingEntry* p;
360 int i;
361
362 // see if original folder has a custom icon
363 *gotCustom = (*fdFlags & 0x0400) != 0;
364 if (*gotCustom)
365 FSMakeFSSpec(fsSpec->vRefNum, dirID, "\pIcon\015", iconSpec);
366
367 *creator = 'MACS';
368 *fType = kContainerFolderAliasType; // default file type for alias file
369
370 // see if the folder is one of the special ones; if so, modify the file type
371 for (i=1, p = table; i<=kNumFolders; i++, p++) {
372 short foundVRefnum;
373 long foundDirID;
374
375 err = FindFolder(fsSpec->vRefNum, p->folderType, false, &foundVRefnum, &foundDirID);
376 if (err == noErr && foundDirID == dirID) {
377 *fType = p->aliasType;
378 break;
379 }
380 }
381 }
382 else { // alias to a file
383 err = FSpGetFInfo(fsSpec, &finderStuff);
384
385 *fdFlags = finderStuff.fdFlags;
386
387 if (err != noErr) return noErr;
388
389 *creator = finderStuff.fdCreator;
390 *fType = finderStuff.fdType;
391
392 if (*fType == 'APPL')
393 *fType = kApplicationAliasType; // special case for aliases to applications
394
395 *gotCustom = (finderStuff.fdFlags & 0x0400) != 0;
396 if (*gotCustom)
397 FSMakeFSSpec(fsSpec->vRefNum, fsSpec->parID, fsSpec->name, iconSpec);
398 }
399 }
400
401 return noErr;
402 }
403
404
405 boolean MakeAliasFile (const FSSpec *srcFile, const FSSpec *destFile) {
406
407
408 //Code change by Timothy Paustian Tuesday, June 20, 2000 1:41:43 PM
409 //We don't do no stinking alias in Carbon.
410 //#if TARGET_API_MAC_CARBON == 1
411 //#pragma unused(srcFile)
412 //#pragma unused(destFile)
413 //return false;
414 //#else
415
416 long result;
417
418 OSErr err = Gestalt (gestaltAliasMgrAttr, &result);
419
420 if ((err != noErr) || (result == 0))
421 return (false);
422
423 return (!oserror (CreateAliasFile(srcFile, destFile)));
424 //#endif
425
426 }
427
428
429
430
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.