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.

957 lines
25 KiB

  1. #ifndef __h323ics_util_h
  2. #define __h323ics_util_h
  3. extern "C" DWORD DebugLevel;
  4. EXTERN_C BOOL IsInList (LIST_ENTRY * ListHead, LIST_ENTRY * ListEntry);
  5. EXTERN_C void ExtractList (LIST_ENTRY * DestinationListHead, LIST_ENTRY * SourceListHead);
  6. EXTERN_C DWORD CountListLength (LIST_ENTRY * ListHead);
  7. EXTERN_C void MergeLists (PLIST_ENTRY Result, PLIST_ENTRY Source);
  8. EXTERN_C void AssertListIntegrity (LIST_ENTRY * ListHead);
  9. #define INET_NTOA(a) inet_ntoa(*(struct in_addr*)&(a))
  10. typedef HANDLE TIMER_HANDLE;
  11. __inline
  12. LPWSTR AnsiToUnicode (LPCSTR string, LPWSTR buffer, DWORD buffer_len)
  13. {
  14. int x;
  15. x = MultiByteToWideChar (CP_ACP, 0, string, -1, buffer, buffer_len);
  16. buffer [x] = 0;
  17. return buffer;
  18. }
  19. __inline
  20. LPSTR UnicodeToAnsi (LPCWSTR string, LPSTR buffer, DWORD buffer_len)
  21. {
  22. int x;
  23. x = WideCharToMultiByte (CP_ACP, 0, string, -1, buffer, buffer_len,
  24. NULL, FALSE);
  25. buffer [x] = 0;
  26. return buffer;
  27. }
  28. class TIMER_PROCESSOR;
  29. class OVERLAPPED_PROCESSOR;
  30. class Q931_INFO;
  31. class SOURCE_Q931_INFO;
  32. class DEST_Q931_INFO;
  33. class LOGICAL_CHANNEL;
  34. class H245_INFO;
  35. class SOURCE_H245_INFO;
  36. class DEST_H245_INFO;
  37. class H323_STATE;
  38. class SOURCE_H323_STATE;
  39. class DEST_H323_STATE;
  40. class CALL_BRIDGE;
  41. #ifdef __cplusplus
  42. template <class T>
  43. inline BOOL BadReadPtr(T* p, DWORD dwSize = 1)
  44. {
  45. return IsBadReadPtr(p, dwSize * sizeof(T));
  46. }
  47. template <class T>
  48. inline BOOL BadWritePtr(T* p, DWORD dwSize = 1)
  49. {
  50. return IsBadWritePtr(p, dwSize * sizeof(T));
  51. }
  52. #endif
  53. #if defined(DBG)
  54. void Debug (LPCTSTR);
  55. void DebugF (LPCTSTR, ...);
  56. void DebugError (DWORD, LPCTSTR);
  57. void DebugErrorF (DWORD, LPCTSTR, ...);
  58. void DebugLastError (LPCTSTR);
  59. void DebugLastErrorF (LPCTSTR, ...);
  60. void DumpMemory (const UCHAR * Data, ULONG Length);
  61. void DumpError (DWORD);
  62. #ifdef __cplusplus
  63. extern "C" {
  64. #endif // __cplusplus
  65. #ifdef __cplusplus
  66. }
  67. #endif // __cplusplus
  68. #else // !defined(DBG)
  69. static __inline void Debug (LPCTSTR) {}
  70. static __inline void DebugF (LPCTSTR, ...) {}
  71. static __inline void DebugError (DWORD, LPCTSTR) {}
  72. static __inline void DebugErrorF (DWORD, LPCTSTR, ...) {}
  73. static __inline void DebugLastError (LPCTSTR) {}
  74. static __inline void DebugLastErrorF (LPCTSTR, ...) {}
  75. static __inline void DumpMemory (const UCHAR * Data, ULONG Length) {}
  76. static __inline void DumpError (DWORD) {}
  77. #endif // defined(DBG)
  78. #ifdef _ASSERTE
  79. #undef _ASSERTE
  80. #endif // _ASSERTE
  81. #ifdef assert
  82. #undef assert
  83. #endif
  84. #if DBG
  85. // The latest and greatest Proxy assert
  86. __inline void PxAssert(LPCTSTR file, DWORD line, LPCTSTR condition)
  87. {
  88. DebugF (_T("%s(%d) : Assertion failed, condition: %s\n"),
  89. file, line, condition);
  90. DebugBreak();
  91. }
  92. #define _ASSERTE(condition) if(condition);else\
  93. { PxAssert(_T(__FILE__), __LINE__, _T(#condition)); }
  94. #define assert _ASSERTE
  95. __inline void PxAssertNeverReached (LPCTSTR File, DWORD Line)
  96. {
  97. DebugF (_T("%s(%d) : Assertion failure, code path should never be executed\n"),
  98. File, Line);
  99. DebugBreak();
  100. }
  101. #define AssertNeverReached() PxAssertNeverReached (_T(__FILE__), __LINE__);
  102. #else // !DBG
  103. #define _ASSERTE(condition) NOP_FUNCTION
  104. #define assert NOP_FUNCTION
  105. #define AssertNeverReached() NOP_FUNCTION
  106. #endif // DBG
  107. // 0,1,2,3 : count of bytes from MSB to LSB in host order
  108. #define BYTE0(l) ((BYTE)((DWORD)(l) >> 24))
  109. #define BYTE1(l) ((BYTE)((DWORD)(l) >> 16))
  110. #define BYTE2(l) ((BYTE)((DWORD)(l) >> 8))
  111. #define BYTE3(l) ((BYTE)((DWORD)(l)))
  112. // Handy macro to use in printf statements
  113. #define BYTES0123(l) BYTE0(l), BYTE1(l), BYTE2(l), BYTE3(l)
  114. // 0,1,2,3 : count of bytes from MSB to LSB in network order
  115. #define NETORDER_BYTE0(l) ((BYTE)((BYTE *) &l)[0])
  116. #define NETORDER_BYTE1(l) ((BYTE)((BYTE *) &l)[1])
  117. #define NETORDER_BYTE2(l) ((BYTE)((BYTE *) &l)[2])
  118. #define NETORDER_BYTE3(l) ((BYTE)((BYTE *) &l)[3])
  119. #define SOCKADDR_IN_PRINTF(SocketAddress) \
  120. ntohl ((SocketAddress) -> sin_addr.s_addr), \
  121. ntohs ((SocketAddress) -> sin_port)
  122. // Handy macro to use in printf statements
  123. #define NETORDER_BYTES0123(l) NETORDER_BYTE0(l), NETORDER_BYTE1(l), \
  124. NETORDER_BYTE2(l), NETORDER_BYTE3(l)
  125. static __inline LONG RegQueryValueString (
  126. IN HKEY Key,
  127. IN LPCTSTR ValueName,
  128. OUT LPTSTR ReturnString,
  129. IN DWORD StringMax)
  130. {
  131. DWORD ValueLength;
  132. DWORD Type;
  133. LONG Status;
  134. ValueLength = sizeof (TCHAR) * StringMax;
  135. Status = RegQueryValueEx (Key, ValueName, NULL, &Type, (LPBYTE) ReturnString, &ValueLength);
  136. if (Status != ERROR_SUCCESS)
  137. return Status;
  138. if (Type != REG_SZ)
  139. return ERROR_INVALID_PARAMETER;
  140. return ERROR_SUCCESS;
  141. }
  142. static __inline LONG RegQueryValueDWORD (
  143. IN HKEY Key,
  144. IN LPCTSTR ValueName,
  145. OUT DWORD * ReturnValue)
  146. {
  147. DWORD ValueLength;
  148. DWORD Type;
  149. LONG Status;
  150. ValueLength = sizeof (DWORD);
  151. Status = RegQueryValueEx (Key, ValueName, NULL, &Type, (LPBYTE) ReturnValue, &ValueLength);
  152. if (Status != ERROR_SUCCESS)
  153. return Status;
  154. if (Type != REG_DWORD)
  155. return ERROR_INVALID_PARAMETER;
  156. return ERROR_SUCCESS;
  157. }
  158. class SIMPLE_CRITICAL_SECTION_BASE
  159. {
  160. protected:
  161. CRITICAL_SECTION CriticalSection;
  162. protected:
  163. void Lock (void) { EnterCriticalSection (&CriticalSection); }
  164. void Unlock (void) { LeaveCriticalSection (&CriticalSection); }
  165. void AssertLocked (void) { assert (PtrToUlong(CriticalSection.OwningThread) == GetCurrentThreadId()); }
  166. void AssertNotLocked (void) { assert (!CriticalSection.OwningThread); }
  167. void AssertThreadNotLocked (void) { assert (PtrToUlong(CriticalSection.OwningThread) != GetCurrentThreadId()); }
  168. protected:
  169. SIMPLE_CRITICAL_SECTION_BASE (void) {
  170. InitializeCriticalSection (&CriticalSection);
  171. }
  172. ~SIMPLE_CRITICAL_SECTION_BASE (void) {
  173. if (CriticalSection.OwningThread) {
  174. DebugF (_T("SIMPLE_CRITICAL_SECTION_BASE::~SIMPLE_CRITICAL_SECTION_BASE: thread %08XH stills holds this critical section (this %p)\n"),
  175. PtrToUlong(CriticalSection.OwningThread), this);
  176. }
  177. AssertNotLocked();
  178. DeleteCriticalSection (&CriticalSection);
  179. }
  180. };
  181. #if ENABLE_REFERENCE_HISTORY
  182. #include "dynarray.h"
  183. #endif // ENABLE_REFERENCE_HISTORY
  184. class SYNC_COUNTER;
  185. class LIFETIME_CONTROLLER
  186. {
  187. #if ENABLE_REFERENCE_HISTORY
  188. public:
  189. LIST_ENTRY ListEntry;
  190. struct REFERENCE_HISTORY {
  191. LONG CurrentReferenceCount;
  192. PVOID CallersAddress;
  193. };
  194. DYNAMIC_ARRAY <REFERENCE_HISTORY> ReferenceHistory;
  195. CRITICAL_SECTION ReferenceHistoryLock;
  196. #define MAKE_REFERENCE_HISTORY_ENTRY() { \
  197. PVOID CallersAddress, CallersCallersAddress; \
  198. RtlGetCallersAddress (&CallersAddress, &CallersCallersAddress); \
  199. EnterCriticalSection (&ReferenceHistoryLock); \
  200. REFERENCE_HISTORY * ReferenceHistoryNode = ReferenceHistory.AllocAtEnd (); \
  201. ReferenceHistoryNode -> CallersAddress = CallersAddress; \
  202. ReferenceHistoryNode -> CurrentReferenceCount = Count; \
  203. LeaveCriticalSection (&ReferenceHistoryLock); \
  204. }
  205. #endif //ENABLE_REFERENCE_HISTORY
  206. private:
  207. LONG ReferenceCount;
  208. SYNC_COUNTER * AssociatedSyncCounter;
  209. protected:
  210. LIFETIME_CONTROLLER (SYNC_COUNTER * AssocSyncCounter = NULL);
  211. virtual ~LIFETIME_CONTROLLER ();
  212. public:
  213. void AddRef (void);
  214. void Release (void);
  215. };
  216. template <DWORD SampleHistorySize>
  217. class SAMPLE_PREDICTOR {
  218. public:
  219. SAMPLE_PREDICTOR (void) {
  220. ZeroMemory ((PVOID) &Samples[0], sizeof (Samples));
  221. FirstSampleIndex = 0;
  222. SamplesArraySize = 0;
  223. }
  224. HRESULT AddSample (LONG Sample) {
  225. DWORD ThisSampleIndex;
  226. if (0UL == SampleHistorySize)
  227. return E_ABORT;
  228. if (SamplesArraySize < SampleHistorySize) {
  229. ThisSampleIndex = SamplesArraySize;
  230. SamplesArraySize++;
  231. } else {
  232. ThisSampleIndex = FirstSampleIndex; // Overwrite the least recent sample
  233. FirstSampleIndex++;
  234. FirstSampleIndex %= SampleHistorySize;
  235. }
  236. Samples [ThisSampleIndex] = Sample;
  237. return S_OK;
  238. }
  239. LONG PredictNextSample (void) {
  240. DWORD Index;
  241. DWORD CurrentSampleIndex;
  242. LONG Coefficient = 0;
  243. LONG Prediction = 0;
  244. if (0 == SampleHistorySize)
  245. return 0;
  246. for (Index = 0; Index < SamplesArraySize; Index++) {
  247. if (0 == Index) {
  248. Coefficient = (LONG)((SamplesArraySize & 1) << 1) - 1; // 1 or -1
  249. } else {
  250. Coefficient *= (LONG) Index - (LONG) SamplesArraySize - 1;
  251. Coefficient /= (LONG) Index;
  252. }
  253. CurrentSampleIndex = (FirstSampleIndex + Index) % SamplesArraySize;
  254. Prediction += Coefficient * Samples [CurrentSampleIndex];
  255. }
  256. return Prediction;
  257. }
  258. #if DBG
  259. void PrintSamples (void) {
  260. DWORD Index;
  261. if (SamplesArraySize) {
  262. DebugF (_T("Samples in predictor %p are: \n"), this);
  263. for (Index = 0; Index < SamplesArraySize; Index++)
  264. DebugF (_T("\t@%d(%d)-- %d\n"), Index, Index < FirstSampleIndex ? SamplesArraySize - (FirstSampleIndex - Index) : Index - FirstSampleIndex, Samples[Index]);
  265. } else {
  266. DebugF (_T("There are no samples in predictor %p.\n"), this);
  267. }
  268. }
  269. #endif
  270. HRESULT RetrieveOldSample (
  271. IN DWORD StepsInThePast, // 0 -- most recent sample
  272. OUT LONG * OldSample) {
  273. DWORD SampleIndex;
  274. if (0 == SampleHistorySize)
  275. return E_ABORT;
  276. if (StepsInThePast < SamplesArraySize) {
  277. // Valid request
  278. _ASSERTE (SamplesArraySize);
  279. SampleIndex = (SamplesArraySize + FirstSampleIndex - StepsInThePast - 1) % SamplesArraySize;
  280. *OldSample = Samples [SampleIndex];
  281. return S_OK;
  282. }
  283. return ERROR_INVALID_DATA;
  284. }
  285. private:
  286. LONG Samples [SampleHistorySize]; // This is where samples are kept
  287. LONG PositiveTerms [SampleHistorySize];
  288. LONG NegativeTerms [SampleHistorySize];
  289. DWORD SamplesArraySize;
  290. DWORD FirstSampleIndex; // Index of the least recent sample
  291. };
  292. static __inline HRESULT GetLastErrorAsResult (void) {
  293. return GetLastError() == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32 (GetLastError());
  294. }
  295. static __inline HRESULT GetLastResult (void) {
  296. return GetLastError() == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32 (GetLastError());
  297. }
  298. // A sync counter is an integer counter.
  299. // It is kind of the opposite of a semaphore.
  300. // When the counter is zero, the sync counter is signaled.
  301. // When the counter is nonzero, the sync counter is not signaled.
  302. class SYNC_COUNTER :
  303. public SIMPLE_CRITICAL_SECTION_BASE
  304. {
  305. friend class LIFETIME_CONTROLLER;
  306. private:
  307. LONG CounterValue; // the current value of the counter
  308. HANDLE ZeroEvent; // signaled when CounterValue = 0
  309. public:
  310. #if ENABLE_REFERENCE_HISTORY
  311. LIST_ENTRY ActiveLifetimeControllers;
  312. #endif // ENABLE_REFERENCE_HISTORY
  313. SYNC_COUNTER ();
  314. ~SYNC_COUNTER ();
  315. HRESULT Start (void);
  316. void Stop (void);
  317. void Increment (void);
  318. void Decrement (void);
  319. DWORD Wait (DWORD Timeout);
  320. };
  321. #define HRESULT_FROM_WIN32_ERROR_CODE HRESULT_FROM_WIN32
  322. #define HRESULT_FROM_WINSOCK_ERROR_CODE HRESULT_FROM_WINSOCK_ERROR_CODE
  323. // ASN.1 utility functions
  324. // Setup_UUIE&
  325. // SetupMember(
  326. // IN H323_UserInformation *pH323UserInfo
  327. // );
  328. #define SetupMember(pH323UserInfo) \
  329. (pH323UserInfo)->h323_uu_pdu.h323_message_body.u.setup
  330. // Returns a non-zero value only. So don't try comparing it with TRUE/FALSE
  331. // BOOL
  332. // IsDestCallSignalAddressPresent(
  333. // IN H323_UserInformation *pH323UserInfo
  334. // );
  335. #define IsDestCallSignalAddressPresent(pH323UserInfo) \
  336. (SetupMember(pH323UserInfo).bit_mask & Setup_UUIE_destCallSignalAddress_present)
  337. // Get the destCallSignalAddress member
  338. // TransportAddress&
  339. // DCSAddrMember(
  340. // IN H323_UserInformation *pH323UserInfo
  341. // );
  342. #define DCSAddrMember(pH323UserInfo) \
  343. SetupMember(pH323UserInfo).destCallSignalAddress
  344. // Get the destCallSignalAddress member
  345. // DESTINATION_ADDRESS *&
  346. // DestAddrMember(
  347. // IN H323_UserInformation *pH323UserInfo
  348. // );
  349. #define DestAddrMember(pH323UserInfo) \
  350. SetupMember(pH323UserInfo).destinationAddress
  351. // BOOL
  352. // IsTransportAddressTypeIP(
  353. // IN TransportAddress Addr
  354. // );
  355. #define IsTransportAddressTypeIP(Addr) \
  356. (Addr.choice == ipAddress_chosen)
  357. // BOOL
  358. // IPAddrMember(
  359. // IN TransportAddress Addr
  360. // );
  361. #define IPAddrMember(Addr) \
  362. Addr.u.ipAddress
  363. typedef struct Setup_UUIE_destinationAddress DESTINATION_ADDRESS;
  364. ///////////////////////////////////////////////////////////////////////////////
  365. // //
  366. // Routines for filling and extracting from structures used to //
  367. // store Transport addresses in Q.931 and H.245 ASN //
  368. // //
  369. ///////////////////////////////////////////////////////////////////////////////
  370. // fills the TransportAddress port and address bytes with
  371. // those specified. assumes that the passed in values are
  372. // in host order
  373. __inline void
  374. FillTransportAddress(
  375. IN DWORD IPv4Address, // host order
  376. IN WORD Port, // host order
  377. OUT TransportAddress &TransportAddress
  378. )
  379. {
  380. // we are filling in an IP address
  381. TransportAddress.choice = ipAddress_chosen;
  382. // fill in the port
  383. TransportAddress.u.ipAddress.port = Port;
  384. // value is a ptr to a struct, so it can't be null
  385. _ASSERTE(NULL != TransportAddress.u.ipAddress.ip.value);
  386. // 4 bytes in the IP address
  387. // copy the bytes into the transport address array
  388. TransportAddress.u.ipAddress.ip.length = 4;
  389. *((DWORD *)TransportAddress.u.ipAddress.ip.value) =
  390. htonl(IPv4Address);
  391. }
  392. static __inline void FillTransportAddress (
  393. IN const SOCKADDR_IN & SocketAddress,
  394. OUT TransportAddress & ReturnTransportAddress)
  395. {
  396. FillTransportAddress (
  397. ntohl (SocketAddress.sin_addr.s_addr),
  398. ntohs (SocketAddress.sin_port),
  399. ReturnTransportAddress);
  400. }
  401. // returns E_INVALIDARG for PDUs which can not be handled.
  402. __inline HRESULT
  403. GetTransportInfo(
  404. IN const TransportAddress &TransportAddress,
  405. OUT DWORD &IPv4Address, // host order
  406. OUT WORD &Port // host order
  407. )
  408. {
  409. // we proceed only if the transport address has the
  410. // IP address (v4) field filled
  411. if (!(ipAddress_chosen & TransportAddress.choice))
  412. {
  413. DebugF( _T("GetTransportInfo(&H245Address, &0x%x, &%u), ")
  414. _T("non unicast address type = %d, returning E_INVALIDARG\n"),
  415. IPv4Address, Port, TransportAddress.choice);
  416. return E_INVALIDARG;
  417. }
  418. // fill in the port
  419. Port = TransportAddress.u.ipAddress.port;
  420. // 4 bytes in the IP address
  421. // copy the bytes into the transport address array
  422. if (4 != TransportAddress.u.ipAddress.ip.length)
  423. {
  424. DebugF( _T("GetTransportInfo: bogus address length (%d) in TransportAddress\n"),
  425. TransportAddress.u.ipAddress.ip.length);
  426. return E_INVALIDARG;
  427. }
  428. IPv4Address = ntohl(*((DWORD *)TransportAddress.u.ipAddress.ip.value));
  429. return S_OK;
  430. }
  431. static __inline HRESULT GetTransportInfo (
  432. IN const TransportAddress & TransportAddress,
  433. OUT SOCKADDR_IN & ReturnSocketAddress)
  434. {
  435. HRESULT Result;
  436. ReturnSocketAddress.sin_family = AF_INET;
  437. Result = GetTransportInfo (TransportAddress,
  438. ReturnSocketAddress.sin_addr.s_addr,
  439. ReturnSocketAddress.sin_port);
  440. ReturnSocketAddress.sin_addr.s_addr = htonl (ReturnSocketAddress.sin_addr.s_addr);
  441. ReturnSocketAddress.sin_port = htons (ReturnSocketAddress.sin_port);
  442. return Result;
  443. }
  444. // fills the H245TransportAddress port and address bytes with
  445. // those specified. assumes that the passed in values are
  446. // in host order
  447. inline void
  448. FillH245TransportAddress(
  449. IN DWORD IPv4Address,
  450. IN WORD Port,
  451. OUT H245TransportAddress &H245Address
  452. )
  453. {
  454. // we are filling in an unicast IP address
  455. H245Address.choice = unicastAddress_chosen;
  456. // alias for the unicast address
  457. UnicastAddress &UnicastIPAddress = H245Address.u.unicastAddress;
  458. // its an IP address
  459. UnicastIPAddress.choice = UnicastAddress_iPAddress_chosen;
  460. // fill in the port
  461. UnicastIPAddress.u.iPAddress.tsapIdentifier = Port;
  462. // value is a ptr to a struct, so it can't be null
  463. _ASSERTE(NULL != UnicastIPAddress.u.iPAddress.network.value);
  464. // 4 bytes in the IP address
  465. // copy the bytes into the transport address array
  466. UnicastIPAddress.u.iPAddress.network.length = 4;
  467. *((DWORD *)UnicastIPAddress.u.iPAddress.network.value) =
  468. htonl(IPv4Address);
  469. }
  470. // Returned IPaddress and port are in host order
  471. inline HRESULT
  472. GetH245TransportInfo(
  473. IN const H245TransportAddress &H245Address,
  474. OUT DWORD &IPv4Address,
  475. OUT WORD &Port
  476. )
  477. {
  478. // we proceed only if the transport address has a unicast address
  479. if (!(unicastAddress_chosen & H245Address.choice))
  480. {
  481. DebugF( _T("GetH245TransportInfo(&H245Address, &0x%x, &%u), ")
  482. _T("non unicast address type = %d, returning E_INVALIDARG\n"),
  483. IPv4Address, Port, H245Address.choice);
  484. return E_INVALIDARG;
  485. }
  486. // we proceed only if the transport address has the
  487. // IP address (v4) field filled
  488. if (!(UnicastAddress_iPAddress_chosen &
  489. H245Address.u.unicastAddress.choice))
  490. {
  491. DebugF( _T("GetH245TransportInfo(&TransportAddress, &0x%x, &%u), ")
  492. _T("non ip address type = %d, returning E_INVALIDARG\n"),
  493. IPv4Address, Port, H245Address.u.unicastAddress.choice);
  494. return E_INVALIDARG;
  495. }
  496. const UnicastAddress & UnicastIPAddress = H245Address.u.unicastAddress;
  497. // fill in the port
  498. Port = UnicastIPAddress.u.iPAddress.tsapIdentifier;
  499. // 4 bytes in the IP address
  500. // copy the bytes into the transport address array
  501. if (4 != UnicastIPAddress.u.iPAddress.network.length)
  502. {
  503. DebugF( _T("GetH245TransportInfo: bogus ip address length (%d), failing\n"),
  504. UnicastIPAddress.u.iPAddress.network.length);
  505. return E_INVALIDARG;
  506. }
  507. // value is a ptr to a struct, so it can't be null
  508. _ASSERTE(NULL != UnicastIPAddress.u.iPAddress.network.value);
  509. IPv4Address = ntohl(*((DWORD *)UnicastIPAddress.u.iPAddress.network.value));
  510. return S_OK;
  511. }
  512. static __inline HRESULT GetH245TransportInfo (
  513. IN const H245TransportAddress & H245Address,
  514. OUT SOCKADDR_IN * ReturnSocketAddress)
  515. {
  516. DWORD IPAddress;
  517. WORD Port;
  518. HRESULT Result;
  519. Result = GetH245TransportInfo (H245Address, IPAddress, Port);
  520. if (Result == S_OK) {
  521. ReturnSocketAddress -> sin_family = AF_INET;
  522. ReturnSocketAddress -> sin_addr.s_addr = htonl (IPAddress);
  523. ReturnSocketAddress -> sin_port = htons (Port);
  524. }
  525. return Result;
  526. }
  527. ///////////////////////////////////////////////////////////////////////////////
  528. // //
  529. // Routines dealing with the T.120 Parameters in H.245 PDUs //
  530. // //
  531. ///////////////////////////////////////////////////////////////////////////////
  532. // In case of failure the routine returns
  533. // INADDR_NONE for the T120ConnectToIPAddr
  534. inline HRESULT
  535. GetT120ConnectToAddress(
  536. IN NetworkAccessParameters separateStack,
  537. OUT DWORD &T120ConnectToIPAddr,
  538. OUT WORD &T120ConnectToPort
  539. )
  540. {
  541. // These are the return values in case of a failure.
  542. T120ConnectToIPAddr = INADDR_NONE;
  543. T120ConnectToPort = 0;
  544. // CODEWORK: should we require the distribution member
  545. // to be present always ?
  546. if ((separateStack.bit_mask & distribution_present) &&
  547. (separateStack.distribution.choice != unicast_chosen))
  548. {
  549. // We support Unicast only
  550. return E_INVALIDARG;
  551. }
  552. // Deal with t120SetupProcedure
  553. if (separateStack.networkAddress.choice != localAreaAddress_chosen)
  554. {
  555. // Support only local area addresses
  556. return E_INVALIDARG;
  557. }
  558. GetH245TransportInfo(
  559. separateStack.networkAddress.u.localAreaAddress,
  560. T120ConnectToIPAddr,
  561. T120ConnectToPort
  562. );
  563. DebugF (_T ("T120: Endpoint is listening on: %08X:%04X.\n"),
  564. T120ConnectToIPAddr,
  565. T120ConnectToPort
  566. );
  567. return S_OK;
  568. }
  569. #define TPKT_HEADER_SIZE 4
  570. #define TPKT_VERSION 3
  571. inline DWORD GetPktLenFromTPKTHdr(BYTE *pbTpktHdr)
  572. /*++
  573. Routine Description:
  574. Compute the length of the packet from the TPKT header.
  575. The TPKT header is four bytes long. Byte 0 gives
  576. the TPKT version (defined by TPKT_VERSION). Byte 1
  577. is reserved and should not be interpreted. Bytes 2 and 3
  578. together give the size of the packet (Byte 2 is the MSB and
  579. Byte 3 is the LSB i.e. in network byte order). (This assumes
  580. that the size of the packet will always fit in 2 bytes).
  581. Arguments:
  582. Return Values:
  583. Returns the length of the PDU which follows the TPKT header.
  584. --*/
  585. {
  586. _ASSERTE(pbTpktHdr[0] == TPKT_VERSION);
  587. return ((pbTpktHdr[2] << 8) + pbTpktHdr[3] - TPKT_HEADER_SIZE);
  588. }
  589. inline void SetupTPKTHeader(
  590. OUT BYTE * pbTpktHdr,
  591. IN DWORD dwLength
  592. )
  593. /*++
  594. Routine Description:
  595. Setup the TPKT header based on the length.
  596. The TPKT header is four bytes long. Byte 0 gives
  597. the TPKT version (defined by TPKT_VERSION). Byte 1
  598. is reserved and should not be interpreted. Bytes 2 and 3
  599. together give the size of the packet (Byte 2 is the MSB and
  600. Byte 3 is the LSB i.e. in network byte order). (This assumes
  601. that the size of the packet will always fit in 2 bytes).
  602. Arguments:
  603. Return Values:
  604. Returns S_OK if the version is right and E_FAIL otherwise.
  605. --*/
  606. {
  607. _ASSERTE(pbTpktHdr);
  608. dwLength += TPKT_HEADER_SIZE;
  609. // TPKT requires that the packet size fit in two bytes.
  610. _ASSERTE(dwLength < (1L << 16));
  611. pbTpktHdr[0] = TPKT_VERSION;
  612. pbTpktHdr[1] = 0;
  613. pbTpktHdr[2] = HIBYTE(dwLength); //(BYTE)(dwLength >> 8);
  614. pbTpktHdr[3] = LOBYTE(dwLength); //(BYTE)dwLength;
  615. }
  616. static __inline BOOLEAN RtlEqualStringConst (
  617. IN const STRING * StringA,
  618. IN const STRING * StringB,
  619. IN BOOLEAN CaseInSensitive)
  620. {
  621. return RtlEqualString (
  622. const_cast<STRING *> (StringA),
  623. const_cast<STRING *> (StringB),
  624. CaseInSensitive);
  625. }
  626. static __inline INT RtlCompareStringConst (
  627. IN const STRING * StringA,
  628. IN const STRING * StringB,
  629. IN BOOLEAN CaseInSensitive)
  630. {
  631. return RtlCompareString (
  632. const_cast<STRING *> (StringA),
  633. const_cast<STRING *> (StringB),
  634. CaseInSensitive);
  635. }
  636. static __inline void InitializeAnsiString (
  637. OUT ANSI_STRING * AnsiString,
  638. IN ASN1octetstring_t * AsnString)
  639. {
  640. assert (AnsiString);
  641. assert (AsnString);
  642. AnsiString -> Buffer = (PSTR) AsnString -> value;
  643. AnsiString -> Length = (USHORT) AsnString -> length / sizeof (CHAR);
  644. }
  645. static __inline void InitializeUnicodeString (
  646. OUT UNICODE_STRING * UnicodeString,
  647. IN ASN1char16string_t * AsnString)
  648. {
  649. assert (UnicodeString);
  650. assert (AsnString);
  651. UnicodeString -> Buffer = (PWSTR)AsnString -> value;
  652. UnicodeString -> Length = (USHORT) AsnString -> length / sizeof (WCHAR);
  653. }
  654. // use with "%.*s" or "%.*S"
  655. #define ANSI_STRING_PRINTF(AnsiString) (AnsiString) -> Length, (AnsiString) -> Buffer
  656. // { Length, MaximumLength, Buffer }
  657. #define ANSI_STRING_INIT(Text) { sizeof (Text) - sizeof (CHAR), 0, (Text) } // account for NUL
  658. void FreeAnsiString (
  659. IN ANSI_STRING * String);
  660. NTSTATUS CopyAnsiString (
  661. IN ANSI_STRING * SourceString,
  662. OUT ANSI_STRING * DestString);
  663. static __inline ULONG ByteSwap (
  664. IN ULONG Value)
  665. {
  666. union ULONG_SWAP {
  667. BYTE Bytes [sizeof (ULONG)];
  668. ULONG Integer;
  669. };
  670. ULONG_SWAP * SwapValue;
  671. ULONG_SWAP SwapResult;
  672. SwapValue = (ULONG_SWAP *) &Value;
  673. SwapResult.Bytes [0] = SwapValue -> Bytes [3];
  674. SwapResult.Bytes [1] = SwapValue -> Bytes [2];
  675. SwapResult.Bytes [2] = SwapValue -> Bytes [1];
  676. SwapResult.Bytes [3] = SwapValue -> Bytes [0];
  677. return SwapResult.Integer;
  678. }
  679. // does NOT convert to host order first
  680. static __inline INT Compare_SOCKADDR_IN (
  681. IN const SOCKADDR_IN * AddressA,
  682. IN const SOCKADDR_IN * AddressB)
  683. {
  684. assert (AddressA);
  685. assert (AddressB);
  686. if (AddressA -> sin_addr.s_addr < AddressB -> sin_addr.s_addr) return -1;
  687. if (AddressA -> sin_addr.s_addr > AddressB -> sin_addr.s_addr) return 1;
  688. return 0;
  689. }
  690. static __inline BOOL IsEqualSocketAddress (
  691. IN const SOCKADDR_IN * AddressA,
  692. IN const SOCKADDR_IN * AddressB)
  693. {
  694. assert (AddressA);
  695. assert (AddressB);
  696. assert (AddressA -> sin_family == AF_INET);
  697. assert (AddressB -> sin_family == AF_INET);
  698. return AddressA -> sin_addr.s_addr == AddressB -> sin_addr.s_addr
  699. && AddressA -> sin_port == AddressB -> sin_port;
  700. }
  701. #if DBG
  702. void ExposeTimingWindow (void);
  703. #endif
  704. // Get the address of the best interface that will
  705. // be used to connect to the DestinationAddress
  706. ULONG GetBestInterfaceAddress (
  707. IN DWORD DestinationAddress, // host order
  708. OUT DWORD * InterfaceAddress); // host order
  709. DWORD
  710. H323MapAdapterToAddress (
  711. IN DWORD AdapterIndex
  712. );
  713. #endif // __h323ics_util_h