2010-07-13 125 views
2

一個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

你不能共享這樣的句柄。處理共享是Win32比你想象的要嚴格得多。

要成功分享Win32的一個手柄,你需要做到以下幾點:

  • 當調用API打開對象(的CreateFile的文件)傳遞一個SECURITY_ATTRIBUTES結構,bInheritHandle設置爲TRUE。
  • 只有創建了所有可共享對象後,才能使用CreateProcess啓動子進程,確保bInheritHandles參數爲TRUE。

這將複製子進程中的句柄,以確保重複的句柄具有相同的值。

這隻有在您可以遵守第二個進程必須由第一個進程啓動並且只有在打開所有潛在共享對象之後才能使用。

但是,在更一般的情況下,進程可能以任何順序啓動,或者需要共享對其他進程啓動後打開的對象的訪問:在這種情況下,您不能直接共享句柄 - 必須打開在兩個進程中通過命名對象 - 顯然使用與多次打開的對象兼容的標誌。

在CreateFile的情況下:FILE_SHARE_READ | FILE_SHARE_WRITE作爲fSharingMode參數將需要打開「Hello.txt」兩次。