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.

303 lines
11 KiB

  1. /******************************************************************
  2. LsFn.cpp -- Properties action functions (GET)
  3. MODULE:
  4. DhcpProv.dll
  5. DESCRIPTION:
  6. Contains the definition for the action functions associated to
  7. each manageable property from the class CDHCP_Reservation
  8. REVISION:
  9. 08/14/98 - created
  10. ******************************************************************/
  11. #include <stdafx.h>
  12. #include "ResScal.h" // needed for DHCP_Reservation_Property[] (for retrieving the property's name)
  13. #include "ResFn.h" // own header
  14. #include "LsFn.h" // for GetKeyInfoFromLease
  15. /*****************************************************************
  16. * The definition of the class CDHCP_Reservation_Parameters
  17. *****************************************************************/
  18. // by default, all the data structures are NULL (and dw variables are 0'ed)
  19. // those values indicates that no data is cached from the server.
  20. void CDHCP_Reservation_Parameters::DeleteReservationInfo(LPDHCP_IP_RESERVATION_V4& pReservationInfo)
  21. {
  22. if (pReservationInfo != NULL)
  23. {
  24. if (pReservationInfo->ReservedForClient != NULL)
  25. {
  26. if (pReservationInfo->ReservedForClient->Data != NULL)
  27. DhcpRpcFreeMemory(pReservationInfo->ReservedForClient->Data);
  28. DhcpRpcFreeMemory(pReservationInfo->ReservedForClient);
  29. }
  30. DhcpRpcFreeMemory(pReservationInfo);
  31. }
  32. }
  33. void CDHCP_Reservation_Parameters::DeleteReservationInfoArray(LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4& pReservationInfoArray)
  34. {
  35. if (pReservationInfoArray)
  36. {
  37. if (pReservationInfoArray->Elements)
  38. {
  39. while(pReservationInfoArray->NumElements)
  40. {
  41. DeleteReservationInfo(pReservationInfoArray->Elements[--(pReservationInfoArray->NumElements)].Element.ReservedIp);
  42. }
  43. DhcpRpcFreeMemory(pReservationInfoArray->Elements);
  44. }
  45. DhcpRpcFreeMemory(pReservationInfoArray);
  46. pReservationInfoArray = NULL;
  47. }
  48. if ( m_pReservationInfo )
  49. {
  50. if (m_pReservationInfo->Element.ReservedIp)
  51. DeleteReservationInfo(m_pReservationInfo->Element.ReservedIp);
  52. DhcpRpcFreeMemory(m_pReservationInfo);
  53. m_pReservationInfo = NULL ;
  54. }
  55. }
  56. CDHCP_Reservation_Parameters::CDHCP_Reservation_Parameters(DHCP_IP_ADDRESS dwSubnetAddress, DHCP_IP_ADDRESS dwReservationAddress)
  57. {
  58. m_dwSubnetAddress = dwSubnetAddress;
  59. m_dwReservationAddress = dwReservationAddress;
  60. m_pReservationInfoArray = NULL;
  61. m_pReservationInfo = NULL ;
  62. }
  63. // the DHCP API calls are allocating memory for which the caller is responsible
  64. // to release. We are releasing this memory upon the destruction of this object's instance.
  65. CDHCP_Reservation_Parameters::~CDHCP_Reservation_Parameters()
  66. {
  67. DeleteReservationInfoArray(m_pReservationInfoArray);
  68. }
  69. BOOL CDHCP_Reservation_Parameters::GetKeyInfoFromLease(CDHCP_Lease_Parameters *pLeaseParams)
  70. {
  71. if (pLeaseParams == NULL ||
  72. pLeaseParams->m_pClientSetInfo == NULL)
  73. return FALSE;
  74. if (!CheckExistsInfoPtr())
  75. return FALSE;
  76. m_pReservationInfo->Element.ReservedIp->ReservedIpAddress = pLeaseParams->m_pClientSetInfo->ClientIpAddress;
  77. return dupDhcpBinaryData(
  78. pLeaseParams->m_pClientSetInfo->ClientHardwareAddress,
  79. *(m_pReservationInfo->Element.ReservedIp->ReservedForClient));
  80. }
  81. // DESCRIPTION:
  82. // Fills in the internal cache with the information from the database, starting
  83. // from the given handle. If the end of the database is reached, the handle is
  84. // reset to 0. Returns TRUE on success (regardless there is more data to be read or not).
  85. LONG CDHCP_Reservation_Parameters::NextSubnetReservation(DHCP_RESUME_HANDLE ResumeHandle)
  86. {
  87. DWORD Error;
  88. DWORD ReservationsRead = 0;
  89. DWORD ReservationsTotal = 0;
  90. // each time the API gets called, the previous
  91. // m_pReservationInfoArray is useless and should be freed
  92. DeleteReservationInfoArray(m_pReservationInfoArray);
  93. // calls the API.
  94. Error = DhcpEnumSubnetElementsV4 (
  95. SERVER_IP_ADDRESS,
  96. m_dwSubnetAddress,
  97. DhcpReservedIps,
  98. &ResumeHandle,
  99. (DWORD)(-1),
  100. &m_pReservationInfoArray,
  101. &ReservationsRead,
  102. &ReservationsTotal);
  103. if (Error == ERROR_SUCCESS)
  104. ResumeHandle = 0;
  105. return (Error == ERROR_SUCCESS || Error == ERROR_MORE_DATA);
  106. }
  107. BOOL CDHCP_Reservation_Parameters::GetReservationInfoFromCache(LPDHCP_IP_RESERVATION_V4& pReservationInfo)
  108. {
  109. if (m_pReservationInfoArray != NULL)
  110. {
  111. for (int i=0; i<m_pReservationInfoArray->NumElements; i++)
  112. {
  113. // match the internal reservation id with the info from cache
  114. if (m_pReservationInfoArray->Elements[i].Element.ReservedIp->ReservedIpAddress == m_dwReservationAddress)
  115. {
  116. DHCP_CLIENT_UID *pClientUid;
  117. // reservation found, return info on client, and TRUE.
  118. pReservationInfo = m_pReservationInfoArray->Elements[i].Element.ReservedIp;
  119. pClientUid = pReservationInfo->ReservedForClient;
  120. if (pClientUid->DataLength >= sizeof(DHCP_IP_ADDRESS) &&
  121. memcmp(pClientUid->Data, &m_dwSubnetAddress, sizeof(DHCP_IP_ADDRESS)) == 0)
  122. {
  123. UINT nPrefix = sizeof(DHCP_IP_ADDRESS) + sizeof(BYTE);
  124. pClientUid->DataLength -= nPrefix;
  125. memmove(pClientUid->Data, pClientUid->Data + nPrefix, pClientUid->DataLength);
  126. }
  127. return TRUE;
  128. }
  129. }
  130. }
  131. return FALSE;
  132. }
  133. // DESCRIPTION:
  134. // Provides the data structure filled in through the DhcpGetReservationInfo API
  135. // If this data is cached and the caller is not forcing the refresh,
  136. // return the internal cache. Otherwise, the internal cache is refreshed as well.
  137. BOOL CDHCP_Reservation_Parameters::GetReservationInfo(LPDHCP_IP_RESERVATION_V4& pReservationInfo, BOOL fRefresh)
  138. {
  139. if (m_pReservationInfoArray == NULL)
  140. fRefresh = TRUE;
  141. if (!fRefresh &&
  142. GetReservationInfoFromCache(pReservationInfo))
  143. return TRUE;
  144. DHCP_RESUME_HANDLE ResumeHandle = 0;
  145. DWORD i;
  146. // either the caller wants full refresh, or the reservation was not found into the cache
  147. // do full refresh.
  148. do
  149. {
  150. if ( ( NextSubnetReservation(ResumeHandle) > 0 ) &&
  151. GetReservationInfoFromCache(pReservationInfo) )
  152. return TRUE;
  153. } while (ResumeHandle != 0);
  154. return FALSE;
  155. }
  156. // DESCRIPTION:
  157. // Checks the m_pConfigInfoV4 pointer to insure it points to a valid buffer.
  158. // It allocates the DHCP_SUBNET_INFO if needed.
  159. BOOL CDHCP_Reservation_Parameters::CheckExistsInfoPtr()
  160. {
  161. if (m_pReservationInfo != NULL)
  162. return TRUE;
  163. m_pReservationInfo = (LPDHCP_SUBNET_ELEMENT_DATA_V4)MIDL_user_allocate(sizeof(DHCP_SUBNET_ELEMENT_DATA_V4));
  164. if (m_pReservationInfo != NULL)
  165. {
  166. m_pReservationInfo->ElementType = DhcpReservedIps ;
  167. m_pReservationInfo->Element.ReservedIp = (LPDHCP_IP_RESERVATION_V4) MIDL_user_allocate(sizeof(DHCP_IP_RESERVATION_V4));
  168. if (m_pReservationInfo->Element.ReservedIp != NULL)
  169. {
  170. m_pReservationInfo->Element.ReservedIp->ReservedForClient = (DHCP_CLIENT_UID*)MIDL_user_allocate(sizeof(DHCP_CLIENT_UID));
  171. return TRUE;
  172. }
  173. }
  174. return FALSE;
  175. }
  176. // DESCRIPTION:
  177. // Creates a new subnet.
  178. // Assumes that all the fields from the DHCP_SUBNET_INFO structure are valid, and filled with
  179. // the data to be set. Calls the underlying API and returns TRUE (on success) or FALSE (on failure)
  180. BOOL CDHCP_Reservation_Parameters::CommitNew(DWORD &returnCode)
  181. {
  182. if (m_pReservationInfo == NULL ||
  183. m_pReservationInfo->Element.ReservedIp == NULL)
  184. return FALSE;
  185. // fill in the reservation address
  186. m_pReservationInfo->Element.ReservedIp->ReservedIpAddress = m_dwReservationAddress;
  187. // we only add here the reservation info. In order to have the reservation active, a lease record has to be created into
  188. // the database as well.
  189. returnCode = DhcpAddSubnetElementV4(
  190. SERVER_IP_ADDRESS,
  191. m_dwSubnetAddress,
  192. m_pReservationInfo);
  193. return returnCode == ERROR_SUCCESS;
  194. }
  195. // DESCRIPTION:
  196. // Assumes the m_dwSubnetAddress,m_dwReservationAddress is initialized, case in
  197. // which it calls the DHCPAPI to delete that reservation from the server.
  198. BOOL CDHCP_Reservation_Parameters::DeleteReservation()
  199. {
  200. LPDHCP_IP_RESERVATION_V4 pReservationInfo;
  201. if (GetReservationInfo(pReservationInfo, FALSE) &&
  202. pReservationInfo != NULL)
  203. {
  204. DHCP_SUBNET_ELEMENT_DATA_V4 subnetElement;
  205. subnetElement.ElementType = DhcpReservedIps;
  206. subnetElement.Element.ReservedIp = pReservationInfo;
  207. // this removes both the reservation registration and the record from the databse
  208. if (DhcpRemoveSubnetElementV4(SERVER_IP_ADDRESS, m_dwSubnetAddress, &subnetElement, DhcpFullForce) == ERROR_SUCCESS)
  209. {
  210. // don't look below :o)
  211. // It's only an exotic way of calling the destructor without destroying the object itself
  212. this->~CDHCP_Reservation_Parameters();
  213. return TRUE;
  214. }
  215. return FALSE;
  216. }
  217. return FALSE ;
  218. }
  219. // GET function for the (RO)"Type" property
  220. MFN_PROPERTY_ACTION_DEFN(fnResGetReservationType, pParams, pIn, pOut)
  221. {
  222. CDHCP_Reservation_Parameters *pReservationParams;
  223. LPDHCP_IP_RESERVATION_V4 pReservationInfo;
  224. if (pParams == NULL || pOut == NULL)
  225. return FALSE;
  226. pReservationParams = (CDHCP_Reservation_Parameters *)pParams;
  227. if (pReservationParams->GetReservationInfo(pReservationInfo, FALSE) &&
  228. pReservationInfo != NULL)
  229. {
  230. // get the value to set from the pIn parameter
  231. return pOut->SetByte(DHCP_Reservation_Property[IDX_Res_ReservationType].m_wsPropName, pReservationInfo->bAllowedClientTypes) ;
  232. }
  233. // the API call failed
  234. return FALSE;
  235. }
  236. // SET function for the (CREATE)"Type" property
  237. MFN_PROPERTY_ACTION_DEFN(fnResSetReservationType, pParams, pIn, pOut)
  238. {
  239. CDHCP_Reservation_Parameters *pReservationParams;
  240. BYTE dwClientType;
  241. // pParams and pIn have to be valid to provide the SubnetAddress and the Name to set
  242. if (pParams == NULL || pIn == NULL)
  243. return FALSE;
  244. // get the CDHCP_Subnet_Parameters out of pParams
  245. pReservationParams = (CDHCP_Reservation_Parameters *)pParams;
  246. // make sure there is a buffer for holding all this info.
  247. pReservationParams->CheckExistsInfoPtr();
  248. // get the value to set from the pIn parameter
  249. if (!pIn->GetByte(DHCP_Reservation_Property[IDX_Res_ReservationType].m_wsPropName, dwClientType))
  250. return FALSE;
  251. pReservationParams->m_pReservationInfo->Element.ReservedIp->bAllowedClientTypes = dwClientType ;
  252. return TRUE ;
  253. }