//+--------------------------------------------------------------------------- // // Microsoft Windows NT Security // Copyright (C) Microsoft Corporation, 1992 - 1999 // // File: acuictl.cpp // // Contents: Authenticode Default UI controls // // History: 12-May-97 kirtd Created // //---------------------------------------------------------------------------- #include #include #include "secauth.h" IACUIControl::IACUIControl(CInvokeInfoHelper& riih) : m_riih( riih ), m_hrInvokeResult( TRUST_E_SUBJECT_NOT_TRUSTED ) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED; m_pszCopyActionText = NULL; m_pszCopyActionTextNoTS = NULL; m_pszCopyActionTextNotSigned = NULL; if ((riih.ProviderData()) && (riih.ProviderData()->psPfns) && (riih.ProviderData()->psPfns->psUIpfns) && (riih.ProviderData()->psPfns->psUIpfns->psUIData)) { if (_ISINSTRUCT(CRYPT_PROVUI_DATA, riih.ProviderData()->psPfns->psUIpfns->psUIData->cbStruct, pCopyActionTextNotSigned)) { this->LoadActionText(&m_pszCopyActionText, riih.ProviderData()->psPfns->psUIpfns->psUIData->pCopyActionText, IDS_ACTIONSIGNED); this->LoadActionText(&m_pszCopyActionTextNoTS, riih.ProviderData()->psPfns->psUIpfns->psUIData->pCopyActionTextNoTS, IDS_ACTIONSIGNED_NODATE); this->LoadActionText(&m_pszCopyActionTextNotSigned, riih.ProviderData()->psPfns->psUIpfns->psUIData->pCopyActionTextNotSigned, IDS_ACTIONNOTSIGNED); } } if (!(m_pszCopyActionText)) { this->LoadActionText(&m_pszCopyActionText, NULL, IDS_ACTIONSIGNED); } if (!(m_pszCopyActionTextNoTS)) { this->LoadActionText(&m_pszCopyActionTextNoTS, NULL, IDS_ACTIONSIGNED_NODATE); } if (!(m_pszCopyActionTextNotSigned)) { this->LoadActionText(&m_pszCopyActionTextNotSigned, NULL, IDS_ACTIONNOTSIGNED); } } void IACUIControl::LoadActionText(WCHAR **ppszRet, WCHAR *pwszIn, DWORD dwDefId) { WCHAR sz[MAX_PATH]; *ppszRet = NULL; sz[0] = NULL; if ((pwszIn) && (*pwszIn)) { sz[0] = NULL; if (wcslen(pwszIn) < MAX_PATH) { wcscpy(&sz[0], pwszIn); } if (sz[0]) { if (*ppszRet = new WCHAR[wcslen(&sz[0]) + 1]) { wcscpy(*ppszRet, &sz[0]); } } } if (!(sz[0])) { sz[0] = NULL; LoadStringU(g_hModule, dwDefId, &sz[0], MAX_PATH); if (sz[0]) { if (*ppszRet = new WCHAR[wcslen(&sz[0]) + 1]) { wcscpy(*ppszRet, &sz[0]); } } } } IACUIControl::~IACUIControl () { DELETE_OBJECT(m_pszCopyActionText); DELETE_OBJECT(m_pszCopyActionTextNoTS); DELETE_OBJECT(m_pszCopyActionTextNotSigned); } void IACUIControl::SetupButtons(HWND hWnd) { char sz[MAX_PATH]; if ((m_riih.ProviderData()) && (m_riih.ProviderData()->psPfns) && (m_riih.ProviderData()->psPfns->psUIpfns) && (m_riih.ProviderData()->psPfns->psUIpfns->psUIData)) { if (m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pYesButtonText) { if (!(m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pYesButtonText[0])) { ShowWindow(GetDlgItem(hWnd, IDYES), SW_HIDE); } else { SetWindowTextU(GetDlgItem(hWnd, IDYES), m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pYesButtonText); } } if (m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pNoButtonText) { if (!(m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pNoButtonText[0])) { ShowWindow(GetDlgItem(hWnd, IDNO), SW_HIDE); } else { SetWindowTextU(GetDlgItem(hWnd, IDNO), m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pNoButtonText); } } } } //+--------------------------------------------------------------------------- // // Member: IACUIControl::OnUIMessage, public // // Synopsis: responds to UI messages // // Arguments: [hwnd] -- window // [uMsg] -- message id // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if message processing should continue, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- BOOL IACUIControl::OnUIMessage ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_INITDIALOG: { BOOL fReturn; HICON hIcon; fReturn = OnInitDialog(hwnd, wParam, lParam); ACUICenterWindow(hwnd); // hIcon = LoadIcon((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDI_LOCK)); // dwOrigIcon = SetClassLongPtr(hwnd, GCLP_HICON, // (LONG_PTR)LoadIcon((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), // MAKEINTRESOURCE(IDI_LOCK))); // PostMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); // PostMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); return( fReturn ); } break; case WM_COMMAND: { WORD wNotifyCode = HIWORD(wParam); WORD wId = LOWORD(wParam); HWND hwndControl = (HWND)lParam; if ( wNotifyCode == BN_CLICKED ) { if ( wId == IDYES ) { return( OnYes(hwnd) ); } else if ( wId == IDNO ) { return( OnNo(hwnd) ); } else if ( wId == IDMORE ) { return( OnMore(hwnd) ); } } return( FALSE ); } break; case WM_CLOSE: return( OnNo(hwnd) ); break; default: return( FALSE ); } return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::CVerifiedTrustUI, public // // Synopsis: Constructor // // Arguments: [riih] -- invoke info helper reference // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- CVerifiedTrustUI::CVerifiedTrustUI (CInvokeInfoHelper& riih, HRESULT& rhr) : IACUIControl( riih ), m_pszInstallAndRun( NULL ), m_pszAuthenticity( NULL ), m_pszCaution( NULL ), m_pszPersonalTrust( NULL ) { DWORD_PTR aMessageArgument[3]; // // Initialize the hot-link subclass data // m_lsdPublisher.uId = IDC_PUBLISHER; m_lsdPublisher.hwndParent = NULL; m_lsdPublisher.wpPrev = (WNDPROC)NULL; m_lsdPublisher.pvData = (LPVOID)&riih; m_lsdPublisher.uToolTipText = IDS_CLICKHEREFORCERT; m_lsdOpusInfo.uId = IDC_INSTALLANDRUN; m_lsdOpusInfo.hwndParent = NULL; m_lsdOpusInfo.wpPrev = (WNDPROC)NULL; m_lsdOpusInfo.pvData = &riih; m_lsdOpusInfo.uToolTipText = (DWORD_PTR)riih.ControlWebPage(); m_lsdCA.uId = IDC_AUTHENTICITY; m_lsdCA.hwndParent = NULL; m_lsdCA.wpPrev = (WNDPROC)NULL; m_lsdCA.pvData = &riih; m_lsdCA.uToolTipText = (DWORD_PTR)riih.CAWebPage(); // IDS_CLICKHEREFORCAINFO; m_lsdAdvanced.uId = IDC_ADVANCED; m_lsdAdvanced.hwndParent = NULL; m_lsdAdvanced.wpPrev = (WNDPROC)NULL; m_lsdAdvanced.pvData = &riih; m_lsdAdvanced.uToolTipText = IDS_CLICKHEREFORADVANCED; // // Format the install and run string // aMessageArgument[2] = NULL; if (m_riih.CertTimestamp()) { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionText; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = (DWORD_PTR)m_riih.CertTimestamp(); } else { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionTextNoTS; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = NULL; } rhr = FormatACUIResourceString(0, aMessageArgument, &m_pszInstallAndRun); // // Format the authenticity string // if ( rhr == S_OK ) { aMessageArgument[0] = (DWORD_PTR)m_riih.PublisherCertIssuer(); rhr = FormatACUIResourceString( IDS_AUTHENTICITY, aMessageArgument, &m_pszAuthenticity ); } // // Get the publisher as a message argument // aMessageArgument[0] = (DWORD_PTR)m_riih.Publisher(); // // Format the caution string // if ( rhr == S_OK ) { rhr = FormatACUIResourceString( IDS_CAUTION, aMessageArgument, &m_pszCaution ); } // // Format the personal trust string // if ( rhr == S_OK ) { rhr = FormatACUIResourceString( IDS_PERSONALTRUST, aMessageArgument, &m_pszPersonalTrust ); } } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::~CVerifiedTrustUI, public // // Synopsis: Destructor // // Arguments: (none) // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- CVerifiedTrustUI::~CVerifiedTrustUI () { DELETE_OBJECT(m_pszInstallAndRun); DELETE_OBJECT(m_pszAuthenticity); DELETE_OBJECT(m_pszCaution); DELETE_OBJECT(m_pszPersonalTrust); } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::InvokeUI, public // // Synopsis: invoke the UI // // Arguments: [hDisplay] -- parent window // // Returns: S_OK, user trusts the subject // TRUST_E_SUBJECT_NOT_TRUSTED, user does NOT trust the subject // Any other valid HRESULT // // Notes: // //---------------------------------------------------------------------------- HRESULT CVerifiedTrustUI::InvokeUI (HWND hDisplay) { // // Bring up the dialog // if ( DialogBoxParamU( g_hModule, (LPWSTR) MAKEINTRESOURCE(IDD_DIALOG1_VERIFIED), hDisplay, ACUIMessageProc, (LPARAM)this ) == -1 ) { return( HRESULT_FROM_WIN32(GetLastError()) ); } // // The result has been stored as a member // return( m_hrInvokeResult ); } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::OnInitDialog, public // // Synopsis: dialog initialization // // Arguments: [hwnd] -- dialog window // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if successful init, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- BOOL CVerifiedTrustUI::OnInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam) { WCHAR psz[MAX_LOADSTRING_BUFFER]; HWND hControl; int deltavpos = 0; int deltaheight; int bmptosep; int septodlg; int savevpos; int hkcharpos; RECT rect; // // Setup the publisher link subclass data parent window // m_lsdPublisher.hwndParent = hwnd; m_lsdOpusInfo.hwndParent = hwnd; m_lsdCA.hwndParent = hwnd; m_lsdAdvanced.hwndParent = hwnd; // // Render the install and run string // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_INSTALLANDRUN, IDC_PUBLISHER, m_pszInstallAndRun, deltavpos, (m_riih.ControlWebPage()) ? TRUE : FALSE, (WNDPROC)ACUILinkSubclass, &m_lsdOpusInfo, 0, m_riih.Subject()); // // Render the publisher, give it a "link" look and feel if it is a known // publisher // // // if there was a test cert in the chain, add it to the text... // if (m_riih.TestCertInChain()) { WCHAR *pszCombine; pszCombine = new WCHAR[wcslen(m_riih.Publisher()) + wcslen(m_riih.TestCertInChain()) + 3]; if (pszCombine != NULL) { wcscpy(pszCombine, m_riih.Publisher()); wcscat(pszCombine, L"\r\n"); wcscat(pszCombine, m_riih.TestCertInChain()); deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PUBLISHER, IDC_AUTHENTICITY, pszCombine, deltavpos, m_riih.IsKnownPublisher() && m_riih.IsCertViewPropertiesAvailable(), (WNDPROC)ACUILinkSubclass, &m_lsdPublisher, 0, NULL ); delete[] pszCombine; } if (LoadStringU(g_hModule, IDS_TESTCERTTITLE, psz, MAX_LOADSTRING_BUFFER) != 0) { int wtlen; wtlen = wcslen(psz) + GetWindowTextLength(hwnd); pszCombine = new WCHAR[wtlen + 1]; if (pszCombine != NULL) { #if (0) // DSIE: Wrong buffer length specified. We don't have wtlen + 1, instead, // we only have GetWindowTextLength(hwnd) + 1. GetWindowTextU(hwnd, pszCombine, wtlen + 1); #else GetWindowTextU(hwnd, pszCombine, GetWindowTextLength(hwnd) + 1); #endif wcscat(pszCombine, psz); SetWindowTextU(hwnd, pszCombine); delete[] pszCombine; } } } else { deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PUBLISHER, IDC_AUTHENTICITY, m_riih.Publisher(), deltavpos, m_riih.IsKnownPublisher() && m_riih.IsCertViewPropertiesAvailable(), (WNDPROC)ACUILinkSubclass, &m_lsdPublisher, 0, NULL ); } // // Render the authenticity statement // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_AUTHENTICITY, IDC_CAUTION, m_pszAuthenticity, deltavpos, (m_riih.CAWebPage()) ? TRUE : FALSE, (WNDPROC)ACUILinkSubclass, &m_lsdCA, 0, m_riih.PublisherCertIssuer()); // // Render the caution statement // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_CAUTION, IDC_ADVANCED, m_pszCaution, deltavpos, FALSE, NULL, NULL, 0, NULL ); // // Render the advanced string // if ((m_riih.AdvancedLink()) && (m_riih.ProviderData()->psPfns->psUIpfns->pfnOnAdvancedClick)) { deltavpos = RenderACUIStringToEditControl( hwnd, IDC_ADVANCED, IDC_PERSONALTRUST, m_riih.AdvancedLink(), deltavpos, TRUE, (WNDPROC)ACUILinkSubclass, &m_lsdAdvanced, 0, NULL ); } else { ShowWindow(GetDlgItem(hwnd, IDC_ADVANCED), SW_HIDE); } // // Calculate the distances from the bottom of the bitmap to the top // of the separator and from the bottom of the separator to the bottom // of the dialog // bmptosep = CalculateControlVerticalDistance( hwnd, IDC_VERBMP, IDC_SEPARATORLINE ); septodlg = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE ); // // Rebase the check box and render the personal trust statement or hide // them the publisher is not known // if ( m_riih.IsKnownPublisher() == TRUE ) { hControl = GetDlgItem(hwnd, IDC_PTCHECK); RebaseControlVertical( hwnd, hControl, NULL, FALSE, deltavpos, 0, bmptosep, &deltaheight ); assert( deltaheight == 0 ); // // Find the hotkey character position for the personal trust // check box // #if (0) //DSIE: Bug 34325 hkcharpos = GetHotKeyCharPosition(GetDlgItem(hwnd, IDC_PTCHECK)); #else hkcharpos = GetHotKeyCharPositionFromString(m_pszPersonalTrust); #endif deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PERSONALTRUST, IDC_SEPARATORLINE, m_pszPersonalTrust, deltavpos, FALSE, NULL, NULL, bmptosep, NULL ); if ( hkcharpos != 0 ) { FormatHotKeyOnEditControl( GetDlgItem(hwnd, IDC_PERSONALTRUST), hkcharpos ); } } else { ShowWindow(GetDlgItem(hwnd, IDC_PTCHECK), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_PERSONALTRUST), SW_HIDE); } // // Rebase the static line // hControl = GetDlgItem(hwnd, IDC_SEPARATORLINE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); // // Rebase the buttons // hControl = GetDlgItem(hwnd, IDYES); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); hControl = GetDlgItem(hwnd, IDNO); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); hControl = GetDlgItem(hwnd, IDMORE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); // // Resize the bitmap and the dialog rectangle if necessary // if ( deltavpos > 0 ) { int cyupd; hControl = GetDlgItem(hwnd, IDC_VERBMP); GetWindowRect(hControl, &rect); cyupd = CalculateControlVerticalDistance( hwnd, IDC_VERBMP, IDC_SEPARATORLINE ); cyupd -= bmptosep; SetWindowPos( hControl, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); GetWindowRect(hwnd, &rect); cyupd = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE ); cyupd = septodlg - cyupd; SetWindowPos( hwnd, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); } // // check for overridden button texts // this->SetupButtons(hwnd); // // Set focus to appropriate control // hControl = GetDlgItem(hwnd, IDNO); ::PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM) hControl, (LPARAM) MAKEWORD(TRUE, 0)); return( FALSE ); } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::OnYes, public // // Synopsis: process IDYES button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CVerifiedTrustUI::OnYes (HWND hwnd) { // // Set the invoke result // m_hrInvokeResult = S_OK; // // Add the publisher to the trust database // if ( SendDlgItemMessage( hwnd, IDC_PTCHECK, BM_GETCHECK, 0, 0 ) == BST_CHECKED ) { m_riih.AddPublisherToPersonalTrust(); } // // End the dialog processing // EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::OnNo, public // // Synopsis: process IDNO button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CVerifiedTrustUI::OnNo (HWND hwnd) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED; EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CVerifiedTrustUI::OnMore, public // // Synopsis: process the IDMORE button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CVerifiedTrustUI::OnMore (HWND hwnd) { WinHelp(hwnd, "SECAUTH.HLP", HELP_CONTEXT, IDH_SECAUTH_SIGNED); // ACUIViewHTMLHelpTopic(hwnd, "sec_signed.htm"); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::CUnverifiedTrustUI, public // // Synopsis: Constructor // // Arguments: [riih] -- invoke info helper reference // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- CUnverifiedTrustUI::CUnverifiedTrustUI (CInvokeInfoHelper& riih, HRESULT& rhr) : IACUIControl( riih ), m_pszNoAuthenticity( NULL ), m_pszProblemsBelow( NULL ), m_pszInstallAndRun3( NULL ) { DWORD_PTR aMessageArgument[3]; // // Initialize the publisher link subclass data // m_lsdPublisher.uId = IDC_PUBLISHER; m_lsdPublisher.hwndParent = NULL; m_lsdPublisher.wpPrev = (WNDPROC)NULL; m_lsdPublisher.pvData = (LPVOID)&riih; m_lsdPublisher.uToolTipText = IDS_CLICKHEREFORCERT; m_lsdOpusInfo.uId = IDC_INSTALLANDRUN; m_lsdOpusInfo.hwndParent = NULL; m_lsdOpusInfo.wpPrev = (WNDPROC)NULL; m_lsdOpusInfo.pvData = &riih; m_lsdOpusInfo.uToolTipText = (DWORD_PTR)riih.ControlWebPage(); // IDS_CLICKHEREFOROPUSINFO; m_lsdAdvanced.uId = IDC_ADVANCED; m_lsdAdvanced.hwndParent = NULL; m_lsdAdvanced.wpPrev = (WNDPROC)NULL; m_lsdAdvanced.pvData = &riih; m_lsdAdvanced.uToolTipText = IDS_CLICKHEREFORADVANCED; // // Format the no authenticity string // rhr = FormatACUIResourceString( IDS_NOAUTHENTICITY, NULL, &m_pszNoAuthenticity ); // // Format the problems below string // if ( rhr == S_OK ) { aMessageArgument[0] = (DWORD_PTR)m_riih.ErrorStatement(); rhr = FormatACUIResourceString( IDS_PROBLEMSBELOW, aMessageArgument, &m_pszProblemsBelow ); } // // Format the install and run string // if ( rhr == S_OK ) { if (m_riih.CertTimestamp()) { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionText; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = (DWORD_PTR)m_riih.CertTimestamp(); } else { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionTextNoTS; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = NULL; } rhr = FormatACUIResourceString(0, aMessageArgument, &m_pszInstallAndRun3); } } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::~CUnverifiedTrustUI, public // // Synopsis: Destructor // // Arguments: (none) // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- CUnverifiedTrustUI::~CUnverifiedTrustUI () { DELETE_OBJECT(m_pszNoAuthenticity); DELETE_OBJECT(m_pszProblemsBelow); DELETE_OBJECT(m_pszInstallAndRun3); } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::InvokeUI, public // // Synopsis: invoke the UI // // Arguments: [hDisplay] -- parent window // // Returns: S_OK, user trusts the subject // TRUST_E_SUBJECT_NOT_TRUSTED, user does NOT trust the subject // Any other valid HRESULT // // Notes: // //---------------------------------------------------------------------------- HRESULT CUnverifiedTrustUI::InvokeUI (HWND hDisplay) { HRESULT hr = S_OK; // // Bring up the dialog // if ( DialogBoxParamU( g_hModule, (LPWSTR) MAKEINTRESOURCE(IDD_DIALOG2_UNVERIFIED), hDisplay, ACUIMessageProc, (LPARAM)this ) == -1 ) { return( HRESULT_FROM_WIN32(GetLastError()) ); } // // The result has been stored as a member // return( m_hrInvokeResult ); } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::OnInitDialog, public // // Synopsis: dialog initialization // // Arguments: [hwnd] -- dialog window // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if successful init, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- BOOL CUnverifiedTrustUI::OnInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam) { HWND hControl; int deltavpos = 0; int deltaheight; int bmptosep; int septodlg; RECT rect; // // Setup the publisher link subclass data parent window // m_lsdPublisher.hwndParent = hwnd; m_lsdOpusInfo.hwndParent = hwnd; m_lsdAdvanced.hwndParent = hwnd; // // Render the no authenticity statement // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_NOAUTHENTICITY, IDC_PROBLEMSBELOW, m_pszNoAuthenticity, deltavpos, FALSE, NULL, NULL, 0, NULL ); // // Render the problems below string // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PROBLEMSBELOW, IDC_INSTALLANDRUN3, m_pszProblemsBelow, deltavpos, FALSE, NULL, NULL, 0, NULL ); // // Render the install and run string // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_INSTALLANDRUN3, IDC_PUBLISHER2, m_pszInstallAndRun3, deltavpos, (m_riih.ControlWebPage()) ? TRUE : FALSE, (WNDPROC)ACUILinkSubclass, &m_lsdOpusInfo, 0, m_riih.Subject()); // // Calculate the distances from the bottom of the bitmap to the top // of the separator and from the bottom of the separator to the bottom // of the dialog // bmptosep = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP2, IDC_SEPARATORLINE ); septodlg = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE ); // // Render the publisher, give it a "link" look and feel // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PUBLISHER2, IDC_ADVANCED, m_riih.Publisher(), deltavpos, m_riih.IsKnownPublisher() && m_riih.IsCertViewPropertiesAvailable(), (WNDPROC)ACUILinkSubclass, &m_lsdPublisher, bmptosep, NULL ); if ((m_riih.AdvancedLink()) && (m_riih.ProviderData()->psPfns->psUIpfns->pfnOnAdvancedClick)) { deltavpos = RenderACUIStringToEditControl( hwnd, IDC_ADVANCED, IDC_SEPARATORLINE, m_riih.AdvancedLink(), deltavpos, TRUE, (WNDPROC)ACUILinkSubclass, &m_lsdAdvanced, 0, NULL ); } else { ShowWindow(GetDlgItem(hwnd, IDC_ADVANCED), SW_HIDE); } // // Rebase the static line // hControl = GetDlgItem(hwnd, IDC_SEPARATORLINE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); // // Rebase the buttons // hControl = GetDlgItem(hwnd, IDYES); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); hControl = GetDlgItem(hwnd, IDNO); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); hControl = GetDlgItem(hwnd, IDMORE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); // // Resize the bitmap and the dialog rectangle if necessary // if ( deltavpos > 0 ) { int cyupd; hControl = GetDlgItem(hwnd, IDC_NOVERBMP2); GetWindowRect(hControl, &rect); cyupd = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP2, IDC_SEPARATORLINE ); cyupd -= bmptosep; SetWindowPos( hControl, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); GetWindowRect(hwnd, &rect); cyupd = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE ); cyupd = septodlg - cyupd; SetWindowPos( hwnd, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); } // // check for overridden button texts // this->SetupButtons(hwnd); // // Set focus to appropriate control // hControl = GetDlgItem(hwnd, IDNO); ::PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM) hControl, (LPARAM) MAKEWORD(TRUE, 0)); return( FALSE ); } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::OnYes, public // // Synopsis: process IDYES button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CUnverifiedTrustUI::OnYes (HWND hwnd) { m_hrInvokeResult = S_OK; EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::OnNo, public // // Synopsis: process IDNO button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CUnverifiedTrustUI::OnNo (HWND hwnd) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED; EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CUnverifiedTrustUI::OnMore, public // // Synopsis: process the IDMORE button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CUnverifiedTrustUI::OnMore (HWND hwnd) { WinHelp(hwnd, "SECAUTH.HLP", HELP_CONTEXT, IDH_SECAUTH_SIGNED_N_INVALID); // ACUIViewHTMLHelpTopic(hwnd, "sec_signed_n_invalid.htm"); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::CNoSignatureUI, public // // Synopsis: Constructor // // Arguments: [riih] -- invoke info helper // [rhr] -- result code reference // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- CNoSignatureUI::CNoSignatureUI (CInvokeInfoHelper& riih, HRESULT& rhr) : IACUIControl( riih ), m_pszInstallAndRun2( NULL ), m_pszNoPublisherFound( NULL ) { DWORD_PTR aMessageArgument[2]; // // Format the install and run string // aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionTextNotSigned; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); rhr = FormatACUIResourceString(0, aMessageArgument, &m_pszInstallAndRun2); // // Format the no publisher found string // if ( rhr == S_OK ) { aMessageArgument[0] = (DWORD_PTR)m_riih.ErrorStatement(); rhr = FormatACUIResourceString( IDS_NOPUBLISHERFOUND, aMessageArgument, &m_pszNoPublisherFound ); } } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::~CNoSignatureUI, public // // Synopsis: Destructor // // Arguments: (none) // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- CNoSignatureUI::~CNoSignatureUI () { DELETE_OBJECT(m_pszInstallAndRun2); DELETE_OBJECT(m_pszNoPublisherFound); } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::InvokeUI, public // // Synopsis: invoke the UI // // Arguments: [hDisplay] -- parent window // // Returns: S_OK, user trusts the subject // TRUST_E_SUBJECT_NOT_TRUSTED, user does NOT trust the subject // Any other valid HRESULT // // Notes: // //---------------------------------------------------------------------------- HRESULT CNoSignatureUI::InvokeUI (HWND hDisplay) { HRESULT hr = S_OK; // // Bring up the dialog // if ( DialogBoxParamU( g_hModule, (LPWSTR) MAKEINTRESOURCE(IDD_DIALOG3_NOSIGNATURE), hDisplay, ACUIMessageProc, (LPARAM)this ) == -1 ) { return( HRESULT_FROM_WIN32(GetLastError()) ); } // // The result has been stored as a member // return( m_hrInvokeResult ); } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::OnInitDialog, public // // Synopsis: dialog initialization // // Arguments: [hwnd] -- dialog window // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if successful init, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- BOOL CNoSignatureUI::OnInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam) { HWND hControl; int deltavpos = 0; int deltaheight; int bmptosep; int septodlg; RECT rect; // // Render the install and run string // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_INSTALLANDRUN2, IDC_NOPUBLISHERFOUND, m_pszInstallAndRun2, deltavpos, FALSE, NULL, NULL, 0, NULL ); // // Calculate the distances from the bottom of the bitmap to the top // of the separator and from the bottom of the separator to the bottom // of the dialog // bmptosep = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP, IDC_SEPARATORLINE ); septodlg = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE ); // // Render the no publisher found statement // deltavpos = RenderACUIStringToEditControl( hwnd, IDC_NOPUBLISHERFOUND, IDC_SEPARATORLINE, m_pszNoPublisherFound, deltavpos, FALSE, NULL, NULL, bmptosep, NULL ); // // Rebase the static line // hControl = GetDlgItem(hwnd, IDC_SEPARATORLINE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); // // Rebase the buttons // hControl = GetDlgItem(hwnd, IDYES); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); hControl = GetDlgItem(hwnd, IDNO); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); hControl = GetDlgItem(hwnd, IDMORE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 ); // // Resize the bitmap and the dialog rectangle if necessary // if ( deltavpos > 0 ) { int cyupd; hControl = GetDlgItem(hwnd, IDC_NOVERBMP); GetWindowRect(hControl, &rect); cyupd = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP, IDC_SEPARATORLINE ); cyupd -= bmptosep; SetWindowPos( hControl, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); GetWindowRect(hwnd, &rect); cyupd = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE ); cyupd = septodlg - cyupd; SetWindowPos( hwnd, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); } // // check for overridden button texts // this->SetupButtons(hwnd); // // Set focus to appropriate control // hControl = GetDlgItem(hwnd, IDNO); ::PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM) hControl, (LPARAM) MAKEWORD(TRUE, 0)); return( FALSE ); } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::OnYes, public // // Synopsis: process IDYES button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CNoSignatureUI::OnYes (HWND hwnd) { m_hrInvokeResult = S_OK; EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::OnNo, public // // Synopsis: process IDNO button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CNoSignatureUI::OnNo (HWND hwnd) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED; EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); } //+--------------------------------------------------------------------------- // // Member: CNoSignatureUI::OnMore, public // // Synopsis: process the IDMORE button click // // Arguments: [hwnd] -- window handle // // Returns: TRUE // // Notes: // //---------------------------------------------------------------------------- BOOL CNoSignatureUI::OnMore (HWND hwnd) { WinHelp(hwnd, "SECAUTH.HLP", HELP_CONTEXT, IDH_SECAUTH_UNSIGNED); // ACUIViewHTMLHelpTopic(hwnd, "sec_unsigned.htm"); return( TRUE ); } //+--------------------------------------------------------------------------- // // Function: ACUIMessageProc // // Synopsis: message proc to process UI messages // // Arguments: [hwnd] -- window // [uMsg] -- message id // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if message processing should continue, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- INT_PTR CALLBACK ACUIMessageProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { IACUIControl* pUI = NULL; // // Get the control // if (uMsg == WM_INITDIALOG) { pUI = (IACUIControl *)lParam; SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam); } else { pUI = (IACUIControl *)GetWindowLongPtr(hwnd, DWLP_USER); } // // If we couldn't find it, we must not have set it yet, so ignore this // message // if ( pUI == NULL ) { return( FALSE ); } // // Pass the message on to the control // return( pUI->OnUIMessage(hwnd, uMsg, wParam, lParam) ); } int GetRichEditControlLineHeight(HWND hwnd) { RECT rect; POINT pointInFirstRow; POINT pointInSecondRow; int secondLineCharIndex; int i; RECT originalRect; GetWindowRect(hwnd, &originalRect); // // HACK ALERT, believe it or not there is no way to get the height of the current // font in the edit control, so get the position a character in the first row and the position // of a character in the second row, and do the subtraction to get the // height of the font // SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInFirstRow, (LPARAM) 0); // // HACK ON TOP OF HACK ALERT, // since there may not be a second row in the edit box, keep reducing the width // by half until the first row falls over into the second row, then get the position // of the first char in the second row and finally reset the edit box size back to // it's original size // secondLineCharIndex = (int)SendMessageA(hwnd, EM_LINEINDEX, (WPARAM) 1, (LPARAM) 0); if (secondLineCharIndex == -1) { for (i=0; i<20; i++) { GetWindowRect(hwnd, &rect); SetWindowPos( hwnd, NULL, 0, 0, (rect.right-rect.left)/2, rect.bottom-rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); secondLineCharIndex = (int)SendMessageA(hwnd, EM_LINEINDEX, (WPARAM) 1, (LPARAM) 0); if (secondLineCharIndex != -1) { break; } } if (secondLineCharIndex == -1) { // if we failed after twenty tries just reset the control to its original size // and get the heck outa here!! SetWindowPos(hwnd, NULL, 0, 0, originalRect.right-originalRect.left, originalRect.bottom-originalRect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); return 0; } SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInSecondRow, (LPARAM) secondLineCharIndex); SetWindowPos(hwnd, NULL, 0, 0, originalRect.right-originalRect.left, originalRect.bottom-originalRect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); } else { SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInSecondRow, (LPARAM) secondLineCharIndex); } return (pointInSecondRow.y - pointInFirstRow.y); } //+--------------------------------------------------------------------------- // // Function: RebaseControlVertical // // Synopsis: Take the window control, if it has to be resized for text, do // so. Reposition it adjusted for delta pos and return any // height difference for the text resizing // // Arguments: [hwndDlg] -- host dialog // [hwnd] -- control // [hwndNext] -- next control // [fResizeForText] -- resize for text flag // [deltavpos] -- delta vertical position // [oline] -- original number of lines // [minsep] -- minimum separator // [pdeltaheight] -- delta in control height // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- VOID RebaseControlVertical ( HWND hwndDlg, HWND hwnd, HWND hwndNext, BOOL fResizeForText, int deltavpos, int oline, int minsep, int* pdeltaheight ) { int x = 0; int y = 0; int odn = 0; int orig_w; RECT rect; RECT rectNext; RECT rectDlg; TEXTMETRIC tm; // // Set the delta height to zero for now. If we resize the text // a new one will be calculated // *pdeltaheight = 0; // // Get the control window rectangle // GetWindowRect(hwnd, &rect); GetWindowRect(hwndNext, &rectNext); odn = rectNext.top - rect.bottom; orig_w = rect.right - rect.left; MapWindowPoints(NULL, hwndDlg, (LPPOINT) &rect, 2); // // If we have to resize the control due to text, find out what font // is being used and the number of lines of text. From that we'll // calculate what the new height for the control is and set it up // if ( fResizeForText == TRUE ) { HDC hdc; HFONT hfont; HFONT hfontOld; int cline; int h; int w; int dh; int lineHeight; // // Get the metrics of the current control font // hdc = GetDC(hwnd); if (hdc == NULL) { hdc = GetDC(NULL); if (hdc == NULL) { return; } } hfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); if ( hfont == NULL ) { hfont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); } hfontOld = (HFONT)SelectObject(hdc, hfont); GetTextMetrics(hdc, &tm); lineHeight = GetRichEditControlLineHeight(hwnd); if (lineHeight == 0) { lineHeight = tm.tmHeight; } // // Set the minimum separation value // if ( minsep == 0 ) { minsep = lineHeight; } // // Calculate the width and the new height needed // cline = (int)SendMessage(hwnd, EM_GETLINECOUNT, 0, 0); h = cline * lineHeight; w = GetEditControlMaxLineWidth(hwnd, hdc, cline); w += 3; // a little bump to make sure string will fit if (w > orig_w) { w = orig_w; } SelectObject(hdc, hfontOld); ReleaseDC(hwnd, hdc); // // Calculate an addition to height by checking how much space was // left when there were the original # of lines and making sure that // that amount is still left when we do any adjustments // h += ( ( rect.bottom - rect.top ) - ( oline * lineHeight ) ); dh = h - ( rect.bottom - rect.top ); // // If the current height is too small, adjust for it, otherwise // leave the current height and just adjust for the width // if ( dh > 0 ) { SetWindowPos(hwnd, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); } else { SetWindowPos( hwnd, NULL, 0, 0, w, ( rect.bottom - rect.top ), SWP_NOZORDER | SWP_NOMOVE ); } if ( cline < SendMessage(hwnd, EM_GETLINECOUNT, 0, 0) ) { AdjustEditControlWidthToLineCount(hwnd, cline, &tm); } } // // If we have to use deltavpos then calculate the X and the new Y // and set the window position appropriately // if ( deltavpos != 0 ) { GetWindowRect(hwndDlg, &rectDlg); MapWindowPoints(NULL, hwndDlg, (LPPOINT) &rectDlg, 2); x = rect.left - rectDlg.left - GetSystemMetrics(SM_CXEDGE); y = rect.top - rectDlg.top - GetSystemMetrics(SM_CYCAPTION) + deltavpos; SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } // // Get the window rect for the next control and see what the distance // is between the current control and it. With that we must now // adjust our deltaheight, if the distance to the next control is less // than a line height then make it a line height, otherwise just let it // be // if ( hwndNext != NULL ) { int dn; GetWindowRect(hwnd, &rect); GetWindowRect(hwndNext, &rectNext); dn = rectNext.top - rect.bottom; if ( odn > minsep ) { if ( dn < minsep ) { *pdeltaheight = minsep - dn; } } else { if ( dn < odn ) { *pdeltaheight = odn - dn; } } } } //+--------------------------------------------------------------------------- // // Function: ACUISetArrowCursorSubclass // // Synopsis: subclass routine for setting the arrow cursor. This can be // set on multiline edit routines used in the dialog UIs for // the default Authenticode provider // // Arguments: [hwnd] -- window handle // [uMsg] -- message id // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if message handled, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- LRESULT CALLBACK ACUISetArrowCursorSubclass ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HDC hdc; WNDPROC wndproc; PAINTSTRUCT ps; wndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch ( uMsg ) { case WM_SETCURSOR: SetCursor(LoadCursor(NULL, IDC_ARROW)); return( TRUE ); break; case WM_CHAR: if ( wParam != (WPARAM)' ' ) { break; } case WM_LBUTTONDOWN: if ( hwnd == GetDlgItem(GetParent(hwnd), IDC_PERSONALTRUST) ) { int check; HWND hwndCheck; // // Toggle the check state of the PTCHECK control if the // personal trust statement is clicked on // hwndCheck = GetDlgItem(GetParent(hwnd), IDC_PTCHECK); check = (int)SendMessage(hwndCheck, BM_GETCHECK, 0, 0); if ( check == BST_CHECKED ) { check = BST_UNCHECKED; } else if ( check == BST_UNCHECKED ) { check = BST_CHECKED; } else { check = BST_UNCHECKED; } SendMessage(hwndCheck, BM_SETCHECK, (WPARAM)check, 0); SetFocus(hwnd); return( TRUE ); } return(TRUE); case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: return( TRUE ); break; case EM_SETSEL: return( TRUE ); break; case WM_PAINT: CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam); if ( hwnd == GetFocus() ) { DrawFocusRectangle(hwnd, NULL); } return( TRUE ); break; case WM_SETFOCUS: if ( hwnd != GetDlgItem(GetParent(hwnd), IDC_PERSONALTRUST) ) { SetFocus(GetNextDlgTabItem(GetParent(hwnd), hwnd, FALSE)); return( TRUE ); } else { InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); SetCursor(LoadCursor(NULL, IDC_ARROW)); return( TRUE ); } break; case WM_KILLFOCUS: InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return( TRUE ); } return(CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam)); } //+--------------------------------------------------------------------------- // // Function: SubclassEditControlForArrowCursor // // Synopsis: subclasses edit control so that the arrow cursor can replace // the edit bar // // Arguments: [hwndEdit] -- edit control // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- VOID SubclassEditControlForArrowCursor (HWND hwndEdit) { LONG_PTR PrevWndProc; PrevWndProc = GetWindowLongPtr(hwndEdit, GWLP_WNDPROC); SetWindowLongPtr(hwndEdit, GWLP_USERDATA, (LONG_PTR)PrevWndProc); SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)ACUISetArrowCursorSubclass); } //+--------------------------------------------------------------------------- // // Function: SubclassEditControlForLink // // Synopsis: subclasses the edit control for a link using the link subclass // data // // Arguments: [hwndDlg] -- dialog // [hwndEdit] -- edit control // [wndproc] -- window proc to subclass with // [plsd] -- data to pass on to window proc // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- VOID SubclassEditControlForLink ( HWND hwndDlg, HWND hwndEdit, WNDPROC wndproc, PTUI_LINK_SUBCLASS_DATA plsd ) { HWND hwndTip; plsd->hwndTip = CreateWindowA( TOOLTIPS_CLASSA, (LPSTR)NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, (HMENU)NULL, g_hModule, NULL ); if ( plsd->hwndTip != NULL ) { TOOLINFOA tia; DWORD cb; LPSTR psz; memset(&tia, 0, sizeof(TOOLINFOA)); tia.cbSize = sizeof(TOOLINFOA); tia.hwnd = hwndEdit; tia.uId = 1; tia.hinst = g_hModule; //GetClientRect(hwndEdit, &tia.rect); SendMessage(hwndEdit, EM_GETRECT, 0, (LPARAM)&tia.rect); // // if plsd->uToolTipText is a string then convert it // if (plsd->uToolTipText &0xffff0000) { cb = WideCharToMultiByte( 0, 0, (LPWSTR)plsd->uToolTipText, -1, NULL, 0, NULL, NULL); if (NULL == (psz = new char[cb])) { return; } WideCharToMultiByte( 0, 0, (LPWSTR)plsd->uToolTipText, -1, psz, cb, NULL, NULL); tia.lpszText = psz; } else { tia.lpszText = (LPSTR)plsd->uToolTipText; } SendMessage(plsd->hwndTip, TTM_ADDTOOL, 0, (LPARAM)&tia); if (plsd->uToolTipText &0xffff0000) { delete[] psz; } } plsd->fMouseCaptured = FALSE; plsd->wpPrev = (WNDPROC)GetWindowLongPtr(hwndEdit, GWLP_WNDPROC); SetWindowLongPtr(hwndEdit, GWLP_USERDATA, (LONG_PTR)plsd); SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)wndproc); } //+--------------------------------------------------------------------------- // // Function: ACUILinkSubclass // // Synopsis: subclass for the publisher link // // Arguments: [hwnd] -- window handle // [uMsg] -- message id // [wParam] -- parameter 1 // [lParam] -- parameter 2 // // Returns: TRUE if message handled, FALSE otherwise // // Notes: // //---------------------------------------------------------------------------- LRESULT CALLBACK ACUILinkSubclass ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { PTUI_LINK_SUBCLASS_DATA plsd; CInvokeInfoHelper* piih; plsd = (PTUI_LINK_SUBCLASS_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA); piih = (CInvokeInfoHelper *)plsd->pvData; switch ( uMsg ) { case WM_SETCURSOR: if (!plsd->fMouseCaptured) { SetCapture(hwnd); plsd->fMouseCaptured = TRUE; } SetCursor(LoadCursor((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDC_TUIHAND))); return( TRUE ); break; case WM_CHAR: if ( wParam != (WPARAM)' ') { break; } // fall through to wm_lbuttondown.... case WM_LBUTTONDOWN: SetFocus(hwnd); switch(plsd->uId) { case IDC_PUBLISHER: piih->CallCertViewProperties(plsd->hwndParent); break; case IDC_INSTALLANDRUN: piih->CallWebLink(plsd->hwndParent, (WCHAR *)piih->ControlWebPage()); break; case IDC_AUTHENTICITY: piih->CallWebLink(plsd->hwndParent, (WCHAR *)piih->CAWebPage()); break; case IDC_ADVANCED: piih->CallAdvancedLink(plsd->hwndParent); break; } return( TRUE ); case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: return( TRUE ); case EM_SETSEL: return( TRUE ); case WM_PAINT: CallWindowProc(plsd->wpPrev, hwnd, uMsg, wParam, lParam); if ( hwnd == GetFocus() ) { DrawFocusRectangle(hwnd, NULL); } return( TRUE ); case WM_SETFOCUS: if ( hwnd == GetFocus() ) { InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); SetCursor(LoadCursor((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDC_TUIHAND))); return( TRUE ); } break; case WM_KILLFOCUS: InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); SetCursor(LoadCursor(NULL, IDC_ARROW)); return( TRUE ); case WM_MOUSEMOVE: MSG msg; DWORD dwCharLine; CHARFORMAT sCharFmt; RECT rect; int xPos, yPos; memset(&msg, 0, sizeof(MSG)); msg.hwnd = hwnd; msg.message = uMsg; msg.wParam = wParam; msg.lParam = lParam; SendMessage(plsd->hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg); // check to see if the mouse is in this windows rect, if not, then reset // the cursor to an arrow and release the mouse GetClientRect(hwnd, &rect); xPos = LOWORD(lParam); yPos = HIWORD(lParam); if ((xPos < 0) || (yPos < 0) || (xPos > (rect.right - rect.left)) || (yPos > (rect.bottom - rect.top))) { SetCursor(LoadCursor(NULL, IDC_ARROW)); ReleaseCapture(); plsd->fMouseCaptured = FALSE; } /* warning! EM_CHARFROMPOS gets an access violation! dwCharLine = SendMessage(hwnd, EM_CHARFROMPOS, 0, lParam); if (dwCharLine == (-1)) { return(TRUE); } SendMessage(hwnd, EM_SETSEL, (WPARAM)LOWORD(dwCharLine), (LPARAM)(LOWORD(dwCharLine) + 1)); memset(&sCharFmt, 0x00, sizeof(CHARFORMAT)); sCharFmt.cbSize = sizeof(CHARFORMAT); SendMessage(hwnd, EM_GETCHARFORMAT, TRUE, (LPARAM)&sCharFmt); if (sCharFmt.dwEffects & CFE_UNDERLINE) { SetCursor(LoadCursor((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDC_TUIHAND))); } else { SetCursor(LoadCursor(NULL, IDC_ARROW)); } */ return( TRUE ); } return(CallWindowProc(plsd->wpPrev, hwnd, uMsg, wParam, lParam)); } //+--------------------------------------------------------------------------- // // Function: FormatACUIResourceString // // Synopsis: formats a string given a resource id and message arguments // // Arguments: [StringResourceId] -- resource id // [aMessageArgument] -- message arguments // [ppszFormatted] -- formatted string goes here // // Returns: S_OK if successful, any valid HRESULT otherwise // //---------------------------------------------------------------------------- HRESULT FormatACUIResourceString ( UINT StringResourceId, DWORD_PTR* aMessageArgument, LPWSTR* ppszFormatted ) { HRESULT hr = S_OK; WCHAR sz[MAX_LOADSTRING_BUFFER]; LPVOID pvMsg; pvMsg = NULL; sz[0] = NULL; // // Load the string resource and format the message with that string and // the message arguments // if (StringResourceId != 0) { if ( LoadStringU(g_hModule, StringResourceId, sz, MAX_LOADSTRING_BUFFER) == 0 ) { return(HRESULT_FROM_WIN32(GetLastError())); } if ( FormatMessageU(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, sz, 0, 0, (LPWSTR)&pvMsg, 0, (va_list *)aMessageArgument) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); } } else { if ( FormatMessageU(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (char *)aMessageArgument[0], 0, 0, (LPWSTR)&pvMsg, 0, (va_list *)&aMessageArgument[1]) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); } } if (pvMsg) { *ppszFormatted = new WCHAR[wcslen((WCHAR *)pvMsg) + 1]; if (*ppszFormatted) { wcscpy(*ppszFormatted, (WCHAR *)pvMsg); } LocalFree(pvMsg); } return( hr ); } //+--------------------------------------------------------------------------- // // Function: RenderACUIStringToEditControl // // Synopsis: renders a string to the control given and if requested, gives // it a link look and feel, subclassed to the wndproc and plsd // given // // Arguments: [hwndDlg] -- dialog window handle // [ControlId] -- control id // [NextControlId] -- next control id // [psz] -- string // [deltavpos] -- delta vertical position // [fLink] -- a link? // [wndproc] -- optional wndproc, valid if fLink == TRUE // [plsd] -- optional plsd, valid if fLink === TRUE // [minsep] -- minimum separation // [pszThisTextOnlyInLink -- only change this text. // // Returns: delta in height of the control // // Notes: // //---------------------------------------------------------------------------- int RenderACUIStringToEditControl ( HWND hwndDlg, UINT ControlId, UINT NextControlId, LPCWSTR psz, int deltavpos, BOOL fLink, WNDPROC wndproc, PTUI_LINK_SUBCLASS_DATA plsd, int minsep, LPCWSTR pszThisTextOnlyInLink ) { HWND hControl; int deltaheight = 0; int oline = 0; int hkcharpos; // // Get the control and set the text on it, make sure the background // is right if it is a rich edit control // hControl = GetDlgItem(hwndDlg, ControlId); oline = (int)SendMessage(hControl, EM_GETLINECOUNT, 0, 0); CryptUISetRicheditTextW(hwndDlg, ControlId, L""); CryptUISetRicheditTextW(hwndDlg, ControlId, psz); //SetWindowTextU(hControl, psz); // // If there is a '&' in the string, then get rid of it // hkcharpos = GetHotKeyCharPosition(hControl); if (IDC_PERSONALTRUST == ControlId && hkcharpos != 0) { CHARRANGE cr; CHARFORMAT cf; cr.cpMin = hkcharpos - 1; cr.cpMax = hkcharpos; SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM) &cr); SendMessage(hControl, EM_REPLACESEL, FALSE, (LPARAM) ""); cr.cpMin = -1; cr.cpMax = 0; SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM) &cr); } SendMessage( hControl, EM_SETBKGNDCOLOR, 0, (LPARAM)GetSysColor(COLOR_3DFACE) ); // // If we have a link then update for the link look // if ( fLink == TRUE ) { CHARFORMAT cf; memset(&cf, 0, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_COLOR | CFM_UNDERLINE; cf.crTextColor = RGB(0, 0, 255); cf.dwEffects |= CFM_UNDERLINE; if (pszThisTextOnlyInLink) { FINDTEXTEX ft; DWORD pos; char *pszOnlyThis; DWORD cb; cb = WideCharToMultiByte( 0, 0, pszThisTextOnlyInLink, -1, NULL, 0, NULL, NULL); if (NULL == (pszOnlyThis = new char[cb])) { return 0; } WideCharToMultiByte( 0, 0, pszThisTextOnlyInLink, -1, pszOnlyThis, cb, NULL, NULL); memset(&ft, 0x00, sizeof(FINDTEXTEX)); ft.chrg.cpMin = 0; ft.chrg.cpMax = (-1); ft.lpstrText = (char *)pszOnlyThis; if ((pos = (DWORD)SendMessage(hControl, EM_FINDTEXTEX, 0, (LPARAM)&ft)) != (-1)) { SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM)&ft.chrgText); SendMessage(hControl, EM_SETCHARFORMAT, SCF_WORD | SCF_SELECTION, (LPARAM)&cf); ft.chrgText.cpMin = 0; ft.chrgText.cpMax = 0; SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM)&ft.chrgText); } delete[] pszOnlyThis; } else { SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); } } // // Rebase the control // RebaseControlVertical( hwndDlg, hControl, GetDlgItem(hwndDlg, NextControlId), TRUE, deltavpos, oline, minsep, &deltaheight ); // // If we have the link look then we must subclass for the appropriate // link feel, otherwise we subclass for a static text control feel // if ( fLink == TRUE ) { SubclassEditControlForLink(hwndDlg, hControl, wndproc, plsd); } else { SubclassEditControlForArrowCursor(hControl); } return( deltaheight ); } //+--------------------------------------------------------------------------- // // Function: CalculateControlVerticalDistance // // Synopsis: calculates the vertical distance from the bottom of Control1 // to the top of Control2 // // Arguments: [hwnd] -- parent dialog // [Control1] -- first control // [Control2] -- second control // // Returns: the distance in pixels // // Notes: assumes control1 is above control2 // //---------------------------------------------------------------------------- int CalculateControlVerticalDistance (HWND hwnd, UINT Control1, UINT Control2) { RECT rect1; RECT rect2; GetWindowRect(GetDlgItem(hwnd, Control1), &rect1); GetWindowRect(GetDlgItem(hwnd, Control2), &rect2); return( rect2.top - rect1.bottom ); } //+--------------------------------------------------------------------------- // // Function: CalculateControlVerticalDistanceFromDlgBottom // // Synopsis: calculates the distance from the bottom of the control to // the bottom of the dialog // // Arguments: [hwnd] -- dialog // [Control] -- control // // Returns: the distance in pixels // // Notes: // //---------------------------------------------------------------------------- int CalculateControlVerticalDistanceFromDlgBottom (HWND hwnd, UINT Control) { RECT rect; RECT rectControl; GetClientRect(hwnd, &rect); GetWindowRect(GetDlgItem(hwnd, Control), &rectControl); return( rect.bottom - rectControl.bottom ); } //+--------------------------------------------------------------------------- // // Function: ACUICenterWindow // // Synopsis: centers the given window // // Arguments: [hWndToCenter] -- window handle // // Returns: (none) // // Notes: This code was stolen from ATL and hacked upon madly :-) // //---------------------------------------------------------------------------- VOID ACUICenterWindow (HWND hWndToCenter) { HWND hWndCenter; // determine owner window to center against DWORD dwStyle = (DWORD)GetWindowLong(hWndToCenter, GWL_STYLE); if(dwStyle & WS_CHILD) hWndCenter = ::GetParent(hWndToCenter); else hWndCenter = ::GetWindow(hWndToCenter, GW_OWNER); if (hWndCenter == NULL) { return; } // get coordinates of the window relative to its parent RECT rcDlg; ::GetWindowRect(hWndToCenter, &rcDlg); RECT rcArea; RECT rcCenter; HWND hWndParent; if(!(dwStyle & WS_CHILD)) { // don't center against invisible or minimized windows if(hWndCenter != NULL) { DWORD dwStyle2 = ::GetWindowLong(hWndCenter, GWL_STYLE); if(!(dwStyle2 & WS_VISIBLE) || (dwStyle2 & WS_MINIMIZE)) hWndCenter = NULL; } // center within screen coordinates ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL); if(hWndCenter == NULL) rcCenter = rcArea; else ::GetWindowRect(hWndCenter, &rcCenter); } else { // center within parent client coordinates hWndParent = ::GetParent(hWndToCenter); ::GetClientRect(hWndParent, &rcArea); ::GetClientRect(hWndCenter, &rcCenter); ::MapWindowPoints(hWndCenter, hWndParent, (POINT*)&rcCenter, 2); } int DlgWidth = rcDlg.right - rcDlg.left; int DlgHeight = rcDlg.bottom - rcDlg.top; // find dialog's upper left based on rcCenter int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2; int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2; // if the dialog is outside the screen, move it inside if(xLeft < rcArea.left) xLeft = rcArea.left; else if(xLeft + DlgWidth > rcArea.right) xLeft = rcArea.right - DlgWidth; if(yTop < rcArea.top) yTop = rcArea.top; else if(yTop + DlgHeight > rcArea.bottom) yTop = rcArea.bottom - DlgHeight; // map screen coordinates to child coordinates ::SetWindowPos( hWndToCenter, HWND_TOPMOST, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOACTIVATE ); } //+--------------------------------------------------------------------------- // // Function: ACUIViewHTMLHelpTopic // // Synopsis: html help viewer // // Arguments: [hwnd] -- caller window // [pszTopic] -- topic // // Returns: (none) // // Notes: // //---------------------------------------------------------------------------- VOID ACUIViewHTMLHelpTopic (HWND hwnd, LPSTR pszTopic) { // HtmlHelpA( // hwnd, // "%SYSTEMROOT%\\help\\iexplore.chm>large_context", // HH_DISPLAY_TOPIC, // (DWORD)pszTopic // ); } //+--------------------------------------------------------------------------- // // Function: GetEditControlMaxLineWidth // // Synopsis: gets the maximum line width of the edit control // //---------------------------------------------------------------------------- int GetEditControlMaxLineWidth (HWND hwndEdit, HDC hdc, int cline) { int index; int line; int charwidth; int maxwidth = 0; CHAR szMaxBuffer[1024]; WCHAR wsz[1024]; TEXTRANGEA tr; SIZE size; tr.lpstrText = szMaxBuffer; for ( line = 0; line < cline; line++ ) { index = (int)SendMessage(hwndEdit, EM_LINEINDEX, (WPARAM)line, 0); charwidth = (int)SendMessage(hwndEdit, EM_LINELENGTH, (WPARAM)index, 0); tr.chrg.cpMin = index; tr.chrg.cpMax = index + charwidth; SendMessage(hwndEdit, EM_GETTEXTRANGE, 0, (LPARAM)&tr); wsz[0] = NULL; MultiByteToWideChar(0, 0, (const char *)tr.lpstrText, -1, &wsz[0], 1024); if (wsz[0]) { GetTextExtentPoint32W(hdc, &wsz[0], charwidth, &size); if ( size.cx > maxwidth ) { maxwidth = size.cx; } } } return( maxwidth ); } //+--------------------------------------------------------------------------- // // Function: DrawFocusRectangle // // Synopsis: draws the focus rectangle for the edit control // //---------------------------------------------------------------------------- void DrawFocusRectangle (HWND hwnd, HDC hdc) { RECT rect; PAINTSTRUCT ps; BOOL fReleaseDC = FALSE; if ( hdc == NULL ) { hdc = GetDC(hwnd); if ( hdc == NULL ) { return; } fReleaseDC = TRUE; } GetClientRect(hwnd, &rect); DrawFocusRect(hdc, &rect); if ( fReleaseDC == TRUE ) { ReleaseDC(hwnd, hdc); } } //+--------------------------------------------------------------------------- // // Function: GetHotKeyCharPositionFromString // // Synopsis: gets the character position for the hotkey, zero means // no-hotkey // //---------------------------------------------------------------------------- int GetHotKeyCharPositionFromString (LPWSTR pwszText) { LPWSTR psz = pwszText; while ( ( psz = wcschr(psz, L'&') ) != NULL ) { psz++; if ( *psz != L'&' ) { break; } } if ( psz == NULL ) { return( 0 ); } return (int)(( psz - pwszText ) ); } //+--------------------------------------------------------------------------- // // Function: GetHotKeyCharPosition // // Synopsis: gets the character position for the hotkey, zero means // no-hotkey // //---------------------------------------------------------------------------- int GetHotKeyCharPosition (HWND hwnd) { int nPos = 0; WCHAR szText[MAX_LOADSTRING_BUFFER] = L""; if (GetWindowTextU(hwnd, szText, MAX_LOADSTRING_BUFFER)) { nPos = GetHotKeyCharPositionFromString(szText); } return nPos; } //+--------------------------------------------------------------------------- // // Function: FormatHotKeyOnEditControl // // Synopsis: formats the hot key on an edit control by making it underlined // //---------------------------------------------------------------------------- VOID FormatHotKeyOnEditControl (HWND hwnd, int hkcharpos) { CHARRANGE cr; CHARFORMAT cf; assert( hkcharpos != 0 ); cr.cpMin = hkcharpos - 1; cr.cpMax = hkcharpos; SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr); memset(&cf, 0, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_UNDERLINE; cf.dwEffects |= CFM_UNDERLINE; SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); cr.cpMin = -1; cr.cpMax = 0; SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr); } //+--------------------------------------------------------------------------- // // Function: AdjustEditControlWidthToLineCount // // Synopsis: adjust edit control width to the given line count // //---------------------------------------------------------------------------- void AdjustEditControlWidthToLineCount(HWND hwnd, int cline, TEXTMETRIC* ptm) { RECT rect; int w; int h; GetWindowRect(hwnd, &rect); h = rect.bottom - rect.top; w = rect.right - rect.left; while ( cline < SendMessage(hwnd, EM_GETLINECOUNT, 0, 0) ) { w += ptm->tmMaxCharWidth; SetWindowPos(hwnd, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); printf( "Line count adjusted to = %d\n", (DWORD) SendMessage(hwnd, EM_GETLINECOUNT, 0, 0) ); } }