Leaked source code of windows server 2003
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.

437 lines
12 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1992 - 1999
  3. Module Name:
  4. wmsgpack.hxx
  5. Abstract:
  6. This file contains the definitions of the packet formats used by
  7. RPC on LPC.
  8. Author:
  9. Steven Zeck (stevez) 11/12/91
  10. Revision History:
  11. 15-Dec-1992 mikemon
  12. Rewrote the majority of the code.
  13. ... implemented WMSG protocol
  14. 05-15-96 merged LRPC / WMSG into a single protocol
  15. Kamen Moutafov (KamenM) Mar-2000 Support for extended error info
  16. --*/
  17. #ifndef __LPCPACK_HXX__
  18. #define __LPCPACK_HXX__
  19. #define LRPC_DIRECTORY_NAME L##"\\RPC Control\\"
  20. #define MINIMUM_PARTIAL_BUFFLEN 10240
  21. #define PORT_NAME_LEN 132 // The max lpc port name in bytes (66 WCHAR's)
  22. #define LRPC_TIMEOUT 100
  23. #define LRPC_THRESHOLD_SIZE (MINIMUM_PARTIAL_BUFFLEN * 3)
  24. #define BIND_BACK_FLAG 1
  25. #define NEW_SECURITY_CONTEXT_FLAG 2
  26. #define NEW_PRESENTATION_CONTEXT_FLAG 4
  27. #define EXTENDED_ERROR_INFO_PRESENT 8
  28. #define DEFAULT_LOGONID_FLAG (0x10)
  29. #define SERVER_BIND_EXCH_RESP (0x20)
  30. #define TS_NDR20_FLAG 1
  31. #define TS_NDR64_FLAG 2
  32. #define TS_NDRTEST_FLAG 4
  33. // A bind back cookie is used to ensure that the bind back is coming
  34. // from the expected server. it is just a rnadom 64 bit number computed
  35. // during association creation.
  36. #define BIND_BACK_COOKIE_SIZE 8
  37. //
  38. // The format of the bind exchange data in the LRPC_BIND_MESSAGE structure
  39. // is somewhat different for the [in] and [out] bind directions.
  40. // On the [in] direction in addition to the common LRPC_BIND_EXCHANGE_BASE data
  41. // we also pass in the PortName. We do not keep a buffer for the EEInfo.
  42. // On the [out] direction we do not return PortName but do return an EEInfo buffer.
  43. // Therefore LRPC_BIND_EXCHANGE_BASE struct keeps the shared data while LRPC_BIND_EXCHANGE
  44. // and LRPC_BIND_EXCHANGE_RETURN contain the data specific to [in] and [out] bind messages.
  45. // Since LRPC_BIND_EXCHANGE and LRPC_BIND_EXCHANGE_RETURN are identical with the exception
  46. // of the PortName/EEInfo Buffer, for simplicity we always deal with LRPC_BIND_EXCHANGE
  47. // unless pickling or unpickling EEInfo.
  48. //
  49. struct _LRPC_BIND_EXCHANGE_BASE
  50. {
  51. INT ConnectType ;
  52. DWORD AssocKey ;
  53. RPC_SYNTAX_IDENTIFIER InterfaceId;
  54. // can be any of TS_NDR20_FLAG, TS_NDR64_FLAG
  55. unsigned int TransferSyntaxSet;
  56. RPC_STATUS RpcStatus;
  57. // can be: BIND_BACK_FLAG, NEW_SECURITY_CONTEXT_FLAG, NEW_PRESENTATION_CONTEXT_FLAG
  58. // EXTENDED_ERROR_INFO_PRESENT, SERVER_BIND_EXCH_RESP on return from the server
  59. unsigned short Flags;
  60. // the first is always the presentation context id for NDR20,
  61. // and the second is for NDR64. The third can be NDRTest - that's
  62. // why the + 1
  63. unsigned short PresentationContext[MaximumNumberOfTransferSyntaxes + 1];
  64. unsigned long SecurityContextId;
  65. // Cookie to verify that bind back is coming from the same server
  66. // that received a bind.
  67. BYTE Cookie[BIND_BACK_COOKIE_SIZE];
  68. };
  69. typedef struct _LRPC_BIND_EXCHANGE: public _LRPC_BIND_EXCHANGE_BASE
  70. {
  71. char szPortName[PORT_NAME_LEN] ;
  72. } LRPC_BIND_EXCHANGE;
  73. typedef struct _LRPC_BIND_EXCHANGE_RETURN: public _LRPC_BIND_EXCHANGE_BASE
  74. {
  75. // provide 16 byte alignment
  76. unsigned char Pad2[12];
  77. unsigned char Buffer[4];
  78. } LRPC_BIND_EXCHANGE_RETURN;
  79. // message types
  80. #define LRPC_MSG_BIND 0
  81. #define LRPC_MSG_REQUEST 1
  82. #define LRPC_MSG_RESPONSE 2
  83. #define LRPC_MSG_CALLBACK 3
  84. #define LRPC_MSG_FAULT 4
  85. #define LRPC_MSG_CLOSE 5
  86. #define LRPC_MSG_ACK 6
  87. #define LRPC_BIND_ACK 7
  88. #define LRPC_MSG_COPY 8
  89. #define LRPC_MSG_PUSH 9
  90. #define LRPC_MSG_CANCEL 10
  91. #define LRPC_MSG_BIND_BACK 11
  92. #define LRPC_ASYNC_REQUEST 12
  93. #define LRPC_PARTIAL_REQUEST 13
  94. #define LRPC_CLIENT_SEND_MORE 14
  95. #define LRPC_SERVER_SEND_MORE 15
  96. #define LRPC_MSG_FAULT2 16
  97. #define MAX_LRPC_MSG 16
  98. // connect types
  99. #define LRPC_CONNECT_REQUEST 0
  100. #define LRPC_CONNECT_RESPONSE 1
  101. #define LRPC_CONNECT_TICKLE 2
  102. typedef struct _OLD_SECURITY_CONTEXTS
  103. {
  104. DWORD NumContexts;
  105. DWORD SecurityContextId[1];
  106. } OLD_SECURITY_CONTEXTS;
  107. #define BIND_NAK_PICKLE_BUFFER_OFFSET (FIELD_OFFSET(LRPC_BIND_EXCHANGE_RETURN, Buffer) \
  108. + FIELD_OFFSET(LRPC_BIND_MESSAGE, BindExchange))
  109. #define MAX_BIND_NAK (PORT_MAXIMUM_MESSAGE_LENGTH - BIND_NAK_PICKLE_BUFFER_OFFSET)
  110. typedef struct _LRPC_BIND_MESSAGE
  111. {
  112. PORT_MESSAGE LpcHeader;
  113. union
  114. {
  115. struct
  116. {
  117. unsigned char MessageType;
  118. unsigned char Pad[3];
  119. };
  120. ULONG ZeroInit;
  121. };
  122. union
  123. {
  124. LRPC_BIND_EXCHANGE BindExchange;
  125. LRPC_BIND_EXCHANGE_RETURN BindExchangeReturn;
  126. };
  127. OLD_SECURITY_CONTEXTS OldSecurityContexts;
  128. } LRPC_BIND_MESSAGE;
  129. #define MAX_LRPC_CONTEXTS ((PORT_MAXIMUM_MESSAGE_LENGTH \
  130. - (FIELD_OFFSET(LRPC_BIND_MESSAGE, OldSecurityContexts) \
  131. + FIELD_OFFSET(OLD_SECURITY_CONTEXTS, SecurityContextId)) \
  132. ) / sizeof(DWORD))
  133. typedef struct _LRPC_BIND_BACK_MESSAGE
  134. {
  135. PORT_MESSAGE LpcHeader;
  136. unsigned char MessageType;
  137. unsigned char Pad[3];
  138. DWORD AssocKey;
  139. // Cookie to verify that bind back is coming from the same server
  140. // that received a bind.
  141. BYTE Cookie[BIND_BACK_COOKIE_SIZE];
  142. char szPortName[PORT_NAME_LEN];
  143. } LRPC_BIND_BACK_MESSAGE;
  144. // buffer flags
  145. #define LRPC_BUFFER_IMMEDIATE 0x0001
  146. #define LRPC_BUFFER_REQUEST 0x0002
  147. #define LRPC_BUFFER_SERVER 0x0004
  148. // misc flags
  149. #define LRPC_SYNC_CLIENT 0x0040
  150. #define LRPC_BUFFER_PARTIAL 0x0080
  151. #define LRPC_OBJECT_UUID 0x0100
  152. #define LRPC_NON_PIPE 0x0200
  153. #define LRPC_CAUSAL 0x0400
  154. #define LRPC_EEINFO_PRESENT 0x0800
  155. typedef struct _LRPC_RPC_HEADER
  156. {
  157. unsigned char MessageType;
  158. unsigned char Pad;
  159. unsigned short PresentContext;
  160. unsigned short Flags ;
  161. unsigned short ProcedureNumber;
  162. UUID ObjectUuid;
  163. unsigned long SecurityContextId;
  164. unsigned long CallId;
  165. } LRPC_RPC_HEADER;
  166. typedef struct _LRPC_SERVER_BUFFER
  167. {
  168. unsigned int Length;
  169. LPC_PVOID Buffer;
  170. } LRPC_SERVER_BUFFER;
  171. #define MAXIMUM_MESSAGE_BUFFER \
  172. (PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(PORT_MESSAGE) \
  173. - sizeof(LRPC_RPC_HEADER))
  174. typedef struct _LRPC_CONNECT_MESSAGE
  175. {
  176. PORT_MESSAGE LpcHeader;
  177. LRPC_BIND_EXCHANGE BindExchange;
  178. } LRPC_CONNECT_MESSAGE;
  179. typedef struct _LRPC_MINIRPC_MESSAGE
  180. {
  181. PORT_MESSAGE LpcHeader;
  182. LRPC_RPC_HEADER RpcHeader;
  183. } LRPC_MINIRPC_MESSAGE;
  184. typedef struct _LRPC_RPC_MESSAGE
  185. {
  186. PORT_MESSAGE LpcHeader;
  187. LRPC_RPC_HEADER RpcHeader;
  188. union
  189. {
  190. unsigned char Buffer[MAXIMUM_MESSAGE_BUFFER];
  191. PORT_DATA_INFORMATION Request;
  192. LRPC_SERVER_BUFFER Server;
  193. };
  194. } LRPC_RPC_MESSAGE;
  195. typedef struct _LRPC_FAULT_MESSAGE
  196. {
  197. PORT_MESSAGE LpcHeader;
  198. LRPC_RPC_HEADER RpcHeader ;
  199. RPC_STATUS RpcStatus;
  200. // align the Buffer on 8 bytes - required for pickling
  201. DWORD Padding1;
  202. // the actual length has to be retrieved
  203. // from LpcHeader.u1.s1.DataLength/TotalLength
  204. unsigned char Buffer[4];
  205. } LRPC_FAULT_MESSAGE;
  206. #define MAXIMUM_FAULT_MESSAGE \
  207. (PORT_MAXIMUM_MESSAGE_LENGTH - sizeof(LRPC_FAULT_MESSAGE))
  208. // N.B. The layout of fault2 must match the layout of
  209. // LRPC_RPC_MESSAGE up to and including the union of
  210. // Request/Server. This is so because many code paths
  211. // will operate on both, and having the same layout
  212. // allows us to avoid special casing those
  213. typedef struct _LRPC_FAULT2_MESSAGE
  214. {
  215. PORT_MESSAGE LpcHeader;
  216. LRPC_RPC_HEADER RpcHeader ;
  217. union
  218. {
  219. PORT_DATA_INFORMATION Request;
  220. LRPC_SERVER_BUFFER Server;
  221. };
  222. RPC_STATUS RpcStatus;
  223. } LRPC_FAULT2_MESSAGE;
  224. typedef struct _LRPC_CLOSE_MESSAGE
  225. {
  226. PORT_MESSAGE LpcHeader;
  227. unsigned char MessageType;
  228. unsigned char Pad[3];
  229. } LRPC_CLOSE_MESSAGE;
  230. typedef struct _LRPC_PUSH_MESSAGE
  231. {
  232. PORT_MESSAGE LpcHeader;
  233. LRPC_RPC_HEADER RpcHeader;
  234. PORT_DATA_INFORMATION Response;
  235. RPC_STATUS RpcStatus;
  236. } LRPC_PUSH_MESSAGE;
  237. #define ACK_BUFFER_COMPLETE 0x01
  238. typedef struct _LRPC_ACK_MESSAGE
  239. {
  240. PORT_MESSAGE LpcHeader;
  241. unsigned char MessageType;
  242. unsigned char Pad ;
  243. short Shutup ;
  244. RPC_STATUS RpcStatus;
  245. int ValidDataSize ;
  246. int Flags ;
  247. } LRPC_ACK_MESSAGE;
  248. typedef struct _LRPC_COPY_MESSAGE
  249. {
  250. PORT_MESSAGE LpcHeader;
  251. LRPC_RPC_HEADER RpcHeader ;
  252. PORT_DATA_INFORMATION Request;
  253. LRPC_SERVER_BUFFER Server;
  254. RPC_STATUS RpcStatus;
  255. int IsPartial ;
  256. } LRPC_COPY_MESSAGE;
  257. typedef struct _LRPC_PARTIAL_MESSAGE
  258. {
  259. PORT_MESSAGE LpcHeader;
  260. LRPC_RPC_HEADER RpcHeader ;
  261. PORT_DATA_INFORMATION Request;
  262. RPC_STATUS RpcStatus;
  263. int IsPartial ;
  264. } LRPC_PARTIAL_MESSAGE;
  265. typedef LRPC_MINIRPC_MESSAGE LRPC_CANCEL_MESSAGE;
  266. typedef LRPC_MINIRPC_MESSAGE LRPC_SENDMORE_MESSAGE;
  267. typedef union _LRPC_MESSAGE
  268. {
  269. LRPC_CONNECT_MESSAGE Connect;
  270. LRPC_BIND_MESSAGE Bind;
  271. LRPC_RPC_MESSAGE Rpc;
  272. LRPC_FAULT_MESSAGE Fault;
  273. LRPC_FAULT2_MESSAGE Fault2;
  274. LRPC_CLOSE_MESSAGE Close;
  275. PORT_MESSAGE LpcHeader;
  276. LRPC_ACK_MESSAGE Ack ;
  277. LRPC_PUSH_MESSAGE Push ;
  278. LRPC_BIND_BACK_MESSAGE BindBack ;
  279. LRPC_PARTIAL_MESSAGE Partial ;
  280. LRPC_CANCEL_MESSAGE Cancel;
  281. LRPC_SENDMORE_MESSAGE SendMore;
  282. } LRPC_MESSAGE;
  283. //
  284. // Conversion functions to use the 64bit LPC structures when built 32bit on 64bit NT(wow64).
  285. #if defined(BUILD_WOW6432)
  286. inline
  287. CLIENT_ID
  288. MsgClientIdToClientId(const CLIENT_ID64 & s) {
  289. CLIENT_ID d;
  290. d.UniqueProcess = (HANDLE)s.UniqueProcess;
  291. d.UniqueThread = (HANDLE)s.UniqueThread;
  292. return d;
  293. }
  294. inline
  295. CLIENT_ID64
  296. ClientIdToMsgClientId(const CLIENT_ID & s) {
  297. CLIENT_ID64 d;
  298. d.UniqueProcess = (ULONGLONG)s.UniqueProcess;
  299. d.UniqueThread = (ULONGLONG)s.UniqueThread;
  300. return d;
  301. }
  302. inline
  303. ULONGLONG
  304. PtrToMsgPtr(void * s) {
  305. return (ULONGLONG)s;
  306. }
  307. inline
  308. void *
  309. MsgPtrToPtr(ULONGLONG s) {
  310. return (void *)s;
  311. }
  312. #else
  313. inline
  314. CLIENT_ID
  315. MsgClientIdToClientId(const CLIENT_ID & s) {
  316. return s;
  317. }
  318. inline
  319. CLIENT_ID
  320. ClientIdToMsgClientId(const CLIENT_ID s) {
  321. return s;
  322. }
  323. inline
  324. PVOID
  325. PtrToMsgPtr(PVOID s) {
  326. return s;
  327. }
  328. inline
  329. void *
  330. MsgPtrToPtr(void *s) {
  331. return s;
  332. }
  333. #endif
  334. RPC_STATUS
  335. LrpcMapRpcStatus (
  336. IN RPC_STATUS RpcStatus
  337. );
  338. void
  339. ShutdownLrpcClient (
  340. ) ;
  341. inline void
  342. SanitizeLpcHeader (
  343. IN OUT PORT_MESSAGE *PortMessage
  344. )
  345. /*++
  346. Routine Description:
  347. Sanitize a port message setting to 0 all fields
  348. we don't use to avoid leaking uninitialized data
  349. to the other process. This function zeroes out the
  350. following fields:
  351. ClientViewSize (on 64 bit and wow64 only)
  352. Arguments:
  353. PortMessage - the port message to sanitized
  354. Return Value:
  355. --*/
  356. {
  357. // ClientViewSize is union with CallbackId. Zero out
  358. // ClientViewSize as it is larger on 64 bit platforms
  359. #if defined(_WIN64) || defined(BUILD_WOW6432)
  360. PortMessage->ClientViewSize = NULL;
  361. #endif // defined(_WIN64) || defined(BUILD_WOW6432)
  362. }
  363. #endif // __LPCPACK_HXX__