909 lines
23 KiB
C++
909 lines
23 KiB
C++
|
/*++
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
}
|