|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
format.cpp
Abstract:
Routines to format volumes, using file-system information passed in. Uses undocumented fmifs calls.
Authors:
Steve DeVos (Veritas) (v-stevde) 15-May-1998 Guhan Suriyanarayanan (guhans) 21-Aug-1999
Environment:
User-mode only.
Revision History:
15-May-1998 v-stevde Initial creation 21-Aug-1999 guhans Cleaned up and re-wrote this module.
--*/
#include "stdafx.h"
#include <winioctl.h>
#include "fmifs.h"
#include "asr_fmt.h"
#include "asr_dlg.h"
BOOL g_bFormatInProgress = FALSE; BOOL g_bFormatSuccessful = FALSE; INT g_iFormatPercentComplete = 0;
HINSTANCE g_hIfsDll = NULL;
INT FormatVolumeThread(PASRFMT_VOLUME_INFO pVolume);
PFMIFS_FORMATEX_ROUTINE g_FormatRoutineEx = NULL;
BOOL FormatInitialise() { //
// Loadlib if needed
//
if (!g_hIfsDll) { g_hIfsDll = LoadLibrary(L"fmifs.dll"); if (!g_hIfsDll) { //
// FMIFS not available
//
return FALSE; }
g_FormatRoutineEx = (PFMIFS_FORMATEX_ROUTINE)GetProcAddress(g_hIfsDll, "FormatEx"); if (!g_FormatRoutineEx) { return FALSE; } }
return TRUE; }
BOOL IsFsTypeOkay( IN PASRFMT_VOLUME_INFO pVolume, OUT PBOOL pIsLabelIntact ) { WCHAR currentFSName[ASRFMT_CCH_FS_NAME]; WCHAR szVolumeGuid[ASRFMT_CCH_VOLUME_GUID]; WCHAR currentLabel[ASRFMT_CCH_VOLUME_LABEL];
DWORD cchGuid = 0; BOOL fsOkay = TRUE, result = TRUE; ASSERT(pIsLabelIntact);
ZeroMemory(currentFSName, sizeof(WCHAR) * ASRFMT_CCH_FS_NAME); *pIsLabelIntact = TRUE;
if (wcslen(pVolume->szGuid) >= ASRFMT_CCH_VOLUME_GUID) { return TRUE; // something's wrong with this GUID
}
if ((wcslen(pVolume->szFsName) <= 0)) { return TRUE; // no check for RAW volumes
}
//
// We don't want the "please insert floppy in drive A" messages ...
//
SetErrorMode(SEM_FAILCRITICALERRORS);
//
// GetVolumeInformation needs the volume guid in the dos-name-space, while the
// the sif file has the volume guid in the nt-name-space. Convert
// the name by changing the \??\ at the beginning to \\?\, and adding
// a back-slash at the end.
//
cchGuid = wcslen(pVolume->szGuid); wcsncpy(szVolumeGuid, pVolume->szGuid, cchGuid); szVolumeGuid[1] = L'\\'; szVolumeGuid[cchGuid] = L'\\'; // Trailing back-slash
szVolumeGuid[cchGuid+1] = L'\0';
fsOkay = TRUE; //
// Call GetVolumeInfo to see if the FS is the same
//
result = GetVolumeInformation(szVolumeGuid, currentLabel, // lpVolumeNameBuffer
ASRFMT_CCH_VOLUME_LABEL, // nVolumeNameSize
NULL, // lpVolumeSerialNumber
NULL, // lpMaximumComponentLength
NULL, // lpFileSystemFlags
currentFSName, ASRFMT_CCH_FS_NAME );
if ((!result) || wcscmp(currentFSName, pVolume->szFsName) ) { fsOkay = FALSE; *pIsLabelIntact = FALSE; }
if (wcscmp(currentLabel, pVolume->szLabel)) { *pIsLabelIntact = FALSE; }
/* if (fsOkay) {
//
//
// Call FindFirst in root to see if drive is readable.
// guhans: If drive is empty but formatted, this will still
// say fsOkay = FALSE;
//
hFindData = FindFirstFile(szPath, &win32FindData);
if (!hFindData || (INVALID_HANDLE_VALUE == hFindData)) { fsOkay = FALSE; } } */
return fsOkay;
}
BOOL IsVolumeIntact( IN PASRFMT_VOLUME_INFO pVolume ){
//
// Call autochk to see if the FS is intact
//
return TRUE; }
///
// Asynchronous function to launch the format routine.
//
BOOL FormatVolume( IN PASRFMT_VOLUME_INFO pVolume ) { HANDLE hThread = NULL;
//
// Set the global flags
//
g_bFormatInProgress = TRUE; g_bFormatSuccessful = TRUE; g_iFormatPercentComplete = 0;
//
// Loadlib if needed
//
if (!g_hIfsDll && !FormatInitialise()) { g_bFormatSuccessful = FALSE; g_bFormatInProgress = FALSE; return FALSE; }
hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) FormatVolumeThread, pVolume, 0, NULL ); if (!hThread || (INVALID_HANDLE_VALUE == hThread)) { g_bFormatSuccessful = FALSE; g_bFormatInProgress = FALSE; return FALSE; }
return TRUE; }
BOOL FormatCleanup() {
if (g_hIfsDll) { FreeLibrary(g_hIfsDll); g_hIfsDll = NULL; g_FormatRoutineEx = NULL; }
return TRUE; }
FmIfsCallback( IN FMIFS_PACKET_TYPE PacketType, IN DWORD PacketLength, IN PVOID PacketData ) {
switch (PacketType) { case FmIfsPercentCompleted: g_iFormatPercentComplete = ((PFMIFS_PERCENT_COMPLETE_INFORMATION)PacketData)->PercentCompleted ; break;
case FmIfsFormattingDestination: case FmIfsInsertDisk: case FmIfsFormatReport: case FmIfsHiddenStatus: default: break;
case FmIfsFinished: g_bFormatSuccessful = g_bFormatSuccessful && ((PFMIFS_FINISHED_INFORMATION) PacketData)->Success; g_iFormatPercentComplete = 101; g_bFormatInProgress = FALSE; break;
case FmIfsIncompatibleFileSystem: case FmIfsIncompatibleMedia: case FmIfsAccessDenied: case FmIfsMediaWriteProtected: case FmIfsCantLock: case FmIfsBadLabel: case FmIfsCantQuickFormat: case FmIfsIoError: case FmIfsVolumeTooSmall: case FmIfsVolumeTooBig: case FmIfsClusterSizeTooSmall: case FmIfsClusterSizeTooBig: g_bFormatSuccessful = FALSE; break; } return TRUE; }
INT FormatVolumeThread(PASRFMT_VOLUME_INFO pVolume) { WCHAR szPath[ASRFMT_CCH_DEVICE_PATH + 1];
swprintf(szPath, TEXT("\\\\?%s"), pVolume->szGuid+3);
(g_FormatRoutineEx)(szPath, FmMediaUnknown, pVolume->szFsName, pVolume->szLabel, #if 0
TRUE, // Quick Format for testing
#else
g_bQuickFormat, #endif
pVolume->dwClusterSize, (FMIFS_CALLBACK) &FmIfsCallback );
return TRUE; }
VOID MountFileSystem( IN PASRFMT_VOLUME_INFO pVolume ) /*++
(based on code in base\fs\utils\hsm\wsb\wsbfmt.cpp)
Routine Description:
Ensures a filesystem is mounted at the given root: a) Opens the mount point and closes it. b) Does a FindFirstFile on the mount point The latter may sound redundant but is not because if we create the first FAT32 filesystem then just opening and closing is not enough
Arguments:
Return Value: none
--*/ { WCHAR szPath[ASRFMT_CCH_DEVICE_PATH + 1]; HANDLE handle = NULL; WIN32_FIND_DATA win32FindData;
if (!pVolume) { ASSERT(0 && L"pVolume is NULL"); return; }
if (!memcmp(pVolume->szDosPath, ASRFMT_WSZ_DOS_DEVICES_PREFIX, ASRFMT_CB_DOS_DEVICES_PREFIX)) { swprintf(szPath, L"\\\\?\\%ws", pVolume->szDosPath + wcslen(ASRFMT_WSZ_DOS_DEVICES_PREFIX)); } else { swprintf(szPath, L"\\\\%ws", pVolume->szDosPath + 2); } handle = CreateFile( szPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 ); if ((handle) && (INVALID_HANDLE_VALUE != handle)) { CloseHandle(handle); }
//
// Try to find the first file, this will make sure that
// the file system is mounted
//
if (!memcmp(pVolume->szDosPath, ASRFMT_WSZ_DOS_DEVICES_PREFIX, ASRFMT_CB_DOS_DEVICES_PREFIX)) { swprintf(szPath, L"\\\\?\\%ws\\*", pVolume->szDosPath + wcslen(ASRFMT_WSZ_DOS_DEVICES_PREFIX)); } else { swprintf(szPath, L"\\\\%ws\\*", pVolume->szDosPath + 2); }
handle = FindFirstFile(szPath, &win32FindData); if ((handle) && (INVALID_HANDLE_VALUE != handle)) { FindClose(handle); }
}
|