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.

421 lines
17 KiB

  1. /******************************************************************
  2. SNetScal.cpp -- WBEM provider class implementation
  3. MODULE:
  4. DhcpProv.dll
  5. DESCRIPTION:
  6. Contains: the definition of the DHCP_Subnet class,
  7. the static table of manageable objects.
  8. REVISION:
  9. 08/03/98 - created
  10. ******************************************************************/
  11. #include <stdafx.h>
  12. #include "SNetFn.h" // needed for the declarations of all the functions.
  13. #include "SNetScal.h" // own header
  14. // static table of CDHCP_Property objects containing the DHCP Server
  15. // scalar parameters (properties) which are WBEM manageable. Each object associates
  16. // the name of the property with their SET and GET functions.
  17. // *** NOTE ***
  18. // The name of each property has to be in sync with the ones specified in the DhcpSchema.mof.
  19. // The indices specified in SrvScal.h should also be in sync with the actual row from this table (they are used
  20. // in the property's action functions.
  21. static const CDHCP_Property DHCP_Subnet_Property[]=
  22. {
  23. CDHCP_Property(L"Address", fnSNetGetAddress, NULL),
  24. CDHCP_Property(L"Mask", fnSNetGetMask, NULL),
  25. CDHCP_Property(L"Name", fnSNetGetName, fnSNetSetName),
  26. CDHCP_Property(L"Comment", fnSNetGetComment, fnSNetSetComment),
  27. CDHCP_Property(L"State", fnSNetGetState, fnSNetSetState),
  28. CDHCP_Property(L"NumberOfAddressesInUse", fnSNetGetNumberOfAddressesInUse, NULL),
  29. CDHCP_Property(L"NumberOfAddressesFree", fnSNetGetNumberOfAddressesFree, NULL),
  30. CDHCP_Property(L"NumberOfPendingOffers", fnSNetGetNumberOfPendingOffers, NULL)
  31. };
  32. // the name of the WBEM class
  33. #define PROVIDER_NAME_DHCP_SUBNET "DHCP_Subnet"
  34. // main class instantiation.
  35. CDHCP_Subnet MyDHCP_Subnet_Scalars (PROVIDER_NAME_DHCP_SUBNET, PROVIDER_NAMESPACE_DHCP) ;
  36. /*****************************************************************************
  37. *
  38. * FUNCTION : CDHCP_Subnet::CDHCP_Subnet
  39. *
  40. * DESCRIPTION : Constructor
  41. *
  42. * INPUTS : none
  43. *
  44. * RETURNS : nothing
  45. *
  46. * COMMENTS : Calls the Provider constructor.
  47. *
  48. *****************************************************************************/
  49. CDHCP_Subnet::CDHCP_Subnet (const CHString& strName, LPCSTR pszNameSpace ) :
  50. Provider(strName, pszNameSpace)
  51. {
  52. }
  53. /*****************************************************************************
  54. *
  55. * FUNCTION : CDHCP_Subnet::~CDHCP_Subnet
  56. *
  57. * DESCRIPTION : Destructor
  58. *
  59. * INPUTS : none
  60. *
  61. * RETURNS : nothing
  62. *
  63. * COMMENTS :
  64. *
  65. *****************************************************************************/
  66. CDHCP_Subnet::~CDHCP_Subnet ()
  67. {
  68. }
  69. /*****************************************************************************
  70. *
  71. * FUNCTION : CDHCP_Subnet::EnumerateInstances
  72. *
  73. * DESCRIPTION : Returns all the instances of this class.
  74. *
  75. * INPUTS : none
  76. *
  77. * RETURNS : WBEM_S_NO_ERROR if successful
  78. *
  79. * COMMENTS : Enumerates all this instances of this class. As there is only one
  80. * DHCP Server per system, there is only one instance for this class
  81. *
  82. *****************************************************************************/
  83. HRESULT CDHCP_Subnet::EnumerateInstances ( MethodContext* pMethodContext, long lFlags )
  84. {
  85. CInstance* pInstance;
  86. CDHCP_Subnet_Parameters subnetParams(0); // don't know here the IP address
  87. LPDHCP_MIB_INFO pMibInfo;
  88. LPSCOPE_MIB_INFO pScopeMibInfo;
  89. HRESULT hRes = WBEM_E_FAILED;
  90. if (subnetParams.GetMibInfo(pMibInfo, pScopeMibInfo, TRUE) && pMibInfo != NULL)
  91. {
  92. hRes = WBEM_S_NO_ERROR;
  93. for (int i=0; hRes == WBEM_S_NO_ERROR && i < pMibInfo->Scopes; i++)
  94. {
  95. LPSCOPE_MIB_INFO pScope = &(pMibInfo->ScopeInfo[i]); // this is the info from the server,
  96. CInstance* pInstance = CreateNewInstance(pMethodContext); // create now the instance
  97. if (pScope != NULL &&
  98. pInstance != NULL)
  99. {
  100. WCHAR szSubnetAddr[16]; // should be enough for holding 'xxx.yyy.zzz.uuu\0'
  101. // don't want to link to ws2_32.lib just for using inet_ntoa only
  102. swprintf(szSubnetAddr, L"%u.%u.%u.%u",(pScope->Subnet & 0xff000000) >> 24,
  103. (pScope->Subnet & 0x00ff0000) >> 16,
  104. (pScope->Subnet & 0x0000ff00) >> 8,
  105. (pScope->Subnet & 0x000000ff));
  106. if (pInstance->SetCHString(DHCP_Subnet_Property[IDX_SNET_Address].m_wsPropName, szSubnetAddr) &&
  107. LoadInstanceProperties(pInstance))
  108. {
  109. hRes = Commit(pInstance);
  110. // now everything relys on the err returned above.
  111. continue;
  112. }
  113. }
  114. // at this point something should have definitively gone wrong
  115. hRes = WBEM_E_FAILED;
  116. }
  117. }
  118. return hRes ;
  119. }
  120. /*****************************************************************************
  121. *
  122. * FUNCTION : CDHCP_Subnet::GetObject
  123. *
  124. * DESCRIPTION : Find a single instance based on the key properties for the
  125. * class.
  126. *
  127. * INPUTS : A pointer to a CInstance object containing the key properties.
  128. *
  129. * RETURNS : WBEM_S_NO_ERROR if the instance can be found
  130. * WBEM_E_NOT_FOUND if the instance described by the key properties
  131. * could not be found
  132. * WBEM_E_FAILED if the instance could be found but another error
  133. * occurred.
  134. *
  135. * COMMENTS :
  136. *
  137. *****************************************************************************/
  138. HRESULT CDHCP_Subnet::GetObject ( CInstance* pInstance, long lFlags )
  139. {
  140. return LoadInstanceProperties(pInstance)? WBEM_S_NO_ERROR : WBEM_E_NOT_FOUND;
  141. }
  142. /*****************************************************************************
  143. *
  144. * FUNCTION : CDHCP_Subnet::ExecQuery
  145. *
  146. * DESCRIPTION : You are passed a method context to use in the creation of
  147. * instances that satisfy the query, and a CFrameworkQuery
  148. * which describes the query. Create and populate all
  149. * instances which satisfy the query. CIMOM will post -
  150. * filter the query for you, you may return more instances
  151. * or more properties than are requested and CIMOM
  152. * will filter out any that do not apply.
  153. *
  154. *
  155. * INPUTS :
  156. *
  157. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not supported for this class
  158. * WBEM_E_FAILED if the query failed
  159. * WBEM_S_NO_ERROR if query was successful
  160. *
  161. * COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, cimom
  162. * will call your enumerate function to get all the instances and perform the
  163. * filtering for you. Unless you expect SIGNIFICANT savings from implementing
  164. * queries, you should remove this entire method.
  165. *
  166. *****************************************************************************/
  167. HRESULT CDHCP_Subnet::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
  168. {
  169. return (WBEM_E_PROVIDER_NOT_CAPABLE);
  170. }
  171. /*****************************************************************************
  172. *
  173. * FUNCTION : CDHCP_Subnet::PutInstance
  174. *
  175. * DESCRIPTION : PutInstance should be used in provider classes that can write
  176. * instance information back to the hardware or software.
  177. * For example: Win32_Environment will allow a PutInstance of a new
  178. * environment variable, because environment variables are "software"
  179. * related. However, a class like Win32_MotherboardDevice will not
  180. * allow editing of the bus speed. Since by default PutInstance
  181. * returns WBEM_E_PROVIDER_NOT_CAPABLE, this function is placed here as a
  182. * skeleton, but can be removed if not used.
  183. *
  184. * INPUTS :
  185. *
  186. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
  187. * WBEM_E_FAILED if there is an error delivering the instance
  188. * WBEM_E_INVALID_PARAMETER if any of the instance properties
  189. * are incorrect.
  190. * WBEM_S_NO_ERROR if instance is properly delivered
  191. *
  192. * COMMENTS : TO DO: If you don't intend to support writing to your provider, remove this method.
  193. *
  194. *****************************************************************************/
  195. HRESULT CDHCP_Subnet::PutInstance ( const CInstance &Instance, long lFlags)
  196. {
  197. int i;
  198. DWORD returnCode;
  199. CHString strName, strMask;
  200. DHCP_IP_ADDRESS dwAddress, dwMask;
  201. LPDHCP_SUBNET_INFO pSubnetInfo;
  202. BOOL newInstance;
  203. if (!Instance.GetCHString(DHCP_Subnet_Property[IDX_SNET_Address].m_wsPropName, strName) ||
  204. !Instance.GetCHString(DHCP_Subnet_Property[IDX_SNET_Mask].m_wsPropName, strMask) ||
  205. !inet_wstodw(strName, dwAddress) ||
  206. !inet_wstodw(strMask, dwMask))
  207. return FALSE;
  208. // the object below is used as a "repository" for all the properties' values.
  209. // once it is filled up with data, it is commited explicitely to the DHCP Server.
  210. CDHCP_Subnet_Parameters SubnetParameters(dwAddress, dwMask);
  211. // first get the subnet information, just to get the info that doesn't change
  212. // if fails => a new instance has to be created
  213. newInstance = !SubnetParameters.GetSubnetInfo(pSubnetInfo,TRUE);
  214. for (i = 0; i < NUM_SUBNET_PROPERTIES; i++)
  215. {
  216. if (DHCP_Subnet_Property[i].m_pfnActionSet != NULL)
  217. {
  218. // execute the SET property action function
  219. // because of the last NULL, no data is written to DHCP Server at this moment,
  220. // only SubnetParameters object is filled up with the values taken from the Instance.
  221. // don't care much here about the error codes. Failure means some properties will
  222. // not be written. At least we are giving a chance to all the writable properties.
  223. (*(DHCP_Subnet_Property[i].m_pfnActionSet))(&SubnetParameters, (CInstance *)&Instance, NULL);
  224. }
  225. }
  226. if (newInstance)
  227. return SubnetParameters.CommitNew(returnCode) ? WBEM_S_NO_ERROR : WBEM_E_FAILED;
  228. else
  229. // commit the values of all the writable properties to DHCP Server
  230. return SubnetParameters.CommitSet(returnCode) ? WBEM_S_NO_ERROR : WBEM_E_FAILED;
  231. }
  232. /*****************************************************************************
  233. *
  234. * FUNCTION : CDHCP_Subnet::DeleteInstance
  235. *
  236. * DESCRIPTION : DeleteInstance, like PutInstance, actually writes information
  237. * to the software or hardware. For most hardware devices,
  238. * DeleteInstance should not be implemented, but for software
  239. * configuration, DeleteInstance implementation is plausible.
  240. * Like PutInstance, DeleteInstance returns WBEM_E_PROVIDER_NOT_CAPABLE from
  241. * inside Provider::DeleteInstance (defined in Provider.h). So, if
  242. * you choose not to implement DeleteInstance, remove this function
  243. * definition and the declaration from DHCP_Server_Scalars.h
  244. *
  245. * INPUTS :
  246. *
  247. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available.
  248. * WBEM_E_FAILED if there is an error deleting the instance.
  249. * WBEM_E_INVALID_PARAMETER if any of the instance properties
  250. * are incorrect.
  251. * WBEM_S_NO_ERROR if instance is properly deleted.
  252. *
  253. * COMMENTS : TO DO: If you don't intend to support deleting instances, remove this method.
  254. *
  255. *****************************************************************************/
  256. HRESULT CDHCP_Subnet::DeleteInstance ( const CInstance &Instance, long lFlags )
  257. {
  258. DWORD returnCode;
  259. CHString str;
  260. DHCP_IP_ADDRESS dwAddress;
  261. if (!Instance.GetCHString(DHCP_Subnet_Property[IDX_SNET_Address].m_wsPropName, str) ||
  262. !inet_wstodw(str, dwAddress))
  263. return (WBEM_E_FAILED);
  264. // the object below is used as a "repository" for all the properties' values.
  265. // once it is filled up with data, it is commited explicitely to the DHCP Server.
  266. CDHCP_Subnet_Parameters SubnetParameters(dwAddress);
  267. return SubnetParameters.DeleteSubnet() ? WBEM_S_NO_ERROR : WBEM_E_FAILED;
  268. }
  269. /*****************************************************************************
  270. *
  271. * FUNCTION : CDHCP_Subnet::ExecMethod
  272. *
  273. * DESCRIPTION : Override this function to provide support for methods.
  274. * A method is an entry point for the user of your provider
  275. * to request your class perform some function above and
  276. * beyond a change of state. (A change of state should be
  277. * handled by PutInstance() )
  278. *
  279. * INPUTS : A pointer to a CInstance containing the instance the method was executed against.
  280. * A string containing the method name
  281. * A pointer to the CInstance which contains the IN parameters.
  282. * A pointer to the CInstance to contain the OUT parameters.
  283. * A set of specialized method flags
  284. *
  285. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not implemented for this class
  286. * WBEM_S_NO_ERROR if method executes successfully
  287. * WBEM_E_FAILED if error occurs executing method
  288. *
  289. * COMMENTS : TO DO: If you don't intend to support Methods, remove this method.
  290. *
  291. *****************************************************************************/
  292. HRESULT CDHCP_Subnet::ExecMethod ( const CInstance& Instance,
  293. const BSTR bstrMethodName,
  294. CInstance *pInParams,
  295. CInstance *pOutParams,
  296. long lFlags)
  297. {
  298. int i;
  299. DWORD returnCode;
  300. CHString str;
  301. DHCP_IP_ADDRESS dwAddress;
  302. LPDHCP_SUBNET_INFO pSubnetInfo;
  303. int nSetPrefixLen = wcslen(_SNET_SET_PREFIX);
  304. if (!Instance.GetCHString(DHCP_Subnet_Property[IDX_SNET_Address].m_wsPropName, str) ||
  305. !inet_wstodw(str, dwAddress))
  306. return FALSE;
  307. // build the object identifying the subnet against which the method is executed
  308. CDHCP_Subnet_Parameters SubnetParameters(dwAddress);
  309. // get the subnet information, just to preserve the info that doesn't change
  310. if (!SubnetParameters.GetSubnetInfo(pSubnetInfo,TRUE))
  311. return WBEM_E_FAILED;
  312. // is it a "SET" operation?
  313. if (!_wcsnicmp (bstrMethodName, _SNET_SET_PREFIX, nSetPrefixLen))
  314. {
  315. int i;
  316. WCHAR *wcsPropertyName = bstrMethodName + nSetPrefixLen; // pointer to the property name
  317. // scan the DHCP_Subnet_Property table looking for the property's row
  318. for (i = 0; i < NUM_SUBNET_PROPERTIES; i++)
  319. {
  320. // if the property row is found
  321. if (!_wcsicmp(wcsPropertyName, DHCP_Subnet_Property[i].m_wsPropName))
  322. {
  323. // see if the property is writable
  324. if (DHCP_Subnet_Property[i].m_pfnActionSet != NULL)
  325. {
  326. // execute the SET property action function
  327. // because of the pOutParams, the method will be commited inside the call
  328. if ((*(DHCP_Subnet_Property[i].m_pfnActionSet))(&SubnetParameters, pInParams, pOutParams))
  329. // everything worked fine.
  330. return WBEM_S_NO_ERROR;
  331. else
  332. // an error occured during "SET"
  333. return WBEM_E_FAILED;
  334. }
  335. else
  336. // no, the property cannot be written. (shouldn't really happen, as the methods from the
  337. // repository should match the writable properties only)
  338. return WBEM_E_READ_ONLY;
  339. }
  340. }
  341. }
  342. // if this point was reached, no method was found => provider not capable
  343. return WBEM_E_PROVIDER_NOT_CAPABLE;
  344. }
  345. /*****************************************************************************
  346. *
  347. * FUNCTION : CDHCP_Subnet::LoadInstanceProperties
  348. *
  349. * RETURNS : TRUE if the values for all the properties was loaded successfully,
  350. * FALSE otherwise.
  351. *
  352. * COMMENTS : It loops through the Server_Property table, calling the GET functions.
  353. *
  354. *****************************************************************************/
  355. BOOL CDHCP_Subnet::LoadInstanceProperties(CInstance* pInstance)
  356. {
  357. CHString str;
  358. DHCP_IP_ADDRESS dwAddress;
  359. if (!pInstance->GetCHString(DHCP_Subnet_Property[IDX_SNET_Address].m_wsPropName, str) ||
  360. !inet_wstodw(str, dwAddress))
  361. return FALSE;
  362. // there should be used this object, in order to not call several times the DHCP Server API.
  363. CDHCP_Subnet_Parameters SubnetParameters(dwAddress);
  364. for (int i = 0; i < NUM_SUBNET_PROPERTIES; i++)
  365. {
  366. // if there is an invisible property (does not support GET) just skip it.
  367. if (DHCP_Subnet_Property[i].m_pfnActionGet == NULL)
  368. continue;
  369. // call the appropriate GET function, fail if the call fails (there should be no reason for failure)
  370. if (!(*(DHCP_Subnet_Property[i].m_pfnActionGet))(&SubnetParameters, NULL, pInstance))
  371. return FALSE;
  372. }
  373. return TRUE;
  374. }