A czy mógłbyś zarzucić jakiś mały przykładzik użycia tych funkcji ?
Czy udało się Tobie to jakoś uruchomić?
Niestety nie można nic z tym zrobić :(
Do tego jest też przykład użycia :
function TfrmMain.LoadISOName(FileName: String): String;
var
ISOFile : Cardinal;
Files : TDirectoryArrayRecord;
Filter : TSearchFilter;
FilesFound : Cardinal;
Offset : Cardinal;
Size : Cardinal;
BytesRead : Cardinal;
Buffer : Array Of Char;
ISOName : String;
I,
Max : Integer;
begin
Result := '';
ISOFile := CreateFile(PChar(FileName),GENERIC_READ,0,nil,OPEN_EXISTING,0,0);
If ISOFile = INVALID_HANDLE_VALUE Then Exit;
Try
SetLength(Files,1);
FillChar(Filter,SizeOf(TSearchFilter),0);
Filter.Flags := FILTER_BY_NAME;
Filter.lwType := ISO_FLAG_FILE;
Filter.Name := 'PARAM.SFO';
Filter.DataSize := 9;
FilesFound := ISOSearchFiles(ISOFile,Files,1,@Filter);
If FilesFound = 0 Then Exit;
Offset := Files[0].ExtentLocation * SECTOR_SIZE;
Size := Files[0].DataLength;
If Size > 0 Then
begin
SetLength(Buffer,Size);
SetFilePointer(ISOFile,Offset,nil,FILE_BEGIN);
ReadFile(ISOFile,Buffer[0],Size,BytesRead,nil);
ISOName := Copy(String(Buffer),$159,255);
ISOName := Copy(ISOName,1,Pos(#0,ISOName) - 1);
I := 1;
Max := Length(ISOName);
While I <= Max Do
begin
If Not(ISOName[I] in ['a'..'z','A'..'Z','0'..'9','-','+','.',' ']) Then
begin
Delete(ISOName,I,1);
Dec(Max);
end
Else
begin
Inc(I);
end;
end;
Result := ISOName;
end;
Finally
CloseHandle(ISOFile);
end;
end;
Niestety, tak samo jak w linku powyżej, dostajemy "Stack Overflow";
Poprawiony unit bez rekurencji :
unit uISO;
interface
uses
Windows, Sysutils, Math, StrUtils;
type
PDirectoryRecord = ^TDirectoryRecord;
TDirectoryRecord = packed record
DirectoryLength : Byte;
XARLength : Byte;
ExtentLocation : LongWord;
ExtentLocationBE : LongWord;
DataLength : LongWord;
DataLengthBE : LongWord;
DateTime : Array[0..6] Of Byte;
FileFlags : Byte;
FileUnitSize : Byte;
InterleaveGapSize : Byte;
ValueSequenceNum : LongWord;
FileNameLength : Byte;
FileName : Array[0..255] Of Char;
end;
TDirectoryArrayRecord = Array Of TDirectoryRecord;
PSearchFilter = ^TSearchFilter;
TSearchFilter = record
Flags : LongWord;
Name : Array[0..255] Of Char;
lwType : LongWord;
Size : LongWord;
SizeType : LongWord;
Data : Pointer;
DataSize : LongWord;
end;
const
SECTOR_SIZE = 2048;
ISO_FLAG_FILE = $00;
ISO_FLAG_EXISTENCE = $01;
ISO_FLAG_DIRECTORY = $02;
ISO_FLAG_ASSOCIATED = $04;
ISO_FLAG_RECORD = $08;
ISO_FLAG_PROTECTION = $10;
ISO_FLAG_MULTIEXTENT = $80;
FILTER_BY_NAME = $01;
function ISOSearchFiles(ISOFile: Cardinal; Output: TDirectoryArrayRecord; Max: Integer; Start: Integer = 0): Integer;
implementation
function PosLen(SubStr, Str: PChar; Length: Integer): Bool;
begin
Result := Not(CompareMem(SubStr,Str,Length));
end;
function ISOScanFiles(ISOFile: Cardinal; Output: TDirectoryArrayRecord; Max: Integer; i: integer) : integer;
var
DR : TDirectoryRecord;
fPointer : Cardinal;
Add : Integer;
OldDirLen : Cardinal;
BytesRead : Cardinal;
begin
OldDirLen := 0;
fPointer := SetFilePointer(ISOFile, 0, nil, FILE_CURRENT);
while True do
begin
FillChar(DR, SizeOf(TDirectoryRecord), 0);
ReadFile(ISOFile, DR, SizeOf(TDirectoryRecord), BytesRead, nil);
if (DR.DirectoryLength = 0) then
begin
if ((SECTOR_SIZE - (fPointer mod SECTOR_SIZE)) <= OldDirLen) then
begin
fPointer := fPointer + (SECTOR_SIZE - (fPointer mod SECTOR_SIZE));
SetFilePointer(ISOFile, fPointer, nil, FILE_BEGIN);
ReadFile(ISOFile, DR, SizeOf(TDirectoryRecord), BytesRead, nil);
if (DR.DirectoryLength = 0) then Break;
end
else
Break;
end;
if ((DR.FileName[1] <> #0) AND (DR.FileName[1] <> #1)) then
begin
Add := 1;
if not(ContainsText(string(DR.FileName), 'system.cnf')) then Add := 0;
if (i = Max) then Break;
if ((Add <> 0) AND (DR.DataLength <> 0)) then
begin
Output[i] := DR;
i := i + 1;
end;
end;
fPointer := fPointer + DR.DirectoryLength;
OldDirLen := DR.DirectoryLength;
SetFilePointer(ISOFile, fPointer, nil, FILE_BEGIN);
end;
Result := i;
end;
function ISOSearchFiles(ISOFile: Cardinal; Output: TDirectoryArrayRecord; Max: Integer; Start: integer = 0): integer;
var
DR : TDirectoryRecord;
BytesRead : Cardinal;
begin
SetFilePointer(ISOFile, (16 * SECTOR_SIZE) + 156, nil, FILE_BEGIN);
ReadFile(ISOFile, DR, SizeOf(TDirectoryRecord), BytesRead, nil);
SetFilePointer(ISOFile, DR.ExtentLocation * SECTOR_SIZE, nil, FILE_BEGIN);
Result := ISOScanFiles(ISOFile, Output, Max, Start);
end;
end.
Błędu już nie ma, ale niestety nie zwraca nic :(