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.

450 lines
11 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: STRUCSUP.C
  6. //
  7. // Contents: This module implements the Dsfs in-memory data structure
  8. // manipulation routines
  9. //
  10. // Functions:
  11. // DfsCreateIrpContext -
  12. // DfsDeleteIrpContext_Real -
  13. // DfsInitializeVcb -
  14. // DfsCreateFcb -
  15. // DfsDeleteFcb_Real -
  16. // DspAllocateStringRoutine -
  17. //
  18. // History: 12 Nov 1991 AlanW Created from CDFS souce.
  19. // 8 May 1992 PeterCo added support for new PKT stuff (M000)
  20. //-----------------------------------------------------------------------------
  21. #include "dfsprocs.h"
  22. //
  23. // The debug trace level
  24. //
  25. #define Dbg (DEBUG_TRACE_STRUCSUP)
  26. #ifdef ALLOC_PRAGMA
  27. #pragma alloc_text( PAGE, DfsInitializeVcb )
  28. #pragma alloc_text( PAGE, DfsDeleteIrpContext_Real)
  29. #pragma alloc_text( PAGE, DfsCreateFcb )
  30. #pragma alloc_text( PAGE, DfsDeleteFcb_Real )
  31. //
  32. // The following routines cannot be paged because they acquire/release
  33. // spin locks
  34. //
  35. // DfsCreateIrpContext
  36. // DfsDeleteIrpContext_Real
  37. //
  38. #endif // ALLOC_PRAGMA
  39. //+-------------------------------------------------------------------
  40. //
  41. // Function: DfsCreateIrpContext, public
  42. //
  43. // Synopsis: This routine creates a new IRP_CONTEXT record
  44. //
  45. // Arguments: [Irp] - Supplies the originating Irp.
  46. // [Wait] - Supplies the wait value to store in the context
  47. //
  48. // Returns: PIRP_CONTEXT - returns a pointer to the newly allocate
  49. // IRP_CONTEXT Record
  50. //
  51. //--------------------------------------------------------------------
  52. PIRP_CONTEXT
  53. DfsCreateIrpContext (
  54. IN PIRP Irp,
  55. IN BOOLEAN Wait
  56. ) {
  57. KIRQL SavedIrql;
  58. PIRP_CONTEXT IrpContext;
  59. PIO_STACK_LOCATION IrpSp;
  60. DfsDbgTrace(+1, Dbg, "DfsCreateIrpContext\n", 0);
  61. IrpContext = ExAllocateFromNPagedLookasideList (&DfsData.IrpContextLookaside);
  62. if (IrpContext != NULL) {
  63. //
  64. // Zero out the irp context and indicate that it is from pool and
  65. // not zone allocated
  66. //
  67. RtlZeroMemory( IrpContext, sizeof(IRP_CONTEXT) );
  68. //
  69. // Set the proper node type code and node byte size
  70. //
  71. IrpContext->NodeTypeCode = DSFS_NTC_IRP_CONTEXT;
  72. IrpContext->NodeByteSize = sizeof(IRP_CONTEXT);
  73. //
  74. // Set the originating Irp field
  75. //
  76. IrpContext->OriginatingIrp = Irp;
  77. IrpSp = IoGetCurrentIrpStackLocation( Irp );
  78. //
  79. // Major/Minor Function codes
  80. //
  81. IrpContext->MajorFunction = IrpSp->MajorFunction;
  82. IrpContext->MinorFunction = IrpSp->MinorFunction;
  83. //
  84. // Set the Wait and InFsd flags
  85. //
  86. if (Wait) {
  87. IrpContext->Flags |= IRP_CONTEXT_FLAG_WAIT;
  88. }
  89. IrpContext->Flags |= IRP_CONTEXT_FLAG_IN_FSD;
  90. }
  91. //
  92. // return and tell the caller
  93. //
  94. DfsDbgTrace(-1, Dbg, "DfsCreateIrpContext -> %08lx\n", IrpContext);
  95. return IrpContext;
  96. }
  97. //+-------------------------------------------------------------------
  98. //
  99. // Function: DfsDeleteIrpContext, public
  100. //
  101. // Synopsis: This routine deallocates and removes the specified
  102. // IRP_CONTEXT record from the Dsfs in-memory data
  103. // structures. It should only be called by DfsCompleteRequest.
  104. //
  105. // Arguments: [IrpContext] -- Supplies the IRP_CONTEXT to remove
  106. //
  107. // Returns: None
  108. //
  109. // Notes:
  110. //
  111. //--------------------------------------------------------------------
  112. VOID
  113. DfsDeleteIrpContext_Real (
  114. IN PIRP_CONTEXT IrpContext
  115. ) {
  116. DfsDbgTrace(+1, Dbg, "DfsDeleteIrpContext, IrpContext = %08lx\n", IrpContext);
  117. ASSERT( IrpContext->NodeTypeCode == DSFS_NTC_IRP_CONTEXT );
  118. ExFreeToNPagedLookasideList (&DfsData.IrpContextLookaside, IrpContext);
  119. //
  120. // return and tell the caller
  121. //
  122. DfsDbgTrace(-1, Dbg, "DfsDeleteIrpContext -> VOID\n", 0);
  123. return;
  124. }
  125. //+-------------------------------------------------------------------
  126. //
  127. // Function: DfsInitializeVcb, public
  128. //
  129. // Synopsis: This routine initializes a DFS_VCB.
  130. //
  131. // Arguments: [IrpContext] --
  132. // [Vcb] -- Supplies the address of the Vcb record being
  133. // initialized.
  134. // [LogRootPrefix] -- Optional Unicode String pointer that
  135. // specifies the relative name of the logical
  136. // root to the highest (org) root.
  137. // [Credentials] -- The credentials associated with this device
  138. // [TargetDeviceObject] -- Supplies the address of the target
  139. // device object to associate with the Vcb record.
  140. //
  141. // Returns: None
  142. //
  143. // Note: If LogRootPrefix is given, its buffer will be "deallocated"
  144. //
  145. //--------------------------------------------------------------------
  146. VOID
  147. DfsInitializeVcb (
  148. IN PIRP_CONTEXT IrpContext,
  149. IN OUT PDFS_VCB Vcb,
  150. IN PUNICODE_STRING LogRootPrefix,
  151. IN PDFS_CREDENTIALS Credentials OPTIONAL,
  152. IN PDEVICE_OBJECT TargetDeviceObject
  153. ) {
  154. DfsDbgTrace(+1, Dbg, "DfsInitializeVcb: Entered\n", 0);
  155. //
  156. // Zero out the memory to remove stale data.
  157. //
  158. RtlZeroMemory( Vcb, sizeof( DFS_VCB ));
  159. //
  160. // Set the proper node type code and node byte size.
  161. //
  162. Vcb->NodeTypeCode = DSFS_NTC_VCB;
  163. Vcb->NodeByteSize = sizeof( DFS_VCB );
  164. //
  165. // Set the prefix string to the input prefix, then `deallocate' the
  166. // input pointer.
  167. //
  168. Vcb->LogRootPrefix = *LogRootPrefix;
  169. RtlZeroMemory( LogRootPrefix, sizeof( UNICODE_STRING ));
  170. //
  171. // Save the credentials
  172. //
  173. Vcb->Credentials = Credentials;
  174. //
  175. // Insert this Vcb record on the DfsData.VcbQueue
  176. //
  177. InsertTailList( &DfsData.VcbQueue, &Vcb->VcbLinks );
  178. DfsDbgTrace(-1, Dbg, "DfsInitializeVcb: Exit\n", 0);
  179. return;
  180. }
  181. //+-------------------------------------------------------------------
  182. //
  183. // Function: DfsCreateFcb, public
  184. //
  185. // Synopsis: This routine allocates, initializes, and inserts a new
  186. // DFS_FCB record into the in-memory data structure.
  187. //
  188. // Arguments: [Vcb] -- Supplies the Vcb to associate the new Fcb under
  189. // [FullName] -- Fully qualified file name for the DFS_FCB
  190. //
  191. // Returns: PDFS_FCB - Pointer to the newly created and initialized Fcb.
  192. //
  193. //--------------------------------------------------------------------
  194. PDFS_FCB
  195. DfsCreateFcb (
  196. IN PIRP_CONTEXT IrpContext,
  197. IN PDFS_VCB Vcb,
  198. IN PUNICODE_STRING FullName OPTIONAL
  199. ) {
  200. PDFS_FCB NewFcb;
  201. ULONG TotalLength;
  202. DfsDbgTrace(+1, Dbg, "DfsCreateFcb: Entered\n", 0);
  203. //
  204. // Allocate a new Fcb and zero it out.
  205. //
  206. TotalLength = sizeof(DFS_FCB);
  207. if (ARGUMENT_PRESENT(FullName))
  208. TotalLength += FullName->Length * sizeof(WCHAR);
  209. NewFcb = (PDFS_FCB) ExAllocatePoolWithTag( NonPagedPool, TotalLength, ' puM' );
  210. if (NewFcb != NULL) {
  211. RtlZeroMemory( NewFcb, sizeof( DFS_FCB ));
  212. //
  213. // Set the proper node type code and node byte size
  214. //
  215. NewFcb->NodeTypeCode = DSFS_NTC_FCB;
  216. NewFcb->NodeByteSize = sizeof( DFS_FCB );
  217. if (ARGUMENT_PRESENT(FullName)) {
  218. NewFcb->FullFileName.Length =
  219. NewFcb->FullFileName.MaximumLength = FullName->Length;
  220. NewFcb->FullFileName.Buffer =
  221. (PWCHAR) ( (PCHAR)NewFcb + sizeof(DFS_FCB) );
  222. RtlMoveMemory( NewFcb->FullFileName.Buffer,
  223. FullName->Buffer,
  224. FullName->Length );
  225. NewFcb->AlternateFileName.Length = 0;
  226. NewFcb->AlternateFileName.MaximumLength = FullName->Length;
  227. NewFcb->AlternateFileName.Buffer =
  228. &NewFcb->FullFileName.Buffer[FullName->Length/sizeof(WCHAR)];
  229. }
  230. NewFcb->Vcb = Vcb;
  231. }
  232. DfsDbgTrace(-1, Dbg, "DfsCreateFcb -> %8lx\n", NewFcb);
  233. return NewFcb;
  234. }
  235. //+-------------------------------------------------------------------
  236. //
  237. // Function: DfsDeleteFcb
  238. //
  239. // Synopsis: This routine removes the Fcb record from DSFS's in-memory data
  240. // structures. It also will remove all associated underlings.
  241. //
  242. // Arguments: [Fcb] -- Supplies the Fcb/Dcb to be removed
  243. //
  244. // Returns: None
  245. //
  246. //--------------------------------------------------------------------
  247. VOID
  248. DfsDeleteFcb_Real (
  249. IN PIRP_CONTEXT IrpContext,
  250. IN PDFS_FCB Fcb
  251. ) {
  252. DfsDbgTrace(+1, Dbg, "DfsDeleteFcb: Fcb = %08lx\n", Fcb);
  253. //
  254. // Zero out the structure and deallocate.
  255. //
  256. ExFreePool( Fcb );
  257. DfsDbgTrace(-1, Dbg, "DfsDeleteFcb: Exit\n", 0);
  258. return;
  259. }
  260. //+-------------------------------------------------------------------
  261. //
  262. // Function: DfsGetLogonId
  263. //
  264. // Synopsis: This routine gets the current LogonID.
  265. // It is assumed that this will be called in the user thread
  266. // or from a thread that is impersonating the user thread.
  267. //
  268. // Arguments: LogonId -- Pointer to LUID where we stuff the LUID
  269. //
  270. // Returns: None
  271. //
  272. //--------------------------------------------------------------------
  273. NTSTATUS
  274. DfsGetLogonId(
  275. PLUID LogonId)
  276. {
  277. SECURITY_SUBJECT_CONTEXT SubjectContext;
  278. SeCaptureSubjectContext(&SubjectContext);
  279. if (SubjectContext.ClientToken != NULL) {
  280. //
  281. // If its impersonating someone that is logged in locally then use
  282. // the local id.
  283. //
  284. SeQueryAuthenticationIdToken(SubjectContext.ClientToken, LogonId);
  285. } else {
  286. //
  287. // Use the processes LogonId
  288. //
  289. SeQueryAuthenticationIdToken(SubjectContext.PrimaryToken, LogonId);
  290. }
  291. SeReleaseSubjectContext(&SubjectContext);
  292. return STATUS_SUCCESS;
  293. }
  294. //+-------------------------------------------------------------------
  295. //
  296. // Function: DfsInitializeDrt, public
  297. //
  298. // Synopsis: This routine initializes a DFS_DEVLESS_ROOT.
  299. //
  300. // Arguments: [Drt] -- Supplies the address of the Vcb record being
  301. // initialized.
  302. // [Name] -- Unicode String pointer that
  303. // specifies the relative name of the logical
  304. // root to the highest (org) root.
  305. // [Credentials] -- The credentials associated with this device
  306. //
  307. // Returns: None
  308. //
  309. //--------------------------------------------------------------------
  310. VOID
  311. DfsInitializeDrt (
  312. IN OUT PDFS_DEVLESS_ROOT Drt,
  313. IN PUNICODE_STRING Name,
  314. IN PDFS_CREDENTIALS Credentials OPTIONAL
  315. ) {
  316. DfsDbgTrace(+1, Dbg, "DfsInitializeDevlessRoot: Entered %x\n", Drt);
  317. //
  318. // Zero out the memory to remove stale data.
  319. //
  320. RtlZeroMemory( Drt, sizeof( DFS_DEVLESS_ROOT ));
  321. //
  322. // Set the proper node type code and node byte size.
  323. //
  324. Drt->NodeTypeCode = DSFS_NTC_DRT;
  325. Drt->NodeByteSize = sizeof( DFS_DEVLESS_ROOT );
  326. Drt->DevlessPath = *Name;
  327. //
  328. // Save the credentials
  329. //
  330. Drt->Credentials = Credentials;
  331. //
  332. // Insert this Drt record on the DfsData.DrtQueue
  333. //
  334. InsertTailList( &DfsData.DrtQueue, &Drt->DrtLinks );
  335. DfsDbgTrace(-1, Dbg, "DfsInitializeDevlessRoot: Exit\n", 0);
  336. return;
  337. }