windows_ipc.tex 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. % TODO: remplacer confiant
  2. Après les présentations des objectifs liés aux communications inter-processus et
  3. de l'implémentation Linux, nous pouvons être assez confiant sur l'implémentation
  4. Windows. Malheureusement celle-ci vient nous rappeler qu'un changement de
  5. système implique parfois un changement de paradigme. La documentation quelque
  6. peu hasardeuse va néanmoins nous permettre de mettre en place une architecture
  7. similaire.
  8. \section{Communication inter-processus}
  9. Windows dispose de beaucoup de moyen de communication inter-processus. Parmi
  10. ceux là, aucun ne va avoir les mêmes propriétés que les sockets Unix. On peut
  11. citer:
  12. \begin{itemize}
  13. \item Les Windows sockets, qui réimplémentent la même interface que les
  14. sockets Berkeley mais ne fournissent pas de sockets locaux ou anonymes.
  15. Ceux-ci passent par la pile réseau pour l'envoi de message. On notera
  16. cependant l'implémentation de «TCP Loopback Fast Path» depuis Windows Server
  17. 2012. Cette fonctionnalité conserve la sémantique du protocole TCP tout en
  18. désactivant des fonctionnalités comme l'algorithme de Nagle. C'est donc ce
  19. qui ressemble le plus aux sockets Unix, excepté l'accès au réseau et le
  20. passage de descripteur de fichiers.
  21. https://blogs.technet.microsoft.com/wincat/2012/12/05/fast-tcp-loopback-performance-and-low-latency-with-windows-server-2012-tcp-loopback-fast-path/
  22. \item Les canaux anonymes, qui donnent un moyen de communication
  23. unidirectionnel avec un écrivain et un lecteur. Il faut donc utiliser une
  24. paire de pipe anonyme pour pouvoir discuter en full-duplex.
  25. \item Les canaux nommés, qui sont capables de fonctionner en duplex
  26. \end{itemize}
  27. Ici, on va d'abord s'intéresser aux canaux nommés et voir comment on peut les
  28. utiliser pour transmettre des messages et des ressources.
  29. \begin{code}{c}{Prototype de \inltype{CreateNamedPipe}}
  30. HANDLE CreateNamedPipeA(
  31. LPCSTR lpName,
  32. DWORD dwOpenMode,
  33. DWORD dwPipeMode,
  34. DWORD nMaxInstances,
  35. DWORD nOutBufferSize,
  36. DWORD nInBufferSize,
  37. DWORD nDefaultTimeOut,
  38. LPSECURITY_ATTRIBUTES lpSecurityAttributes
  39. );
  40. \end{code}
  41. Windows disposent de trois mécanismes pour partager des ressources entre
  42. processus. Les ressources sont représentées par des objets \inltype{HANDLE}.
  43. La première méthode est l'héritage, qui a lieu lors de la création d'un nouveau
  44. processus. Les descripteurs de fichiers marqués comme héritable, ou bien aucun
  45. si \inltype{bInheritHandles} est précisé à \inltype{FALSE} lors de l'appel de
  46. \inltype{CreateProcess}, seront récupérés dans le nouveau processus avec la même
  47. valeur. Lorsqu'un \inltype{HANDLE} est hérité, il garde la même valeur dans le
  48. nouveau processus et il faut donc le transmettre soit par IPC, soit par
  49. paramètre de la ligne de commande, soit par injection de code dans le nouveau
  50. processus.
  51. La seconde méthode utilise la fonction \inltype{DuplicateHandle} pour injecter
  52. le descripteur de fichier dans le nouveau processus. Dans ce cas-là, si l'appel
  53. est fait depuis le processus parent, une nouvelle valeur est générée pour ce
  54. \inltype{HANDLE} et il faut le transmettre au processus enfant par l'une des
  55. méthodes mentionnées dans le cas de l'héritage.
  56. \begin{code}{c}{Prototype de la fonction \inltype{DuplicateHandle}}
  57. BOOL WINAPI DuplicateHandle(
  58. _In_ HANDLE hSourceProcessHandle,
  59. _In_ HANDLE hSourceHandle,
  60. _In_ HANDLE hTargetProcessHandle,
  61. _Out_ LPHANDLE lpTargetHandle,
  62. _In_ DWORD dwDesiredAccess,
  63. _In_ BOOL bInheritHandle,
  64. _In_ DWORD dwOptions
  65. );
  66. \end{code}
  67. Enfin, la troisième méthode consiste à utiliser les objets nommées qui sont
  68. créés d'un côté par le processus parent, puis ouvert par les processus enfants
  69. en les référençant par leur nom.
  70. Dans le prototype, j'ai utilisé des canaux nommés pour faciliter la mise en place
  71. mais j'ai également essayé d'utiliser des paires de canaux anonymes dans d'autres
  72. codes isolés.