Determine if a network resource exists before installation

I am working on a tool for automatically installing network volumes based on which wireless network a user is connected to. Easy to install:

NSURL *volumeURL = /* The URL to the network volume */

// Attempt to mount the volume
FSVolumeRefNum volumeRefNum;
OSStatus error = FSMountServerVolumeSync((CFURLRef)volumeURL, NULL, NULL, NULL, &volumeRefNum, 0L);

However, if there is volumeURLno network resource (if someone disconnected or deleted the network hard drive, for example), Finder will display an error message explaining this fact. My goal is to prevent this from happening - I would like to try to set the volume, but it does not work if the installation failed.

Does anyone have any tips on how to do this? Ideally, I would like to find a way to check if a shared resource exists before trying to mount it (to avoid unnecessary work). If this is not possible, we can say that there is some opportunity to tell the Finder not to display an error message.

+5
source share
1 answer

This answer uses the Private Framework. As naixn notes in the comments, this means that it can break even when the point is released.

There is no way to do this using only the open API (which I can find after hours of searching / disassembling).

URL- - . , , ..

, Finder, , NetAuthApp CoreServices. (netfs_MountURLWithAuthenticationSync) (FSMountServerVolumeSync). kSuppressAllUI.

rc 0, NSStrings .

//
// compile with:
//
//  gcc -o test test.m -framework NetFS -framework Foundation
include <inttypes.h>
#include <Foundation/Foundation.h>

// Calls to FSMountServerVolumeSync result in kSoftMount being set
// kSuppressAllUI was found to exist here:
// http://www.opensource.apple.com/source/autofs/autofs-109.8/mount_url/mount_url.c
// its value was found by trial and error
const uint32_t kSoftMount     = 0x10000;
const uint32_t kSuppressAllUI = 0x00100;

int main(int argc, char** argv)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    NSURL *volumeURL = [NSURL URLWithString:@"afp://server/path"];
    NSArray* mountpoints = nil;

    const uint32_t flags = kSuppressAllUI | kSoftMount;

    const int rc = netfs_MountURLWithAuthenticationSync((CFURLRef)volumeURL, NULL, NULL,
            NULL, flags, (CFArrayRef)&mountpoints);

    NSLog(@"mountpoints: %@; status = 0x%x", mountpoints, rc);

    [pool release];
}
+6

All Articles