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.

250 lines
6.3 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1996, Microsoft Corporation
  4. //
  5. // File: dfsext.c
  6. //
  7. // Contents: Code to see if a path refers to a Dfs path.
  8. //
  9. // Classes: None
  10. //
  11. // Functions: IsThisADfsPath
  12. //
  13. // History: March 11, 1996 Milans created
  14. //
  15. //-----------------------------------------------------------------------------
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <dfsfsctl.h>
  20. #include <windows.h>
  21. NTSTATUS
  22. DfsFsctl(
  23. IN HANDLE DfsHandle,
  24. IN ULONG FsControlCode,
  25. IN PVOID InputBuffer OPTIONAL,
  26. IN ULONG InputBufferLength,
  27. OUT PVOID OutputBuffer OPTIONAL,
  28. IN ULONG OutputBufferLength);
  29. NTSTATUS
  30. DfsOpen(
  31. IN OUT PHANDLE DfsHandle);
  32. //+----------------------------------------------------------------------------
  33. //
  34. // Function: IsThisADfsPath, public
  35. //
  36. // Synopsis: Given a fully qualified UNC or Drive based path, this routine
  37. // will identify if it is a Dfs path or not.
  38. //
  39. // Arguments: [pwszPath] -- The fully qualified path to test.
  40. //
  41. // [cwPath] -- Length, in WCHARs, of pwszPath. If this is 0,
  42. // this routine will compute the length. If it is
  43. // non-zero, it will assume that the length of pwszPath
  44. // is cwPath WCHARs.
  45. //
  46. // Returns: TRUE if pwszPath is a Dfs path, FALSE otherwise.
  47. //
  48. //-----------------------------------------------------------------------------
  49. BOOL
  50. IsThisADfsPath(
  51. IN LPCWSTR pwszPath,
  52. IN DWORD cwPath OPTIONAL)
  53. {
  54. NTSTATUS Status;
  55. HANDLE hDfs;
  56. BOOL fIsDfsPath = FALSE;
  57. PDFS_IS_VALID_PREFIX_ARG pPrefixArg;
  58. ULONG Size;
  59. //
  60. // We only accept UNC or drive letter paths
  61. //
  62. if (pwszPath == NULL)
  63. return( FALSE );
  64. if (cwPath == 0)
  65. cwPath = wcslen( pwszPath );
  66. if (cwPath < 2)
  67. return( FALSE );
  68. Status = DfsOpen( &hDfs );
  69. if (!NT_SUCCESS(Status))
  70. return( FALSE );
  71. //
  72. // From this point on, we must remember to close hDfs before returning.
  73. //
  74. if (pwszPath[0] == L'\\' && pwszPath[1] == L'\\') {
  75. Size = sizeof(DFS_IS_VALID_PREFIX_ARG) +
  76. cwPath * sizeof(WCHAR);
  77. pPrefixArg = (PDFS_IS_VALID_PREFIX_ARG) LocalAlloc(0, Size);
  78. if ( pPrefixArg ) {
  79. //
  80. // the InputBuffer must be in the structure of DFS_IS_VALID_PREFIX_ARG
  81. //
  82. pPrefixArg->CSCAgentCreate = FALSE;
  83. pPrefixArg->RemoteNameLen = (SHORT)( (cwPath-1) * sizeof(WCHAR));
  84. wcscpy(&pPrefixArg->RemoteName[0], pwszPath+1);
  85. Status = DfsFsctl(
  86. hDfs,
  87. FSCTL_DFS_IS_VALID_PREFIX,
  88. (PVOID) pPrefixArg, // &pwszPath[1],
  89. Size, // (cwPath - 1) * sizeof(WCHAR),
  90. NULL,
  91. 0);
  92. LocalFree(pPrefixArg);
  93. } else {
  94. Status = STATUS_NO_MEMORY;
  95. }
  96. if (NT_SUCCESS(Status))
  97. fIsDfsPath = TRUE;
  98. } else if (pwszPath[1] == L':') {
  99. //
  100. // This is a drive based name. We'll fsctl to the driver to return
  101. // the prefix for this drive, if it is indeed a Dfs drive.
  102. //
  103. Status = DfsFsctl(
  104. hDfs,
  105. FSCTL_DFS_IS_VALID_LOGICAL_ROOT,
  106. (PVOID) &pwszPath[0],
  107. sizeof(WCHAR),
  108. NULL,
  109. 0);
  110. if (NT_SUCCESS(Status))
  111. fIsDfsPath = TRUE;
  112. }
  113. NtClose( hDfs );
  114. return( fIsDfsPath );
  115. }
  116. //+-------------------------------------------------------------------------
  117. //
  118. // Function: DfsOpen, private
  119. //
  120. // Synopsis: Opens a handle to the Dfs driver for fsctl purposes.
  121. //
  122. // Arguments: [DfsHandle] -- On successful return, contains handle to the
  123. // driver.
  124. //
  125. // Returns: NTSTATUS of attempt to open the Dfs driver.
  126. //
  127. //--------------------------------------------------------------------------
  128. NTSTATUS
  129. DfsOpen(
  130. IN OUT PHANDLE DfsHandle)
  131. {
  132. NTSTATUS status;
  133. OBJECT_ATTRIBUTES objectAttributes;
  134. IO_STATUS_BLOCK ioStatus;
  135. UNICODE_STRING name = {
  136. sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
  137. sizeof(DFS_DRIVER_NAME)-sizeof(UNICODE_NULL),
  138. DFS_DRIVER_NAME};
  139. InitializeObjectAttributes(
  140. &objectAttributes,
  141. &name,
  142. OBJ_CASE_INSENSITIVE,
  143. NULL,
  144. NULL
  145. );
  146. status = NtCreateFile(
  147. DfsHandle,
  148. SYNCHRONIZE,
  149. &objectAttributes,
  150. &ioStatus,
  151. NULL,
  152. FILE_ATTRIBUTE_NORMAL,
  153. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  154. FILE_OPEN_IF,
  155. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  156. NULL,
  157. 0);
  158. if (NT_SUCCESS(status))
  159. status = ioStatus.Status;
  160. return status;
  161. }
  162. //+-------------------------------------------------------------------------
  163. //
  164. // Function: DfsFsctl, public
  165. //
  166. // Synopsis: Fsctl's to the Dfs driver.
  167. //
  168. // Arguments: [DfsHandle] -- Handle to the Dfs driver, usually obtained by
  169. // calling DfsOpen.
  170. // [FsControlCode] -- The FSCTL code (see private\inc\dfsfsctl.h)
  171. // [InputBuffer] -- InputBuffer to the fsctl.
  172. // [InputBufferLength] -- Length, in BYTES, of InputBuffer
  173. // [OutputBuffer] -- OutputBuffer to the fsctl.
  174. // [OutputBufferLength] -- Length, in BYTES, of OutputBuffer
  175. //
  176. // Returns: NTSTATUS of Fsctl attempt.
  177. //
  178. //--------------------------------------------------------------------------
  179. NTSTATUS
  180. DfsFsctl(
  181. IN HANDLE DfsHandle,
  182. IN ULONG FsControlCode,
  183. IN PVOID InputBuffer OPTIONAL,
  184. IN ULONG InputBufferLength,
  185. OUT PVOID OutputBuffer OPTIONAL,
  186. IN ULONG OutputBufferLength
  187. )
  188. {
  189. NTSTATUS status;
  190. IO_STATUS_BLOCK ioStatus;
  191. status = NtFsControlFile(
  192. DfsHandle,
  193. NULL, // Event,
  194. NULL, // ApcRoutine,
  195. NULL, // ApcContext,
  196. &ioStatus,
  197. FsControlCode,
  198. InputBuffer,
  199. InputBufferLength,
  200. OutputBuffer,
  201. OutputBufferLength
  202. );
  203. if(NT_SUCCESS(status))
  204. status = ioStatus.Status;
  205. return status;
  206. }