2010-07-13 3 views
2

Une DLL a les variables partagées suivantes (j'utilise MinGW):fichier Duplication gère entre les processus d'erreur

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

et la variable globale:

HANDLE hFile = NULL; 

Voilà comment je me occupe mon 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; 

Comme vous pouvez le voir, la première instance de la DLL va créer le fichier et définir le fi partagé le handle. Le reste des instances DLL doit dupliquer le handle de fichier d'origine à celui qui est compatible pour son instance. Cependant, DuplicateHandle donne toujours une erreur de "Le handle est invalide". Je suis confus parce que je ne sais pas de quel manche il parle. J'ai confirmé que les variables partagées sont en effet les mêmes entre toutes les instances. Quelqu'un peut-il me dire ce que je fais mal ici?

Répondre

1

Vous ne pouvez pas partager de poignées de ce type. Le partage de poignée est Win32 est beaucoup plus restrictif que vous pourriez imaginer.

Pour partager avec succès une poignée dans Win32, vous devez effectuer les opérations suivantes:

  • Lorsque vous appelez l'API pour ouvrir l'objet (CreateFile pour les fichiers) passent dans une structure SECURITY_ATTRIBUTES, avec bInheritHandle réglé sur TRUE.
  • Une fois que tous les objets partageables ont été créés, lancez le processus enfant avec CreateProcess, en vérifiant que le paramètre bInheritHandles est TRUE.

Cela dupliquera les poignées dans le processus enfant, en s'assurant que les poignées dupliquées ont les mêmes valeurs. Ceci ne fonctionne que si vous pouvez respecter la restriction selon laquelle le second processus DOIT être lancé par le premier processus, et seulement après que tous les objets potentiellement partagés ont été ouverts. Cependant, dans le cas plus général où les processus peuvent être démarrés dans n'importe quel ordre, ou doivent partager l'accès aux objets ouverts après le lancement de l'autre processus: Vous ne pouvez pas partager directement les handles dans ce cas - vous devez ouvrir le objets par namein dans les deux processus - évidemment en utilisant des drapeaux qui sont compatibles avec l'objet étant ouvert plusieurs fois.

Dans le cas de CreateFile: FILE_SHARE_READ | FILE_SHARE_WRITE car le paramètre fSharingMode serait nécessaire pour ouvrir "Hello.txt" deux fois.

Questions connexes