Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
12 KiB

  1. /****************************************************************************\
  2. SAVEAS.C / OPK Wizard (OPKWIZ.EXE)
  3. Microsoft Confidential
  4. Copyright (c) Microsoft Corporation 1998
  5. All rights reserved
  6. Source file for the OPK Wizard that contains the external and internal
  7. functions used by the "saveas / save" wizard page.
  8. 09/2000 - Stephen Lodwick (STELO)
  9. Ported OPK Wizard to Whistler
  10. \****************************************************************************/
  11. //
  12. // Include File(s):
  13. //
  14. #include "pch.h"
  15. #include "wizard.h"
  16. #include "resource.h"
  17. #include "appinst.h"
  18. //
  19. // Internal Define(s):
  20. //
  21. #define MAX_CONFIG_NAME 32
  22. #define DIR_SBSI _T("sbsi")
  23. #define DIR_SBSI_SETUP _T("setup")
  24. #define FILE_SBSI_SETUP _T("setup.exe")
  25. #define CMD_SBSI_SETUP _T("-SMS -S -f1\"%s\\silent.iss\"")
  26. //
  27. // Internal Function Prototype(s):
  28. //
  29. static BOOL OnInit(HWND, HWND, LPARAM);
  30. static BOOL OnSave(HWND);
  31. static BOOL AddSbsiInstall(LPTSTR lpszShare);
  32. //
  33. // External Function(s):
  34. //
  35. LRESULT CALLBACK SaveAsDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  36. {
  37. switch (uMsg)
  38. {
  39. HANDLE_MSG(hwnd, WM_INITDIALOG, OnInit);
  40. case WM_COMMAND:
  41. switch ( LOWORD(wParam) )
  42. {
  43. case IDOK:
  44. if ( OnSave(hwnd))
  45. EndDialog(hwnd, TRUE);
  46. break;
  47. case IDCANCEL:
  48. EndDialog(hwnd, FALSE);
  49. break;
  50. }
  51. return FALSE;
  52. default:
  53. return FALSE;
  54. }
  55. return TRUE;
  56. }
  57. //
  58. // Internal Function(s):
  59. //
  60. static BOOL OnInit(HWND hwnd, HWND hwndFocus, LPARAM lParam)
  61. {
  62. // Set the limit
  63. //
  64. SendDlgItemMessage(hwnd, IDC_NAME_EDIT, EM_LIMITTEXT, MAX_CONFIG_NAME, 0);
  65. // Set the default config name.
  66. //
  67. SetWindowText(GetDlgItem(hwnd, IDC_NAME_EDIT), g_App.szConfigName);
  68. // Set the focus to the edit dialog
  69. //
  70. SetFocus(GetDlgItem(hwnd, IDC_NAME_EDIT));
  71. // Auto save if the auto run flag is set.
  72. //
  73. if ( GET_FLAG(OPK_AUTORUN) )
  74. PostMessage(GetDlgItem(hwnd, IDOK), BM_CLICK, 0, 0L);
  75. // Always return false to WM_INITDIALOG.
  76. //
  77. return FALSE;
  78. }
  79. static BOOL OnSave(HWND hwnd)
  80. {
  81. INT nStrLen;
  82. TCHAR szConfigDir[MAX_PATH],
  83. szLocalTempDir[MAX_PATH],
  84. szSharePath[MAX_PATH],
  85. szUsername[256],
  86. szPassword[256],
  87. szFullConfigName[MAX_PATH];
  88. LPTSTR lpFullConfigName;
  89. LPTSTR lpConfigName;
  90. BOOL bSameConfig = FALSE;
  91. DWORD dwSize;
  92. HRESULT hrCat;
  93. // Check to see if they want to use an existing config set.
  94. //
  95. // Copy the configuration set directory name into the config directory buffer,
  96. // makeing sure there is a trailing backslash and that we have a pointer
  97. // to the end of the path.
  98. //
  99. lstrcpyn(szConfigDir, g_App.szConfigSetsDir,AS(szConfigDir));
  100. AddPathN(szConfigDir, NULLSTR,AS(szConfigDir));
  101. lpConfigName = szConfigDir + (nStrLen = lstrlen(szConfigDir));
  102. // Now grab the text from the control.
  103. //
  104. GetWindowText(GetDlgItem(hwnd, IDC_NAME_EDIT), lpConfigName, STRSIZE(szConfigDir) - nStrLen );
  105. // Validate the config name.
  106. //
  107. if ( *lpConfigName == NULLCHR )
  108. {
  109. MsgBox(hwnd, IDS_NOCONFIG, IDS_APPNAME, MB_ERRORBOX);
  110. SetFocus(GetDlgItem(hwnd, IDC_NAME_EDIT));
  111. return FALSE;
  112. }
  113. // get the full pathname, this will expand . or ..
  114. // if the entered name doesn't match the full name, we will consider this invalid and make user
  115. // either enter a valid filename or cancel
  116. dwSize=GetFullPathName(lpConfigName,AS(szFullConfigName),szFullConfigName,&lpFullConfigName);
  117. if (!dwSize ||
  118. (dwSize > AS(szFullConfigName)+1) ||
  119. lstrcmpi(lpFullConfigName, lpConfigName))
  120. {
  121. MsgBox(hwnd, IDS_CANNOTSAVE, IDS_APPNAME, MB_OK | MB_ICONERROR, lpConfigName);
  122. SetFocus(GetDlgItem(hwnd, IDC_NAME_EDIT));
  123. return FALSE;
  124. }
  125. // We need to make sure no ini files are cached and everything
  126. // is flushed to disk before we move the directory.
  127. //
  128. WritePrivateProfileString(NULL, NULL, NULL, g_App.szOpkWizIniFile);
  129. if (!lstrcmpi(g_App.szConfigName,lpConfigName))
  130. bSameConfig = TRUE;
  131. // Check to see if the directory exists.
  132. //
  133. if ( DirectoryExists(szConfigDir) )
  134. {
  135. // Check to see if we are updating an existing config or or ask the user
  136. // if they don't mind blowing away the existing directory.
  137. //
  138. if ( bSameConfig || MsgBox(hwnd, IDS_DIREXISTS, IDS_APPNAME, MB_YESNO | MB_ICONQUESTION, lpConfigName) == IDYES )
  139. {
  140. // Alright, remove the existing directory.
  141. //
  142. DeletePath(szConfigDir);
  143. }
  144. else
  145. {
  146. SetFocus(GetDlgItem(hwnd, IDC_NAME_EDIT));
  147. return FALSE;
  148. }
  149. }
  150. // Write out the config set name to the ini file
  151. //
  152. WritePrivateProfileString(INI_SEC_CONFIGSET, INI_SEC_CONFIG, lpConfigName, g_App.szOpkWizIniFile);
  153. // Need to also write the config set name to the winbom for WinPE.
  154. //
  155. WritePrivateProfileString(INI_SEC_WINPE, INI_KEY_WINPE_CFGSET, lpConfigName, g_App.szWinBomIniFile);
  156. // The password needs to have quotes around it.
  157. //
  158. lstrcpyn(szPassword, _T("\""),AS(szPassword));
  159. // Need to figure out what the share info is for the OPK stuff so we can write it out to
  160. // the winbom for WinPE.
  161. //
  162. if ( !GetShareSettings(szSharePath, AS(szSharePath), szUsername, AS(szUsername), szPassword + 1, AS(szPassword) - 1) )
  163. {
  164. if ( ( MsgBox(hwnd, IDS_ASK_SHARENOW, IDS_APPNAME, MB_OKCANCEL | MB_ICONWARNING | MB_APPLMODAL) == IDOK ) &&
  165. ( DistributionShareDialog(hwnd) ) )
  166. {
  167. GetShareSettings(szSharePath, AS(szSharePath), szUsername, AS(szUsername), szPassword + 1, AS(szPassword) - 1);
  168. }
  169. else
  170. MsgBox(hwnd, IDS_ERR_NOSHAREINFO, IDS_APPNAME, MB_ICONERROR);
  171. }
  172. // If there is a password, add the trailing quote.
  173. //
  174. if ( szPassword[1] )
  175. hrCat=StringCchCat(szPassword, AS(szPassword), _T("\""));
  176. else
  177. szPassword[0] = NULLCHR;
  178. // Now write out the settings.
  179. //
  180. // NTRAID#NTBUG9-531482-2002/02/27-stelo,swamip - Password stored in plain text
  181. WritePrivateProfileString(INI_SEC_WINPE, INI_KEY_WINPE_SRCROOT, szSharePath, g_App.szWinBomIniFile);
  182. WritePrivateProfileString(INI_SEC_WINPE, INI_KEY_WINPE_USERNAME, szUsername, g_App.szWinBomIniFile);
  183. WritePrivateProfileString(INI_SEC_WINPE, INI_KEY_WINPE_PASSWORD, szPassword, g_App.szWinBomIniFile);
  184. // If the user didn't specify custom credentials for the app preinstall stuff,
  185. // also write this stuff out to the factory section.
  186. //
  187. if ( GetPrivateProfileInt(INI_SEC_GENERAL, INI_KEY_APPCREDENTIALS, 0, g_App.szOpkWizIniFile) == 0 )
  188. {
  189. WritePrivateProfileString(WBOM_FACTORY_SECTION, INI_VAL_WBOM_USERNAME, szUsername, g_App.szWinBomIniFile);
  190. WritePrivateProfileString(WBOM_FACTORY_SECTION, INI_VAL_WBOM_PASSWORD, szPassword, g_App.szWinBomIniFile);
  191. }
  192. // Once we have the distribution share settings finished, we need
  193. // to make sure they have a runonce entry to install the SBSI stuff.
  194. //
  195. AddSbsiInstall(szSharePath);
  196. // Trim any backslashes off the directory names so we don't fail the MoveFile
  197. //
  198. lstrcpyn(szLocalTempDir, g_App.szTempDir,AS(szLocalTempDir));
  199. StrRTrm(szConfigDir, CHR_BACKSLASH);
  200. StrRTrm(szLocalTempDir, CHR_BACKSLASH);
  201. // Make sure the current directory is somewhere that won't cause us problems.
  202. // This is to fix WinXP bug 324896.
  203. //
  204. SetCurrentDirectory(g_App.szOpkDir);
  205. // Now try to move the temp directory to the new config directory.
  206. //
  207. if ( !MoveFile(szLocalTempDir, szConfigDir) )
  208. {
  209. // We already tried to remove the existing directory, so we must
  210. // be failing for some other reason.
  211. //
  212. #ifndef DBG
  213. MsgBox(hwnd, IDS_CANNOTSAVE, IDS_APPNAME, MB_OK | MB_ICONERROR, szConfigDir);
  214. #else // DBG
  215. DBGOUT(NULL, _T("OPKWIZ: MoveFile('%s', '%s') failed. GLE=%d\n"), szLocalTempDir, szConfigDir, GetLastError());
  216. DBGMSGBOX(hwnd, _T("Cannot save the config set.\n\nMoveFile('%s', '%s') failed. GLE=%d"), _T("OPKWIZ Debug Message"), MB_ERRORBOX, szLocalTempDir, szConfigDir, GetLastError());
  217. #endif // DBG
  218. return FALSE;
  219. }
  220. // Now that we have saved the config set, update the global data with the right paths.
  221. //
  222. lstrcpyn(g_App.szTempDir, szConfigDir,AS(g_App.szTempDir));
  223. SetConfigPath(g_App.szTempDir);
  224. lstrcpyn(g_App.szConfigName, lpConfigName,AS(g_App.szConfigName));
  225. // The last thing to do before we return is to write the ini setting to say this config set is finished.
  226. //
  227. WritePrivateProfileString(INI_SEC_CONFIGSET, INI_KEY_FINISHED, STR_ONE, g_App.szOpkWizIniFile);
  228. // Now that it is saved, check if they want to make a winpe floppy.
  229. //
  230. if ( IsDlgButtonChecked(hwnd, IDC_SAVEAS_WINPEFLOPPY) == BST_CHECKED )
  231. MakeWinpeFloppy(hwnd, g_App.szConfigName, g_App.szWinBomIniFile);
  232. return TRUE;
  233. }
  234. static BOOL AddSbsiInstall(LPTSTR lpszShare)
  235. {
  236. BOOL bRet = FALSE,
  237. bChanged = FALSE;
  238. LPAPPENTRY lpAppList,
  239. lpAppSearch;
  240. APPENTRY appSbsi;
  241. LPTSTR lpszSbsiName = AllocateString(NULL, IDS_INSTALLSBSI),
  242. lpszSbsiPath;
  243. TCHAR szLocalSbsiPath[MAX_PATH];
  244. HRESULT hrPrintf;
  245. // We have to have a friendly name to make this work.
  246. //
  247. if ( NULL == lpszSbsiName )
  248. {
  249. return FALSE;
  250. }
  251. // Start by clearing out the SBSI app structure.
  252. //
  253. ZeroMemory(&appSbsi, sizeof(APPENTRY));
  254. // Set the friendly name.
  255. //
  256. lstrcpyn(appSbsi.szDisplayName, lpszSbsiName, AS(appSbsi.szDisplayName));
  257. FREE(lpszSbsiName);
  258. // The source path starts with the distribution share.
  259. //
  260. lstrcpyn(appSbsi.szSourcePath, lpszShare, AS(appSbsi.szSourcePath));
  261. // Need to save this pointer, we will use this path to make sure the
  262. // SBSI content is there.
  263. //
  264. lpszSbsiPath = appSbsi.szSourcePath + lstrlen(appSbsi.szSourcePath);
  265. // Now create the rest of the path to where the content should be.
  266. //
  267. AddPathN(appSbsi.szSourcePath, g_App.szLangDir + lstrlen(g_App.szOpkDir), AS(appSbsi.szSourcePath));
  268. AddPathN(appSbsi.szSourcePath, g_App.szLangName, AS(appSbsi.szSourcePath));
  269. AddPathN(appSbsi.szSourcePath, DIR_SBSI, AS(appSbsi.szSourcePath));
  270. AddPathN(appSbsi.szSourcePath, g_App.szSkuName, AS(appSbsi.szSourcePath));
  271. AddPathN(appSbsi.szSourcePath, DIR_SBSI_SETUP, AS(appSbsi.szSourcePath));
  272. // This is the name of the setup program.
  273. //
  274. lstrcpyn(appSbsi.szSetupFile, FILE_SBSI_SETUP, AS(appSbsi.szSetupFile));
  275. // This will create the command line for the file.
  276. //
  277. hrPrintf=StringCchPrintf(appSbsi.szCommandLine, AS(appSbsi.szCommandLine), CMD_SBSI_SETUP, appSbsi.szSourcePath);
  278. // This is the base install tech type.
  279. //
  280. appSbsi.itSectionType = installtechUndefined;
  281. // If there is a list, make sure our entry isn't already
  282. // there.
  283. //
  284. lpAppSearch = lpAppList = OpenAppList(g_App.szWinBomIniFile);
  285. while ( lpAppSearch && !bChanged)
  286. {
  287. if ( lstrcmp(lpAppSearch->szDisplayName, appSbsi.szDisplayName) == 0 )
  288. {
  289. if ( RemoveApp(&lpAppList, lpAppSearch) )
  290. {
  291. bChanged = TRUE;
  292. }
  293. }
  294. else
  295. {
  296. lpAppSearch = lpAppSearch->lpNext;
  297. }
  298. }
  299. // Create the local path to the setup file where the SBSI content should
  300. // be. Only if that exists to we add the app.
  301. //
  302. lstrcpyn(szLocalSbsiPath, g_App.szOpkDir, AS(szLocalSbsiPath));
  303. AddPathN(szLocalSbsiPath, lpszSbsiPath, AS(szLocalSbsiPath));
  304. AddPathN(szLocalSbsiPath, appSbsi.szSetupFile, AS(szLocalSbsiPath));
  305. // Now try to insert our SBSI stuff to the end of the list.
  306. //
  307. if ( FileExists(szLocalSbsiPath) &&
  308. InsertApp(&lpAppList, &appSbsi) )
  309. {
  310. bChanged = TRUE;
  311. bRet = TRUE;
  312. }
  313. // Save and close our list.
  314. //
  315. if ( lpAppList )
  316. {
  317. // Only need to save if we changed something.
  318. //
  319. if ( bChanged )
  320. {
  321. if ( !SaveAppList(lpAppList, g_App.szWinBomIniFile, g_App.szOpkWizIniFile) )
  322. {
  323. bRet = FALSE;
  324. }
  325. }
  326. // This will free up the memory for the list.
  327. //
  328. CloseAppList(lpAppList);
  329. }
  330. return bRet;
  331. }