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