2016年7月20日水曜日

CreateFile で ERROR_SHARING_VIOLATION

ディレクトリのオープンで CreateFile が ERROR_SHARING_VIOLATION 32 を返し続けて嵌った・・・

HANDLE hFile = INVALID_HANDLE_VALUE;

do
{
  hFile = ::CreateFile(filePath, GENERIC_WRITE, 0, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);

  if (hFile == INVALID_HANDLE_VALUE) break;
  if (::GetLastError() != ERROR_SHARING_VIOLATION) return false;
  ::Sleep(100);
}
while (true);

こんな感じで、オープンできるまでループしていたがいつまでたっても返ってこない・・・

Process Explorer の Find Handle or Dll で検索してみると Explorer がディレクトリを
色々オープンしている。
Process Monitor でみると、Read, Write, Delete のフラグが。

更新監視でもやっているのだろうか・・・

今回、タイムスタンプの変更のため、GENERIC_WRITE を指定している。
なので、dwShareMode には 0 を指定していた。

MSDN の説明を読む限りは、このフラグはファイルをオープン後の、
後続の CreateFile に影響するように読めるが・・・

一致していないと開けないのだろうか。

今回は、ディレクトリの属性変更で、ファイルの中身を読み書きするわけではないので、

FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE

を指定することでディレクトリのオープンができた。