Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

355 lines
11 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: PortMessage.cpp
  3. //
  4. // Copyright (c) 1999-2000, Microsoft Corporation
  5. //
  6. // A class to wrap a PORT_MESSAGE struct within an object. It contains space
  7. // for PORT_MAXIMUM_MESSAGE_LENGTH bytes of data. Subclass this class to
  8. // write typed functions that access this data. Otherwise use
  9. // CPortMessage::GetData and type case the pointer returned.
  10. //
  11. // History: 1999-11-07 vtan created
  12. // 2000-08-25 vtan moved from Neptune to Whistler
  13. // --------------------------------------------------------------------------
  14. #include "StandardHeader.h"
  15. #include "PortMessage.h"
  16. #include "LPCGeneric.h"
  17. // --------------------------------------------------------------------------
  18. // CPortMessage::CPortMessage
  19. //
  20. // Arguments: <none>
  21. //
  22. // Returns: <none>
  23. //
  24. // Purpose: Constructor for CPortMessage. Zero the memory.
  25. //
  26. // History: 1999-11-07 vtan created
  27. // 2000-08-25 vtan moved from Neptune to Whistler
  28. // --------------------------------------------------------------------------
  29. CPortMessage::CPortMessage (void)
  30. {
  31. ZeroMemory(&_portMessage, sizeof(_portMessage));
  32. ZeroMemory(_data, sizeof(_data));
  33. }
  34. // --------------------------------------------------------------------------
  35. // CPortMessage::CPortMessage
  36. //
  37. // Arguments: <none>
  38. //
  39. // Returns: <none>
  40. //
  41. // Purpose: Copy constructor for CPortMessage. Copies the given
  42. // CPortMessage and all the data in it to the member variable.
  43. //
  44. // History: 1999-11-07 vtan created
  45. // 2000-08-25 vtan moved from Neptune to Whistler
  46. // --------------------------------------------------------------------------
  47. CPortMessage::CPortMessage (const CPortMessage& portMessage) :
  48. _portMessage(*portMessage.GetPortMessage())
  49. {
  50. ASSERTMSG(portMessage.GetDataLength() < PORT_MAXIMUM_MESSAGE_LENGTH, "Impending heap corruption (illegal PORT_MESSAGE) in CPortMessage::CPortMessage");
  51. CopyMemory(_data, portMessage.GetPortMessage() + 1, portMessage.GetDataLength());
  52. }
  53. // --------------------------------------------------------------------------
  54. // CPortMessage::~CPortMessage
  55. //
  56. // Arguments: <none>
  57. //
  58. // Returns: <none>
  59. //
  60. // Purpose: Destructor for CPortMessage.
  61. //
  62. // History: 1999-11-07 vtan created
  63. // 2000-08-25 vtan moved from Neptune to Whistler
  64. // --------------------------------------------------------------------------
  65. CPortMessage::~CPortMessage (void)
  66. {
  67. }
  68. // --------------------------------------------------------------------------
  69. // CPortMessage::GetPortMessage
  70. //
  71. // Arguments: <none>
  72. //
  73. // Returns: const PORT_MESSAGE*
  74. //
  75. // Purpose: Returns a pointer to the PORT_MESSAGE struct for const
  76. // objects.
  77. //
  78. // History: 1999-11-07 vtan created
  79. // 2000-08-25 vtan moved from Neptune to Whistler
  80. // --------------------------------------------------------------------------
  81. const PORT_MESSAGE* CPortMessage::GetPortMessage (void) const
  82. {
  83. return(&_portMessage);
  84. }
  85. // --------------------------------------------------------------------------
  86. // CPortMessage::GetPortMessage
  87. //
  88. // Arguments: <none>
  89. //
  90. // Returns: const PORT_MESSAGE*
  91. //
  92. // Purpose: Returns a pointer to the PORT_MESSAGE struct for non-const
  93. // objects.
  94. //
  95. // History: 1999-11-07 vtan created
  96. // 2000-08-25 vtan moved from Neptune to Whistler
  97. // --------------------------------------------------------------------------
  98. PORT_MESSAGE* CPortMessage::GetPortMessage (void)
  99. {
  100. return(&_portMessage);
  101. }
  102. // --------------------------------------------------------------------------
  103. // CPortMessage::GetData
  104. //
  105. // Arguments: <none>
  106. //
  107. // Returns: const char*
  108. //
  109. // Purpose: Returns a pointer to the data area for const objects.
  110. //
  111. // History: 1999-11-07 vtan created
  112. // 2000-08-25 vtan moved from Neptune to Whistler
  113. // --------------------------------------------------------------------------
  114. const char* CPortMessage::GetData (void) const
  115. {
  116. return(_data);
  117. }
  118. // --------------------------------------------------------------------------
  119. // CPortMessage::GetData
  120. //
  121. // Arguments: <none>
  122. //
  123. // Returns: char*
  124. //
  125. // Purpose: Returns a pointer to the data area for non-const objects.
  126. //
  127. // History: 1999-11-07 vtan created
  128. // 2000-08-25 vtan moved from Neptune to Whistler
  129. // --------------------------------------------------------------------------
  130. char* CPortMessage::GetData (void)
  131. {
  132. return(_data);
  133. }
  134. // --------------------------------------------------------------------------
  135. // CPortMessage::GetDataLength
  136. //
  137. // Arguments: <none>
  138. //
  139. // Returns: CSHORT
  140. //
  141. // Purpose: Returns the length of the data sent in the PORT_MESSAGE.
  142. //
  143. // History: 1999-11-07 vtan created
  144. // 2000-08-25 vtan moved from Neptune to Whistler
  145. // --------------------------------------------------------------------------
  146. CSHORT CPortMessage::GetDataLength (void) const
  147. {
  148. return(_portMessage.u1.s1.DataLength);
  149. }
  150. // --------------------------------------------------------------------------
  151. // CPortMessage::GetType
  152. //
  153. // Arguments: <none>
  154. //
  155. // Returns: CSHORT
  156. //
  157. // Purpose: Returns the type of message sent in the PORT_MESSAGE.
  158. //
  159. // History: 1999-11-07 vtan created
  160. // 2000-08-25 vtan moved from Neptune to Whistler
  161. // --------------------------------------------------------------------------
  162. CSHORT CPortMessage::GetType (void) const
  163. {
  164. #pragma warning (disable:4310)
  165. return(static_cast<CSHORT>(_portMessage.u2.s2.Type & ~LPC_KERNELMODE_MESSAGE));
  166. #pragma warning (default:4310)
  167. }
  168. // --------------------------------------------------------------------------
  169. // CPortMessage::GetUniqueProcess
  170. //
  171. // Arguments: <none>
  172. //
  173. // Returns: HANDLE
  174. //
  175. // Purpose: Returns the process ID of the client process sent in the
  176. // PORT_MESSAGE.
  177. //
  178. // History: 1999-11-07 vtan created
  179. // 2000-08-25 vtan moved from Neptune to Whistler
  180. // --------------------------------------------------------------------------
  181. HANDLE CPortMessage::GetUniqueProcess (void) const
  182. {
  183. return(_portMessage.ClientId.UniqueProcess);
  184. }
  185. // --------------------------------------------------------------------------
  186. // CPortMessage::GetUniqueThread
  187. //
  188. // Arguments: <none>
  189. //
  190. // Returns: HANDLE
  191. //
  192. // Purpose: Returns the thread ID of the client process sent in the
  193. // PORT_MESSAGE.
  194. //
  195. // History: 1999-11-07 vtan created
  196. // 2000-08-25 vtan moved from Neptune to Whistler
  197. // --------------------------------------------------------------------------
  198. HANDLE CPortMessage::GetUniqueThread (void) const
  199. {
  200. return(_portMessage.ClientId.UniqueThread);
  201. }
  202. // --------------------------------------------------------------------------
  203. // CPortMessage::SetReturnCode
  204. //
  205. // Arguments: status = NTSTATUS to send back to client.
  206. //
  207. // Returns: <none>
  208. //
  209. // Purpose: Sets the return NTSTATUS code in the PORT_MESSAGE to send
  210. // back to the client.
  211. //
  212. // History: 1999-11-12 vtan created
  213. // 2000-08-25 vtan moved from Neptune to Whistler
  214. // --------------------------------------------------------------------------
  215. void CPortMessage::SetReturnCode (NTSTATUS status)
  216. {
  217. reinterpret_cast<API_GENERIC*>(&_data)->status = status;
  218. }
  219. // --------------------------------------------------------------------------
  220. // CPortMessage::SetData
  221. //
  222. // Arguments: pData = Pointer to data passed in.
  223. // ulDataSize = Size of data passed in.
  224. //
  225. // Returns: <none>
  226. //
  227. // Purpose: Copies the given data to the port message buffer that follows
  228. // the PORT_MESSAGE struct and set the PORT_MESSAGE sizes to
  229. // match the data size.
  230. //
  231. // History: 1999-11-07 vtan created
  232. // 2000-08-25 vtan moved from Neptune to Whistler
  233. // --------------------------------------------------------------------------
  234. void CPortMessage::SetData (const void *pData, CSHORT sDataSize)
  235. {
  236. ASSERTMSG(sDataSize < (sizeof(PORT_MAXIMUM_MESSAGE_LENGTH) - sizeof(PORT_MESSAGE)), "Too much data passed to CPortMessage::SetData");
  237. CopyMemory(_data, pData, sDataSize);
  238. _portMessage.u1.s1.DataLength = sDataSize;
  239. _portMessage.u1.s1.TotalLength = static_cast<CSHORT>(sizeof(PORT_MESSAGE) + sDataSize);
  240. }
  241. // --------------------------------------------------------------------------
  242. // CPortMessage::SetDataLength
  243. //
  244. // Arguments: ulDataSize = Size of data.
  245. //
  246. // Returns: <none>
  247. //
  248. // Purpose: Set the PORT_MESSAGE sizes to match the data size.
  249. //
  250. // History: 1999-11-07 vtan created
  251. // 2000-08-25 vtan moved from Neptune to Whistler
  252. // --------------------------------------------------------------------------
  253. void CPortMessage::SetDataLength (CSHORT sDataSize)
  254. {
  255. ASSERTMSG(sDataSize < (sizeof(PORT_MAXIMUM_MESSAGE_LENGTH) - sizeof(PORT_MESSAGE)), "Length too large in CPortMessage::SetDataLength");
  256. _portMessage.u1.s1.DataLength = sDataSize;
  257. _portMessage.u1.s1.TotalLength = static_cast<CSHORT>(sizeof(PORT_MESSAGE) + sDataSize);
  258. }
  259. // --------------------------------------------------------------------------
  260. // CPortMessage::OpenClientToken
  261. //
  262. // Arguments: hToken = HANDLE to the token of the client.
  263. //
  264. // Returns: NTSTATUS
  265. //
  266. // Purpose: Gets the token of the client. This can be the thread
  267. // impersonation token, the process primary token or failure.
  268. //
  269. // History: 1999-11-07 vtan created
  270. // 2000-08-25 vtan moved from Neptune to Whistler
  271. // --------------------------------------------------------------------------
  272. NTSTATUS CPortMessage::OpenClientToken (HANDLE& hToken) const
  273. {
  274. NTSTATUS status;
  275. HANDLE hThread;
  276. OBJECT_ATTRIBUTES objectAttributes;
  277. CLIENT_ID clientID;
  278. hToken = NULL;
  279. InitializeObjectAttributes(&objectAttributes,
  280. NULL,
  281. 0,
  282. NULL,
  283. NULL);
  284. clientID.UniqueProcess = NULL;
  285. clientID.UniqueThread = GetUniqueThread();
  286. status = NtOpenThread(&hThread, THREAD_QUERY_INFORMATION, &objectAttributes, &clientID);
  287. if (NT_SUCCESS(status))
  288. {
  289. (NTSTATUS)NtOpenThreadToken(hThread, TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY, FALSE, &hToken);
  290. TSTATUS(NtClose(hThread));
  291. }
  292. if (hToken == NULL)
  293. {
  294. HANDLE hProcess;
  295. clientID.UniqueProcess = GetUniqueProcess();
  296. clientID.UniqueThread = NULL;
  297. status = NtOpenProcess(&hProcess, PROCESS_QUERY_INFORMATION, &objectAttributes, &clientID);
  298. if (NT_SUCCESS(status))
  299. {
  300. (NTSTATUS)NtOpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY, &hToken);
  301. }
  302. TSTATUS(NtClose(hProcess));
  303. }
  304. return(status);
  305. }