⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vd.c

📁 Windows DDK编写的虚拟磁盘驱动程序源代码
💻 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 + -