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.

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