如何使用C在linux中获取挂载驱动器的卷名?

时间:2011-04-05 06:30:29

标签: c linux

我目前正在开发程序,它必须显示有关已安装的闪存驱动器的信息。我想显示完整空间,可用空间,文件系统类型和卷名。但问题是,我找不到任何API,我可以通过它获得卷名(卷标)。有没有api这样做?

P.S。我通过statfs函数获取的全空间,可用空间和文件系统类型

3 个答案:

答案 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;
}