Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

950 lines
17 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 1996-1998 Microsoft Corporation
  3. Module Name:
  4. tsec.c
  5. Abstract:
  6. A sample administration DLL
  7. Author:
  8. Revision History:
  9. --*/
  10. #include <windows.h>
  11. #include <tapi.h>
  12. #include <tapclntp.h> // private\inc\tapclntp.h
  13. #include <tlnklist.h>
  14. #include "tsec.h"
  15. HINSTANCE ghInst;
  16. LIST_ENTRY gClientListHead;
  17. CRITICAL_SECTION gCritSec;
  18. DEVICECHANGECALLBACK glpfnLineChangeCallback = NULL;
  19. DEVICECHANGECALLBACK glpfnPhoneChangeCallback = NULL;
  20. void
  21. FreeClient(
  22. PMYCLIENT pClient
  23. );
  24. BOOL
  25. WINAPI
  26. DllMain(
  27. HANDLE hDLL,
  28. DWORD dwReason,
  29. LPVOID lpReserved
  30. )
  31. {
  32. switch (dwReason)
  33. {
  34. case DLL_PROCESS_ATTACH:
  35. {
  36. #if DBG
  37. gdwDebugLevel = 0;
  38. #endif
  39. DBGOUT((2, "DLL_PROCESS_ATTACH"));
  40. ghInst = hDLL;
  41. InitializeCriticalSection (&gCritSec);
  42. InitializeListHead (&gClientListHead);
  43. break;
  44. }
  45. case DLL_PROCESS_DETACH:
  46. {
  47. PMYCLIENT pClient;
  48. //
  49. // Clean up client list (no need to enter crit sec since
  50. // process detaching)
  51. //
  52. while (!IsListEmpty (&gClientListHead))
  53. {
  54. LIST_ENTRY *pEntry = RemoveHeadList (&gClientListHead);
  55. pClient = CONTAINING_RECORD (pEntry, MYCLIENT, ListEntry);
  56. FreeClient(pClient);
  57. }
  58. DeleteCriticalSection (&gCritSec);
  59. break;
  60. }
  61. case DLL_THREAD_ATTACH:
  62. case DLL_THREAD_DETACH:
  63. break;
  64. } // switch
  65. return TRUE;
  66. }
  67. void
  68. FreeClient(
  69. PMYCLIENT pClient
  70. )
  71. {
  72. GlobalFree (pClient->pszUserName);
  73. GlobalFree (pClient->pszDomainName);
  74. GlobalFree (pClient->pLineDeviceMap);
  75. GlobalFree (pClient->pPhoneDeviceMap);
  76. GlobalFree (pClient);
  77. }
  78. LONG
  79. GetAndParseAMapping(
  80. LPCWSTR pszFullName,
  81. LPCWSTR pszType,
  82. LPTAPIPERMANENTID *ppDevices,
  83. LPDWORD pdwDevices
  84. )
  85. {
  86. LPWSTR pszDevices = NULL, pszHold1, pszHold2;
  87. DWORD dwSize, dwReturn, dwDevices;
  88. DWORD dwPermanentDeviceID;
  89. BOOL bBreak = FALSE;
  90. dwSize = MAXDEVICESTRINGLEN;
  91. // get the string
  92. do
  93. {
  94. if (pszDevices != NULL)
  95. {
  96. dwSize *= 2;
  97. GlobalFree (pszDevices);
  98. }
  99. pszDevices = (LPWSTR) GlobalAlloc (GPTR, dwSize * sizeof(WCHAR));
  100. if (!pszDevices)
  101. {
  102. return LINEERR_NOMEM;
  103. }
  104. dwReturn = GetPrivateProfileString(
  105. pszFullName,
  106. pszType,
  107. SZEMPTYSTRING,
  108. pszDevices,
  109. dwSize,
  110. SZINIFILE
  111. );
  112. if (dwReturn == 0)
  113. {
  114. // valid case. the user has no
  115. // devices, so just return 0
  116. GlobalFree(pszDevices);
  117. *pdwDevices = 0;
  118. *ppDevices = NULL;
  119. return 0;
  120. }
  121. } while (dwReturn == (dwSize - 1));
  122. // parse the string
  123. //
  124. // the string looks line px, x, py, y,pz, z where x,y and z are
  125. // tapi permanent device IDs, and px, py, and pz are the
  126. // permanent provider IDs for the corresponding devices.
  127. pszHold1 = pszDevices;
  128. dwDevices = 0;
  129. // first, count the ,s so we know how many devices there are
  130. while (*pszHold1 != L'\0')
  131. {
  132. if (*pszHold1 == L',')
  133. {
  134. dwDevices++;
  135. }
  136. pszHold1++;
  137. }
  138. dwDevices++;
  139. dwDevices /= 2;
  140. // alloc line mapping, this is freed later
  141. *ppDevices = (LPTAPIPERMANENTID) GlobalAlloc(
  142. GPTR,
  143. dwDevices * sizeof ( TAPIPERMANENTID )
  144. );
  145. if (!*ppDevices)
  146. {
  147. GlobalFree (pszDevices);
  148. return LINEERR_NOMEM;
  149. }
  150. pszHold1 = pszHold2 = pszDevices;
  151. dwDevices = 0;
  152. // go through string
  153. while (TRUE)
  154. {
  155. // wait for ,
  156. while ((*pszHold2 != L'\0') && *pszHold2 != L',')
  157. {
  158. pszHold2++;
  159. }
  160. if (*pszHold2 == L',')
  161. *pszHold2 = L'\0';
  162. else
  163. {
  164. bBreak = TRUE;
  165. }
  166. // save the id
  167. (*ppDevices)[dwDevices].dwProviderID = _wtol(pszHold1);
  168. // if we hit the end, break out
  169. // note here that this is an unmatched provider id
  170. // but we have inc'ed the dwdevices, so this element will be ignored
  171. if (bBreak)
  172. {
  173. break;
  174. }
  175. pszHold2++;
  176. pszHold1 = pszHold2;
  177. // wait for ,
  178. while ((*pszHold2 != L'\0') && *pszHold2 != L',')
  179. {
  180. pszHold2++;
  181. }
  182. if (*pszHold2 == L',')
  183. {
  184. *pszHold2 = L'\0';
  185. }
  186. else
  187. {
  188. bBreak = TRUE;
  189. }
  190. // save the id
  191. (*ppDevices)[dwDevices].dwDeviceID = _wtol(pszHold1);
  192. dwDevices++;
  193. // if we hit the end, break out
  194. if (bBreak)
  195. {
  196. break;
  197. }
  198. pszHold2++;
  199. pszHold1 = pszHold2;
  200. }
  201. *pdwDevices = dwDevices;
  202. GlobalFree(pszDevices);
  203. return 0; // success
  204. }
  205. LONG
  206. GetMappings(
  207. LPCWSTR pszDomainName,
  208. LPCWSTR pszUserName,
  209. LPTAPIPERMANENTID *ppLineMapping,
  210. LPDWORD pdwLines,
  211. LPTAPIPERMANENTID *ppPhoneMapping,
  212. LPDWORD pdwPhones
  213. )
  214. {
  215. LPWSTR pszFullName;
  216. DWORD dwSize;
  217. LONG lResult;
  218. // put the username and domain name together
  219. // for a full name: domain\user
  220. // in the " + 2" 1 is for \ and 1 is for null terminator
  221. pszFullName = (LPWSTR)GlobalAlloc(
  222. GPTR,
  223. ( lstrlen(pszDomainName) + lstrlen(pszUserName) + 2 ) * sizeof(WCHAR)
  224. );
  225. if (!pszFullName)
  226. {
  227. return LINEERR_NOMEM;
  228. }
  229. // put them together
  230. wsprintf(
  231. pszFullName,
  232. L"%s\\%s",
  233. pszDomainName,
  234. pszUserName
  235. );
  236. if (lResult = GetAndParseAMapping(
  237. pszFullName,
  238. SZLINES,
  239. ppLineMapping,
  240. pdwLines
  241. ))
  242. {
  243. GlobalFree(pszFullName);
  244. return lResult;
  245. }
  246. if (lResult = GetAndParseAMapping(
  247. pszFullName,
  248. SZPHONES,
  249. ppPhoneMapping,
  250. pdwPhones
  251. ))
  252. {
  253. GlobalFree (*ppLineMapping);
  254. GlobalFree (pszFullName);
  255. return lResult;
  256. }
  257. GlobalFree(pszFullName);
  258. return 0;
  259. }
  260. LONG
  261. CLIENTAPI
  262. TAPICLIENT_Load(
  263. LPDWORD pdwAPIVersion,
  264. DEVICECHANGECALLBACK lpfnLineChangeCallback,
  265. DEVICECHANGECALLBACK lpfnPhoneChangeCallback,
  266. DWORD Reserved
  267. )
  268. {
  269. if (*pdwAPIVersion > TAPI_CURRENT_VERSION)
  270. {
  271. *pdwAPIVersion = TAPI_CURRENT_VERSION;
  272. }
  273. glpfnLineChangeCallback = lpfnLineChangeCallback;
  274. glpfnPhoneChangeCallback = lpfnPhoneChangeCallback;
  275. return 0;
  276. }
  277. void
  278. CLIENTAPI
  279. TAPICLIENT_Free(
  280. void
  281. )
  282. {
  283. return;
  284. }
  285. LONG
  286. CLIENTAPI
  287. TAPICLIENT_ClientInitialize(
  288. LPCWSTR pszDomainName,
  289. LPCWSTR pszUserName,
  290. LPCWSTR pszMachineName,
  291. LPHMANAGEMENTCLIENT phmClient
  292. )
  293. {
  294. PMYCLIENT pNewClient;
  295. LPTAPIPERMANENTID pLineMapping, pPhoneMapping;
  296. DWORD dwNumLines, dwNumPhones;
  297. LONG lResult;
  298. // first, get the device mappings
  299. // if this fails, most likely the user
  300. // has access to no lines
  301. if (lResult = GetMappings(
  302. pszDomainName,
  303. pszUserName,
  304. &pLineMapping,
  305. &dwNumLines,
  306. &pPhoneMapping,
  307. &dwNumPhones
  308. ))
  309. {
  310. return lResult;
  311. }
  312. // alloc a client structure
  313. pNewClient = (PMYCLIENT) GlobalAlloc (GPTR, sizeof(MYCLIENT));
  314. if (!pNewClient)
  315. {
  316. return LINEERR_NOMEM;
  317. }
  318. // alloc space for the name
  319. pNewClient->pszUserName = (LPWSTR) GlobalAlloc(
  320. GPTR,
  321. (lstrlen(pszUserName) + 1) * sizeof(WCHAR)
  322. );
  323. if (!pNewClient->pszUserName)
  324. {
  325. GlobalFree(pNewClient);
  326. return LINEERR_NOMEM;
  327. }
  328. pNewClient->pszDomainName = (LPWSTR) GlobalAlloc(
  329. GPTR,
  330. (lstrlen(pszDomainName) +1) * sizeof(WCHAR)
  331. );
  332. if (!pNewClient->pszDomainName)
  333. {
  334. GlobalFree(pNewClient->pszUserName);
  335. GlobalFree(pNewClient);
  336. return LINEERR_NOMEM;
  337. }
  338. // initialize stuff
  339. lstrcpy (pNewClient->pszUserName, pszUserName);
  340. lstrcpy (pNewClient->pszDomainName, pszDomainName);
  341. pNewClient->pLineDeviceMap = pLineMapping;
  342. pNewClient->pPhoneDeviceMap = pPhoneMapping;
  343. pNewClient->dwNumLines = dwNumLines;
  344. pNewClient->dwNumPhones = dwNumPhones;
  345. pNewClient->dwKey = TSECCLIENT_KEY;
  346. // insert into list of clients
  347. EnterCriticalSection (&gCritSec);
  348. InsertHeadList (&gClientListHead, &pNewClient->ListEntry);
  349. LeaveCriticalSection (&gCritSec);
  350. // give TAPI the hmClient
  351. *phmClient = (HMANAGEMENTCLIENT)pNewClient;
  352. return 0;
  353. }
  354. LONG
  355. CLIENTAPI
  356. TAPICLIENT_ClientShutdown(
  357. HMANAGEMENTCLIENT hmClient
  358. )
  359. {
  360. PMYCLIENT pClient;
  361. pClient = (PMYCLIENT) hmClient;
  362. EnterCriticalSection (&gCritSec);
  363. try
  364. {
  365. if (pClient->dwKey == TSECCLIENT_KEY)
  366. {
  367. pClient->dwKey = 0;
  368. RemoveEntryList (&pClient->ListEntry);
  369. }
  370. else
  371. {
  372. pClient = NULL;
  373. }
  374. }
  375. except (EXCEPTION_EXECUTE_HANDLER)
  376. {
  377. pClient = NULL;
  378. }
  379. LeaveCriticalSection (&gCritSec);
  380. if (pClient)
  381. {
  382. FreeClient (pClient);
  383. }
  384. return 0;
  385. }
  386. LONG
  387. CLIENTAPI
  388. TAPICLIENT_GetDeviceAccess(
  389. HMANAGEMENTCLIENT hmClient,
  390. HTAPICLIENT htClient,
  391. LPTAPIPERMANENTID pLineDeviceMap,
  392. PDWORD pdwLineDevices,
  393. LPTAPIPERMANENTID pPhoneDeviceMap,
  394. PDWORD pdwPhoneDevices
  395. )
  396. {
  397. LONG lResult;
  398. PMYCLIENT pClient = (PMYCLIENT) hmClient;
  399. EnterCriticalSection (&gCritSec);
  400. try
  401. {
  402. if (pClient->dwKey != TSECCLIENT_KEY)
  403. {
  404. pClient = NULL;
  405. }
  406. }
  407. except (EXCEPTION_EXECUTE_HANDLER)
  408. {
  409. pClient = NULL;
  410. }
  411. if (pClient)
  412. {
  413. // would need to critical section this stuff
  414. // if we added devices dynamically
  415. if (*pdwLineDevices < pClient->dwNumLines)
  416. {
  417. *pdwLineDevices = pClient->dwNumLines;
  418. lResult = LINEERR_STRUCTURETOOSMALL;
  419. goto LeaveCritSec;
  420. }
  421. CopyMemory(
  422. pLineDeviceMap,
  423. pClient->pLineDeviceMap,
  424. pClient->dwNumLines * sizeof( TAPIPERMANENTID )
  425. );
  426. *pdwLineDevices = pClient->dwNumLines;
  427. if (*pdwPhoneDevices < pClient->dwNumPhones)
  428. {
  429. *pdwPhoneDevices = pClient->dwNumPhones;
  430. lResult = LINEERR_STRUCTURETOOSMALL;
  431. goto LeaveCritSec;
  432. }
  433. CopyMemory(
  434. pPhoneDeviceMap,
  435. pClient->pPhoneDeviceMap,
  436. pClient->dwNumPhones * sizeof( TAPIPERMANENTID )
  437. );
  438. *pdwPhoneDevices = pClient->dwNumPhones;
  439. pClient->htClient = htClient;
  440. lResult = 0;
  441. }
  442. else
  443. {
  444. lResult = LINEERR_INVALPOINTER;
  445. }
  446. LeaveCritSec:
  447. LeaveCriticalSection (&gCritSec);
  448. return lResult;
  449. }
  450. LONG
  451. CLIENTAPI
  452. TAPICLIENT_LineAddToConference(
  453. HMANAGEMENTCLIENT hmClient,
  454. LPTAPIPERMANENTID pID,
  455. LPLINECALLINFO lpConsultCallCallInfo
  456. )
  457. {
  458. return 0;
  459. }
  460. LONG
  461. CLIENTAPI
  462. TAPICLIENT_LineBlindTransfer(
  463. HMANAGEMENTCLIENT hmClient,
  464. LPTAPIPERMANENTID pID,
  465. LPWSTR lpszDestAddress,
  466. LPDWORD lpdwSize,
  467. LPDWORD pdwCountryCodeOut
  468. )
  469. {
  470. return 0;
  471. }
  472. LONG
  473. CLIENTAPI
  474. TAPICLIENT_LineConfigDialog(
  475. HMANAGEMENTCLIENT hmClient,
  476. LPTAPIPERMANENTID pID,
  477. LPCWSTR lpszDeviceClass
  478. )
  479. {
  480. return 0;
  481. }
  482. LONG
  483. CLIENTAPI
  484. TAPICLIENT_LineDial(
  485. HMANAGEMENTCLIENT hmClient,
  486. LPTAPIPERMANENTID pID,
  487. DWORD Reserved,
  488. LPWSTR lpszDestAddressIn,
  489. LPDWORD pdwSize,
  490. LPDWORD pdwCountyCode
  491. )
  492. {
  493. return 0;
  494. }
  495. LONG
  496. CLIENTAPI
  497. TAPICLIENT_LineForward(
  498. HMANAGEMENTCLIENT hmClient,
  499. LPTAPIPERMANENTID pID,
  500. LPLINEFORWARDLIST lpFowardListIn,
  501. LPDWORD pdwSize,
  502. LPLINECALLPARAMS lpCallParamsIn,
  503. LPDWORD pdwParamsSize
  504. )
  505. {
  506. return 0;
  507. }
  508. LONG
  509. CLIENTAPI
  510. TAPICLIENT_LineGenerateDigits(
  511. HMANAGEMENTCLIENT hmClient,
  512. LPTAPIPERMANENTID pID,
  513. DWORD Reserved,
  514. LPCWSTR lpszDigits
  515. )
  516. {
  517. return 0;
  518. }
  519. LONG
  520. CLIENTAPI
  521. TAPICLIENT_LineMakeCall(
  522. HMANAGEMENTCLIENT hmClient,
  523. LPTAPIPERMANENTID pID,
  524. DWORD dwReserved,
  525. LPWSTR lpszDestAddress,
  526. LPDWORD pdwSize,
  527. LPDWORD pdwCountryCode,
  528. LPLINECALLPARAMS lpCallParams,
  529. LPDWORD pdwCallParamsSize
  530. )
  531. {
  532. return 0;
  533. }
  534. LONG
  535. CLIENTAPI
  536. TAPICLIENT_LineOpen(
  537. HMANAGEMENTCLIENT hmClient,
  538. LPTAPIPERMANENTID pID,
  539. DWORD dwAPIVersion,
  540. DWORD dwExtVersion,
  541. DWORD dwPrivileges,
  542. DWORD dwMediaModes,
  543. LPLINECALLPARAMS lpCallParamsIn,
  544. LPDWORD pdwParamsSize
  545. )
  546. {
  547. return 0;
  548. }
  549. LONG
  550. CLIENTAPI
  551. TAPICLIENT_LineRedirect(
  552. HMANAGEMENTCLIENT hmClient,
  553. LPTAPIPERMANENTID pID,
  554. LPWSTR lpszDestAddress,
  555. LPDWORD pdwSize,
  556. LPDWORD pdwCountryCode
  557. )
  558. {
  559. return 0;
  560. }
  561. LONG
  562. CLIENTAPI
  563. TAPICLIENT_LineSetCallData(
  564. HMANAGEMENTCLIENT hmClient,
  565. LPTAPIPERMANENTID pID,
  566. LPVOID lpCallData,
  567. LPDWORD pdwSize
  568. )
  569. {
  570. return 0;
  571. }
  572. LONG
  573. CLIENTAPI
  574. TAPICLIENT_LineSetCallParams(
  575. HMANAGEMENTCLIENT hmClient,
  576. LPTAPIPERMANENTID pID,
  577. DWORD dwBearerMode,
  578. DWORD dwMinRate,
  579. DWORD dwMaxRate,
  580. LPLINEDIALPARAMS lpDialParams
  581. )
  582. {
  583. return 0;
  584. }
  585. LONG
  586. CLIENTAPI
  587. TAPICLIENT_LineSetCallPrivilege(
  588. HMANAGEMENTCLIENT hmClient,
  589. LPTAPIPERMANENTID pID,
  590. DWORD dwCallPrivilege
  591. )
  592. {
  593. return 0;
  594. }
  595. LONG
  596. CLIENTAPI
  597. TAPICLIENT_LineSetCallTreatment(
  598. HMANAGEMENTCLIENT hmClient,
  599. LPTAPIPERMANENTID pID,
  600. DWORD dwCallTreatment
  601. )
  602. {
  603. return 0;
  604. }
  605. LONG
  606. CLIENTAPI
  607. TAPICLIENT_LineSetCurrentLocation(
  608. HMANAGEMENTCLIENT hmClient,
  609. LPTAPIPERMANENTID pID,
  610. LPDWORD dwLocation
  611. )
  612. {
  613. return 0;
  614. }
  615. LONG
  616. CLIENTAPI
  617. TAPICLIENT_LineSetDevConfig(
  618. HMANAGEMENTCLIENT hmClient,
  619. LPTAPIPERMANENTID pID,
  620. LPVOID lpDevConfig,
  621. LPDWORD pdwSize,
  622. LPCWSTR lpszDeviceClass
  623. )
  624. {
  625. return 0;
  626. }
  627. LONG
  628. CLIENTAPI
  629. TAPICLIENT_LineSetLineDevStatus(
  630. HMANAGEMENTCLIENT hmClient,
  631. LPTAPIPERMANENTID pID,
  632. DWORD dwStatusToChange,
  633. DWORD fStatus
  634. )
  635. {
  636. return 0;
  637. }
  638. LONG
  639. CLIENTAPI
  640. TAPICLIENT_LineSetMediaControl(
  641. HMANAGEMENTCLIENT hmClient,
  642. LPTAPIPERMANENTID pID,
  643. LPLINEMEDIACONTROLDIGIT const lpDigitList,
  644. DWORD dwDigitNumEntries,
  645. LPLINEMEDIACONTROLMEDIA const lpMediaList,
  646. DWORD dwMediaNumEntries,
  647. LPLINEMEDIACONTROLTONE const lpToneList,
  648. DWORD dwToneNumEntries,
  649. LPLINEMEDIACONTROLCALLSTATE const lpCallstateList,
  650. DWORD dwCallstateNumEntries
  651. )
  652. {
  653. return 0;
  654. }
  655. LONG
  656. CLIENTAPI
  657. TAPICLIENT_LineSetMediaMode(
  658. HMANAGEMENTCLIENT hmClient,
  659. LPTAPIPERMANENTID pID,
  660. DWORD dwMediaModes
  661. )
  662. {
  663. return 0;
  664. }
  665. LONG
  666. CLIENTAPI
  667. TAPICLIENT_LineSetTerminal(
  668. HMANAGEMENTCLIENT hmClient,
  669. LPTAPIPERMANENTID pID,
  670. DWORD dwTerminalModes,
  671. DWORD dwTerminalID,
  672. BOOL bEnable
  673. )
  674. {
  675. return 0;
  676. }
  677. LONG
  678. CLIENTAPI
  679. TAPICLIENT_LineSetTollList(
  680. HMANAGEMENTCLIENT hmClient,
  681. LPTAPIPERMANENTID pID,
  682. LPCWSTR lpszAddressIn,
  683. DWORD dwTollListOption
  684. )
  685. {
  686. return 0;
  687. }
  688. LONG
  689. CLIENTAPI
  690. TAPICLIENT_PhoneConfigDialog(
  691. HMANAGEMENTCLIENT hmClient,
  692. LPTAPIPERMANENTID pID,
  693. LPCWSTR lpszDeviceClass
  694. )
  695. {
  696. return 0;
  697. }
  698. LONG
  699. CLIENTAPI
  700. TAPICLIENT_PhoneOpen(
  701. HMANAGEMENTCLIENT hmClient,
  702. LPTAPIPERMANENTID pID,
  703. DWORD dwAPIVersion,
  704. DWORD dwExtVersion,
  705. DWORD dwPrivilege
  706. )
  707. {
  708. return LINEERR_OPERATIONFAILED;
  709. }
  710. #if DBG
  711. VOID
  712. DbgPrt(
  713. IN DWORD dwDbgLevel,
  714. IN PUCHAR lpszFormat,
  715. IN ...
  716. )
  717. /*++
  718. Routine Description:
  719. Formats the incoming debug message & calls DbgPrint
  720. Arguments:
  721. DbgLevel - level of message verboseness
  722. DbgMessage - printf-style format string, followed by appropriate
  723. list of arguments
  724. Return Value:
  725. --*/
  726. {
  727. if (dwDbgLevel <= gdwDebugLevel)
  728. {
  729. char buf[128] = "TSEC: ";
  730. va_list ap;
  731. va_start(ap, lpszFormat);
  732. wvsprintfA (&buf[6], lpszFormat, ap);
  733. lstrcatA (buf, "\n");
  734. OutputDebugStringA (buf);
  735. va_end(ap);
  736. }
  737. }
  738. #endif