Source code of Windows XP (NT5)
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.

374 lines
7.8 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. #include "precomp.h"
  8. #include <wbemcli.h>
  9. #include <wmimsg.h>
  10. #include <tchar.h>
  11. #include "msmqcomn.h"
  12. #define MAX_FORMAT_NAME 1024
  13. #define CALLFUNC(FUNC) rApi.m_fp ## FUNC
  14. HRESULT MqClassToWmiRes( DWORD dwClass )
  15. {
  16. switch( dwClass )
  17. {
  18. case MQMSG_CLASS_NACK_ACCESS_DENIED :
  19. return WBEM_E_ACCESS_DENIED;
  20. case MQMSG_CLASS_NACK_BAD_DST_Q :
  21. return WMIMSG_E_INVALIDADDRESS;
  22. case MQMSG_CLASS_NACK_BAD_ENCRYPTION :
  23. case MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT :
  24. return WMIMSG_E_ENCRYPTFAILURE;
  25. case MQMSG_CLASS_NACK_BAD_SIGNATURE :
  26. case MQMSG_CLASS_NACK_UNSUPPORTED_CRYPTO_PROVIDER :
  27. return WMIMSG_E_AUTHFAILURE;
  28. case MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q :
  29. case MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG :
  30. return WMIMSG_E_XACTFAILURE;
  31. case MQMSG_CLASS_NACK_PURGED :
  32. case MQMSG_CLASS_NACK_Q_DELETED :
  33. case MQMSG_CLASS_NACK_Q_PURGED :
  34. return WMIMSG_E_QUEUEPURGED;
  35. case MQMSG_CLASS_NACK_RECEIVE_TIMEOUT :
  36. case MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER :
  37. return WMIMSG_E_TIMEDOUT;
  38. };
  39. return dwClass;
  40. }
  41. HRESULT MqResToWmiRes( HRESULT hr, HRESULT hrDefault )
  42. {
  43. switch( hr )
  44. {
  45. case MQ_ERROR_SHARING_VIOLATION :
  46. case MQ_ERROR_ACCESS_DENIED :
  47. return WBEM_E_ACCESS_DENIED;
  48. case MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR :
  49. return WBEM_E_INVALID_PROPERTY;
  50. case MQ_ERROR_SERVICE_NOT_AVAILABLE :
  51. case MQ_ERROR_NO_DS :
  52. case MQ_ERROR_DTC_CONNECT :
  53. return WMIMSG_E_REQSVCNOTAVAIL;
  54. case MQ_ERROR_QUEUE_NOT_FOUND :
  55. return WMIMSG_E_TARGETNOTFOUND;
  56. case MQ_ERROR_ILLEGAL_FORMATNAME :
  57. case MQ_ERROR_ILLEGAL_QUEUE_PATHNAME :
  58. case MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION :
  59. return WMIMSG_E_INVALIDADDRESS;
  60. case MQ_ERROR_NO_INTERNAL_USER_CERT :
  61. return WMIMSG_E_AUTHFAILURE;
  62. case MQ_ERROR_TRANSACTION_USAGE :
  63. return WMIMSG_E_XACTFAILURE;
  64. case MQ_ERROR_INSUFFICIENT_RESOURCES :
  65. return WMIMSG_E_MSGTOOLARGE;
  66. case MQ_ERROR_QUEUE_EXISTS :
  67. return WBEM_E_ALREADY_EXISTS;
  68. case MQ_ERROR_IO_TIMEOUT :
  69. return WMIMSG_E_TIMEDOUT;
  70. };
  71. return hrDefault == S_OK ? hr : hrDefault;
  72. }
  73. HRESULT StartMsmqServiceNT()
  74. {
  75. SC_HANDLE hSvcMgr;
  76. hSvcMgr = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT );
  77. if ( hSvcMgr == NULL )
  78. {
  79. return WBEM_E_ACCESS_DENIED;
  80. }
  81. SC_HANDLE hSvc;
  82. hSvc = OpenServiceW( hSvcMgr, L"msmq", SERVICE_START );
  83. if ( hSvc == NULL )
  84. {
  85. CloseServiceHandle( hSvcMgr );
  86. return WBEM_E_ACCESS_DENIED;
  87. }
  88. BOOL bRes = StartService( hSvc, 0, NULL );
  89. CloseServiceHandle( hSvc );
  90. CloseServiceHandle( hSvcMgr );
  91. return bRes ? S_OK : HRESULT_FROM_WIN32( GetLastError() );
  92. }
  93. HRESULT StartMsmqService9x()
  94. {
  95. //
  96. // TODO: will probably have to exec process here.
  97. //
  98. return S_OK;
  99. }
  100. HRESULT EnsureMsmqService( CMsmqApi& rApi )
  101. {
  102. HRESULT hr;
  103. //
  104. // issue a call to find out if the msmq service is down.
  105. //
  106. hr = IsMsmqOnline( rApi );
  107. if ( hr == WMIMSG_E_REQSVCNOTAVAIL )
  108. {
  109. //
  110. // try to restart the service.
  111. //
  112. OSVERSIONINFO osi;
  113. ZeroMemory( &osi, sizeof(OSVERSIONINFO) );
  114. osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  115. GetVersionEx( &osi );
  116. if ( osi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS )
  117. {
  118. hr = StartMsmqServiceNT();
  119. }
  120. else
  121. {
  122. hr = StartMsmqService9x();
  123. }
  124. }
  125. if ( rApi.m_fpMQRegisterCertificate != NULL )
  126. {
  127. //
  128. // try to ensure that the calling user has an internal certificate
  129. // registered.
  130. //
  131. CALLFUNC(MQRegisterCertificate)( MQCERT_REGISTER_IF_NOT_EXIST,
  132. NULL,
  133. 0 );
  134. }
  135. return WBEM_S_NO_ERROR;
  136. }
  137. HRESULT IsMsmqWorkgroup( CMsmqApi& rApi )
  138. {
  139. HRESULT hr;
  140. //
  141. // if the MQGetPrivateComputerInformation is avaliable use it. if not,
  142. // then we have to go to the registry.
  143. //
  144. if ( rApi.m_fpMQGetPrivateComputerInformation != NULL )
  145. {
  146. MQPROPVARIANT PropVar;
  147. PropVar.vt = VT_BOOL;
  148. QMPROPID PropID = PROPID_PC_DS_ENABLED;
  149. MQPRIVATEPROPS PrivProps;
  150. PrivProps.cProp = 1;
  151. PrivProps.aPropID = &PropID;
  152. PrivProps.aPropVar = &PropVar;
  153. PrivProps.aStatus = NULL;
  154. hr = CALLFUNC(MQGetPrivateComputerInformation)( NULL, &PrivProps );
  155. if ( FAILED(hr) )
  156. {
  157. return hr;
  158. }
  159. hr = PropVar.boolVal == VARIANT_TRUE ? S_OK : S_FALSE;
  160. }
  161. else
  162. {
  163. //
  164. // TODO: Add non win2k version here ..
  165. //
  166. hr = S_FALSE;
  167. }
  168. return hr;
  169. }
  170. HRESULT IsMsmqOnline( CMsmqApi& rApi )
  171. {
  172. //
  173. // There is a public w2k func to do this, but we can't rely on it because
  174. // this module needs to run on older platforms. Going to use internal
  175. // method for now.
  176. //
  177. HRESULT hr;
  178. MQPROPVARIANT MgmtPropVar;
  179. QMPROPID MgmtPropID = PROPID_MGMT_MSMQ_CONNECTED;
  180. MQMGMTPROPS MgmtProps;
  181. MgmtProps.cProp = 1;
  182. MgmtProps.aPropID = &MgmtPropID;
  183. MgmtProps.aPropVar = &MgmtPropVar;
  184. MgmtProps.aStatus = NULL;
  185. hr = CALLFUNC(MQMgmtGetInfo)( NULL, L"MACHINE", &MgmtProps );
  186. if ( FAILED(hr) )
  187. {
  188. return MqResToWmiRes( hr );
  189. }
  190. if ( _wcsicmp( MgmtPropVar.pwszVal, MSMQ_CONNECTED ) != 0 )
  191. {
  192. return S_FALSE;
  193. }
  194. return S_OK;
  195. }
  196. HRESULT NormalizeQueueName( CMsmqApi& rApi,
  197. LPCWSTR wszEndpoint,
  198. WString& rwsFormat )
  199. {
  200. HRESULT hr;
  201. //
  202. // if there is an '=' before any '\', then it is a format name.
  203. // else it is a pathname.
  204. //
  205. WCHAR* pwchEquals = wcschr( wszEndpoint, '=' );
  206. WCHAR* pwchSlash = wcschr( wszEndpoint, '\\' );
  207. if ( pwchEquals != NULL )
  208. {
  209. if ( pwchSlash == NULL || pwchSlash > pwchEquals )
  210. {
  211. rwsFormat = wszEndpoint;
  212. return S_OK;
  213. }
  214. }
  215. WCHAR achFormat[MAX_FORMAT_NAME];
  216. ULONG cFormat = MAX_FORMAT_NAME;
  217. hr = CALLFUNC(MQPathNameToFormatName)( wszEndpoint, achFormat, &cFormat );
  218. if ( FAILED(hr) )
  219. {
  220. return hr;
  221. }
  222. rwsFormat = achFormat;
  223. return S_OK;
  224. }
  225. /**************************************************************************
  226. CMsmqApi
  227. ***************************************************************************/
  228. CMsmqApi::~CMsmqApi()
  229. {
  230. if ( m_hModule != NULL )
  231. {
  232. FreeLibrary( m_hModule );
  233. }
  234. }
  235. #define GETFUNC(FUNC) \
  236. m_fp ##FUNC = (P ##FUNC) GetProcAddress( m_hModule, #FUNC ); \
  237. if ( m_fp ##FUNC == NULL ) { return HRESULT_FROM_WIN32(GetLastError()); }
  238. #define GETFUNC_OPT(FUNC) \
  239. m_fp ##FUNC = (P ##FUNC) GetProcAddress( m_hModule, #FUNC );
  240. HRESULT CMsmqApi::Initialize()
  241. {
  242. if ( m_hModule != NULL )
  243. {
  244. return S_OK;
  245. }
  246. m_hModule = LoadLibrary( _T("mqrt") );
  247. if ( m_hModule == NULL )
  248. {
  249. //
  250. // msmq is not installed.
  251. //
  252. return WMIMSG_E_REQSVCNOTAVAIL;
  253. }
  254. GETFUNC( MQCreateQueue )
  255. GETFUNC( MQOpenQueue )
  256. GETFUNC( MQDeleteQueue )
  257. GETFUNC( MQFreeMemory )
  258. GETFUNC( MQSendMessage )
  259. GETFUNC( MQReceiveMessage )
  260. GETFUNC( MQCloseQueue )
  261. GETFUNC( MQCreateCursor )
  262. GETFUNC( MQCloseCursor )
  263. GETFUNC( MQMgmtGetInfo )
  264. GETFUNC( MQPathNameToFormatName )
  265. GETFUNC( MQGetSecurityContext )
  266. GETFUNC( MQGetQueueProperties)
  267. GETFUNC( MQFreeSecurityContext )
  268. GETFUNC_OPT( MQRegisterCertificate )
  269. GETFUNC_OPT( MQGetPrivateComputerInformation )
  270. return S_OK;
  271. }