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.

383 lines
9.3 KiB

  1. //
  2. // AppList.C
  3. //
  4. // Copyright (C) Microsoft, 1994, 1995, All Rights Reserved.
  5. //
  6. // History:
  7. // ral 5/23/94 - First pass
  8. // ral 9/09/94 - Clean up
  9. // 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
  10. //
  11. //
  12. #include "priv.h"
  13. #include "appwiz.h"
  14. #include "regstr.h"
  15. #ifdef DOWNLEVEL
  16. static const DWORD aApplistHelpIDs[] = {
  17. IDC_BUTTONSETUPFROMLIST, IDH_APPWIZ_NETINTALLL_BUTTON,
  18. IDC_APPLIST, IDH_APPWIZ_NETINSTALL_LIST,
  19. 0, 0 };
  20. #define INST_SECTION TEXT("AppInstallList") // RESOURCE?
  21. #define MAX_KEY_SIZE 45000
  22. //
  23. // Fills in the name of the INF file in the wiz data structure. If
  24. // no INF file is specified then returns FALSE, else TRUE.
  25. //
  26. BOOL AppListGetInfName(LPWIZDATA lpwd)
  27. {
  28. HKEY hk;
  29. LONG RegResult;
  30. DWORD cbFileName = sizeof(lpwd->szIniFile);
  31. DWORD dwType;
  32. BOOL bFileExists = FALSE;
  33. if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hk) != ERROR_SUCCESS)
  34. {
  35. return(FALSE);
  36. }
  37. RegResult = RegQueryValueEx(hk, REGSTR_VAL_APPINSTPATH, NULL,
  38. &dwType, (LPBYTE) lpwd->szIniFile, &cbFileName);
  39. RegCloseKey(hk);
  40. if (RegResult == ERROR_SUCCESS && dwType == REG_SZ)
  41. {
  42. bFileExists = PathFileExists(lpwd->szIniFile);
  43. }
  44. if (!bFileExists)
  45. {
  46. lpwd->szIniFile[0] = 0;
  47. }
  48. return(bFileExists);
  49. }
  50. #ifdef DEBUG
  51. void ValidateINIEntry(LPWIZDATA lpwd, LPTSTR lpszKeyName)
  52. {
  53. TCHAR szFileName[MAX_PATH];
  54. if (GetPrivateProfileString(INST_SECTION, lpszKeyName, TEXT(""),
  55. szFileName, ARRAYSIZE(szFileName),
  56. lpwd->szIniFile))
  57. {
  58. LPTSTR lpszRealName = szFileName;
  59. if (*lpszRealName == TEXT('*'))
  60. {
  61. lpszRealName++;
  62. }
  63. if (!PathFileExists(lpszRealName))
  64. {
  65. ShellMessageBox(g_hinst, lpwd->hwnd,
  66. TEXT("Entry for %1%s points to non-existant setup program: %2%s"),
  67. 0, MB_OK | MB_ICONEXCLAMATION, lpszKeyName, szFileName);
  68. }
  69. }
  70. else
  71. {
  72. ShellMessageBox(g_hinst, lpwd->hwnd,
  73. TEXT("Bad INI file format for entry %1%s."),
  74. 0, MB_OK | MB_ICONEXCLAMATION, lpszKeyName);
  75. }
  76. }
  77. #endif // DEBUG
  78. //
  79. // Initializes the applist property sheet. This function assumes that
  80. // someone else (appwiz.c) has already called AppListGetInfName and the
  81. // inf file name has already been filled in in the wizard data structure.
  82. // If the string is empty, then this function simply returns.
  83. //
  84. void AppList_InitListBox(HWND hDlg, LPPROPSHEETPAGE lpp)
  85. {
  86. LPWIZDATA lpwd = (LPWIZDATA)lpp->lParam;
  87. SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)lpp);
  88. if (lpwd->szIniFile[0] != 0)
  89. {
  90. HWND hLB = GetDlgItem(hDlg, IDC_APPLIST);
  91. LPTSTR lpszKeys = (LPTSTR)GlobalAllocPtr(GPTR, MAX_KEY_SIZE*sizeof(TCHAR));
  92. ListBox_ResetContent(hLB);
  93. //
  94. // If the localalloc failed then we'll just have a
  95. // empty list.
  96. //
  97. if (lpszKeys)
  98. {
  99. HCURSOR hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  100. if (GetPrivateProfileString(INST_SECTION, NULL, NULL, lpszKeys,
  101. MAX_KEY_SIZE, lpwd->szIniFile))
  102. {
  103. LPTSTR lpszCurPos = lpszKeys;
  104. int iCurLBPos = 0;
  105. while (*lpszCurPos)
  106. {
  107. ListBox_InsertString(hLB, iCurLBPos++, lpszCurPos);
  108. #ifdef DEBUG
  109. ValidateINIEntry(lpwd, lpszCurPos);
  110. #endif
  111. while (*lpszCurPos != 0)
  112. {
  113. lpszCurPos = CharNext(lpszCurPos);
  114. }
  115. lpszCurPos++;
  116. }
  117. }
  118. GlobalFreePtr(lpszKeys);
  119. SetCursor(hcurOld);
  120. }
  121. ListBox_SetCurSel(hLB, 0);
  122. }
  123. }
  124. //
  125. // Copies the name of the setup program into the wizard data
  126. //
  127. BOOL GetListSel(HWND hLB, int iCurSel, LPWIZDATA lpwd)
  128. {
  129. TCHAR szKeyName[MAX_PATH];
  130. if ((iCurSel != LB_ERR) &&
  131. (ListBox_GetTextLen(hLB, iCurSel) <= ARRAYSIZE(szKeyName)))
  132. {
  133. ListBox_GetText(hLB, iCurSel, szKeyName);
  134. if (GetPrivateProfileString(INST_SECTION, szKeyName, TEXT(""),
  135. lpwd->szExeName, ARRAYSIZE(lpwd->szExeName),
  136. lpwd->szIniFile))
  137. {
  138. lpwd->szParams[0] = 0; // Make sure this string is empty
  139. return(TRUE);
  140. }
  141. }
  142. return(FALSE);
  143. }
  144. //
  145. // Dismisses the property sheet by pressing the "OK" button.
  146. //
  147. void DismissCPL(LPWIZDATA lpwd)
  148. {
  149. PropSheet_PressButton(GetParent(lpwd->hwnd), PSBTN_OK);
  150. }
  151. //
  152. // Install property sheet page -- Used only if there is an AppInstallPath
  153. // specified in the registry. Otherwise, use NoListInstallDlgProc.
  154. //
  155. BOOL_PTR CALLBACK AppListDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
  156. {
  157. NMHDR FAR *lpnm;
  158. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
  159. LPWIZDATA lpwd;
  160. if (lpPropSheet)
  161. {
  162. lpwd = (LPWIZDATA)lpPropSheet->lParam;
  163. }
  164. switch(message)
  165. {
  166. case WM_NOTIFY:
  167. lpnm = (NMHDR FAR *)lParam;
  168. switch(lpnm->code)
  169. {
  170. case PSN_SETACTIVE:
  171. lpwd->hwnd = hDlg;
  172. break;
  173. default:
  174. return FALSE;
  175. }
  176. break;
  177. case WM_INITDIALOG:
  178. lpPropSheet = (LPPROPSHEETPAGE)lParam;
  179. AppList_InitListBox(hDlg, lpPropSheet);
  180. break;
  181. case WM_DESTROY:
  182. break;
  183. case WM_HELP:
  184. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, NULL,
  185. HELP_WM_HELP, (DWORD_PTR)aApplistHelpIDs);
  186. break;
  187. case WM_CONTEXTMENU:
  188. WinHelp((HWND)wParam, NULL, HELP_CONTEXTMENU,
  189. (DWORD_PTR)aApplistHelpIDs);
  190. break;
  191. case WM_COMMAND:
  192. switch (GET_WM_COMMAND_ID(wParam, lParam))
  193. {
  194. case IDC_BUTTONSETUPFROMLIST:
  195. if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED)
  196. {
  197. HWND hLB = GetDlgItem(hDlg, IDC_APPLIST);
  198. int iCurSel = ListBox_GetCurSel(hLB);
  199. if (iCurSel != LB_ERR &&
  200. GetListSel(hLB, iCurSel, lpwd) &&
  201. ExecSetupProg(lpwd, FALSE, TRUE))
  202. {
  203. DismissCPL(lpwd);
  204. }
  205. }
  206. case IDC_APPLIST:
  207. if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_DBLCLK)
  208. {
  209. SendMessage(hDlg, WM_COMMAND,
  210. GET_WM_COMMAND_MPS(IDC_BUTTONSETUPFROMLIST,
  211. GetDlgItem(hDlg, IDC_BUTTONSETUPFROMLIST),
  212. BN_CLICKED));
  213. }
  214. break;
  215. }
  216. break;
  217. default:
  218. return FALSE;
  219. } // end of switch on message
  220. return TRUE;
  221. } // AppListdlgProc
  222. #endif // DOWNLEVEL
  223. //
  224. // Executes the appropriate setup program
  225. //
  226. BOOL ExecSetupProg(LPWIZDATA lpwd, BOOL ForceWx86, BOOL bMinimizeWiz)
  227. {
  228. SHELLEXECUTEINFO ei;
  229. BOOL fWorked= FALSE;
  230. #ifdef WX86
  231. DWORD Len;
  232. WCHAR ProcArchValue[32];
  233. #endif
  234. HWND hDlgPropSheet = GetParent(lpwd->hwnd);
  235. LPTSTR lpszTarget = NULL;
  236. ei.cbSize = sizeof(ei);
  237. ei.hwnd = lpwd->hwnd;
  238. ei.lpVerb = NULL;
  239. ei.fMask = 0;
  240. lpszTarget = (lpwd->dwFlags & WDFLAG_EXPSZ) ? lpwd->szExpExeName : lpwd->szExeName;
  241. if (lpszTarget[0] == TEXT('*'))
  242. {
  243. ei.lpFile = CharNext(lpszTarget);
  244. ei.fMask |= SEE_MASK_CONNECTNETDRV;
  245. }
  246. else
  247. {
  248. ei.lpFile = lpszTarget;
  249. }
  250. if (lpwd->szParams[0] == 0)
  251. {
  252. ei.lpParameters = NULL;
  253. }
  254. else
  255. {
  256. ei.lpParameters = lpwd->szParams;
  257. }
  258. if (lpwd->szWorkingDir[0] == TEXT('\0'))
  259. {
  260. ei.lpDirectory = NULL;
  261. }
  262. else
  263. {
  264. ei.lpDirectory = lpwd->szWorkingDir;
  265. }
  266. ei.lpClass = NULL;
  267. ei.nShow = SW_SHOWDEFAULT;
  268. ei.hInstApp = g_hinst;
  269. if (bMinimizeWiz)
  270. SetWindowPos(hDlgPropSheet, 0, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
  271. #ifdef WX86
  272. if (ForceWx86) {
  273. Len = GetEnvironmentVariableW(ProcArchName,
  274. ProcArchValue,
  275. sizeof(ProcArchValue)
  276. );
  277. if (!Len || Len >= sizeof(ProcArchValue)) {
  278. ProcArchValue[0]=L'\0';
  279. }
  280. SetEnvironmentVariableW(ProcArchName, L"x86");
  281. ei.fMask |= SEE_MASK_FLAG_SEPVDM;
  282. }
  283. #endif
  284. fWorked = ShellExecuteEx(&ei);
  285. #ifdef WX86
  286. if (ForceWx86) {
  287. SetEnvironmentVariableW(ProcArchName, ProcArchValue);
  288. }
  289. #endif
  290. if (!fWorked)
  291. {
  292. //
  293. // Something went wrong. Put the dialog back up.
  294. //
  295. SetWindowPos(hDlgPropSheet, 0, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
  296. ShellMessageBox(g_hinst, lpwd->hwnd, MAKEINTRESOURCE(IDS_BADSETUP),
  297. 0, MB_OK | MB_ICONEXCLAMATION);
  298. }
  299. return(fWorked);
  300. }