Leaked source code of windows server 2003
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.

346 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. FilObSup.c
  5. Abstract:
  6. This module implements the Ntfs File object support routines.
  7. Author:
  8. Gary Kimura [GaryKi] 21-May-1991
  9. Revision History:
  10. --*/
  11. #include "NtfsProc.h"
  12. //
  13. // The debug trace level
  14. //
  15. #define Dbg (DEBUG_TRACE_FILOBSUP)
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGE, NtfsSetFileObject)
  18. #endif
  19. VOID
  20. NtfsSetFileObject (
  21. IN PFILE_OBJECT FileObject,
  22. IN TYPE_OF_OPEN TypeOfOpen,
  23. IN PSCB Scb,
  24. IN PCCB Ccb OPTIONAL
  25. )
  26. /*++
  27. Routine Description:
  28. This routine sets the file system pointers within the file object
  29. Arguments:
  30. FileObject - Supplies a pointer to the file object being modified.
  31. TypeOfOpen - Supplies the type of open denoted by the file object.
  32. This is only used by this procedure for sanity checking.
  33. Scb - Supplies a pointer to Scb for the file object.
  34. Ccb - Optionally supplies a pointer to a ccb
  35. Return Value:
  36. None.
  37. --*/
  38. {
  39. ASSERT_FILE_OBJECT( FileObject );
  40. ASSERT_SCB( Scb );
  41. ASSERT_OPTIONAL_CCB( Ccb );
  42. PAGED_CODE();
  43. DebugTrace( +1, Dbg, ("NtfsSetFileObject, FileObject = %08lx\n", FileObject) );
  44. //
  45. // Load up the FileObject fields.
  46. //
  47. FileObject->FsContext = Scb;
  48. FileObject->FsContext2 = Ccb;
  49. FileObject->Vpb = Scb->Vcb->Vpb;
  50. //
  51. // Typically the I/O manager has already set this flag correctly. The notable
  52. // exception is when the user did an open by file ID of file record 3, so
  53. // we're doing a DASD open, but the I/O manager didn't notice, since it only
  54. // checks for a zero length filename.
  55. //
  56. if (TypeOfOpen == UserVolumeOpen) {
  57. SetFlag( FileObject->Flags, FO_VOLUME_OPEN );
  58. }
  59. //
  60. // Now store TypeOfOpen if there is a Ccb
  61. //
  62. ASSERT((Ccb != NULL) || (TypeOfOpen == StreamFileOpen) || (TypeOfOpen == UnopenedFileObject));
  63. if (Ccb != NULL) {
  64. Ccb->TypeOfOpen = (UCHAR)TypeOfOpen;
  65. }
  66. //
  67. // If this file has the temporary attribute bit set, don't lazy
  68. // write it unless absolutely necessary.
  69. //
  70. if (FlagOn( Scb->ScbState, SCB_STATE_TEMPORARY )) {
  71. SetFlag( FileObject->Flags, FO_TEMPORARY_FILE );
  72. }
  73. //
  74. // And return to our caller
  75. //
  76. DebugTrace( -1, Dbg, ("NtfsSetFileObject -> VOID\n") );
  77. return;
  78. }
  79. //
  80. // Local support routine
  81. //
  82. VOID
  83. NtfsUpdateScbFromFileObject (
  84. IN PIRP_CONTEXT IrpContext,
  85. IN PFILE_OBJECT FileObject,
  86. IN PSCB Scb,
  87. IN BOOLEAN CheckTimeStamps
  88. )
  89. /*++
  90. Routine Description:
  91. This routine is called to update the Scb/Fcb to reflect the changes to
  92. a file through the fast io path. It only called with a file object which
  93. represents a user's handle.
  94. Arguments:
  95. FileObject - This is the file object used in the fast io path.
  96. Scb - This is the Scb for this stream.
  97. CheckTimeStamps - Indicates whether we want to update the time stamps from the
  98. fast io flags as well. This will be TRUE if our caller will update the standard information,
  99. attribute header and duplicate info. FALSE if only the attribute header and duplicate info.
  100. The latter case is the valid data length callback from the cache manager.
  101. Return Value:
  102. None.
  103. --*/
  104. {
  105. PFCB Fcb = Scb->Fcb;
  106. ULONG CcbFlags;
  107. ULONG ScbFlags = 0;
  108. LONGLONG CurrentTime;
  109. //
  110. // If the size of the main data stream is not part of the Fcb then update it
  111. // now and set the correct Fcb flag.
  112. //
  113. if (FlagOn( Scb->ScbState, SCB_STATE_UNNAMED_DATA )) {
  114. if (Fcb->Info.FileSize != Scb->Header.FileSize.QuadPart) {
  115. Fcb->Info.FileSize = Scb->Header.FileSize.QuadPart;
  116. SetFlag( Fcb->InfoFlags, FCB_INFO_CHANGED_FILE_SIZE );
  117. }
  118. if (Fcb->Info.AllocatedLength != Scb->TotalAllocated) {
  119. Fcb->Info.AllocatedLength = Scb->TotalAllocated;
  120. SetFlag( Fcb->InfoFlags, FCB_INFO_CHANGED_ALLOC_SIZE );
  121. }
  122. if (FlagOn( FileObject->Flags, FO_FILE_SIZE_CHANGED )) {
  123. SetFlag( ScbFlags, SCB_STATE_CHECK_ATTRIBUTE_SIZE );
  124. }
  125. //
  126. // Remember to update the size in the attribute header for named streams as well.
  127. //
  128. } else if (FlagOn( FileObject->Flags, FO_FILE_SIZE_CHANGED )) {
  129. SetFlag( ScbFlags, SCB_STATE_NOTIFY_RESIZE_STREAM | SCB_STATE_CHECK_ATTRIBUTE_SIZE );
  130. }
  131. ClearFlag( FileObject->Flags, FO_FILE_SIZE_CHANGED );
  132. //
  133. // Check whether to update the time stamps if our caller requested it.
  134. //
  135. if (CheckTimeStamps && !FlagOn( FileObject->Flags, FO_CLEANUP_COMPLETE )) {
  136. BOOLEAN UpdateLastAccess = FALSE;
  137. BOOLEAN UpdateLastChange = FALSE;
  138. BOOLEAN UpdateLastModify = FALSE;
  139. BOOLEAN SetArchive = TRUE;
  140. //
  141. // Copy the Ccb flags to a local variable. Then we won't have to test
  142. // for the existence of the Ccb each time.
  143. //
  144. CcbFlags = 0;
  145. //
  146. // Capture the real flags if present and clear them since we will update the Scb/Fcb.
  147. //
  148. if (FileObject->FsContext2 != NULL) {
  149. CcbFlags = ((PCCB) FileObject->FsContext2)->Flags;
  150. ClearFlag( ((PCCB) FileObject->FsContext2)->Flags,
  151. (CCB_FLAG_UPDATE_LAST_MODIFY |
  152. CCB_FLAG_UPDATE_LAST_CHANGE |
  153. CCB_FLAG_SET_ARCHIVE) );
  154. }
  155. NtfsGetCurrentTime( IrpContext, CurrentTime );
  156. //
  157. // If there was a write to the file then update the last change, last access
  158. // and last write and the archive bit.
  159. //
  160. if (FlagOn( FileObject->Flags, FO_FILE_MODIFIED )) {
  161. UpdateLastModify =
  162. UpdateLastAccess =
  163. UpdateLastChange = TRUE;
  164. //
  165. // Otherwise test each of the individual bits in the file object and
  166. // Ccb.
  167. //
  168. } else {
  169. if (FlagOn( FileObject->Flags, FO_FILE_FAST_IO_READ )) {
  170. UpdateLastAccess = TRUE;
  171. }
  172. if (FlagOn( CcbFlags, CCB_FLAG_UPDATE_LAST_CHANGE )) {
  173. UpdateLastChange = TRUE;
  174. if (FlagOn( CcbFlags, CCB_FLAG_UPDATE_LAST_MODIFY )) {
  175. UpdateLastModify = TRUE;
  176. }
  177. if (!FlagOn( CcbFlags, CCB_FLAG_SET_ARCHIVE )) {
  178. SetArchive = FALSE;
  179. }
  180. }
  181. }
  182. //
  183. // Now set the correct Fcb bits.
  184. //
  185. if (UpdateLastChange) {
  186. if (SetArchive) {
  187. ASSERTMSG( "conflict with flush",
  188. ExIsResourceAcquiredSharedLite( Fcb->Resource ) ||
  189. (Fcb->PagingIoResource != NULL &&
  190. ExIsResourceAcquiredSharedLite( Fcb->PagingIoResource )));
  191. SetFlag( Fcb->Info.FileAttributes, FILE_ATTRIBUTE_ARCHIVE );
  192. SetFlag( Fcb->InfoFlags, FCB_INFO_CHANGED_FILE_ATTR );
  193. SetFlag( Fcb->FcbState, FCB_STATE_UPDATE_STD_INFO );
  194. }
  195. if (!FlagOn( CcbFlags, CCB_FLAG_USER_SET_LAST_CHANGE_TIME )) {
  196. Fcb->Info.LastChangeTime = CurrentTime;
  197. SetFlag( Fcb->InfoFlags, FCB_INFO_CHANGED_LAST_CHANGE );
  198. SetFlag( Fcb->FcbState, FCB_STATE_UPDATE_STD_INFO );
  199. }
  200. if (UpdateLastModify) {
  201. //
  202. // Remember a change to a named data stream.
  203. //
  204. if (!FlagOn( Scb->ScbState, SCB_STATE_UNNAMED_DATA ) &&
  205. (Scb->AttributeTypeCode == $DATA)) {
  206. SetFlag( ScbFlags, SCB_STATE_NOTIFY_MODIFY_STREAM );
  207. }
  208. if (!FlagOn( CcbFlags, CCB_FLAG_USER_SET_LAST_MOD_TIME )) {
  209. Fcb->Info.LastModificationTime = CurrentTime;
  210. SetFlag( Fcb->InfoFlags, FCB_INFO_CHANGED_LAST_MOD );
  211. SetFlag( Fcb->FcbState, FCB_STATE_UPDATE_STD_INFO );
  212. }
  213. }
  214. }
  215. if (UpdateLastAccess &&
  216. !FlagOn( CcbFlags, CCB_FLAG_USER_SET_LAST_ACCESS_TIME ) &&
  217. !FlagOn( NtfsData.Flags, NTFS_FLAGS_DISABLE_LAST_ACCESS )) {
  218. Fcb->CurrentLastAccess = CurrentTime;
  219. SetFlag( Fcb->InfoFlags, FCB_INFO_UPDATE_LAST_ACCESS );
  220. }
  221. //
  222. // Clear all of the fast io flags in the file object.
  223. //
  224. ClearFlag( FileObject->Flags, FO_FILE_MODIFIED | FO_FILE_FAST_IO_READ );
  225. }
  226. //
  227. // Now store the Scb flags into the Scb.
  228. //
  229. if (ScbFlags) {
  230. NtfsAcquireFsrtlHeader( Scb );
  231. SetFlag( Scb->ScbState, ScbFlags );
  232. NtfsReleaseFsrtlHeader( Scb );
  233. }
  234. return;
  235. }