📄 volume.cxx
字号:
/*++
Copyright (c) 1991-1999 Microsoft Corporation
Module Name:
volume.cxx
--*/
#include <pch.cxx>
#define _NTAPI_ULIB_
#define _IFSUTIL_MEMBER_
#include "ulib.hxx"
#include "ifsutil.hxx"
#include "error.hxx"
#include "volume.hxx"
#include "supera.hxx"
#include "hmem.hxx"
#include "message.hxx"
#include "rtmsg.h"
#include "ifsentry.hxx"
#if !defined(_EFICHECK_)
#include "autoreg.hxx"
#if !defined(_AUTOCHECK_)
#include "path.hxx"
#endif
extern "C" {
#if !defined(_AUTOCHECK_)
#include <stdio.h>
#endif // _AUTOCHECK_
#include "bootreg.h"
}
#endif // _EFICHECK_
DEFINE_EXPORTED_CONSTRUCTOR( VOL_LIODPDRV, LOG_IO_DP_DRIVE, IFSUTIL_EXPORT );
VOID
VOL_LIODPDRV::Construct (
)
/*++
Routine Description:
Constructor for VOL_LIODPDRV.
Arguments:
None.
Return Value:
None.
--*/
{
_sa = NULL;
}
IFSUTIL_EXPORT
VOL_LIODPDRV::~VOL_LIODPDRV(
)
/*++
Routine Description:
Destructor for VOL_LIODPDRV.
Arguments:
None.
Return Value:
None.
--*/
{
Destroy();
}
VOID
VOL_LIODPDRV::Destroy(
)
/*++
Routine Description:
This routine returns a VOL_LIODPDRV to its initial state.
Arguments:
None.
Return Value:
None.
--*/
{
_sa = NULL;
}
IFSUTIL_EXPORT
FORMAT_ERROR_CODE
VOL_LIODPDRV::Initialize(
IN PCWSTRING NtDriveName,
IN PSUPERAREA SuperArea,
IN OUT PMESSAGE Message,
IN BOOLEAN ExclusiveWrite,
IN BOOLEAN FormatMedia,
IN MEDIA_TYPE MediaType
)
/*++
Routine Description:
This routine initializes a VOL_LIODPDRV to a valid state.
Arguments:
NtDriveName - Supplies the drive path for the volume.
SuperArea - Supplies the superarea for the volume.
Message - Supplies an outlet for messages.
ExclusiveWrite - Supplies whether or not the drive should be
opened for exclusive write.
FormatMedia - Supplies whether or not to format the media.
MediaType - Supplies the type of media to format to.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
CONST MaxSectorsInVerify = 512;
BIG_INT chunk;
BIG_INT amount_to_verify;
BIG_INT i;
BIG_INT sectors;
ULONG percent;
FORMAT_ERROR_CODE errcode;
Destroy();
DebugAssert(NtDriveName);
DebugAssert(SuperArea);
#if defined(FE_SB) && defined(_X86_)
// PC98 Nov.01.1994
// We need to notify DP_DRIVE::Initialize() through ForceFormat()
// that we will format target madia.
if (IsPC98_N() && MediaType) {
ForceFormat(ANY);
}
#endif // JAPAN && _X86_
if (!LOG_IO_DP_DRIVE::Initialize(NtDriveName, Message, ExclusiveWrite)) {
return GeneralError;
}
if (!_bad_sectors.Initialize()) {
return GeneralError;
}
_sa = SuperArea;
// BUGBUG EFI can we ignore unknown media type?
// if (QueryMediaType() == Unknown && MediaType == Unknown) {
// Message ? Message->DisplayMsg(MSG_DISK_NOT_FORMATTED) : 1;
// return GeneralError;
// }
if (!FormatMedia &&
(QueryMediaType() == Unknown ||
(MediaType != Unknown && MediaType != QueryMediaType()))) {
Message ? Message->DisplayMsg(MSG_CANT_QUICKFMT) : 1;
if (Message ? Message->IsYesResponse(FALSE) : FALSE) {
FormatMedia = TRUE;
} else {
return GeneralError;
}
}
if (FormatMedia) {
if (!Lock()) {
// Message ? Message->DisplayMsg(MSG_CANT_LOCK_THE_DRIVE) : 1;
return LockError;
}
//
// We make a weird exception here for the Compaq 120MB floppy,
// because it wants to be formatted as if it were a hard disk.
//
if (IsFloppy() && MediaType != F3_120M_512) {
BOOLEAN rst;
#if !defined( _EFICHECK_ )
es_status = NtSetThreadExecutionState(ES_CONTINUOUS|
ES_DISPLAY_REQUIRED|
ES_SYSTEM_REQUIRED,
&prev_state);
if (!NT_SUCCESS(es_status)) {
DebugPrintTrace(("IFSUTIL: Unable to set thread execution state (%x)\n", es_status));
}
#endif
rst = FormatVerifyFloppy(MediaType, &_bad_sectors, Message);
#if !defined( _EFICHECK_ )
if (NT_SUCCESS(es_status)) {
es_status = NtSetThreadExecutionState(prev_state, &dummy_state);
if (!NT_SUCCESS(es_status)) {
DebugPrintTrace(("IFSUTIL: Unable to reset thread execution state (%x)\n", es_status));
}
}
#endif
if (!rst)
return GeneralError;
} else {
sectors = QuerySectors();
chunk = min( sectors/20 + 1, MaxSectorsInVerify );
percent = 0;
if (Message && !Message->DisplayMsg(MSG_PERCENT_COMPLETE, "%d", percent)) {
return GeneralError;
}
#if !defined(_EFICHECK_)
es_status = NtSetThreadExecutionState(ES_CONTINUOUS|
ES_DISPLAY_REQUIRED|
ES_SYSTEM_REQUIRED,
&prev_state);
if (!NT_SUCCESS(es_status)) {
DebugPrintTrace(("IFSUTIL: Unable to set thread execution state (%x)\n", es_status));
}
#endif
errcode = NoError;
for (i = 0; i < sectors; i += chunk) {
if ((i.GetLowPart() & 0x3ff) == 0) {
if (!Message->DisplayMsg(MSG_HIDDEN_STATUS, NORMAL_MESSAGE, 0)) {
errcode = GeneralError;
break;
}
}
if (i*100/sectors > percent) {
percent = ((i*100)/sectors).GetLowPart();
if (Message && !Message->DisplayMsg(MSG_PERCENT_COMPLETE, "%d", percent)) {
errcode = GeneralError;
break;
}
}
amount_to_verify = min(chunk, sectors - i);
if (!Verify(i, amount_to_verify, &_bad_sectors)) {
if (Message) {
Message->DisplayMsg( (QueryLastNtStatus() == STATUS_NO_MEDIA_IN_DEVICE) ?
MSG_FORMAT_NO_MEDIA_IN_DRIVE :
MSG_CHK_NO_MEMORY );
}
errcode = GeneralError;
break;
}
}
#if !defined(_EFICHECK_)
if (NT_SUCCESS(es_status)) {
es_status = NtSetThreadExecutionState(prev_state, &dummy_state);
if (!NT_SUCCESS(es_status)) {
DebugPrintTrace(("IFSUTIL: Unable to reset thread execution state (%x)\n", es_status));
}
}
#endif
if (errcode != NoError)
return errcode;
if (Message && !Message->DisplayMsg(MSG_PERCENT_COMPLETE, "%d", 100)) {
return GeneralError;
}
}
}
if (QuerySectors() == 0) {
DebugAbort("Sectors is 0");
return GeneralError;
}
return NoError;
}
IFSUTIL_EXPORT
BOOLEAN
VOL_LIODPDRV::Initialize(
IN PCWSTRING NtDriveName,
IN PCWSTRING HostFileName,
IN PSUPERAREA SuperArea,
IN OUT PMESSAGE Message,
IN BOOLEAN ExclusiveWrite
)
/*++
Routine Description:
This routine initializes a VOL_LIODPDRV for a hosted
volume, i.e. one that is implemented as a file on
another volume.
Arguments:
NtDriveName - Supplies the drive path for the volume.
HostFileName - Supplies the drive name for the host file.
SuperArea - Supplies the superarea for the volume.
Message - Supplies an outlet for messages.
ExclusiveWrite - Supplies whether or not the drive should be
opened for exclusive write.
Return Value:
TRUE upon successful completion.
--*/
{
Destroy();
DebugAssert(HostFileName);
DebugAssert(SuperArea);
if (!LOG_IO_DP_DRIVE::Initialize(NtDriveName,
HostFileName,
Message,
ExclusiveWrite)) {
return FALSE;
}
if (!_bad_sectors.Initialize()) {
return FALSE;
}
_sa = SuperArea;
return TRUE;
}
IFSUTIL_EXPORT
FORMAT_ERROR_CODE
VOL_LIODPDRV::Format(
IN PCWSTRING Label,
IN OUT PMESSAGE Message,
IN ULONG Flags,
IN ULONG ClusterSize,
IN ULONG VirtualSectors
)
/*++
Routine Description:
This routine formats a volume.
Arguments:
Label - Supplies an optional label for the volume.
Message - Supplies an outlet for messages.
flags - Supplies flags to control behavior of format
ClusterSize
- supplies the cluster size for the volume.
Return Value:
FALSE - Failure.
TRUE - Success.
--*/
{
MESSAGE msg;
if (!Message) {
Message = &msg;
}
if (!_sa) {
return GeneralError;
}
if (!Lock()) {
return LockError;
}
if (_sa->Create(&_bad_sectors,
Message, Label,
(Flags & FORMAT_BACKWARD_COMPATIBLE) ? TRUE : 0,
ClusterSize,
VirtualSectors)) {
if (!DismountAndUnlock()) {
return GeneralError;
} else {
PWSTRING pLabel;
DSTRING label;
NTSTATUS status;
pLabel = NULL;
while (!NT_SUCCESS(status = _sa->FormatNotification(pLabel))) {
if (status == STATUS_INVALID_VOLUME_LABEL) {
Message->Set(MSG_INVALID_LABEL_CHARACTERS);
Message->Display();
Message->Set(MSG_VOLUME_LABEL_PROMPT);
Message->Display();
Message->QueryStringInput(&label);
pLabel = &label;
} else {
return GeneralError;
}
}
return NoError;
}
} else
return GeneralError;
}
IFSUTIL_EXPORT
BOOLEAN
VOL_LIODPDRV::ChkDsk(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -