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.
781 lines
21 KiB
781 lines
21 KiB
// Copyright (c) 1997-2002 Microsoft Corporation
|
|
#include "precomp.h"
|
|
|
|
#ifdef EXT_DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#include "DepPage.h"
|
|
|
|
// avoid some warnings.
|
|
#undef HDS_HORZ
|
|
#undef HDS_BUTTONS
|
|
#undef HDS_HIDDEN
|
|
#include "resource.h"
|
|
#include <stdlib.h>
|
|
#include <TCHAR.h>
|
|
#include "..\Common\util.h"
|
|
#include <regstr.h>
|
|
#include "..\common\ConnectThread.h"
|
|
#include "..\MMFUtil\MsgDlg.h"
|
|
#include "winuser.h"
|
|
|
|
|
|
BOOL AfxIsValidAddress(const void* lp,
|
|
UINT nBytes,
|
|
BOOL bReadWrite)
|
|
{
|
|
// simple version using Win-32 APIs for pointer validation.
|
|
return (lp != NULL && !IsBadReadPtr(lp, nBytes) &&
|
|
(!bReadWrite || !IsBadWritePtr((LPVOID)lp, nBytes)));
|
|
}
|
|
|
|
|
|
const wchar_t *CFServiceName = L"FILEMGMT_SNAPIN_SERVICE_NAME";
|
|
const wchar_t *CFServiceDisplayName = L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME";
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
DependencyPage::DependencyPage(WbemConnectThread *pConnectThread,
|
|
IDataObject *pDataObject,
|
|
long lNotifyHandle, bool bDeleteHandle, TCHAR* pTitle)
|
|
: PageHelper(pConnectThread),
|
|
CSnapInPropertyPageImpl<DependencyPage> (pTitle),
|
|
m_lNotifyHandle(lNotifyHandle),
|
|
m_bDeleteHandle(bDeleteHandle),
|
|
m_qLang("WQL"),
|
|
m_NameProp("Name"),
|
|
m_DispNameProp("DisplayName")
|
|
{
|
|
m_servIcon = 0;
|
|
m_sysDriverIcon = 0;
|
|
m_emptyIcon = 0;
|
|
m_groupIcon = 0;
|
|
|
|
ATLTRACE(L"dependency Page CTOR\n");
|
|
|
|
m_queryFormat = new TCHAR[QUERY_SIZE];
|
|
m_queryTemp = new TCHAR[QUERY_SIZE];
|
|
|
|
Extract(pDataObject, L"FILEMGMT_SNAPIN_SERVICE_NAME", m_ServiceName);
|
|
Extract(pDataObject, L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME", m_ServiceDispName);
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
DependencyPage::~DependencyPage()
|
|
{
|
|
ATLTRACE(L"dependency Page DTOR\n");
|
|
delete[] m_queryFormat;
|
|
delete[] m_queryTemp;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void DependencyPage::BuildQuery(TV_ITEM *fmNode,
|
|
QUERY_TYPE queryType,
|
|
bool depends,
|
|
bstr_t &query)
|
|
{
|
|
// clean the working space.
|
|
memset(m_queryFormat, 0, QUERY_SIZE * sizeof(TCHAR));
|
|
memset(m_queryTemp, 0, QUERY_SIZE * sizeof(TCHAR));
|
|
|
|
// here's the WQL syntax format.
|
|
switch(queryType)
|
|
{
|
|
case DepService:
|
|
_tcscpy(m_queryFormat,
|
|
_T("Associators of {Win32_BaseService.Name=\"%s\"} where Role=%s AssocClass=Win32_DependentService"));
|
|
|
|
// build the query for this level.
|
|
_sntprintf(m_queryTemp, QUERY_SIZE- 1, m_queryFormat,
|
|
(LPCTSTR)((ITEMEXTRA *)fmNode->lParam)->realName,
|
|
(depends ? _T("Dependent") : _T("Antecedent")));
|
|
|
|
break;
|
|
case DepGroup:
|
|
_tcscpy(m_queryFormat,
|
|
_T("Associators of {Win32_BaseService.Name=\"%s\"} where ResultClass=Win32_LoadOrderGroup Role=%s AssocClass=Win32_LoadOrderGroupServiceDependencies"));
|
|
|
|
// build the query for this level.
|
|
_sntprintf(m_queryTemp, QUERY_SIZE- 1, m_queryFormat,
|
|
(LPCTSTR)((ITEMEXTRA *)fmNode->lParam)->realName,
|
|
(depends ? _T("Dependent") : _T("Antecedent")));
|
|
break;
|
|
|
|
case GroupMember:
|
|
_tcscpy(m_queryFormat,
|
|
_T("Associators of {Win32_LoadOrderGroup.Name=\"%s\"} where Role=GroupComponent AssocClass=Win32_LoadOrderGroupServiceMembers"));
|
|
// L"Associators of {Win32_LoadOrderGroup.Name=\"%s\"} where ResultClass=Win32_Service Role=GroupComponent AssocClass=Win32_LoadOrderGroupServiceMembers");
|
|
|
|
// build the query for this level.
|
|
_sntprintf(m_queryTemp, QUERY_SIZE- 1, m_queryFormat,
|
|
(LPCTSTR)((ITEMEXTRA *)fmNode->lParam)->realName);
|
|
break;
|
|
} // endswitch
|
|
m_queryTemp[QUERY_SIZE - 1] = 0;
|
|
// cast to bstr_t and return.
|
|
query = m_queryTemp;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void DependencyPage::LoadLeaves(HWND hTree, TV_ITEM *fmNode, bool depends )
|
|
{
|
|
bstr_t query;
|
|
NODE_TYPE nodeType = ((ITEMEXTRA *)fmNode->lParam)->nodeType;
|
|
bool foundIt = false;
|
|
|
|
// HourGlass(true);
|
|
|
|
switch(nodeType)
|
|
{
|
|
case ServiceNode:
|
|
// NOTE: services can depend on groups but not the
|
|
// other way around.
|
|
if(depends)
|
|
{
|
|
//load groups.
|
|
BuildQuery(fmNode, DepGroup, depends, query);
|
|
foundIt = Load(hTree, fmNode, query, GroupNode);
|
|
}
|
|
|
|
// load services.
|
|
BuildQuery(fmNode, DepService, depends, query);
|
|
foundIt |= Load(hTree, fmNode, query, ServiceNode);
|
|
break;
|
|
|
|
case GroupNode:
|
|
// NOTE: 'depends' doesn't matter in this case.
|
|
// load group members.
|
|
BuildQuery(fmNode, GroupMember, depends, query);
|
|
foundIt = Load(hTree, fmNode, query, ServiceNode);
|
|
break;
|
|
|
|
}//endswitch
|
|
|
|
//TODO: Decide opn what to do for this
|
|
// HourGlass(false);
|
|
|
|
if(!foundIt)
|
|
{
|
|
NothingMore(hTree, fmNode);
|
|
if(depends)
|
|
{
|
|
if(fmNode->hItem == TVI_ROOT)
|
|
{
|
|
::EnableWindow(GetDlgItem(IDC_DEPENDS_LBL), FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(fmNode->hItem == TVI_ROOT)
|
|
{
|
|
::EnableWindow(GetDlgItem(IDC_NEEDED_LBL), FALSE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
// READ: In 'hTree', run 'query' and make the children
|
|
// 'childType' nodes under 'fmNode'.
|
|
bool DependencyPage::Load(HWND hTree, TV_ITEM *fmNode, bstr_t query,
|
|
NODE_TYPE childType)
|
|
{
|
|
HRESULT hRes;
|
|
variant_t pRealName, pDispName;
|
|
ULONG uReturned;
|
|
|
|
IWbemClassObject *pOther = NULL;
|
|
IEnumWbemClassObject *pEnumOther = NULL;
|
|
|
|
TV_INSERTSTRUCT leaf;
|
|
leaf.hInsertAfter = TVI_SORT;
|
|
leaf.hParent = fmNode->hItem;
|
|
bool foundOne = false;
|
|
|
|
ATLTRACE(L"query started\n");
|
|
|
|
hRes = m_WbemServices.ExecQuery(m_qLang, query,
|
|
WBEM_FLAG_RETURN_IMMEDIATELY |
|
|
WBEM_FLAG_FORWARD_ONLY,
|
|
&pEnumOther);
|
|
//-------------------
|
|
// query for all related services or groups.
|
|
if(hRes == S_OK)
|
|
{
|
|
ATLTRACE(L"query worked %x\n", hRes);
|
|
//-------------------
|
|
// enumerate through services.
|
|
while(SUCCEEDED(hRes = pEnumOther->Next(500, 1, &pOther, &uReturned)))
|
|
{
|
|
if(hRes == WBEM_S_TIMEDOUT)
|
|
continue;
|
|
|
|
if(uReturned != 1)
|
|
{
|
|
ATLTRACE(L"uReturned failed %x: %s \n", hRes, query);
|
|
break;
|
|
}
|
|
|
|
foundOne = true;
|
|
|
|
//-------------------
|
|
// get the node's name(s).
|
|
switch(childType)
|
|
{
|
|
case ServiceNode:
|
|
hRes = pOther->Get(m_DispNameProp, 0, &pDispName, NULL, NULL);
|
|
hRes = pOther->Get(m_NameProp, 0, &pRealName, NULL, NULL);
|
|
if(SUCCEEDED(hRes))
|
|
{
|
|
hRes = pOther->Get(m_DispNameProp, 0, &pDispName, NULL, NULL);
|
|
}
|
|
break;
|
|
|
|
case GroupNode:
|
|
hRes = pOther->Get(m_NameProp, 0, &pRealName, NULL, NULL);
|
|
if(SUCCEEDED(hRes))
|
|
{
|
|
pDispName = pRealName;
|
|
}
|
|
break;
|
|
|
|
}// endswitch
|
|
|
|
|
|
// got the properties ok?
|
|
if(SUCCEEDED(hRes))
|
|
{
|
|
// add the leaf.
|
|
leaf.item.mask = TVIF_TEXT | TVIF_PARAM |
|
|
TVIF_CHILDREN |TVIF_IMAGE |TVIF_SELECTEDIMAGE;
|
|
leaf.item.hItem = 0;
|
|
leaf.item.state = 0;
|
|
leaf.item.stateMask = 0;
|
|
if(pDispName.vt == VT_BSTR)
|
|
{
|
|
leaf.item.pszText = CloneString((bstr_t)pDispName);
|
|
}
|
|
else
|
|
{
|
|
leaf.item.pszText = CloneString((bstr_t)pRealName);
|
|
}
|
|
leaf.item.cchTextMax = ARRAYSIZE(leaf.item.pszText);
|
|
|
|
TCHAR pszCreationClassName[20];
|
|
_tcscpy(pszCreationClassName,_T("CreationClassName"));
|
|
|
|
variant_t pCreationName;
|
|
_bstr_t strCreationClassName;
|
|
|
|
// set the icon based on 'childType'
|
|
switch(childType)
|
|
{
|
|
case ServiceNode:
|
|
//Here we will have to change the icon depending on whether it is a win32_service or
|
|
//Win32_SystemDriver
|
|
|
|
pOther->Get(pszCreationClassName, 0, &pCreationName, NULL, NULL);
|
|
strCreationClassName = pCreationName.bstrVal;
|
|
|
|
if(_tcsicmp(strCreationClassName,_T("Win32_Service")) == 0)
|
|
{
|
|
leaf.item.iImage = m_servIcon;
|
|
leaf.item.iSelectedImage = m_servIcon;
|
|
}
|
|
else
|
|
{
|
|
leaf.item.iImage = m_sysDriverIcon;
|
|
leaf.item.iSelectedImage = m_sysDriverIcon;
|
|
}
|
|
break;
|
|
|
|
case GroupNode:
|
|
leaf.item.iImage = m_groupIcon;
|
|
leaf.item.iSelectedImage = m_groupIcon;
|
|
break;
|
|
|
|
} // endswitch
|
|
|
|
// turn on the '+' sign.
|
|
leaf.item.cChildren = 1;
|
|
|
|
// set internal data.
|
|
ITEMEXTRA *extra = new ITEMEXTRA;
|
|
if (extra != NULL)
|
|
{
|
|
extra->loaded = false;
|
|
extra->nodeType = childType;
|
|
// true name.
|
|
extra->realName = CloneString((bstr_t)pRealName);
|
|
leaf.item.lParam = (LPARAM) extra;
|
|
|
|
TreeView_InsertItem(hTree, &leaf);
|
|
|
|
// if there is a parent...
|
|
if(fmNode->hItem != TVI_ROOT)
|
|
{
|
|
// indicate that the parent's children have been
|
|
// loaded. This helps optimize for collapsing/re-
|
|
// expanding.
|
|
fmNode->mask = TVIF_PARAM | TVIF_HANDLE;
|
|
((ITEMEXTRA *)fmNode->lParam)->loaded = true;
|
|
TreeView_SetItem(hTree, fmNode);
|
|
}
|
|
}
|
|
|
|
} // endif Get() user name
|
|
|
|
// done with the ClassObject
|
|
if (pOther)
|
|
{
|
|
pOther->Release();
|
|
pOther = NULL;
|
|
}
|
|
|
|
} //endwhile Next()
|
|
|
|
ATLTRACE(L"while %x: %s \n", hRes, (wchar_t *)query);
|
|
|
|
|
|
// release the enumerator.
|
|
if(pEnumOther)
|
|
{
|
|
pEnumOther->Release();
|
|
pEnumOther = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ATLTRACE(L"query failed %x: %s \n", hRes, query);
|
|
|
|
} //endif ExecQuery()
|
|
|
|
// if nothing found...
|
|
return foundOne;
|
|
}
|
|
|
|
//---------------------------------------------------
|
|
void DependencyPage::NothingMore(HWND hTree, TV_ITEM *fmNode)
|
|
{
|
|
TV_INSERTSTRUCT leaf;
|
|
leaf.hInsertAfter = TVI_SORT;
|
|
leaf.hParent = fmNode->hItem;
|
|
|
|
// and its the root...
|
|
if(fmNode->hItem == TVI_ROOT)
|
|
{
|
|
// indicate an 'empty' tree.
|
|
leaf.item.pszText = new TCHAR[100];
|
|
|
|
if( NULL == leaf.item.pszText ) return;
|
|
|
|
leaf.item.cchTextMax = 100;
|
|
::LoadString(HINST_THISDLL, IDS_NO_DEPS,
|
|
leaf.item.pszText,
|
|
leaf.item.cchTextMax);
|
|
|
|
leaf.item.mask = TVIF_TEXT | TVIF_PARAM |
|
|
TVIF_CHILDREN | TVIF_IMAGE |
|
|
TVIF_SELECTEDIMAGE;
|
|
leaf.item.hItem = 0;
|
|
leaf.item.state = 0;
|
|
leaf.item.stateMask = 0;
|
|
leaf.item.iImage = m_emptyIcon;
|
|
leaf.item.iSelectedImage = m_emptyIcon;
|
|
leaf.item.cChildren = 0;
|
|
|
|
ITEMEXTRA *extra = new ITEMEXTRA;
|
|
if(extra == NULL)
|
|
{
|
|
delete[] leaf.item.pszText;
|
|
return;
|
|
}
|
|
extra->loaded = false;
|
|
extra->nodeType = ServiceNode;
|
|
extra->realName = NULL; // to be safe during cleanup.
|
|
leaf.item.lParam = (LPARAM) extra;
|
|
TreeView_InsertItem(hTree, &leaf);
|
|
::EnableWindow(hTree, FALSE);
|
|
delete[] leaf.item.pszText;
|
|
}
|
|
else // not the root.
|
|
{
|
|
// Cant drill down anymore.
|
|
// Turn off the [+] symbol.
|
|
fmNode->mask = TVIF_CHILDREN | TVIF_HANDLE;
|
|
fmNode->cChildren = 0;
|
|
TreeView_SetItem(hTree, fmNode);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
void DependencyPage::TwoLines(UINT uID, LPCTSTR staticString, LPCTSTR inStr, LPTSTR outStr,bool bStaticFirst)
|
|
{
|
|
HWND ctl = ::GetDlgItem(m_hWnd, uID);
|
|
HDC hDC = ::GetDC(ctl);
|
|
|
|
//THIS IS A HACK. I COULD NOT CALCULATE THE ACTUAL WIDTH OF THE CONTROL
|
|
//IN LOGICAL UNITS. SO AS OF NOW, CALCULATED MANUALLY AND HARDCODING IT.
|
|
int ctlWidth = 509;
|
|
TCHAR strTemp[1024];
|
|
TCHAR *strCurr;
|
|
int lenstrTemp;
|
|
SIZE sizeTemp;
|
|
int nFit = 0;
|
|
|
|
//First we will try whether the whole string fits in the space
|
|
if(bStaticFirst == true)
|
|
{
|
|
_sntprintf(strTemp, 1023, _T("%s \"%s\""),staticString,inStr);
|
|
}
|
|
else
|
|
{
|
|
_sntprintf(strTemp, 1023, _T("\"%s\" %s"),inStr,staticString);
|
|
}
|
|
strTemp[1023] = 0;
|
|
strCurr = strTemp;
|
|
|
|
lenstrTemp = lstrlen(strTemp);
|
|
|
|
GetTextExtentExPoint(hDC,strTemp,lenstrTemp,ctlWidth,&nFit,NULL,&sizeTemp);
|
|
|
|
if(lenstrTemp <= nFit)
|
|
{
|
|
//The whole string will fit in a line. So we will all a \r\n in the beginning
|
|
_sntprintf(outStr, 1023, _T("\r\n%s"),strTemp);
|
|
outStr[1023] = 0;
|
|
return;
|
|
}
|
|
|
|
//Now we will try if the whole string atleast fits in 2 lines.
|
|
strCurr += nFit;
|
|
|
|
int nFit1;
|
|
lenstrTemp = lstrlen(strCurr);
|
|
|
|
GetTextExtentExPoint(hDC,strCurr,lenstrTemp,ctlWidth,&nFit1,NULL,&sizeTemp);
|
|
|
|
if(lenstrTemp <= nFit1)
|
|
{
|
|
//The whole string will fit in 2 lines. So we will all a \r\n in the end of the first line
|
|
|
|
TCHAR strTemp1[1024];
|
|
_tcsncpy(strTemp1,strTemp,nFit);
|
|
strTemp1[nFit] = _T('\0');
|
|
_sntprintf(outStr,1023,_T("%s\r\n%s"),strTemp1,strCurr);
|
|
outStr[1023] = 0;
|
|
return;
|
|
}
|
|
|
|
//NOW since it won't fit in 2 lines, we will have to do some calculations and
|
|
//add a "..." to the end of the instr so that it will fit in 2 lines.
|
|
|
|
//If the static string is in the from, then we can easily do it.
|
|
TCHAR strLast[5];
|
|
_tcscpy(strLast,_T("...\""));
|
|
int sizeLast = lstrlen(strLast);
|
|
|
|
SIZE sz1;
|
|
GetTextExtentPoint32(hDC,strLast,sizeLast,&sz1);
|
|
TCHAR strTemp1[1024];
|
|
_tcsncpy(strTemp1,strTemp,nFit);
|
|
strTemp1[nFit] = _T('\0');
|
|
|
|
if(bStaticFirst == true)
|
|
{
|
|
TCHAR strTemp2[10];
|
|
|
|
//Now take characters from the end of the array and match it until the
|
|
//width needed to print is greater than the "..."" string
|
|
bool bFit = false;
|
|
int nStart = nFit1 - 4;
|
|
int nStart1;
|
|
SIZE sz2;
|
|
while(bFit == false)
|
|
{
|
|
nStart1 = nStart;
|
|
for(int i=0; i < nFit1 - nStart; i++)
|
|
{
|
|
strTemp2[i] = strCurr[nStart1];
|
|
nStart1 ++;
|
|
}
|
|
|
|
strTemp2[i] = _T('\0');
|
|
|
|
GetTextExtentPoint32(hDC,strTemp2,nFit1 - nStart,&sz2);
|
|
|
|
if(sz2.cx < sz1.cx)
|
|
{
|
|
nStart --;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
strCurr[nStart] = _T('\0');
|
|
_sntprintf(outStr,1023,_T("%s\r\n%s%s"),strTemp1,strCurr,strLast);
|
|
outStr[1023] = 0;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//Now we will have to add strLast to the end of trimmed string.
|
|
//Since it will be the same in the first line, we will first calculate fit1 again.
|
|
|
|
SIZE szFinal;
|
|
TCHAR strFinal[1024];
|
|
|
|
_sntprintf(strFinal,1023,_T("%s %s"),strLast,staticString);
|
|
strFinal[1023] = 0;
|
|
|
|
GetTextExtentPoint32(hDC,strFinal,lstrlen(strFinal),&szFinal);
|
|
|
|
//Now subtract szFinal from the ctlWidth and calculate the number of characters
|
|
//that will fit in to that space
|
|
|
|
GetTextExtentExPoint(hDC,strCurr,lstrlen(strCurr),ctlWidth - szFinal.cx ,&nFit1,NULL,&sizeTemp);
|
|
strCurr[nFit1-1] = _T('\0');
|
|
|
|
_sntprintf(outStr,1023,_T("%s\r\n%s%s"),strTemp1,strCurr,strFinal);
|
|
outStr[1023] = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
LRESULT DependencyPage::OnInit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
m_hDlg = m_hWnd;
|
|
|
|
//TODO: Check this out
|
|
if(m_pgConnectThread)
|
|
{
|
|
m_pgConnectThread->SendPtr(m_hWnd);
|
|
}
|
|
|
|
TCHAR szBuffer1[100] = {0}, szBuffer2[256] = {0};
|
|
|
|
SetDlgItemText(IDC_DEPENDS_SRVC, (wchar_t *)m_ServiceDispName);
|
|
|
|
// set the nice bitmap.
|
|
SetClearBitmap(GetDlgItem(IDC_PICT ), MAKEINTRESOURCE( IDB_SERVICE ), 0);
|
|
|
|
// create an empty imagelist.
|
|
HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 3, 0);
|
|
|
|
// add an icon
|
|
m_servIcon = ImageList_AddIcon(hImageList,
|
|
LoadIcon(HINST_THISDLL,
|
|
MAKEINTRESOURCE(IDI_SERVICE)));
|
|
|
|
m_sysDriverIcon = ImageList_AddIcon(hImageList,
|
|
LoadIcon(HINST_THISDLL,
|
|
MAKEINTRESOURCE(IDI_SYSTEMDRIVER)));
|
|
|
|
|
|
m_emptyIcon = ImageList_AddIcon(hImageList,
|
|
LoadIcon(NULL,
|
|
MAKEINTRESOURCE(IDI_INFORMATION)));
|
|
|
|
m_groupIcon = ImageList_AddIcon(hImageList,
|
|
LoadIcon(HINST_THISDLL,
|
|
MAKEINTRESOURCE(IDI_SERVGROUP)));
|
|
|
|
// sent it to the trees.
|
|
TreeView_SetImageList(GetDlgItem(IDC_DEPENDS_TREE),
|
|
hImageList,
|
|
TVSIL_NORMAL);
|
|
|
|
TreeView_SetImageList(GetDlgItem(IDC_NEEDED_TREE),
|
|
hImageList,
|
|
TVSIL_NORMAL);
|
|
|
|
InvalidateRect(NULL);
|
|
UpdateWindow();
|
|
ATLTRACE(L"UpdateWindow() fm Init\n");
|
|
|
|
// can we get data yet?
|
|
::PostMessage(m_hDlg, WM_ENUM_NOW, 0, 0);
|
|
|
|
|
|
HourGlass(true);
|
|
return S_OK;
|
|
}
|
|
//--------------------------------------------------------------
|
|
void DependencyPage::LoadTrees(void)
|
|
{
|
|
|
|
ATLTRACE(L"checking service\n");
|
|
|
|
// did that background connection thread work yet?
|
|
if(ServiceIsReady(IDS_DISPLAY_NAME, IDS_CONNECTING, IDS_BAD_CONNECT))
|
|
{
|
|
//Now we will check if there is already some nodes.
|
|
//If it is, then it means that we don't have to enumerate it again.
|
|
//This normally happens in the first time when we connect to a remote machine
|
|
|
|
/* //We will clear the nodes if it already exists
|
|
TreeView_DeleteAllItems(GetDlgItem(IDC_DEPENDS_TREE));
|
|
TreeView_DeleteAllItems(GetDlgItem(IDC_NEEDED_TREE));
|
|
*/
|
|
if(TreeView_GetCount(GetDlgItem(IDC_DEPENDS_TREE)) == 0)
|
|
{
|
|
HourGlass(true);
|
|
|
|
TV_ITEM root;
|
|
ITEMEXTRA *extra = new ITEMEXTRA;
|
|
if(extra == NULL)
|
|
return;
|
|
root.hItem = TVI_ROOT; // I'm making a root.
|
|
root.pszText = m_ServiceDispName;
|
|
extra->realName = CloneString(m_ServiceName);
|
|
extra->loaded = false;
|
|
extra->nodeType = ServiceNode;
|
|
root.lParam = (LPARAM)extra;
|
|
|
|
InvalidateRect(NULL);
|
|
|
|
UpdateWindow();
|
|
|
|
// load the first levels.
|
|
LoadLeaves(GetDlgItem(IDC_DEPENDS_TREE),
|
|
&root, true);
|
|
|
|
LoadLeaves(GetDlgItem(IDC_NEEDED_TREE),
|
|
&root, false);
|
|
|
|
SetFocus();
|
|
HourGlass(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
BOOL DependencyPage::OnApply()
|
|
{
|
|
::SetWindowLongPtr(m_hDlg, DWLP_USER, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
BOOL DependencyPage::OnKillActive()
|
|
{
|
|
//SetWindowLong(DWL_MSGRESULT, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
LRESULT DependencyPage::OnEnumNow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
if(lParam)
|
|
{
|
|
IStream *pStream = (IStream *)lParam;
|
|
IWbemServices *pServices = 0;
|
|
HRESULT hr = CoGetInterfaceAndReleaseStream(pStream,
|
|
IID_IWbemServices,
|
|
(void**)&pServices);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
SetWbemService(pServices);
|
|
pServices->Release();
|
|
}
|
|
|
|
LoadTrees(); //calls ServiceIsReady() itself.
|
|
}
|
|
else if(FAILED(m_pgConnectThread->m_hr))
|
|
{
|
|
DisplayUserMessage(m_hDlg, HINST_THISDLL,
|
|
IDS_DISPLAY_NAME, BASED_ON_SRC,
|
|
ConnectServer,
|
|
m_pgConnectThread->m_hr,
|
|
MB_ICONSTOP);
|
|
}
|
|
else
|
|
{
|
|
m_pgConnectThread->NotifyWhenDone(&m_hDlg);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
LRESULT DependencyPage::OnItemExpanding(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
|
|
{
|
|
// which node?
|
|
NM_TREEVIEW *notice = (NM_TREEVIEW *)pnmh;
|
|
|
|
// we're expanding, not collapsing...
|
|
if(notice->action == TVE_EXPAND)
|
|
{
|
|
// which tree?
|
|
HWND treeHWND = GetDlgItem(idCtrl);
|
|
|
|
TV_ITEM item;
|
|
item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN |TVIF_IMAGE;
|
|
item.pszText = new TCHAR[200];
|
|
item.cchTextMax = 200;
|
|
item.hItem = notice->itemNew.hItem;
|
|
|
|
TreeView_GetItem(treeHWND, &item);
|
|
|
|
// if we've never tried...
|
|
if(((ITEMEXTRA *)item.lParam)->loaded == false)
|
|
{
|
|
// NOTE: really cant get here if its not ready
|
|
// but better safe than sorry.
|
|
if(ServiceIsReady(IDS_DISPLAY_NAME, IDS_CONNECTING, IDS_BAD_CONNECT))
|
|
{
|
|
// load it.
|
|
LoadLeaves(treeHWND, &item, (idCtrl == IDC_DEPENDS_TREE));
|
|
}
|
|
}
|
|
|
|
delete[] item.pszText;
|
|
} //end action
|
|
return S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
LRESULT DependencyPage::OnDeleteItem(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
|
|
{
|
|
NM_TREEVIEW *notice = (NM_TREEVIEW *)pnmh;
|
|
delete[] (TCHAR *)((ITEMEXTRA *)notice->itemOld.lParam)->realName;
|
|
delete (ITEMEXTRA *)notice->itemOld.lParam;
|
|
return S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
DWORD aDepHelpIds[] = {
|
|
IDC_PICT, -1,
|
|
IDC_DESC, -1,
|
|
IDC_DEPENDS_LBL, (985), // dependsOn
|
|
IDC_DEPENDS_TREE, (985), // dependsOn
|
|
IDC_NEEDED_LBL, (988), // neededBy
|
|
IDC_NEEDED_TREE, (988), // neededBy
|
|
0, 0
|
|
};
|
|
|
|
LRESULT DependencyPage::OnF1Help(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
::WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
|
|
L"filemgmt.hlp",
|
|
HELP_WM_HELP,
|
|
(ULONG_PTR)(LPSTR)aDepHelpIds);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------
|
|
LRESULT DependencyPage::OnContextHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
::WinHelp((HWND)wParam,
|
|
L"filemgmt.hlp",
|
|
HELP_CONTEXTMENU,
|
|
(ULONG_PTR)(LPSTR)aDepHelpIds);
|
|
|
|
return S_OK;
|
|
}
|