|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
Abstract:
History:
--*/
#include "precomp.h"
#include <wbemcli.h>
#include <wmimsg.h>
#include <tchar.h>
#include "msmqcomn.h"
#define MAX_FORMAT_NAME 1024
#define CALLFUNC(FUNC) rApi.m_fp ## FUNC
HRESULT MqClassToWmiRes( DWORD dwClass ) { switch( dwClass ) { case MQMSG_CLASS_NACK_ACCESS_DENIED : return WBEM_E_ACCESS_DENIED;
case MQMSG_CLASS_NACK_BAD_DST_Q : return WMIMSG_E_INVALIDADDRESS;
case MQMSG_CLASS_NACK_BAD_ENCRYPTION : case MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT : return WMIMSG_E_ENCRYPTFAILURE;
case MQMSG_CLASS_NACK_BAD_SIGNATURE : case MQMSG_CLASS_NACK_UNSUPPORTED_CRYPTO_PROVIDER : return WMIMSG_E_AUTHFAILURE;
case MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q : case MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG : return WMIMSG_E_XACTFAILURE;
case MQMSG_CLASS_NACK_PURGED : case MQMSG_CLASS_NACK_Q_DELETED : case MQMSG_CLASS_NACK_Q_PURGED : return WMIMSG_E_QUEUEPURGED;
case MQMSG_CLASS_NACK_RECEIVE_TIMEOUT : case MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER : return WMIMSG_E_TIMEDOUT; };
return dwClass; }
HRESULT MqResToWmiRes( HRESULT hr, HRESULT hrDefault ) { switch( hr ) { case MQ_ERROR_SHARING_VIOLATION : case MQ_ERROR_ACCESS_DENIED :
return WBEM_E_ACCESS_DENIED;
case MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR : return WBEM_E_INVALID_PROPERTY; case MQ_ERROR_SERVICE_NOT_AVAILABLE : case MQ_ERROR_NO_DS : case MQ_ERROR_DTC_CONNECT :
return WMIMSG_E_REQSVCNOTAVAIL;
case MQ_ERROR_QUEUE_NOT_FOUND : return WMIMSG_E_TARGETNOTFOUND; case MQ_ERROR_ILLEGAL_FORMATNAME : case MQ_ERROR_ILLEGAL_QUEUE_PATHNAME : case MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION : return WMIMSG_E_INVALIDADDRESS;
case MQ_ERROR_NO_INTERNAL_USER_CERT :
return WMIMSG_E_AUTHFAILURE;
case MQ_ERROR_TRANSACTION_USAGE : return WMIMSG_E_XACTFAILURE;
case MQ_ERROR_INSUFFICIENT_RESOURCES : return WMIMSG_E_MSGTOOLARGE;
case MQ_ERROR_QUEUE_EXISTS : return WBEM_E_ALREADY_EXISTS;
case MQ_ERROR_IO_TIMEOUT : return WMIMSG_E_TIMEDOUT; };
return hrDefault == S_OK ? hr : hrDefault; }
HRESULT StartMsmqServiceNT() { SC_HANDLE hSvcMgr;
hSvcMgr = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT );
if ( hSvcMgr == NULL ) { return WBEM_E_ACCESS_DENIED; }
SC_HANDLE hSvc;
hSvc = OpenServiceW( hSvcMgr, L"msmq", SERVICE_START );
if ( hSvc == NULL ) { CloseServiceHandle( hSvcMgr ); return WBEM_E_ACCESS_DENIED; }
BOOL bRes = StartService( hSvc, 0, NULL );
CloseServiceHandle( hSvc ); CloseServiceHandle( hSvcMgr );
return bRes ? S_OK : HRESULT_FROM_WIN32( GetLastError() ); }
HRESULT StartMsmqService9x() { //
// TODO: will probably have to exec process here.
//
return S_OK; }
HRESULT EnsureMsmqService( CMsmqApi& rApi ) { HRESULT hr;
//
// issue a call to find out if the msmq service is down.
//
hr = IsMsmqOnline( rApi );
if ( hr == WMIMSG_E_REQSVCNOTAVAIL ) { //
// try to restart the service.
//
OSVERSIONINFO osi; ZeroMemory( &osi, sizeof(OSVERSIONINFO) ); osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx( &osi ); if ( osi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS ) { hr = StartMsmqServiceNT(); } else { hr = StartMsmqService9x(); } } if ( rApi.m_fpMQRegisterCertificate != NULL ) { //
// try to ensure that the calling user has an internal certificate
// registered.
//
CALLFUNC(MQRegisterCertificate)( MQCERT_REGISTER_IF_NOT_EXIST, NULL, 0 ); } return WBEM_S_NO_ERROR; }
HRESULT IsMsmqWorkgroup( CMsmqApi& rApi ) { HRESULT hr;
//
// if the MQGetPrivateComputerInformation is avaliable use it. if not,
// then we have to go to the registry.
//
if ( rApi.m_fpMQGetPrivateComputerInformation != NULL ) { MQPROPVARIANT PropVar; PropVar.vt = VT_BOOL; QMPROPID PropID = PROPID_PC_DS_ENABLED;
MQPRIVATEPROPS PrivProps; PrivProps.cProp = 1; PrivProps.aPropID = &PropID; PrivProps.aPropVar = &PropVar; PrivProps.aStatus = NULL;
hr = CALLFUNC(MQGetPrivateComputerInformation)( NULL, &PrivProps );
if ( FAILED(hr) ) { return hr; }
hr = PropVar.boolVal == VARIANT_TRUE ? S_OK : S_FALSE; } else { //
// TODO: Add non win2k version here ..
//
hr = S_FALSE; }
return hr; }
HRESULT IsMsmqOnline( CMsmqApi& rApi ) { //
// There is a public w2k func to do this, but we can't rely on it because
// this module needs to run on older platforms. Going to use internal
// method for now.
//
HRESULT hr; MQPROPVARIANT MgmtPropVar; QMPROPID MgmtPropID = PROPID_MGMT_MSMQ_CONNECTED; MQMGMTPROPS MgmtProps; MgmtProps.cProp = 1; MgmtProps.aPropID = &MgmtPropID; MgmtProps.aPropVar = &MgmtPropVar; MgmtProps.aStatus = NULL;
hr = CALLFUNC(MQMgmtGetInfo)( NULL, L"MACHINE", &MgmtProps );
if ( FAILED(hr) ) { return MqResToWmiRes( hr ); }
if ( _wcsicmp( MgmtPropVar.pwszVal, MSMQ_CONNECTED ) != 0 ) { return S_FALSE; }
return S_OK; }
HRESULT NormalizeQueueName( CMsmqApi& rApi, LPCWSTR wszEndpoint, WString& rwsFormat ) { HRESULT hr;
//
// if there is an '=' before any '\', then it is a format name.
// else it is a pathname.
//
WCHAR* pwchEquals = wcschr( wszEndpoint, '=' ); WCHAR* pwchSlash = wcschr( wszEndpoint, '\\' );
if ( pwchEquals != NULL ) { if ( pwchSlash == NULL || pwchSlash > pwchEquals ) { rwsFormat = wszEndpoint; return S_OK; } }
WCHAR achFormat[MAX_FORMAT_NAME]; ULONG cFormat = MAX_FORMAT_NAME;
hr = CALLFUNC(MQPathNameToFormatName)( wszEndpoint, achFormat, &cFormat );
if ( FAILED(hr) ) { return hr; }
rwsFormat = achFormat;
return S_OK; }
/**************************************************************************
CMsmqApi ***************************************************************************/
CMsmqApi::~CMsmqApi() { if ( m_hModule != NULL ) { FreeLibrary( m_hModule ); } }
#define GETFUNC(FUNC) \
m_fp ##FUNC = (P ##FUNC) GetProcAddress( m_hModule, #FUNC ); \ if ( m_fp ##FUNC == NULL ) { return HRESULT_FROM_WIN32(GetLastError()); }
#define GETFUNC_OPT(FUNC) \
m_fp ##FUNC = (P ##FUNC) GetProcAddress( m_hModule, #FUNC );
HRESULT CMsmqApi::Initialize() { if ( m_hModule != NULL ) { return S_OK; }
m_hModule = LoadLibrary( _T("mqrt") );
if ( m_hModule == NULL ) { //
// msmq is not installed.
//
return WMIMSG_E_REQSVCNOTAVAIL; }
GETFUNC( MQCreateQueue ) GETFUNC( MQOpenQueue ) GETFUNC( MQDeleteQueue ) GETFUNC( MQFreeMemory ) GETFUNC( MQSendMessage ) GETFUNC( MQReceiveMessage ) GETFUNC( MQCloseQueue ) GETFUNC( MQCreateCursor ) GETFUNC( MQCloseCursor ) GETFUNC( MQMgmtGetInfo ) GETFUNC( MQPathNameToFormatName ) GETFUNC( MQGetSecurityContext ) GETFUNC( MQGetQueueProperties) GETFUNC( MQFreeSecurityContext ) GETFUNC_OPT( MQRegisterCertificate ) GETFUNC_OPT( MQGetPrivateComputerInformation )
return S_OK; }
|