Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

271 lines
6.4 KiB

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_LENGTH 128
//
// This program is a hack until we have a proper GUI interface for mounting
// double space volumes.
//
// davidgoe [David Goebel] Oct 11, 1993.
//
VOID
__cdecl
main (argc, argv)
int argc;
char *argv[];
{
UCHAR DasdName[7] = "\\\\.\\";
UCHAR HostDrive[3];
UCHAR OemBuffer[13] = "DBLSPACE.";
ULONG SequenceNumber = 0;
BOOLEAN SetHostDrive = FALSE;
HANDLE Handle;
UCHAR TmpBuffer[BUFFER_LENGTH];
ULONG Length, i;
//
// Extract the parameters and check their validity.
//
if ((argc < 2) || (argc > 6) || ((argc & 1) != 0)) {
parameter_error:
printf("Syntax - %s Drive: [-h HostDrive:] [-s SequenceNumber]\n", argv[0]);
return;
}
argv[1][0] = toupper(argv[1][0]);
DasdName[4] = argv[1][0];
DasdName[5] = argv[1][1];
DasdName[6] = argv[1][2];
if ((DasdName[4] < 'A') || (DasdName[4] > 'Z') ||
(DasdName[5] != ':') ||
(DasdName[6] != 0)) {
goto parameter_error;
}
// temp, reject floppies.
/*
if (DasdName[4] < 'C') {
printf("%s does not currently support floppies.\n", argv[0]);
return;
}
*/
for (i = 2; i < (ULONG)argc; i+=2) {
if (argv[2][0] != '-') {
goto parameter_error;
} else {
PUCHAR LeftOver;
if (argv[i][2] != 0) {
goto parameter_error;
}
switch(argv[i][1]) {
case 'h':
case 'H':
argv[i+1][0] = toupper(argv[i+1][0]);
strncpy(HostDrive, argv[i+1], 3);
if ((HostDrive[0] < 'A') || (HostDrive[0] > 'Z') ||
(HostDrive[1] != ':') ||
(HostDrive[2] != 0)) {
printf("Illegal argument for 'HostDrive:' of %s.\n\n", argv[i+1]);
goto parameter_error;
}
SetHostDrive = TRUE;
break;
case 's':
case 'S':
SequenceNumber = strtol(argv[i+1], &LeftOver, 10);
if (*LeftOver != 0) {
printf("Illegal argument for 'SequenceNumber:' of %s.\n\n", argv[i+1]);
goto parameter_error;
}
if (SequenceNumber > 254) {
printf("Sequnce number must be in the range 0-254.\n");
goto parameter_error;
}
break;
default:
printf("Illegal option %s specifed.\n", argv[i]);
goto parameter_error;
}
}
}
//
// First check for a conflict on the host drive letter.
//
if (SetHostDrive && (QueryDosDevice(HostDrive, &TmpBuffer[0], BUFFER_LENGTH) != 0)) {
printf("Conflict with host drive. Drive %s already exists.\n", HostDrive);
goto parameter_error;
}
//
// Try to open the drive DASD.
//
Handle = CreateFile( DasdName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
0 );
if (Handle == INVALID_HANDLE_VALUE) {
printf("Open of %s failed with error %d.\n", argv[1], GetLastError());
printf("You must be administrator to run dsmount.\n");
return;
}
//
// Now build the unicode filename and attempt the mount.
//
{
OEM_STRING OemCvfName;
UNICODE_STRING UnicodeCvfName;
PFILE_MOUNT_DBLS_BUFFER MountFsctl;
UCHAR MountBuffer[sizeof(FILE_MOUNT_DBLS_BUFFER) + 12*sizeof(WCHAR)];
RXSTATUS Status;
IO_STATUS_BLOCK IoStatus;
MountFsctl = (PFILE_MOUNT_DBLS_BUFFER)MountBuffer;
sprintf(&OemBuffer[9], "%03d", SequenceNumber);
OemCvfName.Length =
OemCvfName.MaximumLength = 12;
OemCvfName.Buffer = OemBuffer;
UnicodeCvfName.MaximumLength = 13*sizeof(WCHAR);
UnicodeCvfName.Buffer = &MountFsctl->CvfName[0];
Status = RtlOemStringToUnicodeString( &UnicodeCvfName, &OemCvfName, FALSE );
if (!NT_SUCCESS(Status)) {
printf("Unicode conversion failed with error 0x%08lx.\n", Status);
CloseHandle( Handle);
return;
}
MountFsctl->CvfNameLength = UnicodeCvfName.Length;
//
// Now issue the DevIoCtrl.
//
Status = NtFsControlFile( Handle,
NULL,
NULL,
NULL,
&IoStatus,
FSCTL_MOUNT_DBLS_VOLUME,
MountFsctl,
64,
NULL,
0 );
if (!NT_SUCCESS(Status) || !NT_SUCCESS(IoStatus.Status)) {
if (NT_SUCCESS(Status)) {
Status = IoStatus.Status;
}
printf("Mount failed with error 0x%08lx.\n", Status);
CloseHandle( Handle);
return;
}
}
CloseHandle( Handle);
//
// First get the original base name.
//
Length = QueryDosDevice(argv[1], &TmpBuffer[0], BUFFER_LENGTH);
//
// Now make the host drive link.
//
if (SetHostDrive && !DefineDosDevice( DDD_RAW_TARGET_PATH, &HostDrive[0], &TmpBuffer[0] )) {
printf("Create Host Drive Failed with error: %d\n", GetLastError());
return;
}
//
// and finally create the compressed drive link.
//
TmpBuffer[Length-2] = '.';
RtlCopyMemory( &TmpBuffer[Length-1], OemBuffer, 13 );
if (!DefineDosDevice( DDD_RAW_TARGET_PATH, argv[1], &TmpBuffer[0] )) {
printf("Create Compressed Drive Failed with error: %d\n", GetLastError());
return;
}
//
// Tell the user what we did.
//
printf("The compressed volume file %s\\DBLSPACE.%03d was mounted as %s.\n",
argv[1], SequenceNumber, argv[1]);
if (SetHostDrive) {
printf("The host drive %s contains the original uncompressed volume.\n",
HostDrive);
} else {
printf("No host drive was specified, thus none was created.\n");
}
return;
}