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.

601 lines
18 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Remoting support.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2000.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef __DBGRPC_HPP__
  9. #define __DBGRPC_HPP__
  10. #include <wincrypt.h>
  11. #include <security.h>
  12. #include <winsock2.h>
  13. #include <schannel.h>
  14. #include <pparse.hpp>
  15. #define DEBUG_SERVER_KEY "Software\\Microsoft\\Debug Engine\\Servers"
  16. #define INT_ALIGN2(Val, Pow2) \
  17. (((Val) + (Pow2) - 1) & ~((Pow2) - 1))
  18. #define PTR_ALIGN2(Type, Ptr, Pow2) \
  19. ((Type)INT_ALIGN2((ULONG64)(Ptr), Pow2))
  20. #define DBGRPC_MAX_IDENTITY 128
  21. typedef ULONG64 DbgRpcObjectId;
  22. //
  23. // Stub functions are indexed out of per-interface tables.
  24. // The function indices are encoded as part interface index
  25. // and part method index.
  26. //
  27. #define DBGRPC_STUB_INDEX_INTERFACE_SHIFT 8
  28. #define DBGRPC_STUB_INDEX_INTERFACE_MAX \
  29. ((1 << (8 * sizeof(USHORT) - DBGRPC_STUB_INDEX_INTERFACE_SHIFT)) - 1)
  30. #define DBGRPC_STUB_INDEX_METHOD_MAX \
  31. ((1 << DBGRPC_STUB_INDEX_INTERFACE_SHIFT) - 1)
  32. #define DBGRPC_STUB_INDEX(Interface, Method) \
  33. ((USHORT)(((Interface) << DBGRPC_STUB_INDEX_INTERFACE_SHIFT) | (Method)))
  34. #define DBGRPC_STUB_INDEX_INTERFACE(StubIndex) \
  35. ((StubIndex) >> DBGRPC_STUB_INDEX_INTERFACE_SHIFT)
  36. #define DBGRPC_STUB_INDEX_METHOD(StubIndex) \
  37. ((StubIndex) & DBGRPC_STUB_INDEX_METHOD_MAX)
  38. //
  39. // Interface indices for stub indices are given here
  40. // rather than generated as they must stay constant
  41. // for compatibility.
  42. //
  43. // IMPORTANT: New interfaces must be added at the end of
  44. // the section for that header. New headers must be
  45. // well separated from each other to allow expansion.
  46. //
  47. enum
  48. {
  49. // The first dbgeng interface must always be zero.
  50. DBGRPC_SIF_IDebugAdvanced,
  51. DBGRPC_SIF_IDebugBreakpoint,
  52. DBGRPC_SIF_IDebugClient,
  53. DBGRPC_SIF_IDebugControl,
  54. DBGRPC_SIF_IDebugDataSpaces,
  55. DBGRPC_SIF_IDebugEventCallbacks,
  56. DBGRPC_SIF_IDebugInputCallbacks,
  57. DBGRPC_SIF_IDebugOutputCallbacks,
  58. DBGRPC_SIF_IDebugRegisters,
  59. DBGRPC_SIF_IDebugSymbolGroup,
  60. DBGRPC_SIF_IDebugSymbols,
  61. DBGRPC_SIF_IDebugSystemObjects,
  62. DBGRPC_SIF_IDebugClient2,
  63. DBGRPC_SIF_IDebugControl2,
  64. DBGRPC_SIF_IDebugDataSpaces2,
  65. DBGRPC_SIF_IDebugSymbols2,
  66. DBGRPC_SIF_IDebugSystemObjects2,
  67. // Add new dbgeng interfaces here.
  68. DBGRPC_SIF_IUserDebugServices = 192,
  69. // Add new dbgsvc interfaces here.
  70. };
  71. #define DBGRPC_SIF_DBGENG_FIRST 0
  72. #define DBGRPC_SIF_DBGENG_LAST DBGRPC_SIF_IDebugSystemObjects2
  73. #define DBGRPC_SIF_DBGSVC_FIRST DBGRPC_SIF_IUserDebugServices
  74. #define DBGRPC_SIF_DBGSVC_LAST DBGRPC_SIF_IUserDebugServices
  75. #define DBGRPC_RETURN 0x0001
  76. #define DBGRPC_NO_RETURN 0x0002
  77. #define DBGRPC_LOCKED 0x0004
  78. struct DbgRpcCall
  79. {
  80. DbgRpcObjectId ObjectId;
  81. USHORT StubIndex;
  82. USHORT Flags;
  83. ULONG InSize;
  84. ULONG OutSize;
  85. HRESULT Status;
  86. ULONG Sequence;
  87. ULONG Reserved1;
  88. };
  89. //
  90. // These functions and tables are automatically generated.
  91. //
  92. typedef HRESULT (*DbgRpcStubFunction)
  93. (IUnknown* If, class DbgRpcConnection* Conn, DbgRpcCall* Call,
  94. PUCHAR InData, PUCHAR OutData);
  95. struct DbgRpcStubFunctionTable
  96. {
  97. DbgRpcStubFunction* Functions;
  98. ULONG Count;
  99. };
  100. // These functions are provided by a caller of dbgrpc with
  101. // implementations specific to the caller.
  102. void DbgRpcInitializeClient(void);
  103. DbgRpcStubFunction DbgRpcGetStub(USHORT StubIndex);
  104. #if DBG
  105. PCSTR DbgRpcGetStubName(USHORT StubIndex);
  106. #endif
  107. HRESULT DbgRpcPreallocProxy(REFIID InterfaceId, PVOID* Interface,
  108. class DbgRpcProxy** Proxy, PULONG IfUnique);
  109. void DbgRpcDeleteProxy(class DbgRpcProxy* Proxy);
  110. HRESULT DbgRpcServerThreadInitialize(void);
  111. void DbgRpcServerThreadUninitialize(void);
  112. void DbgRpcError(char* Format, ...);
  113. //----------------------------------------------------------------------------
  114. //
  115. // DbgRpcTransport.
  116. //
  117. //----------------------------------------------------------------------------
  118. #define MAX_SERVER_NAME MAX_PARAM_VALUE
  119. #define MAX_PASSWORD_BUFFER 32
  120. enum
  121. {
  122. TRANS_TCP,
  123. TRANS_NPIPE,
  124. TRANS_SSL,
  125. TRANS_SPIPE,
  126. TRANS_1394,
  127. TRANS_COM,
  128. TRANS_COUNT
  129. };
  130. extern PCSTR g_DbgRpcTransportNames[TRANS_COUNT];
  131. class DbgRpcTransport : public ParameterStringParser
  132. {
  133. public:
  134. DbgRpcTransport(void)
  135. {
  136. m_ServerName[0] = 0;
  137. m_PasswordGiven = FALSE;
  138. }
  139. virtual ~DbgRpcTransport(void);
  140. virtual ULONG GetNumberParameters(void);
  141. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value);
  142. virtual void ResetParameters(void);
  143. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  144. virtual DbgRpcTransport* Clone(void) = 0;
  145. virtual HRESULT CreateServer(void) = 0;
  146. virtual HRESULT AcceptConnection(DbgRpcTransport** ClientTrans,
  147. PSTR Identity) = 0;
  148. virtual HRESULT ConnectServer(void) = 0;
  149. virtual ULONG Read(ULONG Seq, PVOID Buffer, ULONG Len) = 0;
  150. virtual ULONG Write(ULONG Seq, PVOID Buffer, ULONG Len) = 0;
  151. void CloneData(DbgRpcTransport* Trans);
  152. char m_ServerName[MAX_SERVER_NAME];
  153. BOOL m_PasswordGiven;
  154. UCHAR m_HashedPassword[MAX_PASSWORD_BUFFER];
  155. };
  156. class DbgRpcTcpTransport : public DbgRpcTransport
  157. {
  158. public:
  159. DbgRpcTcpTransport(void)
  160. {
  161. m_Name = g_DbgRpcTransportNames[TRANS_TCP];
  162. m_Sock = INVALID_SOCKET;
  163. ZeroMemory(&m_OlRead, sizeof(m_OlRead));
  164. ZeroMemory(&m_OlWrite, sizeof(m_OlWrite));
  165. }
  166. virtual ~DbgRpcTcpTransport(void);
  167. // DbgRpcTransport.
  168. virtual ULONG GetNumberParameters(void);
  169. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value);
  170. virtual void ResetParameters(void);
  171. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  172. virtual DbgRpcTransport* Clone(void);
  173. virtual HRESULT CreateServer(void);
  174. virtual HRESULT AcceptConnection(DbgRpcTransport** ClientTrans,
  175. PSTR Identity);
  176. virtual HRESULT ConnectServer(void);
  177. virtual ULONG Read(ULONG Seq, PVOID Buffer, ULONG Len);
  178. virtual ULONG Write(ULONG Seq, PVOID Buffer, ULONG Len);
  179. HRESULT InitOl(void);
  180. struct sockaddr_in m_Addr;
  181. SOCKET m_Sock;
  182. WSAOVERLAPPED m_OlRead, m_OlWrite;
  183. ULONG m_TopPort;
  184. };
  185. class DbgRpcNamedPipeTransport : public DbgRpcTransport
  186. {
  187. public:
  188. DbgRpcNamedPipeTransport(void)
  189. {
  190. m_Name = g_DbgRpcTransportNames[TRANS_NPIPE];
  191. m_Handle = NULL;
  192. ZeroMemory(&m_ReadOlap, sizeof(m_ReadOlap));
  193. ZeroMemory(&m_WriteOlap, sizeof(m_WriteOlap));
  194. }
  195. virtual ~DbgRpcNamedPipeTransport(void);
  196. // DbgRpcTransport.
  197. virtual ULONG GetNumberParameters(void);
  198. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value);
  199. virtual void ResetParameters(void);
  200. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  201. virtual DbgRpcTransport* Clone(void);
  202. virtual HRESULT CreateServer(void);
  203. virtual HRESULT AcceptConnection(DbgRpcTransport** ClientTrans,
  204. PSTR Identity);
  205. virtual HRESULT ConnectServer(void);
  206. virtual ULONG Read(ULONG Seq, PVOID Buffer, ULONG Len);
  207. virtual ULONG Write(ULONG Seq, PVOID Buffer, ULONG Len);
  208. char m_Pipe[MAX_PARAM_VALUE];
  209. HANDLE m_Handle;
  210. OVERLAPPED m_ReadOlap, m_WriteOlap;
  211. };
  212. // This class is a generic schannel-based wrapper for
  213. // a normal transport.
  214. #define DBGRPC_SCHAN_BUFFER 16384
  215. class DbgRpcSecureChannelTransport : public DbgRpcTransport
  216. {
  217. public:
  218. DbgRpcSecureChannelTransport(ULONG ThisTransport,
  219. ULONG BaseTransport);
  220. virtual ~DbgRpcSecureChannelTransport(void);
  221. // DbgRpcTransport.
  222. virtual ULONG GetNumberParameters(void);
  223. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value);
  224. virtual void ResetParameters(void);
  225. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  226. virtual DbgRpcTransport* Clone(void);
  227. virtual HRESULT CreateServer(void);
  228. virtual HRESULT AcceptConnection(DbgRpcTransport** ClientTrans,
  229. PSTR Identity);
  230. virtual HRESULT ConnectServer(void);
  231. virtual ULONG Read(ULONG Seq, PVOID Buffer, ULONG Len);
  232. virtual ULONG Write(ULONG Seq, PVOID Buffer, ULONG Len);
  233. // DbgRpcSecureChannelTransport.
  234. HRESULT GetSizes(void);
  235. HRESULT AuthenticateClientConnection(void);
  236. HRESULT InitiateServerConnection(LPSTR pszServerName);
  237. HRESULT AuthenticateServerConnection(void);
  238. void GetNewClientCredentials(void);
  239. void DisconnectFromClient(void);
  240. void DisconnectFromServer(void);
  241. ULONG StreamRead(ULONG Seq, PVOID Buffer, ULONG MaxSize)
  242. {
  243. ULONG Size;
  244. if (m_Stream->Read(Seq, &Size, sizeof(Size)) != sizeof(Size) ||
  245. Size > MaxSize)
  246. {
  247. return 0;
  248. }
  249. return m_Stream->Read(Seq, Buffer, Size);
  250. }
  251. ULONG StreamWrite(ULONG Seq, PVOID Buffer, ULONG Size)
  252. {
  253. if (m_Stream->Write(Seq, &Size, sizeof(Size)) != sizeof(Size))
  254. {
  255. return 0;
  256. }
  257. return m_Stream->Write(Seq, Buffer, Size);
  258. }
  259. ULONG m_ThisTransport;
  260. ULONG m_BaseTransport;
  261. DbgRpcTransport* m_Stream;
  262. SCHANNEL_CRED m_ScCreds;
  263. CredHandle m_Creds;
  264. BOOL m_OwnCreds;
  265. CtxtHandle m_Context;
  266. BOOL m_OwnContext;
  267. ULONG m_Protocol;
  268. char m_User[64];
  269. BOOL m_MachineStore;
  270. UCHAR m_Buffer[DBGRPC_SCHAN_BUFFER];
  271. ULONG m_BufferUsed;
  272. SecPkgContext_StreamSizes m_Sizes;
  273. ULONG m_MaxChunk;
  274. BOOL m_Server;
  275. };
  276. class DbgRpc1394Transport : public DbgRpcTransport
  277. {
  278. public:
  279. DbgRpc1394Transport(void)
  280. {
  281. m_Name = g_DbgRpcTransportNames[TRANS_1394];
  282. m_Handle = NULL;
  283. }
  284. virtual ~DbgRpc1394Transport(void);
  285. // DbgRpcTransport.
  286. virtual ULONG GetNumberParameters(void);
  287. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value);
  288. virtual void ResetParameters(void);
  289. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  290. virtual DbgRpcTransport* Clone(void);
  291. virtual HRESULT CreateServer(void);
  292. virtual HRESULT AcceptConnection(DbgRpcTransport** ClientTrans,
  293. PSTR Identity);
  294. virtual HRESULT ConnectServer(void);
  295. virtual ULONG Read(ULONG Seq, PVOID Buffer, ULONG Len);
  296. virtual ULONG Write(ULONG Seq, PVOID Buffer, ULONG Len);
  297. ULONG m_AcceptChannel;
  298. ULONG m_StreamChannel;
  299. HANDLE m_Handle;
  300. };
  301. class DbgRpcComTransport : public DbgRpcTransport
  302. {
  303. public:
  304. DbgRpcComTransport(void)
  305. {
  306. m_Name = g_DbgRpcTransportNames[TRANS_COM];
  307. m_Handle = NULL;
  308. ZeroMemory(&m_ReadOlap, sizeof(m_ReadOlap));
  309. ZeroMemory(&m_WriteOlap, sizeof(m_WriteOlap));
  310. }
  311. virtual ~DbgRpcComTransport(void);
  312. // DbgRpcTransport.
  313. virtual ULONG GetNumberParameters(void);
  314. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value);
  315. virtual void ResetParameters(void);
  316. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  317. virtual DbgRpcTransport* Clone(void);
  318. virtual HRESULT CreateServer(void);
  319. virtual HRESULT AcceptConnection(DbgRpcTransport** ClientTrans,
  320. PSTR Identity);
  321. virtual HRESULT ConnectServer(void);
  322. virtual ULONG Read(ULONG Seq, PVOID Buffer, ULONG Len);
  323. virtual ULONG Write(ULONG Seq, PVOID Buffer, ULONG Len);
  324. USHORT ScanQueue(UCHAR Chan, PVOID Buffer, USHORT Len);
  325. USHORT ScanPort(UCHAR Chan, PVOID Buffer, USHORT Len,
  326. BOOL ScanForAck, UCHAR AckChan);
  327. USHORT ChanRead(UCHAR Chan, PVOID Buffer, USHORT Len);
  328. USHORT ChanWrite(UCHAR Chan, PVOID Buffer, USHORT Len);
  329. char m_PortName[MAX_PARAM_VALUE];
  330. ULONG m_BaudRate;
  331. UCHAR m_AcceptChannel;
  332. UCHAR m_StreamChannel;
  333. HANDLE m_Handle;
  334. OVERLAPPED m_ReadOlap, m_WriteOlap;
  335. static HRESULT InitializeChannels(void);
  336. static BOOL s_ChanInitialized;
  337. static CRITICAL_SECTION s_QueueLock;
  338. static HANDLE s_QueueChangedEvent;
  339. static LONG s_PortReadOwned;
  340. static CRITICAL_SECTION s_PortWriteLock;
  341. static CRITICAL_SECTION s_WriteAckLock;
  342. static HANDLE s_WriteAckEvent;
  343. static struct DbgRpcComQueue* s_QueueHead;
  344. static struct DbgRpcComQueue* s_QueueTail;
  345. };
  346. //----------------------------------------------------------------------------
  347. //
  348. // DbgRpcConnection.
  349. //
  350. //----------------------------------------------------------------------------
  351. // Special value indicating no data was actually allocated.
  352. // NULL is not used to make it easy to catch access.
  353. #define DBGRPC_NO_DATA ((PUCHAR)(ULONG64)-1)
  354. #define DBGRPC_CONN_BUFFER_SIZE 4096
  355. #define DBGRPC_CONN_BUFFER_ALIGN 16
  356. #define DBGRPC_CONN_BUFFER_DYNAMIC_LIMIT 1024
  357. #define DBGRPC_IN_ASYNC_CALL 0x00000001
  358. #define DBGRPC_FULL_REMOTE_UNKNOWN 0x00000002
  359. class DbgRpcConnection
  360. {
  361. public:
  362. DbgRpcConnection(class DbgRpcTransport* Trans);
  363. ~DbgRpcConnection(void);
  364. PUCHAR StartCall(DbgRpcCall* Call, DbgRpcObjectId ObjectId,
  365. ULONG StubIndex, ULONG InSize, ULONG OutSize);
  366. HRESULT SendReceive(DbgRpcCall* Call, PUCHAR* InOutData);
  367. void FreeData(PUCHAR Data)
  368. {
  369. if (Data != NULL && Data != DBGRPC_NO_DATA)
  370. {
  371. Free(Data);
  372. }
  373. }
  374. PVOID MallocAligned(ULONG Size);
  375. void FreeAligned(PVOID Ptr);
  376. PVOID Alloc(ULONG Size);
  377. void Free(PVOID Ptr);
  378. void Disconnect(void);
  379. class DbgRpcTransport* m_Trans;
  380. DbgRpcConnection* m_Next;
  381. ULONG m_ThreadId;
  382. UCHAR m_UnalignedBuffer[DBGRPC_CONN_BUFFER_SIZE +
  383. DBGRPC_CONN_BUFFER_ALIGN];
  384. PUCHAR m_Buffer;
  385. ULONG m_BufferUsed;
  386. ULONG m_Flags;
  387. ULONG m_Objects;
  388. };
  389. //----------------------------------------------------------------------------
  390. //
  391. // DbgRpcProxy.
  392. //
  393. //----------------------------------------------------------------------------
  394. class DbgRpcProxy
  395. {
  396. public:
  397. DbgRpcProxy(ULONG InterfaceIndex);
  398. ~DbgRpcProxy(void);
  399. IUnknown* InitializeProxy(DbgRpcObjectId ObjectId,
  400. IUnknown* ExistingProxy);
  401. DbgRpcObjectId m_ObjectId;
  402. ULONG m_InterfaceIndex;
  403. ULONG m_OwningThread;
  404. ULONG m_LocalRefs, m_RemoteRefs;
  405. };
  406. //----------------------------------------------------------------------------
  407. //
  408. // DbgRpcClientObject.
  409. //
  410. //----------------------------------------------------------------------------
  411. class DbgRpcClientObject
  412. {
  413. public:
  414. virtual HRESULT Initialize(PSTR Identity, PVOID* Interface) = 0;
  415. // Base implementation does nothing.
  416. virtual void Finalize(void);
  417. virtual void Uninitialize(void) = 0;
  418. };
  419. //----------------------------------------------------------------------------
  420. //
  421. // DbgRpcClientObjectFactory.
  422. //
  423. //----------------------------------------------------------------------------
  424. class DbgRpcClientObjectFactory
  425. {
  426. public:
  427. virtual HRESULT CreateInstance(const GUID* DesiredObject,
  428. DbgRpcClientObject** Object) = 0;
  429. virtual void GetServerTypeName(PSTR Buffer) = 0;
  430. };
  431. #define DBGRPC_SIMPLE_FACTORY(Class, Guid, Name, CtorArgs) \
  432. class Class##Factory : public DbgRpcClientObjectFactory \
  433. { \
  434. public: \
  435. virtual HRESULT CreateInstance(const GUID* DesiredObject, \
  436. DbgRpcClientObject** Object); \
  437. virtual void GetServerTypeName(PSTR Buffer); \
  438. }; \
  439. HRESULT \
  440. Class##Factory::CreateInstance(const GUID* DesiredObject, \
  441. DbgRpcClientObject** Object) \
  442. { \
  443. if (DbgIsEqualIID(Guid, *DesiredObject)) \
  444. { \
  445. *Object = (DbgRpcClientObject*)new Class CtorArgs; \
  446. return *Object != NULL ? S_OK : E_OUTOFMEMORY; \
  447. } \
  448. else \
  449. { \
  450. return E_NOINTERFACE; \
  451. } \
  452. } \
  453. void \
  454. Class##Factory::GetServerTypeName(PSTR Buffer) \
  455. { \
  456. strcpy(Buffer, Name); \
  457. }
  458. //----------------------------------------------------------------------------
  459. //
  460. // Functions.
  461. //
  462. //----------------------------------------------------------------------------
  463. DbgRpcTransport*
  464. DbgRpcNewTransport(ULONG Trans);
  465. DbgRpcTransport*
  466. DbgRpcInitializeTransport(PCSTR Options);
  467. void
  468. DbgRpcDeregisterServers(void);
  469. HRESULT
  470. DbgRpcCreateServerConnection(DbgRpcTransport* Trans,
  471. const GUID* DesiredObject,
  472. IUnknown** ClientObject);
  473. HRESULT
  474. DbgRpcCreateServer(PCSTR Options, DbgRpcClientObjectFactory* Factory);
  475. HRESULT
  476. DbgRpcConnectServer(PCSTR Options, const GUID* DesiredObject,
  477. IUnknown** ClientObject);
  478. DbgRpcConnection*
  479. DbgRpcGetConnection(ULONG ThreadId);
  480. #define DRPC_ERR(Args) g_NtDllCalls.DbgPrint Args
  481. #if 0
  482. #define DBG_RPC
  483. #define DRPC(Args) g_NtDllCalls.DbgPrint Args
  484. #else
  485. #define DRPC(Args)
  486. #endif
  487. #if 0
  488. #define DRPC_REF(Args) g_NtDllCalls.DbgPrint Args
  489. #else
  490. #define DRPC_REF(Args)
  491. #endif
  492. #endif // #ifndef __DBGRPC_HPP__