📄 vdkctl.c
字号:
/* vdkctl.c Virtual Disk driver control routines Copyright (C) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "vdkfile.h"#include "vdkioctl.h"#include "vdkver.h"#include "vdkctl.h"#include "VDiskUtil.h"#pragma warning(push,3)#include <winioctl.h>#pragma warning(pop)//// Version info translation//#define VERSIONINFO_PATH "\\StringFileInfo\\" VDK_VERSIONINFO_LANG "\\OriginalFileName"//// DOS device name (\\.\VirtualDK<x>\Partition<y>)//#define VDK_DOS_TEMPLATE VDK_DEVICE_BASENAME "%u" "\\Partition%u"#define VDK_DEV_TEMPLATE "\\\\.\\" VDK_DOS_TEMPLATE#define VDK_REG_CONFIG_KEY "System\\CurrentControlSet\\Services\\" VDK_DEVICE_BASENAME//// Get Virtual Disk driver configuration//DWORD VdkGetDriverConfig( LPTSTR driver_path, LPDWORD start_type, PULONG device_num){ SC_HANDLE hScManager; // Service Control Manager SC_HANDLE hService; // Service (= Driver) LPQUERY_SERVICE_CONFIG config = NULL; DWORD return_len; DWORD ret = ERROR_SUCCESS; if (driver_path) { ZeroMemory(driver_path, MAX_PATH); } if (start_type) { *start_type = (DWORD)-1; } if (device_num) { *device_num = 0; } // Connect to the Service Control Manager hScManager = OpenSCManager(NULL, NULL, 0); if (hScManager == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverConfig: OpenSCManager() - %s\n", VdkStatusStr(ret))); return ret; } // Open Existing Service Object hService = OpenService( hScManager, // Service control manager VDK_DEVICE_BASENAME, // service name SERVICE_QUERY_CONFIG); // service access mode if (hService == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverConfig: OpenService(SERVICE_QUERY_CONFIG) - %s\n", VdkStatusStr(ret))); goto cleanup; } // Get the return_len of config information if (!QueryServiceConfig(hService, NULL, 0, &return_len)) { ret = GetLastError(); if (ret == ERROR_INSUFFICIENT_BUFFER) { ret = ERROR_SUCCESS; } else { VDKTRACE(0, ("VdkGetDriverConfig: QueryServiceConfig() - %s\n", VdkStatusStr(ret))); goto cleanup; } } // allocate a required buffer config = (QUERY_SERVICE_CONFIG *)VdkAllocMem(return_len); if (config == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverConfig: VdkAllocMem(%lu) - %s\n", return_len, VdkStatusStr(ret))); goto cleanup; } // get the config information if (!QueryServiceConfig(hService, config, return_len, &return_len)) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverConfig: QueryServiceConfig() - %s\n", VdkStatusStr(ret))); goto cleanup; } // copy information to output buffer if (driver_path) { if (strncmp(config->lpBinaryPathName, "\\??\\", 4) == 0) { strncpy( driver_path, config->lpBinaryPathName + 4, MAX_PATH); } else { strncpy( driver_path, config->lpBinaryPathName, MAX_PATH); } } if (start_type) { *start_type = config->dwStartType; } if (device_num) { // // Get number of initial devices from registry // HKEY hKey; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VDK_REG_CONFIG_KEY, 0, KEY_READ, &hKey); if (ret == ERROR_SUCCESS) { return_len = sizeof(DWORD); ret = RegQueryValueEx( hKey, VDK_REG_DISKNUM_VALUE, 0, NULL, (LPBYTE)device_num, &return_len); if (ret == ERROR_PATH_NOT_FOUND || ret == ERROR_FILE_NOT_FOUND) { ret = ERROR_SUCCESS; *device_num = VDK_DEFAULT_DISK_NUM; } RegCloseKey(hKey); } if (ret != ERROR_SUCCESS) { VDKTRACE(0, ("VdkGetDriverConfig: RegOpenKeyEx - %s\n", VdkStatusStr(ret))); *device_num = 0; } }cleanup: // Free service config buffer if (config) { VdkFreeMem(config); } // Close the service object handle if (hService) { CloseServiceHandle(hService); } // Close handle to the service control manager. if (hScManager) { CloseServiceHandle(hScManager); } return ret;}//// Get Virtual Disk driver state//DWORD VdkGetDriverState( LPDWORD current_state){ SC_HANDLE hScManager = NULL; // Service Control Manager SC_HANDLE hService = NULL; // Service (= Driver) SERVICE_STATUS status; DWORD ret = ERROR_SUCCESS; if (current_state) { *current_state = 0; } // Connect to the Service Control Manager hScManager = OpenSCManager(NULL, NULL, 0); if (hScManager == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverState: OpenSCManager() - %s\n", VdkStatusStr(ret))); return ret; } // Open Existing Service Object hService = OpenService( hScManager, // Service control manager VDK_DEVICE_BASENAME, // service name SERVICE_QUERY_STATUS); // service access mode if (hService == NULL) { ret = GetLastError(); if (ret == ERROR_SERVICE_DOES_NOT_EXIST) { if (current_state) { *current_state = VDK_NOT_INSTALLED; } ret = ERROR_SUCCESS; } else { VDKTRACE(0, ( "VdkGetDriverState: OpenService(SERVICE_QUERY_STATUS) - %s\n", VdkStatusStr(ret))); } goto cleanup; } // Get current driver status memset(&status, 0, sizeof(status)); if (!QueryServiceStatus(hService, &status)) { ret = GetLastError(); VDKTRACE(0, ("VdkGetDriverState: QueryServiceStatus() - %s\n", VdkStatusStr(ret))); goto cleanup; } if (current_state) { *current_state = status.dwCurrentState; }cleanup: // Close the service object handle if (hService) { CloseServiceHandle(hService); } // Close handle to the service control manager. if (hScManager) { CloseServiceHandle(hScManager); } return ret;}//// Install Virtual Disk Driver dynamically//DWORD VdkInstall( LPCTSTR driver_path, BOOL auto_start){ SC_HANDLE hScManager; // Service Control Manager SC_HANDLE hService; // Service (= Driver) TCHAR full_path[MAX_PATH]; DWORD ret = ERROR_SUCCESS; // Prepare driver binary's full path if (driver_path == NULL || *driver_path == '\0') { // default driver file is vdk.sys in the same directory as executable DWORD len = GetModuleFileName( NULL, full_path, sizeof(full_path)); if (len == 0) { ret = GetLastError(); VDKTRACE(0, ("VdkInstall: GetModuleFileName - %s\n", VdkStatusStr(ret))); return ret; } // search the last '\' char while (len > 0 && full_path[len - 1] != '\\') { len --; } strcpy(&full_path[len], VDK_DRIVER_FILENAME); } else { // ensure that tha path is absolute full path LPTSTR file_part; if (GetFullPathName( driver_path, sizeof(full_path), full_path, &file_part) == 0) { ret = GetLastError(); VDKTRACE(0, ("VdkInstall: GetFullPathName(%s) - %s\n", driver_path, VdkStatusStr(ret))); return ret; } // only directory is specified? if (GetFileAttributes(full_path) & FILE_ATTRIBUTE_DIRECTORY) { strcat(full_path, "\\"); strcat(full_path, VDK_DRIVER_FILENAME); } } // Check if the file is a valid Virtual Disk driver ret = VdkCheckFileVersion(full_path, NULL); if (ret != ERROR_SUCCESS) { VDKTRACE(0, ("VdkInstall: VdkCheckDriverFile(%s)\n", full_path)); return ret; } // If the path is under %SystemRoot% make it relative to %SystemRoot% { TCHAR windir[MAX_PATH]; int len; len = GetEnvironmentVariable("SystemRoot", windir, sizeof(windir)); if (len > sizeof(windir)) { VDKTRACE(0, ( "VdkInstall: %%SystemRoot%% contains too long text\n")); return ERROR_BAD_ENVIRONMENT; } else if (len && _strnicmp(windir, full_path, len) == 0) { memmove(full_path, full_path + len + 1, strlen(full_path) - len); } } // Connect to the Service Control Manager hScManager = OpenSCManager( NULL, // local machine NULL, // local database SC_MANAGER_CREATE_SERVICE); // access required if (hScManager == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkInstall: OpenSCManager() - %s\n", VdkStatusStr(ret))); return ret; } // Create a new service object hService = CreateService( hScManager, // service control manager VDK_DEVICE_BASENAME, // internal service name VDK_DEVICE_BASENAME, // display name SERVICE_ALL_ACCESS, // access mode SERVICE_KERNEL_DRIVER, // service type auto_start ? SERVICE_AUTO_START : SERVICE_DEMAND_START, // service start type SERVICE_ERROR_NORMAL, // start error sevirity full_path, // service image file path NULL, // service group NULL, // service tag NULL, // service dependency NULL, // use LocalSystem account NULL // password for the account ); if (!hService) { // Failed to create a service object ret = GetLastError(); VDKTRACE(0, ("VdkInstall: CreateService() - %s\n", VdkStatusStr(ret))); goto cleanup; }cleanup: // Close the service object handle if (hService) { CloseServiceHandle(hService); } // Close handle to the service control manager. if (hScManager) { CloseServiceHandle(hScManager); } return ret;}//// Remove Virtual Disk Driver entry from system registry//DWORD VdkRemove(){ SC_HANDLE hScManager; // Service Control Manager SC_HANDLE hService; // Service (= Driver) DWORD ret = ERROR_SUCCESS; // Connect to the Service Control Manager hScManager = OpenSCManager(NULL, NULL, 0); if (hScManager == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkRemove: OpenSCManager() - %s\n", VdkStatusStr(ret))); return ret; } // Open Existing Service Object hService = OpenService( hScManager, // Service control manager VDK_DEVICE_BASENAME, // service name DELETE); // service access mode if (hService == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkRemove: OpenService(DELETE) - %s\n", VdkStatusStr(ret))); goto cleanup; } // Remove driver entry from registry if (!DeleteService(hService)) { ret = GetLastError(); VDKTRACE(0, ("VdkRemove: DeleteService() - %s\n", VdkStatusStr(ret))); goto cleanup; }cleanup: // Close the service object handle if (hService) { CloseServiceHandle(hService); } // Close handle to the service control manager. if (hScManager) { CloseServiceHandle(hScManager); } return ret;}//// Start Virtual Disk Driver//DWORD VdkStart(DWORD *state){ SC_HANDLE hScManager; // Service Control Manager SC_HANDLE hService; // Service (= Driver) SERVICE_STATUS stat; DWORD ret = ERROR_SUCCESS; int i; // Connect to the Service Control Manager hScManager = OpenSCManager(NULL, NULL, 0); if (hScManager == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkStart: OpenSCManager() - %s\n", VdkStatusStr(ret))); return ret; } // Open Existing Service Object hService = OpenService( hScManager, // Service control manager VDK_DEVICE_BASENAME, // service name SERVICE_START | SERVICE_QUERY_STATUS); // service access mode if (hService == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkStart: OpenService(SERVICE_START) - %s\n", VdkStatusStr(ret))); goto cleanup; } // Start the driver if (!StartService(hService, 0, NULL)) { ret = GetLastError(); VDKTRACE(0, ("VdkStart: StartService() - %s\n", VdkStatusStr(ret))); goto cleanup; } // Ensure the driver is started for (i = 0;;) { if (!QueryServiceStatus(hService, &stat)) { ret = GetLastError(); VDKTRACE(0, ("VdkStart: QueryServiceStatus() - %s\n", VdkStatusStr(ret))); break; } if (stat.dwCurrentState == SERVICE_RUNNING || ++i == 5) { break; } Sleep(1000); } if (state) { *state = stat.dwCurrentState; }cleanup: // Close the service object handle if (hService) { CloseServiceHandle(hService); } // Close handle to the service control manager. if (hScManager) { CloseServiceHandle(hScManager); } return ret;}//// Stop Virtual Disk Driver//DWORD VdkStop(DWORD *state){ SC_HANDLE hScManager; // Service Control Manager SC_HANDLE hService; // Service (= Driver) SERVICE_STATUS stat; DWORD ret = ERROR_SUCCESS; int i = 0; // Connect to the Service Control Manager hScManager = OpenSCManager(NULL, NULL, 0); if (hScManager == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkStop: OpenSCManager() - %s\n", VdkStatusStr(ret))); return ret; } // Open Existing Service Object hService = OpenService( hScManager, // Service control manager VDK_DEVICE_BASENAME, // service name SERVICE_STOP | SERVICE_QUERY_STATUS); // service access mode if (hService == NULL) { ret = GetLastError(); VDKTRACE(0, ("VdkStop: OpenService(SERVICE_STOP) - %s\n", VdkStatusStr(ret))); goto cleanup; } // Stop the driver if (!ControlService(hService, SERVICE_CONTROL_STOP, &stat)) { ret = GetLastError(); VDKTRACE(0, ("VdkStop: ControlService(SERVICE_CONTROL_STOP) - %s\n", VdkStatusStr(ret))); goto cleanup; } // Ensure the driver is stopped while (stat.dwCurrentState != SERVICE_STOPPED && ++i < 5) { Sleep(1000); if (!QueryServiceStatus(hService, &stat)) { ret = GetLastError(); VDKTRACE(0, ("VdkStop: QueryServiceStatus() - %s\n", VdkStatusStr(ret))); break; } } if (state) { *state = stat.dwCurrentState; }cleanup: // Close the service object handle if (hService) { CloseServiceHandle(hService); } // Close handle to the service control manager. if (hScManager) { CloseServiceHandle(hScManager); } return ret;}//// Set number of initial device//DWORD VdkSetDeviceNum( ULONG device_num){ DWORD ret; HKEY hKey; if (device_num == 0 || device_num > VDK_MAXIMUM_DISK_NUM) { return ERROR_INVALID_PARAMETER; } ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, VDK_REG_CONFIG_KEY, 0, KEY_WRITE, &hKey); if (ret != ERROR_SUCCESS) { VDKTRACE(0, ("VdkSetDeviceNum: RegOpenKeyEx - %s\n", VdkStatusStr(ret))); return ret; } ret = RegSetValueEx( hKey, VDK_REG_DISKNUM_VALUE, 0, REG_DWORD, (PBYTE)&device_num, sizeof(device_num)); if (ret != ERROR_SUCCESS) { VDKTRACE(0, ("VdkSetDeviceNum: RegSetValueEx - %s\n", VdkStatusStr(ret))); } RegCloseKey(hKey); return ret;}//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -