windows-nt/Source/XPSP1/NT/ds/adsi/winnt/cfpnwres.cxx
2020-09-26 16:20:57 +08:00

583 lines
14 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995
//
// File: cfpnwres.cxx
//
// Contents: Contains methods for the following objects
// CFPNWResource, CFPNWFSResourceGeneralInfo
//
//
// History: 05/01/96 ramv (Ram Viswanathan) Created.
//
//----------------------------------------------------------------------------
#include "winnt.hxx"
#pragma hdrstop
#define INITGUID
DECLARE_INFOLEVEL( FPNWResource );
DECLARE_DEBUG( FPNWResource );
#define FPNWResourceDebugOut(x) FPNWResourceInlineDebugOut x
DEFINE_IDispatch_ExtMgr_Implementation(CFPNWResource);
DEFINE_IADsExtension_ExtMgr_Implementation(CFPNWResource);
DEFINE_IADs_TempImplementation(CFPNWResource);
DEFINE_IADs_PutGetImplementation(CFPNWResource,FPNWResourceClass,gdwFPNWResourceTableSize) ;
DEFINE_IADsPropertyList_Implementation(CFPNWResource, FPNWResourceClass,gdwFPNWResourceTableSize)
CFPNWResource::CFPNWResource()
{
_pDispMgr = NULL;
_pExtMgr = NULL;
_pszServerName = NULL;
_pPropertyCache = NULL;
ENLIST_TRACKING(CFPNWResource);
return;
}
CFPNWResource::~CFPNWResource()
{
delete _pExtMgr; // created last, destroyed first
delete _pDispMgr;
if(_pszServerName){
FreeADsStr(_pszServerName);
}
delete _pPropertyCache;
return;
}
//+---------------------------------------------------------------------------
//
// Function: CFPNWResource::Create
//
// Synopsis: Static function used to create a Resource object. This
// will be called by EnumResources::Next
//
// Arguments: [ppFPNWResource] -- Ptr to a ptr to a new Resource object.
//
// Returns: HRESULT.
//
// Modifies:
//
// History: 12-11-95 RamV Created.
//
//----------------------------------------------------------------------------
HRESULT
CFPNWResource::Create(LPTSTR pszServerADsPath,
PNWFILEINFO pFileInfo,
DWORD dwObject,
REFIID riid,
CWinNTCredentials& Credentials,
LPVOID * ppvoid
)
{
CFPNWResource FAR * pCFPNWResource = NULL;
HRESULT hr;
TCHAR szFileName[MAX_LONG_LENGTH];
TCHAR szUncServerName[MAX_PATH];
hr =CFPNWResource::AllocateResourceObject(pszServerADsPath,
pFileInfo,
&pCFPNWResource );
BAIL_IF_ERROR(hr);
ADsAssert(pCFPNWResource->_pDispMgr);
//
// convert the FileId that we have into a string that we move
// into the Name field
//
_ltow(pFileInfo->dwFileId, szFileName, 10);
hr = pCFPNWResource->InitializeCoreObject(pszServerADsPath,
szFileName,
RESOURCE_CLASS_NAME,
FPNW_RESOURCE_SCHEMA_NAME,
CLSID_FPNWResource,
dwObject);
pCFPNWResource->_dwFileId = pFileInfo->dwFileId;
pCFPNWResource->_Credentials = Credentials;
hr = pCFPNWResource->_Credentials.RefServer(
pCFPNWResource->_pszServerName);
BAIL_IF_ERROR(hr);
hr = SetLPTSTRPropertyInCache(
pCFPNWResource->_pPropertyCache,
TEXT("Name"),
pCFPNWResource->_Name,
TRUE
);
BAIL_IF_ERROR(hr);
//
// Load ext mgr and extensions
//
hr = ADSILoadExtensionManager(
RESOURCE_CLASS_NAME,
(IADs* ) pCFPNWResource,
pCFPNWResource->_pDispMgr,
Credentials,
&pCFPNWResource->_pExtMgr
);
BAIL_IF_ERROR(hr);
ADsAssert(pCFPNWResource->_pExtMgr);
// check if the call is from UMI
if(Credentials.GetFlags() & ADS_AUTH_RESERVED) {
//
// we do not pass riid to InitUmiObject below. This is because UMI object
// does not support IDispatch. There are several places in ADSI code where
// riid passed into this function is defaulted to IID_IDispatch -
// IADsContainer::Create for example. To handle these cases, we always
// request IID_IUnknown from the UMI object. Subsequent code within UMI
// will QI for the appropriate interface.
//
// Resource objects have "" as their ADsPath. Just set the class to
// resource for identification purposes.
pCFPNWResource->_CompClasses[0] = L"Resource";
hr = pCFPNWResource->InitUmiObject(
pCFPNWResource->_Credentials,
FPNWResourceClass,
gdwFPNWResourceTableSize,
pCFPNWResource->_pPropertyCache,
(IUnknown *) (INonDelegatingUnknown *) pCFPNWResource,
pCFPNWResource->_pExtMgr,
IID_IUnknown,
ppvoid
);
BAIL_IF_ERROR(hr);
//
// UMI object was created and the interface was obtained successfully.
// UMI object now has a reference to the inner unknown of IADs, since
// the call to Release() below is not going to be made in this case.
//
RRETURN(hr);
}
ADsAssert(ppvoid);
hr = pCFPNWResource->QueryInterface(riid, (void **)ppvoid);
BAIL_IF_ERROR(hr);
pCFPNWResource->Release();
RRETURN(hr);
cleanup:
if(SUCCEEDED(hr)){
RRETURN(hr);
}
delete pCFPNWResource;
RRETURN_EXP_IF_ERR(hr);
}
HRESULT
CFPNWResource::AllocateResourceObject(LPTSTR pszServerADsPath,
PNWFILEINFO pFileInfo,
CFPNWResource ** ppResource)
{
CFPNWResource FAR * pCFPNWResource = NULL;
HRESULT hr;
TCHAR szFileName[MAX_LONG_LENGTH];
TCHAR szUncServerName[MAX_PATH];
POBJECTINFO pServerObjectInfo = NULL;
//
// Create the Resource Object
//
pCFPNWResource = new CFPNWResource();
if (pCFPNWResource == NULL) {
hr = E_OUTOFMEMORY;
goto cleanup;
}
pCFPNWResource->_pDispMgr = new CAggregatorDispMgr;
if(pCFPNWResource ->_pDispMgr == NULL){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = LoadTypeInfoEntry(pCFPNWResource->_pDispMgr,
LIBID_ADs,
IID_IADsResource,
(IADsResource *)pCFPNWResource,
DISPID_REGULAR);
BAIL_IF_ERROR(hr);
hr = LoadTypeInfoEntry(pCFPNWResource->_pDispMgr,
LIBID_ADs,
IID_IADsPropertyList,
(IADsPropertyList *)pCFPNWResource,
DISPID_VALUE);
BAIL_IF_ERROR(hr);
pCFPNWResource->_pszServerADsPath =
AllocADsStr(pszServerADsPath);
if(!(pCFPNWResource->_pszServerADsPath)){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = BuildObjectInfo(pszServerADsPath,
&pServerObjectInfo);
BAIL_IF_ERROR(hr);
pCFPNWResource->_pszServerName =
AllocADsStr(pServerObjectInfo->ComponentArray[1]);
if(!(pCFPNWResource->_pszServerName)){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = CPropertyCache::createpropertycache(
FPNWResourceClass,
gdwFPNWResourceTableSize,
(CCoreADsObject *)pCFPNWResource,
&(pCFPNWResource->_pPropertyCache)
);
hr = SetLPTSTRPropertyInCache(pCFPNWResource->_pPropertyCache,
TEXT("User"),
pFileInfo->lpUserName,
TRUE
);
BAIL_IF_ERROR(hr);
hr = ADsAllocString(pFileInfo->lpUserName,
&(pCFPNWResource->_pszUserName));
BAIL_IF_ERROR(hr);
hr = SetLPTSTRPropertyInCache(pCFPNWResource->_pPropertyCache,
TEXT("Path"),
pFileInfo->lpPathName,
TRUE
);
BAIL_IF_ERROR(hr);
pCFPNWResource->_pszPath =
AllocADsStr(pFileInfo->lpPathName);
if(!(pCFPNWResource->_pszPath)){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = SetDWORDPropertyInCache(pCFPNWResource->_pPropertyCache,
TEXT("LockCount"),
pFileInfo->dwLocks,
TRUE
);
pCFPNWResource->_dwLockCount = pFileInfo->dwLocks;
pCFPNWResource->_pDispMgr->RegisterPropertyCache(
pCFPNWResource->_pPropertyCache
);
*ppResource = pCFPNWResource;
cleanup:
if(pServerObjectInfo){
FreeObjectInfo(pServerObjectInfo);
}
if (!SUCCEEDED(hr)) {
//
// direct memeber assignement assignement at pt of creation, so
// do NOT delete _pPropertyCache or _pDisMgr here to avoid attempt
// of deletion again in pPrintJob destructor and AV
//
delete pCFPNWResource;
}
RRETURN(hr);
}
/* IUnknown methods for Resource object */
//----------------------------------------------------------------------------
// Function: QueryInterface
//
// Synopsis: If this object is aggregated within another object, then
// all calls will delegate to the outer object. Otherwise, the
// non-delegating QI is called
//
// Arguments:
//
// iid interface requested
// ppInterface Returns pointer to interface requested. NULL if interface
// is not supported.
//
// Returns: S_OK on success. Error code otherwise.
//
// Modifies: *ppInterface to return interface pointer
//
//----------------------------------------------------------------------------
STDMETHODIMP CFPNWResource::QueryInterface(
REFIID iid,
LPVOID *ppInterface
)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->QueryInterface(
iid,
ppInterface
));
RRETURN(NonDelegatingQueryInterface(
iid,
ppInterface
));
}
//----------------------------------------------------------------------------
// Function: AddRef
//
// Synopsis: IUnknown::AddRef. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating AddRef is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CFPNWResource::AddRef(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->AddRef());
RRETURN(NonDelegatingAddRef());
}
//----------------------------------------------------------------------------
// Function: Release
//
// Synopsis: IUnknown::Release. If this object is aggregated within
// another, all calls will delegate to the outer object.
// Otherwise, the non-delegating Release is called
//
// Arguments:
//
// None
//
// Returns: New reference count
//
// Modifies: Nothing
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CFPNWResource::Release(void)
{
if(_pUnkOuter != NULL)
RRETURN(_pUnkOuter->Release());
RRETURN(NonDelegatingRelease());
}
//----------------------------------------------------------------------------
STDMETHODIMP
CFPNWResource::NonDelegatingQueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
HRESULT hr = S_OK;
if(ppvObj == NULL){
RRETURN(E_POINTER);
}
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IADs *) this;
}
else if (IsEqualIID(riid, IID_IDispatch))
{
*ppvObj = (IADs *)this;
}
else if (IsEqualIID(riid, IID_ISupportErrorInfo))
{
*ppvObj = (ISupportErrorInfo FAR *) this;
}
else if (IsEqualIID(riid, IID_IADs))
{
*ppvObj = (IADs FAR *) this;
}
else if (IsEqualIID(riid, IID_IADsPropertyList))
{
*ppvObj = (IADsPropertyList FAR *) this;
}
else if (IsEqualIID(riid, IID_IADsResource))
{
*ppvObj = (IADsResource FAR *) this;
}
else if( (_pDispatch != NULL) &&
IsEqualIID(riid, IID_IADsExtension) )
{
*ppvObj = (IADsExtension *) this;
}
else if (_pExtMgr)
{
RRETURN( _pExtMgr->QueryInterface(riid, ppvObj));
}
else
{
*ppvObj = NULL;
RRETURN(E_NOINTERFACE);
}
((LPUNKNOWN)*ppvObj)->AddRef();
RRETURN(S_OK);
}
/* ISupportErrorInfo method */
STDMETHODIMP
CFPNWResource::InterfaceSupportsErrorInfo(
THIS_ REFIID riid
)
{
if (IsEqualIID(riid, IID_IADs) ||
IsEqualIID(riid, IID_IADsResource) ||
IsEqualIID(riid, IID_IADsPropertyList)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
/* IADs methods */
//+-----------------------------------------------------------------
//
// Function: SetInfo
//
// Synopsis: SetInfo on actual Resource
//
// Arguments: void
//
// Returns: HRESULT.
//
// Modifies:
//
// History: 02/08/96 RamV Created
//----------------------------------------------------------------------------
STDMETHODIMP
CFPNWResource::SetInfo(THIS)
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CFPNWResource::GetInfo(THIS)
{
_pPropertyCache->flushpropcache();
RRETURN(S_OK);
}
STDMETHODIMP
CFPNWResource::ImplicitGetInfo(THIS)
{
RRETURN(S_OK);
}
STDMETHODIMP
CFPNWResource::get_User(THIS_ BSTR FAR* retval)
{
HRESULT hr;
if(!retval){
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
}
hr = ADsAllocString(_pszUserName, retval);
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CFPNWResource::get_UserPath(THIS_ BSTR FAR* retval)
{
RRETURN_EXP_IF_ERR(E_ADS_PROPERTY_NOT_SUPPORTED);
}
STDMETHODIMP
CFPNWResource::get_Path(THIS_ BSTR FAR* retval)
{
HRESULT hr;
if(!retval){
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
}
hr = ADsAllocString(_pszPath, retval);
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CFPNWResource::get_LockCount(THIS_ LONG FAR* retval)
{
if(!retval){
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
}
*retval = _dwLockCount;
RRETURN(S_OK);
}