#include #include #include #include #include #include #include #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; }