|
|
//Copyright (c) 1998 - 1999 Microsoft Corporation
/*******************************************************************************
* * appsvdoc.cpp * * implementation of the CAppServerDoc class * * copyright notice: Copyright 1994, Citrix Systems Inc. * * $Author: donm $ Butch Davis * * $Log: N:\nt\private\utils\citrix\winutils\tscfg\VCS\appsvdoc.cpp $ * * Rev 1.54 18 Apr 1998 15:31:08 donm * Added capability bits * * Rev 1.53 14 Feb 1998 11:23:04 donm * fixed memory leak by avoiding CDocManager::OpenDocumentFile * * Rev 1.52 31 Dec 1997 09:13:50 donm * uninitialized variable in RegistryDelete * * Rev 1.51 10 Dec 1997 15:59:14 donm * added ability to have extension DLLs * * Rev 1.50 19 Jun 1997 19:21:08 kurtp * update * * Rev 1.49 25 Mar 1997 08:59:46 butchd * update * * Rev 1.48 18 Mar 1997 15:51:18 butchd * ignore system console registry entry * * Rev 1.47 10 Mar 1997 16:58:26 butchd * update * * Rev 1.46 04 Mar 1997 09:46:46 butchd * update * * Rev 1.45 04 Mar 1997 08:35:12 butchd * update * * Rev 1.44 28 Feb 1997 17:59:22 butchd * update * * Rev 1.43 11 Dec 1996 09:50:18 butchd * update * * Rev 1.42 24 Sep 1996 16:21:18 butchd * update * *******************************************************************************/
/*
* include files */ #include "stdafx.h"
#include "wincfg.h"
#include "security.h"
#include "appsvdoc.h"
#include "rowview.h"
#include "appsvvw.h"
#include "ewsdlg.h"
#include <string.h>
#include <hydra\regapi.h> // for WIN_ENABLEWINSTATION registry entry name
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
extern CWincfgApp *pApp; extern "C" LPCTSTR WinUtilsAppName; extern "C" HWND WinUtilsAppWindow; extern "C" HINSTANCE WinUtilsAppInstance;
PTERMLOBJECT GetWdListObject( PWDNAME pWdName);
/*
* Global command line variables. */
////////////////////////////////////////////////////////////////////////////////
// CWinStationListObjectHint implemetation / construction
IMPLEMENT_DYNAMIC(CWinStationListObjectHint, CObject)
CWinStationListObjectHint::CWinStationListObjectHint() { }
////////////////////////////////////////////////////////////////////////////////
// CAppServerDoc implementation / construction, destruction
IMPLEMENT_SERIAL(CAppServerDoc, CDocument, 0 /*schema*/)
/*******************************************************************************
* * CAppServerDoc - CAppServerDoc constructor * * ENTRY: * EXIT: * ******************************************************************************/
CAppServerDoc::CAppServerDoc() : m_bReadOnly(FALSE), m_pSecurityDescriptor(NULL) { } // end CAppServerDoc::CAppServerDoc
/*******************************************************************************
* * ~CAppServerDoc - CAppServerDoc destructor * * ENTRY: * EXIT: * ******************************************************************************/
CAppServerDoc::~CAppServerDoc() { /*
* Free up all WSL objects currently in use. */ DeleteWSLContents();
} // end CAppServerDoc::~CAppServerDoc
////////////////////////////////////////////////////////////////////////////////
// CAppServerDoc class overrides
/*******************************************************************************
* * OnOpenDocument - CAppServerDoc member function: CDocument class override * * Reads the specified AppServer's registry and initializes the * 'document' contents. * * ENTRY: * pszPathName (input) * Name of the AppServer to access. * * EXIT: * TRUE - sucessful initialization of 'document'. * FALSE - 'document' was not properly initialized. * ******************************************************************************/
BOOL CAppServerDoc::OnNewDocument( /*LPCTSTR pszPathName*/ ) { POSITION pos;
/*
* If this user doesn't have ALL access to the WinStation registry (ie, not * an admin), set the 'admin' flag to FALSE and 'read only' flag to TRUE * to only display the user's current WinStation in the WinStation list; * otherwise set 'admin' flag to TRUE to allow all WinStations to be * displayed, with the 'read only' state being determined from the previous * AppServer check, above. */ if ( RegWinStationAccessCheck(SERVERNAME_CURRENT, KEY_ALL_ACCESS) ) {
m_bAdmin = FALSE; m_bReadOnly = TRUE;
} else {
m_bAdmin = TRUE; }
/*
* Obtain the user's current WinStation information. */ if ( !QueryCurrentWinStation( pApp->m_CurrentWinStation, pApp->m_CurrentUserName, &(pApp->m_CurrentLogonId), &(pApp->m_CurrentWSFlags) ) ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_CURRENT, GetLastError(), IDP_ERROR_QUERYCURRENTWINSTATION )) return(FALSE); }
/*
* Load the WSL with registry information for this AppServer. */ if ( !LoadWSL(NULL/*pszPathName*/) ) return(FALSE);
/*
* Reset the view for this document. */ ((CAppServerView *)GetNextView( pos = GetFirstViewPosition() ))-> ResetView( TRUE );
return ( TRUE );
} // end CAppServerDoc::OnOpenDocument
/*******************************************************************************
* * SetTitle - CAppServerDoc member function: override * * Override default to set our title the way that we want. * * ENTRY: * lpszTitle (input) * Title to set (this is ignored). * EXIT: * ******************************************************************************/
void CAppServerDoc::SetTitle( LPCTSTR lpszTitle ) { /*
* Set our document's title, including the READONLY (User Mode) * string if needed. */ if ( m_bReadOnly ) { CString ReadOnly; ReadOnly.LoadString( IDS_READONLY ); CString sz = pApp->m_szCurrentAppServer + ReadOnly; CDocument::SetTitle(sz);
} else CDocument::SetTitle(pApp->m_szCurrentAppServer);
} // end CAppServerDoc::SetTitle
////////////////////////////////////////////////////////////////////////////////
// CAppServerDoc public operations
/*******************************************************************************
* * IsExitAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the application can be exited, based on whether * or not there are operations pending. * * ENTRY: * * EXIT: * TRUE - no operations are pending: the application can be exited. * FALSE - operations are pending: the application cannot be exited. * ******************************************************************************/
BOOL CAppServerDoc::IsExitAllowed() { return (TRUE);
} // end CAppServerDoc::IsExitAllowed
/*******************************************************************************
* * IsAddAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the WSLObject associated with the specified * list index can be referenced for adding a new WinStation. * * ENTRY: * * EXIT: * (BOOL) TRUE if the WSLObject can be referenced for add; FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::IsAddAllowed( int nIndex ) { /*
* If this document is 'read only' then add is not allowed. * Otherwise, it's OK. */ if ( m_bReadOnly ) return(FALSE); else return(TRUE);
} // end CAppServerDoc::IsAddAllowed
/*******************************************************************************
* * IsCopyAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the WSLObject associated with the specified * list index can be copied. * * ENTRY: * * EXIT: * (BOOL) TRUE if the WSLObject can be copied; FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::IsCopyAllowed( int nIndex ) { PWSLOBJECT pWSLObject;
/*
* If this document is 'read only' or no items yet, * then copy is not allowed. */ if ( m_bReadOnly || !(pWSLObject = GetWSLObject(nIndex)) ) return(FALSE);
/*
* If this WinStation is the main CONSOLE, or is not a single instance * type, we can't copy. */ if ( !lstrcmpi(pWSLObject->m_WinStationName, pApp->m_szSystemConsole) || !(pWSLObject->m_Flags & WSL_SINGLE_INST) ) return(FALSE);
/*
* The copy is allowed. */ return(TRUE);
} // end CAppServerDoc::IsCopyAllowed
/*******************************************************************************
* * IsRenameAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the WSLObject associated with the specified * list index can be renamed. * * ENTRY: * * EXIT: * (BOOL) TRUE if the WSLObject can be renamed; FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::IsRenameAllowed( int nIndex ) { PWSLOBJECT pWSLObject;
/*
* If this document is 'read only' or no items yet, * then rename is not allowed. */ if ( m_bReadOnly || !(pWSLObject = GetWSLObject(nIndex)) ) return(FALSE);
/*
* If this WinStation is the main CONSOLE, we can't rename. */ if ( !lstrcmpi( pWSLObject->m_WinStationName, pApp->m_szSystemConsole ) ) return(FALSE);
/*
* The rename is allowed. */ return(TRUE);
} // end CAppServerDoc::IsRenameAllowed
/*******************************************************************************
* * IsDeleteAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the WSLObject associated with the specified * list index can be deleted. * * ENTRY: * * EXIT: * (BOOL) TRUE if the WSLObject can be deleted; FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::IsDeleteAllowed( int nIndex ) { PWSLOBJECT pWSLObject;
/*
* If this document is 'read only' or no items yet, * then delete is not allowed. */ if ( m_bReadOnly || !(pWSLObject = GetWSLObject(nIndex)) ) return(FALSE);
/*
* If this WinStation is the main CONSOLE, we can't delete. */ if ( !lstrcmpi( pWSLObject->m_WinStationName, pApp->m_szSystemConsole ) ) return(FALSE);
/*
* The delete is allowed. */ return(TRUE);
} // end CAppServerDoc::IsDeleteAllowed
/*******************************************************************************
* * IsEditAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the WSLObject associated with the specified * list index can be edited. * * ENTRY: * * EXIT: * (BOOL) TRUE if the WSLObject can be edited; FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::IsEditAllowed( int nIndex ) { /*
* If no items yet, then edit is not allowed. * Otherwise, it's OK. */ if ( !GetWSLObject(nIndex) ) return(FALSE); else return(TRUE);
} // end CAppServerDoc::IsEditAllowed
/*******************************************************************************
* * IsEnableAllowed - CAppServerDoc member function: public operation * * Indicate whether or not the WinStation(s) associated with the specified * WSLObject can be enabled/disabled. * * ENTRY: * bEnable (input) * TRUE: check for enable allowed; FALSE: check for disable allowed. * EXIT: * (BOOL) TRUE if the WinStation(s) can be enabled/disabled; * FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::IsEnableAllowed( int nIndex, BOOL bEnable ) { PWSLOBJECT pWSLObject;
/*
* If this document is 'read only' no items yet, * then enable/disable is not allowed. */ if ( m_bReadOnly || !(pWSLObject = GetWSLObject(nIndex)) ) return(FALSE);
/*
* If this WinStation is the main CONSOLE, we can't enable/disable. */ if ( !lstrcmpi( pWSLObject->m_WinStationName, pApp->m_szSystemConsole ) ) return(FALSE);
/*
* Make sure that the WSL is 'in sync' with the registry. Return * 'enable/disable not allowed' if error. */ if ( !RefreshWSLObjectState( nIndex, pWSLObject ) ) return(FALSE);
/*
* If this WSLObject indicates that the WinStation(s) are already enabled * and enable allow is requested, or WSLObject indicates that the * WinStation(s) are already disabled and disable allow is requested, * return FALSE (can't enable/disable). */ if ( (bEnable && (pWSLObject->m_Flags & WSL_ENABLED)) || (!bEnable && !(pWSLObject->m_Flags & WSL_ENABLED)) ) return(FALSE);
/*
* The enable/disable is allowed. */ return(TRUE);
} // end CAppServerDoc::IsEnableAllowed
/*******************************************************************************
* * GetWSLCount - CAppServerDoc member function: public operation * * Return the number of WinStationList elements defined in this document. * * ENTRY: * * EXIT: * (int) number of WinStationsList elements present in this document. * ******************************************************************************/
int CAppServerDoc::GetWSLCount() { return( m_WinStationList.GetCount() );
} // end CAppServerDoc::GetWSLCount
/*******************************************************************************
* * GetWSLObject - CAppServerDoc member function: public operation * * Retrieves the WinStation object from the WinStationObjectList that * resides at the specified index. * * ENTRY: * nIndex (input) * WinStationObjectList index of the WinStation to retrieve. * * EXIT: * PWLSOBJECT - pointer to WinStationListObject for the indexed * WinStation. NULL if list is empty. * ******************************************************************************/
PWSLOBJECT CAppServerDoc::GetWSLObject( int nIndex ) { if ( !GetWSLCount() ) return(NULL); else return ( (PWSLOBJECT)m_WinStationList.GetAt( m_WinStationList.FindIndex( nIndex )) );
} // end CAppServerDoc::GetWSLObject
/*******************************************************************************
* * GetWSLIndex - CAppServerDoc member function: public operation * * Retrieves the WinStation List index of WinStation list object that * matches the specified WSName. * * ENTRY: * pWSName (input) * Points to WINSTATIONNAME to compare with list objects. * * EXIT: * int - Index of the specified WSL object in the list. * -1 if an object containing the specified WSName was not found. * ******************************************************************************/
int CAppServerDoc::GetWSLIndex( PWINSTATIONNAME pWSName ) { POSITION pos; int nIndex = 0;
/*
* Traverse the WinStationList. */ for ( pos = m_WinStationList.GetHeadPosition(); pos != NULL; nIndex++ ) {
PWSLOBJECT pObject = (PWSLOBJECT)m_WinStationList.GetNext(pos);
/*
* If this is the specified WSL object, return the current index. */ if ( !lstrcmpi(pObject->m_WinStationName, pWSName) ) return(nIndex); } /*
* WSLObject not found in the list. */ return(-1);
} // end CAppServerDoc::GetWSLIndex
/*******************************************************************************
* * GetWSLObjectNetworkMatch - CAppServerDoc member function: public operation * * Retrieves the WinStation list object (if any) from the WinStationList * that contains the specified PdName, WdName, and LanAdapter. * * ENTRY: * PdName (input) * PdName to compare. * WdName (input) * WdName to compare. * LanAdapter (input) * LanAdapter # to compare. * EXIT: * PWLSOBJECT - pointer to WinStationList object if the PdName, WdName, * and LanAdapter all matched an existing WSL entry. * NULL if no match was found. * ******************************************************************************/
PWSLOBJECT CAppServerDoc::GetWSLObjectNetworkMatch( PDNAME PdName, WDNAME WdName, ULONG LanAdapter ) { POSITION pos;
/*
* Traverse the WinStationList. */ for ( pos = m_WinStationList.GetHeadPosition(); pos != NULL; ) {
PWSLOBJECT pObject = (PWSLOBJECT)m_WinStationList.GetNext(pos);
/*
* If PdName, WdName, and LanAdapter fields match, return this * PWSLOBJECT. */ if ( !lstrcmp( pObject->m_PdName, PdName ) && !lstrcmp( pObject->m_WdName, WdName ) && (pObject->m_LanAdapter == LanAdapter) ) return(pObject); } /*
* No match found. */ return(NULL);
} // end CAppServerDoc::GetWSLObjectNetworkMatch
/*******************************************************************************
* * IsAsyncDeviceAvailable - CAppServerDoc member function: public operation * * Determines if the specified Async device is available for use in * configuring a new WinStation. Availability in this context is * determined by whether or not the device is already configured for * use in an Async WinStation. * * ENTRY: * pDeviceName (input) * Points to the Async device name (NOT decorated) to check for * availablility. * pWSName (input) * Points to WINSTATIONNAME of current WinStation being edited. * * EXIT: * TRUE if the Async device is available for use; FALSE if another * WinStation is already configured to use it. * ******************************************************************************/
BOOL CAppServerDoc::IsAsyncDeviceAvailable( LPCTSTR pDeviceName, PWINSTATIONNAME pWSName ) { POSITION pos; ASYNCCONFIG AsyncConfig;
/*
* Traverse the WinStationList. */ for ( pos = m_WinStationList.GetHeadPosition(); pos != NULL; ) {
PWSLOBJECT pObject = (PWSLOBJECT)m_WinStationList.GetNext(pos);
/*
* If this is an async WinStation, the device is the same as the * one we're checking, but this is not the current WinStation being * edited, return FALSE. */ if ( pObject->m_SdClass == SdAsync ) {
ParseDecoratedAsyncDeviceName( pObject->m_DeviceName, &AsyncConfig );
if ( !lstrcmpi(AsyncConfig.DeviceName, pDeviceName) && lstrcmpi(pWSName, pObject->m_WinStationName) ) return(FALSE); } } /*
* The Async device is not configured in any Async WinStations. */ return(TRUE);
} // end CAppServerDoc::IsAsyncDeviceAvailable
/*******************************************************************************
* * IsOemTdDeviceAvailable - CAppServerDoc member function: public operation * * Determines if the specified OEM Transport device is available for use * in configuring a new WinStation. Availability in this context is * determined by whether or not the device is already configured for * use in a WinStation for the Oem Td. * * ENTRY: * pDeviceName (input) * Points to device name to check against other WinStations of * the specified OEM Transport. * pPdName (input) * Points to PDNAME of the OEM Transport. * pWSName (input) * Points to WINSTATIONNAME of current WinStation being edited. * * EXIT: * TRUE if the OEM Transport device is available for use; FALSE if another * WinStation of the specified OEM Transport is already configured to * use it. * ******************************************************************************/
BOOL CAppServerDoc::IsOemTdDeviceAvailable( LPCTSTR pDeviceName, PPDNAME pPdName, PWINSTATIONNAME pWSName ) { POSITION pos;
/*
* Traverse the WinStationList. */ for ( pos = m_WinStationList.GetHeadPosition(); pos != NULL; ) {
PWSLOBJECT pObject = (PWSLOBJECT)m_WinStationList.GetNext(pos);
/*
* If this is a OEM Transport WinStation of the specified OEM Transport, * the device is the same as the one we're checking, but this is not the * current WinStation being edited, return FALSE. */ if ( (pObject->m_SdClass == SdOemTransport) && !lstrcmpi(pObject->m_PdName, pPdName) && !lstrcmpi(pObject->m_DeviceName, pDeviceName) && lstrcmpi(pWSName, pObject->m_WinStationName) ) {
return(FALSE); } } /*
* The OEM Transport device is not configured in any current WinStations * of the same OEM Transport. */ return(TRUE);
} // end CAppServerDoc::IsOemTdDeviceAvailable
/*******************************************************************************
* * IsWSNameUnique - CAppServerDoc member function: public operation * * Determine if the entered WinStation name is unique. * * ENTRY: * pWinStationName (input) * Points to WINSTATIONNAME to check for uniqueness. * * EXIT: * TRUE if the specified WinStation name is unique; FALSE if not. * ******************************************************************************/
BOOL CAppServerDoc::IsWSNameUnique( PWINSTATIONNAME pWinStationName ) { POSITION pos; WINSTATIONNAME WSRoot; PWINSTATIONNAME pWSRoot;
/*
* Traverse the WinStationList. */ for ( pos = m_WinStationList.GetHeadPosition(); pos != NULL; ) {
PWSLOBJECT pObject = (PWSLOBJECT)m_WinStationList.GetNext(pos);
/*
* Make sure that we only compare the 'root' names. */ lstrcpy(WSRoot, pObject->m_WinStationName); pWSRoot = lstrtok(WSRoot, TEXT("#"));
/*
* If the roots match, return FALSE. */ if ( !lstrcmpi(pWinStationName, pWSRoot) ) return(FALSE); } /*
* WinStation name is unique. */ return(TRUE);
} // end CAppServerDoc::IsWSNameUnique()
/*******************************************************************************
* * AddWinStation - CAppServerDoc member function: public operation * * Add a new WinStation. * * ENTRY: * WSLIndex (input) * WSL index of the currently selected WinStation, to provide some * defaults for the new WinStation. * EXIT: * (int) WSL index of the added WinStation's list item; -1 if error. * ******************************************************************************/
int CAppServerDoc::AddWinStation(int WSLIndex) { LONG Status; int nIndex = -1; CEditWinStationDlg EWSDlg(this); WINSTATIONNAME WSName; PWSLOBJECT pWSLObject; LPCTSTR pszFailedCall = NULL;
/*
* Zero out the WinStation name and config structure. */ memset(WSName, 0, sizeof(WSName)); memset(&EWSDlg.m_WSConfig, 0, sizeof(WINSTATIONCONFIG2));
/*
* Get current WinStation object to anticipate defaults for the new * WinStation and assure that the WSL is 'in sync' with the registry. */ if ( !RefreshWSLObjectState( WSLIndex, pWSLObject = GetWSLObject(WSLIndex)) ) goto BadRefreshWSLObjectState;
/*
* Set the config structure's Pd name field to allow Edit * dialog to form default config structure contents. */ EWSDlg.m_WSConfig.Create.fEnableWinStation = 1; if ( pWSLObject ) { EWSDlg.m_WSConfig.Pd[0].Create.SdClass = pWSLObject->m_SdClass; lstrcpy( EWSDlg.m_WSConfig.Pd[0].Create.PdName, pWSLObject->m_PdName ); }
/*
* Initialize the additional dialog member variables. */ EWSDlg.m_pWSName = WSName; EWSDlg.m_DlgMode = EWSDlgAdd; EWSDlg.m_pExtObject = NULL;
/*
* Invoke the dialog. */ if ( EWSDlg.DoModal() == IDOK ) {
CWaitCursor wait;
/*
* Add a new WSLObject to the WSL. */ if ( (nIndex = InsertInWSL( WSName, &EWSDlg.m_WSConfig, EWSDlg.m_pExtObject, &pWSLObject )) == -1 ) goto BadInsertInWSL;
/*
* Fetch the default WinStation security descriptor. */ if ( (Status = GetDefaultWinStationSecurity(&m_pSecurityDescriptor)) != ERROR_SUCCESS ) {
pszFailedCall = pApp->m_pszGetDefaultWinStationSecurity; goto BadGetDefaultWinStationSecurity; }
/*
* Create the registry entry. */ if((Status = RegistryCreate(WSName, TRUE, &EWSDlg.m_WSConfig, pWSLObject->m_WdName, pWSLObject->m_pExtObject))) {
pszFailedCall = pApp->m_pszRegWinStationCreate; goto BadRegCreate; }
/*
* Set the WinStation security in registry. */ if ( m_pSecurityDescriptor && (Status = RegWinStationSetSecurity( SERVERNAME_CURRENT, WSName, m_pSecurityDescriptor, GetSecurityDescriptorLength(m_pSecurityDescriptor) )) ) {
pszFailedCall = pApp->m_pszRegWinStationSetSecurity; goto BadRegSetSecurity; }
/*
* If we're not 'registry only', tell Session Manager * to re-read registry. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) {
_WinStationReadRegistry(SERVERNAME_CURRENT);
/*
* If this is a modem winstation and it's enabled, * issue the 'must reboot' message and flag the * winstation as 'must reboot'. */ if ( *EWSDlg.m_WSConfig.Pd[0].Params.Async.ModemName && EWSDlg.m_WSConfig.Create.fEnableWinStation ) {
QuestionMessage( MB_OK | MB_ICONEXCLAMATION, IDP_NOTICE_REBOOTFORMODEM_ADD, WSName ); pWSLObject->m_Flags |= WSL_MUST_REBOOT; } } #endif // WINSTA
/*
* A new WSLObject was added: update the entire view. */ UpdateAllViews(NULL, 0, NULL);
/*
* Return the new WSLObject's index. */ return(nIndex);
} else { /*
* User canceled the Add; just return the previously given index. */ DeleteExtensionObject(EWSDlg.m_pExtObject, EWSDlg.m_WSConfig.Wd.WdName); return(WSLIndex); }
/*==============================================================================
* Error returns *============================================================================*/ BadRegSetSecurity: RegWinStationDelete( SERVERNAME_CURRENT, WSName ); BadRegCreate: BadGetDefaultWinStationSecurity: BadInsertInWSL: BadRefreshWSLObjectState: if ( nIndex != -1 ) RemoveFromWSL(nIndex);
if ( pszFailedCall ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_ADDWINSTATION, WSName, pszFailedCall )) } return(-1);
} // end CAppServerDoc::AddWinStation
/*******************************************************************************
* * CopyWinStation - CAppServerDoc member function: public operation * * Copy a given WinStation into a new one. * * ENTRY: * WSLIndex (input) * WSL index of the currently selected WinStation, to provide most * defaults for the new WinStation. * EXIT: * (int) WSL index of the added WinStation's list item; -1 if error. * ******************************************************************************/
int CAppServerDoc::CopyWinStation(int WSLIndex) { LONG Status; ULONG Length; int nIndex = -1; PWSLOBJECT pWSLObject; WINSTATIONNAME WSName; WINSTATIONNAME OriginalWSName; CEditWinStationDlg EWSDlg(this); LPCTSTR pszFailedCall = NULL; /*
* Get current WinStation object to obtain defaults for the new * WinStation and assure that the WSL is 'in sync' with the registry. */ if ( !RefreshWSLObjectState( WSLIndex, pWSLObject = GetWSLObject(WSLIndex)) ) goto BadRefreshWSLObjectState;
lstrcpy( WSName, pWSLObject->m_WinStationName );
/*
* Get the WinStation's config structure and initialize the WSName * array. */
if((Status = RegistryQuery( pWSLObject->m_WinStationName, &EWSDlg.m_WSConfig, pWSLObject->m_WdName, &EWSDlg.m_pExtObject))) {
pszFailedCall = pApp->m_pszRegWinStationQuery; goto BadRegWinStationQuery; } lstrcpy( OriginalWSName, pWSLObject->m_WinStationName );
/*
* If this is an Async WinStation class, null the DeviceName field, since * the device used by an Async WinStation must be unique. */ if ( pWSLObject->m_SdClass == SdAsync ) *(EWSDlg.m_WSConfig.Pd[0].Params.Async.DeviceName) = TEXT('\0');
/*
* Initialize dialog variables and invoke the Edit WinStation dialog * in it's 'copy' mode. */ EWSDlg.m_pWSName = WSName; EWSDlg.m_DlgMode = EWSDlgCopy;
/*
* Invoke the dialog. */ if ( EWSDlg.DoModal() == IDOK ) {
CWaitCursor wait;
/*
* Add a new WSLObject to the WSL. */ if ( (nIndex = InsertInWSL( WSName, &EWSDlg.m_WSConfig, EWSDlg.m_pExtObject, &pWSLObject )) == -1 ) goto BadInsertInWSL;
/*
* Fetch the original WinStation's security descriptor. */ if ( (Status = GetWinStationSecurity( OriginalWSName, &m_pSecurityDescriptor)) != ERROR_SUCCESS ) {
pszFailedCall = pApp->m_pszGetWinStationSecurity; goto BadGetWinStationSecurity; }
/*
* Create the registry entry. */ if((Status = RegistryCreate( WSName, TRUE, &EWSDlg.m_WSConfig, EWSDlg.m_WSConfig.Wd.WdName, EWSDlg.m_pExtObject)) ) {
pszFailedCall = pApp->m_pszRegWinStationCreate; goto BadRegCreate; }
/*
* Set the WinStation security in registry. */ if ( m_pSecurityDescriptor && (Status = RegWinStationSetSecurity( SERVERNAME_CURRENT, WSName, m_pSecurityDescriptor, GetSecurityDescriptorLength(m_pSecurityDescriptor) )) ) {
pszFailedCall = pApp->m_pszRegWinStationSetSecurity; goto BadRegSetSecurity; }
/*
* If we're not 'registry only', tell Session Manager * to re-read registry. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) {
_WinStationReadRegistry(SERVERNAME_CURRENT);
/*
* If this is a modem winstation and it's enabled, * issue the 'must reboot' message and flag the * winstation as 'must reboot'. */ if ( *EWSDlg.m_WSConfig.Pd[0].Params.Async.ModemName && EWSDlg.m_WSConfig.Create.fEnableWinStation ) {
QuestionMessage( MB_OK | MB_ICONEXCLAMATION, IDP_NOTICE_REBOOTFORMODEM_ADD, WSName ); pWSLObject->m_Flags |= WSL_MUST_REBOOT; } } #endif // WINSTA
/*
* A new WSLObject was added: update the entire view. */ UpdateAllViews(NULL, 0, NULL);
/*
* Return the new WSLObject's index. */ return(nIndex);
} else { /*
* User canceled the Copy; just return the previously given index. */ DeleteExtensionObject(EWSDlg.m_pExtObject, EWSDlg.m_WSConfig.Wd.WdName);
return(WSLIndex); }
/*==============================================================================
* Error returns *============================================================================*/ BadRegSetSecurity: RegWinStationDelete( SERVERNAME_CURRENT, WSName ); BadRegCreate: BadGetWinStationSecurity: BadInsertInWSL: BadRegWinStationQuery: BadRefreshWSLObjectState: if ( nIndex != -1 ) RemoveFromWSL(nIndex);
if ( pszFailedCall ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_COPYWINSTATION, WSName, pszFailedCall )) } return(-1);
} // end CAppServerDoc::CopyWinStation
/*******************************************************************************
* * RenameWinStation - CAppServerDoc member function: public operation * * Rename a WinStation. * * ENTRY: * WSLIndex (input) * WSL index of the WinStation to rename. * EXIT: * (int) WSL index of the renamed WinStation's list item; -1 if error. * ******************************************************************************/
int CAppServerDoc::RenameWinStation(int WSLIndex) { LONG Status; ULONG Length; int nIndex = -1; CEditWinStationDlg EWSDlg(this); PWSLOBJECT pOldWSLObject, pNewWSLObject; WINSTATIONNAME OldWSName, NewWSName; LPCTSTR pszFailedCall = NULL; void *pExtObject = NULL;
/*
* Get current WinStation object and assure that the WSL is 'in sync' * with the registry. */ if ( !RefreshWSLObjectState( WSLIndex, pOldWSLObject = GetWSLObject(WSLIndex)) ) goto BadRefreshWSLObjectState;
lstrcpy(OldWSName, pOldWSLObject->m_WinStationName);
/*
* Fetch the WinStation's configuration structure. */ if((Status = RegistryQuery( pOldWSLObject->m_WinStationName, &EWSDlg.m_WSConfig, pOldWSLObject->m_WdName, &pExtObject))) {
pszFailedCall = pApp->m_pszRegWinStationQuery; goto BadRegWinStationQuery; } lstrcpy(NewWSName, pOldWSLObject->m_WinStationName);
/*
* copy the pExtObject into the one for the EWSDlg */ if(pExtObject) { PTERMLOBJECT pObject = GetWdListObject(pOldWSLObject->m_WdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtDupObject) { EWSDlg.m_pExtObject = (*pObject->m_lpfnExtDupObject)(pExtObject); } } else { EWSDlg.m_pExtObject = NULL; }
/*
* Initialize the dialog's member variables. */ EWSDlg.m_pWSName = NewWSName; EWSDlg.m_DlgMode = EWSDlgRename;
/*
* Invoke the dialog. */ if ( EWSDlg.DoModal() == IDOK ) {
CWaitCursor wait;
/*
* Add a new WSLObject to the WSL. */ if ( (nIndex = InsertInWSL(NewWSName, &EWSDlg.m_WSConfig, EWSDlg.m_pExtObject, &pNewWSLObject)) == -1 ) goto BadInsertInWSL;
/*
* Fetch the original WinStation's security descriptor. */ if ( (Status = GetWinStationSecurity( OldWSName, &m_pSecurityDescriptor)) != ERROR_SUCCESS ) {
pszFailedCall = pApp->m_pszGetWinStationSecurity; goto BadGetWinStationSecurity; }
/*
* Create the new registry entry. */ if((Status = RegistryCreate( NewWSName, TRUE, &EWSDlg.m_WSConfig, EWSDlg.m_WSConfig.Wd.WdName, EWSDlg.m_pExtObject))) {
pszFailedCall = pApp->m_pszRegWinStationCreate; goto BadRegCreate; }
/*
* Set the WinStation security in registry. */ if ( m_pSecurityDescriptor && (Status = RegWinStationSetSecurity( SERVERNAME_CURRENT, NewWSName, m_pSecurityDescriptor, GetSecurityDescriptorLength(m_pSecurityDescriptor) )) ) {
pszFailedCall = pApp->m_pszRegWinStationSetSecurity; goto BadRegSetSecurity; }
/*
* Delete the old registry entry. */ if ( (Status = RegistryDelete(OldWSName, EWSDlg.m_WSConfig.Wd.WdName, pExtObject)) ) {
pszFailedCall = pApp->m_pszRegWinStationDelete; goto BadRegDelete; }
/*
* Remove old WSLObject from the WSL and recalculate the * new WSLObject's index (may have changed). */ RemoveFromWSL( GetWSLIndex(OldWSName) ); nIndex = GetWSLIndex(NewWSName);
/*
* If we're not 'registry only', tell Session Manager * to re-read registry and output 'in use' message if * necessary. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) {
_WinStationReadRegistry(SERVERNAME_CURRENT);
/*
* Issue appropriate messages if the winstation being renamed * was enabled. */ if ( EWSDlg.m_WSConfig.Create.fEnableWinStation ) {
if ( *EWSDlg.m_WSConfig.Pd[0].Params.Async.ModemName ) {
QuestionMessage( MB_OK | MB_ICONEXCLAMATION, IDP_NOTICE_REBOOTFORMODEM_RENAME, OldWSName, NewWSName ); pNewWSLObject->m_Flags |= WSL_MUST_REBOOT;
} else {
InUseMessage(OldWSName); } } } #endif // WINSTA
/*
* A new WSLObject was added: update the entire view. */ UpdateAllViews(NULL, 0, NULL);
/*
* Return the new WSLObject's index. */ return(nIndex);
} else { /*
* User canceled the Rename; just return the previously given index. */ DeleteExtensionObject(pExtObject, EWSDlg.m_WSConfig.Wd.WdName); DeleteExtensionObject(EWSDlg.m_pExtObject, EWSDlg.m_WSConfig.Wd.WdName); return(WSLIndex); }
/*==============================================================================
* Error returns *============================================================================*/ BadRegDelete: BadRegSetSecurity: RegWinStationDelete( SERVERNAME_CURRENT, NewWSName ); BadRegCreate: BadGetWinStationSecurity: BadInsertInWSL: BadRegWinStationQuery: BadRefreshWSLObjectState: if ( nIndex != -1 ) RemoveFromWSL(nIndex);
if ( pszFailedCall ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_RENAMEWINSTATION, OldWSName, pszFailedCall )) } return(-1);
} // end CAppServerDoc::RenameWinStation
/*******************************************************************************
* * EditWinStation - CAppServerDoc member function: public operation * * Edit a WinStation. * * ENTRY: * WSLIndex (input) * WSL index of the WinStation to edit. * EXIT: * (int) WSL index of the edited WinStation's list item; -1 if error. * ******************************************************************************/
int CAppServerDoc::EditWinStation(int WSLIndex) { LONG Status; ULONG Length; int nIndex = -1; BOOL bQueueOperationSuccess = TRUE, bAllowAbort = TRUE; CEditWinStationDlg EWSDlg(this); PWSLOBJECT pWSLObject; WINSTATIONCONFIG2 WSConfig; LPCTSTR pszFailedCall = NULL; WINSTATIONNAME WSName; void *pExtObject = NULL;
/*
* Get current WinStation object and assure that the WSL is 'in sync' * with the registry. */ if ( !RefreshWSLObjectState( WSLIndex, pWSLObject = GetWSLObject(WSLIndex) ) ) goto BadRefreshWSLObjectState;
lstrcpy( WSName, pWSLObject->m_WinStationName );
/*
* Fetch the WinStation's configuration structure and save a copy for * update comparison. */ memset( &WSConfig, 0, sizeof(WINSTATIONCONFIG2) ); memset( &EWSDlg.m_WSConfig, 0, sizeof(WINSTATIONCONFIG2) );
if((Status = RegistryQuery( WSName, &WSConfig, pWSLObject->m_WdName, &pExtObject))) {
pszFailedCall = pApp->m_pszRegWinStationQuery; goto BadRegWinStationQuery; } memcpy( &EWSDlg.m_WSConfig, &WSConfig, sizeof(WINSTATIONCONFIG2) );
/*
* copy the pExtObject into the one for the EWSDlg */ if(pExtObject) { PTERMLOBJECT pObject = GetWdListObject(pWSLObject->m_WdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtDupObject) { EWSDlg.m_pExtObject = (*pObject->m_lpfnExtDupObject)(pExtObject); } } else { EWSDlg.m_pExtObject = NULL; }
/*
* Initialize the dialog's member variables. */ EWSDlg.m_pWSName = WSName; EWSDlg.m_DlgMode = m_bReadOnly ? EWSDlgView : EWSDlgEdit;
/*
* Invoke the dialog & update if changes. */ if ( (EWSDlg.DoModal() == IDOK) && (EWSDlg.m_DlgMode == EWSDlgEdit) && HasWSConfigChanged(&WSConfig, &EWSDlg.m_WSConfig, pExtObject, EWSDlg.m_pExtObject, EWSDlg.m_WSConfig.Wd.WdName) ) {
BOOL bUpdateAll = FALSE, bDestructive = FALSE, bAsyncDeviceChanged = ((pWSLObject->m_SdClass == SdAsync) && lstrcmpi(WSConfig.Pd[0].Params.Async.DeviceName, EWSDlg.m_WSConfig.Pd[0].Params.Async.DeviceName)), bAsyncModemChanged = ((pWSLObject->m_SdClass == SdAsync) && lstrcmpi(WSConfig.Pd[0].Params.Async.ModemName, EWSDlg.m_WSConfig.Pd[0].Params.Async.ModemName)), bNetworkDeviceChanged = ((pWSLObject->m_SdClass == SdNetwork) && (WSConfig.Pd[0].Params.Network.LanAdapter != EWSDlg.m_WSConfig.Pd[0].Params.Network.LanAdapter)), bEnabledStateChanged = (WSConfig.Create.fEnableWinStation != EWSDlg.m_WSConfig.Create.fEnableWinStation), bEnabled = EWSDlg.m_WSConfig.Create.fEnableWinStation, bWasEnabled = WSConfig.Create.fEnableWinStation;
/*
* If the winstation is being disabled or the device (or modem) has changed * and folks are connected, the update will cause all instances to be destroyed. * Let user know this so that the update can be canceled. Also allow * normal confirmation if just disabling the winstation and no users are * presently connected. */ if ( !bEnabled || bAsyncDeviceChanged || bAsyncModemChanged || bNetworkDeviceChanged ) {
if ( pApp->m_nConfirmation ) {
int id; UINT nType = 0; long count = QueryLoggedOnCount(WSName); if ( !bEnabled && bWasEnabled ) {
nType = MB_YESNO | (count ? MB_ICONEXCLAMATION : MB_ICONQUESTION); id = count ? ((count == 1) ? IDP_CONFIRM_WINSTATIONDISABLE_1USER : IDP_CONFIRM_WINSTATIONDISABLE_NUSERS) : IDP_CONFIRM_WINSTATIONDISABLE;
} else if ( bAsyncDeviceChanged && count ) {
nType = MB_YESNO | MB_ICONEXCLAMATION; id = IDP_CONFIRM_DEVICECHANGED;
} else if ( bAsyncModemChanged && count ) {
nType = MB_YESNO | MB_ICONEXCLAMATION; id = IDP_CONFIRM_MODEMCHANGED;
} else if ( bNetworkDeviceChanged && count ) {
nType = MB_YESNO | MB_ICONEXCLAMATION; id = ((count == 1) ? IDP_CONFIRM_ADAPTERCHANGED_1USER : IDP_CONFIRM_ADAPTERCHANGED_NUSERS); } if ( nType && (QuestionMessage(nType, id, WSName ) == IDNO) ) goto CancelChanges; } bDestructive = TRUE; }
CWaitCursor wait;
/*
* Special case for Async WinStation. */ if ( pWSLObject->m_SdClass == SdAsync ) {
/*
* If a modem has been added or removed from the WinStation, * delete the current WSLObject and add a new WSLObject to the list. */ if ( bAsyncModemChanged ) {
RemoveFromWSL(WSLIndex); if ( (WSLIndex = InsertInWSL( WSName, &EWSDlg.m_WSConfig, EWSDlg.m_pExtObject, &pWSLObject )) == -1 ) {
LoadWSL(pApp->m_szCurrentAppServer); goto BadInsertInWSL; } bUpdateAll = TRUE; }
/*
* Make sure that the WSL device name is current. */ FormDecoratedAsyncDeviceName( pWSLObject->m_DeviceName, &(EWSDlg.m_WSConfig.Pd[0].Params.Async) ); }
/*
* Special case for OEM Transport WinStation. */ if ( pWSLObject->m_SdClass == SdOemTransport ) {
/*
* Make sure that the WSL device name is current. */ lstrcpy( pWSLObject->m_DeviceName, EWSDlg.m_WSConfig.Pd[0].Params.OemTd.DeviceName ); }
/*
* Update WSL fields. */ lstrcpy( pWSLObject->m_WdName, EWSDlg.m_WSConfig.Wd.WdName ); lstrcpy( pWSLObject->m_Comment, EWSDlg.m_WSConfig.Config.Comment ); pWSLObject->m_Flags = ((pWSLObject->m_Flags & ~WSL_ENABLED) | (EWSDlg.m_WSConfig.Create.fEnableWinStation ? WSL_ENABLED : 0));
/*
* Update registry entry. */ if ( (Status = RegistryCreate( WSName, FALSE, &EWSDlg.m_WSConfig, EWSDlg.m_WSConfig.Wd.WdName, EWSDlg.m_pExtObject)) ) {
pszFailedCall = pApp->m_pszRegWinStationCreate; goto BadRegWinStationCreate; }
/*
* If we're not 'registry only', tell Session Manager * to re-read registry and output 'in use' message if * necessary. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) {
_WinStationReadRegistry(SERVERNAME_CURRENT);
/*
* If the state is now 'enabled' AND * 1) the modem has changed, OR * 2) a modem is now configured AND * a) the state was 'disabled' OR * b) the COM port has changed * Then issue the 'must reboot' message and set must reboot flag. * Otherwise, if this is not a destructive action, issue in use message if needed * and make sure the must reboot flag is cleared. */ if ( bEnabled && (bAsyncModemChanged || (*EWSDlg.m_WSConfig.Pd[0].Params.Async.ModemName && (!bWasEnabled || bAsyncDeviceChanged))) ) {
QuestionMessage( MB_OK | MB_ICONEXCLAMATION, IDP_NOTICE_REBOOTFORMODEM_EDIT, WSName ); pWSLObject->m_Flags |= WSL_MUST_REBOOT;
} else if ( !bDestructive ) {
InUseMessage(WSName); pWSLObject->m_Flags &= ~WSL_MUST_REBOOT; } } #endif // WINSTA
/*
* Update view. */ if ( bUpdateAll ) UpdateAllViews( NULL, 0, NULL ); else UpdateAllViewsWithItem( NULL, WSLIndex, pWSLObject ); } else { /*
* We didn't need to write any changes to the registry * Delete the extension objects we created */ DeleteExtensionObject(pExtObject, WSConfig.Wd.WdName); DeleteExtensionObject(EWSDlg.m_pExtObject, EWSDlg.m_WSConfig.Wd.WdName); }
CancelChanges: return(WSLIndex);
/*==============================================================================
* Error returns *============================================================================*/ BadRegWinStationCreate: BadInsertInWSL: BadRegWinStationQuery: BadRefreshWSLObjectState: if ( pszFailedCall ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_EDITWINSTATION, WSName, pszFailedCall )) } return(-1);
} // end CAppServerDoc::EditWinStation
/*******************************************************************************
* * DeleteWinStation - CAppServerDoc member function: public operation * * Delete a WinStation. * * ENTRY: * WSLIndex (input) * WSL index of the WinStation to delete. * EXIT: * (BOOL) TRUE if WinStation was deleted; FALSE otherwise. * ******************************************************************************/
BOOL CAppServerDoc::DeleteWinStation(int WSLIndex) { PWSLOBJECT pWSLObject; WINSTATIONNAME WSName; LONG Status, LoggedOnCount = 0; ULONG Length; LPCTSTR pszFailedCall = NULL; WINSTATIONCONFIG2 WSConfig; void *pExtObject;
/*
* Get current WinStation object and assure that the WSL is 'in sync' * with the registry. */ if ( !RefreshWSLObjectState( WSLIndex, pWSLObject = GetWSLObject(WSLIndex)) ) goto BadRefreshWSLObjectState;
lstrcpy( WSName, pWSLObject->m_WinStationName );
memset( &WSConfig, 0, sizeof(WINSTATIONCONFIG2) );
if((Status = RegistryQuery( WSName, &WSConfig, pWSLObject->m_WdName, &pExtObject))) {
pszFailedCall = pApp->m_pszRegWinStationQuery; goto BadRegWinStationQuery; }
/*
* Confirm delete if requested. */ if ( pApp->m_nConfirmation ) {
long count = QueryLoggedOnCount(WSName); UINT nType = MB_YESNO; int id;
if ( count == 0 ) { nType |= MB_ICONQUESTION; id = IDP_CONFIRM_WINSTATIONDELETE; } else if ( count == 1 ) { nType |= MB_ICONEXCLAMATION; id = IDP_CONFIRM_WINSTATIONDELETE_1USER; } else { nType |= MB_ICONEXCLAMATION; id = IDP_CONFIRM_WINSTATIONDELETE_NUSERS; }
if ( QuestionMessage( nType, id, WSName ) == IDNO ) goto DontDelete; }
{ CWaitCursor wait;
/*
* Delete the registry entry. */ if ( (Status = RegistryDelete(WSName, WSConfig.Wd.WdName, pExtObject)) ) {
pszFailedCall = pApp->m_pszRegWinStationDelete; goto BadRegDelete; }
/*
* Remove WSLObject from the list. */ RemoveFromWSL(WSLIndex);
/*
* If we're not 'registry only', tell Session Manager * to re-read registry. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) {
_WinStationReadRegistry(SERVERNAME_CURRENT); } #endif // WINSTA
/*
* A WSLObject was removed: update the entire view. */ UpdateAllViews(NULL, 0, NULL); }
DontDelete: return(TRUE);
/*==============================================================================
* Error returns *============================================================================*/ BadRegDelete: BadRegWinStationQuery: BadRefreshWSLObjectState: if ( pszFailedCall ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_DELETEWINSTATION, WSName, pszFailedCall )) } return(FALSE);
} // CAppServerDoc::DeleteWinStation
/*******************************************************************************
* * EnableWinStation - CAppServerDoc member function: public operation * * Enable or Disable specified WinStation(s). * * ENTRY: * WSLIndex (input) * WSL index of the WinStation(s) to enable or disable. * bEnable (input) * TRUE to enable WinStation(s); FALSE to disable WinStation(s). * EXIT: * ******************************************************************************/
void CAppServerDoc::EnableWinStation( int WSLIndex, BOOL bEnable ) { LONG Status; ULONG Length; PWSLOBJECT pWSLObject; WINSTATIONNAME WSName; WINSTATIONCONFIG2 WSConfig; LPCTSTR pszFailedCall = NULL;
/*
* Get current WinStation object and assure that the WSL is 'in sync' * with the registry. */ if ( !RefreshWSLObjectState( WSLIndex, pWSLObject = GetWSLObject(WSLIndex) ) ) goto BadRefreshWSLObjectState;
lstrcpy( WSName, pWSLObject->m_WinStationName );
/*
* Fetch the WinStation's configuration structure. */ if ( (Status = RegWinStationQuery( SERVERNAME_CURRENT, pWSLObject->m_WinStationName, &WSConfig, sizeof(WINSTATIONCONFIG2), &Length)) ) {
pszFailedCall = pApp->m_pszRegWinStationQuery; goto BadRegWinStationQuery; }
/*
* Confirm disable if requested. */ if ( !bEnable && pApp->m_nConfirmation ) {
long count = QueryLoggedOnCount(WSName); UINT nType = MB_YESNO; int id;
if ( count == 0 ) { nType |= MB_ICONQUESTION; id = IDP_CONFIRM_WINSTATIONDISABLE; } else if ( count == 1 ) { nType |= MB_ICONEXCLAMATION; id = IDP_CONFIRM_WINSTATIONDISABLE_1USER; } else { nType |= MB_ICONEXCLAMATION; id = IDP_CONFIRM_WINSTATIONDISABLE_NUSERS; }
if ( QuestionMessage( nType, id, WSName ) == IDNO ) goto DontDisable; }
{ CWaitCursor wait;
/*
* Update registry entry. */ WSConfig.Create.fEnableWinStation = (bEnable ? 1 : 0); if ( (Status = RegWinStationCreate( SERVERNAME_CURRENT, WSName, FALSE, &WSConfig, sizeof(WSConfig))) ) {
pszFailedCall = pApp->m_pszRegWinStationCreate; goto BadRegWinStationCreate; }
/*
* Update WSLObject state. */ pWSLObject->m_Flags = (pWSLObject->m_Flags & ~WSL_ENABLED) | (bEnable ? WSL_ENABLED : 0);
/*
* If we're not 'registry only', tell Session Manager * to re-read registry. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) {
_WinStationReadRegistry(SERVERNAME_CURRENT);
/*
* If we're enabling a modem winstation, issue the 'must reboot' message and * set 'must reboot flag. Otherwise, make sure the must reboot flag is cleared. */ if ( bEnable && *WSConfig.Pd[0].Params.Async.ModemName ) {
QuestionMessage( MB_OK | MB_ICONEXCLAMATION, IDP_NOTICE_REBOOTFORMODEM_ENABLE, WSName ); pWSLObject->m_Flags |= WSL_MUST_REBOOT;
} else {
pWSLObject->m_Flags &= ~WSL_MUST_REBOOT; } } #endif // WINSTA
/*
* Update this WSL in the view. */ UpdateAllViewsWithItem( NULL, WSLIndex, pWSLObject ); }
DontDisable: return;
/*==============================================================================
* Error returns *============================================================================*/ BadRegWinStationCreate: BadRegWinStationQuery: BadRefreshWSLObjectState: if ( pszFailedCall ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, bEnable ? IDP_ERROR_ENABLEWINSTATION : IDP_ERROR_DISABLEWINSTATION, WSName, pszFailedCall )) } return;
} // end CAppServerDoc::EnableWinStation
/*******************************************************************************
* * SecurityPermissions - CAppServerDoc member function: public operation * * View/Edit WinStation security permissions. * * ENTRY: * WSLIndex (input) * WSL index of the selected WinStation. * * EXIT: * ******************************************************************************/
void CAppServerDoc::SecurityPermissions(int WSLIndex) { PWSLOBJECT pWSLObject;
/*
* If no items yet, return immediately. */ if ( !(pWSLObject = GetWSLObject(WSLIndex)) ) return;
/*
* Get current WinStation object and assure that the WSL is 'in sync' * with the registry. */ if ( !RefreshWSLObjectState(WSLIndex, pWSLObject) ) return;
if ( CallPermissionsDialog( pApp->m_pMainWnd->m_hWnd, m_bAdmin, pWSLObject->m_WinStationName ) && (lstrcmpi(pWSLObject->m_WinStationName, pApp->m_szSystemConsole) != 0) ) {
/*
* If we're not 'registry only', tell Session Manager * to re-read registry and output 'in use' message if * necessary. */ #ifdef WINSTA
if ( !pApp->m_nRegistryOnly ) { _WinStationReadRegistry(SERVERNAME_CURRENT);
InUseMessage(pWSLObject->m_WinStationName); } #endif // WINSTA
}
} // end CAppServerDoc::SecurityPermissions
////////////////////////////////////////////////////////////////////////////////
// CAppServerDoc private operations
/*******************************************************************************
* * LoadWSL - CAppServerDoc member function: private operation * * Reset the WSL to 'empty' and read the specified AppServer's WinStation * registry information to load up the WSL. * * ENTRY: * pszAppServer (input) * Name of the AppServer to access. * * EXIT: * (BOOL) TRUE if the load was successful; FALSE if error. * ******************************************************************************/
BOOL CAppServerDoc::LoadWSL( LPCTSTR pszAppServer ) { LONG Status; ULONG Index, ByteCount, Entries, LogonId; WINSTATIONNAME WSName; void *pExtObject = NULL;
/*
* Insure that the WSL is empty. */ DeleteWSLContents();
Index = 0; for ( Index = 0, Entries = 1, ByteCount = sizeof(WINSTATIONNAME); (Status = RegWinStationEnumerate( SERVERNAME_CURRENT, &Index, &Entries, WSName, &ByteCount )) == ERROR_SUCCESS; ByteCount = sizeof(WINSTATIONNAME) ) {
WINSTATIONCONFIG2 WSConfig; PWSLOBJECT pWSLObject; ULONG Length;
/*
* Ignore system console. */ if ( !lstrcmpi(WSName, pApp->m_szSystemConsole) ) continue;
if ( (Status = RegistryQuery(WSName, &WSConfig, WSConfig.Wd.WdName, &pExtObject)) ) { STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_REGWINSTATIONQUERY, WSName )) continue; }
/*
* Insert a WinStation object into the WinStationList. */ if ( InsertInWSL( WSName, &WSConfig, pExtObject, &pWSLObject ) == -1 ) { DeleteWSLContents(); return(FALSE); }
/*
* If this was an enabled modem WinStation and it has not been * created by the system, flag as 'must reboot' (configured TAPI * winstation that requires system reboot before being activated). */ #ifdef WINSTA
if ( (pWSLObject->m_SdClass == SdAsync) && (pWSLObject->m_Flags & WSL_ENABLED) && !(pWSLObject->m_Flags & WSL_DIRECT_ASYNC) && !LogonIdFromWinStationName(SERVERNAME_CURRENT, WSName, &LogonId) ) pWSLObject->m_Flags |= WSL_MUST_REBOOT; #endif // WINSTA
}
return(TRUE);
} // end CAppServerDoc::LoadWSL
/*******************************************************************************
* * RefreshWSLObjectState - CAppServerDoc member function: private operation * * Make sure that the state of the specified WSL matches the WinStation * state in the registry. * * ENTRY: * nIndex (input) * Index of WSL being refreshed. * pWSLObject (input/output) * Points to the WSLOBJECT containing the WinStation(s) being * refreshed. * EXIT: * (BOOL) TRUE if the refresh was successful; FALSE if error. * ******************************************************************************/
BOOL CAppServerDoc::RefreshWSLObjectState( int nIndex, PWSLOBJECT pWSLObject ) { ULONG State; LONG Status;
/*
* Check for invalid WSLObject (return TRUE if so). */ if ( pWSLObject == NULL ) return(TRUE);
#ifdef UNICODE
Status = RegWinStationQueryNumValue( SERVERNAME_CURRENT, pWSLObject->m_WinStationName, WIN_ENABLEWINSTATION, &State ); #else
/*
* Note: this function does not have a ANSI version: must convert the * ANSI WINSTATIONNAME(A) into UNICODE WINSTATIONNAME(W) and call * the UNICODE RegWinStationQueryNumValueW() API. */ WINSTATIONNAMEW WSNameW;
mbstowcs( WSNameW, pWSLObject->m_WinStationName, sizeof(WSNameW) ); Status = RegWinStationQueryNumValueW( SERVERNAME_CURRENT, WSNameW, WIN_ENABLEWINSTATION, &State ); #endif
if ( Status != ERROR_SUCCESS ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, Status, IDP_ERROR_REFRESHWINSTATIONSTATE, pWSLObject->m_WinStationName )) return(FALSE); }
if ( (State && !(pWSLObject->m_Flags & WSL_ENABLED)) || (!State && (pWSLObject->m_Flags & WSL_ENABLED)) ) {
POSITION pos;
/*
* The registry state does not match the WSL's state: update the * WSL and cause the view to redraw it immediately. */ pWSLObject->m_Flags = (pWSLObject->m_Flags & ~WSL_ENABLED) | (State ? WSL_ENABLED : 0); UpdateAllViewsWithItem( NULL, nIndex, NULL ); GetNextView( pos = GetFirstViewPosition() )->UpdateWindow(); }
return(TRUE);
} // end CAppServerDoc::RefreshWSLObjectState
/*******************************************************************************
* * DeleteWSLContents - CAppServerDoc member function: private operation * * Make sure that the WinStationObjectList is empty. * * ENTRY: * EXIT: * ******************************************************************************/
void CAppServerDoc::DeleteWSLContents() { POSITION pos1, pos2; PWSLOBJECT pObject;
/*
* Clean up the WinStationList. */ for ( pos1 = m_WinStationList.GetHeadPosition(); (pos2 = pos1) != NULL; ) { m_WinStationList.GetNext( pos1 ); pObject = (PWSLOBJECT)m_WinStationList.GetAt( pos2 ); m_WinStationList.RemoveAt( pos2 ); delete ( pObject ); }
} // end CAppServerDoc::DeleteWSLContents
/*******************************************************************************
* * InsertInWSL - CAppServerDoc member function: private operation * * Create a new WinStationList object and insert it into the WinStationList * (if needed). * * ENTRY: * pWSName (input) * Points to name of WinStation. * pConfig (input) * Points to WinStation's WINSTATIONCONFIG2 structure. * pExtObject (input) * Points to the extension DLL's data for the WinStation * ppObject (output) * Points to a PWSLOBJECT pointer which is to receive the PWSLOBJECT * for the new WinStationList object. * EXIT: * (int) * index of the WinStationList object in the WinStationList; -1 if * error. * ******************************************************************************/
int CAppServerDoc::InsertInWSL( PWINSTATIONNAME pWSName, PWINSTATIONCONFIG2 pWSConfig, void *pExtObject, PWSLOBJECT * ppObject ) { int Index = 0; BOOL bAdded; POSITION oldpos, pos; PWSLOBJECT pObject, pListObject;
/*
* Create a new WinStationList object and initialize. */ if ( !(pObject = new CWinStationListObject) ) {
ERROR_MESSAGE((IDP_ERROR_WSLISTALLOC)) return(-1); } lstrcpy( pObject->m_WinStationName, pWSName ); lstrlwr(pObject->m_WinStationName); pObject->m_Flags = pWSConfig->Create.fEnableWinStation ? WSL_ENABLED : 0; pObject->m_Flags |= (pWSConfig->Pd[0].Create.PdFlag & PD_SINGLE_INST) ? WSL_SINGLE_INST : 0; lstrcpy( pObject->m_PdName, pWSConfig->Pd[0].Create.PdName ); pObject->m_SdClass = pWSConfig->Pd[0].Create.SdClass; lstrcpy( pObject->m_WdName, pWSConfig->Wd.WdName ); lstrcpy( pObject->m_Comment, pWSConfig->Config.Comment ); pObject->m_pExtObject = pExtObject; pObject->m_pWdListObject = GetWdListObject(pObject->m_WdName);
if ( pObject->m_SdClass == SdAsync ) {
FormDecoratedAsyncDeviceName( pObject->m_DeviceName, &(pWSConfig->Pd[0].Params.Async) );
} else if ( pObject->m_SdClass == SdOemTransport ) {
lstrcpy( pObject->m_DeviceName, pWSConfig->Pd[0].Params.OemTd.DeviceName );
} else {
*(pObject->m_DeviceName) = TEXT('\0'); }
pObject->m_Flags |= (pObject->m_SdClass == SdAsync) ? ( *(pWSConfig->Pd[0].Params.Async.ModemName) ? 0 : WSL_DIRECT_ASYNC ) : 0; pObject->m_LanAdapter = (pObject->m_SdClass == SdNetwork) ? pWSConfig->Pd[0].Params.Network.LanAdapter : 0;
/*
* Traverse the WinStationList and insert this new WinStation, * keeping the list sorted by SdClass, then PdName, then DirectAsync * flag (effects SdAsync types) / LanAdapter # (effects SdNetwork * types), then WinStationName. */ for ( Index = 0, bAdded = FALSE, pos = m_WinStationList.GetHeadPosition(); pos != NULL; Index++ ) {
oldpos = pos; pListObject = (PWSLOBJECT)m_WinStationList.GetNext( pos );
if ( (pListObject->m_SdClass > pObject->m_SdClass) ||
((pListObject->m_SdClass == pObject->m_SdClass) && lstrcmpi( pListObject->m_PdName, pObject->m_PdName ) > 0) ||
((pListObject->m_SdClass == pObject->m_SdClass) && !lstrcmpi( pListObject->m_PdName, pObject->m_PdName ) && ((pListObject->m_Flags & WSL_DIRECT_ASYNC) > (pObject->m_Flags & WSL_DIRECT_ASYNC))) ||
((pListObject->m_SdClass == pObject->m_SdClass) && !lstrcmpi( pListObject->m_PdName, pObject->m_PdName ) && (pListObject->m_LanAdapter > pObject->m_LanAdapter)) ||
((pListObject->m_SdClass == pObject->m_SdClass) && !lstrcmpi( pListObject->m_PdName, pObject->m_PdName ) && ((pListObject->m_Flags & WSL_DIRECT_ASYNC) == (pObject->m_Flags & WSL_DIRECT_ASYNC)) && (pListObject->m_LanAdapter == pObject->m_LanAdapter) && (lstrcmpi( pListObject->m_WinStationName, pObject->m_WinStationName ) > 0)) ) {
/*
* The new object belongs before the current list object. */ m_WinStationList.InsertBefore( oldpos, pObject ); bAdded = TRUE; break; } }
/*
* If we haven't yet added the WinStation, add it now to the tail * of the list. */ if ( !bAdded ) m_WinStationList.AddTail( pObject );
/*
* Set the ppObject referenced PWSLOBJECT pointer to the new PWSLOBJECT * pointer and return the index of the new WinStationList object. */ *ppObject = pObject; return( Index );
} // end CAppServerDoc::InsertInWSL
/*******************************************************************************
* * RemoveFromWSL - CAppServerDoc member function: private operation * * Remove from the WSL the WSLObject associated with the specified * index, and delete the removed WSLObject. * * ENTRY: * nIndex (input) * WSL index of the WSLObject to remove / delete. * EXIT: * ******************************************************************************/
void CAppServerDoc::RemoveFromWSL( int nIndex ) { POSITION pos; PWSLOBJECT pWSLObject;
/*
* Return immediately if invalid index. */ if ( nIndex < 0 ) return;
pWSLObject = (PWSLOBJECT)m_WinStationList.GetAt( (pos = m_WinStationList.FindIndex(nIndex))); m_WinStationList.RemoveAt(pos); delete pWSLObject;
} // end CAppServerDoc::RemoveFromWSL
/*******************************************************************************
* * UpdateAllViewsWithItem - CAppServerDoc member function: private operation * * Update all views of this document with a changed WinStation item. * * ENTRY: * * pSourceView (input) * Points to document view to update (all views if NULL). * * nItemIndex (input) * Document's item (WinStation) index that is causing the update * to occur. * * pWSLObject (input) * Pointer to the Document's WinStation list object pointer (may be * NULL). * * EXIT: * ******************************************************************************/
void CAppServerDoc::UpdateAllViewsWithItem( CView* pSourceView, UINT nItemIndex, PWSLOBJECT pWSLObject ) { CWinStationListObjectHint hint;
hint.m_WSLIndex = nItemIndex; hint.m_pWSLObject = pWSLObject;
UpdateAllViews( pSourceView, 0, &hint );
} // end CAppServerDoc::UpdateAllViewsWithItem
/*******************************************************************************
* * InUseMessage - CAppServerDoc member function: private operation * * If needed, output an appropriate 'in use' message for the specified * WinStation. * * ENTRY: * pWSName (input) * Points WinStation name to output message for. * EXIT: * ******************************************************************************/
void CAppServerDoc::InUseMessage( PWINSTATIONNAME pWSName ) { long count;
if ( (count = QueryLoggedOnCount(pWSName)) ) {
QuestionMessage( MB_OK | MB_ICONINFORMATION, (count == 1) ? IDP_NOTICE_WSINUSE_1USER : IDP_NOTICE_WSINUSE_NUSERS, pWSName ); }
} // end CAppServerDoc::InUseMessage
/*******************************************************************************
* * HasWSConfigChanged - CAppServerDoc member function: private operation * * Determine if WINSTATIONCONFIG2 structure has changed, calling our * HasPDConfigChanged method to handle goofy PdConfig2 regapi behavior * (straight memcmp won't work). * * ENTRY: * pOldConfig (input) * Points to the original WINSTATIONCONFIG2 structure. * pNewConfig (input) * Points to the new WINSTATIONCONFIG2 structure. * pOldExtObject (input) * Points to the original extension DLLs object * pNewExtObject (input) * Points to the new extension DLLs object * EXIT: * TRUE if original and new config structures differ; * FALSE if no changes are detected. * ******************************************************************************/
BOOL CAppServerDoc::HasWSConfigChanged( PWINSTATIONCONFIG2 pOldConfig, PWINSTATIONCONFIG2 pNewConfig, void *pOldExtObject, void *pNewExtObject, PWDNAME pWdName) { BOOL bChanged = FALSE;
if ( memcmp( &pOldConfig->Create, &pNewConfig->Create, sizeof(WINSTATIONCREATE) ) ||
HasPDConfigChanged(pOldConfig, pNewConfig) ||
HasExtensionObjectChanged(pWdName, pOldExtObject, pNewExtObject) ||
memcmp( &pOldConfig->Wd, &pNewConfig->Wd, sizeof(WDCONFIG) ) ||
memcmp( &pOldConfig->Cd, &pNewConfig->Cd, sizeof(CDCONFIG) ) ||
memcmp( &pOldConfig->Config, &pNewConfig->Config, sizeof(WINSTATIONCONFIG) ) ) {
bChanged = TRUE; }
return(bChanged);
} // end CAppServerDoc::HasWSConfigChanged
/*******************************************************************************
* * HasPDConfigChanged - CAppServerDoc member function: private operation * * Determine if the PDConfig structures have changed, with special * compare logic to handle goofy PdConfig2 regapi behavior (straight * memcmp won't work). * * ENTRY: * pOldConfig (input) * Points to the original WINSTATIONCONFIG2 structure. * pNewConfig (input) * Points to the new WINSTATIONCONFIG2 structure. * EXIT: * TRUE if original and new config structures differ; * FALSE if no changes are detected. * ******************************************************************************/
BOOL CAppServerDoc::HasPDConfigChanged( PWINSTATIONCONFIG2 pOldConfig, PWINSTATIONCONFIG2 pNewConfig ) { BOOL bChanged = FALSE; int i;
for ( i = 0; i < MAX_PDCONFIG; i++ ) {
if ( (pOldConfig->Pd[i].Create.SdClass != pNewConfig->Pd[i].Create.SdClass) || memcmp( &pOldConfig->Pd[i].Params, &pNewConfig->Pd[i].Params, sizeof(PDPARAMS) ) ) {
bChanged = TRUE; break; } }
return(bChanged);
} // end CAppServerDoc::HasPDConfigChanged
/*******************************************************************************
* * HasExtensionObjectChanged - CAppServerDoc member function: private operation * * Determine if the object maintained by the extension DLL has changed * * ENTRY: * pOldExtObject (input) * Points to the original extension DLLs object * pNewExtObject (input) * Points to the new extension DLLs object * EXIT: * TRUE if original and new objects differ; * FALSE if no changes are detected. * ******************************************************************************/
BOOL CAppServerDoc::HasExtensionObjectChanged( PWDNAME pWdName, void *pOldExtObject, void *pNewExtObject) { BOOL bChanged = FALSE;
if(!pOldExtObject && !pNewExtObject) return FALSE; if(!pOldExtObject || !pNewExtObject) return TRUE;
/*
* Ask the extension DLL if the objects are the same. * Extension DLL returns TRUE if the objects are the same * and FALSE if they are not, * Therefore, we must NOT the value before returning it */ PTERMLOBJECT pObject = GetWdListObject(pWdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtCompareObjects) { return !(*pObject->m_lpfnExtCompareObjects)(pOldExtObject, pNewExtObject); } /*
* If for some reason, we can't ask the extension DLL, play it safe and * assume that the object has changed */ return TRUE;
}
/*******************************************************************************
* * CAppServerDoc::DeleteExtensionObject * * Tells the extension DLL to delete an object we no longer need * * ENTRY: * pExtObject (input) * Points to the extension object * pWdName (input) * Points to the name of the Wd (this is used to determine * which extension DLL owns the object) * EXIT: * none * ******************************************************************************/ void CAppServerDoc::DeleteExtensionObject(void *pExtObject, PWDNAME pWdName) { if(pExtObject) { /*
* Tell the extension DLL to delete this object */ PTERMLOBJECT pObject = GetWdListObject(pWdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtDeleteObject) { (*pObject->m_lpfnExtDeleteObject)(pExtObject); } }
} // end CAppServerDoc::DeleteExtensionObject
/*******************************************************************************
* * CAppServerDoc::RegistryQuery * * Queries the registry for the information about a WinStation AND * queries the extension DLL for it's information about the WinStation * * ENTRY: * pWinStationName (input) * Points to the name of the WinStation * pWsConfig (output) * Where to put the query results * pWdName (input) * Points to the name of the Wd (this is used to determine * which extension DLL owns the object) * pExtObject (output) * This pointer will point to the extension DLL's object * for this WinStation * EXIT: * ERROR_SUCCESS if successful * Registry error code, if not * ******************************************************************************/ LONG CAppServerDoc::RegistryQuery(PWINSTATIONNAME pWinStationName, PWINSTATIONCONFIG2 pWsConfig, PWDNAME pWdName, void **pExtObject) { LONG Status; ULONG Length;
/*
* Query the registry for WinStation data */ if((Status = RegWinStationQuery( SERVERNAME_CURRENT, pWinStationName, pWsConfig, sizeof(WINSTATIONCONFIG2), &Length)) ) { return Status; }
// Ask the extension DLL for it's data
PTERMLOBJECT pObject = GetWdListObject(pWdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtRegQuery) { *pExtObject = (*pObject->m_lpfnExtRegQuery)(pWinStationName, &pWsConfig->Pd[0]); if(!pExtObject) Status = ERROR_INVALID_FUNCTION; } else *pExtObject = NULL;
return Status;
} // end CAppServerDoc::RegistryQuery
/*******************************************************************************
* * CAppServerDoc::RegistryCreate * * Create/Update the registry for a WinStation AND * tell the extension DLL to store it's information about the WinStation * * ENTRY: * pWinStationName (input) * Points to the name of the WinStation * pWsConfig (input) * Points to the data for this WinStation * pWdName (input) * Points to the name of the Wd (this is used to determine * which extension DLL owns the object) * pExtObject (input) * Points to the extension DLL's data for this WinStation * EXIT: * ERROR_SUCCESS if successful * Registry error code, if not * ******************************************************************************/ LONG CAppServerDoc::RegistryCreate(PWINSTATIONNAME pWinStationName, BOOLEAN bCreate, PWINSTATIONCONFIG2 pWsConfig, PWDNAME pWdName, void *pExtObject) { LONG Status;
if((Status = RegWinStationCreate( SERVERNAME_CURRENT, pWinStationName, bCreate, pWsConfig, sizeof(WINSTATIONCONFIG2))) ) { return Status; }
if(pExtObject) { /*
* Tell the extension DLL to write it's data */ PTERMLOBJECT pObject = GetWdListObject(pWdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtRegCreate) { Status = (*pObject->m_lpfnExtRegCreate)(pWinStationName, pExtObject, bCreate); } } return Status;
} // end CAppServerDoc::RegistryCreate
/*******************************************************************************
* * CAppServerDoc::RegistryDelete * * Deletes a WinStation's data from the registry AND * tells the extension DLL to delete it's data for the WinStation from * the registry (or wherever he stores it) * * ENTRY: * pWinStationName (input) * Points to the name of the WinStation * pWdName (input) * Points to the name of the Wd (this is used to determine * which extension DLL owns the object) * pExtObject (input) * Points to the extension DLL's data for this WinStation * EXIT: * ERROR_SUCCESS if successful * Registry error code, if not * ******************************************************************************/ LONG CAppServerDoc::RegistryDelete(PWINSTATIONNAME pWinStationName, PWDNAME pWdName, void *pExtObject) { LONG Status; LONG ExtStatus = ERROR_SUCCESS;
/*
* Tell the extension DLL to delete it's data first. * This is done because it could be a subkey under the WinStation's data * in the Registry. RegWinStationDelete calls RegDeleteKey which * cannot delete subkeys under Windows NT. */ if(pExtObject) { /*
* Tell the extension DLL to delete it's data */ PTERMLOBJECT pObject = GetWdListObject(pWdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtRegDelete) { ExtStatus = (*pObject->m_lpfnExtRegDelete)(pWinStationName, pExtObject); } }
Status = RegWinStationDelete( SERVERNAME_CURRENT, pWinStationName); if(ExtStatus) return ExtStatus; return Status;
} // end CAppServerDoc::RegistryDelete
///////////////////////////////////////////////////////////////////////////////
// CAppServerDoc message map
BEGIN_MESSAGE_MAP(CAppServerDoc, CDocument) //{{AFX_MSG_MAP(CAppServerDoc)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////////
// CAppServerDoc commands
/*******************************************************************************
* * CWinStationListObject constructor * * * ENTRY: * none * EXIT: * constructors don't have return types * ******************************************************************************/ CWinStationListObject::CWinStationListObject() { m_pExtObject = NULL;
} // end CWinStationListObject::CWinStationListObject
/*******************************************************************************
* * CWinStationListObject destructor * * Tells the extension DLL to delete the object associated with this guy * * ENTRY: * none * EXIT: * destructors don't have return types * ******************************************************************************/ CWinStationListObject::~CWinStationListObject() { if(m_pExtObject) { PTERMLOBJECT pObject = GetWdListObject(m_WdName);
if(pObject && pObject->m_hExtensionDLL && pObject->m_lpfnExtDeleteObject) { (*pObject->m_lpfnExtDeleteObject)(m_pExtObject); } } } // end CWinStationListObject::~CWinStationListObject
/*******************************************************************************
* * GetWdListObject - * * Returns a pointer to the Wd list object for the specified WD * * ENTRY: * pWdName (input) * Points to the name of the Wd * EXIT: * pointer to Wd List Object * NULL if not found * ******************************************************************************/ PTERMLOBJECT GetWdListObject(PWDNAME pWdName) { POSITION pos; PTERMLOBJECT pObject;
/*
* Traverse the WD list */ for ( pos = pApp->m_WdList.GetHeadPosition(); pos != NULL; ) {
pObject = (PTERMLOBJECT)pApp->m_WdList.GetNext( pos );
if ( !lstrcmp( pObject->m_WdConfig.Wd.WdName, pWdName ) ) { return(pObject); } }
return(NULL);
} // end GetWdListObject
|