#include "pch.h" #pragma hdrstop #include "nceh.h" #include "wizard.h" #include "ncnetcfg.h" #include "lancmn.h" #include "cfg.h" #include "wgenericpage.h" // // Function: CWizProvider::CWizProvider // // Purpose: ctor for the CWizProvider class // // Parameters: pPL - Info corresponding to a Connection UI Object // // Returns: nothing // CWizProvider::CWizProvider(ProviderList *pPL, BOOL fDeferLoad) { TraceFileFunc(ttidGuiModeSetup); memcpy(&m_guidUiObject, pPL->pguidProvider, sizeof(GUID)); m_ulMaxPageCount = 0xFFFFFFFF; m_ulPageCnt = 0; m_ulPageBufferLen = 0; m_rghPages = NULL; m_pWizardUi = NULL; m_fDeletePages = TRUE; m_nBtnIdc = pPL->nBtnIdc; m_fDeferLoad = fDeferLoad; } // // Function: CWizProvider::~CWizProvider // // Purpose: dtor for the CWizProvider class // // Parameters: none // // Returns: nothing // CWizProvider::~CWizProvider() { TraceFileFunc(ttidGuiModeSetup); if (m_fDeletePages) { DeleteHPages(); } MemFree(m_rghPages); ReleaseObj(m_pWizardUi); } // // Function: CWizProvider::HrCreate // // Purpose: Two phase constructor for the CWizProvider class // // Parameters: pPL [IN] - Provider info from which to query the // INetConnectionWizardUi interface. // pProvider [OUT] - If this function succeeds this pointer // will contain the constructed and // initialized CWizProvider instance. // fDeferLoad [IN] - Request the provider defer actual load // // Returns: HRESULT, S_OK on success // NOTHROW HRESULT CWizProvider::HrCreate(ProviderList *pPL, CWizProvider ** ppProvider, BOOL fDeferLoad) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = S_OK; CWizProvider *pprov = NULL; Assert((NULL != pPL) && (NULL != ppProvider)); // Initialize output parameters *ppProvider = NULL; // Create the CWizProvider instance pprov = new CWizProvider(pPL, fDeferLoad); if ((NULL != pprov) && (FALSE == fDeferLoad)) { Assert(pPL->pguidProvider); hr = CoCreateInstance( reinterpret_cast(*pPL->pguidProvider), NULL, CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD, IID_INetConnectionWizardUi, (LPVOID*)&pprov->m_pWizardUi); TraceHr(ttidError, FAL, hr, FALSE, "CoCreateInstance"); if (FAILED(hr)) { delete pprov; pprov = NULL; } } // Save the new instance *ppProvider = pprov; TraceHr(ttidWizard, FAL, hr, (REGDB_E_CLASSNOTREG == hr), "CWizProvider::HrCreate"); return hr; } // // Function: CWizProvider::HrCompleteDeferredLoad // // Purpose: Complete the steps necessary to load what was a defer load object // // Parameters: none // // Returns: HRESULT, S_OK on success // HRESULT CWizProvider::HrCompleteDeferredLoad() { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = S_OK; if (m_fDeferLoad) { m_fDeferLoad = FALSE; // Attempt to create the UI Object // hr = CoCreateInstance( reinterpret_cast(m_guidUiObject), NULL, CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD, IID_INetConnectionWizardUi, (LPVOID*)&m_pWizardUi); } TraceHr(ttidWizard, FAL, hr, FALSE, "CWizProvider::HrCompleteDeferredLoad"); return hr; } // // Function: CWizProvider::UlGetMaxPageCount // // Purpose: Queries from the provider the maximum number of pages // that it will return. Subsequent calls to this routine // return the cached count without requerying the provider. // // Parameters: pContext [IN] - Context information, supplied either by // Setup or by the wizard itself (when not // launched from Setup). // // Returns: ULONG, Maximum number of pages provider will return. // NOTHROW ULONG CWizProvider::UlGetMaxPageCount(INetConnectionWizardUiContext *pContext) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = S_OK; if (NULL == m_pWizardUi) { m_ulMaxPageCount = 0; } else if (0xFFFFFFFF == m_ulMaxPageCount) { // Query the provider only once m_ulMaxPageCount = 0L; COM_PROTECT_TRY { Assert(NULL != m_pWizardUi); Assert(NULL != pContext); DWORD dwCount = 0L; hr = m_pWizardUi->QueryMaxPageCount(pContext, &dwCount); if (S_OK == hr) { m_ulMaxPageCount = dwCount; } } COM_PROTECT_CATCH } TraceHr(ttidWizard, FAL, hr, FALSE, "CWizProvider::GetMaxPageCount"); return m_ulMaxPageCount; } // // Function: CWizProvider::DeleteHPages // // Purpose: Call DestroyPropertySheetPage for each cached page // // Parameters: none // // Returns: nothing // VOID CWizProvider::DeleteHPages() { TraceFileFunc(ttidGuiModeSetup); for (ULONG ulIdx=0; ulIdx < ULPageCount(); ulIdx++) { DestroyPropertySheetPage(m_rghPages[ulIdx]); } m_ulPageCnt=0; } // // Function: CWizProvider::HrAddPages // // Purpose: Calls the AddPages method of a provider's // INetConnectionWizardUi interface to allow for the // supply of Wizard Pages // // Parameters: pContext [IN] - Context information, supplied either by // Setup or by the wizard itself (when not // launched from Setup). // // Returns: HRESULT, S_OK on success // NOTHROW HRESULT CWizProvider::HrAddPages(INetConnectionWizardUiContext *pContext) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = S_OK; if (m_pWizardUi) { COM_PROTECT_TRY { // Ensure input params are valid Assert(NULL != m_pWizardUi); Assert(NULL != pContext); hr = m_pWizardUi->AddPages(pContext, CWizProvider::FAddPropSheet, reinterpret_cast(this)); } COM_PROTECT_CATCH } else { hr = E_NOINTERFACE; } TraceHr(ttidWizard, FAL, hr, FALSE, "CWizProvider::HrAddPages"); return hr; } // // Function: CWizProvider::FAddPropSheet // // Purpose: Callback function for the AddPages API used to accept // wizard pages handed back from a provider. // // Parameters: hPage [IN] - The page to add // lParam [IN] - 'this' casted to an LPARAM // // Returns: BOOL, TRUE if the page was successfully added. // BOOL CWizProvider::FAddPropSheet(HPROPSHEETPAGE hPage, LPARAM lParam) { TraceFileFunc(ttidGuiModeSetup); CWizProvider * pProvider; // Validate the input parameters if ((0L == lParam) || (NULL == hPage)) { Assert(lParam); Assert(hPage); TraceHr(ttidWizard, FAL, E_INVALIDARG, FALSE, "CWizProvider::FAddPropSheet"); return FALSE; } pProvider = reinterpret_cast(lParam); // Grow the buffer if necessary if (pProvider->m_ulPageCnt == pProvider->m_ulPageBufferLen) { HPROPSHEETPAGE* rghPages = reinterpret_cast( MemAlloc(sizeof(HPROPSHEETPAGE) * (pProvider->m_ulPageBufferLen + 10))); if (NULL == rghPages) { TraceHr(ttidWizard, FAL, E_OUTOFMEMORY, FALSE, "CWizProvider::FAddPropSheet"); return FALSE; } // Copy the existing pages to the new buffer if (NULL != pProvider->m_rghPages) { memcpy(rghPages, pProvider->m_rghPages, sizeof(HPROPSHEETPAGE) * pProvider->m_ulPageBufferLen); MemFree(pProvider->m_rghPages); } pProvider->m_rghPages = rghPages; pProvider->m_ulPageBufferLen += 10; } // Retain the new page pProvider->m_rghPages[pProvider->m_ulPageCnt++] = hPage; return TRUE; } // // Function: CWizProvider::HrGetLanInterface // // Purpose: Get the special LAN interface // // Parameters: ppIntr [OUT] - The special LAN specific interface // // Returns: HRESULT, S_OK on success // HRESULT CWizProvider::HrGetLanInterface(INetLanConnectionWizardUi ** ppIntr) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr; Assert(NULL != ppIntr); Assert(NULL != m_pWizardUi); *ppIntr = NULL; hr = m_pWizardUi->QueryInterface(IID_INetLanConnectionWizardUi, (LPVOID *)ppIntr); TraceHr(ttidWizard, FAL, hr, FALSE, "CWizProvider::HrGetLanInterface"); return hr; } // // Function: CWizProvider::HrSpecifyAdapterGuid // // Purpose: To notify the provider of the adapter guid to process // // Parameters: pguid [IN] - The adapter guid to process // // Returns: HRESULT, S_OK on success // HRESULT CWizProvider::HrSpecifyAdapterGuid(GUID *pguid) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr; INetLanConnectionWizardUi *pIntr = NULL; hr = HrGetLanInterface(&pIntr); if (SUCCEEDED(hr)) { hr = pIntr->SetDeviceComponent(pguid); ReleaseObj(pIntr); } TraceHr(ttidWizard, FAL, hr, FALSE, "CWizProvider::HrSpecifyAdapterGuid"); return hr; } CAdapterList::CAdapterList() { m_prgAdapters = NULL; // Adapter array m_clAdapters = 0; // Count of adapters in the array m_lBufSize = 0; // Total available slots in the array m_lIdx = -1; // Current adapter index // Range is -1 to m_clAdapters m_fAdaptersInstalled = FALSE; // No adapters on the machine } AdapterEntry * CAdapterList::PAE_Current() { TraceFileFunc(ttidGuiModeSetup); if ((m_lIdx > -1) && (m_lIdx < m_clAdapters)) { Assert(NULL != m_prgAdapters); return &m_prgAdapters[m_lIdx]; } else { return NULL; } } AdapterEntry * CAdapterList::PAE_Next() { // Find the next, not hidden adapter // // Hidden adapters are those which were processed by a previous // run of setup // // Increment the index even if the count is zero // m_lIdx == -1 means before the first adapter // m_lIdx == m_clAdapters means after the last adapter while (m_lIdx < m_clAdapters) { m_lIdx++; if ((m_lIdx < m_clAdapters) && (!m_prgAdapters[m_lIdx].fHide)) break; } Assert(m_lIdx >= -1); return PAE_Current(); } AdapterEntry * CAdapterList::PAE_Prev() { // Find the previous, not hidden adapter // // Hidden adapters are those which were processed by a previous // run of setup // // Decrement the index even if the count is zero // m_lIdx == -1 means before the first adapter // m_lIdx == m_clAdapters means after the last adapter while (-1 < m_lIdx) { m_lIdx--; if ((-1 < m_lIdx) && (!m_prgAdapters[m_lIdx].fHide)) break; } Assert(m_lIdx < m_clAdapters); return PAE_Current(); } GUID * CAdapterList::NextAdapter() { AdapterEntry * pae = PAE_Next(); if (NULL != pae) return &(pae->guidAdapter); else return NULL; } GUID * CAdapterList::PrevAdapter() { AdapterEntry * pae = PAE_Prev(); if (NULL != pae) return &(pae->guidAdapter); else return NULL; } GUID * CAdapterList::CurrentAdapter() { AdapterEntry * pae = PAE_Current(); if (NULL != pae) return &(pae->guidAdapter); else return NULL; } VOID CAdapterList::EmptyList() { if (NULL != m_prgAdapters) { MemFree(m_prgAdapters); m_prgAdapters = NULL; m_clAdapters = 0; // Count of adapters in the array m_lBufSize = 0; // Total available slots in the array m_lIdx = -1; } } VOID CAdapterList::HideAllAdapters() { for (LONG lIdx=0; lIdx < m_clAdapters; lIdx++) m_prgAdapters[lIdx].fHide = TRUE; } VOID CAdapterList::UnhideNewAdapters() { for (LONG lIdx=0; lIdx < m_clAdapters; lIdx++) if (m_prgAdapters[lIdx].fNew) { m_prgAdapters[lIdx].fHide = FALSE; } } HRESULT CAdapterList::HrAppendEntries(AdapterEntry * pae, ULONG cae) { if (0 == cae) { return S_OK; } if (m_clAdapters + (LONG)cae > m_lBufSize) { // Grow the buffer AdapterEntry * prg = reinterpret_cast( MemAlloc(sizeof(AdapterEntry) * (m_lBufSize + cae + 10))); if (NULL == prg) { TraceHr(ttidWizard, FAL, E_OUTOFMEMORY, FALSE, "CAdapterList::HrAppendEntries"); return E_OUTOFMEMORY; } // Copy the existing pages to the new buffer if (NULL != m_prgAdapters) { memcpy(prg, m_prgAdapters, sizeof(AdapterEntry) * m_lBufSize); MemFree(m_prgAdapters); } m_prgAdapters = prg; m_lBufSize += (cae + 10); } memcpy(&m_prgAdapters[m_clAdapters], pae, cae * sizeof(AdapterEntry)); m_clAdapters += cae; return S_OK; } // // Function: CAdapterList::HrQueryLanAdapters // // Purpose: Query the available LAN adapters. // // Parameters: pnc [IN] - An INetCfg interface // pAL [IN,OUT] - Receives the list of LAN adapters // // Returns: HRESULT, S_OK on success // HRESULT CAdapterList::HrQueryLanAdapters(INetCfg * pnc, CAdapterList * pAL) { HRESULT hr = S_OK; CAdapterList ALphys; CAdapterList ALvirt; TraceTag(ttidWizard, "CAdapterList::HrQueryLanAdapters - Querying available adapters"); // Enumerate the available adapters Assert(NULL != pnc); CIterNetCfgComponent nccIter(pnc, &GUID_DEVCLASS_NET); INetCfgComponent* pncc; while (SUCCEEDED(hr) && (S_OK == (hr = nccIter.HrNext(&pncc)))) { hr = HrIsLanCapableAdapter(pncc); if (S_OK == hr) { DWORD dw; AdapterEntry ae; ae.fHide = FALSE; // Get the adapter instance guid hr = pncc->GetInstanceGuid(&ae.guidAdapter); if (FAILED(hr)) goto NextAdapter; // Is it in used in a connection? hr = HrIsConnection(pncc); if (FAILED(hr)) goto NextAdapter; ae.fProcessed = (S_OK == hr); ae.fNew = !ae.fProcessed; // It's new if it has not been processed // Check device, if not present skip it // hr = pncc->GetDeviceStatus(&dw); if (FAILED(hr) || (CM_PROB_DEVICE_NOT_THERE == dw)) { goto NextAdapter; } // Is this a virtual adapter? hr = pncc->GetCharacteristics(&dw); if (FAILED(hr)) goto NextAdapter; ae.fVirtual = ((dw & NCF_VIRTUAL) ? TRUE : FALSE); // Add the entry to the appropriate list if (ae.fVirtual) { hr = ALvirt.HrAppendEntries(&ae, 1); } else { hr = ALphys.HrAppendEntries(&ae, 1); } if (FAILED(hr)) goto NextAdapter; // Note the fact that LAN capable adapters exist. // Because in setup we will show the join page. pAL->m_fAdaptersInstalled = TRUE; } NextAdapter: ReleaseObj(pncc); hr = S_OK; } if (SUCCEEDED(hr)) { // Merge the physical and virtual lists into the pAL input variable pAL->EmptyList(); hr = pAL->HrAppendEntries(ALphys.m_prgAdapters, ALphys.m_clAdapters); if (SUCCEEDED(hr)) { hr = pAL->HrAppendEntries(ALvirt.m_prgAdapters, ALvirt.m_clAdapters); } } TraceHr(ttidWizard, FAL, hr, FALSE, "CAdapterList::HrQueryUnboundAdapters"); return hr; } HRESULT CAdapterList::HrCreateTypicalConnections(CWizard * pWizard) { HRESULT hr = S_OK; // If there are no adapters in the queue or we have no LAN provider... if (0 == pWizard->UlProviderCount()) { return S_OK; } // Set the current provider pWizard->SetCurrentProvider(0); CWizProvider * pWizProvider = pWizard->GetCurrentProvider(); Assert(NULL != pWizProvider); TraceTag(ttidWizard, "CAdapterList::HrCreateTypicalConnections - Creating any new LAN connections."); // For each adapter in the list create a connection for (LONG lIdx=0; lIdxfProcessed) { #if DBG WCHAR szGuid[c_cchGuidWithTerm]; szGuid[0] = 0; StringFromGUID2(pae->guidAdapter, szGuid, c_cchGuidWithTerm); TraceTag(ttidWizard, " Guid: %S",szGuid); #endif pae->fProcessed = TRUE; // Push the adapter guid onto the provider hr = pWizProvider->HrSpecifyAdapterGuid(&(pae->guidAdapter)); if (SUCCEEDED(hr)) { tstring str; INetConnection * pConn = NULL; GenerateUniqueConnectionName(pae->guidAdapter, &str, pWizProvider); TraceTag(ttidWizard, " Name: %S", str.c_str()); hr = (pWizProvider->PWizardUi())->GetNewConnection(&pConn); ReleaseObj(pConn); } // If we failed to create a connection we need to mark it as hidden // so it will be skipped in the future. Eat the error or otherwise // setup will just stop. // if (FAILED(hr)) { TraceHr(ttidWizard, FAL, hr, FALSE, "CAdapterList::HrCreateTypicalConnections - failed creating the connection"); pae->fHide = TRUE; hr = S_OK; } } } // Ask the LAN provider to release any cached pointers. // (VOID)pWizProvider->HrSpecifyAdapterGuid(NULL); TraceHr(ttidWizard, FAL, hr, FALSE, "CAdapterList::HrCreateTypicalConnections"); return hr; } HRESULT CAdapterList::HrQueryUnboundAdapters(CWizard * pWizard) { HRESULT hr = S_OK; LONG lIdx; Assert(NULL != pWizard->PNetCfg()); // Handle the first time the adapters are queried if (0 == m_clAdapters) { hr = HrQueryLanAdapters(pWizard->PNetCfg(), this); if (SUCCEEDED(hr)) { // Mark all already bound adapters as hidden so they // won't be displayed in the UI for (lIdx=0; lIdxPNetCfg(), &AL); if (FAILED(hr)) goto Error; // Eliminate adapters in the original set which are not // present in new list for (lIdx=0; lIdxOperationFlags; m_UMMode = UM_DEFAULTHIDE; m_ulCurProvider = 0; m_ulPageDataCnt = 0; ZeroMemory(m_rgPageData, sizeof(m_rgPageData)); m_ulWizProviderCnt = 0; m_ulPageDataMRU = 0; ZeroMemory(m_rgpWizProviders, sizeof(m_rgpWizProviders)); } // // Function: CWizard::~CWizard // // Purpose: dtor for the CWizProvider class // // Parameters: none // // Returns: nothing // // Note: Remove CWizard member re-init from dtor. Present only // to ensure complete appropriate release of all members CWizard::~CWizard() { TraceFileFunc(ttidGuiModeSetup); ULONG ulIdx; // Call the cleanup callback for all registered wizard internal pages for (ulIdx = 0; ulIdx < m_ulPageDataCnt; ulIdx++) { if (m_rgPageData[ulIdx].pfn) { m_rgPageData[ulIdx].pfn(this, m_rgPageData[ulIdx].lParam); } } m_ulPageDataCnt = 0L; // Note: Do not release m_pSetupData, it's only a reference m_pSetupData = NULL; // Release any providers that had been retained for (ulIdx = 0; ulIdx < m_ulWizProviderCnt; ulIdx++) { Assert(0 != m_rgpWizProviders[ulIdx]); delete m_rgpWizProviders[ulIdx]; m_rgpWizProviders[ulIdx] = NULL; } m_ulWizProviderCnt = 0L; m_ulCurProvider = 0; ReleaseObj(m_pUiContext); m_pUiContext = NULL; ReleaseObj(m_pConn); m_pConn = NULL; if (m_pNetCfg) { (VOID)HrUninitializeAndReleaseINetCfg(FCoUninit(), m_pNetCfg, TRUE); } m_pNetCfg = NULL; } // // Function: CWizard::HrCreate // // Purpose: Two phase constructor for the CWizard class // // Parameters: ppWizard [OUT] - If this function succeeds this pointer // will contain the constructed and // fLanPages [IN] - Processing LAN pages // initialized CWizard instance. // pdata [IN] - Wizard Context info // fDeferred [IN] - Providers are defer loaded // // Returns: HRESULT, S_OK on success // NOTHROW HRESULT CWizard::HrCreate(CWizard ** ppWizard, BOOL fLanPages, PINTERNAL_SETUP_DATA pData, BOOL fDeferred) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = S_OK; CWizardUiContext * pContext = NULL; CWizard * pWiz = NULL; Assert(NULL != ppWizard); // Initialize output parameters *ppWizard = NULL; // Create the CWizard instance pWiz = new CWizard(fLanPages, pData, fDeferred); pContext = new CWizardUiContext(pData); if ((NULL != pWiz) && (NULL != pContext)) { // Save the new instance pWiz->m_pUiContext = pContext; *ppWizard = pWiz; } else { hr = E_OUTOFMEMORY; } TraceHr(ttidWizard, FAL, hr, FALSE, "CWizard::HrCreate"); return hr; } // // Function: CWizard::HrAddProvider // // Purpose: To add a connection provider to list of currently loaded // connection providers // // Parameters: pPL [IN] - GUID of conection provider which implements the // INetConnectionWizardUi interface. // // Returns: HRESULT, S_OK on success // NOTHROW HRESULT CWizard::HrAddProvider(ProviderList *pPL) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = E_OUTOFMEMORY; CWizProvider * pProvider = NULL; Assert(NULL != pPL); Assert(m_eMaxProviders > m_ulWizProviderCnt); // Restrict the total number of providers managed if (m_eMaxProviders > m_ulWizProviderCnt) { // Instantiate a provider hr = CWizProvider::HrCreate(pPL, &pProvider, FDeferredProviderLoad()); if (SUCCEEDED(hr)) { m_rgpWizProviders[m_ulWizProviderCnt++] = pProvider; } } TraceHr(ttidWizard, FAL, hr, (REGDB_E_CLASSNOTREG == hr), "CWizard::HrAddProvider"); return hr; } // // Function: CWizard::LoadWizProviders // // Purpose: Load the requested wizard providers // // Parameters: ulCntProviders [IN] - Count of guids in rgpguidProviders // rgProviders [IN] - Guids of the providers to load // // Returns: none // VOID CWizard::LoadWizProviders( ULONG ulCntProviders, ProviderList * rgProviders) { if (0 == m_ulWizProviderCnt) { TraceTag(ttidWizard, "Loading requested providers"); // Load the connections providers used during Setup for (UINT nIdx=0; nIdx < ulCntProviders; nIdx++) { HRESULT hr = HrAddProvider(&rgProviders[nIdx]); TraceHr(ttidWizard, FAL, hr, FALSE, "FSetupRequestWizardPages - Failed to load provider #%d",nIdx); } } } // // Function: CWizard::HrCreateWizProviderPages // // Purpose: Load the requested wizard provider's pages, if requested. // Otherwise return the expected page count. // // Parameters: fCountOnly [IN] - If True, only the maximum number of // pages this routine will create need // be determined. // pnPages [IN] - Increment by the number of pages // to create/created // // Returns: HRESULT, S_OK on success // HRESULT CWizard::HrCreateWizProviderPages(BOOL fCountOnly, UINT *pcPages) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr = S_OK; ULONG ulCnt = 0; ULONG ulIdx; Assert(NULL != m_pSetupData); Assert(NULL != m_pUiContext); // If provider loading was deferred, load them now // if (FDeferredProviderLoad()) { // Count the maximum number of pages for (ulIdx=0; ulIdxHrCompleteDeferredLoad(); } // Deferred Load is no longer true. Reset the state // DeferredLoadComplete(); } if (fCountOnly) { // Count the maximum number of pages for (ulIdx=0; ulIdxUlGetMaxPageCount(m_pUiContext)) { ulCnt += m_rgpWizProviders[ulIdx]->UlGetMaxPageCount(m_pUiContext); ulCnt += 1; // For the guard page } } } else { TraceTag(ttidWizard, "Loading each providers pages"); bCallRasDlgEntry = TRUE; // Load the pages for (ulIdx=0; ulIdxUlGetMaxPageCount(m_pUiContext)); if (0 != m_rgpWizProviders[ulIdx]->UlGetMaxPageCount(m_pUiContext)) { HRESULT hrTmp = m_rgpWizProviders[ulIdx]->HrAddPages(m_pUiContext); TraceHr(ttidWizard, FAL, hrTmp, S_FALSE == hrTmp, "CWizard::HrCreateWizProviderPages - %d", ulIdx); // We only care about out of memory errors when adding pages. // Providers which fail to add pages are removed from the // provider list m_rgpWizProviders. // if (E_OUTOFMEMORY == hrTmp) { hr = hrTmp; goto Error; } } } // Cull the providers which loaded no pages ULONG ulNewCnt = 0; for (ulIdx=0; ulIdxULPageCount()) { m_rgpWizProviders[ulNewCnt++] = m_rgpWizProviders[ulIdx]; } else { delete m_rgpWizProviders[ulIdx]; } } m_ulWizProviderCnt = ulNewCnt; // Now count how many provider pages were actually loaded, and create // their associated guard pages for (ulIdx=0; ulIdxULPageCount()) { // Create the guard page for this provider // Note that the guard page's id is (CWizProvider *) hr = HrCreateGuardPage(this, m_rgpWizProviders[ulIdx]); if (SUCCEEDED(hr)) { // Includes the guard page ulCnt += (m_rgpWizProviders[ulIdx]->ULPageCount() + 1); } else { m_rgpWizProviders[ulIdx]->DeleteHPages(); TraceHr(ttidWizard, FAL, hr, FALSE,"CWizard::HrCreateWizProviderPages - Guard Page Create Failed"); hr = S_OK; } } } } (*pcPages) += ulCnt; Error: TraceHr(ttidWizard, FAL, hr, S_FALSE == hr,"CWizard::HrCreateWizProviderPages"); return hr; } // // Function: CWizard:AppendProviderPages // // Purpose: Append wizard provider pages and their associated guard pages // to the HPROPSHEETPAGE array // // Parameters: pahpsp [IN,OUT] - Ptr to the HPROPSHEETPAGE array which will // receive the provider pages. // pcPages [IN] - Ptr to indicate the number of pages added to // the pahpsp array // Returns: nothing // VOID CWizard::AppendProviderPages(HPROPSHEETPAGE *pahpsp, UINT *pcPages) { TraceFileFunc(ttidGuiModeSetup); ULONG ulIdx; // Now count how many provider pages were actually loaded, and create // their associated guard pages for (ulIdx=0; ulIdxULPageCount(); if (ulPageCnt) { m_rgpWizProviders[ulIdx]->XFerDeleteResponsibilities(); // Copy the providers pages memcpy(&pahpsp[*pcPages], m_rgpWizProviders[ulIdx]->PHPropPages(), sizeof(HPROPSHEETPAGE) * ulPageCnt); (*pcPages) += ulPageCnt; // Append the guard page AppendGuardPage(this, m_rgpWizProviders[ulIdx], pahpsp, pcPages); } } } // // Function: CWizard:LoadAndInsertDeferredProviderPages // // Purpose: Insert wizard provider pages and their associated guard pages // directly into the wizard // // Parameters: hwndPropSheet [IN] - Handle to the property sheet // iddAfterPage [IN] - Page to insert after. // // Returns: nothing // VOID CWizard::LoadAndInsertDeferredProviderPages(HWND hwndPropSheet, UINT iddAfterPage) { TraceFileFunc(ttidGuiModeSetup); HRESULT hr; UINT cPages = 0; // Create the pages // hr = HrCreateWizProviderPages(FALSE, &cPages); if (SUCCEEDED(hr)) { HPROPSHEETPAGE hPage = GetPageHandle(iddAfterPage); Assert(hPage); for (ULONG ulIdx=0; ulIdxULPageCount(); Assert(0xFFFFFFFF != ulPageCnt); if (ulPageCnt) { BOOL fRet; HPROPSHEETPAGE hpsp = NULL; m_rgpWizProviders[ulIdx]->XFerDeleteResponsibilities(); // Get the guard page and insert // cPages = 0; AppendGuardPage(this, m_rgpWizProviders[ulIdx], &hpsp, &cPages); fRet = PropSheet_InsertPage(hwndPropSheet, hPage, hpsp); Assert(fRet); // Copy the providers pages. do { hpsp = (m_rgpWizProviders[ulIdx]->PHPropPages())[ulPageCnt - 1]; fRet = PropSheet_InsertPage(hwndPropSheet, hPage, hpsp); Assert(fRet); } while (--ulPageCnt>0); } } } TraceHr(ttidWizard, FAL, hr, FALSE,"CWizard::LoadAndInsertDeferredProviderPages"); } // // Function: CWizard::RegisterPage // // Purpose: Allow a wizard internal page to register a callback function // and a page specific LPARAM along with the HPROPSHEETPAGE. // // Parameters: ulId [IN] - A page specific value, must be unique amoung // all registering pages // hpsp [IN] - Handle to the property page being registered // pfnCleanup [IN] - Callback function to call before CWizard // is destroyed. // lParam [IN] - Page specific parameter. // // Returns: nothing // VOID CWizard::RegisterPage(LPARAM ulId, HPROPSHEETPAGE hpsp, PFNPAGECLEANPROC pfnCleanup, LPARAM lParam) { TraceFileFunc(ttidGuiModeSetup); #if DBG Assert(m_eMaxInternalPages + m_eMaxProviders> m_ulPageDataCnt); for (UINT nIdx=0;nIdx