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.

566 lines
17 KiB

  1. /******************************************************************
  2. SNetFn.cpp -- Properties action functions (GET/SET)
  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_Server
  8. REVISION:
  9. 08/03/98 - created
  10. ******************************************************************/
  11. #include <stdafx.h>
  12. #include "SNetScal.h" // needed for DHCP_Subnet_Property[] (for retrieving the property's name, for SET's)
  13. #include "SNetFn.h" // own header
  14. /*****************************************************************
  15. * The definition of the class CDHCP_Subnet_Parameters
  16. *****************************************************************/
  17. // by default, all the data structures are NULL (and dw variables are 0'ed)
  18. // those values indicates that no data is cached from the server.
  19. CDHCP_Subnet_Parameters::CDHCP_Subnet_Parameters(DHCP_IP_ADDRESS dwSubnetAddress)
  20. {
  21. m_dwSubnetAddress = dwSubnetAddress;
  22. m_pMibInfo = NULL;
  23. m_pScopeMibInfo = NULL;
  24. m_pSubnetInfo = NULL;
  25. }
  26. CDHCP_Subnet_Parameters::CDHCP_Subnet_Parameters(DHCP_IP_ADDRESS dwSubnetAddress, DHCP_IP_ADDRESS dwSubnetMask)
  27. {
  28. m_dwSubnetAddress = dwSubnetAddress;
  29. m_pMibInfo = NULL;
  30. m_pScopeMibInfo = NULL;
  31. m_pSubnetInfo = NULL;
  32. CheckExistsInfoPtr();
  33. if (m_pSubnetInfo != NULL)
  34. m_pSubnetInfo->SubnetMask = dwSubnetMask;
  35. }
  36. // the DHCP API calls are allocating memory for which the caller is responsible
  37. // to release. We are releasing this memory upon the destruction of this object's instance.
  38. CDHCP_Subnet_Parameters::~CDHCP_Subnet_Parameters()
  39. {
  40. if (m_pMibInfo != NULL)
  41. {
  42. if (m_pMibInfo->ScopeInfo != NULL)
  43. DhcpRpcFreeMemory(m_pMibInfo->ScopeInfo);
  44. DhcpRpcFreeMemory(m_pMibInfo);
  45. }
  46. // LPDHCP_CONFIG_INFO_V4 contains pointers to memory allocated by the DHCP server and
  47. // which should be released by the caller.
  48. if (m_pSubnetInfo!= NULL)
  49. {
  50. if (m_pSubnetInfo->SubnetName != NULL)
  51. DhcpRpcFreeMemory(m_pSubnetInfo->SubnetName);
  52. if (m_pSubnetInfo->SubnetComment != NULL)
  53. DhcpRpcFreeMemory(m_pSubnetInfo->SubnetComment);
  54. DhcpRpcFreeMemory(m_pSubnetInfo);
  55. }
  56. }
  57. // DESCRIPTION:
  58. // Checks the m_pConfigInfoV4 pointer to insure it points to a valid buffer.
  59. // It allocates the DHCP_SUBNET_INFO if needed.
  60. BOOL CDHCP_Subnet_Parameters::CheckExistsInfoPtr()
  61. {
  62. if (m_pSubnetInfo != NULL)
  63. return TRUE;
  64. m_pSubnetInfo = (LPDHCP_SUBNET_INFO)MIDL_user_allocate(sizeof(DHCP_SUBNET_INFO));
  65. if (m_pSubnetInfo != NULL)
  66. {
  67. m_pSubnetInfo->SubnetAddress = m_dwSubnetAddress;
  68. return TRUE;
  69. }
  70. return FALSE;
  71. }
  72. // DESCRIPTION:
  73. // Provides the data structure filled in through the DhcpGetMibInfo API
  74. // If this data is cached and the caller is not forcing the refresh,
  75. // returns the internal cache.
  76. BOOL CDHCP_Subnet_Parameters::GetMibInfo(LPDHCP_MIB_INFO& pMibInfo, LPSCOPE_MIB_INFO& pScopeMibInfo, BOOL fRefresh)
  77. {
  78. if (m_pMibInfo == NULL)
  79. fRefresh = TRUE;
  80. if (fRefresh)
  81. {
  82. pMibInfo = NULL;
  83. if (DhcpGetMibInfo(SERVER_IP_ADDRESS, &pMibInfo) != ERROR_SUCCESS)
  84. return FALSE;
  85. if (m_pMibInfo != NULL)
  86. DhcpRpcFreeMemory(m_pMibInfo);
  87. m_pMibInfo = pMibInfo;
  88. pScopeMibInfo = NULL;
  89. for (int i=0; i<pMibInfo->Scopes; i++)
  90. {
  91. LPSCOPE_MIB_INFO pLocal = &pMibInfo->ScopeInfo[i];
  92. if (pLocal != NULL && pLocal->Subnet == m_dwSubnetAddress)
  93. {
  94. pScopeMibInfo = pLocal;
  95. break;
  96. }
  97. }
  98. m_pScopeMibInfo = pScopeMibInfo;
  99. }
  100. else
  101. {
  102. pMibInfo = m_pMibInfo;
  103. pScopeMibInfo = m_pScopeMibInfo;
  104. }
  105. return TRUE;
  106. }
  107. // DESCRIPTION:
  108. // Provides the data structure filled in through the DhcpSubnetInfo API
  109. // If this data is cached and the caller is not forcing the refresh,
  110. // return the internal cache. Otherwise, the internal cache is refreshed as well.
  111. BOOL CDHCP_Subnet_Parameters::GetSubnetInfo(LPDHCP_SUBNET_INFO& pSubnetInfo, BOOL fRefresh)
  112. {
  113. if (m_pSubnetInfo == NULL)
  114. fRefresh = TRUE;
  115. if (fRefresh)
  116. {
  117. pSubnetInfo = NULL;
  118. if (DhcpGetSubnetInfo(SERVER_IP_ADDRESS, m_dwSubnetAddress, &pSubnetInfo) != ERROR_SUCCESS)
  119. return FALSE;
  120. if (m_pSubnetInfo != NULL)
  121. DhcpRpcFreeMemory(m_pSubnetInfo);
  122. m_pSubnetInfo = pSubnetInfo;
  123. }
  124. else
  125. pSubnetInfo = m_pSubnetInfo;
  126. return TRUE;
  127. }
  128. // DESCRIPTION:
  129. // Creates a new subnet.
  130. // Assumes that all the fields from the DHCP_SUBNET_INFO structure are valid, and filled with
  131. // the data to be set. Calls the underlying API and returns TRUE (on success) or FALSE (on failure)
  132. BOOL CDHCP_Subnet_Parameters::CommitNew(DWORD &returnCode)
  133. {
  134. if (m_pSubnetInfo == NULL)
  135. return FALSE;
  136. returnCode = DhcpCreateSubnet(
  137. SERVER_IP_ADDRESS,
  138. m_pSubnetInfo->SubnetAddress,
  139. m_pSubnetInfo );
  140. return returnCode == ERROR_SUCCESS;
  141. }
  142. // DESCRIPTION:
  143. // Modifies info on an existing subnet.
  144. // Assumes that all the fields from the DHCP_SUBNET_INFO structure are valid, and filled with
  145. // the data to be set. Calls the underlying API and returns TRUE (on success) or FALSE (on failure)
  146. BOOL CDHCP_Subnet_Parameters::CommitSet(DWORD &returnCode)
  147. {
  148. if (m_pSubnetInfo == NULL)
  149. return FALSE;
  150. returnCode = DhcpSetSubnetInfo(
  151. SERVER_IP_ADDRESS,
  152. m_pSubnetInfo->SubnetAddress,
  153. m_pSubnetInfo );
  154. return returnCode == ERROR_SUCCESS;
  155. }
  156. // DESCRIPTION:
  157. // Assumes the m_dwSubnet is initialized, case in which it calls the DHCPAPI to delete that subnet
  158. // from the server.
  159. BOOL CDHCP_Subnet_Parameters::DeleteSubnet()
  160. {
  161. if (DhcpDeleteSubnet(SERVER_IP_ADDRESS, m_dwSubnetAddress, DhcpFullForce) == ERROR_SUCCESS)
  162. {
  163. m_dwSubnetAddress = 0;
  164. // don't look below :o)
  165. // It's only an exotic way of calling the destructor without destroying the object itself
  166. this->~CDHCP_Subnet_Parameters();
  167. m_pSubnetInfo = NULL;
  168. m_pScopeMibInfo = NULL;
  169. m_pMibInfo = NULL;
  170. return TRUE;
  171. }
  172. return FALSE;
  173. }
  174. /*------------------------Property Action Functions below-----------------------*/
  175. // unlike for SrvScal, we expect the pParams to be not-null, or otherwise this call fails.
  176. // we do this because pParams is the one holding the subnet address which must be known
  177. // in order to call the DHCP api (it has to be filled in by the caller).
  178. // This applies to all 'GET' functions.
  179. MFN_PROPERTY_ACTION_DEFN(fnSNetGetAddress, pParams, pIn, pOut)
  180. {
  181. BOOL fRefresh;
  182. CDHCP_Subnet_Parameters *pSubnetParams;
  183. LPDHCP_SUBNET_INFO pSubnetInfo;
  184. if (pParams == NULL || pOut == NULL)
  185. return FALSE;
  186. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  187. fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
  188. if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
  189. pSubnetInfo != NULL)
  190. {
  191. // nothing special to do here, the property (Address) should be just there!
  192. return TRUE;
  193. }
  194. // the API call failed
  195. return FALSE;
  196. }
  197. MFN_PROPERTY_ACTION_DEFN(fnSNetGetMask, pParams, pIn, pOut)
  198. {
  199. BOOL fRefresh;
  200. CDHCP_Subnet_Parameters *pSubnetParams;
  201. LPDHCP_SUBNET_INFO pSubnetInfo;
  202. if (pParams == NULL || pOut == NULL)
  203. return FALSE;
  204. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  205. fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
  206. if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
  207. pSubnetInfo != NULL)
  208. {
  209. WCHAR szMask[16]; // should be enough for holding 'xxx.yyy.zzz.uuu\0'
  210. swprintf(szMask, L"%u.%u.%u.%u",(pSubnetInfo->SubnetMask & 0xff000000) >> 24,
  211. (pSubnetInfo->SubnetMask & 0x00ff0000) >> 16,
  212. (pSubnetInfo->SubnetMask & 0x0000ff00) >> 8,
  213. (pSubnetInfo->SubnetMask & 0x000000ff));
  214. pOut->SetCHString(DHCP_Subnet_Property[IDX_SNET_Mask].m_wsPropName, szMask);
  215. return TRUE;
  216. }
  217. // the API call failed
  218. return FALSE;
  219. }
  220. MFN_PROPERTY_ACTION_DEFN(fnSNetGetName, pParams, pIn, pOut)
  221. {
  222. BOOL fRefresh;
  223. CDHCP_Subnet_Parameters *pSubnetParams;
  224. LPDHCP_SUBNET_INFO pSubnetInfo;
  225. if (pParams == NULL || pOut == NULL)
  226. return FALSE;
  227. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  228. fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
  229. if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
  230. pSubnetInfo != NULL)
  231. {
  232. pOut->SetCHString(DHCP_Subnet_Property[IDX_SNET_Name].m_wsPropName, pSubnetInfo->SubnetName);
  233. return TRUE;
  234. }
  235. // the API call failed
  236. return FALSE;
  237. }
  238. // Set functions require the SubnetAddress which can be taken only from pParams.
  239. // The changes are applied instantly only if pOut is not NULL (so the caller wants and
  240. // gets a return code)
  241. MFN_PROPERTY_ACTION_DEFN(fnSNetSetName, pParams, pIn, pOut)
  242. {
  243. CDHCP_Subnet_Parameters *pSubnetParams;
  244. CHString wsName;
  245. // pParams and pIn have to be valid to provide the SubnetAddress and the Name to set
  246. if (pParams == NULL || pIn == NULL)
  247. return FALSE;
  248. // get the CDHCP_Subnet_Parameters out of pParams
  249. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  250. // make sure there is a buffer for holding all this info.
  251. pSubnetParams->CheckExistsInfoPtr();
  252. // get the value to set from the pIn parameter
  253. if (!pIn->GetCHString(DHCP_Subnet_Property[IDX_SNET_Name].m_wsPropName, wsName))
  254. return FALSE;
  255. // release any old buffer
  256. if (pSubnetParams->m_pSubnetInfo->SubnetName != NULL)
  257. DhcpRpcFreeMemory(pSubnetParams->m_pSubnetInfo->SubnetName);
  258. // allocate a new buffer able to hold this new name
  259. pSubnetParams->m_pSubnetInfo->SubnetName = (WCHAR*)MIDL_user_allocate(sizeof(WCHAR)*wsName.GetLength()+sizeof(WCHAR));
  260. // make sure the allocation succeeded
  261. if (pSubnetParams->m_pSubnetInfo->SubnetName == NULL)
  262. return FALSE;
  263. // copy the name to the new buffer
  264. #ifdef _UNICODE
  265. wcscpy(pSubnetParams->m_pSubnetInfo->SubnetName, wsName);
  266. #else
  267. swprintf(pSubnetParams->m_pSubnetInfo->SubnetName, L"%S", wsName);
  268. #endif
  269. // if this is a request for 'instant apply', do it now
  270. if (pOut != NULL)
  271. {
  272. DWORD errCode;
  273. pSubnetParams->CommitSet(errCode);
  274. // fill back the code returned by the underlying level
  275. if (pOut != NULL)
  276. pOut->SetDWORD(RETURN_CODE_PROPERTY_NAME, errCode);
  277. }
  278. // the API call succeeded
  279. return TRUE;
  280. }
  281. MFN_PROPERTY_ACTION_DEFN(fnSNetGetComment, pParams, pIn, pOut)
  282. {
  283. BOOL fRefresh;
  284. CDHCP_Subnet_Parameters *pSubnetParams;
  285. LPDHCP_SUBNET_INFO pSubnetInfo;
  286. if (pParams == NULL || pOut == NULL)
  287. return FALSE;
  288. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  289. fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
  290. if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
  291. pSubnetInfo != NULL)
  292. {
  293. pOut->SetCHString(DHCP_Subnet_Property[IDX_SNET_Comment].m_wsPropName, pSubnetInfo->SubnetComment);
  294. return TRUE;
  295. }
  296. // the API call failed
  297. return FALSE;
  298. }
  299. // Set functions require the SubnetAddress which can be taken only from pParams.
  300. // The changes are applied instantly only if pOut is not NULL (so the caller wants and
  301. // gets a return code)
  302. MFN_PROPERTY_ACTION_DEFN(fnSNetSetComment, pParams, pIn, pOut)
  303. {
  304. CDHCP_Subnet_Parameters *pSubnetParams;
  305. CHString wsComment;
  306. // pIn has to be not-null to provide the comment
  307. if (pParams == NULL || pIn == NULL)
  308. return FALSE;
  309. // get the pSubnetParams out of pParams
  310. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  311. // make sure there is a buffer for holding all this info.
  312. pSubnetParams->CheckExistsInfoPtr();
  313. // get the value to set from the pIn parameter
  314. if (!pIn->GetCHString(DHCP_Subnet_Property[IDX_SNET_Comment].m_wsPropName, wsComment))
  315. return FALSE;
  316. // release any old buffer
  317. if (pSubnetParams->m_pSubnetInfo->SubnetComment != NULL)
  318. DhcpRpcFreeMemory(pSubnetParams->m_pSubnetInfo->SubnetComment);
  319. // allocate a new buffer able to hold the new comment
  320. pSubnetParams->m_pSubnetInfo->SubnetComment = (WCHAR*)MIDL_user_allocate(sizeof(WCHAR)*wsComment.GetLength()+sizeof(WCHAR));
  321. if (pSubnetParams->m_pSubnetInfo->SubnetComment == NULL)
  322. return FALSE;
  323. // copy the comment to the new buffer
  324. #ifdef _UNICODE
  325. wcscpy(pSubnetParams->m_pSubnetInfo->SubnetComment, wsComment);
  326. #else
  327. swprintf(pSubnetParams->m_pSubnetInfo->SubnetComment, L"%S", wsComment);
  328. #endif
  329. // if this is a request for 'instant apply', do it now
  330. if (pOut != NULL)
  331. {
  332. DWORD errCode;
  333. pSubnetParams->CommitSet(errCode);
  334. // fill back the code returned by the underlying level
  335. if (pOut != NULL)
  336. pOut->SetDWORD(RETURN_CODE_PROPERTY_NAME, errCode);
  337. }
  338. // the API call succeeded
  339. return TRUE;
  340. }
  341. MFN_PROPERTY_ACTION_DEFN(fnSNetGetState, pParams, pIn, pOut)
  342. {
  343. BOOL fRefresh;
  344. CDHCP_Subnet_Parameters *pSubnetParams;
  345. LPDHCP_SUBNET_INFO pSubnetInfo;
  346. if (pParams == NULL || pOut == NULL)
  347. return FALSE;
  348. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  349. fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
  350. if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
  351. pSubnetInfo != NULL)
  352. {
  353. pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_State].m_wsPropName, pSubnetInfo->SubnetState);
  354. return TRUE;
  355. }
  356. // the API call failed
  357. return FALSE;
  358. }
  359. // Set functions require the SubnetAddress which can be taken only from pParams.
  360. // The changes are applied instantly only if pOut is not NULL (so the caller wants and
  361. // gets a return code)
  362. MFN_PROPERTY_ACTION_DEFN(fnSNetSetState, pParams, pIn, pOut)
  363. {
  364. CDHCP_Subnet_Parameters *pSubnetParams;
  365. DWORD dwState;
  366. // pIn has to be not-null to provide the new State
  367. if (pParams == NULL || pIn == NULL)
  368. return FALSE;
  369. // get pSubnetParams out of pParams
  370. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  371. // make sure there is a buffer for holding all this info.
  372. pSubnetParams->CheckExistsInfoPtr();
  373. // get the value to set from the pIn parameter
  374. if (!pIn->GetDWORD(DHCP_Subnet_Property[IDX_SNET_State].m_wsPropName, dwState))
  375. return FALSE;
  376. // test roughly if the new value matches the range of admissible values
  377. switch((DHCP_SUBNET_STATE)dwState)
  378. {
  379. case DhcpSubnetEnabled:
  380. pSubnetParams->m_pSubnetInfo->SubnetState = DhcpSubnetEnabled;
  381. break;
  382. case DhcpSubnetDisabled:
  383. pSubnetParams->m_pSubnetInfo->SubnetState = DhcpSubnetDisabled;
  384. break;
  385. default:
  386. return FALSE;
  387. }
  388. // if the request is for an 'instant apply', do it now
  389. if (pOut != NULL)
  390. {
  391. DWORD errCode;
  392. pSubnetParams->CommitSet(errCode);
  393. // fill back the code returned by the underlying level
  394. if (pOut != NULL)
  395. pOut->SetDWORD(RETURN_CODE_PROPERTY_NAME, errCode);
  396. }
  397. // the API call succeeded
  398. return TRUE;
  399. }
  400. MFN_PROPERTY_ACTION_DEFN(fnSNetGetNumberOfAddressesInUse, pParams, pIn, pOut)
  401. {
  402. BOOL fRefresh;
  403. CDHCP_Subnet_Parameters *pSubnetParams;
  404. LPDHCP_MIB_INFO pMibInfo;
  405. LPSCOPE_MIB_INFO pScopeMibInfo;
  406. if (pParams == NULL || pOut == NULL)
  407. return FALSE;
  408. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  409. fRefresh = pSubnetParams->m_pMibInfo == NULL;
  410. if (pSubnetParams->GetMibInfo(pMibInfo, pScopeMibInfo, fRefresh) &&
  411. pScopeMibInfo != NULL)
  412. {
  413. pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_NbAddrInUse].m_wsPropName, pScopeMibInfo->NumAddressesInuse);
  414. return TRUE;
  415. }
  416. // the API call failed
  417. return FALSE;
  418. }
  419. MFN_PROPERTY_ACTION_DEFN(fnSNetGetNumberOfAddressesFree, pParams, pIn, pOut)
  420. {
  421. BOOL fRefresh;
  422. CDHCP_Subnet_Parameters *pSubnetParams;
  423. LPDHCP_MIB_INFO pMibInfo;
  424. LPSCOPE_MIB_INFO pScopeMibInfo;
  425. if (pParams == NULL || pOut == NULL)
  426. return FALSE;
  427. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  428. fRefresh = pSubnetParams->m_pMibInfo == NULL;
  429. if (pSubnetParams->GetMibInfo(pMibInfo, pScopeMibInfo, fRefresh) &&
  430. pScopeMibInfo != NULL)
  431. {
  432. pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_NbAddrFree].m_wsPropName, pScopeMibInfo->NumAddressesFree);
  433. return TRUE;
  434. }
  435. // the API call failed
  436. return FALSE;
  437. }
  438. MFN_PROPERTY_ACTION_DEFN(fnSNetGetNumberOfPendingOffers, pParams, pIn, pOut)
  439. {
  440. BOOL fRefresh;
  441. CDHCP_Subnet_Parameters *pSubnetParams;
  442. LPDHCP_MIB_INFO pMibInfo;
  443. LPSCOPE_MIB_INFO pScopeMibInfo;
  444. if (pParams == NULL || pOut == NULL)
  445. return FALSE;
  446. pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
  447. fRefresh = pSubnetParams->m_pMibInfo == NULL;
  448. if (pSubnetParams->GetMibInfo(pMibInfo, pScopeMibInfo, fRefresh) &&
  449. pScopeMibInfo != NULL)
  450. {
  451. pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_NbPendingOffers].m_wsPropName, pScopeMibInfo->NumPendingOffers);
  452. return TRUE;
  453. }
  454. // the API call failed
  455. return FALSE;
  456. }