Einzelnen Beitrag anzeigen

Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

ADS Streams auslesen mit BackupRead und ReadBuffer

  Alt 10. Okt 2007, 15:08
Ich habe folgende Routine geschrieben, um die Alternate Data Streams auszulesen:
Delphi-Quellcode:
function TMpuADS.GetDataStream: WideString;
var
  hFile : THandle;
  hADSFile : THandle;
  BytesRead : DWORD;
  Context : Pointer;
  pBuffer : PByte;
  iLo : DWORD;
  iHi : DWORD;
  wcStreamName : array[0..MAX_PATH] of WideChar;
  StreamName : WideString;
  ReadBuffer : array of WideChar;
begin
  Context := nil;
  Result := '';
  hFile := CreateFileW(PWideChar(FFilename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS,
    0);
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    GetMem(pBuffer, 4096);
    while true do
    begin
      if BackupRead(hFile, pBuffer, 20, BytesRead, False, True, Context) then
      begin
        if BytesRead > 0 then
        begin
          if PWIN32StreamID(pBuffer)^.dwStreamNameSize > 0 then
          begin
            if BackupRead(hFile, @(wcStreamName[0]), PWIN32StreamID(pBuffer)^.dwStreamNameSize, BytesRead, False, True,
              Context) then
            begin
              if BytesRead <> PWIN32StreamID(pBuffer)^.dwStreamNameSize then
                Break
              else
              begin
                if PWIN32StreamID(pBuffer)^.Size > 0 then
                begin
                  SetString(StreamName, wcStreamName, PWIN32StreamID(pBuffer)^.dwStreamNameSize div 2);
                  StreamName := copy(StreamName, 2, length(StreamName));
                  StreamName := ':' + copy(StreamName, 1, pos(':', StreamName) - 1);
                  Writeln(StreamName);
                  hADSFile := CreateFileW(PWideChar(FFilename + StreamName), GENERIC_READ, FILE_SHARE_READ, nil,
                    OPEN_ALWAYS, 0, 0);
                  if hADSFile <> INVALID_HANDLE_VALUE then
                  begin
                    SetLength(ReadBuffer, PWIN32StreamID(pBuffer)^.Size);
                    if ReadFile(hADSFile, ReadBuffer[0], PWIN32StreamID(pBuffer)^.Size, BytesRead, nil) then
                      Writeln(WideString(ReadBuffer))
                    else
                      Writeln(SysErrorMessage(GetLastError));
                  end;
                end;
              end;
            end
            else
              Break;
          end;
          if PWIN32StreamID(pBuffer)^.Size > 0 then
            BackupSeek(hFile, high(DWORD), high(DWORD), iLo, iHi, @Context);
        end
        else
          Break;
      end
      else
        Break;
    end;
    BackupRead(hFile, pBuffer, 0, BytesRead, True, False, Context);
    CloseHandle(hFile);
    FreeMem(pBuffer);
  end
  else
    raise Exception.CreateFmt(rsExceptionTemplate, [GetLastError, SysErrorMessage(GetLastError)]);
end;
Die Streamnamen kan ich alle auslesen, will ich aber mit ReadFile den Inhalt auslesen, bekomm eich die Fehlermeldung:
Zitat:
Der Prozess kann nicht auf die Datei zugreifen, da ein anderer Prozess einen Teil der Datei gesperrt hat
Obwohl ich die Datei mit FILE_SHARE_READ geöffnet habe. Aber wie kan ich die Datei ein zweites mal öffnen, um den ADS auszulesen?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat