当前位置:   article > 正文

WinIO3.0调用键盘实践-winxp、win7、win10下32位64位都适用

winio3.0

目录

 

准备

步骤

第一步:Windows系统开启测试模式(针对64位系统,32系统不需要)

第二步:WinIo64.sys安装签名(针对64位系统,32系统不需要)

第三步:Java代码及c++代码实现

 第四步:执行代码


准备

开发环境:winxp、win7、win10 32位及64位

开发语言:Java和c++

必要文件:WinIo32.dll、WinIo64.dll、WinIo32.sys、WinIo64.sys

步骤

(注:有些步骤的详细做法非常简单,如果不明白请问度哥)

第一步:Windows系统开启测试模式(针对64位系统,32系统不需要)

开启测试模式:cmd执行命令:bcdedit /set testsigning on 然后重启,电脑右下角出现测试模式......

关闭测试模式:cmd执行命令:bcdedit /set testsigning off 然后重启,电脑右下角测试模式消失

参考链接如下:

win10:https://jingyan.baidu.com/article/72ee561a724b74e16138df1c.html
win7、winxp:https://jingyan.baidu.com/article/acf728fd21c3e7f8e510a3ef.html

第二步:WinIo64.sys安装签名(针对64位系统,32系统不需要)

1、打开 WinIO64.sys的属性框,翻到“数字签名”选项卡,点击“详细信息”

2、在新出来的对话框中点击“查看证书”

3、在又新出来的对话框中点击“安装证书”

4、点击“下一步”,然后选择“将所有的证书放入下列存储”

5、点击浏览,选择“受信任的根证书发布机构”

6、点击“下一步”,然后点击“完成”

7、在弹出的“安全性警告”对话框中选择“是”,才能导入成功

8、重启电脑

第三步:Java代码及c++代码实现

网上有很多人使用jnative实现的,这里使用jna实现。jnative是在jna的基础上封装的有局限性。以下是maven依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>net.java.dev.jna</groupId>
  4. <artifactId>jna</artifactId>
  5. <version>4.4.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>net.java.dev.jna</groupId>
  9. <artifactId>jna-platform</artifactId>
  10. <version>4.4.0</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.apache.commons</groupId>
  14. <artifactId>commons-lang3</artifactId>
  15. <version>3.9</version>
  16. </dependency>
  17. </dependencies>

winio代码实现

  1. import com.sun.jna.Library;
  2. import com.sun.jna.Native;
  3. import com.sun.jna.Pointer;
  4. import com.sun.jna.WString;
  5. import com.sun.jna.win32.W32APIOptions;
  6. /**
  7. * author songxq
  8. * date 2020/6/18
  9. * description
  10. */
  11. public interface WinIo extends Library {
  12. /**
  13. * 系统架构32位或者64位
  14. */
  15. String ARCH = System.getProperty("os.arch");
  16. /**
  17. * 使用的winio版本
  18. */
  19. String WIN_IO_LIB_NAME = "x86".equals(ARCH) ? "WinIo32" : "WinIo64";
  20. WinIo INSTANCE = (WinIo) Native.loadLibrary(WIN_IO_LIB_NAME, WinIo.class, W32APIOptions.DEFAULT_OPTIONS);
  21. /**
  22. * PS/2键盘的命令端口
  23. */
  24. int CONTROL_PORT = 0x64;
  25. /**
  26. * PS/2键盘的数据端口
  27. */
  28. int DATA_PORT = 0x60;
  29. /**
  30. * 初始化winiolib库
  31. * @param path 驱动文件绝对路径
  32. * @return
  33. */
  34. boolean InitializeWinIo(WString path);
  35. /**
  36. * 释放资源及开辟的内存空间
  37. */
  38. void ShutdownWinIo();
  39. /**
  40. * 读数据
  41. * 98/ME系列使用GetPortVal NT/2000/XP系列可以使用_inp/_inpw/_inpd
  42. * @param portAddr io地址
  43. * @param pPortVal 指针变量
  44. * @param size 数据大小
  45. * @return
  46. */
  47. boolean GetPortVal(int portAddr, Pointer pPortVal, int size);
  48. /**
  49. * 写数据
  50. * @param portAddr io地址
  51. * @param portVal 指针变量
  52. * @param size 数据大小
  53. * @return
  54. */
  55. boolean SetPortVal(int portAddr, int portVal, int size);
  56. }

