INFINST.C


/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright 1995 - 1998 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/

//
// PROGRAM:InfInst.c
//
// PURPOSE:Demonstrates how create a wizard based install
// using win32 functions in setupapi.dll
//
// PLATFORMS:Windows 95 and NT 4.0
//
// FUNCTIONS:
// WinMain() - calls initialization function, processes message loop
// InitApplication() - Initializes window data nd registers window
// InitInstance() - saves instance handle and creates main window
// MainWindProc() - Processes messages
// RuntimeRegistration() - Add runtime data to registry
// RegisterString() - adds a string to registry, simple win32 registry api wrapper
// GetRegString() - gets a string from registry, simple win32 registry api wrapper
// GetPlatformInfo () - not used but this is an exampleof what you can do in
// a win32 or win16 setup stub program to get your setup started
// NOTE: In this sample we are assuming the autorun.inf takes care of this
//
// CALLS:
// DoInstallation() - Does the resulting installation options in doinst.c
//
// SPECIAL INSTRUCTIONS: N/A
//

#include <windows.h> // includes basic windows functionality
#include <string.h> // includes the string functions
#include <prsht.h> // includes the property sheet functionality
#include "setupapi.h" // includes the inf setup api
#include "resource.h" // includes the definitions for the resources
#include "instwiz.h" // includes the application-specific information
#include "infinst.h" // includes the application-specific information
#include "infdesc.h"

INSTALLINFO setupInfo; // a structure containing the review information
HWND hwndEdit; // handle to the main MLE
TCHAR lpReview[MAX_BUF]; // Buffer for the review

BOOL bCreated = FALSE; // Keep us minimized once we are created

//
//
// FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
//
// PURPOSE: Main entry point for the application.
//
// COMMENTS:
//
// This function calls the initialization functions and processes
// the main message loop.
//
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
MSG msg;

// save off the current instance
setupInfo.hInst = hInstance;

// if the initialization fails, return.
if (!InitApplication(hInstance))
return (FALSE);

// Perform initializations that apply to a specific instance
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);

// Acquire and dispatch messages until a WM_QUIT message is received.
while (GetMessage(&msg, NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return (msg.wParam);
}


//
//
// FUNCTION: InitApplication(HANDLE)
//
// PURPOSE: Initializes window data and registers window class
//
// COMMENTS:
//
// This function registers the window class for the main window.
//
BOOL InitApplication(HANDLE hInstance)
{
WNDCLASS wcSample;

// Fill in window class structure with parameters that describe the
// main window.

wcSample.style = 0;
wcSample.lpfnWndProc = (WNDPROC)MainWndProc;
wcSample.cbClsExtra = 0;
wcSample.cbWndExtra = 0;
wcSample.hInstance = hInstance;
wcSample.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(EXE_ICON));
wcSample.hCursor = LoadCursor(NULL, IDC_ARROW);
wcSample.hbrBackground = GetStockObject(WHITE_BRUSH);
wcSample.lpszMenuName = NULL;
wcSample.lpszClassName = TEXT("SampleWClass");

return (RegisterClass(&wcSample));

}


