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.

676 lines
23 KiB

  1. #include <pch.h>
  2. #pragma hdrstop
  3. #include "persist.h"
  4. #include "ncreg.h"
  5. #include "ncsetup.h"
  6. #include "util.h"
  7. HRESULT HrAddOrRemoveWinsockDependancy(
  8. IN HINF hinfInstallFile,
  9. IN PCWSTR pszSectionName);
  10. HRESULT
  11. HrLoadAndAddComponentFromInstanceKey (
  12. IN HKEY hkey,
  13. IN const GUID* pInstanceGuid,
  14. IN NETCLASS Class,
  15. IN PCWSTR pszPnpId OPTIONAL,
  16. IN OUT CNetConfig* pNetConfig)
  17. {
  18. HRESULT hr;
  19. BASIC_COMPONENT_DATA Data;
  20. CComponent* pComponent;
  21. WCHAR szInfId [_MAX_PATH];
  22. WCHAR szMiniportId [_MAX_PATH];
  23. ULONG cbInfId;
  24. Assert (hkey);
  25. Assert (pInstanceGuid);
  26. Assert (FIsValidNetClass (Class));
  27. Assert (FImplies(pszPnpId, *pszPnpId));
  28. Assert (pNetConfig);
  29. ZeroMemory (&Data, sizeof(Data));
  30. hr = HrRegQueryDword (hkey, L"Characteristics", &Data.dwCharacter);
  31. if (S_OK == hr)
  32. {
  33. // If the component is a filter, copy Ndi\MiniportId to
  34. // Ndi\FilterDeviceInfId.
  35. //
  36. if (Data.dwCharacter & NCF_FILTER)
  37. {
  38. HKEY hkeyNdi;
  39. hr = HrRegOpenKeyEx (
  40. hkey,
  41. L"Ndi",
  42. KEY_READ | KEY_WRITE,
  43. &hkeyNdi);
  44. if (S_OK == hr)
  45. {
  46. HKEY hkeyInterfaces;
  47. DWORD cbMiniportId = sizeof(szMiniportId);
  48. hr = HrRegQuerySzBuffer (
  49. hkeyNdi,
  50. L"MiniportId",
  51. szMiniportId,
  52. &cbMiniportId);
  53. if (S_OK == hr)
  54. {
  55. (VOID) HrRegSetSz (
  56. hkeyNdi,
  57. L"FilterDeviceInfId",
  58. szMiniportId);
  59. }
  60. if (FInSystemSetup())
  61. {
  62. // Need to update LowerExclude for filters (the only one
  63. // being PSched) so we prevent PSched from binding to
  64. // every adapter on the machine. This only needs to
  65. // happen during GUI setup and when we detect no Config
  66. // binary because this happens way before INFs get re-run.)
  67. //
  68. hr = HrRegOpenKeyEx (
  69. hkeyNdi,
  70. L"Interfaces",
  71. KEY_WRITE,
  72. &hkeyInterfaces);
  73. if (S_OK == hr)
  74. {
  75. (VOID) HrRegSetSz (
  76. hkeyInterfaces,
  77. L"LowerExclude",
  78. L"ndiscowan, ndiswan, ndiswanasync, "
  79. L"ndiswanipx, ndiswannbf");
  80. RegCloseKey (hkeyInterfaces);
  81. }
  82. }
  83. RegCloseKey (hkeyNdi);
  84. hr = S_OK;
  85. }
  86. }
  87. cbInfId = sizeof(szInfId);
  88. hr = HrRegQuerySzBuffer (hkey, L"ComponentId", szInfId, &cbInfId);
  89. if (S_OK == hr)
  90. {
  91. // Wanarp needs its refcounts key deleted in case we are
  92. // loaded before netupgrd.inf is run.
  93. //
  94. if (0 == _wcsicmp(L"ms_wanarp", szInfId))
  95. {
  96. (VOID)HrRegDeleteKey (hkey, L"RefCounts");
  97. }
  98. Data.InstanceGuid = *pInstanceGuid;
  99. Data.Class = Class;
  100. Data.pszInfId = szInfId;
  101. Data.pszPnpId = pszPnpId;
  102. // It is important to make sure we can load the external data
  103. // for two reasons:
  104. // 1) If we have a failure reading critical data that we
  105. // need in order to function, we want to know about it
  106. // now, before we add it to the component list.
  107. // 2) For filter devices which will be subsequently upgraded,
  108. // we need to search for specific components by BindForm
  109. // and BindName which are external data loaded by the
  110. // following call.
  111. //
  112. hr = CComponent::HrCreateInstance (
  113. &Data,
  114. CCI_ENSURE_EXTERNAL_DATA_LOADED,
  115. NULL,
  116. &pComponent);
  117. if (S_OK == hr)
  118. {
  119. // Add the component and the stack entries, but don't
  120. // send any notifications to notify objects.
  121. //
  122. hr = pNetConfig->Core.HrAddComponentToCore (
  123. pComponent, INS_SORTED);
  124. }
  125. }
  126. }
  127. TraceHr (ttidError, FAL, hr, FALSE, "HrLoadAndAddComponentFromInstanceKey");
  128. return hr;
  129. }
  130. BOOL
  131. FUpgradeFilterDeviceInstanceKey (
  132. IN CNetConfig* pNetConfig,
  133. IN HKEY hkeyInstance,
  134. IN PCWSTR pszFilterName)
  135. {
  136. CComponent* pFilter;
  137. // The new binding engine uses FilterInfId located in under the instance
  138. // key instead of FilterName under Ndi.
  139. //
  140. pFilter = pNetConfig->Core.Components.PFindComponentByBindForm (
  141. NC_NETSERVICE, pszFilterName);
  142. if (pFilter)
  143. {
  144. (VOID) HrRegSetSz (hkeyInstance, L"FilterInfId", pFilter->m_pszInfId);
  145. return TRUE;
  146. }
  147. return FALSE;
  148. }
  149. HRESULT
  150. HrLoadComponentReferencesFromLegacy (
  151. IN OUT CNetConfig* pNetConfig)
  152. {
  153. HRESULT hr = S_OK;
  154. CComponentList::iterator iter;
  155. CComponent* pComponent;
  156. HKEY hkeyInstance;
  157. Assert (pNetConfig);
  158. for (iter = pNetConfig->Core.Components.begin();
  159. iter != pNetConfig->Core.Components.end();
  160. iter++)
  161. {
  162. pComponent = *iter;
  163. Assert (pComponent);
  164. hr = pComponent->HrOpenInstanceKey (KEY_READ,
  165. &hkeyInstance, NULL, NULL);
  166. if (S_OK == hr)
  167. {
  168. HKEY hkeyRefCounts;
  169. hr = HrRegOpenKeyEx (hkeyInstance, L"RefCounts",
  170. KEY_READ, &hkeyRefCounts);
  171. if (S_OK == hr)
  172. {
  173. DWORD dwIndex;
  174. WCHAR szValueName [_MAX_PATH];
  175. DWORD cchValueName;
  176. DWORD dwType;
  177. DWORD dwRefCount;
  178. DWORD cbData;
  179. CComponent* pRefdByComponent;
  180. GUID InstanceGuid;
  181. for (dwIndex = 0; S_OK == hr; dwIndex++)
  182. {
  183. cchValueName = celems(szValueName);
  184. cbData = sizeof(dwRefCount);
  185. hr = HrRegEnumValue (hkeyRefCounts, dwIndex,
  186. szValueName, &cchValueName, &dwType,
  187. (LPBYTE)&dwRefCount, &cbData);
  188. if (S_OK == hr)
  189. {
  190. if (0 == _wcsicmp (L"User", szValueName))
  191. {
  192. hr = pComponent->Refs.HrAddReferenceByUser ();
  193. }
  194. else if ((L'{' == *szValueName) &&
  195. (S_OK == IIDFromString (szValueName, &InstanceGuid)) &&
  196. (NULL != (pRefdByComponent = pNetConfig->Core.Components.PFindComponentByInstanceGuid(&InstanceGuid))))
  197. {
  198. hr = pComponent->Refs.HrAddReferenceByComponent (
  199. pRefdByComponent);
  200. }
  201. else if (NULL != (pRefdByComponent = pNetConfig->
  202. Core.Components.PFindComponentByInfId (
  203. szValueName, NULL)))
  204. {
  205. hr = pComponent->Refs.HrAddReferenceByComponent (
  206. pRefdByComponent);
  207. }
  208. else
  209. {
  210. hr = pComponent->Refs.HrAddReferenceBySoftware (
  211. szValueName);
  212. }
  213. }
  214. }
  215. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  216. {
  217. hr = S_OK;
  218. }
  219. RegCloseKey (hkeyRefCounts);
  220. }
  221. RegCloseKey (hkeyInstance);
  222. }
  223. }
  224. // If the instance key or the refcounts key don't exist, there is not
  225. // much we can do about it. Don't fail for these reasons.
  226. //
  227. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  228. {
  229. hr = S_OK;
  230. }
  231. TraceHr (ttidError, FAL, hr, FALSE, "HrLoadComponentReferencesFromLegacy");
  232. return hr;
  233. }
  234. VOID
  235. UpgradeConnection (
  236. IN const GUID& InstanceGuid,
  237. IN PCWSTR pszPnpId)
  238. {
  239. HRESULT hr;
  240. WCHAR szPath[_MAX_PATH];
  241. HKEY hkeyConn;
  242. Assert (pszPnpId && *pszPnpId);
  243. // Connections uses a pnp id value as their back pointer to the pnp
  244. // tree.
  245. //
  246. CreateInstanceKeyPath (NC_NET, InstanceGuid, szPath);
  247. wcscat (szPath, L"\\Connection");
  248. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE, szPath, KEY_READ_WRITE,
  249. &hkeyConn);
  250. if (S_OK == hr)
  251. {
  252. HrRegSetSz (hkeyConn, L"PnpInstanceId", pszPnpId);
  253. }
  254. RegCloseKey(hkeyConn);
  255. }
  256. HRESULT
  257. HrLoadNetworkConfigurationFromLegacy (
  258. OUT CNetConfig* pNetConfig)
  259. {
  260. HRESULT hr;
  261. NETCLASS Class;
  262. PCWSTR pszSubtree;
  263. HKEY hkeySubtree;
  264. DWORD dwIndex;
  265. HKEY hkeyInstance;
  266. GUID InstanceGuid;
  267. UINT PassNumber;
  268. // Get the value for whether WAN adapters comes first or last in
  269. // adapter order. We need to give this to the stack table so it will
  270. // know which way to order things.
  271. //
  272. Assert (FALSE == pNetConfig->Core.StackTable.m_fWanAdaptersFirst);
  273. hr = HrOpenNetworkKey (
  274. KEY_READ,
  275. &hkeySubtree);
  276. if (S_OK == hr)
  277. {
  278. DWORD dwValue;
  279. hr = HrRegQueryDword (hkeySubtree, L"WanAdaptersFirst", &dwValue);
  280. if (S_OK == hr)
  281. {
  282. pNetConfig->Core.StackTable.m_fWanAdaptersFirst = !!dwValue;
  283. }
  284. RegCloseKey (hkeySubtree);
  285. }
  286. // We need two passes to correctly upgrade everything. Since filter
  287. // devices reference an adapter, we need to have already read the
  288. // information for all adapters before we can read information about
  289. // a filter device and create a memory representation for it which
  290. // references the memory representation of the adapter which it filters.
  291. //
  292. // The following structure should make this more clear. For each
  293. // element in this array, we enumerate components in the specified
  294. // class. Note that NC_NET is reference twice -- once for pass one
  295. // and once for pass two. The code below uses the pass number to
  296. // know whether it should be ignoring filter devices (in pass one)
  297. // or ignoring adapters (in pass two, because they were already handled
  298. // in pass one.) If it isn't clear by now, don't touch this code. ;-)
  299. //
  300. static const struct
  301. {
  302. NETCLASS Class;
  303. UINT PassNumber;
  304. } aPassInfo [] =
  305. {
  306. { NC_NET, 1 },
  307. { NC_INFRARED, 1 },
  308. { NC_NETTRANS, 1 },
  309. { NC_NETCLIENT, 1 },
  310. { NC_NETSERVICE, 1 },
  311. { NC_NET, 2 },
  312. };
  313. for (UINT i = 0; i < celems(aPassInfo); i++)
  314. {
  315. Class = aPassInfo[i].Class;
  316. PassNumber = aPassInfo[i].PassNumber;
  317. Assert (FIsValidNetClass(Class));
  318. pszSubtree = MAP_NETCLASS_TO_NETWORK_SUBTREE[Class];
  319. if (!FIsEnumerated (Class))
  320. {
  321. hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE, pszSubtree,
  322. KEY_READ, &hkeySubtree);
  323. if (S_OK == hr)
  324. {
  325. DWORD cchGuid;
  326. WCHAR szInstanceGuid [c_cchGuidWithTerm];
  327. FILETIME ftLastWrite;
  328. for (dwIndex = 0; S_OK == hr; dwIndex++)
  329. {
  330. cchGuid = celems(szInstanceGuid);
  331. hr = HrRegEnumKeyEx (
  332. hkeySubtree, dwIndex, szInstanceGuid, &cchGuid,
  333. NULL, NULL, &ftLastWrite);
  334. if ((S_OK == hr) && ((c_cchGuidWithTerm-1) == cchGuid))
  335. {
  336. hr = IIDFromString (szInstanceGuid, &InstanceGuid);
  337. if (S_OK == hr)
  338. {
  339. hr = HrRegOpenKeyEx (
  340. hkeySubtree,
  341. szInstanceGuid,
  342. KEY_READ,
  343. &hkeyInstance);
  344. if (S_OK == hr)
  345. {
  346. hr = HrLoadAndAddComponentFromInstanceKey (
  347. hkeyInstance,
  348. &InstanceGuid,
  349. Class,
  350. NULL,
  351. pNetConfig);
  352. RegCloseKey (hkeyInstance);
  353. }
  354. }
  355. else
  356. {
  357. // Delete the key?
  358. }
  359. // Ignore any errors during the loop
  360. hr = S_OK;
  361. }
  362. }
  363. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  364. {
  365. hr = S_OK;
  366. }
  367. RegCloseKey (hkeySubtree);
  368. }
  369. }
  370. else
  371. {
  372. HDEVINFO hdi;
  373. hr = HrSetupDiGetClassDevs (MAP_NETCLASS_TO_GUID[Class],
  374. NULL, NULL, DIGCF_PROFILE, &hdi);
  375. if (S_OK == hr)
  376. {
  377. SP_DEVINFO_DATA deid;
  378. WCHAR szPnpId [2 * _MAX_PATH];
  379. WCHAR szFilterName [_MAX_PATH];
  380. BOOL fr;
  381. for (dwIndex = 0; S_OK == hr; dwIndex++)
  382. {
  383. hr = HrSetupDiEnumDeviceInfo (hdi, dwIndex, &deid);
  384. if (S_OK == hr)
  385. {
  386. fr = SetupDiGetDeviceInstanceId (
  387. hdi, &deid,
  388. szPnpId, celems(szPnpId), NULL);
  389. if (fr)
  390. {
  391. // We open with KEY_WRITE because we will be
  392. // adding a new value to filter devices we
  393. // upgrade.
  394. //
  395. hr = HrSetupDiOpenDevRegKey (
  396. hdi, &deid,
  397. DICS_FLAG_GLOBAL, 0, DIREG_DRV,
  398. KEY_WRITE | KEY_READ, &hkeyInstance);
  399. if (S_OK == hr)
  400. {
  401. LONG lr;
  402. ULONG cbGuid = sizeof(GUID);
  403. lr = RegQueryGuid (
  404. hkeyInstance,
  405. L"NetCfgInstanceId",
  406. &InstanceGuid,
  407. &cbGuid);
  408. if (!lr)
  409. {
  410. BOOL fIsFilterDevice;
  411. HKEY hkeyNdi;
  412. fIsFilterDevice = FALSE;
  413. hr = HrRegOpenKeyEx (
  414. hkeyInstance,
  415. L"Ndi",
  416. KEY_READ,
  417. &hkeyNdi);
  418. if (S_OK == hr)
  419. {
  420. DWORD cbFilterName = sizeof(szFilterName);
  421. hr = HrRegQuerySzBuffer (
  422. hkeyNdi,
  423. L"FilterName",
  424. szFilterName,
  425. &cbFilterName);
  426. if (S_OK == hr)
  427. {
  428. fIsFilterDevice = TRUE;
  429. }
  430. RegCloseKey (hkeyNdi);
  431. }
  432. // If it's a filter device, ignore it in
  433. // pass one and handle it in pass two.
  434. //
  435. if (fIsFilterDevice && (2 == PassNumber))
  436. {
  437. FUpgradeFilterDeviceInstanceKey (
  438. pNetConfig,
  439. hkeyInstance,
  440. szFilterName);
  441. }
  442. // If it's not a filter device, handle it
  443. // in pass one and ignore it in pass two.
  444. //
  445. else if (!fIsFilterDevice && (1 == PassNumber))
  446. {
  447. UpgradeConnection (InstanceGuid,
  448. szPnpId);
  449. hr = HrLoadAndAddComponentFromInstanceKey (
  450. hkeyInstance,
  451. &InstanceGuid,
  452. Class,
  453. szPnpId,
  454. pNetConfig);
  455. }
  456. }
  457. RegCloseKey (hkeyInstance);
  458. }
  459. }
  460. // Ignore any errors during the loop
  461. hr = S_OK;
  462. }
  463. }
  464. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  465. {
  466. hr = S_OK;
  467. }
  468. SetupDiDestroyDeviceInfoList (hdi);
  469. }
  470. }
  471. }
  472. if (S_OK == hr)
  473. {
  474. hr = HrLoadComponentReferencesFromLegacy (pNetConfig);
  475. }
  476. if (S_OK == hr)
  477. {
  478. CComponentList::iterator iter;
  479. CComponent* pComponent;
  480. CBindPath BindPath;
  481. CBindingSet BindSet;
  482. HKEY hkeyParent;
  483. HKEY hkeyDisabled;
  484. // Upgrade disabled bindings.
  485. //
  486. for (iter = pNetConfig->Core.Components.begin();
  487. iter != pNetConfig->Core.Components.end();
  488. iter++)
  489. {
  490. pComponent = *iter;
  491. Assert (pComponent);
  492. // Open the parent of the linkage key depending on what type
  493. // of component this is.
  494. //
  495. if (FIsEnumerated (pComponent->Class()) || !pComponent->FHasService())
  496. {
  497. hr = pComponent->HrOpenInstanceKey (KEY_READ, &hkeyParent,
  498. NULL, NULL);
  499. }
  500. else
  501. {
  502. hr = pComponent->HrOpenServiceKey (KEY_READ, &hkeyParent);
  503. }
  504. // Open the Linkage\Disabled key.
  505. //
  506. if (S_OK == hr)
  507. {
  508. hr = HrRegOpenKeyEx (hkeyParent, L"Linkage\\Disabled",
  509. KEY_READ,
  510. &hkeyDisabled);
  511. if (S_OK == hr)
  512. {
  513. PWSTR pmszBindPath;
  514. hr = HrRegQueryMultiSzWithAlloc (
  515. hkeyDisabled,
  516. L"BindPath",
  517. &pmszBindPath);
  518. if (S_OK == hr)
  519. {
  520. PWSTR pszBindPath;
  521. PCWSTR pszBindName;
  522. PWSTR pszNext;
  523. CComponent* pOther;
  524. // Get the components current bindings as they
  525. // exist in the new engine. We won't disable
  526. // any bindings that don't exist in this set.
  527. //
  528. (VOID) pNetConfig->Core.HrGetComponentBindings (
  529. pComponent,
  530. GBF_DEFAULT,
  531. &BindSet);
  532. // Iterate the multi-sz of disabled bindpaths.
  533. //
  534. for (pszBindPath = pmszBindPath;
  535. *pszBindPath;
  536. pszBindPath += wcslen(pszBindPath) + 1)
  537. {
  538. // The bindpath will start with this component
  539. // that has the disabled bindings.
  540. //
  541. BindPath.Clear();
  542. BindPath.HrAppendComponent (pComponent);
  543. for (pszBindName = GetNextStringToken (pszBindPath, L"_", &pszNext);
  544. pszBindName && *pszBindName;
  545. pszBindName = GetNextStringToken (NULL, L"_", &pszNext))
  546. {
  547. pOther = pNetConfig->Core.Components.
  548. PFindComponentByBindName (
  549. NC_INVALID, pszBindName);
  550. if (!pOther)
  551. {
  552. break;
  553. }
  554. BindPath.HrAppendComponent (pOther);
  555. }
  556. // If the bindpath is valid, disable it.
  557. //
  558. if (BindSet.FContainsBindPath (&BindPath))
  559. {
  560. pNetConfig->Core.HrDisableBindPath (&BindPath);
  561. }
  562. }
  563. MemFree (pmszBindPath);
  564. }
  565. RegCloseKey (hkeyDisabled);
  566. }
  567. RegCloseKey (hkeyParent);
  568. }
  569. }
  570. // If we can't upgrade disabled bindings, no biggee.
  571. //
  572. hr = S_OK;
  573. }
  574. TraceHr (ttidError, FAL, hr, FALSE, "HrLoadNetworkConfigurationFromLegacy");
  575. return hr;
  576. }