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.

390 lines
7.4 KiB

  1. /*
  2. * Copyright (c) 1996 Microsoft Corporation
  3. *
  4. * Module Name:
  5. *
  6. * oc.cpp
  7. *
  8. * Abstract:
  9. *
  10. * This file handles all messages passed by the OC Manager
  11. *
  12. * Author:
  13. *
  14. * Kazuhiko Matsubara (kazum) June-16-1999
  15. *
  16. * Environment:
  17. *
  18. * User Mode
  19. */
  20. #define _OC_CPP_
  21. #include <stdlib.h>
  22. #include "oc.h"
  23. #include "fsconins.h"
  24. #pragma hdrstop
  25. /*
  26. * called by CRT when _DllMainCRTStartup is the DLL entry point
  27. */
  28. BOOL
  29. WINAPI
  30. DllMain(
  31. IN HINSTANCE hinstance,
  32. IN DWORD reason,
  33. IN LPVOID reserved
  34. )
  35. {
  36. UNREFERENCED_PARAMETER(reserved);
  37. if (reason == DLL_PROCESS_ATTACH) {
  38. ghinst = hinstance;
  39. }
  40. return TRUE;
  41. }
  42. DWORD_PTR
  43. FsConInstallProc(
  44. IN LPCTSTR ComponentId,
  45. IN LPCTSTR SubcomponentId,
  46. IN UINT Function,
  47. IN UINT Param1,
  48. IN OUT PVOID Param2
  49. )
  50. {
  51. DWORD_PTR rc;
  52. switch(Function)
  53. {
  54. case OC_PREINITIALIZE:
  55. rc = OCFLAG_UNICODE;
  56. break;
  57. case OC_INIT_COMPONENT:
  58. rc = OnInitComponent(ComponentId, (PSETUP_INIT_COMPONENT)Param2);
  59. break;
  60. case OC_EXTRA_ROUTINES:
  61. rc = OnExtraRoutines(ComponentId, (PEXTRA_ROUTINES)Param2);
  62. break;
  63. case OC_QUERY_CHANGE_SEL_STATE:
  64. rc = OnQuerySelStateChange(ComponentId, SubcomponentId, Param1, (UINT)((UINT_PTR)Param2));
  65. break;
  66. case OC_CALC_DISK_SPACE:
  67. rc = OnCalcDiskSpace(ComponentId, SubcomponentId, Param1, Param2);
  68. break;
  69. case OC_QUERY_STEP_COUNT:
  70. rc = 0;
  71. break;
  72. case OC_COMPLETE_INSTALLATION:
  73. rc = OnCompleteInstallation(ComponentId, SubcomponentId);
  74. break;
  75. case OC_QUERY_STATE:
  76. rc = OnQueryState(ComponentId, SubcomponentId, Param1);
  77. break;
  78. default:
  79. rc = NO_ERROR;
  80. break;
  81. }
  82. return rc;
  83. }
  84. /*-------------------------------------------------------*/
  85. /*
  86. * OC Manager message handlers
  87. *
  88. *-------------------------------------------------------*/
  89. /*
  90. * OnInitComponent()
  91. *
  92. * handler for OC_INIT_COMPONENT
  93. */
  94. DWORD
  95. OnInitComponent(
  96. LPCTSTR ComponentId,
  97. PSETUP_INIT_COMPONENT psc
  98. )
  99. {
  100. PPER_COMPONENT_DATA cd;
  101. TCHAR buf[256];
  102. HINF hinf;
  103. BOOL rc;
  104. // add component to linked list
  105. if (!(cd = AddNewComponent(ComponentId)))
  106. return ERROR_NOT_ENOUGH_MEMORY;
  107. // store component inf handle
  108. cd->hinf = (psc->ComponentInfHandle == INVALID_HANDLE_VALUE)
  109. ? NULL
  110. : psc->ComponentInfHandle;
  111. // open the inf
  112. if (cd->hinf)
  113. SetupOpenAppendInfFile(NULL, cd->hinf,NULL);
  114. // copy helper routines and flags
  115. cd->HelperRoutines = psc->HelperRoutines;
  116. cd->Flags = psc->SetupData.OperationFlags;
  117. cd->SourcePath = NULL;
  118. return NO_ERROR;
  119. }
  120. /*
  121. * OnExtraRoutines()
  122. *
  123. * handler for OC_EXTRA_ROUTINES
  124. */
  125. DWORD
  126. OnExtraRoutines(
  127. LPCTSTR ComponentId,
  128. PEXTRA_ROUTINES per
  129. )
  130. {
  131. PPER_COMPONENT_DATA cd;
  132. if (!(cd = LocateComponent(ComponentId)))
  133. return NO_ERROR;
  134. memcpy(&cd->ExtraRoutines, per, per->size);
  135. return NO_ERROR;
  136. }
  137. /*
  138. * OnQuerySelStateChange()
  139. *
  140. * don't let the user deselect the sam component
  141. */
  142. DWORD
  143. OnQuerySelStateChange(
  144. LPCTSTR ComponentId,
  145. LPCTSTR SubcomponentId,
  146. UINT state,
  147. UINT flags
  148. )
  149. {
  150. return TRUE;
  151. }
  152. /*
  153. * OnCalcDiskSpace()
  154. *
  155. * handler for OC_ON_CALC_DISK_SPACE
  156. */
  157. DWORD
  158. OnCalcDiskSpace(
  159. LPCTSTR ComponentId,
  160. LPCTSTR SubcomponentId,
  161. DWORD addComponent,
  162. HDSKSPC dspace
  163. )
  164. {
  165. DWORD rc = NO_ERROR;
  166. TCHAR section[S_SIZE];
  167. PPER_COMPONENT_DATA cd;
  168. //
  169. // Param1 = 0 if for removing component or non-0 if for adding component
  170. // Param2 = HDSKSPC to operate on
  171. //
  172. // Return value is Win32 error code indicating outcome.
  173. //
  174. // In our case the private section for this component/subcomponent pair
  175. // is a simple standard inf install section, so we can use the high-level
  176. // disk space list api to do what we want.
  177. //
  178. if (!(cd = LocateComponent(ComponentId)))
  179. return NO_ERROR;
  180. _tcscpy(section, SubcomponentId);
  181. if (addComponent)
  182. {
  183. rc = SetupAddInstallSectionToDiskSpaceList(dspace,
  184. cd->hinf,
  185. NULL,
  186. section,
  187. 0,
  188. 0);
  189. }
  190. else
  191. {
  192. rc = SetupRemoveInstallSectionFromDiskSpaceList(dspace,
  193. cd->hinf,
  194. NULL,
  195. section,
  196. 0,
  197. 0);
  198. }
  199. if (!rc)
  200. rc = GetLastError();
  201. else
  202. rc = NO_ERROR;
  203. return rc;
  204. }
  205. /*
  206. * OnCompleteInstallation
  207. *
  208. * handler for OC_COMPLETE_INSTALLATION
  209. */
  210. DWORD
  211. OnCompleteInstallation(
  212. LPCTSTR ComponentId,
  213. LPCTSTR SubcomponentId
  214. )
  215. {
  216. PPER_COMPONENT_DATA cd;
  217. BOOL rc;
  218. // Do post-installation processing in the cleanup section.
  219. // This way we know all compoents queued for installation
  220. // have beein installed before we do our stuff.
  221. if (!(cd = LocateComponent(ComponentId)))
  222. return NO_ERROR;
  223. if (!SubcomponentId || !*SubcomponentId)
  224. return NO_ERROR;
  225. rc = TRUE;
  226. FsConInstall* pFsCon = new FsConInstall(cd);
  227. if (pFsCon == NULL)
  228. return ERROR_NOT_ENOUGH_MEMORY;
  229. if (pFsCon->QueryStateInfo(SubcomponentId)) {
  230. //
  231. // installation
  232. //
  233. rc = pFsCon->GUIModeSetupInstall();
  234. }
  235. else {
  236. //
  237. // uninstallation
  238. //
  239. rc = pFsCon->GUIModeSetupUninstall();
  240. //
  241. // Remove any registry settings and files by Uninstall section on OC INF file.
  242. //
  243. if (rc) {
  244. rc = pFsCon->InfSectionRegistryAndFiles(SubcomponentId, TEXT("Uninstall"));
  245. }
  246. }
  247. delete pFsCon;
  248. if (rc) {
  249. return NO_ERROR;
  250. }
  251. else {
  252. return GetLastError();
  253. }
  254. }
  255. /*
  256. * OnQueryState()
  257. *
  258. * handler for OC_QUERY_STATE
  259. */
  260. DWORD
  261. OnQueryState(
  262. LPCTSTR ComponentId,
  263. LPCTSTR SubcomponentId,
  264. UINT state
  265. )
  266. {
  267. return SubcompUseOcManagerDefault;
  268. }
  269. /*
  270. * AddNewComponent()
  271. *
  272. * add new compononent to the top of the component list
  273. */
  274. PPER_COMPONENT_DATA
  275. AddNewComponent(
  276. LPCTSTR ComponentId
  277. )
  278. {
  279. PPER_COMPONENT_DATA data;
  280. data = (PPER_COMPONENT_DATA)LocalAlloc(LPTR,sizeof(PER_COMPONENT_DATA));
  281. if (!data)
  282. return data;
  283. data->ComponentId = (TCHAR *)LocalAlloc(LMEM_FIXED,
  284. (_tcslen(ComponentId) + 1) * sizeof(TCHAR));
  285. if(data->ComponentId)
  286. {
  287. _tcscpy((TCHAR *)data->ComponentId, ComponentId);
  288. // Stick at head of list
  289. data->Next = gcd;
  290. gcd = data;
  291. }
  292. else
  293. {
  294. LocalFree((HLOCAL)data);
  295. data = NULL;
  296. }
  297. return(data);
  298. }
  299. /*
  300. * LocateComponent()
  301. *
  302. * returns a compoent struct that matches the
  303. * passed component id.
  304. */
  305. PPER_COMPONENT_DATA
  306. LocateComponent(
  307. LPCTSTR ComponentId
  308. )
  309. {
  310. PPER_COMPONENT_DATA p;
  311. for (p = gcd; p; p=p->Next)
  312. {
  313. if (!_tcsicmp(p->ComponentId, ComponentId))
  314. return p;
  315. }
  316. return NULL;
  317. }