/* Get the Unix disk name of the volume */ static const char *SDL_SYS_CDName (int drive) { /* * !!! FIXME: PBHGetVolParmsSync() is gone in 10.6, * !!! FIXME: replaced with FSGetVolumeParms(), which * !!! FIXME: isn't available before 10.5. :/ */ return "Mac OS X CD-ROM Device"; #if 0 OSStatus err = noErr; HParamBlockRec pb; GetVolParmsInfoBuffer volParmsInfo; if (fakeCD) return "Fake CD-ROM Device"; pb.ioParam.ioNamePtr = NULL; pb.ioParam.ioVRefNum = volumes[drive]; pb.ioParam.ioBuffer = (Ptr)&volParmsInfo; pb.ioParam.ioReqCount = (SInt32)sizeof(volParmsInfo); err = PBHGetVolParmsSync(&pb); if (err != noErr) { SDL_SetError ("PBHGetVolParmsSync returned %d", err); return NULL; } return volParmsInfo.vMDeviceID; #endif }
QString Utils::filesystemName(QString path) { QString name; #if defined(Q_OS_WIN32) wchar_t volname[MAX_PATH+1]; bool res = GetVolumeInformationW((LPTSTR)path.utf16(), volname, MAX_PATH+1, NULL, NULL, NULL, NULL, 0); if(res) { name = QString::fromWCharArray(volname); } #endif #if defined(Q_OS_MACX) // BSD label does not include folder. QString bsd = Utils::resolveDevicename(path).remove("/dev/"); if(bsd.isEmpty()) { return name; } OSStatus result; ItemCount index = 1; do { FSVolumeRefNum volrefnum; HFSUniStr255 volname; result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, index, &volrefnum, kFSVolInfoFSInfo, NULL, &volname, NULL); if(result == noErr) { GetVolParmsInfoBuffer volparms; HParamBlockRec hpb; hpb.ioParam.ioNamePtr = NULL; hpb.ioParam.ioVRefNum = volrefnum; hpb.ioParam.ioBuffer = (Ptr)&volparms; hpb.ioParam.ioReqCount = sizeof(volparms); if(PBHGetVolParmsSync(&hpb) == noErr) { if(volparms.vMServerAdr == 0) { if(bsd == (char*)volparms.vMDeviceID) { name = QString::fromUtf16((const ushort*)volname.unicode, (int)volname.length); break; } } } } index++; } while(result == noErr); #endif qDebug() << "[Utils] Volume name of" << path << "is" << name; return name; }
boolean hasdesktopmanager (short vnum) { GetVolParmsInfoBuffer volparms; HParamBlockRec pb; pb.volumeParam.ioVRefNum = vnum; pb.volumeParam.ioNamePtr = nil; pb.ioParam.ioBuffer = (Ptr) &volparms; pb.ioParam.ioReqCount = sizeof (volparms); if (PBHGetVolParmsSync (&pb) != noErr) return (false); return ((volparms.vMAttrib & (1 << bHasDesktopMgr)) != 0); } /*hasdesktopmanager*/
pascal OSErr HGetVolParms(ConstStr255Param volName, short vRefNum, GetVolParmsInfoBuffer *volParmsInfo, long *infoSize) { HParamBlockRec pb; OSErr error; pb.ioParam.ioNamePtr = (StringPtr)volName; pb.ioParam.ioVRefNum = vRefNum; pb.ioParam.ioBuffer = (Ptr)volParmsInfo; pb.ioParam.ioReqCount = *infoSize; error = PBHGetVolParmsSync(&pb); if ( error == noErr ) { *infoSize = pb.ioParam.ioActCount; } return ( error ); }
static OSErr nglFSGetVolParms( FSVolumeRefNum volRefNum, UInt32 bufferSize, GetVolParmsInfoBuffer *volParmsInfo, UInt32 *actualInfoSize) { OSErr result; HParamBlockRec pb; pb.ioParam.ioNamePtr = NULL; pb.ioParam.ioVRefNum = volRefNum; pb.ioParam.ioBuffer = (Ptr)volParmsInfo; pb.ioParam.ioReqCount = (SInt32)bufferSize; result = PBHGetVolParmsSync(&pb); /* return number of bytes the file system returned in volParmsInfo buffer */ *actualInfoSize = (UInt32)pb.ioParam.ioActCount; return ( result ); }
/* Get the Unix disk name of the volume */ static const char *SDL_SYS_CDName (int drive) { OSStatus err = noErr; HParamBlockRec pb; GetVolParmsInfoBuffer volParmsInfo; if (fakeCD) return "Fake CD-ROM Device"; pb.ioParam.ioNamePtr = NULL; pb.ioParam.ioVRefNum = volumes[drive]; pb.ioParam.ioBuffer = (Ptr)&volParmsInfo; pb.ioParam.ioReqCount = (SInt32)sizeof(volParmsInfo); err = PBHGetVolParmsSync(&pb); if (err != noErr) { SDL_SetError ("PBHGetVolParmsSync returned %d", err); return NULL; } return volParmsInfo.vMDeviceID; }
/** Eject device from PC. * Request the OS to eject the player. * @param device mountpoint of the device * @return true on success, fals otherwise. */ bool Utils::ejectDevice(QString device) { #if defined(Q_OS_WIN32) /* See http://support.microsoft.com/kb/165721 on the procedure to eject a * device. */ bool success = false; int i; HANDLE hdl; DWORD bytesReturned; TCHAR volume[8]; /* CreateFile */ _stprintf(volume, _TEXT("\\\\.\\%c:"), device.toLatin1().at(0)); hdl = CreateFile(volume, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(hdl == INVALID_HANDLE_VALUE) return false; /* lock volume to make sure no other application is accessing the volume. * Try up to 10 times. */ for(i = 0; i < 10; i++) { if(DeviceIoControl(hdl, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &bytesReturned, NULL)) break; /* short break before retry */ Sleep(100); } if(i < 10) { /* successfully locked, now dismount */ if(DeviceIoControl(hdl, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &bytesReturned, NULL)) { /* make sure media can be removed. */ PREVENT_MEDIA_REMOVAL pmr; pmr.PreventMediaRemoval = false; if(DeviceIoControl(hdl, IOCTL_STORAGE_MEDIA_REMOVAL, &pmr, sizeof(PREVENT_MEDIA_REMOVAL), NULL, 0, &bytesReturned, NULL)) { /* eject the media */ if(DeviceIoControl(hdl, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &bytesReturned, NULL)) success = true; } } } /* close handle */ CloseHandle(hdl); return success; #endif #if defined(Q_OS_MACX) // FIXME: FSUnmountVolumeSync is deprecated starting with 10.8. // Use DADiskUnmount / DiskArbitration framework eventually. // BSD label does not include folder. QString bsd = Utils::resolveDevicename(device).remove("/dev/"); OSStatus result; ItemCount index = 1; bool found = false; do { FSVolumeRefNum volrefnum; result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, index, &volrefnum, kFSVolInfoFSInfo, NULL, NULL, NULL); if(result == noErr) { GetVolParmsInfoBuffer volparms; /* See above -- PBHGetVolParmsSync() is not available for 64bit, * and FSGetVolumeParms() on 10.5+ only. */ #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 if(FSGetVolumeParms(volrefnum, &volparms, sizeof(volparms)) == noErr) #else HParamBlockRec hpb; hpb.ioParam.ioNamePtr = NULL; hpb.ioParam.ioVRefNum = volrefnum; hpb.ioParam.ioBuffer = (Ptr)&volparms; hpb.ioParam.ioReqCount = sizeof(volparms); if(PBHGetVolParmsSync(&hpb) == noErr) #endif { if(volparms.vMServerAdr == 0) { if(bsd == (char*)volparms.vMDeviceID) { pid_t dissenter; result = FSUnmountVolumeSync(volrefnum, 0, &dissenter); found = true; break; } } } } index++; } while(result == noErr); if(result == noErr && found) return true; #endif #if defined(Q_OS_LINUX) (void)device; #endif return false; }
QString Utils::filesystemName(QString path) { QString name; #if defined(Q_OS_WIN32) wchar_t volname[MAX_PATH+1]; bool res = GetVolumeInformationW((LPTSTR)path.utf16(), volname, MAX_PATH+1, NULL, NULL, NULL, NULL, 0); if(res) { name = QString::fromWCharArray(volname); } #endif #if defined(Q_OS_MACX) // BSD label does not include folder. QString bsd = Utils::resolveDevicename(path).remove("/dev/"); if(bsd.isEmpty()) { return name; } OSStatus result; ItemCount index = 1; do { FSVolumeRefNum volrefnum; HFSUniStr255 volname; result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, index, &volrefnum, kFSVolInfoFSInfo, NULL, &volname, NULL); if(result == noErr) { GetVolParmsInfoBuffer volparms; /* PBHGetVolParmsSync() is not available for 64bit while FSGetVolumeParms() is available in 10.5+. Thus we need to use PBHGetVolParmsSync() for 10.4, and that also requires 10.4 to always use 32bit. Qt 4 supports 32bit on 10.6 Cocoa only. */ #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 if(FSGetVolumeParms(volrefnum, &volparms, sizeof(volparms)) == noErr) #else HParamBlockRec hpb; hpb.ioParam.ioNamePtr = NULL; hpb.ioParam.ioVRefNum = volrefnum; hpb.ioParam.ioBuffer = (Ptr)&volparms; hpb.ioParam.ioReqCount = sizeof(volparms); if(PBHGetVolParmsSync(&hpb) == noErr) #endif { if(volparms.vMServerAdr == 0) { if(bsd == (char*)volparms.vMDeviceID) { name = QString::fromUtf16((const ushort*)volname.unicode, (int)volname.length); break; } } } } index++; } while(result == noErr); #endif LOG_INFO() << "Volume name of" << path << "is" << name; return name; }
int main(int argc, const char* argv[]) { kern_return_t kernResult; OSErr result = noErr; ItemCount volumeIndex; kernResult = IOMasterPort(MACH_PORT_NULL, &gMasterPort); if (KERN_SUCCESS != kernResult) printf("IOMasterPort returned %d\n", kernResult); // Iterate across all mounted volumes using FSGetVolumeInfo. This will return nsvErr // (no such volume) when volumeIndex becomes greater than the number of mounted volumes. for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) { FSVolumeRefNum actualVolume; HFSUniStr255 volumeName; FSVolumeInfo volumeInfo; bzero((void*)&volumeInfo, sizeof(volumeInfo)); // We're mostly interested in the volume reference number (actualVolume) result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, volumeIndex, &actualVolume, kFSVolInfoFSInfo, &volumeInfo, &volumeName, NULL); if (result == noErr) { GetVolParmsInfoBuffer volumeParms; HParamBlockRec pb; // Use the volume reference number to retrieve the volume parameters. See the documentation // on PBHGetVolParmsSync for other possible ways to specify a volume. pb.ioParam.ioNamePtr = NULL; pb.ioParam.ioVRefNum = actualVolume; pb.ioParam.ioBuffer = (Ptr) & volumeParms; pb.ioParam.ioReqCount = sizeof(volumeParms); // A version 4 GetVolParmsInfoBuffer contains the BSD node name in the vMDeviceID field. // It is actually a char * value. This is mentioned in the header CoreServices/CarbonCore/Files.h. result = PBHGetVolParmsSync(&pb); if (result != noErr) { printf("PBHGetVolParmsSync returned %d\n", result); } else { // This code is just to convert the volume name from a HFSUniCharStr to // a plain C string so we can print it with printf. It'd be preferable to // use CoreFoundation to work with the volume name in its Unicode form. CFStringRef volNameAsCFString; char volNameAsCString[256]; volNameAsCFString = CFStringCreateWithCharacters(kCFAllocatorDefault, volumeName.unicode, volumeName.length); // If the conversion to a C string fails, just treat it as a null string. if (!CFStringGetCString(volNameAsCFString, volNameAsCString, sizeof(volNameAsCString), kCFStringEncodingUTF8)) { volNameAsCString[0] = 0; } // The last parameter of this printf call is the BSD node name from the // GetVolParmsInfoBuffer struct. printf("Volume \"%s\" (vRefNum %d), BSD node /dev/%s, ", volNameAsCString, actualVolume, (char*)volumeParms.vMDeviceID); // Use the BSD node name to call I/O Kit and get additional information about the volume GetAdditionalVolumeInfo((char*)volumeParms.vMDeviceID); } } } return 0; }
pascal OSErr FSpExchangeFilesCompat(const FSSpec *source, const FSSpec *dest) { #if !__MACOSSEVENFIVEORLATER if ( #if !__MACOSSEVENORLATER !FSHasFSSpecCalls() || #endif /* !__MACOSSEVENORLATER */ !HasFSpExchangeFilesCompatibilityFix() ) { HParamBlockRec pb; CInfoPBRec catInfoSource, catInfoDest; OSErr result, result2; Str31 unique1, unique2; StringPtr unique1Ptr, unique2Ptr, swapola; GetVolParmsInfoBuffer volInfo; long theSeed, temp; /* Make sure the source and destination are on the same volume */ if ( source->vRefNum != dest->vRefNum ) { result = diffVolErr; goto errorExit3; } /* Try PBExchangeFiles first since it preserves the file ID reference */ pb.fidParam.ioNamePtr = (StringPtr) &(source->name); pb.fidParam.ioVRefNum = source->vRefNum; pb.fidParam.ioDestNamePtr = (StringPtr) &(dest->name); pb.fidParam.ioDestDirID = dest->parID; pb.fidParam.ioSrcDirID = source->parID; result = PBExchangeFilesSync(&pb); /* Note: The compatibility case won't work for files with *Btree control blocks. */ /* Right now the only *Btree files are created by the system. */ if ( result != noErr ) { pb.ioParam.ioNamePtr = NULL; pb.ioParam.ioBuffer = (Ptr) &volInfo; pb.ioParam.ioReqCount = sizeof(volInfo); result2 = PBHGetVolParmsSync(&pb); /* continue if volume has no fileID support (or no GetVolParms support) */ if ( (result2 == noErr) && hasFileIDs(volInfo) ) { goto errorExit3; } /* Get the catalog information for each file */ /* and make sure both files are *really* files */ catInfoSource.hFileInfo.ioVRefNum = source->vRefNum; catInfoSource.hFileInfo.ioFDirIndex = 0; catInfoSource.hFileInfo.ioNamePtr = (StringPtr) &(source->name); catInfoSource.hFileInfo.ioDirID = source->parID; catInfoSource.hFileInfo.ioACUser = 0; /* ioACUser used to be filler2 */ result = PBGetCatInfoSync(&catInfoSource); if ( result != noErr ) { goto errorExit3; } if ( (catInfoSource.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) { result = notAFileErr; goto errorExit3; } catInfoDest.hFileInfo.ioVRefNum = dest->vRefNum; catInfoDest.hFileInfo.ioFDirIndex = 0; catInfoDest.hFileInfo.ioNamePtr = (StringPtr) &(dest->name); catInfoDest.hFileInfo.ioDirID = dest->parID; catInfoDest.hFileInfo.ioACUser = 0; /* ioACUser used to be filler2 */ result = PBGetCatInfoSync(&catInfoDest); if ( result != noErr ) { goto errorExit3; } if ( (catInfoDest.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) { result = notAFileErr; goto errorExit3; } /* generate 2 filenames that are unique in both directories */ theSeed = 0x64666A6C; /* a fine unlikely filename */ unique1Ptr = (StringPtr)&unique1; unique2Ptr = (StringPtr)&unique2; result = GenerateUniqueName(source->vRefNum, &theSeed, source->parID, dest->parID, unique1Ptr); if ( result != noErr ) { goto errorExit3; } GenerateUniqueName(source->vRefNum, &theSeed, source->parID, dest->parID, unique2Ptr); if ( result != noErr ) { goto errorExit3; } /* rename source to unique1 */ pb.fileParam.ioNamePtr = (StringPtr) &(source->name); pb.ioParam.ioMisc = (Ptr) unique1Ptr; pb.ioParam.ioVersNum = 0; result = PBHRenameSync(&pb); if ( result != noErr ) { goto errorExit3; } /* rename dest to unique2 */ pb.ioParam.ioMisc = (Ptr) unique2Ptr; pb.ioParam.ioVersNum = 0; pb.fileParam.ioNamePtr = (StringPtr) &(dest->name); pb.fileParam.ioDirID = dest->parID; result = PBHRenameSync(&pb); if ( result != noErr ) { goto errorExit2; /* back out gracefully by renaming unique1 back to source */ } /* If files are not in same directory, swap their locations */ if ( source->parID != dest->parID ) { /* move source file to dest directory */ pb.copyParam.ioNamePtr = unique1Ptr; pb.copyParam.ioNewName = NULL; pb.copyParam.ioNewDirID = dest->parID; pb.copyParam.ioDirID = source->parID; result = PBCatMoveSync((CMovePBPtr) &pb); if ( result != noErr ) { goto errorExit1; /* back out gracefully by renaming both files to original names */ } /* move dest file to source directory */ pb.copyParam.ioNamePtr = unique2Ptr; pb.copyParam.ioNewDirID = source->parID; pb.copyParam.ioDirID = dest->parID; result = PBCatMoveSync((CMovePBPtr) &pb); if ( result != noErr) { /* life is very bad. We'll at least try to move source back */ pb.copyParam.ioNamePtr = unique1Ptr; pb.copyParam.ioNewName = NULL; pb.copyParam.ioNewDirID = source->parID; pb.copyParam.ioDirID = dest->parID; (void) PBCatMoveSync((CMovePBPtr) &pb); /* ignore errors */ goto errorExit1; /* back out gracefully by renaming both files to original names */ } } /* Make unique1Ptr point to file in source->parID */ /* and unique2Ptr point to file in dest->parID */ /* This lets us fall through to the rename code below */ swapola = unique1Ptr; unique1Ptr = unique2Ptr; unique2Ptr = swapola; /* At this point, the files are in their new locations (if they were moved) */ /* Source is named Unique1 (name pointed to by unique2Ptr) and is in dest->parID */ /* Dest is named Unique2 (name pointed to by unique1Ptr) and is in source->parID */ /* Need to swap attributes except mod date and swap names */ /* swap the catalog info by re-aiming the CInfoPB's */ catInfoSource.hFileInfo.ioNamePtr = unique1Ptr; catInfoDest.hFileInfo.ioNamePtr = unique2Ptr; catInfoSource.hFileInfo.ioDirID = source->parID; catInfoDest.hFileInfo.ioDirID = dest->parID; /* Swap the original mod dates with each file */ temp = catInfoSource.hFileInfo.ioFlMdDat; catInfoSource.hFileInfo.ioFlMdDat = catInfoDest.hFileInfo.ioFlMdDat; catInfoDest.hFileInfo.ioFlMdDat = temp; /* Here's the swap (ignore errors) */ (void) PBSetCatInfoSync(&catInfoSource); (void) PBSetCatInfoSync(&catInfoDest); /* rename unique2 back to dest */ errorExit1: pb.ioParam.ioMisc = (Ptr) &(dest->name); pb.ioParam.ioVersNum = 0; pb.fileParam.ioNamePtr = unique2Ptr; pb.fileParam.ioDirID = dest->parID; (void) PBHRenameSync(&pb); /* ignore errors */ /* rename unique1 back to source */ errorExit2: pb.ioParam.ioMisc = (Ptr) &(source->name); pb.ioParam.ioVersNum = 0; pb.fileParam.ioNamePtr = unique1Ptr; pb.fileParam.ioDirID = source->parID; (void) PBHRenameSync(&pb); /* ignore errors */ } errorExit3: { /* null statement */ } return ( result ); } else #endif /* !__MACOSSEVENFIVEORLATER */ { return ( FSpExchangeFiles(source, dest) ); } }