📄 setupwiz.cpp
字号:
#include "stdafx.h"
#include "SetupWiz.h"
#include <prsht.h>
#include "SetupInf.h"
extern INSTALLINFO g_InstallInfo;
extern CHAR g_szInfPathName[];
static DWORD RegisterDriver(HINF hInf, HWND hDlg);
static DWORD CopyAllFiles(HANDLE hInf, HWND hDlg, HWND hProgress);
//
//
// FUNCTION: FillInPropertyPage(PROPSHEETPAGE *, int, LPSTR, LPFN)
//
// PURPOSE: Fills in the given PROPSHEETPAGE structure
//
// COMMENTS:
//
// This function fills in a PROPSHEETPAGE structure with the
// information the system needs to create the page.
//
void FillInPropertyPage( PROPSHEETPAGE* psp, int idDlg, LPSTR pszProc, DLGPROC pfnDlgProc)
{
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = 0;
psp->hInstance = g_InstallInfo.hInst;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pszIcon = NULL;
psp->pfnDlgProc = pfnDlgProc;
psp->pszTitle = pszProc;
psp->lParam = 0;
}
//
//
// FUNCTION: CreateWizard(HWND)
//
// PURPOSE: Create the Install control.
//
// COMMENTS:
//
// This function creates the install property sheet.
//
int CreateWizard(HWND hwndOwner, HINSTANCE hInst)
{
PROPSHEETPAGE psp[NUM_PAGES];
PROPSHEETHEADER psh;
FillInPropertyPage( &psp[0], IDD_WELCOME, TEXT("Welcome"), Welcome);
FillInPropertyPage( &psp[1], IDD_COMPLETE, TEXT("Setup Complete"), SetupComplete);
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
psh.hwndParent = hwndOwner;
psh.pszCaption = (LPSTR) TEXT("Driver Install");
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
return (PropertySheet(&psh));
}
//////////////////////////////////////////
//
// Wizard procs
//
//////////////////////////////////////////
//
// FUNCTION: Welcome (HWND, UINT, UINT, LONG)
//
// PURPOSE: Processes messages for "Welcome" page
//
// MESSAGES:
//
// WM_INITDIALOG - intializes the page
// WM_NOTIFY - processes the notifications sent to the page
// WM_COMMAND - saves the id of the choice selected
//
BOOL APIENTRY Welcome(
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
return 1;
break;
case PSN_RESET:
// rest to the original values
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
break;
case PSN_WIZNEXT:
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
//
// FUNCTION: SelectPort(HWND, UINT, UINT, LONG)
//
// PURPOSE: Processes messages for "Welcome" page
//
// MESSAGES:
//
// WM_INITDIALOG - intializes the page
// WM_NOTIFY - processes the notifications sent to the page
// WM_COMMAND - saves the id of the choice selected
//
BOOL APIENTRY SelectPort(
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
return 1;
break;
case PSN_RESET:
// rest to the original values
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
break;
case PSN_WIZNEXT:
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
LRESULT
WINAPI
MyQueueCallback (
IN MY_INSTALL_DATA* pMyInstallData,
IN UINT Notification,
IN UINT Param1,
IN UINT Param2
)
{
LRESULT lRet;
switch(Notification)
{
case SPFILENOTIFY_DELETEERROR:
lRet = FILEOP_SKIP;
break;
case SPFILENOTIFY_STARTQUEUE:
SendMessage(pMyInstallData->hProgress, PBM_SETRANGE, 0, MAKELPARAM(0, 4));
SendMessage(pMyInstallData->hProgress, PBM_SETSTEP, (WPARAM) 1, 0);
lRet = SetupDefaultQueueCallback(pMyInstallData->pDefaultContext,
Notification, Param1, Param2);
break;
case SPFILENOTIFY_ENDCOPY:
SendMessage(pMyInstallData->hProgress, PBM_STEPIT, 0, 0);
lRet = SetupDefaultQueueCallback(pMyInstallData->pDefaultContext,
Notification, Param1, Param2);
break;
default:
lRet = SetupDefaultQueueCallback(pMyInstallData->pDefaultContext,
Notification, Param1, Param2);
break;
}
return lRet;
}
//
// FUNCTION: SetupComplete(HWND, UINT, UINT, LONG)
//
// PURPOSE: Processes messages for "Welcome" page
//
// MESSAGES:
//
// WM_INITDIALOG - intializes the page
// WM_NOTIFY - processes the notifications sent to the page
// WM_COMMAND - saves the id of the choice selected
//
BOOL APIENTRY SetupComplete(
HWND hDlg,
UINT message,
UINT wParam,
LONG lParam)
{
DWORD dwResult;
HWND hProgress = NULL;
switch (message)
{
case WM_INITDIALOG:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code)
{
case PSN_KILLACTIVE:
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
return 1;
break;
case PSN_RESET:
// rest to the original values
SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
break;
case PSN_WIZNEXT:
#if 1
dwResult = RegisterDriver(g_InstallInfo.hInf, hDlg);
if(dwResult)
{
return FALSE;
}
#endif
hProgress = GetDlgItem(hDlg, IDC_PROG_COPY);
ShowWindow(hProgress, SW_NORMAL);
dwResult = CopyAllFiles(g_InstallInfo.hInf, hDlg, hProgress);
if(dwResult)
{
return FALSE;
}
else
{
ShowWindow(hProgress, SW_HIDE);
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_FINISH);
SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
}
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
static DWORD GetHardID(HINF hInf, LPTSTR lptHardID)
{
DWORD dwRet = 1;
INFCONTEXT mfg;
CHAR szModName[MAX_PATH];
if (!SetupFindFirstLine(hInf, "Manufacturer", NULL, &mfg))
dwRet = GetLastError();
else
{
DWORD strNeedLen = 0;
// find mfg0
if(!SetupGetStringField(&mfg, 1, NULL, 0, &strNeedLen))
{
dwRet = GetLastError();
}
else if(SetupGetStringField(&mfg, 1, szModName, strNeedLen, NULL))
{
// find Instance ID
if (!SetupFindFirstLine(hInf, szModName, NULL, &mfg))
dwRet = GetLastError();
else if(SetupGetStringField(&mfg, 2, NULL, 0, &strNeedLen))
{
if(SetupGetStringField(&mfg, 2, lptHardID, strNeedLen, NULL))
{
dwRet = 0;
}
else
dwRet = GetLastError();
}
else
{
dwRet = GetLastError();
}
}
}
return dwRet;
}
static DWORD RegisterDriver(HINF hInf, HWND hDlg)
{
DWORD dwRet = 0;
BOOL bResult = FALSE;
BOOL bFoundHardware = FALSE;
//{4D36E96F-E325-11CE-BFC1-08002BE10318}
GUID ClsGuid = {0x4D36E96F, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18} };
TCHAR lptHardwareID[MAX_PATH];
dwRet = GetHardID(hInf, lptHardwareID);
if(dwRet != 0)
{
goto ExitInstDriver;
}
HDEVINFO hDevInfoSet;
SP_DEVINFO_DATA m_DevInfo;
TCHAR m_DevInstID[MAX_PATH];
// First, get class device info set
hDevInfoSet = SetupDiGetClassDevs(&ClsGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
if(hDevInfoSet == INVALID_HANDLE_VALUE)
{
//report_last_error();
goto ExitInstDriver;
}
else
{
SP_DEVINFO_DATA DevInfo;
int i = 0;
// Second, get device info
while(1)
{
ZeroMemory(&DevInfo, sizeof(DevInfo));
DevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
if(!SetupDiEnumDeviceInfo(
hDevInfoSet,
i++,
&DevInfo
))
{
//report_last_error();
break;
}
else
{
// Third, look for Device Instance Id
TCHAR DevInstID[MAX_PATH];
DWORD dwSize = 0;
if(!SetupDiGetDeviceInstanceId(
hDevInfoSet,
&DevInfo,
DevInstID,
MAX_PATH,
&dwSize
))
{
//report_last_error();
break;
}
else if(_strnicmp(DevInstID, lptHardwareID, strlen(lptHardwareID)) == 0)
{
// found the hardware
m_DevInfo = DevInfo;
strcpy(m_DevInstID, DevInstID);
bFoundHardware = TRUE;
break;
}
}
}
if(!bFoundHardware)
{
// not found hardware
goto ExitInstDriver;
}
if(!SetupDiSetSelectedDevice(hDevInfoSet, &m_DevInfo))
{
//report_last_error();
goto ExitInstDriver;
}
SP_DEVINSTALL_PARAMS DevInstParams;
DevInstParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
if(!SetupDiGetDeviceInstallParams(hDevInfoSet, &m_DevInfo, &DevInstParams))
{
//report_last_error();
goto ExitInstDriver;
}
else
{
DevInstParams.Flags |= (DI_DONOTCALLCONFIGMG |
DI_PROPERTIES_CHANGE |
DI_SHOWOEM );
//DevInstParams.FileQueue = FileQueue;
strcpy(DevInstParams.DriverPath, g_szInfPathName);
if(!SetupDiSetDeviceInstallParams(hDevInfoSet, &m_DevInfo, &DevInstParams))
{
//report_last_error();
goto ExitInstDriver;
}
else
{
if(!SetupDiSelectDevice(hDevInfoSet, &m_DevInfo))
{
//report_last_error();
goto ExitInstDriver;
}
else if(!SetupDiInstallDevice(hDevInfoSet, &m_DevInfo))
{
//report_last_error();
goto ExitInstDriver;
}
else
{
bResult = TRUE;
}
}
}
}
ExitInstDriver:
if(hDevInfoSet != INVALID_HANDLE_VALUE)
{
SetupDiDestroyDeviceInfoList(hDevInfoSet);
}
if(!bResult)
{
dwRet = GetLastError();
}
if(!bFoundHardware)
{
dwRet = 1;
}
return dwRet;
}
static DWORD CopyAllFiles(HANDLE hInf, HWND hDlg, HWND hProgress)
{
DWORD dwRet = 0;
char szSourcePath[MAX_PATH];
// Context for my call back routine
MY_INSTALL_DATA MyInstallData;
HSPFILEQ FileQueue;
BOOL bResult;
GetModuleFileName(NULL, szSourcePath, MAX_PATH);
*(strrchr(szSourcePath, '\\') + 1) = '\0'; // Strip setup.exe off path
FileQueue = SetupOpenFileQueue();
if(!FileQueue || (FileQueue == INVALID_HANDLE_VALUE))
{
dwRet = ERROR_NOT_ENOUGH_MEMORY;
return dwRet;
}
MyInstallData.hProgress = hProgress;
MyInstallData.pDefaultContext = SetupInitDefaultQueueCallbackEx(
hDlg, // HWND of owner window
(HWND)INVALID_HANDLE_VALUE, // HWND of alternate progress dialog which receives -- for example
// if you wanted to display your progress bar right in the wizard
0, // Message sent to above window indicating a progress message
0, // DWORD Reserved
NULL// PVOID Reserved
);
if(!(MyInstallData.pDefaultContext))
{
dwRet = ERROR_NOT_ENOUGH_MEMORY;
//
// Close the queue and the inf file and return
//
SetupCloseFileQueue(FileQueue);
return dwRet;
}
bResult = SetupInstallFilesFromInfSection(
hInf, // HINF that has the directory ids set above
NULL, // layout.inf if you have one, this a convient
// place to do all of your file to media id mapping
FileQueue, // Queue to add files to
TEXT("moufiltr"), // SectionName,
szSourcePath, // Path where the source files are located
SP_COPY_NEWER);// The controls how to version check
// and how to prompt
//
// All the files for each component are now in one queue
// now we commit it to start the copy ui, this way the
// user has one long copy progress dialog--and for a big install
// can go get the cup of coffee
//
if(bResult)
{
bResult = SetupCommitFileQueue(
hDlg, // Owner
FileQueue, // Queue with the file list
(PSP_FILE_CALLBACK) MyQueueCallback,
// This is our handler, it calls the default for us
// NOTE:
// (PSP_FILE_CALLBACK) SetupDefaultQueueCallback
// would use the default message handler automatically
&MyInstallData // Pointer to resources allocated with SetupInitDefaultQueueCallback/Ex
);
dwRet = bResult ? NO_ERROR : GetLastError();
}
else
{
dwRet = GetLastError();
}
bResult = SetupInstallFromInfSection(
hDlg,
hInf,
TEXT("moufiltr"),
SPINST_REGISTRY | SPINST_INIFILES,
NULL,
NULL,//szSourcePath, // Path where the source files are located
0,//SP_COPY_NEWER,
NULL,//(PSP_FILE_CALLBACK) MyQueueCallback,
NULL,//&MyInstallData,
NULL,
NULL
);
SetupTermDefaultQueueCallback(MyInstallData.pDefaultContext);
SetupCloseFileQueue(FileQueue);
return dwRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -