Leaked source code of windows server 2003
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.
 
 
 
 
 
 

377 lines
8.4 KiB

/*++
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);
}
}