syssetup!Wizard函数分析之comctl32!_CreatePropertySheetPage
sysetup!Wizard函数分析之comctl32!_CreatePropertySheetPage
//
// These MUST be in the same order as the items in the WizPage enum!!!
//
WIZPAGE SetupWizardPages[WizPageMaximum] = {
//
// Welcome page
//
{
PSWIZB_NEXT,
0,
{ sizeof(PROPSHEETPAGE), // size of struct
PSP_HIDEHEADER, // full-size page, no header
NULL, // hinst (filled in at run time)
MAKEINTRESOURCE(IDD_WELCOME), // dlg template
NULL, // icon
NULL, // title
WelcomeDlgProc, // dlg proc
0, // lparam
NULL, // callback
NULL // ref count
}},
//
// Product id page for CD
//
{
PSWIZB_NEXT | PSWIZB_BACK,
0,
{ sizeof(PROPSHEETPAGE), // size of struct
PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE,
NULL, // hinst (filled in at run time)
MAKEINTRESOURCE(IDD_PID_CD), // dlg template
NULL, // icon
NULL, // title
Pid30CDDlgProc, // dlg proc
0, // lparam
NULL, // callback
NULL, // ref count
(LPCWSTR)IDS_PID, // title
(LPCWSTR)IDS_PID_SUB // subtitle
}},
./setupp.h:944: WizPageProductIdCd,
VOID
Wizard(
#ifdef _OCM
IN PVOID OcManagerContext
#else
VOID
#endif
)
{
WizardPageHandles[PageCount] = CreatePropertySheetPage(
&SetupWizardPages[PageOrdinal].Page
);
typedef struct _WIZPAGE {
UINT ButtonState;
UINT Spare;
PROPSHEETPAGE Page;
} WIZPAGE, *PWIZPAGE;
//
// CreatePropertySheetPage
//
// Where HPROPSHEETPAGEs come from.
//
// The fNeedShadow parameter means "The incoming LPCPROPSHEETPAGE is in the
// opposite character set from what you implement natively".
//
// If we are compiling UNICODE, then fNeedShadow is TRUE if the incoming
// LPCPROPSHEETPAGE is really an ANSI property sheet page.
//
// If we are compiling ANSI-only, then fNeedShadow is always FALSE because
// we don't support UNICODE in the ANSI-only version.
//
HPROPSHEETPAGE WINAPI _CreatePropertySheetPage(LPCPROPSHEETPAGE psp, BOOL fNeedShadow, BOOL fWx86)
{
PISP pisp;
DWORD dwSize;
ASSERT(PROPSHEETPAGEA_V1_SIZE == PROPSHEETPAGEW_V1_SIZE);
ASSERT(sizeof(PROPSHEETPAGEA) == sizeof(PROPSHEETPAGEW));
if ((psp->dwSize < MINPROPSHEETPAGESIZE) ||
(psp->dwSize > 4096) || // or the second version
(psp->dwFlags & ~PSP_ALL)) // bogus flag used
return NULL;
//
// The PROPSHEETPAGE structure can be larger than the
// defined size. This allows ISV's to place private
// data at the end of the structure. The ISP structure
// consists of some private fields and a PROPSHEETPAGE
// structure. Calculate the size of the private fields,
// and then add in the dwSize field to determine the
// amount of memory necessary.
//
//
// An ISP consists of the "above" part, the "below" part, and
// the baggage passed by the app. Negative baggage is okay;
// it means we have a down-level app that doesn't know about
// pszHeaderTitle.
//
//
// If we have an "other" client, then the native side of the
// property sheet doesn't carry any baggage. It's just a
// plain old PROPSHEETPAGE.
//
dwSize = fNeedShadow ? sizeof(PROPSHEETPAGE) : psp->dwSize;
pisp = AllocPropertySheetPage(dwSize);
if (pisp)
{
STRDUPPROC pfnStrDup;
#ifdef WX86
//
// We we're being called by Wx86, set the flag so we remember.
//
if ( fWx86 ) {
pisp->_pfx.dwInternalFlags |= PSPI_WX86;
}
#endif
SETORIGINALSIZE(pisp, dwSize);
//
// Bulk copy the contents of the PROPSHEETPAGE, or
// as much of it as the app gave us.
//
hmemcpy(&pisp->_psp, psp, min(dwSize, psp->dwSize));
//
// Decide how to copy the strings
//
if (fNeedShadow)
pfnStrDup = StrDup_AtoW;
else
pfnStrDup = StrDup;
// Now copy them
if (!CopyPropertyPageStrings(&pisp->_psp, pfnStrDup))
goto ExitStrings;
if (fNeedShadow)
{
PISP pispAnsi = AllocPropertySheetPage(psp->dwSize);
if (!pispAnsi)
goto ExitShadow;
//
// Copy the entire client PROPSHEETPAGE, including the
// baggage.
//
hmemcpy(&pispAnsi->_psp, psp, psp->dwSize);
//
// Hook the two copies to point to each other.
//
pisp->_cpfx.pispShadow = pispAnsi;
pispAnsi->_cpfx.pispShadow = pispAnsi;
pispAnsi->_cpfx.pispMain = pisp;
//
// If there is a shadow, then the
// external handle is the ANSI shadow.
//
ASSERT(pispAnsi->_pfx.hpage == (HPROPSHEETPAGE)pispAnsi);
pisp->_pfx.hpage = (HPROPSHEETPAGE)pispAnsi;
//
// Okay, now StrDupA them strings.
//
if (!CopyPropertyPageStrings(&pispAnsi->_psp, (STRDUPPROC)StrDupA))
goto ExitShadowStrings;
}
//
// Increment the reference count to the parent object.
//
if (HASREFPARENT(pisp))
InterlockedIncrement((LPLONG)pisp->_psp.pcRefParent);
//
// Welcome to the world.
//
CallPropertyPageCallback(pisp, PSPCB_ADDREF);
return ExternalizeHPROPSHEETPAGE(pisp);
}
else
{
return NULL;
}
ExitShadowStrings:
FreePropertyPageStrings(&pisp->_cpfx.pispShadow->_psp);
FreePropertyPageStruct(pisp->_cpfx.pispShadow);
ExitShadow:;
ExitStrings:
FreePropertyPageStrings(&pisp->_psp);
FreePropertyPageStruct(pisp);
return NULL;
}
#undef fNeedShadow
