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.

402 lines
11 KiB

  1. /*
  2. * Copyright (c) 1996 Microsoft Corporation
  3. *
  4. * Module Name:
  5. *
  6. * fsconins.cpp
  7. *
  8. * Abstract:
  9. *
  10. * This file contain FsConInstall class
  11. *
  12. * Author:
  13. *
  14. * Kazuhiko Matsubara (kazum) June-16-1999
  15. *
  16. * Environment:
  17. *
  18. * User Mode
  19. */
  20. #define _FSCONINS_CPP_
  21. #include <stdlib.h>
  22. #include "oc.h"
  23. #include "fsconins.h"
  24. #include <initguid.h>
  25. #include <devguid.h>
  26. #include <cfgmgr32.h>
  27. #pragma hdrstop
  28. FsConInstall::FsConInstall()
  29. {
  30. m_cd = NULL;
  31. }
  32. FsConInstall::FsConInstall(
  33. IN PPER_COMPONENT_DATA cd
  34. )
  35. {
  36. m_cd = cd;
  37. }
  38. BOOL
  39. FsConInstall::GUIModeSetupInstall(
  40. IN HWND hwndParent
  41. )
  42. /*++
  43. Routine Description:
  44. This is the single entry point for Full Screen Console Driver
  45. GUI-mode setup install routine.
  46. It currently simply creates and installs a dev node for FSVGA/FSNEC to interact with
  47. PnP.
  48. Arguments:
  49. hwndParent Handle to parent window for GUI required by this function.
  50. Return Value:
  51. TRUE on success. FALSE, otherwise.
  52. --*/
  53. {
  54. HINSTANCE hndl = NULL;
  55. //
  56. // Create the deviceinfo list.
  57. //
  58. HDEVINFO devInfoSet;
  59. devInfoSet = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, hwndParent);
  60. if (devInfoSet == INVALID_HANDLE_VALUE) {
  61. return FALSE;
  62. }
  63. //
  64. // Get the "offical" display class name.
  65. //
  66. SP_DEVINFO_DATA deviceInfoData;
  67. TCHAR className[MAX_CLASS_NAME_LEN];
  68. ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA));
  69. deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  70. if (! SetupDiClassNameFromGuid(&GUID_DEVCLASS_DISPLAY,
  71. className,
  72. sizeof(className)/sizeof(TCHAR),
  73. NULL)) {
  74. return FALSE;
  75. }
  76. //
  77. // Create the dev node.
  78. //
  79. if (! SetupDiCreateDeviceInfo(devInfoSet,
  80. TEXT("Root\\DISPLAY\\0000"),
  81. &GUID_DEVCLASS_DISPLAY,
  82. NULL,
  83. hwndParent,
  84. NULL, // No flags.
  85. &deviceInfoData)) {
  86. // If it already exists, then we are done ... because this was an upgrade.
  87. if (GetLastError() == ERROR_DEVINST_ALREADY_EXISTS) {
  88. return TRUE;
  89. }
  90. else {
  91. SetupDiDestroyDeviceInfoList(devInfoSet);
  92. return FALSE;
  93. }
  94. }
  95. else if (! SetupDiSetSelectedDevice(devInfoSet,
  96. &deviceInfoData)) {
  97. goto InstallError;
  98. }
  99. //
  100. // Add the FSVGA/FSNEC PnP ID.
  101. //
  102. // Create the PnP ID string.
  103. TCHAR pnpID[256];
  104. DWORD len;
  105. len = GetPnPID(pnpID, sizeof(pnpID)/sizeof(TCHAR));
  106. if (len == 0) {
  107. goto InstallError;
  108. }
  109. // Add it to the registry entry for the dev node.
  110. if (! SetupDiSetDeviceRegistryProperty(devInfoSet,
  111. &deviceInfoData,
  112. SPDRP_HARDWAREID,
  113. (CONST BYTE*)pnpID,
  114. (len + 1) * sizeof(TCHAR))) {
  115. goto InstallError;
  116. }
  117. //
  118. // Register the, as of yet, phantom dev node with PnP to turn it into a real dev node.
  119. //
  120. if (! SetupDiRegisterDeviceInfo(devInfoSet,
  121. &deviceInfoData,
  122. 0,
  123. NULL,
  124. NULL,
  125. NULL)) {
  126. goto InstallError;
  127. }
  128. //
  129. // Get the device instance ID.
  130. //
  131. TCHAR devInstanceID[MAX_PATH];
  132. if (! SetupDiGetDeviceInstanceId(devInfoSet,
  133. &deviceInfoData,
  134. devInstanceID,
  135. sizeof(devInstanceID)/sizeof(TCHAR),
  136. NULL)) {
  137. goto InstallError;
  138. }
  139. //
  140. // Use newdev.dll to install FSVGA/FSNEC as the driver for this new dev node.
  141. //
  142. hndl = LoadLibrary(TEXT("newdev.dll"));
  143. if (hndl == NULL) {
  144. goto InstallError;
  145. }
  146. typedef BOOL (InstallDevInstFuncType)(
  147. HWND hwndParent,
  148. LPCWSTR DeviceInstanceId,
  149. BOOL UpdateDriver,
  150. PDWORD pReboot,
  151. BOOL silentInstall);
  152. InstallDevInstFuncType *pInstallDevInst;
  153. pInstallDevInst = (InstallDevInstFuncType*)GetProcAddress(hndl, "InstallDevInstEx");
  154. if (pInstallDevInst == NULL) {
  155. goto InstallError;
  156. }
  157. if ((*pInstallDevInst)(hwndParent,
  158. devInstanceID,
  159. FALSE,
  160. NULL,
  161. TRUE)) {
  162. // Clean up and return success!
  163. SetupDiDestroyDeviceInfoList(devInfoSet);
  164. FreeLibrary(hndl);
  165. return TRUE;
  166. }
  167. InstallError:
  168. SetupDiCallClassInstaller(DIF_REMOVE,
  169. devInfoSet,
  170. &deviceInfoData);
  171. SetupDiDestroyDeviceInfoList(devInfoSet);
  172. if (hndl != NULL) {
  173. FreeLibrary(hndl);
  174. }
  175. return FALSE;
  176. }
  177. BOOL
  178. FsConInstall::GUIModeSetupUninstall(
  179. IN HWND hwndParent
  180. )
  181. /*++
  182. Routine Description:
  183. This is the single entry point for Full Screen Console Driver
  184. GUI-mode setup uninstall routine.
  185. It currently simply remove the dev node created so that FSVGA/FSNEC can interact
  186. with PnP.
  187. Arguments:
  188. hwndParent Handle to parent window for GUI required by this function.
  189. Return Value:
  190. TRUE on success. FALSE, otherwise.
  191. --*/
  192. {
  193. //
  194. // Get the set of all devices with the FSVGA/FSNEC PnP ID.
  195. //
  196. HDEVINFO devInfoSet;
  197. GUID *pGuid = (GUID*)&GUID_DEVCLASS_DISPLAY;
  198. devInfoSet = SetupDiGetClassDevs(pGuid,
  199. NULL,
  200. hwndParent,
  201. DIGCF_PRESENT);
  202. if (devInfoSet == INVALID_HANDLE_VALUE) {
  203. return FALSE;
  204. }
  205. // Get FSVGA/FSNEC PnPID
  206. TCHAR FsConPnPID[256];
  207. DWORD len;
  208. len = GetPnPID(FsConPnPID, sizeof(FsConPnPID)/sizeof(TCHAR));
  209. if (len == 0) {
  210. return FALSE;
  211. }
  212. // Assume that we will be successful.
  213. BOOL result = TRUE;
  214. // Get the first device.
  215. DWORD iLoop = 0;
  216. BOOL bMoreDevices;
  217. SP_DEVINFO_DATA deviceInfoData;
  218. deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  219. //
  220. // Get the details for all matching device interfaces.
  221. //
  222. while (bMoreDevices = SetupDiEnumDeviceInfo(devInfoSet,
  223. iLoop++,
  224. &deviceInfoData)) {
  225. //
  226. // Get the PnP ID for the device.
  227. //
  228. TCHAR pnpID[256];
  229. if (SetupDiGetDeviceRegistryProperty(devInfoSet,
  230. &deviceInfoData,
  231. SPDRP_HARDWAREID,
  232. NULL,
  233. (BYTE*)pnpID,
  234. sizeof(pnpID),
  235. NULL)) {
  236. // If the current device matchs FSVGA/FSNEC, then remove it.
  237. if (! _tcscmp(pnpID, FsConPnPID)) {
  238. if (! SetupDiCallClassInstaller(DIF_REMOVE,
  239. devInfoSet,
  240. &deviceInfoData)) {
  241. // If we failed here, set the return status to indicate failure,
  242. // but don't give up on any other FSVGA/FSNEC dev nodes.
  243. result = FALSE;
  244. }
  245. }
  246. }
  247. }
  248. // Release the device info list.
  249. SetupDiDestroyDeviceInfoList(devInfoSet);
  250. return result;
  251. }
  252. DWORD
  253. FsConInstall::GetPnPID(
  254. OUT LPTSTR pszPnPID,
  255. IN DWORD dwSize
  256. )
  257. {
  258. INFCONTEXT context;
  259. if (! SetupFindFirstLine(m_cd->hinf,
  260. TEXT("Manufacturer"), // Section
  261. NULL, // Key
  262. &context)) {
  263. return 0;
  264. }
  265. TCHAR Manufacture[256];
  266. DWORD nSize;
  267. if (! SetupGetStringField(&context,
  268. 1, // Index
  269. Manufacture,
  270. sizeof(Manufacture)/sizeof(TCHAR),
  271. &nSize)) {
  272. return 0;
  273. }
  274. if (! SetupFindFirstLine(m_cd->hinf,
  275. Manufacture, // Section
  276. NULL, // Key
  277. &context)) {
  278. return 0;
  279. }
  280. if (! SetupGetStringField(&context,
  281. 2, // Index 2 is PnP-ID
  282. pszPnPID,
  283. dwSize,
  284. &nSize)) {
  285. return 0;
  286. }
  287. return _tcslen(pszPnPID);
  288. }
  289. BOOL
  290. FsConInstall::InfSectionRegistryAndFiles(
  291. IN LPCTSTR SubcomponentId,
  292. IN LPCTSTR Key
  293. )
  294. {
  295. INFCONTEXT context;
  296. TCHAR section[256];
  297. BOOL rc;
  298. rc = SetupFindFirstLine(m_cd->hinf,
  299. SubcomponentId,
  300. Key,
  301. &context);
  302. if (rc) {
  303. rc = SetupGetStringField(&context,
  304. 1,
  305. section,
  306. sizeof(section)/sizeof(TCHAR),
  307. NULL);
  308. if (rc) {
  309. rc = SetupInstallFromInfSection(NULL, // hwndOwner
  310. m_cd->hinf, // inf handle
  311. section, //
  312. SPINST_ALL & ~SPINST_FILES,
  313. // operation flags
  314. NULL, // relative key root
  315. NULL, // source root path
  316. 0, // copy flags
  317. NULL, // callback routine
  318. NULL, // callback routine context
  319. NULL, // device info set
  320. NULL); // device info struct
  321. }
  322. }
  323. return rc;
  324. }
  325. // loads current selection state info into "state" and
  326. // returns whether the selection state was changed
  327. BOOL
  328. FsConInstall::QueryStateInfo(
  329. LPCTSTR SubcomponentId
  330. )
  331. {
  332. return m_cd->HelperRoutines.QuerySelectionState(m_cd->HelperRoutines.OcManagerContext,
  333. SubcomponentId,
  334. OCSELSTATETYPE_CURRENT);
  335. }