//+---------------------------------------------------------------------------- // // 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 #include #include #include #include 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; }