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.

1338 lines
32 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. ifioctl.c
  5. Abstract:
  6. Network interface control functions.
  7. Author:
  8. John Vert (jvert) 2-Mar-1997
  9. Revision History:
  10. --*/
  11. #include "nmp.h"
  12. //
  13. // Read-Write Common Properties.
  14. //
  15. RESUTIL_PROPERTY_ITEM
  16. NmpInterfaceCommonProperties[] =
  17. {
  18. {
  19. CLUSREG_NAME_NETIFACE_DESC, NULL, CLUSPROP_FORMAT_SZ,
  20. (DWORD_PTR) NmpNullString, 0, 0,
  21. 0,
  22. FIELD_OFFSET(NM_NETWORK_INFO, Description)
  23. },
  24. { 0 }
  25. };
  26. //
  27. // Read-Only Common Properties.
  28. //
  29. RESUTIL_PROPERTY_ITEM
  30. NmpInterfaceROCommonProperties[] =
  31. {
  32. { CLUSREG_NAME_NETIFACE_NAME, NULL, CLUSPROP_FORMAT_SZ,
  33. 0, 0, 0,
  34. RESUTIL_PROPITEM_READ_ONLY,
  35. FIELD_OFFSET(NM_INTERFACE_INFO2, Name)
  36. },
  37. {
  38. CLUSREG_NAME_NETIFACE_NODE, NULL, CLUSPROP_FORMAT_SZ,
  39. 0, 0, 0,
  40. RESUTIL_PROPITEM_READ_ONLY,
  41. FIELD_OFFSET(NM_INTERFACE_INFO2, NodeId)
  42. },
  43. {
  44. CLUSREG_NAME_NETIFACE_NETWORK, NULL, CLUSPROP_FORMAT_SZ,
  45. 0, 0, 0,
  46. RESUTIL_PROPITEM_READ_ONLY,
  47. FIELD_OFFSET(NM_INTERFACE_INFO2, NetworkId)
  48. },
  49. {
  50. CLUSREG_NAME_NETIFACE_ADAPTER_NAME, NULL, CLUSPROP_FORMAT_SZ,
  51. 0, 0, 0,
  52. RESUTIL_PROPITEM_READ_ONLY,
  53. FIELD_OFFSET(NM_INTERFACE_INFO2, AdapterName)
  54. },
  55. {
  56. CLUSREG_NAME_NETIFACE_ADAPTER_ID, NULL, CLUSPROP_FORMAT_SZ,
  57. 0, 0, 0,
  58. RESUTIL_PROPITEM_READ_ONLY,
  59. FIELD_OFFSET(NM_INTERFACE_INFO2, AdapterId)
  60. },
  61. {
  62. CLUSREG_NAME_NETIFACE_ADDRESS, NULL, CLUSPROP_FORMAT_SZ,
  63. 0, 0, 0,
  64. RESUTIL_PROPITEM_READ_ONLY,
  65. FIELD_OFFSET(NM_INTERFACE_INFO2, Address)
  66. },
  67. { 0 }
  68. };
  69. //
  70. // Cluster registry API function pointers.
  71. // defined in ioctl.c
  72. //
  73. extern CLUSTER_REG_APIS NmpClusterRegApis;
  74. //
  75. // Local Functions
  76. //
  77. DWORD
  78. NmpInterfaceControl(
  79. IN PNM_INTERFACE Interface,
  80. IN DWORD ControlCode,
  81. IN PUCHAR InBuffer,
  82. IN DWORD InBufferSize,
  83. OUT PUCHAR OutBuffer,
  84. IN DWORD OutBufferSize,
  85. OUT LPDWORD BytesReturned,
  86. OUT LPDWORD Required
  87. );
  88. DWORD
  89. NmpInterfaceEnumCommonProperties(
  90. OUT PVOID OutBuffer,
  91. IN DWORD OutBufferSize,
  92. OUT LPDWORD BytesReturned,
  93. OUT LPDWORD Required
  94. );
  95. DWORD
  96. NmpInterfaceGetCommonProperties(
  97. IN PNM_INTERFACE Interface,
  98. IN BOOL ReadOnly,
  99. IN HDMKEY RegistryKey,
  100. OUT PVOID OutBuffer,
  101. IN DWORD OutBufferSize,
  102. OUT LPDWORD BytesReturned,
  103. OUT LPDWORD Required
  104. );
  105. DWORD
  106. NmpInterfaceValidateCommonProperties(
  107. IN PNM_INTERFACE Interface,
  108. IN PVOID InBuffer,
  109. IN DWORD InBufferSize,
  110. OUT PNM_INTERFACE_INFO2 InterfaceInfo OPTIONAL
  111. );
  112. DWORD
  113. NmpInterfaceSetCommonProperties(
  114. IN PNM_INTERFACE Interface,
  115. IN HDMKEY RegistryKey,
  116. IN PVOID InBuffer,
  117. IN DWORD InBufferSize
  118. );
  119. DWORD
  120. NmpInterfaceEnumPrivateProperties(
  121. IN PNM_INTERFACE Interface,
  122. IN HDMKEY RegistryKey,
  123. OUT PVOID OutBuffer,
  124. IN DWORD OutBufferSize,
  125. OUT LPDWORD BytesReturned,
  126. OUT LPDWORD Required
  127. );
  128. DWORD
  129. NmpInterfaceGetPrivateProperties(
  130. IN PNM_INTERFACE Interface,
  131. IN HDMKEY RegistryKey,
  132. OUT PVOID OutBuffer,
  133. IN DWORD OutBufferSize,
  134. OUT LPDWORD BytesReturned,
  135. OUT LPDWORD Required
  136. );
  137. DWORD
  138. NmpInterfaceValidatePrivateProperties(
  139. IN PNM_INTERFACE Interface,
  140. IN HDMKEY RegistryKey,
  141. IN PVOID InBuffer,
  142. IN DWORD InBufferSize
  143. );
  144. DWORD
  145. NmpInterfaceSetPrivateProperties(
  146. IN PNM_INTERFACE Interface,
  147. IN HDMKEY RegistryKey,
  148. IN PVOID InBuffer,
  149. IN DWORD InBufferSize
  150. );
  151. DWORD
  152. NmpInterfaceGetFlags(
  153. IN PNM_INTERFACE Interface,
  154. IN HDMKEY RegistryKey,
  155. OUT PVOID OutBuffer,
  156. IN DWORD OutBufferSize,
  157. OUT LPDWORD BytesReturned,
  158. OUT LPDWORD Required
  159. );
  160. DWORD
  161. WINAPI
  162. NmInterfaceControl(
  163. IN PNM_INTERFACE Interface,
  164. IN PNM_NODE HostNode OPTIONAL,
  165. IN DWORD ControlCode,
  166. IN PUCHAR InBuffer,
  167. IN DWORD InBufferSize,
  168. OUT PUCHAR OutBuffer,
  169. IN DWORD OutBufferSize,
  170. OUT LPDWORD BytesReturned,
  171. OUT LPDWORD Required
  172. )
  173. /*++
  174. Routine Description:
  175. Provides for arbitrary communication and control between an application
  176. and a specific instance of a network interface.
  177. Arguments:
  178. Interface - Supplies the network interface to be controlled.
  179. HostNode - Supplies the host node on which the resource control should
  180. be delivered. If this is NULL, the local node is used. Not honored!
  181. ControlCode- Supplies the control code that defines the
  182. structure and action of the resource control.
  183. Values of ControlCode between 0 and 0x10000000 are reserved
  184. for future definition and use by Microsoft. All other values
  185. are available for use by ISVs
  186. InBuffer- Supplies a pointer to the input buffer to be passed
  187. to the resource.
  188. InBufferSize- Supplies the size, in bytes, of the data pointed
  189. to by lpInBuffer..
  190. OutBuffer- Supplies a pointer to the output buffer to be
  191. filled in by the resource..
  192. OutBufferSize- Supplies the size, in bytes, of the available
  193. space pointed to by lpOutBuffer.
  194. BytesReturned - Returns the number of bytes of lpOutBuffer
  195. actually filled in by the resource..
  196. Required - Returns the number of bytes if the OutBuffer is not big
  197. enough.
  198. Return Value:
  199. ERROR_SUCCESS if successful
  200. Win32 error code otherwise
  201. --*/
  202. {
  203. DWORD status;
  204. //
  205. // Cluster service ioctls were designed to have access modes, e.g.
  206. // read-only, read-write, etc. These access modes are not implemented.
  207. // If eventually they are implemented, an access mode check should be
  208. // placed here.
  209. //
  210. if ( CLUSCTL_GET_CONTROL_OBJECT( ControlCode ) != CLUS_OBJECT_NETINTERFACE ) {
  211. return(ERROR_INVALID_FUNCTION);
  212. }
  213. if (NmpEnterApi(NmStateOnline)) {
  214. status = NmpInterfaceControl(
  215. Interface,
  216. ControlCode,
  217. InBuffer,
  218. InBufferSize,
  219. OutBuffer,
  220. OutBufferSize,
  221. BytesReturned,
  222. Required
  223. );
  224. NmpLeaveApi();
  225. }
  226. else {
  227. status = ERROR_NODE_NOT_AVAILABLE;
  228. ClRtlLogPrint(LOG_NOISE,
  229. "[NM] Not in valid state to process InterfaceControl request.\n"
  230. );
  231. }
  232. return(status);
  233. } // NmInterfaceControl
  234. DWORD
  235. NmpInterfaceControl(
  236. IN PNM_INTERFACE Interface,
  237. IN DWORD ControlCode,
  238. IN PUCHAR InBuffer,
  239. IN DWORD InBufferSize,
  240. OUT PUCHAR OutBuffer,
  241. IN DWORD OutBufferSize,
  242. OUT LPDWORD BytesReturned,
  243. OUT LPDWORD Required
  244. )
  245. /*++
  246. Routine Description:
  247. Provides for arbitrary communication and control between an application
  248. and a specific instance of a network interface.
  249. Arguments:
  250. Interface - Supplies the network interface to be controlled.
  251. ControlCode- Supplies the control code that defines the
  252. structure and action of the network interface control.
  253. Values of ControlCode between 0 and 0x10000000 are reserved
  254. for future definition and use by Microsoft. All other values
  255. are available for use by ISVs
  256. InBuffer- Supplies a pointer to the input buffer to be passed
  257. to the network interface.
  258. InBufferSize- Supplies the size, in bytes, of the data pointed
  259. to by lpInBuffer.
  260. OutBuffer- Supplies a pointer to the output buffer to be
  261. filled in by the network interface.
  262. OutBufferSize- Supplies the size, in bytes, of the available
  263. space pointed to by lpOutBuffer.
  264. BytesReturned - Returns the number of bytes of lpOutBuffer
  265. actually filled in by the network interface.
  266. Required - Returns the number of bytes if the OutBuffer is not big
  267. enough.
  268. Return Value:
  269. ERROR_SUCCESS if successful
  270. Win32 error code otherwise
  271. --*/
  272. {
  273. DWORD status;
  274. HDMKEY InterfaceKey;
  275. CLUSPROP_BUFFER_HELPER props;
  276. DWORD bufSize;
  277. InterfaceKey = DmOpenKey(
  278. DmNetInterfacesKey,
  279. OmObjectId( Interface ),
  280. MAXIMUM_ALLOWED
  281. );
  282. if ( InterfaceKey == NULL ) {
  283. return(GetLastError());
  284. }
  285. switch ( ControlCode ) {
  286. case CLUSCTL_NETINTERFACE_UNKNOWN:
  287. *BytesReturned = 0;
  288. status = ERROR_SUCCESS;
  289. break;
  290. case CLUSCTL_NETINTERFACE_GET_NAME:
  291. NmpAcquireLock();
  292. if ( OmObjectName( Interface ) != NULL ) {
  293. props.pb = OutBuffer;
  294. bufSize = (lstrlenW( OmObjectName( Interface ) ) + 1) * sizeof(WCHAR);
  295. if ( bufSize > OutBufferSize ) {
  296. *Required = bufSize;
  297. *BytesReturned = 0;
  298. status = ERROR_MORE_DATA;
  299. } else {
  300. lstrcpyW( props.psz, OmObjectName( Interface ) );
  301. *BytesReturned = bufSize;
  302. *Required = 0;
  303. status = ERROR_SUCCESS;
  304. }
  305. } else {
  306. status = ERROR_NOT_READY;
  307. }
  308. NmpReleaseLock();
  309. break;
  310. case CLUSCTL_NETINTERFACE_GET_ID:
  311. NmpAcquireLock();
  312. if ( OmObjectId( Interface ) != NULL ) {
  313. props.pb = OutBuffer;
  314. bufSize = (lstrlenW( OmObjectId( Interface ) ) + 1) * sizeof(WCHAR);
  315. if ( bufSize > OutBufferSize ) {
  316. *Required = bufSize;
  317. *BytesReturned = 0;
  318. status = ERROR_MORE_DATA;
  319. } else {
  320. lstrcpyW( props.psz, OmObjectId( Interface ) );
  321. *BytesReturned = bufSize;
  322. *Required = 0;
  323. status = ERROR_SUCCESS;
  324. }
  325. } else {
  326. status = ERROR_NOT_READY;
  327. }
  328. NmpReleaseLock();
  329. break;
  330. case CLUSCTL_NETINTERFACE_GET_NODE:
  331. NmpAcquireLock();
  332. if ( (Interface->Node != NULL) && (OmObjectName( Interface->Node ) != NULL) ) {
  333. props.pb = OutBuffer;
  334. bufSize = (lstrlenW( OmObjectName( Interface->Node ) ) + 1) * sizeof(WCHAR);
  335. if ( bufSize > OutBufferSize ) {
  336. *Required = bufSize;
  337. *BytesReturned = 0;
  338. status = ERROR_MORE_DATA;
  339. } else {
  340. lstrcpyW( props.psz, OmObjectName( Interface->Node ) );
  341. *BytesReturned = bufSize;
  342. *Required = 0;
  343. status = ERROR_SUCCESS;
  344. }
  345. } else {
  346. status = ERROR_NOT_READY;
  347. }
  348. NmpReleaseLock();
  349. break;
  350. case CLUSCTL_NETINTERFACE_GET_NETWORK:
  351. NmpAcquireLock();
  352. if ( (Interface->Network != NULL) && (OmObjectName( Interface->Network ) != NULL) ) {
  353. props.pb = OutBuffer;
  354. bufSize = (lstrlenW( OmObjectName( Interface->Network ) ) + 1) * sizeof(WCHAR);
  355. if ( bufSize > OutBufferSize ) {
  356. *Required = bufSize;
  357. *BytesReturned = 0;
  358. status = ERROR_MORE_DATA;
  359. } else {
  360. lstrcpyW( props.psz, OmObjectName( Interface->Network ) );
  361. *BytesReturned = bufSize;
  362. *Required = 0;
  363. status = ERROR_SUCCESS;
  364. }
  365. } else {
  366. status = ERROR_NOT_READY;
  367. }
  368. NmpReleaseLock();
  369. break;
  370. case CLUSCTL_NETINTERFACE_ENUM_COMMON_PROPERTIES:
  371. status = NmpInterfaceEnumCommonProperties(
  372. OutBuffer,
  373. OutBufferSize,
  374. BytesReturned,
  375. Required
  376. );
  377. break;
  378. case CLUSCTL_NETINTERFACE_GET_RO_COMMON_PROPERTIES:
  379. status = NmpInterfaceGetCommonProperties(
  380. Interface,
  381. TRUE, // ReadOnly
  382. InterfaceKey,
  383. OutBuffer,
  384. OutBufferSize,
  385. BytesReturned,
  386. Required
  387. );
  388. break;
  389. case CLUSCTL_NETINTERFACE_GET_COMMON_PROPERTIES:
  390. status = NmpInterfaceGetCommonProperties(
  391. Interface,
  392. FALSE, // ReadOnly
  393. InterfaceKey,
  394. OutBuffer,
  395. OutBufferSize,
  396. BytesReturned,
  397. Required
  398. );
  399. break;
  400. case CLUSCTL_NETINTERFACE_VALIDATE_COMMON_PROPERTIES:
  401. status = NmpInterfaceValidateCommonProperties(
  402. Interface,
  403. InBuffer,
  404. InBufferSize,
  405. NULL
  406. );
  407. break;
  408. case CLUSCTL_NETINTERFACE_SET_COMMON_PROPERTIES:
  409. status = NmpInterfaceSetCommonProperties(
  410. Interface,
  411. InterfaceKey,
  412. InBuffer,
  413. InBufferSize
  414. );
  415. break;
  416. case CLUSCTL_NETINTERFACE_GET_RO_PRIVATE_PROPERTIES:
  417. if ( OutBufferSize < sizeof(DWORD) ) {
  418. *BytesReturned = 0;
  419. *Required = sizeof(DWORD);
  420. if ( OutBuffer == NULL ) {
  421. status = ERROR_SUCCESS;
  422. } else {
  423. status = ERROR_MORE_DATA;
  424. }
  425. } else {
  426. LPDWORD ptrDword = (LPDWORD) OutBuffer;
  427. *ptrDword = 0;
  428. *BytesReturned = sizeof(DWORD);
  429. status = ERROR_SUCCESS;
  430. }
  431. break;
  432. case CLUSCTL_NETINTERFACE_GET_PRIVATE_PROPERTIES:
  433. status = NmpInterfaceGetPrivateProperties(
  434. Interface,
  435. InterfaceKey,
  436. OutBuffer,
  437. OutBufferSize,
  438. BytesReturned,
  439. Required
  440. );
  441. break;
  442. case CLUSCTL_NETINTERFACE_VALIDATE_PRIVATE_PROPERTIES:
  443. status = NmpInterfaceValidatePrivateProperties(
  444. Interface,
  445. InterfaceKey,
  446. InBuffer,
  447. InBufferSize
  448. );
  449. break;
  450. case CLUSCTL_NETINTERFACE_SET_PRIVATE_PROPERTIES:
  451. status = NmpInterfaceSetPrivateProperties(
  452. Interface,
  453. InterfaceKey,
  454. InBuffer,
  455. InBufferSize
  456. );
  457. break;
  458. case CLUSCTL_NETINTERFACE_GET_CHARACTERISTICS:
  459. if ( OutBufferSize < sizeof(DWORD) ) {
  460. *BytesReturned = 0;
  461. *Required = sizeof(DWORD);
  462. if ( OutBuffer == NULL ) {
  463. status = ERROR_SUCCESS;
  464. } else {
  465. status = ERROR_MORE_DATA;
  466. }
  467. } else {
  468. *BytesReturned = sizeof(DWORD);
  469. *(LPDWORD)OutBuffer = 0;
  470. status = ERROR_SUCCESS;
  471. }
  472. break;
  473. case CLUSCTL_NETINTERFACE_GET_FLAGS:
  474. status = NmpInterfaceGetFlags(
  475. Interface,
  476. InterfaceKey,
  477. OutBuffer,
  478. OutBufferSize,
  479. BytesReturned,
  480. Required
  481. );
  482. break;
  483. case CLUSCTL_NETINTERFACE_ENUM_PRIVATE_PROPERTIES:
  484. status = NmpInterfaceEnumPrivateProperties(
  485. Interface,
  486. InterfaceKey,
  487. OutBuffer,
  488. OutBufferSize,
  489. BytesReturned,
  490. Required
  491. );
  492. break;
  493. default:
  494. status = ERROR_INVALID_FUNCTION;
  495. break;
  496. }
  497. DmCloseKey( InterfaceKey );
  498. return(status);
  499. } // NmpInterfaceControl
  500. DWORD
  501. NmpInterfaceEnumCommonProperties(
  502. OUT PVOID OutBuffer,
  503. IN DWORD OutBufferSize,
  504. OUT LPDWORD BytesReturned,
  505. OUT LPDWORD Required
  506. )
  507. /*++
  508. Routine Description:
  509. Enumerates the common property names for a given network interface.
  510. Arguments:
  511. OutBuffer - Supplies the output buffer.
  512. OutBufferSize - Supplies the size of the output buffer.
  513. BytesReturned - The number of bytes returned in OutBuffer.
  514. Required - The required number of bytes if OutBuffer is too small.
  515. Return Value:
  516. ERROR_SUCCESS if successful.
  517. A Win32 error code on failure.
  518. --*/
  519. {
  520. DWORD status;
  521. //
  522. // Get the common properties.
  523. //
  524. status = ClRtlEnumProperties( NmpInterfaceCommonProperties,
  525. OutBuffer,
  526. OutBufferSize,
  527. BytesReturned,
  528. Required );
  529. return(status);
  530. } // NmpInterfaceEnumCommonProperties
  531. DWORD
  532. NmpInterfaceGetCommonProperties(
  533. IN PNM_INTERFACE Interface,
  534. IN BOOL ReadOnly,
  535. IN HDMKEY RegistryKey,
  536. OUT PVOID OutBuffer,
  537. IN DWORD OutBufferSize,
  538. OUT LPDWORD BytesReturned,
  539. OUT LPDWORD Required
  540. )
  541. /*++
  542. Routine Description:
  543. Gets the common properties for a given network interface.
  544. Arguments:
  545. Interface - Supplies the network interface.
  546. ReadOnly - TRUE if the read-only properties should be read. FALSE otherwise.
  547. RegistryKey - Supplies the registry key for this network interface.
  548. OutBuffer - Supplies the output buffer.
  549. OutBufferSize - Supplies the size of the output buffer.
  550. BytesReturned - The number of bytes returned in OutBuffer.
  551. Required - The required number of bytes if OutBuffer is too small.
  552. Return Value:
  553. ERROR_SUCCESS if successful.
  554. A Win32 error code on failure.
  555. --*/
  556. {
  557. DWORD status;
  558. NM_INTERFACE_INFO2 interfaceInfo;
  559. PRESUTIL_PROPERTY_ITEM propertyTable;
  560. DWORD outBufferSize = OutBufferSize;
  561. //
  562. // Fetch the properties from the object
  563. //
  564. ZeroMemory(&interfaceInfo, sizeof(interfaceInfo));
  565. NmpAcquireLock();
  566. status = NmpGetInterfaceObjectInfo(Interface, &interfaceInfo);
  567. if (status != ERROR_SUCCESS) {
  568. NmpReleaseLock();
  569. return(status);
  570. }
  571. if ( ReadOnly ) {
  572. LPCWSTR name;
  573. DWORD nameLength;
  574. propertyTable = NmpInterfaceROCommonProperties;
  575. //
  576. // Replace the network ID with a name
  577. //
  578. name = OmObjectName(Interface->Network);
  579. nameLength = NM_WCSLEN(name);
  580. MIDL_user_free(interfaceInfo.NetworkId);
  581. interfaceInfo.NetworkId = MIDL_user_allocate(nameLength);
  582. if (interfaceInfo.NetworkId != NULL) {
  583. wcscpy(interfaceInfo.NetworkId, name);
  584. //
  585. // Replace the node ID with a name
  586. //
  587. name = OmObjectName(Interface->Node);
  588. nameLength = NM_WCSLEN(name);
  589. MIDL_user_free(interfaceInfo.NodeId);
  590. interfaceInfo.NodeId = MIDL_user_allocate(nameLength);
  591. if (interfaceInfo.NodeId != NULL) {
  592. wcscpy(interfaceInfo.NodeId, name);
  593. }
  594. else {
  595. status = ERROR_NOT_ENOUGH_MEMORY;
  596. }
  597. }
  598. else {
  599. status = ERROR_NOT_ENOUGH_MEMORY;
  600. }
  601. }
  602. else {
  603. //
  604. // Construct a property list from the parameter block
  605. // for the read-write properties.
  606. //
  607. propertyTable = NmpInterfaceCommonProperties;
  608. }
  609. NmpReleaseLock();
  610. if (status == ERROR_SUCCESS) {
  611. status = ClRtlPropertyListFromParameterBlock(
  612. propertyTable,
  613. OutBuffer,
  614. &outBufferSize,
  615. (LPBYTE) &interfaceInfo,
  616. BytesReturned,
  617. Required
  618. );
  619. }
  620. ClNetFreeInterfaceInfo(&interfaceInfo);
  621. return(status);
  622. } // NmpInterfaceGetCommonProperties
  623. DWORD
  624. NmpInterfaceValidateCommonProperties(
  625. IN PNM_INTERFACE Interface,
  626. IN PVOID InBuffer,
  627. IN DWORD InBufferSize,
  628. OUT PNM_INTERFACE_INFO2 InterfaceInfo OPTIONAL
  629. )
  630. /*++
  631. Routine Description:
  632. Validates the common properties for a given network interface.
  633. Arguments:
  634. Interface - Supplies the Interface object.
  635. InBuffer - Supplies the input buffer.
  636. InBufferSize - Supplies the size of the input buffer.
  637. InterfaceInfo - An optional pointer to an interface information structure
  638. to be filled in with the updated property set.
  639. Return Value:
  640. ERROR_SUCCESS if successful.
  641. A Win32 error code on failure.
  642. --*/
  643. {
  644. DWORD status;
  645. NM_INTERFACE_INFO2 infoBuffer;
  646. PNM_INTERFACE_INFO2 interfaceInfo;
  647. LPCWSTR interfaceId = OmObjectId(Interface);
  648. //
  649. // Check if there is input data.
  650. //
  651. if ( (InBuffer == NULL) ||
  652. (InBufferSize < sizeof(DWORD)) ) {
  653. return(ERROR_INVALID_DATA);
  654. }
  655. if (InterfaceInfo != NULL) {
  656. interfaceInfo = InterfaceInfo;
  657. }
  658. else {
  659. interfaceInfo = &infoBuffer;
  660. }
  661. ZeroMemory(interfaceInfo, sizeof(NM_INTERFACE_INFO2));
  662. //
  663. // Get a copy of the current interface parameters.
  664. //
  665. NmpAcquireLock();
  666. status = NmpGetInterfaceObjectInfo(Interface, interfaceInfo);
  667. if ( status != ERROR_SUCCESS ) {
  668. goto error_exit;
  669. }
  670. //
  671. // Validate the property list and update the parameter block.
  672. //
  673. status = ClRtlVerifyPropertyTable(
  674. NmpInterfaceCommonProperties,
  675. NULL, // Reserved
  676. FALSE, // Don't allow unknowns
  677. InBuffer,
  678. InBufferSize,
  679. (LPBYTE) interfaceInfo
  680. );
  681. if ( status != ERROR_SUCCESS ) {
  682. ClRtlLogPrint( LOG_CRITICAL,
  683. "[NM] ValidateCommonProperties, error in verify routine.\n"
  684. );
  685. goto error_exit;
  686. }
  687. //
  688. // The change is valid.
  689. //
  690. CL_ASSERT(status == ERROR_SUCCESS);
  691. error_exit:
  692. NmpReleaseLock();
  693. if ((status != ERROR_SUCCESS) || (interfaceInfo == &infoBuffer)) {
  694. ClNetFreeInterfaceInfo(interfaceInfo);
  695. }
  696. return(status);
  697. } // NmpInterfaceValidateCommonProperties
  698. DWORD
  699. NmpInterfaceSetCommonProperties(
  700. IN PNM_INTERFACE Interface,
  701. IN HDMKEY RegistryKey,
  702. IN PVOID InBuffer,
  703. IN DWORD InBufferSize
  704. )
  705. /*++
  706. Routine Description:
  707. Sets the common properties for a given Interface.
  708. Arguments:
  709. Interface - Supplies the Interface object.
  710. InBuffer - Supplies the input buffer.
  711. InBufferSize - Supplies the size of the input buffer.
  712. Return Value:
  713. ERROR_SUCCESS if successful.
  714. A Win32 error code on failure.
  715. --*/
  716. {
  717. DWORD status;
  718. LPCWSTR interfaceId = OmObjectId(Interface);
  719. ClRtlLogPrint(LOG_NOISE,
  720. "[NM] Setting common properties for interface %1!ws!.\n",
  721. interfaceId
  722. );
  723. //
  724. // Issue a global update
  725. //
  726. status = GumSendUpdateEx(
  727. GumUpdateMembership,
  728. NmUpdateSetInterfaceCommonProperties,
  729. 3,
  730. NM_WCSLEN(interfaceId),
  731. interfaceId,
  732. InBufferSize,
  733. InBuffer,
  734. sizeof(InBufferSize),
  735. &InBufferSize
  736. );
  737. if (status != ERROR_SUCCESS) {
  738. ClRtlLogPrint(LOG_CRITICAL,
  739. "[NM] Global update to set common properties for interface %1!ws! failed, status %2!u!.\n",
  740. interfaceId,
  741. status
  742. );
  743. }
  744. return(status);
  745. } // NmpInterfaceSetCommonProperties
  746. DWORD
  747. NmpInterfaceEnumPrivateProperties(
  748. IN PNM_INTERFACE Interface,
  749. IN HDMKEY RegistryKey,
  750. OUT PVOID OutBuffer,
  751. IN DWORD OutBufferSize,
  752. OUT LPDWORD BytesReturned,
  753. OUT LPDWORD Required
  754. )
  755. /*++
  756. Routine Description:
  757. Enumerates the private property names for a given network interface.
  758. Arguments:
  759. Interface - Supplies the Interface object.
  760. RegistryKey - Registry key for the Interface.
  761. OutBuffer - Supplies the output buffer.
  762. OutBufferSize - Supplies the size of the output buffer.
  763. BytesReturned - The number of bytes returned in OutBuffer.
  764. Required - The required number of bytes if OutBuffer is too small.
  765. Return Value:
  766. ERROR_SUCCESS if successful.
  767. A Win32 error code on failure.
  768. --*/
  769. {
  770. DWORD status;
  771. HDMKEY parametersKey;
  772. DWORD totalBufferSize = 0;
  773. *BytesReturned = 0;
  774. *Required = 0;
  775. //
  776. // Clear the output buffer
  777. //
  778. ZeroMemory( OutBuffer, OutBufferSize );
  779. //
  780. // Open the cluster Interface parameters key.
  781. //
  782. parametersKey = DmOpenKey( RegistryKey,
  783. CLUSREG_KEYNAME_PARAMETERS,
  784. MAXIMUM_ALLOWED );
  785. if ( parametersKey == NULL ) {
  786. status = GetLastError();
  787. if ( status == ERROR_FILE_NOT_FOUND ) {
  788. status = ERROR_SUCCESS;
  789. }
  790. return(status);
  791. }
  792. //
  793. // Get private properties for the interface.
  794. //
  795. status = ClRtlEnumPrivateProperties( parametersKey,
  796. &NmpClusterRegApis,
  797. OutBuffer,
  798. OutBufferSize,
  799. BytesReturned,
  800. Required );
  801. DmCloseKey( parametersKey );
  802. return(status);
  803. } // NmpInterfaceEnumPrivateProperties
  804. DWORD
  805. NmpInterfaceGetPrivateProperties(
  806. IN PNM_INTERFACE Interface,
  807. IN HDMKEY RegistryKey,
  808. OUT PVOID OutBuffer,
  809. IN DWORD OutBufferSize,
  810. OUT LPDWORD BytesReturned,
  811. OUT LPDWORD Required
  812. )
  813. /*++
  814. Routine Description:
  815. Gets the private properties for a given network interface.
  816. Arguments:
  817. Interface - Supplies the Interface object.
  818. OutBuffer - Supplies the output buffer.
  819. OutBufferSize - Supplies the size of the output buffer.
  820. BytesReturned - The number of bytes returned in OutBuffer.
  821. Required - The required number of bytes if OutBuffer is too small.
  822. Return Value:
  823. ERROR_SUCCESS if successful.
  824. A Win32 error code on failure.
  825. --*/
  826. {
  827. DWORD status;
  828. HDMKEY parametersKey;
  829. DWORD totalBufferSize = 0;
  830. *BytesReturned = 0;
  831. *Required = 0;
  832. //
  833. // Clear the output buffer
  834. //
  835. ZeroMemory( OutBuffer, OutBufferSize );
  836. //
  837. // Open the cluster Interface parameters key.
  838. //
  839. parametersKey = DmOpenKey( RegistryKey,
  840. CLUSREG_KEYNAME_PARAMETERS,
  841. MAXIMUM_ALLOWED );
  842. if ( parametersKey == NULL ) {
  843. status = GetLastError();
  844. if ( status == ERROR_FILE_NOT_FOUND ) {
  845. //
  846. // If we don't have a parameters key, then return an
  847. // item count of 0 and an endmark.
  848. //
  849. totalBufferSize = sizeof(DWORD) + sizeof(CLUSPROP_SYNTAX);
  850. if ( OutBufferSize < totalBufferSize ) {
  851. *Required = totalBufferSize;
  852. status = ERROR_MORE_DATA;
  853. } else {
  854. // This is somewhat redundant since we zero the
  855. // buffer above, but it's here for clarity.
  856. CLUSPROP_BUFFER_HELPER buf;
  857. buf.pb = OutBuffer;
  858. buf.pList->nPropertyCount = 0;
  859. buf.pdw++;
  860. buf.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  861. *BytesReturned = totalBufferSize;
  862. status = ERROR_SUCCESS;
  863. }
  864. }
  865. return(status);
  866. }
  867. //
  868. // Get private properties for the network interface.
  869. //
  870. status = ClRtlGetPrivateProperties( parametersKey,
  871. &NmpClusterRegApis,
  872. OutBuffer,
  873. OutBufferSize,
  874. BytesReturned,
  875. Required );
  876. DmCloseKey( parametersKey );
  877. return(status);
  878. } // NmpInterfaceGetPrivateProperties
  879. DWORD
  880. NmpInterfaceValidatePrivateProperties(
  881. IN PNM_INTERFACE Interface,
  882. IN HDMKEY RegistryKey,
  883. IN PVOID InBuffer,
  884. IN DWORD InBufferSize
  885. )
  886. /*++
  887. Routine Description:
  888. Validates the private properties for a given Interface.
  889. Arguments:
  890. Interface - Supplies the Interface object.
  891. RegistryKey - Registry key for the Interface.
  892. InBuffer - Supplies the input buffer.
  893. InBufferSize - Supplies the size of the input buffer.
  894. Return Value:
  895. ERROR_SUCCESS if successful.
  896. A Win32 error code on failure.
  897. --*/
  898. {
  899. DWORD status;
  900. //
  901. // Validate the property list.
  902. //
  903. status = ClRtlVerifyPrivatePropertyList( InBuffer,
  904. InBufferSize );
  905. return(status);
  906. } // NmpInterfaceValidatePrivateProperties
  907. DWORD
  908. NmpInterfaceSetPrivateProperties(
  909. IN PNM_INTERFACE Interface,
  910. IN HDMKEY RegistryKey,
  911. IN PVOID InBuffer,
  912. IN DWORD InBufferSize
  913. )
  914. /*++
  915. Routine Description:
  916. Sets the private properties for a given Interface.
  917. Arguments:
  918. Interface - Supplies the Interface object.
  919. RegistryKey - Registry key for the Interface.
  920. InBuffer - Supplies the input buffer.
  921. InBufferSize - Supplies the size of the input buffer.
  922. Return Value:
  923. ERROR_SUCCESS if successful.
  924. A Win32 error code on failure.
  925. --*/
  926. {
  927. DWORD status;
  928. HDMKEY parametersKey;
  929. DWORD disposition;
  930. //
  931. // Validate the property list.
  932. //
  933. status = ClRtlVerifyPrivatePropertyList( InBuffer,
  934. InBufferSize );
  935. if ( status == ERROR_SUCCESS ) {
  936. //
  937. // Open the cluster Interface\xx\parameters key
  938. //
  939. parametersKey = DmOpenKey( RegistryKey,
  940. CLUSREG_KEYNAME_PARAMETERS,
  941. MAXIMUM_ALLOWED );
  942. if ( parametersKey == NULL ) {
  943. status = GetLastError();
  944. if ( status == ERROR_FILE_NOT_FOUND ) {
  945. //
  946. // Try to create the parameters key.
  947. //
  948. parametersKey = DmCreateKey( RegistryKey,
  949. CLUSREG_KEYNAME_PARAMETERS,
  950. 0,
  951. KEY_READ | KEY_WRITE,
  952. NULL,
  953. &disposition );
  954. if ( parametersKey == NULL ) {
  955. status = GetLastError();
  956. return(status);
  957. }
  958. }
  959. }
  960. status = ClRtlSetPrivatePropertyList( NULL, // IN HANDLE hXsaction
  961. parametersKey,
  962. &NmpClusterRegApis,
  963. InBuffer,
  964. InBufferSize );
  965. DmCloseKey( parametersKey );
  966. }
  967. return(status);
  968. } // NmpInterfaceSetPrivateProperties
  969. DWORD
  970. NmpInterfaceGetFlags(
  971. IN PNM_INTERFACE Interface,
  972. IN HDMKEY RegistryKey,
  973. OUT PVOID OutBuffer,
  974. IN DWORD OutBufferSize,
  975. OUT LPDWORD BytesReturned,
  976. OUT LPDWORD Required
  977. )
  978. /*++
  979. Routine Description:
  980. Gets the flags for a given Interface.
  981. Arguments:
  982. Interface - Supplies the Interface.
  983. RegistryKey - Registry key for the Interface.
  984. OutBuffer - Supplies the output buffer.
  985. OutBufferSize - Supplies the size of the output buffer.
  986. BytesReturned - The number of bytes returned in OutBuffer.
  987. Required - The required number of bytes if OutBuffer is too small.
  988. Return Value:
  989. ERROR_SUCCESS if successful.
  990. A Win32 error code on failure.
  991. --*/
  992. {
  993. DWORD status;
  994. *BytesReturned = 0;
  995. if ( OutBufferSize < sizeof(DWORD) ) {
  996. *Required = sizeof(DWORD);
  997. if ( OutBuffer == NULL ) {
  998. status = ERROR_SUCCESS;
  999. } else {
  1000. status = ERROR_MORE_DATA;
  1001. }
  1002. } else {
  1003. DWORD valueType;
  1004. //
  1005. // Read the Flags value for the Interface.
  1006. //
  1007. *BytesReturned = OutBufferSize;
  1008. status = DmQueryValue( RegistryKey,
  1009. CLUSREG_NAME_FLAGS,
  1010. &valueType,
  1011. OutBuffer,
  1012. BytesReturned );
  1013. if ( status == ERROR_FILE_NOT_FOUND ) {
  1014. *BytesReturned = sizeof(DWORD);
  1015. *(LPDWORD)OutBuffer = 0;
  1016. status = ERROR_SUCCESS;
  1017. }
  1018. }
  1019. return(status);
  1020. } // NmpInterfaceGetFlags