Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1553 lines
44 KiB

// Connect.cpp : Implementation of CConnect
#include "precomp.h"
#include "AddIn.h"
#include "Connect.h"
#include "addin_i.c"
#include "testsettingsctrl.h"
#include "avrfutil.h"
#include <assert.h>
using namespace ShimLib;
// Globals needed by AppVerifier
wstring g_strAppName;
BOOL gp_bConsoleMode;
BOOL gp_bWin2KMode;
BOOL g_bBreakOnLog;
BOOL g_bFullPageHeap;
BOOL g_bPropagateTests;
extern BOOL CheckWindowsVersion(void);
//
// Holds the name of the active EXE.
//
wstring g_wstrExeName;
//
// Indicates if it's okay to run.
//
BOOL g_bCorrectOSVersion = FALSE;
#define AV_OPTION_BREAK_ON_LOG L"BreakOnLog"
#define AV_OPTION_FULL_PAGEHEAP L"FullPageHeap"
#define AV_OPTION_AV_DEBUGGER L"UseAVDebugger"
#define AV_OPTION_DEBUGGER L"Debugger"
#define AV_OPTION_PROPAGATE L"PropagateTests"
void
pReadOptions(
void
)
{
for (CAVAppInfo *pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); ++pApp) {
LPCWSTR szExe = pApp->wstrExeName.c_str();
static const DWORD MAX_DEBUGGER_LEN = 1024;
WCHAR szDebugger[MAX_DEBUGGER_LEN];
g_bBreakOnLog = pApp->bBreakOnLog = GetShimSettingDWORD(L"General", szExe, AV_OPTION_BREAK_ON_LOG, FALSE);
g_bFullPageHeap = pApp->bFullPageHeap = GetShimSettingDWORD(L"General", szExe, AV_OPTION_FULL_PAGEHEAP, FALSE);
pApp->bUseAVDebugger = TRUE;
g_bPropagateTests = pApp->bPropagateTests = GetShimSettingDWORD(L"General", szExe, AV_OPTION_PROPAGATE, FALSE);
pApp->wstrDebugger = L"";
}
}
HPALETTE CreateDIBPalette(
LPBITMAPINFO lpbmi,
LPINT lpiNumColors
)
{
LPBITMAPINFOHEADER lpbi;
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal = NULL;
int i;
lpbi = (LPBITMAPINFOHEADER)lpbmi;
if (lpbi->biBitCount <= 8)
*lpiNumColors = (1 << lpbi->biBitCount);
else
*lpiNumColors = 0; // No palette needed for 24 BPP DIB
if (lpbi->biClrUsed > 0)
*lpiNumColors = lpbi->biClrUsed; // Use biClrUsed
if (*lpiNumColors)
{
hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) + sizeof (PALETTEENTRY) * (*lpiNumColors));
lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
lpPal->palVersion = 0x300;
lpPal->palNumEntries = (WORD)*lpiNumColors;
for (i = 0; i < *lpiNumColors; i++)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
hPal = CreatePalette (lpPal);
GlobalUnlock (hLogPal);
GlobalFree (hLogPal);
}
return hPal;
}
HBITMAP LoadResourceBitmap(
HINSTANCE hInstance,
TCHAR* pszString,
HPALETTE FAR* lphPalette
)
{
HGLOBAL hGlobal;
HBITMAP hBitmapFinal = NULL;
LPBITMAPINFOHEADER lpbi;
HDC hdc;
int iNumColors;
HRSRC hRsrc = FindResource(hInstance, pszString, RT_BITMAP);
if (hRsrc)
{
hGlobal = LoadResource(hInstance, hRsrc);
lpbi = (LPBITMAPINFOHEADER)LockResource(hGlobal);
hdc = GetDC(NULL);
*lphPalette = CreateDIBPalette ((LPBITMAPINFO)lpbi, &iNumColors);
if (*lphPalette)
{
SelectPalette(hdc,*lphPalette,FALSE);
RealizePalette(hdc);
}
hBitmapFinal = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)lpbi, (LONG)CBM_INIT, (LPSTR)lpbi + lpbi->biSize + iNumColors * sizeof(RGBQUAD), (LPBITMAPINFO)lpbi, DIB_RGB_COLORS );
ReleaseDC(NULL,hdc);
UnlockResource(hGlobal);
FreeResource(hGlobal);
}
return (hBitmapFinal);
}
CComPtr<IPictureDisp>GetPicture(PTSTR szResource)
{
CComPtr<IPictureDisp> picture;
PICTDESC pictDesc;
pictDesc.cbSizeofstruct=sizeof(PICTDESC);
pictDesc.picType=PICTYPE_BITMAP;
pictDesc.bmp.hbitmap = LoadResourceBitmap(_Module.GetResourceInstance(), szResource, &pictDesc.bmp.hpal);
OleCreatePictureIndirect(&pictDesc, IID_IPictureDisp, TRUE, (void**)(static_cast<IPictureDisp**>(&picture)));
return picture;
}
// Called when the add-in is loaded into the environment.
STDMETHODIMP
CConnect::OnConnection(
IDispatch *pApplication,
AddInDesignerObjects::ext_ConnectMode ConnectMode,
IDispatch *pAddInInst,
SAFEARRAY ** custom
)
{
HRESULT hr;
INITCOMMONCONTROLSEX icc;
// Initialize AppVerifier settings
g_strAppName = L"";
gp_bConsoleMode = FALSE;
gp_bWin2KMode = FALSE;
g_bBreakOnLog = FALSE;
g_bFullPageHeap = FALSE;
g_bPropagateTests = FALSE;
try {
if (CheckWindowsVersion()) {
g_bCorrectOSVersion = TRUE;
//
// Add our tests to the listview.
//
InitTestInfo();
//
// Load the common control library and set up the link
// window class.
//
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES;
InitCommonControlsEx(&icc);
LinkWindow_RegisterClass();
//
// Get the development environment instance and our add-in instance.
//
hr = pApplication->QueryInterface(__uuidof(EnvDTE::_DTE),
(LPVOID*)&m_pDTE);
if (FAILED(hr)) {
return hr;
}
hr = pAddInInst->QueryInterface(__uuidof(EnvDTE::AddIn),
(LPVOID*)&m_pAddInInstance);
if (FAILED(hr)) {
return hr;
}
//
// OnStartupComplete contains actual connection code.
//
if (ConnectMode != AddInDesignerObjects::ext_cm_Startup) {
return OnStartupComplete(custom);
}
}
} // try
catch(HRESULT err) {
hr = err;
}
return hr;
}
//
// Called when the add-in is unloaded from the environment.
//
STDMETHODIMP
CConnect::OnDisconnection(
AddInDesignerObjects::ext_DisconnectMode /*RemoveMode*/,
SAFEARRAY ** /*custom*/ )
{
m_pDTE.Release();
m_pAddInInstance.Release();
m_pEnableControl.Release();
m_pTestsControl.Release();
m_pOptionControl.Release();
m_pLogViewControl.Release();
return S_OK;
}
//
// Called when there is a change to the add-in's loaded into the environment.
//
STDMETHODIMP
CConnect::OnAddInsUpdate(
SAFEARRAY ** /*custom*/ )
{
//
// We don't care about these changes.
//
return S_OK;
}
STDMETHODIMP
CConnect::OnStartupComplete(
SAFEARRAY ** /*custom*/
)
/*++
Return: S_OK on success, or an HRESULT on failure.
Desc: This is called when the environment has finished
loading or by OnConnection() in other instances.
This is where we add our buttons to the Debug
toolbar and such.
--*/
{
HRESULT hr = E_FAIL;
CComPtr<EnvDTE::Commands> pCommands;
CComPtr<Office::_CommandBars> pCommandBars;
CComPtr<Office::CommandBar> pDebugBar;
CComPtr<EnvDTE::Command> pOptionsCmd;
CComPtr<EnvDTE::Command> pTestsCmd;
CComPtr<EnvDTE::Command> pEnableCmd;
CComPtr<EnvDTE::Command> pLogViewCmd;
CComPtr<EnvDTE::Events> pEventSet;
CComPtr<EnvDTE::_DTEEvents> pDTEEvents;
CComPtr<EnvDTE::_SolutionEvents> pSolutionEvents;
WCHAR wszCommandId[64];
WCHAR wszCommandText[64];
WCHAR wszCommandTooltip[64];
m_solutionEventsSink.m_pParent = this;
m_dteEventsSink.m_pParent = this;
//
// Read settings in from SDB and registry.
//
if (g_bCorrectOSVersion) {
GetCurrentAppSettings();
pReadOptions();
}
try {
//
// Get the main menu bars.
//
hr = m_pDTE->get_CommandBars(&pCommandBars);
if (FAILED(hr)) {
throw hr;
}
hr = m_pDTE->get_Commands(&pCommands);
if (FAILED(hr)) {
throw hr;
}
//
// Delete existing named commands and menus.
//
hr = pCommands->Item(CComVariant(L"AppVerifier.Connect.Enable"),
0,
&pEnableCmd);
if (SUCCEEDED(hr)) {
pEnableCmd->Delete();
pEnableCmd.Release();
}
hr = pCommands->Item(CComVariant(L"AppVerifier.Connect.Tests"),
0,
&pTestsCmd);
if (SUCCEEDED(hr)) {
pTestsCmd->Delete();
pTestsCmd.Release();
}
hr = pCommands->Item(CComVariant(L"AppVerifier.Connect.Options"),
0,
&pOptionsCmd);
if (SUCCEEDED(hr)) {
pOptionsCmd->Delete();
pOptionsCmd.Release();
}
hr = pCommands->Item(CComVariant(L"AppVerifier.Connect.ViewLog"),
0,
&pLogViewCmd);
if (SUCCEEDED(hr)) {
pLogViewCmd->Delete();
pLogViewCmd.Release();
}
//
// Get the 'Debug' toolbar.
//
hr = pCommandBars->get_Item(CComVariant(L"Debug"), &pDebugBar);
if (FAILED(hr)) {
throw hr;
}
//
// Create the commands. These will show as buttons on the 'Debug'
// toolbar.
//
LoadString(g_hInstance,
IDS_TB_VERIFICATION_CMD_ID,
wszCommandId,
ARRAYSIZE(wszCommandId));
LoadString(g_hInstance,
IDS_TB_VERIFICATION_CMD_TEXT,
wszCommandText,
ARRAYSIZE(wszCommandText));
LoadString(g_hInstance,
IDS_TB_VERIFICATION_CMD_TOOLTIP,
wszCommandTooltip,
ARRAYSIZE(wszCommandTooltip));
//
// First one is 'Verification Off'.
//
hr = pCommands->AddNamedCommand(
m_pAddInInstance,
CComBSTR(wszCommandId),
CComBSTR(wszCommandText),
CComBSTR(wszCommandTooltip),
VARIANT_TRUE,
0,
NULL,
EnvDTE::vsCommandStatusSupported|EnvDTE::vsCommandStatusEnabled,
&pEnableCmd);
//
// Add the bitmap for this button including the mask associated
// with it.
//
if (SUCCEEDED(hr)) {
hr = pEnableCmd->AddControl(pDebugBar, 1, &m_pEnableControl);
if (FAILED(hr)) {
throw hr;
}
CComQIPtr<Office::_CommandBarButton,
&_uuidof(Office::_CommandBarButton)>pButton(m_pEnableControl);
CComPtr<IPictureDisp>picture = GetPicture(MAKEINTRESOURCE(IDB_ENABLED));
if (pButton && picture) {
pButton->put_Picture(picture);
CComPtr<IPictureDisp>pictureMask = GetPicture(MAKEINTRESOURCE(IDB_ENABLED_MASK));
if (pictureMask) {
pButton->put_Mask(pictureMask);
}
}
}
//
// Second one is 'Tests'.
//
LoadString(g_hInstance,
IDS_TB_TESTS_CMD_ID,
wszCommandId,
ARRAYSIZE(wszCommandId));
LoadString(g_hInstance,
IDS_TB_TESTS_CMD_TEXT,
wszCommandText,
ARRAYSIZE(wszCommandText));
LoadString(g_hInstance,
IDS_TB_TESTS_CMD_TOOLTIP,
wszCommandTooltip,
ARRAYSIZE(wszCommandTooltip));
hr = pCommands->AddNamedCommand(
m_pAddInInstance,
CComBSTR(wszCommandId),
CComBSTR(wszCommandText),
CComBSTR(wszCommandTooltip),
VARIANT_FALSE,
IDB_TESTSETTINGS_BTN,
NULL,
EnvDTE::vsCommandStatusSupported|EnvDTE::vsCommandStatusEnabled,
&pTestsCmd);
if (SUCCEEDED(hr)) {
//
// Add a button to the app verifier menu.
//
hr = pTestsCmd->AddControl(pDebugBar, 2, &m_pTestsControl);
if (FAILED(hr)) {
throw hr;
}
}
//
// Third one is 'Options'.
//
LoadString(g_hInstance,
IDS_TB_OPTIONS_CMD_ID,
wszCommandId,
ARRAYSIZE(wszCommandId));
LoadString(g_hInstance,
IDS_TB_OPTIONS_CMD_TEXT,
wszCommandText,
ARRAYSIZE(wszCommandText));
LoadString(g_hInstance,
IDS_TB_OPTIONS_CMD_TOOLTIP,
wszCommandTooltip,
ARRAYSIZE(wszCommandTooltip));
hr = pCommands->AddNamedCommand(
m_pAddInInstance,
CComBSTR(wszCommandId),
CComBSTR(wszCommandText),
CComBSTR(wszCommandTooltip),
VARIANT_FALSE,
IDB_OPTIONS_BTN,
NULL,
EnvDTE::vsCommandStatusSupported|EnvDTE::vsCommandStatusEnabled,
&pOptionsCmd);
if (SUCCEEDED(hr)) {
//
// Add a button to the app verifier menu.
//
hr = pOptionsCmd->AddControl(pDebugBar, 3, &m_pOptionControl);
if (FAILED(hr)) {
throw hr;
}
}
//
// Fourth one is 'View Log.'
//
LoadString(g_hInstance,
IDS_TB_VIEWLOG_CMD_ID,
wszCommandId,
ARRAYSIZE(wszCommandId));
LoadString(g_hInstance,
IDS_TB_VIEWLOG_CMD_TEXT,
wszCommandText,
ARRAYSIZE(wszCommandText));
LoadString(g_hInstance,
IDS_TB_VIEWLOG_CMD_TOOLTIP,
wszCommandTooltip,
ARRAYSIZE(wszCommandTooltip));
hr = pCommands->AddNamedCommand(
m_pAddInInstance,
CComBSTR(wszCommandId),
CComBSTR(wszCommandText),
CComBSTR(wszCommandTooltip),
VARIANT_FALSE,
IDB_VIEWLOG_BTN,
NULL,
EnvDTE::vsCommandStatusSupported|EnvDTE::vsCommandStatusEnabled,
&pLogViewCmd);
if (SUCCEEDED(hr)) {
//
// Add a button to the app verifier menu.
//
hr = pLogViewCmd->AddControl(pDebugBar, 4, &m_pLogViewControl);
if (FAILED(hr)) {
throw hr;
}
}
//
// Hookup to environment events.
//
hr = m_pDTE->get_Events(&pEventSet);
if (FAILED(hr)) {
throw hr;
}
hr = pEventSet->get_DTEEvents(&pDTEEvents);
if (FAILED(hr)) {
throw hr;
}
hr = m_dteEventsSink.DispEventAdvise((IUnknown*)pDTEEvents.p);
if (FAILED(hr)) {
throw hr;
}
hr = pEventSet->get_SolutionEvents(&pSolutionEvents);
if (FAILED(hr)) {
throw hr;
}
hr = m_solutionEventsSink.DispEventAdvise((IUnknown*)pSolutionEvents.p);
if (FAILED(hr)) {
throw hr;
}
//
// Setup for current solution.
//
m_solutionEventsSink.Opened();
} // try
catch(HRESULT err) {
hr = err;
}
catch(...) {
hr = E_FAIL;
}
return hr;
}
//
// Called when the environment starts to shutdown.
//
STDMETHODIMP
CConnect::OnBeginShutdown(
SAFEARRAY ** /*custom*/ )
{
return S_OK;
}
//
// Called when the status of a command is queried.
//
STDMETHODIMP
CConnect::QueryStatus(
BSTR bstrCmdName,
EnvDTE::vsCommandStatusTextWanted NeededText,
EnvDTE::vsCommandStatus *pStatusOption,
VARIANT * /*pvarCommandText*/)
{
if (NeededText == EnvDTE::vsCommandStatusTextWantedNone) {
if ((_wcsicmp(bstrCmdName, L"AppVerifier.Connect.Tests")==0) ||
(_wcsicmp(bstrCmdName, L"AppVerifier.Connect.Options")==0)) {
if (m_bEnabled) {
*pStatusOption = (EnvDTE::vsCommandStatus)
(EnvDTE::vsCommandStatusEnabled | EnvDTE::vsCommandStatusSupported);
} else {
*pStatusOption = (EnvDTE::vsCommandStatus)
(EnvDTE::vsCommandStatusEnabled | EnvDTE::vsCommandStatusSupported);
}
}
else if (_wcsicmp(bstrCmdName, L"AppVerifier.Connect.ViewLog")==0) {
*pStatusOption = (EnvDTE::vsCommandStatus)
(EnvDTE::vsCommandStatusEnabled | EnvDTE::vsCommandStatusSupported);
}
else if (_wcsicmp(bstrCmdName, L"AppVerifier.Connect.Enable")==0) {
*pStatusOption = (EnvDTE::vsCommandStatus)
(EnvDTE::vsCommandStatusEnabled | EnvDTE::vsCommandStatusSupported);
}
}
return S_OK;
}
BOOL
CALLBACK
CConnect::DlgViewOptions(
HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
switch (message) {
case WM_INITDIALOG:
if (g_bBreakOnLog) {
CheckDlgButton(hDlg, IDC_BREAK_ON_LOG, BST_CHECKED);
}
if (g_bFullPageHeap) {
CheckDlgButton(hDlg, IDC_FULL_PAGEHEAP, BST_CHECKED);
}
if (g_bPropagateTests) {
CheckDlgButton(hDlg, IDC_PROPAGATE_TESTS_TO_CHILDREN, BST_CHECKED);
}
return TRUE;
case WM_NOTIFY:
switch (((NMHDR FAR *)lParam)->code) {
case PSN_APPLY:
g_bBreakOnLog = FALSE;
g_bFullPageHeap = FALSE;
g_bPropagateTests = FALSE;
//
// Determine which options the user has enabled.
//
if (IsDlgButtonChecked(hDlg, IDC_BREAK_ON_LOG) == BST_CHECKED) {
g_bBreakOnLog = TRUE;
}
if (IsDlgButtonChecked(hDlg, IDC_FULL_PAGEHEAP) == BST_CHECKED) {
g_bFullPageHeap = TRUE;
}
if (IsDlgButtonChecked(hDlg, IDC_PROPAGATE_TESTS_TO_CHILDREN) == BST_CHECKED) {
g_bPropagateTests = TRUE;
}
::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
break;
case PSN_QUERYCANCEL:
return FALSE;
}
}
return FALSE;
}
void
CConnect::CreatePropertySheet(
HWND hWndParent
)
{
CTestInfo* pTest;
DWORD dwPages = 1;
DWORD dwPage = 0;
WCHAR wszTitle[MAX_PATH];
LPCWSTR szExe = g_wstrExeName.c_str();
//
// count the number of pages
//
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) {
if (pTest->PropSheetPage.pfnDlgProc) {
dwPages++;
}
}
m_phPages = new HPROPSHEETPAGE[dwPages];
if (!m_phPages) {
return;
}
//
// init the global page
//
m_PageGlobal.dwSize = sizeof(PROPSHEETPAGE);
m_PageGlobal.dwFlags = PSP_USETITLE;
m_PageGlobal.hInstance = g_hInstance;
m_PageGlobal.pszTemplate = MAKEINTRESOURCE(IDD_AV_OPTIONS);
m_PageGlobal.pfnDlgProc = DlgViewOptions;
m_PageGlobal.pszTitle = MAKEINTRESOURCE(IDS_GLOBAL_OPTIONS);
m_PageGlobal.lParam = 0;
m_PageGlobal.pfnCallback = NULL;
m_phPages[0] = CreatePropertySheetPage(&m_PageGlobal);
if (!m_phPages[0]) {
//
// we need the global page minimum
//
return;
}
//
// add the pages for the various tests
//
dwPage = 1;
for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) {
if (pTest->PropSheetPage.pfnDlgProc) {
//
// we use the lParam to identify the exe involved
//
pTest->PropSheetPage.lParam = (LPARAM)szExe;
m_phPages[dwPage] = CreatePropertySheetPage(&(pTest->PropSheetPage));
if (!m_phPages[dwPage]) {
dwPages--;
} else {
dwPage++;
}
}
}
LoadString(g_hInstance,
IDS_OPTIONS_TITLE,
wszTitle,
ARRAYSIZE(wszTitle));
wstring wstrOptions = wszTitle;
wstrOptions += L" - ";
wstrOptions += szExe;
m_psh.dwSize = sizeof(PROPSHEETHEADER);
m_psh.dwFlags = PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP;
m_psh.hwndParent = hWndParent;
m_psh.hInstance = g_hInstance;
m_psh.pszCaption = wstrOptions.c_str();
m_psh.nPages = dwPages;
m_psh.nStartPage = 0;
m_psh.phpage = m_phPages;
m_psh.pfnCallback = NULL;
PropertySheet(&m_psh);
}
//
// Called to execute a command.
//
STDMETHODIMP
CConnect::Exec(
BSTR bstrCmdName,
EnvDTE::vsCommandExecOption ExecuteOption,
VARIANT * /*pvarVariantIn*/,
VARIANT * /*pvarVariantOut*/,
VARIANT_BOOL *pvbHandled
)
{
HRESULT hr;
CComPtr<IDispatch> pObject;
*pvbHandled = VARIANT_FALSE;
if (ExecuteOption == EnvDTE::vsCommandExecOptionDoDefault) {
*pvbHandled = VARIANT_TRUE;
if (_wcsicmp(bstrCmdName, L"AppVerifier.Connect.Tests")==0) {
CreateToolWindow(CLSID_TestSettingsCtrl);
}
else if (_wcsicmp(bstrCmdName, L"AppVerifier.Connect.Options")==0) {
//CreateToolWindow(CLSID_AVOptions);
CreatePropertySheet(NULL);
}
else if (_wcsicmp(bstrCmdName, L"AppVerifier.Connect.ViewLog")==0) {
CreateToolWindow(CLSID_LogViewer);
}
else if (_wcsicmp(bstrCmdName, L"AppVerifier.Connect.Enable")==0) {
m_bEnabled = !m_bEnabled;
CComQIPtr<Office::_CommandBarButton,
&_uuidof(Office::_CommandBarButton)>pButton(m_pEnableControl);
if (m_bEnabled) {
SetEnabledUI();
} else {
SetDisabledUI();
}
GetCurrentAppSettings();
CConnect::SetCurrentAppSettings();
} else {
*pvbHandled = VARIANT_FALSE;
}
}
return S_OK;
}
CComPtr<EnvDTE::Window>CConnect::GetToolWindow(
CLSID clsid
)
{
HRESULT hr;
CComPtr<EnvDTE::Windows>pWindows;
CComPtr<EnvDTE::Window>pToolWindow;
CComBSTR guidPosition;
hr = m_pDTE->get_Windows(&pWindows);
if (FAILED(hr)) {
return NULL;
}
if(clsid == CLSID_LogViewer) {
guidPosition = L"{D39B1B7A-EFF3-42ae-8F2B-8EEE78154187}";
}
else if (clsid == CLSID_TestSettingsCtrl) {
guidPosition = L"{71CD7261-A72E-4a93-AB5F-3EBCFDEAE842}";
}
else if (clsid == CLSID_AVOptions) {
guidPosition = L"{dc878f00-ac86-4813-8ca9-384fa07cefbf}";
} else {
return NULL;
}
hr = pWindows->Item(CComVariant(guidPosition), &pToolWindow);
if (SUCCEEDED(hr)) {
return pToolWindow;
} else {
return NULL;
}
}
void
CConnect::CreateToolWindow(
const CLSID& clsid
)
{
HRESULT hr;
CComBSTR progID;
CComBSTR caption;
CComBSTR guidPosition;
long lMinWidth, lMinHeight;
long lWidth, lHeight;
BOOL bCreated = FALSE;
CComPtr<IDispatch>pObject;
CComPtr<EnvDTE::Windows>pWindows;
CComPtr<EnvDTE::Window>pToolWindow;
//
// Bail if verifier is enabled, except for logviewer.
//
if (m_bEnabled && clsid != CLSID_LogViewer) {
return;
}
//
// Check if window has been already created.
//
pToolWindow = GetToolWindow(clsid);
if (pToolWindow == NULL) {
bCreated = TRUE;
CComPtr<IPictureDisp> picture;
if(clsid == CLSID_LogViewer) {
progID = L"AppVerifier.LogViewer.1";
caption = L"AppVerifier Log";
guidPosition = L"{D39B1B7A-EFF3-42ae-8F2B-8EEE78154187}";
lMinWidth = 600;
lMinHeight = 400;
picture = GetPicture(MAKEINTRESOURCE(IDB_VIEWLOG));
}
else if (clsid == CLSID_TestSettingsCtrl) {
progID = L"AppVerifier.TestSettingsCtrl.1";
caption = L"AppVerifier Test Settings";
guidPosition = L"{71CD7261-A72E-4a93-AB5F-3EBCFDEAE842}";
lMinWidth = 600;
lMinHeight = 400;
picture = GetPicture(MAKEINTRESOURCE(IDB_TESTSETTINGS));
}
else if (clsid == CLSID_AVOptions) {
progID = L"AppVerifier.AVOptions.1";
caption = L"AppVerifier Options";
guidPosition = L"{dc878f00-ac86-4813-8ca9-384fa07cefbf}";
lMinWidth = 300;
lMinHeight = 100;
picture = GetPicture(MAKEINTRESOURCE(IDB_OPTIONS));
} else {
return;
}
hr = m_pDTE->get_Windows(&pWindows);
if (FAILED(hr)) {
return;
}
hr = pWindows->CreateToolWindow(
m_pAddInInstance,
progID,
caption,
guidPosition,
&pObject,
&pToolWindow);
if (FAILED(hr)) {
return;
}
CComQIPtr<IUnknown, &IID_IUnknown>pictUnk(picture);
if (pictUnk) {
pToolWindow->SetTabPicture(CComVariant(pictUnk));
}
}
//
// Make the window visible and activate it.
//
hr = pToolWindow->put_Visible(VARIANT_TRUE);
if (FAILED(hr)) {
return;
}
hr = pToolWindow->Activate();
if (FAILED(hr)) {
return;
}
if (bCreated) {
hr = pToolWindow->get_Width(&lWidth);
if (SUCCEEDED(hr) && (lWidth < lMinWidth)) {
pToolWindow->put_Width(lMinWidth);
}
hr = pToolWindow->get_Height(&lHeight);
if (SUCCEEDED(hr) && (lHeight < lMinHeight)) {
pToolWindow->put_Height(lMinHeight);
}
}
}
void
CConnect::GetNativeVCExecutableNames(
EnvDTE::Project* pProject
)
{
HRESULT hr;
assert(pProject);
// Get the DTE object associated with this project.
CComPtr<IDispatch> vcProjectObject;
hr = pProject->get_Object(&vcProjectObject);
if (SUCCEEDED(hr))
{
// Cast that object to a VCProject object.
CComQIPtr<VCProjectEngineLibrary::VCProject,
&__uuidof(VCProjectEngineLibrary::VCProject)> vcProject(vcProjectObject);
if (vcProject)
{
// Get the configuration set associated with this project.
CComPtr<IDispatch> vcConfigSetObject;
hr = vcProject->get_Configurations(&vcConfigSetObject);
if (SUCCEEDED(hr))
{
// Cast to IVCCollection
CComQIPtr<VCProjectEngineLibrary::IVCCollection,
&__uuidof(VCProjectEngineLibrary::IVCCollection)>
vcConfigurationSet(vcConfigSetObject);
if (vcConfigurationSet)
{
long lVCConfigCount;
hr = vcConfigurationSet->get_Count(&lVCConfigCount);
if (SUCCEEDED(hr))
{
// Loop through all configurations for this project.
for(long j = 1; j <= lVCConfigCount; j++)
{
CComVariant vtConfigSetIdx(j);
CComPtr<IDispatch> vcConfigObject;
hr = vcConfigurationSet->Item(
vtConfigSetIdx, &vcConfigObject);
if (SUCCEEDED(hr))
{
CComQIPtr<
VCProjectEngineLibrary::
VCConfiguration,
&__uuidof(VCProjectEngineLibrary::
VCConfiguration)>
vcConfig(vcConfigObject);
if (vcConfig)
{
// First, verify that this is
// a native executable.
VARIANT_BOOL bIsManaged;
VCProjectEngineLibrary::ConfigurationTypes
configType;
hr = vcConfig->get_ManagedExtensions(&bIsManaged);
if (FAILED(hr)) {
continue;
}
hr = vcConfig->get_ConfigurationType(&configType);
if (FAILED(hr)) {
continue;
}
if (configType !=
VCProjectEngineLibrary::typeApplication &&
bIsManaged != VARIANT_FALSE) {
continue;
}
CComBSTR bstrOutput;
hr = vcConfig->get_PrimaryOutput(&bstrOutput);
if (SUCCEEDED(hr)) {
std::wstring wsFullPath = bstrOutput;
int nPos = wsFullPath.rfind(L'\\');
std::wstring wsShortName = wsFullPath.substr(nPos + 1);
g_wstrExeName = wsShortName;
m_sExeList.insert(wsShortName);
}
}
}
}
}
}
}
}
}
}
BOOL
CConnect::GetAppExeNames(
void
)
{
HRESULT hr;
CComPtr<EnvDTE::_Solution>pSolution;
CComPtr<EnvDTE::SolutionBuild>pSolBuild;
CComPtr<EnvDTE::Projects>projectSet;
CComVariant varStartupProjects;
m_sExeList.clear();
//
// Get the current solution, there is at most one of these.
//
hr = m_pDTE->get_Solution(&pSolution);
if (FAILED(hr)) {
return FALSE;
}
//
// Get the set of all projects in the solution.
//
hr = pSolution->get_Projects(&projectSet);
if (FAILED(hr)) {
return FALSE;
}
hr = pSolution->get_SolutionBuild(&pSolBuild);
if (FAILED(hr)) {
return FALSE;
}
//
// Get the safe array containing all projects that will be
// launched when the solution is run.
// This may return nothing, if the current solution is empty.
//
hr = pSolBuild->get_StartupProjects(&varStartupProjects);
if (FAILED(hr)){
return FALSE;
}
if((varStartupProjects.vt & VT_ARRAY) && (varStartupProjects.vt & VT_VARIANT)) {
UINT cDim = SafeArrayGetDim(varStartupProjects.parray);
if (cDim == 1) {
long lowerBound, upperBound;
SafeArrayGetLBound(varStartupProjects.parray, 1, &lowerBound);
SafeArrayGetUBound(varStartupProjects.parray, 1, &upperBound);
// Loop through the safe array, getting each startup project.
for (long i = lowerBound; i <= upperBound; i++) {
CComVariant vtStartupProjectName;
hr = SafeArrayGetElement(varStartupProjects.parray, &i,
(VARIANT*)&vtStartupProjectName);
if (SUCCEEDED(hr)) {
CComPtr<EnvDTE::Project> project;
hr = projectSet->Item(vtStartupProjectName,&project);
if (SUCCEEDED(hr)) {
GetNativeVCExecutableNames(project);
}
}
}
}
}
return TRUE;
}
BOOL
CConnect::GetAppInfo(
void
)
{
g_psTests->clear();
m_bEnabled = FALSE;
if (GetAppExeNames()) {
if (m_sExeList.empty()) {
return FALSE;
}
std::set<std::wstring>::iterator iter;
iter = m_sExeList.begin();
for(; iter != m_sExeList.end(); iter++) {
//
// Locate this exe in the list of apps.
//
for (int i = 0; i < g_aAppInfo.size(); i++) {
if ((*iter) == g_aAppInfo[i].wstrExeName) {
m_bEnabled = TRUE;
//
// Add this app's tests to the set of tests to run.
//
CTestInfoArray::iterator test;
test = g_aTestInfo.begin();
for (; test != g_aTestInfo.end(); test++) {
if (g_aAppInfo[i].IsTestActive(*test)) {
g_psTests->insert(test);
}
}
break;
}
}
}
return TRUE;
}
SetCurrentAppSettings();
return FALSE;
}
void
CConnect::SetEnabledUI(
void
)
{
WCHAR wszCommandText[64];
WCHAR wszTooltip[64];
LoadString(g_hInstance,
IDS_TB_VERIFY_ENABLED_TEXT,
wszCommandText,
ARRAYSIZE(wszCommandText));
LoadString(g_hInstance,
IDS_TB_VERIFY_ENABLED_TOOLTIP,
wszTooltip,
ARRAYSIZE(wszTooltip));
//
// Change the text on the button.
//
CComQIPtr<Office::_CommandBarButton,
&_uuidof(Office::_CommandBarButton)>pButton(m_pEnableControl);
m_pEnableControl->put_Caption(CComBSTR(wszCommandText));
//
// Set the picture so we show the button as enabled.
//
CComPtr<IPictureDisp>picture = GetPicture(MAKEINTRESOURCE(IDB_DISABLED));
pButton->put_Picture(picture);
CComPtr<IPictureDisp>pictureMask = GetPicture(MAKEINTRESOURCE(IDB_ENABLED_MASK));
pButton->put_Mask(pictureMask);
//
// Change the tooltip so that it corresponds to the change
// in the button text.
//
m_pEnableControl->put_TooltipText(CComBSTR(wszTooltip));
m_pEnableControl->put_Enabled(VARIANT_TRUE);
m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pOptionControl->put_Enabled(VARIANT_FALSE);
//
// Hide all of our settings windows.
//
CComPtr<EnvDTE::Window>pWindow;
pWindow = GetToolWindow(CLSID_TestSettingsCtrl);
if (pWindow) {
pWindow->put_Visible(VARIANT_FALSE);
}
pWindow = GetToolWindow(CLSID_AVOptions);
if (pWindow) {
pWindow->put_Visible(VARIANT_FALSE);
}
}
void
CConnect::DisableVerificationBtn(
void
)
{
CComQIPtr<Office::_CommandBarButton,
&_uuidof(Office::_CommandBarButton)>pButton(m_pEnableControl);
m_pEnableControl->put_Enabled(VARIANT_FALSE);
}
void
CConnect::EnableVerificationBtn(
void
)
{
CComQIPtr<Office::_CommandBarButton,
&_uuidof(Office::_CommandBarButton)>pButton(m_pEnableControl);
m_pEnableControl->put_Enabled(VARIANT_TRUE);
}
void
CConnect::SetDisabledUI(
void
)
{
WCHAR wszCommandText[64];
WCHAR wszTooltip[64];
LoadString(g_hInstance,
IDS_TB_VERIFICATION_CMD_TEXT,
wszCommandText,
ARRAYSIZE(wszCommandText));
LoadString(g_hInstance,
IDS_TB_VERIFICATION_CMD_TOOLTIP,
wszTooltip,
ARRAYSIZE(wszTooltip));
//
// Change the text on the button.
//
CComQIPtr<Office::_CommandBarButton,
&_uuidof(Office::_CommandBarButton)>pButton(m_pEnableControl);
m_pEnableControl->put_Caption(CComBSTR(wszCommandText));
//
// Set the picture so we show the button as disabled.
//
CComPtr<IPictureDisp> picture = GetPicture(MAKEINTRESOURCE(IDB_ENABLED));
pButton->put_Picture(picture);
CComPtr<IPictureDisp> pictureMask = GetPicture(MAKEINTRESOURCE(IDB_ENABLED_MASK));
pButton->put_Mask(pictureMask);
//
// Change the tooltip so that it corresponds to the change
// in the button text.
//
m_pEnableControl->put_TooltipText(CComBSTR(wszTooltip));
m_pEnableControl->put_Enabled(VARIANT_TRUE);
m_pTestsControl->put_Enabled(VARIANT_TRUE);
m_pOptionControl->put_Enabled(VARIANT_TRUE);
}
void
CConnect::SetCurrentAppSettings(
void
)
{
if (m_bEnabled) {
//
// Insert exes into app array.
//
std::set<std::wstring>::iterator exe;
exe = m_sExeList.begin();
for (; exe != m_sExeList.end(); exe++) {
CAVAppInfo* pApp = NULL;
for (int i = 0; i < g_aAppInfo.size(); i++) {
if (g_aAppInfo[i].wstrExeName==*exe) {
pApp = &g_aAppInfo[i];
break;
}
}
if (pApp == NULL) {
CAVAppInfo app;
app.wstrExeName = *exe;
g_aAppInfo.push_back(app);
pApp = &g_aAppInfo.back();
}
std::set<CTestInfo*, CompareTests>::iterator iter;
iter = g_psTests->begin();
for(; iter != g_psTests->end(); iter++) {
pApp->AddTest(**iter);
}
//
// Add flags.
//
pApp->bBreakOnLog = g_bBreakOnLog;
pApp->bFullPageHeap = g_bFullPageHeap;
pApp->bUseAVDebugger = FALSE;
pApp->bPropagateTests = g_bPropagateTests;
pApp->wstrDebugger = L"";
}
} else {
std::set<std::wstring>::iterator exe;
exe = m_sExeList.begin();
for (; exe != m_sExeList.end(); exe++) {
CAVAppInfoArray::iterator app;
app = g_aAppInfo.begin();
for (; app != g_aAppInfo.end(); app++) {
if (app->wstrExeName==*exe) {
//
// Before we erase this app, remove all kernel tests
// and write app data.
//
app->dwRegFlags = 0;
::SetCurrentAppSettings();
g_aAppInfo.erase(app);
break;
}
}
}
}
if (!g_aAppInfo.empty()) {
//
// Persist Options.
//
for (CAVAppInfo *pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); ++pApp) {
LPCWSTR szExe = pApp->wstrExeName.c_str();
SaveShimSettingDWORD(L"General", szExe, AV_OPTION_BREAK_ON_LOG, (DWORD)pApp->bBreakOnLog);
SaveShimSettingDWORD(L"General", szExe, AV_OPTION_FULL_PAGEHEAP, (DWORD)pApp->bFullPageHeap);
SaveShimSettingDWORD(L"General", szExe, AV_OPTION_AV_DEBUGGER, (DWORD)pApp->bUseAVDebugger);
SaveShimSettingDWORD(L"General", szExe, AV_OPTION_PROPAGATE, (DWORD)pApp->bPropagateTests);
SaveShimSettingString(L"General", szExe, AV_OPTION_DEBUGGER, pApp->wstrDebugger.c_str());
}
::SetCurrentAppSettings();
}
}
HRESULT
CConnect::CSolutionEventsSink::AfterClosing(
void
)
{
// We're done, cleanup.
// Disable our controls
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::BeforeClosing(
void
)
{
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::Opened(
void
)
{
CComPtr<EnvDTE::_Solution>pSolution;
CComPtr<EnvDTE::Globals>pGlobals;
if (!g_bCorrectOSVersion) {
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pLogViewControl->put_Enabled(VARIANT_FALSE);
return S_OK;
}
//
// Change in config.
//
if (m_pParent->GetAppInfo()) {
if (m_pParent->m_bEnabled) {
m_pParent->SetEnabledUI();
} else {
m_pParent->SetDisabledUI();
}
} else {
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
}
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::ProjectAdded(
EnvDTE::Project* /*proj*/
)
{
if (!g_bCorrectOSVersion) {
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pLogViewControl->put_Enabled(VARIANT_FALSE);
return S_OK;
}
//
// Change in config.
//
if (m_pParent->GetAppInfo()) {
if (m_pParent->m_bEnabled) {
m_pParent->SetEnabledUI();
} else {
m_pParent->SetDisabledUI();
}
} else {
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
}
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::ProjectRemoved(
EnvDTE::Project* /*proj*/
)
{
if (!g_bCorrectOSVersion) {
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pLogViewControl->put_Enabled(VARIANT_FALSE);
return S_OK;
}
// Change in config.
if (m_pParent->GetAppInfo()) {
if (m_pParent->m_bEnabled) {
m_pParent->SetEnabledUI();
} else {
m_pParent->SetDisabledUI();
}
} else {
m_pParent->m_pOptionControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pTestsControl->put_Enabled(VARIANT_FALSE);
m_pParent->m_pEnableControl->put_Enabled(VARIANT_FALSE);
}
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::ProjectRenamed(
EnvDTE::Project* /*proj*/,
BSTR /*bstrOldName*/
)
{
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::QueryCloseSolution(
VARIANT_BOOL* fCancel
)
{
*fCancel = VARIANT_FALSE;
return S_OK;
}
HRESULT
CConnect::CSolutionEventsSink::Renamed(
BSTR /*bstrOldName*/
)
{
return S_OK;
}