Beispiel #1
0
static void __DAStageMountAuthorization( DADiskRef disk )
{
    /*
     * We commence the "mount authorization" stage if the conditions are right.
     */

    /*
     * Commence the mount authorization.
     */

    DADiskSetState( disk, kDADiskStateStagedAuthorize, TRUE );

///w:start
    if ( DADiskGetState( disk, _kDADiskStateRequireAuthorize ) )
///w:stop
    {
        DASessionRef session;
        CFArrayRef   sessionList;
        CFIndex      sessionListCount;
        CFIndex      sessionListIndex;

        CFRetain( disk );

        DADiskSetState( disk, kDADiskStateCommandActive, TRUE );

        sessionList      = gDASessionList;
        sessionListCount = CFArrayGetCount( sessionList );

        for ( sessionListIndex = 0; sessionListIndex < sessionListCount; sessionListIndex++ )
        {
            session = ( void * ) CFArrayGetValueAtIndex( sessionList, sessionListIndex );

            if ( strcmp( _DASessionGetName( session ), "SystemUIServer" ) == 0 )
            {
                break;
            }
        }

        if ( sessionListIndex < sessionListCount )
        {
            DAAuthorizeWithCallback( session,
                                     _kDAAuthorizeOptionAuthenticateAdministrator,
                                     disk,
                                     ___UID_ROOT,
                                     ___GID_WHEEL,
                                     __DAStageMountAuthorizationCallback,
                                     disk,
                                     _kDAAuthorizeRightMount );
        }
        else
        {
            __DAStageMountAuthorizationCallback( kDAReturnNotPrivileged, disk );
        }
    }
    else
    {
        DAStageSignal( );
    }
}
Beispiel #2
0
static void __DAStageProbe( DADiskRef disk )
{
    /*
     * We commence the "probe" stage if the conditions are right.
     */

    if ( DAUnitGetState( disk, kDAUnitStateCommandActive ) == FALSE )
    {
        CFMutableArrayRef candidates;

        candidates = CFArrayCreateMutableCopy( kCFAllocatorDefault, 0, gDAFileSystemProbeList );

        if ( candidates )
        {
            CFNumberRef size;

            /*
             * Determine whether the disk is formatted.
             */

            size = DADiskGetDescription( disk, kDADiskDescriptionMediaSizeKey );

            if ( size )
            {
                if ( ___CFNumberGetIntegerValue( size ) == 0 )
                {
                    CFArrayRemoveAllValues( candidates );
                }
            }

            /*
             * Commence the probe.
             */

            CFRetain( disk );

            DADiskSetFileSystem( disk, NULL );

            DADiskSetContext( disk, candidates );

            DADiskSetState( disk, kDADiskStateStagedProbe, TRUE );

            DADiskSetState( disk, kDADiskStateCommandActive, TRUE );

            DAUnitSetState( disk, kDAUnitStateCommandActive, TRUE );

            __DAStageProbeCallback( -1, NULL, NULL, NULL, disk );

            CFRelease( candidates );
        }
    }
}
Beispiel #3
0
static void __DAStagePeekCallback( CFTypeRef response, void * context )
{
    CFMutableArrayRef candidates;
    DADiskRef         disk = context;

    candidates = ( void * ) DADiskGetContext( disk );

    if ( CFArrayGetCount( candidates ) )
    {
        DACallbackRef candidate;

        candidate = ( void * ) CFArrayGetValueAtIndex( candidates, 0 );

        CFRetain( candidate );

        CFArrayRemoveValueAtIndex( candidates, 0 );

        DADiskPeekCallback( disk, candidate, __DAStagePeekCallback, context );

        CFRelease( candidate );

        return;
    }
    
    DADiskSetState( disk, kDADiskStateCommandActive, FALSE );

    DADiskSetContext( disk, NULL );

    DAStageSignal( );

    CFRelease( disk );
}
Beispiel #4
0
static void __DAStageMountCallback( int status, CFURLRef mountpoint, void * context )
{
    DADiskRef disk = context;

    if ( status == 0 )
    {
        /*
         * We were able to mount the volume.
         */

        DADiskSetBypath( disk, mountpoint );

        DADiskSetDescription( disk, kDADiskDescriptionVolumePathKey, mountpoint );

        if ( DADiskGetState( disk, kDADiskStateStagedAppear ) )
        {
            DADiskDescriptionChangedCallback( disk, kDADiskDescriptionVolumePathKey );
        }
    }

    DAUnitSetState( disk, kDAUnitStateCommandActive, FALSE );

    DADiskSetState( disk, kDADiskStateCommandActive, FALSE );

    DAStageSignal( );

    CFRelease( disk );
}
Beispiel #5
0
static void __DAStageMountApproval( DADiskRef disk )
{
    /*
     * We commence the "mount approval" stage if the conditions are right.
     */

    Boolean mount = TRUE;

    /*
     * Determine whether the disk is mountable.
     */

    if ( DADiskGetDescription( disk, kDADiskDescriptionVolumeMountableKey ) == kCFBooleanFalse )
    {
        mount = FALSE;
    }

    /*
     * Determine whether the disk is mounted.
     */

    if ( DADiskGetDescription( disk, kDADiskDescriptionVolumePathKey ) )
    {
        mount = FALSE;
    }

    /*
     * Commence the mount approval.
     */

    DADiskSetState( disk, kDADiskStateStagedApprove, TRUE );

    if ( mount )
    {
        CFRetain( disk );

        DADiskSetState( disk, kDADiskStateCommandActive, TRUE );

        DADiskMountApprovalCallback( disk, __DAStageMountApprovalCallback, disk );
    }
    else
    {
        DADiskSetState( disk, kDADiskStateStagedMount, TRUE );

        DAStageSignal( );
    }
}
Beispiel #6
0
static void __DAStageMountAuthorizationCallback( DAReturn status, void * context )
{
    DADiskRef disk = context;

    if ( status )
    {
        /*
         * The mount was unauthorized.
         */

        DADiskSetState( disk, kDADiskStateStagedMount, TRUE );
    }

    DADiskSetState( disk, kDADiskStateCommandActive, FALSE );

    DAStageSignal( );

    CFRelease( disk );
}
Beispiel #7
0
static void __DAStageAppeared( DADiskRef disk )
{
    /*
     * We commence the "appeared" stage if the conditions are right.
     */

    DADiskSetState( disk, kDADiskStateStagedAppear, TRUE );
    
    DADiskAppearedCallback( disk );

    DAStageSignal( );
}
Beispiel #8
0
static void __DAStageMount( DADiskRef disk )
{
    /*
     * We commence the "mount" stage if the conditions are right.
     */

    if ( DAUnitGetState( disk, kDAUnitStateCommandActive ) == FALSE )
    {
        /*
         * Commence the mount.
         */

        CFRetain( disk );

        DADiskSetState( disk, kDADiskStateStagedMount, TRUE );

        DADiskSetState( disk, kDADiskStateCommandActive, TRUE );

        DAUnitSetState( disk, kDAUnitStateCommandActive, TRUE );

        DAMountWithArguments( disk, NULL, __DAStageMountCallback, disk, CFSTR( "automatic" ), NULL );
    }
}
Beispiel #9
0
static void __DAMountWithArgumentsCallbackStage3( int status, void * parameter )
{
    /*
     * Process the "repair quotas" command's completion.
     */

    __DAMountCallbackContext * context = parameter;

    if ( status )
    {
        DALogError( "unable to repair quotas on disk %@ (status code 0x%08X).", context->disk, status );
    }
    else
    {
        DADiskSetState( context->disk, kDADiskStateRequireRepairQuotas, FALSE );
    }

    __DAMountWithArgumentsCallback( 0, context );
}
Beispiel #10
0
static void __DAStageMountApprovalCallback( CFTypeRef response, void * context )
{
    DADiskRef      disk      = context;
    DADissenterRef dissenter = response;

    if ( dissenter )
    {
        /*
         * The mount was disapproved.
         */

///w:start
        if ( DADissenterGetStatus( dissenter ) == 0xF8DAFF01 )
        {
            DADiskSetState( disk, _kDADiskStateRequireAuthorize, TRUE );
        }
        else if ( DADissenterGetStatus( dissenter ) == 0xF8DAFF02 )
        {
            DADiskSetState( disk, _kDADiskStateMountPreferenceNoWrite, TRUE );
        }
        else if ( DADissenterGetStatus( dissenter ) == 0xF8DAFF03 )
        {
            DADiskSetState( disk, _kDADiskStateRequireAuthorize, TRUE );

            DADiskSetState( disk, _kDADiskStateMountPreferenceNoWrite, TRUE );
        }
        else
///w:stop
        DADiskSetState( disk, kDADiskStateStagedMount, TRUE );
    }

    DADiskSetState( disk, kDADiskStateCommandActive, FALSE );

    DAStageSignal( );

    CFRelease( disk );
}
Beispiel #11
0
static void __DAStageProbeCallback( int status, CFBooleanRef clean, CFStringRef name, CFUUIDRef uuid, void * context )
{
    DADiskRef         disk = context;
    CFMutableArrayRef keys = NULL;
    CFStringRef       kind = NULL;

    DALogDebugHeader( "%s -> %s", gDAProcessNameID, gDAProcessNameID );

    if ( status )
    {
        CFMutableArrayRef candidates;

        candidates = ( void * ) DADiskGetContext( disk );

        if ( DADiskGetFileSystem( disk ) )
        {
            kind = DAFileSystemGetKind( DADiskGetFileSystem( disk ) );

            DALogDebug( "  probed disk, id = %@, with %@, failure.", disk, kind );

            if ( status != FSUR_UNRECOGNIZED )
            {
                DALogError( "unable to probe %@ (status code 0x%08X).", disk, status );
            }
        }

        /*
         * Find a probe candidate for this media object.
         */

        while ( CFArrayGetCount( candidates ) )
        {
            CFDictionaryRef candidate;

            candidate = CFArrayGetValueAtIndex( candidates, 0 );

            if ( candidate )
            {
                DAFileSystemRef filesystem;

                filesystem = ( void * ) CFDictionaryGetValue( candidate, kDAFileSystemKey );

                if ( filesystem )
                {
                    CFDictionaryRef properties;

                    properties = CFDictionaryGetValue( candidate, CFSTR( kFSMediaPropertiesKey ) );

                    if ( properties )
                    {
                        boolean_t match = FALSE;

                        IOServiceMatchPropertyTable( DADiskGetIOMedia( disk ), properties, &match );

                        if ( match )
                        {
                            /*
                             * We have found a probe candidate for this media object.
                             */

                            kind = DAFileSystemGetKind( filesystem );

                            DADiskSetFileSystem( disk, filesystem );

                            if ( CFDictionaryGetValue( candidate, CFSTR( "autodiskmount" ) ) == kCFBooleanFalse )
                            {
                                DADiskSetOption( disk, kDADiskOptionMountAutomatic,        FALSE );
                                DADiskSetOption( disk, kDADiskOptionMountAutomaticNoDefer, FALSE );
                            }

                            CFArrayRemoveValueAtIndex( candidates, 0 );

                            DALogDebug( "  probed disk, id = %@, with %@, ongoing.", disk, kind );

                            DAFileSystemProbe( filesystem, DADiskGetDevice( disk ), __DAStageProbeCallback, context );

                            return;
                        }
                    }
                }
            }

            CFArrayRemoveValueAtIndex( candidates, 0 );
        }
    }

    DADiskSetState( disk, kDADiskStateRequireRepair,       FALSE );
    DADiskSetState( disk, kDADiskStateRequireRepairQuotas, FALSE );

    if ( status )
    {
        /*
         * We have found no probe match for this media object.
         */

        kind = NULL;

        if ( DADiskGetFileSystem( disk ) )
        {
            DADiskSetFileSystem( disk, NULL );

            DALogDebug( "  probed disk, id = %@, no match.", disk );
        }
    }
    else
    {
        /*
         * We have found a probe match for this media object.
         */

        kind = DAFileSystemGetKind( DADiskGetFileSystem( disk ) );

///w:start
        if ( DADiskGetDescription( disk, kDADiskDescriptionMediaWritableKey ) == kCFBooleanFalse )
        {
            clean = kCFBooleanTrue;
        }
///w:stop
        if ( clean == kCFBooleanFalse )
        {
            DADiskSetState( disk, kDADiskStateRequireRepair,       TRUE );
            DADiskSetState( disk, kDADiskStateRequireRepairQuotas, TRUE );
        }

        DALogDebug( "  probed disk, id = %@, with %@, success.", disk, kind );
    }

    keys = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks );

    if ( keys )
    {
        CFTypeRef object;

        object = kind ? kCFBooleanTrue : kCFBooleanFalse;

        if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeMountableKey, object ) )
        {
            DADiskSetDescription( disk, kDADiskDescriptionVolumeMountableKey, object );

            CFArrayAppendValue( keys, kDADiskDescriptionVolumeMountableKey );
        }

        if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeKindKey, kind ) )
        {
            DADiskSetDescription( disk, kDADiskDescriptionVolumeKindKey, kind );

            CFArrayAppendValue( keys, kDADiskDescriptionVolumeKindKey );
        }

        if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeNameKey, name ) )
        {
            DADiskSetDescription( disk, kDADiskDescriptionVolumeNameKey, name );

            CFArrayAppendValue( keys, kDADiskDescriptionVolumeNameKey );
        }

        if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeUUIDKey, uuid ) )
        {
            DADiskSetDescription( disk, kDADiskDescriptionVolumeUUIDKey, uuid );

            CFArrayAppendValue( keys, kDADiskDescriptionVolumeUUIDKey );
        }

        if ( CFArrayGetCount( keys ) )
        {
            if ( DADiskGetState( disk, kDADiskStateStagedAppear ) )
            {
                DADiskDescriptionChangedCallback( disk, keys );
            }
        }

        CFRelease( keys );
    }

    if ( DADiskGetState( disk, kDADiskStateStagedMount ) == FALSE )
    {
        struct statfs * mountList;
        int             mountListCount;
        int             mountListIndex;

        /*
         * Determine whether the disk is mounted.
         */

        mountListCount = getmntinfo( &mountList, MNT_NOWAIT );

        for ( mountListIndex = 0; mountListIndex < mountListCount; mountListIndex++ )
        {
            if ( mountList[mountListIndex].f_fsid.val[0] == DADiskGetBSDNode( disk ) )
            {
                /*
                 * We have determined that the disk is mounted.
                 */

                CFURLRef path;

                path = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault,
                                                                ( void * ) mountList[mountListIndex].f_mntonname,
                                                                strlen( mountList[mountListIndex].f_mntonname ),
                                                                TRUE );

                if ( path )
                {
                    _DAMountCreateTrashFolder( disk, path );
                    
                    DADiskSetBypath( disk, path );

                    DADiskSetDescription( disk, kDADiskDescriptionVolumePathKey, path );

                    CFRelease( path );
                }

                if ( strcmp( mountList[mountListIndex].f_mntonname, "/" ) == 0 )
                {
                    path = DAMountCreateMountPointWithAction( disk, kDAMountPointActionLink );

                    if ( path )
                    {
                        DADiskSetBypath( disk, path );

                        CFRelease( path );
                    }

                    DADiskSetOption( disk, kDADiskOptionMountAutomatic,        TRUE );
                    DADiskSetOption( disk, kDADiskOptionMountAutomaticNoDefer, TRUE );
                }

                DADiskSetState( disk, kDADiskStateRequireRepair,       FALSE );
                DADiskSetState( disk, kDADiskStateRequireRepairQuotas, FALSE );

                break;
            }
        }
    }

    DAUnitSetState( disk, kDAUnitStateCommandActive, FALSE );

    DADiskSetState( disk, kDADiskStateCommandActive, FALSE );

    DADiskSetContext( disk, NULL );

    DAStageSignal( );

    CFRelease( disk );
}
Beispiel #12
0
static void __DAStageDispatch( void * info )
{
    static Boolean fresh = FALSE;

    CFIndex count;
    CFIndex index;
    Boolean quiet = TRUE;

    count = CFArrayGetCount( gDADiskList );

    for ( index = 0; index < count; index++ )
    {
        DADiskRef disk;

        disk = ( void * ) CFArrayGetValueAtIndex( gDADiskList, index );

        if ( DADiskGetState( disk, kDADiskStateCommandActive ) == FALSE )
        {
            if ( DADiskGetState( disk, kDADiskStateStagedProbe ) == FALSE )
            {
                if ( fresh )
                {
                    DAFileSystemListRefresh( );

                    DAMountMapListRefresh1( );
                    
                    DAMountMapListRefresh2( );

                    fresh = FALSE;
                }

                __DAStageProbe( disk );
            }
            else if ( DADiskGetState( disk, kDADiskStateStagedPeek ) == FALSE )
            {
                __DAStagePeek( disk );
            }
///w:start
            else if ( DADiskGetState( disk, kDADiskStateRequireRepair ) == FALSE )
            {
                if ( DADiskGetState( disk, kDADiskStateStagedApprove ) == FALSE )
                {
                    __DAStageMountApproval( disk );
                }
                else if ( DADiskGetState( disk, kDADiskStateStagedAuthorize ) == FALSE )
                {
                    __DAStageMountAuthorization( disk );
                }
                else if ( DADiskGetState( disk, kDADiskStateStagedMount ) == FALSE )
                {
                    __DAStageMount( disk );
                }
                else if ( DADiskGetState( disk, kDADiskStateStagedAppear ) == FALSE )
                {
                    __DAStageAppeared( disk );
                }
                else
                {
///w:start
                    if ( gDAConsoleUserList == NULL )
                    {
                        if ( DADiskGetDescription( disk, kDADiskDescriptionMediaTypeKey ) )
                        {
                            if ( DAUnitGetState( disk, kDAUnitStateStagedUnreadable ) == FALSE )
                            {
                                if ( _DAUnitIsUnreadable( disk ) )
                                {
                                    DADiskEject( disk, kDADiskEjectOptionDefault, NULL );
                                }

                                DAUnitSetState( disk, kDAUnitStateStagedUnreadable, TRUE );
                            }
                        }
                    }
///w:stop
                    continue;
                }
            }
///w:stop
            else if ( DADiskGetState( disk, kDADiskStateStagedAppear ) == FALSE )
            {
                /*
                 * We stall the "appeared" stage if the conditions are not right.
                 */

                if ( DADiskGetState( disk, kDADiskStateRequireRepair ) )
                {
                    CFIndex subcount;
                    CFIndex subindex;

                    subcount = CFArrayGetCount( gDADiskList );

                    for ( subindex = 0; subindex < subcount; subindex++ )
                    {
                        DADiskRef subdisk;

                        subdisk = ( void * ) CFArrayGetValueAtIndex( gDADiskList, subindex );

                        if ( DADiskGetBSDUnit( disk ) == DADiskGetBSDUnit( subdisk ) )
                        {
                            if ( DADiskGetState( subdisk, kDADiskStateStagedProbe ) == FALSE )
                            {
                                break;
                            }

                            if ( DADiskGetState( subdisk, kDADiskStateStagedAppear ) == FALSE )
                            {
                                if ( DADiskGetState( subdisk, kDADiskStateRequireRepair ) == FALSE )
                                {
                                    break;
                                }
                            }
                        }
                    }

                    if ( subindex == subcount )
                    {
                        __DAStageAppeared( disk );
                    }
                }
                else
                {
                    __DAStageAppeared( disk );
                }
            }
            else if ( DADiskGetState( disk, kDADiskStateStagedApprove ) == FALSE )
            {
                __DAStageMountApproval( disk );
            }
            else if ( DADiskGetState( disk, kDADiskStateStagedAuthorize ) == FALSE )
            {
                __DAStageMountAuthorization( disk );
            }
            else if ( DADiskGetState( disk, kDADiskStateStagedMount ) == FALSE )
            {
                if ( gDAExit )
                {
                    continue;
                }

                __DAStageMount( disk );
            }
            else
            {
                continue;
            }
        }

        quiet = FALSE;
    }

    count = CFArrayGetCount( gDARequestList );

    if ( count )
    {
        CFMutableSetRef dependencies;

        dependencies = CFSetCreateMutable( kCFAllocatorDefault, 0, &kCFTypeSetCallBacks );

        if ( dependencies )
        {
            for ( index = 0; index < count; index++ )
            {
                DARequestRef request;

                request = ( void * ) CFArrayGetValueAtIndex( gDARequestList, index );

                if ( request )
                {
                    DADiskRef disk;
                    Boolean   dispatch = TRUE;

                    disk = DARequestGetDisk( request );

                    /*
                     * Determine whether the request has undispatched dependencies.
                     */

                    if ( disk )
                    {
                        CFArrayRef link;

                        link = DARequestGetLink( request );

                        if ( link )
                        {
                            CFIndex subcount;
                            CFIndex subindex;

                            subcount = CFArrayGetCount( link );

                            for ( subindex = 0; subindex < subcount; subindex++ )
                            {
                                DARequestRef subrequest;

                                subrequest = ( void * ) CFArrayGetValueAtIndex( link, subindex );

                                if ( CFSetContainsValue( dependencies, DARequestGetDisk( subrequest ) ) )
                                {
                                    break;
                                }
                            }

                            if ( subindex < subcount )
                            {
                                dispatch = FALSE;
                            }
                        }

                        if ( CFSetContainsValue( dependencies, disk ) )
                        {
                            dispatch = FALSE;
                        }
                    }
                    else
                    {
                        if ( index )
                        {
                            break;
                        }
                    }

                    if ( dispatch )
                    {
                        /*
                         * Prepare to dispatch the request.
                         */

                        if ( DARequestGetKind( request ) == _kDADiskMount )
                        {
                            if ( fresh )
                            {
                                DAFileSystemListRefresh( );

                                DAMountMapListRefresh1( );

                                DAMountMapListRefresh2( );

                                fresh = FALSE;
                            }
                        }

                        /*
                         * Dispatch the request.
                         */

                        dispatch = DARequestDispatch( request );
                    }

                    if ( dispatch )
                    {
                        CFArrayRemoveValueAtIndex( gDARequestList, index );

                        count--;
                        index--;
                    }
                    else
                    {
                        /*
                         * Add the request to the undispatched dependencies.
                         */

                        if ( disk )
                        {
                            CFArrayRef link;

                            link = DARequestGetLink( request );

                            if ( link )
                            {
                                CFIndex subcount;
                                CFIndex subindex;

                                subcount = CFArrayGetCount( link );

                                for ( subindex = 0; subindex < subcount; subindex++ )
                                {
                                    DARequestRef subrequest;

                                    subrequest = ( void * ) CFArrayGetValueAtIndex( link, subindex );

                                    CFSetSetValue( dependencies, DARequestGetDisk( subrequest ) );
                                }
                            }

                            CFSetSetValue( dependencies, disk );
                        }
                    }
                }
            }

            CFRelease( dependencies );
        }

        quiet = FALSE;
    }

    if ( quiet )
    {
        fresh = TRUE;

        gDAIdle = TRUE;

        DAIdleCallback( );

        ___vproc_transaction_end( );

        if ( gDAConsoleUser )
        {
            /*
             * Determine whether a unit is unreadable or a volume is unrepairable.
             */

            count = CFArrayGetCount( gDADiskList );

            for ( index = 0; index < count; index++ )
            {
                DADiskRef disk;

                disk = ( void * ) CFArrayGetValueAtIndex( gDADiskList, index );

                /*
                 * Determine whether a unit is unreadable.
                 */

                if ( DADiskGetDescription( disk, kDADiskDescriptionMediaWholeKey ) == kCFBooleanTrue )
                {
                    if ( DAUnitGetState( disk, kDAUnitStateStagedUnreadable ) == FALSE )
                    {
                        if ( _DAUnitIsUnreadable( disk ) )
                        {
                            DADialogShowDeviceUnreadable( disk );
                        }

                        DAUnitSetState( disk, kDAUnitStateStagedUnreadable, TRUE );
                    }
                }

                /*
                 * Determine whether a volume is unrepairable.
                 */

                if ( DADiskGetDescription( disk, kDADiskDescriptionVolumePathKey ) )
                {
                    if ( DADiskGetState( disk, kDADiskStateStagedUnrepairable ) == FALSE )
                    {
                        if ( DADiskGetState( disk, kDADiskStateRequireRepair ) )
                        {
                            if ( DADiskGetOption( disk, kDADiskOptionMountAutomatic ) )
                            {
                                if ( DADiskGetClaim( disk ) == NULL )
                                {
                                    DADialogShowDeviceUnrepairable( disk );
                                }
                            }
                        }

                        DADiskSetState( disk, kDADiskStateStagedUnrepairable, TRUE );
                    }
                }
            }
        }
    }
}
Beispiel #13
0
static void __DAStagePeek( DADiskRef disk )
{
    /*
     * We commence the "peek" stage if the conditions are right.
     */

    CFMutableArrayRef candidates;

    candidates = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks );

    if ( candidates )
    {
        DASessionRef session;
        CFArrayRef   sessionList;
        CFIndex      sessionListCount;
        CFIndex      sessionListIndex;

        sessionList      = gDASessionList;
        sessionListCount = CFArrayGetCount( sessionList );

        for ( sessionListIndex = 0; sessionListIndex < sessionListCount; sessionListIndex++ )
        {
            DACallbackRef callback;
            CFArrayRef    callbackList;
            CFIndex       callbackListCount;
            CFIndex       callbackListIndex;
            
            session = ( void * ) CFArrayGetValueAtIndex( sessionList, sessionListIndex );

            callbackList      = DASessionGetCallbackRegister( session );
            callbackListCount = CFArrayGetCount( callbackList );

            for ( callbackListIndex = 0; callbackListIndex < callbackListCount; callbackListIndex++ )
            {
                callback = ( void * ) CFArrayGetValueAtIndex( callbackList, callbackListIndex );

                if ( DACallbackGetKind( callback ) == _kDADiskPeekCallback )
                {
                    CFArrayAppendValue( candidates, callback );
                }
            }
        }

        CFArraySortValues( candidates, CFRangeMake( 0, CFArrayGetCount( candidates ) ), __DAStagePeekCompare, NULL );

        /*
         * Commence the peek.
         */

        CFRetain( disk );

        DADiskSetContext( disk, candidates );

        DADiskSetState( disk, kDADiskStateStagedPeek, TRUE );

        DADiskSetState( disk, kDADiskStateCommandActive, TRUE );

        __DAStagePeekCallback( NULL, disk );

        CFRelease( candidates );
    }
}
Beispiel #14
0
static void __DAMountWithArgumentsCallbackStage1( int status, void * parameter )
{
    /*
     * Process the repair command's completion.
     */

    __DAMountCallbackContext * context = parameter;

    DALogDebugHeader( "%s -> %s", gDAProcessNameID, gDAProcessNameID );

    if ( context->assertionID != kIOPMNullAssertionID )
    {
        IOPMAssertionRelease( context->assertionID );

        context->assertionID = kIOPMNullAssertionID;
    }

    if ( status )
    {
        /*
         * We were unable to repair the volume.
         */

        if ( status == ECANCELED )
        {
            status = 0;
        }
        else
        {
            DALogDebug( "  repaired disk, id = %@, failure.", context->disk );

            DALogError( "unable to repair %@ (status code 0x%08X).", context->disk, status );

            if ( context->force )
            {
                status = 0;
            }
            else
            {
                __DAMountWithArgumentsCallback( ___EDIRTY, context );
            }
        }
    }
    else
    {
        /*
         * We were able to repair the volume.
         */

        DADiskSetState( context->disk, kDADiskStateRequireRepair, FALSE );

        DALogDebug( "  repaired disk, id = %@, success.", context->disk );
    }

    /*
     * Mount the volume.
     */

    if ( status == 0 )
    {
        /*
         * Create the mount point, in case one needs to be created.
         */

        if ( context->mountpoint == NULL )
        {
            context->mountpoint = DAMountCreateMountPointWithAction( context->disk, kDAMountPointActionMake );
        }

        /*
         * Execute the mount command.
         */

        if ( context->mountpoint )
        {
            DALogDebug( "  mounted disk, id = %@, ongoing.", context->disk );

            DAFileSystemMountWithArguments( DADiskGetFileSystem( context->disk ),
                                            DADiskGetDevice( context->disk ),
                                            context->mountpoint,
                                            DADiskGetUserUID( context->disk ),
                                            DADiskGetUserGID( context->disk ),
                                            __DAMountWithArgumentsCallbackStage2,
                                            context,
                                            context->options,
                                            NULL );
        }
        else
        {
            __DAMountWithArgumentsCallback( ENOSPC, context );
        }
    }
}
Beispiel #15
0
void DAMountWithArguments( DADiskRef disk, CFURLRef mountpoint, DAMountCallback callback, void * callbackContext, ... )
{
    /*
     * Mount the specified volume.  A status of 0 indicates success.  All arguments in
     * the argument list shall be of type CFStringRef.  The argument list must be NULL
     * terminated.
     */

    CFStringRef                argument   = NULL;
    va_list                    arguments;
    CFBooleanRef               automatic  = kCFBooleanTrue;
    CFBooleanRef               check      = NULL;
    __DAMountCallbackContext * context    = NULL;
    CFIndex                    count      = 0;
    DAFileSystemRef            filesystem = DADiskGetFileSystem( disk );
    Boolean                    force      = FALSE;
    CFIndex                    index      = 0;
    CFDictionaryRef            map        = NULL;
    CFMutableStringRef         options    = NULL;
    int                        status     = 0;

    DALogDebugHeader( "%s -> %s", gDAProcessNameID, gDAProcessNameID );

    /*
     * Initialize our minimal state.
     */

    if ( mountpoint )
    {
        CFRetain( mountpoint );
    }

    /*
     * Prepare the mount context.
     */

    context = malloc( sizeof( __DAMountCallbackContext ) );

    if ( context == NULL )
    {
        status = ENOMEM;

        goto DAMountWithArgumentsErr;
    }

    /*
     * Prepare the mount options.
     */

    options = CFStringCreateMutable( kCFAllocatorDefault, 0 );

    if ( options == NULL )
    {
        status = ENOMEM;

        goto DAMountWithArgumentsErr;
    }

    va_start( arguments, callbackContext );

    while ( ( argument = va_arg( arguments, CFStringRef ) ) )
    {
        if ( CFEqual( argument, kDAFileSystemMountArgumentForce ) )
        {
            force = TRUE;
        }
        else if ( CFEqual( argument, CFSTR( "automatic" ) ) )
        {
            automatic = NULL;

            check = kCFBooleanTrue;
        }
        else
        {
            CFStringAppend( options, argument );
            CFStringAppend( options, CFSTR( "," ) );
        }
    }

    va_end( arguments );

    CFStringTrim( options, CFSTR( "," ) );
///w:start
    context->automatic = ( automatic == NULL ) ? TRUE : FALSE;
///w:stop

    /*
     * Determine whether the volume is to be updated.
     */

    if ( DAMountContainsArgument( options, kDAFileSystemMountArgumentUpdate ) )
    {
        if ( mountpoint )
        {
            status = EINVAL;

            goto DAMountWithArgumentsErr;
        }

        mountpoint = DADiskGetDescription( disk, kDADiskDescriptionVolumePathKey );

        if ( mountpoint == NULL )
        {
            status = EINVAL;

            goto DAMountWithArgumentsErr;
        }

        CFRetain( mountpoint );
    }

    /*
     * Scan the mount map list.
     */

    count = CFArrayGetCount( gDAMountMapList1 );

    for ( index = 0; index < count; index++ )
    {
        map = CFArrayGetValueAtIndex( gDAMountMapList1, index );

        if ( map )
        {
            CFTypeRef   id;
            CFStringRef kind;

            id   = CFDictionaryGetValue( map, kDAMountMapProbeIDKey );
            kind = CFDictionaryGetValue( map, kDAMountMapProbeKindKey );

            if ( kind )
            {
                /*
                 * Determine whether the volume kind matches.
                 */

                if ( CFEqual( kind, DAFileSystemGetKind( filesystem ) ) == FALSE )
                {
                    continue;
                }
            }

            if ( CFGetTypeID( id ) == CFUUIDGetTypeID( ) )
            {
                /*
                 * Determine whether the volume UUID matches.
                 */

                if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeUUIDKey, id ) == kCFCompareEqualTo )
                {
                    break;
                }
            }
            else if ( CFGetTypeID( id ) == CFStringGetTypeID( ) )
            {
                /*
                 * Determine whether the volume name matches.
                 */

                if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeNameKey, id ) == kCFCompareEqualTo )
                {
                    break;
                }
            }
            else if ( CFGetTypeID( id ) == CFDictionaryGetTypeID( ) )
            {
                boolean_t match = FALSE;

                /*
                 * Determine whether the device description matches.
                 */

                IOServiceMatchPropertyTable( DADiskGetIOMedia( disk ), id, &match );

                if ( match )
                {
                    break;
                }
            }
        }
    }

    /*
     * Process the map.
     */

    if ( index < count )
    {
        CFStringRef string;

        /*
         * Determine whether the volume is to be mounted.
         */

        if ( automatic == NULL )
        {
            automatic = CFDictionaryGetValue( map, kDAMountMapMountAutomaticKey );

            if ( automatic == kCFBooleanTrue )
            {
                DADiskSetState( disk, _kDADiskStateMountAutomatic,        TRUE );
                DADiskSetState( disk, _kDADiskStateMountAutomaticNoDefer, TRUE );
            }
        }

        /*
         * Prepare the mount options.
         */

        string = CFDictionaryGetValue( map, kDAMountMapMountOptionsKey );

        if ( string )
        {
            CFStringInsert( options, 0, CFSTR( "," ) );
            CFStringInsert( options, 0, string );
        }

        /*
         * Prepare the mount point.
         */

        if ( mountpoint == NULL )
        {
            mountpoint = CFDictionaryGetValue( map, kDAMountMapMountPathKey );

            if ( mountpoint )
            {
                CFRetain( mountpoint );
            }
        }
    }

    /*
     * Scan the mount map list.
     */

    count = CFArrayGetCount( gDAMountMapList2 );

    for ( index = 0; index < count; index++ )
    {
        map = CFArrayGetValueAtIndex( gDAMountMapList2, index );

        if ( map )
        {
            CFTypeRef id;

            id = CFDictionaryGetValue( map, kDAMountMapProbeIDKey );

            /*
             * Determine whether the volume UUID matches.
             */

            if ( DADiskCompareDescription( disk, kDADiskDescriptionVolumeUUIDKey, id ) == kCFCompareEqualTo )
            {
                break;
            }
        }
    }

    /*
     * Process the map.
     */

    if ( index < count )
    {
        CFStringRef string;

        /*
         * Prepare the mount options.
         */

        string = CFDictionaryGetValue( map, kDAMountMapMountOptionsKey );

        if ( string )
        {
            CFStringInsert( options, 0, CFSTR( "," ) );
            CFStringInsert( options, 0, string );
        }
    }

    /*
     * Determine whether the volume is to be mounted.
     */

    if ( automatic == NULL )
    {
        if ( DADiskGetState( disk, _kDADiskStateMountAutomatic ) )
        {
            if ( DADiskGetState( disk, _kDADiskStateMountAutomaticNoDefer ) )
            {
                automatic = kCFBooleanTrue;
            }
        }
        else
        {
            automatic = kCFBooleanFalse;
        }

        if ( automatic == NULL )
        {
            if ( gDAConsoleUserList == NULL )
            {
                if ( DAMountGetPreference( disk, kDAMountPreferenceDefer ) )
                {
                    automatic = kCFBooleanFalse;
                }
            }
        }
    }

    if ( automatic == kCFBooleanFalse )
    {
        status = ECANCELED;

        goto DAMountWithArgumentsErr;
    }

    /*
     * Prepare the mount options.
     */

    if ( DADiskGetDescription( disk, kDADiskDescriptionMediaWritableKey ) == kCFBooleanFalse )
    {
        CFStringInsert( options, 0, CFSTR( "," ) );
        CFStringInsert( options, 0, kDAFileSystemMountArgumentNoWrite );
    }

    if ( DAMountGetPreference( disk, kDAMountPreferenceTrust ) == FALSE )
    {
        CFStringInsert( options, 0, CFSTR( "," ) );
        CFStringInsert( options, 0, kDAFileSystemMountArgumentNoSetUserID );

        CFStringInsert( options, 0, CFSTR( "," ) );
        CFStringInsert( options, 0, kDAFileSystemMountArgumentNoOwnership );

        CFStringInsert( options, 0, CFSTR( "," ) );
        CFStringInsert( options, 0, kDAFileSystemMountArgumentNoDevice );
    }
///w:start
    if ( CFEqual( DAFileSystemGetKind( filesystem ), CFSTR( "hfs" ) ) )
    {
        ___CFStringInsertFormat( options, 0, CFSTR( "-m=%o," ), 0755 );

        if ( DADiskGetUserGID( disk ) )
        {
            ___CFStringInsertFormat( options, 0, CFSTR( "-g=%d," ), DADiskGetUserGID( disk ) );
        }
        else
        {
            ___CFStringInsertFormat( options, 0, CFSTR( "-g=%d," ), ___GID_UNKNOWN );
        }

        if ( DADiskGetUserUID( disk ) )
        {
            ___CFStringInsertFormat( options, 0, CFSTR( "-u=%d," ), DADiskGetUserUID( disk ) );
        }
        else
        {
            ___CFStringInsertFormat( options, 0, CFSTR( "-u=%d," ), ___UID_UNKNOWN );
        }
    }
///w:stop

    CFStringTrim( options, CFSTR( "," ) );

    /*
     * Determine whether the volume is to be repaired.
     */

    if ( check == NULL )
    {
        if ( DAMountContainsArgument( options, kDAFileSystemMountArgumentNoWrite ) )
        {
            check = kCFBooleanFalse;
        }
        else
        {
            check = kCFBooleanTrue;
        }
    }

    if ( check == kCFBooleanFalse )
    {
        if ( DADiskGetState( disk, kDADiskStateRequireRepair ) )
        {
            if ( force == FALSE )
            {
                status = ___EDIRTY;

                goto DAMountWithArgumentsErr;
            }
        }
    }

    if ( check == kCFBooleanTrue )
    {
        if ( DADiskGetState( disk, kDADiskStateRequireRepair ) == FALSE )
        {
            check = kCFBooleanFalse;
        }
    }

    /*
     * Repair the volume.
     */

    CFRetain( disk );

    context->assertionID     = kIOPMNullAssertionID;
    context->callback        = callback;
    context->callbackContext = callbackContext;
    context->disk            = disk;
    context->force           = force;
    context->mountpoint      = mountpoint;
    context->options         = options;

    if ( check == kCFBooleanTrue )
    {
        DALogDebug( "  repaired disk, id = %@, ongoing.", disk );

        IOPMAssertionCreateWithDescription( kIOPMAssertionTypePreventUserIdleSystemSleep,
                                            CFSTR( _kDADaemonName ),
                                            NULL,
                                            NULL,
                                            NULL,
                                            0,
                                            NULL,
                                            &context->assertionID );

        DAFileSystemRepair( DADiskGetFileSystem( disk ),
                            DADiskGetDevice( disk ),
                            __DAMountWithArgumentsCallbackStage1,
                            context );
    }
    else
    {
        __DAMountWithArgumentsCallbackStage1( ECANCELED, context );
    }

DAMountWithArgumentsErr:

    if ( status )
    {
        if ( context )
        {
            free( context );
        }

        if ( mountpoint )
        {
            CFRelease( mountpoint );
        }

        if ( options )
        {
            CFRelease( options );
        }

        if ( callback )
        {
            ( callback )( status, NULL, callbackContext );
        }
    }
}
Beispiel #16
0
DAReturn _DADiskRefresh( DADiskRef disk )
{
    DAReturn status;

    status = kDAReturnUnsupported;

    if ( DADiskGetDescription( disk, kDADiskDescriptionVolumePathKey ) )
    {
        struct statfs * mountList;
        int             mountListCount;
        int             mountListIndex;

        mountListCount = getmntinfo( &mountList, MNT_NOWAIT );

        for ( mountListIndex = 0; mountListIndex < mountListCount; mountListIndex++ )
        {
            if ( strcmp( _DAVolumeGetID( mountList + mountListIndex ), DADiskGetID( disk ) ) == 0 )
            {
                break;
            }
        }

        if ( mountListIndex == mountListCount )
        {
            CFURLRef mountpoint;

            mountpoint = DADiskGetDescription( disk, kDADiskDescriptionVolumePathKey );

            CFRetain( mountpoint );

            DAThreadExecute( __DADiskRefreshRemoveMountPoint, ( void * ) mountpoint, NULL, NULL );

            DADiskSetBypath( disk, NULL );

            if ( DADiskGetDescription( disk, kDADiskDescriptionMediaPathKey ) )
            {
                DADiskSetDescription( disk, kDADiskDescriptionVolumePathKey, NULL );

                DADiskDescriptionChangedCallback( disk, kDADiskDescriptionVolumePathKey );
            }
            else
            {
                DALogDebugHeader( "bsd [0] -> %s", gDAProcessNameID );

                DALogDebug( "  removed disk, id = %@.", disk );

                DADiskDisappearedCallback( disk );

                DADiskSetDescription( disk, kDADiskDescriptionVolumePathKey, NULL );

                DADiskSetState( disk, kDADiskStateZombie, TRUE );

                ___CFArrayRemoveValue( gDADiskList, disk );
            }

            DAStageSignal( );
        }

        status = kDAReturnSuccess;
    }
    else
    {
        struct statfs * mountList;
        int             mountListCount;
        int             mountListIndex;

        mountListCount = getmntinfo( &mountList, MNT_NOWAIT );

        for ( mountListIndex = 0; mountListIndex < mountListCount; mountListIndex++ )
        {
            if ( strcmp( _DAVolumeGetID( mountList + mountListIndex ), DADiskGetID( disk ) ) == 0 )
            {
                break;
            }
        }

        if ( mountListIndex < mountListCount )
        {
            CFURLRef path;

            path = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault,
                                                            ( void * ) mountList[mountListIndex].f_mntonname,
                                                            strlen( mountList[mountListIndex].f_mntonname ),
                                                            TRUE );

            if ( path )
            {
                DADiskSetBypath( disk, path );

                DADiskSetDescription( disk, kDADiskDescriptionVolumePathKey, path );

                DADiskDescriptionChangedCallback( disk, kDADiskDescriptionVolumePathKey );

                DAStageSignal( );

                CFRelease( path );
            }
        }

        status = kDAReturnSuccess;
    }

    return status;
}