何在Delphi中阅读ISO 9660?

时间:2016-05-29 12:35:37

标签: delphi iso9660

我目前正在开展一个项目,需要知道刻录DVD的时间(刻录DVD的日期)。至于我搜索和查找,发现所有这样的数据都遵循ISO 9660格式,但我无法找到如何访问或读取它,也尝试了一些相关的组件包和库,但没有一个是按照我的预期和需要工作。

也找到了这个链接:How to find out when a disc (DVD) has been written/burned?但是我找不到在Delphi中使用它们的方法。 它是如何工作的?

2 个答案:

答案 0 :(得分:4)

点击此答案的链接:How to find out when a disc (DVD) has been written/burned?给出了在磁盘上阅读日期和时间信息的位置:

读取16个字符加上从位置33582开始的另一个字节,将DVD创建时间设置为:

  

YYYYMMDDHHMMSSCCO

其中CC是厘秒,O是以15分钟为间隔的GMT偏移量,存储为8位整数(二进制补码表示)。

以下代码可用于阅读(另请参阅How to read raw block from an USB storage device with Delphi?):

function GetDVDCreationDate: String;
// Sector size is 2048 on ISO9660 optical data discs
const
  sector_size = 2048;
  rdPos = (33582 DIV sector_size);  // 33582
  rdOfs = (33582 MOD sector_size) - 1;
var
  RawMBR  : array [0..sector_size-1] of byte;
  btsIO   : DWORD;
  hDevice : THandle;
  i       : Integer;
  GMTofs  : ShortInt;
begin
  Result := '';
  hDevice := CreateFile('\\.\E:', GENERIC_READ,  // Select drive 
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if hDevice <> INVALID_HANDLE_VALUE then
  begin
    SetFilePointer(hDevice,sector_size * rdPos,nil,FILE_BEGIN);
    ReadFile(hDevice, RawMBR[0], sector_size, btsIO, nil);
    if (btsIO = sector_size) then begin
      for i := 0 to 15 do begin
        Result := Result + AnsiChar(RawMBR[rdOfs+i]);
      end;
      GMTofs := ShortInt(RawMBR[rdOfs+16]);  // Handle GMT offset if important
    end;
    CloseHandle(hDevice);
  end;
end;

请注意,从光盘读取原始数据必须从偶数扇区大小位置开始。对于ISO 9660磁盘,扇区大小为2048。

答案 1 :(得分:1)

感谢@LU RD回答,这是他的代码,其中包含一些修改:

function GetDVDCreationDate(sectorSize:integer): String;
// Sector size is 2048 on ISO9660 optical data discs
var
  RawMBR  : array [0..2047] of byte;
  btsIO   : DWORD;
  hDevice : THandle;
  i       : Integer;
  GMTofs  : ShortInt;
  rdPos, rdOfs: integer;

begin
  rdPos := (33582 DIV sectorSize);  // 33582
  rdOfs := (33582 MOD sectorSize) - 1;

  hDevice := CreateFile('\\.\H:', GENERIC_READ,  // Select drive
    FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if hDevice <> INVALID_HANDLE_VALUE then
  begin
    SetFilePointer(hDevice,sectorSize * rdPos,nil,FILE_BEGIN);
    ReadFile(hDevice, RawMBR[0], sectorSize, btsIO, nil);
    for i := 0 to 15 do begin
      Result := Result + AnsiChar(RawMBR[rdOfs+i]);
    end;
    GMTofs := ShortInt(RawMBR[rdOfs+16]);  // Handle GMT offset if important
    CloseHandle(hDevice);
  end;
end;

//------------------------------------------------------------------------------

procedure Tfrm_main.btn_creationReadClick(Sender: TObject);
begin
  memo_dataLog.Lines.Add(GetDVDCreationDate(StrToInt(edit_sSize.Text)))
end;