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.

14985 lines
357 KiB

  1. /*++
  2. Copyright (c) 1995-1998 Microsoft Corporation
  3. Module Name:
  4. remotesp.c
  5. Abstract:
  6. This module contains
  7. Author:
  8. Dan Knudson (DanKn) 09-Aug-1995
  9. Revision History:
  10. Notes:
  11. In a nutshell, this service provider connects to tapisrv.exe on remote
  12. pc's via the same rpc interface used by tapi32, and sends the remote
  13. tapisrv's the same kinds of requests (as defined in \dev\server\line.h
  14. & phone.h).
  15. This service provider also acts as an rpc server, receiving async event
  16. notifications from the remote tapisrv's. Remote tapisrv's call our
  17. RemoteSPAttach() function at init time (during our call to their
  18. ClientAttach() proc) to establish a binding instance, and then can call
  19. RemoteSPEventProc() to send async events. Since we don't want to block
  20. the servers for any length of time, we immediately queue the events they
  21. send us, and a dedicated thread (EventHandlerThread) services this
  22. queue.
  23. Now a brief note on handle resolution. When we open a line or a phone,
  24. we alloc our own DRVXXX structure to represent this widget, and pass
  25. tapisrv a pointer to this widget in the open request (see the
  26. hRemoteLine field in LINEOPEN_PARAMS in line.h). Then, when remote
  27. tapisrv's send us events on those lines/phones, they pass us the
  28. widget pointer we passed them (instead of the normal hLine/hPhone).
  29. This allows us to easily find and reference our data structure
  30. associated with this widget. Dealing with calls is a little more
  31. problematic, since remote tapisrv's can present incoming calls, and
  32. there is no clean way to initially specify our own handle to the call
  33. as with lines or phones. (A RemoteSPNewCall() function which would
  34. allow for this handle swapping was considered, but not implemented due
  35. to possible blocking problems on the remote server.) The solution
  36. is to maintain a list of calls in each line structure, and when call
  37. events are parsed we resolve the hCall by walking the list of calls in
  38. the corresponding line (tapisrv is nice enough to indicate our line
  39. pointer in dwParam4 of the relevant messages). Since we expect client
  40. machines using remotesp to have a relatively low call bandwidth, this
  41. look up method should be pretty fast.
  42. --*/
  43. #include <tchar.h>
  44. #include "remotesp.h"
  45. #include "imperson.h"
  46. #include "rmotsp.h"
  47. #include "dslookup.h"
  48. #include "tapihndl.h"
  49. #include "shlwapi.h"
  50. #include "utils.h"
  51. // defined in server\private.h
  52. #define TAPIERR_INVALRPCCONTEXT 0xF101
  53. #if DBG
  54. BOOL gfBreakOnSeriousProblems = FALSE;
  55. #define DrvAlloc(x) RSPAlloc(x, __LINE__, __FILE__)
  56. #else
  57. #define DrvAlloc(x) RSPAlloc(x)
  58. #endif
  59. #define MODULE_NAME "remotesp.tsp"
  60. typedef struct _ASYNCEVENTMSGRSP
  61. {
  62. DWORD TotalSize;
  63. DWORD InitContext;
  64. ULONG_PTR fnPostProcessProcHandle;
  65. DWORD hDevice;
  66. DWORD Msg;
  67. DWORD OpenContext;
  68. union {
  69. ULONG_PTR Param1;
  70. };
  71. union {
  72. ULONG_PTR Param2;
  73. };
  74. union {
  75. ULONG_PTR Param3;
  76. };
  77. union {
  78. ULONG_PTR Param4;
  79. };
  80. } ASYNCEVENTMSGRSP, *PASYNCEVENTMSGRSP;
  81. HANDLE ghRSPHeap, ghHandleTable;
  82. LIST_ENTRY gTlsListHead;
  83. #undef DWORD_CAST
  84. #if DBG
  85. #define DWORD_CAST(v,f,l) (((v)>MAXDWORD)?(DbgPrt(0,"DWORD_CAST: information will be lost during cast from %p in file %s, line %d",(v),(f),(l)), DebugBreak(),((DWORD)(v))):((DWORD)(v)))
  86. #define DWORD_CAST_HINT(v,f,l,h) (((v)>MAXDWORD)?(DbgPrt(0,"DWORD_CAST: information will be lost during cast from %p in file %s, line %d, hint %d",(v),(f),(l),(h)), DebugBreak(),((DWORD)(v))):((DWORD)(v)))
  87. #else
  88. #define DWORD_CAST(v,f,l) ((DWORD)(v))
  89. #define DWORD_CAST_HINT(v,f,l,h) ((DWORD)(v))
  90. #endif
  91. VOID
  92. CALLBACK
  93. FreeContextCallback(
  94. LPVOID Context,
  95. LPVOID Context2
  96. )
  97. {
  98. if (Context2 == (LPVOID) 1)
  99. {
  100. //
  101. // Special case: don't free the Context
  102. //
  103. }
  104. else if (Context != (LPVOID) -1)
  105. {
  106. //
  107. // The general case, Context is the pointer to free
  108. //
  109. DrvFree (Context);
  110. }
  111. }
  112. BOOL
  113. WINAPI
  114. DllMain(
  115. HANDLE hDLL,
  116. DWORD dwReason,
  117. LPVOID lpReserved
  118. )
  119. {
  120. switch (dwReason)
  121. {
  122. case DLL_PROCESS_ATTACH:
  123. {
  124. gpStaleInitContexts = NULL;
  125. gdwNumStaleInitContexts = 0;
  126. #if DBG
  127. {
  128. HKEY hTelephonyKey;
  129. DWORD dwDataSize, dwDataType;
  130. TCHAR szRemotespDebugLevel[] = "RemotespDebugLevel";
  131. RegOpenKeyEx(
  132. HKEY_LOCAL_MACHINE,
  133. gszTelephonyKey,
  134. 0,
  135. KEY_ALL_ACCESS,
  136. &hTelephonyKey
  137. );
  138. dwDataSize = sizeof (DWORD);
  139. gdwDebugLevel=0;
  140. RegQueryValueEx(
  141. hTelephonyKey,
  142. szRemotespDebugLevel,
  143. 0,
  144. &dwDataType,
  145. (LPBYTE) &gdwDebugLevel,
  146. &dwDataSize
  147. );
  148. RegCloseKey (hTelephonyKey);
  149. }
  150. #endif
  151. //
  152. //
  153. //
  154. LOG((TL_INFO, "DLL_PROCESS_ATTACH"));
  155. ghInst = hDLL;
  156. //
  157. // Allocate a private heap (use process heap if that fails)
  158. //
  159. if (!(ghRSPHeap = HeapCreate(
  160. 0, // return NULL on failure, serialize access
  161. 0x1000, // initial heap size
  162. 0 // max heap size (0 == growable)
  163. )))
  164. {
  165. ghRSPHeap = GetProcessHeap();
  166. }
  167. //
  168. //
  169. //
  170. if (!(ghHandleTable = CreateHandleTable(
  171. ghRSPHeap,
  172. FreeContextCallback,
  173. 0x10000000,
  174. 0x7fffffff
  175. )))
  176. {
  177. LOG((TL_ERROR, "DLL_PROCESS_ATTACH, CreateHandleTable() failed"));
  178. return FALSE;
  179. }
  180. //
  181. // Alloc a Tls index
  182. //
  183. if ((gdwTlsIndex = TlsAlloc()) == 0xffffffff)
  184. {
  185. LOG((TL_ERROR, "DLL_PROCESS_ATTACH, TlsAlloc() failed"));
  186. return FALSE;
  187. }
  188. //
  189. // Initialize Tls to NULL for this thread
  190. //
  191. TlsSetValue (gdwTlsIndex, NULL);
  192. //
  193. // Init a couple of critical sections for serializing
  194. // access to resources
  195. //
  196. InitializeCriticalSection (&gEventBufferCriticalSection);
  197. InitializeCriticalSection (&gCallListCriticalSection);
  198. InitializeCriticalSection (&gcsTlsList);
  199. TapiInitializeCriticalSectionAndSpinCount (&gCriticalSection, 100);
  200. InitializeListHead (&gTlsListHead);
  201. //
  202. // Load the device icons
  203. //
  204. {
  205. HINSTANCE hUser;
  206. typedef HICON ( WINAPI PLOADICON(
  207. HINSTANCE hInstance,
  208. LPCTSTR lpIconName
  209. ));
  210. PLOADICON *pLoadIcon;
  211. hUser = LoadLibrary( "USER32.DLL" );
  212. if ( NULL == hUser )
  213. {
  214. LOG((TL_ERROR, "Couldn't load USER32.DLL!!"));
  215. break;
  216. }
  217. pLoadIcon = (PLOADICON *)GetProcAddress( hUser, "LoadIconA");
  218. if ( NULL == pLoadIcon )
  219. {
  220. LOG((TL_ERROR, "Couldn't load LoadIconA()!!"));
  221. FreeLibrary( hUser );
  222. break;
  223. }
  224. ghLineIcon = pLoadIcon( hDLL, MAKEINTRESOURCE(IDI_ICON3) );
  225. ghPhoneIcon = pLoadIcon( hDLL, MAKEINTRESOURCE(IDI_ICON2) );
  226. FreeLibrary( hUser );
  227. }
  228. break;
  229. }
  230. case DLL_PROCESS_DETACH:
  231. {
  232. PRSP_THREAD_INFO pTls;
  233. LOG((TL_INFO, "DLL_PROCESS_DETACH"));
  234. //
  235. // Clean up any Tls (no need to enter crit sec since process detaching)
  236. //
  237. while (!IsListEmpty (&gTlsListHead))
  238. {
  239. LIST_ENTRY *pEntry = RemoveHeadList (&gTlsListHead);
  240. pTls = CONTAINING_RECORD (pEntry, RSP_THREAD_INFO, TlsList);
  241. DrvFree (pTls->pBuf);
  242. DrvFree (pTls);
  243. }
  244. TlsFree (gdwTlsIndex);
  245. //
  246. // Free the critical sections & icons
  247. //
  248. DeleteCriticalSection (&gEventBufferCriticalSection);
  249. DeleteCriticalSection (&gCallListCriticalSection);
  250. DeleteCriticalSection (&gcsTlsList);
  251. TapiDeleteCriticalSection (&gCriticalSection);
  252. {
  253. HINSTANCE hUser;
  254. typedef BOOL ( WINAPI PDESTROYICON(
  255. HICON hIcon
  256. ));
  257. PDESTROYICON *pDestroyIcon;
  258. hUser = LoadLibrary( "USER32.DLL" );
  259. if ( NULL == hUser )
  260. {
  261. LOG((TL_ERROR, "Couldn't load USER32.DLL!!d"));
  262. break;
  263. }
  264. pDestroyIcon = (PDESTROYICON *)GetProcAddress( hUser, "DestroyIcon");
  265. if ( NULL == pDestroyIcon )
  266. {
  267. LOG((TL_ERROR, "Couldn't load DestroyIcon()!!"));
  268. FreeLibrary( hUser );
  269. break;
  270. }
  271. pDestroyIcon (ghLineIcon);
  272. pDestroyIcon (ghPhoneIcon);
  273. FreeLibrary( hUser );
  274. }
  275. DeleteHandleTable (ghHandleTable);
  276. if (ghRSPHeap != GetProcessHeap())
  277. {
  278. HeapDestroy (ghRSPHeap);
  279. }
  280. break;
  281. }
  282. case DLL_THREAD_ATTACH:
  283. //
  284. // Initialize Tls to NULL for this thread
  285. //
  286. TlsSetValue (gdwTlsIndex, NULL);
  287. break;
  288. case DLL_THREAD_DETACH:
  289. {
  290. PRSP_THREAD_INFO pTls;
  291. //
  292. // Clean up any Tls
  293. //
  294. if ((pTls = (PRSP_THREAD_INFO) TlsGetValue (gdwTlsIndex)))
  295. {
  296. EnterCriticalSection (&gcsTlsList);
  297. RemoveEntryList (&pTls->TlsList);
  298. LeaveCriticalSection (&gcsTlsList);
  299. if (pTls->pBuf)
  300. {
  301. DrvFree (pTls->pBuf);
  302. }
  303. DrvFree (pTls);
  304. }
  305. break;
  306. }
  307. } // switch
  308. return TRUE;
  309. }
  310. BOOL
  311. PASCAL
  312. IsValidObject(
  313. PVOID pObject,
  314. DWORD dwKey
  315. )
  316. {
  317. BOOL fResult;
  318. try
  319. {
  320. fResult = (*((LPDWORD) pObject) == dwKey);
  321. }
  322. except (EXCEPTION_EXECUTE_HANDLER)
  323. {
  324. fResult = FALSE;
  325. }
  326. return fResult;
  327. }
  328. void LogRemoteSPError(CHAR * szServer, DWORD dwErrorContext,
  329. DWORD dwErrorCode, DWORD dwErrorDet,
  330. BOOL bNoKeyCreation)
  331. {
  332. HKEY hKeyServer = NULL;
  333. DWORD dwDisposition;
  334. CHAR szRegKeyServer[255];
  335. if (!szServer)
  336. {
  337. goto ExitHere;
  338. }
  339. wsprintf(szRegKeyServer, "%s\\Provider%d\\",
  340. gszTelephonyKey, gdwPermanentProviderID);
  341. lstrcat(szRegKeyServer, szServer);
  342. if (bNoKeyCreation)
  343. {
  344. // If the logging is requested from NetworkPollThread
  345. // do not create ProviderN key if not exist already
  346. if (ERROR_SUCCESS != RegOpenKeyEx (
  347. HKEY_LOCAL_MACHINE,
  348. szRegKeyServer,
  349. 0,
  350. KEY_WRITE,
  351. &hKeyServer
  352. ))
  353. {
  354. goto ExitHere;
  355. }
  356. }
  357. else
  358. {
  359. if (ERROR_SUCCESS != RegCreateKeyEx(
  360. HKEY_LOCAL_MACHINE,
  361. szRegKeyServer,
  362. 0,
  363. NULL,
  364. REG_OPTION_NON_VOLATILE,
  365. KEY_WRITE,
  366. NULL,
  367. &hKeyServer,
  368. &dwDisposition))
  369. {
  370. goto ExitHere;
  371. }
  372. }
  373. RegSetValueExW (hKeyServer,
  374. L"ErrorContext",
  375. 0,
  376. REG_DWORD,
  377. (LPBYTE)&dwErrorContext,
  378. sizeof(dwErrorContext));
  379. RegSetValueExW (hKeyServer,
  380. L"ErrorCode",
  381. 0,
  382. REG_DWORD,
  383. (LPBYTE)&dwErrorCode,
  384. sizeof(dwErrorCode));
  385. RegSetValueExW (hKeyServer,
  386. L"ErrorDetail",
  387. 0,
  388. REG_DWORD,
  389. (LPBYTE)&dwErrorDet,
  390. sizeof(dwErrorCode));
  391. ExitHere:
  392. if (hKeyServer)
  393. {
  394. RegCloseKey(hKeyServer);
  395. }
  396. return;
  397. }
  398. //
  399. // Function get called when the remotesp lost connection with the
  400. // remote server and the status is detected
  401. //
  402. LONG
  403. OnServerDisconnected(PDRVSERVER pServer)
  404. {
  405. LONG lResult = 0;
  406. TapiEnterCriticalSection(&gCriticalSection);
  407. if ( gEventHandlerThreadParams.bExit )
  408. {
  409. goto ExitHere;
  410. }
  411. //
  412. // It is possible we come here durning FinishEnumDevices
  413. // in which case pServer is not in any double link list
  414. //
  415. if (pServer->ServerList.Flink == NULL ||
  416. pServer->ServerList.Blink == NULL)
  417. {
  418. goto ExitHere;
  419. }
  420. //
  421. // Bail if not transiting from connected to disconnected state
  422. // otherwise set the disconnection flag
  423. //
  424. if (pServer->dwFlags & SERVER_DISCONNECTED)
  425. {
  426. goto ExitHere;
  427. }
  428. pServer->dwFlags |= SERVER_DISCONNECTED;
  429. TapiLeaveCriticalSection (&gCriticalSection);
  430. //
  431. // Leave Shutdown() outside of the CS to avoid deadlock
  432. //
  433. Shutdown (pServer);
  434. TapiEnterCriticalSection(&gCriticalSection);
  435. if ( gEventHandlerThreadParams.bExit )
  436. {
  437. goto ExitHere;
  438. }
  439. //
  440. // Put this server into the gNptListHead so that the
  441. // NetworkPollThread will try to re-establish the connection
  442. //
  443. RemoveEntryList (&pServer->ServerList);
  444. InsertTailList (&gNptListHead, &pServer->ServerList);
  445. //
  446. // Start the NetworkPollThread if not started yet
  447. //
  448. if (ghNetworkPollThread == NULL)
  449. {
  450. DWORD dwTID;
  451. ghNptShutdownEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  452. if (!(ghNetworkPollThread = CreateThread(
  453. NULL,
  454. 0,
  455. (LPTHREAD_START_ROUTINE) NetworkPollThread,
  456. (LPVOID) gpszThingToPassToServer,
  457. 0,
  458. &dwTID
  459. )))
  460. {
  461. LOG((TL_ERROR, "OnServerDisconnected: Unable to create poll thread! Argh!"));
  462. CloseHandle (ghNptShutdownEvent);
  463. while (!IsListEmpty (&gNptListHead))
  464. {
  465. LIST_ENTRY *pEntry = RemoveHeadList (&gNptListHead);
  466. DrvFree(
  467. CONTAINING_RECORD (pEntry, DRVSERVER, ServerList)
  468. );
  469. }
  470. }
  471. }
  472. ExitHere:
  473. TapiLeaveCriticalSection (&gCriticalSection);
  474. return lResult;
  475. }
  476. //
  477. // Function get called when remotesp is able to re-establis the
  478. // connection with the remote server after losing it
  479. //
  480. LONG
  481. OnServerConnected(PDRVSERVER pServer)
  482. {
  483. LONG lResult = 0;
  484. //
  485. // Clear the disconnection bit
  486. //
  487. TapiEnterCriticalSection(&gCriticalSection);
  488. pServer->dwFlags &= (~SERVER_DISCONNECTED);
  489. pServer->bShutdown = FALSE;
  490. TapiLeaveCriticalSection(&gCriticalSection);
  491. return lResult;
  492. }
  493. PASYNCEVENTMSG
  494. GetEventFromQueue(
  495. )
  496. {
  497. BOOL bAllocFailed = FALSE;
  498. DWORD dwMsgSize, dwUsedSize, dwMoveSize, dwMoveSizeReal,
  499. dwMoveSizeWrapped, dwMoveSizeWrappedReal;
  500. PASYNCEVENTMSG pMsg;
  501. //
  502. // Enter the critical section to serialize access to the event
  503. // queue, and grab an event from the queue. Copy it to our local
  504. // event buf so that we can leave the critical section asap and
  505. // not block other threads writing to the queue.
  506. //
  507. EnterCriticalSection (&gEventBufferCriticalSection);
  508. //
  509. // If there are no events in the queue return NULL
  510. //
  511. if (gEventHandlerThreadParams.dwEventBufferUsedSize == 0)
  512. {
  513. GetEventFromQueue_noEvents:
  514. pMsg = NULL;
  515. //
  516. // Take this opportunity to tidy up a bit. The reasoning for doing
  517. // this is that we should be reducing the odds we'll have to wrap
  518. // at the end of the buffer, or at least, put off dealing with such
  519. // things until later (as the non-wrap code executes quickest)
  520. //
  521. gEventHandlerThreadParams.pDataOut =
  522. gEventHandlerThreadParams.pDataIn =
  523. gEventHandlerThreadParams.pEventBuffer;
  524. ResetEvent (gEventHandlerThreadParams.hEvent);
  525. goto GetEventFromQueue_done;
  526. }
  527. //
  528. // Determine the size of this msg & the num bytes to the end of the
  529. // event buffer, then from these get the MoveSize & MoveSizeWrapped
  530. // values
  531. //
  532. dwMsgSize = (DWORD) ((PASYNCEVENTMSG)
  533. gEventHandlerThreadParams.pDataOut)->TotalSize;
  534. if ((dwMsgSize & 0x3) ||
  535. (dwMsgSize > gEventHandlerThreadParams.dwEventBufferTotalSize))
  536. {
  537. //
  538. // Something is corrupt (the msg or our queue), so just nuke
  539. // everything in the queue and bail out
  540. //
  541. LOG((TL_ERROR, "GetEventFromQueue: ERROR! bad msgSize=x%x", dwMsgSize));
  542. gEventHandlerThreadParams.dwEventBufferUsedSize = 0;
  543. goto GetEventFromQueue_noEvents;
  544. }
  545. dwUsedSize = (DWORD) ((gEventHandlerThreadParams.pEventBuffer +
  546. gEventHandlerThreadParams.dwEventBufferTotalSize) -
  547. gEventHandlerThreadParams.pDataOut);
  548. if (dwMsgSize <= dwUsedSize)
  549. {
  550. dwMoveSize = dwMoveSizeReal = dwMsgSize;
  551. dwMoveSizeWrapped = 0;
  552. }
  553. else
  554. {
  555. dwMoveSize = dwMoveSizeReal = dwUsedSize;
  556. dwMoveSizeWrapped = dwMoveSizeWrappedReal = dwMsgSize - dwUsedSize;
  557. }
  558. //
  559. // See if we need to grow the msg buffer before we copy
  560. //
  561. if (dwMsgSize > gEventHandlerThreadParams.dwMsgBufferTotalSize)
  562. {
  563. if ((pMsg = DrvAlloc (dwMsgSize)))
  564. {
  565. DrvFree (gEventHandlerThreadParams.pMsgBuffer);
  566. gEventHandlerThreadParams.pMsgBuffer = (LPBYTE) pMsg;
  567. gEventHandlerThreadParams.dwMsgBufferTotalSize = dwMsgSize;
  568. }
  569. else
  570. {
  571. //
  572. // Couldn't alloc a bigger buf, so try to complete this
  573. // msg as gracefully as possible, i.e. set the XxxReal
  574. // vars so that we'll only actually copy over the fixed
  575. // size of the msg (but the event buf ptrs will still
  576. // get updated correctly) and set a flag to say that
  577. // we need to do some munging on the msg before returning
  578. //
  579. dwMoveSizeReal = (dwMoveSizeReal <= sizeof (ASYNCEVENTMSG) ?
  580. dwMoveSizeReal : sizeof (ASYNCEVENTMSG));
  581. dwMoveSizeWrappedReal = (dwMoveSizeReal < sizeof (ASYNCEVENTMSG) ?
  582. sizeof (ASYNCEVENTMSG) - dwMoveSizeReal : 0);
  583. bAllocFailed = TRUE;
  584. }
  585. }
  586. //
  587. // Copy the msg from the event buf to the msg buf, and update the
  588. // event buf pointers
  589. //
  590. pMsg = (PASYNCEVENTMSG) gEventHandlerThreadParams.pMsgBuffer;
  591. CopyMemory (pMsg, gEventHandlerThreadParams.pDataOut, dwMoveSizeReal);
  592. if (dwMoveSizeWrapped)
  593. {
  594. CopyMemory(
  595. ((LPBYTE) pMsg) + dwMoveSizeReal,
  596. gEventHandlerThreadParams.pEventBuffer,
  597. dwMoveSizeWrappedReal
  598. );
  599. gEventHandlerThreadParams.pDataOut =
  600. gEventHandlerThreadParams.pEventBuffer + dwMoveSizeWrapped;
  601. }
  602. else
  603. {
  604. gEventHandlerThreadParams.pDataOut += dwMoveSize;
  605. //
  606. // If msg ran to end of the event buffer then reset pDataOut
  607. //
  608. if (gEventHandlerThreadParams.pDataOut >=
  609. (gEventHandlerThreadParams.pEventBuffer +
  610. gEventHandlerThreadParams.dwEventBufferTotalSize))
  611. {
  612. gEventHandlerThreadParams.pDataOut =
  613. gEventHandlerThreadParams.pEventBuffer;
  614. }
  615. }
  616. gEventHandlerThreadParams.dwEventBufferUsedSize -= dwMsgSize;
  617. //
  618. // Special msg param munging in case an attempt to grow the
  619. // buffer size above failed
  620. //
  621. if (bAllocFailed)
  622. {
  623. switch (pMsg->Msg)
  624. {
  625. case LINE_REPLY:
  626. pMsg->Param2 = LINEERR_NOMEM;
  627. break;
  628. case PHONE_REPLY:
  629. pMsg->Param2 = PHONEERR_NOMEM;
  630. break;
  631. default:
  632. break;
  633. }
  634. }
  635. GetEventFromQueue_done:
  636. LeaveCriticalSection (&gEventBufferCriticalSection);
  637. return pMsg;
  638. }
  639. BOOL
  640. GetEventsFromServer(
  641. DWORD dwInitContext
  642. )
  643. {
  644. BOOL bResult = FALSE;
  645. DWORD dwUsedSize, dwRetryCount;
  646. PDRVSERVER pServer;
  647. PTAPI32_MSG pMsg;
  648. if (!(pServer = (PDRVSERVER) ReferenceObject(
  649. ghHandleTable,
  650. dwInitContext,
  651. gdwDrvServerKey
  652. )) ||
  653. pServer->bShutdown)
  654. {
  655. LOG((TL_ERROR, "GetEventsFromServer: bad InitContext=x%x", dwInitContext));
  656. if (pServer)
  657. {
  658. DereferenceObject (ghHandleTable, dwInitContext, 1);
  659. }
  660. return FALSE;
  661. }
  662. getEvents:
  663. dwRetryCount = 0;
  664. pMsg = (PTAPI32_MSG) gEventHandlerThreadParams.pMsgBuffer;
  665. do
  666. {
  667. pMsg->u.Req_Func = xGetAsyncEvents;
  668. pMsg->Params[0] = gEventHandlerThreadParams.dwMsgBufferTotalSize -
  669. sizeof (TAPI32_MSG);
  670. dwUsedSize = sizeof (TAPI32_MSG);
  671. RpcTryExcept
  672. {
  673. ClientRequest(
  674. pServer->phContext,
  675. (char *) pMsg,
  676. gEventHandlerThreadParams.dwMsgBufferTotalSize,
  677. &dwUsedSize
  678. );
  679. if (pMsg->u.Ack_ReturnValue == TAPIERR_INVALRPCCONTEXT)
  680. {
  681. OnServerDisconnected (pServer);
  682. pMsg->u.Ack_ReturnValue = LINEERR_OPERATIONFAILED;
  683. }
  684. dwRetryCount = gdwRetryCount;
  685. }
  686. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  687. {
  688. LOG((TL_INFO,
  689. "GetEventsFromServer: rpc exception %d handled",
  690. RpcExceptionCode()
  691. ));
  692. dwRetryCount++;
  693. if (dwRetryCount < gdwRetryCount)
  694. {
  695. Sleep (gdwRetryTimeout);
  696. }
  697. else
  698. {
  699. unsigned long ulResult = RpcExceptionCode();
  700. if ((ulResult == RPC_S_SERVER_UNAVAILABLE) ||
  701. (ulResult == ERROR_INVALID_HANDLE))
  702. {
  703. OnServerDisconnected (pServer);
  704. LOG((TL_ERROR,
  705. "GetEventsFromServer: server '%s' unavailable",
  706. pServer->szServerName
  707. ));
  708. }
  709. pMsg->u.Ack_ReturnValue = LINEERR_OPERATIONFAILED;
  710. }
  711. }
  712. RpcEndExcept
  713. } while (dwRetryCount < gdwRetryCount);
  714. if (pMsg->u.Ack_ReturnValue == 0)
  715. {
  716. DWORD dwNeededSize = (DWORD) pMsg->Params[1],
  717. dwUsedSize = (DWORD) pMsg->Params[2];
  718. if (dwUsedSize)
  719. {
  720. RemoteSPEventProc(
  721. (PCONTEXT_HANDLE_TYPE2) IntToPtr(0xfeedface),
  722. (unsigned char *) (pMsg + 1),
  723. dwUsedSize
  724. );
  725. //
  726. // RemoteSPEventProc will set the byte pointed to by (pMsg+1)
  727. // to non-zero on success, or zero on error (indicating
  728. // bad data in the event buffer, which we'll discard)
  729. //
  730. if (*((unsigned char *) (pMsg + 1)) != 0)
  731. {
  732. bResult = TRUE;
  733. }
  734. else
  735. {
  736. bResult = FALSE;
  737. goto GetEventsFromServer_dereference;
  738. }
  739. }
  740. if (dwNeededSize > dwUsedSize)
  741. {
  742. //
  743. // There's still more data to retrieve on the server.
  744. // Grow the buffer so we can get it all next time.
  745. //
  746. DWORD dwNewSize = dwNeededSize + 256;
  747. LPVOID p;
  748. if ((p = DrvAlloc (dwNewSize)))
  749. {
  750. DrvFree (gEventHandlerThreadParams.pMsgBuffer);
  751. gEventHandlerThreadParams.pMsgBuffer = p;
  752. gEventHandlerThreadParams.dwMsgBufferTotalSize = dwNewSize;
  753. }
  754. else if (dwUsedSize == 0)
  755. {
  756. }
  757. goto getEvents;
  758. }
  759. }
  760. GetEventsFromServer_dereference:
  761. DereferenceObject (ghHandleTable, dwInitContext, 1);
  762. return bResult;
  763. }
  764. void
  765. EventHandlerThread(
  766. LPVOID pParams
  767. )
  768. {
  769. //
  770. // NOTES:
  771. //
  772. // 1. depending on server side implementation, we may experience race
  773. // conditions where msgs that we expect to show up in a certain
  774. // sequence show up out of sequence (i.e. call state msgs that show
  775. // up before make call completion msgs), which could present problems.
  776. //
  777. // one solution is to to queue call state/info msgs to incomplete
  778. // calls (to be sent after call is completed). another is not to send
  779. // any call state msgs after the idle is received
  780. //
  781. DWORD dwMsgSize, dwNumObjects, dwResult, dwData,
  782. dwNumBytesRead, dwTimeout;
  783. HANDLE ahObjects[2];
  784. OVERLAPPED overlapped;
  785. PASYNCEVENTMSG pMsg;
  786. #if MEMPHIS
  787. #else
  788. HANDLE hProcess;
  789. #endif
  790. LOG((TL_INFO, "EventHandlerThread: enter"));
  791. #if MEMPHIS
  792. #else
  793. //
  794. // This thread has no user context, which prevents it from rpc'ing
  795. // back to remote tapisrv when/if necessary. So, find the user
  796. // that is logged on and impersonate them in this thread.
  797. //
  798. if (!GetCurrentlyLoggedOnUser (&hProcess))
  799. {
  800. LOG((TL_ERROR, "GetCurrentlyLoggedOnUser failed"));
  801. }
  802. else
  803. {
  804. if (!SetProcessImpersonationToken(hProcess))
  805. {
  806. LOG((TL_ERROR, "SetProcessImpersonationToken failed"));
  807. }
  808. }
  809. #endif
  810. //
  811. // Bump up the thread priority a bit so we don't get starved by
  812. // ill-behaved apps
  813. //
  814. if (!SetThreadPriority(
  815. GetCurrentThread(),
  816. THREAD_PRIORITY_ABOVE_NORMAL
  817. ))
  818. {
  819. LOG((TL_ERROR,
  820. "EventHandlerThread: SetThreadPriority failed, err=%d",
  821. GetLastError()
  822. ));
  823. }
  824. ahObjects[0] = gEventHandlerThreadParams.hEvent;
  825. if (gEventHandlerThreadParams.hMailslot != INVALID_HANDLE_VALUE)
  826. {
  827. ZeroMemory (&overlapped, sizeof (overlapped));
  828. ahObjects[1] =
  829. overlapped.hEvent = gEventHandlerThreadParams.hMailslotEvent;
  830. dwNumObjects = 2;
  831. if (!ReadFile(
  832. gEventHandlerThreadParams.hMailslot,
  833. &dwData,
  834. sizeof (dwData),
  835. &dwNumBytesRead,
  836. &overlapped
  837. )
  838. && (GetLastError() != ERROR_IO_PENDING))
  839. {
  840. LOG((TL_ERROR,
  841. "EventHandlerThread: ReadFile failed, err=%d",
  842. GetLastError()
  843. ));
  844. }
  845. dwTimeout = MAX_MAILSLOT_TIMEOUT;
  846. }
  847. else
  848. {
  849. dwNumObjects = 1;
  850. dwTimeout = INFINITE;
  851. }
  852. while (1)
  853. {
  854. //
  855. // Wait for an event to show up in the queue or for a msg
  856. // to show up in the mailslot
  857. //
  858. dwResult = WaitForMultipleObjects(
  859. dwNumObjects,
  860. ahObjects,
  861. FALSE,
  862. dwTimeout
  863. );
  864. if (gEventHandlerThreadParams.bExit)
  865. {
  866. break;
  867. }
  868. switch (dwResult)
  869. {
  870. case WAIT_OBJECT_0:
  871. //
  872. // Simply break & process the events
  873. //
  874. break;
  875. case WAIT_OBJECT_0+1:
  876. //
  877. // Post another read, the retrieve & process the events
  878. //
  879. if (!ReadFile(
  880. gEventHandlerThreadParams.hMailslot,
  881. &dwData,
  882. sizeof (dwData),
  883. &dwNumBytesRead,
  884. &overlapped
  885. )
  886. && (GetLastError() != ERROR_IO_PENDING))
  887. {
  888. LOG((TL_ERROR,
  889. "EventHandlerThread: ReadFile failed, err=%d",
  890. GetLastError()
  891. ));
  892. }
  893. if (GetEventsFromServer (dwData))
  894. {
  895. dwTimeout = MIN_MAILSLOT_TIMEOUT;
  896. }
  897. break;
  898. case WAIT_TIMEOUT:
  899. {
  900. #define DWORD_ARRAY_BLOCK_SIZE 128
  901. //
  902. // Check to see if any of the mailslot servers have
  903. // events waiting for us
  904. //
  905. BOOL bGotSomeEvents = FALSE;
  906. PDRVSERVER pServer;
  907. LIST_ENTRY * pEntry;
  908. DWORD * pArray = NULL;
  909. DWORD * pTempArray = NULL;
  910. DWORD dwEntriesCount = 0;
  911. DWORD dwEntriesUsed = 0;
  912. DWORD dwIdx;
  913. BOOL bAddOK;
  914. pArray = (DWORD *) DrvAlloc ( sizeof(DWORD) * DWORD_ARRAY_BLOCK_SIZE );
  915. if ( pArray )
  916. {
  917. dwEntriesCount = DWORD_ARRAY_BLOCK_SIZE;
  918. }
  919. TapiEnterCriticalSection(&gCriticalSection);
  920. for(
  921. pEntry = gpCurrentInitContext->ServerList.Flink;
  922. pEntry != &gpCurrentInitContext->ServerList;
  923. // null op
  924. )
  925. {
  926. PDRVSERVER pServer;
  927. pServer = CONTAINING_RECORD(
  928. pEntry,
  929. DRVSERVER,
  930. ServerList
  931. );
  932. pEntry = pEntry->Flink;
  933. if (!pServer->bConnectionOriented &&
  934. pServer->dwFlags == 0)
  935. {
  936. //
  937. // if possible, store the InitContext and postpone
  938. // the RPC call for after we leave the Crit. Sec.
  939. //
  940. bAddOK = FALSE;
  941. if ( pArray )
  942. {
  943. if ( dwEntriesCount == dwEntriesUsed )
  944. {
  945. //
  946. // need to increase the array size
  947. //
  948. pTempArray = (DWORD *) DrvAlloc (
  949. sizeof(DWORD) * (DWORD_ARRAY_BLOCK_SIZE + dwEntriesCount)
  950. );
  951. if ( pTempArray )
  952. {
  953. bAddOK = TRUE;
  954. CopyMemory(
  955. pTempArray,
  956. pArray,
  957. sizeof(DWORD) * dwEntriesCount
  958. );
  959. dwEntriesCount += DWORD_ARRAY_BLOCK_SIZE;
  960. DrvFree( pArray );
  961. pArray = pTempArray;
  962. }
  963. }
  964. else
  965. {
  966. bAddOK = TRUE;
  967. }
  968. if ( bAddOK )
  969. {
  970. pArray[ dwEntriesUsed++ ] = pServer->InitContext;
  971. }
  972. }
  973. if ( !bAddOK )
  974. {
  975. if (GetEventsFromServer (pServer->InitContext))
  976. {
  977. bGotSomeEvents = TRUE;
  978. }
  979. }
  980. }
  981. }
  982. TapiLeaveCriticalSection(&gCriticalSection);
  983. if ( pArray )
  984. {
  985. for( dwIdx = 0; dwIdx < dwEntriesUsed; dwIdx++ )
  986. {
  987. if (GetEventsFromServer (pArray[ dwIdx ]))
  988. {
  989. bGotSomeEvents = TRUE;
  990. }
  991. }
  992. DrvFree( pArray );
  993. }
  994. if (bGotSomeEvents)
  995. {
  996. dwTimeout = MIN_MAILSLOT_TIMEOUT;
  997. }
  998. else if (dwTimeout < MAX_MAILSLOT_TIMEOUT)
  999. {
  1000. dwTimeout += 500;
  1001. }
  1002. break;
  1003. }
  1004. default:
  1005. //
  1006. // Print a dbg msg & process any available events
  1007. //
  1008. LOG((TL_ERROR,
  1009. "EventHandlerThread: WaitForMultObjs failed, result=%d/err=%d",
  1010. dwResult,
  1011. GetLastError()
  1012. ));
  1013. break;
  1014. }
  1015. //
  1016. // Process the events in the queue
  1017. //
  1018. while ((pMsg = GetEventFromQueue()))
  1019. {
  1020. //
  1021. // First validate the pDrvServer pointer in the msg
  1022. //
  1023. PDRVLINE pLine;
  1024. PDRVPHONE pPhone;
  1025. PDRVSERVER pServer;
  1026. if (!(pServer = ReferenceObject(
  1027. ghHandleTable,
  1028. pMsg->InitContext,
  1029. gdwDrvServerKey
  1030. )))
  1031. {
  1032. LOG((TL_ERROR,
  1033. "EventHandlerThread: bad InitContext=x%x in msg",
  1034. pMsg->InitContext
  1035. ));
  1036. continue;
  1037. }
  1038. switch (pMsg->Msg)
  1039. {
  1040. case LINE_CREATEDIALOGINSTANCE:
  1041. break;
  1042. case LINE_PROXYREQUEST:
  1043. break;
  1044. case LINE_ADDRESSSTATE:
  1045. case LINE_AGENTSTATUS:
  1046. case LINE_AGENTSESSIONSTATUS:
  1047. case LINE_QUEUESTATUS:
  1048. case LINE_AGENTSTATUSEX:
  1049. case LINE_GROUPSTATUS:
  1050. case LINE_PROXYSTATUS:
  1051. if ((pLine = ReferenceObject(
  1052. ghHandleTable,
  1053. pMsg->hDevice,
  1054. DRVLINE_KEY
  1055. )))
  1056. {
  1057. (*gpfnLineEventProc)(
  1058. pLine->htLine,
  1059. 0,
  1060. pMsg->Msg,
  1061. pMsg->Param1,
  1062. pMsg->Param2,
  1063. pMsg->Param3
  1064. );
  1065. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1066. }
  1067. break;
  1068. case LINE_AGENTSPECIFIC:
  1069. {
  1070. DWORD hDeviceCallback = (DWORD) (pMsg->Param4 ?
  1071. pMsg->Param4 : pMsg->hDevice);
  1072. PDRVCALL pCall;
  1073. HTAPICALL htCall;
  1074. if (!(pLine = ReferenceObject(
  1075. ghHandleTable,
  1076. hDeviceCallback,
  1077. DRVLINE_KEY
  1078. )))
  1079. {
  1080. break;
  1081. }
  1082. if (pMsg->Param4)
  1083. {
  1084. EnterCriticalSection (&gCallListCriticalSection);
  1085. pCall = (PDRVCALL) pLine->pCalls;
  1086. while (pCall && (pCall->hCall != (HCALL) pMsg->hDevice))
  1087. {
  1088. pCall = pCall->pNext;
  1089. }
  1090. if (!pCall || pCall->dwKey != DRVCALL_KEY)
  1091. {
  1092. LeaveCriticalSection (&gCallListCriticalSection);
  1093. DereferenceObject (ghHandleTable, hDeviceCallback, 1);
  1094. break;
  1095. }
  1096. htCall = pCall->htCall;
  1097. LeaveCriticalSection (&gCallListCriticalSection);
  1098. }
  1099. else
  1100. {
  1101. htCall = 0;
  1102. }
  1103. (*gpfnLineEventProc)(
  1104. pLine->htLine,
  1105. htCall,
  1106. pMsg->Msg,
  1107. pMsg->Param1,
  1108. pMsg->Param2,
  1109. pMsg->Param3
  1110. );
  1111. DereferenceObject (ghHandleTable, hDeviceCallback, 1);
  1112. break;
  1113. }
  1114. case LINE_CALLINFO:
  1115. case LINE_CALLSTATE:
  1116. case LINE_GENERATE:
  1117. case LINE_MONITORDIGITS:
  1118. case LINE_MONITORMEDIA:
  1119. case LINE_MONITORTONE:
  1120. {
  1121. //
  1122. // For all the msgs where hDevice refers to a call tapisrv
  1123. // will pass us the pLine (hRemoteLine) for that call in
  1124. // dwParam4 to make the lookup of the corresponding pCall
  1125. // easier
  1126. //
  1127. HCALL hCall = (HCALL) pMsg->hDevice;
  1128. PDRVCALL pCall;
  1129. HTAPICALL htCall;
  1130. ASYNCEVENTMSGRSP MsgRsp;
  1131. MsgRsp.TotalSize = pMsg->TotalSize;
  1132. MsgRsp.InitContext = pMsg->InitContext;
  1133. MsgRsp.fnPostProcessProcHandle = pMsg->fnPostProcessProcHandle;
  1134. MsgRsp.hDevice = pMsg->hDevice;
  1135. MsgRsp.Msg = pMsg->Msg;
  1136. MsgRsp.OpenContext = pMsg->OpenContext;
  1137. MsgRsp.Param1 = pMsg->Param1;
  1138. MsgRsp.Param2 = pMsg->Param2;
  1139. MsgRsp.Param3 = pMsg->Param3;
  1140. MsgRsp.Param4 = pMsg->Param4;
  1141. if (!(pLine = ReferenceObject(
  1142. ghHandleTable,
  1143. pMsg->Param4,
  1144. DRVLINE_KEY
  1145. )))
  1146. {
  1147. break;
  1148. }
  1149. EnterCriticalSection (&gCallListCriticalSection);
  1150. pCall = (PDRVCALL) pLine->pCalls;
  1151. while (pCall && (pCall->hCall != hCall))
  1152. {
  1153. pCall = pCall->pNext;
  1154. }
  1155. if (!pCall || pCall->dwKey != DRVCALL_KEY)
  1156. {
  1157. LeaveCriticalSection (&gCallListCriticalSection);
  1158. DereferenceObject (ghHandleTable, pMsg->Param4, 1);
  1159. LOG((TL_ERROR,"EventHandlerThread: Bad hCall(cs) x%lx",hCall));
  1160. break;
  1161. }
  1162. htCall = pCall->htCall;
  1163. #if DBG
  1164. if ( 0 == htCall )
  1165. {
  1166. LOG((TL_ERROR, "htCall is now NULL! pCall=x%lx", pCall));
  1167. }
  1168. #endif
  1169. if ( LINE_CALLINFO == MsgRsp.Msg )
  1170. {
  1171. pCall->dwDirtyStructs |= STRUCTCHANGE_LINECALLINFO;
  1172. if (MsgRsp.Param1 & LINECALLINFOSTATE_DEVSPECIFIC)
  1173. {
  1174. pCall->dwDirtyStructs |= STRUCTCHANGE_LINECALLSTATUS;
  1175. }
  1176. #if MEMPHIS
  1177. #else
  1178. if (MsgRsp.Param1 & (LINECALLINFOSTATE_CALLID |
  1179. LINECALLINFOSTATE_RELATEDCALLID))
  1180. {
  1181. pCall->dwDirtyStructs |= STRUCTCHANGE_CALLIDS;
  1182. }
  1183. #endif
  1184. }
  1185. else if (LINE_CALLSTATE == MsgRsp.Msg )
  1186. {
  1187. pCall->dwDirtyStructs |= STRUCTCHANGE_LINECALLSTATUS;
  1188. //
  1189. // If the state == CONFERENCED then dwParam2 should
  1190. // contain the hConfCall. Note that the real dwParam2
  1191. // actually lives in MsgRsp.pfnPostProcessProc (see note
  1192. // below), so we retrieve it from there and (if non-NULL)
  1193. // try to map it to an htCall, then write the htCall
  1194. // value back to MsgRsp.pfnPostProcessProc.
  1195. //
  1196. if (MsgRsp.Param1 == LINECALLSTATE_CONFERENCED &&
  1197. MsgRsp.fnPostProcessProcHandle)
  1198. {
  1199. HCALL hConfCall = (HCALL) DWORD_CAST(MsgRsp.fnPostProcessProcHandle,__FILE__,__LINE__);
  1200. PDRVCALL pConfCall = (PDRVCALL) pLine->pCalls;
  1201. while (pConfCall && (pConfCall->hCall != hConfCall))
  1202. {
  1203. pConfCall = pConfCall->pNext;
  1204. }
  1205. if (!pConfCall || pConfCall->dwKey != DRVCALL_KEY)
  1206. {
  1207. LOG((TL_ERROR,
  1208. "EventHandlerThread: Bad pConfCall(cs) x%lx",
  1209. pCall
  1210. ));
  1211. MsgRsp.fnPostProcessProcHandle = 0;
  1212. }
  1213. else
  1214. {
  1215. MsgRsp.fnPostProcessProcHandle = (ULONG_PTR)(pConfCall->htCall);
  1216. }
  1217. }
  1218. //
  1219. // HACK ALERT!
  1220. //
  1221. // The remote tapisrv will pass us the call privilege
  1222. // in MsgRsp.dwParam2, and the real dwParam2 (the call
  1223. // state mode) in MsgRsp.pfnPostProcess. For the very
  1224. // 1st CALLSTATE msg for an incoming call we want to
  1225. // indicate the appropriate privilege to the local
  1226. // tapisrv so it knows whether or not it needs to find
  1227. // find a local owner for the call. So, we save the
  1228. // privilege & real dwParam2 in the call struct and
  1229. // pass a pointer to these in dwParam2.
  1230. //
  1231. // For all other cases we set MsgRsp.dwParam2 to the
  1232. // real dwParam2 in MsgRsp.pfnPostProcess.
  1233. //
  1234. if (!pCall->dwInitialPrivilege)
  1235. {
  1236. pCall->dwInitialCallStateMode = MsgRsp.fnPostProcessProcHandle;
  1237. pCall->dwInitialPrivilege = MsgRsp.Param2;
  1238. MsgRsp.Param2 = (ULONG_PTR)
  1239. &pCall->dwInitialCallStateMode;
  1240. }
  1241. else
  1242. {
  1243. MsgRsp.Param2 = MsgRsp.fnPostProcessProcHandle;
  1244. }
  1245. }
  1246. LeaveCriticalSection (&gCallListCriticalSection);
  1247. if (MsgRsp.Msg == LINE_MONITORTONE)
  1248. {
  1249. MsgRsp.Param2 = 0;
  1250. }
  1251. (*gpfnLineEventProc)(
  1252. pLine->htLine,
  1253. htCall,
  1254. MsgRsp.Msg,
  1255. MsgRsp.Param1,
  1256. MsgRsp.Param2,
  1257. MsgRsp.Param3
  1258. );
  1259. DereferenceObject (ghHandleTable, pMsg->Param4, 1);
  1260. break;
  1261. }
  1262. case LINE_DEVSPECIFIC:
  1263. case LINE_DEVSPECIFICFEATURE:
  1264. {
  1265. //
  1266. // For all the msgs where hDevice refers to a call tapisrv
  1267. // will pass us the pLine (hRemoteLine) for that call in
  1268. // dwParam4 to make the lookup of the corresponding pCall
  1269. // easier
  1270. //
  1271. HTAPICALL htCall;
  1272. DWORD hDeviceCallback = (DWORD) (pMsg->Param4 ?
  1273. pMsg->Param4 : pMsg->hDevice);
  1274. if (!(pLine = ReferenceObject(
  1275. ghHandleTable,
  1276. hDeviceCallback,
  1277. DRVLINE_KEY
  1278. )))
  1279. {
  1280. break;
  1281. }
  1282. if (pMsg->Param4)
  1283. {
  1284. HCALL hCall = (HCALL) pMsg->hDevice;
  1285. PDRVCALL pCall;
  1286. EnterCriticalSection (&gCallListCriticalSection);
  1287. pCall = (PDRVCALL) pLine->pCalls;
  1288. while (pCall && (pCall->hCall != hCall))
  1289. {
  1290. pCall = pCall->pNext;
  1291. }
  1292. if (pCall)
  1293. {
  1294. if (pCall->dwKey != DRVCALL_KEY)
  1295. {
  1296. LeaveCriticalSection (&gCallListCriticalSection);
  1297. LOG((TL_ERROR,
  1298. "EventHandlerThread: Bad pCall(ds) x%lx",
  1299. pCall
  1300. ));
  1301. goto LINE_DEVSPECIFIC_dereference;
  1302. }
  1303. htCall = pCall->htCall;
  1304. LeaveCriticalSection (&gCallListCriticalSection);
  1305. pMsg->Msg = (pMsg->Msg == LINE_DEVSPECIFIC ?
  1306. LINE_CALLDEVSPECIFIC :
  1307. LINE_CALLDEVSPECIFICFEATURE);
  1308. }
  1309. else
  1310. {
  1311. LeaveCriticalSection (&gCallListCriticalSection);
  1312. goto LINE_DEVSPECIFIC_dereference;
  1313. }
  1314. }
  1315. else
  1316. {
  1317. htCall = 0;
  1318. }
  1319. (*gpfnLineEventProc)(
  1320. pLine->htLine,
  1321. htCall,
  1322. pMsg->Msg,
  1323. pMsg->Param1,
  1324. pMsg->Param2,
  1325. pMsg->Param3
  1326. );
  1327. LINE_DEVSPECIFIC_dereference:
  1328. DereferenceObject (ghHandleTable, hDeviceCallback, 1);
  1329. break;
  1330. }
  1331. case PHONE_BUTTON:
  1332. case PHONE_DEVSPECIFIC:
  1333. if ((pPhone = ReferenceObject(
  1334. ghHandleTable,
  1335. pMsg->hDevice,
  1336. DRVPHONE_KEY
  1337. )))
  1338. {
  1339. (*gpfnPhoneEventProc)(
  1340. pPhone->htPhone,
  1341. pMsg->Msg,
  1342. pMsg->Param1,
  1343. pMsg->Param2,
  1344. pMsg->Param3
  1345. );
  1346. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1347. }
  1348. break;
  1349. case LINE_LINEDEVSTATE:
  1350. if (pMsg->Param1 & LINEDEVSTATE_REINIT)
  1351. {
  1352. //
  1353. // Be on our best behavior and immediately shutdown
  1354. // our init instances on the server
  1355. //
  1356. if (pMsg->InitContext)
  1357. {
  1358. //
  1359. // In the case of TAPISRV shutdown, server sends
  1360. // LINEDEVSTATE_REINIT, then waits for everybody to
  1361. // finish, we do not want to retry the connection until
  1362. // it indeed stopped, so we insert a wait
  1363. //
  1364. Sleep (8000);
  1365. OnServerDisconnected(pServer);
  1366. break;
  1367. }
  1368. pMsg->hDevice = 0;
  1369. /*
  1370. if (pMsg->Param2 == RSP_MSG)
  1371. {
  1372. //
  1373. // This is a message from TAPISRV indicating that this
  1374. // client need to reinit. RemoteSP doesn't need to do
  1375. // it's shut down, but should notify client tapisrv
  1376. // that it needs to reinit.
  1377. }
  1378. else
  1379. {
  1380. Shutdown (pServer);
  1381. }
  1382. */
  1383. }
  1384. if (pMsg->Param1 & LINEDEVSTATE_TRANSLATECHANGE)
  1385. {
  1386. // we shouldn't send this up to tapisrv, since this
  1387. // means that the translatecaps have changed on the
  1388. // server. just ignore this message
  1389. break;
  1390. }
  1391. if (pMsg->hDevice)
  1392. {
  1393. if (!(pLine = ReferenceObject(
  1394. ghHandleTable,
  1395. pMsg->hDevice,
  1396. DRVLINE_KEY
  1397. )))
  1398. {
  1399. break;
  1400. }
  1401. }
  1402. (*gpfnLineEventProc)(
  1403. pMsg->hDevice ? pLine->htLine : 0,
  1404. 0,
  1405. pMsg->Msg,
  1406. pMsg->Param1,
  1407. pMsg->Param2,
  1408. pMsg->Param3
  1409. );
  1410. if (pMsg->hDevice)
  1411. {
  1412. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1413. }
  1414. break;
  1415. case PHONE_STATE:
  1416. if (pMsg->Param1 & PHONESTATE_REINIT)
  1417. {
  1418. //
  1419. // Be on our best behavior and immediately shutdown
  1420. // our init instances on the server
  1421. //
  1422. if (pMsg->InitContext)
  1423. {
  1424. //
  1425. // In the case of TAPISRV shutdown, server sends
  1426. // LINEDEVSTATE_REINIT, then waits for everybody to
  1427. // finish, we do not want to retry the connection until
  1428. // it indeed stopped, so we insert a wait
  1429. //
  1430. Sleep (8000);
  1431. OnServerDisconnected(pServer);
  1432. break;
  1433. }
  1434. pMsg->hDevice = 0;
  1435. }
  1436. if (pMsg->hDevice)
  1437. {
  1438. if (!(pPhone = ReferenceObject(
  1439. ghHandleTable,
  1440. pMsg->hDevice,
  1441. DRVPHONE_KEY
  1442. )))
  1443. {
  1444. break;
  1445. }
  1446. }
  1447. (*gpfnPhoneEventProc)(
  1448. pMsg->hDevice ? pPhone->htPhone : 0,
  1449. pMsg->Msg,
  1450. pMsg->Param1,
  1451. pMsg->Param2,
  1452. pMsg->Param3
  1453. );
  1454. if (pMsg->hDevice)
  1455. {
  1456. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1457. }
  1458. break;
  1459. case LINE_CLOSE:
  1460. {
  1461. PDRVCALL pCall;
  1462. if ((pLine = ReferenceObject(
  1463. ghHandleTable,
  1464. pMsg->hDevice,
  1465. DRVLINE_KEY
  1466. )))
  1467. {
  1468. //
  1469. // Nullify the hLine field so that when TSPI_Close
  1470. // is called we know not to call the server
  1471. //
  1472. pLine->hLine = 0;
  1473. //
  1474. // Safely walk the call list for this line & nullify
  1475. // each call's hCall field so that when TSPI_CloseCall
  1476. // is called we know not to call the server
  1477. //
  1478. EnterCriticalSection (&gCallListCriticalSection);
  1479. pCall = pLine->pCalls;
  1480. while (pCall)
  1481. {
  1482. if (pCall->dwKey != DRVCALL_KEY)
  1483. {
  1484. LOG((TL_ERROR,
  1485. "EventHandlerThread: Bad pCall(lc) x%lx",
  1486. pCall
  1487. ));
  1488. continue;
  1489. }
  1490. pCall->hCall = 0;
  1491. pCall = pCall->pNext;
  1492. }
  1493. LeaveCriticalSection (&gCallListCriticalSection);
  1494. (*gpfnLineEventProc)(
  1495. pLine->htLine,
  1496. 0,
  1497. LINE_CLOSE,
  1498. 0,
  1499. 0,
  1500. 0
  1501. );
  1502. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1503. }
  1504. break;
  1505. }
  1506. case PHONE_CLOSE:
  1507. {
  1508. if ((pPhone = ReferenceObject(
  1509. ghHandleTable,
  1510. pMsg->hDevice,
  1511. DRVPHONE_KEY
  1512. )))
  1513. {
  1514. //
  1515. // Nullify the hPhone field so that when TSPI_Close
  1516. // is called we know not to call the server
  1517. //
  1518. pPhone->hPhone = 0;
  1519. (*gpfnPhoneEventProc)(
  1520. pPhone->htPhone,
  1521. PHONE_CLOSE,
  1522. 0,
  1523. 0,
  1524. 0
  1525. );
  1526. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1527. }
  1528. break;
  1529. }
  1530. case LINE_GATHERDIGITS:
  1531. {
  1532. if (pMsg->TotalSize >= (sizeof (*pMsg) + sizeof (PDRVLINE)))
  1533. {
  1534. DWORD hLineCallback = ((DWORD *)(pMsg + 1))[1];
  1535. HCALL hCall = (HCALL) pMsg->hDevice;
  1536. PDRVCALL pCall;
  1537. HTAPICALL htCall;
  1538. if ((pLine = ReferenceObject(
  1539. ghHandleTable,
  1540. hLineCallback,
  1541. DRVLINE_KEY
  1542. )))
  1543. {
  1544. EnterCriticalSection (&gCallListCriticalSection);
  1545. pCall = (PDRVCALL) pLine->pCalls;
  1546. while (pCall && (pCall->hCall != hCall))
  1547. {
  1548. pCall = pCall->pNext;
  1549. }
  1550. htCall = (pCall ? pCall->htCall : 0);
  1551. if (pCall && pCall->dwKey != DRVCALL_KEY)
  1552. {
  1553. LeaveCriticalSection (&gCallListCriticalSection);
  1554. goto LINE_GATHERDIGITS_dereference;
  1555. }
  1556. LeaveCriticalSection (&gCallListCriticalSection);
  1557. TSPI_lineGatherDigits_PostProcess (pMsg);
  1558. (*gpfnLineEventProc)(
  1559. pLine->htLine,
  1560. htCall,
  1561. LINE_GATHERDIGITS,
  1562. pMsg->Param1,
  1563. pMsg->Param2, // dwEndToEndID
  1564. 0
  1565. );
  1566. LINE_GATHERDIGITS_dereference:
  1567. DereferenceObject (ghHandleTable, hLineCallback, 1);
  1568. }
  1569. }
  1570. break;
  1571. }
  1572. case LINE_REPLY:
  1573. case PHONE_REPLY:
  1574. {
  1575. ULONG_PTR Context2;
  1576. DWORD originalRequestID;
  1577. PASYNCREQUESTCONTEXT pContext;
  1578. if ((pContext = ReferenceObjectEx(
  1579. ghHandleTable,
  1580. pMsg->Param1,
  1581. 0,
  1582. (LPVOID *) &Context2
  1583. )))
  1584. {
  1585. originalRequestID = DWORD_CAST(Context2,__FILE__,__LINE__);
  1586. LOG((TL_INFO,
  1587. "Doing LINE_/PHONE_REPLY: LocID=x%x (RemID=x%x), " \
  1588. "Result=x%x",
  1589. originalRequestID,
  1590. pMsg->Param1,
  1591. pMsg->Param2
  1592. ));
  1593. if (pContext != (PASYNCREQUESTCONTEXT) -1)
  1594. {
  1595. if (pContext->dwKey == DRVASYNC_KEY)
  1596. {
  1597. //
  1598. // Set pContext->dwOriginalRequestID so
  1599. // MakeCallPostProcess &
  1600. // SetupConferencePostProcess can check it
  1601. // againt pCall->dwOriginalRequestID for
  1602. // verification.
  1603. //
  1604. pContext->dwOriginalRequestID = (DWORD)
  1605. originalRequestID;
  1606. (*pContext->pfnPostProcessProc)(
  1607. pMsg,
  1608. pContext
  1609. );
  1610. }
  1611. else
  1612. {
  1613. //
  1614. // Not a valid request id, do a single deref
  1615. // & break
  1616. //
  1617. DereferenceObject (ghHandleTable, pMsg->Param1, 1);
  1618. break;
  1619. }
  1620. }
  1621. (*gpfnCompletionProc)(
  1622. (DRV_REQUESTID) originalRequestID,
  1623. (LONG) pMsg->Param2
  1624. );
  1625. //
  1626. // Double deref to free the object
  1627. //
  1628. DereferenceObject (ghHandleTable, pMsg->Param1, 2);
  1629. }
  1630. break;
  1631. }
  1632. case LINE_CREATE:
  1633. {
  1634. //
  1635. // Check validity of new device ID to thwart RPC attacks.
  1636. // Compare with known/existing device ID's on for this
  1637. // server, and also try to get devCaps for this device
  1638. // from server.
  1639. //
  1640. #define V1_0_LINEDEVCAPS_SIZE 236
  1641. BYTE buf[sizeof (TAPI32_MSG) +
  1642. V1_0_LINEDEVCAPS_SIZE];
  1643. DWORD i, dwRetryCount = 0, dwUsedSize;
  1644. PTAPI32_MSG pReq = (PTAPI32_MSG) buf;
  1645. PDRVLINELOOKUP pLookup;
  1646. TapiEnterCriticalSection(&gCriticalSection);
  1647. pLookup = gpLineLookup;
  1648. while (pLookup)
  1649. {
  1650. for (i = 0; i < pLookup->dwUsedEntries; i++)
  1651. {
  1652. if ((pLookup->aEntries[i].pServer == pServer) &&
  1653. (pLookup->aEntries[i].dwDeviceIDServer ==
  1654. (DWORD) pMsg->Param1))
  1655. {
  1656. //
  1657. // This server/id combo is already in our global
  1658. // table, so blow off this msg
  1659. //
  1660. TapiLeaveCriticalSection(&gCriticalSection);
  1661. goto LINE_CREATE_break;
  1662. }
  1663. }
  1664. pLookup = pLookup->pNext;
  1665. }
  1666. TapiLeaveCriticalSection(&gCriticalSection);
  1667. do
  1668. {
  1669. pReq->u.Req_Func = lGetDevCaps;
  1670. pReq->Params[0] = pServer->hLineApp;
  1671. pReq->Params[1] = pMsg->Param1;
  1672. pReq->Params[2] = TAPI_VERSION1_0;
  1673. pReq->Params[3] = 0;
  1674. pReq->Params[4] = V1_0_LINEDEVCAPS_SIZE;
  1675. dwUsedSize = sizeof (TAPI32_MSG);
  1676. RpcTryExcept
  1677. {
  1678. ClientRequest(
  1679. pServer->phContext,
  1680. (char *) pReq,
  1681. sizeof (buf),
  1682. &dwUsedSize
  1683. );
  1684. dwRetryCount = gdwRetryCount;
  1685. }
  1686. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  1687. {
  1688. dwRetryCount++;
  1689. if (dwRetryCount < gdwRetryCount)
  1690. {
  1691. Sleep (gdwRetryTimeout);
  1692. }
  1693. else
  1694. {
  1695. pReq->u.Ack_ReturnValue = LINEERR_BADDEVICEID;
  1696. }
  1697. }
  1698. RpcEndExcept
  1699. } while (dwRetryCount < gdwRetryCount);
  1700. if ((LONG) pReq->u.Ack_ReturnValue != LINEERR_BADDEVICEID)
  1701. {
  1702. if (AddLine(
  1703. pServer,
  1704. gdwTempLineID,
  1705. (DWORD) pMsg->Param1,
  1706. FALSE,
  1707. FALSE,
  1708. 0,
  1709. NULL
  1710. ) == 0)
  1711. {
  1712. (*gpfnLineEventProc)(
  1713. 0,
  1714. 0,
  1715. LINE_CREATE,
  1716. (ULONG_PTR) ghProvider,
  1717. gdwTempLineID--,
  1718. 0
  1719. );
  1720. }
  1721. }
  1722. LINE_CREATE_break:
  1723. break;
  1724. }
  1725. case LINE_REMOVE:
  1726. {
  1727. PDRVLINELOOKUP pLookup;
  1728. BOOL fValidID = FALSE;
  1729. DWORD dwDeviceID, i;
  1730. TapiEnterCriticalSection(&gCriticalSection);
  1731. pLookup = gpLineLookup;
  1732. while (pLookup)
  1733. {
  1734. for (i = 0; i < pLookup->dwUsedEntries; i++)
  1735. {
  1736. if ((pLookup->aEntries[i].pServer == pServer) &&
  1737. (pLookup->aEntries[i].dwDeviceIDServer ==
  1738. (DWORD) pMsg->Param1))
  1739. {
  1740. //
  1741. // This server/id combo is in our global
  1742. //
  1743. fValidID = TRUE;
  1744. dwDeviceID = pLookup->aEntries[i].dwDeviceIDLocal;
  1745. pLookup->aEntries[i].dwDeviceIDServer = 0xffffffff;
  1746. break;
  1747. }
  1748. }
  1749. if (fValidID)
  1750. {
  1751. break;
  1752. }
  1753. pLookup = pLookup->pNext;
  1754. }
  1755. TapiLeaveCriticalSection(&gCriticalSection);
  1756. if (fValidID)
  1757. {
  1758. (*gpfnLineEventProc)(
  1759. 0,
  1760. 0,
  1761. LINE_REMOVE,
  1762. dwDeviceID,
  1763. 0,
  1764. 0
  1765. );
  1766. }
  1767. }
  1768. break;
  1769. case PHONE_CREATE:
  1770. {
  1771. //
  1772. // Check validity of new device ID to thwart RPC attacks.
  1773. // Compare with known/existing device ID's on for this
  1774. // server, and also try to get devCaps for this device
  1775. // from server.
  1776. //
  1777. #define V1_0_PHONECAPS_SIZE 144
  1778. BYTE buf[sizeof (TAPI32_MSG) + V1_0_PHONECAPS_SIZE];
  1779. DWORD i, dwRetryCount = 0, dwUsedSize;
  1780. PTAPI32_MSG pReq = (PTAPI32_MSG) buf;
  1781. PDRVPHONELOOKUP pLookup;
  1782. TapiEnterCriticalSection(&gCriticalSection);
  1783. pLookup = gpPhoneLookup;
  1784. while (pLookup)
  1785. {
  1786. for (i = 0; i < pLookup->dwUsedEntries; i++)
  1787. {
  1788. if ((pLookup->aEntries[i].pServer == pServer) &&
  1789. (pLookup->aEntries[i].dwDeviceIDServer ==
  1790. (DWORD) pMsg->Param1))
  1791. {
  1792. //
  1793. // This server/id combo is already in our global
  1794. // table, so blow off this msg
  1795. //
  1796. TapiLeaveCriticalSection(&gCriticalSection);
  1797. goto PHONE_CREATE_break;
  1798. }
  1799. }
  1800. pLookup = pLookup->pNext;
  1801. }
  1802. TapiLeaveCriticalSection(&gCriticalSection);
  1803. do
  1804. {
  1805. pReq->u.Req_Func = pGetDevCaps;
  1806. pReq->Params[0] = pServer->hPhoneApp;
  1807. pReq->Params[1] = pMsg->Param1;
  1808. pReq->Params[2] = TAPI_VERSION1_0;
  1809. pReq->Params[3] = 0;
  1810. pReq->Params[4] = V1_0_PHONECAPS_SIZE;
  1811. dwUsedSize = sizeof (TAPI32_MSG);
  1812. RpcTryExcept
  1813. {
  1814. ClientRequest(
  1815. pServer->phContext,
  1816. (char *) pReq,
  1817. sizeof (buf),
  1818. &dwUsedSize
  1819. );
  1820. dwRetryCount = gdwRetryCount;
  1821. }
  1822. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  1823. {
  1824. dwRetryCount++;
  1825. if (dwRetryCount < gdwRetryCount)
  1826. {
  1827. Sleep (gdwRetryTimeout);
  1828. }
  1829. else
  1830. {
  1831. pReq->u.Ack_ReturnValue = PHONEERR_BADDEVICEID;
  1832. }
  1833. }
  1834. RpcEndExcept
  1835. } while (dwRetryCount < gdwRetryCount);
  1836. if ((LONG) pReq->u.Ack_ReturnValue != PHONEERR_BADDEVICEID)
  1837. {
  1838. AddPhone(
  1839. pServer,
  1840. gdwTempPhoneID,
  1841. (DWORD) pMsg->Param1,
  1842. FALSE,
  1843. FALSE,
  1844. 0,
  1845. NULL
  1846. );
  1847. (*gpfnPhoneEventProc)(
  1848. 0,
  1849. PHONE_CREATE,
  1850. (ULONG_PTR) ghProvider,
  1851. gdwTempPhoneID--,
  1852. 0
  1853. );
  1854. }
  1855. PHONE_CREATE_break:
  1856. break;
  1857. }
  1858. case PHONE_REMOVE:
  1859. {
  1860. PDRVPHONELOOKUP pLookup;
  1861. BOOL fValidID = FALSE;
  1862. DWORD dwDeviceID, i;
  1863. TapiEnterCriticalSection(&gCriticalSection);
  1864. pLookup = gpPhoneLookup;
  1865. while (pLookup)
  1866. {
  1867. for (i = 0; i < pLookup->dwUsedEntries; i++)
  1868. {
  1869. if ((pLookup->aEntries[i].pServer == pServer) &&
  1870. (pLookup->aEntries[i].dwDeviceIDServer ==
  1871. (DWORD) pMsg->Param1))
  1872. {
  1873. //
  1874. // This server/id combo is in our global
  1875. //
  1876. fValidID = TRUE;
  1877. dwDeviceID = pLookup->aEntries[i].dwDeviceIDLocal;
  1878. break;
  1879. }
  1880. }
  1881. if (fValidID)
  1882. {
  1883. break;
  1884. }
  1885. pLookup = pLookup->pNext;
  1886. }
  1887. TapiLeaveCriticalSection(&gCriticalSection);
  1888. if (fValidID)
  1889. {
  1890. (*gpfnPhoneEventProc)(
  1891. 0,
  1892. PHONE_REMOVE,
  1893. dwDeviceID,
  1894. 0,
  1895. 0
  1896. );
  1897. }
  1898. }
  1899. break;
  1900. case LINE_APPNEWCALL:
  1901. {
  1902. PDRVCALL pCall;
  1903. HTAPICALL htCall;
  1904. if (!(pLine = ReferenceObject(
  1905. ghHandleTable,
  1906. pMsg->hDevice,
  1907. DRVLINE_KEY
  1908. )))
  1909. {
  1910. break;
  1911. }
  1912. if ((pCall = DrvAlloc (sizeof (DRVCALL))))
  1913. {
  1914. pCall->hCall = (HCALL) pMsg->Param2;
  1915. pCall->dwAddressID = (DWORD) pMsg->Param1;
  1916. #if MEMPHIS
  1917. #else
  1918. if (pMsg->TotalSize >=
  1919. (sizeof (*pMsg) + 2 * sizeof (DWORD)))
  1920. {
  1921. pCall->dwCallID = (DWORD) *(&pMsg->Param4 + 1);
  1922. pCall->dwRelatedCallID = (DWORD) *(&pMsg->Param4 + 2);
  1923. }
  1924. else
  1925. {
  1926. pCall->dwDirtyStructs |= STRUCTCHANGE_CALLIDS;
  1927. pLine->pServer->bVer2xServer = TRUE;
  1928. }
  1929. #endif
  1930. if (pLine->htLine)
  1931. {
  1932. (*gpfnLineEventProc)(
  1933. pLine->htLine,
  1934. 0,
  1935. LINE_NEWCALL,
  1936. (ULONG_PTR) pCall,
  1937. (ULONG_PTR) &(pCall->htCall),
  1938. (ULONG_PTR) 0
  1939. );
  1940. EnterCriticalSection (&gCallListCriticalSection);
  1941. AddCallToList (pLine, pCall);
  1942. htCall = pCall->htCall;
  1943. LeaveCriticalSection (&gCallListCriticalSection);
  1944. if (!htCall)
  1945. {
  1946. //
  1947. // tapi was not able to create it's own instance
  1948. // to represent ths incoming call, perhaps
  1949. // because the line was closed, or out of
  1950. // memory. if the line was closed then we've
  1951. // already notified the remote server, and it
  1952. // should have destroyed the call client.
  1953. // otherwise, we probably want to do a closecall
  1954. // here or in a worker thread
  1955. RemoveCallFromList (pCall);
  1956. }
  1957. }
  1958. else
  1959. {
  1960. DrvFree (pCall);
  1961. }
  1962. }
  1963. else
  1964. {
  1965. }
  1966. DereferenceObject (ghHandleTable, pMsg->hDevice, 1);
  1967. break;
  1968. }
  1969. #if DBG
  1970. default:
  1971. LOG((TL_ERROR,
  1972. "EventHandlerThread: unknown msg=x%x, hDev=x%x, p1=x%x",
  1973. pMsg->Msg,
  1974. pMsg->hDevice,
  1975. pMsg->Param1
  1976. ));
  1977. break;
  1978. #endif
  1979. } // switch (pMsg->dwMsg)
  1980. DereferenceObject (ghHandleTable, pMsg->InitContext, 1);
  1981. } // while ((pMsg = GetEventFromQueue()))
  1982. } // while (1)
  1983. if (gEventHandlerThreadParams.hMailslot != INVALID_HANDLE_VALUE)
  1984. {
  1985. CancelIo (gEventHandlerThreadParams.hMailslot);
  1986. }
  1987. #if MEMPHIS
  1988. #else
  1989. ClearImpersonationToken();
  1990. RevertImpersonation();
  1991. CloseHandle(hProcess);
  1992. #endif
  1993. LOG((TL_INFO, "EventHandlerThread: exit"));
  1994. ExitThread (0);
  1995. }
  1996. PDRVLINE
  1997. GetLineFromID(
  1998. DWORD dwDeviceID
  1999. )
  2000. {
  2001. PDRVLINE pLine;
  2002. //
  2003. // First check to see if it's a valid device ID.
  2004. //
  2005. if (dwDeviceID < gdwLineDeviceIDBase || gpLineLookup == NULL)
  2006. {
  2007. return NULL;
  2008. }
  2009. TapiEnterCriticalSection(&gCriticalSection);
  2010. //
  2011. // First check to see if it's a "static" device, i.e. a device
  2012. // that we knew about at start up time, in which case we know
  2013. // it's exact location in the lookup table
  2014. //
  2015. if (dwDeviceID < (gdwLineDeviceIDBase + gdwInitialNumLineDevices))
  2016. {
  2017. pLine = gpLineLookup->aEntries + dwDeviceID - gdwLineDeviceIDBase;
  2018. }
  2019. //
  2020. // If here, the id references a "dynamic" device, i.e. one that
  2021. // we found out about on the fly via a CREATE msg, so we need to
  2022. // walk the lookup table(s) to find it
  2023. //
  2024. // TODO: the while loops down below are not efficient at all
  2025. //
  2026. else
  2027. {
  2028. PDRVLINELOOKUP pLookup = gpLineLookup;
  2029. DWORD i;
  2030. pLine = NULL;
  2031. while (pLookup)
  2032. {
  2033. i = 0;
  2034. while (i != pLookup->dwUsedEntries &&
  2035. pLookup->aEntries[i].dwDeviceIDLocal != dwDeviceID)
  2036. {
  2037. i++;
  2038. }
  2039. if (i < pLookup->dwUsedEntries)
  2040. {
  2041. pLine = &(pLookup->aEntries[i]);
  2042. break;
  2043. }
  2044. pLookup = pLookup->pNext;
  2045. }
  2046. }
  2047. TapiLeaveCriticalSection(&gCriticalSection);
  2048. return pLine;
  2049. }
  2050. PDRVPHONE
  2051. GetPhoneFromID(
  2052. DWORD dwDeviceID
  2053. )
  2054. {
  2055. PDRVPHONE pPhone;
  2056. //
  2057. // First check to see if it's a valid device ID.
  2058. //
  2059. if (dwDeviceID < gdwPhoneDeviceIDBase || gpPhoneLookup == NULL)
  2060. {
  2061. return NULL;
  2062. }
  2063. TapiEnterCriticalSection(&gCriticalSection);
  2064. //
  2065. // Then check to see if it's a "static" device, i.e. a device
  2066. // that we knew about at start up time, in which case we know
  2067. // it's exact location in the lookup table
  2068. //
  2069. if (dwDeviceID < (gdwPhoneDeviceIDBase + gdwInitialNumPhoneDevices))
  2070. {
  2071. pPhone = gpPhoneLookup->aEntries + dwDeviceID - gdwPhoneDeviceIDBase;
  2072. }
  2073. //
  2074. // If here, the id references a "dynamic" device, i.e. one that
  2075. // we found out about on the fly via a CREATE msg, so we need to
  2076. // walk the lookup table(s) to find it
  2077. //
  2078. // TODO: the while loops down below are not efficient at all
  2079. //
  2080. else
  2081. {
  2082. PDRVPHONELOOKUP pLookup = gpPhoneLookup;
  2083. DWORD i;
  2084. pPhone = NULL;
  2085. while (pLookup)
  2086. {
  2087. i = 0;
  2088. while (i != pLookup->dwUsedEntries &&
  2089. pLookup->aEntries[i].dwDeviceIDLocal != dwDeviceID)
  2090. {
  2091. i++;
  2092. }
  2093. if (i < pLookup->dwUsedEntries)
  2094. {
  2095. pPhone = &(pLookup->aEntries[i]);
  2096. break;
  2097. }
  2098. pLookup = pLookup->pNext;
  2099. }
  2100. }
  2101. TapiLeaveCriticalSection(&gCriticalSection);
  2102. return pPhone;
  2103. }
  2104. BOOL
  2105. WINAPI
  2106. GrowBuf(
  2107. LPBYTE *ppBuf,
  2108. LPDWORD pdwBufSize,
  2109. DWORD dwCurrValidBytes,
  2110. DWORD dwBytesToAdd
  2111. )
  2112. {
  2113. DWORD dwCurrBufSize, dwNewBufSize;
  2114. LPBYTE pNewBuf;
  2115. //
  2116. // Try to get a new buffer big enough to hold everything
  2117. //
  2118. for(
  2119. dwNewBufSize = 2 * (dwCurrBufSize = *pdwBufSize);
  2120. dwNewBufSize < (dwCurrBufSize + dwBytesToAdd);
  2121. dwNewBufSize *= 2
  2122. );
  2123. if (!(pNewBuf = DrvAlloc (dwNewBufSize)))
  2124. {
  2125. return FALSE;
  2126. }
  2127. //
  2128. // Copy the "valid" bytes in the old buf to the new buf,
  2129. // then free the old buf
  2130. //
  2131. CopyMemory (pNewBuf, *ppBuf, dwCurrValidBytes);
  2132. DrvFree (*ppBuf);
  2133. //
  2134. // Reset the pointers to the new buf & buf size
  2135. //
  2136. *ppBuf = pNewBuf;
  2137. *pdwBufSize = dwNewBufSize;
  2138. return TRUE;
  2139. }
  2140. PRSP_THREAD_INFO
  2141. WINAPI
  2142. GetTls(
  2143. void
  2144. )
  2145. {
  2146. PRSP_THREAD_INFO pClientThreadInfo;
  2147. if (!(pClientThreadInfo = TlsGetValue (gdwTlsIndex)))
  2148. {
  2149. pClientThreadInfo = (PRSP_THREAD_INFO)
  2150. DrvAlloc (sizeof(RSP_THREAD_INFO));
  2151. if (!pClientThreadInfo)
  2152. {
  2153. return NULL;
  2154. }
  2155. pClientThreadInfo->pBuf = DrvAlloc (INITIAL_CLIENT_THREAD_BUF_SIZE);
  2156. if (!pClientThreadInfo->pBuf)
  2157. {
  2158. DrvFree (pClientThreadInfo);
  2159. return NULL;
  2160. }
  2161. pClientThreadInfo->dwBufSize = INITIAL_CLIENT_THREAD_BUF_SIZE;
  2162. EnterCriticalSection (&gcsTlsList);
  2163. InsertHeadList (&gTlsListHead, &pClientThreadInfo->TlsList);
  2164. LeaveCriticalSection (&gcsTlsList);
  2165. TlsSetValue (gdwTlsIndex, (LPVOID) pClientThreadInfo);
  2166. }
  2167. return pClientThreadInfo;
  2168. }
  2169. #if DBG
  2170. LONG
  2171. WINAPI
  2172. RemoteDoFunc(
  2173. PREMOTE_FUNC_ARGS pFuncArgs,
  2174. char *pszFuncName
  2175. )
  2176. #else
  2177. LONG
  2178. WINAPI
  2179. RemoteDoFunc(
  2180. PREMOTE_FUNC_ARGS pFuncArgs
  2181. )
  2182. #endif
  2183. {
  2184. LONG lResult;
  2185. BOOL bCopyOnSuccess = FALSE, bRpcImpersonate, bNeedToReInit = FALSE;
  2186. DWORD i, j, dwUsedSize, dwNeededSize;
  2187. DWORD dwFuncClassErrorIndex = (pFuncArgs->Flags & 0x00000030) >> 4;
  2188. DWORD requestID;
  2189. ULONG_PTR value;
  2190. PDRVSERVER pServer = NULL;
  2191. PRSP_THREAD_INFO pTls;
  2192. //
  2193. // Get the tls
  2194. //
  2195. if (!(pTls = GetTls()))
  2196. {
  2197. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2198. goto RemoteDoFunc_return;
  2199. }
  2200. //
  2201. // Validate all the func args
  2202. //
  2203. dwNeededSize = dwUsedSize = sizeof (TAPI32_MSG);
  2204. for (i = 0, j = 0; i < (pFuncArgs->Flags & NUM_ARGS_MASK); i++, j++)
  2205. {
  2206. value = pFuncArgs->Args[i];
  2207. switch (pFuncArgs->ArgTypes[i])
  2208. {
  2209. case lpContext:
  2210. // do nothing
  2211. continue;
  2212. case Dword:
  2213. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = DWORD_CAST_HINT(pFuncArgs->Args[i],__FILE__,__LINE__,i);
  2214. continue;
  2215. case LineID:
  2216. {
  2217. PDRVLINE pLine = GetLineFromID ((DWORD) value);
  2218. try
  2219. {
  2220. pServer = pLine->pServer;
  2221. }
  2222. except (EXCEPTION_EXECUTE_HANDLER)
  2223. {
  2224. lResult = LINEERR_BADDEVICEID;
  2225. goto RemoteDoFunc_return;
  2226. }
  2227. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = pLine->dwDeviceIDServer;
  2228. continue;
  2229. }
  2230. case PhoneID:
  2231. {
  2232. PDRVPHONE pPhone = GetPhoneFromID ((DWORD) value);
  2233. try
  2234. {
  2235. pServer = pPhone->pServer;
  2236. }
  2237. except (EXCEPTION_EXECUTE_HANDLER)
  2238. {
  2239. lResult = PHONEERR_BADDEVICEID;
  2240. goto RemoteDoFunc_return;
  2241. }
  2242. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = pPhone->dwDeviceIDServer;
  2243. continue;
  2244. }
  2245. case Hdcall:
  2246. //
  2247. // Save the pServer & adjust the call handle as understood by
  2248. // the server
  2249. //
  2250. try
  2251. {
  2252. pServer = ((PDRVCALL) value)->pServer;
  2253. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = ((PDRVCALL) value)->hCall;
  2254. }
  2255. except (EXCEPTION_EXECUTE_HANDLER)
  2256. {
  2257. lResult = LINEERR_INVALCALLHANDLE;
  2258. goto RemoteDoFunc_return;
  2259. }
  2260. continue;
  2261. case Hdline:
  2262. //
  2263. // Save the pServer & adjust the line handle as understood by
  2264. // the server. There's no need to wrap this in a try/except
  2265. // since the object pointed at by the pLine is static, whether
  2266. // or not the device is actually open.
  2267. //
  2268. pServer = ((PDRVLINE) value)->pServer;
  2269. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = ((PDRVLINE) value)->hLine;
  2270. continue;
  2271. case Hdphone:
  2272. //
  2273. // Save the pServer & adjust the phone handle as understood by
  2274. // the server. There's no need to wrap this in a try/except
  2275. // since the object pointed at by the pLine is static, whether
  2276. // or not the device is actually open.
  2277. //
  2278. pServer = ((PDRVPHONE) value)->pServer;
  2279. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = ((PDRVPHONE) value)->hPhone;
  2280. continue;
  2281. case lpDword:
  2282. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = TAPI_NO_DATA;
  2283. bCopyOnSuccess = TRUE;
  2284. continue;
  2285. case lpsz:
  2286. //
  2287. // Check if value is a valid string ptr and if so
  2288. // copy the contents of the string to the extra data
  2289. // buffer passed to the server, else indicate no data
  2290. //
  2291. if (value)
  2292. {
  2293. DWORD n = (lstrlenW ((WCHAR *) value) + 1) *
  2294. sizeof (WCHAR),
  2295. nAligned = (n + 3) & 0xfffffffc;
  2296. if ((nAligned + dwUsedSize) > pTls->dwBufSize)
  2297. {
  2298. if (!GrowBuf(
  2299. &pTls->pBuf,
  2300. &pTls->dwBufSize,
  2301. dwUsedSize,
  2302. nAligned
  2303. ))
  2304. {
  2305. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2306. goto RemoteDoFunc_return;
  2307. }
  2308. }
  2309. CopyMemory (pTls->pBuf + dwUsedSize, (LPBYTE) value, n);
  2310. //
  2311. // Pass the server the offset of the string in the var data
  2312. // portion of the buffer
  2313. //
  2314. ((PTAPI32_MSG) pTls->pBuf)->Params[j] =
  2315. dwUsedSize - sizeof (TAPI32_MSG);
  2316. //
  2317. // Increment the total number of data bytes
  2318. //
  2319. dwUsedSize += nAligned;
  2320. dwNeededSize += nAligned;
  2321. }
  2322. else
  2323. {
  2324. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = TAPI_NO_DATA;
  2325. }
  2326. continue;
  2327. case lpGet_Struct:
  2328. case lpGet_CallParamsStruct:
  2329. case lpGet_SizeToFollow:
  2330. {
  2331. BOOL bSizeToFollow = (pFuncArgs->ArgTypes[i]==lpGet_SizeToFollow);
  2332. DWORD dwSize;
  2333. if (bSizeToFollow)
  2334. {
  2335. #if DBG
  2336. //
  2337. // Check to make sure the following arg is of type Size
  2338. //
  2339. if ((i == ((pFuncArgs->Flags & NUM_ARGS_MASK) - 1)) ||
  2340. (pFuncArgs->ArgTypes[i + 1] != Size))
  2341. {
  2342. LOG((TL_ERROR,
  2343. "DoFunc: error, lpGet_SizeToFollow !followed by Size"
  2344. ));
  2345. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2346. goto RemoteDoFunc_return;
  2347. }
  2348. #endif
  2349. dwSize = DWORD_CAST_HINT(pFuncArgs->Args[i + 1],__FILE__,__LINE__,i);
  2350. }
  2351. else
  2352. {
  2353. dwSize = *((LPDWORD) value); // lpXxx->dwTotalSize
  2354. }
  2355. if (bSizeToFollow)
  2356. {
  2357. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = TAPI_NO_DATA;
  2358. ++j;++i;
  2359. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = DWORD_CAST_HINT(pFuncArgs->Args[i],__FILE__,__LINE__,i);
  2360. }
  2361. else
  2362. {
  2363. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = dwSize;
  2364. }
  2365. //
  2366. // Now set the bCopyOnSuccess flag to indicate that we've data
  2367. // to copy back on successful completion, and add to the
  2368. // dwNeededSize field
  2369. //
  2370. bCopyOnSuccess = TRUE;
  2371. dwNeededSize += dwSize;
  2372. continue;
  2373. }
  2374. case lpSet_Struct:
  2375. case lpSet_SizeToFollow:
  2376. {
  2377. BOOL bSizeToFollow = (pFuncArgs->ArgTypes[i]==lpSet_SizeToFollow);
  2378. DWORD dwSize, dwSizeAligned;
  2379. #if DBG
  2380. //
  2381. // Check to make sure the following arg is of type Size
  2382. //
  2383. if (bSizeToFollow &&
  2384. ((i == ((pFuncArgs->Flags & NUM_ARGS_MASK) - 1)) ||
  2385. (pFuncArgs->ArgTypes[i + 1] != Size)))
  2386. {
  2387. LOG((TL_ERROR,
  2388. "DoFunc: error, lpSet_SizeToFollow !followed by Size"
  2389. ));
  2390. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2391. goto RemoteDoFunc_return;
  2392. }
  2393. #endif
  2394. if (bSizeToFollow)
  2395. {
  2396. dwSize = (value ? DWORD_CAST_HINT(pFuncArgs->Args[i + 1],__FILE__,__LINE__,i) : 0);
  2397. }
  2398. else
  2399. {
  2400. dwSize = (value ? *((LPDWORD) value) : 0);
  2401. }
  2402. if (dwSize)
  2403. {
  2404. //
  2405. // Grow the buffer if necessary, & do the copy
  2406. //
  2407. dwSizeAligned = (dwSize + 3) & 0xfffffffc;
  2408. if ((dwSizeAligned + dwUsedSize) > pTls->dwBufSize)
  2409. {
  2410. if (!GrowBuf(
  2411. &pTls->pBuf,
  2412. &pTls->dwBufSize,
  2413. dwUsedSize,
  2414. dwSizeAligned
  2415. ))
  2416. {
  2417. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2418. goto RemoteDoFunc_return;
  2419. }
  2420. }
  2421. CopyMemory (pTls->pBuf + dwUsedSize, (LPBYTE) value, dwSize);
  2422. }
  2423. else
  2424. {
  2425. dwSizeAligned = 0;
  2426. }
  2427. //
  2428. // Pass the server the offset of the data in the var data
  2429. // portion of the buffer
  2430. //
  2431. if (dwSize)
  2432. {
  2433. ((PTAPI32_MSG) pTls->pBuf)->Params[j] =
  2434. dwUsedSize - sizeof (TAPI32_MSG);
  2435. }
  2436. else
  2437. {
  2438. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = TAPI_NO_DATA;
  2439. }
  2440. //
  2441. // Increment the dwXxxSize vars appropriately
  2442. //
  2443. dwUsedSize += dwSizeAligned;
  2444. dwNeededSize += dwSizeAligned;
  2445. //
  2446. // Since we already know the next arg (Size) just handle
  2447. // it here so we don't have to run thru the loop again
  2448. //
  2449. if (bSizeToFollow)
  2450. {
  2451. ++j;++i;
  2452. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = DWORD_CAST_HINT(pFuncArgs->Args[i],__FILE__,__LINE__,i);
  2453. }
  2454. continue;
  2455. }
  2456. case lpServer:
  2457. pServer = (PDRVSERVER) value;
  2458. --j;
  2459. continue;
  2460. #if DBG
  2461. case Size:
  2462. LOG((TL_ERROR, "DoFunc: error, hit case Size"));
  2463. continue;
  2464. default:
  2465. LOG((TL_ERROR, "DoFunc: error, unknown arg type"));
  2466. continue;
  2467. #endif
  2468. } // switch
  2469. } // for
  2470. //
  2471. // Verify if the target server is valid & in a good state
  2472. //
  2473. if (IsValidObject ((PVOID) pServer, gdwDrvServerKey))
  2474. {
  2475. if (SERVER_REINIT & pServer->dwFlags)
  2476. {
  2477. LOG((TL_ERROR, "pServer says REINIT in RemoteDoFunc"));
  2478. lResult = gaServerReInitErrors[dwFuncClassErrorIndex];
  2479. goto RemoteDoFunc_return;
  2480. }
  2481. if (SERVER_DISCONNECTED & pServer->dwFlags)
  2482. {
  2483. LOG((TL_ERROR, "pServer is disconnected in RemoteDoFunc"));
  2484. lResult = gaServerDisconnectedErrors[dwFuncClassErrorIndex];
  2485. goto RemoteDoFunc_return;
  2486. }
  2487. }
  2488. else
  2489. {
  2490. lResult = (pServer ?
  2491. gaOpFailedErrors[dwFuncClassErrorIndex] :
  2492. gaServerDisconnectedErrors[dwFuncClassErrorIndex]);
  2493. goto RemoteDoFunc_return;
  2494. }
  2495. //
  2496. // Now make the request
  2497. //
  2498. if (dwNeededSize > pTls->dwBufSize)
  2499. {
  2500. if (!GrowBuf(
  2501. &pTls->pBuf,
  2502. &pTls->dwBufSize,
  2503. dwUsedSize,
  2504. dwNeededSize - pTls->dwBufSize
  2505. ))
  2506. {
  2507. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2508. goto RemoteDoFunc_return;
  2509. }
  2510. }
  2511. ((PTAPI32_MSG) pTls->pBuf)->u.Req_Func = (DWORD)HIWORD(pFuncArgs->Flags);
  2512. //
  2513. // If this is an async request then add it to our "handle" table &
  2514. // used the returned value for the request id passed to the server.
  2515. //
  2516. // TODO: would be faster to do this before the loop above so could
  2517. // bypass 1 or 2 loop iterations
  2518. //
  2519. if (pFuncArgs->Flags & ASYNC)
  2520. {
  2521. PASYNCREQUESTCONTEXT pContext;
  2522. if (pFuncArgs->Flags & INCL_CONTEXT)
  2523. {
  2524. pContext = (PASYNCREQUESTCONTEXT) pFuncArgs->Args[1];
  2525. pContext->dwKey = DRVASYNC_KEY;
  2526. ((PTAPI32_MSG) pTls->pBuf)->Params[1] = 0;
  2527. }
  2528. else
  2529. {
  2530. pContext = (PASYNCREQUESTCONTEXT) -1;
  2531. }
  2532. requestID =
  2533. ((PTAPI32_MSG) pTls->pBuf)->Params[0] = NewObject(
  2534. ghHandleTable,
  2535. pContext,
  2536. (LPVOID) pFuncArgs->Args[0] // the original request id
  2537. );
  2538. if (!requestID)
  2539. {
  2540. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2541. goto RemoteDoFunc_return;
  2542. }
  2543. }
  2544. //
  2545. // Impersonate the client. In some cases impersonation
  2546. // will fail, mostly likely because we're being called
  2547. // by a worker thread in tapisrv to close a line/call/
  2548. // phone object; what we do in this case is impersonate
  2549. // the logged on user (like the EventHandlerThread does).
  2550. //
  2551. if (!pTls->bAlreadyImpersonated)
  2552. {
  2553. #if MEMPHIS
  2554. #else
  2555. RPC_STATUS status;
  2556. status = RpcImpersonateClient(0);
  2557. if (status == RPC_S_OK)
  2558. {
  2559. bRpcImpersonate = TRUE;
  2560. }
  2561. else
  2562. {
  2563. bRpcImpersonate = FALSE;
  2564. LOG((TL_ERROR,
  2565. "RemoteDoFunc: RpcImpersonateClient failed, err=%d",
  2566. status
  2567. ));
  2568. if (!SetProcessImpersonationToken (NULL))
  2569. {
  2570. LOG((TL_ERROR,
  2571. "RemoteDoFunc: SetProcessImpersToken failed, lastErr=%d",
  2572. GetLastError()
  2573. ));
  2574. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2575. goto RemoteDoFunc_return;
  2576. }
  2577. }
  2578. #endif
  2579. }
  2580. {
  2581. DWORD dwRetryCount = 0;
  2582. do
  2583. {
  2584. //
  2585. // check if the server is shutting down, to avoid making RPC request
  2586. // with invalid handle
  2587. //
  2588. if (pServer->bShutdown)
  2589. {
  2590. lResult = gaServerDisconnectedErrors[dwFuncClassErrorIndex];
  2591. break;
  2592. }
  2593. RpcTryExcept
  2594. {
  2595. ClientRequest(
  2596. pServer->phContext,
  2597. pTls->pBuf,
  2598. dwNeededSize,
  2599. &dwUsedSize
  2600. );
  2601. lResult = (LONG) ((PTAPI32_MSG) pTls->pBuf)->u.Ack_ReturnValue;
  2602. if (lResult == TAPIERR_INVALRPCCONTEXT)
  2603. {
  2604. OnServerDisconnected (pServer);
  2605. lResult = gaServerDisconnectedErrors[dwFuncClassErrorIndex];
  2606. }
  2607. break; // break out of do while
  2608. }
  2609. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  2610. {
  2611. if (dwRetryCount++ < gdwRetryCount)
  2612. {
  2613. Sleep (gdwRetryTimeout);
  2614. }
  2615. else
  2616. {
  2617. unsigned long ulResult = RpcExceptionCode();
  2618. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2619. if ((ulResult == RPC_S_SERVER_UNAVAILABLE) ||
  2620. (ulResult == ERROR_INVALID_HANDLE))
  2621. {
  2622. OnServerDisconnected (pServer);
  2623. lResult = gaServerDisconnectedErrors[dwFuncClassErrorIndex];
  2624. }
  2625. break;
  2626. }
  2627. }
  2628. RpcEndExcept
  2629. } while (TRUE); //while (dwRetryCount < gdwRetryCount);
  2630. }
  2631. if (!pTls->bAlreadyImpersonated)
  2632. {
  2633. if (bRpcImpersonate)
  2634. {
  2635. RpcRevertToSelf();
  2636. }
  2637. else
  2638. {
  2639. ClearImpersonationToken();
  2640. }
  2641. }
  2642. //
  2643. // Post-processing for async requests:
  2644. // SUCCESS - restore the original/local request id for return to tapi
  2645. // ERROR - dereference the new/remote request id to free it
  2646. //
  2647. if ((pFuncArgs->Flags & ASYNC))
  2648. {
  2649. if (lResult == (LONG)requestID)
  2650. {
  2651. lResult = (LONG) pFuncArgs->Args[0];
  2652. }
  2653. else // error
  2654. {
  2655. DereferenceObject (ghHandleTable, requestID, 1);
  2656. }
  2657. }
  2658. //
  2659. // Check if server returned REINIT (it's EventNotificationThread
  2660. // timed out on an rpc request so it thinks we're toast)
  2661. //
  2662. if (lResult == LINEERR_REINIT)
  2663. {
  2664. LOG((TL_ERROR, "server returned REINIT in RemoteDoFunc"));
  2665. OnServerDisconnected (pServer);
  2666. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2667. goto RemoteDoFunc_return;
  2668. }
  2669. //
  2670. // If request completed successfully and the bCopyOnSuccess flag
  2671. // is set then we need to copy data back to client buffer(s)
  2672. //
  2673. if ((lResult == TAPI_SUCCESS) && bCopyOnSuccess)
  2674. {
  2675. for (i = 0, j = 0; i < (pFuncArgs->Flags & NUM_ARGS_MASK); i++, j++)
  2676. {
  2677. PTAPI32_MSG pMsg = (PTAPI32_MSG) pTls->pBuf;
  2678. switch (pFuncArgs->ArgTypes[i])
  2679. {
  2680. case Dword:
  2681. case LineID:
  2682. case PhoneID:
  2683. case Hdcall:
  2684. case Hdline:
  2685. case Hdphone:
  2686. case lpsz:
  2687. case lpSet_Struct:
  2688. continue;
  2689. case lpServer:
  2690. --j;
  2691. continue;
  2692. case lpDword:
  2693. //
  2694. // Fill in the pointer with the return value
  2695. //
  2696. *((LPDWORD) pFuncArgs->Args[i]) = pMsg->Params[j];
  2697. continue;
  2698. case lpGet_SizeToFollow:
  2699. //
  2700. // Fill in the buf with the return data
  2701. //
  2702. CopyMemory(
  2703. (LPBYTE) pFuncArgs->Args[i],
  2704. pTls->pBuf + pMsg->Params[j] + sizeof(TAPI32_MSG),
  2705. pMsg->Params[j+1]
  2706. );
  2707. //
  2708. // Increment i (and j, since Size passed as arg in msg)
  2709. // to skip following Size arg in pFuncArgs->Args
  2710. //
  2711. i++;
  2712. j++;
  2713. continue;
  2714. case lpSet_SizeToFollow:
  2715. //
  2716. // Increment i (and j, since Size passed as arg in msg)
  2717. // to skip following Size arg in pFuncArgs->Args
  2718. //
  2719. i++;
  2720. j++;
  2721. continue;
  2722. case lpGet_Struct:
  2723. //
  2724. // Params[j] contains the offset in the var data
  2725. // portion of pTls->pBuf of some TAPI struct.
  2726. // Get the dwUsedSize value from this struct &
  2727. // copy that many bytes from pTls->pBuf to client buf
  2728. //
  2729. if (pMsg->Params[j] != TAPI_NO_DATA)
  2730. {
  2731. LPDWORD pStruct;
  2732. pStruct = (LPDWORD) (pTls->pBuf + sizeof(TAPI32_MSG) +
  2733. pMsg->Params[j]);
  2734. CopyMemory(
  2735. (LPBYTE) pFuncArgs->Args[i],
  2736. (LPBYTE) pStruct,
  2737. *(pStruct + 2) // ptr to dwUsedSize field
  2738. );
  2739. }
  2740. continue;
  2741. case lpGet_CallParamsStruct:
  2742. //
  2743. // Params[j] contains the offset in the var data
  2744. // portion of pTls->pBuf of some TAPI struct.
  2745. // Get the dwUsedSize value from this struct &
  2746. // copy that many bytes from pTls->pBuf to client buf
  2747. //
  2748. if (pMsg->Params[j] != TAPI_NO_DATA)
  2749. {
  2750. LPDWORD pStruct;
  2751. pStruct = (LPDWORD) (pTls->pBuf + sizeof(TAPI32_MSG) +
  2752. pMsg->Params[j]);
  2753. CopyMemory(
  2754. (LPBYTE) pFuncArgs->Args[i],
  2755. (LPBYTE) pStruct,
  2756. *(pStruct) // callparams has no dwusedsize
  2757. );
  2758. }
  2759. continue;
  2760. default:
  2761. continue;
  2762. }
  2763. }
  2764. }
  2765. RemoteDoFunc_return:
  2766. #if DBG
  2767. LOG((TL_INFO, "%s: exit, returning x%x", pszFuncName, lResult));
  2768. #endif
  2769. if (bNeedToReInit)
  2770. {
  2771. ASYNCEVENTMSG msg;
  2772. LOG((TL_INFO,
  2773. "Telephony server is no longer available. " \
  2774. "Sending REINIT message to TAPI"
  2775. ));
  2776. msg.TotalSize = sizeof(msg);
  2777. msg.InitContext = pServer->InitContext;
  2778. msg.fnPostProcessProcHandle = 0;
  2779. msg.hDevice = 0;
  2780. msg.Msg = LINE_LINEDEVSTATE;
  2781. msg.OpenContext = 0;
  2782. msg.Param1 = LINEDEVSTATE_REINIT;
  2783. msg.Param2 = RSP_MSG;
  2784. msg.Param3 = 0;
  2785. msg.Param4 = 0;
  2786. RemoteSPEventProc (NULL, (unsigned char *)&msg, sizeof(msg));
  2787. }
  2788. return lResult;
  2789. }
  2790. //
  2791. // --------------------------- TAPI_lineXxx funcs -----------------------------
  2792. //
  2793. LONG
  2794. TSPIAPI
  2795. TSPI_lineAccept(
  2796. DRV_REQUESTID dwRequestID,
  2797. HDRVCALL hdCall,
  2798. LPCSTR lpsUserUserInfo,
  2799. DWORD dwSize
  2800. )
  2801. {
  2802. static REMOTE_ARG_TYPES argTypes[] =
  2803. {
  2804. Dword,
  2805. Hdcall,
  2806. lpSet_SizeToFollow,
  2807. Size
  2808. };
  2809. ULONG_PTR args[] =
  2810. {
  2811. (ULONG_PTR) dwRequestID,
  2812. (ULONG_PTR) hdCall,
  2813. (ULONG_PTR) lpsUserUserInfo,
  2814. (ULONG_PTR) dwSize
  2815. };
  2816. REMOTE_FUNC_ARGS funcArgs =
  2817. {
  2818. MAKELONG (LINE_FUNC | ASYNC | 4, lAccept),
  2819. args,
  2820. argTypes
  2821. };
  2822. return (REMOTEDOFUNC (&funcArgs, "lineAccept"));
  2823. }
  2824. LONG
  2825. TSPIAPI
  2826. TSPI_lineAddToConference(
  2827. DRV_REQUESTID dwRequestID,
  2828. HDRVCALL hdConfCall,
  2829. HDRVCALL hdConsultCall
  2830. )
  2831. {
  2832. static REMOTE_ARG_TYPES argTypes[] =
  2833. {
  2834. Dword,
  2835. Hdcall,
  2836. Hdcall
  2837. };
  2838. ULONG_PTR args[] =
  2839. {
  2840. (ULONG_PTR) dwRequestID,
  2841. (ULONG_PTR) hdConfCall,
  2842. (ULONG_PTR) hdConsultCall
  2843. };
  2844. REMOTE_FUNC_ARGS funcArgs =
  2845. {
  2846. MAKELONG (LINE_FUNC | ASYNC | 3, lAddToConference),
  2847. args,
  2848. argTypes
  2849. };
  2850. return (REMOTEDOFUNC (&funcArgs, "lineAddToConference"));
  2851. }
  2852. void
  2853. PASCAL
  2854. TSPI_lineGetAgentxxx_PostProcess(
  2855. PASYNCEVENTMSG pMsg,
  2856. PASYNCREQUESTCONTEXT pContext
  2857. )
  2858. {
  2859. LOG((TL_INFO, "lineGetAgentxxx_PostProcess: enter"));
  2860. LOG((TL_INFO,
  2861. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  2862. pMsg->Param1,
  2863. pMsg->Param2,
  2864. pMsg->Param3,
  2865. pMsg->Param4
  2866. ));
  2867. if (pMsg->Param2 == 0)
  2868. {
  2869. DWORD dwSize = (DWORD) pMsg->Param4;
  2870. LPBYTE pParams = (LPBYTE) pContext->Params[0];
  2871. CopyMemory (pParams, (LPBYTE) (pMsg + 1), dwSize);
  2872. }
  2873. }
  2874. void
  2875. PASCAL
  2876. TSPI_lineDevSpecific_PostProcess(
  2877. PASYNCEVENTMSG pMsg,
  2878. PASYNCREQUESTCONTEXT pContext
  2879. );
  2880. LONG
  2881. TSPIAPI
  2882. TSPI_lineAgentSpecific(
  2883. DRV_REQUESTID dwRequestID,
  2884. HDRVLINE hdLine,
  2885. DWORD dwAddressID,
  2886. DWORD dwAgentExtensionIDIndex,
  2887. LPVOID lpParams,
  2888. DWORD dwSize
  2889. )
  2890. {
  2891. static REMOTE_ARG_TYPES argTypes[] =
  2892. {
  2893. Dword,
  2894. Dword,
  2895. Hdline,
  2896. Dword,
  2897. Dword,
  2898. Dword,
  2899. lpSet_SizeToFollow,
  2900. Size
  2901. };
  2902. ULONG_PTR args[] =
  2903. {
  2904. (ULONG_PTR) dwRequestID,
  2905. (ULONG_PTR) 0,
  2906. (ULONG_PTR) hdLine,
  2907. (ULONG_PTR) dwAddressID,
  2908. (ULONG_PTR) dwAgentExtensionIDIndex,
  2909. (ULONG_PTR) 0,
  2910. (ULONG_PTR) lpParams,
  2911. (ULONG_PTR) dwSize
  2912. };
  2913. REMOTE_FUNC_ARGS funcArgs =
  2914. {
  2915. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 8, lAgentSpecific),
  2916. args,
  2917. argTypes
  2918. };
  2919. PASYNCREQUESTCONTEXT pContext;
  2920. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  2921. {
  2922. return LINEERR_NOMEM;
  2923. }
  2924. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  2925. TSPI_lineDevSpecific_PostProcess;
  2926. pContext->Params[0] = (ULONG_PTR) lpParams;
  2927. pContext->Params[1] = dwSize;
  2928. args[1] = (ULONG_PTR) pContext;
  2929. argTypes[1] = lpContext;
  2930. return (REMOTEDOFUNC (&funcArgs, "lAgentSpecific"));
  2931. }
  2932. LONG
  2933. TSPIAPI
  2934. TSPI_lineAnswer(
  2935. DRV_REQUESTID dwRequestID,
  2936. HDRVCALL hdCall,
  2937. LPCSTR lpsUserUserInfo,
  2938. DWORD dwSize
  2939. )
  2940. {
  2941. static REMOTE_ARG_TYPES argTypes[] =
  2942. {
  2943. Dword,
  2944. Hdcall,
  2945. lpSet_SizeToFollow,
  2946. Size
  2947. };
  2948. ULONG_PTR args[] =
  2949. {
  2950. (ULONG_PTR) dwRequestID,
  2951. (ULONG_PTR) hdCall,
  2952. (ULONG_PTR) lpsUserUserInfo,
  2953. (ULONG_PTR) dwSize
  2954. };
  2955. REMOTE_FUNC_ARGS funcArgs =
  2956. {
  2957. MAKELONG (LINE_FUNC | ASYNC | 4, lAnswer),
  2958. args,
  2959. argTypes
  2960. };
  2961. return (REMOTEDOFUNC (&funcArgs, "lineAnswer"));
  2962. }
  2963. LONG
  2964. TSPIAPI
  2965. TSPI_lineBlindTransfer(
  2966. DRV_REQUESTID dwRequestID,
  2967. HDRVCALL hdCall,
  2968. LPCWSTR lpszDestAddress,
  2969. DWORD dwCountryCode
  2970. )
  2971. {
  2972. static REMOTE_ARG_TYPES argTypes[] =
  2973. {
  2974. Dword,
  2975. Hdcall,
  2976. lpsz,
  2977. Dword
  2978. };
  2979. ULONG_PTR args[] =
  2980. {
  2981. (ULONG_PTR) dwRequestID,
  2982. (ULONG_PTR) hdCall,
  2983. (ULONG_PTR) lpszDestAddress,
  2984. (ULONG_PTR) dwCountryCode
  2985. };
  2986. REMOTE_FUNC_ARGS funcArgs =
  2987. {
  2988. MAKELONG (LINE_FUNC | ASYNC | 4, lBlindTransfer),
  2989. args,
  2990. argTypes
  2991. };
  2992. return (REMOTEDOFUNC (&funcArgs, "lineBlindTransfer"));
  2993. }
  2994. LONG
  2995. TSPIAPI
  2996. TSPI_lineClose(
  2997. HDRVLINE hdLine
  2998. )
  2999. {
  3000. //
  3001. // Check if the hLine is still valid (could have been zeroed
  3002. // out on LINE_CLOSE, so no need to call server)
  3003. //
  3004. if (((PDRVLINE) hdLine)->hLine)
  3005. {
  3006. static REMOTE_ARG_TYPES argTypes[] =
  3007. {
  3008. Hdline
  3009. };
  3010. REMOTE_FUNC_ARGS funcArgs =
  3011. {
  3012. MAKELONG (LINE_FUNC | SYNC | 1, lClose),
  3013. (ULONG_PTR *) &hdLine,
  3014. argTypes
  3015. };
  3016. DereferenceObject(
  3017. ghHandleTable,
  3018. ((PDRVLINE) hdLine)->hDeviceCallback,
  3019. 1
  3020. );
  3021. EnterCriticalSection (&gCallListCriticalSection);
  3022. ((PDRVLINE) hdLine)->htLine = 0;
  3023. ((PDRVLINE) hdLine)->hDeviceCallback = 0;
  3024. LeaveCriticalSection (&gCallListCriticalSection);
  3025. REMOTEDOFUNC (&funcArgs, "lineClose");
  3026. }
  3027. //assert (((PDRVLINE) hdLine)->pCalls == NULL);
  3028. return 0;
  3029. }
  3030. LONG
  3031. TSPIAPI
  3032. TSPI_lineCloseCall(
  3033. HDRVCALL hdCall
  3034. )
  3035. {
  3036. PDRVCALL pCall = (PDRVCALL) hdCall;
  3037. HTAPICALL htCall;
  3038. //
  3039. // Check if the hCall is still valid (could have been zeroed
  3040. // out on LINE_CLOSE, so no need to call server)
  3041. //
  3042. LOG((TL_INFO, "TSPI_lineCloseCall - pCall x%lx", hdCall));
  3043. EnterCriticalSection (&gCallListCriticalSection);
  3044. if (IsValidObject (pCall, DRVCALL_KEY))
  3045. {
  3046. htCall = pCall->htCall;
  3047. }
  3048. else
  3049. {
  3050. htCall = 0;
  3051. }
  3052. LeaveCriticalSection (&gCallListCriticalSection);
  3053. if (htCall)
  3054. {
  3055. static REMOTE_ARG_TYPES argTypes[] =
  3056. {
  3057. Hdcall
  3058. };
  3059. REMOTE_FUNC_ARGS funcArgs =
  3060. {
  3061. MAKELONG (LINE_FUNC | SYNC | 1, lDeallocateCall), // API differs
  3062. (ULONG_PTR *) &hdCall,
  3063. argTypes
  3064. };
  3065. REMOTEDOFUNC (&funcArgs, "lineCloseCall");
  3066. EnterCriticalSection (&gCallListCriticalSection);
  3067. RemoveCallFromList (pCall);
  3068. LeaveCriticalSection (&gCallListCriticalSection);
  3069. }
  3070. return 0;
  3071. }
  3072. void
  3073. PASCAL
  3074. TSPI_lineCompleteCall_PostProcess(
  3075. PASYNCEVENTMSG pMsg,
  3076. PASYNCREQUESTCONTEXT pContext
  3077. )
  3078. {
  3079. LOG((TL_INFO, "lineCompleteCall PostProcess: enter"));
  3080. LOG((TL_INFO,
  3081. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  3082. pMsg->Param1,
  3083. pMsg->Param2,
  3084. pMsg->Param3,
  3085. pMsg->Param4
  3086. ));
  3087. if (pMsg->Param2 == 0)
  3088. {
  3089. LPDWORD lpdwCompletionID = (LPDWORD) pContext->Params[0];
  3090. *lpdwCompletionID = (DWORD) pMsg->Param3;
  3091. }
  3092. }
  3093. LONG
  3094. TSPIAPI
  3095. TSPI_lineCompleteCall(
  3096. DRV_REQUESTID dwRequestID,
  3097. HDRVCALL hdCall,
  3098. LPDWORD lpdwCompletionID,
  3099. DWORD dwCompletionMode,
  3100. DWORD dwMessageID
  3101. )
  3102. {
  3103. static REMOTE_ARG_TYPES argTypes[] =
  3104. {
  3105. Dword,
  3106. Dword,
  3107. Hdcall,
  3108. Dword,
  3109. Dword,
  3110. Dword
  3111. };
  3112. ULONG_PTR args[] =
  3113. {
  3114. (ULONG_PTR) dwRequestID,
  3115. (ULONG_PTR) 0,
  3116. (ULONG_PTR) hdCall,
  3117. (ULONG_PTR) 0,
  3118. (ULONG_PTR) dwCompletionMode,
  3119. (ULONG_PTR) dwMessageID
  3120. };
  3121. REMOTE_FUNC_ARGS funcArgs =
  3122. {
  3123. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lCompleteCall),
  3124. args,
  3125. argTypes
  3126. };
  3127. PASYNCREQUESTCONTEXT pContext;
  3128. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3129. {
  3130. return LINEERR_NOMEM;
  3131. }
  3132. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3133. TSPI_lineCompleteCall_PostProcess;
  3134. pContext->Params[0] = (ULONG_PTR) lpdwCompletionID;
  3135. args[1] = (ULONG_PTR) pContext;
  3136. argTypes[1] = lpContext;
  3137. return (REMOTEDOFUNC (&funcArgs, "lineCompleteCall"));
  3138. }
  3139. LONG
  3140. TSPIAPI
  3141. TSPI_lineCompleteTransfer(
  3142. DRV_REQUESTID dwRequestID,
  3143. HDRVCALL hdCall,
  3144. HDRVCALL hdConsultCall,
  3145. HTAPICALL htConfCall,
  3146. LPHDRVCALL lphdConfCall,
  3147. DWORD dwTransferMode
  3148. )
  3149. {
  3150. static REMOTE_ARG_TYPES argTypes[] =
  3151. {
  3152. Dword,
  3153. Dword,
  3154. Hdcall,
  3155. Hdcall,
  3156. Dword,
  3157. Dword
  3158. };
  3159. ULONG_PTR args[] =
  3160. {
  3161. (ULONG_PTR) dwRequestID,
  3162. (ULONG_PTR) 0,
  3163. (ULONG_PTR) hdCall,
  3164. (ULONG_PTR) hdConsultCall,
  3165. (ULONG_PTR) 0,
  3166. (ULONG_PTR) dwTransferMode
  3167. };
  3168. REMOTE_FUNC_ARGS funcArgs =
  3169. {
  3170. MAKELONG (LINE_FUNC | ASYNC | 6, lCompleteTransfer),
  3171. args,
  3172. argTypes
  3173. };
  3174. LONG lResult;
  3175. PDRVCALL pConfCall;
  3176. if (dwTransferMode == LINETRANSFERMODE_CONFERENCE)
  3177. {
  3178. PASYNCREQUESTCONTEXT pContext;
  3179. if (!(pConfCall = DrvAlloc (sizeof (DRVCALL))))
  3180. {
  3181. return LINEERR_NOMEM;
  3182. }
  3183. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3184. {
  3185. DrvFree (pConfCall);
  3186. return LINEERR_NOMEM;
  3187. }
  3188. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3189. TSPI_lineMakeCall_PostProcess;
  3190. pContext->Params[0] = (ULONG_PTR) pConfCall;
  3191. args[1] = (ULONG_PTR) pContext;
  3192. argTypes[1] = lpContext;
  3193. funcArgs.Flags |= INCL_CONTEXT;
  3194. //
  3195. // Assume success & add the call to the line's list before we
  3196. // even make the request. This makes cleanup alot easier if
  3197. // the server goes down or some such uncooth event.
  3198. //
  3199. pConfCall->dwOriginalRequestID = dwRequestID;
  3200. pConfCall->htCall = htConfCall;
  3201. pConfCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  3202. AddCallToList ((PDRVLINE) ((PDRVCALL) hdCall)->pLine, pConfCall);
  3203. *lphdConfCall = (HDRVCALL) pConfCall;
  3204. }
  3205. else
  3206. {
  3207. pConfCall = NULL;
  3208. }
  3209. if ((lResult = REMOTEDOFUNC (&funcArgs, "lineCompleteTransfer")) < 0)
  3210. {
  3211. if (pConfCall)
  3212. {
  3213. RemoveCallFromList (pConfCall);
  3214. }
  3215. }
  3216. return lResult;
  3217. }
  3218. LONG
  3219. TSPIAPI
  3220. TSPI_lineConditionalMediaDetection(
  3221. HDRVLINE hdLine,
  3222. DWORD dwMediaModes,
  3223. LPLINECALLPARAMS const lpCallParams
  3224. )
  3225. {
  3226. static REMOTE_ARG_TYPES argTypes[] =
  3227. {
  3228. Hdline,
  3229. Dword,
  3230. lpSet_Struct,
  3231. Dword
  3232. };
  3233. ULONG_PTR args[] =
  3234. {
  3235. (ULONG_PTR) hdLine,
  3236. (ULONG_PTR) dwMediaModes,
  3237. (ULONG_PTR) lpCallParams,
  3238. (ULONG_PTR) 0xFFFFFFFF
  3239. };
  3240. REMOTE_FUNC_ARGS funcArgs =
  3241. {
  3242. MAKELONG (LINE_FUNC | SYNC | 4, lConditionalMediaDetection),
  3243. args,
  3244. argTypes
  3245. };
  3246. return (REMOTEDOFUNC (&funcArgs, "lineConditionalMediaDetection"));
  3247. }
  3248. void
  3249. PASCAL
  3250. TSPI_lineDevSpecific_PostProcess(
  3251. PASYNCEVENTMSG pMsg,
  3252. PASYNCREQUESTCONTEXT pContext
  3253. )
  3254. {
  3255. LOG((TL_INFO, "lineDevSpecificPostProcess: enter"));
  3256. if (pMsg->Param2 == 0)
  3257. {
  3258. DWORD dwSize = (DWORD) pContext->Params[1];
  3259. LPBYTE pParams = (LPBYTE) pContext->Params[0];
  3260. CopyMemory (pParams, (LPBYTE) (pMsg + 1), dwSize);
  3261. }
  3262. }
  3263. LONG
  3264. TSPIAPI
  3265. TSPI_lineCreateAgent(
  3266. DRV_REQUESTID dwRequestID,
  3267. HDRVLINE hdLine,
  3268. LPWSTR lpszAgentID,
  3269. LPWSTR lpszAgentPIN,
  3270. LPHAGENT lphAgent
  3271. )
  3272. {
  3273. REMOTE_ARG_TYPES argTypes[] =
  3274. {
  3275. Dword,
  3276. Dword,
  3277. Hdline,
  3278. lpszAgentID?lpsz:Dword,
  3279. lpszAgentPIN?lpsz:Dword,
  3280. Dword
  3281. };
  3282. ULONG_PTR args[] =
  3283. {
  3284. (ULONG_PTR) dwRequestID,
  3285. (ULONG_PTR) 0,
  3286. (ULONG_PTR) hdLine,
  3287. (ULONG_PTR) lpszAgentID,
  3288. (ULONG_PTR) lpszAgentPIN,
  3289. (ULONG_PTR) 0
  3290. };
  3291. REMOTE_FUNC_ARGS funcArgs =
  3292. {
  3293. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lCreateAgent),
  3294. args,
  3295. argTypes
  3296. };
  3297. PASYNCREQUESTCONTEXT pContext;
  3298. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3299. {
  3300. return LINEERR_NOMEM;
  3301. }
  3302. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3303. TSPI_lineGetAgentxxx_PostProcess;
  3304. pContext->Params[0] = (ULONG_PTR) lphAgent;
  3305. args[1] = (ULONG_PTR) pContext;
  3306. argTypes[1] = lpContext;
  3307. if ( lpszAgentID == NULL )
  3308. {
  3309. funcArgs.Args[3] = TAPI_NO_DATA;
  3310. funcArgs.ArgTypes[3] = Dword;
  3311. }
  3312. if ( lpszAgentPIN == NULL)
  3313. {
  3314. funcArgs.Args[4] = TAPI_NO_DATA;
  3315. funcArgs.ArgTypes[4] = Dword;
  3316. }
  3317. return (REMOTEDOFUNC (&funcArgs, "lCreateAgent"));
  3318. }
  3319. LONG
  3320. TSPIAPI
  3321. TSPI_lineCreateAgentSession(
  3322. DRV_REQUESTID dwRequestID,
  3323. HDRVLINE hdLine,
  3324. HAGENT hAgent,
  3325. LPWSTR lpszAgentPIN,
  3326. DWORD dwWorkingAddressID,
  3327. LPGUID lpGroupID,
  3328. LPHAGENTSESSION lphAgentSession
  3329. )
  3330. {
  3331. REMOTE_ARG_TYPES argTypes[] =
  3332. {
  3333. Dword,
  3334. Dword,
  3335. Hdline,
  3336. Dword,
  3337. lpszAgentPIN ? lpsz : Dword,
  3338. Dword,
  3339. lpSet_SizeToFollow,
  3340. Size,
  3341. Dword
  3342. };
  3343. ULONG_PTR args[] =
  3344. {
  3345. (ULONG_PTR) dwRequestID,
  3346. (ULONG_PTR) 0,
  3347. (ULONG_PTR) hdLine,
  3348. (ULONG_PTR) hAgent,
  3349. (ULONG_PTR) lpszAgentPIN,
  3350. (ULONG_PTR) dwWorkingAddressID,
  3351. (ULONG_PTR) lpGroupID,
  3352. (ULONG_PTR) sizeof(GUID),
  3353. (ULONG_PTR) 0
  3354. };
  3355. REMOTE_FUNC_ARGS funcArgs =
  3356. {
  3357. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 9, lCreateAgentSession),
  3358. args,
  3359. argTypes
  3360. };
  3361. PASYNCREQUESTCONTEXT pContext;
  3362. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3363. {
  3364. return LINEERR_NOMEM;
  3365. }
  3366. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3367. TSPI_lineGetAgentxxx_PostProcess;
  3368. pContext->Params[0] = (ULONG_PTR) lphAgentSession;
  3369. args[1] = (ULONG_PTR) pContext;
  3370. argTypes[1] = lpContext;
  3371. if ( lpszAgentPIN == NULL )
  3372. {
  3373. funcArgs.Args[4] = TAPI_NO_DATA;
  3374. funcArgs.ArgTypes[4] = Dword;
  3375. }
  3376. return (REMOTEDOFUNC (&funcArgs, "lCreateAgentSession"));
  3377. }
  3378. LONG
  3379. TSPIAPI
  3380. TSPI_lineDevSpecific(
  3381. DRV_REQUESTID dwRequestID,
  3382. HDRVLINE hdLine,
  3383. DWORD dwAddressID,
  3384. HDRVCALL hdCall,
  3385. LPVOID lpParams,
  3386. DWORD dwSize
  3387. )
  3388. {
  3389. REMOTE_ARG_TYPES argTypes[] =
  3390. {
  3391. Dword,
  3392. Dword,
  3393. Hdline,
  3394. Dword,
  3395. (hdCall ? Hdcall : Dword ),
  3396. Dword,
  3397. lpSet_SizeToFollow,
  3398. Size
  3399. };
  3400. ULONG_PTR args[] =
  3401. {
  3402. (ULONG_PTR) dwRequestID,
  3403. (ULONG_PTR) 0,
  3404. (ULONG_PTR) hdLine,
  3405. (ULONG_PTR) dwAddressID,
  3406. (ULONG_PTR) hdCall,
  3407. (ULONG_PTR) 0,
  3408. (ULONG_PTR) lpParams, // pass data
  3409. (ULONG_PTR) dwSize
  3410. };
  3411. REMOTE_FUNC_ARGS funcArgs =
  3412. {
  3413. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 8, lDevSpecific),
  3414. args,
  3415. argTypes
  3416. };
  3417. PASYNCREQUESTCONTEXT pContext;
  3418. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3419. {
  3420. return LINEERR_NOMEM;
  3421. }
  3422. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3423. TSPI_lineDevSpecific_PostProcess;
  3424. pContext->Params[0] = (ULONG_PTR) lpParams;
  3425. pContext->Params[1] = dwSize;
  3426. args[1] = (ULONG_PTR) pContext;
  3427. argTypes[1] = lpContext;
  3428. return (REMOTEDOFUNC (&funcArgs, "lineDevSpecific"));
  3429. }
  3430. LONG
  3431. TSPIAPI
  3432. TSPI_lineDevSpecificFeature(
  3433. DRV_REQUESTID dwRequestID,
  3434. HDRVLINE hdLine,
  3435. DWORD dwFeature,
  3436. LPVOID lpParams,
  3437. DWORD dwSize
  3438. )
  3439. {
  3440. static REMOTE_ARG_TYPES argTypes[] =
  3441. {
  3442. Dword,
  3443. Dword,
  3444. Hdline,
  3445. Dword,
  3446. Dword,
  3447. lpSet_SizeToFollow,
  3448. Size
  3449. };
  3450. ULONG_PTR args[] =
  3451. {
  3452. (ULONG_PTR) dwRequestID,
  3453. (ULONG_PTR) 0,
  3454. (ULONG_PTR) hdLine,
  3455. (ULONG_PTR) dwFeature,
  3456. (ULONG_PTR) 0,
  3457. (ULONG_PTR) lpParams, // pass data
  3458. (ULONG_PTR) dwSize
  3459. };
  3460. REMOTE_FUNC_ARGS funcArgs =
  3461. {
  3462. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 7, lDevSpecificFeature),
  3463. args,
  3464. argTypes
  3465. };
  3466. PASYNCREQUESTCONTEXT pContext;
  3467. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3468. {
  3469. return LINEERR_NOMEM;
  3470. }
  3471. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3472. TSPI_lineDevSpecific_PostProcess;
  3473. pContext->Params[0] = (ULONG_PTR) lpParams;
  3474. pContext->Params[1] = dwSize;
  3475. args[1] = (ULONG_PTR) pContext;
  3476. argTypes[1] = lpContext;
  3477. return (REMOTEDOFUNC (&funcArgs, "lineDevSpecificFeature"));
  3478. }
  3479. LONG
  3480. TSPIAPI
  3481. TSPI_lineDial(
  3482. DRV_REQUESTID dwRequestID,
  3483. HDRVCALL hdCall,
  3484. LPCWSTR lpszDestAddress,
  3485. DWORD dwCountryCode
  3486. )
  3487. {
  3488. static REMOTE_ARG_TYPES argTypes[] =
  3489. {
  3490. Dword,
  3491. Hdcall,
  3492. lpsz,
  3493. Dword
  3494. };
  3495. ULONG_PTR args[] =
  3496. {
  3497. (ULONG_PTR) dwRequestID,
  3498. (ULONG_PTR) hdCall,
  3499. (ULONG_PTR) lpszDestAddress,
  3500. (ULONG_PTR) dwCountryCode
  3501. };
  3502. REMOTE_FUNC_ARGS funcArgs =
  3503. {
  3504. MAKELONG (LINE_FUNC | ASYNC | 4, lDial),
  3505. args,
  3506. argTypes
  3507. };
  3508. return (REMOTEDOFUNC (&funcArgs, "lineDial"));
  3509. }
  3510. LONG
  3511. TSPIAPI
  3512. TSPI_lineDrop(
  3513. DRV_REQUESTID dwRequestID,
  3514. HDRVCALL hdCall,
  3515. LPCSTR lpsUserUserInfo,
  3516. DWORD dwSize
  3517. )
  3518. {
  3519. static REMOTE_ARG_TYPES argTypes[] =
  3520. {
  3521. Dword,
  3522. Hdcall,
  3523. lpSet_SizeToFollow,
  3524. Size
  3525. };
  3526. ULONG_PTR args[] =
  3527. {
  3528. (ULONG_PTR) dwRequestID,
  3529. (ULONG_PTR) hdCall,
  3530. (ULONG_PTR) lpsUserUserInfo,
  3531. (ULONG_PTR) dwSize
  3532. };
  3533. REMOTE_FUNC_ARGS funcArgs =
  3534. {
  3535. MAKELONG (LINE_FUNC | ASYNC | 4, lDrop),
  3536. args,
  3537. argTypes
  3538. };
  3539. return (REMOTEDOFUNC (&funcArgs, "lineDrop"));
  3540. }
  3541. LONG
  3542. TSPIAPI
  3543. TSPI_lineForward(
  3544. DRV_REQUESTID dwRequestID,
  3545. HDRVLINE hdLine,
  3546. DWORD bAllAddresses,
  3547. DWORD dwAddressID,
  3548. LPLINEFORWARDLIST const lpForwardList,
  3549. DWORD dwNumRingsNoAnswer,
  3550. HTAPICALL htConsultCall,
  3551. LPHDRVCALL lphdConsultCall,
  3552. LPLINECALLPARAMS const lpCallParams
  3553. )
  3554. {
  3555. static REMOTE_ARG_TYPES argTypes[] =
  3556. {
  3557. Dword,
  3558. Dword,
  3559. Hdline,
  3560. Dword,
  3561. Dword,
  3562. lpSet_Struct,
  3563. Dword,
  3564. Dword,
  3565. lpSet_Struct,
  3566. Dword
  3567. };
  3568. PDRVCALL pCall = DrvAlloc (sizeof (DRVCALL));
  3569. ULONG_PTR args[] =
  3570. {
  3571. (ULONG_PTR) dwRequestID,
  3572. (ULONG_PTR) 0,
  3573. (ULONG_PTR) hdLine,
  3574. (ULONG_PTR) bAllAddresses,
  3575. (ULONG_PTR) dwAddressID,
  3576. (ULONG_PTR) lpForwardList,
  3577. (ULONG_PTR) dwNumRingsNoAnswer,
  3578. (ULONG_PTR) 0,
  3579. (ULONG_PTR) lpCallParams,
  3580. (ULONG_PTR) 0xFFFFFFFF
  3581. };
  3582. REMOTE_FUNC_ARGS funcArgs =
  3583. {
  3584. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 10, lForward),
  3585. args,
  3586. argTypes
  3587. };
  3588. LONG lResult;
  3589. if (pCall)
  3590. {
  3591. PASYNCREQUESTCONTEXT pContext;
  3592. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3593. {
  3594. DrvFree (pCall);
  3595. return LINEERR_NOMEM;
  3596. }
  3597. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3598. TSPI_lineMakeCall_PostProcess;
  3599. pContext->Params[0] = (ULONG_PTR) pCall;
  3600. pContext->Params[1] = (ULONG_PTR) lphdConsultCall;
  3601. // save the ptr in case we need to NULL-ify later
  3602. args[1] = (ULONG_PTR) pContext;
  3603. argTypes[1] = lpContext;
  3604. pCall->htCall = htConsultCall;
  3605. pCall->dwOriginalRequestID = dwRequestID;
  3606. pCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  3607. AddCallToList ((PDRVLINE) hdLine, pCall);
  3608. *lphdConsultCall = (HDRVCALL) pCall;
  3609. if ((lResult = REMOTEDOFUNC (&funcArgs, "lineForward")) < 0)
  3610. {
  3611. RemoveCallFromList (pCall);
  3612. }
  3613. }
  3614. else
  3615. {
  3616. lResult = LINEERR_NOMEM;
  3617. }
  3618. return lResult;
  3619. }
  3620. void
  3621. PASCAL
  3622. TSPI_lineGatherDigits_PostProcess(
  3623. PASYNCEVENTMSG pMsg
  3624. )
  3625. {
  3626. DWORD dwEndToEndIDRemoteSP = ((DWORD *)(pMsg + 1))[0];
  3627. PASYNCREQUESTCONTEXT pContext;
  3628. LOG((TL_INFO, "TSPI_lineGatherDigits_PostProcess: enter"));
  3629. if ((pContext = ReferenceObject(
  3630. ghHandleTable,
  3631. dwEndToEndIDRemoteSP,
  3632. 0
  3633. )))
  3634. {
  3635. if (pMsg->Param1 &
  3636. (LINEGATHERTERM_BUFFERFULL | LINEGATHERTERM_CANCEL |
  3637. LINEGATHERTERM_TERMDIGIT | LINEGATHERTERM_INTERTIMEOUT))
  3638. {
  3639. LPSTR lpsDigits = (LPSTR) pContext->Params[0];
  3640. DWORD dwNumDigits = (DWORD) pMsg->Param4;
  3641. LPCWSTR pBuffer = (LPCWSTR) ( ( (DWORD *) (pMsg + 1) ) + 2);
  3642. try
  3643. {
  3644. CopyMemory (lpsDigits, pBuffer, dwNumDigits * sizeof(WCHAR));
  3645. }
  3646. except (EXCEPTION_EXECUTE_HANDLER)
  3647. {
  3648. }
  3649. }
  3650. pMsg->Param2 = DWORD_CAST(pContext->Params[1],__FILE__,__LINE__);
  3651. DereferenceObject (ghHandleTable, dwEndToEndIDRemoteSP, 2);
  3652. }
  3653. else
  3654. {
  3655. pMsg->Param2 = 0;
  3656. }
  3657. }
  3658. LONG
  3659. TSPIAPI
  3660. TSPI_lineGatherDigits(
  3661. HDRVCALL hdCall,
  3662. DWORD dwEndToEndID,
  3663. DWORD dwDigitModes,
  3664. LPWSTR lpsDigits,
  3665. DWORD dwNumDigits,
  3666. LPCWSTR lpszTerminationDigits,
  3667. DWORD dwFirstDigitTimeout,
  3668. DWORD dwInterDigitTimeout
  3669. )
  3670. {
  3671. static REMOTE_ARG_TYPES argTypes[] =
  3672. {
  3673. Dword,
  3674. Hdcall,
  3675. Dword,
  3676. Dword,
  3677. Dword,
  3678. Dword,
  3679. lpsz,
  3680. Dword,
  3681. Dword
  3682. };
  3683. ULONG_PTR args[] =
  3684. {
  3685. (ULONG_PTR) 0,
  3686. (ULONG_PTR) hdCall,
  3687. (ULONG_PTR) 0, // dwEndToEndID,
  3688. (ULONG_PTR) dwDigitModes,
  3689. (ULONG_PTR) 0, // lpsDigits,
  3690. (ULONG_PTR) dwNumDigits,
  3691. (ULONG_PTR) lpszTerminationDigits,
  3692. (ULONG_PTR) dwFirstDigitTimeout,
  3693. (ULONG_PTR) dwInterDigitTimeout
  3694. };
  3695. REMOTE_FUNC_ARGS funcArgs =
  3696. {
  3697. MAKELONG (LINE_FUNC | SYNC | 9, lGatherDigits),
  3698. args,
  3699. argTypes
  3700. };
  3701. PASYNCREQUESTCONTEXT pContext;
  3702. if (lpsDigits)
  3703. {
  3704. if (IsBadWritePtr (lpsDigits, dwNumDigits * sizeof(WCHAR)))
  3705. {
  3706. return LINEERR_INVALPOINTER;
  3707. }
  3708. if (!(pContext = DrvAlloc (sizeof(*pContext))))
  3709. {
  3710. return LINEERR_NOMEM;
  3711. }
  3712. pContext->Params[0] = (ULONG_PTR) lpsDigits;
  3713. pContext->Params[1] = dwEndToEndID;
  3714. if (!(args[2] = NewObject (ghHandleTable, pContext, NULL)))
  3715. {
  3716. DrvFree (pContext);
  3717. return LINEERR_NOMEM;
  3718. }
  3719. args[4] = 1; // Set the lpsDigits param to something non-zero
  3720. }
  3721. if (lpszTerminationDigits == (LPCWSTR) NULL)
  3722. {
  3723. funcArgs.ArgTypes[6] = Dword;
  3724. funcArgs.Args[6] = TAPI_NO_DATA;
  3725. }
  3726. return (REMOTEDOFUNC (&funcArgs, "lineGatherDigits"));
  3727. }
  3728. LONG
  3729. TSPIAPI
  3730. TSPI_lineGenerateDigits(
  3731. HDRVCALL hdCall,
  3732. DWORD dwEndToEndID,
  3733. DWORD dwDigitMode,
  3734. LPCWSTR lpszDigits,
  3735. DWORD dwDuration
  3736. )
  3737. {
  3738. static REMOTE_ARG_TYPES argTypes[] =
  3739. {
  3740. Hdcall,
  3741. Dword,
  3742. lpsz,
  3743. Dword,
  3744. Dword
  3745. };
  3746. ULONG_PTR args[] =
  3747. {
  3748. (ULONG_PTR) hdCall,
  3749. (ULONG_PTR) dwDigitMode,
  3750. (ULONG_PTR) lpszDigits,
  3751. (ULONG_PTR) dwDuration,
  3752. (ULONG_PTR) dwEndToEndID,
  3753. };
  3754. REMOTE_FUNC_ARGS funcArgs =
  3755. {
  3756. MAKELONG (LINE_FUNC | SYNC | 5, lGenerateDigits),
  3757. args,
  3758. argTypes
  3759. };
  3760. return (REMOTEDOFUNC (&funcArgs, "lineGenerateDigits"));
  3761. }
  3762. LONG
  3763. TSPIAPI
  3764. TSPI_lineGenerateTone(
  3765. HDRVCALL hdCall,
  3766. DWORD dwEndToEndID,
  3767. DWORD dwToneMode,
  3768. DWORD dwDuration,
  3769. DWORD dwNumTones,
  3770. LPLINEGENERATETONE const lpTones
  3771. )
  3772. {
  3773. REMOTE_ARG_TYPES argTypes[] =
  3774. {
  3775. Hdcall,
  3776. Dword,
  3777. Dword,
  3778. Dword,
  3779. Dword,
  3780. Dword,
  3781. Dword
  3782. };
  3783. ULONG_PTR args[] =
  3784. {
  3785. (ULONG_PTR) hdCall,
  3786. (ULONG_PTR) dwToneMode,
  3787. (ULONG_PTR) dwDuration,
  3788. (ULONG_PTR) dwNumTones,
  3789. (ULONG_PTR) TAPI_NO_DATA,
  3790. (ULONG_PTR) 0,
  3791. (ULONG_PTR) dwEndToEndID
  3792. };
  3793. REMOTE_FUNC_ARGS funcArgs =
  3794. {
  3795. MAKELONG (LINE_FUNC | SYNC | 7, lGenerateTone),
  3796. args,
  3797. argTypes
  3798. };
  3799. if (dwToneMode == LINETONEMODE_CUSTOM)
  3800. {
  3801. argTypes[4] = lpSet_SizeToFollow;
  3802. args[4] = (ULONG_PTR) lpTones;
  3803. argTypes[5] = Size;
  3804. args[5] = dwNumTones * sizeof(LINEGENERATETONE);
  3805. }
  3806. return (REMOTEDOFUNC (&funcArgs, "lineGenerateTone"));
  3807. }
  3808. LONG
  3809. TSPIAPI
  3810. TSPI_lineGetAddressCaps(
  3811. DWORD dwDeviceID,
  3812. DWORD dwAddressID,
  3813. DWORD dwTSPIVersion,
  3814. DWORD dwExtVersion,
  3815. LPLINEADDRESSCAPS lpAddressCaps
  3816. )
  3817. {
  3818. static REMOTE_ARG_TYPES argTypes[] =
  3819. {
  3820. Dword,
  3821. LineID,
  3822. Dword,
  3823. Dword,
  3824. Dword,
  3825. lpGet_Struct
  3826. };
  3827. ULONG_PTR args[] =
  3828. {
  3829. (ULONG_PTR) 0,
  3830. (ULONG_PTR) dwDeviceID,
  3831. (ULONG_PTR) dwAddressID,
  3832. (ULONG_PTR) dwTSPIVersion,
  3833. (ULONG_PTR) dwExtVersion,
  3834. (ULONG_PTR) lpAddressCaps,
  3835. };
  3836. REMOTE_FUNC_ARGS funcArgs =
  3837. {
  3838. MAKELONG (LINE_FUNC | SYNC | 6, lGetAddressCaps),
  3839. args,
  3840. argTypes
  3841. };
  3842. PDRVLINE pLine = GetLineFromID (dwDeviceID);
  3843. if (NULL == pLine)
  3844. {
  3845. return LINEERR_BADDEVICEID;
  3846. }
  3847. args[0] = pLine->pServer->hLineApp;
  3848. return (REMOTEDOFUNC (&funcArgs, "lineGetAddressCaps"));
  3849. }
  3850. LONG
  3851. TSPIAPI
  3852. TSPI_lineGetAddressID(
  3853. HDRVLINE hdLine,
  3854. LPDWORD lpdwAddressID,
  3855. DWORD dwAddressMode,
  3856. LPCWSTR lpsAddress,
  3857. DWORD dwSize
  3858. )
  3859. {
  3860. static REMOTE_ARG_TYPES argTypes[] =
  3861. {
  3862. Hdline,
  3863. lpDword,
  3864. Dword,
  3865. lpSet_SizeToFollow,
  3866. Size
  3867. };
  3868. ULONG_PTR args[] =
  3869. {
  3870. (ULONG_PTR) hdLine,
  3871. (ULONG_PTR) lpdwAddressID,
  3872. (ULONG_PTR) dwAddressMode,
  3873. (ULONG_PTR) lpsAddress,
  3874. (ULONG_PTR) dwSize
  3875. };
  3876. REMOTE_FUNC_ARGS funcArgs =
  3877. {
  3878. MAKELONG (LINE_FUNC | SYNC | 5, lGetAddressID),
  3879. args,
  3880. argTypes
  3881. };
  3882. return (REMOTEDOFUNC (&funcArgs, "lineGetAddressID"));
  3883. }
  3884. LONG
  3885. TSPIAPI
  3886. TSPI_lineGetAddressStatus(
  3887. HDRVLINE hdLine,
  3888. DWORD dwAddressID,
  3889. LPLINEADDRESSSTATUS lpAddressStatus
  3890. )
  3891. {
  3892. static REMOTE_ARG_TYPES argTypes[] =
  3893. {
  3894. Hdline,
  3895. Dword,
  3896. lpGet_Struct
  3897. };
  3898. ULONG_PTR args[] =
  3899. {
  3900. (ULONG_PTR) hdLine,
  3901. (ULONG_PTR) dwAddressID,
  3902. (ULONG_PTR) lpAddressStatus
  3903. };
  3904. REMOTE_FUNC_ARGS funcArgs =
  3905. {
  3906. MAKELONG (LINE_FUNC | SYNC | 3, lGetAddressStatus),
  3907. args,
  3908. argTypes
  3909. };
  3910. return (REMOTEDOFUNC (&funcArgs, "lineGetAddressStatus"));
  3911. }
  3912. LONG
  3913. TSPIAPI
  3914. TSPI_lineGetAgentActivityList(
  3915. DRV_REQUESTID dwRequestID,
  3916. HDRVLINE hdLine,
  3917. DWORD dwAddressID,
  3918. LPLINEAGENTACTIVITYLIST lpAgentActivityList
  3919. )
  3920. {
  3921. static REMOTE_ARG_TYPES argTypes[] =
  3922. {
  3923. Dword,
  3924. Dword,
  3925. Hdline,
  3926. Dword,
  3927. Dword,
  3928. lpGet_Struct
  3929. };
  3930. ULONG_PTR args[] =
  3931. {
  3932. (ULONG_PTR) dwRequestID,
  3933. (ULONG_PTR) 0,
  3934. (ULONG_PTR) hdLine,
  3935. (ULONG_PTR) dwAddressID,
  3936. (ULONG_PTR) 0,
  3937. (ULONG_PTR) lpAgentActivityList
  3938. };
  3939. REMOTE_FUNC_ARGS funcArgs =
  3940. {
  3941. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetAgentActivityList),
  3942. args,
  3943. argTypes
  3944. };
  3945. PASYNCREQUESTCONTEXT pContext;
  3946. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  3947. {
  3948. return LINEERR_NOMEM;
  3949. }
  3950. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  3951. TSPI_lineGetAgentxxx_PostProcess;
  3952. pContext->Params[0] = (ULONG_PTR) lpAgentActivityList;
  3953. args[1] = (ULONG_PTR) pContext;
  3954. argTypes[1] = lpContext;
  3955. return (REMOTEDOFUNC (&funcArgs, "lGetAgentActivityList"));
  3956. }
  3957. LONG
  3958. TSPIAPI
  3959. TSPI_lineGetAgentCaps(
  3960. DRV_REQUESTID dwRequestID,
  3961. DWORD dwDeviceID,
  3962. DWORD dwAddressID,
  3963. DWORD dwAppAPIVersion,
  3964. LPLINEAGENTCAPS lpAgentCaps
  3965. )
  3966. {
  3967. static REMOTE_ARG_TYPES argTypes[] =
  3968. {
  3969. Dword,
  3970. Dword,
  3971. Dword,
  3972. LineID,
  3973. Dword,
  3974. Dword,
  3975. Dword,
  3976. lpGet_Struct
  3977. };
  3978. ULONG_PTR args[] =
  3979. {
  3980. (ULONG_PTR) dwRequestID,
  3981. (ULONG_PTR) 0,
  3982. (ULONG_PTR) 0,
  3983. (ULONG_PTR) dwDeviceID,
  3984. (ULONG_PTR) dwAddressID,
  3985. (ULONG_PTR) dwAppAPIVersion,
  3986. (ULONG_PTR) 0,
  3987. (ULONG_PTR) lpAgentCaps
  3988. };
  3989. REMOTE_FUNC_ARGS funcArgs =
  3990. {
  3991. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 8, lGetAgentCaps),
  3992. args,
  3993. argTypes
  3994. };
  3995. PASYNCREQUESTCONTEXT pContext;
  3996. PDRVLINE pLine = GetLineFromID (dwDeviceID);
  3997. if (NULL == pLine)
  3998. {
  3999. return LINEERR_BADDEVICEID;
  4000. }
  4001. args[2] = pLine->pServer->hLineApp;
  4002. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4003. {
  4004. return LINEERR_NOMEM;
  4005. }
  4006. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4007. TSPI_lineGetAgentxxx_PostProcess;
  4008. pContext->Params[0] = (ULONG_PTR) lpAgentCaps;
  4009. args[1] = (ULONG_PTR) pContext;
  4010. argTypes[1] = lpContext;
  4011. return (REMOTEDOFUNC (&funcArgs, "lGetAgentCaps"));
  4012. }
  4013. LONG
  4014. TSPIAPI
  4015. TSPI_lineGetAgentGroupList(
  4016. DRV_REQUESTID dwRequestID,
  4017. HDRVLINE hdLine,
  4018. DWORD dwAddressID,
  4019. LPLINEAGENTGROUPLIST lpAgentGroupList
  4020. )
  4021. {
  4022. static REMOTE_ARG_TYPES argTypes[] =
  4023. {
  4024. Dword,
  4025. Dword,
  4026. Hdline,
  4027. Dword,
  4028. Dword,
  4029. lpGet_Struct
  4030. };
  4031. ULONG_PTR args[] =
  4032. {
  4033. (ULONG_PTR) dwRequestID,
  4034. (ULONG_PTR) 0,
  4035. (ULONG_PTR) hdLine,
  4036. (ULONG_PTR) dwAddressID,
  4037. (ULONG_PTR) 0,
  4038. (ULONG_PTR) lpAgentGroupList
  4039. };
  4040. REMOTE_FUNC_ARGS funcArgs =
  4041. {
  4042. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetAgentGroupList),
  4043. args,
  4044. argTypes
  4045. };
  4046. PASYNCREQUESTCONTEXT pContext;
  4047. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4048. {
  4049. return LINEERR_NOMEM;
  4050. }
  4051. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4052. TSPI_lineGetAgentxxx_PostProcess;
  4053. pContext->Params[0] = (ULONG_PTR) lpAgentGroupList;
  4054. args[1] = (ULONG_PTR) pContext;
  4055. argTypes[1] = lpContext;
  4056. return (REMOTEDOFUNC (&funcArgs, "lGetAgentGroupList"));
  4057. }
  4058. LONG
  4059. TSPIAPI
  4060. TSPI_lineGetAgentInfo(
  4061. DRV_REQUESTID dwRequestID,
  4062. HDRVLINE hdLine,
  4063. HAGENT hAgent,
  4064. LPLINEAGENTINFO lpAgentInfo
  4065. )
  4066. {
  4067. static REMOTE_ARG_TYPES argTypes[] =
  4068. {
  4069. Dword,
  4070. Dword,
  4071. Hdline,
  4072. Dword,
  4073. Dword,
  4074. lpGet_Struct
  4075. };
  4076. ULONG_PTR args[] =
  4077. {
  4078. (ULONG_PTR) dwRequestID,
  4079. (ULONG_PTR) 0,
  4080. (ULONG_PTR) hdLine,
  4081. (ULONG_PTR) hAgent,
  4082. (ULONG_PTR) 0,
  4083. (ULONG_PTR) lpAgentInfo
  4084. };
  4085. REMOTE_FUNC_ARGS funcArgs =
  4086. {
  4087. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetAgentInfo),
  4088. args,
  4089. argTypes
  4090. };
  4091. PASYNCREQUESTCONTEXT pContext;
  4092. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4093. {
  4094. return LINEERR_NOMEM;
  4095. }
  4096. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4097. TSPI_lineGetAgentxxx_PostProcess;
  4098. pContext->Params[0] = (ULONG_PTR) lpAgentInfo;
  4099. args[1] = (ULONG_PTR) pContext;
  4100. argTypes[1] = lpContext;
  4101. return (REMOTEDOFUNC (&funcArgs, "lGetAgentInfo"));
  4102. }
  4103. LONG
  4104. TSPIAPI
  4105. TSPI_lineGetAgentSessionInfo(
  4106. DRV_REQUESTID dwRequestID,
  4107. HDRVLINE hdLine,
  4108. HAGENT hAgent,
  4109. LPLINEAGENTSESSIONINFO lpAgentSessionInfo
  4110. )
  4111. {
  4112. static REMOTE_ARG_TYPES argTypes[] =
  4113. {
  4114. Dword,
  4115. Dword,
  4116. Hdline,
  4117. Dword,
  4118. Dword,
  4119. lpGet_Struct
  4120. };
  4121. ULONG_PTR args[] =
  4122. {
  4123. (ULONG_PTR) dwRequestID,
  4124. (ULONG_PTR) 0,
  4125. (ULONG_PTR) hdLine,
  4126. (ULONG_PTR) hAgent,
  4127. (ULONG_PTR) 0,
  4128. (ULONG_PTR) lpAgentSessionInfo
  4129. };
  4130. REMOTE_FUNC_ARGS funcArgs =
  4131. {
  4132. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetAgentSessionInfo),
  4133. args,
  4134. argTypes
  4135. };
  4136. PASYNCREQUESTCONTEXT pContext;
  4137. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4138. {
  4139. return LINEERR_NOMEM;
  4140. }
  4141. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4142. TSPI_lineGetAgentxxx_PostProcess;
  4143. pContext->Params[0] = (ULONG_PTR) lpAgentSessionInfo;
  4144. args[1] = (ULONG_PTR) pContext;
  4145. argTypes[1] = lpContext;
  4146. return (REMOTEDOFUNC (&funcArgs, "lGetAgentSessionInfo"));
  4147. }
  4148. LONG
  4149. TSPIAPI
  4150. TSPI_lineGetAgentSessionList(
  4151. DRV_REQUESTID dwRequestID,
  4152. HDRVLINE hdLine,
  4153. HAGENT hAgent,
  4154. LPLINEAGENTSESSIONLIST lpAgentSessionList
  4155. )
  4156. {
  4157. static REMOTE_ARG_TYPES argTypes[] =
  4158. {
  4159. Dword,
  4160. Dword,
  4161. Hdline,
  4162. Dword,
  4163. Dword,
  4164. lpGet_Struct
  4165. };
  4166. ULONG_PTR args[] =
  4167. {
  4168. (ULONG_PTR) dwRequestID,
  4169. (ULONG_PTR) 0,
  4170. (ULONG_PTR) hdLine,
  4171. (ULONG_PTR) hAgent,
  4172. (ULONG_PTR) 0,
  4173. (ULONG_PTR) lpAgentSessionList
  4174. };
  4175. REMOTE_FUNC_ARGS funcArgs =
  4176. {
  4177. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetAgentSessionList),
  4178. args,
  4179. argTypes
  4180. };
  4181. PASYNCREQUESTCONTEXT pContext;
  4182. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4183. {
  4184. return LINEERR_NOMEM;
  4185. }
  4186. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4187. TSPI_lineGetAgentxxx_PostProcess;
  4188. pContext->Params[0] = (ULONG_PTR) lpAgentSessionList;
  4189. args[1] = (ULONG_PTR) pContext;
  4190. argTypes[1] = lpContext;
  4191. return (REMOTEDOFUNC (&funcArgs, "lGetAgentSessionList"));
  4192. }
  4193. LONG
  4194. TSPIAPI
  4195. TSPI_lineGetAgentStatus(
  4196. DRV_REQUESTID dwRequestID,
  4197. HDRVLINE hdLine,
  4198. DWORD dwAddressID,
  4199. LPLINEAGENTSTATUS lpAgentStatus
  4200. )
  4201. {
  4202. static REMOTE_ARG_TYPES argTypes[] =
  4203. {
  4204. Dword,
  4205. Dword,
  4206. Hdline,
  4207. Dword,
  4208. Dword,
  4209. lpGet_Struct
  4210. };
  4211. ULONG_PTR args[] =
  4212. {
  4213. (ULONG_PTR) dwRequestID,
  4214. (ULONG_PTR) 0,
  4215. (ULONG_PTR) hdLine,
  4216. (ULONG_PTR) dwAddressID,
  4217. (ULONG_PTR) 0,
  4218. (ULONG_PTR) lpAgentStatus
  4219. };
  4220. REMOTE_FUNC_ARGS funcArgs =
  4221. {
  4222. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetAgentStatus),
  4223. args,
  4224. argTypes
  4225. };
  4226. PASYNCREQUESTCONTEXT pContext;
  4227. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4228. {
  4229. return LINEERR_NOMEM;
  4230. }
  4231. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4232. TSPI_lineGetAgentxxx_PostProcess;
  4233. pContext->Params[0] = (ULONG_PTR) lpAgentStatus;
  4234. args[1] = (ULONG_PTR) pContext;
  4235. argTypes[1] = lpContext;
  4236. return (REMOTEDOFUNC (&funcArgs, "lGetAgentStatus"));
  4237. }
  4238. #if MEMPHIS
  4239. LONG
  4240. TSPIAPI
  4241. TSPI_lineGetCallAddressID(
  4242. HDRVCALL hdCall,
  4243. LPDWORD lpdwAddressID
  4244. )
  4245. {
  4246. static REMOTE_ARG_TYPES argTypes[] =
  4247. {
  4248. Hdcall,
  4249. lpDword
  4250. };
  4251. ULONG_PTR args[] =
  4252. {
  4253. (ULONG_PTR) hdCall,
  4254. (ULONG_PTR) lpdwAddressID
  4255. };
  4256. REMOTE_FUNC_ARGS funcArgs =
  4257. {
  4258. MAKELONG (LINE_FUNC | SYNC | 2, lGetCallAddressID),
  4259. args,
  4260. argTypes
  4261. };
  4262. return (REMOTEDOFUNC (&funcArgs, "lineGetCallAddressID"));
  4263. }
  4264. #else
  4265. LONG
  4266. TSPIAPI
  4267. TSPI_lineGetCallAddressID(
  4268. HDRVCALL hdCall,
  4269. LPDWORD lpdwAddressID
  4270. )
  4271. {
  4272. LONG lResult = LINEERR_INVALCALLHANDLE;
  4273. try
  4274. {
  4275. *lpdwAddressID = ((PDRVCALL) hdCall)->dwAddressID;
  4276. if (((PDRVCALL) hdCall)->dwKey == DRVCALL_KEY)
  4277. {
  4278. lResult = 0;
  4279. }
  4280. }
  4281. except (EXCEPTION_EXECUTE_HANDLER)
  4282. {
  4283. // do nothing, just fall thru
  4284. }
  4285. return lResult;
  4286. }
  4287. LONG
  4288. TSPIAPI
  4289. TSPI_lineGetCallHubTracking(
  4290. HDRVLINE hdLine,
  4291. LPLINECALLHUBTRACKINGINFO lpTrackingInfo
  4292. )
  4293. {
  4294. static REMOTE_ARG_TYPES argTypes[] =
  4295. {
  4296. Hdline,
  4297. lpGet_Struct
  4298. };
  4299. ULONG_PTR args[] =
  4300. {
  4301. (ULONG_PTR) hdLine,
  4302. (ULONG_PTR) lpTrackingInfo
  4303. };
  4304. REMOTE_FUNC_ARGS funcArgs =
  4305. {
  4306. MAKELONG (LINE_FUNC | SYNC | 2, lGetCallHubTracking),
  4307. args,
  4308. argTypes
  4309. };
  4310. return (REMOTEDOFUNC (&funcArgs, "lineGetCallHubTracking"));
  4311. }
  4312. LONG
  4313. TSPIAPI
  4314. TSPI_lineGetCallIDs(
  4315. HDRVCALL hdCall,
  4316. LPDWORD lpdwAddressID,
  4317. LPDWORD lpdwCallID,
  4318. LPDWORD lpdwRelatedCallID
  4319. )
  4320. {
  4321. LONG lResult = LINEERR_INVALCALLHANDLE;
  4322. PDRVCALL pCall = (PDRVCALL) hdCall;
  4323. PDRVSERVER pServer;
  4324. try
  4325. {
  4326. *lpdwAddressID = pCall->dwAddressID;
  4327. *lpdwCallID = pCall->dwCallID;
  4328. *lpdwRelatedCallID = pCall->dwRelatedCallID;
  4329. pServer = pCall->pServer;
  4330. if (pCall->dwKey == DRVCALL_KEY)
  4331. {
  4332. lResult = (pCall->dwDirtyStructs & STRUCTCHANGE_CALLIDS ? 1 : 0);
  4333. }
  4334. }
  4335. except (EXCEPTION_EXECUTE_HANDLER)
  4336. {
  4337. // do nothing, just fall thru
  4338. }
  4339. if (lResult == 1)
  4340. {
  4341. if (!pServer->bVer2xServer)
  4342. {
  4343. static REMOTE_ARG_TYPES argTypes[] =
  4344. {
  4345. Hdcall,
  4346. lpDword,
  4347. lpDword,
  4348. lpDword
  4349. };
  4350. ULONG_PTR args[] =
  4351. {
  4352. (ULONG_PTR) hdCall,
  4353. (ULONG_PTR) lpdwAddressID,
  4354. (ULONG_PTR) lpdwCallID,
  4355. (ULONG_PTR) lpdwRelatedCallID
  4356. };
  4357. REMOTE_FUNC_ARGS funcArgs =
  4358. {
  4359. MAKELONG (LINE_FUNC | SYNC | 4, lGetCallIDs),
  4360. args,
  4361. argTypes
  4362. };
  4363. lResult = REMOTEDOFUNC (&funcArgs, "lGetCallIDs");
  4364. }
  4365. else
  4366. {
  4367. LINECALLINFO callInfo;
  4368. callInfo.dwTotalSize = sizeof (callInfo);
  4369. if ((lResult = TSPI_lineGetCallInfo (hdCall, &callInfo)) == 0)
  4370. {
  4371. *lpdwAddressID = callInfo.dwAddressID;
  4372. *lpdwCallID = callInfo.dwCallID;
  4373. *lpdwRelatedCallID = callInfo.dwRelatedCallID;
  4374. }
  4375. }
  4376. if (lResult == 0)
  4377. {
  4378. EnterCriticalSection (&gCallListCriticalSection);
  4379. if (IsValidObject (pCall, DRVCALL_KEY))
  4380. {
  4381. pCall->dwAddressID = *lpdwAddressID;
  4382. pCall->dwCallID = *lpdwCallID;
  4383. pCall->dwRelatedCallID = *lpdwRelatedCallID;
  4384. pCall->dwDirtyStructs &= ~STRUCTCHANGE_CALLIDS;
  4385. }
  4386. LeaveCriticalSection (&gCallListCriticalSection);
  4387. }
  4388. }
  4389. return lResult;
  4390. }
  4391. #endif //MEMPHIS
  4392. LONG
  4393. TSPIAPI
  4394. TSPI_lineGetCallInfo(
  4395. HDRVCALL hdCall,
  4396. LPLINECALLINFO lpCallInfo
  4397. )
  4398. {
  4399. LONG lResult;
  4400. static REMOTE_ARG_TYPES argTypes[] =
  4401. {
  4402. Hdcall,
  4403. lpGet_Struct
  4404. };
  4405. ULONG_PTR args[] =
  4406. {
  4407. (ULONG_PTR) hdCall,
  4408. (ULONG_PTR) lpCallInfo
  4409. };
  4410. REMOTE_FUNC_ARGS funcArgs =
  4411. {
  4412. MAKELONG (LINE_FUNC | SYNC | 2, lGetCallInfo),
  4413. args,
  4414. argTypes
  4415. };
  4416. PDRVCALL pCall = (PDRVCALL)hdCall;
  4417. //
  4418. // Has the cached structure been invalidated?
  4419. //
  4420. EnterCriticalSection (&gCallListCriticalSection);
  4421. if (!IsValidObject (pCall, DRVCALL_KEY))
  4422. {
  4423. LeaveCriticalSection (&gCallListCriticalSection);
  4424. return LINEERR_INVALCALLHANDLE;
  4425. }
  4426. if ( ( pCall->dwDirtyStructs & STRUCTCHANGE_LINECALLINFO ) ||
  4427. ( pCall->dwCachedCallInfoCount > gdwCacheForceCallCount ) )
  4428. {
  4429. //
  4430. // The cache not valid, get the real info
  4431. //
  4432. LeaveCriticalSection (&gCallListCriticalSection);
  4433. lResult = (REMOTEDOFUNC (&funcArgs, "lineGetCallInfo"));
  4434. //
  4435. // Did the function succeed and was the entire struct returned?
  4436. //
  4437. if (
  4438. (ERROR_SUCCESS == lResult)
  4439. &&
  4440. (lpCallInfo->dwNeededSize <= lpCallInfo->dwTotalSize)
  4441. )
  4442. {
  4443. EnterCriticalSection (&gCallListCriticalSection);
  4444. if (!IsValidObject (pCall, DRVCALL_KEY))
  4445. {
  4446. LeaveCriticalSection (&gCallListCriticalSection);
  4447. return LINEERR_INVALCALLHANDLE;
  4448. }
  4449. //
  4450. // Did we already have a good pointer?
  4451. //
  4452. if ( pCall->pCachedCallInfo )
  4453. {
  4454. DrvFree( pCall->pCachedCallInfo );
  4455. }
  4456. pCall->pCachedCallInfo = DrvAlloc( lpCallInfo->dwUsedSize );
  4457. if ( pCall->pCachedCallInfo )
  4458. {
  4459. //
  4460. // Mark the cache data as clean
  4461. //
  4462. pCall->dwDirtyStructs &= ~STRUCTCHANGE_LINECALLINFO;
  4463. pCall->dwCachedCallInfoCount = 0;
  4464. //
  4465. // Adjust the LineID for the local machine
  4466. //
  4467. lpCallInfo->dwLineDeviceID += gdwLineDeviceIDBase;
  4468. CopyMemory( pCall->pCachedCallInfo,
  4469. lpCallInfo,
  4470. lpCallInfo->dwUsedSize
  4471. );
  4472. }
  4473. LeaveCriticalSection (&gCallListCriticalSection);
  4474. }
  4475. }
  4476. else
  4477. {
  4478. //
  4479. // The cache is valid, return data from there
  4480. //
  4481. if ( lpCallInfo->dwTotalSize >= pCall->pCachedCallInfo->dwUsedSize )
  4482. {
  4483. CopyMemory(
  4484. (PBYTE)&(((PDWORD)lpCallInfo)[1]),
  4485. (PBYTE)&(((PDWORD)(pCall->pCachedCallInfo))[1]),
  4486. pCall->pCachedCallInfo->dwUsedSize - sizeof(DWORD)
  4487. );
  4488. }
  4489. else
  4490. {
  4491. // Copy fixed size starting past the dwTotalSize field
  4492. CopyMemory(
  4493. (PBYTE)&(((PDWORD)lpCallInfo)[3]),
  4494. (PBYTE)&(((PDWORD)(pCall->pCachedCallInfo))[3]),
  4495. lpCallInfo->dwTotalSize - sizeof(DWORD)*3
  4496. );
  4497. lpCallInfo->dwNeededSize = pCall->pCachedCallInfo->dwUsedSize;
  4498. lpCallInfo->dwUsedSize = lpCallInfo->dwTotalSize;
  4499. //
  4500. // Zero the dwXxxSize fields so app won't try to read from them
  4501. // (& so tapi32.dll won't try to convert them from unicode to ascii)
  4502. //
  4503. lpCallInfo->dwCallerIDSize =
  4504. lpCallInfo->dwCallerIDNameSize =
  4505. lpCallInfo->dwCalledIDSize =
  4506. lpCallInfo->dwCalledIDNameSize =
  4507. lpCallInfo->dwConnectedIDSize =
  4508. lpCallInfo->dwConnectedIDNameSize =
  4509. lpCallInfo->dwRedirectionIDSize =
  4510. lpCallInfo->dwRedirectionIDNameSize =
  4511. lpCallInfo->dwRedirectingIDSize =
  4512. lpCallInfo->dwRedirectingIDNameSize =
  4513. lpCallInfo->dwAppNameSize =
  4514. lpCallInfo->dwDisplayableAddressSize =
  4515. lpCallInfo->dwCalledPartySize =
  4516. lpCallInfo->dwCommentSize =
  4517. lpCallInfo->dwDisplaySize =
  4518. lpCallInfo->dwUserUserInfoSize =
  4519. lpCallInfo->dwHighLevelCompSize =
  4520. lpCallInfo->dwLowLevelCompSize =
  4521. lpCallInfo->dwChargingInfoSize =
  4522. lpCallInfo->dwTerminalModesSize =
  4523. lpCallInfo->dwDevSpecificSize = 0;
  4524. if (pCall->pLine->dwXPIVersion >= TAPI_VERSION2_0)
  4525. {
  4526. lpCallInfo->dwCallDataSize =
  4527. lpCallInfo->dwSendingFlowspecSize =
  4528. lpCallInfo->dwReceivingFlowspecSize = 0;
  4529. }
  4530. }
  4531. pCall->dwCachedCallInfoCount++;
  4532. LeaveCriticalSection (&gCallListCriticalSection);
  4533. lResult = 0;
  4534. }
  4535. return( lResult );
  4536. }
  4537. LONG
  4538. TSPIAPI
  4539. TSPI_lineGetCallStatus(
  4540. HDRVCALL hdCall,
  4541. LPLINECALLSTATUS lpCallStatus
  4542. )
  4543. {
  4544. LONG lResult=0;
  4545. static REMOTE_ARG_TYPES argTypes[] =
  4546. {
  4547. Hdcall,
  4548. lpGet_Struct
  4549. };
  4550. ULONG_PTR args[] =
  4551. {
  4552. (ULONG_PTR) hdCall,
  4553. (ULONG_PTR) lpCallStatus
  4554. };
  4555. REMOTE_FUNC_ARGS funcArgs =
  4556. {
  4557. MAKELONG (LINE_FUNC | SYNC | 2, lGetCallStatus),
  4558. args,
  4559. argTypes
  4560. };
  4561. PDRVCALL pCall = (PDRVCALL)hdCall;
  4562. //
  4563. // Has the cached structure been invalidated?
  4564. //
  4565. EnterCriticalSection (&gCallListCriticalSection);
  4566. if (!IsValidObject (pCall, DRVCALL_KEY))
  4567. {
  4568. LeaveCriticalSection (&gCallListCriticalSection);
  4569. return LINEERR_INVALCALLHANDLE;
  4570. }
  4571. if ( ( pCall->dwDirtyStructs & STRUCTCHANGE_LINECALLSTATUS ) ||
  4572. ( pCall->dwCachedCallStatusCount > gdwCacheForceCallCount ) )
  4573. {
  4574. //
  4575. // The cache not valid, get the real info
  4576. //
  4577. LeaveCriticalSection (&gCallListCriticalSection);
  4578. lResult = (REMOTEDOFUNC (&funcArgs, "lineGetCallStatus"));
  4579. //
  4580. // Did the function succeed and was the entire struct returned?
  4581. //
  4582. if (
  4583. (ERROR_SUCCESS == lResult)
  4584. &&
  4585. (lpCallStatus->dwNeededSize <= lpCallStatus->dwTotalSize)
  4586. )
  4587. {
  4588. EnterCriticalSection (&gCallListCriticalSection);
  4589. if (!IsValidObject (pCall, DRVCALL_KEY))
  4590. {
  4591. LeaveCriticalSection (&gCallListCriticalSection);
  4592. return LINEERR_INVALCALLHANDLE;
  4593. }
  4594. //
  4595. // Did we already have a good pointer?
  4596. //
  4597. if ( pCall->pCachedCallStatus )
  4598. {
  4599. DrvFree( pCall->pCachedCallStatus );
  4600. }
  4601. pCall->pCachedCallStatus = DrvAlloc( lpCallStatus->dwUsedSize );
  4602. if ( pCall->pCachedCallStatus )
  4603. {
  4604. //
  4605. // Mark the cache data as clean
  4606. //
  4607. pCall->dwDirtyStructs &= ~STRUCTCHANGE_LINECALLSTATUS;
  4608. pCall->dwCachedCallStatusCount = 0;
  4609. CopyMemory( pCall->pCachedCallStatus,
  4610. lpCallStatus,
  4611. lpCallStatus->dwUsedSize
  4612. );
  4613. }
  4614. LeaveCriticalSection (&gCallListCriticalSection);
  4615. }
  4616. }
  4617. else
  4618. {
  4619. //
  4620. // The cache is valid, return data from there
  4621. //
  4622. if ( lpCallStatus->dwTotalSize >= pCall->pCachedCallStatus->dwUsedSize )
  4623. {
  4624. CopyMemory(
  4625. (PBYTE)&(((PDWORD)lpCallStatus)[1]),
  4626. (PBYTE)&(((PDWORD)(pCall->pCachedCallStatus))[1]),
  4627. pCall->pCachedCallStatus->dwUsedSize - sizeof(DWORD)
  4628. );
  4629. }
  4630. else
  4631. {
  4632. // Copy fixed size starting past the dwTotalSize field
  4633. CopyMemory(
  4634. (PBYTE)&(((PDWORD)lpCallStatus)[3]),
  4635. (PBYTE)&(((PDWORD)(pCall->pCachedCallStatus))[3]),
  4636. lpCallStatus->dwTotalSize - sizeof(DWORD)*3
  4637. );
  4638. lpCallStatus->dwNeededSize = pCall->pCachedCallStatus->dwUsedSize;
  4639. lpCallStatus->dwUsedSize = lpCallStatus->dwTotalSize;
  4640. //
  4641. // Zero the dwXxxSize fields so app won't try to read from them
  4642. //
  4643. lpCallStatus->dwDevSpecificSize = 0;
  4644. }
  4645. pCall->dwCachedCallStatusCount++;
  4646. LeaveCriticalSection (&gCallListCriticalSection);
  4647. lResult = 0;
  4648. }
  4649. return( lResult );
  4650. }
  4651. LONG
  4652. TSPIAPI
  4653. TSPI_lineGetDevCaps(
  4654. DWORD dwDeviceID,
  4655. DWORD dwTSPIVersion,
  4656. DWORD dwExtVersion,
  4657. LPLINEDEVCAPS lpLineDevCaps
  4658. )
  4659. {
  4660. LONG lResult;
  4661. static REMOTE_ARG_TYPES argTypes[] =
  4662. {
  4663. Dword,
  4664. LineID,
  4665. Dword,
  4666. Dword,
  4667. lpGet_Struct
  4668. };
  4669. ULONG_PTR args[] =
  4670. {
  4671. (ULONG_PTR) 0,
  4672. (ULONG_PTR) dwDeviceID,
  4673. (ULONG_PTR) dwTSPIVersion,
  4674. (ULONG_PTR) dwExtVersion,
  4675. (ULONG_PTR) lpLineDevCaps
  4676. };
  4677. REMOTE_FUNC_ARGS funcArgs =
  4678. {
  4679. MAKELONG (LINE_FUNC | SYNC | 5, lGetDevCaps),
  4680. args,
  4681. argTypes
  4682. };
  4683. PDRVLINE pLine = GetLineFromID (dwDeviceID);
  4684. if (NULL == pLine)
  4685. {
  4686. return LINEERR_BADDEVICEID;
  4687. }
  4688. args[0] = pLine->pServer->hLineApp;
  4689. lResult = REMOTEDOFUNC (&funcArgs, "lineGetDevCaps");
  4690. //
  4691. // We were munging the PermID in the original release of tapi 2.1.
  4692. // The intent was to make sure that we didn't present apps with
  4693. // overlapping id's (both local & remote), but none of our other service
  4694. // providers (i.e. unimdm, kmddsp) use the HIWORD(providerID) /
  4695. // LOWORD(devID) model, so it really doesn't do any good.
  4696. //
  4697. // if (lResult == 0)
  4698. // {
  4699. // lpLineDevCaps->dwPermanentLineID = MAKELONG(
  4700. // LOWORD(lpLineDevCaps->dwPermanentLineID),
  4701. // gdwPermanentProviderID
  4702. // );
  4703. // }
  4704. //
  4705. return lResult;
  4706. }
  4707. LONG
  4708. TSPIAPI
  4709. TSPI_lineGetDevConfig(
  4710. DWORD dwDeviceID,
  4711. LPVARSTRING lpDeviceConfig,
  4712. LPCWSTR lpszDeviceClass
  4713. )
  4714. {
  4715. static REMOTE_ARG_TYPES argTypes[] =
  4716. {
  4717. LineID,
  4718. lpGet_Struct,
  4719. lpsz
  4720. };
  4721. ULONG_PTR args[] =
  4722. {
  4723. (ULONG_PTR) dwDeviceID,
  4724. (ULONG_PTR) lpDeviceConfig,
  4725. (ULONG_PTR) lpszDeviceClass
  4726. };
  4727. REMOTE_FUNC_ARGS funcArgs =
  4728. {
  4729. MAKELONG (LINE_FUNC | SYNC | 3, lGetDevConfig),
  4730. args,
  4731. argTypes
  4732. };
  4733. return (REMOTEDOFUNC (&funcArgs, "lineGetDevConfig"));
  4734. }
  4735. LONG
  4736. TSPIAPI
  4737. TSPI_lineGetExtensionID(
  4738. DWORD dwDeviceID,
  4739. DWORD dwTSPIVersion,
  4740. LPLINEEXTENSIONID lpExtensionID
  4741. )
  4742. {
  4743. PDRVLINE pDrvLine = GetLineFromID (dwDeviceID);
  4744. if (NULL == pDrvLine)
  4745. {
  4746. return LINEERR_BADDEVICEID;
  4747. }
  4748. CopyMemory(
  4749. lpExtensionID,
  4750. &pDrvLine->ExtensionID,
  4751. sizeof (LINEEXTENSIONID)
  4752. );
  4753. return 0;
  4754. }
  4755. LONG
  4756. TSPIAPI
  4757. TSPI_lineGetGroupList(
  4758. DRV_REQUESTID dwRequestID,
  4759. HDRVLINE hdLine,
  4760. LPLINEAGENTGROUPLIST lpAgentGroupList
  4761. )
  4762. {
  4763. static REMOTE_ARG_TYPES argTypes[] =
  4764. {
  4765. Dword,
  4766. Dword,
  4767. Hdline,
  4768. Dword,
  4769. lpGet_Struct
  4770. };
  4771. ULONG_PTR args[] =
  4772. {
  4773. (ULONG_PTR) dwRequestID,
  4774. (ULONG_PTR) 0,
  4775. (ULONG_PTR) hdLine,
  4776. (ULONG_PTR) 0,
  4777. (ULONG_PTR) lpAgentGroupList
  4778. };
  4779. REMOTE_FUNC_ARGS funcArgs =
  4780. {
  4781. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 5, lGetGroupList),
  4782. args,
  4783. argTypes
  4784. };
  4785. PASYNCREQUESTCONTEXT pContext;
  4786. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  4787. {
  4788. return LINEERR_NOMEM;
  4789. }
  4790. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  4791. TSPI_lineGetAgentxxx_PostProcess;
  4792. pContext->Params[0] = (ULONG_PTR) lpAgentGroupList;
  4793. args[1] = (ULONG_PTR) pContext;
  4794. argTypes[1] = lpContext;
  4795. return (REMOTEDOFUNC (&funcArgs, "lineGetGroupList"));
  4796. }
  4797. LONG
  4798. TSPIAPI
  4799. TSPI_lineGetIcon(
  4800. DWORD dwDeviceID,
  4801. LPCWSTR lpszDeviceClass,
  4802. LPHICON lphIcon
  4803. )
  4804. {
  4805. *lphIcon = ghLineIcon;
  4806. return 0;
  4807. }
  4808. LONG
  4809. TSPIAPI
  4810. TSPI_lineGetID(
  4811. HDRVLINE hdLine,
  4812. DWORD dwAddressID,
  4813. HDRVCALL hdCall,
  4814. DWORD dwSelect,
  4815. LPVARSTRING lpDeviceID,
  4816. LPCWSTR lpszDeviceClass,
  4817. HANDLE hTargetProcess
  4818. )
  4819. {
  4820. //
  4821. // NOTE: Tapisrv will handle the "tapi/line" class
  4822. //
  4823. // NOTE: The "GetNewCalls" class is just for remotesp, & is
  4824. // special cased below
  4825. //
  4826. LONG lResult;
  4827. const WCHAR szGetNewCalls[] = L"GetNewCalls";
  4828. const WCHAR szTapiPhone[] = L"tapi/phone";
  4829. //
  4830. // The device ID for wave devices is meaningless on remote machines.
  4831. // Return op. unavailable
  4832. //
  4833. if (lpszDeviceClass &&
  4834. ( !_wcsicmp(lpszDeviceClass, L"wave/in") ||
  4835. !_wcsicmp(lpszDeviceClass, L"wave/out") ||
  4836. !_wcsicmp(lpszDeviceClass, L"midi/in") ||
  4837. !_wcsicmp(lpszDeviceClass, L"midi/out") ||
  4838. !_wcsicmp(lpszDeviceClass, L"wave/in/out")
  4839. )
  4840. )
  4841. {
  4842. return LINEERR_OPERATIONUNAVAIL;
  4843. }
  4844. if (lpDeviceID || // should be NULL if class == "GetNewCalls"
  4845. lstrcmpiW (lpszDeviceClass, szGetNewCalls))
  4846. {
  4847. REMOTE_ARG_TYPES argTypes[] =
  4848. {
  4849. Dword,
  4850. //(dwSelect == LINECALLSELECT_CALL ? Dword : Hdline),
  4851. Dword,
  4852. Dword,
  4853. //(dwSelect == LINECALLSELECT_CALL ? Hdcall : Dword),
  4854. Dword,
  4855. lpGet_Struct,
  4856. lpsz
  4857. };
  4858. ULONG_PTR args[] =
  4859. {
  4860. (ULONG_PTR) hdLine,
  4861. (ULONG_PTR) dwAddressID,
  4862. (ULONG_PTR) hdCall,
  4863. (ULONG_PTR) dwSelect,
  4864. (ULONG_PTR) lpDeviceID,
  4865. (ULONG_PTR) lpszDeviceClass
  4866. };
  4867. REMOTE_FUNC_ARGS funcArgs =
  4868. {
  4869. MAKELONG (LINE_FUNC | SYNC | 6, lGetID),
  4870. args,
  4871. argTypes
  4872. };
  4873. switch (dwSelect)
  4874. {
  4875. case LINECALLSELECT_CALL:
  4876. argTypes[2] = Hdcall;
  4877. break;
  4878. case LINECALLSELECT_ADDRESS:
  4879. case LINECALLSELECT_LINE:
  4880. argTypes[0] = Hdline;
  4881. break;
  4882. case LINECALLSELECT_DEVICEID:
  4883. break;
  4884. }
  4885. lResult = REMOTEDOFUNC (&funcArgs, "lineGetID");
  4886. //
  4887. // If success && dev class == "tapi/phone" && there was
  4888. // enough room in the device ID struct for a returned ID,
  4889. // then we need to map the 0-based server ID back to it's
  4890. // corresponding local ID.
  4891. //
  4892. if (lResult == 0 &&
  4893. lstrcmpiW (lpszDeviceClass, szTapiPhone) == 0 &&
  4894. lpDeviceID->dwUsedSize >= (sizeof (*lpDeviceID) + sizeof (DWORD)))
  4895. {
  4896. LPDWORD pdwPhoneID = (LPDWORD) (((LPBYTE) lpDeviceID) +
  4897. lpDeviceID->dwStringOffset);
  4898. PDRVPHONE pPhone;
  4899. PDRVSERVER pServer = ((PDRVLINE) hdLine)->pServer;
  4900. if ((pPhone = GetPhoneFromID (gdwPhoneDeviceIDBase + *pdwPhoneID)))
  4901. {
  4902. if (pPhone->pServer == pServer &&
  4903. pPhone->dwDeviceIDServer == *pdwPhoneID)
  4904. {
  4905. //
  4906. // The easy case - a direct mapping between the ID
  4907. // returned from the server & the index into the
  4908. // lookup table
  4909. //
  4910. *pdwPhoneID = pPhone->dwDeviceIDLocal;
  4911. }
  4912. else
  4913. {
  4914. //
  4915. // The hard case - have to walk the lookup table(s)
  4916. // looking for the matching device.
  4917. //
  4918. // We'll take the simplest, though slowest, route
  4919. // and start at the first entry of the first table.
  4920. // The good news is that there generally won't be
  4921. // many devices, and this request won't occur often.
  4922. //
  4923. DWORD i;
  4924. PDRVPHONELOOKUP pLookup = gpPhoneLookup;
  4925. while (pLookup)
  4926. {
  4927. for (i = 0; i < pLookup->dwUsedEntries; i++)
  4928. {
  4929. if (pLookup->aEntries[i].dwDeviceIDServer ==
  4930. *pdwPhoneID &&
  4931. pLookup->aEntries[i].pServer == pServer)
  4932. {
  4933. *pdwPhoneID =
  4934. pLookup->aEntries[i].dwDeviceIDLocal;
  4935. goto TSPI_lineGetID_return;
  4936. }
  4937. }
  4938. pLookup = pLookup->pNext;
  4939. }
  4940. //
  4941. // If here no matching local ID, so fail the request
  4942. //
  4943. lResult = LINEERR_OPERATIONFAILED;
  4944. }
  4945. }
  4946. else
  4947. {
  4948. lResult = LINEERR_OPERATIONFAILED;
  4949. }
  4950. }
  4951. }
  4952. else
  4953. {
  4954. //
  4955. // An app has done lineGetNewCalls for a remote line.
  4956. // We deal with this by retrieving any new calls for
  4957. // this line (or address), and indicating NEWCALL &
  4958. // CALLSTTE\UNKNOWN msgs to tapi.
  4959. //
  4960. // Note that hTargetProcess is really a pointer to the
  4961. // internal tapisrv!LineEventProc, which actually processes
  4962. // call state msgs, etc inline instead of queueing them for
  4963. // later processing like tapisrv!LineEventProcSP does.
  4964. // We want to submit the LINE_CALLSTATE msgs to this
  4965. // function to make sure they get processed right away
  4966. // so call monitors get created, etc before we return to
  4967. // the call function.
  4968. //
  4969. DWORD dwTotalSize;
  4970. LINECALLLIST fastCallList[2], *pCallList = fastCallList;
  4971. LINEEVENT internalLineEventProc = (LINEEVENT)
  4972. ((ULONG_PTR) hTargetProcess);
  4973. REMOTE_ARG_TYPES argTypes[] =
  4974. {
  4975. Hdline,
  4976. Dword,
  4977. Dword,
  4978. lpGet_Struct
  4979. };
  4980. ULONG_PTR args[] =
  4981. {
  4982. (ULONG_PTR) hdLine,
  4983. (ULONG_PTR) dwAddressID,
  4984. (ULONG_PTR) dwSelect,
  4985. (ULONG_PTR) 0
  4986. };
  4987. REMOTE_FUNC_ARGS funcArgs =
  4988. {
  4989. MAKELONG (LINE_FUNC | SYNC | 4, lGetNewCalls),
  4990. args,
  4991. argTypes
  4992. };
  4993. dwTotalSize = sizeof (fastCallList);
  4994. do
  4995. {
  4996. pCallList->dwTotalSize = dwTotalSize;
  4997. args[3] = (ULONG_PTR) pCallList;
  4998. lResult = REMOTEDOFUNC (&funcArgs, "lineGetNewCalls");
  4999. if (lResult == 0)
  5000. {
  5001. if (pCallList->dwNeededSize > pCallList->dwTotalSize)
  5002. {
  5003. //
  5004. // Get a bigger buffer & try again
  5005. //
  5006. dwTotalSize = pCallList->dwNeededSize + 4 * sizeof (HCALL);
  5007. if (pCallList != fastCallList)
  5008. {
  5009. DrvFree (pCallList);
  5010. }
  5011. if (!(pCallList = DrvAlloc (dwTotalSize)))
  5012. {
  5013. return LINEERR_NOMEM;
  5014. }
  5015. }
  5016. else
  5017. {
  5018. //
  5019. // We got all the info, so break
  5020. //
  5021. break;
  5022. }
  5023. }
  5024. } while (lResult == 0);
  5025. if (lResult == 0)
  5026. {
  5027. if (pCallList->dwCallsNumEntries == 0)
  5028. {
  5029. lResult = LINEERR_OPERATIONFAILED;
  5030. }
  5031. else
  5032. {
  5033. //
  5034. // For each returned call in the list indicate a NEWCALL
  5035. // & a CALLSTATE\UNKNOWN msg. (We could call over to the
  5036. // server to retrieve the current call state, call id's,
  5037. // etc, but that would be painful)
  5038. //
  5039. DWORD i;
  5040. LPHCALL phCall = (LPHCALL) (((LPBYTE) pCallList) +
  5041. pCallList->dwCallsOffset);
  5042. PDRVLINE pLine = (PDRVLINE) hdLine;
  5043. PDRVCALL pCall;
  5044. EnterCriticalSection (&gCallListCriticalSection);
  5045. if (pLine->htLine)
  5046. {
  5047. for (i = 0; i < pCallList->dwCallsNumEntries; i++,phCall++)
  5048. {
  5049. if ((pCall = DrvAlloc (sizeof (DRVCALL))))
  5050. {
  5051. pCall->hCall = *phCall;
  5052. pCall->dwInitialCallStateMode = 0xa5a5a5a5;
  5053. pCall->dwInitialPrivilege =
  5054. LINECALLPRIVILEGE_MONITOR;
  5055. #if MEMPHIS
  5056. #else
  5057. pCall->dwDirtyStructs |= STRUCTCHANGE_CALLIDS;
  5058. #endif
  5059. AddCallToList (pLine, pCall);
  5060. (*gpfnLineEventProc)(
  5061. pLine->htLine,
  5062. 0,
  5063. LINE_NEWCALL,
  5064. (ULONG_PTR) pCall,
  5065. (ULONG_PTR) &(pCall->htCall),
  5066. (ULONG_PTR) 0
  5067. );
  5068. if (!pCall->htCall)
  5069. {
  5070. //
  5071. // tapi was not able to create it's own inst
  5072. // to represent ths incoming call, perhaps
  5073. // because the line was closed, or out of
  5074. // memory. if the line was closed then we've
  5075. // already notified the remote server, and it
  5076. // should have destroyed the call client.
  5077. // otherwise, we probably want to do a
  5078. // closecall here or in a worker thread
  5079. //
  5080. static REMOTE_ARG_TYPES argTypes[] =
  5081. {
  5082. Hdcall
  5083. };
  5084. REMOTE_FUNC_ARGS funcArgs =
  5085. {
  5086. MAKELONG (LINE_FUNC | SYNC | 1, lDeallocateCall),
  5087. (ULONG_PTR *) &pCall,
  5088. argTypes
  5089. };
  5090. REMOTEDOFUNC (&funcArgs, "lineCloseCall");
  5091. RemoveCallFromList (pCall);
  5092. break;
  5093. }
  5094. //
  5095. // Note we call the internalLineEventProc here,
  5096. // using ghProvider as a key
  5097. //
  5098. (*internalLineEventProc)(
  5099. pLine->htLine,
  5100. pCall->htCall,
  5101. LINE_CALLSTATE,
  5102. (ULONG_PTR) LINECALLSTATE_UNKNOWN,
  5103. (ULONG_PTR) &pCall->dwInitialCallStateMode,
  5104. (ULONG_PTR) 0
  5105. );
  5106. }
  5107. else
  5108. {
  5109. break;
  5110. }
  5111. }
  5112. }
  5113. LeaveCriticalSection (&gCallListCriticalSection);
  5114. }
  5115. }
  5116. if (pCallList != fastCallList)
  5117. {
  5118. DrvFree (pCallList);
  5119. }
  5120. }
  5121. TSPI_lineGetID_return:
  5122. return lResult;
  5123. }
  5124. LONG
  5125. TSPIAPI
  5126. TSPI_lineGetLineDevStatus(
  5127. HDRVLINE hdLine,
  5128. LPLINEDEVSTATUS lpLineDevStatus
  5129. )
  5130. {
  5131. static REMOTE_ARG_TYPES argTypes[] =
  5132. {
  5133. Hdline,
  5134. lpGet_Struct
  5135. };
  5136. ULONG_PTR args[] =
  5137. {
  5138. (ULONG_PTR) hdLine,
  5139. (ULONG_PTR) lpLineDevStatus
  5140. };
  5141. REMOTE_FUNC_ARGS funcArgs =
  5142. {
  5143. MAKELONG (LINE_FUNC | SYNC | 2, lGetLineDevStatus),
  5144. args,
  5145. argTypes
  5146. };
  5147. return (REMOTEDOFUNC (&funcArgs, "lineGetLineDevStatus"));
  5148. }
  5149. LONG
  5150. TSPIAPI
  5151. TSPI_lineGetProxyStatus(
  5152. DWORD dwDeviceID,
  5153. DWORD dwAppAPIVersion,
  5154. LPLINEPROXYREQUESTLIST lpLineProxyReqestList
  5155. )
  5156. {
  5157. static REMOTE_ARG_TYPES argTypes[] =
  5158. {
  5159. Dword,
  5160. LineID,
  5161. Dword,
  5162. lpGet_Struct
  5163. };
  5164. ULONG_PTR args[] =
  5165. {
  5166. (ULONG_PTR) 0,
  5167. (ULONG_PTR) dwDeviceID,
  5168. (ULONG_PTR) dwAppAPIVersion,
  5169. (ULONG_PTR) lpLineProxyReqestList
  5170. };
  5171. REMOTE_FUNC_ARGS funcArgs =
  5172. {
  5173. MAKELONG (LINE_FUNC | SYNC | 4, lGetProxyStatus),
  5174. args,
  5175. argTypes
  5176. };
  5177. PDRVLINE pLine = GetLineFromID (dwDeviceID);
  5178. if (NULL == pLine)
  5179. {
  5180. return LINEERR_BADDEVICEID;
  5181. }
  5182. args[0] = pLine->pServer->hLineApp;
  5183. return (REMOTEDOFUNC (&funcArgs, "lineGetProxyStatus"));
  5184. }
  5185. LONG
  5186. TSPIAPI
  5187. TSPI_lineGetQueueInfo(
  5188. DRV_REQUESTID dwRequestID,
  5189. HDRVLINE hdLine,
  5190. DWORD dwQueueID,
  5191. LPLINEQUEUEINFO lpQueueInfo
  5192. )
  5193. {
  5194. static REMOTE_ARG_TYPES argTypes[] =
  5195. {
  5196. Dword,
  5197. Dword,
  5198. Hdline,
  5199. Dword,
  5200. Dword,
  5201. lpGet_Struct
  5202. };
  5203. ULONG_PTR args[] =
  5204. {
  5205. (ULONG_PTR) dwRequestID,
  5206. (ULONG_PTR) 0,
  5207. (ULONG_PTR) hdLine,
  5208. (ULONG_PTR) dwQueueID,
  5209. (ULONG_PTR) 0,
  5210. (ULONG_PTR) lpQueueInfo
  5211. };
  5212. REMOTE_FUNC_ARGS funcArgs =
  5213. {
  5214. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lGetQueueInfo),
  5215. args,
  5216. argTypes
  5217. };
  5218. PASYNCREQUESTCONTEXT pContext;
  5219. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  5220. {
  5221. return LINEERR_NOMEM;
  5222. }
  5223. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  5224. TSPI_lineGetAgentxxx_PostProcess;
  5225. pContext->Params[0] = (ULONG_PTR) lpQueueInfo;
  5226. args[1] = (ULONG_PTR) pContext;
  5227. argTypes[1] = lpContext;
  5228. return (REMOTEDOFUNC (&funcArgs, "lGetQueueInfo"));
  5229. }
  5230. LONG
  5231. TSPIAPI
  5232. TSPI_lineGetQueueList(
  5233. DRV_REQUESTID dwRequestID,
  5234. HDRVLINE hdLine,
  5235. GUID *pGroupID,
  5236. LPLINEQUEUELIST lpQueueList
  5237. )
  5238. {
  5239. static REMOTE_ARG_TYPES argTypes[] =
  5240. {
  5241. Dword,
  5242. Dword,
  5243. Hdline,
  5244. lpSet_SizeToFollow,
  5245. Size,
  5246. Dword,
  5247. lpGet_Struct
  5248. };
  5249. ULONG_PTR args[] =
  5250. {
  5251. (ULONG_PTR) dwRequestID,
  5252. (ULONG_PTR) 0,
  5253. (ULONG_PTR) hdLine,
  5254. (ULONG_PTR) pGroupID,
  5255. (ULONG_PTR) sizeof( GUID ),
  5256. (ULONG_PTR) 0,
  5257. (ULONG_PTR) lpQueueList
  5258. };
  5259. REMOTE_FUNC_ARGS funcArgs =
  5260. {
  5261. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 7, lGetQueueList),
  5262. args,
  5263. argTypes
  5264. };
  5265. PASYNCREQUESTCONTEXT pContext;
  5266. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  5267. {
  5268. return LINEERR_NOMEM;
  5269. }
  5270. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  5271. TSPI_lineGetAgentxxx_PostProcess;
  5272. pContext->Params[0] = (ULONG_PTR) lpQueueList;
  5273. args[1] = (ULONG_PTR) pContext;
  5274. argTypes[1] = lpContext;
  5275. return (REMOTEDOFUNC (&funcArgs, "lGetQueueList"));
  5276. }
  5277. LONG
  5278. TSPIAPI
  5279. TSPI_lineGetNumAddressIDs(
  5280. HDRVLINE hdLine,
  5281. LPDWORD lpdwNumAddressIDs
  5282. )
  5283. {
  5284. static REMOTE_ARG_TYPES argTypes[] =
  5285. {
  5286. Hdline,
  5287. lpDword
  5288. };
  5289. ULONG_PTR args[] =
  5290. {
  5291. (ULONG_PTR) hdLine,
  5292. (ULONG_PTR) lpdwNumAddressIDs
  5293. };
  5294. REMOTE_FUNC_ARGS funcArgs =
  5295. {
  5296. MAKELONG (LINE_FUNC | SYNC | 2, lGetNumAddressIDs),
  5297. args,
  5298. argTypes
  5299. };
  5300. return (REMOTEDOFUNC (&funcArgs, "lineGetNumAddressIDs"));
  5301. }
  5302. LONG
  5303. TSPIAPI
  5304. TSPI_lineHold(
  5305. DRV_REQUESTID dwRequestID,
  5306. HDRVCALL hdCall
  5307. )
  5308. {
  5309. static REMOTE_ARG_TYPES argTypes[] =
  5310. {
  5311. Dword,
  5312. Hdcall
  5313. };
  5314. ULONG_PTR args[] =
  5315. {
  5316. (ULONG_PTR) dwRequestID,
  5317. (ULONG_PTR) hdCall
  5318. };
  5319. REMOTE_FUNC_ARGS funcArgs =
  5320. {
  5321. MAKELONG (LINE_FUNC | ASYNC | 2, lHold),
  5322. args,
  5323. argTypes
  5324. };
  5325. return (REMOTEDOFUNC (&funcArgs, "lineHold"));
  5326. }
  5327. void
  5328. PASCAL
  5329. TSPI_lineMakeCall_PostProcess(
  5330. PASYNCEVENTMSG pMsg,
  5331. PASYNCREQUESTCONTEXT pContext
  5332. )
  5333. {
  5334. PDRVCALL pCall = (PDRVCALL) pContext->Params[0];
  5335. LOG((TL_INFO, "TSPI_lineMakeCall_PostProcess: enter"));
  5336. LOG((TL_INFO,
  5337. "\t\tp1=x%x, p2=x%x, p3=x%x, p4=x%x",
  5338. pMsg->Param1,
  5339. pMsg->Param2,
  5340. pMsg->Param3,
  5341. pMsg->Param4
  5342. ));
  5343. EnterCriticalSection (&gCallListCriticalSection);
  5344. if (!IsValidObject (pCall, DRVCALL_KEY) ||
  5345. (pCall->dwOriginalRequestID != pContext->dwOriginalRequestID))
  5346. {
  5347. LOG((TL_ERROR,
  5348. "TSPI_lineMakeCall_PostProcess: Bad pCall or ID - pCall x%lx",
  5349. pCall
  5350. ));
  5351. pMsg->Param2 = LINEERR_INVALLINEHANDLE;
  5352. }
  5353. else
  5354. {
  5355. if (pMsg->Param2 == 0)
  5356. {
  5357. if (pMsg->Param3 != 0)
  5358. {
  5359. // this is the normal success case
  5360. pCall->hCall = (HCALL) pMsg->Param3;
  5361. #if MEMPHIS
  5362. #else
  5363. if (pMsg->TotalSize >= (sizeof (*pMsg) + 3 * sizeof(ULONG_PTR)))
  5364. {
  5365. pCall->dwAddressID = (DWORD) *(&pMsg->Param4 + 1);
  5366. pCall->dwCallID = (DWORD) *(&pMsg->Param4 + 2);
  5367. pCall->dwRelatedCallID = (DWORD) *(&pMsg->Param4 + 3);
  5368. }
  5369. else
  5370. {
  5371. pCall->dwDirtyStructs |= STRUCTCHANGE_CALLIDS;
  5372. pCall->pServer->bVer2xServer = TRUE;
  5373. }
  5374. #endif
  5375. }
  5376. else
  5377. {
  5378. if (pContext->Params[1])
  5379. {
  5380. //
  5381. // This is the special lineforward case
  5382. // where we save the lphdCall in case
  5383. // we need to null it out
  5384. //
  5385. LPHDRVCALL lphdConsultCall = (LPHDRVCALL)
  5386. pContext->Params[1];
  5387. *lphdConsultCall = 0;
  5388. RemoveCallFromList (pCall);
  5389. }
  5390. else
  5391. {
  5392. }
  5393. }
  5394. }
  5395. else
  5396. {
  5397. RemoveCallFromList (pCall);
  5398. }
  5399. }
  5400. LeaveCriticalSection (&gCallListCriticalSection);
  5401. }
  5402. LONG
  5403. TSPIAPI
  5404. TSPI_lineMakeCall(
  5405. DRV_REQUESTID dwRequestID,
  5406. HDRVLINE hdLine,
  5407. HTAPICALL htCall,
  5408. LPHDRVCALL lphdCall,
  5409. LPCWSTR lpszDestAddress,
  5410. DWORD dwCountryCode,
  5411. LPLINECALLPARAMS const lpCallParams
  5412. )
  5413. {
  5414. static REMOTE_ARG_TYPES argTypes[] =
  5415. {
  5416. Dword,
  5417. Dword,
  5418. Hdline,
  5419. Dword,
  5420. lpsz,
  5421. Dword,
  5422. lpSet_Struct,
  5423. Dword
  5424. };
  5425. PDRVCALL pCall = DrvAlloc (sizeof (DRVCALL));
  5426. ULONG_PTR args[] =
  5427. {
  5428. (ULONG_PTR) DWORD_CAST(dwRequestID,__FILE__,__LINE__),
  5429. (ULONG_PTR) 0,
  5430. (ULONG_PTR) hdLine,
  5431. (ULONG_PTR) 0,
  5432. (ULONG_PTR) lpszDestAddress,
  5433. (ULONG_PTR) DWORD_CAST(dwCountryCode,__FILE__,__LINE__),
  5434. (ULONG_PTR) lpCallParams,
  5435. (ULONG_PTR) 0xffffffff // dwCallParamsCodePage
  5436. };
  5437. REMOTE_FUNC_ARGS funcArgs =
  5438. {
  5439. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 8, lMakeCall),
  5440. args,
  5441. argTypes
  5442. };
  5443. LONG lResult;
  5444. if (pCall)
  5445. {
  5446. PASYNCREQUESTCONTEXT pContext;
  5447. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  5448. {
  5449. DrvFree (pCall);
  5450. return LINEERR_NOMEM;
  5451. }
  5452. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  5453. TSPI_lineMakeCall_PostProcess;
  5454. pContext->Params[0] = (ULONG_PTR) pCall;
  5455. args[1] = (ULONG_PTR) pContext;
  5456. argTypes[1] = lpContext;
  5457. //
  5458. // Assume success & add the call to the line's list before we
  5459. // even make the request. This makes cleanup alot easier if
  5460. // the server goes down or some such uncooth event.
  5461. //
  5462. pCall->dwOriginalRequestID = dwRequestID;
  5463. pCall->htCall = htCall;
  5464. pCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  5465. AddCallToList ((PDRVLINE) hdLine, pCall);
  5466. *lphdCall = (HDRVCALL) pCall;
  5467. if ((lResult = REMOTEDOFUNC (&funcArgs, "lineMakeCall")) < 0)
  5468. {
  5469. RemoveCallFromList (pCall);
  5470. }
  5471. LOG((TL_INFO, "TSPI_lineMakeCall - new pCall x%lx", pCall));
  5472. }
  5473. else
  5474. {
  5475. lResult = LINEERR_NOMEM;
  5476. }
  5477. return lResult;
  5478. }
  5479. LONG
  5480. TSPIAPI
  5481. TSPI_lineMonitorDigits(
  5482. HDRVCALL hdCall,
  5483. DWORD dwDigitModes
  5484. )
  5485. {
  5486. static REMOTE_ARG_TYPES argTypes[] =
  5487. {
  5488. Hdcall,
  5489. Dword
  5490. };
  5491. ULONG_PTR args[] =
  5492. {
  5493. (ULONG_PTR) hdCall,
  5494. (ULONG_PTR) dwDigitModes
  5495. };
  5496. REMOTE_FUNC_ARGS funcArgs =
  5497. {
  5498. MAKELONG (LINE_FUNC | SYNC | 2, lMonitorDigits),
  5499. args,
  5500. argTypes
  5501. };
  5502. return (REMOTEDOFUNC (&funcArgs, "lineMonitorDigits"));
  5503. }
  5504. LONG
  5505. TSPIAPI
  5506. TSPI_lineMonitorMedia(
  5507. HDRVCALL hdCall,
  5508. DWORD dwMediaModes
  5509. )
  5510. {
  5511. static REMOTE_ARG_TYPES argTypes[] =
  5512. {
  5513. Hdcall,
  5514. Dword
  5515. };
  5516. ULONG_PTR args[] =
  5517. {
  5518. (ULONG_PTR) hdCall,
  5519. (ULONG_PTR) dwMediaModes
  5520. };
  5521. REMOTE_FUNC_ARGS funcArgs =
  5522. {
  5523. MAKELONG (LINE_FUNC | SYNC | 2, lMonitorMedia),
  5524. args,
  5525. argTypes
  5526. };
  5527. return (REMOTEDOFUNC (&funcArgs, "lineMonitorMedia"));
  5528. }
  5529. LONG
  5530. TSPIAPI
  5531. TSPI_lineMonitorTones(
  5532. HDRVCALL hdCall,
  5533. DWORD dwToneListID,
  5534. LPLINEMONITORTONE const lpToneList,
  5535. DWORD dwNumEntries
  5536. )
  5537. {
  5538. REMOTE_ARG_TYPES argTypes[] =
  5539. {
  5540. Hdcall,
  5541. lpSet_SizeToFollow,
  5542. Size,
  5543. Dword
  5544. };
  5545. ULONG_PTR args[] =
  5546. {
  5547. (ULONG_PTR) hdCall,
  5548. (ULONG_PTR) lpToneList,
  5549. (ULONG_PTR) dwNumEntries * sizeof (LINEMONITORTONE),
  5550. (ULONG_PTR) dwToneListID
  5551. };
  5552. REMOTE_FUNC_ARGS funcArgs =
  5553. {
  5554. MAKELONG (LINE_FUNC | SYNC | 4, lMonitorTones),
  5555. args,
  5556. argTypes
  5557. };
  5558. if (!lpToneList)
  5559. {
  5560. funcArgs.ArgTypes[1] = Dword;
  5561. funcArgs.Args[1] = TAPI_NO_DATA;
  5562. funcArgs.ArgTypes[2] = Dword;
  5563. }
  5564. return (REMOTEDOFUNC (&funcArgs, "lineMonitorTones"));
  5565. }
  5566. LONG
  5567. TSPIAPI
  5568. TSPI_lineNegotiateExtVersion(
  5569. DWORD dwDeviceID,
  5570. DWORD dwTSPIVersion,
  5571. DWORD dwLowVersion,
  5572. DWORD dwHighVersion,
  5573. LPDWORD lpdwExtVersion
  5574. )
  5575. {
  5576. static REMOTE_ARG_TYPES argTypes[] =
  5577. {
  5578. Dword,
  5579. LineID,
  5580. Dword,
  5581. Dword,
  5582. Dword,
  5583. lpDword
  5584. };
  5585. ULONG_PTR args[] =
  5586. {
  5587. (ULONG_PTR) 0,
  5588. (ULONG_PTR) dwDeviceID,
  5589. (ULONG_PTR) dwTSPIVersion,
  5590. (ULONG_PTR) dwLowVersion,
  5591. (ULONG_PTR) dwHighVersion,
  5592. (ULONG_PTR) lpdwExtVersion,
  5593. };
  5594. REMOTE_FUNC_ARGS funcArgs =
  5595. {
  5596. MAKELONG (LINE_FUNC | SYNC | 6, lNegotiateExtVersion),
  5597. args,
  5598. argTypes
  5599. };
  5600. PDRVLINE pLine = GetLineFromID (dwDeviceID);
  5601. if (NULL == pLine)
  5602. {
  5603. return LINEERR_BADDEVICEID;
  5604. }
  5605. args[0] = pLine->pServer->hLineApp;
  5606. return (REMOTEDOFUNC (&funcArgs, "lineNegotiateExtVersion"));
  5607. }
  5608. LONG
  5609. TSPIAPI
  5610. TSPI_lineNegotiateTSPIVersion(
  5611. DWORD dwDeviceID,
  5612. DWORD dwLowVersion,
  5613. DWORD dwHighVersion,
  5614. LPDWORD lpdwTSPIVersion
  5615. )
  5616. {
  5617. LONG lRet = 0;
  5618. //
  5619. // Check ghInst to ensure DllMain(DLL_PROCESS_ATTACH) has been called properly
  5620. //
  5621. if ( NULL == ghInst )
  5622. {
  5623. return LINEERR_OPERATIONFAILED;
  5624. }
  5625. if (dwDeviceID == INITIALIZE_NEGOTIATION)
  5626. {
  5627. *lpdwTSPIVersion = TAPI_VERSION_CURRENT;
  5628. }
  5629. else
  5630. {
  5631. try
  5632. {
  5633. *lpdwTSPIVersion = (GetLineFromID (dwDeviceID))->dwXPIVersion;
  5634. }
  5635. except (EXCEPTION_EXECUTE_HANDLER)
  5636. {
  5637. lRet = LINEERR_OPERATIONFAILED;
  5638. }
  5639. }
  5640. return lRet;
  5641. }
  5642. LONG
  5643. TSPIAPI
  5644. TSPI_lineOpen(
  5645. DWORD dwDeviceID,
  5646. HTAPILINE pParams, // Hack Alert! see below
  5647. LPHDRVLINE lphdLine,
  5648. DWORD dwTSPIVersion,
  5649. LINEEVENT lpfnEventProc
  5650. )
  5651. {
  5652. //
  5653. // Hack Alert!
  5654. //
  5655. // Tapisrv does a special case for remotesp and line open
  5656. // to pass in the privileges, etc - htLine is really pParams,
  5657. // pointing at a ULONG_PTR array containing the htLine,
  5658. // privileges, media modes, call params, & ext version
  5659. //
  5660. LONG lResult;
  5661. REMOTE_ARG_TYPES argTypes[] =
  5662. {
  5663. Dword, // hLineApp
  5664. LineID, // dev id
  5665. lpDword, // lphLine
  5666. Dword, // API version
  5667. Dword, // ext version
  5668. Dword, // callback inst
  5669. Dword, // privileges
  5670. Dword, // dw media modes
  5671. lpSet_Struct, // call params
  5672. Dword, // dwAsciiCallParamsCodePage
  5673. lpGet_CallParamsStruct,
  5674. Dword // remote hLine
  5675. };
  5676. PDRVLINE pLine = GetLineFromID (dwDeviceID);
  5677. ULONG_PTR args[] =
  5678. {
  5679. (ULONG_PTR) 0,
  5680. (ULONG_PTR) dwDeviceID,
  5681. (ULONG_PTR) 0,
  5682. (ULONG_PTR) dwTSPIVersion,
  5683. (ULONG_PTR) ((ULONG_PTR *) pParams)[4], // ext version
  5684. (ULONG_PTR) 0,
  5685. (ULONG_PTR) ((ULONG_PTR *) pParams)[1], // privilege(s)
  5686. (ULONG_PTR) ((ULONG_PTR *) pParams)[2], // media mode
  5687. (ULONG_PTR) ((ULONG_PTR *) pParams)[3], // pCallParams
  5688. (ULONG_PTR) 0xffffffff,
  5689. (ULONG_PTR) ((ULONG_PTR *) pParams)[3],
  5690. (ULONG_PTR) 0
  5691. };
  5692. REMOTE_FUNC_ARGS funcArgs =
  5693. {
  5694. MAKELONG (LINE_FUNC | SYNC | 12, lOpen),
  5695. args,
  5696. argTypes
  5697. };
  5698. if (NULL == pLine)
  5699. {
  5700. return LINEERR_BADDEVICEID;
  5701. }
  5702. args[0] = pLine->pServer->hLineApp;
  5703. args[2] = (ULONG_PTR)&pLine->hLine;
  5704. if (!(args[11] = NewObject (ghHandleTable, pLine, (LPVOID) 1)))
  5705. {
  5706. return LINEERR_NOMEM;
  5707. }
  5708. pLine->hDeviceCallback = (DWORD) args[11];
  5709. if ( (((ULONG_PTR *) pParams)[3] == 0) ||
  5710. (((ULONG_PTR *) pParams)[3] == TAPI_NO_DATA) )
  5711. {
  5712. argTypes[8] = Dword;
  5713. args[8] = TAPI_NO_DATA;
  5714. argTypes[10] = Dword;
  5715. args[10] = TAPI_NO_DATA;
  5716. }
  5717. pLine->dwKey = DRVLINE_KEY;
  5718. pLine->htLine = (HTAPILINE) (((ULONG_PTR *) pParams)[0]);
  5719. *lphdLine = (HDRVLINE) pLine;
  5720. lResult = REMOTEDOFUNC (&funcArgs, "lineOpen");
  5721. if (lResult != 0)
  5722. {
  5723. DereferenceObject (ghHandleTable, pLine->hDeviceCallback, 1);
  5724. if ((HIWORD(lResult) == RSP_CALLPARAMS))
  5725. {
  5726. //
  5727. // Hack Alert!
  5728. //
  5729. // If structure too small, give tapisrv the
  5730. // needed size in lphdLine
  5731. //
  5732. *lphdLine = (HDRVLINE)(LOWORD(lResult));
  5733. lResult = LINEERR_STRUCTURETOOSMALL;
  5734. }
  5735. }
  5736. return lResult;
  5737. }
  5738. void
  5739. PASCAL
  5740. TSPI_linePark_PostProcess(
  5741. PASYNCEVENTMSG pMsg,
  5742. PASYNCREQUESTCONTEXT pContext
  5743. )
  5744. {
  5745. LOG((TL_INFO, "lineParkPostProcess: enter"));
  5746. LOG((TL_INFO,
  5747. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  5748. pMsg->Param1,
  5749. pMsg->Param2,
  5750. pMsg->Param3,
  5751. pMsg->Param4
  5752. ));
  5753. if (pMsg->Param2 == 0)
  5754. {
  5755. DWORD dwSize = (DWORD) pMsg->Param4;
  5756. LPVARSTRING pNonDirAddress = (LPVARSTRING) pContext->Params[0];
  5757. CopyMemory (pNonDirAddress, (LPBYTE) (pMsg + 1), dwSize);
  5758. }
  5759. }
  5760. LONG
  5761. TSPIAPI
  5762. TSPI_linePark(
  5763. DRV_REQUESTID dwRequestID,
  5764. HDRVCALL hdCall,
  5765. DWORD dwParkMode,
  5766. LPCWSTR lpszDirAddress,
  5767. LPVARSTRING lpNonDirAddress
  5768. )
  5769. {
  5770. REMOTE_ARG_TYPES argTypes[] =
  5771. {
  5772. Dword,
  5773. Dword,
  5774. Hdcall,
  5775. Dword,
  5776. (dwParkMode == LINEPARKMODE_DIRECTED) ? lpsz : Dword,
  5777. Dword, // pass ptr as Dword for post processing
  5778. (lpNonDirAddress ? lpGet_Struct : Dword) // pass ptr as lpGet_Xx to retrieve dwTotalSize
  5779. };
  5780. ULONG_PTR args[] =
  5781. {
  5782. (ULONG_PTR) dwRequestID,
  5783. (ULONG_PTR) 0,
  5784. (ULONG_PTR) hdCall,
  5785. (ULONG_PTR) dwParkMode,
  5786. (ULONG_PTR) lpszDirAddress,
  5787. (ULONG_PTR) 0,
  5788. (ULONG_PTR) lpNonDirAddress
  5789. };
  5790. REMOTE_FUNC_ARGS funcArgs =
  5791. {
  5792. MAKELONG (LINE_FUNC | ASYNC | 7, lPark),
  5793. args,
  5794. argTypes
  5795. };
  5796. PASYNCREQUESTCONTEXT pContext;
  5797. if (dwParkMode == LINEPARKMODE_NONDIRECTED)
  5798. {
  5799. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  5800. {
  5801. return LINEERR_NOMEM;
  5802. }
  5803. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  5804. TSPI_linePark_PostProcess;
  5805. pContext->Params[0] = (ULONG_PTR) lpNonDirAddress;
  5806. args[1] = (ULONG_PTR) pContext;
  5807. argTypes[1] = lpContext;
  5808. funcArgs.Flags |= INCL_CONTEXT;
  5809. }
  5810. return (REMOTEDOFUNC (&funcArgs, "linePark"));
  5811. }
  5812. LONG
  5813. TSPIAPI
  5814. TSPI_linePickup(
  5815. DRV_REQUESTID dwRequestID,
  5816. HDRVLINE hdLine,
  5817. DWORD dwAddressID,
  5818. HTAPICALL htCall,
  5819. LPHDRVCALL lphdCall,
  5820. LPCWSTR lpszDestAddress,
  5821. LPCWSTR lpszGroupID
  5822. )
  5823. {
  5824. static REMOTE_ARG_TYPES argTypes[] =
  5825. {
  5826. Dword,
  5827. Dword,
  5828. Hdline,
  5829. Dword,
  5830. Dword,
  5831. lpsz,
  5832. lpsz
  5833. };
  5834. PDRVCALL pCall = DrvAlloc (sizeof (DRVCALL));
  5835. ULONG_PTR args[] =
  5836. {
  5837. (ULONG_PTR) dwRequestID,
  5838. (ULONG_PTR) 0,
  5839. (ULONG_PTR) hdLine,
  5840. (ULONG_PTR) dwAddressID,
  5841. (ULONG_PTR) 0,
  5842. (ULONG_PTR) lpszDestAddress,
  5843. (ULONG_PTR) lpszGroupID
  5844. };
  5845. REMOTE_FUNC_ARGS funcArgs =
  5846. {
  5847. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 7, lPickup),
  5848. args,
  5849. argTypes
  5850. };
  5851. LONG lResult;
  5852. if (pCall)
  5853. {
  5854. PASYNCREQUESTCONTEXT pContext;
  5855. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  5856. {
  5857. DrvFree (pCall);
  5858. return LINEERR_NOMEM;
  5859. }
  5860. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  5861. TSPI_lineMakeCall_PostProcess;
  5862. pContext->Params[0] = (ULONG_PTR) pCall;
  5863. args[1] = (ULONG_PTR) pContext;
  5864. argTypes[1] = lpContext;
  5865. pCall->htCall = htCall;
  5866. pCall->dwOriginalRequestID = dwRequestID;
  5867. pCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  5868. AddCallToList ((PDRVLINE) hdLine, pCall);
  5869. *lphdCall = (HDRVCALL) pCall;
  5870. if ((lResult = REMOTEDOFUNC (&funcArgs, "linePickup")) < 0)
  5871. {
  5872. RemoveCallFromList (pCall);
  5873. }
  5874. }
  5875. else
  5876. {
  5877. lResult = LINEERR_NOMEM;
  5878. }
  5879. return lResult;
  5880. }
  5881. LONG
  5882. TSPIAPI
  5883. TSPI_linePrepareAddToConference(
  5884. DRV_REQUESTID dwRequestID,
  5885. HDRVCALL hdConfCall,
  5886. HTAPICALL htConsultCall,
  5887. LPHDRVCALL lphdConsultCall,
  5888. LPLINECALLPARAMS const lpCallParams
  5889. )
  5890. {
  5891. static REMOTE_ARG_TYPES argTypes[] =
  5892. {
  5893. Dword,
  5894. Dword,
  5895. Hdcall,
  5896. Dword,
  5897. lpSet_Struct,
  5898. Dword
  5899. };
  5900. PDRVCALL pConsultCall = DrvAlloc (sizeof (DRVCALL));
  5901. ULONG_PTR args[] =
  5902. {
  5903. (ULONG_PTR) dwRequestID,
  5904. (ULONG_PTR) 0,
  5905. (ULONG_PTR) hdConfCall,
  5906. (ULONG_PTR) 0,
  5907. (ULONG_PTR) lpCallParams,
  5908. (ULONG_PTR) 0xffffffff // dwAsciiCallParamsCodePage
  5909. };
  5910. REMOTE_FUNC_ARGS funcArgs =
  5911. {
  5912. MAKELONG(LINE_FUNC | ASYNC | INCL_CONTEXT | 6,lPrepareAddToConference),
  5913. args,
  5914. argTypes
  5915. };
  5916. LONG lResult;
  5917. if (pConsultCall)
  5918. {
  5919. PASYNCREQUESTCONTEXT pContext;
  5920. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  5921. {
  5922. DrvFree (pConsultCall);
  5923. return LINEERR_NOMEM;
  5924. }
  5925. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  5926. TSPI_lineMakeCall_PostProcess;
  5927. pContext->Params[0] = (ULONG_PTR) pConsultCall;
  5928. args[1] = (ULONG_PTR) pContext;
  5929. argTypes[1] = lpContext;
  5930. pConsultCall->htCall = htConsultCall;
  5931. pConsultCall->dwOriginalRequestID = dwRequestID;
  5932. pConsultCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  5933. AddCallToList (((PDRVCALL) hdConfCall)->pLine, pConsultCall);
  5934. *lphdConsultCall = (HDRVCALL) pConsultCall;
  5935. if ((lResult = REMOTEDOFUNC (&funcArgs, "linePrepareAddToConference"))
  5936. < 0)
  5937. {
  5938. RemoveCallFromList (pConsultCall);
  5939. }
  5940. }
  5941. else
  5942. {
  5943. lResult = LINEERR_NOMEM;
  5944. }
  5945. return lResult;
  5946. }
  5947. LONG
  5948. TSPIAPI
  5949. TSPI_lineRedirect(
  5950. DRV_REQUESTID dwRequestID,
  5951. HDRVCALL hdCall,
  5952. LPCWSTR lpszDestAddress,
  5953. DWORD dwCountryCode
  5954. )
  5955. {
  5956. static REMOTE_ARG_TYPES argTypes[] =
  5957. {
  5958. Dword,
  5959. Hdcall,
  5960. lpsz,
  5961. Dword
  5962. };
  5963. ULONG_PTR args[] =
  5964. {
  5965. (ULONG_PTR) dwRequestID,
  5966. (ULONG_PTR) hdCall,
  5967. (ULONG_PTR) lpszDestAddress,
  5968. (ULONG_PTR) dwCountryCode
  5969. };
  5970. REMOTE_FUNC_ARGS funcArgs =
  5971. {
  5972. MAKELONG (LINE_FUNC | ASYNC | 4, lRedirect),
  5973. args,
  5974. argTypes
  5975. };
  5976. return (REMOTEDOFUNC (&funcArgs, "lineRedirect"));
  5977. }
  5978. LONG
  5979. TSPIAPI
  5980. TSPI_lineReleaseUserUserInfo(
  5981. DRV_REQUESTID dwRequestID,
  5982. HDRVCALL hdCall
  5983. )
  5984. {
  5985. static REMOTE_ARG_TYPES argTypes[] =
  5986. {
  5987. Dword,
  5988. Hdcall
  5989. };
  5990. ULONG_PTR args[] =
  5991. {
  5992. (ULONG_PTR) dwRequestID,
  5993. (ULONG_PTR) hdCall
  5994. };
  5995. REMOTE_FUNC_ARGS funcArgs =
  5996. {
  5997. MAKELONG (LINE_FUNC | ASYNC | 2, lReleaseUserUserInfo),
  5998. args,
  5999. argTypes
  6000. };
  6001. return (REMOTEDOFUNC (&funcArgs, "lineReleaseUserUserInfo"));
  6002. }
  6003. LONG
  6004. TSPIAPI
  6005. TSPI_lineRemoveFromConference(
  6006. DRV_REQUESTID dwRequestID,
  6007. HDRVCALL hdCall
  6008. )
  6009. {
  6010. static REMOTE_ARG_TYPES argTypes[] =
  6011. {
  6012. Dword,
  6013. Hdcall
  6014. };
  6015. ULONG_PTR args[] =
  6016. {
  6017. (ULONG_PTR) dwRequestID,
  6018. (ULONG_PTR) hdCall
  6019. };
  6020. REMOTE_FUNC_ARGS funcArgs =
  6021. {
  6022. MAKELONG (LINE_FUNC | ASYNC | 2, lRemoveFromConference),
  6023. args,
  6024. argTypes
  6025. };
  6026. return (REMOTEDOFUNC (&funcArgs, "lineRemoveFromConference"));
  6027. }
  6028. LONG
  6029. TSPIAPI
  6030. TSPI_lineSecureCall(
  6031. DRV_REQUESTID dwRequestID,
  6032. HDRVCALL hdCall
  6033. )
  6034. {
  6035. static REMOTE_ARG_TYPES argTypes[] =
  6036. {
  6037. Dword,
  6038. Hdcall
  6039. };
  6040. ULONG_PTR args[] =
  6041. {
  6042. (ULONG_PTR) dwRequestID,
  6043. (ULONG_PTR) hdCall
  6044. };
  6045. REMOTE_FUNC_ARGS funcArgs =
  6046. {
  6047. MAKELONG (LINE_FUNC | ASYNC | 2, lSecureCall),
  6048. args,
  6049. argTypes
  6050. };
  6051. return (REMOTEDOFUNC (&funcArgs, "lineSecureCall"));
  6052. }
  6053. LONG
  6054. TSPIAPI
  6055. TSPI_lineSelectExtVersion(
  6056. HDRVLINE hdLine,
  6057. DWORD dwExtVersion
  6058. )
  6059. {
  6060. static REMOTE_ARG_TYPES argTypes[] =
  6061. {
  6062. Hdline,
  6063. Dword
  6064. };
  6065. ULONG_PTR args[] =
  6066. {
  6067. (ULONG_PTR) hdLine,
  6068. (ULONG_PTR) dwExtVersion
  6069. };
  6070. REMOTE_FUNC_ARGS funcArgs =
  6071. {
  6072. MAKELONG (LINE_FUNC | SYNC | 2, lSelectExtVersion),
  6073. args,
  6074. argTypes
  6075. };
  6076. return (REMOTEDOFUNC (&funcArgs, "lineSelectExtVersion"));
  6077. }
  6078. LONG
  6079. TSPIAPI
  6080. TSPI_lineSendUserUserInfo(
  6081. DRV_REQUESTID dwRequestID,
  6082. HDRVCALL hdCall,
  6083. LPCSTR lpsUserUserInfo,
  6084. DWORD dwSize
  6085. )
  6086. {
  6087. static REMOTE_ARG_TYPES argTypes[] =
  6088. {
  6089. Dword,
  6090. Hdcall,
  6091. lpSet_SizeToFollow,
  6092. Size
  6093. };
  6094. ULONG_PTR args[] =
  6095. {
  6096. (ULONG_PTR) dwRequestID,
  6097. (ULONG_PTR) hdCall,
  6098. (ULONG_PTR) lpsUserUserInfo,
  6099. (ULONG_PTR) dwSize
  6100. };
  6101. REMOTE_FUNC_ARGS funcArgs =
  6102. {
  6103. MAKELONG (LINE_FUNC | ASYNC | 4, lSendUserUserInfo),
  6104. args,
  6105. argTypes
  6106. };
  6107. return (REMOTEDOFUNC (&funcArgs, "lineSendUserUserInfo"));
  6108. }
  6109. LONG
  6110. TSPIAPI
  6111. TSPI_lineSetAgentActivity(
  6112. DRV_REQUESTID dwRequestID,
  6113. HDRVLINE hdLine,
  6114. DWORD dwAddressID,
  6115. DWORD dwActivityID
  6116. )
  6117. {
  6118. static REMOTE_ARG_TYPES argTypes[] =
  6119. {
  6120. Dword,
  6121. Hdline,
  6122. Dword,
  6123. Dword
  6124. };
  6125. ULONG_PTR args[] =
  6126. {
  6127. (ULONG_PTR) dwRequestID,
  6128. (ULONG_PTR) hdLine,
  6129. (ULONG_PTR) dwAddressID,
  6130. (ULONG_PTR) dwActivityID
  6131. };
  6132. REMOTE_FUNC_ARGS funcArgs =
  6133. {
  6134. MAKELONG (LINE_FUNC | ASYNC | 4, lSetAgentActivity),
  6135. args,
  6136. argTypes
  6137. };
  6138. return (REMOTEDOFUNC (&funcArgs, "lineSetAgentActivity"));
  6139. }
  6140. LONG
  6141. TSPIAPI
  6142. TSPI_lineSetAgentGroup(
  6143. DRV_REQUESTID dwRequestID,
  6144. HDRVLINE hdLine,
  6145. DWORD dwAddressID,
  6146. LPLINEAGENTGROUPLIST lpAgentGroupList
  6147. )
  6148. {
  6149. static REMOTE_ARG_TYPES argTypes[] =
  6150. {
  6151. Dword,
  6152. Hdline,
  6153. Dword,
  6154. lpSet_Struct
  6155. };
  6156. ULONG_PTR args[] =
  6157. {
  6158. (ULONG_PTR) dwRequestID,
  6159. (ULONG_PTR) hdLine,
  6160. (ULONG_PTR) dwAddressID,
  6161. (ULONG_PTR) lpAgentGroupList
  6162. };
  6163. REMOTE_FUNC_ARGS funcArgs =
  6164. {
  6165. MAKELONG (LINE_FUNC | ASYNC | 4, lSetAgentGroup),
  6166. args,
  6167. argTypes
  6168. };
  6169. return (REMOTEDOFUNC (&funcArgs, "lineSetAgentGroup"));
  6170. }
  6171. LONG
  6172. TSPIAPI
  6173. TSPI_lineSetAgentMeasurementPeriod(
  6174. DRV_REQUESTID dwRequestID,
  6175. HDRVLINE hdLine,
  6176. HAGENT hAgent,
  6177. DWORD dwMeasurementPeriod
  6178. )
  6179. {
  6180. static REMOTE_ARG_TYPES argTypes[] =
  6181. {
  6182. Dword,
  6183. Hdline,
  6184. Dword,
  6185. Dword
  6186. };
  6187. ULONG_PTR args[] =
  6188. {
  6189. (ULONG_PTR) dwRequestID,
  6190. (ULONG_PTR) hdLine,
  6191. (ULONG_PTR) hAgent,
  6192. (ULONG_PTR) dwMeasurementPeriod
  6193. };
  6194. REMOTE_FUNC_ARGS funcArgs =
  6195. {
  6196. MAKELONG (LINE_FUNC | ASYNC | 4, lSetAgentMeasurementPeriod),
  6197. args,
  6198. argTypes
  6199. };
  6200. return (REMOTEDOFUNC (&funcArgs, "lineSetAgentMeasurementPeriod"));
  6201. }
  6202. LONG
  6203. TSPIAPI
  6204. TSPI_lineSetAgentSessionState(
  6205. DRV_REQUESTID dwRequestID,
  6206. HDRVLINE hdLine,
  6207. HAGENTSESSION hAgentSession,
  6208. DWORD dwAgentState,
  6209. DWORD dwNextAgentState
  6210. )
  6211. {
  6212. static REMOTE_ARG_TYPES argTypes[] =
  6213. {
  6214. Dword,
  6215. Hdline,
  6216. Dword,
  6217. Dword,
  6218. Dword
  6219. };
  6220. ULONG_PTR args[] =
  6221. {
  6222. (ULONG_PTR) dwRequestID,
  6223. (ULONG_PTR) hdLine,
  6224. (ULONG_PTR) hAgentSession,
  6225. (ULONG_PTR) dwAgentState,
  6226. (ULONG_PTR) dwNextAgentState
  6227. };
  6228. REMOTE_FUNC_ARGS funcArgs =
  6229. {
  6230. MAKELONG (LINE_FUNC | ASYNC | 5, lSetAgentSessionState),
  6231. args,
  6232. argTypes
  6233. };
  6234. return (REMOTEDOFUNC (&funcArgs, "lineSetAgentSessionState"));
  6235. }
  6236. LONG
  6237. TSPIAPI
  6238. TSPI_lineSetAgentState(
  6239. DRV_REQUESTID dwRequestID,
  6240. HDRVLINE hdLine,
  6241. DWORD dwAddressID,
  6242. DWORD dwAgentState,
  6243. DWORD dwNextAgentState
  6244. )
  6245. {
  6246. static REMOTE_ARG_TYPES argTypes[] =
  6247. {
  6248. Dword,
  6249. Hdline,
  6250. Dword,
  6251. Dword,
  6252. Dword
  6253. };
  6254. ULONG_PTR args[] =
  6255. {
  6256. (ULONG_PTR) dwRequestID,
  6257. (ULONG_PTR) hdLine,
  6258. (ULONG_PTR) dwAddressID,
  6259. (ULONG_PTR) dwAgentState,
  6260. (ULONG_PTR) dwNextAgentState
  6261. };
  6262. REMOTE_FUNC_ARGS funcArgs =
  6263. {
  6264. MAKELONG (LINE_FUNC | ASYNC | 5, lSetAgentState),
  6265. args,
  6266. argTypes
  6267. };
  6268. return (REMOTEDOFUNC (&funcArgs, "lineSetAgentState"));
  6269. }
  6270. LONG
  6271. TSPIAPI
  6272. TSPI_lineSetAgentStateEx(
  6273. DRV_REQUESTID dwRequestID,
  6274. HDRVLINE hdLine,
  6275. HAGENT hAgent,
  6276. DWORD dwAgentState,
  6277. DWORD dwNextAgentState
  6278. )
  6279. {
  6280. static REMOTE_ARG_TYPES argTypes[] =
  6281. {
  6282. Dword,
  6283. Hdline,
  6284. Dword,
  6285. Dword,
  6286. Dword
  6287. };
  6288. ULONG_PTR args[] =
  6289. {
  6290. (ULONG_PTR) dwRequestID,
  6291. (ULONG_PTR) hdLine,
  6292. (ULONG_PTR) hAgent,
  6293. (ULONG_PTR) dwAgentState,
  6294. (ULONG_PTR) dwNextAgentState
  6295. };
  6296. REMOTE_FUNC_ARGS funcArgs =
  6297. {
  6298. MAKELONG (LINE_FUNC | ASYNC | 5, lSetAgentStateEx),
  6299. args,
  6300. argTypes
  6301. };
  6302. return (REMOTEDOFUNC (&funcArgs, "lineSetAgentStateEx"));
  6303. }
  6304. LONG
  6305. TSPIAPI
  6306. TSPI_lineSetAppSpecific(
  6307. HDRVCALL hdCall,
  6308. DWORD dwAppSpecific
  6309. )
  6310. {
  6311. static REMOTE_ARG_TYPES argTypes[] =
  6312. {
  6313. Hdcall,
  6314. Dword
  6315. };
  6316. ULONG_PTR args[] =
  6317. {
  6318. (ULONG_PTR) hdCall,
  6319. (ULONG_PTR) dwAppSpecific
  6320. };
  6321. REMOTE_FUNC_ARGS funcArgs =
  6322. {
  6323. MAKELONG (LINE_FUNC | SYNC | 2, lSetAppSpecific),
  6324. args,
  6325. argTypes
  6326. };
  6327. return (REMOTEDOFUNC (&funcArgs, "lineSetAppSpecific"));
  6328. }
  6329. LONG
  6330. TSPIAPI
  6331. TSPI_lineSetCallData(
  6332. DRV_REQUESTID dwRequestID,
  6333. HDRVCALL hdCall,
  6334. LPVOID lpCallData,
  6335. DWORD dwSize
  6336. )
  6337. {
  6338. static REMOTE_ARG_TYPES argTypes[] =
  6339. {
  6340. Dword,
  6341. Hdcall,
  6342. lpSet_SizeToFollow,
  6343. Size
  6344. };
  6345. ULONG_PTR args[] =
  6346. {
  6347. (ULONG_PTR) dwRequestID,
  6348. (ULONG_PTR) hdCall,
  6349. (ULONG_PTR) lpCallData,
  6350. (ULONG_PTR) dwSize
  6351. };
  6352. REMOTE_FUNC_ARGS funcArgs =
  6353. {
  6354. MAKELONG (LINE_FUNC | ASYNC | 4, lSetCallData),
  6355. args,
  6356. argTypes
  6357. };
  6358. return (REMOTEDOFUNC (&funcArgs, "lineSetCallData"));
  6359. }
  6360. LONG
  6361. TSPIAPI
  6362. TSPI_lineSetCallHubTracking(
  6363. HDRVLINE hdLine,
  6364. LPLINECALLHUBTRACKINGINFO lpTrackingInfo
  6365. )
  6366. {
  6367. static REMOTE_ARG_TYPES argTypes[] =
  6368. {
  6369. Hdline,
  6370. lpSet_Struct
  6371. };
  6372. ULONG_PTR args[] =
  6373. {
  6374. (ULONG_PTR) hdLine,
  6375. (ULONG_PTR) lpTrackingInfo
  6376. };
  6377. REMOTE_FUNC_ARGS funcArgs =
  6378. {
  6379. MAKELONG (LINE_FUNC | SYNC | 2, lSetCallHubTracking),
  6380. args,
  6381. argTypes
  6382. };
  6383. return (REMOTEDOFUNC (&funcArgs, "lineSetCallHubTracking"));
  6384. }
  6385. LONG
  6386. TSPIAPI
  6387. TSPI_lineSetCallParams(
  6388. DRV_REQUESTID dwRequestID,
  6389. HDRVCALL hdCall,
  6390. DWORD dwBearerMode,
  6391. DWORD dwMinRate,
  6392. DWORD dwMaxRate,
  6393. LPLINEDIALPARAMS const lpDialParams
  6394. )
  6395. {
  6396. static REMOTE_ARG_TYPES argTypes[] =
  6397. {
  6398. Dword,
  6399. Hdcall,
  6400. Dword,
  6401. Dword,
  6402. Dword,
  6403. lpSet_SizeToFollow,
  6404. Size
  6405. };
  6406. ULONG_PTR args[] =
  6407. {
  6408. (ULONG_PTR) dwRequestID,
  6409. (ULONG_PTR) hdCall,
  6410. (ULONG_PTR) dwBearerMode,
  6411. (ULONG_PTR) dwMinRate,
  6412. (ULONG_PTR) dwMaxRate,
  6413. (ULONG_PTR) lpDialParams,
  6414. (ULONG_PTR) (lpDialParams ? sizeof (LINEDIALPARAMS) : 0)
  6415. };
  6416. REMOTE_FUNC_ARGS funcArgs =
  6417. {
  6418. MAKELONG (LINE_FUNC | ASYNC | 7, lSetCallParams),
  6419. args,
  6420. argTypes
  6421. };
  6422. return (REMOTEDOFUNC (&funcArgs, "lineSetCallParams"));
  6423. }
  6424. LONG
  6425. TSPIAPI
  6426. TSPI_lineSetCallQualityOfService(
  6427. DRV_REQUESTID dwRequestID,
  6428. HDRVCALL hdCall,
  6429. LPVOID lpSendingFlowspec,
  6430. DWORD dwSendingFlowspecSize,
  6431. LPVOID lpReceivingFlowspec,
  6432. DWORD dwReceivingFlowspecSize
  6433. )
  6434. {
  6435. static REMOTE_ARG_TYPES argTypes[] =
  6436. {
  6437. Dword,
  6438. Hdcall,
  6439. lpSet_SizeToFollow,
  6440. Size,
  6441. lpSet_SizeToFollow,
  6442. Size
  6443. };
  6444. ULONG_PTR args[] =
  6445. {
  6446. (ULONG_PTR) dwRequestID,
  6447. (ULONG_PTR) hdCall,
  6448. (ULONG_PTR) lpSendingFlowspec,
  6449. (ULONG_PTR) dwSendingFlowspecSize,
  6450. (ULONG_PTR) lpReceivingFlowspec,
  6451. (ULONG_PTR) dwReceivingFlowspecSize
  6452. };
  6453. REMOTE_FUNC_ARGS funcArgs =
  6454. {
  6455. MAKELONG (LINE_FUNC | ASYNC | 6, lSetCallQualityOfService),
  6456. args,
  6457. argTypes
  6458. };
  6459. return (REMOTEDOFUNC (&funcArgs, "lineSetCallQualityOfService"));
  6460. }
  6461. LONG
  6462. TSPIAPI
  6463. TSPI_lineSetCallTreatment(
  6464. DRV_REQUESTID dwRequestID,
  6465. HDRVCALL hdCall,
  6466. DWORD dwTreatment
  6467. )
  6468. {
  6469. static REMOTE_ARG_TYPES argTypes[] =
  6470. {
  6471. Dword,
  6472. Hdcall,
  6473. Dword
  6474. };
  6475. ULONG_PTR args[] =
  6476. {
  6477. (ULONG_PTR) dwRequestID,
  6478. (ULONG_PTR) hdCall,
  6479. (ULONG_PTR) dwTreatment
  6480. };
  6481. REMOTE_FUNC_ARGS funcArgs =
  6482. {
  6483. MAKELONG (LINE_FUNC | ASYNC | 3, lSetCallTreatment),
  6484. args,
  6485. argTypes
  6486. };
  6487. return (REMOTEDOFUNC (&funcArgs, "lineSetCallTreatment"));
  6488. }
  6489. LONG
  6490. TSPIAPI
  6491. TSPI_lineSetCurrentLocation(
  6492. DWORD dwLocation
  6493. )
  6494. {
  6495. return LINEERR_OPERATIONUNAVAIL;
  6496. }
  6497. LONG
  6498. TSPIAPI
  6499. TSPI_lineSetDefaultMediaDetection(
  6500. HDRVLINE hdLine,
  6501. DWORD dwMediaModes
  6502. )
  6503. {
  6504. static REMOTE_ARG_TYPES argTypes[] =
  6505. {
  6506. Hdline,
  6507. Dword
  6508. };
  6509. ULONG_PTR args[] =
  6510. {
  6511. (ULONG_PTR) hdLine,
  6512. (ULONG_PTR) dwMediaModes,
  6513. };
  6514. REMOTE_FUNC_ARGS funcArgs =
  6515. {
  6516. MAKELONG (LINE_FUNC | SYNC | 2, lSetDefaultMediaDetection),
  6517. args,
  6518. argTypes
  6519. };
  6520. return (REMOTEDOFUNC (&funcArgs, "lineSetDefaultMediaDetection"));
  6521. }
  6522. LONG
  6523. TSPIAPI
  6524. TSPI_lineSetDevConfig(
  6525. DWORD dwDeviceID,
  6526. LPVOID const lpDeviceConfig,
  6527. DWORD dwSize,
  6528. LPCWSTR lpszDeviceClass
  6529. )
  6530. {
  6531. static REMOTE_ARG_TYPES argTypes[] =
  6532. {
  6533. LineID,
  6534. lpSet_SizeToFollow,
  6535. Size,
  6536. lpsz
  6537. };
  6538. ULONG_PTR args[] =
  6539. {
  6540. (ULONG_PTR) dwDeviceID,
  6541. (ULONG_PTR) lpDeviceConfig,
  6542. (ULONG_PTR) dwSize,
  6543. (ULONG_PTR) lpszDeviceClass
  6544. };
  6545. REMOTE_FUNC_ARGS funcArgs =
  6546. {
  6547. MAKELONG (LINE_FUNC | SYNC | 4, lSetDevConfig),
  6548. args,
  6549. argTypes
  6550. };
  6551. return (REMOTEDOFUNC (&funcArgs, "lineSetDevConfig"));
  6552. }
  6553. LONG
  6554. TSPIAPI
  6555. TSPI_lineSetLineDevStatus(
  6556. DRV_REQUESTID dwRequestID,
  6557. HDRVLINE hdLine,
  6558. DWORD dwStatusToChange,
  6559. DWORD fStatus
  6560. )
  6561. {
  6562. static REMOTE_ARG_TYPES argTypes[] =
  6563. {
  6564. Dword,
  6565. Hdline,
  6566. Dword,
  6567. Dword
  6568. };
  6569. ULONG_PTR args[] =
  6570. {
  6571. (ULONG_PTR) dwRequestID,
  6572. (ULONG_PTR) hdLine,
  6573. (ULONG_PTR) dwStatusToChange,
  6574. (ULONG_PTR) fStatus
  6575. };
  6576. REMOTE_FUNC_ARGS funcArgs =
  6577. {
  6578. MAKELONG (LINE_FUNC | ASYNC | 4, lSetLineDevStatus),
  6579. args,
  6580. argTypes
  6581. };
  6582. return (REMOTEDOFUNC (&funcArgs, "lineSetLineDevStatus"));
  6583. }
  6584. LONG
  6585. TSPIAPI
  6586. TSPI_lineSetMediaControl(
  6587. HDRVLINE hdLine,
  6588. DWORD dwAddressID,
  6589. HDRVCALL hdCall,
  6590. DWORD dwSelect,
  6591. LPLINEMEDIACONTROLDIGIT const lpDigitList,
  6592. DWORD dwDigitNumEntries,
  6593. LPLINEMEDIACONTROLMEDIA const lpMediaList,
  6594. DWORD dwMediaNumEntries,
  6595. LPLINEMEDIACONTROLTONE const lpToneList,
  6596. DWORD dwToneNumEntries,
  6597. LPLINEMEDIACONTROLCALLSTATE const lpCallStateList,
  6598. DWORD dwCallStateNumEntries
  6599. )
  6600. {
  6601. REMOTE_ARG_TYPES argTypes[] =
  6602. {
  6603. (dwSelect == LINECALLSELECT_CALL ? Dword : Hdline),
  6604. Dword,
  6605. (dwSelect == LINECALLSELECT_CALL ? Hdcall : Dword),
  6606. Dword,
  6607. lpSet_SizeToFollow,
  6608. Size,
  6609. lpSet_SizeToFollow,
  6610. Size,
  6611. lpSet_SizeToFollow,
  6612. Size,
  6613. lpSet_SizeToFollow,
  6614. Size
  6615. };
  6616. ULONG_PTR args[] =
  6617. {
  6618. (ULONG_PTR) hdLine,
  6619. (ULONG_PTR) dwAddressID,
  6620. (ULONG_PTR) hdCall,
  6621. (ULONG_PTR) dwSelect,
  6622. (ULONG_PTR) lpDigitList,
  6623. (ULONG_PTR) dwDigitNumEntries,
  6624. (ULONG_PTR) lpMediaList,
  6625. (ULONG_PTR) dwMediaNumEntries,
  6626. (ULONG_PTR) lpToneList,
  6627. (ULONG_PTR) dwToneNumEntries,
  6628. (ULONG_PTR) lpCallStateList,
  6629. (ULONG_PTR) dwCallStateNumEntries
  6630. };
  6631. REMOTE_FUNC_ARGS funcArgs =
  6632. {
  6633. MAKELONG (LINE_FUNC | SYNC | 12, lSetMediaControl),
  6634. args,
  6635. argTypes
  6636. };
  6637. dwDigitNumEntries *= sizeof (LINEMEDIACONTROLDIGIT);
  6638. dwMediaNumEntries *= sizeof (LINEMEDIACONTROLMEDIA);
  6639. dwToneNumEntries *= sizeof (LINEMEDIACONTROLTONE);
  6640. dwCallStateNumEntries *= sizeof (LINEMEDIACONTROLCALLSTATE);
  6641. return (REMOTEDOFUNC (&funcArgs, "lineSetMediaControl"));
  6642. }
  6643. LONG
  6644. TSPIAPI
  6645. TSPI_lineSetMediaMode(
  6646. HDRVCALL hdCall,
  6647. DWORD dwMediaMode
  6648. )
  6649. {
  6650. static REMOTE_ARG_TYPES argTypes[] =
  6651. {
  6652. Hdcall,
  6653. Dword
  6654. };
  6655. ULONG_PTR args[] =
  6656. {
  6657. (ULONG_PTR) hdCall,
  6658. (ULONG_PTR) dwMediaMode
  6659. };
  6660. REMOTE_FUNC_ARGS funcArgs =
  6661. {
  6662. MAKELONG (LINE_FUNC | SYNC | 2, lSetMediaMode),
  6663. args,
  6664. argTypes
  6665. };
  6666. return (REMOTEDOFUNC (&funcArgs, "lineSetMediaMode"));
  6667. }
  6668. LONG
  6669. TSPIAPI
  6670. TSPI_lineSetQueueMeasurementPeriod(
  6671. DRV_REQUESTID dwRequestID,
  6672. HDRVLINE hdLine,
  6673. DWORD dwQueueID,
  6674. DWORD dwMeasurementPeriod
  6675. )
  6676. {
  6677. static REMOTE_ARG_TYPES argTypes[] =
  6678. {
  6679. Dword,
  6680. Hdline,
  6681. Dword,
  6682. Dword
  6683. };
  6684. ULONG_PTR args[] =
  6685. {
  6686. (ULONG_PTR) dwRequestID,
  6687. (ULONG_PTR) hdLine,
  6688. (ULONG_PTR) dwQueueID,
  6689. (ULONG_PTR) dwMeasurementPeriod
  6690. };
  6691. REMOTE_FUNC_ARGS funcArgs =
  6692. {
  6693. MAKELONG (LINE_FUNC | ASYNC | 4, lSetQueueMeasurementPeriod),
  6694. args,
  6695. argTypes
  6696. };
  6697. return (REMOTEDOFUNC (&funcArgs, "lineSetQueueMeasurementPeriod"));
  6698. }
  6699. LONG
  6700. TSPIAPI
  6701. TSPI_lineSetStatusMessages(
  6702. HDRVLINE hdLine,
  6703. DWORD dwLineStates,
  6704. DWORD dwAddressStates
  6705. )
  6706. {
  6707. static REMOTE_ARG_TYPES argTypes[] =
  6708. {
  6709. Hdline,
  6710. Dword,
  6711. Dword
  6712. };
  6713. ULONG_PTR args[] =
  6714. {
  6715. (ULONG_PTR) hdLine,
  6716. (ULONG_PTR) dwLineStates,
  6717. (ULONG_PTR) dwAddressStates
  6718. };
  6719. REMOTE_FUNC_ARGS funcArgs =
  6720. {
  6721. MAKELONG (LINE_FUNC | SYNC | 3, lSetStatusMessages),
  6722. args,
  6723. argTypes
  6724. };
  6725. return (REMOTEDOFUNC (&funcArgs, "lineSetStatusMessages"));
  6726. }
  6727. LONG
  6728. TSPIAPI
  6729. TSPI_lineSetTerminal(
  6730. DRV_REQUESTID dwRequestID,
  6731. HDRVLINE hdLine,
  6732. DWORD dwAddressID,
  6733. HDRVCALL hdCall,
  6734. DWORD dwSelect,
  6735. DWORD dwTerminalModes,
  6736. DWORD dwTerminalID,
  6737. DWORD bEnable
  6738. )
  6739. {
  6740. REMOTE_ARG_TYPES argTypes[] =
  6741. {
  6742. Dword,
  6743. (dwSelect == LINECALLSELECT_CALL ? Dword : Hdline),
  6744. Dword,
  6745. (dwSelect == LINECALLSELECT_CALL ? Hdcall : Dword),
  6746. Dword,
  6747. Dword,
  6748. Dword,
  6749. Dword
  6750. };
  6751. ULONG_PTR args[] =
  6752. {
  6753. (ULONG_PTR) dwRequestID,
  6754. (ULONG_PTR) hdLine,
  6755. (ULONG_PTR) dwAddressID,
  6756. (ULONG_PTR) hdCall,
  6757. (ULONG_PTR) dwSelect,
  6758. (ULONG_PTR) dwTerminalModes,
  6759. (ULONG_PTR) dwTerminalID,
  6760. (ULONG_PTR) bEnable
  6761. };
  6762. REMOTE_FUNC_ARGS funcArgs =
  6763. {
  6764. MAKELONG (LINE_FUNC | ASYNC | 8, lSetTerminal),
  6765. args,
  6766. argTypes
  6767. };
  6768. return (REMOTEDOFUNC (&funcArgs, "lineSetTerminal"));
  6769. }
  6770. void
  6771. PASCAL
  6772. TSPI_lineSetupConference_PostProcess(
  6773. PASYNCEVENTMSG pMsg,
  6774. PASYNCREQUESTCONTEXT pContext
  6775. )
  6776. {
  6777. PDRVCALL pConfCall = (PDRVCALL) pContext->Params[0],
  6778. pConsultCall = (PDRVCALL) pContext->Params[1];
  6779. LOG((TL_INFO, "TSPI_lineSetupConference_PostProcess: enter"));
  6780. EnterCriticalSection (&gCallListCriticalSection);
  6781. if (!IsValidObject (pConfCall, DRVCALL_KEY) ||
  6782. pConfCall->dwOriginalRequestID != pContext->dwOriginalRequestID)
  6783. {
  6784. LOG((TL_ERROR,"TSPI_lineSetupConference_PostProcess: Bad pConfCall dwID"));
  6785. pMsg->Param2 = LINEERR_INVALLINEHANDLE;
  6786. }
  6787. else
  6788. {
  6789. if (!IsValidObject (pConsultCall, DRVCALL_KEY) ||
  6790. pConsultCall->dwOriginalRequestID != pContext->dwOriginalRequestID)
  6791. {
  6792. //
  6793. // If here then the was closed & the calls have
  6794. // already been destroyed
  6795. //
  6796. LOG((TL_ERROR,
  6797. "TSPI_lineSetupConference_PostProcess: Bad pConsultCall dwID"
  6798. ));
  6799. pMsg->Param2 = LINEERR_INVALLINEHANDLE;
  6800. }
  6801. else
  6802. {
  6803. LOG((TL_INFO,
  6804. "\t\tp1=x%x, p2=x%x, p3=x%x",
  6805. pMsg->Param1,
  6806. pMsg->Param2,
  6807. pMsg->Param3
  6808. ));
  6809. LOG((TL_INFO,
  6810. "\t\tp4=x%x, p5=x%x, p6=x%x",
  6811. pMsg->Param4,
  6812. *(&pMsg->Param4 + 1),
  6813. pConsultCall
  6814. ));
  6815. if (pMsg->Param2 == 0)
  6816. {
  6817. HCALL hConfCall = (HCALL) pMsg->Param3,
  6818. hConsultCall = (HCALL) *(&pMsg->Param4 + 1);
  6819. pConfCall->hCall = hConfCall;
  6820. pConsultCall->hCall = hConsultCall;
  6821. #if MEMPHIS
  6822. #else
  6823. if (pMsg->TotalSize >= (sizeof (*pMsg) + 8 * sizeof (DWORD)))
  6824. {
  6825. pConfCall->dwAddressID = (DWORD) *(&pMsg->Param4 + 3);
  6826. pConfCall->dwCallID = (DWORD) *(&pMsg->Param4 + 4);
  6827. pConfCall->dwRelatedCallID = (DWORD) *(&pMsg->Param4 + 5);
  6828. pConsultCall->dwAddressID = (DWORD) *(&pMsg->Param4+6);
  6829. pConsultCall->dwCallID = (DWORD) *(&pMsg->Param4+7);
  6830. pConsultCall->dwRelatedCallID = (DWORD) *(&pMsg->Param4+8);
  6831. }
  6832. else
  6833. {
  6834. pConfCall->dwDirtyStructs |= STRUCTCHANGE_CALLIDS;
  6835. pConfCall->pServer->bVer2xServer = TRUE;
  6836. pConsultCall->dwDirtyStructs |= STRUCTCHANGE_CALLIDS;
  6837. }
  6838. #endif
  6839. }
  6840. else
  6841. {
  6842. RemoveCallFromList (pConfCall);
  6843. RemoveCallFromList (pConsultCall);
  6844. }
  6845. }
  6846. }
  6847. LeaveCriticalSection (&gCallListCriticalSection);
  6848. }
  6849. LONG
  6850. TSPIAPI
  6851. TSPI_lineSetupConference(
  6852. DRV_REQUESTID dwRequestID,
  6853. HDRVCALL hdCall,
  6854. HDRVLINE hdLine,
  6855. HTAPICALL htConfCall,
  6856. LPHDRVCALL lphdConfCall,
  6857. HTAPICALL htConsultCall,
  6858. LPHDRVCALL lphdConsultCall,
  6859. DWORD dwNumParties,
  6860. LPLINECALLPARAMS const lpCallParams
  6861. )
  6862. {
  6863. REMOTE_ARG_TYPES argTypes[] =
  6864. {
  6865. Dword,
  6866. Dword,
  6867. (hdCall ? Hdcall : Dword),
  6868. (hdCall ? Dword : Hdline),
  6869. Dword,
  6870. Dword,
  6871. Dword,
  6872. lpSet_Struct,
  6873. Dword
  6874. };
  6875. PDRVCALL pConfCall = DrvAlloc (sizeof (DRVCALL)),
  6876. pConsultCall = DrvAlloc (sizeof (DRVCALL));
  6877. ULONG_PTR args[] =
  6878. {
  6879. (ULONG_PTR) dwRequestID,
  6880. (ULONG_PTR) 0,
  6881. (ULONG_PTR) hdCall,
  6882. (ULONG_PTR) hdLine,
  6883. (ULONG_PTR) pConfCall,
  6884. (ULONG_PTR) pConsultCall,
  6885. (ULONG_PTR) dwNumParties,
  6886. (ULONG_PTR) lpCallParams,
  6887. (ULONG_PTR) 0xffffffff // dwAsciiCallParamsCodePage
  6888. };
  6889. REMOTE_FUNC_ARGS funcArgs =
  6890. {
  6891. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 9, lSetupConference),
  6892. args,
  6893. argTypes
  6894. };
  6895. LONG lResult;
  6896. if (pConfCall)
  6897. {
  6898. if (pConsultCall)
  6899. {
  6900. PDRVLINE pLine;
  6901. PASYNCREQUESTCONTEXT pContext;
  6902. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  6903. {
  6904. DrvFree (pConfCall);
  6905. DrvFree (pConsultCall);
  6906. return LINEERR_NOMEM;
  6907. }
  6908. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  6909. TSPI_lineSetupConference_PostProcess;
  6910. pContext->Params[0] = (ULONG_PTR) pConfCall;
  6911. pContext->Params[1] = (ULONG_PTR) pConsultCall;
  6912. args[1] = (ULONG_PTR) pContext;
  6913. argTypes[1] = lpContext;
  6914. pConfCall->htCall = htConfCall;
  6915. pConsultCall->htCall = htConsultCall;
  6916. pConfCall->dwOriginalRequestID = dwRequestID;
  6917. pConsultCall->dwOriginalRequestID = dwRequestID;
  6918. pConfCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  6919. pConsultCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  6920. if (hdCall)
  6921. {
  6922. EnterCriticalSection (&gCallListCriticalSection);
  6923. if (IsValidObject ((PVOID) hdCall, DRVCALL_KEY))
  6924. {
  6925. pLine = ((PDRVCALL) hdCall)->pLine;
  6926. }
  6927. else
  6928. {
  6929. LeaveCriticalSection (&gCallListCriticalSection);
  6930. DrvFree (pConfCall);
  6931. DrvFree (pConsultCall);
  6932. return LINEERR_INVALCALLHANDLE;
  6933. }
  6934. LeaveCriticalSection (&gCallListCriticalSection);
  6935. }
  6936. else
  6937. {
  6938. pLine = (PDRVLINE) hdLine;
  6939. }
  6940. AddCallToList (pLine, pConfCall);
  6941. AddCallToList (pLine, pConsultCall);
  6942. *lphdConfCall = (HDRVCALL) pConfCall;
  6943. *lphdConsultCall = (HDRVCALL) pConsultCall;
  6944. if ((lResult = REMOTEDOFUNC (&funcArgs, "lineSetupConference"))
  6945. < 0)
  6946. {
  6947. RemoveCallFromList (pConfCall);
  6948. RemoveCallFromList (pConsultCall);
  6949. }
  6950. }
  6951. else
  6952. {
  6953. DrvFree (pConfCall);
  6954. lResult = LINEERR_NOMEM;
  6955. }
  6956. }
  6957. else
  6958. {
  6959. lResult = LINEERR_NOMEM;
  6960. }
  6961. return lResult;
  6962. }
  6963. LONG
  6964. TSPIAPI
  6965. TSPI_lineSetupTransfer(
  6966. DRV_REQUESTID dwRequestID,
  6967. HDRVCALL hdCall,
  6968. HTAPICALL htConsultCall,
  6969. LPHDRVCALL lphdConsultCall,
  6970. LPLINECALLPARAMS const lpCallParams
  6971. )
  6972. {
  6973. REMOTE_ARG_TYPES argTypes[] =
  6974. {
  6975. Dword,
  6976. Dword,
  6977. Hdcall,
  6978. Dword,
  6979. lpSet_Struct,
  6980. Dword
  6981. };
  6982. PDRVCALL pConsultCall = DrvAlloc (sizeof (DRVCALL));
  6983. ULONG_PTR args[] =
  6984. {
  6985. (ULONG_PTR) dwRequestID,
  6986. (ULONG_PTR) 0,
  6987. (ULONG_PTR) hdCall,
  6988. (ULONG_PTR) 0,
  6989. (ULONG_PTR) lpCallParams,
  6990. (ULONG_PTR) 0xffffffff, // dwAsciiCallParamsCodePage
  6991. };
  6992. REMOTE_FUNC_ARGS funcArgs =
  6993. {
  6994. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lSetupTransfer),
  6995. args,
  6996. argTypes
  6997. };
  6998. LONG lResult;
  6999. if (pConsultCall)
  7000. {
  7001. PASYNCREQUESTCONTEXT pContext;
  7002. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  7003. {
  7004. DrvFree (pConsultCall);
  7005. return LINEERR_NOMEM;
  7006. }
  7007. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  7008. TSPI_lineMakeCall_PostProcess;
  7009. pContext->Params[0] = (ULONG_PTR) pConsultCall;
  7010. args[1] = (ULONG_PTR) pContext;
  7011. argTypes[1] = lpContext;
  7012. pConsultCall->dwOriginalRequestID = dwRequestID;
  7013. pConsultCall->htCall = htConsultCall;
  7014. pConsultCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  7015. AddCallToList (((PDRVCALL) hdCall)->pLine, pConsultCall);
  7016. *lphdConsultCall = (HDRVCALL) pConsultCall;
  7017. if ((lResult = REMOTEDOFUNC (&funcArgs, "lineSetupTransfer")) < 0)
  7018. {
  7019. RemoveCallFromList (pConsultCall);
  7020. }
  7021. }
  7022. else
  7023. {
  7024. lResult = LINEERR_NOMEM;
  7025. }
  7026. return lResult;
  7027. }
  7028. LONG
  7029. TSPIAPI
  7030. TSPI_lineSwapHold(
  7031. DRV_REQUESTID dwRequestID,
  7032. HDRVCALL hdActiveCall,
  7033. HDRVCALL hdHeldCall
  7034. )
  7035. {
  7036. static REMOTE_ARG_TYPES argTypes[] =
  7037. {
  7038. Dword,
  7039. Hdcall,
  7040. Hdcall
  7041. };
  7042. ULONG_PTR args[] =
  7043. {
  7044. (ULONG_PTR) dwRequestID,
  7045. (ULONG_PTR) hdActiveCall,
  7046. (ULONG_PTR) hdHeldCall
  7047. };
  7048. REMOTE_FUNC_ARGS funcArgs =
  7049. {
  7050. MAKELONG (LINE_FUNC | ASYNC | 3, lSwapHold),
  7051. args,
  7052. argTypes
  7053. };
  7054. return (REMOTEDOFUNC (&funcArgs, "lineSwapHold"));
  7055. }
  7056. LONG
  7057. TSPIAPI
  7058. TSPI_lineUncompleteCall(
  7059. DRV_REQUESTID dwRequestID,
  7060. HDRVLINE hdLine,
  7061. DWORD dwCompletionID
  7062. )
  7063. {
  7064. static REMOTE_ARG_TYPES argTypes[] =
  7065. {
  7066. Dword,
  7067. Hdline,
  7068. Dword
  7069. };
  7070. ULONG_PTR args[] =
  7071. {
  7072. (ULONG_PTR) dwRequestID,
  7073. (ULONG_PTR) hdLine,
  7074. (ULONG_PTR) dwCompletionID
  7075. };
  7076. REMOTE_FUNC_ARGS funcArgs =
  7077. {
  7078. MAKELONG (LINE_FUNC | ASYNC | 3, lUncompleteCall),
  7079. args,
  7080. argTypes
  7081. };
  7082. return (REMOTEDOFUNC (&funcArgs, "lineUncompleteCall"));
  7083. }
  7084. LONG
  7085. TSPIAPI
  7086. TSPI_lineUnhold(
  7087. DRV_REQUESTID dwRequestID,
  7088. HDRVCALL hdCall
  7089. )
  7090. {
  7091. static REMOTE_ARG_TYPES argTypes[] =
  7092. {
  7093. Dword,
  7094. Hdcall
  7095. };
  7096. ULONG_PTR args[] =
  7097. {
  7098. (ULONG_PTR) dwRequestID,
  7099. (ULONG_PTR) hdCall
  7100. };
  7101. REMOTE_FUNC_ARGS funcArgs =
  7102. {
  7103. MAKELONG (LINE_FUNC | ASYNC | 2, lUnhold),
  7104. args,
  7105. argTypes
  7106. };
  7107. return (REMOTEDOFUNC (&funcArgs, "lineUnhold"));
  7108. }
  7109. LONG
  7110. TSPIAPI
  7111. TSPI_lineUnpark(
  7112. DRV_REQUESTID dwRequestID,
  7113. HDRVLINE hdLine,
  7114. DWORD dwAddressID,
  7115. HTAPICALL htCall,
  7116. LPHDRVCALL lphdCall,
  7117. LPCWSTR lpszDestAddress
  7118. )
  7119. {
  7120. REMOTE_ARG_TYPES argTypes[] =
  7121. {
  7122. Dword,
  7123. Dword,
  7124. Hdline,
  7125. Dword,
  7126. Dword,
  7127. lpsz
  7128. };
  7129. PDRVCALL pCall = DrvAlloc (sizeof (DRVCALL));
  7130. ULONG_PTR args[] =
  7131. {
  7132. (ULONG_PTR) dwRequestID,
  7133. (ULONG_PTR) 0,
  7134. (ULONG_PTR) hdLine,
  7135. (ULONG_PTR) dwAddressID,
  7136. (ULONG_PTR) 0,
  7137. (ULONG_PTR) lpszDestAddress
  7138. };
  7139. REMOTE_FUNC_ARGS funcArgs =
  7140. {
  7141. MAKELONG (LINE_FUNC | ASYNC | INCL_CONTEXT | 6, lUnpark),
  7142. args,
  7143. argTypes
  7144. };
  7145. LONG lResult;
  7146. if (pCall)
  7147. {
  7148. PASYNCREQUESTCONTEXT pContext;
  7149. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  7150. {
  7151. DrvFree (pCall);
  7152. return LINEERR_NOMEM;
  7153. }
  7154. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  7155. TSPI_lineMakeCall_PostProcess;
  7156. pContext->Params[0] = (ULONG_PTR) pCall;
  7157. args[1] = (ULONG_PTR) pContext;
  7158. argTypes[1] = lpContext;
  7159. pCall->dwOriginalRequestID = dwRequestID;
  7160. pCall->htCall = htCall;
  7161. pCall->dwInitialPrivilege = LINECALLPRIVILEGE_OWNER;
  7162. AddCallToList ((PDRVLINE) hdLine, pCall);
  7163. *lphdCall = (HDRVCALL) pCall;
  7164. if ((lResult = REMOTEDOFUNC (&funcArgs, "lineUnpark")) < 0)
  7165. {
  7166. RemoveCallFromList (pCall);
  7167. }
  7168. }
  7169. else
  7170. {
  7171. lResult = LINEERR_NOMEM;
  7172. }
  7173. return lResult;
  7174. }
  7175. //
  7176. // -------------------------- TSPI_phoneXxx funcs -----------------------------
  7177. //
  7178. LONG
  7179. TSPIAPI
  7180. TSPI_phoneClose(
  7181. HDRVPHONE hdPhone
  7182. )
  7183. {
  7184. //
  7185. // Check if the hPhone is still valid (could have been zeroed
  7186. // out on PHONE_CLOSE, so no need to call server)
  7187. //
  7188. if (((PDRVPHONE) hdPhone)->hPhone)
  7189. {
  7190. static REMOTE_ARG_TYPES argTypes[] =
  7191. {
  7192. Hdphone
  7193. };
  7194. REMOTE_FUNC_ARGS funcArgs =
  7195. {
  7196. MAKELONG (PHONE_FUNC | SYNC | 1, pClose),
  7197. (ULONG_PTR *) &hdPhone,
  7198. argTypes
  7199. };
  7200. DereferenceObject(
  7201. ghHandleTable,
  7202. ((PDRVPHONE) hdPhone)->hDeviceCallback,
  7203. 1
  7204. );
  7205. EnterCriticalSection (&gCallListCriticalSection);
  7206. ((PDRVPHONE) hdPhone)->htPhone = 0;
  7207. ((PDRVPHONE) hdPhone)->hDeviceCallback = 0;
  7208. LeaveCriticalSection (&gCallListCriticalSection);
  7209. REMOTEDOFUNC (&funcArgs, "phoneClose");
  7210. }
  7211. return 0;
  7212. }
  7213. LONG
  7214. TSPIAPI
  7215. TSPI_phoneDevSpecific(
  7216. DRV_REQUESTID dwRequestID,
  7217. HDRVPHONE hdPhone,
  7218. LPVOID lpParams,
  7219. DWORD dwSize
  7220. )
  7221. {
  7222. static REMOTE_ARG_TYPES argTypes[] =
  7223. {
  7224. Dword,
  7225. Dword,
  7226. Hdphone,
  7227. Dword,
  7228. lpSet_SizeToFollow,
  7229. Size
  7230. };
  7231. ULONG_PTR args[] =
  7232. {
  7233. (ULONG_PTR) dwRequestID,
  7234. (ULONG_PTR) 0,
  7235. (ULONG_PTR) hdPhone,
  7236. (ULONG_PTR) 0,
  7237. (ULONG_PTR) lpParams, // pass data
  7238. (ULONG_PTR) dwSize
  7239. };
  7240. REMOTE_FUNC_ARGS funcArgs =
  7241. {
  7242. MAKELONG (PHONE_FUNC | ASYNC | INCL_CONTEXT | 6, pDevSpecific),
  7243. args,
  7244. argTypes
  7245. };
  7246. PASYNCREQUESTCONTEXT pContext;
  7247. if (!(pContext = DrvAlloc (sizeof (*pContext))))
  7248. {
  7249. return PHONEERR_NOMEM;
  7250. }
  7251. pContext->pfnPostProcessProc = (RSPPOSTPROCESSPROC)
  7252. TSPI_lineDevSpecific_PostProcess;
  7253. pContext->Params[0] = (ULONG_PTR) lpParams;
  7254. pContext->Params[1] = dwSize;
  7255. args[1] = (ULONG_PTR) pContext;
  7256. argTypes[1] = lpContext;
  7257. return (REMOTEDOFUNC (&funcArgs, "phoneDevSpecific"));
  7258. }
  7259. LONG
  7260. TSPIAPI
  7261. TSPI_phoneGetButtonInfo(
  7262. HDRVPHONE hdPhone,
  7263. DWORD dwButtonLampID,
  7264. LPPHONEBUTTONINFO lpButtonInfo
  7265. )
  7266. {
  7267. static REMOTE_ARG_TYPES argTypes[] =
  7268. {
  7269. Hdphone,
  7270. Dword,
  7271. lpGet_Struct
  7272. };
  7273. ULONG_PTR args[] =
  7274. {
  7275. (ULONG_PTR) hdPhone,
  7276. (ULONG_PTR) dwButtonLampID,
  7277. (ULONG_PTR) lpButtonInfo
  7278. };
  7279. REMOTE_FUNC_ARGS funcArgs =
  7280. {
  7281. MAKELONG (PHONE_FUNC | SYNC | 3, pGetButtonInfo),
  7282. args,
  7283. argTypes
  7284. };
  7285. return (REMOTEDOFUNC (&funcArgs, "phoneGetButtonInfo"));
  7286. }
  7287. LONG
  7288. TSPIAPI
  7289. TSPI_phoneGetData(
  7290. HDRVPHONE hdPhone,
  7291. DWORD dwDataID,
  7292. LPVOID lpData,
  7293. DWORD dwSize
  7294. )
  7295. {
  7296. static REMOTE_ARG_TYPES argTypes[] =
  7297. {
  7298. Hdphone,
  7299. Dword,
  7300. lpGet_SizeToFollow,
  7301. Size
  7302. };
  7303. ULONG_PTR args[] =
  7304. {
  7305. (ULONG_PTR) hdPhone,
  7306. (ULONG_PTR) dwDataID,
  7307. (ULONG_PTR) lpData,
  7308. (ULONG_PTR) dwSize
  7309. };
  7310. REMOTE_FUNC_ARGS funcArgs =
  7311. {
  7312. MAKELONG (PHONE_FUNC | SYNC | 4, pGetData),
  7313. args,
  7314. argTypes
  7315. };
  7316. return (REMOTEDOFUNC (&funcArgs, "phoneGetData"));
  7317. }
  7318. LONG
  7319. TSPIAPI
  7320. TSPI_phoneGetDevCaps(
  7321. DWORD dwDeviceID,
  7322. DWORD dwTSPIVersion,
  7323. DWORD dwExtVersion,
  7324. LPPHONECAPS lpPhoneCaps
  7325. )
  7326. {
  7327. LONG lResult;
  7328. static REMOTE_ARG_TYPES argTypes[] =
  7329. {
  7330. Dword,
  7331. PhoneID,
  7332. Dword,
  7333. Dword,
  7334. lpGet_Struct
  7335. };
  7336. ULONG_PTR args[] =
  7337. {
  7338. (ULONG_PTR) 0,
  7339. (ULONG_PTR) dwDeviceID,
  7340. (ULONG_PTR) dwTSPIVersion,
  7341. (ULONG_PTR) dwExtVersion,
  7342. (ULONG_PTR) lpPhoneCaps
  7343. };
  7344. REMOTE_FUNC_ARGS funcArgs =
  7345. {
  7346. MAKELONG (LINE_FUNC | SYNC | 5, pGetDevCaps),
  7347. args,
  7348. argTypes
  7349. };
  7350. PDRVPHONE pPhone = GetPhoneFromID (dwDeviceID);
  7351. if (NULL == pPhone)
  7352. {
  7353. return PHONEERR_BADDEVICEID;
  7354. }
  7355. args[0] = pPhone->pServer->hPhoneApp;
  7356. lResult = REMOTEDOFUNC (&funcArgs, "phoneGetDevCaps");
  7357. //
  7358. // We were munging the PermID in the original release of tapi 2.1.
  7359. // The intent was to make sure that we didn't present apps with
  7360. // overlapping id's (both local & remote), but none of our other service
  7361. // providers (i.e. unimdm, kmddsp) use the HIWORD(providerID) /
  7362. // LOWORD(devID) model, so it really doesn't do any good.
  7363. //
  7364. // if (lResult == 0)
  7365. // {
  7366. // lpPhoneCaps->dwPermanentPhoneID = MAKELONG(
  7367. // LOWORD(lpPhoneCaps->dwPermanentPhoneID),
  7368. // gdwPermanentProviderID
  7369. // );
  7370. // }
  7371. //
  7372. return lResult;
  7373. }
  7374. LONG
  7375. TSPIAPI
  7376. TSPI_phoneGetDisplay(
  7377. HDRVPHONE hdPhone,
  7378. LPVARSTRING lpDisplay
  7379. )
  7380. {
  7381. static REMOTE_ARG_TYPES argTypes[] =
  7382. {
  7383. Hdphone,
  7384. lpGet_Struct
  7385. };
  7386. ULONG_PTR args[] =
  7387. {
  7388. (ULONG_PTR) hdPhone,
  7389. (ULONG_PTR) lpDisplay
  7390. };
  7391. REMOTE_FUNC_ARGS funcArgs =
  7392. {
  7393. MAKELONG (PHONE_FUNC | SYNC | 2, pGetDisplay),
  7394. args,
  7395. argTypes
  7396. };
  7397. return (REMOTEDOFUNC (&funcArgs, "phoneGetDisplay"));
  7398. }
  7399. LONG
  7400. TSPIAPI
  7401. TSPI_phoneGetExtensionID(
  7402. DWORD dwDeviceID,
  7403. DWORD dwTSPIVersion,
  7404. LPPHONEEXTENSIONID lpExtensionID
  7405. )
  7406. {
  7407. PDRVPHONE pPhone = GetPhoneFromID (dwDeviceID);
  7408. if (NULL == pPhone)
  7409. {
  7410. return PHONEERR_BADDEVICEID;
  7411. }
  7412. CopyMemory(
  7413. lpExtensionID,
  7414. &pPhone->ExtensionID,
  7415. sizeof (PHONEEXTENSIONID)
  7416. );
  7417. return 0;
  7418. }
  7419. LONG
  7420. TSPIAPI
  7421. TSPI_phoneGetGain(
  7422. HDRVPHONE hdPhone,
  7423. DWORD dwHookSwitchDev,
  7424. LPDWORD lpdwGain
  7425. )
  7426. {
  7427. static REMOTE_ARG_TYPES argTypes[] =
  7428. {
  7429. Hdphone,
  7430. Dword,
  7431. lpDword
  7432. };
  7433. ULONG_PTR args[] =
  7434. {
  7435. (ULONG_PTR) hdPhone,
  7436. (ULONG_PTR) dwHookSwitchDev,
  7437. (ULONG_PTR) lpdwGain
  7438. };
  7439. REMOTE_FUNC_ARGS funcArgs =
  7440. {
  7441. MAKELONG (PHONE_FUNC | SYNC | 3, pGetGain),
  7442. args,
  7443. argTypes
  7444. };
  7445. return (REMOTEDOFUNC (&funcArgs, "phoneGetGain"));
  7446. }
  7447. LONG
  7448. TSPIAPI
  7449. TSPI_phoneGetHookSwitch(
  7450. HDRVPHONE hdPhone,
  7451. LPDWORD lpdwHookSwitchDevs
  7452. )
  7453. {
  7454. static REMOTE_ARG_TYPES argTypes[] =
  7455. {
  7456. Hdphone,
  7457. lpDword
  7458. };
  7459. ULONG_PTR args[] =
  7460. {
  7461. (ULONG_PTR) hdPhone,
  7462. (ULONG_PTR) lpdwHookSwitchDevs
  7463. };
  7464. REMOTE_FUNC_ARGS funcArgs =
  7465. {
  7466. MAKELONG (PHONE_FUNC | SYNC | 2, pGetHookSwitch),
  7467. args,
  7468. argTypes
  7469. };
  7470. return (REMOTEDOFUNC (&funcArgs, "phoneGetHookSwitch"));
  7471. }
  7472. LONG
  7473. TSPIAPI
  7474. TSPI_phoneGetIcon(
  7475. DWORD dwDeviceID,
  7476. LPCWSTR lpszDeviceClass,
  7477. LPHICON lphIcon
  7478. )
  7479. {
  7480. *lphIcon = ghPhoneIcon;
  7481. return 0;
  7482. }
  7483. LONG
  7484. TSPIAPI
  7485. TSPI_phoneGetID(
  7486. HDRVPHONE hdPhone,
  7487. LPVARSTRING lpDeviceID,
  7488. LPCWSTR lpszDeviceClass,
  7489. HANDLE hTargetProcess
  7490. )
  7491. {
  7492. //
  7493. // NOTE: Tapisrv will handle the "tapi/phone" class
  7494. //
  7495. LONG lResult;
  7496. static REMOTE_ARG_TYPES argTypes[] =
  7497. {
  7498. Hdphone,
  7499. lpGet_Struct,
  7500. lpsz
  7501. };
  7502. ULONG_PTR args[] =
  7503. {
  7504. (ULONG_PTR) hdPhone,
  7505. (ULONG_PTR) lpDeviceID,
  7506. (ULONG_PTR) lpszDeviceClass
  7507. };
  7508. REMOTE_FUNC_ARGS funcArgs =
  7509. {
  7510. MAKELONG (PHONE_FUNC | SYNC | 3, pGetID),
  7511. args,
  7512. argTypes
  7513. };
  7514. //
  7515. // The device ID for wave devices is meaningless on remote machines.
  7516. // Return op. unavailable
  7517. //
  7518. if (lpszDeviceClass &&
  7519. ( !_wcsicmp(lpszDeviceClass, L"wave/in") ||
  7520. !_wcsicmp(lpszDeviceClass, L"wave/out") ||
  7521. !_wcsicmp(lpszDeviceClass, L"midi/in") ||
  7522. !_wcsicmp(lpszDeviceClass, L"midi/out") ||
  7523. !_wcsicmp(lpszDeviceClass, L"wave/in/out")
  7524. )
  7525. )
  7526. {
  7527. return PHONEERR_OPERATIONUNAVAIL;
  7528. }
  7529. lResult = REMOTEDOFUNC (&funcArgs, "phoneGetID");
  7530. //
  7531. // If success && dev class == "tapi/line" && there was
  7532. // enough room in the device ID struct for a returned ID,
  7533. // then we need to map the 0-based server ID back to it's
  7534. // corresponding local ID.
  7535. //
  7536. if (lResult == 0 &&
  7537. lstrcmpiW (lpszDeviceClass, L"tapi/line") == 0 &&
  7538. lpDeviceID->dwUsedSize >= (sizeof (*lpDeviceID) + sizeof (DWORD)))
  7539. {
  7540. LPDWORD pdwLineID = (LPDWORD) (((LPBYTE) lpDeviceID) +
  7541. lpDeviceID->dwStringOffset);
  7542. PDRVLINE pLine;
  7543. PDRVSERVER pServer = ((PDRVPHONE) hdPhone)->pServer;
  7544. if ((pLine = GetLineFromID (gdwLineDeviceIDBase + *pdwLineID)))
  7545. {
  7546. if (pLine->pServer == pServer &&
  7547. pLine->dwDeviceIDServer == *pdwLineID)
  7548. {
  7549. //
  7550. // The easy case - a direct mapping between the ID
  7551. // returned from the server & the index into the
  7552. // lookup table
  7553. //
  7554. *pdwLineID = pLine->dwDeviceIDLocal;
  7555. }
  7556. else
  7557. {
  7558. //
  7559. // The hard case - have to walk the lookup table(s)
  7560. // looking for the matching device.
  7561. //
  7562. // We'll take the simplest, though slowest, route
  7563. // and start at the first entry of the first table.
  7564. // The good news is that there generally won't be
  7565. // many devices, and this request won't occur often.
  7566. //
  7567. DWORD i;
  7568. PDRVLINELOOKUP pLookup;
  7569. TapiEnterCriticalSection(&gCriticalSection);
  7570. pLookup = gpLineLookup;
  7571. while (pLookup)
  7572. {
  7573. for (i = 0; i < pLookup->dwUsedEntries; i++)
  7574. {
  7575. if (pLookup->aEntries[i].dwDeviceIDServer ==
  7576. *pdwLineID &&
  7577. pLookup->aEntries[i].pServer == pServer)
  7578. {
  7579. *pdwLineID = pLookup->aEntries[i].dwDeviceIDLocal;
  7580. TapiLeaveCriticalSection(&gCriticalSection);
  7581. goto TSPI_phoneGetID_return;
  7582. }
  7583. }
  7584. pLookup = pLookup->pNext;
  7585. }
  7586. TapiLeaveCriticalSection(&gCriticalSection);
  7587. //
  7588. // If here no matching local ID, so fail the request
  7589. //
  7590. lResult = PHONEERR_OPERATIONFAILED;
  7591. }
  7592. }
  7593. else
  7594. {
  7595. lResult = PHONEERR_OPERATIONFAILED;
  7596. }
  7597. }
  7598. TSPI_phoneGetID_return:
  7599. return lResult;
  7600. }
  7601. LONG
  7602. TSPIAPI
  7603. TSPI_phoneGetLamp(
  7604. HDRVPHONE hdPhone,
  7605. DWORD dwButtonLampID,
  7606. LPDWORD lpdwLampMode
  7607. )
  7608. {
  7609. static REMOTE_ARG_TYPES argTypes[] =
  7610. {
  7611. Hdphone,
  7612. Dword,
  7613. lpDword
  7614. };
  7615. ULONG_PTR args[] =
  7616. {
  7617. (ULONG_PTR) hdPhone,
  7618. (ULONG_PTR) dwButtonLampID,
  7619. (ULONG_PTR) lpdwLampMode
  7620. };
  7621. REMOTE_FUNC_ARGS funcArgs =
  7622. {
  7623. MAKELONG (PHONE_FUNC | SYNC | 3, pGetLamp),
  7624. args,
  7625. argTypes
  7626. };
  7627. return (REMOTEDOFUNC (&funcArgs, "phoneGetLamp"));
  7628. }
  7629. LONG
  7630. TSPIAPI
  7631. TSPI_phoneGetRing(
  7632. HDRVPHONE hdPhone,
  7633. LPDWORD lpdwRingMode,
  7634. LPDWORD lpdwVolume
  7635. )
  7636. {
  7637. static REMOTE_ARG_TYPES argTypes[] =
  7638. {
  7639. Hdphone,
  7640. lpDword,
  7641. lpDword
  7642. };
  7643. ULONG_PTR args[] =
  7644. {
  7645. (ULONG_PTR) hdPhone,
  7646. (ULONG_PTR) lpdwRingMode,
  7647. (ULONG_PTR) lpdwVolume
  7648. };
  7649. REMOTE_FUNC_ARGS funcArgs =
  7650. {
  7651. MAKELONG (PHONE_FUNC | SYNC | 3, pGetRing),
  7652. args,
  7653. argTypes
  7654. };
  7655. return (REMOTEDOFUNC (&funcArgs, "phoneGetRing"));
  7656. }
  7657. LONG
  7658. TSPIAPI
  7659. TSPI_phoneGetStatus(
  7660. HDRVPHONE hdPhone,
  7661. LPPHONESTATUS lpPhoneStatus
  7662. )
  7663. {
  7664. static REMOTE_ARG_TYPES argTypes[] =
  7665. {
  7666. Hdphone,
  7667. lpGet_Struct
  7668. };
  7669. ULONG_PTR args[] =
  7670. {
  7671. (ULONG_PTR) hdPhone,
  7672. (ULONG_PTR) lpPhoneStatus
  7673. };
  7674. REMOTE_FUNC_ARGS funcArgs =
  7675. {
  7676. MAKELONG (PHONE_FUNC | SYNC | 2, pGetStatus),
  7677. args,
  7678. argTypes
  7679. };
  7680. return (REMOTEDOFUNC (&funcArgs, "phoneGetStatus"));
  7681. }
  7682. LONG
  7683. TSPIAPI
  7684. TSPI_phoneGetVolume(
  7685. HDRVPHONE hdPhone,
  7686. DWORD dwHookSwitchDev,
  7687. LPDWORD lpdwVolume
  7688. )
  7689. {
  7690. static REMOTE_ARG_TYPES argTypes[] =
  7691. {
  7692. Hdphone,
  7693. Dword,
  7694. lpDword
  7695. };
  7696. ULONG_PTR args[] =
  7697. {
  7698. (ULONG_PTR) hdPhone,
  7699. (ULONG_PTR) dwHookSwitchDev,
  7700. (ULONG_PTR) lpdwVolume
  7701. };
  7702. REMOTE_FUNC_ARGS funcArgs =
  7703. {
  7704. MAKELONG (PHONE_FUNC | SYNC | 3, pGetVolume),
  7705. args,
  7706. argTypes
  7707. };
  7708. return (REMOTEDOFUNC (&funcArgs, "phoneGetVolume"));
  7709. }
  7710. LONG
  7711. TSPIAPI
  7712. TSPI_phoneNegotiateExtVersion(
  7713. DWORD dwDeviceID,
  7714. DWORD dwTSPIVersion,
  7715. DWORD dwLowVersion,
  7716. DWORD dwHighVersion,
  7717. LPDWORD lpdwExtVersion
  7718. )
  7719. {
  7720. static REMOTE_ARG_TYPES argTypes[] =
  7721. {
  7722. Dword,
  7723. PhoneID,
  7724. Dword,
  7725. Dword,
  7726. Dword,
  7727. lpDword
  7728. };
  7729. ULONG_PTR args[] =
  7730. {
  7731. (ULONG_PTR) 0,
  7732. (ULONG_PTR) dwDeviceID,
  7733. (ULONG_PTR) dwTSPIVersion,
  7734. (ULONG_PTR) dwLowVersion,
  7735. (ULONG_PTR) dwHighVersion,
  7736. (ULONG_PTR) lpdwExtVersion,
  7737. };
  7738. REMOTE_FUNC_ARGS funcArgs =
  7739. {
  7740. MAKELONG (LINE_FUNC | SYNC | 6, pNegotiateExtVersion),
  7741. args,
  7742. argTypes
  7743. };
  7744. PDRVPHONE pPhone = GetPhoneFromID (dwDeviceID);
  7745. if (NULL == pPhone)
  7746. {
  7747. return PHONEERR_BADDEVICEID;
  7748. }
  7749. args[0] = pPhone->pServer->hPhoneApp;
  7750. return (REMOTEDOFUNC (&funcArgs, "phoneNegotiateExtVersion"));
  7751. }
  7752. LONG
  7753. TSPIAPI
  7754. TSPI_phoneNegotiateTSPIVersion(
  7755. DWORD dwDeviceID,
  7756. DWORD dwLowVersion,
  7757. DWORD dwHighVersion,
  7758. LPDWORD lpdwTSPIVersion
  7759. )
  7760. {
  7761. LONG lRet = 0;
  7762. if (dwDeviceID == INITIALIZE_NEGOTIATION)
  7763. {
  7764. *lpdwTSPIVersion = TAPI_VERSION_CURRENT;
  7765. }
  7766. else
  7767. {
  7768. try
  7769. {
  7770. *lpdwTSPIVersion = (GetPhoneFromID (dwDeviceID))->dwXPIVersion;
  7771. }
  7772. except (EXCEPTION_EXECUTE_HANDLER)
  7773. {
  7774. lRet = PHONEERR_OPERATIONFAILED;
  7775. }
  7776. }
  7777. return lRet;
  7778. }
  7779. LONG
  7780. TSPIAPI
  7781. TSPI_phoneOpen(
  7782. DWORD dwDeviceID,
  7783. HTAPIPHONE pParams, // Hack Alert! See below
  7784. LPHDRVPHONE lphdPhone,
  7785. DWORD dwTSPIVersion,
  7786. PHONEEVENT lpfnEventProc
  7787. )
  7788. {
  7789. //
  7790. // Hack Alert!
  7791. //
  7792. // Tapisrv does a special case for remotesp and phone open
  7793. // to pass in the ext version - htPhone is really pParams,
  7794. // pointing at a ULONG_PTR array containing the htPhone &
  7795. // ext version
  7796. //
  7797. static REMOTE_ARG_TYPES argTypes[] =
  7798. {
  7799. Dword, // hPhoneApp
  7800. PhoneID, // dev id
  7801. lpDword, // lphPhone
  7802. Dword, // API version
  7803. Dword, // ext version
  7804. Dword, // callback inst
  7805. Dword, // privilege
  7806. Dword // remote hPhone
  7807. };
  7808. PDRVPHONE pPhone = GetPhoneFromID (dwDeviceID);
  7809. ULONG_PTR args[] =
  7810. {
  7811. (ULONG_PTR) 0,
  7812. (ULONG_PTR) dwDeviceID,
  7813. (ULONG_PTR) 0,
  7814. (ULONG_PTR) dwTSPIVersion,
  7815. (ULONG_PTR) ((ULONG_PTR *) pParams)[1], // ext version
  7816. (ULONG_PTR) 0,
  7817. (ULONG_PTR) PHONEPRIVILEGE_OWNER,
  7818. (ULONG_PTR) pPhone
  7819. };
  7820. REMOTE_FUNC_ARGS funcArgs =
  7821. {
  7822. MAKELONG (PHONE_FUNC | SYNC | 8, pOpen),
  7823. args,
  7824. argTypes
  7825. };
  7826. LONG lResult;
  7827. if (NULL == pPhone)
  7828. {
  7829. return PHONEERR_BADDEVICEID;
  7830. }
  7831. args[0] = pPhone->pServer->hPhoneApp;
  7832. args[2] = (ULONG_PTR)&pPhone->hPhone;
  7833. if (!(args[7] = NewObject (ghHandleTable, pPhone, (LPVOID) 1)))
  7834. {
  7835. return PHONEERR_NOMEM;
  7836. }
  7837. pPhone->hDeviceCallback = (DWORD) args[7];
  7838. pPhone->dwKey = DRVPHONE_KEY;
  7839. pPhone->htPhone = (HTAPIPHONE) ((ULONG_PTR *) pParams)[0];
  7840. *lphdPhone = (HDRVPHONE) pPhone;
  7841. lResult = REMOTEDOFUNC (&funcArgs, "phoneOpen");
  7842. if (lResult != 0)
  7843. {
  7844. DereferenceObject (ghHandleTable, pPhone->hDeviceCallback, 1);
  7845. }
  7846. return lResult;
  7847. }
  7848. LONG
  7849. TSPIAPI
  7850. TSPI_phoneSelectExtVersion(
  7851. HDRVPHONE hdPhone,
  7852. DWORD dwExtVersion
  7853. )
  7854. {
  7855. static REMOTE_ARG_TYPES argTypes[] =
  7856. {
  7857. Hdphone,
  7858. Dword
  7859. };
  7860. ULONG_PTR args[] =
  7861. {
  7862. (ULONG_PTR) hdPhone,
  7863. (ULONG_PTR) dwExtVersion
  7864. };
  7865. REMOTE_FUNC_ARGS funcArgs =
  7866. {
  7867. MAKELONG (PHONE_FUNC | SYNC | 2, pSelectExtVersion),
  7868. args,
  7869. argTypes
  7870. };
  7871. return (REMOTEDOFUNC (&funcArgs, "phoneSelectExtVersion"));
  7872. }
  7873. LONG
  7874. TSPIAPI
  7875. TSPI_phoneSetButtonInfo(
  7876. DRV_REQUESTID dwRequestID,
  7877. HDRVPHONE hdPhone,
  7878. DWORD dwButtonLampID,
  7879. LPPHONEBUTTONINFO const lpButtonInfo
  7880. )
  7881. {
  7882. static REMOTE_ARG_TYPES argTypes[] =
  7883. {
  7884. Dword,
  7885. Hdphone,
  7886. Dword,
  7887. lpSet_Struct
  7888. };
  7889. ULONG_PTR args[] =
  7890. {
  7891. (ULONG_PTR) dwRequestID,
  7892. (ULONG_PTR) hdPhone,
  7893. (ULONG_PTR) dwButtonLampID,
  7894. (ULONG_PTR) lpButtonInfo
  7895. };
  7896. REMOTE_FUNC_ARGS funcArgs =
  7897. {
  7898. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetButtonInfo),
  7899. args,
  7900. argTypes
  7901. };
  7902. return (REMOTEDOFUNC (&funcArgs, "phoneSetButtonInfo"));
  7903. }
  7904. LONG
  7905. TSPIAPI
  7906. TSPI_phoneSetData(
  7907. DRV_REQUESTID dwRequestID,
  7908. HDRVPHONE hdPhone,
  7909. DWORD dwDataID,
  7910. LPVOID const lpData,
  7911. DWORD dwSize
  7912. )
  7913. {
  7914. static REMOTE_ARG_TYPES argTypes[] =
  7915. {
  7916. Dword,
  7917. Hdphone,
  7918. Dword,
  7919. lpSet_SizeToFollow,
  7920. Size
  7921. };
  7922. ULONG_PTR args[] =
  7923. {
  7924. (ULONG_PTR) dwRequestID,
  7925. (ULONG_PTR) hdPhone,
  7926. (ULONG_PTR) dwDataID,
  7927. (ULONG_PTR) lpData,
  7928. (ULONG_PTR) dwSize
  7929. };
  7930. REMOTE_FUNC_ARGS funcArgs =
  7931. {
  7932. MAKELONG (PHONE_FUNC | ASYNC | 5, pSetData),
  7933. args,
  7934. argTypes
  7935. };
  7936. return (REMOTEDOFUNC (&funcArgs, "phoneSetData"));
  7937. }
  7938. LONG
  7939. TSPIAPI
  7940. TSPI_phoneSetDisplay(
  7941. DRV_REQUESTID dwRequestID,
  7942. HDRVPHONE hdPhone,
  7943. DWORD dwRow,
  7944. DWORD dwColumn,
  7945. LPCWSTR lpsDisplay,
  7946. DWORD dwSize
  7947. )
  7948. {
  7949. static REMOTE_ARG_TYPES argTypes[] =
  7950. {
  7951. Dword,
  7952. Hdphone,
  7953. Dword,
  7954. Dword,
  7955. lpSet_SizeToFollow,
  7956. Size
  7957. };
  7958. ULONG_PTR args[] =
  7959. {
  7960. (ULONG_PTR) dwRequestID,
  7961. (ULONG_PTR) hdPhone,
  7962. (ULONG_PTR) dwRow,
  7963. (ULONG_PTR) dwColumn,
  7964. (ULONG_PTR) lpsDisplay,
  7965. (ULONG_PTR) dwSize
  7966. };
  7967. REMOTE_FUNC_ARGS funcArgs =
  7968. {
  7969. MAKELONG (PHONE_FUNC | ASYNC | 6, pSetDisplay),
  7970. args,
  7971. argTypes
  7972. };
  7973. return (REMOTEDOFUNC (&funcArgs, "phoneSetDisplay"));
  7974. }
  7975. LONG
  7976. TSPIAPI
  7977. TSPI_phoneSetGain(
  7978. DRV_REQUESTID dwRequestID,
  7979. HDRVPHONE hdPhone,
  7980. DWORD dwHookSwitchDev,
  7981. DWORD dwGain
  7982. )
  7983. {
  7984. static REMOTE_ARG_TYPES argTypes[] =
  7985. {
  7986. Dword,
  7987. Hdphone,
  7988. Dword,
  7989. Dword
  7990. };
  7991. ULONG_PTR args[] =
  7992. {
  7993. (ULONG_PTR) dwRequestID,
  7994. (ULONG_PTR) hdPhone,
  7995. (ULONG_PTR) dwHookSwitchDev,
  7996. (ULONG_PTR) dwGain
  7997. };
  7998. REMOTE_FUNC_ARGS funcArgs =
  7999. {
  8000. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetGain),
  8001. args,
  8002. argTypes
  8003. };
  8004. return (REMOTEDOFUNC (&funcArgs, "phoneSetGain"));
  8005. }
  8006. LONG
  8007. TSPIAPI
  8008. TSPI_phoneSetHookSwitch(
  8009. DRV_REQUESTID dwRequestID,
  8010. HDRVPHONE hdPhone,
  8011. DWORD dwHookSwitchDevs,
  8012. DWORD dwHookSwitchMode
  8013. )
  8014. {
  8015. static REMOTE_ARG_TYPES argTypes[] =
  8016. {
  8017. Dword,
  8018. Hdphone,
  8019. Dword,
  8020. Dword
  8021. };
  8022. ULONG_PTR args[] =
  8023. {
  8024. (ULONG_PTR) dwRequestID,
  8025. (ULONG_PTR) hdPhone,
  8026. (ULONG_PTR) dwHookSwitchDevs,
  8027. (ULONG_PTR) dwHookSwitchMode
  8028. };
  8029. REMOTE_FUNC_ARGS funcArgs =
  8030. {
  8031. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetHookSwitch),
  8032. args,
  8033. argTypes
  8034. };
  8035. return (REMOTEDOFUNC (&funcArgs, "phoneSetHookswitch"));
  8036. }
  8037. LONG
  8038. TSPIAPI
  8039. TSPI_phoneSetLamp(
  8040. DRV_REQUESTID dwRequestID,
  8041. HDRVPHONE hdPhone,
  8042. DWORD dwButtonLampID,
  8043. DWORD dwLampMode
  8044. )
  8045. {
  8046. static REMOTE_ARG_TYPES argTypes[] =
  8047. {
  8048. Dword,
  8049. Hdphone,
  8050. Dword,
  8051. Dword
  8052. };
  8053. ULONG_PTR args[] =
  8054. {
  8055. (ULONG_PTR) dwRequestID,
  8056. (ULONG_PTR) hdPhone,
  8057. (ULONG_PTR) dwButtonLampID,
  8058. (ULONG_PTR) dwLampMode
  8059. };
  8060. REMOTE_FUNC_ARGS funcArgs =
  8061. {
  8062. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetLamp),
  8063. args,
  8064. argTypes
  8065. };
  8066. return (REMOTEDOFUNC (&funcArgs, "phoneSetLamp"));
  8067. }
  8068. LONG
  8069. TSPIAPI
  8070. TSPI_phoneSetRing(
  8071. DRV_REQUESTID dwRequestID,
  8072. HDRVPHONE hdPhone,
  8073. DWORD dwRingMode,
  8074. DWORD dwVolume
  8075. )
  8076. {
  8077. static REMOTE_ARG_TYPES argTypes[] =
  8078. {
  8079. Dword,
  8080. Hdphone,
  8081. Dword,
  8082. Dword
  8083. };
  8084. ULONG_PTR args[] =
  8085. {
  8086. (ULONG_PTR) dwRequestID,
  8087. (ULONG_PTR) hdPhone,
  8088. (ULONG_PTR) dwRingMode,
  8089. (ULONG_PTR) dwVolume
  8090. };
  8091. REMOTE_FUNC_ARGS funcArgs =
  8092. {
  8093. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetRing),
  8094. args,
  8095. argTypes
  8096. };
  8097. return (REMOTEDOFUNC (&funcArgs, "phoneSetRing"));
  8098. }
  8099. LONG
  8100. TSPIAPI
  8101. TSPI_phoneSetStatusMessages(
  8102. HDRVPHONE hdPhone,
  8103. DWORD dwPhoneStates,
  8104. DWORD dwButtonModes,
  8105. DWORD dwButtonStates
  8106. )
  8107. {
  8108. static REMOTE_ARG_TYPES argTypes[] =
  8109. {
  8110. Hdphone,
  8111. Dword,
  8112. Dword,
  8113. Dword
  8114. };
  8115. ULONG_PTR args[] =
  8116. {
  8117. (ULONG_PTR) hdPhone,
  8118. (ULONG_PTR) dwPhoneStates,
  8119. (ULONG_PTR) dwButtonModes,
  8120. (ULONG_PTR) dwButtonStates
  8121. };
  8122. REMOTE_FUNC_ARGS funcArgs =
  8123. {
  8124. MAKELONG (PHONE_FUNC | SYNC | 4, pSetStatusMessages),
  8125. args,
  8126. argTypes
  8127. };
  8128. return (REMOTEDOFUNC (&funcArgs, "phoneSetStatusMessages"));
  8129. }
  8130. LONG
  8131. TSPIAPI
  8132. TSPI_phoneSetVolume(
  8133. DRV_REQUESTID dwRequestID,
  8134. HDRVPHONE hdPhone,
  8135. DWORD dwHookSwitchDev,
  8136. DWORD dwVolume
  8137. )
  8138. {
  8139. static REMOTE_ARG_TYPES argTypes[] =
  8140. {
  8141. Dword,
  8142. Hdphone,
  8143. Dword,
  8144. Dword
  8145. };
  8146. ULONG_PTR args[] =
  8147. {
  8148. (ULONG_PTR) dwRequestID,
  8149. (ULONG_PTR) hdPhone,
  8150. (ULONG_PTR) dwHookSwitchDev,
  8151. (ULONG_PTR) dwVolume
  8152. };
  8153. REMOTE_FUNC_ARGS funcArgs =
  8154. {
  8155. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetVolume),
  8156. args,
  8157. argTypes
  8158. };
  8159. return (REMOTEDOFUNC (&funcArgs, "phoneSetVolume"));
  8160. }
  8161. //
  8162. // ------------------------- TSPI_providerXxx funcs ---------------------------
  8163. //
  8164. LONG
  8165. TSPIAPI
  8166. TSPI_providerCheckForNewUser(
  8167. DWORD dwPermanentProviderID
  8168. )
  8169. {
  8170. //
  8171. // This func gets called when a new process attaches to TAPISRV.
  8172. // We take advantage of this notification by checking to see if
  8173. // we've previously gone through full initialization, and if not
  8174. // (because previously attached processes were running in the
  8175. // system account which didn't allow for net access, and there
  8176. // was no logged on user to impersonate) then we try again here.
  8177. //
  8178. // Note that TAPISRV serializes calls to this func along with calls
  8179. // to init & shutdown, so we don't have to worry about serialization
  8180. // ourselves.
  8181. //
  8182. #if MEMPHIS
  8183. #else
  8184. if (!gbInitialized)
  8185. {
  8186. LONG lResult;
  8187. DWORD dwNumLines, dwNumPhones;
  8188. LOG((TL_INFO,
  8189. "TSPI_providerCheckForNewUser: trying deferred init..."
  8190. ));
  8191. lResult = TSPI_providerEnumDevices(
  8192. 0xffffffff,
  8193. &dwNumLines,
  8194. &dwNumPhones,
  8195. 0,
  8196. NULL,
  8197. NULL
  8198. );
  8199. if (lResult == 1)
  8200. {
  8201. lResult = TSPI_providerInit(
  8202. TAPI_VERSION_CURRENT,
  8203. 0xffffffff, // dwPermanentProviderID,
  8204. 0, // dwLineDeviceIDBase,
  8205. 0, // dwPhoneDeviceIDBase,
  8206. 0, // dwNumLines,
  8207. 0, // dwNumPhones,
  8208. NULL, // lpfnCompletionProc,
  8209. NULL // lpdwTSPIOptions
  8210. );
  8211. LOG((TL_INFO,
  8212. "TSPI_providerCheckForNewUser: deferred Init result=x%x",
  8213. lResult
  8214. ));
  8215. }
  8216. }
  8217. #endif
  8218. return 0;
  8219. }
  8220. LONG
  8221. TSPIAPI
  8222. TSPI_providerConfig(
  8223. HWND hwndOwner,
  8224. DWORD dwPermanentProviderID
  8225. )
  8226. {
  8227. //
  8228. // Although this func is never called by TAPI v2.0, we export
  8229. // it so that the Telephony Control Panel Applet knows that it
  8230. // can configure this provider via lineConfigProvider(),
  8231. // otherwise Telephon.cpl will not consider it configurable
  8232. //
  8233. // for this release, we do not implement provider UI functions
  8234. return LINEERR_OPERATIONFAILED;
  8235. }
  8236. LONG
  8237. TSPIAPI
  8238. TSPI_providerCreateLineDevice(
  8239. ULONG_PTR TempID,
  8240. DWORD dwDeviceID
  8241. )
  8242. {
  8243. PDRVLINE pLine = GetLineFromID ((DWORD) TempID);
  8244. if (NULL == pLine)
  8245. {
  8246. return LINEERR_BADDEVICEID;
  8247. }
  8248. pLine->dwDeviceIDLocal = dwDeviceID;
  8249. if (pLine->dwXPIVersion == 0)
  8250. {
  8251. static REMOTE_ARG_TYPES argTypes[] =
  8252. {
  8253. Dword,
  8254. LineID,
  8255. Dword,
  8256. Dword,
  8257. lpDword,
  8258. lpGet_SizeToFollow,
  8259. Size
  8260. };
  8261. ULONG_PTR args[] =
  8262. {
  8263. (ULONG_PTR) pLine->pServer->hLineApp,
  8264. (ULONG_PTR) dwDeviceID,
  8265. (ULONG_PTR) TAPI_VERSION1_0,
  8266. (ULONG_PTR) TAPI_VERSION_CURRENT,
  8267. (ULONG_PTR) &pLine->dwXPIVersion,
  8268. (ULONG_PTR) &pLine->ExtensionID,
  8269. (ULONG_PTR) sizeof (LINEEXTENSIONID)
  8270. };
  8271. REMOTE_FUNC_ARGS funcArgs =
  8272. {
  8273. MAKELONG (LINE_FUNC | SYNC | 7, lNegotiateAPIVersion),
  8274. args,
  8275. argTypes
  8276. };
  8277. REMOTEDOFUNC (&funcArgs, "lineNegotiateAPIVersion");
  8278. }
  8279. return 0;
  8280. }
  8281. LONG
  8282. TSPIAPI
  8283. TSPI_providerCreatePhoneDevice(
  8284. ULONG_PTR TempID,
  8285. DWORD dwDeviceID
  8286. )
  8287. {
  8288. PDRVPHONE pPhone = GetPhoneFromID ((DWORD) TempID);
  8289. if (NULL == pPhone)
  8290. {
  8291. return PHONEERR_BADDEVICEID;
  8292. }
  8293. pPhone->dwDeviceIDLocal = dwDeviceID;
  8294. if (pPhone->dwXPIVersion == 0)
  8295. {
  8296. static REMOTE_ARG_TYPES argTypes[] =
  8297. {
  8298. Dword,
  8299. PhoneID,
  8300. Dword,
  8301. Dword,
  8302. lpDword,
  8303. lpGet_SizeToFollow,
  8304. Size
  8305. };
  8306. ULONG_PTR args[] =
  8307. {
  8308. (ULONG_PTR) pPhone->pServer->hPhoneApp,
  8309. (ULONG_PTR) dwDeviceID,
  8310. (ULONG_PTR) TAPI_VERSION1_0,
  8311. (ULONG_PTR) TAPI_VERSION_CURRENT,
  8312. (ULONG_PTR) &pPhone->dwXPIVersion,
  8313. (ULONG_PTR) &pPhone->ExtensionID,
  8314. (ULONG_PTR) sizeof (PHONEEXTENSIONID),
  8315. };
  8316. REMOTE_FUNC_ARGS funcArgs =
  8317. {
  8318. MAKELONG (PHONE_FUNC | SYNC | 7, pNegotiateAPIVersion),
  8319. args,
  8320. argTypes
  8321. };
  8322. REMOTEDOFUNC (&funcArgs, "phoneNegotiateAPIVersion");
  8323. }
  8324. return 0;
  8325. }
  8326. LONG
  8327. TSPIAPI
  8328. TSPI_providerEnumDevices(
  8329. DWORD dwPermanentProviderID,
  8330. LPDWORD lpdwNumLines,
  8331. LPDWORD lpdwNumPhones,
  8332. HPROVIDER hProvider,
  8333. LINEEVENT lpfnLineCreateProc,
  8334. PHONEEVENT lpfnPhoneCreateProc
  8335. )
  8336. {
  8337. char szProviderN[16], szComputerName[MAX_COMPUTERNAME_LENGTH+1];
  8338. DWORD dwSize, dwTID, dwMultiProtocolSupport,
  8339. dwConnectionOrientedOnly,
  8340. dwRSPInitRpcTimeout;
  8341. HKEY hTelephonyKey;
  8342. HKEY hProviderNKey;
  8343. DWORD dwDataSize;
  8344. DWORD dwDataType;
  8345. PWSTR pszThingToPassToServer;
  8346. LONG lResult;
  8347. HANDLE hProcess;
  8348. PDRVSERVER pServer;
  8349. PRSP_THREAD_INFO pTls;
  8350. DWORD dwDisp;
  8351. RSPSOCKET socket;
  8352. //
  8353. // Check ghInst to ensure DllMain(DLL_PROCESS_ATTACH) has been called properly
  8354. //
  8355. if ( NULL == ghInst )
  8356. {
  8357. return LINEERR_OPERATIONFAILED;
  8358. }
  8359. //
  8360. // Init globals.
  8361. //
  8362. // If dwPermanentProviderID != 0xffffffff then we're being called
  8363. // directly by TAPISRV, so we want to init all the globals and
  8364. // keep going.
  8365. //
  8366. // Otherwise, we're being called from TSPI_providerCheckForNewUser,
  8367. // and we only want to continue if we've not actually initialized
  8368. // yet.
  8369. //
  8370. if (dwPermanentProviderID != 0xffffffff)
  8371. {
  8372. ghProvider = hProvider;
  8373. gdwPermanentProviderID = dwPermanentProviderID;
  8374. gpfnLineEventProc = lpfnLineCreateProc;
  8375. gpfnPhoneEventProc = lpfnPhoneCreateProc;
  8376. gbInitialized = FALSE;
  8377. TRACELOGREGISTER(_T("remotesp"));
  8378. }
  8379. #if MEMPHIS
  8380. #else
  8381. else if (gbInitialized)
  8382. {
  8383. return 0;
  8384. }
  8385. //
  8386. // Is the client app running in the system account? If so,
  8387. // then try to impersonate the logged-on user, because the
  8388. // system account doesn't have net privileges. If no one is
  8389. // logged in yet then we'll simply return success & no devices,
  8390. // and if a user happens to log on later & run a tapi app
  8391. // then we'll try to do init at that time (from within
  8392. // TSPI_providerCheckForNewUser).
  8393. //
  8394. if (IsClientSystem())
  8395. {
  8396. LOG((TL_INFO,
  8397. "TSPI_providerEnumDevices: Client is system account"
  8398. ));
  8399. LOG((TL_INFO,
  8400. " ...attempting logged-on-user impersonation"
  8401. ));
  8402. if (!GetCurrentlyLoggedOnUser (&hProcess))
  8403. {
  8404. LOG((TL_ERROR,
  8405. "TSPI_providerEnumDevices: GetCurrentlyLoggedOnUser failed"
  8406. ));
  8407. LOG((TL_INFO,
  8408. " ...deferring initialization"
  8409. ));
  8410. gdwInitialNumLineDevices = 0;
  8411. gdwInitialNumPhoneDevices = 0;
  8412. return 0;
  8413. }
  8414. }
  8415. else
  8416. {
  8417. hProcess = NULL;
  8418. }
  8419. gbInitialized = TRUE;
  8420. #endif
  8421. gdwDrvServerKey = GetTickCount();
  8422. if (!(gpCurrentInitContext = DrvAlloc (sizeof (RSP_INIT_CONTEXT))))
  8423. {
  8424. if (hProcess)
  8425. {
  8426. CloseHandle (hProcess);
  8427. }
  8428. return LINEERR_NOMEM;
  8429. }
  8430. gpCurrentInitContext->dwDrvServerKey = gdwDrvServerKey;
  8431. InitializeListHead (&gpCurrentInitContext->ServerList);
  8432. InitializeListHead (&gNptListHead);
  8433. if (!(pszThingToPassToServer = DrvAlloc(
  8434. MAX_COMPUTERNAME_LENGTH+1 + 256) // incl protseq 0-N, endpoint 0-N
  8435. ))
  8436. {
  8437. if (hProcess)
  8438. {
  8439. CloseHandle (hProcess);
  8440. }
  8441. DrvFree (gpCurrentInitContext);
  8442. return LINEERR_NOMEM;
  8443. }
  8444. gdwInitialNumLineDevices = gdwLineDeviceIDBase =
  8445. gdwInitialNumPhoneDevices = gdwPhoneDeviceIDBase = 0;
  8446. if (ERROR_SUCCESS !=
  8447. RegOpenKeyEx(
  8448. HKEY_LOCAL_MACHINE,
  8449. gszTelephonyKey,
  8450. 0,
  8451. KEY_ALL_ACCESS,
  8452. &hTelephonyKey
  8453. ))
  8454. {
  8455. if (hProcess)
  8456. {
  8457. CloseHandle (hProcess);
  8458. }
  8459. DrvFree (gpCurrentInitContext);
  8460. DrvFree (pszThingToPassToServer);
  8461. return LINEERR_OPERATIONFAILED;
  8462. }
  8463. {
  8464. DWORD dwSize;
  8465. dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  8466. #ifdef PARTIAL_UNICODE
  8467. {
  8468. CHAR buf[MAX_COMPUTERNAME_LENGTH + 1];
  8469. GetComputerName (buf, &dwSize);
  8470. MultiByteToWideChar(
  8471. GetACP(),
  8472. MB_PRECOMPOSED,
  8473. buf,
  8474. dwSize,
  8475. gszMachineName,
  8476. dwSize
  8477. );
  8478. }
  8479. #else
  8480. GetComputerNameW (gszMachineName, &dwSize);
  8481. #endif
  8482. }
  8483. wcscpy( pszThingToPassToServer, gszMachineName );
  8484. wcscat( pszThingToPassToServer, L"\"");
  8485. //
  8486. // See if multi-protocol support is enabled in the registry
  8487. // (for talking to post-TAPI 2.1 servers)
  8488. //
  8489. wsprintf (szProviderN, "Provider%d", gdwPermanentProviderID);
  8490. RegCreateKeyEx(
  8491. hTelephonyKey,
  8492. szProviderN,
  8493. 0,
  8494. NULL,
  8495. REG_OPTION_NON_VOLATILE,
  8496. KEY_ALL_ACCESS,
  8497. NULL,
  8498. &hProviderNKey,
  8499. &dwDisp
  8500. );
  8501. dwDataSize = sizeof (dwMultiProtocolSupport);
  8502. dwMultiProtocolSupport = 1;
  8503. RegQueryValueEx(
  8504. hProviderNKey,
  8505. "MultiProtocolSupport",
  8506. 0,
  8507. &dwDataType,
  8508. (LPBYTE) &dwMultiProtocolSupport,
  8509. &dwDataSize
  8510. );
  8511. dwDataSize = sizeof (dwConnectionOrientedOnly);
  8512. dwConnectionOrientedOnly = 0;
  8513. RegQueryValueEx(
  8514. hProviderNKey,
  8515. "ConnectionOrientedOnly",
  8516. 0,
  8517. &dwDataType,
  8518. (LPBYTE) &dwConnectionOrientedOnly,
  8519. &dwDataSize
  8520. );
  8521. dwDataSize = sizeof (gdwRSPRpcTimeout);
  8522. if (RegQueryValueEx(
  8523. hTelephonyKey,
  8524. "RspRpcTimeout",
  8525. 0,
  8526. &dwDataType,
  8527. (LPBYTE) &gdwRSPRpcTimeout,
  8528. &dwDataSize
  8529. ) != ERROR_SUCCESS)
  8530. {
  8531. gdwRSPRpcTimeout = 5 * 60 * 1000; // default to 5 minutes
  8532. }
  8533. if (gdwRSPRpcTimeout < 10 * 1000)
  8534. {
  8535. // Do not allow a value less then 10 seconds
  8536. gdwRSPRpcTimeout = 10 * 1000;
  8537. }
  8538. dwDataSize = sizeof (dwRSPInitRpcTimeout);
  8539. if (RegQueryValueEx(
  8540. hTelephonyKey,
  8541. "RspInitRpcTimeout",
  8542. 0,
  8543. &dwDataType,
  8544. (LPBYTE) &dwRSPInitRpcTimeout,
  8545. &dwDataSize
  8546. ) != ERROR_SUCCESS)
  8547. {
  8548. dwRSPInitRpcTimeout = 10 * 1000; // default to 10 seconds
  8549. }
  8550. if (dwRSPInitRpcTimeout < 1000)
  8551. {
  8552. // Do not allow this to be less than 1 second
  8553. dwRSPInitRpcTimeout = 1000;
  8554. }
  8555. dwDataSize = sizeof (gdwMaxEventBufferSize);
  8556. gdwMaxEventBufferSize = DEF_MAX_EVENT_BUFFER_SIZE;
  8557. RegQueryValueEx(
  8558. hProviderNKey,
  8559. "MaxEventBufferSize",
  8560. 0,
  8561. &dwDataType,
  8562. (LPBYTE) &gdwMaxEventBufferSize,
  8563. &dwDataSize
  8564. );
  8565. RegCloseKey (hProviderNKey);
  8566. //
  8567. // Init gEventHandlerThreadParams
  8568. //
  8569. gEventHandlerThreadParams.dwEventBufferTotalSize = 1024;
  8570. gEventHandlerThreadParams.dwEventBufferUsedSize = 0;
  8571. if (!(gEventHandlerThreadParams.pEventBuffer = DrvAlloc(
  8572. gEventHandlerThreadParams.dwEventBufferTotalSize
  8573. )))
  8574. {
  8575. if (hProcess)
  8576. {
  8577. CloseHandle (hProcess);
  8578. }
  8579. DrvFree (gpCurrentInitContext);
  8580. DrvFree (pszThingToPassToServer);
  8581. CloseHandle (hTelephonyKey);
  8582. return LINEERR_NOMEM;
  8583. }
  8584. gEventHandlerThreadParams.pDataIn =
  8585. gEventHandlerThreadParams.pDataOut =
  8586. gEventHandlerThreadParams.pEventBuffer;
  8587. if (!(gEventHandlerThreadParams.hEvent = CreateEvent(
  8588. (LPSECURITY_ATTRIBUTES) NULL, // no security attrs
  8589. TRUE, // manual reset
  8590. FALSE, // initially non-signaled
  8591. NULL // unnamed
  8592. )))
  8593. {
  8594. if (hProcess)
  8595. {
  8596. CloseHandle (hProcess);
  8597. }
  8598. DrvFree (gpCurrentInitContext);
  8599. DrvFree (pszThingToPassToServer);
  8600. CloseHandle (hTelephonyKey);
  8601. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  8602. return LINEERR_NOMEM;
  8603. }
  8604. gEventHandlerThreadParams.dwMsgBufferTotalSize = 1024;
  8605. if (!(gEventHandlerThreadParams.pMsgBuffer = DrvAlloc(
  8606. gEventHandlerThreadParams.dwMsgBufferTotalSize
  8607. )))
  8608. {
  8609. if (hProcess)
  8610. {
  8611. CloseHandle (hProcess);
  8612. }
  8613. DrvFree (gpCurrentInitContext);
  8614. DrvFree (pszThingToPassToServer);
  8615. CloseHandle (hTelephonyKey);
  8616. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  8617. CloseHandle (gEventHandlerThreadParams.hEvent);
  8618. return LINEERR_NOMEM;
  8619. }
  8620. //
  8621. // Register the Rpc interface (leverage tapisrv's rpc server thread)
  8622. //
  8623. {
  8624. BOOL bFoundProtseq;
  8625. DWORD i;
  8626. RPC_STATUS status;
  8627. unsigned char * pszSecurity = NULL;
  8628. unsigned int cMaxCalls = 20;
  8629. unsigned char *aszProtseqs[] =
  8630. {
  8631. "ncacn_ip_tcp",
  8632. "ncacn_spx",
  8633. "ncacn_nb_nb",
  8634. NULL
  8635. };
  8636. unsigned char *aszEndpoints[] =
  8637. {
  8638. "251",
  8639. "1000",
  8640. "251",
  8641. NULL
  8642. };
  8643. const WCHAR *awszProtseqs[] =
  8644. {
  8645. L"ncacn_ip_tcp\"",
  8646. L"ncacn_spx\"",
  8647. L"ncacn_nb_nb\"",
  8648. NULL
  8649. };
  8650. const WCHAR *awszEndpoints[] =
  8651. {
  8652. L"251",
  8653. L"1000",
  8654. L"251"
  8655. };
  8656. bFoundProtseq = FALSE;
  8657. for (i = 0; aszProtseqs[i]; i++)
  8658. {
  8659. status = RpcServerUseProtseqEp(
  8660. aszProtseqs[i],
  8661. cMaxCalls,
  8662. aszEndpoints[i],
  8663. pszSecurity // Security descriptor
  8664. );
  8665. LOG((TL_INFO,
  8666. "RpcServerUseProtseqEp(%s) ret'd %d",
  8667. aszProtseqs[i],
  8668. status
  8669. ));
  8670. if (status == 0 || status == RPC_S_DUPLICATE_ENDPOINT)
  8671. {
  8672. wcscat (pszThingToPassToServer, awszProtseqs[i]);
  8673. wcscat (pszThingToPassToServer, awszEndpoints[i]);
  8674. bFoundProtseq = TRUE;
  8675. if (!dwMultiProtocolSupport)
  8676. {
  8677. //
  8678. // In TAPI 2.1 we'd only pass 1 proto/port pair to
  8679. // the server, & the string looked like :
  8680. //
  8681. // <protseq>"<port>
  8682. //
  8683. // ... so break out of this loop now that we've found
  8684. // a valid proto/port pair
  8685. //
  8686. break;
  8687. }
  8688. else
  8689. {
  8690. //
  8691. // Post-TAPI 2.1 servers support >=1 proto/port pair
  8692. // strings, & they look like:
  8693. //
  8694. // <protseq1>"<port1>"..."<protseqN>"<portN>"
  8695. //
  8696. // ... so we need to append a dbl-quote (") char to
  8697. // the string, and then continue to look for any
  8698. // other valid proto/port pairs
  8699. //
  8700. wcscat (pszThingToPassToServer, L"\"");
  8701. }
  8702. }
  8703. }
  8704. if (!bFoundProtseq)
  8705. {
  8706. LOG((TL_ERROR,
  8707. "TSPI_providerEnumDevices: fatal error, couldn't get a protseq"
  8708. ));
  8709. if (hProcess)
  8710. {
  8711. CloseHandle (hProcess);
  8712. }
  8713. DrvFree (gpCurrentInitContext);
  8714. DrvFree (pszThingToPassToServer);
  8715. CloseHandle (hTelephonyKey);
  8716. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  8717. CloseHandle (gEventHandlerThreadParams.hEvent);
  8718. return LINEERR_OPERATIONFAILED;
  8719. }
  8720. status = RpcServerRegisterIfEx(
  8721. remotesp_ServerIfHandle, // interface to register
  8722. NULL, // MgrTypeUuid
  8723. NULL, // MgrEpv; null means use default
  8724. RPC_IF_AUTOLISTEN | RPC_IF_ALLOW_SECURE_ONLY,
  8725. RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
  8726. NULL
  8727. );
  8728. if (status)
  8729. {
  8730. LOG((TL_INFO,
  8731. "TSPI_providerEnumDevices: RpcServerRegisterIf ret'd %d",
  8732. status
  8733. ));
  8734. }
  8735. status = RpcServerRegisterAuthInfo(
  8736. NULL,
  8737. RPC_C_AUTHN_WINNT,
  8738. NULL,
  8739. NULL
  8740. );
  8741. if (status)
  8742. {
  8743. LOG((TL_INFO,
  8744. "TSPI_providerEnumDevices: RpcServerRegisterAuthInfo " \
  8745. "returned %d",
  8746. status
  8747. ));
  8748. }
  8749. }
  8750. //
  8751. // Open a mailslot iff appropriate (use a semi-random name seeded
  8752. // via process id)
  8753. //
  8754. if (!dwConnectionOrientedOnly)
  8755. {
  8756. DWORD dwPID = GetCurrentProcessId(), dwRandomNum;
  8757. WCHAR szMailslotName[32];
  8758. dwRandomNum = (65537 * dwPID * dwPID * dwPID) & 0x00ffffff;
  8759. wsprintfW(
  8760. gszMailslotName,
  8761. L"\\\\%ws\\mailslot\\tapi\\tp%x",
  8762. gszMachineName,
  8763. dwRandomNum
  8764. );
  8765. wsprintfW(
  8766. szMailslotName,
  8767. L"\\\\.\\mailslot\\tapi\\tp%x",
  8768. dwRandomNum
  8769. );
  8770. if ((gEventHandlerThreadParams.hMailslot = CreateMailslotW(
  8771. szMailslotName,
  8772. sizeof (DWORD), // max msg size
  8773. MAILSLOT_WAIT_FOREVER,
  8774. (LPSECURITY_ATTRIBUTES) NULL
  8775. )) == INVALID_HANDLE_VALUE)
  8776. {
  8777. LOG((TL_ERROR,
  8778. "TSPI_providerEnumDevices: CreateMailslot failed, err=%d",
  8779. GetLastError()
  8780. ));
  8781. goto no_mailslot;
  8782. }
  8783. else
  8784. {
  8785. RegOpenKeyEx(
  8786. hTelephonyKey,
  8787. szProviderN,
  8788. 0,
  8789. KEY_ALL_ACCESS,
  8790. &hProviderNKey
  8791. );
  8792. RegCloseKey (hProviderNKey);
  8793. }
  8794. if (gEventHandlerThreadParams.hMailslot != INVALID_HANDLE_VALUE)
  8795. {
  8796. gEventHandlerThreadParams.hMailslotEvent = CreateEvent(
  8797. NULL, // no security attrs
  8798. FALSE, // auto-reset
  8799. FALSE, // initially non-signaled
  8800. NULL // unnamed
  8801. );
  8802. if (!gEventHandlerThreadParams.hMailslotEvent)
  8803. {
  8804. LOG((TL_ERROR,
  8805. "TSPI_providerEnumDevices: CreateEvent failed, err=%d",
  8806. GetLastError()
  8807. ));
  8808. goto no_mailslot;
  8809. }
  8810. }
  8811. }
  8812. else
  8813. {
  8814. no_mailslot:
  8815. LOG((TL_INFO,"TSPI_providerEnumDevices: doing connection-oriented only"));
  8816. gEventHandlerThreadParams.hMailslot = INVALID_HANDLE_VALUE;
  8817. gszMailslotName[0] = (WCHAR) 0;
  8818. }
  8819. //
  8820. // Init globals
  8821. //
  8822. // NOTE: TAPI's xxxEvent & xxxCreate procs are currently one in the same
  8823. //
  8824. wsprintf (szProviderN, "Provider%d", gdwPermanentProviderID);
  8825. gpLineLookup = (PDRVLINELOOKUP) NULL;
  8826. gpPhoneLookup = (PDRVPHONELOOKUP) NULL;
  8827. RegOpenKeyEx(
  8828. hTelephonyKey,
  8829. szProviderN,
  8830. 0,
  8831. KEY_ALL_ACCESS,
  8832. &hProviderNKey
  8833. );
  8834. dwDataSize = sizeof(gdwRetryCount);
  8835. gdwRetryCount = 2;
  8836. RegQueryValueEx(
  8837. hProviderNKey,
  8838. "RetryCount",
  8839. 0,
  8840. &dwDataType,
  8841. (LPBYTE) &gdwRetryCount,
  8842. &dwDataSize
  8843. );
  8844. dwDataSize = sizeof(gdwRetryTimeout);
  8845. gdwRetryTimeout = 1000;
  8846. RegQueryValueEx(
  8847. hProviderNKey,
  8848. "RetryTimeout",
  8849. 0,
  8850. &dwDataType,
  8851. (LPBYTE) &gdwRetryTimeout,
  8852. &dwDataSize
  8853. );
  8854. gfCacheStructures = TRUE;
  8855. dwDataSize = sizeof(gfCacheStructures);
  8856. RegQueryValueEx(
  8857. hProviderNKey,
  8858. "CacheStructures",
  8859. 0,
  8860. &dwDataType,
  8861. (LPBYTE)&gfCacheStructures,
  8862. &dwDataSize
  8863. );
  8864. if (gfCacheStructures)
  8865. {
  8866. gdwCacheForceCallCount = 5;
  8867. dwDataSize = sizeof(gdwCacheForceCallCount);
  8868. RegQueryValueEx(
  8869. hProviderNKey,
  8870. "CacheForceCallCount",
  8871. 0,
  8872. &dwDataType,
  8873. (LPBYTE)&gdwCacheForceCallCount,
  8874. &dwDataSize
  8875. );
  8876. }
  8877. dwSize = MAX_COMPUTERNAME_LENGTH+1;
  8878. GetComputerName (szComputerName, &dwSize);
  8879. //
  8880. // Initialize Directory server lookup
  8881. // we pass in a registry key in case the
  8882. // Directory does not exist
  8883. //
  8884. if (!OpenServerLookup(hProviderNKey))
  8885. {
  8886. LOG((TL_ERROR, "TSPI_providerEnumDevices: OpenServerLookup() failed"));
  8887. fatal_error:
  8888. if (hProcess)
  8889. {
  8890. CloseHandle (hProcess);
  8891. }
  8892. DrvFree (gpCurrentInitContext);
  8893. DrvFree (pszThingToPassToServer);
  8894. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  8895. CloseHandle (gEventHandlerThreadParams.hEvent);
  8896. RegCloseKey (hProviderNKey);
  8897. RegCloseKey (hTelephonyKey);
  8898. return LINEERR_OPERATIONFAILED;
  8899. }
  8900. #if MEMPHIS
  8901. #else
  8902. if (!hProcess)
  8903. {
  8904. RPC_STATUS status;
  8905. status = RpcImpersonateClient(0);
  8906. if (status != RPC_S_OK && status != RPC_S_NO_CALL_ACTIVE)
  8907. {
  8908. LOG((TL_ERROR, "RpcImpersonateClient failed, err %d", status));
  8909. CloseLookup();
  8910. goto fatal_error;
  8911. }
  8912. }
  8913. else if (!SetProcessImpersonationToken(hProcess))
  8914. {
  8915. LOG((TL_ERROR, "SetProcessImpersonationToken failed"));
  8916. CloseLookup();
  8917. goto fatal_error;
  8918. }
  8919. if (pTls = GetTls())
  8920. {
  8921. pTls->bAlreadyImpersonated = TRUE;
  8922. }
  8923. #endif
  8924. if (SockStartup (&socket) != S_OK)
  8925. {
  8926. goto fatal_error;
  8927. }
  8928. //
  8929. // Loop trying to attach to each server
  8930. //
  8931. while (1)
  8932. {
  8933. char szServerName[MAX_COMPUTERNAME_LENGTH+1];
  8934. PCONTEXT_HANDLE_TYPE phContext = NULL;
  8935. BOOL bFromReg;
  8936. if (!GetNextServer(szServerName, sizeof(szServerName), &bFromReg))
  8937. {
  8938. CloseLookup();
  8939. break;
  8940. }
  8941. LOG((TL_INFO, "init: Server name='%s'", szServerName));
  8942. if (!szServerName[0])
  8943. {
  8944. continue;
  8945. }
  8946. if (!lstrcmpi(szComputerName, szServerName))
  8947. {
  8948. LOG((TL_ERROR,"init: ServerName is the same a local computer name"));
  8949. LOG((TL_INFO," Ignoring this server"));
  8950. continue;
  8951. }
  8952. //
  8953. // Init the RPC connection
  8954. //
  8955. pServer = DrvAlloc (sizeof (DRVSERVER));
  8956. pServer->pInitContext = gpCurrentInitContext;
  8957. pServer->dwKey = gdwDrvServerKey;
  8958. lstrcpy (pServer->szServerName, szServerName);
  8959. {
  8960. RPC_STATUS status;
  8961. unsigned char * pszStringBinding = NULL;
  8962. LOG((TL_INFO, "Creating binding..."));
  8963. status = RpcStringBindingCompose(
  8964. NULL, // uuid
  8965. "ncacn_np", // prot
  8966. szServerName, // server name
  8967. "\\pipe\\tapsrv", // interface name
  8968. NULL, // options
  8969. &pszStringBinding
  8970. );
  8971. if (status)
  8972. {
  8973. LOG((TL_ERROR,
  8974. "RpcStringBindingCompose failed: err=%d, szNetAddr='%s'",
  8975. status,
  8976. szServerName
  8977. ));
  8978. }
  8979. status = RpcBindingFromStringBinding(
  8980. pszStringBinding,
  8981. &hTapSrv
  8982. );
  8983. if (status)
  8984. {
  8985. LOG((TL_ERROR,
  8986. "RpcBindingFromStringBinding failed, err=%d, szBinding='%s'",
  8987. status,
  8988. pszStringBinding
  8989. ));
  8990. }
  8991. status = RpcStringFree (&pszStringBinding);
  8992. if (status)
  8993. {
  8994. LOG((TL_ERROR, "RpcStringBindingFree failed: err=%d", status));
  8995. }
  8996. status = RpcBindingSetAuthInfo(
  8997. hTapSrv,
  8998. NULL,
  8999. RPC_C_AUTHN_LEVEL_DEFAULT,
  9000. //#ifdef MEMPHIS
  9001. // RPC_C_AUTHN_DEFAULT,
  9002. //#else
  9003. RPC_C_AUTHN_WINNT,
  9004. //#endif
  9005. NULL,
  9006. 0
  9007. );
  9008. if (status)
  9009. {
  9010. LOG((TL_ERROR,
  9011. "RpcBindingSetAuthInfo failed, err=%d",
  9012. status
  9013. ));
  9014. lResult = LINEERR_OPERATIONFAILED;
  9015. }
  9016. else
  9017. {
  9018. DWORD dwSize = 32;
  9019. pServer->bSetAuthInfo = TRUE;
  9020. //
  9021. // Per Bug 110291
  9022. // RPC team has added a timeout feature we can use in
  9023. // whistler build. In the past when a RPC server drops
  9024. // into a user mode debugger, all calling RPC clients
  9025. // will hang there indefinitely, this is very annoying
  9026. // in stress enviroment when we need to debug the server
  9027. // machine we would cause a large number of client breaks.
  9028. // This could be fixed by using the RPC timeout feature.
  9029. //
  9030. // For RPC calls, we use a timeout value of 5 minutes based
  9031. // on RPC team recommendation (dwRSPRpcTimeout). But
  9032. // during RemoteSP startup, we use a even shorter
  9033. // timeout value for RPC (dwRSPInitRpcTimeout), this could
  9034. // cause us falsely declare a server dead when it is in fact not
  9035. // if the network connection is bad or the server is busy.
  9036. // But this would not be a problem because such a server
  9037. // will be inserted into the gNptListHead list and eventually
  9038. // recover by the NetworkPollThread.
  9039. //
  9040. // Both the above timeout value can be configured from
  9041. // registry by using DWORD registry value of
  9042. // "RspRpcTimeout" & "RspInitRpcTimeout
  9043. // under HKLM\Software\Microsoft\Windows\CurrentVersion\Telephony
  9044. // They should be expressed in the unit of milli-seconds
  9045. //
  9046. RpcBindingSetOption (
  9047. hTapSrv,
  9048. RPC_C_OPT_CALL_TIMEOUT,
  9049. dwRSPInitRpcTimeout
  9050. );
  9051. //
  9052. // Set the global which RemoteSPAttach looks at to know
  9053. // who the current server is (could pass this as arg to
  9054. // ClientAttach, but this is easiest for now)
  9055. //
  9056. //
  9057. // RPC exception retry comments (xzhang):
  9058. //
  9059. // In case we get a RPC exception with the ClientAttach,
  9060. // we were retrying for 3 times (by default) hoping the
  9061. // rpc problem could go away in the subsequent retries. This
  9062. // causes significant delay for remotesp start-up if one
  9063. // or more of the servers are down thus throwing exceptions.
  9064. // Since we have a NetworkPollThread taking care of those
  9065. // temporarily unavailable TAPI servers, we do not really
  9066. // need to retry here. Thus I removed the retry code.
  9067. //
  9068. gpCurrInitServer = pServer;
  9069. RpcTryExcept
  9070. {
  9071. pServer->dwSpecialHack = 0;
  9072. if (SockIsServerResponding(&socket, szServerName) != S_OK)
  9073. {
  9074. LOG((TL_ERROR,"init: %s is not responding", szServerName));
  9075. LOG((TL_INFO," Ignoring this server"));
  9076. lResult = RPC_S_SERVER_UNAVAILABLE;
  9077. }
  9078. else
  9079. {
  9080. LOG((TL_INFO, "Calling ClientAttach..."));
  9081. lResult = ClientAttach(
  9082. &phContext,
  9083. 0xffffffff, // dwProcessID, -1 implies remotesp
  9084. &pServer->dwSpecialHack,
  9085. gszMailslotName,
  9086. pszThingToPassToServer // gszMachineName
  9087. );
  9088. LOG((TL_INFO, "ClientAttach returned..."));
  9089. }
  9090. if (lResult != 0)
  9091. {
  9092. LogRemoteSPError(pServer->szServerName,
  9093. ERROR_REMOTESP_ATTACH, lResult, 0,
  9094. FALSE);
  9095. }
  9096. else
  9097. {
  9098. LogRemoteSPError(pServer->szServerName,
  9099. ERROR_REMOTESP_NONE, 0, 0,
  9100. FALSE);
  9101. }
  9102. }
  9103. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  9104. {
  9105. LogRemoteSPError(pServer->szServerName,
  9106. ERROR_REMOTESP_EXCEPTION,
  9107. RpcExceptionCode(), 0, FALSE);
  9108. //
  9109. // Go onto next server. The poll thread
  9110. // will take care of things...
  9111. //
  9112. LOG((TL_ERROR,
  9113. "ClientAttach failed - check server name"
  9114. ));
  9115. lResult = LINEERR_OPERATIONFAILED;
  9116. }
  9117. RpcEndExcept
  9118. }
  9119. pServer->hTapSrv = hTapSrv;
  9120. if ( 0 != lResult )
  9121. {
  9122. //
  9123. // RPC attach failed. We'll start a thread
  9124. // and poll for it. When it works, we can add
  9125. // the phones/lines dynamically.
  9126. // In the meantime, this thread will continue
  9127. // to contact other servers.
  9128. //
  9129. RpcBindingSetOption (
  9130. hTapSrv,
  9131. RPC_C_OPT_CALL_TIMEOUT,
  9132. gdwRSPRpcTimeout
  9133. );
  9134. InsertTailList (&gNptListHead, &pServer->ServerList);
  9135. continue;
  9136. }
  9137. //
  9138. // Enable all events for remotesp
  9139. //
  9140. pServer->phContext = phContext;
  9141. RSPSetEventFilterMasks (
  9142. pServer,
  9143. TAPIOBJ_NULL,
  9144. (LONG_PTR)NULL,
  9145. (ULONG64)EM_ALL
  9146. );
  9147. //
  9148. // Now that we have contacted this server, init it and
  9149. // add the phones/lines.
  9150. //
  9151. FinishEnumDevices(
  9152. pServer,
  9153. phContext,
  9154. lpdwNumLines,
  9155. lpdwNumPhones,
  9156. (dwPermanentProviderID == 0xffffffff ? FALSE : TRUE),
  9157. bFromReg
  9158. );
  9159. }
  9160. }
  9161. SockShutdown (&socket);
  9162. //
  9163. // If we successfully attached to all servers then clean up,
  9164. // otherwise start the poll thread
  9165. //
  9166. if (gpszThingToPassToServer)
  9167. {
  9168. DrvFree (gpszThingToPassToServer);
  9169. }
  9170. gpszThingToPassToServer = pszThingToPassToServer;
  9171. TapiEnterCriticalSection ( &gCriticalSection );
  9172. if (!IsListEmpty (&gNptListHead) && !ghNetworkPollThread)
  9173. {
  9174. ghNptShutdownEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  9175. if (!(ghNetworkPollThread = CreateThread(
  9176. NULL,
  9177. 0,
  9178. (LPTHREAD_START_ROUTINE) NetworkPollThread,
  9179. (LPVOID) pszThingToPassToServer,
  9180. 0,
  9181. &dwTID
  9182. )))
  9183. {
  9184. LOG((TL_ERROR, "Unable to create poll thread! Argh!"));
  9185. CloseHandle (ghNptShutdownEvent);
  9186. while (!IsListEmpty (&gNptListHead))
  9187. {
  9188. LIST_ENTRY *pEntry = RemoveHeadList (&gNptListHead);
  9189. DrvFree(
  9190. CONTAINING_RECORD (pEntry, DRVSERVER, ServerList)
  9191. );
  9192. }
  9193. }
  9194. }
  9195. TapiLeaveCriticalSection( &gCriticalSection );
  9196. RegCloseKey (hProviderNKey);
  9197. RegCloseKey (hTelephonyKey);
  9198. if (hProcess)
  9199. {
  9200. ClearImpersonationToken();
  9201. CloseHandle (hProcess);
  9202. }
  9203. else
  9204. {
  9205. RevertToSelf();
  9206. }
  9207. if (pTls)
  9208. {
  9209. pTls->bAlreadyImpersonated = FALSE;
  9210. }
  9211. //
  9212. // If dwPermanentProviderID == 0xffffffff we're being called by
  9213. // TSPI_providerCheckForNewUser, so return a special value of 1
  9214. // so that it'll know to follow up with a TSPI_providerInit.
  9215. //
  9216. // Otherwise, we're being called directly from TAPI so simply
  9217. // return 0 to indicate success.
  9218. //
  9219. return (dwPermanentProviderID == 0xffffffff ? 1 : 0);
  9220. }
  9221. LONG
  9222. TSPIAPI
  9223. TSPI_providerFreeDialogInstance(
  9224. HDRVDIALOGINSTANCE hdDlgInst
  9225. )
  9226. {
  9227. return 0;
  9228. }
  9229. LONG
  9230. TSPIAPI
  9231. TSPI_providerGenericDialogData(
  9232. ULONG_PTR ObjectID,
  9233. DWORD dwObjectType,
  9234. LPVOID lpParams,
  9235. DWORD dwSize
  9236. )
  9237. {
  9238. LPDWORD lpBuffer;
  9239. REMOTE_ARG_TYPES argTypes[] =
  9240. {
  9241. LineID,
  9242. Dword,
  9243. lpSet_SizeToFollow,
  9244. Size,
  9245. lpGet_SizeToFollow,
  9246. Size
  9247. };
  9248. ULONG_PTR args[] =
  9249. {
  9250. (ULONG_PTR) ObjectID,
  9251. (ULONG_PTR) dwObjectType,
  9252. (ULONG_PTR) lpParams,
  9253. (ULONG_PTR) dwSize,
  9254. (ULONG_PTR) lpParams,
  9255. (ULONG_PTR) dwSize
  9256. };
  9257. REMOTE_FUNC_ARGS funcArgs =
  9258. {
  9259. MAKELONG (LINE_FUNC | SYNC | 6, xUIDLLCallback),
  9260. args,
  9261. argTypes
  9262. };
  9263. // first check to see if this is a message to ourselves.
  9264. lpBuffer = (LPDWORD) lpParams;
  9265. if ((dwSize > (2 * sizeof(DWORD))) &&
  9266. (lpBuffer[0] == RSP_MSG) &&
  9267. (lpBuffer[1] == RSP_MSG_UIID))
  9268. {
  9269. // if it is, we're looking for the real provider ui dll. fill in the
  9270. // buffer and return
  9271. // note that we only handle one sp here, but it may be easy to handle multiple
  9272. // by sending in additional info in the buffer ( like the line ID or something)
  9273. wcscpy ((LPWSTR)(lpBuffer+2), gszRealSPUIDLL);
  9274. return 0;
  9275. }
  9276. switch (dwObjectType)
  9277. {
  9278. case TUISPIDLL_OBJECT_LINEID:
  9279. // argTypes[0] already set correctly, just break
  9280. break;
  9281. case TUISPIDLL_OBJECT_PHONEID:
  9282. argTypes[0] = PhoneID;
  9283. break;
  9284. case TUISPIDLL_OBJECT_PROVIDERID:
  9285. default: // case TUISPIDLL_OBJECT_DIALOGINSTANCE:
  9286. break;
  9287. }
  9288. return (REMOTEDOFUNC (&funcArgs, "UIDLLCallback"));
  9289. }
  9290. LONG
  9291. TSPIAPI
  9292. TSPI_providerInit(
  9293. DWORD dwTSPIVersion,
  9294. DWORD dwPermanentProviderID,
  9295. DWORD dwLineDeviceIDBase,
  9296. DWORD dwPhoneDeviceIDBase,
  9297. DWORD_PTR dwNumLines,
  9298. DWORD_PTR dwNumPhones,
  9299. ASYNC_COMPLETION lpfnCompletionProc,
  9300. LPDWORD lpdwTSPIOptions
  9301. )
  9302. {
  9303. DWORD i;
  9304. //
  9305. // Init globals
  9306. //
  9307. // If dwPermanentProviderID != 0xffffffff then we're being called
  9308. // directly by TAPISRV, so we want to init all the globals and
  9309. // keep going only if the gbInitialized flag is set (implying
  9310. // that we've gone thru all the code in EnumDevices).
  9311. //
  9312. // Otherwise, we're being called from TSPI_providerCheckForNewUser.
  9313. //
  9314. if (dwPermanentProviderID != 0xffffffff)
  9315. {
  9316. gdwLineDeviceIDBase = dwLineDeviceIDBase;
  9317. gdwPhoneDeviceIDBase = dwPhoneDeviceIDBase;
  9318. gpfnCompletionProc = lpfnCompletionProc;
  9319. *lpdwTSPIOptions = 0;
  9320. #if MEMPHIS
  9321. #else
  9322. if (!gbInitialized)
  9323. {
  9324. return 0;
  9325. }
  9326. #endif
  9327. }
  9328. //
  9329. // Adjust the .dwDeviceIDLocal values for all the initial devices
  9330. // now that we know the device id bases
  9331. //
  9332. for (i = 0; i < gdwInitialNumLineDevices; i++)
  9333. {
  9334. gpLineLookup->aEntries[i].dwDeviceIDLocal = dwLineDeviceIDBase + i;
  9335. }
  9336. for (i = 0; i < gdwInitialNumPhoneDevices; i++)
  9337. {
  9338. gpPhoneLookup->aEntries[i].dwDeviceIDLocal = dwPhoneDeviceIDBase + i;
  9339. }
  9340. //
  9341. // Start EventHandlerThread
  9342. //
  9343. gEventHandlerThreadParams.bExit = FALSE;
  9344. if (!(gEventHandlerThreadParams.hThread = CreateThread(
  9345. (LPSECURITY_ATTRIBUTES) NULL,
  9346. 0,
  9347. (LPTHREAD_START_ROUTINE) EventHandlerThread,
  9348. NULL,
  9349. 0,
  9350. &i // &dwThreadID
  9351. )))
  9352. {
  9353. LOG((TL_ERROR,
  9354. "CreateThread('EventHandlerThread') failed, err=%d",
  9355. GetLastError()
  9356. ));
  9357. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  9358. CloseHandle (gEventHandlerThreadParams.hEvent);
  9359. return LINEERR_OPERATIONFAILED;
  9360. }
  9361. return 0;
  9362. }
  9363. LONG
  9364. TSPIAPI
  9365. TSPI_providerInstall(
  9366. HWND hwndOwner,
  9367. DWORD dwPermanentProviderID
  9368. )
  9369. {
  9370. //
  9371. // Although this func is never called by TAPI v2.0, we export
  9372. // it so that the Telephony Control Panel Applet knows that it
  9373. // can add this provider via lineAddProvider(), otherwise
  9374. // Telephon.cpl will not consider it installable
  9375. //
  9376. //
  9377. return 0;
  9378. }
  9379. LONG
  9380. TSPIAPI
  9381. TSPI_providerRemove(
  9382. HWND hwndOwner,
  9383. DWORD dwPermanentProviderID
  9384. )
  9385. {
  9386. //
  9387. // Although this func is never called by TAPI v2.0, we export
  9388. // it so that the Telephony Control Panel Applet knows that it
  9389. // can remove this provider via lineRemoveProvider(), otherwise
  9390. // Telephon.cpl will not consider it removable
  9391. //
  9392. return 0;
  9393. }
  9394. LONG
  9395. TSPIAPI
  9396. TSPI_providerShutdown(
  9397. DWORD dwTSPIVersion,
  9398. DWORD dwPermanentProviderID
  9399. )
  9400. {
  9401. DWORD i;
  9402. PDRVSERVER pServer;
  9403. RPC_STATUS status;
  9404. LIST_ENTRY *pEntry;
  9405. //
  9406. // If the gbInitialized flag is not set then we never fully
  9407. // initialized because no client process with user (as opposed
  9408. // to system) privileges ever attached to tapisrv and/or there
  9409. // was no logged on user to impersonate. So we can just return 0.
  9410. //
  9411. #if MEMPHIS
  9412. #else
  9413. if (!gbInitialized)
  9414. {
  9415. return 0;
  9416. }
  9417. #endif
  9418. //
  9419. // Set the flag instructing the EventHandlerThread to terminate
  9420. //
  9421. gEventHandlerThreadParams.bExit = TRUE;
  9422. //
  9423. // If there's a network poll thread running then tell it to exit
  9424. // & wait for it to terminate
  9425. //
  9426. TapiEnterCriticalSection ( &gCriticalSection );
  9427. if (ghNetworkPollThread)
  9428. {
  9429. SetEvent (ghNptShutdownEvent);
  9430. TapiLeaveCriticalSection( &gCriticalSection );
  9431. WaitForSingleObject (ghNetworkPollThread, INFINITE);
  9432. TapiEnterCriticalSection ( &gCriticalSection );
  9433. CloseHandle (ghNetworkPollThread);
  9434. ghNetworkPollThread = NULL;
  9435. }
  9436. TapiLeaveCriticalSection( &gCriticalSection );
  9437. if (gpszThingToPassToServer)
  9438. {
  9439. DrvFree (gpszThingToPassToServer);
  9440. gpszThingToPassToServer = NULL;
  9441. }
  9442. //
  9443. // Tell the event handler thread to exit wait for it to terminate
  9444. //
  9445. while (WaitForSingleObject (gEventHandlerThreadParams.hThread, 0) !=
  9446. WAIT_OBJECT_0)
  9447. {
  9448. SetEvent (gEventHandlerThreadParams.hEvent);
  9449. Sleep (50);
  9450. }
  9451. CloseHandle (gEventHandlerThreadParams.hThread);
  9452. //
  9453. // Send detach to each server
  9454. //
  9455. #if MEMPHIS
  9456. #else
  9457. status = RpcImpersonateClient(0);
  9458. if (status != RPC_S_OK)
  9459. {
  9460. LOG((TL_ERROR, "RpcImpersonateClient failed, err=%d", status));
  9461. // fall thru
  9462. }
  9463. #endif
  9464. TapiEnterCriticalSection(&gCriticalSection);
  9465. pEntry = gpCurrentInitContext->ServerList.Flink;
  9466. while (pEntry != &gpCurrentInitContext->ServerList)
  9467. {
  9468. DWORD dwRetryCount = 0;
  9469. pServer = CONTAINING_RECORD (pEntry, DRVSERVER, ServerList);
  9470. do
  9471. {
  9472. RpcTryExcept
  9473. {
  9474. ClientDetach (&pServer->phContext);
  9475. dwRetryCount = gdwRetryCount;
  9476. }
  9477. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  9478. {
  9479. if (dwRetryCount++ < gdwRetryCount)
  9480. {
  9481. Sleep (gdwRetryTimeout);
  9482. }
  9483. }
  9484. RpcEndExcept
  9485. } while (dwRetryCount < gdwRetryCount);
  9486. pEntry = pEntry->Flink;
  9487. }
  9488. TapiLeaveCriticalSection(&gCriticalSection);
  9489. RpcRevertToSelf();
  9490. //
  9491. // Wait a period of time for all the expected rundowns to occur.
  9492. // If they all occur then free up context info for this
  9493. // provider initialization instance; otherwise, do a LoadLibrary
  9494. // on ourself (only once) to prevent the possiblity of the
  9495. // rundown routine getting called after the DLL has been unloaded,
  9496. // and insert the current init context in a "stale" queue, removing
  9497. // & freeing the oldest item in the queue if we've reached a
  9498. // pre-determined queue limit
  9499. //
  9500. #define MAX_RSP_WAIT_TIME 2000
  9501. #define RSP_WAIT_INCR 250
  9502. for(
  9503. i = 0;
  9504. ((gpCurrentInitContext->dwNumRundownsExpected != 0) &&
  9505. (i < MAX_RSP_WAIT_TIME));
  9506. i += RSP_WAIT_INCR
  9507. )
  9508. {
  9509. Sleep (RSP_WAIT_INCR);
  9510. }
  9511. if (i < MAX_RSP_WAIT_TIME)
  9512. {
  9513. FreeInitContext (gpCurrentInitContext);
  9514. }
  9515. else
  9516. {
  9517. if (!gbLoadedSelf)
  9518. {
  9519. LoadLibrary (MODULE_NAME);
  9520. gbLoadedSelf = TRUE;
  9521. }
  9522. gpCurrentInitContext->pNextStaleInitContext = gpStaleInitContexts;
  9523. gpStaleInitContexts = gpCurrentInitContext;
  9524. LOG((TL_INFO, "Queued stale init context x%x", gpCurrentInitContext));
  9525. #define RSP_MAX_NUM_STALE_INIT_CONTEXTS 4
  9526. if (gdwNumStaleInitContexts >= RSP_MAX_NUM_STALE_INIT_CONTEXTS)
  9527. {
  9528. PRSP_INIT_CONTEXT pPrevStaleInitContext;
  9529. while (gpCurrentInitContext->pNextStaleInitContext)
  9530. {
  9531. pPrevStaleInitContext = gpCurrentInitContext;
  9532. gpCurrentInitContext =
  9533. gpCurrentInitContext->pNextStaleInitContext;
  9534. }
  9535. pPrevStaleInitContext->pNextStaleInitContext = NULL;
  9536. FreeInitContext (gpCurrentInitContext);
  9537. LOG((TL_INFO, "Freed stale init context x%x", gpCurrentInitContext));
  9538. }
  9539. else
  9540. {
  9541. gdwNumStaleInitContexts++;
  9542. }
  9543. }
  9544. //
  9545. // Unregister out rpc server interface
  9546. //
  9547. status = RpcServerUnregisterIf(
  9548. remotesp_ServerIfHandle, // interface to register
  9549. NULL, // MgrTypeUuid
  9550. TRUE // wait for calls to complete
  9551. );
  9552. LOG((TL_INFO, "RpcServerUnregisterIf ret'd %d", status));
  9553. //
  9554. // Clean up resources
  9555. //
  9556. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  9557. CloseHandle (gEventHandlerThreadParams.hEvent);
  9558. //
  9559. // Note: We intentionally leak the hMailslot for now, because the
  9560. // docs say that the mailslot is not actually destroyed
  9561. // until the process exits. Since service providers can get
  9562. // loaded & unloaded alot without tapisrv.exe ever exiting,
  9563. // we could wind up with alot of mailslots laying around.
  9564. //
  9565. // Closing this hMailSlot to avoid dependance on the registry to
  9566. // remember the hMailSlot.
  9567. //
  9568. if (gEventHandlerThreadParams.hMailslot != INVALID_HANDLE_VALUE)
  9569. {
  9570. CloseHandle (gEventHandlerThreadParams.hMailslot);
  9571. CloseHandle (gEventHandlerThreadParams.hMailslotEvent);
  9572. }
  9573. DrvFree (gEventHandlerThreadParams.pMsgBuffer);
  9574. //
  9575. // Manually walk the handle table, completing any pending async
  9576. // requests with an error. No need to call any post-processing
  9577. // procs, since any calls would've been torn down already, and
  9578. // the other non-MakeCall-style post processing procs simply do
  9579. // CopyMemory, etc.
  9580. //
  9581. // Also, if the gbLoadedSelf flag is set, then we want to deref
  9582. // active handles left in the table, because the table is
  9583. // only freed in DLL_PROCESS_DETACH (which won't get called now)
  9584. // and we don't want to end up leaking handles.
  9585. //
  9586. {
  9587. PHANDLETABLEENTRY pEntry, pEnd;
  9588. PHANDLETABLEHEADER pHeader = ghHandleTable;
  9589. EnterCriticalSection (&pHeader->Lock);
  9590. pEnd = pHeader->Table + pHeader->NumEntries;
  9591. for (pEntry = pHeader->Table; pEntry != pEnd; pEntry++)
  9592. {
  9593. if (pEntry->Handle)
  9594. {
  9595. PASYNCREQUESTCONTEXT pContext = pEntry->Context.C;
  9596. if (pEntry->Context.C2 == (LPVOID) 1)
  9597. {
  9598. DereferenceObject (
  9599. ghHandleTable,
  9600. pEntry->Handle,
  9601. (DWORD)pEntry->ReferenceCount
  9602. );
  9603. }
  9604. else if (pContext == (PASYNCREQUESTCONTEXT) -1 ||
  9605. pContext->dwKey == DRVASYNC_KEY)
  9606. {
  9607. (*gpfnCompletionProc)(
  9608. DWORD_CAST((ULONG_PTR)pEntry->Context.C2,__FILE__,__LINE__),
  9609. LINEERR_OPERATIONFAILED
  9610. );
  9611. if (gbLoadedSelf)
  9612. {
  9613. DereferenceObject(
  9614. ghHandleTable,
  9615. pEntry->Handle,
  9616. (DWORD)pEntry->ReferenceCount
  9617. );
  9618. }
  9619. }
  9620. }
  9621. }
  9622. LeaveCriticalSection (&pHeader->Lock);
  9623. }
  9624. //
  9625. // Free the lookup tables
  9626. //
  9627. while (gpLineLookup)
  9628. {
  9629. PDRVLINELOOKUP pNextLineLookup = gpLineLookup->pNext;
  9630. DrvFree (gpLineLookup);
  9631. gpLineLookup = pNextLineLookup;
  9632. }
  9633. while (gpPhoneLookup)
  9634. {
  9635. PDRVPHONELOOKUP pNextPhoneLookup = gpPhoneLookup->pNext;
  9636. DrvFree (gpPhoneLookup);
  9637. gpPhoneLookup = pNextPhoneLookup;
  9638. }
  9639. TRACELOGDEREGISTER();
  9640. return 0;
  9641. }
  9642. LONG
  9643. TSPIAPI
  9644. TSPI_providerUIIdentify(
  9645. LPWSTR lpszUIDLLName
  9646. )
  9647. {
  9648. LONG lResult;
  9649. PDRVSERVER pServer = NULL;
  9650. LPDWORD lpdwHold = (LPDWORD) lpszUIDLLName;
  9651. // we've put a special case into tapisrv to give this addtional info
  9652. // to remotesp. the buffer passed in is in the following
  9653. // format
  9654. // DWORD dwKey == RSP_MSG tells us that TAPISRV did fill in this info
  9655. // DWORD dwDeviceID == device ID of whatever
  9656. // DWORD dwType == TUISPIDLL_ type
  9657. // this way, remotesp can intelligently rpc over to the
  9658. // telephony server.
  9659. BOOL bOK = (lpdwHold[0] == RSP_MSG);
  9660. DWORD dwDeviceID = (bOK ? lpdwHold[1] : 0);
  9661. DWORD dwType = (bOK ? lpdwHold[2] : TUISPIDLL_OBJECT_LINEID);
  9662. // we're being asked for the ui dll name
  9663. // we will return remotesp, but at this point we'll try to find out the
  9664. // real ui dll
  9665. // note that we only only one service provider here, but we may be able
  9666. // to add support for additonal ones by saving the ui dll name on
  9667. // a per provider basis
  9668. REMOTE_ARG_TYPES argTypes[] =
  9669. {
  9670. LineID,
  9671. Dword,
  9672. lpGet_SizeToFollow,
  9673. Size
  9674. };
  9675. ULONG_PTR args[] =
  9676. {
  9677. (ULONG_PTR) dwDeviceID,
  9678. (ULONG_PTR) dwType,
  9679. (ULONG_PTR) gszRealSPUIDLL,
  9680. (ULONG_PTR) MAX_PATH
  9681. };
  9682. REMOTE_FUNC_ARGS funcArgs =
  9683. {
  9684. MAKELONG (LINE_FUNC | SYNC | 4, xGetUIDllName),
  9685. args,
  9686. argTypes
  9687. };
  9688. if (bOK)
  9689. {
  9690. // need to get the server first
  9691. if (dwType == TUISPIDLL_OBJECT_LINEID)
  9692. {
  9693. if (gpLineLookup)
  9694. {
  9695. PDRVLINE pLine;
  9696. if ((pLine = GetLineFromID (dwDeviceID)))
  9697. {
  9698. pServer = pLine->pServer;
  9699. }
  9700. }
  9701. }
  9702. else if (dwType == TUISPIDLL_OBJECT_LINEID)
  9703. {
  9704. argTypes[0] = PhoneID;
  9705. if (gpPhoneLookup)
  9706. {
  9707. PDRVPHONE pPhone;
  9708. if ((pPhone = GetPhoneFromID (dwDeviceID)))
  9709. {
  9710. pServer = pPhone->pServer;
  9711. }
  9712. }
  9713. }
  9714. else
  9715. {
  9716. }
  9717. // call over.
  9718. // in the case of the telephony cpl, pLine has not been initialized yet,
  9719. // so we have to do this check. in that case, we won't have a
  9720. // gszuidllname, but it's OK since the cpl only calls provider UI functions
  9721. // which remotesp can handle by itself.
  9722. if (pServer)
  9723. {
  9724. LOG((TL_INFO, "Calling GetUIDllName in server"));
  9725. lResult = REMOTEDOFUNC (&funcArgs, "GetUIDllName");
  9726. }
  9727. }
  9728. // always return remotesp
  9729. wcscpy(lpszUIDLLName, L"remotesp.tsp");
  9730. return 0;
  9731. }
  9732. HINSTANCE
  9733. TAPILoadLibraryW(
  9734. PWSTR pLibrary
  9735. )
  9736. {
  9737. PSTR pszTempString;
  9738. HINSTANCE hResult;
  9739. DWORD dwSize;
  9740. dwSize = WideCharToMultiByte(
  9741. GetACP(),
  9742. 0,
  9743. pLibrary,
  9744. -1,
  9745. NULL,
  9746. 0,
  9747. NULL,
  9748. NULL
  9749. );
  9750. if ( NULL == (pszTempString = LocalAlloc( LPTR, dwSize )) )
  9751. {
  9752. LOG((TL_ERROR, "Alloc failed - LoadLibW - 0x%08lx", dwSize));
  9753. return NULL;
  9754. }
  9755. WideCharToMultiByte(
  9756. GetACP(),
  9757. 0,
  9758. pLibrary,
  9759. dwSize,
  9760. pszTempString,
  9761. dwSize,
  9762. NULL,
  9763. NULL
  9764. );
  9765. hResult = LoadLibrary (pszTempString);
  9766. LocalFree (pszTempString);
  9767. return hResult;
  9768. }
  9769. //
  9770. // ---------------------------- TUISPI_xxx funcs ------------------------------
  9771. //
  9772. LONG
  9773. LoadUIDll(
  9774. DWORD dwDeviceID,
  9775. DWORD dwDeviceType,
  9776. HANDLE *phDll,
  9777. CHAR *pszTUISPI_xxx,
  9778. TUISPIPROC *ppfnTUISPI_xxx,
  9779. TUISPIDLLCALLBACK lpfnUIDLLCallback
  9780. )
  9781. {
  9782. //
  9783. // At this point, remotesp is loaded as a ui dll in tapi32.dll's
  9784. // (& the client's) context, so we have none of the global info
  9785. // normally available. Use the ui callback to call into the
  9786. // other instance of remotesp to get the real ui dll name.
  9787. //
  9788. // Note we only handle on sp here, but can easily add in more
  9789. // info when we handle more than one
  9790. //
  9791. LPDWORD lpBuffer;
  9792. if (!(lpBuffer = DrvAlloc (MAX_PATH + 2 * sizeof (DWORD))))
  9793. {
  9794. return (dwDeviceType == TUISPIDLL_OBJECT_PHONEID ?
  9795. PHONEERR_NOMEM : LINEERR_NOMEM);
  9796. }
  9797. // format is
  9798. // DWORD dwKey
  9799. // DWORD dwMsgType
  9800. // LPWSTR szUIDLLName (returned)
  9801. lpBuffer[0] = RSP_MSG;
  9802. lpBuffer[1] = RSP_MSG_UIID;
  9803. lpfnUIDLLCallback(
  9804. dwDeviceID,
  9805. dwDeviceType,
  9806. lpBuffer,
  9807. MAX_PATH + 2 * sizeof (DWORD)
  9808. );
  9809. *phDll = TAPILoadLibraryW((LPWSTR)(lpBuffer + 2));
  9810. DrvFree (lpBuffer);
  9811. if (!*phDll)
  9812. {
  9813. LOG((TL_ERROR, "LoadLibrary failed in the LoadUIDll"));
  9814. return (dwDeviceType == TUISPIDLL_OBJECT_PHONEID ?
  9815. PHONEERR_OPERATIONFAILED : LINEERR_OPERATIONFAILED);
  9816. }
  9817. if (!(*ppfnTUISPI_xxx = (TUISPIPROC) GetProcAddress(
  9818. *phDll,
  9819. pszTUISPI_xxx
  9820. )))
  9821. {
  9822. LOG((TL_ERROR, "GetProcAddress failed on LoadUIDll"));
  9823. FreeLibrary(*phDll);
  9824. return (dwDeviceType == TUISPIDLL_OBJECT_PHONEID ?
  9825. PHONEERR_OPERATIONFAILED : LINEERR_OPERATIONFAILED);
  9826. }
  9827. return 0;
  9828. }
  9829. LONG
  9830. TSPIAPI
  9831. TUISPI_lineConfigDialog(
  9832. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  9833. DWORD dwDeviceID,
  9834. HWND hwndOwner,
  9835. LPCWSTR lpszDeviceClass
  9836. )
  9837. {
  9838. TUISPIPROC pfnTUISPI_lineConfigDialog;
  9839. HANDLE hDll;
  9840. LONG lResult;
  9841. lResult = LoadUIDll(
  9842. dwDeviceID,
  9843. TUISPIDLL_OBJECT_LINEID,
  9844. &hDll,
  9845. "TUISPI_lineConfigDialog",
  9846. &pfnTUISPI_lineConfigDialog,
  9847. lpfnUIDLLCallback
  9848. );
  9849. if (lResult)
  9850. {
  9851. return lResult;
  9852. }
  9853. LOG((TL_INFO, "Calling TUISPI_lineConfigDialog"));
  9854. lResult = (*pfnTUISPI_lineConfigDialog)(
  9855. lpfnUIDLLCallback,
  9856. dwDeviceID,
  9857. hwndOwner,
  9858. lpszDeviceClass
  9859. );
  9860. FreeLibrary (hDll);
  9861. return lResult;
  9862. }
  9863. LONG
  9864. TSPIAPI
  9865. TUISPI_lineConfigDialogEdit(
  9866. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  9867. DWORD dwDeviceID,
  9868. HWND hwndOwner,
  9869. LPCWSTR lpszDeviceClass,
  9870. LPVOID const lpDeviceConfigIn,
  9871. DWORD dwSize,
  9872. LPVARSTRING lpDeviceConfigOut
  9873. )
  9874. {
  9875. TUISPIPROC pfnTUISPI_lineConfigDialogEdit;
  9876. HANDLE hDll;
  9877. LONG lResult;
  9878. lResult = LoadUIDll(
  9879. dwDeviceID,
  9880. TUISPIDLL_OBJECT_LINEID,
  9881. &hDll,
  9882. "TUISPI_lineConfigDialogEdit",
  9883. &pfnTUISPI_lineConfigDialogEdit,
  9884. lpfnUIDLLCallback
  9885. );
  9886. if (lResult)
  9887. {
  9888. return lResult;
  9889. }
  9890. LOG((TL_INFO, "Calling TUISPI_lineConfigDialogEdit"));
  9891. lResult = (*pfnTUISPI_lineConfigDialogEdit)(
  9892. lpfnUIDLLCallback,
  9893. dwDeviceID,
  9894. hwndOwner,
  9895. lpszDeviceClass,
  9896. lpDeviceConfigIn,
  9897. dwSize,
  9898. lpDeviceConfigOut
  9899. );
  9900. FreeLibrary(hDll);
  9901. return lResult;
  9902. }
  9903. LONG
  9904. TSPIAPI
  9905. TUISPI_phoneConfigDialog(
  9906. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  9907. DWORD dwDeviceID,
  9908. HWND hwndOwner,
  9909. LPCWSTR lpszDeviceClass
  9910. )
  9911. {
  9912. TUISPIPROC pfnTUISPI_phoneConfigDialog;
  9913. HANDLE hDll;
  9914. LONG lResult;
  9915. lResult = LoadUIDll(
  9916. dwDeviceID,
  9917. TUISPIDLL_OBJECT_PHONEID,
  9918. &hDll,
  9919. "TUISPI_phoneConfigDialog",
  9920. &pfnTUISPI_phoneConfigDialog,
  9921. lpfnUIDLLCallback
  9922. );
  9923. if (lResult)
  9924. {
  9925. return lResult;
  9926. }
  9927. LOG((TL_INFO, "Calling TUISPI_phoneConfigDialog"));
  9928. lResult = (*pfnTUISPI_phoneConfigDialog)(
  9929. lpfnUIDLLCallback,
  9930. dwDeviceID,
  9931. hwndOwner,
  9932. lpszDeviceClass
  9933. );
  9934. FreeLibrary(hDll);
  9935. return lResult;
  9936. }
  9937. LONG
  9938. TSPIAPI
  9939. TUISPI_providerConfig(
  9940. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  9941. HWND hwndOwner,
  9942. DWORD dwPermanentProviderID
  9943. )
  9944. {
  9945. return LINEERR_OPERATIONFAILED;
  9946. /*
  9947. DialogBoxParam(
  9948. ghInst,
  9949. MAKEINTRESOURCE(IDD_REMOTESPCONFIG),
  9950. hwndOwner,
  9951. (DLGPROC) ConfigDlgProc,
  9952. (LPARAM) dwPermanentProviderID
  9953. );
  9954. return 0;
  9955. */
  9956. }
  9957. /*
  9958. LONG
  9959. TSPIAPI
  9960. TUISPI_providerGenericDialog(
  9961. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  9962. HTAPIDIALOGINSTANCE htDlgInst,
  9963. LPVOID lpParams,
  9964. DWORD dwSize,
  9965. HANDLE hEvent
  9966. )
  9967. {
  9968. TUISPIPROC pfnTUISPI_providerGenericDialog;
  9969. HANDLE hDll;
  9970. LONG lResult;
  9971. lResult = LoadUIDll(
  9972. (HWND) 0,
  9973. 0, // hardcode 0
  9974. TUISPIDLL_OBJECT_LINEID,
  9975. &hDll,
  9976. "TUISPI_providerGenericDialog",
  9977. &pfnTUISPI_providerGenericDialog
  9978. );
  9979. if (lResult == 0)
  9980. {
  9981. LOG((TL_INFO, "Calling TUISPI_providerGenericDialog"));
  9982. lResult = (*pfnTUISPI_providerGenericDialog)(
  9983. lpfnUIDLLCallback,
  9984. htDlgInst,
  9985. lpParams,
  9986. dwSize,
  9987. hEvent
  9988. );
  9989. FreeLibrary(hDll);
  9990. }
  9991. else
  9992. {
  9993. LOG((TL_ERROR, "Failed to load UI DLL"));
  9994. }
  9995. return lResult;
  9996. }
  9997. LONG
  9998. TSPIAPI
  9999. TUISPI_providerGenericDialogData(
  10000. HTAPIDIALOGINSTANCE htDlgInst,
  10001. LPVOID lpParams,
  10002. DWORD dwSize
  10003. )
  10004. {
  10005. TUISPIPROC pfnTUISPI_providerGenericDialogData;
  10006. HANDLE hDll;
  10007. LONG lResult;
  10008. DBGOUT((
  10009. 3,
  10010. "TUISPI_providerGenericDialogData: enter (lpParams=x%x, dwSize=x%x)",
  10011. lpParams,
  10012. dwSize
  10013. ));
  10014. lResult = LoadUIDll(
  10015. (HWND) 0,
  10016. 0,
  10017. TUISPIDLL_OBJECT_LINEID,
  10018. &hDll,
  10019. "TUISPI_providerGenericDialogData",
  10020. &pfnTUISPI_providerGenericDialogData
  10021. );
  10022. if (lResult == 0)
  10023. {
  10024. LOG((TL_INFO, "Calling TUISPI_providerGenericDialogData"));
  10025. lResult = (*pfnTUISPI_providerGenericDialogData)(
  10026. htDlgInst,
  10027. lpParams,
  10028. dwSize
  10029. );
  10030. FreeLibrary(hDll);
  10031. }
  10032. else
  10033. {
  10034. LOG((TL_ERROR, "Failed to load UI DLL"));
  10035. }
  10036. return lResult;
  10037. }
  10038. */
  10039. //
  10040. // GetRSPID
  10041. // To return the provider ID of remotesp if any. Otherwise
  10042. // return zero
  10043. //
  10044. DWORD
  10045. GetRSPID (
  10046. )
  10047. {
  10048. DWORD dwRet = 0;
  10049. LONG (WINAPI *pfnGetProviderList)();
  10050. DWORD dwTotalSize, i;
  10051. HINSTANCE hTapi32 = NULL;
  10052. LPLINEPROVIDERLIST pProviderList = NULL;
  10053. LPLINEPROVIDERENTRY pProviderEntry;
  10054. //
  10055. // Load Tapi32.dll & get a pointer to the lineGetProviderList
  10056. // func. We could just statically link with Tapi32.lib and
  10057. // avoid the hassle (and this wouldn't have any adverse
  10058. // performance effects because of the fact that this
  10059. // implementation has a separate ui dll that runs only on the
  10060. // client context), but a provider who implemented these funcs
  10061. // in it's TSP module would want to do an explicit load like
  10062. // we do here to prevent the performance hit of Tapi32.dll
  10063. // always getting loaded in Tapisrv.exe's context.
  10064. //
  10065. if (!(hTapi32 = LoadLibrary ("tapi32.dll")))
  10066. {
  10067. LOG((TL_ERROR,
  10068. "LoadLibrary(tapi32.dll) failed, err=%d",
  10069. GetLastError()
  10070. ));
  10071. goto ExitHere;
  10072. }
  10073. if (!((FARPROC) pfnGetProviderList = GetProcAddress(
  10074. hTapi32,
  10075. (LPCSTR) "lineGetProviderList"
  10076. )))
  10077. {
  10078. LOG((TL_ERROR,
  10079. "GetProcAddr(lineGetProviderList) failed, err=%d",
  10080. GetLastError()
  10081. ));
  10082. goto ExitHere;
  10083. }
  10084. //
  10085. // Loop until we get the full provider list
  10086. //
  10087. dwTotalSize = sizeof (LINEPROVIDERLIST);
  10088. while (1)
  10089. {
  10090. if (!(pProviderList = DrvAlloc (dwTotalSize)))
  10091. {
  10092. goto ExitHere;
  10093. }
  10094. pProviderList->dwTotalSize = dwTotalSize;
  10095. if (((*pfnGetProviderList)(0x00020000, pProviderList)) != 0)
  10096. {
  10097. goto ExitHere;
  10098. }
  10099. if (pProviderList->dwNeededSize > pProviderList->dwTotalSize)
  10100. {
  10101. dwTotalSize = pProviderList->dwNeededSize;
  10102. DrvFree (pProviderList);
  10103. }
  10104. else
  10105. {
  10106. break;
  10107. }
  10108. }
  10109. //
  10110. // Inspect the provider list entries to see if this provider
  10111. // is already installed
  10112. //
  10113. pProviderEntry = (LPLINEPROVIDERENTRY) (((LPBYTE) pProviderList) +
  10114. pProviderList->dwProviderListOffset);
  10115. for (i = 0; i < pProviderList->dwNumProviders; i++)
  10116. {
  10117. char *pszInstalledProviderName = ((char *) pProviderList) +
  10118. pProviderEntry->dwProviderFilenameOffset,
  10119. *psz;
  10120. if ((psz = strrchr (pszInstalledProviderName, '\\')))
  10121. {
  10122. pszInstalledProviderName = psz + 1;
  10123. }
  10124. if (lstrcmpi (pszInstalledProviderName, "remotesp.tsp") == 0)
  10125. {
  10126. dwRet = pProviderEntry->dwPermanentProviderID;
  10127. goto ExitHere;
  10128. }
  10129. pProviderEntry++;
  10130. }
  10131. ExitHere:
  10132. if (hTapi32)
  10133. {
  10134. FreeLibrary (hTapi32);
  10135. }
  10136. if (pProviderList)
  10137. {
  10138. DrvFree (pProviderList);
  10139. }
  10140. return dwRet;
  10141. }
  10142. LONG
  10143. TSPIAPI
  10144. TUISPI_providerInstall(
  10145. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  10146. HWND hwndOwner,
  10147. DWORD dwPermanentProviderID
  10148. )
  10149. {
  10150. if (GetRSPID())
  10151. {
  10152. // Return failure if it is already installed
  10153. // to prevent duplication
  10154. return TAPIERR_PROVIDERALREADYINSTALLED;
  10155. }
  10156. else
  10157. {
  10158. return S_OK;
  10159. }
  10160. }
  10161. LONG
  10162. TSPIAPI
  10163. TUISPI_providerRemove(
  10164. TUISPIDLLCALLBACK lpfnUIDLLCallback,
  10165. HWND hwndOwner,
  10166. DWORD dwPermanentProviderID
  10167. )
  10168. {
  10169. DWORD dwProviderID = GetRSPID();
  10170. LONG lResult = S_OK;
  10171. char buf[32];
  10172. HKEY hTelephonyKey;
  10173. if (dwProviderID == 0 || dwProviderID != dwPermanentProviderID)
  10174. {
  10175. // return failure if remotesp is not installed
  10176. lResult = LINEERR_OPERATIONFAILED;
  10177. goto ExitHere;
  10178. }
  10179. //
  10180. // Clean up our ProviderN section
  10181. //
  10182. wsprintf (buf, "Provider%d", dwPermanentProviderID);
  10183. if (RegOpenKeyExA(
  10184. HKEY_LOCAL_MACHINE,
  10185. gszTelephonyKey,
  10186. 0,
  10187. KEY_ALL_ACCESS,
  10188. &hTelephonyKey
  10189. ) == ERROR_SUCCESS)
  10190. {
  10191. SHDeleteKey (hTelephonyKey, buf);
  10192. RegCloseKey (hTelephonyKey);
  10193. }
  10194. else
  10195. {
  10196. lResult = LINEERR_OPERATIONFAILED;
  10197. }
  10198. ExitHere:
  10199. return lResult;
  10200. }
  10201. //
  10202. // ------------------------ Private support routines --------------------------
  10203. //
  10204. #if DBG
  10205. VOID
  10206. DbgPrt(
  10207. IN DWORD dwDbgLevel,
  10208. IN PUCHAR lpszFormat,
  10209. IN ...
  10210. )
  10211. /*++
  10212. Routine Description:
  10213. Formats the incoming debug message & calls DbgPrint
  10214. Arguments:
  10215. DbgLevel - level of message verboseness
  10216. DbgMessage - printf-style format string, followed by appropriate
  10217. list of arguments
  10218. Return Value:
  10219. --*/
  10220. {
  10221. if (dwDbgLevel <= gdwDebugLevel)
  10222. {
  10223. char buf[128] = "REMOTESP: ";
  10224. va_list ap;
  10225. va_start(ap, lpszFormat);
  10226. wvsprintf (&buf[10], lpszFormat, ap);
  10227. lstrcatA (buf, "\n");
  10228. OutputDebugStringA (buf);
  10229. va_end(ap);
  10230. }
  10231. }
  10232. #endif
  10233. LONG
  10234. AddLine(
  10235. PDRVSERVER pServer,
  10236. DWORD dwLocalID,
  10237. DWORD dwServerID,
  10238. BOOL bInit,
  10239. BOOL bNegotiate,
  10240. DWORD dwAPIVersion,
  10241. LPLINEEXTENSIONID pExtID
  10242. )
  10243. {
  10244. PDRVLINE pLine;
  10245. PDRVLINELOOKUP pLineLookup;
  10246. LONG lResult = 0;
  10247. BOOL bLeaveCriticalSection = FALSE;
  10248. LINEDEVCAPS lineDevCaps;
  10249. DWORD dwPermLineID;
  10250. int iEntry;
  10251. //
  10252. // Get the permanent line device ID
  10253. //
  10254. static REMOTE_ARG_TYPES argTypes[] =
  10255. {
  10256. lpServer,
  10257. Dword,
  10258. Dword,
  10259. Dword,
  10260. Dword,
  10261. lpGet_Struct
  10262. };
  10263. ULONG_PTR args[] =
  10264. {
  10265. (ULONG_PTR) pServer,
  10266. (ULONG_PTR) pServer->hLineApp,
  10267. (ULONG_PTR) dwServerID,
  10268. (ULONG_PTR) (dwAPIVersion?dwAPIVersion:TAPI_VERSION1_0),
  10269. (ULONG_PTR) 0,
  10270. (ULONG_PTR) &lineDevCaps
  10271. };
  10272. REMOTE_FUNC_ARGS funcArgs =
  10273. {
  10274. MAKELONG (LINE_FUNC | SYNC | 6, lGetDevCaps),
  10275. args,
  10276. argTypes
  10277. };
  10278. lineDevCaps.dwTotalSize = sizeof(LINEDEVCAPS);
  10279. lResult = REMOTEDOFUNC(&funcArgs, "lineGetDevCaps");
  10280. if (lResult != 0)
  10281. {
  10282. goto ExitHere;
  10283. }
  10284. dwPermLineID = lineDevCaps.dwPermanentLineID;
  10285. TapiEnterCriticalSection(&gCriticalSection);
  10286. bLeaveCriticalSection = TRUE;
  10287. if (!gpLineLookup)
  10288. {
  10289. if (!(gpLineLookup = DrvAlloc(
  10290. sizeof(DRVLINELOOKUP) +
  10291. (DEF_NUM_LINE_ENTRIES-1) * sizeof (DRVLINE)
  10292. )))
  10293. {
  10294. lResult = LINEERR_NOMEM;
  10295. goto ExitHere;
  10296. }
  10297. gpLineLookup->dwTotalEntries = DEF_NUM_LINE_ENTRIES;
  10298. }
  10299. pLineLookup = gpLineLookup;
  10300. //
  10301. // Check if the line is already in based on the permanent ID
  10302. //
  10303. if (!bInit)
  10304. {
  10305. while (pLineLookup)
  10306. {
  10307. pLine = pLineLookup->aEntries;
  10308. for (iEntry = 0;
  10309. iEntry < (int)pLineLookup->dwUsedEntries;
  10310. ++iEntry, ++pLine)
  10311. {
  10312. if ((pLine->dwPermanentLineID == dwPermLineID) &&
  10313. (pLine->pServer->hTapSrv == pServer->hTapSrv))
  10314. {
  10315. //
  10316. // if dwDeviceIDServer == (-1), it was removed earlier
  10317. // put it back, otherwise fail the operation
  10318. //
  10319. if (pLine->dwDeviceIDServer == 0xffffffff)
  10320. {
  10321. pLine->dwDeviceIDServer = dwServerID;
  10322. pLine->dwDeviceIDLocal = dwLocalID;
  10323. }
  10324. else
  10325. {
  10326. lResult = LINEERR_INUSE;
  10327. }
  10328. goto ExitHere;
  10329. }
  10330. }
  10331. pLineLookup = pLineLookup->pNext;
  10332. }
  10333. }
  10334. pLineLookup = gpLineLookup;
  10335. while (pLineLookup->pNext)
  10336. {
  10337. pLineLookup = pLineLookup->pNext;
  10338. }
  10339. if (pLineLookup->dwUsedEntries == pLineLookup->dwTotalEntries)
  10340. {
  10341. PDRVLINELOOKUP pNewLineLookup;
  10342. if (!(pNewLineLookup = DrvAlloc(
  10343. sizeof(DRVLINELOOKUP) +
  10344. (2 * pLineLookup->dwTotalEntries - 1) * sizeof(DRVLINE)
  10345. )))
  10346. {
  10347. lResult = LINEERR_NOMEM;
  10348. goto ExitHere;
  10349. }
  10350. pNewLineLookup->dwTotalEntries = 2 * pLineLookup->dwTotalEntries;
  10351. if (bInit)
  10352. {
  10353. pNewLineLookup->dwUsedEntries = pLineLookup->dwTotalEntries;
  10354. CopyMemory(
  10355. pNewLineLookup->aEntries,
  10356. pLineLookup->aEntries,
  10357. pLineLookup->dwTotalEntries * sizeof (DRVLINE)
  10358. );
  10359. DrvFree (pLineLookup);
  10360. gpLineLookup = pNewLineLookup;
  10361. }
  10362. else
  10363. {
  10364. pLineLookup->pNext = pNewLineLookup;
  10365. }
  10366. pLineLookup = pNewLineLookup;
  10367. //
  10368. // Fix the hDeviceCallback in PDRVLINE
  10369. //
  10370. pLine = pLineLookup->aEntries;
  10371. for (iEntry = 0; iEntry < (int)pLineLookup->dwUsedEntries; ++iEntry)
  10372. {
  10373. if (pLine->hDeviceCallback)
  10374. {
  10375. DereferenceObject (
  10376. ghHandleTable,
  10377. pLine->hDeviceCallback,
  10378. 1
  10379. );
  10380. pLine->hDeviceCallback = (DWORD) NewObject (
  10381. ghHandleTable,
  10382. pLine,
  10383. (LPVOID) 1
  10384. );
  10385. }
  10386. }
  10387. }
  10388. pLine = pLineLookup->aEntries + pLineLookup->dwUsedEntries;
  10389. pLine->pServer = pServer;
  10390. pLine->dwDeviceIDLocal = dwLocalID;
  10391. pLine->dwDeviceIDServer = dwServerID;
  10392. pLine->dwPermanentLineID = dwPermLineID;
  10393. if (bInit)
  10394. {
  10395. gdwInitialNumLineDevices++;
  10396. }
  10397. pLineLookup->dwUsedEntries++;
  10398. //
  10399. // Negotiate the API/SPI version
  10400. //
  10401. if (bNegotiate)
  10402. {
  10403. if (dwAPIVersion)
  10404. {
  10405. pLine->dwXPIVersion = dwAPIVersion;
  10406. CopyMemory (&pLine->ExtensionID, pExtID, sizeof (*pExtID));
  10407. }
  10408. else
  10409. {
  10410. static REMOTE_ARG_TYPES argTypes[] =
  10411. {
  10412. Dword,
  10413. LineID,
  10414. Dword,
  10415. Dword,
  10416. lpDword,
  10417. lpGet_SizeToFollow,
  10418. Size
  10419. };
  10420. ULONG_PTR args[] =
  10421. {
  10422. (ULONG_PTR) pServer->hLineApp,
  10423. (ULONG_PTR) dwLocalID, // dwServerID,
  10424. (ULONG_PTR) TAPI_VERSION1_0,
  10425. (ULONG_PTR) TAPI_VERSION_CURRENT,
  10426. (ULONG_PTR) &pLine->dwXPIVersion,
  10427. (ULONG_PTR) &pLine->ExtensionID,
  10428. (ULONG_PTR) sizeof (LINEEXTENSIONID)
  10429. };
  10430. REMOTE_FUNC_ARGS funcArgs =
  10431. {
  10432. MAKELONG (LINE_FUNC | SYNC | 7, lNegotiateAPIVersion),
  10433. args,
  10434. argTypes
  10435. };
  10436. REMOTEDOFUNC (&funcArgs, "lineNegotiateAPIVersion");
  10437. }
  10438. }
  10439. ExitHere:
  10440. if (bLeaveCriticalSection)
  10441. {
  10442. TapiLeaveCriticalSection(&gCriticalSection);
  10443. }
  10444. return lResult;
  10445. }
  10446. LONG
  10447. AddPhone(
  10448. PDRVSERVER pServer,
  10449. DWORD dwDeviceIDLocal,
  10450. DWORD dwDeviceIDServer,
  10451. BOOL bInit,
  10452. BOOL bNegotiate,
  10453. DWORD dwAPIVersion,
  10454. LPPHONEEXTENSIONID pExtID
  10455. )
  10456. {
  10457. PDRVPHONE pPhone;
  10458. PDRVPHONELOOKUP pPhoneLookup;
  10459. LONG lResult = 0;
  10460. BOOL bLeaveCriticalSection = FALSE;
  10461. PHONECAPS phoneDevCaps;
  10462. DWORD dwPermPhoneID;
  10463. int iEntry;
  10464. //
  10465. // Get the permanent phone device ID
  10466. //
  10467. static REMOTE_ARG_TYPES argTypes[] =
  10468. {
  10469. lpServer,
  10470. Dword,
  10471. Dword,
  10472. Dword,
  10473. Dword,
  10474. lpGet_Struct
  10475. };
  10476. ULONG_PTR args[] =
  10477. {
  10478. (ULONG_PTR) pServer,
  10479. (ULONG_PTR) pServer->hPhoneApp,
  10480. (ULONG_PTR) dwDeviceIDServer,
  10481. (ULONG_PTR) (dwAPIVersion?dwAPIVersion:TAPI_VERSION1_0),
  10482. (ULONG_PTR) 0,
  10483. (ULONG_PTR) &phoneDevCaps
  10484. };
  10485. REMOTE_FUNC_ARGS funcArgs =
  10486. {
  10487. MAKELONG (PHONE_FUNC | SYNC | 6, pGetDevCaps),
  10488. args,
  10489. argTypes
  10490. };
  10491. phoneDevCaps.dwTotalSize = sizeof(PHONECAPS);
  10492. lResult = REMOTEDOFUNC (&funcArgs, "phoneGetDevCaps");
  10493. if (lResult != 0)
  10494. {
  10495. goto ExitHere;
  10496. }
  10497. dwPermPhoneID = phoneDevCaps.dwPermanentPhoneID;
  10498. TapiEnterCriticalSection(&gCriticalSection);
  10499. bLeaveCriticalSection = TRUE;
  10500. if (!gpPhoneLookup)
  10501. {
  10502. if (!(gpPhoneLookup = DrvAlloc(
  10503. sizeof(DRVPHONELOOKUP) +
  10504. (DEF_NUM_PHONE_ENTRIES-1) * sizeof (DRVPHONE)
  10505. )))
  10506. {
  10507. lResult = (bInit ? LINEERR_NOMEM : PHONEERR_NOMEM);
  10508. goto ExitHere;
  10509. }
  10510. gpPhoneLookup->dwTotalEntries = DEF_NUM_PHONE_ENTRIES;
  10511. }
  10512. //
  10513. // Check if the phone device is already in based on the permanent ID
  10514. //
  10515. if (!bInit)
  10516. {
  10517. pPhoneLookup = gpPhoneLookup;
  10518. while (pPhoneLookup)
  10519. {
  10520. pPhone = pPhoneLookup->aEntries;
  10521. for (iEntry = 0;
  10522. iEntry < (int)pPhoneLookup->dwUsedEntries;
  10523. ++iEntry, ++pPhone)
  10524. {
  10525. if ((pPhone->dwPermanentPhoneID == dwPermPhoneID) &&
  10526. (pPhone->pServer->hTapSrv == pServer->hTapSrv))
  10527. {
  10528. //
  10529. // if dwDeviceIDServer == (-1), it was removed earlier
  10530. // put it back, otherwise fail the operation
  10531. //
  10532. if (pPhone->dwDeviceIDServer == 0xffffffff)
  10533. {
  10534. pPhone->dwDeviceIDServer = dwDeviceIDServer;
  10535. pPhone->dwDeviceIDLocal = dwDeviceIDLocal;
  10536. }
  10537. else
  10538. {
  10539. lResult = PHONEERR_INUSE;
  10540. }
  10541. goto ExitHere;
  10542. }
  10543. }
  10544. pPhoneLookup = pPhoneLookup->pNext;
  10545. }
  10546. }
  10547. pPhoneLookup = gpPhoneLookup;
  10548. while (pPhoneLookup->pNext)
  10549. {
  10550. pPhoneLookup = pPhoneLookup->pNext;
  10551. }
  10552. if (pPhoneLookup->dwUsedEntries == pPhoneLookup->dwTotalEntries)
  10553. {
  10554. PDRVPHONELOOKUP pNewPhoneLookup;
  10555. if (!(pNewPhoneLookup = DrvAlloc(
  10556. sizeof(DRVPHONELOOKUP) +
  10557. (2 * pPhoneLookup->dwTotalEntries - 1) * sizeof(DRVPHONE)
  10558. )))
  10559. {
  10560. lResult = (bInit ? LINEERR_NOMEM : PHONEERR_NOMEM);
  10561. goto ExitHere;
  10562. }
  10563. pNewPhoneLookup->dwTotalEntries = 2 * pPhoneLookup->dwTotalEntries;
  10564. if (bInit)
  10565. {
  10566. pNewPhoneLookup->dwUsedEntries = pPhoneLookup->dwTotalEntries;
  10567. CopyMemory(
  10568. pNewPhoneLookup->aEntries,
  10569. pPhoneLookup->aEntries,
  10570. pPhoneLookup->dwTotalEntries * sizeof (DRVPHONE)
  10571. );
  10572. DrvFree (pPhoneLookup);
  10573. gpPhoneLookup = pNewPhoneLookup;
  10574. }
  10575. else
  10576. {
  10577. pPhoneLookup->pNext = pNewPhoneLookup;
  10578. }
  10579. pPhoneLookup = pNewPhoneLookup;
  10580. //
  10581. // Fix the hDeviceCallback in PDRVPHONE
  10582. //
  10583. pPhone = pPhoneLookup->aEntries;
  10584. for (iEntry = 0; iEntry < (int) pPhoneLookup->dwUsedEntries; ++iEntry)
  10585. {
  10586. if (pPhone->hDeviceCallback)
  10587. {
  10588. DereferenceObject (
  10589. ghHandleTable,
  10590. pPhone->hDeviceCallback,
  10591. 1
  10592. );
  10593. pPhone->hDeviceCallback = (DWORD) NewObject (
  10594. ghHandleTable,
  10595. pPhone,
  10596. (LPVOID) 1
  10597. );
  10598. }
  10599. }
  10600. }
  10601. pPhone = pPhoneLookup->aEntries + pPhoneLookup->dwUsedEntries;
  10602. pPhone->pServer = pServer;
  10603. pPhone->dwDeviceIDLocal = dwDeviceIDLocal;
  10604. pPhone->dwDeviceIDServer = dwDeviceIDServer;
  10605. pPhone->dwPermanentPhoneID = dwPermPhoneID;
  10606. if (bInit)
  10607. {
  10608. gdwInitialNumPhoneDevices++;
  10609. }
  10610. pPhoneLookup->dwUsedEntries++;
  10611. //
  10612. // Negotiate the API/SPI version
  10613. //
  10614. if (bNegotiate)
  10615. {
  10616. if (dwAPIVersion)
  10617. {
  10618. pPhone->dwXPIVersion = dwAPIVersion;
  10619. CopyMemory (&pPhone->ExtensionID, pExtID, sizeof (*pExtID));
  10620. }
  10621. else
  10622. {
  10623. static REMOTE_ARG_TYPES argTypes[] =
  10624. {
  10625. Dword,
  10626. PhoneID,
  10627. Dword,
  10628. Dword,
  10629. lpDword,
  10630. lpGet_SizeToFollow,
  10631. Size
  10632. };
  10633. ULONG_PTR args[] =
  10634. {
  10635. (ULONG_PTR) pServer->hPhoneApp,
  10636. (ULONG_PTR) dwDeviceIDLocal,
  10637. (ULONG_PTR) TAPI_VERSION1_0,
  10638. (ULONG_PTR) TAPI_VERSION_CURRENT,
  10639. (ULONG_PTR) &pPhone->dwXPIVersion,
  10640. (ULONG_PTR) &pPhone->ExtensionID,
  10641. (ULONG_PTR) sizeof (PHONEEXTENSIONID),
  10642. };
  10643. REMOTE_FUNC_ARGS funcArgs =
  10644. {
  10645. MAKELONG (PHONE_FUNC | SYNC | 7, pNegotiateAPIVersion),
  10646. args,
  10647. argTypes
  10648. };
  10649. TapiLeaveCriticalSection(&gCriticalSection);
  10650. bLeaveCriticalSection = FALSE;
  10651. REMOTEDOFUNC (&funcArgs, "phoneNegotiateAPIVersion");
  10652. }
  10653. }
  10654. ExitHere:
  10655. if (bLeaveCriticalSection)
  10656. {
  10657. TapiLeaveCriticalSection(&gCriticalSection);
  10658. }
  10659. return lResult;
  10660. }
  10661. #if DBG
  10662. LPVOID
  10663. WINAPI
  10664. RSPAlloc(
  10665. DWORD dwSize,
  10666. DWORD dwLine,
  10667. PSTR pszFile
  10668. )
  10669. #else
  10670. LPVOID
  10671. WINAPI
  10672. RSPAlloc(
  10673. DWORD dwSize
  10674. )
  10675. #endif
  10676. {
  10677. LPVOID p;
  10678. #if DBG
  10679. dwSize += sizeof (MYMEMINFO);
  10680. #endif
  10681. p = HeapAlloc (ghRSPHeap, HEAP_ZERO_MEMORY, dwSize);
  10682. #if DBG
  10683. if (p)
  10684. {
  10685. ((PMYMEMINFO) p)->dwLine = dwLine;
  10686. ((PMYMEMINFO) p)->pszFile = pszFile;
  10687. p = (LPVOID) (((PMYMEMINFO) p) + 1);
  10688. }
  10689. #endif
  10690. return p;
  10691. }
  10692. void
  10693. DrvFree(
  10694. LPVOID p
  10695. )
  10696. {
  10697. if (!p)
  10698. {
  10699. return;
  10700. }
  10701. #if DBG
  10702. //
  10703. // Fill the buffer (but not the MYMEMINFO header) with 0xa9's
  10704. // to facilitate debugging
  10705. //
  10706. {
  10707. LPVOID p2 = p;
  10708. p = (LPVOID) (((PMYMEMINFO) p) - 1);
  10709. FillMemory(
  10710. p2,
  10711. HeapSize (ghRSPHeap, 0, p) - sizeof (MYMEMINFO),
  10712. 0xa9
  10713. );
  10714. }
  10715. #endif
  10716. HeapFree (ghRSPHeap, 0, p);
  10717. }
  10718. void
  10719. __RPC_FAR *
  10720. __RPC_API
  10721. midl_user_allocate(
  10722. size_t len
  10723. )
  10724. {
  10725. return (DrvAlloc (len));
  10726. }
  10727. void
  10728. __RPC_API
  10729. midl_user_free(
  10730. void __RPC_FAR * ptr
  10731. )
  10732. {
  10733. DrvFree (ptr);
  10734. }
  10735. LONG
  10736. RemoteSPAttach(
  10737. PCONTEXT_HANDLE_TYPE2 *pphContext
  10738. )
  10739. {
  10740. //
  10741. // This func is called by TapiSrv.exe on a remote machine as a
  10742. // result of the call to ClientAttach in TSPI_providerEnumDevices.
  10743. // The gpServer variable contains a pointer to the DRVSERVER
  10744. // structure we are currently initializing for this tapi server,
  10745. // so we'll use this as the context value.
  10746. //
  10747. LOG((TL_INFO, "RemoteSPAttach: enter"));
  10748. // DBGOUT((9, " hLineApp= 0x%08lx", gpServer));
  10749. *pphContext = (PCONTEXT_HANDLE_TYPE) gpCurrInitServer;
  10750. gpCurrInitServer->bConnectionOriented = TRUE;
  10751. return 0;
  10752. }
  10753. void
  10754. RemoteSPEventProc(
  10755. PCONTEXT_HANDLE_TYPE2 phContext,
  10756. unsigned char *pBuffer,
  10757. long lSize
  10758. )
  10759. {
  10760. //
  10761. // This func is called by tapisrv on a remote machine. We want to do
  10762. // things as quickly as possible here and return so we don't block the
  10763. // calling server thread.
  10764. //
  10765. // This func might also be called by the EventHandlerThread, in the
  10766. // case where we're using a connectionless event notification scheme
  10767. // and we pull events over from the server. In this case, phContext
  10768. // will == 0xfeedface, and prior to returning we want to set
  10769. // the char pointed at by pBuffer to 1 on success, or 0 otherwise.
  10770. //
  10771. DWORD dwMsgSize, dwRemainingSize = (DWORD) lSize,
  10772. dwMoveSize = (DWORD) lSize,
  10773. dwMoveSizeWrapped = 0;
  10774. unsigned char *pMsg = pBuffer;
  10775. //
  10776. // Make sure the buffer is DWORD aligned, big enough for at least 1 msg,
  10777. // and that the lSize is not overly large (overflow)
  10778. //
  10779. if ((lSize < 0) ||
  10780. (lSize & 0x3) ||
  10781. (lSize < sizeof (ASYNCEVENTMSG)) ||
  10782. ((pBuffer + lSize) < pBuffer))
  10783. {
  10784. LOG((TL_ERROR, "RemoteSPEventProc: ERROR! bad lSize=x%x", lSize));
  10785. if (phContext == (PCONTEXT_HANDLE_TYPE2) IntToPtr(0xfeedface))
  10786. {
  10787. *pBuffer = 0;
  10788. }
  10789. return;
  10790. }
  10791. //
  10792. // Validate the pDrvServer pointer in the first msg
  10793. //
  10794. if (!ReferenceObject(
  10795. ghHandleTable,
  10796. ((PASYNCEVENTMSG) pMsg)->InitContext,
  10797. gdwDrvServerKey
  10798. ))
  10799. {
  10800. LOG((TL_ERROR,
  10801. "RemoteSPEventProc: bad InitContext=x%x in msg",
  10802. ((PASYNCEVENTMSG) pMsg)->InitContext
  10803. ));
  10804. if (phContext == (PCONTEXT_HANDLE_TYPE2) IntToPtr(0xfeedface))
  10805. {
  10806. *pBuffer = 0;
  10807. }
  10808. return;
  10809. }
  10810. DereferenceObject (ghHandleTable, ((PASYNCEVENTMSG) pMsg)->InitContext, 1);
  10811. //
  10812. // Make sure every msg in the buffer has a valid dwTotalSize
  10813. //
  10814. do
  10815. {
  10816. dwMsgSize = (DWORD) ((PASYNCEVENTMSG) pMsg)->TotalSize;
  10817. if ((dwMsgSize & 0x3) ||
  10818. (dwMsgSize < sizeof (ASYNCEVENTMSG)) ||
  10819. (dwMsgSize > dwRemainingSize))
  10820. {
  10821. LOG((TL_ERROR, "RemoteSPEventProc: ERROR! bad msgSize=x%x",dwMsgSize));
  10822. if (phContext == (PCONTEXT_HANDLE_TYPE2) IntToPtr(0xfeedface))
  10823. {
  10824. *pBuffer = 0;
  10825. }
  10826. return;
  10827. }
  10828. dwRemainingSize -= dwMsgSize;
  10829. pMsg += dwMsgSize;
  10830. } while (dwRemainingSize >= sizeof(ASYNCEVENTMSG));
  10831. if (0 != dwRemainingSize)
  10832. {
  10833. LOG((TL_ERROR, "RemoteSPEventProc: ERROR! bad last msgSize=x%x",dwRemainingSize));
  10834. if (phContext == (PCONTEXT_HANDLE_TYPE2) IntToPtr(0xfeedface))
  10835. {
  10836. *pBuffer = 0;
  10837. }
  10838. return;
  10839. }
  10840. //
  10841. // Enter the critical section to sync access to gEventHandlerThreadParams
  10842. //
  10843. EnterCriticalSection (&gEventBufferCriticalSection);
  10844. {
  10845. PASYNCEVENTMSG pMsg = (PASYNCEVENTMSG) pBuffer;
  10846. LOG((TL_INFO, "RemoteSPEventProc: x%lx", pMsg));
  10847. if (pMsg->Msg == LINE_REPLY)
  10848. {
  10849. LOG((TL_INFO,
  10850. "Got a LINE_REPLY: p1=%lx, p2=%lx",
  10851. pMsg->Param1,
  10852. pMsg->Param2
  10853. ));
  10854. }
  10855. }
  10856. //
  10857. // Check to see if there's enough room for this msg in the event buffer.
  10858. // If not, then alloc a new event buffer, copy contents of existing buffer
  10859. // to new buffer (careful to preserve ordering of valid data), free the
  10860. // existing buffer, and reset the pointers.
  10861. //
  10862. if ((gEventHandlerThreadParams.dwEventBufferUsedSize + lSize) >
  10863. gEventHandlerThreadParams.dwEventBufferTotalSize)
  10864. {
  10865. DWORD dwMoveSize2, dwMoveSizeWrapped2, dwNewEventBufferTotalSize;
  10866. LPBYTE pNewEventBuffer;
  10867. LOG((TL_INFO, "EventHandlerThread: we're gonna need a bigger boat..."));
  10868. //
  10869. // Make sure we're not exceeding our max allowedable buffer size, &
  10870. // alloc a few more bytes than actually needed in the hope that we
  10871. // won't have to do this again soon (we don't want to go overboard
  10872. // & alloc a whole bunch since we don't currently free the buffer
  10873. // until provider shutdown)
  10874. //
  10875. dwNewEventBufferTotalSize =
  10876. gEventHandlerThreadParams.dwEventBufferTotalSize + lSize;
  10877. if (dwNewEventBufferTotalSize > gdwMaxEventBufferSize)
  10878. {
  10879. LOG((TL_ERROR,
  10880. "RemoveSPEventProc: event buf max'd, discarding events"
  10881. ));
  10882. LeaveCriticalSection (&gEventBufferCriticalSection);
  10883. return;
  10884. }
  10885. else if (dwNewEventBufferTotalSize + 512 <= gdwMaxEventBufferSize)
  10886. {
  10887. dwNewEventBufferTotalSize += 512;
  10888. }
  10889. if (!(pNewEventBuffer = DrvAlloc (dwNewEventBufferTotalSize)))
  10890. {
  10891. LeaveCriticalSection (&gEventBufferCriticalSection);
  10892. return;
  10893. }
  10894. if (gEventHandlerThreadParams.dwEventBufferUsedSize != 0)
  10895. {
  10896. if (gEventHandlerThreadParams.pDataIn >
  10897. gEventHandlerThreadParams.pDataOut)
  10898. {
  10899. dwMoveSize2 = (DWORD) (gEventHandlerThreadParams.pDataIn -
  10900. gEventHandlerThreadParams.pDataOut);
  10901. dwMoveSizeWrapped2 = 0;
  10902. }
  10903. else
  10904. {
  10905. dwMoveSize2 = (DWORD) ((gEventHandlerThreadParams.pEventBuffer
  10906. + gEventHandlerThreadParams.dwEventBufferTotalSize)
  10907. - gEventHandlerThreadParams.pDataOut);
  10908. dwMoveSizeWrapped2 = (DWORD) (gEventHandlerThreadParams.pDataIn
  10909. - gEventHandlerThreadParams.pEventBuffer);
  10910. }
  10911. CopyMemory(
  10912. pNewEventBuffer,
  10913. gEventHandlerThreadParams.pDataOut,
  10914. dwMoveSize2
  10915. );
  10916. if (dwMoveSizeWrapped2)
  10917. {
  10918. CopyMemory(
  10919. pNewEventBuffer + dwMoveSize2,
  10920. gEventHandlerThreadParams.pEventBuffer,
  10921. dwMoveSizeWrapped2
  10922. );
  10923. }
  10924. gEventHandlerThreadParams.pDataIn = pNewEventBuffer + dwMoveSize2 +
  10925. dwMoveSizeWrapped2;
  10926. }
  10927. else
  10928. {
  10929. gEventHandlerThreadParams.pDataIn = pNewEventBuffer;
  10930. }
  10931. DrvFree (gEventHandlerThreadParams.pEventBuffer);
  10932. gEventHandlerThreadParams.pDataOut =
  10933. gEventHandlerThreadParams.pEventBuffer = pNewEventBuffer;
  10934. gEventHandlerThreadParams.dwEventBufferTotalSize =
  10935. dwNewEventBufferTotalSize;
  10936. }
  10937. //
  10938. // Write the msg data to the buffer
  10939. //
  10940. if (gEventHandlerThreadParams.pDataIn >=
  10941. gEventHandlerThreadParams.pDataOut)
  10942. {
  10943. DWORD dwFreeSize;
  10944. dwFreeSize = gEventHandlerThreadParams.dwEventBufferTotalSize -
  10945. (DWORD) (gEventHandlerThreadParams.pDataIn -
  10946. gEventHandlerThreadParams.pEventBuffer);
  10947. if (dwMoveSize > dwFreeSize)
  10948. {
  10949. dwMoveSizeWrapped = dwMoveSize - dwFreeSize;
  10950. dwMoveSize = dwFreeSize;
  10951. }
  10952. }
  10953. CopyMemory (gEventHandlerThreadParams.pDataIn, pBuffer, dwMoveSize);
  10954. if (dwMoveSizeWrapped != 0)
  10955. {
  10956. CopyMemory(
  10957. gEventHandlerThreadParams.pEventBuffer,
  10958. pBuffer + dwMoveSize,
  10959. dwMoveSizeWrapped
  10960. );
  10961. gEventHandlerThreadParams.pDataIn =
  10962. gEventHandlerThreadParams.pEventBuffer + dwMoveSizeWrapped;
  10963. }
  10964. else
  10965. {
  10966. gEventHandlerThreadParams.pDataIn += dwMoveSize;
  10967. if (gEventHandlerThreadParams.pDataIn >=
  10968. (gEventHandlerThreadParams.pEventBuffer +
  10969. gEventHandlerThreadParams.dwEventBufferTotalSize))
  10970. {
  10971. gEventHandlerThreadParams.pDataIn =
  10972. gEventHandlerThreadParams.pEventBuffer;
  10973. }
  10974. }
  10975. gEventHandlerThreadParams.dwEventBufferUsedSize += (DWORD) lSize;
  10976. //
  10977. // Tell the EventHandlerThread there's another event to handle by
  10978. // signaling the event (if we're getting called by that thread
  10979. // [phContext == 0xfeedface] then set *pBuffer = 1 to indicate success)
  10980. //
  10981. if (phContext != (PCONTEXT_HANDLE_TYPE2) IntToPtr(0xfeedface))
  10982. {
  10983. SetEvent (gEventHandlerThreadParams.hEvent);
  10984. }
  10985. else
  10986. {
  10987. *pBuffer = 1;
  10988. }
  10989. //
  10990. // We're done...
  10991. //
  10992. LeaveCriticalSection (&gEventBufferCriticalSection);
  10993. LOG((TL_INFO, "RemoteSPEventProc: bytesWritten=x%x", lSize));
  10994. }
  10995. void
  10996. __RPC_USER
  10997. PCONTEXT_HANDLE_TYPE2_rundown(
  10998. PCONTEXT_HANDLE_TYPE2 phContext
  10999. )
  11000. {
  11001. //
  11002. // This happens (at least) when the server trys to call to REMOTESP, but
  11003. // times out and cancels the RPC request. When that happens, the RPC
  11004. // session will be broken.
  11005. //
  11006. PDRVSERVER pServer = (PDRVSERVER) phContext;
  11007. LOG((TL_INFO, "Rundown: phContext=x%x", phContext));
  11008. try
  11009. {
  11010. if (pServer->dwKey != pServer->pInitContext->dwDrvServerKey)
  11011. {
  11012. LOG((TL_ERROR, "Rundown: bad phContext=x%x", phContext));
  11013. return;
  11014. }
  11015. }
  11016. except (EXCEPTION_EXECUTE_HANDLER)
  11017. {
  11018. LOG((TL_ERROR, "Rundown: bad phContext=x%x", phContext));
  11019. return;
  11020. }
  11021. if (!pServer->pInitContext->bShutdown)
  11022. {
  11023. OnServerDisconnected(pServer);
  11024. }
  11025. InterlockedDecrement (&pServer->pInitContext->dwNumRundownsExpected);
  11026. }
  11027. void
  11028. RemoteSPDetach(
  11029. PCONTEXT_HANDLE_TYPE2 *pphContext
  11030. )
  11031. {
  11032. PCONTEXT_HANDLE_TYPE2 phContext;
  11033. LOG((TL_INFO, "RemoteSPDetach: phContext=x%x", *pphContext));
  11034. try
  11035. {
  11036. phContext = *pphContext;
  11037. *pphContext = (PCONTEXT_HANDLE_TYPE) NULL;
  11038. ((PDRVSERVER)phContext)->pInitContext->bShutdown = TRUE;
  11039. }
  11040. myexcept
  11041. {
  11042. phContext = NULL;
  11043. }
  11044. if (phContext)
  11045. {
  11046. PCONTEXT_HANDLE_TYPE2_rundown (phContext);
  11047. }
  11048. LOG((TL_INFO, "RemoteSPDetach: exit"));
  11049. }
  11050. LONG
  11051. AddCallToList(
  11052. PDRVLINE pLine,
  11053. PDRVCALL pCall
  11054. )
  11055. {
  11056. //
  11057. // Initialize some common fields in the call
  11058. //
  11059. pCall->dwKey = DRVCALL_KEY;
  11060. pCall->pServer = pLine->pServer;
  11061. pCall->pLine = pLine;
  11062. pCall->pCachedCallInfo = NULL;
  11063. pCall->dwDirtyStructs =
  11064. STRUCTCHANGE_LINECALLSTATUS | STRUCTCHANGE_LINECALLINFO;
  11065. //
  11066. // Safely add the call to the line's list
  11067. //
  11068. EnterCriticalSection (&gCallListCriticalSection);
  11069. if ((pCall->pNext = (PDRVCALL) pLine->pCalls))
  11070. {
  11071. pCall->pNext->pPrev = pCall;
  11072. }
  11073. pLine->pCalls = pCall;
  11074. LeaveCriticalSection (&gCallListCriticalSection);
  11075. return 0;
  11076. }
  11077. LONG
  11078. RemoveCallFromList(
  11079. PDRVCALL pCall
  11080. )
  11081. {
  11082. //
  11083. // Safely remove the call from the line's list
  11084. //
  11085. EnterCriticalSection (&gCallListCriticalSection);
  11086. if (!IsValidObject (pCall, DRVCALL_KEY))
  11087. {
  11088. LOG((TL_ERROR, "RemoveCallFromList: Call x%lx: Call key does not match.", pCall));
  11089. LeaveCriticalSection(&gCallListCriticalSection);
  11090. return 0;
  11091. }
  11092. //
  11093. // Mark the pCall as toast
  11094. //
  11095. pCall->dwKey = DRVINVAL_KEY;
  11096. if (pCall->pNext)
  11097. {
  11098. pCall->pNext->pPrev = pCall->pPrev;
  11099. }
  11100. if (pCall->pPrev)
  11101. {
  11102. pCall->pPrev->pNext = pCall->pNext;
  11103. }
  11104. else
  11105. {
  11106. pCall->pLine->pCalls = pCall->pNext;
  11107. }
  11108. LeaveCriticalSection (&gCallListCriticalSection);
  11109. // free structures
  11110. if ( pCall->pCachedCallInfo )
  11111. {
  11112. DrvFree( pCall->pCachedCallInfo );
  11113. }
  11114. if ( pCall->pCachedCallStatus )
  11115. {
  11116. DrvFree( pCall->pCachedCallStatus );
  11117. }
  11118. DrvFree(pCall);
  11119. return 0;
  11120. }
  11121. void
  11122. Shutdown(
  11123. PDRVSERVER pServer
  11124. )
  11125. {
  11126. TapiEnterCriticalSection (&gCriticalSection);
  11127. if ((pServer == NULL) || pServer->bShutdown)
  11128. {
  11129. TapiLeaveCriticalSection (&gCriticalSection);
  11130. goto ExitHere;
  11131. }
  11132. pServer->bShutdown = TRUE;
  11133. TapiLeaveCriticalSection (&gCriticalSection);
  11134. //
  11135. // Do a lineShutdown
  11136. //
  11137. {
  11138. DWORD dwSize;
  11139. TAPI32_MSG msg;
  11140. PLINESHUTDOWN_PARAMS pParams;
  11141. msg.u.Req_Func = lShutdown;
  11142. pParams = (PLINESHUTDOWN_PARAMS) &msg;
  11143. pParams->hLineApp = pServer->hLineApp;
  11144. dwSize = sizeof (TAPI32_MSG);
  11145. {
  11146. DWORD dwRetryCount = 0;
  11147. do
  11148. {
  11149. RpcTryExcept
  11150. {
  11151. ClientRequest(
  11152. pServer->phContext,
  11153. (char *) &msg,
  11154. dwSize,
  11155. &dwSize
  11156. );
  11157. dwRetryCount = gdwRetryCount;
  11158. }
  11159. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  11160. {
  11161. // TODO may want to increase the retry count here since we
  11162. // have to do this, & a million other clients may be
  11163. // trying to do the same thing at the same time
  11164. if (dwRetryCount++ < gdwRetryCount)
  11165. {
  11166. Sleep (gdwRetryTimeout);
  11167. }
  11168. }
  11169. RpcEndExcept
  11170. } while (dwRetryCount < gdwRetryCount);
  11171. }
  11172. }
  11173. //
  11174. // Do a phoneShutdown
  11175. //
  11176. {
  11177. DWORD dwSize;
  11178. TAPI32_MSG msg;
  11179. PPHONESHUTDOWN_PARAMS pParams;
  11180. msg.u.Req_Func = pShutdown;
  11181. pParams = (PPHONESHUTDOWN_PARAMS) &msg;
  11182. pParams->hPhoneApp = pServer->hPhoneApp;
  11183. dwSize = sizeof (TAPI32_MSG);
  11184. {
  11185. DWORD dwRetryCount = 0;
  11186. do
  11187. {
  11188. RpcTryExcept
  11189. {
  11190. ClientRequest(
  11191. pServer->phContext,
  11192. (char *) &msg,
  11193. dwSize,
  11194. &dwSize
  11195. );
  11196. dwRetryCount = gdwRetryCount;
  11197. }
  11198. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  11199. {
  11200. // TODO may want to increase the retry count here since we
  11201. // have to do this, & a million other clients may be
  11202. // trying to do the same thing at the same time
  11203. if (dwRetryCount++ < gdwRetryCount)
  11204. {
  11205. Sleep (gdwRetryTimeout);
  11206. }
  11207. }
  11208. RpcEndExcept
  11209. } while (dwRetryCount < gdwRetryCount);
  11210. }
  11211. }
  11212. RpcTryExcept
  11213. {
  11214. ClientDetach (&pServer->phContext);
  11215. pServer->phContext = NULL;
  11216. }
  11217. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  11218. {
  11219. pServer->phContext = NULL;
  11220. }
  11221. RpcEndExcept
  11222. TapiEnterCriticalSection (&gCriticalSection);
  11223. //
  11224. // Walk the line lookup tables & send a CLOSE msg for each open line
  11225. // associated with the server
  11226. //
  11227. {
  11228. PDRVLINELOOKUP pLookup = gpLineLookup;
  11229. try
  11230. {
  11231. while (pLookup)
  11232. {
  11233. DWORD i;
  11234. PDRVLINE pLine;
  11235. for(
  11236. i = 0, pLine = pLookup->aEntries;
  11237. i < pLookup->dwUsedEntries;
  11238. i++, pLine++
  11239. )
  11240. {
  11241. if (pLine->pServer == pServer)
  11242. {
  11243. if (pLine->htLine)
  11244. {
  11245. PDRVCALL pCall;
  11246. pLine->hLine = 0;
  11247. EnterCriticalSection (&gCallListCriticalSection);
  11248. try
  11249. {
  11250. pCall = pLine->pCalls;
  11251. while (pCall)
  11252. {
  11253. pCall->hCall = 0;
  11254. pCall = pCall->pNext;
  11255. }
  11256. }
  11257. except (EXCEPTION_EXECUTE_HANDLER)
  11258. {
  11259. LOG((TL_ERROR, "Shutdown: Exception x%lx while walking the calls list",
  11260. GetExceptionCode()));
  11261. }
  11262. LeaveCriticalSection (&gCallListCriticalSection);
  11263. try
  11264. {
  11265. (*gpfnLineEventProc)(
  11266. pLine->htLine,
  11267. 0,
  11268. LINE_CLOSE,
  11269. 0,
  11270. 0,
  11271. 0
  11272. );
  11273. }
  11274. except (EXCEPTION_EXECUTE_HANDLER)
  11275. {
  11276. LOG((TL_ERROR, "Shutdown: Exception x%lx while sending the LINE_CLOSE message",
  11277. GetExceptionCode()));
  11278. }
  11279. }
  11280. }
  11281. }
  11282. pLookup = pLookup->pNext;
  11283. }
  11284. }
  11285. except (EXCEPTION_EXECUTE_HANDLER)
  11286. {
  11287. LOG((TL_ERROR, "Shutdown: Exception x%lx while walking the line lookup table",
  11288. GetExceptionCode()));
  11289. }
  11290. }
  11291. //
  11292. // Walk the phone lookup tables & send a CLOSE msg for each open phone
  11293. // associated with the server
  11294. //
  11295. {
  11296. PDRVPHONELOOKUP pLookup = gpPhoneLookup;
  11297. while (pLookup)
  11298. {
  11299. DWORD i;
  11300. PDRVPHONE pPhone;
  11301. for(
  11302. i = 0, pPhone = pLookup->aEntries;
  11303. i < pLookup->dwUsedEntries;
  11304. i++, pPhone++
  11305. )
  11306. {
  11307. if (pPhone->pServer == pServer)
  11308. {
  11309. if (pPhone->htPhone)
  11310. {
  11311. pPhone->hPhone = 0;
  11312. (*gpfnPhoneEventProc)(
  11313. pPhone->htPhone,
  11314. PHONE_CLOSE,
  11315. 0,
  11316. 0,
  11317. 0
  11318. );
  11319. }
  11320. }
  11321. }
  11322. pLookup = pLookup->pNext;
  11323. }
  11324. }
  11325. TapiLeaveCriticalSection (&gCriticalSection);
  11326. ExitHere:
  11327. return;
  11328. }
  11329. /*
  11330. BOOL
  11331. CALLBACK
  11332. ConfigDlgProc(
  11333. HWND hwnd,
  11334. UINT msg,
  11335. WPARAM wParam,
  11336. LPARAM lParam
  11337. )
  11338. {
  11339. static HKEY hTelephonyKey, hProviderNKey;
  11340. DWORD dwDataType, dwDataSize;
  11341. switch (msg)
  11342. {
  11343. case WM_INITDIALOG:
  11344. {
  11345. char buf[32], szProviderN[16], szServerN[16];
  11346. BOOL bReadOnly;
  11347. // DWORD i;
  11348. DWORD dwPermanentProviderID = (DWORD) lParam;
  11349. //
  11350. // First try to open the Telephony key with read/write access.
  11351. // If that fails, disable any controls that could cause a chg
  11352. // in config & try opening again with read only access.
  11353. //
  11354. if (RegOpenKeyEx(
  11355. HKEY_LOCAL_MACHINE,
  11356. gszTelephonyKey,
  11357. 0,
  11358. KEY_ALL_ACCESS,
  11359. &hTelephonyKey
  11360. ) != ERROR_SUCCESS)
  11361. {
  11362. EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
  11363. if (RegOpenKeyEx(
  11364. HKEY_LOCAL_MACHINE,
  11365. gszTelephonyKey,
  11366. 0,
  11367. KEY_READ,
  11368. &hTelephonyKey
  11369. ) != ERROR_SUCCESS)
  11370. {
  11371. EndDialog (hwnd, 0);
  11372. return FALSE;
  11373. }
  11374. bReadOnly = TRUE;
  11375. }
  11376. else
  11377. {
  11378. bReadOnly = FALSE;
  11379. }
  11380. wsprintf (szProviderN, "%s%d", gszProvider, dwPermanentProviderID);
  11381. buf[0] = '\0';
  11382. RegOpenKeyEx(
  11383. hTelephonyKey,
  11384. szProviderN,
  11385. 0,
  11386. (bReadOnly ? KEY_READ : KEY_ALL_ACCESS),
  11387. &hProviderNKey
  11388. );
  11389. // we're just going to handle one server for now
  11390. wsprintf (szServerN, "%s%d", gszServer, 0);
  11391. dwDataSize = sizeof(buf);
  11392. RegQueryValueEx(
  11393. hProviderNKey,
  11394. szServerN,
  11395. 0,
  11396. &dwDataType,
  11397. (LPBYTE) buf,
  11398. &dwDataSize
  11399. );
  11400. buf[dwDataSize] = '\0';
  11401. SetDlgItemText(
  11402. hwnd,
  11403. IDC_SERVERNAME,
  11404. (LPSTR)buf
  11405. );
  11406. SetFocus(
  11407. GetDlgItem(
  11408. hwnd,
  11409. IDC_SERVERNAME
  11410. )
  11411. );
  11412. SendMessage(
  11413. GetDlgItem(
  11414. hwnd,
  11415. IDC_SERVERNAME
  11416. ),
  11417. EM_LIMITTEXT,
  11418. MAX_COMPUTERNAME_LENGTH,
  11419. 0
  11420. );
  11421. break;
  11422. }
  11423. case WM_COMMAND:
  11424. switch (LOWORD(wParam))
  11425. {
  11426. case IDOK:
  11427. {
  11428. char buf[MAX_COMPUTERNAME_LENGTH + 1], szServerN[MAX_COMPUTERNAME_LENGTH + 10];
  11429. DWORD dwSize;
  11430. DWORD dw = 1;
  11431. if (!GetDlgItemText(
  11432. hwnd,
  11433. IDC_SERVERNAME,
  11434. buf,
  11435. MAX_COMPUTERNAME_LENGTH + 1
  11436. ))
  11437. {
  11438. LOG((TL_ERROR, "GetDlgItemText failed"));
  11439. // don't end dialog , cause I think this
  11440. // is the empty string case
  11441. MessageBox(
  11442. hwnd,
  11443. "Must enter a server name",
  11444. "Remote SP Configuration",
  11445. MB_OK
  11446. );
  11447. SetFocus(
  11448. GetDlgItem(
  11449. hwnd,
  11450. IDC_SERVERNAME
  11451. )
  11452. );
  11453. break;
  11454. }
  11455. dwSize = MAX_COMPUTERNAME_LENGTH+1;
  11456. GetComputerName(
  11457. szServerN,
  11458. &dwSize
  11459. );
  11460. if (!(lstrcmpi(
  11461. szServerN,
  11462. buf
  11463. )
  11464. ))
  11465. {
  11466. LOG((TL_ERROR, "Tried to set the server to the current machine name"));
  11467. MessageBox(hwnd,
  11468. "Server name cannot be local machine name",
  11469. "Remote SP Configuration",
  11470. MB_OK);
  11471. SetFocus(
  11472. GetDlgItem(
  11473. hwnd,
  11474. IDC_SERVERNAME
  11475. )
  11476. );
  11477. // don't end dialog
  11478. break;
  11479. }
  11480. wsprintf (szServerN, "%s%d", gszServer, 0);
  11481. // now set the registry key
  11482. RegSetValueEx(
  11483. hProviderNKey,
  11484. szServerN,
  11485. 0,
  11486. REG_SZ,
  11487. buf,
  11488. lstrlen(buf) + 1
  11489. );
  11490. RegSetValueEx(
  11491. hProviderNKey,
  11492. gszNumServers,
  11493. 0,
  11494. REG_DWORD,
  11495. (LPBYTE)&dw,
  11496. sizeof(dw)
  11497. );
  11498. // fall thru to below
  11499. }
  11500. case IDCANCEL:
  11501. RegCloseKey (hProviderNKey);
  11502. RegCloseKey (hTelephonyKey);
  11503. EndDialog (hwnd, 0);
  11504. break;
  11505. } // switch (LOWORD(wParam))
  11506. break;
  11507. } // switch (msg)
  11508. return FALSE;
  11509. }
  11510. */
  11511. PNEGOTIATEAPIVERSIONFORALLDEVICES_PARAMS
  11512. NegotiateAllDevices(
  11513. HLINEAPP hLineApp,
  11514. DWORD dwNumLineDevices,
  11515. DWORD dwNumPhoneDevices,
  11516. PCONTEXT_HANDLE_TYPE phContext
  11517. )
  11518. {
  11519. DWORD dwBufSize, dwUsedSize,
  11520. dwRetryCount = 0;
  11521. PNEGOTIATEAPIVERSIONFORALLDEVICES_PARAMS pParams;
  11522. if (!dwNumLineDevices && !dwNumPhoneDevices)
  11523. {
  11524. return NULL;
  11525. }
  11526. dwBufSize =
  11527. sizeof (TAPI32_MSG) +
  11528. (dwNumLineDevices * sizeof (DWORD)) +
  11529. (dwNumLineDevices * sizeof (LINEEXTENSIONID)) +
  11530. (dwNumPhoneDevices * sizeof (DWORD)) +
  11531. (dwNumPhoneDevices * sizeof (PHONEEXTENSIONID));
  11532. if (!(pParams = DrvAlloc (dwBufSize)))
  11533. {
  11534. return NULL;
  11535. }
  11536. pParams->lResult = xNegotiateAPIVersionForAllDevices;
  11537. pParams->hLineApp = hLineApp;
  11538. pParams->dwNumLineDevices = dwNumLineDevices;
  11539. pParams->dwNumPhoneDevices = dwNumPhoneDevices;
  11540. pParams->dwAPIHighVersion = TAPI_VERSION_CURRENT;
  11541. pParams->dwLineAPIVersionListSize = dwNumLineDevices * sizeof (DWORD);
  11542. pParams->dwLineExtensionIDListSize = dwNumLineDevices *
  11543. sizeof (LINEEXTENSIONID);
  11544. pParams->dwPhoneAPIVersionListSize = dwNumPhoneDevices * sizeof (DWORD);
  11545. pParams->dwPhoneExtensionIDListSize = dwNumPhoneDevices *
  11546. sizeof (PHONEEXTENSIONID);
  11547. dwUsedSize = sizeof (TAPI32_MSG);
  11548. {
  11549. do
  11550. {
  11551. RpcTryExcept
  11552. {
  11553. ClientRequest(
  11554. phContext,
  11555. (char *) pParams,
  11556. dwBufSize,
  11557. &dwUsedSize
  11558. );
  11559. dwRetryCount = gdwRetryCount;
  11560. }
  11561. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  11562. {
  11563. LOG((TL_ERROR,
  11564. "NegotiateAllDevices: exception %d doing negotiation",
  11565. RpcExceptionCode()
  11566. ));
  11567. if (dwRetryCount++ < gdwRetryCount)
  11568. {
  11569. Sleep (gdwRetryTimeout);
  11570. }
  11571. else
  11572. {
  11573. pParams->lResult = LINEERR_OPERATIONFAILED;
  11574. }
  11575. }
  11576. RpcEndExcept
  11577. } while (dwRetryCount < gdwRetryCount);
  11578. }
  11579. if (pParams->lResult != 0)
  11580. {
  11581. LOG((TL_ERROR,
  11582. "NegotiateAllDevices: negotiation failed (x%x)",
  11583. pParams->lResult
  11584. ));
  11585. DrvFree (pParams);
  11586. pParams = NULL;
  11587. }
  11588. return pParams;
  11589. }
  11590. LONG
  11591. FinishEnumDevices(
  11592. PDRVSERVER pServer,
  11593. PCONTEXT_HANDLE_TYPE phContext,
  11594. LPDWORD lpdwNumLines,
  11595. LPDWORD lpdwNumPhones,
  11596. BOOL fStartup,
  11597. BOOL bFromReg
  11598. )
  11599. /*++
  11600. Function: FinishEnumDevices
  11601. Purpose: Initializes remote server and queries for
  11602. # of lines and phones.
  11603. Notes: We must already be connected via ClientAttach
  11604. and we must already be impersonating the client
  11605. Created: 6/26/97 t-mperh
  11606. --*/
  11607. {
  11608. TAPI32_MSG msg[2];
  11609. DWORD dwUsedSize, dwBufSize;
  11610. DWORD dwRetryCount = 0;
  11611. HLINEAPP hLineApp;
  11612. HPHONEAPP hPhoneApp;
  11613. DWORD dwNumLineDevices, dwNumPhoneDevices;
  11614. DWORD dwNumDevices = 0;
  11615. BOOL bFailed = FALSE;
  11616. PNEGOTIATEAPIVERSIONFORALLDEVICES_PARAMS pNegoAPIVerParams;
  11617. if (!(pServer->InitContext))
  11618. {
  11619. if (!(pServer->InitContext = (DWORD) NewObject(
  11620. ghHandleTable,
  11621. pServer,
  11622. NULL
  11623. )))
  11624. {
  11625. dwNumLineDevices = 0;
  11626. dwNumPhoneDevices = 0;
  11627. bFailed = TRUE;
  11628. goto cleanup;
  11629. }
  11630. }
  11631. {
  11632. PLINEINITIALIZE_PARAMS pParams;
  11633. msg[0].u.Req_Func = lInitialize;
  11634. pParams = (PLINEINITIALIZE_PARAMS) msg;
  11635. //
  11636. // NOTE: we pass the pServer in place of the lpfnCallback
  11637. // so the we always know which server is sending us
  11638. // async events
  11639. //
  11640. pParams->InitContext = pServer->InitContext;
  11641. pParams->hInstance =
  11642. pParams->dwFriendlyNameOffset =
  11643. pParams->dwModuleNameOffset = 0;
  11644. pParams->dwAPIVersion = TAPI_VERSION_CURRENT;
  11645. wcscpy ((WCHAR *) (msg + 1), gszMachineName);
  11646. dwBufSize =
  11647. dwUsedSize = sizeof (TAPI32_MSG) +
  11648. (lstrlenW (gszMachineName) + 1) * sizeof (WCHAR);
  11649. {
  11650. DWORD dwRetryCount = 0;
  11651. do
  11652. {
  11653. RpcTryExcept
  11654. {
  11655. ClientRequest(
  11656. phContext,
  11657. (char *) &msg,
  11658. dwBufSize,
  11659. &dwUsedSize
  11660. );
  11661. dwRetryCount = gdwRetryCount;
  11662. }
  11663. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  11664. {
  11665. LOG((TL_ERROR,
  11666. "FinishEnumDevices: exception %d doing lineInit",
  11667. RpcExceptionCode()
  11668. ));
  11669. if (dwRetryCount++ < gdwRetryCount)
  11670. {
  11671. Sleep (gdwRetryTimeout);
  11672. }
  11673. else
  11674. {
  11675. bFailed = TRUE;
  11676. }
  11677. }
  11678. RpcEndExcept
  11679. } while (dwRetryCount < gdwRetryCount);
  11680. }
  11681. hLineApp = pParams->hLineApp;
  11682. if (pParams->lResult == 0)
  11683. {
  11684. dwNumLineDevices = pParams->dwNumDevs;
  11685. }
  11686. else
  11687. {
  11688. LOG((TL_ERROR,
  11689. "FinishEnumDevices: lineInit failed (x%x) on server %s",
  11690. pParams->lResult,
  11691. pServer->szServerName
  11692. ));
  11693. dwNumLineDevices = 0;
  11694. dwNumPhoneDevices = 0;
  11695. bFailed = TRUE;
  11696. goto cleanup;
  11697. }
  11698. }
  11699. {
  11700. PPHONEINITIALIZE_PARAMS pParams;
  11701. msg[0].u.Req_Func = pInitialize;
  11702. pParams = (PPHONEINITIALIZE_PARAMS) msg;
  11703. //
  11704. // NOTE: we pass the pServer in place of the lpfnCallback
  11705. // so the we always know which server is sending us
  11706. // async events
  11707. //
  11708. pParams->InitContext = pServer->InitContext;
  11709. pParams->hInstance =
  11710. pParams->dwFriendlyNameOffset =
  11711. pParams->dwModuleNameOffset = 0;
  11712. pParams->dwAPIVersion = TAPI_VERSION_CURRENT;
  11713. wcscpy ((WCHAR *) (msg + 1), gszMachineName);
  11714. dwBufSize =
  11715. dwUsedSize = sizeof (TAPI32_MSG) +
  11716. (lstrlenW (gszMachineName) + 1) * sizeof (WCHAR);
  11717. {
  11718. DWORD dwRetryCount = 0;
  11719. do
  11720. {
  11721. RpcTryExcept
  11722. {
  11723. ClientRequest(
  11724. phContext,
  11725. (char *) &msg,
  11726. dwBufSize,
  11727. &dwUsedSize
  11728. );
  11729. dwRetryCount = gdwRetryCount;
  11730. }
  11731. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  11732. {
  11733. LOG((TL_ERROR,
  11734. "FinishEnumDevices: exception %d doing phoneInit",
  11735. RpcExceptionCode()
  11736. ));
  11737. if (dwRetryCount++ < gdwRetryCount)
  11738. {
  11739. Sleep (gdwRetryTimeout);
  11740. }
  11741. else
  11742. {
  11743. bFailed = TRUE;
  11744. }
  11745. }
  11746. RpcEndExcept
  11747. } while (dwRetryCount < gdwRetryCount);
  11748. }
  11749. hPhoneApp = pParams->hPhoneApp;
  11750. if (pParams->lResult == 0)
  11751. {
  11752. dwNumPhoneDevices = pParams->dwNumDevs;
  11753. }
  11754. else
  11755. {
  11756. LOG((TL_ERROR,
  11757. "FinishEnumDevices: phoneInit failed (x%x) on server %s",
  11758. pParams->lResult,
  11759. pServer->szServerName
  11760. ));
  11761. dwNumPhoneDevices = 0;
  11762. dwNumLineDevices = 0;
  11763. bFailed = TRUE;
  11764. goto cleanup;
  11765. }
  11766. }
  11767. LOG((TL_INFO,
  11768. "FinishEnumDevices: srv='%s', lines=%d, phones=%d",
  11769. pServer->szServerName,
  11770. dwNumLineDevices,
  11771. dwNumPhoneDevices
  11772. ));
  11773. LogRemoteSPError(pServer->szServerName,
  11774. ERROR_REMOTESP_NONE,
  11775. dwNumLineDevices,
  11776. dwNumPhoneDevices,
  11777. !fStartup);
  11778. if (pServer->dwSpecialHack == 0xa5c369a5)
  11779. {
  11780. pNegoAPIVerParams = NegotiateAllDevices(
  11781. hLineApp,
  11782. dwNumLineDevices,
  11783. dwNumPhoneDevices,
  11784. phContext
  11785. );
  11786. }
  11787. else
  11788. {
  11789. pNegoAPIVerParams = NULL;
  11790. }
  11791. {
  11792. DWORD dwServerID,
  11793. dwLocalID,
  11794. myLineDevIDBase,
  11795. myTempLineID,
  11796. myPhoneDevIDBase,
  11797. myTempPhoneID,
  11798. dwZero = 0,
  11799. *pdwAPIVersion;
  11800. LPLINEEXTENSIONID pExtID;
  11801. LONG lResult;
  11802. pServer->phContext = phContext;
  11803. pServer->hLineApp = hLineApp;
  11804. pServer->hPhoneApp = hPhoneApp;
  11805. //
  11806. // If we are not being called during initialization
  11807. // we need to simulate LINE_CREATE and PHONE_CREATE
  11808. // messages from the server SP.
  11809. //
  11810. // Note we differentiate between static line devices
  11811. // (those avail. at startup) and dynamic line devices
  11812. // (those we are notified of dynamically) based on the
  11813. // fStartup flag.
  11814. //
  11815. // _NOTE ALSO_ that the local device id's we assign to
  11816. // devices at startup are 0-based, rather than based
  11817. // on the dwDeviceIDBase's (which we don't know yet
  11818. // because providerInit hasn't been called). This
  11819. // is desirable because AddLine/Phone might have to
  11820. // negotiate versions, which requires a call to DoFunc,
  11821. // which needss to know how to get pDevices from ID's.
  11822. // We'll reset the .dwDeviceIDLocal fields for static
  11823. // devices later on, in TSPI_providerInit.
  11824. //
  11825. myLineDevIDBase = gdwInitialNumLineDevices;
  11826. myTempLineID = gdwTempLineID;
  11827. myPhoneDevIDBase = gdwInitialNumPhoneDevices;
  11828. myTempPhoneID = gdwTempPhoneID;
  11829. if (pNegoAPIVerParams)
  11830. {
  11831. pdwAPIVersion = (LPDWORD)
  11832. (((LPBYTE) pNegoAPIVerParams) + sizeof (TAPI32_MSG) +
  11833. pNegoAPIVerParams->dwLineAPIVersionListOffset);
  11834. pExtID = (LPLINEEXTENSIONID)
  11835. (((LPBYTE) pNegoAPIVerParams) + sizeof (TAPI32_MSG) +
  11836. pNegoAPIVerParams->dwLineExtensionIDListOffset);
  11837. }
  11838. else
  11839. {
  11840. pdwAPIVersion = &dwZero;
  11841. pExtID = (LPLINEEXTENSIONID) NULL;
  11842. }
  11843. for (dwServerID = 0; dwServerID < dwNumLineDevices; dwServerID++)
  11844. {
  11845. dwLocalID = (fStartup ? myLineDevIDBase++ : myTempLineID);
  11846. lResult = AddLine(
  11847. pServer,
  11848. dwLocalID,
  11849. dwServerID,
  11850. fStartup,
  11851. TRUE,
  11852. *pdwAPIVersion,
  11853. pExtID
  11854. );
  11855. if (lResult == LINEERR_NODEVICE)
  11856. {
  11857. if (fStartup)
  11858. {
  11859. --myLineDevIDBase;
  11860. }
  11861. continue;
  11862. }
  11863. if (lResult != 0)
  11864. {
  11865. break;
  11866. }
  11867. ++dwNumDevices;
  11868. if (pNegoAPIVerParams)
  11869. {
  11870. pdwAPIVersion++;
  11871. pExtID++;
  11872. }
  11873. if (!fStartup)
  11874. {
  11875. --myTempLineID;
  11876. (*gpfnLineEventProc)(
  11877. 0,
  11878. 0,
  11879. LINE_CREATE,
  11880. (ULONG_PTR) ghProvider,
  11881. dwLocalID,
  11882. 0
  11883. );
  11884. }
  11885. }
  11886. gdwTempLineID = myTempLineID;
  11887. if (pNegoAPIVerParams)
  11888. {
  11889. pdwAPIVersion = (LPDWORD)
  11890. (((LPBYTE) pNegoAPIVerParams) + sizeof (TAPI32_MSG) +
  11891. pNegoAPIVerParams->dwPhoneAPIVersionListOffset);
  11892. pExtID = (LPLINEEXTENSIONID)
  11893. (((LPBYTE) pNegoAPIVerParams) + sizeof (TAPI32_MSG) +
  11894. pNegoAPIVerParams->dwPhoneExtensionIDListOffset);
  11895. }
  11896. for (dwServerID = 0; dwServerID < dwNumPhoneDevices; dwServerID++)
  11897. {
  11898. dwLocalID = (fStartup ? myPhoneDevIDBase++ : myTempPhoneID);
  11899. lResult = AddPhone(
  11900. pServer,
  11901. dwLocalID,
  11902. dwServerID,
  11903. fStartup,
  11904. TRUE,
  11905. *pdwAPIVersion,
  11906. (LPPHONEEXTENSIONID) pExtID
  11907. );
  11908. if (lResult == PHONEERR_NODEVICE)
  11909. {
  11910. if (fStartup)
  11911. {
  11912. --myPhoneDevIDBase;
  11913. }
  11914. continue;
  11915. }
  11916. if (lResult != 0)
  11917. {
  11918. break;
  11919. }
  11920. ++dwNumDevices;
  11921. if (pNegoAPIVerParams)
  11922. {
  11923. pdwAPIVersion++;
  11924. pExtID++;
  11925. }
  11926. if (!fStartup)
  11927. {
  11928. myTempPhoneID--;
  11929. (*gpfnPhoneEventProc)(
  11930. 0,
  11931. PHONE_CREATE,
  11932. (ULONG_PTR) ghProvider,
  11933. dwLocalID,
  11934. 0
  11935. );
  11936. }
  11937. }
  11938. gdwTempPhoneID = myTempPhoneID;
  11939. }
  11940. if (pNegoAPIVerParams)
  11941. {
  11942. DrvFree (pNegoAPIVerParams);
  11943. }
  11944. cleanup:
  11945. if (pServer->bConnectionOriented)
  11946. {
  11947. InterlockedIncrement(
  11948. &gpCurrentInitContext->dwNumRundownsExpected
  11949. );
  11950. }
  11951. TapiEnterCriticalSection(&gCriticalSection);
  11952. InsertTailList(
  11953. &gpCurrentInitContext->ServerList,
  11954. &pServer->ServerList
  11955. );
  11956. TapiLeaveCriticalSection(&gCriticalSection);
  11957. if (TRUE == fStartup)
  11958. {
  11959. gdwInitialNumLineDevices =
  11960. *lpdwNumLines = (gpLineLookup ? gpLineLookup->dwUsedEntries : 0);
  11961. gdwInitialNumPhoneDevices =
  11962. *lpdwNumPhones = (gpPhoneLookup ? gpPhoneLookup->dwUsedEntries : 0);
  11963. }
  11964. if (bFailed)
  11965. {
  11966. //
  11967. // Failed in seting up lines for this server, retry later.
  11968. //
  11969. Sleep (4000);
  11970. RpcBindingSetOption (
  11971. pServer->hTapSrv,
  11972. RPC_C_OPT_CALL_TIMEOUT,
  11973. gdwRSPRpcTimeout
  11974. );
  11975. OnServerDisconnected (pServer);
  11976. }
  11977. else
  11978. {
  11979. if (!bFromReg && dwNumDevices == 0)
  11980. {
  11981. //
  11982. // The server is found from DS and does not
  11983. // contain any lines for me, detach from it
  11984. //
  11985. TapiEnterCriticalSection(&gCriticalSection);
  11986. RemoveEntryList (&pServer->ServerList);
  11987. TapiLeaveCriticalSection(&gCriticalSection);
  11988. Shutdown (pServer);
  11989. RpcBindingFree(&pServer->hTapSrv);
  11990. pServer->hTapSrv = NULL;
  11991. DereferenceObject (ghHandleTable, pServer->InitContext, 1);
  11992. }
  11993. else
  11994. {
  11995. RpcBindingSetOption (
  11996. pServer->hTapSrv,
  11997. RPC_C_OPT_CALL_TIMEOUT,
  11998. gdwRSPRpcTimeout
  11999. );
  12000. }
  12001. }
  12002. return 0;
  12003. }
  12004. VOID
  12005. WINAPI
  12006. NetworkPollThread(
  12007. LPVOID pszThingtoPassToServer
  12008. )
  12009. {
  12010. LONG lResult;
  12011. LIST_ENTRY *pEntry;
  12012. PCONTEXT_HANDLE_TYPE phContext = NULL;
  12013. #if MEMPHIS
  12014. LOG((TL_INFO, "NetworkPollThread: enter"));
  12015. #else
  12016. HANDLE hProcess;
  12017. PRSP_THREAD_INFO pTls;
  12018. LOG((TL_INFO, "NetworkPollThread: enter"));
  12019. //
  12020. // This thread has no user context, which would prevent us from rpc'ing
  12021. // back to remote tapisrv if necessary. So, find the user that is logged
  12022. // on and impersonate them in this thread.
  12023. //
  12024. if (!GetCurrentlyLoggedOnUser (&hProcess))
  12025. {
  12026. LOG((TL_ERROR, "NetworkPollThread: GetCurrentlyLoggedOnUser failed"));
  12027. goto cleanup;
  12028. }
  12029. else if (!SetProcessImpersonationToken(hProcess))
  12030. {
  12031. LOG((TL_ERROR, "NetworkPollThread: SetProcessImpersonationToken failed"));
  12032. goto cleanup;
  12033. }
  12034. if ((pTls = GetTls()))
  12035. {
  12036. pTls->bAlreadyImpersonated = TRUE;
  12037. }
  12038. else
  12039. {
  12040. goto cleanup;
  12041. }
  12042. #endif
  12043. //
  12044. // Try to attach to servers once in a while. If we successfully attach
  12045. // to a server then remove it from the Npt list and insert it in the
  12046. // global "current" list. When all the servers have been initialized
  12047. // or TSPI_providerShutdown has signalled us then drop out of the loop
  12048. // and clean up.
  12049. //
  12050. while (WaitForSingleObject (ghNptShutdownEvent, NPT_TIMEOUT)
  12051. == WAIT_TIMEOUT)
  12052. {
  12053. BOOL bListEmpty;
  12054. if (gEventHandlerThreadParams.bExit)
  12055. {
  12056. goto cleanup;
  12057. }
  12058. TapiEnterCriticalSection (&gCriticalSection);
  12059. bListEmpty = IsListEmpty (&gNptListHead);
  12060. pEntry = gNptListHead.Flink;
  12061. TapiLeaveCriticalSection (&gCriticalSection);
  12062. if (bListEmpty)
  12063. {
  12064. continue;
  12065. }
  12066. while (pEntry != &gNptListHead)
  12067. {
  12068. if (gEventHandlerThreadParams.bExit)
  12069. {
  12070. goto cleanup;
  12071. }
  12072. //
  12073. // Set the global which RemoteSPAttach looks at to know
  12074. // who the current server is (could pass this as arg to
  12075. // ClientAttach, but this is easiest for now)
  12076. //
  12077. gpCurrInitServer =
  12078. CONTAINING_RECORD (pEntry, DRVSERVER, ServerList);
  12079. if (!gpCurrInitServer->bSetAuthInfo)
  12080. {
  12081. RPC_STATUS status;
  12082. status = RpcBindingSetAuthInfo(
  12083. gpCurrInitServer->hTapSrv,
  12084. NULL,
  12085. RPC_C_AUTHN_LEVEL_DEFAULT,
  12086. RPC_C_AUTHN_WINNT,
  12087. NULL,
  12088. 0
  12089. );
  12090. if (status == RPC_S_OK)
  12091. {
  12092. gpCurrInitServer->bSetAuthInfo = TRUE;
  12093. }
  12094. }
  12095. RpcTryExcept
  12096. {
  12097. // set RPC binding
  12098. hTapSrv = gpCurrInitServer->hTapSrv;
  12099. gpCurrInitServer->dwSpecialHack = 0;
  12100. lResult = ClientAttach(
  12101. &phContext,
  12102. 0xffffffff,
  12103. &gpCurrInitServer->dwSpecialHack,
  12104. gszMailslotName,
  12105. pszThingtoPassToServer
  12106. );
  12107. if (lResult != 0)
  12108. {
  12109. LogRemoteSPError(gpCurrInitServer->szServerName,
  12110. ERROR_REMOTESP_NP_ATTACH, lResult, 0,
  12111. TRUE);
  12112. }
  12113. else
  12114. {
  12115. LogRemoteSPError(gpCurrInitServer->szServerName,
  12116. ERROR_REMOTESP_NONE, 0, 0,
  12117. TRUE);
  12118. }
  12119. }
  12120. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  12121. {
  12122. LogRemoteSPError (gpCurrInitServer->szServerName,
  12123. ERROR_REMOTESP_NP_EXCEPTION,
  12124. RpcExceptionCode(), 0, TRUE);
  12125. lResult = LINEERR_OPERATIONFAILED;
  12126. }
  12127. RpcEndExcept
  12128. if (lResult == 0)
  12129. {
  12130. LOG((TL_INFO,
  12131. "NetworkPollThread: attached to server %s",
  12132. gpCurrInitServer->szServerName
  12133. ));
  12134. TapiEnterCriticalSection(&gCriticalSection);
  12135. RemoveEntryList (pEntry);
  12136. pEntry->Blink = NULL; //This node now is not in any link list
  12137. pEntry = pEntry->Flink;
  12138. TapiLeaveCriticalSection (&gCriticalSection);
  12139. if (gpCurrInitServer->dwFlags & SERVER_DISCONNECTED)
  12140. {
  12141. OnServerConnected(gpCurrInitServer);
  12142. }
  12143. //
  12144. // Enable all events for remotesp
  12145. //
  12146. gpCurrInitServer->phContext = phContext;
  12147. RSPSetEventFilterMasks (
  12148. gpCurrInitServer,
  12149. TAPIOBJ_NULL,
  12150. (LONG_PTR)NULL,
  12151. (ULONG64)EM_ALL
  12152. );
  12153. FinishEnumDevices(
  12154. gpCurrInitServer,
  12155. phContext,
  12156. NULL,
  12157. NULL,
  12158. FALSE, // after init
  12159. TRUE
  12160. );
  12161. }
  12162. else
  12163. {
  12164. TapiEnterCriticalSection (&gCriticalSection);
  12165. pEntry = pEntry->Flink;
  12166. TapiLeaveCriticalSection (&gCriticalSection);
  12167. }
  12168. }
  12169. }
  12170. cleanup:
  12171. #if MEMPHIS
  12172. #else
  12173. ClearImpersonationToken();
  12174. CloseHandle(hProcess);
  12175. #endif
  12176. CloseHandle (ghNptShutdownEvent);
  12177. TapiEnterCriticalSection (&gCriticalSection);
  12178. while (!IsListEmpty (&gNptListHead))
  12179. {
  12180. PDRVSERVER pServer;
  12181. pEntry = RemoveHeadList (&gNptListHead);
  12182. pServer = CONTAINING_RECORD (pEntry, DRVSERVER, ServerList);
  12183. RpcBindingFree (&pServer->hTapSrv);
  12184. DrvFree (CONTAINING_RECORD (pEntry, DRVSERVER, ServerList));
  12185. }
  12186. TapiLeaveCriticalSection (&gCriticalSection);
  12187. LOG((TL_INFO, "NetworkPollThread: exit"));
  12188. ExitThread (0);
  12189. }
  12190. VOID
  12191. PASCAL
  12192. FreeInitContext(
  12193. PRSP_INIT_CONTEXT pInitContext
  12194. )
  12195. {
  12196. LIST_ENTRY *pEntry;
  12197. while (!IsListEmpty (&pInitContext->ServerList))
  12198. {
  12199. PDRVSERVER pServer;
  12200. pEntry = RemoveHeadList (&pInitContext->ServerList);
  12201. pServer = CONTAINING_RECORD (pEntry, DRVSERVER, ServerList);
  12202. RpcBindingFree(&pServer->hTapSrv);
  12203. DereferenceObject (ghHandleTable, pServer->InitContext, 1);
  12204. }
  12205. DrvFree (pInitContext);
  12206. }
  12207. BOOL
  12208. IsClientSystem(
  12209. VOID
  12210. )
  12211. {
  12212. BOOL bResult = FALSE;
  12213. DWORD dwInfoBufferSize, dwSize;
  12214. HANDLE hAccessToken;
  12215. LPWSTR InfoBuffer;
  12216. PTOKEN_USER ptuUser;
  12217. PSID pLocalSystemSid = NULL;
  12218. PSID pLocalServiceSid = NULL;
  12219. PSID pNetworkServiceSid = NULL;
  12220. SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
  12221. // First, build the SID for LocalSystem;
  12222. if (!AllocateAndInitializeSid (
  12223. &NtAuthority,
  12224. 1,
  12225. SECURITY_LOCAL_SYSTEM_RID,
  12226. 0, 0, 0, 0, 0, 0, 0,
  12227. &pLocalSystemSid) ||
  12228. !AllocateAndInitializeSid (
  12229. &NtAuthority,
  12230. 1,
  12231. SECURITY_LOCAL_SERVICE_RID,
  12232. 0, 0, 0, 0, 0, 0, 0,
  12233. &pLocalServiceSid) ||
  12234. !AllocateAndInitializeSid (
  12235. &NtAuthority,
  12236. 1,
  12237. SECURITY_NETWORK_SERVICE_RID,
  12238. 0, 0, 0, 0, 0, 0, 0,
  12239. &pNetworkServiceSid)
  12240. )
  12241. {
  12242. goto Return;
  12243. }
  12244. // Impersonate the client, and get it's SID
  12245. if (RPC_S_OK != RpcImpersonateClient (0))
  12246. {
  12247. goto Return;
  12248. }
  12249. if (OpenThreadToken(
  12250. GetCurrentThread(),
  12251. TOKEN_READ,
  12252. FALSE,
  12253. &hAccessToken
  12254. ))
  12255. {
  12256. dwSize = 2048;
  12257. alloc_infobuffer:
  12258. dwInfoBufferSize = 0;
  12259. InfoBuffer = (LPWSTR) DrvAlloc (dwSize);
  12260. if (NULL != InfoBuffer)
  12261. {
  12262. ptuUser = (PTOKEN_USER) InfoBuffer;
  12263. if (GetTokenInformation(
  12264. hAccessToken,
  12265. TokenUser,
  12266. InfoBuffer,
  12267. dwSize,
  12268. &dwInfoBufferSize
  12269. ))
  12270. {
  12271. // Now, compare the 2 SIDs
  12272. if (EqualSid (pLocalSystemSid, ptuUser->User.Sid) ||
  12273. EqualSid (pLocalServiceSid, ptuUser->User.Sid) ||
  12274. EqualSid (pNetworkServiceSid, ptuUser->User.Sid))
  12275. {
  12276. bResult = TRUE;
  12277. }
  12278. }
  12279. else
  12280. {
  12281. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  12282. {
  12283. DrvFree (InfoBuffer);
  12284. dwSize *= 2;
  12285. goto alloc_infobuffer;
  12286. }
  12287. LOG((TL_ERROR,
  12288. "IsClientSystem: GetTokenInformation failed, error=%d",
  12289. GetLastError()
  12290. ));
  12291. }
  12292. DrvFree (InfoBuffer);
  12293. CloseHandle (hAccessToken);
  12294. }
  12295. else
  12296. {
  12297. LOG((TL_ERROR,
  12298. "IsClientSystem: DrvAlloc (%d) failed",
  12299. dwSize
  12300. ));
  12301. }
  12302. }
  12303. else
  12304. {
  12305. LOG((TL_ERROR,
  12306. "IsClientSystem: OpenThreadToken failed, error=%d",
  12307. GetLastError()
  12308. ));
  12309. }
  12310. RpcRevertToSelf ();
  12311. Return:
  12312. if (pLocalSystemSid)
  12313. {
  12314. FreeSid (pLocalSystemSid);
  12315. }
  12316. if (pLocalServiceSid)
  12317. {
  12318. FreeSid (pLocalServiceSid);
  12319. }
  12320. if (pNetworkServiceSid)
  12321. {
  12322. FreeSid (pNetworkServiceSid);
  12323. }
  12324. return bResult;
  12325. }
  12326. #define LOWDWORD(ul64) ((DWORD)(ul64 & 0xffffffff))
  12327. #define HIDWORD(ul64) ((DWORD)((ul64 & 0xffffffff00000000) >> 32))
  12328. LONG
  12329. WINAPI
  12330. RSPSetEventFilterMasks (
  12331. PDRVSERVER pServer,
  12332. DWORD dwObjType,
  12333. LONG_PTR lObjectID,
  12334. ULONG64 ulEventMasks
  12335. )
  12336. {
  12337. ULONG_PTR args[] =
  12338. {
  12339. (ULONG_PTR) pServer, // The server to call
  12340. (ULONG_PTR) dwObjType, // type of object handle
  12341. (ULONG_PTR) lObjectID, // object handle
  12342. (ULONG_PTR) FALSE, // fSubMask
  12343. (ULONG_PTR) 0, // dwSubMasks
  12344. (ULONG_PTR) LOWDWORD(ulEventMasks), // ulEventMasks low
  12345. (ULONG_PTR) HIDWORD(ulEventMasks) // ulEventMasks hi
  12346. };
  12347. REMOTE_ARG_TYPES argTypes[] =
  12348. {
  12349. lpServer,
  12350. Dword,
  12351. Dword,
  12352. Dword,
  12353. Dword,
  12354. Dword,
  12355. Dword
  12356. };
  12357. REMOTE_FUNC_ARGS funcArgs =
  12358. {
  12359. MAKELONG (TAPI_FUNC | SYNC | 6, tSetEventMasksOrSubMasks),
  12360. args,
  12361. argTypes
  12362. };
  12363. return (REMOTEDOFUNC (&funcArgs, "RSPSetEventFilter"));
  12364. }