2008-10-06 10 views
6

J'ai développé une application Windows qui utilise de la mémoire partagée, c'est-à-dire des fichiers mappés en mémoire pour la communication interprocessus. J'ai un service Windows qui effectue un traitement et écrit périodiquement des données dans le fichier mappé en mémoire. J'ai une application Windows séparée qui lit à partir du fichier mappé en mémoire et affiche les informations. L'application fonctionne comme prévu sur Windows XP, XP Pro et Server 2003, mais PAS sur Vista.Autorisations d'accès à la mémoire partagée sous Windows

Je peux voir que les données écrites dans le fichier mappé en mémoire se passe correctement par le service Windows parce que je peux ouvrir le fichier avec un éditeur de texte et voir les messages stockés, mais l'application "consommateur" ne peut pas lire à partir du fichier. Une chose intéressante à noter ici, est que si je ferme l'application client et le redémarre, il consomme les messages qui ont été précédemment écrits dans le fichier mappé en mémoire.

Également, une autre chose étrange est que j'ai le même comportement lorsque je me connecte à l'hôte Windows à l'aide de Bureau à distance et invoque/utilise l'application grand public via le bureau à distance. Toutefois, si j'appelle le Bureau à distance et me connecte à la session de console de l'hôte cible avec la commande suivante: mstsc -v:servername /F -console, tout fonctionne parfaitement. C'est pourquoi je pense que le problème est lié aux permissions. C'est ce que je veux dire. Quelqu'un peut-il commenter cela?

EDIT:

L'ACL que j'utilise pour créer le fichier mappé en mémoire et les objets Mutex que l'accès sychronize est comme suit:

TCHAR * szSD = TEXT("D:") 
       TEXT("(A;;RPWPCCDCLCSWRCWDWOGAFA;;;S-1-1-0)") 
       TEXT("(A;;GA;;;BG)") 
       TEXT("(A;;GA;;;AN)") 
       TEXT("(A;;GA;;;AU)") 
       TEXT("(A;;GA;;;LS)") 
       TEXT("(A;;GA;;;RD)") 
       TEXT("(A;;GA;;;WD)") 
       TEXT("(A;;GA;;;BA)"); 

Je pense que cela peut faire partie de la question .

Répondre

0

Avez-vous essayé de déplacer le fichier à un emplacement différent. Essayez de le placer dans le dossier 'Documents partagés', cela semble être le dossier le plus librement accessible dans Vista.

+0

Les documents partagés ne sont pas du tout sécurisés pour les fichiers IPC - ne faites pas cela. –

1

À quel accès ouvrez-vous la section de mémoire partagée? Essayez avec FILE_MAP_ALL_ACCESS et travaillez votre chemin vers le bas. Assurez-vous également que vous n'avez pas de condition de concurrence entre le producteur et les consommateurs - lequel crée la mémoire partagée? Assurez-vous que ce soit créé avant que l'autre essaie de l'ouvrir. Une méthode consiste à créer la section dans le parent avant de démarrer le processus enfant - si vous utilisez une architecture parent/enfant.

Votre enfant devra peut-être s'exécuter sous Vista pour pouvoir accéder à la mémoire partagée. Cela peut également être lié à la session de fenêtre que vous utilisez. Les services s'exécutent dans la session 0 (je pense) alors que d'autres applications (surtout si vous vous connectez via le bureau à distance) peuvent s'exécuter dans une autre session.

+0

J'utilise donc FILE_MAP_ALL_ACCESS pour mapper la mémoire partagée et j'ai conçu le code de sorte que peu importe qui crée la mémoire partagée en premier. Mais votre suggestion sur la session est intéressante. Je vais regarder ça. –

6

donc j'ai trouvé la solution à mon problème:

Sous Windows XP, tout noyau nommé des objets tels que mutex, sémaphores et de la mémoire objets mis en correspondance sont stockés dans le même espace. Ainsi, lorsque différents processus dans différentes sessions utilisateur font référence à un objet particulier en utilisant son nom, ils obtiennent un handle pour cet objet. Toutefois, par mesure de sécurité, les services Terminal Server Windows créent un espace de noms distinct pour les objets noyau référencés à partir des processus démarrés dans la session. Windows Vista intègre également ce comportement, c'est pourquoi mon application ne fonctionne pas correctement sur Vista. Pour élaborer, j'ai un service Windows qui s'exécute dans la session nulle et une application qui s'exécute dans une session utilisateur, de sorte que mes objets nommés ont été créés dans des espaces de noms distincts.

Le correctif rapide pour ce problème était utiliser l'espace de noms global en ajoutant "Global \" à chaque nom d'objet noyau que j'ai utilisé et qui a fait l'affaire.

+0

Vous avez probablement créé un trou de sécurité sur votre système. –

+1

Eh bien, il y a des pensées mélangées sur celui-là. Il y a des moments où vous voulez donner à un service des droits et une capacité plus élevés (disons Système local) qu'une application utilisateur qui doit être capable de s'interfacer avec ce service. Discutable que vous permettez la sécurité en donnant seulement le service et pas l'application tout cet accès. Cependant, vous pouvez voir le fait que le service existe à tous comme un trou de sécurité potentiel. Mais je ne suis pas d'accord. – Dan

3

Le préfixe "Global \" peut ne pas fonctionner sur la mémoire partagée. Voir "Impact of Session 0 Isolation on Services and Drivers in Windows Vista" pour la solution.

+2

Ce document valide mes solutions ... il indique "La manière correcte pour les applications utilisateur de se synchroniser avec un service est d'utiliser explicitement le préfixe Global \". –

Questions connexes