⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 allusernode.cpp

📁 .net编写的个人理财系统
💻 CPP
字号:
#include "stdafx.h"
#include "AllUsernode.h"
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
#include "comutil.h"
// {0BC9978F-2767-4748-8590-8E93349D524E}
static const GUID CAllUserNodeGUID_NODETYPE= 
{ 0xbc9978f, 0x2767, 0x4748, { 0x85, 0x90, 0x8e, 0x93, 0x34, 0x9d, 0x52, 0x4e } };

const GUID*  CAllUserNode::m_NODETYPE = &CAllUserNodeGUID_NODETYPE;
const OLECHAR* CAllUserNode::m_SZNODETYPE = OLESTR("0BC9978F-2767-4748-8590-8E93349D524E");
const OLECHAR* CAllUserNode::m_SZDISPLAY_NAME = OLESTR("本地用户");
const CLSID* CAllUserNode::m_SNAPIN_CLASSID = &CLSID_AuthorityMgr;


HRESULT CAllUserNode::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();
	}
	return S_OK;
//after this MMC calls GetDisplayInfo() which 
//in ATL translates to GetScopePaneInfo()
}

BOOL CAllUserNode::InitChildren()
{

	
	HRESULT hr;
	IADsContainer *pCont;
	CoInitialize(NULL);
	

	////////////////////////////////
	// 绑定到一个目录对象这里绑定到一个本地计算机
	//目标计算机可能需要修改,或提供更灵活的机制自动得到本地计算机名和域名
	//////////////////////////////////
	hr = ADsGetObject(L"WinNT://WORKGROUP/XP", IID_IADsContainer, (void**) &pCont );

	if ( !SUCCEEDED(hr) )
	{
		return FALSE;
	}



	///////////////////////////////////
	// 建立过滤器
	/////////////////////////////////
	LPWSTR pszFilter[] = { L"user" };
	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;
		VariantInit(&var);

		ULONG   lFetch;
		IADs   *pChild=NULL;
		IADsMembers *pMembers=NULL;
		IADsUser *pUser=NULL;



		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 bstrGUID;
                //pChild->get_GUID(&bstrGUID);

				BSTR bstrADsPath;
				pChild->get_ADsPath(&bstrADsPath);
				//*********************************************
				//以下查询该用户的详细信息,包括全名,描述,用户所属于的所有组
				//*********************************************
				const size_t cchBuffer = 500;
				static _TCHAR buf[cchBuffer];
				StringCchPrintf(buf, cchBuffer, _T("%s,User"),_com_util::ConvertBSTRToString(bstrADsPath));
				//注意下面的Ansi到unicode的字符转换
				USES_CONVERSION; 
				hr=ADsGetObject((LPWSTR)A2W(buf),IID_IADsUser,(void**)&pUser);
				if ( !SUCCEEDED(hr) )
				{
					return FALSE;
				}
			    BSTR bstrFullName;
                pUser->get_FullName(&bstrFullName);
				BSTR bstrDes;
				pUser->get_Description(&bstrDes);
				//考虑到Windows NT对GUID的支持的特殊性,
				//在此,采用ADsPath来代替GUID的作用
				//对于ActiveDictionary,我们可以使用GUID来
				//标识对象,因为,GUID一旦生成,将不再改变
				//而ADsPath会因为用户名/组名改变引起变化
				//造成程序数据的不一致
				BSTR bstrGUID;
				//pUser->get_GUID(&bstrGUID);
				pUser->get_ADsPath(&bstrGUID);
				//******************************************************
                //以下得到该用户所有属于的组
				//******************************************************
				//清空buf,用于存储组的信息
				StringCchPrintf(buf, cchBuffer, _T("%s"), _T(""));

				hr=pUser->Groups(&pMembers); 
				if ( !SUCCEEDED(hr) )
				{
					return FALSE;
				}
			
				IUnknown *pUnk;
				hr = pMembers->get__NewEnum(&pUnk);
				if ( SUCCEEDED(hr) ){
					IEnumVARIANT *pGroupEnum = NULL;
					hr = pUnk->QueryInterface(IID_IEnumVARIANT,(void**)&pGroupEnum);
					if ( SUCCEEDED(hr) ){
						 // 开始枚举
							BSTR bstr;
							VARIANT varGroup;
							IADs *pADs;
							ULONG lGroupFetch;
							IDispatch *pDisp;
					VariantInit(&varGroup);
					hr = pGroupEnum->Next(1, &varGroup, &lGroupFetch);
					while(hr == S_OK)
					{
						if (lGroupFetch == 1)
						{
							 pDisp = V_DISPATCH(&varGroup);
							 pDisp->QueryInterface(IID_IADs, (void**)&pADs);
							 pADs->get_Name(&bstr);
							 if(strlen(buf)==0){//如果为第一个组
								StringCchPrintf(buf, cchBuffer, _T("%s"),_com_util::ConvertBSTRToString(bstr));
							 }else{//不为第一个组时,添加到一前的组名前,用","分开
								StringCchPrintf(buf, cchBuffer, _T("%s,%s"),buf,_com_util::ConvertBSTRToString(bstr));
							 }
							 SysFreeString(bstr);
							 pADs->Release();
						}
						VariantClear(&varGroup);
						pDisp=NULL;
						hr = pGroupEnum->Next(1, &varGroup, &lGroupFetch);
					};
					hr = pGroupEnum->Release();

					}
				}	
             	//******************************************************
                //以上得到该用户所有属于的组
				//******************************************************  

				//名称
	           CComBSTR param_bstrName(bstrName);
		       //全名
	           CComBSTR param_bstrFullName(bstrFullName);
			   //描述  
			   CComBSTR param_bstrDes(bstrDes);
			   //所属于的组
				CComBSTR param_bstrGroups(buf);

				m_vecItems.push_back(new CUserNode(param_bstrName.Detach(),
				param_bstrFullName.Detach(),param_bstrDes.Detach(),param_bstrGroups.Detach(),bstrGUID));

				// 释放变量
				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_USER;
	   m_vecItems[i]->m_scopeDataItem.nOpenImage=INDEX_USER;

		hr=m_pConsoleNameSpace->InsertItem(&m_vecItems[i]->m_scopeDataItem);
		_ASSERT( SUCCEEDED(hr) );
	}



	return true;
}



 
//线程体
DWORD WINAPI  CAllUserNode::ThreadProc(
  LPVOID lpParameter   // thread data
)
{
     CAllUserNode *pThis = ( CAllUserNode *)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 CAllUserNode::StartThread()
{
		EnterCriticalSection(&m_critSect);
		m_thread = CreateThread(NULL, 0, ThreadProc, (void *)this, 0, &m_threadId);
		LeaveCriticalSection(&m_critSect);

}
//结束线程
void CAllUserNode::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 + -