Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. instdev.c
  5. Abstract:
  6. Implements InstallDevice
  7. Environment:
  8. Usre mode
  9. Revision History:
  10. 27-Jun-1997 : Bogdan Andreiu (bogdana) created from testdrv.c
  11. 25-April-2002 ; Bogdan Andreiu (bogdana) - resued for testing IoCreateDeviceSecure
  12. --*/
  13. #include "instdev.h"
  14. #include <initguid.h>
  15. #include <devguid.h>
  16. #include "common.h"
  17. BOOL
  18. InstallDevice (
  19. IN PTSTR DeviceName,
  20. IN PTSTR HardwareId,
  21. IN PTSTR FinalDeviceName
  22. )
  23. /*++
  24. Routine Description
  25. The routine creates a key in the registry for the device, register
  26. the device, adds the hardware ID and then attempts to find a driver
  27. for the device. Note that you need an INF file in which the hardware
  28. ID matches the hardware ID supplied here.
  29. Arguments
  30. DeviceName - the name for the device; if it is NULL, it is
  31. generated a name with the device name GENERATED
  32. HardwareId - must match the one in the INF file. Should be \0\0 terminated !!!
  33. FinalDeviceName - the name the system assigned to our device
  34. We assume that the buffer was properly allocated
  35. and will return an empty string if the name can't
  36. be written in the buffer
  37. Return Value
  38. None
  39. --*/
  40. {
  41. DWORD dwFlag = 0;
  42. BOOL bResult;
  43. HDEVINFO DeviceInfoSet;
  44. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  45. SP_DEVINFO_DATA DeviceInfoData;
  46. TCHAR szAux[MAX_PATH];
  47. DEVNODE dnRoot;
  48. if (FinalDeviceName) {
  49. FinalDeviceName[0] = TEXT('\0');
  50. }
  51. //
  52. // Analyze the name first
  53. //
  54. if (DeviceName == NULL) {
  55. DeviceName = DEFAULT_DEVICE_NAME;
  56. dwFlag = DICD_GENERATE_ID;
  57. }
  58. if (HardwareId == NULL) {
  59. _tprintf(TEXT("Can't install a with a NULL hardware ID...(0x%x)\n"),
  60. GetLastError());
  61. return FALSE;
  62. }
  63. if (!_tcschr(DeviceName, TEXT('\\'))) {
  64. //
  65. // We need to generate
  66. //
  67. dwFlag = DICD_GENERATE_ID;
  68. }
  69. DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL,
  70. NULL);
  71. if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
  72. _tprintf(TEXT("Unable to create device info list (0x%x)\n"),
  73. GetLastError());
  74. return FALSE;
  75. }
  76. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  77. if (!SetupDiCreateDeviceInfo(DeviceInfoSet,
  78. DeviceName,
  79. (LPGUID)&GUID_DEVCLASS_UNKNOWN,
  80. NULL,
  81. NULL, // hwndParent
  82. dwFlag,
  83. &DeviceInfoData)) {
  84. _tprintf(TEXT("Can't create the device info (0x%x)\n"),
  85. GetLastError());
  86. return FALSE;
  87. }
  88. //
  89. // Register the new guy
  90. //
  91. bResult = SetupDiRegisterDeviceInfo(DeviceInfoSet,
  92. &DeviceInfoData,
  93. 0, // Flags
  94. NULL, // CompareProc
  95. NULL, // CompareContext
  96. NULL // DupDeviceInfoData
  97. );
  98. bResult = SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
  99. &DeviceInfoData,
  100. SPDRP_HARDWAREID,
  101. (PBYTE)HardwareId,
  102. (_tcslen(HardwareId) + 2) * sizeof(TCHAR)
  103. // this is a multistring...
  104. );
  105. if (!bResult) {
  106. _tprintf(TEXT("Unable to set hardware ID (0x%x)\n"),
  107. GetLastError());
  108. return FALSE;
  109. }
  110. bResult = SetupDiBuildDriverInfoList(DeviceInfoSet,
  111. &DeviceInfoData,
  112. SPDIT_COMPATDRIVER);
  113. if (!bResult) {
  114. _tprintf(TEXT("Unable to build driver list (0x%x)\n"),
  115. GetLastError());
  116. return FALSE;
  117. }
  118. //
  119. // select the best driver (the only one, in fact...)
  120. //
  121. bResult = SetupDiSelectBestCompatDrv(DeviceInfoSet,
  122. &DeviceInfoData
  123. );
  124. if (!bResult) {
  125. _tprintf(TEXT("Unable to select best driver (0x%x)\n"),
  126. GetLastError());
  127. // return FALSE;
  128. }
  129. DeviceInstallParams.FlagsEx=DI_FLAGSEX_PREINSTALLBACKUP;
  130. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  131. if (!(SetupDiSetDeviceInstallParams(DeviceInfoSet,NULL,&DeviceInstallParams))) {
  132. _tprintf(TEXT("Unable to set the Device Install Params\n"));
  133. }
  134. bResult = SetupDiInstallDevice(DeviceInfoSet,
  135. &DeviceInfoData
  136. );
  137. if (!bResult) {
  138. _tprintf(TEXT("Unable to install device (0x%x)\n"),
  139. GetLastError());
  140. return FALSE;
  141. }
  142. if (FinalDeviceName &&
  143. ! SetupDiGetDeviceInstanceId(
  144. DeviceInfoSet,
  145. &DeviceInfoData,
  146. FinalDeviceName,
  147. MAX_PATH,
  148. NULL)) {
  149. //
  150. // Reset the name
  151. //
  152. FinalDeviceName = TEXT('\0');
  153. }
  154. _tprintf(TEXT("Name = %s\n"), FinalDeviceName);
  155. //
  156. // Clean up
  157. //
  158. SetupDiDeleteDeviceInfo(DeviceInfoSet,
  159. &DeviceInfoData
  160. );
  161. SetupDiDestroyDeviceInfoList(DeviceInfoSet);
  162. //
  163. // Well, this should have been done already, but just in case...
  164. //
  165. if (CR_SUCCESS == CM_Locate_DevNode(&dnRoot,
  166. NULL,
  167. CM_LOCATE_DEVNODE_NORMAL)
  168. ) {
  169. CM_Reenumerate_DevNode(dnRoot, CM_REENUMERATE_SYNCHRONOUS);
  170. }
  171. return TRUE;
  172. }
  173. HANDLE
  174. OpenDriver (
  175. VOID
  176. )
  177. /*++
  178. Routine Description
  179. The routine opens a handle to a device driven by the wdmsectest.sys driver
  180. We'll use this later to instruct the driver to report legacy devices.
  181. The handle should be closed with CloseHandle.
  182. Arguments
  183. None.
  184. Return Value
  185. A valid handle if success, INVALID_HANDLE_VALUE if not.
  186. --*/
  187. {
  188. HANDLE hDevice;
  189. HDEVINFO hDevInfo;
  190. SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
  191. TCHAR szMsg[MAX_PATH];
  192. //
  193. // This is the user-defined structure that will holds the interface
  194. // device name (SP_DEVICE_INTERFACE_DETAIL_DATA will have room for
  195. // only one character)
  196. //
  197. struct {
  198. DWORD cbSize;
  199. TCHAR DevicePath[MAX_PATH];
  200. } DeviceInterfaceDetailData;
  201. hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_WDMSECTEST_REPORT_DEVICE, NULL,
  202. NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
  203. if (hDevInfo == INVALID_HANDLE_VALUE) {
  204. _stprintf(szMsg, TEXT("Unable to get class devs (%d)\n"),
  205. GetLastError());
  206. OutputDebugString(szMsg);
  207. return INVALID_HANDLE_VALUE;
  208. }
  209. DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  210. if (!SetupDiEnumDeviceInterfaces(hDevInfo,
  211. NULL,
  212. (LPGUID)&GUID_WDMSECTEST_REPORT_DEVICE,
  213. 0,
  214. &DeviceInterfaceData)) {
  215. _stprintf(szMsg, TEXT("Unable to enum interfaces (%d)\n"),
  216. GetLastError());
  217. OutputDebugString(szMsg);
  218. return INVALID_HANDLE_VALUE;
  219. }
  220. DeviceInterfaceDetailData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  221. if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,
  222. &DeviceInterfaceData,
  223. (PSP_DEVICE_INTERFACE_DETAIL_DATA)&DeviceInterfaceDetailData,
  224. sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH - 1,
  225. NULL,
  226. NULL)) {
  227. _stprintf(szMsg, TEXT("Unable to get detail (%d)\n"),
  228. GetLastError());
  229. OutputDebugString(szMsg);
  230. return INVALID_HANDLE_VALUE;
  231. }
  232. //
  233. // We got the name !!! Go ahead and create the file
  234. //
  235. hDevice = CreateFile(DeviceInterfaceDetailData.DevicePath,
  236. GENERIC_READ | GENERIC_WRITE,
  237. FILE_SHARE_READ | FILE_SHARE_WRITE,
  238. NULL,
  239. OPEN_EXISTING,
  240. FILE_ATTRIBUTE_NORMAL,
  241. NULL);
  242. if (hDevice == INVALID_HANDLE_VALUE) {
  243. _stprintf(szMsg, TEXT("Unable to CreateFile for %s (error %d)\n"),
  244. DeviceInterfaceDetailData.DevicePath,
  245. GetLastError());
  246. OutputDebugString(szMsg);
  247. return INVALID_HANDLE_VALUE;
  248. }
  249. SetupDiDestroyDeviceInfoList(hDevInfo);
  250. return hDevice ;
  251. }