lowl-mswin.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright 2014 Luke Dashjr
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <malloc.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <objbase.h>
  15. #include <rpc.h>
  16. #include <setupapi.h>
  17. #include <utlist.h>
  18. #include "logging.h"
  19. #include "lowlevel.h"
  20. #include "lowl-mswin.h"
  21. #include "util.h"
  22. static
  23. struct lowlevel_device_info *mswin_devinfo_scan()
  24. {
  25. struct lowlevel_device_info *devinfo_list = NULL, *info;
  26. HDEVINFO devinfo = SetupDiGetClassDevs(NULL, NULL, NULL, (DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));
  27. if (INVALID_HANDLE_VALUE == devinfo)
  28. applogfailinfor(NULL, LOG_DEBUG, "SetupDiGetClassDevs", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
  29. SP_DEVINFO_DATA devinfodata = {
  30. .cbSize = sizeof(devinfodata),
  31. };
  32. SP_DEVICE_INTERFACE_DATA devifacedata = {
  33. .cbSize = sizeof(devifacedata),
  34. };
  35. for (int i = 0; SetupDiEnumDeviceInfo(devinfo, i, &devinfodata); ++i)
  36. {
  37. // FIXME: Figure out a way to get all GUIDs here
  38. if (!SetupDiEnumDeviceInterfaces(devinfo, &devinfodata, &WIN_GUID_DEVINTERFACE_MonarchKMDF, 0, &devifacedata))
  39. {
  40. applogfailinfo(LOG_DEBUG, "SetupDiEnumDeviceInterfaces", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
  41. continue;
  42. }
  43. DWORD detailsz;
  44. if (!(!SetupDiGetDeviceInterfaceDetail(devinfo, &devifacedata, NULL, 0, &detailsz, NULL) && GetLastError() == ERROR_INSUFFICIENT_BUFFER))
  45. {
  46. applogfailinfo(LOG_ERR, "SetupDiEnumDeviceInterfaceDetail (1)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
  47. continue;
  48. }
  49. PSP_DEVICE_INTERFACE_DETAIL_DATA detail = alloca(detailsz);
  50. detail->cbSize = sizeof(*detail);
  51. if (!SetupDiGetDeviceInterfaceDetail(devinfo, &devifacedata, detail, detailsz, &detailsz, NULL))
  52. {
  53. applogfailinfo(LOG_ERR, "SetupDiEnumDeviceInterfaceDetail (2)", "%s", bfg_strerror(GetLastError(), BST_SYSTEM));
  54. continue;
  55. }
  56. char *devid = malloc(6 + strlen(detail->DevicePath) + 1);
  57. sprintf(devid, "mswin:%s", detail->DevicePath);
  58. info = malloc(sizeof(struct lowlevel_device_info));
  59. *info = (struct lowlevel_device_info){
  60. .lowl = &lowl_mswin,
  61. .devid = devid,
  62. .path = strdup(detail->DevicePath),
  63. .lowl_data = (void *)&WIN_GUID_DEVINTERFACE_MonarchKMDF,
  64. };
  65. LL_PREPEND(devinfo_list, info);
  66. }
  67. SetupDiDestroyDeviceInfoList(devinfo);
  68. return devinfo_list;
  69. }
  70. bool lowl_mswin_match_guid(const struct lowlevel_device_info * const info, const GUID * const guid)
  71. {
  72. if (info->lowl != &lowl_mswin)
  73. return false;
  74. return IsEqualGUID(info->lowl_data, guid);
  75. }
  76. struct lowlevel_driver lowl_mswin = {
  77. .dname = "mswin",
  78. .devinfo_scan = mswin_devinfo_scan,
  79. };