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.

606 lines
15 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // CopyRight ( c ) 1999 Microsoft Corporation
  4. //
  5. // Module Name: server.cpp
  6. //
  7. // Description:
  8. // Implementation of CDnsserver class
  9. //
  10. // Author:
  11. // Henry Wang ( henrywa ) March 8, 2000
  12. //
  13. //
  14. //////////////////////////////////////////////////////////////////////
  15. #include "DnsWmi.h"
  16. /////////////////////////////////////////////////////////////////////////////
  17. //++
  18. //
  19. // Description:
  20. // execute methods defined for dns server class in the mof
  21. //
  22. // Arguments:
  23. // ObjPath [IN] pointing to the object that the
  24. // method should be performed on
  25. // wzMethodName [IN] name of the method to be invoked
  26. // lFlags [IN] WMI flag
  27. // pInParams [IN] Input parameters for the method
  28. // pHandler [IN] WMI sink pointer
  29. //
  30. // Return Value:
  31. // WBEM_S_NO_ERROR
  32. // WBEM_E_INVALID_PARAMETER
  33. //
  34. //--
  35. /////////////////////////////////////////////////////////////////////////////
  36. SCODE
  37. CDnsServer::ExecuteMethod(
  38. CObjPath & ObjPath,
  39. WCHAR * wzMethodName,
  40. long lFlag,
  41. IWbemClassObject * pInArgs,
  42. IWbemObjectSink * pHandler)
  43. {
  44. CDnsWrap& dns = CDnsWrap::DnsObject();
  45. #if 0
  46. //
  47. // Restart is so totally broken I'm not going to expose it.
  48. //
  49. if(_wcsicmp( wzMethodName, PVD_MTH_SRV_RESTART) == 0)
  50. {
  51. wstring wstrServer = ObjPath.GetStringValueForProperty(
  52. PVD_SRV_SERVER_NAME );
  53. int rt = dns.dnsRestartServer((WCHAR*)wstrServer.data());
  54. if( rt != ERROR_SUCCESS)
  55. {
  56. return WBEM_E_FAILED;
  57. }
  58. }
  59. else
  60. #endif
  61. if(_wcsicmp( wzMethodName, PVD_MTH_SRV_START_SERVICE) == 0)
  62. {
  63. return StartServer();
  64. }
  65. else if(_wcsicmp( wzMethodName, PVD_MTH_SRV_STOP_SERVICE) == 0)
  66. {
  67. return StopServer();
  68. }
  69. else if(_wcsicmp(
  70. wzMethodName,
  71. PVD_MTH_ZONE_GETDISTINGUISHEDNAME) == 0)
  72. {
  73. wstring wstrName ;
  74. CWbemClassObject OutParams, OutClass, Class ;
  75. HRESULT hr;
  76. dns.dnsDsServerName(wstrName);
  77. BSTR ClassName=NULL;
  78. ClassName = AllocBstr(PVD_CLASS_SERVER);
  79. hr = m_pNamespace->GetObject(ClassName, 0, 0, &Class, NULL);
  80. SysFreeString(ClassName);
  81. if ( SUCCEEDED ( hr ) )
  82. {
  83. Class.GetMethod(wzMethodName, 0, NULL, &OutClass);
  84. OutClass.SpawnInstance(0, &OutParams);
  85. OutParams.SetProperty(wstrName, PVD_DNS_RETURN_VALUE);
  86. hr = pHandler->Indicate(1, &OutParams);
  87. }
  88. return hr;
  89. }
  90. return S_OK;
  91. }
  92. /////////////////////////////////////////////////////////////////////////////
  93. //++
  94. //
  95. // Description:
  96. // retrieve record object pointed by the given object path
  97. //
  98. // Arguments:
  99. // ObjectPath [IN] object path to object
  100. // lFlags [IN] WMI flag
  101. // pCtx [IN] WMI context
  102. // pHandler [IN] WMI sink pointer
  103. //
  104. // Return Value:
  105. // WBEM_S_NO_ERROR
  106. //
  107. //--
  108. /////////////////////////////////////////////////////////////////////////////
  109. SCODE
  110. CDnsServer::GetObject(
  111. CObjPath & ObjectPath,
  112. long lFlags,
  113. IWbemContext * pCtx,
  114. IWbemObjectSink * pHandler
  115. )
  116. {
  117. SCODE sc;
  118. CWbemClassObject NewInst;
  119. sc = m_pClass->SpawnInstance(0, &NewInst);
  120. if(FAILED(sc))
  121. {
  122. return sc;
  123. }
  124. wstring wstrServerName = ObjectPath.GetStringValueForProperty(
  125. PVD_SRV_SERVER_NAME );
  126. if ( wstrServerName.empty())
  127. {
  128. return WBEM_E_FAILED;
  129. }
  130. SC_HANDLE schService = NULL;
  131. SC_HANDLE schSCManager = NULL;
  132. LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
  133. DWORD cbBufSize;
  134. DWORD BytesNeeded;
  135. SERVICE_STATUS ServiceStatus;
  136. try
  137. {
  138. if ((schSCManager = OpenSCManager (
  139. NULL, // machine (NULL == local)
  140. NULL, // database (NULL == default)
  141. SC_MANAGER_ALL_ACCESS))==NULL) // access required
  142. {
  143. throw GetLastError();
  144. }
  145. if ((schService = OpenService(
  146. schSCManager,
  147. "DNS",
  148. SERVICE_ALL_ACCESS))==NULL)
  149. {
  150. throw GetLastError();
  151. }
  152. if (QueryServiceConfig(
  153. schService, // handle to service
  154. lpServiceConfig,
  155. 0, // size of structure
  156. &cbBufSize // bytes needed
  157. ) == FALSE)
  158. {
  159. lpServiceConfig =
  160. (LPQUERY_SERVICE_CONFIG) new BYTE[cbBufSize];
  161. if ( !lpServiceConfig)
  162. {
  163. throw ( ERROR_OUTOFMEMORY );
  164. }
  165. if(QueryServiceConfig(
  166. schService, // handle to service
  167. lpServiceConfig,
  168. cbBufSize, // size of structure
  169. &BytesNeeded // bytes needed
  170. ) == FALSE)
  171. throw GetLastError();
  172. wstring wstrStartMode;
  173. switch(lpServiceConfig->dwStartType)
  174. {
  175. case SERVICE_DEMAND_START:
  176. wstrStartMode = L"Manual";
  177. break;
  178. default:
  179. wstrStartMode = L"Automatic";
  180. break;
  181. }
  182. NewInst.SetProperty(
  183. wstrStartMode,
  184. PVD_SRV_STARTMODE);
  185. if(QueryServiceStatus(
  186. schService, // handle to service
  187. &ServiceStatus // pointer to service status structure
  188. ) == FALSE)
  189. {
  190. throw GetLastError();
  191. }
  192. DWORD dwStatus;
  193. switch(ServiceStatus.dwCurrentState)
  194. {
  195. case SERVICE_RUNNING:
  196. dwStatus = 1;
  197. break;
  198. default:
  199. dwStatus = 0;
  200. }
  201. NewInst.SetProperty(
  202. dwStatus,
  203. PVD_SRV_STARTED);
  204. }
  205. CDnsWrap& dns = CDnsWrap::DnsObject();
  206. NewInst.SetProperty(
  207. dns.GetServerName(),
  208. PVD_SRV_SERVER_NAME);
  209. dns.dnsServerPropertyGet(
  210. NewInst,
  211. TRUE);
  212. }
  213. catch(DWORD dwError)
  214. {
  215. CloseServiceHandle(schService);
  216. CloseServiceHandle(schSCManager);
  217. delete [] lpServiceConfig;
  218. }
  219. catch(CDnsProvException e)
  220. {
  221. CloseServiceHandle(schService);
  222. CloseServiceHandle(schSCManager);
  223. delete [] lpServiceConfig;
  224. lpServiceConfig=NULL;
  225. // if server not running, we still want to
  226. //return an instance, so user can call start service
  227. //
  228. if(_stricmp(e.what(), "RPC_S_SERVER_UNAVAILABLE") != 0)
  229. {
  230. throw e;
  231. }
  232. }
  233. CloseServiceHandle(schService);
  234. CloseServiceHandle(schSCManager);
  235. delete [] lpServiceConfig;
  236. pHandler->Indicate(1,&NewInst);
  237. return sc;
  238. }
  239. /////////////////////////////////////////////////////////////////////////////
  240. //++
  241. //
  242. // Description:
  243. // enum instances of dns server
  244. //
  245. // Arguments:
  246. // lFlags [IN] WMI flag
  247. // pCtx [IN] WMI context
  248. // pHandler [IN] WMI sink pointer
  249. //
  250. // Return Value:
  251. // WBEM_S_NO_ERROR
  252. //
  253. //--
  254. /////////////////////////////////////////////////////////////////////////////
  255. SCODE
  256. CDnsServer::EnumInstance(
  257. long lFlags,
  258. IWbemContext * pCtx,
  259. IWbemObjectSink * pHandler
  260. )
  261. {
  262. // there is only one instance
  263. CObjPath ObjPath;
  264. ObjPath.SetClass(PVD_CLASS_SERVER);
  265. ObjPath.AddProperty(
  266. PVD_SRV_SERVER_NAME,
  267. PVD_DNS_LOCAL_SERVER);
  268. return GetObject(ObjPath, lFlags,pCtx,pHandler);
  269. }
  270. //////////////////////////////////////////////////////////////////////
  271. // Construction/Destruction
  272. //////////////////////////////////////////////////////////////////////
  273. CDnsServer::CDnsServer()
  274. {
  275. }
  276. CDnsServer::CDnsServer(
  277. const WCHAR* wszName,
  278. CWbemServices *pNamespace)
  279. :CDnsBase(wszName, pNamespace)
  280. {
  281. }
  282. CDnsServer::~CDnsServer()
  283. {
  284. }
  285. /////////////////////////////////////////////////////////////////////////////
  286. //++
  287. //
  288. // Description:
  289. // create an instance of CDnsServer
  290. //
  291. // Arguments:
  292. // wszName [IN] class name
  293. // pNamespace [IN] wmi namespace
  294. // szType [IN] child class name of resource record class
  295. //
  296. // Return Value:
  297. // WBEM_S_NO_ERROR
  298. //
  299. //--
  300. /////////////////////////////////////////////////////////////////////////////
  301. CDnsBase*
  302. CDnsServer::CreateThis(
  303. const WCHAR * wszName,
  304. CWbemServices * pNamespace,
  305. const char * szType
  306. )
  307. {
  308. return new CDnsServer(wszName, pNamespace);
  309. }
  310. /////////////////////////////////////////////////////////////////////////////
  311. //++
  312. //
  313. // Description:
  314. // start dns server
  315. //
  316. // Arguments:
  317. // Return Value:
  318. //
  319. //
  320. //--
  321. /////////////////////////////////////////////////////////////////////////////
  322. SCODE
  323. CDnsServer::StartServer()
  324. {
  325. SC_HANDLE schService = NULL;
  326. SC_HANDLE schSCManager = NULL;
  327. try
  328. {
  329. if ((schSCManager = OpenSCManager (
  330. NULL, // machine (NULL == local)
  331. NULL, // database (NULL == default)
  332. SC_MANAGER_ALL_ACCESS))==NULL) // access required
  333. {
  334. throw GetLastError();
  335. }
  336. if ((schService = OpenService(
  337. schSCManager,
  338. "DNS",
  339. SERVICE_ALL_ACCESS))==NULL)
  340. {
  341. throw GetLastError();
  342. }
  343. // make sure database is not locked
  344. QUERY_SERVICE_LOCK_STATUS qsls;
  345. DWORD dwbBytesNeeded, dwRet=1;
  346. while(dwRet)
  347. {
  348. if(!QueryServiceLockStatus(
  349. schSCManager,
  350. &qsls,
  351. sizeof(qsls)+2,
  352. &dwbBytesNeeded))
  353. {
  354. throw GetLastError();
  355. }
  356. if( (dwRet = qsls.fIsLocked) > 0)
  357. {
  358. Sleep(2000);
  359. }
  360. }
  361. if (StartService(
  362. schService,
  363. 0,
  364. NULL)==FALSE)
  365. {
  366. throw GetLastError();
  367. }
  368. DWORD dwTimeOut=6000; // 6 sec
  369. DWORD dwTimeCount=0;
  370. while ( dwTimeCount < dwTimeOut)
  371. {
  372. SERVICE_STATUS ServiceStatus;
  373. if(QueryServiceStatus(
  374. schService, // handle to service
  375. &ServiceStatus // pointer to service status structure
  376. ) == FALSE)
  377. {
  378. throw GetLastError();
  379. }
  380. if(ServiceStatus.dwCurrentState != SERVICE_RUNNING)
  381. {
  382. Sleep(2000);
  383. dwTimeCount +=2000;
  384. }
  385. else
  386. {
  387. break;
  388. }
  389. }
  390. }
  391. catch(DWORD dwError)
  392. {
  393. CloseServiceHandle(schService);
  394. CloseServiceHandle(schSCManager);
  395. CHAR szErrDesc[MAX_PATH];
  396. FormatMessage(
  397. FORMAT_MESSAGE_FROM_SYSTEM |
  398. FORMAT_MESSAGE_IGNORE_INSERTS,
  399. NULL,
  400. dwError,
  401. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  402. szErrDesc,
  403. MAX_PATH,
  404. NULL
  405. );
  406. CHAR szErr[MAX_PATH];
  407. strcpy(szErr, "Fail to start Dns because ");
  408. strcat(szErr, szErrDesc);
  409. CDnsProvException e(szErr);
  410. throw e;
  411. }
  412. CloseServiceHandle(schService);
  413. CloseServiceHandle(schSCManager);
  414. return S_OK;
  415. }
  416. /////////////////////////////////////////////////////////////////////////////
  417. //++
  418. //
  419. // Description:
  420. // stop dns server
  421. //
  422. // Arguments:
  423. // Return Value:
  424. //
  425. //
  426. //--
  427. /////////////////////////////////////////////////////////////////////////////
  428. SCODE
  429. CDnsServer::StopServer()
  430. {
  431. SERVICE_STATUS ss;
  432. SC_HANDLE schService = NULL;
  433. SC_HANDLE schSCManager = NULL;
  434. try
  435. {
  436. if ((schSCManager = OpenSCManager (
  437. NULL, // machine (NULL == local)
  438. NULL, // database (NULL == default)
  439. SC_MANAGER_ALL_ACCESS))==NULL) // access required
  440. {
  441. throw GetLastError();
  442. }
  443. if ((schService = OpenService(
  444. schSCManager,
  445. "DNS",
  446. SERVICE_ALL_ACCESS))==NULL)
  447. {
  448. throw GetLastError();
  449. }
  450. if (ControlService(
  451. schService,
  452. SERVICE_CONTROL_STOP,
  453. (LPSERVICE_STATUS)&ss) == FALSE)
  454. {
  455. throw GetLastError();
  456. }
  457. // check its state
  458. DWORD dwTimeOut=6000; // 6 sec
  459. DWORD dwTimeCount=0;
  460. while ( dwTimeCount < dwTimeOut)
  461. {
  462. SERVICE_STATUS ServiceStatus;
  463. if(QueryServiceStatus(
  464. schService, // handle to service
  465. &ServiceStatus // pointer to service status structure
  466. ) == FALSE)
  467. {
  468. throw GetLastError();
  469. }
  470. if(ServiceStatus.dwCurrentState != SERVICE_STOPPED)
  471. {
  472. Sleep(2000);
  473. dwTimeCount +=2000;
  474. }
  475. else
  476. break;
  477. }
  478. }
  479. catch(DWORD dwError)
  480. {
  481. CloseServiceHandle(schService);
  482. CloseServiceHandle(schSCManager);
  483. CHAR szErrDesc[MAX_PATH];
  484. FormatMessage(
  485. FORMAT_MESSAGE_FROM_SYSTEM |
  486. FORMAT_MESSAGE_IGNORE_INSERTS,
  487. NULL,
  488. dwError,
  489. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  490. szErrDesc,
  491. MAX_PATH,
  492. NULL
  493. );
  494. CHAR szErr[MAX_PATH];
  495. strcpy(szErr, "Fail to stop Dns because ");
  496. strcat(szErr, szErrDesc);
  497. CDnsProvException e(szErr);
  498. throw e;
  499. }
  500. CloseServiceHandle(schService);
  501. CloseServiceHandle(schSCManager);
  502. return WBEM_S_NO_ERROR;
  503. }
  504. /////////////////////////////////////////////////////////////////////////////
  505. //++
  506. //
  507. // Description:
  508. // save this instance
  509. //
  510. // Arguments:
  511. // InstToPut [IN] WMI object to be saved
  512. // lFlags [IN] WMI flag
  513. // pCtx [IN] WMI context
  514. // pHandler [IN] WMI sink pointer
  515. //
  516. // Return Value:
  517. //
  518. //
  519. //--
  520. /////////////////////////////////////////////////////////////////////////////
  521. SCODE
  522. CDnsServer::PutInstance(
  523. IWbemClassObject * pInst ,
  524. long lFlags,
  525. IWbemContext* pCtx ,
  526. IWbemObjectSink * pHandler
  527. )
  528. {
  529. DBG_FN( "CDnsServer::PutInstance" )
  530. DNS_DEBUG( INSTPROV, (
  531. "%s: pInst=%p\n", fn, pInst ));
  532. CDnsWrap& dns = CDnsWrap::DnsObject();
  533. CWbemClassObject Inst(pInst);
  534. dns.dnsServerPropertySet(
  535. Inst,
  536. FALSE);
  537. return S_OK;
  538. };