Ошибка CreateFile для Windows в Delphi THandleStream - PullRequest
3 голосов
/ 29 мая 2011

У меня есть простой класс, производный от 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;

Значение дескриптора соответствует коду ошибки, описанному как ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING в msdn, но, похоже, это очень редкоПараметр aDrive задан правильно (в формате \\. \ X: ).

Что здесь не так, как я могу получить мой действительный дескриптор файла

Ответы [ 2 ]

10 голосов
/ 29 мая 2011

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 голосов
/ 29 мая 2011

Они выглядят как действительные значения дескриптора для меня.Что заставляет вас думать, что это не так?

CreateFile не возвращает коды ошибок.Если это не удается, возвращается Invalid_Handle_Value.Код ошибки дается путем вызова GetLastError.Подробнее о том, как работают эти функции, см. Документацию по MSDN.

В случае сбоя CreateFile я рекомендую вам в свою очередь вызвать конструктор, вызвав исключение:

if Hdl = Invalid_Handle_Value then
  RaiseLastOSError;
...