- Silence TCPIP.
[reactos.git] / reactos / 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 *
8 * PROGRAMMERS: Hartmut Birr
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* GLOBALS *******************************************************************/
18
19 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList;
20
21 /* FUNCTIONS *****************************************************************/
22
23 /*
24 * @implemented
25 */
26 BOOLEAN STDCALL
27 CcMapData (IN PFILE_OBJECT FileObject,
28 IN PLARGE_INTEGER FileOffset,
29 IN ULONG Length,
30 IN BOOLEAN Wait,
31 OUT PVOID *pBcb,
32 OUT PVOID *pBuffer)
33 {
34 ULONG ReadOffset;
35 BOOLEAN Valid;
36 PBCB Bcb;
37 PCACHE_SEGMENT CacheSeg;
38 NTSTATUS Status;
39 PINTERNAL_BCB iBcb;
40 ULONG ROffset;
41
42 DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %d, Wait %d,"
43 " pBcb 0x%p, pBuffer 0x%p)\n", FileObject, FileOffset->QuadPart,
44 Length, Wait, pBcb, pBuffer);
45
46 ReadOffset = (ULONG)FileOffset->QuadPart;
47 Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
48 ASSERT(Bcb);
49
50 DPRINT("AllocationSize %I64x, FileSize %I64x\n",
51 Bcb->AllocationSize.QuadPart,
52 Bcb->FileSize.QuadPart);
53
54 if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
55 {
56 return(FALSE);
57 }
58 ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize);
59 Status = CcRosRequestCacheSegment(Bcb,
60 ROffset,
61 pBuffer,
62 &Valid,
63 &CacheSeg);
64 if (!NT_SUCCESS(Status))
65 {
66 return(FALSE);
67 }
68 if (!Valid)
69 {
70 if (!Wait)
71 {
72 CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
73 return(FALSE);
74 }
75 if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
76 {
77 CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
78 return(FALSE);
79 }
80 }
81
82 *pBuffer = (PVOID)((ULONG_PTR)(*pBuffer) + (ReadOffset % Bcb->CacheSegmentSize));
83 iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
84 if (iBcb == NULL)
85 {
86 CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
87 return FALSE;
88 }
89 memset(iBcb, 0, sizeof(INTERNAL_BCB));
90 iBcb->PFCB.NodeTypeCode = 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
91 iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
92 iBcb->PFCB.MappedLength = Length;
93 iBcb->PFCB.MappedFileOffset = *FileOffset;
94 iBcb->CacheSegment = CacheSeg;
95 iBcb->Dirty = FALSE;
96 iBcb->RefCount = 1;
97 *pBcb = (PVOID)iBcb;
98 return(TRUE);
99 }
100
101 /*
102 * @unimplemented
103 */
104 BOOLEAN
105 STDCALL
106 CcPinMappedData (
107 IN PFILE_OBJECT FileObject,
108 IN PLARGE_INTEGER FileOffset,
109 IN ULONG Length,
110 IN ULONG Flags,
111 OUT PVOID * Bcb
112 )
113 {
114 /* no-op for current implementation. */
115 return TRUE;
116 }
117
118 /*
119 * @unimplemented
120 */
121 BOOLEAN
122 STDCALL
123 CcPinRead (
124 IN PFILE_OBJECT FileObject,
125 IN PLARGE_INTEGER FileOffset,
126 IN ULONG Length,
127 IN ULONG Flags,
128 OUT PVOID * Bcb,
129 OUT PVOID * Buffer
130 )
131 {
132 if (CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer))
133 {
134 if (CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
135 return TRUE;
136 else
137 CcUnpinData(Bcb);
138 }
139 return FALSE;
140 }
141
142 /*
143 * @unimplemented
144 */
145 BOOLEAN
146 STDCALL
147 CcPreparePinWrite (
148 IN PFILE_OBJECT FileObject,
149 IN PLARGE_INTEGER FileOffset,
150 IN ULONG Length,
151 IN BOOLEAN Zero,
152 IN ULONG Flags,
153 OUT PVOID * Bcb,
154 OUT PVOID * Buffer
155 )
156 {
157 /*
158 * FIXME: This is function is similar to CcPinRead, but doesn't
159 * read the data if they're not present. Instead it should just
160 * prepare the cache segments and zero them out if Zero == TRUE.
161 *
162 * For now calling CcPinRead is better than returning error or
163 * just having UNIMPLEMENTED here.
164 */
165 return CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer);
166 }
167
168 /*
169 * @implemented
170 */
171 VOID STDCALL
172 CcSetDirtyPinnedData (IN PVOID Bcb,
173 IN PLARGE_INTEGER Lsn)
174 {
175 PINTERNAL_BCB iBcb = Bcb;
176 iBcb->Dirty = TRUE;
177 }
178
179
180 /*
181 * @implemented
182 */
183 VOID STDCALL
184 CcUnpinData (IN PVOID Bcb)
185 {
186 PINTERNAL_BCB iBcb = Bcb;
187 CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE,
188 iBcb->Dirty, FALSE);
189 if (--iBcb->RefCount == 0)
190 {
191 ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
192 }
193 }
194
195 /*
196 * @unimplemented
197 */
198 VOID
199 STDCALL
200 CcUnpinDataForThread (
201 IN PVOID Bcb,
202 IN ERESOURCE_THREAD ResourceThreadId
203 )
204 {
205 UNIMPLEMENTED;
206 }
207
208 /*
209 * @implemented
210 */
211 VOID
212 STDCALL
213 CcRepinBcb (
214 IN PVOID Bcb
215 )
216 {
217 PINTERNAL_BCB iBcb = Bcb;
218 iBcb->RefCount++;
219 }
220
221 /*
222 * @unimplemented
223 */
224 VOID
225 STDCALL
226 CcUnpinRepinnedBcb (
227 IN PVOID Bcb,
228 IN BOOLEAN WriteThrough,
229 IN PIO_STATUS_BLOCK IoStatus
230 )
231 {
232 PINTERNAL_BCB iBcb = Bcb;
233
234 if (--iBcb->RefCount == 0)
235 {
236 IoStatus->Information = 0;
237 if (WriteThrough)
238 {
239 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&iBcb->CacheSegment->Lock);
240 if (iBcb->CacheSegment->Dirty)
241 {
242 IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
243 }
244 else
245 {
246 IoStatus->Status = STATUS_SUCCESS;
247 }
248 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&iBcb->CacheSegment->Lock);
249 }
250 else
251 {
252 IoStatus->Status = STATUS_SUCCESS;
253 }
254
255 ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
256 }
257 }