/************************************
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;
}