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.

799 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N E T U P G R D . C P P
  7. //
  8. // Contents: DllMain and winnt32.exe plug-in exported functions
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 25-Nov-1996
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <winnt32p.h>
  18. #include "afilestr.h"
  19. #include "conflict.h"
  20. #include "kkcwinf.h"
  21. #include "kkutils.h"
  22. #include "nceh.h"
  23. #include "ncreg.h"
  24. #include "netreg.h"
  25. #include "netupgrd.h"
  26. #include "nuutils.h"
  27. #include "oemupg.h"
  28. #include "resource.h"
  29. #include "dhcpupg.h"
  30. extern const WCHAR c_szNetUpgradeDll[];
  31. extern const WCHAR c_szAfUnknown[];
  32. //Global
  33. WINNT32_PLUGIN_INIT_INFORMATION_BLOCK g_PlugInInfo;
  34. NetUpgradeInfo g_NetUpgradeInfo;
  35. CWInfFile* g_pwifAnswerFile;
  36. HINSTANCE g_hinst;
  37. DWORD g_dwUpgradeError;
  38. void CleanupNetupgrdTempFiles();
  39. void GetNetworkingSections(IN CWInfFile* pwif,
  40. OUT TStringList* pslSections);
  41. const WCHAR c_szExceptionInNetupgrd[] = L"netupgrd.dll threw an exception";
  42. EXTERN_C
  43. BOOL
  44. WINAPI
  45. DllMain (
  46. HINSTANCE hInstance,
  47. DWORD dwReason,
  48. LPVOID /* lpReserved */)
  49. {
  50. if (DLL_PROCESS_ATTACH == dwReason)
  51. {
  52. g_hinst = hInstance;
  53. DisableThreadLibraryCalls(hInstance);
  54. InitializeDebugging();
  55. }
  56. else if (DLL_PROCESS_DETACH == dwReason)
  57. {
  58. UnInitializeDebugging();
  59. }
  60. return TRUE;
  61. }
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Function: HrGetProductTypeUpgradingFrom
  65. //
  66. // Purpose: Determine the product type of the current system
  67. //
  68. // Arguments:
  69. // ppt [out] pointer to
  70. //
  71. // Returns: S_OK on success, otherwise an error code
  72. //
  73. HRESULT HrGetProductTypeUpgradingFrom(
  74. OUT PRODUCTTYPE* ppt)
  75. {
  76. Assert (ppt);
  77. *ppt = NT_WORKSTATION;
  78. HRESULT hr;
  79. HKEY hkeyProductOptions;
  80. hr = HrRegOpenKeyEx(
  81. HKEY_LOCAL_MACHINE,
  82. L"System\\CurrentControlSet\\Control\\ProductOptions",
  83. KEY_READ, &hkeyProductOptions);
  84. if (S_OK == hr)
  85. {
  86. WCHAR szProductType [64];
  87. ULONG cbProductType = sizeof(szProductType);
  88. hr = HrRegQuerySzBuffer(
  89. hkeyProductOptions,
  90. L"ProductType",
  91. szProductType,
  92. &cbProductType);
  93. if (S_OK == hr)
  94. {
  95. if (0 != lstrcmpiW(szProductType, L"WinNT"))
  96. {
  97. *ppt = NT_SERVER;
  98. }
  99. }
  100. RegCloseKey(hkeyProductOptions);
  101. }
  102. return hr;
  103. }
  104. //+---------------------------------------------------------------------------
  105. // The following four functions are required to be exported so that
  106. // winnt32.exe can correctly use this plug-in DLL during down level
  107. // upgrade for description of each see winnt32p.h
  108. //
  109. //+---------------------------------------------------------------------------
  110. //
  111. // Function: Winnt32PluginInit
  112. //
  113. // Purpose: Initialize the DLL
  114. //
  115. // Arguments:
  116. // pInfo [in] winnt32 plug-in initialization info
  117. //
  118. // Returns: ERROR_SUCCESS on success, else win32 error code
  119. //
  120. // Author: kumarp 19-December-97
  121. //
  122. // Notes: see winnt32p.h for more information
  123. //
  124. DWORD
  125. CALLBACK
  126. Winnt32PluginInit(
  127. PWINNT32_PLUGIN_INIT_INFORMATION_BLOCK pInfo)
  128. {
  129. DefineFunctionName("Winnt32PluginInit");
  130. TraceFunctionEntry(ttidNetUpgrade);
  131. Assert (pInfo);
  132. CopyMemory(&g_PlugInInfo, pInfo, sizeof(g_PlugInInfo));
  133. // We should only be doing this once.
  134. //
  135. Assert (0 == g_NetUpgradeInfo.To.dwBuildNumber);
  136. Assert (0 == g_NetUpgradeInfo.From.dwBuildNumber);
  137. g_NetUpgradeInfo.To.ProductType = *g_PlugInInfo.ProductType;
  138. g_NetUpgradeInfo.To.dwBuildNumber = g_PlugInInfo.BuildNumber;
  139. g_dwUpgradeError = ERROR_OPERATION_ABORTED;
  140. OSVERSIONINFO osv;
  141. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  142. if (GetVersionEx(&osv))
  143. {
  144. // This DLL doesn't upgrade anything but Windows NT.
  145. //
  146. if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
  147. {
  148. PRODUCTTYPE pt;
  149. HRESULT hr = HrGetProductTypeUpgradingFrom(&pt);
  150. if (S_OK == hr)
  151. {
  152. g_NetUpgradeInfo.From.dwBuildNumber = osv.dwBuildNumber;
  153. g_NetUpgradeInfo.From.ProductType = pt;
  154. NC_TRY
  155. {
  156. g_dwUpgradeError = NOERROR;
  157. (void) HrInitNetUpgrade();
  158. }
  159. NC_CATCH_ALL
  160. {
  161. TraceTag(ttidNetUpgrade, "%s: exception!!", __FUNCNAME__);
  162. g_dwUpgradeError = ERROR_OPERATION_ABORTED;
  163. AbortUpgradeFn(g_dwUpgradeError, c_szExceptionInNetupgrd);
  164. }
  165. }
  166. }
  167. }
  168. TraceTag(ttidNetUpgrade, "%s: returning status code: %ld",
  169. __FUNCNAME__, g_dwUpgradeError);
  170. return g_dwUpgradeError;
  171. }
  172. //+---------------------------------------------------------------------------
  173. //
  174. // Function: Winnt32PluginGetPages
  175. //
  176. // Purpose: Supply wizard pages to winnt32.exe
  177. //
  178. // Arguments:
  179. // PageCount1 [in] number of pages in group 1
  180. // Pages1 [in] array of pages in group 1
  181. // PageCount2 [in] number of pages in group 2
  182. // Pages2 [in] array of pages in group 2
  183. // PageCount3 [in] number of pages in group 3
  184. // Pages3 [in] array of pages in group 3
  185. //
  186. // Returns: ERROR_SUCCESS on success, else win32 error code
  187. //
  188. // Author: kumarp 19-December-97
  189. //
  190. // Notes: see winnt32p.h for more information
  191. //
  192. DWORD
  193. CALLBACK
  194. Winnt32PluginGetPages(
  195. PUINT PageCount1,
  196. LPPROPSHEETPAGE *Pages1,
  197. PUINT PageCount2,
  198. LPPROPSHEETPAGE *Pages2,
  199. PUINT PageCount3,
  200. LPPROPSHEETPAGE *Pages3)
  201. {
  202. //We dont need any UI for upgrade and hence no pages
  203. *PageCount1 = 0;
  204. *PageCount2 = 0;
  205. *PageCount3 = 0;
  206. *Pages1 = NULL;
  207. *Pages2 = NULL;
  208. *Pages3 = NULL;
  209. return NOERROR;
  210. }
  211. //+---------------------------------------------------------------------------
  212. //
  213. // Function: Winnt32WriteParams
  214. //
  215. // Purpose: Write network parameters to the answerfile
  216. //
  217. // Arguments:
  218. // FileName [in] name of answerfile
  219. //
  220. // Returns: ERROR_SUCCESS on success, else win32 error code
  221. //
  222. // Author: kumarp 19-December-97
  223. //
  224. // Notes: see winnt32p.h for more information
  225. //
  226. DWORD
  227. CALLBACK
  228. Winnt32WriteParams(
  229. PCWSTR FileName)
  230. {
  231. DefineFunctionName("Winnt32WriteParams");
  232. TraceFunctionEntry(ttidNetUpgrade);
  233. TraceTag(ttidNetUpgrade, "netupgrd.dll: Winnt32WriteParams(%S)", FileName);
  234. NC_TRY
  235. {
  236. if (*g_PlugInInfo.UpgradeFlag && (!(*g_PlugInInfo.CancelledFlag)))
  237. {
  238. // g_pwifAnswerFile needs to be global since functions in
  239. // oemnuex.cpp require it that way.
  240. //
  241. g_pwifAnswerFile = new CWInfFile();
  242. // initialize answer file class
  243. if ((g_pwifAnswerFile == NULL) ||
  244. (g_pwifAnswerFile->Init() == FALSE))
  245. {
  246. AssertSz(FALSE,"Winnt32WriteParams 1 - Failed to initialize CWInfFile");
  247. return(ERROR_OPERATION_ABORTED);
  248. }
  249. g_pwifAnswerFile->Open(FileName);
  250. // ------------------------------------------------------------
  251. //$ REVIEW kumarp 25-November-98
  252. //
  253. // the code between the two dashed lines in temporary.
  254. //
  255. // Currently we do not support merging of the system generated answerfile
  256. // with the user supplied answerfile, because the code was never
  257. // designed to handle that. This causes problem (#175623) when a user
  258. // supplies an answerfile with "NtUpgrade = Yes" value. To get
  259. // around this problem, we just remove all user supplied
  260. // networking sections using the following code. As an additional
  261. // special case, we preserve the key NetComponentsToRemove if
  262. // present in the [Networking] section of the user supplied answerfile.
  263. //
  264. CWInfSection* pwisNetworking;
  265. TStringList slNetComponentsToRemove;
  266. // remember the value of NetComponentsToRemove
  267. if (pwisNetworking =
  268. g_pwifAnswerFile->FindSection(c_szAfSectionNetworking))
  269. {
  270. pwisNetworking->GetStringListValue(c_szAfNetComponentsToRemove,
  271. slNetComponentsToRemove);
  272. }
  273. // get the list of networking sections in the user supplied file
  274. TStringList slUserSuppliedNetworkingSections;
  275. GetNetworkingSections(g_pwifAnswerFile,
  276. &slUserSuppliedNetworkingSections);
  277. TraceStringList(ttidNetUpgrade,
  278. L"User supplied networking sections",
  279. slUserSuppliedNetworkingSections);
  280. // remove the user supplied networking sections
  281. g_pwifAnswerFile->RemoveSections(slUserSuppliedNetworkingSections);
  282. // if NetComponentsToRemove was specified, re-insert it
  283. if (slNetComponentsToRemove.size())
  284. {
  285. pwisNetworking =
  286. g_pwifAnswerFile->AddSection(c_szAfSectionNetworking);
  287. pwisNetworking->AddKey(c_szAfNetComponentsToRemove,
  288. slNetComponentsToRemove);
  289. }
  290. // 295708: cached ptrs may be trashed, so close and reopen the file
  291. // Note: this fix is considered temporary for beta3. The right fix
  292. // is to either fix up the trashed ptrs when removing the sections,
  293. // or to check when accessing the ptrs later. The crash should be
  294. // easy to repro by removing the block below and using the answerfile
  295. // attached to the bug.
  296. //
  297. g_pwifAnswerFile->Close();
  298. delete g_pwifAnswerFile;
  299. g_pwifAnswerFile = NULL;
  300. g_pwifAnswerFile = new CWInfFile();
  301. // initialize answer file class
  302. if ((g_pwifAnswerFile == NULL) ||
  303. (g_pwifAnswerFile->Init() == FALSE))
  304. {
  305. AssertSz(FALSE,"Winnt32WriteParams 2 - Failed to initialize CWInfFile");
  306. return(ERROR_OPERATION_ABORTED);
  307. }
  308. g_pwifAnswerFile->Open(FileName);
  309. // ------------------------------------------------------------
  310. WriteNetworkInfoToAnswerFile(g_pwifAnswerFile);
  311. BOOL fStatus = g_pwifAnswerFile->Close();
  312. delete g_pwifAnswerFile;
  313. g_pwifAnswerFile = NULL;
  314. if (!fStatus)
  315. {
  316. AbortUpgradeId(GetLastError(), IDS_E_WritingAnswerFile);
  317. }
  318. else if( DhcpUpgGetLastError() != NO_ERROR )
  319. {
  320. TraceTag(ttidNetUpgrade, "DhcpUpgGetLastError: %d", DhcpUpgGetLastError() );
  321. AbortUpgradeId( DhcpUpgGetLastError(), IDS_E_DhcpServerUpgradeError);
  322. }
  323. }
  324. else
  325. {
  326. TraceTag(ttidNetUpgrade, "%s: network parameters not written to answerfile: g_pfUpgrade is %d, g_pfCancelled is %d",
  327. __FUNCNAME__, *g_PlugInInfo.UpgradeFlag,
  328. *g_PlugInInfo.CancelledFlag);
  329. }
  330. }
  331. NC_CATCH_ALL
  332. {
  333. TraceTag(ttidNetUpgrade, "%s: exception!!", __FUNCNAME__);
  334. g_dwUpgradeError = ERROR_OPERATION_ABORTED;
  335. AbortUpgradeFn(g_dwUpgradeError, c_szExceptionInNetupgrd);
  336. }
  337. TraceTag(ttidNetUpgrade, "%s: returning status code: %ld, CancelledFlag: %ld",
  338. __FUNCNAME__, g_dwUpgradeError, (DWORD) (*g_PlugInInfo.CancelledFlag));
  339. return g_dwUpgradeError;
  340. }
  341. //+---------------------------------------------------------------------------
  342. //
  343. // Function: Winnt32Cleanup
  344. //
  345. // Purpose: Cleanup
  346. //
  347. // Arguments: None
  348. //
  349. // Returns: ERROR_SUCCESS on success, else win32 error code
  350. //
  351. // Author: kumarp 19-December-97
  352. //
  353. // Notes: see winnt32p.h for more information
  354. //
  355. DWORD
  356. CALLBACK
  357. Winnt32Cleanup(
  358. VOID)
  359. {
  360. DefineFunctionName("Winnt32Cleanup");
  361. TraceFunctionEntry(ttidNetUpgrade);
  362. NC_TRY
  363. {
  364. // netmap-info and conflicts-list is initialized in
  365. // HrInitNetUpgrade and destroyed here
  366. //
  367. UnInitNetMapInfo();
  368. UninitConflictList();
  369. if (*g_PlugInInfo.CancelledFlag)
  370. {
  371. CleanupNetupgrdTempFiles();
  372. DhcpUpgCleanupDhcpTempFiles();
  373. }
  374. }
  375. NC_CATCH_ALL
  376. {
  377. TraceTag(ttidNetUpgrade, "%s: exception!!", __FUNCNAME__);
  378. g_dwUpgradeError = ERROR_OPERATION_ABORTED;
  379. }
  380. TraceTag(ttidNetUpgrade, "%s: returning status code: %ld",
  381. __FUNCNAME__, g_dwUpgradeError);
  382. return g_dwUpgradeError;
  383. }
  384. //+---------------------------------------------------------------------------
  385. //
  386. // Function: GetSections
  387. //
  388. // Purpose: Enumerate over the keys in the specified section and
  389. // return value of each key in a list.
  390. //
  391. // Arguments:
  392. // pwif [in] answerfile
  393. // pszSection [in] section to use
  394. // pslSections [out] list of values of keys in that section
  395. //
  396. // Returns: None
  397. //
  398. // Author: kumarp 25-November-98
  399. //
  400. // Notes:
  401. // For example:
  402. // if pszSection == NetServices and the answerfile has the following section
  403. //
  404. // [NetServices]
  405. // MS_Server = params.MS_Server
  406. // MS_Foo = params.MS_Foo
  407. // bar = p.bar
  408. //
  409. // then this function returns the following list:
  410. // NetServices,params.MS_Server,params.MS_Foo,p.bar
  411. //
  412. void
  413. GetSections(
  414. IN CWInfFile* pwif,
  415. IN PCWSTR pszSection,
  416. OUT TStringList* pslSections)
  417. {
  418. AssertValidReadPtr(pwif);
  419. AssertValidReadPtr(pszSection);
  420. AssertValidWritePtr(pslSections);
  421. PCWSTR pszParamsSection;
  422. CWInfKey* pwik;
  423. CWInfSection* pwis;
  424. if (pwis = pwif->FindSection(pszSection))
  425. {
  426. pslSections->push_back(new tstring(pszSection));
  427. pwik = pwis->FirstKey();
  428. do
  429. {
  430. if (pszParamsSection = pwik->GetStringValue(NULL))
  431. {
  432. pslSections->push_back(new tstring(pszParamsSection));
  433. }
  434. }
  435. while (pwik = pwis->NextKey());
  436. }
  437. }
  438. //+---------------------------------------------------------------------------
  439. //
  440. // Function: GetNetworkingSections
  441. //
  442. // Purpose: Locate all networking related sections in the specified file
  443. // and return their names in a list
  444. //
  445. // Arguments:
  446. // pwif [in] answerfile
  447. // pslSections [out] list of networking sections
  448. //
  449. // Returns: None
  450. //
  451. // Author: kumarp 25-November-98
  452. //
  453. // Notes:
  454. //
  455. void
  456. GetNetworkingSections(
  457. IN CWInfFile* pwif,
  458. OUT TStringList* pslSections)
  459. {
  460. if (pwif->FindSection(c_szAfSectionNetworking))
  461. {
  462. pslSections->push_back(new tstring(c_szAfSectionNetworking));
  463. }
  464. if (pwif->FindSection(c_szAfSectionNetBindings))
  465. {
  466. pslSections->push_back(new tstring(c_szAfSectionNetBindings));
  467. }
  468. GetSections(pwif, c_szAfSectionNetAdapters, pslSections);
  469. GetSections(pwif, c_szAfSectionNetServices, pslSections);
  470. GetSections(pwif, c_szAfSectionNetClients, pslSections);
  471. TStringList slProtocolSections;
  472. TStringListIter pos;
  473. tstring strSection;
  474. CWInfSection* pwis;
  475. TStringList slAdapterSections;
  476. GetSections(pwif, c_szAfSectionNetProtocols, &slProtocolSections);
  477. for (pos = slProtocolSections.begin();
  478. pos != slProtocolSections.end(); )
  479. {
  480. strSection = **pos++;
  481. if (pwis = pwif->FindSection(strSection.c_str()))
  482. {
  483. pslSections->push_back(new tstring(strSection));
  484. pwis->GetStringListValue(c_szAfAdapterSections,
  485. slAdapterSections);
  486. pslSections->splice(pslSections->end(),
  487. slAdapterSections,
  488. slAdapterSections.begin(),
  489. slAdapterSections.end());
  490. }
  491. }
  492. }
  493. //+---------------------------------------------------------------------------
  494. //
  495. // Function: CleanupNetupgrdTempFiles
  496. //
  497. // Purpose: Delete any temp files/dirs created
  498. //
  499. // Arguments: None
  500. //
  501. // Returns: None
  502. //
  503. // Author: kumarp 19-December-97
  504. //
  505. // Notes:
  506. //
  507. VOID
  508. CleanupNetupgrdTempFiles(
  509. VOID)
  510. {
  511. HRESULT hr=S_OK;
  512. tstring strNetupgrdTempDir;
  513. hr = HrGetNetUpgradeTempDir(&strNetupgrdTempDir);
  514. if (S_OK == hr)
  515. {
  516. hr = HrDeleteDirectory(strNetupgrdTempDir.c_str(), TRUE);
  517. }
  518. }
  519. //+---------------------------------------------------------------------------
  520. //
  521. // Function: AbortUpgradeFn
  522. //
  523. // Purpose: Helper function for aborting upgrade
  524. //
  525. // Arguments:
  526. // dwErrorCode [in] win32 error code
  527. // pszMessage [in] message to be traced
  528. //
  529. // Returns: None
  530. //
  531. // Author: kumarp 19-December-97
  532. //
  533. // Notes:
  534. //
  535. VOID
  536. AbortUpgradeFn(
  537. IN DWORD dwErrorCode,
  538. IN PCWSTR pszMessage)
  539. {
  540. DefineFunctionName("AbortUpgradeFn");
  541. g_dwUpgradeError = dwErrorCode;
  542. if (g_PlugInInfo.CancelledFlag)
  543. {
  544. *g_PlugInInfo.CancelledFlag = TRUE;
  545. }
  546. else
  547. {
  548. TraceTag(ttidNetUpgrade, "%s: g_PlugInInfo.CancelledFlag is NULL!!",
  549. __FUNCNAME__);
  550. }
  551. TraceTag(ttidError, "AbortUpgrade: %d: %S", dwErrorCode, pszMessage);
  552. }
  553. //+---------------------------------------------------------------------------
  554. //
  555. // Function: AbortUpgradeSz
  556. //
  557. // Purpose: Helper function for aborting upgrade
  558. //
  559. // Arguments:
  560. // dwErrorCode [in] win32 error code
  561. // pszMessage [in] message to be displayed and traced
  562. //
  563. // Returns: None
  564. //
  565. // Author: kumarp 19-December-97
  566. //
  567. // Notes:
  568. //
  569. VOID
  570. AbortUpgradeSz(
  571. IN DWORD dwErrorCode,
  572. IN PCWSTR pszMessage)
  573. {
  574. AssertValidReadPtr(pszMessage);
  575. tstring strMessage;
  576. strMessage = pszMessage;
  577. strMessage += L"\n\n";
  578. strMessage += SzLoadString(g_hinst, IDS_E_SetupCannotContinue);
  579. AbortUpgradeFn(dwErrorCode, pszMessage);
  580. MessageBox (NULL, strMessage.c_str(),
  581. SzLoadString(g_hinst, IDS_NetupgrdCaption),
  582. MB_OK | MB_TASKMODAL);
  583. }
  584. //+---------------------------------------------------------------------------
  585. //
  586. // Function: AbortUpgradeId
  587. //
  588. // Purpose: Helper function for aborting upgrade
  589. //
  590. // Arguments:
  591. // dwErrorCode [in] win32 error code
  592. // dwResourceId [in] resource ID of message to be displayed
  593. //
  594. // Returns: None
  595. //
  596. // Author: kumarp 19-December-97
  597. //
  598. // Notes:
  599. //
  600. VOID
  601. AbortUpgradeId (
  602. IN DWORD dwErrorCode,
  603. IN DWORD dwResourceId)
  604. {
  605. Assert(g_hinst);
  606. PCWSTR pszMessage;
  607. pszMessage = SzLoadString(g_hinst, dwResourceId);
  608. AbortUpgradeSz(dwErrorCode, pszMessage);
  609. }
  610. //+---------------------------------------------------------------------------
  611. //
  612. // Function: FIsUpgradeAborted
  613. //
  614. // Purpose: Determine if the upgrade has been aborted
  615. //
  616. // Arguments: None
  617. //
  618. // Returns: TRUE on success, FALSE otherwise
  619. //
  620. // Author: kumarp 19-December-97
  621. //
  622. // Notes:
  623. //
  624. BOOL
  625. FIsUpgradeAborted(
  626. VOID)
  627. {
  628. return g_PlugInInfo.CancelledFlag && *g_PlugInInfo.CancelledFlag;
  629. }
  630. //+---------------------------------------------------------------------------
  631. //
  632. // Function: FGetConfirmationForAbortingUpgrade
  633. //
  634. // Purpose: Ask user confirmation for aborting upgrade
  635. //
  636. // Arguments:
  637. // pszMessage [in] message prompt
  638. //
  639. // Returns: TRUE on success, FALSE otherwise
  640. //
  641. // Author: kumarp 19-December-97
  642. //
  643. // Notes:
  644. //
  645. BOOL
  646. FGetConfirmationForAbortingUpgrade(
  647. IN PCWSTR pszMessage)
  648. {
  649. tstring strMessage;
  650. if (pszMessage)
  651. {
  652. strMessage = pszMessage;
  653. strMessage += L"\n\n";
  654. }
  655. PCWSTR pszDoYouWantToAbortUpgrade =
  656. SzLoadString(g_hinst, IDS_DoYouWantToAbortUpgrade);
  657. strMessage += pszDoYouWantToAbortUpgrade;
  658. DWORD dwRet = MessageBox (NULL, strMessage.c_str(),
  659. SzLoadString(g_hinst, IDS_NetupgrdCaption),
  660. MB_YESNO | MB_TASKMODAL);
  661. return dwRet == IDYES;
  662. }
  663. //+---------------------------------------------------------------------------
  664. //
  665. // Function: FGetConfirmationAndAbortUpgrade
  666. //
  667. // Purpose: Abort upgrade if user confirms
  668. //
  669. // Arguments:
  670. // pszMessage [in] message prompt
  671. //
  672. // Returns: TRUE on success, FALSE otherwise
  673. //
  674. // Author: kumarp 19-December-97
  675. //
  676. // Notes:
  677. //
  678. BOOL
  679. FGetConfirmationAndAbortUpgrade(
  680. IN PCWSTR pszMessage)
  681. {
  682. BOOL fUpgradeAborted=FALSE;
  683. if (FGetConfirmationForAbortingUpgrade(pszMessage))
  684. {
  685. AbortUpgradeFn(ERROR_SUCCESS, pszMessage);
  686. fUpgradeAborted = TRUE;
  687. }
  688. return fUpgradeAborted;
  689. }
  690. //+---------------------------------------------------------------------------
  691. //
  692. // Function: FGetConfirmationAndAbortUpgradeId
  693. //
  694. // Purpose: Abort upgrade if user confirms
  695. //
  696. // Arguments:
  697. // dwErrorMessageId [in] message prompt
  698. //
  699. // Returns: TRUE on success, FALSE otherwise
  700. //
  701. // Author: kumarp 19-December-97
  702. //
  703. // Notes:
  704. //
  705. BOOL
  706. FGetConfirmationAndAbortUpgradeId(
  707. IN DWORD dwErrorMessageId)
  708. {
  709. return FGetConfirmationAndAbortUpgrade(SzLoadString(g_hinst,
  710. dwErrorMessageId));
  711. }