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.

781 lines
31 KiB

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. //
  4. // Constants
  5. //
  6. #define CP_USASCII 1252
  7. #define END_OF_CODEPAGES -1
  8. // vendor info struct used in QueryVersion
  9. typedef struct {
  10. CHAR CompanyName[256];
  11. CHAR SupportNumber[256];
  12. CHAR SupportUrl[256];
  13. CHAR InstructionsToUser[1024];
  14. } VENDORINFO, *PVENDORINFO;
  15. VENDORINFO g_VendorInfo;
  16. //
  17. // Code page array
  18. //
  19. INT g_CodePageArray[] = {CP_USASCII,END_OF_CODEPAGES};
  20. //
  21. // Multi-sz (i.e., double-nul terminated) list of files to find
  22. //
  23. CHAR g_ExeNamesBuf[] = "MetaData.bin\0";
  24. CHAR g_MyProductId[100];
  25. //#define UNATTEND_TXT_PWS_SECTION "PWS_W9x_Migrate_To_NT"
  26. //#define UNATTEND_TXT_PWS_KEY1 "MigrateFile"
  27. #define UNATTEND_TXT_PWS_SECTION "InternetServer"
  28. #define UNATTEND_TXT_PWS_KEY1 "Win95MigrateDll"
  29. #define PRODUCTID_IFRESOURCEFAILS "Microsoft Personal Web Server"
  30. #define LOGFILENAME_IFRESOURCEFAILS "iis_w95.log"
  31. CHAR g_MyDataFileName[] = "iis_w95.dat\0";
  32. CHAR g_MyLogFileName[_MAX_FNAME];
  33. CHAR g_PWS10_Migration_Section_Name_AddReg[] = "PWS10_MIGRATE_TO_NT5_REG\0";
  34. CHAR g_PWS40_Migration_Section_Name_AddReg[] = "PWS40_MIGRATE_TO_NT5_REG\0";
  35. char g_Migration_Section_Name_AddReg[50];
  36. CHAR g_PWS10_Migration_Section_Name_CopyFiles[] = "PWS10_MIGRATE_TO_NT5_COPYFILES\0";
  37. CHAR g_PWS40_Migration_Section_Name_CopyFiles[] = "PWS40_MIGRATE_TO_NT5_COPYFILES\0";
  38. char g_Migration_Section_Name_CopyFiles[50];
  39. CHAR g_WorkingDirectory[_MAX_PATH];
  40. CHAR g_SourceDirectories[_MAX_PATH];
  41. CHAR g_FullFileNamePathToSettingsFile[_MAX_PATH];
  42. int g_iPWS40OrBetterInstalled = FALSE;
  43. int g_iPWS10Installed = FALSE;
  44. int g_iVermeerPWS10Installed = FALSE;
  45. HANDLE g_MyModuleHandle = NULL;
  46. MyLogFile g_MyLogFile;
  47. int TurnOnPrivateLogFile(void)
  48. {
  49. DWORD rc, err, size, type;
  50. HKEY hkey;
  51. err = RegOpenKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft"), &hkey);
  52. if (err != ERROR_SUCCESS) {return 0;}
  53. size = sizeof(DWORD);
  54. err = RegQueryValueEx(hkey,_T("SetupDebugLog"),0,&type,(LPBYTE)&rc,&size);
  55. if (err != ERROR_SUCCESS || type != REG_DWORD) {rc = 0;}
  56. RegCloseKey(hkey);
  57. //return 1;
  58. return (int) rc;
  59. }
  60. void My_MigInf_AddMessage(char *szProductId, char *szLoadedString)
  61. {
  62. iisDebugOut(_T("MigInf_AddMessage:%s,%s"), g_MyProductId,szLoadedString);
  63. // 1. get the path to our pws migrate.inf
  64. // 2. stick this information in this section.
  65. // [Incompatible Messages]
  66. // Microsoft Personal Web Server = "szLoadedString"
  67. char szMyWorkingDirInfFile[_MAX_PATH];
  68. strcpy(szMyWorkingDirInfFile, g_WorkingDirectory);
  69. AddPath(szMyWorkingDirInfFile, "Migrate.inf");
  70. // the nt supplied api
  71. // this will write out the stuff below.
  72. // [Incompatible Messages]
  73. // Microsoft Personal Web Server = "szLoadedString"
  74. MigInf_AddMessage(g_MyProductId, szLoadedString);
  75. // Set the other required section.
  76. // This has to be written, otherwise the user will never get the message.
  77. // we have to set something, so let's just set the below, that way we know that this will showup.
  78. // HKLM\Software\Microsoft=Registry
  79. //
  80. // [Microsoft Personal Web Server]
  81. // something=File
  82. // something=Directory
  83. // something=Registry
  84. //
  85. if (FALSE == WritePrivateProfileString(szProductId, "\"HKLM\\Software\\Microsoft\"", "Registry", szMyWorkingDirInfFile))
  86. {iisDebugOut(_T("MigInf_AddMessage:WritePrivateProfileString(2) FAILED"));}
  87. return;
  88. }
  89. //
  90. // Standard Win32 DLL Entry point
  91. //
  92. BOOL WINAPI DllMain(IN HANDLE DllHandle,IN DWORD Reason,IN LPVOID Reserved)
  93. {
  94. BOOL bReturn;
  95. bReturn = TRUE;
  96. switch(Reason)
  97. {
  98. case DLL_PROCESS_ATTACH:
  99. g_MyModuleHandle = DllHandle;
  100. //
  101. // We don't need DLL_THREAD_ATTACH or DLL_THREAD_DETACH messages
  102. //
  103. DisableThreadLibraryCalls ((HINSTANCE) DllHandle);
  104. // open Our log file.
  105. if (TurnOnPrivateLogFile() != 0)
  106. {
  107. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_MIGRATION_LOG_FILENAME, g_MyLogFileName, sizeof(g_MyLogFileName))) {strcpy(g_MyLogFileName, LOGFILENAME_IFRESOURCEFAILS);}
  108. strcpy(g_MyLogFile.m_szLogPreLineInfo, "DllMain, DLL_PROCESS_ATTACH:");
  109. g_MyLogFile.LogFileCreate(g_MyLogFileName);
  110. }
  111. // SetupAPI error log levels
  112. // -------------------------
  113. // LogSevInformation,
  114. // LogSevWarning,
  115. // LogSevError,
  116. // LogSevFatalError, (Reserved for use by windows nt setup)
  117. // LogSevMaximum
  118. // Open Setupapi log; FALSE means do not delete existing log
  119. SetupOpenLog(FALSE);
  120. LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId));
  121. iisDebugOut(_T("ProductID=%s"), g_MyProductId);
  122. // if we can't initialize the migration writeback routines
  123. // then hey we can't do anything
  124. if (!MigInf_Initialize())
  125. {
  126. SetupLogError_Wrap(LogSevError, "MigInf_Initialize() FAILED.");
  127. return FALSE;
  128. }
  129. // Fall through to process first thread
  130. case DLL_THREAD_ATTACH:
  131. bReturn = TRUE;
  132. break;
  133. case DLL_PROCESS_DETACH:
  134. strcpy(g_MyLogFile.m_szLogPreLineInfo, "DllMain, DLL_PROCESS_DETACH:");
  135. // clean up migration inf stuff
  136. MigInf_CleanUp();
  137. // Close our log file
  138. g_MyLogFile.LogFileClose();
  139. // Close setupapi log file
  140. SetupCloseLog();
  141. break;
  142. case DLL_THREAD_DETACH:
  143. break;
  144. }
  145. return(bReturn);
  146. }
  147. //-----------------------------------------------------------------------
  148. // Required entry point that is called by setup
  149. // Return Values:
  150. // ERROR_SUCCESS: if your migration DLL found one or more installed components for its target application. This guarantees that Setup will call your migration DLL for later processing.
  151. // ERROR_NOT_INSTALLED: if your migration DLL initializes properly but did not find any of its components installed on the active Windows 9x installation. Note that Setup will not call your DLL again if it returns ERROR_NOT_INSTALLED.
  152. //
  153. // Your migration DLL must also return ERROR_SUCCESS if it does not attempt to detect installed components in QueryVersion.
  154. //
  155. // All other return values (Win32 error values) are considered initialization errors. Setup will report the error to the user, clean up your migration DLL's files, and ask the user to continue or cancel the Windows NT installation process.
  156. //-----------------------------------------------------------------------
  157. LONG
  158. CALLBACK
  159. QueryVersion (
  160. OUT LPCSTR *ProductID,
  161. OUT LPUINT DllVersion,
  162. OUT LPINT *CodePageArray, OPTIONAL
  163. OUT LPCSTR *ExeNamesBuf, OPTIONAL
  164. OUT PVENDORINFO *MyVendorInfo
  165. )
  166. {
  167. long lReturn = ERROR_NOT_INSTALLED;
  168. strcpy(g_MyLogFile.m_szLogPreLineInfo, "QueryVersion:");
  169. iisDebugOut(_T("Start. DllVersion=%d."), DllVersion);
  170. //
  171. // First, we do some preliminary investigation to see if
  172. // our components are installed.
  173. //
  174. if (TRUE != CheckIfPWS95Exists())
  175. {
  176. //
  177. // We didn't detect any components, so we return
  178. // ERROR_NOT_INSTALLED and the DLL will stop being called.
  179. // Use this method as much as possible, because user enumeration
  180. // for MigrateUser9x is relatively slow. However, don't spend too
  181. // much time here because QueryVersion is expected to run quickly.
  182. //
  183. // Check if frontpage.ini is there!
  184. if (TRUE != CheckFrontPageINI())
  185. {
  186. goto QueryVersion_Exit;
  187. }
  188. }
  189. //
  190. // Screen saver is enabled, so tell Setup who we are. ProductID is used
  191. // for display, so it must be localized. The ProductID string is
  192. // converted to UNICODE for use on Windows NT via the MultiByteToWideChar
  193. // Win32 API. The first element of CodePageArray is used to specify
  194. // the code page of ProductID, and if no elements are returned in
  195. // CodePageArray, Setup assumes CP_ACP.
  196. //
  197. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId)))
  198. {strcpy(g_MyProductId, PRODUCTID_IFRESOURCEFAILS);}
  199. // return back this product id
  200. // warning: somehow they set this back to null or something, so
  201. // make sure to load g_MyProductId from the resource again.
  202. *ProductID = g_MyProductId;
  203. //
  204. // Report our version. Zero is reserved for use by DLLs that
  205. // ship with Windows NT.
  206. //
  207. *DllVersion = 1;
  208. //
  209. // Because we have English messages, we return an array that has
  210. // the English language ID. The sublanguage is neutral because
  211. // we do not have currency, time, or other geographic-specific
  212. // information in our messages.
  213. //
  214. // Tip: If it makes more sense for your DLL to use locales,
  215. // return ERROR_NOT_INSTALLED if the DLL detects that an appropriate
  216. // locale is not installed on the machine.
  217. //
  218. // comment this line out so that it works on all languages...
  219. //*CodePageArray = g_CodePageArray;
  220. *CodePageArray = NULL;
  221. //
  222. // ExeNamesBuf - we pass a list of file names (the long versions)
  223. // and let Setup find them for us. Keep this list short because
  224. // every instance of the file on every hard drive will be reported
  225. // in migrate.inf.
  226. //
  227. // Most applications don't need this behavior, because the registry
  228. // usually contains full paths to installed components. We need it,
  229. // though, because there are no registry settings that give us the
  230. // paths of the screen saver DLLs.
  231. //
  232. // Check which directories we need to make sure are copied over.
  233. // for pws 1.0
  234. // 1. msftpsvc values for "Virtual Roots"
  235. // 2. w3svc values for "Script Map"
  236. // 3. w3svc values for "Virtual Roots"
  237. // for pws 4.0
  238. // everything is in the metabase
  239. // do a function here which makes sure that our stuff in these above
  240. // directories gets copied over or that a warning gets put out to the
  241. // user that these directories will not be copied...etc,
  242. ReturnImportantDirs();
  243. *ExeNamesBuf = g_ExeNamesBuf;
  244. ZeroMemory(&g_VendorInfo, sizeof(g_VendorInfo));
  245. if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  246. g_MyModuleHandle,
  247. MSG_VI_COMPANY_NAME,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
  248. (LPTSTR) g_VendorInfo.CompanyName,
  249. sizeof(g_VendorInfo.CompanyName),
  250. NULL) <= 0)
  251. {
  252. strcpy(g_VendorInfo.CompanyName, "Microsoft Corporation.");
  253. }
  254. if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  255. g_MyModuleHandle,
  256. MSG_VI_SUPPORT_NUMBER,
  257. MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
  258. (LPTSTR) g_VendorInfo.SupportNumber,
  259. sizeof(g_VendorInfo.SupportNumber),
  260. NULL) <= 0)
  261. {
  262. strcpy(g_VendorInfo.SupportNumber, "1-800-555-1212 (USA Only).");
  263. }
  264. if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  265. g_MyModuleHandle,
  266. MSG_VI_SUPPORT_URL,
  267. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  268. (LPTSTR) g_VendorInfo.SupportUrl,
  269. sizeof(g_VendorInfo.SupportUrl),
  270. NULL) <= 0)
  271. {
  272. strcpy(g_VendorInfo.SupportUrl, "http://www.microsoft.com/support.");
  273. }
  274. if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  275. g_MyModuleHandle,
  276. MSG_VI_INSTRUCTIONS,
  277. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  278. (LPTSTR) g_VendorInfo.InstructionsToUser,
  279. sizeof(g_VendorInfo.InstructionsToUser),
  280. NULL) <= 0)
  281. {
  282. strcpy(g_VendorInfo.InstructionsToUser, "Please contact Microsoft Technical Support for assistance with this problem..");
  283. }
  284. *MyVendorInfo = &g_VendorInfo;
  285. iisDebugOut(_T("CompanyName=%s"), g_VendorInfo.CompanyName);
  286. iisDebugOut(_T("SupportNumber=%s"), g_VendorInfo.SupportNumber);
  287. iisDebugOut(_T("SupportUrl=%s"), g_VendorInfo.SupportUrl);
  288. iisDebugOut(_T("InstructionsToUser=%s"), g_VendorInfo.InstructionsToUser);
  289. // We've gotten this far that means things are okay.
  290. lReturn = ERROR_SUCCESS;
  291. QueryVersion_Exit:
  292. iisDebugOut(_T(" End. Return=%d"), lReturn);
  293. return lReturn;
  294. }
  295. //-----------------------------------------------------------------------
  296. // Required entry point that is called by setup
  297. // Return Values:
  298. // ERROR_SUCCESS: if your migration DLL found one or more installed components for the target application. If your DLL does not attempt to detect installed components in Initialize9x, it must also return ERROR_SUCCESS
  299. // ERROR_NOT_INSTALLED: if the migration DLL initializes properly but does not find any of its components installed on the active Windows 9x installation. Note that Setup will not call your DLL again if it returns ERROR_NOT_INSTALLED.
  300. //-----------------------------------------------------------------------
  301. LONG CALLBACK Initialize9x ( IN LPCSTR WorkingDirectory, IN LPCSTR SourceDirectories, LPVOID Reserved )
  302. {
  303. strcpy(g_MyLogFile.m_szLogPreLineInfo, "Initialize9x:");
  304. long lReturn = ERROR_NOT_INSTALLED;
  305. iisDebugOut(_T("Start. WorkingDir=%s, SourceDir=%s."), WorkingDirectory, SourceDirectories);
  306. // Load the productId into the global variable just incase
  307. LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId));
  308. //
  309. // Because we returned ERROR_SUCCESS in QueryVersion, we are being
  310. // called for initialization. Therefore, we know we are
  311. // enabled on the machine at this point.
  312. //
  313. //
  314. // Make global copies of WorkingDirectory and SourceDirectories --
  315. // we will not get this information again, and we shouldn't
  316. // count on Setup keeping the pointer valid for the life of our
  317. // DLL.
  318. //
  319. // Save the working directories
  320. strcpy(g_WorkingDirectory, WorkingDirectory);
  321. strcpy(g_SourceDirectories, SourceDirectories);
  322. // name the settings file
  323. strcpy(g_FullFileNamePathToSettingsFile, g_WorkingDirectory);
  324. AddPath(g_FullFileNamePathToSettingsFile, g_MyDataFileName);
  325. //
  326. // First, we do some preliminary investigation to see if
  327. // our components are installed.
  328. //
  329. if (TRUE != CheckIfPWS95Exists())
  330. {
  331. // Check if frontpage.ini is there!
  332. if (TRUE != CheckFrontPageINI())
  333. {
  334. goto Initialize9x_Exit;
  335. }
  336. }
  337. // We've gotten this far that means things are okay.
  338. lReturn = ERROR_SUCCESS;
  339. Initialize9x_Exit:
  340. iisDebugOut(_T(" End. Return=%d. g_WorkingDir=%s, g_SourceDir=%s, g_SettingsFile=%s."), lReturn, g_WorkingDirectory, g_SourceDirectories, g_FullFileNamePathToSettingsFile);
  341. return lReturn;
  342. }
  343. //-----------------------------------------------------------------------
  344. // Required entry point that is called by setup
  345. // we totally don't care about this part
  346. // Return Values:
  347. // ERROR_SUCCESS if the target application is installed for the specified user. Also return ERROR_SUCCESS if your migration DLL needs further processing during the Windows NT phase.
  348. // ERROR_NOT_INSTALLED if your target application is not installed for the specified user account and that user's registry does not require any processing. However, Setup will continue to call MigrateUser9x for the rest of the users, and MigrateSystem9x if this function returns ERROR_NOT_INSTALLED.
  349. // ERROR_CANCELLED if the user wants to exit Setup. You should specify this return value only if ParentWnd is not set to NULL.
  350. //-----------------------------------------------------------------------
  351. LONG
  352. CALLBACK
  353. MigrateUser9x (
  354. IN HWND ParentWnd,
  355. IN LPCSTR AnswerFile,
  356. IN HKEY UserRegKey,
  357. IN LPCSTR UserName,
  358. LPVOID Reserved
  359. )
  360. {
  361. strcpy(g_MyLogFile.m_szLogPreLineInfo, "MigrateUser9x:");
  362. long lReturn = ERROR_NOT_INSTALLED;
  363. // Return not installed since we don't do any user specific stuff.
  364. lReturn = ERROR_NOT_INSTALLED;
  365. return ERROR_NOT_INSTALLED;
  366. }
  367. void HandleFrontPageUpgrade(LPCSTR AnswerFile)
  368. {
  369. //[HKEY_LOCAL_MACHINE\Software\Microsoft\FrontPage\3.0]
  370. //"PWSInstalled"="1"
  371. iisDebugOut(_T("HandleFrontPageUpgrade. Start."));
  372. // Check if pws 4.0 or better is installed.
  373. DWORD rc = 0;
  374. HKEY hKey = NULL;
  375. DWORD dwType, cbData;
  376. BYTE bData[1000];
  377. cbData = 1000;
  378. int iTempFlag = FALSE;
  379. rc = RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\FrontPage", &hKey);
  380. if (rc != ERROR_SUCCESS) {goto HandleFrontPageUpgrade_Exit;}
  381. // Check if we can read a Value.
  382. //rc = RegQueryValueEx(hKey,REG_INETSTP_MAJORVERSION_STRINGVALUE,NULL,&dwType,bData,&cbData);
  383. //if (ERROR_SUCCESS != rc) {goto HandleFrontPageUpgrade_Exit;}
  384. // kool the key exists
  385. // let's tell Win2000 setup to make sure to upgrade the FrontPageServer Extensions
  386. if (0 == WritePrivateProfileString("Components", "fp_extensions", "ON", AnswerFile))
  387. {
  388. SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", "fp_extensions", AnswerFile, GetLastError());
  389. }
  390. else
  391. {
  392. iisDebugOut(_T("HandleFrontPageUpgrade. Set 'fp_extensions=ON'"));
  393. }
  394. HandleFrontPageUpgrade_Exit:
  395. if (hKey){RegCloseKey(hKey);}
  396. iisDebugOut(_T("HandleFrontPageUpgrade. End."));
  397. return;
  398. }
  399. // function: HandleInetsrvDir
  400. //
  401. // This function marks all of the inetsrv files as handled. This causes
  402. // NT to correctly back them up, and reinstall if we remove Whistler, and
  403. // go back to Win9x.
  404. //
  405. // Return Values
  406. // FALSE - It failed
  407. // TRUE - It succeeded
  408. DWORD
  409. HandleInetsrvDir()
  410. {
  411. TCHAR szSystemDir[_MAX_PATH];
  412. TCHAR szWindowsSearch[_MAX_PATH];
  413. TCHAR szFilePath[_MAX_PATH];
  414. WIN32_FIND_DATA fd;
  415. HANDLE hFile;
  416. // Create Path
  417. if ( GetWindowsDirectory(szSystemDir, sizeof(szSystemDir) / sizeof(TCHAR) ) == 0)
  418. {
  419. return FALSE;
  420. }
  421. AddPath(szSystemDir,_T("system\\inetsrv\\"));
  422. strcpy(szWindowsSearch,szSystemDir);
  423. AddPath(szWindowsSearch,_T("*.*"));
  424. iisDebugOut(_T("HandleInetsrvDir:Path=%s\r\n"),szWindowsSearch);
  425. // Find First File
  426. hFile = FindFirstFile(szWindowsSearch, &fd);
  427. if ( hFile == INVALID_HANDLE_VALUE )
  428. {
  429. // Could not find file
  430. return FALSE;
  431. }
  432. do {
  433. if ( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  434. {
  435. // It is not a directory, so lets add it
  436. strcpy(szFilePath,szSystemDir);
  437. AddPath(szFilePath,fd.cFileName);
  438. iisDebugOut(_T("HandleInetsrvDir:delete=%s\r\n"),szFilePath);
  439. MigInf_AddHandledFile( szFilePath );
  440. }
  441. else
  442. {
  443. strcpy(szFilePath,fd.cFileName);
  444. iisDebugOut(_T("HandleInetsrvDir:skip del=%s\r\n"),szFilePath);
  445. }
  446. } while ( FindNextFile(hFile, &fd) );
  447. FindClose(hFile);
  448. return TRUE;
  449. }
  450. //-----------------------------------------------------------------------
  451. // Required entry point that is called by setup
  452. // Return Values:
  453. // ERROR_SUCCESS if your target application is installed on the system. Also returns ERROR_SUCCESS if system-wide changes need to be made for the target application during the Windows NT phase of the upgrade.
  454. // ERROR_NOT_INSTALLED if your migration DLL detects no application components common to the entire system or if your DLL requires no further processing. Note that Setup will continue to call MigrateUser9x for the rest of the users, and MigrateSystem9x if this function returns ERROR_NOT_INSTALLED.
  455. // ERROR_CANCELLED if the user elects to exit the Setup program. Use this return value only if ParentWnd is not NULL.
  456. //-----------------------------------------------------------------------
  457. LONG
  458. CALLBACK
  459. MigrateSystem9x (
  460. IN HWND ParentWnd,
  461. IN LPCSTR AnswerFile,
  462. LPVOID Reserved
  463. )
  464. {
  465. strcpy(g_MyLogFile.m_szLogPreLineInfo, "MigrateSystem9x:");
  466. long lReturn = ERROR_NOT_INSTALLED;
  467. iisDebugOut(_T("Start. AnswerFile=%s."), AnswerFile);
  468. char szMyWorkingDirInfFile[_MAX_PATH];
  469. strcpy(szMyWorkingDirInfFile, g_WorkingDirectory);
  470. AddPath(szMyWorkingDirInfFile, "Migrate.inf");
  471. // Load the productId into the global variable just incase
  472. LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId));
  473. // do some special stuff for frontpage's .ini file
  474. MoveFrontPageINI();
  475. //
  476. // First, maybe iis isn't even installed, check first.
  477. // but do this after doing the frontpage stuff
  478. //
  479. if (TRUE != CheckIfPWS95Exists())
  480. {
  481. lReturn = ERROR_SUCCESS;
  482. goto MigrateSystem9x_Exit;
  483. }
  484. // If the user has Vermeer pws 1.0 installed then we have to put up a
  485. // Message saying "sorry we can't upgrade this."
  486. if (g_iVermeerPWS10Installed == TRUE)
  487. {
  488. // get from resource
  489. char szLoadedString[512];
  490. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_VERMEER_PWS_1_NOT_SUPPORTED, szLoadedString, sizeof(szLoadedString)))
  491. {strcpy(szLoadedString, "Warning: Vermeer Frontpage Personal Web Server 1.0 detected and will not be upgraded to IIS 5.0.");}
  492. // Write the string out to our answer file so that nt5 setup will show it to the user
  493. My_MigInf_AddMessage(g_MyProductId, szLoadedString);
  494. // Important: Write memory version of migrate.inf to disk
  495. if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");lReturn = GetLastError();}
  496. goto MigrateSystem9x_Exit;
  497. }
  498. //
  499. // Upgrade from win95 to NT5/iis5 is not supported.
  500. // IDS_NT5_BETA2_NOT_SUPPORTED
  501. //
  502. /*
  503. 8/19/98 commented this stuff for RTM
  504. if (TRUE == CheckIfPWS95Exists())
  505. {
  506. // get from resource
  507. char szLoadedString[512];
  508. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_NT5_BETA2_NOT_SUPPORTED, szLoadedString, sizeof(szLoadedString)))
  509. {strcpy(szLoadedString, "Win2000 Beta will not support upgrades of Personal Web Server from Windows 95, or Windows 98. Please remove Personal Web Server from your Windows machine, and then add IIS after Win2000 setup has completed. Setup will continue without installing IIS 5.0.");}
  510. // Write the string out to our answer file so that nt5 setup will show it to the user
  511. My_MigInf_AddMessage(g_MyProductId, szLoadedString);
  512. // Important: Write memory version of migrate.inf to disk
  513. if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");lReturn = GetLastError();}
  514. goto MigrateSystem9x_Exit;
  515. }
  516. */
  517. // remove all old stuff from the win95 pws10/40 installation.
  518. // this has to be done regardless if the target os support iis...
  519. // We need to tell migration setup that we are going to handle certain files...
  520. // particularly the c:\windows\SendTo\Personal Web Server.lnk file
  521. // since it doesn't seem to be accessible during win2000/20001 guimode setup
  522. iisDebugOut(_T("Start. Calling HandleSendToItems."));
  523. HandleSendToItems(AnswerFile);
  524. iisDebugOut(_T("Start. Calling HandleDesktopItems."));
  525. HandleDesktopItems(AnswerFile);
  526. iisDebugOut(_T("Start. Calling HandleStartMenuItems."));
  527. HandleStartMenuItems(AnswerFile);
  528. iisDebugOut(_T("Start. Calling HandleSpecialRegKey."));
  529. HandleSpecialRegKey();
  530. // Handle the inetsrv dir
  531. iisDebugOut(_T("Start. Calling HandleInetsrvDir."));
  532. HandleInetsrvDir();
  533. if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");lReturn = GetLastError();}
  534. //MessageBox(NULL, "check out the file now", AnswerFile, MB_OK);
  535. // check if the target OS (that we want to upgrade to) supports iis on it
  536. if (FALSE == IsUpgradeTargetSupportIIS(szMyWorkingDirInfFile))
  537. {
  538. iisDebugOut(_T("Target OS does not support IIS. put up msg."));
  539. // get from resource
  540. char szLoadedString[512];
  541. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_TARGET_OS_DOES_NOT_SUPPORT_UPGRADE, szLoadedString, sizeof(szLoadedString)))
  542. {strcpy(szLoadedString, "Warning, the target OS does not support IIS. IIS will be removed upon upgrade.");}
  543. // Write the string out to our answer file so that nt setup will show it to the user
  544. My_MigInf_AddMessage(g_MyProductId, szLoadedString);
  545. // Important: Write memory version of migrate.inf to disk
  546. if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");lReturn = GetLastError();}
  547. lReturn = ERROR_SUCCESS;
  548. goto MigrateSystem9x_Exit;
  549. }
  550. // 1. do any setup upgrade type of work to ensure
  551. // that we get all the settings stuff over to NT5 land.
  552. // -------------------------------
  553. iisDebugOut(_T("Start. Calling MyUpgradeTasks."));
  554. MyUpgradeTasks(AnswerFile);
  555. // If FrontPage is installed, then do some funky hack since
  556. // the frontpage guys can't fix they upgrade setup bug.
  557. // HandleFrontPageUpgrade(AnswerFile);
  558. // 2. move over the registry stuff
  559. // -------------------------------
  560. // Lookup the registry settings and save into our "settings" file.
  561. iisDebugOut(_T("Start. Calling MySettingsFile_Write."));
  562. MySettingsFile_Write();
  563. // We need to tell NT5 gui mode setup (where iis/pws will actually get upgraded).
  564. // Where to find the upgrade file.
  565. // during upgrade it should just install the DefaultInstall section of the pwsmigt.dat file
  566. // We will tell iis/pws nt5 setup where the pwsmigt.dat in the answer file.
  567. // Answer file should be located in the c:\windows\setup\unattend.tmp file on the win95 side.
  568. // On the WinNT5 side, it should be at...
  569. assert(AnswerFile);
  570. iisDebugOut(_T("Start. Calling WritePrivateProfileString.%s."), AnswerFile);
  571. if (0 == WritePrivateProfileString(UNATTEND_TXT_PWS_SECTION, UNATTEND_TXT_PWS_KEY1, g_FullFileNamePathToSettingsFile, AnswerFile))
  572. {
  573. SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_PWS_SECTION, AnswerFile, GetLastError());
  574. goto MigrateSystem9x_Exit;
  575. }
  576. /*
  577. Example: For Generating messages to the user during Win95 time
  578. MigInf_AddMessage(g_MyProductId, "We were unable to upgrade the pws 1.0 installation because of failure.");
  579. // Important: Write memory version of migrate.inf to disk
  580. if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");lReturn = GetLastError();}
  581. */
  582. // We've gotten this far that means things are okay.
  583. lReturn = ERROR_SUCCESS;
  584. MigrateSystem9x_Exit:
  585. W95ShutdownW3SVC();
  586. iisDebugOut(_T(" End. Return=%d."), lReturn);
  587. return lReturn;
  588. }
  589. //-----------------------------------------------------------------------
  590. // Required entry point that is called by setup
  591. // Return Values:
  592. // ERROR_SUCCESS if your migration DLL initializes properly within the Windows NT environment.
  593. // All other return values (Win32 error values) are considered critical errors. Setup reports the error to the user and then cancels processing your migration DLL. However, Setup will not continue the upgrade. Any errors or logs generated will include the ProductID string specified in QueryVersion to identify your DLL.
  594. //-----------------------------------------------------------------------
  595. LONG CALLBACK InitializeNT ( IN LPCWSTR WorkingDirectory, IN LPCWSTR SourceDirectories, LPVOID Reserved )
  596. {
  597. strcpy(g_MyLogFile.m_szLogPreLineInfo, "InitializeNT:");
  598. iisDebugOut(_T("Start."));
  599. long lReturn = ERROR_NOT_INSTALLED;
  600. // Load the productId into the global variable just incase
  601. LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId));
  602. // change the Wide characters to ansi
  603. WideCharToMultiByte (CP_ACP, 0, WorkingDirectory, -1,g_WorkingDirectory,_MAX_PATH,NULL,NULL);
  604. WideCharToMultiByte (CP_ACP, 0, SourceDirectories, -1,g_SourceDirectories,_MAX_PATH,NULL,NULL);
  605. // name the settings file
  606. strcpy(g_FullFileNamePathToSettingsFile, g_WorkingDirectory);
  607. AddPath(g_FullFileNamePathToSettingsFile, g_MyDataFileName);
  608. // We've gotten this far that means things are okay.
  609. lReturn = ERROR_SUCCESS;
  610. iisDebugOut(_T(" End. Return=%d, g_WorkingDir=%s, g_SourceDir=%s, g_SettingsFile=%s."), lReturn, g_WorkingDirectory, g_SourceDirectories, g_FullFileNamePathToSettingsFile);
  611. return lReturn;
  612. }
  613. //-----------------------------------------------------------------------
  614. // Required entry point that is called by setup
  615. // Return Values:
  616. // ERROR_SUCCESS if the migration of user-specific settings is successful.
  617. // Other error codes will terminate the processing of your migration DLL. However, Windows NT Setup will proceed. Ideally, only critical problems (such as a hardware failure) should generate terminating error codes.
  618. //-----------------------------------------------------------------------
  619. LONG CALLBACK MigrateUserNT ( IN HINF AnswerFileHandle, IN HKEY UserRegKey, IN LPCWSTR UserName, LPVOID Reserved )
  620. {
  621. strcpy(g_MyLogFile.m_szLogPreLineInfo, "MigrateUserNT:");
  622. iisDebugOut(_T("Start."));
  623. long lReturn = ERROR_NOT_INSTALLED;
  624. // Load the productId into the global variable just incase
  625. LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId));
  626. // We've gotten this far that means things are okay.
  627. lReturn = ERROR_SUCCESS;
  628. iisDebugOut(_T(" End. Return=%d."), lReturn);
  629. return lReturn;
  630. }
  631. //-----------------------------------------------------------------------
  632. // Required entry point that is called by setup
  633. // Return Values:
  634. // ERROR_SUCCESS if the migration of system-wide settings is successful.
  635. // Other error codes will terminate the processing of your migration DLL. However, Windows NT Setup will proceed. Ideally, only critical problems (such as a hardware failure) should generate terminating error codes
  636. //-----------------------------------------------------------------------
  637. LONG CALLBACK MigrateSystemNT ( IN HINF AnswerFileHandle, LPVOID Reserved )
  638. {
  639. strcpy(g_MyLogFile.m_szLogPreLineInfo, "MigrateSystemNT:");
  640. long lReturn = ERROR_NOT_INSTALLED;
  641. iisDebugOut(_T("Start."));
  642. // Load the productId into the global variable just incase
  643. LoadString((HINSTANCE) g_MyModuleHandle, IDS_PRODUCT_ID, g_MyProductId, sizeof(g_MyProductId));
  644. // Delete the Win95 migrated StartMenu/Desktop Items!
  645. iisDebugOut(_T("Calling iis.dll section: %s. Start."),_T("OC_CLEANUP_WIN95_MIGRATE"));
  646. Call_IIS_DLL_INF_Section("OC_CLEANUP_WIN95_MIGRATE");
  647. iisDebugOut(_T("Calling iis.dll section: %s. End."), _T("OC_CLEANUP_WIN95_MIGRATE"));
  648. // ------------------------------------------
  649. // We don't need to do anything in this part:
  650. // Because:
  651. // 1. this migration stuff (MigrateSystemNT) Gets called in NT5 setup
  652. // after all the ocmanage stuff is completed. By then our IIS5/PWS5 setup
  653. // would have already upgrade the internet server.
  654. // We just have to make sure that the iis/pws 5.0 setup finds our
  655. // "Settings" file and installs the default section within it.
  656. // 2. based on #1 if we install the "settings" file, we will hose
  657. // the registry settings which were created during the ocmanage nt5 gui mode setup.
  658. // ------------------------------------------
  659. // Execute an .inf section from our "settings" file
  660. //if (MySettingsFile_Install() != TRUE) {goto MigrateSystemNT_Exit;}
  661. AnswerFile_ReadSectionAndDoDelete(AnswerFileHandle);
  662. // We've gotten this far that means things are okay.
  663. lReturn = ERROR_SUCCESS;
  664. //MigrateSystemNT_Exit:
  665. iisDebugOut(_T(" End. Return=%d."), lReturn);
  666. return lReturn;
  667. }