Beispiel #1
0
NTSTATUS
NTAPI
_MiWriteBackPage(PFILE_OBJECT FileObject,
                 PLARGE_INTEGER FileOffset,
                 ULONG Length,
                 PFN_NUMBER Page,
                 const char *File,
                 int Line)
{
    NTSTATUS Status;
    PVOID Hyperspace;
    IO_STATUS_BLOCK Iosb;
    KIRQL OldIrql;
    PVOID PageBuffer = ExAllocatePool(NonPagedPool, PAGE_SIZE);

    if (!PageBuffer) return STATUS_NO_MEMORY;

    Hyperspace = MiMapPageInHyperSpace(PsGetCurrentProcess(), Page, &OldIrql);
    if (!Hyperspace)
    {
        ExFreePool(PageBuffer);
        return STATUS_NO_MEMORY;
    }
    RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE);
    MiUnmapPageInHyperSpace(PsGetCurrentProcess(), Hyperspace, OldIrql);

    DPRINT("MiWriteBackPage(%wZ,%08x%08x,%s:%d)\n",
           &FileObject->FileName,
           FileOffset->u.HighPart,
           FileOffset->u.LowPart,
           File,
           Line);

    Status = MiSimpleWrite(FileObject,
                           FileOffset,
                           PageBuffer,
                           Length,
                           &Iosb);

    ExFreePool(PageBuffer);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("MiSimpleWrite failed (%x)\n", Status);
    }

    return Status;
}
Beispiel #2
0
NTSTATUS
NTAPI
_MiWriteBackPage
(PFILE_OBJECT FileObject,
 PLARGE_INTEGER FileOffset,
 ULONG Length,
 PFN_NUMBER Page,
 const char *File,
 int Line)
{
	NTSTATUS Status;
	PVOID Hyperspace;
	IO_STATUS_BLOCK Iosb;
	KIRQL OldIrql;
	PVOID PageBuffer = ExAllocatePool(NonPagedPool, PAGE_SIZE);

	if (!PageBuffer) return STATUS_NO_MEMORY;

	KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
	Hyperspace = MmCreateHyperspaceMapping(Page);
	RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE);
	MmDeleteHyperspaceMapping(Hyperspace);
	KeLowerIrql(OldIrql);

	DPRINT1("MiWriteBackPage(%wZ,%08x%08x,%s:%d)\n", &FileObject->FileName, FileOffset->u.HighPart, FileOffset->u.LowPart, File, Line);
	Status = MiSimpleWrite
		(FileObject,
		 FileOffset,
		 PageBuffer,
		 Length,
		 &Iosb);

	ExFreePool(PageBuffer);

	if (!NT_SUCCESS(Status))
	{
		DPRINT1("MiSimpleWrite failed (%x)\n", Status);
	}

	return Status;
}
Beispiel #3
0
/*

This could be implemented much more intelligently by mapping instances
of a CoW zero page into the affected regions.  We just RtlZeroMemory
for now.

*/
BOOLEAN
NTAPI
CcZeroData(IN PFILE_OBJECT FileObject,
           IN PLARGE_INTEGER StartOffset,
           IN PLARGE_INTEGER EndOffset,
           IN BOOLEAN Wait)
{
    PNOCC_BCB Bcb = NULL;
    PLIST_ENTRY ListEntry = NULL;
    LARGE_INTEGER LowerBound = *StartOffset;
    LARGE_INTEGER UpperBound = *EndOffset;
    LARGE_INTEGER Target, End;
    PVOID PinnedBcb, PinnedBuffer;
    PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;

    DPRINT("S %08x%08x E %08x%08x\n",
           StartOffset->u.HighPart,
           StartOffset->u.LowPart,
           EndOffset->u.HighPart,
           EndOffset->u.LowPart);

    if (!Map)
    {
        NTSTATUS Status;
        IO_STATUS_BLOCK IOSB;
        PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
        ULONG ToWrite;

        if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
        DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
        RtlZeroMemory(ZeroBuf, PAGE_SIZE);

        Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
        End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);

        // Handle leading page
        if (LowerBound.QuadPart != Target.QuadPart)
        {
            ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
                          (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));

            DPRINT("Zero last half %08x%08x %x\n",
                   Target.u.HighPart,
                   Target.u.LowPart,
                   ToWrite);

            Status = MiSimpleRead(FileObject,
                                  &Target,
                                  ZeroBuf,
                                  PAGE_SIZE,
                                  TRUE,
                                  &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }

            DPRINT1("RtlZeroMemory(%x,%x)\n",
                    ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
                    ToWrite);

            RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
                          ToWrite);

            Status = MiSimpleWrite(FileObject,
                                   &Target,
                                   ZeroBuf,
                                   MIN(PAGE_SIZE,
                                       UpperBound.QuadPart-Target.QuadPart),
                                   &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            Target.QuadPart += PAGE_SIZE;
        }

        DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
        RtlZeroMemory(ZeroBuf, PAGE_SIZE);

        while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
        {
            DPRINT("Zero full page %08x%08x\n",
                   Target.u.HighPart,
                   Target.u.LowPart);

            Status = MiSimpleWrite(FileObject,
                                   &Target,
                                   ZeroBuf,
                                   PAGE_SIZE,
                                   &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            Target.QuadPart += PAGE_SIZE;
        }

        if (UpperBound.QuadPart > Target.QuadPart)
        {
            ToWrite = UpperBound.QuadPart - Target.QuadPart;
            DPRINT("Zero first half %08x%08x %x\n",
                   Target.u.HighPart,
                   Target.u.LowPart,
                   ToWrite);

            Status = MiSimpleRead(FileObject,
                                  &Target,
                                  ZeroBuf,
                                  PAGE_SIZE,
                                  TRUE,
                                  &IOSB);

            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
            RtlZeroMemory(ZeroBuf, ToWrite);
            Status = MiSimpleWrite(FileObject,
                                   &Target,
                                   ZeroBuf,
                                   MIN(PAGE_SIZE,
                                       UpperBound.QuadPart-Target.QuadPart),
                                   &IOSB);
            if (!NT_SUCCESS(Status))
            {
                ExFreePool(ZeroBuf);
                RtlRaiseStatus(Status);
            }
            Target.QuadPart += PAGE_SIZE;
        }

        ExFreePool(ZeroBuf);
        return TRUE;
    }

    CcpLock();
    ListEntry = Map->AssociatedBcb.Flink;

    while (ListEntry != &Map->AssociatedBcb)
    {
        Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
        CcpReferenceCache(Bcb - CcCacheSections);

        if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
            Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
        {
            DPRINT("Bcb #%x (@%08x%08x)\n",
                   Bcb - CcCacheSections,
                   Bcb->FileOffset.u.HighPart,
                   Bcb->FileOffset.u.LowPart);

            Target.QuadPart = MAX(Bcb->FileOffset.QuadPart,
                                  LowerBound.QuadPart);

            End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart,
                               UpperBound.QuadPart);

            End.QuadPart = MIN(End.QuadPart,
                               Bcb->FileOffset.QuadPart + Bcb->Length);

            CcpUnlock();

            if (!CcPreparePinWrite(FileObject,
                                   &Target,
                                   End.QuadPart - Target.QuadPart,
                                   TRUE,
                                   Wait,
                                   &PinnedBcb,
                                   &PinnedBuffer))
            {
                return FALSE;
            }

            ASSERT(PinnedBcb == Bcb);

            CcpLock();
            ListEntry = ListEntry->Flink;
            /* Return from pin state */
            CcpUnpinData(PinnedBcb, TRUE);
        }

        CcpUnpinData(Bcb, TRUE);
    }

    CcpUnlock();

    return TRUE;
}