在进程之间复制文件句柄错误

时间:2010-07-13 03:52:35

标签: c winapi

DLL有以下共享变量(我正在使用MinGW):

int iCount __attribute__((section(".str"), shared)) = 0;
HANDLE hMainFile __attribute__((section(".shr"), shared)) = NULL;
HANDLE hProcess __attribute__((section(".shr"), shared)) = NULL;

和全局变量:

HANDLE hFile = NULL;

这就是我处理DLL_PROCESS_ATTACH的方式:

case DLL_PROCESS_ATTACH:
  if(!iCount)
  {
    hMainFile = CreateFile("Hello.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    hFile = hMainFile;
    hProcess = GetCurrentProcess();
    iCount = 1;
  }
  else
  {
    DuplicateHandle(hProcess, hMainFile, GetCurrentProcess(), &hFile, 0, FALSE, DUPLICATE_SAME_ACCESS);
  }
  break;

如您所见,DLL的第一个实例将创建文件并设置共享文件句柄。其余的DLL实例应该将原始文件句柄复制到与其实例兼容的文件句柄。但是,DuplicateHandle始终给出错误“句柄无效”。我很困惑,因为我不知道它在谈论哪个处理。我已经确认所有实例之间的共享变量确实相同。有人能告诉我这里我做错了吗?

1 个答案:

答案 0 :(得分:1)

你不能分享这样的句柄。处理共享是Win32比你想象的要严格得多。

要在Win32中成功共享句柄,您需要执行以下操作:

  • 调用API打开对象(文件的CreateFile)时,传入SECURITY_ATTRIBUTES结构,并将bInheritHandle设置为TRUE。
  • 只有在创建了所有可共享对象后,才能使用CreateProcess启动子进程,确保bInheritHandles参数为TRUE。

这将复制子进程中的句柄,确保重复的句柄具有相同的值。

这只有在你能够遵守第一个进程必须启动第二个进程的限制时才有效,并且只有在所有可能的共享对象都被打开之后才会有效。

但是,在更一般的情况下,进程可能以任何顺序启动,或者需要共享对启动其他进程后打开的对象的访问权限:在这种情况下你不能直接共享句柄 - 你必须打开对象按名称在两个进程中 - 显然使用与多次打开的对象兼容的标志。

对于CreateFile:FILE_SHARE_READ | FILE_SHARE_WRITE,因为fSharingMode参数需要两次打开“Hello.txt”。