|
|
/*++
Copyright (C) Microsoft Corporation, 1998 - 1999 All rights reserved.
Module Name:
locprop.cxx
Abstract:
Server Properties
Author:
Steve Kiraly (SteveKi) 09/08/98 Lazar Ivanov (LazarI) Nov-28-2000 - validation
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "dsinterf.hxx"
#include "locprop.hxx"
#include "findloc.hxx"
#include "physloc.hxx"
#define INVALID_RESOURCE_ID ((UINT )-1)
TLocationPropertySheetFrontEnd:: TLocationPropertySheetFrontEnd( IN IShellPropSheetExt *pShellPropSheetExt, IN LPDATAOBJECT lpdobj, IN LPFNADDPROPSHEETPAGE lpfnAddPage, IN LPARAM lParam ) : _bValid( FALSE ), _pShellPropSheetExt( pShellPropSheetExt ), _lpdobj( lpdobj ), _pLocation( NULL ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::TLocationPropertySheetFrontEnd\n" ) );
if( AddPropertyPages( lpfnAddPage, lParam ) ) { _bValid = TRUE; } }
TLocationPropertySheetFrontEnd:: ~TLocationPropertySheetFrontEnd( VOID ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::~TLocationPropertySheetFrontEnd\n" ) ); delete _pLocation; }
BOOL TLocationPropertySheetFrontEnd:: bValid( VOID ) const { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::bValid\n" ) ); return _bValid; }
HRESULT TLocationPropertySheetFrontEnd:: Create( IN OUT TLocationPropertySheetFrontEnd **ppPropertySheet, IN IShellPropSheetExt *pShellPropSheetExt, IN LPDATAOBJECT lpdobj, IN LPFNADDPROPSHEETPAGE lpfnAddPage, IN LPARAM lParam ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::Create\n" ) );
HRESULT hr = S_OK;
*ppPropertySheet = new TLocationPropertySheetFrontEnd (pShellPropSheetExt, lpdobj, lpfnAddPage, lParam);
if (!VALID_PTR(*ppPropertySheet)) { Destroy (ppPropertySheet); hr = E_FAIL; }
return hr; }
VOID TLocationPropertySheetFrontEnd:: Destroy( IN OUT TLocationPropertySheetFrontEnd **ppPropertySheet ) { if (*ppPropertySheet) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::Destroy\n" ) );
delete *ppPropertySheet; *ppPropertySheet = NULL; } }
BOOL TLocationPropertySheetFrontEnd:: AddPropertyPages( IN LPFNADDPROPSHEETPAGE lpfnAddPage, IN LPARAM lParam ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::AddPropertyPages\n" ) );
BOOL bRetval = TRUE;
if( bRetval ) { _pLocation = new TLocationPropertySheet( _pShellPropSheetExt, _lpdobj );
if( VALID_PTR( _pLocation ) ) { bRetval = CreatePropertyPage( lpfnAddPage, lParam, _pLocation, _pLocation->uGetResourceTemplateID() ); } }
return bRetval; }
BOOL TLocationPropertySheetFrontEnd:: CreatePropertyPage( IN LPFNADDPROPSHEETPAGE lpfnAddPage, IN LPARAM lParam, IN MGenericProp *pPage, IN UINT Template ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheetFrontEnd::CreatePropertyPage\n" ) );
//
// Ensure the page pointer and page object is valid.
//
BOOL bRetval = VALID_PTR( pPage );
if( bRetval ) { PROPSHEETPAGE psp = {0};
psp.dwSize = sizeof( psp ); psp.dwFlags = PSP_DEFAULT | PSP_USEREFPARENT | PSP_USECALLBACK | PSP_PREMATURE; psp.hInstance = ghInst; psp.pfnDlgProc = MGenericProp::SetupDlgProc; psp.pfnCallback = MGenericProp::CallbackProc; psp.pcRefParent = reinterpret_cast<UINT *>( &gcRefThisDll ); psp.pszTemplate = MAKEINTRESOURCE( Template ); psp.lParam = reinterpret_cast<LPARAM>( pPage );
//
// Create the actual page and get the pages handle.
//
HPROPSHEETPAGE hPage = ::CreatePropertySheetPage( &psp );
//
// Add the page to the property sheet.
//
if( hPage && lpfnAddPage( hPage, lParam ) ) { if( _pShellPropSheetExt ) { _pShellPropSheetExt->AddRef(); } } else { //
// We could not add the page, remember to destroy the handle
//
if( hPage ) { ::DestroyPropertySheetPage (hPage); }
bRetval = FALSE; } } return bRetval; }
/********************************************************************
Location property sheet.
********************************************************************/
TLocationPropertySheet:: TLocationPropertySheet( IN IShellPropSheetExt *pShellPropSheetExt, IN IDataObject *pdobj ) : _pShellPropSheetExt( pShellPropSheetExt ), _bValid( FALSE ), _cfDsObjectNames( 0 ), _pDsObject( NULL ), _uLocationEditID( INVALID_RESOURCE_ID ), _uBrowseID( INVALID_RESOURCE_ID ), _PropertyAccess( kPropertyAccessNone ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheet::TLocationPropertySheet\n" ) );
TStatusB bStatus;
//
// Ensure the ds interface object is in a valid state.
//
if( VALID_OBJ( _Ds ) ) { //
// Initialize the ds object clipboard format.
//
bStatus DBGCHK = InitializeDsObjectClipboardFormat();
if( bStatus ) { //
// Get the ds object name.
//
bStatus DBGCHK = GetDsObjectNameFromIDataObject( pdobj, _strDsObjectName, _strDsObjectClass );
if( bStatus ) { DBGMSG( DBG_TRACE, ( "DsObjectName " TSTR "\n", (LPCTSTR)_strDsObjectName ) ); DBGMSG( DBG_TRACE, ( "DsObjectClass " TSTR "\n", (LPCTSTR)_strDsObjectClass ) );
//
// Computer location page will have different resource
// template in order to have different control IDs and
// thereafter different help IDs.
//
_uBrowseID = IDC_BROWSE_PHYSICAL_LOCATION; if( !_tcsicmp( _strDsObjectClass, gszComputer ) ) { _uLocationEditID = IDC_PHYSICAL_COMPUTER_LOCATION; } else { _uLocationEditID = IDC_PHYSICAL_LOCATION; }
//
// Get the objects interface.
//
bStatus DBGCHK = GetObjectInterface( _strDsObjectName, &_pDsObject );
if( bStatus ) { //
// Check our current access priviliges. None, Read, Read|Write
//
bStatus DBGCHK = CheckPropertyAccess( gszLocation, _PropertyAccess );
//
// If were able to determine our access and we have at least read
// access then display the property sheet.
//
if( bStatus && ( _PropertyAccess != kPropertyAccessNone ) ) { //
// If we get here every this is ok, ready to display the page.
//
_bValid = TRUE; } } } } } }
TLocationPropertySheet:: ~TLocationPropertySheet( VOID ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheet::~TLocationPropertySheet\n" ) );
//
// Release the adsi interface, if aquired.
//
if( _pDsObject ) { _pDsObject->Release(); } }
BOOL TLocationPropertySheet:: bValid( VOID ) const { return _bValid; }
UINT TLocationPropertySheet:: uGetResourceTemplateID( VOID ) const { UINT uDefTemplateID = DLG_PRINTER_LOCATION;
//
// Computer location page will have different resource
// template in order to have different control IDs and
// different help IDs.
//
if( !_tcsicmp( _strDsObjectClass, gszComputer ) ) { uDefTemplateID = DLG_COMPUTER_LOCATION; }
return uDefTemplateID; }
VOID TLocationPropertySheet:: vDestroy( VOID ) { //
// This fuction is called from the property sheet callback when the
// sheet is destroyed.
//
if( _pShellPropSheetExt ) { _pShellPropSheetExt->Release(); } }
BOOL TLocationPropertySheet:: InitializeDsObjectClipboardFormat( VOID ) { //
// If the clipboard format has not been registred then do it now.
//
if( !_cfDsObjectNames ) { _cfDsObjectNames = RegisterClipboardFormat( CFSTR_DSOBJECTNAMES ); }
return _cfDsObjectNames != 0; }
BOOL TLocationPropertySheet:: GetDsObjectNameFromIDataObject( IN IDataObject *pdobj, IN TString &strDsObjectName, IN TString &strDsObjectClass ) { HRESULT hr = E_FAIL; TStatusB bStatus;
if( pdobj ) { STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL }; FORMATETC formatetc = { (CLIPFORMAT)_cfDsObjectNames, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
hr = pdobj->GetData(&formatetc, &stgmedium);
if (SUCCEEDED(hr)) { LPDSOBJECTNAMES pDsObjectNames = reinterpret_cast<LPDSOBJECTNAMES>( stgmedium.hGlobal );
hr = pDsObjectNames ? S_OK : E_FAIL;
if( SUCCEEDED(hr) ) { if( pDsObjectNames->cItems == 1 ) { bStatus DBGCHK = strDsObjectName.bUpdate( ByteOffset( pDsObjectNames, pDsObjectNames->aObjects[0].offsetName ) );
if( bStatus ) { bStatus DBGCHK = strDsObjectClass.bUpdate( ByteOffset( pDsObjectNames, pDsObjectNames->aObjects[0].offsetClass ) ); }
hr = bStatus ? S_OK : E_FAIL; } else { hr = E_FAIL; } }
ReleaseStgMedium(&stgmedium); } }
return SUCCEEDED(hr); }
BOOL TLocationPropertySheet:: CheckPropertyAccess( IN LPCTSTR pszPropertyName, IN EPropertyAccess &Access ) { DBGMSG( DBG_TRACE, ( "TLocationPropertySheet::CheckPropertyAccess\n" ) );
//
// Assume no access.
//
Access = kPropertyAccessNone;
//
// Need a directory object interface to query for the effective attributes.
//
IDirectoryObject *pDsObj = NULL;
//
// Get the directory object interface.
//
HRESULT hr = ADsOpenObject( const_cast<LPTSTR>( static_cast<LPCTSTR>(_strDsObjectName)), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, reinterpret_cast<LPVOID*>( &pDsObj ) );
if( SUCCEEDED(hr) ) { DWORD cAttrs = 0; PADS_ATTR_INFO pAttrs = NULL; LPCTSTR szNames[2] = {gszName, gszAllowed};
//
// Query for this objects attributes.
//
hr = pDsObj->GetObjectAttributes( (LPTSTR*)szNames, 2, &pAttrs, &cAttrs );
if( SUCCEEDED(hr) ) { //
// The object was opened and we were able to read the attributes then
// We assume we have read access.
//
Access = kPropertyAccessRead;
for (UINT i = 0; i < cAttrs; i++) { DBGMSG( DBG_TRACE, ( "Allowed Name " TSTR "\n", pAttrs[i].pszAttrName ) );
if (!_tcsicmp( pAttrs[i].pszAttrName, gszAllowed )) { for (UINT j = 0; j < pAttrs[i].dwNumValues; j++) { DBGMSG( DBG_TRACE, ( "Allowed attribute (effective): %d " TSTR "\n", pAttrs[i].pADsValues[j].dwType, pAttrs[i].pADsValues[j].CaseIgnoreString ) );
if (!_tcsicmp( pAttrs[i].pADsValues[j].CaseIgnoreString, gszLocation )) { //
// We found the location property in the attribute list,
// by this fact we now know we can write this property.
//
Access = kPropertyAccessWrite; } } } }
//
// Release the writeable attribute memory.
//
if( pAttrs ) { FreeADsMem( pAttrs ); } }
//
// Release the directory object interface.
//
pDsObj->Release(); }
return TRUE; }
LPTSTR TLocationPropertySheet:: ByteOffset( IN LPDSOBJECTNAMES pObject, IN UINT uOffset ) { return reinterpret_cast<LPTSTR>( reinterpret_cast<LPBYTE>( pObject ) + uOffset ); }
BOOL TLocationPropertySheet:: bHandleMessage( IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) { BOOL bRetval;
switch( uMsg ) { case WM_INITDIALOG: bRetval = Handle_InitDialog( wParam, lParam ); break;
case WM_COMMAND: bRetval = Handle_Command( wParam, lParam ); break;
case WM_NOTIFY: bRetval = Handle_Notify( wParam, lParam ); vSetDlgMsgResult( bRetval ); break;
case WM_HELP: bRetval = Handle_Help( uMsg, wParam, lParam ); break;
case WM_CONTEXTMENU: bRetval = Handle_Help( uMsg, wParam, lParam ); break;
default: bRetval = FALSE; break; }
return bRetval; }
BOOL TLocationPropertySheet:: Handle_InitDialog( IN WPARAM wParam, IN LPARAM lParam ) { TStatusB bStatus;
//
// Get the location property from the object. We ignore the return
// value because the Get will fail if the property is not set.
//
bStatus DBGCHK = _Ds.Get( _pDsObject, gszLocation, _strLocation );
//
//
// If we have write access then allow browsing the location tree,
// otherwise disable the button
//
if( (kPropertyAccessWrite != _PropertyAccess) || !TPhysicalLocation::bLocationEnabled() ) { EnableWindow( GetDlgItem(_hDlg, _uBrowseID), FALSE ); }
//
// Set the location text in the UI.
//
bStatus DBGCHK = bSetEditText( _hDlg, _uLocationEditID, _strLocation );
//
// If we only have read access to the location property then
// set the location edit control to read only.
//
if( _PropertyAccess == kPropertyAccessRead ) { SendDlgItemMessage( _hDlg, _uLocationEditID, EM_SETREADONLY, TRUE, 0); }
//
// Set the location limit text.
//
SendDlgItemMessage( _hDlg, _uLocationEditID, EM_SETLIMITTEXT, kPrinterLocationBufMax, 0 );
return TRUE; }
BOOL TLocationPropertySheet:: Handle_Help( IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) { PrintUIHelp( uMsg, _hDlg, wParam, lParam ); return TRUE; }
BOOL TLocationPropertySheet:: Handle_Command( IN WPARAM wParam, IN LPARAM lParam ) { BOOL bRetval = TRUE;
UINT uID = GET_WM_COMMAND_ID( wParam, lParam );
if( uID == _uLocationEditID ) { //
// If the user changed the text in the location edit control then
// enable the apply button.
//
if( GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE ) { PropSheet_Changed( GetParent( _hDlg ), _hDlg ); } } else if( uID == _uBrowseID ) { BrowseLocations (); } else { bRetval = FALSE; }
return bRetval; }
BOOL TLocationPropertySheet:: Handle_Notify( IN WPARAM wParam, IN LPARAM lParam ) { BOOL bRetval = TRUE; LPNMHDR pnmh = (LPNMHDR)lParam;
switch( pnmh->code ) { case PSN_APPLY: { DBGMSG( DBG_TRACE, ( "TLocationPropertySheet::Handle_Notify PSN_APPLY\n" ) ); LPPSHNOTIFY lppsn = (LPPSHNOTIFY )lParam;
TStatusB bStatus;
bStatus DBGNOCHK = TRUE;
//
// Check if we have write access, not much to do if we only have read access.
//
if( _PropertyAccess == kPropertyAccessWrite ) { UINT u, uLen; TString strLocation;
bStatus DBGCHK = bGetEditText( _hDlg, _uLocationEditID, strLocation );
// make all separators the same character
strLocation.bReplaceAll( TEXT('\\'), TEXT('/') );
StartOver: // remove the duplicated separators
uLen = strLocation.uLen(); for( u = 0; (u+1)<uLen; u++ ) { if( TEXT('/') == strLocation[u] && TEXT('/') == strLocation[u+1] ) { // duplicated separator - delete & start all over
strLocation.bDeleteChar(u); goto StartOver; } }
// remove the leading separator
uLen = strLocation.uLen(); if( uLen && TEXT('/') == strLocation[0] ) { strLocation.bDeleteChar(0); }
// remove the trailing separator
uLen = strLocation.uLen(); if( uLen && TEXT('/') == strLocation[uLen-1] ) { strLocation.bDeleteChar(uLen-1); }
if( _tcscmp( _strLocation, strLocation ) && bStatus ) { bStatus DBGCHK = _Ds.Put( _pDsObject, gszLocation, strLocation ); }
if (bStatus) { //
// DS put succeeded. Just save the last valid location.
//
_strLocation.bUpdate( strLocation );
//
// Since we may have modified the location - update UI.
//
bSetEditText( _hDlg, _uLocationEditID, strLocation ); } }
//
// Something failed let the user know.
//
if (!bStatus) { //
// If the lParam is true the OK/Close button was used to
// dismiss the dialog. Let the dialog exit in this case.
//
if( lppsn->lParam == TRUE ) { if( iMessage( _hDlg, IDS_ERR_LOCATION_PROP_TITLE, IDS_ERR_WANT_TO_EXIT, MB_YESNO|MB_ICONSTOP, kMsgNone, NULL ) == IDYES ) { bStatus DBGCHK = TRUE; } } else { iMessage( _hDlg, IDS_ERR_LOCATION_PROP_TITLE, IDS_ERR_GENERIC, MB_OK|MB_ICONSTOP, kMsgGetLastError, NULL ); } }
bRetval = bStatus ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE; break; }
default: { bRetval = FALSE; break; } }
return bRetval; }
BOOL TLocationPropertySheet:: GetObjectInterface( IN LPCTSTR strDsObject, IN OUT IADs **ppDsObject ) { //
// Get the adsi object interface pointer.
//
HRESULT hr = ADsOpenObject( const_cast<LPTSTR>( strDsObject ), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IADs, reinterpret_cast<LPVOID*>( ppDsObject ) );
return SUCCEEDED( hr ); }
BOOL TLocationPropertySheet:: GetDefaultSiteName( IN TString &strSiteName ) { TStatusB bStatus;
//
// Get the current objects site name. If the current
// object is a site object we just read the site name
//
if( !_tcsicmp( _strDsObjectClass, gszSite ) ) { bStatus DBGCHK = _Ds.Get( _pDsObject, gszName, strSiteName ); } else if ( !_tcsicmp( _strDsObjectClass, gszSubnet ) ) { //
// To get the default site name for a subnet object
// we need to build a path to the site object and read the
// the name property from the site.
//
TString strSiteObjectName;
bStatus DBGCHK = _Ds.Get( _pDsObject, gszSiteObject, strSiteObjectName );
if( bStatus ) { TString strSiteObjectPath; TString strLDAPPrefix;
//
// Build the site object path.
//
bStatus DBGCHK = _Ds.GetLDAPPrefix( strLDAPPrefix ) && strSiteObjectPath.bUpdate( strLDAPPrefix ) && strSiteObjectPath.bCat( strSiteObjectName );
if( bStatus ) { IADs *pDsSiteObject = NULL;
//
// Get the site object interface pointer.
//
bStatus DBGCHK = GetObjectInterface( strSiteObjectPath, &pDsSiteObject );
if( bStatus ) { //
// Read the site name from the site object.
//
bStatus DBGCHK = _Ds.Get( pDsSiteObject, gszName, strSiteName ); }
if( pDsSiteObject ) { pDsSiteObject->Release(); } } }
bStatus DBGNOCHK = FALSE; } else { bStatus DBGNOCHK = FALSE; }
return bStatus; }
VOID TLocationPropertySheet:: BrowseLocations( VOID ) { TFindLocDlg *pFindLocDlg = new TFindLocDlg(TFindLocDlg::kLocationShowHelp);
if( VALID_PTR(pFindLocDlg) ) { TString strLocation; TStatusB bStatus;
bGetEditText ( _hDlg, _uLocationEditID, strLocation );
bStatus DBGCHK = pFindLocDlg->bDoModal(_hDlg, &strLocation);
if (bStatus) { bStatus DBGCHK = pFindLocDlg->bGetLocation(strLocation);
if (bStatus && !strLocation.bEmpty()) { //
// Check to append a trailing slash
//
UINT uLen = strLocation.uLen(); if( uLen && gchSeparator != static_cast<LPCTSTR>(strLocation)[uLen-1] ) { static const TCHAR szSepStr[] = { gchSeparator }; bStatus DBGCHK = strLocation.bCat( szSepStr ); }
bStatus DBGCHK = bSetEditText( _hDlg, _uLocationEditID, strLocation ); } } }
if( pFindLocDlg ) { delete pFindLocDlg; } }
|