summaryrefslogtreecommitdiff
path: root/print/XPSDrvSmpl/src/ui/xdsmplui.cpp
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-04-29 09:48:49 -0700
committerDave Wilson <[email protected]>2015-04-29 10:47:29 -0700
commitd40232638faaab19de557e70a3ee938da7a35295 (patch)
tree14e61c973745949af186b7940e3a53d25322f5de /print/XPSDrvSmpl/src/ui/xdsmplui.cpp
parent02e5b090a6131a7cc1b90f4a9373117c9e3c7088 (diff)
samples update for //build
Diffstat (limited to 'print/XPSDrvSmpl/src/ui/xdsmplui.cpp')
-rw-r--r--print/XPSDrvSmpl/src/ui/xdsmplui.cpp1018
1 files changed, 1018 insertions, 0 deletions
diff --git a/print/XPSDrvSmpl/src/ui/xdsmplui.cpp b/print/XPSDrvSmpl/src/ui/xdsmplui.cpp
new file mode 100644
index 00000000..b41116a6
--- /dev/null
+++ b/print/XPSDrvSmpl/src/ui/xdsmplui.cpp
@@ -0,0 +1,1018 @@
+/*++
+
+Copyright (c) 2005 Microsoft Corporation
+
+All rights reserved.
+
+THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+PARTICULAR PURPOSE.
+
+File Name:
+
+ xdsmplui.cpp
+
+Abstract:
+
+ Implementation of the UI plugin. This is responsible for initialising and maintaining
+ the property pages used in the XPSDrv feature sample UI.
+
+--*/
+
+#include "precomp.h"
+#include "debug.h"
+#include "globals.h"
+#include "xdexcept.h"
+#include "xdstring.h"
+#include "xdsmplui.h"
+#include "colppg.h"
+#include "wmppg.h"
+#include "ftrppg.h"
+#include "UIProperties.h"
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::CXDSmplUI
+
+Routine Description:
+
+ CXDSmplUI class constructor.
+ Creates a handler class object for every property page added in Unidrv UI Plug-in.
+ Each of these handlers is stored in a collection.
+
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+
+--*/
+CXDSmplUI::CXDSmplUI() :
+ CUnknown<IPrintOemUI>(IID_IPrintOemUI),
+ m_pDriverUIHelp(NULL),
+ m_pOemCUIPParam(NULL),
+ m_pUIProperties(NULL)
+{
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::~CXDSmplUI
+
+Routine Description:
+
+ CXDSmplUI class destructor.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None.
+
+--*/
+CXDSmplUI::~CXDSmplUI()
+{
+ DestroyPropPages();
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::PublishDriverInterface
+
+Routine Description:
+
+ The PublishDriverInterface method allows a user interface plug-in to obtain
+ the Unidrv driver's IPrintOemDriverUI interface.
+
+Arguments:
+
+ pIUnknown - Caller-supplied pointer to the IUnknown interface of the driver's
+ IPrintOemDriverUI COM Interface.
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+HRESULT
+CXDSmplUI::PublishDriverInterface(
+ _In_ IUnknown* pIUnknown
+ )
+{
+ HRESULT hr = E_FAIL;
+ PVOID pInterface = NULL;
+
+ if (m_pDriverUIHelp == NULL &&
+ SUCCEEDED(hr = pIUnknown->QueryInterface(IID_IPrintOemDriverUI, &pInterface)))
+ {
+ m_pDriverUIHelp = reinterpret_cast<IPrintOemDriverUI*>(pInterface);
+ hr = S_OK;
+ }
+
+ return hr;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::GetInfo
+
+Routine Description:
+
+ Unidrv will call this routine to obtain identification information.
+
+Arguments:
+
+ dwMode - Supported modes are OEMGI_GETSIGNATURE and OEMGI_GETVERSION.
+ pBuffer - Caller-supplied pointer to memory allocated to receive the information specified by dwMode.
+ cbSize - Caller-supplied size of the buffer pointed to by pBuffer.
+ pcbNeeded - Caller-supplied pointer to a location to receive the number of bytes written into the buffer pointed to by pBuffer.
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+HRESULT
+CXDSmplUI::GetInfo(
+ _In_ DWORD dwMode,
+ _Out_writes_bytes_(cbSize) PVOID pBuffer,
+ _In_ DWORD cbSize,
+ _Out_ PDWORD pcbNeeded
+ )
+{
+ HRESULT hr = S_OK;
+
+ if ((NULL == pcbNeeded) ||
+ ((OEMGI_GETSIGNATURE != dwMode) &&
+ (OEMGI_GETVERSION != dwMode) &&
+ (OEMGI_GETREQUESTEDHELPERINTERFACES != dwMode)))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ hr = E_INVALIDARG;
+ }
+ else
+ {
+ *pcbNeeded = sizeof(DWORD);
+
+ if ((cbSize < *pcbNeeded) ||
+ (NULL == pBuffer))
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+ }
+ else
+ {
+ switch (dwMode)
+ {
+ case OEMGI_GETSIGNATURE:
+ {
+ *reinterpret_cast<PDWORD>(pBuffer) = OEM_SIGNATURE;
+ }
+ break;
+
+ case OEMGI_GETVERSION:
+ {
+ *reinterpret_cast<PDWORD>(pBuffer) = OEM_VERSION;
+ }
+ break;
+
+ default:
+ {
+ *pcbNeeded = 0;
+ hr = E_NOTIMPL;
+ }
+ break;
+ }
+ }
+ }
+
+ ERR_ON_HR_EXC(hr, E_NOTIMPL);
+ return hr;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DevMode
+
+Routine Description:
+
+ Performs operation on UI Plugins Private DevMode Members.
+ Called via IPrintOemUI::DevMode
+
+Arguments:
+
+ dwMode - Supported modes are OEMDM_SIZE, OEMDM_DEFAULT, OEMDM_CONVERT and OEMDM_MERGE.
+ pOemDMParam - Caller-supplied pointer to an OEMDMPARAM structure.
+ Dependent on which dwMode is set.
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+HRESULT
+CXDSmplUI::DevMode(
+ _In_ DWORD dwMode,
+ _In_ POEMDMPARAM pOemDMParam
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (SUCCEEDED(hr = CHECK_POINTER(pOemDMParam, E_POINTER)))
+ {
+ if ((OEMDM_SIZE != dwMode) &&
+ (OEMDM_DEFAULT != dwMode) &&
+ (OEMDM_CONVERT != dwMode)&&
+ (OEMDM_MERGE != dwMode))
+ {
+ hr = E_INVALIDARG;
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ switch (dwMode)
+ {
+ //
+ // The method should return the size of the memory allocation needed to store the UI plugin Private DEVMODE.
+ //
+ case OEMDM_SIZE:
+ {
+ pOemDMParam->cbBufSize = sizeof(OEMDEV);
+ }
+ break;
+
+ //
+ // Should fill the Private DEVMODE with the default values.
+ //
+ case OEMDM_DEFAULT:
+ {
+ try
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pOemDMParam->pOEMDMOut, E_POINTER)))
+ {
+ CUIProperties oemDevOut = CUIProperties(reinterpret_cast<POEMDEV>(pOemDMParam->pOEMDMOut));
+
+ hr = oemDevOut.SetDefaults();
+ }
+ }
+ catch (CXDException &e)
+ {
+ hr = e;
+ }
+ catch (...)
+ {
+ hr = E_FAIL;
+ }
+ }
+ break;
+
+ //
+ // The method should convert private DEVMODE members to the current version, if necessary.
+ //
+ case OEMDM_CONVERT:
+ {
+ try
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pOemDMParam->pOEMDMOut, E_POINTER)) &&
+ SUCCEEDED(hr = CHECK_POINTER(pOemDMParam->pOEMDMIn, E_POINTER)))
+ {
+ CUIProperties oemDevIn = CUIProperties(reinterpret_cast<POEMDEV>(pOemDMParam->pOEMDMIn));
+ CUIProperties oemDevOut = CUIProperties(reinterpret_cast<POEMDEV>(pOemDMParam->pOEMDMOut));
+
+ hr = oemDevOut.Convert(&oemDevIn);
+ }
+ }
+ catch (CXDException &e)
+ {
+ hr = e;
+ }
+ catch (...)
+ {
+ hr = E_FAIL;
+ }
+ }
+ break;
+
+ //
+ //The method should validate the information contained in private DEVMODE members and merge validated values into a private DEVMODE structure containing default values
+ //
+ case OEMDM_MERGE:
+ {
+ try
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pOemDMParam->pOEMDMOut, E_POINTER)) &&
+ SUCCEEDED(hr = CHECK_POINTER(pOemDMParam->pOEMDMIn, E_POINTER)))
+ {
+ CUIProperties oemDevIn = CUIProperties(reinterpret_cast<POEMDEV>(pOemDMParam->pOEMDMIn));
+ CUIProperties oemDevOut = CUIProperties(reinterpret_cast<POEMDEV>(pOemDMParam->pOEMDMOut));
+
+ if (SUCCEEDED(hr = oemDevOut.Convert(&oemDevIn)))
+ {
+ hr = oemDevOut.Validate();
+ }
+ }
+ }
+ catch (CXDException &e)
+ {
+ hr = e;
+ }
+ catch (...)
+ {
+ hr = E_FAIL;
+ }
+ }
+ break;
+ }
+ }
+
+ ERR_ON_HR(hr);
+ return hr;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::CommonUIProp
+
+Routine Description:
+
+ This method allows a user interface plug-in to modify an existing printer property sheet page.
+
+Arguments:
+
+ dwMode - Supported modes are OEMCUIP_DOCPROP and OEMCUIP_PRNPROP.
+ pOemCUIPParam - Caller-supplied pointer to an OEMCUIPPARAM structure.
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+HRESULT
+CXDSmplUI::CommonUIProp(
+ _In_ DWORD dwMode,
+ _In_ POEMCUIPPARAM pOemCUIPParam
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (dwMode == OEMCUIP_PRNPROP)
+ {
+ //
+ // We do not implement any printer property sheets
+ //
+ hr = E_NOTIMPL;
+ }
+ else if (dwMode != OEMCUIP_DOCPROP)
+ {
+ //
+ // Unknown mode encountered
+ //
+ hr = E_INVALIDARG;
+ }
+
+ if (SUCCEEDED(hr) &&
+ SUCCEEDED(hr = CHECK_POINTER(pOemCUIPParam, E_POINTER)))
+ {
+ //
+ // Store the OEMCUIPPARAM pointer so we can modify data and OPTITEMS.
+ //
+ m_pOemCUIPParam = pOemCUIPParam;
+
+ //
+ // The pDrvOptItems member is NULL on the first call through to CommonUIProp().
+ //
+ if (pOemCUIPParam->pDrvOptItems != NULL)
+ {
+ try
+ {
+ CUIProperties uiProperties;
+ hr = uiProperties.HideOptItems(pOemCUIPParam);
+ }
+ catch (CXDException& e)
+ {
+ hr = e;
+ }
+ catch (...)
+ {
+ hr = E_FAIL;
+ }
+ }
+ }
+
+ ERR_ON_HR_EXC(hr, E_NOTIMPL);
+ return hr;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DocumentPropertySheets
+
+Routine Description:
+
+ This method allows a user interface plug-in to append a new page to a printer device's
+ document property sheet.
+
+Arguments:
+
+ pPSUIInfo - Caller-supplied pointer to a PROPSHEETUI_INFO structure.
+ lParam - Caller-supplied value that depends on the reason value in pPSUIInfo->Reason.
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+HRESULT
+CXDSmplUI::DocumentPropertySheets(
+ _In_ PPROPSHEETUI_INFO pPSUIInfo,
+ _In_ LPARAM lParam
+ )
+{
+ HRESULT hr = S_OK;
+
+ if (pPSUIInfo == NULL ||
+ pPSUIInfo->Version != PROPSHEETUI_INFO_VERSION)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ hr = E_INVALIDARG;
+ }
+ else
+ {
+ switch (pPSUIInfo->Reason)
+ {
+ case PROPSHEETUI_REASON_INIT:
+ {
+ //
+ // We need to report the OEMCUIPPARAM structure to the prop sheet
+ // so ASSERT it is valid. We will let the prop sheet decide if it
+ // is critical to have a valid pointer or not
+ //
+ ASSERTMSG(m_pOemCUIPParam != NULL, "NULL pointer to OEMCUIPPARAM structure.\n");
+
+ try
+ {
+ //
+ // Create the UI properties object
+ //
+ m_pUIProperties = new(std::nothrow) CUIProperties(reinterpret_cast<POEMDEV>(m_pOemCUIPParam->pOEMDM));
+
+ //
+ // Create the property pages for the document property sheet
+ //
+ if (SUCCEEDED(hr = CHECK_POINTER(m_pUIProperties, E_OUTOFMEMORY)) &&
+ SUCCEEDED(hr = CreatePropertyPages()))
+ {
+ DocPropertyPageMap::iterator iterPropSheets = m_vectPropPages.begin();
+
+ //
+ // Make sure the helper interfaces and the OEMCUIPPARAM structure
+ // are published to the page first. This allows the prop sheet to
+ // propogate these interfaces to the UI control objects when initializing
+ //
+ while (iterPropSheets != m_vectPropPages.end() &&
+ SUCCEEDED(hr = CHECK_POINTER(*iterPropSheets, E_FAIL)) &&
+ SUCCEEDED(hr = (*iterPropSheets)->SetPrintOemDriverUI(m_pDriverUIHelp)) &&
+ SUCCEEDED(hr = (*iterPropSheets)->SetOemCUIPParam(m_pOemCUIPParam))&&
+ SUCCEEDED(hr = (*iterPropSheets)->SetUIProperties(m_pUIProperties))&&
+ SUCCEEDED(hr = (*iterPropSheets)->PropPageInit(pPSUIInfo)))
+ {
+ iterPropSheets++;
+ }
+ }
+ }
+ catch (CXDException &e)
+ {
+ hr = e;
+ }
+ catch (exception& DBG_ONLY(e))
+ {
+ ERR(e.what());
+ hr = E_FAIL;
+ }
+ }
+ break;
+
+ case PROPSHEETUI_REASON_GET_INFO_HEADER:
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pPSUIInfo, E_POINTER)))
+ {
+ pPSUIInfo->Result = TRUE;
+ }
+ }
+ break;
+
+ case PROPSHEETUI_REASON_DESTROY:
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pPSUIInfo, E_POINTER)))
+ {
+ pPSUIInfo->Result = TRUE;
+ }
+ }
+ break;
+
+ case PROPSHEETUI_REASON_SET_RESULT:
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pPSUIInfo, E_POINTER)))
+ {
+ pPSUIInfo->Result = reinterpret_cast<PSETRESULT_INFO>(lParam)->Result;
+ }
+ }
+ break;
+
+ case PROPSHEETUI_REASON_GET_ICON:
+ {
+ if (SUCCEEDED(hr = CHECK_POINTER(pPSUIInfo, E_POINTER)))
+ {
+ //
+ // No icon
+ //
+ pPSUIInfo->Result = FALSE;
+ }
+ }
+ break;
+
+ default:
+ {
+ hr = E_FAIL;
+ }
+ break;
+ }
+ }
+
+ ERR_ON_HR(hr);
+ return hr;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DevicePropertySheets
+
+Routine Description:
+
+ This method allows a user interface plug-in to append a new page to a printer device's
+ printer property sheet.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::DevicePropertySheets(
+ _In_ PPROPSHEETUI_INFO,
+ _In_ LPARAM
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DevQueryPrintEx
+
+Routine Description:
+
+ This method allows a user interface plug-in to help determine if a print job is printable.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::DevQueryPrintEx(
+ _In_ POEMUIOBJ,
+ _In_ PDEVQUERYPRINT_INFO,
+ _In_ PDEVMODE,
+ _In_ PVOID
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DeviceCapabilities
+
+Routine Description:
+
+ This method enables a user interface plug-in to specify customized device capabilities.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::DeviceCapabilities(
+ _In_ POEMUIOBJ,
+ _In_ HANDLE,
+ _In_z_ PWSTR,
+ _In_ WORD,
+ _In_ PVOID,
+ _In_ PDEVMODE,
+ _In_ PVOID,
+ _In_ DWORD,
+ _In_ DWORD*
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::UpgradePrinter
+
+Routine Description:
+
+ This method allows a user interface plug-in to upgrade device option values
+ that are stored in the registry.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::UpgradePrinter(
+ _In_ DWORD,
+ _In_ PBYTE
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::PrinterEvent
+
+Routine Description:
+
+ This method allows a user interface plug-in to process printer events.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::PrinterEvent(
+ _In_ PWSTR ,
+ _In_ INT ,
+ _In_ DWORD ,
+ _In_ LPARAM
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DriverEvent
+
+Routine Description:
+
+ The printer driver's DrvDriverEvent function calls a user interface plug-in's
+ IPrintOemUI::DriverEvent method for additional processing of printer driver events.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::DriverEvent(
+ _In_ DWORD ,
+ _In_ DWORD ,
+ _In_reads_(_Inexpressible_("varies")) PBYTE ,
+ _In_ LPARAM
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::QueryColorProfile
+
+Routine Description:
+
+ This method allows a user interface plug-in to specify an ICC profile to use for color management.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::QueryColorProfile(
+ _In_ HANDLE ,
+ _In_ POEMUIOBJ ,
+ _In_ PDEVMODE ,
+ _In_ PVOID ,
+ _In_ ULONG ,
+ _Out_writes_(*pcbProfileData) VOID* ,
+ _Inout_ ULONG* pcbProfileData,
+ _Out_ FLONG*
+ )
+{
+ UNREFERENCED_PARAMETER(pcbProfileData);
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::FontInstallerDlgProc
+
+Routine Description:
+
+ A user interface plug-in's IPrintOemUI::FontInstallerDlgProc method replaces
+ the Unidrv font installer's user interface.
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::FontInstallerDlgProc(
+ _In_ HWND ,
+ _In_ UINT ,
+ _In_ WPARAM ,
+ _In_ LPARAM
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::UpdateExternalFonts
+
+Routine Description:
+
+ This allows a user interface plug-in to update a printer's Unidrv Font Format Files (.uff file).
+
+Arguments:
+
+ None referenced.
+
+Return Value:
+
+ HRESULT
+ E_NOTIMPL - Method not implemented
+
+--*/
+HRESULT
+CXDSmplUI::UpdateExternalFonts(
+ _In_ HANDLE,
+ _In_ HANDLE,
+ _In_z_ PWSTR
+ )
+{
+ return E_NOTIMPL;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::CreatePropertyPages
+
+Routine Description:
+
+ Creates all property page handler objects.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+HRESULT
+CXDSmplUI::CreatePropertyPages(
+ VOID
+ )
+{
+ HRESULT hr = S_OK;
+ CDocPropPage* pPropPage = NULL;
+
+//
+// This Prefast warning indicates that memory could be leaked
+// in the event of an exception. We suppress this false positive because we
+// know that the local try/catch block will clean up a single
+// CDocPropPage, and the destructor will clean up any that are
+// successfully added to the vector.
+//
+#pragma prefast(push)
+#pragma prefast(disable:__WARNING_ALIASED_MEMORY_LEAK_EXCEPTION)
+
+ try
+ {
+ //
+ // Populate the property page vector
+ //
+ pPropPage = new(std::nothrow) CColorPropPage();
+
+ hr = AddPropPage(pPropPage);
+
+ if (SUCCEEDED(hr))
+ {
+ pPropPage = new(std::nothrow) CWatermarkPropPage();
+ hr = AddPropPage(pPropPage);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ pPropPage = new(std::nothrow) CFeaturePropPage();
+ hr = AddPropPage(pPropPage);
+ }
+ }
+ catch (CXDException &e)
+ {
+ hr = e;
+ }
+ catch (exception& DBG_ONLY(e))
+ {
+ ERR(e.what());
+ hr = E_FAIL;
+ }
+
+ if (FAILED(hr))
+ {
+ //
+ // If we successfully created a property page but failed to push it onto
+ // the vector we need to free the allocated property page
+ //
+ if (pPropPage != NULL)
+ {
+ delete pPropPage;
+ pPropPage = NULL;
+ }
+ }
+
+#pragma prefast(pop)
+
+ return hr;
+}
+
+/*++
+
+Routine Name:
+
+ CXDSmplUI::DestroyPropPages
+
+Routine Description:
+
+ Destroy all property page handler classes that have been added into the collection.
+
+Arguments:
+
+ None
+
+Return Value:
+
+ HRESULT
+ S_OK - On success
+ E_* - On error
+
+--*/
+inline VOID
+CXDSmplUI::DestroyPropPages(
+ VOID
+ )
+{
+ while (!m_vectPropPages.empty())
+ {
+ if (m_vectPropPages.back() != NULL)
+ {
+ delete m_vectPropPages.back();
+ m_vectPropPages.back() = NULL;
+ }
+
+ m_vectPropPages.pop_back();
+ }
+
+ if (m_pUIProperties != NULL)
+ {
+ delete m_pUIProperties;
+ m_pUIProperties = NULL;
+ }
+}
+
+//
+// Use __drv_aliasesMem annotation to avoid PREfast warning 28197: Possibly leaking memory,
+//
+HRESULT
+// Prefast warning 28194: The function was declared as aliasing the value in variable and exited without doing so.
+// We suppress this false positive because STL vector does not have annotation, and we know the pointer has been saved
+// to STL vector, which is released in DestroyPropPages().
+#pragma warning(suppress: 28194)
+CXDSmplUI::AddPropPage(
+ _In_opt_ __drv_aliasesMem CDocPropPage* pPropPage
+ )
+{
+ HRESULT hr = CHECK_POINTER(pPropPage, E_OUTOFMEMORY);
+
+ if (SUCCEEDED(hr))
+ {
+ m_vectPropPages.push_back(pPropPage);
+ }
+
+ return hr;
+}
+