1/* 2 * Copyright (c) 1998-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "DiskArbitrationPrivate.h" 25 26#include "DAInternal.h" 27#include "DAServer.h" 28 29#ifndef __LP64__ 30 31#include <paths.h> 32#include <unistd.h> 33#include <servers/bootstrap.h> 34#include <sys/attr.h> 35#include <sys/mount.h> 36#include <IOKit/IOKitLib.h> 37#include <IOKit/storage/IOMedia.h> 38#include <IOKit/storage/IOBDMedia.h> 39#include <IOKit/storage/IOCDMedia.h> 40#include <IOKit/storage/IODVDMedia.h> 41///w:start 42static kern_return_t __gDiskArbStatus = KERN_SUCCESS; 43static Boolean __gDiskArbStatusLock = FALSE; 44///w:stop 45 46static int __gDiskArbAck = 0; 47static CFMutableDictionaryRef __gDiskArbCallbackList = NULL; 48static CFMutableSetRef __gDiskArbEjectList = NULL; 49static int __gDiskArbHandlesUnrecognized = 0; 50static int __gDiskArbHandlesUnrecognizedPriority = 0; 51static int __gDiskArbHandlesUnrecognizedTypes = 0; 52static int __gDiskArbNotificationComplete = 0; 53static CFMutableArrayRef __gDiskArbRegisterList = NULL; 54static CFMutableSetRef __gDiskArbReservationList = NULL; 55static DASessionRef __gDiskArbSession = NULL; 56static CFMutableSetRef __gDiskArbUnmountList = NULL; 57 58#endif /* !__LP64__ */ 59 60__private_extern__ DAReturn _DAAuthorize( DASessionRef session, _DAAuthorizeOptions options, DADiskRef disk, const char * right ); 61 62__private_extern__ char * _DADiskGetID( DADiskRef disk ); 63__private_extern__ mach_port_t _DADiskGetSessionID( DADiskRef disk ); 64 65__private_extern__ void _DARegisterCallback( DASessionRef session, 66 void * callback, 67 void * context, 68 _DACallbackKind kind, 69 CFIndex order, 70 CFDictionaryRef match, 71 CFArrayRef watch ); 72 73#ifndef __LP64__ 74 75__private_extern__ void _DASessionCallback( CFMachPortRef port, void * message, CFIndex messageSize, void * info ); 76__private_extern__ AuthorizationRef _DASessionGetAuthorization( DASessionRef session ); 77__private_extern__ mach_port_t _DASessionGetClientPort( DASessionRef session ); 78__private_extern__ void _DASessionScheduleWithRunLoop( DASessionRef session ); 79 80static unsigned __DiskArbCopyDiskDescriptionAppearanceTime( DADiskRef disk ) 81{ 82 double time = 0; 83 84 if ( disk ) 85 { 86 CFDictionaryRef description; 87 88 description = DADiskCopyDescription( disk ); 89 90 if ( description ) 91 { 92 CFNumberRef number; 93 94 number = CFDictionaryGetValue( description, kDADiskDescriptionAppearanceTimeKey ); 95 96 if ( number ) 97 { 98 CFNumberGetValue( number, kCFNumberDoubleType, &time ); 99 } 100 101 CFRelease( description ); 102 } 103 } 104 105 return time; 106} 107 108static char * __DiskArbCopyDiskDescriptionDeviceTreePath( DADiskRef disk ) 109{ 110 char * path = NULL; 111 112 if ( disk ) 113 { 114 CFDictionaryRef description; 115 116 description = DADiskCopyDescription( disk ); 117 118 if ( description ) 119 { 120 CFStringRef string; 121 122 string = CFDictionaryGetValue( description, kDADiskDescriptionMediaPathKey ); 123 124 if ( string ) 125 { 126 char * buffer; 127 128 buffer = ___CFStringCopyCString( string ); 129 130 if ( buffer ) 131 { 132 if ( strncmp( buffer, kIODeviceTreePlane ":", strlen( kIODeviceTreePlane ":" ) ) == 0 ) 133 { 134 path = strdup( buffer + strlen( kIODeviceTreePlane ":" ) ); 135 } 136 137 free( buffer ); 138 } 139 } 140 141 CFRelease( description ); 142 } 143 } 144 145 return path ? path : strdup( "" ); 146} 147 148static unsigned __DiskArbCopyDiskDescriptionFlags( DADiskRef disk ) 149{ 150 unsigned flags = 0; 151 152 if ( disk ) 153 { 154 CFDictionaryRef description; 155 156 description = DADiskCopyDescription( disk ); 157 158 if ( description ) 159 { 160 CFTypeRef object; 161 162 object = CFDictionaryGetValue( description, kDADiskDescriptionDeviceInternalKey ); 163 164 if ( object ) 165 { 166 if ( object == kCFBooleanTrue ) 167 { 168 flags |= kDiskArbDiskAppearedInternal; 169 } 170 } 171 172 object = CFDictionaryGetValue( description, kDADiskDescriptionMediaEjectableKey ); 173 174 if ( object ) 175 { 176 if ( object == kCFBooleanTrue ) 177 { 178 flags |= kDiskArbDiskAppearedEjectableMask; 179 180 object = CFDictionaryGetValue( description, kDADiskDescriptionMediaKindKey ); 181 182 if ( object ) 183 { 184 DADiskRef whole; 185 186 whole = DADiskCopyWholeDisk( disk ); 187 188 if ( whole ) 189 { 190 io_service_t media; 191 192 media = DADiskCopyIOMedia( whole ); 193 194 if ( media ) 195 { 196 if ( IOObjectConformsTo( media, kIOBDMediaClass ) ) 197 { 198 flags |= kDiskArbDiskAppearedBDROMMask; 199 } 200 201 if ( IOObjectConformsTo( media, kIOCDMediaClass ) ) 202 { 203 flags |= kDiskArbDiskAppearedCDROMMask; 204 } 205 206 if ( IOObjectConformsTo( media, kIODVDMediaClass ) ) 207 { 208 flags |= kDiskArbDiskAppearedDVDROMMask; 209 } 210 211 IOObjectRelease( media ); 212 } 213 214 CFRelease( whole ); 215 } 216 } 217 } 218 } 219 220 object = CFDictionaryGetValue( description, kDADiskDescriptionMediaLeafKey ); 221 222 if ( object ) 223 { 224 if ( object == kCFBooleanFalse ) 225 { 226 flags |= kDiskArbDiskAppearedNonLeafDiskMask; 227 } 228 } 229 230 object = CFDictionaryGetValue( description, kDADiskDescriptionMediaSizeKey ); 231 232 if ( object ) 233 { 234 if ( ___CFNumberGetIntegerValue( object ) == 0 ) 235 { 236 flags |= kDiskArbDiskAppearedNoSizeMask; 237 } 238 } 239 240 object = CFDictionaryGetValue( description, kDADiskDescriptionMediaWholeKey ); 241 242 if ( object ) 243 { 244 if ( object == kCFBooleanTrue ) 245 { 246 flags |= kDiskArbDiskAppearedWholeDiskMask; 247 } 248 } 249 250 object = CFDictionaryGetValue( description, kDADiskDescriptionMediaWritableKey ); 251 252 if ( object ) 253 { 254 if ( object == kCFBooleanFalse ) 255 { 256 flags |= kDiskArbDiskAppearedLockedMask; 257 } 258 } 259 260 object = CFDictionaryGetValue( description, kDADiskDescriptionVolumeMountableKey ); 261 262 if ( object ) 263 { 264 if ( object == kCFBooleanFalse ) 265 { 266 flags |= kDiskArbDiskAppearedUnrecognizableFormat; 267 } 268 } 269 270 object = CFDictionaryGetValue( description, kDADiskDescriptionVolumeNetworkKey ); 271 272 if ( object ) 273 { 274 if ( object == kCFBooleanTrue ) 275 { 276 flags |= kDiskArbDiskAppearedNetworkDiskMask; 277 } 278 } 279 280 CFRelease( description ); 281 } 282 } 283 284 return flags; 285} 286 287static char * __DiskArbCopyDiskDescriptionMediaContent( DADiskRef disk ) 288{ 289 char * content = NULL; 290 291 if ( disk ) 292 { 293 CFDictionaryRef description; 294 295 description = DADiskCopyDescription( disk ); 296 297 if ( description ) 298 { 299 CFStringRef string; 300 301 string = CFDictionaryGetValue( description, kDADiskDescriptionMediaContentKey ); 302 303 if ( string ) 304 { 305 content = ___CFStringCopyCString( string ); 306 } 307 308 CFRelease( description ); 309 } 310 } 311 312 return content ? content : strdup( "" ); 313} 314 315static unsigned __DiskArbCopyDiskDescriptionSequenceNumber( DADiskRef disk ) 316{ 317 unsigned sequence = -1; 318 319 if ( disk ) 320 { 321 CFDictionaryRef description; 322 323 description = DADiskCopyDescription( disk ); 324 325 if ( description ) 326 { 327 CFURLRef url; 328 329 url = CFDictionaryGetValue( description, kDADiskDescriptionVolumePathKey ); 330 331 if ( url ) 332 { 333 CFNumberRef number; 334 335 number = CFDictionaryGetValue( description, kDADiskDescriptionMediaBSDMinorKey ); 336 337 if ( number ) 338 { 339 CFNumberGetValue( number, kCFNumberIntType, &sequence ); 340 } 341 } 342 343 CFRelease( description ); 344 } 345 } 346 347 return sequence; 348} 349 350static char * __DiskArbCopyDiskDescriptionVolumeKind( DADiskRef disk ) 351{ 352 char * kind = NULL; 353 354 if ( disk ) 355 { 356 CFDictionaryRef description; 357 358 description = DADiskCopyDescription( disk ); 359 360 if ( description ) 361 { 362 CFStringRef string; 363 364 string = CFDictionaryGetValue( description, kDADiskDescriptionVolumeKindKey ); 365 366 if ( string ) 367 { 368 kind = ___CFStringCopyCString( string ); 369 } 370 371 CFRelease( description ); 372 } 373 } 374 375 return kind ? kind : strdup( "" ); 376} 377 378static char * __DiskArbCopyDiskDescriptionVolumeName( DADiskRef disk ) 379{ 380 char * name = NULL; 381 382 if ( disk ) 383 { 384 CFDictionaryRef description; 385 386 description = DADiskCopyDescription( disk ); 387 388 if ( description ) 389 { 390 CFStringRef string; 391 392 string = CFDictionaryGetValue( description, kDADiskDescriptionVolumeNameKey ); 393 394 if ( string ) 395 { 396 name = ___CFStringCopyCString( string ); 397 } 398 399 CFRelease( description ); 400 } 401 } 402 403 return name ? name : strdup( "" ); 404} 405 406static char * __DiskArbCopyDiskDescriptionVolumePath( DADiskRef disk ) 407{ 408 char * path = NULL; 409 410 if ( disk ) 411 { 412 CFDictionaryRef description; 413 414 description = DADiskCopyDescription( disk ); 415 416 if ( description ) 417 { 418 CFURLRef url; 419 420 url = CFDictionaryGetValue( description, kDADiskDescriptionVolumePathKey ); 421 422 if ( url ) 423 { 424 path = ___CFURLCopyFileSystemRepresentation( url ); 425 } 426 427 CFRelease( description ); 428 } 429 } 430 431 return path ? path : strdup( "" ); 432} 433 434static CFArrayRef __DiskArbGetCallbackHandler( int type ) 435{ 436 CFArrayRef callbacks = NULL; 437 438 if ( __gDiskArbCallbackList ) 439 { 440 CFNumberRef key; 441 442 key = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &type ); 443 444 if ( key ) 445 { 446 callbacks = CFDictionaryGetValue( __gDiskArbCallbackList, key ); 447 448 CFRelease( key ); 449 } 450 } 451 452 return callbacks; 453} 454 455static char * __DiskArbGetDiskID( DADiskRef _disk ) 456{ 457 char * disk; 458 459 disk = _DADiskGetID( _disk ); 460 461 if ( strncmp( disk, _PATH_DEV, strlen( _PATH_DEV ) ) == 0 ) 462 { 463 disk += strlen( _PATH_DEV ); 464 } 465 466 return disk; 467} 468 469static struct statfs * __DiskArbGetFileSystemStatus( char * disk ) 470{ 471 struct statfs * mountList; 472 int mountListCount; 473 int mountListIndex; 474 475 mountListCount = getmntinfo( &mountList, MNT_NOWAIT ); 476 477 for ( mountListIndex = 0; mountListIndex < mountListCount; mountListIndex++ ) 478 { 479 if ( strncmp( disk, "disk", strlen( "disk" ) ) ) 480 { 481 if ( strcmp( mountList[mountListIndex].f_mntfromname, disk ) == 0 ) 482 { 483 break; 484 } 485 486 if ( strcmp( mountList[mountListIndex].f_mntonname, disk ) == 0 ) 487 { 488 break; 489 } 490 } 491 else 492 { 493 if ( strncmp( mountList[mountListIndex].f_mntfromname, _PATH_DEV, strlen( _PATH_DEV ) ) == 0 ) 494 { 495 if ( strcmp( mountList[mountListIndex].f_mntfromname + strlen( _PATH_DEV ), disk ) == 0 ) 496 { 497 break; 498 } 499 } 500 } 501 } 502 503 return ( mountListIndex < mountListCount ) ? ( mountList + mountListIndex ) : ( NULL ); 504} 505 506static void __DiskArbCallback_CallFailedNotification( char * disk, int type, int status ) 507{ 508 CFArrayRef callbacks; 509 510 callbacks = __DiskArbGetCallbackHandler( kDA_CALL_FAILED ); 511 512 if ( callbacks ) 513 { 514 CFIndex count; 515 CFIndex index; 516 517 count = CFArrayGetCount( callbacks ); 518 519 for ( index = 0; index < count; index++ ) 520 { 521 DiskArbCallback_CallFailedNotification_t callback; 522 523 callback = CFArrayGetValueAtIndex( callbacks, index ); 524 525 if ( callback ) 526 { 527 ( callback )( disk, type, status ); 528 } 529 } 530 } 531} 532 533static void __DiskArbCallback_Device_Reservation_Status( char * disk, int status, int pid ) 534{ 535 CFArrayRef callbacks; 536 537 callbacks = __DiskArbGetCallbackHandler( kDA_DEVICE_RESERVATION_STATUS ); 538 539 if ( callbacks ) 540 { 541 CFIndex count; 542 CFIndex index; 543 544 count = CFArrayGetCount( callbacks ); 545 546 for ( index = 0; index < count; index++ ) 547 { 548 DiskArbCallback_Device_Reservation_Status_t callback; 549 550 callback = CFArrayGetValueAtIndex( callbacks, index ); 551 552 if ( callback ) 553 { 554 ( callback )( disk, status, pid ); 555 } 556 } 557 } 558} 559 560static void __DiskArbCallback_DiskChangedNotification( char * disk, char * mountpoint, char * name, int context, int success ) 561{ 562 CFArrayRef callbacks; 563 564 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_CHANGED ); 565 566 if ( callbacks ) 567 { 568 CFIndex count; 569 CFIndex index; 570 571 count = CFArrayGetCount( callbacks ); 572 573 for ( index = 0; index < count; index++ ) 574 { 575 DiskArbCallback_DiskChangedNotification_t callback; 576 577 callback = CFArrayGetValueAtIndex( callbacks, index ); 578 579 if ( callback ) 580 { 581 ( callback )( disk, mountpoint, name, context, success ); 582 } 583 } 584 } 585} 586 587static void __DiskArbCallback_EjectPostNotification( char * disk, int status, pid_t dissenter ) 588{ 589 CFArrayRef callbacks; 590 591 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_EJECT_POST_NOTIFY ); 592 593 if ( callbacks ) 594 { 595 CFIndex count; 596 CFIndex index; 597 598 count = CFArrayGetCount( callbacks ); 599 600 for ( index = 0; index < count; index++ ) 601 { 602 DiskArbCallback_EjectPostNotification_t callback; 603 604 callback = CFArrayGetValueAtIndex( callbacks, index ); 605 606 if ( callback ) 607 { 608 ( callback )( disk, status, dissenter ); 609 } 610 } 611 } 612 613 __gDiskArbNotificationComplete |= kDiskArbCompletedPostEject; 614} 615 616static void __DiskArbCallback_EjectPostNotificationApplier( const void * value, void * context ) 617{ 618 DADiskRef disk = ( DADiskRef ) value; 619 620 __DiskArbCallback_EjectPostNotification( __DiskArbGetDiskID( disk ), context ? EBUSY : 0, context ? -1 : 0 ); 621} 622 623static void __DiskArbCallback_UnmountPostNotification( char * disk, int status, pid_t dissenter ) 624{ 625 CFArrayRef callbacks; 626 627 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_UNMOUNT_POST_NOTIFY ); 628 629 if ( callbacks ) 630 { 631 CFIndex count; 632 CFIndex index; 633 634 count = CFArrayGetCount( callbacks ); 635 636 for ( index = 0; index < count; index++ ) 637 { 638 DiskArbCallback_UnmountPostNotification_t callback; 639 640 callback = CFArrayGetValueAtIndex( callbacks, index ); 641 642 if ( callback ) 643 { 644 ( callback )( disk, status, dissenter ); 645 } 646 } 647 } 648 649 __gDiskArbNotificationComplete |= kDiskArbCompletedPostUnmount; 650} 651 652static void __DiskArbCallback_UnmountPostNotificationApplier( const void * value, void * context ) 653{ 654 DADiskRef disk = ( DADiskRef ) value; 655 656 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( disk ), context ? EBUSY : 0, context ? -1 : 0 ); 657} 658 659static void __DiskArbDiskAppearedCallback( DADiskRef disk, void * context ) 660{ 661 CFArrayRef callbacks = NULL; 662 char * content = NULL; 663 char * filesystem = NULL; 664 unsigned flags = 0; 665 char * mountpoint = NULL; 666 char * name = NULL; 667 char * path = NULL; 668 unsigned sequence = -1; 669 double time = 0; 670 671 content = __DiskArbCopyDiskDescriptionMediaContent( disk ); 672 filesystem = __DiskArbCopyDiskDescriptionVolumeKind( disk ); 673 flags = __DiskArbCopyDiskDescriptionFlags( disk ); 674 mountpoint = __DiskArbCopyDiskDescriptionVolumePath( disk ); 675 name = __DiskArbCopyDiskDescriptionVolumeName( disk ); 676 path = __DiskArbCopyDiskDescriptionDeviceTreePath( disk ); 677 sequence = __DiskArbCopyDiskDescriptionSequenceNumber( disk ); 678 time = __DiskArbCopyDiskDescriptionAppearanceTime( disk ); 679 680 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_APPEARED ); 681 682 if ( callbacks ) 683 { 684 CFIndex count; 685 CFIndex index; 686 687 count = CFArrayGetCount( callbacks ); 688 689 for ( index = 0; index < count; index++ ) 690 { 691 DiskArbCallback_DiskAppeared2_t callback; 692 693 callback = CFArrayGetValueAtIndex( callbacks, index ); 694 695 if ( callback ) 696 { 697 ( callback )( __DiskArbGetDiskID( disk ), flags, mountpoint, content, path, sequence ); 698 } 699 } 700 } 701 702 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_APPEARED1 ); 703 704 if ( callbacks ) 705 { 706 CFIndex count; 707 CFIndex index; 708 709 count = CFArrayGetCount( callbacks ); 710 711 for ( index = 0; index < count; index++ ) 712 { 713 DiskArbCallback_DiskAppeared_t callback; 714 715 callback = CFArrayGetValueAtIndex( callbacks, index ); 716 717 if ( callback ) 718 { 719 ( callback )( __DiskArbGetDiskID( disk ), flags, mountpoint, content ); 720 } 721 } 722 } 723 724 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_APPEARED_COMPLETE ); 725 726 if ( callbacks ) 727 { 728 CFIndex count; 729 CFIndex index; 730 731 count = CFArrayGetCount( callbacks ); 732 733 for ( index = 0; index < count; index++ ) 734 { 735 DiskArbCallback_DiskAppearedComplete_t callback; 736 737 callback = CFArrayGetValueAtIndex( callbacks, index ); 738 739 if ( callback ) 740 { 741 ( callback )( __DiskArbGetDiskID( disk ), flags, mountpoint, content, path, sequence, time, filesystem, name ); 742 } 743 } 744 } 745 746 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_APPEARED_WITH_MT ); 747 748 if ( callbacks ) 749 { 750 if ( strcmp( mountpoint, "" ) ) 751 { 752 CFIndex count; 753 CFIndex index; 754 755 count = CFArrayGetCount( callbacks ); 756 757 for ( index = 0; index < count; index++ ) 758 { 759 DiskArbCallback_DiskAppearedWithMountpoint_t callback; 760 761 callback = CFArrayGetValueAtIndex( callbacks, index ); 762 763 if ( callback ) 764 { 765 ( callback )( __DiskArbGetDiskID( disk ), flags, mountpoint ); 766 } 767 } 768 } 769 } 770 771 __gDiskArbNotificationComplete |= kDiskArbCompletedDiskAppeared; 772 773 if ( content ) free( content ); 774 if ( filesystem ) free( filesystem ); 775 if ( mountpoint ) free( mountpoint ); 776 if ( name ) free( name ); 777 if ( path ) free( path ); 778} 779 780static void __DiskArbDiskClaimCallback( DADiskRef disk, DADissenterRef dissenter, void * context ) 781{ 782 if ( dissenter == NULL ) 783 { 784 CFSetSetValue( __gDiskArbReservationList, disk ); 785 } 786 787 if ( context == 0 ) 788 { 789 if ( dissenter ) 790 { 791 __DiskArbCallback_Device_Reservation_Status( __DiskArbGetDiskID( disk ), kDiskArbDeviceReservationRefused, -1 ); 792 } 793 else 794 { 795 __DiskArbCallback_Device_Reservation_Status( __DiskArbGetDiskID( disk ), kDiskArbDeviceReservationObtained, getpid( ) ); 796 } 797 } 798} 799 800static DADissenterRef __DiskArbDiskClaimReleaseCallback( DADiskRef disk, void * context ) 801{ 802 DADissenterRef dissenter = NULL; 803 804 if ( context == 0 ) 805 { 806 CFArrayRef callbacks; 807 808 callbacks = __DiskArbGetCallbackHandler( kDA_WILL_CLIENT_RELEASE_DEVICE ); 809 810 if ( callbacks ) 811 { 812 CFIndex count; 813 CFIndex index; 814 815 count = CFArrayGetCount( callbacks ); 816 817 if ( count ) 818 { 819 for ( index = 0; index < count; index++ ) 820 { 821 DiskArbCallback_Will_Client_Release_t callback; 822 823 callback = CFArrayGetValueAtIndex( callbacks, index ); 824 825 if ( callback ) 826 { 827 __gDiskArbAck = 0; 828 829 ( callback )( __DiskArbGetDiskID( disk ), -1 ); 830 831 if ( dissenter == NULL ) 832 { 833 if ( __gDiskArbAck == 0 ) 834 { 835 dissenter = DADissenterCreate( kCFAllocatorDefault, kDAReturnNotPermitted, NULL ); 836 } 837 } 838 } 839 } 840 } 841 else 842 { 843 dissenter = DADissenterCreate( kCFAllocatorDefault, kDAReturnNotPermitted, NULL ); 844 } 845 } 846 else 847 { 848 dissenter = DADissenterCreate( kCFAllocatorDefault, kDAReturnNotPermitted, NULL ); 849 } 850 } 851 852 if ( dissenter == NULL ) 853 { 854 CFSetRemoveValue( __gDiskArbReservationList, disk ); 855 } 856 857 return dissenter; 858} 859 860static void __DiskArbDiskDescriptionChangedCallback( DADiskRef disk, CFArrayRef keys, void * context ) 861{ 862 CFDictionaryRef description; 863 864 description = DADiskCopyDescription( disk ); 865 866 if ( description ) 867 { 868 if ( ___CFArrayContainsValue( keys, kDADiskDescriptionVolumeNameKey ) ) 869 { 870 if ( CFDictionaryGetValue( description, kDADiskDescriptionVolumePathKey ) ) 871 { 872 char * name; 873 char * path; 874 875 name = __DiskArbCopyDiskDescriptionVolumeName( disk ); 876 path = __DiskArbCopyDiskDescriptionVolumePath( disk ); 877 878 __DiskArbCallback_DiskChangedNotification( __DiskArbGetDiskID( disk ), path, name, 0, kDiskArbRenameSuccessful ); 879 880 if ( name ) free( name ); 881 if ( path ) free( path ); 882 } 883 } 884 else if ( ___CFArrayContainsValue( keys, kDADiskDescriptionVolumePathKey ) ) 885 { 886 if ( CFDictionaryGetValue( description, kDADiskDescriptionVolumePathKey ) ) 887 { 888 __DiskArbDiskAppearedCallback( disk, NULL ); 889 } 890 else 891 { 892 CFSetRemoveValue( __gDiskArbUnmountList, disk ); 893 894 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( disk ), 0, 0 ); 895 } 896 } 897 898 CFRelease( description ); 899 } 900} 901 902static void __DiskArbDiskDisappearedCallback( DADiskRef disk, void * context ) 903{ 904 CFDictionaryRef description; 905 906 CFSetRemoveValue( __gDiskArbUnmountList, disk ); 907 908 CFSetRemoveValue( __gDiskArbEjectList, disk ); 909 910 description = DADiskCopyDescription( disk ); 911 912 if ( description ) 913 { 914 if ( CFDictionaryGetValue( description, kDADiskDescriptionVolumePathKey ) ) 915 { 916 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( disk ), 0, 0 ); 917 } 918 919 CFRelease( description ); 920 } 921 922 __DiskArbCallback_EjectPostNotification( __DiskArbGetDiskID( disk ), 0, 0 ); 923} 924 925static void __DiskArbDiskEjectCallback( DADiskRef disk, DADissenterRef dissenter, void * context ) 926{ 927 if ( dissenter ) 928 { 929 io_service_t media; 930 DAReturn status; 931 932 status = DADissenterGetStatus( dissenter ); 933 934 media = DADiskCopyIOMedia( disk ); 935 936 if ( media ) 937 { 938 io_iterator_t services = IO_OBJECT_NULL; 939 940 IORegistryEntryCreateIterator( media, kIOServicePlane, kIORegistryIterateRecursively, &services ); 941 942 if ( services ) 943 { 944 io_service_t service; 945 946 while ( ( service = IOIteratorNext( services ) ) ) 947 { 948 if ( IOObjectConformsTo( service, kIOMediaClass ) ) 949 { 950 DADiskRef child; 951 952 child = DADiskCreateFromIOMedia( kCFAllocatorDefault, __gDiskArbSession, service ); 953 954 if ( child ) 955 { 956 CFSetRemoveValue( __gDiskArbEjectList, child ); 957 958 __DiskArbCallback_EjectPostNotification( __DiskArbGetDiskID( child ), status ? EBUSY : 0, status ? -1 : 0 ); 959 960 CFRelease( child ); 961 } 962 } 963 964 IOObjectRelease( service ); 965 } 966 967 IOObjectRelease( services ); 968 } 969 970 IOObjectRelease( media ); 971 } 972 973 CFSetRemoveValue( __gDiskArbEjectList, disk ); 974 975 __DiskArbCallback_EjectPostNotification( __DiskArbGetDiskID( disk ), status ? EBUSY : 0, status ? -1 : 0 ); 976 977 if ( ( ( ( int ) context ) & kDiskArbUnmountAndEjectFlag ) ) 978 { 979 __DiskArbCallback_CallFailedNotification( __DiskArbGetDiskID( disk ), kDiskArbUnmountAndEjectRequestFailed, status ? EBUSY : 0 ); 980 } 981 else 982 { 983 __DiskArbCallback_CallFailedNotification( __DiskArbGetDiskID( disk ), kDiskArbEjectRequestFailed, status ? EBUSY : 0 ); 984 } 985 } 986 else 987 { 988 io_service_t media; 989 990 media = DADiskCopyIOMedia( disk ); 991 992 if ( media ) 993 { 994 io_iterator_t services = IO_OBJECT_NULL; 995 996 IORegistryEntryCreateIterator( media, kIOServicePlane, kIORegistryIterateRecursively, &services ); 997 998 if ( services ) 999 { 1000 io_service_t service; 1001 1002 while ( ( service = IOIteratorNext( services ) ) ) 1003 { 1004 if ( IOObjectConformsTo( service, kIOMediaClass ) ) 1005 { 1006 DADiskRef child; 1007 1008 child = DADiskCreateFromIOMedia( kCFAllocatorDefault, __gDiskArbSession, service ); 1009 1010 if ( child ) 1011 { 1012 CFSetRemoveValue( __gDiskArbEjectList, child ); 1013 1014 __DiskArbCallback_EjectPostNotification( __DiskArbGetDiskID( child ), 0, 0 ); 1015 1016 CFRelease( child ); 1017 } 1018 } 1019 1020 IOObjectRelease( service ); 1021 } 1022 1023 IOObjectRelease( services ); 1024 } 1025 1026 IOObjectRelease( media ); 1027 } 1028 1029 CFSetRemoveValue( __gDiskArbEjectList, disk ); 1030 1031 __DiskArbCallback_EjectPostNotification( __DiskArbGetDiskID( disk ), 0, 0 ); 1032 } 1033} 1034 1035static DADissenterRef __DiskArbDiskEjectApprovalCallback( DADiskRef disk, void * context ) 1036{ 1037 CFArrayRef callbacks; 1038 DADissenterRef dissenter = NULL; 1039 1040 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_EJECT_PRE_NOTIFY ); 1041 1042 if ( callbacks ) 1043 { 1044 io_service_t media; 1045 1046 media = DADiskCopyIOMedia( disk ); 1047 1048 if ( media ) 1049 { 1050 io_iterator_t services = IO_OBJECT_NULL; 1051 1052 IORegistryEntryCreateIterator( media, kIOServicePlane, kIORegistryIterateRecursively, &services ); 1053 1054 if ( services ) 1055 { 1056 io_service_t service; 1057 1058 IOObjectRetain( media ); 1059 1060 for ( service = media; service; service = IOIteratorNext( services ) ) 1061 { 1062 if ( IOObjectConformsTo( service, kIOMediaClass ) ) 1063 { 1064 DADiskRef child; 1065 1066 child = DADiskCreateFromIOMedia( kCFAllocatorDefault, __gDiskArbSession, service ); 1067 1068 if ( child ) 1069 { 1070 CFIndex count; 1071 CFIndex index; 1072 1073 count = CFArrayGetCount( callbacks ); 1074 1075 for ( index = 0; index < count; index++ ) 1076 { 1077 DiskArbCallback_EjectPreNotification_t callback; 1078 1079 callback = CFArrayGetValueAtIndex( callbacks, index ); 1080 1081 if ( callback ) 1082 { 1083 __gDiskArbAck = 0; 1084 1085 ( callback )( __DiskArbGetDiskID( child ), 0 ); 1086 1087 if ( dissenter == NULL ) 1088 { 1089 switch ( __gDiskArbAck ) 1090 { 1091 case 0: 1092 { 1093 break; 1094 } 1095 default: 1096 { 1097 dissenter = DADissenterCreate( kCFAllocatorDefault, kDAReturnNotPermitted, NULL ); 1098 1099 break; 1100 } 1101 } 1102 } 1103 } 1104 } 1105 1106 CFSetSetValue( __gDiskArbEjectList, child ); 1107 1108 CFRelease( child ); 1109 } 1110 } 1111 1112 IOObjectRelease( service ); 1113 } 1114 1115 IOObjectRelease( services ); 1116 } 1117 1118 IOObjectRelease( media ); 1119 } 1120 } 1121 1122 return dissenter; 1123} 1124 1125static void __DiskArbDiskMountCallback( DADiskRef disk, DADissenterRef dissenter, void * context ) 1126{ 1127 if ( dissenter ) 1128 { 1129///w:start 1130 DAReturn status; 1131 1132 status = DADissenterGetStatus( dissenter ); 1133 1134 if ( __gDiskArbStatusLock ) 1135 { 1136 if ( status ) 1137 { 1138 __gDiskArbStatus = status; 1139 1140 return; 1141 } 1142 } 1143///w:stop 1144 __DiskArbDiskAppearedCallback( disk, NULL ); 1145 } 1146 else 1147 { 1148 if ( context ) 1149 { 1150 __DiskArbDiskAppearedCallback( disk, NULL ); 1151 } 1152 } 1153} 1154 1155static DADissenterRef __DiskArbDiskMountApprovalCallback( DADiskRef disk, void * context ) 1156{ 1157 CFArrayRef callbacks = NULL; 1158 char * content = NULL; 1159 DADissenterRef dissenter = NULL; 1160 char * filesystem = NULL; 1161 unsigned flags = 0; 1162 char * name = NULL; 1163 char * path = NULL; 1164 int removable = FALSE; 1165 int whole = FALSE; 1166 int writable = FALSE; 1167 1168 content = __DiskArbCopyDiskDescriptionMediaContent( disk ); 1169 filesystem = __DiskArbCopyDiskDescriptionVolumeKind( disk ); 1170 flags = __DiskArbCopyDiskDescriptionFlags( disk ); 1171 name = __DiskArbCopyDiskDescriptionVolumeName( disk ); 1172 path = __DiskArbCopyDiskDescriptionDeviceTreePath( disk ); 1173 removable = ( flags & kDiskArbDiskAppearedEjectableMask ) ? TRUE : FALSE; 1174 whole = ( flags & kDiskArbDiskAppearedWholeDiskMask ) ? TRUE : FALSE; 1175 writable = ( flags & kDiskArbDiskAppearedLockedMask ) ? FALSE : TRUE; 1176 1177 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_APPROVAL_NOTIFY ); 1178 1179 if ( callbacks ) 1180 { 1181 CFIndex count; 1182 CFIndex index; 1183 1184 count = CFArrayGetCount( callbacks ); 1185 1186 for ( index = 0; index < count; index++ ) 1187 { 1188 DiskArbCallback_DiskApprovalNotification_t callback; 1189 1190 callback = CFArrayGetValueAtIndex( callbacks, index ); 1191 1192 if ( callback ) 1193 { 1194 __gDiskArbAck = 0; 1195 1196 ( callback )( __DiskArbGetDiskID( disk ), name, content, path, flags, writable, removable, whole, filesystem ); 1197 1198 if ( dissenter == NULL ) 1199 { 1200///w:start 1201 if ( ( __gDiskArbAck & kDiskArbEjectDevice ) ) 1202 { 1203 if ( removable ) 1204 { 1205 DiskArbEjectRequest_async_auto( __DiskArbGetDiskID( disk ), 0 ); 1206 } 1207 1208 __gDiskArbAck &= ~kDiskArbEjectDevice; 1209 1210 if ( __gDiskArbAck == 0 ) 1211 { 1212 __gDiskArbAck = kDiskArbDisallowMounting; 1213 } 1214 } 1215///w:stop 1216 1217 switch ( __gDiskArbAck ) 1218 { 1219 case 0: 1220 { 1221 break; 1222 } 1223///w:start 1224 case kDiskArbMountReadOnly | kDiskArbRequireAuthentication: 1225 { 1226 dissenter = DADissenterCreate( kCFAllocatorDefault, 0xF8DAFF03, NULL ); 1227 1228 break; 1229 } 1230 case kDiskArbMountReadOnly: 1231 { 1232 dissenter = DADissenterCreate( kCFAllocatorDefault, 0xF8DAFF02, NULL ); 1233 1234 break; 1235 } 1236 case kDiskArbRequireAuthentication: 1237 { 1238 dissenter = DADissenterCreate( kCFAllocatorDefault, 0xF8DAFF01, NULL ); 1239 1240 break; 1241 } 1242///w:stop 1243 default: 1244 { 1245 dissenter = DADissenterCreate( kCFAllocatorDefault, kDAReturnNotPermitted, NULL ); 1246 1247 break; 1248 } 1249 } 1250 } 1251 } 1252 } 1253 } 1254 1255 if ( content ) free( content ); 1256 if ( filesystem ) free( filesystem ); 1257 if ( name ) free( name ); 1258 if ( path ) free( path ); 1259 1260 return dissenter; 1261} 1262 1263static void __DiskArbDiskPeekCallback( DADiskRef disk, void * context ) 1264{ 1265 CFDictionaryRef description = NULL; 1266 unsigned flags = 0; 1267 CFStringRef kind = NULL; 1268 int removable = FALSE; 1269 UInt64 size = 0; 1270 int type = 0; 1271 int whole = FALSE; 1272 int writable = FALSE; 1273 1274 description = DADiskCopyDescription( disk ); 1275 1276 if ( description ) 1277 { 1278 flags = __DiskArbCopyDiskDescriptionFlags( disk ); 1279 kind = CFDictionaryGetValue( description, kDADiskDescriptionMediaKindKey ); 1280 removable = ( flags & kDiskArbDiskAppearedEjectableMask ) ? TRUE : FALSE; 1281 size = ___CFDictionaryGetIntegerValue( description, kDADiskDescriptionMediaSizeKey ); 1282 whole = ( flags & kDiskArbDiskAppearedWholeDiskMask ) ? TRUE : FALSE; 1283 writable = ( flags & kDiskArbDiskAppearedLockedMask ) ? FALSE : TRUE; 1284 1285 if ( CFEqual( kind, CFSTR( kIOBDMediaClass ) ) ) 1286 { 1287 type = size ? kDiskArbHandlesUnrecognizedBDMedia : kDiskArbHandlesUninitializedBDMedia; 1288 } 1289 else if ( CFEqual( kind, CFSTR( kIOCDMediaClass ) ) ) 1290 { 1291 type = size ? kDiskArbHandlesUnrecognizedCDMedia : kDiskArbHandlesUninitializedCDMedia; 1292 } 1293 else if ( CFEqual( kind, CFSTR( kIODVDMediaClass ) ) ) 1294 { 1295 type = size ? kDiskArbHandlesUnrecognizedDVDMedia : kDiskArbHandlesUninitializedDVDMedia; 1296 } 1297 else if ( CFDictionaryGetValue( description, kDADiskDescriptionMediaEjectableKey ) == kCFBooleanTrue ) 1298 { 1299 type = size ? kDiskArbHandlesUnrecognizedOtherRemovableMedia : kDiskArbHandlesUninitializedOtherRemovableMedia; 1300 } 1301 else 1302 { 1303 type = size ? kDiskArbHandlesUnrecognizedFixedMedia : kDiskArbHandlesUninitializedFixedMedia; 1304 } 1305 1306 CFRelease( description ); 1307 } 1308 1309 if ( context ) 1310 { 1311 if ( __gDiskArbHandlesUnrecognized ) 1312 { 1313 DADiskClaim( disk, kDADiskClaimOptionDefault, __DiskArbDiskClaimReleaseCallback, ( void * ) 1, __DiskArbDiskClaimCallback, ( void * ) 1 ); 1314 } 1315 } 1316 else 1317 { 1318 if ( __gDiskArbHandlesUnrecognizedPriority > 0 ) 1319 { 1320 if ( ( __gDiskArbHandlesUnrecognizedTypes & type ) ) 1321 { 1322 CFArrayRef callbacks; 1323 1324 callbacks = __DiskArbGetCallbackHandler( kDA_CLIENT_WILL_HANDLE_UNRECOGNIZED_DISK ); 1325 1326 if ( callbacks ) 1327 { 1328 CFIndex count; 1329 CFIndex index; 1330 1331 count = CFArrayGetCount( callbacks ); 1332 1333 for ( index = 0; index < count; index++ ) 1334 { 1335 DiskArbCallback_Will_Client_Handle_Unrecognized_Disk_t callback; 1336 1337 callback = CFArrayGetValueAtIndex( callbacks, index ); 1338 1339 ( callback )( __DiskArbGetDiskID( disk ), type, "", "", writable, removable, whole ); 1340 } 1341 } 1342 } 1343 } 1344 } 1345} 1346 1347static void __DiskArbDiskRenameCallback( DADiskRef disk, DADissenterRef dissenter, void * context ) 1348{ 1349 if ( dissenter ) 1350 { 1351 DAReturn status; 1352 1353 status = DADissenterGetStatus( dissenter ); 1354///w:start 1355 if ( __gDiskArbStatusLock ) 1356 { 1357 if ( status ) 1358 { 1359 __gDiskArbStatus = status; 1360 1361 return; 1362 } 1363 } 1364///w:stop 1365 1366 __DiskArbCallback_DiskChangedNotification( __DiskArbGetDiskID( disk ), "", "", 0, 0 ); 1367 1368 __DiskArbCallback_CallFailedNotification( __DiskArbGetDiskID( disk ), kDiskArbDiskChangeRequestFailed, status ? EBUSY : 0 ); 1369 } 1370} 1371 1372static void __DiskArbDiskUnmountCallback( DADiskRef disk, DADissenterRef dissenter, void * context ) 1373{ 1374 if ( dissenter ) 1375 { 1376 DAReturn status; 1377 1378 status = DADissenterGetStatus( dissenter ); 1379///w:start 1380 if ( __gDiskArbStatusLock ) 1381 { 1382 if ( status ) 1383 { 1384 __gDiskArbStatus = status; 1385 1386 return; 1387 } 1388 } 1389///w:stop 1390 1391 if ( ( ( ( int ) context ) & kDiskArbUnmountOneFlag ) == 0 ) 1392 { 1393 io_service_t media; 1394 1395 media = DADiskCopyIOMedia( disk ); 1396 1397 if ( media ) 1398 { 1399 io_iterator_t services = IO_OBJECT_NULL; 1400 1401 IORegistryEntryCreateIterator( media, kIOServicePlane, kIORegistryIterateRecursively, &services ); 1402 1403 if ( services ) 1404 { 1405 io_service_t service; 1406 1407 while ( ( service = IOIteratorNext( services ) ) ) 1408 { 1409 if ( IOObjectConformsTo( service, kIOMediaClass ) ) 1410 { 1411 DADiskRef child; 1412 1413 child = DADiskCreateFromIOMedia( kCFAllocatorDefault, __gDiskArbSession, service ); 1414 1415 if ( child ) 1416 { 1417 if ( __DiskArbGetFileSystemStatus( __DiskArbGetDiskID( child ) ) ) 1418 { 1419 CFSetRemoveValue( __gDiskArbUnmountList, child ); 1420 1421 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( child ), status ? EBUSY : 0, status ? -1 : 0 ); 1422 } 1423 1424 CFRelease( child ); 1425 } 1426 } 1427 1428 IOObjectRelease( service ); 1429 } 1430 1431 IOObjectRelease( services ); 1432 } 1433 1434 IOObjectRelease( media ); 1435 } 1436 } 1437 1438 if ( status == kDAReturnNotMounted ) 1439 { 1440 CFSetRemoveValue( __gDiskArbUnmountList, disk ); 1441 1442 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( disk ), 0, 0 ); 1443 } 1444 else 1445 { 1446 CFSetRemoveValue( __gDiskArbUnmountList, disk ); 1447 1448 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( disk ), status ? EBUSY : 0, status ? -1 : 0 ); 1449 1450 if ( ( ( ( int ) context ) & kDiskArbUnmountAndEjectFlag ) ) 1451 { 1452 __DiskArbCallback_CallFailedNotification( __DiskArbGetDiskID( disk ), kDiskArbUnmountAndEjectRequestFailed, status ? EBUSY : 0 ); 1453 } 1454 else 1455 { 1456 __DiskArbCallback_CallFailedNotification( __DiskArbGetDiskID( disk ), kDiskArbUnmountRequestFailed, status ? EBUSY : 0 ); 1457 } 1458 } 1459 } 1460 else 1461 { 1462 if ( ( ( ( int ) context ) & kDiskArbUnmountOneFlag ) == 0 ) 1463 { 1464 CFSetRemoveValue( __gDiskArbUnmountList, disk ); 1465 1466 __DiskArbCallback_UnmountPostNotification( __DiskArbGetDiskID( disk ), 0, 0 ); 1467 } 1468 1469 if ( ( ( ( int ) context ) & kDiskArbUnmountAndEjectFlag ) ) 1470 { 1471 DADiskEject( disk, kDADiskEjectOptionDefault, __DiskArbDiskEjectCallback, ( void * ) kDiskArbUnmountAndEjectFlag ); 1472 } 1473 } 1474} 1475 1476static DADissenterRef __DiskArbDiskUnmountApprovalCallback( DADiskRef disk, void * context ) 1477{ 1478 CFArrayRef callbacks; 1479 DADissenterRef dissenter = NULL; 1480 1481 callbacks = __DiskArbGetCallbackHandler( kDA_DISK_UNMOUNT_PRE_NOTIFY ); 1482 1483 if ( callbacks ) 1484 { 1485 CFIndex count; 1486 CFIndex index; 1487 1488 count = CFArrayGetCount( callbacks ); 1489 1490 for ( index = 0; index < count; index++ ) 1491 { 1492 DiskArbCallback_UnmountPreNotification_t callback; 1493 1494 callback = CFArrayGetValueAtIndex( callbacks, index ); 1495 1496 if ( callback ) 1497 { 1498 __gDiskArbAck = 0; 1499 1500 ( callback )( __DiskArbGetDiskID( disk ), 0 ); 1501 1502 if ( dissenter == NULL ) 1503 { 1504 switch ( __gDiskArbAck ) 1505 { 1506 case 0: 1507 { 1508 break; 1509 } 1510 default: 1511 { 1512 dissenter = DADissenterCreate( kCFAllocatorDefault, kDAReturnNotPermitted, NULL ); 1513 1514 break; 1515 } 1516 } 1517 } 1518 } 1519 } 1520 1521 CFSetSetValue( __gDiskArbUnmountList, disk ); 1522 } 1523 1524 return dissenter; 1525} 1526 1527static void __DiskArbIdleCallback( void * context ) 1528{ 1529 CFArrayRef callbacks; 1530 1531 CFSetApplyFunction( __gDiskArbUnmountList, __DiskArbCallback_UnmountPostNotificationApplier, ( void * ) 1 ); 1532 1533 CFSetRemoveAllValues( __gDiskArbUnmountList ); 1534 1535 CFSetApplyFunction( __gDiskArbEjectList, __DiskArbCallback_EjectPostNotificationApplier, ( void * ) 1 ); 1536 1537 CFSetRemoveAllValues( __gDiskArbEjectList ); 1538 1539 callbacks = __DiskArbGetCallbackHandler( kDA_NOTIFICATIONS_COMPLETE ); 1540 1541 if ( callbacks ) 1542 { 1543 CFIndex count; 1544 CFIndex index; 1545 1546 count = CFArrayGetCount( callbacks ); 1547 1548 for ( index = 0; index < count; index++ ) 1549 { 1550 DiskArbCallback_NotificationComplete_t callback; 1551 1552 callback = CFArrayGetValueAtIndex( callbacks, index ); 1553 1554 if ( callback ) 1555 { 1556 if ( ( __gDiskArbNotificationComplete & kDiskArbCompletedDiskAppeared ) ) 1557 { 1558 ( callback )( kDiskArbCompletedDiskAppeared ); 1559 } 1560 1561 if ( ( __gDiskArbNotificationComplete & kDiskArbCompletedPostUnmount ) ) 1562 { 1563 ( callback )( kDiskArbCompletedPostUnmount ); 1564 } 1565 1566 if ( ( __gDiskArbNotificationComplete & kDiskArbCompletedPostEject ) ) 1567 { 1568 ( callback )( kDiskArbCompletedPostEject ); 1569 } 1570 } 1571 } 1572 } 1573 1574 __gDiskArbNotificationComplete = 0; 1575} 1576 1577void DiskArbAddCallbackHandler( int type, void * callback, int overwrite ) 1578{ 1579 if ( __gDiskArbCallbackList == NULL ) 1580 { 1581 __gDiskArbCallbackList = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); 1582 1583 assert( __gDiskArbCallbackList ); 1584 1585 __gDiskArbEjectList = CFSetCreateMutable( kCFAllocatorDefault, 0, &kCFTypeSetCallBacks ); 1586 1587 assert( __gDiskArbEjectList ); 1588 1589 __gDiskArbRegisterList = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks ); 1590 1591 assert( __gDiskArbRegisterList ); 1592 1593 __gDiskArbReservationList = CFSetCreateMutable( kCFAllocatorDefault, 0, &kCFTypeSetCallBacks ); 1594 1595 assert( __gDiskArbReservationList ); 1596 1597 __gDiskArbUnmountList = CFSetCreateMutable( kCFAllocatorDefault, 0, &kCFTypeSetCallBacks ); 1598 1599 assert( __gDiskArbUnmountList ); 1600 } 1601 1602 if ( callback ) 1603 { 1604 CFNumberRef key; 1605 1606 key = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &type ); 1607 1608 if ( key ) 1609 { 1610 CFMutableArrayRef callbacks; 1611 1612 callbacks = ( void * ) CFDictionaryGetValue( __gDiskArbCallbackList, key ); 1613 1614 if ( callbacks ) 1615 { 1616 CFRetain( callbacks ); 1617 } 1618 else 1619 { 1620 callbacks = CFArrayCreateMutable( kCFAllocatorDefault, 0, NULL ); 1621 1622 CFArrayAppendValue( __gDiskArbRegisterList, key ); 1623 } 1624 1625 if ( callbacks ) 1626 { 1627 if ( overwrite ) 1628 { 1629 CFArrayRemoveAllValues( callbacks ); 1630 } 1631 1632 CFArrayAppendValue( callbacks, callback ); 1633 1634 CFDictionarySetValue( __gDiskArbCallbackList, key, callbacks ); 1635 1636 CFRelease( callbacks ); 1637 } 1638 1639 CFRelease( key ); 1640 } 1641 } 1642} 1643 1644kern_return_t DiskArbClientHandlesUninitializedDisks_auto( int yes ) 1645{ 1646 if ( __gDiskArbSession ) 1647 { 1648 static Boolean registered = FALSE; 1649 1650 __gDiskArbHandlesUnrecognized = yes; 1651 1652 if ( yes ) 1653 { 1654 if ( registered == FALSE ) 1655 { 1656 DARegisterDiskPeekCallback( __gDiskArbSession, kDADiskDescriptionMatchVolumeUnrecognized, -16384, __DiskArbDiskPeekCallback, ( void * ) 1 ); 1657 1658 registered = TRUE; 1659 } 1660 } 1661 } 1662 1663 return KERN_SUCCESS; 1664} 1665 1666kern_return_t DiskArbClientHandlesUnrecognizedDisks( int types, int priority ) 1667{ 1668 if ( __gDiskArbSession ) 1669 { 1670 static Boolean registered = FALSE; 1671 1672 __gDiskArbHandlesUnrecognizedPriority = priority; 1673 __gDiskArbHandlesUnrecognizedTypes = types; 1674 1675 if ( priority > 0 ) 1676 { 1677 if ( registered == FALSE ) 1678 { 1679 DARegisterDiskPeekCallback( __gDiskArbSession, kDADiskDescriptionMatchVolumeUnrecognized, 16384 - priority, __DiskArbDiskPeekCallback, NULL ); 1680 1681 registered = TRUE; 1682 } 1683 } 1684 } 1685 1686 return KERN_SUCCESS; 1687} 1688 1689kern_return_t DiskArbClientRelinquishesReservation( char * disk, int pid, int status ) 1690{ 1691 __gDiskArbAck = status; 1692 1693 return KERN_SUCCESS; 1694} 1695 1696kern_return_t DiskArbClientWillHandleUnrecognizedDisk( char * disk, int yes ) 1697{ 1698 if ( yes ) 1699 { 1700 DADiskRef _disk; 1701 1702 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 1703 1704 if ( _disk ) 1705 { 1706 DADiskClaim( _disk, kDADiskClaimOptionDefault, __DiskArbDiskClaimReleaseCallback, NULL, __DiskArbDiskClaimCallback, ( void * ) 1 ); 1707 1708 CFRelease( _disk ); 1709 } 1710 } 1711 1712 return KERN_SUCCESS; 1713} 1714 1715kern_return_t DiskArbDiskAppearedWithMountpointPing_auto( char * disk, unsigned reserved, char * mountpoint ) 1716{ 1717 return KERN_SUCCESS; 1718} 1719 1720kern_return_t DiskArbDiskApprovedAck_auto( char * disk, int status ) 1721{ 1722 __gDiskArbAck = status; 1723 1724 return KERN_SUCCESS; 1725} 1726 1727kern_return_t DiskArbDiskDisappearedPing_auto( char * disk, unsigned reserved ) 1728{ 1729 return KERN_SUCCESS; 1730} 1731 1732kern_return_t DiskArbEjectPreNotifyAck_async_auto( char * disk, int status ) 1733{ 1734 __gDiskArbAck = status; 1735 1736 return KERN_SUCCESS; 1737} 1738 1739kern_return_t DiskArbEjectRequest_async_auto( char * disk, unsigned flags ) 1740{ 1741 kern_return_t status; 1742 1743 status = KERN_FAILURE; 1744 1745 if ( disk ) 1746 { 1747 DADiskRef _disk; 1748 1749 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 1750 1751 if ( _disk ) 1752 { 1753 DADiskRef whole; 1754 1755 whole = DADiskCopyWholeDisk( _disk ); 1756 1757 if ( whole ) 1758 { 1759 DADiskEject( whole, kDADiskEjectOptionDefault, __DiskArbDiskEjectCallback, NULL ); 1760 1761 status = KERN_SUCCESS; 1762 1763 CFRelease( whole ); 1764 } 1765 1766 CFRelease( _disk ); 1767 } 1768 } 1769 1770 return status; 1771} 1772 1773int DiskArbGetVolumeEncoding_auto( char * disk ) 1774{ 1775 struct attr_text_encoding_t 1776 { 1777 size_t size; 1778 text_encoding_t text_encoding; 1779 }; 1780 1781 struct attr_text_encoding_t attr; 1782 struct attrlist attrlist; 1783 struct statfs * fs; 1784 1785 bzero( &attrlist, sizeof( attrlist ) ); 1786 1787 attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; 1788 attrlist.commonattr = ATTR_CMN_SCRIPT; 1789 1790 fs = __DiskArbGetFileSystemStatus( disk ); 1791 1792 return fs ? ( getattrlist( fs->f_mntonname, &attrlist, &attr, sizeof( attr ), 0 ) ? -1 : ( int ) attr.text_encoding ) : -1; 1793} 1794 1795boolean_t DiskArbHandleMsg( mach_msg_header_t * message, mach_msg_header_t * reply ) 1796{ 1797 if ( reply ) 1798 { 1799 reply->msgh_bits = MACH_MSGH_BITS_ZERO; 1800 reply->msgh_id = 0; 1801 reply->msgh_local_port = MACH_PORT_NULL; 1802 reply->msgh_remote_port = MACH_PORT_NULL; 1803 reply->msgh_reserved = 0; 1804 reply->msgh_size = sizeof( mach_msg_header_t ); 1805 } 1806 1807 if ( message->msgh_id == 0 ) 1808 { 1809 _DASessionCallback( NULL, message, message->msgh_size, __gDiskArbSession ); 1810 1811 return TRUE; 1812 } 1813 1814 return FALSE; 1815} 1816 1817kern_return_t DiskArbInit( void ) 1818{ 1819 if ( __gDiskArbSession == NULL ) 1820 { 1821 __gDiskArbSession = DASessionCreate( kCFAllocatorDefault ); 1822 1823 if ( __gDiskArbSession ) 1824 { 1825 _DASessionScheduleWithRunLoop( __gDiskArbSession ); 1826 } 1827 } 1828 1829 return __gDiskArbSession ? BOOTSTRAP_SUCCESS : BOOTSTRAP_UNKNOWN_SERVICE; 1830} 1831 1832int DiskArbIsActive( void ) 1833{ 1834 return __gDiskArbSession ? 1 : 0; 1835} 1836 1837kern_return_t DiskArbIsDeviceReservedForClient( char * disk ) 1838{ 1839 kern_return_t status; 1840 1841 status = KERN_FAILURE; 1842 1843 if ( disk ) 1844 { 1845 DADiskRef _disk; 1846 1847 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 1848 1849 if ( _disk ) 1850 { 1851 status = DADiskIsClaimed( _disk ) ? kDiskArbDeviceIsReserved : kDiskArbDeviceIsNotReserved; 1852 1853 if ( CFSetContainsValue( __gDiskArbReservationList, _disk ) ) 1854 { 1855 __DiskArbCallback_Device_Reservation_Status( disk, status, getpid( ) ); 1856 } 1857 else 1858 { 1859 __DiskArbCallback_Device_Reservation_Status( disk, status, -1 ); 1860 } 1861 1862 status = KERN_SUCCESS; 1863 1864 CFRelease( _disk ); 1865 } 1866 } 1867 1868 return status; 1869} 1870 1871kern_return_t DiskArbMsgLoop( void ) 1872{ 1873 return DiskArbMsgLoopWithTimeout( MACH_MSG_TIMEOUT_NONE ); 1874} 1875 1876kern_return_t DiskArbMsgLoopWithTimeout( mach_msg_timeout_t timeout ) 1877{ 1878 mach_msg_return_t status; 1879 1880 status = KERN_FAILURE; 1881 1882 if ( __gDiskArbSession ) 1883 { 1884 mach_msg_empty_rcv_t message; 1885 1886 status = mach_msg( ( void * ) &message, 1887 MACH_RCV_MSG | ( timeout ? MACH_RCV_TIMEOUT : 0 ), 1888 0, 1889 sizeof( message ), 1890 _DASessionGetClientPort( __gDiskArbSession ), 1891 timeout, 1892 MACH_PORT_NULL ); 1893 1894 if ( status == MACH_MSG_SUCCESS ) 1895 { 1896 DiskArbHandleMsg( ( void * ) &message, NULL ); 1897 } 1898 } 1899 1900 return status; 1901} 1902 1903void DiskArbNoOp( void ) 1904{ 1905 return; 1906} 1907 1908kern_return_t DiskArbRefresh_auto( void ) 1909{ 1910 return KERN_SUCCESS; 1911} 1912 1913void DiskArbRegisterCallback_CallFailedNotification( DiskArbCallback_CallFailedNotification_t callback ) 1914{ 1915 DiskArbAddCallbackHandler( kDA_CALL_FAILED, callback, 0 ); 1916} 1917 1918void DiskArbRegisterCallback_CallSucceededNotification( DiskArbCallback_CallSucceededNotification_t callback ) 1919{ 1920 return; 1921} 1922 1923void DiskArbRegisterCallback_ClientDisconnectedNotification( DiskArbCallback_ClientDisconnectedNotification_t callback ) 1924{ 1925 return; 1926} 1927 1928void DiskArbRegisterCallback_DiskAppeared( DiskArbCallback_DiskAppeared_t callback ) 1929{ 1930 DiskArbAddCallbackHandler( kDA_DISK_APPEARED1, callback, 0 ); 1931} 1932 1933void DiskArbRegisterCallback_DiskAppeared2( DiskArbCallback_DiskAppeared2_t callback ) 1934{ 1935 DiskArbAddCallbackHandler( kDA_DISK_APPEARED, callback, 0 ); 1936} 1937 1938void DiskArbRegisterCallback_DiskAppearedWithMountpoint( DiskArbCallback_DiskAppearedWithMountpoint_t callback ) 1939{ 1940 DiskArbAddCallbackHandler( kDA_DISK_APPEARED_WITH_MT, callback, 0 ); 1941} 1942 1943void DiskArbRegisterCallback_DiskChangedNotification( DiskArbCallback_DiskChangedNotification_t callback ) 1944{ 1945 DiskArbAddCallbackHandler( kDA_DISK_CHANGED, callback, 0 ); 1946} 1947 1948void DiskArbRegisterCallback_DiskWillBeCheckedNotification( DiskArbCallback_DiskWillBeCheckedNotification_t callback ) 1949{ 1950 return; 1951} 1952 1953void DiskArbRegisterCallback_EjectPostNotification( DiskArbCallback_EjectPostNotification_t callback ) 1954{ 1955 DiskArbAddCallbackHandler( kDA_DISK_EJECT_POST_NOTIFY, callback, 0 ); 1956} 1957 1958void DiskArbRegisterCallback_EjectPreNotification( DiskArbCallback_EjectPreNotification_t callback ) 1959{ 1960 DiskArbAddCallbackHandler( kDA_DISK_EJECT_PRE_NOTIFY, callback, 1 ); 1961} 1962 1963void DiskArbRegisterCallback_NotificationComplete( DiskArbCallback_NotificationComplete_t callback ) 1964{ 1965 DiskArbAddCallbackHandler( kDA_NOTIFICATIONS_COMPLETE, callback, 0 ); 1966} 1967 1968void DiskArbRegisterCallback_UnknownFileSystemNotification( DiskArbCallback_UnknownFileSystemNotification_t callback ) 1969{ 1970 return; 1971} 1972 1973void DiskArbRegisterCallback_UnmountPostNotification( DiskArbCallback_UnmountPostNotification_t callback ) 1974{ 1975 DiskArbAddCallbackHandler( kDA_DISK_UNMOUNT_POST_NOTIFY, callback, 0 ); 1976} 1977 1978void DiskArbRegisterCallback_UnmountPreNotification( DiskArbCallback_UnmountPreNotification_t callback ) 1979{ 1980 DiskArbAddCallbackHandler( kDA_DISK_UNMOUNT_PRE_NOTIFY, callback, 1 ); 1981} 1982 1983kern_return_t DiskArbReleaseClientReservationForDevice( char * disk ) 1984{ 1985 kern_return_t status; 1986 1987 status = KERN_FAILURE; 1988 1989 if ( disk ) 1990 { 1991 DADiskRef _disk; 1992 1993 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 1994 1995 if ( _disk ) 1996 { 1997 CFSetRemoveValue( __gDiskArbReservationList, _disk ); 1998 1999 DADiskUnclaim( _disk ); 2000 2001 status = KERN_SUCCESS; 2002 2003 CFRelease( _disk ); 2004 } 2005 } 2006 2007 return status; 2008} 2009 2010void DiskArbRemoveCallbackHandler( int type, void * callback ) 2011{ 2012 if ( __gDiskArbCallbackList ) 2013 { 2014 CFNumberRef key; 2015 2016 key = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &type ); 2017 2018 if ( key ) 2019 { 2020 CFMutableArrayRef callbacks; 2021 2022 callbacks = ( void * ) CFDictionaryGetValue( __gDiskArbCallbackList, key ); 2023 2024 if ( callbacks ) 2025 { 2026 ___CFArrayRemoveValue( callbacks, callback ); 2027 } 2028 2029 CFRelease( key ); 2030 } 2031 } 2032} 2033 2034kern_return_t DiskArbRequestDiskChange_auto( char * disk, char * name, int flags ) 2035{ 2036 kern_return_t status; 2037 2038 status = KERN_FAILURE; 2039 2040 if ( disk ) 2041 { 2042 DADiskRef _disk; 2043 2044 _disk = NULL; 2045 2046 if ( strncmp( disk, "disk", strlen( "disk" ) ) ) 2047 { 2048 struct statfs * fs; 2049 2050 fs = __DiskArbGetFileSystemStatus( disk ); 2051 2052 if ( fs ) 2053 { 2054 CFURLRef path; 2055 2056 path = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, ( void * ) fs->f_mntonname, strlen( fs->f_mntonname ), TRUE ); 2057 2058 if ( path ) 2059 { 2060 _disk = DADiskCreateFromVolumePath( kCFAllocatorDefault, __gDiskArbSession, path ); 2061 2062 CFRelease( path ); 2063 } 2064 } 2065 } 2066 else 2067 { 2068 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2069 } 2070 2071 if ( _disk ) 2072 { 2073 CFStringRef string; 2074 2075 string = CFStringCreateWithCString( kCFAllocatorDefault, name, kCFStringEncodingUTF8 ); 2076 2077 if ( string ) 2078 { 2079///w:start 2080 __gDiskArbStatusLock = TRUE; 2081 __gDiskArbStatus = KERN_SUCCESS; 2082///w:stop 2083 DADiskRename( _disk, string, kDADiskRenameOptionDefault, __DiskArbDiskRenameCallback, ( void * ) flags ); 2084 2085 status = KERN_SUCCESS; 2086///w:start 2087 status = __gDiskArbStatus ? KERN_FAILURE : KERN_SUCCESS; 2088 __gDiskArbStatusLock = FALSE; 2089///w:stop 2090 2091 CFRelease( string ); 2092 } 2093 2094 CFRelease( _disk ); 2095 } 2096 } 2097 2098 return status; 2099} 2100 2101kern_return_t DiskArbRequestMount_auto( char * disk ) 2102{ 2103 kern_return_t status; 2104 2105 status = KERN_FAILURE; 2106 2107 if ( disk ) 2108 { 2109 DADiskRef _disk; 2110 2111 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2112 2113 if ( _disk ) 2114 { 2115 DADiskRef whole; 2116 2117 whole = DADiskCopyWholeDisk( _disk ); 2118 2119 if ( whole ) 2120 { 2121 if ( CFEqual( whole, _disk ) ) 2122 { 2123///w:start 2124 __gDiskArbStatusLock = TRUE; 2125 __gDiskArbStatus = KERN_SUCCESS; 2126///w:stop 2127 DADiskMount( _disk, NULL, kDADiskMountOptionWhole, __DiskArbDiskMountCallback, ( void * ) 1 ); 2128 2129 status = KERN_SUCCESS; 2130///w:start 2131 status = __gDiskArbStatus ? KERN_FAILURE : KERN_SUCCESS; 2132 __gDiskArbStatusLock = FALSE; 2133///w:stop 2134 } 2135 2136 CFRelease( whole ); 2137 } 2138 2139 if ( status ) 2140 { 2141///w:start 2142 __gDiskArbStatusLock = TRUE; 2143 __gDiskArbStatus = KERN_SUCCESS; 2144///w:stop 2145 DADiskMount( _disk, NULL, kDADiskMountOptionDefault, __DiskArbDiskMountCallback, NULL ); 2146 2147 status = KERN_SUCCESS; 2148///w:start 2149 status = __gDiskArbStatus ? KERN_FAILURE : KERN_SUCCESS; 2150 __gDiskArbStatusLock = FALSE; 2151///w:stop 2152 } 2153 2154 CFRelease( _disk ); 2155 } 2156 } 2157 2158 return status; 2159} 2160 2161kern_return_t DiskArbRequestMountAndOwn_auto( char * disk ) 2162{ 2163 return DiskArbRequestMount_auto( disk ); 2164} 2165 2166kern_return_t DiskArbRetainClientReservationForDevice( char * disk ) 2167{ 2168 kern_return_t status; 2169 2170 status = KERN_FAILURE; 2171 2172 if ( disk ) 2173 { 2174 DADiskRef _disk; 2175 2176 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2177 2178 if ( _disk ) 2179 { 2180 DADiskClaim( _disk, kDADiskClaimOptionDefault, __DiskArbDiskClaimReleaseCallback, NULL, __DiskArbDiskClaimCallback, NULL ); 2181 2182 status = KERN_SUCCESS; 2183 2184 CFRelease( _disk ); 2185 } 2186 } 2187 2188 return status; 2189} 2190 2191kern_return_t DiskArbSetCurrentUser_auto( int user ) 2192{ 2193 return KERN_FAILURE; 2194} 2195 2196kern_return_t DiskArbSetVolumeEncoding_auto( char * disk, int encoding ) 2197{ 2198 kern_return_t status; 2199 2200 status = KERN_FAILURE; 2201 2202 if ( disk ) 2203 { 2204 DADiskRef _disk; 2205 2206 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2207 2208 if ( _disk ) 2209 { 2210 status = _DADiskSetEncoding( _disk, encoding ); 2211 2212 CFRelease( _disk ); 2213 } 2214 } 2215 2216 return status; 2217} 2218 2219kern_return_t DiskArbStart( mach_port_t * port ) 2220{ 2221 kern_return_t status; 2222 2223 status = DiskArbInit( ); 2224 2225 if ( status == KERN_SUCCESS ) 2226 { 2227 DiskArbUpdateClientFlags( ); 2228 2229 *port = _DASessionGetClientPort( __gDiskArbSession ); 2230 } 2231 2232 return status; 2233} 2234 2235kern_return_t DiskArbUnmountAndEjectRequest_async_auto( char * disk, unsigned flags ) 2236{ 2237 return DiskArbUnmountRequest_async_auto( disk, flags | kDiskArbUnmountAndEjectFlag ); 2238} 2239 2240kern_return_t DiskArbUnmountPreNotifyAck_async_auto( char * disk, int status ) 2241{ 2242 __gDiskArbAck = status; 2243 2244 return KERN_SUCCESS; 2245} 2246 2247kern_return_t DiskArbUnmountRequest_async_auto( char * disk, unsigned flags ) 2248{ 2249 kern_return_t status; 2250 2251 status = KERN_FAILURE; 2252 2253 if ( disk ) 2254 { 2255 DADiskRef _disk; 2256 2257 _disk = NULL; 2258 2259 if ( strncmp( disk, "disk", strlen( "disk" ) ) ) 2260 { 2261 struct statfs * fs; 2262 2263 fs = __DiskArbGetFileSystemStatus( disk ); 2264 2265 if ( fs ) 2266 { 2267 CFURLRef path; 2268 2269 path = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, ( void * ) fs->f_mntonname, strlen( fs->f_mntonname ), TRUE ); 2270 2271 if ( path ) 2272 { 2273 flags |= kDiskArbUnmountOneFlag; 2274 flags &= ~kDiskArbUnmountAndEjectFlag; 2275 2276 if ( ( flags & kDiskArbNetworkUnmountFlag ) ) 2277 { 2278 flags |= kDiskArbForceUnmountFlag; 2279 } 2280 2281 _disk = DADiskCreateFromVolumePath( kCFAllocatorDefault, __gDiskArbSession, path ); 2282 2283 CFRelease( path ); 2284 } 2285 } 2286 } 2287 else 2288 { 2289 if ( ( flags & kDiskArbUnmountAndEjectFlag ) ) 2290 { 2291 flags &= ~kDiskArbUnmountOneFlag; 2292 } 2293 2294 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2295 } 2296 2297 if ( _disk ) 2298 { 2299 DADiskUnmountOptions options = 0; 2300 2301 if ( ( flags & kDiskArbForceUnmountFlag ) ) 2302 { 2303 options |= kDADiskUnmountOptionForce; 2304 } 2305 2306 if ( ( flags & kDiskArbUnmountOneFlag ) ) 2307 { 2308///w:start 2309 __gDiskArbStatusLock = TRUE; 2310 __gDiskArbStatus = KERN_SUCCESS; 2311///w:stop 2312 DADiskUnmount( _disk, options, __DiskArbDiskUnmountCallback, ( void * ) kDiskArbUnmountOneFlag ); 2313 2314 status = KERN_SUCCESS; 2315///w:start 2316 status = __gDiskArbStatus ? KERN_FAILURE : KERN_SUCCESS; 2317 __gDiskArbStatusLock = FALSE; 2318///w:stop 2319 } 2320 else 2321 { 2322 DADiskRef whole; 2323 2324 whole = DADiskCopyWholeDisk( _disk ); 2325 2326 if ( whole ) 2327 { 2328 options |= kDADiskUnmountOptionWhole; 2329 2330///w:start 2331 __gDiskArbStatusLock = TRUE; 2332 __gDiskArbStatus = KERN_SUCCESS; 2333///w:stop 2334 DADiskUnmount( whole, options, __DiskArbDiskUnmountCallback, ( void * ) ( flags & kDiskArbUnmountAndEjectFlag ) ); 2335 2336 status = KERN_SUCCESS; 2337///w:start 2338 status = __gDiskArbStatus ? KERN_FAILURE : KERN_SUCCESS; 2339 __gDiskArbStatusLock = FALSE; 2340///w:stop 2341 2342 CFRelease( whole ); 2343 } 2344 } 2345 2346 CFRelease( _disk ); 2347 } 2348 } 2349 2350 return status; 2351} 2352 2353void DiskArbUpdateClientFlags( void ) 2354{ 2355 if ( __gDiskArbSession ) 2356 { 2357 if ( __gDiskArbRegisterList ) 2358 { 2359 CFIndex count; 2360 CFIndex index; 2361 2362 count = CFArrayGetCount( __gDiskArbRegisterList ); 2363 2364 for ( index = 0; index < count; index++ ) 2365 { 2366 CFNumberRef key; 2367 2368 key = CFArrayGetValueAtIndex( __gDiskArbRegisterList, index ); 2369 2370 if ( key ) 2371 { 2372 int type; 2373 2374 CFNumberGetValue( key, kCFNumberIntType, &type ); 2375 2376 switch ( type ) 2377 { 2378 case kDA_DISK_APPEARED: 2379 case kDA_DISK_APPEARED1: 2380 case kDA_DISK_APPEARED_COMPLETE: 2381 case kDA_DISK_APPEARED_WITH_MT: 2382 case kDA_DISK_CHANGED: 2383 case kDA_DISK_EJECT_POST_NOTIFY: 2384 case kDA_DISK_UNMOUNT_POST_NOTIFY: 2385 { 2386 static Boolean registered = FALSE; 2387 2388 if ( registered == FALSE ) 2389 { 2390 DARegisterDiskDescriptionChangedCallback( __gDiskArbSession, NULL, NULL, __DiskArbDiskDescriptionChangedCallback, NULL ); 2391 2392 DARegisterDiskDisappearedCallback( __gDiskArbSession, NULL, __DiskArbDiskDisappearedCallback, NULL ); 2393 2394 DARegisterDiskAppearedCallback( __gDiskArbSession, NULL, __DiskArbDiskAppearedCallback, NULL ); 2395 2396 registered = TRUE; 2397 } 2398 2399 break; 2400 } 2401 case kDA_DISK_APPROVAL_NOTIFY: 2402 { 2403 DARegisterDiskMountApprovalCallback( ( void * ) __gDiskArbSession, NULL, __DiskArbDiskMountApprovalCallback, NULL ); 2404 2405 break; 2406 } 2407 case kDA_DISK_EJECT_PRE_NOTIFY: 2408 { 2409 DARegisterDiskEjectApprovalCallback( ( void * ) __gDiskArbSession, NULL, __DiskArbDiskEjectApprovalCallback, NULL ); 2410 2411 break; 2412 } 2413 case kDA_DISK_UNMOUNT_PRE_NOTIFY: 2414 { 2415 DARegisterDiskUnmountApprovalCallback( ( void * ) __gDiskArbSession, NULL, __DiskArbDiskUnmountApprovalCallback, NULL ); 2416 2417 break; 2418 } 2419 case kDA_NOTIFICATIONS_COMPLETE: 2420 { 2421 DARegisterIdleCallback( __gDiskArbSession, __DiskArbIdleCallback, NULL ); 2422 2423 break; 2424 } 2425 } 2426 } 2427 } 2428 2429 CFArrayRemoveAllValues( __gDiskArbRegisterList ); 2430 } 2431 } 2432} 2433 2434kern_return_t DiskArbVSDBAdoptVolume_auto( char * disk ) 2435{ 2436 kern_return_t status; 2437 2438 status = KERN_FAILURE; 2439 2440 if ( disk ) 2441 { 2442 DADiskRef _disk; 2443 2444 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2445 2446 if ( _disk ) 2447 { 2448 status = _DADiskSetAdoption( _disk, TRUE ); 2449 2450 CFRelease( _disk ); 2451 } 2452 } 2453 2454 return status; 2455} 2456 2457kern_return_t DiskArbVSDBDisownVolume_auto( char * disk ) 2458{ 2459 kern_return_t status; 2460 2461 status = KERN_FAILURE; 2462 2463 if ( disk ) 2464 { 2465 DADiskRef _disk; 2466 2467 _disk = DADiskCreateFromBSDName( kCFAllocatorDefault, __gDiskArbSession, disk ); 2468 2469 if ( _disk ) 2470 { 2471 status = _DADiskSetAdoption( _disk, FALSE ); 2472 2473 CFRelease( _disk ); 2474 } 2475 } 2476 2477 return status; 2478} 2479 2480int DiskArbVSDBGetVolumeStatus_auto( char * disk ) 2481{ 2482 struct statfs * fs; 2483 2484 fs = __DiskArbGetFileSystemStatus( disk ); 2485 2486 return fs ? ( ( fs->f_flags & MNT_IGNORE_OWNERSHIP ) ? 2 : 1 ) : 0; 2487} 2488 2489#endif /* !__LP64__ */ 2490 2491DAReturn _DADiskSetAdoption( DADiskRef disk, Boolean adoption ) 2492{ 2493 DAReturn status; 2494 2495 status = _DAAuthorize( _DADiskGetSession( disk ), _kDAAuthorizeOptionDefault, disk, _kDAAuthorizeRightAdopt ); 2496 2497 if ( status == kDAReturnSuccess ) 2498 { 2499 status = _DAServerDiskSetAdoption( _DADiskGetSessionID( disk ), _DADiskGetID( disk ), adoption ); 2500 } 2501 2502 return status; 2503} 2504 2505DAReturn _DADiskSetEncoding( DADiskRef disk, UInt32 encoding ) 2506{ 2507 DAReturn status; 2508 2509 status = _DAAuthorize( _DADiskGetSession( disk ), _kDAAuthorizeOptionIsOwner, disk, _kDAAuthorizeRightEncode ); 2510 2511 if ( status == kDAReturnSuccess ) 2512 { 2513 status = _DAServerDiskSetEncoding( _DADiskGetSessionID( disk ), _DADiskGetID( disk ), encoding ); 2514 } 2515 2516 return status; 2517} 2518 2519void DARegisterIdleCallback( DASessionRef session, DAIdleCallback callback, void * context ) 2520{ 2521 _DARegisterCallback( session, callback, context, _kDAIdleCallback, 0, NULL, NULL ); 2522} 2523