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.

426 lines
12 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. * @parm HWND | hwndOwner |
  97. *
  98. * Window to act as owner window for UI.
  99. *
  100. * @parm REFGUID | rguidClass |
  101. *
  102. * <t GUID> which specifies the class of the hardware device.
  103. *
  104. * @comm Win9x and Win2k have completely different versions of this.
  105. *
  106. *****************************************************************************/
  107. HRESULT EXTERNAL
  108. AddNewHardware(HWND hwnd, REFGUID rguid)
  109. #ifdef WINNT
  110. {
  111. HRESULT hres;
  112. HINSTANCE hInst;
  113. BOOL b;
  114. FARPROC proc;
  115. DWORD le;
  116. EnterProcR(AddNewHardware, (_ "xG", hwnd, rguid));
  117. hres = E_NOTIMPL;
  118. /* Load AddNewHardware proc from newdev.dll part of AddNewHardware wizard.
  119. */
  120. hInst = LoadLibrary(TEXT("newdev.dll"));
  121. if (hInst) {
  122. proc = GetProcAddress(hInst, (LPCSTR)"InstallNewDevice");
  123. if (proc) {
  124. le = ERROR_SUCCESS;
  125. b = (BOOL)(*proc)(hwnd, rguid, 0); // 0 means newdev decides about reboot
  126. if (!b) {
  127. le = GetLastError();
  128. }
  129. hres = hresFromDiErr_NT(le);
  130. }
  131. FreeLibrary(hInst);
  132. }
  133. ExitOleProc();
  134. return hres;
  135. }
  136. #else
  137. /*
  138. * We pull a gross hack because Device Manager is completely unmanageable.
  139. * We simply call the RunDll entry point and let it do its thing.
  140. * Note that this means we have no way of knowing what the result was.
  141. */
  142. {
  143. SYSDM sysdm;
  144. HINSTANCE hinst;
  145. HRESULT hres;
  146. EnterProcR(AddNewHardware, (_ "xG", hwnd, rguid));
  147. if (Thunk_GetKernelProcAddresses() &&
  148. (hinst = Thunk_GetProcAddresses((PV)&sysdm, rgpszSysdm,
  149. cA(rgpszSysdm),
  150. ("SYSDM.CPL")))) {
  151. int icmap;
  152. for (icmap = 0; icmap < cA(c_rgcmap); icmap++) {
  153. if (IsEqualGUID(rguid, c_rgcmap[icmap].pguidClass)) {
  154. goto found;
  155. }
  156. }
  157. RPF("%s: Unknown device class", s_szProc);
  158. hres = DIERR_INVALIDCLASSINSTALLER;
  159. goto done;
  160. found:;
  161. InstallDevice_RunDLL(&sysdm, hwnd, hinst,
  162. c_rgcmap[icmap].ptszClass, SW_NORMAL);
  163. g_kpa.FreeLibrary16(hinst);
  164. hres = S_FALSE;
  165. } else {
  166. RPF("%s: Problems thunking to configuration manager", s_szProc);
  167. hres = E_FAIL;
  168. }
  169. done:;
  170. ExitOleProc();
  171. return hres;
  172. }
  173. #endif
  174. /*****************************************************************************
  175. *
  176. * @doc INTERNAL
  177. *
  178. * @func HRESULT | hresFromDiErr |
  179. *
  180. * Convert a device installer error code into an HRESULT.
  181. *
  182. *****************************************************************************/
  183. HRESULT INTERNAL
  184. hresFromDiErr_NT(DWORD et)
  185. {
  186. HRESULT hres;
  187. switch (et) {
  188. case ERROR_SUCCESS:
  189. hres = S_OK; break;
  190. /*
  191. * Do the default action for the requested operation.
  192. */
  193. caseNT(ERROR_DI_DO_DEFAULT);
  194. hres = S_OK; break;
  195. /*
  196. * No need to copy files (in install).
  197. */
  198. caseNT(ERROR_DI_NOFILECOPY);
  199. hres = S_OK; break;
  200. /*
  201. * Registry entry or DLL for class installer invalid.
  202. */
  203. caseNT(ERROR_INVALID_CLASS_INSTALLER);
  204. hres = DIERR_INVALIDCLASSINSTALLER; break;
  205. /*
  206. * Insufficient memory.
  207. */
  208. caseNT(ERROR_NOT_ENOUGH_MEMORY);
  209. caseNT(ERROR_OUTOFMEMORY);
  210. hres = E_OUTOFMEMORY; break;
  211. /*
  212. * The user cancelled the operation.
  213. */
  214. caseNT(ERROR_CANCELLED);
  215. caseNT(ERROR_NO_DRIVER_SELECTED);
  216. hres = DIERR_CANCELLED; break;
  217. /*
  218. * Various impossible things.
  219. */
  220. caseNT(ERROR_NO_ASSOCIATED_CLASS);
  221. caseNT(ERROR_CLASS_MISMATCH);
  222. caseNT(ERROR_DUPLICATE_FOUND);
  223. caseNT(ERROR_KEY_DOES_NOT_EXIST);
  224. caseNT(ERROR_INVALID_DEVINST_NAME);
  225. caseNT(ERROR_INVALID_CLASS);
  226. caseNT(ERROR_DEVINFO_NOT_REGISTERED);
  227. caseNT(ERROR_DEVINST_ALREADY_EXISTS);
  228. caseNT(ERROR_INVALID_REG_PROPERTY);
  229. caseNT(ERROR_NO_SUCH_DEVINST);
  230. caseNT(ERROR_CANT_LOAD_CLASS_ICON);
  231. caseNT(ERROR_INVALID_HWPROFILE);
  232. caseNT(ERROR_DEVINFO_LIST_LOCKED);
  233. caseNT(ERROR_DEVINFO_DATA_LOCKED);
  234. caseNT(ERROR_NO_CLASSINSTALL_PARAMS);
  235. caseNT(ERROR_FILEQUEUE_LOCKED);
  236. caseNT(ERROR_BAD_SERVICE_INSTALLSECT);
  237. caseNT(ERROR_NO_CLASS_DRIVER_LIST);
  238. caseNT(ERROR_NO_ASSOCIATED_SERVICE);
  239. caseNT(ERROR_NO_DEFAULT_DEVICE_INTERFACE);
  240. default:;
  241. hres = E_FAIL; break;
  242. caseNT(ERROR_DI_BAD_PATH);
  243. caseNT(ERROR_NO_INF);
  244. hres = DIERR_BADINF; break;
  245. }
  246. return hres;
  247. }
  248. #ifndef DI_ERROR
  249. #define DI_ERROR (500) // Device Installer
  250. #endif
  251. enum _ERR_DEVICE_INSTALL
  252. {
  253. ERR_DI_INVALID_DEVICE_ID = DI_ERROR, // Incorrectly formed device IDF
  254. ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST, // Invalid compatible device list
  255. ERR_DI_REG_API, // Error returned by Reg API.
  256. ERR_DI_LOW_MEM, // Insufficient memory to complete
  257. ERR_DI_BAD_DEV_INFO, // Device Info struct invalid
  258. ERR_DI_INVALID_CLASS_INSTALLER, // Registry entry / DLL invalid
  259. ERR_DI_DO_DEFAULT, // Take default action
  260. ERR_DI_USER_CANCEL, // the user cancelled the operation
  261. ERR_DI_NOFILECOPY, // No need to copy files (in install)
  262. ERR_DI_BAD_CLASS_INFO, // Class Info Struct invalid
  263. ERR_DI_BAD_INF, // Bad INF file encountered
  264. ERR_DI_BAD_MOVEDEV_PARAMS, // Bad Move Device Params struct
  265. ERR_DI_NO_INF, // No INF found on OEM disk
  266. ERR_DI_BAD_PROPCHANGE_PARAMS, // Bad property change param struct
  267. ERR_DI_BAD_SELECTDEVICE_PARAMS, // Bad Select Device Parameters
  268. ERR_DI_BAD_REMOVEDEVICE_PARAMS, // Bad Remove Device Parameters
  269. ERR_DI_BAD_ENABLECLASS_PARAMS, // Bad Enable Class Parameters
  270. ERR_DI_FAIL_QUERY, // Fail the Enable Class query
  271. ERR_DI_API_ERROR, // DI API called incorrectly
  272. ERR_DI_BAD_PATH, // An OEM path was specified incorrectly
  273. ERR_DI_BAD_UNREMOVEDEVICE_PARAMS, // Bad Unremove Device Parameters
  274. ERR_DI_NOUPDATE, // No Drivers Were updated
  275. ERR_DI_NODATE, // The driver does not have a Date stamp in the INF
  276. ERR_DI_NOVERSION, // There is not version string in the INF
  277. ERR_DI_DONT_INSTALL, // Don't upgrade the current driver
  278. ERR_DI_NO_DIGITAL_SIGNATURE_CATALOG, // Catalog is not digitally signed
  279. ERR_DI_NO_DIGITAL_SIGNATURE_INF, // Inf is not digitally signed
  280. ERR_DI_NO_DIGITAL_SIGNATURE_FILE, // A file is not digitally signed
  281. };
  282. HRESULT INTERNAL
  283. hresFromDiErr_95(int et)
  284. {
  285. HRESULT hres;
  286. switch (et) {
  287. case ERROR_SUCCESS:
  288. hres = S_OK; break;
  289. /*
  290. * Do the default action for the requested operation.
  291. */
  292. case95(ERR_DI_DO_DEFAULT);
  293. hres = S_OK; break;
  294. /*
  295. * No need to copy files (in install).
  296. */
  297. case95(ERR_DI_NOFILECOPY);
  298. hres = S_OK; break;
  299. /*
  300. * No Drivers Were updated.
  301. */
  302. // case95(ERR_DI_NOUPDATE);
  303. // hres = S_OK; break;
  304. /*
  305. * Don't upgrade the current driver.
  306. */
  307. // case95(ERR_DI_DONT_UPGRADE);
  308. // hres = S_OK; break;
  309. /*
  310. * No Drivers Were updated.
  311. */
  312. case95(ERR_DI_NOUPDATE);
  313. hres = S_OK; break;
  314. /*
  315. * Registry entry or DLL for class installer invalid.
  316. */
  317. case95(ERR_DI_INVALID_CLASS_INSTALLER);
  318. hres = DIERR_INVALIDCLASSINSTALLER; break;
  319. /*
  320. * Insufficient memory.
  321. */
  322. case95(ERR_DI_LOW_MEM);
  323. hres = E_OUTOFMEMORY; break;
  324. /*
  325. * The user cancelled the operation.
  326. */
  327. case95(ERR_DI_USER_CANCEL);
  328. hres = DIERR_CANCELLED; break;
  329. /*
  330. * Various impossible things.
  331. */
  332. case95(ERR_DI_BAD_DEV_INFO); /* Device Info struct invalid */
  333. case95(ERR_DI_BAD_CLASS_INFO); /* Class Info Struct invalid */
  334. case95(ERR_DI_API_ERROR); /* DI API called incorrectly */
  335. case95(ERR_DI_BAD_PROPCHANGE_PARAMS); /* Bad property chg param struct */
  336. case95(ERR_DI_BAD_SELECTDEVICE_PARAMS); /* Bad Select Device Parameters */
  337. case95(ERR_DI_BAD_REMOVEDEVICE_PARAMS); /* Bad Remove Device Parameters */
  338. case95(ERR_DI_BAD_ENABLECLASS_PARAMS); /* Bad Enable Class Parameters */
  339. case95(ERR_DI_BAD_MOVEDEV_PARAMS); /* Bad Move Device Params struct */
  340. case95(ERR_DI_FAIL_QUERY); /* Fail the Enable Class query */
  341. case95(ERR_DI_INVALID_COMPATIBLE_DEVICE_LIST);
  342. /* Invalid compatible device list*/
  343. case95(ERR_DI_BAD_UNREMOVEDEVICE_PARAMS);
  344. /* Bad Unremove Device Parameters*/
  345. case95(ERR_DI_INVALID_DEVICE_ID); /* Incorrectly formed device IDF */
  346. case95(ERR_DI_REG_API); /* Error returned by Reg API. */
  347. default:;
  348. hres = E_FAIL; break;
  349. case95(ERR_DI_BAD_PATH); /* OEM path specified incorrectly*/
  350. case95(ERR_DI_BAD_INF); /* Bad INF file encountered */
  351. case95(ERR_DI_NO_INF); /* No INF found on OEM disk */
  352. case95(ERR_DI_NOVERSION); /* No version string in the INF */
  353. case95(ERR_DI_NODATE); /* No Date stamp in the INF */
  354. hres = DIERR_BADINF; break;
  355. }
  356. return hres;
  357. }
  358. #endif /* defined(IDirectInputJoyConfigVtbl) */