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.

1151 lines
29 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. mmcmgmt.cpp
  5. Abstract:
  6. Source file module for MMC manipulation
  7. Author:
  8. Xiaohai Zhang (xzhang) 22-March-2000
  9. Revision History:
  10. --*/
  11. #include <stdio.h>
  12. #include "windows.h"
  13. #include "objbase.h"
  14. #include "tapi.h"
  15. #include "mmcmgmt.h"
  16. #include "error.h"
  17. #include "tchar.h"
  18. ///////////////////////////////////////////////////////////
  19. //
  20. // CMMCManagement implementation
  21. //
  22. ///////////////////////////////////////////////////////////
  23. HRESULT CMMCManagement::GetMMCData ()
  24. {
  25. HRESULT hr = S_OK;
  26. DWORD dwAPIVersion = TAPI_CURRENT_VERSION;
  27. DWORD dw, dw1, dw2;
  28. LPDEVICEINFO pDeviceInfo;
  29. TAPISERVERCONFIG cfg;
  30. LINEPROVIDERLIST tapiProviderList = {0};
  31. LPLINEPROVIDERENTRY pProvider;
  32. AVAILABLEPROVIDERLIST tapiAvailProvList = {0};
  33. LPAVAILABLEPROVIDERLIST pAvailProvList = NULL;
  34. AVAILABLEPROVIDERENTRY *pAvailProv;
  35. hr = MMCInitialize (
  36. NULL, // Local computer
  37. &m_hMmc, // HMMCAPP to return
  38. &dwAPIVersion, // API version
  39. NULL
  40. );
  41. if (FAILED(hr) || m_hMmc == NULL)
  42. {
  43. goto ExitHere;
  44. }
  45. // Mark MMC to be busy
  46. cfg.dwTotalSize = sizeof(TAPISERVERCONFIG);
  47. hr = MMCGetServerConfig (m_hMmc, &cfg);
  48. if (FAILED(hr))
  49. {
  50. goto ExitHere;
  51. }
  52. cfg.dwFlags |= TAPISERVERCONFIGFLAGS_LOCKMMCWRITE;
  53. hr = MMCSetServerConfig (m_hMmc, &cfg);
  54. if (FAILED(hr))
  55. {
  56. goto ExitHere;
  57. }
  58. m_bMarkedBusy = TRUE;
  59. // Get the DEVICEINFOLIST structure
  60. m_pDeviceInfoList = (LPDEVICEINFOLIST) new BYTE[sizeof(DEVICEINFOLIST)];
  61. if (m_pDeviceInfoList == NULL)
  62. {
  63. hr = TSECERR_NOMEM;
  64. goto ExitHere;
  65. }
  66. m_pDeviceInfoList->dwTotalSize = sizeof(DEVICEINFOLIST);
  67. hr = MMCGetLineInfo (
  68. m_hMmc,
  69. m_pDeviceInfoList
  70. );
  71. if (FAILED(hr))
  72. {
  73. goto ExitHere;
  74. }
  75. else if (m_pDeviceInfoList->dwNeededSize > m_pDeviceInfoList->dwTotalSize)
  76. {
  77. dw = m_pDeviceInfoList->dwNeededSize;
  78. delete [] m_pDeviceInfoList;
  79. m_pDeviceInfoList = (LPDEVICEINFOLIST) new BYTE[dw];
  80. if (m_pDeviceInfoList == NULL)
  81. {
  82. hr = TSECERR_NOMEM;
  83. goto ExitHere;
  84. }
  85. m_pDeviceInfoList->dwTotalSize = dw;
  86. hr = MMCGetLineInfo (
  87. m_hMmc,
  88. m_pDeviceInfoList
  89. );
  90. if (FAILED(hr))
  91. {
  92. goto ExitHere;
  93. }
  94. }
  95. if (m_pDeviceInfoList->dwNumDeviceInfoEntries == 0)
  96. {
  97. delete [] m_pDeviceInfoList;
  98. if (m_hMmc)
  99. {
  100. cfg.dwFlags &= (~TAPISERVERCONFIGFLAGS_LOCKMMCWRITE);
  101. cfg.dwFlags |= TAPISERVERCONFIGFLAGS_UNLOCKMMCWRITE;
  102. MMCSetServerConfig (m_hMmc, &cfg);
  103. m_bMarkedBusy = FALSE;
  104. MMCShutdown (m_hMmc);
  105. m_hMmc = NULL;
  106. }
  107. goto ExitHere;
  108. }
  109. // Build the user name tuple
  110. m_pUserTuple =
  111. new USERNAME_TUPLE[m_pDeviceInfoList->dwNumDeviceInfoEntries];
  112. if (m_pUserTuple == NULL)
  113. {
  114. hr = TSECERR_NOMEM;
  115. goto ExitHere;
  116. }
  117. pDeviceInfo = (LPDEVICEINFO)(((LPBYTE)m_pDeviceInfoList) +
  118. m_pDeviceInfoList->dwDeviceInfoOffset);
  119. for (dw = 0;
  120. dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
  121. ++dw, ++pDeviceInfo)
  122. {
  123. if (pDeviceInfo->dwDomainUserNamesSize == 0)
  124. {
  125. m_pUserTuple[dw].pDomainUserNames = NULL;
  126. m_pUserTuple[dw].pFriendlyUserNames = NULL;
  127. }
  128. else
  129. {
  130. m_pUserTuple[dw].pDomainUserNames =
  131. (LPTSTR) new BYTE[pDeviceInfo->dwDomainUserNamesSize];
  132. m_pUserTuple[dw].pFriendlyUserNames =
  133. (LPTSTR) new BYTE[pDeviceInfo->dwFriendlyUserNamesSize];
  134. if (m_pUserTuple[dw].pDomainUserNames == NULL ||
  135. m_pUserTuple[dw].pFriendlyUserNames == NULL)
  136. {
  137. hr = TSECERR_NOMEM;
  138. goto ExitHere;
  139. }
  140. memcpy (
  141. m_pUserTuple[dw].pDomainUserNames,
  142. (((LPBYTE)m_pDeviceInfoList) +
  143. pDeviceInfo->dwDomainUserNamesOffset),
  144. pDeviceInfo->dwDomainUserNamesSize
  145. );
  146. memcpy (
  147. m_pUserTuple[dw].pFriendlyUserNames,
  148. (((LPBYTE)m_pDeviceInfoList) +
  149. pDeviceInfo->dwFriendlyUserNamesOffset),
  150. pDeviceInfo->dwFriendlyUserNamesSize
  151. );
  152. }
  153. }
  154. // Get the provider list
  155. tapiProviderList.dwTotalSize = sizeof(LINEPROVIDERLIST);
  156. hr = MMCGetProviderList( m_hMmc, &tapiProviderList);
  157. if (FAILED(hr))
  158. {
  159. goto ExitHere;
  160. }
  161. m_pProviderList = (LPLINEPROVIDERLIST) new BYTE[tapiProviderList.dwNeededSize];
  162. if (NULL == m_pProviderList)
  163. {
  164. hr = TSECERR_NOMEM;
  165. goto ExitHere;
  166. }
  167. memset(m_pProviderList, 0, tapiProviderList.dwNeededSize);
  168. m_pProviderList->dwTotalSize = tapiProviderList.dwNeededSize;
  169. hr = MMCGetProviderList( m_hMmc, m_pProviderList);
  170. if (FAILED(hr) || !m_pProviderList->dwNumProviders)
  171. {
  172. goto ExitHere;
  173. }
  174. // Get the available providers
  175. tapiAvailProvList.dwTotalSize = sizeof(LINEPROVIDERLIST);
  176. hr = MMCGetAvailableProviders (m_hMmc, &tapiAvailProvList);
  177. if (FAILED(hr))
  178. {
  179. goto ExitHere;
  180. }
  181. pAvailProvList = (LPAVAILABLEPROVIDERLIST) new BYTE[tapiAvailProvList.dwNeededSize];
  182. if (NULL == pAvailProvList)
  183. {
  184. hr = TSECERR_NOMEM;
  185. goto ExitHere;
  186. }
  187. memset(pAvailProvList, 0, tapiAvailProvList.dwNeededSize);
  188. pAvailProvList->dwTotalSize = tapiAvailProvList.dwNeededSize;
  189. hr = MMCGetAvailableProviders (m_hMmc, pAvailProvList);
  190. if (FAILED(hr) || !pAvailProvList->dwNumProviderListEntries)
  191. {
  192. delete [] pAvailProvList;
  193. goto ExitHere;
  194. }
  195. m_pProviderName = new LPTSTR[ m_pProviderList->dwNumProviders ];
  196. if (NULL == m_pProviderName)
  197. {
  198. hr = TSECERR_NOMEM;
  199. delete [] pAvailProvList;
  200. goto ExitHere;
  201. }
  202. memset(m_pProviderName, 0, m_pProviderList->dwNumProviders * sizeof (LPTSTR) );
  203. // find providers friendly name
  204. LPTSTR szAvailProvFilename;
  205. LPTSTR szProviderFilename;
  206. LPTSTR szAvailProvFriendlyName;
  207. pProvider = (LPLINEPROVIDERENTRY)
  208. ((LPBYTE) m_pProviderList + m_pProviderList->dwProviderListOffset);
  209. for( dw1=0; dw1 < m_pProviderList->dwNumProviders; dw1++, pProvider++ )
  210. {
  211. szProviderFilename =
  212. (LPTSTR) ((LPBYTE) m_pProviderList + pProvider->dwProviderFilenameOffset);
  213. for ( dw2=0; dw2 < pAvailProvList->dwNumProviderListEntries; dw2++ )
  214. {
  215. pAvailProv = (LPAVAILABLEPROVIDERENTRY)
  216. (( LPBYTE) pAvailProvList + pAvailProvList->dwProviderListOffset) + dw2;
  217. szAvailProvFilename =
  218. (LPTSTR) ((LPBYTE) pAvailProvList + pAvailProv->dwFileNameOffset);
  219. if (_tcsicmp(szAvailProvFilename, szProviderFilename) == 0)
  220. {
  221. szAvailProvFriendlyName =
  222. (LPTSTR) ((LPBYTE) pAvailProvList + pAvailProv->dwFriendlyNameOffset);
  223. m_pProviderName[ dw1 ] = new TCHAR[ _tcslen( szAvailProvFriendlyName ) + 1 ];
  224. if (m_pProviderName[ dw1 ])
  225. {
  226. _tcscpy( m_pProviderName[ dw1 ], szAvailProvFriendlyName );
  227. }
  228. break;
  229. }
  230. }
  231. }
  232. delete [] pAvailProvList;
  233. ExitHere:
  234. if (FAILED(hr))
  235. {
  236. FreeMMCData ();
  237. }
  238. return hr;
  239. }
  240. HRESULT CMMCManagement::FreeMMCData ()
  241. {
  242. DWORD dw;
  243. if (m_pUserTuple && m_pDeviceInfoList)
  244. {
  245. for (dw = 0;
  246. dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
  247. ++dw)
  248. {
  249. if (m_pUserTuple[dw].pDomainUserNames)
  250. {
  251. delete [] m_pUserTuple[dw].pDomainUserNames;
  252. }
  253. if (m_pUserTuple[dw].pFriendlyUserNames)
  254. {
  255. delete [] m_pUserTuple[dw].pFriendlyUserNames;
  256. }
  257. }
  258. delete [] m_pUserTuple;
  259. m_pUserTuple = NULL;
  260. }
  261. if (m_pDeviceInfoList)
  262. {
  263. delete [] m_pDeviceInfoList;
  264. m_pDeviceInfoList = NULL;
  265. }
  266. if (m_pProviderList)
  267. {
  268. delete [] m_pProviderList;
  269. m_pProviderList = NULL;
  270. }
  271. if (m_pProviderName)
  272. {
  273. for ( DWORD dw=0; dw < sizeof( m_pProviderName ) / sizeof(LPTSTR); dw++ )
  274. {
  275. if (m_pProviderName[ dw ])
  276. {
  277. delete [] m_pProviderName[ dw ];
  278. }
  279. }
  280. delete [] m_pProviderName;
  281. }
  282. if (m_bMarkedBusy && m_hMmc)
  283. {
  284. TAPISERVERCONFIG cfg;
  285. cfg.dwTotalSize = sizeof(TAPISERVERCONFIG);
  286. if (S_OK == MMCGetServerConfig (m_hMmc, &cfg))
  287. {
  288. cfg.dwFlags |= TAPISERVERCONFIGFLAGS_UNLOCKMMCWRITE;
  289. MMCSetServerConfig (m_hMmc, &cfg);
  290. }
  291. m_bMarkedBusy = FALSE;
  292. }
  293. if (m_hMmc)
  294. {
  295. MMCShutdown (m_hMmc);
  296. m_hMmc = NULL;
  297. }
  298. return S_OK;
  299. }
  300. HRESULT CMMCManagement::RemoveLinesForUser (LPTSTR szDomainUser)
  301. {
  302. HRESULT hr = S_OK;
  303. LPDWORD adwIndex = NULL;
  304. DWORD dwNumEntries;
  305. DWORD dw;
  306. // Ensure we are properly initialized
  307. if (m_hMmc == NULL)
  308. {
  309. goto ExitHere;
  310. }
  311. hr = FindEntriesForUser (szDomainUser, &adwIndex, &dwNumEntries);
  312. if (hr)
  313. {
  314. goto ExitHere;
  315. }
  316. for (dw = 0; dw < dwNumEntries; ++dw)
  317. {
  318. hr = RemoveEntryForUser (
  319. adwIndex[dw],
  320. szDomainUser
  321. );
  322. if(FAILED(hr))
  323. {
  324. goto ExitHere;
  325. }
  326. }
  327. ExitHere:
  328. if (adwIndex)
  329. {
  330. delete [] adwIndex;
  331. }
  332. return hr;
  333. }
  334. HRESULT CMMCManagement::IsValidPID (
  335. DWORD dwPermanentID
  336. )
  337. {
  338. DWORD dwEntry;
  339. return FindEntryFromPID (dwPermanentID, &dwEntry);
  340. }
  341. HRESULT CMMCManagement::IsValidAddress (
  342. LPTSTR szAddr
  343. )
  344. {
  345. DWORD dwEntry;
  346. return FindEntryFromAddr (szAddr, &dwEntry);
  347. }
  348. HRESULT CMMCManagement::AddLinePIDForUser (
  349. DWORD dwPermanentID,
  350. LPTSTR szDomainUser,
  351. LPTSTR szFriendlyName
  352. )
  353. {
  354. HRESULT hr = S_OK;
  355. DWORD dwEntry;
  356. // Ensure we are properly initialized
  357. if (m_hMmc == NULL)
  358. {
  359. goto ExitHere;
  360. }
  361. hr = FindEntryFromPID (dwPermanentID, &dwEntry);
  362. if (hr)
  363. {
  364. goto ExitHere;
  365. }
  366. hr = AddEntryForUser (dwEntry, szDomainUser, szFriendlyName);
  367. ExitHere:
  368. return hr;
  369. }
  370. HRESULT CMMCManagement::AddLineAddrForUser (
  371. LPTSTR szAddr,
  372. LPTSTR szDomainUser,
  373. LPTSTR szFriendlyName
  374. )
  375. {
  376. HRESULT hr = S_OK;
  377. DWORD dwEntry;
  378. // Ensure we are properly initialized
  379. if (m_hMmc == NULL)
  380. {
  381. goto ExitHere;
  382. }
  383. hr = FindEntryFromAddr (szAddr, &dwEntry);
  384. if (hr)
  385. {
  386. goto ExitHere;
  387. }
  388. hr = AddEntryForUser (dwEntry, szDomainUser, szFriendlyName);
  389. ExitHere:
  390. return hr;
  391. }
  392. HRESULT CMMCManagement::RemoveLinePIDForUser (
  393. DWORD dwPermanentID,
  394. LPTSTR szDomainUser
  395. )
  396. {
  397. HRESULT hr = S_OK;
  398. DWORD dwEntry;
  399. // Ensure we are properly initialized
  400. if (m_hMmc == NULL)
  401. {
  402. goto ExitHere;
  403. }
  404. hr = FindEntryFromPID (dwPermanentID, &dwEntry);
  405. if (hr)
  406. {
  407. goto ExitHere;
  408. }
  409. hr = RemoveEntryForUser (dwEntry, szDomainUser);
  410. ExitHere:
  411. return hr;
  412. }
  413. HRESULT CMMCManagement::RemoveLineAddrForUser (
  414. LPTSTR szAddr,
  415. LPTSTR szDomainUser
  416. )
  417. {
  418. HRESULT hr = S_OK;
  419. DWORD dwEntry;
  420. // Ensure we are properly initialized
  421. if (m_hMmc == NULL)
  422. {
  423. goto ExitHere;
  424. }
  425. hr = FindEntryFromAddr (szAddr, &dwEntry);
  426. if (hr)
  427. {
  428. goto ExitHere;
  429. }
  430. hr = RemoveEntryForUser (dwEntry, szDomainUser);
  431. ExitHere:
  432. return hr;
  433. }
  434. BOOL CMMCManagement::IsDeviceLocalOnly (DWORD dwProviderID, DWORD dwDeviceID)
  435. {
  436. HRESULT hr;
  437. DWORD dwFlags, dwDev;
  438. if (m_pFuncGetDeviceFlags == NULL)
  439. {
  440. return TRUE;
  441. }
  442. hr = (*m_pFuncGetDeviceFlags)(
  443. m_hMmc,
  444. TRUE,
  445. dwProviderID,
  446. dwDeviceID,
  447. &dwFlags,
  448. &dwDev
  449. );
  450. if (hr || dwFlags & LINEDEVCAPFLAGS_LOCAL)
  451. {
  452. return TRUE;
  453. }
  454. else
  455. {
  456. return FALSE;
  457. }
  458. }
  459. HRESULT CMMCManagement::FindEntryFromAddr (LPTSTR szAddr, DWORD * pdwIndex)
  460. {
  461. HRESULT hr = S_FALSE;
  462. DWORD dw;
  463. LPDEVICEINFO pDevInfo;
  464. LPTSTR szAddr2;
  465. pDevInfo = (LPDEVICEINFO) (((LPBYTE)m_pDeviceInfoList) +
  466. m_pDeviceInfoList->dwDeviceInfoOffset);
  467. for (dw = 0;
  468. dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
  469. ++dw, ++pDevInfo)
  470. {
  471. szAddr2 = (LPTSTR)(((LPBYTE)m_pDeviceInfoList) +
  472. pDevInfo->dwAddressesOffset);
  473. while (*szAddr2)
  474. {
  475. if (_tcsicmp (szAddr, szAddr2) == 0)
  476. {
  477. if (IsDeviceLocalOnly (
  478. pDevInfo->dwProviderID,
  479. pDevInfo->dwPermanentDeviceID
  480. ))
  481. {
  482. hr = TSECERR_DEVLOCALONLY;
  483. }
  484. else
  485. {
  486. hr = S_OK;
  487. *pdwIndex = dw;
  488. }
  489. goto ExitHere;
  490. }
  491. szAddr2 += _tcslen (szAddr2) + 1;
  492. }
  493. }
  494. ExitHere:
  495. return hr;
  496. }
  497. HRESULT CMMCManagement::FindEntryFromPID (DWORD dwPID, DWORD * pdwIndex)
  498. {
  499. HRESULT hr = S_FALSE;
  500. DWORD dw;
  501. LPDEVICEINFO pDevInfo;
  502. pDevInfo = (LPDEVICEINFO) (((LPBYTE)m_pDeviceInfoList) +
  503. m_pDeviceInfoList->dwDeviceInfoOffset);
  504. for (dw = 0;
  505. dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
  506. ++dw, ++pDevInfo)
  507. {
  508. if (dwPID == pDevInfo->dwPermanentDeviceID)
  509. {
  510. if (IsDeviceLocalOnly (
  511. pDevInfo->dwProviderID,
  512. pDevInfo->dwPermanentDeviceID
  513. ))
  514. {
  515. hr = TSECERR_DEVLOCALONLY;
  516. }
  517. else
  518. {
  519. *pdwIndex = dw;
  520. hr = S_OK;
  521. }
  522. goto ExitHere;
  523. }
  524. }
  525. ExitHere:
  526. return hr;
  527. }
  528. HRESULT CMMCManagement::FindEntriesForUser (
  529. LPTSTR szDomainUser,
  530. LPDWORD * padwIndex,
  531. DWORD * pdwNumEntries
  532. )
  533. {
  534. HRESULT hr = S_OK;
  535. DWORD dw;
  536. LPTSTR szUsers;
  537. LPDWORD adw;
  538. *padwIndex = NULL;
  539. *pdwNumEntries = 0;
  540. for (dw = 0;
  541. dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
  542. ++dw)
  543. {
  544. szUsers = m_pUserTuple[dw].pDomainUserNames;
  545. while (szUsers && *szUsers)
  546. {
  547. if (_tcsicmp (szDomainUser, szUsers) == 0)
  548. {
  549. hr = S_OK;
  550. adw = new DWORD[*pdwNumEntries + 1];
  551. if (adw == NULL)
  552. {
  553. hr = TSECERR_NOMEM;
  554. goto ExitHere;
  555. }
  556. if (*pdwNumEntries > 0)
  557. {
  558. memcpy (adw, *padwIndex, sizeof(DWORD) * (*pdwNumEntries));
  559. }
  560. if (*padwIndex)
  561. {
  562. delete [] (*padwIndex);
  563. }
  564. *padwIndex = adw;
  565. adw[*pdwNumEntries] = dw;
  566. *pdwNumEntries += 1;
  567. }
  568. szUsers += _tcslen (szUsers) + 1;
  569. }
  570. }
  571. ExitHere:
  572. if (FAILED(hr))
  573. {
  574. *pdwNumEntries = 0;
  575. if (*padwIndex)
  576. {
  577. delete [] (*padwIndex);
  578. }
  579. }
  580. else if (*pdwNumEntries == 0)
  581. {
  582. hr = S_FALSE;
  583. }
  584. return hr;
  585. }
  586. HRESULT CMMCManagement::AddEntryForUser (
  587. DWORD dwIndex,
  588. LPTSTR szDomainUser,
  589. LPTSTR szFriendlyName
  590. )
  591. {
  592. HRESULT hr = S_OK;
  593. DWORD dwSize, dw;
  594. LPTSTR szUsers, szNewUsers = NULL, szNewFriendlyNames = NULL;
  595. if (dwIndex >= m_pDeviceInfoList->dwNumDeviceInfoEntries ||
  596. szDomainUser[0] == 0 ||
  597. szFriendlyName[0] == 0)
  598. {
  599. hr = S_FALSE;
  600. goto ExitHere;
  601. }
  602. //
  603. // Add szDomainUser into the user tuple
  604. //
  605. // Computer the existing domain user size and make sure
  606. // this user is not there already
  607. dwSize = 0;
  608. szUsers = m_pUserTuple[dwIndex].pDomainUserNames;
  609. while (szUsers && *szUsers)
  610. {
  611. if (_tcsicmp (szDomainUser, szUsers) == 0)
  612. {
  613. goto ExitHere;
  614. }
  615. dw = _tcslen (szUsers) + 1;
  616. dwSize += dw;
  617. szUsers += dw;
  618. }
  619. // Extra space for double zero terminating
  620. dw = _tcslen (szDomainUser);
  621. szNewUsers = new TCHAR[dwSize + dw + 2];
  622. if (szNewUsers == NULL)
  623. {
  624. hr = TSECERR_NOMEM;
  625. goto ExitHere;
  626. }
  627. // copy over the old domain users
  628. if (dwSize > 0)
  629. {
  630. memcpy (
  631. szNewUsers,
  632. m_pUserTuple[dwIndex].pDomainUserNames,
  633. dwSize * sizeof(TCHAR)
  634. );
  635. }
  636. // Append the new domain user
  637. memcpy (
  638. szNewUsers + dwSize,
  639. szDomainUser,
  640. (dw + 1) * sizeof(TCHAR)
  641. );
  642. // double zero terminate and assign the data
  643. szNewUsers[dwSize + dw + 1] = 0;
  644. //
  645. // Add the szFriendlyName into the user tuple
  646. //
  647. // Compute the existing friendly names size
  648. dwSize = 0;
  649. szUsers = m_pUserTuple[dwIndex].pFriendlyUserNames;
  650. while (szUsers && *szUsers)
  651. {
  652. dw = _tcslen (szUsers) + 1;
  653. dwSize += dw;
  654. szUsers += dw;
  655. }
  656. // Extra space for double zero terminating
  657. dw = _tcslen (szFriendlyName);
  658. szNewFriendlyNames = new TCHAR[dwSize + dw + 2];
  659. if (szNewFriendlyNames == NULL)
  660. {
  661. hr = TSECERR_NOMEM;
  662. goto ExitHere;
  663. }
  664. // Copy over the old friendly names
  665. if (dwSize > 0)
  666. {
  667. memcpy (
  668. szNewFriendlyNames,
  669. m_pUserTuple[dwIndex].pFriendlyUserNames,
  670. dwSize * sizeof(TCHAR)
  671. );
  672. }
  673. // Append the new friendly name
  674. memcpy (
  675. szNewFriendlyNames + dwSize,
  676. szFriendlyName,
  677. (dw + 1) * sizeof(TCHAR)
  678. );
  679. // Double zero terminate the friend names
  680. szNewFriendlyNames[dwSize + dw + 1] = 0;
  681. //
  682. // Everything is fine, set the new data in
  683. //
  684. if (m_pUserTuple[dwIndex].pDomainUserNames)
  685. {
  686. delete [] m_pUserTuple[dwIndex].pDomainUserNames;
  687. }
  688. m_pUserTuple[dwIndex].pDomainUserNames = szNewUsers;
  689. if (m_pUserTuple[dwIndex].pFriendlyUserNames)
  690. {
  691. delete [] m_pUserTuple[dwIndex].pFriendlyUserNames;
  692. }
  693. m_pUserTuple[dwIndex].pFriendlyUserNames = szNewFriendlyNames;
  694. // Call WriteMMCEntry
  695. hr = WriteMMCEntry (dwIndex);
  696. ExitHere:
  697. return hr;
  698. }
  699. HRESULT CMMCManagement::RemoveEntryForUser (
  700. DWORD dwIndex,
  701. LPTSTR szDomainUser
  702. )
  703. {
  704. HRESULT hr = S_OK;
  705. LPTSTR szLoc, szUsers;
  706. DWORD dwLoc, dw, dwSize;
  707. BOOL bFound;
  708. if (dwIndex >= m_pDeviceInfoList->dwNumDeviceInfoEntries ||
  709. szDomainUser[0] == 0)
  710. {
  711. hr = S_FALSE;
  712. goto ExitHere;
  713. }
  714. // Locate the domain user and its index in the array
  715. // of domain users
  716. szUsers = m_pUserTuple[dwIndex].pDomainUserNames;
  717. dwLoc = 0;
  718. dwSize = 0;
  719. bFound = FALSE;
  720. while (szUsers && *szUsers)
  721. {
  722. dw = _tcslen (szUsers) + 1;
  723. if (bFound)
  724. {
  725. dwSize += dw;
  726. }
  727. else
  728. {
  729. if (_tcsicmp (szDomainUser, szUsers) == 0)
  730. {
  731. bFound = TRUE;
  732. szLoc = szUsers;
  733. }
  734. else
  735. {
  736. ++dwLoc;
  737. }
  738. }
  739. szUsers += dw;
  740. }
  741. if (!bFound)
  742. {
  743. goto ExitHere;
  744. }
  745. // Move down the pszDomainUserNames
  746. if (dwSize > 0)
  747. {
  748. dw = _tcslen (szDomainUser);
  749. // Memory copy includes the double zero terminator
  750. memmove (szLoc, szLoc + dw + 1, (dwSize + 1) * sizeof(TCHAR));
  751. }
  752. else
  753. {
  754. // The is the last item, simple double zero terminate
  755. *szLoc = 0;
  756. }
  757. // Now find corresponding friendly name based on dwLoc
  758. szUsers = m_pUserTuple[dwIndex].pFriendlyUserNames;
  759. while (szUsers && *szUsers && dwLoc > 0)
  760. {
  761. --dwLoc;
  762. szUsers += _tcslen (szUsers) + 1;
  763. }
  764. // bail if not exist, otherwise, remember the location
  765. if (szUsers == NULL || *szUsers == 0)
  766. {
  767. goto ExitHere;
  768. }
  769. szLoc = szUsers;
  770. // Go to the next item
  771. szUsers += _tcslen (szUsers) + 1;
  772. // This is the last item
  773. if (*szUsers == 0)
  774. {
  775. *szLoc = 0;
  776. }
  777. // Otherwise compute the remaining size to move
  778. else
  779. {
  780. dwSize = 0;
  781. while (*szUsers)
  782. {
  783. dw = _tcslen (szUsers) + 1;
  784. dwSize += dw;
  785. szUsers += dw;
  786. }
  787. // Compensate for the double zero terminating
  788. dwSize++;
  789. // Do the memory move
  790. memmove (
  791. szLoc,
  792. szLoc + _tcslen (szLoc) + 1,
  793. dwSize * sizeof(TCHAR)
  794. );
  795. }
  796. // Call WriteMMCEntry
  797. hr = WriteMMCEntry (dwIndex);
  798. ExitHere:
  799. return hr;
  800. }
  801. HRESULT CMMCManagement::WriteMMCEntry (DWORD dwIndex)
  802. {
  803. HRESULT hr = S_OK;
  804. DWORD dwSize, dwSizeDU, dwSizeFU;
  805. LPUSERNAME_TUPLE pUserTuple;
  806. LPTSTR szUsers;
  807. DWORD dw;
  808. LPDEVICEINFOLIST pDevList = NULL;
  809. LPDEVICEINFO pDevInfo, pDevInfoOld;
  810. LPBYTE pDest;
  811. if (dwIndex >= m_pDeviceInfoList->dwNumDeviceInfoEntries)
  812. {
  813. hr = S_FALSE;
  814. goto ExitHere;
  815. }
  816. pUserTuple = m_pUserTuple + dwIndex;
  817. // Computer domain user name size
  818. dwSizeDU = 0;
  819. if (pUserTuple->pDomainUserNames != NULL &&
  820. *pUserTuple->pDomainUserNames != 0)
  821. {
  822. szUsers = pUserTuple->pDomainUserNames;
  823. while (*szUsers)
  824. {
  825. dw = _tcslen (szUsers) + 1;
  826. szUsers += dw;
  827. dwSizeDU += dw;
  828. }
  829. dwSizeDU++; // double zero terminator
  830. }
  831. // Computer the friendly user name size
  832. dwSizeFU = 0;
  833. if (pUserTuple->pFriendlyUserNames != NULL &&
  834. *pUserTuple->pFriendlyUserNames != 0)
  835. {
  836. szUsers = pUserTuple->pFriendlyUserNames;
  837. while (*szUsers)
  838. {
  839. dw = _tcslen (szUsers) + 1;
  840. szUsers += dw;
  841. dwSizeFU += dw;
  842. }
  843. dwSizeFU++; // double zero terminator
  844. }
  845. // Computer the total size
  846. dwSize = sizeof(DEVICEINFOLIST) + sizeof(DEVICEINFO) +
  847. (dwSizeDU + dwSizeFU) * sizeof(TCHAR);
  848. // Allocate the structure
  849. pDevList = (LPDEVICEINFOLIST) new BYTE[dwSize];
  850. if (pDevList == NULL)
  851. {
  852. hr = TSECERR_NOMEM;
  853. goto ExitHere;
  854. }
  855. // Set the data member of DEVICEINFOLIST
  856. pDevList->dwTotalSize = dwSize;
  857. pDevList->dwNeededSize = dwSize;
  858. pDevList->dwUsedSize = dwSize;
  859. pDevList->dwNumDeviceInfoEntries = 1;
  860. pDevList->dwDeviceInfoSize = sizeof(DEVICEINFO);
  861. pDevList->dwDeviceInfoOffset = sizeof(DEVICEINFOLIST);
  862. // Set the member of DEVICEINFO
  863. pDevInfo = (LPDEVICEINFO)(((LPBYTE)pDevList) +
  864. pDevList->dwDeviceInfoOffset);
  865. pDevInfoOld = (LPDEVICEINFO)(((LPBYTE)m_pDeviceInfoList) +
  866. m_pDeviceInfoList->dwDeviceInfoOffset) + dwIndex;
  867. memset (pDevInfo, 0, sizeof(DEVICEINFO));
  868. pDevInfo->dwPermanentDeviceID = pDevInfoOld->dwPermanentDeviceID;
  869. pDevInfo->dwProviderID = pDevInfoOld->dwProviderID;
  870. if (dwSizeDU > 0)
  871. {
  872. pDevInfo->dwDomainUserNamesSize = dwSizeDU * sizeof(TCHAR);
  873. pDevInfo->dwDomainUserNamesOffset =
  874. sizeof(DEVICEINFOLIST) + sizeof(DEVICEINFO);
  875. pDest = ((LPBYTE)pDevList) + pDevInfo->dwDomainUserNamesOffset;
  876. memcpy (
  877. pDest,
  878. pUserTuple->pDomainUserNames,
  879. dwSizeDU * sizeof(TCHAR)
  880. );
  881. }
  882. if (dwSizeFU)
  883. {
  884. pDevInfo->dwFriendlyUserNamesSize = dwSizeFU * sizeof(TCHAR);
  885. pDevInfo->dwFriendlyUserNamesOffset =
  886. pDevInfo->dwDomainUserNamesOffset + dwSizeDU * sizeof(TCHAR);
  887. pDest = ((LPBYTE)pDevList) + pDevInfo->dwFriendlyUserNamesOffset;
  888. memcpy (
  889. pDest,
  890. pUserTuple->pFriendlyUserNames,
  891. dwSizeFU * sizeof(TCHAR)
  892. );
  893. }
  894. hr = MMCSetLineInfo (
  895. m_hMmc,
  896. pDevList
  897. );
  898. ExitHere:
  899. if (pDevList)
  900. {
  901. delete [] pDevList;
  902. }
  903. return hr;
  904. }
  905. HRESULT CMMCManagement::DisplayMMCData ()
  906. {
  907. HRESULT hr = S_OK;
  908. LPDEVICEINFO pDeviceInfo;
  909. DWORD * pdwIndex = NULL;
  910. DWORD dwProviderId;
  911. DWORD dwAddressCount,dw1,dw2;
  912. LPLINEPROVIDERENTRY pProvider;
  913. LPTSTR pUserName;
  914. LPTSTR pAddress,
  915. pAddressFirst,
  916. pAddressLast;
  917. if ( !m_pDeviceInfoList || !m_pDeviceInfoList->dwNumDeviceInfoEntries )
  918. {
  919. CIds IdsNoDevices (IDS_NODEVICES);
  920. _tprintf ( IdsNoDevices.GetString () );
  921. return hr;
  922. }
  923. //
  924. // Build an index by provider ID
  925. //
  926. pdwIndex = new DWORD [ m_pDeviceInfoList->dwNumDeviceInfoEntries ];
  927. if ( !pdwIndex )
  928. {
  929. hr = TSECERR_NOMEM;
  930. return hr;
  931. }
  932. for ( dw1=0; dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries; dw1++ )
  933. {
  934. pdwIndex[ dw1 ] = dw1;
  935. }
  936. dw1 = 0;
  937. while ( dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries )
  938. {
  939. pDeviceInfo = (LPDEVICEINFO)((LPBYTE)m_pDeviceInfoList +
  940. m_pDeviceInfoList->dwDeviceInfoOffset) + pdwIndex[ dw1 ];
  941. dwProviderId = pDeviceInfo->dwProviderID;
  942. dw1++;
  943. for ( dw2=dw1; dw2 < m_pDeviceInfoList->dwNumDeviceInfoEntries; dw2++ )
  944. {
  945. pDeviceInfo = (LPDEVICEINFO)((LPBYTE)m_pDeviceInfoList +
  946. m_pDeviceInfoList->dwDeviceInfoOffset) + pdwIndex[ dw2 ];
  947. if ( dwProviderId == pDeviceInfo->dwProviderID )
  948. {
  949. DWORD dwTemp = pdwIndex[ dw2 ];
  950. pdwIndex[ dw2 ] = pdwIndex[ dw1 ];
  951. pdwIndex[ dw1 ] = dwTemp;
  952. dw1++;
  953. }
  954. }
  955. }
  956. //
  957. // Display the device list
  958. //
  959. dw1 = 0;
  960. while ( dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries )
  961. {
  962. pDeviceInfo = (LPDEVICEINFO)((LPBYTE)m_pDeviceInfoList +
  963. m_pDeviceInfoList->dwDeviceInfoOffset) + pdwIndex[ dw1 ];
  964. dwProviderId = pDeviceInfo->dwProviderID;
  965. // find the provider entry
  966. pProvider = (LPLINEPROVIDERENTRY) ((LPBYTE) m_pProviderList + m_pProviderList->dwProviderListOffset);
  967. for( dw2=0; dw2 < m_pProviderList->dwNumProviders; dw2++, pProvider++ )
  968. {
  969. if ( dwProviderId == pProvider->dwPermanentProviderID )
  970. {
  971. break;
  972. }
  973. }
  974. // display the provider name
  975. if ( dw2 < m_pProviderList->dwNumProviders )
  976. {
  977. // provider entry found
  978. _tprintf(
  979. _T("\n%s\n"),
  980. m_pProviderName[ dw2 ] ? m_pProviderName[ dw2 ] :
  981. (LPTSTR)((LPBYTE) m_pProviderList + pProvider->dwProviderFilenameOffset)
  982. );
  983. }
  984. else
  985. {
  986. CIds IdsProvider (IDS_PROVIDER);
  987. _tprintf( IdsProvider.GetString(), dwProviderId );
  988. }
  989. // list devices / users for this provider
  990. do
  991. {
  992. CIds IdsLine (IDS_LINE);
  993. CIds IdsPermanentID (IDS_PID);
  994. CIds IdsAddresses (IDS_ADDRESSES);
  995. _tprintf( IdsLine.GetString(),
  996. (LPTSTR)((LPBYTE)m_pDeviceInfoList + pDeviceInfo->dwDeviceNameOffset));
  997. _tprintf( IdsPermanentID.GetString(), pDeviceInfo->dwPermanentDeviceID);
  998. if ( pDeviceInfo->dwFriendlyUserNamesSize )
  999. {
  1000. CIds IdsUsers (IDS_USERS);
  1001. _tprintf ( IdsUsers.GetString () );
  1002. pUserName = (LPTSTR) (((LPBYTE) m_pDeviceInfoList) +
  1003. pDeviceInfo->dwFriendlyUserNamesOffset);
  1004. while ( *pUserName != _T('\0') )
  1005. {
  1006. _tprintf( _T("\t\t\t%s\n"), pUserName );
  1007. pUserName += _tcslen (pUserName) + 1;
  1008. }
  1009. }
  1010. if ( pDeviceInfo->dwAddressesSize )
  1011. {
  1012. _tprintf( IdsAddresses.GetString() );
  1013. pAddress = (LPTSTR) (((LPBYTE) m_pDeviceInfoList) +
  1014. pDeviceInfo->dwAddressesOffset);
  1015. while ( *pAddress != _T('\0') )
  1016. {
  1017. _tprintf( _T("\t\t\t%s\n"), pAddress );
  1018. pAddress += _tcslen (pAddress) + 1;
  1019. }
  1020. }
  1021. dw1++;
  1022. pDeviceInfo++;
  1023. }
  1024. while ( dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries &&
  1025. pDeviceInfo->dwProviderID == dwProviderId );
  1026. }
  1027. return hr;
  1028. }