1 /* Copyright (c) Mark Harmstone 2016
3 * This file is part of WinBtrfs.
5 * WinBtrfs is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public Licence as published by
7 * the Free Software Foundation, either version 3 of the Licence, or
8 * (at your option) any later version.
10 * WinBtrfs is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public Licence for more details.
15 * You should have received a copy of the GNU Lesser General Public Licence
16 * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
18 #include "btrfs_drv.h"
21 device_extension
* Vcb
;
26 void do_read_job(PIRP Irp
) {
29 BOOL top_level
= is_top_level(Irp
);
30 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
31 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
32 fcb
* fcb
= FileObject
->FsContext
;
33 BOOL fcb_lock
= FALSE
;
35 Irp
->IoStatus
.Information
= 0;
37 if (!ExIsResourceAcquiredSharedLite(fcb
->Header
.Resource
)) {
38 ExAcquireResourceSharedLite(fcb
->Header
.Resource
, TRUE
);
42 Status
= do_read(Irp
, TRUE
, &bytes_read
);
45 ExReleaseResourceLite(fcb
->Header
.Resource
);
47 Irp
->IoStatus
.Status
= Status
;
49 // // fastfat doesn't do this, but the Wine ntdll file test seems to think we ought to
51 // *Irp->UserIosb = Irp->IoStatus;
53 TRACE("Irp->IoStatus.Status = %08x\n", Irp
->IoStatus
.Status
);
54 TRACE("Irp->IoStatus.Information = %lu\n", Irp
->IoStatus
.Information
);
55 TRACE("returning %08x\n", Status
);
57 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
60 IoSetTopLevelIrp(NULL
);
63 void do_write_job(device_extension
* Vcb
, PIRP Irp
) {
64 BOOL top_level
= is_top_level(Irp
);
68 Status
= write_file(Vcb
, Irp
, TRUE
, TRUE
);
69 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER
) {
70 Status
= _SEH2_GetExceptionCode();
73 if (!NT_SUCCESS(Status
))
74 ERR("write_file returned %08x\n", Status
);
76 Irp
->IoStatus
.Status
= Status
;
78 TRACE("wrote %u bytes\n", Irp
->IoStatus
.Information
);
80 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
83 IoSetTopLevelIrp(NULL
);
85 TRACE("returning %08x\n", Status
);
89 static void NTAPI
do_job(void* context
) {
91 static void do_job(void* context
) {
93 job_info
* ji
= context
;
94 PIO_STACK_LOCATION IrpSp
= ji
->Irp
? IoGetCurrentIrpStackLocation(ji
->Irp
) : NULL
;
96 if (IrpSp
->MajorFunction
== IRP_MJ_READ
) {
98 } else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
) {
99 do_write_job(ji
->Vcb
, ji
->Irp
);
105 BOOL
add_thread_job(device_extension
* Vcb
, PIRP Irp
) {
108 ji
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(job_info
), ALLOC_TAG
);
110 ERR("out of memory\n");
117 if (!Irp
->MdlAddress
) {
121 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
123 if (IrpSp
->MajorFunction
== IRP_MJ_READ
) {
125 len
= IrpSp
->Parameters
.Read
.Length
;
126 } else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
) {
128 len
= IrpSp
->Parameters
.Write
.Length
;
130 ERR("unexpected major function %u\n", IrpSp
->MajorFunction
);
134 Mdl
= IoAllocateMdl(Irp
->UserBuffer
, len
, FALSE
, FALSE
, Irp
);
137 ERR("out of memory\n");
142 MmProbeAndLockPages(Mdl
, Irp
->RequestorMode
, op
);
143 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER
) {
144 ERR("MmProbeAndLockPages raised status %08x\n", _SEH2_GetExceptionCode());
147 Irp
->MdlAddress
= NULL
;
149 _SEH2_YIELD(return FALSE
);
153 ExInitializeWorkItem(&ji
->item
, do_job
, ji
);
154 ExQueueWorkItem(&ji
->item
, DelayedWorkQueue
);