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.

615 lines
15 KiB

  1. /******************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. GotNet.CPP -- WMI provider class implementation
  4. Generated by Microsoft WMI Code Generation Engine
  5. TO DO: - See individual function headers
  6. - When linking, make sure you link to framedyd.lib &
  7. msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail).
  8. Description:
  9. ******************************************************************/
  10. #include "stdpch.h"
  11. #pragma hdrstop
  12. #include "GotNet.h"
  13. #include "host.h" // CHost
  14. #include "output.h" // COutput
  15. #include "diag.h"
  16. #include "oe.h"
  17. #include "proxy.h"
  18. #include "connect.h" // ConnectToPort
  19. // TO DO: Replace "NameSpace" with the appropriate namespace for your
  20. // provider instance. For instance: "root\\default or "root\\cimv2".
  21. //===================================================================
  22. //CGotNet MyGotNetSet (PROVIDER_NAME_GOTNET, L"root\\default") ;
  23. // Property names
  24. //===============
  25. const static WCHAR* pid = L"id" ;
  26. const static WCHAR* pbIEProxy = L"bIEProxy" ;
  27. const static WCHAR* pIEProxy = L"IEProxy" ;
  28. const static WCHAR* pIEProxyPort = L"IEProxyPort" ;
  29. // Counts the number of times the com object is referenced
  30. //
  31. long g_nModuleRef = 0;
  32. void
  33. AddRefModule()
  34. /*++
  35. Routine Description
  36. This routine is counts the number of time the dll/COM is being refernce.
  37. Increments the ref count
  38. Arguments
  39. none
  40. Return Value
  41. none
  42. --*/
  43. {
  44. InterlockedIncrement(&g_nModuleRef);
  45. }
  46. void
  47. ReleaseModule()
  48. /*++
  49. Routine Description
  50. This routine is decrements the ref count.
  51. Arguments
  52. none
  53. Return Value
  54. none
  55. --*/
  56. {
  57. InterlockedDecrement(&g_nModuleRef);
  58. }
  59. /*****************************************************************************
  60. *
  61. * FUNCTION : CGotNet::CGotNet
  62. *
  63. * DESCRIPTION : Constructor
  64. *
  65. * INPUTS : none
  66. *
  67. * RETURNS : nothing
  68. *
  69. * COMMENTS : Calls the Provider constructor.
  70. *
  71. *****************************************************************************/
  72. CGotNet::CGotNet ()
  73. {
  74. AddRefModule();
  75. }
  76. /*****************************************************************************
  77. *
  78. * FUNCTION : CGotNet::~CGotNet
  79. *
  80. * DESCRIPTION : Destructor
  81. *
  82. * INPUTS : none
  83. *
  84. * RETURNS : nothing
  85. *
  86. * COMMENTS :
  87. *
  88. *****************************************************************************/
  89. CGotNet::~CGotNet ()
  90. {
  91. ReleaseModule();
  92. }
  93. //***************************************************************************
  94. //
  95. // CGotNet::QueryInterface
  96. // CGotNet::AddRef
  97. // CGotNet::Release
  98. //
  99. // Purpose: IUnknown members for CInstPro object.
  100. //***************************************************************************
  101. STDMETHODIMP CGotNet::QueryInterface(REFIID riid, LPVOID* ppv)
  102. {
  103. *ppv=NULL;
  104. // Since we have dual inheritance, it is necessary to cast the return type
  105. if(riid== IID_IWbemServices)
  106. *ppv=(IWbemServices*)this;
  107. if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
  108. *ppv=(IWbemProviderInit*)this;
  109. if (NULL!=*ppv) {
  110. AddRef();
  111. return NOERROR;
  112. }
  113. else
  114. return E_NOINTERFACE;
  115. }
  116. STDMETHODIMP_(ULONG) CGotNet::AddRef(void)
  117. {
  118. return ++m_cRef;
  119. }
  120. STDMETHODIMP_(ULONG) CGotNet::Release(void)
  121. {
  122. ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
  123. if (0L == nNewCount)
  124. delete this;
  125. return nNewCount;
  126. }
  127. /***********************************************************************
  128. * *
  129. * CInstPro::Initialize *
  130. * *
  131. * Purpose: This is the implementation of IWbemProviderInit. The method *
  132. * is need to initialize with CIMOM. *
  133. * *
  134. ***********************************************************************/
  135. STDMETHODIMP CGotNet::Initialize(LPWSTR pszUser, LONG lFlags,
  136. LPWSTR pszNamespace, LPWSTR pszLocale,
  137. IWbemServices *pNamespace,
  138. IWbemContext *pCtx,
  139. IWbemProviderInitSink *pInitSink)
  140. {
  141. if(pNamespace)
  142. pNamespace->AddRef();
  143. m_pNamespace = pNamespace;
  144. //Let CIMOM know you are initialized
  145. //==================================
  146. pInitSink->SetStatus(WBEM_S_INITIALIZED,0);
  147. return WBEM_S_NO_ERROR;
  148. }
  149. //***************************************************************************
  150. //
  151. // CInstPro::CreateInstanceEnumAsync
  152. //
  153. // Purpose: Asynchronously enumerates the instances.
  154. //
  155. //***************************************************************************
  156. SCODE CGotNet::CreateInstanceEnumAsync( const BSTR RefStr, long lFlags, IWbemContext *pCtx,
  157. IWbemObjectSink FAR* pHandler)
  158. {
  159. SCODE sc;
  160. int iCnt;
  161. IWbemClassObject FAR* pNewInst;
  162. HRESULT hr;
  163. // Do a check of arguments and make sure we have pointer to Namespace
  164. if(pHandler == NULL || m_pNamespace == NULL)
  165. return WBEM_E_INVALID_PARAMETER;
  166. hr = CoImpersonateClient();
  167. if( hr != S_OK )
  168. {
  169. return hr;
  170. }
  171. for(iCnt=0; iCnt < 1; iCnt++)
  172. {
  173. sc = CreateInst(
  174. m_pNamespace,
  175. &pNewInst,
  176. RefStr,
  177. pCtx);
  178. if(sc != S_OK)
  179. break;
  180. sc = AddProps(pNewInst);
  181. if(sc != S_OK)
  182. break;
  183. // Send the object to the caller
  184. pHandler->Indicate(1,&pNewInst);
  185. pNewInst->Release();
  186. }
  187. // Set status
  188. pHandler->SetStatus(0,sc,NULL, NULL);
  189. CoRevertToSelf();
  190. return sc;
  191. }
  192. //***************************************************************************
  193. //
  194. // CGotNet::GetObjectByPath
  195. // CGetNet::GetObjectByPathAsync
  196. //
  197. // Purpose: Creates an instance given a particular path value.
  198. //
  199. //***************************************************************************
  200. SCODE CGotNet::GetObjectAsync(const BSTR ObjectPath, long lFlags,IWbemContext *pCtx,
  201. IWbemObjectSink FAR* pHandler)
  202. {
  203. SCODE sc;
  204. IWbemClassObject FAR* pObj;
  205. BOOL bOK = FALSE;
  206. // Do a check of arguments and make sure we have pointer to Namespace
  207. if(ObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL)
  208. return WBEM_E_INVALID_PARAMETER;
  209. // do the get, pass the object on to the notify
  210. sc = GetByPath(ObjectPath,&pObj, pCtx);
  211. if(sc == S_OK)
  212. {
  213. pHandler->Indicate(1,&pObj);
  214. pObj->Release();
  215. bOK = TRUE;
  216. }
  217. sc = (bOK) ? S_OK : WBEM_E_NOT_FOUND;
  218. // Set Status
  219. pHandler->SetStatus(0,sc, NULL, NULL);
  220. return sc;
  221. }
  222. //***************************************************************************
  223. //
  224. // CGotNet::GetByPath
  225. //
  226. // Purpose: Creates an instance given a particular Path value.
  227. //
  228. //***************************************************************************
  229. SCODE
  230. CGotNet::GetByPath(
  231. BSTR ObjectPath,
  232. IWbemClassObject FAR* FAR* ppObj,
  233. IWbemContext *pCtx)
  234. {
  235. SCODE sc = S_OK;
  236. if(!_wcsicmp(L"NetDiagnostics=@", ObjectPath))
  237. {
  238. sc = CreateInst(
  239. m_pNamespace,
  240. ppObj,
  241. L"NetDiagnostics",
  242. pCtx);
  243. return sc;
  244. }
  245. return WBEM_E_NOT_FOUND;
  246. }
  247. HRESULT STDMETHODCALLTYPE
  248. CGotNet::ExecMethodAsync(
  249. const BSTR ObjectPath,
  250. const BSTR MethodName,
  251. long lFlags,
  252. IWbemContext* pCtx,
  253. IWbemClassObject* pInParams,
  254. IWbemObjectSink* pResultSink)
  255. {
  256. if(0 == _wcsicmp(MethodName, L"Ping"))
  257. {
  258. return WMIPing(lFlags, pCtx, pInParams, pResultSink);
  259. }
  260. else if (0 == _wcsicmp(MethodName, L"ConnectToPort"))
  261. {
  262. return WMIConnectToPort(lFlags, pCtx, pInParams, pResultSink);
  263. }
  264. else
  265. {
  266. return WBEM_E_INVALID_PARAMETER;
  267. }
  268. }
  269. HRESULT CGotNet::WMIPing(
  270. long lFlags,
  271. IWbemContext* pCtx,
  272. IWbemClassObject* pInParams,
  273. IWbemObjectSink* pResultSink)
  274. {
  275. HRESULT hr;
  276. IWbemClassObject * pClass = NULL;
  277. IWbemClassObject * pOutClass = NULL;
  278. IWbemClassObject* pOutParams = NULL;
  279. TEST_INFO ping;
  280. CHost host;
  281. char buffer[100];
  282. WSADATA wsa;
  283. WSAStartup(MAKEWORD(2,1), &wsa);
  284. hr = CoImpersonateClient();
  285. if( hr != S_OK )
  286. {
  287. WSACleanup();
  288. return hr;
  289. }
  290. // Allocate some BSTRs
  291. BSTR ClassName = SysAllocString(L"NetDiagnostics");
  292. BSTR InputArgName = SysAllocString(L"sInAddr");
  293. BSTR OutputArgName = SysAllocString(L"sOutArg");
  294. BSTR retValName = SysAllocString(L"ReturnValue");
  295. // Get the class object, this is hard coded and matches the class
  296. // in the MOF. A more sophisticated example would parse the
  297. // ObjectPath to determine the class and possibly the instance.
  298. hr = m_pNamespace->GetObject(ClassName, 0, pCtx, &pClass, NULL);
  299. if(hr != S_OK)
  300. {
  301. pResultSink->SetStatus(0,hr, NULL, NULL);
  302. WSACleanup();
  303. CoRevertToSelf();
  304. return WBEM_S_NO_ERROR;
  305. }
  306. // This method returns values, and so create an instance of the
  307. // output argument class.
  308. hr = pClass->GetMethod(L"Ping", 0, NULL, &pOutClass);
  309. pOutClass->SpawnInstance(0, &pOutParams);
  310. // Copy the input argument into the output object
  311. auto_var var;
  312. // Get the input argument
  313. pInParams->Get(InputArgName, 0, &var, NULL, NULL);
  314. wcstombs(buffer, var.bstrVal, 100);
  315. ping.host.SetHost(buffer);
  316. CheckPing(&ping);
  317. WaitForSingleObject(ping.hEvent, INFINITE);
  318. // put it into the output object
  319. _variant_t v ((bool)(ping.dwErr == S_OK));
  320. pOutParams->Put(retValName , 0, &v, 0);
  321. v = ping.output.Status();
  322. pOutParams->Put(OutputArgName , 0, &v, 0);
  323. // Send the output object back to the client via the sink. Then
  324. // release the pointers and free the strings.
  325. hr = pResultSink->Indicate(1, &pOutParams);
  326. pOutParams->Release();
  327. pOutClass->Release();
  328. pClass->Release();
  329. SysFreeString(ClassName);
  330. SysFreeString(InputArgName);
  331. SysFreeString(OutputArgName);
  332. SysFreeString(retValName);
  333. // all done now, set the status
  334. hr = pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
  335. CoRevertToSelf();
  336. WSACleanup();
  337. return WBEM_S_NO_ERROR;
  338. }
  339. HRESULT CGotNet::WMIConnectToPort(
  340. long lFlags,
  341. IWbemContext* pCtx,
  342. IWbemClassObject* pInParams,
  343. IWbemObjectSink* pResultSink)
  344. {
  345. HRESULT hr;
  346. IWbemClassObject * pClass = NULL;
  347. IWbemClassObject * pOutClass = NULL;
  348. IWbemClassObject* pOutParams = NULL;
  349. TEST_INFO ping;
  350. CHost host;
  351. char buffer[100];
  352. bool bConnect = false;
  353. hr = CoImpersonateClient();
  354. if( hr != S_OK )
  355. {
  356. return hr;
  357. }
  358. // Allocate some BSTRs
  359. BSTR ClassName = SysAllocString(L"NetDiagnostics");
  360. BSTR AddrArgName = SysAllocString(L"sInAddr");
  361. BSTR PortArgName = SysAllocString(L"port");
  362. BSTR OutputArgName = SysAllocString(L"sOutArg");
  363. BSTR retValName = SysAllocString(L"ReturnValue");
  364. // Get the class object, this is hard coded and matches the class
  365. // in the MOF. A more sophisticated example would parse the
  366. // ObjectPath to determine the class and possibly the instance.
  367. hr = m_pNamespace->GetObject(ClassName, 0, pCtx, &pClass, NULL);
  368. if(hr != S_OK)
  369. {
  370. pResultSink->SetStatus(0,hr, NULL, NULL);
  371. CoRevertToSelf();
  372. return WBEM_S_NO_ERROR;
  373. }
  374. // This method returns values, and so create an instance of the
  375. // output argument class.
  376. hr = pClass->GetMethod(L"ConnectToPort", 0, NULL, &pOutClass);
  377. pOutClass->SpawnInstance(0, &pOutParams);
  378. // Copy the input argument into the output object
  379. auto_var addr;
  380. auto_var port;
  381. // Get the input argument
  382. pInParams->Get(AddrArgName, 0, &addr, NULL, NULL);
  383. pInParams->Get(PortArgName, 0, &port, NULL, NULL);
  384. wcstombs(buffer, addr.bstrVal, 100);
  385. host.SetHost(buffer);
  386. Connect(host, port.lVal, bConnect);
  387. // put it into the output object
  388. _variant_t v (bConnect);
  389. pOutParams->Put(retValName , 0, &v, 0);
  390. v = ping.output.Status();
  391. pOutParams->Put(OutputArgName , 0, &v, 0);
  392. // Send the output object back to the client via the sink. Then
  393. // release the pointers and free the strings.
  394. hr = pResultSink->Indicate(1, &pOutParams);
  395. pOutParams->Release();
  396. pOutClass->Release();
  397. pClass->Release();
  398. SysFreeString(ClassName);
  399. SysFreeString(AddrArgName);
  400. SysFreeString(PortArgName);
  401. SysFreeString(OutputArgName);
  402. SysFreeString(retValName);
  403. // all done now, set the status
  404. hr = pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
  405. CoRevertToSelf();
  406. return WBEM_S_NO_ERROR;
  407. }
  408. HRESULT CGotNet::AddProps(IWbemClassObject* pInstance)
  409. {
  410. HRESULT hRes = WBEM_S_NO_ERROR;
  411. CHost host;
  412. DWORD dwPort = 0;
  413. DWORD dwProxyPort = 0;
  414. DWORD dwProxyEnabled = 0;
  415. _variant_t v;
  416. v.Clear();
  417. /*
  418. //
  419. // Grab all the mail server information
  420. ///////////////////////////////////////
  421. CHost InBoundMailHost, OutBoundMailHost;
  422. DWORD dwInBoundPort, dwOutBoundPort;
  423. WCHAR wszInBoundMailType, wszOutBoundMailType;
  424. hRes = GetOEDefaultMailServer(InBoundMailHost,
  425. dwInBoundPort,
  426. wszInBoundMailType,
  427. OutBoundMailHost,
  428. dwOutBoundPort,
  429. wszOutBoundMailType);
  430. if( SUCCEEDED(hRes) )
  431. {
  432. v = InBoundMailHost.GetHost();
  433. pInstance->Put(pInBoundMailServer, 0, &v, 0);
  434. v = (long)dwInBoundPort;
  435. pInstance->Put(pInBoundMailPort, 0, &v, 0);
  436. v = wszInBoundMailType
  437. pInstance->Put(pInBoundMailType, 0, &v, 0);
  438. v = OutBoundMailHost.GetHost();
  439. pInstance->Put(pOutBoundMailServer, 0, &v, 0);
  440. v = (long)dwOutBoundPort;
  441. pInstance->Put(pOutBoundMailPort, 0, &v, 0);
  442. v = wszOutBoundMailType
  443. pInstance->Put(pOutBoundMailType, 0, &v, 0);
  444. }
  445. */
  446. //
  447. // Grab all the news server information
  448. ///////////////////////////////////////
  449. v.Clear();
  450. hRes = GetOEDefaultNewsServer(host, dwPort);
  451. v = host.GetHost();
  452. pInstance->Put(pNewsServer, 0, &v, 0);
  453. v = (long)dwPort;
  454. pInstance->Put(pNewsNNTPPort, 0, &v, 0);
  455. v.Clear();
  456. if (FindProxy(&host, &dwProxyPort, &dwProxyEnabled))
  457. {
  458. v = (bool)(dwProxyEnabled == TRUE);
  459. pInstance->Put(pbIEProxy, 0, &v, 0);
  460. v.Clear();
  461. v = host.GetHost();
  462. pInstance->Put(pIEProxy, 0, &v, 0);
  463. v.Clear();
  464. v = (long)dwProxyPort;
  465. pInstance->Put(pIEProxyPort, 0, &v, 0);
  466. }
  467. else
  468. {
  469. v = (bool)FALSE;
  470. pInstance->Put(pbIEProxy, 0, &v, 0);
  471. pInstance->Put(pIEProxy, 0, NULL, 0);
  472. pInstance->Put(pIEProxyPort, 0, NULL, 0);
  473. }
  474. return hRes;
  475. }