我有一个从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:)。
这里出了什么问题,我如何才能获得有效的文件句柄?
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]));
...
对我来说,这些看起来像是有效的句柄值。你为什么认为它们不是?
CreateFile未返回错误代码。如果失败,则返回Invalid_Handle_Value。错误代码是通过调用GetLastError给出的。有关这些函数如何工作的详细信息,请参阅MSDN上的文档。
如果CreateFile失败,我建议您通过引发异常来依次使构造函数失败:
if Hdl = Invalid_Handle_Value then
RaiseLastOSError;