//#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, FsRtlpInitNotifyImplementation)
+#endif
-PAGED_LOOKASIDE_LIST NotifyEntryLookaside;
-#define FSRTL_NOTIFY_TAG TAG('N','O','T','I')
+PAGED_LOOKASIDE_LIST NotifyEntryLookaside;
typedef struct _NOTIFY_ENTRY
{
LIST_ENTRY ListEntry;
PSTRING FullDirectoryName;
BOOLEAN WatchTree;
- BOOLEAN IgnoreBuffer;
BOOLEAN PendingChanges;
ULONG CompletionFilter;
LIST_ENTRY IrpQueue;
BOOLEAN Unicode;
BOOLEAN BufferExhausted;
PVOID Buffer; /* Buffer == NULL equals IgnoreBuffer == TRUE */
- ULONG BufferSize;
- ULONG NextEntryOffset;
+ ULONG BufferSize;
+ ULONG NextEntryOffset;
PFILE_NOTIFY_INFORMATION PrevEntry;
} NOTIFY_ENTRY, *PNOTIFY_ENTRY;
0
);
-
+
}
static
-inline
+__inline
BOOLEAN
FsRtlpIsUnicodePath(
PSTRING Path
)
{
ASSERT(Path->Length);
-
- if (Path->Length == 1) return FALSE;
-
+
+ if (Path->Length == 1) return FALSE;
+
if (*(WCHAR*)Path->Buffer == '\\') return TRUE;
-
+
return FALSE;
}
*/
static
VOID
-STDCALL
+STDCALL
FsRtlpNotifyCancelRoutine(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PFAST_MUTEX Lock;
//don't need this since we have our own sync. protecting irp cancellation
- IoReleaseCancelSpinLock(Irp->CancelIrql);
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
Lock = (PFAST_MUTEX)Irp->Tail.Overlay.DriverContext[3];
ExAcquireFastMutex(Lock );
-
+
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
-
+
ExReleaseFastMutex(Lock);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+
}
PVOID FsContext
)
{
- PLIST_ENTRY EnumEntry;
PNOTIFY_ENTRY NotifyEntry;
-
- LIST_FOR_EACH(EnumEntry, NotifyList)
+
+ LIST_FOR_EACH(NotifyEntry, NotifyList, NOTIFY_ENTRY, ListEntry)
{
- NotifyEntry = CONTAINING_RECORD(EnumEntry, NOTIFY_ENTRY, ListEntry);
-
if (NotifyEntry->FsContext == FsContext)
{
return NotifyEntry;
}
}
- return NULL;
+ return NULL;
}
/**********************************************************************
* FsRtlNotifyChangeDirectory@28
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
LIST_ENTRY CompletedListHead;
PLIST_ENTRY TmpEntry;
PIRP Irp;
-
+
InitializeListHead(&CompletedListHead);
-
- ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
-
+
+ ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
+
NotifyEntry = FsRtlpFindNotifyEntry(NotifyList, FsContext);
-
+
if (NotifyEntry)
{
/* free buffered changes */
/* irp cancelation bolilerplate */
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
/* avoid holding lock while completing irp */
InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
-
+
/* Unlink and free the NotifyStruct */
RemoveEntryList(&NotifyEntry->ListEntry);
ExFreeToPagedLookasideList(&NotifyEntryLookaside, NotifyEntry);
}
-
+
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
/* complete defered irps */
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
TmpEntry = RemoveHeadList(&CompletedListHead);
Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-
+
}
)
{
LIST_ENTRY CompletedListHead;
- PLIST_ENTRY EnumEntry, TmpEntry;
- PNOTIFY_ENTRY NotifyEntry;
+ PLIST_ENTRY TmpEntry;
+ PNOTIFY_ENTRY NotifyEntry, tmp;
PIRP Irp;
-
+
InitializeListHead(&CompletedListHead);
-
+
ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
- LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
+ LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry )
{
if (NotifyEntry->Fcb == Fcb)
{
- RemoveEntryList(&NotifyEntry->ListEntry);
-
+ RemoveEntryList(&NotifyEntry->ListEntry);
+
/* free buffered changes */
if (NotifyEntry->Buffer)
{
ExFreePool(NotifyEntry->Buffer);
}
-
+
/* cleanup pending irps */
while (!IsListEmpty(&NotifyEntry->IrpQueue))
{
/* irp cancelation bolilerplate */
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
}
-
+
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
Irp->IoStatus.Information = 0;
-
+
/* avoid holding lock while completing irp */
InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
}
}
-
- ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
+ ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
+
/* complete defered irps */
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
TmpEntry = RemoveHeadList(&CompletedListHead);
Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-
+
}
* FsRtlNotifyFullChangeDirectory@40
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
IN BOOLEAN WatchTree,
IN BOOLEAN IgnoreBuffer,
IN ULONG CompletionFilter,
- IN PIRP NotifyIrp,
+ IN PIRP Irp,
IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL,
IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL
)
{
- PIO_STACK_LOCATION IrpStack;
+ PIO_STACK_LOCATION IrpStack;
PNOTIFY_ENTRY NotifyEntry;
ULONG IrpBuffLen;
-
- if (!NotifyIrp)
+
+ if (!Irp)
{
/* all other params are ignored if NotifyIrp == NULL */
FsRtlpWatchedDirectoryWasDeleted(NotifySync, NotifyList, FsContext);
return;
}
-
+
DPRINT("FullDirectoryName: %wZ\n", FullDirectoryName);
-
+
ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
-
- IrpStack = IoGetCurrentIrpStackLocation(NotifyIrp);
+
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
if (IrpStack->FileObject->Flags & FO_CLEANUP_COMPLETE)
{
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
- NotifyIrp->IoStatus.Information = 0;
- NotifyIrp->IoStatus.Status = STATUS_NOTIFY_CLEANUP;
- IoCompleteRequest(NotifyIrp, IO_NO_INCREMENT);
- return;
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_NOTIFY_CLEANUP;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return;
}
-
+
IrpBuffLen = IrpStack->Parameters.NotifyDirectory.Length;
-
+
NotifyEntry = FsRtlpFindNotifyEntry(NotifyList, FsContext);
if (!NotifyEntry)
{
/* No NotifyStruct for this FileObject existed */
-
+
/* The first request for this FileObject set the standards.
* For subsequent requests, these params will be ignored.
* Ref: Windows NT File System Internals page 516
*/
-
+
NotifyEntry = ExAllocateFromPagedLookasideList(&NotifyEntryLookaside);
-
+
RtlZeroMemory(NotifyEntry, sizeof(NOTIFY_ENTRY));
-
+
NotifyEntry->FsContext = FsContext;
NotifyEntry->FullDirectoryName = FullDirectoryName;
NotifyEntry->WatchTree = WatchTree;
IrpBuffLen,
FSRTL_NOTIFY_TAG
);
-
- NotifyEntry->PrevEntry = NotifyEntry->Buffer;
+
NotifyEntry->BufferSize = IrpBuffLen;
}
_SEH_HANDLE
{
- /* ExAllocatePoolWithQuotaTag raised exception */
+ /* ExAllocatePoolWithQuotaTag raised exception but we dont care.
+ The impl. doesnt require a buffer, so well continue as usual.
+ */
}
_SEH_END;
}
InitializeListHead(&NotifyEntry->IrpQueue);
-
+
InsertTailList(NotifyList, &NotifyEntry->ListEntry);
}
-
-
-
+
+
+
if (!NotifyEntry->PendingChanges)
{
/* No changes are pending. Queue the irp */
/* Irp cancelation boilerplate */
- IoSetCancelRoutine(NotifyIrp, FsRtlpNotifyCancelRoutine);
- if (NotifyIrp->Cancel && IoSetCancelRoutine(NotifyIrp, NULL))
- {
+
+ /* save NotifySych for use in the cancel routine */
+ Irp->Tail.Overlay.DriverContext[3] = NotifySync;
+
+ IoSetCancelRoutine(Irp, FsRtlpNotifyCancelRoutine);
+ if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
+ {
//irp was canceled
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
- NotifyIrp->IoStatus.Status = STATUS_CANCELLED;
- NotifyIrp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
- IoCompleteRequest(NotifyIrp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return;
}
- IoMarkIrpPending(NotifyIrp);
+ IoMarkIrpPending(Irp);
//FIXME: any point in setting irp status/information before queueing?
-
- /* save NotifySych for use in the cancel routine */
- NotifyIrp->Tail.Overlay.DriverContext[3] = NotifySync;
- InsertTailList(&NotifyEntry->IrpQueue, &NotifyIrp->Tail.Overlay.ListEntry);
+ Irp->IoStatus.Status = STATUS_PENDING;
+
+ InsertTailList(&NotifyEntry->IrpQueue, &Irp->Tail.Overlay.ListEntry);
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
return;
}
-
+
/* Pending changes exist */
-
- if (NotifyEntry->Buffer == NULL ||
+
+ if (NotifyEntry->Buffer == NULL ||
NotifyEntry->BufferExhausted ||
IrpBuffLen < NotifyEntry->NextEntryOffset)
{
-Buffer were overflowed, OR
-Current irp buff was not large enough
*/
-
- NotifyIrp->IoStatus.Information = 0;
- NotifyIrp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR;
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR;
}
else
{
- /* terminate last entry */
- NotifyEntry->PrevEntry->NextEntryOffset = 0;
-
- //FIXME: copy data correctly to user
- memcpy(NotifyIrp->UserBuffer, NotifyEntry->Buffer, NotifyEntry->NextEntryOffset);
-
- NotifyIrp->IoStatus.Information = NotifyEntry->NextEntryOffset;
- NotifyIrp->IoStatus.Status = STATUS_SUCCESS;
+ PVOID Adr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
+
+ if (Adr)
+ {
+ memcpy(Adr, NotifyEntry->Buffer, NotifyEntry->NextEntryOffset);
+ Irp->IoStatus.Information = NotifyEntry->NextEntryOffset;
+ }
+ else
+ {
+ Irp->IoStatus.Information = 0;
+ }
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
}
-
+
/* reset buffer */
- NotifyEntry->PrevEntry = NotifyEntry->Buffer;
+ NotifyEntry->PrevEntry = NULL;
NotifyEntry->NextEntryOffset = 0;
NotifyEntry->BufferExhausted = FALSE;
-
+
NotifyEntry->PendingChanges = FALSE;
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
- IoCompleteRequest(NotifyIrp, IO_NO_INCREMENT);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ /* caller must return STATUS_PENDING */
}
FsRtlpGetNextIrp(PNOTIFY_ENTRY NotifyEntry)
{
PIRP Irp;
- PLIST_ENTRY TmpEntry;
-
+ PLIST_ENTRY TmpEntry;
+
/* Loop to get a non-canceled irp */
while (!IsListEmpty(&NotifyEntry->IrpQueue))
{
/* If we have queued irp(s) we can't possibly have pending changes too */
ASSERT(!NotifyEntry->PendingChanges);
-
+
TmpEntry = RemoveHeadList(&NotifyEntry->IrpQueue);
Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry);
/* irp cancelation bolilerplate */
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
}
/* Finally we got a non-canceled irp */
- return Irp;
+ return Irp;
}
-
+
return NULL;
}
-
-
+
+
static
-inline
+__inline
VOID
FsRtlpCopyName(
PFILE_NOTIFY_INFORMATION CurrentEntry,
if (Unicode)
{
- memcpy(CurrentEntry->Name, RelativeName->Buffer, RelativeName->Length);
+ memcpy(CurrentEntry->FileName, RelativeName->Buffer, RelativeName->Length);
if (StreamName)
{
- CurrentEntry->Name[RelativeName->Length/sizeof(WCHAR)] = ':';
- memcpy(&CurrentEntry ->Name[(RelativeName->Length/sizeof(WCHAR))+1],
+ CurrentEntry->FileName[RelativeName->Length/sizeof(WCHAR)] = ':';
+ memcpy(&CurrentEntry->FileName[(RelativeName->Length/sizeof(WCHAR))+1],
StreamName->Buffer,
StreamName->Length);
}
* FsRtlNotifyFullReportChange@36
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
{
USHORT FullDirLen;
STRING RelativeName;
+ PNOTIFY_ENTRY NotifyEntry, tmp;
PLIST_ENTRY EnumEntry;
- PNOTIFY_ENTRY NotifyEntry;
PIRP Irp;
LIST_ENTRY CompletedListHead;
USHORT NameLenU;
ULONG RecordLen;
PFILE_NOTIFY_INFORMATION CurrentEntry;
-
+
InitializeListHead(&CompletedListHead);
DPRINT("FullTargetName: %wZ\n", FullTargetName);
I think FullTargetName can include/be a short file name! What the heck do i do with this?
Dont think this apply to FsRtlNotifyFullChangeDirectory's FullDirectoryName.
*/
-
-
- ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
- LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
+
+ ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
+
+ LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry )
{
ASSERT(NotifyEntry->Unicode == FsRtlpIsUnicodePath(FullTargetName));
-
+
/* rule out some easy cases */
- /* FIXME: short vs. long names??? */
+ /* FIXME: short vs. long names??? lower case/upper case/mixed case? */
if (!(FilterMatch & NotifyEntry->CompletionFilter)) continue;
-
- FullDirLen = TargetNameOffset - (NotifyEntry->Unicode?sizeof(WCHAR):sizeof(char));
-
-
+
+ FullDirLen = TargetNameOffset - (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char));
+ if (FullDirLen == 0)
+ {
+ /* special case for root dir */
+ FullDirLen = (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char));
+ }
+
if (FullDirLen < NotifyEntry->FullDirectoryName->Length) continue;
-
+
if (!NotifyEntry->WatchTree && FullDirLen != NotifyEntry->FullDirectoryName->Length) continue;
DPRINT("NotifyEntry->FullDirectoryName: %wZ\n", NotifyEntry->FullDirectoryName);
-
- if (memcmp(NotifyEntry->FullDirectoryName->Buffer,
- FullTargetName->Buffer,
+
+ /* FIXME: short vs. long names??? lower case/upper case/mixed case? */
+ if (memcmp(NotifyEntry->FullDirectoryName->Buffer,
+ FullTargetName->Buffer,
NotifyEntry->FullDirectoryName->Length) != 0) continue;
-
- if (NotifyEntry->WatchTree &&
+
+ if (NotifyEntry->WatchTree &&
NotifyEntry->TraverseCallback &&
FullDirLen != NotifyEntry->FullDirectoryName->Length)
{
NTSTATUS Status = NotifyEntry->TraverseCallback(NotifyEntry->FsContext,
TargetContext,
NotifyEntry->SubjectContext);
-
+
if (!NT_SUCCESS(Status)) continue;
-
+
/*
FIXME: notify-dir impl. should release and free the SubjectContext
*/
}
DPRINT("Found match\n");
-
+
/* Found a valid change */
RelativeName.Buffer = FullTargetName->Buffer + TargetNameOffset;
- RelativeName.MaximumLength =
- RelativeName.Length =
+ RelativeName.MaximumLength =
+ RelativeName.Length =
FullTargetName->Length - TargetNameOffset;
-
+
DPRINT("RelativeName: %wZ\n",&RelativeName);
-
+
/* calculate unicode bytes of relative-name + stream-name */
if (NotifyEntry->Unicode)
{
}
else
{
- NameLenU = RelativeName.Length * sizeof(WCHAR) +
+ NameLenU = RelativeName.Length * sizeof(WCHAR) +
(StreamName ? ((StreamName->Length * sizeof(WCHAR)) + sizeof(WCHAR)) : 0);
}
-
- RecordLen = FIELD_OFFSET(FILE_NOTIFY_INFORMATION, Name) + NameLenU;
-
+
+ RecordLen = FIELD_OFFSET(FILE_NOTIFY_INFORMATION, FileName) + NameLenU;
+
if ((Irp = FsRtlpGetNextIrp(NotifyEntry)))
{
PIO_STACK_LOCATION IrpStack;
ULONG IrpBuffLen;
-
+
IrpStack = IoGetCurrentIrpStackLocation(Irp);
IrpBuffLen = IrpStack->Parameters.NotifyDirectory.Length;
-
+
DPRINT("Got pending irp\n");
-
+
ASSERT(!NotifyEntry->PendingChanges);
-
- if (NotifyEntry->Buffer == NULL || /* aka. IgnoreBuffer */
+
+ if (NotifyEntry->Buffer == NULL || /* aka. IgnoreBuffer */
RecordLen > IrpBuffLen)
{
/* ignore buffer / buffer not large enough */
}
else
{
- //FIXME: copy data to user correctly
- CurrentEntry = (PFILE_NOTIFY_INFORMATION)Irp->UserBuffer;
-
- CurrentEntry->Action = Action;
- CurrentEntry->NameLength = NameLenU;
- CurrentEntry->NextEntryOffset = 0;
-
- FsRtlpCopyName(
- CurrentEntry,
- NotifyEntry->Unicode,
- &RelativeName,
- StreamName
- );
+ CurrentEntry = (PFILE_NOTIFY_INFORMATION)
+ MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
+
+ if (CurrentEntry)
+ {
+ CurrentEntry->Action = Action;
+ CurrentEntry->FileNameLength = NameLenU;
+ CurrentEntry->NextEntryOffset = 0;
+
+ FsRtlpCopyName(
+ CurrentEntry,
+ NotifyEntry->Unicode,
+ &RelativeName,
+ StreamName
+ );
+
+ Irp->IoStatus.Information = RecordLen;
+ }
+ else
+ {
+ Irp->IoStatus.Information = 0;
+ }
+
Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = RecordLen;
}
-
+
/* avoid holding lock while completing irp */
InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
else
{
DPRINT("No irp\n");
-
+
NotifyEntry->PendingChanges = TRUE;
if (NotifyEntry->Buffer == NULL || NotifyEntry->BufferExhausted) continue;
-
+
if (RecordLen > NotifyEntry->BufferSize - NotifyEntry->NextEntryOffset)
{
/* overflow. drop these changes and stop buffering any other changes too */
/* The buffer has enough room for the changes.
* Copy data to buffer.
*/
-
+
CurrentEntry = (PFILE_NOTIFY_INFORMATION)NotifyEntry->Buffer;
-
- CurrentEntry->Action = Action;
- CurrentEntry->NameLength = NameLenU;
+
+ CurrentEntry->Action = Action;
+ CurrentEntry->FileNameLength = NameLenU;
CurrentEntry->NextEntryOffset = 0;
FsRtlpCopyName(CurrentEntry,
&RelativeName,
StreamName
);
-
- /* adjust buffer */
- NotifyEntry->PrevEntry->NextEntryOffset = (char*)CurrentEntry - (char*)NotifyEntry->PrevEntry;
+
+ if (NotifyEntry->PrevEntry)
+ {
+ NotifyEntry->PrevEntry->NextEntryOffset = (char*)CurrentEntry - (char*)NotifyEntry->PrevEntry;
+ }
NotifyEntry->PrevEntry = CurrentEntry;
NotifyEntry->NextEntryOffset += RecordLen;
-
+
// {
// UNICODE_STRING TmpStr;
// TmpStr.MaximumLength = TmpStr.Length = BufferedChange->NameLen;
// DPRINT("BufferedChange->RelativeName: %wZ\n", &TmpStr);
// }
-
+
}
}
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
/* complete defered irps */
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
EnumEntry = RemoveHeadList(&CompletedListHead);
Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry);
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-
+
}
* FsRtlNotifyInitializeSync@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlNotifyReportChange@20
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
VOID
STDCALL
FsRtlNotifyUninitializeSync (
- IN PNOTIFY_SYNC NotifySync
+ IN PNOTIFY_SYNC *NotifySync
)
{
- ExFreePool (NotifySync);
+ ExFreePool (*NotifySync);
}
/**********************************************************************