在Delphi的THandleStream中创建文件时出现Windows错误

3

我有一个简单的类,是从THandleStream派生而来的,用于编辑原始卷。我调用Windows的createfile()函数来打开驱动器,但该函数从未返回有效的句柄,而是返回一个奇怪的错误代码(在调试时是348,在运行时是304,但并没有引发错误,只是句柄值看起来很奇怪)。这是我正在做的事情:

Constructor TDiskStream.Create(Const aDrive: String);
Var
  Hdl: Cardinal;
  A,B: Int64;
Begin

  Hdl := CreateFile( PChar(ADrive), 
                     GENERIC_WRITE, 
                     FILE_SHARE_READ Or FILE_SHARE_WRITE, 
                     0, OPEN_EXISTING, 0, 0);

  Inherited Create( Hdl );
  GetDiskFreeSpaceEx( PChar( RightStr(ADrive,2) + '\'), A, FSize, @B );

End;

该句柄值匹配msdn上描述的错误代码ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING,但似乎非常罕见。参数aDrive已正确设置(格式为\\.\x:)。

这里有什么问题,我怎样才能获得有效的文件句柄?

2个回答

10

CreateFile函数不返回错误代码,它返回一个有效的句柄或INVALID_HANDLE_VALUE(-1)。这是使用CreateFile函数调用并检查错误的标准方法:

var
  H: THandle;

begin
  H:= CreateFile(PChar('\\.\D:'), GENERIC_READ,
    FILE_SHARE_WRITE or FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if H = INVALID_HANDLE_VALUE then
    raise Exception.Create(Format('Oops - error opening disk: %d', [GetLastError]));
...

4

在我看来,那些句柄值看起来是有效的。你为什么认为它们不是呢?

CreateFile不会返回错误代码。如果失败,它会返回Invalid_Handle_Value。调用GetLastError可以获得错误代码。有关这些函数的详细信息,请参阅MSDN上的文档。

如果CreateFile失败,我建议你通过引发异常来使构造函数失败:

if Hdl = Invalid_Handle_Value then
  RaiseLastOSError;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接