1308 lines
32 KiB
C++
1308 lines
32 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
convert.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the definition of the CONVERT class, which
|
|||
|
implements the File System Conversion Utility.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ramon J. San Andres (ramonsa) sep-23-1991
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
ULIB, User Mode
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#define _NTAPI_ULIB_
|
|||
|
#include "ulib.hxx"
|
|||
|
#include "ulibcl.hxx"
|
|||
|
#include "error.hxx"
|
|||
|
#include "arg.hxx"
|
|||
|
#include "file.hxx"
|
|||
|
#include "smsg.hxx"
|
|||
|
#include "rtmsg.h"
|
|||
|
#include "wstring.hxx"
|
|||
|
#include "system.hxx"
|
|||
|
#include "autoreg.hxx"
|
|||
|
#include "ifssys.hxx"
|
|||
|
#include "ifsentry.hxx"
|
|||
|
#include "convert.hxx"
|
|||
|
|
|||
|
extern "C" {
|
|||
|
#include <stdio.h>
|
|||
|
}
|
|||
|
|
|||
|
#include "fatofs.hxx"
|
|||
|
|
|||
|
ERRSTACK* perrstk;
|
|||
|
|
|||
|
|
|||
|
#define AUTOCHK_PROGRAM_NAME L"AUTOCHK.EXE"
|
|||
|
#define AUTOCONV_PROGRAM_NAME L"AUTOCONV.EXE"
|
|||
|
|
|||
|
#define AUTOCHK_NAME L"AUTOCHK"
|
|||
|
#define AUTOCONV_NAME L"AUTOCONV"
|
|||
|
|
|||
|
#define VALUE_NAME_PATH L"PATH"
|
|||
|
#define VALUE_NAME_ARGS L"ARGUMENTS"
|
|||
|
#define VALUE_NAME_FS L"TARGET FILESYSTEM"
|
|||
|
|
|||
|
//
|
|||
|
// Scheduling status codes
|
|||
|
//
|
|||
|
#define CONV_STATUS_NONE 0
|
|||
|
#define CONV_STATUS_SCHEDULED 1
|
|||
|
|
|||
|
static WCHAR NameBuffer[16]; // holds cvf name
|
|||
|
|
|||
|
|
|||
|
|
|||
|
INT _CRTAPI1
|
|||
|
main (
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Entry point for the conversion utility.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
One of the CONVERT exit codes.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
INT ExitCode = EXIT_ERROR; // Let's be pessimistic
|
|||
|
|
|||
|
DEFINE_CLASS_DESCRIPTOR( CONVERT );
|
|||
|
|
|||
|
{
|
|||
|
CONVERT Convert;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the CONVERT object.
|
|||
|
//
|
|||
|
if ( Convert.Initialize( &ExitCode ) ) {
|
|||
|
|
|||
|
//
|
|||
|
// Do the conversion
|
|||
|
//
|
|||
|
ExitCode = Convert.Convert();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return ExitCode;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DEFINE_CONSTRUCTOR( CONVERT, PROGRAM );
|
|||
|
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
CONVERT::Construct (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
converts a CONVERT object
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
_Autochk = NULL;
|
|||
|
_Autoconv = NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NONVIRTUAL
|
|||
|
VOID
|
|||
|
CONVERT::Destroy (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Destroys a CONVERT object
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DELETE( _Autochk );
|
|||
|
DELETE( _Autoconv );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CONVERT::~CONVERT (
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Destructs a CONVERT object
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
Destroy();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CONVERT::Initialize (
|
|||
|
OUT PINT ExitCode
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initializes the CONVERT object. Initialization consist of allocating memory
|
|||
|
for certain object members and argument parsing.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ExitCode - Supplies pointer to CONVERT exit code.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if initialization succeeded, FALSE otherwise.
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
Destroy();
|
|||
|
|
|||
|
//
|
|||
|
// Initialize program object
|
|||
|
//
|
|||
|
if ( PROGRAM::Initialize( MSG_CONV_USAGE ) ) {
|
|||
|
|
|||
|
//
|
|||
|
// Parse the arguments
|
|||
|
//
|
|||
|
return ParseArguments( ExitCode );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Could not initialize the program object.
|
|||
|
//
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN IsRestartFatToOfs( WSTRING const & CurrentFsName,
|
|||
|
WSTRING const & NtDriveName )
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Checks if a FAT->OFS convert is being restarted because of a failure
|
|||
|
after the Phase1. So, the currrent file system will be OFS but it is not
|
|||
|
fully converted/
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
CurrentFsName - Name of the current file system
|
|||
|
NtDriveName - NtStyle name of the drive to check.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if it is a restart of FAT->OFS. FALSE o/w
|
|||
|
|
|||
|
History:
|
|||
|
|
|||
|
Created Srikants August 24, 1995 (WIN95 launch day!!)
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DSTRING libraryName;
|
|||
|
DSTRING entryPoint;
|
|||
|
HANDLE fsUtilityHandle;
|
|||
|
|
|||
|
DSTRING Ofs;
|
|||
|
Ofs.Initialize("OFS");
|
|||
|
if ( 0 != Ofs.Stricmp(&CurrentFsName) ) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
libraryName.Initialize( FAT_TO_OFS_DLL_NAME );
|
|||
|
entryPoint.Initialize( FAT_TO_OFS_RESTART_FUNCTION_NAME );
|
|||
|
|
|||
|
FAT_OFS_RESTART_FN IsRestartFatOfs;
|
|||
|
|
|||
|
IsRestartFatOfs = (FAT_OFS_RESTART_FN)SYSTEM::QueryLibraryEntryPoint(
|
|||
|
&libraryName, &entryPoint, &fsUtilityHandle );
|
|||
|
|
|||
|
if ( NULL == IsRestartFatOfs )
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
PWSTR pwszNtDriveName = NtDriveName.QueryWSTR();
|
|||
|
BOOLEAN fResult= IsRestartFatOfs( pwszNtDriveName );
|
|||
|
|
|||
|
DELETE( pwszNtDriveName );
|
|||
|
SYSTEM::FreeLibraryHandle( fsUtilityHandle );
|
|||
|
|
|||
|
return fResult;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INT
|
|||
|
CONVERT::Convert (
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Converts the file system in a volume.
|
|||
|
Depending on the current file system, it loads the appropriate
|
|||
|
conversion library and calls its conversion entry point.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
INT - One of the CONVERT return codes
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DSTRING CurrentFsName; // Name of current FS in volume
|
|||
|
DSTRING LibraryName; // Name of library to load
|
|||
|
DSTRING EntryPoint; // Name of entry point in DLL
|
|||
|
FSTRING NameTableFnName; // Name of Name-Table construction fn
|
|||
|
INT ExitCode = EXIT_SUCCESS; // CONVERT exit code
|
|||
|
CONVERT_STATUS ConvertStatus; // Conversion status
|
|||
|
NTSTATUS Status; // NT API status
|
|||
|
HANDLE FsUtilityHandle; // Handle to DLL
|
|||
|
HANDLE CuDbfsHandle; // Handle to cudbfs.dll
|
|||
|
CONVERT_FN Convert; // Pointer to entry point in DLL
|
|||
|
NAMETABLE_FN ConstructNameTable; // Pointer to entry point in DLL
|
|||
|
CHECKSPACE_FN CheckSpace; // Pointer to entry point in DLL
|
|||
|
BOOLEAN ConvertDblsHost = TRUE;
|
|||
|
BOOLEAN Error = FALSE;
|
|||
|
BOOLEAN Success;
|
|||
|
BOOLEAN Result;
|
|||
|
|
|||
|
// Check to see if this is an ARC System Partition--if it
|
|||
|
// is, don't convert it.
|
|||
|
//
|
|||
|
if( IFS_SYSTEM::IsArcSystemPartition( &_NtDrive, &Error ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_ARC_SYSTEM_PARTITION, ERROR_MESSAGE );
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Ask the volume what file system it has, and use that name to
|
|||
|
// figure out what DLL to load.
|
|||
|
//
|
|||
|
if ( !IFS_SYSTEM::QueryFileSystemName( &_NtDrive,
|
|||
|
&CurrentFsName,
|
|||
|
&Status )) {
|
|||
|
|
|||
|
if ( Status == STATUS_ACCESS_DENIED ) {
|
|||
|
DisplayMessage( MSG_DASD_ACCESS_DENIED, ERROR_MESSAGE );
|
|||
|
} else {
|
|||
|
DisplayMessage( MSG_FS_NOT_DETERMINED, ERROR_MESSAGE, "%W", &_DosDrive );
|
|||
|
}
|
|||
|
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
// If the source and target file system are the same, there's
|
|||
|
// nothing to do. But if we're uncompressing, that's not true.
|
|||
|
//
|
|||
|
|
|||
|
if (_Restart) {
|
|||
|
if ( IsRestartFatToOfs( CurrentFsName, _NtDrive ) ) {
|
|||
|
CurrentFsName.Initialize("FAT");
|
|||
|
}
|
|||
|
else {
|
|||
|
//XXX.mjb: assume that we're restarting from NTFS to OFS.
|
|||
|
CurrentFsName.Initialize("NTFS");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if( CurrentFsName.Stricmp( &_FsName ) == 0) {
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
if (!_Uncompress) {
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
DisplayMessage( MSG_CONV_ALREADY_CONVERTED, ERROR_MESSAGE, "%W%W",
|
|||
|
&_DosDrive, &_FsName );
|
|||
|
return EXIT_ERROR;
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We're uncompressing, and we don't need to convert the
|
|||
|
// host filesystem.
|
|||
|
//
|
|||
|
|
|||
|
ConvertDblsHost = FALSE;
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
}
|
|||
|
|
|||
|
// Make sure that the target file system is enabled in the
|
|||
|
// registry.
|
|||
|
//
|
|||
|
if( !IFS_SYSTEM::IsFileSystemEnabled( &_FsName ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_FMT_INSTALL_FILE_SYSTEM, NORMAL_MESSAGE, "%W", &_FsName );
|
|||
|
|
|||
|
if( _Message.IsYesResponse(TRUE) ) {
|
|||
|
|
|||
|
if( IFS_SYSTEM::EnableFileSystem( &_FsName ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_FMT_FILE_SYSTEM_INSTALLED );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
DisplayMessage( MSG_FMT_CANT_INSTALL_FILE_SYSTEM, ERROR_MESSAGE );
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
if (_Uncompress) {
|
|||
|
//
|
|||
|
// Make sure the indicated cvf exists before we try to do
|
|||
|
// anything.
|
|||
|
//
|
|||
|
|
|||
|
DSTRING CvfPath;
|
|||
|
DSTRING backslash;
|
|||
|
|
|||
|
if (!backslash.Initialize("\\")) {
|
|||
|
DisplayMessage(MSG_CONV_NO_MEMORY, ERROR_MESSAGE);
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
if (!CvfPath.Initialize(&_DosDrive) ||
|
|||
|
!CvfPath.Strcat(&backslash) ||
|
|||
|
!CvfPath.Strcat(&_CvfName)) {
|
|||
|
DisplayMessage(MSG_CONV_NO_MEMORY, ERROR_MESSAGE);
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
if (0xffffffff == GetFileAttributes(CvfPath.GetWSTR())) {
|
|||
|
if (ERROR_FILE_NOT_FOUND == GetLastError()) {
|
|||
|
DisplayMessage(MSG_DBLSPACE_NO_SUCH_FILE, ERROR_MESSAGE,
|
|||
|
"%W", &CvfPath);
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
//
|
|||
|
// Display the current file system type. (Standard in all file system utilities)
|
|||
|
//
|
|||
|
DisplayMessage( MSG_FILE_SYSTEM_TYPE, NORMAL_MESSAGE, "%W", &CurrentFsName );
|
|||
|
|
|||
|
if (ConvertDblsHost) {
|
|||
|
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
|
|||
|
if (_Uncompress) {
|
|||
|
if (!LibraryName.Initialize("CNVDBFS") ||
|
|||
|
!EntryPoint.Initialize("CheckFreeSpaceDBFS")) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
if (NULL == (CheckSpace = (CHECKSPACE_FN)SYSTEM::
|
|||
|
QueryLibraryEntryPoint(&LibraryName, &EntryPoint,
|
|||
|
&CuDbfsHandle))) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
Success = CheckSpace(&_NtDrive, &_CvfName, &_Message, _Verbose,
|
|||
|
_Compress, /* HostIsCompressed */
|
|||
|
TRUE /* WillConvertHost */
|
|||
|
);
|
|||
|
|
|||
|
SYSTEM::FreeLibraryHandle( CuDbfsHandle );
|
|||
|
|
|||
|
if (!Success) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
//
|
|||
|
// Depending on the current file system, form the name of the conversion
|
|||
|
// DLL in charge of converting that file system. The name of the
|
|||
|
// conversion library is the name of the file system prefixed with "CNV"
|
|||
|
// eg FAT->CNVFAT, HPFS->CNVHPFS
|
|||
|
//
|
|||
|
// We also initialize the name of the conversion entry point in the DLL
|
|||
|
// ("Convert")
|
|||
|
//
|
|||
|
if ( !LibraryName.Initialize( "CNV" ) ||
|
|||
|
!LibraryName.Strcat( &CurrentFsName ) ||
|
|||
|
!EntryPoint.Initialize( "Convert" ) ||
|
|||
|
!EntryPoint.Strcat( &CurrentFsName )
|
|||
|
) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
return( EXIT_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get pointer to the conversion entry point and convert the volume.
|
|||
|
//
|
|||
|
if (NULL == (Convert = (CONVERT_FN)SYSTEM::QueryLibraryEntryPoint(
|
|||
|
&LibraryName, &EntryPoint, &FsUtilityHandle ))) {
|
|||
|
//
|
|||
|
// There is no conversion DLL for the file system in the volume.
|
|||
|
//
|
|||
|
DisplayMessage( MSG_FS_NOT_SUPPORTED, ERROR_MESSAGE, "%s%W",
|
|||
|
"CONVERT", &CurrentFsName );
|
|||
|
DisplayMessage( MSG_BLANK_LINE, ERROR_MESSAGE );
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
Result = Convert( &_NtDrive,
|
|||
|
&_FsName,
|
|||
|
&_Message,
|
|||
|
_Verbose,
|
|||
|
FALSE, /* Pause */
|
|||
|
&ConvertStatus);
|
|||
|
|
|||
|
SYSTEM::FreeLibraryHandle( FsUtilityHandle );
|
|||
|
|
|||
|
if( Result ) {
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
if (!_Uncompress) {
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
//
|
|||
|
// We're done.
|
|||
|
//
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_CONVERSION_COMPLETE, NORMAL_MESSAGE );
|
|||
|
return EXIT_SUCCESS;
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
}
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// The conversion was not successful. Determine what the problem
|
|||
|
// was and return the appropriate CONVERT exit code.
|
|||
|
//
|
|||
|
switch ( ConvertStatus ) {
|
|||
|
|
|||
|
case CONVERT_STATUS_CONVERTED:
|
|||
|
//
|
|||
|
// This is an inconsistent state, Convert should return
|
|||
|
// TRUE if the conversion was successful!
|
|||
|
//
|
|||
|
DebugPrintf( "CONVERT Error: Conversion failed, but status is success!\n" );
|
|||
|
DebugAssert( FALSE );
|
|||
|
ExitCode = EXIT_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
case CONVERT_STATUS_INVALID_FILESYSTEM:
|
|||
|
//
|
|||
|
// The conversion DLL does not recognize the target file system.
|
|||
|
//
|
|||
|
DisplayMessage( MSG_CONV_INVALID_FILESYSTEM, ERROR_MESSAGE, "%W", &_FsName );
|
|||
|
ExitCode = EXIT_UNKNOWN;
|
|||
|
break;
|
|||
|
|
|||
|
case CONVERT_STATUS_CONVERSION_NOT_AVAILABLE:
|
|||
|
//
|
|||
|
// The target file system is valid, but the conversion is not
|
|||
|
// available.
|
|||
|
//
|
|||
|
DisplayMessage( MSG_CONV_CONVERSION_NOT_AVAILABLE, ERROR_MESSAGE,
|
|||
|
"%W%W", &CurrentFsName, &_FsName );
|
|||
|
ExitCode = EXIT_NOCANDO;
|
|||
|
break;
|
|||
|
|
|||
|
case CONVERT_STATUS_CANNOT_LOCK_DRIVE:
|
|||
|
//
|
|||
|
// The drive cannot be locked. We must schedule ChkDsk and AutoConv
|
|||
|
// to do the job during the next system boot.
|
|||
|
//
|
|||
|
|
|||
|
if( _NameTable.QueryChCount() ) {
|
|||
|
|
|||
|
NameTableFnName.Initialize( L"ConstructNameTable" );
|
|||
|
|
|||
|
ConstructNameTable = (NAMETABLE_FN)
|
|||
|
SYSTEM::QueryLibraryEntryPoint( &LibraryName,
|
|||
|
&NameTableFnName,
|
|||
|
&FsUtilityHandle );
|
|||
|
|
|||
|
if( ConstructNameTable == NULL ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_NAME_TABLE_NOT_SUPPORTED,
|
|||
|
ERROR_MESSAGE,
|
|||
|
"%W",
|
|||
|
&_FsName );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
ConstructNameTable( &_NtDrive, &_NameTable, &_Message );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DisplayMessage( MSG_CONVERT_ON_REBOOT_PROMPT, NORMAL_MESSAGE, "%W",
|
|||
|
&_DosDrive );
|
|||
|
|
|||
|
// Note that ScheduleAutoConv reports its success or
|
|||
|
// failure, so no additional messages are required.
|
|||
|
//
|
|||
|
if( _Message.IsYesResponse( FALSE ) &&
|
|||
|
ScheduleAutoConv() ) {
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
if (_Uncompress) {
|
|||
|
DisplayMessage(MSG_DBLCONV_AGAIN, NORMAL_MESSAGE);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
ExitCode = EXIT_SCHEDULED;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
ExitCode = EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case CONVERT_STATUS_ERROR:
|
|||
|
//
|
|||
|
// The conversion failed.
|
|||
|
//
|
|||
|
DisplayMessage( MSG_CONV_CONVERSION_FAILED, ERROR_MESSAGE,
|
|||
|
"%W%W", &_DosDrive, &_FsName );
|
|||
|
ExitCode = EXIT_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
//
|
|||
|
// Invalid status code
|
|||
|
//
|
|||
|
DebugPrintf( "CONVERT Error: Convert status code %X invalid!\n",
|
|||
|
ConvertStatus );
|
|||
|
DisplayMessage( MSG_CONV_CONVERSION_FAILED, ERROR_MESSAGE,
|
|||
|
"%W%W", &_DosDrive, &_FsName );
|
|||
|
ExitCode = EXIT_ERROR;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return ExitCode;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
//
|
|||
|
// Uncompress the cvf named by _CvfName.
|
|||
|
//
|
|||
|
|
|||
|
if (!LibraryName.Initialize("CNVDBFS") ||
|
|||
|
!EntryPoint.Initialize("CheckFreeSpaceDBFS")) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
if (_Compress) {
|
|||
|
//
|
|||
|
// Indicate that the files we're about to create should
|
|||
|
// be compressed.
|
|||
|
//
|
|||
|
|
|||
|
if (!IFS_SYSTEM::EnableVolumeCompression(&_NtDrive)) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!ConvertDblsHost) {
|
|||
|
|
|||
|
if (NULL == (CheckSpace = (CHECKSPACE_FN)SYSTEM::QueryLibraryEntryPoint(
|
|||
|
&LibraryName, &EntryPoint, &CuDbfsHandle))) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
Success = CheckSpace(&_NtDrive, &_CvfName, &_Message, _Verbose,
|
|||
|
FALSE, /* HostIsCompressed */
|
|||
|
TRUE /* WillConvertHost */
|
|||
|
);
|
|||
|
|
|||
|
SYSTEM::FreeLibraryHandle( CuDbfsHandle );
|
|||
|
|
|||
|
if (!Success) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!EntryPoint.Initialize("ConvertDBFS")) {
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
if (NULL == (Convert = (CONVERT_FN)SYSTEM::QueryLibraryEntryPoint(
|
|||
|
&LibraryName, &EntryPoint, &CuDbfsHandle))) {
|
|||
|
|
|||
|
return EXIT_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
DisplayMessage( MSG_DBLSPACE_UNCOMPRESSING, NORMAL_MESSAGE );
|
|||
|
|
|||
|
if (Convert(&_NtDrive, &_CvfName, &_Message, _Verbose,
|
|||
|
&ConvertStatus)) {
|
|||
|
ExitCode = EXIT_SUCCESS;
|
|||
|
} else {
|
|||
|
|
|||
|
if (CONVERT_STATUS_INSUFFICIENT_SPACE == ConvertStatus) {
|
|||
|
DisplayMessage( MSG_DBLCONV_SPACE_EXHAUSTED, ERROR_MESSAGE );
|
|||
|
}
|
|||
|
|
|||
|
ExitCode = EXIT_ERROR;
|
|||
|
}
|
|||
|
SYSTEM::FreeLibraryHandle( CuDbfsHandle );
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_CONVERSION_COMPLETE, NORMAL_MESSAGE );
|
|||
|
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
return ExitCode;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PPATH
|
|||
|
CONVERT::FindSystemFile(
|
|||
|
IN PWSTR FileName
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Makes sure that the given file is in the system directory.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
FileName - Supplies the name of the file to look for.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
PPATH - Path to the file found
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
DSTRING Name;
|
|||
|
PPATH Path = NULL;
|
|||
|
PFSN_FILE File = NULL;
|
|||
|
|
|||
|
|
|||
|
if ( !(Path = SYSTEM::QuerySystemDirectory() ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_CANNOT_FIND_SYSTEM_DIR, ERROR_MESSAGE );
|
|||
|
return FALSE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( !Name.Initialize( FileName ) ||
|
|||
|
!Path->AppendBase( &Name ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
DELETE( Path );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( !(File = SYSTEM::QueryFile( Path )) ) {
|
|||
|
DisplayMessage( MSG_CONV_CANNOT_FIND_FILE, ERROR_MESSAGE, "%W", Path->GetPathString() );
|
|||
|
DELETE( Path );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
DELETE( File );
|
|||
|
|
|||
|
return Path;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CONVERT::ParseArguments(
|
|||
|
OUT PINT ExitCode
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Parses the command line and sets the parameters used by the conversion
|
|||
|
utility.
|
|||
|
|
|||
|
The arguments accepted are:
|
|||
|
|
|||
|
drive: Drive to convert
|
|||
|
/fs:fsname File system to convert to
|
|||
|
/v Verbose mode
|
|||
|
/uncompress uncompress a cvf after converting
|
|||
|
/c Compress the resulting filesystem
|
|||
|
/? Help
|
|||
|
/NAMETABLE:filename Filename for name translation table.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ExitCode - Supplies pointer to CONVERT exit code
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if arguments were parsed correctly and program can
|
|||
|
continue.
|
|||
|
FALSE if the program should exit. ExitCode contains the
|
|||
|
value with which the program should exit. Note that this
|
|||
|
does not necessarily means an error (e.g. user requested
|
|||
|
help).
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DSTRING Colon;
|
|||
|
UCHAR SequenceNumber;
|
|||
|
|
|||
|
DebugPtrAssert( ExitCode );
|
|||
|
|
|||
|
//
|
|||
|
// Parse command line
|
|||
|
//
|
|||
|
if ( !Colon.Initialize( (LPWSTR)L":" ) ||
|
|||
|
!ParseCommandLine( NULL, TRUE ) ) {
|
|||
|
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the user requested help, give it.
|
|||
|
//
|
|||
|
if( _Help ) {
|
|||
|
DisplayMessage( MSG_CONV_USAGE );
|
|||
|
*ExitCode = EXIT_SUCCESS;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
if (_Compress && !_Uncompress) {
|
|||
|
//
|
|||
|
// We don't allow you to specify /c (compress resulting
|
|||
|
// filesystem) unless the source filesystem has dblspace.
|
|||
|
//
|
|||
|
|
|||
|
DisplayMessage(MSG_CONV_SLASH_C_INVALID, ERROR_MESSAGE);
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
//
|
|||
|
// If the command line did not specify a drive, we use the
|
|||
|
// current drive.
|
|||
|
//
|
|||
|
if ( _DosDrive.QueryChCount() > 0 ) {
|
|||
|
|
|||
|
if ( !_DosDrive.Strcat( &Colon ) ||
|
|||
|
!_DosDrive.Strupr()) {
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
if ( !SYSTEM::QueryCurrentDosDriveName( &_DosDrive ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make sure that drive is valid and is not remote.
|
|||
|
//
|
|||
|
switch ( SYSTEM::QueryDriveType( &_DosDrive ) ) {
|
|||
|
|
|||
|
case UnknownDrive:
|
|||
|
DisplayMessage( MSG_CONV_INVALID_DRIVE, ERROR_MESSAGE, "%W", &_DosDrive );
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
|
|||
|
case RemoteDrive:
|
|||
|
DisplayMessage( MSG_CONV_CANT_NETWORK, ERROR_MESSAGE );
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Make sure a target file system was specified. Note that we do not
|
|||
|
// validate the file system, we accept any string.
|
|||
|
//
|
|||
|
if ( _FsName.QueryChCount() == 0 ) {
|
|||
|
DisplayMessage( MSG_CONV_NO_FILESYSTEM_SPECIFIED, ERROR_MESSAGE );
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Set other object members.
|
|||
|
//
|
|||
|
if ( !IFS_SYSTEM::DosDriveNameToNtDriveName( &_DosDrive, &_NtDrive )) {
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
//
|
|||
|
// If we're to uncompress a dblspace volume, generate the cvf name.
|
|||
|
//
|
|||
|
|
|||
|
if (_Uncompress) {
|
|||
|
swprintf(NameBuffer, L"DBLSPACE.%03d", SequenceNumber);
|
|||
|
|
|||
|
if (!_CvfName.Initialize(NameBuffer)) {
|
|||
|
DisplayMessage(MSG_CONV_NO_MEMORY, ERROR_MESSAGE);
|
|||
|
*ExitCode = EXIT_ERROR;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
*ExitCode = EXIT_SUCCESS;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CONVERT::ParseCommandLine (
|
|||
|
IN PCWSTRING CommandLine,
|
|||
|
IN BOOLEAN Interactive
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Parses the CONVERT (AUTOCONV) command line.
|
|||
|
|
|||
|
The arguments accepted are:
|
|||
|
|
|||
|
drive: Drive to convert
|
|||
|
/fs:fsname File system to convert to
|
|||
|
/v Verbose mode
|
|||
|
/uncompress[:sss] Convert from dblspace
|
|||
|
/c Compress resulting filesystem
|
|||
|
/? Help
|
|||
|
/NAMETABLE:filename Filename for name translation table
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
CommandLine - Supplies command line to parse
|
|||
|
Interactive - Supplies Interactive flag
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if arguments were parsed correctly.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ARRAY ArgArray; // Array of arguments
|
|||
|
ARRAY LexArray; // Array of lexemes
|
|||
|
ARGUMENT_LEXEMIZER ArgLex; // Argument Lexemizer
|
|||
|
STRING_ARGUMENT DriveArgument; // Drive argument
|
|||
|
STRING_ARGUMENT ProgramNameArgument; // Program name argument
|
|||
|
STRING_ARGUMENT FsNameArgument; // Target FS name argument
|
|||
|
STRING_ARGUMENT NameTableArgument; // Name Table file name
|
|||
|
FLAG_ARGUMENT HelpArgument; // Help flag argument
|
|||
|
FLAG_ARGUMENT VerboseArgument; // Verbose flag argument
|
|||
|
FLAG_ARGUMENT RestartArgument; // Restart (/r) flag argument
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
FLAG_ARGUMENT UncompressArgument; // Uncompress flag argument
|
|||
|
FLAG_ARGUMENT CompressArgument; // Compress flag argument
|
|||
|
LONG_ARGUMENT UncompressNumberArgument;// Sequence number argument
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
PWSTRING InvalidArg; // Invalid argument catcher
|
|||
|
DSTRING Colon; // Colon
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Initialize all the argument parsing machinery.
|
|||
|
//
|
|||
|
if( !Colon.Initialize( ":" ) ||
|
|||
|
!ArgArray.Initialize( 7, 1 ) ||
|
|||
|
!LexArray.Initialize( 7, 1 ) ||
|
|||
|
!ArgLex.Initialize( &LexArray ) ||
|
|||
|
!DriveArgument.Initialize( "*:" ) ||
|
|||
|
!HelpArgument.Initialize( "/?" ) ||
|
|||
|
!RestartArgument.Initialize( "/R" ) ||
|
|||
|
!VerboseArgument.Initialize( "/V" ) ||
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
!CompressArgument.Initialize( "/C" ) ||
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
!ProgramNameArgument.Initialize( "*" ) ||
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
!UncompressArgument.Initialize( "/UNCOMPRESS" ) ||
|
|||
|
!UncompressNumberArgument.Initialize( "/UNCOMPRESS:*" ) ||
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
!FsNameArgument.Initialize( "/FS:*" ) ||
|
|||
|
!NameTableArgument.Initialize( "/NAMETABLE:*" ) ) {
|
|||
|
|
|||
|
if ( Interactive ) {
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The conversion utility is case-insensitive
|
|||
|
//
|
|||
|
ArgLex.SetCaseSensitive( FALSE );
|
|||
|
|
|||
|
if( !ArgArray.Put( &DriveArgument ) ||
|
|||
|
!ArgArray.Put( &HelpArgument ) ||
|
|||
|
!ArgArray.Put( &VerboseArgument ) ||
|
|||
|
!ArgArray.Put( &RestartArgument ) ||
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
!ArgArray.Put( &CompressArgument ) ||
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
!ArgArray.Put( &ProgramNameArgument ) ||
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
!ArgArray.Put( &UncompressArgument ) ||
|
|||
|
!ArgArray.Put( &UncompressNumberArgument ) ||
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
!ArgArray.Put( &FsNameArgument ) ||
|
|||
|
!ArgArray.Put( &NameTableArgument ) ) {
|
|||
|
|
|||
|
if ( Interactive ) {
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Lexemize the command line.
|
|||
|
//
|
|||
|
if ( !ArgLex.PrepareToParse( (PWSTRING)CommandLine ) ) {
|
|||
|
|
|||
|
if ( Interactive ) {
|
|||
|
DisplayMessage( MSG_CONV_NO_MEMORY, ERROR_MESSAGE );
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Parse the arguments.
|
|||
|
//
|
|||
|
if( !ArgLex.DoParsing( &ArgArray ) ) {
|
|||
|
|
|||
|
if ( Interactive ) {
|
|||
|
DisplayMessage( MSG_CONV_INVALID_PARAMETER, ERROR_MESSAGE, "%W", InvalidArg = ArgLex.QueryInvalidArgument() );
|
|||
|
DELETE( InvalidArg );
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
_Help = HelpArgument.QueryFlag();
|
|||
|
_Verbose = VerboseArgument.QueryFlag();
|
|||
|
_Restart = RestartArgument.QueryFlag();
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
_Compress = CompressArgument.QueryFlag();
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
|
|||
|
if ( DriveArgument.IsValueSet() ) {
|
|||
|
if ( !_DosDrive.Initialize( DriveArgument.GetString() ) ) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
if ( !_DosDrive.Initialize( L"" ) ) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( FsNameArgument.IsValueSet() ) {
|
|||
|
if ( !_FsName.Initialize( FsNameArgument.GetString() ) ) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
} else {
|
|||
|
if ( !_FsName.Initialize( L"" ) ) {
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if( NameTableArgument.IsValueSet() ) {
|
|||
|
|
|||
|
if( !_NameTable.Initialize( NameTableArgument.GetString() ) ) {
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
_NameTable.Initialize( L"" );
|
|||
|
}
|
|||
|
|
|||
|
#ifdef DBLSPACE_ENABLED
|
|||
|
_SequenceNumber = 0;
|
|||
|
|
|||
|
_Uncompress = FALSE;
|
|||
|
if (UncompressArgument.IsValueSet()) {
|
|||
|
_Uncompress = TRUE;
|
|||
|
}
|
|||
|
if (UncompressNumberArgument.IsValueSet()) {
|
|||
|
_SequenceNumber = (UCHAR)UncompressNumberArgument.QueryLong();
|
|||
|
_Uncompress = TRUE;
|
|||
|
}
|
|||
|
#endif // DBLSPACE_ENABLED
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CONVERT::Schedule (
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Schedules AutoConv
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if AutoConv successfully scheduled.
|
|||
|
FALSE otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING CommandLine;
|
|||
|
DSTRING Space;
|
|||
|
DSTRING FileSystem;
|
|||
|
DSTRING NameTableFlag;
|
|||
|
|
|||
|
if( !CommandLine.Initialize( (LPWSTR)L"autocheck autoconv " ) ||
|
|||
|
!Space.Initialize( (LPWSTR)L" " ) ||
|
|||
|
!FileSystem.Initialize( (LPWSTR)L"/FS:" ) ||
|
|||
|
!CommandLine.Strcat( &_NtDrive ) ||
|
|||
|
!CommandLine.Strcat( &Space ) ||
|
|||
|
!CommandLine.Strcat( &FileSystem ) ||
|
|||
|
!CommandLine.Strcat( &_FsName ) ) {
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if( _NameTable.QueryChCount() &&
|
|||
|
( !CommandLine.Strcat( &Space ) ||
|
|||
|
!NameTableFlag.Initialize( L"/NAMETABLE:" ) ||
|
|||
|
!CommandLine.Strcat( &NameTableFlag ) ||
|
|||
|
!CommandLine.Strcat( &_NameTable ) ) ) {
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
return( AUTOREG::AddEntry( &CommandLine ) );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CONVERT::ScheduleAutoConv(
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Schedules AutoConv to be invoked during boot the next time
|
|||
|
that the machine reboots.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN - TRUE if AutoConv successfully scheduled.
|
|||
|
FALSE otherwise
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ARRAY EntryArray;
|
|||
|
PITERATOR Iterator = NULL;
|
|||
|
BOOLEAN Ok = TRUE;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Make sure that Autochk.exe and Autoconv.exe are in the
|
|||
|
// right place.
|
|||
|
//
|
|||
|
if ( !(_Autochk = FindSystemFile( (LPWSTR)AUTOCHK_PROGRAM_NAME )) ||
|
|||
|
!(_Autoconv = FindSystemFile( (LPWSTR)AUTOCONV_PROGRAM_NAME )) ) {
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
// See if this conversion has already been scheduled:
|
|||
|
//
|
|||
|
if ( IsAutoConvScheduled( ) ) {
|
|||
|
|
|||
|
DisplayMessage( MSG_CONV_ALREADY_SCHEDULED, ERROR_MESSAGE, "%W", &_DosDrive );
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// schedule autoconvert
|
|||
|
//
|
|||
|
if ( Ok = Schedule( ) ) {
|
|||
|
DisplayMessage( MSG_CONV_WILL_CONVERT_ON_REBOOT, NORMAL_MESSAGE, "%W", &_DosDrive );
|
|||
|
} else {
|
|||
|
DisplayMessage( MSG_CONV_CANNOT_SCHEDULE, ERROR_MESSAGE );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
return Ok;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
CONVERT::IsAutoConvScheduled(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines if an AutoEntry contains a scheduled AUTOCONV for this
|
|||
|
drive.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Entry - AutoEntry to be inspected
|
|||
|
FileSystem - File system to be converted to,
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DSTRING CommandLine;
|
|||
|
DSTRING Space;
|
|||
|
DSTRING FileSystem;
|
|||
|
|
|||
|
return (BOOLEAN)
|
|||
|
( CommandLine.Initialize( (LPWSTR)L"autocheck autoconv " ) &&
|
|||
|
Space.Initialize( (LPWSTR)L" " ) &&
|
|||
|
FileSystem.Initialize( (LPWSTR)L"/FS:" ) &&
|
|||
|
CommandLine.Strcat( &_NtDrive ) &&
|
|||
|
CommandLine.Strcat( &Space ) &&
|
|||
|
CommandLine.Strcat( &FileSystem ) &&
|
|||
|
CommandLine.Strcat( &_FsName ) &&
|
|||
|
AUTOREG::IsEntryPresent( &CommandLine ) );
|
|||
|
|
|||
|
}
|