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.

618 lines
17 KiB

  1. /******************************************************************************
  2. *
  3. * INTEL Corporation Proprietary Information
  4. * Copyright (c) 1994, 1995, 1996 Intel Corporation.
  5. *
  6. * This listing is supplied under the terms of a license agreement
  7. * with INTEL Corporation and may not be used, copied, nor disclosed
  8. * except in accordance with the terms of that agreement.
  9. *
  10. *****************************************************************************/
  11. /******************************************************************************
  12. *
  13. * $Workfile: h245sys.c $
  14. * $Revision: 1.8 $
  15. * $Modtime: Mar 04 1997 17:38:08 $
  16. * $Log: S:/STURGEON/SRC/H245/SRC/VCS/h245sys.c_v $
  17. *
  18. * Rev 1.8 Mar 04 1997 17:51:56 tomitowx
  19. * process detach fix
  20. *
  21. * Rev 1.7 24 Jan 1997 19:40:48 SBELL1
  22. * upgraded to oss 4.2
  23. *
  24. * Rev 1.6 21 Jun 1996 18:53:22 unknown
  25. * Changed InstUnlock() to fix shutdown re-entrancy bug.
  26. *
  27. * Rev 1.5 10 Jun 1996 16:59:34 EHOWARDX
  28. * Moved init/shutdown of submodules to CreateInstance/InstanceUnlock.
  29. *
  30. * Rev 1.3 04 Jun 1996 13:57:02 EHOWARDX
  31. * Fixed Release build warnings.
  32. *
  33. * Rev 1.2 28 May 1996 14:25:38 EHOWARDX
  34. * Tel Aviv update.
  35. *
  36. * Rev 1.1 16 May 1996 13:51:26 EHOWARDX
  37. * Fixed minor timer/lock count interaction bugs.
  38. *
  39. * Rev 1.0 09 May 1996 21:06:28 EHOWARDX
  40. * Initial revision.
  41. *
  42. * Rev 1.25 09 May 1996 19:39:04 EHOWARDX
  43. * Changed includes.
  44. *
  45. * Rev 1.24 29 Apr 1996 12:56:58 EHOWARDX
  46. * Made timers more accurate & made them use fewer resources.
  47. * Note: This is windows-specific.
  48. *
  49. * Rev 1.18.1.2 15 Apr 1996 15:12:34 EHOWARDX
  50. * Kludge to not call H245DeInitTimer() when last timer is stopped.
  51. * This will have to be revisited later.
  52. *
  53. * Rev 1.18.1.1 02 Apr 1996 22:06:22 EHOWARDX
  54. * No change.
  55. *
  56. * Rev 1.18.1.0 27 Mar 1996 16:44:18 EHOWARDX
  57. * Changed timer code; decided it would work better if H245InitTimer()
  58. * actually got called.
  59. *
  60. * Rev 1.18 26 Mar 1996 09:46:08 cjutzi
  61. *
  62. * - ok.. Added Enter&Leave&Init&Delete Critical Sections for Ring 0
  63. *
  64. * Rev 1.17 25 Mar 1996 18:30:14 helgebax
  65. * - removed H245ASSERT .
  66. * .
  67. *
  68. *
  69. * Rev 1.16 25 Mar 1996 18:10:48 cjutzi
  70. *
  71. * - well .. I broke the build.. had to put back what I did..
  72. *
  73. *
  74. * Rev 1.15 25 Mar 1996 17:50:02 cjutzi
  75. *
  76. * - removed critical section.. back step
  77. *
  78. * Rev 1.14 25 Mar 1996 17:20:34 cjutzi
  79. *
  80. * - added Remesh's EnterCritical section definitions.. to use
  81. * oil layer.
  82. *
  83. * Rev 1.13 18 Mar 1996 12:44:40 cjutzi
  84. *
  85. * - put NULL as callback at shutdown
  86. *
  87. * Rev 1.12 18 Mar 1996 12:41:32 cjutzi
  88. * - added timer code for multiple timers queue..
  89. *
  90. * Rev 1.11 12 Mar 1996 15:48:46 cjutzi
  91. *
  92. * - added InstanceTbl Lock
  93. *
  94. * Rev 1.10 07 Mar 1996 22:47:34 dabrown1
  95. *
  96. * Modifications required for ring0/ring3 compatibilty
  97. *
  98. * Rev 1.9 02 Mar 1996 22:14:52 DABROWN1
  99. *
  100. * removed h245_bzero and h245_bcopy (use memset and memcpy instead)
  101. *
  102. * Rev 1.8 26 Feb 1996 17:10:56 cjutzi
  103. *
  104. * - removed h245sys.h
  105. *
  106. * Rev 1.7 26 Feb 1996 12:42:26 cjutzi
  107. *
  108. * - added bcopy
  109. *
  110. * Rev 1.6 21 Feb 1996 16:23:38 DABROWN1
  111. *
  112. * removed h245_ASN1free
  113. * modified malloc and free to save buffer size internally
  114. *
  115. * Rev 1.5 13 Feb 1996 14:54:12 DABROWN1
  116. *
  117. * removed trace/debug files to new debug directory
  118. *
  119. * Rev 1.4 09 Feb 1996 15:45:08 cjutzi
  120. * - added h245trace
  121. * - added h245Assert
  122. *
  123. *****************************************************************************/
  124. #ifndef STRICT
  125. #define STRICT
  126. #endif
  127. #include "precomp.h"
  128. #include "h245api.h"
  129. #include "h245com.h"
  130. #include "h245sys.x"
  131. /**************************************************************************
  132. *
  133. * Instance Table/Instance Lock implementation
  134. *
  135. **************************************************************************/
  136. CRITICAL_SECTION InstanceCreateLock = {0};
  137. CRITICAL_SECTION InstanceLocks[MAXINST] = {0};
  138. struct InstanceStruct * InstanceTable[MAXINST] = {0};
  139. struct InstanceStruct *InstanceCreate(DWORD dwPhysId, H245_CONFIG_T Configuration)
  140. {
  141. register struct InstanceStruct *pInstance;
  142. register unsigned int uIndex;
  143. unsigned int uFirst = (dwPhysId - 1) % MAXINST;
  144. HRESULT lError;
  145. // Allocate new instance
  146. pInstance = (struct InstanceStruct *)MemAlloc(sizeof(*pInstance));
  147. if (pInstance == NULL)
  148. {
  149. H245TRACE(dwPhysId,1,"InstanceCreate -> Instance malloc failed");
  150. return NULL;
  151. }
  152. // Make sure no one is trying to simultaneously add same physical Id
  153. // (I know this is a stretch...)
  154. EnterCriticalSection(&InstanceCreateLock);
  155. // Check if instance corresponding to dwPhysId already exists
  156. uIndex = uFirst; // Hash start index into table
  157. do
  158. {
  159. // Avoid entering critical section for unused instances
  160. if (InstanceTable[uIndex])
  161. {
  162. EnterCriticalSection(&InstanceLocks[uIndex]);
  163. if (InstanceTable[uIndex] && InstanceTable[uIndex]->dwPhysId == dwPhysId)
  164. {
  165. LeaveCriticalSection(&InstanceLocks[uIndex]);
  166. LeaveCriticalSection(&InstanceCreateLock);
  167. MemFree(pInstance);
  168. H245TRACE(dwPhysId,1,"InstanceCreate -> Physical Id already in use");
  169. return NULL;
  170. }
  171. LeaveCriticalSection(&InstanceLocks[uIndex]);
  172. }
  173. uIndex = (uIndex + 1) % MAXINST;
  174. } while (uIndex != uFirst);
  175. // Find empty slot for new instance
  176. uIndex = uFirst; // Hash start index into table
  177. do
  178. {
  179. // Avoid entering critical section for used instances
  180. if (InstanceTable[uIndex] == NULL)
  181. {
  182. EnterCriticalSection(&InstanceLocks[uIndex]);
  183. if (InstanceTable[uIndex] == NULL)
  184. {
  185. // Initialize new instance
  186. // Once the new instance is added to the instance table,
  187. // we can relinquish the CreateInstanceLock
  188. InstanceTable[uIndex] = pInstance;
  189. LeaveCriticalSection(&InstanceCreateLock);
  190. memset(pInstance, 0, sizeof(*pInstance));
  191. pInstance->dwPhysId = dwPhysId;
  192. pInstance->dwInst = uIndex + 1;
  193. pInstance->LockCount = 1;
  194. /* API Subsystem Initialization */
  195. pInstance->Configuration = Configuration;
  196. lError = api_init(pInstance);
  197. if (lError != H245_ERROR_OK)
  198. {
  199. InstanceTable[uIndex] = NULL;
  200. LeaveCriticalSection(&InstanceLocks[uIndex]);
  201. MemFree(pInstance);
  202. H245TRACE(dwPhysId,1,"InstanceCreate -> api_init failed");
  203. return NULL;
  204. }
  205. /* Send Receive Subsystem Initialization */
  206. lError = sendRcvInit(pInstance);
  207. if (lError != H245_ERROR_OK)
  208. {
  209. api_deinit(pInstance);
  210. InstanceTable[uIndex] = NULL;
  211. LeaveCriticalSection(&InstanceLocks[uIndex]);
  212. MemFree(pInstance);
  213. H245TRACE(dwPhysId,1,"InstanceCreate -> sendRcvInit failed");
  214. return NULL;
  215. }
  216. /* State Machine Subsystem Initialization */
  217. lError = Fsm_init(pInstance);
  218. if (lError != H245_ERROR_OK)
  219. {
  220. sendRcvShutdown(pInstance);
  221. api_deinit(pInstance);
  222. InstanceTable[uIndex] = NULL;
  223. LeaveCriticalSection(&InstanceLocks[uIndex]);
  224. MemFree(pInstance);
  225. H245TRACE(dwPhysId,1,"InstanceCreate -> Fsm_init failed");
  226. return NULL;
  227. }
  228. H245TRACE(pInstance->dwInst,9,"InstanceCreate: ++LockCount=%d", pInstance->LockCount);
  229. return pInstance; // Return locked instance
  230. }
  231. LeaveCriticalSection(&InstanceLocks[uIndex]);
  232. }
  233. uIndex = (uIndex + 1) % MAXINST;
  234. } while (uIndex != uFirst);
  235. LeaveCriticalSection(&InstanceCreateLock);
  236. MemFree(pInstance);
  237. H245TRACE(dwPhysId,1,"InstanceCreate -> Too many instances");
  238. return NULL;
  239. } // InstanceCreate()
  240. struct InstanceStruct *InstanceLock(register H245_INST_T dwInst)
  241. {
  242. if (--dwInst >= MAXINST)
  243. {
  244. H245TRACE(dwInst+1,1,"InstanceLock -> Invalid instance");
  245. return NULL;
  246. }
  247. if (!InstanceTable[dwInst])
  248. {
  249. H245TRACE(dwInst+1,1,"InstanceLock -> Invalid instance");
  250. return NULL;
  251. }
  252. // Lock instance, then see if it still exists
  253. EnterCriticalSection(&InstanceLocks[dwInst]);
  254. if (InstanceTable[dwInst])
  255. {
  256. InstanceTable[dwInst]->LockCount++;
  257. H245TRACE(dwInst+1,9,"InstanceLock: ++LockCount=%d", InstanceTable[dwInst]->LockCount);
  258. return InstanceTable[dwInst]; // Return locked instance
  259. }
  260. LeaveCriticalSection(&InstanceLocks[dwInst]);
  261. H245TRACE(dwInst+1,1,"InstanceLock -> Invalid instance");
  262. return NULL;
  263. } // InstanceLock()
  264. int InstanceUnlock(struct InstanceStruct *pInstance)
  265. {
  266. register H245_INST_T dwInst = pInstance->dwInst - 1;
  267. if (dwInst >= MAXINST || InstanceTable[dwInst] != pInstance)
  268. {
  269. H245TRACE(pInstance->dwInst,1,"InstanceUnlock -> Invalid instance");
  270. return -1;
  271. }
  272. if (pInstance->fDelete && pInstance->LockCount == 1)
  273. {
  274. H245TRACE(pInstance->dwInst,9,"InstanceUnlock: deleting instance");
  275. pInstance->fDelete = FALSE; // InstanceUnlock will be re-entered from H245WS callback!
  276. Fsm_shutdown(pInstance);
  277. sendRcvShutdown(pInstance);
  278. api_deinit(pInstance);
  279. InstanceTable[dwInst] = NULL;
  280. LeaveCriticalSection(&InstanceLocks[dwInst]);
  281. while (pInstance->pTimerList)
  282. {
  283. register TimerList_T *pTimer = pInstance->pTimerList;
  284. pInstance->pTimerList = pTimer->pNext;
  285. H245TRACE(pInstance->dwInst,1,"InstanceUnlock: deleting timer");
  286. MemFree(pTimer);
  287. }
  288. MemFree(pInstance);
  289. }
  290. else
  291. {
  292. pInstance->LockCount--;
  293. H245TRACE(pInstance->dwInst,9,"InstanceUnlock: --LockCount=%d", pInstance->LockCount);
  294. LeaveCriticalSection(&InstanceLocks[dwInst]);
  295. }
  296. return 0;
  297. } // InstanceUnlock()
  298. int InstanceDelete(struct InstanceStruct *pInstance)
  299. {
  300. H245TRACE(pInstance->dwInst,9,"InstanceDelete");
  301. pInstance->fDelete = TRUE;
  302. return InstanceUnlock(pInstance);
  303. } // InstanceDelete()
  304. int InstanceUnlock_ProcessDetach(struct InstanceStruct *pInstance, BOOL fProcessDetach)
  305. {
  306. register H245_INST_T dwInst = pInstance->dwInst - 1;
  307. if (dwInst >= MAXINST || InstanceTable[dwInst] != pInstance)
  308. {
  309. H245TRACE(pInstance->dwInst,1,"InstanceUnlock -> Invalid instance");
  310. return -1;
  311. }
  312. if (pInstance->fDelete && pInstance->LockCount == 1)
  313. {
  314. H245TRACE(pInstance->dwInst,9,"InstanceUnlock: deleting instance");
  315. pInstance->fDelete = FALSE; // InstanceUnlock will be re-entered from H245WS callback!
  316. Fsm_shutdown(pInstance);
  317. //sendRcvShutdown(pInstance);
  318. sendRcvShutdown_ProcessDetach(pInstance,fProcessDetach);
  319. api_deinit(pInstance);
  320. InstanceTable[dwInst] = NULL;
  321. LeaveCriticalSection(&InstanceLocks[dwInst]);
  322. while (pInstance->pTimerList)
  323. {
  324. register TimerList_T *pTimer = pInstance->pTimerList;
  325. pInstance->pTimerList = pTimer->pNext;
  326. H245TRACE(pInstance->dwInst,1,"InstanceUnlock: deleting timer");
  327. MemFree(pTimer);
  328. }
  329. MemFree(pInstance);
  330. }
  331. else
  332. {
  333. pInstance->LockCount--;
  334. H245TRACE(pInstance->dwInst,9,"InstanceUnlock: --LockCount=%d", pInstance->LockCount);
  335. LeaveCriticalSection(&InstanceLocks[dwInst]);
  336. }
  337. return 0;
  338. } // InstanceUnlock_ProcessDetach()
  339. /*****************************************************************************
  340. *
  341. * TYPE: TIMER STUFF
  342. *
  343. *****************************************************************************/
  344. CRITICAL_SECTION TimerLock = {0};
  345. static int TimerInited = 0;
  346. #ifndef _IA_SPOX_
  347. static UINT_PTR H245TimerId;
  348. #endif
  349. /*****************************************************************************
  350. *
  351. * TYPE: Global System
  352. *
  353. * PROCEDURE: H245TimerTick - ticks every 1000ms
  354. *
  355. * DESCRIPTION:
  356. *
  357. * RETURN:
  358. *
  359. *****************************************************************************/
  360. void H245TimerTick (void)
  361. {
  362. DWORD dwTickCount = GetTickCount();
  363. unsigned int uIndex;
  364. register struct InstanceStruct *pInstance;
  365. register TimerList_T *pTimer;
  366. H245TRACE(0,9,"H245TimerTick <-");
  367. if (0 != TimerInited)
  368. {
  369. for (uIndex = 0; uIndex < MAXINST; ++uIndex)
  370. {
  371. // Avoid entering critical section for unused instances
  372. if (InstanceTable[uIndex])
  373. {
  374. pInstance = InstanceLock(uIndex + 1);
  375. if (pInstance)
  376. {
  377. while (pInstance->pTimerList && (pInstance->pTimerList->dwAlarm - dwTickCount) >= 0x80000000)
  378. {
  379. pTimer = pInstance->pTimerList;
  380. pInstance->pTimerList = pTimer->pNext;
  381. EnterCriticalSection(&TimerLock);
  382. if (--TimerInited == 0)
  383. {
  384. #ifdef _IA_SPOX_
  385. H223_RegisterTimerCallBack((H223TIMERCB)NULL);
  386. #else
  387. KillTimer (NULL, H245TimerId);
  388. #endif
  389. }
  390. LeaveCriticalSection(&TimerLock);
  391. if (pTimer->pfnCallBack)
  392. {
  393. // TBD - what if pContext is no longer valid?
  394. (pTimer->pfnCallBack)(pInstance, (DWORD_PTR)pTimer, pTimer->pContext);
  395. }
  396. MemFree (pTimer);
  397. } // while
  398. InstanceUnlock(pInstance);
  399. } // if
  400. } // if
  401. } // for
  402. }
  403. H245TRACE(0,9,"H245TimerTick ->");
  404. } // TimerTick()
  405. /*****************************************************************************
  406. *
  407. * TYPE: Global System
  408. *
  409. * PROCEDURE: H245TimerProc - FOR WINDOWS Ring 3 only
  410. *
  411. * DESCRIPTION:
  412. *
  413. * RETURN:
  414. *
  415. *****************************************************************************/
  416. #ifndef _IA_SPOX_
  417. void CALLBACK H245TimerProc(HWND hwHwnd,
  418. UINT uiMessg,
  419. UINT_PTR idTimer,
  420. DWORD dwTime)
  421. {
  422. if (idTimer == H245TimerId)
  423. H245TimerTick ();
  424. }
  425. #endif
  426. /*****************************************************************************
  427. *
  428. * TYPE: Global System
  429. *
  430. * PROCEDURE: H245StartTimer
  431. *
  432. * DESCRIPTION:
  433. *
  434. * RETURN:
  435. *
  436. *****************************************************************************/
  437. DWORD_PTR H245StartTimer (struct InstanceStruct * pInstance,
  438. void * pContext,
  439. H245TIMERCALLBACK pfnCallBack,
  440. DWORD dwTicks)
  441. {
  442. TimerList_T *pNew;
  443. TimerList_T *pLook;
  444. TimerList_T *pList;
  445. if (!pfnCallBack)
  446. {
  447. H245TRACE(pInstance->dwInst,1,"H245StartTimer: pfnCallBack == NULL");
  448. return 0;
  449. }
  450. pNew = (TimerList_T *)MemAlloc(sizeof(TimerList_T));
  451. if (pNew == NULL)
  452. {
  453. H245TRACE(pInstance->dwInst,1,"H245StartTimer: memory allocation failed");
  454. return 0;
  455. }
  456. pNew->pNext = NULL;
  457. pNew->pContext = pContext;
  458. pNew->pfnCallBack = pfnCallBack;
  459. pNew->dwAlarm = GetTickCount() + dwTicks;
  460. EnterCriticalSection(&TimerLock);
  461. if (++TimerInited == 1)
  462. {
  463. #ifdef _IA_SPOX_
  464. H223_RegisterTimerCallBack((H223TIMERCB)H245TimerTick);
  465. #else
  466. H245TimerId = SetTimer ((HWND)NULL, (UINT)0, (UINT)1000, H245TimerProc);
  467. #endif
  468. }
  469. LeaveCriticalSection(&TimerLock);
  470. /* as you traverse the list.. subtract the delta off the new one */
  471. /* and link it in.. this list is a list of delta's off the time */
  472. /* out that is linked in front of it.. so subtract as you go */
  473. for (pList = NULL, pLook = pInstance->pTimerList;
  474. pLook && (pLook->dwAlarm - pNew->dwAlarm) >= 0x80000000;
  475. pList = pLook, pLook = pLook->pNext);
  476. /* link it in the list */
  477. pNew->pNext = pLook;
  478. if (pList)
  479. {
  480. // Insert new timer after pList and before pLook
  481. pList->pNext = pNew;
  482. }
  483. else
  484. {
  485. // Insert new timer at front of list
  486. pInstance->pTimerList = pNew;
  487. }
  488. return (DWORD_PTR)pNew;
  489. }
  490. /*****************************************************************************
  491. *
  492. * TYPE: Global System
  493. *
  494. * PROCEDURE: H245StopTimer
  495. *
  496. * DESCRIPTION:
  497. *
  498. * RETURN:
  499. *
  500. *****************************************************************************/
  501. DWORD H245StopTimer(struct InstanceStruct *pInstance, DWORD_PTR dwTimerId)
  502. {
  503. TimerList_T *pTimer = (TimerList_T *)dwTimerId;
  504. TimerList_T *pLook;
  505. TimerList_T *pList;
  506. ASSERT(TimerInited != 0);
  507. EnterCriticalSection(&TimerLock);
  508. if (--TimerInited == 0)
  509. {
  510. #ifdef _IA_SPOX_
  511. H223_RegisterTimerCallBack((H223TIMERCB)NULL);
  512. #else
  513. KillTimer (NULL, H245TimerId);
  514. #endif
  515. }
  516. LeaveCriticalSection(&TimerLock);
  517. if (pInstance->pTimerList == NULL)
  518. {
  519. H245TRACE(pInstance->dwInst,1,"H245StopTimer: timer list NULL");
  520. return TRUE;
  521. }
  522. if (pTimer == pInstance->pTimerList)
  523. {
  524. pInstance->pTimerList = pTimer->pNext;
  525. MemFree (pTimer);
  526. return FALSE;
  527. }
  528. pList = pInstance->pTimerList;
  529. pLook = pList->pNext;
  530. while (pLook && pLook != pTimer)
  531. {
  532. pList = pLook;
  533. pLook = pLook->pNext;
  534. }
  535. /* if the timer exists.. */
  536. if (pLook == NULL)
  537. {
  538. H245TRACE(pInstance->dwInst,1,"H245StopTimer: pTimer not in timer list");
  539. return TRUE;
  540. }
  541. pList->pNext = pTimer->pNext;
  542. MemFree (pTimer);
  543. return FALSE;
  544. }
  545. #ifdef _IA_SPOX_
  546. PUBLIC RESULT InitializeCriticalSection(CRITICAL_SECTION * phLock)
  547. {
  548. return OIL_CreateLock(phLock);
  549. }
  550. PUBLIC RESULT EnterCriticalSection(CRITICAL_SECTION * phLock)
  551. {
  552. return OIL_AcquireLock(*phLock);
  553. }
  554. PUBLIC RESULT LeaveCriticalSection(CRITICAL_SECTION * phLock)
  555. {
  556. return OIL_ReleaseLock(*phLock);
  557. }
  558. PUBLIC RESULT DeleteCriticalSection(CRITICAL_SECTION * phLock)
  559. {
  560. return OIL_DeleteLock(*phLock);
  561. }
  562. #endif
  563.