|
|
/*******************************************************************************
* * admindoc.cpp * * implementation of the CWinAdminDoc class * * copyright notice: Copyright 1997, Citrix Systems Inc. * Copyright (c) 1998 - 1999 Microsoft Corporation * * $Author: donm $ Don Messerli * * $Log: N:\nt\private\utils\citrix\winutils\tsadmin\VCS\admindoc.cpp $ * * Rev 1.15 25 Apr 1998 13:43:08 donm * MS 2167: try to use proper Wd from registry * * Rev 1.14 19 Feb 1998 17:39:28 donm * removed latest extension DLL support * * Rev 1.12 19 Jan 1998 16:45:28 donm * new ui behavior for domains and servers * * Rev 1.11 13 Nov 1997 13:18:46 donm * removed check for ICA for shadowing * * Rev 1.10 07 Nov 1997 23:05:58 donm * fixed inability to logoff/reset * Rev 1.0 30 Jul 1997 17:10:10 butchd * Initial revision. * *******************************************************************************/
#include "stdafx.h"
#include "winadmin.h"
#include "admindoc.h"
#include "dialogs.h"
#include <malloc.h> // for alloca used by Unicode conversion macros
#include <mfc42\afxconv.h> // for Unicode conversion macros
static int _convert;
#include <winsta.h>
#include <regapi.h>
#include "..\..\inc\utilsub.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#ifdef _STRESS_BUILD
extern BOOL g_fWaitForAllServersToDisconnect; #endif
DWORD Shadow_WarningProc( LPVOID param ); INT_PTR CALLBACK ShadowWarn_WndProc( HWND , UINT , WPARAM , LPARAM ); void CenterDlg(HWND hwndToCenterOn , HWND hDlg ); HWND g_hwndShadowWarn = NULL; DWORD g_dwTreeViewExpandedStates;
// Initialize static variable
NODETYPE CWinAdminDoc::gm_CurrentSelType = NODE_NONE;
#define WM_SETTHEEVENT ( WM_USER + 755 )
// Sort order for Connect States
ULONG SortOrder[] = { 3, //State_Active user logged on to WinStation
2, //State_Connected WinStation connected to client
0, //State_ConnectQuery in the process of connecting to client
5, //State_Shadow shadowing another WinStation
4, //State_Disconnected WinStation logged on without client
6, //State_Idle waiting for client to connect
1, //State_Listen WinStation is listening for connection
9, //State_Reset WinStation is being reset
7, //State_Down WinStation is down due to error
8 //State_Init WinStation in initialization
};
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc
IMPLEMENT_DYNCREATE(CWinAdminDoc, CDocument)
BEGIN_MESSAGE_MAP(CWinAdminDoc, CDocument) //{{AFX_MSG_MAP(CWinAdminDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CWinAdminDoc::m_ProcessContinue = TRUE;
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc constructor
//
CWinAdminDoc::CWinAdminDoc() { // TODO: add one-time construction code here
m_CurrentSelectedNode = NULL; m_CurrentSelectedType = NODE_NONE; m_pTempSelectedNode = NULL; m_TempSelectedType = NODE_NONE; m_AllViewsReady = FALSE; m_hProcessThread = NULL; m_pCurrentDomain = NULL; m_pCurrentServer = NULL; m_pPersistentConnections = NULL; m_InRefresh = FALSE; m_bInShutdown = FALSE; m_UnknownString = ::GetUnknownString();
ASSERT( m_UnknownString != NULL );
((CWinAdminApp*)AfxGetApp())->SetDocument(this);
// If there is an extension DLL, get a pointer to it's global
// info structure
LPFNEXGETGLOBALINFOPROC InfoProc = ((CWinAdminApp*)AfxGetApp())->GetExtGetGlobalInfoProc(); if(InfoProc) { m_pExtGlobalInfo = (*InfoProc)(); } else { m_pExtGlobalInfo = NULL; } // create the default extended server info
// for servers that haven't had their extended info
// created yet
m_pDefaultExtServerInfo = new ExtServerInfo; CString NAString; NAString.LoadString(IDS_NOT_APPLICABLE);
memset(m_pDefaultExtServerInfo, 0, sizeof(ExtServerInfo)); // This is so the N/A TcpAddresses will sort at the end
m_pDefaultExtServerInfo->RawTcpAddress = 0xFFFFFFFF; m_pDefaultExtServerInfo->ServerTotalInUse = 0xFFFFFFFF; lstrcpyn(m_pDefaultExtServerInfo->TcpAddress, NAString, sizeof(m_pDefaultExtServerInfo->TcpAddress) / sizeof(TCHAR)); lstrcpyn(m_pDefaultExtServerInfo->IpxAddress, NAString, sizeof(m_pDefaultExtServerInfo->IpxAddress) / sizeof(TCHAR));
m_focusstate = TREE_VIEW; m_prevFocusState = TAB_CTRL; m_fOnTab = FALSE;
m_pszFavList = NULL;
} // end CWinAdminDoc::CWinAdminDoc
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc destructor
//
CWinAdminDoc::~CWinAdminDoc() { // all code moved to Shutdown();
delete m_pDefaultExtServerInfo; if(m_pPersistentConnections) LocalFree(m_pPersistentConnections);
if( m_UnknownString != NULL ) { LocalFree( ( PVOID )m_UnknownString ); }
} // end CWinAdminDoc::~CWinAdminDoc
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ShutdownMessage
//
void CWinAdminDoc::ShutdownMessage(UINT id, CDialog *pDlg) { ASSERT(pDlg);
CString AString;
AString.LoadString(id); pDlg->SetDlgItemText(IDC_SHUTDOWN_MSG, AString);
} // end CWinAdminDoc::ShutdownMessage
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::Shutdown
//
void CWinAdminDoc::Shutdown(CDialog *pDlg) { ASSERT(pDlg); m_bInShutdown = TRUE; // Iterate through the domain list
POSITION pos = m_DomainList.GetHeadPosition(); ShutdownMessage(IDS_SHUTDOWN_DOMAINTHREADS, pDlg); while(pos) { // Go to the next domain in the list
CDomain *pDomain = (CDomain*)m_DomainList.GetNext(pos); pDomain->ClearBackgroundContinue(); // Fire off the event to wake him up if he is
// waiting
pDomain->SetEnumEvent(); } pos = m_DomainList.GetHeadPosition(); while(pos) { // Go to the next domain in the list
CDomain *pDomain = (CDomain*)m_DomainList.GetNext(pos); pDomain->StopEnumerating(); }
// Tell the process thread to terminate and wait for it to do so
// make sure the process thread is still running first
DWORD dwThreadExitCode; GetExitCodeThread(m_hProcessThread, &dwThreadExitCode); if (dwThreadExitCode == STILL_ACTIVE) { ShutdownMessage(IDS_SHUTDOWN_PROCTHREAD, pDlg); m_ProcessContinue = FALSE;
// fire off the event to wake him up if he is waiting
m_ProcessWakeUpEvent.SetEvent();
// wait until the thread is finished
WaitForSingleObject(m_hProcessThread, INFINITE);
// we're done with our process thread so we can close the handle
CloseHandle(m_hProcessThread); }
ShutdownMessage(IDS_SHUTDOWN_PREFS, pDlg); WritePreferences(); LockServerList(); ShutdownMessage(IDS_SHUTDOWN_NOTIFY, pDlg); // First, tell all the server background threads to stop.
// We do this before the destructor for each server does it
// so that the background threads for all the servers can stop
// and we don't have to wait until we get to the destructor for
// each server
pos = m_ServerList.GetHeadPosition(); while(pos) { // Go to the next server in the list
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); pServer->ClearBackgroundContinue(); } // Iterate through the server list
pos = m_ServerList.GetHeadPosition(); while(pos) { // Go to the next server in the list
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if(pServer->IsState(SS_GOOD)) { CString AString; AString.Format(IDS_DISCONNECTING, pServer->GetName()); pDlg->SetDlgItemText(IDC_SHUTDOWN_MSG, AString); } pServer->Disconnect( ); delete pServer; } m_ServerList.RemoveAll(); UnlockServerList(); // Iterate through the domain list
pos = m_DomainList.GetHeadPosition(); while(pos) { // Go to the next domain in the list
CDomain *pDomain = (CDomain*)m_DomainList.GetNext(pos); delete pDomain; } m_DomainList.RemoveAll(); // If there is an extension DLL, call it's shutdown function
LPFNEXSHUTDOWNPROC ShutdownProc = ((CWinAdminApp*)AfxGetApp())->GetExtShutdownProc(); if(ShutdownProc) { (*ShutdownProc)(); } // Iterate through the Wd list
LockWdList(); pos = m_WdList.GetHeadPosition(); while(pos) { // Go to the next Wd in the list
CWd *pWd = (CWd*)m_WdList.GetNext(pos); delete pWd; } m_WdList.RemoveAll(); UnlockWdList(); ShutdownMessage(IDS_DONE, pDlg); } // end CWinAdminDoc::Shutdown
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanCloseFrame
//
BOOL CWinAdminDoc::CanCloseFrame(CFrameWnd *pFW) { ASSERT(pFW); CWaitCursor Nikki; CDialog dlgWait; dlgWait.Create(IDD_SHUTDOWN, pFW); Shutdown(&dlgWait); dlgWait.PostMessage(WM_CLOSE); return TRUE; } // end CWinAdminDoc::CanCloseFrame
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::OnNewDocument
//
BOOL CWinAdminDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here
// (SDI documents will reuse this document)
ReadPreferences(); BuildWdList(); BuildDomainList(); // Create a pServer object for the Server we are running on, this will give
// him a headstart in getting his information
CServer *pServer = new CServer(m_pCurrentDomain, ((CWinAdminApp*)AfxGetApp())->GetCurrentServerName(), FALSE, TRUE); m_pCurrentServer = pServer; if( pServer ) { AddServer(pServer); } // Start enumerating servers in the current domain
// if(m_pCurrentDomain) m_pCurrentDomain->StartEnumerating();
// Start the background thread to enumerate processes
DWORD dwThreadID; m_hProcessThread = CreateThread(NULL, // default security attributes
0, // default stack size
CWinAdminDoc::ProcessThreadProc, this, // param passed into threadProc
0, // default creation flags
&dwThreadID); // make sure our thread created by ensuring the handle is non null
if (!m_hProcessThread) { return FALSE; } return TRUE; } // end CWinAdminDoc::OnNewDocument
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc serialization
//
void CWinAdminDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here
} else { // TODO: add loading code here
} } // end CWinAdminDoc::Serialize
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc diagnostics
//
#ifdef _DEBUG
void CWinAdminDoc::AssertValid() const { CDocument::AssertValid(); }
void CWinAdminDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ShouldConnect
//
// Returns TRUE if the server is in the list of persistent connections
//
BOOL CWinAdminDoc::ShouldConnect(LPWSTR pServerName) { ASSERT(pServerName); if(m_ConnectionsPersistent && m_pPersistentConnections) { LPWSTR pTemp = m_pPersistentConnections; while(*pTemp) { if( !wcscmp( pTemp , pServerName ) ) { return TRUE; } // Go to the next server in the buffer
pTemp += (wcslen(pTemp) + 1); } } return FALSE; }
//=-------------------------------------------------------------------
BOOL CWinAdminDoc::ShouldAddToFav( LPTSTR pServerName ) { ODS( L"CWinAdminDoc::ShouldAddToFav\n" ); if( m_pszFavList != NULL ) { LPTSTR pszTemp = m_pszFavList; while(*pszTemp) { if( !wcscmp( pszTemp , pServerName ) ) { DBGMSG( L"Adding %s to favorites\n" , pszTemp ); return TRUE; } // Go to the next server in the buffer
pszTemp += ( wcslen( pszTemp ) + 1 ); } } return FALSE; }
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ProcessThreadProc
//
// Static member function for process thread
// Called with AfxBeginThread
// Thread terminates when function returns
//
DWORD WINAPI CWinAdminDoc::ProcessThreadProc(LPVOID _doc) { ASSERT(_doc); // We need a pointer to the document so we can make
// calls to member functions
CWinAdminDoc *pDoc = (CWinAdminDoc*)_doc; // We can't send messages to the view until they're ready
while(!pDoc->AreAllViewsReady()) Sleep(500); pDoc->AddToFavoritesNow( ); CFrameWnd *p = (CFrameWnd*)pDoc->GetMainWnd(); if( p != NULL ) { p->SendMessage( WM_ADMIN_UPDATE_TVSTATE , 0 , 0 ); } while(1) { // We don't want to do this constantly, it eats up processor cycles
// Document destructor will signal the event to wake us up if he
// wants us to quit
pDoc->m_ProcessWakeUpEvent.Lock(((CWinAdminApp*)AfxGetApp())->GetProcessListRefreshTime()); // Make sure we don't have to quit
if(!ShouldProcessContinue()) return 0; // We only want to enumerate processes if the page is VIEW_SERVER or VIEW_WINSTATION
if(pDoc->GetCurrentView() == VIEW_SERVER || pDoc->GetCurrentView() == VIEW_WINSTATION) { CServer *pServer = (pDoc->GetCurrentView() == VIEW_SERVER) ? (CServer*)pDoc->GetCurrentSelectedNode() : (CServer*)((CWinStation*)pDoc->GetCurrentSelectedNode())->GetServer(); // Enumerate processes for this server if his state is SS_GOOD
if(pServer->IsState(SS_GOOD)) { pServer->EnumerateProcesses(); } // Make sure we don't have to quit
if(!ShouldProcessContinue()) return 0; // We only want to send a message to update the view if the
// view is still VEIW_SERVER/VIEW_WINSTATION and the currently
// selected Server is the same one that we just enumerate processes for
if((pDoc->GetCurrentView() == VIEW_SERVER && pServer == (CServer*)pDoc->GetCurrentSelectedNode()) || (pDoc->GetCurrentView() == VIEW_WINSTATION && pServer == (CServer*)((CWinStation*)pDoc->GetCurrentSelectedNode())->GetServer())) { CFrameWnd *pWnd = (CFrameWnd*)pDoc->GetMainWnd(); if(pWnd && ::IsWindow(pWnd->GetSafeHwnd())) pWnd->SendMessage(WM_ADMIN_UPDATE_PROCESSES, 0, (LPARAM)pServer); } } // Make sure we don't have to quit
if(!ShouldProcessContinue()) return 0; } return 0; } // end CWinAdminDoc::ProcessThreadProc
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::UpdateAllProcesses
//
void CWinAdminDoc::UpdateAllProcesses() { LockServerList(); POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // Enumerate processes for this server if his state is SS_GOOD
if(pServer->IsState(SS_GOOD)) { pServer->EnumerateProcesses(); // Send a message to the view to update this server's processes
CFrameWnd *p = (CFrameWnd*)GetMainWnd(); if(p && ::IsWindow(p->GetSafeHwnd())) p->SendMessage(WM_ADMIN_UPDATE_PROCESSES, 0, (LPARAM)pServer); } } UnlockServerList(); } // end CWinAdminDoc::UpdateAllProcesses
static TCHAR szWinAdminAppKey[] = REG_SOFTWARE_TSERVER TEXT("\\TSADMIN"); static TCHAR szConnectionsPersistent[] = TEXT("ConnectionsPersistent"); static TCHAR szFavList[] = TEXT("Favorites" ); static TCHAR szTVStates[] = TEXT( "TreeViewStates" ); static TCHAR szConnections[] = TEXT("Connections");
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ReadPreferences
//
// Read user preferences
//
void CWinAdminDoc::ReadPreferences() { HKEY hKeyWinAdmin; DWORD dwType, cbData, dwValue; // Set to defaults
m_ConnectionsPersistent = FALSE; // Open registry key for our application
DWORD Disposition; if( RegCreateKeyEx( HKEY_CURRENT_USER , szWinAdminAppKey, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &hKeyWinAdmin, &Disposition) != ERROR_SUCCESS ) { return; } // Read the favorites list
DWORD dwLen = 0; dwType = 0; // See how big the multi-string is
int err = RegQueryValueEx( hKeyWinAdmin, szFavList, NULL, &dwType, NULL, &dwLen ); if( err == ERROR_SUCCESS || err == ERROR_BUFFER_OVERFLOW ) { m_pszFavList = ( LPWSTR )LocalAlloc( 0 , dwLen ); if( m_pszFavList != NULL ) { memset( m_pszFavList , 0 , dwLen ); RegQueryValueEx( hKeyWinAdmin, szFavList, NULL, &dwType, (LPBYTE)m_pszFavList, &dwLen); } } // Read the Connections Persist preference
cbData = sizeof( m_ConnectionsPersistent ); if( RegQueryValueEx( hKeyWinAdmin , szConnectionsPersistent , NULL, &dwType, (LPBYTE)&dwValue, &cbData) == ERROR_SUCCESS) { m_ConnectionsPersistent = dwValue; } // If connections are persistent, read the list of connections saved
if( m_ConnectionsPersistent ) { dwLen = 0; dwType = 0; // See how big the multi-string is
err = RegQueryValueEx( hKeyWinAdmin, szConnections, NULL, &dwType, NULL, &dwLen ); if(err && (err != ERROR_BUFFER_OVERFLOW) ) { RegCloseKey(hKeyWinAdmin); return; } m_pPersistentConnections = (LPWSTR)LocalAlloc(0, dwLen); if( m_pPersistentConnections != NULL ) { memset(m_pPersistentConnections, 0, dwLen); RegQueryValueEx( hKeyWinAdmin, szConnections, NULL, &dwType, (LPBYTE)m_pPersistentConnections, &dwLen); } } g_dwTreeViewExpandedStates = 0; dwLen = sizeof( g_dwTreeViewExpandedStates ); RegQueryValueEx( hKeyWinAdmin , szTVStates, NULL, &dwType, ( LPBYTE )&g_dwTreeViewExpandedStates, &dwLen ); RegCloseKey(hKeyWinAdmin); } // end CWinAdminDoc::ReadPreferences
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::WritePreferences
//
// Write user preferences
//
void CWinAdminDoc::WritePreferences() { HKEY hKeyWinAdmin; DWORD dwValue; // Open registry key for our application
DWORD Disposition;
if( RegCreateKeyEx( HKEY_CURRENT_USER, szWinAdminAppKey, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyWinAdmin, &Disposition) != ERROR_SUCCESS ) { return; } // Write the servers that are in the favorite list
DWORD dwByteCount = 0; LockServerList();
POSITION pos = m_ServerList.GetHeadPosition();
#ifdef _STRESS_BUILD
int nStressServerLimit = 0; #endif;
while(pos) { #ifdef _STRESS_BUILD
if( nStressServerLimit >= 10000 ) { break; }
nStressServerLimit++; #endif
CServer *pServer = (CServer*)m_ServerList.GetNext(pos);
if( pServer->GetTreeItemFromFav( ) != NULL ) { // format is domain/server
if( pServer->GetDomain( ) ) { dwByteCount += ( wcslen( pServer->GetDomain( )->GetName() ) * 2 ); dwByteCount += 2; } dwByteCount += ( wcslen( pServer->GetName() ) + 1) * 2; } }
LPWSTR pBuffer = NULL;
if( dwByteCount != 0 ) { dwByteCount += 2; // for ending null
// Allocate memory.
if( ( pBuffer = ( LPWSTR )LocalAlloc( LPTR, dwByteCount ) ) != NULL ) { // Traverse list again and copy servers to buffer.
LPWSTR pTemp = pBuffer;
pos = m_ServerList.GetHeadPosition();
#ifdef _STRESS_BUILD
nStressServerLimit = 0; #endif
while(pos) {
#ifdef _STRESS_BUILD
if( nStressServerLimit >= 10000 ) { break; }
nStressServerLimit++; #endif
// Go to the next server in the list
CServer *pServer = (CServer*)m_ServerList.GetNext(pos);
if( pServer->GetTreeItemFromFav( ) != NULL ) { if( pServer->GetDomain( ) ) { lstrcpy( pTemp , pServer->GetDomain( )->GetName( ) ); lstrcat( pTemp , L"/" ); } lstrcat(pTemp, pServer->GetName());
pTemp += ( wcslen( pTemp ) + 1); } } *pTemp = L'\0'; // ending null
RegSetValueEx (hKeyWinAdmin, szFavList, 0, REG_MULTI_SZ, (PBYTE)pBuffer, dwByteCount); LocalFree(pBuffer); } } else { RegDeleteValue( hKeyWinAdmin , szFavList ); }
UnlockServerList();
// Write the persistent connections preference
dwValue = m_ConnectionsPersistent;
RegSetValueEx( hKeyWinAdmin, szConnectionsPersistent, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD) ); if( m_ConnectionsPersistent ) { // Create a multistring of the persistent connections
// loop through the list of servers and see how much memory
// to allocate for the multistring.
dwByteCount = 0; LockServerList(); pos = m_ServerList.GetHeadPosition(); while(pos) { // Go to the next server in the list
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if( pServer->IsState(SS_GOOD) ) { dwByteCount += (wcslen(pServer->GetName()) + 1) * 2; } } UnlockServerList();
dwByteCount += 2; // for ending null
// Allocate memory.
pBuffer = NULL; if( ( pBuffer = ( LPWSTR )LocalAlloc( LPTR, dwByteCount ) ) != NULL ) { // Traverse list again and copy servers to buffer.
LPWSTR pTemp = pBuffer; LockServerList(); pos = m_ServerList.GetHeadPosition(); while(pos) { // Go to the next server in the list
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if( pServer->IsState(SS_GOOD) ) { wcscpy(pTemp, pServer->GetName()); pTemp += (wcslen(pServer->GetName()) + 1); } } UnlockServerList(); *pTemp = L'\0'; // ending null
// write the registry entry
RegSetValueEx(hKeyWinAdmin, szConnections, 0, REG_MULTI_SZ, (PBYTE)pBuffer, dwByteCount); LocalFree(pBuffer); }
} else { RegDeleteValue(hKeyWinAdmin, szConnections); }
// persist treeview state
// send message to treeview to retreive tv state bits
CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
CFrameWnd *p = (CFrameWnd*)pDoc->GetMainWnd();
DWORD dwTVStates = 0;
if( p != NULL ) { dwTVStates = ( DWORD )p->SendMessage( WM_ADMIN_GET_TV_STATES , 0 , 0 ); }
RegSetValueEx( hKeyWinAdmin , szTVStates , 0 , REG_DWORD , ( PBYTE )&dwTVStates , sizeof( DWORD ) ); RegCloseKey(hKeyWinAdmin);
} // end CWinAdminDoc::WritePreferences
/*
static TCHAR DOMAIN_KEY[] = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"); static TCHAR PRIMARY_VAL[] = TEXT("CachePrimaryDomain"); static TCHAR CACHE_VAL[] = TEXT("DomainCache"); */
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::BuildDomainList
//
// Read the list of trusted domains from the registry
// and build a linked list of CDomains
//
void CWinAdminDoc::BuildDomainList() { /*
HKEY hKey,hSubKey; DWORD size = 128; DWORD dwIndex = 0; */ PDOMAIN_CONTROLLER_INFO pDCI;
if( DsGetDcName( NULL , NULL , NULL , NULL , DS_RETURN_FLAT_NAME, &pDCI ) == NO_ERROR ) { CDomain *pDomain = new CDomain( pDCI->DomainName );
if(pDomain != NULL ) { pDomain->SetCurrentDomain();
m_pCurrentDomain = pDomain;
AddDomain( pDomain ); }
NetApiBufferFree( pDCI );
// query for the other domains
LPWSTR szDomainNames = NULL;
if( NetEnumerateTrustedDomains( NULL , &szDomainNames ) == ERROR_SUCCESS ) { LPWSTR pszDN = szDomainNames;
while( *pszDN ) { CDomain *pNewDomain = new CDomain( pszDN ); if( pNewDomain != NULL ) { AddDomain( pNewDomain ); } pszDN += ( wcslen( pszDN ) + 1 ); } NetApiBufferFree( szDomainNames ); } } } // end CWinAdminDoc::BuildDomainList
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::AddDomain
//
// Add a Domain to DomainList in sorted order
//
void CWinAdminDoc::AddDomain(CDomain *pNewDomain) { ASSERT(pNewDomain);
BOOLEAN bAdded = FALSE; POSITION pos, oldpos; int Index;
// Traverse the DomainList and insert this new Domain,
// keeping the list sorted by Name.
for(Index = 0, pos = m_DomainList.GetHeadPosition(); pos != NULL; Index++) { oldpos = pos; CDomain *pDomain = (CDomain*)m_DomainList.GetNext(pos);
if(wcscmp(pDomain->GetName(), pNewDomain->GetName()) > 0) { // The new object belongs before the current list object.
m_DomainList.InsertBefore(oldpos, pNewDomain); bAdded = TRUE; // NOTE: If you add a critical section to protect the domain list,
// you should change this to a break; and unlock the list
// just before exiting this function
return; } }
// If we haven't yet added the Domain, add it now to the tail
// of the list.
if(!bAdded) { m_DomainList.AddTail(pNewDomain); }
} // end CWinAdminDoc::AddDomain
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::BuildWdList
//
// Read the list of Wds from the registry
// and build a linked list of CWds
//
void CWinAdminDoc::BuildWdList() { LONG Status; ULONG Index, ByteCount, Entries; WDNAME WdKey; LONG QStatus; WDCONFIG2 WdConfig; TCHAR WdDll[MAX_PATH]; CWd *pWd;
// Initialize the Wd list.
for ( Index = 0, Entries = 1, ByteCount = sizeof(WDNAME); (Status = RegWdEnumerate( SERVERNAME_CURRENT, &Index, &Entries, WdKey, &ByteCount )) == ERROR_SUCCESS; ByteCount = sizeof(WDNAME) ) {
if ( ( QStatus = RegWdQuery( SERVERNAME_CURRENT, WdKey, &WdConfig, sizeof(WdConfig), &ByteCount ) ) != ERROR_SUCCESS ) {
//If this is added back in, the signature of StandardErrorMessage has changed!!!!
#if 0
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus, IDP_ERROR_REGWDQUERY, WdKey )) return(FALSE); #endif
}
/*
* Only place this Wd in the WdList if it's DLL is present * on the system. */ GetSystemDirectory( WdDll, MAX_PATH ); lstrcat( WdDll, TEXT("\\Drivers\\") ); lstrcat( WdDll, WdConfig.Wd.WdDLL ); lstrcat( WdDll, TEXT(".sys" ) ); if ( _waccess( WdDll, 0 ) != 0 ) continue;
pWd = new CWd(&WdConfig, (PWDNAME)&WdKey);
m_WdList.AddTail(pWd); }
} // end CWinAdminDoc::BuildWdList
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::Refresh
//
// Perform a Refresh
//
void CWinAdminDoc::Refresh() { // We don't want to refresh if we are currently doing one
if(m_InRefresh) return;
CWaitCursor Nikki;
m_InRefresh = TRUE;
// Wake up our background tasks that enumerates servers
POSITION pos = m_DomainList.GetHeadPosition(); while(pos) { CDomain *pDomain = (CDomain*)m_DomainList.GetNext(pos); pDomain->SetEnumEvent(); }
// Make each of the Server's background tasks enumerate WinStations
LockServerList(); pos = m_ServerList.GetHeadPosition(); while(pos) { ULONG WSEventFlags; CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if(pServer->IsHandleGood() && pServer->IsState(SS_GOOD)) { WinStationWaitSystemEvent(pServer->GetHandle(), WEVENT_FLUSH, &WSEventFlags); } }
UnlockServerList();
// If the current page is a processes page, tell appropriate process enumeration
// background thread to do their thing
if(m_CurrentView == VIEW_ALL_SERVERS && m_CurrentPage == PAGE_AS_PROCESSES) { UpdateAllProcesses(); }
if(m_CurrentView == VIEW_DOMAIN && m_CurrentPage == PAGE_DOMAIN_PROCESSES) { UpdateAllProcesses(); }
if((m_CurrentView == VIEW_SERVER && m_CurrentPage == PAGE_PROCESSES) || (m_CurrentView == VIEW_WINSTATION && m_CurrentPage == PAGE_WS_PROCESSES)) { m_ProcessWakeUpEvent.SetEvent(); }
m_InRefresh = FALSE;
} // end CWinAdminDoc::Refresh
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::AddServer
//
// Add a Server to ServerList in sorted order
//
void CWinAdminDoc::AddServer(CServer *pNewServer) { ASSERT(pNewServer); LockServerList(); BOOLEAN bAdded = FALSE; POSITION pos, oldpos; int Index; // Traverse the ServerList and insert this new Server,
// keeping the list sorted by Name.
for(Index = 0, pos = m_ServerList.GetHeadPosition(); pos != NULL; Index++) { oldpos = pos;
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if( lstrcmpi( pServer->GetName() , pNewServer->GetName() ) > 0 ) { // The new object belongs before the current list object.
m_ServerList.InsertBefore(oldpos, pNewServer); bAdded = TRUE; break; } } // If we haven't yet added the Server, add it now to the tail
// of the list.
if(!bAdded) { m_ServerList.AddTail(pNewServer); } UnlockServerList();
} // end CWinAdminDoc::AddServer
//=----------------------------------------------------------------------------------
//= AddToFavoritesNow will add all persisted servers to the fav node and
//= connect to them as appropriate.
void CWinAdminDoc::AddToFavoritesNow( ) { CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
CFrameWnd *p = (CFrameWnd*)pDoc->GetMainWnd();
LPTSTR pszDomain = NULL; LPTSTR pszServer = NULL; LPTSTR pszDomServer = NULL;
int nJump = 0;
POSITION pos;
if( m_pszFavList != NULL ) { pszDomServer = m_pszFavList; while( *pszDomServer ) { pos = m_DomainList.GetHeadPosition();
nJump = wcslen( pszDomServer );
pszDomain = pszDomServer;
TCHAR *pTemp = pszDomServer;
while( *pTemp ) { if( *pTemp == L'/' ) { break; }
pTemp++; } if(*pTemp == L'/') { *pTemp = 0; pTemp++; pszServer = pTemp; } else { //there is no domain for this server
pszServer = pszDomServer; pszDomain = NULL; } // let's check to see if server already exist primarily "this computer"
if( m_pCurrentServer != NULL && lstrcmpi( pszServer , m_pCurrentServer->GetName( ) ) == 0 ) { p->SendMessage(WM_ADMIN_ADDSERVERTOFAV , 0 , (LPARAM)m_pCurrentServer ); } else { CDomain *pDomain = NULL; CServer *pServer = NULL;
if( pszDomain ) { BOOL bFound = FALSE;
while( pos ) { pDomain = (CDomain*)m_DomainList.GetNext(pos); if( _wcsicmp( pDomain->GetName() , pszDomain ) == 0 ) { bFound = TRUE; break; } }
if(!bFound) { pDomain = new CDomain( pszDomain );
if( pDomain != NULL ) { AddDomain( pDomain ); p->SendMessage( WM_ADMIN_ADD_DOMAIN , (WPARAM)NULL , ( LPARAM )pDomain ); } } }
pServer = new CServer( pDomain , pszServer , FALSE , FALSE ); if( pServer != NULL ) { pServer->SetManualFind( );
AddServer(pServer); p->SendMessage(WM_ADMIN_ADDSERVERTOFAV , 0 , (LPARAM)pServer); } } pszDomServer += nJump + 1; } }
// check to see if we need to connect these servers.
LockServerList();
pos = m_ServerList.GetHeadPosition();
while( pos ) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos);
if( ShouldConnect( pServer->GetName( ) ) ) { if( pServer->GetTreeItemFromFav( ) != NULL ) { pServer->Connect( ); } } }
UnlockServerList();
} /////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::FindServerByName
//
// returns a pointer to a given CServer object if it is in our list
//
CServer* CWinAdminDoc::FindServerByName(TCHAR *pServerName) { ASSERT(pServerName);
LockServerList();
POSITION pos = m_ServerList.GetHeadPosition();
while(pos) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if( lstrcmpi( pServer->GetName() , pServerName ) == 0) { UnlockServerList(); return pServer; } }
UnlockServerList();
return NULL;
} // end CWinAdminDoc::FindServerByName
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::FindWdByName
//
// returns a pointer to a given CWd object if it is in our list
//
CWd* CWinAdminDoc::FindWdByName(TCHAR *pWdName) { ASSERT(pWdName);
LockWdList();
POSITION pos = m_WdList.GetHeadPosition();
while(pos) { CWd *pWd = (CWd*)m_WdList.GetNext(pos); if(wcscmp(pWd->GetName(), pWdName) == 0) { UnlockWdList(); return pWd; } }
UnlockWdList();
return NULL;
} // end CWinAdminDoc::FindWdByName
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::SetTreeCurrent
//
void CWinAdminDoc::SetTreeCurrent(CObject* selected, NODETYPE type) { m_CurrentSelectedNode = selected; m_CurrentSelectedType = type; // We need to be able to check the current selected type from other
// threads, in particular when resetting, disconnecting and sending
// a message, to check that we still have a valid winstation
CWinAdminDoc::gm_CurrentSelType = type; CString TitleString;
// Set the window title
switch(m_CurrentSelectedType) { case NODE_ALL_SERVERS: TitleString.LoadString(IDS_TREEROOT); SetTitle(TitleString); break; case NODE_DOMAIN: TitleString.Format(TEXT("\\\\%s"), ((CDomain*)selected)->GetName()); SetTitle(TitleString); break; case NODE_SERVER: SetTitle(((CServer*)selected)->GetName()); break; case NODE_WINSTATION: SetTitle(((CWinStation*)selected)->GetServer()->GetName()); break;
case NODE_THIS_COMP: TitleString.LoadString( IDS_THISCOMPUTER ); SetTitle( TitleString ); break;
case NODE_FAV_LIST: TitleString.LoadString( IDS_FAVSERVERS ); SetTitle( TitleString ); break; }
} // end CWinAdminDoc::SetTreeCurrent
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::SendWinStationMessage
//
// bTemp is TRUE if message is to be sent to the temporarily selected
// tree item.
//
void CWinAdminDoc::SendWinStationMessage(BOOL bTemp, MessageParms *pParms) { ASSERT(pParms);
// Are we sending a message to temporarily selected tree item?
if(bTemp) { // Is the temporarily selected item in the tree a WinStation?
if(m_TempSelectedType == NODE_WINSTATION) { // If the winstation we're working on disappears before we get here
// then just return
if (m_CurrentSelectedType != NODE_WINSTATION) { return; }
pParms->pWinStation = (CWinStation*)m_pTempSelectedNode; pParms->bActionOnCurrentSelection = TRUE; AfxBeginThread((AFX_THREADPROC)CWinStation::SendMessage, pParms); }
return; }
// Is the WinStation selected in the tree?
if(m_CurrentSelectedType == NODE_WINSTATION) { pParms->pWinStation = (CWinStation*)m_CurrentSelectedNode; pParms->bActionOnCurrentSelection = TRUE; AfxBeginThread((AFX_THREADPROC)CWinStation::SendMessage, pParms); }
// Go through the list of WinStations on the currently selected server
// and send messages to those that are selected
else if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { // Make a copy of the MessageParms
MessageParms *pParmsCopy = new MessageParms; if(pParmsCopy) { memcpy(pParmsCopy, pParms, sizeof(MessageParms)); // Start a thread to send the message
pParmsCopy->pWinStation = pWinStation; pParmsCopy->bActionOnCurrentSelection = FALSE; AfxBeginThread((AFX_THREADPROC)CWinStation::SendMessage, pParmsCopy); } } }
// Unlock the list of WinStations
pServer->UnlockWinStationList();
// Delete MessageParms - we sent copies to the WinStation objects
// They will delete their copies
delete pParms; } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { // Make a copy of the MessageParms
MessageParms *pParmsCopy = new MessageParms; if(pParmsCopy) { memcpy(pParmsCopy, pParms, sizeof(MessageParms)); // Start a thread to send the message
pParmsCopy->pWinStation = pWinStation; pParmsCopy->bActionOnCurrentSelection = FALSE; AfxBeginThread((AFX_THREADPROC)CWinStation::SendMessage, pParmsCopy); } } }
// Unlock the list of WinStations
pServer->UnlockWinStationList(); }
UnlockServerList();
// Delete MessageParms - we sent copies to the WinStation objects
// They will delete their copies
delete pParms; }
} // end CWinAdminDoc::SendWinStationMessage
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ConnectWinStation
//
// bTemp is TRUE if we are to connect to the temporarily selected tree item.
//
void CWinAdminDoc::ConnectWinStation(BOOL bTemp, BOOL bUser) { // Are we connecting to temporarily selected tree item?
if(bTemp) { // Is the temporarily selected item in the tree a WinStation?
if(m_TempSelectedType == NODE_WINSTATION) { ((CWinStation*)m_pTempSelectedNode)->Connect(NULL); }
return; }
if(m_CurrentSelectedType == NODE_WINSTATION) { ((CWinStation*)m_CurrentSelectedNode)->Connect(NULL); } // Go through the list of WinStations on the currently selected server
// and disconnect those that are selected
else if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { // do the connect
pWinStation->Connect(bUser); break; // we can only connect to one WinStation
} }
// Unlock the list of WinStations
pServer->UnlockWinStationList(); } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { // do the connect
pWinStation->Connect(bUser); break; // we can only connect to one WinStation
} } // Unlock the list of WinStations
pServer->UnlockWinStationList(); }
UnlockServerList(); }
} // end CWinAdminDoc::ConnectWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::StatusWinStation
//
// bTemp is TRUE if we are to show status for the temporarily selected tree item.
//
void CWinAdminDoc::StatusWinStation(BOOL bTemp) { // Are we showing status for the temporarily selected tree item?
if(bTemp) { // Is the temporarily selected item in the tree a WinStation?
if(m_TempSelectedType == NODE_WINSTATION) { ((CWinStation*)m_pTempSelectedNode)->ShowStatus(); }
return; }
if(m_CurrentSelectedType == NODE_WINSTATION) { ((CWinStation*)m_CurrentSelectedNode)->ShowStatus(); } // Go through the list of WinStations on the currently selected server
// and show status for those that are selected
else if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { pWinStation->ShowStatus(); } }
// Unlock the list of WinStations
pServer->UnlockWinStationList(); } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { pWinStation->ShowStatus(); } }
// Unlock the list of WinStations
pServer->UnlockWinStationList(); }
UnlockServerList(); }
} // end CWinAdminDoc::StatusWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::DisconnectWinStation
//
// bTemp is TRUE if we are disconnecting the temporarily selected tree item.
//
void CWinAdminDoc::DisconnectWinStation(BOOL bTemp) { CWinStation * pCurWinStation; CServer * pCurServer;
// Are we disconnecting the temporarily selected tree item?
if(bTemp) { // Is the temporarily selected item in the tree a WinStation?
if(m_TempSelectedType == NODE_WINSTATION) { // If the winstation we're working on disappears before we get here
// then just return
if (m_CurrentSelectedType != NODE_WINSTATION) { return; }
// create a disconnect parameters structure
DisconnectParms * pDisconParms = new DisconnectParms; if(pDisconParms) { // get currecnt selected node winstation and server
pCurWinStation = (CWinStation*)m_pTempSelectedNode; pCurServer = pCurWinStation->GetServer();
pDisconParms->hServer = pCurServer->GetHandle(); pDisconParms->ulLogonId = pCurWinStation->GetLogonId(); pDisconParms->bActionOnCurrentSelection = TRUE;
AfxBeginThread((AFX_THREADPROC)CWinStation::Disconnect, pDisconParms);
// the thread will delete pDisconParms
} } return; }
if(m_CurrentSelectedType == NODE_WINSTATION) { // create a disconnect parameters structure
DisconnectParms *pDisconParms = new DisconnectParms; if(pDisconParms) { // get currecnt selected node winstation and server
pCurWinStation = (CWinStation*)m_CurrentSelectedNode; pCurServer = pCurWinStation->GetServer();
pDisconParms->hServer = pCurServer->GetHandle(); pDisconParms->ulLogonId = pCurWinStation->GetLogonId(); pDisconParms->bActionOnCurrentSelection = TRUE;
AfxBeginThread((AFX_THREADPROC)CWinStation::Disconnect, pDisconParms);
// the thread will delete pDisconParms
} }
// Go through the list of WinStations on the currently selected server
// and disconnect those that are selected
else if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { // create a disconnect parameters structure
DisconnectParms *pDisconParms = new DisconnectParms; if(pDisconParms) { // get currecnt selected node winstation and server
//pCurWinStation = (CWinStation*)m_pTempSelectedNode;
pCurServer = pWinStation->GetServer();
pDisconParms->hServer = pCurServer->GetHandle(); pDisconParms->ulLogonId = pWinStation->GetLogonId(); pDisconParms->bActionOnCurrentSelection = FALSE;
// Start a thread to do the disconnect
AfxBeginThread((AFX_THREADPROC)CWinStation::Disconnect, pDisconParms);
// the thread will delete pDisconParms
} } }
// Unlock the list of WinStations
pServer->UnlockWinStationList(); } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList();
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { // create a disconnect parameters structure
DisconnectParms *pDisconParms = new DisconnectParms; if(pDisconParms) { // get currecnt selected node winstation and server
//pCurWinStation = (CWinStation*)m_pTempSelectedNode;
pCurServer = pWinStation->GetServer();
pDisconParms->hServer = pCurServer->GetHandle(); pDisconParms->ulLogonId = pWinStation->GetLogonId(); pDisconParms->bActionOnCurrentSelection = FALSE;
// Start a thread to do the disconnect
AfxBeginThread((AFX_THREADPROC)CWinStation::Disconnect, pDisconParms);
// the thread will delete pDisconParms
} } }
// Unlock the list of WinStations
pServer->UnlockWinStationList(); }
UnlockServerList(); } } // end CWinAdminDoc::DisconnectWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ResetWinStation
//
// bTemp is TRUE if we are to reset the temporarily selected tree item.
// bReset is TRUE if reset, FALSE if logoff
//
void CWinAdminDoc::ResetWinStation(BOOL bTemp, BOOL bReset) { // Are we resetting the temporarily selected tree item?
if(bTemp) { // Is the temporarily selected item in the tree a WinStation?
if(m_TempSelectedType == NODE_WINSTATION) { // If the winstation we're working on disappears before we get here
// then just return
if (m_CurrentSelectedType != NODE_WINSTATION) { return; }
// create a reset parameters structure
ResetParms *pResetParms = new ResetParms; if(pResetParms) { pResetParms->pWinStation = (CWinStation*)m_pTempSelectedNode; pResetParms->bReset = bReset; pResetParms->bActionOnCurrentSelection = TRUE; AfxBeginThread((AFX_THREADPROC)CWinStation::Reset, pResetParms);
// the thread will delete pResetParms
} } return; } if(m_CurrentSelectedType == NODE_WINSTATION) { // create a reset parameters structure
ResetParms *pResetParms = new ResetParms;
if(pResetParms) { pResetParms->pWinStation = (CWinStation*)m_CurrentSelectedNode; pResetParms->bReset = bReset; pResetParms->bActionOnCurrentSelection = TRUE; AfxBeginThread((AFX_THREADPROC)CWinStation::Reset, pResetParms);
// the thread will delete pResetParms
} } // Go through the list of WinStations on the currently selected server
// and reset those that are selected
else if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList(); // Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition(); while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
if(pWinStation->IsSelected()) { // create a reset parameters structure
ResetParms *pResetParms = new ResetParms;
if(pResetParms) { pResetParms->pWinStation = pWinStation; pResetParms->bReset = bReset; pResetParms->bActionOnCurrentSelection = FALSE;
// Start a thread to do the reset
AfxBeginThread((AFX_THREADPROC)CWinStation::Reset, pResetParms); // the thread will delete pResetParms
} } } // Unlock the list of WinStations
pServer->UnlockWinStationList(); } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList(); // Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition(); while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
if( pWinStationList != NULL && pWinStation->IsSelected() ) { if( GetCurrentPage( ) == PAGE_AS_USERS && pWinStation->GetState() == State_Listen ) { // from a user experience if the listener winstation has been selected from a
// previous page that went out of focus - then not skipping this winstation
// would appear as if we disconnected from every connected winstation.
continue; } // create a reset parameters structure
ResetParms *pResetParms = new ResetParms; if( pResetParms != NULL ) { pResetParms->pWinStation = pWinStation; pResetParms->bReset = bReset; pResetParms->bActionOnCurrentSelection = FALSE; // Start a thread to do the reset
DBGMSG( L"TSMAN!CWinAdminDoc_ResetWinStation %s\n", pWinStation->GetName() ); AfxBeginThread((AFX_THREADPROC)CWinStation::Reset, pResetParms); } } } // Unlock the list of WinStations
pServer->UnlockWinStationList(); } UnlockServerList(); } } // end CWinAdminDoc::ResetWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ShadowWinStation
//
// bTemp is TRUE if we are to shadow the temporarily selected tree item.
//
void CWinAdminDoc::ShadowWinStation(BOOL bTemp) { // Are we resetting the temporarily selected tree item?
if(bTemp) { // Is the temporarily selected item in the tree a WinStation?
if(m_TempSelectedType == NODE_WINSTATION) { ((CWinStation*)m_pTempSelectedNode)->Shadow(); }
return; }
// Is the WinStation selected in the tree?
if(m_CurrentSelectedType == NODE_WINSTATION) { ((CWinStation*)m_CurrentSelectedNode)->Shadow(); } // Go through the list of WinStations on the currently selected server
// and send messages to those that are selected
else if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList(); BOOL IsLockAlreadyReleased = FALSE;
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { pServer->UnlockWinStationList(); IsLockAlreadyReleased = TRUE; pWinStation->Shadow(); break; // we can only shadow one WinStation
} }
// Unlock the list of WinStations
if (IsLockAlreadyReleased == FALSE) { pServer->UnlockWinStationList(); } } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of WinStations
pServer->LockWinStationList(); // Get a pointer to the server's list of WinStations
CObList *pWinStationList = pServer->GetWinStationList(); BOOL IsLockAlreadyReleased = FALSE;
// Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition();
while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { pServer->UnlockWinStationList(); IsLockAlreadyReleased = TRUE; pWinStation->Shadow(); break; // we can only shadow one WinStation
} }
// Unlock the list of WinStations
if (IsLockAlreadyReleased == FALSE) { pServer->UnlockWinStationList(); } else { break; // we can only shadow one WinStation
} } UnlockServerList(); }
} // end CWinAdminDoc::ShadowWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ServerConnect
//
void CWinAdminDoc::ServerConnect() { ODS( L"CWinAdminDoc::ServerConnect\n" ); // Is the Server selected in the tree?
if(m_TempSelectedType == NODE_SERVER) { CServer *pServer = (CServer*)m_pTempSelectedNode; // Tell the server to connect
if ((pServer->GetState() == SS_BAD) && (pServer->HasLostConnection() || !(pServer->IsServerSane()))) { ODS( L"\tDisconnecting from server\n" ); /* disconnect */ pServer->Disconnect( ); } pServer->Connect(); } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { LockServerList(); POSITION pos = m_ServerList.GetHeadPosition(); ODS( L"\tenumerating from server list\n" ); while(pos) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // If this Server is selected, connect to it
if( pServer->IsSelected() ) { // Tell the server to connect
if ((pServer->GetState() == SS_BAD) && (pServer->HasLostConnection() || !(pServer->IsServerSane()))) { ODS( L"\tDisconnecting from server\n" ); /* disconnect */ pServer->Disconnect( ); } pServer->Connect(); } } UnlockServerList(); }
} // end CWinAdminDoc::ServerConnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ServerDisconnect
//
void CWinAdminDoc::ServerDisconnect() { // Is the Server selected in the tree?
if(m_TempSelectedType == NODE_SERVER) { CServer *pServer = (CServer*)m_pTempSelectedNode; // Tell the server to disconnect
pServer->Disconnect(); } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { CString AString; CDialog dlgWait; dlgWait.Create(IDD_SHUTDOWN, NULL);
LockServerList(); // Do a first loop to signal the server background threads that they must stop
POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // If this Server is selected, stop its background thread
if(pServer->IsSelected()) { // thell the server background thread to stop
pServer->ClearBackgroundContinue(); } } // do a second loop to disconnect the servers
pos = m_ServerList.GetHeadPosition(); while(pos) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // If this Server is selected, disconnect from it
if(pServer->IsSelected()) { AString.Format(IDS_DISCONNECTING, pServer->GetName()); dlgWait.SetDlgItemText(IDC_SHUTDOWN_MSG, AString);
// Tell the server to disconnect
pServer->Disconnect(); } } UnlockServerList();
dlgWait.PostMessage(WM_CLOSE);
}
} // end CWinAdminDoc::ServerDisconnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::TempDomainConnectAllServers
//
// Connect to all the servers in temporarily selected Domain
//
void CWinAdminDoc::TempDomainConnectAllServers() { if(m_TempSelectedType == NODE_DOMAIN) { ((CDomain*)m_pTempSelectedNode)->ConnectAllServers(); }
} // end CWinAdminDoc::TempDomainConnectAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::TempDomainDisconnectAllServers
//
// Disconnect from all servers in temporarily selected Domain
//
void CWinAdminDoc::TempDomainDisconnectAllServers() { if(m_TempSelectedType == NODE_DOMAIN) {
((CDomain*)m_pTempSelectedNode)->DisconnectAllServers(); }
} // end CWinAdminDoc::TempDomainDisconnectAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CurrentDomainConnectAllServers
//
// Connect to all the servers in currently selected Domain
//
void CWinAdminDoc::CurrentDomainConnectAllServers() { if(m_CurrentSelectedType == NODE_DOMAIN) {
((CDomain*)m_CurrentSelectedNode)->ConnectAllServers();
}
} // end CWinAdminDoc::CurrentDomainConnectAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CurrentDomainDisconnectAllServers
//
// Disconnect from all servers in currently selected Domain
//
void CWinAdminDoc::CurrentDomainDisconnectAllServers() { if(m_CurrentSelectedType == NODE_DOMAIN) {
((CDomain*)m_CurrentSelectedNode)->DisconnectAllServers(); }
} // end CWinAdminDoc::CurrentDomainDisconnectAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::DomainFindServers
//
// Find all servers in a Domain
//
void CWinAdminDoc::DomainFindServers() { if(m_TempSelectedType == NODE_DOMAIN) { CDomain *pDomain = (CDomain*)m_pTempSelectedNode;
if(!pDomain->GetThreadPointer()) pDomain->StartEnumerating(); }
} // end CWinAdminDoc::DomainFindServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::ConnectToAllServers
//
// Connect to all the servers
//
void CWinAdminDoc::ConnectToAllServers() { LockServerList(); POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // If this server isn't currently connected, connect to it
if(pServer->IsState(SS_NOT_CONNECTED)) { // Tell the server to connect
pServer->Connect(); } }
UnlockServerList();
} // end CWinAdminDoc::ConnectToAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::DisconnectFromAllServers
//
// Disconnect from all the servers
//
void CWinAdminDoc::DisconnectFromAllServers() { CString AString; CDialog dlgWait; dlgWait.Create(IDD_SHUTDOWN, NULL); // tell each domain thread to stop enumerating while we're shutting down all servers
#ifdef _STRESS_BUILD
g_fWaitForAllServersToDisconnect = 1; #endif
POSITION pos; LockServerList(); // Do a first loop to signal the server background threads that they must stop
pos = m_ServerList.GetHeadPosition();
while( pos ) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // If this Server is currently connected, tell the server background thread to stop
if(pServer->GetState() != SS_NOT_CONNECTED) { pServer->ClearBackgroundContinue(); } } // do a second loop to disconnect the servers
pos = m_ServerList.GetHeadPosition(); while(pos) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos); // If this server is currently connected, disconnect from it
if(pServer->GetState() != SS_NOT_CONNECTED) { AString.Format(IDS_DISCONNECTING, pServer->GetName()); dlgWait.SetDlgItemText(IDC_SHUTDOWN_MSG, AString); // Tell the server to disconnect
pServer->Disconnect(); } } UnlockServerList(); dlgWait.PostMessage(WM_CLOSE);
#ifdef _STRESS_BUILD
g_fWaitForAllServersToDisconnect = 0; #endif
} // end CWinAdminDoc::DisconnectFromAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::FindAllServers
//
// find all Servers in all Domains
//
void CWinAdminDoc::FindAllServers() { if(m_bInShutdown) return;
POSITION pos = m_DomainList.GetHeadPosition(); while(pos) { // Get a pointer to the domain
CDomain *pDomain = (CDomain*)m_DomainList.GetNext(pos); // If this domain isn't currently enumerating servers, tell it to
if(!pDomain->GetThreadPointer()) pDomain->StartEnumerating();
}
} // end CWinAdminDoc::FindAllServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::TerminateProcess
//
void CWinAdminDoc::TerminateProcess() { if(m_CurrentView == VIEW_SERVER) { // Get a pointer to the selected server
CServer *pServer = (CServer*)m_CurrentSelectedNode; // Lock the server's list of Processes
pServer->LockProcessList(); // Get a pointer to the server's list of Processes
CObList *pProcessList = pServer->GetProcessList();
// Iterate through the Process list
POSITION pos = pProcessList->GetHeadPosition();
while(pos) { CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos); if(pProcess->IsSelected() && !pProcess->IsTerminating()) { // Start a thread to do the terminate
AfxBeginThread((AFX_THREADPROC)CWinAdminDoc::TerminateProc, pProcess); } }
// Unlock the list of Processes
pServer->UnlockProcessList(); }
else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { // Get a pointer to the server
CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Lock the server's list of Processes
pServer->LockProcessList(); // Get a pointer to the server's list of Processes
CObList *pProcessList = pServer->GetProcessList();
// Iterate through the Process list
POSITION pos = pProcessList->GetHeadPosition();
while(pos) { CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos); if(pProcess->IsSelected() && !pProcess->IsTerminating()) { // Start a thread to do the terminate
AfxBeginThread((AFX_THREADPROC)CWinAdminDoc::TerminateProc, pProcess); } }
// Unlock the list of Processes
pServer->UnlockProcessList(); } }
else if(m_CurrentView == VIEW_WINSTATION) { // Get the Server for the currently viewed WinStation
CServer *pServer = (CServer*)((CWinStation*)m_CurrentSelectedNode)->GetServer();
// Lock the server's list of Processes
pServer->LockProcessList(); // Get a pointer to the server's list of Processes
CObList *pProcessList = pServer->GetProcessList();
// Iterate through the Process list
POSITION pos = pProcessList->GetHeadPosition();
while(pos) { CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos); if(pProcess->IsSelected() && !pProcess->IsTerminating() && (pProcess->GetWinStation() == (CWinStation*)m_CurrentSelectedNode)) { // Start a thread to do the terminate
AfxBeginThread((AFX_THREADPROC)CWinAdminDoc::TerminateProc, pProcess); } }
// Unlock the list of Processes
pServer->UnlockProcessList(); }
} // end CWinAdminDoc::TerminateProcess
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::TerminateProc
//
UINT CWinAdminDoc::TerminateProc(LPVOID parms) { ASSERT(parms);
CProcess *pProcess = (CProcess*)parms; CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
// Set the flag to say that we are trying to terminate this process
pProcess->SetTerminating();
CFrameWnd *p = (CFrameWnd*)pDoc->GetMainWnd();
if(WinStationTerminateProcess(pProcess->GetServer()->GetHandle(),pProcess->GetPID(), 0)) { // Send a message to remove the process from the view
if(p && ::IsWindow(p->GetSafeHwnd())) { p->SendMessage(WM_ADMIN_REMOVE_PROCESS, 0, (LPARAM)pProcess);
} } else { pProcess->ClearTerminating(); //Display Error Message
if(p && ::IsWindow(p->GetSafeHwnd())) { DWORD Error = GetLastError(); //We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_CANNOT_TERMINATE); StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), LOGONID_NONE,Error,tempErrorMessage.GetLength(),wcslen(pProcess->GetImageName()), IDS_CANNOT_TERMINATE,pProcess->GetImageName()); }
}
return 0;
} // end CWinAdminDoc::TerminateProc
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckConnectAllowed
//
BOOL CWinAdminDoc::CheckConnectAllowed(CWinStation *pWinStation) { ASSERT(pWinStation);
// If they are the same WinStation, don't let them connect
if(pWinStation->GetServer()->IsCurrentServer() && ((CWinAdminApp*)AfxGetApp())->GetCurrentLogonId() == pWinStation->GetLogonId()) return FALSE;
if((((CWinAdminApp*)AfxGetApp())->GetCurrentWSFlags() & WDF_SHADOW_SOURCE) && !pWinStation->HasOutstandingThreads() && !pWinStation->IsDown() && !pWinStation->IsListener() && !pWinStation->IsSystemConsole() && (pWinStation->IsDisconnected() || pWinStation->IsActive()) && pWinStation->IsOnCurrentServer()) return TRUE;
return FALSE;
} // end CWinAdminDoc::CheckConnectAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckDisconnectAllowed
//
BOOL CWinAdminDoc::CheckDisconnectAllowed(CWinStation *pWinStation) { ASSERT(pWinStation);
if(!pWinStation->HasOutstandingThreads() && !pWinStation->IsDown() && !pWinStation->IsListener() && !pWinStation->IsSystemConsole() && pWinStation->IsConnected()) return TRUE;
return FALSE;
} // end CWinAdminDoc::CheckDisconnectAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckResetAllowed
//
BOOL CWinAdminDoc::CheckResetAllowed(CWinStation *pWinStation) { ASSERT(pWinStation);
if(!pWinStation->HasOutstandingThreads() && !pWinStation->IsSystemConsole()) return TRUE;
return FALSE;
} // end CWinAdminDoc::CheckResetAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckShadowAllowed
//
BOOL CWinAdminDoc::CheckShadowAllowed(CWinStation *pWinStation) { ASSERT(pWinStation);
// If they are the same WinStation, don't let them shadow
if( pWinStation->GetServer()->IsCurrentServer() && ((CWinAdminApp*)AfxGetApp())->GetCurrentLogonId() == pWinStation->GetLogonId() ) { return FALSE; }
if(!pWinStation->HasOutstandingThreads() && !pWinStation->IsDown() && // winstation is not down
!pWinStation->IsListener() && // not a listening winstation
!pWinStation->IsDisconnected() && //not disconnected
(((CWinAdminApp*)AfxGetApp())->GetCurrentWSFlags() & WDF_SHADOW_SOURCE) && // We are valid shadow source, query winstation's wdflag in registry
(pWinStation->CanBeShadowed()) && // target can be shadow.
(pWinStation->GetState() != State_Shadow)) // target is not already in shadow
{ return TRUE; }
return FALSE;
} // end CWinAdminDoc::CheckShadowAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckSendMessageAllowed
//
BOOL CWinAdminDoc::CheckSendMessageAllowed(CWinStation *pWinStation) { ASSERT(pWinStation);
if(!pWinStation->HasOutstandingThreads() && !pWinStation->IsDown() && !pWinStation->IsListener() && pWinStation->IsConnected()) return TRUE;
return FALSE;
} // end CWinAdminDoc::CheckSendMessageAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckStatusAllowed
//
BOOL CWinAdminDoc::CheckStatusAllowed(CWinStation *pWinStation) { ASSERT(pWinStation);
if(!pWinStation->HasOutstandingThreads() && !pWinStation->IsDown() && !pWinStation->IsDisconnected() && !pWinStation->IsIdle() && !pWinStation->IsListener() && !pWinStation->IsSystemConsole()) return TRUE;
return FALSE;
} // end CWinAdminDoc::CheckStatusAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CheckActionAllowed
//
BOOL CWinAdminDoc::CheckActionAllowed(BOOL (*CheckFunction)(CWinStation *pWinStation), BOOL AllowMultipleSelected) { ASSERT(CheckFunction); // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_CurrentSelectedType == NODE_WINSTATION) { CWinStation *pWinStation = (CWinStation*)m_CurrentSelectedNode; return CheckFunction(pWinStation); } // We only care if the current view is Server or All Listed Servers
if(m_CurrentView == VIEW_SERVER) { // We need to make sure we are on the WinStation or Users page
if(m_CurrentPage != PAGE_WINSTATIONS && m_CurrentPage != PAGE_USERS) { return FALSE; } int NumSelected = 0; CServer *pServer = (CServer*)m_CurrentSelectedNode; // If there aren't any WinStations selected on this server, return
if(!pServer->GetNumWinStationsSelected()) { return FALSE; } pServer->LockWinStationList(); CObList *pWinStationList = pServer->GetWinStationList(); // Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition(); while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { if(!CheckFunction(pWinStation)) { pServer->UnlockWinStationList(); return FALSE; } NumSelected++; if(!AllowMultipleSelected && NumSelected > 1) { pServer->UnlockWinStationList(); return FALSE; } } } pServer->UnlockWinStationList(); // If we got here, all the selected WinStations passed our criteria
if(NumSelected) return TRUE; } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { // If we are doing a refresh, we can't do anything else
if(m_InRefresh) return FALSE; // We need to make sure we are on the WinStation or Users page
if(m_CurrentPage != PAGE_AS_WINSTATIONS && m_CurrentPage != PAGE_AS_USERS && m_CurrentPage != PAGE_DOMAIN_WINSTATIONS && m_CurrentPage != PAGE_DOMAIN_USERS) return FALSE; int NumSelected = 0; LockServerList(); POSITION pos1 = m_ServerList.GetHeadPosition(); while(pos1) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos1); // Are there any WinStations selected on this server?
if(pServer->GetNumWinStationsSelected()) { pServer->LockWinStationList(); CObList *pWinStationList = pServer->GetWinStationList(); // Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition(); while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { if(!CheckFunction(pWinStation)) { pServer->UnlockWinStationList(); UnlockServerList(); return FALSE; } NumSelected++; if(!AllowMultipleSelected && NumSelected > 1) { pServer->UnlockWinStationList(); UnlockServerList(); return FALSE; } } } pServer->UnlockWinStationList(); } // end if(pServer->GetNumWinStationsSelected())
} UnlockServerList();
// If we got this far, all the selected WinStations passed the criteria
if(NumSelected) return TRUE; } return FALSE; } // end CWinAdminDoc::CheckActionAllowed
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanConnect
//
// Returns TRUE if the currently selected item in views can be Connected to
//
BOOL CWinAdminDoc::CanConnect() { return CheckActionAllowed(CheckConnectAllowed, FALSE);
} // end CWinAdminDoc::CanConnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanDisconnect
//
// Returns TRUE if the currently selected item in views can be Disconnected
//
BOOL CWinAdminDoc::CanDisconnect() { return CheckActionAllowed(CheckDisconnectAllowed, TRUE);
} // end CWinAdminDoc::CanDisconnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanReset
//
// Returns TRUE if the currently selected item in views can be Reset
//
BOOL CWinAdminDoc::CanReset() { return CheckActionAllowed(CheckResetAllowed, TRUE);
} // end CWinAdminDoc::CanReset
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanShadow
//
// Returns TRUE if the currently selected item in views can be Shadowed
//
BOOL CWinAdminDoc::CanShadow() { return CheckActionAllowed(CheckShadowAllowed, FALSE);
} // end CWinAdminDoc::CanShadow
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanSendMessage
//
// Returns TRUE if the currently selected item in views can be sent a message
//
BOOL CWinAdminDoc::CanSendMessage() { return CheckActionAllowed(CheckSendMessageAllowed, TRUE);
} // end CWinAdminDoc::CanSendMessage
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanStatus
//
// Returns TRUE if the currently selected item in views can show Status
//
BOOL CWinAdminDoc::CanStatus() { return CheckActionAllowed(CheckStatusAllowed, TRUE);
} // end CWinAdminDoc::CanStatus
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanLogoff
//
// Returns TRUE if the currently selected item in views can be Logged Off
//
BOOL CWinAdminDoc::CanLogoff() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_CurrentSelectedType == NODE_WINSTATION) { return FALSE; } // We only care if the current view is Server or All Listed Servers
if(m_CurrentView == VIEW_SERVER) { // We need to make sure we are on the Users page
if(m_CurrentPage != PAGE_USERS) return FALSE; BOOL Answer = FALSE; CServer *pServer = (CServer*)m_CurrentSelectedNode; // If there aren't any WinStations selected on this server, return
if(!pServer->GetNumWinStationsSelected()) return FALSE; pServer->LockWinStationList(); CObList *pWinStationList = pServer->GetWinStationList(); // Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition(); while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { if(!pWinStation->HasOutstandingThreads()) Answer = TRUE; } } pServer->UnlockWinStationList(); return Answer; } else if(m_CurrentView == VIEW_ALL_SERVERS || m_CurrentView == VIEW_DOMAIN) { // If we are doing a refesh, we can't do anything else
if(m_InRefresh) return FALSE; // We need to make sure we are on the Users page
if(m_CurrentPage != PAGE_AS_USERS && m_CurrentPage != PAGE_DOMAIN_USERS) return FALSE; BOOL Answer = FALSE; LockServerList(); POSITION pos1 = m_ServerList.GetHeadPosition(); while(pos1) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos1); // Are there any WinStations selected on this server?
if(pServer->GetNumWinStationsSelected()) { pServer->LockWinStationList(); CObList *pWinStationList = pServer->GetWinStationList(); // Iterate through the WinStation list
POSITION pos = pWinStationList->GetHeadPosition(); while(pos) { CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos); if(pWinStation->IsSelected()) { if(!pWinStation->HasOutstandingThreads()) Answer = TRUE; } } pServer->UnlockWinStationList(); } // end if(pServer->GetNumWinStationsSelected())
} UnlockServerList(); return Answer; } return FALSE;
} // end CWinAdminDoc::CanLogoff
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTerminate
//
// Returns TRUE if the currently selected item in views can be Terminated
//
BOOL CWinAdminDoc::CanTerminate() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // We have to be in All Selected Servers, Server, or WinStation view
if((m_CurrentView == VIEW_ALL_SERVERS && m_CurrentPage == PAGE_AS_PROCESSES) || (m_CurrentView == VIEW_DOMAIN && m_CurrentPage == PAGE_DOMAIN_PROCESSES)) { // If we are doing a refresh, we can't do anything else
if(m_InRefresh) return FALSE; // Loop through all the servers and see if any processes are selected
LockServerList(); POSITION pos2 = m_ServerList.GetHeadPosition(); while(pos2) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos2); // Are there any processes selected on this server?
if(pServer->GetNumProcessesSelected()) { pServer->LockProcessList(); CObList *pProcessList = pServer->GetProcessList(); POSITION pos = pProcessList->GetHeadPosition(); while(pos) { CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos); // We only need one process to be selected
if(pProcess->IsSelected() && !pProcess->IsTerminating()) { pServer->UnlockProcessList(); UnlockServerList(); return TRUE; } } pServer->UnlockProcessList(); } // end if(pServer->GetNumProcessesSelected())
} UnlockServerList(); return FALSE; } if(m_CurrentView == VIEW_SERVER && m_CurrentPage == PAGE_PROCESSES) { CServer *pServer = (CServer*)m_CurrentSelectedNode; // If there aren't any processes selected on this server, return
if(!pServer->GetNumProcessesSelected()) return FALSE; pServer->LockProcessList(); CObList *pProcessList = pServer->GetProcessList(); POSITION pos = pProcessList->GetHeadPosition(); while(pos) { CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos); // We only need one process to be selected
if(pProcess->IsSelected() && !pProcess->IsTerminating()) { pServer->UnlockProcessList(); return TRUE; } } pServer->UnlockProcessList(); return FALSE; } if(m_CurrentView == VIEW_WINSTATION && m_CurrentPage == PAGE_WS_PROCESSES) { CServer *pServer = (CServer*)((CWinStation*)m_CurrentSelectedNode)->GetServer(); pServer->LockProcessList(); CObList *pProcessList = pServer->GetProcessList(); POSITION pos = pProcessList->GetHeadPosition(); while(pos) { CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos); // We only need one process to be selected
if(pProcess->IsSelected() && !pProcess->IsTerminating()) { pServer->UnlockProcessList(); return TRUE; } } pServer->UnlockProcessList(); return FALSE; } return FALSE; } // end CWinAdminDoc::CanTerminate
//=--------------------------------------------------------
BOOL CWinAdminDoc::IsAlreadyFavorite( ) { if(m_TempSelectedType == NODE_SERVER) { CServer *pServer = (CServer*)m_pTempSelectedNode; if( pServer->GetTreeItemFromFav( ) != NULL ) { return TRUE; } } return FALSE; }
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanServerConnect
//
// Returns TRUE if the currently selected server in views can be connected to
//
BOOL CWinAdminDoc::CanServerConnect() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a Server selected in the tree?
if(m_TempSelectedType == NODE_SERVER) { if(((CServer*)m_pTempSelectedNode)->GetState() == SS_NOT_CONNECTED || ((CServer*)m_pTempSelectedNode)->GetState() == SS_BAD ) return TRUE; } // Is a Server selected in the tree?
else if(m_CurrentSelectedType == NODE_SERVER) { if(((CServer*)m_CurrentSelectedNode)->GetState() == SS_NOT_CONNECTED || ((CServer*)m_CurrentSelectedNode)->GetState() == SS_BAD ) return TRUE; } // We only care if the current view is Domain or All Listed Servers
else if(m_CurrentView == VIEW_DOMAIN) { // We need to make sure we are on the Servers page
if(m_CurrentPage != PAGE_DOMAIN_SERVERS) return FALSE; int NumSelected = 0; CDomain *pDomain = (CDomain*)m_CurrentSelectedNode; LockServerList(); // Iterate through the Server list
POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if(pServer->IsSelected() && pServer->GetDomain() == pDomain) { if(!pServer->IsState(SS_NOT_CONNECTED)) { UnlockServerList(); return FALSE; } NumSelected++; } } UnlockServerList(); // If we got here, all the selected Servers passed our criteria
if(NumSelected) return TRUE; } else if(m_CurrentView == VIEW_ALL_SERVERS) { // We need to make sure we are on the Servers page
if(m_CurrentPage != PAGE_AS_SERVERS) return FALSE; int NumSelected = 0; LockServerList(); // Iterate through the Server list
POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if(pServer->IsSelected()) { if(!pServer->IsState(SS_NOT_CONNECTED)) { UnlockServerList(); return FALSE; } NumSelected++; } } UnlockServerList(); // If we got here, all the selected Servers passed our criteria
if(NumSelected) return TRUE; } return FALSE; } // end CWinAdminDoc::CanServerConnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanServerDisconnect
//
// Returns TRUE if the currently selected server in views can be disconnected from
//
BOOL CWinAdminDoc::CanServerDisconnect() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a Server selected in the tree?
if(m_TempSelectedType == NODE_SERVER) { if(((CServer*)m_pTempSelectedNode)->GetState() == SS_GOOD) return TRUE; } // Is a Server selected in the tree?
else if(m_CurrentSelectedType == NODE_SERVER) { if(((CServer*)m_CurrentSelectedNode)->GetState() == SS_GOOD) return TRUE; } // We only care if the current view is Domain or All Listed Servers
else if(m_CurrentView == VIEW_DOMAIN) { // We need to make sure we are on the Servers page
if(m_CurrentPage != PAGE_DOMAIN_SERVERS) return FALSE; int NumSelected = 0; CDomain *pDomain = (CDomain*)m_CurrentSelectedNode; LockServerList(); // Iterate through the Server list
POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if(pServer->IsSelected() && pServer->GetDomain() == pDomain) { if(!pServer->IsState(SS_GOOD)) { UnlockServerList(); return FALSE; } NumSelected++; } } UnlockServerList(); // If we got here, all the selected Servers passed our criteria
if(NumSelected) return TRUE; } else if(m_CurrentView == VIEW_ALL_SERVERS) { // We need to make sure we are on the Servers page
if(m_CurrentPage != PAGE_AS_SERVERS) return FALSE; int NumSelected = 0; LockServerList(); // Iterate through the Server list
POSITION pos = m_ServerList.GetHeadPosition(); while(pos) { CServer *pServer = (CServer*)m_ServerList.GetNext(pos); if(pServer->IsSelected()) { if(!pServer->IsState(SS_GOOD)) { UnlockServerList(); return FALSE; } NumSelected++; } } UnlockServerList(); // If we got here, all the selected Servers passed our criteria
if(NumSelected) return TRUE; } return FALSE; } // end CWinAdminDoc::CanServerDisconnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempConnect
//
// Returns TRUE if the temporarily selected item in views can be Connected to
//
BOOL CWinAdminDoc::CanTempConnect() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_TempSelectedType == NODE_WINSTATION) { return CheckConnectAllowed((CWinStation*)m_pTempSelectedNode); } return FALSE; } // end CWinAdminDoc::CanTempConnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempDisconnect
//
// Returns TRUE if the temporarily selected item in views can be Disconnected
//
BOOL CWinAdminDoc::CanTempDisconnect() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_TempSelectedType == NODE_WINSTATION) { return CheckDisconnectAllowed((CWinStation*)m_pTempSelectedNode); } return FALSE; } // end CWinAdminDoc::CanTempDisconnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempReset
//
// Returns TRUE if the temporarily selected item in views can be Reset
//
BOOL CWinAdminDoc::CanTempReset() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_TempSelectedType == NODE_WINSTATION) { // If the winstation we're working on disappears before we get here
// then just return
if (m_CurrentSelectedType == NODE_WINSTATION) { return CheckResetAllowed((CWinStation*)m_pTempSelectedNode); } } return FALSE; } // end CWinAdminDoc::CanTempReset
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempShadow
//
// Returns TRUE if the temporarily selected item in views can be Shadowed
//
BOOL CWinAdminDoc::CanTempShadow() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_TempSelectedType == NODE_WINSTATION) { return CheckShadowAllowed((CWinStation*)m_pTempSelectedNode); } return FALSE; } // end CWinAdminDoc::CanTempShadow
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempSendMessage
//
// Returns TRUE if the temporarily selected item in views can be sent a message
//
BOOL CWinAdminDoc::CanTempSendMessage() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_TempSelectedType == NODE_WINSTATION) { return CheckSendMessageAllowed((CWinStation*)m_pTempSelectedNode); } return FALSE; } // end CWinAdminDoc::CanTempSendMessage
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempStatus
//
// Returns TRUE if the temporarily selected item in views can show Status
//
BOOL CWinAdminDoc::CanTempStatus() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a WinStation selected in the tree?
if(m_TempSelectedType == NODE_WINSTATION) { return CheckStatusAllowed((CWinStation*)m_pTempSelectedNode); } return FALSE; } // end CWinAdminDoc::CanTempStatus
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempDomainConnect
//
// Returns TRUE if the temporarily selected Domain in tree can have all it's
// Servers connected/disconnected to/from.
//
BOOL CWinAdminDoc::CanTempDomainConnect() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a Domain selected in the tree?
if(m_TempSelectedType == NODE_DOMAIN) { if(((CDomain*)m_pTempSelectedNode)->IsState(DS_ENUMERATING)) return TRUE; } return FALSE; } // end CWinAdminDoc::CanTempDomainConnect
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanTempDomainFindServers
//
// Returns TRUE if the temporarily selected Domain in tree can go out
// and find Servers
//
BOOL CWinAdminDoc::CanTempDomainFindServers() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a Domain selected in the tree?
if(m_TempSelectedType == NODE_DOMAIN) { if(!((CDomain*)m_pTempSelectedNode)->GetThreadPointer()) return TRUE; } return FALSE; } // end CWinAdminDoc::CanTempDomainFindServers
/////////////////////////////////////////////////////////////////////////////
// CWinAdminDoc::CanDomainConnect
//
// Returns TRUE if the currently selected Domain in tree can have all it's
// Servers connected/disconnected to/from.
//
BOOL CWinAdminDoc::CanDomainConnect() { // If we are shutting down, we don't care anymore
if(m_bInShutdown) return FALSE; // Is a Domain selected in the tree?
if(m_CurrentSelectedType == NODE_DOMAIN) { if(((CDomain*)m_CurrentSelectedNode)->IsState(DS_ENUMERATING)) return TRUE; } return FALSE; } // end CWinAdminDoc::CanDomainConnect
//------------------------------------------------------------------------------
void CWinAdminDoc::ServerAddToFavorites( BOOL bAdd ) { ODS( L"CWinAdminDoc::ServerAddToFavorites\n"); // we got here from a context menu selection
CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument(); if(m_TempSelectedType == NODE_SERVER && pDoc != NULL ) { CServer* pServer = ( CServer* )m_pTempSelectedNode; if( pServer != NULL ) { // test to see if the server is being removed
if( pServer->IsState(SS_DISCONNECTING) ) { ODS( L"=-sneaky popup menu was up when server went away\n=-not adding server to favs\n"); return; } CFrameWnd *p = (CFrameWnd*)pDoc->GetMainWnd(); if( p !=NULL && ::IsWindow(p->GetSafeHwnd() ) ) { // ok we're off to treeview ville
if( bAdd ) { p->SendMessage(WM_ADMIN_ADDSERVERTOFAV , 0 , (LPARAM)pServer); } else { p->SendMessage( WM_ADMIN_REMOVESERVERFROMFAV, 0 , (LPARAM)pServer); } } } } }
//////////////////////////////////////////////////////////////////////////////////////////
//
// CWinStation Member Functions
//
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CWinStation::CWinStation
//
CWinStation::CWinStation(CServer *pServer, PLOGONID pLogonId) { ASSERT(pServer); m_WinStationFlags = 0L; m_OutstandingThreads = 0; m_hTreeItem = NULL; m_hFavTree = NULL; m_hTreeThisComputer = NULL; m_pWd = NULL; m_UserName[0] = '\0'; m_WdName[0] = '\0'; m_ClientName[0] = '\0'; m_Comment[0] = '\0'; m_SdClass = SdNone; m_LogonTime.HighPart = 0L; m_LogonTime.LowPart = 0L; m_LastInputTime.HighPart = 0L; m_LastInputTime.LowPart = 0L; m_CurrentTime.HighPart = 0L; m_CurrentTime.LowPart = 0L; m_IdleTime.days = 0; m_IdleTime.hours = 0; m_IdleTime.minutes = 0; m_IdleTime.seconds = 0; m_pExtensionInfo = NULL; m_pExtWinStationInfo = NULL; m_pExtModuleInfo = NULL; m_NumModules = 0; m_ProtocolType = 0; m_clientDigProductId[0] = '\0'; SetCurrent(); m_pServer = pServer; m_LogonId = pLogonId->LogonId; wcscpy(m_Name, pLogonId->WinStationName); m_State = pLogonId->State; m_SortOrder = SortOrder[pLogonId->State]; HANDLE Handle = m_pServer->GetHandle(); CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument(); ULONG Length; PDCONFIG PdConfig; if(WinStationQueryInformation(Handle, m_LogonId, WinStationPd, &PdConfig, sizeof(PDCONFIG), &Length)) { m_SdClass = PdConfig.Create.SdClass; wcscpy(m_PdName, PdConfig.Create.PdName); if(m_SdClass == SdAsync) { CDCONFIG CdConfig; if(WinStationQueryInformation(Handle, m_LogonId, WinStationCd, &CdConfig, sizeof(CDCONFIG), &Length)) { if(CdConfig.CdClass != CdModem) SetDirectAsync(); } } } WDCONFIG WdConfig; if(WinStationQueryInformation(Handle, m_LogonId, WinStationWd, &WdConfig, sizeof(WDCONFIG), &Length)) { wcscpy(m_WdName, WdConfig.WdName); m_pWd = pDoc->FindWdByName(m_WdName); // if(WdConfig.WdFlag & WDF_SHADOW_TARGET) SetCanBeShadowed();
WINSTATIONCLIENT WsClient; if(WinStationQueryInformation(Handle, m_LogonId, WinStationClient, &WsClient, sizeof(WINSTATIONCLIENT), &Length)) { wcscpy(m_ClientName, WsClient.ClientName); wcscpy(m_clientDigProductId, WsClient.clientDigProductId); } } WINSTATIONCONFIG WsConfig; if(WinStationQueryInformation(Handle, m_LogonId, WinStationConfiguration, &WsConfig, sizeof(WINSTATIONCONFIG), &Length)) { wcscpy(m_Comment, WsConfig.Comment);
if(WdConfig.WdFlag & WDF_SHADOW_TARGET) { //
// WHY we have IsDisconnected() then IsConnected() ?
// WHY we don't allow shadowing view only session
//
if( (!((IsDisconnected()) && ((WsConfig.User.Shadow == Shadow_EnableInputNotify) || (WsConfig.User.Shadow == Shadow_EnableNoInputNotify)))) || (IsConnected()) ) { SetCanBeShadowed(); } } } WINSTATIONINFORMATION WsInfo; if(WinStationQueryInformation(Handle, m_LogonId, WinStationInformation, &WsInfo, sizeof(WINSTATIONINFORMATION), &Length)) { // the state may have already changed
m_State = WsInfo.ConnectState; wcscpy(m_UserName, WsInfo.UserName); m_LogonTime = WsInfo.LogonTime; m_LastInputTime = IsActive() ? WsInfo.LastInputTime : WsInfo.DisconnectTime; m_CurrentTime = WsInfo.CurrentTime; // Calculate elapsed time
if((IsActive() || IsDisconnected()) && m_LastInputTime.QuadPart <= m_CurrentTime.QuadPart && m_LastInputTime.QuadPart) { LARGE_INTEGER DiffTime = CalculateDiffTime(m_LastInputTime, m_CurrentTime); ULONG_PTR d_time = ( ULONG_PTR )DiffTime.QuadPart; ELAPSEDTIME IdleTime; // Calculate the days, hours, minutes, seconds since specified time.
IdleTime.days = (USHORT)(d_time / 86400L); // days since
d_time = d_time % 86400L; // seconds => partial day
IdleTime.hours = (USHORT)(d_time / 3600L); // hours since
d_time = d_time % 3600L; // seconds => partial hour
IdleTime.minutes = (USHORT)(d_time / 60L); // minutes since
IdleTime.seconds = (USHORT)(d_time % 60L);// seconds remaining
m_IdleTime = IdleTime; TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH]; ElapsedTimeString( &IdleTime, FALSE, IdleTimeString); } } WINSTATIONCLIENT ClientData; // Get the protocol this WinStation is using
if(WinStationQueryInformation( Handle, m_LogonId, WinStationClient, &ClientData, sizeof(WINSTATIONCLIENT), &Length ) ) { m_ProtocolType = ClientData.ProtocolType; m_EncryptionLevel = ClientData.EncryptionLevel; } // If there is a user, set a flag bit
if(wcslen(m_UserName)) SetHasUser(); else ClearHasUser(); // Remember when we got this information
SetLastUpdateClock(); SetQueriesSuccessful(); // If there is an extension DLL loaded, allow it to add it's own info for this WinStation
LPFNEXWINSTATIONINITPROC InitProc = ((CWinAdminApp*)AfxGetApp())->GetExtWinStationInitProc(); if(InitProc) { m_pExtensionInfo = (*InitProc)(Handle, m_LogonId); if(m_pExtensionInfo) { LPFNEXGETWINSTATIONINFOPROC InfoProc = ((CWinAdminApp*)AfxGetApp())->GetExtGetWinStationInfoProc(); if(InfoProc) { m_pExtWinStationInfo = (*InfoProc)(m_pExtensionInfo); } } } } // end CWinStation::CWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinStation::~CWinStation
//
CWinStation::~CWinStation() { // Remove all of the processes attributed to this WinStation
// from the Server's list
m_pServer->RemoveWinStationProcesses(this); // If there is an extension DLL, let it cleanup anything it added to this WinStation
LPFNEXWINSTATIONCLEANUPPROC CleanupProc = ((CWinAdminApp*)AfxGetApp())->GetExtWinStationCleanupProc(); if(CleanupProc) { (*CleanupProc)(m_pExtensionInfo); } if(m_pExtModuleInfo) { // Get the extension DLL's function to free the module info
LPFNEXFREEWINSTATIONMODULESPROC FreeModulesProc = ((CWinAdminApp*)AfxGetApp())->GetExtFreeWinStationModulesProc(); if(FreeModulesProc) { (*FreeModulesProc)(m_pExtModuleInfo); } else { TRACE0("WAExGetWinStationModules exists without WAExFreeWinStationModules\n"); ASSERT(0); } } } // end CWinStation::~CWinStation
/////////////////////////////////////////////////////////////////////////////
// CWinStation::Update
//
// Updates this WinStation with new data from another CWinStation
//
BOOL CWinStation::Update(CWinStation *pWinStation) { ASSERT(pWinStation); // Check for any information that has changed
BOOL bInfoChanged = FALSE; // Check the State
if(m_State != pWinStation->GetState()) { // If the old state was disconnected, then we want to
// go out and get the module (client) information again
if(m_State == State_Disconnected) ClearAdditionalDone(); m_State = pWinStation->GetState(); // Sort order only changes when state changes
m_SortOrder = pWinStation->GetSortOrder(); bInfoChanged = TRUE; } // Check the UserName
if(wcscmp(m_UserName, pWinStation->GetUserName()) != 0) { SetUserName(pWinStation->GetUserName()); if(pWinStation->HasUser()) SetHasUser(); else ClearHasUser(); bInfoChanged = TRUE; } // Check the SdClass
if(m_SdClass != pWinStation->GetSdClass()) { m_SdClass = pWinStation->GetSdClass(); bInfoChanged = TRUE; } // Check the Comment
if(wcscmp(m_Comment, pWinStation->GetComment()) != 0) { SetComment(pWinStation->GetComment()); bInfoChanged = TRUE; } // Check the WdName
if(wcscmp(m_WdName, pWinStation->GetWdName()) != 0) { SetWdName(pWinStation->GetWdName()); SetWd(pWinStation->GetWd()); bInfoChanged = TRUE; } // Check the Encryption Level
if (GetEncryptionLevel() != pWinStation->GetEncryptionLevel() ) { SetEncryptionLevel(pWinStation->GetEncryptionLevel()); bInfoChanged = TRUE; } // Check the Name
if(wcscmp(m_Name, pWinStation->GetName()) != 0) { SetName(pWinStation->GetName()); bInfoChanged = TRUE; } // Check the Client Name
if(wcscmp(m_ClientName, pWinStation->GetClientName()) != 0) { SetClientName(pWinStation->GetClientName()); bInfoChanged = TRUE; }
if(wcscmp(m_clientDigProductId, pWinStation->GetClientDigProductId()) != 0) { SetClientDigProductId(pWinStation->GetClientDigProductId()); bInfoChanged = TRUE; }
// Always copy the LastInputTime
SetLastInputTime(pWinStation->GetLastInputTime()); // Always copy the CurrentTime
SetCurrentTime(pWinStation->GetCurrentTime()); // Always copy the LogonTime
// (The logon time is not set when we create a CWinStation on the fly)
SetLogonTime(pWinStation->GetLogonTime()); // Always copy the IdleTime
SetIdleTime(pWinStation->GetIdleTime()); // Always copy the Can Shadow flag
if(pWinStation->CanBeShadowed()) SetCanBeShadowed(); // Copy the Extension Info pointer if necessary
if(pWinStation->GetExtensionInfo() && !m_pExtensionInfo) { m_pExtensionInfo = pWinStation->GetExtensionInfo(); pWinStation->SetExtensionInfo(NULL); } // Copy the Extended Info pointer if necessary
if(pWinStation->GetExtendedInfo() && !m_pExtWinStationInfo) { m_pExtWinStationInfo = pWinStation->GetExtendedInfo(); pWinStation->SetExtendedInfo(NULL); } // If this guy hasn't been updated in a while, do it now
if(!bInfoChanged) { clock_t now = clock(); if((now - GetLastUpdateClock()) > 30) bInfoChanged = TRUE; } if(bInfoChanged) { SetChanged(); SetLastUpdateClock(); } return bInfoChanged; } // end CWinStation::Update
/////////////////////////////////////////////////////////////////////////////
// CWinStation::Connect
//
void CWinStation::Connect(BOOL bUser) { TCHAR szPassword[PASSWORD_LENGTH+1]; BOOL bFirstTime = TRUE; DWORD Error; HANDLE hServer = m_pServer->GetHandle(); // Start the connect loop with null password to try first.
szPassword[0] = '\0'; while(1) { if(WinStationConnect(hServer, m_LogonId, LOGONID_CURRENT, szPassword, TRUE)) break; // success - break out of loop
if(((Error = GetLastError()) != ERROR_LOGON_FAILURE) || !bFirstTime ) { //We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_ERR_CONNECT); StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), m_LogonId, Error, tempErrorMessage.GetLength(), 10, IDS_ERR_CONNECT, m_LogonId); } // If a 'logon failure' brought us here, issue password dialog.
// Otherwise, break the connect loop.
if(Error == ERROR_LOGON_FAILURE) { CPasswordDlg CPDlg; CPDlg.SetDialogMode(bUser ? PwdDlg_UserMode : PwdDlg_WinStationMode); if(CPDlg.DoModal() == IDOK ) { lstrcpy(szPassword, CPDlg.GetPassword()); } else { break; // user CANCEL: break connect loop
} } else break; // other error: break connect loop
// the next time through the loop won't be the first
bFirstTime = FALSE; } SecureZeroMemory((PVOID)szPassword , sizeof(szPassword)); return; } // end CWinStation::Connect
/////////////////////////////////////////////////////////////////////////////
// CWinStation::ShowStatus
//
void CWinStation::ShowStatus() { switch(m_SdClass) { case SdNetwork: case SdNasi: new CNetworkStatusDlg(this); break; case SdAsync: new CAsyncStatusDlg(this); break; default: break; } } // end CWinStation::ShowStatus
/////////////////////////////////////////////////////////////////////////////
// CWinStation::Shadow
//
void CWinStation::Shadow() { WINSTATIONCONFIG WSConfig; SHADOWCLASS Shadow; ULONG ReturnLength; DWORD ShadowError; HANDLE hServer = m_pServer->GetHandle(); // Determine the WinStation's shadow state.
if(!WinStationQueryInformation(hServer, m_LogonId, WinStationConfiguration, &WSConfig, sizeof(WINSTATIONCONFIG), &ReturnLength ) ) { // Can't query WinStation configuration; complain and return
return; } Shadow = WSConfig.User.Shadow; // If shadowing is disabled, let the user know and return
if(Shadow == Shadow_Disable ) { DWORD Error = GetLastError();
//We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_ERR_SHADOW_DISABLED); StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), m_LogonId, Error, tempErrorMessage.GetLength(), 10, IDS_ERR_SHADOW_DISABLED, m_LogonId); return; } // If the WinStation is disconnected and shadow notify is 'on',
// let the user know and break out.
if((m_State == State_Disconnected) && ((Shadow == Shadow_EnableInputNotify) || (Shadow == Shadow_EnableNoInputNotify)) ) { DWORD Error = GetLastError();
//We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_ERR_SHADOW_DISCONNECTED_NOTIFY_ON); StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), m_LogonId, Error, tempErrorMessage.GetLength(), 10, IDS_ERR_SHADOW_DISCONNECTED_NOTIFY_ON, m_LogonId); return; } // Display the 'start shadow' dialog for hotkey reminder and
// final 'ok' prior to shadowing.
CShadowStartDlg SSDlg; SSDlg.m_ShadowHotkeyKey = ((CWinAdminApp*)AfxGetApp())->GetShadowHotkeyKey(); SSDlg.m_ShadowHotkeyShift = ((CWinAdminApp*)AfxGetApp())->GetShadowHotkeyShift(); if(SSDlg.DoModal() != IDOK) { return; } // launch UI thread.
DWORD tid; HANDLE hThread = ::CreateThread( NULL , 0 , ( LPTHREAD_START_ROUTINE )Shadow_WarningProc , ( LPVOID )AfxGetInstanceHandle() , 0 , &tid ); ((CWinAdminApp*)AfxGetApp())->SetShadowHotkeyKey(SSDlg.m_ShadowHotkeyKey); ((CWinAdminApp*)AfxGetApp())->SetShadowHotkeyShift(SSDlg.m_ShadowHotkeyShift); // Invoke the shadow DLL.
CWaitCursor Nikki; // allow UI thread to init window
Sleep( 900 ); // Shadow API always connects to local server,
// passing target servername as a parameter.
BOOL bOK = WinStationShadow(SERVERNAME_CURRENT, m_pServer->GetName(), m_LogonId, (BYTE)((CWinAdminApp*)AfxGetApp())->GetShadowHotkeyKey(), (WORD)((CWinAdminApp*)AfxGetApp())->GetShadowHotkeyShift()); if (!bOK) { ShadowError = GetLastError(); } if( g_hwndShadowWarn != NULL ) { OutputDebugString( L"Posting WM_DESTROY to dialog\n"); EndDialog( g_hwndShadowWarn , 0 ); //PostMessage( g_hwndShadowWarn , WM_CLOSEDIALOG , 0 , 0 );
} if( !bOK ) { //We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_ERR_SHADOW); StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), m_LogonId, ShadowError, tempErrorMessage.GetLength(), 10, IDS_ERR_SHADOW, m_LogonId); } CloseHandle( hThread ); } // end CWinStation::Shadow
/////////////////////////////////////////////////////////////////////////////
// CWinStation::SendMessage
//
UINT CWinStation::SendMessage(LPVOID pParam) { ASSERT(pParam); ULONG Response; UINT RetVal = 0; ((CWinAdminApp*)AfxGetApp())->BeginOutstandingThread(); MessageParms *pMsgParms = (MessageParms*)pParam;
// If we are operating on the current selected Item in the tree it's
// possible that the winstation has disappeared by the time we get here
// so we should just gracefully cleanup
if (pMsgParms->bActionOnCurrentSelection) { if (CWinAdminDoc::gm_CurrentSelType != NODE_WINSTATION) { goto Cleanup; } }
HANDLE hServer = pMsgParms->pWinStation->m_pServer->GetHandle(); if(!WinStationSendMessage(hServer, pMsgParms->pWinStation->m_LogonId, pMsgParms->MessageTitle, (wcslen(pMsgParms->MessageTitle)+1)*sizeof(TCHAR), pMsgParms->MessageBody, (wcslen(pMsgParms->MessageBody)+1)*sizeof(TCHAR), MB_OK, 60, &Response, TRUE ) ) { DWORD Error = GetLastError();
//We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_ERR_MESSAGE); StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), pMsgParms->pWinStation->m_LogonId, Error, tempErrorMessage.GetLength(), 10, IDS_ERR_MESSAGE, pMsgParms->pWinStation->m_LogonId); RetVal = 1; } Cleanup: ((CWinAdminApp*)AfxGetApp())->EndOutstandingThread();
delete pMsgParms;
return RetVal; } // end CWinStation::SendMessage
/////////////////////////////////////////////////////////////////////////////
// CWinStation::Disconnect
//
UINT CWinStation::Disconnect(LPVOID pParam) { ASSERT(pParam); UINT RetVal = 0; HANDLE hServer; ((CWinAdminApp*)AfxGetApp())->BeginOutstandingThread();
DisconnectParms *pDisconnectParms = (DisconnectParms*)pParam;
// If we are operating on the current selected Item in the tree it's
// possible that the winstation has disappeared by the time we get here
// so we should just gracefully cleanup
if (pDisconnectParms->bActionOnCurrentSelection) { if (CWinAdminDoc::gm_CurrentSelType != NODE_WINSTATION) { goto Cleanup; } }
hServer = pDisconnectParms->hServer; if(!WinStationDisconnect(hServer, pDisconnectParms->ulLogonId, TRUE)) { DWORD Error = GetLastError();
// We need this to know the length of the error message
// now that StandardErrorMessage requires that
CString tempErrorMessage; tempErrorMessage.LoadString(IDS_ERR_DISCONNECT);
StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), pDisconnectParms->ulLogonId, Error, tempErrorMessage.GetLength(), 10, IDS_ERR_DISCONNECT, pDisconnectParms->ulLogonId); RetVal = 1; }
Cleanup: ((CWinAdminApp*)AfxGetApp())->EndOutstandingThread(); delete pDisconnectParms;
return RetVal; } // end CWinStation::Disconnect
/////////////////////////////////////////////////////////////////////////////
// CWinStation::Reset
//
UINT CWinStation::Reset(LPVOID pParam) { ASSERT(pParam); UINT RetVal = 0; ((CWinAdminApp*)AfxGetApp())->BeginOutstandingThread(); ResetParms *pResetParms = (ResetParms*)pParam; // If we are operating on the current selected Item in the tree it's
// possible that the winstation has disappeared by the time we get here
// so we should just gracefully cleanup
if (pResetParms->bActionOnCurrentSelection) { if (CWinAdminDoc::gm_CurrentSelType != NODE_WINSTATION) { goto Cleanup; } }
HANDLE hServer = pResetParms->pWinStation->m_pServer->GetHandle(); if(!WinStationReset(hServer, pResetParms->pWinStation->m_LogonId, TRUE)) { DWORD Error = GetLastError(); //We need this to know the length of the error message
//now that StandardErrorMessage requires that
CString tempErrorMessage1, tempErrorMessage2; tempErrorMessage1.LoadString(IDS_ERR_RESET); tempErrorMessage2.LoadString(IDS_ERR_USER_LOGOFF);
StandardErrorMessage(AfxGetAppName(), AfxGetMainWnd()->m_hWnd, AfxGetInstanceHandle(), pResetParms->pWinStation->m_LogonId, Error, pResetParms->bReset ? tempErrorMessage1.GetLength() : tempErrorMessage2.GetLength(), 10, pResetParms->bReset ? IDS_ERR_RESET : IDS_ERR_USER_LOGOFF, pResetParms->pWinStation->m_LogonId); RetVal = 1; }
Cleanup: ((CWinAdminApp*)AfxGetApp())->EndOutstandingThread(); delete pParam; return RetVal; } // end CWinStation::Reset
/////////////////////////////////////////////////////////////////////////////
// CWinStation::QueryAdditionalInformation
//
void CWinStation::QueryAdditionalInformation() { ULONG ReturnLength; HANDLE hServer = m_pServer->GetHandle(); WINSTATIONCLIENT ClientData; // Set all the strings to start with a NULL
m_ClientDir[0] = '\0'; m_ModemName[0] = '\0'; m_ClientLicense[0] = '\0'; m_ClientAddress[0] = '\0'; m_Colors[0] = '\0'; // Set all the values to 0
m_ClientBuildNumber = 0; m_ClientProductId = 0; m_HostBuffers = 0; m_ClientBuffers = 0; m_BufferLength = 0; m_ClientSerialNumber = 0; m_VRes = 0; m_HRes = 0; SetAdditionalDone(); if ( WinStationQueryInformation( hServer, m_LogonId, WinStationClient, &ClientData, sizeof(WINSTATIONCLIENT), &ReturnLength ) ) { // Assign string values.
wcscpy(m_ClientDir, ClientData.ClientDirectory); wcscpy(m_ModemName, ClientData.ClientModem); wcscpy(m_ClientLicense, ClientData.ClientLicense); wcscpy(m_ClientAddress, ClientData.ClientAddress); switch ( ClientData.ColorDepth ) { case 0x0001: wcscpy(m_Colors, TEXT("16")); break; case 0x0002: wcscpy(m_Colors, TEXT("256")); break; case 0x0004: wcscpy(m_Colors, TEXT("64K")); break; case 0x0008: wcscpy(m_Colors, TEXT("16M")); break; case 0x0010: wcscpy(m_Colors, TEXT("32M")); break; } // Assign numeric values.
m_ClientBuildNumber = ClientData.ClientBuildNumber; m_ClientProductId = ClientData.ClientProductId; m_HostBuffers = ClientData.OutBufCountHost; m_ClientBuffers = ClientData.OutBufCountClient; m_BufferLength = ClientData.OutBufLength; m_ClientSerialNumber = ClientData.SerialNumber; m_HRes = ClientData.HRes; m_VRes = ClientData.VRes; } // If there is an extension DLL loaded, allow it to add it's own info for this WinStation
LPFNEXWINSTATIONINFOPROC InfoProc = ((CWinAdminApp*)AfxGetApp())->GetExtWinStationInfoProc(); if(InfoProc) { (*InfoProc)(m_pExtensionInfo, m_State); } LPFNEXGETWINSTATIONMODULESPROC ModuleProc = ((CWinAdminApp*)AfxGetApp())->GetExtGetWinStationModulesProc(); if(ModuleProc) { if(m_pExtModuleInfo) { // Get the extension DLL's function to free the module info
LPFNEXFREEWINSTATIONMODULESPROC FreeModulesProc = ((CWinAdminApp*)AfxGetApp())->GetExtFreeWinStationModulesProc(); if(FreeModulesProc) { (*FreeModulesProc)(m_pExtModuleInfo); } else { TRACE0("WAExGetWinStationModules exists without WAExFreeWinStationModules\n"); ASSERT(0); } } m_pExtModuleInfo = (*ModuleProc)(GetExtensionInfo(), &m_NumModules); } } // end CWinStation::QueryAdditionalInformation
//////////////////////////////////////////////////////////////////////////////////////////
//
// CProcess Member Functions
//
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CProcess::CProcess
//
CProcess::CProcess(ULONG PID, ULONG LogonId, CServer *pServer, PSID pSID, CWinStation *pWinStation, TCHAR *ImageName) { ASSERT(pServer); DWORD dwImageNameLen;
m_Flags = PF_CURRENT; m_PID = PID; m_LogonId = LogonId; m_pServer = pServer; m_pWinStation = pWinStation; m_ImageName = NULL; if(PID == 0 && !pSID) { CString sTemp; sTemp.LoadString(IDS_SYSTEM_IDLE_PROCESS);
// allocate memory for Image Name and copy to member variable
dwImageNameLen = sTemp.GetLength(); m_ImageName = (LPTSTR)LocalAlloc(LPTR, (dwImageNameLen + 1) * sizeof(TCHAR)); if (m_ImageName != NULL) { _tcscpy(m_ImageName, sTemp); }
SetSystemProcess(); _tcscpy(m_UserName, TEXT("System")); m_SidCrc = 0; } else { if(pSID) { DWORD SidLength = GetLengthSid(pSID); m_SidCrc = CalculateCrc16((PBYTE)pSID, (USHORT)SidLength); } else m_SidCrc = 0; DetermineProcessUser(pSID);
// allocate memory for Image Name and copy to member variable
dwImageNameLen = _tcslen(ImageName); m_ImageName = (LPTSTR)LocalAlloc(LPTR, (dwImageNameLen + 1) * sizeof(TCHAR)); if (m_ImageName != NULL) { _tcscpy(m_ImageName, ImageName); if(QuerySystemProcess()) SetSystemProcess(); } } } // end CProcess::CProcess
TCHAR *SysProcTable[] = { TEXT("csrss.exe"), TEXT("smss.exe"), TEXT("screg.exe"), TEXT("lsass.exe"), TEXT("spoolss.exe"), TEXT("EventLog.exe"), TEXT("netdde.exe"), TEXT("clipsrv.exe"), TEXT("lmsvcs.exe"), TEXT("MsgSvc.exe"), TEXT("winlogon.exe"), TEXT("NETSTRS.EXE"), TEXT("nddeagnt.exe"), TEXT("wfshell.exe"), TEXT("chgcdm.exe"), TEXT("userinit.exe"), NULL };
/////////////////////////////////////////////////////////////////////////////
// CProcess::~CProcess
//
/////////////////////////////////////////////////////////////////////////////
CProcess::~CProcess() { if (m_ImageName != NULL) { LocalFree(m_ImageName); } }
/////////////////////////////////////////////////////////////////////////////
// CProcess::QuerySystemProcess
//
BOOL CProcess::QuerySystemProcess() { // First: if the user name is 'system' or no image name is present, treat
// as a 'system' process.
if(!lstrcmpi(m_UserName, TEXT("system")) || !(*m_ImageName) ) return TRUE; // Last: if the image name is one of the well known 'system' images,
// treat it as a 'system' process.
for(int i = 0; SysProcTable[i]; i++) if(!lstrcmpi( m_ImageName, SysProcTable[i])) return TRUE; // Not a 'system' process.
return FALSE; } // end CProcess::QuerySystemProcess
/////////////////////////////////////////////////////////////////////////////
// CProcess::DetermineProcessUser
//
void CProcess::DetermineProcessUser(PSID pSid) { CObList *pUserSidList = m_pServer->GetUserSidList(); // Look for the user Sid in the list
POSITION pos = pUserSidList->GetHeadPosition(); while(pos) { CUserSid *pUserSid = (CUserSid*)pUserSidList->GetNext(pos); if(pUserSid->m_SidCrc == m_SidCrc) { wcscpy(m_UserName, pUserSid->m_UserName); return; } } // It wasn't in the list
// Get the user from the Sid and put it in our list
GetUserFromSid(pSid, m_UserName, USERNAME_LENGTH); if (!lstrcmpi(m_UserName,TEXT("system"))) { wcscpy(m_UserName, TEXT("System")); // to make the UI guys happy
} CUserSid *pUserSid = new CUserSid; if(pUserSid == NULL) { return; } pUserSid->m_SidCrc = m_SidCrc;
memset(pUserSid->m_UserName, 0, sizeof(pUserSid->m_UserName)); lstrcpy(pUserSid->m_UserName, m_UserName); pUserSidList->AddTail(pUserSid); } // end CProcess::DetermineProcessUser
/////////////////////////////////////////////////////////////////////////////
// CProcess::Update
//
BOOL CProcess::Update(CProcess *pProcess) { ASSERT(pProcess); BOOL bChanged = FALSE; // Check the WinStation
if(m_pWinStation != pProcess->GetWinStation()) { m_pWinStation = pProcess->GetWinStation(); bChanged = TRUE; } else { if(m_pWinStation->IsChanged()) { bChanged = TRUE; } } if(bChanged) SetChanged(); return bChanged; } // end CProcess::Update
//////////////////////////////////////////////////////////////////////////////////////////
//
// CLicense Member Functions
//
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CLicense::CLicense
//
CLicense::CLicense(CServer *pServer, ExtLicenseInfo *pLicenseInfo) { ASSERT(pServer); ASSERT(pLicenseInfo); m_pServer = pServer; m_Class = pLicenseInfo->Class; m_PoolLicenseCount = pLicenseInfo->PoolLicenseCount; m_LicenseCount = pLicenseInfo->LicenseCount; m_Flags = pLicenseInfo->Flags; wcscpy(m_RegSerialNumber, pLicenseInfo->RegSerialNumber); wcscpy(m_LicenseNumber, pLicenseInfo->LicenseNumber); wcscpy(m_Description, pLicenseInfo->Description); // Figure out the pooling count
if(m_Flags & ELF_POOLING) m_PoolCount = m_PoolLicenseCount; else m_PoolCount = 0xFFFFFFFF; } // end CLicense::CLicense
//////////////////////////////////////////////////////////////////////////////////////////
//
// CWd Member Functions
//
//////////////////////////////////////////////////////////////////////////////////////////
static CHAR szEncryptionLevels[] = "ExtEncryptionLevels";
/////////////////////////////////////////////////////////////////////////////
// CWd::CWd
//
CWd::CWd(PWDCONFIG2 pWdConfig, PWDNAME pRegistryName) { m_pEncryptionLevels = NULL; m_NumEncryptionLevels = 0L; wcscpy(m_WdName, pWdConfig->Wd.WdName); wcscpy(m_RegistryName, pRegistryName); // Load the extension DLL for this WD
m_hExtensionDLL = ::LoadLibrary(pWdConfig->Wd.CfgDLL); if(m_hExtensionDLL) { // Get the entry points
m_lpfnExtEncryptionLevels = (LPFNEXTENCRYPTIONLEVELSPROC)::GetProcAddress(m_hExtensionDLL, szEncryptionLevels); if(m_lpfnExtEncryptionLevels) { m_NumEncryptionLevels = (*m_lpfnExtEncryptionLevels)(NULL, &m_pEncryptionLevels); } } } // end CWd::CWd
/////////////////////////////////////////////////////////////////////////////
// CWd::~CWd
//
CWd::~CWd() { if(m_hExtensionDLL) { ::FreeLibrary(m_hExtensionDLL); } } // end CWd::~CWd
/////////////////////////////////////////////////////////////////////////////
// CWd::GetEncryptionLevelString
//
BOOL CWd::GetEncryptionLevelString(DWORD Value, CString *pString) { if(!m_NumEncryptionLevels) return FALSE; for(LONG i = 0; i < m_NumEncryptionLevels; i++) { // Is this the right encryption level
if(Value == m_pEncryptionLevels[i].RegistryValue) { TCHAR estring[128]; if(::LoadString(m_hExtensionDLL, m_pEncryptionLevels[i].StringID, estring, 127)) { pString->Format(TEXT("%s"), estring); return TRUE; } return FALSE; } } return FALSE; } // end CWd::GetEncryptionLevelString
//------------------------------------------------
DWORD Shadow_WarningProc( LPVOID param ) { HINSTANCE hInst = ( HINSTANCE )param; OutputDebugString( L"Shadow_WarningProc called\n" ); DialogBox( hInst , MAKEINTRESOURCE( IDD_DIALOG_SHADOWWARN ) , NULL , ShadowWarn_WndProc ); OutputDebugString( L"Shadow_WarningProc exiting thread\n" ); ExitThread( 0 ); return 0; }
//------------------------------------------------
INT_PTR CALLBACK ShadowWarn_WndProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp ) { switch( msg ) { case WM_INITDIALOG: g_hwndShadowWarn = hwnd; OutputDebugString( L"WM_INITDIALOG -- in ShadowWarn_WndProc\n" ); CenterDlg( GetDesktopWindow( ) , hwnd ); break; case WM_CLOSE: EndDialog( hwnd , 0 ); break; } return FALSE; }
void CenterDlg(HWND hwndToCenterOn , HWND hDlg ) { RECT rc, rcwk, rcToCenterOn; SetRect( &rcToCenterOn , 0 , 0 , GetSystemMetrics(SM_CXSCREEN) , GetSystemMetrics( SM_CYSCREEN ) ); if (hwndToCenterOn != NULL) { ::GetWindowRect(hwndToCenterOn, &rcToCenterOn); } ::GetWindowRect( hDlg , &rc); UINT uiWidth = rc.right - rc.left; UINT uiHeight = rc.bottom - rc.top; rc.left = (rcToCenterOn.left + rcToCenterOn.right) / 2 - ( rc.right - rc.left ) / 2; rc.top = (rcToCenterOn.top + rcToCenterOn.bottom) / 2 - ( rc.bottom - rc.top ) / 2; //ensure the dialog always with the work area
if(SystemParametersInfo(SPI_GETWORKAREA, 0, &rcwk, 0)) { UINT wkWidth = rcwk.right - rcwk.left; UINT wkHeight = rcwk.bottom - rcwk.top; if(rc.left + uiWidth > wkWidth) //right cut
rc.left = wkWidth - uiWidth; if(rc.top + uiHeight > wkHeight) //bottom cut
rc.top = wkHeight - uiHeight; if(rc.left < rcwk.left) //left cut
rc.left += rcwk.left - rc.left; if(rc.top < rcwk.top) //top cut
rc.top += rcwk.top - rc.top; } ::SetWindowPos( hDlg, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_DRAWFRAME); }
|