Como combinar o caminho do dispositivo Linux com o nome da unidade do Windows?

StackOverflow https://stackoverflow.com/questions/18959

  •  09-06-2019
  •  | 
  •  

Pergunta

Estou escrevendo um aplicativo que, em algum estágio, executa operações de disco de baixo nível no ambiente Linux.Na verdade, o aplicativo consiste em 2 partes, uma roda no Windows e interage com o usuário e a outra é uma parte Linux que roda a partir de um LiveCD.O usuário escolhe as letras das unidades do Windows e, em seguida, uma parte do Linux executa ações com as partições correspondentes.O problema é encontrar uma correspondência entre uma letra de unidade do Windows (como C:) e um nome de dispositivo Linux (como/dev/sda1).Esta é a minha solução atual que considero feia:

  • armazenar informações de partições (ou seja,letra da unidade, número de blocos, número de série da unidade, etc.) no Windows em algum local predefinido (ou seja,a raiz da partição do sistema).

  • leia uma lista de partições em /proc/partitions.Obtenha apenas as partições que possuem um número maior para discos rígidos SCSI ou IDE e um número menor que as identifica como partições reais e não como discos inteiros.

  • Tente montar cada um deles com sistemas de arquivos NTFS ou VFAT.Verifique se a partição montada contém as informações armazenadas pelo aplicativo Windows.

  • Ao encontrar as informações necessárias escritas pelo aplicativo do Windows, faça a correspondência real.Para cada partição encontrada em /proc/partitions adquira o número de série da unidade (via syscall HDIO_GET_IDENTITY), número de blocos (de /proc/partitions) e deslocamento da unidade (/sys/blocks/drive_path/partition_name/start), compare isso com o Windows informações e se corresponder - armazene uma letra de unidade do Windows junto com um nome de dispositivo Linux.

Existem alguns problemas neste esquema:

  • Isso é feio.Escrever dados no Windows e depois lê-los no Linux torna os testes um pesadelo.

  • O número principal do dispositivo Linux é comparado apenas com dispositivos IDE ou SCSI.Isso provavelmente falharia, ou seja,em discos USB ou FireWire.É possível adicionar esses tipos de discos, mas limitar o aplicativo apenas a um subconjunto conhecido de dispositivos possíveis parece ser uma má ideia.

  • parece que HDIO_GET_IDENTITY funciona apenas em unidades IDE e SATA.

  • /sys/block hack pode não funcionar em unidades diferentes de IDE ou SATA.

Alguma idéia de como melhorar esse esquema?Talvez haja outra maneira de determinar os nomes do Windows sem gravar todos os dados no aplicativo Windows?

P.S.A linguagem do aplicativo é C++.Eu não posso mudar isso.

Foi útil?

Solução

As partições possuem UUIDs associados a elas.Não sei como encontrá-los no Windows, mas no Linux você pode encontrar o UUID para cada partição com:

sudo vol_id -u dispositivo (por exemplo/dev/sda1)

Se houver uma função equivalente no Windows, você pode simplesmente armazenar os UUIDs para qualquer partição escolhida e, em seguida, iterar por todas as partições conhecidas no Linux e combinar os UUIDs.

Editar: Isso pode ser apenas para Linux e pode ser especificamente o utilitário volid que os gera a partir de algo (em vez de ler metadados para a unidade).Dito isto, não há nada que impeça você de obter a fonte do volid e verificar o que ela faz.

Outras dicas

As partições têm UUIDs associados a elas

Meu conhecimento disso é muito superficial, mas pensei que isso só fosse verdade para discos formatados com partições GPT (Guid Partition Table), em vez do formato MBR antigo, ao qual 99% do mundo ainda está preso.

Meu conhecimento disso é muito superficial, mas eu pensei que isso só era verdade para os discos formatados com partições GPT (Tabela de Partição GUID), em vez do formato MBR de estilo antigo com o qual 99% do mundo ainda está preso?

Não parece um clichê de usuário Linux, mas funciona para mim.Eu uso com partições NTFS e não tive problemas.Como eu disse na minha edição, vol_id pode estar gerando eles próprios.Se fosse esse o caso, não haveria dependência de nenhum formato de partição específico, o que seria ótimo.

As partições possuem UUIDs associados a elas.Não sei como encontrá-los no Windows, mas no Linux você pode encontrar o UUID para cada partição com:

sudo vol_id -u dispositivo (por exemplo/dev/sda1)

Se houver uma função equivalente no Windows, você pode simplesmente armazenar os UUIDs para qualquer partição escolhida e, em seguida, iterar por todas as partições conhecidas no Linux e combinar os UUIDs.

Esse é um bom ponto, obrigado!Eu olhei para as fontes de vol_id (uma parte do tarball do udev) e parece que para FAT (32) e NTFS ele gera UUUD usando o número de série do volume que é lido no local predefinido na partição.Como não espero nada além de fat32 e ntfs, considero usar essas informações como identificador de partição.

Você precisa marcar a unidade de alguma forma (por exemplo,escrever um arquivo etc.) ou encontrar algum identificador que esteja associado apenas a essa unidade específica.

É muito difícil, quase impossível, descobrir que letra o Windows atribuiria a uma partição específica da unidade, sem realmente executar o Windows.Isso ocorre porque o Windows sempre associa a unidade a partir da qual é executado com C:.Que pode ser qualquer unidade, se você tiver mais de um sistema operacional instalado.O Windows também permite que você escolha qual letra de unidade tentará primeiro, para uma partição específica, causando mais problemas.

Seria muito mais fácil fazer as coisas da GUI dentro do Linux do que tentar esta solução mista Windows/Linux.Não estou dizendo para não tentar dessa maneira, o que estou dizendo é que há muitas armadilhas possíveis com essa abordagem.Tenho certeza de que nem sei sobre todos eles.

Outra opção seria ver se você realmente consegue fazer a parte do Linux, dentro do Windows.Se você for um programador Windows muito bom, poderá obter acesso ao sistema de arquivos bruto.Provavelmente existem muitas armadilhas nessa abordagem, porque o Windows estará em execução enquanto tudo isso estiver em operação.

Então, para reiterar, eu veria se você poderia fazer tudo no Linux, se puder.É muito mais simples no longo prazo.

No Windows você pode ler o "Número de série do volume NTFS" que parece corresponder ao UUID no Linux.

Possibilidades de obter o "NTFS Volume Serial" de janelas:

  • linha de comando desde XP: fsutil.exe fsinfo ntfsinfo C:

  • em c++

    HANDLE fileHandle = CreateFile(L"\\\\.\\C:", // or use syntax "\\?\Volume{GUID}" 
                                   GENERIC_READ,
                                   FILE_SHARE_READ|FILE_SHARE_WRITE,
                                   NULL,
                                   OPEN_EXISTING,
                                   NULL,
                                   NULL);
    DWORD i;
    NTFS_VOLUME_DATA_BUFFER ntfsInfo;
    DeviceIoControl(fileHandle, 
                    FSCTL_GET_NTFS_VOLUME_DATA, 
                    NULL, 
                    0, 
                    &ntfsInfo,
                    sizeof(ntfsInfo), 
                    &i, 
                    NULL));
    cout << "UUID is " << std::hex << ntfsInfo.VolumeSerialNumber.HighPart << std::hex << ntfsInfo.VolumeSerialNumber.LowPart << endl;
    

Possibilidades de obter o UUID Linux:

  • ls -l /dev/disco/by-uuid
  • ls -l /dev/disco/por-rótulo
  • blkid /dev/sda1
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top