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

时间:2017-04-30 14:20:44

标签: linux volume cd dvd

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

ps如果有人不明白我在谈论这种序列号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);
}

1 个答案:

答案 0 :(得分:-1)

在更多地点[1][2][3][4]上看到此问题的问题,但尚未得到答复。所以我会在这里做。

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

所以你的问题仍然只适用于UDF文件系统。对于Windows上的UDF文件系统,校验和是根据512字节长的文件集描述符(FSD)结构计算的。我建议你阅读OSTA UDF specification如何在UDF光盘上找到FSD。

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

对于带增值税的UDF(例如在CD-R / DVD-R / BD-R上),备用表(例如在CD-RW / DVD-RW上)或元数据分区(例如在蓝光上),它很多更复杂。您需要查看虚拟,可分区或元数据分区,以了解如何将FSD的逻辑位置转换为媒体的物理位置。

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