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.5 KiB

  1. /****************************************************************************
  2. Copyright (c) Microsoft Corporation 1997
  3. All rights reserved
  4. ***************************************************************************/
  5. #include "pch.h"
  6. #include <windowsx.h>
  7. #include <prsht.h>
  8. #include <lm.h>
  9. #include "dialogs.h"
  10. DEFINE_MODULE("Main");
  11. // Globals
  12. HINSTANCE g_hinstance = NULL;
  13. HANDLE g_hGraphic = NULL;
  14. OPTIONS g_Options;
  15. // Constants
  16. #define NUMBER_OF_PAGES 10
  17. typedef struct _DLGTEMPLATE2 {
  18. WORD DlgVersion;
  19. WORD Signature;
  20. DWORD HelpId;
  21. DWORD StyleEx;
  22. DWORD Style;
  23. WORD cDlgItems;
  24. short x;
  25. short y;
  26. short cx;
  27. short cy;
  28. } DLGTEMPLATE2;
  29. HPALETTE
  30. CreateDIBPalette(
  31. LPBITMAPINFO pbi,
  32. int *piColorCount )
  33. {
  34. LPBITMAPINFOHEADER pbih;
  35. HPALETTE hPalette;
  36. pbih = (LPBITMAPINFOHEADER) pbi;
  37. //
  38. // No palette needed for >= 16 bpp
  39. //
  40. *piColorCount = (pbih->biBitCount <= 8)
  41. ? (1 << pbih->biBitCount)
  42. : 0;
  43. if ( *piColorCount )
  44. {
  45. LPLOGPALETTE pLogPalette;
  46. pLogPalette =
  47. (LPLOGPALETTE) TraceAlloc( GMEM_FIXED,
  48. sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * ( *piColorCount)) );
  49. if( !pLogPalette )
  50. {
  51. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  52. return NULL;
  53. }
  54. pLogPalette->palVersion = 0x300;
  55. pLogPalette->palNumEntries = *piColorCount;
  56. for( int i = 0; i < *piColorCount; i++ )
  57. {
  58. pLogPalette->palPalEntry[i].peRed = pbi->bmiColors[i].rgbRed;
  59. pLogPalette->palPalEntry[i].peGreen = pbi->bmiColors[i].rgbGreen;
  60. pLogPalette->palPalEntry[i].peBlue = pbi->bmiColors[i].rgbBlue;
  61. pLogPalette->palPalEntry[i].peFlags = 0;
  62. }
  63. hPalette = CreatePalette( pLogPalette );
  64. TraceFree( pLogPalette );
  65. }
  66. else
  67. {
  68. hPalette = NULL;
  69. }
  70. return hPalette;
  71. }
  72. //
  73. // Retreives device-independent bitmap data and a color table from a
  74. // bitmap in a resource.
  75. //
  76. BOOL
  77. GetBitmapDataAndPalette(
  78. HINSTANCE g_hinstance,
  79. LPCTSTR pszId,
  80. HPALETTE *phPalette,
  81. PINT piColorCount,
  82. CONST BITMAPINFOHEADER **ppbih )
  83. {
  84. BOOL fResult = FALSE;
  85. HRSRC hBlock = NULL;
  86. HGLOBAL hResource = NULL;
  87. //
  88. // None of FindResource(), LoadResource(), or LockResource()
  89. // need to have cleanup routines called in Win32.
  90. //
  91. hBlock = FindResource( g_hinstance, pszId, RT_BITMAP );
  92. if( !hBlock )
  93. goto Error;
  94. hResource = LoadResource( g_hinstance, hBlock );
  95. if( !hResource )
  96. goto Error;
  97. *ppbih = (LPBITMAPINFOHEADER) LockResource( hResource );
  98. if( *ppbih == NULL )
  99. goto Error;
  100. *phPalette = CreateDIBPalette( (LPBITMAPINFO) *ppbih, piColorCount );
  101. fResult = TRUE;
  102. Error:
  103. return fResult;
  104. }
  105. //
  106. // Property sheet callback to handle the initialization of the watermark.
  107. //
  108. int CALLBACK
  109. Winnt32SheetCallback(
  110. IN HWND hDlg,
  111. IN UINT uMsg,
  112. IN LPARAM lParam
  113. )
  114. {
  115. switch( uMsg )
  116. {
  117. case PSCB_PRECREATE:
  118. {
  119. DLGTEMPLATE *DlgTemplate;
  120. //
  121. // Make sure we get into the foreground.
  122. //
  123. DlgTemplate = (DLGTEMPLATE *)lParam;
  124. DlgTemplate->style &= ~DS_CONTEXTHELP;
  125. DlgTemplate->style |= DS_SETFOREGROUND;
  126. }
  127. break;
  128. case PSCB_INITIALIZED:
  129. {
  130. //
  131. // Load the watermark bitmap and override the dialog procedure for the wizard.
  132. //
  133. HDC hdc;
  134. WNDPROC OldWizardProc;
  135. CenterDialog( hDlg );
  136. hdc = GetDC(NULL);
  137. GetBitmapDataAndPalette(
  138. g_hinstance,
  139. (!hdc || (GetDeviceCaps(hdc,BITSPIXEL) < 8))
  140. ? MAKEINTRESOURCE(IDB_WATERMARK16) : MAKEINTRESOURCE(IDB_WATERMARK256),
  141. &g_hWatermarkPalette,
  142. &g_uWatermarkPaletteColorCount,
  143. &g_pbihWatermark );
  144. g_pWatermarkBitmapBits = (LPBYTE)g_pbihWatermark
  145. + g_pbihWatermark->biSize + (g_uWatermarkPaletteColorCount * sizeof(RGBQUAD));
  146. if(hdc)
  147. ReleaseDC(NULL,hdc);
  148. g_OldWizardProc =
  149. (WNDPROC) SetWindowLong( hDlg, DWL_DLGPROC, (LONG) WizardDlgProc );
  150. }
  151. break;
  152. }
  153. return(0);
  154. }
  155. //
  156. // Adds a page to the dialog.
  157. //
  158. void
  159. AddPage(
  160. LPPROPSHEETHEADER ppsh,
  161. UINT id,
  162. DLGPROC pfn )
  163. {
  164. PROPSHEETPAGE psp;
  165. ZeroMemory( &psp, sizeof(psp) );
  166. psp.dwSize = sizeof(psp);
  167. psp.dwFlags = PSP_DEFAULT | PSP_HASHELP | PSP_USETITLE;
  168. psp.pszTitle = MAKEINTRESOURCE( IDS_APPNAME );
  169. psp.hInstance = ppsh->hInstance;
  170. psp.pszTemplate = MAKEINTRESOURCE(id);
  171. psp.pfnDlgProc = pfn;
  172. ppsh->phpage[ ppsh->nPages ] = CreatePropertySheetPage( &psp );
  173. if ( ppsh->phpage[ ppsh->nPages ] )
  174. ppsh->nPages++;
  175. }
  176. //
  177. // Creates the UI pages and kicks off the property sheet.
  178. //
  179. HRESULT
  180. InitSetupPages( )
  181. {
  182. HRESULT hr = S_OK;
  183. HPROPSHEETPAGE rPages[ NUMBER_OF_PAGES ];
  184. PROPSHEETHEADER pshead;
  185. ZeroMemory( &pshead, sizeof(pshead) );
  186. pshead.dwSize = sizeof(pshead);
  187. pshead.dwFlags = PSH_WIZARD | PSH_PROPTITLE | PSH_USEHICON |
  188. PSH_USECALLBACK;
  189. pshead.hwndParent = NULL;
  190. pshead.nStartPage = 0;
  191. pshead.hInstance = g_hinstance;
  192. pshead.pszCaption = MAKEINTRESOURCE( IDS_APPNAME );
  193. pshead.nPages = 0;
  194. pshead.phpage = rPages;
  195. pshead.hIcon = LoadIcon( g_hinstance, MAKEINTRESOURCE( IDI_SETUP ) );
  196. pshead.pfnCallback = Winnt32SheetCallback;
  197. AddPage( &pshead, IDD_WELCOME, (DLGPROC) WelcomeDlgProc );
  198. AddPage( &pshead, IDD_RBDIRECTORY, (DLGPROC) RemoteBootDlgProc );
  199. AddPage( &pshead, IDD_OS, (DLGPROC) OSDlgProc );
  200. AddPage( &pshead, IDD_SETUPDIR, (DLGPROC) SourceDlgProc );
  201. AddPage( &pshead, IDD_INFO, (DLGPROC) InfoDlgProc );
  202. AddPage( &pshead, IDD_SETUP, (DLGPROC) SetupDlgProc );
  203. AddPage( &pshead, IDD_FINISH, (DLGPROC) FinishDlgProc );
  204. if( PropertySheet( &pshead ) == -1)
  205. {
  206. hr = E_FAIL;
  207. }
  208. RRETURN(hr);
  209. }
  210. //
  211. // Initializes g_Options.
  212. //
  213. void
  214. InitializeOptions( void )
  215. {
  216. TCHAR sz[ MAX_PATH ];
  217. LPSHARE_INFO_502 psi;
  218. DWORD dw;
  219. dw = LoadString( g_hinstance, IDS_DEFAULTPATH, sz, ARRAYSIZE( sz ) );
  220. Assert( dw );
  221. dw = ExpandEnvironmentStrings( sz, g_Options.szRemoteBootPath, ARRAYSIZE( szRemoteBootPath ) );
  222. Assert( dw );
  223. dw = LoadString( g_hinstance, IDS_DEFAULTSETUP, g_Options.szName, ARRAYSIZE( g_Options.szName ) );
  224. Assert( dw );
  225. g_Options.szSourcePath[ 0 ] = 0;
  226. g_Options.fCreateDirectory = FALSE;
  227. g_Options.fError = FALSE;
  228. g_Options.fAbort = FALSE;
  229. g_Options.fKnowRBDirectory = FALSE;
  230. dw = LoadString( g_hinstance, IDS_REMOTEBOOTSHARENAME, sz, ARRAYSIZE( sz ) );
  231. Assert( dw );
  232. if ( NERR_Success == NetShareGetInfo( NULL, sz, 502, (LPBYTE *)&psi ) )
  233. {
  234. lstrcpy( g_Options.szRemoteBootPath, psi->shi502_path );
  235. g_Options.fKnowRBDirectory = TRUE;
  236. }
  237. }
  238. //
  239. // WinMain()
  240. //
  241. int APIENTRY
  242. WinMain(
  243. HINSTANCE hInstance,
  244. HINSTANCE hPrevInstance,
  245. LPSTR lpCmdLine,
  246. int nCmdShow)
  247. {
  248. HANDLE hMutex;
  249. HRESULT hr = E_FAIL;
  250. g_hinstance = hInstance;
  251. INITIALIZE_TRACE_MEMORY;
  252. // allow only one instance running at a time
  253. TraceMsgDo( hMutex = CreateMutex( NULL, TRUE, TEXT("RemoteBootSetup.Mutext")),
  254. "V hMutex = 0x%08x\n" );
  255. if ((hMutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS))
  256. {
  257. //
  258. // TODO: Do something fancy like find the other instance and
  259. // bring it to the foreground.
  260. //
  261. goto Cleanup;
  262. }
  263. g_hGraphic = LoadImage( g_hinstance, MAKEINTRESOURCE( IDB_BUTTON ), IMAGE_BITMAP,
  264. 0, 0, LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  265. Assert( g_hGraphic );
  266. DebugMemoryAddHandle( g_hGraphic );
  267. InitializeOptions( );
  268. hr = THR( InitSetupPages( ) );
  269. Cleanup:
  270. if ( hMutex )
  271. CloseHandle( hMutex );
  272. if ( g_hGraphic )
  273. {
  274. DebugMemoryDelete( g_hGraphic );
  275. DeleteObject( g_hGraphic );
  276. }
  277. UNINITIALIZE_TRACE_MEMORY;
  278. RRETURN(hr);
  279. }
  280. // stolen from the CRT, used to shrink our code
  281. int _stdcall ModuleEntry(void)
  282. {
  283. int i;
  284. STARTUPINFOA si;
  285. LPSTR pszCmdLine = GetCommandLineA();
  286. if ( *pszCmdLine == '\"' )
  287. {
  288. /*
  289. * Scan, and skip over, subsequent characters until
  290. * another double-quote or a null is encountered.
  291. */
  292. while ( *++pszCmdLine && (*pszCmdLine != '\"') );
  293. /*
  294. * If we stopped on a double-quote (usual case), skip
  295. * over it.
  296. */
  297. if ( *pszCmdLine == '\"' )
  298. pszCmdLine++;
  299. }
  300. else
  301. {
  302. while (*pszCmdLine > ' ')
  303. pszCmdLine++;
  304. }
  305. /*
  306. * Skip past any white space preceeding the second token.
  307. */
  308. while (*pszCmdLine && (*pszCmdLine <= ' '))
  309. {
  310. pszCmdLine++;
  311. }
  312. si.dwFlags = 0;
  313. GetStartupInfoA(&si);
  314. i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine,
  315. si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
  316. ExitProcess(i);
  317. return i; // We never come here.
  318. }