📄 vdkctl.c
字号:
// Check VDK driver file version//DWORD VdkCheckFileVersion( LPCTSTR driver_path, PULONG version){ DWORD return_len; DWORD dummy; LPVOID info; VS_FIXEDFILEINFO *fixedinfo; DWORD ret = ERROR_SUCCESS; LPTSTR str; // Check parameter if (!driver_path || !*driver_path) { return ERROR_INVALID_PARAMETER; } if (version) { *version = 0; } // Check if the driver file is accessible? { HANDLE hFile = CreateFile( driver_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { ret = GetLastError(); return ret; } CloseHandle(hFile); } // Ensure that the driver binary is located on a local drive // because device driver cannot be started on network drives. if (*driver_path == '\\' && *(driver_path + 1) == '\\') { // full path is a UNC path -- \\server\dir\... VDKTRACE(0, ( "VdkCheckDriverFile: Driver is located on a network drive\n")); return ERROR_NETWORK_ACCESS_DENIED; } else { // ensure that the drive letter is not a network drive char root[] = " :\\"; root[0] = *driver_path; if (GetDriveType(root) == DRIVE_REMOTE) { // the drive is a network drive VDKTRACE(0, ( "VdkCheckDriverFile: Driver is located on a network drive\n")); return ERROR_NETWORK_ACCESS_DENIED; } } // check file version return_len = GetFileVersionInfoSize((LPTSTR)driver_path, &dummy); if (return_len == 0) { ret = ERROR_BAD_FORMAT; VDKTRACE(0, ( "VdkCheckDriverFile: GetFileVersionInfoSize == 0\n")); return ret; } if ((info = VdkAllocMem(return_len)) == NULL) { ret = GetLastError(); VDKTRACE(0, ( "VdkCheckDriverFile: VdkAllocMem(%lu) - %s\n", return_len, VdkStatusStr(ret))); return ret; } if (!GetFileVersionInfo((LPTSTR)driver_path, 0, return_len, info)) { ret = GetLastError(); VDKTRACE(0, ( "VdkCheckDriverFile: GetFileVersionInfo - %s\n", VdkStatusStr(ret))); goto cleanup; } return_len = sizeof(fixedinfo); if (!VerQueryValue(info, "\\", (PVOID *)&fixedinfo, (PUINT)&return_len)) { VDKTRACE(0, ( "VdkCheckDriverFile: Failed to get fixed version info\n")); ret = ERROR_BAD_FORMAT; goto cleanup; } if (version) { *version = fixedinfo->dwFileVersionMS; if (fixedinfo->dwFileFlags & VS_FF_DEBUG) { *version |= 0x00008000; } } if (fixedinfo->dwFileOS != VOS_NT_WINDOWS32 || fixedinfo->dwFileType != VFT_DRV || fixedinfo->dwFileSubtype != VFT2_DRV_SYSTEM) { VDKTRACE(0, ( "VdkCheckDriverFile: Invalid file type flags\n")); ret = ERROR_BAD_FORMAT; goto cleanup; } if (HIWORD(fixedinfo->dwFileVersionMS) != HIWORD(VDK_DRIVER_VERSION_VAL) || HIWORD(fixedinfo->dwProductVersionMS) != HIWORD(VDK_PRODUCT_VERSION_VAL)) { VDKTRACE(0, ( "VdkCheckDriverFile: Invalid version values - file:%08x, prod: %08x\n", fixedinfo->dwFileVersionMS, fixedinfo->dwProductVersionMS)); ret = ERROR_REVISION_MISMATCH; goto cleanup; } if (!VerQueryValue(info, VERSIONINFO_PATH, (PVOID *)&str, (PUINT)&return_len)) { VDKTRACE(0, ( "VdkCheckDriverFile: Failed to get OriginalFileName\n")); ret = ERROR_BAD_FORMAT; goto cleanup; } if (strcmp(str, VDK_DRIVER_FILENAME)) { VDKTRACE(0, ( "VdkCheckDriverFile: Invalid original file name\n")); ret = ERROR_BAD_FORMAT; goto cleanup; }cleanup: VdkFreeMem(info); return ret;}//// open the Virtual Disk device without showing the "Insert Disk"// dialog when the drive is empty.//HANDLE VdkOpenDevice( ULONG disk_number, ULONG part_number){ TCHAR device_name[sizeof(VDK_DEV_TEMPLATE) + 10]; HANDLE hDevice; UINT err_mode; sprintf(device_name, VDK_DEV_TEMPLATE, disk_number, part_number); // change error mode in order to avoid "Insert Disk" dialog err_mode = SetErrorMode(SEM_FAILCRITICALERRORS); // open the Virtual Disk device hDevice = CreateFile( device_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL); // revert to the previous error mode SetErrorMode(err_mode); // return the handle to the Virtual Disk device return hDevice;}//// check running VDK driver version//DWORD VdkCheckVersion( HANDLE hDevice, PULONG version){ ULONG ver; DWORD len; BOOL close_device = FALSE; DWORD ret = ERROR_SUCCESS; if (version) { *version = 0; } // // Open Virtual Disk device // if (!hDevice || hDevice == INVALID_HANDLE_VALUE) { if ((hDevice = VdkOpenDevice(0, 0)) == INVALID_HANDLE_VALUE) { ret = GetLastError(); VDKTRACE(0, ("VdkCheckVersion: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", 0, 0, VdkStatusStr(ret))); goto cleanup; } close_device = TRUE; } if (!DeviceIoControl( hDevice, IOCTL_VDK_GET_VERSION, NULL, 0, &ver, sizeof(ver), &len, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkCheckVersion: DeviceIoControl(IOCTL_VDK_GET_VERSION) - %s\n", VdkStatusStr(ret))); goto cleanup; } if (HIWORD(ver) != HIWORD(VDK_DRIVER_VERSION_VAL)) { ret = ERROR_REVISION_MISMATCH; } if (version) { *version = ver; }cleanup: if (hDevice != INVALID_HANDLE_VALUE && close_device) { CloseHandle(hDevice); } return ret;}//// Get running driver information//DWORD VdkGetDriverInfo( HANDLE hDevice, PULONG disk_device, PULONG attached_part, PULONG orphaned_part, PULONG reference_count){ DWORD tmp; BOOL close_device = FALSE; DWORD ret = ERROR_SUCCESS; VDK_DRIVER_INFO driver_info; if (disk_device) { *disk_device = 0; } if (attached_part) { *attached_part = 0; } if (orphaned_part) { *orphaned_part = 0; } if (reference_count) { *reference_count = 0; } // // Open Virtual Disk device // if (!hDevice || hDevice == INVALID_HANDLE_VALUE) { if ((hDevice = VdkOpenDevice(0, 0)) == INVALID_HANDLE_VALUE) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverInfo: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", 0, 0, VdkStatusStr(ret))); goto cleanup; } close_device = TRUE; } // // Query driver information // if (!DeviceIoControl(hDevice, IOCTL_VDK_DRIVER_INFO, NULL, 0, &driver_info, sizeof(driver_info), &tmp, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverInfo: IOCTL_VDK_DRIVER_INFO - %s\n", VdkStatusStr(ret))); goto cleanup; } if (disk_device) { *disk_device = driver_info.DiskDevices; } if (attached_part) { *attached_part = driver_info.AttachedParts; } if (orphaned_part) { *orphaned_part = driver_info.OrphanedParts; } if (reference_count) { *reference_count = driver_info.TotalReference; }cleanup: if (hDevice != INVALID_HANDLE_VALUE && close_device) { CloseHandle(hDevice); } return ret;}//// Create a new disk device//DWORD VdkCreateDisk( HANDLE hDevice){ DWORD tmp; BOOL close_device = FALSE; DWORD ret = ERROR_SUCCESS; // // Open Virtual Disk device // if (!hDevice || hDevice == INVALID_HANDLE_VALUE) { if ((hDevice = VdkOpenDevice(0, 0)) == INVALID_HANDLE_VALUE) { ret = GetLastError(); VDKTRACE(0, ("VdkCreateDisk: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", 0, 0, VdkStatusStr(ret))); goto cleanup; } close_device = TRUE; } // // Create virtual disk device // if (!DeviceIoControl(hDevice, IOCTL_VDK_CREATE_DISK, NULL, 0, NULL, 0, &tmp, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkCreateDisk: DeviceIoControl(IOCTL_VDK_CREATE_DISK) - %s\n", VdkStatusStr(ret))); goto cleanup; }cleanup: if (hDevice != INVALID_HANDLE_VALUE && close_device) { CloseHandle(hDevice); } return ret;}//// Delete a disk device//DWORD VdkDeleteDisk( HANDLE hDevice){ DWORD tmp; BOOL close_device = FALSE; DWORD ret = ERROR_SUCCESS; // // Open Virtual Disk device // if (!hDevice || hDevice == INVALID_HANDLE_VALUE) { if ((hDevice = VdkOpenDevice(0, 0)) == INVALID_HANDLE_VALUE) { ret = GetLastError(); VDKTRACE(0, ("VdkDeleteDisk: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", 0, 0, VdkStatusStr(ret))); goto cleanup; } close_device = TRUE; } // // Delete a virtual disk device // if (!DeviceIoControl(hDevice, IOCTL_VDK_DELETE_DISK, NULL, 0, NULL, 0, &tmp, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkDeleteDisk: DeviceIoControl(IOCTL_VDK_DELETE_DISK) - %s\n", VdkStatusStr(ret))); goto cleanup; }cleanup: if (hDevice != INVALID_HANDLE_VALUE && close_device) { CloseHandle(hDevice); } return ret;}//// Check current device state//DWORD VdkCheckDeviceState( HANDLE hDevice, ULONG disk_number, ULONG part_number){ DWORD tmp; 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, ("VdkCheckDeviceState: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", disk_number, part_number, VdkStatusStr(ret))); return ret; } close_device = TRUE; } if (!DeviceIoControl(hDevice, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, &tmp, NULL)) { ret = GetLastError(); if (ret == ERROR_BUSY) { // drive is a zombie -- try to dismount if (VdkDismount(hDevice, 0, 0, TRUE) == ERROR_SUCCESS) { // succeeded to dismount ret = ERROR_NOT_READY; } } else if (ret == ERROR_WRITE_PROTECT) { ret = ERROR_SUCCESS; }#ifdef VDK_DEBUG if (ret != ERROR_NOT_READY) { VDKTRACE(0, ("VdkCheckDeviceState: IOCTL_DISK_IS_WRITABLE - %s\n", VdkStatusStr(ret))); }#endif // VDK_DEBUG } if (close_device && hDevice != INVALID_HANDLE_VALUE) { CloseHandle(hDevice); } return ret;}//// Get device information//DWORD VdkGetDeviceList( PULONG device_num, PVDK_DEVICE_INFO *device_info){ HANDLE hDevice; ULONG disk_num, part_num, orphan_num; DWORD result; DWORD ret = ERROR_SUCCESS; if (device_num) { *device_num = 0; } if (device_info) { *device_info = NULL; } // // Get information about all devices // hDevice = VdkOpenDevice(0, 0); if (hDevice == INVALID_HANDLE_VALUE) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDeviceList: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", 0, 0, VdkStatusStr(ret))); return ret; } ret = VdkGetDriverInfo(hDevice, &disk_num, &part_num, &orphan_num, NULL); if (ret != ERROR_SUCCESS) { goto cleanup; } *device_num = disk_num + part_num + orphan_num; *device_info = (PVDK_DEVICE_INFO)VdkAllocMem(*device_num * sizeof(VDK_DEVICE_INFO)); if (*device_info == NULL) { ret = GetLastError(); goto cleanup; } if (!DeviceIoControl(hDevice, IOCTL_VDK_DEVICE_INFO, device_num, sizeof(device_num), (LPBYTE)*device_info, *device_num * sizeof(VDK_DEVICE_INFO), &result, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDeviceList: IOCTL_VDK_DEVICE_INFO - %s\n", VdkStatusStr(ret))); goto cleanup; }cleanup: CloseHandle(hDevice); return ret;}#ifdef VDK_DEBUG//// Get and set debug trace flags//ULONG VdkTraceFlags( PULONG flags){ HANDLE hDevice; ULONG result; ULONG current = 0; hDevice = VdkOpenDevice(0, 0); if (hDevice != INVALID_HANDLE_VALUE) { DeviceIoControl(hDevice, IOCTL_VDK_DEBUG_TRACE, flags, flags ? sizeof(ULONG) : 0, ¤t, sizeof(current), &result, NULL); CloseHandle(hDevice); } return current;}#endif//// Open Virtual Disk Image File//DWORD VdkOpen( HANDLE hDevice, ULONG disk_number, PVOID pDisk, ULONG AccessMode){ PVDK_OPEN_FILE_INFO open_info = NULL; ULONG info_len; BOOL close_device = FALSE; DWORD ret = ERROR_SUCCESS; if (!pDisk) { return ERROR_INVALID_PARAMETER; } ret = VDiskMapToOpenInfo(pDisk, (PVOID *)&open_info, &info_len); if (ret != ERROR_SUCCESS) { return ret; } open_info->DiskType = AccessMode; // // Open Virtual Disk device // if (!hDevice || hDevice == INVALID_HANDLE_VALUE) { if ((hDevice = VdkOpenDevice(disk_number, 0)) == INVALID_HANDLE_VALUE) { ret = GetLastError(); VDKTRACE(0, ("VdkOpen: CreateFile(" VDK_DEV_TEMPLATE ") - %s\n", disk_number, 0, VdkStatusStr(ret))); goto cleanup; } close_device = TRUE; } // // Check driver version // ret = VdkCheckVersion(hDevice, NULL); if (ret != ERROR_SUCCESS) { goto cleanup; } // // Open image file // if (!DeviceIoControl( hDevice, IOCTL_VDK_OPEN_FILE, open_info, info_len, NULL, 0, &info_len, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkOpen: DeviceIoControl(IOCTL_VDK_OPEN_FILE) - %s\n", VdkStatusStr(ret))); goto cleanup; } // // update device configuration accordingly // if (!DeviceIoControl( hDevice, IOCTL_VDK_UPDATE_DEVICE, NULL, 0, NULL, 0, &info_len, NULL)) { ULONG graceful = TRUE; ret = GetLastError(); VDKTRACE(0, ("VdkOpen: DeviceIoControl(IOCTL_VDK_UPDATE_DEVICE) - %s\n", VdkStatusStr(ret))); DeviceIoControl(hDevice, IOCTL_VDK_CLOSE_FILE, &graceful, sizeof(graceful), NULL, 0, &info_len, NULL); goto cleanup; }cleanup: if (hDevice != INVALID_HANDLE_VALUE && close_device) { CloseHandle(hDevice); } if (open_info) { VdkFreeMem(open_info); } return ret;}//// Close Image File//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -