[EXT2] Upgrade to 0.69
[reactos.git] / drivers / filesystems / ext2 / src / fastio.c
1 /*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: fastio.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "ext2fs.h"
13
14 /* GLOBALS ***************************************************************/
15
16 extern PEXT2_GLOBAL Ext2Global;
17
18 /* DEFINITIONS *************************************************************/
19
20 #define FASTIO_DEBUG_LEVEL DL_NVR
21
22
23 #ifdef ALLOC_PRAGMA
24
25 #pragma alloc_text(PAGE, Ext2FastIoRead)
26 #pragma alloc_text(PAGE, Ext2FastIoWrite)
27 #pragma alloc_text(PAGE, Ext2FastIoCheckIfPossible)
28 #pragma alloc_text(PAGE, Ext2FastIoQueryBasicInfo)
29 #pragma alloc_text(PAGE, Ext2FastIoQueryStandardInfo)
30 #pragma alloc_text(PAGE, Ext2FastIoQueryNetworkOpenInfo)
31 #pragma alloc_text(PAGE, Ext2FastIoLock)
32 #pragma alloc_text(PAGE, Ext2FastIoUnlockSingle)
33 #pragma alloc_text(PAGE, Ext2FastIoUnlockAll)
34 #pragma alloc_text(PAGE, Ext2FastIoUnlockAll)
35 #endif
36
37 FAST_IO_POSSIBLE
38 Ext2IsFastIoPossible(
39 IN PEXT2_FCB Fcb
40 )
41 {
42 FAST_IO_POSSIBLE IsPossible = FastIoIsNotPossible;
43
44 if (!Fcb || !FsRtlOplockIsFastIoPossible(&Fcb->Oplock))
45 return IsPossible;
46
47 IsPossible = FastIoIsQuestionable;
48
49 if (!FsRtlAreThereCurrentFileLocks(&Fcb->FileLockAnchor)) {
50 if (!IsVcbReadOnly(Fcb->Vcb) && !FlagOn(Fcb->Vcb->Flags, VCB_VOLUME_LOCKED)) {
51 IsPossible = FastIoIsPossible;
52 }
53 }
54
55 return IsPossible;
56 }
57
58
59 BOOLEAN NTAPI
60 Ext2FastIoCheckIfPossible (
61 IN PFILE_OBJECT FileObject,
62 IN PLARGE_INTEGER FileOffset,
63 IN ULONG Length,
64 IN BOOLEAN Wait,
65 IN ULONG LockKey,
66 IN BOOLEAN CheckForReadOperation,
67 OUT PIO_STATUS_BLOCK IoStatus,
68 IN PDEVICE_OBJECT DeviceObject
69 )
70 {
71 BOOLEAN bPossible = FastIoIsNotPossible;
72 PEXT2_FCB Fcb;
73 PEXT2_CCB Ccb;
74 LARGE_INTEGER lLength;
75
76 lLength.QuadPart = Length;
77
78 _SEH2_TRY {
79
80 FsRtlEnterFileSystem();
81
82 _SEH2_TRY {
83
84 if (IsExt2FsDevice(DeviceObject)) {
85 _SEH2_LEAVE;
86 }
87
88 Fcb = (PEXT2_FCB) FileObject->FsContext;
89 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
90 _SEH2_LEAVE;
91 }
92
93 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
94 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
95
96 /* do nothing if target fie was deleted */
97 if (FlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
98 _SEH2_LEAVE;
99 }
100
101 if (IsDirectory(Fcb)) {
102 _SEH2_LEAVE;
103 }
104
105 Ccb = (PEXT2_CCB) FileObject->FsContext2;
106 if (Ccb == NULL) {
107 _SEH2_LEAVE;
108 }
109
110 if (CheckForReadOperation) {
111
112 bPossible = FsRtlFastCheckLockForRead(
113 &Fcb->FileLockAnchor,
114 FileOffset,
115 &lLength,
116 LockKey,
117 FileObject,
118 PsGetCurrentProcess());
119
120 } else {
121
122 if (!IsVcbReadOnly(Fcb->Vcb)) {
123 bPossible = FsRtlFastCheckLockForWrite(
124 &Fcb->FileLockAnchor,
125 FileOffset,
126 &lLength,
127 LockKey,
128 FileObject,
129 PsGetCurrentProcess());
130 }
131 }
132
133 #if EXT2_DEBUG
134 DEBUG(DL_INF, ("Ext2FastIIOCheckPossible: %s %s %wZ\n",
135 Ext2GetCurrentProcessName(),
136 "FASTIO_CHECK_IF_POSSIBLE",
137 &Fcb->Mcb->FullName
138 ));
139
140 DEBUG(DL_INF, (
141 "Ext2FastIIOCheckPossible: Offset: %I64xg Length: %xh Key: %u %s %s\n",
142 FileOffset->QuadPart,
143 Length,
144 LockKey,
145 (CheckForReadOperation ? "CheckForReadOperation:" :
146 "CheckForWriteOperation:"),
147 (bPossible ? "Succeeded" : "Failed")));
148 #endif
149
150 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
151 bPossible = FastIoIsNotPossible;
152 } _SEH2_END;
153
154 } _SEH2_FINALLY {
155
156 FsRtlExitFileSystem();
157 } _SEH2_END;
158
159 return bPossible;
160 }
161
162
163 BOOLEAN NTAPI
164 Ext2FastIoRead (IN PFILE_OBJECT FileObject,
165 IN PLARGE_INTEGER FileOffset,
166 IN ULONG Length,
167 IN BOOLEAN Wait,
168 IN ULONG LockKey,
169 OUT PVOID Buffer,
170 OUT PIO_STATUS_BLOCK IoStatus,
171 IN PDEVICE_OBJECT DeviceObject)
172 {
173 PEXT2_FCB Fcb;
174 BOOLEAN Status = FALSE;
175
176 Fcb = (PEXT2_FCB) FileObject->FsContext;
177 if (Fcb == NULL) {
178 return FALSE;
179 }
180
181 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
182 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
183
184 Status = FsRtlCopyRead (
185 FileObject, FileOffset, Length, Wait,
186 LockKey, Buffer, IoStatus, DeviceObject);
187
188 DEBUG(DL_IO, ("Ext2FastIoRead: %wZ Offset: %I64xh Length: %xh Key: %u Status: %d\n",
189 &Fcb->Mcb->ShortName, FileOffset->QuadPart, Length, LockKey, Status));
190
191 return Status;
192 }
193
194 BOOLEAN NTAPI
195 Ext2FastIoWrite (
196 IN PFILE_OBJECT FileObject,
197 IN PLARGE_INTEGER FileOffset,
198 IN ULONG Length,
199 IN BOOLEAN Wait,
200 IN ULONG LockKey,
201 OUT PVOID Buffer,
202 OUT PIO_STATUS_BLOCK IoStatus,
203 IN PDEVICE_OBJECT DeviceObject)
204 {
205 PEXT2_FCB Fcb = NULL;
206 BOOLEAN Status = FALSE;
207 BOOLEAN Locked = FALSE;
208
209 Fcb = (PEXT2_FCB) FileObject->FsContext;
210 if (Fcb == NULL)
211 return FALSE;
212
213 _SEH2_TRY {
214
215 FsRtlEnterFileSystem();
216
217 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
218 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
219
220 if (IsVcbReadOnly(Fcb->Vcb)) {
221 _SEH2_LEAVE;
222 }
223
224 if (!ExAcquireResourceSharedLite(Fcb->Header.Resource, Wait)) {
225 _SEH2_LEAVE;
226 }
227 Locked = TRUE;
228
229 if (IsWritingToEof(*FileOffset) ||
230 Fcb->Header.ValidDataLength.QuadPart < FileOffset->QuadPart + Length ||
231 Fcb->Header.FileSize.QuadPart < FileOffset->QuadPart + Length ) {
232 Status = FALSE;
233 _SEH2_LEAVE;
234 }
235
236 if (Locked) {
237 ExReleaseResourceLite(Fcb->Header.Resource);
238 Locked = FALSE;
239 }
240
241 Status = FsRtlCopyWrite(FileObject, FileOffset, Length, Wait,
242 LockKey, Buffer, IoStatus, DeviceObject);
243 if (Status) {
244 if (IoStatus)
245 Length = (ULONG)IoStatus->Information;
246 }
247
248 } _SEH2_FINALLY {
249
250 if (Locked) {
251 ExReleaseResourceLite(Fcb->Header.Resource);
252 }
253
254 FsRtlExitFileSystem();
255 } _SEH2_END;
256
257 DEBUG(DL_IO, ("Ext2FastIoWrite: %wZ Offset: %I64xh Length: %xh Key: %xh Status=%d\n",
258 &Fcb->Mcb->ShortName, FileOffset->QuadPart, Length, LockKey, Status));
259
260 return Status;
261 }
262
263 BOOLEAN NTAPI
264 Ext2FastIoQueryBasicInfo (
265 IN PFILE_OBJECT FileObject,
266 IN BOOLEAN Wait,
267 OUT PFILE_BASIC_INFORMATION Buffer,
268 OUT PIO_STATUS_BLOCK IoStatus,
269 IN PDEVICE_OBJECT DeviceObject)
270 {
271 PEXT2_FCB Fcb = NULL;
272 PEXT2_CCB Ccb = NULL;
273 PEXT2_MCB Mcb = NULL;
274 BOOLEAN Status = FALSE;
275 BOOLEAN FcbMainResourceAcquired = FALSE;
276
277 _SEH2_TRY {
278
279 FsRtlEnterFileSystem();
280
281 _SEH2_TRY {
282
283 if (IsExt2FsDevice(DeviceObject)) {
284 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
285 _SEH2_LEAVE;
286 }
287
288 Fcb = (PEXT2_FCB) FileObject->FsContext;
289 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
290 IoStatus->Status = STATUS_INVALID_PARAMETER;
291 _SEH2_LEAVE;
292 }
293 Ccb = (PEXT2_CCB) FileObject->FsContext2;
294 Mcb = Fcb->Mcb;
295 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
296 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
297 #if EXT2_DEBUG
298 DEBUG(DL_INF, (
299 "Ext2FastIoQueryBasicInfo: %s %s %wZ\n",
300 Ext2GetCurrentProcessName(),
301 "FASTIO_QUERY_BASIC_INFO",
302 &Fcb->Mcb->FullName
303 ));
304 #endif
305 if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) {
306 if (!ExAcquireResourceSharedLite(
307 &Fcb->MainResource,
308 Wait)) {
309 _SEH2_LEAVE;
310 }
311 FcbMainResourceAcquired = TRUE;
312 }
313
314 RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));
315
316 /*
317 typedef struct _FILE_BASIC_INFORMATION {
318 LARGE_INTEGER CreationTime;
319 LARGE_INTEGER LastAccessTime;
320 LARGE_INTEGER LastWriteTime;
321 LARGE_INTEGER ChangeTime;
322 ULONG FileAttributes;
323 } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
324 */
325
326 Buffer->CreationTime = Mcb->CreationTime;
327 Buffer->LastAccessTime = Mcb->LastAccessTime;
328 Buffer->LastWriteTime = Mcb->LastWriteTime;
329 Buffer->ChangeTime = Mcb->ChangeTime;
330 Buffer->FileAttributes = Mcb->FileAttr;
331 if (Buffer->FileAttributes == 0) {
332 Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
333 }
334
335 IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
336 IoStatus->Status = STATUS_SUCCESS;
337
338 Status = TRUE;
339
340 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
341 IoStatus->Status = _SEH2_GetExceptionCode();
342 } _SEH2_END;
343
344 } _SEH2_FINALLY {
345
346 if (FcbMainResourceAcquired) {
347 ExReleaseResourceLite(&Fcb->MainResource);
348 }
349
350 FsRtlExitFileSystem();
351 } _SEH2_END;
352
353 #if EXT2_DEBUG
354
355 if (Status == FALSE) {
356
357 DEBUG(DL_ERR, ("Ext2FastIoQueryBasicInfo: %s %s Status: FALSE ***\n",
358 Ext2GetCurrentProcessName(),
359 "FASTIO_QUERY_BASIC_INFO"));
360
361 } else if (IoStatus->Status != STATUS_SUCCESS) {
362
363 DEBUG(DL_ERR, (
364 "Ext2FastIoQueryBasicInfo: %s %s Status: %#x ***\n",
365 Ext2FastIoQueryBasicInfo,
366 "FASTIO_QUERY_BASIC_INFO",
367 IoStatus->Status
368 ));
369 }
370 #endif
371
372 return Status;
373 }
374
375 BOOLEAN NTAPI
376 Ext2FastIoQueryStandardInfo (
377 IN PFILE_OBJECT FileObject,
378 IN BOOLEAN Wait,
379 OUT PFILE_STANDARD_INFORMATION Buffer,
380 OUT PIO_STATUS_BLOCK IoStatus,
381 IN PDEVICE_OBJECT DeviceObject
382 )
383 {
384
385 BOOLEAN Status = FALSE;
386 PEXT2_VCB Vcb = NULL;
387 PEXT2_FCB Fcb = NULL;
388 BOOLEAN FcbMainResourceAcquired = FALSE;
389
390 _SEH2_TRY {
391
392 FsRtlEnterFileSystem();
393
394 _SEH2_TRY {
395
396 if (IsExt2FsDevice(DeviceObject)) {
397 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
398 _SEH2_LEAVE;
399 }
400
401 Fcb = (PEXT2_FCB) FileObject->FsContext;
402 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
403 IoStatus->Status = STATUS_INVALID_PARAMETER;
404 _SEH2_LEAVE;
405 }
406
407 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
408 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
409
410 #if EXT2_DEBUG
411 DEBUG(DL_INF, (
412 "Ext2FastIoQueryStandardInfo: %s %s %wZ\n",
413 Ext2GetCurrentProcessName(),
414 "FASTIO_QUERY_STANDARD_INFO",
415 &Fcb->Mcb->FullName ));
416 #endif
417 Vcb = Fcb->Vcb;
418
419 if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) {
420 if (!ExAcquireResourceSharedLite(
421 &Fcb->MainResource,
422 Wait )) {
423 _SEH2_LEAVE;
424 }
425 FcbMainResourceAcquired = TRUE;
426 }
427
428 RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION));
429
430 /*
431 typedef struct _FILE_STANDARD_INFORMATION {
432 LARGE_INTEGER AllocationSize;
433 LARGE_INTEGER EndOfFile;
434 ULONG NumberOfLinks;
435 BOOLEAN DeletePending;
436 BOOLEAN Directory;
437 } FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
438 */
439
440 Buffer->NumberOfLinks = Fcb->Inode->i_nlink;
441 Buffer->DeletePending = IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING);
442
443 if (IsDirectory(Fcb)) {
444 Buffer->Directory = IsDirectory(Fcb);
445 Buffer->AllocationSize.QuadPart = 0;
446 Buffer->EndOfFile.QuadPart = 0;
447 } else {
448 Buffer->Directory = FALSE;
449 Buffer->AllocationSize = Fcb->Header.AllocationSize;
450 Buffer->EndOfFile = Fcb->Header.FileSize;
451 }
452
453 IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
454 IoStatus->Status = STATUS_SUCCESS;
455 #if EXT2_DEBUG
456 DEBUG(DL_INF, ( "Ext2FastIoQueryStandInfo: AllocatieonSize = %I64xh FileSize = %I64xh\n",
457 Buffer->AllocationSize.QuadPart, Buffer->EndOfFile.QuadPart));
458 #endif
459 Status = TRUE;
460
461 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
462 IoStatus->Status = _SEH2_GetExceptionCode();
463 } _SEH2_END;
464
465 } _SEH2_FINALLY {
466
467 if (FcbMainResourceAcquired) {
468 ExReleaseResourceLite(&Fcb->MainResource);
469 }
470
471 FsRtlExitFileSystem();
472 } _SEH2_END;
473
474 #if EXT2_DEBUG
475 if (Status == FALSE) {
476 DEBUG(DL_INF, (
477 "Ext2FastIoQueryStandardInfo: %s %s Status: FALSE ***\n",
478 Ext2GetCurrentProcessName(),
479 "FASTIO_QUERY_STANDARD_INFO" ));
480 } else if (IoStatus->Status != STATUS_SUCCESS) {
481 DEBUG(DL_INF, (
482 "Ext2FastIoQueryStandardInfo: %s %s Status: %#x ***\n",
483 Ext2GetCurrentProcessName(),
484 "FASTIO_QUERY_STANDARD_INFO",
485 IoStatus->Status ));
486 }
487 #endif
488
489 return Status;
490 }
491
492 BOOLEAN NTAPI
493 Ext2FastIoLock (
494 IN PFILE_OBJECT FileObject,
495 IN PLARGE_INTEGER FileOffset,
496 IN PLARGE_INTEGER Length,
497 IN PEPROCESS Process,
498 IN ULONG Key,
499 IN BOOLEAN FailImmediately,
500 IN BOOLEAN ExclusiveLock,
501 OUT PIO_STATUS_BLOCK IoStatus,
502 IN PDEVICE_OBJECT DeviceObject
503 )
504 {
505 BOOLEAN Status = FALSE;
506 PEXT2_FCB Fcb;
507
508 _SEH2_TRY {
509
510 FsRtlEnterFileSystem();
511
512 _SEH2_TRY {
513
514 if (IsExt2FsDevice(DeviceObject)) {
515 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
516 _SEH2_LEAVE;
517 }
518
519 Fcb = (PEXT2_FCB) FileObject->FsContext;
520 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
521 IoStatus->Status = STATUS_INVALID_PARAMETER;
522 _SEH2_LEAVE;
523 }
524
525 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
526 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
527
528 if (IsDirectory(Fcb)) {
529 DbgBreak();
530 IoStatus->Status = STATUS_INVALID_PARAMETER;
531 _SEH2_LEAVE;
532 }
533 #if EXT2_DEBUG
534 DEBUG(DL_INF, (
535 "Ext2FastIoLock: %s %s %wZ\n",
536 Ext2GetCurrentProcessName(),
537 "FASTIO_LOCK",
538 &Fcb->Mcb->FullName ));
539
540 DEBUG(DL_INF, (
541 "Ext2FastIoLock: Offset: %I64xh Length: %I64xh Key: %u %s%s\n",
542 FileOffset->QuadPart,
543 Length->QuadPart,
544 Key,
545 (FailImmediately ? "FailImmediately " : ""),
546 (ExclusiveLock ? "ExclusiveLock " : "") ));
547 #endif
548
549 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) {
550 _SEH2_LEAVE;
551 }
552
553 Status = FsRtlFastLock(
554 &Fcb->FileLockAnchor,
555 FileObject,
556 FileOffset,
557 Length,
558 Process,
559 Key,
560 FailImmediately,
561 ExclusiveLock,
562 IoStatus,
563 NULL,
564 FALSE);
565
566 if (Status) {
567 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
568 }
569
570 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
571 IoStatus->Status = _SEH2_GetExceptionCode();
572 } _SEH2_END;
573
574 } _SEH2_FINALLY {
575
576 FsRtlExitFileSystem();
577 } _SEH2_END;
578
579 #if EXT2_DEBUG
580 if (Status == FALSE) {
581 DEBUG(DL_ERR, (
582 "Ext2FastIoLock: %s %s *** Status: FALSE ***\n",
583 (PUCHAR) Process + ProcessNameOffset,
584 "FASTIO_LOCK"
585 ));
586 } else if (IoStatus->Status != STATUS_SUCCESS) {
587 DEBUG(DL_ERR, (
588 "Ext2FastIoLock: %s %s *** Status: %s (%#x) ***\n",
589 (PUCHAR) Process + ProcessNameOffset,
590 "FASTIO_LOCK",
591 Ext2NtStatusToString(IoStatus->Status),
592 IoStatus->Status
593 ));
594 }
595 #endif
596
597 return Status;
598 }
599
600 BOOLEAN NTAPI
601 Ext2FastIoUnlockSingle (
602 IN PFILE_OBJECT FileObject,
603 IN PLARGE_INTEGER FileOffset,
604 IN PLARGE_INTEGER Length,
605 IN PEPROCESS Process,
606 IN ULONG Key,
607 OUT PIO_STATUS_BLOCK IoStatus,
608 IN PDEVICE_OBJECT DeviceObject
609 )
610 {
611 BOOLEAN Status = FALSE;
612 PEXT2_FCB Fcb;
613
614 _SEH2_TRY {
615
616 FsRtlEnterFileSystem();
617
618 _SEH2_TRY {
619
620 if (IsExt2FsDevice(DeviceObject)) {
621 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
622 _SEH2_LEAVE;
623 }
624
625 Fcb = (PEXT2_FCB) FileObject->FsContext;
626 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
627 DbgBreak();
628 IoStatus->Status = STATUS_INVALID_PARAMETER;
629 _SEH2_LEAVE;
630 }
631
632 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
633 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
634
635 if (IsDirectory(Fcb)) {
636 DbgBreak();
637 IoStatus->Status = STATUS_INVALID_PARAMETER;
638 _SEH2_LEAVE;
639 }
640
641 #if EXT2_DEBUG
642 DEBUG(DL_INF, (
643 "Ext2FastIoUnlockSingle: %s %s %wZ\n",
644 (PUCHAR) Process + ProcessNameOffset,
645 "FASTIO_UNLOCK_SINGLE",
646 &Fcb->Mcb->FullName ));
647
648 DEBUG(DL_INF, (
649 "Ext2FastIoUnlockSingle: Offset: %I64xh Length: %I64xh Key: %u\n",
650 FileOffset->QuadPart,
651 Length->QuadPart,
652 Key ));
653 #endif
654
655 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) {
656 _SEH2_LEAVE;
657 }
658
659 IoStatus->Status = FsRtlFastUnlockSingle(
660 &Fcb->FileLockAnchor,
661 FileObject,
662 FileOffset,
663 Length,
664 Process,
665 Key,
666 NULL,
667 FALSE);
668
669 IoStatus->Information = 0;
670 Status = TRUE;
671
672 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
673
674 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
675 IoStatus->Status = _SEH2_GetExceptionCode();
676 } _SEH2_END;
677
678 } _SEH2_FINALLY {
679
680 FsRtlExitFileSystem();
681 } _SEH2_END;
682
683 #if EXT2_DEBUG
684 if (Status == FALSE) {
685
686 DEBUG(DL_ERR, (
687 "Ext2FastIoUnlockSingle: %s %s *** Status: FALSE ***\n",
688 (PUCHAR) Process + ProcessNameOffset,
689 "FASTIO_UNLOCK_SINGLE" ));
690 } else if (IoStatus->Status != STATUS_SUCCESS) {
691 DEBUG(DL_ERR, (
692 "Ext2FastIoUnlockSingle: %s %s *** Status: %s (%#x) ***\n",
693 (PUCHAR) Process + ProcessNameOffset,
694 "FASTIO_UNLOCK_SINGLE",
695 Ext2NtStatusToString(IoStatus->Status),
696 IoStatus->Status ));
697 }
698 #endif
699
700 return Status;
701 }
702
703 BOOLEAN NTAPI
704 Ext2FastIoUnlockAll (
705 IN PFILE_OBJECT FileObject,
706 IN PEPROCESS Process,
707 OUT PIO_STATUS_BLOCK IoStatus,
708 IN PDEVICE_OBJECT DeviceObject)
709 {
710 BOOLEAN Status = FALSE;
711 PEXT2_FCB Fcb;
712
713 _SEH2_TRY {
714
715 FsRtlEnterFileSystem();
716
717 _SEH2_TRY {
718
719 if (IsExt2FsDevice(DeviceObject)) {
720 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
721 _SEH2_LEAVE;
722 }
723
724 Fcb = (PEXT2_FCB) FileObject->FsContext;
725 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
726 DbgBreak();
727 IoStatus->Status = STATUS_INVALID_PARAMETER;
728 _SEH2_LEAVE;
729 }
730
731 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
732 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
733
734 if (IsDirectory(Fcb)) {
735 DbgBreak();
736 IoStatus->Status = STATUS_INVALID_PARAMETER;
737 _SEH2_LEAVE;
738 }
739 #if EXT2_DEBUG
740 DEBUG(DL_INF, (
741 "Ext2FastIoUnlockSingle: %s %s %wZ\n",
742 (PUCHAR) Process + ProcessNameOffset,
743 "FASTIO_UNLOCK_ALL",
744 &Fcb->Mcb->FullName
745 ));
746 #endif
747
748 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) {
749 _SEH2_LEAVE;
750 }
751
752 IoStatus->Status = FsRtlFastUnlockAll(
753 &Fcb->FileLockAnchor,
754 FileObject,
755 Process,
756 NULL );
757
758 IoStatus->Information = 0;
759 Status = TRUE;
760
761 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
762
763 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
764 IoStatus->Status = _SEH2_GetExceptionCode();
765 } _SEH2_END;
766
767 } _SEH2_FINALLY {
768
769 FsRtlExitFileSystem();
770 } _SEH2_END;
771
772 #if EXT2_DEBUG
773 if (Status == FALSE) {
774
775 DEBUG(DL_ERR, (
776 "Ext2FastIoUnlockSingle: %s %s *** Status: FALSE ***\n",
777 (PUCHAR) Process + ProcessNameOffset,
778 "FASTIO_UNLOCK_ALL"
779 ));
780 } else if (IoStatus->Status != STATUS_SUCCESS) {
781 DEBUG(DL_ERR, (
782 "Ext2FastIoUnlockSingle: %s %s *** Status: %s (%#x) ***\n",
783 (PUCHAR) Process + ProcessNameOffset,
784 "FASTIO_UNLOCK_ALL",
785 Ext2NtStatusToString(IoStatus->Status),
786 IoStatus->Status
787 ));
788 }
789 #endif
790
791 return Status;
792 }
793
794 BOOLEAN NTAPI
795 Ext2FastIoUnlockAllByKey (
796 IN PFILE_OBJECT FileObject,
797 #ifdef __REACTOS__
798 IN PVOID Process,
799 #else
800 IN PEPROCESS Process,
801 #endif
802 IN ULONG Key,
803 OUT PIO_STATUS_BLOCK IoStatus,
804 IN PDEVICE_OBJECT DeviceObject
805 )
806 {
807 BOOLEAN Status = FALSE;
808 PEXT2_FCB Fcb;
809
810 _SEH2_TRY {
811
812 FsRtlEnterFileSystem();
813
814 _SEH2_TRY {
815
816 if (IsExt2FsDevice(DeviceObject)) {
817 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
818 _SEH2_LEAVE;
819 }
820
821 Fcb = (PEXT2_FCB) FileObject->FsContext;
822 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
823 DbgBreak();
824 IoStatus->Status = STATUS_INVALID_PARAMETER;
825 _SEH2_LEAVE;
826 }
827
828 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
829 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
830
831 if (IsDirectory(Fcb)) {
832 DbgBreak();
833 IoStatus->Status = STATUS_INVALID_PARAMETER;
834 _SEH2_LEAVE;
835 }
836
837 #if EXT2_DEBUG
838 DEBUG(DL_INF, (
839 "Ext2FastIoUnlockAllByKey: %s %s %wZ\n",
840 (PUCHAR) Process + ProcessNameOffset,
841 "FASTIO_UNLOCK_ALL_BY_KEY",
842 &Fcb->Mcb->FullName
843 ));
844
845 DEBUG(DL_INF, (
846 "Ext2FastIoUnlockAllByKey: Key: %u\n",
847 Key
848 ));
849 #endif
850
851 if (!FsRtlOplockIsFastIoPossible(&Fcb->Oplock)) {
852 _SEH2_LEAVE;
853 }
854
855 IoStatus->Status = FsRtlFastUnlockAllByKey(
856 &Fcb->FileLockAnchor,
857 FileObject,
858 Process,
859 Key,
860 NULL
861 );
862
863 IoStatus->Information = 0;
864 Status = TRUE;
865
866 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
867
868 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
869 IoStatus->Status = _SEH2_GetExceptionCode();
870 } _SEH2_END;
871
872 } _SEH2_FINALLY {
873
874 FsRtlExitFileSystem();
875 } _SEH2_END;
876
877 #if EXT2_DEBUG
878 if (Status == FALSE) {
879
880 DEBUG(DL_ERR, (
881 "Ext2FastIoUnlockAllByKey: %s %s *** Status: FALSE ***\n",
882 (PUCHAR) Process + ProcessNameOffset,
883 "FASTIO_UNLOCK_ALL_BY_KEY"
884 ));
885 } else if (IoStatus->Status != STATUS_SUCCESS) {
886
887 DEBUG(DL_ERR, (
888 "Ext2FastIoUnlockAllByKey: %s %s *** Status: %s (%#x) ***\n",
889 (PUCHAR) Process + ProcessNameOffset,
890 "FASTIO_UNLOCK_ALL_BY_KEY",
891 Ext2NtStatusToString(IoStatus->Status),
892 IoStatus->Status
893 ));
894 }
895 #endif
896
897 return Status;
898 }
899
900
901 BOOLEAN NTAPI
902 Ext2FastIoQueryNetworkOpenInfo (
903 IN PFILE_OBJECT FileObject,
904 IN BOOLEAN Wait,
905 IN OUT PFILE_NETWORK_OPEN_INFORMATION PFNOI,
906 OUT PIO_STATUS_BLOCK IoStatus,
907 IN PDEVICE_OBJECT DeviceObject
908 )
909 {
910 PEXT2_FCB Fcb = NULL;
911 PEXT2_CCB Ccb = NULL;
912 PEXT2_MCB Mcb = NULL;
913
914 BOOLEAN bResult = FALSE;
915 BOOLEAN FcbResourceAcquired = FALSE;
916
917 _SEH2_TRY {
918
919 FsRtlEnterFileSystem();
920
921 if (IsExt2FsDevice(DeviceObject)) {
922 IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
923 _SEH2_LEAVE;
924 }
925
926 Fcb = (PEXT2_FCB) FileObject->FsContext;
927 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
928 DbgBreak();
929 IoStatus->Status = STATUS_INVALID_PARAMETER;
930 _SEH2_LEAVE;
931 }
932
933 ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
934 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
935 Ccb = (PEXT2_CCB) FileObject->FsContext2;
936 Mcb = Fcb->Mcb;
937
938 #if EXT2_DEBUG
939 DEBUG(DL_INF, (
940 "%-31s %wZ\n",
941 "FASTIO_QUERY_NETWORK_OPEN_INFO",
942 &Fcb->Mcb->FullName
943 ));
944 #endif
945
946 if (!Ccb) {
947 _SEH2_LEAVE;
948 }
949
950 if (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)) {
951
952 if (!ExAcquireResourceSharedLite(
953 &Fcb->MainResource,
954 Wait
955 )) {
956 _SEH2_LEAVE;
957 }
958
959 FcbResourceAcquired = TRUE;
960 }
961
962 if (IsDirectory(Fcb)) {
963 PFNOI->AllocationSize.QuadPart = 0;
964 PFNOI->EndOfFile.QuadPart = 0;
965 } else {
966 PFNOI->AllocationSize = Fcb->Header.AllocationSize;
967 PFNOI->EndOfFile = Fcb->Header.FileSize;
968 }
969
970 PFNOI->FileAttributes = Mcb->FileAttr;
971 if (PFNOI->FileAttributes == 0) {
972 PFNOI->FileAttributes = FILE_ATTRIBUTE_NORMAL;
973 }
974
975 PFNOI->CreationTime = Mcb->CreationTime;
976 PFNOI->LastAccessTime = Mcb->LastAccessTime;
977 PFNOI->LastWriteTime = Mcb->LastWriteTime;
978 PFNOI->ChangeTime = Mcb->ChangeTime;
979
980 bResult = TRUE;
981
982 IoStatus->Status = STATUS_SUCCESS;
983 IoStatus->Information = sizeof(FILE_NETWORK_OPEN_INFORMATION);
984
985 } _SEH2_FINALLY {
986
987 if (FcbResourceAcquired) {
988 ExReleaseResourceLite(&Fcb->MainResource);
989 }
990
991 FsRtlExitFileSystem();
992 } _SEH2_END;
993
994 return bResult;
995 }
996
997
998 VOID NTAPI
999 Ext2AcquireForCreateSection (
1000 IN PFILE_OBJECT FileObject
1001 )
1002
1003 {
1004 PEXT2_FCB Fcb = FileObject->FsContext;
1005
1006 if (Fcb->Header.Resource != NULL) {
1007 ExAcquireResourceExclusiveLite(Fcb->Header.Resource, TRUE);
1008 }
1009
1010 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2AcquireForCreateSection: Fcb=%p\n", Fcb));
1011 }
1012
1013 VOID NTAPI
1014 Ext2ReleaseForCreateSection (
1015 IN PFILE_OBJECT FileObject
1016 )
1017 {
1018 PEXT2_FCB Fcb = FileObject->FsContext;
1019
1020 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2ReleaseForCreateSection: Fcb=%p\n", Fcb));
1021
1022 if (Fcb->Header.Resource != NULL) {
1023 ExReleaseResourceLite(Fcb->Header.Resource);
1024 }
1025 }
1026
1027
1028 NTSTATUS NTAPI
1029 Ext2AcquireFileForModWrite (
1030 IN PFILE_OBJECT FileObject,
1031 IN PLARGE_INTEGER EndingOffset,
1032 OUT PERESOURCE *ResourceToRelease,
1033 IN PDEVICE_OBJECT DeviceObject
1034 )
1035
1036 {
1037 BOOLEAN ResourceAcquired = FALSE;
1038
1039 PEXT2_FCB Fcb = FileObject->FsContext;
1040
1041 *ResourceToRelease = Fcb->Header.Resource;
1042 ResourceAcquired = ExAcquireResourceExclusiveLite(*ResourceToRelease, FALSE);
1043 if (!ResourceAcquired) {
1044 *ResourceToRelease = NULL;
1045 }
1046
1047 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2AcquireFileForModWrite: Fcb=%p Acquired=%d\n",
1048 Fcb, ResourceAcquired));
1049
1050 return (ResourceAcquired ? STATUS_SUCCESS : STATUS_CANT_WAIT);
1051 }
1052
1053 NTSTATUS NTAPI
1054 Ext2ReleaseFileForModWrite (
1055 IN PFILE_OBJECT FileObject,
1056 IN PERESOURCE ResourceToRelease,
1057 IN PDEVICE_OBJECT DeviceObject
1058 )
1059 {
1060 PEXT2_FCB Fcb = FileObject->FsContext;
1061
1062 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2ReleaseFileForModWrite: Fcb=%p\n", Fcb));
1063
1064 if (ResourceToRelease != NULL) {
1065 ASSERT(ResourceToRelease == Fcb->Header.Resource);
1066 ExReleaseResourceLite(ResourceToRelease);
1067 } else {
1068 DbgBreak();
1069 }
1070
1071 return STATUS_SUCCESS;
1072 }
1073
1074 NTSTATUS NTAPI
1075 Ext2AcquireFileForCcFlush (
1076 IN PFILE_OBJECT FileObject,
1077 IN PDEVICE_OBJECT DeviceObject
1078 )
1079 {
1080 PEXT2_FCB Fcb = FileObject->FsContext;
1081
1082 if (Fcb->Header.Resource != NULL) {
1083 ExAcquireResourceExclusiveLite(Fcb->Header.Resource, TRUE);
1084 }
1085
1086 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2AcquireFileForCcFlush: Fcb=%p\n", Fcb));
1087
1088 return STATUS_SUCCESS;
1089 }
1090
1091 NTSTATUS NTAPI
1092 Ext2ReleaseFileForCcFlush (
1093 IN PFILE_OBJECT FileObject,
1094 IN PDEVICE_OBJECT DeviceObject
1095 )
1096 {
1097 PEXT2_FCB Fcb = FileObject->FsContext;
1098
1099 DEBUG(FASTIO_DEBUG_LEVEL, ("Ext2ReleaseFileForCcFlush: Fcb=%p\n", Fcb));
1100
1101 if (Fcb->Header.Resource != NULL) {
1102 ExReleaseResourceLite(Fcb->Header.Resource);
1103 }
1104
1105 return STATUS_SUCCESS;
1106 }
1107
1108
1109 NTSTATUS NTAPI
1110 Ext2PreAcquireForCreateSection(
1111 IN PFS_FILTER_CALLBACK_DATA cd,
1112 OUT PVOID *cc
1113 )
1114 {
1115 PEXT2_FCB Fcb = (PEXT2_FCB)cd->FileObject->FsContext;
1116 NTSTATUS status;
1117
1118 ASSERT(cd->Operation == FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION);
1119 ExAcquireResourceExclusiveLite(Fcb->Header.Resource, TRUE);
1120 if (cd->Parameters.AcquireForSectionSynchronization.SyncType != SyncTypeCreateSection) {
1121 status = STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY;
1122 } else if (Fcb->ShareAccess.Writers == 0) {
1123 status = STATUS_FILE_LOCKED_WITH_ONLY_READERS;
1124 } else {
1125 status = STATUS_FILE_LOCKED_WITH_WRITERS;
1126 }
1127
1128 return status;
1129 }