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.

376 lines
10 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 2000 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: setup.cpp
  6. //
  7. // Project: Windows 2000 IAS
  8. //
  9. // Description: IAS Upgrade class implementation
  10. //
  11. // Author: tperraut 06/13/2000
  12. //
  13. // Revision
  14. //
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "stdafx.h"
  17. #include "doupgrade.h"
  18. #include "iasdb.h"
  19. #include "setup.h" // to get the CIASUpgrade class
  20. ////////////////////////////
  21. // CIASUpgrade Constructor
  22. ////////////////////////////
  23. CIASUpgrade::CIASUpgrade()
  24. {
  25. ///////////////////////////////////////////////////////////////
  26. // Expand the three string even if two only might be needed in
  27. // the netshell scenario
  28. // The mdb files can be:
  29. // \ias\iasnew.mdb";
  30. // \ias\ias.mdb";
  31. // \ias\iasold.mdb";
  32. ///////////////////////////////////////////////////////////////
  33. wchar_t sysWow64Path[MAX_PATH+1] = L"";
  34. //
  35. // << GetSystemWow64Directory>> returns the number of chars copied to the buffer.
  36. // If we get zero back, then we need to check the last error code to see what the
  37. // reason for failure was. If it was call not implemented then we know we are
  38. // running on native x86.
  39. //
  40. UINT uReturn = GetSystemWow64DirectoryW(sysWow64Path, MAX_PATH);
  41. if ( uReturn != 0 )
  42. {
  43. // proper path found
  44. m_pIASNewMdb = sysWow64Path;
  45. m_pIASNewMdb += L"\\ias\\iasnew.mdb";
  46. m_pIASMdb = sysWow64Path;
  47. m_pIASMdb += L"\\ias\\ias.mdb";
  48. m_pIASOldMdb = sysWow64Path;
  49. m_pIASOldMdb += L"\\ias\\iasold.mdb";
  50. }
  51. else
  52. {
  53. // check the error message
  54. DWORD error = GetLastError();
  55. if (ERROR_CALL_NOT_IMPLEMENTED == error)
  56. {
  57. // Pure 32 bits environment
  58. uReturn = GetWindowsDirectoryW(sysWow64Path, MAX_PATH);
  59. if ( uReturn != 0 )
  60. {
  61. // proper path found
  62. m_pIASNewMdb = sysWow64Path;
  63. m_pIASNewMdb += L"\\System32\\ias\\iasnew.mdb";
  64. m_pIASMdb = sysWow64Path;
  65. m_pIASMdb += L"\\System32\\ias\\ias.mdb";
  66. m_pIASOldMdb = sysWow64Path;
  67. m_pIASOldMdb += L"\\System32\\ias\\iasold.mdb";
  68. }
  69. else
  70. {
  71. _com_issue_error(HRESULT_FROM_WIN32(error));
  72. }
  73. }
  74. else
  75. {
  76. _com_issue_error(HRESULT_FROM_WIN32(error));
  77. }
  78. }
  79. ///////////////////////////////////////////////
  80. // Check that all the strings are properly set
  81. ///////////////////////////////////////////////
  82. if ( !m_pIASNewMdb || !m_pIASMdb || !m_pIASOldMdb )
  83. {
  84. _com_issue_error(E_OUTOFMEMORY);
  85. }
  86. }
  87. /////////////////////////////////
  88. // CIASUpgrade::GetVersionNumber
  89. /////////////////////////////////
  90. LONG CIASUpgrade::GetVersionNumber(LPCWSTR DatabaseName)
  91. {
  92. if ( !DatabaseName )
  93. {
  94. _com_issue_error(E_INVALIDARG);
  95. }
  96. /////////////////////////////////////////////////
  97. // Check %TMP% and create a directory if needed
  98. // That's to fix a bug with JET
  99. /////////////////////////////////////////////////
  100. IASCreateTmpDirectory();
  101. CComPtr<IUnknown> Session = NULL;
  102. HRESULT hr = IASOpenJetDatabase(DatabaseName, TRUE, &Session);
  103. if ( FAILED(hr) )
  104. {
  105. _com_issue_error(hr);
  106. }
  107. CComBSTR SelectVersion(L"SELECT * FROM Version");
  108. if ( !SelectVersion )
  109. {
  110. _com_issue_error(E_OUTOFMEMORY);
  111. }
  112. LONG Version = 0;
  113. hr = IASExecuteSQLFunction(Session, SelectVersion, &Version);
  114. if ( FAILED(hr) ) // no Version table for instance
  115. {
  116. // Version 0. That's not an error
  117. }
  118. Session.Release();
  119. return Version;
  120. }
  121. ///////////////////////////////////////////////////////////////
  122. // CIASUpgrade::DoWin2kUpgradeFromNetshell
  123. //
  124. // The call to the upgrade is the result of a Netshell script
  125. // ias.mdb is assumed present and good (Whistler).
  126. // iasold is assumed present and will be migrated into ias.mdb
  127. ///////////////////////////////////////////////////////////////
  128. void CIASUpgrade::DoWin2kUpgradeFromNetshell()
  129. {
  130. ///////////////////////////////////////////////////////
  131. // Now Upgrade the Win2k, Whistler 1.0 or Whistler 2.0
  132. // DB into the current Whistler 2.0 DB
  133. // The upgrade will throw if it fails
  134. ///////////////////////////////////////////////////////
  135. {
  136. CUpgradeWin2k Upgrade2k;
  137. Upgrade2k.Execute();
  138. }
  139. ////////////////////////////////////
  140. // Delete iasold.mdb no matter what
  141. // here the upgrade was successful
  142. ////////////////////////////////////
  143. DeleteFile(m_pIASOldMdb);
  144. }
  145. //////////////////////////////////////////////////
  146. // DoNT4UpgradeOrCleanInstall
  147. //
  148. // The file ias.mdb did not exist before
  149. // That's either a NT4 upgrade or a clean install
  150. // iasnew.mdb was successfuly copied into ias.mdb
  151. //////////////////////////////////////////////////
  152. void CIASUpgrade::DoNT4UpgradeOrCleanInstall()
  153. {
  154. ////////////////////////////////////
  155. // Delete iasnew.mdb no matter what
  156. ////////////////////////////////////
  157. DeleteFile(m_pIASNewMdb);
  158. //////////////////////////////////////////////////////
  159. // Call DoUpgrade: that will check if a NT4 migration
  160. // should be done or not and do it if necessary
  161. //////////////////////////////////////////////////////
  162. CDoNT4OrCleanUpgrade Upgrade;
  163. Upgrade.Execute();
  164. }
  165. /////////////////////////////////////////////////////////////////////////////
  166. // CIASUpgrade::DoWin2kUpgrade
  167. /////////////////////////////////////////////////////////////////////////////
  168. void CIASUpgrade::DoWin2kUpgrade()
  169. {
  170. LONG Result = ERROR_SUCCESS;
  171. //////////////////////////////////////////
  172. // now force copy ias.mdb into iasold.mdb
  173. //////////////////////////////////////////
  174. BOOL Succeeded = CopyFile(m_pIASMdb, m_pIASOldMdb, FALSE);
  175. if ( !Succeeded )
  176. {
  177. ////////////////////////////////////////////////
  178. // iasnew.mdb will still be copied into ias.mdb
  179. // later but not upgraded after that
  180. ////////////////////////////////////////////////
  181. Result = GetLastError();
  182. }
  183. //////////////////////////////////////
  184. // force copy iasnew.mdb into ias.mdb
  185. //////////////////////////////////////
  186. Succeeded = CopyFile(m_pIASNewMdb, m_pIASMdb, FALSE);
  187. if ( !Succeeded )
  188. {
  189. /////////////////////////////
  190. // do not upgrade after that
  191. /////////////////////////////
  192. Result = GetLastError();
  193. }
  194. ////////////////////////////////////////////////////
  195. // Delete iasnew.mdb no matter what: if the upgrade
  196. // throws an exception then iasnew.mdb will not be
  197. // left on the drive
  198. ////////////////////////////////////////////////////
  199. DeleteFile(m_pIASNewMdb);
  200. /////////////////////////////////////////////
  201. // Now Upgrade the Win2k or Whistler 1.0 DB
  202. // into the Whistler DB if the previous copy
  203. // operations were successful
  204. /////////////////////////////////////////////
  205. if ( Result == ERROR_SUCCESS )
  206. {
  207. ///////////////////////////////////
  208. // will throw if the upgrade fails
  209. ///////////////////////////////////
  210. CUpgradeWin2k Upgrade2k;
  211. Upgrade2k.Execute();
  212. }
  213. else
  214. {
  215. _com_issue_error(HRESULT_FROM_WIN32(Result));
  216. }
  217. ////////////////////////////////////
  218. // Delete iasold.mdb no matter what
  219. // here the upgrade was successful
  220. ////////////////////////////////////
  221. DeleteFile(m_pIASOldMdb);
  222. }
  223. ////////////////////////////////////////
  224. // CIASUpgrade::DoWhistlerUpgrade
  225. //
  226. // nothing to do: already a Whistler DB
  227. ////////////////////////////////////////
  228. void CIASUpgrade::DoWhistlerUpgrade()
  229. {
  230. ////////////////////////////////////
  231. // Delete iasnew.mdb no matter what
  232. ////////////////////////////////////
  233. DeleteFile(m_pIASNewMdb);
  234. }
  235. /////////////////////////////////////////////////////////////////////////////
  236. // CIASUpgrade::IASUpgrade
  237. /////////////////////////////////////////////////////////////////////////////
  238. HRESULT CIASUpgrade::IASUpgrade(BOOL FromNetshell)
  239. {
  240. HRESULT hr = S_OK;
  241. ////////////////////////////
  242. // Now get the upgrade type
  243. ////////////////////////////
  244. do
  245. {
  246. if ( FromNetshell )
  247. {
  248. UpgradeType = Win2kUpgradeFromNetshell;
  249. break;
  250. }
  251. ///////////////////////////////////////
  252. // try to copy iasnew.mdb into ias.mdb
  253. // fails if the file is already there
  254. ///////////////////////////////////////
  255. BOOL IsNT4OrCleanInstall = CopyFile(m_pIASNewMdb, m_pIASMdb, TRUE);
  256. if ( IsNT4OrCleanInstall )
  257. {
  258. // select NT4 or Clean install
  259. UpgradeType = NT4UpgradeOrCleanInstall;
  260. break;
  261. }
  262. else // Win2k or Whistler upgrade
  263. {
  264. ///////////////////////////////////////////
  265. // cannot copy: the file is already there.
  266. // Check the version number (of ias.mdb)
  267. ///////////////////////////////////////////
  268. LONG CurrentVersion = GetVersionNumber(m_pIASMdb);
  269. const LONG IAS_5_1_VERSION = 3;
  270. if ( CurrentVersion < IAS_5_1_VERSION )
  271. {
  272. UpgradeType = Win2kUpgrade;
  273. break;
  274. }
  275. else
  276. {
  277. UpgradeType = WhistlerUpgrade;
  278. break;
  279. }
  280. }
  281. }
  282. while (FALSE);
  283. try
  284. {
  285. switch ( UpgradeType )
  286. {
  287. case Win2kUpgradeFromNetshell:
  288. {
  289. DoWin2kUpgradeFromNetshell();
  290. break;
  291. }
  292. case NT4UpgradeOrCleanInstall:
  293. {
  294. DoNT4UpgradeOrCleanInstall();
  295. break;
  296. }
  297. case Win2kUpgrade:
  298. {
  299. DoWin2kUpgrade();
  300. break;
  301. }
  302. case WhistlerUpgrade:
  303. {
  304. DoWhistlerUpgrade();
  305. break;
  306. }
  307. default:
  308. {
  309. _com_issue_error(E_FAIL);
  310. }
  311. }
  312. }
  313. catch(const _com_error& e)
  314. {
  315. hr = e.Error();
  316. }
  317. catch(...)
  318. {
  319. hr = HRESULT_FROM_WIN32(GetLastError());
  320. }
  321. if ( FromNetshell )
  322. {
  323. /////////////////////////////////////
  324. // Return the error code to netshell
  325. /////////////////////////////////////
  326. return hr;
  327. }
  328. else
  329. {
  330. ///////////////////////////////////////
  331. // Result ignored: no errors returned.
  332. ///////////////////////////////////////
  333. return S_OK;
  334. }
  335. }