windows-nt/Source/XPSP1/NT/ds/security/ntmarta/newsrc/dfsext.c
2020-09-26 16:20:57 +08:00

251 lines
6.3 KiB
C

//+----------------------------------------------------------------------------
//
// Copyright (C) 1996, Microsoft Corporation
//
// File: dfsext.c
//
// Contents: Code to see if a path refers to a Dfs path.
//
// Classes: None
//
// Functions: IsThisADfsPath
//
// History: March 11, 1996 Milans created
//
//-----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <dfsfsctl.h>
#include <windows.h>
NTSTATUS
DfsFsctl(
IN HANDLE DfsHandle,
IN ULONG FsControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength);
NTSTATUS
DfsOpen(
IN OUT PHANDLE DfsHandle);
//+----------------------------------------------------------------------------
//
// Function: IsThisADfsPath, public
//
// Synopsis: Given a fully qualified UNC or Drive based path, this routine
// will identify if it is a Dfs path or not.
//
// Arguments: [pwszPath] -- The fully qualified path to test.
//
// [cwPath] -- Length, in WCHARs, of pwszPath. If this is 0,
// this routine will compute the length. If it is
// non-zero, it will assume that the length of pwszPath
// is cwPath WCHARs.
//
// Returns: TRUE if pwszPath is a Dfs path, FALSE otherwise.
//
//-----------------------------------------------------------------------------
BOOL
IsThisADfsPath(
IN LPCWSTR pwszPath,
IN DWORD cwPath OPTIONAL)
{
NTSTATUS Status;
HANDLE hDfs;
BOOL fIsDfsPath = FALSE;
PDFS_IS_VALID_PREFIX_ARG pPrefixArg;
ULONG Size;
//
// We only accept UNC or drive letter paths
//
if (pwszPath == NULL)
return( FALSE );
if (cwPath == 0)
cwPath = wcslen( pwszPath );
if (cwPath < 2)
return( FALSE );
Status = DfsOpen( &hDfs );
if (!NT_SUCCESS(Status))
return( FALSE );
//
// From this point on, we must remember to close hDfs before returning.
//
if (pwszPath[0] == L'\\' && pwszPath[1] == L'\\') {
Size = sizeof(DFS_IS_VALID_PREFIX_ARG) +
cwPath * sizeof(WCHAR);
pPrefixArg = (PDFS_IS_VALID_PREFIX_ARG) LocalAlloc(0, Size);
if ( pPrefixArg ) {
//
// the InputBuffer must be in the structure of DFS_IS_VALID_PREFIX_ARG
//
pPrefixArg->CSCAgentCreate = FALSE;
pPrefixArg->RemoteNameLen = (SHORT)( (cwPath-1) * sizeof(WCHAR));
wcscpy(&pPrefixArg->RemoteName[0], pwszPath+1);
Status = DfsFsctl(
hDfs,
FSCTL_DFS_IS_VALID_PREFIX,
(PVOID) pPrefixArg, // &pwszPath[1],
Size, // (cwPath - 1) * sizeof(WCHAR),
NULL,
0);
LocalFree(pPrefixArg);
} else {
Status = STATUS_NO_MEMORY;
}
if (NT_SUCCESS(Status))
fIsDfsPath = TRUE;
} else if (pwszPath[1] == L':') {
//
// This is a drive based name. We'll fsctl to the driver to return
// the prefix for this drive, if it is indeed a Dfs drive.
//
Status = DfsFsctl(
hDfs,
FSCTL_DFS_IS_VALID_LOGICAL_ROOT,
(PVOID) &pwszPath[0],
sizeof(WCHAR),
NULL,
0);
if (NT_SUCCESS(Status))
fIsDfsPath = TRUE;
}
NtClose( hDfs );
return( fIsDfsPath );
}
//+-------------------------------------------------------------------------
//
// Function: DfsOpen, private
//
// Synopsis: Opens a handle to the Dfs driver for fsctl purposes.
//
// Arguments: [DfsHandle] -- On successful return, contains handle to the
// driver.
//
// Returns: NTSTATUS of attempt to open the Dfs driver.
//
//--------------------------------------------------------------------------
NTSTATUS
DfsOpen(
IN OUT PHANDLE DfsHandle)
{
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING name = {
sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
DFS_DRIVER_NAME};
InitializeObjectAttributes(
&objectAttributes,
&name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = NtCreateFile(
DfsHandle,
SYNCHRONIZE,
&objectAttributes,
&ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_IF,
FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(status))
status = ioStatus.Status;
return status;
}
//+-------------------------------------------------------------------------
//
// Function: DfsFsctl, public
//
// Synopsis: Fsctl's to the Dfs driver.
//
// Arguments: [DfsHandle] -- Handle to the Dfs driver, usually obtained by
// calling DfsOpen.
// [FsControlCode] -- The FSCTL code (see private\inc\dfsfsctl.h)
// [InputBuffer] -- InputBuffer to the fsctl.
// [InputBufferLength] -- Length, in BYTES, of InputBuffer
// [OutputBuffer] -- OutputBuffer to the fsctl.
// [OutputBufferLength] -- Length, in BYTES, of OutputBuffer
//
// Returns: NTSTATUS of Fsctl attempt.
//
//--------------------------------------------------------------------------
NTSTATUS
DfsFsctl(
IN HANDLE DfsHandle,
IN ULONG FsControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
)
{
NTSTATUS status;
IO_STATUS_BLOCK ioStatus;
status = NtFsControlFile(
DfsHandle,
NULL, // Event,
NULL, // ApcRoutine,
NULL, // ApcContext,
&ioStatus,
FsControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength
);
if(NT_SUCCESS(status))
status = ioStatus.Status;
return status;
}