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.

1091 lines
26 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: UPkt.c
  6. //
  7. // Contents: This module contains user mode functions which support
  8. // operations on the DFS Partition Knowledge Table.
  9. //
  10. // Functions: PktOpen -
  11. // PktClose -
  12. // PktCreateEntry -
  13. // PktCreateSubordinateEntry -
  14. // PktFlushCache -
  15. // PktDestroyEntry -
  16. // PktModifyEntryGuid -
  17. // PktSetRelationInfo -
  18. //
  19. // History:
  20. //
  21. // [mikese] I replaced MemAlloc's by malloc's, but consider using
  22. // RtlAllocateHeap.
  23. // Also, most of the routines in the module have a remarkably similar
  24. // structure, and could probably be recoded using a common subroutine.
  25. //
  26. //-----------------------------------------------------------------------------
  27. #include <ntifs.h>
  28. #include <ntext.h>
  29. #include "dfsmrshl.h"
  30. #include "nodetype.h"
  31. #include "libsup.h"
  32. #include "upkt.h"
  33. #include "dfsfsctl.h"
  34. #include "fsctrl.h" // needed for FSCTL_DFS_PKT_FLUSH_CACHE
  35. #define MAX_OUT_BUFFER_SIZE_RELINFO 0x1000
  36. //+-------------------------------------------------------------------------
  37. //
  38. // Function: PktOpen, public
  39. //
  40. // Synopsis: Returns a handle to the Dfs PKT so operations can be made
  41. // to it.
  42. //
  43. // Arguments:
  44. //
  45. // Returns: [STATUS_SUCCESS] -- Successfully opened the pkt.
  46. //
  47. // [STATUS_FS_DRIVER_REQUIRED] -- Dfs driver not loaded
  48. //
  49. //--------------------------------------------------------------------------
  50. NTSTATUS
  51. PktOpen(
  52. IN OUT PHANDLE PktHandle,
  53. IN ACCESS_MASK DesiredAccess,
  54. IN ULONG ShareAccess,
  55. IN PUNICODE_STRING DfsNtPathName OPTIONAL
  56. )
  57. {
  58. NTSTATUS status;
  59. HANDLE dfsHandle;
  60. status = DfsOpen(&dfsHandle, DfsNtPathName);
  61. if(NT_SUCCESS(status)) {
  62. *PktHandle = dfsHandle;
  63. } else {
  64. status = STATUS_FS_DRIVER_REQUIRED;
  65. }
  66. return status;
  67. }
  68. //+-------------------------------------------------------------------------
  69. //
  70. // Function: PktClose, public
  71. //
  72. // Synopsis:
  73. //
  74. // Arguments:
  75. //
  76. // Returns: Nothing
  77. //
  78. //--------------------------------------------------------------------------
  79. VOID
  80. PktClose(
  81. IN HANDLE PktHandle
  82. )
  83. {
  84. NTSTATUS status = STATUS_SUCCESS;
  85. if(NT_SUCCESS(status))
  86. NtClose(PktHandle);
  87. }
  88. //+-------------------------------------------------------------------------
  89. //
  90. // Function: PktCreateEntry, public
  91. //
  92. // Synopsis:
  93. //
  94. // Arguments:
  95. //
  96. // Returns:
  97. //
  98. //--------------------------------------------------------------------------
  99. NTSTATUS
  100. PktCreateEntry(
  101. IN HANDLE PktHandle,
  102. IN ULONG EntryType,
  103. IN PDFS_PKT_ENTRY_ID EntryId,
  104. IN PDFS_PKT_ENTRY_INFO EntryInfo,
  105. IN ULONG CreateDisposition
  106. )
  107. {
  108. NTSTATUS status;
  109. DFS_PKT_CREATE_ENTRY_ARG arg;
  110. MARSHAL_BUFFER marshalBuffer;
  111. ULONG size;
  112. arg.EntryType = EntryType;
  113. arg.EntryId = (*EntryId);
  114. arg.EntryInfo = (*EntryInfo);
  115. arg.CreateDisposition = CreateDisposition;
  116. size = 0L;
  117. status = DfsRtlSize(&MiPktCreateEntryArg, &arg, &size);
  118. if(NT_SUCCESS(status))
  119. {
  120. PVOID buffer = malloc ( size );
  121. if ( buffer == NULL )
  122. return(STATUS_NO_MEMORY);
  123. MarshalBufferInitialize(&marshalBuffer, size, buffer);
  124. status = DfsRtlPut(
  125. &marshalBuffer,
  126. &MiPktCreateEntryArg,
  127. &arg
  128. );
  129. if(NT_SUCCESS(status))
  130. {
  131. status = DfsFsctl(
  132. PktHandle,
  133. FSCTL_DFS_PKT_CREATE_ENTRY,
  134. buffer,
  135. size,
  136. NULL,
  137. 0L
  138. );
  139. }
  140. free(buffer);
  141. }
  142. return status;
  143. }
  144. //+-------------------------------------------------------------------------
  145. //
  146. // Function: PktCreateSubordinateEntry, public
  147. //
  148. // Synopsis:
  149. //
  150. // Arguments:
  151. //
  152. // Returns:
  153. //
  154. //--------------------------------------------------------------------------
  155. NTSTATUS
  156. PktCreateSubordinateEntry(
  157. IN HANDLE PktHandle,
  158. IN PDFS_PKT_ENTRY_ID SuperiorId,
  159. IN ULONG SubordinateType,
  160. IN PDFS_PKT_ENTRY_ID SubordinateId,
  161. IN PDFS_PKT_ENTRY_INFO SubordinateInfo OPTIONAL,
  162. IN ULONG CreateDisposition
  163. )
  164. {
  165. NTSTATUS status;
  166. DFS_PKT_CREATE_SUBORDINATE_ENTRY_ARG arg;
  167. MARSHAL_BUFFER marshalBuffer;
  168. ULONG size;
  169. arg.EntryId = (*SuperiorId);
  170. arg.SubEntryType = SubordinateType;
  171. arg.SubEntryId = (*SubordinateId);
  172. arg.SubEntryInfo = (*SubordinateInfo);
  173. arg.CreateDisposition = CreateDisposition;
  174. size = 0L;
  175. status = DfsRtlSize(&MiPktCreateSubordinateEntryArg, &arg, &size);
  176. if(NT_SUCCESS(status)) {
  177. PVOID buffer = malloc ( size );
  178. if ( buffer == NULL )
  179. return(STATUS_NO_MEMORY);
  180. MarshalBufferInitialize(&marshalBuffer, size, buffer);
  181. status = DfsRtlPut(
  182. &marshalBuffer,
  183. &MiPktCreateSubordinateEntryArg,
  184. &arg
  185. );
  186. if(NT_SUCCESS(status)) {
  187. status = DfsFsctl(
  188. PktHandle,
  189. FSCTL_DFS_PKT_CREATE_SUBORDINATE_ENTRY,
  190. buffer,
  191. size,
  192. NULL,
  193. 0L
  194. );
  195. }
  196. free(buffer);
  197. }
  198. return status;
  199. }
  200. //+-------------------------------------------------------------------------
  201. //
  202. // Function: PktDestroyEntry, public
  203. //
  204. // Synopsis:
  205. //
  206. // Arguments:
  207. //
  208. // Returns:
  209. //
  210. //--------------------------------------------------------------------------
  211. NTSTATUS
  212. PktDestroyEntry(
  213. IN HANDLE PktHandle,
  214. IN DFS_PKT_ENTRY_ID victim
  215. )
  216. {
  217. NTSTATUS status;
  218. MARSHAL_BUFFER marshalBuffer;
  219. ULONG size;
  220. size = 0L;
  221. status = DfsRtlSize(&MiPktEntryId, &victim, &size);
  222. if(NT_SUCCESS(status))
  223. {
  224. PVOID buffer = malloc ( size );
  225. if ( buffer == NULL )
  226. return(STATUS_NO_MEMORY);
  227. MarshalBufferInitialize(&marshalBuffer, size, buffer);
  228. status = DfsRtlPut(
  229. &marshalBuffer,
  230. &MiPktEntryId,
  231. &victim
  232. );
  233. if(NT_SUCCESS(status))
  234. {
  235. status = DfsFsctl(
  236. PktHandle,
  237. FSCTL_DFS_PKT_DESTROY_ENTRY,
  238. buffer,
  239. size,
  240. NULL,
  241. 0L
  242. );
  243. }
  244. free(buffer);
  245. }
  246. return status;
  247. }
  248. //+-------------------------------------------------------------------------
  249. //
  250. // Function: PktGetRelationInfo, public
  251. //
  252. // Synopsis:
  253. //
  254. // Arguments:
  255. //
  256. // Returns:
  257. //
  258. // Notes: The relationalInfo structure should be made available
  259. // by the caller but additional memory is allocated in here.
  260. // The caller should deallocate all that memory himself.
  261. //
  262. //--------------------------------------------------------------------------
  263. NTSTATUS
  264. PktGetRelationInfo(
  265. IN HANDLE PktHandle,
  266. IN PDFS_PKT_ENTRY_ID EntryId,
  267. IN OUT PDFS_PKT_RELATION_INFO RelationInfo
  268. )
  269. {
  270. NTSTATUS status;
  271. MARSHAL_BUFFER marshalBuffer;
  272. ULONG size;
  273. PVOID OutputBuffer;
  274. size = 0L;
  275. status = DfsRtlSize(&MiPktEntryId, EntryId, &size);
  276. if(NT_SUCCESS(status))
  277. {
  278. PVOID buffer = malloc ( size );
  279. if ( buffer == NULL )
  280. return(STATUS_NO_MEMORY);
  281. MarshalBufferInitialize(&marshalBuffer, size, buffer);
  282. status = DfsRtlPut(
  283. &marshalBuffer,
  284. &MiPktEntryId,
  285. EntryId
  286. );
  287. if(NT_SUCCESS(status))
  288. {
  289. // Do we want to retry with larger sizes?
  290. OutputBuffer = malloc ( MAX_OUT_BUFFER_SIZE_RELINFO );
  291. if ( OutputBuffer == NULL )
  292. {
  293. status = STATUS_INSUFFICIENT_RESOURCES;
  294. }
  295. else
  296. {
  297. status = DfsFsctl(
  298. PktHandle,
  299. FSCTL_DFS_PKT_GET_RELATION_INFO,
  300. buffer,
  301. size,
  302. OutputBuffer,
  303. MAX_OUT_BUFFER_SIZE_RELINFO);
  304. //
  305. // We can get rid of this right away.
  306. //
  307. if(NT_SUCCESS(status)) {
  308. MarshalBufferInitialize(
  309. &marshalBuffer,
  310. MAX_OUT_BUFFER_SIZE_RELINFO,
  311. OutputBuffer
  312. );
  313. status = DfsRtlGet(
  314. &marshalBuffer,
  315. &MiPktRelationInfo,
  316. RelationInfo
  317. );
  318. }
  319. free(OutputBuffer);
  320. }
  321. }
  322. free(buffer);
  323. } //Status from DfsRtlSize
  324. if (!NT_SUCCESS(status)) {
  325. RtlZeroMemory(RelationInfo, sizeof(DFS_PKT_RELATION_INFO));
  326. }
  327. return status;
  328. }
  329. //+----------------------------------------------------------------------------
  330. //
  331. // Function: PktValidateLocalVolumeInfo, public
  332. //
  333. // Synopsis: Asks the Dfs driver to validate its local volume info with
  334. // the one that is passed in.
  335. //
  336. // Arguments: [relationInfo] -- The DFS_PKT_RELATION_INFO to validate
  337. // against.
  338. //
  339. // Returns: [STATUS_SUCCESS] -- Successfully validated local volume info
  340. //
  341. // [STATUS_REGISTRY_RECOVERED] -- Successfully validated info,
  342. // but had to make changes to local info
  343. //
  344. // [DFS_STATUS_NOSUCH_LOCAL_VOLUME] -- The driver has no record
  345. // of local volume described in relation info.
  346. //
  347. // [STATUS_UNSUCCESSFUL] -- Unable to fixup the local relation
  348. // info. An appropriate message was logged to the
  349. // local eventlog.
  350. //
  351. // [STATUS_DATA_ERROR] -- Passed in relationInfo is bogus.
  352. //
  353. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
  354. //
  355. // [STATUS_FS_DRIVER_REQUIRED] -- Unable to open handle to the
  356. // Dfs driver
  357. //
  358. //-----------------------------------------------------------------------------
  359. NTSTATUS
  360. PktValidateLocalVolumeInfo(
  361. IN PDFS_PKT_RELATION_INFO relationInfo)
  362. {
  363. NTSTATUS status;
  364. HANDLE dfsHandle;
  365. MARSHAL_BUFFER marshalBuffer;
  366. PUCHAR pBuffer;
  367. ULONG cbBuffer;
  368. status = DfsOpen(&dfsHandle, NULL);
  369. if (NT_SUCCESS(status)) {
  370. cbBuffer = 0;
  371. status = DfsRtlSize( &MiPktRelationInfo, relationInfo, &cbBuffer );
  372. if (NT_SUCCESS(status)) {
  373. pBuffer = malloc( cbBuffer );
  374. if (pBuffer != NULL) {
  375. MarshalBufferInitialize(&marshalBuffer, cbBuffer, pBuffer);
  376. status = DfsRtlPut(
  377. &marshalBuffer,
  378. &MiPktRelationInfo,
  379. relationInfo);
  380. } else {
  381. status = STATUS_INSUFFICIENT_RESOURCES;
  382. }
  383. if (NT_SUCCESS(status)) {
  384. status = DfsFsctl(
  385. dfsHandle,
  386. FSCTL_DFS_VERIFY_LOCAL_VOLUME_KNOWLEDGE,
  387. pBuffer,
  388. cbBuffer,
  389. NULL,
  390. 0);
  391. }
  392. if (pBuffer != NULL)
  393. free(pBuffer);
  394. }
  395. NtClose( dfsHandle );
  396. }
  397. return( status );
  398. }
  399. //+----------------------------------------------------------------------------
  400. //
  401. // Function: PktPruneLocalPartition
  402. //
  403. // Synopsis: Asks the Dfs Driver to get rid of a local volume that is
  404. // not supposed to be supported by this server.
  405. //
  406. // Arguments: [EntryId] -- The entry id of the volume to prune.
  407. //
  408. // Returns: [STATUS_SUCCESS] -- Successfully pruned the volume
  409. //
  410. // [DFS_STATUS_NOSUCH_LOCAL_VOLUME] -- The driver has no record
  411. // of local volume described in relation info.
  412. //
  413. // [STATUS_UNSUCCESSFUL] -- Unable to fixup the local relation
  414. // info. An appropriate message was logged to the
  415. // local eventlog.
  416. //
  417. // [STATUS_DATA_ERROR] -- Passed in relationInfo is bogus.
  418. //
  419. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
  420. //
  421. // [STATUS_FS_DRIVER_REQUIRED] -- Unable to open handle to the
  422. // Dfs driver
  423. //
  424. //-----------------------------------------------------------------------------
  425. NTSTATUS
  426. PktPruneLocalPartition(
  427. IN PDFS_PKT_ENTRY_ID EntryId)
  428. {
  429. NTSTATUS status;
  430. HANDLE dfsHandle;
  431. MARSHAL_BUFFER marshalBuffer;
  432. PUCHAR pBuffer;
  433. ULONG cbBuffer;
  434. status = DfsOpen(&dfsHandle, NULL);
  435. if (NT_SUCCESS(status)) {
  436. cbBuffer = 0;
  437. status = DfsRtlSize( &MiPktEntryId, EntryId, &cbBuffer );
  438. if (NT_SUCCESS(status)) {
  439. pBuffer = malloc( cbBuffer );
  440. if (pBuffer != NULL) {
  441. MarshalBufferInitialize(&marshalBuffer, cbBuffer, pBuffer);
  442. status = DfsRtlPut(
  443. &marshalBuffer,
  444. &MiPktEntryId,
  445. EntryId);
  446. } else {
  447. status = STATUS_INSUFFICIENT_RESOURCES;
  448. }
  449. if (NT_SUCCESS(status)) {
  450. status = DfsFsctl(
  451. dfsHandle,
  452. FSCTL_DFS_PRUNE_LOCAL_PARTITION,
  453. pBuffer,
  454. cbBuffer,
  455. NULL,
  456. 0);
  457. }
  458. if (pBuffer != NULL)
  459. free(pBuffer);
  460. }
  461. NtClose( dfsHandle );
  462. }
  463. return( status );
  464. }
  465. //+----------------------------------------------------------------------------
  466. //
  467. // Function: PktIsChildnameLegal, public
  468. //
  469. // Synopsis:
  470. //
  471. // Arguments:
  472. //
  473. // Returns:
  474. //
  475. //-----------------------------------------------------------------------------
  476. NTSTATUS
  477. PktIsChildnameLegal(
  478. IN PWCHAR pwszParent,
  479. IN PWCHAR pwszChild,
  480. IN GUID *pidChild)
  481. {
  482. HANDLE dfsHandle;
  483. NTSTATUS Status;
  484. DFS_PKT_ENTRY_ID idParent, idChild;
  485. MARSHAL_BUFFER marshalBuffer;
  486. PUCHAR pBuffer;
  487. ULONG cbBuffer;
  488. RtlZeroMemory( &idParent, sizeof(DFS_PKT_ENTRY_ID) );
  489. RtlZeroMemory( &idChild, sizeof(DFS_PKT_ENTRY_ID) );
  490. RtlInitUnicodeString( &idParent.Prefix, pwszParent );
  491. RtlInitUnicodeString( &idChild.Prefix, pwszChild );
  492. idChild.Uid = *pidChild;
  493. cbBuffer = 0;
  494. Status = DfsOpen(&dfsHandle, NULL);
  495. if (NT_SUCCESS(Status)) {
  496. Status = DfsRtlSize( &MiPktEntryId, &idParent, &cbBuffer );
  497. if (NT_SUCCESS(Status)) {
  498. Status = DfsRtlSize( &MiPktEntryId, &idChild, &cbBuffer );
  499. }
  500. if (NT_SUCCESS(Status)) {
  501. pBuffer = malloc( cbBuffer );
  502. if (pBuffer != NULL) {
  503. MarshalBufferInitialize( &marshalBuffer, cbBuffer, pBuffer );
  504. Status = DfsRtlPut(
  505. &marshalBuffer,
  506. &MiPktEntryId,
  507. &idParent );
  508. if (NT_SUCCESS(Status)) {
  509. Status = DfsRtlPut(
  510. &marshalBuffer,
  511. &MiPktEntryId,
  512. &idChild );
  513. }
  514. if (NT_SUCCESS(Status)) {
  515. Status = DfsFsctl(
  516. dfsHandle,
  517. FSCTL_DFS_IS_CHILDNAME_LEGAL,
  518. pBuffer,
  519. cbBuffer,
  520. NULL,
  521. 0L);
  522. }
  523. free( pBuffer );
  524. } else {
  525. Status = STATUS_INSUFFICIENT_RESOURCES;
  526. }
  527. }
  528. NtClose( dfsHandle );
  529. }
  530. return( Status );
  531. }
  532. //+----------------------------------------------------------------------------
  533. //
  534. // Function: PktGetEntryType, public
  535. //
  536. // Synopsis: Given a prefix, this routine retrieves the entry type of the
  537. // PktEntry
  538. //
  539. // Arguments: [pwszPrefix] -- The prefix whose PktEntry's type is required
  540. // [pType] -- The type is returned here.
  541. //
  542. // Returns:
  543. //
  544. //-----------------------------------------------------------------------------
  545. NTSTATUS
  546. PktGetEntryType(
  547. IN PWSTR pwszPrefix,
  548. IN PULONG pType)
  549. {
  550. HANDLE dfsHandle;
  551. NTSTATUS Status;
  552. Status = DfsOpen(&dfsHandle, NULL);
  553. if (NT_SUCCESS(Status)) {
  554. Status = DfsFsctl(
  555. dfsHandle,
  556. FSCTL_DFS_GET_ENTRY_TYPE,
  557. pwszPrefix,
  558. wcslen(pwszPrefix) * sizeof(WCHAR),
  559. pType,
  560. sizeof(ULONG));
  561. NtClose( dfsHandle );
  562. }
  563. return( Status );
  564. }
  565. //+----------------------------------------------------------------------------
  566. //
  567. // Function: DfsSetServiceState
  568. //
  569. // Synopsis: Sets the state of a service on a volume.
  570. //
  571. // Arguments: [VolumeId] -- The volume on which to operate
  572. // [ServiceName] -- Name of service
  573. // [State] -- Either 0 or DFS_SERVICE_TYPE_OFFLINE
  574. //
  575. // Returns: [STATUS_SUCCESS] -- The specified replica was set
  576. // online/offline as speficied.
  577. //
  578. // [DFS_STATUS_NO_SUCH_ENTRY] -- The specified volume was not
  579. // found, or the specified replica is not a server for
  580. // the volume.
  581. //
  582. // [STATUS_DATA_ERROR] -- marshalling or unmarshalling error.
  583. //
  584. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory situation.
  585. //
  586. // Status from opening handle to the Dfs driver.
  587. //
  588. //-----------------------------------------------------------------------------
  589. NTSTATUS
  590. DfsSetServiceState(
  591. IN PDFS_PKT_ENTRY_ID VolumeId,
  592. IN PWSTR ServiceName,
  593. IN ULONG State)
  594. {
  595. NTSTATUS status;
  596. HANDLE dfsHandle = NULL;
  597. DFS_DC_SET_SERVICE_STATE setSvcState;
  598. MARSHAL_BUFFER marshalBuffer;
  599. PUCHAR buffer = NULL;
  600. ULONG size;
  601. status = DfsOpen( &dfsHandle, NULL );
  602. if (NT_SUCCESS(status)) {
  603. setSvcState.Id = *VolumeId;
  604. RtlInitUnicodeString(
  605. &setSvcState.ServiceName,
  606. ServiceName);
  607. setSvcState.State = State;
  608. size = 0;
  609. status = DfsRtlSize( &MiDCSetServiceState, &setSvcState, &size );
  610. if (NT_SUCCESS(status)) {
  611. buffer = (PUCHAR) malloc( size );
  612. if (buffer == NULL) {
  613. status = STATUS_INSUFFICIENT_RESOURCES;
  614. }
  615. }
  616. if (NT_SUCCESS(status)) {
  617. MarshalBufferInitialize( &marshalBuffer, size, buffer );
  618. status = DfsRtlPut( &
  619. marshalBuffer,
  620. &MiDCSetServiceState,
  621. &setSvcState );
  622. }
  623. if (NT_SUCCESS(status)) {
  624. status = DfsFsctl(
  625. dfsHandle,
  626. FSCTL_DFS_SET_SERVICE_STATE,
  627. buffer,
  628. size,
  629. NULL,
  630. 0);
  631. }
  632. NtClose( dfsHandle );
  633. if (buffer != NULL) {
  634. free( buffer );
  635. }
  636. }
  637. return( status );
  638. }
  639. //+----------------------------------------------------------------------------
  640. //
  641. // Function: DfsDCSetVolumeState
  642. //
  643. // Synopsis: Sets the state of a volume in the DCs. This will control
  644. // whether referrals will be given out to this volume or not.
  645. //
  646. // Arguments: [VolumeId] -- The volume on which to operate
  647. // [State] -- Either 0 or PKT_ENTRY_TYPE_OFFLINE
  648. //
  649. // Returns: [STATUS_SUCCESS] -- The specified replica was set
  650. // online/offline as speficied.
  651. //
  652. // [DFS_STATUS_NO_SUCH_ENTRY] -- The specified volume was not
  653. // found.
  654. //
  655. // [STATUS_DATA_ERROR] -- marshalling or unmarshalling error.
  656. //
  657. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory situation.
  658. //
  659. // Status from opening handle to the Dfs driver.
  660. //
  661. //-----------------------------------------------------------------------------
  662. NTSTATUS
  663. DfsDCSetVolumeState(
  664. IN const PDFS_PKT_ENTRY_ID VolumeId,
  665. IN const ULONG State)
  666. {
  667. NTSTATUS status;
  668. HANDLE dfsHandle = NULL;
  669. DFS_SETSTATE_ARG setStateArg;
  670. MARSHAL_BUFFER marshalBuffer;
  671. PUCHAR buffer = NULL;
  672. ULONG size;
  673. status = DfsOpen( &dfsHandle, NULL );
  674. if (NT_SUCCESS(status)) {
  675. setStateArg.Id = *VolumeId;
  676. setStateArg.Type = State;
  677. size = 0;
  678. status = DfsRtlSize( &MiSetStateArg, &setStateArg, &size );
  679. if (NT_SUCCESS(status)) {
  680. buffer = (PUCHAR) malloc( size );
  681. if (buffer == NULL) {
  682. status = STATUS_INSUFFICIENT_RESOURCES;
  683. }
  684. }
  685. if (NT_SUCCESS(status)) {
  686. MarshalBufferInitialize( &marshalBuffer, size, buffer );
  687. status = DfsRtlPut( &
  688. marshalBuffer,
  689. &MiSetStateArg,
  690. &setStateArg );
  691. }
  692. if (NT_SUCCESS(status)) {
  693. status = DfsFsctl(
  694. dfsHandle,
  695. FSCTL_DFS_DC_SET_VOLUME_STATE,
  696. buffer,
  697. size,
  698. NULL,
  699. 0);
  700. }
  701. NtClose( dfsHandle );
  702. if (buffer != NULL) {
  703. free( buffer );
  704. }
  705. }
  706. return( status );
  707. }
  708. //+----------------------------------------------------------------------------
  709. //
  710. // Function: DfsSetVolumeTimeout
  711. //
  712. // Synopsis: Sets the timeout of a volume in the DCs.
  713. //
  714. // Arguments: [VolumeId] -- The volume on which to operate
  715. // [Timeout] -- Timeout, in seconds
  716. //
  717. // Returns: [STATUS_SUCCESS] -- The specified timeout was set as specified.
  718. //
  719. // [DFS_STATUS_NO_SUCH_ENTRY] -- The specified volume was not
  720. // found.
  721. //
  722. // [STATUS_DATA_ERROR] -- marshalling or unmarshalling error.
  723. //
  724. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory situation.
  725. //
  726. // Status from opening handle to the Dfs driver.
  727. //
  728. //-----------------------------------------------------------------------------
  729. NTSTATUS
  730. DfsSetVolumeTimeout(
  731. IN const PDFS_PKT_ENTRY_ID VolumeId,
  732. IN const ULONG Timeout)
  733. {
  734. NTSTATUS status;
  735. HANDLE dfsHandle = NULL;
  736. DFS_SET_VOLUME_TIMEOUT_ARG setVolTimeoutArg;
  737. MARSHAL_BUFFER marshalBuffer;
  738. PUCHAR buffer = NULL;
  739. ULONG size;
  740. status = DfsOpen( &dfsHandle, NULL );
  741. if (NT_SUCCESS(status)) {
  742. setVolTimeoutArg.Id = *VolumeId;
  743. setVolTimeoutArg.Timeout = Timeout;
  744. size = 0;
  745. status = DfsRtlSize( &MiSetVolTimeoutArg, &setVolTimeoutArg, &size );
  746. if (NT_SUCCESS(status)) {
  747. buffer = (PUCHAR) malloc( size );
  748. if (buffer == NULL) {
  749. status = STATUS_INSUFFICIENT_RESOURCES;
  750. }
  751. }
  752. if (NT_SUCCESS(status)) {
  753. MarshalBufferInitialize( &marshalBuffer, size, buffer );
  754. status = DfsRtlPut( &
  755. marshalBuffer,
  756. &MiSetVolTimeoutArg,
  757. &setVolTimeoutArg );
  758. }
  759. if (NT_SUCCESS(status)) {
  760. status = DfsFsctl(
  761. dfsHandle,
  762. FSCTL_DFS_SET_VOLUME_TIMEOUT,
  763. buffer,
  764. size,
  765. NULL,
  766. 0);
  767. }
  768. NtClose( dfsHandle );
  769. if (buffer != NULL) {
  770. free( buffer );
  771. }
  772. }
  773. return( status );
  774. }
  775. //+----------------------------------------------------------------------------
  776. //
  777. // Function: DfsCreateSiteEntry
  778. //
  779. // Synopsis: Loads a Site entry into the dfs site table
  780. //
  781. // Arguments: [pInfoArg] -- DFS_CREATE_SITE_INFO_ARG with info to update
  782. //
  783. // Returns: Status from opening handle to the Dfs driver.
  784. //
  785. //-----------------------------------------------------------------------------
  786. NTSTATUS
  787. DfsCreateSiteEntry(
  788. PCHAR arg,
  789. ULONG size)
  790. {
  791. NTSTATUS status;
  792. HANDLE dfsHandle = NULL;
  793. status = DfsOpen( &dfsHandle, NULL );
  794. if (NT_SUCCESS(status)) {
  795. status = DfsFsctl(
  796. dfsHandle,
  797. FSCTL_DFS_CREATE_SITE_INFO,
  798. arg,
  799. size,
  800. NULL,
  801. 0);
  802. NtClose( dfsHandle );
  803. }
  804. return( status );
  805. }
  806. //+----------------------------------------------------------------------------
  807. //
  808. // Function: DfsDeleteSiteEntry
  809. //
  810. // Synopsis: Loads a Site entry into the dfs site table
  811. //
  812. // Arguments: [pInfoArg] -- DFS_DELETE_SITE_INFO_ARG with info to update
  813. //
  814. // Returns: Status from opening handle to the Dfs driver.
  815. //
  816. //-----------------------------------------------------------------------------
  817. NTSTATUS
  818. DfsDeleteSiteEntry(
  819. PCHAR arg,
  820. ULONG size)
  821. {
  822. NTSTATUS status;
  823. HANDLE dfsHandle = NULL;
  824. status = DfsOpen( &dfsHandle, NULL );
  825. if (NT_SUCCESS(status)) {
  826. status = DfsFsctl(
  827. dfsHandle,
  828. FSCTL_DFS_DELETE_SITE_INFO,
  829. arg,
  830. size,
  831. NULL,
  832. 0);
  833. NtClose( dfsHandle );
  834. }
  835. return( status );
  836. }