我目前正在编写程序,该程序必须显示有关安装的闪存驱动器的信息。 我想要显示完整的空间,可用空间,文件系统types和卷名称。 但问题是,我无法find任何API,通过它我可以得到卷名(卷标)。 有没有这样做?
PS完整的空间,可用空间和文件系统types我通过statfs
函数获取
假设您使用最近的类似桌面的发行版(Fedora,Ubuntu等),您将运行HAL守护程序和一个D-Bus会话。
在org.freedesktop.UDisks
命名空间中,你可以找到代表这个驱动器的对象(比如org/freedekstop/UDisks/devices/sdb/
,它实现了org.freedesktop.UDisks.interface
。这个接口拥有你可以梦想的所有属性包括UUID( IdUuid
),FAT标签( IdLabel
),文件系统的所有细节,SMART状态(如果驱动器支持)等等。
如何在C中使用D-Bus API是另一个问题的话题。 我假设已经详细讨论过 – 只要搜索[dbus]和[c]标签。
闪存驱动器通常是FAT32,这意味着您正在寻找的“名称”可能是FAT驱动器标签。 检索该信息的最常用的linux命令是mtools包中的mlabel
。
该命令如下所示:
[root@localhost]$ mlabel -i /dev/sde1 -s :: Volume label is USB-DISK
该程序通过读取文件系统的原始FAT头并从该数据中检索标签来工作。 您可以查看应用程序的源代码,了解如何在自己的应用程序中复制FAT数据的解析…或者您可以简单地执行mlabel
二进制文件并将结果读入您的程序。 后者听起来比较简单。
调用方法:
kernResult = self->FindEjectableCDMedia(&mediaIterator); if (KERN_SUCCESS != kernResult) { printf("FindEjectableCDMedia returned 0x%08x\n", kernResult); } kernResult = self->GetPath(mediaIterator, bsdPath, sizeof(bsdPath)); if (KERN_SUCCESS != kernResult) { printf("GetPath returned 0x%08x\n", kernResult); }
和方法:
// Returns an iterator across all DVD media (class IODVDMedia). Caller is responsible for releasing // the iterator when iteration is complete. kern_return_t ScanPstEs::FindEjectableCDMedia(io_iterator_t *mediaIterator) { kern_return_t kernResult; CFMutableDictionaryRef classesToMatch; // CD media are instances of class kIODVDMediaTypeROM classesToMatch = IOServiceMatching(kIODVDMediaClass); if (classesToMatch == NULL) { printf("IOServiceMatching returned a NULL dictionary.\n"); } else { CFDictionarySetValue(classesToMatch, CFSTR(kIODVDMediaClass), kCFBooleanTrue); } kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, mediaIterator); return kernResult; } // Given an iterator across a set of CD media, return the BSD path to the // next one. If no CD media was found the path name is set to an empty string. kern_return_t GetPath(io_iterator_t mediaIterator, char *Path, CFIndex maxPathSize) { io_object_t nextMedia; kern_return_t kernResult = KERN_FAILURE; DADiskRef disk = NULL; DASessionRef session = NULL; CFDictionaryRef props = NULL; char * bsdPath = '\0'; *Path = '\0'; nextMedia = IOIteratorNext(mediaIterator); if (nextMedia) { CFTypeRef bsdPathAsCFString; bsdPathAsCFString = IORegistryEntryCreateCFProperty(nextMedia,CFSTR(kIOBSDNameKey),kCFAllocatorDefault,0); if (bsdPathAsCFString) { //strlcpy(bsdPath, _PATH_DEV, maxPathSize); // Add "r" before the BSD node name from the I/O Registry to specify the raw disk // node. The raw disk nodes receive I/O requests directly and do not go through // the buffer cache. //strlcat(bsdPath, "r", maxPathSize); size_t devPathLength = strlen(bsdPath); if (CFStringGetCString( (CFStringRef)bsdPathAsCFString , bsdPath + devPathLength,maxPathSize - devPathLength, kCFStringEncodingUTF8)) { qDebug("BSD path: %s\n", bsdPath); kernResult = KERN_SUCCESS; } session = DASessionCreate(kCFAllocatorDefault); if(session == NULL) { qDebug("Can't connect to DiskArb\n"); return -1; } disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, bsdPath); if(disk == NULL) { CFRelease(session); qDebug( "Can't create DADisk for %s\n", bsdPath); return -1; } props = DADiskCopyDescription(disk); if(props == NULL) { CFRelease(session); CFRelease(disk); qDebug("Can't get properties for %s\n",bsdPath); return -1; } CFStringRef daName = (CFStringRef )CFDictionaryGetValue(props, kDADiskDescriptionVolumeNameKey); CFStringGetCString(daName,Path,sizeof(Path),kCFStringEncodingUTF8); if(daName) { qDebug("%s",Path); CFRetain(daName); } CFRelease(daName); CFRelease(props); CFRelease(disk); CFRelease(session); CFRelease(bsdPathAsCFString); } IOObjectRelease(nextMedia); } return kernResult; }