mirror of https://github.com/tongzx/nt5src
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
1091 lines
26 KiB
//+----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1992, Microsoft Corporation.
|
|
//
|
|
// File: UPkt.c
|
|
//
|
|
// Contents: This module contains user mode functions which support
|
|
// operations on the DFS Partition Knowledge Table.
|
|
//
|
|
// Functions: PktOpen -
|
|
// PktClose -
|
|
// PktCreateEntry -
|
|
// PktCreateSubordinateEntry -
|
|
// PktFlushCache -
|
|
// PktDestroyEntry -
|
|
// PktModifyEntryGuid -
|
|
// PktSetRelationInfo -
|
|
//
|
|
// History:
|
|
//
|
|
// [mikese] I replaced MemAlloc's by malloc's, but consider using
|
|
// RtlAllocateHeap.
|
|
// Also, most of the routines in the module have a remarkably similar
|
|
// structure, and could probably be recoded using a common subroutine.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
#include <ntifs.h>
|
|
#include <ntext.h>
|
|
#include "dfsmrshl.h"
|
|
#include "nodetype.h"
|
|
#include "libsup.h"
|
|
#include "upkt.h"
|
|
#include "dfsfsctl.h"
|
|
#include "fsctrl.h" // needed for FSCTL_DFS_PKT_FLUSH_CACHE
|
|
|
|
#define MAX_OUT_BUFFER_SIZE_RELINFO 0x1000
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: PktOpen, public
|
|
//
|
|
// Synopsis: Returns a handle to the Dfs PKT so operations can be made
|
|
// to it.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: [STATUS_SUCCESS] -- Successfully opened the pkt.
|
|
//
|
|
// [STATUS_FS_DRIVER_REQUIRED] -- Dfs driver not loaded
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktOpen(
|
|
IN OUT PHANDLE PktHandle,
|
|
IN ACCESS_MASK DesiredAccess,
|
|
IN ULONG ShareAccess,
|
|
IN PUNICODE_STRING DfsNtPathName OPTIONAL
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle;
|
|
|
|
status = DfsOpen(&dfsHandle, DfsNtPathName);
|
|
|
|
if(NT_SUCCESS(status)) {
|
|
|
|
*PktHandle = dfsHandle;
|
|
|
|
} else {
|
|
|
|
status = STATUS_FS_DRIVER_REQUIRED;
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: PktClose, public
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
VOID
|
|
PktClose(
|
|
IN HANDLE PktHandle
|
|
)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
if(NT_SUCCESS(status))
|
|
NtClose(PktHandle);
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: PktCreateEntry, public
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktCreateEntry(
|
|
IN HANDLE PktHandle,
|
|
IN ULONG EntryType,
|
|
IN PDFS_PKT_ENTRY_ID EntryId,
|
|
IN PDFS_PKT_ENTRY_INFO EntryInfo,
|
|
IN ULONG CreateDisposition
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
DFS_PKT_CREATE_ENTRY_ARG arg;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
ULONG size;
|
|
|
|
arg.EntryType = EntryType;
|
|
arg.EntryId = (*EntryId);
|
|
arg.EntryInfo = (*EntryInfo);
|
|
arg.CreateDisposition = CreateDisposition;
|
|
|
|
size = 0L;
|
|
status = DfsRtlSize(&MiPktCreateEntryArg, &arg, &size);
|
|
if(NT_SUCCESS(status))
|
|
{
|
|
|
|
PVOID buffer = malloc ( size );
|
|
|
|
if ( buffer == NULL )
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
MarshalBufferInitialize(&marshalBuffer, size, buffer);
|
|
status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktCreateEntryArg,
|
|
&arg
|
|
);
|
|
|
|
if(NT_SUCCESS(status))
|
|
{
|
|
|
|
status = DfsFsctl(
|
|
PktHandle,
|
|
FSCTL_DFS_PKT_CREATE_ENTRY,
|
|
buffer,
|
|
size,
|
|
NULL,
|
|
0L
|
|
);
|
|
}
|
|
free(buffer);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: PktCreateSubordinateEntry, public
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktCreateSubordinateEntry(
|
|
IN HANDLE PktHandle,
|
|
IN PDFS_PKT_ENTRY_ID SuperiorId,
|
|
IN ULONG SubordinateType,
|
|
IN PDFS_PKT_ENTRY_ID SubordinateId,
|
|
IN PDFS_PKT_ENTRY_INFO SubordinateInfo OPTIONAL,
|
|
IN ULONG CreateDisposition
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
DFS_PKT_CREATE_SUBORDINATE_ENTRY_ARG arg;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
ULONG size;
|
|
|
|
arg.EntryId = (*SuperiorId);
|
|
arg.SubEntryType = SubordinateType;
|
|
arg.SubEntryId = (*SubordinateId);
|
|
arg.SubEntryInfo = (*SubordinateInfo);
|
|
arg.CreateDisposition = CreateDisposition;
|
|
|
|
size = 0L;
|
|
status = DfsRtlSize(&MiPktCreateSubordinateEntryArg, &arg, &size);
|
|
if(NT_SUCCESS(status)) {
|
|
|
|
PVOID buffer = malloc ( size );
|
|
|
|
if ( buffer == NULL )
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
MarshalBufferInitialize(&marshalBuffer, size, buffer);
|
|
status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktCreateSubordinateEntryArg,
|
|
&arg
|
|
);
|
|
|
|
if(NT_SUCCESS(status)) {
|
|
|
|
status = DfsFsctl(
|
|
PktHandle,
|
|
FSCTL_DFS_PKT_CREATE_SUBORDINATE_ENTRY,
|
|
buffer,
|
|
size,
|
|
NULL,
|
|
0L
|
|
);
|
|
}
|
|
free(buffer);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: PktDestroyEntry, public
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktDestroyEntry(
|
|
IN HANDLE PktHandle,
|
|
IN DFS_PKT_ENTRY_ID victim
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
ULONG size;
|
|
|
|
size = 0L;
|
|
status = DfsRtlSize(&MiPktEntryId, &victim, &size);
|
|
if(NT_SUCCESS(status))
|
|
{
|
|
PVOID buffer = malloc ( size );
|
|
|
|
if ( buffer == NULL )
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
MarshalBufferInitialize(&marshalBuffer, size, buffer);
|
|
status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktEntryId,
|
|
&victim
|
|
);
|
|
|
|
if(NT_SUCCESS(status))
|
|
{
|
|
|
|
status = DfsFsctl(
|
|
PktHandle,
|
|
FSCTL_DFS_PKT_DESTROY_ENTRY,
|
|
buffer,
|
|
size,
|
|
NULL,
|
|
0L
|
|
);
|
|
}
|
|
free(buffer);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: PktGetRelationInfo, public
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: The relationalInfo structure should be made available
|
|
// by the caller but additional memory is allocated in here.
|
|
// The caller should deallocate all that memory himself.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
NTSTATUS
|
|
PktGetRelationInfo(
|
|
IN HANDLE PktHandle,
|
|
IN PDFS_PKT_ENTRY_ID EntryId,
|
|
IN OUT PDFS_PKT_RELATION_INFO RelationInfo
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
ULONG size;
|
|
PVOID OutputBuffer;
|
|
|
|
size = 0L;
|
|
status = DfsRtlSize(&MiPktEntryId, EntryId, &size);
|
|
if(NT_SUCCESS(status))
|
|
{
|
|
PVOID buffer = malloc ( size );
|
|
|
|
if ( buffer == NULL )
|
|
return(STATUS_NO_MEMORY);
|
|
|
|
MarshalBufferInitialize(&marshalBuffer, size, buffer);
|
|
status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktEntryId,
|
|
EntryId
|
|
);
|
|
|
|
|
|
if(NT_SUCCESS(status))
|
|
{
|
|
|
|
// Do we want to retry with larger sizes?
|
|
OutputBuffer = malloc ( MAX_OUT_BUFFER_SIZE_RELINFO );
|
|
if ( OutputBuffer == NULL )
|
|
{
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
else
|
|
{
|
|
|
|
status = DfsFsctl(
|
|
PktHandle,
|
|
FSCTL_DFS_PKT_GET_RELATION_INFO,
|
|
buffer,
|
|
size,
|
|
OutputBuffer,
|
|
MAX_OUT_BUFFER_SIZE_RELINFO);
|
|
|
|
//
|
|
// We can get rid of this right away.
|
|
//
|
|
|
|
|
|
if(NT_SUCCESS(status)) {
|
|
|
|
MarshalBufferInitialize(
|
|
&marshalBuffer,
|
|
MAX_OUT_BUFFER_SIZE_RELINFO,
|
|
OutputBuffer
|
|
);
|
|
|
|
status = DfsRtlGet(
|
|
&marshalBuffer,
|
|
&MiPktRelationInfo,
|
|
RelationInfo
|
|
);
|
|
}
|
|
|
|
free(OutputBuffer);
|
|
}
|
|
}
|
|
free(buffer);
|
|
|
|
} //Status from DfsRtlSize
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
RtlZeroMemory(RelationInfo, sizeof(DFS_PKT_RELATION_INFO));
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: PktValidateLocalVolumeInfo, public
|
|
//
|
|
// Synopsis: Asks the Dfs driver to validate its local volume info with
|
|
// the one that is passed in.
|
|
//
|
|
// Arguments: [relationInfo] -- The DFS_PKT_RELATION_INFO to validate
|
|
// against.
|
|
//
|
|
// Returns: [STATUS_SUCCESS] -- Successfully validated local volume info
|
|
//
|
|
// [STATUS_REGISTRY_RECOVERED] -- Successfully validated info,
|
|
// but had to make changes to local info
|
|
//
|
|
// [DFS_STATUS_NOSUCH_LOCAL_VOLUME] -- The driver has no record
|
|
// of local volume described in relation info.
|
|
//
|
|
// [STATUS_UNSUCCESSFUL] -- Unable to fixup the local relation
|
|
// info. An appropriate message was logged to the
|
|
// local eventlog.
|
|
//
|
|
// [STATUS_DATA_ERROR] -- Passed in relationInfo is bogus.
|
|
//
|
|
// [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
|
|
//
|
|
// [STATUS_FS_DRIVER_REQUIRED] -- Unable to open handle to the
|
|
// Dfs driver
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktValidateLocalVolumeInfo(
|
|
IN PDFS_PKT_RELATION_INFO relationInfo)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
PUCHAR pBuffer;
|
|
ULONG cbBuffer;
|
|
|
|
status = DfsOpen(&dfsHandle, NULL);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
cbBuffer = 0;
|
|
|
|
status = DfsRtlSize( &MiPktRelationInfo, relationInfo, &cbBuffer );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
pBuffer = malloc( cbBuffer );
|
|
|
|
if (pBuffer != NULL) {
|
|
|
|
MarshalBufferInitialize(&marshalBuffer, cbBuffer, pBuffer);
|
|
|
|
status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktRelationInfo,
|
|
relationInfo);
|
|
|
|
|
|
} else {
|
|
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_VERIFY_LOCAL_VOLUME_KNOWLEDGE,
|
|
pBuffer,
|
|
cbBuffer,
|
|
NULL,
|
|
0);
|
|
|
|
}
|
|
|
|
if (pBuffer != NULL)
|
|
free(pBuffer);
|
|
|
|
}
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
}
|
|
|
|
return( status );
|
|
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: PktPruneLocalPartition
|
|
//
|
|
// Synopsis: Asks the Dfs Driver to get rid of a local volume that is
|
|
// not supposed to be supported by this server.
|
|
//
|
|
// Arguments: [EntryId] -- The entry id of the volume to prune.
|
|
//
|
|
// Returns: [STATUS_SUCCESS] -- Successfully pruned the volume
|
|
//
|
|
// [DFS_STATUS_NOSUCH_LOCAL_VOLUME] -- The driver has no record
|
|
// of local volume described in relation info.
|
|
//
|
|
// [STATUS_UNSUCCESSFUL] -- Unable to fixup the local relation
|
|
// info. An appropriate message was logged to the
|
|
// local eventlog.
|
|
//
|
|
// [STATUS_DATA_ERROR] -- Passed in relationInfo is bogus.
|
|
//
|
|
// [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
|
|
//
|
|
// [STATUS_FS_DRIVER_REQUIRED] -- Unable to open handle to the
|
|
// Dfs driver
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktPruneLocalPartition(
|
|
IN PDFS_PKT_ENTRY_ID EntryId)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
PUCHAR pBuffer;
|
|
ULONG cbBuffer;
|
|
|
|
status = DfsOpen(&dfsHandle, NULL);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
cbBuffer = 0;
|
|
|
|
status = DfsRtlSize( &MiPktEntryId, EntryId, &cbBuffer );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
pBuffer = malloc( cbBuffer );
|
|
|
|
if (pBuffer != NULL) {
|
|
|
|
MarshalBufferInitialize(&marshalBuffer, cbBuffer, pBuffer);
|
|
|
|
status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktEntryId,
|
|
EntryId);
|
|
|
|
|
|
} else {
|
|
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_PRUNE_LOCAL_PARTITION,
|
|
pBuffer,
|
|
cbBuffer,
|
|
NULL,
|
|
0);
|
|
|
|
}
|
|
|
|
if (pBuffer != NULL)
|
|
free(pBuffer);
|
|
|
|
}
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
}
|
|
|
|
return( status );
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: PktIsChildnameLegal, public
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktIsChildnameLegal(
|
|
IN PWCHAR pwszParent,
|
|
IN PWCHAR pwszChild,
|
|
IN GUID *pidChild)
|
|
{
|
|
HANDLE dfsHandle;
|
|
NTSTATUS Status;
|
|
DFS_PKT_ENTRY_ID idParent, idChild;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
PUCHAR pBuffer;
|
|
ULONG cbBuffer;
|
|
|
|
RtlZeroMemory( &idParent, sizeof(DFS_PKT_ENTRY_ID) );
|
|
|
|
RtlZeroMemory( &idChild, sizeof(DFS_PKT_ENTRY_ID) );
|
|
|
|
RtlInitUnicodeString( &idParent.Prefix, pwszParent );
|
|
|
|
RtlInitUnicodeString( &idChild.Prefix, pwszChild );
|
|
|
|
idChild.Uid = *pidChild;
|
|
|
|
cbBuffer = 0;
|
|
|
|
Status = DfsOpen(&dfsHandle, NULL);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
Status = DfsRtlSize( &MiPktEntryId, &idParent, &cbBuffer );
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
Status = DfsRtlSize( &MiPktEntryId, &idChild, &cbBuffer );
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
pBuffer = malloc( cbBuffer );
|
|
|
|
if (pBuffer != NULL) {
|
|
|
|
MarshalBufferInitialize( &marshalBuffer, cbBuffer, pBuffer );
|
|
|
|
Status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktEntryId,
|
|
&idParent );
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
Status = DfsRtlPut(
|
|
&marshalBuffer,
|
|
&MiPktEntryId,
|
|
&idChild );
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
Status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_IS_CHILDNAME_LEGAL,
|
|
pBuffer,
|
|
cbBuffer,
|
|
NULL,
|
|
0L);
|
|
|
|
}
|
|
|
|
free( pBuffer );
|
|
|
|
} else {
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
}
|
|
|
|
return( Status );
|
|
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: PktGetEntryType, public
|
|
//
|
|
// Synopsis: Given a prefix, this routine retrieves the entry type of the
|
|
// PktEntry
|
|
//
|
|
// Arguments: [pwszPrefix] -- The prefix whose PktEntry's type is required
|
|
// [pType] -- The type is returned here.
|
|
//
|
|
// Returns:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
PktGetEntryType(
|
|
IN PWSTR pwszPrefix,
|
|
IN PULONG pType)
|
|
{
|
|
HANDLE dfsHandle;
|
|
NTSTATUS Status;
|
|
|
|
Status = DfsOpen(&dfsHandle, NULL);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
Status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_GET_ENTRY_TYPE,
|
|
pwszPrefix,
|
|
wcslen(pwszPrefix) * sizeof(WCHAR),
|
|
pType,
|
|
sizeof(ULONG));
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
}
|
|
|
|
return( Status );
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: DfsSetServiceState
|
|
//
|
|
// Synopsis: Sets the state of a service on a volume.
|
|
//
|
|
// Arguments: [VolumeId] -- The volume on which to operate
|
|
// [ServiceName] -- Name of service
|
|
// [State] -- Either 0 or DFS_SERVICE_TYPE_OFFLINE
|
|
//
|
|
// Returns: [STATUS_SUCCESS] -- The specified replica was set
|
|
// online/offline as speficied.
|
|
//
|
|
// [DFS_STATUS_NO_SUCH_ENTRY] -- The specified volume was not
|
|
// found, or the specified replica is not a server for
|
|
// the volume.
|
|
//
|
|
// [STATUS_DATA_ERROR] -- marshalling or unmarshalling error.
|
|
//
|
|
// [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory situation.
|
|
//
|
|
// Status from opening handle to the Dfs driver.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DfsSetServiceState(
|
|
IN PDFS_PKT_ENTRY_ID VolumeId,
|
|
IN PWSTR ServiceName,
|
|
IN ULONG State)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle = NULL;
|
|
DFS_DC_SET_SERVICE_STATE setSvcState;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
PUCHAR buffer = NULL;
|
|
ULONG size;
|
|
|
|
status = DfsOpen( &dfsHandle, NULL );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
setSvcState.Id = *VolumeId;
|
|
RtlInitUnicodeString(
|
|
&setSvcState.ServiceName,
|
|
ServiceName);
|
|
setSvcState.State = State;
|
|
|
|
size = 0;
|
|
|
|
status = DfsRtlSize( &MiDCSetServiceState, &setSvcState, &size );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
buffer = (PUCHAR) malloc( size );
|
|
|
|
if (buffer == NULL) {
|
|
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
MarshalBufferInitialize( &marshalBuffer, size, buffer );
|
|
|
|
status = DfsRtlPut( &
|
|
marshalBuffer,
|
|
&MiDCSetServiceState,
|
|
&setSvcState );
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_SET_SERVICE_STATE,
|
|
buffer,
|
|
size,
|
|
NULL,
|
|
0);
|
|
|
|
}
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
if (buffer != NULL) {
|
|
|
|
free( buffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( status );
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: DfsDCSetVolumeState
|
|
//
|
|
// Synopsis: Sets the state of a volume in the DCs. This will control
|
|
// whether referrals will be given out to this volume or not.
|
|
//
|
|
// Arguments: [VolumeId] -- The volume on which to operate
|
|
// [State] -- Either 0 or PKT_ENTRY_TYPE_OFFLINE
|
|
//
|
|
// Returns: [STATUS_SUCCESS] -- The specified replica was set
|
|
// online/offline as speficied.
|
|
//
|
|
// [DFS_STATUS_NO_SUCH_ENTRY] -- The specified volume was not
|
|
// found.
|
|
//
|
|
// [STATUS_DATA_ERROR] -- marshalling or unmarshalling error.
|
|
//
|
|
// [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory situation.
|
|
//
|
|
// Status from opening handle to the Dfs driver.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DfsDCSetVolumeState(
|
|
IN const PDFS_PKT_ENTRY_ID VolumeId,
|
|
IN const ULONG State)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle = NULL;
|
|
DFS_SETSTATE_ARG setStateArg;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
PUCHAR buffer = NULL;
|
|
ULONG size;
|
|
|
|
status = DfsOpen( &dfsHandle, NULL );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
setStateArg.Id = *VolumeId;
|
|
setStateArg.Type = State;
|
|
|
|
size = 0;
|
|
|
|
status = DfsRtlSize( &MiSetStateArg, &setStateArg, &size );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
buffer = (PUCHAR) malloc( size );
|
|
|
|
if (buffer == NULL) {
|
|
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
MarshalBufferInitialize( &marshalBuffer, size, buffer );
|
|
|
|
status = DfsRtlPut( &
|
|
marshalBuffer,
|
|
&MiSetStateArg,
|
|
&setStateArg );
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_DC_SET_VOLUME_STATE,
|
|
buffer,
|
|
size,
|
|
NULL,
|
|
0);
|
|
|
|
}
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
if (buffer != NULL) {
|
|
|
|
free( buffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( status );
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: DfsSetVolumeTimeout
|
|
//
|
|
// Synopsis: Sets the timeout of a volume in the DCs.
|
|
//
|
|
// Arguments: [VolumeId] -- The volume on which to operate
|
|
// [Timeout] -- Timeout, in seconds
|
|
//
|
|
// Returns: [STATUS_SUCCESS] -- The specified timeout was set as specified.
|
|
//
|
|
// [DFS_STATUS_NO_SUCH_ENTRY] -- The specified volume was not
|
|
// found.
|
|
//
|
|
// [STATUS_DATA_ERROR] -- marshalling or unmarshalling error.
|
|
//
|
|
// [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory situation.
|
|
//
|
|
// Status from opening handle to the Dfs driver.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DfsSetVolumeTimeout(
|
|
IN const PDFS_PKT_ENTRY_ID VolumeId,
|
|
IN const ULONG Timeout)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle = NULL;
|
|
DFS_SET_VOLUME_TIMEOUT_ARG setVolTimeoutArg;
|
|
MARSHAL_BUFFER marshalBuffer;
|
|
PUCHAR buffer = NULL;
|
|
ULONG size;
|
|
|
|
status = DfsOpen( &dfsHandle, NULL );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
setVolTimeoutArg.Id = *VolumeId;
|
|
setVolTimeoutArg.Timeout = Timeout;
|
|
|
|
size = 0;
|
|
|
|
status = DfsRtlSize( &MiSetVolTimeoutArg, &setVolTimeoutArg, &size );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
buffer = (PUCHAR) malloc( size );
|
|
|
|
if (buffer == NULL) {
|
|
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
MarshalBufferInitialize( &marshalBuffer, size, buffer );
|
|
|
|
status = DfsRtlPut( &
|
|
marshalBuffer,
|
|
&MiSetVolTimeoutArg,
|
|
&setVolTimeoutArg );
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_SET_VOLUME_TIMEOUT,
|
|
buffer,
|
|
size,
|
|
NULL,
|
|
0);
|
|
|
|
}
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
if (buffer != NULL) {
|
|
|
|
free( buffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( status );
|
|
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: DfsCreateSiteEntry
|
|
//
|
|
// Synopsis: Loads a Site entry into the dfs site table
|
|
//
|
|
// Arguments: [pInfoArg] -- DFS_CREATE_SITE_INFO_ARG with info to update
|
|
//
|
|
// Returns: Status from opening handle to the Dfs driver.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DfsCreateSiteEntry(
|
|
PCHAR arg,
|
|
ULONG size)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle = NULL;
|
|
|
|
status = DfsOpen( &dfsHandle, NULL );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_CREATE_SITE_INFO,
|
|
arg,
|
|
size,
|
|
NULL,
|
|
0);
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
}
|
|
|
|
return( status );
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: DfsDeleteSiteEntry
|
|
//
|
|
// Synopsis: Loads a Site entry into the dfs site table
|
|
//
|
|
// Arguments: [pInfoArg] -- DFS_DELETE_SITE_INFO_ARG with info to update
|
|
//
|
|
// Returns: Status from opening handle to the Dfs driver.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DfsDeleteSiteEntry(
|
|
PCHAR arg,
|
|
ULONG size)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE dfsHandle = NULL;
|
|
|
|
status = DfsOpen( &dfsHandle, NULL );
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
|
|
status = DfsFsctl(
|
|
dfsHandle,
|
|
FSCTL_DFS_DELETE_SITE_INFO,
|
|
arg,
|
|
size,
|
|
NULL,
|
|
0);
|
|
|
|
NtClose( dfsHandle );
|
|
|
|
}
|
|
|
|
return( status );
|
|
}
|