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.

653 lines
17 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2000.
  5. //
  6. // File: N D I S W A N . C P P
  7. //
  8. // Contents: Implementation of NdisWan configuration object.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 28 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ndiswan.h"
  18. #include "ncreg.h"
  19. #include "mprerror.h"
  20. #include "rtutils.h"
  21. extern const WCHAR c_szInfId_MS_AppleTalk[];
  22. extern const WCHAR c_szInfId_MS_L2TP[];
  23. extern const WCHAR c_szInfId_MS_L2tpMiniport[];
  24. extern const WCHAR c_szInfId_MS_NWIPX[];
  25. extern const WCHAR c_szInfId_MS_NdisWanAtalk[];
  26. extern const WCHAR c_szInfId_MS_NdisWanBh[];
  27. extern const WCHAR c_szInfId_MS_NdisWanIp[];
  28. extern const WCHAR c_szInfId_MS_NdisWanIpx[];
  29. extern const WCHAR c_szInfId_MS_NdisWanNbfIn[];
  30. extern const WCHAR c_szInfId_MS_NdisWanNbfOut[];
  31. extern const WCHAR c_szInfId_MS_NetBEUI[];
  32. extern const WCHAR c_szInfId_MS_NetMon[];
  33. extern const WCHAR c_szInfId_MS_PPTP[];
  34. extern const WCHAR c_szInfId_MS_PptpMiniport[];
  35. extern const WCHAR c_szInfId_MS_RasMan[];
  36. extern const WCHAR c_szInfId_MS_TCPIP[];
  37. extern const WCHAR c_szInfId_MS_PPPOE[];
  38. extern const WCHAR c_szInfId_MS_PppoeMiniport[];
  39. extern const WCHAR c_szRegValWanEndpoints[] = L"WanEndpoints";
  40. static const WCHAR c_szRegValMinWanEndpoints[] = L"MinWanEndpoints";
  41. static const WCHAR c_szRegValMaxWanEndpoints[] = L"MaxWanEndpoints";
  42. //$ TODO (shaunco) 3 Feb 1998: rasman has no notify object so just
  43. // merge its services into ndiswan's and eliminate c_apguidInstalledOboNdiswan
  44. //----------------------------------------------------------------------------
  45. // Data used for installing other components.
  46. //
  47. static const GUID* c_apguidInstalledOboNdiswan [] =
  48. {
  49. &GUID_DEVCLASS_NETSERVICE, // RasMan
  50. };
  51. static const PCWSTR c_apszInstalledOboNdiswan [] =
  52. {
  53. c_szInfId_MS_RasMan,
  54. };
  55. static const GUID* c_apguidInstalledOboUser [] =
  56. {
  57. &GUID_DEVCLASS_NETTRANS, // L2TP
  58. &GUID_DEVCLASS_NETTRANS, // PPTP
  59. &GUID_DEVCLASS_NETTRANS, // PPPOE
  60. };
  61. static const PCWSTR c_apszInstalledOboUser [] =
  62. {
  63. c_szInfId_MS_L2TP,
  64. c_szInfId_MS_PPTP,
  65. c_szInfId_MS_PPPOE,
  66. };
  67. CNdisWan::CNdisWan () : CRasBindObject ()
  68. {
  69. m_fInstalling = FALSE;
  70. m_fRemoving = FALSE;
  71. m_pnccMe = NULL;
  72. }
  73. CNdisWan::~CNdisWan ()
  74. {
  75. ReleaseObj (m_pnccMe);
  76. }
  77. //+---------------------------------------------------------------------------
  78. // INetCfgComponentControl
  79. //
  80. STDMETHODIMP
  81. CNdisWan::Initialize (
  82. INetCfgComponent* pncc,
  83. INetCfg* pnc,
  84. BOOL fInstalling)
  85. {
  86. Validate_INetCfgNotify_Initialize (pncc, pnc, fInstalling);
  87. // Hold on to our the component representing us and our host
  88. // INetCfg object.
  89. //
  90. AddRefObj (m_pnccMe = pncc);
  91. AddRefObj (m_pnc = pnc);
  92. m_fInstalling = fInstalling;
  93. return S_OK;
  94. }
  95. STDMETHODIMP
  96. CNdisWan::Validate ()
  97. {
  98. return S_OK;
  99. }
  100. STDMETHODIMP
  101. CNdisWan::CancelChanges ()
  102. {
  103. return S_OK;
  104. }
  105. STDMETHODIMP
  106. CNdisWan::ApplyRegistryChanges ()
  107. {
  108. return S_OK;
  109. }
  110. //+---------------------------------------------------------------------------
  111. // INetCfgComponentSetup
  112. //
  113. STDMETHODIMP
  114. CNdisWan::ReadAnswerFile (
  115. PCWSTR pszAnswerFile,
  116. PCWSTR pszAnswerSection)
  117. {
  118. return S_OK;
  119. }
  120. STDMETHODIMP
  121. CNdisWan::Install (DWORD dwSetupFlags)
  122. {
  123. HRESULT hr;
  124. Validate_INetCfgNotify_Install (dwSetupFlags);
  125. // Install rasman.
  126. //
  127. hr = HrInstallComponentsOboComponent (m_pnc, NULL,
  128. celems (c_apguidInstalledOboNdiswan),
  129. c_apguidInstalledOboNdiswan,
  130. c_apszInstalledOboNdiswan,
  131. m_pnccMe);
  132. //$ TODO (shaunco) 28 Dec 1997: Install L2TP, PPTP, PPPOE obo ndiswan.
  133. // But, this creates an upgrade problem.
  134. if (SUCCEEDED(hr))
  135. {
  136. hr = HrInstallComponentsOboUser (m_pnc, NULL,
  137. celems (c_apguidInstalledOboUser),
  138. c_apguidInstalledOboUser,
  139. c_apszInstalledOboUser);
  140. }
  141. if (SUCCEEDED(hr))
  142. {
  143. hr = HrAddOrRemovePti (ARA_ADD);
  144. }
  145. if (SUCCEEDED(hr))
  146. {
  147. hr = HrFindOtherComponents ();
  148. if (SUCCEEDED(hr))
  149. {
  150. if (SUCCEEDED(hr) && PnccAtalk())
  151. {
  152. hr = HrAddOrRemoveAtalkInOut (ARA_ADD);
  153. }
  154. if (SUCCEEDED(hr) && PnccIp())
  155. {
  156. hr = HrAddOrRemoveIpAdapter (ARA_ADD);
  157. }
  158. if (SUCCEEDED(hr) && PnccIpx())
  159. {
  160. hr = HrAddOrRemoveIpxInOut (ARA_ADD);
  161. }
  162. if (SUCCEEDED(hr) && PnccNetMon())
  163. {
  164. hr = HrAddOrRemoveNetMonInOut (ARA_ADD);
  165. }
  166. ReleaseOtherComponents ();
  167. }
  168. }
  169. // Recompute (and adjust if needed) the number of ndiswan miniports.
  170. //
  171. hr = HrProcessEndpointChange ();
  172. TraceError ("CNdisWan::Install: HrProcessEndpointChange failed. "
  173. "(not propagating error)", hr);
  174. // Normalize the HRESULT. (i.e. don't return S_FALSE)
  175. if (S_FALSE == hr)
  176. {
  177. hr = S_OK;
  178. }
  179. if ((NSF_WINNT_WKS_UPGRADE & dwSetupFlags) ||
  180. (NSF_WINNT_SBS_UPGRADE & dwSetupFlags) ||
  181. (NSF_WINNT_SVR_UPGRADE & dwSetupFlags))
  182. {
  183. HKEY hkeyMd5;
  184. if (SUCCEEDED(HrRegOpenKeyEx (HKEY_LOCAL_MACHINE,
  185. L"System\\CurrentControlSet\\Services\\Rasman\\PPP\\CHAP\\MD5",
  186. KEY_READ, &hkeyMd5)))
  187. {
  188. HANDLE hLog;
  189. // MD5 key was found. Need to log something to the eventlog.
  190. hLog = RouterLogRegister(L"RemoteAccess");
  191. if (hLog)
  192. {
  193. RouterLogWarning(hLog, WARNING_NO_MD5_MIGRATION, 0,
  194. NULL, NO_ERROR);
  195. RouterLogDeregister(hLog);
  196. }
  197. RegCloseKey (hkeyMd5);
  198. }
  199. }
  200. // Check to see if Connection Manager is installed and
  201. // if there are any profiles to migrate. We do this
  202. // by opening the CM mappings key and checking to see if it contains any
  203. // values. and if so then write a run-once setup key so that
  204. // we can migrate profiles when the user logs in for the first time.
  205. // Note that this only works for NT to NT upgrades. The win9x registry
  206. // hasn't been filled in by the time that this runs. Thus our win9x
  207. // migration dll (cmmgr\migration.dll) takes care of the win9x case.
  208. //
  209. static const WCHAR c_CmdString[] = L"cmstp.exe /m";
  210. static const WCHAR c_ValueString[] = L"Connection Manager Profiles Upgrade";
  211. static const WCHAR c_szRegCmMappings[] = L"SOFTWARE\\Microsoft\\Connection Manager\\Mappings";
  212. static const WCHAR c_szRegRunKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
  213. static const WCHAR c_szRegCmUninstallKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Connection Manager";
  214. static const WCHAR c_szRegSysCompValue[] = L"SystemComponent";
  215. // dwTemp is used as temp DWORD. Used as Disposition DWORD for RegCreateKey, and
  216. // as a value holder for RegSetValueEx
  217. //
  218. DWORD dwTemp;
  219. HKEY hKey;
  220. HRESULT hrT;
  221. // Set the Connection Manager key as a system component. This will prevent 1.0 installs
  222. // from writing this key and having it show up in Add/Remove Programs (the syscomp flags
  223. // tells ARP not to display the key).
  224. //
  225. hrT = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE,
  226. c_szRegCmUninstallKey,
  227. REG_OPTION_NON_VOLATILE,
  228. KEY_ALL_ACCESS,
  229. NULL,
  230. &hKey,
  231. &dwTemp);
  232. if (SUCCEEDED(hrT))
  233. {
  234. dwTemp = 1;
  235. hrT = HrRegSetDword(hKey, c_szRegSysCompValue, dwTemp);
  236. RegCloseKey(hKey);
  237. }
  238. // Now try to migrate profiles
  239. //
  240. hrT = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE,
  241. c_szRegCmMappings,
  242. KEY_READ,
  243. &hKey);
  244. if (SUCCEEDED(hrT))
  245. {
  246. dwTemp = 0;
  247. hrT = HrRegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL,
  248. &dwTemp, NULL, NULL, NULL, NULL);
  249. if ((SUCCEEDED(hrT)) && (dwTemp > 0))
  250. {
  251. // Then we have mappings values, so we need to migrate them.
  252. //
  253. RegCloseKey(hKey);
  254. hrT = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE,
  255. c_szRegRunKey,
  256. REG_OPTION_NON_VOLATILE,
  257. KEY_WRITE | KEY_READ,
  258. NULL,
  259. &hKey,
  260. &dwTemp);
  261. if (SUCCEEDED(hrT))
  262. {
  263. hrT = HrRegSetSz (hKey, c_ValueString, c_CmdString);
  264. RegCloseKey(hKey);
  265. }
  266. }
  267. else
  268. {
  269. RegCloseKey(hKey);
  270. }
  271. }
  272. TraceError ("CNdisWan::Install", hr);
  273. return hr;
  274. }
  275. STDMETHODIMP
  276. CNdisWan::Removing ()
  277. {
  278. static const PCWSTR c_apszInfIdRemove [] =
  279. {
  280. c_szInfId_MS_L2tpMiniport,
  281. c_szInfId_MS_NdisWanAtalk,
  282. c_szInfId_MS_NdisWanBh,
  283. c_szInfId_MS_NdisWanIp,
  284. c_szInfId_MS_NdisWanIpx,
  285. c_szInfId_MS_NdisWanNbfIn,
  286. c_szInfId_MS_NdisWanNbfOut,
  287. c_szInfId_MS_PptpMiniport,
  288. c_szInfId_MS_PtiMiniport,
  289. c_szInfId_MS_PppoeMiniport,
  290. };
  291. m_fRemoving = TRUE;
  292. HRESULT hr = S_OK;
  293. // Remove wanarp and rasman.
  294. //
  295. HRESULT hrT = HrFindAndRemoveComponentsOboComponent (m_pnc,
  296. celems (c_apguidInstalledOboNdiswan),
  297. c_apguidInstalledOboNdiswan,
  298. c_apszInstalledOboNdiswan,
  299. m_pnccMe);
  300. hr = hrT;
  301. // Remove L2TP, PPTP and PPPOE on behalf of the user.
  302. //
  303. hrT = HrFindAndRemoveComponentsOboUser (m_pnc,
  304. celems (c_apguidInstalledOboUser),
  305. c_apguidInstalledOboUser,
  306. c_apszInstalledOboUser);
  307. if (SUCCEEDED(hr))
  308. {
  309. hr = hrT;
  310. }
  311. // Remove all of the adapters we may have created.
  312. //
  313. hrT = HrFindAndRemoveAllInstancesOfAdapters (m_pnc,
  314. celems(c_apszInfIdRemove),
  315. c_apszInfIdRemove);
  316. if (SUCCEEDED(hr))
  317. {
  318. hr = hrT;
  319. }
  320. // Don't return S_FALSE or NETCFG_S_STILL_REFERENCED
  321. //
  322. if (SUCCEEDED(hr))
  323. {
  324. hr = S_OK;
  325. }
  326. Validate_INetCfgNotify_Removing_Return (hr);
  327. TraceError ("CNdisWan::Removing", hr);
  328. return hr;
  329. }
  330. STDMETHODIMP
  331. CNdisWan::Upgrade (
  332. DWORD dwSetupFlags,
  333. DWORD dwUpgradeFromBuildNo)
  334. {
  335. HRESULT hr;
  336. hr= HrInstallComponentsOboUser (m_pnc, NULL,
  337. celems (c_apguidInstalledOboUser),
  338. c_apguidInstalledOboUser,
  339. c_apszInstalledOboUser);
  340. TraceError ("CNdisWan::Upgrade: HrInstallComponentsOboUser failed. "
  341. "(not propagating error)", hr);
  342. HKEY hkeyNew;
  343. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE,
  344. L"System\\CurrentControlSet\\Services\\RemoteAccess\\Parameters",
  345. KEY_WRITE,
  346. &hkeyNew);
  347. if (SUCCEEDED(hr))
  348. {
  349. HKEY hkeyCurrent;
  350. DWORD dwValue;
  351. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE,
  352. L"System\\CurrentControlSet\\Services\\Rasman\\PPP",
  353. KEY_READ,
  354. &hkeyCurrent);
  355. if (SUCCEEDED(hr))
  356. {
  357. // Move 'ServerFlags' value to new location. This is for
  358. // interim NT5 builds. This can go away after Beta3 ships.
  359. //
  360. hr = HrRegQueryDword (hkeyCurrent, L"ServerFlags", &dwValue);
  361. if (SUCCEEDED(hr))
  362. {
  363. hr = HrRegSetDword (hkeyNew, L"ServerFlags", dwValue);
  364. (VOID) HrRegDeleteValue (hkeyCurrent, L"ServerFlags");
  365. }
  366. RegCloseKey (hkeyCurrent);
  367. }
  368. // Copy 'RouterType' value to new location.
  369. //
  370. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE,
  371. L"Software\\Microsoft\\Ras\\Protocols",
  372. KEY_READ,
  373. &hkeyCurrent);
  374. if (SUCCEEDED(hr))
  375. {
  376. hr = HrRegQueryDword (hkeyCurrent, L"RouterType", &dwValue);
  377. if (SUCCEEDED(hr))
  378. {
  379. hr = HrRegSetDword (hkeyNew, L"RouterType", dwValue);
  380. }
  381. RegCloseKey (hkeyCurrent);
  382. }
  383. RegCloseKey (hkeyNew);
  384. }
  385. return S_OK;
  386. }
  387. //+---------------------------------------------------------------------------
  388. // INetCfgSystemNotify
  389. //
  390. STDMETHODIMP
  391. CNdisWan::GetSupportedNotifications (
  392. DWORD* pdwNotificationFlag)
  393. {
  394. Validate_INetCfgSystemNotify_GetSupportedNotifications (pdwNotificationFlag);
  395. *pdwNotificationFlag = NCN_BINDING_PATH |
  396. NCN_NETTRANS | NCN_NETSERVICE |
  397. NCN_ADD | NCN_REMOVE;
  398. return S_OK;
  399. }
  400. STDMETHODIMP
  401. CNdisWan::SysQueryBindingPath (
  402. DWORD dwChangeFlag,
  403. INetCfgBindingPath* pncbp)
  404. {
  405. return S_OK;
  406. }
  407. STDMETHODIMP
  408. CNdisWan::SysQueryComponent (
  409. DWORD dwChangeFlag,
  410. INetCfgComponent* pncc)
  411. {
  412. return S_OK;
  413. }
  414. STDMETHODIMP
  415. CNdisWan::SysNotifyBindingPath (
  416. DWORD dwChangeFlag,
  417. INetCfgBindingPath* pncbp)
  418. {
  419. HRESULT hr;
  420. HKEY hkey;
  421. Validate_INetCfgSystemNotify_SysNotifyBindingPath (dwChangeFlag, pncbp);
  422. hkey = NULL;
  423. // ndisatm miniports don't write WanEndpoints to their instance key.
  424. // We default it and write WanEndpoints for them.
  425. //
  426. if (dwChangeFlag & NCN_ADD)
  427. {
  428. CIterNetCfgBindingInterface ncbiIter(pncbp);
  429. INetCfgBindingInterface* pncbi;
  430. hr = S_OK;
  431. while (!hkey && SUCCEEDED(hr) &&
  432. (S_OK == (hr = ncbiIter.HrNext (&pncbi))))
  433. {
  434. RAS_BINDING_ID RasBindId;
  435. if (FIsRasBindingInterface (pncbi, &RasBindId) &&
  436. (RBID_NDISATM == RasBindId))
  437. {
  438. INetCfgComponent* pnccLower;
  439. hr = pncbi->GetLowerComponent (&pnccLower);
  440. if (SUCCEEDED(hr))
  441. {
  442. TraceTag (ttidRasCfg, "New ATM adapter");
  443. hr = pnccLower->OpenParamKey (&hkey);
  444. ReleaseObj (pnccLower);
  445. }
  446. }
  447. ReleaseObj(pncbi);
  448. }
  449. }
  450. if (hkey)
  451. {
  452. DWORD dwEndpoints;
  453. DWORD dwValue;
  454. hr = HrRegQueryDword (hkey, c_szRegValWanEndpoints, &dwEndpoints);
  455. if (FAILED(hr))
  456. {
  457. TraceTag (ttidRasCfg, "Defaulting WanEndpoints");
  458. dwEndpoints = 5;
  459. // Validate the default between the min and max
  460. // specified by the driver (if specified).
  461. //
  462. if (SUCCEEDED(HrRegQueryDword (hkey,
  463. c_szRegValMaxWanEndpoints,
  464. &dwValue)))
  465. {
  466. if ((dwValue < INT_MAX) && (dwEndpoints > dwValue))
  467. {
  468. dwEndpoints = dwValue;
  469. }
  470. }
  471. else
  472. {
  473. (VOID) HrRegSetDword(hkey, c_szRegValMaxWanEndpoints, 500);
  474. }
  475. if (SUCCEEDED(HrRegQueryDword (hkey,
  476. c_szRegValMinWanEndpoints,
  477. &dwValue)))
  478. {
  479. if ((dwValue < INT_MAX) && (dwEndpoints < dwValue))
  480. {
  481. dwEndpoints = dwValue;
  482. }
  483. }
  484. else
  485. {
  486. (VOID) HrRegSetDword(hkey, c_szRegValMinWanEndpoints, 0);
  487. }
  488. (VOID) HrRegSetDword (hkey, c_szRegValWanEndpoints, dwEndpoints);
  489. }
  490. RegCloseKey (hkey);
  491. }
  492. return S_FALSE;
  493. }
  494. STDMETHODIMP
  495. CNdisWan::SysNotifyComponent (
  496. DWORD dwChangeFlag,
  497. INetCfgComponent* pncc)
  498. {
  499. HRESULT hr = S_OK;
  500. Validate_INetCfgSystemNotify_SysNotifyComponent (dwChangeFlag, pncc);
  501. // If a protocol is coming or going, add or remove the
  502. // ndiswanXXX miniports.
  503. //
  504. DWORD dwAraFlags = 0;
  505. if (dwChangeFlag & NCN_ADD)
  506. {
  507. dwAraFlags = ARA_ADD;
  508. }
  509. else if (dwChangeFlag & NCN_REMOVE)
  510. {
  511. dwAraFlags = ARA_REMOVE;
  512. }
  513. if (dwAraFlags)
  514. {
  515. BOOL fProcessEndpoingChange = FALSE;
  516. PWSTR pszId;
  517. hr = pncc->GetId (&pszId);
  518. if (SUCCEEDED(hr))
  519. {
  520. if (FEqualComponentId (c_szInfId_MS_TCPIP, pszId))
  521. {
  522. hr = HrAddOrRemoveIpAdapter (dwAraFlags);
  523. fProcessEndpoingChange = TRUE;
  524. }
  525. else if (FEqualComponentId (c_szInfId_MS_NWIPX, pszId))
  526. {
  527. hr = HrAddOrRemoveIpxInOut (dwAraFlags);
  528. }
  529. else if (FEqualComponentId (c_szInfId_MS_NetBEUI, pszId))
  530. {
  531. fProcessEndpoingChange = TRUE;
  532. }
  533. else if (FEqualComponentId (c_szInfId_MS_AppleTalk, pszId))
  534. {
  535. hr = HrAddOrRemoveAtalkInOut (dwAraFlags);
  536. }
  537. else if (FEqualComponentId (c_szInfId_MS_NetMon, pszId))
  538. {
  539. hr = HrAddOrRemoveNetMonInOut (dwAraFlags);
  540. }
  541. CoTaskMemFree (pszId);
  542. }
  543. if (SUCCEEDED(hr) && fProcessEndpoingChange)
  544. {
  545. hr = HrProcessEndpointChange ();
  546. }
  547. }
  548. TraceError ("CNdisWan::SysNotifyComponent", hr);
  549. return hr;
  550. }