Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi RPC State (Region Code) auslesen. (https://www.delphipraxis.net/111292-rpc-state-region-code-auslesen.html)

Garfield 1. Apr 2008 18:55


RPC State (Region Code) auslesen.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Auf http://www.codeproject.com/KB/system/mydvdregion.aspx gibt es ein Tool, mit welchem man ein paar Informationen zum Region Code von DVD-Laufwerken auslesen kann. Die Dokumentation gibt es es unter http://www.t10.org/drafts.htm#SCSI3_CMNDSETS -> http://www.t10.org/ftp/t10/drafts/mmc5/mmc5r04.pdf (ab Seite 513).

Jetzt wollte ich das in Delphi ausprobieren.

Delphi-Quellcode:
procedure TCDDVDDrives.DVDFeature(i: Byte);
const
  KEY_FORMAT_RPC_STATE    = 8;

type
  _REPORT_KEY_DATA_RPC_STATE = record
    REPORT_KEY_Data_Length : Word;
    Reserved1              : array[2..3] of Byte;
    RPC_State             : Byte;
    Region_Mask           : Byte;
    RPC_Scheme            : Byte;
    Reserved2              : Byte;
  end;

const
  // Type Code Field Definitions
  TCFD_NONE               = $00; // 00b No Drive region setting
  TCFD_SET                = $01; // 01b Drive region is set
  TCFD_LAST_CHANCE        = $02; // 10b Drive Region is set. Additional restrictions required to make a change.
  TCFD_PERM               = $03; // 11b Drive Region has been set permanently, but may be reset by the

const
  // RPC Scheme Field Definition
  RSFD_Unknown            = $00; // Drive does enforce Region
  RSFD_RPC_Phase_II       = $01; // Drive region shall adhere to this standard and all requirements of the
                                  // CSS license agreement coceming RPC.
type
  // REPORT KEY Data Format
  _REPORT_KEY_CDB = record
    OperationCode      : Byte;
    Reserved1           : Byte;
    LogicalBlockAddress : Array[2..5] of Byte;
    Reserved2           : Byte;
    KeyClass           : Byte;
    AllocationLength   : Word;
    AGID_KeyFormat     : Byte; // 0-5 = Keyformat, 6-7 AGID
    Control            : Byte;
  end;

var
  buf            : array[0..1023] of Char;
  hDevice        : THandle;
  pcmd           : PSCSI_PASS_THROUGH_DIRECT;
  rb             : Cardinal;
  REPORT_KEY_DATA : _REPORT_KEY_DATA_RPC_STATE;
  REPORT_KEY_CDB : _REPORT_KEY_CDB;

begin
  Drive[i].DVDFeature.User_changes := $FF;
  Drive[i].DVDFeature.Vendor_resets := $FF;
  Drive[i].DVDFeature.Type_code    := $FF;
  Drive[i].DVDFeature.Region_mask  := $FF;
  Drive[i].DVDFeature.RPC_scheme   := $FF;

  hDevice := CreateFile(PChar(Format('\\.\%s:', [Drive[i].Letter])),
                   GENERIC_READ or GENERIC_WRITE,
                   FILE_SHARE_READ,
                   nil,
                   OPEN_EXISTING,
                   0,
                   0 );

  if hDevice <> INVALID_HANDLE_VALUE
  then begin
    ZeroMemory(@buf, 1024);
    ZeroMemory(@REPORT_KEY_CDB, SizeOf(REPORT_KEY_CDB));

    pcmd                           := PSCSI_PASS_THROUGH_DIRECT(@buf);
    pcmd^.Length                   := SizeOf(SCSI_PASS_THROUGH_DIRECT);
    pcmd^.CdbLength                := CDB10GENERIC_LENGTH;
    pcmd^.SenseInfoLength          := SizeOf(SCSI_PASS_THROUGH_DIRECT);
    pcmd^.DataIn                   := SCSI_IOCTL_DATA_IN;
    pcmd^.DataTransferLength       := sizeof(_REPORT_KEY_DATA_RPC_STATE);
    pcmd^.TimeOutValue             := 6000;
    pcmd^.DataBufferOffset         := @REPORT_KEY_DATA;

    REPORT_KEY_CDB.OperationCode   := SCSIOP_REPORT_KEY;
    REPORT_KEY_CDB.KeyClass        := $00;
    REPORT_KEY_CDB.AllocationLength := SizeOf(_REPORT_KEY_DATA_RPC_STATE);
    REPORT_KEY_CDB.AGID_KeyFormat  := KEY_FORMAT_RPC_STATE; // AGID = 0;

    pcmd^.cdb[0]                   := REPORT_KEY_CDB.OperationCode;
    pcmd^.cdb[1]                   := REPORT_KEY_CDB.Reserved1;
    pcmd^.Cdb[2]                   := REPORT_KEY_CDB.LogicalBlockAddress[2];
    pcmd^.Cdb[3]                   := REPORT_KEY_CDB.LogicalBlockAddress[3];
    pcmd^.Cdb[4]                   := REPORT_KEY_CDB.LogicalBlockAddress[4];
    pcmd^.Cdb[5]                   := REPORT_KEY_CDB.LogicalBlockAddress[5];
    pcmd^.Cdb[6]                   := REPORT_KEY_CDB.Reserved2;
    pcmd^.Cdb[7]                   := REPORT_KEY_CDB.KeyClass;
    pcmd^.Cdb[8]                   := LoByte(REPORT_KEY_CDB.AllocationLength);
    pcmd^.Cdb[9]                   := HiByte(REPORT_KEY_CDB.AllocationLength);
    pcmd^.Cdb[10]                  := REPORT_KEY_CDB.AGID_KeyFormat;
    pcmd^.Cdb[11]                  := REPORT_KEY_CDB.Control;

    if DeviceIoControl(hDevice,
                       IOCTL_SCSI_PASS_THROUGH_DIRECT,
                       pcmd,
                       SizeOf(SCSI_PASS_THROUGH_DIRECT),
                       pcmd,
                       SizeOf(SCSI_PASS_THROUGH_DIRECT),
                       rb,
                       nil)
    then begin
      Drive[i].DVDFeature.User_changes := REPORT_KEY_DATA.RPC_State and $07;
      Drive[i].DVDFeature.Vendor_resets := (REPORT_KEY_DATA.RPC_State shr 3) and $07;
      Drive[i].DVDFeature.Type_code    := REPORT_KEY_DATA.RPC_State shr 6;
      Drive[i].DVDFeature.Region_mask  := REPORT_KEY_DATA.Region_Mask;
      Drive[i].DVDFeature.RPC_scheme   := REPORT_KEY_DATA.RPC_Scheme;
    end
    else
      ShowMessage(GetStatus);
  end;
  CloseHandle(hDevice);
end;
Die Fehlermeldung lautet: "Falscher Parameter."

Garfield 1. Apr 2008 21:14

Re: RPC State (Region Code) auslesen.
 
Es ist schon eigenartig. Man sucht mehrere Tage nach der Lösung und wenn man dann fragt, findet man doch noch die Lösung. Zwei Fehler waren drin.

Delphi-Quellcode:
pcmd^.CdbLength                := CDB12GENERIC_LENGTH;
pcmd^.SenseInfoOffset          := SizeOf(SCSI_PASS_THROUGH_DIRECT);
// pcmd^.SenseInfoLength          := SizeOf(SCSI_PASS_THROUGH_DIRECT);
Die CdbLength war um zwei Byte zu gering und anstelle des SenseInfoOffset hatte ich SenseInfoLength gesetzt.

Garfield 3. Apr 2008 17:51

Re: RPC State (Region Code) auslesen.
 
Liste der Anhänge anzeigen (Anzahl: 2)
Falls von Interesse:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz