+NtSetInformationFile()
[reactos.git] / ntoskrnl / cc / pin.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/cc/pin.c
6  * PURPOSE:         Implements cache managers pinning interface
7  * PROGRAMMER:      Hartmut Birr
8  * UPDATE HISTORY:
9  *                  Created 05.10.2001
10  */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <ddk/ntifs.h>
16 #include <internal/mm.h>
17 #include <internal/cc.h>
18 #include <internal/pool.h>
19 #include <internal/io.h>
20 #include <ntos/minmax.h>
21
22 #define NDEBUG
23 #include <internal/debug.h>
24
25 /* GLOBALS *******************************************************************/
26
27 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
28
29 /* FUNCTIONS *****************************************************************/
30
31 typedef struct _INTERNAL_BCB
32 {
33   PUBLIC_BCB PFCB;
34   PCACHE_SEGMENT CacheSegment;
35   BOOLEAN Dirty;
36 } INTERNAL_BCB, *PINTERNAL_BCB;
37
38 BOOLEAN STDCALL
39 CcMapData (IN PFILE_OBJECT FileObject,
40            IN PLARGE_INTEGER FileOffset,
41            IN ULONG Length,
42            IN ULONG Flags,
43            OUT PVOID *pBcb,
44            OUT PVOID *pBuffer)
45 {
46   ULONG ReadOffset;
47   BOOLEAN Valid;
48   PBCB Bcb;
49   PCACHE_SEGMENT CacheSeg;
50   NTSTATUS Status;
51   PINTERNAL_BCB iBcb;
52   ULONG ROffset;
53   
54   DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
55          " pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
56          Length, Wait, pBcb, pBuffer);
57   
58   /* FIXME: 4GB limit! */
59   ReadOffset = FileOffset->QuadPart;
60   Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
61   
62   DPRINT("AllocationSize %d, FileSize %d\n",
63          (ULONG)Bcb->AllocationSize.QuadPart,
64          (ULONG)Bcb->FileSize.QuadPart);
65   
66   if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
67     {
68       return(FALSE);
69     }
70   ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize);
71   Status = CcRosRequestCacheSegment(Bcb,
72                                     ROffset,
73                                     pBuffer,
74                                     &Valid,
75                                     &CacheSeg);
76   if (!NT_SUCCESS(Status))
77     {
78       return(FALSE);
79     }
80   if (!Valid)
81     {
82       if (!Wait)
83         {
84           CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
85           return(FALSE);
86         }
87       if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
88         {
89           CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
90           return(FALSE);
91         }
92     }
93   *pBuffer += ReadOffset % Bcb->CacheSegmentSize;
94   iBcb = ExAllocatePool (NonPagedPool, sizeof(INTERNAL_BCB));
95   if (iBcb == NULL)
96     {
97       CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
98       return FALSE;
99     }
100   iBcb->CacheSegment = CacheSeg;
101   iBcb->Dirty = FALSE;
102   iBcb->PFCB.MappedLength = Length;
103   iBcb->PFCB.MappedFileOffset.QuadPart = FileOffset->QuadPart;
104   *pBcb = (PVOID)iBcb;
105   return(TRUE);
106 }
107
108 #ifndef LIBCAPTIVE
109
110 VOID STDCALL
111 CcUnpinData (IN PVOID Bcb)
112 {
113   PINTERNAL_BCB iBcb = Bcb;
114   CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, 
115                            iBcb->Dirty, FALSE);
116   ExFreePool(iBcb);
117 }
118
119 VOID STDCALL
120 CcSetDirtyPinnedData (IN PVOID Bcb,
121                       IN PLARGE_INTEGER Lsn)
122 {
123    PINTERNAL_BCB iBcb = Bcb;
124 #if 0
125    iBcb->Dirty = TRUE;
126 #else
127    WriteCacheSegment(iBcb->CacheSegment);
128 #endif
129 }
130
131 #endif /* LIBCAPTIVE */