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.

464 lines
14 KiB

  1. /*++
  2. Copyright (c) 1990 - 1995 Microsoft Corporation
  3. Module Name:
  4. upgrade.c
  5. Abstract:
  6. The routines in this file are for Upgrading from NT 3.1 to NT 4.0 for Drivers
  7. for all CPU Environment.
  8. This is achieved by copy the files to a %systemroot%\system32\spool\tmp
  9. directory then calling copying them back 1 at a time and calling
  10. InternalAddPrinterDriver, which will do version checking and copy them to the
  11. correct version.
  12. This code only has to worry about upgrading from NT 3.1, because NT 3.1 didn't have
  13. the ability to store different versions of drivers. If we are upgrading from 3.5 or
  14. 3.51 the drivers and registy will already have them installed in the correct location.
  15. Setup is responsible ( after the spooler has been loaded ) to actually bring down new
  16. versions of each printer driver. It does that by calling EnumPrinterDrivers to figure
  17. out what we have, then calling AddPrinterDriver to install a new version of each driver.
  18. ( at some point it will do that for all environments.
  19. Author:
  20. Krishna Ganugapati (KrishnaG) 21-Apr-1994
  21. Revision History:
  22. Matthew A Felton ( MattFe ) Aug 9 1995
  23. Remove the code which was married to TextMode setup to move drivers for one directory to another
  24. Now all environment upgrade from 3.1 is handled the same.
  25. --*/
  26. #include <precomp.h>
  27. #pragma hdrstop
  28. #include "clusspl.h"
  29. extern WCHAR *szSpoolDirectory;
  30. extern WCHAR *szDirectory;
  31. extern PWCHAR ipszRegistryWin32Root;
  32. extern DWORD dwUpgradeFlag;
  33. extern BUILTIN_FORM BuiltInForms[];
  34. VOID
  35. UpgradeDrivers(
  36. HKEY hEnvironmentsRootKey,
  37. LPWSTR pszEnvironmentName,
  38. PINISPOOLER pIniSpooler
  39. )
  40. {
  41. HKEY hEnvironmentKey;
  42. HKEY hDriversKey;
  43. WCHAR VersionName[MAX_PATH];
  44. DWORD cbBuffer, cchBuffer;
  45. DWORD cVersion;
  46. PINIDRIVER pIniDriver;
  47. WCHAR szEnvironmentDriverDirectory[MAX_PATH];
  48. WCHAR szEnvironmentScratchDirectory[MAX_PATH];
  49. DRIVER_INFO_2 DriverInfo;
  50. DWORD Level = 2;
  51. //
  52. // Open Environment Key e.g. W32X86
  53. //
  54. if ( RegOpenKeyEx( hEnvironmentsRootKey,
  55. pszEnvironmentName,
  56. 0,
  57. KEY_ALL_ACCESS,
  58. &hEnvironmentKey) != ERROR_SUCCESS) {
  59. DBGMSG( DBG_WARN, ("UpgradeDrivers Could not open %ws key\n", pszEnvironmentName));
  60. return;
  61. }
  62. //
  63. // Open Drivers Key
  64. //
  65. if ( RegOpenKeyEx( hEnvironmentKey,
  66. szDriversKey,
  67. 0,
  68. KEY_ALL_ACCESS,
  69. &hDriversKey) != ERROR_SUCCESS) {
  70. DBGMSG( DBG_WARN, ("UpgradeDrivers Could not open %ws key\n", szDriversKey));
  71. RegCloseKey( hEnvironmentKey );
  72. return;
  73. }
  74. cbBuffer = sizeof( szEnvironmentScratchDirectory );
  75. if ( RegQueryValueEx( hEnvironmentKey,
  76. L"Directory",
  77. NULL,
  78. NULL,
  79. (LPBYTE)szEnvironmentScratchDirectory,
  80. &cbBuffer) != ERROR_SUCCESS) {
  81. DBGMSG( DBG_TRACE, ("UpgradeDrivers RegQueryValueEx -- Error %d\n", GetLastError()));
  82. }
  83. DBGMSG(DBG_TRACE, ("UpgradeDrivers The name of the scratch directory is %ws\n", szEnvironmentScratchDirectory));
  84. if((StrNCatBuff(szEnvironmentDriverDirectory,
  85. COUNTOF(szEnvironmentDriverDirectory),
  86. pIniSpooler->pDir,
  87. L"\\drivers\\",
  88. szEnvironmentScratchDirectory,
  89. NULL)==ERROR_SUCCESS))
  90. {
  91. DBGMSG(DBG_TRACE, ("UpgradeDrivers The name of the driver directory is %ws\n", szEnvironmentDriverDirectory));
  92. cVersion = 0;
  93. memset(VersionName, 0, sizeof(VersionName));
  94. cchBuffer = COUNTOF(VersionName);
  95. //
  96. // Loop through all the NT 3.1 driver and do an AddPrinterDriver to move them
  97. // to the correct destination.
  98. //
  99. while ( RegEnumKeyEx( hDriversKey,
  100. cVersion,
  101. VersionName,
  102. &cchBuffer,
  103. NULL,
  104. NULL,
  105. NULL,
  106. NULL) == ERROR_SUCCESS) {
  107. DBGMSG( DBG_TRACE, ("UpgradeDrivers Name of the sub-key is %ws\n", VersionName));
  108. //
  109. // If Key begins "Version-" then it is not a printer driver, skip it
  110. //
  111. if ( !_wcsnicmp( VersionName, L"Version-", 8 )) {
  112. cVersion++;
  113. memset(VersionName, 0, sizeof(VersionName));
  114. cchBuffer = COUNTOF(VersionName);
  115. continue;
  116. }
  117. DBGMSG( DBG_TRACE,("UpgradeDrivers Older Driver Version Found\n", VersionName));
  118. if ( !(pIniDriver = GetDriver( hDriversKey, VersionName, pIniSpooler, NULL, NULL ))) {
  119. RegDeleteKey(hDriversKey, VersionName);
  120. cVersion = 0;
  121. memset(VersionName, 0, sizeof(VersionName));
  122. cchBuffer = COUNTOF(VersionName);
  123. continue;
  124. }
  125. memset( &DriverInfo, 0, sizeof(DRIVER_INFO_2));
  126. DriverInfo.pName = pIniDriver->pName;
  127. DriverInfo.pEnvironment = pszEnvironmentName;
  128. DriverInfo.pDriverPath = pIniDriver->pDriverFile;
  129. DriverInfo.pConfigFile = pIniDriver->pConfigFile;
  130. DriverInfo.pDataFile = pIniDriver->pDataFile;
  131. DriverInfo.cVersion = pIniDriver->cVersion;
  132. InternalAddPrinterDriverEx( NULL, Level, (LPBYTE)&DriverInfo, APD_COPY_NEW_FILES,
  133. pIniSpooler, USE_SCRATCH_DIR, DO_NOT_IMPERSONATE_USER );
  134. //
  135. // Get Rid of the NT 3.1 Driver Key, since it is now in the correct Version-0 sub key
  136. //
  137. RegDeleteKey( hDriversKey, VersionName );
  138. cVersion = 0;
  139. memset(VersionName, 0, sizeof( VersionName ));
  140. cchBuffer = COUNTOF(VersionName);
  141. FreeSplStr(pIniDriver->pName);
  142. FreeSplStr(pIniDriver->pDriverFile);
  143. FreeSplStr(pIniDriver->pConfigFile);
  144. FreeSplStr(pIniDriver->pDataFile);
  145. FreeSplMem(pIniDriver);
  146. }
  147. }
  148. RegCloseKey(hDriversKey);
  149. RegCloseKey(hEnvironmentKey);
  150. }
  151. VOID
  152. Upgrade31DriversRegistryForAllEnvironments(
  153. PINISPOOLER pIniSpooler
  154. )
  155. /*++
  156. Routine Description:
  157. This routine "Upgrades" the registry and moves printer drivers to their correct
  158. location based on the version of the printer driver.
  159. This only has to happen when upgrading from NT 3.1, because on newer builds the
  160. registry and drivers are correct.
  161. ON NT 3.1 the drivers are in %systemroot%\system32\spool\drivers\w32x86
  162. On new builds the are in %systemroot%\system32\spool\drivers\w32x86\2 ( version 2 )
  163. 3.1 registry the drivers are stored ...\Environments\Windows NT x86\Drivers
  164. on new builds they are in ...\Environments\Windows NT x86\Drivers\Version-2 ( version 2 )
  165. So all the old Version 0 drivers need to be moved to the correct location and the registy updated
  166. Arguments:
  167. pIniSpooer - pointer to spooler
  168. Return Value:
  169. None
  170. --*/
  171. {
  172. HKEY hEnvironmentsRootKey;
  173. WCHAR EnvironmentName[MAX_PATH];
  174. DWORD cEnvironment;
  175. DWORD cchBuffer;
  176. DWORD dwLastError = ERROR_SUCCESS;
  177. LeaveSplSem();
  178. SplOutSem();
  179. dwLastError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  180. pIniSpooler->pszRegistryEnvironments,
  181. 0,
  182. KEY_ALL_ACCESS,
  183. &hEnvironmentsRootKey );
  184. if ( dwLastError != ERROR_SUCCESS) {
  185. DBGMSG( DBG_WARN, ("Upgrade31DriversRegistryForAllEnvironments Could not open %ws key error %d\n", pIniSpooler->pszRegistryEnvironments, dwLastError));
  186. SetLastError( dwLastError );
  187. return;
  188. }
  189. cEnvironment = 0;
  190. cchBuffer = COUNTOF( EnvironmentName );
  191. memset(EnvironmentName, 0, sizeof( EnvironmentName ));
  192. while ( RegEnumKeyEx( hEnvironmentsRootKey,
  193. cEnvironment,
  194. EnvironmentName,
  195. &cchBuffer,
  196. NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
  197. DBGMSG( DBG_TRACE, ("Upgrade31DriversRegistryForAllEnvironments Name of the sub-key is %ws\n", EnvironmentName));
  198. UpgradeDrivers( hEnvironmentsRootKey, EnvironmentName, pIniSpooler );
  199. cEnvironment++;
  200. memset( EnvironmentName, 0, sizeof(EnvironmentName) );
  201. cchBuffer = COUNTOF( EnvironmentName );
  202. }
  203. RegCloseKey( hEnvironmentsRootKey );
  204. SplOutSem();
  205. EnterSplSem();
  206. return;
  207. }
  208. DWORD
  209. RemoveCachedInfo(
  210. )
  211. /*++
  212. Description:
  213. Removes all the cached info about the connections user had on upgrade.
  214. This is temporary solution. Later we will need to go through each
  215. connection and "upgrade" the cached info -- particularly DevMode
  216. Return Vlaue:
  217. ERROR_SUCCESS on successfully deleting. Otherwis error code
  218. --*/
  219. {
  220. DWORD dwLastError;
  221. HKEY hRootKey;
  222. dwLastError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  223. ipszRegistryWin32Root,
  224. 0,
  225. KEY_ALL_ACCESS,
  226. &hRootKey);
  227. if ( dwLastError != ERROR_SUCCESS ) {
  228. DBGMSG(DBG_WARNING,
  229. ("RemoveCachedConnectionInfo RegOepnKeyEx error %d\n",
  230. dwLastError));
  231. goto Cleanup;
  232. }
  233. dwLastError = DeleteSubkeys(hRootKey, NULL);
  234. RegCloseKey(hRootKey);
  235. if ( dwLastError != ERROR_SUCCESS ) {
  236. DBGMSG(DBG_WARNING,
  237. ("RemoveCachedConnectionInfo RegSetValue error %d\n", dwLastError));
  238. }
  239. Cleanup:
  240. return dwLastError;
  241. }
  242. VOID
  243. QueryUpgradeFlag(
  244. PINISPOOLER pIniSpooler
  245. )
  246. /*++
  247. Description: the query update flag is set up by TedM. We will read this flag
  248. if the flag has been set, we will set a boolean variable saying that we're in
  249. the upgrade mode. All upgrade activities will be carried out based on this flag.
  250. For subsequents startups of the spooler, this flag will be unvailable so we
  251. won't run the spooler in upgrade mode.
  252. This code has been moved into router spoolss\dll\init.c
  253. --*/
  254. {
  255. dwUpgradeFlag = SplIsUpgrade ();
  256. //
  257. // Not needed anymore since ntprint.dll will perform the clean up
  258. //
  259. //if ( dwUpgradeFlag )
  260. // RemoveCachedInfo();
  261. DBGMSG(DBG_TRACE, ("The Spooler Upgrade flag is %d\n", dwUpgradeFlag));
  262. return;
  263. }
  264. VOID UpgradeForms(
  265. PINISPOOLER pIniSpooler
  266. )
  267. {
  268. PBUILTIN_FORM pBuiltInForm;
  269. HKEY hFormsKey;
  270. WCHAR BuiltInFormName[MAX_PATH];
  271. WCHAR CustomFormName[FORM_NAME_LEN+1];
  272. WCHAR CustomPad[CUSTOM_NAME_LEN+1];
  273. BYTE FormData[32];
  274. DWORD cbCustomFormName;
  275. DWORD cbFormData;
  276. int cForm;
  277. if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  278. pIniSpooler->pszRegistryForms,
  279. 0,
  280. KEY_ALL_ACCESS,
  281. &hFormsKey) != ERROR_SUCCESS)
  282. {
  283. DBGMSG( DBG_WARN, ("UpgradeForms Could not open %ws key\n", ipszRegistryForms));
  284. return;
  285. }
  286. if(!LoadStringW(hInst,
  287. IDS_FORM_CUSTOMPAD,
  288. CustomPad,
  289. CUSTOM_NAME_LEN+1))
  290. {
  291. DBGMSG( DBG_WARN, ("UpgradeForms Could not find Custom string in resources"));
  292. goto CleanUp;
  293. }
  294. for(cForm=0;
  295. memset(CustomFormName, 0, sizeof(CustomFormName)),
  296. cbCustomFormName = COUNTOF(CustomFormName),
  297. RegEnumValueW(hFormsKey,
  298. cForm,
  299. CustomFormName,
  300. &cbCustomFormName,
  301. NULL,
  302. NULL,
  303. NULL,
  304. NULL) == ERROR_SUCCESS;
  305. cForm++)
  306. {
  307. for(pBuiltInForm = BuiltInForms; pBuiltInForm->NameId; pBuiltInForm++)
  308. {
  309. if(!LoadStringW(hInst,
  310. pBuiltInForm->NameId,
  311. BuiltInFormName,
  312. FORM_NAME_LEN+1))
  313. {
  314. DBGMSG( DBG_WARN, ("UpgradeForms Could not find Built in Form with Resource ID = %d in resource",pBuiltInForm->NameId));
  315. goto CleanUp;
  316. }
  317. if(!_wcsicmp(BuiltInFormName,CustomFormName))
  318. {
  319. SPLASSERT(wcslen(CustomFormName)<=FORM_NAME_LEN);
  320. cbFormData=FORM_DATA_LEN;
  321. if(RegQueryValueExW(hFormsKey, CustomFormName,
  322. NULL,NULL, (LPBYTE)FormData,
  323. &cbFormData)!=ERROR_SUCCESS)
  324. {
  325. DBGMSG( DBG_WARN, ("UpgradeForms Could not find value %ws",CustomFormName));
  326. goto CleanUp;
  327. }
  328. if(RegDeleteValueW(hFormsKey,CustomFormName)!=ERROR_SUCCESS)
  329. {
  330. DBGMSG( DBG_WARN, ("UpgradeForms Could not delete value %ws",CustomFormName));
  331. goto CleanUp;
  332. }
  333. wcsncat(CustomFormName,CustomPad,
  334. CUSTOM_NAME_LEN-wcslen(CustomFormName));
  335. if(RegSetValueExW(hFormsKey,CustomFormName, 0, REG_BINARY,
  336. (LPBYTE)FormData,
  337. cbFormData)!=ERROR_SUCCESS)
  338. {
  339. DBGMSG( DBG_WARN, ("UpgradeForms Could not set value %s",CustomFormName));
  340. goto CleanUp;
  341. }
  342. cForm = -1;
  343. break;
  344. }
  345. }
  346. }
  347. CleanUp:
  348. RegCloseKey(hFormsKey);
  349. return;
  350. }