Как получить имя тома смонтированного диска в Linux с помощью C? - PullRequest
2 голосов
/ 05 апреля 2011

Я сейчас работаю над программой, которая должна отображать информацию о подключенной флешке. Я хочу отобразить полное пространство, свободное пространство, тип файловой системы и имя тома. Но проблема в том, что я не могу найти API, с помощью которого я могу получить имя тома (метка тома). Есть ли API для этого?

p.s. полное пространство, свободное пространство и тип файловой системы, которую я получаю через statfs функцию

Ответы [ 3 ]

2 голосов
/ 05 апреля 2011

Предполагая, что вы работаете в недавнем настольном дистрибутиве (Fedora, Ubuntu и т. Д.), У вас работает демон HAL и сеанс D-Bus.

В пространстве имен org.freedesktop.UDisks вы можете найтиобъект, который представляет этот диск (скажем, org/freedekstop/UDisks/devices/sdb/. Он реализует org.freedesktop.UDisks.interface. Этот интерфейс имеет все свойства, о которых вы можете мечтать, включая UUID (IdUuid), метку FAT (IdLabel), все подробности о файловой системе, Состояние SMART (если привод поддерживает это) и т. Д. И т. Д.

Как использовать D-Bus API в C - это тема для другого вопроса. Я предполагаю, что это уже обсуждалось подробно - просто поиск [dbus] и теги [c].

1 голос
/ 05 апреля 2011

Флэш-диски, как правило, FAT32, что означает, что «имя», которое вы ищете, вероятно, является меткой диска FAT. Наиболее распространенная команда linux для получения этой информации - mlabel из пакета mtools .

Команда выглядит так:

[root@localhost]$ mlabel -i /dev/sde1 -s ::
  Volume label is USB-DISK

Эта программа работает путем считывания необработанного заголовка FAT файловой системы и извлечения метки из этих данных. Вы можете посмотреть исходный код приложения, чтобы увидеть, как вы можете реплицировать синтаксический анализ данных FAT в вашем собственном приложении ... или вы можете просто выполнить, запустить двоичный файл mlabel и прочитать результат в своей программе. Последнее звучит проще для меня.

0 голосов
/ 08 мая 2012

Для вызова методов:

 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...