Erreur lors de l’utilisation de CreateFileMapping – C

J’utilise le tutoriel sur ce lien MSDN pour implémenter un moyen de transférer des données d’un processus à un autre. Bien que l’on m’ait conseillé dans une question précédente d’utiliser les méthodes Pipe, en raison de certaines contraintes, je n’ai d’autre choix que d’utiliser la méthode CreateFileMapping.

Maintenant, j’ai réussi à créer deux projets de formulaire de fenêtre distincts au sein de la même solution et en modifiant certaines propriétés, les deux formulaires étant chargés en même temps.

De plus, j’ai réussi à implémenter le code donné dans l’exemple MSDN dans le premier programme (Producer) et le deuxième programme (Consumer) sans aucune erreur de compilation.

Le problème que je rencontre maintenant, c’est lorsque j’exécute le premier programme et que je tente de créer le descripteur du fichier mappé. Une erreur s’affiche: le message a été infructueux et je ne comprends pas pourquoi cela se produit.

J’ai ajouté les fichiers de code du producteur et du consommateur pour montrer ce que j’essaie de faire.

Producteur :

#include  #include  #include  //File header definitions #define IDM_FILE_ROLLDICE 1 #define IDM_FILE_QUIT 2 #define BUF_SIZE 256 TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); TCHAR szMsg[]=TEXT("Message from first process!"); void AddMenus(HWND); LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); ////Standard windows stuff - omitted to save space. ////////////////////// // WINDOWS FUNCTION // ////////////////////// LRESULT CALLBACK WindowFunc(HWND hMainWindow, UINT message, WPARAM wParam, LPARAM lParam) { WCHAR buffer[256]; LPCTSTR pBuf; struct DiceData storage; HANDLE hMapFile; switch(message) { case WM_CREATE: { // Create Menus AddMenus(hMainWindow); } break; case WM_COMMAND: // Intercept menu choices switch(LOWORD(wParam)) { case IDM_FILE_ROLLDICE: { //Roll dice and store results in variable //storage = RollDice(); ////Copy results to buffer //swprintf(buffer,255,L"Dice 1: %d, Dice 2: %d",storage.dice1,storage.dice2); ////Show via message box //MessageBox(hMainWindow,buffer,L"Dice Result",MB_OK); hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF, // use paging file NULL, // default security PAGE_READWRITE, // read/write access 0, // maximum object size (high-order DWORD) BUF_SIZE, // maximum object size (low-order DWORD) szName); // name of mapping object if (hMapFile == NULL) { MessageBox(hMainWindow,L"Could not create file mapping object",L"Error",NULL); return 1; } pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { MessageBox(hMainWindow,L"Could not map view of file",L"Error",NULL); CloseHandle(hMapFile); return 1; } CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR))); _getch(); UnmapViewOfFile(pBuf); CloseHandle(hMapFile); } break; case IDM_FILE_QUIT: SendMessage(hMainWindow, WM_CLOSE, 0, 0); break; } break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hMainWindow, message, wParam, lParam); } // //Setup menus // 

Consommateur :

 #include  #include  #include  //File header definitions #define IDM_FILE_QUIT 1 #define IDM_FILE_POLL 2 #define BUF_SIZE 256 TCHAR szName[]=TEXT("Global\\MyFileMappingObject"); //Prototypes void AddMenus(HWND); LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); //More standard windows creation, again omitted. ////////////////////// // WINDOWS FUNCTION // ////////////////////// LRESULT CALLBACK WindowFunc(HWND hMainWindow, UINT message, WPARAM wParam, LPARAM lParam) { HANDLE hMapFile; LPCTSTR pBuf; switch(message) { case WM_CREATE: { // Create Menus AddMenus(hMainWindow); break; } case WM_COMMAND: { // Intercept menu choices switch(LOWORD(wParam)) { case IDM_FILE_POLL: { hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, // read/write access FALSE, // do not inherit the name szName); // name of mapping object if (hMapFile == NULL) { MessageBox(hMainWindow,L"Could not open file mapping object",L"Error",NULL); return 1; } pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object FILE_MAP_ALL_ACCESS, // read/write permission 0, 0, BUF_SIZE); if (pBuf == NULL) { MessageBox(hMainWindow,L"Could not map view of file",L"Error",NULL); CloseHandle(hMapFile); return 1; } MessageBox(NULL, pBuf, TEXT("Process2"), MB_OK); UnmapViewOfFile(pBuf); CloseHandle(hMapFile); break; } case IDM_FILE_QUIT: SendMessage(hMainWindow, WM_CLOSE, 0, 0); break; } break; } case WM_DESTROY: { PostQuitMessage(0); break; } } return DefWindowProc(hMainWindow, message, wParam, lParam); } // //Setup menus // 

Ce n’est en aucun cas bien rangé et définitif, mais ce n’est qu’un début, merci pour toute aide.

Edit: Erreur

Image d'erreur

Edit2: sortie

Image de sortie

Votre code pour le producteur fonctionne pour moi. Quelle version de Windows utilisez-vous? Dans les versions plus récentes (comme Vista et 7), des ressortingctions de sécurité supplémentaires sont imposées à l’access à la mémoire partagée. Il existe une note à ce sujet dans l’article MSDN mentionné précédemment, indiquant que vous devez être un administrateur pour créer des objects de mémoire partagée globale dans Windows Vista / 7.

Vous devez également appeler GetLastError () pour connaître le code d’erreur renvoyé par CreateFileMapping (), ce qui peut être utile pour déterminer la cause première du problème.

Assurez-vous que le nom global est unique. Cela peut être fait avec un outil nommé Process Explorer.

S’il n’est pas unique, cela échouera généralement avec le code d’erreur 6 (le descripteur n’est pas valide) lors de l’appel de CreateFileMappinng.

  1. Télécharger Process Explorer à partir de SysInternals
  2. Exécuter Process Explorer
  3. Exécutez votre application jusqu’à un point d’arrêt juste avant l’échec de CreateFileMapping ()
  4. Rechercher MyFileMappingObject en utilisant Find (Ctrl-F)
  5. Si quelque chose se présente, tel qu’un autre FileMap, Mutex, etc., considérez un nom plus unique et assurez-vous que votre application n’est pas celle qui l’a créée.

Remarque: Pensez à nommer votre FileMapping à l’aide d’un GUID (Fichier -> Outils> Créer un GUID) dans Visual Studio.

Dans le code producteur, _getch () est-il également destiné à une application non-console?

Peut-être avons-nous appris de la même matière / des exemples par le passé. J’ai eu le même problème après avoir migré de XP vers Windows 7:

NULL Handle renvoie la valeur et GetLastError () = 5.

 ERROR_ACCESS_DENIED 5 (0x5) Access is denied. 

Codes d’erreur système (0 à 499): http://msdn.microsoft.com/en-us/library/ms681382.aspx

J’ai utilisé un lpName avec des barres obliques inverses comme dans l’exemple Microsoft de http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537.aspx que vous avez posté ci-dessus. Après avoir modifié le nom de l’object de mappage de fichier (lpName) de “Global \ MyFileMappingObject” en “GlobalMyFileMappingObject”, la fonction CreateFileMapping fonctionne à nouveau sous Windows 7 sans autre modification.

“Le nom peut avoir un préfixe” Global \ “ou” Local \ “pour créer explicitement l’object dans l’espace de nom global ou de session. Le rest du nom peut contenir n’importe quel caractère sauf le caractère barre oblique inversée (‘\’). Création d’un fichier Le mappage d’object dans l’espace de noms global à partir d’une session autre que la session zéro nécessite le privilège SeCreateGlobalPrivilege . Pour plus d’informations, voir Espaces de nommage des objects du kernel “.

Ce n’est pas juste un changement de nom! Si vous avez besoin d’accéder à l’espace de noms global, vous devez alors utiliser la méthode SeCreateGlobalPrivilege .

Essayez de remplacer “Global \ MyFileMappingObject” par “MyFileMappingObject”.

Sous Windows 7, j’ai trouvé:

 OpenFileMapping(FILE_MAP_ALL_ACCESS, ...); 

Provoque des problèmes avec:

 CreateFileMapping( (HANDLE)0xFFFFFFFF, // use paging file 

Essayer:

 OpenFileMappingA(SECTION_MAP_WRITE | SECTION_MAP_READ,...);