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.

708 lines
18 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT5.0
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N U U T I L S . C P P
  7. //
  8. // Contents: Functions needed by OEM DLLs for OEM network upgrade
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 16-October-97
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "kkstl.h"
  18. #include "nustrs.h"
  19. #include "nuutils.h"
  20. #include "netupgrd.h"
  21. #include "kkutils.h"
  22. #include "ncreg.h"
  23. // ----------------------------------------------------------------------
  24. extern const WCHAR c_szNetUpgradeDll[];
  25. extern const WCHAR c_szRegValServiceName[];
  26. static const WCHAR c_szComponent[] = L"Component";
  27. // ----------------------------------------------------------------------
  28. //
  29. // Function: HrGetWindowsDir
  30. //
  31. // Purpose: Return full path to %WINDIR%
  32. //
  33. // Arguments:
  34. // pstrWinDir [out] full path to windir
  35. //
  36. // Returns: S_OK on success, otherwise an error code
  37. //
  38. // Author: kumarp 19-December-97
  39. //
  40. // Notes:
  41. //
  42. HRESULT HrGetWindowsDir(OUT tstring* pstrWinDir)
  43. {
  44. DefineFunctionName("HrGetWindowsDir");
  45. HRESULT hr=S_OK;
  46. WCHAR szWindowsDir[MAX_PATH+1];
  47. DWORD cNumCharsReturned = GetWindowsDirectory(szWindowsDir, MAX_PATH);
  48. if (cNumCharsReturned)
  49. {
  50. *pstrWinDir = szWindowsDir;
  51. }
  52. else
  53. {
  54. hr = HrFromLastWin32Error();
  55. }
  56. TraceError(__FUNCNAME__, hr);
  57. return hr;
  58. }
  59. //+---------------------------------------------------------------------------
  60. //
  61. // Function: HrGetNetupgrdDir
  62. //
  63. // Purpose: Get the full path of directory containing netupgrd.dll
  64. //
  65. // Arguments:
  66. // pstrNetupgrdDir [out] the directory path is returned in this
  67. //
  68. // Returns: S_OK or an HRESULT_FROM_WIN32 error code.
  69. //
  70. // Author: kumarp 24-July-97
  71. //
  72. // Notes:
  73. //
  74. HRESULT HrGetNetupgrdDir(OUT tstring* pstrNetupgrdDir)
  75. {
  76. DefineFunctionName("HrGetNetupgrdDir");
  77. AssertValidWritePtr(pstrNetupgrdDir);
  78. HRESULT hr=S_OK;
  79. WCHAR szNetupgrd[MAX_PATH+1];
  80. HMODULE hModule = GetModuleHandle(c_szNetUpgradeDll);
  81. DWORD cPathLen = GetModuleFileName(hModule, szNetupgrd, MAX_PATH);
  82. if (!cPathLen)
  83. {
  84. hr = ERROR_FILE_NOT_FOUND;
  85. goto return_from_function;
  86. }
  87. // split path into components
  88. WCHAR szDrive[_MAX_DRIVE+1];
  89. WCHAR szDir[_MAX_DIR+1];
  90. _wsplitpath(szNetupgrd, szDrive, szDir, NULL, NULL);
  91. *pstrNetupgrdDir = szDrive;
  92. *pstrNetupgrdDir += szDir;
  93. return_from_function:
  94. TraceError(__FUNCNAME__, hr);
  95. return hr;
  96. }
  97. // ======================================================================
  98. // move to common code
  99. // ======================================================================
  100. // ----------------------------------------------------------------------
  101. //
  102. // Function: HrSetupGetLineText
  103. //
  104. // Purpose: Wrapper around SetupGetLineText
  105. //
  106. // Arguments:
  107. // Context [in] pointer to INFCONTEXT
  108. // hinf [in] handle of INF
  109. // pszSection [in] section name
  110. // pszKey [in] key name
  111. // pstrReturnedText [in] pointer to returned text
  112. //
  113. // Returns: S_OK on success, otherwise an error code
  114. //
  115. // Author: kumarp 19-December-97
  116. //
  117. // Notes:
  118. //
  119. HRESULT HrSetupGetLineText(PINFCONTEXT Context,
  120. HINF hinf,
  121. PCWSTR pszSection,
  122. PCWSTR pszKey,
  123. tstring* pstrReturnedText)
  124. {
  125. DefineFunctionName("HrSetupGetLineText");
  126. BOOL fStatus;
  127. HRESULT hr;
  128. WCHAR szLineText[MAX_INF_STRING_LENGTH+1];
  129. if (::SetupGetLineText(Context, hinf, pszSection, pszKey, szLineText,
  130. MAX_INF_STRING_LENGTH, NULL))
  131. {
  132. hr = S_OK;
  133. *pstrReturnedText = szLineText;
  134. }
  135. else
  136. {
  137. hr = HrFromLastWin32Error ();
  138. }
  139. TraceError(__FUNCNAME__, hr);
  140. return hr;
  141. }
  142. // ----------------------------------------------------------------------
  143. //
  144. // Function: HrCopyFiles
  145. //
  146. // Purpose: Recursively copy all files in SrcDir to DstDir
  147. //
  148. // Arguments:
  149. // pszSrcDir [in] source dir
  150. // pszDstDir [in] dest. dir
  151. //
  152. // Returns: S_OK on success, otherwise an error code
  153. //
  154. // Author: kumarp 19-December-97
  155. //
  156. // Notes:
  157. //
  158. HRESULT HrCopyFiles(IN PCWSTR pszSrcDir, IN PCWSTR pszDstDir)
  159. {
  160. DefineFunctionName("HrCopyFiles");
  161. HRESULT hr=S_OK;
  162. BOOL fStatus=FALSE;
  163. DWORD dwError=ERROR_SUCCESS;
  164. TraceTag(ttidNetUpgrade, "%s: Src: %S, Dst: %S",
  165. __FUNCNAME__, pszSrcDir, pszDstDir);
  166. HANDLE hFileContext;
  167. WIN32_FIND_DATA fd;
  168. tstring strSrcDirAllFiles;
  169. tstring strDstDir;
  170. tstring strSrcDir;
  171. tstring strFileSrcFullPath;
  172. tstring strFileDstFullPath;
  173. strSrcDir = pszSrcDir;
  174. AppendToPath(&strSrcDir, c_szEmpty);
  175. strDstDir = pszDstDir;
  176. AppendToPath(&strDstDir, c_szEmpty);
  177. strSrcDirAllFiles = pszSrcDir;
  178. AppendToPath(&strSrcDirAllFiles, L"*");
  179. hFileContext = FindFirstFile(strSrcDirAllFiles.c_str(), &fd);
  180. if (hFileContext != INVALID_HANDLE_VALUE)
  181. {
  182. do
  183. {
  184. strFileSrcFullPath = strSrcDir + fd.cFileName;
  185. strFileDstFullPath = strDstDir + fd.cFileName;
  186. if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  187. {
  188. if (!lstrcmpiW(fd.cFileName, L".") ||
  189. !lstrcmpiW(fd.cFileName, L".."))
  190. {
  191. hr = S_OK;
  192. TraceTag(ttidNetUpgrade, "%s: skipped %S",
  193. __FUNCNAME__, strFileSrcFullPath.c_str());
  194. }
  195. else
  196. {
  197. TraceTag(ttidNetUpgrade, "%s: creating dir: %S",
  198. __FUNCNAME__, strFileDstFullPath.c_str());
  199. fStatus = CreateDirectory(strFileDstFullPath.c_str(), NULL);
  200. if (!fStatus)
  201. {
  202. dwError = GetLastError();
  203. }
  204. if (fStatus || (ERROR_ALREADY_EXISTS == dwError))
  205. {
  206. hr = HrCopyFiles(strFileSrcFullPath.c_str(),
  207. strFileDstFullPath.c_str());
  208. }
  209. else
  210. {
  211. hr = HrFromLastWin32Error();
  212. }
  213. }
  214. }
  215. else if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE))
  216. {
  217. TraceTag(ttidNetUpgrade, "%s: copying %S to %S",
  218. __FUNCNAME__, strFileSrcFullPath.c_str(),
  219. strFileDstFullPath.c_str());
  220. if (CopyFile(strFileSrcFullPath.c_str(),
  221. strFileDstFullPath.c_str(), FALSE))
  222. {
  223. hr = S_OK;
  224. }
  225. else
  226. {
  227. hr = HrFromLastWin32Error();
  228. }
  229. }
  230. else
  231. {
  232. TraceTag(ttidNetUpgrade, "%s: skipped %S",
  233. __FUNCNAME__, strFileSrcFullPath.c_str());
  234. }
  235. if ((S_OK == hr) && FindNextFile(hFileContext, &fd))
  236. {
  237. hr = S_OK;
  238. }
  239. else
  240. {
  241. hr = HrFromLastWin32Error();
  242. }
  243. }
  244. while (S_OK == hr);
  245. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES))
  246. {
  247. hr = S_OK;
  248. }
  249. FindClose(hFileContext);
  250. }
  251. else
  252. {
  253. hr = HrFromLastWin32Error();
  254. }
  255. TraceError(__FUNCNAME__, hr);
  256. return hr;
  257. }
  258. // ----------------------------------------------------------------------
  259. //
  260. // Function: HrGetNumNetCardsPreNT5
  261. //
  262. // Purpose: Get number of netcards installed on a pre-NT5 system
  263. //
  264. // Arguments:
  265. // pcNetCards [out] pointer to num net cards value
  266. //
  267. // Returns: S_OK on success, otherwise an error code
  268. //
  269. // Author: kumarp 13-April-98
  270. //
  271. // Notes: Dont use it on NT5!
  272. //
  273. HRESULT HrGetNumNetCardsPreNT5(OUT UINT* pcNetCards)
  274. {
  275. DefineFunctionName("HrGetNumNetCardsPreNT5");
  276. HRESULT hr=S_OK;
  277. HKEY hkeyAdapters;
  278. *pcNetCards = 0;
  279. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyAdapterHome,
  280. KEY_READ, &hkeyAdapters);
  281. if (S_OK == hr)
  282. {
  283. WCHAR szBuf[MAX_PATH];
  284. FILETIME time;
  285. DWORD dwSize = celems(szBuf);
  286. DWORD dwRegIndex = 0;
  287. while(S_OK == (hr = HrRegEnumKeyEx(hkeyAdapters, dwRegIndex++, szBuf,
  288. &dwSize, NULL, NULL, &time)))
  289. {
  290. Assert(*szBuf);
  291. dwSize = celems(szBuf);
  292. (*pcNetCards)++;
  293. }
  294. RegCloseKey(hkeyAdapters);
  295. }
  296. TraceErrorSkip2(__FUNCNAME__, hr,
  297. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
  298. HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS));
  299. return hr;
  300. }
  301. // ----------------------------------------------------------------------
  302. //
  303. // Function: HrDirExists
  304. //
  305. // Purpose: Check if the given directory exists
  306. //
  307. // Arguments:
  308. // pszDir [in] full path to a directory
  309. //
  310. // Returns: S_OK if it exists, S_FALSE if not, otherwise an error code
  311. //
  312. // Author: kumarp 09-April-98
  313. //
  314. // Notes:
  315. //
  316. HRESULT HrDirectoryExists(IN PCWSTR pszDir)
  317. {
  318. DefineFunctionName("HrDirExists");
  319. HRESULT hr=S_FALSE;
  320. HANDLE hFile=0;
  321. BY_HANDLE_FILE_INFORMATION bhfi;
  322. hFile = CreateFile(pszDir, GENERIC_READ, FILE_SHARE_READ,
  323. NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
  324. NULL);
  325. if(INVALID_HANDLE_VALUE != hFile) {
  326. if(GetFileInformationByHandle(hFile, &bhfi)) {
  327. if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  328. {
  329. hr = S_OK;
  330. }
  331. }
  332. else
  333. {
  334. hr = HrFromLastWin32Error();
  335. }
  336. CloseHandle(hFile);
  337. }
  338. else
  339. {
  340. hr = HrFromLastWin32Error();
  341. }
  342. if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ||
  343. (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr))
  344. {
  345. hr = S_FALSE;
  346. }
  347. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  348. return hr;
  349. }
  350. // ======================================================================
  351. // ----------------------------------------------------------------------
  352. //
  353. // Function: HrGetPreNT5InfIdAndDesc
  354. //
  355. // Purpose: Get pre-NT5 InfID and description of a net component
  356. //
  357. // Arguments:
  358. // hkeyCurrentVersion [in] handle of HKLM\Software\<provider>\<component>\CurrentVersion
  359. // pstrInfId [out] InfID returned
  360. // pstrDescription [out] description returned
  361. // pstrServiceName [out] service name returned
  362. //
  363. // Returns: S_OK on success, otherwise an error code
  364. //
  365. // Author: kumarp 19-December-97
  366. //
  367. // Notes:
  368. //
  369. HRESULT HrGetPreNT5InfIdAndDesc(IN HKEY hkeyCurrentVersion,
  370. OUT tstring* pstrInfId,
  371. OUT tstring* pstrDescription,
  372. OUT tstring* pstrServiceName)
  373. {
  374. DefineFunctionName("HrGetPreNT5InfIdAndDesc");
  375. Assert(hkeyCurrentVersion);
  376. AssertValidWritePtr(pstrInfId);
  377. HRESULT hr=S_OK;
  378. HKEY hkeyNetRules;
  379. hr = HrRegOpenKeyEx(hkeyCurrentVersion, c_szRegKeyNetRules,
  380. KEY_READ, &hkeyNetRules);
  381. if (S_OK == hr)
  382. {
  383. hr = HrRegQueryString(hkeyNetRules, c_szRegValInfOption, pstrInfId);
  384. if ((S_OK == hr) && pstrDescription)
  385. {
  386. hr = HrRegQueryString(hkeyCurrentVersion, c_szRegValDescription,
  387. pstrDescription);
  388. }
  389. if ((S_OK == hr) && pstrServiceName)
  390. {
  391. hr = HrRegQueryString(hkeyCurrentVersion, c_szRegValServiceName,
  392. pstrServiceName);
  393. }
  394. RegCloseKey(hkeyNetRules);
  395. }
  396. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  397. {
  398. hr = S_FALSE;
  399. }
  400. TraceErrorOptional(__FUNCNAME__, hr, (hr == S_FALSE));
  401. return hr;
  402. }
  403. // ----------------------------------------------------------------------
  404. //
  405. // Function: GetUnsupportedMessage
  406. //
  407. // Purpose: Generate a message of the form:
  408. // Unsupported Net Card: DEC FDDIcontroller/PCI (DEFPA)
  409. //
  410. // Arguments:
  411. // pszComponentType [in] type of component (net card/service/proto)
  412. // pszPreNT5InfId [in] pre-NT5 InfID
  413. // pszDescription [in] description
  414. // pstrMsg [out] generated message
  415. //
  416. // Returns: None
  417. //
  418. // Author: kumarp 19-December-97
  419. //
  420. // Notes:
  421. //
  422. void GetUnsupportedMessage(IN PCWSTR pszComponentType,
  423. IN PCWSTR pszPreNT5InfId,
  424. IN PCWSTR pszDescription,
  425. OUT tstring* pstrMsg)
  426. {
  427. AssertValidReadPtr(pszPreNT5InfId);
  428. AssertValidReadPtr(pszDescription);
  429. AssertValidWritePtr(pstrMsg);
  430. if (!pszComponentType)
  431. {
  432. pszComponentType = c_szComponent;
  433. }
  434. const WCHAR c_szUnsupported[] = L"Possibly unsupported ";
  435. *pstrMsg = c_szUnsupported;
  436. *pstrMsg = *pstrMsg + pszComponentType + L" : " +
  437. pszDescription + L" (" + pszPreNT5InfId + L")";
  438. }
  439. // ----------------------------------------------------------------------
  440. //
  441. // Function: GetUnsupportedMessageBool
  442. //
  443. // Purpose: Generate a message of the form:
  444. // Unsupported Net Card: DEC FDDIcontroller/PCI (DEFPA)
  445. //
  446. // Arguments:
  447. // fIsHardwareComponent [in] TRUE for a net card
  448. // pszPreNT5InfId [in] pre-NT5 InfID
  449. // pszDescription [in] description
  450. // pstrMsg [out] generated message
  451. //
  452. // Returns: None
  453. //
  454. // Author: kumarp 19-December-97
  455. //
  456. // Notes:
  457. //
  458. void GetUnsupportedMessageBool(IN BOOL fIsHardwareComponent,
  459. IN PCWSTR pszPreNT5InfId,
  460. IN PCWSTR pszDescription,
  461. OUT tstring* pstrMsg)
  462. {
  463. AssertValidReadPtr(pszPreNT5InfId);
  464. AssertValidReadPtr(pszDescription);
  465. AssertValidWritePtr(pstrMsg);
  466. GetUnsupportedMessage(fIsHardwareComponent ?
  467. c_szNetCard : c_szComponent,
  468. pszPreNT5InfId, pszDescription, pstrMsg);
  469. }
  470. // ----------------------------------------------------------------------
  471. //
  472. // Function: ConvertMultiSzToDelimitedList
  473. //
  474. // Purpose: Convert a multi-sz to a delimited list
  475. //
  476. // Arguments:
  477. // mszList [in] multi-sz
  478. // chDelimeter [in] delimiter
  479. // pstrList [out] delimited list
  480. //
  481. // Returns: None
  482. //
  483. // Author: kumarp 19-December-97
  484. //
  485. // Notes:
  486. //
  487. void ConvertMultiSzToDelimitedList(IN PCWSTR mszList,
  488. IN WCHAR chDelimeter,
  489. OUT tstring* pstrList)
  490. {
  491. ULONG ulLen;
  492. *pstrList = c_szEmpty;
  493. if (mszList)
  494. {
  495. while (*mszList)
  496. {
  497. ulLen = lstrlen(mszList);
  498. *pstrList += mszList;
  499. *pstrList += chDelimeter;
  500. mszList += (ulLen + 1);
  501. }
  502. }
  503. }
  504. //+---------------------------------------------------------------------------
  505. //
  506. // Function: FIsPreNT5NetworkingInstalled
  507. //
  508. // Purpose: Find out if atleast one networking component is installed
  509. //
  510. // Arguments: None
  511. //
  512. // Returns: TRUE on success, FALSE otherwise
  513. //
  514. // Author: kumarp 29-July-98
  515. //
  516. // Notes: Valid only on pre NT5 versions
  517. //
  518. BOOL FIsPreNT5NetworkingInstalled()
  519. {
  520. DefineFunctionName("FIsPreNT5NetworkingInstalled");
  521. HRESULT hr=S_OK;
  522. UINT cAdapters=0;
  523. if ((S_OK == HrGetNumNetCardsPreNT5(&cAdapters)) &&
  524. (cAdapters > 0))
  525. {
  526. return TRUE;
  527. }
  528. else
  529. {
  530. TraceTag(ttidNetUpgrade, "%s: no netcard found, trying to find other network components...", __FUNCNAME__);
  531. static const PCWSTR c_aszPreNt5NetworkingServices[] =
  532. {
  533. L"Alerter",
  534. L"Browser",
  535. L"DHCP",
  536. L"IpRip",
  537. L"LanmanServer",
  538. L"LanmanWorkstation",
  539. L"Messenger",
  540. L"NWCWorkstation",
  541. L"NetBIOS",
  542. L"NetBT",
  543. L"NtLmSsp",
  544. L"NwlnkIpx",
  545. L"NwlnkNb",
  546. L"NwlnkRip",
  547. L"NwlnkSpx",
  548. L"RasAuto",
  549. L"RasMan",
  550. L"Rdr",
  551. L"RelayAgent",
  552. L"RemoteAccess",
  553. L"Router",
  554. L"Rpclocator",
  555. L"Srv",
  556. L"Tcpip",
  557. };
  558. for (int i = 0; i < celems(c_aszPreNt5NetworkingServices); i++)
  559. {
  560. if (FIsServiceKeyPresent(c_aszPreNt5NetworkingServices[i]))
  561. {
  562. return TRUE;
  563. }
  564. }
  565. }
  566. TraceTag(ttidNetUpgrade, "%s: no netcards or net components found",
  567. __FUNCNAME__);
  568. return FALSE;
  569. }
  570. #ifdef ENABLETRACE
  571. // ----------------------------------------------------------------------
  572. //
  573. // Function: TraceStringList
  574. //
  575. // Purpose: Trace items of a TStringList
  576. //
  577. // Arguments:
  578. // ttid [in] trace tag id to use
  579. // pszMsgPrefix [in] prefix to use
  580. // sl [in] list
  581. //
  582. // Returns: None
  583. //
  584. // Author: kumarp 19-December-97
  585. //
  586. // Notes:
  587. //
  588. void TraceStringList(IN TraceTagId ttid,
  589. IN PCWSTR pszMsgPrefix,
  590. IN TStringList& sl)
  591. {
  592. tstring strTemp;
  593. ConvertStringListToCommaList(sl, strTemp);
  594. TraceTag(ttid, "%S : %S", pszMsgPrefix, strTemp.c_str());
  595. }
  596. // ----------------------------------------------------------------------
  597. //
  598. // Function: TraceMultiSz
  599. //
  600. // Purpose: Trace elements of a multi-sz
  601. //
  602. // Arguments:
  603. // ttid [in] trace tag id to use
  604. // pszMsgPrefix [in] prefix to use
  605. // msz [in] multi-sz
  606. //
  607. // Returns: None
  608. //
  609. // Author: kumarp 19-December-97
  610. //
  611. // Notes:
  612. //
  613. void TraceMultiSz(IN TraceTagId ttid,
  614. IN PCWSTR pszMsgPrefix,
  615. IN PCWSTR msz)
  616. {
  617. tstring strTemp;
  618. ConvertMultiSzToDelimitedList(msz, ',', &strTemp);
  619. TraceTag(ttid, "%S : %S", pszMsgPrefix, strTemp.c_str());
  620. }
  621. #endif