Delphi Использование LockFile на Windows 7 64 - PullRequest
1 голос
/ 24 сентября 2010

Я обнаружил, что если вы откроете файл, который находится на 32-битном сервере в общей папке на 64-битной машине с Windows 7, прочитайте его, заблокируйте, а затем снова откройте.Когда вы закрываете все открытые дескрипторы, файл фактически остается открытым.

Точные шаги:

  1. Поместите файл длиной от 7000 до 10000 байт в общую папку.на 32-битном компьютере с Windows мы используем Windows Server 2003.

  2. Скомпилируйте следующий код для Win32, чтобы он работал под WOW64.Обратите внимание, что я упустил try..finally, объявления и т. Д. Для простоты.
    (см. Фрагмент кода ниже; ошибка StackOverflow неправильно форматирует код, когда он находится внутри списка)

  3. Запустите приложение на компьютере с 64-разрядной ОС Windows.файл должен быть на 32-битной машине, мы используем Windows Server 2003, ошибка не возникает, если файл находится на 64-битном сервере.

  4. Завершите работу вашего приложения.

  5. Если вы сейчас откроете диспетчер компьютеров на сервере (панель управления-> Управление компьютером) и посмотрите на открытые файлы в общей папке, где находится ваш файл, вы увидите, что ваш файл все ещеopen.

Это код:

procedure CauseFileLockBug(FileName: PChar);
var
  FileHandle1: LongInt;
  FileHandle2: LongInt;
  Buffer: Pointer;
  BytesRead: Cardinal;
begin
  FileHandle1 := CreateFile(
    FileName, 
    GENERIC_READ or GENERIC_WRITE, 
    FILE_SHARE_READ or FILE_SHARE_WRITE, 
    nil, 
    OPEN_EXISTING, 
    FILE_FLAG_RANDOM_ACCESS, 
    0);

  if FileHandle1 > 0 then
  begin
    try
      GetMem(Buffer, 1);

      try
        if ReadFile(FileHandle1, Buffer^, 1, BytesRead, nil) then
        begin
          if LockFile(FileHandle1, 6217, 0, 1, 0) then
          begin
            try
              FileHandle2 := CreateFile(
                FileName, 
                GENERIC_READ or GENERIC_WRITE, 
                FILE_SHARE_READ or FILE_SHARE_WRITE, 
                nil, 
                OPEN_EXISTING, 
                FILE_FLAG_RANDOM_ACCESS, 
                0);

              if FileHandle2 > 0 then
              begin
                CloseHandle(FileHandle2);
              end;
            finally
              UnLockFile(FileHandle1, 6217, 0, 1, 0);
            end;
          end;
        end;
      finally
        FreeMem(Buffer);
      end;
    finally
      CloseHandle(FileHandle1);
    end;
  end;
end;

Проблема не возникает, если вы используете флаг FILE_FLAG_NO_BUFFERING при открытии файла во второй раз или если выне читайте файл перед его блокировкой.

Кто-нибудь заметил это раньше или знает, как его решить, не используя FILE_FLAG_NO_BUFFERING?Обратите внимание, что это происходит только тогда, когда 64-разрядный клиент Windows открывает файл таким способом на 32-разрядной машине Windows, это не происходит с 32-разрядным или 64-разрядным - 64.

1 Ответ

0 голосов
/ 15 октября 2010

ОК. Проблема решена.

Похоже, что проблема была в Nod32 x64. Добавление всех возможных путей в папку (все сетевые пути и сопоставленные диски) в список исключений с подстановочным знаком *, а затем перезагрузка ПК исправили это.

В любом случае спасибо за вашу помощь.

...