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.

605 lines
18 KiB

  1. // **************************************************************************
  2. //
  3. // rodlg.c
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1992-1993
  7. // All rights reserved
  8. //
  9. // RunOnce wrapper. This encapsulates all applications that would like
  10. // to run the first time we re-boot. It lists these apps for the user
  11. // and allows the user to launce the apps (like apple at ease).
  12. //
  13. // 5 June 1994 FelixA Started
  14. // 8 June Felix Defined registry strings and functionality.
  15. // Got small buttons displayed, but not working.
  16. // 9 June Felix Both big and small buttons. Nice UI.
  17. // Got single click app launching.
  18. //
  19. // 23 June Felix Moving it to a Chicago make thingy not Dolphin
  20. //
  21. // *************************************************************************/
  22. //
  23. #include "precomp.h"
  24. #include <shlobj.h>
  25. #include <stdlib.h>
  26. #include <regstr.h>
  27. #include <shellapi.h>
  28. #include <shlobjp.h>
  29. #include <strsafe.h>
  30. // #include <shsemip.h>
  31. extern int g_iState; // Command line args.
  32. extern HINSTANCE g_hInst; // current instance
  33. #define WM_FINISHED (WM_USER+0x123)
  34. #include "resource.h"
  35. int g_fCleanBoot;
  36. TCHAR c_szRunOnce[]=REGSTR_PATH_RUNONCE;
  37. TCHAR c_szSetup[]=REGSTR_PATH_SETUP;
  38. TCHAR g_szWallpaper[] = TEXT("wallpaper");
  39. TCHAR szTileWall[] = TEXT("TileWallpaper");
  40. TCHAR szFallback[] = TEXT("*DisplayFallback");
  41. const TCHAR c_szTimeChangedRunOnce[] = TEXT("WarnTimeChanged"); //kernel32 and explorer use this
  42. // Run time can be set for big or small buttons.
  43. int g_Small=0;
  44. HDC g_hdcMem=NULL;
  45. DWORD g_dwThread;
  46. //***************************************************************************
  47. //
  48. // <Function>()
  49. // <Explanation>
  50. //
  51. // ENTRY:
  52. // <Params>
  53. //
  54. // EXIT:
  55. // <Params>
  56. //
  57. //***************************************************************************
  58. //***************************************************************************
  59. //
  60. // DoAnyRandomOneTimeStuff()
  61. // Just a place to toss random stuff for RunOnce app to do.
  62. //
  63. // ENTRY:
  64. // void
  65. //
  66. // EXIT:
  67. // void
  68. //
  69. //***************************************************************************
  70. void DoAnyRandomOneTimeStuff(void)
  71. {
  72. HKEY runonce;
  73. // remove any time-changed warning added by kernel32 during boot
  74. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRunOnce, 0, KEY_SET_VALUE, &runonce) == ERROR_SUCCESS)
  75. {
  76. RegDeleteValue(runonce, (LPCTSTR)c_szTimeChangedRunOnce);
  77. RegCloseKey(runonce);
  78. }
  79. }
  80. //***************************************************************************
  81. //
  82. // RunOnceFill()
  83. // Fills the List box in the run-once dlg.
  84. //
  85. // ENTRY:
  86. // HWND of the thing to fill.
  87. //
  88. // EXIT:
  89. // <Params>
  90. // BOOL NEAR PASCAL RunRegApps(HKEY hkeyParent, LPCSTR szSubkey, BOOL fDelete, BOOL fWait)
  91. //
  92. //***************************************************************************
  93. BOOL RunOnceFill(HWND hWnd)
  94. {
  95. HKEY hkey;
  96. // HKEY hDescKey;
  97. BOOL fShellInit = FALSE;
  98. HKEY hkeyParent = HKEY_LOCAL_MACHINE;
  99. TCHAR szSubkey[MAX_PATH];
  100. BOOL fDelete=FALSE;
  101. BOOL fWait=FALSE;
  102. // Enumerate HKLM\Runonce\Setup - *.*
  103. StringCchCopy(szSubkey, ARRAYSIZE(szSubkey), c_szRunOnce);
  104. StringCchCat(szSubkey, ARRAYSIZE(szSubkey), TEXT("\\Setup"));
  105. if (RegOpenKeyEx(hkeyParent, szSubkey, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
  106. {
  107. DWORD cbData, cchValue, dwType, i;
  108. TCHAR szValueName[MAX_PATH], szCmdLine[MAX_PATH];
  109. LRESULT lRes;
  110. DWORD dwNumSubkeys=1, dwNumValues=5;
  111. for (i = 0; ; i++)
  112. {
  113. cchValue = sizeof(szValueName) / sizeof(TCHAR);
  114. cbData = sizeof(szCmdLine);
  115. if (RegEnumValue(hkey, i, szValueName, &cchValue, NULL, &dwType, (LPBYTE) szCmdLine, &cbData) != ERROR_SUCCESS)
  116. break;
  117. if (dwType == REG_SZ)
  118. {
  119. PTASK pTask;
  120. pTask = (PTASK)LocalAlloc( LPTR ,sizeof(TASK));
  121. StringCchCopy(pTask->Text, ARRAYSIZE(pTask->Text) - 1, szValueName);
  122. StringCchCopy(pTask->Cmd, ARRAYSIZE(pTask->Cmd) - 1, szCmdLine);
  123. lRes = SendMessage( hWnd, LB_ADDSTRING, 0, (LPARAM)pTask );
  124. if( lRes == LB_ERR || lRes == LB_ERRSPACE )
  125. {
  126. LocalFree(pTask);
  127. pTask=NULL;
  128. }
  129. }
  130. }
  131. RegCloseKey(hkey);
  132. }
  133. return(fShellInit);
  134. }
  135. //***************************************************************************
  136. //
  137. // LaunchApp()
  138. // Given an index into the list box, will spawn the task, wait for it to
  139. // finish.
  140. //
  141. // ENTRY:
  142. // Index into list.
  143. //
  144. // EXIT:
  145. // <Params>
  146. //
  147. //***************************************************************************
  148. int LaunchApp(HWND hWnd, WORD wItem )
  149. {
  150. LPTSTR lpszCmdLine;
  151. STARTUPINFO startup;
  152. #ifndef DEBUG
  153. PROCESS_INFORMATION pi;
  154. #endif
  155. PTASK pTask;
  156. RECT rWnd;
  157. GetWindowRect(hWnd, &rWnd);
  158. SendMessage(hWnd,LB_SETCURSEL,wItem,0);
  159. pTask = (PTASK)SendMessage( hWnd, LB_GETITEMDATA, wItem, 0L);
  160. if(pTask != (PTASK)LB_ERR )
  161. {
  162. lpszCmdLine = &pTask->Cmd[0];
  163. // Now exec it.
  164. startup.cb = sizeof(startup);
  165. startup.lpReserved = NULL;
  166. startup.lpDesktop = NULL;
  167. startup.lpTitle = NULL;
  168. startup.dwFlags = STARTF_USEPOSITION; // Set start position
  169. startup.dwX=rWnd.right+5;
  170. startup.dwY=rWnd.top+5;
  171. startup.cbReserved2 = 0;
  172. startup.lpReserved2 = NULL;
  173. #ifdef DEBUG
  174. MessageBox(hWnd, lpszCmdLine,TEXT("DebugRun"),MB_OK);
  175. #else
  176. if (CreateProcess(NULL, lpszCmdLine, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP,
  177. NULL, NULL, &startup, &pi))
  178. {
  179. WaitForSingleObjectEx(pi.hProcess, INFINITE, TRUE);
  180. CloseHandle(pi.hProcess);
  181. CloseHandle(pi.hThread);
  182. }
  183. else
  184. {
  185. MessageBeep( MB_ICONEXCLAMATION );
  186. }
  187. #endif
  188. }
  189. else
  190. {
  191. MessageBeep( MB_ICONEXCLAMATION );
  192. }
  193. // Remove any selection after the app terminates.
  194. SendMessage( hWnd, LB_SETCURSEL, (WPARAM)-1, 0);
  195. return FALSE;
  196. }
  197. //***************************************************************************
  198. //
  199. // RunAppsInList()
  200. // Enumerates all the items in the list box, spawning each in turn.
  201. //
  202. // ENTRY:
  203. // HWND of Parent.
  204. //
  205. // EXIT:
  206. // <Params>
  207. //
  208. //***************************************************************************
  209. DWORD WINAPI RunAppsInList(LPVOID lp)
  210. {
  211. HWND hWnd=(HWND)lp;
  212. WORD i,iNumItems;
  213. TCHAR szSubkey[MAX_PATH];
  214. TCHAR szWallpaper[MAX_PATH];
  215. DWORD cbSize;
  216. DWORD dwType;
  217. // Run all the applications in the list
  218. iNumItems = (WORD)SendMessage(hWnd,LB_GETCOUNT,0,0L);
  219. for(i=0;i<iNumItems;i++)
  220. {
  221. LaunchApp(hWnd,i);
  222. }
  223. // Delete the runonce subkey for setup.
  224. #ifdef DEBUG
  225. MessageBox( hWnd, szSubkey, TEXT("Delete Key - not done"), MB_OK);
  226. #else
  227. StringCchCopy(szSubkey, ARRAYSIZE(szSubkey), c_szRunOnce);
  228. StringCchCat(szSubkey, ARRAYSIZE(szSubkey), TEXT("\\Setup"));
  229. RegDeleteKey( HKEY_LOCAL_MACHINE, szSubkey );
  230. #endif
  231. // Now see if we should reboot/restart.
  232. if (g_iState & (CMD_DO_REBOOT|CMD_DO_RESTART))
  233. {
  234. HKEY hkey;
  235. TCHAR achTitle[80];
  236. DWORD dwSetupFlags=0;
  237. //
  238. // because we are going to reboot, remove the VGA fallback.
  239. // line from OneRunce.
  240. //
  241. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRunOnce, 0, KEY_SET_VALUE, &hkey) == ERROR_SUCCESS)
  242. {
  243. RegDeleteValue(hkey, szFallback);
  244. RegCloseKey(hkey);
  245. }
  246. szWallpaper[0]=0;
  247. LoadString(g_hInst, IDS_PAMPER, szWallpaper, sizeof(szWallpaper) / sizeof(TCHAR));
  248. GetWindowText(GetParent(hWnd), achTitle, sizeof(achTitle) / sizeof(TCHAR));
  249. // Get the setup flags.
  250. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSetup, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
  251. {
  252. cbSize=sizeof(dwSetupFlags);
  253. if(RegQueryValueEx(hkey, REGSTR_VAL_SETUPFLAGS, NULL , &dwType, (LPBYTE)&dwSetupFlags, &cbSize) != ERROR_SUCCESS )
  254. dwSetupFlags=0;
  255. RegCloseKey(hkey);
  256. }
  257. //
  258. // always reboot the system, dont give the user a choice.
  259. //
  260. // alow OEMs not to have to click OK.
  261. #ifdef DEBUG
  262. MessageBox(hWnd,dwSetupFlags & SUF_BATCHINF?TEXT("Batchfile used"):TEXT("No batch"),TEXT("Batch"),MB_OK);
  263. #endif
  264. if( !(dwSetupFlags & SUF_BATCHINF) || !GetPrivateProfileInt(TEXT("Setup"),TEXT("NoPrompt2Boot"),0,TEXT("MSBATCH.INF")))
  265. MessageBox(GetParent(hWnd),szWallpaper,achTitle,MB_OK|MB_ICONEXCLAMATION);
  266. #ifndef DEBUG
  267. ExitWindowsEx(EWX_REBOOT, 0);
  268. #endif
  269. }
  270. PostMessage(GetParent(hWnd),WM_FINISHED,0,0L);
  271. return 0;
  272. }
  273. //***************************************************************************
  274. //
  275. // <Function>()
  276. // <Explanation>
  277. //
  278. // ENTRY:
  279. // <Params>
  280. //
  281. // EXIT:
  282. // <Params>
  283. //
  284. //***************************************************************************
  285. #define CXBORDER 3
  286. LRESULT _HandleLBMeasureItem(HWND hwndLB, MEASUREITEMSTRUCT *lpmi)
  287. {
  288. RECT rWnd;
  289. int wWnd;
  290. HDC hDC;
  291. HFONT hfontOld;
  292. PTASK pTask;
  293. // Get the Height and Width of the child window
  294. GetWindowRect (hwndLB, &rWnd);
  295. wWnd = rWnd.right - rWnd.left;
  296. lpmi->itemWidth = wWnd;
  297. pTask = (PTASK)lpmi->itemData;
  298. hDC= GetDC(NULL);
  299. if( (hfontOld = SelectObject(hDC,g_hBoldFont)) != 0 )
  300. {
  301. rWnd.top = 0;
  302. rWnd.left = CXBORDER*2 + g_cxSmIcon;
  303. rWnd.right = lpmi->itemWidth - rWnd.left - CXBORDER*2 - g_cxSmIcon;
  304. rWnd.bottom = 0;
  305. DrawText(hDC,pTask->Text, lstrlen(pTask->Text),&rWnd, DT_CALCRECT | DT_WORDBREAK );
  306. SelectObject(hDC, hfontOld);
  307. }
  308. ReleaseDC(NULL,hDC);
  309. lpmi->itemHeight = rWnd.bottom + 2*CXBORDER;
  310. return TRUE;
  311. }
  312. //---------------------------------------------------------------------------
  313. //***************************************************************************
  314. //
  315. // <Function>()
  316. // <Explanation>
  317. //
  318. // ENTRY:
  319. // <Params>
  320. //
  321. // EXIT:
  322. // <Params>
  323. //
  324. //***************************************************************************
  325. LRESULT _HandleMeasureItem(HWND hwnd, MEASUREITEMSTRUCT *lpmi)
  326. {
  327. if (lpmi->CtlType == ODT_LISTBOX)
  328. return _HandleLBMeasureItem(hwnd, lpmi);
  329. return TRUE;
  330. }
  331. //---------------------------------------------------------------------------
  332. //***************************************************************************
  333. //
  334. // _HandleLBDrawItem()
  335. // Draws the Title, Text, and icon for an entry.
  336. //
  337. // ENTRY:
  338. // HWND and the Item to draw.
  339. //
  340. // EXIT:
  341. // <Params>
  342. //
  343. //***************************************************************************
  344. LRESULT _HandleLBDrawItem(HWND hwndLB, DRAWITEMSTRUCT *lpdi)
  345. {
  346. RECT rc;
  347. HFONT hfontOld;
  348. int xArrow,y;
  349. PTASK pTask;
  350. BITMAP bm;
  351. HGDIOBJ hbmArrow,hbmOld;
  352. // Don't draw anything for an empty list.
  353. if ((int)lpdi->itemID < 0)
  354. return TRUE;
  355. pTask = (PTASK)lpdi->itemData;
  356. if(pTask == (PTASK)LB_ERR || !pTask )
  357. return FALSE;
  358. if ((lpdi->itemAction & ODA_SELECT) || (lpdi->itemAction & ODA_DRAWENTIRE))
  359. {
  360. // Put in the Title text
  361. hfontOld = SelectObject(lpdi->hDC,(lpdi->itemState & ODS_SELECTED)?g_hBoldFont:g_hfont);
  362. ExtTextOut(lpdi->hDC,
  363. lpdi->rcItem.left+ CXBORDER*2 + g_cxSmIcon,
  364. lpdi->rcItem.top+CXBORDER,
  365. ETO_OPAQUE,
  366. &lpdi->rcItem,
  367. NULL, 0,
  368. NULL);
  369. rc.top = lpdi->rcItem.top + CXBORDER;
  370. rc.left = lpdi->rcItem.left + CXBORDER*2 + g_cxSmIcon;
  371. rc.right = lpdi->rcItem.right;
  372. rc.bottom = lpdi->rcItem.bottom;
  373. DrawText( lpdi->hDC,
  374. pTask->Text, lstrlen(pTask->Text),
  375. &rc,
  376. DT_WORDBREAK);
  377. SelectObject(lpdi->hDC, hfontOld);
  378. // Draw the little triangle thingies.
  379. if(lpdi->itemState & ODS_SELECTED)
  380. {
  381. if (!g_hdcMem)
  382. {
  383. g_hdcMem = CreateCompatibleDC(lpdi->hDC);
  384. }
  385. // selected SRCSTENCIL=0x00d8074a
  386. // not selected SRCAND.
  387. if (g_hdcMem)
  388. {
  389. hbmArrow = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW));
  390. GetObject(hbmArrow, sizeof(bm), &bm);
  391. hbmOld = SelectObject(g_hdcMem, hbmArrow);
  392. xArrow = lpdi->rcItem.left + CXBORDER; // - bm.bmWidth;
  393. y = ((g_SizeTextExt.cy - bm.bmHeight)/2) + CXBORDER + lpdi->rcItem.top;
  394. BitBlt(lpdi->hDC, xArrow, y, bm.bmWidth, bm.bmHeight, g_hdcMem, 0, 0, SRCAND); // dwRop);
  395. SelectObject(g_hdcMem, hbmOld);
  396. DeleteObject(hbmArrow);
  397. }
  398. }
  399. }
  400. return TRUE;
  401. }
  402. //---------------------------------------------------------------------------
  403. LRESULT _HandleCtlColorListbox(HWND hwnd, HDC hdc)
  404. {
  405. SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
  406. return (LRESULT) g_hbrBkGnd;
  407. }
  408. //---------------------------------------------------------------------------
  409. LRESULT _HandleDrawItem(HWND hwnd, DRAWITEMSTRUCT *lpdi)
  410. {
  411. if (lpdi->CtlType == ODT_LISTBOX)
  412. return _HandleLBDrawItem(hwnd, lpdi);
  413. return TRUE;
  414. }
  415. //---------------------------------------------------------------------------
  416. LRESULT _HandleDeleteItem(HWND hwnd, DELETEITEMSTRUCT *lpdi)
  417. {
  418. if(lpdi)
  419. if(lpdi->itemData)
  420. {
  421. LocalFree( (HLOCAL)lpdi->itemData );
  422. return TRUE;
  423. }
  424. return FALSE;
  425. }
  426. //***************************************************************************
  427. //
  428. // ShrinkToFit()
  429. // Makes the List box no bigger then it has to be
  430. // makes the parent window rsize to the LB size.
  431. //
  432. // ENTRY:
  433. // hwnd Parent
  434. // hwnd List box
  435. //
  436. // EXIT:
  437. //
  438. //***************************************************************************
  439. void ShrinkToFit( HWND hWnd, HWND hLb )
  440. {
  441. LONG lCount;
  442. LONG lNumItems;
  443. LONG lTotalHeight;
  444. LONG lHeight;
  445. RECT rWnd;
  446. LONG lChange;
  447. lNumItems = (LONG)SendMessage( hLb, LB_GETCOUNT, 0, 0L );
  448. lTotalHeight =0;
  449. for( lCount=0;lCount<lNumItems; lCount++ )
  450. {
  451. lHeight = (LONG)SendMessage( hLb, LB_GETITEMHEIGHT, lCount, 0L );
  452. lTotalHeight+=lHeight;
  453. }
  454. // Set the height of the ListBox to the number of items in it.
  455. GetWindowRect (hLb, &rWnd);
  456. SetWindowPos( hLb, hWnd, 0,0,
  457. rWnd.right - rWnd.left - (CXBORDER*2 + g_cxSmIcon) ,
  458. lTotalHeight,
  459. SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER );
  460. // Work out how much it changed in height
  461. lChange = lTotalHeight - (rWnd.bottom-rWnd.top);
  462. // Size the parent to fit around the child.
  463. GetWindowRect(hWnd, &rWnd);
  464. SetWindowPos( hWnd,0, 0,0,
  465. rWnd.right - rWnd.left,
  466. rWnd.bottom-rWnd.top + lChange,
  467. SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER );
  468. }
  469. //***************************************************************************
  470. //
  471. // <Function>()
  472. // <Explanation>
  473. //
  474. // ENTRY:
  475. // <Params>
  476. //
  477. // EXIT:
  478. // <Params>
  479. //
  480. //***************************************************************************
  481. LRESULT CALLBACK dlgProcRunOnce(
  482. HWND hWnd, // window handle
  483. UINT message, // type of message
  484. WPARAM uParam, // additional information
  485. LPARAM lParam) // additional information
  486. {
  487. int wmId, wmEvent;
  488. HANDLE hThread;
  489. switch (message)
  490. {
  491. case WM_DELETEITEM:
  492. return _HandleDeleteItem( hWnd, (LPDELETEITEMSTRUCT)lParam );
  493. case WM_MEASUREITEM:
  494. return _HandleMeasureItem(hWnd, (MEASUREITEMSTRUCT *) lParam);
  495. case WM_DRAWITEM:
  496. return _HandleDrawItem(hWnd, (DRAWITEMSTRUCT *) lParam);
  497. case WM_INITDIALOG:
  498. CreateGlobals( hWnd );
  499. DoAnyRandomOneTimeStuff();
  500. g_fCleanBoot = GetSystemMetrics(SM_CLEANBOOT);
  501. TopLeftWindow( hWnd, GetParent(hWnd) );
  502. RunOnceFill( GetDlgItem(hWnd,IDC_LIST2) );
  503. // Now calculate the size needed for the LB and resize LB and parent.
  504. ShrinkToFit( hWnd, GetDlgItem(hWnd,IDC_LIST2));
  505. hThread = CreateThread(NULL, 0, RunAppsInList, (LPVOID)GetDlgItem(hWnd,IDC_LIST2),0, &g_dwThread );
  506. CloseHandle(hThread);
  507. break;
  508. case WM_FINISHED:
  509. EndDialog(hWnd,0);
  510. // DestroyWindow(hWnd);
  511. break;
  512. case WM_CTLCOLORLISTBOX:
  513. return _HandleCtlColorListbox((HWND)lParam, (HDC)uParam);
  514. case WM_COMMAND: // message: command from application menu
  515. wmId = LOWORD(uParam);
  516. wmEvent = HIWORD(uParam);
  517. if( wmEvent==LBN_SELCHANGE )
  518. {
  519. // LaunchApp( (HWND) lParam, LOWORD(uParam) );
  520. // De-select the item now.
  521. break;
  522. }
  523. else
  524. switch (wmId)
  525. {
  526. case IDOK:
  527. EndDialog( hWnd, wmId);
  528. break;
  529. default:
  530. // return (DefWindowProc(hWnd, message, uParam, lParam));
  531. break;
  532. }
  533. break;
  534. default: // Passes it on if unproccessed
  535. // return (DefWindowProc(hWnd, message, uParam, lParam));
  536. return FALSE;
  537. }
  538. return TRUE;
  539. }