使用Freepascal实现libEWF

时间:2015-06-18 16:44:00

标签: freepascal lazarus

我希望将一个名为libEWF的C库(由Joachim Metz编写)实现到我的Freepascal程序中。一个名叫Erwan的小伙子已经在去年初转换了早期版本的library to Delphi,我反过来调整了一点用于Freepascal。

我的问题与OS Error code 32 'access sharing violation'有关,它由以下代码返回,并表明访问输出文件存在问题(输出文件创建为零字节文件,但没有写入任何内容)。

uses
LibEWFUnit, Windows, ....  
// Image\backup disk using EWF image format, return bytes imaged
function WindowsImageDiskEWF(hDiskHandle : THandle; DiskSize : Int64) : Int64;
var
  Buffer  : array [0..32767] of Byte; 
  fLibEWF : TLibEWF;

begin

  // Initilise the libEWF instance
  fLibEWF:=TLibEWF.create;
  fLibEWF.libewf_SetCompressionValues(1,0);
  fLibEWF.libewf_SetHeaderValue('acquiry_software_version','YAFFI');

  // Create and open the output file, .e.g MyImage.E01 with write access      
  if fLibEWF.libewf_open(frmYaffi.ledtImageName.Text,LIBEWF_OPEN_WRITE)=0 then
  begin
  try      
  // Now to seek to start of device
   FileSeek(hDiskHandle, 0, 0);
     repeat
       // Read source device handle in buffered segments. 
       BytesRead     := FileRead(hDiskHandle, Buffer, SizeOf(Buffer));
       if BytesRead = -1 then
         begin
           RaiseLastOSError;
           exit;
         end;
       inc(TotalBytesRead, BytesRead);

       // Now write buffer to libEWF instance, but -1 keeps being returned
       BytesWritten  := fLibEWF.libewf_write_random(@Buffer, SizeOf(Buffer), TotalBytesRead);         
       if BytesWritten = -1 then
         begin
           RaiseLastOSError;  //THIS KEEPS BEING RAISED : OS ERROR 32
           exit;
         end;          
       inc(TotalBytesWritten, BytesWritten);
   .....
   finally
     fLibEWF.libewf_close;
   ..... 
  end;
end;

并且应该直到TotalBytesRead等于输入设备的大小。

但是,正如笔记所示,由于某些原因,

总是返回-1
BytesWritten  := fLibEWF.libewf_write_random(@Buffer, SizeOf(Buffer), BytesRead);

和RaiseLastOSError不断生成操作系统错误代码32 - 访问共享冲突。使用UnlockIT检查图像文件文件中是否还有其他内容,它只显示我的prgram。与Erwan提供的转换库一起提供的DLL文件也是如此。

我已经尝试联系Erwan,看看他是否可以提供帮助(因为他设法用他的实用程序CloneDisk创建E01备份文件,它使用相同的库但是使用Delphi)但答案尚未到来且可能永远不会做。所以我希望有人可以就如何解决这个问题向我提供指导? Joachim Metz已经足够好回复我,但他显然有许多项目,但尽管他已经足够好,可以告诉我共享权由this other library, line 505 of libcfile_file.c分配。但由于我的单元来自早期版本的libEWF,然后转换为Delphi然后转换为Freepascal,我认为我不能使用或依赖它。

我已经调整过用于Freepascal的转换后的Delphi单元可见HERE。该文件的第301行使得result = -1,这是BytesWritten随后变为等于-1的方式,因此失败。如果有人能看到我需要做出哪些改变,我将不得不承担责任。

在有人说“只是将C库转换为pascal单元”之前,我建议你在建议之前尝试这样做!如果这很容易,我会从https://github.com/libyal/libewf下载最新的和最新的主人,并创建一个新的,新的DLL和单元与所有现代化。但是我花了三天时间与这个概念作斗争并且只遇到了失败。所以Erwans德尔福单位是我最好的希望。谢谢

1 个答案:

答案 0 :(得分:3)

RaiseLastOSError可能在这里甚至不相关。在Erwan的Delphi实现中,对libewf_write_random的调用如下:

function TLibEWF.libewf_write_random(buffer : pointer; 
                                     size : longword; 
                                     offset : int64) : integer;
var
  err:pointer;
begin
  err:=nil;
  Result:=-1;
  if fLibHandle<>0 then begin
    if LIBEWF_VERSION='V1' then 
      Result:=fLibEWFWriteRand(fCurEWFHandle, buffer, size, offset);
    if LIBEWF_VERSION='V2' then 
      Result:=flibewfhandlewriterandom(fCurEWFHandle, buffer, size, offset,@err);
  end;
end;

由于版本V2很可能是最新的,并且您很可能使用版本2,并且由于版本2提供了错误信息,因此该Delphi实现隐藏了LibEWF返回的错误信息。有大量错误检查和处理in the C library。此write方法的方法签名解析为:

 ssize_t libewf_handle_write_buffer(libewf_handle_t *handle,
                                    const void *buffer,
                                    size_t buffer_size,
                                    libcerror_error_t **error )

其中error参数是指向结构(standard libcerror structure)的指针,该结构包含有助于调试的详细错误信息。例如,libewf_handle_write_buffer中的数十个此类来电之一:

if( internal_handle->current_offset < 0 )
{
    libcerror_error_set(
     error,               
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
     function );

    return( -1 );
}

libewf_write_random返回-1的所有情况下,底层库调用也会返回错误信息。这是您需要检查的错误信息。使用当前正在使用的Delphi实现似乎无法做到这一点。我强烈建议您为LibEWF DLL编写自己的包装器,或修改您拥有的包装器,以便检索此错误信息。这将告诉你真正的问题在哪里。肯定错误不是I/O 32错误。