Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

370 lines
8.8 KiB

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
cvthpfs.cxx
Abstract:
This module contains the declaration of ConvertHPFS, which is
the main entry point for this DLL.
Author:
Bill McJohn (billmc) 09-Jan-1992
Environment:
ULIB, User Mode
--*/
#include <pch.cxx>
#define _NTAPI_ULIB_
#include "ulib.hxx"
#include "message.hxx"
#include "rtmsg.h"
#include "drive.hxx"
#include "rwcache.hxx"
#include "intstack.hxx"
#include "numset.hxx"
#include "uhpfs.hxx"
#include "hpfsvol.hxx"
#include "hpfssa.hxx"
#include "cuhpfs.hxx"
#include "nametab.hxx"
DECLARE_CLASS( NAME_TABLE );
DECLARE_CLASS( NAME_LOOKUP_TABLE );
extern "C" BOOLEAN
InitializeCuhpfs (
PVOID DllHandle,
ULONG Reason,
PCONTEXT Context
)
/*++
Routine Description:
This function is the initialization entry point for CUHPFS.DLL.
At present, it's a null function, but this is where any initialization
goes if it's ever needed.
--*/
{
if( !DEFINE_CLASS_DESCRIPTOR( NAME_TABLE ) ||
!DEFINE_CLASS_DESCRIPTOR( NAME_LOOKUP_TABLE ) ) {
return FALSE;
}
return TRUE;
}
BOOLEAN
FAR APIENTRY
ConvertHPFSVolume(
IN PHPFS_VOL HpfsVolume,
IN PCWSTRING TargetFileSystem,
IN PCNAME_LOOKUP_TABLE NameTable,
IN OUT PMESSAGE Message,
IN BOOLEAN Verbose,
OUT PCONVERT_STATUS Status
)
/*++
Routine Description:
This function converts an opened HPFS Volume to a new file system.
Arguments:
Drive -- Supplies the drive to convert. Note that
it the caller must lock the drive (Convert)
or open it for exclusive write access
(Autoconvert).
TargetFileSystem -- Supplies the file system to which the drive
will be converted. Note that only "NTFS"
is presently supported.
Message -- Supplies an outlet for messages.
Verbose -- Supplies a flag indicating (if TRUE) that
conversion should be carried out in verbose mode.
Status -- Receives the status of the conversion.
--*/
{
PREAD_WRITE_CACHE RwCache;
NUMBER_SET BadSectorSet;
DSTRING FatString, HpfsString, NtfsString, CdfsString;
PHPFS_SA HpfsSuperArea;
PLBN BadLbnList;
ULONG NumberOfBadLbns, ActualNumberOfBadLbns, i;
BOOLEAN Result, Corrupt;
// Load in the read write cache.
if ((RwCache = NEW READ_WRITE_CACHE) &&
RwCache->Initialize( HpfsVolume, 75 )) {
HpfsVolume->SetCache(RwCache);
} else {
DELETE(RwCache);
}
// Check that this volume meets the requirements for conversion.
// It must be a clean HPFS volume with no hotfixes.
HpfsSuperArea = HpfsVolume->GetHPFSSuperArea();
if( !HpfsSuperArea->CheckSuperBlockSignatures() ) {
Message->Set( MSG_CONV_HPFS_NOT_HPFS );
Message->Display( "" );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
if( HpfsSuperArea->GetSuper()->QueryVersion() != SUPERB_VERSION ||
( HpfsSuperArea->GetSuper()->QueryFuncVersion() != SUPERB_FVERSION_2 &&
HpfsSuperArea->GetSuper()->QueryFuncVersion() != SUPERB_FVERSION_3 ) ) {
Message->Set( MSG_HPFS_CHKDSK_WRONG_VERSION );
Message->Display( "" );
return FALSE;
}
if( !HpfsSuperArea->IsClean() ) {
Message->Set( MSG_CONV_HPFS_DIRTY_VOLUME );
Message->Display( "" );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
if( HpfsSuperArea->GetSpare()->QueryHotFixCount() != 0 ||
HpfsSuperArea->GetSpare()->IsHotFixesUsed() ) {
Message->Set( MSG_CONV_HPFS_HOTFIXES_PRESENT );
Message->Display( "" );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
// Fetch the list of bad lbns and bundle them up into an intstack.
NumberOfBadLbns = HpfsSuperArea->GetSuper()->QueryBadSectors();
if( (BadLbnList = (PLBN)MALLOC( NumberOfBadLbns * sizeof(LBN) )) ==
NULL ) {
Message->Set( MSG_CONV_NO_MEMORY );
Message->Display( "" );
DebugPrint( "Insufficient memory.\n" );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
if( !HpfsSuperArea->QueryBadLbns( NumberOfBadLbns,
BadLbnList,
&ActualNumberOfBadLbns ) ) {
Message->Set( MSG_CONV_HPFS_CORRUPT_VOLUME );
Message->Display( "" );
FREE( BadLbnList );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
if( !BadSectorSet.Initialize() ) {
Message->Set( MSG_CONV_NO_MEMORY );
Message->Display( "" );
FREE( BadLbnList );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
for( i = 0; i < ActualNumberOfBadLbns; i++ ) {
if( !BadSectorSet.Add( BadLbnList[i] ) ) {
Message->Set( MSG_CONV_NO_MEMORY );
Message->Display( "" );
FREE( BadLbnList );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
}
// Tell the HPFS SuperArea to read its codepage information
if( !HpfsSuperArea->ReadCodepage() ) {
Message->Set( MSG_CONV_HPFS_CORRUPT_VOLUME );
Message->Display( "" );
FREE( BadLbnList );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
// Determine whether the target file system is supported. Set up
// a WSTRING for each recognized target file system.
if( !FatString.Initialize( "FAT" ) ||
!HpfsString.Initialize( "HPFS" ) ||
!NtfsString.Initialize( "NTFS" ) ||
!CdfsString.Initialize( "CDFS" ) ) {
Message->Set( MSG_CONV_NO_MEMORY );
Message->Display( "" );
FREE( BadLbnList );
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
if( *TargetFileSystem == NtfsString ) {
Result = ConvertToNtfs( HpfsVolume,
NameTable,
&BadSectorSet,
Message,
Verbose,
&Corrupt );
*Status = (Result) ? CONVERT_STATUS_CONVERTED : CONVERT_STATUS_ERROR;
if( !Result && Corrupt ) {
Message->Set( MSG_CONV_HPFS_CORRUPT_VOLUME );
Message->Display( "" );
}
} else if ( *TargetFileSystem == FatString ||
*TargetFileSystem == HpfsString ||
*TargetFileSystem == CdfsString ) {
// recognized but unsupported target
*Status = CONVERT_STATUS_CONVERSION_NOT_AVAILABLE;
Result = FALSE;
} else {
*Status = CONVERT_STATUS_INVALID_FILESYSTEM;
Result = FALSE;
}
FREE( BadLbnList );
return Result;
}
BOOLEAN
FAR APIENTRY
ConvertHPFS(
IN PCWSTRING NtDriveName,
IN PCWSTRING TargetFileSystem,
IN OUT PMESSAGE Message,
IN BOOLEAN Verbose,
OUT PCONVERT_STATUS Status
)
/*++
Routine Description:
This function converts an HPFS volume to the target file system
in-place.
This function opens and locks the volume, so it is not suitable
for use by autoconvert.
Arguments:
NtDriveName -- Supplies the name of the drive.
TargetFileSystem -- Supplies the file system to which the drive
will be converted. Note that only "NTFS"
is presently supported.
Message -- Supplies an outlet for messages.
Verbose -- Supplies a flag indicating (if TRUE) that
conversion should be carried out in verbose mode.
Status -- Receives the status of the conversion.
Return Value:
TRUE upon successful completion.
--*/
{
HPFS_VOL HpfsVolume;
DP_DRIVE DpDrive;
// Make sure that the volume does not have a queer sector size.
if (!DpDrive.Initialize(NtDriveName, Message)) {
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
if (DpDrive.QuerySectorSize() != 512) {
Message->Set(MSG_CONVERT_UNSUPPORTED_SECTOR_SIZE);
Message->Display("%W", TargetFileSystem);
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
// Initialize and lock the volume.
if( !HpfsVolume.Initialize( NtDriveName, Message )) {
*Status = CONVERT_STATUS_ERROR;
return FALSE;
}
// Lock the volume for exclusive access.
if( !HpfsVolume.Lock() ) {
*Status = CONVERT_STATUS_CANNOT_LOCK_DRIVE;
return FALSE;
}
return( ConvertHPFSVolume( &HpfsVolume,
TargetFileSystem,
NULL,
Message,
Verbose,
Status ) );
}