Click here to Skip to main content
15,897,704 members
Articles / Programming Languages / C++

GUI-Based RunAsEx

Rate me:
Please Sign up or sign in to vote.
4.97/5 (61 votes)
24 Oct 2006CPOL42 min read 401.4K   10.8K   200  
An ultimate tool that lets you RunAs... (With support for non-Pwd, WTS, fake privilege, fake user groups, etc...)
/************************************
  REVISION LOG ENTRY
  Revision By: Zhefu Zhang 
  Contact : codetiger@hotmail.com
  Revised on 2/13/2004 10:11:25 AM
  Comment: it is part of the code sample of 
           http://www.codeguru.com/misc/RunUser.html
 ************************************/
// AccountListDlg.cpp : �C���v�������e�[�V���� �t�@�C��
//

#include "stdafx.h"
#include "zaccessman.h"
#include "AccountListDlg.h"
#include <Lm.h>
#include "z.h"
#include "xMisc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAccountListDlg �_�C�A���O


CAccountListDlg::CAccountListDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAccountListDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CAccountListDlg)
		// ���� - ClassWizard �͂��̈ʒu�Ƀ}�b�s���O�p�̃}�N����lj��܂��͍폜���܂��B
	//}}AFX_DATA_INIT
	m_strRetAccountName = _T("");
}


void CAccountListDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAccountListDlg)
	DDX_Control(pDX, IDC_LIST, m_list);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CAccountListDlg, CDialog)
	//{{AFX_MSG_MAP(CAccountListDlg)
	ON_WM_SIZE()
	ON_NOTIFY(NM_DBLCLK, IDC_LIST, OnDblclkList)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAccountListDlg ���b�Z�[�W �n���h��

BOOL CAccountListDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	CRect rect;
	GetClientRect(&rect);
	m_list.MoveWindow(-1,-1,rect.Width()+2,rect.Height()+2); 
    
	CImageList image;
	image.Create(MAKEINTRESOURCE(IDB_ACCOUNT), 16, 1, RGB(255, 0, 255));
	m_list.SetImageList(&image, LVSIL_SMALL);
	image.Detach();

	ListView_SetExtendedListViewStyle(m_list.GetSafeHwnd(),
		LVS_EX_FULLROWSELECT /*| LVS_SHOWSELALWAYS*/);

	int count = 0;
	//0 name; password_age; priv; comment; full_name; usr_comment; parms;
    //user_sid; primary_group_id;
    m_list.AddColumn(_T("Name   "), count++);
    m_list.AddColumn(_T("Pwd Age"), count++);
	m_list.AddColumn(_T("Priv"), count++);
    m_list.AddColumn(_T("Comment"), count++);
	m_list.AddColumn(_T("full name"), count++);
	m_list.AddColumn(_T("User Comment"), count++);
	m_list.AddColumn(_T("UsrID"), count++);
    m_list.AddColumn(_T("GrpID"), count++);
	PopulateTrusteeList(NULL);
	return TRUE;  // �R���g���[���Ƀt�H�[�J�X��ݒ肵�Ȃ��Ƃ��A�߂�l�� TRUE �ƂȂ�܂�
	              // ��O: OCX �v���p�e�B �y�[�W�̖߂�l�� FALSE �ƂȂ�܂�
}

void CAccountListDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	if(cx > 0 && cx < 2000 && m_list.GetSafeHwnd())
	{
		m_list.MoveWindow(-1,-1,cx+2,cy+2);
	}
}

void CAccountListDlg::PopulateTrusteeList(LPCTSTR szComputerName)
{
	NET_API_STATUS netStatus;

    ListView_DeleteAllItems(m_list.GetSafeHwnd());

    // Enumerate local groups of the system, and add to the trustee list
    ULONG lIndex2 = 0;
    ULONG lRetEntries, lTotalEntries;
    ULONG_PTR ulPtr = 0;
    LOCALGROUP_INFO_0* pinfoGroups;
   
    do
	{
		netStatus = NetLocalGroupEnum(szComputerName, 0, (PBYTE*) &pinfoGroups,
           1000, &lRetEntries, &lTotalEntries, &ulPtr);
        if ((netStatus != ERROR_MORE_DATA) && (netStatus != NERR_Success)) 
		{
            ReportErrEx(TEXT("NetLocalGroupEnum %d"), netStatus);
            break;
		}

        if (lRetEntries != 0) 
		{
			for (lIndex2 = 0; lIndex2 < lRetEntries; lIndex2++) 
			{
				AddTrusteeToList(szComputerName, pinfoGroups[lIndex2].lgrpi0_name, TRUE);
			}
		}
      
        // Free the buffer containing the local groups
        NetApiBufferFree(pinfoGroups);

   } while (netStatus == ERROR_MORE_DATA);

   // Enumerate users of the system and add to the trustee list
   ULONG lIndex = 0;
   NET_DISPLAY_USER* pnetUsers;
   do 
   {
      // Because of the potentially many users on a system, this function
      // is more appropriate than NetUserEnum for UI programs.
      // We will return no more than 20000 users with this call in 1 k chunks
      netStatus = NetQueryDisplayInformation(szComputerName, 1, lIndex, 20000,
         1024, &lRetEntries, (PVOID*) &pnetUsers);
      if ((netStatus != ERROR_MORE_DATA) && (netStatus != NERR_Success)) 
	  {
		  ReportErrEx(TEXT("NetQueryDisplayInformation %d"), netStatus);
          break;
      }

      for (lIndex2 = 0; lIndex2 < lRetEntries; lIndex2++) 
	  {
         AddTrusteeToList(szComputerName, pnetUsers[lIndex2].usri1_name, FALSE);
      }
      
      // Start enumeration where we left off
      lIndex = pnetUsers[lIndex2 - 1].usri1_next_index;
      
      // Free the buffer
      NetApiBufferFree(pnetUsers);

   } while (netStatus == ERROR_MORE_DATA);
	return;
}

int CAccountListDlg::AddTrusteeToList(LPCTSTR szComputerName, LPCTSTR szTrustName, BOOL fGroup)
{
	LVITEM item = { 0 };
    item.mask = LVIF_TEXT | LVIF_IMAGE;
    item.iItem = 0;
    item.iImage = fGroup ? 0 : 1;
    item.pszText =  (LPTSTR)szTrustName;
    int nIndex = ListView_InsertItem(m_list.GetSafeHwnd(), &item);
    ListView_SetItemText(m_list.GetSafeHwnd(), nIndex, 1, 
      fGroup ? TEXT("Group") : TEXT("User"));
    QueryTrusteeDetail(szComputerName, szTrustName, fGroup, nIndex);
	
	return(nIndex);
}

void CAccountListDlg::QueryTrusteeDetail(LPCTSTR szComputerName, LPCTSTR szTrustName, BOOL fGroup, int nIndex)
{
	CString strPwdAge, strPriv, strComment;
	CString strFullName, strUserComment;
	CString strUserID, strGrpID;

	if(!fGroup)
	{
		USER_INFO_3* lpUserInfo = {0};
		NET_API_STATUS netStatus = NetUserGetInfo(szComputerName,  
                 szTrustName, 3, (PBYTE*)&lpUserInfo);
		if (netStatus == NERR_Success) 
		{
			DWORD dw = lpUserInfo->usri3_password_age;
			strPwdAge.Format(_T("%d:%d:%d"), dw/3600, (dw%3600)/60, dw%60);
			switch(lpUserInfo->usri3_priv)
			{
			case USER_PRIV_GUEST:
				strPriv = _T("Guest");
				break;
			case USER_PRIV_USER:
				strPriv = _T("User");
				break;
			case USER_PRIV_ADMIN:
				strPriv = _T("Admin");
				break;
			default:
				strPriv = _T("???");
				break;
			}
			strComment = lpUserInfo->usri3_comment;
			
            strFullName = lpUserInfo->usri3_full_name;
            strUserComment = lpUserInfo->usri3_usr_comment;
			
			LPTSTR UsrSIDString;
			if(ConvertSidToStringSid((PSID)(lpUserInfo->usri3_user_id), &UsrSIDString))
			{
				strUserID = UsrSIDString;
			}
			::LocalFree(UsrSIDString);

			if(strUserID.IsEmpty())
			{
				BYTE sid[50];
				DWORD dwSizeSid = 50;
				TCHAR szDomain[MAX_PATH];
				DWORD dwSizeDomain = MAX_PATH;
				SID_NAME_USE use;
				BOOL fRet = LookupAccountName(szComputerName, szTrustName,
                   &sid, &dwSizeSid, szDomain, &dwSizeDomain, &use);
				if(fRet)
				{
					if(ConvertSidToStringSid((PSID)sid, &UsrSIDString))
					{
						strUserID = UsrSIDString;
					}
			        ::LocalFree(UsrSIDString);
				}
			}


			strGrpID.Format(_T("%d"), lpUserInfo->usri3_primary_group_id);
		}
		else 
			ReportErr(_T("GetUserInfo Failure"));
		NetApiBufferFree(lpUserInfo);
	}
	else //Group
	{
		GROUP_INFO_2* lpGrpInfo = {0};
		NET_API_STATUS netStatus = ::NetGroupGetInfo(szComputerName,  
                 szTrustName, 2, (PBYTE*)&lpGrpInfo);
		if (netStatus == NERR_Success) 
		{
			strComment = lpGrpInfo->grpi2_comment;
			strFullName = lpGrpInfo->grpi2_name;
			strGrpID.Format(_T("%d"), lpGrpInfo->grpi2_group_id);
		}
		else if(netStatus == ERROR_ACCESS_DENIED) 
		{
			ReportErr(_T("GetGroupInfo Failure -- ERROR_ACCESS_DENIED"));
		}
		else if(netStatus == NERR_InvalidComputer) 
		{
			ReportErr(_T("GetGroupInfo Failure -- NERR_InvalidComputer"));
		}
	    else if(netStatus == NERR_GroupNotFound ) 
		{
			//ReportErr(_T("GetGroupInfo Failure -- NERR_GroupNotFound"));
		}
		else
			ReportErr(_T("GetGroupInfo Failure"));
		NetApiBufferFree(lpGrpInfo);
	}

	m_list.AddItem(nIndex, 1, strPwdAge);
	m_list.AddItem(nIndex, 2, strPriv);	
	m_list.AddItem(nIndex, 3, strComment);
	m_list.AddItem(nIndex, 4, strFullName);
	m_list.AddItem(nIndex, 5, strUserComment);
	m_list.AddItem(nIndex, 6, strUserID);
	m_list.AddItem(nIndex, 7, strGrpID);
}

void CAccountListDlg::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
    LVHITTESTINFO lvhti;
	lvhti.pt = pNMListView->ptAction;
	int nItem = m_list.SubItemHitTest(&lvhti);

    //if (lvhti.flags & LVHT_ONITEMLABEL)
	if (lvhti.flags & LVHT_ONITEM)
    {
		if(nItem != -1)
			m_strRetAccountName = m_list.GetItemText(nItem, 0);
	}
	PostMessage(WM_CLOSE, 0, 0);
	*pResult = 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other
United States United States
fdefewtr534554yutki8op09;[pio';l.n,kbnmcvbxcvzxaqW876876UIYIUJUGHJGFHYFGHRDTR4564QWEDASASFDXCBVCBNGHNMJHMJN,NJKL;O[P-0=-]'[P';L/L,M.NM,BNMCGNGFXDGDFGTYU76TRYW34TR5AWERFASDVGfdsxbvfbvnvnm,jkl.k

Comments and Discussions