//
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Creates the main window.
//
// COMMENTS: N/A
//
//
BOOL InitInstance(
HANDLE hInstance,
int nCmdShow)
{
HWND hWndMain;

hWndMain = CreateWindow(
TEXT("SampleWClass"),
TEXT("Install Sample"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);

/* If window could not be created, return "failure" */
if (!hWndMain)
return (FALSE);

/* Make the window visible; update its client area; and return "success" */
ShowWindow(hWndMain, SW_MINIMIZE);
UpdateWindow(hWndMain);
return (TRUE);

}

//
// FUNCTION: MainWndProc(HWND, UINT, UINT, LONG)
//
// PURPOSE: Processes messages for the main window procedure
//
// MESSAGES:
//
// WM_CREATE - creates the main MLE for the window
// WM_COMMAND - processes the menu commands for the application
// WM_SIZE - sizes the MLE to fill the client area of the window
// WM_DESTROY - posts a quit message and returns
//
LONG APIENTRY MainWndProc(
HWND hWnd, // window handle
UINT message, // type of message
UINT wParam, // additional information
LONG lParam) // additional information
{

switch (message)
{
case WM_CREATE:
// TODO: put in a Bitmap for a splash window );

GetRegString(MYPRODUCT_KEY, USER_NAME_KEY, setupInfo.pszUserName);
GetRegString(MYPRODUCT_KEY, COMPANY_KEY, setupInfo.pszCompany);
GetRegString(MYPRODUCT_KEY, PRODUCT_ID_KEY, setupInfo.pszProductIdString);
GetRegString(MYPRODUCT_KEY, EMAIL_KEY, setupInfo.pszEmailAddress);
GetRegString(MYPRODUCT_KEY, TEXT("DestinationPath"), setupInfo.pszDestPath);

// Start up the install
PostMessage(hWnd, WM_COMMAND, ID_INSTALL, 0 );
return 0;

case WM_WINDOWPOSCHANGING:
if (bCreated)
{
LPWINDOWPOS lpwp;

lpwp = (LPWINDOWPOS) lParam; // points to size and position data
lpwp->flags = SWP_NOMOVE | SWP_NOOWNERZORDER |
SWP_NOSIZE | SWP_NOREDRAW |
SWP_NOREPOSITION;

}
else
{
bCreated = TRUE;
}
break;

case WM_COMMAND:
switch( LOWORD( wParam ))
{
/*******************************************************\
*
* Here is where the real work takes place
* Do the wizard to collect the user information
* Do the installation with the setupapis
* Update the registry with runtime user data
*
\*******************************************************/
case ID_INSTALL:
// Do installation
DoInstallation(hWnd, &setupInfo);

//installs done so go away
PostMessage(hWnd, WM_DESTROY, 0, 0 );
break;

default:
return (DefWindowProc(hWnd, message, wParam, lParam));

}
break;

case WM_DESTROY: /* message: window being destroyed */
PostQuitMessage(0);
break;

default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}


void RuntimeRegistration(INSTALLINFO *si)
{
//
// The setupapi calls have completed
// now we will finish up by updating the user information
// and uninstall in the registry
//

char buf[MAX_PATH];

//
// Stuff for out product
// fixed application values are done by the inf
// We are only doing runtime values here
//

RegisterString(MYPRODUCT_KEY,
USER_NAME_KEY,
si->pszUserName);

RegisterString(MYPRODUCT_KEY,
COMPANY_KEY,
si->pszCompany);

RegisterString(MYPRODUCT_KEY,
PRODUCT_ID_KEY,
si->pszProductIdString);

RegisterString(MYPRODUCT_KEY,
EMAIL_KEY,
si->pszEmailAddress);


wsprintf(buf, "%s", si->pszDestPath);

RegisterString(MYPRODUCT_KEY,
TEXT("DestinationPath"),
buf);

/*
//
// Setup up Add/Remove Programs Control Panel Applet
// We need to set Display name and how to uninstall
//
// UNINSTALL Info
//

RegisterString(UNINSTALL_KEY,
TEXT("DisplayName"),
TEXT("MyProduct Version 1.0"));

wsprintf(buf, "%s\\setup.exe Uninstall", si->pszDestPath);

RegisterString(UNINSTALL_KEY,
TEXT("UninstallString"),
buf);

*/
return;
}


BOOL
RegisterString (
LPSTR pszKey,
LPSTR pszValue,
LPSTR pszData
)
{

HKEY hKey;
DWORD dwDisposition;

//
// Create the key, if it exists it will be opened
//

if (ERROR_SUCCESS !=
RegCreateKeyEx(
HKEY_LOCAL_MACHINE, // handle of an open key
pszKey, // address of subkey name
0, // reserved
NULL, // address of class string
REG_OPTION_NON_VOLATILE, // special options flag
KEY_ALL_ACCESS, // desired security access
NULL, // address of key security structure
&hKey, // address of buffer for opened handle
&dwDisposition)) // address of disposition value buffer
{
return FALSE;
}

//
// Write the value and it's data to the key
//

if (ERROR_SUCCESS !=
RegSetValueEx(
hKey, // handle of key to set value for
pszValue, // address of value to set
0, // reserved
REG_SZ, // flag for value type
pszData, // address of value data
strlen(pszData) )) // size of value data
{

RegCloseKey(hKey);
return FALSE;
}

//
// Close the key
//

RegCloseKey(hKey);

return TRUE;
}

BOOL
GetRegString (
LPSTR pszKey,
LPSTR pszValue,
LPSTR pszData
)
{

HKEY hKey;
DWORD dwDataSize = MAX_PATH - 1;
DWORD dwValueType = REG_SZ;

RegOpenKeyEx(
HKEY_LOCAL_MACHINE, // handle of open key
pszKey, // address of name of subkey to open
0, // reserved
KEY_QUERY_VALUE, // security access mask
&hKey // address of handle of open key
);

RegQueryValueEx(
hKey, // handle of key to query
pszValue, // address of name of value to query
0, // reserved
&dwValueType,// address of buffer for value type
pszData, // address of data buffer
&dwDataSize // address of data buffer size
);

if (pszData[dwDataSize] != '\0')
pszData[dwDataSize] = '\0';

return TRUE;
}

/*

// GetPlatformInfo () - not used but this is an example of what you can do in
// a win32 or win16 setup stub program to get your setup started
// NOTE: In this sample we are assuming the autorun.inf takes care of this
// for us. See the autorun.inf which shows this
//
// The core of this could be your entire WinMain in a win16 stub
//
int GetPlatformInfo(HINSTANCE hInstance)
{
char szCpu[64], szPath[_MAX_PATH], szExeStr[128];
char szSystemDir[_MAX_PATH];

GetModuleFileName(hInstance, szPath, _MAX_PATH);
*(strrchr(szPath, '\\') + 1) = '\0';// Strip SETUPPROG off path
GetSystemDirectory(szSystemDir, _MAX_PATH);


if (getenv("PROCESSOR_ARCHITECTURE") != NULL)
{
lstrcpyn(szCpu, getenv("PROCESSOR_ARCHITECTURE"), 63);
}
else
{ // Not defined, guess x86
lstrcpy(szCpu, "x86");
}

if (HIBYTE(LOWORD(GetVersion())) > 11) // Check if Win95
{
//Win95
sprintf(szExeStr, "%s\\Bin\\I386\\infinst.exe CmdLineOptions", szPath);
}
// Else pick the NT platform
else if (!lstrcmp(szCpu, "MIPS"))
{
sprintf(szExeStr, "%s\\Bin\\MIPS\\infinst.exe CmdLineOptions", szPath);
}
else if (!lstrcmp(szCpu, "ALPHA"))
{
sprintf(szExeStr, "%s\\Bin\\ALPHA\\infinst.exe CmdLineOptions", szPath);
}
else if (!lstrcmp(szCpu, "PPC"))
{
sprintf(szExeStr, "%s\\Bin\\PPC\\infinst.exe CmdLineOptions", szPath);
}
else // x86 NT box
{
sprintf(szExeStr, "%s\\Bin\\I386\\infinst.exe CmdLineOptions", szPath);
}

// MessageBox ( NULL, szExeStr,szCpu,MB_OK);

// WinExec(szExeStr, SW_SHOW);

if (wReturn < 32) {
//Failed
}
else {
//Worked
}

return(0);
}
*/