Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1897 lines
51 KiB

/*
03.13.96 Joe Holman (joehol) Ported from Win95 to NT.
Issues:
- for Win95, we want to show:
- WINNT Setup
- Explore the CD
- for WinNT, we want to show:
- WINNT32.EXE Setup
- Explore the CD
- Add Remove Programs
- The following value is used in WinMain to help not display the applet
when some NT Setup thing is asking for the OS CD. Currently, we do not
have any windows with this object for NT. Perhaps maybe we will for 5.0.
static const char c_szAutoRunPrevention[] = "__WinNTSetupDiskQuery";
- Anybody have any problem with version checking - Win95 checked it before:
if (!CheckVersionConsistency(data))
*/
//---------------------------------------------------------------------------
// AutoRun applet.
//---------------------------------------------------------------------------
#include "autorun.h"
#include "resource.h"
#include <mmsystem.h>
#include <regstr.h>
#include <string.h>
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
//---------------------------------------------------------------------------
// define this to force 4bit mode in debug builds
//#define FORCE_CRAP
//---------------------------------------------------------------------------
// appwide globals
HINSTANCE g_hinst = NULL;
BOOL g_fCrapForColor = FALSE;
BOOL g_fNeedPalette = FALSE;
BOOL g_fMouseAvailable = FALSE;
//---------------------------------------------------------------------------
// file globals
BOOL g_fAppDisabled = TRUE;
HHOOK g_hMouseHook = NULL;
HWND g_hMainWindow = NULL; // less of a pain for our mouse hook to see
int g_iActiveButton = -2; // less of a pain for our mouse hook to see
const RGBQUAD g_rgbBlack = {0};
const RGBQUAD g_rgbWhite = {0xFF, 0xFF, 0xFF, 0};
#pragma data_seg(".text")
static const char c_szAutoRunPrevention[] = "__WinNTSetupDiskQuery";
static const char c_szAutoRunClass[] = "AutoRunMain";
static const char c_szNULL[] = "";
static const char c_szArial[] = "Arial";
static const char c_szButtonClass[] = "Button";
static const char c_szSetupKey[] = REGSTR_PATH_SETUP "\\SETUP";
static const char c_szExpoSwitch[] = "Expostrt";
#pragma data_seg()
char szAppTitle[MAX_PATH];
CHAR dbgStr[MAX_PATH];
BOOL bWin95 = FALSE;
//---------------------------------------------------------------------------
// private messages
#define ARM_MOUSEOVER (WM_APP)
//---------------------------------------------------------------------------
// states for tracking mouse over buttons
#define BTNST_DEAD (0)
#define BTNST_UP (1)
#define BTNST_DOWN (2)
#define BTNST_UNDOWN (3)
//---------------------------------------------------------------------------
// how to root a relative path (if at all)
#define NOROOT (0x00000000)
#define ONACD (0x00000001)
#define INWIN (0x00000002)
#define INSYS (0x00000003)
#define ALLROOTS (0x00000003)
#define ROOTED(app,parms,dir) \
((((DWORD)app)<<6)|(((DWORD)parms)<<3)|(DWORD)dir)
#define CMD_ROOT(item) ((((DWORD)item)>>6)&ALLROOTS)
#define PARAMS_ROOT(item) ((((DWORD)item)>>3)&ALLROOTS)
#define DEFDIR_ROOT(item) (((DWORD)item)&ALLROOTS)
#define BUTTON_IMAGE_X_SIZE (59)
#define BUTTON_IMAGE_Y_SIZE (59)
#define NORMAL_IMAGE_X_OFFSET (0)
#define FOCUS_IMAGE_X_OFFSET (BUTTON_IMAGE_X_SIZE)
#define SELECTED_IMAGE_X_OFFSET (2 * BUTTON_IMAGE_X_SIZE)
#define DISABLED_IMAGE_X_OFFSET (3 * BUTTON_IMAGE_X_SIZE)
#define BUTTON_DEFAULT_CX (BUTTON_IMAGE_X_SIZE)
#define BUTTON_DEFAULT_CY (BUTTON_IMAGE_Y_SIZE)
#define BUTTON_LABEL_RECT { -160, 17, -20, 66 }
#define DEF_BUTTON_LABEL_HEIGHT (19)
#define AUTORUN_DESCRIPTION_LEFT (36)
#define AUTORUN_DESCRIPTION_TOP (313)
#define AUTORUN_DESCRIPTION_RIGHT (360)
#define AUTORUN_4BIT_TEXTCOLOR RGB(192,192,192)
#define AUTORUN_4BIT_HIGHLIGHT RGB(255,255,255)
#define AUTORUN_4BIT_DISABLED RGB(127,127,127)
#define AUTORUN_4BIT_DESCRIPTION RGB(192,192,192)
//#define AUTORUN_8BIT_TEXTCOLOR PALETTERGB( 75, 90,129)
//#define AUTORUN_8BIT_HIGHLIGHT RGB(000,000,000)
//#define AUTORUN_8BIT_DISABLED PALETTERGB(107,136,185)
//#define AUTORUN_8BIT_DESCRIPTION RGB(000,000,000)
#define AUTORUN_8BIT_TEXTCOLOR PALETTERGB(125,125,125)
#define AUTORUN_8BIT_HIGHLIGHT RGB(175,175,175)
#define AUTORUN_8BIT_DISABLED PALETTERGB(107,136,185)
#define AUTORUN_8BIT_DESCRIPTION RGB(220,220,220)
#define BUTTON_X_PLACEMENT (519)
#define BUTTON_Y_MARGIN (9)
#define SHADOW_FACTOR (930)
#define LABEL_VERIFY_TIMER (0)
//---------------------------------------------------------------------------
typedef struct
{
int res; // base for all resources this button owns
DWORD rooting; // packed info on how to root paths for the command
int xpos, ypos; // location of button in window
RECT face; // client coordinates of actual button image on video
RECT textrect; // parent coordinates of accompanying label text
BOOL abdicated; // did we just release the capture?
int state; // what are we doing?
HWND window; // handle of button control
WNDPROC oldproc; // original window procedure
BOOL isdorky; // is this a dorky icon button?
char text[64]; // the label for the button
char description[256]; // the description of the button's function
} AUTORUNBTN;
//---------------------------------------------------------------------------
AUTORUNBTN g_ButtonInfo[] =
{
// { WINTOUR, ROOTED(ONACD, NOROOT, ONACD), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
// { MSEXPO, ROOTED(ONACD, NOROOT, ONACD), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
// { HOVER, ROOTED(ONACD, NOROOT, ONACD), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
// { VIDEOS, ROOTED(NOROOT, ONACD, ONACD), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
{ NTSETUP, ROOTED(ONACD, NOROOT, ONACD), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
{ EXPLORECD, ROOTED(NOROOT, ONACD, ONACD), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
{ OCSETUP, ROOTED(NOROOT, NOROOT, INSYS), 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, FALSE, 0, NULL, NULL, FALSE, 0 },
};
//#define IDAB_WINTOUR 0
//#define IDAB_MSEXPO 1
//#define IDAB_HOVER 2
//#define IDAB_VIDEOS 3
//#define IDAB_EXPLORECD 4
//#define IDAB_OCSETUP 5
#define IDAB_NTSETUP 0
#define IDAB_EXLPORECD 1
#define IDAB_OCSETUP 2
#define AUTORUN_NUM_BUTTONS (sizeof(g_ButtonInfo)/sizeof(g_ButtonInfo[0]))
//---------------------------------------------------------------------------
typedef struct
{
HWND window; // main app window
HDC image; // source dc with our cool backdrop
HBITMAP oldbmp; // the default bitmap from the dc above
HDC btnimage; // source dc with our cool buttons
HBITMAP oldbtnbmp; // the default bitmap from the dc above
HPALETTE palette; // our app's palette (if any)
HFONT textfont; // font for labels
RECT descrect; // client coordinates of description text
int wndheight; // height of client area
COLORREF clrnormal; // normal text color
COLORREF clrhigh; // highlighted text color
COLORREF clrdisable; // disabled text color
COLORREF clrdescription; // disabled text color
BOOL keyboard; // whether the app is under keyboard control
} AUTORUNDATA;
BOOL PathAppend( char * prefix, const char * spec) {
//wsprintf ( dbgStr, "myPathAppend: prefix = %s, spec = %s", prefix, spec );
//MessageBox ( NULL, dbgStr, "", MB_ICONASTERISK );
strcat ( prefix, spec );
return TRUE;
}
BOOL PathFileExists ( LPCSTR FileName ) {
/*++
Routine Description:
Determine if a file exists and is accessible.
Errormode is set (and then restored) so the user will not see
any pop-ups.
Arguments:
FileName - supplies full path of file to check for existance.
Return Value:
TRUE if the file exists and is accessible.
FALSE if not. GetLastError() returns extended error info.
--*/
WIN32_FIND_DATA FindData;
HANDLE FindHandle;
BOOL b;
UINT OldMode;
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
FindHandle = FindFirstFile(FileName,&FindData);
if(FindHandle == INVALID_HANDLE_VALUE) {
b = FALSE;
} else {
FindClose(FindHandle);
b = TRUE;
}
SetErrorMode(OldMode);
return(b);
}
/////////////////////////////////////////////////////////////////////////////
// randomness
/////////////////////////////////////////////////////////////////////////////
LONG WINAPI AnotherStrToLong(LPCSTR sz)
{
long l=0;
BOOL fNeg = (*sz == '-');
if (fNeg)
sz++;
while (*sz >= '0' && *sz <= '9')
l = l*10 + (*sz++ - '0');
if (fNeg)
l *= -1L;
return l;
}
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
/*** this stuff uses the bitmap array - we won't use it.
BOOL AssembleButtonImagesReal(AUTORUNDATA *data, HDC cellimage, HDC srcimage,
SIZE size)
{
RGBQUAD rgbSrc[256], rgbCell[256], rgbMask[256] = {0};
HBITMAP dstbmp = CreateCompatibleBitmap(data->image, size.cx, size.cy);
UINT uColors, uSrcColors, u;
int iButton;
//
// set up the destination dc
//
if (!dstbmp)
return FALSE;
if ((data->btnimage = CreateCompatibleDC(data->image)) == NULL)
{
DeleteBitmap(dstbmp);
return FALSE;
}
data->oldbtnbmp = SelectBitmap(data->btnimage, dstbmp);
//
// build a tile of the cell backgrounds based on button positions
//
for (iButton = 0; iButton < AUTORUN_NUM_BUTTONS; iButton++)
{
AUTORUNBTN *pButton = g_ButtonInfo + iButton;
if (pButton->res != -1)
{
BOOL b;
int xsrc = pButton->xpos;
int ysrc = pButton->ypos;
int xdst, ydst = iButton * BUTTON_IMAGE_Y_SIZE;
for (xdst = 0; xdst < size.cx; xdst += BUTTON_IMAGE_X_SIZE)
{
b = BitBlt(cellimage, xdst, ydst, BUTTON_IMAGE_X_SIZE,
BUTTON_IMAGE_Y_SIZE, data->image, xsrc, ysrc,
SRCCOPY);
}
}
}
//
// copy the entire cell backgrounds to the destination image
//
BitBlt(data->btnimage, 0, 0, size.cx, size.cy, cellimage, 0, 0, SRCCOPY);
//
// save the color table of the source image for posterity
//
uSrcColors = GetDIBColorTable(srcimage, 0, 256, rgbSrc);
//
// mask out holes on the destination for the buttons and shadows
//
rgbMask[0] = g_rgbWhite;
SetDIBColorTable(srcimage, 0, uSrcColors, rgbMask);
BitBlt(data->btnimage, 0, 0, size.cx, size.cy, srcimage, 0, 0, SRCAND);
//
// dim the background cells to produce the shadow image
//
u = uColors = GetDIBColorTable(cellimage, 0, 256, rgbCell);
while (u--)
{
rgbCell[u].rgbBlue =
(BYTE)(SHADOW_FACTOR * (UINT)rgbCell[u].rgbBlue / 1000);
rgbCell[u].rgbGreen =
(BYTE)(SHADOW_FACTOR * (UINT)rgbCell[u].rgbGreen / 1000);
rgbCell[u].rgbRed =
(BYTE)(SHADOW_FACTOR * (UINT)rgbCell[u].rgbRed / 1000);
}
SetDIBColorTable(cellimage, 0, uColors, rgbCell);
//
// mask out the shadows and add them to the destination image
//
rgbMask[0] = g_rgbBlack;
rgbMask[1] = g_rgbWhite;
SetDIBColorTable(srcimage, 0, uSrcColors, rgbMask);
BitBlt(cellimage, 0, 0, size.cx, size.cy, srcimage, 0, 0, SRCAND);
BitBlt(data->btnimage, 0, 0, size.cx, size.cy, cellimage, 0, 0, SRCPAINT);
//
// mask out the button faces and add them to the destination image
//
rgbSrc[0] = rgbSrc[1] = g_rgbBlack;
SetDIBColorTable(srcimage, 0, uSrcColors, rgbSrc);
BitBlt(data->btnimage, 0, 0, size.cx, size.cy, srcimage, 0, 0, SRCPAINT);
// all done
return TRUE;
}
//---------------------------------------------------------------------------
BOOL AssembleButtonImages(AUTORUNDATA *data)
{
BOOL result = FALSE;
HBITMAP hbmSrc = LoadImage(HINST_THISAPP,
MAKEINTRESOURCE(IDB_8BPP_BUTTONS), IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION);
if (hbmSrc)
{
HDC hdcSrc = CreateCompatibleDC(data->image);
BITMAP bm;
GetObject(hbmSrc, sizeof(bm), &bm);
if (hdcSrc)
{
HBITMAP hbmSrcOld = SelectBitmap(hdcSrc, hbmSrc);
SIZE size = {bm.bmWidth, bm.bmHeight};
HBITMAP hbmTmp =
CreateCompatibleBitmap(data->image, size.cx, size.cy);
if (hbmTmp)
{
HDC hdcTmp = CreateCompatibleDC(data->image);
if (hdcTmp)
{
HBITMAP hbmTmpOld = SelectBitmap(hdcTmp, hbmTmp);
result = AssembleButtonImagesReal(data, hdcTmp, hdcSrc,
size);
SelectBitmap(hdcTmp, hbmTmpOld);
DeleteDC(hdcTmp);
}
DeleteBitmap(hbmTmp);
}
SelectBitmap(hdcSrc, hbmSrcOld);
DeleteDC(hdcSrc);
}
DeleteBitmap(hbmSrc);
}
return result;
}
*/
//---------------------------------------------------------------------------
LRESULT CALLBACK
AutoRunButtonSubclassProc(HWND window, UINT msg, WPARAM wp, LPARAM lp)
{
int index = (int)GetWindowLong(window, GWL_ID);
if ((index >= 0) && (index < AUTORUN_NUM_BUTTONS))
{
if (msg == WM_KEYDOWN)
PostMessage(GetParent(window), msg, wp, lp);
return CallWindowProc((g_ButtonInfo + index)->oldproc,
window, msg, wp, lp);
}
return 0L;
}
//---------------------------------------------------------------------------
#define DORKYBUTTONSTYLE \
(WS_CHILD | WS_VISIBLE | BS_ICON | BS_CENTER | BS_VCENTER)
HWND AutoRunCreateDorkyButton(AUTORUNDATA *data, AUTORUNBTN *button)
{
HICON icon = LoadIcon(HINST_THISAPP, IDI_ICON(button->res));
HWND child = NULL;
if (icon) {
child = CreateWindow(c_szButtonClass, c_szNULL, DORKYBUTTONSTYLE,
0, 0, 0, 0, data->window, NULL, HINST_THISAPP, 0);
if (child) {
button->isdorky = TRUE;
SendMessage(child, BM_SETIMAGE, MAKEWPARAM(IMAGE_ICON,0),(LPARAM)icon);
}
// remove this debugging later
else {
//wsprintf ( dbgStr, "CreateWindow FAILed. gle = %ld, res = %ld", GetLastError(), button->res );
//MessageBox ( NULL, dbgStr, szAppName, MB_ICONASTERISK );
}
}
// remove this debugging later
else {
//wsprintf ( dbgStr, "LoadIcon FAILed. gle = %ld, res = %ld", GetLastError(), button->res );
//MessageBox ( NULL, dbgStr, szAppName, MB_ICONASTERISK );
}
return child;
}
//---------------------------------------------------------------------------
#define COOLBUTTONSTYLE \
(WS_CHILD | WS_VISIBLE | BS_OWNERDRAW)
HWND AutoRunCreateCoolButton(AUTORUNDATA *data, AUTORUNBTN *button)
{
HWND h;
h = CreateWindow(c_szButtonClass, c_szNULL, COOLBUTTONSTYLE,
0, 0, 0, 0, data->window, NULL, HINST_THISAPP, 0);
return ( h );
}
//---------------------------------------------------------------------------
void AutoRunCreateButtons(AUTORUNDATA *data)
{
RECT labelbase = BUTTON_LABEL_RECT;
int i;
for (i = 0; i < AUTORUN_NUM_BUTTONS; i++)
{
AUTORUNBTN *button = g_ButtonInfo + i;
HWND child = NULL;
if (button->res != -1)
{
child = AutoRunCreateDorkyButton(data, button);
/*** Don't call this code because we don't use the bitmap array.
if (!g_fCrapForColor) {
child = AutoRunCreateCoolButton(data, button);
}
if (!child) {
child = AutoRunCreateDorkyButton(data, button);
}
***/
}
if (child)
{
BOOL b;
int cx = BUTTON_DEFAULT_CX;
int cy = BUTTON_DEFAULT_CY;
button->window = child;
SetWindowLong(child, GWL_ID, i);
button->oldproc = SubclassWindow(child,
(WNDPROC)AutoRunButtonSubclassProc);
if (button->isdorky)
{
cx = button->face.right - button->face.left;
cy = button->face.bottom - button->face.top;
}
b = SetWindowPos(child, NULL, button->xpos, button->ypos, cx, cy,
SWP_NOZORDER | SWP_NOACTIVATE);
LoadString(HINST_THISAPP, IDS_TITLE(button->res),
button->text, ARRAYSIZE(button->text));
LoadString(HINST_THISAPP, IDS_INFO(button->res),
button->description, ARRAYSIZE(button->description));
button->textrect = labelbase;
b = OffsetRect(&button->textrect, button->xpos, button->ypos);
b = InvalidateRect(data->window, &button->textrect, FALSE);
}
}
}
//---------------------------------------------------------------------------
void CleanupAutoRunWindow(AUTORUNDATA *data)
{
//
// Deactivate any button so its timer will get killed
//
if (g_iActiveButton >= 0)
{
data->keyboard = FALSE;
SendMessage(data->window, ARM_MOUSEOVER, TRUE, (LPARAM)-1L);
}
if (data->image)
{
if (data->oldbmp)
{
SelectBitmap(data->image, data->oldbmp);
// real backdrop image is deleted in WinMain
data->oldbmp = NULL;
}
DeleteDC(data->image);
data->image = NULL;
}
if (data->btnimage)
{
if (data->oldbtnbmp)
{
DeleteBitmap(SelectBitmap(data->btnimage, data->oldbtnbmp));
data->oldbtnbmp = NULL;
}
DeleteDC(data->btnimage);
data->btnimage = NULL;
}
if (data->palette)
{
DeleteObject(data->palette);
data->palette = NULL;
}
if (data->textfont)
{
DeleteObject(data->textfont);
data->textfont = NULL;
}
}
//---------------------------------------------------------------------------
BOOL AutoRunBuildPath(char *spec, int resid, DWORD rooting)
{
char prefix[MAX_PATH];
//
// get the relative path of the spec
//
if (resid == -1)
{
//
// empty string hack for callers
//
*spec = 0;
}
else {
//
// Normal case, where we load the resource from the block of resource ids.
//
if (!LoadString(HINST_THISAPP, resid, spec, MAX_PATH)) {
return FALSE;
}
// However, now since we may be coming initiating setup from any of the platforms,
// we need to specify the correct platform.
// Do the following:
// - see if we are going to attempt to run setup, ie. winnt[32].exe.
// - if so, figure out from which platform
// - and, load the appropriate string.
if ( strstr ( spec, "winnt" ) != NULL ) {
// We are going to attempt to run setup.
//
// Determine the platform.
//
if ( bWin95 ) {
// If we are running Win95, load the Winnt.exe command.
//
LoadString(HINST_THISAPP, IDS_CMD_NTSETUP_WIN95, spec, MAX_PATH);
}
else {
char launchLocation[MAX_PATH];
// Otherwise, we are running NT and need to figure out what platform.
//
GetModuleFileName(HINST_THISAPP, launchLocation, ARRAYSIZE(prefix));
_strupr ( launchLocation );
if ( strstr ( launchLocation, "I386" ) == NULL ) {
if ( strstr ( launchLocation, "MIPS" ) == NULL ) {
if ( strstr ( launchLocation, "ALPHA" ) == NULL ) {
if ( strstr ( launchLocation, "PPC" ) == NULL ) {
// BUG BUG - didn't find anything, put up message ?
}
else {
LoadString(HINST_THISAPP, IDS_CMD_NTSETUP_PPC, spec, MAX_PATH);
}
}
else {
LoadString(HINST_THISAPP, IDS_CMD_NTSETUP_ALPHA, spec, MAX_PATH);
}
}
else {
LoadString(HINST_THISAPP, IDS_CMD_NTSETUP_MIPS, spec, MAX_PATH);
}
}
else {
LoadString(HINST_THISAPP, IDS_CMD_NTSETUP_X86, spec, MAX_PATH);
}
}
}
// However, now since we may be coming initiating setup from any of the platforms,
// we need to specify the correct platform directory.
// Do the following:
// - see if we loaded the 'platform' resource string, our indicator to find platform.
// - if so, figure out from which platform
// - and, load the appropriate string.
else if ( strstr ( spec, "platform" ) != NULL ) {
char launchLocation[MAX_PATH];
// We are loading from the setup button for directory resource.
//
// Determine the platform.
//
// Load location from where we are executing.
//
GetModuleFileName(HINST_THISAPP, launchLocation, ARRAYSIZE(prefix));
_strupr ( launchLocation );
if ( strstr ( launchLocation, "I386" ) == NULL ) {
if ( strstr ( launchLocation, "MIPS" ) == NULL ) {
if ( strstr ( launchLocation, "ALPHA" ) == NULL ) {
if ( strstr ( launchLocation, "PPC" ) == NULL ) {
// BUG BUG - didn't find anything, put up message.
//wsprintf ( dbgStr, "not matched launchLocation = %s", launchLocation );
//MessageBox ( NULL, dbgStr, "", MB_ICONASTERISK );
}
else {
LoadString(HINST_THISAPP, IDS_DIR_NTSETUP_PPC, spec, MAX_PATH);
}
}
else {
LoadString(HINST_THISAPP, IDS_DIR_NTSETUP_ALPHA, spec, MAX_PATH);
}
}
else {
LoadString(HINST_THISAPP, IDS_DIR_NTSETUP_MIPS, spec, MAX_PATH);
}
}
else {
LoadString(HINST_THISAPP, IDS_DIR_NTSETUP_X86, spec, MAX_PATH);
}
}
else if ( strstr ( spec, "slashb" ) != NULL ) {
char launchLocation[MAX_PATH];
// We are loading from the setup button for directory resource.
//
// Determine the platform.
//
// Load location from where we are executing.
//
GetModuleFileName(HINST_THISAPP, launchLocation, ARRAYSIZE(prefix));
_strupr ( launchLocation );
if ( strstr ( launchLocation, "I386" ) == NULL ) {
LoadString (HINST_THISAPP, IDS_PARAMS_NTSETUP_RISC, spec, MAX_PATH );
}
else {
LoadString (HINST_THISAPP, IDS_PARAMS_NTSETUP_X86, spec, MAX_PATH);
}
}
}
//
// our "empty" strings contain a single space so we know they succeeded
//
if ((*spec == ' ') && !spec[1])
*spec = 0;
//
// figure out what the prefix should be
//
*prefix = 0;
switch (rooting)
{
case ONACD:
//
// assume the cd is the root of wherever we were launched from
//
GetModuleFileName(HINST_THISAPP, prefix, ARRAYSIZE(prefix));
_PathStripToRoot(prefix);
break;
case INWIN:
GetRealWindowsDirectory(prefix, ARRAYSIZE(prefix));
break;
case INSYS:
GetSystemDirectory(prefix, ARRAYSIZE(prefix));
break;
}
//
// if we have a prefix then prepend it
//
if (*prefix)
{
if (*spec)
{
PathAppend(prefix, spec);
}
//
// copy the whole mess out to the original buffer
//
lstrcpy(spec, prefix);
}
return TRUE;
}
//---------------------------------------------------------------------------
BOOL InitAutoRunWindow(HWND window, AUTORUNDATA *data, LPCREATESTRUCT cs)
{
//char command[MAX_PATH];
AUTORUNBTN *button;
OSVERSIONINFO osVersionInfo;
BOOL b;
data->window = window;
if ((data->image = CreateCompatibleDC(NULL)) == NULL)
goto im_doug;
if ((data->oldbmp = SelectBitmap(data->image,
(HBITMAP)cs->lpCreateParams)) == NULL)
{
goto im_doug;
}
if (g_fNeedPalette)
{
if ((data->palette = PaletteFromDS(data->image)) == NULL)
goto im_doug;
}
/*** NT doesn't do the Expo Button.
// should we show the expo button?
button = g_ButtonInfo + IDAB_MSEXPO;
if (!AutoRunBuildPath(command, IDS_CMD(button->res),
CMD_ROOT(button->rooting)) || !PathFileExists(command))
{
button->res = -1;
}
***/
// Should we show the Add/Remove program button ?
// Yes, if running on NT.
// No, if running on anything else.
button = g_ButtonInfo + IDAB_OCSETUP;
osVersionInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO );
b = GetVersionEx ( &osVersionInfo );
if ( !b || !(osVersionInfo.dwPlatformId & VER_PLATFORM_WIN32_NT) ) {
button->res = -1;
}
bWin95 = osVersionInfo.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS;
// artifical scoping oh boy!
{
BITMAP bm;
int i, ivis = 0;
int range = 0;
int origin, extent;
for (i = 0; i < AUTORUN_NUM_BUTTONS; i++)
{
button = g_ButtonInfo + i;
if (button->res != -1)
range++;
}
GetObject((HBITMAP)cs->lpCreateParams, sizeof(bm), &bm);
origin = BUTTON_Y_MARGIN * ((1 + AUTORUN_NUM_BUTTONS) - range);
extent = bm.bmHeight - ((2 * origin) + BUTTON_IMAGE_Y_SIZE);
if (--range < 1)
range = 1;
for (i = 0; i < AUTORUN_NUM_BUTTONS; i++)
{
button = g_ButtonInfo + i;
if (button->res != -1)
{
button->xpos = BUTTON_X_PLACEMENT;
button->ypos = ivis * extent / range + origin;
ivis++;
}
}
}
// more artifical scoping!
{
HDC screen = GetDC(NULL);
LOGFONT lf = { DEF_BUTTON_LABEL_HEIGHT, 0, 0, 0, FW_BOLD, FALSE,
FALSE, FALSE, (screen? GetTextCharset(screen) : DEFAULT_CHARSET),
OUT_STROKE_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY | NONANTIALIASED_QUALITY,
VARIABLE_PITCH | FF_DONTCARE, 0 };
char buf[32];
if (screen)
ReleaseDC(NULL, screen);
if (!LoadString(HINST_THISAPP, IDS_LABELFONT, lf.lfFaceName,
ARRAYSIZE(lf.lfFaceName)))
{
lstrcpy(lf.lfFaceName, c_szArial);
}
if (LoadString(HINST_THISAPP, IDS_LABELHEIGHT, buf, ARRAYSIZE(buf)))
lf.lfHeight = AnotherStrToLong(buf);
if ((data->textfont = CreateFontIndirect(&lf)) == NULL)
goto im_doug;
}
//
// see if we need to do 8bit+ work...
//
if (g_fCrapForColor)
{
data->clrnormal = AUTORUN_4BIT_TEXTCOLOR;
data->clrhigh = AUTORUN_4BIT_HIGHLIGHT;
data->clrdisable = AUTORUN_4BIT_DISABLED;
data->clrdescription = AUTORUN_4BIT_DESCRIPTION;
}
else
{
data->clrnormal = AUTORUN_8BIT_TEXTCOLOR;
data->clrhigh = AUTORUN_8BIT_HIGHLIGHT;
data->clrdisable = AUTORUN_8BIT_DISABLED;
data->clrdescription = AUTORUN_8BIT_DESCRIPTION;
/***
if (!AssembleButtonImages(data))
goto im_doug;
***/
}
PostMessage(g_hMainWindow, ARM_MOUSEOVER, TRUE, (LPARAM)-1L);
return TRUE;
im_doug:
CleanupAutoRunWindow(data);
return FALSE;
}
//---------------------------------------------------------------------------
void AutoRunSized(AUTORUNDATA *data)
{
GetClientRect(data->window, &data->descrect);
data->wndheight = data->descrect.bottom - data->descrect.top;
data->descrect.left = AUTORUN_DESCRIPTION_LEFT;
data->descrect.top = AUTORUN_DESCRIPTION_TOP;
data->descrect.right = AUTORUN_DESCRIPTION_RIGHT;
}
//---------------------------------------------------------------------------
void AutoRunRealize(HWND window, AUTORUNDATA *data, HDC theirdc)
{
if (data->palette)
{
HDC dc = theirdc? theirdc : GetDC(window);
if (dc)
{
BOOL repaint = FALSE;
SelectPalette(dc, data->palette, FALSE);
repaint = (RealizePalette(dc) > 0);
if (!theirdc)
ReleaseDC(window, dc);
if (repaint)
{
RedrawWindow(window, NULL, NULL, RDW_INVALIDATE |
RDW_ERASE | RDW_ALLCHILDREN);
}
}
}
}
//---------------------------------------------------------------------------
void AutoRunErase(AUTORUNDATA *data, HDC dc)
{
RECT rc;
GetClientRect(data->window, &rc);
AutoRunRealize(data->window, data, dc);
BitBlt(dc, 0, 0, rc.right, rc.bottom, data->image, 0, 0, SRCCOPY);
}
//---------------------------------------------------------------------------
void AutoRunPaint(AUTORUNDATA *data)
{
PAINTSTRUCT ps;
HDC dc = BeginPaint(data->window, &ps);
AUTORUNBTN *button;
COLORREF curtextcolor = GetTextColor(dc);
COLORREF color;
HFONT hfold = NULL;
int i;
AutoRunRealize(data->window, data, dc);
SetBkMode(dc, TRANSPARENT);
//
// paint all the button labels
//
if (data->textfont)
hfold = SelectFont(dc, data->textfont);
for (i = 0; i < AUTORUN_NUM_BUTTONS; i++)
{
button = g_ButtonInfo + i;
if (button->window)
{
color = (i == g_iActiveButton)? data->clrhigh :
(IsWindowEnabled(button->window)? data->clrnormal :
data->clrdisable);
if (color != curtextcolor)
{
SetTextColor(dc, color);
curtextcolor = color;
}
DrawText(dc, button->text, -1, &button->textrect,
DT_WORDBREAK | DT_RIGHT | DT_TOP);
}
}
//
// paint the description for the current button
//
if (g_iActiveButton >= 0)
{
button = g_ButtonInfo + g_iActiveButton;
color = data->clrdescription;
if (color != curtextcolor)
{
SetTextColor(dc, color);
curtextcolor = color;
}
DrawText(dc, button->description, -1, &data->descrect,
DT_WORDBREAK | DT_LEFT | DT_TOP);
}
if (hfold)
SelectFont(dc, hfold);
EndPaint(data->window, &ps);
}
//---------------------------------------------------------------------------
void AutoRunDrawItem(AUTORUNDATA *data, DRAWITEMSTRUCT *dis)
{
POINT loc = { dis->rcItem.left, dis->rcItem.top };
SIZE size = { dis->rcItem.right - loc.x, dis->rcItem.bottom - loc.y };
loc.y += dis->CtlID * BUTTON_IMAGE_Y_SIZE;
if (dis->itemState & ODS_DISABLED)
{
loc.x += DISABLED_IMAGE_X_OFFSET;
}
else if (dis->itemState & ODS_SELECTED)
{
loc.x += SELECTED_IMAGE_X_OFFSET;
}
else if (dis->itemState & ODS_FOCUS)
{
loc.x += FOCUS_IMAGE_X_OFFSET;
}
AutoRunRealize(dis->hwndItem, data, dis->hDC);
BitBlt(dis->hDC, dis->rcItem.left, dis->rcItem.top, size.cx, size.cy,
data->btnimage, loc.x, loc.y, SRCCOPY);
}
//---------------------------------------------------------------------------
void AutoRunActivateItem(AUTORUNDATA *data, int index)
{
if (index >= 0)
{
//
// prevent disabled buttons from getting focus...
//
AUTORUNBTN *button = g_ButtonInfo + index;
if (!button->window || !IsWindowEnabled(button->window))
index = -1;
}
if (g_iActiveButton != index)
{
AUTORUNBTN *newbtn = (index >= 0)? (g_ButtonInfo + index) : NULL;
AUTORUNBTN *oldbtn = (g_iActiveButton >= 0)?
(g_ButtonInfo + g_iActiveButton) : NULL;
//
// if there was an previous button, repaint its label highlight
//
if (oldbtn)
InvalidateRect(data->window, &oldbtn->textrect, FALSE);
g_iActiveButton = index;
if (newbtn)
{
InvalidateRect(data->window, &newbtn->textrect, FALSE);
SetFocus(newbtn->window);
//
// if activating via mouse, track it (trust me...)
//
if (g_fMouseAvailable && !data->keyboard)
SetTimer(data->window, LABEL_VERIFY_TIMER, 333, NULL);
}
else
{
SetFocus(data->window);
if (g_fMouseAvailable)
KillTimer(data->window, LABEL_VERIFY_TIMER);
}
//
// go ahead and paint any label changes now before we erase
//
UpdateWindow(data->window);
InvalidateRect(data->window, &data->descrect, TRUE);
}
}
//---------------------------------------------------------------------------
void AutoRunMouseOver(AUTORUNDATA *data, int index, BOOL fForce)
{
if ((index >= 0) || !data->keyboard || fForce)
{
data->keyboard = !g_fMouseAvailable;
AutoRunActivateItem(data, index);
}
}
//---------------------------------------------------------------------------
int AutoRunProcessPotentialHit(HWND candidate, const POINT *loc)
{
if (GetAsyncKeyState(VK_LBUTTON) < 0)
return g_iActiveButton;
if (candidate && IsWindowEnabled(candidate) &&
(GetParent(candidate) == g_hMainWindow))
{
int index;
index = (int)GetWindowLong(candidate, GWL_ID);
if ((index >= 0) && (index < AUTORUN_NUM_BUTTONS))
{
AUTORUNBTN *button = g_ButtonInfo + index;
POINT cli = *loc;
ScreenToClient(candidate, &cli);
if (PtInRect(&button->face, cli))
return index;
}
}
return -1;
}
//---------------------------------------------------------------------------
void AutoRunVerifyActiveItem(AUTORUNDATA *data)
{
if (!data->keyboard)
{
int index = -1;
if (!g_fAppDisabled)
{
POINT loc;
HWND candidate;
GetCursorPos(&loc);
if ((candidate = WindowFromPoint(loc)) != NULL)
index = AutoRunProcessPotentialHit(candidate, &loc);
}
if (index != g_iActiveButton)
AutoRunMouseOver(data, index, FALSE);
}
}
//---------------------------------------------------------------------------
void AutorunEnableButton(AUTORUNDATA *data, int id, BOOL f)
{
if ((id >= 0) && (id < AUTORUN_NUM_BUTTONS))
{
AUTORUNBTN *button = g_ButtonInfo + id;
HWND window = button->window;
if (button->window && IsWindow(button->window))
{
EnableWindow(button->window, f);
InvalidateRect(data->window, &button->textrect, FALSE);
AutoRunVerifyActiveItem(data);
}
}
}
//---------------------------------------------------------------------------
BOOL AutoRunCDIsInDrive(HWND hwndOwner)
{
char me[MAX_PATH];
GetModuleFileName(HINST_THISAPP, me, ARRAYSIZE(me));
//MessageBox ( NULL, "Entering AutoRunCDIsInDrive...", "", MB_ICONASTERISK );
while (!PathFileExists(me))
{
char szNeed[MAX_PATH];
char szName[MAX_PATH];
LoadString(HINST_THISAPP, IDS_NEEDCDROM, szNeed, MAX_PATH);
LoadString(HINST_THISAPP, IDS_APPTITLE, szName, MAX_PATH);
//////if (ShellMessageBox(HINST_THISAPP, hwndOwner,
if ( MessageBox ( NULL,
szNeed,
szName,
MB_OKCANCEL | MB_ICONSTOP) == IDCANCEL ) {
//MessageBox ( NULL, "AutoRunCDIsInDrive FALSE", "", MB_ICONASTERISK );
return FALSE;
}
}
//MessageBox ( NULL, "AutoRunCDIsInDrive TRUE", "", MB_ICONASTERISK );
return TRUE;
}
//---------------------------------------------------------------------------
void AutoRunClick(AUTORUNDATA *data, int nCmd)
{
char command[MAX_PATH], dir[MAX_PATH], params[MAX_PATH];
AUTORUNBTN *button;
ULONG uRC;
if ((nCmd < 0) || (nCmd >= AUTORUN_NUM_BUTTONS))
return;
button = g_ButtonInfo + nCmd;
//
// meep at the user (meep meep!) so they know something is happening...
//
PlaySound(MAKEINTRESOURCE(IDW_BLIP), HINST_THISAPP,
SND_RESOURCE | SND_ASYNC | SND_NODEFAULT);
//
// verify that the app disk is still visible and prompt if not...
//
if (!AutoRunCDIsInDrive(data->window)) {
return;
}
//
// calculate the paths for the command
//
if (!AutoRunBuildPath(command, IDS_CMD(button->res), CMD_ROOT(button->rooting)) ||
!AutoRunBuildPath(params, IDS_PARAMS(button->res), PARAMS_ROOT(button->rooting)) ||
!AutoRunBuildPath(dir, IDS_DIR(button->res), DEFDIR_ROOT(button->rooting))) {
// BUGBUG an error message would be nice
}
//wsprintf ( dbgStr, "ShellExecute : command = %s, params = %s, dir = %s", command, params, dir );
//MessageBox ( NULL, dbgStr, "", MB_ICONASTERISK );
uRC = (ULONG) ShellExecute(data->window, NULL, command, params, dir, SW_SHOWNORMAL);
if ( uRC >= 0 && uRC <= 32 ) {
char cmdString[MAX_PATH];
LoadString(HINST_THISAPP, IDS_SHELLEXECUTE_ERROR, cmdString, MAX_PATH);
wsprintf ( dbgStr, "%s lpFiles = %s, lpParameters = %s, lpDirectory = %s", cmdString, command, params, dir );
MessageBox ( NULL, dbgStr, szAppTitle, MB_ICONASTERISK );
}
}
//---------------------------------------------------------------------------
void AutoRunHandleKeystroke(AUTORUNDATA *data, TCHAR key, LPARAM lp)
{
int move = 0;
int where = g_iActiveButton;
//
// see if we care about this keystroke
//
switch (key)
{
case VK_RETURN:
if (where >= 0)
AutoRunClick(data, where);
//fallthru
case VK_ESCAPE:
where = -1;
break;
case VK_TAB:
move = (GetKeyState(VK_SHIFT) < 0)? -1 : 1;
break;
case VK_END:
where = AUTORUN_NUM_BUTTONS;
//fallthru
case VK_UP:
case VK_LEFT:
move = -1;
break;
case VK_HOME:
where = -1;
//fallthru
case VK_DOWN:
case VK_RIGHT:
move = 1;
break;
default:
return;
}
//
// we should only get down here if the active button is going to change
//
if (move)
{
int scanned;
for (scanned = 0; scanned <= AUTORUN_NUM_BUTTONS; scanned++)
{
where += move;
if (where >= (int)AUTORUN_NUM_BUTTONS)
{
where = -1;
}
else if (where < 0)
{
where = AUTORUN_NUM_BUTTONS;
}
else
{
HWND child = (g_ButtonInfo + where)->window;
if (child && IsWindowEnabled(child))
break;
}
}
}
if (where >= 0)
{
SetCursor(NULL);
data->keyboard = TRUE;
}
else
data->keyboard = !g_fMouseAvailable;
AutoRunActivateItem(data, where);
}
//---------------------------------------------------------------------------
/***** NT doesn't use since we don't use the version consistency stuff.
void LaunchSetup(HWND window)
{
char command[MAX_PATH], params[MAX_PATH], dir[MAX_PATH];
//
// calculate the paths for the command
//
if (!AutoRunBuildPath(command, IDS_SETUPCMD, ONACD) ||
!AutoRunBuildPath(params, -1, NOROOT) ||
!AutoRunBuildPath(dir, -1, ONACD))
{
// BUGBUG an error message would be nice
}
ShellExecute(window, NULL, command, params, dir, SW_SHOWNORMAL);
// BUGBUG an error message would be nice
}
*****/
//---------------------------------------------------------------------------
#define CD_PLATFORM_ID (VER_PLATFORM_WIN32_WINDOWS)
#define CD_MAJOR_VERSION (4)
#define CD_MINOR_VERSION (0)
#define CD_BUILD_NUMBER (VER_PRODUCTVERSION_DW)
/**** NT doesn't currently use this.
BOOL CheckVersionConsistency(AUTORUNDATA *data)
{
OSVERSIONINFO ovi = { sizeof(ovi), 0, 0, 0, 0, 0 };
int message = 0;
UINT msgtype = 0;
BOOL result = FALSE;
BOOL fDisableSetupStuff = FALSE;
if (!GetVersionEx(&ovi))
{
message = IDS_CANTGETVERSION;
msgtype = MB_OK | MB_ICONSTOP;
goto deal;
}
//
// is this CD a version of the same os platform?
//
if (ovi.dwPlatformId != CD_PLATFORM_ID)
{
fDisableSetupStuff = TRUE;
}
else
{
BOOL offersetup = FALSE;
//
// is this CD an old beta build?
//
if ((ovi.dwMajorVersion == CD_MAJOR_VERSION) &&
(ovi.dwMinorVersion == CD_MINOR_VERSION) &&
(ovi.dwBuildNumber > CD_BUILD_NUMBER))
{
//
// tell them to go find a newer CD
//
message = IDS_CRUSTYCDROM;
msgtype = MB_OK | MB_ICONEXCLAMATION;
fDisableSetupStuff = TRUE;
result = TRUE;
goto deal;
}
//
// is this CD a newer version of the same os?
//
if (ovi.dwMajorVersion < CD_MAJOR_VERSION)
{
offersetup = TRUE;
}
else if (ovi.dwMajorVersion == CD_MAJOR_VERSION)
{
if (ovi.dwMinorVersion < CD_MINOR_VERSION)
{
offersetup = TRUE;
}
else if ((ovi.dwMinorVersion == CD_MINOR_VERSION) &&
(ovi.dwBuildNumber < CD_BUILD_NUMBER))
{
offersetup = TRUE;
}
}
//
// look at the result of that hulking mess above
//
if (offersetup)
{
//
// offer to upgrade them to this version
//
message = IDS_CRUSTYINSTALLATION;
msgtype = MB_YESNO | MB_ICONQUESTION;
goto deal;
}
}
deal:
if (fDisableSetupStuff)
AutorunEnableButton(data, IDAB_OCSETUP, FALSE);
if (msgtype)
{
ShowWindow(data->window, SW_SHOWNORMAL);
if (ShellMessageBox(HINST_THISAPP, data->window,
MAKEINTRESOURCE(message), MAKEINTRESOURCE(IDS_APPTITLE),
msgtype) == IDYES)
{
LaunchSetup(data->window);
}
#ifdef DEBUG
result = TRUE;
#endif
}
else
result = TRUE;
return result;
}
*****/
//---------------------------------------------------------------------------
LRESULT CALLBACK AutoRunMouseHook(int code, WPARAM wp, LPARAM lp)
{
if (code >= 0)
{
#define hook ((MOUSEHOOKSTRUCT *)lp)
int id = g_fAppDisabled? -1 :
AutoRunProcessPotentialHit(hook->hwnd, &hook->pt);
if (id != g_iActiveButton)
PostMessage(g_hMainWindow, ARM_MOUSEOVER, FALSE, (LPARAM)id);
#undef hook
}
return CallNextHookEx(g_hMouseHook, code, wp, lp);
}
//---------------------------------------------------------------------------
LRESULT CALLBACK AutoRunWndProc(HWND window, UINT msg, WPARAM wp, LPARAM lp)
{
AUTORUNDATA *data = (AUTORUNDATA *)GetWindowLong(window, GWL_USERDATA);
switch (msg)
{
case WM_NCCREATE:
data = (AUTORUNDATA *)LocalAlloc(LPTR, sizeof(AUTORUNDATA));
if (data && !InitAutoRunWindow(window, data, (LPCREATESTRUCT)lp))
{
LocalFree((HANDLE)data);
data = NULL;
}
SetWindowLong(window, GWL_USERDATA, (LONG)data);
if (!data)
return FALSE;
g_hMainWindow = window;
goto DoDefault;
case WM_CREATE:
PlaySound(MAKEINTRESOURCE(IDW_STARTAPP), HINST_THISAPP,
SND_RESOURCE | SND_ASYNC | SND_NODEFAULT);
AutoRunCreateButtons(data);
ShowWindow(window, SW_SHOWNORMAL);
/****
if (!CheckVersionConsistency(data))
return -1;
****/
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_NCDESTROY:
if (data)
{
CleanupAutoRunWindow(data);
LocalFree((HANDLE)data);
}
g_hMainWindow = NULL;
goto DoDefault;
case WM_SIZE:
AutoRunSized(data);
break;
case WM_DRAWITEM:
AutoRunDrawItem(data, (DRAWITEMSTRUCT *)lp);
break;
case ARM_MOUSEOVER:
AutoRunMouseOver(data, (int)lp, (BOOL)wp);
break;
case WM_ACTIVATE:
g_fAppDisabled = ((LOWORD(wp) == WA_INACTIVE) || HIWORD(wp));
AutoRunVerifyActiveItem(data);
goto DoDefault;
case WM_TIMER:
AutoRunVerifyActiveItem(data);
break;
case WM_KEYDOWN:
AutoRunHandleKeystroke(data, (TCHAR)wp, lp);
break;
case WM_COMMAND:
if (GET_WM_COMMAND_CMD(wp, lp) == BN_CLICKED)
AutoRunClick(data, GET_WM_COMMAND_ID(wp, lp));
break;
case WM_PALETTECHANGED:
if ((HWND)wp == window)
break;
//fallthru
case WM_QUERYNEWPALETTE:
AutoRunRealize(window, data, NULL);
break;
case WM_ERASEBKGND:
AutoRunErase(data, (HDC)wp);
break;
case WM_PAINT:
AutoRunPaint(data);
break;
default:
DoDefault:
return DefWindowProc(window, msg, wp, lp);
}
return 1;
}
//---------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
HBITMAP hbm = NULL;
BITMAP bm;
DWORD style;
HWND window;
RECT r;
HDC screen;
int retval = -1;
g_hinst = hInstance;
//
// The below code is here in order to prevent this application from
// displaying any windows, etc., in the case where NT Setup is asking the user to
// insert the system CD, for example, when the user is installing a new driver.
// Otherwise, we'll get this app each time the CD is put in the drive for NT 4.0 and
// beyond.
//
window = FindWindow(c_szAutoRunPrevention, c_szAutoRunPrevention);
if (window)
{
// do nothing
// setup is probably trying to copy a driver or something...
retval = 0;
goto im_doug;
}
//
// Stop if we can't load the app title in for this application.
//
if (!LoadString(HINST_THISAPP, IDS_APPTITLE, szAppTitle,
sizeof(szAppTitle)))
{
goto im_doug;
}
//
// Stop if we can't find our window ?
//
window = FindWindow(c_szAutoRunClass, szAppTitle);
if (window)
{
retval = 0;
SetForegroundWindow(window);
goto im_doug;
}
//
// yet more mundane platform-centric details
//
if (!GetClassInfo(HINST_THISAPP, c_szAutoRunClass, &wc))
{
wc.style = 0;
wc.lpfnWndProc = AutoRunWndProc;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = c_szAutoRunClass;
if (!RegisterClass(&wc))
goto im_doug;
}
//
// get a few tidbits about the display we're running on
//
screen = GetDC(NULL);
#if defined (DEBUG) && defined (FORCE_CRAP)
g_fCrapForColor = TRUE;
#else
g_fCrapForColor = (GetDeviceCaps(screen, PLANES) *
GetDeviceCaps(screen, BITSPIXEL)) < 8;
//g_fCrapForColor = TRUE; // testing...
#endif
g_fNeedPalette = (!g_fCrapForColor &&
(GetDeviceCaps(screen, RASTERCAPS) & RC_PALETTE));
ReleaseDC(NULL, screen);
//
// load the window backdrop image
//
hbm = LoadImage(HINST_THISAPP, MAKEINTRESOURCE(g_fCrapForColor?
IDB_4BPP_BACKDROP : IDB_8BPP_BACKDROP), IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION);
if (!hbm)
goto im_doug;
//
//
// See if there is a mouse on the system.
//
if ((g_fMouseAvailable = (GetSystemMetrics(SM_MOUSEPRESENT) != 0)) != 0)
{
//
// Set-up a mouse hook for our thread, but
// don't worry if it fails, the app will still work.
//
g_hMouseHook = SetWindowsHookEx(WH_MOUSE, AutoRunMouseHook,
HINST_THISAPP, GetCurrentThreadId());
}
//
// create the window based on the backdrop image
//
GetObject(hbm, sizeof(bm), &bm);
r.left = (GetSystemMetrics(SM_CXSCREEN) - bm.bmWidth) / 2;
r.top = (GetSystemMetrics(SM_CYSCREEN) - bm.bmHeight) / 3; // intended
r.right = r.left + bm.bmWidth;
r.bottom = r.top + bm.bmHeight;
style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
AdjustWindowRect(&r, style, FALSE);
g_hMainWindow = CreateWindow(c_szAutoRunClass, szAppTitle, style,
r.left, r.top, r.right - r.left, r.bottom - r.top, NULL, NULL,
HINST_THISAPP, hbm);
//
// if we got here it's probably safe to show ourselves and pump messages
//
if (g_hMainWindow)
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
retval = (int)msg.wParam;
}
im_doug:
//
// random cleanup
//
if (g_hMouseHook)
{
UnhookWindowsHookEx(g_hMouseHook);
g_hMouseHook = NULL;
}
if (hbm)
DeleteObject(hbm);
return retval;
}
//---------------------------------------------------------------------------
/**** NT doesn't use this, currently.
int _stdcall ModuleEntry(void)
{
int i;
STARTUPINFO si;
LPSTR pszCmdLine = GetCommandLine();
if ( *pszCmdLine == '\"' ) {
// Scan, and skip over, subsequent characters until
// another double-quote or a null is encountered.
//
while ( *++pszCmdLine && (*pszCmdLine
!= '\"') );
// If we stopped on a double-quote (usual case), skip
// over it.
if ( *pszCmdLine == '\"' )
pszCmdLine++;
}
else {
while (*pszCmdLine > ' ')
pszCmdLine++;
}
//Skip past any white space preceeding the second token.
//
while (*pszCmdLine && (*pszCmdLine <= ' ')) {
pszCmdLine++;
}
si.dwFlags = 0;
GetStartupInfoA(&si);
i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine,
si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
ExitProcess(i);
return i; // We never comes here.
}
****/