键盘调用代码

  1. import com.sun.jna.Memory;
  2. import com.sun.jna.Pointer;
  3. import com.sun.jna.WString;
  4. import java.io.File;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.nio.file.Files;
  8. import java.nio.file.Paths;
  9. import java.nio.file.StandardCopyOption;
  10. /**
  11. * author songxq
  12. * date 2020/6/18
  13. * description
  14. */
  15. public class VirtualKB {
  16. private static final WinIo WIN_IO = WinIo.INSTANCE;
  17. private static final String WIN_BASE_SYSTEM32 = "C:\\Windows\\System32";
  18. private static final String WINIO_INSTALL_PATH = "C:\\INSTALLWINIO";
  19. private static final String WINIO_INSTALL_EXE = "C:\\INSTALLWINIO\\InstallWinIo.exe";
  20. private static final String WIN_32_SYS = "WinIo32.sys";
  21. private static final String WIN_64_SYS = "WinIo64.sys";
  22. //keyame
  23. public static final String Tab = "Tab";
  24. public static final String Esc = "Esc";
  25. public static final String Backspace = "Backspace";
  26. public static final String Enter = "Enter";
  27. public static final String LCtrl = "LCtrl";
  28. public static final String LShift = "LShift";
  29. public static final String RShift = "RShift";
  30. public static final String LAlt = "LAlt";
  31. public static final String Space = "Space";
  32. public static final String CapsLock = "CapsLock";
  33. public static final String F1 = "F1";
  34. public static final String F2 = "F2";
  35. public static final String F3 = "F3";
  36. public static final String F4 = "F4";
  37. public static final String F5 = "F5";
  38. public static final String F6 = "F6";
  39. public static final String F7 = "F7";
  40. public static final String F8 = "F8";
  41. public static final String F9 = "F9";
  42. public static final String F10 = "F10";
  43. public static final String F11 = "F11";
  44. public static final String F12 = "F12";
  45. public static final String NumLock = "NumLock";
  46. public static final String ScrollLock = "ScrollLock";
  47. static{
  48. String x86 = "x86";
  49. String driverName;
  50. if (x86.equals(WinIo.ARCH)) {
  51. driverName = WIN_BASE_SYSTEM32 + File.separator + WIN_32_SYS;
  52. } else {
  53. driverName = WIN_BASE_SYSTEM32 + File.separator + WIN_64_SYS;
  54. }
  55. if(!WIN_IO.InitializeWinIo(new WString(driverName))){
  56. installSys();
  57. }
  58. }
  59. /**
  60. * 等待缓冲区置空
  61. */
  62. private static void KBCWait4IBE() {
  63. int val;
  64. do {
  65. Pointer p = new Memory(8);
  66. if (!WIN_IO.GetPortVal(WinIo.CONTROL_PORT, p, 1)) {
  67. throw new RuntimeException("Cannot Get The Port!");
  68. }
  69. val = p.getInt(0);
  70. } while ((0x2 & val) > 0);
  71. }
  72. private static void down(int key) {
  73. KBCWait4IBE();
  74. WIN_IO.SetPortVal(WinIo.CONTROL_PORT, 0xd2, 1);
  75. KBCWait4IBE();
  76. WIN_IO.SetPortVal(WinIo.DATA_PORT, key, 1);
  77. }
  78. private static void up(int key) {
  79. KBCWait4IBE();
  80. WIN_IO.SetPortVal(WinIo.CONTROL_PORT, 0xd2, 1);
  81. KBCWait4IBE();
  82. WIN_IO.SetPortVal(WinIo.DATA_PORT, (key | 0x80), 1);
  83. }
  84. private static void press(String[] words, long firstSleepTime, long sleepTime) throws Exception{
  85. if (null == words || words.length == 0) {
  86. throw new IllegalArgumentException("words Is NULL Or Empty");
  87. }
  88. int minSleepTime = 50;
  89. if (sleepTime < minSleepTime) {
  90. throw new IllegalArgumentException("SleepTime Less Than 50 ms");
  91. }
  92. if (firstSleepTime > 0) {
  93. Thread.sleep(firstSleepTime);
  94. }
  95. for (String word : words) {
  96. Integer vk = VirtualKBMapping.VK_MAP.get(word);
  97. if (null == vk) {
  98. vk = VirtualKBMapping.NEED_SHIFT_VK.get(word);
  99. }
  100. if (null == vk) {
  101. throw new RuntimeException(word + " Not Support");
  102. }
  103. boolean needShift = word.length() == 1 && null != VirtualKBMapping.NEED_SHIFT_VK.get(word);
  104. if (needShift) {
  105. down(VirtualKBMapping.VK_MAP.get("LShift"));
  106. }
  107. down(vk);
  108. Thread.sleep(sleepTime);
  109. up(vk);
  110. if (needShift) {
  111. up(VirtualKBMapping.VK_MAP.get("LShift"));
  112. }
  113. }
  114. }
  115. /**
  116. * 键盘输入文本
  117. * @param content 文本
  118. * @param sleepTime 等待时间间隔
  119. */
  120. public static void inputStr(String content,long sleepTime) throws Exception {
  121. if (null == content || content.length() == 0) {
  122. throw new IllegalArgumentException("content Is NULL Or Empty");
  123. }
  124. char[] chars = content.toCharArray();
  125. for (int i=0;i<chars.length;i++){
  126. press(new String[]{String.valueOf(chars[i])},sleepTime,50);
  127. }
  128. }
  129. /**
  130. * 键盘按键
  131. * @param keyname 按键名称
  132. * @param sleepTime 等待时间间隔
  133. */
  134. public static void pressKey(String keyname,long sleepTime) throws Exception {
  135. if (null == keyname || keyname.length() == 0) {
  136. throw new IllegalArgumentException("keyname Is NULL Or Empty");
  137. }
  138. press(new String[]{keyname},sleepTime,50);
  139. }
  140. private static void extract(final String fileName, final String name) {
  141. if (new File(fileName).exists()) {
  142. return;
  143. }
  144. try(InputStream inputStream = VirtualKB.class.getResourceAsStream("/" + name)) {
  145. Files.copy(inputStream, Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING);
  146. } catch (IOException e) {
  147. e.printStackTrace();
  148. }
  149. }
  150. /**
  151. * 执行sys驱动安装
  152. */
  153. public static void installSys() {
  154. if (!new File(WINIO_INSTALL_EXE).exists()) {
  155. if(!new File(WINIO_INSTALL_PATH).exists()){
  156. new File(WINIO_INSTALL_PATH).mkdirs();
  157. }
  158. extract(WINIO_INSTALL_EXE,"InstallWinIo.exe");
  159. }
  160. Runtime rn = Runtime.getRuntime();
  161. Process p = null;
  162. try {
  163. p = rn.exec(WINIO_INSTALL_EXE);
  164. } catch (Exception e) {
  165. e.printStackTrace();
  166. }
  167. }
  168. }

