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.

18232 lines
413 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 1995-1998 Microsoft Corporation
  3. Module Name:
  4. client.c
  5. Abstract:
  6. This module contains the tapi.dll implementation (client-side tapi)
  7. Author:
  8. Dan Knudson (DanKn) 01-Apr-1995
  9. Revision History:
  10. Notes:
  11. 1. Make all funcArg structs STATIC, & just do whatever mov's necessary
  12. for the params (saves mov's for flags, pfnPostProcess, funcName, &
  13. argTypes)
  14. --*/
  15. #include "windows.h"
  16. #include "wownt32.h"
  17. #include "stdarg.h"
  18. #include "stdio.h"
  19. #include "tapi.h"
  20. #include "tspi.h"
  21. #include "utils.h"
  22. #include "client.h"
  23. #include "clntprivate.h"
  24. #include "tapsrv.h"
  25. #include "loc_comn.h"
  26. #include "prsht.h"
  27. #include "shellapi.h"
  28. #include "tapiperf.h"
  29. #include "tlnklist.h"
  30. #include "tapihndl.h"
  31. #include "resource.h"
  32. #include "tchar.h"
  33. #include "shfusion.h"
  34. #include <shlwapi.h>
  35. #include <shlwapip.h> // from private\inc
  36. #include <MMSYSTEM.H>
  37. #include <mmddk.h>
  38. #undef lineBlindTransfer
  39. #undef lineConfigDialog
  40. #undef lineConfigDialogEdit
  41. #undef lineDial
  42. #undef lineForward
  43. #undef lineGatherDigits
  44. #undef lineGenerateDigits
  45. #undef lineGetAddressCaps
  46. #undef lineGetAddressID
  47. #undef lineGetAddressStatus
  48. #undef lineGetCallInfo
  49. #undef lineGetDevCaps
  50. #undef lineGetDevConfig
  51. #undef lineGetIcon
  52. #undef lineGetID
  53. #undef lineGetLineDevStatus
  54. #undef lineGetRequest
  55. #undef lineGetTranslateCaps
  56. #undef lineHandoff
  57. #undef lineMakeCall
  58. #undef lineOpen
  59. #undef linePark
  60. #undef linePickup
  61. #undef linePrepareAddToConference
  62. #undef lineRedirect
  63. #undef lineSetDevConfig
  64. #undef lineSetTollList
  65. #undef lineSetupConference
  66. #undef lineSetupTransfer
  67. #undef lineTranslateAddress
  68. #undef lineUnpark
  69. #undef phoneConfigDialog
  70. #undef phoneGetButtonInfo
  71. #undef phoneGetDevCaps
  72. #undef phoneGetIcon
  73. #undef phoneGetID
  74. #undef phoneGetStatus
  75. #undef phoneSetButtonInfo
  76. #undef tapiGetLocationInfo
  77. #undef tapiRequestMakeCall
  78. #undef tapiRequestMediaCall
  79. #undef lineAddProvider
  80. #undef lineGetAppPriority
  81. #undef lineGetCountry
  82. #undef lineGetProviderList
  83. #undef lineSetAppPriority
  84. #undef lineTranslateDialog
  85. //
  86. //
  87. //
  88. #define HUB_MONITOR_LINE_CONTEXT_BASE 0xc0000000
  89. #define ASNYC_MSG_BUF_SIZE 1024
  90. typedef struct _ASYNC_EVENTS_THREAD_PARAMS
  91. {
  92. BOOL bExitThread;
  93. DWORD dwBufSize;
  94. HANDLE hTapi32;
  95. HANDLE hWow32;
  96. LPBYTE pBuf;
  97. } ASYNC_EVENTS_THREAD_PARAMS, *PASYNC_EVENTS_THREAD_PARAMS;
  98. #if DBG
  99. //
  100. // N.B. This structure MUST be a multiple of 8 bytes in size.
  101. //
  102. typedef struct _MYMEMINFO
  103. {
  104. struct _MYMEMINFO * pNext;
  105. struct _MYMEMINFO * pPrev;
  106. DWORD dwSize;
  107. DWORD dwLine;
  108. PSTR pszFile;
  109. DWORD dwAlign;
  110. // LPTSTR pName;
  111. } MYMEMINFO, *PMYMEMINFO;
  112. PMYMEMINFO gpMemFirst = NULL, gpMemLast = NULL;
  113. CRITICAL_SECTION csMemoryList;
  114. BOOL gbBreakOnLeak = FALSE;
  115. void
  116. DumpMemoryList();
  117. #endif
  118. //
  119. // Global vars
  120. //
  121. BOOL gbHiddenWndClassRegistered = FALSE;
  122. BOOL gbNTVDMClient = FALSE;
  123. DWORD gdwRpcRefCount = 0;
  124. BOOL gbDisableGetTranslateCapsHack = FALSE;
  125. DWORD gdwNumInits = 0;
  126. DWORD gdwTlsIndex;
  127. DWORD gdwTlsIndexRpcCtx;
  128. DWORD gdwNumLineDevices = 0;
  129. DWORD gdwNumPhoneDevices = 0;
  130. DWORD gdwInitialTickCount;
  131. HANDLE ghAsyncEventsEvent = NULL;
  132. HANDLE ghInitMutex;
  133. #if DBG
  134. DWORD gdwDebugLevel = 0;
  135. #endif
  136. TCHAR gszLCRDLL[] = TEXT("LeastCostRoutingDLL");
  137. TCHAR gszRemoteSP[] = TEXT("RemoteSP.TSP");
  138. LONG
  139. (WINAPI
  140. *pfnLineOpenWLCR)(
  141. HLINEAPP hLineApp,
  142. DWORD dwDeviceID,
  143. LPHLINE lphLine,
  144. DWORD dwAPIVersion,
  145. DWORD dwExtVersion,
  146. DWORD_PTR dwCallbackInstance,
  147. DWORD dwPrivileges,
  148. DWORD dwMediaModes,
  149. LPLINECALLPARAMS const lpCallParams
  150. );
  151. LONG
  152. (WINAPI
  153. *pfnLineOpenALCR)(
  154. HLINEAPP hLineApp,
  155. DWORD dwDeviceID,
  156. LPHLINE lphLine,
  157. DWORD dwAPIVersion,
  158. DWORD dwExtVersion,
  159. DWORD_PTR dwCallbackInstance,
  160. DWORD dwPrivileges,
  161. DWORD dwMediaModes,
  162. LPLINECALLPARAMS const lpCallParams
  163. );
  164. LONG
  165. (WINAPI
  166. *pfnLineTranslateAddressWLCR)(
  167. HLINEAPP hLineApp,
  168. DWORD dwDeviceID,
  169. DWORD dwAPIVersion,
  170. LPCWSTR lpszAddressIn,
  171. DWORD dwCard,
  172. DWORD dwTranslateOptions,
  173. LPLINETRANSLATEOUTPUT lpTranslateOutput
  174. );
  175. LONG EnsureOneLocation (HWND hwnd);
  176. extern BOOL gbTranslateSimple;
  177. extern BOOL gbTranslateSilent;
  178. HINSTANCE g_hInst;
  179. PASYNC_EVENTS_THREAD_PARAMS gpAsyncEventsThreadParams = NULL;
  180. #if DBG
  181. const TCHAR gszTapi32DebugLevel[] = TEXT("Tapi32DebugLevel");
  182. #endif
  183. const TCHAR gszTapi32MaxNumRequestRetries[] = TEXT("Tapi32MaxNumRequestRetries");
  184. const TCHAR gszTapi32RequestRetryTimeout[] = TEXT("Tapi32RequestRetryTimeout");
  185. extern TCHAR gszTelephonyKey[];
  186. DWORD gdwMaxNumRequestRetries;
  187. DWORD gdwRequestRetryTimeout;
  188. const TCHAR szTapi32WndClass[] = TEXT("Tapi32WndClass");
  189. // These all get passed to GetProcAddress so they stay as ANSI
  190. const CHAR gszTUISPI_providerConfig[] = "TUISPI_providerConfig";
  191. const CHAR gszTUISPI_providerGenericDialog[] = "TUISPI_providerGenericDialog";
  192. const CHAR gszTUISPI_providerGenericDialogData[] = "TUISPI_providerGenericDialogData";
  193. const CHAR gszTUISPI_providerInstall[] = "TUISPI_providerInstall";
  194. const CHAR gszTUISPI_providerRemove[] = "TUISPI_providerRemove";
  195. const CHAR gszTUISPI_lineConfigDialog[] = "TUISPI_lineConfigDialog";
  196. const CHAR gszTUISPI_lineConfigDialogEdit[] = "TUISPI_lineConfigDialogEdit";
  197. const CHAR gszTUISPI_phoneConfigDialog[] = "TUISPI_phoneConfigDialog";
  198. extern TCHAR gszLocations[];
  199. HANDLE ghHandleTable;
  200. HINSTANCE ghWow32Dll = NULL;
  201. FARPROC gpfnWOWGetVDMPointer = NULL;
  202. static FARPROC gpPostQueuedCompletionStatus = NULL;
  203. PUITHREADDATA gpUIThreadInstances = NULL;
  204. CRITICAL_SECTION gCriticalSection;
  205. CRITICAL_SECTION gUICriticalSection;
  206. PCONTEXT_HANDLE_TYPE gphCx = (PCONTEXT_HANDLE_TYPE) NULL;
  207. LIST_ENTRY gTlsListHead;
  208. CRITICAL_SECTION gTlsCriticalSection;
  209. #if DBG
  210. // All the debug only stuff stays as ANSI (just because it was easier than chagning it).
  211. const char *aszMsgs[] =
  212. {
  213. "LINE_ADDRESSSTATE",
  214. "LINE_CALLINFO",
  215. "LINE_CALLSTATE",
  216. "LINE_CLOSE",
  217. "LINE_DEVSPECIFIC",
  218. "LINE_DEVSPECIFICFEATURE",
  219. "LINE_GATHERDIGITS",
  220. "LINE_GENERATE",
  221. "LINE_LINEDEVSTATE",
  222. "LINE_MONITORDIGITS",
  223. "LINE_MONITORMEDIA",
  224. "LINE_MONITORTONE",
  225. "LINE_REPLY",
  226. "LINE_REQUEST",
  227. "PHONE_BUTTON",
  228. "PHONE_CLOSE",
  229. "PHONE_DEVSPECIFIC",
  230. "PHONE_REPLY",
  231. "PHONE_STATE",
  232. "LINE_CREATE",
  233. "PHONE_CREATE",
  234. "LINE_AGENTSPECIFIC",
  235. "LINE_AGENTSTATUS",
  236. "LINE_APPNEWCALL",
  237. "LINE_PROXYREQUEST",
  238. "LINE_REMOVE",
  239. "PHONE_REMOVE"
  240. };
  241. #endif
  242. LONG gaNoMemErrors[3] =
  243. {
  244. TAPIERR_REQUESTFAILED,
  245. LINEERR_NOMEM,
  246. PHONEERR_NOMEM
  247. };
  248. LONG gaInvalHwndErrors[3] =
  249. {
  250. TAPIERR_INVALWINDOWHANDLE,
  251. LINEERR_INVALPARAM,
  252. PHONEERR_INVALPARAM
  253. };
  254. LONG gaInvalPtrErrors[3] =
  255. {
  256. TAPIERR_INVALPOINTER,
  257. LINEERR_INVALPOINTER,
  258. PHONEERR_INVALPOINTER
  259. };
  260. LONG gaOpFailedErrors[3] =
  261. {
  262. TAPIERR_REQUESTFAILED,
  263. LINEERR_OPERATIONFAILED,
  264. PHONEERR_OPERATIONFAILED
  265. };
  266. LONG gaStructTooSmallErrors[3] =
  267. {
  268. TAPIERR_REQUESTFAILED,
  269. LINEERR_STRUCTURETOOSMALL,
  270. PHONEERR_STRUCTURETOOSMALL
  271. };
  272. LONG gaServiceNotRunningErrors[3] =
  273. {
  274. TAPIERR_REQUESTFAILED,
  275. LINEERR_SERVICE_NOT_RUNNING,
  276. PHONEERR_SERVICE_NOT_RUNNING
  277. };
  278. #define AllInitExOptions2_0 \
  279. (LINEINITIALIZEEXOPTION_USEHIDDENWINDOW | \
  280. LINEINITIALIZEEXOPTION_USEEVENT | \
  281. LINEINITIALIZEEXOPTION_USECOMPLETIONPORT)
  282. //
  283. // Function prototypes
  284. //
  285. void
  286. PASCAL
  287. lineMakeCallPostProcess(
  288. PASYNCEVENTMSG pMsg
  289. );
  290. LONG
  291. WINAPI
  292. AllocClientResources(
  293. DWORD dwErrorClass
  294. );
  295. LONG
  296. WINAPI
  297. ReAllocClientResources(
  298. DWORD dwErrorClass
  299. );
  300. BOOL
  301. WINAPI
  302. _CRT_INIT(
  303. HINSTANCE hDLL,
  304. DWORD dwReason,
  305. LPVOID lpReserved
  306. );
  307. LONG
  308. CreateHiddenWindow(
  309. HWND *lphwnd,
  310. DWORD dwErrorClass
  311. );
  312. void
  313. FreeInitData(
  314. PINIT_DATA pInitData
  315. );
  316. LONG
  317. WINAPI
  318. FreeClientResources(
  319. void
  320. );
  321. LONG
  322. CALLBACK
  323. TUISPIDLLCallback(
  324. DWORD dwObjectID,
  325. DWORD dwObjectType,
  326. LPVOID lpParams,
  327. DWORD dwSize
  328. );
  329. BOOL
  330. CALLBACK
  331. TranslateDlgProc(
  332. HWND hwnd,
  333. UINT msg,
  334. WPARAM wParam,
  335. LPARAM lParam
  336. );
  337. void
  338. UIThread(
  339. LPVOID pParams
  340. );
  341. char *
  342. PASCAL
  343. MapResultCodeToText(
  344. LONG lResult,
  345. char *pszResult
  346. );
  347. void
  348. PASCAL
  349. lineDevSpecificPostProcess(
  350. PASYNCEVENTMSG pMsg
  351. );
  352. BOOL
  353. WaveStringIdToDeviceId(
  354. LPWSTR pwszStringID,
  355. LPCWSTR pwszDeviceType,
  356. LPDWORD pdwDeviceId
  357. );
  358. LONG
  359. PASCAL
  360. xxxShutdown(
  361. HLINEAPP hXXXApp,
  362. BOOL bLineShutdown
  363. );
  364. LONG
  365. PASCAL
  366. xxxGetMessage(
  367. BOOL bLine,
  368. HLINEAPP hLineApp,
  369. LPLINEMESSAGE pMsg,
  370. DWORD dwTimeout
  371. );
  372. void
  373. PASCAL
  374. lineGetAgentActivityListAPostProcess(
  375. PASYNCEVENTMSG pMsg
  376. );
  377. void
  378. PASCAL
  379. lineCompleteCallPostProcess(
  380. PASYNCEVENTMSG pMsg
  381. );
  382. void
  383. PASCAL
  384. lineGatherDigitsPostProcess(
  385. PASYNCEVENTMSG pMsg
  386. );
  387. void
  388. PASCAL
  389. lineGatherDigitsWPostProcess(
  390. PASYNCEVENTMSG pMsg
  391. );
  392. void
  393. PASCAL
  394. lineGetAgentCapsAPostProcess(
  395. PASYNCEVENTMSG pMsg
  396. );
  397. void
  398. PASCAL
  399. lineGetAgentGroupListAPostProcess(
  400. PASYNCEVENTMSG pMsg
  401. );
  402. void
  403. PASCAL
  404. lineGetQueueListAPostProcess(
  405. PASYNCEVENTMSG pMsg
  406. );
  407. void
  408. PASCAL
  409. lineGetAgentStatusAPostProcess(
  410. PASYNCEVENTMSG pMsg
  411. );
  412. void
  413. PASCAL
  414. lineParkAPostProcess(
  415. PASYNCEVENTMSG pMsg
  416. );
  417. void
  418. PASCAL
  419. lineSetupConferencePostProcess(
  420. PASYNCEVENTMSG pMsg
  421. );
  422. void
  423. PASCAL
  424. phoneDevSpecificPostProcess(
  425. PASYNCEVENTMSG pMsg
  426. );
  427. POSTPROCESSPROC gPostProcessingFunctions[] =
  428. {
  429. NULL,
  430. lineGetAgentActivityListAPostProcess,
  431. lineCompleteCallPostProcess,
  432. lineDevSpecificPostProcess,
  433. lineGatherDigitsPostProcess,
  434. lineGatherDigitsWPostProcess,
  435. lineGetAgentCapsAPostProcess,
  436. lineGetAgentGroupListAPostProcess,
  437. lineGetAgentStatusAPostProcess,
  438. lineGetQueueListAPostProcess,
  439. lineMakeCallPostProcess,
  440. lineParkAPostProcess,
  441. lineSetupConferencePostProcess,
  442. phoneDevSpecificPostProcess
  443. };
  444. //
  445. // The code...
  446. //
  447. /////////////////////////////////////
  448. //
  449. // GetFunctionIndex
  450. //
  451. // find the array index of the function.
  452. //
  453. // returns 0 if the function was not found in the array
  454. //
  455. DWORD GetFunctionIndex(POSTPROCESSPROC Function)
  456. {
  457. int i;
  458. const int nArraySize =
  459. sizeof(gPostProcessingFunctions)/sizeof(POSTPROCESSPROC);
  460. for (i = 0; i < nArraySize; i++)
  461. {
  462. if (Function == gPostProcessingFunctions[i])
  463. {
  464. break;
  465. }
  466. }
  467. //
  468. // the function that is passed in had better be in the array. if not -- this should be caught in testing!
  469. //
  470. #if DBG
  471. if (0 == i)
  472. {
  473. DebugBreak ();
  474. }
  475. #endif
  476. if (i == nArraySize)
  477. {
  478. LOG((TL_ERROR,
  479. "GetFunctionIndex: function %p is not found in the array of functions!",
  480. Function));
  481. i = 0;
  482. }
  483. LOG((TL_ERROR,
  484. "GetFunctionIndex: function %p mapped to index %d.", Function, i));
  485. return i;
  486. }
  487. PWSTR
  488. PASCAL
  489. NotSoWideStringToWideString(
  490. LPCSTR lpStr,
  491. DWORD dwLength
  492. )
  493. {
  494. DWORD dwSize;
  495. PWSTR pwStr;
  496. if (IsBadStringPtrA (lpStr, dwLength))
  497. {
  498. return NULL;
  499. }
  500. dwSize = MultiByteToWideChar(
  501. GetACP(),
  502. MB_PRECOMPOSED,
  503. lpStr,
  504. dwLength,
  505. NULL,
  506. 0
  507. );
  508. pwStr = ClientAlloc( dwSize * sizeof(WCHAR) );
  509. if (NULL != pwStr)
  510. {
  511. MultiByteToWideChar(
  512. GetACP(),
  513. MB_PRECOMPOSED,
  514. lpStr,
  515. dwLength,
  516. pwStr,
  517. dwSize
  518. );
  519. }
  520. return pwStr;
  521. }
  522. //
  523. //NOTE: This function requires that lpBase is a pointer to the start of
  524. // a TAPI struct that has dwTotalSize as the first DWORD
  525. //
  526. void
  527. PASCAL
  528. WideStringToNotSoWideString(
  529. LPBYTE lpBase,
  530. LPDWORD lpdwXxxSize
  531. )
  532. {
  533. DWORD dwSize;
  534. DWORD dwNewSize;
  535. DWORD dwOffset;
  536. DWORD dwTotalSize;
  537. DWORD dwUsedSize;
  538. PWSTR pString;
  539. char szStackBuf[64];
  540. PSTR lpszStringA;
  541. if ((dwSize = *lpdwXxxSize) != 0)
  542. {
  543. dwTotalSize = *((LPDWORD) lpBase);
  544. dwUsedSize = *(((LPDWORD) lpBase)+2);
  545. dwOffset = *(lpdwXxxSize + 1);
  546. pString = (PWSTR)(lpBase + dwOffset);
  547. if (TAPIIsBadStringPtrW (pString, dwSize))
  548. {
  549. LOG((TL_ERROR,
  550. "The service provider returned an invalid field " \
  551. "in the structure 0x%p : 0x%p",
  552. lpBase,
  553. lpdwXxxSize
  554. ));
  555. *lpdwXxxSize = 0;
  556. *(lpdwXxxSize+1) = 0;
  557. return;
  558. }
  559. //
  560. // Did we get enough chars?
  561. //
  562. if (dwUsedSize > dwOffset )
  563. {
  564. dwNewSize = WideCharToMultiByte(
  565. GetACP(),
  566. 0,
  567. pString,
  568. ( dwUsedSize >= (dwOffset+dwSize)) ?
  569. (dwSize/sizeof(WCHAR)) :
  570. (dwUsedSize - dwOffset) / sizeof(WCHAR),
  571. NULL,
  572. 0,
  573. NULL,
  574. NULL
  575. );
  576. lpszStringA = (dwNewSize <= sizeof (szStackBuf) ?
  577. (PSTR) szStackBuf : ClientAlloc (dwNewSize) );
  578. if ( NULL == lpszStringA )
  579. {
  580. *lpdwXxxSize = 0;
  581. *(lpdwXxxSize+1) = 0;
  582. return;
  583. }
  584. WideCharToMultiByte(
  585. GetACP(),
  586. 0,
  587. pString,
  588. // dwSize,
  589. ( dwUsedSize >= (dwOffset+dwSize)) ?
  590. (dwSize/sizeof(WCHAR)) :
  591. (dwUsedSize - dwOffset) / sizeof(WCHAR),
  592. lpszStringA,
  593. dwNewSize,
  594. NULL,
  595. NULL
  596. );
  597. //
  598. // Copy the new ANSI string back to where the Unicode string was
  599. // // and write out NULL terminator if possible.
  600. //
  601. CopyMemory ( (LPBYTE) pString,
  602. lpszStringA,
  603. dwNewSize // + (
  604. // ((dwNewSize + dwOffset) < dwUsedSize ) ?
  605. // 1 :
  606. // 0
  607. // )
  608. );
  609. if (lpszStringA != (PSTR) szStackBuf)
  610. {
  611. ClientFree (lpszStringA);
  612. }
  613. //
  614. // Update the number of bytes
  615. //
  616. *lpdwXxxSize = dwNewSize;
  617. }
  618. }
  619. }
  620. VOID
  621. CALLBACK
  622. FreeContextCallback(
  623. LPVOID Context,
  624. LPVOID Context2
  625. )
  626. {
  627. //ClientFree (Context);
  628. }
  629. BOOL
  630. WINAPI
  631. DllMain(
  632. HANDLE hDLL,
  633. DWORD dwReason,
  634. LPVOID lpReserved
  635. )
  636. {
  637. switch (dwReason)
  638. {
  639. case DLL_PROCESS_ATTACH:
  640. {
  641. g_hInst = hDLL;
  642. InitializeListHead (&gTlsListHead);
  643. SHFusionInitializeFromModuleID (hDLL,124);
  644. gdwInitialTickCount = GetTickCount();
  645. ghHandleTable = CreateHandleTable(
  646. GetProcessHeap(),
  647. FreeContextCallback,
  648. 0x80000000,
  649. 0x8fffffff
  650. );
  651. if (NULL == ghHandleTable)
  652. {
  653. return FALSE;
  654. }
  655. //
  656. // Init CRT
  657. //
  658. if (!_CRT_INIT (hDLL, dwReason, lpReserved))
  659. {
  660. return FALSE;
  661. }
  662. {
  663. HKEY hKey;
  664. #if DBG
  665. gdwDebugLevel = 0;
  666. #endif
  667. gdwMaxNumRequestRetries = 40;
  668. gdwRequestRetryTimeout = 250; // milliseconds
  669. if (RegOpenKeyEx(
  670. HKEY_LOCAL_MACHINE,
  671. gszTelephonyKey,
  672. 0,
  673. KEY_READ,
  674. &hKey
  675. ) == ERROR_SUCCESS)
  676. {
  677. DWORD dwDataSize = sizeof(DWORD), dwDataType;
  678. #if DBG
  679. RegQueryValueEx(
  680. hKey,
  681. gszTapi32DebugLevel,
  682. 0,
  683. &dwDataType,
  684. (LPBYTE) &gdwDebugLevel,
  685. &dwDataSize
  686. );
  687. dwDataSize = sizeof(DWORD);
  688. #endif
  689. RegQueryValueEx(
  690. hKey,
  691. gszTapi32MaxNumRequestRetries,
  692. 0,
  693. &dwDataType,
  694. (LPBYTE) &gdwMaxNumRequestRetries,
  695. &dwDataSize
  696. );
  697. RegQueryValueEx(
  698. hKey,
  699. gszTapi32RequestRetryTimeout,
  700. 0,
  701. &dwDataType,
  702. (LPBYTE) &gdwRequestRetryTimeout,
  703. &dwDataSize
  704. );
  705. RegCloseKey (hKey);
  706. }
  707. }
  708. //
  709. // Alloc a Tls index
  710. //
  711. if ((gdwTlsIndex = TlsAlloc()) == 0xffffffff ||
  712. (gdwTlsIndexRpcCtx = TlsAlloc()) == 0xffffffff)
  713. {
  714. return FALSE;
  715. }
  716. //
  717. // Initialize Tls to NULL for this thread
  718. //
  719. TlsSetValue (gdwTlsIndex, NULL);
  720. TlsSetValue (gdwTlsIndexRpcCtx, NULL);
  721. //
  722. //
  723. //
  724. ghInitMutex = CreateMutex (NULL, FALSE, NULL);
  725. InitializeCriticalSection (&gCriticalSection);
  726. InitializeCriticalSection (&gUICriticalSection);
  727. InitializeCriticalSection (&gTlsCriticalSection);
  728. #if DBG
  729. InitializeCriticalSection( &csMemoryList);
  730. #endif
  731. ListNodePoolsInitialize();
  732. break;
  733. }
  734. case DLL_PROCESS_DETACH:
  735. {
  736. PCLIENT_THREAD_INFO pTls;
  737. //
  738. // Clean up any Tls (no need to enter crit sec since process detaching)
  739. //
  740. while (!IsListEmpty (&gTlsListHead))
  741. {
  742. LIST_ENTRY *pEntry = RemoveHeadList (&gTlsListHead);
  743. pTls = CONTAINING_RECORD (pEntry, CLIENT_THREAD_INFO, TlsList);
  744. ClientFree (pTls->pBuf);
  745. ClientFree (pTls);
  746. }
  747. //
  748. // If gpAsyncEventsThreadParams is non-NULL it means the AsyncEventsThread
  749. // is still running (an ill-behaved app is trying to unload us
  750. // without calling shutdown) so go thru the motions of getting
  751. // the thread to terminate (like we do in xxxShutdown)
  752. //
  753. // Otherwise close our handle to the shared event
  754. //
  755. if (gpAsyncEventsThreadParams)
  756. {
  757. gpAsyncEventsThreadParams->bExitThread = TRUE;
  758. SetEvent (ghAsyncEventsEvent);
  759. gpAsyncEventsThreadParams = NULL;
  760. gdwNumInits = 0;
  761. }
  762. else if (gphCx && ghAsyncEventsEvent)
  763. {
  764. CloseHandle (ghAsyncEventsEvent);
  765. ghAsyncEventsEvent = NULL;
  766. }
  767. //
  768. // Free up any other resources we were using
  769. //
  770. if (ghWow32Dll)
  771. {
  772. FreeLibrary (ghWow32Dll);
  773. ghWow32Dll = NULL;
  774. }
  775. TlsFree (gdwTlsIndex);
  776. TlsFree (gdwTlsIndexRpcCtx);
  777. _CRT_INIT (hDLL, dwReason, lpReserved);
  778. CloseHandle (ghInitMutex);
  779. DeleteCriticalSection (&gCriticalSection);
  780. DeleteCriticalSection (&gUICriticalSection);
  781. DeleteCriticalSection (&gTlsCriticalSection);
  782. #if DBG
  783. DumpMemoryList();
  784. DeleteCriticalSection( &csMemoryList);
  785. #endif
  786. ListNodePoolsUninitialize();
  787. DeleteHandleTable (ghHandleTable);
  788. SHFusionUninitialize();
  789. break;
  790. }
  791. case DLL_THREAD_ATTACH:
  792. //
  793. // First must init CRT
  794. //
  795. if (!_CRT_INIT (hDLL, dwReason, lpReserved))
  796. {
  797. return FALSE;
  798. }
  799. //
  800. // Initialize Tls to NULL for this thread
  801. //
  802. TlsSetValue (gdwTlsIndex, NULL);
  803. break;
  804. case DLL_THREAD_DETACH:
  805. {
  806. PCLIENT_THREAD_INFO pTls;
  807. //
  808. // Clean up any Tls
  809. //
  810. if ((pTls = (PCLIENT_THREAD_INFO) TlsGetValue (gdwTlsIndex)))
  811. {
  812. EnterCriticalSection (&gTlsCriticalSection);
  813. RemoveEntryList (&pTls->TlsList);
  814. LeaveCriticalSection (&gTlsCriticalSection);
  815. if (pTls->pBuf)
  816. {
  817. ClientFree (pTls->pBuf);
  818. }
  819. ClientFree (pTls);
  820. }
  821. //
  822. // Finally, alert CRT
  823. //
  824. _CRT_INIT (hDLL, dwReason, lpReserved);
  825. break;
  826. }
  827. } // switch
  828. return TRUE;
  829. }
  830. BOOL
  831. IsLeastCostRoutingEnabled(
  832. void
  833. )
  834. {
  835. static BOOL bInited = FALSE, bEnabled = FALSE;
  836. HKEY hKey;
  837. TCHAR szPath[MAX_PATH];
  838. DWORD dwDataSize, dwDataType;
  839. HANDLE hDll;
  840. if (!bInited)
  841. {
  842. //
  843. // Check the registry to see if there's an LCR DLL registered
  844. //
  845. if (RegOpenKeyEx(
  846. HKEY_LOCAL_MACHINE,
  847. gszTelephonyKey,
  848. 0,
  849. KEY_QUERY_VALUE,
  850. &hKey
  851. ) == ERROR_SUCCESS)
  852. {
  853. dwDataSize = sizeof (szPath);
  854. szPath[0] = 0;
  855. if (RegQueryValueEx(
  856. hKey,
  857. gszLCRDLL,
  858. 0,
  859. &dwDataType,
  860. (LPBYTE) szPath,
  861. &dwDataSize
  862. ) == ERROR_SUCCESS)
  863. {
  864. //
  865. // Try to load the LCR DLL.
  866. //
  867. // Note that we will never explicitly free the DLL,
  868. // since there is no well-defined time at which we'd
  869. // know to free it. (Apps can can lineTranslateAddress
  870. // without having done a lineInitialize(Ex), so that
  871. // could happen at any time between us being loaded
  872. // & unloaded, and doing Load/FreeLibrary from within
  873. // a DLLEntryPoint is not a good idea)
  874. //
  875. if ((hDll = LoadLibrary (szPath)))
  876. {
  877. //
  878. // Get the hook addresses & increment our own ref
  879. // count (via LoadLibrary) so we'll never get
  880. // unloaded (since we never unload the LCR DLL
  881. // it might call back in to us at any time, & if
  882. // an app unloaded us that would be a problem)
  883. //
  884. if (hDll)
  885. {
  886. (FARPROC) pfnLineOpenWLCR = GetProcAddress(
  887. hDll,
  888. "lineOpenW"
  889. );
  890. (FARPROC) pfnLineOpenALCR = GetProcAddress(
  891. hDll,
  892. "lineOpenA"
  893. );
  894. (FARPROC) pfnLineTranslateAddressWLCR = GetProcAddress(
  895. hDll,
  896. "lineTranslateAddressW"
  897. );
  898. if (pfnLineOpenWLCR ||
  899. pfnLineOpenALCR ||
  900. pfnLineTranslateAddressWLCR)
  901. {
  902. LoadLibrary (TEXT("tapi32"));
  903. bEnabled = TRUE;
  904. }
  905. }
  906. }
  907. else
  908. {
  909. LOG((TL_ERROR,
  910. "IsLeastCostRoutingEnabled: LoadLibrary() " \
  911. "failed, err=%d",
  912. GetLastError()
  913. ));
  914. }
  915. }
  916. RegCloseKey (hKey);
  917. }
  918. bInited = TRUE;
  919. }
  920. return bEnabled;
  921. }
  922. void
  923. AsyncEventsThread(
  924. PASYNC_EVENTS_THREAD_PARAMS pAsyncEventsThreadParams
  925. );
  926. void NonAsyncEventThread( void )
  927. {
  928. if ( gpAsyncEventsThreadParams )
  929. AsyncEventsThread( (LPVOID) gpAsyncEventsThreadParams );
  930. }
  931. void
  932. AsyncEventsThread(
  933. PASYNC_EVENTS_THREAD_PARAMS pAsyncEventsThreadParams
  934. )
  935. {
  936. BOOL *pbExitThread = &pAsyncEventsThreadParams->bExitThread,
  937. bRetry;
  938. DWORD dwBufSize = pAsyncEventsThreadParams->dwBufSize;
  939. LPBYTE pBuf = pAsyncEventsThreadParams->pBuf;
  940. PTAPI32_MSG pMsg = (PTAPI32_MSG) pBuf;
  941. LOG((TL_TRACE, "AsyncEventsThread: enter"));
  942. //
  943. // Just loop reading async events/completions from server &
  944. // handling them
  945. //
  946. while (1)
  947. {
  948. DWORD dwUsedSize, dwNeededSize;
  949. ASYNC_EVENT_PARAMS AsyncEventParams;
  950. PASYNCEVENTMSG pAsyncEventMsg;
  951. //
  952. // Check to see if xxxShutdown or FreeClientResources
  953. // is signaling us to exit (we need to check both before
  954. // & after the wait to dela with a event setting/resetting
  955. // race condition between FreeClientResources & Tapisrv)
  956. //
  957. EnterCriticalSection (&gCriticalSection);
  958. if (*pbExitThread)
  959. {
  960. LeaveCriticalSection (&gCriticalSection);
  961. break;
  962. }
  963. //
  964. // Block until tapisrv signals us that it has some event data for us
  965. //
  966. LeaveCriticalSection (&gCriticalSection);
  967. {
  968. WaitForSingleObject (ghAsyncEventsEvent, INFINITE);
  969. }
  970. //
  971. // Check to see if xxxShutdown or FreeClientResources
  972. // is signaling us to exit
  973. //
  974. if (*pbExitThread)
  975. {
  976. break;
  977. }
  978. //
  979. // Retrieve the data from tapisrv
  980. //
  981. AsyncEventsThread_clientRequest:
  982. do
  983. {
  984. pMsg->u.Req_Func = xGetAsyncEvents;
  985. pMsg->Params[0] = dwBufSize - sizeof (TAPI32_MSG);
  986. dwUsedSize = sizeof (TAPI32_MSG);
  987. RpcTryExcept
  988. {
  989. ClientRequest (gphCx, (char *) pMsg, dwBufSize, &dwUsedSize);
  990. bRetry = FALSE;
  991. }
  992. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  993. {
  994. bRetry = !(*pbExitThread);
  995. LOG((TL_INFO,
  996. "AsyncEventsThread: rpc exception %d handled",
  997. RpcExceptionCode()
  998. ));
  999. Sleep (10);
  1000. }
  1001. RpcEndExcept
  1002. } while (bRetry);
  1003. #if DBG
  1004. if (
  1005. ( dwUsedSize > dwBufSize )
  1006. ||
  1007. ( pMsg->Params[2] > dwBufSize )
  1008. )
  1009. {
  1010. LOG((TL_ERROR, "OVERFLOW!!!"));
  1011. LOG((TL_ERROR, "Watch this..."));
  1012. ClientFree( ClientAlloc( 0x10000 ) );
  1013. }
  1014. #endif
  1015. if ((dwUsedSize = (DWORD) pMsg->Params[2]) == 0 &&
  1016. (dwNeededSize = (DWORD) pMsg->Params[1]) != 0)
  1017. {
  1018. //
  1019. // There's a msg waiting for us that is bigger than our buffer,
  1020. // so alloc a larger buffer & try again
  1021. //
  1022. LPBYTE pNewBuf;
  1023. LOG((TL_INFO,
  1024. "AsyncEventsThread: allocating larger event buf (size=x%x)",
  1025. dwNeededSize
  1026. ));
  1027. dwNeededSize += sizeof (TAPI32_MSG) + 128;
  1028. if (!(pNewBuf = ClientAlloc (dwNeededSize)))
  1029. {
  1030. goto AsyncEventsThread_clientRequest;
  1031. }
  1032. dwBufSize = dwNeededSize;
  1033. ClientFree (pBuf);
  1034. pBuf = pNewBuf;
  1035. pMsg = (PTAPI32_MSG) pBuf;
  1036. goto AsyncEventsThread_clientRequest;
  1037. }
  1038. //
  1039. // Handle the events
  1040. //
  1041. pAsyncEventMsg = (PASYNCEVENTMSG) (pBuf + sizeof (TAPI32_MSG));
  1042. while (dwUsedSize)
  1043. {
  1044. PINIT_DATA pInitData = (PINIT_DATA)ReferenceObject (ghHandleTable, pAsyncEventMsg->InitContext, INITDATA_KEY);
  1045. if (NULL == pInitData)
  1046. {
  1047. // There is something very wrong with this
  1048. // message. Skip to the next one.
  1049. goto AsyncEventsThread_nextMessage;
  1050. }
  1051. #ifdef _WIN64
  1052. // For win64 we need to convert DWORDs to ULONG_PTRs (64 bit values)
  1053. AsyncEventParams.hDevice = pAsyncEventMsg->hDevice;
  1054. AsyncEventParams.dwMsg = pAsyncEventMsg->Msg;
  1055. AsyncEventParams.dwCallbackInstance = pAsyncEventMsg->OpenContext;
  1056. AsyncEventParams.dwParam1 = pAsyncEventMsg->Param1;
  1057. AsyncEventParams.dwParam2 = pAsyncEventMsg->Param2;
  1058. AsyncEventParams.dwParam3 = pAsyncEventMsg->Param3;
  1059. #else // not _WIN64
  1060. CopyMemory (&AsyncEventParams.hDevice,
  1061. &pAsyncEventMsg->hDevice,
  1062. sizeof (ASYNC_EVENT_PARAMS));
  1063. #endif // _WIN64
  1064. switch (pAsyncEventMsg->Msg)
  1065. {
  1066. case LINE_REMOVE:
  1067. case PHONE_REMOVE:
  1068. case LINE_CREATE:
  1069. case LINE_REQUEST:
  1070. case PHONE_CREATE:
  1071. // For all messages EXCEPT these, pAsyncEventMsg is a handle
  1072. // to the callbackInstance value passed in line/phoneOpen.
  1073. // For these messages, do nothing!
  1074. break;
  1075. default:
  1076. // We need to get the CallbackInstance value back.
  1077. if (0 != pAsyncEventMsg->OpenContext)
  1078. {
  1079. AsyncEventParams.dwCallbackInstance = (ULONG_PTR)
  1080. ReferenceObject (ghHandleTable, pAsyncEventMsg->OpenContext, 0);
  1081. DereferenceObject (ghHandleTable, pAsyncEventMsg->OpenContext, 1);
  1082. if (LINE_CLOSE == pAsyncEventMsg->Msg ||
  1083. PHONE_CLOSE == pAsyncEventMsg->Msg)
  1084. {
  1085. // for these messages, we need to get rid of
  1086. // the handle to the callback instance, so
  1087. // dereference it once more.
  1088. DereferenceObject (ghHandleTable, pAsyncEventMsg->OpenContext, 1);
  1089. }
  1090. }
  1091. }
  1092. LOG((TL_INFO,
  1093. "AsyncEventsThread: msg=%d, hDev=x%x, p1=x%x, p2=x%x, p3=x%x",
  1094. AsyncEventParams.dwMsg,
  1095. AsyncEventParams.hDevice,
  1096. AsyncEventParams.dwParam1,
  1097. AsyncEventParams.dwParam2,
  1098. AsyncEventParams.dwParam3
  1099. ));
  1100. //
  1101. // Special case for UI msgs (not fwd'd to client)
  1102. //
  1103. switch (pAsyncEventMsg->Msg)
  1104. {
  1105. case LINE_CREATEDIALOGINSTANCE:
  1106. {
  1107. DWORD dwThreadID,
  1108. dwDataOffset = pAsyncEventMsg->Param1,
  1109. dwDataSize = pAsyncEventMsg->Param2,
  1110. dwUIDllNameOffset = pAsyncEventMsg->Param3;
  1111. PUITHREADDATA pUIThreadData;
  1112. if (!(pUIThreadData = ClientAlloc (sizeof (UITHREADDATA))))
  1113. {
  1114. goto LINE_CREATEDIALOGINSTANCE_error;
  1115. }
  1116. if ((pUIThreadData->dwSize = dwDataSize) != 0)
  1117. {
  1118. if (!(pUIThreadData->pParams = ClientAlloc (dwDataSize)))
  1119. {
  1120. goto LINE_CREATEDIALOGINSTANCE_error;
  1121. }
  1122. CopyMemory(
  1123. pUIThreadData->pParams,
  1124. ((LPBYTE)pAsyncEventMsg) + dwDataOffset,
  1125. dwDataSize
  1126. );
  1127. }
  1128. if (!(pUIThreadData->hUIDll = TAPILoadLibraryW(
  1129. (PWSTR)(((LPBYTE) pAsyncEventMsg) +
  1130. dwUIDllNameOffset)
  1131. )))
  1132. {
  1133. LOG((TL_ERROR,
  1134. "LoadLibraryW(%ls) failed, err=%d",
  1135. ((LPBYTE)pAsyncEventMsg + dwUIDllNameOffset),
  1136. GetLastError()
  1137. ));
  1138. goto LINE_CREATEDIALOGINSTANCE_error;
  1139. }
  1140. if (!(pUIThreadData->pfnTUISPI_providerGenericDialog =
  1141. (TUISPIPROC) GetProcAddress(
  1142. pUIThreadData->hUIDll,
  1143. (LPCSTR) gszTUISPI_providerGenericDialog
  1144. )))
  1145. {
  1146. LOG((TL_ERROR,
  1147. "GetProcAddr(TUISPI_providerGenericDialog) failed"
  1148. ));
  1149. goto LINE_CREATEDIALOGINSTANCE_error;
  1150. }
  1151. pUIThreadData->pfnTUISPI_providerGenericDialogData =
  1152. (TUISPIPROC) GetProcAddress(
  1153. pUIThreadData->hUIDll,
  1154. (LPCSTR) gszTUISPI_providerGenericDialogData
  1155. );
  1156. if (!(pUIThreadData->hEvent = CreateEvent(
  1157. (LPSECURITY_ATTRIBUTES) NULL,
  1158. TRUE, // manual reset
  1159. FALSE, // non-signaled
  1160. NULL // unnamed
  1161. )))
  1162. {
  1163. goto LINE_CREATEDIALOGINSTANCE_error;
  1164. }
  1165. pUIThreadData->htDlgInst = (HTAPIDIALOGINSTANCE)
  1166. pAsyncEventMsg->hDevice;
  1167. //
  1168. // Safely add this instance to the global list
  1169. // (check if gdwNumInits == 0, & if so fail)
  1170. //
  1171. EnterCriticalSection (&gCriticalSection);
  1172. if (gdwNumInits != 0)
  1173. {
  1174. if ((pUIThreadData->pNext = gpUIThreadInstances))
  1175. {
  1176. pUIThreadData->pNext->pPrev = pUIThreadData;
  1177. }
  1178. gpUIThreadInstances = pUIThreadData;
  1179. LeaveCriticalSection (&gCriticalSection);
  1180. }
  1181. else
  1182. {
  1183. LeaveCriticalSection (&gCriticalSection);
  1184. goto LINE_CREATEDIALOGINSTANCE_error;
  1185. }
  1186. if ((pUIThreadData->hThread = CreateThread(
  1187. (LPSECURITY_ATTRIBUTES) NULL,
  1188. 0,
  1189. (LPTHREAD_START_ROUTINE) UIThread,
  1190. (LPVOID) pUIThreadData,
  1191. 0,
  1192. &dwThreadID
  1193. )))
  1194. {
  1195. goto AsyncEventsThread_decrUsedSize;
  1196. }
  1197. //
  1198. // If here an error occured, so safely remove the ui
  1199. // thread data struct from the global list
  1200. //
  1201. EnterCriticalSection (&gCriticalSection);
  1202. if (pUIThreadData->pNext)
  1203. {
  1204. pUIThreadData->pNext->pPrev = pUIThreadData->pPrev;
  1205. }
  1206. if (pUIThreadData->pPrev)
  1207. {
  1208. pUIThreadData->pPrev->pNext = pUIThreadData->pNext;
  1209. }
  1210. else
  1211. {
  1212. gpUIThreadInstances = pUIThreadData->pNext;
  1213. }
  1214. LeaveCriticalSection (&gCriticalSection);
  1215. LINE_CREATEDIALOGINSTANCE_error:
  1216. if (pUIThreadData)
  1217. {
  1218. if (pUIThreadData->pParams)
  1219. {
  1220. ClientFree (pUIThreadData->pParams);
  1221. }
  1222. if (pUIThreadData->hUIDll)
  1223. {
  1224. FreeLibrary (pUIThreadData->hUIDll);
  1225. }
  1226. if (pUIThreadData->hEvent)
  1227. {
  1228. CloseHandle (pUIThreadData->hEvent);
  1229. }
  1230. ClientFree (pUIThreadData);
  1231. }
  1232. {
  1233. FUNC_ARGS funcArgs =
  1234. {
  1235. MAKELONG (LINE_FUNC | SYNC | 1, xFreeDialogInstance),
  1236. {
  1237. (DWORD) pAsyncEventMsg->hDevice
  1238. },
  1239. {
  1240. Dword
  1241. }
  1242. };
  1243. DOFUNC (&funcArgs, "FreeDialogInstance");
  1244. }
  1245. goto AsyncEventsThread_decrUsedSize;
  1246. }
  1247. case LINE_SENDDIALOGINSTANCEDATA:
  1248. {
  1249. PUITHREADDATA pUIThreadData = gpUIThreadInstances;
  1250. HTAPIDIALOGINSTANCE htDlgInst = (HTAPIDIALOGINSTANCE)
  1251. pAsyncEventMsg->hDevice;
  1252. EnterCriticalSection (&gCriticalSection);
  1253. while (pUIThreadData)
  1254. {
  1255. if (pUIThreadData->htDlgInst == htDlgInst)
  1256. {
  1257. WaitForSingleObject (pUIThreadData->hEvent, INFINITE);
  1258. (*pUIThreadData->pfnTUISPI_providerGenericDialogData)(
  1259. htDlgInst,
  1260. ((LPBYTE) pAsyncEventMsg) +
  1261. pAsyncEventMsg->Param1, // data offset
  1262. pAsyncEventMsg->Param2 // data size
  1263. );
  1264. break;
  1265. }
  1266. pUIThreadData = pUIThreadData->pNext;
  1267. }
  1268. LeaveCriticalSection (&gCriticalSection);
  1269. goto AsyncEventsThread_decrUsedSize;
  1270. }
  1271. }
  1272. //
  1273. // Enter the critical section so we've exclusive access
  1274. // to the init data, & verify it
  1275. //
  1276. EnterCriticalSection (&gCriticalSection);
  1277. try
  1278. {
  1279. #if defined(_M_IX86) && _MSC_FULL_VER <= 13008806
  1280. DWORD dw= pInitData->dwKey; // workaround compiler bug.
  1281. if (dw != INITDATA_KEY)
  1282. #else
  1283. if (pInitData->dwKey != INITDATA_KEY)
  1284. #endif
  1285. {
  1286. LOG((TL_ERROR, "Bad pInitInst, discarding msg"));
  1287. goto AsyncEventsThread_leaveCritSec;
  1288. }
  1289. }
  1290. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  1291. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  1292. {
  1293. goto AsyncEventsThread_leaveCritSec;
  1294. }
  1295. //
  1296. // Special case for PROXYREQUEST
  1297. //
  1298. if (pAsyncEventMsg->Msg == LINE_PROXYREQUEST)
  1299. {
  1300. PPROXYREQUESTHEADER pProxyRequestHeader;
  1301. LPLINEPROXYREQUEST pProxyRequest = (LPLINEPROXYREQUEST)
  1302. (pAsyncEventMsg + 1),
  1303. pProxyRequestApp;
  1304. switch (pProxyRequest->dwRequestType)
  1305. {
  1306. case LINEPROXYREQUEST_SETAGENTGROUP:
  1307. case LINEPROXYREQUEST_SETAGENTSTATE:
  1308. case LINEPROXYREQUEST_SETAGENTACTIVITY:
  1309. case LINEPROXYREQUEST_AGENTSPECIFIC:
  1310. case LINEPROXYREQUEST_CREATEAGENT:
  1311. case LINEPROXYREQUEST_CREATEAGENTSESSION:
  1312. case LINEPROXYREQUEST_SETAGENTMEASUREMENTPERIOD:
  1313. case LINEPROXYREQUEST_SETAGENTSESSIONSTATE:
  1314. case LINEPROXYREQUEST_SETQUEUEMEASUREMENTPERIOD:
  1315. case LINEPROXYREQUEST_SETAGENTSTATEEX:
  1316. //
  1317. // For these msgs the proxy request as received from
  1318. // the tapisrv already contains the exact bits we want
  1319. // to pass on to the app, so we just alloc a buffer of
  1320. // the same size (plus a little extra for the key at
  1321. // the head of the buffer) and copy the data to it
  1322. //
  1323. if (!(pProxyRequestHeader = ClientAlloc(
  1324. sizeof (PROXYREQUESTHEADER) + pProxyRequest->dwSize
  1325. )))
  1326. {
  1327. // Could not allocate memory;
  1328. // skip this...
  1329. goto AsyncEventsThread_leaveCritSec;
  1330. }
  1331. pProxyRequestApp = (LPLINEPROXYREQUEST)
  1332. (pProxyRequestHeader + 1);
  1333. CopyMemory(
  1334. pProxyRequestApp,
  1335. pProxyRequest,
  1336. pProxyRequest->dwSize
  1337. );
  1338. break;
  1339. case LINEPROXYREQUEST_GETAGENTCAPS:
  1340. case LINEPROXYREQUEST_GETAGENTSTATUS:
  1341. case LINEPROXYREQUEST_GETAGENTACTIVITYLIST:
  1342. case LINEPROXYREQUEST_GETAGENTGROUPLIST:
  1343. case LINEPROXYREQUEST_GETQUEUEINFO:
  1344. case LINEPROXYREQUEST_GETGROUPLIST:
  1345. case LINEPROXYREQUEST_GETQUEUELIST:
  1346. case LINEPROXYREQUEST_GETAGENTINFO:
  1347. case LINEPROXYREQUEST_GETAGENTSESSIONINFO:
  1348. case LINEPROXYREQUEST_GETAGENTSESSIONLIST:
  1349. {
  1350. DWORD dwSizeToCopy = 0;
  1351. //
  1352. // For these msgs tapisrv only embedded the dwTotalSize
  1353. // field of the corresponding structure (to save having
  1354. // to send us a bunch of unused bits), so we want to
  1355. // increase the pProxyRequest->dwSize by the dwTotalSize
  1356. // - sizeof (DWORD), alloc a buffer (including a little
  1357. // extra space for the key at the head of the buffer),
  1358. // and rebuild the request
  1359. //
  1360. if ( pProxyRequest->dwRequestType ==
  1361. LINEPROXYREQUEST_GETGROUPLIST )
  1362. {
  1363. pProxyRequest->dwSize +=
  1364. (pProxyRequest->GetGroupList.GroupList.dwTotalSize)&TALIGN_MASK;
  1365. dwSizeToCopy = 8 * sizeof(DWORD);
  1366. }
  1367. else if ( pProxyRequest->dwRequestType ==
  1368. LINEPROXYREQUEST_GETQUEUELIST )
  1369. {
  1370. pProxyRequest->dwSize +=
  1371. (pProxyRequest->GetQueueList.QueueList.dwTotalSize)&TALIGN_MASK;
  1372. dwSizeToCopy = 8 * sizeof(DWORD) + sizeof(GUID);
  1373. }
  1374. else
  1375. {
  1376. //
  1377. // all of the rest of the structures have the
  1378. // same format
  1379. //
  1380. pProxyRequest->dwSize +=
  1381. (pProxyRequest->GetAgentCaps.AgentCaps.dwTotalSize)&TALIGN_MASK;
  1382. dwSizeToCopy = 9 * sizeof(DWORD);
  1383. }
  1384. if (!(pProxyRequestHeader = ClientAlloc(
  1385. sizeof (PROXYREQUESTHEADER) + pProxyRequest->dwSize
  1386. + sizeof(DWORD) + sizeof(DWORD)
  1387. )))
  1388. {
  1389. // Could not allocate memory;
  1390. // skip this...
  1391. goto AsyncEventsThread_leaveCritSec;
  1392. }
  1393. pProxyRequestApp = (LPLINEPROXYREQUEST)
  1394. (pProxyRequestHeader + 1);
  1395. //
  1396. // The following will copy the non-union fields in the
  1397. // proxy message, as well as the first two DWORD in the
  1398. // union (which currently are the dwAddressID and the
  1399. // dwTotalSize field of the corresponding structure)
  1400. //
  1401. CopyMemory(
  1402. pProxyRequestApp,
  1403. pProxyRequest,
  1404. dwSizeToCopy
  1405. );
  1406. //
  1407. // Relocate the machine & user names to the end of the
  1408. // structure
  1409. //
  1410. pProxyRequestApp->dwClientMachineNameOffset =
  1411. pProxyRequest->dwSize -
  1412. pProxyRequest->dwClientMachineNameSize;
  1413. wcscpy(
  1414. (WCHAR *)(((LPBYTE) pProxyRequestApp) +
  1415. pProxyRequestApp->dwClientMachineNameOffset),
  1416. (WCHAR *)(((LPBYTE) pProxyRequest) +
  1417. pProxyRequest->dwClientMachineNameOffset)
  1418. );
  1419. pProxyRequestApp->dwClientUserNameOffset =
  1420. pProxyRequestApp->dwClientMachineNameOffset -
  1421. pProxyRequest->dwClientUserNameSize;
  1422. wcscpy(
  1423. (WCHAR *)(((LPBYTE) pProxyRequestApp) +
  1424. pProxyRequestApp->dwClientUserNameOffset),
  1425. (WCHAR *)(((LPBYTE) pProxyRequest) +
  1426. pProxyRequest->dwClientUserNameOffset)
  1427. );
  1428. break;
  1429. }
  1430. }
  1431. pProxyRequestHeader->dwKey = TPROXYREQUESTHEADER_KEY;
  1432. pProxyRequestHeader->dwInstance = pAsyncEventMsg->Param1;
  1433. AsyncEventParams.dwParam1 = (ULONG_PTR) pProxyRequestApp;
  1434. }
  1435. //
  1436. // Call the post processing proc if there is one
  1437. //
  1438. if (pAsyncEventMsg->fnPostProcessProcHandle)
  1439. {
  1440. (*(gPostProcessingFunctions[
  1441. pAsyncEventMsg->fnPostProcessProcHandle]))(pAsyncEventMsg);
  1442. }
  1443. //
  1444. // If this init instance is using a completion port then
  1445. // alloc msg struct & post the msg to the completion port,
  1446. // then jump down below to exit the critsec, etc
  1447. //
  1448. if ((pInitData->dwInitOptions & 0x3) ==
  1449. LINEINITIALIZEEXOPTION_USECOMPLETIONPORT)
  1450. {
  1451. LPLINEMESSAGE pMsg;
  1452. if ((pMsg = LocalAlloc (LMEM_FIXED, sizeof(LINEMESSAGE))))
  1453. {
  1454. CopyMemory (pMsg, &AsyncEventParams, sizeof(LINEMESSAGE));
  1455. if (gpPostQueuedCompletionStatus &&
  1456. !gpPostQueuedCompletionStatus(
  1457. pInitData->hCompletionPort,
  1458. sizeof (LINEMESSAGE),
  1459. pInitData->dwCompletionKey,
  1460. (LPOVERLAPPED) pMsg
  1461. ))
  1462. {
  1463. LocalFree (pMsg);
  1464. LOG((TL_ERROR,
  1465. "AsyncEventsThread: PostQueuedCompletionStatus " \
  1466. "failed, err=%d",
  1467. GetLastError()
  1468. ));
  1469. }
  1470. else
  1471. {
  1472. LOG((TL_INFO,
  1473. "AsyncEventsThread: posted complPort msg\n",
  1474. "\thDev=x%x, ctx=x%x, p1=x%x, p2=x%x, p3=x%x",
  1475. AsyncEventParams.hDevice,
  1476. AsyncEventParams.dwCallbackInstance,
  1477. AsyncEventParams.dwParam1,
  1478. AsyncEventParams.dwParam2,
  1479. AsyncEventParams.dwParam3
  1480. ));
  1481. }
  1482. }
  1483. goto AsyncEventsThread_leaveCritSec;
  1484. }
  1485. //
  1486. // See if we need to increase the msg queue size, and if
  1487. // so alloc a new buf, copy the existing msgs over (careful
  1488. // to preserve order in a wrapped buffer), free the old buf
  1489. // and reset the appropriate fields in the init data struct
  1490. //
  1491. if (pInitData->dwNumTotalEntries ==
  1492. pInitData->dwNumUsedEntries)
  1493. {
  1494. DWORD dwNumTotalEntries =
  1495. pInitData->dwNumTotalEntries;
  1496. PASYNC_EVENT_PARAMS pNewEventBuffer;
  1497. if ((pNewEventBuffer = ClientAlloc(
  1498. 2 * dwNumTotalEntries * sizeof (ASYNC_EVENT_PARAMS)
  1499. )))
  1500. {
  1501. DWORD dwNumWrappedEntries = (DWORD)
  1502. (pInitData->pValidEntry -
  1503. pInitData->pEventBuffer);
  1504. CopyMemory(
  1505. pNewEventBuffer,
  1506. pInitData->pValidEntry,
  1507. (dwNumTotalEntries - dwNumWrappedEntries)
  1508. * sizeof (ASYNC_EVENT_PARAMS)
  1509. );
  1510. if (dwNumWrappedEntries)
  1511. {
  1512. CopyMemory(
  1513. pNewEventBuffer +
  1514. (dwNumTotalEntries - dwNumWrappedEntries),
  1515. pInitData->pEventBuffer,
  1516. dwNumWrappedEntries * sizeof (ASYNC_EVENT_PARAMS)
  1517. );
  1518. }
  1519. ClientFree (pInitData->pEventBuffer);
  1520. pInitData->pEventBuffer =
  1521. pInitData->pValidEntry = pNewEventBuffer;
  1522. pInitData->pFreeEntry =
  1523. pNewEventBuffer + dwNumTotalEntries;
  1524. pInitData->dwNumTotalEntries *= 2;
  1525. }
  1526. else
  1527. {
  1528. // Could not allocate memory,
  1529. // skip this message...
  1530. goto AsyncEventsThread_leaveCritSec;
  1531. }
  1532. }
  1533. //
  1534. // Copy the msg to the hidden window's msg queue,
  1535. // and update that queue's pointers
  1536. //
  1537. CopyMemory(
  1538. pInitData->pFreeEntry,
  1539. &AsyncEventParams,
  1540. sizeof (ASYNC_EVENT_PARAMS)
  1541. );
  1542. pInitData->dwNumUsedEntries++;
  1543. pInitData->pFreeEntry++;
  1544. if (pInitData->pFreeEntry >= (pInitData->pEventBuffer +
  1545. pInitData->dwNumTotalEntries))
  1546. {
  1547. pInitData->pFreeEntry = pInitData->pEventBuffer;
  1548. }
  1549. //
  1550. // If this init instance is using events for msg notification
  1551. // then see if we need to signal the app that there's an
  1552. // event waiting for it
  1553. //
  1554. // Else, post a msg to the hidden window (if there's not
  1555. // already one outstanding) to alert it that there's some
  1556. // events it needs to pass on to the app's callback
  1557. //
  1558. if ((pInitData->dwInitOptions & 0x3)
  1559. == LINEINITIALIZEEXOPTION_USEEVENT)
  1560. {
  1561. if (pInitData->dwNumUsedEntries > 0)
  1562. {
  1563. SetEvent (pInitData->hEvent);
  1564. }
  1565. }
  1566. else // HIDDENWINDOW
  1567. {
  1568. if (pInitData->bPendingAsyncEventMsg == FALSE)
  1569. {
  1570. LOG((TL_INFO,
  1571. "AsyncEventsThread: posting msg, hwnd=x%lx",
  1572. pInitData->hwnd
  1573. ));
  1574. PostMessage(
  1575. pInitData->hwnd,
  1576. WM_ASYNCEVENT,
  1577. 0,
  1578. (LPARAM) pInitData
  1579. );
  1580. pInitData->bPendingAsyncEventMsg = TRUE;
  1581. }
  1582. }
  1583. AsyncEventsThread_leaveCritSec:
  1584. LeaveCriticalSection (&gCriticalSection);
  1585. AsyncEventsThread_decrUsedSize:
  1586. DereferenceObject (ghHandleTable, pAsyncEventMsg->InitContext, 1);
  1587. AsyncEventsThread_nextMessage:
  1588. dwUsedSize -= (DWORD) pAsyncEventMsg->TotalSize;
  1589. pAsyncEventMsg = (PASYNCEVENTMSG)
  1590. ((LPBYTE) pAsyncEventMsg + pAsyncEventMsg->TotalSize);
  1591. if ( (LONG)dwUsedSize < 0 )
  1592. {
  1593. LOG((TL_ERROR, "dwUsedSize went negative!!!"));
  1594. }
  1595. }
  1596. }
  1597. {
  1598. //
  1599. // Free our resources, and then exit
  1600. //
  1601. HANDLE hTapi32 = pAsyncEventsThreadParams->hTapi32;
  1602. if (pAsyncEventsThreadParams->hWow32)
  1603. {
  1604. FreeLibrary (pAsyncEventsThreadParams->hWow32);
  1605. }
  1606. ClientFree (pBuf);
  1607. ClientFree (pAsyncEventsThreadParams);
  1608. LOG((TL_TRACE, "AsyncEventsThread: exit"));
  1609. FreeLibraryAndExitThread (hTapi32, 0);
  1610. }
  1611. }
  1612. BOOL
  1613. PASCAL
  1614. IsBadDwordPtr(
  1615. LPDWORD p
  1616. )
  1617. {
  1618. //
  1619. // Since IsBadWritePtr won't tell us if "p" is not DWORD-aligned (an
  1620. // issue on non-x86 platforms), we use the following to determine
  1621. // if the pointer is good. Note that DWORD p points at will get
  1622. // overwritten on successful completion of the request anyway, so
  1623. // preserving the original value is not important.
  1624. //
  1625. DWORD dwError;
  1626. BOOL bRet = FALSE;
  1627. try
  1628. {
  1629. *p = *p + 1;
  1630. *p = *p - 1;
  1631. }
  1632. except ((((dwError = GetExceptionCode()) == EXCEPTION_ACCESS_VIOLATION) ||
  1633. dwError == EXCEPTION_DATATYPE_MISALIGNMENT) ?
  1634. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  1635. {
  1636. bRet = TRUE;
  1637. }
  1638. return bRet;
  1639. }
  1640. BOOL
  1641. WINAPI
  1642. GrowBuf(
  1643. LPBYTE *ppBuf,
  1644. LPDWORD pdwBufSize,
  1645. DWORD dwCurrValidBytes,
  1646. DWORD dwBytesToAdd
  1647. )
  1648. {
  1649. DWORD dwCurrBufSize, dwNewBufSize;
  1650. LPBYTE pNewBuf;
  1651. //
  1652. // Try to get a new buffer big enough to hold everything
  1653. //
  1654. for(
  1655. dwNewBufSize = 2 * (dwCurrBufSize = *pdwBufSize);
  1656. dwNewBufSize < (dwCurrBufSize + dwBytesToAdd);
  1657. dwNewBufSize *= 2
  1658. );
  1659. if (!(pNewBuf = ClientAlloc (dwNewBufSize)))
  1660. {
  1661. return FALSE;
  1662. }
  1663. //
  1664. // Copy the "valid" bytes in the old buf to the new buf,
  1665. // then free the old buf
  1666. //
  1667. CopyMemory (pNewBuf, *ppBuf, dwCurrValidBytes);
  1668. ClientFree (*ppBuf);
  1669. //
  1670. // Reset the pointers to the new buf & buf size
  1671. //
  1672. *ppBuf = pNewBuf;
  1673. *pdwBufSize = dwNewBufSize;
  1674. return TRUE;
  1675. }
  1676. PCLIENT_THREAD_INFO
  1677. WINAPI
  1678. GetTls(
  1679. void
  1680. )
  1681. {
  1682. PCLIENT_THREAD_INFO pClientThreadInfo;
  1683. if (!(pClientThreadInfo = TlsGetValue (gdwTlsIndex)))
  1684. {
  1685. pClientThreadInfo = (PCLIENT_THREAD_INFO)
  1686. ClientAlloc (sizeof(CLIENT_THREAD_INFO));
  1687. if (!pClientThreadInfo)
  1688. {
  1689. return NULL;
  1690. }
  1691. pClientThreadInfo->pBuf = ClientAlloc (INITIAL_CLIENT_THREAD_BUF_SIZE);
  1692. if (!pClientThreadInfo->pBuf)
  1693. {
  1694. ClientFree (pClientThreadInfo);
  1695. return NULL;
  1696. }
  1697. pClientThreadInfo->dwBufSize = INITIAL_CLIENT_THREAD_BUF_SIZE;
  1698. TlsSetValue (gdwTlsIndex, (LPVOID) pClientThreadInfo);
  1699. EnterCriticalSection (&gTlsCriticalSection);
  1700. InsertHeadList (&gTlsListHead, &pClientThreadInfo->TlsList);
  1701. LeaveCriticalSection (&gTlsCriticalSection);
  1702. }
  1703. return pClientThreadInfo;
  1704. }
  1705. PCONTEXT_HANDLE_TYPE
  1706. WINAPI
  1707. GetTlsPCtxHandle(
  1708. void
  1709. )
  1710. {
  1711. return TlsGetValue (gdwTlsIndexRpcCtx);
  1712. }
  1713. BOOL
  1714. WINAPI
  1715. SetTlsPCtxHandle(
  1716. PCONTEXT_HANDLE_TYPE phCtxHandle
  1717. )
  1718. {
  1719. return TlsSetValue(gdwTlsIndexRpcCtx, phCtxHandle);
  1720. }
  1721. #if DBG
  1722. LONG
  1723. WINAPI
  1724. DoFunc(
  1725. PFUNC_ARGS pFuncArgs,
  1726. char *pszFuncName
  1727. )
  1728. #else
  1729. LONG
  1730. WINAPI
  1731. DoFunc(
  1732. PFUNC_ARGS pFuncArgs
  1733. )
  1734. #endif
  1735. {
  1736. DWORD dwFuncClassErrorIndex = (pFuncArgs->Flags & 0x00000030) >> 4;
  1737. LONG lResult;
  1738. BOOL bCopyOnSuccess = FALSE;
  1739. BOOL bResAllocated = FALSE;
  1740. DWORD i, j, dwUsedSize, dwNeededSize;
  1741. ULONG_PTR value;
  1742. PCONTEXT_HANDLE_TYPE phCtx;
  1743. PCLIENT_THREAD_INFO pTls;
  1744. #if DBG
  1745. LOG((TL_TRACE, "About to call %hs", pszFuncName));
  1746. #else
  1747. LOG((TL_TRACE, "DoFunc -- enter"));
  1748. #endif
  1749. //
  1750. // Check to make sure resources allocated
  1751. // (TAPISRV started, pipes opened, etc.)
  1752. //
  1753. if ( (lResult = AllocClientResources (dwFuncClassErrorIndex))
  1754. != TAPI_SUCCESS)
  1755. {
  1756. goto DoFunc_return;
  1757. }
  1758. bResAllocated = TRUE;
  1759. //
  1760. // Get the tls
  1761. //
  1762. if (!(pTls = GetTls()))
  1763. {
  1764. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  1765. goto DoFunc_return;
  1766. }
  1767. //
  1768. // The first arg of all async msg blocks is a remote request id; set
  1769. // this to zero to indicate that we are a local client (not remotesp)
  1770. //
  1771. if (pFuncArgs->Flags & ASYNC)
  1772. {
  1773. ((PTAPI32_MSG) pTls->pBuf)->Params[0] = 0;
  1774. }
  1775. //
  1776. // Validate all the func args
  1777. //
  1778. dwNeededSize = dwUsedSize = ALIGN(sizeof (TAPI32_MSG));
  1779. for(
  1780. i = 0, j = (pFuncArgs->Flags & ASYNC ? 1 : 0);
  1781. i < (pFuncArgs->Flags & NUM_ARGS_MASK);
  1782. i++, j++
  1783. )
  1784. {
  1785. value = /*((PTAPI32_MSG) pTls->pBuf)->Params[j] =*/ pFuncArgs->Args[i];
  1786. switch (pFuncArgs->ArgTypes[i])
  1787. {
  1788. case Dword:
  1789. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = DWORD_CAST(pFuncArgs->Args[i],__FILE__,__LINE__);
  1790. continue;
  1791. case hXxxApp_NULLOK:
  1792. case hXxxApp:
  1793. {
  1794. //
  1795. // Verify that the hXxxApp is a pointer to a valid InitData
  1796. // struct, then retrieve the real hXxxApp from that struct.
  1797. // If the hXxxApp is bad, pass the server 0xffffffff so that
  1798. // it can figure out whether to return an UNINITIALIZED error
  1799. // or a INVALAPPHANDLE error.
  1800. //
  1801. DWORD dwError;
  1802. PINIT_DATA pInitData;
  1803. if ((0 == pFuncArgs->Args[i]) &&
  1804. (hXxxApp_NULLOK == pFuncArgs->ArgTypes[i]))
  1805. {
  1806. //
  1807. // Looks good to me...
  1808. //
  1809. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = 0;
  1810. continue;
  1811. }
  1812. if ((pInitData = (PINIT_DATA) ReferenceObject(
  1813. ghHandleTable,
  1814. DWORD_CAST(pFuncArgs->Args[i],__FILE__,__LINE__),
  1815. INITDATA_KEY
  1816. )))
  1817. {
  1818. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = pInitData->hXxxApp;
  1819. DereferenceObject (ghHandleTable, DWORD_CAST(pFuncArgs->Args[i],__FILE__,__LINE__), 1);
  1820. }
  1821. else
  1822. {
  1823. //
  1824. // Fill in with a bogus hXxxApp so tapisrv can decide which
  1825. // error it wants to return
  1826. //
  1827. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = 0xffffffff;
  1828. }
  1829. continue;
  1830. }
  1831. case Hwnd:
  1832. if (!IsWindow ((HWND) value))
  1833. {
  1834. LOG((TL_ERROR, "Bad hWnd in dofunc"));
  1835. lResult = gaInvalHwndErrors[dwFuncClassErrorIndex];
  1836. goto DoFunc_return;
  1837. }
  1838. // The only functions that pass in Hwnd are
  1839. // tapiRequestDrop and tapiRequestMediaCall;
  1840. // both of these are non functional on the server side
  1841. // (correctly noted by the documentation). Parameters
  1842. // are not checked. Simply passing in 0 for the Hwnd will
  1843. // not affect functionality in any way, and will save a lot
  1844. // of grief coming from the 32 / 64 bit conversions (hwnd are
  1845. // 64 bits on 64 bit system, and the params we're using over
  1846. // the wire are only 32 bits).
  1847. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = 0;
  1848. continue;
  1849. case lpDword:
  1850. if (IsBadDwordPtr ((LPDWORD) value))
  1851. {
  1852. LOG((TL_ERROR, "Bad lpdword in dofunc"));
  1853. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  1854. goto DoFunc_return;
  1855. }
  1856. bCopyOnSuccess = TRUE;
  1857. continue;
  1858. case lpszW:
  1859. //
  1860. // Check if value is a valid string ptr and if so
  1861. // copy the contents of the string to the extra data
  1862. // buffer passed to the server
  1863. //
  1864. try
  1865. {
  1866. DWORD n = (lstrlenW((WCHAR *) value) + 1) * sizeof(WCHAR),
  1867. nAligned = ALIGN(n);
  1868. if ((nAligned + dwUsedSize) > pTls->dwBufSize)
  1869. {
  1870. if (!GrowBuf(
  1871. &pTls->pBuf,
  1872. &pTls->dwBufSize,
  1873. dwUsedSize,
  1874. nAligned
  1875. ))
  1876. {
  1877. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  1878. goto DoFunc_return;
  1879. }
  1880. }
  1881. CopyMemory (pTls->pBuf + dwUsedSize, (LPBYTE) value, n);
  1882. //
  1883. // Pass the server the offset of the string in the var data
  1884. // portion of the buffer
  1885. //
  1886. ((PTAPI32_MSG) pTls->pBuf)->Params[j] =
  1887. dwUsedSize - sizeof (TAPI32_MSG);
  1888. //
  1889. // Increment the total number of data bytes
  1890. //
  1891. dwUsedSize += nAligned;
  1892. dwNeededSize += nAligned;
  1893. }
  1894. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  1895. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  1896. {
  1897. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  1898. goto DoFunc_return;
  1899. }
  1900. continue;
  1901. case lpGet_Struct:
  1902. case lpGet_SizeToFollow:
  1903. {
  1904. BOOL bSizeToFollow = (pFuncArgs->ArgTypes[i]==lpGet_SizeToFollow);
  1905. DWORD dwSize;
  1906. if (bSizeToFollow)
  1907. {
  1908. #if DBG
  1909. //
  1910. // Check to make sure the following arg is of type Size
  1911. //
  1912. if ((i == ((pFuncArgs->Flags & NUM_ARGS_MASK) - 1)) ||
  1913. (pFuncArgs->ArgTypes[i + 1] != Size))
  1914. {
  1915. LOG((TL_ERROR,
  1916. "DoFunc: error, lpGet_SizeToFollow !followed by Size"
  1917. ));
  1918. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  1919. goto DoFunc_return;
  1920. }
  1921. #endif
  1922. dwSize = DWORD_CAST(pFuncArgs->Args[i + 1],__FILE__,__LINE__);
  1923. }
  1924. else
  1925. {
  1926. DWORD dwError;
  1927. try
  1928. {
  1929. dwSize = *((LPDWORD) value);
  1930. }
  1931. except ((((dwError = GetExceptionCode())
  1932. == EXCEPTION_ACCESS_VIOLATION) ||
  1933. dwError == EXCEPTION_DATATYPE_MISALIGNMENT) ?
  1934. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  1935. {
  1936. LOG((TL_ERROR, "Bad get struct/size in dofunc"));
  1937. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  1938. goto DoFunc_return;
  1939. }
  1940. }
  1941. if (IsBadWritePtr ((LPVOID) value, dwSize))
  1942. {
  1943. LOG((TL_ERROR, "Bad get size/struct2 in dofunc"));
  1944. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  1945. goto DoFunc_return;
  1946. }
  1947. if (bSizeToFollow)
  1948. {
  1949. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = TAPI_NO_DATA;
  1950. ++j;++i;
  1951. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = DWORD_CAST(pFuncArgs->Args[i],__FILE__,__LINE__);
  1952. }
  1953. else
  1954. {
  1955. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = dwSize;
  1956. }
  1957. //
  1958. // Now set the bCopyOnSuccess flag to indicate that we've data
  1959. // to copy back on successful completion, and add to the
  1960. // dwNeededSize field
  1961. //
  1962. bCopyOnSuccess = TRUE;
  1963. dwNeededSize += ALIGN(dwSize);
  1964. continue;
  1965. }
  1966. case lpSet_Struct:
  1967. case lpSet_SizeToFollow:
  1968. {
  1969. BOOL bSizeToFollow = (pFuncArgs->ArgTypes[i]==lpSet_SizeToFollow);
  1970. DWORD dwSize, dwError, dwSizeAligned;
  1971. #if DBG
  1972. //
  1973. // Check to make sure the following arg is of type Size
  1974. //
  1975. if (bSizeToFollow &&
  1976. ((i == ((pFuncArgs->Flags & NUM_ARGS_MASK) - 1)) ||
  1977. (pFuncArgs->ArgTypes[i + 1] != Size)))
  1978. {
  1979. LOG((TL_ERROR,
  1980. "DoFunc: error, lpSet_SizeToFollow !followed by Size"
  1981. ));
  1982. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  1983. goto DoFunc_return;
  1984. }
  1985. #endif
  1986. try
  1987. {
  1988. //
  1989. // First determine the data size & if the ptr is bad
  1990. //
  1991. dwSize = (bSizeToFollow ? DWORD_CAST(pFuncArgs->Args[i + 1],__FILE__,__LINE__) :
  1992. *((LPDWORD) value));
  1993. if (IsBadReadPtr ((LPVOID) value, dwSize))
  1994. {
  1995. LOG((TL_ERROR, "Bad set size/struct in dofunc"));
  1996. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  1997. goto DoFunc_return;
  1998. }
  1999. dwSizeAligned = ALIGN(dwSize);
  2000. //
  2001. // Special case if the size isn't even big enough to pass
  2002. // over a complete DWORD for the dwTotalSize field
  2003. //
  2004. if (!bSizeToFollow && (dwSize < sizeof (DWORD)))
  2005. {
  2006. static DWORD dwZeroTotalSize = 0;
  2007. dwSize = dwSizeAligned = sizeof (DWORD);
  2008. value = (ULONG_PTR) &dwZeroTotalSize;
  2009. // LOG((TL_ERROR, TEXT("Bad set size/struct2 in dofunc")));
  2010. // lResult = gaStructTooSmallErrors[dwFuncClassErrorIndex];
  2011. // goto DoFunc_return;
  2012. }
  2013. //
  2014. // Grow the buffer if necessary, & do the copy
  2015. //
  2016. if ((dwSizeAligned + dwUsedSize) > pTls->dwBufSize)
  2017. {
  2018. if (!GrowBuf(
  2019. &pTls->pBuf,
  2020. &pTls->dwBufSize,
  2021. dwUsedSize,
  2022. dwSizeAligned
  2023. ))
  2024. {
  2025. LOG((TL_ERROR, "Nomem set size/struct in dofunc"));
  2026. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2027. goto DoFunc_return;
  2028. }
  2029. }
  2030. CopyMemory (pTls->pBuf + dwUsedSize, (LPBYTE) value, dwSize);
  2031. }
  2032. except ((((dwError = GetExceptionCode())
  2033. == EXCEPTION_ACCESS_VIOLATION) ||
  2034. dwError == EXCEPTION_DATATYPE_MISALIGNMENT) ?
  2035. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  2036. {
  2037. LOG((TL_ERROR, "Bad pointer in get size/struct in dofunc"));
  2038. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  2039. goto DoFunc_return;
  2040. }
  2041. //
  2042. // Pass the server the offset of the data in the var data
  2043. // portion of the buffer
  2044. //
  2045. if (dwSize)
  2046. {
  2047. ((PTAPI32_MSG) pTls->pBuf)->Params[j] =
  2048. dwUsedSize - sizeof (TAPI32_MSG);
  2049. }
  2050. else
  2051. {
  2052. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = TAPI_NO_DATA;
  2053. }
  2054. //
  2055. // Increment the dwXxxSize vars appropriately
  2056. //
  2057. dwUsedSize += dwSizeAligned;
  2058. dwNeededSize += dwSizeAligned;
  2059. //
  2060. // Since we already know the next arg (Size) just handle
  2061. // it here so we don't have to run thru the loop again
  2062. //
  2063. if (bSizeToFollow)
  2064. {
  2065. ++i;++j;
  2066. ((PTAPI32_MSG) pTls->pBuf)->Params[j] = DWORD_CAST(pFuncArgs->Args[i],__FILE__,__LINE__);
  2067. }
  2068. continue;
  2069. }
  2070. #if DBG
  2071. case Size:
  2072. LOG((TL_ERROR, "DoFunc: error, hit case Size"));
  2073. continue;
  2074. default:
  2075. LOG((TL_ERROR, "DoFunc: error, unknown arg type"));
  2076. continue;
  2077. #endif
  2078. } // switch
  2079. } // for
  2080. //
  2081. // Now make the request
  2082. //
  2083. if (dwNeededSize > pTls->dwBufSize)
  2084. {
  2085. if (!GrowBuf(
  2086. &pTls->pBuf,
  2087. &pTls->dwBufSize,
  2088. dwUsedSize,
  2089. dwNeededSize - pTls->dwBufSize
  2090. ))
  2091. {
  2092. lResult = gaNoMemErrors[dwFuncClassErrorIndex];
  2093. goto DoFunc_return;
  2094. }
  2095. }
  2096. ((PTAPI32_MSG) pTls->pBuf)->u.Req_Func = (DWORD)HIWORD(pFuncArgs->Flags);
  2097. {
  2098. DWORD dwRetryCount = 0;
  2099. BOOL bReinitResource;
  2100. PCONTEXT_HANDLE_TYPE phCtxTmp = GetTlsPCtxHandle();
  2101. do
  2102. {
  2103. phCtx = (phCtxTmp != NULL)?phCtxTmp : gphCx;
  2104. bReinitResource = FALSE;
  2105. RpcTryExcept
  2106. {
  2107. ClientRequest (phCtx, pTls->pBuf, dwNeededSize, &dwUsedSize);
  2108. lResult = (LONG) ((PTAPI32_MSG) pTls->pBuf)->u.Ack_ReturnValue;
  2109. if (lResult == TAPIERR_INVALRPCCONTEXT)
  2110. {
  2111. if (dwRetryCount ++ >= gdwMaxNumRequestRetries)
  2112. {
  2113. bReinitResource = FALSE;
  2114. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2115. dwRetryCount = 0;
  2116. }
  2117. else
  2118. {
  2119. ((PTAPI32_MSG) pTls->pBuf)->u.Req_Func =
  2120. (DWORD)HIWORD(pFuncArgs->Flags);
  2121. bReinitResource = TRUE;
  2122. }
  2123. }
  2124. else
  2125. {
  2126. bReinitResource = FALSE;
  2127. dwRetryCount = 0;
  2128. }
  2129. }
  2130. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  2131. {
  2132. unsigned long rpcException = RpcExceptionCode();
  2133. if (rpcException == RPC_S_SERVER_TOO_BUSY)
  2134. {
  2135. if (dwRetryCount++ < gdwMaxNumRequestRetries)
  2136. {
  2137. Sleep (gdwRequestRetryTimeout);
  2138. }
  2139. else
  2140. {
  2141. dwRetryCount = 0;
  2142. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2143. }
  2144. }
  2145. else if ((rpcException == RPC_S_SERVER_UNAVAILABLE) ||
  2146. (rpcException == RPC_S_CALL_FAILED_DNE) ||
  2147. (rpcException == RPC_S_UNKNOWN_IF))
  2148. {
  2149. if (dwRetryCount ++ >= gdwMaxNumRequestRetries)
  2150. {
  2151. bReinitResource = FALSE;
  2152. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2153. dwRetryCount = 0;
  2154. }
  2155. else
  2156. {
  2157. bReinitResource = TRUE;
  2158. }
  2159. }
  2160. else
  2161. {
  2162. LOG((TL_ERROR, "DoFunc: rpcException # %d", rpcException));
  2163. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2164. dwRetryCount = 0;
  2165. }
  2166. }
  2167. RpcEndExcept
  2168. if (bReinitResource)
  2169. {
  2170. if (ReAllocClientResources(dwFuncClassErrorIndex) != TAPI_SUCCESS)
  2171. {
  2172. LOG((TL_ERROR, "DoFunc: ReAllocClientResources failed"));
  2173. lResult = gaOpFailedErrors[dwFuncClassErrorIndex];
  2174. dwRetryCount = 0;
  2175. bResAllocated = FALSE;
  2176. }
  2177. }
  2178. } while (dwRetryCount != 0);
  2179. }
  2180. // note: 99.99% of the time this result dump will == the one at end of the
  2181. // func (only when ptrs have gone bad will the result differ), no reason
  2182. // to dump 2x unless doing internal dbgging
  2183. //
  2184. LOG((TL_TRACE, "DoFunc: back from srv- return code=0x%08lx", lResult));
  2185. //
  2186. // If request completed successfully and the bCopyOnSuccess flag
  2187. // is set then we need to copy data back to client buffer(s)
  2188. //
  2189. if ((lResult == TAPI_SUCCESS) && bCopyOnSuccess)
  2190. {
  2191. for (i = 0, j = 0; i < (pFuncArgs->Flags & NUM_ARGS_MASK); i++, j++)
  2192. {
  2193. PTAPI32_MSG pMsg = (PTAPI32_MSG) pTls->pBuf;
  2194. switch (pFuncArgs->ArgTypes[i])
  2195. {
  2196. case Dword:
  2197. case Hwnd:
  2198. // case lpsz:
  2199. case lpszW:
  2200. case lpSet_Struct:
  2201. continue;
  2202. case lpDword:
  2203. try
  2204. {
  2205. //
  2206. // Fill in the pointer with the return value
  2207. //
  2208. *((LPDWORD) pFuncArgs->Args[i]) = (DWORD) pMsg->Params[j];
  2209. }
  2210. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  2211. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  2212. {
  2213. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  2214. goto DoFunc_return;
  2215. }
  2216. continue;
  2217. case lpGet_SizeToFollow:
  2218. try
  2219. {
  2220. //
  2221. // Fill in the pointer with the return value
  2222. //
  2223. CopyMemory(
  2224. (LPBYTE) pFuncArgs->Args[i],
  2225. pTls->pBuf + (DWORD)pMsg->Params[j] + sizeof(TAPI32_MSG),
  2226. pMsg->Params[j+1]
  2227. );
  2228. }
  2229. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  2230. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  2231. {
  2232. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  2233. goto DoFunc_return;
  2234. }
  2235. //
  2236. // Increment i (and j, since Size passed as arg in msg)
  2237. // to skip following Size arg in pFuncArgs->Args
  2238. //
  2239. i++;
  2240. j++;
  2241. continue;
  2242. case lpSet_SizeToFollow:
  2243. //
  2244. // Increment i (and j, since Size passed as arg in msg)
  2245. // to skip following Size arg in pFuncArgs->Args
  2246. //
  2247. i++;
  2248. j++;
  2249. continue;
  2250. case lpGet_Struct:
  2251. try
  2252. {
  2253. //
  2254. // Params[j] contains the offset in the var data
  2255. // portion of pTls->pBuf of some TAPI struct.
  2256. // Get the dwUsedSize value from this struct &
  2257. // copy that many bytes from pTls->pBuf to client buf
  2258. //
  2259. if ((DWORD)pMsg->Params[j] != TAPI_NO_DATA)
  2260. {
  2261. LPDWORD pStruct;
  2262. pStruct = (LPDWORD) (pTls->pBuf + sizeof(TAPI32_MSG) +
  2263. (DWORD)pMsg->Params[j]);
  2264. CopyMemory(
  2265. (LPBYTE) pFuncArgs->Args[i],
  2266. (LPBYTE) pStruct,
  2267. *(pStruct + 2) // ptr to dwUsedSize field
  2268. );
  2269. }
  2270. }
  2271. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  2272. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  2273. {
  2274. lResult = gaInvalPtrErrors[dwFuncClassErrorIndex];
  2275. goto DoFunc_return;
  2276. }
  2277. continue;
  2278. default:
  2279. continue;
  2280. }
  2281. }
  2282. }
  2283. DoFunc_return:
  2284. if (bResAllocated)
  2285. {
  2286. FreeClientResources();
  2287. }
  2288. #if DBG
  2289. {
  2290. char szResult[32];
  2291. LOG((TL_TRACE,
  2292. "%hs: result = %hs",
  2293. pszFuncName,
  2294. MapResultCodeToText (lResult, szResult)
  2295. ));
  2296. }
  2297. #else
  2298. LOG((TL_TRACE,
  2299. "DoFunc: result = x%x",
  2300. lResult
  2301. ));
  2302. #endif
  2303. return lResult;
  2304. }
  2305. LONG
  2306. LoadUIDll(
  2307. HWND hwndOwner,
  2308. DWORD dwWidgetID,
  2309. DWORD dwWidgetType,
  2310. HANDLE *phDll,
  2311. LPCSTR pszTUISPI_xxx, // use for GetProcAddress, leave as ANSI
  2312. TUISPIPROC *ppfnTUISPI_xxx
  2313. )
  2314. {
  2315. LONG lResult;
  2316. HANDLE hDll = NULL;
  2317. WCHAR szUIDllName[MAX_PATH];
  2318. HANDLE hProvidersMutex;
  2319. FUNC_ARGS funcArgs =
  2320. {
  2321. MAKELONG (LINE_FUNC | SYNC | 4, xGetUIDllName),
  2322. {
  2323. (ULONG_PTR) dwWidgetID,
  2324. (ULONG_PTR) dwWidgetType,
  2325. (ULONG_PTR) szUIDllName,
  2326. (ULONG_PTR) MAX_PATH
  2327. },
  2328. {
  2329. Dword,
  2330. Dword,
  2331. lpGet_SizeToFollow,
  2332. Size
  2333. }
  2334. };
  2335. if (hwndOwner && !IsWindow (hwndOwner))
  2336. {
  2337. lResult = (dwWidgetType == TUISPIDLL_OBJECT_PHONEID ?
  2338. PHONEERR_INVALPARAM : LINEERR_INVALPARAM);
  2339. goto LoadUIDll_return;
  2340. }
  2341. hProvidersMutex = CreateMutex (
  2342. NULL,
  2343. FALSE,
  2344. TEXT("TapisrvProviderListMutex")
  2345. );
  2346. if (NULL == hProvidersMutex)
  2347. {
  2348. lResult = (dwWidgetType == TUISPIDLL_OBJECT_PHONEID ?
  2349. PHONEERR_OPERATIONFAILED : LINEERR_OPERATIONFAILED);
  2350. goto LoadUIDll_return;
  2351. }
  2352. WaitForSingleObject (hProvidersMutex, INFINITE);
  2353. if ((lResult = DOFUNC (&funcArgs, "GetUIDllName")) == 0)
  2354. {
  2355. if (hDll = TAPILoadLibraryW(szUIDllName))
  2356. {
  2357. if ((*ppfnTUISPI_xxx = (TUISPIPROC) GetProcAddress(
  2358. hDll,
  2359. pszTUISPI_xxx
  2360. )))
  2361. {
  2362. *phDll = hDll;
  2363. lResult = 0;
  2364. }
  2365. else
  2366. {
  2367. LOG((TL_ERROR,
  2368. "LoadUIDll: GetProcAddress(%ls,%hs) failed, err=%d",
  2369. szUIDllName,
  2370. pszTUISPI_xxx,
  2371. GetLastError()
  2372. ));
  2373. FreeLibrary (hDll);
  2374. lResult = (dwWidgetType == TUISPIDLL_OBJECT_PHONEID ?
  2375. PHONEERR_OPERATIONUNAVAIL : LINEERR_OPERATIONUNAVAIL);
  2376. }
  2377. }
  2378. else
  2379. {
  2380. LOG((TL_ERROR,
  2381. "LoadLibraryW(%ls) failed, err=%d",
  2382. szUIDllName,
  2383. GetLastError()
  2384. ));
  2385. lResult = (dwWidgetType == TUISPIDLL_OBJECT_PHONEID ?
  2386. PHONEERR_OPERATIONFAILED : LINEERR_OPERATIONFAILED);
  2387. }
  2388. }
  2389. if (hProvidersMutex)
  2390. {
  2391. ReleaseMutex (hProvidersMutex);
  2392. CloseHandle (hProvidersMutex);
  2393. }
  2394. LoadUIDll_return:
  2395. return lResult;
  2396. }
  2397. LONG
  2398. PASCAL
  2399. lineXxxProvider(
  2400. LPCSTR pszTUISPI_providerXxx,
  2401. LPCSTR lpszProviderFilename,
  2402. HWND hwndOwner,
  2403. DWORD dwPermProviderID,
  2404. LPDWORD lpdwPermProviderID
  2405. )
  2406. {
  2407. BOOL bAddProvider = (pszTUISPI_providerXxx ==
  2408. gszTUISPI_providerInstall);
  2409. WCHAR szUIDllName[MAX_PATH];
  2410. LONG lResult;
  2411. HINSTANCE hDll;
  2412. TUISPIPROC pfnTUISPI_providerXxx;
  2413. HTAPIDIALOGINSTANCE htDlgInst;
  2414. LPTSTR tszProviderFilename;
  2415. #ifdef UNICODE
  2416. WCHAR wszProviderFilename[255];
  2417. HANDLE hProvidersMutex;
  2418. if (lpszProviderFilename)
  2419. {
  2420. MultiByteToWideChar(
  2421. GetACP(),
  2422. MB_PRECOMPOSED,
  2423. lpszProviderFilename,
  2424. lstrlenA (lpszProviderFilename) + 1,
  2425. wszProviderFilename,
  2426. sizeof(wszProviderFilename) / sizeof(WCHAR)
  2427. );
  2428. }
  2429. else
  2430. {
  2431. wszProviderFilename[0] = 0;
  2432. }
  2433. tszProviderFilename = wszProviderFilename;
  2434. #else
  2435. tszProviderFilename = lpszProviderFilename;
  2436. #endif
  2437. hProvidersMutex = CreateMutex (
  2438. NULL,
  2439. FALSE,
  2440. TEXT("TapisrvProviderListMutex")
  2441. );
  2442. if (NULL == hProvidersMutex)
  2443. {
  2444. return LINEERR_OPERATIONFAILED;
  2445. }
  2446. lResult = AllocClientResources(0);
  2447. if (lResult)
  2448. {
  2449. return lResult;
  2450. }
  2451. WaitForSingleObject (hProvidersMutex, INFINITE);
  2452. if (bAddProvider && IsBadDwordPtr (lpdwPermProviderID))
  2453. {
  2454. LOG((TL_ERROR, "Bad lpdwPermProviderID pointer"));
  2455. if (hProvidersMutex)
  2456. {
  2457. ReleaseMutex (hProvidersMutex);
  2458. CloseHandle (hProvidersMutex);
  2459. }
  2460. FreeClientResources ();
  2461. return LINEERR_INVALPOINTER;
  2462. }
  2463. else if (hwndOwner && !IsWindow (hwndOwner))
  2464. {
  2465. LOG((TL_ERROR, "hwndOwner is not a window"));
  2466. if (hProvidersMutex)
  2467. {
  2468. ReleaseMutex (hProvidersMutex);
  2469. CloseHandle (hProvidersMutex);
  2470. }
  2471. FreeClientResources ();
  2472. return LINEERR_INVALPARAM;
  2473. }
  2474. {
  2475. FUNC_ARGS funcArgs =
  2476. {
  2477. MAKELONG (LINE_FUNC | SYNC | 7, xGetUIDllName),
  2478. {
  2479. (bAddProvider ? (ULONG_PTR) &dwPermProviderID :
  2480. (ULONG_PTR) dwPermProviderID),
  2481. (ULONG_PTR) TUISPIDLL_OBJECT_PROVIDERID,
  2482. (ULONG_PTR) szUIDllName,
  2483. (ULONG_PTR) MAX_PATH,
  2484. (bAddProvider ? (ULONG_PTR) tszProviderFilename :
  2485. (ULONG_PTR) TAPI_NO_DATA),
  2486. (ULONG_PTR) (pszTUISPI_providerXxx==gszTUISPI_providerRemove ?
  2487. 1 : 0),
  2488. (ULONG_PTR) &htDlgInst
  2489. },
  2490. {
  2491. (bAddProvider ? lpDword : Dword),
  2492. Dword,
  2493. lpGet_SizeToFollow,
  2494. Size,
  2495. (bAddProvider ? lpszW : Dword),
  2496. Dword,
  2497. lpDword
  2498. }
  2499. };
  2500. if ((lResult = DOFUNC (&funcArgs,"lineXxxProvider/GetUIDllName")) != 0)
  2501. {
  2502. if (lResult == TAPI16BITSUCCESS)
  2503. {
  2504. // 16 bit sp success
  2505. // set result correctly, and return here
  2506. lResult = 0;
  2507. }
  2508. if (hProvidersMutex)
  2509. {
  2510. ReleaseMutex (hProvidersMutex);
  2511. CloseHandle (hProvidersMutex);
  2512. }
  2513. FreeClientResources ();
  2514. return lResult;
  2515. }
  2516. }
  2517. if ((hDll = TAPILoadLibraryW(szUIDllName)))
  2518. {
  2519. if ((pfnTUISPI_providerXxx = (TUISPIPROC) GetProcAddress(
  2520. hDll,
  2521. pszTUISPI_providerXxx
  2522. )))
  2523. {
  2524. LOG((TL_TRACE, "Calling %hs...", pszTUISPI_providerXxx));
  2525. lResult = (*pfnTUISPI_providerXxx)(
  2526. TUISPIDLLCallback,
  2527. hwndOwner,
  2528. dwPermProviderID
  2529. );
  2530. #if DBG
  2531. {
  2532. char szResult[32];
  2533. LOG((TL_TRACE,
  2534. "%hs: result = %hs",
  2535. pszTUISPI_providerXxx,
  2536. MapResultCodeToText (lResult, szResult)
  2537. ));
  2538. }
  2539. #else
  2540. LOG((TL_TRACE,
  2541. ": result = x%x",
  2542. lResult
  2543. ));
  2544. #endif
  2545. }
  2546. else
  2547. {
  2548. LOG((TL_ERROR,
  2549. "lineXxxProvider: GetProcAddr(%ls,%hs) failed, err=%d",
  2550. szUIDllName,
  2551. pszTUISPI_providerXxx,
  2552. GetLastError()
  2553. ));
  2554. //
  2555. // HACK ALERT !
  2556. // Even though remotesp.tsp does not have the add/remove/config
  2557. // provider function, we silently allow it to be added from
  2558. // tcmsetup.exe
  2559. //
  2560. if (lstrcmpi (gszRemoteSP, szUIDllName) != 0)
  2561. {
  2562. lResult = LINEERR_OPERATIONUNAVAIL;
  2563. }
  2564. }
  2565. FreeLibrary (hDll);
  2566. }
  2567. else
  2568. {
  2569. LOG((TL_ERROR,
  2570. "lineXxxProvider: LoadLibraryW('%ls') failed, err=%d",
  2571. szUIDllName,
  2572. GetLastError()
  2573. ));
  2574. lResult = LINEERR_OPERATIONFAILED;
  2575. }
  2576. {
  2577. LONG lResult2;
  2578. FUNC_ARGS funcArgs =
  2579. {
  2580. MAKELONG (LINE_FUNC | SYNC | 2, xFreeDialogInstance),
  2581. {
  2582. (ULONG_PTR) htDlgInst,
  2583. (ULONG_PTR) (ULONG)lResult
  2584. },
  2585. {
  2586. Dword,
  2587. Dword
  2588. }
  2589. };
  2590. //
  2591. // If TUISPI_providerXxx failed then we want to pass that error back
  2592. // to the app, else if it succeeded & FreeDlgInst failed then pass
  2593. // that error back to the app
  2594. //
  2595. if ((lResult2 = DOFUNC(
  2596. &funcArgs,
  2597. "lineXxxProvider/FreeDialogInstance"
  2598. )) == 0)
  2599. {
  2600. if (bAddProvider)
  2601. {
  2602. *lpdwPermProviderID = dwPermProviderID;
  2603. }
  2604. }
  2605. else if (lResult == 0)
  2606. {
  2607. lResult = lResult2;
  2608. }
  2609. }
  2610. if (hProvidersMutex)
  2611. {
  2612. ReleaseMutex (hProvidersMutex);
  2613. CloseHandle (hProvidersMutex);
  2614. }
  2615. FreeClientResources ();
  2616. return lResult;
  2617. }
  2618. LONG
  2619. PASCAL
  2620. ValidateXxxInitializeParams(
  2621. DWORD dwAPIVersion,
  2622. BOOL bLine,
  2623. LPLINEINITIALIZEEXPARAMS pXxxInitExParams,
  2624. LINECALLBACK pfnCallback
  2625. )
  2626. {
  2627. DWORD dwError;
  2628. try
  2629. {
  2630. DWORD dwTotalSize = pXxxInitExParams->dwTotalSize;
  2631. if (dwTotalSize < sizeof (LINEINITIALIZEEXPARAMS))
  2632. {
  2633. return (bLine ? LINEERR_STRUCTURETOOSMALL :
  2634. PHONEERR_STRUCTURETOOSMALL);
  2635. }
  2636. if (IsBadWritePtr (pXxxInitExParams, dwTotalSize))
  2637. {
  2638. return (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2639. }
  2640. //
  2641. // When checking the dwOptions field be careful about compatibility
  2642. // with future vers, so we only look at the currently valid bits
  2643. //
  2644. switch ((pXxxInitExParams->dwOptions & 0xf))
  2645. {
  2646. case 0:
  2647. case LINEINITIALIZEEXOPTION_USEHIDDENWINDOW:
  2648. if (IsBadCodePtr ((FARPROC) pfnCallback))
  2649. {
  2650. return (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2651. }
  2652. break;
  2653. case LINEINITIALIZEEXOPTION_USECOMPLETIONPORT:
  2654. if ( !gpPostQueuedCompletionStatus )
  2655. {
  2656. HINSTANCE hInst;
  2657. hInst = GetModuleHandle( TEXT("Kernel32.dll") );
  2658. #ifdef MEMPHIS
  2659. {
  2660. FARPROC pfn;
  2661. BOOL fResult;
  2662. DWORD dw;
  2663. OVERLAPPED o;
  2664. pfn = GetProcAddress (hInst, "GetCompletionPortStatus");
  2665. if ( NULL == pfn )
  2666. {
  2667. LOG((TL_ERROR,
  2668. "GetProcAddr(GetCompletionPortStatus) failed"
  2669. ));
  2670. return (bLine ?
  2671. LINEERR_INVALFEATURE : PHONEERR_OPERATIONFAILED);
  2672. }
  2673. fResult = pfn( -1, &dw, &dw, &o, 0 );
  2674. }
  2675. if ( ERROR_NOT_SUPPORTED != GetLastError() )
  2676. #endif
  2677. {
  2678. gpPostQueuedCompletionStatus = GetProcAddress(
  2679. hInst,
  2680. "PostQueuedCompletionStatus"
  2681. );
  2682. if ( NULL == gpPostQueuedCompletionStatus )
  2683. {
  2684. LOG((TL_ERROR,
  2685. "GetProcAddr(PostQueuedCompletionStatus) failed"
  2686. ));
  2687. return (bLine ?
  2688. LINEERR_INVALFEATURE : PHONEERR_OPERATIONFAILED);
  2689. }
  2690. }
  2691. }
  2692. break;
  2693. case LINEINITIALIZEEXOPTION_USEEVENT:
  2694. break;
  2695. default:
  2696. if ((TAPI_VERSION2_2 == dwAPIVersion) ||
  2697. (TAPI_VERSION2_1 == dwAPIVersion) ||
  2698. (TAPI_VERSION2_0 == dwAPIVersion))
  2699. {
  2700. //
  2701. // Invalid parameter for these versions
  2702. //
  2703. return (bLine ? LINEERR_INVALPARAM : PHONEERR_INVALPARAM);
  2704. }
  2705. else
  2706. {
  2707. //
  2708. // This app is asking for something we can't do.
  2709. //
  2710. return (bLine ? LINEERR_INCOMPATIBLEAPIVERSION :
  2711. PHONEERR_INCOMPATIBLEAPIVERSION);
  2712. }
  2713. }
  2714. pXxxInitExParams->dwNeededSize =
  2715. pXxxInitExParams->dwUsedSize = sizeof (LINEINITIALIZEEXPARAMS);
  2716. }
  2717. except ((((dwError = GetExceptionCode()) == EXCEPTION_ACCESS_VIOLATION) ||
  2718. dwError == EXCEPTION_DATATYPE_MISALIGNMENT) ?
  2719. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  2720. {
  2721. return (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2722. }
  2723. return 0;
  2724. }
  2725. LONG
  2726. WINAPI
  2727. xxxInitialize(
  2728. BOOL bLine,
  2729. LPVOID phXxxApp,
  2730. HINSTANCE hInstance,
  2731. LINECALLBACK pfnCallback,
  2732. LPCWSTR pszAppName,
  2733. LPDWORD pdwNumDevs,
  2734. LPDWORD pdwAPIVersion,
  2735. LPLINEINITIALIZEEXPARAMS pXxxInitExParams
  2736. #if DBG
  2737. ,char *pszFuncName
  2738. #endif
  2739. )
  2740. {
  2741. FUNC_ARGS funcArgs =
  2742. {
  2743. MAKELONG ((bLine ? LINE_FUNC : PHONE_FUNC) | SYNC | 7,
  2744. (bLine ? lInitialize : pInitialize)),
  2745. {
  2746. (ULONG_PTR) phXxxApp,
  2747. (ULONG_PTR) 0, // hInstance is ignored by tapisrv, so pass 0,
  2748. // to save ourselves grief over HINSTANCE -> DWORD conversion
  2749. (ULONG_PTR) 0, // pfnCallback, we subst pInitData in here
  2750. (ULONG_PTR) pszAppName,
  2751. (ULONG_PTR) pdwNumDevs,
  2752. (ULONG_PTR) 0, // pszModuleName
  2753. (ULONG_PTR) TAPI_VERSION1_0
  2754. },
  2755. {
  2756. lpDword,
  2757. Dword,
  2758. Dword,
  2759. lpszW,
  2760. lpDword,
  2761. lpszW,
  2762. Dword
  2763. }
  2764. };
  2765. WCHAR *pszModuleNamePathW = NULL;
  2766. WCHAR *pszModuleNameW = NULL;
  2767. LONG lResult;
  2768. BOOL bReleaseMutex = FALSE;
  2769. BOOL bResAllocated = FALSE;
  2770. PINIT_DATA pInitData = (PINIT_DATA) NULL;
  2771. BOOL fIs16bitCaller = FALSE;
  2772. DWORD dwAllInitExOptions;
  2773. EnterCriticalSection (&gCriticalSection);
  2774. if (gdwNumInits == 0)
  2775. {
  2776. TRACELOGREGISTER (_T("tapi32"));
  2777. }
  2778. LeaveCriticalSection (&gCriticalSection);
  2779. if (phXxxApp == (LPVOID) pdwNumDevs)
  2780. {
  2781. #if DBG
  2782. LOG((TL_TRACE, "%hs: error, lphApp == lpdwNumDevs", pszFuncName));
  2783. #else
  2784. LOG((TL_TRACE, ": error, lphApp == lpdwNumDevs"));
  2785. #endif
  2786. lResult = (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2787. goto xxxInitialize_return;
  2788. }
  2789. if (pdwAPIVersion)
  2790. {
  2791. if (phXxxApp == (LPVOID) pdwAPIVersion ||
  2792. phXxxApp == (LPVOID) pXxxInitExParams ||
  2793. pdwNumDevs == pdwAPIVersion ||
  2794. pdwNumDevs == (LPDWORD) pXxxInitExParams ||
  2795. pdwAPIVersion == (LPDWORD) pXxxInitExParams)
  2796. {
  2797. lResult = (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2798. goto xxxInitialize_return;
  2799. }
  2800. //
  2801. // line- & phoneInitializeEx both require a valid lpdwAPIVersion
  2802. // pointer parameter, and the value it points to on the way in
  2803. // must be >= 0x00020000. (Careful to allow for future vers of TAPI.)
  2804. //
  2805. if (*pdwAPIVersion < TAPI_VERSION2_0)
  2806. {
  2807. LOG((TL_ERROR,
  2808. "%InitializeEx: error, *lpdwAPIVersion = x%x, " \
  2809. "must be set >= 0x20000",
  2810. *pdwAPIVersion,
  2811. (bLine ? "line" : "phone")
  2812. ));
  2813. lResult = (bLine ? LINEERR_INCOMPATIBLEAPIVERSION :
  2814. PHONEERR_INCOMPATIBLEAPIVERSION);
  2815. goto xxxInitialize_return;
  2816. }
  2817. //
  2818. // Validate the InitEx params, or if the pointer is NULL (implying
  2819. // that app wants to use "old" hidden window scheme) validate
  2820. // the pfnCallback
  2821. //
  2822. if (pXxxInitExParams)
  2823. {
  2824. if ((lResult = ValidateXxxInitializeParams(
  2825. (*pdwAPIVersion),
  2826. bLine,
  2827. pXxxInitExParams,
  2828. pfnCallback
  2829. )) != 0)
  2830. {
  2831. goto xxxInitialize_return;
  2832. }
  2833. }
  2834. else if (IsBadCodePtr ((FARPROC) pfnCallback))
  2835. {
  2836. #if DBG
  2837. LOG((TL_ERROR, "%hs: bad lpfnCallback", pszFuncName));
  2838. #else
  2839. LOG((TL_ERROR, ": bad lpfnCallback"));
  2840. #endif
  2841. lResult = (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2842. goto xxxInitialize_return;
  2843. }
  2844. //
  2845. // Now fill in *pdwAPIVersion with the version # we support, and
  2846. // also indicate this in the params we pass to tapisrv.exe (so
  2847. // it knows it can start sending us 2.0 msgs right away)
  2848. //
  2849. // bug #69742. don't assume version 2.0
  2850. if ( (*pdwAPIVersion == TAPI_VERSION2_2) ||
  2851. (*pdwAPIVersion == TAPI_VERSION2_1) ||
  2852. (*pdwAPIVersion == TAPI_VERSION2_0))
  2853. {
  2854. funcArgs.Args[6] = *pdwAPIVersion;
  2855. }
  2856. else
  2857. {
  2858. //
  2859. // the app is at least 2.0 if they are calling lineIntializeEx,
  2860. // but they passed in a bogus tapi version, so set it correctly.
  2861. //
  2862. funcArgs.Args[6] = *pdwAPIVersion = TAPI_CURRENT_VERSION;
  2863. }
  2864. }
  2865. #ifndef _WIN64
  2866. else if ((((DWORD) pfnCallback) & 0xffff0000) == 0xffff0000)
  2867. {
  2868. //
  2869. // This is a 16-bit client going through the thunk. The
  2870. // pfnCallback var is actually a window handle.
  2871. //
  2872. // Note: On NT, 32-bit code can talk to 16-bit HWNDs
  2873. // by setting the hi-word to 0xffff.
  2874. //
  2875. // On Win95, 32-bit can talk to 16-bit HWNDs
  2876. // by setting the hi-word to 0x0000.
  2877. //
  2878. //<! ((DWORD) pfnCallback) = HWND_32( pfnCallback );
  2879. //<!
  2880. //<!
  2881. if (!IsWindow ((HWND) pfnCallback))
  2882. {
  2883. //
  2884. // If here chances are it's a 32-bit app passing in a bad
  2885. // pfnCallback
  2886. //
  2887. #if DBG
  2888. LOG((TL_ERROR, "%hs: bad lpfnCallback", pszFuncName));
  2889. #else
  2890. LOG((TL_ERROR, ": bad lpfnCallback"));
  2891. #endif
  2892. lResult = (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2893. goto xxxInitialize_return;
  2894. }
  2895. if (!ghWow32Dll &&
  2896. !(ghWow32Dll = LoadLibrary (TEXT("wow32.dll"))))
  2897. {
  2898. #if DBG
  2899. LOG((TL_ERROR,
  2900. "%hs: LoadLib(wow32.dll) failed, err=%d",
  2901. pszFuncName,
  2902. GetLastError()
  2903. ));
  2904. #else
  2905. LOG((TL_ERROR,
  2906. ": LoadLib(wow32.dll) failed, err=%d",
  2907. GetLastError()
  2908. ));
  2909. #endif
  2910. lResult =
  2911. (bLine ? LINEERR_OPERATIONFAILED : PHONEERR_OPERATIONFAILED);
  2912. goto xxxInitialize_return;
  2913. }
  2914. if (!gpfnWOWGetVDMPointer &&
  2915. !(gpfnWOWGetVDMPointer = GetProcAddress(
  2916. ghWow32Dll,
  2917. "WOWGetVDMPointer"
  2918. )))
  2919. {
  2920. #if DBG
  2921. LOG((TL_ERROR,
  2922. "%hs: GetProcAddr(WOWGetVDMPointer) failed, err=%d",
  2923. pszFuncName,
  2924. GetLastError()
  2925. ));
  2926. #else
  2927. LOG((TL_ERROR,
  2928. ": GetProcAddr(WOWGetVDMPointer) failed, err=%d",
  2929. GetLastError()
  2930. ));
  2931. #endif
  2932. lResult =
  2933. (bLine ? LINEERR_OPERATIONFAILED : PHONEERR_OPERATIONFAILED);
  2934. goto xxxInitialize_return;
  2935. }
  2936. gbNTVDMClient = TRUE;
  2937. //
  2938. // For 16-bit clients the module name will follow the app name
  2939. //
  2940. // HACK ALERT!
  2941. //
  2942. // Since the lpszAppName pointer was already converted to a
  2943. // unicode string by the calling function, the following
  2944. // module name part was lost. So, we pass the original
  2945. // (16->32 mapped) lpszAppName pointer in pXxxInitExParams
  2946. // so we can discover the module name
  2947. //
  2948. {
  2949. char *pszAppName2 = (char *) pXxxInitExParams;
  2950. pXxxInitExParams = NULL; // so we don't blow up below
  2951. pszModuleNamePathW = NotSoWideStringToWideString(
  2952. pszAppName2 + lstrlenA (pszAppName2) + 1,
  2953. (DWORD) -1
  2954. );
  2955. funcArgs.Args[5] = (ULONG_PTR) pszModuleNamePathW;
  2956. LOG((TL_INFO,
  2957. "FName='%ls', MName='%ls'",
  2958. pszAppName,
  2959. funcArgs.Args[5]
  2960. ));
  2961. }
  2962. }
  2963. #endif
  2964. else if (IsBadCodePtr ((FARPROC) pfnCallback))
  2965. {
  2966. //
  2967. // If here a 32-bit app is call line/phoneInitialize
  2968. //
  2969. #if DBG
  2970. LOG((TL_ERROR, "%hs: bad lpfnCallback", pszFuncName));
  2971. #else
  2972. LOG((TL_ERROR, ": bad lpfnCallback"));
  2973. #endif
  2974. lResult = (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  2975. goto xxxInitialize_return;
  2976. }
  2977. //
  2978. // Check to see if hInstance is bad by getting the module name
  2979. //
  2980. // Note: We now allow a NULL hInstance (16-bit TAPI didn't)
  2981. //
  2982. if (gbNTVDMClient == FALSE)
  2983. {
  2984. DWORD dwSize = MAX_PATH, dwLength;
  2985. alloc_module_name_buf:
  2986. if (!(pszModuleNamePathW = ClientAlloc (dwSize*sizeof(WCHAR))))
  2987. {
  2988. lResult = (bLine ? LINEERR_NOMEM : PHONEERR_NOMEM);
  2989. goto xxxInitialize_return;
  2990. }
  2991. //
  2992. // We're on WinNT - do Unicode
  2993. //
  2994. if ((dwLength = GetModuleFileNameW(
  2995. hInstance,
  2996. pszModuleNamePathW,
  2997. dwSize
  2998. )) == 0)
  2999. {
  3000. #if DBG
  3001. LOG((TL_ERROR,
  3002. "%hs: GetModuleFileNameW(x%p, ...) failed, err=%d",
  3003. pszFuncName,
  3004. hInstance,
  3005. GetLastError()
  3006. ));
  3007. #else
  3008. LOG((TL_ERROR,
  3009. ": GetModuleFileNameW(x%p, ...) failed, err=%d",
  3010. hInstance,
  3011. GetLastError()
  3012. ));
  3013. #endif
  3014. lResult = (bLine ? LINEERR_INVALPARAM : PHONEERR_INVALPARAM);
  3015. goto xxxInitialize_cleanup;
  3016. }
  3017. else if (dwLength >= dwSize)
  3018. {
  3019. ClientFree (pszModuleNamePathW);
  3020. dwSize *= 2;
  3021. goto alloc_module_name_buf;
  3022. }
  3023. pszModuleNameW = wcsrchr (pszModuleNamePathW, '\\') + 1;
  3024. // For MSWORKS.EXE, the behavior of lineGetTranslateCaps
  3025. // will be different
  3026. if(0 == _wcsicmp(pszModuleNameW, L"MSWORKS.EXE"))
  3027. {
  3028. LOG((TL_ERROR, "MSWORKS detected..."));
  3029. gbDisableGetTranslateCapsHack = TRUE;
  3030. }
  3031. else
  3032. {
  3033. gbDisableGetTranslateCapsHack = FALSE;
  3034. }
  3035. funcArgs.Args[5] = (ULONG_PTR) pszModuleNameW;
  3036. if (!pszAppName)
  3037. {
  3038. funcArgs.Args[3] = funcArgs.Args[5];
  3039. }
  3040. }
  3041. if (!(pInitData = ClientAlloc (sizeof(INIT_DATA))) ||
  3042. !(pInitData->pEventBuffer = ClientAlloc(
  3043. DEF_NUM_EVENT_BUFFER_ENTRIES * sizeof (ASYNC_EVENT_PARAMS))) ||
  3044. !(pInitData->hInitData = NewObject (ghHandleTable, pInitData, NULL)))
  3045. {
  3046. lResult = (bLine ? LINEERR_NOMEM : PHONEERR_NOMEM);
  3047. goto xxxInitialize_cleanup;
  3048. }
  3049. //
  3050. // When checking the dwOptions field be careful about compatibility
  3051. // with future vers, so we only look at the currently valid bits
  3052. // (The ExOptions are currently ordinals, but we track bits here just
  3053. // in case we wanna use high bits later.)
  3054. //
  3055. dwAllInitExOptions = AllInitExOptions2_0;
  3056. pInitData->dwInitOptions = (pXxxInitExParams ?
  3057. (pXxxInitExParams->dwOptions & dwAllInitExOptions) :
  3058. LINEINITIALIZEEXOPTION_USEHIDDENWINDOW);
  3059. switch (pInitData->dwInitOptions & 0xf)
  3060. {
  3061. case LINEINITIALIZEEXOPTION_USECOMPLETIONPORT:
  3062. //
  3063. // Be libertarian- if the app wants to hose itself by passing
  3064. // a bad hCompletionPort then so be it
  3065. //
  3066. pInitData->hCompletionPort =
  3067. pXxxInitExParams->Handles.hCompletionPort;
  3068. pInitData->dwCompletionKey = pXxxInitExParams->dwCompletionKey;
  3069. break;
  3070. case LINEINITIALIZEEXOPTION_USEEVENT:
  3071. if ((pInitData->hEvent = CreateEvent(
  3072. (LPSECURITY_ATTRIBUTES) NULL,
  3073. TRUE, // manual reset
  3074. FALSE, // unsignaled
  3075. NULL // unnamed
  3076. )) == NULL)
  3077. {
  3078. lResult = (bLine ? LINEERR_OPERATIONFAILED :
  3079. PHONEERR_OPERATIONFAILED);
  3080. goto xxxInitialize_cleanup;
  3081. }
  3082. pXxxInitExParams->Handles.hEvent = pInitData->hEvent;
  3083. break;
  3084. default: // case LINEINITIALIZEEXOPTION_USEHIDDENWINDOW:
  3085. pInitData->dwInitOptions |= LINEINITIALIZEEXOPTION_USEHIDDENWINDOW;
  3086. if (gbNTVDMClient == FALSE)
  3087. {
  3088. if ((lResult = CreateHiddenWindow(
  3089. &pInitData->hwnd,
  3090. (bLine ? 1 : 2)
  3091. )) != 0)
  3092. {
  3093. goto xxxInitialize_cleanup;
  3094. }
  3095. }
  3096. else
  3097. {
  3098. pInitData->hwnd = (HWND) pfnCallback;
  3099. }
  3100. pInitData->lpfnCallback = pfnCallback;
  3101. pInitData->bPendingAsyncEventMsg = FALSE;
  3102. break;
  3103. }
  3104. pInitData->dwKey = INITDATA_KEY;
  3105. pInitData->dwNumTotalEntries = DEF_NUM_EVENT_BUFFER_ENTRIES;
  3106. pInitData->dwNumUsedEntries = 0;
  3107. pInitData->pValidEntry =
  3108. pInitData->pFreeEntry = pInitData->pEventBuffer;
  3109. pInitData->bLine = bLine;
  3110. pInitData->dwThreadID = GetCurrentThreadId();
  3111. //
  3112. // We want to pass TAPISRV pInitData so that later when it does async
  3113. // completion/event notification it can pass pInitData along too so
  3114. // we know which init instance to talk to
  3115. //
  3116. funcArgs.Args[2] = (ULONG_PTR) pInitData->hInitData;
  3117. WaitForSingleObject (ghInitMutex, INFINITE);
  3118. bReleaseMutex = TRUE;
  3119. #ifdef MEMPHIS
  3120. //
  3121. // Make sure we only do it once per
  3122. //
  3123. if (fIs16bitCaller && gdwNumInits == 0)
  3124. {
  3125. HANDLE LocalEvent;
  3126. char buf[256];
  3127. LocalEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
  3128. wsprintfA(
  3129. buf,
  3130. "TAPI16.exe %lu %lu %lu %lu",
  3131. 0,
  3132. (DWORD)GetCurrentProcessId(),
  3133. (DWORD)LocalEvent,
  3134. h16bitHelperAppTerminateEvent
  3135. );
  3136. LOG((TL_TRACE, "Launching [%hs]", buf));
  3137. WinExec( buf, SW_HIDE );
  3138. LOG((TL_TRACE, "Waiting..."));
  3139. WaitForSingleObject( LocalEvent, INFINITE );
  3140. CloseHandle( LocalEvent );
  3141. LOG((TL_TRACE, "Not waiting..."));
  3142. }
  3143. #endif
  3144. //
  3145. // Need to hold a reference of the Rpc connection
  3146. // so we don't close it until lineShutdown
  3147. //
  3148. bResAllocated = (0 == AllocClientResources(bLine ? 1 : 2));
  3149. if (bResAllocated)
  3150. {
  3151. lResult = DOFUNC (&funcArgs, pszFuncName);
  3152. }
  3153. else
  3154. {
  3155. lResult = (bLine ? LINEERR_OPERATIONFAILED :
  3156. PHONEERR_OPERATIONFAILED);
  3157. }
  3158. xxxInitialize_cleanup:
  3159. if (pszModuleNamePathW)
  3160. {
  3161. ClientFree (pszModuleNamePathW);
  3162. }
  3163. if (lResult == 0)
  3164. {
  3165. //
  3166. // If total number of init instances is 0 we need to start a
  3167. // new async events thread
  3168. //
  3169. EnterCriticalSection (&gCriticalSection);
  3170. if (gdwNumInits == 0)
  3171. {
  3172. DWORD dwThreadID;
  3173. HANDLE hThread;
  3174. //
  3175. // Alloc resources for a new async events thread, then
  3176. // create the thread
  3177. //
  3178. if ((gpAsyncEventsThreadParams = ClientAlloc(
  3179. sizeof (ASYNC_EVENTS_THREAD_PARAMS)
  3180. )))
  3181. {
  3182. //
  3183. // Load ourself to increment our usage count. This is
  3184. // done to give the AsyncEventThread a chance to
  3185. // terminate cleanly if an app thread calls xxxShutdown
  3186. // and then immediately unloads tapi32.dll.
  3187. //
  3188. // (For a while we were doing a Wait on this thread's
  3189. // handle in xxxShutdown waiting for it to terminate,
  3190. // but if xxxShutdown was being called from another DLL's
  3191. // DllEntryPoint then deadlock occured, because
  3192. // DllEntryPoint's aren't reentrant.)
  3193. //
  3194. if ((gpAsyncEventsThreadParams->hTapi32 = LoadLibrary(
  3195. TEXT("tapi32.dll")
  3196. )))
  3197. {
  3198. //
  3199. // If we're supporting a 16-bit client we want to inc
  3200. // the usage count for wow32 too
  3201. //
  3202. if (ghWow32Dll == NULL ||
  3203. (gpAsyncEventsThreadParams->hWow32 = LoadLibrary(
  3204. TEXT("wow32.dll")
  3205. )))
  3206. {
  3207. //
  3208. // Create the initial buffer the thread will use for
  3209. // retreiving async events
  3210. //
  3211. gpAsyncEventsThreadParams->dwBufSize =
  3212. ASNYC_MSG_BUF_SIZE;
  3213. if ((gpAsyncEventsThreadParams->pBuf = ClientAlloc(
  3214. gpAsyncEventsThreadParams->dwBufSize
  3215. )))
  3216. {
  3217. //
  3218. // Now that we've all the resources try to exec
  3219. // the thread
  3220. //
  3221. if ((hThread = CreateThread(
  3222. NULL,
  3223. 0,
  3224. (LPTHREAD_START_ROUTINE) AsyncEventsThread,
  3225. (LPVOID) gpAsyncEventsThreadParams,
  3226. 0,
  3227. &dwThreadID
  3228. )) != NULL)
  3229. {
  3230. CloseHandle (hThread);
  3231. gdwNumInits++;
  3232. LeaveCriticalSection(&gCriticalSection);
  3233. goto xxxInitialize_releaseMutex;
  3234. }
  3235. ClientFree (gpAsyncEventsThreadParams->pBuf);
  3236. #if DBG
  3237. LOG((TL_ERROR,
  3238. "%hs: CreateThread(AsyncEventsThread) " \
  3239. "failed, err=%d",
  3240. pszFuncName,
  3241. GetLastError()
  3242. ));
  3243. #else
  3244. LOG((TL_ERROR,
  3245. ": CreateThread(AsyncEventsThread) " \
  3246. "failed, err=%d",
  3247. GetLastError()
  3248. ));
  3249. #endif
  3250. }
  3251. if (ghWow32Dll)
  3252. {
  3253. FreeLibrary (gpAsyncEventsThreadParams->hWow32);
  3254. }
  3255. }
  3256. FreeLibrary (gpAsyncEventsThreadParams->hTapi32);
  3257. }
  3258. else
  3259. {
  3260. #if DBG
  3261. LOG((TL_ERROR,
  3262. "%hs: LoadLibrary('tapi32.dll') failed, err=%d",
  3263. pszFuncName,
  3264. GetLastError()
  3265. ));
  3266. #else
  3267. LOG((TL_ERROR,
  3268. ": LoadLibrary('tapi32.dll') failed, err=%d",
  3269. GetLastError()
  3270. ));
  3271. #endif
  3272. }
  3273. ClientFree (gpAsyncEventsThreadParams);
  3274. }
  3275. gpAsyncEventsThreadParams = NULL;
  3276. lResult =
  3277. (bLine ? LINEERR_OPERATIONFAILED : PHONEERR_OPERATIONFAILED);
  3278. }
  3279. else
  3280. {
  3281. gdwNumInits++;
  3282. }
  3283. LeaveCriticalSection(&gCriticalSection);
  3284. }
  3285. if (lResult != 0)
  3286. {
  3287. if (gbNTVDMClient && pInitData)
  3288. {
  3289. pInitData->hwnd = (HWND) NULL;
  3290. }
  3291. FreeInitData (pInitData);
  3292. }
  3293. xxxInitialize_releaseMutex:
  3294. if (bReleaseMutex)
  3295. {
  3296. ReleaseMutex (ghInitMutex);
  3297. }
  3298. if (lResult == 0)
  3299. {
  3300. //
  3301. // Save the hLineApp returned by TAPISRV in our InitData struct,
  3302. // and give the app back a unique handle
  3303. //
  3304. pInitData->hXxxApp = *((LPHLINEAPP) phXxxApp);
  3305. *((LPHLINEAPP) phXxxApp) = pInitData->hInitData;
  3306. }
  3307. xxxInitialize_return:
  3308. //
  3309. // if we failed, we need to release the RPC ref count,
  3310. // nobody will call lineShutdown
  3311. //
  3312. if (bResAllocated &&
  3313. lResult !=0)
  3314. {
  3315. FreeClientResources();
  3316. }
  3317. #if DBG
  3318. {
  3319. char szResult[32];
  3320. LOG((TL_TRACE,
  3321. "%hs: exit, result=%hs",
  3322. pszFuncName,
  3323. MapResultCodeToText (lResult, szResult)
  3324. ));
  3325. }
  3326. #else
  3327. LOG((TL_TRACE,
  3328. ": exit, result=x%x",
  3329. lResult
  3330. ));
  3331. #endif
  3332. return lResult;
  3333. }
  3334. //
  3335. // --------------------------------- lineXxx ----------------------------------
  3336. //
  3337. LONG
  3338. WINAPI
  3339. lineAccept(
  3340. HCALL hCall,
  3341. LPCSTR lpsUserUserInfo,
  3342. DWORD dwSize
  3343. )
  3344. {
  3345. FUNC_ARGS funcArgs =
  3346. {
  3347. MAKELONG (LINE_FUNC | ASYNC | 3, lAccept),
  3348. {
  3349. (ULONG_PTR) hCall,
  3350. (ULONG_PTR) lpsUserUserInfo,
  3351. dwSize
  3352. },
  3353. {
  3354. Dword,
  3355. lpSet_SizeToFollow,
  3356. Size
  3357. }
  3358. };
  3359. if (!lpsUserUserInfo)
  3360. {
  3361. //
  3362. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  3363. //
  3364. funcArgs.ArgTypes[1] = Dword;
  3365. funcArgs.Args[1] = TAPI_NO_DATA;
  3366. funcArgs.ArgTypes[2] = Dword;
  3367. }
  3368. return (DOFUNC (&funcArgs, "lineAccept"));
  3369. }
  3370. LONG
  3371. WINAPI
  3372. lineAddProviderA(
  3373. LPCSTR lpszProviderFilename,
  3374. HWND hwndOwner,
  3375. LPDWORD lpdwPermanentProviderID
  3376. )
  3377. {
  3378. LONG lResult;
  3379. LOG((TL_TRACE, "lineAddProviderA: enter"));
  3380. LOG((TL_INFO, " lpszProviderFilename=0x%p", lpszProviderFilename));
  3381. #if DBG
  3382. if (!IsBadStringPtrA(lpszProviderFilename, (UINT)-1) )
  3383. {
  3384. LOG((TL_INFO, " *lpszProviderFilename=[%hs]", lpszProviderFilename));
  3385. }
  3386. #endif
  3387. LOG((TL_INFO, " hwndOwner=0x%p", hwndOwner));
  3388. LOG((TL_INFO, " lpdwPermanentProviderID=0x%p", lpdwPermanentProviderID));
  3389. if ( IsBadStringPtrA(lpszProviderFilename, (UINT)-1) )
  3390. {
  3391. LOG((TL_ERROR, "Bad lpszProviderFilename (0x%p)", lpszProviderFilename));
  3392. return LINEERR_INVALPOINTER;
  3393. }
  3394. lResult = lineXxxProvider(
  3395. gszTUISPI_providerInstall, // funcName
  3396. lpszProviderFilename, // lpszProviderFilename
  3397. hwndOwner, // hwndOwner
  3398. 0, // dwPermProviderID
  3399. lpdwPermanentProviderID // lpdwPermProviderID
  3400. );
  3401. #if DBG
  3402. {
  3403. char szResult[32];
  3404. LOG((TL_TRACE,
  3405. "lineAddProvider: result = %hs",
  3406. MapResultCodeToText (lResult, szResult)
  3407. ));
  3408. }
  3409. #else
  3410. LOG((TL_TRACE,
  3411. "lineAddProvider: result = x%x",
  3412. lResult
  3413. ));
  3414. #endif
  3415. return lResult;
  3416. }
  3417. LONG
  3418. WINAPI
  3419. lineAddProviderW(
  3420. LPCWSTR lpszProviderFilename,
  3421. HWND hwndOwner,
  3422. LPDWORD lpdwPermanentProviderID
  3423. )
  3424. {
  3425. LONG lResult;
  3426. LPBYTE pszTempPtr;
  3427. DWORD dwSize;
  3428. LOG((TL_TRACE, "Entering lineAddProvider"));
  3429. LOG((TL_INFO, " lpszProviderFilename=0x%p", lpszProviderFilename));
  3430. if ( TAPIIsBadStringPtrW(lpszProviderFilename, (UINT)-1) )
  3431. {
  3432. LOG((TL_ERROR,
  3433. "Bad lpszProviderFilename [0x%p] passed to lineAddProviderW",
  3434. lpszProviderFilename
  3435. ));
  3436. return( LINEERR_INVALPOINTER );
  3437. }
  3438. LOG((TL_INFO, " *lpszProviderFilename=[%ls]", lpszProviderFilename));
  3439. LOG((TL_INFO, " hwndOwner=0x%p", hwndOwner));
  3440. LOG((TL_INFO, " lpdwPermanentProviderID=0x%p", lpdwPermanentProviderID));
  3441. dwSize = lstrlenW(lpszProviderFilename) + 1;
  3442. pszTempPtr = ClientAlloc(dwSize * sizeof (WCHAR));
  3443. if (NULL == pszTempPtr)
  3444. {
  3445. return LINEERR_NOMEM;
  3446. }
  3447. // can't use this because this is for strings
  3448. // embedded in structures.
  3449. // WideStringToNotSoWideString (pszTempPtr, &dwSize);
  3450. WideCharToMultiByte(
  3451. GetACP(),
  3452. 0,
  3453. lpszProviderFilename,
  3454. -1,
  3455. pszTempPtr,
  3456. dwSize * sizeof(WCHAR),
  3457. NULL,
  3458. NULL
  3459. );
  3460. lResult = lineAddProviderA(
  3461. (LPCSTR) pszTempPtr,
  3462. hwndOwner,
  3463. lpdwPermanentProviderID
  3464. );
  3465. ClientFree(pszTempPtr);
  3466. return lResult;
  3467. }
  3468. LONG
  3469. WINAPI
  3470. lineAddProvider(
  3471. LPCSTR lpszProviderFilename,
  3472. HWND hwndOwner,
  3473. LPDWORD lpdwPermanentProviderID
  3474. )
  3475. {
  3476. return lineAddProviderA(
  3477. lpszProviderFilename,
  3478. hwndOwner,
  3479. lpdwPermanentProviderID
  3480. );
  3481. }
  3482. LONG
  3483. WINAPI
  3484. lineAddToConference(
  3485. HCALL hConfCall,
  3486. HCALL hConsultCall
  3487. )
  3488. {
  3489. FUNC_ARGS funcArgs =
  3490. {
  3491. MAKELONG (LINE_FUNC | ASYNC | 2, lAddToConference),
  3492. {
  3493. (ULONG_PTR) hConfCall ,
  3494. (ULONG_PTR) hConsultCall
  3495. },
  3496. {
  3497. Dword,
  3498. Dword
  3499. }
  3500. };
  3501. return (DOFUNC (&funcArgs, "lineAddToConference"));
  3502. }
  3503. LONG
  3504. WINAPI
  3505. lineAgentSpecific(
  3506. HLINE hLine,
  3507. DWORD dwAddressID,
  3508. DWORD dwAgentExtensionIDIndex,
  3509. LPVOID lpParams,
  3510. DWORD dwSize
  3511. )
  3512. {
  3513. FUNC_ARGS funcArgs =
  3514. {
  3515. MAKELONG (LINE_FUNC | ASYNC | 7, lAgentSpecific),
  3516. {
  3517. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  3518. (ULONG_PTR) hLine,
  3519. (ULONG_PTR) dwAddressID,
  3520. (ULONG_PTR) dwAgentExtensionIDIndex,
  3521. (ULONG_PTR) lpParams,
  3522. (ULONG_PTR) lpParams,
  3523. (ULONG_PTR) dwSize
  3524. },
  3525. {
  3526. Dword,
  3527. Dword,
  3528. Dword,
  3529. Dword,
  3530. Dword,
  3531. lpSet_SizeToFollow,
  3532. Size
  3533. }
  3534. };
  3535. DWORD hPointer = 0;
  3536. LONG lResult;
  3537. if ( !hLine )
  3538. {
  3539. return LINEERR_INVALLINEHANDLE;
  3540. }
  3541. if ( !lpParams )
  3542. {
  3543. return LINEERR_INVALPOINTER;
  3544. }
  3545. // Since we're passing lpParams twice, once a handle to it
  3546. // and another time unchanged, we rely on DoFunc to test it.
  3547. hPointer = NewObject (ghHandleTable, (PVOID)lpParams, NULL);
  3548. if (0 == hPointer)
  3549. {
  3550. return LINEERR_NOMEM;
  3551. }
  3552. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  3553. if (0 > (lResult = DOFUNC (&funcArgs, "lineAgentSpecific")))
  3554. {
  3555. // There was an error, free the handle...
  3556. DereferenceObject (ghHandleTable, hPointer, 1);
  3557. }
  3558. return lResult;
  3559. }
  3560. LONG
  3561. WINAPI
  3562. lineAnswer(
  3563. HCALL hCall,
  3564. LPCSTR lpsUserUserInfo,
  3565. DWORD dwSize
  3566. )
  3567. {
  3568. FUNC_ARGS funcArgs =
  3569. {
  3570. MAKELONG (LINE_FUNC | ASYNC | 3, lAnswer),
  3571. {
  3572. (ULONG_PTR) hCall,
  3573. (ULONG_PTR) lpsUserUserInfo,
  3574. dwSize
  3575. },
  3576. {
  3577. Dword,
  3578. lpSet_SizeToFollow,
  3579. Size
  3580. }
  3581. };
  3582. if (!lpsUserUserInfo)
  3583. {
  3584. //
  3585. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  3586. //
  3587. funcArgs.ArgTypes[1] = Dword;
  3588. funcArgs.Args[1] = TAPI_NO_DATA;
  3589. funcArgs.ArgTypes[2] = Dword;
  3590. }
  3591. return (DOFUNC (&funcArgs, "lineAnswer"));
  3592. }
  3593. LONG
  3594. WINAPI
  3595. lineBlindTransferW(
  3596. HCALL hCall,
  3597. LPCWSTR lpszDestAddress,
  3598. DWORD dwCountryCode
  3599. )
  3600. {
  3601. FUNC_ARGS funcArgs =
  3602. {
  3603. MAKELONG (LINE_FUNC | ASYNC | 3, lBlindTransfer),
  3604. {
  3605. (ULONG_PTR) hCall,
  3606. (ULONG_PTR) lpszDestAddress,
  3607. dwCountryCode
  3608. },
  3609. {
  3610. Dword,
  3611. lpszW,
  3612. Dword
  3613. }
  3614. };
  3615. if ( TAPIIsBadStringPtrW( lpszDestAddress, (UINT)-1 ) )
  3616. {
  3617. LOG((TL_ERROR,
  3618. "lineBlindTransferW: bad lpszDestAddress: 0x%p",
  3619. lpszDestAddress
  3620. ));
  3621. return(LINEERR_INVALPOINTER);
  3622. }
  3623. return (DOFUNC (&funcArgs, "lineBlindTransfer"));
  3624. }
  3625. LONG
  3626. WINAPI
  3627. lineBlindTransferA(
  3628. HCALL hCall,
  3629. LPCSTR lpszDestAddress,
  3630. DWORD dwCountryCode
  3631. )
  3632. {
  3633. LONG lResult;
  3634. PWSTR szTempPtr;
  3635. if ( IsBadStringPtrA( lpszDestAddress, (UINT)-1 ) )
  3636. {
  3637. LOG((TL_ERROR,
  3638. "lineBlindTransferA: bad lpszDestAddress: 0x%08lx",
  3639. lpszDestAddress
  3640. ));
  3641. return(LINEERR_INVALPOINTER);
  3642. }
  3643. szTempPtr = NotSoWideStringToWideString (lpszDestAddress, (DWORD) -1);
  3644. if ( !szTempPtr )
  3645. {
  3646. LOG((TL_ERROR,
  3647. "lineBlindTransferA: NotSoWideStringToWideString returned NULL"
  3648. ));
  3649. return(LINEERR_INVALPOINTER);
  3650. }
  3651. lResult = lineBlindTransferW (hCall, szTempPtr, dwCountryCode);
  3652. if (szTempPtr)
  3653. {
  3654. ClientFree (szTempPtr);
  3655. }
  3656. return lResult;
  3657. }
  3658. LONG
  3659. WINAPI
  3660. lineBlindTransfer(
  3661. HCALL hCall,
  3662. LPCSTR lpszDestAddress,
  3663. DWORD dwCountryCode
  3664. )
  3665. {
  3666. return lineBlindTransferA(
  3667. hCall,
  3668. lpszDestAddress,
  3669. dwCountryCode
  3670. );
  3671. }
  3672. LONG
  3673. WINAPI
  3674. lineClose(
  3675. HLINE hLine
  3676. )
  3677. {
  3678. LONG lResult;
  3679. DWORD Handle = 0;
  3680. FUNC_ARGS funcArgs =
  3681. {
  3682. MAKELONG (LINE_FUNC | SYNC | 2, lClose),
  3683. {
  3684. (ULONG_PTR) hLine,
  3685. (ULONG_PTR) &Handle
  3686. },
  3687. {
  3688. Dword,
  3689. lpDword
  3690. }
  3691. };
  3692. lResult = DOFUNC (&funcArgs, "lineClose");
  3693. if (0 == lResult &&
  3694. 0 != Handle)
  3695. {
  3696. DereferenceObject (ghHandleTable, Handle, 1);
  3697. }
  3698. return lResult;
  3699. }
  3700. void
  3701. PASCAL
  3702. lineCompleteCallPostProcess(
  3703. PASYNCEVENTMSG pMsg
  3704. )
  3705. {
  3706. LOG((TL_TRACE, "lineCompleteCallPostProcess: enter"));
  3707. LOG((TL_INFO,
  3708. "\t\tdwP1=x%lx, dwP2=x%lx, dwP3=x%lx, dwP4=x%lx",
  3709. pMsg->Param1,
  3710. pMsg->Param2,
  3711. pMsg->Param3,
  3712. pMsg->Param4
  3713. ));
  3714. if (pMsg->Param2 == 0)
  3715. {
  3716. DWORD dwCompletionID = (DWORD) pMsg->Param3;
  3717. LPDWORD lpdwCompletionID = (LPDWORD) ReferenceObject (ghHandleTable, pMsg->Param4, 0);
  3718. // We don't need the handle to the pointer any more...
  3719. DereferenceObject (ghHandleTable, pMsg->Param4, 2);
  3720. try
  3721. {
  3722. if (gbNTVDMClient)
  3723. {
  3724. #ifndef _WIN64
  3725. LPDWORD lpdwCompletionIDVDM = (LPDWORD) gpfnWOWGetVDMPointer (
  3726. (DWORD) lpdwCompletionID,
  3727. sizeof(DWORD),
  3728. TRUE // fProtectedMode
  3729. );
  3730. if (lpdwCompletionIDVDM)
  3731. {
  3732. *lpdwCompletionIDVDM = dwCompletionID;
  3733. }
  3734. else
  3735. {
  3736. pMsg->Param2 = LINEERR_INVALPOINTER;
  3737. }
  3738. #endif
  3739. }
  3740. else
  3741. {
  3742. *lpdwCompletionID = dwCompletionID;
  3743. }
  3744. }
  3745. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  3746. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  3747. {
  3748. pMsg->Param2 = LINEERR_INVALPOINTER;
  3749. }
  3750. }
  3751. }
  3752. LONG
  3753. WINAPI
  3754. lineCompleteCall(
  3755. HCALL hCall,
  3756. LPDWORD lpdwCompletionID,
  3757. DWORD dwCompletionMode,
  3758. DWORD dwMessageID
  3759. )
  3760. {
  3761. FUNC_ARGS funcArgs =
  3762. {
  3763. MAKELONG (LINE_FUNC | ASYNC | 5, lCompleteCall),
  3764. {
  3765. (ULONG_PTR) GetFunctionIndex(lineCompleteCallPostProcess),
  3766. (ULONG_PTR) hCall,
  3767. (ULONG_PTR) lpdwCompletionID,
  3768. (ULONG_PTR) dwCompletionMode,
  3769. (ULONG_PTR) dwMessageID
  3770. },
  3771. {
  3772. Dword,
  3773. Dword,
  3774. Dword,
  3775. Dword,
  3776. Dword
  3777. }
  3778. };
  3779. DWORD hPointer = 0;
  3780. LONG lResult;
  3781. if (!gbNTVDMClient)
  3782. {
  3783. if (IsBadDwordPtr (lpdwCompletionID))
  3784. {
  3785. return LINEERR_INVALPOINTER;
  3786. }
  3787. hPointer = NewObject (ghHandleTable, (PVOID)lpdwCompletionID, NULL);
  3788. if (0 == hPointer)
  3789. {
  3790. return LINEERR_NOMEM;
  3791. }
  3792. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  3793. }
  3794. lResult = DOFUNC (&funcArgs, "lineCompleteCall");
  3795. if (hPointer && 0 > lResult)
  3796. {
  3797. DereferenceObject (ghHandleTable, hPointer, 1);
  3798. }
  3799. return lResult;
  3800. }
  3801. LONG
  3802. WINAPI
  3803. lineCompleteTransfer(
  3804. HCALL hCall,
  3805. HCALL hConsultCall,
  3806. LPHCALL lphConfCall,
  3807. DWORD dwTransferMode
  3808. )
  3809. {
  3810. FUNC_ARGS funcArgs =
  3811. {
  3812. MAKELONG (LINE_FUNC | ASYNC | 5, lCompleteTransfer),
  3813. {
  3814. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  3815. (ULONG_PTR) hCall,
  3816. (ULONG_PTR) hConsultCall,
  3817. (ULONG_PTR) lphConfCall,
  3818. (ULONG_PTR) dwTransferMode,
  3819. },
  3820. {
  3821. Dword,
  3822. Dword,
  3823. Dword,
  3824. Dword,
  3825. Dword,
  3826. }
  3827. };
  3828. DWORD hPointer = 0;
  3829. LONG lResult;
  3830. if (dwTransferMode == LINETRANSFERMODE_TRANSFER)
  3831. {
  3832. //
  3833. // lphCall should be ignored
  3834. //
  3835. funcArgs.Args[0] = 0; // (POSTPROCESSPROC) NULL;
  3836. }
  3837. else if (!gbNTVDMClient)
  3838. {
  3839. if (IsBadDwordPtr (lphConfCall))
  3840. {
  3841. return LINEERR_INVALPOINTER;
  3842. }
  3843. hPointer = NewObject (ghHandleTable, (PVOID)lphConfCall, NULL);
  3844. if (0 == hPointer)
  3845. {
  3846. return LINEERR_NOMEM;
  3847. }
  3848. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  3849. }
  3850. lResult = DOFUNC (&funcArgs, "lineCompleteTransfer");
  3851. if (hPointer && 0 > lResult)
  3852. {
  3853. DereferenceObject (ghHandleTable, hPointer, 1);
  3854. }
  3855. return lResult;
  3856. }
  3857. LONG
  3858. WINAPI
  3859. lineConfigDialogW(
  3860. DWORD dwDeviceID,
  3861. HWND hwndOwner,
  3862. LPCWSTR lpszDeviceClass
  3863. )
  3864. {
  3865. LONG lResult;
  3866. HANDLE hDll;
  3867. TUISPIPROC pfnTUISPI_lineConfigDialog;
  3868. if (lpszDeviceClass && TAPIIsBadStringPtrW (lpszDeviceClass, 256))
  3869. {
  3870. return LINEERR_INVALPOINTER;
  3871. }
  3872. if ((lResult = LoadUIDll(
  3873. hwndOwner,
  3874. dwDeviceID,
  3875. TUISPIDLL_OBJECT_LINEID,
  3876. &hDll,
  3877. gszTUISPI_lineConfigDialog,
  3878. &pfnTUISPI_lineConfigDialog
  3879. )) == 0)
  3880. {
  3881. LOG((TL_TRACE, "Calling TUISPI_lineConfigDialog..."));
  3882. lResult = (*pfnTUISPI_lineConfigDialog)(
  3883. TUISPIDLLCallback,
  3884. dwDeviceID,
  3885. hwndOwner,
  3886. lpszDeviceClass
  3887. );
  3888. #if DBG
  3889. {
  3890. char szResult[32];
  3891. LOG((TL_TRACE,
  3892. "TUISPI_lineConfigDialog: result = %hs",
  3893. MapResultCodeToText (lResult, szResult)
  3894. ));
  3895. }
  3896. #else
  3897. LOG((TL_TRACE,
  3898. "TUISPI_lineConfigDialog: result = x%x",
  3899. lResult
  3900. ));
  3901. #endif
  3902. FreeLibrary (hDll);
  3903. }
  3904. return lResult;
  3905. }
  3906. LONG
  3907. WINAPI
  3908. lineConfigDialogA(
  3909. DWORD dwDeviceID,
  3910. HWND hwndOwner,
  3911. LPCSTR lpszDeviceClass
  3912. )
  3913. {
  3914. PWSTR szTempString = NULL;
  3915. LONG lResult;
  3916. if (lpszDeviceClass && IsBadStringPtrA (lpszDeviceClass, (DWORD) -1))
  3917. {
  3918. return LINEERR_INVALPOINTER;
  3919. }
  3920. szTempString = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  3921. lResult = lineConfigDialogW (dwDeviceID, hwndOwner, szTempString);
  3922. if (szTempString)
  3923. {
  3924. ClientFree (szTempString);
  3925. }
  3926. return lResult;
  3927. }
  3928. LONG
  3929. WINAPI
  3930. lineConfigDialog(
  3931. DWORD dwDeviceID,
  3932. HWND hwndOwner,
  3933. LPCSTR lpszDeviceClass
  3934. )
  3935. {
  3936. return lineConfigDialogA(
  3937. dwDeviceID,
  3938. hwndOwner,
  3939. lpszDeviceClass
  3940. );
  3941. }
  3942. LONG
  3943. WINAPI
  3944. lineConfigDialogEditW(
  3945. DWORD dwDeviceID,
  3946. HWND hwndOwner,
  3947. LPCWSTR lpszDeviceClass,
  3948. LPVOID const lpDeviceConfigIn,
  3949. DWORD dwSize,
  3950. LPVARSTRING lpDeviceConfigOut
  3951. )
  3952. {
  3953. LONG lResult;
  3954. HANDLE hDll;
  3955. TUISPIPROC pfnTUISPI_lineConfigDialogEdit;
  3956. if (lpszDeviceClass && TAPIIsBadStringPtrW (lpszDeviceClass, (UINT) -1))
  3957. {
  3958. return LINEERR_INVALPOINTER;
  3959. }
  3960. if (IsBadReadPtr (lpDeviceConfigIn, dwSize))
  3961. {
  3962. return LINEERR_INVALPOINTER;
  3963. }
  3964. if (IsBadWritePtr (lpDeviceConfigOut, sizeof (VARSTRING)))
  3965. {
  3966. return LINEERR_INVALPOINTER;
  3967. }
  3968. if (lpDeviceConfigOut->dwTotalSize < sizeof (VARSTRING))
  3969. {
  3970. return LINEERR_STRUCTURETOOSMALL;
  3971. }
  3972. if (IsBadWritePtr (lpDeviceConfigOut, lpDeviceConfigOut->dwTotalSize))
  3973. {
  3974. return LINEERR_INVALPOINTER;
  3975. }
  3976. if ((lResult = LoadUIDll(
  3977. hwndOwner,
  3978. dwDeviceID,
  3979. TUISPIDLL_OBJECT_LINEID,
  3980. &hDll,
  3981. gszTUISPI_lineConfigDialogEdit,
  3982. &pfnTUISPI_lineConfigDialogEdit
  3983. )) == 0)
  3984. {
  3985. LOG((TL_TRACE, "Calling TUISPI_lineConfigDialogEdit..."));
  3986. lResult = (*pfnTUISPI_lineConfigDialogEdit)(
  3987. TUISPIDLLCallback,
  3988. dwDeviceID,
  3989. hwndOwner,
  3990. lpszDeviceClass,
  3991. lpDeviceConfigIn,
  3992. dwSize,
  3993. lpDeviceConfigOut
  3994. );
  3995. #if DBG
  3996. {
  3997. char szResult[32];
  3998. LOG((TL_TRACE,
  3999. "TUISPI_lineConfigDialogEdit: result = %hs",
  4000. MapResultCodeToText (lResult, szResult)
  4001. ));
  4002. }
  4003. #else
  4004. LOG((TL_TRACE,
  4005. "TUISPI_lineConfigDialogEdit: result = x%x",
  4006. lResult
  4007. ));
  4008. #endif
  4009. FreeLibrary (hDll);
  4010. }
  4011. return lResult;
  4012. }
  4013. LONG
  4014. WINAPI
  4015. lineConfigDialogEditA(
  4016. DWORD dwDeviceID,
  4017. HWND hwndOwner,
  4018. LPCSTR lpszDeviceClass,
  4019. LPVOID const lpDeviceConfigIn,
  4020. DWORD dwSize,
  4021. LPVARSTRING lpDeviceConfigOut
  4022. )
  4023. {
  4024. PWSTR szTempString;
  4025. LONG lResult;
  4026. if (lpszDeviceClass && IsBadStringPtrA (lpszDeviceClass, (DWORD) -1))
  4027. {
  4028. return LINEERR_INVALPOINTER;
  4029. }
  4030. szTempString = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  4031. lResult = lineConfigDialogEditW(
  4032. dwDeviceID,
  4033. hwndOwner,
  4034. szTempString,
  4035. lpDeviceConfigIn,
  4036. dwSize,
  4037. lpDeviceConfigOut
  4038. );
  4039. if (szTempString)
  4040. {
  4041. ClientFree (szTempString);
  4042. }
  4043. return lResult;
  4044. }
  4045. LONG
  4046. WINAPI
  4047. lineConfigDialogEdit(
  4048. DWORD dwDeviceID,
  4049. HWND hwndOwner,
  4050. LPCSTR lpszDeviceClass,
  4051. LPVOID const lpDeviceConfigIn,
  4052. DWORD dwSize,
  4053. LPVARSTRING lpDeviceConfigOut
  4054. )
  4055. {
  4056. return lineConfigDialogEditA(
  4057. dwDeviceID,
  4058. hwndOwner,
  4059. lpszDeviceClass,
  4060. lpDeviceConfigIn,
  4061. dwSize,
  4062. lpDeviceConfigOut
  4063. );
  4064. }
  4065. LONG
  4066. WINAPI
  4067. lineConfigProvider(
  4068. HWND hwndOwner,
  4069. DWORD dwPermanentProviderID
  4070. )
  4071. {
  4072. return (lineXxxProvider(
  4073. gszTUISPI_providerConfig, // func name
  4074. NULL, // lpszProviderFilename
  4075. hwndOwner, // hwndOwner
  4076. dwPermanentProviderID, // dwPermProviderID
  4077. NULL // lpdwPermProviderID
  4078. ));
  4079. }
  4080. LONG
  4081. WINAPI
  4082. lineCreateAgentW(
  4083. HLINE hLine,
  4084. LPWSTR lpszAgentID,
  4085. LPWSTR lpszAgentPIN,
  4086. LPHAGENT lphAgent
  4087. )
  4088. {
  4089. DWORD hPointer = 0;
  4090. LONG lResult;
  4091. FUNC_ARGS funcArgs =
  4092. {
  4093. MAKELONG (LINE_FUNC | ASYNC | 5, lCreateAgent),
  4094. {
  4095. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  4096. (ULONG_PTR) hLine,
  4097. (ULONG_PTR) lpszAgentID,
  4098. (ULONG_PTR) lpszAgentPIN,
  4099. (ULONG_PTR) lphAgent
  4100. },
  4101. {
  4102. Dword,
  4103. Dword,
  4104. lpszAgentID?lpszW:Dword,
  4105. lpszAgentPIN?lpszW:Dword,
  4106. Dword,
  4107. }
  4108. };
  4109. if ( NULL == lpszAgentID )
  4110. {
  4111. funcArgs.Args[2] = TAPI_NO_DATA;
  4112. funcArgs.ArgTypes[2] = Dword;
  4113. }
  4114. else if ( TAPIIsBadStringPtrW(lpszAgentID, (UINT)-1) )
  4115. {
  4116. LOG((TL_ERROR, "Bad lpszAgentID in lineCreateAgentW"));
  4117. return( LINEERR_INVALPOINTER );
  4118. }
  4119. if ( NULL == lpszAgentPIN )
  4120. {
  4121. funcArgs.Args[3] = TAPI_NO_DATA;
  4122. funcArgs.ArgTypes[3] = Dword;
  4123. }
  4124. else if ( TAPIIsBadStringPtrW(lpszAgentPIN, (UINT)-1) )
  4125. {
  4126. LOG((TL_ERROR, "Bad lpszAgentPIN in lineCreateAgentW"));
  4127. return( LINEERR_INVALPOINTER );
  4128. }
  4129. if (IsBadDwordPtr (lphAgent))
  4130. {
  4131. return LINEERR_INVALPOINTER;
  4132. }
  4133. hPointer = NewObject (ghHandleTable, (PVOID)lphAgent, NULL);
  4134. if (0 == hPointer)
  4135. {
  4136. return LINEERR_NOMEM;
  4137. }
  4138. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  4139. lResult = DOFUNC (&funcArgs, "lineCreateAgentW");
  4140. if (0 > lResult)
  4141. {
  4142. DereferenceObject (ghHandleTable, hPointer, 1);
  4143. }
  4144. return lResult;
  4145. }
  4146. LONG
  4147. WINAPI
  4148. lineCreateAgentA(
  4149. HLINE hLine,
  4150. LPSTR lpszAgentID,
  4151. LPSTR lpszAgentPIN,
  4152. LPHAGENT lphAgent
  4153. )
  4154. {
  4155. PWSTR pwAgentID;
  4156. PWSTR pwAgentPIN;
  4157. LONG lResult;
  4158. if (lpszAgentID)
  4159. {
  4160. if ( IsBadStringPtrA(lpszAgentID, (UINT)-1) )
  4161. {
  4162. LOG((TL_ERROR, "Bad lpszAgentID in lineCreateAgentA"));
  4163. return( LINEERR_INVALPOINTER );
  4164. }
  4165. pwAgentID = NotSoWideStringToWideString (lpszAgentID, (DWORD) -1);
  4166. }
  4167. else
  4168. {
  4169. pwAgentID = NULL;
  4170. }
  4171. if (lpszAgentPIN)
  4172. {
  4173. if ( IsBadStringPtrA(lpszAgentPIN, (UINT)-1) )
  4174. {
  4175. LOG((TL_ERROR, "Bad lpszAgentPIN in lineCreateAgentA"));
  4176. return( LINEERR_INVALPOINTER );
  4177. }
  4178. pwAgentPIN = NotSoWideStringToWideString (lpszAgentPIN, (DWORD) -1);
  4179. }
  4180. else
  4181. {
  4182. pwAgentPIN = NULL;
  4183. }
  4184. lResult = lineCreateAgentW (hLine, pwAgentID, pwAgentPIN, lphAgent);
  4185. if (pwAgentPIN)
  4186. {
  4187. ClientFree (pwAgentPIN);
  4188. }
  4189. if (pwAgentID)
  4190. {
  4191. ClientFree (pwAgentID);
  4192. }
  4193. return lResult;
  4194. }
  4195. LONG
  4196. WINAPI
  4197. lineCreateAgentSessionW(
  4198. HLINE hLine,
  4199. HAGENT hAgent,
  4200. LPWSTR lpszAgentPIN,
  4201. DWORD dwWorkingAddressID,
  4202. LPGUID lpGroupID,
  4203. LPHAGENTSESSION lphAgentSession
  4204. )
  4205. {
  4206. FUNC_ARGS funcArgs =
  4207. {
  4208. MAKELONG (LINE_FUNC | ASYNC | 8, lCreateAgentSession),
  4209. {
  4210. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  4211. (ULONG_PTR) hLine,
  4212. (ULONG_PTR) hAgent,
  4213. (ULONG_PTR) lpszAgentPIN,
  4214. (ULONG_PTR) dwWorkingAddressID,
  4215. (ULONG_PTR) lpGroupID,
  4216. (ULONG_PTR) sizeof( GUID ),
  4217. (ULONG_PTR) lphAgentSession
  4218. },
  4219. {
  4220. Dword,
  4221. Dword,
  4222. Dword,
  4223. lpszAgentPIN?lpszW:Dword,
  4224. Dword,
  4225. lpSet_SizeToFollow,
  4226. Size,
  4227. Dword,
  4228. }
  4229. };
  4230. DWORD hPointer = 0;
  4231. LONG lResult;
  4232. if ( NULL == lpszAgentPIN )
  4233. {
  4234. funcArgs.Args[3] = TAPI_NO_DATA;
  4235. funcArgs.ArgTypes[3] = Dword;
  4236. }
  4237. else if ( TAPIIsBadStringPtrW(lpszAgentPIN, (UINT)-1) )
  4238. {
  4239. LOG((TL_ERROR, "Bad lpszAgentPIN in lineCreateAgentSessionW"));
  4240. return( LINEERR_INVALPOINTER );
  4241. }
  4242. if (IsBadDwordPtr (lphAgentSession))
  4243. {
  4244. return LINEERR_INVALPOINTER;
  4245. }
  4246. hPointer = NewObject (ghHandleTable, (PVOID)lphAgentSession, NULL);
  4247. if (0 == hPointer)
  4248. {
  4249. return LINEERR_NOMEM;
  4250. }
  4251. funcArgs.Args[7] = (ULONG_PTR)hPointer;
  4252. lResult = DOFUNC (&funcArgs, "lineCreateAgentSessionW");
  4253. if (0 > lResult)
  4254. {
  4255. DereferenceObject (ghHandleTable, hPointer, 1);
  4256. }
  4257. return lResult;
  4258. }
  4259. LONG
  4260. WINAPI
  4261. lineCreateAgentSessionA(
  4262. HLINE hLine,
  4263. HAGENT hAgent,
  4264. LPSTR lpszAgentPIN,
  4265. DWORD dwWorkingAddressID,
  4266. LPGUID lpGroupID,
  4267. LPHAGENTSESSION lphAgentSession
  4268. )
  4269. {
  4270. LONG lResult;
  4271. PWSTR pwAgentPIN;
  4272. if (lpszAgentPIN)
  4273. {
  4274. if ( IsBadStringPtrA(lpszAgentPIN, (UINT)-1) )
  4275. {
  4276. LOG((TL_ERROR, "Bad lpszAgentPIN in lineCreateAgentSessionA"));
  4277. return( LINEERR_INVALPOINTER );
  4278. }
  4279. pwAgentPIN = NotSoWideStringToWideString (lpszAgentPIN, (DWORD) -1);
  4280. }
  4281. else
  4282. {
  4283. pwAgentPIN = NULL;
  4284. }
  4285. lResult = lineCreateAgentSessionW(
  4286. hLine,
  4287. hAgent,
  4288. pwAgentPIN,
  4289. dwWorkingAddressID,
  4290. lpGroupID,
  4291. lphAgentSession
  4292. );
  4293. if (pwAgentPIN)
  4294. {
  4295. ClientFree (pwAgentPIN);
  4296. }
  4297. return lResult;
  4298. }
  4299. LONG
  4300. WINAPI
  4301. lineDeallocateCall(
  4302. HCALL hCall
  4303. )
  4304. {
  4305. FUNC_ARGS funcArgs =
  4306. {
  4307. MAKELONG (LINE_FUNC | SYNC | 1, lDeallocateCall),
  4308. {
  4309. (ULONG_PTR) hCall
  4310. },
  4311. {
  4312. Dword
  4313. }
  4314. };
  4315. LOG((TL_TRACE,
  4316. "lineDeallocateCall: enter on thread: 0x%08lx",
  4317. GetCurrentThreadId()
  4318. ));
  4319. LOG((TL_INFO, " hCall = 0x%08lx", hCall));
  4320. return (DOFUNC (&funcArgs, "lineDeallocateCall"));
  4321. }
  4322. void
  4323. PASCAL
  4324. lineDevSpecificPostProcess(
  4325. PASYNCEVENTMSG pMsg
  4326. )
  4327. {
  4328. LOG((TL_TRACE, "lineDevSpecificPostProcess: enter"));
  4329. LOG((TL_INFO,
  4330. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  4331. pMsg->Param1,
  4332. pMsg->Param2,
  4333. pMsg->Param3,
  4334. pMsg->Param4
  4335. ));
  4336. if (pMsg->Param2 == 0)
  4337. {
  4338. DWORD dwSize = (DWORD) pMsg->Param4;
  4339. if (dwSize != 0)
  4340. {
  4341. LPBYTE pParams = (LPBYTE) ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  4342. // We don't need the handle to the pointer any more...
  4343. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  4344. try
  4345. {
  4346. if (gbNTVDMClient)
  4347. {
  4348. #ifndef _WIN64
  4349. LPBYTE pParamsVDM = (LPBYTE) gpfnWOWGetVDMPointer(
  4350. (DWORD) pParams,
  4351. dwSize,
  4352. TRUE // fProtectedMode
  4353. );
  4354. if (pParamsVDM)
  4355. {
  4356. CopyMemory (pParamsVDM, (LPBYTE) (pMsg + 1), dwSize);
  4357. }
  4358. else
  4359. {
  4360. pMsg->Param2 = LINEERR_INVALPOINTER;
  4361. }
  4362. #endif
  4363. }
  4364. else
  4365. {
  4366. CopyMemory (pParams, (LPBYTE) (pMsg + 1), dwSize);
  4367. }
  4368. }
  4369. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  4370. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  4371. {
  4372. pMsg->Param2 = LINEERR_INVALPOINTER;
  4373. }
  4374. }
  4375. }
  4376. }
  4377. LONG
  4378. WINAPI
  4379. lineDevSpecific(
  4380. HLINE hLine,
  4381. DWORD dwAddressID,
  4382. HCALL hCall,
  4383. LPVOID lpParams,
  4384. DWORD dwSize
  4385. )
  4386. {
  4387. FUNC_ARGS funcArgs =
  4388. {
  4389. MAKELONG (LINE_FUNC | ASYNC | 7, lDevSpecific),
  4390. {
  4391. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  4392. (ULONG_PTR) hLine,
  4393. (ULONG_PTR) dwAddressID,
  4394. (ULONG_PTR) hCall,
  4395. (ULONG_PTR) lpParams, // pass the actual pointer (for post proc'g)
  4396. (ULONG_PTR) lpParams, // pass data
  4397. (ULONG_PTR) dwSize
  4398. },
  4399. {
  4400. Dword,
  4401. Dword,
  4402. Dword,
  4403. Dword,
  4404. Dword,
  4405. lpSet_SizeToFollow,
  4406. Size,
  4407. }
  4408. };
  4409. DWORD hPointer = 0;
  4410. LONG lResult;
  4411. if (gbNTVDMClient)
  4412. {
  4413. #ifndef _WIN64
  4414. if (!gpfnWOWGetVDMPointer ||
  4415. !(funcArgs.Args[5] = gpfnWOWGetVDMPointer(
  4416. (DWORD) lpParams,
  4417. dwSize,
  4418. TRUE // fProtectedMode
  4419. )))
  4420. #endif
  4421. {
  4422. return LINEERR_OPERATIONFAILED;
  4423. }
  4424. }
  4425. if ( !lpParams && dwSize > 0)
  4426. {
  4427. return LINEERR_INVALPOINTER;
  4428. }
  4429. if (dwSize > 0)
  4430. {
  4431. hPointer = NewObject (ghHandleTable, (PVOID)lpParams, NULL);
  4432. if (0 == hPointer)
  4433. {
  4434. return LINEERR_NOMEM;
  4435. }
  4436. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  4437. }
  4438. lResult = DOFUNC (&funcArgs, "lineDevSpecific");
  4439. if (0 > lResult)
  4440. {
  4441. DereferenceObject (ghHandleTable, hPointer, 1);
  4442. }
  4443. return lResult;
  4444. }
  4445. LONG
  4446. WINAPI
  4447. lineDevSpecificFeature(
  4448. HLINE hLine,
  4449. DWORD dwFeature,
  4450. LPVOID lpParams,
  4451. DWORD dwSize
  4452. )
  4453. {
  4454. FUNC_ARGS funcArgs =
  4455. {
  4456. MAKELONG (LINE_FUNC | ASYNC | 6, lDevSpecificFeature),
  4457. {
  4458. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  4459. (ULONG_PTR) hLine,
  4460. (ULONG_PTR) dwFeature,
  4461. (ULONG_PTR) lpParams, // pass the actual pointer (for post processing)
  4462. (ULONG_PTR) lpParams, // pass data
  4463. (ULONG_PTR) dwSize
  4464. },
  4465. {
  4466. Dword,
  4467. Dword,
  4468. Dword,
  4469. Dword,
  4470. lpSet_SizeToFollow,
  4471. Size
  4472. }
  4473. };
  4474. DWORD hPointer = 0;
  4475. LONG lResult;
  4476. if (gbNTVDMClient)
  4477. {
  4478. #ifndef _WIN64
  4479. if (!gpfnWOWGetVDMPointer ||
  4480. !(funcArgs.Args[4] = gpfnWOWGetVDMPointer(
  4481. (DWORD) lpParams,
  4482. dwSize,
  4483. TRUE // fProtectedMode
  4484. )))
  4485. #endif
  4486. {
  4487. return LINEERR_OPERATIONFAILED;
  4488. }
  4489. }
  4490. if ( !lpParams && dwSize > 0)
  4491. {
  4492. return LINEERR_INVALPOINTER;
  4493. }
  4494. if (dwSize > 0)
  4495. {
  4496. hPointer = NewObject (ghHandleTable, (PVOID)lpParams, NULL);
  4497. if (0 == hPointer)
  4498. {
  4499. return LINEERR_NOMEM;
  4500. }
  4501. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  4502. }
  4503. lResult = DOFUNC (&funcArgs, "lineDevSpecificFeature");
  4504. if (0 > lResult)
  4505. {
  4506. DereferenceObject (ghHandleTable, hPointer, 1);
  4507. }
  4508. return lResult;
  4509. }
  4510. LONG
  4511. WINAPI
  4512. lineDialW(
  4513. HCALL hCall,
  4514. LPCWSTR lpszDestAddress,
  4515. DWORD dwCountryCode
  4516. )
  4517. {
  4518. FUNC_ARGS funcArgs =
  4519. {
  4520. MAKELONG (LINE_FUNC | ASYNC | 3, lDial),
  4521. {
  4522. (ULONG_PTR) hCall,
  4523. (ULONG_PTR) lpszDestAddress,
  4524. (ULONG_PTR) dwCountryCode
  4525. },
  4526. {
  4527. Dword,
  4528. lpszW,
  4529. Dword
  4530. }
  4531. };
  4532. if ( TAPIIsBadStringPtrW(lpszDestAddress, (UINT)-1) )
  4533. {
  4534. LOG((TL_ERROR, "Bad lpszDestAddress in lineDialW"));
  4535. return( LINEERR_INVALPOINTER );
  4536. }
  4537. return (DOFUNC (&funcArgs, "lineDial"));
  4538. }
  4539. LONG
  4540. WINAPI
  4541. lineDialA(
  4542. HCALL hCall,
  4543. LPCSTR lpszDestAddress,
  4544. DWORD dwCountryCode
  4545. )
  4546. {
  4547. LONG lResult;
  4548. PWSTR szTempPtr;
  4549. if ( IsBadStringPtrA(lpszDestAddress, (UINT)-1) )
  4550. {
  4551. LOG((TL_ERROR, "Bad lpszDestAddress in lineDialA"));
  4552. return( LINEERR_INVALPOINTER );
  4553. }
  4554. szTempPtr = NotSoWideStringToWideString (lpszDestAddress, (DWORD) -1);
  4555. if ( !szTempPtr )
  4556. {
  4557. LOG((TL_ERROR, "lineDialA: NotSoWideStringToWideString returned NULL"));
  4558. return( LINEERR_INVALPOINTER );
  4559. }
  4560. lResult = lineDialW (hCall, szTempPtr, dwCountryCode);
  4561. ClientFree (szTempPtr);
  4562. return lResult;
  4563. }
  4564. LONG
  4565. WINAPI
  4566. lineDial(
  4567. HCALL hCall,
  4568. LPCSTR lpszDestAddress,
  4569. DWORD dwCountryCode
  4570. )
  4571. {
  4572. return lineDialA(
  4573. hCall,
  4574. lpszDestAddress,
  4575. dwCountryCode
  4576. );
  4577. }
  4578. LONG
  4579. WINAPI
  4580. lineDrop(
  4581. HCALL hCall,
  4582. LPCSTR lpsUserUserInfo,
  4583. DWORD dwSize
  4584. )
  4585. {
  4586. FUNC_ARGS funcArgs =
  4587. {
  4588. MAKELONG (LINE_FUNC | ASYNC | 3, lDrop),
  4589. {
  4590. (ULONG_PTR) hCall,
  4591. (ULONG_PTR) lpsUserUserInfo,
  4592. (ULONG_PTR) dwSize
  4593. },
  4594. {
  4595. Dword,
  4596. lpSet_SizeToFollow,
  4597. Size
  4598. }
  4599. };
  4600. if (!lpsUserUserInfo)
  4601. {
  4602. //
  4603. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  4604. //
  4605. funcArgs.ArgTypes[1] = Dword;
  4606. funcArgs.Args[1] = TAPI_NO_DATA;
  4607. funcArgs.ArgTypes[2] = Dword;
  4608. }
  4609. return (DOFUNC (&funcArgs, "lineDrop"));
  4610. }
  4611. LONG
  4612. WINAPI
  4613. lineForwardW(
  4614. HLINE hLine,
  4615. DWORD bAllAddresses,
  4616. DWORD dwAddressID,
  4617. LPLINEFORWARDLIST const lpForwardList,
  4618. DWORD dwNumRingsNoAnswer,
  4619. LPHCALL lphConsultCall,
  4620. LPLINECALLPARAMS const lpCallParams
  4621. )
  4622. {
  4623. FUNC_ARGS funcArgs =
  4624. {
  4625. MAKELONG (LINE_FUNC | ASYNC | 9, lForward),
  4626. {
  4627. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  4628. (ULONG_PTR) hLine,
  4629. (ULONG_PTR) bAllAddresses,
  4630. (ULONG_PTR) dwAddressID,
  4631. (ULONG_PTR) lpForwardList,
  4632. (ULONG_PTR) dwNumRingsNoAnswer,
  4633. (ULONG_PTR) lphConsultCall,
  4634. (ULONG_PTR) lpCallParams,
  4635. (ULONG_PTR) TAPI_NO_DATA // dwAsciiCallParamsCodePage
  4636. },
  4637. {
  4638. Dword,
  4639. Dword,
  4640. Dword,
  4641. Dword,
  4642. lpSet_Struct,
  4643. Dword,
  4644. Dword,
  4645. lpSet_Struct,
  4646. Dword
  4647. }
  4648. };
  4649. DWORD hPointer = 0;
  4650. LONG lResult;
  4651. if (!lpForwardList)
  4652. {
  4653. //
  4654. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  4655. //
  4656. funcArgs.ArgTypes[4] = Dword;
  4657. funcArgs.Args[4] = TAPI_NO_DATA;
  4658. }
  4659. if (!lpCallParams)
  4660. {
  4661. //
  4662. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  4663. //
  4664. funcArgs.ArgTypes[7] = Dword;
  4665. funcArgs.Args[7] = TAPI_NO_DATA;
  4666. }
  4667. if (!gbNTVDMClient)
  4668. {
  4669. if (IsBadDwordPtr (lphConsultCall))
  4670. {
  4671. return LINEERR_INVALPOINTER;
  4672. }
  4673. hPointer = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  4674. if (0 == hPointer)
  4675. {
  4676. return LINEERR_NOMEM;
  4677. }
  4678. funcArgs.Args[6] = (ULONG_PTR)hPointer;
  4679. }
  4680. lResult = DOFUNC (&funcArgs, "lineForwardW");
  4681. if (hPointer && 0 > lResult)
  4682. {
  4683. DereferenceObject (ghHandleTable, hPointer, 1);
  4684. }
  4685. return lResult;
  4686. }
  4687. // void
  4688. // LayDownNewString(
  4689. // LPBYTE pOldBase,
  4690. // LPDWORD pdwOldSizeOffset,
  4691. // LPBYTE pNewBase,
  4692. // LPDWORD pdwNewSizeOffset,
  4693. // LPDWORD pdwNewOffset
  4694. // )
  4695. // {
  4696. // LPBYTE pOldString;
  4697. // DWORD dwNewStringSize;
  4698. //
  4699. //
  4700. // pOldString = pOldBase + *(pdwOldSizeOffset + 1);
  4701. //
  4702. // *(pdwNewSizeOffset + 1) = *pdwNewOffset;
  4703. //
  4704. // if ( IsBadStringPtr( pOldString, 256) )
  4705. // {
  4706. // return;
  4707. // }
  4708. //
  4709. // dwNewStringSize = sizeof(WCHAR) * MultiByteToWideChar(
  4710. // GetACP(),
  4711. // MB_PRECOMPOSED,
  4712. // pOldString,
  4713. // *pdwOldSizeOffset,
  4714. // (PWSTR)(pNewBase + *(pdwNewSizeOffset + 1)),
  4715. // *pdwOldSizeOffset
  4716. // );
  4717. //
  4718. // *pdwNewSizeOffset = dwNewStringSize;
  4719. //
  4720. // *pdwNewOffset = (*pdwNewOffset + dwNewStringSize + 3) & 0xfffffffc;
  4721. // }
  4722. LONG
  4723. WINAPI
  4724. lineForwardA(
  4725. HLINE hLine,
  4726. DWORD bAllAddresses,
  4727. DWORD dwAddressID,
  4728. LPLINEFORWARDLIST const lpForwardList,
  4729. DWORD dwNumRingsNoAnswer,
  4730. LPHCALL lphConsultCall,
  4731. LPLINECALLPARAMS const lpCallParams
  4732. )
  4733. {
  4734. FUNC_ARGS funcArgs =
  4735. {
  4736. MAKELONG (LINE_FUNC | ASYNC | 9, lForward),
  4737. {
  4738. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  4739. (ULONG_PTR) hLine,
  4740. (ULONG_PTR) bAllAddresses,
  4741. (ULONG_PTR) dwAddressID,
  4742. (ULONG_PTR) lpForwardList,
  4743. (ULONG_PTR) dwNumRingsNoAnswer,
  4744. (ULONG_PTR) lphConsultCall,
  4745. (ULONG_PTR) lpCallParams,
  4746. (ULONG_PTR) GetACP() // dwAsciiCallParamsCodePage
  4747. },
  4748. {
  4749. Dword,
  4750. Dword,
  4751. Dword,
  4752. Dword,
  4753. lpSet_Struct,
  4754. Dword,
  4755. Dword,
  4756. lpSet_Struct,
  4757. Dword
  4758. }
  4759. };
  4760. DWORD hPointer = 0;
  4761. LONG lResult;
  4762. if (!lpForwardList)
  4763. {
  4764. //
  4765. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  4766. //
  4767. funcArgs.ArgTypes[4] = Dword;
  4768. funcArgs.Args[4] = TAPI_NO_DATA;
  4769. }
  4770. if (!lpCallParams)
  4771. {
  4772. //
  4773. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  4774. //
  4775. funcArgs.ArgTypes[7] = Dword;
  4776. funcArgs.Args[7] = TAPI_NO_DATA;
  4777. }
  4778. if (!gbNTVDMClient)
  4779. {
  4780. if (IsBadDwordPtr (lphConsultCall))
  4781. {
  4782. return LINEERR_INVALPOINTER;
  4783. }
  4784. hPointer = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  4785. if (0 == hPointer)
  4786. {
  4787. return LINEERR_NOMEM;
  4788. }
  4789. funcArgs.Args[6] = (ULONG_PTR)hPointer;
  4790. }
  4791. lResult = DOFUNC (&funcArgs, "lineForward");
  4792. if (hPointer && 0 > lResult)
  4793. {
  4794. DereferenceObject (ghHandleTable, hPointer, 1);
  4795. }
  4796. return lResult;
  4797. }
  4798. LONG
  4799. WINAPI
  4800. lineForward(
  4801. HLINE hLine,
  4802. DWORD bAllAddresses,
  4803. DWORD dwAddressID,
  4804. LPLINEFORWARDLIST const lpForwardList,
  4805. DWORD dwNumRingsNoAnswer,
  4806. LPHCALL lphConsultCall,
  4807. LPLINECALLPARAMS const lpCallParams
  4808. )
  4809. {
  4810. return lineForwardA(
  4811. hLine,
  4812. bAllAddresses,
  4813. dwAddressID,
  4814. lpForwardList,
  4815. dwNumRingsNoAnswer,
  4816. lphConsultCall,
  4817. lpCallParams
  4818. );
  4819. }
  4820. void
  4821. PASCAL
  4822. lineGatherDigitsWPostProcess(
  4823. PASYNCEVENTMSG pMsg
  4824. )
  4825. {
  4826. LOG((TL_TRACE, "lineGatherDigitsWPostProcess: enter"));
  4827. LOG((TL_INFO,
  4828. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  4829. pMsg->Param1,
  4830. pMsg->Param2,
  4831. pMsg->Param3,
  4832. pMsg->Param4
  4833. ));
  4834. if (pMsg->Param1 & (LINEGATHERTERM_BUFFERFULL | LINEGATHERTERM_CANCEL |
  4835. LINEGATHERTERM_TERMDIGIT | LINEGATHERTERM_INTERTIMEOUT))
  4836. {
  4837. LPSTR lpsDigits = (LPSTR) ReferenceObject (ghHandleTable, pMsg->Param2, 0);
  4838. DWORD dwNumDigits = (DWORD) pMsg->Param4;
  4839. #if NEWTAPI32
  4840. LPBYTE lpBuf = (LPBYTE)(((ULONG_PTR *)(pMsg + 1)) + 2);
  4841. #endif
  4842. // We don't need the handle to the pointer any more...
  4843. DereferenceObject (ghHandleTable, pMsg->Param2, 2);
  4844. try
  4845. {
  4846. if (gbNTVDMClient)
  4847. {
  4848. #ifndef _WIN64
  4849. LPSTR lpsDigitsVDM = (LPSTR) gpfnWOWGetVDMPointer(
  4850. (DWORD) lpsDigits,
  4851. dwNumDigits * sizeof(WCHAR),
  4852. TRUE // fProtectedMode
  4853. );
  4854. if (lpsDigitsVDM)
  4855. {
  4856. #if NEWTAPI32
  4857. CopyMemory(
  4858. lpsDigitsVDM,
  4859. lpBuf,
  4860. dwNumDigits * sizeof (WCHAR)
  4861. );
  4862. #else
  4863. CopyMemory(
  4864. lpsDigitsVDM,
  4865. pMsg + 1,
  4866. dwNumDigits * sizeof (WCHAR)
  4867. );
  4868. #endif
  4869. }
  4870. else
  4871. {
  4872. }
  4873. #endif
  4874. }
  4875. else
  4876. {
  4877. CopyMemory (lpsDigits, lpBuf, dwNumDigits * sizeof(WCHAR));
  4878. }
  4879. }
  4880. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  4881. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  4882. {
  4883. //
  4884. // Don't do anything if we GPF
  4885. //
  4886. }
  4887. }
  4888. pMsg->Param2 = 0;
  4889. }
  4890. LONG
  4891. WINAPI
  4892. lineGatherDigitsW(
  4893. HCALL hCall,
  4894. DWORD dwDigitModes,
  4895. LPWSTR lpsDigits,
  4896. DWORD dwNumDigits,
  4897. LPCWSTR lpszTerminationDigits,
  4898. DWORD dwFirstDigitTimeout,
  4899. DWORD dwInterDigitTimeout
  4900. )
  4901. {
  4902. FUNC_ARGS funcArgs =
  4903. {
  4904. #if NEWTAPI32
  4905. MAKELONG (LINE_FUNC | SYNC | 9, lGatherDigits),
  4906. #else
  4907. MAKELONG (LINE_FUNC | SYNC | 8, lGatherDigits),
  4908. #endif
  4909. {
  4910. (ULONG_PTR) GetFunctionIndex(lineGatherDigitsWPostProcess),
  4911. (ULONG_PTR) hCall,
  4912. #if NEWTAPI32
  4913. (ULONG_PTR) 0, // this is the dwendtoendid for remotesp
  4914. #endif
  4915. (ULONG_PTR) dwDigitModes,
  4916. (ULONG_PTR) lpsDigits,
  4917. (ULONG_PTR) dwNumDigits,
  4918. (ULONG_PTR) lpszTerminationDigits,
  4919. (ULONG_PTR) dwFirstDigitTimeout,
  4920. (ULONG_PTR) dwInterDigitTimeout
  4921. },
  4922. {
  4923. Dword,
  4924. Dword,
  4925. #if NEWTAPI32
  4926. Dword,
  4927. #endif
  4928. Dword,
  4929. Dword,
  4930. Dword,
  4931. lpszW,
  4932. Dword,
  4933. Dword
  4934. }
  4935. };
  4936. DWORD hPointer = 0;
  4937. LONG lResult;
  4938. //
  4939. // Note: we do the ptr check here rather than in DOFUNC because we're
  4940. // not passing any digits data within the context of this func
  4941. //
  4942. if (lpsDigits && IsBadWritePtr (lpsDigits, dwNumDigits * sizeof (WCHAR)))
  4943. {
  4944. return LINEERR_INVALPOINTER;
  4945. }
  4946. if (lpszTerminationDigits == (LPCWSTR) NULL)
  4947. {
  4948. //
  4949. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  4950. //
  4951. #if NEWTAPI32
  4952. funcArgs.ArgTypes[6] = Dword;
  4953. funcArgs.Args[6] = TAPI_NO_DATA;
  4954. #else
  4955. funcArgs.ArgTypes[5] = Dword;
  4956. funcArgs.Args[5] = TAPI_NO_DATA;
  4957. #endif
  4958. }
  4959. else
  4960. {
  4961. if ( TAPIIsBadStringPtrW(lpszTerminationDigits, (UINT)-1) )
  4962. {
  4963. LOG((TL_ERROR, "Bad lpszDestAddress in lineGatherDigitsW"));
  4964. return( LINEERR_INVALPOINTER );
  4965. }
  4966. }
  4967. hPointer = NewObject (ghHandleTable, (PVOID)lpsDigits, NULL);
  4968. if (0 == hPointer)
  4969. {
  4970. return LINEERR_NOMEM;
  4971. }
  4972. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  4973. lResult = DOFUNC (&funcArgs, "lineGatherDigits");
  4974. if (0 > lResult)
  4975. {
  4976. DereferenceObject (ghHandleTable, hPointer, 1);
  4977. }
  4978. return lResult;
  4979. }
  4980. void
  4981. PASCAL
  4982. lineGatherDigitsPostProcess(
  4983. PASYNCEVENTMSG pMsg
  4984. )
  4985. {
  4986. LOG((TL_TRACE, "lineGatherDigitsPostProcess: enter"));
  4987. LOG((TL_INFO,
  4988. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  4989. pMsg->Param1,
  4990. pMsg->Param2,
  4991. pMsg->Param3,
  4992. pMsg->Param4
  4993. ));
  4994. if (pMsg->Param1 & (LINEGATHERTERM_BUFFERFULL | LINEGATHERTERM_CANCEL |
  4995. LINEGATHERTERM_TERMDIGIT | LINEGATHERTERM_INTERTIMEOUT))
  4996. {
  4997. LPSTR lpsDigits = (LPSTR) ReferenceObject (ghHandleTable, pMsg->Param2, 0);
  4998. DWORD dwNumDigits = (DWORD) pMsg->Param4;
  4999. LPWSTR pBuffer = (LPWSTR) (((ULONG_PTR *)(pMsg + 1)) + 2);
  5000. // We don't need the handle to the pointer any more...
  5001. DereferenceObject (ghHandleTable, pMsg->Param2, 2);
  5002. try
  5003. {
  5004. if (gbNTVDMClient)
  5005. {
  5006. #ifndef _WIN64
  5007. LPSTR lpsDigitsVDM = (LPSTR) gpfnWOWGetVDMPointer(
  5008. (DWORD) lpsDigits,
  5009. dwNumDigits * sizeof(WCHAR),
  5010. TRUE // fProtectedMode
  5011. );
  5012. if (lpsDigitsVDM)
  5013. {
  5014. WideCharToMultiByte(
  5015. GetACP(),
  5016. 0,
  5017. #if NEWTAPI32
  5018. pBuffer,
  5019. #else
  5020. (LPCWSTR)(pMsg + 1),
  5021. #endif
  5022. dwNumDigits,
  5023. lpsDigitsVDM,
  5024. dwNumDigits,
  5025. NULL,
  5026. NULL
  5027. );
  5028. }
  5029. else
  5030. {
  5031. }
  5032. #endif
  5033. }
  5034. else
  5035. {
  5036. WideCharToMultiByte(
  5037. GetACP(),
  5038. 0,
  5039. #if NEWTAPI32
  5040. pBuffer,
  5041. #else
  5042. (LPCWSTR)(pMsg + 1),
  5043. #endif
  5044. dwNumDigits,
  5045. lpsDigits,
  5046. dwNumDigits,
  5047. NULL,
  5048. NULL
  5049. );
  5050. }
  5051. }
  5052. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  5053. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  5054. {
  5055. //
  5056. // Don't do anything if we GPF
  5057. //
  5058. }
  5059. }
  5060. pMsg->Param2 = 0;
  5061. }
  5062. LONG
  5063. WINAPI
  5064. lineGatherDigitsA(
  5065. HCALL hCall,
  5066. DWORD dwDigitModes,
  5067. LPSTR lpsDigits,
  5068. DWORD dwNumDigits,
  5069. LPCSTR lpszTerminationDigits,
  5070. DWORD dwFirstDigitTimeout,
  5071. DWORD dwInterDigitTimeout
  5072. )
  5073. {
  5074. LONG lResult;
  5075. DWORD hPointer = 0;
  5076. FUNC_ARGS funcArgs =
  5077. {
  5078. #if NEWTAPI32
  5079. MAKELONG (LINE_FUNC | SYNC | 9, lGatherDigits),
  5080. #else
  5081. MAKELONG (LINE_FUNC | SYNC | 8, lGatherDigits),
  5082. #endif
  5083. {
  5084. (ULONG_PTR) GetFunctionIndex(lineGatherDigitsPostProcess),
  5085. (ULONG_PTR) hCall,
  5086. #if NEWTAPI32
  5087. (ULONG_PTR) 0, // dw end to end id for remotesp
  5088. #endif
  5089. (ULONG_PTR) dwDigitModes,
  5090. (ULONG_PTR) lpsDigits,
  5091. (ULONG_PTR) dwNumDigits,
  5092. //BJM 06/04/97 what was this? 0, // (DWORD) lpszTerminationDigits,
  5093. (ULONG_PTR) lpszTerminationDigits,
  5094. (ULONG_PTR) dwFirstDigitTimeout,
  5095. (ULONG_PTR) dwInterDigitTimeout
  5096. },
  5097. {
  5098. Dword,
  5099. Dword,
  5100. #if NEWTAPI32
  5101. Dword,
  5102. #endif
  5103. Dword,
  5104. Dword,
  5105. Dword,
  5106. lpszW,
  5107. Dword,
  5108. Dword
  5109. }
  5110. };
  5111. //
  5112. // Note: we do the ptr check here rather than in DOFUNC because we're
  5113. // not passing any digits data within the context of this func
  5114. //
  5115. if (gbNTVDMClient == FALSE)
  5116. {
  5117. if (lpsDigits && IsBadWritePtr (lpsDigits, dwNumDigits))
  5118. {
  5119. return LINEERR_INVALPOINTER;
  5120. }
  5121. }
  5122. if (lpszTerminationDigits == (LPCSTR) NULL)
  5123. {
  5124. //
  5125. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  5126. //
  5127. #if NEWTAPI32
  5128. funcArgs.ArgTypes[6] = Dword;
  5129. funcArgs.Args[6] = TAPI_NO_DATA;
  5130. #else
  5131. funcArgs.ArgTypes[5] = Dword;
  5132. funcArgs.Args[5] = TAPI_NO_DATA;
  5133. #endif
  5134. }
  5135. else
  5136. {
  5137. if ( IsBadStringPtrA(lpszTerminationDigits, (UINT)-1) )
  5138. {
  5139. LOG((TL_ERROR, "Bad lpszDestAddress in lineGatherDigitsA"));
  5140. return( LINEERR_INVALPOINTER );
  5141. }
  5142. #if NEWTAPI32
  5143. funcArgs.Args[6] = (ULONG_PTR) NotSoWideStringToWideString(
  5144. lpszTerminationDigits,
  5145. (DWORD) -1
  5146. );
  5147. #else
  5148. funcArgs.Args[5] = (ULONG_PTR) NotSoWideStringToWideString(
  5149. lpszTerminationDigits,
  5150. (DWORD) -1
  5151. );
  5152. #endif
  5153. }
  5154. if ( lpsDigits )
  5155. {
  5156. hPointer = NewObject (ghHandleTable, (PVOID)lpsDigits, NULL);
  5157. if (0 == hPointer)
  5158. {
  5159. return LINEERR_NOMEM;
  5160. }
  5161. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  5162. }
  5163. else
  5164. {
  5165. funcArgs.Args[4] = (ULONG_PTR) 0;
  5166. }
  5167. lResult = (DOFUNC (&funcArgs, "lineGatherDigits"));
  5168. if (hPointer && 0 > lResult)
  5169. {
  5170. DereferenceObject (ghHandleTable, hPointer, 1);
  5171. }
  5172. #if NEWTAPI32
  5173. if ( funcArgs.Args[6] && (funcArgs.Args[6] != TAPI_NO_DATA) )
  5174. {
  5175. ClientFree( (LPVOID)funcArgs.Args[6] );
  5176. }
  5177. #else
  5178. if ( funcArgs.Args[5] && (funcArgs.Args[5] != TAPI_NO_DATA) )
  5179. {
  5180. ClientFree( (LPVOID)funcArgs.Args[5] );
  5181. }
  5182. #endif
  5183. return lResult;
  5184. }
  5185. LONG
  5186. WINAPI
  5187. lineGatherDigits(
  5188. HCALL hCall,
  5189. DWORD dwDigitModes,
  5190. LPSTR lpsDigits,
  5191. DWORD dwNumDigits,
  5192. LPCSTR lpszTerminationDigits,
  5193. DWORD dwFirstDigitTimeout,
  5194. DWORD dwInterDigitTimeout
  5195. )
  5196. {
  5197. return lineGatherDigitsA(
  5198. hCall,
  5199. dwDigitModes,
  5200. lpsDigits,
  5201. dwNumDigits,
  5202. lpszTerminationDigits,
  5203. dwFirstDigitTimeout,
  5204. dwInterDigitTimeout
  5205. );
  5206. }
  5207. LONG
  5208. WINAPI
  5209. lineGenerateDigitsW(
  5210. HCALL hCall,
  5211. DWORD dwDigitMode,
  5212. LPCWSTR lpszDigits,
  5213. DWORD dwDuration
  5214. )
  5215. {
  5216. FUNC_ARGS funcArgs =
  5217. {
  5218. MAKELONG (LINE_FUNC | SYNC | 5, lGenerateDigits),
  5219. {
  5220. (ULONG_PTR) hCall,
  5221. (ULONG_PTR) dwDigitMode,
  5222. (ULONG_PTR) lpszDigits,
  5223. (ULONG_PTR) dwDuration,
  5224. (ULONG_PTR) 0 // dwEndToEndID, remotesp only
  5225. },
  5226. {
  5227. Dword,
  5228. Dword,
  5229. lpszW,
  5230. Dword,
  5231. Dword
  5232. }
  5233. };
  5234. if (!lpszDigits)
  5235. {
  5236. funcArgs.Args[2] = TAPI_NO_DATA;
  5237. funcArgs.ArgTypes[2] = Dword;
  5238. }
  5239. return (DOFUNC (&funcArgs, "lineGenerateDigits"));
  5240. }
  5241. LONG
  5242. WINAPI
  5243. lineGenerateDigitsA(
  5244. HCALL hCall,
  5245. DWORD dwDigitMode,
  5246. LPCSTR lpszDigits,
  5247. DWORD dwDuration
  5248. )
  5249. {
  5250. LONG lResult;
  5251. FUNC_ARGS funcArgs =
  5252. {
  5253. MAKELONG (LINE_FUNC | SYNC | 5, lGenerateDigits),
  5254. {
  5255. (ULONG_PTR) hCall,
  5256. (ULONG_PTR) dwDigitMode,
  5257. (ULONG_PTR) 0, // (DWORD) lpszDigits,
  5258. (ULONG_PTR) dwDuration,
  5259. (ULONG_PTR) 0 // dwEndToEndID, remotesp only
  5260. },
  5261. {
  5262. Dword,
  5263. Dword,
  5264. lpszW,
  5265. Dword,
  5266. Dword
  5267. }
  5268. };
  5269. if (lpszDigits)
  5270. {
  5271. if (IsBadStringPtrA (lpszDigits, (DWORD) -1))
  5272. {
  5273. return LINEERR_INVALPOINTER;
  5274. }
  5275. else if (!(funcArgs.Args[2] = (ULONG_PTR) NotSoWideStringToWideString(
  5276. lpszDigits,
  5277. (DWORD) -1
  5278. )))
  5279. {
  5280. return LINEERR_NOMEM;
  5281. }
  5282. }
  5283. else
  5284. {
  5285. funcArgs.Args[2] = TAPI_NO_DATA;
  5286. funcArgs.ArgTypes[2] = Dword;
  5287. }
  5288. lResult = (DOFUNC (&funcArgs, "lineGenerateDigits"));
  5289. if (funcArgs.Args[2] != TAPI_NO_DATA)
  5290. {
  5291. ClientFree ((LPVOID) funcArgs.Args[2]);
  5292. }
  5293. return lResult;
  5294. }
  5295. LONG
  5296. WINAPI
  5297. lineGenerateDigits(
  5298. HCALL hCall,
  5299. DWORD dwDigitMode,
  5300. LPCSTR lpszDigits,
  5301. DWORD dwDuration
  5302. )
  5303. {
  5304. return lineGenerateDigitsA(
  5305. hCall,
  5306. dwDigitMode,
  5307. lpszDigits,
  5308. dwDuration
  5309. );
  5310. }
  5311. LONG
  5312. WINAPI
  5313. lineGenerateTone(
  5314. HCALL hCall,
  5315. DWORD dwToneMode,
  5316. DWORD dwDuration,
  5317. DWORD dwNumTones,
  5318. LPLINEGENERATETONE const lpTones
  5319. )
  5320. {
  5321. FUNC_ARGS funcArgs =
  5322. {
  5323. MAKELONG (LINE_FUNC | SYNC | 7, lGenerateTone),
  5324. {
  5325. (ULONG_PTR) hCall,
  5326. (ULONG_PTR) dwToneMode,
  5327. (ULONG_PTR) dwDuration,
  5328. (ULONG_PTR) dwNumTones,
  5329. (ULONG_PTR) TAPI_NO_DATA, // (DWORD) lpTones,
  5330. (ULONG_PTR) 0, // dwNumTones * sizeof(LINEGENERATETONE)
  5331. (ULONG_PTR) 0 // dwEndToEndID, remotesp only
  5332. },
  5333. {
  5334. Dword,
  5335. Dword,
  5336. Dword,
  5337. Dword,
  5338. Dword, // lpSet_SizeToFollow,
  5339. Dword, // Size
  5340. Dword
  5341. }
  5342. };
  5343. if (dwToneMode == LINETONEMODE_CUSTOM)
  5344. {
  5345. //
  5346. // Set lpTones (& following Size arg) since in this case
  5347. // they are valid args
  5348. //
  5349. funcArgs.ArgTypes[4] = lpSet_SizeToFollow;
  5350. funcArgs.Args[4] = (ULONG_PTR) lpTones;
  5351. funcArgs.ArgTypes[5] = Size;
  5352. funcArgs.Args[5] = dwNumTones * sizeof(LINEGENERATETONE);
  5353. }
  5354. return (DOFUNC (&funcArgs, "lineGenerateTone"));
  5355. }
  5356. LONG
  5357. WINAPI
  5358. lineGetAddressCapsW(
  5359. HLINEAPP hLineApp,
  5360. DWORD dwDeviceID,
  5361. DWORD dwAddressID,
  5362. DWORD dwAPIVersion,
  5363. DWORD dwExtVersion,
  5364. LPLINEADDRESSCAPS lpAddressCaps
  5365. )
  5366. {
  5367. FUNC_ARGS funcArgs =
  5368. {
  5369. MAKELONG (LINE_FUNC | SYNC | 6, lGetAddressCaps),
  5370. {
  5371. (ULONG_PTR) hLineApp,
  5372. (ULONG_PTR) dwDeviceID,
  5373. (ULONG_PTR) dwAddressID,
  5374. (ULONG_PTR) dwAPIVersion,
  5375. (ULONG_PTR) dwExtVersion,
  5376. (ULONG_PTR) lpAddressCaps
  5377. },
  5378. {
  5379. hXxxApp,
  5380. Dword,
  5381. Dword,
  5382. Dword,
  5383. Dword,
  5384. lpGet_Struct
  5385. }
  5386. };
  5387. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  5388. {
  5389. return LINEERR_INCOMPATIBLEAPIVERSION;
  5390. }
  5391. return (DOFUNC (&funcArgs, "lineGetAddressCaps"));
  5392. }
  5393. LONG
  5394. WINAPI
  5395. lineGetAddressCapsA(
  5396. HLINEAPP hLineApp,
  5397. DWORD dwDeviceID,
  5398. DWORD dwAddressID,
  5399. DWORD dwAPIVersion,
  5400. DWORD dwExtVersion,
  5401. LPLINEADDRESSCAPS lpAddressCaps
  5402. )
  5403. {
  5404. LONG lResult;
  5405. lResult = lineGetAddressCapsW(
  5406. hLineApp,
  5407. dwDeviceID,
  5408. dwAddressID,
  5409. dwAPIVersion,
  5410. dwExtVersion,
  5411. lpAddressCaps
  5412. );
  5413. if (lResult == 0)
  5414. {
  5415. WideStringToNotSoWideString(
  5416. (LPBYTE)lpAddressCaps,
  5417. &lpAddressCaps->dwAddressSize
  5418. );
  5419. //
  5420. // WideChar to multibyte translation of the completion message
  5421. // array is somewhat problematic in that we can't be sure
  5422. // the msgs will all be the same size after translation. So
  5423. // we'll translate them, pad the remainder of each msg entry
  5424. // with 0's, and not bother touching any of the size or
  5425. // offset values.
  5426. //
  5427. if (lpAddressCaps->dwNumCompletionMessages &&
  5428. lpAddressCaps->dwCompletionMsgTextEntrySize)
  5429. {
  5430. PWSTR pStrW;
  5431. PSTR pStrA;
  5432. DWORD dwMsgSize = lpAddressCaps->dwCompletionMsgTextEntrySize,
  5433. dwNewSize, i;
  5434. if ((pStrA = ClientAlloc (dwMsgSize)))
  5435. {
  5436. pStrW = (PWSTR) (((LPBYTE) lpAddressCaps) +
  5437. lpAddressCaps->dwCompletionMsgTextOffset);
  5438. for (i = 0; i < lpAddressCaps->dwNumCompletionMessages; i++)
  5439. {
  5440. dwNewSize = WideCharToMultiByte(
  5441. GetACP(),
  5442. 0,
  5443. pStrW,
  5444. dwMsgSize / sizeof(WCHAR),
  5445. pStrA,
  5446. dwMsgSize,
  5447. NULL,
  5448. NULL
  5449. );
  5450. CopyMemory (pStrW, pStrA, dwNewSize);
  5451. ZeroMemory(
  5452. ((LPBYTE) pStrW) + dwNewSize,
  5453. dwMsgSize - dwNewSize
  5454. );
  5455. pStrW = (PWSTR) (((LPBYTE) pStrW) + dwMsgSize);
  5456. }
  5457. ClientFree (pStrA);
  5458. }
  5459. else
  5460. {
  5461. lpAddressCaps->dwNumCompletionMessages =
  5462. lpAddressCaps->dwCompletionMsgTextEntrySize =
  5463. lpAddressCaps->dwCompletionMsgTextSize =
  5464. lpAddressCaps->dwCompletionMsgTextOffset = 0;
  5465. }
  5466. }
  5467. if (dwAPIVersion >= 0x00020000)
  5468. {
  5469. WideStringToNotSoWideString(
  5470. (LPBYTE)lpAddressCaps,
  5471. &lpAddressCaps->dwDeviceClassesSize
  5472. );
  5473. }
  5474. }
  5475. return lResult;
  5476. }
  5477. LONG
  5478. WINAPI
  5479. lineGetAddressCaps(
  5480. HLINEAPP hLineApp,
  5481. DWORD dwDeviceID,
  5482. DWORD dwAddressID,
  5483. DWORD dwAPIVersion,
  5484. DWORD dwExtVersion,
  5485. LPLINEADDRESSCAPS lpAddressCaps
  5486. )
  5487. {
  5488. return lineGetAddressCapsA(
  5489. hLineApp,
  5490. dwDeviceID,
  5491. dwAddressID,
  5492. dwAPIVersion,
  5493. dwExtVersion,
  5494. lpAddressCaps
  5495. );
  5496. }
  5497. LONG
  5498. WINAPI
  5499. lineGetAddressIDW(
  5500. HLINE hLine,
  5501. LPDWORD lpdwAddressID,
  5502. DWORD dwAddressMode,
  5503. LPCWSTR lpsAddress,
  5504. DWORD dwSize
  5505. )
  5506. {
  5507. FUNC_ARGS funcArgs =
  5508. {
  5509. MAKELONG (LINE_FUNC | SYNC | 5, lGetAddressID),
  5510. {
  5511. (ULONG_PTR) hLine,
  5512. (ULONG_PTR) lpdwAddressID,
  5513. (ULONG_PTR) dwAddressMode,
  5514. (ULONG_PTR) lpsAddress,
  5515. (ULONG_PTR) dwSize
  5516. },
  5517. {
  5518. Dword,
  5519. lpDword,
  5520. Dword,
  5521. lpSet_SizeToFollow,
  5522. Size
  5523. }
  5524. };
  5525. return (DOFUNC (&funcArgs, "lineGetAddressID"));
  5526. }
  5527. LONG
  5528. WINAPI
  5529. lineGetAddressIDA(
  5530. HLINE hLine,
  5531. LPDWORD lpdwAddressID,
  5532. DWORD dwAddressMode,
  5533. LPCSTR lpsAddress,
  5534. DWORD dwSize
  5535. )
  5536. {
  5537. LONG lResult;
  5538. DWORD dwNumChars;
  5539. PWSTR szTempPtr;
  5540. //
  5541. // Special case for dwSize = -1 (implies a NULL-terminated string as
  5542. // far as IsBadStringPtrA is concerned)
  5543. //
  5544. if (dwSize == 0 || IsBadReadPtr (lpsAddress, dwSize))
  5545. {
  5546. LOG((TL_ERROR, "lineGetAddressID: Bad lpsAddress or dwSize"));
  5547. return LINEERR_INVALPOINTER;
  5548. }
  5549. dwNumChars = MultiByteToWideChar(
  5550. GetACP(),
  5551. MB_PRECOMPOSED,
  5552. lpsAddress,
  5553. dwSize,
  5554. NULL,
  5555. 0
  5556. );
  5557. if (!(szTempPtr = ClientAlloc (dwNumChars * sizeof (WCHAR))))
  5558. {
  5559. return LINEERR_NOMEM;
  5560. }
  5561. MultiByteToWideChar(
  5562. GetACP(),
  5563. MB_PRECOMPOSED,
  5564. lpsAddress,
  5565. dwSize,
  5566. szTempPtr,
  5567. dwNumChars
  5568. );
  5569. lResult = lineGetAddressIDW(
  5570. hLine,
  5571. lpdwAddressID,
  5572. dwAddressMode,
  5573. szTempPtr,
  5574. dwNumChars * sizeof (WCHAR)
  5575. );
  5576. ClientFree (szTempPtr);
  5577. return lResult;
  5578. }
  5579. LONG
  5580. WINAPI
  5581. lineGetAddressID(
  5582. HLINE hLine,
  5583. LPDWORD lpdwAddressID,
  5584. DWORD dwAddressMode,
  5585. LPCSTR lpsAddress,
  5586. DWORD dwSize
  5587. )
  5588. {
  5589. return lineGetAddressIDA(
  5590. hLine,
  5591. lpdwAddressID,
  5592. dwAddressMode,
  5593. lpsAddress,
  5594. dwSize
  5595. );
  5596. }
  5597. LONG
  5598. WINAPI
  5599. lineGetAddressStatusW(
  5600. HLINE hLine,
  5601. DWORD dwAddressID,
  5602. LPLINEADDRESSSTATUS lpAddressStatus
  5603. )
  5604. {
  5605. FUNC_ARGS funcArgs =
  5606. {
  5607. MAKELONG (LINE_FUNC | SYNC | 3, lGetAddressStatus),
  5608. {
  5609. (ULONG_PTR) hLine,
  5610. (ULONG_PTR) dwAddressID,
  5611. (ULONG_PTR) lpAddressStatus
  5612. },
  5613. {
  5614. Dword,
  5615. Dword,
  5616. lpGet_Struct
  5617. }
  5618. };
  5619. return (DOFUNC (&funcArgs, "lineGetAddressStatus"));
  5620. }
  5621. LONG
  5622. WINAPI
  5623. lineGetAddressStatusA(
  5624. HLINE hLine,
  5625. DWORD dwAddressID,
  5626. LPLINEADDRESSSTATUS lpAddressStatus
  5627. )
  5628. {
  5629. LONG lResult;
  5630. PWSTR szTempPtr = NULL;
  5631. if ( IsBadWritePtr(lpAddressStatus, sizeof(LINEADDRESSSTATUS)) )
  5632. {
  5633. LOG((TL_ERROR, "lineGetAddressStatus: Bad lpAddressStatus pointer"));
  5634. return LINEERR_INVALPOINTER;
  5635. }
  5636. lResult = lineGetAddressStatusW(
  5637. hLine,
  5638. dwAddressID,
  5639. lpAddressStatus
  5640. );
  5641. if (lResult == 0)
  5642. {
  5643. DWORD i;
  5644. LPLINEFORWARD lplf;
  5645. lplf = (LPLINEFORWARD) (((LPBYTE)lpAddressStatus) +
  5646. lpAddressStatus->dwForwardOffset);
  5647. for (i = 0; i < lpAddressStatus->dwForwardNumEntries; i++, lplf++)
  5648. {
  5649. WideStringToNotSoWideString(
  5650. (LPBYTE) lpAddressStatus,
  5651. &(lplf->dwCallerAddressSize)
  5652. );
  5653. WideStringToNotSoWideString(
  5654. (LPBYTE) lpAddressStatus,
  5655. &(lplf->dwDestAddressSize)
  5656. );
  5657. }
  5658. }
  5659. return lResult;
  5660. }
  5661. LONG
  5662. WINAPI
  5663. lineGetAddressStatus(
  5664. HLINE hLine,
  5665. DWORD dwAddressID,
  5666. LPLINEADDRESSSTATUS lpAddressStatus
  5667. )
  5668. {
  5669. return lineGetAddressStatusA(
  5670. hLine,
  5671. dwAddressID,
  5672. lpAddressStatus
  5673. );
  5674. }
  5675. LONG
  5676. WINAPI
  5677. lineGetAgentActivityListW(
  5678. HLINE hLine,
  5679. DWORD dwAddressID,
  5680. LPLINEAGENTACTIVITYLIST lpAgentActivityList
  5681. )
  5682. {
  5683. FUNC_ARGS funcArgs =
  5684. {
  5685. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentActivityList),
  5686. {
  5687. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  5688. (ULONG_PTR) hLine,
  5689. (ULONG_PTR) dwAddressID,
  5690. (ULONG_PTR) lpAgentActivityList,// pass the actual ptr (for ppproc)
  5691. (ULONG_PTR) lpAgentActivityList // pass data
  5692. },
  5693. {
  5694. Dword,
  5695. Dword,
  5696. Dword,
  5697. Dword,
  5698. lpGet_Struct,
  5699. }
  5700. };
  5701. DWORD hPointer = 0;
  5702. LONG lResult;
  5703. if ( !lpAgentActivityList )
  5704. {
  5705. return LINEERR_INVALPOINTER;
  5706. }
  5707. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentActivityList, NULL);
  5708. if (0 == hPointer)
  5709. {
  5710. return LINEERR_NOMEM;
  5711. }
  5712. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  5713. lResult = (DOFUNC (&funcArgs, "lineGetAgentActivityListW"));
  5714. if (0 > lResult)
  5715. {
  5716. DereferenceObject (ghHandleTable, hPointer, 1);
  5717. }
  5718. return lResult;
  5719. }
  5720. void
  5721. PASCAL
  5722. lineGetAgentActivityListAPostProcess(
  5723. PASYNCEVENTMSG pMsg
  5724. )
  5725. {
  5726. LOG((TL_TRACE, "lineGetAgentActivityListAPostProcess: enter"));
  5727. LOG((TL_INFO,
  5728. "\t\tdwP1=x%lx, dwP2=x%lx, dwP3=x%lx, dwP4=x%lx",
  5729. pMsg->Param1,
  5730. pMsg->Param2,
  5731. pMsg->Param3,
  5732. pMsg->Param4
  5733. ));
  5734. if (pMsg->Param2 == 0)
  5735. {
  5736. DWORD dwSize = (DWORD) pMsg->Param4;
  5737. LPLINEAGENTACTIVITYLIST lpAgentActivityList = (LPLINEAGENTACTIVITYLIST)
  5738. ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  5739. // We don't need the handle to the pointer any more...
  5740. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  5741. try
  5742. {
  5743. DWORD dw, dwNumEntries;
  5744. LPLINEAGENTACTIVITYENTRY lplaae;
  5745. //
  5746. // Note: the agent APIs are not exposed to 16-bit apps, so
  5747. // there's no reason to special case on gbNTVDMClient like
  5748. // lineDevSpecificPostProcess does
  5749. //
  5750. CopyMemory (lpAgentActivityList, (LPBYTE) (pMsg + 1), dwSize);
  5751. //
  5752. // Now some unicode->ascii post processing on embedded strings
  5753. //
  5754. lplaae = (LPLINEAGENTACTIVITYENTRY)(((LPBYTE)lpAgentActivityList) +
  5755. lpAgentActivityList->dwListOffset);
  5756. dwNumEntries = lpAgentActivityList->dwNumEntries;
  5757. for (dw = 0; dw < dwNumEntries; dw++, lplaae++)
  5758. {
  5759. WideStringToNotSoWideString(
  5760. (LPBYTE) lpAgentActivityList,
  5761. &(lplaae->dwNameSize)
  5762. );
  5763. }
  5764. }
  5765. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  5766. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  5767. {
  5768. pMsg->Param2 = LINEERR_INVALPOINTER;
  5769. }
  5770. }
  5771. }
  5772. LONG
  5773. WINAPI
  5774. lineGetAgentActivityListA(
  5775. HLINE hLine,
  5776. DWORD dwAddressID,
  5777. LPLINEAGENTACTIVITYLIST lpAgentActivityList
  5778. )
  5779. {
  5780. FUNC_ARGS funcArgs =
  5781. {
  5782. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentActivityList),
  5783. {
  5784. (ULONG_PTR) GetFunctionIndex(lineGetAgentActivityListAPostProcess),
  5785. (ULONG_PTR) hLine,
  5786. (ULONG_PTR) dwAddressID,
  5787. (ULONG_PTR) lpAgentActivityList,// pass the actual ptr (for ppproc)
  5788. (ULONG_PTR) lpAgentActivityList // pass data
  5789. },
  5790. {
  5791. Dword,
  5792. Dword,
  5793. Dword,
  5794. Dword,
  5795. lpGet_Struct,
  5796. }
  5797. };
  5798. DWORD hPointer = 0;
  5799. LONG lResult;
  5800. if ( !lpAgentActivityList )
  5801. {
  5802. return LINEERR_INVALPOINTER;
  5803. }
  5804. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentActivityList, NULL);
  5805. if (0 == hPointer)
  5806. {
  5807. return LINEERR_NOMEM;
  5808. }
  5809. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  5810. lResult = DOFUNC (&funcArgs, "lineGetAgentActivityListA");
  5811. if (0 > lResult)
  5812. {
  5813. DereferenceObject (ghHandleTable, hPointer, 1);
  5814. }
  5815. return lResult;
  5816. }
  5817. LONG
  5818. WINAPI
  5819. lineGetAgentCapsW(
  5820. HLINEAPP hLineApp,
  5821. DWORD dwDeviceID,
  5822. DWORD dwAddressID,
  5823. DWORD dwAppAPIVersion,
  5824. LPLINEAGENTCAPS lpAgentCaps
  5825. )
  5826. {
  5827. FUNC_ARGS funcArgs =
  5828. {
  5829. MAKELONG (LINE_FUNC | ASYNC | 7, lGetAgentCaps),
  5830. {
  5831. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  5832. (ULONG_PTR) hLineApp,
  5833. (ULONG_PTR) dwDeviceID,
  5834. (ULONG_PTR) dwAddressID,
  5835. (ULONG_PTR) dwAppAPIVersion,
  5836. (ULONG_PTR) lpAgentCaps, // pass the actual ptr (for ppproc)
  5837. (ULONG_PTR) lpAgentCaps // pass data
  5838. },
  5839. {
  5840. Dword,
  5841. hXxxApp,
  5842. Dword,
  5843. Dword,
  5844. Dword,
  5845. Dword,
  5846. lpGet_Struct,
  5847. }
  5848. };
  5849. DWORD hPointer = 0;
  5850. LONG lResult;
  5851. if ( !lpAgentCaps )
  5852. {
  5853. return LINEERR_INVALPOINTER;
  5854. }
  5855. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentCaps, NULL);
  5856. if (0 == hPointer)
  5857. {
  5858. return LINEERR_NOMEM;
  5859. }
  5860. funcArgs.Args[5] = (ULONG_PTR)hPointer;
  5861. lResult = DOFUNC (&funcArgs, "lineGetAgentCapsW");
  5862. if (0 > lResult)
  5863. {
  5864. DereferenceObject (ghHandleTable, hPointer, 1);
  5865. }
  5866. return lResult;
  5867. }
  5868. void
  5869. PASCAL
  5870. lineGetAgentCapsAPostProcess(
  5871. PASYNCEVENTMSG pMsg
  5872. )
  5873. {
  5874. LOG((TL_TRACE, "lineGetAgentCapsAPostProcess: enter"));
  5875. LOG((TL_INFO,
  5876. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  5877. pMsg->Param1,
  5878. pMsg->Param2,
  5879. pMsg->Param3,
  5880. pMsg->Param4
  5881. ));
  5882. if (pMsg->Param2 == 0)
  5883. {
  5884. DWORD dwSize = (DWORD) pMsg->Param4;
  5885. LPLINEAGENTCAPS lpAgentCaps = (LPLINEAGENTCAPS) ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  5886. // We don't need the handle to the pointer any more...
  5887. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  5888. try
  5889. {
  5890. //
  5891. // Note: the agent APIs are not exposed to 16-bit apps, so
  5892. // there's no reason to special case on gbNTVDMClient like
  5893. // lineDevSpecificPostProcess does
  5894. //
  5895. CopyMemory (lpAgentCaps, (LPBYTE) (pMsg + 1), dwSize);
  5896. //
  5897. // Now some unicode->ascii post processing on embedded strings
  5898. //
  5899. WideStringToNotSoWideString(
  5900. (LPBYTE) lpAgentCaps,
  5901. &lpAgentCaps->dwAgentHandlerInfoSize
  5902. );
  5903. }
  5904. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  5905. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  5906. {
  5907. pMsg->Param2 = LINEERR_INVALPOINTER;
  5908. }
  5909. }
  5910. }
  5911. LONG
  5912. WINAPI
  5913. lineGetAgentCapsA(
  5914. HLINEAPP hLineApp,
  5915. DWORD dwDeviceID,
  5916. DWORD dwAddressID,
  5917. DWORD dwAppAPIVersion,
  5918. LPLINEAGENTCAPS lpAgentCaps
  5919. )
  5920. {
  5921. FUNC_ARGS funcArgs =
  5922. {
  5923. MAKELONG (LINE_FUNC | ASYNC | 7, lGetAgentCaps),
  5924. {
  5925. (ULONG_PTR) GetFunctionIndex(lineGetAgentCapsAPostProcess),
  5926. (ULONG_PTR) hLineApp,
  5927. (ULONG_PTR) dwDeviceID,
  5928. (ULONG_PTR) dwAddressID,
  5929. (ULONG_PTR) dwAppAPIVersion,
  5930. (ULONG_PTR) lpAgentCaps, // pass the actual ptr (for ppproc)
  5931. (ULONG_PTR) lpAgentCaps // pass data
  5932. },
  5933. {
  5934. Dword,
  5935. hXxxApp,
  5936. Dword,
  5937. Dword,
  5938. Dword,
  5939. Dword,
  5940. lpGet_Struct,
  5941. }
  5942. };
  5943. DWORD hPointer = 0;
  5944. LONG lResult;
  5945. if ( !lpAgentCaps )
  5946. {
  5947. return LINEERR_INVALPOINTER;
  5948. }
  5949. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentCaps, NULL);
  5950. if (0 == hPointer)
  5951. {
  5952. return LINEERR_NOMEM;
  5953. }
  5954. funcArgs.Args[5] = (ULONG_PTR)hPointer;
  5955. lResult = DOFUNC (&funcArgs, "lineGetAgentCapsA");
  5956. if (0 > lResult)
  5957. {
  5958. DereferenceObject (ghHandleTable, hPointer, 1);
  5959. }
  5960. return lResult;
  5961. }
  5962. LONG
  5963. WINAPI
  5964. lineGetAgentGroupListW(
  5965. HLINE hLine,
  5966. DWORD dwAddressID,
  5967. LPLINEAGENTGROUPLIST lpAgentGroupList
  5968. )
  5969. {
  5970. FUNC_ARGS funcArgs =
  5971. {
  5972. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentGroupList),
  5973. {
  5974. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  5975. (ULONG_PTR) hLine,
  5976. (ULONG_PTR) dwAddressID,
  5977. (ULONG_PTR) lpAgentGroupList, // pass the actual ptr (for ppproc)
  5978. (ULONG_PTR) lpAgentGroupList // pass data
  5979. },
  5980. {
  5981. Dword,
  5982. Dword,
  5983. Dword,
  5984. Dword,
  5985. lpGet_Struct,
  5986. }
  5987. };
  5988. DWORD hPointer = 0;
  5989. LONG lResult;
  5990. if ( !lpAgentGroupList )
  5991. {
  5992. return LINEERR_INVALPOINTER;
  5993. }
  5994. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentGroupList, NULL);
  5995. if (0 == hPointer)
  5996. {
  5997. return LINEERR_NOMEM;
  5998. }
  5999. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6000. lResult = DOFUNC (&funcArgs, "lineGetAgentGroupListW");
  6001. if (0 > lResult)
  6002. {
  6003. DereferenceObject (ghHandleTable, hPointer, 1);
  6004. }
  6005. return lResult;
  6006. }
  6007. void
  6008. PASCAL
  6009. lineGetAgentGroupListAPostProcess(
  6010. PASYNCEVENTMSG pMsg
  6011. )
  6012. {
  6013. LOG((TL_TRACE, "lineGetAgentGroupListAPostProcess: enter"));
  6014. LOG((TL_INFO,
  6015. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  6016. pMsg->Param1,
  6017. pMsg->Param2,
  6018. pMsg->Param3,
  6019. pMsg->Param4
  6020. ));
  6021. if (pMsg->Param2 == 0)
  6022. {
  6023. DWORD dwSize = (DWORD) pMsg->Param4;
  6024. LPLINEAGENTGROUPLIST lpAgentGroupList = (LPLINEAGENTGROUPLIST)
  6025. ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  6026. // We don't need the handle to the pointer any more...
  6027. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  6028. try
  6029. {
  6030. DWORD dw, dwNumEntries;
  6031. LPLINEAGENTGROUPENTRY lplage;
  6032. //
  6033. // Note: the agent APIs are not exposed to 16-bit apps, so
  6034. // there's no reason to special case on gbNTVDMClient like
  6035. // lineDevSpecificPostProcess does
  6036. //
  6037. CopyMemory (lpAgentGroupList, (LPBYTE) (pMsg + 1), dwSize);
  6038. //
  6039. // Now some unicode->ascii post processing on embedded strings
  6040. //
  6041. lplage = (LPLINEAGENTGROUPENTRY)(((LPBYTE) lpAgentGroupList) +
  6042. lpAgentGroupList->dwListOffset);
  6043. dwNumEntries = lpAgentGroupList->dwNumEntries;
  6044. for (dw = 0; dw < dwNumEntries; dw++, lplage++)
  6045. {
  6046. WideStringToNotSoWideString(
  6047. (LPBYTE) lpAgentGroupList,
  6048. &(lplage->dwNameSize)
  6049. );
  6050. }
  6051. }
  6052. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  6053. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  6054. {
  6055. pMsg->Param2 = LINEERR_INVALPOINTER;
  6056. }
  6057. }
  6058. }
  6059. LONG
  6060. WINAPI
  6061. lineGetAgentGroupListA(
  6062. HLINE hLine,
  6063. DWORD dwAddressID,
  6064. LPLINEAGENTGROUPLIST lpAgentGroupList
  6065. )
  6066. {
  6067. FUNC_ARGS funcArgs =
  6068. {
  6069. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentGroupList),
  6070. {
  6071. (ULONG_PTR) GetFunctionIndex(lineGetAgentGroupListAPostProcess),
  6072. (ULONG_PTR) hLine,
  6073. (ULONG_PTR) dwAddressID,
  6074. (ULONG_PTR) lpAgentGroupList, // pass the actual ptr (for ppproc)
  6075. (ULONG_PTR) lpAgentGroupList // pass data
  6076. },
  6077. {
  6078. Dword,
  6079. Dword,
  6080. Dword,
  6081. Dword,
  6082. lpGet_Struct,
  6083. }
  6084. };
  6085. DWORD hPointer = 0;
  6086. LONG lResult;
  6087. if ( !lpAgentGroupList )
  6088. {
  6089. return LINEERR_INVALPOINTER;
  6090. }
  6091. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentGroupList, NULL);
  6092. if (0 == hPointer)
  6093. {
  6094. return LINEERR_NOMEM;
  6095. }
  6096. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6097. lResult = DOFUNC (&funcArgs, "lineGetAgentGroupListA");
  6098. if (0 > lResult)
  6099. {
  6100. DereferenceObject (ghHandleTable, hPointer, 1);
  6101. }
  6102. return lResult;
  6103. }
  6104. LONG
  6105. WINAPI
  6106. lineGetAgentInfo(
  6107. HLINE hLine,
  6108. HAGENT hAgent,
  6109. LPLINEAGENTINFO lpAgentInfo
  6110. )
  6111. {
  6112. FUNC_ARGS funcArgs =
  6113. {
  6114. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentInfo),
  6115. {
  6116. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  6117. (ULONG_PTR) hLine,
  6118. (ULONG_PTR) hAgent,
  6119. (ULONG_PTR) lpAgentInfo, // pass the actual ptr (for ppproc)
  6120. (ULONG_PTR) lpAgentInfo // pass data
  6121. },
  6122. {
  6123. Dword,
  6124. Dword,
  6125. Dword,
  6126. Dword,
  6127. lpGet_Struct,
  6128. }
  6129. };
  6130. DWORD hPointer = 0;
  6131. LONG lResult;
  6132. if ( !lpAgentInfo )
  6133. {
  6134. return LINEERR_INVALPOINTER;
  6135. }
  6136. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentInfo, NULL);
  6137. if (0 == hPointer)
  6138. {
  6139. return LINEERR_NOMEM;
  6140. }
  6141. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6142. lResult = DOFUNC (&funcArgs, "lineGetAgentInfo");
  6143. if (0 > lResult)
  6144. {
  6145. DereferenceObject (ghHandleTable, hPointer, 1);
  6146. }
  6147. return lResult;
  6148. }
  6149. LONG
  6150. WINAPI
  6151. lineGetAgentSessionInfo(
  6152. HLINE hLine,
  6153. HAGENTSESSION hAgentSession,
  6154. LPLINEAGENTSESSIONINFO lpAgentSessionInfo
  6155. )
  6156. {
  6157. FUNC_ARGS funcArgs =
  6158. {
  6159. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentSessionInfo),
  6160. {
  6161. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  6162. (ULONG_PTR) hLine,
  6163. (ULONG_PTR) hAgentSession,
  6164. (ULONG_PTR) lpAgentSessionInfo, // pass the actual ptr (for ppproc)
  6165. (ULONG_PTR) lpAgentSessionInfo // pass data
  6166. },
  6167. {
  6168. Dword,
  6169. Dword,
  6170. Dword,
  6171. Dword,
  6172. lpGet_Struct,
  6173. }
  6174. };
  6175. DWORD hPointer = 0;
  6176. LONG lResult;
  6177. if ( !lpAgentSessionInfo )
  6178. {
  6179. return LINEERR_INVALPOINTER;
  6180. }
  6181. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentSessionInfo, NULL);
  6182. if (0 == hPointer)
  6183. {
  6184. return LINEERR_NOMEM;
  6185. }
  6186. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6187. lResult = DOFUNC (&funcArgs, "lineGetAgentSessionInfo");
  6188. if (0 > lResult)
  6189. {
  6190. DereferenceObject (ghHandleTable, hPointer, 1);
  6191. }
  6192. return lResult;
  6193. }
  6194. LONG
  6195. WINAPI
  6196. lineGetAgentSessionList(
  6197. HLINE hLine,
  6198. HAGENT hAgent,
  6199. LPLINEAGENTSESSIONLIST lpAgentSessionList
  6200. )
  6201. {
  6202. FUNC_ARGS funcArgs =
  6203. {
  6204. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentSessionList),
  6205. {
  6206. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  6207. (ULONG_PTR) hLine,
  6208. (ULONG_PTR) hAgent,
  6209. (ULONG_PTR) lpAgentSessionList, // pass the actual ptr (for ppproc)
  6210. (ULONG_PTR) lpAgentSessionList // pass data
  6211. },
  6212. {
  6213. Dword,
  6214. Dword,
  6215. Dword,
  6216. Dword,
  6217. lpGet_Struct,
  6218. }
  6219. };
  6220. DWORD hPointer = 0;
  6221. LONG lResult;
  6222. if ( !lpAgentSessionList )
  6223. {
  6224. return LINEERR_INVALPARAM;
  6225. }
  6226. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentSessionList, NULL);
  6227. if (0 == hPointer)
  6228. {
  6229. return LINEERR_NOMEM;
  6230. }
  6231. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6232. lResult = DOFUNC (&funcArgs, "lineGetAgentSessionList");
  6233. if (0 > lResult)
  6234. {
  6235. DereferenceObject (ghHandleTable, hPointer, 1);
  6236. }
  6237. return lResult;
  6238. }
  6239. LONG
  6240. WINAPI
  6241. lineGetAgentStatusW(
  6242. HLINE hLine,
  6243. DWORD dwAddressID,
  6244. LPLINEAGENTSTATUS lpAgentStatus
  6245. )
  6246. {
  6247. FUNC_ARGS funcArgs =
  6248. {
  6249. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentStatus),
  6250. {
  6251. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  6252. (ULONG_PTR) hLine,
  6253. (ULONG_PTR) dwAddressID,
  6254. (ULONG_PTR) lpAgentStatus, // pass the actual ptr (for ppproc)
  6255. (ULONG_PTR) lpAgentStatus // pass data
  6256. },
  6257. {
  6258. Dword,
  6259. Dword,
  6260. Dword,
  6261. Dword,
  6262. lpGet_Struct,
  6263. }
  6264. };
  6265. DWORD hPointer = 0;
  6266. LONG lResult;
  6267. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentStatus, NULL);
  6268. if (0 == hPointer)
  6269. {
  6270. return LINEERR_NOMEM;
  6271. }
  6272. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6273. lResult = DOFUNC (&funcArgs, "lineGetAgentStatusW");
  6274. if (0 > lResult)
  6275. {
  6276. DereferenceObject (ghHandleTable, hPointer, 1);
  6277. }
  6278. return lResult;
  6279. }
  6280. void
  6281. PASCAL
  6282. lineGetAgentStatusAPostProcess(
  6283. PASYNCEVENTMSG pMsg
  6284. )
  6285. {
  6286. LOG((TL_TRACE, "lineGetAgentStatusAPostProcess: enter"));
  6287. LOG((TL_INFO,
  6288. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  6289. pMsg->Param1,
  6290. pMsg->Param2,
  6291. pMsg->Param3,
  6292. pMsg->Param4
  6293. ));
  6294. if (pMsg->Param2 == 0)
  6295. {
  6296. DWORD dwSize = (DWORD) pMsg->Param4;
  6297. LPLINEAGENTSTATUS lpAgentStatus = (LPLINEAGENTSTATUS) ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  6298. // We don't need the handle to the pointer any more...
  6299. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  6300. try
  6301. {
  6302. DWORD dw, dwNumEntries;
  6303. LPLINEAGENTGROUPENTRY lplage;
  6304. //
  6305. // Note: the agent APIs are not exposed to 16-bit apps, so
  6306. // there's no reason to special case on gbNTVDMClient like
  6307. // lineDevSpecificPostProcess does
  6308. //
  6309. CopyMemory (lpAgentStatus, (LPBYTE) (pMsg + 1), dwSize);
  6310. //
  6311. // Now some unicode->ascii post processing on embedded strings
  6312. //
  6313. lplage = (LPLINEAGENTGROUPENTRY) (((LPBYTE) lpAgentStatus) +
  6314. lpAgentStatus->dwGroupListOffset);
  6315. dwNumEntries = lpAgentStatus->dwNumEntries;
  6316. for (dw = 0; dw < dwNumEntries; dw++, lplage++)
  6317. {
  6318. WideStringToNotSoWideString(
  6319. (LPBYTE)lpAgentStatus,
  6320. &(lplage->dwNameSize)
  6321. );
  6322. }
  6323. WideStringToNotSoWideString(
  6324. (LPBYTE)lpAgentStatus,
  6325. &lpAgentStatus->dwActivitySize
  6326. );
  6327. }
  6328. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  6329. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  6330. {
  6331. pMsg->Param2 = LINEERR_INVALPOINTER;
  6332. }
  6333. }
  6334. }
  6335. LONG
  6336. WINAPI
  6337. lineGetAgentStatusA(
  6338. HLINE hLine,
  6339. DWORD dwAddressID,
  6340. LPLINEAGENTSTATUS lpAgentStatus
  6341. )
  6342. {
  6343. FUNC_ARGS funcArgs =
  6344. {
  6345. MAKELONG (LINE_FUNC | ASYNC | 5, lGetAgentStatus),
  6346. {
  6347. (ULONG_PTR) GetFunctionIndex(lineGetAgentStatusAPostProcess),
  6348. (ULONG_PTR) hLine,
  6349. (ULONG_PTR) dwAddressID,
  6350. (ULONG_PTR) lpAgentStatus, // pass the actual ptr (for ppproc)
  6351. (ULONG_PTR) lpAgentStatus // pass data
  6352. },
  6353. {
  6354. Dword,
  6355. Dword,
  6356. Dword,
  6357. Dword,
  6358. lpGet_Struct,
  6359. }
  6360. };
  6361. DWORD hPointer = 0;
  6362. LONG lResult;
  6363. hPointer = NewObject (ghHandleTable, (PVOID)lpAgentStatus, NULL);
  6364. if (0 == hPointer)
  6365. {
  6366. return LINEERR_NOMEM;
  6367. }
  6368. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  6369. lResult = (DOFUNC (&funcArgs, "lineGetAgentStatusA"));
  6370. if (0 > lResult)
  6371. {
  6372. DereferenceObject (ghHandleTable, hPointer, 1);
  6373. }
  6374. return lResult;
  6375. }
  6376. LONG
  6377. WINAPI
  6378. lineGetAppPriorityW(
  6379. LPCWSTR lpszAppName,
  6380. DWORD dwMediaMode,
  6381. LPLINEEXTENSIONID lpExtensionID,
  6382. DWORD dwRequestMode,
  6383. LPVARSTRING lpExtensionName,
  6384. LPDWORD lpdwPriority
  6385. )
  6386. {
  6387. FUNC_ARGS funcArgs =
  6388. {
  6389. MAKELONG (LINE_FUNC | SYNC | 7, lGetAppPriority),
  6390. {
  6391. (ULONG_PTR) lpszAppName,
  6392. (ULONG_PTR) dwMediaMode,
  6393. (ULONG_PTR) 0,
  6394. (ULONG_PTR) 0,
  6395. (ULONG_PTR) dwRequestMode,
  6396. (ULONG_PTR) 0,
  6397. (ULONG_PTR) lpdwPriority
  6398. },
  6399. {
  6400. lpszW, // app name
  6401. Dword, // media mode
  6402. Dword, // ext id (offset)
  6403. Dword, // ext id (size)
  6404. Dword, // request mode
  6405. Dword, // ext name total size
  6406. lpDword // lp pri
  6407. }
  6408. };
  6409. if (dwMediaMode & 0xff000000)
  6410. {
  6411. if ((LPVOID) lpExtensionName == (LPVOID) lpdwPriority)
  6412. {
  6413. return LINEERR_INVALPOINTER;
  6414. }
  6415. //
  6416. // We have to do some arg list munging here (adding an extra arg)
  6417. //
  6418. //
  6419. // Set lpExtensionID, the following Size arg,
  6420. // lpExtensionName, and the following MinSize
  6421. // Type's and Value appropriately since they're
  6422. // valid args in this case
  6423. //
  6424. funcArgs.ArgTypes[2] = lpSet_SizeToFollow;
  6425. funcArgs.Args[2] = (ULONG_PTR) lpExtensionID;
  6426. funcArgs.ArgTypes[3] = Size;
  6427. funcArgs.Args[3] = (ULONG_PTR) sizeof (LINEEXTENSIONID);
  6428. funcArgs.ArgTypes[5] = lpGet_Struct;
  6429. funcArgs.Args[5] = (ULONG_PTR) lpExtensionName;
  6430. }
  6431. if ( TAPIIsBadStringPtrW(lpszAppName, (UINT)-1) )
  6432. {
  6433. LOG((TL_ERROR, "Bad lpszDestAddress in lineGetAppPriorityW"));
  6434. return( LINEERR_INVALPOINTER );
  6435. }
  6436. return (DOFUNC (&funcArgs, "lineGetAppPriority"));
  6437. }
  6438. LONG
  6439. WINAPI
  6440. lineGetAppPriorityA(
  6441. LPCSTR lpszAppName,
  6442. DWORD dwMediaMode,
  6443. LPLINEEXTENSIONID lpExtensionID,
  6444. DWORD dwRequestMode,
  6445. LPVARSTRING lpExtensionName,
  6446. LPDWORD lpdwPriority
  6447. )
  6448. {
  6449. LONG lResult;
  6450. FUNC_ARGS funcArgs =
  6451. {
  6452. MAKELONG (LINE_FUNC | SYNC | 7, lGetAppPriority),
  6453. {
  6454. (ULONG_PTR) 0, // (DWORD) lpszAppName,
  6455. (ULONG_PTR) dwMediaMode,
  6456. (ULONG_PTR) 0,
  6457. (ULONG_PTR) 0,
  6458. (ULONG_PTR) dwRequestMode,
  6459. (ULONG_PTR) 0,
  6460. (ULONG_PTR) lpdwPriority
  6461. },
  6462. {
  6463. lpszW, // app name
  6464. Dword, // media mode
  6465. Dword, // ext id (offset)
  6466. Dword, // ext id (size)
  6467. Dword, // request mode
  6468. Dword, // ext name total size
  6469. lpDword // lp pri
  6470. }
  6471. };
  6472. if (dwMediaMode & 0xff000000)
  6473. {
  6474. //
  6475. // We have to do some arg list munging here (adding an extra arg)
  6476. //
  6477. //
  6478. // Set lpExtensionID, the following Size arg,
  6479. // lpExtensionName, and the following MinSize
  6480. // Type's and Value appropriately since they're
  6481. // valid args in this case
  6482. //
  6483. funcArgs.ArgTypes[2] = lpSet_SizeToFollow;
  6484. funcArgs.Args[2] = (ULONG_PTR) lpExtensionID;
  6485. funcArgs.ArgTypes[3] = Size;
  6486. funcArgs.Args[3] = (ULONG_PTR) sizeof (LINEEXTENSIONID);
  6487. funcArgs.ArgTypes[5] = lpGet_Struct;
  6488. funcArgs.Args[5] = (ULONG_PTR) lpExtensionName;
  6489. }
  6490. if ( IsBadStringPtrA(lpszAppName, (UINT)-1) )
  6491. {
  6492. LOG((TL_ERROR, "Bad lpszDestAddress in lineGetAppPriorityA"));
  6493. return( LINEERR_INVALPOINTER );
  6494. }
  6495. funcArgs.Args[0] = (ULONG_PTR) NotSoWideStringToWideString(
  6496. lpszAppName,
  6497. (DWORD) -1
  6498. );
  6499. lResult = (DOFUNC (&funcArgs, "lineGetAppPriority"));
  6500. if (funcArgs.Args[0])
  6501. {
  6502. ClientFree ((LPVOID) funcArgs.Args[0]);
  6503. }
  6504. return lResult;
  6505. }
  6506. LONG
  6507. WINAPI
  6508. lineGetAppPriority(
  6509. LPCSTR lpszAppName,
  6510. DWORD dwMediaMode,
  6511. LPLINEEXTENSIONID lpExtensionID,
  6512. DWORD dwRequestMode,
  6513. LPVARSTRING lpExtensionName,
  6514. LPDWORD lpdwPriority
  6515. )
  6516. {
  6517. return lineGetAppPriorityA(
  6518. lpszAppName,
  6519. dwMediaMode,
  6520. lpExtensionID,
  6521. dwRequestMode,
  6522. lpExtensionName,
  6523. lpdwPriority
  6524. );
  6525. }
  6526. LONG
  6527. WINAPI
  6528. lineGetCallInfoW(
  6529. HCALL hCall,
  6530. LPLINECALLINFO lpCallInfo
  6531. )
  6532. {
  6533. FUNC_ARGS funcArgs =
  6534. {
  6535. MAKELONG (LINE_FUNC | SYNC | 2, lGetCallInfo),
  6536. {
  6537. (ULONG_PTR) hCall,
  6538. (ULONG_PTR) lpCallInfo
  6539. },
  6540. {
  6541. Dword,
  6542. lpGet_Struct
  6543. }
  6544. };
  6545. return (DOFUNC (&funcArgs, "lineGetCallInfo"));
  6546. }
  6547. LONG
  6548. WINAPI
  6549. lineGetCallInfoA(
  6550. HCALL hCall,
  6551. LPLINECALLINFO lpCallInfo
  6552. )
  6553. {
  6554. LONG lResult;
  6555. lResult = lineGetCallInfoW(
  6556. hCall,
  6557. lpCallInfo
  6558. );
  6559. if ( 0 == lResult )
  6560. {
  6561. WideStringToNotSoWideString(
  6562. (LPBYTE)lpCallInfo,
  6563. &(lpCallInfo->dwCallerIDSize)
  6564. );
  6565. WideStringToNotSoWideString(
  6566. (LPBYTE)lpCallInfo,
  6567. &(lpCallInfo->dwCallerIDNameSize)
  6568. );
  6569. WideStringToNotSoWideString(
  6570. (LPBYTE)lpCallInfo,
  6571. &(lpCallInfo->dwCalledIDSize)
  6572. );
  6573. WideStringToNotSoWideString(
  6574. (LPBYTE)lpCallInfo,
  6575. &(lpCallInfo->dwCalledIDNameSize)
  6576. );
  6577. WideStringToNotSoWideString(
  6578. (LPBYTE)lpCallInfo,
  6579. &(lpCallInfo->dwConnectedIDSize)
  6580. );
  6581. WideStringToNotSoWideString(
  6582. (LPBYTE)lpCallInfo,
  6583. &(lpCallInfo->dwConnectedIDNameSize)
  6584. );
  6585. WideStringToNotSoWideString(
  6586. (LPBYTE)lpCallInfo,
  6587. &(lpCallInfo->dwRedirectionIDSize)
  6588. );
  6589. WideStringToNotSoWideString(
  6590. (LPBYTE)lpCallInfo,
  6591. &(lpCallInfo->dwRedirectionIDNameSize)
  6592. );
  6593. WideStringToNotSoWideString(
  6594. (LPBYTE)lpCallInfo,
  6595. &(lpCallInfo->dwRedirectingIDSize)
  6596. );
  6597. WideStringToNotSoWideString(
  6598. (LPBYTE)lpCallInfo,
  6599. &(lpCallInfo->dwRedirectingIDNameSize)
  6600. );
  6601. WideStringToNotSoWideString(
  6602. (LPBYTE)lpCallInfo,
  6603. &(lpCallInfo->dwAppNameSize)
  6604. );
  6605. WideStringToNotSoWideString(
  6606. (LPBYTE)lpCallInfo,
  6607. &(lpCallInfo->dwDisplayableAddressSize)
  6608. );
  6609. WideStringToNotSoWideString(
  6610. (LPBYTE)lpCallInfo,
  6611. &(lpCallInfo->dwCalledPartySize)
  6612. );
  6613. WideStringToNotSoWideString(
  6614. (LPBYTE)lpCallInfo,
  6615. &(lpCallInfo->dwCommentSize)
  6616. );
  6617. /*
  6618. //
  6619. // Note: per TNixon (3/21/96), none of the following are guaranteed
  6620. // to be in ascii format, so we don't want to convert them
  6621. //
  6622. WideStringToNotSoWideString(
  6623. (LPBYTE)lpCallInfo,
  6624. &(lpCallInfo->dwDisplaySize)
  6625. );
  6626. WideStringToNotSoWideString(
  6627. (LPBYTE)lpCallInfo,
  6628. &(lpCallInfo->dwHighLevelCompSize)
  6629. );
  6630. WideStringToNotSoWideString(
  6631. (LPBYTE)lpCallInfo,
  6632. &(lpCallInfo->dwLowLevelCompSize)
  6633. );
  6634. WideStringToNotSoWideString(
  6635. (LPBYTE)lpCallInfo,
  6636. &(lpCallInfo->dwChargingInfoSize)
  6637. );
  6638. */
  6639. }
  6640. return lResult;
  6641. }
  6642. LONG
  6643. WINAPI
  6644. lineGetCallInfo(
  6645. HCALL hCall,
  6646. LPLINECALLINFO lpCallInfo
  6647. )
  6648. {
  6649. return lineGetCallInfoA(
  6650. hCall,
  6651. lpCallInfo
  6652. );
  6653. }
  6654. LONG
  6655. WINAPI
  6656. lineGetCallStatus(
  6657. HCALL hCall,
  6658. LPLINECALLSTATUS lpCallStatus
  6659. )
  6660. {
  6661. FUNC_ARGS funcArgs =
  6662. {
  6663. MAKELONG (LINE_FUNC | SYNC | 2, lGetCallStatus),
  6664. {
  6665. (ULONG_PTR) hCall,
  6666. (ULONG_PTR) lpCallStatus
  6667. },
  6668. {
  6669. Dword,
  6670. lpGet_Struct
  6671. }
  6672. };
  6673. return (DOFUNC (&funcArgs, "lineGetCallStatus"));
  6674. }
  6675. LONG
  6676. WINAPI
  6677. lineGetConfRelatedCalls(
  6678. HCALL hCall,
  6679. LPLINECALLLIST lpCallList
  6680. )
  6681. {
  6682. FUNC_ARGS funcArgs =
  6683. {
  6684. MAKELONG (LINE_FUNC | SYNC| 2, lGetConfRelatedCalls),
  6685. {
  6686. (ULONG_PTR) hCall,
  6687. (ULONG_PTR) lpCallList
  6688. },
  6689. {
  6690. Dword,
  6691. lpGet_Struct
  6692. }
  6693. };
  6694. return (DOFUNC (&funcArgs, "lineGetConfRelatedCalls"));
  6695. }
  6696. LONG
  6697. WINAPI
  6698. lineGetCountryW(
  6699. DWORD dwCountryID,
  6700. DWORD dwAPIVersion,
  6701. LPLINECOUNTRYLIST lpLineCountryList
  6702. )
  6703. {
  6704. FUNC_ARGS funcArgs =
  6705. {
  6706. MAKELONG (LINE_FUNC | SYNC | 4, lGetCountry),
  6707. {
  6708. (ULONG_PTR) dwCountryID,
  6709. (ULONG_PTR) dwAPIVersion,
  6710. (ULONG_PTR) 0,
  6711. (ULONG_PTR) lpLineCountryList
  6712. },
  6713. {
  6714. Dword,
  6715. Dword,
  6716. Dword,
  6717. lpGet_Struct
  6718. }
  6719. };
  6720. if (
  6721. ( TAPI_CURRENT_VERSION != dwAPIVersion )
  6722. &&
  6723. ( 0x00020001 != dwAPIVersion )
  6724. &&
  6725. ( 0x00020000 != dwAPIVersion )
  6726. &&
  6727. ( 0x00010004 != dwAPIVersion )
  6728. &&
  6729. ( 0x00010003 != dwAPIVersion )
  6730. )
  6731. {
  6732. LOG((TL_ERROR, "lineGetCountryW - bad API version 0x%08lx", dwAPIVersion));
  6733. return LINEERR_INCOMPATIBLEAPIVERSION;
  6734. }
  6735. return (DOFUNC (&funcArgs, "lineGetCountry"));
  6736. }
  6737. LONG
  6738. WINAPI
  6739. lineGetCountryA(
  6740. DWORD dwCountryID,
  6741. DWORD dwAPIVersion,
  6742. LPLINECOUNTRYLIST lpLineCountryList
  6743. )
  6744. {
  6745. LONG lResult;
  6746. DWORD n;
  6747. lResult = lineGetCountryW (dwCountryID, dwAPIVersion, lpLineCountryList);
  6748. if (lResult == 0)
  6749. {
  6750. //
  6751. // Go through the list of countries and change from Unicode to ANSI
  6752. //
  6753. LPLINECOUNTRYENTRY lpce;
  6754. lpce = (LPLINECOUNTRYENTRY) (((LPBYTE) lpLineCountryList) +
  6755. lpLineCountryList->dwCountryListOffset);
  6756. for (n = 0; n < lpLineCountryList->dwNumCountries; n++, lpce++)
  6757. {
  6758. WideStringToNotSoWideString(
  6759. (LPBYTE)lpLineCountryList,
  6760. &lpce->dwCountryNameSize
  6761. );
  6762. WideStringToNotSoWideString(
  6763. (LPBYTE)lpLineCountryList,
  6764. &lpce->dwSameAreaRuleSize
  6765. );
  6766. WideStringToNotSoWideString(
  6767. (LPBYTE)lpLineCountryList,
  6768. &lpce->dwLongDistanceRuleSize
  6769. );
  6770. WideStringToNotSoWideString(
  6771. (LPBYTE)lpLineCountryList,
  6772. &lpce->dwInternationalRuleSize
  6773. );
  6774. }
  6775. }
  6776. return lResult;
  6777. }
  6778. LONG
  6779. WINAPI
  6780. lineGetCountry(
  6781. DWORD dwCountryID,
  6782. DWORD dwAPIVersion,
  6783. LPLINECOUNTRYLIST lpLineCountryList
  6784. )
  6785. {
  6786. LPLINECOUNTRYLIST pTempList;
  6787. LONG lResult;
  6788. DWORD dwSize;
  6789. if ( IsBadWritePtr(lpLineCountryList, sizeof(LINECOUNTRYLIST)) )
  6790. {
  6791. LOG((TL_ERROR,
  6792. "lineGetCountry - bad pointer: lpLineCountryList [0x%p]",
  6793. lpLineCountryList
  6794. ));
  6795. return LINEERR_INVALPOINTER;
  6796. }
  6797. if ( lpLineCountryList->dwTotalSize < sizeof(LINECOUNTRYLIST) )
  6798. {
  6799. LOG((TL_ERROR,
  6800. "lineGetCountry - dwTotalSize less than sizeof(LINECOUNTRYLIST)"
  6801. ));
  6802. return LINEERR_INVALPOINTER;
  6803. }
  6804. dwSize = lpLineCountryList->dwTotalSize * 2;
  6805. while (TRUE)
  6806. {
  6807. pTempList = ClientAlloc( dwSize );
  6808. if (NULL == pTempList)
  6809. {
  6810. LOG((TL_ERROR,
  6811. "lineGetCountry - alloc failed for [x%lx] bytes",
  6812. dwSize
  6813. ));
  6814. return( LINEERR_NOMEM );
  6815. }
  6816. pTempList->dwTotalSize = dwSize;
  6817. lResult = lineGetCountryA(
  6818. dwCountryID,
  6819. dwAPIVersion,
  6820. pTempList
  6821. );
  6822. // hack - if the structure isn't big enough
  6823. // realloc ourselves.
  6824. if (pTempList->dwNeededSize <= pTempList->dwTotalSize)
  6825. {
  6826. break;
  6827. }
  6828. dwSize = pTempList->dwNeededSize;
  6829. ClientFree( pTempList );
  6830. pTempList = NULL;
  6831. } // while
  6832. if ( 0 == lResult )
  6833. {
  6834. DWORD dwNewUsedSize = 0; // = sizeof(LINECOUNTRYLIST);
  6835. DWORD i;
  6836. DWORD dwCurrentOffset = sizeof(LINECOUNTRYLIST) +
  6837. (sizeof(LINECOUNTRYENTRY) * pTempList->dwNumCountries);
  6838. LPLINECOUNTRYENTRY pOldCountryEntry;
  6839. LPLINECOUNTRYENTRY pNewCountryEntry;
  6840. for (
  6841. i=0;
  6842. (i < pTempList->dwNumCountries);
  6843. i++
  6844. )
  6845. {
  6846. pOldCountryEntry = (LPLINECOUNTRYENTRY)
  6847. ((PBYTE)(lpLineCountryList + 1) +
  6848. (i * sizeof(LINECOUNTRYENTRY)));
  6849. pNewCountryEntry = (LPLINECOUNTRYENTRY)
  6850. ((PBYTE)(pTempList + 1) + (i * sizeof(LINECOUNTRYENTRY)));
  6851. // check to see if there is enough space in the buffer.
  6852. // add 1 because we're starting with an offset, and we
  6853. // need to convert it to a size.
  6854. dwNewUsedSize = dwCurrentOffset +
  6855. pNewCountryEntry->dwCountryNameSize +
  6856. pNewCountryEntry->dwSameAreaRuleSize +
  6857. pNewCountryEntry->dwLongDistanceRuleSize +
  6858. pNewCountryEntry->dwInternationalRuleSize +
  6859. 1;
  6860. if (lpLineCountryList->dwTotalSize < dwNewUsedSize)
  6861. {
  6862. // i is checked at the end, so
  6863. // subtract one here, because we're
  6864. // not actually copying this entry
  6865. // i--;
  6866. break;
  6867. }
  6868. pOldCountryEntry->dwCountryID =
  6869. pNewCountryEntry->dwCountryID;
  6870. pOldCountryEntry->dwCountryCode =
  6871. pNewCountryEntry->dwCountryCode;
  6872. pOldCountryEntry->dwNextCountryID =
  6873. pNewCountryEntry->dwNextCountryID;
  6874. pOldCountryEntry->dwCountryNameSize =
  6875. pNewCountryEntry->dwCountryNameSize;
  6876. pOldCountryEntry->dwSameAreaRuleSize =
  6877. pNewCountryEntry->dwSameAreaRuleSize;
  6878. pOldCountryEntry->dwLongDistanceRuleSize =
  6879. pNewCountryEntry->dwLongDistanceRuleSize;
  6880. pOldCountryEntry->dwInternationalRuleSize =
  6881. pNewCountryEntry->dwInternationalRuleSize;
  6882. //
  6883. // Copy Country name
  6884. //
  6885. CopyMemory(
  6886. (PBYTE)lpLineCountryList + dwCurrentOffset,
  6887. (PBYTE)pTempList + pNewCountryEntry->dwCountryNameOffset,
  6888. pNewCountryEntry->dwCountryNameSize
  6889. );
  6890. pOldCountryEntry->dwCountryNameOffset = dwCurrentOffset;
  6891. dwCurrentOffset += pNewCountryEntry->dwCountryNameSize;
  6892. //
  6893. // Copy same area rule
  6894. //
  6895. CopyMemory(
  6896. (PBYTE)lpLineCountryList + dwCurrentOffset,
  6897. (PBYTE)pTempList + pNewCountryEntry->dwSameAreaRuleOffset,
  6898. pNewCountryEntry->dwSameAreaRuleSize
  6899. );
  6900. pOldCountryEntry->dwSameAreaRuleOffset = dwCurrentOffset;
  6901. dwCurrentOffset += pNewCountryEntry->dwSameAreaRuleSize;
  6902. //
  6903. // Copy long distance rule
  6904. //
  6905. CopyMemory(
  6906. (PBYTE)lpLineCountryList + dwCurrentOffset,
  6907. (PBYTE)pTempList + pNewCountryEntry->dwLongDistanceRuleOffset,
  6908. pNewCountryEntry->dwLongDistanceRuleSize
  6909. );
  6910. pOldCountryEntry->dwLongDistanceRuleOffset = dwCurrentOffset;
  6911. dwCurrentOffset += pNewCountryEntry->dwLongDistanceRuleSize;
  6912. //
  6913. // Copy international rule
  6914. //
  6915. CopyMemory(
  6916. (PBYTE)lpLineCountryList + dwCurrentOffset,
  6917. (PBYTE)pTempList + pNewCountryEntry->dwInternationalRuleOffset,
  6918. pNewCountryEntry->dwInternationalRuleSize
  6919. );
  6920. pOldCountryEntry->dwInternationalRuleOffset = dwCurrentOffset;
  6921. dwCurrentOffset += pNewCountryEntry->dwInternationalRuleSize;
  6922. // dwNewUsedSize += sizeof(LINECOUNTRYENTRY) +
  6923. // pOldCountryEntry->dwCountryNameSize +
  6924. // pOldCountryEntry->dwSameAreaRuleSize +
  6925. // pOldCountryEntry->dwLongDistanceRuleSize +
  6926. // pOldCountryEntry->dwInternationalRuleSize ;
  6927. }
  6928. //
  6929. // Did we stop short?
  6930. //
  6931. if ( i < pTempList->dwNumCountries )
  6932. {
  6933. lpLineCountryList->dwNeededSize = pTempList->dwNeededSize;
  6934. }
  6935. else
  6936. {
  6937. lpLineCountryList->dwNeededSize = dwNewUsedSize;
  6938. lpLineCountryList->dwUsedSize = dwNewUsedSize;
  6939. lpLineCountryList->dwNumCountries = pTempList->dwNumCountries;
  6940. lpLineCountryList->dwCountryListSize =
  6941. pTempList->dwNumCountries * sizeof(LINECOUNTRYENTRY);
  6942. lpLineCountryList->dwCountryListOffset = sizeof(LINECOUNTRYLIST);
  6943. }
  6944. }
  6945. ClientFree( pTempList );
  6946. return lResult;
  6947. }
  6948. LONG
  6949. WINAPI
  6950. lineGetDevCapsW(
  6951. HLINEAPP hLineApp,
  6952. DWORD dwDeviceID,
  6953. DWORD dwAPIVersion,
  6954. DWORD dwExtVersion,
  6955. LPLINEDEVCAPS lpLineDevCaps
  6956. )
  6957. {
  6958. LONG lResult;
  6959. FUNC_ARGS funcArgs =
  6960. {
  6961. MAKELONG (LINE_FUNC | SYNC | 5, lGetDevCaps),
  6962. {
  6963. (ULONG_PTR) hLineApp,
  6964. (ULONG_PTR) dwDeviceID,
  6965. (ULONG_PTR) dwAPIVersion,
  6966. (ULONG_PTR) dwExtVersion,
  6967. (ULONG_PTR) lpLineDevCaps
  6968. },
  6969. {
  6970. hXxxApp,
  6971. Dword,
  6972. Dword,
  6973. Dword,
  6974. lpGet_Struct
  6975. }
  6976. };
  6977. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  6978. {
  6979. lResult = LINEERR_INCOMPATIBLEAPIVERSION;
  6980. goto ExitHere;
  6981. }
  6982. lResult = (DOFUNC (&funcArgs, "lineGetDevCaps"));
  6983. if ( 0 == lResult )
  6984. {
  6985. lpLineDevCaps->dwStringFormat = STRINGFORMAT_UNICODE;
  6986. }
  6987. ExitHere:
  6988. return lResult;
  6989. }
  6990. LONG
  6991. WINAPI
  6992. lineGetDevCapsA(
  6993. HLINEAPP hLineApp,
  6994. DWORD dwDeviceID,
  6995. DWORD dwAPIVersion,
  6996. DWORD dwExtVersion,
  6997. LPLINEDEVCAPS lpLineDevCaps
  6998. )
  6999. {
  7000. LONG lResult;
  7001. lResult = lineGetDevCapsW(
  7002. hLineApp,
  7003. dwDeviceID,
  7004. dwAPIVersion,
  7005. dwExtVersion,
  7006. lpLineDevCaps
  7007. );
  7008. if (lResult == 0)
  7009. {
  7010. lpLineDevCaps->dwStringFormat = STRINGFORMAT_ASCII;
  7011. WideStringToNotSoWideString(
  7012. (LPBYTE)lpLineDevCaps,
  7013. &lpLineDevCaps->dwProviderInfoSize
  7014. );
  7015. WideStringToNotSoWideString(
  7016. (LPBYTE)lpLineDevCaps,
  7017. &lpLineDevCaps->dwSwitchInfoSize
  7018. );
  7019. WideStringToNotSoWideString(
  7020. (LPBYTE)lpLineDevCaps,
  7021. &lpLineDevCaps->dwLineNameSize
  7022. );
  7023. WideStringToNotSoWideString(
  7024. (LPBYTE)lpLineDevCaps,
  7025. &lpLineDevCaps->dwTerminalTextSize
  7026. );
  7027. if (lpLineDevCaps->dwTerminalTextEntrySize)
  7028. {
  7029. lpLineDevCaps->dwTerminalTextEntrySize /= sizeof(WCHAR);
  7030. }
  7031. if (dwAPIVersion >= 0x00020000)
  7032. {
  7033. WideStringToNotSoWideString(
  7034. (LPBYTE) lpLineDevCaps,
  7035. &lpLineDevCaps->dwDeviceClassesSize
  7036. );
  7037. }
  7038. }
  7039. return lResult;
  7040. }
  7041. LONG
  7042. WINAPI
  7043. lineGetDevCaps(
  7044. HLINEAPP hLineApp,
  7045. DWORD dwDeviceID,
  7046. DWORD dwAPIVersion,
  7047. DWORD dwExtVersion,
  7048. LPLINEDEVCAPS lpLineDevCaps
  7049. )
  7050. {
  7051. return lineGetDevCapsA(
  7052. hLineApp,
  7053. dwDeviceID,
  7054. dwAPIVersion,
  7055. dwExtVersion,
  7056. lpLineDevCaps
  7057. );
  7058. }
  7059. LONG
  7060. WINAPI
  7061. lineGetDevConfigW(
  7062. DWORD dwDeviceID,
  7063. LPVARSTRING lpDeviceConfig,
  7064. LPCWSTR lpszDeviceClass
  7065. )
  7066. {
  7067. FUNC_ARGS funcArgs =
  7068. {
  7069. MAKELONG (LINE_FUNC | SYNC | 3, lGetDevConfig),
  7070. {
  7071. (ULONG_PTR) dwDeviceID,
  7072. (ULONG_PTR) lpDeviceConfig,
  7073. (ULONG_PTR) lpszDeviceClass
  7074. },
  7075. {
  7076. Dword,
  7077. lpGet_Struct,
  7078. lpszW
  7079. }
  7080. };
  7081. if ( lpszDeviceClass && TAPIIsBadStringPtrW(lpszDeviceClass, (UINT)-1) )
  7082. {
  7083. LOG((TL_ERROR, "Bad lpszDestAddress in lineGetDevConfigW"));
  7084. return( LINEERR_INVALPOINTER );
  7085. }
  7086. return (DOFUNC (&funcArgs, "lineGetDevConfig"));
  7087. }
  7088. LONG
  7089. WINAPI
  7090. lineGetDevConfigA(
  7091. DWORD dwDeviceID,
  7092. LPVARSTRING lpDeviceConfig,
  7093. LPCSTR lpszDeviceClass
  7094. )
  7095. {
  7096. LONG lResult;
  7097. FUNC_ARGS funcArgs =
  7098. {
  7099. MAKELONG (LINE_FUNC | SYNC | 3, lGetDevConfig),
  7100. {
  7101. (ULONG_PTR) dwDeviceID,
  7102. (ULONG_PTR) lpDeviceConfig,
  7103. 0 // (DWORD) lpszDeviceClass
  7104. },
  7105. {
  7106. Dword,
  7107. lpGet_Struct,
  7108. lpszW
  7109. }
  7110. };
  7111. if ( lpszDeviceClass && IsBadStringPtrA(lpszDeviceClass, (UINT)-1) )
  7112. {
  7113. LOG((TL_ERROR, "Bad lpszDestAddress in lineGetDevConfigA"));
  7114. return( LINEERR_INVALPOINTER );
  7115. }
  7116. funcArgs.Args[2] = (ULONG_PTR) NotSoWideStringToWideString(
  7117. lpszDeviceClass,
  7118. (DWORD) -1
  7119. );
  7120. lResult = (DOFUNC (&funcArgs, "lineGetDevConfig"));
  7121. if ((LPVOID)funcArgs.Args[2])
  7122. {
  7123. ClientFree ((LPVOID)funcArgs.Args[2]);
  7124. }
  7125. return lResult;
  7126. }
  7127. LONG
  7128. WINAPI
  7129. lineGetDevConfig(
  7130. DWORD dwDeviceID,
  7131. LPVARSTRING lpDeviceConfig,
  7132. LPCSTR lpszDeviceClass
  7133. )
  7134. {
  7135. return lineGetDevConfigA(
  7136. dwDeviceID,
  7137. lpDeviceConfig,
  7138. lpszDeviceClass
  7139. );
  7140. }
  7141. LONG
  7142. WINAPI
  7143. lineGetGroupListA(
  7144. HLINE hLine,
  7145. LPLINEAGENTGROUPLIST lpGroupList
  7146. )
  7147. {
  7148. FUNC_ARGS funcArgs =
  7149. {
  7150. MAKELONG (LINE_FUNC | ASYNC | 4, lGetGroupList),
  7151. {
  7152. (ULONG_PTR) GetFunctionIndex(lineGetAgentGroupListAPostProcess),
  7153. (ULONG_PTR) hLine,
  7154. (ULONG_PTR) lpGroupList, // pass the actual ptr (for ppproc)
  7155. (ULONG_PTR) lpGroupList // pass data
  7156. },
  7157. {
  7158. Dword,
  7159. Dword,
  7160. Dword,
  7161. lpGet_Struct
  7162. }
  7163. };
  7164. DWORD hPointer = 0;
  7165. LONG lResult;
  7166. hPointer = NewObject (ghHandleTable, (PVOID)lpGroupList, NULL);
  7167. if (0 == hPointer)
  7168. {
  7169. return LINEERR_NOMEM;
  7170. }
  7171. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  7172. lResult = (DOFUNC (&funcArgs, "lineGetGroupListA"));
  7173. if (0 > lResult)
  7174. {
  7175. DereferenceObject (ghHandleTable, hPointer, 1);
  7176. }
  7177. return lResult;
  7178. }
  7179. LONG
  7180. WINAPI
  7181. lineGetGroupListW(
  7182. HLINE hLine,
  7183. LPLINEAGENTGROUPLIST lpGroupList
  7184. )
  7185. {
  7186. FUNC_ARGS funcArgs =
  7187. {
  7188. MAKELONG (LINE_FUNC | ASYNC | 4, lGetGroupList),
  7189. {
  7190. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  7191. (ULONG_PTR) hLine,
  7192. (ULONG_PTR) lpGroupList, // pass the actual ptr (for ppproc)
  7193. (ULONG_PTR) lpGroupList // pass data
  7194. },
  7195. {
  7196. Dword,
  7197. Dword,
  7198. Dword,
  7199. lpGet_Struct
  7200. }
  7201. };
  7202. DWORD hPointer = 0;
  7203. LONG lResult;
  7204. hPointer = NewObject (ghHandleTable, (PVOID)lpGroupList, NULL);
  7205. if (0 == hPointer)
  7206. {
  7207. return LINEERR_NOMEM;
  7208. }
  7209. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  7210. lResult = (DOFUNC (&funcArgs, "lineGetAgentGroupListW"));
  7211. if (0 > lResult)
  7212. {
  7213. DereferenceObject (ghHandleTable, hPointer, 1);
  7214. }
  7215. return lResult;
  7216. }
  7217. LONG
  7218. WINAPI
  7219. lineGetIconW(
  7220. DWORD dwDeviceID,
  7221. LPCWSTR lpszDeviceClass,
  7222. LPHICON lphIcon
  7223. )
  7224. {
  7225. FUNC_ARGS funcArgs =
  7226. {
  7227. MAKELONG (LINE_FUNC | SYNC | 3, lGetIcon),
  7228. {
  7229. (ULONG_PTR) dwDeviceID,
  7230. (ULONG_PTR) lpszDeviceClass,
  7231. (ULONG_PTR) lphIcon
  7232. },
  7233. {
  7234. Dword,
  7235. lpszW,
  7236. lpDword
  7237. }
  7238. };
  7239. if (IsBadDwordPtr ((LPDWORD) lphIcon))
  7240. {
  7241. LOG((TL_ERROR, "lphIcon is an invalid pointer [0x%p]!", lphIcon));
  7242. return LINEERR_INVALPOINTER;
  7243. }
  7244. if (lpszDeviceClass == (LPCWSTR) NULL)
  7245. {
  7246. //
  7247. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  7248. //
  7249. funcArgs.ArgTypes[1] = Dword;
  7250. funcArgs.Args[1] = TAPI_NO_DATA;
  7251. }
  7252. return DOFUNC (&funcArgs, "lineGetIcon");
  7253. }
  7254. LONG
  7255. WINAPI
  7256. lineGetIconA(
  7257. DWORD dwDeviceID,
  7258. LPCSTR lpszDeviceClass,
  7259. LPHICON lphIcon
  7260. )
  7261. {
  7262. LONG lResult;
  7263. PWSTR szTempPtr;
  7264. if (lpszDeviceClass && IsBadStringPtrA (lpszDeviceClass, (DWORD) -1))
  7265. {
  7266. LOG((TL_ERROR,
  7267. "Bad class name pointer passed into lineGetIconA [0x%p]",
  7268. lpszDeviceClass
  7269. ));
  7270. return LINEERR_INVALPOINTER;
  7271. }
  7272. szTempPtr = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  7273. lResult = lineGetIconW (dwDeviceID, szTempPtr, lphIcon);
  7274. if (szTempPtr)
  7275. {
  7276. ClientFree (szTempPtr);
  7277. }
  7278. return lResult;
  7279. }
  7280. LONG
  7281. WINAPI
  7282. lineGetIcon(
  7283. DWORD dwDeviceID,
  7284. LPCSTR lpszDeviceClass,
  7285. LPHICON lphIcon
  7286. )
  7287. {
  7288. return (lineGetIconA (dwDeviceID, lpszDeviceClass, lphIcon));
  7289. }
  7290. LONG
  7291. WINAPI
  7292. lineGetIDW(
  7293. HLINE hLine,
  7294. DWORD dwAddressID,
  7295. HCALL hCall,
  7296. DWORD dwSelect,
  7297. LPVARSTRING lpDeviceID,
  7298. LPCWSTR lpszDeviceClass
  7299. )
  7300. {
  7301. FUNC_ARGS funcArgs =
  7302. {
  7303. MAKELONG (LINE_FUNC | SYNC | 6, lGetID),
  7304. {
  7305. (ULONG_PTR) hLine,
  7306. (ULONG_PTR) dwAddressID,
  7307. (ULONG_PTR) hCall,
  7308. (ULONG_PTR) dwSelect,
  7309. (ULONG_PTR) lpDeviceID,
  7310. (ULONG_PTR) lpszDeviceClass
  7311. },
  7312. {
  7313. Dword,
  7314. Dword,
  7315. Dword,
  7316. Dword,
  7317. lpGet_Struct,
  7318. lpszW
  7319. }
  7320. };
  7321. LPVARSTRING lpDeviceIDTemp = NULL;
  7322. DWORD dwNumDevices;
  7323. DWORD dwBufSize;
  7324. DWORD dwResult;
  7325. DWORD dwDeviceId1, dwDeviceId2;
  7326. BOOL bDoItAgain = FALSE;
  7327. if (TAPIIsBadStringPtrW (lpszDeviceClass, (UINT)-1) ||
  7328. lstrlenW(lpszDeviceClass) == 0)
  7329. {
  7330. LOG((TL_ERROR, "Bad lpszDeviceClass in lineGetIDW"));
  7331. return( LINEERR_INVALPOINTER);
  7332. }
  7333. if ( IsBadWritePtr(lpDeviceID, sizeof(VARSTRING)) )
  7334. {
  7335. LOG((TL_ERROR, "Bad lpDeviceID in lineGetIDW"));
  7336. return( LINEERR_INVALPOINTER);
  7337. }
  7338. //
  7339. // if the request is for a wave device, call LGetIDEx
  7340. //
  7341. if (!_wcsicmp(lpszDeviceClass, L"wave/in") ||
  7342. !_wcsicmp(lpszDeviceClass, L"wave/out") ||
  7343. !_wcsicmp(lpszDeviceClass, L"midi/in") ||
  7344. !_wcsicmp(lpszDeviceClass, L"midi/out") ||
  7345. !_wcsicmp(lpszDeviceClass, L"wave/in/out")
  7346. )
  7347. {
  7348. dwNumDevices = _wcsicmp(lpszDeviceClass, L"wave/in/out") ? 1 : 2;
  7349. dwBufSize = lpDeviceID->dwTotalSize + dwNumDevices * WAVE_STRING_ID_BUFFER_SIZE;
  7350. do
  7351. {
  7352. //
  7353. // Allocate additional memory for the device string ID
  7354. //
  7355. lpDeviceIDTemp = (LPVARSTRING)ClientAlloc (dwBufSize);
  7356. if (!lpDeviceIDTemp)
  7357. {
  7358. LOG((TL_ERROR, "Failed to allocate memory"));
  7359. return( LINEERR_NOMEM );
  7360. }
  7361. lpDeviceIDTemp->dwTotalSize = dwBufSize;
  7362. funcArgs.Flags = MAKELONG (LINE_FUNC | SYNC | 6, lGetIDEx);
  7363. funcArgs.Args[4] = (ULONG_PTR)lpDeviceIDTemp;
  7364. //
  7365. // Call LGetIDEx
  7366. //
  7367. dwResult = DOFUNC (&funcArgs, "lineGetIDEx");
  7368. if (dwResult)
  7369. {
  7370. LOG((TL_ERROR, "lineGetIDEx failed with x%x", dwResult));
  7371. ClientFree (lpDeviceIDTemp);
  7372. return dwResult;
  7373. }
  7374. if (lpDeviceIDTemp->dwNeededSize > lpDeviceIDTemp->dwTotalSize && !bDoItAgain)
  7375. {
  7376. LOG((TL_INFO,
  7377. "lineGetIDEx returned needed size (%d) bigger than total size (%d) -> need to realloc",
  7378. lpDeviceIDTemp->dwNeededSize,
  7379. lpDeviceIDTemp->dwTotalSize ));
  7380. dwBufSize = lpDeviceIDTemp->dwNeededSize;
  7381. ClientFree ( lpDeviceIDTemp );
  7382. bDoItAgain = TRUE;
  7383. }
  7384. else
  7385. {
  7386. bDoItAgain = FALSE;
  7387. }
  7388. } while (bDoItAgain);
  7389. if (lpDeviceIDTemp->dwNeededSize > lpDeviceIDTemp->dwTotalSize)
  7390. {
  7391. LOG((TL_ERROR, "needed size (%d) still bigger than total size (%d)",
  7392. lpDeviceIDTemp->dwNeededSize,
  7393. lpDeviceIDTemp->dwTotalSize ));
  7394. ClientFree (lpDeviceIDTemp);
  7395. return LINEERR_OPERATIONFAILED;
  7396. }
  7397. //
  7398. // Get the device ID from string ID
  7399. //
  7400. if (dwNumDevices == 1)
  7401. {
  7402. if (!WaveStringIdToDeviceId (
  7403. (LPWSTR)((LPBYTE)lpDeviceIDTemp + lpDeviceIDTemp->dwStringOffset),
  7404. lpszDeviceClass,
  7405. &dwDeviceId1)
  7406. )
  7407. {
  7408. LOG((TL_ERROR, "WaveStringIdToDeviceId failed"));
  7409. ClientFree (lpDeviceIDTemp);
  7410. return LINEERR_OPERATIONFAILED;
  7411. }
  7412. // check if the client buffer is big enough
  7413. if (lpDeviceID->dwTotalSize < sizeof(VARSTRING) + sizeof(DWORD))
  7414. {
  7415. lpDeviceID->dwNeededSize = sizeof(VARSTRING) + sizeof(DWORD);
  7416. lpDeviceID->dwUsedSize = sizeof(VARSTRING);
  7417. }
  7418. else
  7419. {
  7420. lpDeviceID->dwNeededSize = lpDeviceID->dwUsedSize = sizeof(VARSTRING) + sizeof(DWORD);
  7421. lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
  7422. lpDeviceID->dwStringSize = sizeof(DWORD);
  7423. lpDeviceID->dwStringOffset = sizeof(VARSTRING);
  7424. *(DWORD *)(lpDeviceID + 1) = dwDeviceId1;
  7425. }
  7426. }
  7427. else
  7428. {
  7429. LPWSTR szString1 = (LPWSTR)((LPBYTE)lpDeviceIDTemp + lpDeviceIDTemp->dwStringOffset);
  7430. if (!WaveStringIdToDeviceId (
  7431. szString1,
  7432. L"wave/in",
  7433. &dwDeviceId1) ||
  7434. !WaveStringIdToDeviceId (
  7435. (LPWSTR)((LPBYTE)lpDeviceIDTemp + lpDeviceIDTemp->dwStringOffset + wcslen(szString1)),
  7436. L"wave/out",
  7437. &dwDeviceId2)
  7438. )
  7439. {
  7440. LOG((TL_ERROR, "WaveStringIdToDeviceId failed"));
  7441. ClientFree (lpDeviceIDTemp);
  7442. return LINEERR_OPERATIONFAILED;
  7443. }
  7444. // check if the client buffer is big enough
  7445. if (lpDeviceID->dwTotalSize < sizeof(VARSTRING) + 2 * sizeof(DWORD))
  7446. {
  7447. lpDeviceID->dwNeededSize = sizeof(VARSTRING) + 2 * sizeof(DWORD);
  7448. lpDeviceID->dwUsedSize = sizeof(VARSTRING);
  7449. }
  7450. else
  7451. {
  7452. lpDeviceID->dwNeededSize = lpDeviceID->dwUsedSize = sizeof(VARSTRING) + 2 * sizeof(DWORD);
  7453. lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
  7454. lpDeviceID->dwStringSize = 2 * sizeof(DWORD);
  7455. lpDeviceID->dwStringOffset = sizeof(VARSTRING);
  7456. *(DWORD *)(lpDeviceID + 1) = dwDeviceId1;
  7457. *((DWORD *)(lpDeviceID + 1) + 1) = dwDeviceId2;
  7458. }
  7459. }
  7460. ClientFree (lpDeviceIDTemp);
  7461. return NO_ERROR;
  7462. }
  7463. else
  7464. {
  7465. return (DOFUNC (&funcArgs, "lineGetID"));
  7466. }
  7467. }
  7468. LONG
  7469. WINAPI
  7470. lineGetIDA(
  7471. HLINE hLine,
  7472. DWORD dwAddressID,
  7473. HCALL hCall,
  7474. DWORD dwSelect,
  7475. LPVARSTRING lpDeviceID,
  7476. LPCSTR lpszDeviceClass
  7477. )
  7478. {
  7479. LONG lResult;
  7480. PWSTR szTempPtr;
  7481. if (IsBadStringPtrA (lpszDeviceClass, (UINT)-1) ||
  7482. lstrlenA(lpszDeviceClass) == 0)
  7483. {
  7484. LOG((TL_ERROR, "Bad lpszDeviceClass in lineGetIDA"));
  7485. return( LINEERR_INVALPOINTER);
  7486. }
  7487. szTempPtr = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  7488. if (NULL == szTempPtr)
  7489. {
  7490. return LINEERR_NOMEM;
  7491. }
  7492. lResult = lineGetIDW(
  7493. hLine,
  7494. dwAddressID,
  7495. hCall,
  7496. dwSelect,
  7497. lpDeviceID,
  7498. szTempPtr
  7499. );
  7500. ClientFree (szTempPtr);
  7501. return lResult;
  7502. }
  7503. LONG
  7504. WINAPI
  7505. lineGetID(
  7506. HLINE hLine,
  7507. DWORD dwAddressID,
  7508. HCALL hCall,
  7509. DWORD dwSelect,
  7510. LPVARSTRING lpDeviceID,
  7511. LPCSTR lpszDeviceClass
  7512. )
  7513. {
  7514. return lineGetIDA(
  7515. hLine,
  7516. dwAddressID,
  7517. hCall,
  7518. dwSelect,
  7519. lpDeviceID,
  7520. lpszDeviceClass
  7521. );
  7522. }
  7523. LONG
  7524. WINAPI
  7525. lineGetLineDevStatusW(
  7526. HLINE hLine,
  7527. LPLINEDEVSTATUS lpLineDevStatus
  7528. )
  7529. {
  7530. FUNC_ARGS funcArgs =
  7531. {
  7532. MAKELONG (LINE_FUNC | SYNC | 2, lGetLineDevStatus),
  7533. {
  7534. (ULONG_PTR) hLine,
  7535. (ULONG_PTR) lpLineDevStatus
  7536. },
  7537. {
  7538. Dword,
  7539. lpGet_Struct
  7540. }
  7541. };
  7542. return (DOFUNC (&funcArgs, "lineGetLineDevStatus"));
  7543. }
  7544. LONG
  7545. WINAPI
  7546. lineGetLineDevStatusA(
  7547. HLINE hLine,
  7548. LPLINEDEVSTATUS lpLineDevStatus
  7549. )
  7550. {
  7551. DWORD dwAPIVersion;
  7552. FUNC_ARGS funcArgs =
  7553. {
  7554. MAKELONG (LINE_FUNC | SYNC | 3, lGetLineDevStatus),
  7555. {
  7556. (ULONG_PTR) hLine,
  7557. (ULONG_PTR) lpLineDevStatus,
  7558. (ULONG_PTR) &dwAPIVersion
  7559. },
  7560. {
  7561. Dword,
  7562. lpGet_Struct,
  7563. lpDword
  7564. }
  7565. };
  7566. LONG lResult;
  7567. if ((lResult = DOFUNC (&funcArgs, "lineGetLineDevStatus")) == 0)
  7568. {
  7569. if (dwAPIVersion >= 0x00020000)
  7570. {
  7571. DWORD i;
  7572. LPLINEAPPINFO lplai;
  7573. lplai = (LPLINEAPPINFO) (((LPBYTE)lpLineDevStatus) +
  7574. lpLineDevStatus->dwAppInfoOffset);
  7575. for (i = 0; i < lpLineDevStatus->dwNumOpens; i++, lplai++)
  7576. {
  7577. WideStringToNotSoWideString(
  7578. (LPBYTE) lpLineDevStatus,
  7579. &lplai->dwMachineNameSize
  7580. );
  7581. WideStringToNotSoWideString(
  7582. (LPBYTE) lpLineDevStatus,
  7583. &lplai->dwUserNameSize
  7584. );
  7585. WideStringToNotSoWideString(
  7586. (LPBYTE) lpLineDevStatus,
  7587. &lplai->dwModuleFilenameSize
  7588. );
  7589. WideStringToNotSoWideString(
  7590. (LPBYTE) lpLineDevStatus,
  7591. &lplai->dwFriendlyNameSize
  7592. );
  7593. }
  7594. }
  7595. }
  7596. return lResult;
  7597. }
  7598. LONG
  7599. WINAPI
  7600. lineGetLineDevStatus(
  7601. HLINE hLine,
  7602. LPLINEDEVSTATUS lpLineDevStatus
  7603. )
  7604. {
  7605. return lineGetLineDevStatusA (hLine, lpLineDevStatus);
  7606. }
  7607. LONG
  7608. WINAPI
  7609. lineGetMessage(
  7610. HLINEAPP hLineApp,
  7611. LPLINEMESSAGE lpMessage,
  7612. DWORD dwTimeout
  7613. )
  7614. {
  7615. return (xxxGetMessage (TRUE, hLineApp, lpMessage, dwTimeout));
  7616. }
  7617. LONG
  7618. WINAPI
  7619. lineGetNewCalls(
  7620. HLINE hLine,
  7621. DWORD dwAddressID,
  7622. DWORD dwSelect,
  7623. LPLINECALLLIST lpCallList
  7624. )
  7625. {
  7626. FUNC_ARGS funcArgs =
  7627. {
  7628. MAKELONG (LINE_FUNC | SYNC | 4, lGetNewCalls),
  7629. {
  7630. (ULONG_PTR) hLine,
  7631. (ULONG_PTR) dwAddressID,
  7632. (ULONG_PTR) dwSelect,
  7633. (ULONG_PTR) lpCallList
  7634. },
  7635. {
  7636. Dword,
  7637. Dword,
  7638. Dword,
  7639. lpGet_Struct
  7640. }
  7641. };
  7642. return (DOFUNC (&funcArgs, "lineGetNewCalls"));
  7643. }
  7644. LONG
  7645. WINAPI
  7646. lineGetNumRings(
  7647. HLINE hLine,
  7648. DWORD dwAddressID,
  7649. LPDWORD lpdwNumRings
  7650. )
  7651. {
  7652. FUNC_ARGS funcArgs =
  7653. {
  7654. MAKELONG (LINE_FUNC | SYNC | 3, lGetNumRings),
  7655. {
  7656. (ULONG_PTR) hLine,
  7657. (ULONG_PTR) dwAddressID,
  7658. (ULONG_PTR) lpdwNumRings
  7659. },
  7660. {
  7661. Dword,
  7662. Dword,
  7663. lpDword
  7664. }
  7665. };
  7666. return (DOFUNC (&funcArgs, "lineGetNumRings"));
  7667. }
  7668. LONG
  7669. WINAPI
  7670. lineGetProviderListW(
  7671. DWORD dwAPIVersion,
  7672. LPLINEPROVIDERLIST lpProviderList
  7673. )
  7674. {
  7675. HANDLE hProvidersMutex;
  7676. LONG lResult;
  7677. FUNC_ARGS funcArgs =
  7678. {
  7679. MAKELONG (LINE_FUNC | SYNC | 2, lGetProviderList),
  7680. {
  7681. (ULONG_PTR) dwAPIVersion,
  7682. (ULONG_PTR) lpProviderList
  7683. },
  7684. {
  7685. Dword,
  7686. lpGet_Struct
  7687. }
  7688. };
  7689. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  7690. {
  7691. return LINEERR_INCOMPATIBLEAPIVERSION;
  7692. }
  7693. hProvidersMutex = CreateMutex (
  7694. NULL,
  7695. FALSE,
  7696. TEXT ("TapisrvProviderListMutex")
  7697. );
  7698. if (NULL == hProvidersMutex)
  7699. {
  7700. return LINEERR_OPERATIONFAILED;
  7701. }
  7702. WaitForSingleObject (hProvidersMutex, INFINITE);
  7703. lResult = DOFUNC (&funcArgs, "lineGetProviderList");
  7704. if (hProvidersMutex)
  7705. {
  7706. ReleaseMutex (hProvidersMutex);
  7707. CloseHandle (hProvidersMutex);
  7708. }
  7709. return lResult;
  7710. }
  7711. LONG
  7712. WINAPI
  7713. lineGetProviderListA(
  7714. DWORD dwAPIVersion,
  7715. LPLINEPROVIDERLIST lpProviderList
  7716. )
  7717. {
  7718. LONG lResult;
  7719. lResult = lineGetProviderListW (dwAPIVersion, lpProviderList);
  7720. if (lResult == 0)
  7721. {
  7722. DWORD i;
  7723. LPLINEPROVIDERENTRY lplpe;
  7724. lplpe = (LPLINEPROVIDERENTRY) (((LPBYTE)lpProviderList) +
  7725. lpProviderList->dwProviderListOffset);
  7726. for (i = 0; i < lpProviderList->dwNumProviders; i++, lplpe++)
  7727. {
  7728. WideStringToNotSoWideString(
  7729. (LPBYTE)lpProviderList,
  7730. &(lplpe->dwProviderFilenameSize)
  7731. );
  7732. }
  7733. }
  7734. return lResult;
  7735. }
  7736. LONG
  7737. WINAPI
  7738. lineGetProviderList(
  7739. DWORD dwAPIVersion,
  7740. LPLINEPROVIDERLIST lpProviderList
  7741. )
  7742. {
  7743. return lineGetProviderListA (dwAPIVersion, lpProviderList);
  7744. }
  7745. LONG
  7746. WINAPI
  7747. lineGetProxyStatus(
  7748. HLINEAPP hLineApp,
  7749. DWORD dwDeviceID,
  7750. DWORD dwAppAPIVersion,
  7751. LPLINEPROXYREQUESTLIST lpLineProxyReqestList
  7752. )
  7753. {
  7754. FUNC_ARGS funcArgs =
  7755. {
  7756. MAKELONG (LINE_FUNC | SYNC | 4, lGetProxyStatus),
  7757. {
  7758. (ULONG_PTR) hLineApp,
  7759. (ULONG_PTR) dwDeviceID,
  7760. (ULONG_PTR) dwAppAPIVersion,
  7761. (ULONG_PTR) lpLineProxyReqestList
  7762. },
  7763. {
  7764. hXxxApp,
  7765. Dword,
  7766. Dword,
  7767. lpGet_Struct
  7768. }
  7769. };
  7770. if (dwAppAPIVersion > TAPI_CURRENT_VERSION)
  7771. {
  7772. return LINEERR_INCOMPATIBLEAPIVERSION;
  7773. }
  7774. return (DOFUNC (&funcArgs, "lineGetProxyStatus"));
  7775. }
  7776. LONG
  7777. WINAPI
  7778. lineGetQueueInfo(
  7779. HLINE hLine,
  7780. DWORD dwQueueID,
  7781. LPLINEQUEUEINFO lpLineQueueInfo
  7782. )
  7783. {
  7784. FUNC_ARGS funcArgs =
  7785. {
  7786. MAKELONG (LINE_FUNC | ASYNC | 5, lGetQueueInfo),
  7787. {
  7788. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  7789. (ULONG_PTR) hLine,
  7790. (ULONG_PTR) dwQueueID,
  7791. (ULONG_PTR) lpLineQueueInfo, // pass the actual ptr (for ppproc)
  7792. (ULONG_PTR) lpLineQueueInfo // pass data
  7793. },
  7794. {
  7795. Dword,
  7796. Dword,
  7797. Dword,
  7798. Dword,
  7799. lpGet_Struct
  7800. }
  7801. };
  7802. DWORD hPointer = 0;
  7803. LONG lResult;
  7804. if ( !lpLineQueueInfo )
  7805. {
  7806. return LINEERR_INVALPARAM;
  7807. }
  7808. hPointer = NewObject (ghHandleTable, (PVOID)lpLineQueueInfo, NULL);
  7809. if (0 == hPointer)
  7810. {
  7811. return LINEERR_NOMEM;
  7812. }
  7813. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  7814. lResult = (DOFUNC (&funcArgs, "lineGetQueueInfo"));
  7815. if (0 > lResult)
  7816. {
  7817. DereferenceObject (ghHandleTable, hPointer, 1);
  7818. }
  7819. return lResult;
  7820. }
  7821. void
  7822. PASCAL
  7823. lineGetQueueListAPostProcess(
  7824. PASYNCEVENTMSG pMsg
  7825. )
  7826. {
  7827. LOG((TL_TRACE, "lineGetQueueListAPostProcess: enter"));
  7828. LOG((TL_INFO,
  7829. "\t\tdwP1=x%lx, dwP2=x%lx, dwP3=x%lx, dwP4=x%lx",
  7830. pMsg->Param1,
  7831. pMsg->Param2,
  7832. pMsg->Param3,
  7833. pMsg->Param4
  7834. ));
  7835. if (pMsg->Param2 == 0)
  7836. {
  7837. DWORD dwSize = (DWORD) pMsg->Param4;
  7838. LPLINEQUEUELIST lpQueueList = (LPLINEQUEUELIST) ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  7839. // We don't need the handle to the pointer any more...
  7840. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  7841. try
  7842. {
  7843. DWORD dw, dwNumEntries;
  7844. LPLINEQUEUEENTRY lpqe;
  7845. //
  7846. // Note: the agent APIs are not exposed to 16-bit apps, so
  7847. // there's no reason to special case on gbNTVDMClient like
  7848. // lineDevSpecificPostProcess does
  7849. //
  7850. CopyMemory (lpQueueList, (LPBYTE) (pMsg + 1), dwSize);
  7851. //
  7852. // Now some unicode->ascii post processing on embedded strings
  7853. //
  7854. lpqe = (LPLINEQUEUEENTRY)(((LPBYTE)lpQueueList) +
  7855. lpQueueList->dwListOffset);
  7856. dwNumEntries = lpQueueList->dwNumEntries;
  7857. for (dw = 0; dw < dwNumEntries; dw++, lpqe++)
  7858. {
  7859. WideStringToNotSoWideString(
  7860. (LPBYTE) lpQueueList,
  7861. &(lpqe->dwNameSize)
  7862. );
  7863. }
  7864. }
  7865. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  7866. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  7867. {
  7868. pMsg->Param2 = LINEERR_INVALPOINTER;
  7869. }
  7870. }
  7871. }
  7872. LONG
  7873. WINAPI
  7874. lineGetQueueListA(
  7875. HLINE hLine,
  7876. LPGUID lpGroupID,
  7877. LPLINEQUEUELIST lpQueueList
  7878. )
  7879. {
  7880. FUNC_ARGS funcArgs =
  7881. {
  7882. MAKELONG (LINE_FUNC | ASYNC | 6, lGetQueueList),
  7883. {
  7884. (ULONG_PTR) GetFunctionIndex(lineGetQueueListAPostProcess),
  7885. (ULONG_PTR) hLine,
  7886. (ULONG_PTR) lpGroupID,
  7887. (ULONG_PTR) sizeof( GUID ),
  7888. (ULONG_PTR) lpQueueList, // pass the actual ptr (for ppproc)
  7889. (ULONG_PTR) lpQueueList // pass data
  7890. },
  7891. {
  7892. Dword,
  7893. Dword,
  7894. lpSet_SizeToFollow,
  7895. Size,
  7896. Dword,
  7897. lpGet_Struct,
  7898. }
  7899. };
  7900. DWORD hPointer = 0;
  7901. LONG lResult;
  7902. hPointer = NewObject (ghHandleTable, (PVOID)lpQueueList, NULL);
  7903. if (0 == hPointer)
  7904. {
  7905. return LINEERR_NOMEM;
  7906. }
  7907. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  7908. lResult = (DOFUNC (&funcArgs, "lineGetQueueListA"));
  7909. if (0 > lResult)
  7910. {
  7911. DereferenceObject (ghHandleTable, hPointer, 1);
  7912. }
  7913. return lResult;
  7914. }
  7915. LONG
  7916. WINAPI
  7917. lineGetQueueListW(
  7918. HLINE hLine,
  7919. LPGUID lpGroupID,
  7920. LPLINEQUEUELIST lpQueueList
  7921. )
  7922. {
  7923. FUNC_ARGS funcArgs =
  7924. {
  7925. MAKELONG (LINE_FUNC | ASYNC | 6, lGetQueueList),
  7926. {
  7927. (ULONG_PTR) GetFunctionIndex(lineDevSpecificPostProcess),
  7928. (ULONG_PTR) hLine,
  7929. (ULONG_PTR) lpGroupID,
  7930. (ULONG_PTR) sizeof( GUID ),
  7931. (ULONG_PTR) lpQueueList, // pass the actual ptr (for ppproc)
  7932. (ULONG_PTR) lpQueueList // pass data
  7933. },
  7934. {
  7935. Dword,
  7936. Dword,
  7937. lpSet_SizeToFollow,
  7938. Size,
  7939. Dword,
  7940. lpGet_Struct,
  7941. }
  7942. };
  7943. DWORD hPointer = 0;
  7944. LONG lResult;
  7945. hPointer = NewObject (ghHandleTable, (PVOID)lpQueueList, NULL);
  7946. if (0 == hPointer)
  7947. {
  7948. return LINEERR_NOMEM;
  7949. }
  7950. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  7951. lResult = (DOFUNC (&funcArgs, "lineGetQueueList"));
  7952. if (0 > lResult)
  7953. {
  7954. DereferenceObject (ghHandleTable, hPointer, 1);
  7955. }
  7956. return lResult;
  7957. }
  7958. LONG
  7959. WINAPI
  7960. lineGetRequestW(
  7961. HLINEAPP hLineApp,
  7962. DWORD dwRequestMode,
  7963. LPVOID lpRequestBuffer
  7964. )
  7965. {
  7966. FUNC_ARGS funcArgs =
  7967. {
  7968. MAKELONG (LINE_FUNC | SYNC | 4, lGetRequest),
  7969. {
  7970. (ULONG_PTR) hLineApp,
  7971. (ULONG_PTR) dwRequestMode,
  7972. (ULONG_PTR) lpRequestBuffer,
  7973. (ULONG_PTR) 0
  7974. },
  7975. {
  7976. hXxxApp,
  7977. Dword,
  7978. lpGet_SizeToFollow,
  7979. Size
  7980. }
  7981. };
  7982. if (dwRequestMode == LINEREQUESTMODE_MAKECALL)
  7983. {
  7984. //
  7985. // Set the size param appropriately
  7986. //
  7987. funcArgs.Args[3] = (ULONG_PTR) sizeof(LINEREQMAKECALLW);
  7988. }
  7989. else if (dwRequestMode == LINEREQUESTMODE_MEDIACALL)
  7990. {
  7991. //
  7992. // Set the size param appropriately
  7993. //
  7994. funcArgs.Args[3] = (ULONG_PTR) sizeof(LINEREQMEDIACALLW);
  7995. }
  7996. return (DOFUNC (&funcArgs, "lineGetRequest"));
  7997. }
  7998. LONG
  7999. WINAPI
  8000. lineGetRequestA(
  8001. HLINEAPP hLineApp,
  8002. DWORD dwRequestMode,
  8003. LPVOID lpRequestBuffer
  8004. )
  8005. {
  8006. LONG lResult;
  8007. LPVOID pszTempPtr = NULL;
  8008. FUNC_ARGS funcArgs =
  8009. {
  8010. MAKELONG (LINE_FUNC | SYNC | 4, lGetRequest),
  8011. {
  8012. (ULONG_PTR) hLineApp,
  8013. (ULONG_PTR) dwRequestMode,
  8014. (ULONG_PTR) 0, // (DWORD) lpRequestBuffer,
  8015. (ULONG_PTR) 0
  8016. },
  8017. {
  8018. hXxxApp,
  8019. Dword,
  8020. lpGet_SizeToFollow,
  8021. Size
  8022. }
  8023. };
  8024. if (IsBadWritePtr(
  8025. lpRequestBuffer,
  8026. (dwRequestMode == LINEREQUESTMODE_MAKECALL ?
  8027. sizeof (LINEREQMAKECALL) : sizeof (LINEREQMEDIACALL))
  8028. ))
  8029. {
  8030. return LINEERR_INVALPOINTER;
  8031. }
  8032. if (dwRequestMode == LINEREQUESTMODE_MAKECALL)
  8033. {
  8034. //
  8035. // Set the size param appropriately
  8036. //
  8037. funcArgs.Args[3] = (ULONG_PTR) sizeof(LINEREQMAKECALLW);
  8038. pszTempPtr = ClientAlloc( sizeof(LINEREQMAKECALLW) );
  8039. if (NULL == pszTempPtr)
  8040. {
  8041. return LINEERR_NOMEM;
  8042. }
  8043. }
  8044. else if (dwRequestMode == LINEREQUESTMODE_MEDIACALL)
  8045. {
  8046. //
  8047. // Set the size param appropriately
  8048. //
  8049. funcArgs.Args[3] = (ULONG_PTR) sizeof(LINEREQMEDIACALLW);
  8050. pszTempPtr = ClientAlloc( sizeof(LINEREQMEDIACALLW) );
  8051. if (NULL == pszTempPtr)
  8052. {
  8053. return LINEERR_NOMEM;
  8054. }
  8055. }
  8056. funcArgs.Args[2] = (ULONG_PTR) pszTempPtr;
  8057. lResult = (DOFUNC (&funcArgs, "lineGetRequest"));
  8058. if ( 0 == lResult )
  8059. {
  8060. if (dwRequestMode == LINEREQUESTMODE_MAKECALL)
  8061. {
  8062. LPLINEREQMAKECALLW lplrmc = pszTempPtr;
  8063. WideCharToMultiByte(
  8064. GetACP(),
  8065. 0,
  8066. lplrmc->szDestAddress,
  8067. -1,
  8068. ((LPLINEREQMAKECALL)lpRequestBuffer)->szDestAddress,
  8069. TAPIMAXDESTADDRESSSIZE,
  8070. NULL,
  8071. NULL
  8072. );
  8073. WideCharToMultiByte(
  8074. GetACP(),
  8075. 0,
  8076. lplrmc->szAppName,
  8077. -1,
  8078. ((LPLINEREQMAKECALL)lpRequestBuffer)->szAppName,
  8079. TAPIMAXAPPNAMESIZE,
  8080. NULL,
  8081. NULL
  8082. );
  8083. WideCharToMultiByte(
  8084. GetACP(),
  8085. 0,
  8086. lplrmc->szCalledParty,
  8087. -1,
  8088. ((LPLINEREQMAKECALL)lpRequestBuffer)->szCalledParty,
  8089. TAPIMAXCALLEDPARTYSIZE,
  8090. NULL,
  8091. NULL
  8092. );
  8093. WideCharToMultiByte(
  8094. GetACP(),
  8095. 0,
  8096. lplrmc->szComment,
  8097. -1,
  8098. ((LPLINEREQMAKECALL)lpRequestBuffer)->szComment,
  8099. TAPIMAXCOMMENTSIZE,
  8100. NULL,
  8101. NULL
  8102. );
  8103. }
  8104. else
  8105. {
  8106. // We don't currently support this...
  8107. //typedef struct linereqmediacallW_tag
  8108. //{
  8109. // HWND hWnd;
  8110. // WPARAM wRequestID;
  8111. // WCHAR szDeviceClass[TAPIMAXDEVICECLASSSIZE];
  8112. // unsigned char ucDeviceID[TAPIMAXDEVICEIDSIZE];
  8113. // DWORD dwSize;
  8114. // DWORD dwSecure;
  8115. // WCHAR szDestAddress[TAPIMAXDESTADDRESSSIZE];
  8116. // WCHAR szAppName[TAPIMAXAPPNAMESIZE];
  8117. // WCHAR szCalledParty[TAPIMAXCALLEDPARTYSIZE];
  8118. // WCHAR szComment[TAPIMAXCOMMENTSIZE];
  8119. //}
  8120. }
  8121. }
  8122. if ( pszTempPtr )
  8123. {
  8124. ClientFree( pszTempPtr );
  8125. }
  8126. return lResult;
  8127. }
  8128. LONG
  8129. WINAPI
  8130. lineGetRequest(
  8131. HLINEAPP hLineApp,
  8132. DWORD dwRequestMode,
  8133. LPVOID lpRequestBuffer
  8134. )
  8135. {
  8136. return lineGetRequestA (hLineApp, dwRequestMode, lpRequestBuffer);
  8137. }
  8138. LONG
  8139. WINAPI
  8140. lineGetStatusMessages(
  8141. HLINE hLine,
  8142. LPDWORD lpdwLineStates,
  8143. LPDWORD lpdwAddressStates
  8144. )
  8145. {
  8146. FUNC_ARGS funcArgs =
  8147. {
  8148. MAKELONG (LINE_FUNC | SYNC | 3, lGetStatusMessages),
  8149. {
  8150. (ULONG_PTR) hLine,
  8151. (ULONG_PTR) lpdwLineStates,
  8152. (ULONG_PTR) lpdwAddressStates
  8153. },
  8154. {
  8155. Dword,
  8156. lpDword,
  8157. lpDword
  8158. }
  8159. };
  8160. if (lpdwLineStates == lpdwAddressStates)
  8161. {
  8162. return LINEERR_INVALPOINTER;
  8163. }
  8164. return (DOFUNC (&funcArgs, "lineGetStatusMessages"));
  8165. }
  8166. LONG
  8167. WINAPI
  8168. lineHandoffW(
  8169. HCALL hCall,
  8170. LPCWSTR lpszFileName,
  8171. DWORD dwMediaMode
  8172. )
  8173. {
  8174. FUNC_ARGS funcArgs =
  8175. {
  8176. MAKELONG (LINE_FUNC | SYNC | 3, lHandoff),
  8177. {
  8178. (ULONG_PTR) hCall,
  8179. (ULONG_PTR) lpszFileName,
  8180. (ULONG_PTR) dwMediaMode
  8181. },
  8182. {
  8183. Dword,
  8184. lpszW,
  8185. Dword
  8186. }
  8187. };
  8188. if (lpszFileName == (LPCWSTR) NULL)
  8189. {
  8190. //
  8191. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  8192. //
  8193. funcArgs.ArgTypes[1] = Dword;
  8194. funcArgs.Args[1] = (ULONG_PTR) TAPI_NO_DATA;
  8195. }
  8196. return (DOFUNC (&funcArgs, "lineHandoff"));
  8197. }
  8198. LONG
  8199. WINAPI
  8200. lineHandoffA(
  8201. HCALL hCall,
  8202. LPCSTR lpszFileName,
  8203. DWORD dwMediaMode
  8204. )
  8205. {
  8206. LONG lResult;
  8207. LPWSTR pTempPtr;
  8208. if (lpszFileName)
  8209. {
  8210. if (IsBadStringPtrA (lpszFileName, (DWORD) -1))
  8211. {
  8212. return LINEERR_INVALPOINTER;
  8213. }
  8214. else if (!(pTempPtr = NotSoWideStringToWideString(
  8215. lpszFileName,
  8216. (DWORD) -1
  8217. )))
  8218. {
  8219. return LINEERR_NOMEM;
  8220. }
  8221. }
  8222. else
  8223. {
  8224. pTempPtr = NULL;
  8225. }
  8226. lResult = lineHandoffW (hCall, pTempPtr, dwMediaMode);
  8227. if (pTempPtr)
  8228. {
  8229. ClientFree (pTempPtr);
  8230. }
  8231. return lResult;
  8232. }
  8233. LONG
  8234. WINAPI
  8235. lineHandoff(
  8236. HCALL hCall,
  8237. LPCSTR lpszFileName,
  8238. DWORD dwMediaMode
  8239. )
  8240. {
  8241. return lineHandoffA (hCall, lpszFileName, dwMediaMode);
  8242. }
  8243. LONG
  8244. WINAPI
  8245. lineHold(
  8246. HCALL hCall
  8247. )
  8248. {
  8249. FUNC_ARGS funcArgs =
  8250. {
  8251. MAKELONG (LINE_FUNC | ASYNC | 1, lHold),
  8252. {
  8253. (ULONG_PTR) hCall
  8254. },
  8255. {
  8256. Dword
  8257. }
  8258. };
  8259. return (DOFUNC (&funcArgs, "lineHold"));
  8260. }
  8261. PWSTR
  8262. PASCAL
  8263. MultiToWide(
  8264. LPCSTR lpStr
  8265. )
  8266. {
  8267. DWORD dwSize;
  8268. PWSTR szTempPtr;
  8269. dwSize = MultiByteToWideChar(
  8270. GetACP(),
  8271. MB_PRECOMPOSED,
  8272. lpStr,
  8273. -1,
  8274. NULL,
  8275. 0
  8276. );
  8277. if ((szTempPtr = ClientAlloc ((dwSize + 1) * sizeof (WCHAR))))
  8278. {
  8279. MultiByteToWideChar(
  8280. GetACP(),
  8281. MB_PRECOMPOSED,
  8282. lpStr,
  8283. -1,
  8284. szTempPtr,
  8285. dwSize + 1
  8286. );
  8287. }
  8288. return szTempPtr;
  8289. }
  8290. // Don't need this 'cause 2.0 apps must use lineInitializeEx()
  8291. //
  8292. //LONG
  8293. //WINAPI
  8294. //lineInitializeW(
  8295. // LPHLINEAPP lphLineApp,
  8296. // HINSTANCE hInstance,
  8297. // LINECALLBACK lpfnCallback,
  8298. // LPCWSTR lpszAppName,
  8299. // LPDWORD lpdwNumDevs
  8300. // )
  8301. //{
  8302. // return (xxxInitialize(
  8303. // TRUE,
  8304. // (LPVOID) lphLineApp,
  8305. // hInstance,
  8306. // lpfnCallback,
  8307. // lpszAppName,
  8308. // lpdwNumDevs,
  8309. // NULL,
  8310. // NULL
  8311. //#if DBG
  8312. // ,"lineInitializeW"
  8313. //#endif
  8314. // ));
  8315. //}
  8316. LONG
  8317. WINAPI
  8318. lineInitialize(
  8319. LPHLINEAPP lphLineApp,
  8320. HINSTANCE hInstance,
  8321. LINECALLBACK lpfnCallback,
  8322. LPCSTR lpszAppName,
  8323. LPDWORD lpdwNumDevs
  8324. )
  8325. {
  8326. LONG lResult;
  8327. PWSTR szTempPtr;
  8328. if (lpszAppName )
  8329. {
  8330. if ( IsBadStringPtrA (lpszAppName, (DWORD) -1))
  8331. {
  8332. LOG((TL_ERROR, "lineInitialize: Bad lpszAddName pointer"));
  8333. return LINEERR_INVALPOINTER;
  8334. }
  8335. szTempPtr = NotSoWideStringToWideString (lpszAppName, (DWORD) -1);
  8336. }
  8337. else
  8338. {
  8339. szTempPtr = NULL;
  8340. }
  8341. //
  8342. // NOTE: the hack below for the lpInitExParam is for 16-bit apps,
  8343. // since the lpszAppName really points at a
  8344. // <friendly name>\0<module name>\0 string and we need the
  8345. // module name in xxxInitialize()
  8346. //
  8347. lResult = (xxxInitialize(
  8348. TRUE,
  8349. (LPVOID) lphLineApp,
  8350. hInstance,
  8351. lpfnCallback,
  8352. szTempPtr,
  8353. lpdwNumDevs,
  8354. NULL,
  8355. #ifdef _WIN64
  8356. NULL
  8357. #else
  8358. (LPLINEINITIALIZEEXPARAMS)
  8359. (((DWORD) lpfnCallback & 0xffff0000) == 0xffff0000 ?
  8360. lpszAppName : NULL)
  8361. #endif
  8362. #if DBG
  8363. ,"lineInitialize"
  8364. #endif
  8365. ));
  8366. if (szTempPtr)
  8367. {
  8368. ClientFree (szTempPtr);
  8369. }
  8370. return lResult;
  8371. }
  8372. LONG
  8373. WINAPI
  8374. lineInitializeExW(
  8375. LPHLINEAPP lphLineApp,
  8376. HINSTANCE hInstance,
  8377. LINECALLBACK lpfnCallback,
  8378. LPCWSTR lpszFriendlyAppName,
  8379. LPDWORD lpdwNumDevs,
  8380. LPDWORD lpdwAPIVersion,
  8381. LPLINEINITIALIZEEXPARAMS lpLineInitializeExParams
  8382. )
  8383. {
  8384. if (IsBadDwordPtr (lpdwAPIVersion))
  8385. {
  8386. LOG((TL_ERROR,
  8387. "lineInitializeExW: bad lpdwAPIVersion pointer (x%p)",
  8388. lpdwAPIVersion
  8389. ));
  8390. return LINEERR_INVALPOINTER;
  8391. }
  8392. return (xxxInitialize(
  8393. TRUE,
  8394. (LPVOID) lphLineApp,
  8395. hInstance,
  8396. lpfnCallback,
  8397. lpszFriendlyAppName,
  8398. lpdwNumDevs,
  8399. lpdwAPIVersion,
  8400. (LPVOID) lpLineInitializeExParams
  8401. #if DBG
  8402. ,"lineInitializeExW"
  8403. #endif
  8404. ));
  8405. }
  8406. LONG
  8407. WINAPI
  8408. lineInitializeExA(
  8409. LPHLINEAPP lphLineApp,
  8410. HINSTANCE hInstance,
  8411. LINECALLBACK lpfnCallback,
  8412. LPCSTR lpszFriendlyAppName,
  8413. LPDWORD lpdwNumDevs,
  8414. LPDWORD lpdwAPIVersion,
  8415. LPLINEINITIALIZEEXPARAMS lpLineInitializeExParams
  8416. )
  8417. {
  8418. LONG lResult;
  8419. WCHAR *pszFriendlyAppNameW;
  8420. if (lpszFriendlyAppName)
  8421. {
  8422. if (IsBadStringPtrA (lpszFriendlyAppName, (DWORD) -1))
  8423. {
  8424. LOG((TL_ERROR,
  8425. "lineInitializeEx: bad lpszFriendlyAppName (x%p)",
  8426. lpszFriendlyAppName
  8427. ));
  8428. return LINEERR_INVALPOINTER;
  8429. }
  8430. if (!(pszFriendlyAppNameW = MultiToWide (lpszFriendlyAppName)))
  8431. {
  8432. return LINEERR_INVALPOINTER;
  8433. }
  8434. }
  8435. else
  8436. {
  8437. pszFriendlyAppNameW = NULL;
  8438. }
  8439. lResult = lineInitializeExW(
  8440. lphLineApp,
  8441. hInstance,
  8442. lpfnCallback,
  8443. pszFriendlyAppNameW,
  8444. lpdwNumDevs,
  8445. lpdwAPIVersion,
  8446. lpLineInitializeExParams
  8447. );
  8448. if (pszFriendlyAppNameW)
  8449. {
  8450. ClientFree (pszFriendlyAppNameW);
  8451. }
  8452. return lResult;
  8453. }
  8454. void
  8455. PASCAL
  8456. lineMakeCallPostProcess(
  8457. PASYNCEVENTMSG pMsg
  8458. )
  8459. {
  8460. LOG((TL_TRACE, "lineMakeCallPostProcess: enter"));
  8461. LOG((TL_INFO,
  8462. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  8463. pMsg->Param1,
  8464. pMsg->Param2,
  8465. pMsg->Param3,
  8466. pMsg->Param4
  8467. ));
  8468. if (pMsg->Param2 == 0)
  8469. {
  8470. HCALL hCall = (HCALL) pMsg->Param3;
  8471. LPHCALL lphCall = (LPDWORD) ReferenceObject (ghHandleTable, pMsg->Param4, 0);
  8472. // We don't need the handle to the pointer any more...
  8473. DereferenceObject (ghHandleTable, pMsg->Param4, 2);
  8474. try
  8475. {
  8476. if (gbNTVDMClient)
  8477. {
  8478. #ifndef _WIN64
  8479. LPHCALL lphCallVDM = (LPHCALL) gpfnWOWGetVDMPointer (
  8480. (DWORD) lphCall,
  8481. sizeof(HCALL),
  8482. TRUE // fProtectedMode
  8483. );
  8484. if (lphCallVDM)
  8485. {
  8486. *lphCallVDM = hCall;
  8487. }
  8488. else
  8489. {
  8490. pMsg->Param2 = LINEERR_INVALPOINTER;
  8491. }
  8492. #endif
  8493. }
  8494. else
  8495. {
  8496. *lphCall = hCall;
  8497. }
  8498. }
  8499. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  8500. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  8501. {
  8502. pMsg->Param2 = LINEERR_INVALPOINTER;
  8503. }
  8504. }
  8505. }
  8506. LONG
  8507. WINAPI
  8508. lineMakeCallW(
  8509. HLINE hLine,
  8510. LPHCALL lphCall,
  8511. LPCWSTR lpszDestAddress,
  8512. DWORD dwCountryCode,
  8513. LPLINECALLPARAMS const lpCallParams
  8514. )
  8515. {
  8516. FUNC_ARGS funcArgs =
  8517. {
  8518. MAKELONG (LINE_FUNC | ASYNC | 7, lMakeCall),
  8519. {
  8520. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  8521. (ULONG_PTR) hLine,
  8522. (ULONG_PTR) lphCall,
  8523. (ULONG_PTR) lpszDestAddress,
  8524. (ULONG_PTR) dwCountryCode,
  8525. (ULONG_PTR) lpCallParams,
  8526. (ULONG_PTR) TAPI_NO_DATA // dwAsciiCallParamsCodePage
  8527. },
  8528. {
  8529. Dword,
  8530. Dword,
  8531. Dword,
  8532. lpszW,
  8533. Dword,
  8534. lpSet_Struct,
  8535. Dword
  8536. }
  8537. };
  8538. DWORD hPointer = 0;
  8539. LONG lResult;
  8540. if (!gbNTVDMClient)
  8541. {
  8542. if (IsBadDwordPtr (lphCall))
  8543. {
  8544. return LINEERR_INVALPOINTER;
  8545. }
  8546. hPointer = NewObject (ghHandleTable, (PVOID)lphCall, NULL);
  8547. if (0 == hPointer)
  8548. {
  8549. return LINEERR_NOMEM;
  8550. }
  8551. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  8552. }
  8553. if (!lpszDestAddress)
  8554. {
  8555. //
  8556. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  8557. //
  8558. funcArgs.ArgTypes[3] = Dword;
  8559. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  8560. }
  8561. if (!lpCallParams)
  8562. {
  8563. //
  8564. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  8565. //
  8566. funcArgs.ArgTypes[5] = Dword;
  8567. funcArgs.Args[5] = (ULONG_PTR) TAPI_NO_DATA;
  8568. }
  8569. lResult = (DOFUNC (&funcArgs, "lineMakeCall"));
  8570. if (hPointer && 0 > lResult)
  8571. {
  8572. DereferenceObject (ghHandleTable, hPointer, 1);
  8573. }
  8574. return lResult;
  8575. }
  8576. LONG
  8577. WINAPI
  8578. lineMakeCallA(
  8579. HLINE hLine,
  8580. LPHCALL lphCall,
  8581. LPCSTR lpszDestAddress,
  8582. DWORD dwCountryCode,
  8583. LPLINECALLPARAMS const lpCallParams
  8584. )
  8585. {
  8586. LONG lResult;
  8587. FUNC_ARGS funcArgs =
  8588. {
  8589. MAKELONG (LINE_FUNC | ASYNC | 7, lMakeCall),
  8590. {
  8591. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  8592. (ULONG_PTR) hLine,
  8593. (ULONG_PTR) lphCall,
  8594. (ULONG_PTR) 0,
  8595. (ULONG_PTR) dwCountryCode,
  8596. (ULONG_PTR) lpCallParams,
  8597. (ULONG_PTR) GetACP() // dwAsciiCallParamsCodePage
  8598. },
  8599. {
  8600. Dword,
  8601. Dword,
  8602. Dword,
  8603. lpszW,
  8604. Dword,
  8605. lpSet_Struct,
  8606. Dword
  8607. }
  8608. };
  8609. DWORD hPointer = 0;
  8610. LOG((TL_TRACE, "Entering lineMakeCallA"));
  8611. LOG((TL_INFO, " hLine= 0x%08lx", hLine));
  8612. if (!lpszDestAddress)
  8613. {
  8614. //
  8615. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  8616. //
  8617. funcArgs.ArgTypes[3] = Dword;
  8618. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  8619. }
  8620. else if (IsBadStringPtrA (lpszDestAddress, (DWORD) -1))
  8621. {
  8622. LOG((TL_ERROR, "lineMakeCall: Bad lpszDestAddress pointer"));
  8623. return LINEERR_INVALPOINTER;
  8624. }
  8625. else if (!(funcArgs.Args[3] = (ULONG_PTR) NotSoWideStringToWideString(
  8626. lpszDestAddress,
  8627. (DWORD) -1
  8628. )))
  8629. {
  8630. return LINEERR_OPERATIONFAILED; // really either NOMEM. INVALPOINTER
  8631. }
  8632. if (!gbNTVDMClient)
  8633. {
  8634. if (IsBadDwordPtr (lphCall))
  8635. {
  8636. return LINEERR_INVALPOINTER;
  8637. }
  8638. hPointer = NewObject (ghHandleTable, (PVOID)lphCall, NULL);
  8639. if (0 == hPointer)
  8640. {
  8641. lResult = LINEERR_NOMEM;
  8642. goto _return;
  8643. }
  8644. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  8645. }
  8646. if (!lpCallParams)
  8647. {
  8648. //
  8649. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  8650. //
  8651. funcArgs.ArgTypes[5] = Dword;
  8652. funcArgs.Args[5] = (ULONG_PTR) TAPI_NO_DATA;
  8653. }
  8654. lResult = DOFUNC (&funcArgs, "lineMakeCall");
  8655. if (hPointer && 0 > lResult)
  8656. {
  8657. DereferenceObject (ghHandleTable, hPointer, 1);
  8658. }
  8659. _return:
  8660. if (funcArgs.Args[3] != (ULONG_PTR) TAPI_NO_DATA)
  8661. {
  8662. ClientFree ((LPVOID) funcArgs.Args[3]);
  8663. }
  8664. return lResult;
  8665. }
  8666. LONG
  8667. WINAPI
  8668. lineMakeCall(
  8669. HLINE hLine,
  8670. LPHCALL lphCall,
  8671. LPCSTR lpszDestAddress,
  8672. DWORD dwCountryCode,
  8673. LPLINECALLPARAMS const lpCallParams
  8674. )
  8675. {
  8676. return lineMakeCallA(
  8677. hLine,
  8678. lphCall,
  8679. lpszDestAddress,
  8680. dwCountryCode,
  8681. lpCallParams
  8682. );
  8683. }
  8684. LONG
  8685. WINAPI
  8686. lineMonitorDigits(
  8687. HCALL hCall,
  8688. DWORD dwDigitModes
  8689. )
  8690. {
  8691. FUNC_ARGS funcArgs =
  8692. {
  8693. MAKELONG (LINE_FUNC | SYNC | 2, lMonitorDigits),
  8694. {
  8695. (ULONG_PTR) hCall,
  8696. (ULONG_PTR) dwDigitModes
  8697. },
  8698. {
  8699. Dword,
  8700. Dword
  8701. }
  8702. };
  8703. return (DOFUNC (&funcArgs, "lineMonitorDigits"));
  8704. }
  8705. LONG
  8706. WINAPI
  8707. lineMonitorMedia(
  8708. HCALL hCall,
  8709. DWORD dwMediaModes
  8710. )
  8711. {
  8712. FUNC_ARGS funcArgs =
  8713. {
  8714. MAKELONG (LINE_FUNC | SYNC | 2, lMonitorMedia),
  8715. {
  8716. (ULONG_PTR) hCall,
  8717. (ULONG_PTR) dwMediaModes
  8718. },
  8719. {
  8720. Dword,
  8721. Dword
  8722. }
  8723. };
  8724. return (DOFUNC (&funcArgs, "lineMonitorMedia"));
  8725. }
  8726. LONG
  8727. WINAPI
  8728. lineMonitorTones(
  8729. HCALL hCall,
  8730. LPLINEMONITORTONE const lpToneList,
  8731. DWORD dwNumEntries
  8732. )
  8733. {
  8734. FUNC_ARGS funcArgs =
  8735. {
  8736. MAKELONG (LINE_FUNC | SYNC | 4, lMonitorTones),
  8737. {
  8738. (ULONG_PTR) hCall,
  8739. (ULONG_PTR) lpToneList,
  8740. (ULONG_PTR) dwNumEntries * sizeof(LINEMONITORTONE),
  8741. (ULONG_PTR) 0 // dwToneListID, remotesp only
  8742. },
  8743. {
  8744. Dword,
  8745. lpSet_SizeToFollow,
  8746. Size,
  8747. Dword
  8748. }
  8749. };
  8750. if (!lpToneList)
  8751. {
  8752. //
  8753. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  8754. //
  8755. funcArgs.ArgTypes[1] = Dword;
  8756. funcArgs.Args[1] = (ULONG_PTR) TAPI_NO_DATA;
  8757. funcArgs.ArgTypes[2] = Dword;
  8758. }
  8759. return (DOFUNC (&funcArgs, "lineMonitorTones"));
  8760. }
  8761. LONG
  8762. WINAPI
  8763. lineNegotiateAPIVersion(
  8764. HLINEAPP hLineApp,
  8765. DWORD dwDeviceID,
  8766. DWORD dwAPILowVersion,
  8767. DWORD dwAPIHighVersion,
  8768. LPDWORD lpdwAPIVersion,
  8769. LPLINEEXTENSIONID lpExtensionID
  8770. )
  8771. {
  8772. FUNC_ARGS funcArgs =
  8773. {
  8774. MAKELONG (LINE_FUNC | SYNC | 7, lNegotiateAPIVersion),
  8775. {
  8776. (ULONG_PTR) hLineApp,
  8777. (ULONG_PTR) dwDeviceID,
  8778. (ULONG_PTR) dwAPILowVersion,
  8779. (ULONG_PTR) dwAPIHighVersion,
  8780. (ULONG_PTR) lpdwAPIVersion,
  8781. (ULONG_PTR) lpExtensionID,
  8782. (ULONG_PTR) sizeof(LINEEXTENSIONID)
  8783. },
  8784. {
  8785. hXxxApp,
  8786. Dword,
  8787. Dword,
  8788. Dword,
  8789. lpDword,
  8790. lpGet_SizeToFollow,
  8791. Size
  8792. }
  8793. };
  8794. if (dwAPIHighVersion > TAPI_CURRENT_VERSION)
  8795. {
  8796. funcArgs.Args[3] = TAPI_CURRENT_VERSION;
  8797. }
  8798. if ((LPVOID) lpdwAPIVersion == (LPVOID) lpExtensionID)
  8799. {
  8800. return LINEERR_INVALPOINTER;
  8801. }
  8802. return (DOFUNC (&funcArgs, "lineNegotiateAPIVersion"));
  8803. }
  8804. LONG
  8805. WINAPI
  8806. lineNegotiateExtVersion(
  8807. HLINEAPP hLineApp,
  8808. DWORD dwDeviceID,
  8809. DWORD dwAPIVersion,
  8810. DWORD dwExtLowVersion,
  8811. DWORD dwExtHighVersion,
  8812. LPDWORD lpdwExtVersion
  8813. )
  8814. {
  8815. FUNC_ARGS funcArgs =
  8816. {
  8817. MAKELONG (LINE_FUNC | SYNC | 6, lNegotiateExtVersion),
  8818. {
  8819. (ULONG_PTR) hLineApp,
  8820. (ULONG_PTR) dwDeviceID,
  8821. (ULONG_PTR) dwAPIVersion,
  8822. (ULONG_PTR) dwExtLowVersion,
  8823. (ULONG_PTR) dwExtHighVersion,
  8824. (ULONG_PTR) lpdwExtVersion
  8825. },
  8826. {
  8827. hXxxApp,
  8828. Dword,
  8829. Dword,
  8830. Dword,
  8831. Dword,
  8832. lpDword
  8833. }
  8834. };
  8835. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  8836. {
  8837. return LINEERR_INCOMPATIBLEAPIVERSION;
  8838. }
  8839. return (DOFUNC (&funcArgs, "lineNegotiateExtVersion"));
  8840. }
  8841. LONG
  8842. WINAPI
  8843. lineOpenW(
  8844. HLINEAPP hLineApp,
  8845. DWORD dwDeviceID,
  8846. LPHLINE lphLine,
  8847. DWORD dwAPIVersion,
  8848. DWORD dwExtVersion,
  8849. DWORD_PTR dwCallbackInstance,
  8850. DWORD dwPrivileges,
  8851. DWORD dwMediaModes,
  8852. LPLINECALLPARAMS const lpCallParams
  8853. )
  8854. {
  8855. LONG lResult;
  8856. DWORD hCallbackInstance = 0;
  8857. FUNC_ARGS funcArgs =
  8858. {
  8859. MAKELONG (LINE_FUNC | SYNC | 12, lOpen),
  8860. {
  8861. (ULONG_PTR) hLineApp,
  8862. (ULONG_PTR) dwDeviceID,
  8863. (ULONG_PTR) lphLine,
  8864. (ULONG_PTR) dwAPIVersion,
  8865. (ULONG_PTR) dwExtVersion,
  8866. (ULONG_PTR) dwCallbackInstance,
  8867. (ULONG_PTR) dwPrivileges,
  8868. (ULONG_PTR) dwMediaModes,
  8869. (ULONG_PTR) lpCallParams,
  8870. (ULONG_PTR) TAPI_NO_DATA, // dwAsciiCallParamsCodePage
  8871. (ULONG_PTR) 0,
  8872. (ULONG_PTR) 0 // LINEOPEN_PARAMS.hRemoteLine
  8873. },
  8874. {
  8875. hXxxApp,
  8876. Dword,
  8877. lpDword,
  8878. Dword,
  8879. Dword,
  8880. Dword,
  8881. Dword,
  8882. Dword,
  8883. lpSet_Struct,
  8884. Dword,
  8885. Dword,
  8886. Dword
  8887. }
  8888. };
  8889. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  8890. {
  8891. return LINEERR_INCOMPATIBLEAPIVERSION;
  8892. }
  8893. if (dwDeviceID != LINEMAPPER &&
  8894. !(dwPrivileges &
  8895. (LINEOPENOPTION_PROXY|LINEOPENOPTION_SINGLEADDRESS)))
  8896. {
  8897. //
  8898. // Reset Arg & ArgType so no inval ptr err,
  8899. // & TAPI_NO_DATA is indicated
  8900. //
  8901. funcArgs.ArgTypes[8] = Dword;
  8902. funcArgs.Args[8] = (ULONG_PTR) TAPI_NO_DATA;
  8903. }
  8904. if (0 != dwCallbackInstance)
  8905. {
  8906. hCallbackInstance = NewObject (ghHandleTable, (PVOID)dwCallbackInstance, (PVOID)UIntToPtr(hLineApp));
  8907. if (0 == hCallbackInstance)
  8908. {
  8909. return LINEERR_NOMEM;
  8910. }
  8911. funcArgs.Args[5] = hCallbackInstance;
  8912. }
  8913. lResult = (DOFUNC (&funcArgs, "lineOpen"));
  8914. //
  8915. // If we we managed a successful LINEMAPPER & there's an LCR hook
  8916. // for this function then call it to allow it to override our
  8917. // results if it wants to. (One good thing about calling it after
  8918. // the fact is that we leverage our param checking.)
  8919. //
  8920. if (dwDeviceID == LINEMAPPER &&
  8921. lResult == 0 &&
  8922. IsLeastCostRoutingEnabled() &&
  8923. pfnLineOpenWLCR)
  8924. {
  8925. lResult = (*pfnLineOpenWLCR)(
  8926. hLineApp,
  8927. dwDeviceID,
  8928. lphLine,
  8929. dwAPIVersion,
  8930. dwExtVersion,
  8931. dwCallbackInstance,
  8932. dwPrivileges,
  8933. dwMediaModes,
  8934. lpCallParams
  8935. );
  8936. }
  8937. #if DBG
  8938. if ( !IsBadWritePtr( (LPBYTE)lphLine, 4 ) )
  8939. {
  8940. LOG((TL_TRACE,
  8941. "Returning from lineOpenW, *lphLine = 0x%08lx",
  8942. *lphLine
  8943. ));
  8944. }
  8945. LOG((TL_TRACE, "Returning from lineOpenW, retcode = 0x%08lx", lResult));
  8946. #endif
  8947. if (lResult && 0 != hCallbackInstance)
  8948. {
  8949. DereferenceObject (ghHandleTable, hCallbackInstance, 1);
  8950. }
  8951. return( lResult );
  8952. }
  8953. LONG
  8954. WINAPI
  8955. lineOpenA(
  8956. HLINEAPP hLineApp,
  8957. DWORD dwDeviceID,
  8958. LPHLINE lphLine,
  8959. DWORD dwAPIVersion,
  8960. DWORD dwExtVersion,
  8961. DWORD_PTR dwCallbackInstance,
  8962. DWORD dwPrivileges,
  8963. DWORD dwMediaModes,
  8964. LPLINECALLPARAMS const lpCallParams
  8965. )
  8966. {
  8967. LONG lResult;
  8968. DWORD hCallbackInstance = 0;
  8969. FUNC_ARGS funcArgs =
  8970. {
  8971. MAKELONG (LINE_FUNC | SYNC | 12, lOpen),
  8972. {
  8973. (ULONG_PTR) hLineApp,
  8974. (ULONG_PTR) dwDeviceID,
  8975. (ULONG_PTR) lphLine,
  8976. (ULONG_PTR) dwAPIVersion,
  8977. (ULONG_PTR) dwExtVersion,
  8978. (ULONG_PTR) dwCallbackInstance,
  8979. (ULONG_PTR) dwPrivileges,
  8980. (ULONG_PTR) dwMediaModes,
  8981. (ULONG_PTR) lpCallParams,
  8982. (ULONG_PTR) GetACP(), // dwAsciiCallParamsCodePage
  8983. (ULONG_PTR) 0,
  8984. (ULONG_PTR) 0 // LINEOPEN_PARAMS.hRemoteLine
  8985. },
  8986. {
  8987. hXxxApp,
  8988. Dword,
  8989. lpDword,
  8990. Dword,
  8991. Dword,
  8992. Dword,
  8993. Dword,
  8994. Dword,
  8995. lpSet_Struct,
  8996. Dword,
  8997. Dword,
  8998. Dword
  8999. }
  9000. };
  9001. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  9002. {
  9003. return LINEERR_INCOMPATIBLEAPIVERSION;
  9004. }
  9005. if (dwDeviceID != LINEMAPPER &&
  9006. !(dwPrivileges & (LINEOPENOPTION_PROXY|LINEOPENOPTION_SINGLEADDRESS)))
  9007. {
  9008. //
  9009. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  9010. //
  9011. funcArgs.ArgTypes[8] = Dword;
  9012. funcArgs.Args[8] = (ULONG_PTR) TAPI_NO_DATA;
  9013. }
  9014. if (0 != dwCallbackInstance)
  9015. {
  9016. hCallbackInstance = NewObject (ghHandleTable, (PVOID)dwCallbackInstance, (PVOID)UIntToPtr(hLineApp));
  9017. if (0 == hCallbackInstance)
  9018. {
  9019. return LINEERR_NOMEM;
  9020. }
  9021. funcArgs.Args[5] = hCallbackInstance;
  9022. }
  9023. lResult = (DOFUNC (&funcArgs, "lineOpen"));
  9024. //
  9025. // If we we managed a successful LINEMAPPER & there's an LCR hook
  9026. // for this function then call it to allow it to override our
  9027. // results if it wants to. (One good thing about calling it after
  9028. // the fact is that we leverage our param checking.)
  9029. //
  9030. if (dwDeviceID == LINEMAPPER &&
  9031. lResult == 0 &&
  9032. IsLeastCostRoutingEnabled() &&
  9033. pfnLineOpenALCR)
  9034. {
  9035. lResult = (*pfnLineOpenALCR)(
  9036. hLineApp,
  9037. dwDeviceID,
  9038. lphLine,
  9039. dwAPIVersion,
  9040. dwExtVersion,
  9041. dwCallbackInstance,
  9042. dwPrivileges,
  9043. dwMediaModes,
  9044. lpCallParams
  9045. );
  9046. }
  9047. #if DBG
  9048. if ( !IsBadWritePtr( (LPBYTE)lphLine, 4 ) )
  9049. {
  9050. LOG((TL_TRACE,
  9051. "Returning from lineOpenA, *lphLine = 0x%08lx",
  9052. *lphLine
  9053. ));
  9054. }
  9055. LOG((TL_TRACE, "Returning from lineOpenA, retcode = 0x%08lx", lResult));
  9056. #endif
  9057. if (lResult && 0 != hCallbackInstance)
  9058. {
  9059. DereferenceObject (ghHandleTable, hCallbackInstance, 1);
  9060. }
  9061. return( lResult );
  9062. }
  9063. LONG
  9064. WINAPI
  9065. lineOpen(
  9066. HLINEAPP hLineApp,
  9067. DWORD dwDeviceID,
  9068. LPHLINE lphLine,
  9069. DWORD dwAPIVersion,
  9070. DWORD dwExtVersion,
  9071. DWORD_PTR dwCallbackInstance,
  9072. DWORD dwPrivileges,
  9073. DWORD dwMediaModes,
  9074. LPLINECALLPARAMS const lpCallParams
  9075. )
  9076. {
  9077. return lineOpenA(
  9078. hLineApp,
  9079. dwDeviceID,
  9080. lphLine,
  9081. dwAPIVersion,
  9082. dwExtVersion,
  9083. dwCallbackInstance,
  9084. dwPrivileges,
  9085. dwMediaModes,
  9086. lpCallParams
  9087. );
  9088. }
  9089. void
  9090. PASCAL
  9091. lineParkAPostProcess(
  9092. PASYNCEVENTMSG pMsg
  9093. )
  9094. {
  9095. LOG((TL_TRACE, "lineParkAPostProcess: enter"));
  9096. LOG((TL_INFO,
  9097. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  9098. pMsg->Param1,
  9099. pMsg->Param2,
  9100. pMsg->Param3,
  9101. pMsg->Param4
  9102. ));
  9103. if (pMsg->Param2 == 0)
  9104. {
  9105. DWORD dwSize = (DWORD) pMsg->Param4;
  9106. LPVARSTRING pNonDirAddress = (LPVARSTRING) ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  9107. // We don't need the handle to the pointer any more...
  9108. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  9109. try
  9110. {
  9111. if (gbNTVDMClient)
  9112. {
  9113. #ifndef _WIN64
  9114. LPVARSTRING pNonDirAddressVDM = (LPVARSTRING)
  9115. gpfnWOWGetVDMPointer(
  9116. (DWORD) pNonDirAddress,
  9117. dwSize,
  9118. TRUE // fProtectedMode
  9119. );
  9120. if (pNonDirAddressVDM)
  9121. {
  9122. CopyMemory(
  9123. pNonDirAddressVDM,
  9124. (LPBYTE) (pMsg + 1),
  9125. dwSize
  9126. );
  9127. if (pNonDirAddressVDM->dwUsedSize >= sizeof (VARSTRING) &&
  9128. pNonDirAddressVDM->dwStringSize != 0)
  9129. {
  9130. TCHAR *p;
  9131. DWORD dwStringSize =
  9132. pNonDirAddressVDM->dwStringSize /
  9133. sizeof (WCHAR);
  9134. if ((p = ClientAlloc(pNonDirAddressVDM->dwStringSize)))
  9135. {
  9136. pNonDirAddressVDM->dwStringFormat =
  9137. STRINGFORMAT_ASCII;
  9138. pNonDirAddressVDM->dwStringSize =
  9139. dwStringSize;
  9140. WideCharToMultiByte(
  9141. GetACP(),
  9142. 0,
  9143. (LPCWSTR) (((LPBYTE) pNonDirAddressVDM) +
  9144. pNonDirAddressVDM->dwStringOffset),
  9145. dwStringSize,
  9146. (LPSTR) p,
  9147. dwStringSize,
  9148. NULL,
  9149. NULL
  9150. );
  9151. CopyMemory(
  9152. (((LPBYTE) pNonDirAddressVDM) +
  9153. pNonDirAddressVDM->dwStringOffset),
  9154. p,
  9155. dwStringSize
  9156. );
  9157. ClientFree (p);
  9158. }
  9159. }
  9160. }
  9161. else
  9162. {
  9163. pMsg->Param2 = LINEERR_INVALPOINTER;
  9164. }
  9165. #endif
  9166. }
  9167. else
  9168. {
  9169. CopyMemory (pNonDirAddress, (LPBYTE) (pMsg + 1), dwSize);
  9170. if (pNonDirAddress->dwUsedSize >= sizeof (VARSTRING) &&
  9171. pNonDirAddress->dwStringSize != 0)
  9172. {
  9173. TCHAR *p;
  9174. DWORD dwStringSize = pNonDirAddress->dwStringSize /
  9175. sizeof (WCHAR);
  9176. if ((p = ClientAlloc (pNonDirAddress->dwStringSize)))
  9177. {
  9178. pNonDirAddress->dwStringFormat = STRINGFORMAT_ASCII;
  9179. pNonDirAddress->dwStringSize = dwStringSize;
  9180. WideCharToMultiByte(
  9181. GetACP(),
  9182. 0,
  9183. (LPCWSTR) (((LPBYTE) pNonDirAddress) +
  9184. pNonDirAddress->dwStringOffset),
  9185. dwStringSize,
  9186. (LPSTR) p,
  9187. dwStringSize,
  9188. NULL,
  9189. NULL
  9190. );
  9191. CopyMemory(
  9192. (((LPBYTE) pNonDirAddress) +
  9193. pNonDirAddress->dwStringOffset),
  9194. p,
  9195. dwStringSize
  9196. );
  9197. ClientFree (p);
  9198. }
  9199. }
  9200. }
  9201. }
  9202. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  9203. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  9204. {
  9205. pMsg->Param2 = LINEERR_INVALPOINTER;
  9206. }
  9207. }
  9208. }
  9209. LONG
  9210. WINAPI
  9211. lineParkW(
  9212. HCALL hCall,
  9213. DWORD dwParkMode,
  9214. LPCWSTR lpszDirAddress,
  9215. LPVARSTRING lpNonDirAddress
  9216. )
  9217. {
  9218. FUNC_ARGS funcArgs =
  9219. {
  9220. MAKELONG (LINE_FUNC | ASYNC | 6, lPark),
  9221. {
  9222. (ULONG_PTR) 0, // post process proc
  9223. (ULONG_PTR) hCall,
  9224. (ULONG_PTR) dwParkMode,
  9225. (ULONG_PTR) TAPI_NO_DATA, // lpszDirAddress,
  9226. (ULONG_PTR) lpNonDirAddress, // pass ptr as Dword for post proc
  9227. (ULONG_PTR) TAPI_NO_DATA, // lpNonDirAddress, pass ptr as
  9228. // lpGet_Xx for IsValPtr chk
  9229. },
  9230. {
  9231. Dword,
  9232. Dword,
  9233. Dword,
  9234. Dword, // lpszW,
  9235. Dword,
  9236. Dword, // lpGet_Struct
  9237. }
  9238. };
  9239. DWORD hPointer = 0;
  9240. LONG lResult;
  9241. if (dwParkMode == LINEPARKMODE_DIRECTED)
  9242. {
  9243. funcArgs.ArgTypes[3] = lpszW;
  9244. funcArgs.Args[3] = (ULONG_PTR) lpszDirAddress;
  9245. }
  9246. else if (dwParkMode == LINEPARKMODE_NONDIRECTED)
  9247. {
  9248. if ( !lpNonDirAddress )
  9249. {
  9250. return LINEERR_INVALPOINTER;
  9251. }
  9252. //
  9253. // Set post process proc
  9254. //
  9255. hPointer = NewObject (ghHandleTable, (PVOID)lpNonDirAddress, NULL);
  9256. if (0 == hPointer)
  9257. {
  9258. return LINEERR_NOMEM;
  9259. }
  9260. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  9261. funcArgs.Args[0] = (ULONG_PTR)
  9262. GetFunctionIndex(lineDevSpecificPostProcess);
  9263. funcArgs.ArgTypes[5] = lpGet_Struct;
  9264. funcArgs.Args[5] = (ULONG_PTR) lpNonDirAddress;
  9265. }
  9266. lResult = (DOFUNC (&funcArgs, "linePark"));
  9267. if (0 > lResult && hPointer)
  9268. {
  9269. DereferenceObject (ghHandleTable, hPointer, 1);
  9270. }
  9271. return lResult;
  9272. }
  9273. LONG
  9274. WINAPI
  9275. lineParkA(
  9276. HCALL hCall,
  9277. DWORD dwParkMode,
  9278. LPCSTR lpszDirAddress,
  9279. LPVARSTRING lpNonDirAddress
  9280. )
  9281. {
  9282. FUNC_ARGS funcArgs =
  9283. {
  9284. MAKELONG (LINE_FUNC | ASYNC | 6, lPark),
  9285. {
  9286. (ULONG_PTR) 0, // post process proc
  9287. (ULONG_PTR) hCall,
  9288. (ULONG_PTR) dwParkMode,
  9289. (ULONG_PTR) TAPI_NO_DATA, // lpszDirAddress,
  9290. (ULONG_PTR) lpNonDirAddress, // pass ptr as Dword for post proc
  9291. (ULONG_PTR) TAPI_NO_DATA, // lpNonDirAddress, pass ptr as
  9292. // lpGet_Xx for IsValPtr chk
  9293. },
  9294. {
  9295. Dword,
  9296. Dword,
  9297. Dword,
  9298. Dword, // lpszW,
  9299. Dword,
  9300. Dword, // lpGet_Struct
  9301. }
  9302. };
  9303. LONG lResult;
  9304. PWSTR szTempPtr = NULL;
  9305. DWORD hPointer = 0;
  9306. switch (dwParkMode)
  9307. {
  9308. case LINEPARKMODE_DIRECTED:
  9309. {
  9310. if (IsBadStringPtrA (lpszDirAddress, (DWORD) -1))
  9311. {
  9312. return LINEERR_INVALPOINTER;
  9313. }
  9314. szTempPtr = NotSoWideStringToWideString (lpszDirAddress, (DWORD) -1);
  9315. funcArgs.ArgTypes[3] = lpszW;
  9316. funcArgs.Args[3] = (ULONG_PTR) szTempPtr;
  9317. break;
  9318. }
  9319. case LINEPARKMODE_NONDIRECTED:
  9320. {
  9321. if ( !lpNonDirAddress )
  9322. {
  9323. return LINEERR_INVALPOINTER;
  9324. }
  9325. //
  9326. // Set post process proc
  9327. //
  9328. hPointer = NewObject (ghHandleTable, (PVOID)lpNonDirAddress, NULL);
  9329. if (0 == hPointer)
  9330. {
  9331. return LINEERR_NOMEM;
  9332. }
  9333. funcArgs.Args[4] = (ULONG_PTR)hPointer;
  9334. funcArgs.Args[0] = (ULONG_PTR)
  9335. GetFunctionIndex(lineParkAPostProcess);
  9336. funcArgs.ArgTypes[5] = lpGet_Struct;
  9337. if (gbNTVDMClient == FALSE)
  9338. {
  9339. funcArgs.Args[5] = (ULONG_PTR) lpNonDirAddress;
  9340. }
  9341. else
  9342. {
  9343. #ifndef _WIN64
  9344. if (!gpfnWOWGetVDMPointer ||
  9345. !(funcArgs.Args[5] = (ULONG_PTR) gpfnWOWGetVDMPointer(
  9346. (DWORD) lpNonDirAddress,
  9347. sizeof (VARSTRING), // what if it's > sizeof(VARS)?
  9348. TRUE // fProtectedMode
  9349. )))
  9350. #endif
  9351. {
  9352. return LINEERR_OPERATIONFAILED;
  9353. }
  9354. }
  9355. break;
  9356. }
  9357. default:
  9358. return LINEERR_INVALPARKMODE;
  9359. }
  9360. lResult = (DOFUNC (&funcArgs, "linePark"));
  9361. if (0 > lResult && hPointer)
  9362. {
  9363. DereferenceObject (ghHandleTable, hPointer, 1);
  9364. }
  9365. if (szTempPtr)
  9366. {
  9367. ClientFree (szTempPtr);
  9368. }
  9369. return lResult;
  9370. }
  9371. LONG
  9372. WINAPI
  9373. linePark(
  9374. HCALL hCall,
  9375. DWORD dwParkMode,
  9376. LPCSTR lpszDirAddress,
  9377. LPVARSTRING lpNonDirAddress
  9378. )
  9379. {
  9380. return lineParkA (hCall, dwParkMode, lpszDirAddress, lpNonDirAddress);
  9381. }
  9382. LONG
  9383. WINAPI
  9384. linePickupW(
  9385. HLINE hLine,
  9386. DWORD dwAddressID,
  9387. LPHCALL lphCall,
  9388. LPCWSTR lpszDestAddress,
  9389. LPCWSTR lpszGroupID
  9390. )
  9391. {
  9392. FUNC_ARGS funcArgs =
  9393. {
  9394. MAKELONG (LINE_FUNC | ASYNC | 6, lPickup),
  9395. {
  9396. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  9397. (ULONG_PTR) hLine,
  9398. (ULONG_PTR) dwAddressID,
  9399. (ULONG_PTR) lphCall,
  9400. (ULONG_PTR) lpszDestAddress,
  9401. (ULONG_PTR) lpszGroupID
  9402. },
  9403. {
  9404. Dword,
  9405. Dword,
  9406. Dword,
  9407. Dword,
  9408. lpszW,
  9409. lpszW
  9410. }
  9411. };
  9412. DWORD hPointer = 0;
  9413. LONG lResult;
  9414. if (!lpszDestAddress)
  9415. {
  9416. //
  9417. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  9418. //
  9419. funcArgs.ArgTypes[4] = Dword;
  9420. funcArgs.Args[4] = (ULONG_PTR) TAPI_NO_DATA;
  9421. }
  9422. if (!lpszGroupID)
  9423. {
  9424. //
  9425. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  9426. //
  9427. funcArgs.ArgTypes[5] = Dword;
  9428. funcArgs.Args[5] = (ULONG_PTR) TAPI_NO_DATA;
  9429. }
  9430. if (!gbNTVDMClient)
  9431. {
  9432. if (IsBadDwordPtr (lphCall))
  9433. {
  9434. return LINEERR_INVALPOINTER;
  9435. }
  9436. hPointer = NewObject (ghHandleTable, (PVOID)lphCall, NULL);
  9437. if (0 == hPointer)
  9438. {
  9439. return LINEERR_NOMEM;
  9440. }
  9441. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  9442. }
  9443. lResult = (DOFUNC (&funcArgs, "linePickup"));
  9444. if (0 > lResult && hPointer)
  9445. {
  9446. DereferenceObject (ghHandleTable, hPointer, 1);
  9447. }
  9448. return lResult;
  9449. }
  9450. LONG
  9451. WINAPI
  9452. linePickupA(
  9453. HLINE hLine,
  9454. DWORD dwAddressID,
  9455. LPHCALL lphCall,
  9456. LPCSTR lpszDestAddress,
  9457. LPCSTR lpszGroupID
  9458. )
  9459. {
  9460. LONG lResult;
  9461. PWSTR szTempPtr;
  9462. PWSTR szTempPtr2;
  9463. if ((lpszDestAddress && IsBadStringPtrA (lpszDestAddress, (DWORD) -1)) ||
  9464. (lpszGroupID && IsBadStringPtrA (lpszGroupID, (DWORD) -1)))
  9465. {
  9466. return LINEERR_INVALPOINTER;
  9467. }
  9468. szTempPtr = NotSoWideStringToWideString (lpszDestAddress, (DWORD) -1);
  9469. szTempPtr2 = NotSoWideStringToWideString (lpszGroupID, (DWORD) -1);
  9470. lResult = linePickupW (hLine, dwAddressID, lphCall, szTempPtr, szTempPtr2);
  9471. if (szTempPtr)
  9472. {
  9473. ClientFree (szTempPtr);
  9474. }
  9475. if (szTempPtr2)
  9476. {
  9477. ClientFree (szTempPtr2);
  9478. }
  9479. return lResult;
  9480. }
  9481. LONG
  9482. WINAPI
  9483. linePickup(
  9484. HLINE hLine,
  9485. DWORD dwAddressID,
  9486. LPHCALL lphCall,
  9487. LPCSTR lpszDestAddress,
  9488. LPCSTR lpszGroupID
  9489. )
  9490. {
  9491. return linePickupA(
  9492. hLine,
  9493. dwAddressID,
  9494. lphCall,
  9495. lpszDestAddress,
  9496. lpszGroupID
  9497. );
  9498. }
  9499. LONG
  9500. WINAPI
  9501. linePrepareAddToConferenceW(
  9502. HCALL hConfCall,
  9503. LPHCALL lphConsultCall,
  9504. LPLINECALLPARAMS const lpCallParams
  9505. )
  9506. {
  9507. FUNC_ARGS funcArgs =
  9508. {
  9509. MAKELONG (LINE_FUNC | ASYNC | 5, lPrepareAddToConference),
  9510. {
  9511. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  9512. (ULONG_PTR) hConfCall,
  9513. (ULONG_PTR) lphConsultCall,
  9514. (ULONG_PTR) lpCallParams,
  9515. (ULONG_PTR) TAPI_NO_DATA // dwAsciiCallParamsCodePage
  9516. },
  9517. {
  9518. Dword,
  9519. Dword,
  9520. Dword,
  9521. lpSet_Struct,
  9522. Dword
  9523. }
  9524. };
  9525. DWORD hPointer = 0;
  9526. LONG lResult;
  9527. if (!lpCallParams)
  9528. {
  9529. //
  9530. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  9531. //
  9532. funcArgs.ArgTypes[3] = Dword;
  9533. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  9534. }
  9535. if (!gbNTVDMClient)
  9536. {
  9537. if (IsBadDwordPtr (lphConsultCall))
  9538. {
  9539. return LINEERR_INVALPOINTER;
  9540. }
  9541. hPointer = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  9542. if (0 == hPointer)
  9543. {
  9544. return LINEERR_NOMEM;
  9545. }
  9546. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  9547. }
  9548. lResult = (DOFUNC (&funcArgs, "linePrepareAddToConferenceW"));
  9549. if (0 > lResult && hPointer)
  9550. {
  9551. DereferenceObject (ghHandleTable, hPointer, 1);
  9552. }
  9553. return lResult;
  9554. }
  9555. LONG
  9556. WINAPI
  9557. linePrepareAddToConferenceA(
  9558. HCALL hConfCall,
  9559. LPHCALL lphConsultCall,
  9560. LPLINECALLPARAMS const lpCallParams
  9561. )
  9562. {
  9563. FUNC_ARGS funcArgs =
  9564. {
  9565. MAKELONG (LINE_FUNC | ASYNC | 5, lPrepareAddToConference),
  9566. {
  9567. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  9568. (ULONG_PTR) hConfCall,
  9569. (ULONG_PTR) lphConsultCall,
  9570. (ULONG_PTR) lpCallParams,
  9571. (ULONG_PTR) GetACP() // dwAsciiCallParamsCodePage
  9572. },
  9573. {
  9574. Dword,
  9575. Dword,
  9576. Dword,
  9577. lpSet_Struct,
  9578. Dword
  9579. }
  9580. };
  9581. DWORD hPointer = 0;
  9582. LONG lResult;
  9583. if (!lpCallParams)
  9584. {
  9585. //
  9586. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  9587. //
  9588. funcArgs.ArgTypes[3] = Dword;
  9589. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  9590. }
  9591. if (!gbNTVDMClient)
  9592. {
  9593. if (IsBadDwordPtr (lphConsultCall))
  9594. {
  9595. return LINEERR_INVALPOINTER;
  9596. }
  9597. hPointer = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  9598. if (0 == hPointer)
  9599. {
  9600. return LINEERR_NOMEM;
  9601. }
  9602. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  9603. }
  9604. lResult = (DOFUNC (&funcArgs, "linePrepareAddToConference"));
  9605. if (0 > lResult && hPointer)
  9606. {
  9607. DereferenceObject (ghHandleTable, hPointer, 1);
  9608. }
  9609. return lResult;
  9610. }
  9611. LONG
  9612. WINAPI
  9613. linePrepareAddToConference(
  9614. HCALL hConfCall,
  9615. LPHCALL lphConsultCall,
  9616. LPLINECALLPARAMS const lpCallParams
  9617. )
  9618. {
  9619. return linePrepareAddToConferenceA(
  9620. hConfCall,
  9621. lphConsultCall,
  9622. lpCallParams
  9623. );
  9624. }
  9625. LONG
  9626. WINAPI
  9627. lineProxyMessage(
  9628. HLINE hLine,
  9629. HCALL hCall,
  9630. DWORD dwMsg,
  9631. DWORD dwParam1,
  9632. DWORD dwParam2,
  9633. DWORD dwParam3
  9634. )
  9635. {
  9636. FUNC_ARGS funcArgs =
  9637. {
  9638. MAKELONG (LINE_FUNC | SYNC | 6, lProxyMessage),
  9639. {
  9640. (ULONG_PTR) hLine,
  9641. (ULONG_PTR) hCall,
  9642. (ULONG_PTR) dwMsg,
  9643. (ULONG_PTR) dwParam1,
  9644. (ULONG_PTR) dwParam2,
  9645. (ULONG_PTR) dwParam3
  9646. },
  9647. {
  9648. Dword,
  9649. Dword,
  9650. Dword,
  9651. Dword,
  9652. Dword,
  9653. Dword,
  9654. }
  9655. };
  9656. return (DOFUNC (&funcArgs, "lineProxyMessage"));
  9657. }
  9658. LONG
  9659. WINAPI
  9660. lineProxyResponse(
  9661. HLINE hLine,
  9662. LPLINEPROXYREQUEST lpProxyRequest,
  9663. DWORD dwResult
  9664. )
  9665. {
  9666. LONG lResult = 0;
  9667. FUNC_ARGS funcArgs =
  9668. {
  9669. MAKELONG (LINE_FUNC | SYNC | 4, lProxyResponse),
  9670. {
  9671. (ULONG_PTR) hLine,
  9672. (ULONG_PTR) 0,
  9673. (ULONG_PTR) lpProxyRequest,
  9674. (ULONG_PTR) dwResult
  9675. },
  9676. {
  9677. Dword,
  9678. Dword,
  9679. lpSet_Struct,
  9680. Dword
  9681. }
  9682. };
  9683. PPROXYREQUESTHEADER pProxyRequestHeader;
  9684. //
  9685. // The following is not the most thorough checking, but it's close
  9686. // enough that a client app won't get a totally unexpected value
  9687. // back
  9688. //
  9689. if (dwResult != 0 &&
  9690. (dwResult < LINEERR_ALLOCATED ||
  9691. dwResult > LINEERR_DIALVOICEDETECT))
  9692. {
  9693. return LINEERR_INVALPARAM;
  9694. }
  9695. //
  9696. // Backtrack a little bit to get the pointer to what ought to be
  9697. // the proxy header, and then make sure we're dealing with a valid
  9698. // proxy request
  9699. //
  9700. pProxyRequestHeader = (PPROXYREQUESTHEADER)
  9701. (((LPBYTE) lpProxyRequest) - sizeof (PROXYREQUESTHEADER));
  9702. try
  9703. {
  9704. //
  9705. // Make sure we've a valid pProxyRequestHeader, then invalidate
  9706. // the key so subsequent attempts to call lineProxyResponse with
  9707. // the same lpProxyRequest fail
  9708. //
  9709. if (pProxyRequestHeader->dwKey != TPROXYREQUESTHEADER_KEY)
  9710. {
  9711. lResult = LINEERR_INVALPOINTER;
  9712. }
  9713. pProxyRequestHeader->dwKey = 0xefefefef;
  9714. funcArgs.Args[1] = (ULONG_PTR) pProxyRequestHeader->dwInstance;
  9715. //
  9716. // See if this is one of the requests that don't require
  9717. // any data to get passed back & reset the appropriate
  9718. // params if so
  9719. //
  9720. switch (lpProxyRequest->dwRequestType)
  9721. {
  9722. case LINEPROXYREQUEST_SETAGENTGROUP:
  9723. case LINEPROXYREQUEST_SETAGENTSTATE:
  9724. case LINEPROXYREQUEST_SETAGENTACTIVITY:
  9725. case LINEPROXYREQUEST_SETAGENTMEASUREMENTPERIOD:
  9726. case LINEPROXYREQUEST_SETAGENTSESSIONSTATE:
  9727. case LINEPROXYREQUEST_SETQUEUEMEASUREMENTPERIOD:
  9728. case LINEPROXYREQUEST_SETAGENTSTATEEX:
  9729. funcArgs.Args[2] = (ULONG_PTR) TAPI_NO_DATA;
  9730. funcArgs.ArgTypes[2] = Dword;
  9731. break;
  9732. }
  9733. }
  9734. except (EXCEPTION_EXECUTE_HANDLER)
  9735. {
  9736. lResult = LINEERR_INVALPOINTER;
  9737. }
  9738. if (lResult == 0)
  9739. {
  9740. lResult = DOFUNC (&funcArgs, "lineProxyResponse");
  9741. //
  9742. // If we've gotten this far we want to free the buffer
  9743. // unconditionally
  9744. //
  9745. ClientFree (pProxyRequestHeader);
  9746. }
  9747. return lResult;
  9748. }
  9749. LONG
  9750. WINAPI
  9751. lineRedirectW(
  9752. HCALL hCall,
  9753. LPCWSTR lpszDestAddress,
  9754. DWORD dwCountryCode
  9755. )
  9756. {
  9757. FUNC_ARGS funcArgs =
  9758. {
  9759. MAKELONG (LINE_FUNC | ASYNC | 3, lRedirect),
  9760. {
  9761. (ULONG_PTR) hCall,
  9762. (ULONG_PTR) lpszDestAddress,
  9763. (ULONG_PTR) dwCountryCode
  9764. },
  9765. {
  9766. Dword,
  9767. lpszW,
  9768. Dword
  9769. }
  9770. };
  9771. return (DOFUNC (&funcArgs, "lineRedirect"));
  9772. }
  9773. LONG
  9774. WINAPI
  9775. lineRedirectA(
  9776. HCALL hCall,
  9777. LPCSTR lpszDestAddress,
  9778. DWORD dwCountryCode
  9779. )
  9780. {
  9781. LONG lResult;
  9782. PWSTR szTempPtr;
  9783. if (IsBadStringPtrA (lpszDestAddress, (DWORD) -1))
  9784. {
  9785. return LINEERR_INVALPOINTER;
  9786. }
  9787. szTempPtr = NotSoWideStringToWideString (lpszDestAddress, (DWORD) -1);
  9788. lResult = lineRedirectW (hCall, szTempPtr, dwCountryCode);
  9789. if (szTempPtr)
  9790. {
  9791. ClientFree (szTempPtr);
  9792. }
  9793. return lResult;
  9794. }
  9795. LONG
  9796. WINAPI
  9797. lineRedirect(
  9798. HCALL hCall,
  9799. LPCSTR lpszDestAddress,
  9800. DWORD dwCountryCode
  9801. )
  9802. {
  9803. return lineRedirectA (hCall, lpszDestAddress, dwCountryCode);
  9804. }
  9805. LONG
  9806. WINAPI
  9807. lineRegisterRequestRecipient(
  9808. HLINEAPP hLineApp,
  9809. DWORD dwRegistrationInstance,
  9810. DWORD dwRequestMode,
  9811. DWORD bEnable
  9812. )
  9813. {
  9814. FUNC_ARGS funcArgs =
  9815. {
  9816. MAKELONG (LINE_FUNC | SYNC | 4, lRegisterRequestRecipient),
  9817. {
  9818. (ULONG_PTR) hLineApp,
  9819. (ULONG_PTR) dwRegistrationInstance,
  9820. (ULONG_PTR) dwRequestMode,
  9821. (ULONG_PTR) bEnable
  9822. },
  9823. {
  9824. hXxxApp,
  9825. Dword,
  9826. Dword,
  9827. Dword
  9828. }
  9829. };
  9830. return (DOFUNC (&funcArgs, "lineRegisterRequestRecipient"));
  9831. }
  9832. LONG
  9833. WINAPI
  9834. lineReleaseUserUserInfo(
  9835. HCALL hCall
  9836. )
  9837. {
  9838. FUNC_ARGS funcArgs =
  9839. {
  9840. MAKELONG (LINE_FUNC | ASYNC | 1, lReleaseUserUserInfo),
  9841. {
  9842. (ULONG_PTR) hCall
  9843. },
  9844. {
  9845. Dword,
  9846. }
  9847. };
  9848. return (DOFUNC (&funcArgs, "lineReleaseUserUserInfo"));
  9849. }
  9850. LONG
  9851. WINAPI
  9852. lineRemoveFromConference(
  9853. HCALL hCall
  9854. )
  9855. {
  9856. FUNC_ARGS funcArgs =
  9857. {
  9858. MAKELONG (LINE_FUNC | ASYNC | 1, lRemoveFromConference),
  9859. {
  9860. (ULONG_PTR) hCall
  9861. },
  9862. {
  9863. Dword
  9864. }
  9865. };
  9866. return (DOFUNC (&funcArgs, "lineRemoveFromConference"));
  9867. }
  9868. LONG
  9869. WINAPI
  9870. lineRemoveProvider(
  9871. DWORD dwPermanentProviderID,
  9872. HWND hwndOwner
  9873. )
  9874. {
  9875. return (lineXxxProvider(
  9876. gszTUISPI_providerRemove, // func name
  9877. NULL, // lpszProviderFilename
  9878. hwndOwner, // hwndOwner
  9879. dwPermanentProviderID, // dwPermProviderID
  9880. NULL // lpdwPermProviderID
  9881. ));
  9882. }
  9883. LONG
  9884. WINAPI
  9885. lineSecureCall(
  9886. HCALL hCall
  9887. )
  9888. {
  9889. FUNC_ARGS funcArgs =
  9890. {
  9891. MAKELONG (LINE_FUNC | ASYNC | 1, lSecureCall),
  9892. {
  9893. (ULONG_PTR) hCall
  9894. },
  9895. {
  9896. Dword
  9897. }
  9898. };
  9899. return (DOFUNC (&funcArgs, "lineSecureCall"));
  9900. }
  9901. LONG
  9902. WINAPI
  9903. lineSendUserUserInfo(
  9904. HCALL hCall,
  9905. LPCSTR lpsUserUserInfo,
  9906. DWORD dwSize
  9907. )
  9908. {
  9909. FUNC_ARGS funcArgs =
  9910. {
  9911. MAKELONG (LINE_FUNC | ASYNC | 3, lSendUserUserInfo),
  9912. {
  9913. (ULONG_PTR) hCall,
  9914. (ULONG_PTR) lpsUserUserInfo,
  9915. (ULONG_PTR) dwSize
  9916. },
  9917. {
  9918. Dword,
  9919. lpSet_SizeToFollow,
  9920. Size
  9921. }
  9922. };
  9923. if (!lpsUserUserInfo)
  9924. {
  9925. //
  9926. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  9927. //
  9928. funcArgs.ArgTypes[1] = Dword;
  9929. funcArgs.Args[1] = (ULONG_PTR) TAPI_NO_DATA;
  9930. funcArgs.ArgTypes[2] = Dword;
  9931. }
  9932. return (DOFUNC (&funcArgs, "lineSendUserUserInfo"));
  9933. }
  9934. LONG
  9935. WINAPI
  9936. lineSetAgentActivity(
  9937. HLINE hLine,
  9938. DWORD dwAddressID,
  9939. DWORD dwActivityID
  9940. )
  9941. {
  9942. FUNC_ARGS funcArgs =
  9943. {
  9944. MAKELONG (LINE_FUNC | ASYNC | 3, lSetAgentActivity),
  9945. {
  9946. (ULONG_PTR) hLine,
  9947. (ULONG_PTR) dwAddressID,
  9948. (ULONG_PTR) dwActivityID
  9949. },
  9950. {
  9951. Dword,
  9952. Dword,
  9953. Dword
  9954. }
  9955. };
  9956. return (DOFUNC (&funcArgs, "lineSetAgentActivity"));
  9957. }
  9958. LONG
  9959. WINAPI
  9960. lineSetAgentGroup(
  9961. HLINE hLine,
  9962. DWORD dwAddressID,
  9963. LPLINEAGENTGROUPLIST lpAgentGroupList
  9964. )
  9965. {
  9966. static LINEAGENTGROUPLIST EmptyGroupList =
  9967. {
  9968. sizeof (LINEAGENTGROUPLIST), // dwTotalSize
  9969. sizeof (LINEAGENTGROUPLIST), // dwNeededSize
  9970. sizeof (LINEAGENTGROUPLIST), // dwUsedSize
  9971. 0, // dwNumEntries
  9972. 0, // dwListSize
  9973. 0 // dwListOffset
  9974. };
  9975. FUNC_ARGS funcArgs =
  9976. {
  9977. MAKELONG (LINE_FUNC | ASYNC | 3, lSetAgentGroup),
  9978. {
  9979. (ULONG_PTR) hLine,
  9980. (ULONG_PTR) dwAddressID,
  9981. (ULONG_PTR) lpAgentGroupList
  9982. },
  9983. {
  9984. Dword,
  9985. Dword,
  9986. lpSet_Struct
  9987. }
  9988. };
  9989. if (!lpAgentGroupList)
  9990. {
  9991. funcArgs.Args[2] = (ULONG_PTR) &EmptyGroupList;
  9992. }
  9993. return (DOFUNC (&funcArgs, "lineSetAgentGroup"));
  9994. }
  9995. LONG
  9996. WINAPI
  9997. lineSetAgentMeasurementPeriod(
  9998. HLINE hLine,
  9999. HAGENT hAgent,
  10000. DWORD dwMeasurementPeriod
  10001. )
  10002. {
  10003. FUNC_ARGS funcArgs =
  10004. {
  10005. MAKELONG (LINE_FUNC | ASYNC | 3, lSetAgentMeasurementPeriod),
  10006. {
  10007. (ULONG_PTR) hLine,
  10008. (ULONG_PTR) hAgent,
  10009. (ULONG_PTR) dwMeasurementPeriod
  10010. },
  10011. {
  10012. Dword,
  10013. Dword,
  10014. Dword
  10015. }
  10016. };
  10017. return (DOFUNC (&funcArgs, "lineSetAgentMeasurementPeriod"));
  10018. }
  10019. LONG
  10020. WINAPI
  10021. lineSetAgentSessionState(
  10022. HLINE hLine,
  10023. HAGENTSESSION hAgentSession,
  10024. DWORD dwSessionState,
  10025. DWORD dwNextSessionState
  10026. )
  10027. {
  10028. FUNC_ARGS funcArgs =
  10029. {
  10030. MAKELONG (LINE_FUNC | ASYNC | 4, lSetAgentSessionState),
  10031. {
  10032. (ULONG_PTR) hLine,
  10033. (ULONG_PTR) hAgentSession,
  10034. (ULONG_PTR) dwSessionState,
  10035. (ULONG_PTR) dwNextSessionState
  10036. },
  10037. {
  10038. Dword,
  10039. Dword,
  10040. Dword,
  10041. Dword
  10042. }
  10043. };
  10044. return (DOFUNC (&funcArgs, "lineSetAgentSessionState"));
  10045. }
  10046. LONG
  10047. WINAPI
  10048. lineSetAgentState(
  10049. HLINE hLine,
  10050. DWORD dwAddressID,
  10051. DWORD dwAgentState,
  10052. DWORD dwNextAgentState
  10053. )
  10054. {
  10055. FUNC_ARGS funcArgs =
  10056. {
  10057. MAKELONG (LINE_FUNC | ASYNC | 4, lSetAgentState),
  10058. {
  10059. (ULONG_PTR) hLine,
  10060. (ULONG_PTR) dwAddressID,
  10061. (ULONG_PTR) dwAgentState,
  10062. (ULONG_PTR) dwNextAgentState
  10063. },
  10064. {
  10065. Dword,
  10066. Dword,
  10067. Dword,
  10068. Dword
  10069. }
  10070. };
  10071. return (DOFUNC (&funcArgs, "lineSetAgentState"));
  10072. }
  10073. LONG
  10074. WINAPI
  10075. lineSetAgentStateEx(
  10076. HLINE hLine,
  10077. HAGENT hAgent,
  10078. DWORD dwAgentState,
  10079. DWORD dwNextAgentState
  10080. )
  10081. {
  10082. FUNC_ARGS funcArgs =
  10083. {
  10084. MAKELONG (LINE_FUNC | ASYNC | 4, lSetAgentStateEx),
  10085. {
  10086. (ULONG_PTR) hLine,
  10087. (ULONG_PTR) hAgent,
  10088. (ULONG_PTR) dwAgentState,
  10089. (ULONG_PTR) dwNextAgentState
  10090. },
  10091. {
  10092. Dword,
  10093. Dword,
  10094. Dword,
  10095. Dword
  10096. }
  10097. };
  10098. return (DOFUNC (&funcArgs, "lineSetAgentStateEx"));
  10099. }
  10100. LONG
  10101. WINAPI
  10102. lineSetAppPriorityW(
  10103. LPCWSTR lpszAppName,
  10104. DWORD dwMediaMode,
  10105. LPLINEEXTENSIONID lpExtensionID,
  10106. DWORD dwRequestMode,
  10107. LPCWSTR lpszExtensionName,
  10108. DWORD dwPriority
  10109. )
  10110. {
  10111. FUNC_ARGS funcArgs =
  10112. {
  10113. MAKELONG (LINE_FUNC | SYNC | 7, lSetAppPriority),
  10114. {
  10115. (ULONG_PTR) lpszAppName,
  10116. (ULONG_PTR) dwMediaMode,
  10117. (ULONG_PTR) TAPI_NO_DATA, // (DWORD) lpExtensionID,
  10118. (ULONG_PTR) 0, // (DWORD) sizeof(LINEEXTENSIONID),
  10119. (ULONG_PTR) dwRequestMode,
  10120. (ULONG_PTR) TAPI_NO_DATA, // (DWORD) lpszExtensionName,
  10121. (ULONG_PTR) dwPriority
  10122. },
  10123. {
  10124. lpszW,
  10125. Dword,
  10126. Dword, // lpSet_SizeToFollow,
  10127. Dword, // Size,
  10128. Dword,
  10129. Dword, // lpsz,
  10130. Dword
  10131. }
  10132. };
  10133. #if 0
  10134. if (dwMediaMode & 0xff000000)
  10135. {
  10136. //
  10137. // Reset lpExtensionID (& following Size) Arg & ArgType
  10138. // since it's a valid param in this case
  10139. //
  10140. funcArgs.ArgTypes[2] = lpSet_SizeToFollow;
  10141. funcArgs.Args[2] = (ULONG_PTR) lpExtensionID;
  10142. funcArgs.ArgTypes[3] = Size;
  10143. funcArgs.Args[3] = (ULONG_PTR) sizeof(LINEEXTENSIONID);
  10144. if (lpszExtensionName)
  10145. {
  10146. //
  10147. // Reset lpszExtensionName Arg & ArgType since it's
  10148. // a valid param in this case
  10149. //
  10150. funcArgs.ArgTypes[5] = lpszW;
  10151. funcArgs.Args[5] = (ULONG_PTR) lpszExtensionName;
  10152. }
  10153. }
  10154. #endif
  10155. return (DOFUNC (&funcArgs, "lineSetAppPriority"));
  10156. }
  10157. LONG
  10158. WINAPI
  10159. lineSetAppPriorityA(
  10160. LPCSTR lpszAppName,
  10161. DWORD dwMediaMode,
  10162. LPLINEEXTENSIONID lpExtensionID,
  10163. DWORD dwRequestMode,
  10164. LPCSTR lpszExtensionName,
  10165. DWORD dwPriority
  10166. )
  10167. {
  10168. LONG lResult;
  10169. PWSTR szTempPtr;
  10170. #if 0
  10171. PWSTR szTempPtr2;
  10172. if (IsBadStringPtrA (lpszAppName, (DWORD) -1) ||
  10173. ((dwMediaMode & 0xff000000) && lpszExtensionName &&
  10174. IsBadStringPtrA (lpszExtensionName, (DWORD) -1)))
  10175. {
  10176. return LINEERR_INVALPOINTER;
  10177. }
  10178. szTempPtr2 = NotSoWideStringToWideString (lpszExtensionName, (DWORD) -1);
  10179. #endif
  10180. szTempPtr = NotSoWideStringToWideString (lpszAppName, (DWORD) -1);
  10181. lResult = lineSetAppPriorityW(
  10182. szTempPtr,
  10183. dwMediaMode,
  10184. lpExtensionID,
  10185. dwRequestMode,
  10186. NULL, //szTempPtr2,
  10187. dwPriority
  10188. );
  10189. if (szTempPtr)
  10190. {
  10191. ClientFree (szTempPtr);
  10192. }
  10193. #if 0
  10194. if (szTempPtr2)
  10195. {
  10196. ClientFree (szTempPtr2);
  10197. }
  10198. #endif
  10199. return lResult;
  10200. }
  10201. LONG
  10202. WINAPI
  10203. lineSetAppPriority(
  10204. LPCSTR lpszAppName,
  10205. DWORD dwMediaMode,
  10206. LPLINEEXTENSIONID lpExtensionID,
  10207. DWORD dwRequestMode,
  10208. LPCSTR lpszExtensionName,
  10209. DWORD dwPriority
  10210. )
  10211. {
  10212. return lineSetAppPriorityA(
  10213. lpszAppName,
  10214. dwMediaMode,
  10215. lpExtensionID,
  10216. dwRequestMode,
  10217. lpszExtensionName,
  10218. dwPriority
  10219. );
  10220. }
  10221. LONG
  10222. WINAPI
  10223. lineSetAppSpecific(
  10224. HCALL hCall,
  10225. DWORD dwAppSpecific
  10226. )
  10227. {
  10228. FUNC_ARGS funcArgs =
  10229. {
  10230. MAKELONG (LINE_FUNC | SYNC | 2, lSetAppSpecific),
  10231. {
  10232. (ULONG_PTR) hCall,
  10233. (ULONG_PTR) dwAppSpecific
  10234. },
  10235. {
  10236. Dword,
  10237. Dword
  10238. }
  10239. };
  10240. return (DOFUNC (&funcArgs, "lineSetAppSpecific"));
  10241. }
  10242. LONG
  10243. WINAPI
  10244. lineSetCallData(
  10245. HCALL hCall,
  10246. LPVOID lpCallData,
  10247. DWORD dwSize
  10248. )
  10249. {
  10250. FUNC_ARGS funcArgs =
  10251. {
  10252. MAKELONG (LINE_FUNC | ASYNC | 3, lSetCallData),
  10253. {
  10254. (ULONG_PTR) hCall,
  10255. (ULONG_PTR) lpCallData,
  10256. (ULONG_PTR) dwSize
  10257. },
  10258. {
  10259. Dword,
  10260. lpSet_SizeToFollow,
  10261. Size
  10262. }
  10263. };
  10264. if (dwSize == 0)
  10265. {
  10266. funcArgs.Args[1] = (ULONG_PTR) TAPI_NO_DATA;
  10267. funcArgs.ArgTypes[1] =
  10268. funcArgs.ArgTypes[2] = Dword;
  10269. }
  10270. return (DOFUNC (&funcArgs, "lineSetCallData"));
  10271. }
  10272. LONG
  10273. WINAPI
  10274. lineSetCallParams(
  10275. HCALL hCall,
  10276. DWORD dwBearerMode,
  10277. DWORD dwMinRate,
  10278. DWORD dwMaxRate,
  10279. LPLINEDIALPARAMS const lpDialParams
  10280. )
  10281. {
  10282. FUNC_ARGS funcArgs =
  10283. {
  10284. MAKELONG (LINE_FUNC | ASYNC | 6, lSetCallParams),
  10285. {
  10286. (ULONG_PTR) hCall,
  10287. (ULONG_PTR) dwBearerMode,
  10288. (ULONG_PTR) dwMinRate,
  10289. (ULONG_PTR) dwMaxRate,
  10290. (ULONG_PTR) lpDialParams,
  10291. (ULONG_PTR) sizeof(LINEDIALPARAMS)
  10292. },
  10293. {
  10294. Dword,
  10295. Dword,
  10296. Dword,
  10297. Dword,
  10298. lpSet_SizeToFollow,
  10299. Size
  10300. }
  10301. };
  10302. if (!lpDialParams)
  10303. {
  10304. //
  10305. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  10306. //
  10307. funcArgs.ArgTypes[4] = Dword;
  10308. funcArgs.Args[4] = (ULONG_PTR) TAPI_NO_DATA;
  10309. funcArgs.ArgTypes[5] = Dword;
  10310. }
  10311. return (DOFUNC (&funcArgs, "lineSetCallParams"));
  10312. }
  10313. LONG
  10314. WINAPI
  10315. lineSetCallPrivilege(
  10316. HCALL hCall,
  10317. DWORD dwCallPrivilege
  10318. )
  10319. {
  10320. FUNC_ARGS funcArgs =
  10321. {
  10322. MAKELONG (LINE_FUNC | SYNC | 2, lSetCallPrivilege),
  10323. {
  10324. (ULONG_PTR) hCall,
  10325. (ULONG_PTR) dwCallPrivilege
  10326. },
  10327. {
  10328. Dword,
  10329. Dword
  10330. }
  10331. };
  10332. return (DOFUNC (&funcArgs, "lineSetCallPrivilege"));
  10333. }
  10334. LONG
  10335. WINAPI
  10336. lineSetCallQualityOfService(
  10337. HCALL hCall,
  10338. LPVOID lpSendingFlowspec,
  10339. DWORD dwSendingFlowspecSize,
  10340. LPVOID lpReceivingFlowspec,
  10341. DWORD dwReceivingFlowspecSize
  10342. )
  10343. {
  10344. FUNC_ARGS funcArgs =
  10345. {
  10346. MAKELONG (LINE_FUNC | ASYNC | 5, lSetCallQualityOfService),
  10347. {
  10348. (ULONG_PTR) hCall,
  10349. (ULONG_PTR) lpSendingFlowspec,
  10350. (ULONG_PTR) dwSendingFlowspecSize,
  10351. (ULONG_PTR) lpReceivingFlowspec,
  10352. (ULONG_PTR) dwReceivingFlowspecSize
  10353. },
  10354. {
  10355. Dword,
  10356. lpSet_SizeToFollow,
  10357. Size,
  10358. lpSet_SizeToFollow,
  10359. Size,
  10360. }
  10361. };
  10362. return (DOFUNC (&funcArgs, "lineSetCallQualityOfService"));
  10363. }
  10364. LONG
  10365. WINAPI
  10366. lineSetCallTreatment(
  10367. HCALL hCall,
  10368. DWORD dwTreatment
  10369. )
  10370. {
  10371. FUNC_ARGS funcArgs =
  10372. {
  10373. MAKELONG (LINE_FUNC | ASYNC | 2, lSetCallTreatment),
  10374. {
  10375. (ULONG_PTR) hCall,
  10376. (ULONG_PTR) dwTreatment
  10377. },
  10378. {
  10379. Dword,
  10380. Dword
  10381. }
  10382. };
  10383. return (DOFUNC (&funcArgs, "lineSetCallTreatment"));
  10384. }
  10385. LONG
  10386. WINAPI
  10387. lineSetDevConfigW(
  10388. DWORD dwDeviceID,
  10389. LPVOID const lpDeviceConfig,
  10390. DWORD dwSize,
  10391. LPCWSTR lpszDeviceClass
  10392. )
  10393. {
  10394. FUNC_ARGS funcArgs =
  10395. {
  10396. MAKELONG (LINE_FUNC | SYNC | 4, lSetDevConfig),
  10397. {
  10398. (ULONG_PTR) dwDeviceID,
  10399. (ULONG_PTR) lpDeviceConfig,
  10400. (ULONG_PTR) dwSize,
  10401. (ULONG_PTR) lpszDeviceClass
  10402. },
  10403. {
  10404. Dword,
  10405. lpSet_SizeToFollow,
  10406. Size,
  10407. lpszW
  10408. }
  10409. };
  10410. return (DOFUNC (&funcArgs, "lineSetDevConfig"));
  10411. }
  10412. LONG
  10413. WINAPI
  10414. lineSetDevConfigA(
  10415. DWORD dwDeviceID,
  10416. LPVOID const lpDeviceConfig,
  10417. DWORD dwSize,
  10418. LPCSTR lpszDeviceClass
  10419. )
  10420. {
  10421. LONG lResult;
  10422. PWSTR szTempPtr;
  10423. if (IsBadStringPtrA (lpszDeviceClass, (DWORD) -1))
  10424. {
  10425. return LINEERR_INVALPOINTER;
  10426. }
  10427. else if (!(szTempPtr = NotSoWideStringToWideString(
  10428. lpszDeviceClass,
  10429. (DWORD) -1
  10430. )))
  10431. {
  10432. return LINEERR_NOMEM;
  10433. }
  10434. lResult = lineSetDevConfigW(
  10435. dwDeviceID,
  10436. lpDeviceConfig,
  10437. dwSize,
  10438. szTempPtr
  10439. );
  10440. ClientFree (szTempPtr);
  10441. return lResult;
  10442. }
  10443. LONG
  10444. WINAPI
  10445. lineSetDevConfig(
  10446. DWORD dwDeviceID,
  10447. LPVOID const lpDeviceConfig,
  10448. DWORD dwSize,
  10449. LPCSTR lpszDeviceClass
  10450. )
  10451. {
  10452. return lineSetDevConfigA(
  10453. dwDeviceID,
  10454. lpDeviceConfig,
  10455. dwSize,
  10456. lpszDeviceClass
  10457. );
  10458. }
  10459. LONG
  10460. WINAPI
  10461. lineSetLineDevStatus(
  10462. HLINE hLine,
  10463. DWORD dwStatusToChange,
  10464. DWORD fStatus
  10465. )
  10466. {
  10467. FUNC_ARGS funcArgs =
  10468. {
  10469. MAKELONG (LINE_FUNC | ASYNC | 3, lSetLineDevStatus),
  10470. {
  10471. (ULONG_PTR) hLine,
  10472. (ULONG_PTR) dwStatusToChange,
  10473. (ULONG_PTR) fStatus
  10474. },
  10475. {
  10476. Dword,
  10477. Dword,
  10478. Dword
  10479. }
  10480. };
  10481. return (DOFUNC (&funcArgs, "lineSetLineDevStatus"));
  10482. }
  10483. LONG
  10484. WINAPI
  10485. lineSetMediaControl(
  10486. HLINE hLine,
  10487. DWORD dwAddressID,
  10488. HCALL hCall,
  10489. DWORD dwSelect,
  10490. LPLINEMEDIACONTROLDIGIT const lpDigitList,
  10491. DWORD dwDigitNumEntries,
  10492. LPLINEMEDIACONTROLMEDIA const lpMediaList,
  10493. DWORD dwMediaNumEntries,
  10494. LPLINEMEDIACONTROLTONE const lpToneList,
  10495. DWORD dwToneNumEntries,
  10496. LPLINEMEDIACONTROLCALLSTATE const lpCallStateList,
  10497. DWORD dwCallStateNumEntries
  10498. )
  10499. {
  10500. FUNC_ARGS funcArgs =
  10501. {
  10502. MAKELONG (LINE_FUNC | SYNC | 12, lSetMediaControl),
  10503. {
  10504. (ULONG_PTR) hLine,
  10505. (ULONG_PTR) dwAddressID,
  10506. (ULONG_PTR) hCall,
  10507. (ULONG_PTR) dwSelect,
  10508. (ULONG_PTR) TAPI_NO_DATA,
  10509. (ULONG_PTR) dwDigitNumEntries * sizeof(LINEMEDIACONTROLDIGIT),
  10510. (ULONG_PTR) TAPI_NO_DATA,
  10511. (ULONG_PTR) dwMediaNumEntries * sizeof(LINEMEDIACONTROLMEDIA),
  10512. (ULONG_PTR) TAPI_NO_DATA,
  10513. (ULONG_PTR) dwToneNumEntries * sizeof(LINEMEDIACONTROLTONE),
  10514. (ULONG_PTR) TAPI_NO_DATA,
  10515. (ULONG_PTR) dwCallStateNumEntries * sizeof(LINEMEDIACONTROLCALLSTATE)
  10516. },
  10517. {
  10518. Dword,
  10519. Dword,
  10520. Dword,
  10521. Dword,
  10522. Dword,
  10523. Dword,
  10524. Dword,
  10525. Dword,
  10526. Dword,
  10527. Dword,
  10528. Dword,
  10529. Dword
  10530. }
  10531. };
  10532. //
  10533. // If lpXxxList is non-NULL reset Arg & ArgType, and check
  10534. // to see that dwXxxNumEntries is not unacceptably large
  10535. //
  10536. if (lpDigitList)
  10537. {
  10538. if (dwDigitNumEntries >
  10539. (0x1000000 / sizeof (LINEMEDIACONTROLDIGIT)))
  10540. {
  10541. return LINEERR_INVALPOINTER;
  10542. }
  10543. funcArgs.ArgTypes[4] = lpSet_SizeToFollow;
  10544. funcArgs.Args[4] = (ULONG_PTR) lpDigitList;
  10545. funcArgs.ArgTypes[5] = Size;
  10546. }
  10547. if (lpMediaList)
  10548. {
  10549. if (dwMediaNumEntries >
  10550. (0x1000000 / sizeof (LINEMEDIACONTROLMEDIA)))
  10551. {
  10552. return LINEERR_INVALPOINTER;
  10553. }
  10554. funcArgs.ArgTypes[6] = lpSet_SizeToFollow;
  10555. funcArgs.Args[6] = (ULONG_PTR) lpMediaList;
  10556. funcArgs.ArgTypes[7] = Size;
  10557. }
  10558. if (lpToneList)
  10559. {
  10560. if (dwToneNumEntries >
  10561. (0x1000000 / sizeof (LINEMEDIACONTROLTONE)))
  10562. {
  10563. return LINEERR_INVALPOINTER;
  10564. }
  10565. funcArgs.ArgTypes[8] = lpSet_SizeToFollow;
  10566. funcArgs.Args[8] = (ULONG_PTR) lpToneList;
  10567. funcArgs.ArgTypes[9] = Size;
  10568. }
  10569. if (lpCallStateList)
  10570. {
  10571. if (dwCallStateNumEntries >
  10572. (0x1000000 / sizeof (LINEMEDIACONTROLCALLSTATE)))
  10573. {
  10574. return LINEERR_INVALPOINTER;
  10575. }
  10576. funcArgs.ArgTypes[10] = lpSet_SizeToFollow;
  10577. funcArgs.Args[10] = (ULONG_PTR) lpCallStateList;
  10578. funcArgs.ArgTypes[11] = Size;
  10579. }
  10580. return (DOFUNC (&funcArgs, "lineSetMediaControl"));
  10581. }
  10582. LONG
  10583. WINAPI
  10584. lineSetMediaMode(
  10585. HCALL hCall,
  10586. DWORD dwMediaModes
  10587. )
  10588. {
  10589. FUNC_ARGS funcArgs =
  10590. {
  10591. MAKELONG (LINE_FUNC | SYNC | 2, lSetMediaMode),
  10592. {
  10593. (ULONG_PTR) hCall,
  10594. (ULONG_PTR) dwMediaModes
  10595. },
  10596. {
  10597. Dword,
  10598. Dword
  10599. }
  10600. };
  10601. return (DOFUNC (&funcArgs, "lineSetMediaMode"));
  10602. }
  10603. LONG
  10604. WINAPI
  10605. lineSetNumRings(
  10606. HLINE hLine,
  10607. DWORD dwAddressID,
  10608. DWORD dwNumRings
  10609. )
  10610. {
  10611. FUNC_ARGS funcArgs =
  10612. {
  10613. MAKELONG (LINE_FUNC | SYNC | 3, lSetNumRings),
  10614. {
  10615. (ULONG_PTR) hLine,
  10616. (ULONG_PTR) dwAddressID,
  10617. (ULONG_PTR) dwNumRings
  10618. },
  10619. {
  10620. Dword,
  10621. Dword,
  10622. Dword
  10623. }
  10624. };
  10625. return (DOFUNC (&funcArgs, "lineSetNumRings"));
  10626. }
  10627. LONG
  10628. WINAPI
  10629. lineSetQueueMeasurementPeriod(
  10630. HLINE hLine,
  10631. DWORD dwQueueID,
  10632. DWORD dwMeasurementPeriod
  10633. )
  10634. {
  10635. FUNC_ARGS funcArgs =
  10636. {
  10637. MAKELONG (LINE_FUNC | ASYNC | 3, lSetQueueMeasurementPeriod),
  10638. {
  10639. (ULONG_PTR) hLine,
  10640. (ULONG_PTR) dwQueueID,
  10641. (ULONG_PTR) dwMeasurementPeriod
  10642. },
  10643. {
  10644. Dword,
  10645. Dword,
  10646. Dword
  10647. }
  10648. };
  10649. return (DOFUNC (&funcArgs, "lineSetQueueMeasurementPeriod"));
  10650. }
  10651. LONG
  10652. WINAPI
  10653. lineSetStatusMessages(
  10654. HLINE hLine,
  10655. DWORD dwLineStates,
  10656. DWORD dwAddressStates
  10657. )
  10658. {
  10659. FUNC_ARGS funcArgs =
  10660. {
  10661. MAKELONG (LINE_FUNC | SYNC | 3, lSetStatusMessages),
  10662. {
  10663. (ULONG_PTR) hLine,
  10664. (ULONG_PTR) dwLineStates,
  10665. (ULONG_PTR) dwAddressStates
  10666. },
  10667. {
  10668. Dword,
  10669. Dword,
  10670. Dword
  10671. }
  10672. };
  10673. return (DOFUNC (&funcArgs, "lineSetStatusMessages"));
  10674. }
  10675. LONG
  10676. WINAPI
  10677. lineSetTerminal(
  10678. HLINE hLine,
  10679. DWORD dwAddressID,
  10680. HCALL hCall,
  10681. DWORD dwSelect,
  10682. DWORD dwTerminalModes,
  10683. DWORD dwTerminalID,
  10684. DWORD bEnable
  10685. )
  10686. {
  10687. FUNC_ARGS funcArgs =
  10688. {
  10689. MAKELONG (LINE_FUNC | ASYNC | 7, lSetTerminal),
  10690. {
  10691. (ULONG_PTR) hLine,
  10692. (ULONG_PTR) dwAddressID,
  10693. (ULONG_PTR) hCall,
  10694. (ULONG_PTR) dwSelect,
  10695. (ULONG_PTR) dwTerminalModes,
  10696. (ULONG_PTR) dwTerminalID,
  10697. (ULONG_PTR) bEnable
  10698. },
  10699. {
  10700. Dword,
  10701. Dword,
  10702. Dword,
  10703. Dword,
  10704. Dword,
  10705. Dword,
  10706. Dword
  10707. }
  10708. };
  10709. return (DOFUNC (&funcArgs, "lineSetTerminal"));
  10710. }
  10711. void
  10712. PASCAL
  10713. lineSetupConferencePostProcess(
  10714. PASYNCEVENTMSG pMsg
  10715. )
  10716. {
  10717. LOG((TL_TRACE, "lineSetupConfPostProcess: enter"));
  10718. LOG((TL_INFO,
  10719. "\t\tdwP1=x%lx, dwP2=x%lx, dwP3=x%lx, dwP4=x%lx",
  10720. pMsg->Param1,
  10721. pMsg->Param2,
  10722. pMsg->Param3,
  10723. pMsg->Param4
  10724. ));
  10725. if (pMsg->Param2 == 0)
  10726. {
  10727. HCALL hConfCall = (HCALL) pMsg->Param3,
  10728. hConsultCall = (HCALL) *(&pMsg->Param4 + 1);
  10729. LPHCALL lphConfCall = (LPHCALL) ReferenceObject (ghHandleTable, pMsg->Param4, 0),
  10730. lphConsultCall = (LPHCALL) ReferenceObject (ghHandleTable, *(&pMsg->Param4 + 2), 0);
  10731. // We don't need the handle to the pointer any more...
  10732. DereferenceObject (ghHandleTable, pMsg->Param4, 2);
  10733. DereferenceObject (ghHandleTable, *(&pMsg->Param4 + 2), 2);
  10734. try
  10735. {
  10736. if (gbNTVDMClient)
  10737. {
  10738. #ifndef _WIN64
  10739. LPHCALL lphConfCallVDM = (LPHCALL) gpfnWOWGetVDMPointer(
  10740. (DWORD) lphConfCall,
  10741. sizeof (HCALL),
  10742. TRUE // fProtectedMode
  10743. ),
  10744. lphConsultCallVDM = (LPHCALL) gpfnWOWGetVDMPointer(
  10745. (DWORD) lphConsultCall,
  10746. sizeof (HCALL),
  10747. TRUE // fProtectedMode
  10748. );
  10749. if (lphConfCallVDM && lphConsultCallVDM)
  10750. {
  10751. *lphConfCallVDM = hConfCall;
  10752. *lphConsultCallVDM = hConsultCall;
  10753. }
  10754. else
  10755. {
  10756. pMsg->Param2 = LINEERR_INVALPOINTER;
  10757. }
  10758. #endif
  10759. }
  10760. else
  10761. {
  10762. *lphConfCall = hConfCall;
  10763. *lphConsultCall = hConsultCall;
  10764. }
  10765. }
  10766. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  10767. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  10768. {
  10769. pMsg->Param2 = LINEERR_INVALPOINTER;
  10770. }
  10771. }
  10772. }
  10773. LONG
  10774. WINAPI
  10775. lineSetupConferenceW(
  10776. HCALL hCall,
  10777. HLINE hLine,
  10778. LPHCALL lphConfCall,
  10779. LPHCALL lphConsultCall,
  10780. DWORD dwNumParties,
  10781. LPLINECALLPARAMS const lpCallParams
  10782. )
  10783. {
  10784. FUNC_ARGS funcArgs =
  10785. {
  10786. MAKELONG (LINE_FUNC | ASYNC | 8, lSetupConference),
  10787. {
  10788. (ULONG_PTR) GetFunctionIndex(lineSetupConferencePostProcess),
  10789. (ULONG_PTR) hCall,
  10790. (ULONG_PTR) hLine,
  10791. (ULONG_PTR) lphConfCall,
  10792. (ULONG_PTR) lphConsultCall,
  10793. (ULONG_PTR) dwNumParties,
  10794. (ULONG_PTR) lpCallParams,
  10795. (ULONG_PTR) TAPI_NO_DATA // dwAsciiCallParamsCodePage
  10796. },
  10797. {
  10798. Dword,
  10799. Dword,
  10800. Dword,
  10801. Dword,
  10802. Dword,
  10803. Dword,
  10804. lpSet_Struct,
  10805. Dword
  10806. }
  10807. };
  10808. DWORD hPointer1 = 0, hPointer2 = 0;
  10809. LONG lResult;
  10810. if (lphConfCall == lphConsultCall)
  10811. {
  10812. return LINEERR_INVALPOINTER;
  10813. }
  10814. if (!lpCallParams)
  10815. {
  10816. //
  10817. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  10818. //
  10819. funcArgs.ArgTypes[6] = Dword;
  10820. funcArgs.Args[6] = (ULONG_PTR) TAPI_NO_DATA;
  10821. }
  10822. if (!gbNTVDMClient)
  10823. {
  10824. if (IsBadDwordPtr (lphConfCall) ||
  10825. IsBadDwordPtr (lphConsultCall))
  10826. {
  10827. return LINEERR_INVALPOINTER;
  10828. }
  10829. hPointer1 = NewObject (ghHandleTable, (PVOID)lphConfCall, NULL);
  10830. if (0 == hPointer1)
  10831. {
  10832. return LINEERR_NOMEM;
  10833. }
  10834. hPointer2 = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  10835. if (0 == hPointer2)
  10836. {
  10837. DereferenceObject (ghHandleTable, hPointer1, 1);
  10838. return LINEERR_NOMEM;
  10839. }
  10840. funcArgs.Args[3] = (ULONG_PTR)hPointer1;
  10841. funcArgs.Args[4] = (ULONG_PTR)hPointer2;
  10842. }
  10843. lResult = (DOFUNC (&funcArgs, "lineSetupConferenceW"));
  10844. if (0 > lResult && hPointer1)
  10845. {
  10846. DereferenceObject (ghHandleTable, hPointer1, 1);
  10847. DereferenceObject (ghHandleTable, hPointer2, 1);
  10848. }
  10849. return lResult;
  10850. }
  10851. LONG
  10852. WINAPI
  10853. lineSetupConferenceA(
  10854. HCALL hCall,
  10855. HLINE hLine,
  10856. LPHCALL lphConfCall,
  10857. LPHCALL lphConsultCall,
  10858. DWORD dwNumParties,
  10859. LPLINECALLPARAMS const lpCallParams
  10860. )
  10861. {
  10862. FUNC_ARGS funcArgs =
  10863. {
  10864. MAKELONG (LINE_FUNC | ASYNC | 8, lSetupConference),
  10865. {
  10866. (ULONG_PTR) GetFunctionIndex(lineSetupConferencePostProcess),
  10867. (ULONG_PTR) hCall,
  10868. (ULONG_PTR) hLine,
  10869. (ULONG_PTR) lphConfCall,
  10870. (ULONG_PTR) lphConsultCall,
  10871. (ULONG_PTR) dwNumParties,
  10872. (ULONG_PTR) lpCallParams,
  10873. (ULONG_PTR) GetACP() // dwAsciiCallParamsCodePage
  10874. },
  10875. {
  10876. Dword,
  10877. Dword,
  10878. Dword,
  10879. Dword,
  10880. Dword,
  10881. Dword,
  10882. lpSet_Struct,
  10883. Dword
  10884. }
  10885. };
  10886. DWORD hPointer1 = 0, hPointer2 = 0;
  10887. LONG lResult;
  10888. if (lphConfCall == lphConsultCall)
  10889. {
  10890. return LINEERR_INVALPOINTER;
  10891. }
  10892. if (!lpCallParams)
  10893. {
  10894. //
  10895. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  10896. //
  10897. funcArgs.ArgTypes[6] = Dword;
  10898. funcArgs.Args[6] = (ULONG_PTR) TAPI_NO_DATA;
  10899. }
  10900. if (!gbNTVDMClient)
  10901. {
  10902. if (IsBadDwordPtr (lphConfCall) ||
  10903. IsBadDwordPtr (lphConsultCall))
  10904. {
  10905. return LINEERR_INVALPOINTER;
  10906. }
  10907. hPointer1 = NewObject (ghHandleTable, (PVOID)lphConfCall, NULL);
  10908. if (0 == hPointer1)
  10909. {
  10910. return LINEERR_NOMEM;
  10911. }
  10912. hPointer2 = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  10913. if (0 == hPointer2)
  10914. {
  10915. DereferenceObject (ghHandleTable, hPointer1, 1);
  10916. return LINEERR_NOMEM;
  10917. }
  10918. funcArgs.Args[3] = (ULONG_PTR)hPointer1;
  10919. funcArgs.Args[4] = (ULONG_PTR)hPointer2;
  10920. }
  10921. lResult = (DOFUNC (&funcArgs, "lineSetupConference"));
  10922. if (0 > lResult && hPointer1)
  10923. {
  10924. DereferenceObject (ghHandleTable, hPointer1, 1);
  10925. DereferenceObject (ghHandleTable, hPointer2, 1);
  10926. }
  10927. return lResult;
  10928. }
  10929. LONG
  10930. WINAPI
  10931. lineSetupConference(
  10932. HCALL hCall,
  10933. HLINE hLine,
  10934. LPHCALL lphConfCall,
  10935. LPHCALL lphConsultCall,
  10936. DWORD dwNumParties,
  10937. LPLINECALLPARAMS const lpCallParams
  10938. )
  10939. {
  10940. return lineSetupConferenceA(
  10941. hCall,
  10942. hLine,
  10943. lphConfCall,
  10944. lphConsultCall,
  10945. dwNumParties,
  10946. lpCallParams
  10947. );
  10948. }
  10949. LONG
  10950. WINAPI
  10951. lineSetupTransferW(
  10952. HCALL hCall,
  10953. LPHCALL lphConsultCall,
  10954. LPLINECALLPARAMS const lpCallParams
  10955. )
  10956. {
  10957. FUNC_ARGS funcArgs =
  10958. {
  10959. MAKELONG (LINE_FUNC | ASYNC | 5, lSetupTransfer),
  10960. {
  10961. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  10962. (ULONG_PTR) hCall,
  10963. (ULONG_PTR) lphConsultCall,
  10964. (ULONG_PTR) lpCallParams,
  10965. (ULONG_PTR) TAPI_NO_DATA // dwAsciiCallParamsCodePage
  10966. },
  10967. {
  10968. Dword,
  10969. Dword,
  10970. Dword,
  10971. lpSet_Struct,
  10972. Dword
  10973. }
  10974. };
  10975. DWORD hPointer = 0;
  10976. LONG lResult;
  10977. if (!lpCallParams)
  10978. {
  10979. //
  10980. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  10981. //
  10982. funcArgs.ArgTypes[3] = Dword;
  10983. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  10984. }
  10985. if (!gbNTVDMClient)
  10986. {
  10987. if (IsBadDwordPtr (lphConsultCall))
  10988. {
  10989. return LINEERR_INVALPOINTER;
  10990. }
  10991. hPointer = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  10992. if (0 == hPointer)
  10993. {
  10994. return LINEERR_NOMEM;
  10995. }
  10996. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  10997. }
  10998. lResult = (DOFUNC (&funcArgs, "lineSetupTransferW"));
  10999. if (0 > lResult && hPointer)
  11000. {
  11001. DereferenceObject (ghHandleTable, hPointer, 1);
  11002. }
  11003. return lResult;
  11004. }
  11005. LONG
  11006. WINAPI
  11007. lineSetupTransferA(
  11008. HCALL hCall,
  11009. LPHCALL lphConsultCall,
  11010. LPLINECALLPARAMS const lpCallParams
  11011. )
  11012. {
  11013. FUNC_ARGS funcArgs =
  11014. {
  11015. MAKELONG (LINE_FUNC | ASYNC | 5, lSetupTransfer),
  11016. {
  11017. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  11018. (ULONG_PTR) hCall,
  11019. (ULONG_PTR) lphConsultCall,
  11020. (ULONG_PTR) lpCallParams,
  11021. (ULONG_PTR) GetACP() // dwAsciiCallParamsCodePage
  11022. },
  11023. {
  11024. Dword,
  11025. Dword,
  11026. Dword,
  11027. lpSet_Struct,
  11028. Dword
  11029. }
  11030. };
  11031. DWORD hPointer = 0;
  11032. LONG lResult;
  11033. if (!lpCallParams)
  11034. {
  11035. //
  11036. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  11037. //
  11038. funcArgs.ArgTypes[3] = Dword;
  11039. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  11040. }
  11041. if (!gbNTVDMClient)
  11042. {
  11043. if (IsBadDwordPtr (lphConsultCall))
  11044. {
  11045. return LINEERR_INVALPOINTER;
  11046. }
  11047. hPointer = NewObject (ghHandleTable, (PVOID)lphConsultCall, NULL);
  11048. if (0 == hPointer)
  11049. {
  11050. return LINEERR_NOMEM;
  11051. }
  11052. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  11053. }
  11054. lResult = (DOFUNC (&funcArgs, "lineSetupTransferW"));
  11055. if (0 > lResult && hPointer)
  11056. {
  11057. DereferenceObject (ghHandleTable, hPointer, 1);
  11058. }
  11059. return lResult;
  11060. }
  11061. LONG
  11062. WINAPI
  11063. lineSetupTransfer(
  11064. HCALL hCall,
  11065. LPHCALL lphConsultCall,
  11066. LPLINECALLPARAMS const lpCallParams
  11067. )
  11068. {
  11069. return lineSetupTransferA (hCall, lphConsultCall, lpCallParams);
  11070. }
  11071. LONG
  11072. WINAPI
  11073. lineShutdown(
  11074. HLINEAPP hLineApp
  11075. )
  11076. {
  11077. return (xxxShutdown (hLineApp, TRUE));
  11078. }
  11079. LONG
  11080. WINAPI
  11081. lineSwapHold(
  11082. HCALL hActiveCall,
  11083. HCALL hHeldCall
  11084. )
  11085. {
  11086. FUNC_ARGS funcArgs =
  11087. {
  11088. MAKELONG (LINE_FUNC | ASYNC | 2, lSwapHold),
  11089. {
  11090. (ULONG_PTR) hActiveCall,
  11091. (ULONG_PTR) hHeldCall
  11092. },
  11093. {
  11094. Dword,
  11095. Dword
  11096. }
  11097. };
  11098. return (DOFUNC (&funcArgs, "lineSwapHold"));
  11099. }
  11100. LONG
  11101. WINAPI
  11102. lineUncompleteCall(
  11103. HLINE hLine,
  11104. DWORD dwCompletionID
  11105. )
  11106. {
  11107. FUNC_ARGS funcArgs =
  11108. {
  11109. MAKELONG (LINE_FUNC | ASYNC | 2, lUncompleteCall),
  11110. {
  11111. (ULONG_PTR) hLine,
  11112. (ULONG_PTR) dwCompletionID
  11113. },
  11114. {
  11115. Dword,
  11116. Dword
  11117. }
  11118. };
  11119. return (DOFUNC (&funcArgs, "lineUncompleteCall"));
  11120. }
  11121. LONG
  11122. WINAPI
  11123. lineUnhold(
  11124. HCALL hCall
  11125. )
  11126. {
  11127. FUNC_ARGS funcArgs =
  11128. {
  11129. MAKELONG (LINE_FUNC | ASYNC | 1, lUnhold),
  11130. {
  11131. (ULONG_PTR) hCall
  11132. },
  11133. {
  11134. Dword
  11135. }
  11136. };
  11137. return (DOFUNC (&funcArgs, "lineUnhold"));
  11138. }
  11139. LONG
  11140. WINAPI
  11141. lineUnparkW(
  11142. HLINE hLine,
  11143. DWORD dwAddressID,
  11144. LPHCALL lphCall,
  11145. LPCWSTR lpszDestAddress
  11146. )
  11147. {
  11148. FUNC_ARGS funcArgs =
  11149. {
  11150. MAKELONG (LINE_FUNC | ASYNC | 5, lUnpark),
  11151. {
  11152. (ULONG_PTR) GetFunctionIndex(lineMakeCallPostProcess),
  11153. (ULONG_PTR) hLine,
  11154. (ULONG_PTR) dwAddressID,
  11155. (ULONG_PTR) lphCall,
  11156. (ULONG_PTR) lpszDestAddress
  11157. },
  11158. {
  11159. Dword,
  11160. Dword,
  11161. Dword,
  11162. Dword,
  11163. lpszW
  11164. }
  11165. };
  11166. DWORD hPointer = 0;
  11167. LONG lResult;
  11168. if (!gbNTVDMClient)
  11169. {
  11170. if (IsBadDwordPtr (lphCall))
  11171. {
  11172. return LINEERR_INVALPOINTER;
  11173. }
  11174. hPointer = NewObject (ghHandleTable, (PVOID)lphCall, NULL);
  11175. if (0 == hPointer)
  11176. {
  11177. return LINEERR_NOMEM;
  11178. }
  11179. funcArgs.Args[3] = (ULONG_PTR)hPointer;
  11180. }
  11181. lResult = (DOFUNC (&funcArgs, "lineUnpark"));
  11182. if (0 > lResult && hPointer)
  11183. {
  11184. DereferenceObject (ghHandleTable, hPointer, 1);
  11185. }
  11186. return lResult;
  11187. }
  11188. LONG
  11189. WINAPI
  11190. lineUnparkA(
  11191. HLINE hLine,
  11192. DWORD dwAddressID,
  11193. LPHCALL lphCall,
  11194. LPCSTR lpszDestAddress
  11195. )
  11196. {
  11197. LONG lResult;
  11198. PWSTR szTempPtr;
  11199. if (IsBadStringPtrA (lpszDestAddress, (DWORD) -1))
  11200. {
  11201. return LINEERR_INVALPOINTER;
  11202. }
  11203. else if (!(szTempPtr = NotSoWideStringToWideString(
  11204. lpszDestAddress,
  11205. (DWORD) -1
  11206. )))
  11207. {
  11208. return LINEERR_NOMEM;
  11209. }
  11210. lResult = lineUnparkW (hLine, dwAddressID, lphCall, szTempPtr);
  11211. ClientFree (szTempPtr);
  11212. return lResult;
  11213. }
  11214. LONG
  11215. WINAPI
  11216. lineUnpark(
  11217. HLINE hLine,
  11218. DWORD dwAddressID,
  11219. LPHCALL lphCall,
  11220. LPCSTR lpszDestAddress
  11221. )
  11222. {
  11223. return lineUnparkA (hLine, dwAddressID, lphCall, lpszDestAddress);
  11224. }
  11225. //
  11226. // ------------------------------- phoneXxx -----------------------------------
  11227. //
  11228. LONG
  11229. WINAPI
  11230. phoneClose(
  11231. HPHONE hPhone
  11232. )
  11233. {
  11234. LONG lResult;
  11235. DWORD Handle = 0;
  11236. FUNC_ARGS funcArgs =
  11237. {
  11238. MAKELONG (PHONE_FUNC | SYNC | 2, pClose),
  11239. {
  11240. (ULONG_PTR) hPhone,
  11241. (ULONG_PTR) &Handle
  11242. },
  11243. {
  11244. Dword,
  11245. lpDword
  11246. }
  11247. };
  11248. lResult = DOFUNC (&funcArgs, "phoneClose");
  11249. if (0 == lResult &&
  11250. 0 != Handle)
  11251. {
  11252. DereferenceObject (ghHandleTable, Handle, 1);
  11253. }
  11254. return lResult;
  11255. }
  11256. LONG
  11257. WINAPI
  11258. phoneConfigDialogW(
  11259. DWORD dwDeviceID,
  11260. HWND hwndOwner,
  11261. LPCWSTR lpszDeviceClass
  11262. )
  11263. {
  11264. LONG lResult;
  11265. HANDLE hDll;
  11266. TUISPIPROC pfnTUISPI_phoneConfigDialog;
  11267. if (lpszDeviceClass && TAPIIsBadStringPtrW (lpszDeviceClass, (UINT) -1))
  11268. {
  11269. LOG((TL_ERROR, "Bad lpszDeviceClass in phoneConfigDialogW [%p]",
  11270. lpszDeviceClass ));
  11271. return PHONEERR_INVALPOINTER;
  11272. }
  11273. if ((lResult = LoadUIDll(
  11274. hwndOwner,
  11275. dwDeviceID,
  11276. TUISPIDLL_OBJECT_PHONEID,
  11277. &hDll,
  11278. gszTUISPI_phoneConfigDialog,
  11279. &pfnTUISPI_phoneConfigDialog
  11280. )) == 0)
  11281. {
  11282. LOG((TL_TRACE, "Calling TUISPI_phoneConfigDialog..."));
  11283. lResult = (*pfnTUISPI_phoneConfigDialog)(
  11284. TUISPIDLLCallback,
  11285. dwDeviceID,
  11286. hwndOwner,
  11287. lpszDeviceClass
  11288. );
  11289. #if DBG
  11290. {
  11291. char szResult[32];
  11292. LOG((TL_TRACE,
  11293. "TUISPI_phoneConfigDialog: result = %hs",
  11294. MapResultCodeToText (lResult, szResult)
  11295. ));
  11296. }
  11297. #else
  11298. LOG((TL_TRACE,
  11299. "TUISPI_phoneConfigDialog: result = x%x",
  11300. lResult
  11301. ));
  11302. #endif
  11303. FreeLibrary (hDll);
  11304. }
  11305. return lResult;
  11306. }
  11307. LONG
  11308. WINAPI
  11309. phoneConfigDialogA(
  11310. DWORD dwDeviceID,
  11311. HWND hwndOwner,
  11312. LPCSTR lpszDeviceClass
  11313. )
  11314. {
  11315. LONG lResult;
  11316. PWSTR szTempString;
  11317. if (lpszDeviceClass && IsBadStringPtrA (lpszDeviceClass, (DWORD) -1))
  11318. {
  11319. return PHONEERR_INVALPOINTER;
  11320. }
  11321. szTempString = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  11322. lResult = phoneConfigDialogW (dwDeviceID, hwndOwner, szTempString);
  11323. if (szTempString)
  11324. {
  11325. ClientFree (szTempString);
  11326. }
  11327. return lResult;
  11328. }
  11329. LONG
  11330. WINAPI
  11331. phoneConfigDialog(
  11332. DWORD dwDeviceID,
  11333. HWND hwndOwner,
  11334. LPCSTR lpszDeviceClass
  11335. )
  11336. {
  11337. return phoneConfigDialogA (dwDeviceID, hwndOwner, lpszDeviceClass);
  11338. }
  11339. void
  11340. PASCAL
  11341. phoneDevSpecificPostProcess(
  11342. PASYNCEVENTMSG pMsg
  11343. )
  11344. {
  11345. LOG((TL_TRACE, "phoneDevSpecificPostProcess: enter"));
  11346. LOG((TL_INFO,
  11347. "\t\tp1=x%lx, p2=x%lx, p3=x%lx, p4=x%lx",
  11348. pMsg->Param1,
  11349. pMsg->Param2,
  11350. pMsg->Param3,
  11351. pMsg->Param4
  11352. ));
  11353. if (pMsg->Param2 == 0)
  11354. {
  11355. DWORD dwSize = (DWORD) pMsg->Param4;
  11356. if (dwSize > 0)
  11357. {
  11358. LPBYTE pParams = (LPBYTE) ReferenceObject (ghHandleTable, pMsg->Param3, 0);
  11359. // We don't need the handle to the pointer any more...
  11360. DereferenceObject (ghHandleTable, pMsg->Param3, 2);
  11361. try
  11362. {
  11363. if (gbNTVDMClient)
  11364. {
  11365. #ifndef _WIN64
  11366. LPVARSTRING pParamsVDM = (LPVARSTRING) gpfnWOWGetVDMPointer(
  11367. (DWORD) pParams,
  11368. dwSize,
  11369. TRUE // fProtectedMode
  11370. );
  11371. if (pParamsVDM)
  11372. {
  11373. CopyMemory (pParamsVDM, (LPBYTE) (pMsg + 1), dwSize);
  11374. }
  11375. else
  11376. {
  11377. pMsg->Param2 = PHONEERR_INVALPOINTER;
  11378. }
  11379. #endif
  11380. }
  11381. else
  11382. {
  11383. CopyMemory (pParams, (LPBYTE) (pMsg + 1), dwSize);
  11384. }
  11385. }
  11386. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  11387. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  11388. {
  11389. pMsg->Param2 = PHONEERR_INVALPOINTER;
  11390. }
  11391. }
  11392. }
  11393. }
  11394. LONG
  11395. WINAPI
  11396. phoneDevSpecific(
  11397. HPHONE hPhone,
  11398. LPVOID lpParams,
  11399. DWORD dwSize
  11400. )
  11401. {
  11402. FUNC_ARGS funcArgs =
  11403. {
  11404. MAKELONG (PHONE_FUNC | ASYNC | 5, pDevSpecific),
  11405. {
  11406. (ULONG_PTR) GetFunctionIndex(phoneDevSpecificPostProcess),
  11407. (ULONG_PTR) hPhone,
  11408. (ULONG_PTR) lpParams, // passed as Dword for post processing
  11409. (ULONG_PTR) lpParams, // passed as LpSet_Xxx for IsValidPtr chk
  11410. (ULONG_PTR) dwSize
  11411. },
  11412. {
  11413. Dword,
  11414. Dword,
  11415. Dword,
  11416. lpSet_SizeToFollow,
  11417. Size
  11418. }
  11419. };
  11420. DWORD hPointer = 0;
  11421. LONG lResult;
  11422. if (gbNTVDMClient)
  11423. {
  11424. #ifndef _WIN64
  11425. if (!gpfnWOWGetVDMPointer ||
  11426. !(funcArgs.Args[3] = (ULONG_PTR) gpfnWOWGetVDMPointer(
  11427. (DWORD) lpParams,
  11428. dwSize,
  11429. TRUE // fProtectedMode
  11430. )))
  11431. #endif
  11432. {
  11433. return PHONEERR_OPERATIONFAILED;
  11434. }
  11435. }
  11436. if (!gbNTVDMClient)
  11437. {
  11438. if ( !lpParams && dwSize > 0)
  11439. {
  11440. return PHONEERR_INVALPOINTER;
  11441. }
  11442. if (dwSize > 0)
  11443. {
  11444. hPointer = NewObject (ghHandleTable, (PVOID)lpParams, NULL);
  11445. if (0 == hPointer)
  11446. {
  11447. return PHONEERR_NOMEM;
  11448. }
  11449. funcArgs.Args[2] = (ULONG_PTR)hPointer;
  11450. }
  11451. }
  11452. lResult = (DOFUNC (&funcArgs, "phoneDevSpecific"));
  11453. if (0 > lResult && hPointer)
  11454. {
  11455. DereferenceObject (ghHandleTable, hPointer, 1);
  11456. }
  11457. return lResult;
  11458. }
  11459. LONG
  11460. WINAPI
  11461. phoneGetButtonInfoW(
  11462. HPHONE hPhone,
  11463. DWORD dwButtonLampID,
  11464. LPPHONEBUTTONINFO lpButtonInfo
  11465. )
  11466. {
  11467. FUNC_ARGS funcArgs =
  11468. {
  11469. MAKELONG (PHONE_FUNC | SYNC | 3, pGetButtonInfo),
  11470. {
  11471. (ULONG_PTR) hPhone,
  11472. (ULONG_PTR) dwButtonLampID,
  11473. (ULONG_PTR) lpButtonInfo
  11474. },
  11475. {
  11476. Dword,
  11477. Dword,
  11478. lpGet_Struct
  11479. }
  11480. };
  11481. return (DOFUNC (&funcArgs, "phoneGetButtonInfo"));
  11482. }
  11483. LONG
  11484. WINAPI
  11485. phoneGetButtonInfoA(
  11486. HPHONE hPhone,
  11487. DWORD dwButtonLampID,
  11488. LPPHONEBUTTONINFO lpButtonInfo
  11489. )
  11490. {
  11491. LONG lResult;
  11492. lResult = phoneGetButtonInfoW (hPhone, dwButtonLampID, lpButtonInfo);
  11493. if ( 0 == lResult )
  11494. {
  11495. WideStringToNotSoWideString(
  11496. (LPBYTE)lpButtonInfo,
  11497. &lpButtonInfo->dwButtonTextSize
  11498. );
  11499. }
  11500. return lResult;
  11501. }
  11502. LONG
  11503. WINAPI
  11504. phoneGetButtonInfo(
  11505. HPHONE hPhone,
  11506. DWORD dwButtonLampID,
  11507. LPPHONEBUTTONINFO lpButtonInfo
  11508. )
  11509. {
  11510. return phoneGetButtonInfoA (hPhone, dwButtonLampID, lpButtonInfo);
  11511. }
  11512. LONG
  11513. WINAPI
  11514. phoneGetData(
  11515. HPHONE hPhone,
  11516. DWORD dwDataID,
  11517. LPVOID lpData,
  11518. DWORD dwSize
  11519. )
  11520. {
  11521. FUNC_ARGS funcArgs =
  11522. {
  11523. MAKELONG (PHONE_FUNC | SYNC | 4, pGetData),
  11524. {
  11525. (ULONG_PTR) hPhone,
  11526. (ULONG_PTR) dwDataID,
  11527. (ULONG_PTR) lpData,
  11528. (ULONG_PTR) dwSize
  11529. },
  11530. {
  11531. Dword,
  11532. Dword,
  11533. lpGet_SizeToFollow,
  11534. Size
  11535. }
  11536. };
  11537. return (DOFUNC (&funcArgs, "phoneGetData"));
  11538. }
  11539. LONG
  11540. WINAPI
  11541. phoneGetDevCapsW(
  11542. HPHONEAPP hPhoneApp,
  11543. DWORD dwDeviceID,
  11544. DWORD dwAPIVersion,
  11545. DWORD dwExtVersion,
  11546. LPPHONECAPS lpPhoneCaps
  11547. )
  11548. {
  11549. FUNC_ARGS funcArgs =
  11550. {
  11551. MAKELONG (PHONE_FUNC | SYNC | 5, pGetDevCaps),
  11552. {
  11553. (ULONG_PTR) hPhoneApp,
  11554. (ULONG_PTR) dwDeviceID,
  11555. (ULONG_PTR) dwAPIVersion,
  11556. (ULONG_PTR) dwExtVersion,
  11557. (ULONG_PTR) lpPhoneCaps
  11558. },
  11559. {
  11560. hXxxApp,
  11561. Dword,
  11562. Dword,
  11563. Dword,
  11564. lpGet_Struct
  11565. }
  11566. };
  11567. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  11568. {
  11569. return PHONEERR_INCOMPATIBLEAPIVERSION;
  11570. }
  11571. return (DOFUNC (&funcArgs, "phoneGetDevCaps"));
  11572. }
  11573. LONG
  11574. WINAPI
  11575. phoneGetDevCapsA(
  11576. HPHONEAPP hPhoneApp,
  11577. DWORD dwDeviceID,
  11578. DWORD dwAPIVersion,
  11579. DWORD dwExtVersion,
  11580. LPPHONECAPS lpPhoneCaps
  11581. )
  11582. {
  11583. LONG lResult;
  11584. lResult = phoneGetDevCapsW(
  11585. hPhoneApp,
  11586. dwDeviceID,
  11587. dwAPIVersion,
  11588. dwExtVersion,
  11589. lpPhoneCaps
  11590. );
  11591. if (lResult == 0)
  11592. {
  11593. lpPhoneCaps->dwStringFormat = STRINGFORMAT_ASCII;
  11594. WideStringToNotSoWideString(
  11595. (LPBYTE) lpPhoneCaps,
  11596. &lpPhoneCaps->dwProviderInfoSize
  11597. );
  11598. WideStringToNotSoWideString(
  11599. (LPBYTE) lpPhoneCaps,
  11600. &lpPhoneCaps->dwPhoneInfoSize
  11601. );
  11602. WideStringToNotSoWideString(
  11603. (LPBYTE) lpPhoneCaps,
  11604. &lpPhoneCaps->dwPhoneNameSize
  11605. );
  11606. if (dwAPIVersion >= 0x00020000)
  11607. {
  11608. WideStringToNotSoWideString(
  11609. (LPBYTE) lpPhoneCaps,
  11610. &lpPhoneCaps->dwDeviceClassesSize
  11611. );
  11612. }
  11613. }
  11614. return lResult;
  11615. }
  11616. LONG
  11617. WINAPI
  11618. phoneGetDevCaps(
  11619. HPHONEAPP hPhoneApp,
  11620. DWORD dwDeviceID,
  11621. DWORD dwAPIVersion,
  11622. DWORD dwExtVersion,
  11623. LPPHONECAPS lpPhoneCaps
  11624. )
  11625. {
  11626. return phoneGetDevCapsA(
  11627. hPhoneApp,
  11628. dwDeviceID,
  11629. dwAPIVersion,
  11630. dwExtVersion,
  11631. lpPhoneCaps
  11632. );
  11633. }
  11634. LONG
  11635. WINAPI
  11636. phoneGetDisplay(
  11637. HPHONE hPhone,
  11638. LPVARSTRING lpDisplay
  11639. )
  11640. {
  11641. FUNC_ARGS funcArgs =
  11642. {
  11643. MAKELONG (PHONE_FUNC | SYNC | 2, pGetDisplay),
  11644. {
  11645. (ULONG_PTR) hPhone,
  11646. (ULONG_PTR) lpDisplay
  11647. },
  11648. {
  11649. Dword,
  11650. lpGet_Struct
  11651. }
  11652. };
  11653. return (DOFUNC (&funcArgs, "phoneGetDisplay"));
  11654. }
  11655. LONG
  11656. WINAPI
  11657. phoneGetGain(
  11658. HPHONE hPhone,
  11659. DWORD dwHookSwitchDev,
  11660. LPDWORD lpdwGain
  11661. )
  11662. {
  11663. FUNC_ARGS funcArgs =
  11664. {
  11665. MAKELONG (PHONE_FUNC | SYNC | 3, pGetGain),
  11666. {
  11667. (ULONG_PTR) hPhone,
  11668. (ULONG_PTR) dwHookSwitchDev,
  11669. (ULONG_PTR) lpdwGain
  11670. },
  11671. {
  11672. Dword,
  11673. Dword,
  11674. lpDword
  11675. }
  11676. };
  11677. return (DOFUNC (&funcArgs, "phoneGetGain"));
  11678. }
  11679. LONG
  11680. WINAPI
  11681. phoneGetHookSwitch(
  11682. HPHONE hPhone,
  11683. LPDWORD lpdwHookSwitchDevs
  11684. )
  11685. {
  11686. FUNC_ARGS funcArgs =
  11687. {
  11688. MAKELONG (PHONE_FUNC | SYNC | 2, pGetHookSwitch),
  11689. {
  11690. (ULONG_PTR) hPhone,
  11691. (ULONG_PTR) lpdwHookSwitchDevs
  11692. },
  11693. {
  11694. Dword,
  11695. lpDword
  11696. }
  11697. };
  11698. return (DOFUNC (&funcArgs, "phoneGetHookSwitch"));
  11699. }
  11700. LONG
  11701. WINAPI
  11702. phoneGetIconW(
  11703. DWORD dwDeviceID,
  11704. LPCWSTR lpszDeviceClass,
  11705. LPHICON lphIcon
  11706. )
  11707. {
  11708. FUNC_ARGS funcArgs =
  11709. {
  11710. MAKELONG (PHONE_FUNC | SYNC | 3, pGetIcon),
  11711. {
  11712. (ULONG_PTR) dwDeviceID,
  11713. (ULONG_PTR) lpszDeviceClass,
  11714. (ULONG_PTR) lphIcon
  11715. },
  11716. {
  11717. Dword,
  11718. lpszW,
  11719. lpDword
  11720. }
  11721. };
  11722. if (IsBadDwordPtr ((LPDWORD) lphIcon))
  11723. {
  11724. LOG((TL_ERROR,
  11725. "Bad icon pointer passed into PhoneGetIconA [0x%p]",
  11726. lphIcon
  11727. ));
  11728. return PHONEERR_INVALPOINTER;
  11729. }
  11730. if (lpszDeviceClass == (LPCWSTR) NULL)
  11731. {
  11732. //
  11733. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  11734. //
  11735. funcArgs.ArgTypes[1] = Dword;
  11736. funcArgs.Args[1] = (ULONG_PTR) TAPI_NO_DATA;
  11737. }
  11738. return DOFUNC (&funcArgs, "phoneGetIcon");
  11739. }
  11740. LONG
  11741. WINAPI
  11742. phoneGetIconA(
  11743. DWORD dwDeviceID,
  11744. LPCSTR lpszDeviceClass,
  11745. LPHICON lphIcon
  11746. )
  11747. {
  11748. LONG lResult;
  11749. PWSTR szTempPtr;
  11750. if (lpszDeviceClass)
  11751. {
  11752. if (IsBadStringPtrA (lpszDeviceClass, (DWORD) (DWORD) -1))
  11753. {
  11754. return PHONEERR_INVALPOINTER;
  11755. }
  11756. szTempPtr = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  11757. }
  11758. else
  11759. {
  11760. szTempPtr = NULL;
  11761. }
  11762. lResult = phoneGetIconW (dwDeviceID, szTempPtr, lphIcon);
  11763. if (szTempPtr)
  11764. {
  11765. ClientFree (szTempPtr);
  11766. }
  11767. return lResult;
  11768. }
  11769. LONG
  11770. WINAPI
  11771. phoneGetIcon(
  11772. DWORD dwDeviceID,
  11773. LPCSTR lpszDeviceClass,
  11774. LPHICON lphIcon
  11775. )
  11776. {
  11777. return (phoneGetIconA (dwDeviceID, lpszDeviceClass, lphIcon));
  11778. }
  11779. LONG
  11780. WINAPI
  11781. phoneGetIDW(
  11782. HPHONE hPhone,
  11783. LPVARSTRING lpDeviceID,
  11784. LPCWSTR lpszDeviceClass
  11785. )
  11786. {
  11787. FUNC_ARGS funcArgs =
  11788. {
  11789. MAKELONG (PHONE_FUNC | SYNC | 3, pGetID),
  11790. {
  11791. (ULONG_PTR) hPhone,
  11792. (ULONG_PTR) lpDeviceID,
  11793. (ULONG_PTR) lpszDeviceClass
  11794. },
  11795. {
  11796. Dword,
  11797. lpGet_Struct,
  11798. lpszW
  11799. }
  11800. };
  11801. LPVARSTRING lpDeviceIDTemp = NULL;
  11802. DWORD dwNumDevices;
  11803. DWORD dwBufSize;
  11804. DWORD dwResult;
  11805. DWORD dwDeviceId1, dwDeviceId2;
  11806. BOOL bDoItAgain = FALSE;
  11807. if ( TAPIIsBadStringPtrW(lpszDeviceClass, (UINT)-1) )
  11808. {
  11809. LOG((TL_ERROR, "Bad lpszDeviceClass in phoneGetIDW"));
  11810. return( PHONEERR_INVALPOINTER );
  11811. }
  11812. if ( IsBadWritePtr(lpDeviceID, sizeof(VARSTRING)) )
  11813. {
  11814. LOG((TL_ERROR, "Bad lpDeviceID in lineGetIDW"));
  11815. return( PHONEERR_INVALPOINTER);
  11816. }
  11817. //
  11818. // if the request is for a wave device, call LGetIDEx
  11819. //
  11820. if (!_wcsicmp(lpszDeviceClass, L"wave/in") ||
  11821. !_wcsicmp(lpszDeviceClass, L"wave/out") ||
  11822. !_wcsicmp(lpszDeviceClass, L"midi/in") ||
  11823. !_wcsicmp(lpszDeviceClass, L"midi/out") ||
  11824. !_wcsicmp(lpszDeviceClass, L"wave/in/out")
  11825. )
  11826. {
  11827. dwNumDevices = _wcsicmp(lpszDeviceClass, L"wave/in/out") ? 1 : 2;
  11828. dwBufSize = lpDeviceID->dwTotalSize + dwNumDevices * WAVE_STRING_ID_BUFFER_SIZE;
  11829. do
  11830. {
  11831. //
  11832. // Allocate additional memory for the device string ID
  11833. //
  11834. lpDeviceIDTemp = (LPVARSTRING)ClientAlloc (dwBufSize);
  11835. if (!lpDeviceIDTemp)
  11836. {
  11837. LOG((TL_ERROR, "Failed to allocate memory"));
  11838. return( PHONEERR_NOMEM );
  11839. }
  11840. lpDeviceIDTemp->dwTotalSize = dwBufSize;
  11841. funcArgs.Flags = MAKELONG (PHONE_FUNC | SYNC | 3, pGetIDEx);
  11842. funcArgs.Args[1] = (ULONG_PTR)lpDeviceIDTemp;
  11843. //
  11844. // Call LGetIDEx
  11845. //
  11846. dwResult = DOFUNC (&funcArgs, "phoneGetIDEx");
  11847. if (dwResult)
  11848. {
  11849. LOG((TL_ERROR, "phoneGetIDEx failed with x%x", dwResult));
  11850. ClientFree (lpDeviceIDTemp);
  11851. return dwResult;
  11852. }
  11853. if (lpDeviceIDTemp->dwNeededSize > lpDeviceIDTemp->dwTotalSize && !bDoItAgain)
  11854. {
  11855. LOG((TL_INFO,
  11856. "phoneGetIDEx returned needed size (%d) bigger than total size (%d) -> need to realloc",
  11857. lpDeviceIDTemp->dwNeededSize,
  11858. lpDeviceIDTemp->dwTotalSize ));
  11859. dwBufSize = lpDeviceIDTemp->dwNeededSize;
  11860. ClientFree ( lpDeviceIDTemp );
  11861. bDoItAgain = TRUE;
  11862. }
  11863. else
  11864. {
  11865. bDoItAgain = FALSE;
  11866. }
  11867. } while (bDoItAgain);
  11868. if (lpDeviceIDTemp->dwNeededSize > lpDeviceIDTemp->dwTotalSize)
  11869. {
  11870. LOG((TL_ERROR, "needed size (%d) still bigger than total size (%d)",
  11871. lpDeviceIDTemp->dwNeededSize,
  11872. lpDeviceIDTemp->dwTotalSize ));
  11873. ClientFree (lpDeviceIDTemp);
  11874. return PHONEERR_OPERATIONFAILED;
  11875. }
  11876. //
  11877. // Get the device ID from string ID
  11878. //
  11879. if (dwNumDevices == 1)
  11880. {
  11881. if (!WaveStringIdToDeviceId (
  11882. (LPWSTR)((LPBYTE)lpDeviceIDTemp + lpDeviceIDTemp->dwStringOffset),
  11883. lpszDeviceClass,
  11884. &dwDeviceId1)
  11885. )
  11886. {
  11887. LOG((TL_ERROR, "WaveStringIdToDeviceId failed"));
  11888. ClientFree (lpDeviceIDTemp);
  11889. return PHONEERR_OPERATIONFAILED;
  11890. }
  11891. // check if the client buffer is big enough
  11892. if (lpDeviceID->dwTotalSize < sizeof(VARSTRING) + sizeof(DWORD))
  11893. {
  11894. lpDeviceID->dwNeededSize = sizeof(VARSTRING) + sizeof(DWORD);
  11895. lpDeviceID->dwUsedSize = sizeof(VARSTRING);
  11896. }
  11897. else
  11898. {
  11899. lpDeviceID->dwNeededSize = lpDeviceID->dwUsedSize = sizeof(VARSTRING) + sizeof(DWORD);
  11900. lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
  11901. lpDeviceID->dwStringSize = sizeof(DWORD);
  11902. lpDeviceID->dwStringOffset = sizeof(VARSTRING);
  11903. *(DWORD *)(lpDeviceID + 1) = dwDeviceId1;
  11904. }
  11905. }
  11906. else
  11907. {
  11908. LPWSTR szString1 = (LPWSTR)((LPBYTE)lpDeviceIDTemp + lpDeviceIDTemp->dwStringOffset);
  11909. if (!WaveStringIdToDeviceId (
  11910. szString1,
  11911. L"wave/in",
  11912. &dwDeviceId1) ||
  11913. !WaveStringIdToDeviceId (
  11914. (LPWSTR)((LPBYTE)lpDeviceIDTemp + lpDeviceIDTemp->dwStringOffset + wcslen(szString1)),
  11915. L"wave/out",
  11916. &dwDeviceId2)
  11917. )
  11918. {
  11919. LOG((TL_ERROR, "WaveStringIdToDeviceId failed"));
  11920. ClientFree (lpDeviceIDTemp);
  11921. return PHONEERR_OPERATIONFAILED;
  11922. }
  11923. // check if the client buffer is big enough
  11924. if (lpDeviceID->dwTotalSize < sizeof(VARSTRING) + 2 * sizeof(DWORD))
  11925. {
  11926. lpDeviceID->dwNeededSize = sizeof(VARSTRING) + 2 * sizeof(DWORD);
  11927. lpDeviceID->dwUsedSize = sizeof(VARSTRING);
  11928. }
  11929. else
  11930. {
  11931. lpDeviceID->dwNeededSize = lpDeviceID->dwUsedSize = sizeof(VARSTRING) + 2 * sizeof(DWORD);
  11932. lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
  11933. lpDeviceID->dwStringSize = 2 * sizeof(DWORD);
  11934. lpDeviceID->dwStringOffset = sizeof(VARSTRING);
  11935. *(DWORD *)(lpDeviceID + 1) = dwDeviceId1;
  11936. *((DWORD *)(lpDeviceID + 1) + 1) = dwDeviceId2;
  11937. }
  11938. }
  11939. ClientFree (lpDeviceIDTemp);
  11940. return NO_ERROR;
  11941. }
  11942. else
  11943. {
  11944. return (DOFUNC (&funcArgs, "phoneGetID"));
  11945. }
  11946. }
  11947. LONG
  11948. WINAPI
  11949. phoneGetIDA(
  11950. HPHONE hPhone,
  11951. LPVARSTRING lpDeviceID,
  11952. LPCSTR lpszDeviceClass
  11953. )
  11954. {
  11955. LONG lResult;
  11956. PWSTR szTempPtr;
  11957. if ( IsBadStringPtrA(lpszDeviceClass, (UINT)-1) )
  11958. {
  11959. LOG((TL_ERROR, "Bad lpszDeviceClass in phoneGetIDA"));
  11960. return( PHONEERR_INVALPOINTER );
  11961. }
  11962. szTempPtr = NotSoWideStringToWideString (lpszDeviceClass, (DWORD) -1);
  11963. lResult = phoneGetIDW (hPhone, lpDeviceID, szTempPtr);
  11964. if (szTempPtr)
  11965. {
  11966. ClientFree (szTempPtr);
  11967. }
  11968. return lResult;
  11969. }
  11970. LONG
  11971. WINAPI
  11972. phoneGetID(
  11973. HPHONE hPhone,
  11974. LPVARSTRING lpDeviceID,
  11975. LPCSTR lpszDeviceClass
  11976. )
  11977. {
  11978. return phoneGetIDA (hPhone, lpDeviceID, lpszDeviceClass);
  11979. }
  11980. LONG
  11981. WINAPI
  11982. phoneGetLamp(
  11983. HPHONE hPhone,
  11984. DWORD dwButtonLampID,
  11985. LPDWORD lpdwLampMode
  11986. )
  11987. {
  11988. FUNC_ARGS funcArgs =
  11989. {
  11990. MAKELONG (PHONE_FUNC | SYNC | 3, pGetLamp),
  11991. {
  11992. (ULONG_PTR) hPhone,
  11993. (ULONG_PTR) dwButtonLampID,
  11994. (ULONG_PTR) lpdwLampMode
  11995. },
  11996. {
  11997. Dword,
  11998. Dword,
  11999. lpDword
  12000. }
  12001. };
  12002. return (DOFUNC (&funcArgs, "phoneGetLamp"));
  12003. }
  12004. LONG
  12005. WINAPI
  12006. phoneGetMessage(
  12007. HPHONEAPP hPhoneApp,
  12008. LPPHONEMESSAGE lpMessage,
  12009. DWORD dwTimeout
  12010. )
  12011. {
  12012. return (xxxGetMessage(
  12013. FALSE,
  12014. (HLINEAPP) hPhoneApp,
  12015. (LPLINEMESSAGE) lpMessage,
  12016. dwTimeout
  12017. ));
  12018. }
  12019. LONG
  12020. WINAPI
  12021. phoneGetRing(
  12022. HPHONE hPhone,
  12023. LPDWORD lpdwRingMode,
  12024. LPDWORD lpdwVolume
  12025. )
  12026. {
  12027. FUNC_ARGS funcArgs =
  12028. {
  12029. MAKELONG (PHONE_FUNC | SYNC | 3, pGetRing),
  12030. {
  12031. (ULONG_PTR) hPhone,
  12032. (ULONG_PTR) lpdwRingMode,
  12033. (ULONG_PTR) lpdwVolume
  12034. },
  12035. {
  12036. Dword,
  12037. lpDword,
  12038. lpDword
  12039. }
  12040. };
  12041. if (lpdwRingMode == lpdwVolume)
  12042. {
  12043. return PHONEERR_INVALPOINTER;
  12044. }
  12045. return (DOFUNC (&funcArgs, "phoneGetRing"));
  12046. }
  12047. LONG
  12048. WINAPI
  12049. phoneGetStatusW(
  12050. HPHONE hPhone,
  12051. LPPHONESTATUS lpPhoneStatus
  12052. )
  12053. {
  12054. FUNC_ARGS funcArgs =
  12055. {
  12056. MAKELONG (PHONE_FUNC | SYNC | 2, pGetStatus),
  12057. {
  12058. (ULONG_PTR) hPhone,
  12059. (ULONG_PTR) lpPhoneStatus
  12060. },
  12061. {
  12062. Dword,
  12063. lpGet_Struct
  12064. }
  12065. };
  12066. return (DOFUNC (&funcArgs, "phoneGetStatus"));
  12067. }
  12068. LONG
  12069. WINAPI
  12070. phoneGetStatusA(
  12071. HPHONE hPhone,
  12072. LPPHONESTATUS lpPhoneStatus
  12073. )
  12074. {
  12075. LONG lResult;
  12076. lResult = phoneGetStatusW (hPhone, lpPhoneStatus);
  12077. if (lResult == 0)
  12078. {
  12079. WideStringToNotSoWideString(
  12080. (LPBYTE)lpPhoneStatus,
  12081. &lpPhoneStatus->dwOwnerNameSize
  12082. );
  12083. }
  12084. return lResult;
  12085. }
  12086. LONG
  12087. WINAPI
  12088. phoneGetStatus(
  12089. HPHONE hPhone,
  12090. LPPHONESTATUS lpPhoneStatus
  12091. )
  12092. {
  12093. return phoneGetStatusA (hPhone, lpPhoneStatus);
  12094. }
  12095. LONG
  12096. WINAPI
  12097. phoneGetStatusMessages(
  12098. HPHONE hPhone,
  12099. LPDWORD lpdwPhoneStates,
  12100. LPDWORD lpdwButtonModes,
  12101. LPDWORD lpdwButtonStates
  12102. )
  12103. {
  12104. FUNC_ARGS funcArgs =
  12105. {
  12106. MAKELONG (PHONE_FUNC | SYNC | 4, pGetStatusMessages),
  12107. {
  12108. (ULONG_PTR) hPhone,
  12109. (ULONG_PTR) lpdwPhoneStates,
  12110. (ULONG_PTR) lpdwButtonModes,
  12111. (ULONG_PTR) lpdwButtonStates
  12112. },
  12113. {
  12114. Dword,
  12115. lpDword,
  12116. lpDword,
  12117. lpDword
  12118. }
  12119. };
  12120. if (lpdwPhoneStates == lpdwButtonModes ||
  12121. lpdwPhoneStates == lpdwButtonStates ||
  12122. lpdwButtonModes == lpdwButtonStates)
  12123. {
  12124. return PHONEERR_INVALPOINTER;
  12125. }
  12126. return (DOFUNC (&funcArgs, "phoneGetStatusMessages"));
  12127. }
  12128. LONG
  12129. WINAPI
  12130. phoneGetVolume(
  12131. HPHONE hPhone,
  12132. DWORD dwHookSwitchDev,
  12133. LPDWORD lpdwVolume
  12134. )
  12135. {
  12136. FUNC_ARGS funcArgs =
  12137. {
  12138. MAKELONG (PHONE_FUNC | SYNC | 3, pGetVolume),
  12139. {
  12140. (ULONG_PTR) hPhone,
  12141. (ULONG_PTR) dwHookSwitchDev,
  12142. (ULONG_PTR) lpdwVolume
  12143. },
  12144. {
  12145. Dword,
  12146. Dword,
  12147. lpDword
  12148. }
  12149. };
  12150. return (DOFUNC (&funcArgs, "phoneGetVolume"));
  12151. }
  12152. LONG
  12153. WINAPI
  12154. phoneInitialize(
  12155. LPHPHONEAPP lphPhoneApp,
  12156. HINSTANCE hInstance,
  12157. PHONECALLBACK lpfnCallback,
  12158. LPCSTR lpszFriendlyAppName,
  12159. LPDWORD lpdwNumDevs
  12160. )
  12161. {
  12162. LONG lResult;
  12163. PWSTR szTempPtr;
  12164. if (lpszFriendlyAppName)
  12165. {
  12166. if (IsBadStringPtrA (lpszFriendlyAppName, (DWORD) -1))
  12167. {
  12168. LOG((TL_ERROR,
  12169. "phoneInitialize: bad lpszFriendlyAppName (x%p)",
  12170. lpszFriendlyAppName
  12171. ));
  12172. return PHONEERR_INVALPOINTER;
  12173. }
  12174. szTempPtr = NotSoWideStringToWideString(
  12175. lpszFriendlyAppName,
  12176. (DWORD) -1
  12177. );
  12178. }
  12179. else
  12180. {
  12181. szTempPtr = NULL;
  12182. }
  12183. //
  12184. // NOTE: the hack below for the lpInitExParam is for 16-bit apps,
  12185. // since the lpszAppName really points at a
  12186. // <friendly name>\0<module name>\0 string and we need the
  12187. // module name in xxxInitialize()
  12188. //
  12189. lResult = (xxxInitialize(
  12190. FALSE,
  12191. (LPVOID) lphPhoneApp,
  12192. hInstance,
  12193. lpfnCallback,
  12194. szTempPtr,
  12195. lpdwNumDevs,
  12196. NULL,
  12197. #ifdef _WIN64
  12198. NULL
  12199. #else
  12200. (LPLINEINITIALIZEEXPARAMS)
  12201. (((DWORD) lpfnCallback & 0xffff0000) == 0xffff0000 ?
  12202. lpszFriendlyAppName : NULL)
  12203. #endif
  12204. #if DBG
  12205. ,"phoneInitialize"
  12206. #endif
  12207. ));
  12208. if (szTempPtr)
  12209. {
  12210. ClientFree (szTempPtr);
  12211. }
  12212. return lResult;
  12213. }
  12214. LONG
  12215. WINAPI
  12216. phoneInitializeExW(
  12217. LPHPHONEAPP lphPhoneApp,
  12218. HINSTANCE hInstance,
  12219. PHONECALLBACK lpfnCallback,
  12220. LPCWSTR lpszFriendlyAppName,
  12221. LPDWORD lpdwNumDevs,
  12222. LPDWORD lpdwAPIVersion,
  12223. LPPHONEINITIALIZEEXPARAMS lpPhoneInitializeExParams
  12224. )
  12225. {
  12226. if (IsBadDwordPtr (lpdwAPIVersion))
  12227. {
  12228. LOG((TL_ERROR,
  12229. "phoneInitializeExW: bad lpdwAPIVersion (x%p)",
  12230. lpdwAPIVersion
  12231. ));
  12232. return PHONEERR_INVALPOINTER;
  12233. }
  12234. return (xxxInitialize(
  12235. FALSE,
  12236. (LPVOID) lphPhoneApp,
  12237. hInstance,
  12238. lpfnCallback,
  12239. lpszFriendlyAppName,
  12240. lpdwNumDevs,
  12241. lpdwAPIVersion,
  12242. (LPVOID) lpPhoneInitializeExParams
  12243. #if DBG
  12244. ,"phoneInitializeExW"
  12245. #endif
  12246. ));
  12247. }
  12248. LONG
  12249. WINAPI
  12250. phoneInitializeExA(
  12251. LPHPHONEAPP lphPhoneApp,
  12252. HINSTANCE hInstance,
  12253. PHONECALLBACK lpfnCallback,
  12254. LPCSTR lpszFriendlyAppName,
  12255. LPDWORD lpdwNumDevs,
  12256. LPDWORD lpdwAPIVersion,
  12257. LPPHONEINITIALIZEEXPARAMS lpPhoneInitializeExParams
  12258. )
  12259. {
  12260. LONG lResult;
  12261. PWSTR szTempPtr = NULL;
  12262. if (lpszFriendlyAppName)
  12263. {
  12264. if (IsBadStringPtrA (lpszFriendlyAppName, (DWORD) -1))
  12265. {
  12266. LOG((TL_ERROR,
  12267. "phoneInitializeExA: bad lpszFriendlyAppName (x%p)",
  12268. lpszFriendlyAppName
  12269. ));
  12270. return PHONEERR_INVALPOINTER;
  12271. }
  12272. szTempPtr = NotSoWideStringToWideString(
  12273. lpszFriendlyAppName,
  12274. (DWORD) -1
  12275. );
  12276. }
  12277. else
  12278. {
  12279. szTempPtr = NULL;
  12280. }
  12281. lResult = phoneInitializeExW(
  12282. lphPhoneApp,
  12283. hInstance,
  12284. lpfnCallback,
  12285. szTempPtr,
  12286. lpdwNumDevs,
  12287. lpdwAPIVersion,
  12288. lpPhoneInitializeExParams
  12289. );
  12290. if (szTempPtr)
  12291. {
  12292. ClientFree (szTempPtr);
  12293. }
  12294. return lResult;
  12295. }
  12296. LONG
  12297. WINAPI
  12298. phoneNegotiateAPIVersion(
  12299. HPHONEAPP hPhoneApp,
  12300. DWORD dwDeviceID,
  12301. DWORD dwAPILowVersion,
  12302. DWORD dwAPIHighVersion,
  12303. LPDWORD lpdwAPIVersion,
  12304. LPPHONEEXTENSIONID lpExtensionID
  12305. )
  12306. {
  12307. FUNC_ARGS funcArgs =
  12308. {
  12309. MAKELONG (PHONE_FUNC | SYNC | 7, pNegotiateAPIVersion),
  12310. {
  12311. (ULONG_PTR) hPhoneApp,
  12312. (ULONG_PTR) dwDeviceID,
  12313. (ULONG_PTR) dwAPILowVersion,
  12314. (ULONG_PTR) dwAPIHighVersion,
  12315. (ULONG_PTR) lpdwAPIVersion,
  12316. (ULONG_PTR) lpExtensionID,
  12317. (ULONG_PTR) sizeof(PHONEEXTENSIONID)
  12318. },
  12319. {
  12320. hXxxApp,
  12321. Dword,
  12322. Dword,
  12323. Dword,
  12324. lpDword,
  12325. lpGet_SizeToFollow,
  12326. Size
  12327. }
  12328. };
  12329. if (dwAPIHighVersion > TAPI_CURRENT_VERSION)
  12330. {
  12331. funcArgs.Args[3] = TAPI_CURRENT_VERSION;
  12332. }
  12333. if ((LPVOID) lpdwAPIVersion == (LPVOID) lpExtensionID)
  12334. {
  12335. return PHONEERR_INVALPOINTER;
  12336. }
  12337. return (DOFUNC (&funcArgs, "phoneNegotiateAPIVersion"));
  12338. }
  12339. LONG
  12340. WINAPI
  12341. phoneNegotiateExtVersion(
  12342. HPHONEAPP hPhoneApp,
  12343. DWORD dwDeviceID,
  12344. DWORD dwAPIVersion,
  12345. DWORD dwExtLowVersion,
  12346. DWORD dwExtHighVersion,
  12347. LPDWORD lpdwExtVersion
  12348. )
  12349. {
  12350. FUNC_ARGS funcArgs =
  12351. {
  12352. MAKELONG (PHONE_FUNC | SYNC | 6, pNegotiateExtVersion),
  12353. {
  12354. (ULONG_PTR) hPhoneApp,
  12355. (ULONG_PTR) dwDeviceID,
  12356. (ULONG_PTR) dwAPIVersion,
  12357. (ULONG_PTR) dwExtLowVersion,
  12358. (ULONG_PTR) dwExtHighVersion,
  12359. (ULONG_PTR) lpdwExtVersion
  12360. },
  12361. {
  12362. hXxxApp,
  12363. Dword,
  12364. Dword,
  12365. Dword,
  12366. Dword,
  12367. lpDword
  12368. }
  12369. };
  12370. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  12371. {
  12372. return PHONEERR_INCOMPATIBLEAPIVERSION;
  12373. }
  12374. return (DOFUNC (&funcArgs, "phoneNegotiateExtVersion"));
  12375. }
  12376. LONG
  12377. WINAPI
  12378. phoneOpen(
  12379. HPHONEAPP hPhoneApp,
  12380. DWORD dwDeviceID,
  12381. LPHPHONE lphPhone,
  12382. DWORD dwAPIVersion,
  12383. DWORD dwExtVersion,
  12384. DWORD_PTR dwCallbackInstance,
  12385. DWORD dwPrivilege
  12386. )
  12387. {
  12388. DWORD hCallbackInstance = 0;
  12389. LONG lResult;
  12390. FUNC_ARGS funcArgs =
  12391. {
  12392. MAKELONG (PHONE_FUNC | SYNC | 8, pOpen),
  12393. {
  12394. (ULONG_PTR) hPhoneApp,
  12395. (ULONG_PTR) dwDeviceID,
  12396. (ULONG_PTR) lphPhone,
  12397. (ULONG_PTR) dwAPIVersion,
  12398. (ULONG_PTR) dwExtVersion,
  12399. (ULONG_PTR) dwCallbackInstance,
  12400. (ULONG_PTR) dwPrivilege,
  12401. (ULONG_PTR) 0, // PHONEOPEN_PARAMS.hRemotePhone
  12402. },
  12403. {
  12404. hXxxApp,
  12405. Dword,
  12406. lpDword,
  12407. Dword,
  12408. Dword,
  12409. Dword,
  12410. Dword,
  12411. Dword
  12412. }
  12413. };
  12414. if (dwAPIVersion > TAPI_CURRENT_VERSION)
  12415. {
  12416. return PHONEERR_INCOMPATIBLEAPIVERSION;
  12417. }
  12418. if (0 != dwCallbackInstance)
  12419. {
  12420. hCallbackInstance = NewObject (ghHandleTable, (PVOID)dwCallbackInstance, (PVOID)UIntToPtr(hPhoneApp));
  12421. if (0 == hCallbackInstance)
  12422. {
  12423. return PHONEERR_NOMEM;
  12424. }
  12425. funcArgs.Args[5] = hCallbackInstance;
  12426. }
  12427. lResult = DOFUNC (&funcArgs, "phoneOpen");
  12428. if (lResult && 0 != hCallbackInstance)
  12429. {
  12430. DereferenceObject (ghHandleTable, hCallbackInstance, 1);
  12431. }
  12432. return lResult;
  12433. }
  12434. LONG
  12435. WINAPI
  12436. phoneSetButtonInfoW(
  12437. HPHONE hPhone,
  12438. DWORD dwButtonLampID,
  12439. LPPHONEBUTTONINFO const lpButtonInfo
  12440. )
  12441. {
  12442. FUNC_ARGS funcArgs =
  12443. {
  12444. MAKELONG (PHONE_FUNC | ASYNC | 3, pSetButtonInfo),
  12445. {
  12446. (ULONG_PTR) hPhone,
  12447. (ULONG_PTR) dwButtonLampID,
  12448. (ULONG_PTR) lpButtonInfo
  12449. },
  12450. {
  12451. Dword,
  12452. Dword,
  12453. lpSet_Struct
  12454. }
  12455. };
  12456. return (DOFUNC (&funcArgs, "phoneSetButtonInfo"));
  12457. }
  12458. LONG
  12459. WINAPI
  12460. phoneSetButtonInfoA(
  12461. HPHONE hPhone,
  12462. DWORD dwButtonLampID,
  12463. LPPHONEBUTTONINFO const lpButtonInfo
  12464. )
  12465. {
  12466. LONG lResult;
  12467. LPPHONEBUTTONINFO lppbi;
  12468. if (IsBadReadPtr( lpButtonInfo, sizeof(PHONEBUTTONINFO)) ||
  12469. IsBadReadPtr( lpButtonInfo, lpButtonInfo->dwTotalSize))
  12470. {
  12471. LOG((TL_ERROR, "Bad lpButtonInfo - not at least sizeof(PHONEBUTTONINFO)"));
  12472. return PHONEERR_INVALPOINTER;
  12473. }
  12474. //
  12475. // See if there's a need to do this, first
  12476. //
  12477. if ( lpButtonInfo->dwButtonTextSize )
  12478. {
  12479. DWORD dwNewStringSize,
  12480. dwOffset = lpButtonInfo->dwButtonTextOffset,
  12481. dwSize = lpButtonInfo->dwButtonTextSize,
  12482. dwTotalSize = lpButtonInfo->dwTotalSize;
  12483. //
  12484. // Check to see if dwButtonTextSize/Offset is valid before
  12485. // conversion (check against size of 1.0 PHONEBUTTONINFO here
  12486. // (9*DWORD), tapisrv will check again for the appropriate version)
  12487. //
  12488. if ((dwOffset < (9 * sizeof (DWORD))) ||
  12489. (dwOffset >= dwTotalSize) ||
  12490. ((dwOffset + dwSize) > dwTotalSize) ||
  12491. ((dwOffset + dwSize) < dwOffset))
  12492. {
  12493. LOG((TL_ERROR, "phoneSetButtonInfo: dwButtonTextSize/Offset invalid"));
  12494. return PHONEERR_OPERATIONFAILED;
  12495. }
  12496. //
  12497. // Assume the worst for size...
  12498. //
  12499. if (!(lppbi = ClientAlloc (lpButtonInfo->dwTotalSize * sizeof(WCHAR))))
  12500. {
  12501. return PHONEERR_NOMEM;
  12502. }
  12503. CopyMemory( lppbi, lpButtonInfo, lpButtonInfo->dwTotalSize );
  12504. //
  12505. // We _KNOW_ that the old structure was as big as the dwTotalSize
  12506. // so we can put our rebuilt string starting there. Make sure
  12507. // to align new wide string on WORD boundary.
  12508. //
  12509. dwNewStringSize = sizeof(WCHAR) * MultiByteToWideChar(
  12510. GetACP(),
  12511. MB_PRECOMPOSED,
  12512. (LPBYTE)lpButtonInfo + lpButtonInfo->dwButtonTextOffset,
  12513. lpButtonInfo->dwButtonTextSize,
  12514. (PWSTR)((LPBYTE)lppbi + ((dwTotalSize + 1) & 0xfffffffe)),
  12515. lpButtonInfo->dwButtonTextSize
  12516. );
  12517. lppbi->dwTotalSize += dwNewStringSize;
  12518. lppbi->dwButtonTextSize = dwNewStringSize;
  12519. lppbi->dwButtonTextOffset = (dwTotalSize + 1) & 0xfffffffe;
  12520. }
  12521. else
  12522. {
  12523. lppbi = NULL;
  12524. }
  12525. lResult = phoneSetButtonInfoW(
  12526. hPhone,
  12527. dwButtonLampID,
  12528. lppbi ? lppbi : lpButtonInfo
  12529. );
  12530. if (lppbi)
  12531. {
  12532. ClientFree (lppbi);
  12533. }
  12534. return lResult;
  12535. }
  12536. LONG
  12537. WINAPI
  12538. phoneSetButtonInfo(
  12539. HPHONE hPhone,
  12540. DWORD dwButtonLampID,
  12541. LPPHONEBUTTONINFO const lpButtonInfo
  12542. )
  12543. {
  12544. return phoneSetButtonInfoA (hPhone, dwButtonLampID, lpButtonInfo);
  12545. }
  12546. LONG
  12547. WINAPI
  12548. phoneSetData(
  12549. HPHONE hPhone,
  12550. DWORD dwDataID,
  12551. LPVOID const lpData,
  12552. DWORD dwSize
  12553. )
  12554. {
  12555. FUNC_ARGS funcArgs =
  12556. {
  12557. MAKELONG (PHONE_FUNC | ASYNC | 4, pSetData),
  12558. {
  12559. (ULONG_PTR) hPhone,
  12560. (ULONG_PTR) dwDataID,
  12561. (ULONG_PTR) lpData,
  12562. (ULONG_PTR) dwSize
  12563. },
  12564. {
  12565. Dword,
  12566. Dword,
  12567. lpSet_SizeToFollow,
  12568. Size
  12569. }
  12570. };
  12571. return (DOFUNC (&funcArgs, "phoneSetData"));
  12572. }
  12573. LONG
  12574. WINAPI
  12575. phoneSetDisplay(
  12576. HPHONE hPhone,
  12577. DWORD dwRow,
  12578. DWORD dwColumn,
  12579. LPCSTR lpsDisplay,
  12580. DWORD dwSize
  12581. )
  12582. {
  12583. FUNC_ARGS funcArgs =
  12584. {
  12585. MAKELONG (PHONE_FUNC | ASYNC | 5, pSetDisplay),
  12586. {
  12587. (ULONG_PTR) hPhone,
  12588. (ULONG_PTR) dwRow,
  12589. (ULONG_PTR) dwColumn,
  12590. (ULONG_PTR) lpsDisplay,
  12591. (ULONG_PTR) dwSize
  12592. },
  12593. {
  12594. Dword,
  12595. Dword,
  12596. Dword,
  12597. lpSet_SizeToFollow,
  12598. Size
  12599. }
  12600. };
  12601. return (DOFUNC (&funcArgs, "phoneSetDisplay"));
  12602. }
  12603. LONG
  12604. WINAPI
  12605. phoneSetGain(
  12606. HPHONE hPhone,
  12607. DWORD dwHookSwitchDev,
  12608. DWORD dwGain
  12609. )
  12610. {
  12611. FUNC_ARGS funcArgs =
  12612. {
  12613. MAKELONG (PHONE_FUNC | ASYNC | 3, pSetGain),
  12614. {
  12615. (ULONG_PTR) hPhone,
  12616. (ULONG_PTR) dwHookSwitchDev,
  12617. (ULONG_PTR) dwGain
  12618. },
  12619. {
  12620. Dword,
  12621. Dword,
  12622. Dword
  12623. }
  12624. };
  12625. return (DOFUNC (&funcArgs, "phoneSetGain"));
  12626. }
  12627. LONG
  12628. WINAPI
  12629. phoneSetHookSwitch(
  12630. HPHONE hPhone,
  12631. DWORD dwHookSwitchDevs,
  12632. DWORD dwHookSwitchMode
  12633. )
  12634. {
  12635. FUNC_ARGS funcArgs =
  12636. {
  12637. MAKELONG (PHONE_FUNC | ASYNC | 3, pSetHookSwitch),
  12638. {
  12639. (ULONG_PTR) hPhone,
  12640. (ULONG_PTR) dwHookSwitchDevs,
  12641. (ULONG_PTR) dwHookSwitchMode
  12642. },
  12643. {
  12644. Dword,
  12645. Dword,
  12646. Dword
  12647. }
  12648. };
  12649. if (!(dwHookSwitchDevs & AllHookSwitchDevs) ||
  12650. (dwHookSwitchDevs & (~AllHookSwitchDevs)))
  12651. {
  12652. return PHONEERR_INVALHOOKSWITCHDEV;
  12653. }
  12654. if (!IsOnlyOneBitSetInDWORD (dwHookSwitchMode) ||
  12655. (dwHookSwitchMode & ~AllHookSwitchModes))
  12656. {
  12657. return PHONEERR_INVALHOOKSWITCHMODE;
  12658. }
  12659. return (DOFUNC (&funcArgs, "phoneSetHookSwitch"));
  12660. }
  12661. LONG
  12662. WINAPI
  12663. phoneSetLamp(
  12664. HPHONE hPhone,
  12665. DWORD dwButtonLampID,
  12666. DWORD dwLampMode
  12667. )
  12668. {
  12669. FUNC_ARGS funcArgs =
  12670. {
  12671. MAKELONG (PHONE_FUNC | ASYNC | 3, pSetLamp),
  12672. {
  12673. (ULONG_PTR) hPhone,
  12674. (ULONG_PTR) dwButtonLampID,
  12675. (ULONG_PTR) dwLampMode
  12676. },
  12677. {
  12678. Dword,
  12679. Dword,
  12680. Dword
  12681. }
  12682. };
  12683. return (DOFUNC (&funcArgs, "phoneSetLamp"));
  12684. }
  12685. LONG
  12686. WINAPI
  12687. phoneSetRing(
  12688. HPHONE hPhone,
  12689. DWORD dwRingMode,
  12690. DWORD dwVolume
  12691. )
  12692. {
  12693. FUNC_ARGS funcArgs =
  12694. {
  12695. MAKELONG (PHONE_FUNC | ASYNC | 3, pSetRing),
  12696. {
  12697. (ULONG_PTR) hPhone,
  12698. (ULONG_PTR) dwRingMode,
  12699. (ULONG_PTR) dwVolume
  12700. },
  12701. {
  12702. Dword,
  12703. Dword,
  12704. Dword
  12705. }
  12706. };
  12707. return (DOFUNC (&funcArgs, "phoneSetRing"));
  12708. }
  12709. LONG
  12710. WINAPI
  12711. phoneSetStatusMessages(
  12712. HPHONE hPhone,
  12713. DWORD dwPhoneStates,
  12714. DWORD dwButtonModes,
  12715. DWORD dwButtonStates
  12716. )
  12717. {
  12718. FUNC_ARGS funcArgs =
  12719. {
  12720. MAKELONG (PHONE_FUNC | SYNC | 4, pSetStatusMessages),
  12721. {
  12722. (ULONG_PTR) hPhone,
  12723. (ULONG_PTR) dwPhoneStates,
  12724. (ULONG_PTR) dwButtonModes,
  12725. (ULONG_PTR) dwButtonStates
  12726. },
  12727. {
  12728. Dword,
  12729. Dword,
  12730. Dword,
  12731. Dword
  12732. }
  12733. };
  12734. return (DOFUNC (&funcArgs, "phoneSetStatusMessages"));
  12735. }
  12736. LONG
  12737. WINAPI
  12738. phoneSetVolume(
  12739. HPHONE hPhone,
  12740. DWORD dwHookSwitchDev,
  12741. DWORD dwVolume
  12742. )
  12743. {
  12744. FUNC_ARGS funcArgs =
  12745. {
  12746. MAKELONG (PHONE_FUNC | ASYNC | 3, pSetVolume),
  12747. {
  12748. (ULONG_PTR) hPhone,
  12749. (ULONG_PTR) dwHookSwitchDev,
  12750. (ULONG_PTR) dwVolume
  12751. },
  12752. {
  12753. Dword,
  12754. Dword,
  12755. Dword
  12756. }
  12757. };
  12758. return (DOFUNC (&funcArgs, "phoneSetVolume"));
  12759. }
  12760. LONG
  12761. WINAPI
  12762. phoneShutdown(
  12763. HPHONEAPP hPhoneApp
  12764. )
  12765. {
  12766. return (xxxShutdown ((HLINEAPP) hPhoneApp, FALSE));
  12767. }
  12768. //
  12769. // ------------------------------- tapiXxx ------------------------------------
  12770. //
  12771. LONG
  12772. WINAPI
  12773. tapiRequestDrop(
  12774. HWND hWnd,
  12775. WPARAM wRequestID
  12776. )
  12777. {
  12778. FUNC_ARGS funcArgs =
  12779. {
  12780. MAKELONG (TAPI_FUNC | SYNC | 2, tRequestDrop),
  12781. {
  12782. (ULONG_PTR) hWnd,
  12783. (ULONG_PTR) wRequestID
  12784. },
  12785. {
  12786. Hwnd,
  12787. Dword
  12788. }
  12789. };
  12790. return (DOFUNC (&funcArgs, "tapiRequestDrop"));
  12791. }
  12792. LONG
  12793. WINAPI
  12794. tapiRequestMakeCallW(
  12795. LPCWSTR lpszDestAddress,
  12796. LPCWSTR lpszAppName,
  12797. LPCWSTR lpszCalledParty,
  12798. LPCWSTR lpszComment
  12799. )
  12800. {
  12801. LONG lResult;
  12802. DWORD hRequestMakeCallAttempted, dwProxyListSize = 512;
  12803. LPVARSTRING pProxyList;
  12804. FUNC_ARGS funcArgs =
  12805. {
  12806. MAKELONG (TAPI_FUNC | SYNC | 7, tRequestMakeCall),
  12807. {
  12808. (ULONG_PTR) lpszDestAddress,
  12809. (ULONG_PTR) lpszAppName,
  12810. (ULONG_PTR) lpszCalledParty,
  12811. (ULONG_PTR) lpszComment,
  12812. (ULONG_PTR) 0,
  12813. (ULONG_PTR) 0,
  12814. (ULONG_PTR) &hRequestMakeCallAttempted
  12815. },
  12816. {
  12817. lpszW,
  12818. lpszW,
  12819. lpszW,
  12820. lpszW,
  12821. lpGet_Struct,
  12822. Dword,
  12823. lpDword
  12824. }
  12825. };
  12826. if (TAPIIsBadStringPtrW (lpszDestAddress, (DWORD) -1) ||
  12827. (lstrlenW (lpszDestAddress) + 1) > TAPIMAXDESTADDRESSSIZE)
  12828. {
  12829. return TAPIERR_INVALDESTADDRESS;
  12830. }
  12831. if (!lpszAppName)
  12832. {
  12833. //
  12834. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  12835. //
  12836. funcArgs.ArgTypes[1] = Dword;
  12837. funcArgs.Args[1] = (ULONG_PTR) TAPI_NO_DATA;
  12838. }
  12839. if (!lpszCalledParty)
  12840. {
  12841. //
  12842. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  12843. //
  12844. funcArgs.ArgTypes[2] = Dword;
  12845. funcArgs.Args[2] = (ULONG_PTR) TAPI_NO_DATA;
  12846. }
  12847. if (!lpszComment)
  12848. {
  12849. //
  12850. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  12851. //
  12852. funcArgs.ArgTypes[3] = Dword;
  12853. funcArgs.Args[3] = (ULONG_PTR) TAPI_NO_DATA;
  12854. }
  12855. //
  12856. //
  12857. //
  12858. if (!(pProxyList = ClientAlloc (dwProxyListSize)))
  12859. {
  12860. return TAPIERR_NOREQUESTRECIPIENT;
  12861. }
  12862. pProxyList->dwTotalSize = dwProxyListSize;
  12863. funcArgs.Args[4] = (ULONG_PTR) pProxyList;
  12864. if ((lResult = DOFUNC (&funcArgs, "tapiRequestMakeCall")) == 0)
  12865. {
  12866. //
  12867. //
  12868. //
  12869. if (hRequestMakeCallAttempted != 0)
  12870. {
  12871. WCHAR *pszProxyName, *pszNextProxyName;
  12872. BOOL bLastAppInList = FALSE, bStartedProxy = FALSE;
  12873. pszProxyName =
  12874. pszNextProxyName =
  12875. (WCHAR *)(((LPBYTE) pProxyList) + pProxyList->dwStringOffset);
  12876. while (!bLastAppInList)
  12877. {
  12878. while (1)
  12879. {
  12880. if (*pszNextProxyName == 0)
  12881. {
  12882. bLastAppInList = TRUE;
  12883. break;
  12884. }
  12885. else if (*pszNextProxyName == L'"')
  12886. {
  12887. *pszNextProxyName = 0;
  12888. pszNextProxyName++;
  12889. break;
  12890. }
  12891. pszNextProxyName++;
  12892. }
  12893. //
  12894. // Fake layer to get a local struct
  12895. //
  12896. {
  12897. FARPROC pShellExecuteEx = NULL;
  12898. HINSTANCE hInst;
  12899. LPTSTR pszBuffer;
  12900. DWORD dwSize = lstrlenW(pszProxyName)+1;
  12901. SHELLEXECUTEINFO sei =
  12902. {
  12903. sizeof(SHELLEXECUTEINFO),
  12904. 0,
  12905. 0, // hWnd
  12906. NULL, //"Open"
  12907. NULL, // lpFile
  12908. NULL,
  12909. NULL, //Directory
  12910. SW_MINIMIZE,
  12911. NULL //hProcess - huh?
  12912. };
  12913. pszBuffer = (LPTSTR)ClientAlloc(dwSize*sizeof(TCHAR));
  12914. SHUnicodeToTChar(pszProxyName, pszBuffer, dwSize );
  12915. sei.lpFile = pszBuffer;
  12916. hInst = LoadLibrary( TEXT("shell32.dll") );
  12917. if (NULL != hInst)
  12918. {
  12919. pShellExecuteEx = GetProcAddress(
  12920. hInst,
  12921. #ifdef UNICODE
  12922. "ShellExecuteExW"
  12923. #else
  12924. "ShellExecuteEx"
  12925. #endif
  12926. );
  12927. if (pShellExecuteEx && pShellExecuteEx(&sei) == TRUE)
  12928. {
  12929. bStartedProxy = TRUE;
  12930. ClientFree(pszBuffer);
  12931. break;
  12932. }
  12933. else
  12934. #if DBG
  12935. {
  12936. LOG((TL_ERROR,
  12937. "tapiRequestMakeCall: ShellExecuteExW(%ls) error - x%x",
  12938. pszProxyName,
  12939. GetLastError()
  12940. ));
  12941. }
  12942. #else
  12943. LOG((TL_ERROR,
  12944. "tapiRequestMakeCall: ShellExecuteExW error - x%x",
  12945. GetLastError()
  12946. ));
  12947. #endif
  12948. ClientFree(pszBuffer);
  12949. FreeLibrary( hInst );
  12950. }
  12951. else
  12952. {
  12953. LOG((TL_ERROR,
  12954. "tapiRequestMakeCall: LoadLibrary(shell32.dll) failed - x%x",
  12955. GetLastError()
  12956. ));
  12957. }
  12958. }
  12959. pszProxyName = pszNextProxyName;
  12960. }
  12961. if (bStartedProxy == FALSE)
  12962. {
  12963. //
  12964. // Alert tapisrv that it needs to free the ReqMakeCall inst
  12965. //
  12966. FUNC_ARGS funcArgs =
  12967. {
  12968. MAKELONG (TAPI_FUNC | SYNC | 7, tRequestMakeCall),
  12969. {
  12970. (ULONG_PTR) 0,
  12971. (ULONG_PTR) 0,
  12972. (ULONG_PTR) 0,
  12973. (ULONG_PTR) 0,
  12974. (ULONG_PTR) 0,
  12975. (ULONG_PTR) hRequestMakeCallAttempted,
  12976. (ULONG_PTR) 0
  12977. },
  12978. {
  12979. Dword,
  12980. Dword,
  12981. Dword,
  12982. Dword,
  12983. Dword,
  12984. Dword,
  12985. Dword,
  12986. }
  12987. };
  12988. LOG((TL_ERROR,
  12989. "tapiRequestMakeCall: failed to start proxy, deleting request"
  12990. ));
  12991. lResult = DOFUNC (&funcArgs, "tapiRequestMakeCall_cleanup");
  12992. }
  12993. }
  12994. }
  12995. ClientFree (pProxyList);
  12996. return lResult;
  12997. }
  12998. LONG
  12999. WINAPI
  13000. tapiRequestMakeCallA(
  13001. LPCSTR lpszDestAddress,
  13002. LPCSTR lpszAppName,
  13003. LPCSTR lpszCalledParty,
  13004. LPCSTR lpszComment
  13005. )
  13006. {
  13007. LONG lResult;
  13008. PWSTR szTempPtr1;
  13009. PWSTR szTempPtr2;
  13010. PWSTR szTempPtr3;
  13011. PWSTR szTempPtr4;
  13012. if (IsBadStringPtrA (lpszDestAddress, (DWORD) -1) ||
  13013. (lstrlenA (lpszDestAddress) + 1) > TAPIMAXDESTADDRESSSIZE)
  13014. {
  13015. return TAPIERR_INVALDESTADDRESS;
  13016. }
  13017. if ((lpszAppName && IsBadStringPtrA (lpszAppName, (DWORD) -1)) ||
  13018. (lpszCalledParty && IsBadStringPtrA (lpszCalledParty, (DWORD) -1)) ||
  13019. (lpszComment && IsBadStringPtrA (lpszComment, (DWORD) -1)))
  13020. {
  13021. return TAPIERR_INVALPOINTER;
  13022. }
  13023. szTempPtr1= NotSoWideStringToWideString (lpszDestAddress, (DWORD) -1);
  13024. if ( !szTempPtr1 )
  13025. {
  13026. return TAPIERR_INVALPOINTER;
  13027. }
  13028. szTempPtr2= NotSoWideStringToWideString (lpszAppName, (DWORD) -1);
  13029. szTempPtr3= NotSoWideStringToWideString (lpszCalledParty, (DWORD) -1);
  13030. szTempPtr4= NotSoWideStringToWideString (lpszComment, (DWORD) -1);
  13031. lResult = tapiRequestMakeCallW(
  13032. szTempPtr1,
  13033. szTempPtr2,
  13034. szTempPtr3,
  13035. szTempPtr4
  13036. );
  13037. ClientFree (szTempPtr1);
  13038. if (szTempPtr2)
  13039. {
  13040. ClientFree (szTempPtr2);
  13041. }
  13042. if (szTempPtr3)
  13043. {
  13044. ClientFree (szTempPtr3);
  13045. }
  13046. if (szTempPtr4)
  13047. {
  13048. ClientFree (szTempPtr4);
  13049. }
  13050. return lResult;
  13051. }
  13052. LONG
  13053. WINAPI
  13054. tapiRequestMakeCall(
  13055. LPCSTR lpszDestAddress,
  13056. LPCSTR lpszAppName,
  13057. LPCSTR lpszCalledParty,
  13058. LPCSTR lpszComment
  13059. )
  13060. {
  13061. return tapiRequestMakeCallA(
  13062. lpszDestAddress,
  13063. lpszAppName,
  13064. lpszCalledParty,
  13065. lpszComment
  13066. );
  13067. }
  13068. LONG
  13069. WINAPI
  13070. tapiRequestMediaCallW(
  13071. HWND hWnd,
  13072. WPARAM wRequestID,
  13073. LPCWSTR lpszDeviceClass,
  13074. LPCWSTR lpDeviceID,
  13075. DWORD dwSize,
  13076. DWORD dwSecure,
  13077. LPCWSTR lpszDestAddress,
  13078. LPCWSTR lpszAppName,
  13079. LPCWSTR lpszCalledParty,
  13080. LPCWSTR lpszComment
  13081. )
  13082. {
  13083. FUNC_ARGS funcArgs =
  13084. {
  13085. MAKELONG (TAPI_FUNC | SYNC | 10, tRequestMediaCall),
  13086. {
  13087. (ULONG_PTR) hWnd,
  13088. (ULONG_PTR) wRequestID,
  13089. (ULONG_PTR) lpszDeviceClass,
  13090. (ULONG_PTR) lpDeviceID,
  13091. (ULONG_PTR) dwSize,
  13092. (ULONG_PTR) dwSecure,
  13093. (ULONG_PTR) lpszDestAddress,
  13094. (ULONG_PTR) lpszAppName,
  13095. (ULONG_PTR) lpszCalledParty,
  13096. (ULONG_PTR) lpszComment,
  13097. },
  13098. {
  13099. Hwnd,
  13100. Dword,
  13101. lpszW,
  13102. lpGet_SizeToFollow,
  13103. Size,
  13104. Dword,
  13105. lpszW,
  13106. lpszW,
  13107. lpszW,
  13108. lpszW
  13109. }
  13110. };
  13111. if (TAPIIsBadStringPtrW (lpszDeviceClass, (UINT) -1) ||
  13112. (lstrlenW (lpszDeviceClass) + 1) > TAPIMAXDEVICECLASSSIZE)
  13113. {
  13114. return TAPIERR_INVALDEVICECLASS;
  13115. }
  13116. if (IsBadWritePtr ((LPVOID) lpDeviceID, dwSize) ||
  13117. dwSize > (TAPIMAXDEVICEIDSIZE * sizeof (WCHAR)))
  13118. {
  13119. return TAPIERR_INVALDEVICEID;
  13120. }
  13121. if (TAPIIsBadStringPtrW (lpszDestAddress, (UINT) -1) ||
  13122. (lstrlenW (lpszDestAddress) + 1) > TAPIMAXDESTADDRESSSIZE)
  13123. {
  13124. return TAPIERR_INVALDESTADDRESS;
  13125. }
  13126. if (!lpszAppName)
  13127. {
  13128. //
  13129. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  13130. //
  13131. funcArgs.ArgTypes[7] = Dword;
  13132. funcArgs.Args[7] = (ULONG_PTR) TAPI_NO_DATA;
  13133. }
  13134. if (!lpszCalledParty)
  13135. {
  13136. //
  13137. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  13138. //
  13139. funcArgs.ArgTypes[8] = Dword;
  13140. funcArgs.Args[8] = (ULONG_PTR) TAPI_NO_DATA;
  13141. }
  13142. if (!lpszComment)
  13143. {
  13144. //
  13145. // Reset Arg & ArgType so no inval ptr err, & TAPI_NO_DATA is indicated
  13146. //
  13147. funcArgs.ArgTypes[9] = Dword;
  13148. funcArgs.Args[9] = (ULONG_PTR) TAPI_NO_DATA;
  13149. }
  13150. return (DOFUNC (&funcArgs, "tapiRequestMediaCall"));
  13151. }
  13152. LONG
  13153. WINAPI
  13154. tapiRequestMediaCallA(
  13155. HWND hWnd,
  13156. WPARAM wRequestID,
  13157. LPCSTR lpszDeviceClass,
  13158. LPCSTR lpDeviceID,
  13159. DWORD dwSize,
  13160. DWORD dwSecure,
  13161. LPCSTR lpszDestAddress,
  13162. LPCSTR lpszAppName,
  13163. LPCSTR lpszCalledParty,
  13164. LPCSTR lpszComment
  13165. )
  13166. {
  13167. LONG lResult;
  13168. PWSTR szTempPtr1 = NULL, szTempPtr2 = NULL, szTempPtr3 = NULL,
  13169. szTempPtr4 = NULL, szTempPtr5 = NULL, szTempPtr6 = NULL;
  13170. if (IsBadStringPtrA (lpszDeviceClass, (UINT) -1) ||
  13171. (lstrlenA (lpszDeviceClass) + 1) > TAPIMAXDEVICECLASSSIZE)
  13172. {
  13173. lResult = TAPIERR_INVALDEVICECLASS;
  13174. goto ExitHere;
  13175. }
  13176. else
  13177. {
  13178. szTempPtr1 = NotSoWideStringToWideString(
  13179. lpszDeviceClass,
  13180. (DWORD) -1
  13181. );
  13182. }
  13183. if (IsBadWritePtr ((LPVOID) lpDeviceID, dwSize) ||
  13184. dwSize > TAPIMAXDEVICEIDSIZE)
  13185. {
  13186. lResult = TAPIERR_INVALDEVICEID;
  13187. goto ExitHere;
  13188. }
  13189. else
  13190. {
  13191. dwSize *= 2;
  13192. szTempPtr2 = ClientAlloc (dwSize);
  13193. }
  13194. if (IsBadStringPtrA (lpszDestAddress, (UINT) -1) ||
  13195. (lstrlenA (lpszDestAddress) + 1) > TAPIMAXDESTADDRESSSIZE)
  13196. {
  13197. lResult = TAPIERR_INVALDESTADDRESS;
  13198. goto ExitHere;
  13199. }
  13200. else
  13201. {
  13202. szTempPtr3 = NotSoWideStringToWideString(
  13203. lpszDestAddress,
  13204. (DWORD) -1
  13205. );
  13206. }
  13207. if ((lpszAppName && IsBadStringPtrA (lpszAppName, (UINT) -1)) ||
  13208. (lpszCalledParty && IsBadStringPtrA (lpszCalledParty, (UINT) -1)) ||
  13209. (lpszComment && IsBadStringPtrA (lpszComment, (UINT) -1)))
  13210. {
  13211. lResult = TAPIERR_INVALPOINTER;
  13212. goto ExitHere;
  13213. }
  13214. szTempPtr4 = NotSoWideStringToWideString (lpszAppName, (DWORD) -1);
  13215. szTempPtr5 = NotSoWideStringToWideString (lpszCalledParty, (DWORD) -1);
  13216. szTempPtr6 = NotSoWideStringToWideString (lpszComment, (DWORD) -1);
  13217. lResult = tapiRequestMediaCallW(
  13218. hWnd,
  13219. wRequestID,
  13220. szTempPtr1,
  13221. szTempPtr2,
  13222. dwSize,
  13223. dwSecure,
  13224. szTempPtr3,
  13225. szTempPtr4,
  13226. szTempPtr5,
  13227. szTempPtr6
  13228. );
  13229. ExitHere:
  13230. if (szTempPtr1)
  13231. {
  13232. ClientFree (szTempPtr1);
  13233. }
  13234. if (szTempPtr2)
  13235. {
  13236. ClientFree (szTempPtr2);
  13237. }
  13238. if (szTempPtr3)
  13239. {
  13240. ClientFree (szTempPtr3);
  13241. }
  13242. if (szTempPtr4)
  13243. {
  13244. ClientFree (szTempPtr4);
  13245. }
  13246. if (szTempPtr5)
  13247. {
  13248. ClientFree (szTempPtr5);
  13249. }
  13250. if (szTempPtr6)
  13251. {
  13252. ClientFree (szTempPtr6);
  13253. }
  13254. return lResult;
  13255. }
  13256. LONG
  13257. WINAPI
  13258. tapiRequestMediaCall(
  13259. HWND hWnd,
  13260. WPARAM wRequestID,
  13261. LPCSTR lpszDeviceClass,
  13262. LPCSTR lpDeviceID,
  13263. DWORD dwSize,
  13264. DWORD dwSecure,
  13265. LPCSTR lpszDestAddress,
  13266. LPCSTR lpszAppName,
  13267. LPCSTR lpszCalledParty,
  13268. LPCSTR lpszComment
  13269. )
  13270. {
  13271. return tapiRequestMediaCallA(
  13272. hWnd,
  13273. wRequestID,
  13274. lpszDeviceClass,
  13275. lpDeviceID,
  13276. dwSize,
  13277. dwSecure,
  13278. lpszDestAddress,
  13279. lpszAppName,
  13280. lpszCalledParty,
  13281. lpszComment
  13282. );
  13283. }
  13284. //
  13285. // ----------------------------------------------------------------------------
  13286. //
  13287. LONG
  13288. WINAPI
  13289. GetTapi16CallbackMsg(
  13290. PINIT_DATA pInitData,
  13291. LPDWORD pMsg
  13292. )
  13293. {
  13294. LONG lResult = 0;
  13295. LOG((TL_TRACE, "GetTapi16CallbackMsg: enter"));
  13296. EnterCriticalSection (&gCriticalSection);
  13297. try
  13298. {
  13299. if (pInitData->dwKey != INITDATA_KEY)
  13300. {
  13301. goto GetTapi16CallbackMsg_leaveCritSec;
  13302. }
  13303. }
  13304. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  13305. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  13306. {
  13307. goto GetTapi16CallbackMsg_leaveCritSec;
  13308. }
  13309. if (pInitData->dwNumUsedEntries > 0)
  13310. {
  13311. CopyMemory(
  13312. pMsg,
  13313. pInitData->pValidEntry,
  13314. sizeof(ASYNC_EVENT_PARAMS)
  13315. );
  13316. pInitData->pValidEntry++;
  13317. if (pInitData->pValidEntry >= (pInitData->pEventBuffer +
  13318. pInitData->dwNumTotalEntries))
  13319. {
  13320. pInitData->pValidEntry = pInitData->pEventBuffer;
  13321. }
  13322. pInitData->dwNumUsedEntries--;
  13323. if (pInitData->dwNumUsedEntries == 0)
  13324. {
  13325. pInitData->bPendingAsyncEventMsg = FALSE;
  13326. }
  13327. lResult = 1;
  13328. }
  13329. GetTapi16CallbackMsg_leaveCritSec:
  13330. LeaveCriticalSection (&gCriticalSection);
  13331. LOG((TL_TRACE, "GetTapi16CallbackMsg: exit (result=x%x)", lResult));
  13332. return lResult;
  13333. }
  13334. //
  13335. // ----------------------- Private support routines ---------------------------
  13336. //
  13337. void
  13338. FreeInitData(
  13339. PINIT_DATA pInitData
  13340. )
  13341. {
  13342. EnterCriticalSection (&gCriticalSection);
  13343. if (pInitData && ( pInitData->dwKey != 0xefefefef ) )
  13344. {
  13345. pInitData->dwKey = 0xefefefef;
  13346. LeaveCriticalSection (&gCriticalSection);
  13347. if ((pInitData->dwInitOptions & 0x3) ==
  13348. LINEINITIALIZEEXOPTION_USEEVENT)
  13349. {
  13350. if (pInitData->hEvent)
  13351. {
  13352. //
  13353. // Signal the event to release any threads which might
  13354. // be waiting on it, then close the handle
  13355. //
  13356. SetEvent (pInitData->hEvent);
  13357. CloseHandle (pInitData->hEvent);
  13358. }
  13359. }
  13360. else if ((pInitData->dwInitOptions & 0x3) ==
  13361. LINEINITIALIZEEXOPTION_USEHIDDENWINDOW)
  13362. {
  13363. // NOTE: let thunk destroy it's own window
  13364. if (pInitData->hwnd && !gbNTVDMClient)
  13365. {
  13366. //
  13367. // If this is the thread which created the window
  13368. // then we can destroy the window in line. Otherwise,
  13369. // post a message telling the window to destroy itself.
  13370. //
  13371. if (pInitData->dwThreadID == GetCurrentThreadId())
  13372. {
  13373. DestroyWindow (pInitData->hwnd);
  13374. }
  13375. else
  13376. {
  13377. PostMessage(
  13378. pInitData->hwnd,
  13379. WM_ASYNCEVENT,
  13380. (WPARAM) gdwInitialTickCount,
  13381. (LPARAM) 0xffffffff
  13382. );
  13383. }
  13384. }
  13385. }
  13386. if (pInitData->pEventBuffer)
  13387. {
  13388. ClientFree (pInitData->pEventBuffer);
  13389. }
  13390. DereferenceObject (ghHandleTable, pInitData->hInitData, 1);
  13391. ClientFree (pInitData);
  13392. }
  13393. else
  13394. {
  13395. LeaveCriticalSection (&gCriticalSection);
  13396. }
  13397. }
  13398. INT_PTR
  13399. CALLBACK
  13400. TAPIWndProc(
  13401. HWND hwnd,
  13402. UINT msg,
  13403. WPARAM wParam,
  13404. LPARAM lParam
  13405. )
  13406. {
  13407. switch (msg)
  13408. {
  13409. case WM_ASYNCEVENT:
  13410. {
  13411. BOOL bFirstPass = TRUE, bPostMsg;
  13412. PINIT_DATA pInitData = (PINIT_DATA) lParam;
  13413. LOG((TL_TRACE, "TAPIWndProc: received WM_ASYNCEVENT, hwnd=x%p", hwnd));
  13414. if (lParam == (LPARAM) 0xffffffff)
  13415. {
  13416. if (wParam == (WPARAM) gdwInitialTickCount)
  13417. {
  13418. DestroyWindow (hwnd);
  13419. }
  13420. return FALSE;
  13421. }
  13422. while (1)
  13423. {
  13424. //
  13425. // Enter the critical section, verify the pInitData, and
  13426. // see if there are any events in in the queue to process.
  13427. // If so, remove an event from the queue, adjust the
  13428. // ptrs & count, leave the critical section, and call
  13429. // the callback.
  13430. //
  13431. // Note that there is some tricky stuff below to insure
  13432. // that there is always another outstanding WM_ASYNCEVENT
  13433. // msg prior to calling the app's callback (if there are)
  13434. // any more events inthe queue. This is necessary because
  13435. // some ill-behaved apps have msg loops (to synchronously
  13436. // wait for async request results, etc) within their
  13437. // callbacks, and we don't want to block sending any msgs
  13438. // to them.
  13439. //
  13440. EnterCriticalSection (&gCriticalSection);
  13441. try
  13442. {
  13443. if (pInitData->dwKey != INITDATA_KEY)
  13444. {
  13445. LOG((TL_ERROR, "TAPIWndProc: bad pInitInst (x%p)", pInitData));
  13446. LeaveCriticalSection (&gCriticalSection);
  13447. break;
  13448. }
  13449. }
  13450. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  13451. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  13452. {
  13453. LOG((TL_ERROR, "TAPIWndProc: bad pInitInst (x%p)", pInitData));
  13454. LeaveCriticalSection (&gCriticalSection);
  13455. break;
  13456. }
  13457. if (bFirstPass)
  13458. {
  13459. pInitData->bPendingAsyncEventMsg = FALSE;
  13460. bFirstPass = FALSE;
  13461. }
  13462. if (pInitData->dwNumUsedEntries != 0)
  13463. {
  13464. ASYNC_EVENT_PARAMS event;
  13465. LINECALLBACK lpfnCallback;
  13466. CopyMemory(
  13467. &event,
  13468. pInitData->pValidEntry,
  13469. sizeof (ASYNC_EVENT_PARAMS)
  13470. );
  13471. pInitData->pValidEntry++;
  13472. if (pInitData->pValidEntry >= (pInitData->pEventBuffer +
  13473. pInitData->dwNumTotalEntries))
  13474. {
  13475. pInitData->pValidEntry = pInitData->pEventBuffer;
  13476. }
  13477. pInitData->dwNumUsedEntries--;
  13478. if (pInitData->dwNumUsedEntries != 0 &&
  13479. pInitData->bPendingAsyncEventMsg == FALSE)
  13480. {
  13481. bPostMsg = TRUE;
  13482. pInitData->bPendingAsyncEventMsg = TRUE;
  13483. }
  13484. lpfnCallback = pInitData->lpfnCallback;
  13485. LeaveCriticalSection (&gCriticalSection);
  13486. LOG((TL_INFO,
  13487. "Calling app's callback, hDev=x%x, "\
  13488. "Msg=%d, dwInst=x%lx P1=x%lx, P2=x%x P3=x%lx",
  13489. event.hDevice,
  13490. event.dwMsg,
  13491. event.dwCallbackInstance,
  13492. event.dwParam1,
  13493. event.dwParam2,
  13494. event.dwParam3
  13495. ));
  13496. if (bPostMsg)
  13497. {
  13498. PostMessage (hwnd, WM_ASYNCEVENT, wParam, lParam);
  13499. }
  13500. (*lpfnCallback)(
  13501. event.hDevice,
  13502. event.dwMsg,
  13503. event.dwCallbackInstance,
  13504. event.dwParam1,
  13505. event.dwParam2,
  13506. event.dwParam3
  13507. );
  13508. }
  13509. else
  13510. {
  13511. LOG((TL_TRACE, "No entries - spurious entry."));
  13512. LeaveCriticalSection (&gCriticalSection);
  13513. break;
  13514. }
  13515. }
  13516. return FALSE;
  13517. }
  13518. default:
  13519. break;
  13520. }
  13521. return (DefWindowProc (hwnd, msg, wParam, lParam));
  13522. }
  13523. LONG
  13524. CreateHiddenWindow(
  13525. HWND *lphwnd,
  13526. DWORD dwErrorClass
  13527. )
  13528. {
  13529. LONG lResult = 0;
  13530. //
  13531. // Register the hidden window class
  13532. //
  13533. if (!gbHiddenWndClassRegistered)
  13534. {
  13535. DWORD dwError;
  13536. WNDCLASS wndclass;
  13537. ZeroMemory(&wndclass, sizeof(WNDCLASS));
  13538. wndclass.lpfnWndProc = (WNDPROC) TAPIWndProc;
  13539. wndclass.hInstance = g_hInst;
  13540. wndclass.lpszClassName = szTapi32WndClass;
  13541. if (!RegisterClass (&wndclass) &&
  13542. ((dwError = GetLastError()) != ERROR_CLASS_ALREADY_EXISTS))
  13543. {
  13544. LOG((TL_ERROR,
  13545. "CreateHiddenWindow: RegisterClass failed, err=%d",
  13546. dwError
  13547. ));
  13548. }
  13549. else
  13550. {
  13551. gbHiddenWndClassRegistered = TRUE;
  13552. }
  13553. }
  13554. if (!(*lphwnd = CreateWindow(
  13555. szTapi32WndClass, // class name
  13556. NULL, // title
  13557. WS_OVERLAPPED | WS_MINIMIZE, // 0, // dwStyle
  13558. 0, // x
  13559. 0, // y
  13560. 0, // width
  13561. 0, // height
  13562. (HWND) NULL, // parent wnd
  13563. (HMENU) NULL, // menu
  13564. g_hInst, // instance
  13565. NULL // params
  13566. )))
  13567. {
  13568. LOG((TL_ERROR, "CreateWindow failed, err=%ld", GetLastError()));
  13569. lResult = gaOpFailedErrors[dwErrorClass];
  13570. }
  13571. return lResult;
  13572. }
  13573. void __RPC_FAR * __RPC_API midl_user_allocate(size_t len)
  13574. {
  13575. LOG((TL_TRACE, "midl_user_allocate: enter, size=x%x", len));
  13576. return (ClientAlloc (len));
  13577. }
  13578. void __RPC_API midl_user_free(void __RPC_FAR * ptr)
  13579. {
  13580. LOG((TL_TRACE, "midl_user_free: enter, p=x%p", ptr));
  13581. ClientFree (ptr);
  13582. }
  13583. LONG
  13584. WINAPI
  13585. ReAllocClientResources(
  13586. DWORD dwErrorClass
  13587. )
  13588. {
  13589. LONG lResult;
  13590. DWORD dwRefCountTemp;
  13591. LOG((TL_TRACE, "AllocClientResources: enter"));
  13592. WaitForSingleObject (ghInitMutex, INFINITE);
  13593. if (0 == gdwRpcRefCount)
  13594. {
  13595. ReleaseMutex (ghInitMutex);
  13596. return TAPIERR_REQUESTFAILED;
  13597. }
  13598. dwRefCountTemp = gdwRpcRefCount;
  13599. gdwRpcRefCount = 1;
  13600. FreeClientResources ();
  13601. lResult = AllocClientResources(dwErrorClass);
  13602. if (TAPI_SUCCESS == lResult)
  13603. {
  13604. gdwRpcRefCount = dwRefCountTemp;
  13605. }
  13606. else
  13607. {
  13608. gdwRpcRefCount = 0;
  13609. }
  13610. ReleaseMutex (ghInitMutex);
  13611. return lResult;
  13612. }
  13613. LONG
  13614. WINAPI
  13615. AllocClientResources(
  13616. DWORD dwErrorClass
  13617. )
  13618. {
  13619. DWORD dwExceptionCount = 0;
  13620. DWORD dwError = 0;
  13621. LONG lResult = gaOpFailedErrors[dwErrorClass];
  13622. SC_HANDLE hSCMgr = NULL, hTapiSrv = NULL;
  13623. LOG((TL_TRACE, "AllocClientResources: enter"));
  13624. //
  13625. // If we're in safeboot mode, tapisrv won't start;
  13626. // fail initialization.
  13627. //
  13628. if (0 != GetSystemMetrics (SM_CLEANBOOT))
  13629. {
  13630. lResult = gaOpFailedErrors[dwErrorClass];
  13631. goto AllocClientResources_return;
  13632. }
  13633. //
  13634. // Serialize the following init code
  13635. //
  13636. WaitForSingleObject (ghInitMutex, INFINITE);
  13637. if (0 != gdwRpcRefCount)
  13638. {
  13639. gdwRpcRefCount++;
  13640. lResult = TAPI_SUCCESS;
  13641. goto AllocClientResources_return;
  13642. }
  13643. //
  13644. // Start the TAPISRV.EXE service
  13645. //
  13646. if ((hSCMgr = OpenSCManager(
  13647. NULL, // local machine
  13648. NULL, // ServicesActive database
  13649. SC_MANAGER_CONNECT // desired access
  13650. )) == NULL)
  13651. {
  13652. dwError = GetLastError();
  13653. LOG((TL_ERROR, "OpenSCManager failed, err=%d", dwError ));
  13654. if ( ERROR_ACCESS_DENIED == dwError ||
  13655. ERROR_NOACCESS == dwError
  13656. )
  13657. {
  13658. // if OpenSCManager fails with ACCESS_DENIED,
  13659. // we still need to try to attach to TAPISRV
  13660. goto AllocClientResources_attachToServer;
  13661. }
  13662. else
  13663. {
  13664. goto AllocClientResources_return;
  13665. }
  13666. }
  13667. if ((hTapiSrv = OpenService(
  13668. hSCMgr, // SC mgr handle
  13669. TEXT("TAPISRV"), // name of service to open
  13670. SERVICE_START | // desired access
  13671. SERVICE_QUERY_STATUS
  13672. )) == NULL)
  13673. {
  13674. dwError = GetLastError();
  13675. LOG((TL_ERROR, "OpenService failed, err=%d", dwError));
  13676. if ( ERROR_ACCESS_DENIED == dwError ||
  13677. ERROR_NOACCESS == dwError
  13678. )
  13679. {
  13680. // if OpenService fails with ACCESS_DENIED,
  13681. // we still need to try to attach to TAPISRV
  13682. goto AllocClientResources_attachToServer;
  13683. }
  13684. else
  13685. {
  13686. goto AllocClientResources_cleanup1;
  13687. }
  13688. }
  13689. AllocClientResources_queryServiceStatus:
  13690. {
  13691. #define MAX_NUM_SECONDS_TO_WAIT_FOR_TAPISRV 180
  13692. DWORD dwNumSecondsSleptStartPending = 0,
  13693. dwNumSecondsSleptStopPending = 0;
  13694. while (1)
  13695. {
  13696. SERVICE_STATUS status;
  13697. QueryServiceStatus (hTapiSrv, &status);
  13698. switch (status.dwCurrentState)
  13699. {
  13700. case SERVICE_RUNNING:
  13701. LOG((TL_INFO, "Tapisrv running"));
  13702. goto AllocClientResources_attachToServer;
  13703. case SERVICE_START_PENDING:
  13704. Sleep (1000);
  13705. if (++dwNumSecondsSleptStartPending >
  13706. MAX_NUM_SECONDS_TO_WAIT_FOR_TAPISRV)
  13707. {
  13708. LOG((TL_ERROR,
  13709. "ERROR: Tapisrv stuck SERVICE_START_PENDING"
  13710. ));
  13711. goto AllocClientResources_cleanup2;
  13712. }
  13713. break;
  13714. case SERVICE_STOP_PENDING:
  13715. Sleep (1000);
  13716. if (++dwNumSecondsSleptStopPending >
  13717. MAX_NUM_SECONDS_TO_WAIT_FOR_TAPISRV)
  13718. {
  13719. LOG((TL_ERROR,
  13720. "ERROR: Tapisrv stuck SERVICE_STOP_PENDING"
  13721. ));
  13722. goto AllocClientResources_cleanup2;
  13723. }
  13724. break;
  13725. case SERVICE_STOPPED:
  13726. LOG((TL_TRACE, "Starting tapisrv (NT)..."));
  13727. if (!StartService(
  13728. hTapiSrv, // service handle
  13729. 0, // num args
  13730. NULL // args
  13731. ))
  13732. {
  13733. DWORD dwLastError = GetLastError();
  13734. if (dwLastError != ERROR_SERVICE_ALREADY_RUNNING)
  13735. {
  13736. LOG((TL_ERROR,
  13737. "StartService(TapiSrv) failed, err=%d",
  13738. dwLastError
  13739. ));
  13740. goto AllocClientResources_cleanup2;
  13741. }
  13742. }
  13743. break;
  13744. default:
  13745. LOG((TL_ERROR,
  13746. "error, service status=%d",
  13747. status.dwCurrentState
  13748. ));
  13749. goto AllocClientResources_cleanup2;
  13750. }
  13751. }
  13752. }
  13753. //
  13754. // Init the RPC connection
  13755. //
  13756. AllocClientResources_attachToServer:
  13757. {
  13758. #define CNLEN 25 // computer name length
  13759. #define UNCLEN CNLEN+2 // \\computername
  13760. #define PATHLEN 260 // Path
  13761. #define MAXPROTSEQ 20 // protocol sequence "ncacn_np"
  13762. BOOL bException = FALSE;
  13763. RPC_STATUS status;
  13764. TCHAR pszNetworkAddress[UNCLEN+1];
  13765. LPTSTR pszUuid = NULL;
  13766. LPTSTR pszOptions = NULL;
  13767. LPTSTR pszStringBinding = NULL;
  13768. LPTSTR pszBuffer;
  13769. DWORD dwProcessID = GetCurrentProcessId(), dwSize = 256;
  13770. WCHAR *pszUserName = ClientAlloc (dwSize * sizeof(WCHAR) );
  13771. WCHAR *pszComputerName = ClientAlloc(
  13772. (MAX_COMPUTERNAME_LENGTH+1) * sizeof(WCHAR)
  13773. );
  13774. pszNetworkAddress[0] = TEXT('\0');
  13775. status = RpcStringBindingCompose(
  13776. pszUuid,
  13777. TEXT("ncalrpc"),
  13778. pszNetworkAddress,
  13779. TEXT("tapsrvlpc"),
  13780. pszOptions,
  13781. &pszStringBinding
  13782. );
  13783. if (status)
  13784. {
  13785. LOG((TL_ERROR,
  13786. "RpcStringBindingCompose failed: err=%d, szNetAddr='%s'",
  13787. status,
  13788. pszNetworkAddress
  13789. ));
  13790. lResult = gaOpFailedErrors[dwErrorClass];
  13791. ClientFree (pszUserName);
  13792. ClientFree (pszComputerName);
  13793. goto AllocClientResources_cleanup2;
  13794. }
  13795. status = RpcBindingFromStringBinding(
  13796. pszStringBinding,
  13797. &hTapSrv
  13798. );
  13799. if (status)
  13800. {
  13801. LOG((TL_ERROR,
  13802. "RpcBindingFromStringBinding failed, err=%d, szBinding='%s'",
  13803. status,
  13804. pszStringBinding
  13805. ));
  13806. lResult = gaOpFailedErrors[dwErrorClass];
  13807. RpcStringFree(&pszStringBinding);
  13808. ClientFree (pszUserName);
  13809. ClientFree (pszComputerName);
  13810. goto AllocClientResources_cleanup2;
  13811. }
  13812. pszBuffer = (LPTSTR)ClientAlloc( (dwSize>(MAX_COMPUTERNAME_LENGTH+1)?dwSize:(MAX_COMPUTERNAME_LENGTH+1) ) * sizeof(TCHAR));
  13813. if ( NULL == pszBuffer )
  13814. {
  13815. LOG((TL_ERROR, "Mem alloc of 0x%lx bytes failed(ca1)", dwSize ));
  13816. lResult = gaOpFailedErrors[dwErrorClass];
  13817. RpcStringFree(&pszStringBinding);
  13818. ClientFree (pszUserName);
  13819. ClientFree (pszComputerName);
  13820. goto AllocClientResources_cleanup2;
  13821. }
  13822. GetUserName(pszBuffer, &dwSize);
  13823. SHTCharToUnicode(pszBuffer, pszUserName, 256);
  13824. dwSize = (MAX_COMPUTERNAME_LENGTH+1);
  13825. GetComputerName( pszBuffer, &dwSize );
  13826. SHTCharToUnicode(pszBuffer, pszComputerName, MAX_COMPUTERNAME_LENGTH+1);
  13827. ClientFree(pszBuffer);
  13828. RpcTryExcept
  13829. {
  13830. LOG((TL_TRACE, "AllocCliRes: calling ClientAttach..."));
  13831. lResult = ClientAttach(
  13832. (PCONTEXT_HANDLE_TYPE *) &gphCx,
  13833. dwProcessID,
  13834. (long *) &ghAsyncEventsEvent,
  13835. pszUserName,
  13836. pszComputerName
  13837. );
  13838. LOG((TL_TRACE, "AllocCliRes: ClientAttach returned x%x", lResult));
  13839. }
  13840. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  13841. {
  13842. LOG((TL_ERROR,
  13843. "AllocCliRes: ClientAttach caused except=%d",
  13844. RpcExceptionCode()
  13845. ));
  13846. bException = TRUE;
  13847. }
  13848. RpcEndExcept
  13849. ClientFree (pszUserName);
  13850. ClientFree (pszComputerName);
  13851. RpcBindingFree (&hTapSrv);
  13852. RpcStringFree(&pszStringBinding);
  13853. if (bException)
  13854. {
  13855. //
  13856. // Make sure we don't leak the handle duplicated in ClientAttach
  13857. //
  13858. if (ghAsyncEventsEvent)
  13859. {
  13860. CloseHandle (ghAsyncEventsEvent);
  13861. ghAsyncEventsEvent = NULL;
  13862. }
  13863. //
  13864. // If here chances are that we started the service and it's
  13865. // not ready to receive rpc requests. So we'll give it a
  13866. // little time to get rolling and then try again.
  13867. //
  13868. if (dwExceptionCount < gdwMaxNumRequestRetries)
  13869. {
  13870. Sleep ((++dwExceptionCount > 1 ? gdwRequestRetryTimeout : 0));
  13871. if (hTapiSrv) // Win NT && successful OpenService()
  13872. {
  13873. goto AllocClientResources_queryServiceStatus;
  13874. }
  13875. else
  13876. {
  13877. goto AllocClientResources_attachToServer;
  13878. }
  13879. }
  13880. else
  13881. {
  13882. LOG((TL_ERROR,
  13883. "AllocCliRes: ClientAttach failed, result=x%x",
  13884. gaServiceNotRunningErrors[dwErrorClass]
  13885. ));
  13886. lResult = gaServiceNotRunningErrors[dwErrorClass];
  13887. }
  13888. }
  13889. }
  13890. if (lResult == 0)
  13891. {
  13892. gdwRpcRefCount++;
  13893. }
  13894. AllocClientResources_cleanup2:
  13895. if (hTapiSrv)
  13896. {
  13897. CloseServiceHandle (hTapiSrv);
  13898. }
  13899. AllocClientResources_cleanup1:
  13900. if (hSCMgr)
  13901. {
  13902. CloseServiceHandle (hSCMgr);
  13903. }
  13904. AllocClientResources_return:
  13905. ReleaseMutex (ghInitMutex);
  13906. LOG((TL_TRACE, "AllocClientResources: exit, returning x%x", lResult));
  13907. return lResult;
  13908. }
  13909. LONG
  13910. PASCAL
  13911. xxxShutdown(
  13912. HLINEAPP hXXXApp,
  13913. BOOL bLineShutdown
  13914. )
  13915. {
  13916. //NOTE NOTE NOTE NOTE NOTE NOTE
  13917. //NOTE NOTE NOTE NOTE NOTE NOTE
  13918. // There is "identical" code in lineShutdownInt - if this changes that should
  13919. // probably change as well!!!!!
  13920. FUNC_ARGS funcArgs =
  13921. {
  13922. MAKELONG (LINE_FUNC | SYNC | 1, (bLineShutdown ? lShutdown:pShutdown)),
  13923. {
  13924. (ULONG_PTR) hXXXApp
  13925. },
  13926. {
  13927. hXxxApp
  13928. }
  13929. };
  13930. LONG lResult;
  13931. WaitForSingleObject (ghInitMutex, INFINITE);
  13932. lResult = DOFUNC(
  13933. &funcArgs,
  13934. (bLineShutdown ? "lineShutdown" : "phoneShutdown")
  13935. );
  13936. if (lResult == 0)
  13937. {
  13938. PINIT_DATA pInitData;
  13939. ReleaseAllHandles (ghHandleTable, (PVOID)UIntToPtr(hXXXApp));
  13940. if ((pInitData = ReferenceObject (ghHandleTable, hXXXApp, 0)))
  13941. {
  13942. DereferenceObject (ghHandleTable, hXXXApp, 1);
  13943. FreeInitData (pInitData);
  13944. }
  13945. EnterCriticalSection (&gCriticalSection);
  13946. gdwNumInits--;
  13947. if (gdwNumInits == 0)
  13948. {
  13949. //
  13950. // Tell the async events thread to quit
  13951. //
  13952. gpAsyncEventsThreadParams->bExitThread = TRUE;
  13953. SetEvent (ghAsyncEventsEvent);
  13954. gpAsyncEventsThreadParams = NULL;
  13955. //
  13956. // Safely close any existing generic dialog instances
  13957. //
  13958. if (gpUIThreadInstances)
  13959. {
  13960. PUITHREADDATA pUIThreadData, pNextUIThreadData;
  13961. pUIThreadData = gpUIThreadInstances;
  13962. while (pUIThreadData)
  13963. {
  13964. //
  13965. // Grab a ptr to the next UIThreadData while it's still
  13966. // safe, wait until the ui dll has indicated that it
  13967. // is will to receive generic dlg data, then pass it
  13968. // NULL/0 to tell it to shutdown the dlg inst
  13969. //
  13970. pNextUIThreadData = pUIThreadData->pNext;
  13971. WaitForSingleObject (pUIThreadData->hEvent, INFINITE);
  13972. LOG((TL_TRACE,
  13973. "xxxShutdown: calling " \
  13974. "TUISPI_providerGenericDialogData..."
  13975. ));
  13976. (*pUIThreadData->pfnTUISPI_providerGenericDialogData)(
  13977. pUIThreadData->htDlgInst,
  13978. NULL,
  13979. 0
  13980. );
  13981. LOG((TL_TRACE,
  13982. "xxxShutdown: " \
  13983. "TUISPI_providerGenericDialogData returned"
  13984. ));
  13985. pUIThreadData = pNextUIThreadData;
  13986. }
  13987. }
  13988. //
  13989. // Free up any other resources we were using
  13990. //
  13991. if (ghWow32Dll)
  13992. {
  13993. FreeLibrary (ghWow32Dll);
  13994. ghWow32Dll = NULL;
  13995. }
  13996. // Disable tracing after last line shutdown
  13997. TRACELOGDEREGISTER();
  13998. }
  13999. LeaveCriticalSection (&gCriticalSection);
  14000. //
  14001. // Remove the RPC ref count added in lineInitialize
  14002. //
  14003. FreeClientResources();
  14004. }
  14005. ReleaseMutex (ghInitMutex);
  14006. return lResult;
  14007. }
  14008. LONG
  14009. PASCAL
  14010. xxxGetMessage(
  14011. BOOL bLine,
  14012. HLINEAPP hXxxApp,
  14013. LPLINEMESSAGE pMsg,
  14014. DWORD dwTimeout
  14015. )
  14016. {
  14017. LONG lResult;
  14018. BOOL bInCriticalSection = FALSE;
  14019. PINIT_DATA pInitData;
  14020. if (IsBadWritePtr (pMsg, sizeof (LINEMESSAGE)))
  14021. {
  14022. lResult = (bLine ? LINEERR_INVALPOINTER : PHONEERR_INVALPOINTER);
  14023. goto xxxGetMessage_return2;
  14024. }
  14025. if (!(pInitData = (PINIT_DATA) ReferenceObject(
  14026. ghHandleTable,
  14027. hXxxApp,
  14028. INITDATA_KEY
  14029. )))
  14030. {
  14031. LOG((TL_ERROR, "xxxGetMessage: hXxxApp=x%x invalid", hXxxApp));
  14032. lResult = (bLine ? LINEERR_INVALAPPHANDLE :
  14033. PHONEERR_INVALAPPHANDLE);
  14034. goto xxxGetMessage_return2;
  14035. }
  14036. try
  14037. {
  14038. if ((pInitData->dwInitOptions & 0x3) !=
  14039. LINEINITIALIZEEXOPTION_USEEVENT)
  14040. {
  14041. LOG((TL_ERROR,
  14042. "GetMessage: This app did not call initex with _USEEVENT"
  14043. ));
  14044. lResult = (bLine ? LINEERR_INVALAPPHANDLE :
  14045. PHONEERR_INVALAPPHANDLE);
  14046. goto xxxGetMessage_return;
  14047. }
  14048. if (pInitData->dwNumUsedEntries)
  14049. {
  14050. EnterCriticalSection (&gCriticalSection);
  14051. bInCriticalSection = TRUE;
  14052. if (pInitData->dwKey == INITDATA_KEY)
  14053. {
  14054. if (pInitData->dwNumUsedEntries)
  14055. {
  14056. CopyMemory(
  14057. pMsg,
  14058. pInitData->pValidEntry,
  14059. sizeof (ASYNC_EVENT_PARAMS)
  14060. );
  14061. pInitData->pValidEntry++;
  14062. if (pInitData->pValidEntry >= (pInitData->pEventBuffer +
  14063. pInitData->dwNumTotalEntries))
  14064. {
  14065. pInitData->pValidEntry = pInitData->pEventBuffer;
  14066. }
  14067. pInitData->dwNumUsedEntries--;
  14068. //
  14069. // If the buffer is empty then reset the event
  14070. // to nonsignaled
  14071. //
  14072. if (pInitData->dwNumUsedEntries == 0)
  14073. {
  14074. ResetEvent (pInitData->hEvent);
  14075. }
  14076. lResult = 0;
  14077. }
  14078. else
  14079. {
  14080. lResult = (bLine ? LINEERR_OPERATIONFAILED :
  14081. PHONEERR_OPERATIONFAILED);
  14082. }
  14083. }
  14084. else
  14085. {
  14086. LOG((TL_ERROR, "GetMessage: bad key2"));
  14087. lResult = (bLine ? LINEERR_INVALAPPHANDLE :
  14088. PHONEERR_INVALAPPHANDLE);
  14089. }
  14090. LeaveCriticalSection (&gCriticalSection);
  14091. bInCriticalSection = FALSE;
  14092. }
  14093. else
  14094. {
  14095. lResult = (bLine ? LINEERR_OPERATIONFAILED :
  14096. PHONEERR_OPERATIONFAILED);
  14097. }
  14098. if (dwTimeout != 0 && lResult != 0)
  14099. {
  14100. xxxGetMessage_wait:
  14101. switch (WaitForSingleObject (pInitData->hEvent, dwTimeout))
  14102. {
  14103. case WAIT_OBJECT_0:
  14104. EnterCriticalSection (&gCriticalSection);
  14105. bInCriticalSection = TRUE;
  14106. if (pInitData->dwKey == INITDATA_KEY)
  14107. {
  14108. if (pInitData->dwNumUsedEntries)
  14109. {
  14110. CopyMemory(
  14111. pMsg,
  14112. pInitData->pValidEntry,
  14113. sizeof (ASYNC_EVENT_PARAMS)
  14114. );
  14115. pInitData->pValidEntry++;
  14116. if (pInitData->pValidEntry >= (pInitData->pEventBuffer+
  14117. pInitData->dwNumTotalEntries))
  14118. {
  14119. pInitData->pValidEntry = pInitData->pEventBuffer;
  14120. }
  14121. pInitData->dwNumUsedEntries--;
  14122. //
  14123. // If the buffer is empty then reset the event
  14124. // to nonsignaled
  14125. //
  14126. if (pInitData->dwNumUsedEntries == 0)
  14127. {
  14128. ResetEvent (pInitData->hEvent);
  14129. }
  14130. //
  14131. // Everything looks good, now.
  14132. //
  14133. lResult = 0;
  14134. }
  14135. else if (dwTimeout == INFINITE)
  14136. {
  14137. LeaveCriticalSection (&gCriticalSection);
  14138. bInCriticalSection = FALSE;
  14139. goto xxxGetMessage_wait;
  14140. }
  14141. }
  14142. else
  14143. {
  14144. LOG((TL_ERROR, "GetMessage: bad key1"));
  14145. lResult = (bLine ? LINEERR_INVALAPPHANDLE :
  14146. PHONEERR_INVALAPPHANDLE);
  14147. }
  14148. LeaveCriticalSection (&gCriticalSection);
  14149. bInCriticalSection = FALSE;
  14150. break;
  14151. case WAIT_TIMEOUT:
  14152. default:
  14153. lResult = (bLine ? LINEERR_OPERATIONFAILED :
  14154. PHONEERR_OPERATIONFAILED);
  14155. }
  14156. }
  14157. }
  14158. except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
  14159. EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  14160. {
  14161. LOG((TL_ERROR, "GetMessage: exception"));
  14162. if (bInCriticalSection)
  14163. {
  14164. LeaveCriticalSection (&gCriticalSection);
  14165. }
  14166. lResult = (bLine ? LINEERR_INVALAPPHANDLE : PHONEERR_INVALAPPHANDLE);
  14167. }
  14168. xxxGetMessage_return:
  14169. DereferenceObject (ghHandleTable, hXxxApp, 1);
  14170. xxxGetMessage_return2:
  14171. {
  14172. char szResult[32],
  14173. *pszFuncName = (bLine ? "lineGetMessage" : "phoneGetMessage");
  14174. #if DBG
  14175. if (lResult == 0)
  14176. {
  14177. LOG((TL_TRACE,
  14178. "%hs: exit, returning msg=%hs\n" \
  14179. "\thDev=x%01lx, ctx=x%01lx, p1=x%01lx, " \
  14180. "p2=x%01lx, p3=x%01lx",
  14181. pszFuncName,
  14182. aszMsgs[pMsg->dwMessageID],
  14183. (DWORD)pMsg->hDevice,
  14184. pMsg->dwCallbackInstance,
  14185. pMsg->dwParam1,
  14186. pMsg->dwParam2,
  14187. pMsg->dwParam3
  14188. ));
  14189. }
  14190. else
  14191. {
  14192. LOG((TL_TRACE,
  14193. "%hs: exit, result=%hs",
  14194. pszFuncName,
  14195. MapResultCodeToText (lResult, szResult)
  14196. ));
  14197. }
  14198. #else
  14199. if (lResult == 0)
  14200. {
  14201. LOG((TL_TRACE,
  14202. "%hs: exit, returning msgID=x%x\n" \
  14203. "\thDev=x%01lx, ctx=x%01lx, p1=x%01lx, " \
  14204. "p2=x%01lx, p3=x%01lx",
  14205. pszFuncName,
  14206. pMsg->dwMessageID,
  14207. (DWORD)pMsg->hDevice,
  14208. pMsg->dwCallbackInstance,
  14209. pMsg->dwParam1,
  14210. pMsg->dwParam2,
  14211. pMsg->dwParam3
  14212. ));
  14213. }
  14214. else
  14215. {
  14216. LOG((TL_TRACE,
  14217. "%hs: exit, result=x%x",
  14218. pszFuncName,
  14219. lResult
  14220. ));
  14221. }
  14222. #endif
  14223. }
  14224. return lResult;
  14225. }
  14226. /*
  14227. #if DBG
  14228. LPVOID
  14229. WINAPI
  14230. ClientAllocReal(
  14231. DWORD dwSize,
  14232. DWORD dwLine,
  14233. PSTR pszFile
  14234. )
  14235. #else
  14236. LPVOID
  14237. WINAPI
  14238. ClientAllocReal(
  14239. DWORD dwSize
  14240. )
  14241. #endif
  14242. {
  14243. LPVOID p;
  14244. #if DBG
  14245. dwSize += sizeof (MYMEMINFO);
  14246. #endif
  14247. p = LocalAlloc (LPTR, dwSize);
  14248. #if DBG
  14249. if (p)
  14250. {
  14251. ((PMYMEMINFO) p)->dwLine = dwLine;
  14252. ((PMYMEMINFO) p)->pszFile = pszFile;
  14253. p = (LPVOID) (((PMYMEMINFO) p) + 1);
  14254. }
  14255. #endif
  14256. return p;
  14257. }
  14258. VOID
  14259. WINAPI
  14260. ClientFree(
  14261. LPVOID p
  14262. )
  14263. {
  14264. if (!p)
  14265. {
  14266. return;
  14267. }
  14268. #if DBG
  14269. //
  14270. // Fill the buffer (but not the MYMEMINFO header) with 0xa1's
  14271. // to facilitate debugging
  14272. //
  14273. {
  14274. LPVOID p2 = p;
  14275. p = (LPVOID) (((PMYMEMINFO) p) - 1);
  14276. FillMemory(
  14277. p2,
  14278. LocalSize (p) - sizeof (MYMEMINFO),
  14279. 0xa1
  14280. );
  14281. }
  14282. #endif
  14283. LocalFree (p);
  14284. }
  14285. */
  14286. #if DBG
  14287. LPVOID
  14288. WINAPI
  14289. ClientAllocReal(
  14290. DWORD dwSize,
  14291. DWORD dwLine,
  14292. PSTR pszFile
  14293. )
  14294. #else
  14295. LPVOID
  14296. WINAPI
  14297. ClientAllocReal(
  14298. DWORD dwSize
  14299. )
  14300. #endif
  14301. {
  14302. //
  14303. // Alloc 16 extra bytes so we can make sure the pointer we pass back
  14304. // is 64-bit aligned & have space to store the original pointer
  14305. //
  14306. #if DBG
  14307. PMYMEMINFO pHold;
  14308. PDWORD_PTR pAligned;
  14309. PBYTE p;
  14310. if (0 == dwSize)
  14311. {
  14312. return NULL;
  14313. }
  14314. p = (PBYTE)LocalAlloc(LPTR, dwSize + sizeof(MYMEMINFO) + 16);
  14315. if (p == NULL)
  14316. {
  14317. return NULL;
  14318. }
  14319. // note note note - this only works because mymeminfo is
  14320. // a 16 bit multiple in size. if it wasn't, this
  14321. // align stuff would cause problems.
  14322. pAligned = (PDWORD_PTR) (p + 8 - (((DWORD_PTR) p) & (DWORD_PTR)0x7));
  14323. *pAligned = (DWORD_PTR) p;
  14324. pHold = (PMYMEMINFO)((DWORD_PTR)pAligned + 8);
  14325. pHold->dwSize = dwSize;
  14326. pHold->dwLine = dwLine;
  14327. pHold->pszFile = pszFile;
  14328. EnterCriticalSection(&csMemoryList);
  14329. if (gpMemLast != NULL)
  14330. {
  14331. gpMemLast->pNext = pHold;
  14332. pHold->pPrev = gpMemLast;
  14333. gpMemLast = pHold;
  14334. }
  14335. else
  14336. {
  14337. gpMemFirst = gpMemLast = pHold;
  14338. }
  14339. LeaveCriticalSection(&csMemoryList);
  14340. return (LPVOID)(pHold + 1);
  14341. #else
  14342. LPBYTE p;
  14343. PDWORD_PTR pAligned;
  14344. if (0 == dwSize)
  14345. {
  14346. return NULL;
  14347. }
  14348. if ((p = (LPBYTE) LocalAlloc (LPTR, dwSize + 16)))
  14349. {
  14350. pAligned = (PDWORD_PTR) (p + 8 - (((DWORD_PTR) p) & (DWORD_PTR)0x7));
  14351. *pAligned = (DWORD_PTR) p;
  14352. pAligned = (PDWORD_PTR)((DWORD_PTR)pAligned + 8);
  14353. }
  14354. else
  14355. {
  14356. pAligned = NULL;
  14357. }
  14358. return ((LPVOID) pAligned);
  14359. #endif
  14360. }
  14361. void
  14362. WINAPI
  14363. ClientFree(
  14364. LPVOID p
  14365. )
  14366. {
  14367. #if DBG
  14368. PMYMEMINFO pHold;
  14369. if (p == NULL)
  14370. {
  14371. return;
  14372. }
  14373. pHold = (PMYMEMINFO)(((LPBYTE)p) - sizeof(MYMEMINFO));
  14374. EnterCriticalSection(&csMemoryList);
  14375. if (pHold->pPrev)
  14376. {
  14377. pHold->pPrev->pNext = pHold->pNext;
  14378. }
  14379. else
  14380. {
  14381. gpMemFirst = pHold->pNext;
  14382. }
  14383. if (pHold->pNext)
  14384. {
  14385. pHold->pNext->pPrev = pHold->pPrev;
  14386. }
  14387. else
  14388. {
  14389. gpMemLast = pHold->pPrev;
  14390. }
  14391. LeaveCriticalSection(&csMemoryList);
  14392. {
  14393. LPVOID pOrig = (LPVOID) *((PDWORD_PTR)((DWORD_PTR)pHold - 8));
  14394. LocalFree (pOrig);
  14395. }
  14396. // LocalFree(pHold);
  14397. return;
  14398. #else
  14399. if (p != NULL)
  14400. {
  14401. LPVOID pOrig = (LPVOID) *((PDWORD_PTR)((DWORD_PTR)p - 8));
  14402. LocalFree (pOrig);
  14403. }
  14404. #endif
  14405. }
  14406. #if DBG
  14407. void
  14408. DumpMemoryList()
  14409. {
  14410. PMYMEMINFO pHold;
  14411. if (gpMemFirst == NULL)
  14412. {
  14413. LOG((TL_INFO, "DumpMemoryList: ALL MEMORY DEALLOCATED"));
  14414. return;
  14415. }
  14416. pHold = gpMemFirst;
  14417. while (pHold)
  14418. {
  14419. LOG((TL_ERROR, "DumpMemoryList: %p not freed - LINE %d FILE %hs!", pHold+1, pHold->dwLine, pHold->pszFile));
  14420. pHold = pHold->pNext;
  14421. }
  14422. if (gbBreakOnLeak)
  14423. {
  14424. DebugBreak();
  14425. }
  14426. }
  14427. #endif
  14428. SIZE_T
  14429. WINAPI
  14430. ClientSize(
  14431. LPVOID p
  14432. )
  14433. {
  14434. if (p != NULL)
  14435. {
  14436. #if DBG
  14437. p = (LPVOID)(((LPBYTE)p) - sizeof(MYMEMINFO));
  14438. #endif
  14439. p = (LPVOID)*((PDWORD_PTR)((DWORD_PTR)p - 8));
  14440. return (LocalSize (p) - 16);
  14441. }
  14442. return 0;
  14443. }
  14444. LONG
  14445. WINAPI
  14446. FreeClientResources(
  14447. void
  14448. )
  14449. {
  14450. //
  14451. // Serialize the following code
  14452. //
  14453. WaitForSingleObject (ghInitMutex, INFINITE);
  14454. if (0 == gdwRpcRefCount)
  14455. {
  14456. ReleaseMutex (ghInitMutex);
  14457. return TAPIERR_REQUESTFAILED;
  14458. }
  14459. gdwRpcRefCount--;
  14460. if (0 == gdwRpcRefCount)
  14461. {
  14462. //
  14463. // If we've made an rpc connection with tapisrv then cleanly detach
  14464. //
  14465. if (gphCx)
  14466. {
  14467. RpcTryExcept
  14468. {
  14469. ClientDetach (&gphCx);
  14470. }
  14471. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  14472. {
  14473. // do something?
  14474. }
  14475. RpcEndExcept
  14476. gphCx = NULL;
  14477. //
  14478. // we also need to close the handle to ghAsyncEventsEvent
  14479. //
  14480. if (ghAsyncEventsEvent)
  14481. {
  14482. CloseHandle(ghAsyncEventsEvent);
  14483. ghAsyncEventsEvent = NULL;
  14484. }
  14485. }
  14486. }
  14487. ReleaseMutex (ghInitMutex);
  14488. return 0;
  14489. }
  14490. #if DBG
  14491. VOID
  14492. DbgPrt(
  14493. IN DWORD dwDbgLevel,
  14494. IN LPTSTR lpszFormat,
  14495. IN ...
  14496. )
  14497. /*++
  14498. Routine Description:
  14499. Formats the incoming debug message & calls DbgPrint
  14500. Arguments:
  14501. DbgLevel - level of message verboseness
  14502. DbgMessage - printf-style format string, followed by appropriate
  14503. list of arguments
  14504. Return Value:
  14505. --*/
  14506. {
  14507. if (dwDbgLevel <= gdwDebugLevel)
  14508. {
  14509. TCHAR buf[1280] = TEXT("TAPI32 (xxxxxxxx): ");
  14510. va_list ap;
  14511. wsprintf( &buf[8], TEXT("%08lx"), GetCurrentThreadId() );
  14512. buf[16] = TEXT(')');
  14513. va_start(ap, lpszFormat);
  14514. wvsprintf(&buf[19],
  14515. lpszFormat,
  14516. ap
  14517. );
  14518. lstrcat (buf, TEXT("\n"));
  14519. OutputDebugString (buf);
  14520. va_end(ap);
  14521. }
  14522. }
  14523. #endif
  14524. LONG
  14525. CALLBACK
  14526. TUISPIDLLCallback(
  14527. DWORD dwObjectID,
  14528. DWORD dwObjectType,
  14529. LPVOID lpParams,
  14530. DWORD dwSize
  14531. )
  14532. {
  14533. FUNC_ARGS funcArgs =
  14534. {
  14535. MAKELONG (LINE_FUNC | SYNC | 6, xUIDLLCallback),
  14536. {
  14537. (ULONG_PTR) dwObjectID,
  14538. (ULONG_PTR) dwObjectType,
  14539. (ULONG_PTR) lpParams,
  14540. (ULONG_PTR) dwSize,
  14541. (ULONG_PTR) lpParams,
  14542. (ULONG_PTR) dwSize
  14543. },
  14544. {
  14545. Dword,
  14546. Dword,
  14547. lpSet_SizeToFollow,
  14548. Size,
  14549. lpGet_SizeToFollow,
  14550. Size
  14551. }
  14552. };
  14553. return (DOFUNC (&funcArgs, "UIDLLCallback"));
  14554. }
  14555. void
  14556. UIThread(
  14557. LPVOID pParams
  14558. )
  14559. {
  14560. DWORD dwThreadID = GetCurrentThreadId();
  14561. HANDLE hTapi32;
  14562. PUITHREADDATA pUIThreadData = (PUITHREADDATA) pParams;
  14563. LOG((TL_TRACE, "UIThread: enter (tid=%d)", dwThreadID));
  14564. //
  14565. // Call LoadLibrary to increment the reference count in case this
  14566. // thread is still running when this dll gets unloaded
  14567. //
  14568. hTapi32 = LoadLibrary (TEXT("tapi32.dll"));
  14569. LOG((TL_TRACE, "UIThread: calling TUISPI_providerGenericDialog..."));
  14570. (*pUIThreadData->pfnTUISPI_providerGenericDialog)(
  14571. TUISPIDLLCallback,
  14572. pUIThreadData->htDlgInst,
  14573. pUIThreadData->pParams,
  14574. pUIThreadData->dwSize,
  14575. pUIThreadData->hEvent
  14576. );
  14577. LOG((TL_TRACE,
  14578. "UIThread: TUISPI_providerGenericDialog returned (tid=%d)",
  14579. dwThreadID
  14580. ));
  14581. //
  14582. // Remove the ui thread data struct from the global list
  14583. //
  14584. EnterCriticalSection (&gCriticalSection);
  14585. if (pUIThreadData->pNext)
  14586. {
  14587. pUIThreadData->pNext->pPrev = pUIThreadData->pPrev;
  14588. }
  14589. if (pUIThreadData->pPrev)
  14590. {
  14591. pUIThreadData->pPrev->pNext = pUIThreadData->pNext;
  14592. }
  14593. else
  14594. {
  14595. gpUIThreadInstances = pUIThreadData->pNext;
  14596. }
  14597. LeaveCriticalSection (&gCriticalSection);
  14598. //
  14599. // Free the library & buffers, then alert tapisrv
  14600. //
  14601. FreeLibrary (pUIThreadData->hUIDll);
  14602. CloseHandle (pUIThreadData->hThread);
  14603. CloseHandle (pUIThreadData->hEvent);
  14604. if (pUIThreadData->pParams)
  14605. {
  14606. ClientFree (pUIThreadData->pParams);
  14607. }
  14608. {
  14609. FUNC_ARGS funcArgs =
  14610. {
  14611. MAKELONG (LINE_FUNC | SYNC | 1, xFreeDialogInstance),
  14612. {
  14613. (ULONG_PTR) pUIThreadData->htDlgInst
  14614. },
  14615. {
  14616. Dword
  14617. }
  14618. };
  14619. DOFUNC (&funcArgs, "FreeDialogInstance");
  14620. }
  14621. ClientFree (pUIThreadData);
  14622. LOG((TL_TRACE, "UIThread: exit (tid=%d)", dwThreadID));
  14623. FreeLibraryAndExitThread (hTapi32, 0);
  14624. }
  14625. LONG
  14626. //WINAPI
  14627. CALLBACK
  14628. LAddrParamsInited(
  14629. LPDWORD lpdwInited
  14630. )
  14631. {
  14632. HKEY hKey;
  14633. HKEY hKey2;
  14634. //
  14635. // Default to 0, i.e. not initialized
  14636. //
  14637. *lpdwInited = 0;
  14638. //
  14639. // This is called by the modem setup wizard to determine
  14640. // whether they should put up TAPI's Wizard page.
  14641. //
  14642. if (RegOpenKeyEx(
  14643. HKEY_LOCAL_MACHINE,
  14644. gszTelephonyKey,
  14645. 0,
  14646. KEY_READ,
  14647. &hKey2
  14648. ) == ERROR_SUCCESS)
  14649. {
  14650. if (RegOpenKeyEx(
  14651. hKey2,
  14652. gszLocations,
  14653. 0,
  14654. KEY_READ,
  14655. &hKey
  14656. ) == ERROR_SUCCESS)
  14657. {
  14658. // query the Locations key for number of locations (subkeys)
  14659. if (RegQueryInfoKey(hKey,
  14660. NULL,
  14661. NULL,
  14662. NULL,
  14663. lpdwInited,
  14664. NULL,
  14665. NULL,
  14666. NULL,
  14667. NULL,
  14668. NULL,
  14669. NULL,
  14670. NULL
  14671. ) == ERROR_SUCCESS)
  14672. {
  14673. //
  14674. // Make sure we return a "proper" code
  14675. //
  14676. if ( *lpdwInited > 1 )
  14677. {
  14678. *lpdwInited = 1;
  14679. }
  14680. }
  14681. RegCloseKey (hKey);
  14682. }
  14683. RegCloseKey (hKey2);
  14684. }
  14685. return 0;
  14686. }
  14687. LONG
  14688. WINAPI
  14689. lineTranslateDialogA(
  14690. HLINEAPP hLineApp,
  14691. DWORD dwDeviceID,
  14692. DWORD dwAPIVersion,
  14693. HWND hwndOwner,
  14694. LPCSTR lpszAddressIn
  14695. );
  14696. LONG
  14697. CALLBACK
  14698. //WINAPI
  14699. LOpenDialAsst(
  14700. HWND hwnd,
  14701. LPCSTR lpszAddressIn,
  14702. BOOL fSimple,
  14703. BOOL fSilentInstall
  14704. )
  14705. {
  14706. TCHAR szBuf[256];
  14707. TCHAR szWinlogon[64];
  14708. DWORD dwLengthNeeded;
  14709. HDESK hDesk;
  14710. // lineTranslateDialog(hLineApp, 0, 0x00020000, hwnd, lpszAddressIn );
  14711. gbTranslateSimple = fSimple;
  14712. gbTranslateSilent = fSilentInstall;
  14713. //
  14714. // Check to see if we are called from LOGON desktop, if so, simply
  14715. // make sure we have at least one location
  14716. //
  14717. hDesk = GetThreadDesktop (GetCurrentThreadId ());
  14718. if (hDesk == NULL ||
  14719. !GetUserObjectInformation (
  14720. hDesk,
  14721. UOI_NAME,
  14722. (PVOID)szBuf,
  14723. sizeof(szBuf),
  14724. &dwLengthNeeded
  14725. ) ||
  14726. LoadString (
  14727. g_hInst,
  14728. IDS_LOGONDESKNAME,
  14729. szWinlogon,
  14730. sizeof(szWinlogon)/sizeof(TCHAR)
  14731. ) == 0 ||
  14732. _tcsicmp (szBuf, szWinlogon) == 0)
  14733. {
  14734. return EnsureOneLocation (hwnd);
  14735. }
  14736. return lineTranslateDialogA( 0, 0, 0x00020000, hwnd, lpszAddressIn );
  14737. }
  14738. /////////////////////////////////////////////////////////////////////
  14739. // internalPerformance
  14740. // tapiperf.dll calls this function to get performance data
  14741. // this just calls into tapisrv
  14742. /////////////////////////////////////////////////////////////////////
  14743. LONG
  14744. WINAPI
  14745. internalPerformance(
  14746. PPERFBLOCK pPerfBlock
  14747. )
  14748. {
  14749. FUNC_ARGS funcArgs =
  14750. {
  14751. MAKELONG (LINE_FUNC | SYNC | 2, tPerformance),
  14752. {
  14753. (ULONG_PTR) pPerfBlock,
  14754. (ULONG_PTR) sizeof(PERFBLOCK)
  14755. },
  14756. {
  14757. lpGet_SizeToFollow,
  14758. Size
  14759. }
  14760. };
  14761. return (DOFUNC (&funcArgs, "PerfDataCall"));
  14762. }
  14763. BOOL
  14764. WaveStringIdToDeviceId(
  14765. LPWSTR pwszStringID,
  14766. LPCWSTR pwszDeviceType,
  14767. LPDWORD pdwDeviceId
  14768. )
  14769. {
  14770. if (!pwszDeviceType || !pwszStringID)
  14771. return FALSE;
  14772. // get the device id, based on string id and device class
  14773. if ( !_wcsicmp(pwszDeviceType, L"wave/in") ||
  14774. !_wcsicmp(pwszDeviceType, L"wave/in/out")
  14775. )
  14776. {
  14777. return (MMSYSERR_NOERROR == waveInMessage(
  14778. NULL,
  14779. DRV_QUERYIDFROMSTRINGID,
  14780. (DWORD_PTR)pwszStringID,
  14781. (DWORD_PTR)pdwDeviceId));
  14782. } else if (!_wcsicmp(pwszDeviceType, L"wave/out"))
  14783. {
  14784. return (MMSYSERR_NOERROR == waveOutMessage(
  14785. NULL,
  14786. DRV_QUERYIDFROMSTRINGID,
  14787. (DWORD_PTR)pwszStringID,
  14788. (DWORD_PTR)pdwDeviceId));
  14789. } else if (!_wcsicmp(pwszDeviceType, L"midi/in"))
  14790. {
  14791. return (MMSYSERR_NOERROR == midiInMessage(
  14792. NULL,
  14793. DRV_QUERYIDFROMSTRINGID,
  14794. (DWORD_PTR)pwszStringID,
  14795. (DWORD_PTR)pdwDeviceId));
  14796. } else if (!_wcsicmp(pwszDeviceType, L"midi/out"))
  14797. {
  14798. return (MMSYSERR_NOERROR == midiOutMessage(
  14799. NULL,
  14800. DRV_QUERYIDFROMSTRINGID,
  14801. (DWORD_PTR)pwszStringID,
  14802. (DWORD_PTR)pdwDeviceId));
  14803. }
  14804. return FALSE;
  14805. }
  14806. //***************************************************************************
  14807. //***************************************************************************
  14808. //***************************************************************************
  14809. #if DBG
  14810. // Debug only stuff was left as ANSI
  14811. char *aszLineErrors[] =
  14812. {
  14813. NULL,
  14814. "ALLOCATED",
  14815. "BADDEVICEID",
  14816. "BEARERMODEUNAVAIL",
  14817. "inval err value (0x80000004)", // 0x80000004 isn't valid err code
  14818. "CALLUNAVAIL",
  14819. "COMPLETIONOVERRUN",
  14820. "CONFERENCEFULL",
  14821. "DIALBILLING",
  14822. "DIALDIALTONE",
  14823. "DIALPROMPT",
  14824. "DIALQUIET",
  14825. "INCOMPATIBLEAPIVERSION",
  14826. "INCOMPATIBLEEXTVERSION",
  14827. "INIFILECORRUPT",
  14828. "INUSE",
  14829. "INVALADDRESS", // 0x80000010
  14830. "INVALADDRESSID",
  14831. "INVALADDRESSMODE",
  14832. "INVALADDRESSSTATE",
  14833. "INVALAPPHANDLE",
  14834. "INVALAPPNAME",
  14835. "INVALBEARERMODE",
  14836. "INVALCALLCOMPLMODE",
  14837. "INVALCALLHANDLE",
  14838. "INVALCALLPARAMS",
  14839. "INVALCALLPRIVILEGE",
  14840. "INVALCALLSELECT",
  14841. "INVALCALLSTATE",
  14842. "INVALCALLSTATELIST",
  14843. "INVALCARD",
  14844. "INVALCOMPLETIONID",
  14845. "INVALCONFCALLHANDLE", // 0x80000020
  14846. "INVALCONSULTCALLHANDLE",
  14847. "INVALCOUNTRYCODE",
  14848. "INVALDEVICECLASS",
  14849. "INVALDEVICEHANDLE",
  14850. "INVALDIALPARAMS",
  14851. "INVALDIGITLIST",
  14852. "INVALDIGITMODE",
  14853. "INVALDIGITS",
  14854. "INVALEXTVERSION",
  14855. "INVALGROUPID",
  14856. "INVALLINEHANDLE",
  14857. "INVALLINESTATE",
  14858. "INVALLOCATION",
  14859. "INVALMEDIALIST",
  14860. "INVALMEDIAMODE",
  14861. "INVALMESSAGEID", // 0x80000030
  14862. "inval err value (0x80000031)", // 0x80000031 isn't valid err code
  14863. "INVALPARAM",
  14864. "INVALPARKID",
  14865. "INVALPARKMODE",
  14866. "INVALPOINTER",
  14867. "INVALPRIVSELECT",
  14868. "INVALRATE",
  14869. "INVALREQUESTMODE",
  14870. "INVALTERMINALID",
  14871. "INVALTERMINALMODE",
  14872. "INVALTIMEOUT",
  14873. "INVALTONE",
  14874. "INVALTONELIST",
  14875. "INVALTONEMODE",
  14876. "INVALTRANSFERMODE",
  14877. "LINEMAPPERFAILED", // 0x80000040
  14878. "NOCONFERENCE",
  14879. "NODEVICE",
  14880. "NODRIVER",
  14881. "NOMEM",
  14882. "NOREQUEST",
  14883. "NOTOWNER",
  14884. "NOTREGISTERED",
  14885. "OPERATIONFAILED",
  14886. "OPERATIONUNAVAIL",
  14887. "RATEUNAVAIL",
  14888. "RESOURCEUNAVAIL",
  14889. "REQUESTOVERRUN",
  14890. "STRUCTURETOOSMALL",
  14891. "TARGETNOTFOUND",
  14892. "TARGETSELF",
  14893. "UNINITIALIZED", // 0x80000050
  14894. "USERUSERINFOTOOBIG",
  14895. "REINIT",
  14896. "ADDRESSBLOCKED",
  14897. "BILLINGREJECTED",
  14898. "INVALFEATURE",
  14899. "NOMULTIPLEINSTANCE",
  14900. "INVALAGENTID",
  14901. "INVALAGENTGROUP",
  14902. "INVALPASSWORD",
  14903. "INVALAGENTSTATE",
  14904. "INVALAGENTACTIVITY",
  14905. "DIALVOICEDETECT"
  14906. };
  14907. char *aszPhoneErrors[] =
  14908. {
  14909. "SUCCESS",
  14910. "ALLOCATED",
  14911. "BADDEVICEID",
  14912. "INCOMPATIBLEAPIVERSION",
  14913. "INCOMPATIBLEEXTVERSION",
  14914. "INIFILECORRUPT",
  14915. "INUSE",
  14916. "INVALAPPHANDLE",
  14917. "INVALAPPNAME",
  14918. "INVALBUTTONLAMPID",
  14919. "INVALBUTTONMODE",
  14920. "INVALBUTTONSTATE",
  14921. "INVALDATAID",
  14922. "INVALDEVICECLASS",
  14923. "INVALEXTVERSION",
  14924. "INVALHOOKSWITCHDEV",
  14925. "INVALHOOKSWITCHMODE", // 0x90000010
  14926. "INVALLAMPMODE",
  14927. "INVALPARAM",
  14928. "INVALPHONEHANDLE",
  14929. "INVALPHONESTATE",
  14930. "INVALPOINTER",
  14931. "INVALPRIVILEGE",
  14932. "INVALRINGMODE",
  14933. "NODEVICE",
  14934. "NODRIVER",
  14935. "NOMEM",
  14936. "NOTOWNER",
  14937. "OPERATIONFAILED",
  14938. "OPERATIONUNAVAIL",
  14939. "inval err value (0x9000001e)", // 0x9000001e isn't valid err code
  14940. "RESOURCEUNAVAIL",
  14941. "REQUESTOVERRUN", // 0x90000020
  14942. "STRUCTURETOOSMALL",
  14943. "UNINITIALIZED",
  14944. "REINIT"
  14945. };
  14946. char *aszTapiErrors[] =
  14947. {
  14948. "SUCCESS",
  14949. "DROPPED",
  14950. "NOREQUESTRECIPIENT",
  14951. "REQUESTQUEUEFULL",
  14952. "INVALDESTADDRESS",
  14953. "INVALWINDOWHANDLE",
  14954. "INVALDEVICECLASS",
  14955. "INVALDEVICEID",
  14956. "DEVICECLASSUNAVAIL",
  14957. "DEVICEIDUNAVAIL",
  14958. "DEVICEINUSE",
  14959. "DESTBUSY",
  14960. "DESTNOANSWER",
  14961. "DESTUNAVAIL",
  14962. "UNKNOWNWINHANDLE",
  14963. "UNKNOWNREQUESTID",
  14964. "REQUESTFAILED",
  14965. "REQUESTCANCELLED",
  14966. "INVALPOINTER"
  14967. };
  14968. char *
  14969. PASCAL
  14970. MapResultCodeToText(
  14971. LONG lResult,
  14972. char *pszResult
  14973. )
  14974. {
  14975. if (lResult == 0)
  14976. {
  14977. wsprintfA (pszResult, "SUCCESS");
  14978. }
  14979. else if (lResult > 0)
  14980. {
  14981. wsprintfA (pszResult, "x%x (completing async)", lResult);
  14982. }
  14983. else if (((DWORD) lResult) <= LINEERR_DIALVOICEDETECT)
  14984. {
  14985. lResult &= 0x0fffffff;
  14986. wsprintfA (pszResult, "LINEERR_%s", aszLineErrors[lResult]);
  14987. }
  14988. else if (((DWORD) lResult) <= PHONEERR_REINIT)
  14989. {
  14990. if (((DWORD) lResult) >= PHONEERR_ALLOCATED)
  14991. {
  14992. lResult &= 0x0fffffff;
  14993. wsprintfA (pszResult, "PHONEERR_%s", aszPhoneErrors[lResult]);
  14994. }
  14995. else
  14996. {
  14997. goto MapResultCodeToText_badErrorCode;
  14998. }
  14999. }
  15000. else if (((DWORD) lResult) <= ((DWORD) TAPIERR_DROPPED) &&
  15001. ((DWORD) lResult) >= ((DWORD) TAPIERR_INVALPOINTER))
  15002. {
  15003. lResult = ~lResult + 1;
  15004. wsprintfA (pszResult, "TAPIERR_%s", aszTapiErrors[lResult]);
  15005. }
  15006. else
  15007. {
  15008. MapResultCodeToText_badErrorCode:
  15009. wsprintfA (pszResult, "inval error value (x%x)");
  15010. }
  15011. return pszResult;
  15012. }
  15013. #endif