2017-04-30 2 views
2

J'écris un programme dans Linux qui compte le numéro de série (xxxx-xxxx) du volume du CD dans Windows 7. Mon programme détermine correctement le numéro de série du volume sur les disques avec les systèmes de fichiers iso9660 et joilet. Mais comment définir un renifleur de volume de disque avec un système de fichiers udf? Quelqu'un peut-il me dire ....Obtenez le numéro de série du volume udf cd/dvd disk?

ps si quelqu'un ne comprend pas que je parle du numéro de série de ce genre https://extra-torrent.jimdo.com/2016/01/23/hard-disk-volume-serial-number-change/

#include <QCoreApplication> 
#include <stdio.h> 
#include <sys/ioctl.h> 
#include <linux/cdrom.h> 
#include <string.h> 
#include <szi/szimac.h> 
#include <qfile.h> 
#include <iostream> 
#include <QDir> 
#include <unistd.h> 

#define SEC_SIZE 2048 
#define VD_N 16 
#define VD_TYPE_SUPP 2 
#define VD_TYPE_END 255 
#define ESC_IDX 88 
#define ESC_LEN 3 
#define ESC_UCS2L1 "%/@" 
#define ESC_UCS2L2 "%/C" 
#define ESC_UCS2L3 "%/E" 
using namespace std; 
int cdid(unsigned char pvd[SEC_SIZE]) 
{ 

    unsigned char part[4] = {0}; 
    int i; 
    for(i = 0; i < SEC_SIZE; i += 4) 
    { 
     part[3] += pvd[i + 0]; 
     part[2] += pvd[i + 1]; 
     part[1] += pvd[i + 2]; 
     part[0] += pvd[i + 3]; 
    } 

    return (part[3] << 24) + (part[2] << 16) + (part[1] << 8) + part[0]; 
} 
int main(int argc, char *argv[]) 
{ 
     FILE *in; 
     unsigned char buf[SEC_SIZE]; 
     struct cdrom_multisession msinfo; 
     long session_start; 
     int id; 

     QString home=QString(getenv("HOME"))+QString("/chteniestorm"); 
     QFile file(home); 

     ustr="/dev/sr0"; 
     in = fopen(ustr.toLocal8Bit().data(), "rb"); 
     if(in == NULL) 
     { 
      if (file.open(QIODevice::WriteOnly)) 
      { 
       file.write("sernom=1"); 
       file.close(); 
      } 
      cout<<"netdiska"<<endl; 
      return 0; 
     } 
     /* Get session info */ 
     msinfo.addr_format = CDROM_LBA; 

     if(ioctl(fileno(in), CDROMMULTISESSION, &msinfo) != 0) 
     { 
      fprintf(stderr, "WARNING: Can't get multisession info\n"); 
      perror(NULL); 
      session_start = 0; 
     } 
     else 
     { 
      session_start = msinfo.addr.lba; 
     } 

     fseek(in, 0, SEEK_SET); //to the begining 



     /* Seek to primary volume descriptor */ 
     if(fseek(in, (session_start + VD_N) * SEC_SIZE, SEEK_SET) != 0) 
     { 
      if (file.open(QIODevice::WriteOnly)) 
      { 
       file.write("sernom=2"); 
       file.close(); 
      } 
      fclose(in); 
      return 0; 
     } 

     /* Read descriptor */ 
     if(fread(buf, 1, SEC_SIZE, in) != SEC_SIZE) 
     { 
      if (file.open(QIODevice::WriteOnly)) 
      { 
       file.write("sernom=3"); 
       file.close(); 

      } 
      fclose(in); 
      return 0; 
     } 

     /* Caclculate disc id */ 
     id = cdid(buf); 

     /* Search for Joliet extension */ 
     while(buf[0] != VD_TYPE_END) 
     { 
      /* Read descriptor */ 
      if(fread(buf, 1, SEC_SIZE, in) != SEC_SIZE) 
      { 
      perror(NULL); 
      return 0; 
      } 

      if(buf[0] == VD_TYPE_SUPP 
       && (memcmp(buf + ESC_IDX, ESC_UCS2L1, ESC_LEN) == 0 
        || memcmp(buf + ESC_IDX, ESC_UCS2L2, ESC_LEN) == 0 
        || memcmp(buf + ESC_IDX, ESC_UCS2L3, ESC_LEN) == 0) 
       ) 
       { 
        /* Joliet found */ 
        id = cdid(buf); 
       } 
     } 
     fclose(in); 
} 

Répondre

-1

Il semble a demandé que cette question sur plus d'endroits [1], [2] , [3], [4] mais nulle part a été répondu pour le moment. Donc je vais le faire ici.

Dans certains de ces postes personnes décodé algorithme de génération de numéro de série. C'est juste la somme de contrôle que vous avez déjà trouvée et placée dans votre fonction cdid(). Le même algorithme de somme de contrôle est utilisé pour les systèmes de fichiers ISO9660 et UDF sous Windows. Vous avez déjà compris à partir de quelles structures ISO9660 cette somme de contrôle est calculée. Donc, votre question reste seulement pour le système de fichiers UDF. Pour le système de fichiers UDF sous Windows, la somme de contrôle est calculée à partir de la structure FSD (File Set Descriptor) de 512 octets. Je vous suggère de lire OSTA UDF specification comment locale que FSD sur le disque UDF. Fondamentalement pour UDF ordinaire qui n'utilise pas la table d'allocation virtuelle (VAT), la table de sauvegarde ou la partition de métadonnées, l'emplacement du FSD est stocké dans la structure LVD (Logical Volume Descriptor), dans le champ LogicalVolumeContentsUse (de type long_ad) . LVD est stocké dans la séquence de descripteur de volume (VDS). L'emplacement de VDS est stocké dans le pointeur de descripteur de volume d'ancre (AVDP), dans le champ MainVolumeDescriptorSequenceExtent. AVDP lui-même est situé au secteur 256 de moyen. Les supports optiques ont une taille de secteur de 2048 octets et un disque dur commun de 512 octets.

Pour UDF avec TVA (par exemple sur CD-R/DVD-R), Table de sauvegarde (par exemple sur CD-RW/DVD-RW) ou Partition de métadonnées (par exemple sur Blu-ray), c'est beaucoup plus compliqué. Vous devez regarder dans Virtual, Sparable ou Métadonnées Partition pour comprendre comment traduire l'emplacement logique de la FSD à l'emplacement physique du média.

Dans le projet udftools à partir de la version 1.4, il existe un nouvel outil udfinfo qui fournit diverses informations sur le système de fichiers UDF. Il montre également que Windows spécifique Volume Numéro de série de votre question sous winserialnum clé. Notez que udfinfo ne peut pas encore lire FSD à partir du système de fichiers UDF avec VAT ou Metadata.

+0

Pourquoi downvoted? S'il vous plaît mettre un commentaire ce qui ne va pas et comment l'améliorer au lieu de marquer silencieusement ma réponse avec -1. – Pali