虚拟键盘映射代码

  1. import org.apache.commons.lang3.StringUtils;
  2. import java.util.Arrays;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. /**
  6. * author songxq
  7. * date 2020/6/18
  8. * description
  9. */
  10. public class VirtualKBMapping {
  11. /**
  12. * 映射基本键map
  13. */
  14. static final Map<String, Integer> VK_MAP = new HashMap<>();
  15. /**
  16. * 映射shift转换键map
  17. */
  18. static final Map<String, Integer> NEED_SHIFT_VK = new HashMap<>();
  19. static {
  20. VK_MAP.put("Esc", 0x01);
  21. VK_MAP.put("1", 0x02);
  22. VK_MAP.put("2", 0x03);
  23. VK_MAP.put("3", 0x04);
  24. VK_MAP.put("4", 0x05);
  25. VK_MAP.put("5", 0x06);
  26. VK_MAP.put("6", 0x07);
  27. VK_MAP.put("7", 0x08);
  28. VK_MAP.put("8", 0x09);
  29. VK_MAP.put("9", 0x0a);
  30. VK_MAP.put("0", 0x0b);
  31. VK_MAP.put("-", 0x0c);
  32. VK_MAP.put("=", 0x0d);
  33. VK_MAP.put("Backspace", 0x0e);
  34. VK_MAP.put("Tab", 0x0f);
  35. VK_MAP.put("q", 0x10);
  36. VK_MAP.put("w", 0x11);
  37. VK_MAP.put("e", 0x12);
  38. VK_MAP.put("r", 0x13);
  39. VK_MAP.put("t", 0x14);
  40. VK_MAP.put("y", 0x15);
  41. VK_MAP.put("u", 0x16);
  42. VK_MAP.put("i", 0x17);
  43. VK_MAP.put("o", 0x18);
  44. VK_MAP.put("p", 0x19);
  45. VK_MAP.put("[", 0x1a);
  46. VK_MAP.put("]", 0x1b);
  47. VK_MAP.put("Enter", 0x1c);
  48. VK_MAP.put("LCtrl", 0x1d);
  49. VK_MAP.put("a", 0x1e);
  50. VK_MAP.put("s", 0x1f);
  51. VK_MAP.put("d", 0x20);
  52. VK_MAP.put("f", 0x21);
  53. VK_MAP.put("g", 0x22);
  54. VK_MAP.put("h", 0x23);
  55. VK_MAP.put("j", 0x24);
  56. VK_MAP.put("k", 0x25);
  57. VK_MAP.put("l", 0x26);
  58. VK_MAP.put(";", 0x27);
  59. VK_MAP.put("'", 0x28);
  60. VK_MAP.put("`", 0x29);
  61. VK_MAP.put("LShift", 0x2a);
  62. VK_MAP.put("\\", 0x2b);
  63. VK_MAP.put("z", 0x2c);
  64. VK_MAP.put("x", 0x2d);
  65. VK_MAP.put("c", 0x2e);
  66. VK_MAP.put("v", 0x2f);
  67. VK_MAP.put("b", 0x30);
  68. VK_MAP.put("n", 0x31);
  69. VK_MAP.put("m", 0x32);
  70. VK_MAP.put(",", 0x33);
  71. VK_MAP.put(".", 0x34);
  72. VK_MAP.put("/", 0x35);
  73. VK_MAP.put("RShift", 0x36);
  74. VK_MAP.put("LAlt", 0x38);
  75. VK_MAP.put("Space", 0x39);
  76. VK_MAP.put("CapsLock", 0x3a);
  77. VK_MAP.put("F1", 0x3b);
  78. VK_MAP.put("F2", 0x3c);
  79. VK_MAP.put("F3", 0x3d);
  80. VK_MAP.put("F4", 0x3e);
  81. VK_MAP.put("F5", 0x3f);
  82. VK_MAP.put("F6", 0x40);
  83. VK_MAP.put("F7", 0x41);
  84. VK_MAP.put("F8", 0x42);
  85. VK_MAP.put("F9", 0x43);
  86. VK_MAP.put("F10", 0x44);
  87. VK_MAP.put("NumLock", 0x45);
  88. VK_MAP.put("ScrollLock", 0x46);
  89. VK_MAP.put("F11", 0x57);
  90. VK_MAP.put("F12", 0x58);
  91. }
  92. static {
  93. NEED_SHIFT_VK.put("!", 0x02);
  94. NEED_SHIFT_VK.put("@", 0x03);
  95. NEED_SHIFT_VK.put("#", 0x04);
  96. NEED_SHIFT_VK.put("$", 0x05);
  97. NEED_SHIFT_VK.put("%", 0x06);
  98. NEED_SHIFT_VK.put("^", 0x07);
  99. NEED_SHIFT_VK.put("&", 0x08);
  100. NEED_SHIFT_VK.put("*", 0x09);
  101. NEED_SHIFT_VK.put("(", 0x0a);
  102. NEED_SHIFT_VK.put(")", 0x0b);
  103. NEED_SHIFT_VK.put("_", 0x0c);
  104. NEED_SHIFT_VK.put("+", 0x0d);
  105. NEED_SHIFT_VK.put("{", 0x1a);
  106. NEED_SHIFT_VK.put("}", 0x1b);
  107. NEED_SHIFT_VK.put(":", 0x27);
  108. NEED_SHIFT_VK.put("\"", 0x28);
  109. NEED_SHIFT_VK.put("~", 0x29);
  110. NEED_SHIFT_VK.put("|", 0x2b);
  111. NEED_SHIFT_VK.put("<", 0x33);
  112. NEED_SHIFT_VK.put(">", 0x34);
  113. NEED_SHIFT_VK.put("?", 0x35);
  114. NEED_SHIFT_VK.put("Q", 0x10);
  115. NEED_SHIFT_VK.put("W", 0x11);
  116. NEED_SHIFT_VK.put("E", 0x12);
  117. NEED_SHIFT_VK.put("R", 0x13);
  118. NEED_SHIFT_VK.put("T", 0x14);
  119. NEED_SHIFT_VK.put("Y", 0x15);
  120. NEED_SHIFT_VK.put("U", 0x16);
  121. NEED_SHIFT_VK.put("I", 0x17);
  122. NEED_SHIFT_VK.put("O", 0x18);
  123. NEED_SHIFT_VK.put("P", 0x19);
  124. NEED_SHIFT_VK.put("A", 0x1e);
  125. NEED_SHIFT_VK.put("S", 0x1f);
  126. NEED_SHIFT_VK.put("D", 0x20);
  127. NEED_SHIFT_VK.put("F", 0x21);
  128. NEED_SHIFT_VK.put("G", 0x22);
  129. NEED_SHIFT_VK.put("H", 0x23);
  130. NEED_SHIFT_VK.put("J", 0x24);
  131. NEED_SHIFT_VK.put("K", 0x25);
  132. NEED_SHIFT_VK.put("L", 0x26);
  133. NEED_SHIFT_VK.put("Z", 0x2c);
  134. NEED_SHIFT_VK.put("X", 0x2d);
  135. NEED_SHIFT_VK.put("C", 0x2e);
  136. NEED_SHIFT_VK.put("V", 0x2f);
  137. NEED_SHIFT_VK.put("B", 0x30);
  138. NEED_SHIFT_VK.put("N", 0x31);
  139. NEED_SHIFT_VK.put("M", 0x32);
  140. }
  141. /**
  142. * 返回所有支持的按键
  143. */
  144. public static String[] getSupportKeys() {
  145. String[] vkArray = VK_MAP.keySet().toArray(new String[0]);
  146. String[] needShiftVKArray = NEED_SHIFT_VK.keySet().toArray(new String[0]);
  147. String[] supportKeys = new String[vkArray.length + needShiftVKArray.length];
  148. System.arraycopy(vkArray, 0, supportKeys, 0, vkArray.length);
  149. System.arraycopy(needShiftVKArray, 0, supportKeys, vkArray.length, needShiftVKArray.length);
  150. return supportKeys;
  151. }
  152. /**
  153. * 返回是否支持按键
  154. */
  155. public static boolean isSupportKey(String key) {
  156. return StringUtils.join(Arrays.asList(VirtualKBMapping.getSupportKeys()),"").contains(key);
  157. }
  158. }

 

 c++装载驱动代码可以生成为dll文件调用,也可生成为exe文件调用。这里编译为exe。

