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.

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