Leaked source code of windows server 2003
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.

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