Skip to content

Commit b845c08

Browse files
authored
Merge pull request #286 from bailey27/more_FsRtlCheckOplock
More fs rtl check oplock
2 parents 9d6bace + 0c64b84 commit b845c08

File tree

6 files changed

+105
-3
lines changed

6 files changed

+105
-3
lines changed

sys/cleanup.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,23 @@ Return Value:
110110
eventContext->Operation.Cleanup.FileNameLength = fcb->FileName.Length;
111111
RtlCopyMemory(eventContext->Operation.Cleanup.FileName,
112112
fcb->FileName.Buffer, fcb->FileName.Length);
113+
114+
115+
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
116+
DokanOplockComplete, DokanPrePostIrp);
117+
118+
//
119+
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
120+
// to service an oplock break and we need to leave now.
121+
//
122+
if (status != STATUS_SUCCESS) {
123+
if (status == STATUS_PENDING) {
124+
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
125+
} else {
126+
DokanFreeEventContext(eventContext);
127+
}
128+
__leave;
129+
}
113130

114131
// register this IRP to pending IRP list
115132
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);

sys/fileinfo.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,22 @@ DokanDispatchSetInformation(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
459459
eventContext->Operation.SetFile.FileNameLength = fcb->FileName.Length;
460460
RtlCopyMemory(eventContext->Operation.SetFile.FileName,
461461
fcb->FileName.Buffer, fcb->FileName.Length);
462+
463+
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
464+
DokanOplockComplete, DokanPrePostIrp);
465+
466+
//
467+
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
468+
// to service an oplock break and we need to leave now.
469+
//
470+
if (status != STATUS_SUCCESS) {
471+
if (status == STATUS_PENDING) {
472+
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
473+
} else {
474+
DokanFreeEventContext(eventContext);
475+
}
476+
__leave;
477+
}
462478

463479
// register this IRP to waiting IRP list and make it pending status
464480
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);

sys/flush.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ DokanDispatchFlush(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
7777

7878
CcUninitializeCacheMap(fileObject, NULL, NULL);
7979
// fileObject->Flags &= FO_CLEANUP_COMPLETE;
80+
81+
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
82+
DokanOplockComplete, DokanPrePostIrp);
83+
84+
//
85+
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
86+
// to service an oplock break and we need to leave now.
87+
//
88+
if (status != STATUS_SUCCESS) {
89+
if (status == STATUS_PENDING) {
90+
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
91+
} else {
92+
DokanFreeEventContext(eventContext);
93+
}
94+
__leave;
95+
}
8096

8197
// register this IRP to waiting IRP list and make it pending status
8298
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);

sys/fscontrol.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ NTSTATUS DokanOplockRequest(__in PIRP *pIrp) {
131131
) {
132132

133133
AcquiredVcb = ExAcquireResourceSharedLite(&(Fcb->Vcb->Resource), TRUE);
134-
AcquiredFcb = ExAcquireResourceSharedLite(&(Fcb->Resource), TRUE);
134+
AcquiredFcb = ExAcquireResourceExclusiveLite(&(Fcb->Resource), TRUE);
135135

136136
#if (NTDDI_VERSION >= NTDDI_WIN7)
137137
if (!Dcb->FileLockInUserMode && FsRtlOplockIsSharedRequest(Irp)) {

sys/read.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,12 @@ Return Value:
203203
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
204204
// to service an oplock break and we need to leave now.
205205
//
206-
if (status == STATUS_PENDING) {
207-
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
206+
if (status != STATUS_SUCCESS) {
207+
if (status == STATUS_PENDING) {
208+
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
209+
} else {
210+
DokanFreeEventContext(eventContext);
211+
}
208212
__leave;
209213
}
210214

sys/write.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ DokanDispatchWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
168168
eventContext->Operation.Write.FileNameLength = fcb->FileName.Length;
169169
RtlCopyMemory(eventContext->Operation.Write.FileName, fcb->FileName.Buffer,
170170
fcb->FileName.Length);
171+
172+
171173

172174
// When eventlength is less than event notification buffer,
173175
// returns it to user-mode using pending event.
@@ -180,6 +182,29 @@ DokanDispatchWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
180182

181183
// EventContext is no longer needed, clear it
182184
Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = 0;
185+
186+
187+
//
188+
// We now check whether we can proceed based on the state of
189+
// the file oplocks.
190+
//
191+
if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
192+
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, eventContext,
193+
DokanOplockComplete, DokanPrePostIrp);
194+
195+
//
196+
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
197+
// to service an oplock break and we need to leave now.
198+
//
199+
if (status != STATUS_SUCCESS) {
200+
if (status == STATUS_PENDING) {
201+
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
202+
} else {
203+
DokanFreeEventContext(eventContext);
204+
}
205+
__leave;
206+
}
207+
}
183208

184209
// register this IRP to IRP waiting list and make it pending status
185210
status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext, 0);
@@ -214,6 +239,30 @@ DokanDispatchWrite(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) {
214239
requestContext->Length = requestContextLength;
215240
// requsts enough size to copy EventContext
216241
requestContext->Operation.Write.RequestLength = eventLength;
242+
243+
//
244+
// We now check whether we can proceed based on the state of
245+
// the file oplocks.
246+
//
247+
if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
248+
status = FsRtlCheckOplock(DokanGetFcbOplock(fcb), Irp, requestContext,
249+
DokanOplockComplete, DokanPrePostIrp);
250+
251+
//
252+
// if FsRtlCheckOplock returns STATUS_PENDING the IRP has been posted
253+
// to service an oplock break and we need to leave now.
254+
//
255+
if (status != STATUS_SUCCESS) {
256+
if (status == STATUS_PENDING) {
257+
DDbgPrint(" FsRtlCheckOplock returned STATUS_PENDING\n");
258+
} else {
259+
DokanFreeEventContext(requestContext);
260+
Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_EVENT] = 0;
261+
DokanFreeEventContext(eventContext);
262+
}
263+
__leave;
264+
}
265+
}
217266

218267
// regiters this IRP to IRP wainting list and make it pending status
219268
status = DokanRegisterPendingIrp(DeviceObject, Irp, requestContext, 0);

0 commit comments

Comments
 (0)