Leaked source code of windows server 2003
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.

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