我目前正在开发程序,它必须显示有关已安装的闪存驱动器的信息。我想显示完整空间,可用空间,文件系统类型和卷名。但问题是,我找不到任何API,我可以通过它获得卷名(卷标)。有没有api这样做?
P.S。我通过statfs
函数获取的全空间,可用空间和文件系统类型
答案 0 :(得分:2)
假设您使用最近的类似桌面的发行版(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]标签。
答案 1 :(得分:1)
闪存驱动器通常是FAT32,这意味着您正在寻找的“名称”可能是FAT驱动器标签。从 mtools 包中检索该信息的最常见的linux命令是mlabel
。
命令如下所示:
[root@localhost]$ mlabel -i /dev/sde1 -s ::
Volume label is USB-DISK
该程序通过读取文件系统的原始FAT头并从该数据中检索标签来工作。您可以查看applciation的源代码,了解如何在您自己的应用程序中复制FAT数据的解析...或者您只需执行运行mlabel
二进制文件并将结果读入您的程序。后者听起来更简单。
答案 2 :(得分:0)
调用方法:
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;
}