Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

804 lines
20 KiB

/******************************************************************
DfsReplica.CPP -- WMI provider class implementation
Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
DESCRIPTION DFS Provider
******************************************************************/
#include "precomp.h"
#include <computerAPI.h>
CDfsReplica MyCDFSReplicaSet (
PROVIDER_NAME_DFSREPLICA ,
Namespace
) ;
/*****************************************************************************
*
* FUNCTION : CDfsReplica::CDfsReplica
*
* DESCRIPTION : Constructor
*
*****************************************************************************/
CDfsReplica :: CDfsReplica (
LPCWSTR lpwszName,
LPCWSTR lpwszNameSpace
) : Provider ( lpwszName , lpwszNameSpace )
{
m_ComputerName = GetLocalComputerName();
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::~CDfsReplica
*
* DESCRIPTION : Destructor
*
*****************************************************************************/
CDfsReplica :: ~CDfsReplica ()
{
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::EnumerateInstances
*
* DESCRIPTION : Returns all the instances of this class.
*
*****************************************************************************/
HRESULT CDfsReplica :: EnumerateInstances (
MethodContext *pMethodContext,
long lFlags
)
{
HRESULT hRes = WBEM_S_NO_ERROR ;
DWORD dwPropertiesReq = DFSREPLICA_ALL_PROPS;
hRes = EnumerateAllReplicas ( pMethodContext, dwPropertiesReq );
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::GetObject
*
* DESCRIPTION : Find a single instance based on the key properties for the
* class.
*
*****************************************************************************/
HRESULT CDfsReplica :: GetObject (
CInstance *pInstance,
long lFlags,
CFrameworkQuery& Query
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
DWORD dwPropertiesReq = 0;
CHString t_Link ;
CHString t_Server;
CHString t_Share;
hRes = GetKeys(pInstance, t_Link, t_Server, t_Share);
if ( SUCCEEDED ( hRes ) )
{
if ( Query.AllPropertiesAreRequired() )
{
dwPropertiesReq = DFSREPLICA_ALL_PROPS;
}
else
{
if ( Query.IsPropertyRequired ( LINKNAME ) )
{
dwPropertiesReq |= DFSREPLICA_PROP_LinkName;
}
if ( Query.IsPropertyRequired ( SERVERNAME ) )
{
dwPropertiesReq |= DFSREPLICA_PROP_ServerName;
}
if ( Query.IsPropertyRequired ( SHARENAME ) )
{
dwPropertiesReq |= DFSREPLICA_PROP_ShareName;
}
if ( Query.IsPropertyRequired ( STATE ) )
{
dwPropertiesReq |= DFSREPLICA_PROP_State;
}
}
bool bRoot = false;
hRes = FindAndSetDfsReplica ( t_Link, t_Server, t_Share, dwPropertiesReq, pInstance, eGet, bRoot );
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::PutInstance
*
* DESCRIPTION : PutInstance should be used in provider classes that can
* write instance information back to the hardware or
* software. For example: Win32_Environment will allow a
* PutInstance to create or update an environment variable.
* However, a class like MotherboardDevice will not allow
* editing of the number of slots, since it is difficult for
* a provider to affect that number.
*
*****************************************************************************/
HRESULT CDfsReplica :: PutInstance (
const CInstance &Instance,
long lFlags
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
DWORD dwPropertiesReq = 0;
CHString t_Link ;
CHString t_Server;
CHString t_Share;
bool bRoot = false;
// Get the Compound Key
hRes = GetKeys(&Instance, t_Link, t_Server, t_Share);
if ( SUCCEEDED ( hRes ) )
{
hRes = FindAndSetDfsReplica ( t_Link, t_Server, t_Share, dwPropertiesReq, NULL, eAdd, bRoot );
}
bool bFound;
if (SUCCEEDED(hRes))
{
bFound = true;
}
else if (hRes == WBEM_E_NOT_FOUND)
{
bFound = false;
hRes = WBEM_S_NO_ERROR;
}
if (SUCCEEDED(hRes))
{
DWORD dwOperationsReq = (WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_CREATE_ONLY | WBEM_FLAG_UPDATE_ONLY);
switch ( lFlags & dwOperationsReq )
{
case WBEM_FLAG_CREATE_OR_UPDATE:
{
if (bFound)
{
hRes = WBEM_E_INVALID_PARAMETER;
}
else
{
if (NetDfsAdd (
t_Link.GetBuffer ( 0 ),
t_Server.GetBuffer ( 0 ),
t_Share.GetBuffer ( 0 ),
L"",
0
) == NERR_Success)
{
hRes = WBEM_S_NO_ERROR;
}
else
{
hRes = WBEM_E_FAILED;
}
}
break;
}
case WBEM_FLAG_CREATE_ONLY:
{
if (!bFound)
{
if (NetDfsAdd (
t_Link.GetBuffer ( 0 ),
t_Server.GetBuffer ( 0 ),
t_Share.GetBuffer ( 0 ),
L"",
0
) == NERR_Success)
{
hRes = WBEM_S_NO_ERROR;
}
else
{
hRes = WBEM_E_FAILED;
}
}
else
{
hRes = WBEM_E_ALREADY_EXISTS;
}
break;
}
default:
{
hRes = WBEM_E_INVALID_PARAMETER;
}
}
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::DeleteInstance
*
* DESCRIPTION : DeleteInstance, like PutInstance, actually writes information
* to the software or hardware. For most hardware devices,
* DeleteInstance should not be implemented, but for software
* configuration, DeleteInstance implementation is plausible.
*
*****************************************************************************/
HRESULT CDfsReplica :: DeleteInstance (
const CInstance &Instance,
long lFlags
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
DWORD dwPropertiesReq = 0;
CHString t_Link ;
CHString t_Server;
CHString t_Share;
bool bRoot = false;
// Get the Compound Key
hRes = GetKeys(&Instance, t_Link, t_Server, t_Share);
if ( SUCCEEDED ( hRes ) )
{
hRes = FindAndSetDfsReplica ( t_Link, t_Server, t_Share, dwPropertiesReq, NULL, eDelete, bRoot );
}
if ( SUCCEEDED ( hRes ) )
{
NET_API_STATUS t_Status = NERR_Success;
if (!bRoot)
{
t_Status = NetDfsRemove(
t_Link.GetBuffer(0),
t_Server.GetBuffer(0),
t_Share.GetBuffer(0)
);
if ( t_Status != NERR_Success )
{
hRes = WBEM_E_FAILED;
}
}
else
{
wchar_t *pEntryPath = t_Link.GetBuffer(0);
if ((wcslen(pEntryPath) > 4) &&
(pEntryPath[0] == pEntryPath[1]) &&
(pEntryPath[0] == L'\\'))
{
wchar_t *pSlash = wcschr(&(pEntryPath[2]), L'\\');
if (pSlash > &(pEntryPath[2]))
{
wchar_t *pServer = new wchar_t[pSlash - &(pEntryPath[2]) + 1];
BOOL bRemove = FALSE;
try
{
wcsncpy(pServer, &(pEntryPath[2]), pSlash - &(pEntryPath[2]));
pServer[pSlash - &(pEntryPath[2])] = L'\0';
if (0 == m_ComputerName.CompareNoCase(pServer))
{
bRemove = TRUE;
}
else
{
DWORD dwDnsName = 256;
DWORD dwDnsNameSize = 256;
wchar_t *pDnsName = new wchar_t[dwDnsName];
try
{
while (!ProviderGetComputerNameEx(ComputerNamePhysicalDnsHostname, pDnsName, &dwDnsName))
{
if (GetLastError() != ERROR_MORE_DATA)
{
delete [] pDnsName;
pDnsName = NULL;
break;
}
else
{
delete [] pDnsName;
pDnsName = NULL;
dwDnsName = dwDnsNameSize * 2;
dwDnsNameSize = dwDnsName;
pDnsName = new wchar_t[dwDnsName];
}
}
}
catch (...)
{
if (pDnsName)
{
delete [] pDnsName;
pDnsName = NULL;
}
throw;
}
if (pDnsName)
{
if (_wcsicmp(pDnsName, pServer) == 0)
{
bRemove = TRUE;
}
delete [] pDnsName;
pDnsName = NULL;
}
}
}
catch(...)
{
if (pServer)
{
delete [] pServer;
}
throw;
}
if (bRemove)
{
t_Status = NetDfsRemoveStdRoot(
t_Server.GetBuffer(0),
t_Share.GetBuffer(0),
0
);
if ( t_Status != NERR_Success )
{
hRes = WBEM_E_FAILED;
}
}
else
{
//can't delete roots not on this machine
hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
}
delete [] pServer;
}
else
{
hRes = WBEM_E_FAILED;
}
}
else
{
hRes = WBEM_E_FAILED;
}
}
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::EnumerateAllReplicas
*
* DESCRIPTION : Enumerates all the Dfs Replicas of all junction points
*
******************************************************************************/
HRESULT CDfsReplica::EnumerateAllReplicas ( MethodContext *pMethodContext, DWORD dwPropertiesReq )
{
HRESULT hRes = WBEM_S_NO_ERROR;
BOOL bLoadReplicaFailure = FALSE;
PDFS_STORAGE_INFO pRepBuf;
PDFS_INFO_300 pData300 = NULL;
DWORD er300 = 0;
DWORD tr300 = 0;
// Call the NetDfsEnum function, specifying level 300.
DWORD res = NetDfsEnum( m_ComputerName.GetBuffer ( 0 ), 300, -1, (LPBYTE *) &pData300, &er300, &tr300 );
// If no error occurred,
if(res==NERR_Success)
{
if ( pData300 != NULL )
{
try
{
PDFS_INFO_300 p300 = pData300;
CInstancePtr pInstance;
for ( int i = 0; (i < er300) && SUCCEEDED( hRes ); i++, p300++ )
{
DWORD er4 = 0;
DWORD tr4 = 0;
PDFS_INFO_4 pData4 = NULL;
if (p300->DfsName != NULL)
{
if ( ( res = NetDfsEnum(p300->DfsName, 4, -1, (LPBYTE *) &pData4, &er4, &tr4) ) == NERR_Success)
{
if ( pData4 != NULL )
{
try
{
PDFS_INFO_4 p4 = pData4;
for ( int ii = 0; (ii < er4) && SUCCEEDED ( hRes ); ii++, p4++ )
{
// Walk all the replicas on each link
pRepBuf = p4->Storage;
for ( int j = 0; j < p4->NumberOfStorages; j++, pRepBuf++ )
{
pInstance.Attach(CreateNewInstance( pMethodContext ));
hRes = LoadDfsReplica ( dwPropertiesReq, pInstance, p4->EntryPath, pRepBuf );
if ( SUCCEEDED ( hRes ) )
{
hRes = pInstance->Commit();
}
else
{
bLoadReplicaFailure = TRUE;
}
}
}
}
catch(...)
{
NetApiBufferFree(pData4);
pData4 = NULL;
throw;
}
NetApiBufferFree(pData4);
pData4 = NULL;
}
}
// Check to see if there are ANY roots
else if (
(res != ERROR_NO_MORE_ITEMS) &&
(res != ERROR_NO_SUCH_DOMAIN) &&
(res != ERROR_NOT_FOUND) &&
(res != ERROR_ACCESS_DENIED)
)
{
hRes = WBEM_E_FAILED;
}
}
}
}
catch ( ... )
{
NetApiBufferFree(pData300);
pData300 = NULL;
throw;
}
NetApiBufferFree(pData300);
pData300 = NULL;
}
}
else
{
if ( (res != ERROR_NO_MORE_ITEMS) && (res != ERROR_NO_SUCH_DOMAIN) && (res != ERROR_NOT_FOUND) ) // Check to see if there are ANY roots
{
if ( ERROR_ACCESS_DENIED == res )
{
hRes = WBEM_E_ACCESS_DENIED ;
}
else
{
hRes = WBEM_E_FAILED ;
}
}
// No replicas
else if (res == ERROR_NO_MORE_ITEMS)
{
hRes = WBEM_S_NO_ERROR;
}
}
if ( bLoadReplicaFailure )
{
hRes = WBEM_E_PROVIDER_FAILURE;
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::FindAndSetDfsReplica
*
* DESCRIPTION : Finds an entry matching the dfsEntryPath and loads the
* Instance if found or acts based on the Operation passed
*
******************************************************************************/
HRESULT CDfsReplica::FindAndSetDfsReplica ( LPCWSTR a_EntryPath, LPCWSTR a_ServerName, LPCWSTR a_ShareName,
DWORD dwPropertiesReq, CInstance *pInstance, DWORD eOperation, bool &bRoot )
{
PDFS_STORAGE_INFO pRepBuf;
HRESULT hRes = WBEM_E_NOT_FOUND;
PDFS_INFO_300 pData300 = NULL;
DWORD er300 = 0;
DWORD tr300 = 0;
DWORD res = NERR_Success;
// Call the NetDfsEnum function, specifying level 300.
if( ( res = NetDfsEnum( m_ComputerName.GetBuffer ( 0 ), 300, -1, (LPBYTE *) &pData300, &er300, &tr300 ) ) == NERR_Success )
{
if ( pData300 != NULL )
{
try
{
BOOL bContinue = TRUE;
PDFS_INFO_300 p300 = pData300;
for ( int i = 0; (i < er300) && bContinue; i++, p300++ )
{
if ( p300->DfsName != NULL )
{
PDFS_INFO_4 pData4 = NULL;
DWORD er4=0;
DWORD tr4=0;
if ( ( res = NetDfsEnum(p300->DfsName, 4, -1, (LPBYTE *) &pData4, &er4, &tr4) ) == NERR_Success )
{
if ( pData4 != NULL )
{
try
{
BOOL bFound = FALSE;
PDFS_INFO_4 p4 = pData4;
for ( int jj = 0; (jj < er4) && bContinue; jj++, bContinue && (jj < er4) ? p4++ : p4 )
{
if ( _wcsicmp ( a_EntryPath, p4->EntryPath ) == 0 )
{
bFound = TRUE;
bContinue = FALSE;
}
}
if ( bFound )
{
bFound = FALSE;
bContinue = TRUE;
pRepBuf = p4->Storage;
for ( int j = 0; j < p4->NumberOfStorages && bContinue; j++, bContinue && (j < p4->NumberOfStorages) ? pRepBuf++ : pRepBuf )
{
if ( ( _wcsicmp(a_ServerName, pRepBuf->ServerName ) == 0 ) &&
( _wcsicmp(a_ShareName, pRepBuf->ShareName ) == 0 ) )
{
bFound = TRUE;
bRoot = (pData4 == p4);
bContinue = FALSE;
}
}
if ( bFound )
{
switch ( eOperation )
{
case eGet :
{
hRes = LoadDfsReplica ( dwPropertiesReq, pInstance, p4->EntryPath, pRepBuf );
break;
}
case eDelete:
{
hRes = WBEM_S_NO_ERROR;
break;
}
case eAdd:
{
hRes = WBEM_S_NO_ERROR;
break;
}
}
}
else
{
// we didn't find replica
bContinue = FALSE;
}
}
}
catch(...)
{
NetApiBufferFree(pData4);
pData4 = NULL;
throw;
}
NetApiBufferFree(pData4);
pData4 = NULL;
}
}
// Check to see if there are ANY roots
else if (
(res != ERROR_NO_MORE_ITEMS) &&
(res != ERROR_NO_SUCH_DOMAIN) &&
(res != ERROR_NOT_FOUND) &&
(res != ERROR_ACCESS_DENIED)
)
{
hRes = WBEM_E_FAILED;
bContinue = FALSE;
}
}
}
}
catch ( ... )
{
NetApiBufferFree(pData300);
pData300 = NULL;
throw;
}
NetApiBufferFree(pData300);
pData300 = NULL;
}
}
else if ( (res != ERROR_NO_MORE_ITEMS) && (res != ERROR_NO_SUCH_DOMAIN) && (res != ERROR_NOT_FOUND) ) // Check to see if there are ANY roots
{
if ( ERROR_ACCESS_DENIED == res )
{
hRes = WBEM_E_ACCESS_DENIED ;
}
else
{
hRes = WBEM_E_FAILED ;
}
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::LoadDfsReplica
*
* DESCRIPTION : Loads a Dfs Replica into the instance
*
******************************************************************************/
HRESULT CDfsReplica::LoadDfsReplica ( DWORD dwPropertiesReq, CInstance *pInstance, LPWSTR lpLinkName, PDFS_STORAGE_INFO pRepBuf )
{
HRESULT hRes = WBEM_S_NO_ERROR;
if ( dwPropertiesReq & DFSREPLICA_PROP_LinkName )
{
if ( pInstance->SetCHString ( LINKNAME, lpLinkName ) == FALSE )
{
hRes = WBEM_E_FAILED;
}
}
if ( dwPropertiesReq & DFSREPLICA_PROP_ServerName )
{
if ( pInstance->SetCHString ( SERVERNAME, pRepBuf->ServerName ) == FALSE )
{
hRes = WBEM_E_FAILED;
}
}
if ( dwPropertiesReq & DFSREPLICA_PROP_ShareName )
{
if ( pInstance->SetCHString ( SHARENAME, pRepBuf->ShareName ) == FALSE )
{
hRes = WBEM_E_FAILED;
}
}
if ( dwPropertiesReq & DFSREPLICA_PROP_State )
{
// need to check the state and then valuemap
DWORD dwState = 0xffff;
switch ( pRepBuf->State )
{
case DFS_STORAGE_STATE_OFFLINE :
{
dwState = 0;
break;
}
case DFS_STORAGE_STATE_ONLINE :
{
dwState = 1;
break;
}
case DFS_STORAGE_STATE_ACTIVE :
{
dwState = 2;
break;
}
}
if ( !pInstance->SetDWORD ( STATE, dwState ) )
{
hRes = WBEM_E_FAILED;
}
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CDfsReplica::GetKeys
*
* DESCRIPTION : Get the multi part key
*
*****************************************************************************/
HRESULT CDfsReplica::GetKeys(const CInstance *pInstance, CHString &sLink, CHString &sServer, CHString &sShare)
{
HRESULT hRes = WBEM_S_NO_ERROR;
// Get the Compound Key
if ( !pInstance->GetCHString ( LINKNAME , sLink ) ||
!pInstance->GetCHString ( SERVERNAME , sServer ) ||
!pInstance->GetCHString ( SHARENAME , sShare ) )
{
hRes = WBEM_E_FAILED;
}
return hRes;
}