335 lines
4.9 KiB
C++
335 lines
4.9 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) 1991-5 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
ftvol.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the code specific to all volume objects.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Norbert Kusters 2-Feb-1995
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
kernel mode only
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
extern "C" {
|
|||
|
#include <ntddk.h>
|
|||
|
}
|
|||
|
|
|||
|
#include <ftdisk.h>
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma code_seg("PAGE")
|
|||
|
#endif
|
|||
|
|
|||
|
VOID
|
|||
|
FT_VOLUME::Initialize(
|
|||
|
IN OUT PROOT_EXTENSION RootExtension,
|
|||
|
IN FT_LOGICAL_DISK_ID LogicalDiskId
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the init routine for an FT_VOLUME. It must be called before
|
|||
|
the FT_VOLUME is used.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
RootExtension - Supplies the root device extension.
|
|||
|
|
|||
|
LogicalDiskId - Supplies the logical disk id for this volume.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
KeInitializeSpinLock(&_spinLock);
|
|||
|
_diskInfoSet = RootExtension->DiskInfoSet;
|
|||
|
_rootExtension = RootExtension;
|
|||
|
_logicalDiskId = LogicalDiskId;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
FT_VOLUME::IsVolumeSuitableForRegenerate(
|
|||
|
IN USHORT MemberNumber,
|
|||
|
IN PFT_VOLUME Volume
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine computes whether or not the given volume is suitable
|
|||
|
for a regenerate operation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
MemberNumber - Supplies the member number.
|
|||
|
|
|||
|
Volume - Supplies the volume.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
FALSE - The volume is not suitable.
|
|||
|
|
|||
|
TRUE - The volume is suitable.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FT_VOLUME::ModifyStateForUser(
|
|||
|
IN OUT PVOID State
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine modifies the state for the user to see, possibly adding
|
|||
|
non-persistant state different than what is stored on disk.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
State - Supplies and returns the state for the logical disk.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma code_seg("PAGELK")
|
|||
|
#endif
|
|||
|
|
|||
|
PVOID
|
|||
|
FT_BASE_CLASS::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.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return ExAllocatePool(NonPagedPool, Size);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FT_BASE_CLASS::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.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if (MemPtr) {
|
|||
|
ExFreePool(MemPtr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
FT_LOGICAL_DISK_ID
|
|||
|
FT_VOLUME::QueryLogicalDiskId(
|
|||
|
)
|
|||
|
{
|
|||
|
KIRQL irql;
|
|||
|
FT_LOGICAL_DISK_ID r;
|
|||
|
|
|||
|
KeAcquireSpinLock(&_spinLock, &irql);
|
|||
|
r = _logicalDiskId;
|
|||
|
KeReleaseSpinLock(&_spinLock, irql);
|
|||
|
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FT_VOLUME::SetLogicalDiskId(
|
|||
|
IN FT_LOGICAL_DISK_ID NewLogicalDiskId
|
|||
|
)
|
|||
|
{
|
|||
|
KIRQL irql;
|
|||
|
|
|||
|
KeAcquireSpinLock(&_spinLock, &irql);
|
|||
|
_logicalDiskId = NewLogicalDiskId;
|
|||
|
KeReleaseSpinLock(&_spinLock, irql);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FtVolumeNotifyWorker(
|
|||
|
IN PVOID FtVolume
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the worker routine to signal a notify on the given volume
|
|||
|
object.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
FtVolume - Supplies the FT volume.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PFT_VOLUME vol = (PFT_VOLUME) FtVolume;
|
|||
|
PVOLUME_EXTENSION extension;
|
|||
|
|
|||
|
FtpAcquire(vol->_rootExtension);
|
|||
|
extension = FtpFindExtensionCoveringDiskId(vol->_rootExtension,
|
|||
|
vol->QueryLogicalDiskId());
|
|||
|
FtpRelease(vol->_rootExtension);
|
|||
|
|
|||
|
if (extension) {
|
|||
|
FtpNotify(extension->Root, extension);
|
|||
|
}
|
|||
|
|
|||
|
if (!InterlockedDecrement(&vol->_refCount)) {
|
|||
|
delete vol;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FT_VOLUME::Notify(
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called when a sub class would like to post notification
|
|||
|
about a state change.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PWORK_QUEUE_ITEM workItem;
|
|||
|
|
|||
|
workItem = (PWORK_QUEUE_ITEM)
|
|||
|
ExAllocatePool(NonPagedPool, sizeof(WORK_QUEUE_ITEM));
|
|||
|
if (!workItem) {
|
|||
|
return;
|
|||
|
}
|
|||
|
ExInitializeWorkItem(workItem, FtVolumeNotifyWorker, this);
|
|||
|
|
|||
|
InterlockedIncrement(&_refCount);
|
|||
|
|
|||
|
FtpQueueWorkItem(_rootExtension, workItem);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
FT_VOLUME::NewStateArrival(
|
|||
|
IN PVOID NewStateInstance
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine takes the new state instance arrival combined with its
|
|||
|
current state to come up with the new current state for the volume.
|
|||
|
If the two states cannot be reconciled then this routine returns FALSE
|
|||
|
indicating that the volume is invalid and should be broken into its
|
|||
|
constituant parts.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NewStateInstance - Supplies the new state instance.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
FT_VOLUME::~FT_VOLUME(
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Desctructor for FT_VOLUME.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
}
|