注:生成dll文件及exe文件的时候一定生成64位的文件(32位系统不需要这个)。

  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <winsvc.h>
  4. #include <conio.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <tchar.h>
  8. #pragma comment (lib, "Advapi32.lib")
  9. #pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
  10. #define DRIVER_NAME "WinIo64"
  11. #define DRIVER_PATH "C:\\Windows\\System32\\WinIo64.sys"
  12. //装载NT驱动程序
  13. BOOL LoadNTDriver(char* lpszDriverName, char* lpszDriverPath)
  14. {
  15. char szDriverImagePath[256];
  16. //得到完整的驱动路径
  17. GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
  18. BOOL bRet = FALSE;
  19. SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
  20. SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄
  21. //打开服务控制管理器
  22. hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  23. if (hServiceMgr == NULL)
  24. {
  25. //OpenSCManager失败
  26. printf("OpenSCManager() Faild ! \n");
  27. //printf(GetLastError());
  28. bRet = FALSE;
  29. goto BeforeLeave;
  30. }
  31. else
  32. {
  33. OpenSCManager成功
  34. printf("OpenSCManager() ok ! \n");
  35. }
  36. //创建驱动所对应的服务
  37. hServiceDDK = CreateService(hServiceMgr,
  38. lpszDriverName, //驱动程序的在注册表中的名字
  39. lpszDriverName, // 注册表驱动程序的 DisplayName 值
  40. SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
  41. SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序
  42. SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值
  43. SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值
  44. szDriverImagePath, // 注册表驱动程序的 ImagePath 值
  45. NULL,
  46. NULL,
  47. NULL,
  48. NULL,
  49. NULL);
  50. DWORD dwRtn;
  51. //判断服务是否失败
  52. if (hServiceDDK == NULL)
  53. {
  54. dwRtn = GetLastError();
  55. if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
  56. {
  57. //由于其他原因创建服务失败
  58. printf("CrateService() Faild ! \n");
  59. ///printf(dwRtn);
  60. bRet = FALSE;
  61. goto BeforeLeave;
  62. }
  63. else
  64. {
  65. //服务创建失败,是由于服务已经创立过
  66. printf("CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n");
  67. }
  68. // 驱动程序已经加载,只需要打开
  69. hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS);
  70. if (hServiceDDK == NULL)
  71. {
  72. //如果打开服务也失败,则意味错误
  73. dwRtn = GetLastError();
  74. printf("OpenService() Faild ! \n");
  75. //printf(dwRtn);
  76. bRet = FALSE;
  77. goto BeforeLeave;
  78. }
  79. else
  80. {
  81. printf("OpenService() ok ! \n");
  82. }
  83. }
  84. else
  85. {
  86. printf("CrateService() ok ! \n");
  87. }
  88. //开启此项服务
  89. bRet = StartService(hServiceDDK, NULL, NULL);
  90. if (!bRet)
  91. {
  92. DWORD dwRtn = GetLastError();
  93. if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING)
  94. {
  95. printf("StartService() Faild ! \n" );
  96. //printf(dwRtn);
  97. bRet = FALSE;
  98. goto BeforeLeave;
  99. }
  100. else
  101. {
  102. if (dwRtn == ERROR_IO_PENDING)
  103. {
  104. //设备被挂住
  105. printf("StartService() Faild ERROR_IO_PENDING ! \n");
  106. bRet = FALSE;
  107. goto BeforeLeave;
  108. }
  109. else
  110. {
  111. //服务已经开启
  112. printf("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
  113. bRet = TRUE;
  114. goto BeforeLeave;
  115. }
  116. }
  117. }
  118. bRet = TRUE;
  119. //离开前关闭句柄
  120. BeforeLeave:
  121. if (hServiceDDK)
  122. {
  123. CloseServiceHandle(hServiceDDK);
  124. }
  125. if (hServiceMgr)
  126. {
  127. CloseServiceHandle(hServiceMgr);
  128. }
  129. return bRet;
  130. }
  131. //卸载驱动程序
  132. BOOL UnloadNTDriver(char * szSvrName)
  133. {
  134. BOOL bRet = FALSE;
  135. SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
  136. SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄
  137. SERVICE_STATUS SvrSta;
  138. //打开SCM管理器
  139. hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  140. if (hServiceMgr == NULL)
  141. {
  142. //带开SCM管理器失败
  143. printf("OpenSCManager() Faild ! \n");
  144. //printf(GetLastError());
  145. bRet = FALSE;
  146. goto BeforeLeave;
  147. }
  148. else
  149. {
  150. //带开SCM管理器失败成功
  151. printf("OpenSCManager() ok ! \n");
  152. }
  153. //打开驱动所对应的服务
  154. hServiceDDK = OpenService(hServiceMgr, szSvrName, SERVICE_ALL_ACCESS);
  155. if (hServiceDDK == NULL)
  156. {
  157. //打开驱动所对应的服务失败
  158. printf("OpenService() Faild ! \n");
  159. //printf(GetLastError());
  160. bRet = FALSE;
  161. goto BeforeLeave;
  162. }
  163. else
  164. {
  165. printf("OpenService() ok ! \n");
  166. }
  167. //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。
  168. if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta))
  169. {
  170. printf("ControlService() Faild %d !\n", GetLastError());
  171. }
  172. else
  173. {
  174. //打开驱动所对应的失败
  175. printf("ControlService() ok !\n");
  176. }
  177. //动态卸载驱动程序。
  178. if (!DeleteService(hServiceDDK))
  179. {
  180. //卸载失败
  181. printf("DeleteSrevice() Faild %d !\n", GetLastError());
  182. }
  183. else
  184. {
  185. //卸载成功
  186. printf("DelServer:eleteSrevice() ok !\n");
  187. }
  188. bRet = TRUE;
  189. BeforeLeave:
  190. //离开前关闭打开的句柄
  191. if (hServiceDDK)
  192. {
  193. CloseServiceHandle(hServiceDDK);
  194. }
  195. if (hServiceMgr)
  196. {
  197. CloseServiceHandle(hServiceMgr);
  198. }
  199. return bRet;
  200. }
  201. int main(int argc, char* argv[])
  202. {
  203. //加载驱动
  204. BOOL bRet = LoadNTDriver(DRIVER_NAME, DRIVER_PATH);
  205. if (!bRet)
  206. {
  207. printf("install winio error\n");
  208. return 0;
  209. }
  210. //加载成功
  211. //printf("install winio successed!\n");
  212. //getch();
  213. //这时候你可以通过注册表,或其他查看符号连接的软件验证。
  214. //printf("press any to unload the driver!\n");
  215. //getch();
  216. //卸载驱动
  217. //BOOL bRet = UnloadNTDriver(DRIVER_NAME);
  218. //if (!bRet)
  219. //{
  220. // printf("unload winio error!\n");
  221. // return 0;
  222. //}
  223. //printf("unload winio successed!\n");
  224. //return 0;
  225. }

 第四步:执行代码

大家按照上述代码都写好后就是执行了。有人可能成功了,有人可能还不行。所以下面介绍下这个代码基本的运行逻辑。供大家自行调整bug。

windows系统开启测试模式后,winio64.sys安装签名后。

执行代码:

1、***首先执行装载winio64.sys驱动代码,就是c++生成的dll或者exe文件里的LoadNTDriver方法。(这一步必须有,网上大部分没有这一步,所以大部分你试了都不会成功。)

2、执行winio的初始化方法 InitializeWinIo

3、KBCWait4IBE方法等待0x64控制端口空闲

4、0x64控制端口空闲时SetPortVal发送命令到0x64端口,在发送按键对应的虚拟码到0x60端口即可

5、winio.ShutdownWinIo释放资源

6、winio64.sys驱动加载后,系统重启后需要重新加载(注意)

以上即是本人实践总结,欢迎留言交流。

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号