|
|
/**********************************************************************/ /** Microsoft Windows NT **/ /** Copyright(c) Microsoft Corp., 1991-1996 **/ /**********************************************************************/
/*
LUsers.cpp : implementation file
CPropertyPage support for Group management wizard FILE HISTORY: Jony Apr-1996 created */
#include "stdafx.h"
#include "Romaine.h"
#include "userlist.h"
#include "LUsers.h"
#include "trstlist.h"
#include <winreg.h>
#include <lmcons.h>
#include <lmaccess.h>
#include <lmerr.h>
#include <lmapibuf.h>
#include <winnetwk.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
// some global objects used in the EnumUsers and EnumGroups threads
CStringList csaNames; CStringList csaLNames; CStringList csaGroups; void EnumGroups(DWORD pDCName); void EnumLocalGroups(DWORD pDCName); void EnumUsers(DWORD pDCName);
/////////////////////////////////////////////////////////////////////////////
// CLUsers property page
IMPLEMENT_DYNCREATE(CLUsers, CPropertyPage)
CLUsers::CLUsers() : CPropertyPage(CLUsers::IDD) { //{{AFX_DATA_INIT(CLUsers)
m_csDomainName = _T(""); m_csAvailableUserList = _T(""); //}}AFX_DATA_INIT
}
CLUsers::~CLUsers() { }
void CLUsers::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CLUsers)
DDX_Control(pDX, IDC_ADDED_LOCAL_USERS, m_lbAddedUserList); DDX_Control(pDX, IDC_AVAILABLE_LOCAL_USERS, m_lbAvailableUserList); DDX_Control(pDX, IDC_DOMAIN_COMBO, m_csDomainList); DDX_CBString(pDX, IDC_DOMAIN_COMBO, m_csDomainName); DDX_LBString(pDX, IDC_AVAILABLE_LOCAL_USERS, m_csAvailableUserList); //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLUsers, CPropertyPage) //{{AFX_MSG_MAP(CLUsers)
ON_BN_CLICKED(IDC_ADD_BUTTON, OnAddButton) ON_CBN_SELCHANGE(IDC_DOMAIN_COMBO, OnSelchangeDomainCombo) ON_WM_SHOWWINDOW() ON_LBN_DBLCLK(IDC_ADDED_LOCAL_USERS, OnDblclkAddedLocalUsers) ON_LBN_DBLCLK(IDC_AVAILABLE_LOCAL_USERS, OnDblclkAvailableLocalUsers) ON_LBN_SETFOCUS(IDC_AVAILABLE_LOCAL_USERS, OnSetfocusAvailableLocalUsers) ON_LBN_SETFOCUS(IDC_ADDED_LOCAL_USERS, OnSetfocusAddedLocalUsers) ON_BN_CLICKED(IDC_REMOVE_BUTTON, OnRemoveButton) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLUsers message handlers
BOOL CLUsers::OnInitDialog() { CPropertyPage::OnInitDialog();
return FALSE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// launch two threads to enumerate the global groups and user accounts in the selected domain
void CLUsers::CatalogAccounts(const TCHAR* lpDomain, CUserList& pListBox, BOOL bLocal /* = FALSE*/) { CWaitCursor wait; wchar_t lpwDomain[255]; _tcscpy(lpwDomain, lpDomain); wchar_t* lpszPrimaryDC = NULL;
NET_API_STATUS err = 0; // first get the name of the PDC machine
if (bLocal) { lpszPrimaryDC = (TCHAR*)malloc((_tcslen(lpDomain) + 1)* sizeof(TCHAR)); _tcscpy(lpszPrimaryDC, lpDomain); }
else err = NetGetDCName( NULL, // Local Machine
lpwDomain, // Domain Name
(LPBYTE *)&lpszPrimaryDC ); // returned PDC *
// empty the listbox
pListBox.ResetContent();
if (err != 0) { AfxMessageBox(IDS_GENERIC_NO_PDC, MB_ICONEXCLAMATION); return; }
csaNames.RemoveAll(); csaLNames.RemoveAll(); csaGroups.RemoveAll();
// create a thread each for names and groups. Run them simultaneously to save some time.
HANDLE hThreads[2]; USHORT usObjCount = 2; DWORD dwThreadID; hThreads[0] = ::CreateThread(NULL, 100, (LPTHREAD_START_ROUTINE)EnumUsers, lpszPrimaryDC, 0, &dwThreadID);
if (!bLocal) { hThreads[1] = ::CreateThread(NULL, 100, (LPTHREAD_START_ROUTINE)EnumGroups, lpszPrimaryDC, 0, &dwThreadID); } else usObjCount = 1; // when both threads return, add all the names to the listbox.
DWORD dwWait = WaitForMultipleObjects(usObjCount, hThreads, TRUE, INFINITE);
POSITION pos; CRomaineApp* pApp = (CRomaineApp*)AfxGetApp();
for (pos = csaNames.GetHeadPosition(); pos != NULL;) pListBox.AddString(0, csaNames.GetNext(pos));
if (!bLocal) { for (pos = csaGroups.GetHeadPosition(); pos != NULL;) pListBox.AddString(1, csaGroups.GetNext(pos)); } if (!bLocal) NetApiBufferFree( lpszPrimaryDC ); else free(lpszPrimaryDC); }
// enum users thread
void EnumUsers(DWORD pDCName) { wchar_t* lpszPrimaryDC = NULL; lpszPrimaryDC = (TCHAR*)pDCName; CString csTemp;
// now enumerate the users on that machine
void* netUserBuffer; DWORD dwReturnedEntries; DWORD err = NetQueryDisplayInformation(lpszPrimaryDC, 1, 0, 100, 100 * sizeof(NET_DISPLAY_USER), &dwReturnedEntries, &netUserBuffer);
// check return for error
if (err != NERR_Success && err != ERROR_MORE_DATA) return;
// add these users to the dialog
DWORD dwCurrent; NET_DISPLAY_USER* netUser; netUser = (NET_DISPLAY_USER*)netUserBuffer; for (dwCurrent = 0; dwCurrent < dwReturnedEntries; dwCurrent++) { csTemp = netUser->usri1_name; csTemp += ";"; csTemp += netUser->usri1_comment;
if (netUser->usri1_flags & UF_NORMAL_ACCOUNT) csaNames.AddHead(csTemp); else csaLNames.AddHead(csTemp);
netUser++; } // add more users?
DWORD dwNext; while (err == ERROR_MORE_DATA) { netUser--; NetGetDisplayInformationIndex(lpszPrimaryDC, 1, netUser->usri1_name, &dwNext); NetApiBufferFree(netUserBuffer); err = NetQueryDisplayInformation(lpszPrimaryDC, 1, dwNext, 100, 32767, &dwReturnedEntries, &netUserBuffer);
// check return for error
if (err != NERR_Success && err != ERROR_MORE_DATA) return;
netUser = (NET_DISPLAY_USER*)netUserBuffer; for (dwCurrent = 0; dwCurrent < dwReturnedEntries; dwCurrent++) { csTemp = netUser->usri1_name; csTemp += ";"; csTemp += netUser->usri1_comment;
if (netUser->usri1_flags & UF_NORMAL_ACCOUNT) csaNames.AddHead(csTemp); else csaLNames.AddHead(csTemp); netUser++; } }
NetApiBufferFree(netUserBuffer);
}
void EnumGroups(DWORD pDCName) { wchar_t* lpszPrimaryDC = NULL; lpszPrimaryDC = (TCHAR*)pDCName; CString csTemp;
void* netGroupBuffer; DWORD dwReturnedEntries; DWORD dwCurrent; DWORD dwNext; // now enumerate the groups on that machine
DWORD err = NetQueryDisplayInformation(lpszPrimaryDC, 3, 0, 100, 100 * sizeof(NET_DISPLAY_GROUP), &dwReturnedEntries, &netGroupBuffer);
// check return for error
if (err != NERR_Success && err != ERROR_MORE_DATA) return;
NET_DISPLAY_GROUP* netGroup; netGroup = (NET_DISPLAY_GROUP*)netGroupBuffer;
// add these names to the dialog
netGroup = (NET_DISPLAY_GROUP*)netGroupBuffer; for (dwCurrent = 0; dwCurrent < dwReturnedEntries; dwCurrent++) { csTemp = netGroup->grpi3_name; csTemp += ";"; csTemp += netGroup->grpi3_comment; csaGroups.AddHead(csTemp); netGroup++; }
// add more names?
while (err == ERROR_MORE_DATA) { netGroup--; NetGetDisplayInformationIndex(lpszPrimaryDC, 3, netGroup->grpi3_name, &dwNext); NetApiBufferFree(netGroupBuffer); err = NetQueryDisplayInformation(lpszPrimaryDC, 3, dwNext, 100, 32767, &dwReturnedEntries, &netGroupBuffer);
// check return for error
if (err != NERR_Success && err != ERROR_MORE_DATA) return;
netGroup = (NET_DISPLAY_GROUP*)netGroupBuffer; for (dwCurrent = 0; dwCurrent < dwReturnedEntries; dwCurrent++) { csTemp = netGroup->grpi3_name; csTemp += ";"; csTemp += netGroup->grpi3_comment; csaGroups.AddHead(csTemp); netGroup++; } } NetApiBufferFree(netGroupBuffer);
}
void CLUsers::OnAddButton() { UpdateData(TRUE);
// start with the domain or machine name to create the account information
CString csValue = m_csDomainName; if (csValue.Left(2) == _T("\\\\")) csValue = csValue.Right(csValue.GetLength() - 2);
csValue += "\\"; csValue += m_csAvailableUserList.Left(m_csAvailableUserList.Find(_T(";")));;
if (m_lbAddedUserList.FindString(-1, csValue) == LB_ERR) m_lbAddedUserList.AddString(csValue, m_lbAvailableUserList.GetItemData(m_lbAvailableUserList.GetCurSel())); /*
// start with the domain or machine name to create the account information
CString csValue = m_csDomainName; if (csValue.Left(2) == _T("\\\\")) csValue = csValue.Right(csValue.GetLength() - 2); csValue += "\\";
INT* pnItems; m_lbAvailableUserList.GetSelItems(1024, pnItems); USHORT sCount = 0; while (sCount < m_lbAvailableUserList.GetSelCount()) { CString csUserName = csValue; CString csSelItem; m_lbAvailableUserList.GetText(*pnItems, csSelItem);
csUserName += csSelItem.Left(csSelItem.Find(_T(";")));
if (m_lbAddedUserList.FindString(-1, csUserName) == LB_ERR) m_lbAddedUserList.AddString(csUserName, m_lbAvailableUserList.GetItemData(*pnItems));
pnItems++; sCount++; } */ }
LRESULT CLUsers::OnWizardBack() { CRomaineApp* pApp = (CRomaineApp*)AfxGetApp(); if (pApp->m_bServer) return IDD_GROUP_TYPE_DLG; else if (pApp->m_csCmdLine != L"") return IDD_GROUP_LIST_DIALOG; else if (pApp->m_sMode == 1) return IDD_GROUP_LIST_DIALOG; else return IDD_LR_DIALOG;
}
LRESULT CLUsers::OnWizardNext() { CRomaineApp* pApp = (CRomaineApp*)AfxGetApp(); pApp->m_cps1.SetWizardButtons(PSWIZB_FINISH | PSWIZB_BACK);
// empty the list
pApp->m_csaNames.RemoveAll();
// fill with new names.
USHORT us; CString csTemp; for (us = 0; us < m_lbAddedUserList.GetCount(); us++) { m_lbAddedUserList.GetText(us, csTemp); pApp->m_csaNames.AddHead(csTemp); }
return IDD_FINISH_DLG; }
void CLUsers::OnSelchangeDomainCombo() { UpdateData(TRUE); m_lbAvailableUserList.ResetContent(); if (m_csDomainName.Left(2) == "\\\\") CatalogAccounts((const TCHAR*)m_csDomainName, m_lbAvailableUserList, TRUE); else CatalogAccounts((const TCHAR*)m_csDomainName, m_lbAvailableUserList); //#ifdef KKBUGFIX
m_lbAvailableUserList.SetCurSel(0); //#endif
}
void CLUsers::OnShowWindow(BOOL bShow, UINT nStatus) { CPropertyPage::OnShowWindow(bShow, nStatus); CRomaineApp* pApp = (CRomaineApp*)AfxGetApp();
CWaitCursor wait; if (bShow) { if (m_csServer != pApp->m_csServer) { m_csServer = pApp->m_csServer; m_lbAddedUserList.ResetContent(); } // on a rerun clean out the members from the last group
else if (pApp->bRestart2) { m_lbAddedUserList.ResetContent(); pApp->bRestart2 = FALSE; } else return;
m_csDomainList.ResetContent(); // get domain list
CWaitCursor wait;
CTrustList pList; if (!pList.BuildTrustList((LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()))) { AfxMessageBox(IDS_NO_WKSALLOWED); pApp->m_cps1.SetActivePage(1); return; }
UINT i; for(i = 0 ; i < pList.m_dwTrustCount ; i++) m_csDomainList.AddString(pList.m_ppszTrustList[i]);
// remove the current machine from the list
if ((i = m_csDomainList.FindStringExact(-1, pApp->m_csServer.Right(pApp->m_csServer.GetLength() - 2))) != LB_ERR) m_csDomainList.DeleteString(i);
// put machine name into list (assuming we are adding to a machine and not a domain)
if (!pApp->m_bDomain) m_csDomainList.AddString(pApp->m_csServer);
// get primary domain
DWORD dwRet; HKEY hKey; DWORD cbProv = 0; TCHAR* lpProv = NULL;
CRomaineApp* pApp = (CRomaineApp*)AfxGetApp(); long lRet = RegConnectRegistry( (LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()), HKEY_LOCAL_MACHINE, &hKey); dwRet = RegOpenKey(hKey, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey );
TCHAR* lpPrimaryDomain = NULL; if ((dwRet = RegQueryValueEx( hKey, TEXT("CachePrimaryDomain"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS) { lpPrimaryDomain = (TCHAR*)malloc(cbProv); if (lpPrimaryDomain == NULL) { AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION); exit(1); }
dwRet = RegQueryValueEx( hKey, TEXT("CachePrimaryDomain"), NULL, NULL, (LPBYTE) lpPrimaryDomain, &cbProv );
}
m_csPrimaryDomain = lpPrimaryDomain; free(lpPrimaryDomain); RegCloseKey(hKey);
CatalogAccounts((const TCHAR*)m_csPrimaryDomain, m_lbAvailableUserList); //#ifdef KKBUGFIX
if (m_csDomainList.SelectString(-1, (const TCHAR*)m_csPrimaryDomain ) == CB_ERR) { CatalogAccounts((const TCHAR*)m_csServer, m_lbAvailableUserList,TRUE); m_csDomainList.SelectString(-1, (const TCHAR*)m_csServer); } //#else
else m_csDomainList.SelectString(-1, (const TCHAR*)m_csPrimaryDomain); //#endif
GetDlgItem(IDC_AVAILABLE_LOCAL_USERS)->SetFocus(); m_lbAvailableUserList.SetCurSel(0);
// editing a group? add the current members
if (pApp->m_sMode == 1) { DWORD dwEntriesRead; DWORD dwTotalEntries; DWORD dwResumeHandle = 0; // m_lbAddedUserList.ResetContent();
TCHAR* pServer = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()); pApp->m_csServer.ReleaseBuffer();
TCHAR* pGroup = pApp->m_csGroupName.GetBuffer(pApp->m_csGroupName.GetLength()); pApp->m_csGroupName.ReleaseBuffer();
PLOCALGROUP_MEMBERS_INFO_1 pMembers; NET_API_STATUS nApi = NetLocalGroupGetMembers(pServer, pGroup, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
if (nApi != ERROR_SUCCESS) return;
USHORT sIndex; for (sIndex = 0; sIndex < dwEntriesRead; sIndex++) { TCHAR pName[50]; DWORD dwNameSize = 50; TCHAR pDomain[50]; DWORD dwDomainNameSize = 50; SID_NAME_USE pUse; LookupAccountSid(pServer, pMembers[sIndex].lgrmi1_sid, pName, &dwNameSize, pDomain, &dwDomainNameSize, &pUse); wchar_t sTemp[150]; swprintf(sTemp, TEXT("%s\\%s"), pDomain, pName);
if (pUse == 1) m_lbAddedUserList.AddString(0, sTemp); else m_lbAddedUserList.AddString(1, sTemp); }
NetApiBufferFree(pMembers);
while (dwResumeHandle != 0) { nApi = NetLocalGroupGetMembers(pServer, pGroup, 1, (LPBYTE*)&pMembers, 5000, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
if (nApi != ERROR_SUCCESS) return;
USHORT sIndex; for (sIndex = 0; sIndex < dwEntriesRead; sIndex++) { TCHAR pName[50]; DWORD dwNameSize = 50; TCHAR pDomain[50]; DWORD dwDomainNameSize = 50; SID_NAME_USE pUse; LookupAccountSid(pServer, pMembers[sIndex].lgrmi1_sid, pName, &dwNameSize, pDomain, &dwDomainNameSize, &pUse); wchar_t sTemp[150]; swprintf(sTemp, TEXT("%s\\%s"), pDomain, pName);
if (pUse == 1) m_lbAddedUserList.AddString(0, sTemp); else m_lbAddedUserList.AddString(1, sTemp);
} NetApiBufferFree(pMembers); } } } }
void CLUsers::OnDblclkAddedLocalUsers() { // CString csSelItem;
// int nSel = m_lbAddedUserList.GetCaretIndex();
// m_lbAddedUserList.DeleteString(nSel);
m_lbAddedUserList.DeleteString(m_lbAddedUserList.GetCurSel());
}
void CLUsers::OnDblclkAvailableLocalUsers() { UpdateData(TRUE); // start with the domain or machine name to create the account information
CString csValue = m_csDomainName; if (csValue.Left(2) == _T("\\\\")) csValue = csValue.Right(csValue.GetLength() - 2);
csValue += "\\"; csValue += m_csAvailableUserList.Left(m_csAvailableUserList.Find(_T(";")));;
if (m_lbAddedUserList.FindString(-1, csValue) == LB_ERR) m_lbAddedUserList.AddString(csValue, m_lbAvailableUserList.GetItemData(m_lbAvailableUserList.GetCurSel())); // start with the domain or machine name to create the account information
/* CString csValue = m_csDomainName;
if (csValue.Left(2) == _T("\\\\")) csValue = csValue.Right(csValue.GetLength() - 2);
csValue += "\\";
CString csSelItem; int nSel = m_lbAvailableUserList.GetCaretIndex(); m_lbAvailableUserList.GetText(nSel, csSelItem); csValue += csSelItem.Left(csSelItem.Find(_T(";")));
if (m_lbAddedUserList.FindString(-1, csValue) == LB_ERR) m_lbAddedUserList.AddString(csValue, m_lbAvailableUserList.GetItemData(nSel)); */
}
void CLUsers::OnSetfocusAvailableLocalUsers() { GetDlgItem(IDC_ADD_BUTTON)->EnableWindow(TRUE); GetDlgItem(IDC_REMOVE_BUTTON)->EnableWindow(FALSE); m_lbAddedUserList.SetCurSel(-1); }
void CLUsers::OnSetfocusAddedLocalUsers() { GetDlgItem(IDC_ADD_BUTTON)->EnableWindow(FALSE); GetDlgItem(IDC_REMOVE_BUTTON)->EnableWindow(TRUE); m_lbAvailableUserList.SetCurSel(-1); }
void CLUsers::OnRemoveButton() { /* INT* pnItems;
m_lbAddedUserList.GetSelItems(1024, pnItems); USHORT sCount = 0; while (sCount < m_lbAddedUserList.GetSelCount()) { // m_lbAddedUserList.DeleteString(*pnItems);
TRACE(L"Item = %d\n\r", *pnItems);
pnItems++; sCount++; } */ m_lbAddedUserList.DeleteString(m_lbAddedUserList.GetCurSel()); m_lbAddedUserList.SetCurSel(0); }
|