Je supposais que si vous utilisiez CreateFileW demandant un accès exclusif, que s'il était déjà ouvert, je devrais recevoir une violation de partage. Cependant, j'ai trouvé un exemple où ce n'est pas le cas. Si LoadLibraryEx est appelée pour charger une DLL avec le jeu d'indicateurs LOAD_LIBRARY_AS_DATAFILE, CreateFileW est renvoyé avec succès. Cependant, certaines opérations seront rejetées (comme la définition d'attributs comme la fin du fichier). Existe-t-il un meilleur moyen de détecter si ces fichiers sont ouverts? Est-ce que j'utilise CreateFileW de manière incorrecte? Le chargement d'une DLL sans l'indicateur LOAD_LIBRARY_AS_DATAFILE entraîne l'échec de CreateFileW indiquant qu'elle ne peut pas accéder au fichier car elle est utilisée par un autre processus.CreateFileW avec accès exclusif réussit lorsque LoadLibraryEx est appelé avec LOAD_LIBRARY_AS_DATAFILE
HMODULE hModule = LoadLibraryEx(L"\\Pathto\\module.dll", NULL, NULL);
DWORD access = GENERIC_READ | GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY;
DWORD creation = OPEN_EXISTING;
DWORD flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
HANDLE file = CreateFileW(L"\\Pathto\\module.dll", access, 0, NULL, creation, flags, 0);
Le sera ci-dessus se traduire par CreateFileW défaut avec le code d'erreur 32 (ne peut pas accéder à la cause, il est utilisé par un autre procédé), qui est le résultat attendu. Si j'ajoute le drapeau à LoadLibraryEx:
HMODULE hModule = LoadLibraryEx(name, NULL, LOAD_LIBRARY_AS_DATAFILE);
Et utilise le même appel exactement à CreateFileW alors je me dit que c'est un succès, même si je vais avoir des problèmes plus tard lors d'une tentative de mettre fin de fichier (par exemple) . En outre, la suppression du fichier échouera avec une erreur d'accès refusé (sans l'application ou tout autre ayant un handle ouvert).
Un autre comportement impair implique des liens matériels avec des bibliothèques chargées. Si je génère un nouveau lien physique vers le module chargé, et que j'essaie de supprimer le nouveau lien physique nouvellement créé, il échoue également (PAS de poignées de fichier ouvertes, juste un module chargé). Pourquoi? Ne devrait-il pas simplement supprimer le lien et déréférencer le nombre de liens, ou programmer la suppression sur le module de fermeture puisque j'aurais pu obtenir un accès exclusif auparavant?
A noter également, le processus lui-même fonctionne dans un compte utilisateur privilégié avec les privilèges suivants a permis: SE_SECURITY_NAME, SE_BACKUP_NAME, SE_RESTORE_NAME, SE_TAKE_OWNERSHIP_NAME
Comment peut-on déterminer si vous avez vraiment un accès exclusif à un fichier lorsque les bibliothèques sont chargées?
Editer: Juste pour vérifier deux fois, je n'ai vérifié aucune autre poignée ouverte en plus de charger le module via l'outil SysInternals "handle".
Je suppose que les données sont simplement placées en mémoire mais le fichier n'est pas maintenu ouvert. https://blogs.msdn.microsoft.com/oldnewthing/20141120-00/?p=43573 peut être pertinent. –
Je pense qu'il y a plus que ça. Il est clairement encore référencé par le processus propriétaire (listé comme une DLL pour la vie du processus si vous regardez dans SysInternals Process Explorer). Votre lien indique également qu'il est mappé dans l'espace d'adressage du processus. Aussi, pourquoi les downvotes sans explication? Ceci est facilement reproductible. Si c'est une question "stupide", veuillez expliquer pourquoi. – ConfusedDeveloper
Le blog de Raymond suggère qu'il ne devrait pas être répertorié comme une DLL si elle a seulement été ouverte en tant que fichier de données. Btw les downvotes n'étaient pas à moi. –