Source code of Windows XP (NT5)
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.

447 lines
13 KiB

  1. /*****************************************************************************
  2. *
  3. * DIAddHw.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Add New Hardware
  10. *
  11. * Contents:
  12. *
  13. * AddNewHardware
  14. *
  15. *****************************************************************************/
  16. #include "dinputpr.h"
  17. #include "dithunk.h"
  18. #pragma BEGIN_CONST_DATA
  19. /*****************************************************************************
  20. *
  21. * The sqiffle for this file.
  22. *
  23. *****************************************************************************/
  24. #define sqfl sqflJoyCfg
  25. #ifdef IDirectInputJoyConfig_QueryInterface
  26. #define case95(n) case n:
  27. #define caseNT(n) case n:
  28. HRESULT INTERNAL hresFromDiErr_NT(DWORD et);
  29. HRESULT INTERNAL hresFromDiErr_95(int et);
  30. /*****************************************************************************
  31. *
  32. * These are the functions we have to steal from SYSDM...
  33. *
  34. *****************************************************************************/
  35. LPCSTR rgpszSysdm[] = {
  36. "InstallDevice_RunDLL", /* InstallDevice_RunDLL */
  37. };
  38. typedef struct SYSDM { /* sysdm */
  39. FARPROC InstallDevice_RunDLL;
  40. } SYSDM, *PSYSDM;
  41. /*****************************************************************************
  42. *
  43. * @doc INTERNAL
  44. *
  45. * @func int | DiDestroyDeviceInfoList |
  46. *
  47. * Thunk down to SETUPX.DiCallClassInstaller.
  48. *
  49. *****************************************************************************/
  50. void INLINE
  51. InstallDevice_RunDLL(PSYSDM psysdm, HWND hwnd,
  52. HINSTANCE hinst, LPCSTR psz, UINT show)
  53. {
  54. TemplateThunk(psysdm->InstallDevice_RunDLL, "ssps",
  55. hwnd, hinst, psz, show);
  56. }
  57. /*****************************************************************************
  58. *
  59. * @doc INTERNAL
  60. *
  61. * @struct CLASSMAP |
  62. *
  63. * Structure that establishes the relationship between
  64. * <t GUIDs> for device classes and the name of the class.
  65. *
  66. * This code needs to hang around because Windows 95
  67. * doesn't have SETUPAPI.DLL, so we need to fake it.
  68. *
  69. * @parm HWND | hwndOwner |
  70. *
  71. * Window to act as owner window for UI.
  72. *
  73. * @parm REFGUID | rguidClass |
  74. *
  75. * <t GUID> which specifies the class of the hardware device.
  76. *
  77. *****************************************************************************/
  78. typedef struct CLASSMAP {
  79. REFGUID pguidClass;
  80. LPCSTR ptszClass;
  81. } CLASSMAP, *PCLASSMAP;
  82. const CLASSMAP c_rgcmap[] = {
  83. { &GUID_KeyboardClass, ("keyboard"), },
  84. { &GUID_MediaClass, ("media"), },
  85. { &GUID_MouseClass, ("mouse"), },
  86. { &GUID_HIDClass, ("HID"), },
  87. };
  88. /*****************************************************************************
  89. *
  90. * @doc INTERNAL
  91. *
  92. * @func RESULT | AddNewHardware |
  93. *
  94. * Display the "Add new hardware" dialog.
  95. *
  96. * We pull a gross hack because Device Manager is completely
  97. * unmanageable. We simply call the RunDll entry point and
  98. * let it do its thing. Note that this means we have no way
  99. * of knowing what the result was. Oh well.
  100. *
  101. * @parm HWND | hwndOwner |
  102. *
  103. * Window to act as owner window for UI.
  104. *
  105. * @parm REFGUID | rguidClass |
  106. *
  107. * <t GUID> which specifies the class of the hardware device.
  108. *
  109. *****************************************************************************/
  110. HRESULT INTERNAL
  111. AddNewHardware_95(HWND hwnd, REFGUID rguid)
  112. {
  113. SYSDM sysdm;
  114. HINSTANCE hinst;
  115. HRESULT hres;
  116. EnterProcR(AddNewHardware, (_ "xG", hwnd, rguid));
  117. if (Thunk_GetKernelProcAddresses() &&
  118. (hinst = Thunk_GetProcAddresses((PV)&sysdm, rgpszSysdm,
  119. cA(rgpszSysdm),
  120. ("SYSDM.CPL")))) {
  121. int icmap;
  122. for (icmap = 0; icmap < cA(c_rgcmap); icmap++) {
  123. if (IsEqualGUID(rguid, c_rgcmap[icmap].pguidClass)) {
  124. goto found;
  125. }
  126. }
  127. RPF("%s: Unknown device class", s_szProc);
  128. hres = DIERR_INVALIDCLASSINSTALLER;
  129. goto done;
  130. found:;
  131. InstallDevice_RunDLL(&sysdm, hwnd, hinst,
  132. c_rgcmap[icmap].ptszClass, SW_NORMAL);
  133. g_kpa.FreeLibrary16(hinst);
  134. hres = S_FALSE;
  135. } else {
  136. RPF("%s: Problems thunking to configuration manager", s_szProc);
  137. hres = E_FAIL;
  138. }
  139. done:;
  140. ExitOleProc();
  141. return hres;
  142. }
  143. /*****************************************************************************
  144. *
  145. * @doc INTERNAL
  146. *
  147. * @func RESULT | AddNewHardware |
  148. *
  149. * Display the "Add new hardware" dialog.
  150. *
  151. * @parm HWND | hwndOwner |
  152. *
  153. * Window to act as owner window for UI.
  154. *
  155. * @parm REFGUID | rguidClass |
  156. *
  157. * <t GUID> which specifies the class of the hardware device.
  158. *
  159. *****************************************************************************/
  160. HRESULT INTERNAL
  161. AddNewHardware_NT(HWND hwnd, REFGUID rguid)
  162. {
  163. HRESULT hres;
  164. HINSTANCE hInst;
  165. BOOL b;
  166. FARPROC proc;
  167. DWORD le;
  168. hres = E_NOTIMPL;
  169. /* Load AddNewHardware proc from newdev.dll part of AddNewHardware wizard.
  170. */
  171. hInst = LoadLibrary(TEXT("newdev.dll"));
  172. if (hInst) {
  173. proc = GetProcAddress(hInst, (LPCSTR)"InstallNewDevice");
  174. if (proc) {
  175. le = ERROR_SUCCESS;
  176. b = (BOOL)(*proc)(hwnd, rguid, 0); // 0 means newdev decides about reboot
  177. if (!b) {
  178. le = GetLastError();
  179. }
  180. hres = hresFromDiErr_NT(le);
  181. }
  182. FreeLibrary(hInst);
  183. }
  184. return hres;
  185. }
  186. HRESULT EXTERNAL
  187. AddNewHardware(HWND hwnd, REFGUID rguid)
  188. {
  189. return ((fWinnt)? AddNewHardware_NT(hwnd, rguid) : AddNewHardware_95(hwnd, rguid));
  190. }
  191. /*****************************************************************************
  192. *
  193. * @doc INTERNAL
  194. *
  195. * @func HRESULT | hresFromDiErr |
  196. *
  197. * Convert a device installer error code into an HRESULT.
  198. *
  199. *****************************************************************************/
  200. HRESULT INTERNAL
  201. hresFromDiErr_NT(DWORD et)
  202. {
  203. HRESULT hres;
  204. switch (et) {
  205. case ERROR_SUCCESS:
  206. hres = S_OK; break;
  207. /*
  208. * Do the default action for the requested operation.
  209. */
  210. caseNT(ERROR_DI_DO_DEFAULT);
  211. hres = S_OK; break;
  212. /*
  213. * No need to copy files (in install).
  214. */
  215. caseNT(ERROR_DI_NOFILECOPY);
  216. hres = S_OK; break;
  217. /*
  218. * Registry entry or DLL for class installer invalid.
  219. */
  220. caseNT(ERROR_INVALID_CLASS_INSTALLER);
  221. hres = DIERR_INVALIDCLASSINSTALLER; break;
  222. /*
  223. * Insufficient memory.
  224. */
  225. caseNT(ERROR_NOT_ENOUGH_MEMORY);
  226. caseNT(ERROR_OUTOFMEMORY);
  227. hres = E_OUTOFMEMORY; break;
  228. /*
  229. * The user cancelled the operation.
  230. */
  231. caseNT(ERROR_CANCELLED);
  232. caseNT(ERROR_NO_DRIVER_SELECTED);
  233. hres = DIERR_CANCELLED; break;
  234. /*
  235. * Various impossible things.
  236. */
  237. caseNT(ERROR_NO_ASSOCIATED_CLASS);
  238. caseNT(ERROR_CLASS_MISMATCH);
  239. caseNT(ERROR_DUPLICATE_FOUND);
  240. caseNT(ERROR_KEY_DOES_NOT_EXIST);
  241. caseNT(ERROR_INVALID_DEVINST_NAME);
  242. caseNT(ERROR_INVALID_CLASS);
  243. caseNT(ERROR_DEVINFO_NOT_REGISTERED);
  244. caseNT(ERROR_DEVINST_ALREADY_EXISTS);
  245. caseNT(ERROR_INVALID_REG_PROPERTY);
  246. caseNT(ERROR_NO_SUCH_DEVINST);
  247. caseNT(ERROR_CANT_LOAD_CLASS_ICON);
  248. caseNT(ERROR_INVALID_HWPROFILE);
  249. caseNT(ERROR_DEVINFO_LIST_LOCKED);
  250. caseNT(ERROR_DEVINFO_DATA_LOCKED);
  251. caseNT(ERROR_NO_CLASSINSTALL_PARAMS);
  252. caseNT(ERROR_FILEQUEUE_LOCKED);
  253. caseNT(ERROR_BAD_SERVICE_INSTALLSECT);
  254. caseNT(ERROR_NO_CLASS_DRIVER_LIST);
  255. caseNT(ERROR_NO_ASSOCIATED_SERVICE);
  256. caseNT(ERROR_NO_DEFAULT_DEVICE_INTERFACE);
  257. default:;
  258. hres = E_FAIL; break;
  259. caseNT(ERROR_DI_BAD_PATH);
  260. caseNT(ERROR_NO_INF);
  261. hres = DIERR_BADINF; break;
  262. }
  263. return hres;
  264. }
  265. #ifndef DI_ERROR
  266. #define DI_ERROR (500) // Device Installer
  267. #endif
  268. enum _ERR_DEVICE_INSTALL
  269. {
  270. ERR_DI_INVALID_DEVICE_ID = DI_ERROR, // Incorrectly formed device IDF
  271. ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST, // Invalid compatible device list
  272. ERR_DI_REG_API, // Error returned by Reg API.
  273. ERR_DI_LOW_MEM, // Insufficient memory to complete
  274. ERR_DI_BAD_DEV_INFO, // Device Info struct invalid
  275. ERR_DI_INVALID_CLASS_INSTALLER, // Registry entry / DLL invalid
  276. ERR_DI_DO_DEFAULT, // Take default action
  277. ERR_DI_USER_CANCEL, // the user cancelled the operation
  278. ERR_DI_NOFILECOPY, // No need to copy files (in install)
  279. ERR_DI_BAD_CLASS_INFO, // Class Info Struct invalid
  280. ERR_DI_BAD_INF, // Bad INF file encountered
  281. ERR_DI_BAD_MOVEDEV_PARAMS, // Bad Move Device Params struct
  282. ERR_DI_NO_INF, // No INF found on OEM disk
  283. ERR_DI_BAD_PROPCHANGE_PARAMS, // Bad property change param struct
  284. ERR_DI_BAD_SELECTDEVICE_PARAMS, // Bad Select Device Parameters
  285. ERR_DI_BAD_REMOVEDEVICE_PARAMS, // Bad Remove Device Parameters
  286. ERR_DI_BAD_ENABLECLASS_PARAMS, // Bad Enable Class Parameters
  287. ERR_DI_FAIL_QUERY, // Fail the Enable Class query
  288. ERR_DI_API_ERROR, // DI API called incorrectly
  289. ERR_DI_BAD_PATH, // An OEM path was specified incorrectly
  290. ERR_DI_BAD_UNREMOVEDEVICE_PARAMS, // Bad Unremove Device Parameters
  291. ERR_DI_NOUPDATE, // No Drivers Were updated
  292. ERR_DI_NODATE, // The driver does not have a Date stamp in the INF
  293. ERR_DI_NOVERSION, // There is not version string in the INF
  294. ERR_DI_DONT_INSTALL, // Don't upgrade the current driver
  295. ERR_DI_NO_DIGITAL_SIGNATURE_CATALOG, // Catalog is not digitally signed
  296. ERR_DI_NO_DIGITAL_SIGNATURE_INF, // Inf is not digitally signed
  297. ERR_DI_NO_DIGITAL_SIGNATURE_FILE, // A file is not digitally signed
  298. };
  299. HRESULT INTERNAL
  300. hresFromDiErr_95(int et)
  301. {
  302. HRESULT hres;
  303. switch (et) {
  304. case ERROR_SUCCESS:
  305. hres = S_OK; break;
  306. /*
  307. * Do the default action for the requested operation.
  308. */
  309. case95(ERR_DI_DO_DEFAULT);
  310. hres = S_OK; break;
  311. /*
  312. * No need to copy files (in install).
  313. */
  314. case95(ERR_DI_NOFILECOPY);
  315. hres = S_OK; break;
  316. /*
  317. * No Drivers Were updated.
  318. */
  319. // case95(ERR_DI_NOUPDATE);
  320. // hres = S_OK; break;
  321. /*
  322. * Don't upgrade the current driver.
  323. */
  324. // case95(ERR_DI_DONT_UPGRADE);
  325. // hres = S_OK; break;
  326. /*
  327. * No Drivers Were updated.
  328. */
  329. case95(ERR_DI_NOUPDATE);
  330. hres = S_OK; break;
  331. /*
  332. * Registry entry or DLL for class installer invalid.
  333. */
  334. case95(ERR_DI_INVALID_CLASS_INSTALLER);
  335. hres = DIERR_INVALIDCLASSINSTALLER; break;
  336. /*
  337. * Insufficient memory.
  338. */
  339. case95(ERR_DI_LOW_MEM);
  340. hres = E_OUTOFMEMORY; break;
  341. /*
  342. * The user cancelled the operation.
  343. */
  344. case95(ERR_DI_USER_CANCEL);
  345. hres = DIERR_CANCELLED; break;
  346. /*
  347. * Various impossible things.
  348. */
  349. case95(ERR_DI_BAD_DEV_INFO); /* Device Info struct invalid */
  350. case95(ERR_DI_BAD_CLASS_INFO); /* Class Info Struct invalid */
  351. case95(ERR_DI_API_ERROR); /* DI API called incorrectly */
  352. case95(ERR_DI_BAD_PROPCHANGE_PARAMS); /* Bad property chg param struct */
  353. case95(ERR_DI_BAD_SELECTDEVICE_PARAMS); /* Bad Select Device Parameters */
  354. case95(ERR_DI_BAD_REMOVEDEVICE_PARAMS); /* Bad Remove Device Parameters */
  355. case95(ERR_DI_BAD_ENABLECLASS_PARAMS); /* Bad Enable Class Parameters */
  356. case95(ERR_DI_BAD_MOVEDEV_PARAMS); /* Bad Move Device Params struct */
  357. case95(ERR_DI_FAIL_QUERY); /* Fail the Enable Class query */
  358. case95(ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST);
  359. /* Invalid compatible device list*/
  360. case95(ERR_DI_BAD_UNREMOVEDEVICE_PARAMS);
  361. /* Bad Unremove Device Parameters*/
  362. case95(ERR_DI_INVALID_DEVICE_ID); /* Incorrectly formed device IDF */
  363. case95(ERR_DI_REG_API); /* Error returned by Reg API. */
  364. default:;
  365. hres = E_FAIL; break;
  366. case95(ERR_DI_BAD_PATH); /* OEM path specified incorrectly*/
  367. case95(ERR_DI_BAD_INF); /* Bad INF file encountered */
  368. case95(ERR_DI_NO_INF); /* No INF found on OEM disk */
  369. case95(ERR_DI_NOVERSION); /* No version string in the INF */
  370. case95(ERR_DI_NODATE); /* No Date stamp in the INF */
  371. hres = DIERR_BADINF; break;
  372. }
  373. return hres;
  374. }
  375. #endif /* defined(IDirectInputJoyConfigVtbl) */