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.

413 lines
17 KiB

  1. /******************************************************************
  2. ResScal.cpp -- WBEM provider class implementation
  3. MODULE:
  4. DhcpProv.dll
  5. DESCRIPTION:
  6. Contains: the definition of the DHCP_Reservation class,
  7. the static table of manageable objects.
  8. REVISION:
  9. 08/14/98 - created
  10. ******************************************************************/
  11. #include <stdafx.h>
  12. #include "ResFn.h" // needed for the declarations of all the functions.
  13. #include "ResScal.h" // own header
  14. #include "SrvFn.h" // for server parameters
  15. #include "LsFn.h" // for lease parameters
  16. // static table of CDHCP_Property objects containing the DHCP Reservation
  17. // scalar parameters (properties) which are WBEM manageable. Each object associates
  18. // the name of the property with their SET and GET functions.
  19. // *** NOTE ***
  20. // The name of each property has to be in sync with the ones specified in the DhcpSchema.mof.
  21. // The indices specified in ResScal.h should also be in sync with the actual row from this table (they are used
  22. // in the property's action functions.
  23. static const CDHCP_Property DHCP_Reservation_Property[]=
  24. {
  25. // CDHCP_Property(L"Subnet", fnResGetSubnet, NULL),
  26. // CDHCP_Property(L"Address", fnResGetAddress, fnResSetAddress),
  27. // CDHCP_Property(L"UniqueClientIdentifier", fnResGetHdwAddress, fnResSetHdwAddress),
  28. CDHCP_Property(L"ReservationType", fnResGetReservationType, fnResSetReservationType)
  29. };
  30. // the name of the WBEM class
  31. #define PROVIDER_NAME_DHCP_RESERVATION "DHCP_Reservation"
  32. // main class instantiation.
  33. CDHCP_Reservation MyDHCP_Reservation_Scalars (PROVIDER_NAME_DHCP_RESERVATION, PROVIDER_NAMESPACE_DHCP) ;
  34. /*****************************************************************************
  35. *
  36. * FUNCTION : CDHCP_Reservation::CDHCP_Reservation
  37. *
  38. * DESCRIPTION : Constructor
  39. *
  40. * INPUTS : none
  41. *
  42. * RETURNS : nothing
  43. *
  44. * COMMENTS : Calls the Provider constructor.
  45. *
  46. *****************************************************************************/
  47. CDHCP_Reservation::CDHCP_Reservation (const CHString& strName, LPCSTR pszNameSpace ) :
  48. CDHCP_Lease(strName, pszNameSpace)
  49. {
  50. }
  51. /*****************************************************************************
  52. *
  53. * FUNCTION : CDHCP_Reservation::~CDHCP_Reservation
  54. *
  55. * DESCRIPTION : Destructor
  56. *
  57. * INPUTS : none
  58. *
  59. * RETURNS : nothing
  60. *
  61. * COMMENTS :
  62. *
  63. *****************************************************************************/
  64. CDHCP_Reservation::~CDHCP_Reservation ()
  65. {
  66. }
  67. /*****************************************************************************
  68. *
  69. * FUNCTION : CDHCP_Reservation::EnumerateInstances
  70. *
  71. * DESCRIPTION : Returns all the instances of this class.
  72. *
  73. * INPUTS : none
  74. *
  75. * RETURNS : WBEM_S_NO_ERROR if successful
  76. *
  77. * COMMENTS : Enumerates all this instances of this class. Here we scan
  78. * all the subnets, for which we get the info on all
  79. * clients.
  80. *****************************************************************************/
  81. HRESULT CDHCP_Reservation::EnumerateInstances ( MethodContext* pMethodContext, long lFlags )
  82. {
  83. CDHCP_Server_Parameters srvParams;
  84. LPDHCP_MIB_INFO pSrvMibInfo;
  85. if (srvParams.GetMibInfo(pSrvMibInfo, TRUE))
  86. {
  87. // loop through all the subnets configured on the local server
  88. for (int i = 0; i < pSrvMibInfo->Scopes; i++)
  89. {
  90. DWORD dwSubnet;
  91. DHCP_RESUME_HANDLE ResumeHandle;
  92. dwSubnet = pSrvMibInfo->ScopeInfo[i].Subnet;
  93. CDHCP_Reservation_Parameters resParams(dwSubnet, 0);
  94. ResumeHandle = 0;
  95. // for each subnet, loop through all the client buffers belonging to it
  96. do
  97. {
  98. HRESULT hRes = WBEM_S_NO_ERROR;
  99. // load the next buffer
  100. LONG t_Res = resParams.NextSubnetReservation(ResumeHandle) ;
  101. if ( t_Res < 0 )
  102. return WBEM_E_FAILED; // will fail here
  103. if ( t_Res == 0 )
  104. return WBEM_S_NO_ERROR ;
  105. // for the current buffer, loop through all the clients
  106. for (int j = 0; hRes == WBEM_S_NO_ERROR && j < resParams.m_pReservationInfoArray->NumElements; j++)
  107. {
  108. // this is finally the info of the current client
  109. LPDHCP_IP_RESERVATION_V4 pReservation = RESERVATION_CAST(resParams.m_pReservationInfoArray->Elements[j].Element.ReservedIp);
  110. WCHAR wcsSubnet[16], wcsAddress[16]; // should be enough for holding 'xxx.yyy.zzz.uuu\0'
  111. // build the str representation of the Subnet address
  112. swprintf(wcsSubnet, L"%u.%u.%u.%u",(dwSubnet & 0xff000000) >> 24,
  113. (dwSubnet & 0x00ff0000) >> 16,
  114. (dwSubnet & 0x0000ff00) >> 8,
  115. (dwSubnet & 0x000000ff));
  116. // build the str representation of the ReservationIpAddress address
  117. swprintf(wcsAddress, L"%u.%u.%u.%u",(pReservation->ReservedIpAddress & 0xff000000) >> 24,
  118. (pReservation->ReservedIpAddress & 0x00ff0000) >> 16,
  119. (pReservation->ReservedIpAddress & 0x0000ff00) >> 8,
  120. (pReservation->ReservedIpAddress & 0x000000ff));
  121. // update the second key into the resParams
  122. resParams.m_dwReservationAddress = pReservation->ReservedIpAddress;
  123. // we finally have everything we need for the creating one more instance
  124. CInstance* pInstance = CreateNewInstance(pMethodContext);
  125. // initialize the instance with the key info and call LoadInstanceProperties for the rest of the info
  126. if (pInstance->SetCHString(DHCP_Lease_Property[IDX_Ls_Subnet].m_wsPropName, wcsSubnet) &&
  127. pInstance->SetCHString(DHCP_Lease_Property[IDX_Ls_Address].m_wsPropName, wcsAddress) &&
  128. LoadInstanceProperties(pInstance))
  129. {
  130. hRes = Commit(pInstance);
  131. // now everything relys on the err returned above.
  132. }
  133. }
  134. // if there was an error above, bail
  135. if (hRes != WBEM_S_NO_ERROR)
  136. return WBEM_E_FAILED;
  137. } while (ResumeHandle != 0); // bail if ResumeHandle got back to 0 (the end was reached)
  138. }
  139. }
  140. return WBEM_S_NO_ERROR;
  141. }
  142. /*****************************************************************************
  143. *
  144. * FUNCTION : CDHCP_Reservation::GetObject
  145. *
  146. * DESCRIPTION : Find a single instance based on the key properties for the
  147. * class.
  148. *
  149. * INPUTS : A pointer to a CInstance object containing the key properties.
  150. *
  151. * RETURNS : WBEM_S_NO_ERROR if the instance can be found
  152. * WBEM_E_NOT_FOUND if the instance described by the key properties
  153. * could not be found
  154. * WBEM_E_FAILED if the instance could be found but another error
  155. * occurred.
  156. *
  157. * COMMENTS :
  158. *
  159. *****************************************************************************/
  160. HRESULT CDHCP_Reservation::GetObject ( CInstance* pInstance, long lFlags )
  161. {
  162. return LoadInstanceProperties(pInstance)? WBEM_S_NO_ERROR : WBEM_E_NOT_FOUND;
  163. }
  164. /*****************************************************************************
  165. *
  166. * FUNCTION : CDHCP_Reservation::PutInstance
  167. *
  168. * DESCRIPTION : PutInstance should be used in provider classes that can write
  169. * instance information back to the hardware or software.
  170. * For example: Win32_Environment will allow a PutInstance of a new
  171. * environment variable, because environment variables are "software"
  172. * related. However, a class like Win32_MotherboardDevice will not
  173. * allow editing of the bus speed. Since by default PutInstance
  174. * returns WBEM_E_PROVIDER_NOT_CAPABLE, this function is placed here as a
  175. * skeleton, but can be removed if not used.
  176. *
  177. * INPUTS :
  178. *
  179. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
  180. * WBEM_E_FAILED if there is an error delivering the instance
  181. * WBEM_E_INVALID_PARAMETER if any of the instance properties
  182. * are incorrect.
  183. * WBEM_S_NO_ERROR if instance is properly delivered
  184. *
  185. * COMMENTS : TO DO: If you don't intend to support writing to your provider, remove this method.
  186. *
  187. *****************************************************************************/
  188. HRESULT CDHCP_Reservation::PutInstance ( const CInstance &Instance, long lFlags)
  189. {
  190. int i;
  191. DWORD returnCode;
  192. CHString strName, str ;
  193. DHCP_IP_ADDRESS dwSubnet, dwAddress;
  194. LPDHCP_IP_RESERVATION_V4 pReservationInfo;
  195. // at this point, the key information should be provided by the pInstance
  196. if (!Instance.GetCHString(DHCP_Lease_Property[IDX_Ls_Subnet].m_wsPropName, str) ||
  197. !inet_wstodw(str, dwSubnet) ||
  198. !Instance.GetCHString(DHCP_Lease_Property[IDX_Ls_Address].m_wsPropName, str) ||
  199. !inet_wstodw(str, dwAddress))
  200. return (WBEM_E_FAILED);
  201. // the object below is used as a "repository" for all the properties' values.
  202. // once it is filled up with data, it is commited explicitely to the DHCP Server.
  203. CDHCP_Reservation_Parameters resParams(dwSubnet,dwAddress);
  204. // if GetReservationInfo succeeds, then we have to remove the old reservation and create a
  205. // new one with the info from Instance.
  206. // if GetReservationInfo fails, Instance is a new reservation already
  207. if (resParams.GetReservationInfo(pReservationInfo,TRUE) &&
  208. !resParams.DeleteReservation())
  209. return WBEM_E_FAILED;
  210. for (i = 0; i < NUM_RESERVATION_PROPERTIES; i++)
  211. {
  212. if (DHCP_Reservation_Property[i].m_pfnActionSet != NULL)
  213. {
  214. // execute the SET property action function
  215. // because of the last NULL, no data is written to DHCP Server at this moment,
  216. // only SubnetParameters object is filled up with the values taken from the Instance.
  217. // don't care much here about the error codes. Failure means some properties will
  218. // not be written. At least we are giving a chance to all the writable properties.
  219. if (!(*(DHCP_Reservation_Property[i].m_pfnActionSet))(&resParams, (CInstance *)&Instance, NULL))
  220. return WBEM_E_FAILED;
  221. }
  222. }
  223. // get from the instance the info which is missing for creating a reservation
  224. CDHCP_Lease_Parameters leaseParams(dwSubnet, dwAddress);
  225. CDHCP_Lease::LoadLeaseParams(&leaseParams, (CInstance *)&Instance);
  226. // transfer the key lease info from the leaseParams to reservationParameters
  227. resParams.GetKeyInfoFromLease(&leaseParams);
  228. return (resParams.CommitNew(returnCode) &&
  229. returnCode == ERROR_SUCCESS &&
  230. leaseParams.CommitSet(returnCode) &&
  231. returnCode == ERROR_SUCCESS) ? WBEM_S_NO_ERROR : WBEM_E_FAILED;
  232. }
  233. /*****************************************************************************
  234. *
  235. * FUNCTION : CDHCP_Reservation::DeleteInstance
  236. *
  237. * DESCRIPTION : DeleteInstance, like PutInstance, actually writes information
  238. * to the software or hardware. For most hardware devices,
  239. * DeleteInstance should not be implemented, but for software
  240. * configuration, DeleteInstance implementation is plausible.
  241. * Like PutInstance, DeleteInstance returns WBEM_E_PROVIDER_NOT_CAPABLE from
  242. * inside Provider::DeleteInstance (defined in Provider.h). So, if
  243. * you choose not to implement DeleteInstance, remove this function
  244. * definition and the declaration from DHCP_Server_Scalars.h
  245. *
  246. * INPUTS :
  247. *
  248. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available.
  249. * WBEM_E_FAILED if there is an error deleting the instance.
  250. * WBEM_E_INVALID_PARAMETER if any of the instance properties
  251. * are incorrect.
  252. * WBEM_S_NO_ERROR if instance is properly deleted.
  253. *
  254. * COMMENTS : TO DO: If you don't intend to support deleting instances, remove this method.
  255. *
  256. *****************************************************************************/
  257. HRESULT CDHCP_Reservation::DeleteInstance ( const CInstance &Instance, long lFlags )
  258. {
  259. DWORD returnCode;
  260. CHString str;
  261. DHCP_IP_ADDRESS dwSubnet;
  262. DHCP_IP_ADDRESS dwAddress;
  263. // at this point, the key information should be provided by the pInstance
  264. if (!Instance.GetCHString(DHCP_Lease_Property[IDX_Ls_Subnet].m_wsPropName, str) ||
  265. !inet_wstodw(str, dwSubnet) ||
  266. !Instance.GetCHString(DHCP_Lease_Property[IDX_Ls_Address].m_wsPropName, str) ||
  267. !inet_wstodw(str, dwAddress))
  268. return (WBEM_E_FAILED);
  269. CDHCP_Reservation_Parameters ReservationParameters(dwSubnet,dwAddress);
  270. return ReservationParameters.DeleteReservation() ? WBEM_S_NO_ERROR : WBEM_E_FAILED;
  271. }
  272. /*****************************************************************************
  273. *
  274. * FUNCTION : CDHCP_Reservation::ExecQuery
  275. *
  276. * DESCRIPTION : You are passed a method context to use in the creation of
  277. * instances that satisfy the query, and a CFrameworkQuery
  278. * which describes the query. Create and populate all
  279. * instances which satisfy the query. CIMOM will post -
  280. * filter the query for you, you may return more instances
  281. * or more properties than are requested and CIMOM
  282. * will filter out any that do not apply.
  283. *
  284. *
  285. * INPUTS :
  286. *
  287. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not supported for this class
  288. * WBEM_E_FAILED if the query failed
  289. * WBEM_S_NO_ERROR if query was successful
  290. *
  291. * COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, cimom
  292. * will call your enumerate function to get all the instances and perform the
  293. * filtering for you. Unless you expect SIGNIFICANT savings from implementing
  294. * queries, you should remove this entire method.
  295. *
  296. *****************************************************************************/
  297. HRESULT CDHCP_Reservation::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
  298. {
  299. return (WBEM_E_PROVIDER_NOT_CAPABLE);
  300. }
  301. /*****************************************************************************
  302. *
  303. * FUNCTION : CDHCP_Reservation::ExecMethod
  304. *
  305. * DESCRIPTION : Override this function to provide support for methods.
  306. * A method is an entry point for the user of your provider
  307. * to request your class perform some function above and
  308. * beyond a change of state. (A change of state should be
  309. * handled by PutInstance() )
  310. *
  311. * INPUTS : A pointer to a CInstance containing the instance the method was executed against.
  312. * A string containing the method name
  313. * A pointer to the CInstance which contains the IN parameters.
  314. * A pointer to the CInstance to contain the OUT parameters.
  315. * A set of specialized method flags
  316. *
  317. * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not implemented for this class
  318. * WBEM_S_NO_ERROR if method executes successfully
  319. * WBEM_E_FAILED if error occurs executing method
  320. *
  321. * COMMENTS : TO DO: If you don't intend to support Methods, remove this method.
  322. *
  323. *****************************************************************************/
  324. HRESULT CDHCP_Reservation::ExecMethod ( const CInstance& Instance,
  325. const BSTR bstrMethodName,
  326. CInstance *pInParams,
  327. CInstance *pOutParams,
  328. long lFlags)
  329. {
  330. return WBEM_E_PROVIDER_NOT_CAPABLE;
  331. }
  332. /*****************************************************************************
  333. *
  334. * FUNCTION : CDHCP_Reservation::LoadInstanceProperties
  335. *
  336. * RETURNS : TRUE if the values for all the properties was loaded successfully,
  337. * FALSE otherwise.
  338. *
  339. * COMMENTS : It loops through the Reservation_Property table, calling the GET functions.
  340. * The pInstance parameter must have at this point all the key information
  341. * (Subnet and Address in this case)
  342. *
  343. *****************************************************************************/
  344. BOOL CDHCP_Reservation::LoadInstanceProperties(CInstance* pInstance)
  345. {
  346. CHString str;
  347. DHCP_IP_ADDRESS dwSubnet, dwAddress;
  348. // load first the lease properties
  349. if (!CDHCP_Lease::LoadInstanceProperties(pInstance, dwSubnet, dwAddress))
  350. return FALSE;
  351. CDHCP_Reservation_Parameters reservationParams(dwSubnet, dwAddress);
  352. // load now the properties of the reservation
  353. for (int i = 0; i < NUM_RESERVATION_PROPERTIES; i++)
  354. {
  355. // if there is an invisible property (does not support GET) just skip it.
  356. if (DHCP_Reservation_Property[i].m_pfnActionGet == NULL)
  357. continue;
  358. // call the appropriate GET function, fail if the call fails (there should be no reason for failure)
  359. if (!(*(DHCP_Reservation_Property[i].m_pfnActionGet))(&reservationParams, NULL, pInstance))
  360. return FALSE;
  361. }
  362. return TRUE;
  363. }