📄 vd.c
字号:
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <string.h>
#include "vd.h"
void PrintLastError(const TCHAR *);
void Usage();
void MountDisk(POPEN_FILE_INFORMATION, char);
void UmountDisk(char);
void QueryDisk(char);
int main(int argc, char ** argv)
{
POPEN_FILE_INFORMATION openFileInformation = NULL;
char driveLetter;
if(argc >= 2)
{
if(strcmp(argv[1], "/umount") == 0)
{
if(argc >= 3)
{
if((argv[2][0] >= 'a' && argv[2][0] <= 'z') || (argv[2][0] >= 'A' && argv[2][0] <= 'Z'))
UmountDisk(argv[2][0]);
else
Usage();
}
else
Usage();
}
else if(strcmp(argv[1], "/query") == 0)
{
if(argc >= 3)
{
if((argv[2][0] >= 'a' && argv[2][0] <= 'z') || (argv[2][0] >= 'A' && argv[2][0] <= 'Z'))
QueryDisk(argv[2][0]);
else
Usage();
}
else
Usage();
}
else if(strcmp(argv[1], "/mount") == 0)
{
if(argc >= 4)
{
openFileInformation = (POPEN_FILE_INFORMATION)malloc(sizeof(OPEN_FILE_INFORMATION) + strlen(argv[2]) + 4);
memset(openFileInformation, 0, sizeof(OPEN_FILE_INFORMATION) + strlen(argv[2]) + 4);
strcpy(openFileInformation->FileName, "\\??\\");
strcat(openFileInformation->FileName, argv[2]);
openFileInformation->FileNameLength = strlen(openFileInformation->FileName);
if(argc >= 5)
{
if(argv[3][strlen(argv[3]) - 1] == 'G')
openFileInformation->FileSize.QuadPart = _atoi64(argv[3]) * 1024 * 1024 * 1024;
else if(argv[3][strlen(argv[3]) - 1] == 'M')
openFileInformation->FileSize.QuadPart = _atoi64(argv[3]) * 1024 * 1024;
else if(argv[3][strlen(argv[3]) - 1] == 'K')
openFileInformation->FileSize.QuadPart = _atoi64(argv[3]) * 1024;
else
openFileInformation->FileSize.QuadPart = _atoi64(argv[3]);
driveLetter = argv[4][0];
}
else
driveLetter = argv[3][0];
MountDisk(openFileInformation, driveLetter);
}
else
Usage();
}
else
Usage();
}
else
Usage();
}
void MountDisk(POPEN_FILE_INFORMATION openFileInformation, char driveLetter)
{
DWORD dwError;
char volumeName[] = "\\\\.\\ :";
HANDLE hDevice;
DWORD dwBytesReturned;
TCHAR path[MAX_PATH];
GetCurrentDirectory(sizeof(path), path);
_stprintf(path + lstrlen(path), "\\%s", DRIVER_FILE_NAME);
LoadDeviceDriver(DRIVER_NAME, path, NULL, &dwError);
volumeName[4] = driveLetter;
hDevice = CreateFile(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if(hDevice != INVALID_HANDLE_VALUE)
{
SetLastError(ERROR_BUSY);
PrintLastError(&volumeName[4]);
return;
}
if(!DefineDosDevice(DDD_RAW_TARGET_PATH, &volumeName[4], FULL_DRIVER_NAME))
{
PrintLastError(&volumeName[4]);
return;
}
hDevice = CreateFile(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
PrintLastError(&volumeName[4]);
DefineDosDevice(DDD_REMOVE_DEFINITION, &volumeName[4], NULL);
return;
}
if(!DeviceIoControl(hDevice, IOCTL_VIRTUAL_DISK_CREATE_DISK, openFileInformation,
sizeof(OPEN_FILE_INFORMATION) + openFileInformation->FileNameLength - 1, NULL, 0, &dwBytesReturned, NULL))
{
PrintLastError("VirtualDisk: ");
DefineDosDevice(DDD_REMOVE_DEFINITION, &volumeName[4], NULL);
return;
}
}
void QueryDisk(char driveLetter)
{
char volumeName[] = "\\\\.\\ :";
HANDLE hDevice;
DWORD dwBytesReturned;
POPEN_FILE_INFORMATION openFileInformation = NULL;
volumeName[4] = driveLetter;
hDevice = CreateFile(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
PrintLastError(&volumeName[4]);
return;
}
openFileInformation = (POPEN_FILE_INFORMATION)malloc(sizeof(OPEN_FILE_INFORMATION) + MAX_PATH);
if(!DeviceIoControl(hDevice, IOCTL_VIRTUAL_DISK_QUERY_DISK, NULL, 0, openFileInformation,
sizeof(OPEN_FILE_INFORMATION) + MAX_PATH, &dwBytesReturned, NULL))
{
PrintLastError(&volumeName[4]);
return;
}
if(dwBytesReturned < sizeof(OPEN_FILE_INFORMATION))
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
PrintLastError(&volumeName[4]);
return;
}
printf("%c: %.*s Size: %I64u bytes\n",
driveLetter,
openFileInformation->FileNameLength,
openFileInformation->FileName,
openFileInformation->FileSize
);
}
void UmountDisk(char driveLetter)
{
char volumeName[] = "\\\\.\\ :";
HANDLE hDevice;
DWORD dwBytesReturned;
volumeName[4] = driveLetter;
hDevice = CreateFile(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
PrintLastError(&volumeName[4]);
return;
}
if(!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
{
PrintLastError(&volumeName[4]);
return;
}
if(!DeviceIoControl(hDevice, IOCTL_VIRTUAL_DISK_CLOSE_DISK, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
{
PrintLastError("VirtualDisk: ");
return;
}
if(!DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
{
PrintLastError(&volumeName[4]);
return;
}
if(!DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
{
PrintLastError(&volumeName[4]);
return;
}
CloseHandle(hDevice);
if(!DefineDosDevice(DDD_REMOVE_DEFINITION, &volumeName[4], NULL))
{
PrintLastError(&volumeName[4]);
return;
}
UnLoadDriver(DRIVER_NAME);
}
void Usage()
{
fprintf(stdout, "vd /mount path [size] drive\n");
fprintf(stdout, "vd /umount drive\n");
fprintf(stdout, "vd /query drive\n");
}
void PrintLastError(const TCHAR * Prefix)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0,
(LPTSTR) &lpMsgBuf,
0,
NULL
);
_ftprintf(stderr, "%s %s", Prefix, (LPTSTR) lpMsgBuf);
LocalFree(lpMsgBuf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -