windows-nt/Source/XPSP1/NT/drivers/storage/newft/packet.cxx
2020-09-26 16:20:57 +08:00

544 lines
9.4 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (C) 1991-5 Microsoft Corporation
Module Name:
packet.cxx
Abstract:
This module contains the code specific to all types of TRANSFER_PACKETS
objects.
Author:
Norbert Kusters 2-Feb-1995
Environment:
kernel mode only
Notes:
Revision History:
--*/
extern "C" {
#include <ntddk.h>
}
#include <ftdisk.h>
static PNPAGED_LOOKASIDE_LIST StripeLookasidePackets = NULL;
static PNPAGED_LOOKASIDE_LIST MirrorLookasidePackets = NULL;
#ifdef ALLOC_PRAGMA
#pragma code_seg("PAGELK")
#endif
PVOID
TRANSFER_PACKET::operator new(
IN size_t Size
)
/*++
Routine Description:
This routine is the memory allocator for all classes derived from
FT_VOLUME.
Arguments:
Size - Supplies the number of bytes to allocate.
Return Value:
A pointer to Size bytes of non-paged pool.
--*/
{
PTRANSFER_PACKET p;
if (Size <= sizeof(STRIPE_TP)) {
if (!StripeLookasidePackets) {
StripeLookasidePackets = (PNPAGED_LOOKASIDE_LIST)
ExAllocatePool(NonPagedPool,
sizeof(NPAGED_LOOKASIDE_LIST));
if (!StripeLookasidePackets) {
return NULL;
}
ExInitializeNPagedLookasideList(StripeLookasidePackets, NULL, NULL,
0, sizeof(STRIPE_TP), 'sFcS', 32);
}
p = (PTRANSFER_PACKET)
ExAllocateFromNPagedLookasideList(StripeLookasidePackets);
if (p) {
p->_allocationType = TP_ALLOCATION_STRIPE_POOL;
}
return p;
}
if (Size <= sizeof(MIRROR_TP)) {
if (!MirrorLookasidePackets) {
MirrorLookasidePackets = (PNPAGED_LOOKASIDE_LIST)
ExAllocatePool(NonPagedPool,
sizeof(NPAGED_LOOKASIDE_LIST));
if (!MirrorLookasidePackets) {
return NULL;
}
ExInitializeNPagedLookasideList(MirrorLookasidePackets, NULL, NULL,
0, sizeof(MIRROR_TP), 'mFcS', 32);
}
p = (PTRANSFER_PACKET)
ExAllocateFromNPagedLookasideList(MirrorLookasidePackets);
if (p) {
p->_allocationType = TP_ALLOCATION_MIRROR_POOL;
}
return p;
}
p = (PTRANSFER_PACKET) ExAllocatePool(NonPagedPool, Size);
if (p) {
p->_allocationType = 0;
}
return p;
}
VOID
TRANSFER_PACKET::operator delete(
IN PVOID MemPtr
)
/*++
Routine Description:
This routine frees memory allocated for all classes derived from
FT_VOLUME.
Arguments:
MemPtr - Supplies a pointer to the memory to free.
Return Value:
None.
--*/
{
PTRANSFER_PACKET p = (PTRANSFER_PACKET) MemPtr;
if (!p) {
return;
}
if (p->_allocationType == TP_ALLOCATION_STRIPE_POOL) {
ExFreeToNPagedLookasideList(StripeLookasidePackets, MemPtr);
} else if (p->_allocationType == TP_ALLOCATION_MIRROR_POOL) {
ExFreeToNPagedLookasideList(MirrorLookasidePackets, MemPtr);
} else {
ExFreePool(MemPtr);
}
}
TRANSFER_PACKET::~TRANSFER_PACKET(
)
/*++
Routine Description:
This is the destructor for a transfer packet. It frees up any allocated
MDL and buffer.
Arguments:
None.
Return Value:
None.
--*/
{
FreeMdl();
}
BOOLEAN
TRANSFER_PACKET::AllocateMdl(
IN PVOID Buffer,
IN ULONG Length
)
/*++
Routine Description:
This routine allocates an MDL and for this transfer packet.
Arguments:
Buffer - Supplies the buffer.
Length - Supplies the buffer length.
Return Value:
FALSE - Insufficient resources.
TRUE - Success.
--*/
{
FreeMdl();
Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
if (!Mdl) {
return FALSE;
}
_freeMdl = TRUE;
return TRUE;
}
BOOLEAN
TRANSFER_PACKET::AllocateMdl(
IN ULONG Length
)
/*++
Routine Description:
This routine allocates an MDL and buffer for this transfer packet.
Arguments:
Length - Supplies the buffer length.
Return Value:
FALSE - Insufficient resources.
TRUE - Success.
--*/
{
PVOID buffer;
FreeMdl();
buffer = ExAllocatePool(NonPagedPoolCacheAligned,
Length < PAGE_SIZE ? PAGE_SIZE : Length);
if (!buffer) {
return FALSE;
}
_freeBuffer = TRUE;
Mdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
if (!Mdl) {
ExFreePool(buffer);
_freeBuffer = FALSE;
return FALSE;
}
_freeMdl = TRUE;
MmBuildMdlForNonPagedPool(Mdl);
return TRUE;
}
VOID
TRANSFER_PACKET::FreeMdl(
)
/*++
Routine Description:
It frees up any allocated MDL and buffer.
Arguments:
None.
Return Value:
None.
--*/
{
if (_freeBuffer) {
ExFreePool(MmGetMdlVirtualAddress(Mdl));
_freeBuffer = FALSE;
}
if (_freeMdl) {
IoFreeMdl(Mdl);
_freeMdl = FALSE;
}
}
OVERLAP_TP::~OVERLAP_TP(
)
{
if (InQueue) {
OverlappedIoManager->ReleaseIoRegion(this);
}
}
MIRROR_RECOVER_TP::~MIRROR_RECOVER_TP(
)
{
FreeMdls();
}
BOOLEAN
MIRROR_RECOVER_TP::AllocateMdls(
IN ULONG Length
)
{
PVOID buffer;
FreeMdls();
PartialMdl = IoAllocateMdl((PVOID) (PAGE_SIZE - 1), Length,
FALSE, FALSE, NULL);
if (!PartialMdl) {
FreeMdls();
return FALSE;
}
buffer = ExAllocatePool(NonPagedPoolCacheAligned,
Length < PAGE_SIZE ? PAGE_SIZE : Length);
if (!buffer) {
FreeMdls();
return FALSE;
}
VerifyMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
if (!VerifyMdl) {
ExFreePool(buffer);
FreeMdls();
return FALSE;
}
MmBuildMdlForNonPagedPool(VerifyMdl);
return TRUE;
}
VOID
MIRROR_RECOVER_TP::FreeMdls(
)
{
if (PartialMdl) {
IoFreeMdl(PartialMdl);
PartialMdl = NULL;
}
if (VerifyMdl) {
ExFreePool(MmGetMdlVirtualAddress(VerifyMdl));
IoFreeMdl(VerifyMdl);
VerifyMdl = NULL;
}
}
SWP_RECOVER_TP::~SWP_RECOVER_TP(
)
{
FreeMdls();
}
BOOLEAN
SWP_RECOVER_TP::AllocateMdls(
IN ULONG Length
)
{
PVOID buffer;
FreeMdls();
PartialMdl = IoAllocateMdl((PVOID) (PAGE_SIZE - 1), Length,
FALSE, FALSE, NULL);
if (!PartialMdl) {
FreeMdls();
return FALSE;
}
buffer = ExAllocatePool(NonPagedPoolCacheAligned,
Length < PAGE_SIZE ? PAGE_SIZE : Length);
if (!buffer) {
FreeMdls();
return FALSE;
}
VerifyMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
if (!VerifyMdl) {
ExFreePool(buffer);
FreeMdls();
return FALSE;
}
MmBuildMdlForNonPagedPool(VerifyMdl);
return TRUE;
}
VOID
SWP_RECOVER_TP::FreeMdls(
)
{
if (PartialMdl) {
IoFreeMdl(PartialMdl);
PartialMdl = NULL;
}
if (VerifyMdl) {
ExFreePool(MmGetMdlVirtualAddress(VerifyMdl));
IoFreeMdl(VerifyMdl);
VerifyMdl = NULL;
}
}
SWP_WRITE_TP::~SWP_WRITE_TP(
)
{
FreeMdls();
}
BOOLEAN
SWP_WRITE_TP::AllocateMdls(
IN ULONG Length
)
{
PVOID buffer;
FreeMdls();
buffer = ExAllocatePool(NonPagedPoolCacheAligned,
Length < PAGE_SIZE ? PAGE_SIZE : Length);
if (!buffer) {
return FALSE;
}
ReadAndParityMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
if (!ReadAndParityMdl) {
ExFreePool(buffer);
return FALSE;
}
MmBuildMdlForNonPagedPool(ReadAndParityMdl);
buffer = ExAllocatePool(NonPagedPoolCacheAligned,
Length < PAGE_SIZE ? PAGE_SIZE : Length);
if (!buffer) {
FreeMdls();
return FALSE;
}
WriteMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
if (!WriteMdl) {
ExFreePool(buffer);
FreeMdls();
return FALSE;
}
MmBuildMdlForNonPagedPool(WriteMdl);
return TRUE;
}
VOID
SWP_WRITE_TP::FreeMdls(
)
{
if (ReadAndParityMdl) {
ExFreePool(MmGetMdlVirtualAddress(ReadAndParityMdl));
IoFreeMdl(ReadAndParityMdl);
ReadAndParityMdl = NULL;
}
if (WriteMdl) {
ExFreePool(MmGetMdlVirtualAddress(WriteMdl));
IoFreeMdl(WriteMdl);
WriteMdl = NULL;
}
}
REDISTRIBUTION_CW_TP::~REDISTRIBUTION_CW_TP(
)
{
FreeMdls();
}
BOOLEAN
REDISTRIBUTION_CW_TP::AllocateMdls(
IN ULONG Length
)
{
PVOID buffer;
FreeMdls();
PartialMdl = IoAllocateMdl((PVOID) (PAGE_SIZE - 1), Length,
FALSE, FALSE, NULL);
if (!PartialMdl) {
FreeMdls();
return FALSE;
}
buffer = ExAllocatePool(NonPagedPoolCacheAligned,
Length < PAGE_SIZE ? PAGE_SIZE : Length);
if (!buffer) {
FreeMdls();
return FALSE;
}
VerifyMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
if (!VerifyMdl) {
ExFreePool(buffer);
FreeMdls();
return FALSE;
}
MmBuildMdlForNonPagedPool(VerifyMdl);
return TRUE;
}
VOID
REDISTRIBUTION_CW_TP::FreeMdls(
)
{
if (PartialMdl) {
IoFreeMdl(PartialMdl);
PartialMdl = NULL;
}
if (VerifyMdl) {
ExFreePool(MmGetMdlVirtualAddress(VerifyMdl));
IoFreeMdl(VerifyMdl);
VerifyMdl = NULL;
}
}