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.
1687 lines
58 KiB
1687 lines
58 KiB
/******************************************************************
|
|
Copyright (C) 2001 Microsoft Corp.
|
|
|
|
sdwmi.cpp -- WMI provider class implementation
|
|
|
|
Generated by Microsoft WMI Code Generation Engine
|
|
|
|
TO DO: - See individual function headers
|
|
- When linking, make sure you link to framedyd.lib &
|
|
msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail).
|
|
|
|
Description:
|
|
|
|
|
|
|
|
******************************************************************/
|
|
#include "stdafx.h"
|
|
#include <fwcommon.h>
|
|
#include "sdwmi.h"
|
|
#include "smartptr.h"
|
|
#include <windows.h>
|
|
|
|
LPWSTR pszUuid = L"6af13c8b-0844-4c83-9064-1892ba825527"; // From JETRPC.IDL
|
|
|
|
#define SD_QUERY_ENDPOINT_NAME L"TSSessionDirectoryQueryApi"
|
|
|
|
/****************************************************************************/
|
|
// MIDL_user_allocate
|
|
// MIDL_user_free
|
|
//
|
|
// RPC-required allocation functions.
|
|
/****************************************************************************/
|
|
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t Size)
|
|
{
|
|
return LocalAlloc(LMEM_FIXED, Size);
|
|
}
|
|
|
|
void __RPC_USER MIDL_user_free(void __RPC_FAR *p)
|
|
{
|
|
LocalFree(p);
|
|
}
|
|
|
|
// Get the handle of the SD RPC server
|
|
RPC_BINDING_HANDLE OpenSDWMIServer()
|
|
{
|
|
|
|
HRESULT hr;
|
|
WCHAR *pBindingString = NULL;
|
|
RPC_BINDING_HANDLE hRPCBinding = NULL;
|
|
|
|
hr = RpcStringBindingCompose(/*(WCHAR *)g_RPCUUID,*/
|
|
0,
|
|
L"ncalrpc", NULL,
|
|
SD_QUERY_ENDPOINT_NAME, // Endpoint
|
|
NULL, &pBindingString);
|
|
|
|
if (hr == RPC_S_OK) {
|
|
// Generate the RPC binding from the canonical RPC binding string.
|
|
hr = RpcBindingFromStringBinding(pBindingString, &hRPCBinding);
|
|
if (hr != RPC_S_OK) {
|
|
ERR((TB,"SDWMI OpenSDWMIServer: Error %d in RpcBindingFromStringBinding\n", hr));
|
|
goto HandleError;
|
|
}
|
|
}
|
|
else {
|
|
ERR((TB,"SDWMI OpenSDWMIServer: Error %d in RpcStringBindingCompose\n", hr));
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = RpcEpResolveBinding(hRPCBinding, TSSDQUERYRPC_ClientIfHandle);
|
|
if (hr != RPC_S_OK) {
|
|
ERR((TB, "SDWMI OpenSDWMIServer: Error %d in RpcEpResolveBinding", hr));
|
|
goto HandleError;
|
|
}
|
|
HandleError:
|
|
if (pBindingString != NULL) {
|
|
RpcStringFree(&pBindingString);
|
|
}
|
|
return hRPCBinding;
|
|
}
|
|
|
|
|
|
// wrapper to make RPC call: TSSDRpcQueryAllClusterInfo
|
|
BOOL SDWMIQueryAllClusterInfo(DWORD *pNumberOfClusters,
|
|
TSSD_ClusterInfo **ppClusterInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
DWORD result;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQueryAllClusterInfo(rpcHandle, pNumberOfClusters, ppClusterInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQueryAllClusterInfo: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQueryAllClusterInfo: RPC call failed, result=0x%X", result));
|
|
}
|
|
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
|
|
// wrapper to make RPC call: TSSDRpcQueryClusterInfo
|
|
BOOL SDWMIQueryClusterInfo(WCHAR *ClusterName,
|
|
DWORD *pNumberOfClusters,
|
|
TSSD_ClusterInfo **ppClusterInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
DWORD result;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQueryClusterInfo(rpcHandle, ClusterName,
|
|
pNumberOfClusters, ppClusterInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQueryClusterInfo: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQueryClusterInfo: RPC call failed, result=0x%X", result));
|
|
}
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
|
|
// wrapper to make RPC call: TSSDRpcQueryServerByName
|
|
BOOL SDWMIQueryServerByName(WCHAR *ServerName,
|
|
DWORD *pNumberOfServers,
|
|
TSSD_ServerInfo **ppServerInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
DWORD result;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQueryServerByName(rpcHandle, ServerName, pNumberOfServers, ppServerInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQueryServerByName: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQueryServerByName: RPC call failed, result=0x%X", result));
|
|
}
|
|
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
// wrapper to make RPC call: TSSDRpcQueryServersInCluster
|
|
BOOL SDWMIQueryServersInCluster(WCHAR *ClusterName,
|
|
DWORD *pNumberOfServers,
|
|
TSSD_ServerInfo **ppServerInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
DWORD result;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQueryServersInCluster(rpcHandle, ClusterName, pNumberOfServers, ppServerInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQueryServersInCluster: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQueryServersInCluster: RPC call failed, result=0x%X", result));
|
|
}
|
|
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
|
|
// wrapper to make RPC call: TSSDRpcQueryAllServers
|
|
BOOL SDWMIQueryAllServers(DWORD *pNumberOfServers,
|
|
TSSD_ServerInfo **ppServerInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
DWORD result;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQueryAllServers(rpcHandle, pNumberOfServers, ppServerInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQueryAllServers: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQueryAllServers: RPC call failed, result=0x%X", result));
|
|
}
|
|
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
// wrapper to make RPC call: TSSDRpcQuerySessionInfoByUserName
|
|
BOOL SDWMIQuerySessionInfoByUserName(WCHAR *UserName,
|
|
WCHAR *DomainName,
|
|
DWORD *pNumberOfSessions,
|
|
TSSD_SessionInfo **ppSessionInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
DWORD result;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQuerySessionInfoByUserName(rpcHandle, UserName, DomainName,
|
|
pNumberOfSessions, ppSessionInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQuerySessionInfoByUserName: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQuerySessionInfoByUserName: RPC call failed, result=0x%X", result));
|
|
}
|
|
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
|
|
// wrapper to make RPC call: TSSDRpcQuerySessionInfoByServer
|
|
BOOL SDWMIQuerySessionInfoByServer(WCHAR *ServerName,
|
|
DWORD *pNumberOfSessions,
|
|
TSSD_SessionInfo **ppSessionInfo)
|
|
{
|
|
BOOL rc = FALSE;
|
|
RPC_BINDING_HANDLE rpcHandle;
|
|
DWORD result;
|
|
unsigned long RpcException;
|
|
|
|
rpcHandle = OpenSDWMIServer();
|
|
if (rpcHandle == NULL) {
|
|
goto HandleError;
|
|
}
|
|
|
|
RpcTryExcept {
|
|
// Make the call.
|
|
result = TSSDRpcQuerySessionInfoByServer(rpcHandle, ServerName,
|
|
pNumberOfSessions, ppSessionInfo);
|
|
}
|
|
RpcExcept(TRUE) {
|
|
RpcException = RpcExceptionCode();
|
|
ERR((TB,"TSSDRpcQuerySessionInfoByServer: RPC Exception %d\n", RpcException));
|
|
result = E_FAIL;
|
|
}
|
|
RpcEndExcept
|
|
|
|
if (SUCCEEDED(result)) {
|
|
rc = TRUE;
|
|
}
|
|
else {
|
|
ERR((TB,"TSSDRpcQuerySessionInfoByServer: RPC call failed, result=0x%X", result));
|
|
}
|
|
|
|
HandleError:
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
|
|
// TO DO: Replace "NameSpace" with the appropriate namespace for your
|
|
// provider instance. For instance: "root\\default or "root\\cimv2".
|
|
//===================================================================
|
|
|
|
|
|
/***********************************************************************
|
|
CWin32_SessionDirectoryCluster
|
|
************************************************************************/
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::CWin32_SessionDirectoryCluster
|
|
* This class reads properties such as NumberOfServers, etc.
|
|
*
|
|
*****************************************************************************/
|
|
CWin32_SessionDirectoryCluster::CWin32_SessionDirectoryCluster (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
|
|
{
|
|
TRC2((TB, "CWin32_SessionDirectoryCluster_ctor"));
|
|
|
|
_tcscpy(m_szClusterName, _T("ClusterName"));
|
|
|
|
_tcscpy(m_szNumberOfServers, _T("NumberOfServers"));
|
|
|
|
_tcscpy(m_szSingleSessionMode, _T("SingleSessionMode"));
|
|
|
|
m_pClusterInfo = NULL;
|
|
}
|
|
|
|
//=-------------
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::~CWin32_SessionDirectoryCluster
|
|
*****************************************************************************/
|
|
CWin32_SessionDirectoryCluster::~CWin32_SessionDirectoryCluster ()
|
|
{
|
|
}
|
|
//=-------------
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::EnumerateInstances
|
|
*
|
|
* DESCRIPTION : Returns all the instances of this class.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
* WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if successful
|
|
*
|
|
* COMMENTS : All instances on the machine are returned here and
|
|
* all properties that this class knows how to populate must
|
|
* be filled in. If there are no instances, return
|
|
* WBEM_S_NO_ERROR.
|
|
*****************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectoryCluster::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
DWORD dwRequiredProperties = 0;
|
|
//CHStringArray asNames;
|
|
CHStringArray aszNames;
|
|
DWORD i, NumberOfClusters = 0;
|
|
WCHAR ClusterName[TSSD_NameLength];
|
|
BOOL rc;
|
|
|
|
ERR((TB, "EnumerateInstances in SDCluster"));
|
|
|
|
rc = SDWMIQueryAllClusterInfo(&NumberOfClusters, &m_pClusterInfo);
|
|
if (!rc || (NumberOfClusters == 0)) {
|
|
goto HandleError;
|
|
}
|
|
|
|
//
|
|
for(i=0; i<NumberOfClusters; i++)
|
|
{
|
|
CInstance* pInstance = CreateNewInstance(pMethodContext);
|
|
|
|
if( pInstance == NULL)
|
|
{
|
|
ERR((TB, "CWin32_SessionDirectoryCluster@ExecQuery: CreateNewInstance failed"));
|
|
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = LoadPropertyValues(pInstance, i, BIT_ALL_PROPERTIES);
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
hr = pInstance->Commit();
|
|
}
|
|
|
|
pInstance->Release();
|
|
}
|
|
|
|
if (m_pClusterInfo != NULL) {
|
|
MIDL_user_free(m_pClusterInfo);
|
|
m_pClusterInfo = NULL;
|
|
}
|
|
HandleError:
|
|
return hr ;
|
|
}
|
|
|
|
//=---------
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::GetObject
|
|
*
|
|
* DESCRIPTION : Find a single instance based on the key property, the TerminalName.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key properties.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::GetObjectAsync.
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if the instance can be found
|
|
* WBEM_E_NOT_FOUND if the instance described by the key properties
|
|
* could not be found
|
|
* WBEM_E_FAILED if the instance could be found but another error
|
|
* occurred.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectoryCluster::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
CHString StrClusterName;
|
|
DWORD dwRequiredProperties = 0;
|
|
DWORD NumberOfClusters = 0;
|
|
WCHAR ClusterName[TSSD_NameLength];
|
|
BOOL rc;
|
|
|
|
ERR((TB, "GetObject in SDCluster"));
|
|
if( Query.IsPropertyRequired(m_szClusterName))
|
|
dwRequiredProperties |= BIT_CLUSTERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szNumberOfServers))
|
|
dwRequiredProperties |= BIT_NUMBEROFSERVERS;
|
|
|
|
if (Query.IsPropertyRequired(m_szSingleSessionMode))
|
|
dwRequiredProperties |= BIT_SINGLESESSIONMODE;
|
|
|
|
// Get the key property
|
|
pInstance->GetCHString(m_szClusterName, StrClusterName);
|
|
|
|
wcsncpy(ClusterName, StrClusterName, TSSD_NameLength);
|
|
ClusterName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB,"TSSDRpcQueryClusterInfo: Query cluster name: %S", ClusterName));
|
|
rc = SDWMIQueryClusterInfo(ClusterName, &NumberOfClusters, &m_pClusterInfo);
|
|
ERR((TB,"ExecQuery: Get numCluster is %d", NumberOfClusters));
|
|
if (!rc || (NumberOfClusters == 0)) {
|
|
goto HandleError;
|
|
}
|
|
|
|
|
|
hr = LoadPropertyValues(pInstance, 0, dwRequiredProperties);
|
|
|
|
if (m_pClusterInfo != NULL) {
|
|
MIDL_user_free(m_pClusterInfo);
|
|
m_pClusterInfo = NULL;
|
|
}
|
|
|
|
HandleError:
|
|
return hr ;
|
|
}
|
|
//=---------
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::ExecQuery
|
|
*
|
|
* DESCRIPTION : The method context is passed for use in the creation of
|
|
* instances that satisfy the query, and a CFrameworkQuery
|
|
* which describes the query. Create and populate all
|
|
* instances which satisfy the query. You may return more
|
|
* instances or more properties than are requested and WinMgmt
|
|
* will post filter out any that do not apply.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A query object describing the query to satisfy.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_FORWARD_ONLY
|
|
* WBEM_FLAG_BIDIRECTIONAL
|
|
* WBEM_FLAG_ENSURE_LOCATABLE
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if queries not supported for
|
|
* this class or if the query is too complex for this class
|
|
* to interpret. The framework will call the EnumerateInstances
|
|
* function instead and let Winmgmt post filter.
|
|
* WBEM_E_FAILED if the query failed
|
|
* WBEM_S_NO_ERROR if query was successful
|
|
*
|
|
* COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, WinMgmt
|
|
* will call your enumerate function to get all the instances and perform the
|
|
* filtering for you. Unless you expect SIGNIFICANT savings from implementing
|
|
* queries, you should remove this method. You should also remove this method
|
|
* if you are implementing a 'method only' provider.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CWin32_SessionDirectoryCluster::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
|
|
{
|
|
|
|
HRESULT hr = WBEM_E_NOT_FOUND, result;
|
|
DWORD dwRequiredProperties = 0;
|
|
//CHStringArray asNames;
|
|
CHStringArray aszNames;
|
|
DWORD i, NumberOfClusters = 0;
|
|
WCHAR ClusterName[TSSD_NameLength];
|
|
BOOL rc;
|
|
|
|
//Query.GetValuesForProp(m_szClusterName, asNames);
|
|
|
|
//BOOL bGetAllInstances = asNames.GetSize() == 0;
|
|
|
|
// Method 1
|
|
if (Query.IsPropertyRequired(m_szClusterName))
|
|
dwRequiredProperties |= BIT_CLUSTERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szNumberOfServers))
|
|
dwRequiredProperties |= BIT_NUMBEROFSERVERS;
|
|
|
|
if (Query.IsPropertyRequired(m_szSingleSessionMode))
|
|
dwRequiredProperties |= BIT_SINGLESESSIONMODE;
|
|
|
|
result = Query.GetValuesForProp(m_szClusterName, aszNames);
|
|
if ((result != WBEM_S_NO_ERROR) ||
|
|
(aszNames.GetSize() == 0)) {
|
|
// No query found
|
|
goto HandleError;
|
|
}
|
|
|
|
wcsncpy(ClusterName, aszNames.GetAt(0), TSSD_NameLength);
|
|
ClusterName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB,"TSSDRpcQueryClusterInfo: Query cluster name: %S", ClusterName));
|
|
|
|
rc = SDWMIQueryClusterInfo(ClusterName, &NumberOfClusters, &m_pClusterInfo);
|
|
ERR((TB,"ExecQuery: Get numCluster is %d", NumberOfClusters));
|
|
if (!rc || (NumberOfClusters == 0)) {
|
|
goto HandleError;
|
|
}
|
|
|
|
//
|
|
for(i=0; i<NumberOfClusters; i++)
|
|
{
|
|
CInstance* pInstance = CreateNewInstance(pMethodContext);
|
|
|
|
if( pInstance == NULL)
|
|
{
|
|
ERR((TB, "CWin32_SessionDirectoryCluster@ExecQuery: CreateNewInstance failed"));
|
|
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = LoadPropertyValues(pInstance, i, dwRequiredProperties);
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
hr = pInstance->Commit();
|
|
}
|
|
|
|
pInstance->Release();
|
|
}
|
|
|
|
if (m_pClusterInfo != NULL) {
|
|
MIDL_user_free(m_pClusterInfo);
|
|
m_pClusterInfo = NULL;
|
|
}
|
|
|
|
HandleError:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
BOOL CWin32_SessionDirectoryCluster::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
|
|
{
|
|
DWORD dwSize = asArray.GetSize();
|
|
|
|
for (DWORD x=0; x < dwSize; x++)
|
|
{
|
|
if( asArray[x].CompareNoCase(pszString) == 0 )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//=---------
|
|
/*************************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::PutInstance
|
|
*
|
|
* DESCRIPTION : PutInstance is in provider classes that can
|
|
* write instance information back to the registry.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key
|
|
* property - ClusterName
|
|
*
|
|
* A long that contains the flags described in
|
|
* IWbemServices::PutInstanceAsync.
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
|
|
* WBEM_E_FAILED if there is an error delivering the instance
|
|
* WBEM_E_INVALID_PARAMETER if any of the instance properties
|
|
* are incorrect.
|
|
* WBEM_S_NO_ERROR if instance is properly delivered
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
***************************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectoryCluster::PutInstance ( const CInstance &Instance, long lFlags)
|
|
{
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
}
|
|
|
|
|
|
//=---------
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::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.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key properties.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::DeleteInstanceAsync.
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available.
|
|
* WBEM_E_FAILED if there is an error deleting the instance.
|
|
* WBEM_E_INVALID_PARAMETER if any of the instance properties
|
|
* are incorrect.
|
|
* WBEM_S_NO_ERROR if instance is properly deleted.
|
|
*
|
|
* COMMENTS : TO DO: If you don't intend to support deleting instances or are
|
|
* creating a 'method only' provider, remove this method.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CWin32_SessionDirectoryCluster::DeleteInstance ( const CInstance &Instance, long lFlags )
|
|
{
|
|
|
|
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
|
|
}
|
|
|
|
|
|
//=---------
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryCluster::ExecMethod
|
|
*
|
|
* DESCRIPTION : Override this function to provide support for methods.
|
|
* A method is an entry point for the user of your provider
|
|
* to request your class perform some function above and
|
|
* beyond a change of state. (A change of state should be
|
|
* handled by PutInstance() )
|
|
*
|
|
* INPUTS : A pointer to a CInstance containing the instance the method was executed against.
|
|
* A string containing the method name
|
|
* A pointer to the CInstance which contains the IN parameters.
|
|
* A pointer to the CInstance to contain the OUT parameters.
|
|
* A set of specialized method flags
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not implemented for this class
|
|
* WBEM_S_NO_ERROR if method executes successfully
|
|
* WBEM_E_FAILED if error occurs executing method
|
|
*
|
|
* COMMENTS : Provides method to configure the License type base on
|
|
* the Terminal server mode, UseTempFolders, DeleteTempFolders
|
|
* and Help that are group policy based.
|
|
*
|
|
*****************************************************************************/
|
|
/*HRESULT CWin32_SessionDirectoryCluster::ExecMethod ( const CInstance& Inst,
|
|
const BSTR bstrMethodName,
|
|
CInstance *pInParams,
|
|
CInstance *pOutParams,
|
|
long lFlags)
|
|
|
|
{
|
|
|
|
|
|
DWORD dwData = 0;
|
|
BOOL fRet = FALSE;
|
|
bool bRet;
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
|
|
//If the method takes one or more parameters, require to check for validity of pInParams
|
|
|
|
if(pInParams == NULL)
|
|
{
|
|
return WBEM_E_INVALID_METHOD_PARAMETERS;
|
|
}
|
|
|
|
|
|
if( _wcsicmp(bstrMethodName, m_szSetNumberOfSessions) == 0 )
|
|
{
|
|
bRet = pInParams->GetDWORD(m_szNumberOfSessions, dwData);
|
|
|
|
if ( !bRet )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
// RPC function that sets the Number of Sessions
|
|
|
|
TRC2( (TB, "CWin32_SessionDirectoryClusterSetting@ExecMethod returned 0x%x \n" , hr) );
|
|
|
|
if( ERROR_SUCCESS == hr && pOutParams != NULL )
|
|
{
|
|
pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_INVALID_OPERATION;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
*/
|
|
//=---------
|
|
|
|
HRESULT CWin32_SessionDirectoryCluster::LoadPropertyValues( CInstance *pInstance, DWORD dwIndex, DWORD dwRequiredProperties)
|
|
{
|
|
dwIndex;
|
|
DWORD dwData = 0;
|
|
DWORD dwSize = 0;
|
|
BOOL bData = 0;
|
|
BOOL bActivate = 0;
|
|
DWORD dwStatus = 0;
|
|
|
|
HRESULT hr = WBEM_E_INVALID_PARAMETER;
|
|
|
|
// Your RPC call that gets all the data for the instance of interest. You could override the LoadPropertyValues method
|
|
// to pass the data structure you got in GetObject, EnumerateInstances or ExecQuery
|
|
|
|
if( dwRequiredProperties & BIT_CLUSTERNAME )
|
|
{
|
|
pInstance->SetCHString(m_szClusterName, m_pClusterInfo[dwIndex].ClusterName);
|
|
ERR((TB,"UserName is %S", m_pClusterInfo[dwIndex].ClusterName));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_NUMBEROFSERVERS )
|
|
{
|
|
pInstance->SetDWORD(m_szNumberOfServers, m_pClusterInfo[dwIndex].NumberOfServers);
|
|
ERR((TB,"NumberofServers is %d", m_pClusterInfo[dwIndex].NumberOfServers));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_SINGLESESSIONMODE )
|
|
{
|
|
pInstance->SetDWORD(m_szSingleSessionMode, m_pClusterInfo[dwIndex].SingleSessionMode ? 1 : 0);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
CWin32_SessionDirectoryServer
|
|
************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::CWin32_SessionDirectoryServer
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
CWin32_SessionDirectoryServer::CWin32_SessionDirectoryServer (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
|
|
{
|
|
TRC2((TB, "CWin32_SessionDirectoryServer_ctor"));
|
|
|
|
_tcscpy(m_szServerName, _T("ServerName"));
|
|
|
|
_tcscpy(m_szServerIPAddress, _T("ServerIPAddress"));
|
|
|
|
_tcscpy(m_szClusterName, _T("ClusterName"));
|
|
|
|
_tcscpy(m_szNumberOfSessions, _T("NumberOfSessions"));
|
|
|
|
_tcscpy(m_szSingleSessionMode, _T("SingleSessionMode"));
|
|
|
|
m_pServerInfo = NULL;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::~CWin32_SessionDirectoryServer
|
|
*****************************************************************************/
|
|
CWin32_SessionDirectoryServer::~CWin32_SessionDirectoryServer ()
|
|
{
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::EnumerateInstances
|
|
*
|
|
* DESCRIPTION : Returns all the instances of this class.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
* WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if successful
|
|
*
|
|
* COMMENTS : All instances on the machine are returned here and
|
|
* all properties that this class knows how to populate must
|
|
* be filled in. If there are no instances, return
|
|
* WBEM_S_NO_ERROR.
|
|
*****************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectoryServer::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
RPC_BINDING_HANDLE rpcHandle = NULL;
|
|
DWORD i, NumberOfServers = 0;
|
|
BOOL rc;
|
|
|
|
ERR((TB, "EnumerateInstances in SDServer"));
|
|
|
|
rc = SDWMIQueryAllServers(&NumberOfServers, &m_pServerInfo);
|
|
if (!rc || (NumberOfServers == 0)) {
|
|
goto HandleError;
|
|
}
|
|
|
|
for(i=0; i<NumberOfServers; i++)
|
|
{
|
|
CInstance* pInstance = CreateNewInstance(pMethodContext);
|
|
|
|
if( pInstance == NULL)
|
|
{
|
|
ERR((TB, "CWin32_SessionDirectoryServer@ExecQuery: CreateNewInstance failed"));
|
|
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = LoadPropertyValues(pInstance, i, BIT_ALL_PROPERTIES);
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
hr = pInstance->Commit();
|
|
}
|
|
|
|
pInstance->Release();
|
|
}
|
|
|
|
if (m_pServerInfo != NULL) {
|
|
MIDL_user_free(m_pServerInfo);
|
|
m_pServerInfo = NULL;
|
|
}
|
|
HandleError:
|
|
return hr ;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::GetObject
|
|
*
|
|
* DESCRIPTION : Find a single instance based on the key property, the TerminalName.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key properties.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::GetObjectAsync.
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if the instance can be found
|
|
* WBEM_E_NOT_FOUND if the instance described by the key properties
|
|
* could not be found
|
|
* WBEM_E_FAILED if the instance could be found but another error
|
|
* occurred.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectoryServer::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND, result;
|
|
DWORD dwRequiredProperties = 0;
|
|
CHString StrServerName;
|
|
DWORD i, NumberOfServers = 0;
|
|
WCHAR ServerName[TSSD_NameLength];
|
|
BOOL rc;
|
|
|
|
if (Query.IsPropertyRequired(m_szServerName))
|
|
dwRequiredProperties |= BIT_SERVERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szServerIPAddress))
|
|
dwRequiredProperties |= BIT_SERVERIPADDRESS;
|
|
|
|
if (Query.IsPropertyRequired(m_szClusterName))
|
|
dwRequiredProperties |= BIT_CLUSTERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szNumberOfSessions))
|
|
dwRequiredProperties |= BIT_NUMBEROFSESSIONS;
|
|
|
|
if (Query.IsPropertyRequired(m_szSingleSessionMode))
|
|
dwRequiredProperties |= BIT_SINGLESESSIONMODE;
|
|
|
|
// Get the key property
|
|
pInstance->GetCHString(m_szServerName, StrServerName);
|
|
|
|
wcsncpy(ServerName, StrServerName, TSSD_NameLength);
|
|
ServerName[TSSD_NameLength - 1] = L'\0';
|
|
|
|
// Query by Server Name
|
|
ERR((TB,"SDQueryServerInfo: Query server name: %S", ServerName));
|
|
|
|
rc = SDWMIQueryServerByName(ServerName, &NumberOfServers, &m_pServerInfo);
|
|
ERR((TB,"ExecQuery: Get numServer is %d", NumberOfServers));
|
|
if (!rc || (NumberOfServers == 0)) {
|
|
// Not found
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = LoadPropertyValues(pInstance, 0, dwRequiredProperties);
|
|
|
|
if (m_pServerInfo != NULL) {
|
|
MIDL_user_free(m_pServerInfo);
|
|
m_pServerInfo = NULL;
|
|
}
|
|
|
|
HandleError:
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::ExecQuery
|
|
*
|
|
* DESCRIPTION : The method context is passed for use in the creation of
|
|
* instances that satisfy the query, and a CFrameworkQuery
|
|
* which describes the query. Create and populate all
|
|
* instances which satisfy the query. You may return more
|
|
* instances or more properties than are requested and WinMgmt
|
|
* will post filter out any that do not apply.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A query object describing the query to satisfy.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_FORWARD_ONLY
|
|
* WBEM_FLAG_BIDIRECTIONAL
|
|
* WBEM_FLAG_ENSURE_LOCATABLE
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if queries not supported for
|
|
* this class or if the query is too complex for this class
|
|
* to interpret. The framework will call the EnumerateInstances
|
|
* function instead and let Winmgmt post filter.
|
|
* WBEM_E_FAILED if the query failed
|
|
* WBEM_S_NO_ERROR if query was successful
|
|
*
|
|
* COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, WinMgmt
|
|
* will call your enumerate function to get all the instances and perform the
|
|
* filtering for you. Unless you expect SIGNIFICANT savings from implementing
|
|
* queries, you should remove this method. You should also remove this method
|
|
* if you are implementing a 'method only' provider.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CWin32_SessionDirectoryServer::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
|
|
{
|
|
|
|
HRESULT hr = WBEM_E_NOT_FOUND, result;
|
|
DWORD dwRequiredProperties = 0;
|
|
//CHStringArray asNames;
|
|
CHStringArray aszNames;
|
|
DWORD i, NumberOfServers = 0;
|
|
WCHAR ServerName[TSSD_NameLength], ClusterName[TSSD_NameLength];
|
|
BOOL rc;
|
|
|
|
if (Query.IsPropertyRequired(m_szServerName))
|
|
dwRequiredProperties |= BIT_SERVERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szServerIPAddress))
|
|
dwRequiredProperties |= BIT_SERVERIPADDRESS;
|
|
|
|
if (Query.IsPropertyRequired(m_szClusterName))
|
|
dwRequiredProperties |= BIT_CLUSTERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szNumberOfSessions))
|
|
dwRequiredProperties |= BIT_NUMBEROFSESSIONS;
|
|
|
|
if (Query.IsPropertyRequired(m_szSingleSessionMode))
|
|
dwRequiredProperties |= BIT_SINGLESESSIONMODE;
|
|
|
|
// Query by Server Name
|
|
result = Query.GetValuesForProp(m_szServerName, aszNames);
|
|
if ((result == WBEM_S_NO_ERROR) &&
|
|
(aszNames.GetSize() != 0)) {
|
|
wcsncpy(ServerName, aszNames.GetAt(0), TSSD_NameLength);
|
|
ServerName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB,"SDQueryServerInfo: Query server name: %S", ServerName));
|
|
|
|
rc = SDWMIQueryServerByName(ServerName, &NumberOfServers, &m_pServerInfo);
|
|
ERR((TB,"ExecQuery: Get numServer is %d", NumberOfServers));
|
|
if (!rc || (NumberOfServers == 0)) {
|
|
// Not found
|
|
goto HandleError;
|
|
}
|
|
}
|
|
else {
|
|
result = Query.GetValuesForProp(m_szClusterName, aszNames);
|
|
if ((result == WBEM_S_NO_ERROR) &&
|
|
(aszNames.GetSize() != 0)) {
|
|
wcsncpy(ClusterName, aszNames.GetAt(0), TSSD_NameLength);
|
|
ClusterName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB,"SDQueryServerInfo: Query Cluster name: %S", ClusterName));
|
|
|
|
rc = SDWMIQueryServersInCluster(ClusterName, &NumberOfServers, &m_pServerInfo);
|
|
ERR((TB,"ExecQuery: Get numServer is %d", NumberOfServers));
|
|
if (!rc || (NumberOfServers == 0)) {
|
|
// Not found
|
|
goto HandleError;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
for(i=0; i<NumberOfServers; i++)
|
|
{
|
|
CInstance* pInstance = CreateNewInstance(pMethodContext);
|
|
|
|
if( pInstance == NULL)
|
|
{
|
|
ERR((TB, "CWin32_SessionDirectoryServer@ExecQuery: CreateNewInstance failed"));
|
|
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = LoadPropertyValues(pInstance, i, dwRequiredProperties);
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
hr = pInstance->Commit();
|
|
}
|
|
|
|
pInstance->Release();
|
|
}
|
|
|
|
if (m_pServerInfo != NULL) {
|
|
MIDL_user_free(m_pServerInfo);
|
|
m_pServerInfo = NULL;
|
|
}
|
|
|
|
HandleError:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
BOOL CWin32_SessionDirectoryServer::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
|
|
{
|
|
DWORD dwSize = asArray.GetSize();
|
|
|
|
for (DWORD x=0; x < dwSize; x++)
|
|
{
|
|
if( asArray[x].CompareNoCase(pszString) == 0 )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*************************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::PutInstance
|
|
*
|
|
* DESCRIPTION : PutInstance is in provider classes that can
|
|
* write instance information back to the registry.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key
|
|
* property - ClusterName
|
|
*
|
|
* A long that contains the flags described in
|
|
* IWbemServices::PutInstanceAsync.
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
|
|
* WBEM_E_FAILED if there is an error delivering the instance
|
|
* WBEM_E_INVALID_PARAMETER if any of the instance properties
|
|
* are incorrect.
|
|
* WBEM_S_NO_ERROR if instance is properly delivered
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
***************************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectoryServer::PutInstance ( const CInstance &Instance, long lFlags)
|
|
{
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectoryServer::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.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key properties.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::DeleteInstanceAsync.
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available.
|
|
* WBEM_E_FAILED if there is an error deleting the instance.
|
|
* WBEM_E_INVALID_PARAMETER if any of the instance properties
|
|
* are incorrect.
|
|
* WBEM_S_NO_ERROR if instance is properly deleted.
|
|
*
|
|
* COMMENTS : TO DO: If you don't intend to support deleting instances or are
|
|
* creating a 'method only' provider, remove this method.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CWin32_SessionDirectoryServer::DeleteInstance ( const CInstance &Instance, long lFlags )
|
|
{
|
|
|
|
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT CWin32_SessionDirectoryServer::LoadPropertyValues( CInstance *pInstance, DWORD dwIndex, DWORD dwRequiredProperties)
|
|
{
|
|
DWORD dwData = 0;
|
|
DWORD dwSize = 0;
|
|
BOOL bData = 0;
|
|
BOOL bActivate = 0;
|
|
DWORD dwStatus = 0;
|
|
|
|
HRESULT hr = WBEM_E_INVALID_PARAMETER;
|
|
|
|
if( dwRequiredProperties & BIT_SERVERNAME )
|
|
{
|
|
pInstance->SetCHString(m_szServerName, m_pServerInfo[dwIndex].ServerName);
|
|
ERR((TB,"Server is %S", m_pServerInfo[dwIndex].ServerName));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_SERVERIPADDRESS )
|
|
{
|
|
pInstance->SetCHString(m_szServerIPAddress, m_pServerInfo[dwIndex].ServerIPAddress);
|
|
ERR((TB,"ServerIP is %S", m_pServerInfo[dwIndex].ServerIPAddress));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_CLUSTERNAME )
|
|
{
|
|
pInstance->SetCHString(m_szClusterName, m_pServerInfo[dwIndex].ClusterName);
|
|
ERR((TB,"ClusterName is %S", m_pServerInfo[dwIndex].ClusterName));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_NUMBEROFSESSIONS )
|
|
{
|
|
pInstance->SetDWORD(m_szNumberOfSessions, m_pServerInfo[dwIndex].NumberOfSessions);
|
|
ERR((TB,"NumberofSessions is %d", m_pServerInfo[dwIndex].NumberOfSessions));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_SINGLESESSIONMODE )
|
|
{
|
|
pInstance->SetDWORD(m_szSingleSessionMode, m_pServerInfo[dwIndex].SingleSessionMode ? 1 : 0);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
CWin32_SessionDirectorySession
|
|
************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::CWin32_SessionDirectorySession
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
CWin32_SessionDirectorySession::CWin32_SessionDirectorySession (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
|
|
{
|
|
TRC2((TB, "CWin32_SessionDirectorySession_ctor"));
|
|
|
|
_tcscpy(m_szServerName, _T("ServerName"));
|
|
|
|
_tcscpy(m_szSessionID, _T("SessionID"));
|
|
|
|
_tcscpy(m_szUserName, _T("UserName"));
|
|
|
|
_tcscpy(m_szDomainName, _T("DomainName"));
|
|
|
|
_tcscpy(m_szServerIPAddress, _T("ServerIPAddress"));
|
|
|
|
_tcscpy(m_szTSProtocol, _T("TSProtocol"));
|
|
|
|
_tcscpy(m_szApplicationType, _T("ApplicationType"));
|
|
|
|
_tcscpy(m_szResolutionWidth, _T("ResolutionWidth"));
|
|
|
|
_tcscpy(m_szResolutionHeight, _T("ResolutionHeight"));
|
|
|
|
_tcscpy(m_szColorDepth, _T("ColorDepth"));
|
|
|
|
_tcscpy(m_szCreateTime, _T("CreateTime"));
|
|
|
|
_tcscpy(m_szDisconnectTime, _T("DisconnectTime"));
|
|
|
|
_tcscpy(m_szSessionState, _T("SessionState"));
|
|
|
|
m_pSessionInfo = NULL;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::~CWin32_SessionDirectorySession
|
|
*****************************************************************************/
|
|
CWin32_SessionDirectorySession::~CWin32_SessionDirectorySession ()
|
|
{
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::EnumerateInstances
|
|
*
|
|
* DESCRIPTION : Returns all the instances of this class.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
* WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if successful
|
|
*
|
|
* COMMENTS : All instances on the machine are returned here and
|
|
* all properties that this class knows how to populate must
|
|
* be filled in. If there are no instances, return
|
|
* WBEM_S_NO_ERROR.
|
|
*****************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectorySession::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
|
|
{
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::GetObject
|
|
*
|
|
* DESCRIPTION : Find a single instance based on the key property, the TerminalName.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key properties.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::GetObjectAsync.
|
|
*
|
|
* RETURNS : WBEM_S_NO_ERROR if the instance can be found
|
|
* WBEM_E_NOT_FOUND if the instance described by the key properties
|
|
* could not be found
|
|
* WBEM_E_FAILED if the instance could be found but another error
|
|
* occurred.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectorySession::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
|
|
{
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::ExecQuery
|
|
*
|
|
* DESCRIPTION : The method context is passed for use in the creation of
|
|
* instances that satisfy the query, and a CFrameworkQuery
|
|
* which describes the query. Create and populate all
|
|
* instances which satisfy the query. You may return more
|
|
* instances or more properties than are requested and WinMgmt
|
|
* will post filter out any that do not apply.
|
|
*
|
|
* INPUTS : A pointer to the MethodContext for communication with WinMgmt.
|
|
* A query object describing the query to satisfy.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::CreateInstanceEnumAsync. Note that the following
|
|
* flags are handled by (and filtered out by) WinMgmt:
|
|
* WBEM_FLAG_FORWARD_ONLY
|
|
* WBEM_FLAG_BIDIRECTIONAL
|
|
* WBEM_FLAG_ENSURE_LOCATABLE
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if queries not supported for
|
|
* this class or if the query is too complex for this class
|
|
* to interpret. The framework will call the EnumerateInstances
|
|
* function instead and let Winmgmt post filter.
|
|
* WBEM_E_FAILED if the query failed
|
|
* WBEM_S_NO_ERROR if query was successful
|
|
*
|
|
* COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, WinMgmt
|
|
* will call your enumerate function to get all the instances and perform the
|
|
* filtering for you. Unless you expect SIGNIFICANT savings from implementing
|
|
* queries, you should remove this method. You should also remove this method
|
|
* if you are implementing a 'method only' provider.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CWin32_SessionDirectorySession::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
|
|
{
|
|
|
|
HRESULT hr = WBEM_E_NOT_FOUND, result;
|
|
DWORD dwRequiredProperties = 0;
|
|
//CHStringArray asNames;
|
|
CHStringArray aszNames;
|
|
DWORD i, NumberOfSessions = 0;
|
|
WCHAR UserName[TSSD_NameLength], DomainName[TSSD_NameLength], ServerName[TSSD_NameLength];
|
|
BOOL rc;
|
|
BOOL bQueryByServerName = FALSE;
|
|
|
|
|
|
if (Query.IsPropertyRequired(m_szServerName))
|
|
dwRequiredProperties |= BIT_SERVERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szSessionID))
|
|
dwRequiredProperties |= BIT_SESSIONID;
|
|
|
|
if (Query.IsPropertyRequired(m_szUserName))
|
|
dwRequiredProperties |= BIT_USERNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szDomainName))
|
|
dwRequiredProperties |= BIT_DOMAINNAME;
|
|
|
|
if (Query.IsPropertyRequired(m_szServerIPAddress))
|
|
dwRequiredProperties |= BIT_SERVERIPADDRESS;
|
|
|
|
if (Query.IsPropertyRequired(m_szTSProtocol))
|
|
dwRequiredProperties |= BIT_TSPROTOCOL;
|
|
|
|
if (Query.IsPropertyRequired(m_szApplicationType))
|
|
dwRequiredProperties |= BIT_APPLICATIONTYPE;
|
|
|
|
if (Query.IsPropertyRequired(m_szResolutionWidth))
|
|
dwRequiredProperties |= BIT_RESOLUTIONWIDTH;
|
|
|
|
if (Query.IsPropertyRequired(m_szResolutionHeight))
|
|
dwRequiredProperties |= BIT_RESOLUTIONHEIGHT;
|
|
|
|
if (Query.IsPropertyRequired(m_szColorDepth))
|
|
dwRequiredProperties |= BIT_COLORDEPTH;
|
|
|
|
if (Query.IsPropertyRequired(m_szCreateTime))
|
|
dwRequiredProperties |= BIT_CREATETIME;
|
|
|
|
if (Query.IsPropertyRequired(m_szDisconnectTime))
|
|
dwRequiredProperties |= BIT_DISCONNECTTIME;
|
|
|
|
if (Query.IsPropertyRequired(m_szSessionState))
|
|
dwRequiredProperties |= BIT_SESSIONSTATE;
|
|
|
|
// Get the server name
|
|
result = Query.GetValuesForProp(m_szServerName, aszNames);
|
|
if ((result == WBEM_S_NO_ERROR) &&
|
|
(aszNames.GetSize() != 0)) {
|
|
bQueryByServerName = TRUE;
|
|
wcsncpy(ServerName, aszNames.GetAt(0), TSSD_NameLength);
|
|
ServerName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB, "Query sessions for servername %S", ServerName));
|
|
|
|
rc = SDWMIQuerySessionInfoByServer(ServerName, &NumberOfSessions, &m_pSessionInfo);
|
|
ERR((TB,"ExecQuery: Get numSession is %d", NumberOfSessions));
|
|
if (!rc || (NumberOfSessions == 0)) {
|
|
goto HandleError;
|
|
}
|
|
}
|
|
else {
|
|
// Get the user name
|
|
result = Query.GetValuesForProp(m_szUserName, aszNames);
|
|
if ((result != WBEM_S_NO_ERROR) ||
|
|
(aszNames.GetSize() == 0)) {
|
|
// No query found
|
|
goto HandleError;
|
|
}
|
|
wcsncpy(UserName, aszNames.GetAt(0), TSSD_NameLength);
|
|
UserName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB, "Query UserName is %S", UserName));
|
|
|
|
// Get the domain name
|
|
result = Query.GetValuesForProp(m_szDomainName, aszNames);
|
|
if ((result != WBEM_S_NO_ERROR) ||
|
|
(aszNames.GetSize() == 0)) {
|
|
// No query found
|
|
goto HandleError;
|
|
}
|
|
wcsncpy(DomainName, aszNames.GetAt(0), TSSD_NameLength);
|
|
DomainName[TSSD_NameLength - 1] = L'\0';
|
|
ERR((TB, "Query DomainName is %S", DomainName));
|
|
|
|
rc = SDWMIQuerySessionInfoByUserName(UserName, DomainName, &NumberOfSessions, &m_pSessionInfo);
|
|
ERR((TB,"ExecQuery: Get numSession is %d", NumberOfSessions));
|
|
if (!rc || (NumberOfSessions == 0)) {
|
|
goto HandleError;
|
|
}
|
|
}
|
|
|
|
//
|
|
for(i=0; i<NumberOfSessions; i++)
|
|
{
|
|
CInstance* pInstance = CreateNewInstance(pMethodContext);
|
|
|
|
if( pInstance == NULL)
|
|
{
|
|
ERR((TB, "CWin32_SessionDirectorySession@ExecQuery: CreateNewInstance failed"));
|
|
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto HandleError;
|
|
}
|
|
|
|
hr = LoadPropertyValues(pInstance, i, dwRequiredProperties);
|
|
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
hr = pInstance->Commit();
|
|
}
|
|
|
|
pInstance->Release();
|
|
}
|
|
|
|
if (m_pSessionInfo != NULL) {
|
|
MIDL_user_free(m_pSessionInfo);
|
|
m_pSessionInfo = NULL;
|
|
}
|
|
|
|
HandleError:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
BOOL CWin32_SessionDirectorySession::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
|
|
{
|
|
DWORD dwSize = asArray.GetSize();
|
|
|
|
for (DWORD x=0; x < dwSize; x++)
|
|
{
|
|
if( asArray[x].CompareNoCase(pszString) == 0 )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*************************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::PutInstance
|
|
*
|
|
* DESCRIPTION : PutInstance is in provider classes that can
|
|
* write instance information back to the registry.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key
|
|
* property - ClusterName
|
|
*
|
|
* A long that contains the flags described in
|
|
* IWbemServices::PutInstanceAsync.
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
|
|
* WBEM_E_FAILED if there is an error delivering the instance
|
|
* WBEM_E_INVALID_PARAMETER if any of the instance properties
|
|
* are incorrect.
|
|
* WBEM_S_NO_ERROR if instance is properly delivered
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
***************************************************************************************/
|
|
|
|
HRESULT CWin32_SessionDirectorySession::PutInstance ( const CInstance &Instance, long lFlags)
|
|
{
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CWin32_SessionDirectorySession::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.
|
|
*
|
|
* INPUTS : A pointer to a CInstance object containing the key properties.
|
|
* A long that contains the flags described in
|
|
* IWbemServices::DeleteInstanceAsync.
|
|
*
|
|
* RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available.
|
|
* WBEM_E_FAILED if there is an error deleting the instance.
|
|
* WBEM_E_INVALID_PARAMETER if any of the instance properties
|
|
* are incorrect.
|
|
* WBEM_S_NO_ERROR if instance is properly deleted.
|
|
*
|
|
* COMMENTS : TO DO: If you don't intend to support deleting instances or are
|
|
* creating a 'method only' provider, remove this method.
|
|
*
|
|
*****************************************************************************/
|
|
HRESULT CWin32_SessionDirectorySession::DeleteInstance ( const CInstance &Instance, long lFlags )
|
|
{
|
|
return (WBEM_E_PROVIDER_NOT_CAPABLE);
|
|
}
|
|
|
|
|
|
|
|
HRESULT CWin32_SessionDirectorySession::LoadPropertyValues( CInstance *pInstance, DWORD dwIndex, DWORD dwRequiredProperties)
|
|
{
|
|
BOOL rc;
|
|
|
|
HRESULT hr = WBEM_E_INVALID_PARAMETER;
|
|
|
|
if( dwRequiredProperties & BIT_SERVERNAME )
|
|
{
|
|
pInstance->SetCHString(m_szServerName, m_pSessionInfo[dwIndex].ServerName);
|
|
ERR((TB,"Server is %S", m_pSessionInfo[dwIndex].ServerName));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_SESSIONID )
|
|
{
|
|
pInstance->SetDWORD(m_szSessionID, m_pSessionInfo[dwIndex].SessionID);
|
|
ERR((TB,"Session ID is %d", m_pSessionInfo[dwIndex].SessionID));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_USERNAME )
|
|
{
|
|
pInstance->SetCHString(m_szUserName, m_pSessionInfo[dwIndex].UserName);
|
|
ERR((TB,"UserName is %S", m_pSessionInfo[dwIndex].UserName));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_DOMAINNAME )
|
|
{
|
|
pInstance->SetCHString(m_szDomainName, m_pSessionInfo[dwIndex].DomainName);
|
|
ERR((TB,"DomainName is %S", m_pSessionInfo[dwIndex].DomainName));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_SERVERIPADDRESS )
|
|
{
|
|
pInstance->SetCHString(m_szServerIPAddress, m_pSessionInfo[dwIndex].ServerIPAddress);
|
|
ERR((TB,"ServerIP is %S", m_pSessionInfo[dwIndex].ServerIPAddress));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_TSPROTOCOL )
|
|
{
|
|
pInstance->SetDWORD(m_szTSProtocol, m_pSessionInfo[dwIndex].TSProtocol);
|
|
ERR((TB,"TSProtocol is %d", m_pSessionInfo[dwIndex].TSProtocol));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_APPLICATIONTYPE )
|
|
{
|
|
pInstance->SetCHString(m_szApplicationType, m_pSessionInfo[dwIndex].ApplicationType);
|
|
ERR((TB,"AppType is %S", m_pSessionInfo[dwIndex].ApplicationType));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_RESOLUTIONWIDTH )
|
|
{
|
|
pInstance->SetDWORD(m_szResolutionWidth, m_pSessionInfo[dwIndex].ResolutionWidth);
|
|
ERR((TB,"ResolutionWidth is %d", m_pSessionInfo[dwIndex].ResolutionWidth));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_RESOLUTIONHEIGHT )
|
|
{
|
|
pInstance->SetDWORD(m_szResolutionHeight, m_pSessionInfo[dwIndex].ResolutionHeight);
|
|
ERR((TB,"ResolutionHeight is %d", m_pSessionInfo[dwIndex].ResolutionHeight));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_COLORDEPTH )
|
|
{
|
|
pInstance->SetDWORD(m_szColorDepth, m_pSessionInfo[dwIndex].ColorDepth);
|
|
ERR((TB,"ColorDepth is %d", m_pSessionInfo[dwIndex].ColorDepth));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_CREATETIME )
|
|
{
|
|
rc = pInstance->SetDateTime(m_szCreateTime, WBEMTime(m_pSessionInfo[dwIndex].CreateTime));
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_DISCONNECTTIME )
|
|
{
|
|
// Only set Disconnect time when the session is disconnected
|
|
if (m_pSessionInfo[dwIndex].SessionState != 0) {
|
|
pInstance->SetDateTime(m_szDisconnectTime, WBEMTime(m_pSessionInfo[dwIndex].DisconnectTime));
|
|
}
|
|
}
|
|
|
|
if( dwRequiredProperties & BIT_SESSIONSTATE )
|
|
{
|
|
pInstance->SetDWORD(m_szSessionState, m_pSessionInfo[dwIndex].SessionState ? 1 : 0);
|
|
ERR((TB,"SessionState is %d", m_pSessionInfo[dwIndex].SessionState));
|
|
}
|
|
return S_OK;
|
|
}
|