I am running into an issue getting the full url for a file with FSCopyURLForVolume
. I am using the code from this issue Determine AFP share from a file URL but it isn't giving me the full url. For example:
With a path like: /Volume/server/html/index.html
All I get back is url to the base mount: nfs://real_server_name/vol
Leaf directories and the file names are left off, the full path is available in the files info so there has to be a way to get this information.
EDIT:
After some more digging is seems like I want to use kFSCatInfoParentDirID
and kFSCatInfoNodeID
to get the parent and node(file) id but I'm not sure how to turn this into something useful.
because the FSPathMakeRef, FSGetCatalogInfo and FSCopyURLForVolume are deprecated from Mac OS X 10.8 I modernised the code for get UNC network path on Mac OS X mounted volumes.
NSError *error=nil; //Error
NSURL *volumePath=nil; //result of UNC network mounting path
NSString* testPath =@"/Volumes/SCAMBIO/testreport.exe"; //File path to test
NSURL *testUrl = [NSURL fileURLWithPath:testPath]; //Create a NSURL from file path
NSString* mountPath = [testPath stringByDeletingLastPathComponent]; //Get only mounted volume part i.e. /Volumes/SCAMBIO
NSString* pathComponents = [testPath substringFromIndex:[mountPath length]]; //Get the rest of the path starting after the mounted path i.e. /testereport.exe
[testUrl getResourceValue:&volumePath forKey:NSURLVolumeURLForRemountingKey error:&error]; //Get real UNC network mounted path i.e. smb://....
NSLog(@"Path: %@%@", volumePath,pathComponents); //Write result to debug console
The result is in my case,
Path: smb://FRANCESCO@192.168.69.44/SCAMBIO/testreport.exe
You need to specify your network mapped volume.
ciao.
A solution to this problem was suggested on the Apple Dev Forums, here is the final function I came up with:
- (NSURL *)volumeMountPathFromPath:(NSString *)path{
NSString *mountPath = nil;
NSString *testPath = [path copy];
while(![testPath isEqualToString:@"/"]){
NSURL *testUrl = [NSURL fileURLWithPath:testPath];
NSNumber *isVolumeKey;
[testUrl getResourceValue:&isVolumeKey forKey:NSURLIsVolumeKey error:nil];
if([isVolumeKey boolValue]){
mountPath = testPath;
break;
}
testPath = [testPath stringByDeletingLastPathComponent];
}
if(mountPath == nil){
return nil;
}
NSString *pathCompointents = [path substringFromIndex:[mountPath length]];
FSRef pathRef;
FSPathMakeRef((UInt8*)[path fileSystemRepresentation], &pathRef, NULL);
FSCatalogInfo catalogInfo;
OSErr osErr = FSGetCatalogInfo(&pathRef, kFSCatInfoVolume|kFSCatInfoParentDirID,
&catalogInfo, NULL, NULL, NULL);
FSVolumeRefNum volumeRefNum = 0;
if(osErr == noErr){
volumeRefNum = catalogInfo.volume;
}
CFURLRef serverLocation;
OSStatus result = FSCopyURLForVolume(volumeRefNum, &serverLocation);
if(result == noErr){
NSString *fullUrl = [NSString stringWithFormat:@"%@%@",
CFURLGetString(serverLocation), pathCompointents];
return [NSURL URLWithString:fullUrl];
}else{
NSLog(@"Error getting the mount path: %i", result);
}
return nil;
}