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.

380 lines
9.3 KiB

  1. //
  2. // Setup.C
  3. //
  4. // Copyright (C) Microsoft, 1994,1995 All Rights Reserved.
  5. //
  6. // History:
  7. // ral 5/23/94 - First pass
  8. // 3/20/95 [stevecat] - NT port & real clean up, unicode, etc.
  9. //
  10. //
  11. #include "priv.h"
  12. #include "appwiz.h"
  13. void _inline InitSetupWiz(HWND hDlg, LPARAM lParam)
  14. {
  15. InitWizSheet(hDlg, lParam, 0);
  16. }
  17. //
  18. // Loads the specified resource ID string and replaces all ';' characters
  19. // with NULL. The end of the string will be doubly null-teminated.
  20. //
  21. BOOL LoadAndStrip(int id, LPTSTR lpsz, int cbstr)
  22. {
  23. ASSERT(lpsz);
  24. ASSERT(cbstr != 0);
  25. if (!LoadString(g_hinst, id, lpsz, cbstr-1))
  26. {
  27. return FALSE;
  28. }
  29. else
  30. {
  31. while (*lpsz)
  32. {
  33. if (*lpsz == TEXT('@'))
  34. {
  35. *lpsz = 0;
  36. lpsz++;
  37. }
  38. else
  39. {
  40. lpsz = CharNext(lpsz);
  41. }
  42. }
  43. *(lpsz+1) = 0;
  44. return TRUE;
  45. }
  46. }
  47. //
  48. // Skips to the first charcter of the next string in a list of null-terminated
  49. // strings. The caller should check to see if the pointer returned points to
  50. // a null. If so, the end of the table has been reached.
  51. //
  52. LPTSTR SkipStr(LPTSTR lpsz)
  53. {
  54. while (*lpsz)
  55. {
  56. lpsz = CharNext(lpsz);
  57. }
  58. lpsz++;
  59. return(lpsz);
  60. }
  61. void SetStaticStr(HWND hCtl, int id)
  62. {
  63. TCHAR szText[MAX_PATH];
  64. LoadString(g_hinst, id, szText, ARRAYSIZE(szText));
  65. Static_SetText(hCtl, szText);
  66. }
  67. void FreeIcon(HWND hDlg)
  68. {
  69. HICON hicon = Static_SetIcon(GetDlgItem(hDlg, IDC_SEARCHICON), NULL);
  70. if (hicon)
  71. {
  72. DestroyIcon(hicon);
  73. }
  74. }
  75. //
  76. // ProgramExists returns TRUE if the specified file exists. This function
  77. // accepts wildcards, and if a file matches the specified name then
  78. // the file name buffer will be updated to the actual name of the first
  79. // matching file. This allows FindBestSetupPrg to pass in *setup to find
  80. // programs such as WPSETUP.EXE.
  81. //
  82. // This function assumes that szFindName is of size MAX_PATH.
  83. //
  84. BOOL ProgramExists(LPTSTR lpszFindName, UINT cchFindName)
  85. {
  86. HANDLE hfind;
  87. WIN32_FIND_DATA fd;
  88. hfind = FindFirstFile(lpszFindName, &fd);
  89. if (hfind == INVALID_HANDLE_VALUE)
  90. {
  91. return(FALSE);
  92. }
  93. FindClose(hfind);
  94. StringCchCopy(lpszFindName+3, cchFindName-3, fd.cFileName);
  95. return(TRUE);
  96. }
  97. //
  98. // This function searches for the "best" setup program. Once a windows app
  99. // with the appropriate name is found it stops. If it finds a install/setup
  100. // program that is a DOS program, it remembers the first one, but continues
  101. // searching for a Windows setup program.
  102. // Games like Math Rabbit have a DOS Install.Exe and a Windows Setup.Exe.
  103. //
  104. BOOL FindBestSetupPrg(LPTSTR lpszExeName, UINT cchExeName, LPTSTR lpszDriveRoot, LPTSTR lpszSpecialCase,
  105. LPTSTR lpszAppNames, LPTSTR lpszExtensions)
  106. {
  107. LPTSTR lpszCurApp, lpszCurExt;
  108. TCHAR szThisOne[MAX_PATH];
  109. *lpszExeName = 0;
  110. //
  111. // Look for special-case programs first
  112. //
  113. lpszCurApp = lpszSpecialCase;
  114. while(*lpszCurApp)
  115. {
  116. StringCchPrintf(szThisOne, ARRAYSIZE(szThisOne), TEXT("%s%s"), lpszDriveRoot, lpszCurApp);
  117. if (ProgramExists(szThisOne, ARRAYSIZE(szThisOne)))
  118. {
  119. StringCchCopy(lpszExeName, cchExeName, szThisOne);
  120. return(TRUE);
  121. }
  122. lpszCurApp = SkipStr(lpszCurApp);
  123. }
  124. //
  125. // Now look for generic setup program names
  126. //
  127. lpszCurApp = lpszAppNames;
  128. while (*lpszCurApp)
  129. {
  130. lpszCurExt = lpszExtensions;
  131. while (*lpszCurExt)
  132. {
  133. StringCchPrintf(szThisOne, ARRAYSIZE(szThisOne), TEXT("%s%s.%s"), lpszDriveRoot, lpszCurApp, lpszCurExt);
  134. if (ProgramExists(szThisOne, ARRAYSIZE(szThisOne)))
  135. {
  136. BOOL fIsWinApp = HIWORD(SHGetFileInfo(szThisOne, 0, NULL,
  137. 0, SHGFI_EXETYPE)) > 0;
  138. if (*lpszExeName == 0 || fIsWinApp)
  139. {
  140. StringCchCopy(lpszExeName, cchExeName, szThisOne);
  141. }
  142. if (fIsWinApp)
  143. {
  144. return(TRUE);
  145. }
  146. }
  147. lpszCurExt = SkipStr(lpszCurExt);
  148. }
  149. lpszCurApp = SkipStr(lpszCurApp);
  150. }
  151. return(*lpszExeName != 0);
  152. }
  153. //
  154. // Gets information about the specified file/drive root and sets the
  155. // icon and description fields in the dialog.
  156. //
  157. void _inline UpdateFileInfo(LPWIZDATA lpwd, LPTSTR lpszFileName)
  158. {
  159. HWND hKiddie;
  160. HICON hOldIcon;
  161. SHFILEINFO fi;
  162. DWORD_PTR pdwRes;
  163. pdwRes = SHGetFileInfo(lpszFileName, 0, &fi, sizeof(fi),
  164. SHGFI_ICON | SHGFI_DISPLAYNAME | SHGFI_LARGEICON);
  165. if (pdwRes)
  166. {
  167. hKiddie = GetDlgItem(lpwd->hwnd, IDC_SEARCHICON);
  168. hOldIcon = Static_SetIcon(hKiddie, fi.hIcon);
  169. if (hOldIcon)
  170. {
  171. DestroyIcon(hOldIcon);
  172. }
  173. UpdateWindow(hKiddie);
  174. hKiddie = GetDlgItem(lpwd->hwnd, IDC_SEARCHNAME);
  175. Static_SetText(hKiddie, fi.szDisplayName);
  176. UpdateWindow(hKiddie);
  177. }
  178. }
  179. //
  180. // Search for the setup program
  181. //
  182. BOOL SetupNextPressed(LPWIZDATA lpwd)
  183. {
  184. int iDrive, iDrvType;
  185. BOOL fFoundExe = FALSE;
  186. HWND hMainMsg = GetDlgItem(lpwd->hwnd, IDC_SETUPMSG);
  187. HWND hSetupName = GetDlgItem(lpwd->hwnd, IDC_SEARCHNAME);
  188. TCHAR szAppNames[MAX_PATH];
  189. TCHAR szExtensions[100];
  190. TCHAR szSpecialCase[MAX_PATH];
  191. TCHAR szDriveRoot[4];
  192. HCURSOR hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  193. //BOOL fFoundDisk = FALSE;
  194. lpwd->szExeName[0] = 0; // Reset any existing name
  195. SetStaticStr(hMainMsg, IDS_SEARCHING);
  196. LoadAndStrip(IDS_SETUPPRGNAMES, szAppNames, ARRAYSIZE(szAppNames));
  197. LoadAndStrip(IDS_EXTENSIONS, szExtensions, ARRAYSIZE(szExtensions));
  198. LoadAndStrip(IDS_SPECIALCASE, szSpecialCase, ARRAYSIZE(szSpecialCase));
  199. for (iDrive = 0; (!fFoundExe) && (iDrive < 26); iDrive++)
  200. {
  201. iDrvType = DriveType(iDrive);
  202. if ((iDrvType == DRIVE_REMOVABLE) || (iDrvType == DRIVE_CDROM))
  203. {
  204. PathBuildRoot(szDriveRoot, iDrive);
  205. UpdateFileInfo(lpwd, szDriveRoot);
  206. if (PathFileExists(szDriveRoot))
  207. {
  208. //fFoundDisk = TRUE;
  209. fFoundExe = FindBestSetupPrg(lpwd->szExeName, ARRAYSIZE(lpwd->szExeName), szDriveRoot,
  210. szSpecialCase,
  211. szAppNames, szExtensions);
  212. }
  213. }
  214. }
  215. FreeIcon(lpwd->hwnd);
  216. SetCursor(hcurOld);
  217. return(fFoundExe);
  218. }
  219. void SetupSetToDefault(LPWIZDATA lpwd)
  220. {
  221. SetStaticStr(GetDlgItem(lpwd->hwnd, IDC_SETUPMSG), IDS_INSERTDISK);
  222. Static_SetText(GetDlgItem(lpwd->hwnd, IDC_SEARCHNAME), NULL);
  223. FreeIcon(lpwd->hwnd);
  224. PropSheet_SetWizButtons(GetParent(lpwd->hwnd), PSWIZB_NEXT);
  225. //
  226. // To make sure that the next button always has the focus, we post
  227. // this message that sets the wiz buttons AFTER we're active. We have
  228. // to do the one above to make sure that Back is disabled to avoid any
  229. // random window where the back button could be hit.
  230. //
  231. PostMessage(lpwd->hwnd, WMPRIV_POKEFOCUS, 0, 0);
  232. }
  233. BOOL_PTR CALLBACK SetupDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
  234. {
  235. NMHDR FAR *lpnm = NULL;
  236. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
  237. LPWIZDATA lpwd = NULL;
  238. if (lpPropSheet)
  239. {
  240. lpwd = (LPWIZDATA)lpPropSheet->lParam;
  241. }
  242. switch(message)
  243. {
  244. case WM_NOTIFY:
  245. lpnm = (NMHDR FAR *)lParam;
  246. if(lpnm)
  247. {
  248. switch(lpnm->code)
  249. {
  250. case PSN_SETACTIVE:
  251. if(lpwd)
  252. {
  253. lpwd->hwnd = hDlg;
  254. SetupSetToDefault(lpwd);
  255. }
  256. break;
  257. case PSN_WIZNEXT:
  258. if(lpwd)
  259. {
  260. SetupNextPressed(lpwd);
  261. SetDlgMsgResult(hDlg, WM_NOTIFY, 0);
  262. }
  263. break;
  264. case PSN_RESET:
  265. if(lpwd)
  266. {
  267. CleanUpWizData(lpwd);
  268. }
  269. break;
  270. default:
  271. return FALSE;
  272. }
  273. }
  274. break;
  275. case WMPRIV_POKEFOCUS:
  276. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
  277. break;
  278. case WM_INITDIALOG:
  279. InitSetupWiz(hDlg, lParam);
  280. break;
  281. case WM_DESTROY:
  282. FreeIcon(hDlg);
  283. break;
  284. default:
  285. return FALSE;
  286. } // end of switch on message
  287. return TRUE;
  288. } // SetupdlgProc