Почему LockFile () предотвращает запись в тот же поток для удаленных папок на NAS? - PullRequest
0 голосов
/ 27 сентября 2018

При работе с удаленной папкой NAS-устройства Synology я испытываю странное поведение методов WinFI c ++ LockFile () и WriteFile ().Настройка сети:

  • Клиент Windows 10
  • NAS-устройство Synology (RS812)
  • NAS-устройство Synology (DS1815 +)

Крепления RS812одна папка из DS1815 + в качестве удаленной папки CIFS (см. https://www.synology.com/en-global/knowledgebase/DSM/help/FileStation/mountremotevolume).

Когда я получаю доступ к этой удаленной папке на RS812 из клиента Windows и блокирую файл в этой папке, я не могу записатьк нему больше из той же темы.Я очень уверен, что нет другого потока / процесса, обращающегося к файлу.

Интересный факт: я могу воспроизвести это, используя только методы WinAPI - я не могу воспроизвести его, используя скрипт PowerShell.

Это c ++ googletest, где проблема может наблюдаться при установке «tempPath» для файла в этой удаленной папке

TEST( FileLockTest, RemoteFolderTest ) {
    auto tempPath = "\\\\nas\\Data\\RemoteFolder\\subfolder\\example.txt";
    if(boost::filesystem::exists(tempPath)) {
        boost::filesystem::remove(tempPath);
    }
    FileLock::Entity ent = CreateFile(tempPath,
                              GENERIC_ALL,
                              0,
                              NULL,
                              CREATE_NEW,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL );
    ASSERT_EQ(0, GetLastError());

    bool hasLock = LockFile( ent, 0, 0, MAXDWORD, MAXDWORD );
    ASSERT_TRUE(hasLock);
    ASSERT_EQ(0, GetLastError());

    char DataBuffer[] = "some example data";
    DWORD bytesToWrite = (DWORD)strlen(DataBuffer);
    DWORD bytesWritten = 0;

    bool success = WriteFile(
                    ent,
                    DataBuffer,
                    bytesToWrite,
                    &bytesWritten,
                    NULL);

    ASSERT_EQ(0, GetLastError());
    ASSERT_TRUE(success);
}

Тест не пройден, потому что getLastError () возвращает код 33 (ERROR_LOCK_VIOLATION) после WriteFile () назывался.Также можно заметить, что в файл ничего не записано.Проверка не дает сбоя при изменении пути к обычной папке на NAS.

Это сценарий PowerShell, который позволяет установить блокировку файла и затем записать его в эту папку.Любые подсказки, почему этот скрипт ведет себя не так, как моя реализация на С ++, также приветствуются!

    $path = $args[0]
    if([System.IO.File]::Exists($path)) {
      [System.IO.File]::Delete($path)
    }
    $file = [System.IO.File]::Create($path)

    $file.lock(0, [Int64].MaxValue)

    $enc = [system.Text.Encoding]::UTF8
    $text = "Some example text"
    $data = $enc.GetBytes($text) 
    $file.Write($data, 0, $data.length)
    $file.close()
...