Linux 获取卷udf cd/dvd磁盘的序列号?

Linux 获取卷udf cd/dvd磁盘的序列号?,linux,volume,cd,dvd,Linux,Volume,Cd,Dvd,我正在用linux编写一个程序,计算Windows7中CD卷的序列号(xxxx xxxx)。我的程序使用iso9660和joilet文件系统正确地确定磁盘上卷的序列号。但是如何使用文件系统udf定义磁盘卷嗅探器呢?谁能告诉我 ps如果有人不明白我说的是这种序列号 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #定义SEC_尺寸2048 #定义VD_N 16 #定义VD_类型_支持2 #定义VD\U类型\U结束255 #定义ESC_IDX 88 #定义ESC_LE

我正在用linux编写一个程序,计算Windows7中CD卷的序列号(xxxx xxxx)。我的程序使用iso9660和joilet文件系统正确地确定磁盘上卷的序列号。但是如何使用文件系统udf定义磁盘卷嗅探器呢?谁能告诉我

ps如果有人不明白我说的是这种序列号

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义SEC_尺寸2048
#定义VD_N 16
#定义VD_类型_支持2
#定义VD\U类型\U结束255
#定义ESC_IDX 88
#定义ESC_LEN 3
#定义ESC_UCS2L1“%/@”
#定义ESC_UCS2L2“%/C”
#定义ESC_UCS2L3“%/E”
使用名称空间std;
int cdid(无符号字符pvd[秒大小])
{
无符号字符部分[4]={0};
int i;
对于(i=0;ireturn(第[3]部分)这个问题似乎在更多的地方被问到了,但还没有答案。所以我将在这里回答

在其中一些帖子中,人们对序列号生成算法进行了解码。它只是您已经找到并放入cdid()函数中的校验和。相同的校验和算法用于Windows上的ISO9660和UDF文件系统。您已经了解到,校验和是从哪个ISO9660结构计算出来的

因此,您的问题只针对UDF文件系统。对于Windows上的UDF文件系统,校验和是根据512字节长的文件集描述符(FSD)结构计算的。我建议您阅读如何在UDF光盘上设置该FSD

基本上,对于不使用虚拟分配表(VAT)、备用表或元数据分区的普通UDF,FSD的位置存储在逻辑卷描述符(LVD)结构中的LogicalVolumeContentsUse字段中(类型为long_ad)。LVD存储在卷描述符序列(VDS)中.VDS的位置存储在字段MainVolumeDescriptorSequenceExtent中的锚定卷描述符指针(AVDP)中。AVDP本身位于介质的扇区256处。光学介质的扇区大小为2048字节,公共硬盘大小为512字节

对于带有VAT(例如在CD-R/DVD-R/BD-R上)、备用表(例如在CD-RW/DVD-RW上)或元数据分区(例如在蓝光上)的UDF,它要复杂得多。您需要研究虚拟、备用或元数据分区,以找出如何将FSD的逻辑位置转换为介质的物理位置


在从2.0版开始的项目中,有一个新的工具提供了有关UDF文件系统的各种信息。它还显示了您问题中winserialnum键下的Windows特定卷序列号。请注意,udfinfo还不能使用VAT或元数据从UDF文件系统读取FSD。

为什么被否决?请说明原因以及如何改进它,而不是默默地用-1标记我的答案。
#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);
}