Почему LockFile () предотвращает запись в тот же поток для удаленных папок на NAS?

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

  • Клиент Windows 10
  • Synology NAS (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()

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]