📄 allgroupnode.cpp
字号:
#include "stdafx.h"
#include "AllGroupNode.h"
#include <strsafe.h>
#include "comutil.h"
// {4D2C78C6-D62F-401f-9687-1F65A8D0812C}
static const GUID CAllGroupNodeGUID_NODETYPE =
{ 0x4d2c78c6, 0xd62f, 0x401f, { 0x96, 0x87, 0x1f, 0x65, 0xa8, 0xd0, 0x81, 0x2c } };
const GUID* CAllGroupNode::m_NODETYPE = &CAllGroupNodeGUID_NODETYPE;
const OLECHAR* CAllGroupNode::m_SZNODETYPE = OLESTR("4D2C78C6-D62F-401f-9687-1F65A8D0812C");
const OLECHAR* CAllGroupNode::m_SZDISPLAY_NAME = OLESTR("本地组");
const CLSID* CAllGroupNode::m_SNAPIN_CLASSID = &CLSID_AuthorityMgr;
HRESULT CAllGroupNode::OnExpand(BOOL bExpand, IConsole *pConsole, HSCOPEITEM parent)
{
if (!bExpand)
return S_OK;
m_scopeDataItem.ID = parent;
HSCOPEITEM hChild = NULL;
long cookie = 0;
CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(pConsole);
spConsoleNameSpace->GetChildItem(m_scopeDataItem.ID, &hChild, &cookie);
if (hChild != NULL)
spConsoleNameSpace->DeleteItem(m_scopeDataItem.ID, FALSE);
// cache the stuff
m_pConsoleNameSpace = spConsoleNameSpace;
m_scopeitem = parent;
if (m_bViewUpdated == false && m_running == false)
{
StartThread();
}
/*
HRESULT hr;
for(int i=0; i<m_vecItems.size(); i++)
{
m_vecItems[i]->m_scopeDataItem.relativeID = m_scopeDataItem.ID;
m_vecItems[i]->m_scopeDataItem.nImage=INDEX_Group;
m_vecItems[i]->m_scopeDataItem.nOpenImage=INDEX_Group;
hr=spConsoleNameSpace->InsertItem(&m_vecItems[i]->m_scopeDataItem);
_ASSERT( SUCCEEDED(hr) );
}
*/
return S_OK;
//after this MMC calls GetDisplayInfo() which
//in ATL translates to GetScopePaneInfo()
}
BOOL CAllGroupNode::InitChildren()
{
HRESULT hr;
IADsContainer *pCont;
CoInitialize(NULL);
////////////////////////////////
// 绑定到一个目录对象这里绑定到一个本地计算机
//////////////////////////////////
// hr = ADsGetObject(L"WinNT://INDEPENDENCE", IID_IADsContainer, (void**) &pCont );
hr = ADsGetObject(L"WinNT://WORKGROUP/XP", IID_IADsContainer, (void**) &pCont );
if ( !SUCCEEDED(hr) )
{
return 0;
}
///////////////////////////////////
// 建立过滤器
/////////////////////////////////
LPWSTR pszFilter[] = { L"group" };
DWORD dwNumber = sizeof( pszFilter ) /sizeof(LPWSTR);
VARIANT var;
hr = ADsBuildVarArrayStr( pszFilter, dwNumber, &var );
if ( !SUCCEEDED(hr) )
{
pCont->Release();
return hr;
}
///////////////////////////////////
// 设置过滤器
/////////////////////////////////
hr = pCont->put_Filter(var);
VariantClear(&var);
if (!SUCCEEDED(hr) )
{
pCont->Release();
return hr;
}
/////////////////////////////////
// 枚举所有组对象,初试化所有组对象节点
/////////////////////////////////
IEnumVARIANT *pEnum = NULL;
hr = ADsBuildEnumerator( pCont, &pEnum );
if ( SUCCEEDED(hr) )
{
VARIANT var;
ULONG lFetch;
IADs *pChild=NULL;
VariantInit(&var);
while( SUCCEEDED(ADsEnumerateNext( pEnum, 1, &var, &lFetch )) && lFetch == 1 )
{
hr = V_DISPATCH(&var)->QueryInterface( IID_IADs, (void**) &pChild );
if ( SUCCEEDED(hr) )
{
BSTR bstrName;
BSTR bstrClass;
// 得到组目录对象的相关信息
pChild->get_Name(&bstrName);
pChild->get_Class(&bstrClass);
BSTR bstrADsPath;
pChild->get_ADsPath(&bstrADsPath);
//*********************************************
//以下查询该组的详细信息,包括描述,
//如果需要,可进一步查询属于该组的所有用户
//*********************************************
IADsGroup *pGroup=NULL;
const size_t cchBuffer = 500;
static _TCHAR buf[cchBuffer];
StringCchPrintf(buf, cchBuffer, _T("%s,Group"),_com_util::ConvertBSTRToString(bstrADsPath));
//注意下面的Ansi到unicode的字符转换
USES_CONVERSION;
hr=ADsGetObject((LPWSTR)A2W(buf),IID_IADsGroup,(void**)&pGroup);
if ( !SUCCEEDED(hr) )
{
return FALSE;
}
BSTR bstrDes;
pGroup->get_Description(&bstrDes);
//组的GUID
BSTR bstrGUID;
//考虑到Windows NT对GUID的支持的特殊性,
//在此,采用ADsPath来代替GUID的作用
//对于ActiveDictionary,可以使用GUID来
//标识对象,因为,GUID一旦生成,将不再改变,
//而ADsPath会因为用户名/组名改变引起变化,
//造成程序数据的不一致
//pGroup->get_ADsPath(&bstrGUID);
pGroup->get_ADsPath(&bstrGUID);
//名称
CComBSTR param_bstr(bstrName);
//描述
CComBSTR param_bstrDes(bstrDes);
CComBSTR param_bstrGUID(bstrGUID);
m_vecItems.push_back(new CGroupNode(param_bstr.Detach(),
param_bstrDes.Detach(),param_bstrGUID.Detach() ));
// 释放变量
SysFreeString(bstrName);
SysFreeString(bstrClass);
pChild->Release();
}
VariantClear(&var);
}
}
if ( pEnum )
{
ADsFreeEnumerator( pEnum );
}
pCont->Release();
CoUninitialize();
//插入节点
for(int i=0; i<m_vecItems.size(); i++)
{
m_vecItems[i]->m_scopeDataItem.relativeID = m_scopeitem;
m_vecItems[i]->m_scopeDataItem.nImage=INDEX_Group;
m_vecItems[i]->m_scopeDataItem.nOpenImage=INDEX_Group;
hr=m_pConsoleNameSpace->InsertItem(&m_vecItems[i]->m_scopeDataItem);
_ASSERT( SUCCEEDED(hr) );
}
return true;
}
DWORD WINAPI CAllGroupNode::ThreadProc(
LPVOID lpParameter // thread data
)
{
CAllGroupNode *pThis = ( CAllGroupNode *)lpParameter;
EnterCriticalSection(&pThis->m_critSect);
pThis->m_running = true;
LeaveCriticalSection(&pThis->m_critSect);
pThis->InitChildren();
EnterCriticalSection(&pThis->m_critSect);
pThis->m_running = false;
pThis->m_bViewUpdated=true;
LeaveCriticalSection(&pThis->m_critSect);
return 0;
}
void CAllGroupNode::StartThread()
{
EnterCriticalSection(&m_critSect);
m_thread = CreateThread(NULL, 0, ThreadProc, (void *)this, 0, &m_threadId);
LeaveCriticalSection(&m_critSect);
}
void CAllGroupNode::StopThread()
{
EnterCriticalSection(&m_critSect);
m_running = false;
if (m_thread != NULL) {
// this is ugly, wait for 10 seconds, then kill the thread
DWORD res = WaitForSingleObject(m_thread, 10000);
if (res == WAIT_TIMEOUT)
TerminateThread(m_thread, 0);
CloseHandle(m_thread);
m_thread = NULL;
}
LeaveCriticalSection(&m_critSect);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -