4 Contains: A robust, general purpose directory copy routine.
6 Version: Technology: MoreFiles
9 Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved.
11 Bugs?: For bug reports, consult the following page on
14 http://developer.apple.com/bugreporter/
19 You may incorporate this sample code into your applications without
20 restriction, though the sample code has been provided "AS IS" and the
21 responsibility for its operation is 100% yours. However, what you are
22 not permitted to do is to redistribute the source as "DSC Sample Code"
23 after having made changes. If you're going to re-distribute the source,
24 we require that you make it clear in the source that the code was
25 descended from Apple Sample Code, but that you've made changes.
28 #ifndef __DIRECTORYCOPY__
29 #define __DIRECTORYCOPY__
39 #include "Optimization.h"
54 #if PRAGMA_STRUCT_ALIGN
55 #pragma options align=mac68k
56 #elif PRAGMA_STRUCT_PACKPUSH
58 #elif PRAGMA_STRUCT_PACK
62 /*****************************************************************************/
65 getNextItemOp
= 1, /* couldn't access items in this directory - no access privileges */
66 copyDirCommentOp
= 2, /* couldn't copy directory's Finder comment */
67 copyDirAccessPrivsOp
= 3, /* couldn't copy directory's AFP access privileges */
68 copyDirFMAttributesOp
= 4, /* couldn't copy directory's File Manager attributes */
69 dirCreateOp
= 5, /* couldn't create destination directory */
70 fileCopyOp
= 6 /* couldn't copy file */
74 /*****************************************************************************/
76 typedef CALLBACK_API( Boolean
, CopyErrProcPtr
)(OSErr error
, short failedOperation
, short srcVRefNum
, long srcDirID
, ConstStr255Param srcName
, short dstVRefNum
, long dstDirID
, ConstStr255Param dstName
);
78 This is the prototype for the CopyErrProc function DirectoryCopy
79 calls if an error condition is detected sometime during the copy. If
80 CopyErrProc returns false, then DirectoryCopy attempts to continue with
81 the directory copy operation. If CopyErrProc returns true, then
82 DirectoryCopy stops the directory copy operation.
84 error input: The error result code that caused CopyErrProc to
86 failedOperation input: The operation that returned an error to
88 srcVRefNum input: Source volume specification.
89 srcDirID input: Source directory ID.
90 srcName input: Source file or directory name, or nil if
91 srcDirID specifies the directory.
92 dstVRefNum input: Destination volume specification.
93 dstDirID input: Destination directory ID.
94 dstName input: Destination file or directory name, or nil if
95 dstDirID specifies the directory.
99 Also see: FilteredDirectoryCopy, FSpFilteredDirectoryCopy, DirectoryCopy, FSpDirectoryCopy
101 #define CallCopyErrProc(userRoutine, error, failedOperation, srcVRefNum, srcDirID, srcName, dstVRefNum, dstDirID, dstName) \
102 (*(userRoutine))((error), (failedOperation), (srcVRefNum), (srcDirID), (srcName), (dstVRefNum), (dstDirID), (dstName))
104 /*****************************************************************************/
106 typedef CALLBACK_API( Boolean
, CopyFilterProcPtr
)(const CInfoPBRec
* cpbPtr
);
108 This is the prototype for the CopyFilterProc function called by
109 FilteredDirectoryCopy and GetLevelSize. If true is returned,
110 the file/folder is included in the copy, otherwise it is excluded.
112 pb input: Points to the CInfoPBRec for the item under consideration.
116 Also see: FilteredDirectoryCopy, FSpFilteredDirectoryCopy
118 #define CallCopyFilterProc(userRoutine, cpbPtr) \
119 (*(userRoutine))((cpbPtr))
121 /*****************************************************************************/
124 FilteredDirectoryCopy(
127 ConstStr255Param srcName
,
130 ConstStr255Param dstName
,
131 ConstStr255Param copyName
,
132 void * copyBufferPtr
,
135 CopyErrProcPtr copyErrHandler
,
136 CopyFilterProcPtr copyFilterProc
);
140 The FilteredDirectoryCopy function makes a copy of a directory
141 structure in a new location. If copyBufferPtr <> NIL, it points to
142 a buffer of copyBufferSize that is used to copy files data. The
143 larger the supplied buffer, the faster the copy. If
144 copyBufferPtr = NIL, then this routine allocates a buffer in the
145 application heap. If you pass a copy buffer to this routine, make
146 its size a multiple of 512 ($200) bytes for optimum performance.
148 The optional copyFilterProc parameter lets a routine you define
149 decide what files or directories are copied to the destination.
151 FilteredDirectoryCopy normally creates a new directory *in* the
152 specified destination directory and copies the source directory's
153 content into the new directory. However, if root parent directory
154 (fsRtParID) is passed as the dstDirID parameter and NULL is
155 passed as the dstName parameter, DirectoryCopy renames the
156 destination volume to the source directory's name (truncating
157 if the name is longer than 27 characters) and copies the source
158 directory's content into the destination volume's root directory.
159 This special case is supported by FilteredDirectoryCopy, but
160 not by FSpFilteredDirectoryCopy since with FSpFilteredDirectoryCopy,
161 the dstName parameter can not be NULL.
163 srcVRefNum input: Source volume specification.
164 srcDirID input: Source directory ID.
165 srcName input: Source directory name, or nil if
166 srcDirID specifies the directory.
167 dstVRefNum input: Destination volume specification.
168 dstDirID input: Destination directory ID.
169 dstName input: Destination directory name, or nil if
170 dstDirID specifies the directory.
171 copyName input: Points to the new directory name if the directory
172 is to be renamed or nil if the directory isn't to
174 copyBufferPtr input: Points to a buffer of copyBufferSize that
175 is used the i/o buffer for the copy or
176 nil if you want DirectoryCopy to allocate its
177 own buffer in the application heap.
178 copyBufferSize input: The size of the buffer pointed to
180 preflight input: If true, DirectoryCopy makes sure there are
181 enough allocation blocks on the destination
182 volume to hold the directory's files before
184 copyErrHandler input: A pointer to the routine you want called if an
185 error condition is detected during the copy, or
186 nil if you don't want to handle error conditions.
187 If you don't handle error conditions, the first
188 error will cause the copy to quit and
189 DirectoryCopy will return the error.
190 Error handling is recommended...
191 copyFilterProc input: A pointer to the filter routine you want called
192 for each item in the source directory, or NULL
193 if you don't want to filter.
197 readErr Ð19 Driver does not respond to read requests
198 writErr Ð20 Driver does not respond to write requests
199 badUnitErr Ð21 Driver reference number does not
201 unitEmptyErr Ð22 Driver reference number specifies a
202 nil handle in unit table
203 abortErr Ð27 Request aborted by KillIO
204 notOpenErr Ð28 Driver not open
205 dskFulErr -34 Destination volume is full
206 nsvErr -35 No such volume
208 bdNamErr -37 Bad filename
209 tmfoErr -42 Too many files open
210 fnfErr -43 Source file not found, or destination
211 directory does not exist
212 wPrErr -44 Volume locked by hardware
213 fLckdErr -45 File is locked
214 vLckdErr -46 Destination volume is read-only
215 fBsyErr -47 The source or destination file could
216 not be opened with the correct access
218 dupFNErr -48 Destination file already exists
219 opWrErr -49 File already open for writing
220 paramErr -50 No default volume or function not
222 permErr -54 File is already open and cannot be opened using specified deny modes
223 memFullErr -108 Copy buffer could not be allocated
224 dirNFErr -120 Directory not found or incomplete pathname
225 wrgVolTypErr -123 Function not supported by volume
226 afpAccessDenied -5000 User does not have the correct access
227 afpDenyConflict -5006 The source or destination file could
228 not be opened with the correct access
230 afpObjectTypeErr -5025 Source is a directory, directory not found
231 or incomplete pathname
235 Also see: CopyErrProcPtr, CopyFilterProcPtr, FSpFilteredDirectoryCopy,
236 DirectoryCopy, FSpDirectoryCopy, FileCopy, FSpFileCopy
239 /*****************************************************************************/
242 FSpFilteredDirectoryCopy(
243 const FSSpec
* srcSpec
,
244 const FSSpec
* dstSpec
,
245 ConstStr255Param copyName
,
246 void * copyBufferPtr
,
249 CopyErrProcPtr copyErrHandler
,
250 CopyFilterProcPtr copyFilterProc
);
254 The FSpFilteredDirectoryCopy function makes a copy of a directory
255 structure in a new location. If copyBufferPtr <> NIL, it points to
256 a buffer of copyBufferSize that is used to copy files data. The
257 larger the supplied buffer, the faster the copy. If
258 copyBufferPtr = NIL, then this routine allocates a buffer in the
259 application heap. If you pass a copy buffer to this routine, make
260 its size a multiple of 512 ($200) bytes for optimum performance.
262 The optional copyFilterProc parameter lets a routine you define
263 decide what files or directories are copied to the destination.
265 srcSpec input: An FSSpec record specifying the directory to copy.
266 dstSpec input: An FSSpec record specifying destination directory
268 copyName input: Points to the new directory name if the directory
269 is to be renamed or nil if the directory isn't to
271 copyBufferPtr input: Points to a buffer of copyBufferSize that
272 is used the i/o buffer for the copy or
273 nil if you want DirectoryCopy to allocate its
274 own buffer in the application heap.
275 copyBufferSize input: The size of the buffer pointed to
277 preflight input: If true, FSpDirectoryCopy makes sure there are
278 enough allocation blocks on the destination
279 volume to hold the directory's files before
281 copyErrHandler input: A pointer to the routine you want called if an
282 error condition is detected during the copy, or
283 nil if you don't want to handle error conditions.
284 If you don't handle error conditions, the first
285 error will cause the copy to quit and
286 DirectoryCopy will return the error.
287 Error handling is recommended...
288 copyFilterProc input: A pointer to the filter routine you want called
289 for each item in the source directory, or NULL
290 if you don't want to filter.
294 readErr Ð19 Driver does not respond to read requests
295 writErr Ð20 Driver does not respond to write requests
296 badUnitErr Ð21 Driver reference number does not
298 unitEmptyErr Ð22 Driver reference number specifies a
299 nil handle in unit table
300 abortErr Ð27 Request aborted by KillIO
301 notOpenErr Ð28 Driver not open
302 dskFulErr -34 Destination volume is full
303 nsvErr -35 No such volume
305 bdNamErr -37 Bad filename
306 tmfoErr -42 Too many files open
307 fnfErr -43 Source file not found, or destination
308 directory does not exist
309 wPrErr -44 Volume locked by hardware
310 fLckdErr -45 File is locked
311 vLckdErr -46 Destination volume is read-only
312 fBsyErr -47 The source or destination file could
313 not be opened with the correct access
315 dupFNErr -48 Destination file already exists
316 opWrErr -49 File already open for writing
317 paramErr -50 No default volume or function not
319 permErr -54 File is already open and cannot be opened using specified deny modes
320 memFullErr -108 Copy buffer could not be allocated
321 dirNFErr -120 Directory not found or incomplete pathname
322 wrgVolTypErr -123 Function not supported by volume
323 afpAccessDenied -5000 User does not have the correct access
324 afpDenyConflict -5006 The source or destination file could
325 not be opened with the correct access
327 afpObjectTypeErr -5025 Source is a directory, directory not found
328 or incomplete pathname
332 Also see: CopyErrProcPtr, CopyFilterProcPtr, FilteredDirectoryCopy,
333 DirectoryCopy, FSpDirectoryCopy, FileCopy, FSpFileCopy
336 /*****************************************************************************/
342 ConstStr255Param srcName
,
345 ConstStr255Param dstName
,
346 ConstStr255Param copyName
,
347 void * copyBufferPtr
,
350 CopyErrProcPtr copyErrHandler
);
354 The DirectoryCopy function makes a copy of a directory structure in a
355 new location. If copyBufferPtr <> NIL, it points to a buffer of
356 copyBufferSize that is used to copy files data. The larger the
357 supplied buffer, the faster the copy. If copyBufferPtr = NIL, then this
358 routine allocates a buffer in the application heap. If you pass a
359 copy buffer to this routine, make its size a multiple of 512
360 ($200) bytes for optimum performance.
362 DirectoryCopy normally creates a new directory *in* the specified
363 destination directory and copies the source directory's content into
364 the new directory. However, if root parent directory (fsRtParID)
365 is passed as the dstDirID parameter and NULL is passed as the
366 dstName parameter, DirectoryCopy renames the destination volume to
367 the source directory's name (truncating if the name is longer than
368 27 characters) and copies the source directory's content into the
369 destination volume's root directory. This special case is supported
370 by DirectoryCopy, but not by FSpDirectoryCopy since with
371 FSpDirectoryCopy, the dstName parameter can not be NULL.
373 srcVRefNum input: Source volume specification.
374 srcDirID input: Source directory ID.
375 srcName input: Source directory name, or nil if
376 srcDirID specifies the directory.
377 dstVRefNum input: Destination volume specification.
378 dstDirID input: Destination directory ID.
379 dstName input: Destination directory name, or nil if
380 dstDirID specifies the directory.
381 copyName input: Points to the new directory name if the directory
382 is to be renamed or nil if the directory isn't to
384 copyBufferPtr input: Points to a buffer of copyBufferSize that
385 is used the i/o buffer for the copy or
386 nil if you want DirectoryCopy to allocate its
387 own buffer in the application heap.
388 copyBufferSize input: The size of the buffer pointed to
390 preflight input: If true, DirectoryCopy makes sure there are
391 enough allocation blocks on the destination
392 volume to hold the directory's files before
394 copyErrHandler input: A pointer to the routine you want called if an
395 error condition is detected during the copy, or
396 nil if you don't want to handle error conditions.
397 If you don't handle error conditions, the first
398 error will cause the copy to quit and
399 DirectoryCopy will return the error.
400 Error handling is recommended...
404 readErr Ð19 Driver does not respond to read requests
405 writErr Ð20 Driver does not respond to write requests
406 badUnitErr Ð21 Driver reference number does not
408 unitEmptyErr Ð22 Driver reference number specifies a
409 nil handle in unit table
410 abortErr Ð27 Request aborted by KillIO
411 notOpenErr Ð28 Driver not open
412 dskFulErr -34 Destination volume is full
413 nsvErr -35 No such volume
415 bdNamErr -37 Bad filename
416 tmfoErr -42 Too many files open
417 fnfErr -43 Source file not found, or destination
418 directory does not exist
419 wPrErr -44 Volume locked by hardware
420 fLckdErr -45 File is locked
421 vLckdErr -46 Destination volume is read-only
422 fBsyErr -47 The source or destination file could
423 not be opened with the correct access
425 dupFNErr -48 Destination file already exists
426 opWrErr -49 File already open for writing
427 paramErr -50 No default volume or function not
429 permErr -54 File is already open and cannot be opened using specified deny modes
430 memFullErr -108 Copy buffer could not be allocated
431 dirNFErr -120 Directory not found or incomplete pathname
432 wrgVolTypErr -123 Function not supported by volume
433 afpAccessDenied -5000 User does not have the correct access
434 afpDenyConflict -5006 The source or destination file could
435 not be opened with the correct access
437 afpObjectTypeErr -5025 Source is a directory, directory not found
438 or incomplete pathname
442 Also see: CopyErrProcPtr, FSpDirectoryCopy, FilteredDirectoryCopy,
443 FSpFilteredDirectoryCopy, FileCopy, FSpFileCopy
446 /*****************************************************************************/
450 const FSSpec
* srcSpec
,
451 const FSSpec
* dstSpec
,
452 ConstStr255Param copyName
,
453 void * copyBufferPtr
,
456 CopyErrProcPtr copyErrHandler
);
460 The FSpDirectoryCopy function makes a copy of a directory structure in a
461 new location. If copyBufferPtr <> NIL, it points to a buffer of
462 copyBufferSize that is used to copy files data. The larger the
463 supplied buffer, the faster the copy. If copyBufferPtr = NIL, then this
464 routine allocates a buffer in the application heap. If you pass a
465 copy buffer to this routine, make its size a multiple of 512
466 ($200) bytes for optimum performance.
468 srcSpec input: An FSSpec record specifying the directory to copy.
469 dstSpec input: An FSSpec record specifying destination directory
471 copyName input: Points to the new directory name if the directory
472 is to be renamed or nil if the directory isn't to
474 copyBufferPtr input: Points to a buffer of copyBufferSize that
475 is used the i/o buffer for the copy or
476 nil if you want DirectoryCopy to allocate its
477 own buffer in the application heap.
478 copyBufferSize input: The size of the buffer pointed to
480 preflight input: If true, FSpDirectoryCopy makes sure there are
481 enough allocation blocks on the destination
482 volume to hold the directory's files before
484 copyErrHandler input: A pointer to the routine you want called if an
485 error condition is detected during the copy, or
486 nil if you don't want to handle error conditions.
487 If you don't handle error conditions, the first
488 error will cause the copy to quit and
489 DirectoryCopy will return the error.
490 Error handling is recommended...
494 readErr Ð19 Driver does not respond to read requests
495 writErr Ð20 Driver does not respond to write requests
496 badUnitErr Ð21 Driver reference number does not
498 unitEmptyErr Ð22 Driver reference number specifies a
499 nil handle in unit table
500 abortErr Ð27 Request aborted by KillIO
501 notOpenErr Ð28 Driver not open
502 dskFulErr -34 Destination volume is full
503 nsvErr -35 No such volume
505 bdNamErr -37 Bad filename
506 tmfoErr -42 Too many files open
507 fnfErr -43 Source file not found, or destination
508 directory does not exist
509 wPrErr -44 Volume locked by hardware
510 fLckdErr -45 File is locked
511 vLckdErr -46 Destination volume is read-only
512 fBsyErr -47 The source or destination file could
513 not be opened with the correct access
515 dupFNErr -48 Destination file already exists
516 opWrErr -49 File already open for writing
517 paramErr -50 No default volume or function not
519 permErr -54 File is already open and cannot be opened using specified deny modes
520 memFullErr -108 Copy buffer could not be allocated
521 dirNFErr -120 Directory not found or incomplete pathname
522 wrgVolTypErr -123 Function not supported by volume
523 afpAccessDenied -5000 User does not have the correct access
524 afpDenyConflict -5006 The source or destination file could
525 not be opened with the correct access
527 afpObjectTypeErr -5025 Source is a directory, directory not found
528 or incomplete pathname
532 Also see: CopyErrProcPtr, DirectoryCopy, FilteredDirectoryCopy,
533 FSpFilteredDirectoryCopy, FileCopy, FSpFileCopy
536 /*****************************************************************************/
538 #include "OptimizationEnd.h"
540 #if PRAGMA_STRUCT_ALIGN
541 #pragma options align=reset
542 #elif PRAGMA_STRUCT_PACKPUSH
544 #elif PRAGMA_STRUCT_PACK
548 #ifdef PRAGMA_IMPORT_OFF
558 #endif /* __DIRECTORYCOPY__ */