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.

2631 lines
91 KiB

  1. #include "stdafx.h"
  2. #include "guid.h"
  3. #include "iadm.h"
  4. #include "mdkey.h"
  5. extern HANDLE g_MyModuleHandle;
  6. extern int g_iPWS40OrBetterInstalled;
  7. extern int g_iPWS10Installed;
  8. extern int g_iVermeerPWS10Installed;
  9. extern CHAR g_FullFileNamePathToSettingsFile[_MAX_PATH];
  10. extern CHAR g_PWS10_Migration_Section_Name_AddReg[];
  11. extern CHAR g_PWS40_Migration_Section_Name_AddReg[];
  12. extern CHAR g_Migration_Section_Name_AddReg[];
  13. extern CHAR g_PWS10_Migration_Section_Name_CopyFiles[];
  14. extern CHAR g_PWS40_Migration_Section_Name_CopyFiles[];
  15. extern char g_Migration_Section_Name_CopyFiles[];
  16. extern MyLogFile g_MyLogFile;
  17. int g_SectionCount = 0;
  18. #define METABASE_BIN_FILENAME "Metabase.bin"
  19. #define METABASE_BIN_BEFORE_CHANGE "kjhgfdsa.001"
  20. #define METABASE_BIN_AFTER_CHANGE "kjhgfdsa.002"
  21. #define REG_NETWORK_MSWEBSVR "Enum\\Network\\MSWEBSVR"
  22. #define REG_HKLM_NETWORK_MSWEBSVR "HKLM\\Enum\\Network\\MSWEBSVR"
  23. #define REG_PWS_40_UNINSTALL_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSIIS"
  24. #define REG_HKLM_PWS_40_UNINSTALL_KEY "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSIIS"
  25. // used to check if pws 4.0 is installed
  26. #define REG_INETSTP "Software\\Microsoft\\INetStp"
  27. #define REG_INETSTP_MAJORVERSION_STRINGVALUE "MajorVersion"
  28. #define REG_INETSTP_INSTALLPATH_STRINGVALUE "InstallPath"
  29. // used to check if pws 1.0 is installed
  30. #define REG_WWWPARAMETERS "System\\CurrentControlSet\\Services\\W3Svc\\Parameters"
  31. #define REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE "MajorVersion"
  32. // used to check if vermeer pws 1.0 is installed
  33. #define FILENAME_FRONTPG_INI "frontpg.ini"
  34. #define FILENAME_FRONTPG_INI_SECTION "FrontPage 1.1"
  35. #define FILENAME_FRONTPG_INI_KEY "PWSRoot"
  36. // used for parsing the values in the .rc file
  37. #define g_LoadString_token_delimiters ",;\t\n\r"
  38. // regkey value for the metabase flag for doing unsecuredread
  39. #define METABASEUNSECUREDREAD_VALUENAME "MetabaseUnSecuredRead"
  40. // unattend answer file stuff for UNATTEND_TXT_PWS_SECTION section
  41. #define UNATTEND_TXT_PWS_SECTION "InternetServer"
  42. #define UNATTEND_TXT_PWS_METABASE_NEW "Win95MigrateDllMetabaseNew"
  43. #define UNATTEND_TXT_PWS_METABASE_ORGINAL "Win95MigrateDllMetabaseOrg"
  44. #define UNATTEND_TXT_FILES_TO_DELETE_SECTION "Win95MigrateDll_DeleteFilesOrDirs_IIS"
  45. // Special key to say "hey, we need to do some special metabase stuff
  46. // like: doing an AppDeleteRecoverable() on the metabase.
  47. // we don't have to do AppDeleteRecoverable if MTS is migrated automagically.
  48. //#define SPECIAL_METABASE_STUFF
  49. int MyMessageBox(char [], char []);
  50. int MySettingsFile_Write_PWS10(HANDLE);
  51. int MySettingsFile_Write_PWS40(HANDLE);
  52. int InstallInfSection(char szINFFilename[],char szSectionName[]);
  53. void RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile);
  54. int RecursivelyMoveRegFormatToInfFormat(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile);
  55. int SetMetabaseToDoUnEncryptedRead(int iOnFlag);
  56. typedef struct _QUEUECONTEXT {
  57. HWND OwnerWindow;
  58. DWORD MainThreadId;
  59. HWND ProgressDialog;
  60. HWND ProgressBar;
  61. BOOL Cancelled;
  62. PTSTR CurrentSourceName;
  63. BOOL ScreenReader;
  64. BOOL MessageBoxUp;
  65. WPARAM PendingUiType;
  66. PVOID PendingUiParameters;
  67. UINT CancelReturnCode;
  68. BOOL DialogKilled;
  69. //
  70. // If the SetupInitDefaultQueueCallbackEx is used, the caller can
  71. // specify an alternate handler for progress. This is useful to
  72. // get the default behavior for disk prompting, error handling, etc,
  73. // but to provide a gas gauge embedded, say, in a wizard page.
  74. //
  75. // The alternate window is sent ProgressMsg once when the copy queue
  76. // is started (wParam = 0. lParam = number of files to copy).
  77. // It is then also sent once per file copied (wParam = 1. lParam = 0).
  78. //
  79. // NOTE: a silent installation (i.e., no progress UI) can be accomplished
  80. // by specifying an AlternateProgressWindow handle of INVALID_HANDLE_VALUE.
  81. //
  82. HWND AlternateProgressWindow;
  83. UINT ProgressMsg;
  84. UINT NoToAllMask;
  85. HANDLE UiThreadHandle;
  86. #ifdef NOCANCEL_SUPPORT
  87. BOOL AllowCancel;
  88. #endif
  89. } QUEUECONTEXT, *PQUEUECONTEXT;
  90. int ReturnTrueIfPWS40_Installed(void)
  91. {
  92. iisDebugOut(_T("ReturnTrueIfPWS40_Installed. Start."));
  93. int iReturn = FALSE;
  94. // Check if pws 4.0 or better is installed.
  95. DWORD rc = 0;
  96. HKEY hKey = NULL;
  97. DWORD dwType, cbData;
  98. BYTE bData[1000];
  99. cbData = 1000;
  100. rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_INETSTP, &hKey);
  101. if (rc == ERROR_SUCCESS)
  102. {
  103. // try open a particular value...
  104. // Check if we can read the Major Version Value.
  105. // try to query the value
  106. rc = RegQueryValueEx(hKey,REG_INETSTP_MAJORVERSION_STRINGVALUE,NULL,&dwType,bData,&cbData);
  107. if ( ERROR_SUCCESS == rc)
  108. {iReturn = TRUE;}
  109. }
  110. else
  111. {
  112. SetLastError(rc);
  113. }
  114. if (hKey){RegCloseKey(hKey);}
  115. iisDebugOut(_T("ReturnTrueIfPWS40_Installed. Return=%d. End."), iReturn);
  116. return iReturn;
  117. }
  118. int ReturnTrueIfVermeerPWS10_Installed(void)
  119. {
  120. iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Start."));
  121. int iReturn = FALSE;
  122. char szFrontpgIniFile[_MAX_PATH];
  123. strcpy(szFrontpgIniFile, "");
  124. if (0 == GetSystemDirectory(szFrontpgIniFile, sizeof(szFrontpgIniFile)))
  125. {
  126. // Error so write it out
  127. SetupLogError_Wrap(LogSevError, "Call to GetSystemDirectory() Failed. GetLastError=%x.", GetLastError());
  128. goto ReturnTrueIfVermeerPWS10_Installed_Exit;
  129. }
  130. else
  131. {
  132. AddPath(szFrontpgIniFile, FILENAME_FRONTPG_INI);
  133. }
  134. if (CheckIfFileExists(szFrontpgIniFile) == TRUE)
  135. {
  136. iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Found %s file. Check FrontPage 1.1/PWSRoot Section."), szFrontpgIniFile);
  137. char buf[_MAX_PATH];
  138. GetPrivateProfileString(FILENAME_FRONTPG_INI_SECTION, FILENAME_FRONTPG_INI_KEY, _T(""), buf, _MAX_PATH, szFrontpgIniFile);
  139. if (*buf && CheckIfFileExists(buf))
  140. {
  141. // yes, vermeer frontpage's personal web server is installed
  142. iReturn = TRUE;
  143. }
  144. else
  145. {
  146. iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Check FrontPage 1.1/PWSRoot Section references file %s. but it's not found so, Vermeer pws1.0 not installed."), buf);
  147. }
  148. }
  149. ReturnTrueIfVermeerPWS10_Installed_Exit:
  150. iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Return=%d. End."), iReturn);
  151. return iReturn;
  152. }
  153. int ReturnTrueIfPWS10_Installed(void)
  154. {
  155. iisDebugOut(_T("ReturnTrueIfPWS10_Installed. Start."));
  156. int iReturn = FALSE;
  157. // For old win95 pws 1.0 check
  158. // Check if we can get the w3svc\parameters key.
  159. HKEY hKey = NULL;
  160. DWORD rc = 0;
  161. DWORD dwType, cbData;
  162. BYTE bData[1000];
  163. cbData = 1000;
  164. rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_WWWPARAMETERS, &hKey);
  165. if ( ERROR_SUCCESS != rc)
  166. {
  167. SetLastError (rc);
  168. // if the key Does not exists pws 1.0a is not installed
  169. goto ReturnTrueIfPWS10_Installed_Exit;
  170. }
  171. // Check if we can read the Major Version Value. Should be set to '\0' if pws 1.0
  172. // try to query the value
  173. rc = RegQueryValueEx(hKey,REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE,NULL,&dwType,bData,&cbData);
  174. if ( ERROR_SUCCESS != rc)
  175. {
  176. // SetLastError (rc);
  177. // if the key Does not exists pws 1.0a is not installed
  178. //SetupLogError_Wrap(LogSevError, "Failed to Read Registry Value '%s' in Key '%s'. GetLastError()=%x",REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE, REG_WWWPARAMETERS, GetLastError());
  179. //iisDebugOut(_T("Failed to Read Registry Value '%s' in Key '%s'. pws1.0a is not installed."),REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE,REG_WWWPARAMETERS);
  180. goto ReturnTrueIfPWS10_Installed_Exit;
  181. }
  182. // Check if we can read the MajorVersion value should be set to '\0' if pws 1.0
  183. if (bData[0] == '\0') {iReturn = TRUE;}
  184. ReturnTrueIfPWS10_Installed_Exit:
  185. if (hKey){RegCloseKey(hKey);}
  186. iisDebugOut(_T("ReturnTrueIfPWS10_Installed. Return=%d. End."), iReturn);
  187. return iReturn;
  188. }
  189. int CheckIfPWS95Exists(void)
  190. {
  191. iisDebugOut(_T("CheckIfPWS95Exists. Start."));
  192. int iReturn = FALSE;
  193. // Check if this is pws 4.0 or better
  194. if (ReturnTrueIfPWS40_Installed() == TRUE)
  195. {
  196. g_iPWS40OrBetterInstalled = TRUE;
  197. iReturn = TRUE;
  198. goto CheckIfPWS95Exists_Exit;
  199. }
  200. // Check if this is pws 1.0a
  201. if (ReturnTrueIfPWS10_Installed() == TRUE)
  202. {
  203. iReturn = TRUE;
  204. g_iPWS10Installed = TRUE;
  205. goto CheckIfPWS95Exists_Exit;
  206. }
  207. // Check if this is Vermeer pws 1.0
  208. if (ReturnTrueIfVermeerPWS10_Installed() == TRUE)
  209. {
  210. iReturn = TRUE;
  211. g_iVermeerPWS10Installed = TRUE;
  212. goto CheckIfPWS95Exists_Exit;
  213. }
  214. CheckIfPWS95Exists_Exit:
  215. iisDebugOut(_T("CheckIfPWS95Exists. Return=%d. End."), iReturn);
  216. return iReturn;
  217. }
  218. void iisDebugOut( TCHAR *pszfmt, ...)
  219. {
  220. TCHAR acsString[1000];
  221. TCHAR acsString2[1000];
  222. va_list va;
  223. va_start(va, pszfmt);
  224. _vstprintf(acsString, pszfmt, va);
  225. va_end(va);
  226. #if DBG == 1 || DEBUG == 1 || _DEBUG == 1
  227. _stprintf(acsString2, _T("%s"), acsString);
  228. OutputDebugString(acsString2);
  229. g_MyLogFile.LogFileWrite(acsString2);
  230. #else // DBG == 0
  231. _stprintf(acsString2, _T("%s"), acsString);
  232. // no outputdebug string for fre builds
  233. g_MyLogFile.LogFileWrite(acsString2);
  234. #endif // DBG
  235. return;
  236. }
  237. //***************************************************************************
  238. //*
  239. //* purpose: TRUE if the file is opened, FALSE if the file does not exists.
  240. //*
  241. //***************************************************************************
  242. int CheckIfFileExists(LPCTSTR szFile)
  243. {
  244. return (GetFileAttributes(szFile) != 0xFFFFFFFF);
  245. }
  246. BOOL isDirEmpty(LPCTSTR szDirName)
  247. {
  248. TCHAR szSearchString[MAX_PATH+1];
  249. HANDLE hFileSearch;
  250. WIN32_FIND_DATA wfdFindData;
  251. BOOL bMoreFiles = TRUE;
  252. //
  253. // Now search for files
  254. //
  255. sprintf(szSearchString, _T("%s\\*.*"), szDirName);
  256. hFileSearch = FindFirstFile(szSearchString, &wfdFindData);
  257. while ((INVALID_HANDLE_VALUE != hFileSearch) && bMoreFiles)
  258. {
  259. if ((0 != lstrcmpi(wfdFindData.cFileName, _T("."))) &&
  260. (0 != lstrcmpi(wfdFindData.cFileName, _T(".."))))
  261. {
  262. FindClose(hFileSearch);
  263. return FALSE;
  264. }
  265. bMoreFiles = FindNextFile(hFileSearch, &wfdFindData);
  266. }
  267. if (INVALID_HANDLE_VALUE != hFileSearch)
  268. {
  269. FindClose(hFileSearch);
  270. }
  271. return TRUE;
  272. }
  273. BOOL RemoveAllDirsIfEmpty(LPCTSTR szTheDir)
  274. {
  275. TCHAR szDirCopy[_MAX_PATH];
  276. DWORD retCode = GetFileAttributes(szTheDir);
  277. _tcscpy(szDirCopy,szTheDir);
  278. if (retCode == 0xFFFFFFFF)
  279. {
  280. return FALSE;
  281. }
  282. if ((retCode & FILE_ATTRIBUTE_DIRECTORY))
  283. {
  284. if (TRUE == isDirEmpty(szDirCopy))
  285. {
  286. iisDebugOut(_T("RemoveDirectory:%s"),szDirCopy);
  287. RemoveDirectory(szDirCopy);
  288. // Get the next dir in...
  289. // and see if it's empty
  290. // strip off the filename
  291. TCHAR * pTemp = strrchr(szDirCopy, '\\');
  292. if (pTemp){*pTemp = '\0';}
  293. RemoveAllDirsIfEmpty(szDirCopy);
  294. // strip off the filename
  295. pTemp = strrchr(szDirCopy, '\\');
  296. if (pTemp){*pTemp = '\0';}
  297. RemoveAllDirsIfEmpty(szDirCopy);
  298. }
  299. }
  300. return TRUE;
  301. }
  302. BOOL InetDeleteFile(LPCTSTR szFileName)
  303. {
  304. // if file exists but DeleteFile() fails
  305. if ( CheckIfFileExists(szFileName) && !(DeleteFile(szFileName)) )
  306. {
  307. // failed to delete it
  308. return FALSE;
  309. }
  310. else
  311. {
  312. iisDebugOut(_T("InetDeleteFile:%s"),szFileName);
  313. TCHAR szDrive_only[_MAX_DRIVE];
  314. TCHAR szPath_only[_MAX_PATH];
  315. TCHAR szTheDir[_MAX_PATH];
  316. _tsplitpath(szFileName,szDrive_only,szPath_only,NULL,NULL);
  317. _tcscpy(szTheDir, szDrive_only);
  318. _tcscat(szTheDir, szPath_only);
  319. // see if the directory is empty...
  320. // if it is.. then remove it...
  321. RemoveAllDirsIfEmpty(szTheDir);
  322. }
  323. return TRUE;
  324. }
  325. BOOL RecRemoveDir(LPCTSTR szName)
  326. {
  327. BOOL iRet = FALSE;
  328. DWORD retCode;
  329. WIN32_FIND_DATA FindFileData;
  330. HANDLE hFile = INVALID_HANDLE_VALUE;
  331. TCHAR szSubDir[_MAX_PATH] = _T("");
  332. TCHAR szDirName[_MAX_PATH] = _T("");
  333. retCode = GetFileAttributes(szName);
  334. if (retCode == 0xFFFFFFFF)
  335. return FALSE;
  336. if (!(retCode & FILE_ATTRIBUTE_DIRECTORY)) {
  337. InetDeleteFile(szName);
  338. return TRUE;
  339. }
  340. _stprintf(szDirName, _T("%s\\*"), szName);
  341. hFile = FindFirstFile(szDirName, &FindFileData);
  342. if (hFile != INVALID_HANDLE_VALUE) {
  343. do {
  344. if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 &&
  345. _tcsicmp(FindFileData.cFileName, _T("..")) != 0 ) {
  346. _stprintf(szSubDir, _T("%s\\%s"), szName, FindFileData.cFileName);
  347. RecRemoveDir(szSubDir);
  348. }
  349. if ( !FindNextFile(hFile, &FindFileData) ) {
  350. FindClose(hFile);
  351. break;
  352. }
  353. } while (TRUE);
  354. }
  355. iRet = RemoveAllDirsIfEmpty(szName);
  356. return iRet;
  357. }
  358. void MyDeleteLinkWildcard(TCHAR *szDir, TCHAR *szFileName)
  359. {
  360. WIN32_FIND_DATA FindFileData;
  361. HANDLE hFile = INVALID_HANDLE_VALUE;
  362. TCHAR szFileToBeDeleted[_MAX_PATH];
  363. _stprintf(szFileToBeDeleted, _T("%s\\%s"), szDir, szFileName);
  364. hFile = FindFirstFile(szFileToBeDeleted, &FindFileData);
  365. if (hFile != INVALID_HANDLE_VALUE)
  366. {
  367. do {
  368. if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 && _tcsicmp(FindFileData.cFileName, _T("..")) != 0 )
  369. {
  370. if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  371. {
  372. // this is a directory, so let's skip it
  373. }
  374. else
  375. {
  376. // this is a file, so let's Delete it.
  377. TCHAR szTempFileName[_MAX_PATH];
  378. _stprintf(szTempFileName, _T("%s\\%s"), szDir, FindFileData.cFileName);
  379. // set to normal attributes, so we can delete it
  380. SetFileAttributes(szTempFileName, FILE_ATTRIBUTE_NORMAL);
  381. // delete it, hopefully
  382. InetDeleteFile(szTempFileName);
  383. }
  384. }
  385. // get the next file
  386. if ( !FindNextFile(hFile, &FindFileData) )
  387. {
  388. FindClose(hFile);
  389. break;
  390. }
  391. } while (TRUE);
  392. }
  393. return;
  394. }
  395. //***************************************************************************
  396. //*
  397. //* purpose: Write out our "settings" file which is just a setupapi .inf file
  398. //* which will get installed on the WinNT side
  399. //*
  400. //***************************************************************************
  401. int MySettingsFile_Write(void)
  402. {
  403. int iReturn = FALSE;
  404. HANDLE hFile = INVALID_HANDLE_VALUE;
  405. iisDebugOut(_T("MySettingsFile_Write. Start."));
  406. // Get From the registry
  407. // if pws 4.0 installed then get all that information
  408. // and save it in the Settings file.
  409. if (g_iPWS40OrBetterInstalled == TRUE)
  410. {
  411. strcpy(g_Migration_Section_Name_AddReg, g_PWS40_Migration_Section_Name_AddReg);
  412. strcpy(g_Migration_Section_Name_CopyFiles, g_PWS40_Migration_Section_Name_CopyFiles);
  413. }
  414. else if (g_iPWS10Installed == TRUE)
  415. {
  416. strcpy(g_Migration_Section_Name_AddReg, g_PWS10_Migration_Section_Name_AddReg);
  417. strcpy(g_Migration_Section_Name_CopyFiles, g_PWS10_Migration_Section_Name_CopyFiles);
  418. }
  419. if (g_iPWS40OrBetterInstalled || g_iPWS10Installed)
  420. {
  421. // Open existing file or create a new one.
  422. if (g_FullFileNamePathToSettingsFile)
  423. {
  424. iisDebugOut(_T("MySettingsFile_Write. CreatingFile '%s'."), g_FullFileNamePathToSettingsFile);
  425. hFile = CreateFile(g_FullFileNamePathToSettingsFile,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  426. if (hFile != INVALID_HANDLE_VALUE)
  427. {
  428. if (g_iPWS40OrBetterInstalled == TRUE)
  429. {
  430. // Get all the pws4.0 registry stuff and save it in the settings file.
  431. iReturn = MySettingsFile_Write_PWS40(hFile);
  432. if (iReturn != TRUE) {SetupLogError_Wrap(LogSevError, "Failed to Write PWS40 Registry values to file '%s'.",g_FullFileNamePathToSettingsFile);}
  433. // On PWS 4.0, We need to make sure to
  434. // 1. Not copy over files/dirs in the inetsrv directory from pws 4.0
  435. // 2. copy over all other files in the inetsrv directory for the user
  436. // might have some controls and such that they created and want to keep.
  437. // add deleted files
  438. }
  439. else if (g_iPWS10Installed == TRUE)
  440. {
  441. // if pws 1.0 installed then get all that information and save it in the Settings file.
  442. iReturn = MySettingsFile_Write_PWS10(hFile);
  443. if (iReturn != TRUE) {SetupLogError_Wrap(LogSevError, "Failed to Write PWS10 Registry values to file '%s'.",g_FullFileNamePathToSettingsFile);}
  444. }
  445. }
  446. else
  447. {
  448. SetupLogError_Wrap(LogSevError, "Failed to Create to file '%s'.",g_FullFileNamePathToSettingsFile);
  449. }
  450. }
  451. else
  452. {
  453. SetupLogError_Wrap(LogSevError, "File handle Does not exist '%s'.",g_FullFileNamePathToSettingsFile);
  454. }
  455. }
  456. else
  457. {
  458. iisDebugOut(_T("MySettingsFile_Write. Neither PWS 1.0 or 4.0 is currently installed, no upgraded required."));
  459. }
  460. if (hFile && hFile != INVALID_HANDLE_VALUE) {CloseHandle(hFile);hFile=NULL;}
  461. iisDebugOut(_T("MySettingsFile_Write. End. Return = %d"), iReturn);
  462. return iReturn;
  463. }
  464. int AnswerFile_AppendDeletion(TCHAR * szFileNameOrPathToDelete,LPCSTR AnswerFile)
  465. {
  466. int iReturn = FALSE;
  467. CHAR szTempString[30];
  468. CHAR szQuotedPath[_MAX_PATH];
  469. if (!szFileNameOrPathToDelete)
  470. {
  471. goto AnswerFile_AppendDeletion_Exit;
  472. }
  473. // Open existing file or create a new one.
  474. if (!AnswerFile)
  475. {
  476. SetupLogError_Wrap(LogSevError, "File handle Does not exist '%s'.",AnswerFile);
  477. goto AnswerFile_AppendDeletion_Exit;
  478. }
  479. if (CheckIfFileExists(AnswerFile) != TRUE)
  480. {
  481. iisDebugOut(_T("AnswerFile_AppendDeletion:file not exist...\n"));
  482. goto AnswerFile_AppendDeletion_Exit;
  483. }
  484. sprintf(szTempString,"%d",g_SectionCount);
  485. iisDebugOut(_T("AnswerFile_AppendDeletion:%s=%s\n"), szTempString,szFileNameOrPathToDelete);
  486. sprintf(szQuotedPath, "\"%s\"",szFileNameOrPathToDelete);
  487. if (0 == WritePrivateProfileString(UNATTEND_TXT_FILES_TO_DELETE_SECTION, szTempString, szQuotedPath, AnswerFile))
  488. {
  489. SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_FILES_TO_DELETE_SECTION, AnswerFile, GetLastError());
  490. iisDebugOut(_T("Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x."), UNATTEND_TXT_FILES_TO_DELETE_SECTION, AnswerFile, GetLastError());
  491. goto AnswerFile_AppendDeletion_Exit;
  492. }
  493. g_SectionCount++;
  494. iReturn = TRUE;
  495. AnswerFile_AppendDeletion_Exit:
  496. iisDebugOut(_T("AnswerFile_AppendDeletion:end.ret=%d,%s\n"),iReturn,szFileNameOrPathToDelete);
  497. return iReturn;
  498. }
  499. int AnswerFile_ReadSectionAndDoDelete(IN HINF AnswerFileHandle)
  500. {
  501. int iReturn = FALSE;
  502. BOOL bFlag = FALSE;
  503. INFCONTEXT Context;
  504. DWORD dwRequiredSize = 0;
  505. LPTSTR szLine = NULL;
  506. DWORD retCode = 0;
  507. iisDebugOut(_T("MySettingsFile_ReadSectionAndDoDelete:start\n"));
  508. // go to the beginning of the section in the INF file
  509. bFlag = SetupFindFirstLine(AnswerFileHandle,UNATTEND_TXT_FILES_TO_DELETE_SECTION, NULL, &Context);
  510. if (!bFlag)
  511. {
  512. goto MySettingsFile_ReadSectionAndDoDelete_Exit;
  513. }
  514. // loop through the items in the section.
  515. while (bFlag)
  516. {
  517. // get the size of the memory we need for this
  518. bFlag = SetupGetLineText(&Context, NULL, NULL, NULL, NULL, 0, &dwRequiredSize);
  519. // prepare the buffer to receive the line
  520. szLine = (LPTSTR)GlobalAlloc( GPTR, dwRequiredSize * sizeof(TCHAR) );
  521. if ( !szLine )
  522. {
  523. iisDebugOut(_T("err:Out of Memory"));
  524. goto MySettingsFile_ReadSectionAndDoDelete_Exit;
  525. }
  526. // get the line from the inf file1
  527. if (SetupGetLineText(&Context, NULL, NULL, NULL, szLine, dwRequiredSize, NULL) == FALSE)
  528. {
  529. iisDebugOut(_T("SetupGetLineText failed"));
  530. goto MySettingsFile_ReadSectionAndDoDelete_Exit;
  531. }
  532. // For each of these entries do something
  533. // Delete the file...
  534. retCode = GetFileAttributes(szLine);
  535. if (retCode != 0xFFFFFFFF)
  536. {
  537. iReturn = TRUE;
  538. if (retCode & FILE_ATTRIBUTE_DIRECTORY)
  539. {
  540. // it's a directory...recusively delete it
  541. iisDebugOut(_T("RecRemoveDir:%s\n"),szLine);
  542. RecRemoveDir(szLine);
  543. }
  544. else
  545. {
  546. iisDebugOut(_T("InetDeleteFile:%s\n"),szLine);
  547. InetDeleteFile(szLine);
  548. }
  549. }
  550. else
  551. {
  552. iisDebugOut(_T("not found:%s, skipping delete\n"),szLine);
  553. }
  554. // find the next line in the section. If there is no next line it should return false
  555. bFlag = SetupFindNextLine(&Context, &Context);
  556. // free the temporary buffer
  557. if (szLine) {GlobalFree(szLine);szLine=NULL;}
  558. iReturn = TRUE;
  559. }
  560. MySettingsFile_ReadSectionAndDoDelete_Exit:
  561. if (szLine) {GlobalFree(szLine);szLine=NULL;}
  562. iisDebugOut(_T("MySettingsFile_ReadSectionAndDoDelete:end\n"));
  563. return iReturn;
  564. }
  565. int MySettingsFile_Install(void)
  566. {
  567. int iReturn = 0;
  568. iReturn = InstallInfSection(g_FullFileNamePathToSettingsFile, "DefaultInstall");
  569. return iReturn;
  570. }
  571. //***************************************************************************
  572. //*
  573. //* purpose:
  574. //*
  575. //***************************************************************************
  576. LPWSTR MakeWideStrFromAnsi(LPSTR psz)
  577. {
  578. LPWSTR pwsz;
  579. int i;
  580. // arg checking.
  581. if (!psz)
  582. return NULL;
  583. // compute the length
  584. i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
  585. if (i <= 0) return NULL;
  586. pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
  587. if (!pwsz) return NULL;
  588. MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
  589. pwsz[i - 1] = 0;
  590. return pwsz;
  591. }
  592. //***************************************************************************
  593. //*
  594. //* purpose:
  595. //*
  596. //***************************************************************************
  597. void MakePath(LPTSTR lpPath)
  598. {
  599. LPTSTR lpTmp;
  600. lpTmp = CharPrev( lpPath, lpPath + _tcslen(lpPath));
  601. // chop filename off
  602. while ( (lpTmp > lpPath) && *lpTmp && (*lpTmp != '\\') )
  603. lpTmp = CharPrev( lpPath, lpTmp );
  604. if ( *CharPrev( lpPath, lpTmp ) != ':' )
  605. *lpTmp = '\0';
  606. else
  607. *CharNext(lpTmp) = '\0';
  608. return;
  609. }
  610. //***************************************************************************
  611. //*
  612. //* purpose: add's filename onto path
  613. //*
  614. //***************************************************************************
  615. void AddPath(LPTSTR szPath, LPCTSTR szName )
  616. {
  617. LPTSTR p = szPath;
  618. // Find end of the string
  619. while (*p){p = _tcsinc(p);}
  620. // If no trailing backslash then add one
  621. if (*(_tcsdec(szPath, p)) != _T('\\'))
  622. {_tcscat(szPath, _T("\\"));}
  623. // if there are spaces precluding szName, then skip
  624. while ( *szName == ' ' ) szName = _tcsinc(szName);;
  625. // Add new name to existing path string
  626. _tcscat(szPath, szName);
  627. }
  628. // Prepare to read a value by finding the value's size.
  629. LONG RegPrepareValue(HKEY hKey, LPCTSTR pchValueName, DWORD * pdwType,DWORD * pcbSize,BYTE ** ppbData )
  630. {
  631. LONG err = 0 ;
  632. BYTE chDummy[2] ;
  633. DWORD cbData = 0 ;
  634. do
  635. {
  636. // Set the resulting buffer size to 0.
  637. *pcbSize = 0 ;
  638. *ppbData = NULL ;
  639. err = ::RegQueryValueEx( hKey, (TCHAR *) pchValueName, 0, pdwType, chDummy, & cbData ) ;
  640. // The only error we should get here is ERROR_MORE_DATA, but
  641. // we may get no error if the value has no data.
  642. if ( err == 0 )
  643. {
  644. cbData = sizeof (LONG) ; // Just a fudgy number
  645. }
  646. else
  647. if ( err != ERROR_MORE_DATA )
  648. break ;
  649. // Allocate a buffer large enough for the data.
  650. *ppbData = new BYTE [ (*pcbSize = cbData) + sizeof (LONG) ] ;
  651. if ( *ppbData == NULL )
  652. {
  653. err = ERROR_NOT_ENOUGH_MEMORY ;
  654. break ;
  655. }
  656. // Now that have a buffer, re-fetch the value.
  657. err = ::RegQueryValueEx( hKey, (TCHAR *) pchValueName, 0, pdwType, *ppbData, pcbSize ) ;
  658. } while ( FALSE ) ;
  659. if ( err ) {delete [] *ppbData ;}
  660. return err ;
  661. }
  662. int AddRegToInfIfExist_Dword(HKEY hRootKeyType,CHAR szRootKey[],CHAR szRootName[],HANDLE fAppendToFile)
  663. {
  664. int iReturn = FALSE;
  665. HKEY hOpen = NULL;
  666. DWORD dwType;
  667. DWORD cbData = 500;
  668. BYTE bData[500];
  669. CHAR szTheStringToWrite[2000];
  670. DWORD dwBytesWritten = 0;
  671. // Create the HKLM string for the output string
  672. CHAR szThisKeyType[5];
  673. strcpy(szThisKeyType, "HKLM");
  674. if (hRootKeyType == HKEY_LOCAL_MACHINE) {strcpy(szThisKeyType, "HKLM");}
  675. if (hRootKeyType == HKEY_CLASSES_ROOT) {strcpy(szThisKeyType, "HKCR");}
  676. if (hRootKeyType == HKEY_CURRENT_USER) {strcpy(szThisKeyType, "HKCU");}
  677. if (hRootKeyType == HKEY_USERS) {strcpy(szThisKeyType, "HKU");}
  678. // try to open the key
  679. if (ERROR_SUCCESS == RegOpenKey(hRootKeyType, szRootKey, &hOpen))
  680. {
  681. // try to query the value
  682. DWORD dwData = 0;
  683. DWORD dwDataSize = 0;
  684. dwDataSize = sizeof (DWORD);
  685. if (ERROR_SUCCESS == RegQueryValueEx(hOpen,szRootName,NULL,&dwType,(LPBYTE) &dwData,&dwDataSize))
  686. {
  687. DWORD dwTheValue = 0;
  688. dwTheValue = dwData;
  689. // We got the value. so now let's write the darn thing out to the file.
  690. //HKLM,"System\CurrentControlSet\Services\W3Svc\Parameters","MajorVersion",0x00010001,4
  691. sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00010001,%ld\r\n",szThisKeyType,szRootKey,szRootName,dwTheValue);
  692. iisDebugOut(_T("AddRegToInfIfExist_Dword:%s."),szTheStringToWrite);
  693. // write it to the file
  694. if (fAppendToFile) {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
  695. else {printf(szTheStringToWrite);}
  696. iReturn = TRUE;
  697. }
  698. }
  699. if (hOpen) {RegCloseKey(hOpen);}
  700. return iReturn;
  701. }
  702. /*
  703. This function can be used to recursively grab a whole key out
  704. of the registry and write it to a setupapi style .inf file.
  705. [version]
  706. signature="$CHICAGO$"
  707. advancedinf=2.0
  708. [PWS10_Migrate_install]
  709. AddReg=PWS10_Migrate_Reg
  710. [PWS10_Migrate_Reg] (Creates this section)
  711. HKLM,"System\CurrentControlSet\Services\InetInfo",,,""
  712. HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters",,,""
  713. HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","MaxPoolThreads",0x00000001,05
  714. HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","MaxConcurrency",0x00000001,01
  715. HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","ThreadTimeout",0x00000001,00,2
  716. ...
  717. ...
  718. Here are the flags as defined in the setupapi.h file:
  719. #define FLG_ADDREG_BINVALUETYPE ( 0x00000001 )
  720. #define FLG_ADDREG_NOCLOBBER ( 0x00000002 )
  721. #define FLG_ADDREG_DELVAL ( 0x00000004 )
  722. #define FLG_ADDREG_APPEND ( 0x00000008 ) // Currently supported only for REG_MULTI_SZ values.
  723. #define FLG_ADDREG_KEYONLY ( 0x00000010 ) // Just create the key, ignore value
  724. #define FLG_ADDREG_OVERWRITEONLY ( 0x00000020 ) // Set only if value already exists
  725. #define FLG_ADDREG_TYPE_SZ ( 0x00000000 )
  726. #define FLG_ADDREG_TYPE_MULTI_SZ ( 0x00010000 )
  727. #define FLG_ADDREG_TYPE_EXPAND_SZ ( 0x00020000 )
  728. #define FLG_ADDREG_TYPE_BINARY ( 0x00000000 | FLG_ADDREG_BINVALUETYPE )
  729. #define FLG_ADDREG_TYPE_DWORD ( 0x00010000 | FLG_ADDREG_BINVALUETYPE )
  730. #define FLG_ADDREG_TYPE_NONE ( 0x00020000 | FLG_ADDREG_BINVALUETYPE )
  731. #define FLG_ADDREG_TYPE_MASK ( 0xFFFF0000 | FLG_ADDREG_BINVALUETYPE )
  732. */
  733. int RecursivelyMoveRegFormatToInfFormat(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile)
  734. {
  735. int iReturn = FALSE;
  736. int iGotDefaultValue = FALSE;
  737. // Stuff for getting values in our node
  738. HKEY hKey = NULL;
  739. DWORD rc = 0;
  740. DWORD dwIndex =0, dwType, cbValueName, cbValue, nStrSize;
  741. CHAR lpTemp[20], lpValueName[32], msg[512];
  742. CHAR *strResult = NULL;
  743. unsigned int i = 0;
  744. union vEntry
  745. {
  746. DWORD dw; // REG_DWORD, REG_DWORD_LITTLE_ENDIAN
  747. CHAR sz[256]; // REG_SZ
  748. CHAR esz[256]; // REG_EXPAND_SZ
  749. CHAR bin[1024]; // REG_BINARY
  750. CHAR dwbig[4]; // REG_DWORD_BIG_ENDIAN
  751. CHAR msz[2048]; // REG_MULTI_SZ
  752. } vEntry1;
  753. // Stuff for looping thru keys that we can see
  754. HANDLE hHeap = NULL;
  755. DWORD dwBufSize, nSubkeys, nSubkeyNameLen;
  756. LPTSTR lpBuffer = NULL;
  757. CHAR szThisKeyType[5];
  758. CHAR szCompoundFromRootKey[1000];
  759. CHAR szTheStringToWrite[2000];
  760. DWORD dwBytesWritten = 0;
  761. // Create the HKLM string for the output string
  762. strcpy(szThisKeyType, "HKLM");
  763. if (hRootKeyType == HKEY_LOCAL_MACHINE) {strcpy(szThisKeyType, "HKLM");}
  764. if (hRootKeyType == HKEY_CLASSES_ROOT) {strcpy(szThisKeyType, "HKCR");}
  765. if (hRootKeyType == HKEY_CURRENT_USER) {strcpy(szThisKeyType, "HKCU");}
  766. if (hRootKeyType == HKEY_USERS) {strcpy(szThisKeyType, "HKU");}
  767. // Get the szRootKey and work from there
  768. rc = RegOpenKey(hRootKeyType, szRootKey, &hKey);
  769. if (rc != ERROR_SUCCESS)
  770. {
  771. goto RecursivelyMoveRegFormatToInfFormat_Exit;
  772. }
  773. // Grab the "Default" Entry if there is one.
  774. cbValue = sizeof(vEntry1);
  775. rc = RegQueryValueEx(hKey, NULL, 0, &dwType, (LPBYTE) &vEntry1, &cbValue) ;
  776. if ( ERROR_SUCCESS == rc)
  777. {
  778. if (vEntry1.sz)
  779. {
  780. iGotDefaultValue = TRUE;
  781. strResult = (TCHAR *) vEntry1.sz;
  782. // This can only be a string!
  783. // from: System\\CurrentControlSet\\Services\\InetInfo
  784. // Value = Something
  785. // to: HKLM,"Software\Microsoft\InetSrv",,,"Something"
  786. // ---------------------------------------------------
  787. sprintf(szTheStringToWrite, "%s,\"%s\",,,\"%s\"\r\n",szThisKeyType, szRootKey, strResult);
  788. if (fAppendToFile)
  789. {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
  790. else
  791. {printf(szTheStringToWrite);}
  792. }
  793. }
  794. // if there was no default entry, then just write the key without a default entry.
  795. if (!iGotDefaultValue)
  796. {
  797. // to: HKLM,"Software\Microsoft\InetSrv",,0x00000010,"Something"
  798. sprintf(szTheStringToWrite, "%s,\"%s\",,0x00000010,\"%s\"\r\n",szThisKeyType, szRootKey, strResult);
  799. if (fAppendToFile) {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
  800. else {printf(szTheStringToWrite);}
  801. }
  802. // Now Enum all ValueNames under this
  803. dwIndex = 0;
  804. while (rc == ERROR_SUCCESS)
  805. {
  806. memset(msg, 0, sizeof(msg));
  807. cbValueName = 32;
  808. cbValue = sizeof(vEntry1);
  809. rc = RegEnumValue( hKey, dwIndex++, lpValueName, &cbValueName, NULL, &dwType, (LPBYTE) &vEntry1, &cbValue );
  810. if ( ERROR_SUCCESS == rc)
  811. {
  812. strcpy(szTheStringToWrite, "");
  813. switch (dwType)
  814. {
  815. case REG_SZ:
  816. // to: HKLM,"Software\Microsoft\InetSrv","SomethingName",0x00000000,"SomethingData"
  817. sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00000000,\"%s\"\r\n",szThisKeyType,szRootKey, lpValueName, vEntry1.sz);
  818. break;
  819. case REG_EXPAND_SZ:
  820. // to: HKLM,"Software\Microsoft\InetSrv","SomethingName",0x00020000,"%windir%\SomethingData"
  821. nStrSize = ExpandEnvironmentStrings(vEntry1.esz, msg, 512);
  822. sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00020000,\"%s\"\r\n",szThisKeyType,szRootKey, lpValueName, vEntry1.sz);
  823. break;
  824. case REG_MULTI_SZ:
  825. // to: HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","ThreadTimeout",0x00000001,00,20
  826. strcpy(msg, "");
  827. for (i=0;i < cbValue; i++)
  828. {
  829. if (i==0){sprintf(lpTemp, "%02X", (BYTE) vEntry1.bin[i]);}
  830. else{sprintf(lpTemp, ",%02X", (BYTE) vEntry1.bin[i]);}
  831. strcat(msg, lpTemp);
  832. }
  833. sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00000001,%s\r\n",szThisKeyType,szRootKey, lpValueName, msg);
  834. break;
  835. case REG_DWORD:
  836. // to: HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","StartupServices",0x00010001,1
  837. sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00010001,%ld\r\n",szThisKeyType,szRootKey, lpValueName, vEntry1.dw);
  838. break;
  839. case REG_DWORD_BIG_ENDIAN:
  840. case REG_BINARY:
  841. // to: HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","MaxPoolThreads",0x00000001,05
  842. strcpy(msg, "");
  843. for (i=0;i < cbValue; i++)
  844. {
  845. if (i==0){sprintf(lpTemp, "%02X", (BYTE) vEntry1.bin[i]);}
  846. else{sprintf(lpTemp, ",%02X", (BYTE) vEntry1.bin[i]);}
  847. strcat(msg, lpTemp);
  848. }
  849. sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00000001,%s\r\n",szThisKeyType,szRootKey, lpValueName, msg);
  850. break;
  851. default:
  852. sprintf(szTheStringToWrite, "; Unknown data value for Key '%s', Value '%s'", szRootKey, lpValueName);
  853. SetupLogError_Wrap(LogSevError, "Error Reading Registry Key '%s', Unknown data value for key '%s'.",szRootKey, lpValueName);
  854. }
  855. if (fAppendToFile) {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
  856. else {printf(szTheStringToWrite);}
  857. }
  858. }
  859. //
  860. // Now Recursively go thru the Sub keys
  861. //
  862. RegQueryInfoKey(hKey, NULL, NULL, NULL, &nSubkeys, &nSubkeyNameLen, NULL, NULL, NULL, NULL, NULL, NULL);
  863. // Allocate memory
  864. hHeap = GetProcessHeap();
  865. lpBuffer = (CHAR *) HeapAlloc(hHeap, 0, ++nSubkeyNameLen);
  866. if (lpBuffer)
  867. {
  868. // Enum thru the keys
  869. for (dwIndex = 0; dwIndex < nSubkeys; dwIndex++)
  870. {
  871. dwBufSize = nSubkeyNameLen;
  872. rc = RegEnumKeyEx(hKey, dwIndex, lpBuffer, &dwBufSize, NULL, NULL, NULL, NULL);
  873. if ( ERROR_SUCCESS == rc)
  874. {
  875. strcpy(szCompoundFromRootKey, szRootKey);
  876. strcat(szCompoundFromRootKey, "\\");
  877. strcat(szCompoundFromRootKey, lpBuffer);
  878. // Call this function again, but with the newly created key.
  879. // and they'll tell they're friends, who will tell they're friends... it's amway!
  880. RecursivelyMoveRegFormatToInfFormat(hRootKeyType, szCompoundFromRootKey, fAppendToFile);
  881. }
  882. }
  883. }
  884. // Set the flag to say, yes we did some work
  885. iReturn = TRUE;
  886. RecursivelyMoveRegFormatToInfFormat_Exit:
  887. if (hKey){RegCloseKey(hKey);}
  888. if (hHeap && lpBuffer){HeapFree(hHeap, 0, lpBuffer);}
  889. return iReturn;
  890. }
  891. //-------------------------------------------------------------------
  892. // purpose: install an section in an .inf file
  893. //-------------------------------------------------------------------
  894. int InstallInfSection(char szINFFilename_Full[],char szSectionName[])
  895. {
  896. HWND Window = NULL;
  897. PTSTR SourcePath = NULL;
  898. HINF InfHandle = INVALID_HANDLE_VALUE;
  899. HSPFILEQ FileQueue = INVALID_HANDLE_VALUE;
  900. PQUEUECONTEXT QueueContext = NULL;
  901. BOOL bReturn = FALSE;
  902. BOOL bError = TRUE; // assume failure.
  903. TCHAR ActualSection[1000];
  904. DWORD ActualSectionLength;
  905. TCHAR * pTemp = NULL;
  906. iisDebugOut(_T("InstallInfSection(%s, [%s]). Start."),szINFFilename_Full,szSectionName);
  907. //__try {
  908. // Get the path to setup.exe and strip off filename so we only have the path
  909. char szPath[_MAX_PATH];
  910. // get the path only
  911. strcpy(szPath,g_FullFileNamePathToSettingsFile);
  912. // strip off the filename
  913. pTemp = strrchr(szPath, '\\');
  914. if (pTemp){*pTemp = '\0';}
  915. // set it to the pointer
  916. SourcePath = szPath;
  917. pTemp = NULL;
  918. pTemp = strrchr(SourcePath, '\\');
  919. if (pTemp) {*pTemp = '\0';}
  920. // Check if the file exists
  921. if (CheckIfFileExists(szINFFilename_Full) == FALSE)
  922. {
  923. SetupLogError_Wrap(LogSevError, "InstallInfSection() Error: Cannot Find the file '%s'. FAILURE.", szINFFilename_Full);
  924. goto c0;
  925. }
  926. //
  927. // Load the inf file and get the handle
  928. //
  929. InfHandle = SetupOpenInfFile(szINFFilename_Full, NULL, INF_STYLE_WIN4, NULL);
  930. if(InfHandle == INVALID_HANDLE_VALUE)
  931. {
  932. if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupOpenInfFile(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
  933. goto c1;
  934. }
  935. //
  936. // See if there is an nt-specific section
  937. //
  938. SetupDiGetActualSectionToInstall(InfHandle,szSectionName,ActualSection,sizeof(ActualSection),&ActualSectionLength,NULL);
  939. //
  940. // Create a setup file queue and initialize the default queue callback.
  941. //
  942. FileQueue = SetupOpenFileQueue();
  943. if(FileQueue == INVALID_HANDLE_VALUE)
  944. {
  945. if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupOpenFileQueue(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
  946. goto c1;
  947. }
  948. //QueueContext = SetupInitDefaultQueueCallback(Window);
  949. //if(!QueueContext) {goto c1;}
  950. QueueContext = (PQUEUECONTEXT) SetupInitDefaultQueueCallbackEx(Window,NULL,0,0,0);
  951. if(!QueueContext)
  952. {
  953. if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupInitDefaultQueueCallbackEx(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
  954. goto c1;
  955. }
  956. QueueContext->PendingUiType = IDF_CHECKFIRST;
  957. //
  958. // Enqueue file operations for the section passed on the cmd line.
  959. //
  960. //SourcePath = NULL;
  961. bReturn = SetupInstallFilesFromInfSection(InfHandle,NULL,FileQueue,ActualSection,SourcePath,SP_COPY_NEWER);
  962. if(!bReturn)
  963. {
  964. if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupInstallFilesFromInfSection(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
  965. goto c1;
  966. }
  967. //
  968. // Commit file queue.
  969. //
  970. if(!SetupCommitFileQueue(Window, FileQueue, SetupDefaultQueueCallback, QueueContext))
  971. {
  972. if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupCommitFileQueue(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
  973. goto c1;
  974. }
  975. //
  976. // Perform non-file operations for the section passed on the cmd line.
  977. //
  978. bReturn = SetupInstallFromInfSection(Window,InfHandle,ActualSection,SPINST_ALL ^ SPINST_FILES,NULL,NULL,0,NULL,NULL,NULL,NULL);
  979. if(!bReturn)
  980. {
  981. if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupInstallFromInfSection(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
  982. goto c1;
  983. }
  984. //
  985. // Refresh the desktop.
  986. //
  987. SHChangeNotify(SHCNE_ASSOCCHANGED,SHCNF_FLUSHNOWAIT,0,0);
  988. //
  989. // If we get to here, then this routine has been successful.
  990. //
  991. bError = FALSE;
  992. c1:
  993. //
  994. // If the bError was because the user cancelled, then we don't want to consider
  995. // that as an bError (i.e., we don't want to give an bError popup later).
  996. //
  997. if(bError && (GetLastError() == ERROR_CANCELLED)) {bError = FALSE;}
  998. if(QueueContext) {SetupTermDefaultQueueCallback(QueueContext);QueueContext = NULL;}
  999. if(FileQueue != INVALID_HANDLE_VALUE) {SetupCloseFileQueue(FileQueue);FileQueue = INVALID_HANDLE_VALUE;}
  1000. if(InfHandle != INVALID_HANDLE_VALUE) {SetupCloseInfFile(InfHandle);InfHandle = INVALID_HANDLE_VALUE;}
  1001. c0: ;
  1002. // } __except(EXCEPTION_EXECUTE_HANDLER)
  1003. // {
  1004. // if(QueueContext) {SetupTermDefaultQueueCallback(QueueContext);}
  1005. // if(FileQueue != INVALID_HANDLE_VALUE) {SetupCloseFileQueue(FileQueue);}
  1006. // if(InfHandle != INVALID_HANDLE_VALUE) {SetupCloseInfFile(InfHandle);}
  1007. // }
  1008. //
  1009. // If the bError was because the user cancelled, then we don't want to consider
  1010. // that as an bError (i.e., we don't want to give an bError popup later).
  1011. //
  1012. if(bError && (GetLastError() == ERROR_CANCELLED)) {bError = FALSE;}
  1013. // Display installation failed message
  1014. if(bError)
  1015. {
  1016. SetupLogError_Wrap(LogSevError, "InstallInfSection(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);
  1017. }
  1018. else
  1019. {
  1020. iisDebugOut(_T("InstallInfSection(%s, [%s]). End."),szINFFilename_Full,szSectionName);
  1021. }
  1022. return bError;
  1023. }
  1024. int MySettingsFile_Write_PWS40(HANDLE hFile)
  1025. {
  1026. int iReturn = FALSE;
  1027. int iEverythingIsKool = TRUE;
  1028. CHAR szTheStringToWrite[2000];
  1029. DWORD dwBytesWritten = 0;
  1030. TCHAR szMetabaseFullPath[_MAX_PATH];
  1031. // Registry variables
  1032. HKEY hKey = NULL;
  1033. DWORD dwType, cbData=1000,rc=0;
  1034. BYTE bData[1000];
  1035. char *token = NULL;
  1036. iisDebugOut(_T("MySettingsFile_Write_PWS40. Start."));
  1037. if (hFile)
  1038. {
  1039. // ----------------------------
  1040. // Write the header information
  1041. // ----------------------------
  1042. strcpy(szTheStringToWrite, "[version]\r\n");
  1043. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1044. if (!iReturn) {iEverythingIsKool = FALSE;}
  1045. strcpy(szTheStringToWrite, "signature=\"$CHICAGO$\"\r\n");
  1046. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1047. if (!iReturn) {iEverythingIsKool = FALSE;}
  1048. strcpy(szTheStringToWrite, "advancedinf=2.0\r\n\r\n");
  1049. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1050. if (!iReturn) {iEverythingIsKool = FALSE;}
  1051. // Create a [DefaultInstall] section which will get run
  1052. // ----------------------------
  1053. strcpy(szTheStringToWrite, "[DefaultInstall]\r\n");
  1054. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1055. if (!iReturn) {iEverythingIsKool = FALSE;}
  1056. sprintf(szTheStringToWrite, "AddReg=%s\r\n", g_Migration_Section_Name_AddReg);
  1057. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1058. if (!iReturn) {iEverythingIsKool = FALSE;}
  1059. // sprintf(szTheStringToWrite, "CopyFiles=%s\r\n\r\n", g_Migration_Section_Name_CopyFiles);
  1060. // iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1061. // if (!iReturn) {iEverythingIsKool = FALSE;}
  1062. // inetstp setup information
  1063. // AddReg information
  1064. // ----------------------------
  1065. iisDebugOut(_T("MySettingsFile_Write_PWS40. Adding AddReg Section."));
  1066. sprintf(szTheStringToWrite, "[%s]\r\n", g_Migration_Section_Name_AddReg);
  1067. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1068. if (!iReturn) {iEverythingIsKool = FALSE;}
  1069. // Now, Get the ";" delimited list of HKLM registry values to read and write to our file.
  1070. char szSemiColonDelimitedList[1024];
  1071. strcpy(szSemiColonDelimitedList,"");
  1072. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_PWS40_HKLM_REG_TO_MIGRATE, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
  1073. {
  1074. iisDebugOut(_T("MySettingsFile_Write_PWS40. Err or LoadString retieval of IDS_PWS40_HKLM_REG_TO_MIGRATE, Defaulting with english registry values to copy over."));
  1075. strcpy(szSemiColonDelimitedList,"Software\\Microsoft\\InetStp;System\\CurrentControlSet\\Services\\InetInfo;System\\CurrentControlSet\\Services\\W3Svc;System\\CurrentControlSet\\Services\\ASP");
  1076. }
  1077. //LOOP THRU THE LIST
  1078. token = NULL;
  1079. token = strtok( szSemiColonDelimitedList, g_LoadString_token_delimiters);
  1080. while( token != NULL )
  1081. {
  1082. // we really should remove pre/post trailing spaces
  1083. // Grab this certain value("Software\\Microsoft\\INetStp")
  1084. // and recursively write it to our "settings" file
  1085. RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY_LOCAL_MACHINE,token,hFile);
  1086. // Get next token
  1087. token = strtok( NULL, g_LoadString_token_delimiters);
  1088. }
  1089. // Lookup these key,string value pairs and
  1090. // if they exist, add them to the inf file.
  1091. AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_common",hFile);
  1092. AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_www",hFile);
  1093. AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_pwmgr",hFile);
  1094. AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_doc_common",hFile);
  1095. AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_doc_pwmcore",hFile);
  1096. AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_doc_asp",hFile);
  1097. /*
  1098. // CopyFiles information
  1099. // ----------------------------
  1100. // Lookup the inetstp key to get the location of inetsrv directory.
  1101. iisDebugOut(_T("MySettingsFile_Write_PWS40. CopyFiles Section. lookup registry inetstp."));
  1102. rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_INETSTP, &hKey);
  1103. if ( ERROR_SUCCESS != rc)
  1104. {
  1105. SetLastError (rc);
  1106. SetupLogError_Wrap(LogSevError, "Failed to open registry key %s GetLastError()=%x", REG_INETSTP, GetLastError());
  1107. // if the key does not exist, then hey, we won't be able to find
  1108. // the metabase, much less upgrade it!
  1109. // so let's bag out of here!
  1110. iEverythingIsKool = FALSE;
  1111. goto MySettingsFile_Write_PWS40_Exit;
  1112. }
  1113. // try to query the value
  1114. rc = RegQueryValueEx(hKey,REG_INETSTP_INSTALLPATH_STRINGVALUE,NULL,&dwType,bData,&cbData);
  1115. if ( ERROR_SUCCESS != rc)
  1116. {
  1117. SetLastError (rc);
  1118. SetupLogError_Wrap(LogSevError, "Failed to Read Registry key %s Value in Key '%s'. GetLastError()=%x", REG_INETSTP_INSTALLPATH_STRINGVALUE, REG_INETSTP, GetLastError());
  1119. iEverythingIsKool = FALSE;
  1120. goto MySettingsFile_Write_PWS40_Exit;
  1121. }
  1122. // We have the value, copy it to our string
  1123. // Should look something like this "c:\\windows\system\inetsrv"
  1124. _tcscpy(szMetabaseFullPath, (const char *) bData);
  1125. // Now add on the metadata.dll part
  1126. AddPath(szMetabaseFullPath, METADATA_DLL_FILENAME);
  1127. // Check if it exists.
  1128. if (CheckIfFileExists(szMetabaseFullPath) != TRUE)
  1129. {
  1130. SetupLogError_Wrap(LogSevError, "File not found FAILURE. '%s'.", szMetabaseFullPath);
  1131. iEverythingIsKool = FALSE;
  1132. goto MySettingsFile_Write_PWS40_Exit;
  1133. }
  1134. iisDebugOut(_T("MySettingsFile_Write_PWS40. CopyFiles Section. Check if file exist %s = TRUE", szMetabaseFullPath));
  1135. // Now we need to copy this file from
  1136. // the system dir to the system32 directory.
  1137. // So... let's create an entry in our "settings" file
  1138. // to do it upon installation.
  1139. //[Section1]
  1140. //Metabase.Dll
  1141. iisDebugOut(_T("MySettingsFile_Write_PWS40. Adding CopyFiles supporting Sections."));
  1142. sprintf(szTheStringToWrite, "\r\n[%s]\r\n", g_Migration_Section_Name_CopyFiles);
  1143. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1144. if (!iReturn) {iEverythingIsKool = FALSE;}
  1145. sprintf(szTheStringToWrite, "%s\r\n\r\n", METADATA_DLL_FILENAME);
  1146. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1147. if (!iReturn) {iEverythingIsKool = FALSE;}
  1148. //[DestinationDirs]
  1149. //Section1=11
  1150. sprintf(szTheStringToWrite, "[DestinationDirs]\r\n");
  1151. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1152. if (!iReturn) {iEverythingIsKool = FALSE;}
  1153. sprintf(szTheStringToWrite, "%s=11 ;System on win95, System32 on WinNT\r\n\r\n", g_Migration_Section_Name_CopyFiles);
  1154. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1155. if (!iReturn) {iEverythingIsKool = FALSE;}
  1156. //[SourceDisksNames]
  1157. //1="Setup Files",,,system
  1158. sprintf(szTheStringToWrite, "[SourceDisksNames]\r\n");
  1159. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1160. if (!iReturn) {iEverythingIsKool = FALSE;}
  1161. sprintf(szTheStringToWrite, "1= \"Files copied from win95\\system dir\",,,System\r\n\r\n");
  1162. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1163. if (!iReturn) {iEverythingIsKool = FALSE;}
  1164. //[SourceDisksFiles]
  1165. //Metabase.Dll=1
  1166. sprintf(szTheStringToWrite, "[SourceDisksFiles]\r\n");
  1167. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1168. if (!iReturn) {iEverythingIsKool = FALSE;}
  1169. sprintf(szTheStringToWrite, "%s=1\r\n\r\n", METADATA_DLL_FILENAME);
  1170. iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1171. if (!iReturn) {iEverythingIsKool = FALSE;}
  1172. */
  1173. iReturn = iEverythingIsKool;
  1174. }
  1175. //MySettingsFile_Write_PWS40_Exit:
  1176. iisDebugOut(_T("MySettingsFile_Write_PWS40. End. Return=%d"), iReturn);
  1177. if (hKey){RegCloseKey(hKey);}
  1178. return iReturn;
  1179. }
  1180. int MySettingsFile_Write_PWS10(HANDLE hFile)
  1181. {
  1182. int iReturn = FALSE;
  1183. int iEverythingIsKool = TRUE;
  1184. CHAR szTheStringToWrite[2000];
  1185. DWORD dwBytesWritten;
  1186. char *token = NULL;
  1187. iisDebugOut(_T("MySettingsFile_Write_PWS10. Start."));
  1188. if (hFile)
  1189. {
  1190. strcpy(szTheStringToWrite, "[version]\r\n");
  1191. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1192. if (!iReturn) {iEverythingIsKool = FALSE;}
  1193. strcpy(szTheStringToWrite, "signature=\"$CHICAGO$\"\r\n");
  1194. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1195. if (!iReturn) {iEverythingIsKool = FALSE;}
  1196. strcpy(szTheStringToWrite, "advancedinf=2.0\r\n\r\n");
  1197. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1198. if (!iReturn) {iEverythingIsKool = FALSE;}
  1199. // Create a [DefaultInstall] section which will get run
  1200. strcpy(szTheStringToWrite, "[DefaultInstall]\r\n");
  1201. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1202. if (!iReturn) {iEverythingIsKool = FALSE;}
  1203. sprintf(szTheStringToWrite, "AddReg=%s\r\n\r\n", g_Migration_Section_Name_AddReg);
  1204. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1205. if (!iReturn) {iEverythingIsKool = FALSE;}
  1206. sprintf(szTheStringToWrite, "[%s]\r\n", g_Migration_Section_Name_AddReg);
  1207. iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
  1208. if (!iReturn) {iEverythingIsKool = FALSE;}
  1209. // Now, Get the ";" delimited list of HKLM registry values to read and write to our file.
  1210. char szSemiColonDelimitedList[1024];
  1211. strcpy(szSemiColonDelimitedList,"");
  1212. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_PWS10_HKLM_REG_TO_MIGRATE, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
  1213. {
  1214. iisDebugOut(_T("MySettingsFile_Write_PWS10. Err or LoadString retieval of IDS_PWS10_HKLM_REG_TO_MIGRATE, Defaulting with english registry values to copy over."));
  1215. strcpy(szSemiColonDelimitedList, "Software\\Microsoft\\INetStp;System\\CurrentControlSet\\Services\\InetInfo;System\\CurrentControlSet\\Services\\MsFtpSvc;System\\CurrentControlSet\\Services\\W3Svc");
  1216. }
  1217. //LOOP THRU THE LIST
  1218. token = NULL;
  1219. token = strtok( szSemiColonDelimitedList, g_LoadString_token_delimiters);
  1220. while( token != NULL )
  1221. {
  1222. // we really should remove pre/post trailing spaces
  1223. // Grab this certain value("Software\\Microsoft\\INetStp")
  1224. // and recursively write it to our "settings" file
  1225. RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY_LOCAL_MACHINE,token,hFile);
  1226. // Get next token
  1227. token = strtok( NULL, g_LoadString_token_delimiters);
  1228. }
  1229. // set the return value to
  1230. iReturn = iEverythingIsKool;
  1231. }
  1232. iisDebugOut(_T("MySettingsFile_Write_PWS10. End. Return=%d"), iReturn);
  1233. return iReturn;
  1234. }
  1235. int MyMessageBox(char szMsg[], char szFileName[])
  1236. {
  1237. char szTempErrString[200];
  1238. sprintf(szTempErrString, szMsg, szFileName);
  1239. return MessageBox(NULL, szTempErrString, "PWS Migration Dll Failure", MB_OK);
  1240. }
  1241. // handle the [HKEY_LOCAL_MACHINE\Enum\Network\MSWEBSVR] reg key
  1242. void HandleSpecialRegKey(void)
  1243. {
  1244. int iReturn = FALSE;
  1245. HKEY hKey = NULL;
  1246. if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REG_NETWORK_MSWEBSVR, &hKey))
  1247. {iReturn = TRUE;}
  1248. if (hKey){RegCloseKey(hKey);}
  1249. if (iReturn == TRUE)
  1250. {
  1251. // Write to the Migrate.inf file that we are "Handling" this registry settings.
  1252. iisDebugOut(_T("HandleSpecialRegKey. Write Entry to Migrate.inf file."));
  1253. iReturn = MigInf_AddHandledRegistry(REG_HKLM_NETWORK_MSWEBSVR, NULL);
  1254. if (iReturn != TRUE) {SetupLogError_Wrap(LogSevWarning, "Warning: MigInf_AddHandledRegistry() FAILED.");}
  1255. //
  1256. // Important: Write memory version of migrate.inf to disk
  1257. //
  1258. if (!MigInf_WriteInfToDisk())
  1259. {
  1260. iReturn = GetLastError();
  1261. SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.err=0x%x",iReturn);
  1262. }
  1263. }
  1264. if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REG_PWS_40_UNINSTALL_KEY, &hKey))
  1265. {iReturn = TRUE;}
  1266. if (hKey){RegCloseKey(hKey);}
  1267. if (iReturn == TRUE)
  1268. {
  1269. // Write to the Migrate.inf file that we are "Handling" this registry settings.
  1270. iisDebugOut(_T("HandleSpecialRegKey. Write Entry2 to Migrate.inf file."));
  1271. iReturn = MigInf_AddHandledRegistry(REG_HKLM_PWS_40_UNINSTALL_KEY, NULL);
  1272. if (iReturn != TRUE) {SetupLogError_Wrap(LogSevWarning, "Warning: MigInf_AddHandledRegistry2() FAILED.");}
  1273. //
  1274. // Important: Write memory version of migrate.inf to disk
  1275. //
  1276. if (!MigInf_WriteInfToDisk())
  1277. {
  1278. iReturn = GetLastError();
  1279. SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk2() FAILED.err=0x%x",iReturn);
  1280. }
  1281. }
  1282. }
  1283. void RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile)
  1284. {
  1285. int iReturn = FALSE;
  1286. char szTheFullKey[512];
  1287. char szTheMask[50];
  1288. // use this stuff for the migrate.inf file
  1289. strcpy(szTheMask, "HKLM\\%s");
  1290. if (hRootKeyType == HKEY_LOCAL_MACHINE) {strcpy(szTheMask, "HKLM\\%s");}
  1291. if (hRootKeyType == HKEY_CLASSES_ROOT) {strcpy(szTheMask, "HKCR\\%s");}
  1292. if (hRootKeyType == HKEY_CURRENT_USER) {strcpy(szTheMask, "HKCU\\%s");}
  1293. if (hRootKeyType == HKEY_USERS) {strcpy(szTheMask, "HKU\\%s");}
  1294. sprintf(szTheFullKey, szTheMask, szRootKey);
  1295. iisDebugOut(_T("RecursivelyMoveRegFormatToInfFormat_Wrap1. %s"), szTheFullKey);
  1296. // Call the real recursive function
  1297. iReturn = RecursivelyMoveRegFormatToInfFormat(hRootKeyType, szRootKey, fAppendToFile);
  1298. //
  1299. // Write handled for every setting we are processing. Because this
  1300. // DLL supports only some of the values in the Desktop key, we must
  1301. // be very specific as to which values are actually handled. If
  1302. // your DLL handles all registry values AND subkeys of a registry
  1303. // key, you can specify NULL in the second parameter of
  1304. // MigInf_AddHandledRegistry.
  1305. //
  1306. if (iReturn == TRUE)
  1307. {
  1308. // Write to the Migrate.inf file that we are "Handling" this registry settings.
  1309. iisDebugOut(_T("RecursivelyMoveRegFormatToInfFormat_Wrap1. Write Entry to Migrate.inf file."));
  1310. iReturn = MigInf_AddHandledRegistry(szTheFullKey, NULL);
  1311. if (iReturn != TRUE) {SetupLogError_Wrap(LogSevWarning, "Warning: MigInf_AddHandledRegistry() FAILED.");}
  1312. //
  1313. // Important: Write memory version of migrate.inf to disk
  1314. //
  1315. if (!MigInf_WriteInfToDisk())
  1316. {
  1317. iReturn = GetLastError();
  1318. SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.err=0x%x",iReturn);
  1319. }
  1320. }
  1321. return;
  1322. }
  1323. int ReturnImportantDirs(void)
  1324. {
  1325. int iReturn = FALSE;
  1326. if (g_iPWS40OrBetterInstalled == TRUE)
  1327. {
  1328. // do something
  1329. }
  1330. else if (g_iPWS10Installed == TRUE)
  1331. {
  1332. // do something else
  1333. }
  1334. return iReturn;
  1335. }
  1336. void SetupLogError_Wrap(IN LogSeverity TheSeverityErr, TCHAR *MessageString, ...)
  1337. {
  1338. TCHAR acsString[1000];
  1339. TCHAR acsString2[1000];
  1340. va_list va;
  1341. va_start(va, MessageString);
  1342. _vstprintf(acsString, MessageString, va);
  1343. va_end(va);
  1344. // Append on Our modules information.
  1345. _stprintf(acsString2, _T("SetupLogError: %s"), acsString);
  1346. iisDebugOut(acsString2);
  1347. _stprintf(acsString2, _T("[PWS Migration DLL]:%s%s"), g_MyLogFile.m_szLogPreLineInfo, acsString);
  1348. SetupLogError(acsString2, TheSeverityErr);
  1349. return;
  1350. }
  1351. int SetMetabaseToDoUnEncryptedRead(int iOnFlag)
  1352. {
  1353. int iReturn = FALSE;
  1354. DWORD rc = 0;
  1355. HKEY hKey = NULL;
  1356. DWORD dwResult = 0;
  1357. DWORD DontCare;
  1358. rc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_INETSTP, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, &DontCare);
  1359. if (rc != ERROR_SUCCESS)
  1360. {
  1361. SetLastError(rc);
  1362. goto SetMetabaseToDoUnEncryptedRead_Exit;
  1363. }
  1364. dwResult = 1;
  1365. rc = RegSetValueEx(hKey, METABASEUNSECUREDREAD_VALUENAME, 0, REG_DWORD, (const BYTE *) &dwResult, sizeof dwResult);
  1366. if (rc != ERROR_SUCCESS)
  1367. {
  1368. SetLastError(rc);
  1369. goto SetMetabaseToDoUnEncryptedRead_Exit;
  1370. }
  1371. iReturn = TRUE;
  1372. SetMetabaseToDoUnEncryptedRead_Exit:
  1373. if (hKey){RegCloseKey(hKey);}
  1374. return iReturn;
  1375. }
  1376. void DeleteMetabaseSchemaNode(void)
  1377. {
  1378. CMDKey cmdKey;
  1379. cmdKey.OpenNode(_T("/"));
  1380. if ( (METADATA_HANDLE) cmdKey )
  1381. {
  1382. iisDebugOut(_T("MyUpgradeTasks.DeleteNode /Schema.Start."));
  1383. cmdKey.DeleteNode(_T("Schema"));
  1384. cmdKey.Close();
  1385. iisDebugOut(_T("MyUpgradeTasks.DeleteNode /Schema.End."));
  1386. }
  1387. return;
  1388. }
  1389. BOOL MyDeleteLink(LPTSTR lpszShortcut)
  1390. {
  1391. TCHAR szFile[_MAX_PATH];
  1392. SHFILEOPSTRUCT fos;
  1393. ZeroMemory(szFile, sizeof(szFile));
  1394. _tcscpy(szFile, lpszShortcut);
  1395. iisDebugOut(_T("MyDeleteLink(): %s.\n"), szFile);
  1396. if (CheckIfFileExists(szFile))
  1397. {
  1398. ZeroMemory(&fos, sizeof(fos));
  1399. fos.hwnd = NULL;
  1400. fos.wFunc = FO_DELETE;
  1401. fos.pFrom = szFile;
  1402. fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
  1403. if (SHFileOperation(&fos) != 0)
  1404. {
  1405. iisDebugOut(_T("MyDeleteLink(): SHFileOperation FAILED\n"));
  1406. }
  1407. }
  1408. else
  1409. {
  1410. //iisDebugOutSafeParams((_T("MyDeleteLink(): CheckIfFileExists(%1!s!) = FALSE FAILURE\n"), szFile));
  1411. }
  1412. return TRUE;
  1413. }
  1414. void MyDeleteItem(LPCTSTR szGroupName, LPCTSTR szAppName)
  1415. {
  1416. TCHAR szPath[_MAX_PATH];
  1417. MyGetGroupPath(szGroupName, szPath);
  1418. _tcscat(szPath, _T("\\"));
  1419. _tcscat(szPath, szAppName);
  1420. _tcscat(szPath, _T(".lnk"));
  1421. MyDeleteLink(szPath);
  1422. // try to remove items added by AddURLShortcutItem()
  1423. MyGetGroupPath(szGroupName, szPath);
  1424. _tcscat(szPath, _T("\\"));
  1425. _tcscat(szPath, szAppName);
  1426. _tcscat(szPath, _T(".url"));
  1427. MyDeleteLink(szPath);
  1428. if (MyIsGroupEmpty(szGroupName)) {MyDeleteGroup(szGroupName);}
  1429. }
  1430. void MyGetGroupPath(LPCTSTR szGroupName, LPTSTR szPath)
  1431. {
  1432. int nLen = 0;
  1433. LPITEMIDLIST pidlPrograms;
  1434. if (SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_PROGRAMS, &pidlPrograms) != NOERROR)
  1435. {
  1436. if (SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidlPrograms) != NOERROR)
  1437. {iisDebugOut(_T("MyGetGroupPath() SHGetSpecialFolderLocation FAILED\n"));}
  1438. }
  1439. if (SHGetPathFromIDList(pidlPrograms, szPath) != TRUE)
  1440. {iisDebugOut(_T("MyGetGroupPath() SHGetPathFromIDList FAILED\n"));}
  1441. nLen = _tcslen(szPath);
  1442. if (szGroupName)
  1443. {
  1444. if (szPath[nLen-1] != _T('\\')){_tcscat(szPath, _T("\\"));}
  1445. _tcscat(szPath, szGroupName);
  1446. }
  1447. //iisDebugOut(_T("MyGetGroupPath(%s). Returns %s.\n"), szGroupName, szPath);
  1448. return;
  1449. }
  1450. BOOL MyIsGroupEmpty(LPCTSTR szGroupName)
  1451. {
  1452. TCHAR szPath[MAX_PATH];
  1453. TCHAR szFile[MAX_PATH];
  1454. WIN32_FIND_DATA FindData;
  1455. HANDLE hFind;
  1456. BOOL bFindFile = TRUE;
  1457. BOOL fReturn = TRUE;
  1458. MyGetGroupPath(szGroupName, szPath);
  1459. _tcscpy(szFile, szPath);
  1460. _tcscat(szFile, _T("\\*.*"));
  1461. hFind = FindFirstFile(szFile, &FindData);
  1462. while((INVALID_HANDLE_VALUE != hFind) && bFindFile)
  1463. {
  1464. if(*(FindData.cFileName) != _T('.'))
  1465. {
  1466. fReturn = FALSE;
  1467. break;
  1468. }
  1469. //find the next file
  1470. bFindFile = FindNextFile(hFind, &FindData);
  1471. }
  1472. FindClose(hFind);
  1473. return fReturn;
  1474. }
  1475. BOOL MyDeleteGroup(LPCTSTR szGroupName)
  1476. {
  1477. BOOL fResult;
  1478. TCHAR szPath[MAX_PATH];
  1479. TCHAR szFile[MAX_PATH];
  1480. SHFILEOPSTRUCT fos;
  1481. WIN32_FIND_DATA FindData;
  1482. HANDLE hFind;
  1483. BOOL bFindFile = TRUE;
  1484. MyGetGroupPath(szGroupName, szPath);
  1485. //we can't remove a directory that is not empty, so we need to empty this one
  1486. _tcscpy(szFile, szPath);
  1487. _tcscat(szFile, _T("\\*.*"));
  1488. ZeroMemory(&fos, sizeof(fos));
  1489. fos.hwnd = NULL;
  1490. fos.wFunc = FO_DELETE;
  1491. fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
  1492. hFind = FindFirstFile(szFile, &FindData);
  1493. while((INVALID_HANDLE_VALUE != hFind) && bFindFile)
  1494. {
  1495. if(*(FindData.cFileName) != _T('.'))
  1496. {
  1497. //copy the path and file name to our temp buffer
  1498. memset( (PVOID)szFile, 0, sizeof(szFile));
  1499. _tcscpy(szFile, szPath);
  1500. _tcscat(szFile, _T("\\"));
  1501. _tcscat(szFile, FindData.cFileName);
  1502. //add a second NULL because SHFileOperation is looking for this
  1503. _tcscat(szFile, _T("\0"));
  1504. //delete the file
  1505. fos.pFrom = szFile;
  1506. if (SHFileOperation(&fos) != 0)
  1507. {iisDebugOut(_T("MyDeleteGroup(): SHFileOperation FAILED\n"));}
  1508. }
  1509. //find the next file
  1510. bFindFile = FindNextFile(hFind, &FindData);
  1511. }
  1512. FindClose(hFind);
  1513. fResult = RemoveDirectory(szPath);
  1514. if (fResult) {SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, szPath, 0);}
  1515. return(fResult);
  1516. }
  1517. #define PWS_SHUTDOWN_EVENT "Inet_shutdown"
  1518. BOOL W95ShutdownW3SVC(void)
  1519. {
  1520. HANDLE hEvent;
  1521. hEvent = CreateEvent(NULL, TRUE, FALSE, _T(PWS_SHUTDOWN_EVENT));
  1522. if ( hEvent == NULL )
  1523. {return(TRUE);}
  1524. if ( GetLastError() == ERROR_ALREADY_EXISTS )
  1525. {SetEvent( hEvent );}
  1526. CloseHandle(hEvent);
  1527. return(TRUE);
  1528. }
  1529. typedef void (*pFunctionIISDLL)(CHAR *szSectionName);
  1530. int Call_IIS_DLL_INF_Section(CHAR *szSectionName)
  1531. {
  1532. int iReturn = FALSE;
  1533. HINSTANCE hDll = NULL;
  1534. pFunctionIISDLL pMyFunctionPointer = NULL;
  1535. TCHAR szSystemDir[_MAX_PATH];
  1536. TCHAR szFullPath[_MAX_PATH];
  1537. // get the c:\winnt\system32 dir
  1538. if (0 == GetSystemDirectory(szSystemDir, _MAX_PATH))
  1539. {
  1540. iisDebugOut(_T("Call_IIS_DLL_INF_Section(%s).GetSystemDirectory FAILED."),szSectionName);
  1541. goto Call_IIS_DLL_INF_Section_Exit;
  1542. }
  1543. // Tack on the setup\iis.dll subdir and filename
  1544. sprintf(szFullPath, "%s\\setup\\iis.dll",szSystemDir);
  1545. // Check if the file exists
  1546. if (TRUE != CheckIfFileExists(szFullPath))
  1547. {
  1548. iisDebugOut(_T("Call_IIS_DLL_INF_Section.CheckIfFileExists(%s) FAILED."),szFullPath);
  1549. goto Call_IIS_DLL_INF_Section_Exit;
  1550. }
  1551. // Try to load the module,dll,ocx.
  1552. hDll = LoadLibraryEx(szFullPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
  1553. if (!hDll)
  1554. {
  1555. iisDebugOut(_T("Call_IIS_DLL_INF_Section.LoadLibraryEx(%s) FAILED."),szFullPath);
  1556. goto Call_IIS_DLL_INF_Section_Exit;
  1557. }
  1558. // get the function
  1559. pMyFunctionPointer = (pFunctionIISDLL) GetProcAddress( hDll, "ProcessInfSection");
  1560. if (pMyFunctionPointer)
  1561. {
  1562. // we have the function.. let's call it.
  1563. iisDebugOut(_T("Call_IIS_DLL_INF_Section.Calling function [ProcessInfSection] Now...start"));
  1564. (*pMyFunctionPointer)(szSectionName);
  1565. iisDebugOut(_T("Call_IIS_DLL_INF_Section.Calling function [ProcessInfSection] Now...end"));
  1566. iReturn = TRUE;
  1567. }
  1568. else
  1569. {
  1570. iisDebugOut(_T("Call_IIS_DLL_INF_Section.GetProcAddress(ProcessInfSection) FAILED."));
  1571. }
  1572. Call_IIS_DLL_INF_Section_Exit:
  1573. if (hDll){FreeLibrary(hDll);}
  1574. return iReturn;
  1575. }
  1576. int GetInetSrvDir(CHAR *szOutputThisFullPath)
  1577. {
  1578. int iEverythingIsKool = TRUE;
  1579. TCHAR szMetabaseFullPath[_MAX_PATH];
  1580. // Registry variables
  1581. HKEY hKey = NULL;
  1582. DWORD dwType, cbData=1000,rc=0;
  1583. BYTE bData[1000];
  1584. // CopyFiles information
  1585. // ----------------------------
  1586. // Lookup the inetstp key to get the location of inetsrv directory.
  1587. iisDebugOut(_T("GetInetSrvDir. lookup registry inetstp."));
  1588. rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_INETSTP, &hKey);
  1589. if ( ERROR_SUCCESS != rc)
  1590. {
  1591. SetLastError (rc);
  1592. SetupLogError_Wrap(LogSevError, "Failed to open registry key %s GetLastError()=%x", REG_INETSTP, GetLastError());
  1593. // if the key does not exist, then hey, we won't be able to find
  1594. // the metabase, much less upgrade it!
  1595. // so let's bag out of here!
  1596. iEverythingIsKool = FALSE;
  1597. goto GetInetSrvDir_Exit;
  1598. }
  1599. // try to query the value
  1600. rc = RegQueryValueEx(hKey,REG_INETSTP_INSTALLPATH_STRINGVALUE,NULL,&dwType,bData,&cbData);
  1601. if ( ERROR_SUCCESS != rc)
  1602. {
  1603. SetLastError (rc);
  1604. SetupLogError_Wrap(LogSevError, "Failed to Read Registry key %s Value in Key '%s'. GetLastError()=%x", REG_INETSTP_INSTALLPATH_STRINGVALUE, REG_INETSTP, GetLastError());
  1605. iEverythingIsKool = FALSE;
  1606. goto GetInetSrvDir_Exit;
  1607. }
  1608. // We have the value, copy it to our string
  1609. // Should look something like this "c:\\windows\system\inetsrv"
  1610. _tcsncpy(szMetabaseFullPath, (const char *) bData, _MAX_PATH);
  1611. szMetabaseFullPath[_MAX_PATH - 1] = '\0';
  1612. // we only want the path part, so copy that to the output string
  1613. _tcscpy(szOutputThisFullPath, szMetabaseFullPath);
  1614. iEverythingIsKool = TRUE;
  1615. iisDebugOut(_T("GetInetSrvDir. Check if file exist %s = TRUE"), szMetabaseFullPath);
  1616. GetInetSrvDir_Exit:
  1617. if (hKey){RegCloseKey(hKey);}
  1618. return iEverythingIsKool;
  1619. }
  1620. int MyUpgradeTasks(LPCSTR AnswerFile)
  1621. {
  1622. int iReturn = FALSE;
  1623. HANDLE hFile;
  1624. TCHAR szQuotedPath[_MAX_PATH];
  1625. TCHAR szMyInetsrvDir[_MAX_PATH];
  1626. TCHAR szFullMetadataPath[_MAX_PATH];
  1627. TCHAR szNewFileName[_MAX_PATH];
  1628. int iDoTheSwap = FALSE;
  1629. iisDebugOut(_T("MyUpgradeTasks. Start."));
  1630. // if this is pws 1.0, then hey, we don't need to do anything
  1631. // other than copy over the registry, so just get out of here.
  1632. if (g_iPWS10Installed == TRUE) {goto MyUpgradeTasks_Exit;}
  1633. // if this is pws 4.0 then we
  1634. // need to take the iis 4.0 metabase and do certain things to it:
  1635. // 1. Call DeleteApp
  1636. if (g_iPWS40OrBetterInstalled == TRUE)
  1637. {
  1638. // Facts:
  1639. // 1. win95 doesn't have security, so the encrypted stuff in metabase on win95
  1640. // is not encrypted.
  1641. // 2. NT does have security, so the encrypted stuff in the metabase is read/write
  1642. // as encrypted automatically, within the metabase code.
  1643. //
  1644. // problem:
  1645. // 1. If we are migrating the metabase from pws 4.0 on win95, then there is
  1646. // a bunch of encrypted keys in the metabase which aren't encrypted and
  1647. // we need a way to tell the metabase that it needs to read the data
  1648. // as "not encrypted" data. it's okay to write it out as encrypted, but
  1649. // it's not cool to read the "not encrypted" data as encrypted.
  1650. //
  1651. // Solution:
  1652. // 1. Set the registry stuff:
  1653. // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\INetStp
  1654. // MetabaseUnSecuredRead= (DWORD) 1 or 0
  1655. // 1= Yes, metabase, please read your stuff our of the metabase as unsecured.
  1656. // 2= No, Metabase, read your stuff out of the metabase like you normally do.
  1657. // The noexistance of the key is equal to MetabaseUnSecuredRead=0
  1658. // Create a special key in the registry.
  1659. if (SetMetabaseToDoUnEncryptedRead(TRUE) != TRUE)
  1660. {
  1661. SetupLogError_Wrap(LogSevError, "Unable to set Metabase (MetabaseUnSecuredRead flag) on. PWS 4.0 metabase will not be Migrated. FAILER.");
  1662. goto MyUpgradeTasks_Exit;
  1663. }
  1664. // try to call the AppDeleteRecoverable() function in the metabase.
  1665. // Which will tell the metabase to prepare to disconnect itself from
  1666. // Transaction Server and save all it's data to it's dat file.
  1667. /*
  1668. #ifdef SPECIAL_METABASE_STUFF
  1669. if (TRUE != AppDeleteRecoverable_Wrap("LM/W3SVC"))
  1670. {
  1671. // Set to true anyway, because the user could be re-running this.
  1672. iReturn = TRUE;
  1673. SetupLogError_Wrap(LogSevError, "Call to AppDeleteRecoverable_Wrap() FAILED.");
  1674. goto MyUpgradeTasks_Exit;
  1675. }
  1676. #endif
  1677. */
  1678. // Before changing the metabase.bin file
  1679. // let's save it somewhere.
  1680. // 1. Get the %windir%\system\inetsrv directory where metabase.bin lives.
  1681. // 2. copy that metabase.bin file to "anothername".
  1682. _tcscpy(szMyInetsrvDir, _T(""));
  1683. if (TRUE == GetInetSrvDir(szMyInetsrvDir))
  1684. {
  1685. _tcscpy(szFullMetadataPath, szMyInetsrvDir);
  1686. AddPath(szFullMetadataPath, METABASE_BIN_FILENAME);
  1687. // Check if it exists.
  1688. if (CheckIfFileExists(szFullMetadataPath) == TRUE)
  1689. {iDoTheSwap = TRUE;}
  1690. if (TRUE == iDoTheSwap)
  1691. {
  1692. _tcscpy(szNewFileName, szMyInetsrvDir);
  1693. AddPath(szNewFileName, METABASE_BIN_BEFORE_CHANGE);
  1694. // Delete any that already exists.
  1695. if (CheckIfFileExists(szNewFileName) == TRUE){DeleteFile(szNewFileName);}
  1696. iisDebugOut(_T("Calling WritePrivateProfileString.%s."), AnswerFile);
  1697. sprintf(szQuotedPath, "\"%s\"",szFullMetadataPath);
  1698. if (0 == WritePrivateProfileString(UNATTEND_TXT_PWS_SECTION, UNATTEND_TXT_PWS_METABASE_ORGINAL, szQuotedPath, AnswerFile))
  1699. {
  1700. SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_PWS_METABASE_ORGINAL, AnswerFile, GetLastError());
  1701. }
  1702. // Copy Metadata.bin to anothername
  1703. if (0 == CopyFile(szFullMetadataPath, szNewFileName, FALSE))
  1704. {
  1705. SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. from=s%,to=%s. GetLastError=%x.", szFullMetadataPath, szNewFileName, GetLastError());
  1706. iDoTheSwap = FALSE;
  1707. }
  1708. }
  1709. }
  1710. // 3. change the metabase.bin
  1711. // Delete the "Schema" node
  1712. DeleteMetabaseSchemaNode();
  1713. // 4. stop the web server
  1714. // 5. rename metabase.bin to "asdfghjk.002"
  1715. // 6. rename "asdfghjk.001" to metabase.bin
  1716. // 7. this way if setup is cancelled, then they will still have a win95/98 web server that works!
  1717. if (TRUE == iDoTheSwap)
  1718. {
  1719. // Stop the web server...
  1720. W95ShutdownW3SVC();
  1721. W95ShutdownIISADMIN();
  1722. _tcscpy(szFullMetadataPath, szMyInetsrvDir);
  1723. AddPath(szFullMetadataPath, METABASE_BIN_FILENAME);
  1724. // Check if it exists.
  1725. if (CheckIfFileExists(szFullMetadataPath) == TRUE)
  1726. {
  1727. // rename metadata.bin to somethingelsenew
  1728. _tcscpy(szNewFileName, szMyInetsrvDir);
  1729. AddPath(szNewFileName, METABASE_BIN_AFTER_CHANGE);
  1730. // Delete any that already exists.
  1731. if (CheckIfFileExists(szNewFileName) == TRUE){DeleteFile(szNewFileName);}
  1732. // Copy Metadata.bin to anothername
  1733. if (0 == CopyFile(szFullMetadataPath, szNewFileName, FALSE))
  1734. {
  1735. SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. from=s%,to=%s. GetLastError=%x.", szFullMetadataPath, szNewFileName, GetLastError());
  1736. }
  1737. else
  1738. {
  1739. iisDebugOut(_T("Calling WritePrivateProfileString.%s."), AnswerFile);
  1740. sprintf(szQuotedPath, "\"%s\"",szNewFileName);
  1741. if (0 == WritePrivateProfileString(UNATTEND_TXT_PWS_SECTION, UNATTEND_TXT_PWS_METABASE_NEW, szQuotedPath, AnswerFile))
  1742. {
  1743. SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_PWS_METABASE_NEW, AnswerFile, GetLastError());
  1744. }
  1745. // rename old backedupname to metadata.bin
  1746. _tcscpy(szNewFileName, szMyInetsrvDir);
  1747. AddPath(szNewFileName, METABASE_BIN_BEFORE_CHANGE);
  1748. // Delete any that already exists.
  1749. if (CheckIfFileExists(szFullMetadataPath) == TRUE){DeleteFile(szFullMetadataPath);}
  1750. // Copy anothername to Metadata.bin
  1751. if (0 == CopyFile(szNewFileName, szFullMetadataPath, FALSE))
  1752. {
  1753. SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. from=s%,to=%s. GetLastError=%x.", szNewFileName, szFullMetadataPath, GetLastError());
  1754. }
  1755. else
  1756. {
  1757. // Delete the anothername old file
  1758. DeleteFile(szNewFileName);
  1759. }
  1760. }
  1761. }
  1762. }
  1763. // we've gotten this far, things must be good.
  1764. iReturn = TRUE;
  1765. }
  1766. MyUpgradeTasks_Exit:
  1767. iisDebugOut(_T("MyUpgradeTasks. End. Return = %d"), iReturn);
  1768. return iReturn;
  1769. }
  1770. #define IISADMIN_SHUTDOWN_EVENT "Internet_infosvc_as_exe"
  1771. BOOL W95ShutdownIISADMIN(void)
  1772. {
  1773. DWORD i;
  1774. HANDLE hEvent;
  1775. hEvent = CreateEvent(NULL, TRUE, FALSE, _T(IISADMIN_SHUTDOWN_EVENT));
  1776. if ( hEvent == NULL ) {
  1777. return(TRUE);
  1778. }
  1779. if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
  1780. SetEvent( hEvent );
  1781. }
  1782. CloseHandle(hEvent);
  1783. for (i=0; i < 20; i++)
  1784. {
  1785. hEvent = CreateEvent(NULL, TRUE, FALSE, _T(IISADMIN_SHUTDOWN_EVENT));
  1786. if ( hEvent != NULL ) {
  1787. DWORD err = GetLastError();
  1788. CloseHandle(hEvent);
  1789. if ( err == ERROR_ALREADY_EXISTS ) {
  1790. Sleep(500);
  1791. continue;
  1792. }
  1793. }
  1794. break;
  1795. }
  1796. return(TRUE);
  1797. }
  1798. int CheckFrontPageINI(void)
  1799. {
  1800. int iReturn = FALSE;
  1801. char szWindowsDir[_MAX_PATH];
  1802. char szFullPathedFilename[_MAX_PATH];
  1803. char szFrontPageINIFilename[] = "frontpg.ini\0";
  1804. strcpy(szWindowsDir, "");
  1805. if (0 == GetWindowsDirectory(szWindowsDir, sizeof(szWindowsDir)))
  1806. {
  1807. // Error so write it out
  1808. SetupLogError_Wrap(LogSevError, "Call to GetWindowsDirectory() Failed. GetLastError=%x.", GetLastError());
  1809. goto CheckFrontPageINI_Exit;
  1810. }
  1811. // copy our settings file to this directory.
  1812. strcpy(szFullPathedFilename, szWindowsDir);
  1813. AddPath(szFullPathedFilename, szFrontPageINIFilename);
  1814. iReturn = CheckIfFileExists(szFullPathedFilename);
  1815. CheckFrontPageINI_Exit:
  1816. return iReturn;
  1817. }
  1818. void MoveFrontPageINI(void)
  1819. {
  1820. // since the frontpage guys didn't write a migrate.dll
  1821. // we'll have to handle one file for them during the win95/98 upgrade.
  1822. //
  1823. // if we find the c:\windows\frontpg.ini file
  1824. // then we'll have to rename it to frontpage.txt
  1825. // then during they're install they will rename it back to frontpg.ini
  1826. int iSomethingToDo = FALSE;
  1827. int iFileExists = FALSE;
  1828. int iFileExists_new = FALSE;
  1829. char szWindowsDir[_MAX_PATH];
  1830. char szFullPathedFilename[_MAX_PATH];
  1831. char szFullPathedFilename_new[_MAX_PATH];
  1832. char szFrontPageINIFilename[] = "frontpg.ini\0";
  1833. char szFrontPageINIFilename_new[] = "frontpg.txt\0";
  1834. strcpy(szWindowsDir, "");
  1835. if (0 == GetWindowsDirectory(szWindowsDir, sizeof(szWindowsDir)))
  1836. {
  1837. // Error so write it out
  1838. SetupLogError_Wrap(LogSevError, "Call to GetWindowsDirectory() Failed. GetLastError=%x.", GetLastError());
  1839. goto MoveFrontPageINI_Exit;
  1840. }
  1841. // copy our settings file to this directory.
  1842. strcpy(szFullPathedFilename, szWindowsDir);
  1843. AddPath(szFullPathedFilename, szFrontPageINIFilename);
  1844. iFileExists = CheckIfFileExists(szFullPathedFilename);
  1845. strcpy(szFullPathedFilename_new, szWindowsDir);
  1846. AddPath(szFullPathedFilename_new, szFrontPageINIFilename_new);
  1847. iFileExists_new = CheckIfFileExists(szFullPathedFilename_new);
  1848. if (FALSE == iFileExists && FALSE == iFileExists_new)
  1849. {
  1850. // Neither files exists, we don't have to do jack
  1851. goto MoveFrontPageINI_Exit;
  1852. }
  1853. if (TRUE == iFileExists)
  1854. {
  1855. if (TRUE == iFileExists_new)
  1856. {DeleteFile(szFullPathedFilename_new);}
  1857. if (0 == CopyFile(szFullPathedFilename, szFullPathedFilename_new, FALSE))
  1858. {
  1859. SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. GetLastError=%x.", GetLastError());
  1860. goto MoveFrontPageINI_Exit;
  1861. }
  1862. else
  1863. {
  1864. iisDebugOut(_T("MoveFrontPageINI. %s renamed to %s"),szFullPathedFilename,szFrontPageINIFilename_new);
  1865. // don't delete the old .ini file since the user could actually cancel the upgrade.
  1866. //DeleteFile(szFullPathedFilename);
  1867. iSomethingToDo = TRUE;
  1868. }
  1869. }
  1870. else
  1871. {
  1872. // if we're here then that means that
  1873. // file1 doesn't exists and file2 does exist.
  1874. // that means that we probably already copied file1 to file2 and deleted file1.
  1875. iSomethingToDo = TRUE;
  1876. }
  1877. if (iSomethingToDo)
  1878. {
  1879. // Tell the upgrade module that we are going to 'handle' this newly created file.
  1880. // We really don't care if this get's added to the file or not,
  1881. // so let's not check the return code.
  1882. MigInf_AddHandledFile(szFullPathedFilename_new);
  1883. // Important: Write memory version of migrate.inf to disk
  1884. if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");}
  1885. }
  1886. else
  1887. {
  1888. iisDebugOut(_T("MoveFrontPageINI. %s not exist. no action."),szFullPathedFilename);
  1889. }
  1890. MoveFrontPageINI_Exit:
  1891. return;
  1892. }
  1893. HRESULT GetLNKProgramRunInfo(LPCTSTR lpszLink, LPTSTR lpszProgram)
  1894. {
  1895. HRESULT hres;
  1896. int iDoUninit = FALSE;
  1897. IShellLink* pShellLink = NULL;
  1898. WIN32_FIND_DATA wfd;
  1899. if (SUCCEEDED(CoInitialize(NULL)))
  1900. {iDoUninit = TRUE;}
  1901. hres = CoCreateInstance( CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&pShellLink);
  1902. if (SUCCEEDED(hres))
  1903. {
  1904. IPersistFile* pPersistFile = NULL;
  1905. hres = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&pPersistFile);
  1906. if (SUCCEEDED(hres))
  1907. {
  1908. WCHAR wsz[_MAX_PATH];
  1909. // Ensure that the string is WCHAR.
  1910. #if defined(UNICODE) || defined(_UNICODE)
  1911. _tcscpy(wsz, lpszLink);
  1912. #else
  1913. MultiByteToWideChar( CP_ACP, 0, lpszLink, -1, wsz, _MAX_PATH);
  1914. #endif
  1915. hres = pPersistFile->Load(wsz, STGM_READ);
  1916. if (SUCCEEDED(hres))
  1917. {
  1918. hres = pShellLink->Resolve(NULL, SLR_ANY_MATCH | SLR_NO_UI);
  1919. if (SUCCEEDED(hres))
  1920. {
  1921. pShellLink->GetPath(lpszProgram, _MAX_PATH, (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH);
  1922. }
  1923. }
  1924. if (pPersistFile)
  1925. {pPersistFile->Release();pPersistFile = NULL;}
  1926. }
  1927. if (pShellLink)
  1928. {pShellLink->Release();pShellLink = NULL;}
  1929. }
  1930. if (TRUE == iDoUninit)
  1931. {CoUninitialize();}
  1932. return hres;
  1933. }
  1934. int LNKSearchAndReturn(LPTSTR szDirToLookThru, LPTSTR szExeNameWithoutPath, LPTSTR szFileNameReturned)
  1935. {
  1936. int iReturn = FALSE;
  1937. WIN32_FIND_DATA FindFileData;
  1938. HANDLE hFile = INVALID_HANDLE_VALUE;
  1939. TCHAR szFilePath[_MAX_PATH];
  1940. TCHAR szFilename_ext_only[_MAX_EXT];
  1941. _tcscpy(szFileNameReturned, _T(""));
  1942. _tcscpy(szFilePath, szDirToLookThru);
  1943. AddPath(szFilePath, _T("*.lnk"));
  1944. hFile = FindFirstFile(szFilePath, &FindFileData);
  1945. if (hFile != INVALID_HANDLE_VALUE)
  1946. {
  1947. do {
  1948. if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 && _tcsicmp(FindFileData.cFileName, _T("..")) != 0 )
  1949. {
  1950. if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  1951. {
  1952. // this is a directory, so let's skip it
  1953. }
  1954. else
  1955. {
  1956. // check if this file is a .lnk file
  1957. // if it is then let's open it and
  1958. // see if it points to our .exe we're looking for...
  1959. // get only the filename's extention
  1960. _tsplitpath( FindFileData.cFileName, NULL, NULL, NULL, szFilename_ext_only);
  1961. // check for .lnk
  1962. if (0 == _tcsicmp(szFilename_ext_only, _T(".lnk")))
  1963. {
  1964. TCHAR szFilename_only[_MAX_FNAME];
  1965. TCHAR szFullPathAndFilename[_MAX_PATH];
  1966. TCHAR szTemporaryString[_MAX_PATH];
  1967. // this is a .lnk,
  1968. // open it and check the .exe..
  1969. _tcscpy(szFullPathAndFilename,szDirToLookThru);
  1970. AddPath(szFullPathAndFilename,FindFileData.cFileName);
  1971. _tcscpy(szTemporaryString,_T(""));
  1972. if (SUCCEEDED(GetLNKProgramRunInfo(szFullPathAndFilename, szTemporaryString)))
  1973. {
  1974. _tsplitpath( szTemporaryString, NULL, NULL, szFilename_only, szFilename_ext_only);
  1975. _tcscpy(szTemporaryString, szFilename_only);
  1976. _tcscat(szTemporaryString, szFilename_ext_only);
  1977. // check if it matches our .exe name.
  1978. if (0 == _tcsicmp(szTemporaryString,szExeNameWithoutPath))
  1979. {
  1980. _tcscpy(szFileNameReturned,FindFileData.cFileName);
  1981. iReturn = TRUE;
  1982. FindClose(hFile);
  1983. break;
  1984. }
  1985. }
  1986. }
  1987. }
  1988. }
  1989. // get the next file
  1990. if ( !FindNextFile(hFile, &FindFileData) )
  1991. {
  1992. FindClose(hFile);
  1993. break;
  1994. }
  1995. } while (TRUE);
  1996. }
  1997. return iReturn;
  1998. }
  1999. int MyGetSendToPath(LPTSTR szPath)
  2000. {
  2001. LPITEMIDLIST pidlSendTo;
  2002. HRESULT hRes = NOERROR;
  2003. int iTemp;
  2004. int iReturn = FALSE;
  2005. hRes = SHGetSpecialFolderLocation(NULL, CSIDL_SENDTO, &pidlSendTo);
  2006. if (hRes != NOERROR)
  2007. {
  2008. iReturn = FALSE;
  2009. }
  2010. iTemp = SHGetPathFromIDList(pidlSendTo, szPath);
  2011. if (iTemp != TRUE)
  2012. {
  2013. iReturn = FALSE;
  2014. goto MyGetSendToPath_Exit;
  2015. }
  2016. iReturn = TRUE;
  2017. MyGetSendToPath_Exit:
  2018. return iReturn;
  2019. }
  2020. int MyGetDesktopPath(LPTSTR szPath)
  2021. {
  2022. LPITEMIDLIST pidlSendTo;
  2023. HRESULT hRes = NOERROR;
  2024. int iTemp;
  2025. int iReturn = FALSE;
  2026. hRes = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &pidlSendTo);
  2027. if (hRes != NOERROR)
  2028. {
  2029. iReturn = FALSE;
  2030. }
  2031. iTemp = SHGetPathFromIDList(pidlSendTo, szPath);
  2032. if (iTemp != TRUE)
  2033. {
  2034. iReturn = FALSE;
  2035. goto MyGetDesktopPath_Exit;
  2036. }
  2037. iReturn = TRUE;
  2038. MyGetDesktopPath_Exit:
  2039. return iReturn;
  2040. }
  2041. void MyDeleteSendToItem(LPCTSTR szAppName)
  2042. {
  2043. TCHAR szPath[_MAX_PATH];
  2044. TCHAR szPath2[_MAX_PATH];
  2045. MyGetSendToPath(szPath);
  2046. _tcscpy(szPath2, szAppName);
  2047. //_tcscat(szPath2, _T(".lnk")); // already in the resource, so let's not tack it on again.
  2048. MyDeleteLinkWildcard(szPath, szPath2);
  2049. }
  2050. BOOL IsFileNameInDelimitedList(LPTSTR szCommaDelimList,LPTSTR szExeNameWithoutPath)
  2051. {
  2052. BOOL bReturn = FALSE;
  2053. char *token = NULL;
  2054. TCHAR szCopyOfDataBecauseStrTokIsLame[_MAX_PATH];
  2055. _tcscpy(szCopyOfDataBecauseStrTokIsLame,szCommaDelimList);
  2056. // breakup the szCommaDelimList into strings and see if it contains the szExeNameWithoutPath string
  2057. token = strtok(szCopyOfDataBecauseStrTokIsLame, g_LoadString_token_delimiters);
  2058. while(token != NULL)
  2059. {
  2060. // check if it matches our .exe name.
  2061. if (0 == _tcsicmp(token,szExeNameWithoutPath))
  2062. {
  2063. return TRUE;
  2064. }
  2065. // Get next token
  2066. token = strtok(NULL, g_LoadString_token_delimiters);
  2067. }
  2068. return FALSE;
  2069. }
  2070. int LNKSearchAndDestroyRecursive(LPTSTR szDirToLookThru, LPTSTR szSemiColonDelmitedListOfExeNames, BOOL bDeleteItsDirToo, LPCSTR AnswerFile)
  2071. {
  2072. int iReturn = FALSE;
  2073. WIN32_FIND_DATA FindFileData;
  2074. HANDLE hFile = INVALID_HANDLE_VALUE;
  2075. TCHAR szFilePath[_MAX_PATH];
  2076. TCHAR szFilename_ext_only[_MAX_EXT];
  2077. DWORD retCode = GetFileAttributes(szDirToLookThru);
  2078. if (retCode == 0xFFFFFFFF || !(retCode & FILE_ATTRIBUTE_DIRECTORY))
  2079. {
  2080. return FALSE;
  2081. }
  2082. _tcscpy(szFilePath, szDirToLookThru);
  2083. AddPath(szFilePath, _T("*.*"));
  2084. hFile = FindFirstFile(szFilePath, &FindFileData);
  2085. if (hFile != INVALID_HANDLE_VALUE)
  2086. {
  2087. do {
  2088. if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 && _tcsicmp(FindFileData.cFileName, _T("..")) != 0 )
  2089. {
  2090. if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  2091. {
  2092. TCHAR szFullNewDirToLookInto[_MAX_EXT];
  2093. _tcscpy(szFullNewDirToLookInto, szDirToLookThru);
  2094. AddPath(szFullNewDirToLookInto,FindFileData.cFileName);
  2095. // this is a directory, so let's go into this
  2096. // directory recursively
  2097. LNKSearchAndDestroyRecursive(szFullNewDirToLookInto,szSemiColonDelmitedListOfExeNames,bDeleteItsDirToo,AnswerFile);
  2098. }
  2099. else
  2100. {
  2101. // check if this file is a .lnk file
  2102. // if it is then let's open it and
  2103. // see if it points to our .exe we're looking for...
  2104. // get only the filename's extention
  2105. _tsplitpath( FindFileData.cFileName, NULL, NULL, NULL, szFilename_ext_only);
  2106. // check for .lnk
  2107. if (0 == _tcsicmp(szFilename_ext_only, _T(".lnk")))
  2108. {
  2109. TCHAR szFilename_only[_MAX_FNAME];
  2110. TCHAR szFullPathAndFilename[_MAX_PATH];
  2111. TCHAR szTemporaryString[_MAX_PATH];
  2112. // this is a .lnk,
  2113. // open it and check the .exe..
  2114. _tcscpy(szFullPathAndFilename,szDirToLookThru);
  2115. AddPath(szFullPathAndFilename,FindFileData.cFileName);
  2116. _tcscpy(szTemporaryString,_T(""));
  2117. if (SUCCEEDED(GetLNKProgramRunInfo(szFullPathAndFilename, szTemporaryString)))
  2118. {
  2119. _tsplitpath( szTemporaryString, NULL, NULL, szFilename_only, szFilename_ext_only);
  2120. _tcscpy(szTemporaryString, szFilename_only);
  2121. _tcscat(szTemporaryString, szFilename_ext_only);
  2122. //_tprintf(TEXT("open:%s,%s\n"),szFullPathAndFilename,szTemporaryString);
  2123. // see if it is on our list of comma delimited names...
  2124. if (TRUE == IsFileNameInDelimitedList(szSemiColonDelmitedListOfExeNames,szTemporaryString))
  2125. {
  2126. // DELETE the file that references this .exe
  2127. MigInf_AddMovedFile(szFullPathAndFilename, "");
  2128. AnswerFile_AppendDeletion(szFullPathAndFilename,AnswerFile);
  2129. if (bDeleteItsDirToo)
  2130. {
  2131. // Get it's dirname and delete that too...
  2132. MigInf_AddMovedDirectory(szDirToLookThru, "");
  2133. AnswerFile_AppendDeletion(szDirToLookThru,AnswerFile);
  2134. }
  2135. iReturn = TRUE;
  2136. }
  2137. }
  2138. }
  2139. }
  2140. }
  2141. // get the next file
  2142. if ( !FindNextFile(hFile, &FindFileData) )
  2143. {
  2144. FindClose(hFile);
  2145. break;
  2146. }
  2147. } while (TRUE);
  2148. }
  2149. return iReturn;
  2150. }
  2151. // We need to tell migration setup that we are going to handle certain files...
  2152. // particularly the c:\windows\SendTo\Personal Web Server.lnk file
  2153. // since it doesn't seem to be accessible during win2000/20001 guimode setup
  2154. void HandleSendToItems(LPCSTR AnswerFile)
  2155. {
  2156. char szPath[_MAX_PATH];
  2157. char szSemiColonDelimitedList[255];
  2158. // Now, Get the ";" delimited list of things to act upon
  2159. strcpy(szSemiColonDelimitedList,"");
  2160. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_DEL_LNK_TO_THESE_EXE_FILENAMES, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
  2161. {
  2162. iisDebugOut(_T("LoopThruStartMenuDeletions.Err LoadString IDS_DEL_LNK_TO_THESE_EXE_FILENAMES\n"));
  2163. return;
  2164. }
  2165. if (TRUE == MyGetSendToPath(szPath))
  2166. {
  2167. LNKSearchAndDestroyRecursive(szPath,szSemiColonDelimitedList,FALSE,AnswerFile);
  2168. }
  2169. return;
  2170. }
  2171. void HandleDesktopItems(LPCSTR AnswerFile)
  2172. {
  2173. char szPath[_MAX_PATH];
  2174. char szSemiColonDelimitedList[255];
  2175. // Now, Get the ";" delimited list of things to act upon
  2176. strcpy(szSemiColonDelimitedList,"");
  2177. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_DEL_LNK_TO_THESE_EXE_FILENAMES, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
  2178. {
  2179. iisDebugOut(_T("LoopThruStartMenuDeletions.Err LoadString IDS_DEL_LNK_TO_THESE_EXE_FILENAMES\n"));
  2180. return;
  2181. }
  2182. if (TRUE == MyGetDesktopPath(szPath))
  2183. {
  2184. LNKSearchAndDestroyRecursive(szPath,szSemiColonDelimitedList,FALSE,AnswerFile);
  2185. }
  2186. return;
  2187. }
  2188. void HandleStartMenuItems(LPCSTR AnswerFile)
  2189. {
  2190. TCHAR szPath[_MAX_PATH];
  2191. char szSemiColonDelimitedList[255];
  2192. // Now, Get the ";" delimited list of things to act upon
  2193. strcpy(szSemiColonDelimitedList,"");
  2194. if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_DEL_LNK_TO_THESE_EXE_FILENAMES, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
  2195. {
  2196. iisDebugOut(_T("LoopThruStartMenuDeletions.Err LoadString IDS_DEL_LNK_TO_THESE_EXE_FILENAMES\n"));
  2197. return;
  2198. }
  2199. MyGetGroupPath(_T(""), szPath);
  2200. // search thru all the start menu items looking for
  2201. // anything that links to our know programs...
  2202. LNKSearchAndDestroyRecursive(szPath,szSemiColonDelimitedList,TRUE,AnswerFile);
  2203. return;
  2204. }