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

📄 vdkctl.c

📁 Virtual Disk Driver
💻 C
📖 第 1 页 / 共 3 页
字号:
DWORD VdkClose(	HANDLE	hDevice,	ULONG	disk_number,	ULONG	graceful){	DWORD	return_len;	BOOL	close_device = FALSE;	DWORD	ret = ERROR_SUCCESS;	if (!hDevice || hDevice == INVALID_HANDLE_VALUE) {		if ((hDevice = VdkOpenDevice(disk_number, 0)) == INVALID_HANDLE_VALUE) {			ret = GetLastError();			VDKTRACE(0, ("VdkClose: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n",				disk_number, 0, VdkStatusStr(ret)));			goto cleanup;		}		close_device = TRUE;	}	if (!DeviceIoControl(hDevice, IOCTL_VDK_CLOSE_FILE,		&graceful, sizeof(graceful), NULL, 0, &return_len, NULL)) {		ret = GetLastError();		VDKTRACE(0, ("VdkClose: IOCTL_VDK_CLOSE_FILE - %s\n",			VdkStatusStr(ret)));		goto cleanup;	}cleanup:	if (close_device && hDevice != INVALID_HANDLE_VALUE) {		CloseHandle(hDevice);	}	return ret;}////	Get Virtual Disk image file info//DWORD VdkGetFileInfo(	HANDLE	hDevice,	ULONG	disk_number,	PVDK_OPEN_FILE_INFO	*file_info){	ULONG	info_size;	DWORD	return_len;	BOOL	close_device = FALSE;	DWORD	ret = ERROR_SUCCESS;	if (!file_info) {		return ERROR_INVALID_PARAMETER;	}	*file_info = NULL;	//	//	Open device	//	if (!hDevice || hDevice == INVALID_HANDLE_VALUE) {		if ((hDevice = VdkOpenDevice(disk_number, 0)) == INVALID_HANDLE_VALUE) {			ret = GetLastError();			VDKTRACE(0, (				"VdkGetFileInfo: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n",				disk_number, 0, VdkStatusStr(ret)));			goto cleanup;;		}		close_device = TRUE;	}	//	//	Query file information size	//	if (!DeviceIoControl(hDevice, IOCTL_VDK_QUERY_FILE_SIZE,		NULL, 0, &info_size, sizeof(info_size), &return_len, NULL)) {		ret = GetLastError();		VDKTRACE(0, ("VdkGetFileInfo: DeviceIoControl(IOCTL_VDK_QUERY_FILE_SIZE) - %s\n",			VdkStatusStr(ret)));		goto cleanup;	}	if (info_size == 0) {		goto cleanup;	}	//	//	Allocate information area	//	if ((*file_info = (PVDK_OPEN_FILE_INFO)VdkAllocMem(info_size)) == NULL) {		ret = GetLastError();		VDKTRACE(0, ("VdkGetFileInfo: VdkAllocMem(%lu) - %s\n",			info_size, VdkStatusStr(ret)));		goto cleanup;	}	memset(*file_info, 0, info_size);	//	//	Query file information	//	if (!DeviceIoControl(hDevice, IOCTL_VDK_QUERY_FILE,		NULL, 0, *file_info, info_size, &return_len, NULL)) {		ret = GetLastError();		VDKTRACE(0, ("VdkGetFileInfo: DeviceIoControl(IOCTL_VDK_QUERY_FILE) - %s\n",			VdkStatusStr(ret)));		VdkFreeMem(*file_info);		*file_info = NULL;		goto cleanup;	}cleanup:	if (close_device && hDevice != INVALID_HANDLE_VALUE) {		CloseHandle(hDevice);	}	return ret;}////	Dismount a single virtual partition//DWORD VdkDismount(	HANDLE	hDevice,	ULONG	disk_number,	ULONG	part_number,	ULONG	unlock){	DWORD	return_len;	BOOL	close_device = FALSE;	DWORD	ret = ERROR_SUCCESS;	if (!hDevice || hDevice == INVALID_HANDLE_VALUE) {		hDevice = VdkOpenDevice(disk_number, part_number);		if (hDevice == INVALID_HANDLE_VALUE) {			ret = GetLastError();			VDKTRACE(0, ("VdkDismount: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n",				disk_number, part_number, VdkStatusStr(ret)));			return ret;		}		close_device = TRUE;	}	if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME,		NULL, 0, NULL, 0, &return_len, NULL)) {		ret = GetLastError();		VDKTRACE(0, (			"VdkDismount: DeviceIoControl(FSCTL_LOCK_VOLUME) - %s\n",			VdkStatusStr(ret)));		goto cleanup;	}	if (!DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME,		NULL, 0, NULL, 0, &return_len, NULL)) {		ret = GetLastError();		VDKTRACE(0, ("VdkDismount: DeviceIoControl(FSCTL_DISMOUNT_VOLUME) - %s\n",			VdkStatusStr(ret)));	}	if (ret == ERROR_SUCCESS) {		if (!DeviceIoControl(hDevice, IOCTL_VDK_NOTIFY_DISMOUNT,			NULL, 0, NULL, 0, &return_len, NULL)) {			VDKTRACE(0, ("VdkDismount: DeviceIoControl(IOCTL_VDK_NOTIFY_DISMOUNT) - %s\n",				VdkStatusStr(GetLastError())));		}	}	if (unlock && !DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME,		NULL, 0, NULL, 0, &return_len, NULL)) {		VDKTRACE(0, ("VdkDismount: DeviceIoControl(FSCTL_UNLOCK_VOLUME) - %s\n",			VdkStatusStr(GetLastError())));	}cleanup:	if (hDevice != INVALID_HANDLE_VALUE && close_device) {		CloseHandle(hDevice);	}	return ret;}////	Dismount all virtual partition devices//DWORD VdkDismountAll(BOOL zombie_only){	HANDLE hDevice;	ULONG device_num = 0;	PVDK_DEVICE_INFO device_info = NULL;	DWORD tmp;	DWORD ret;	//	//	Get information about all devices	//	ret = VdkGetDeviceList(&device_num, &device_info);	if (ret != VDK_OK) {		return ret;	}	//	//	dismount existing devices	//	for (tmp = 0; tmp < device_num; tmp++) {		if (!device_info[tmp].ReferenceCount ||			(zombie_only && !device_info[tmp].Zombie)) {			continue;		}		DefineDosDevice(DDD_RAW_TARGET_PATH, "VDKTMP", device_info[tmp].DeviceName);		hDevice = CreateFile(			"\\\\.\\VDKTMP",			GENERIC_READ | GENERIC_WRITE,			FILE_SHARE_READ | FILE_SHARE_WRITE,			NULL,			OPEN_EXISTING,			FILE_FLAG_NO_BUFFERING,			NULL);		if (hDevice == INVALID_HANDLE_VALUE) {			ret = GetLastError();			VDKTRACE(0, ("VdkDismountAll: CreateFile(\\\\.\\VDKTMP) - %s\n",				VdkStatusStr(ret)));		}		DefineDosDevice(DDD_REMOVE_DEFINITION, "VDKTMP", NULL);		if (ret == ERROR_SUCCESS) {			VdkDismount(hDevice, 0, 0, TRUE);			CloseHandle(hDevice);		}	}	//	//	check if all devices are released	//	ret = VdkGetDriverInfo(NULL, NULL, NULL, NULL, &tmp);	if (ret == ERROR_SUCCESS && tmp > 1) {		ret = ERROR_BUSY;	}	if (device_info) {		VdkFreeMem(device_info);	}	return ret;}////	Get VDK device name in the kernel namespace//DWORD VdkGetDeviceName(	ULONG disk_number,	ULONG part_number,	LPTSTR buf){	TCHAR dos_name[sizeof(VDK_DOS_TEMPLATE) + 10];	TCHAR dir_name[MAX_DEVNAME_LEN];	*buf = '\0';	sprintf(dos_name, VDK_DEVICE_BASENAME "%u", disk_number);	if (!QueryDosDevice(dos_name, dir_name, sizeof(dir_name))) {		return GetLastError();	}	if (part_number != (ULONG)-1) {		sprintf(buf, "%s\\Partition%lu", dir_name, part_number);	}	else {		strcpy(buf, dir_name);	}	return ERROR_SUCCESS;}////	Get Virtual Disk drive letter//DWORD VdkGetDriveLetter(	ULONG	disk_number,	ULONG	part_number,	TCHAR	*drive_letter){	DWORD	logical_drives;	TCHAR	dos_device[] = " :";	TCHAR	device_name[MAX_PATH], dos_name[MAX_PATH];	DWORD	ret = ERROR_SUCCESS;	if (!drive_letter) {		return ERROR_INVALID_PARAMETER;	}	*drive_letter = '\0';	ret = VdkGetDeviceName(disk_number, part_number, device_name);	if (ret != ERROR_SUCCESS) {		return ret;	}	logical_drives = GetLogicalDrives();	if (logical_drives == 0) {		ret = GetLastError();		VDKTRACE(0, (			"VdkGetDriveLetter: GetLogicalDrives - %s\n", VdkStatusStr(ret)));		return ret;	}	dos_device[0] = 'A';	while (logical_drives) {		if (logical_drives & 0x01) {			if (QueryDosDevice(dos_device, dos_name, sizeof(dos_name))) {				if (_stricmp(device_name, dos_name) == 0) {					*drive_letter = dos_device[0];					return ERROR_SUCCESS;				}			}			else {				ret = GetLastError();				VDKTRACE(0, (					"VdkGetDriveLetter: QueryDosDevice(%s) - %s\n",					dos_device, VdkStatusStr(ret)));				return ret;			}		}		logical_drives >>= 1;		dos_device[0]++;	}	return ret;}////	Assign a DOS drive letter to Virtual Disk Drive//DWORD VdkSetDriveLetter(	ULONG	disk_number,	ULONG	part_number,	TCHAR	drive_letter){	DWORD ret = ERROR_SUCCESS;	TCHAR dos_device[] = " :";	TCHAR device_name[MAX_PATH], dos_name[MAX_PATH];	if (!isalpha(drive_letter)) {		return ERROR_INVALID_PARAMETER;	}	//	check if device is active	ret = VdkCheckDeviceState(NULL, disk_number, part_number);	if (ret != ERROR_SUCCESS) {		return ret;	}	//	Check if the drive letter is already in use	dos_device[0] = (TCHAR)toupper(drive_letter);	ret = VdkGetDeviceName(disk_number, part_number, device_name);	if (ret != ERROR_SUCCESS) {		return ret;	}	if (QueryDosDevice(dos_device, dos_name, sizeof(dos_name))) {		if (strcmp(dos_name, device_name) == 0) {			return ERROR_SUCCESS;		}		else {			VDKTRACE(0, (				"VdkSetDriveLetter: Drive letter '%c' is linked to '%s'\n",				dos_device[0], dos_name));			return ERROR_ALREADY_ASSIGNED;		}	}	else {		if ((ret = GetLastError()) != ERROR_FILE_NOT_FOUND) {			VDKTRACE(0, (				"VdkSetDriveLetter: QueryDosDevice(%s) - %lu\n",				dos_device, VdkStatusStr(ret)));			return ret;		}	}	//	Check if the Virtual Disk drive has a DriveLetter already assigned	ret = VdkGetDriveLetter(disk_number, part_number, &drive_letter);	if (ret != ERROR_SUCCESS) {		return ret;	}	if (isalpha(drive_letter)) {		if (drive_letter == dos_device[0]) {			return ERROR_SUCCESS;		}		else {			VDKTRACE(0, ("VdkSetDriveLetter: Drive Letter '%c' is already assigned to %s\n",				drive_letter, device_name));			return ERROR_ALREADY_ASSIGNED;		}	}	//	Assign the new drive letter	if (!DefineDosDevice(DDD_RAW_TARGET_PATH, dos_device, device_name)) {		ret = GetLastError();		VDKTRACE(0, ("VdkSetDriveLetter: DefineDosDevice(%s) - %s\n",			dos_device, VdkStatusStr(ret)));	}	return ret;}////	Remove Dos Drive Letter//DWORD VdkDelDriveLetter(	TCHAR	drive_letter){	HANDLE	hDevice;	ULONG	tmp;	TCHAR	dos_device[] = "\\\\.\\ :";	DWORD	ret = ERROR_SUCCESS;	if (!isalpha(drive_letter)) {		return ERROR_INVALID_DRIVE;	}	dos_device[4] = drive_letter;	//	//	Check if the target device is a VDK device	//	hDevice = CreateFile(		dos_device,		GENERIC_READ,		FILE_SHARE_READ | FILE_SHARE_WRITE,		NULL,		OPEN_EXISTING,		0,		NULL);	if (hDevice == INVALID_HANDLE_VALUE) {		ret = GetLastError();		if (ret != ERROR_FILE_NOT_FOUND &&			ret != ERROR_PATH_NOT_FOUND) {			return ret;		}		goto execute;	}	if (!DeviceIoControl(hDevice, IOCTL_VDK_GET_VERSION,		NULL, 0, NULL, 0, &tmp, NULL)) {		ret = ERROR_INVALID_PARAMETER;	}	CloseHandle(hDevice);	if (ret != ERROR_SUCCESS) {		return ret;	}execute:	if (!DefineDosDevice(DDD_REMOVE_DEFINITION, &dos_device[4], NULL)) {		ret = GetLastError();		VDKTRACE(0, (			"VdkUnlink: DefineDosDevice(%s) - %s\n",			&dos_device[4], VdkStatusStr(ret)));	}	return ret;}//// choose first available drive letter//char ChooseDriveLetter(){	DWORD	logical_drives = GetLogicalDrives();	char	drive_letter = 'C';	if (logical_drives == 0) {		return '\0';	}	//	//	Do not assign A and B to Virtual Disk even if they are not used	//	logical_drives >>= 2;	while (logical_drives & 0x1) {		logical_drives >>= 1;		drive_letter++;	}	if (drive_letter > 'Z') {		return '\0';	}	return drive_letter;}////	Ensure Virtual Disk image is closed//DWORD VdkCloseDrive(	ULONG			disk_number,	VDK_CALLBACK	retrycb,	VDK_CALLBACK	contcb,	PVOID			param){	HANDLE	hDisk;	TCHAR	vdk_dev[MAX_PATH];	ULONG	dos_dev[26];	ULONG	part_num;	ULONG	max_parts;	ULONG	graceful;	ULONG	i;	DWORD	ret = ERROR_SUCCESS;	VdkGetDeviceName(disk_number, 0, vdk_dev);	//	//	Delete all drive letters	//	for (i = 0; i < 26; i++) {		TCHAR	dos_link[] = " :";		TCHAR	dos_device[MAX_PATH];		dos_link[0] = (TCHAR)(i + 'a');		dos_device[0] = '\0';		if (QueryDosDevice(dos_link, dos_device, sizeof(dos_device)) &&			!_strnicmp(vdk_dev, dos_device, strlen(vdk_dev) - 1)) {			dos_dev[i] = atol(dos_device + strlen(vdk_dev) - 1);			DefineDosDevice(				(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE),				dos_link,				dos_device);		}		else {			dos_dev[i] = (ULONG)-1;		}	}	hDisk = VdkOpenDevice(disk_number, 0);	if (hDisk == INVALID_HANDLE_VALUE) {		ret = VdkLastError();		VDKTRACE(0, ("VdkCloseDrive: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n",			disk_number, 0, VdkStatusStr(ret)));		return ret;	}	if (!DeviceIoControl(hDisk, IOCTL_VDK_NUMBER_OF_PARTS,		NULL, 0, &max_parts, sizeof(max_parts), &part_num, NULL)) {		ret = VdkLastError();		VDKTRACE(0, ("VdkCloseDrive: IOCTL_VDK_NUMBER_OF_PARTS - %s\n",			VdkStatusStr(ret)));		CloseHandle(hDisk);		return ret;	}	//	//	Dismount all partitions on this disk	//	graceful = TRUE;	for (part_num = 0; part_num <= max_parts; part_num++) {		ret = VdkCheckDeviceState(			part_num ? NULL : hDisk, disk_number, part_num);		if (ret != ERROR_SUCCESS) {			break;		}dismount_retry:		SetCursor(LoadCursor(NULL, IDC_WAIT));		for(i = 0;;) {			ret = VdkDismount(				part_num ? NULL : hDisk, disk_number, part_num, FALSE);			if (ret != ERROR_ACCESS_DENIED || ++i > 10) {				break;			}			Sleep(500);			//	retry after 0.5 sec.		}		SetCursor(LoadCursor(NULL, IDC_ARROW));		if (ret == ERROR_ACCESS_DENIED &&			retrycb && (*retrycb)(param, ret)) {			goto dismount_retry;		}		if (ret != ERROR_SUCCESS) {			// Failed to dismount			if (contcb && (*contcb)(param, ret)) {				//	proceed anyway				if (!part_num) {					graceful = FALSE;				}				ret = ERROR_SUCCESS;			}			else {				//	abort operation				break;			}		}	}	// next partition	//	//	couldn't dismount partition 0 -> file is not opened	//	if (!part_num) {		CloseHandle(hDisk);		return ret;	}	//	//	Close virtual disk file	//	if (ret == ERROR_SUCCESS) {		ret = VdkClose(hDisk, disk_number, graceful);	}	if (ret != ERROR_SUCCESS) {		//		//	Close failed -- restore drive letters		//		for (i = 0; i < 26; i++) {			if (dos_dev[i] != -1) {				if (VdkSetDriveLetter(disk_number, dos_dev[i], (char)(i + 'a')) != ERROR_SUCCESS) {				}			}		}	}	CloseHandle(hDisk);	return ret;}// End Of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -