|
|
#ifndef _ADM_COIMP_
#define _ADM_COIMP_
#include "connect.h"
#include "sink.hxx"
#include "admacl.hxx"
//
// Handle mapping table structure
//
#define HASHSIZE 5
#define INVALID_ADMINHANDLE_VALUE 0xFFFFFFFF
//
// How long to wait getting a handle before saving
// Wait a long time, as we want a safe save
//
#define DEFAULT_SAVE_TIMEOUT 5000
//
// Period to sleep while waiting for service to attain desired state
//
#define SLEEP_INTERVAL (500L)
//
// Maximum time to wait for service to attain desired state
//
#define MAX_SLEEP (180000) // For a service
#define IS_MD_PATH_DELIM(a) ((a)==L'/' || (a)==L'\\')
#define SERVICE_START_MAX_POLL 30
#define SERVICE_START_POLL_DELAY 1000
typedef struct _HANDLE_TABLE { struct _HANDLE_TABLE *next; // next entry
METADATA_HANDLE hAdminHandle; // admin handle value
METADATA_HANDLE hActualHandle; // actual handle value
COpenHandle *pohHandle;
} HANDLE_TABLE, *LPHANDLE_TABLE, *PHANDLE_TABLE;
class CADMCOMSrvFactoryW : public IClassFactory { public:
CADMCOMSrvFactoryW(); ~CADMCOMSrvFactoryW();
STDMETHODIMP QueryInterface( REFIID riid, void **ppObject);
STDMETHODIMP_(ULONG) AddRef( VOID );
STDMETHODIMP_(ULONG) Release( VOID );
STDMETHODIMP CreateInstance( IUnknown *pUnkOuter, REFIID riid, void **pObject);
STDMETHODIMP LockServer( BOOL fLock);
private:
ULONG m_dwRefCount; };
class CADMCOMW : public IMSAdminBase3W { public:
CADMCOMW(); ~CADMCOMW();
STDMETHODIMP AddKey( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath);
STDMETHODIMP DeleteKey( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath);
STDMETHODIMP DeleteChildKeys( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath);
STDMETHODIMP EnumKeys( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [size_is][out] */ LPWSTR pszMDName, /* [in] */ DWORD dwMDEnumObjectIndex);
STDMETHODIMP CopyKey( /* [in] */ METADATA_HANDLE hMDSourceHandle, /* [string][in][unique] */ LPCWSTR pszMDSourcePath, /* [in] */ METADATA_HANDLE hMDDestHandle, /* [string][in][unique] */ LPCWSTR pszMDDestPath, /* [in] */ BOOL bMDOverwriteFlag, /* [in] */ BOOL bMDCopyFlag);
STDMETHODIMP RenameKey( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [string][in][unique] */ LPCWSTR pszMDNewName);
STDMETHODIMP SetData( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ PMETADATA_RECORD pmdrMDData);
STDMETHODIMP GetData( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [out][in] */ PMETADATA_RECORD pmdrMDData, /* [out] */ DWORD *pdwMDRequiredDataLen);
STDMETHODIMP DeleteData( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDIdentifier, /* [in] */ DWORD dwMDDataType);
STDMETHODIMP EnumData( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [out][in] */ PMETADATA_RECORD pmdrMDData, /* [in] */ DWORD dwMDEnumDataIndex, /* [out] */ DWORD *pdwMDRequiredDataLen);
STDMETHODIMP GetAllData( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDAttributes, /* [in] */ DWORD dwMDUserType, /* [in] */ DWORD dwMDDataType, /* [out] */ DWORD *pdwMDNumDataEntries, /* [out] */ DWORD *pdwMDDataSetNumber, /* [in] */ DWORD dwMDBufferSize, /* [size_is][out] */ unsigned char *pbMDBuffer, /* [out] */ DWORD *pdwMDRequiredBufferSize);
STDMETHODIMP DeleteAllData( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDUserType, /* [in] */ DWORD dwMDDataType);
STDMETHODIMP CopyData( /* [in] */ METADATA_HANDLE hMDSourceHandle, /* [string][in][unique] */ LPCWSTR pszMDSourcePath, /* [in] */ METADATA_HANDLE hMDDestHandle, /* [string][in][unique] */ LPCWSTR pszMDDestPath, /* [in] */ DWORD dwMDAttributes, /* [in] */ DWORD dwMDUserType, /* [in] */ DWORD dwMDDataType, /* [in] */ BOOL bMDCopyFlag);
STDMETHODIMP GetDataPaths( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDIdentifier, /* [in] */ DWORD dwMDDataType, /* [in] */ DWORD dwMDBufferSize, /* [size_is][out] */ LPWSTR pszBuffer, /* [out] */ DWORD *pdwMDRequiredBufferSize);
STDMETHODIMP OpenKey( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDAccessRequested, /* [in] */ DWORD dwMDTimeOut, /* [out] */ PMETADATA_HANDLE phMDNewHandle);
STDMETHODIMP CloseKey( /* [in] */ METADATA_HANDLE hMDHandle);
STDMETHODIMP ChangePermissions( /* [in] */ METADATA_HANDLE hMDHandle, /* [in] */ DWORD dwMDTimeOut, /* [in] */ DWORD dwMDAccessRequested);
STDMETHODIMP SaveData( VOID );
STDMETHODIMP GetHandleInfo( /* [in] */ METADATA_HANDLE hMDHandle, /* [out] */ PMETADATA_HANDLE_INFO pmdhiInfo);
STDMETHODIMP GetSystemChangeNumber( /* [out] */ DWORD *pdwSystemChangeNumber);
STDMETHODIMP GetDataSetNumber( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [out] */ DWORD *pdwMDDataSetNumber);
STDMETHODIMP SetLastChangeTime( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ PFILETIME pftMDLastChangeTime, /* [in] */ BOOL bLocalTime);
STDMETHODIMP GetLastChangeTime( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [out] */ PFILETIME pftMDLastChangeTime, /* [in] */ BOOL bLocalTime);
STDMETHODIMP NotifySinks( /* [in] */ METADATA_HANDLE hMDHandle, /* [in] */ DWORD dwMDNumElements, /* [size_is][in] */ MD_CHANGE_OBJECT_W pcoChangeList[], /* [in] */ BOOL bIsMainNotification);
STDMETHODIMP KeyExchangePhase1( VOID ); STDMETHODIMP KeyExchangePhase2( VOID );
STDMETHODIMP Backup( /* [string][in][unique] */ LPCWSTR pszMDBackupLocation, /* [in] */ DWORD dwMDVersion, /* [in] */ DWORD dwMDFlags);
STDMETHODIMP Restore( /* [string][in][unique] */ LPCWSTR pszMDBackupLocation, /* [in] */ DWORD dwMDVersion, /* [in] */ DWORD dwMDFlags);
STDMETHODIMP BackupWithPasswd( /* [string][in][unique] */ LPCWSTR pszMDBackupLocation, /* [in] */ DWORD dwMDVersion, /* [in] */ DWORD dwMDFlags, /* [string][in][unique] */ LPCWSTR pszPasswd);
STDMETHODIMP RestoreWithPasswd( /* [string][in][unique] */ LPCWSTR pszMDBackupLocation, /* [in] */ DWORD dwMDVersion, /* [in] */ DWORD dwMDFlags, /* [string][in][unique] */ LPCWSTR pszPasswd);
STDMETHODIMP EnumBackups( /* [size_is][out][in] */ LPWSTR pszMDBackupLocation, /* [out] */ DWORD *pdwMDVersion, /* [out] */ PFILETIME pftMDBackupTime, /* [in] */ DWORD dwMDEnumIndex);
STDMETHODIMP DeleteBackup( /* [string][in][unique] */ LPCWSTR pszMDBackupLocation, /* [in] */ DWORD dwMDVersion);
STDMETHODIMP Export( /* [string][in][unique] */ LPCWSTR pszPasswd, /* [string][in][unique] */ LPCWSTR pszFileName, /* [string][in][unique] */ LPCWSTR pszSourcePath, /* [in] */ DWORD dwMDFlags);
STDMETHODIMP Import( /* [string][in][unique] */ LPCWSTR pszPasswd, /* [string][in][unique] */ LPCWSTR pszFileName, /* [string][in][unique] */ LPCWSTR pszSourcePath, /* [string][in][unique] */ LPCWSTR pszDestPath, /* [in] */ DWORD dwMDFlags);
STDMETHODIMP RestoreHistory( /* [unique][in][string] */ LPCWSTR pszMDHistoryLocation, /* [in] */ DWORD dwMDMajorVersion, /* [in] */ DWORD dwMDMinorVersion, /* [in] */ DWORD dwMDFlags);
STDMETHODIMP EnumHistory( /* [size_is][out][in] */ LPWSTR pszMDHistoryLocation, /* [out] */ DWORD *pdwMDMajorVersion, /* [out] */ DWORD *pdwMDMinorVersion, /* [out] */ PFILETIME pftMDHistoryTime, /* [in] */ DWORD dwMDEnumIndex);
/* IMSAdminBase3W methods */
STDMETHODIMP GetChildPaths( /* [in] */ METADATA_HANDLE hMDHandle, /* [unique, in, string] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDBufferSize, /* [out, size_is(dwMDBufferSize)] */ WCHAR *pszBuffer, /* [out] */ DWORD *pdwMDRequiredBufferSize);
STDMETHODIMP UnmarshalInterface( /* [out] */ IMSAdminBaseW **piadmbwInterface);
STDMETHODIMP GetServerGuid( VOID );
STDMETHODIMP QueryInterface( REFIID riid, void **ppObject);
STDMETHODIMP_(ULONG) AddRef( VOID );
STDMETHODIMP_(ULONG) Release( VOID );
//
// Internal Use members
//
HRESULT AddNode( METADATA_HANDLE hActualHandle, COpenHandle *pohParentHandle, PMETADATA_HANDLE phAdminHandle, LPCWSTR pszPath);
HRESULT AddKeyHelper( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath);
HRESULT OpenKeyHelper( /* [in] */ METADATA_HANDLE hMDHandle, /* [string][in][unique] */ LPCWSTR pszMDPath, /* [in] */ DWORD dwMDAccessRequested, /* [in] */ DWORD dwMDTimeOut, /* [out] */ PMETADATA_HANDLE phMDNewHandle);
DWORD Lookup( IN METADATA_HANDLE hHandle, OUT METADATA_HANDLE *phActHandle, OUT COpenHandle **pphoHandle = NULL);
HRESULT LookupAndAccessCheck( IN METADATA_HANDLE hHandle, OUT METADATA_HANDLE *phActualHandle, IN LPCWSTR pszPath, IN DWORD dwId, // check for MD_ADMIN_ACL, must have special right to write them
IN DWORD dwAccess, // METADATA_PERMISSION_*
OUT LPBOOL pfEnableSecureAccess = NULL);
VOID DisableAllHandles( VOID );
DWORD IsReadAccessGranted( METADATA_HANDLE hHandle, LPWSTR pszPath, METADATA_RECORD* pmdRecord);
DWORD FindClosestProp( METADATA_HANDLE hHandle, LPWSTR pszRelPathIndex, LPWSTR* ppszAclPath, DWORD dwPropId, DWORD dwDataType, DWORD dwUserType, DWORD dwAttr, BOOL fSkipCurrentNode);
DWORD LookupActualHandle( IN METADATA_HANDLE hHandle);
DWORD DeleteNode( IN METADATA_HANDLE hHandle);
VOID SetStatus( HRESULT hRes) { m_hRes = hRes; }
HRESULT GetStatus( VOID ) { return m_hRes; }
static VOID ShutDownObjects( VOID );
static VOID InitObjectList( VOID );
static VOID TerminateObjectList( VOID );
private:
IUnknown *m_piuFTM; IMDCOM2* m_pMdObject; IMDCOM3* m_pMdObject3;
volatile ULONG m_dwRefCount; DWORD m_dwHandleValue; // last handle value used
HANDLE_TABLE *m_hashtab[HASHSIZE]; // handle table
CImpIMDCOMSINKW *m_pEventSink; IConnectionPoint *m_pConnPoint; DWORD m_dwCookie; BOOL m_bTerminated; BOOL m_bIsTerminateRoutineComplete;
HRESULT m_hRes;
//
// Keep a global list of these objects around to allow us to
// cleanup during shutdown.
//
VOID AddObjectToList( VOID );
BOOL RemoveObjectFromList( BOOL bIgnoreShutdown = FALSE);
static VOID GetObjectListLock( VOID ) { EnterCriticalSection( &sm_csObjectListLock ); }
static VOID ReleaseObjectListLock( VOID ) { LeaveCriticalSection( &sm_csObjectListLock ); }
LIST_ENTRY m_ObjectListEntry;
static LIST_ENTRY sm_ObjectList;
static CRITICAL_SECTION sm_csObjectListLock; static BOOL sm_fShutdownInProgress;
static DWORD sm_dwProcessIdThis; static DWORD sm_dwProcessIdRpcSs; DWORD m_dwProcessIdCaller; HANDLE m_hProcessCaller; HANDLE m_hWaitCaller; DWORD m_dwThreadIdDisconnect;
static PTRACE_LOG sm_pDbgRefTraceLog;
public: HRESULT RemoveAllPendingNotifications( BOOL fWaitForCurrent);
private: HRESULT StopNotifications( BOOL fRemoveAllPending);
VOID Terminate( VOID );
VOID ForceTerminate( VOID );
HRESULT InitializeCallerWatch(VOID);
HRESULT ShutdownCallerWatch(VOID);
BOOL IsCallerWatchInitialized( VOID ) { return ( m_dwProcessIdCaller != 0 ); }
HRESULT DisconnectOrphaned(VOID);
static VOID CALLBACK CallerWatchWaitOrTimerCallback( PVOID lpParameter, // thread data
BOOLEAN TimerOrWaitFired); // reason
public: static HRESULT GetPids(VOID);
private: // ImpExp
class CImpExpHelp : public IMSImpExpHelpW { public: CImpExpHelp(); virtual ~CImpExpHelp(); VOID Init(CADMCOMW *);
// IUnknown methods.
STDMETHODIMP QueryInterface( REFIID , PPVOID );
STDMETHODIMP_(ULONG) AddRef( VOID );
STDMETHODIMP_(ULONG) Release( VOID );
STDMETHODIMP EnumeratePathsInFile( /* [unique, in, string] */ LPCWSTR pszFileName, /* [unique, in, string] */ LPCWSTR pszKeyType, /* [in] */ DWORD dwMDBufferSize, /* [out, size_is(dwMDBufferSize)] */ WCHAR *pszBuffer, /* [out] */ DWORD *pdwMDRequiredBufferSize);
private: IUnknown *m_pUnkOuter; // Outer unknown for Delegation.
};
friend CImpExpHelp; CImpExpHelp m_ImpExpHelp;
//
// synchronization to manipulate the handle table
//
CReaderWriterLock3 m_LockHandleResource;
class CImpIConnectionPointContainer : public IConnectionPointContainer { public:
// Interface Implementation Constructor & Destructor.
CImpIConnectionPointContainer();
virtual ~CImpIConnectionPointContainer();
VOID Init( CADMCOMW *);
// IUnknown methods.
STDMETHODIMP QueryInterface( REFIID , PPVOID );
STDMETHODIMP_(ULONG) AddRef( VOID );
STDMETHODIMP_(ULONG) Release( VOID );
// IConnectionPointContainer methods.
STDMETHODIMP FindConnectionPoint( REFIID , IConnectionPoint** );
STDMETHODIMP EnumConnectionPoints( IEnumConnectionPoints **);
private: // Data private to this interface implementation.
CADMCOMW *m_pBackObj; // Parent Object back pointer.
IUnknown *m_pUnkOuter; // Outer unknown for Delegation.
};
friend CImpIConnectionPointContainer; // Nested IConnectionPointContainer implementation instantiation.
CImpIConnectionPointContainer m_ImpIConnectionPointContainer;
// The array of connection points for this connectable COM object.
COConnectionPoint m_ConnectionPoint;
BOOL CheckGetAttributes( DWORD dwAttributes);
HRESULT BackupHelper( LPCWSTR pszMDBackupLocation, DWORD dwMDVersion, DWORD dwMDFlags, LPCWSTR pszPasswd = NULL);
HRESULT RestoreHelper( LPCWSTR pszMDBackupLocation, DWORD dwMDVersion, DWORD dwMDMinorVersion, LPCWSTR pszPasswd, DWORD dwMDFlags, DWORD dwRestoreType);
HRESULT EnumAndStopDependentServices( DWORD *pcServices, BUFFER *pbufDependentServices);
HRESULT StartDependentServices( DWORD cServices, ENUM_SERVICE_STATUS *pessDependentServices);
HRESULT SetHistoryAndEWR( DWORD dwEnableHistory, DWORD dwEnableEWR);
HRESULT DisableHistory( DWORD *pdwEnableHistoryOld, DWORD *pdwEnableEWROld);
HRESULT NotifySinkHelper( IUnknown *pUnk, DWORD dwMDNumElements, MD_CHANGE_OBJECT_W pcoChangeList[], BOOL bIsMainNotification);
public: HRESULT NotifySinksAsync( /* [in] */ DWORD dwMDNumElements, /* [size_is][in] */ MD_CHANGE_OBJECT_W pcoChangeList[], /* [in] */ BOOL bIsMainNotification); };
VOID WaitForServiceStatus( SC_HANDLE schDependent, DWORD dwDesiredServiceState);
const DWORD NOTIFY_CONTEXT_SIGNATURE = ((DWORD) 'XTCN'); const DWORD NOTIFY_CONTEXT_SIGNATURE_FREE = ((DWORD) 'xTCN');
class NOTIFY_CONTEXT { private: DWORD _dwSignature; CADMCOMW *_pCADMCOMW; DWORD _dwMDNumElements; MD_CHANGE_OBJECT_W *_pcoChangeList; BOOL _bIsMainNotification; LIST_ENTRY _listEntry;
public: static HRESULT CreateNewContext( CADMCOMW *pCADMCOMW, METADATA_HANDLE hMDHandle, DWORD dwMDNumElements, MD_CHANGE_OBJECT_W *pcoChangeList, BOOL bIsMainNotification);
static VOID RemoveWorkFor( CADMCOMW *pCADMCOMW, BOOL fWaitForCurrent);
static VOID RemoveAllWork( VOID );
static HRESULT Initialize( VOID );
static VOID Terminate( VOID );
private: NOTIFY_CONTEXT(); ~NOTIFY_CONTEXT();
BOOL CheckSignature( VOID ) { return NOTIFY_CONTEXT_SIGNATURE == _dwSignature; }
static NOTIFY_CONTEXT * NOTIFY_CONTEXTFromListEntry( PLIST_ENTRY ple) { NOTIFY_CONTEXT *pContext = CONTAINING_RECORD(ple, NOTIFY_CONTEXT, _listEntry);
DBG_ASSERT(pContext->CheckSignature());
return pContext; }
static NOTIFY_CONTEXT * s_pCurrentlyWorkingOn; static CReaderWriterLock3 s_LockCurrentlyWorkingOn;
static LIST_ENTRY s_listEntry; static CRITICAL_SECTION s_critSec; static BOOL s_fInitializedCritSec; static HANDLE s_hShutdown; static HANDLE s_hDataAvailable; static HANDLE s_hThread; static DWORD s_dwThreadId;
static DWORD WINAPI NotifyThreadProc( LPVOID lpParameter ); static HRESULT GetNextContext(NOTIFY_CONTEXT ** ppContext); };
HRESULT MakePathCanonicalizationProof( IN LPCWSTR pwszName, IN BOOL fResolve, OUT STRAU *pstrPath);
#endif
|