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.

1078 lines
27 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. infopriv.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "infoi.h"
  11. #include "rtrstr.h" // common router strings
  12. #include "rtrdata.h" // CRouterDataObject
  13. #include "setupapi.h" // SetupDi* functions
  14. static const GUID GUID_DevClass_Net = {0x4D36E972,0xE325,0x11CE,{0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18}};
  15. typedef DWORD (APIENTRY* PRASRPCCONNECTSERVER)(LPTSTR, HANDLE *);
  16. typedef DWORD (APIENTRY* PRASRPCDISCONNECTSERVER)(HANDLE);
  17. typedef DWORD (APIENTRY* PRASRPCREMOTEGETSYSTEMDIRECTORY)(HANDLE, LPTSTR, UINT);
  18. typedef DWORD (APIENTRY* PRASRPCREMOTERASDELETEENTRY)(HANDLE, LPTSTR, LPTSTR);
  19. HRESULT RasPhoneBookRemoveInterface(LPCTSTR pszMachine, LPCTSTR pszIf)
  20. {
  21. CString stPath;
  22. DWORD dwErr;
  23. HINSTANCE hrpcdll = NULL;
  24. TCHAR szSysDir[MAX_PATH+1];
  25. PRASRPCCONNECTSERVER pRasRpcConnectServer;
  26. PRASRPCDISCONNECTSERVER pRasRpcDisconnectServer;
  27. PRASRPCREMOTEGETSYSTEMDIRECTORY pRasRpcRemoteGetSystemDirectory;
  28. PRASRPCREMOTERASDELETEENTRY pRasRpcRemoteRasDeleteEntry;
  29. HANDLE hConnection = NULL;
  30. if (!(hrpcdll = LoadLibrary(TEXT("rasman.dll"))) ||
  31. !(pRasRpcConnectServer = (PRASRPCCONNECTSERVER)GetProcAddress(
  32. hrpcdll, "RasRpcConnectServer"
  33. )) ||
  34. !(pRasRpcDisconnectServer = (PRASRPCDISCONNECTSERVER)GetProcAddress(
  35. hrpcdll, "RasRpcDisconnectServer"
  36. )) ||
  37. !(pRasRpcRemoteGetSystemDirectory =
  38. (PRASRPCREMOTEGETSYSTEMDIRECTORY)GetProcAddress(
  39. hrpcdll, "RasRpcRemoteGetSystemDirectory"
  40. )) ||
  41. !(pRasRpcRemoteRasDeleteEntry =
  42. (PRASRPCREMOTERASDELETEENTRY)GetProcAddress(
  43. hrpcdll, "RasRpcRemoteRasDeleteEntry"
  44. )))
  45. {
  46. if (hrpcdll) { FreeLibrary(hrpcdll); }
  47. return hrOK;
  48. }
  49. dwErr = pRasRpcConnectServer((LPTSTR)pszMachine, &hConnection);
  50. if (dwErr == NO_ERROR)
  51. {
  52. szSysDir[0] = TEXT('\0');
  53. //$ Review: kennt, are these functions WIDE or ANSI?
  54. // We can't just pass in TCHARs. Since we're dynamically
  55. // linking to these functions we need to know.
  56. // This is bogus, if this call fails we don't know what to do
  57. pRasRpcRemoteGetSystemDirectory(hConnection, szSysDir, MAX_PATH);
  58. stPath.Format(TEXT("%s\\RAS\\%s"), szSysDir, c_szRouterPbk);
  59. dwErr = pRasRpcRemoteRasDeleteEntry(
  60. hConnection,
  61. (LPTSTR)(LPCTSTR)stPath,
  62. (LPTSTR)(LPCTSTR)pszIf
  63. );
  64. pRasRpcDisconnectServer(hConnection);
  65. }
  66. if (hrpcdll)
  67. FreeLibrary(hrpcdll);
  68. return HRESULT_FROM_WIN32(dwErr);
  69. }
  70. /*---------------------------------------------------------------------------
  71. CNetcardRegistryHelper implemenation
  72. ---------------------------------------------------------------------------*/
  73. /*!--------------------------------------------------------------------------
  74. CNetcardRegistryHelper::CNetcardRegistryHelper
  75. -
  76. Author: KennT
  77. ---------------------------------------------------------------------------*/
  78. CNetcardRegistryHelper::CNetcardRegistryHelper()
  79. : m_hkeyBase(NULL),
  80. m_hkeyService(NULL),
  81. m_hkeyTitle(NULL),
  82. m_hkeyConnection(NULL),
  83. m_fInit(FALSE),
  84. m_fNt4(FALSE),
  85. m_hDevInfo(INVALID_HANDLE_VALUE)
  86. {
  87. }
  88. /*!--------------------------------------------------------------------------
  89. CNetcardRegistryHelper::~CNetcardRegistryHelper
  90. -
  91. Author: KennT
  92. ---------------------------------------------------------------------------*/
  93. CNetcardRegistryHelper::~CNetcardRegistryHelper()
  94. {
  95. FreeDevInfo();
  96. if (m_hkeyTitle && (m_hkeyTitle != m_hkeyBase))
  97. ::RegCloseKey(m_hkeyTitle);
  98. if (m_hkeyService && (m_hkeyService != m_hkeyBase))
  99. ::RegCloseKey(m_hkeyService);
  100. if (m_hkeyConnection)
  101. ::RegCloseKey(m_hkeyConnection);
  102. }
  103. void CNetcardRegistryHelper::FreeDevInfo()
  104. {
  105. if (m_hDevInfo != INVALID_HANDLE_VALUE)
  106. {
  107. SetupDiDestroyDeviceInfoList(m_hDevInfo);
  108. m_hDevInfo = INVALID_HANDLE_VALUE;
  109. }
  110. }
  111. /*!--------------------------------------------------------------------------
  112. CNetcardRegistryHelper::Initialize
  113. -
  114. Author: KennT
  115. ---------------------------------------------------------------------------*/
  116. void CNetcardRegistryHelper::Initialize(BOOL fNt4, HKEY hkeyBase, LPCTSTR pszKeyBase, LPCTSTR pszMachineName)
  117. {
  118. m_fNt4 = fNt4;
  119. m_hkeyBase = hkeyBase;
  120. m_hkeyService = NULL;
  121. m_hkeyTitle = NULL;
  122. m_fInit = FALSE;
  123. m_stService.Empty();
  124. m_stTitle.Empty();
  125. m_stKeyBase = pszKeyBase;
  126. m_stMachineName.Empty();
  127. // Get the connection registry key
  128. if (!m_fNt4 && hkeyBase)
  129. {
  130. if (m_hkeyConnection != NULL)
  131. {
  132. RegCloseKey(m_hkeyConnection);
  133. m_hkeyConnection = NULL;
  134. }
  135. if (RegOpenKey(hkeyBase, c_szRegKeyConnection, &m_hkeyConnection)
  136. != ERROR_SUCCESS)
  137. {
  138. m_hkeyConnection = NULL;
  139. }
  140. }
  141. // Get up the setup api info
  142. if (!m_fNt4)
  143. {
  144. FreeDevInfo();
  145. if (IsLocalMachine(pszMachineName))
  146. {
  147. m_hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DevClass_Net, NULL);
  148. }
  149. else
  150. {
  151. if (StrniCmp(pszMachineName, _T("\\\\"), 2) != 0)
  152. {
  153. m_stMachineName = _T("\\\\");
  154. m_stMachineName += pszMachineName;
  155. }
  156. else
  157. m_stMachineName = pszMachineName;
  158. m_hDevInfo = SetupDiCreateDeviceInfoListEx(
  159. (LPGUID) &GUID_DevClass_Net,
  160. NULL,
  161. (LPCTSTR) m_stMachineName,
  162. 0);
  163. }
  164. }
  165. }
  166. /*!--------------------------------------------------------------------------
  167. CNetcardRegistryHelper::ReadServiceName
  168. -
  169. Author: KennT
  170. ---------------------------------------------------------------------------*/
  171. DWORD CNetcardRegistryHelper::ReadServiceName()
  172. {
  173. DWORD dwErr = ERROR_SUCCESS;
  174. LPCTSTR pszService;
  175. dwErr = PrivateInit();
  176. if (dwErr != ERROR_SUCCESS)
  177. return dwErr;
  178. Assert(m_fNt4);
  179. pszService = m_fNt4 ? c_szServiceName : c_szService;
  180. dwErr = ReadRegistryCString(_T(""), pszService,
  181. m_hkeyService, &m_stService);
  182. return dwErr;
  183. }
  184. /*!--------------------------------------------------------------------------
  185. CNetcardRegistryHelper::GetServiceName
  186. -
  187. Author: KennT
  188. ---------------------------------------------------------------------------*/
  189. LPCTSTR CNetcardRegistryHelper::GetServiceName()
  190. {
  191. ASSERT(m_fInit);
  192. return m_stService;
  193. }
  194. /*!--------------------------------------------------------------------------
  195. CNetcardRegistryHelper::ReadTitle
  196. -
  197. Author: KennT
  198. ---------------------------------------------------------------------------*/
  199. DWORD CNetcardRegistryHelper::ReadTitle()
  200. {
  201. DWORD dwErr = ERROR_SUCCESS;
  202. CString stTemp;
  203. TCHAR szDesc[1024];
  204. dwErr = PrivateInit();
  205. if (dwErr != ERROR_SUCCESS)
  206. return dwErr;
  207. if (m_fNt4)
  208. {
  209. dwErr = ReadRegistryCString(_T(""), c_szTitle,
  210. m_hkeyTitle, &stTemp);
  211. if (dwErr == ERROR_SUCCESS)
  212. m_stTitle = stTemp;
  213. }
  214. else
  215. {
  216. //$NT5
  217. SPMprConfigHandle sphConfig;
  218. LPWSTR pswz;
  219. if (m_stMachineName.IsEmpty())
  220. pswz = NULL;
  221. else
  222. pswz = (LPTSTR) (LPCTSTR) m_stMachineName;
  223. dwErr = ::MprConfigServerConnect(pswz,
  224. &sphConfig);
  225. if (dwErr == ERROR_SUCCESS)
  226. dwErr = ::MprConfigGetFriendlyName(sphConfig,
  227. T2W((LPTSTR)(LPCTSTR)m_stKeyBase),
  228. szDesc,
  229. sizeof(szDesc));
  230. m_stTitle = szDesc;
  231. }
  232. //Error:
  233. return dwErr;
  234. }
  235. /*!--------------------------------------------------------------------------
  236. CNetcardRegistryHelper::GetTitle
  237. -
  238. Author: KennT
  239. ---------------------------------------------------------------------------*/
  240. LPCTSTR CNetcardRegistryHelper::GetTitle()
  241. {
  242. Assert(m_fInit);
  243. return m_stTitle;
  244. }
  245. /*!--------------------------------------------------------------------------
  246. CNetcardRegistryHelper::ReadDeviceName
  247. -
  248. Author: KennT
  249. ---------------------------------------------------------------------------*/
  250. DWORD CNetcardRegistryHelper::ReadDeviceName()
  251. {
  252. SP_DEVINFO_DATA DevInfo;
  253. CString stPnpInstanceID;
  254. DWORD dwType = REG_SZ;
  255. TCHAR szDesc[1024];
  256. DWORD dwErr = ERROR_SUCCESS;
  257. if (m_fNt4)
  258. {
  259. if (m_stTitle.IsEmpty())
  260. dwErr = ReadTitle();
  261. m_stDeviceName = m_stTitle;
  262. }
  263. else
  264. {
  265. //$NT5
  266. // For NT5, we have a much harder time, since this involves
  267. // multiple lookups
  268. // Windows NT Bug : ?
  269. // The New Binding Engine changed some of the keys around,
  270. // We neet do look at the
  271. // HKLM\SYSTEM\CCS\Control\Network\{GUID_DEVCLASS_NET}\{netcard guid}\Connection
  272. // From this subkey get the PnpInstanceID
  273. if (m_hkeyConnection)
  274. dwErr = ReadRegistryCString(_T("HKLM\\SYSTEM\\CCS\\Control\\Network\\{GID_DEVCLASS_NET}\\{netcard guid}\\Connection"),
  275. c_szPnpInstanceID,
  276. m_hkeyConnection,
  277. &stPnpInstanceID);
  278. // ok, the base key is
  279. // HKLM\SYSTEM\CCS\Control\Network\{GUID_DEVCLASS_NET}\{netcard guid}
  280. // From this subkey get the PnpInstanceID
  281. if (dwErr != ERROR_SUCCESS)
  282. dwErr = ReadRegistryCString(_T("HKLM\\SYSTEM\\CCS\\Control\\Network\\{GID_DEVCLASS_NET}\\{netcard guid}"),
  283. c_szPnpInstanceID,
  284. m_hkeyBase,
  285. &stPnpInstanceID);
  286. if (dwErr != ERROR_SUCCESS)
  287. goto Error;
  288. // Initialize the structure
  289. ::ZeroMemory(&DevInfo, sizeof(DevInfo));
  290. DevInfo.cbSize = sizeof(DevInfo);
  291. if (!SetupDiOpenDeviceInfo(m_hDevInfo,
  292. (LPCTSTR) stPnpInstanceID,
  293. NULL,
  294. 0,
  295. &DevInfo
  296. ))
  297. {
  298. dwErr = GetLastError();
  299. goto Error;
  300. }
  301. // Try to get the friendly name first
  302. if (!SetupDiGetDeviceRegistryProperty(m_hDevInfo,
  303. &DevInfo,
  304. SPDRP_FRIENDLYNAME,
  305. &dwType,
  306. (LPBYTE) szDesc,
  307. sizeof(szDesc),
  308. NULL
  309. ))
  310. {
  311. // If we fail to get the friendly name, try to
  312. // get the device description instead.
  313. if (!SetupDiGetDeviceRegistryProperty(m_hDevInfo,
  314. &DevInfo,
  315. SPDRP_DEVICEDESC,
  316. &dwType,
  317. (LPBYTE) szDesc,
  318. sizeof(szDesc),
  319. NULL
  320. ))
  321. {
  322. dwErr = GetLastError();
  323. goto Error;
  324. }
  325. }
  326. m_stDeviceName = szDesc;
  327. }
  328. Error:
  329. return dwErr;
  330. }
  331. /*!--------------------------------------------------------------------------
  332. CNetcardRegistryHelper::GetDeviceName
  333. -
  334. Author: KennT
  335. ---------------------------------------------------------------------------*/
  336. LPCTSTR CNetcardRegistryHelper::GetDeviceName()
  337. {
  338. Assert(m_fInit);
  339. return m_stDeviceName;
  340. }
  341. /*!--------------------------------------------------------------------------
  342. CNetcardRegistryHelper::PrivateInit
  343. -
  344. Author: KennT
  345. ---------------------------------------------------------------------------*/
  346. DWORD CNetcardRegistryHelper::PrivateInit()
  347. {
  348. DWORD dwErr = ERROR_SUCCESS;
  349. if (m_fInit)
  350. return ERROR_SUCCESS;
  351. m_fInit = TRUE;
  352. if (m_fNt4)
  353. {
  354. // For NT4, we don't need to do anything, we are at the
  355. // place where we want to read the data
  356. m_hkeyService = m_hkeyBase;
  357. m_hkeyTitle = m_hkeyBase;
  358. }
  359. else
  360. {
  361. // We don't need m_hkeyService for NT5
  362. m_hkeyService = NULL;
  363. m_hkeyTitle = NULL;
  364. }
  365. //Error:
  366. if (dwErr != ERROR_SUCCESS)
  367. {
  368. if (m_hkeyService)
  369. ::RegCloseKey(m_hkeyService);
  370. m_hkeyService = NULL;
  371. if (m_hkeyTitle)
  372. ::RegCloseKey(m_hkeyTitle);
  373. m_hkeyTitle = NULL;
  374. m_fInit = FALSE;
  375. }
  376. return dwErr;
  377. }
  378. /*!--------------------------------------------------------------------------
  379. CNetcardRegistryHelper::ReadRegistryCString
  380. -
  381. Author: KennT
  382. ---------------------------------------------------------------------------*/
  383. DWORD CNetcardRegistryHelper::ReadRegistryCString(
  384. LPCTSTR pszKey,
  385. LPCTSTR pszValue,
  386. HKEY hkey,
  387. CString *pstDest)
  388. {
  389. DWORD dwSize, dwType;
  390. DWORD dwErr = ERROR_SUCCESS;
  391. ASSERT(pstDest);
  392. dwSize = 0;
  393. dwErr = ::RegQueryValueEx(hkey,
  394. pszValue,
  395. NULL,
  396. &dwType,
  397. NULL,
  398. &dwSize);
  399. CheckRegQueryValueError(dwErr, pszKey, pszValue, TEXT("CNetcardRegistryHelper::ReadRegistryCString"));
  400. if (dwErr != ERROR_SUCCESS)
  401. goto Error;
  402. ASSERT(dwType == REG_SZ);
  403. // Increase size to handle terminating NULL
  404. dwSize ++;
  405. dwErr = ::RegQueryValueEx(hkey,
  406. pszValue,
  407. NULL,
  408. &dwType,
  409. (LPBYTE) pstDest->GetBuffer(dwSize),
  410. &dwSize);
  411. pstDest->ReleaseBuffer();
  412. CheckRegQueryValueError(dwErr, pszKey, pszValue, _T("CNetcardRegistryHelper::ReadRegistryCString"));
  413. if (dwErr != ERROR_SUCCESS)
  414. goto Error;
  415. Error:
  416. return dwErr;
  417. }
  418. CWeakRef::CWeakRef()
  419. : m_cRef(1),
  420. m_cRefWeak(0),
  421. m_fStrongRef(TRUE),
  422. m_fDestruct(FALSE),
  423. m_fInShutdown(FALSE)
  424. {
  425. }
  426. STDMETHODIMP_(ULONG) CWeakRef::AddRef()
  427. {
  428. ULONG ulReturn;
  429. Assert(m_cRef >= m_cRefWeak);
  430. ulReturn = InterlockedIncrement(&m_cRef);
  431. if (!m_fStrongRef)
  432. {
  433. m_fStrongRef = TRUE;
  434. ReviveStrongRef();
  435. }
  436. return ulReturn;
  437. }
  438. STDMETHODIMP_(ULONG) CWeakRef::Release()
  439. {
  440. ULONG ulReturn;
  441. BOOL fShutdown = m_fInShutdown;
  442. Assert(m_cRef >= m_cRefWeak);
  443. ulReturn = InterlockedDecrement(&m_cRef);
  444. if (ulReturn == 0)
  445. m_fInShutdown = TRUE;
  446. if ((m_cRef == m_cRefWeak) && m_fStrongRef)
  447. {
  448. m_fStrongRef = FALSE;
  449. AddWeakRef();
  450. OnLastStrongRef();
  451. ReleaseWeakRef();
  452. }
  453. if (ulReturn == 0 && (m_fInShutdown != fShutdown) && m_fInShutdown)
  454. delete this;
  455. return ulReturn;
  456. }
  457. STDMETHODIMP CWeakRef::AddWeakRef()
  458. {
  459. Assert(m_cRef >= m_cRefWeak);
  460. InterlockedIncrement(&m_cRef);
  461. InterlockedIncrement(&m_cRefWeak);
  462. return hrOK;
  463. }
  464. STDMETHODIMP CWeakRef::ReleaseWeakRef()
  465. {
  466. Assert(m_cRef >= m_cRefWeak);
  467. InterlockedDecrement(&m_cRefWeak);
  468. Release();
  469. return hrOK;
  470. }
  471. void SRouterCB::LoadFrom(const RouterCB *pcb)
  472. {
  473. dwLANOnlyMode = pcb->dwLANOnlyMode;
  474. }
  475. void SRouterCB::SaveTo(RouterCB *pcb)
  476. {
  477. pcb->dwLANOnlyMode = dwLANOnlyMode;
  478. }
  479. void SRtrMgrCB::LoadFrom(const RtrMgrCB *pcb)
  480. {
  481. dwTransportId = pcb->dwTransportId;
  482. stId = pcb->szId;
  483. stTitle = pcb->szTitle;
  484. stDLLPath = pcb->szDLLPath;
  485. // stConfigDLL = pcb->szConfigDLL;
  486. }
  487. void SRtrMgrCB::SaveTo(RtrMgrCB *pcb)
  488. {
  489. pcb->dwTransportId = dwTransportId;
  490. StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
  491. StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
  492. StrnCpyOleFromT(pcb->szDLLPath, (LPCTSTR) stDLLPath, RTR_PATH_MAX);
  493. // StrnCpyOleFromT(pcb->szConfigDLL, (LPCTSTR) stConfigDLL, RTR_PATH_MAX);
  494. }
  495. void SRtrMgrProtocolCB::LoadFrom(const RtrMgrProtocolCB *pcb)
  496. {
  497. dwProtocolId = pcb->dwProtocolId;
  498. stId = pcb->szId;
  499. dwFlags = pcb->dwFlags;
  500. dwTransportId = pcb->dwTransportId;
  501. stRtrMgrId = pcb->szRtrMgrId;
  502. stTitle = pcb->szTitle;
  503. stDLLName = pcb->szDLLName;
  504. // stConfigDLL = pcb->szConfigDLL;
  505. guidAdminUI = pcb->guidAdminUI;
  506. guidConfig = pcb->guidConfig;
  507. stVendorName = pcb->szVendorName;
  508. }
  509. void SRtrMgrProtocolCB::SaveTo(RtrMgrProtocolCB *pcb)
  510. {
  511. pcb->dwProtocolId = dwProtocolId;
  512. StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
  513. pcb->dwFlags = dwFlags;
  514. pcb->dwTransportId = dwTransportId;
  515. StrnCpyOleFromT(pcb->szRtrMgrId, (LPCTSTR) stRtrMgrId, RTR_ID_MAX);
  516. StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
  517. StrnCpyOleFromT(pcb->szDLLName, (LPCTSTR) stDLLName, RTR_PATH_MAX);
  518. // StrnCpyOleFromT(pcb->szConfigDLL, (LPCTSTR) stConfigDLL, RTR_PATH_MAX);
  519. pcb->guidAdminUI = guidAdminUI;
  520. pcb->guidConfig = guidConfig;
  521. StrnCpyOleFromT(pcb->szVendorName, (LPCTSTR) stVendorName, VENDOR_NAME_MAX);
  522. }
  523. void SInterfaceCB::LoadFrom(const InterfaceCB *pcb)
  524. {
  525. stId = pcb->szId;
  526. stDeviceName = pcb->szDevice;
  527. dwIfType = pcb->dwIfType;
  528. bEnable = pcb->bEnable;
  529. stTitle = pcb->szTitle;
  530. dwBindFlags = pcb->dwBindFlags;
  531. }
  532. void SInterfaceCB::SaveTo(InterfaceCB *pcb)
  533. {
  534. StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
  535. StrnCpyOleFromT(pcb->szDevice, (LPCTSTR) stDeviceName, RTR_DEVICE_MAX);
  536. pcb->dwIfType = dwIfType;
  537. pcb->bEnable = bEnable;
  538. StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
  539. pcb->dwBindFlags = dwBindFlags;
  540. }
  541. void SRtrMgrInterfaceCB::LoadFrom(const RtrMgrInterfaceCB *pcb)
  542. {
  543. dwTransportId = pcb->dwTransportId;
  544. stId = pcb->szId;
  545. stInterfaceId = pcb->szInterfaceId;
  546. dwIfType = pcb->dwIfType;
  547. stTitle = pcb->szTitle;
  548. }
  549. void SRtrMgrInterfaceCB::SaveTo(RtrMgrInterfaceCB *pcb)
  550. {
  551. pcb->dwTransportId = dwTransportId;
  552. StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
  553. StrnCpyOleFromT(pcb->szInterfaceId, (LPCTSTR) stInterfaceId, RTR_ID_MAX);
  554. pcb->dwIfType = dwIfType;
  555. StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_TITLE_MAX);
  556. }
  557. void SRtrMgrProtocolInterfaceCB::LoadFrom(const RtrMgrProtocolInterfaceCB *pcb)
  558. {
  559. dwProtocolId = pcb->dwProtocolId;
  560. stId = pcb->szId;
  561. dwTransportId = pcb->dwTransportId;
  562. stRtrMgrId = pcb->szRtrMgrId;
  563. stInterfaceId = pcb->szInterfaceId;
  564. dwIfType = pcb->dwIfType;
  565. stTitle = pcb->szTitle;
  566. }
  567. void SRtrMgrProtocolInterfaceCB::SaveTo(RtrMgrProtocolInterfaceCB *pcb)
  568. {
  569. pcb->dwProtocolId = dwProtocolId;
  570. StrnCpyOleFromT(pcb->szId, (LPCTSTR) stId, RTR_ID_MAX);
  571. pcb->dwTransportId = dwTransportId;
  572. StrnCpyOleFromT(pcb->szRtrMgrId, (LPCTSTR) stRtrMgrId, RTR_ID_MAX);
  573. StrnCpyOleFromT(pcb->szInterfaceId, (LPCTSTR) stInterfaceId, RTR_TITLE_MAX);
  574. pcb->dwIfType = dwIfType;
  575. StrnCpyOleFromT(pcb->szTitle, (LPCTSTR) stTitle, RTR_PATH_MAX);
  576. }
  577. /*!--------------------------------------------------------------------------
  578. CreateDataObjectFromRouterInfo
  579. -
  580. Author: KennT
  581. ---------------------------------------------------------------------------*/
  582. HRESULT CreateDataObjectFromRouterInfo(IRouterInfo *pInfo,
  583. LPCTSTR pszMachineName,
  584. DATA_OBJECT_TYPES type,
  585. MMC_COOKIE cookie,
  586. ITFSComponentData *pTFSCompData,
  587. IDataObject **ppDataObject,
  588. CDynamicExtensions * pDynExt,
  589. BOOL fAddedAsLocal)
  590. {
  591. Assert(ppDataObject);
  592. CRouterDataObject * pdo = NULL;
  593. HRESULT hr = hrOK;
  594. SPIUnknown spunk;
  595. SPIDataObject spDataObject;
  596. pdo = new CRouterDataObject;
  597. spDataObject = pdo;
  598. pdo->SetComputerName(pszMachineName);
  599. pdo->SetComputerAddedAsLocal(fAddedAsLocal);
  600. CORg( CreateRouterInfoAggregation(pInfo, pdo, &spunk) );
  601. pdo->SetInnerIUnknown(spunk);
  602. // Save cookie and type for delayed rendering
  603. pdo->SetType(type);
  604. pdo->SetCookie(cookie);
  605. // Store the coclasscls with the data object
  606. pdo->SetClsid(*(pTFSCompData->GetCoClassID()));
  607. pdo->SetTFSComponentData(pTFSCompData);
  608. pdo->SetDynExt(pDynExt);
  609. *ppDataObject = spDataObject.Transfer();
  610. Error:
  611. return hr;
  612. }
  613. /*!--------------------------------------------------------------------------
  614. AdviseDataList::AddConnection
  615. Adds a connection to the list.
  616. Author: KennT
  617. ---------------------------------------------------------------------------*/
  618. HRESULT AdviseDataList::AddConnection(IRtrAdviseSink *pAdvise,
  619. LONG_PTR ulConnId,
  620. LPARAM lUserParam)
  621. {
  622. Assert(pAdvise);
  623. HRESULT hr = hrOK;
  624. SAdviseData adviseData;
  625. COM_PROTECT_TRY
  626. {
  627. adviseData.m_ulConnection = ulConnId;
  628. adviseData.m_pAdvise = pAdvise;
  629. adviseData.m_lUserParam = lUserParam;
  630. AddTail(adviseData);
  631. pAdvise->AddRef();
  632. }
  633. COM_PROTECT_CATCH;
  634. return hr;
  635. }
  636. /*!--------------------------------------------------------------------------
  637. AdviseDataList::RemoveConnection
  638. Removes the connection from the list.
  639. Author: KennT
  640. ---------------------------------------------------------------------------*/
  641. HRESULT AdviseDataList::RemoveConnection(LONG_PTR ulConnection)
  642. {
  643. HRESULT hr = E_INVALIDARG;
  644. POSITION pos, posTemp;
  645. POSITION posNotify;
  646. SAdviseData adviseData;
  647. COM_PROTECT_TRY
  648. {
  649. pos = GetHeadPosition();
  650. while (pos)
  651. {
  652. posTemp = pos;
  653. adviseData = GetNext(pos);
  654. if (adviseData.m_ulConnection == ulConnection)
  655. {
  656. hr = hrOK;
  657. SAdviseData::Destroy(&adviseData);
  658. RemoveAt(posTemp);
  659. // Remove this connection from the list
  660. if (!m_listNotify.IsEmpty())
  661. {
  662. posNotify = m_listNotify.GetHeadPosition();
  663. while (posNotify)
  664. {
  665. posTemp = posNotify;
  666. adviseData = m_listNotify.GetNext(posNotify);
  667. if (adviseData.m_ulConnection == ulConnection)
  668. {
  669. adviseData.m_ulFlags |= ADVISEDATA_DELETED;
  670. m_listNotify.SetAt(posTemp, adviseData);
  671. break;
  672. }
  673. }
  674. }
  675. break;
  676. }
  677. }
  678. }
  679. COM_PROTECT_CATCH;
  680. return hr;
  681. }
  682. /*!--------------------------------------------------------------------------
  683. AdviseDataList::NotifyChange
  684. Enumerates through the list of advise sinks and sends this
  685. notification to each one.
  686. Author: KennT
  687. ---------------------------------------------------------------------------*/
  688. HRESULT AdviseDataList::NotifyChange(DWORD dwChangeType,
  689. DWORD dwObjectType,
  690. LPARAM lParam)
  691. {
  692. POSITION pos;
  693. SAdviseData adviseData;
  694. HRESULT hr = hrOK;
  695. // This requires a two-step process. (this is necessary since
  696. // a callback here, may change the items in the list).
  697. // First, gather a list of all the advise sinks (place them
  698. // in a list).
  699. //
  700. // Secondly, go through the list calling the OnChange()
  701. // notifications. THIS LIST MAY BE MODIFIED BY A CALL TO
  702. // THE UNADVISE FUNCTIONS. This means that the unadvise must
  703. // traverse this list.
  704. // Remove all entries in m_listNotify
  705. m_listNotify.RemoveAll();
  706. // Do the first step and build up the list
  707. pos = GetHeadPosition();
  708. while (pos)
  709. {
  710. adviseData = GetNext(pos);
  711. adviseData.m_ulFlags = 0;
  712. m_listNotify.AddTail(adviseData);
  713. }
  714. // Now go through the notify list and send out the notifies
  715. pos = m_listNotify.GetHeadPosition();
  716. while (pos)
  717. {
  718. adviseData = m_listNotify.GetNext(pos);
  719. if ((adviseData.m_ulFlags & ADVISEDATA_DELETED) == 0)
  720. {
  721. // Ignore the return value
  722. adviseData.m_pAdvise->OnChange(adviseData.m_ulConnection,
  723. dwChangeType,
  724. dwObjectType,
  725. adviseData.m_lUserParam,
  726. lParam);
  727. }
  728. }
  729. // Clear out the list again
  730. m_listNotify.RemoveAll();
  731. return hr;
  732. }
  733. void SAdviseData::Destroy(SAdviseData *pAdviseData)
  734. {
  735. if (pAdviseData && pAdviseData->m_pAdvise)
  736. {
  737. pAdviseData->m_pAdvise->Release();
  738. pAdviseData->m_pAdvise = NULL;
  739. pAdviseData->m_ulConnection = NULL;
  740. pAdviseData->m_lUserParam = 0;
  741. }
  742. #ifdef DEBUG
  743. else if (pAdviseData)
  744. Assert(pAdviseData->m_ulConnection == 0);
  745. #endif
  746. }
  747. void SRmData::Destroy(SRmData *pRmData)
  748. {
  749. if (pRmData && pRmData->m_pRmInfo)
  750. {
  751. // This destruct should only get called if this RtrMgr is
  752. // a child of this node.
  753. pRmData->m_pRmInfo->Destruct();
  754. pRmData->m_pRmInfo->ReleaseWeakRef();
  755. pRmData->m_pRmInfo = NULL;
  756. }
  757. }
  758. /*!--------------------------------------------------------------------------
  759. CreateDataObjectFromInterfaceInfo
  760. -
  761. Author: KennT
  762. ---------------------------------------------------------------------------*/
  763. HRESULT CreateDataObjectFromInterfaceInfo(IInterfaceInfo *pInfo,
  764. DATA_OBJECT_TYPES type,
  765. MMC_COOKIE cookie,
  766. ITFSComponentData *pTFSCompData,
  767. IDataObject **ppDataObject)
  768. {
  769. Assert(ppDataObject);
  770. HRESULT hr = hrOK;
  771. CRouterDataObject * pdo = NULL;
  772. SPIDataObject spDataObject;
  773. SPIUnknown spunk;
  774. pdo = new CRouterDataObject;
  775. spDataObject = pdo;
  776. pdo->SetComputerName(pInfo->GetMachineName());
  777. CORg( CreateInterfaceInfoAggregation(pInfo, pdo, &spunk) );
  778. pdo->SetInnerIUnknown(spunk);
  779. // Save cookie and type for delayed rendering
  780. pdo->SetType(type);
  781. pdo->SetCookie(cookie);
  782. // Store the coclass with the data object
  783. pdo->SetClsid(*(pTFSCompData->GetCoClassID()));
  784. pdo->SetTFSComponentData(pTFSCompData);
  785. *ppDataObject = spDataObject.Transfer();
  786. Error:
  787. return hr;
  788. }
  789. /*!--------------------------------------------------------------------------
  790. LookupRtrMgr
  791. -
  792. Author: KennT
  793. ---------------------------------------------------------------------------*/
  794. TFSCORE_API(HRESULT) LookupRtrMgr(IRouterInfo *pRouter,
  795. DWORD dwTransportId,
  796. IRtrMgrInfo **ppRm)
  797. {
  798. Assert(pRouter);
  799. Assert(ppRm);
  800. return pRouter->FindRtrMgr(dwTransportId, ppRm);
  801. }
  802. /*!--------------------------------------------------------------------------
  803. LookupRtrMgrProtocol
  804. -
  805. Author: KennT
  806. ---------------------------------------------------------------------------*/
  807. TFSCORE_API(HRESULT) LookupRtrMgrProtocol(IRouterInfo *pRouter,
  808. DWORD dwTransportId,
  809. DWORD dwProtocolId,
  810. IRtrMgrProtocolInfo **ppRmProt)
  811. {
  812. Assert(pRouter);
  813. Assert(ppRmProt);
  814. SPIRtrMgrInfo spRm;
  815. HRESULT hr = hrOK;
  816. CORg( LookupRtrMgr(pRouter, dwTransportId, &spRm) );
  817. if (FHrOK(hr))
  818. CORg( spRm->FindRtrMgrProtocol(dwProtocolId, ppRmProt) );
  819. Error:
  820. return hr;
  821. }
  822. TFSCORE_API(HRESULT) LookupRtrMgrInterface(IRouterInfo *pRouter,
  823. LPCOLESTR pszInterfaceId,
  824. DWORD dwTransportId,
  825. IRtrMgrInterfaceInfo **ppRmIf)
  826. {
  827. Assert(pRouter);
  828. SPIInterfaceInfo spIf;
  829. HRESULT hr = hrFalse;
  830. CORg( pRouter->FindInterface(pszInterfaceId, &spIf) );
  831. if (FHrOK(hr))
  832. {
  833. hr = spIf->FindRtrMgrInterface(dwTransportId, ppRmIf);
  834. }
  835. Error:
  836. return hr;
  837. }
  838. TFSCORE_API(HRESULT) LookupRtrMgrProtocolInterface(
  839. IInterfaceInfo *pIf, DWORD dwTransportId, DWORD dwProtocolId,
  840. IRtrMgrProtocolInterfaceInfo **ppRmProtIf)
  841. {
  842. Assert(pIf);
  843. SPIRtrMgrInterfaceInfo spRmIf;
  844. HRESULT hr = hrFalse;
  845. hr = pIf->FindRtrMgrInterface(dwTransportId, &spRmIf);
  846. if (FHrOK(hr))
  847. CORg( spRmIf->FindRtrMgrProtocolInterface(dwProtocolId, ppRmProtIf) );
  848. Error:
  849. return hr;
  850. }
  851. /*!--------------------------------------------------------------------------
  852. CreateRouterDataObject
  853. -
  854. Author: KennT
  855. ---------------------------------------------------------------------------*/
  856. HRESULT CreateRouterDataObject(LPCTSTR pszMachineName,
  857. DATA_OBJECT_TYPES type,
  858. MMC_COOKIE cookie,
  859. ITFSComponentData *pTFSCompData,
  860. IDataObject **ppDataObject,
  861. CDynamicExtensions * pDynExt,
  862. BOOL fAddedAsLocal)
  863. {
  864. Assert(ppDataObject);
  865. CRouterDataObject * pdo = NULL;
  866. HRESULT hr = hrOK;
  867. SPIUnknown spunk;
  868. SPIDataObject spDataObject;
  869. pdo = new CRouterDataObject;
  870. spDataObject = pdo;
  871. pdo->SetComputerName(pszMachineName);
  872. pdo->SetComputerAddedAsLocal(fAddedAsLocal);
  873. // Save cookie and type for delayed rendering
  874. pdo->SetType(type);
  875. pdo->SetCookie(cookie);
  876. // Store the coclasscls with the data object
  877. pdo->SetClsid(*(pTFSCompData->GetCoClassID()));
  878. pdo->SetTFSComponentData(pTFSCompData);
  879. pdo->SetDynExt(pDynExt);
  880. *ppDataObject = spDataObject.Transfer();
  881. //Error:
  882. return hr;
  883. }