static OSStatus _FSGetVolumeParms(FSVolumeRefNum volume, GetVolParmsInfoBuffer *buffer, ByteCount bufferSize) { OSStatus status = FSGetVolumeParms(volume,buffer,bufferSize); int isCaseSensitive = !!(buffer->vMExtendedAttributes & (1 << bIsCaseSensitive)); if(isCaseSensitive) { printf("== FSGetVolumeParms - lying and saying the volume is case insensitive, though it is case sensitive. ==\n"); buffer->vMExtendedAttributes &= ~(1 << bIsCaseSensitive); } return status; }
/** 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; }