windows-nt/Source/XPSP1/NT/base/fs/utils/mountvol/mountvol.c

360 lines
7.9 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#include <windows.h>
#include <stdio.h>
#include <msg.h>
HANDLE OutputFile;
BOOL IsConsoleOutput;
void
DisplayIt(
IN PWSTR Message
)
{
DWORD bytes, len;
PSTR message;
if (IsConsoleOutput) {
WriteConsole(OutputFile, Message, wcslen(Message),
&bytes, NULL);
} else {
len = wcslen(Message);
message = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
if (!message) {
return;
}
CharToOem(Message, message);
WriteFile(OutputFile, message, strlen(message), &bytes, NULL);
LocalFree(message);
}
}
void
PrintMessage(
DWORD messageID,
...
)
{
unsigned short messagebuffer[4096];
va_list ap;
va_start(ap, messageID);
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, NULL, messageID, 0,
messagebuffer, 4095, &ap);
DisplayIt(messagebuffer);
va_end(ap);
} // PrintMessage
void
PrintTargetForName(
IN PWSTR VolumeName
)
{
BOOL b;
DWORD len;
WCHAR messageBuffer[MAX_PATH];
PWSTR volumePaths, p;
PrintMessage(MOUNTVOL_VOLUME_NAME, VolumeName);
b = GetVolumePathNamesForVolumeName(VolumeName, NULL, 0, &len);
if (!b && GetLastError() != ERROR_MORE_DATA) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
messageBuffer, MAX_PATH, NULL);
DisplayIt(messageBuffer);
return;
}
volumePaths = LocalAlloc(0, len*sizeof(WCHAR));
if (!volumePaths) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
ERROR_NOT_ENOUGH_MEMORY, 0, messageBuffer, MAX_PATH,
NULL);
DisplayIt(messageBuffer);
return;
}
b = GetVolumePathNamesForVolumeName(VolumeName, volumePaths, len, NULL);
if (!b) {
LocalFree(volumePaths);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
messageBuffer, MAX_PATH, NULL);
DisplayIt(messageBuffer);
return;
}
if (!volumePaths[0]) {
PrintMessage(MOUNTVOL_NO_MOUNT_POINTS);
LocalFree(volumePaths);
return;
}
p = volumePaths;
for (;;) {
PrintMessage(MOUNTVOL_MOUNT_POINT, p);
while (*p++);
if (!*p) {
break;
}
}
LocalFree(volumePaths);
PrintMessage(MOUNTVOL_NEWLINE);
}
BOOL
GetSystemPartitionFromRegistry(
IN OUT PWCHAR SystemPartition
)
{
LONG r;
HKEY key;
DWORD bytes;
r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE,
&key);
if (r) {
SetLastError(r);
return FALSE;
}
bytes = MAX_PATH*sizeof(WCHAR);
r = RegQueryValueEx(key, L"SystemPartition", NULL, NULL,
(LPBYTE) SystemPartition, &bytes);
RegCloseKey(key);
if (r) {
SetLastError(r);
return FALSE;
}
return TRUE;
}
void
PrintMappedESP(
)
{
WCHAR systemPartition[MAX_PATH];
UCHAR c;
WCHAR dosDevice[10], dosTarget[MAX_PATH];
if (!GetSystemPartitionFromRegistry(systemPartition)) {
return;
}
dosDevice[1] = ':';
dosDevice[2] = 0;
for (c = 'A'; c <= 'Z'; c++) {
dosDevice[0] = c;
if (!QueryDosDevice(dosDevice, dosTarget, MAX_PATH)) {
continue;
}
if (lstrcmp(dosTarget, systemPartition)) {
continue;
}
dosDevice[2] = '\\';
dosDevice[3] = 0;
PrintMessage(MOUNTVOL_EFI, dosDevice);
break;
}
}
void
PrintVolumeList(
)
{
HANDLE h;
WCHAR volumeName[MAX_PATH];
WCHAR messageBuffer[MAX_PATH];
BOOL b;
h = FindFirstVolume(volumeName, MAX_PATH);
if (h == INVALID_HANDLE_VALUE) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
0, messageBuffer, MAX_PATH, NULL);
DisplayIt(messageBuffer);
return;
}
for (;;) {
PrintTargetForName(volumeName);
b = FindNextVolume(h, volumeName, MAX_PATH);
if (!b) {
break;
}
}
FindVolumeClose(h);
#if defined(_M_IA64)
PrintMappedESP();
#endif
}
BOOL
SetSystemPartitionDriveLetter(
IN PWCHAR DirName
)
/*++
Routine Description:
This routine will set the given drive letter to the system partition.
Arguments:
DirName - Supplies the drive letter directory name.
Return Value:
BOOL
--*/
{
WCHAR systemPartition[MAX_PATH];
if (!GetSystemPartitionFromRegistry(systemPartition)) {
return FALSE;
}
DirName[wcslen(DirName) - 1] = 0;
if (!DefineDosDevice(DDD_RAW_TARGET_PATH, DirName, systemPartition)) {
return FALSE;
}
return TRUE;
}
int __cdecl
main(
int argc,
char** argv
)
{
DWORD mode;
WCHAR dirName[MAX_PATH];
WCHAR volumeName[MAX_PATH];
DWORD dirLen, volumeLen;
BOOLEAN deletePoint, listPoint, systemPartition;
BOOL b;
WCHAR messageBuffer[MAX_PATH];
SetErrorMode(SEM_FAILCRITICALERRORS);
OutputFile = GetStdHandle(STD_OUTPUT_HANDLE);
IsConsoleOutput = GetConsoleMode(OutputFile, &mode);
if (argc != 3) {
PrintMessage(MOUNTVOL_USAGE1);
#if defined(_M_IA64)
PrintMessage(MOUNTVOL_USAGE1_IA64);
#endif
PrintMessage(MOUNTVOL_USAGE2);
#if defined(_M_IA64)
PrintMessage(MOUNTVOL_USAGE2_IA64);
#endif
PrintMessage(MOUNTVOL_START_OF_LIST);
PrintVolumeList();
return 0;
}
SetErrorMode(SEM_FAILCRITICALERRORS);
swprintf(dirName, L"%hs", argv[1]);
swprintf(volumeName, L"%hs", argv[2]);
dirLen = wcslen(dirName);
volumeLen = wcslen(volumeName);
if (argv[2][0] == '/' && argv[2][1] != 0 && argv[2][2] == 0) {
if (argv[2][1] == 'd' || argv[2][1] == 'D') {
deletePoint = TRUE;
listPoint = FALSE;
systemPartition = FALSE;
} else if (argv[2][1] == 'l' || argv[2][1] == 'L') {
deletePoint = FALSE;
listPoint = TRUE;
systemPartition = FALSE;
} else if (argv[2][1] == 's' || argv[2][1] == 'S') {
deletePoint = FALSE;
listPoint = FALSE;
systemPartition = TRUE;
} else {
deletePoint = FALSE;
listPoint = FALSE;
systemPartition = FALSE;
}
} else {
deletePoint = FALSE;
listPoint = FALSE;
systemPartition = FALSE;
}
if (dirName[dirLen - 1] != '\\') {
wcscat(dirName, L"\\");
dirLen++;
}
if (volumeName[volumeLen - 1] != '\\') {
wcscat(volumeName, L"\\");
volumeLen++;
}
if (deletePoint) {
b = DeleteVolumeMountPoint(dirName);
if (!b && GetLastError() == ERROR_INVALID_PARAMETER) {
dirName[dirLen - 1] = 0;
b = DefineDosDevice(DDD_REMOVE_DEFINITION, dirName, NULL);
}
} else if (listPoint) {
b = GetVolumeNameForVolumeMountPoint(dirName, volumeName, MAX_PATH);
if (b) {
PrintMessage(MOUNTVOL_VOLUME_NAME, volumeName);
}
} else if (systemPartition) {
b = SetSystemPartitionDriveLetter(dirName);
} else {
if (dirName[1] == ':' && dirName[2] == '\\' && !dirName[3]) {
dirName[2] = 0;
b = QueryDosDevice(dirName, messageBuffer, MAX_PATH);
if (b) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
ERROR_DIR_NOT_EMPTY, 0, messageBuffer, MAX_PATH,
NULL);
DisplayIt(messageBuffer);
return 1;
}
dirName[2] = '\\';
}
b = SetVolumeMountPoint(dirName, volumeName);
}
if (!b) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
messageBuffer, MAX_PATH, NULL);
DisplayIt(messageBuffer);
return 1;
}
return 0;
}