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.

1282 lines
29 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. tapimmc.c
  5. Abstract:
  6. Client-side implementation of TAPI MMC support APIs
  7. Author:
  8. Dan Knudson (DanKn) 10-Dec-1997
  9. Revision History:
  10. Notes:
  11. --*/
  12. #include "windows.h"
  13. #include "stdarg.h"
  14. #include "stdio.h"
  15. #include "tapi.h"
  16. #include "tspi.h"
  17. #include "utils.h"
  18. #include "tapimmc.h"
  19. #include "client.h"
  20. #include "clntprivate.h"
  21. #include "tapsrv.h"
  22. #include "lmcons.h"
  23. #include "resource.h"
  24. #define MMCAPP_KEY ((DWORD) 'CmMt')
  25. typedef struct _MMCAPP
  26. {
  27. DWORD dwKey;
  28. BOOL bLocal;
  29. HLINEAPP hLineApp;
  30. DWORD dwAPIVersion;
  31. HANDLE hReinitializeEvent;
  32. PCONTEXT_HANDLE_TYPE phCtx; // RPC handle context
  33. BOOL bNoServiceControl;
  34. } MMCAPP, *PMMCAPP;
  35. LONG
  36. WINAPI
  37. FreeClientResources(
  38. void
  39. );
  40. PMMCAPP
  41. PASCAL
  42. IsValidMmcApp(
  43. HMMCAPP hMmcApp
  44. )
  45. {
  46. PMMCAPP pMmcApp = NULL;
  47. try
  48. {
  49. if (((PMMCAPP) hMmcApp)->dwKey == MMCAPP_KEY)
  50. {
  51. pMmcApp = (PMMCAPP) hMmcApp;
  52. }
  53. }
  54. except (EXCEPTION_EXECUTE_HANDLER)
  55. {
  56. // do nothing
  57. }
  58. return pMmcApp;
  59. }
  60. LONG
  61. WINAPI
  62. MMCAddProvider(
  63. HMMCAPP hMmcApp,
  64. HWND hwndOwner,
  65. LPCWSTR lpszProviderFilename,
  66. LPDWORD lpdwProviderID
  67. )
  68. {
  69. LONG lResult;
  70. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  71. if (!pMmcApp)
  72. {
  73. lResult = LINEERR_INVALAPPHANDLE;
  74. }
  75. else if (pMmcApp->bLocal)
  76. {
  77. lResult = lineAddProviderW(
  78. lpszProviderFilename,
  79. hwndOwner,
  80. lpdwProviderID
  81. );
  82. }
  83. else
  84. {
  85. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  86. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  87. {
  88. lResult = LINEERR_OPERATIONUNAVAIL;
  89. goto ExitHere;
  90. }
  91. lResult = lineAddProviderW(
  92. lpszProviderFilename,
  93. hwndOwner,
  94. lpdwProviderID
  95. );
  96. if (!SetTlsPCtxHandle(NULL) && !lResult)
  97. {
  98. lResult = LINEERR_OPERATIONUNAVAIL;
  99. goto ExitHere;
  100. }
  101. }
  102. ExitHere:
  103. return lResult;
  104. }
  105. LONG
  106. WINAPI
  107. MMCConfigProvider(
  108. HMMCAPP hMmcApp,
  109. HWND hwndOwner,
  110. DWORD dwProviderID
  111. )
  112. {
  113. LONG lResult;
  114. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  115. if (!pMmcApp)
  116. {
  117. lResult = LINEERR_INVALAPPHANDLE;
  118. }
  119. else if (pMmcApp->bLocal)
  120. {
  121. lResult = lineConfigProvider (hwndOwner, dwProviderID);
  122. }
  123. else
  124. {
  125. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  126. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  127. {
  128. lResult = LINEERR_OPERATIONUNAVAIL;
  129. goto ExitHere;
  130. }
  131. lResult = lineConfigProvider (hwndOwner, dwProviderID);
  132. if (!SetTlsPCtxHandle(NULL) && !lResult)
  133. {
  134. lResult = LINEERR_OPERATIONUNAVAIL;
  135. goto ExitHere;
  136. }
  137. }
  138. ExitHere:
  139. return lResult;
  140. }
  141. LONG
  142. WINAPI
  143. MMCGetAvailableProviders(
  144. HMMCAPP hMmcApp,
  145. LPAVAILABLEPROVIDERLIST lpProviderList
  146. )
  147. {
  148. FUNC_ARGS funcArgs =
  149. {
  150. MAKELONG (LINE_FUNC | SYNC | 2, mGetAvailableProviders),
  151. {
  152. (ULONG_PTR) 0,
  153. (ULONG_PTR) lpProviderList
  154. },
  155. {
  156. hXxxApp,
  157. lpGet_Struct
  158. }
  159. };
  160. LONG lResult;
  161. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  162. if (!pMmcApp)
  163. {
  164. lResult = LINEERR_INVALAPPHANDLE;
  165. }
  166. else if (pMmcApp->bLocal)
  167. {
  168. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  169. lResult = DOFUNC (&funcArgs, "GetAvailableProviders");
  170. }
  171. else
  172. {
  173. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  174. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  175. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  176. {
  177. lResult = LINEERR_OPERATIONUNAVAIL;
  178. goto ExitHere;
  179. }
  180. lResult = DOFUNC (&funcArgs, "GetAvailableProviders");
  181. if (!SetTlsPCtxHandle(NULL) && !lResult)
  182. {
  183. lResult = LINEERR_OPERATIONUNAVAIL;
  184. goto ExitHere;
  185. }
  186. }
  187. ExitHere:
  188. return lResult;
  189. }
  190. LONG
  191. WINAPI
  192. MMCGetLineInfo(
  193. HMMCAPP hMmcApp,
  194. LPDEVICEINFOLIST lpDeviceInfoList
  195. )
  196. {
  197. FUNC_ARGS funcArgs =
  198. {
  199. MAKELONG (LINE_FUNC | SYNC | 2, mGetLineInfo),
  200. {
  201. (ULONG_PTR) 0,
  202. (ULONG_PTR) lpDeviceInfoList
  203. },
  204. {
  205. hXxxApp,
  206. lpGet_Struct
  207. }
  208. };
  209. LONG lResult;
  210. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  211. if (!pMmcApp)
  212. {
  213. lResult = LINEERR_INVALAPPHANDLE;
  214. }
  215. else if (pMmcApp->bLocal)
  216. {
  217. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  218. lResult = DOFUNC (&funcArgs, "GetLineInfo");
  219. }
  220. else
  221. {
  222. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  223. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  224. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  225. {
  226. lResult = LINEERR_OPERATIONUNAVAIL;
  227. goto ExitHere;
  228. }
  229. lResult = DOFUNC (&funcArgs, "GetLineInfo");
  230. if (!SetTlsPCtxHandle(NULL) && !lResult)
  231. {
  232. lResult = LINEERR_OPERATIONUNAVAIL;
  233. goto ExitHere;
  234. }
  235. }
  236. ExitHere:
  237. return lResult;
  238. }
  239. #define MAX_DEFAULT_STATUS 64
  240. extern HINSTANCE g_hInst;
  241. LONG
  242. WINAPI
  243. MMCGetLineStatus(
  244. HMMCAPP hMmcApp,
  245. HWND hwndOwner,
  246. DWORD dwStatusLevel,
  247. DWORD dwProviderID,
  248. DWORD dwPermanentLineID,
  249. LPVARSTRING lpStatusBuffer
  250. )
  251. {
  252. static WCHAR szDefStatus[MAX_DEFAULT_STATUS] = L"";
  253. static int cbCount;
  254. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  255. if (!pMmcApp)
  256. {
  257. return LINEERR_INVALAPPHANDLE;
  258. }
  259. if (!lpStatusBuffer ||
  260. IsBadWritePtr (lpStatusBuffer, sizeof (*lpStatusBuffer)))
  261. {
  262. return LINEERR_INVALPOINTER;
  263. }
  264. if (lpStatusBuffer->dwTotalSize < sizeof (*lpStatusBuffer))
  265. {
  266. return LINEERR_STRUCTURETOOSMALL;
  267. }
  268. if (0 == cbCount ||
  269. 0 == szDefStatus[0])
  270. {
  271. cbCount = LoadString (g_hInst, IDS_DEFAULT_STATUS, szDefStatus, MAX_DEFAULT_STATUS);
  272. cbCount = (cbCount+1)<<1; // + 1 because LoadString does not count the terminating NULL;
  273. // <<1 because we need the size in bytes, not characters, and WCHAR is 2 bytes.
  274. }
  275. lpStatusBuffer->dwNeededSize = sizeof (*lpStatusBuffer) + cbCount;
  276. if (lpStatusBuffer->dwTotalSize >= lpStatusBuffer->dwNeededSize)
  277. {
  278. lpStatusBuffer->dwStringFormat = STRINGFORMAT_UNICODE;
  279. lpStatusBuffer->dwStringSize = cbCount;
  280. lpStatusBuffer->dwStringOffset = sizeof (*lpStatusBuffer);
  281. wcscpy ((WCHAR *) (lpStatusBuffer + 1), szDefStatus);
  282. }
  283. else
  284. {
  285. lpStatusBuffer->dwUsedSize = sizeof (*lpStatusBuffer);
  286. lpStatusBuffer->dwStringFormat =
  287. lpStatusBuffer->dwStringSize =
  288. lpStatusBuffer->dwStringOffset = 0;
  289. }
  290. return 0;
  291. }
  292. LONG
  293. WINAPI
  294. MMCGetPhoneInfo(
  295. HMMCAPP hMmcApp,
  296. LPDEVICEINFOLIST lpDeviceInfoList
  297. )
  298. {
  299. FUNC_ARGS funcArgs =
  300. {
  301. MAKELONG (LINE_FUNC | SYNC | 2, mGetPhoneInfo),
  302. {
  303. (ULONG_PTR) 0,
  304. (ULONG_PTR) lpDeviceInfoList
  305. },
  306. {
  307. hXxxApp,
  308. lpGet_Struct
  309. }
  310. };
  311. LONG lResult;
  312. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  313. if (!pMmcApp)
  314. {
  315. lResult = LINEERR_INVALAPPHANDLE;
  316. }
  317. else if (pMmcApp->bLocal)
  318. {
  319. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  320. lResult = DOFUNC (&funcArgs, "GetPhoneInfo");
  321. }
  322. else
  323. {
  324. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  325. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  326. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  327. {
  328. lResult = LINEERR_OPERATIONUNAVAIL;
  329. goto ExitHere;
  330. }
  331. lResult = DOFUNC (&funcArgs, "GetPhoneInfo");
  332. if (!SetTlsPCtxHandle(NULL) && !lResult)
  333. {
  334. lResult = LINEERR_OPERATIONUNAVAIL;
  335. goto ExitHere;
  336. }
  337. }
  338. ExitHere:
  339. return lResult;
  340. }
  341. LONG
  342. WINAPI
  343. MMCGetPhoneStatus(
  344. HMMCAPP hMmcApp,
  345. HWND hwndOwner,
  346. DWORD dwStatusLevel,
  347. DWORD dwProviderID,
  348. DWORD dwPermanentLineID,
  349. LPVARSTRING lpStatusBuffer
  350. )
  351. {
  352. static WCHAR szDefStatus[MAX_DEFAULT_STATUS] = L"";
  353. static int cbCount;
  354. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  355. if (!pMmcApp)
  356. {
  357. return LINEERR_INVALAPPHANDLE;
  358. }
  359. if (!lpStatusBuffer ||
  360. IsBadWritePtr (lpStatusBuffer, sizeof (*lpStatusBuffer)))
  361. {
  362. return LINEERR_INVALPOINTER;
  363. }
  364. if (lpStatusBuffer->dwTotalSize < sizeof (*lpStatusBuffer))
  365. {
  366. return LINEERR_STRUCTURETOOSMALL;
  367. }
  368. if (0 == cbCount ||
  369. 0 == szDefStatus[0])
  370. {
  371. cbCount = LoadString (g_hInst, IDS_DEFAULT_STATUS, szDefStatus, MAX_DEFAULT_STATUS);
  372. cbCount = (cbCount+1)<<1; // + 1 because LoadString does not count the terminating NULL;
  373. // <<1 because we need the size in bytes, not characters, and WCHAR is 2 bytes.
  374. }
  375. lpStatusBuffer->dwNeededSize = sizeof (*lpStatusBuffer) + cbCount;
  376. if (lpStatusBuffer->dwTotalSize >= lpStatusBuffer->dwNeededSize)
  377. {
  378. lpStatusBuffer->dwStringFormat = STRINGFORMAT_UNICODE;
  379. lpStatusBuffer->dwStringSize = cbCount;
  380. lpStatusBuffer->dwStringOffset = sizeof (*lpStatusBuffer);
  381. wcscpy ((WCHAR *) (lpStatusBuffer + 1), szDefStatus);
  382. }
  383. else
  384. {
  385. lpStatusBuffer->dwUsedSize = sizeof (*lpStatusBuffer);
  386. lpStatusBuffer->dwStringFormat =
  387. lpStatusBuffer->dwStringSize =
  388. lpStatusBuffer->dwStringOffset = 0;
  389. }
  390. return 0;
  391. }
  392. LONG
  393. WINAPI
  394. MMCGetProviderList(
  395. HMMCAPP hMmcApp,
  396. LPLINEPROVIDERLIST lpProviderList
  397. )
  398. {
  399. LONG lResult;
  400. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  401. if (!pMmcApp)
  402. {
  403. lResult = LINEERR_INVALAPPHANDLE;
  404. }
  405. else if (pMmcApp->bLocal)
  406. {
  407. lResult = lineGetProviderListW(
  408. pMmcApp->dwAPIVersion,
  409. lpProviderList
  410. );
  411. }
  412. else
  413. {
  414. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  415. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  416. {
  417. lResult = LINEERR_OPERATIONUNAVAIL;
  418. goto ExitHere;
  419. }
  420. lResult = lineGetProviderListW(
  421. pMmcApp->dwAPIVersion,
  422. lpProviderList
  423. );
  424. if (!SetTlsPCtxHandle(NULL) && !lResult)
  425. {
  426. lResult = LINEERR_OPERATIONUNAVAIL;
  427. goto ExitHere;
  428. }
  429. }
  430. ExitHere:
  431. return lResult;
  432. }
  433. LONG
  434. WINAPI
  435. MMCGetServerConfig(
  436. HMMCAPP hMmcApp,
  437. LPTAPISERVERCONFIG lpConfig
  438. )
  439. {
  440. FUNC_ARGS funcArgs =
  441. {
  442. MAKELONG (LINE_FUNC | SYNC | 2, mGetServerConfig),
  443. {
  444. (ULONG_PTR) 0,
  445. (ULONG_PTR) lpConfig
  446. },
  447. {
  448. hXxxApp,
  449. lpGet_Struct
  450. }
  451. };
  452. LONG lResult;
  453. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  454. if (!pMmcApp)
  455. {
  456. lResult = LINEERR_INVALAPPHANDLE;
  457. }
  458. else if (pMmcApp->bLocal)
  459. {
  460. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  461. lResult = DOFUNC (&funcArgs, "GetServerConfig");
  462. }
  463. else
  464. {
  465. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  466. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  467. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  468. {
  469. lResult = LINEERR_OPERATIONUNAVAIL;
  470. goto ExitHere;
  471. }
  472. lResult = DOFUNC (&funcArgs, "GetServerConfig");
  473. if (!SetTlsPCtxHandle(NULL) && !lResult)
  474. {
  475. lResult = LINEERR_OPERATIONUNAVAIL;
  476. goto ExitHere;
  477. }
  478. }
  479. if (lpConfig && pMmcApp && pMmcApp->bNoServiceControl)
  480. {
  481. lpConfig->dwFlags |= TAPISERVERCONFIGFLAGS_NOSERVICECONTROL;
  482. }
  483. ExitHere:
  484. return lResult;
  485. }
  486. LONG
  487. WINAPI
  488. EnsureTapiService(LPCWSTR lpszComputerName, DWORD * pdwServiceState)
  489. {
  490. SC_HANDLE hSCMgr = NULL;
  491. SC_HANDLE hTapiSrv = NULL;
  492. LONG lResult = 0;
  493. DWORD dwNumSecondsSleptStartPending = 0,
  494. dwNumSecondsSleptStopPending = 0;
  495. SERVICE_STATUS status;
  496. BOOL bBreakOut = FALSE;
  497. if ((hSCMgr = OpenSCManagerW(
  498. lpszComputerName, // Machine name
  499. NULL, // ServicesActive database
  500. SC_MANAGER_CONNECT // desired access
  501. )) == NULL)
  502. {
  503. lResult = GetLastError();
  504. LOG((TL_ERROR, "OpenSCManager failed, err=%d", lResult));
  505. goto ExitHere;
  506. }
  507. if ((hTapiSrv = OpenServiceW(
  508. hSCMgr, // SC mgr handle
  509. L"TAPISRV", // name of service to open
  510. SERVICE_START | // desired access
  511. SERVICE_QUERY_STATUS |
  512. SERVICE_STOP |
  513. SERVICE_CHANGE_CONFIG
  514. )) == NULL)
  515. {
  516. lResult = GetLastError() | 0x80000000;
  517. LOG((TL_ERROR, "OpenService failed, err=%d", GetLastError()));
  518. goto ExitHere;
  519. }
  520. while (1)
  521. {
  522. QueryServiceStatus (hTapiSrv, &status);
  523. switch (status.dwCurrentState)
  524. {
  525. case SERVICE_RUNNING:
  526. LOG((TL_INFO, "Tapisrv running"));
  527. bBreakOut = TRUE;
  528. break;
  529. case SERVICE_START_PENDING:
  530. Sleep (1000);
  531. if (++dwNumSecondsSleptStartPending > 180)
  532. {
  533. // Wait for no longer than 3 minutes
  534. LOG((TL_ERROR, "ERROR: Tapisrv stuck SERVICE_START_PENDING"));
  535. bBreakOut = TRUE;
  536. }
  537. break;
  538. case SERVICE_STOP_PENDING:
  539. Sleep (1000);
  540. if (++dwNumSecondsSleptStopPending > 180)
  541. {
  542. // Wait for no more than 3 minutes
  543. LOG((TL_ERROR, "ERROR: Tapisrv stuck SERVICE_STOP_PENDING"));
  544. bBreakOut = TRUE;
  545. }
  546. break;
  547. case SERVICE_STOPPED:
  548. LOG((TL_INFO, "Starting tapisrv (NT)..."));
  549. if (!StartService(
  550. hTapiSrv, // service handle
  551. 0, // num args
  552. NULL // args
  553. ))
  554. {
  555. lResult = GetLastError();
  556. if (lResult != ERROR_SERVICE_ALREADY_RUNNING)
  557. {
  558. LOG((TL_ERROR,
  559. "StartService(TapiSrv) failed, err=%d",
  560. lResult
  561. ));
  562. bBreakOut = TRUE;
  563. }
  564. else
  565. {
  566. lResult = 0;
  567. }
  568. }
  569. break;
  570. default:
  571. LOG((TL_ERROR, "error, service status=%d",
  572. status.dwCurrentState));
  573. lResult = GetLastError();
  574. bBreakOut = TRUE;
  575. break;
  576. }
  577. if (bBreakOut)
  578. {
  579. break;
  580. }
  581. }
  582. if (pdwServiceState)
  583. {
  584. *pdwServiceState = status.dwCurrentState;
  585. }
  586. ExitHere:
  587. if (hSCMgr)
  588. CloseServiceHandle(hSCMgr);
  589. if (hTapiSrv)
  590. CloseServiceHandle(hTapiSrv);
  591. return lResult;
  592. }
  593. LONG
  594. WINAPI
  595. MMCInitialize(
  596. LPCWSTR lpszComputerName,
  597. LPHMMCAPP lphMmcApp,
  598. LPDWORD lpdwAPIVersion,
  599. HANDLE hReinitializeEvent
  600. )
  601. {
  602. LONG lResult = 0;
  603. LONG lSrvResult = 0;
  604. DWORD dwSize;
  605. WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1] = L"";
  606. PMMCAPP pMmcApp;
  607. if ((lpszComputerName &&
  608. IsBadStringPtrW (lpszComputerName, 0xffffffff)) ||
  609. IsBadWritePtr (lphMmcApp, sizeof (*lphMmcApp)) ||
  610. IsBadWritePtr (lpdwAPIVersion, sizeof (*lpdwAPIVersion)))
  611. {
  612. return LINEERR_INVALPOINTER;
  613. }
  614. if (!(pMmcApp = ClientAlloc (sizeof (*pMmcApp))))
  615. {
  616. return LINEERR_NOMEM;
  617. }
  618. dwSize = sizeof (szComputerName) / sizeof (WCHAR);
  619. GetComputerNameW (szComputerName, &dwSize);
  620. lSrvResult = EnsureTapiService(lpszComputerName, NULL);
  621. if (!lpszComputerName || _wcsicmp (lpszComputerName, szComputerName) == 0)
  622. {
  623. pMmcApp->bLocal = TRUE;
  624. }
  625. else
  626. {
  627. // We need to manage another computer
  628. RPC_STATUS status, status2;
  629. BOOL bRet;
  630. BOOL bException = FALSE;
  631. HANDLE hAsyncEventsEvent = NULL;
  632. LPWSTR pszStringBinding;
  633. WCHAR szUserName[UNLEN + 1];
  634. dwSize = sizeof(szUserName) / sizeof(WCHAR);
  635. bRet = GetUserNameW(szUserName, &dwSize);
  636. if (!bRet)
  637. {
  638. lResult = GetLastError();
  639. LOG((TL_ERROR, "GetUserNameW failed: err=%d", lResult));
  640. goto ExitHere;
  641. }
  642. // Init the RPC connection with the server
  643. status = RpcStringBindingComposeW (
  644. NULL, // ObjUuid
  645. L"ncacn_np", // ProtSeq
  646. (LPWSTR)lpszComputerName, // NetworkAddr
  647. L"\\pipe\\tapsrv", // EndPoint
  648. NULL, // Options
  649. &pszStringBinding); // StringBinding
  650. if (status)
  651. {
  652. LOG((TL_ERROR, "RpcStringBindingCompose failed: err=%d", status));
  653. lResult = LINEERR_OPERATIONUNAVAIL;
  654. goto ExitHere;
  655. }
  656. status = RpcBindingFromStringBindingW(
  657. pszStringBinding, // StringBinding
  658. &hTapSrv); // Binding
  659. status2 = RpcStringFreeW(&pszStringBinding);
  660. if (status || status2)
  661. {
  662. LOG((TL_ERROR, "RpcBindingFromStringBinding failed: err=%d", status));
  663. lResult = LINEERR_OPERATIONUNAVAIL;
  664. goto ExitHere;
  665. }
  666. status = RpcBindingSetAuthInfoW (
  667. hTapSrv, // hBinding
  668. NULL, // ServerPrincName
  669. RPC_C_AUTHN_LEVEL_DEFAULT, // AuthnLevel
  670. RPC_C_AUTHN_WINNT, // AuthService
  671. NULL, // AuthIdentity
  672. 0); // AuthzService
  673. if (status)
  674. {
  675. LOG((TL_ERROR, "RpcBindingSetAuthInfo failed: err=%d", status));
  676. RpcBindingFree(hTapSrv);
  677. lResult = LINEERR_OPERATIONUNAVAIL;
  678. goto ExitHere;
  679. }
  680. RpcTryExcept
  681. {
  682. LOG((TL_TRACE, "MMCInitialize: calling ClientAttach..."));
  683. lResult = ClientAttach(
  684. &(pMmcApp->phCtx),
  685. 0xfffffffd, // Indicate to the server this is from MMC client
  686. // on another machine
  687. (long *)&hAsyncEventsEvent,
  688. szUserName,
  689. szComputerName
  690. );
  691. LOG((TL_TRACE, "MMCInitialize: ClientAttach returned x%x", lResult));
  692. }
  693. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  694. {
  695. LOG((TL_TRACE,
  696. "MMCInitialize: ClientAttach caused except=%d",
  697. RpcExceptionCode()
  698. ));
  699. bException = TRUE;
  700. }
  701. RpcEndExcept
  702. status = RpcBindingFree(&hTapSrv);
  703. if (status || bException)
  704. {
  705. lResult = LINEERR_OPERATIONUNAVAIL;
  706. goto ExitHere;
  707. }
  708. if (lResult)
  709. {
  710. goto ExitHere;
  711. }
  712. pMmcApp->bLocal = FALSE;
  713. }
  714. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  715. if (!(pMmcApp->bLocal) && !SetTlsPCtxHandle(pMmcApp->phCtx))
  716. {
  717. lResult = LINEERR_OPERATIONUNAVAIL;
  718. goto ExitHere;
  719. }
  720. {
  721. DWORD dwNumLines;
  722. LINEINITIALIZEEXPARAMS initExParams;
  723. initExParams.dwTotalSize = sizeof (initExParams);
  724. initExParams.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
  725. lResult = lineInitializeExW(
  726. &pMmcApp->hLineApp,
  727. NULL,
  728. NULL,
  729. NULL,
  730. &dwNumLines,
  731. lpdwAPIVersion,
  732. &initExParams
  733. );
  734. pMmcApp->dwAPIVersion = *lpdwAPIVersion;
  735. }
  736. // Clear the PCONTEXT_TYPE_HANDLE in TLS
  737. if (!(pMmcApp->bLocal) && !SetTlsPCtxHandle(NULL))
  738. {
  739. lResult = LINEERR_OPERATIONUNAVAIL;
  740. }
  741. ExitHere:
  742. if (lResult == 0)
  743. {
  744. pMmcApp->dwKey = MMCAPP_KEY;
  745. *lphMmcApp = (HMMCAPP) pMmcApp;
  746. }
  747. else
  748. {
  749. ClientFree (pMmcApp);
  750. }
  751. if (lSrvResult && (lResult == 0))
  752. {
  753. //
  754. // We have no problem in connecting to the remote computer
  755. // but we can not manipulate its TAPI service, i.e start service
  756. // tell the app about it.
  757. //
  758. pMmcApp->bNoServiceControl = TRUE;
  759. }
  760. return lResult;
  761. }
  762. LONG
  763. WINAPI
  764. MMCRemoveProvider(
  765. HMMCAPP hMmcApp,
  766. HWND hwndOwner,
  767. DWORD dwProviderID
  768. )
  769. {
  770. LONG lResult;
  771. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  772. if (!pMmcApp)
  773. {
  774. lResult = LINEERR_INVALAPPHANDLE;
  775. }
  776. else if (pMmcApp->bLocal)
  777. {
  778. lResult = lineRemoveProvider (dwProviderID, hwndOwner);
  779. }
  780. else
  781. {
  782. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  783. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  784. {
  785. lResult = LINEERR_OPERATIONUNAVAIL;
  786. goto ExitHere;
  787. }
  788. lResult = lineRemoveProvider (dwProviderID, hwndOwner);
  789. if (!SetTlsPCtxHandle(NULL) && !lResult)
  790. {
  791. lResult = LINEERR_OPERATIONUNAVAIL;
  792. goto ExitHere;
  793. }
  794. }
  795. ExitHere:
  796. return lResult;
  797. }
  798. LONG
  799. WINAPI
  800. MMCSetLineInfo(
  801. HMMCAPP hMmcApp,
  802. LPDEVICEINFOLIST lpDeviceInfoList
  803. )
  804. {
  805. FUNC_ARGS funcArgs =
  806. {
  807. MAKELONG (LINE_FUNC | SYNC | 2, mSetLineInfo),
  808. {
  809. (ULONG_PTR) 0,
  810. (ULONG_PTR) lpDeviceInfoList
  811. },
  812. {
  813. hXxxApp,
  814. lpSet_Struct
  815. }
  816. };
  817. LONG lResult;
  818. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  819. if (!pMmcApp)
  820. {
  821. lResult = LINEERR_INVALAPPHANDLE;
  822. }
  823. else if (pMmcApp->bLocal)
  824. {
  825. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  826. lResult = DOFUNC (&funcArgs, "SetLineInfo");
  827. }
  828. else
  829. {
  830. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  831. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  832. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  833. {
  834. lResult = LINEERR_OPERATIONUNAVAIL;
  835. goto ExitHere;
  836. }
  837. lResult = DOFUNC (&funcArgs, "SetLineInfo");
  838. if (!SetTlsPCtxHandle(NULL) && !lResult)
  839. {
  840. lResult = LINEERR_OPERATIONUNAVAIL;
  841. goto ExitHere;
  842. }
  843. }
  844. ExitHere:
  845. return lResult;
  846. }
  847. LONG
  848. WINAPI
  849. MMCSetPhoneInfo(
  850. HMMCAPP hMmcApp,
  851. LPDEVICEINFOLIST lpDeviceInfoList
  852. )
  853. {
  854. FUNC_ARGS funcArgs =
  855. {
  856. MAKELONG (LINE_FUNC | SYNC | 2, mSetPhoneInfo),
  857. {
  858. (ULONG_PTR) 0,
  859. (ULONG_PTR) lpDeviceInfoList
  860. },
  861. {
  862. hXxxApp,
  863. lpSet_Struct
  864. }
  865. };
  866. LONG lResult;
  867. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  868. if (!pMmcApp)
  869. {
  870. lResult = LINEERR_INVALAPPHANDLE;
  871. }
  872. else if (pMmcApp->bLocal)
  873. {
  874. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  875. lResult = DOFUNC (&funcArgs, "SetPhoneInfo");
  876. }
  877. else
  878. {
  879. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  880. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  881. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  882. {
  883. lResult = LINEERR_OPERATIONUNAVAIL;
  884. goto ExitHere;
  885. }
  886. lResult = DOFUNC (&funcArgs, "SetPhoneInfo");
  887. if (!SetTlsPCtxHandle(NULL) && !lResult)
  888. {
  889. lResult = LINEERR_OPERATIONUNAVAIL;
  890. goto ExitHere;
  891. }
  892. }
  893. ExitHere:
  894. return lResult;
  895. }
  896. LONG
  897. WINAPI
  898. MMCSetServerConfig(
  899. HMMCAPP hMmcApp,
  900. LPTAPISERVERCONFIG lpConfig
  901. )
  902. {
  903. FUNC_ARGS funcArgs =
  904. {
  905. MAKELONG (LINE_FUNC | SYNC | 2, mSetServerConfig),
  906. {
  907. (ULONG_PTR) 0,
  908. (ULONG_PTR) lpConfig
  909. },
  910. {
  911. hXxxApp,
  912. lpSet_Struct
  913. }
  914. };
  915. LONG lResult;
  916. DWORD dwFlags;
  917. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  918. if (lpConfig && pMmcApp)
  919. {
  920. dwFlags = lpConfig->dwFlags;
  921. lpConfig->dwFlags &= (~TAPISERVERCONFIGFLAGS_NOSERVICECONTROL);
  922. }
  923. if (!pMmcApp)
  924. {
  925. lResult = LINEERR_INVALAPPHANDLE;
  926. }
  927. else if (pMmcApp->bLocal)
  928. {
  929. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  930. lResult = DOFUNC (&funcArgs, "SetServerConfig");
  931. }
  932. else
  933. {
  934. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  935. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  936. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  937. {
  938. lResult = LINEERR_OPERATIONUNAVAIL;
  939. goto ExitHere;
  940. }
  941. lResult = DOFUNC (&funcArgs, "SetServerConfig");
  942. if (!SetTlsPCtxHandle(NULL) && !lResult)
  943. {
  944. lResult = LINEERR_OPERATIONUNAVAIL;
  945. goto ExitHere;
  946. }
  947. }
  948. if (lpConfig && pMmcApp)
  949. {
  950. lpConfig->dwFlags = dwFlags;
  951. }
  952. ExitHere:
  953. return lResult;
  954. }
  955. LONG
  956. WINAPI
  957. MMCGetDeviceFlags(
  958. HMMCAPP hMmcApp,
  959. BOOL bLine,
  960. DWORD dwProviderID,
  961. DWORD dwPermanentDeviceID,
  962. DWORD * pdwFlags,
  963. DWORD * pdwDeviceID
  964. )
  965. {
  966. FUNC_ARGS funcArgs =
  967. {
  968. MAKELONG (LINE_FUNC | SYNC | 6, mGetDeviceFlags),
  969. {
  970. (ULONG_PTR) 0,
  971. (ULONG_PTR) bLine,
  972. (ULONG_PTR) dwProviderID,
  973. (ULONG_PTR) dwPermanentDeviceID,
  974. (ULONG_PTR) pdwFlags,
  975. (ULONG_PTR) pdwDeviceID,
  976. },
  977. {
  978. hXxxApp,
  979. Dword,
  980. Dword,
  981. Dword,
  982. lpDword,
  983. lpDword
  984. }
  985. };
  986. LONG lResult;
  987. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  988. if (!pMmcApp)
  989. {
  990. lResult = LINEERR_INVALAPPHANDLE;
  991. }
  992. else if (pMmcApp->bLocal)
  993. {
  994. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  995. lResult = DOFUNC (&funcArgs, "SetPhoneInfo");
  996. }
  997. else
  998. {
  999. funcArgs.Args[0] = (ULONG_PTR) pMmcApp->hLineApp;
  1000. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  1001. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  1002. {
  1003. lResult = LINEERR_OPERATIONUNAVAIL;
  1004. goto ExitHere;
  1005. }
  1006. lResult = DOFUNC (&funcArgs, "SetPhoneInfo");
  1007. if (!SetTlsPCtxHandle(NULL) && !lResult)
  1008. {
  1009. lResult = LINEERR_OPERATIONUNAVAIL;
  1010. goto ExitHere;
  1011. }
  1012. }
  1013. ExitHere:
  1014. return lResult;
  1015. }
  1016. LONG
  1017. WINAPI
  1018. MMCShutdown(
  1019. HMMCAPP hMmcApp
  1020. )
  1021. {
  1022. LONG lResult = 0;
  1023. PMMCAPP pMmcApp = IsValidMmcApp (hMmcApp);
  1024. if (!pMmcApp)
  1025. {
  1026. lResult = LINEERR_INVALAPPHANDLE;
  1027. }
  1028. else if (pMmcApp->bLocal)
  1029. {
  1030. pMmcApp->dwKey = 0xfffffffe;
  1031. lResult = lineShutdown (pMmcApp->hLineApp);
  1032. ClientFree (pMmcApp);
  1033. //
  1034. // #196350 - After enabling tapi as a server the MMC does a
  1035. // FreeLibrary on us, thinking that we'll terminate our rpc
  1036. // connection with the tapisrv, so it can shutdown tapisrv
  1037. // and restart it w/ different credentials, etc. However,
  1038. // the MMC is linked with CSCUI.DLL, who in turn links with
  1039. // a RAS DLL, who in turn links with TAPI32.DLL, therefore
  1040. // we never actually get unloaded. Since we don't otherwise
  1041. // deal with the service going down at this point, we want
  1042. // to manually call FreeClientResources() to make it seem
  1043. // like we've never been talking to tapisrv.
  1044. //
  1045. // Not needed anymore, now lineShutdown closes the RPC connection
  1046. // FreeClientResources();
  1047. }
  1048. else if (pMmcApp->phCtx)
  1049. {
  1050. pMmcApp->dwKey = 0xfffffffe;
  1051. // Set the PCONTEXT_TYPE_HANDLE for lineInializeExW to use
  1052. if (!SetTlsPCtxHandle(pMmcApp->phCtx))
  1053. {
  1054. lResult = LINEERR_OPERATIONUNAVAIL;
  1055. goto ExitHere;
  1056. }
  1057. lResult = lineShutdown (pMmcApp->hLineApp);
  1058. if (!SetTlsPCtxHandle(NULL) && !lResult)
  1059. {
  1060. lResult = LINEERR_OPERATIONUNAVAIL;
  1061. }
  1062. RpcTryExcept
  1063. {
  1064. ClientDetach (&(pMmcApp->phCtx));
  1065. }
  1066. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  1067. {
  1068. // do something?
  1069. }
  1070. RpcEndExcept
  1071. pMmcApp->phCtx = NULL;
  1072. ClientFree (pMmcApp);
  1073. }
  1074. ExitHere:
  1075. return lResult;
  1076. }