1/* 2 File: DirectoryCopy.h 3 4 Contains: A robust, general purpose directory copy routine. 5 6 Version: Technology: MoreFiles 7 Release: 1.5.2 8 9 Copyright: � 1992-2001 by Apple Computer, Inc., all rights reserved. 10 11 Bugs?: For bug reports, consult the following page on 12 the World Wide Web: 13 14 http://developer.apple.com/bugreporter/ 15 16*/ 17 18/* 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. 26*/ 27 28#ifndef __DIRECTORYCOPY__ 29#define __DIRECTORYCOPY__ 30 31#ifndef __MACTYPES__ 32#include <MacTypes.h> 33#endif 34 35#ifndef __FILES__ 36#include <Files.h> 37#endif 38 39#include "Optimization.h" 40 41 42#if PRAGMA_ONCE 43#pragma once 44#endif 45 46#ifdef __cplusplus 47extern "C" { 48#endif 49 50#if PRAGMA_IMPORT 51#pragma import on 52#endif 53 54#if PRAGMA_STRUCT_ALIGN 55 #pragma options align=mac68k 56#elif PRAGMA_STRUCT_PACKPUSH 57 #pragma pack(push, 2) 58#elif PRAGMA_STRUCT_PACK 59 #pragma pack(2) 60#endif 61 62/*****************************************************************************/ 63 64enum { 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 */ 71}; 72 73 74/*****************************************************************************/ 75 76typedef CALLBACK_API( Boolean , CopyErrProcPtr )(OSErr error, short failedOperation, short srcVRefNum, long srcDirID, ConstStr255Param srcName, short dstVRefNum, long dstDirID, ConstStr255Param dstName); 77/* 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. 83 84 error input: The error result code that caused CopyErrProc to 85 be called. 86 failedOperation input: The operation that returned an error to 87 DirectoryCopy. 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. 96 97 __________ 98 99 Also see: FilteredDirectoryCopy, FSpFilteredDirectoryCopy, DirectoryCopy, FSpDirectoryCopy 100*/ 101#define CallCopyErrProc(userRoutine, error, failedOperation, srcVRefNum, srcDirID, srcName, dstVRefNum, dstDirID, dstName) \ 102 (*(userRoutine))((error), (failedOperation), (srcVRefNum), (srcDirID), (srcName), (dstVRefNum), (dstDirID), (dstName)) 103 104/*****************************************************************************/ 105 106typedef CALLBACK_API( Boolean , CopyFilterProcPtr )(const CInfoPBRec * cpbPtr); 107/* 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. 111 112 pb input: Points to the CInfoPBRec for the item under consideration. 113 114 __________ 115 116 Also see: FilteredDirectoryCopy, FSpFilteredDirectoryCopy 117*/ 118#define CallCopyFilterProc(userRoutine, cpbPtr) \ 119 (*(userRoutine))((cpbPtr)) 120 121/*****************************************************************************/ 122 123EXTERN_API( OSErr ) 124FilteredDirectoryCopy( 125 short srcVRefNum, 126 long srcDirID, 127 ConstStr255Param srcName, 128 short dstVRefNum, 129 long dstDirID, 130 ConstStr255Param dstName, 131 ConstStr255Param copyName, 132 void * copyBufferPtr, 133 long copyBufferSize, 134 Boolean preflight, 135 CopyErrProcPtr copyErrHandler, 136 CopyFilterProcPtr copyFilterProc); 137 138 139/* 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. 147 148 The optional copyFilterProc parameter lets a routine you define 149 decide what files or directories are copied to the destination. 150 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. 162 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 173 be renamed. 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 179 by copyBufferPtr. 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 183 starting the copy. 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. 194 195 Result Codes 196 noErr 0 No error 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 200 match unit table 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 207 ioErr -36 I/O error 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 217 modes 218 dupFNErr -48 Destination file already exists 219 opWrErr -49 File already open for writing 220 paramErr -50 No default volume or function not 221 supported by volume 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 229 modes 230 afpObjectTypeErr -5025 Source is a directory, directory not found 231 or incomplete pathname 232 233 __________ 234 235 Also see: CopyErrProcPtr, CopyFilterProcPtr, FSpFilteredDirectoryCopy, 236 DirectoryCopy, FSpDirectoryCopy, FileCopy, FSpFileCopy 237*/ 238 239/*****************************************************************************/ 240 241EXTERN_API( OSErr ) 242FSpFilteredDirectoryCopy( 243 const FSSpec * srcSpec, 244 const FSSpec * dstSpec, 245 ConstStr255Param copyName, 246 void * copyBufferPtr, 247 long copyBufferSize, 248 Boolean preflight, 249 CopyErrProcPtr copyErrHandler, 250 CopyFilterProcPtr copyFilterProc); 251 252 253/* 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. 261 262 The optional copyFilterProc parameter lets a routine you define 263 decide what files or directories are copied to the destination. 264 265 srcSpec input: An FSSpec record specifying the directory to copy. 266 dstSpec input: An FSSpec record specifying destination directory 267 of the copy. 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 270 be renamed. 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 276 by copyBufferPtr. 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 280 starting the copy. 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. 291 292 Result Codes 293 noErr 0 No error 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 297 match unit table 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 304 ioErr -36 I/O error 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 314 modes 315 dupFNErr -48 Destination file already exists 316 opWrErr -49 File already open for writing 317 paramErr -50 No default volume or function not 318 supported by volume 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 326 modes 327 afpObjectTypeErr -5025 Source is a directory, directory not found 328 or incomplete pathname 329 330 __________ 331 332 Also see: CopyErrProcPtr, CopyFilterProcPtr, FilteredDirectoryCopy, 333 DirectoryCopy, FSpDirectoryCopy, FileCopy, FSpFileCopy 334*/ 335 336/*****************************************************************************/ 337 338EXTERN_API( OSErr ) 339DirectoryCopy( 340 short srcVRefNum, 341 long srcDirID, 342 ConstStr255Param srcName, 343 short dstVRefNum, 344 long dstDirID, 345 ConstStr255Param dstName, 346 ConstStr255Param copyName, 347 void * copyBufferPtr, 348 long copyBufferSize, 349 Boolean preflight, 350 CopyErrProcPtr copyErrHandler); 351 352 353/* 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. 361 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. 372 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 383 be renamed. 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 389 by copyBufferPtr. 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 393 starting the copy. 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... 401 402 Result Codes 403 noErr 0 No error 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 407 match unit table 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 414 ioErr -36 I/O error 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 424 modes 425 dupFNErr -48 Destination file already exists 426 opWrErr -49 File already open for writing 427 paramErr -50 No default volume or function not 428 supported by volume 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 436 modes 437 afpObjectTypeErr -5025 Source is a directory, directory not found 438 or incomplete pathname 439 440 __________ 441 442 Also see: CopyErrProcPtr, FSpDirectoryCopy, FilteredDirectoryCopy, 443 FSpFilteredDirectoryCopy, FileCopy, FSpFileCopy 444*/ 445 446/*****************************************************************************/ 447 448EXTERN_API( OSErr ) 449FSpDirectoryCopy( 450 const FSSpec * srcSpec, 451 const FSSpec * dstSpec, 452 ConstStr255Param copyName, 453 void * copyBufferPtr, 454 long copyBufferSize, 455 Boolean preflight, 456 CopyErrProcPtr copyErrHandler); 457 458 459/* 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. 467 468 srcSpec input: An FSSpec record specifying the directory to copy. 469 dstSpec input: An FSSpec record specifying destination directory 470 of the copy. 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 473 be renamed. 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 479 by copyBufferPtr. 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 483 starting the copy. 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... 491 492 Result Codes 493 noErr 0 No error 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 497 match unit table 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 504 ioErr -36 I/O error 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 514 modes 515 dupFNErr -48 Destination file already exists 516 opWrErr -49 File already open for writing 517 paramErr -50 No default volume or function not 518 supported by volume 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 526 modes 527 afpObjectTypeErr -5025 Source is a directory, directory not found 528 or incomplete pathname 529 530 __________ 531 532 Also see: CopyErrProcPtr, DirectoryCopy, FilteredDirectoryCopy, 533 FSpFilteredDirectoryCopy, FileCopy, FSpFileCopy 534*/ 535 536/*****************************************************************************/ 537 538#include "OptimizationEnd.h" 539 540#if PRAGMA_STRUCT_ALIGN 541 #pragma options align=reset 542#elif PRAGMA_STRUCT_PACKPUSH 543 #pragma pack(pop) 544#elif PRAGMA_STRUCT_PACK 545 #pragma pack() 546#endif 547 548#ifdef PRAGMA_IMPORT_OFF 549#pragma import off 550#elif PRAGMA_IMPORT 551#pragma import reset 552#endif 553 554#ifdef __cplusplus 555} 556#endif 557 558#endif /* __DIRECTORYCOPY__ */ 559 560