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.

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