Leaked source code of windows server 2003
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.

491 lines
15 KiB

  1. /*++
  2. Copyright (c) 1994 - 1995 Microsoft Corporation
  3. Module Name:
  4. version.c
  5. Abstract:
  6. This module contains code that determines what the driver major
  7. version is.
  8. Author:
  9. Krishna Ganugapati (KrishnaG) 15-Mar-1994
  10. Revision History:
  11. --*/
  12. #include <precomp.h>
  13. #define X86_ENVIRONMENT L"Windows NT x86"
  14. #define IA64_ENVIRONMENT L"Windows IA64"
  15. #define MIPS_ENVIRONMENT L"Windows NT R4000"
  16. #define ALPHA_ENVIRONMENT L"Windows NT Alpha_AXP"
  17. #define PPC_ENVIRONMENT L"Windows NT PowerPC"
  18. #define WIN95_ENVIRONMENT L"Windows 4.0"
  19. #define AMD64_ENVIRONMENT L"Windows NT AMD64"
  20. BOOL
  21. GetPrintDriverVersion(
  22. IN LPCWSTR pszFileName,
  23. OUT LPDWORD pdwFileMajorVersion,
  24. OUT LPDWORD pdwFileMinorVersion
  25. )
  26. /*++
  27. Routine Name:
  28. GetPrintDriverVersion
  29. Routine Description:
  30. Gets version information about an executable file.
  31. If the file is not an executable, it will return 0
  32. for both major and minor version.
  33. Arguments:
  34. pszFileName - file name
  35. pdwFileMajorVersion - pointer to major version
  36. pdwFileMinorVersion - pointer to minor version
  37. Return Value:
  38. TRUE if success.
  39. --*/
  40. {
  41. DWORD dwSize = 0;
  42. LPVOID pFileVersion = NULL;
  43. UINT uLen = 0;
  44. LPVOID pMem = NULL;
  45. DWORD dwFileVersionLS;
  46. DWORD dwFileVersionMS;
  47. DWORD dwProductVersionMS;
  48. DWORD dwProductVersionLS;
  49. DWORD dwFileOS, dwFileType, dwFileSubType;
  50. BOOL bRetValue = FALSE;
  51. if (pdwFileMajorVersion)
  52. {
  53. *pdwFileMajorVersion = 0;
  54. }
  55. if (pdwFileMinorVersion)
  56. {
  57. *pdwFileMinorVersion = 0;
  58. }
  59. try
  60. {
  61. if (pszFileName && *pszFileName)
  62. {
  63. dwSize = GetFileVersionInfoSize((LPWSTR)pszFileName, 0);
  64. if (dwSize == 0)
  65. {
  66. //
  67. // Return version 0 for files without a version resource
  68. //
  69. bRetValue = TRUE;
  70. }
  71. else if ((pMem = AllocSplMem(dwSize)) &&
  72. GetFileVersionInfo((LPWSTR)pszFileName, 0, dwSize, pMem) &&
  73. VerQueryValue(pMem, L"\\", &pFileVersion, &uLen))
  74. {
  75. dwFileOS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileOS;
  76. dwFileType = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileType;
  77. dwFileSubType = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileSubtype;
  78. dwFileVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionMS;
  79. dwFileVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionLS;
  80. dwProductVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionMS;
  81. dwProductVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionLS;
  82. //
  83. // Return versions for drivers designed for Windows NT/Windows 2000,
  84. // marked as printer drivers.
  85. // Hold for all dlls Pre-Daytona.
  86. // After Daytona, printer driver writers must support
  87. // version control or we'll dump them as Version 0 drivers.
  88. //
  89. if (dwFileOS == VOS_NT_WINDOWS32)
  90. {
  91. if (dwFileType == VFT_DRV &&
  92. dwFileSubType == VFT2_DRV_VERSIONED_PRINTER)
  93. {
  94. if (pdwFileMinorVersion)
  95. {
  96. *pdwFileMinorVersion = dwFileVersionLS;
  97. }
  98. if (pdwFileMajorVersion)
  99. {
  100. *pdwFileMajorVersion = dwFileVersionMS;
  101. }
  102. }
  103. else
  104. {
  105. if (pdwFileMajorVersion)
  106. {
  107. if (dwProductVersionMS == dwFileVersionMS)
  108. {
  109. //
  110. // Hold for all dlls Pre-Daytona.
  111. // After Daytona, printer driver writers must support
  112. // version control or we'll dump them as Version 0
  113. // drivers.
  114. //
  115. *pdwFileMajorVersion = 0;
  116. }
  117. else
  118. {
  119. *pdwFileMajorVersion = dwFileVersionMS;
  120. }
  121. }
  122. }
  123. }
  124. bRetValue = TRUE;
  125. }
  126. }
  127. }
  128. finally
  129. {
  130. FreeSplMem(pMem);
  131. }
  132. return bRetValue;
  133. }
  134. BOOL
  135. CheckFilePlatform(
  136. IN LPWSTR pszFileName,
  137. IN LPWSTR pszEnvironment
  138. )
  139. {
  140. HANDLE hFile, hMapping;
  141. LPVOID BaseAddress = NULL;
  142. PIMAGE_NT_HEADERS pImgHdr;
  143. BOOL bRet = FALSE;
  144. try {
  145. hFile = CreateFile(pszFileName,
  146. GENERIC_READ,
  147. FILE_SHARE_READ | FILE_SHARE_WRITE,
  148. NULL,
  149. OPEN_EXISTING,
  150. FILE_ATTRIBUTE_NORMAL,
  151. NULL);
  152. if ( hFile == INVALID_HANDLE_VALUE )
  153. leave;
  154. hMapping = CreateFileMapping(hFile,
  155. NULL,
  156. PAGE_READONLY,
  157. 0,
  158. 0,
  159. NULL);
  160. if ( !hMapping )
  161. leave;
  162. BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  163. CloseHandle(hMapping);
  164. if ( !BaseAddress )
  165. leave;
  166. pImgHdr = RtlImageNtHeader(BaseAddress);
  167. if ( !pImgHdr ) {
  168. //
  169. // This happens for Win95 drivers. The second part of || is for
  170. // any environments we may add in the future
  171. //
  172. bRet = !_wcsicmp(pszEnvironment, WIN95_ENVIRONMENT) ||
  173. !( _wcsicmp(pszEnvironment, X86_ENVIRONMENT) &&
  174. _wcsicmp(pszEnvironment, IA64_ENVIRONMENT) &&
  175. _wcsicmp(pszEnvironment, ALPHA_ENVIRONMENT) &&
  176. _wcsicmp(pszEnvironment, PPC_ENVIRONMENT) &&
  177. _wcsicmp(pszEnvironment, MIPS_ENVIRONMENT) );
  178. leave;
  179. }
  180. switch (pImgHdr->FileHeader.Machine) {
  181. case IMAGE_FILE_MACHINE_I386:
  182. bRet = !_wcsicmp(pszEnvironment, X86_ENVIRONMENT);
  183. break;
  184. case IMAGE_FILE_MACHINE_ALPHA:
  185. bRet = !_wcsicmp(pszEnvironment, ALPHA_ENVIRONMENT);
  186. break;
  187. case IMAGE_FILE_MACHINE_AMD64:
  188. bRet = !_wcsicmp(pszEnvironment, AMD64_ENVIRONMENT);
  189. break;
  190. case IMAGE_FILE_MACHINE_IA64:
  191. bRet = !_wcsicmp(pszEnvironment, IA64_ENVIRONMENT);
  192. break;
  193. case IMAGE_FILE_MACHINE_POWERPC:
  194. bRet = !_wcsicmp(pszEnvironment, PPC_ENVIRONMENT);
  195. break;
  196. case IMAGE_FILE_MACHINE_R3000:
  197. case IMAGE_FILE_MACHINE_R4000:
  198. case IMAGE_FILE_MACHINE_R10000:
  199. bRet = !_wcsicmp(pszEnvironment, MIPS_ENVIRONMENT);
  200. break;
  201. default:
  202. //
  203. // For any environments we may add in the future.
  204. //
  205. bRet = !(_wcsicmp(pszEnvironment, X86_ENVIRONMENT) &&
  206. _wcsicmp(pszEnvironment, IA64_ENVIRONMENT) &&
  207. _wcsicmp(pszEnvironment, ALPHA_ENVIRONMENT) &&
  208. _wcsicmp(pszEnvironment, PPC_ENVIRONMENT) &&
  209. _wcsicmp(pszEnvironment, MIPS_ENVIRONMENT) );
  210. }
  211. } finally {
  212. if ( hFile != INVALID_HANDLE_VALUE ) {
  213. if ( BaseAddress )
  214. UnmapViewOfFile(BaseAddress);
  215. CloseHandle(hFile);
  216. }
  217. }
  218. return bRet;
  219. }
  220. /*++
  221. Routine Name:
  222. GetBinaryVersion
  223. Routine Description:
  224. Gets version information about an executable file.
  225. If the file is not an executable, it will return 0
  226. for both major and minor version. This function does
  227. not are if the file is a printer driver or anything
  228. else as long as it has a resource.
  229. Arguments:
  230. pszFileName - file name
  231. pdwFileMajorVersion - pointer to major version
  232. pdwFileMinorVersion - pointer to minor version
  233. Return Value:
  234. TRUE if success.
  235. --*/
  236. BOOL
  237. GetBinaryVersion(
  238. IN PCWSTR pszFileName,
  239. OUT PDWORD pdwFileMajorVersion,
  240. OUT PDWORD pdwFileMinorVersion
  241. )
  242. {
  243. DWORD dwSize = 0;
  244. LPVOID pFileVersion = NULL;
  245. UINT uLen = 0;
  246. LPVOID pMem = NULL;
  247. DWORD dwFileVersionLS;
  248. DWORD dwFileVersionMS;
  249. BOOL bRetValue = FALSE;
  250. if (pdwFileMajorVersion && pdwFileMinorVersion && pszFileName && *pszFileName)
  251. {
  252. *pdwFileMajorVersion = 0;
  253. *pdwFileMinorVersion = 0;
  254. try
  255. {
  256. dwSize = GetFileVersionInfoSize((LPWSTR)pszFileName, 0);
  257. if (dwSize == 0)
  258. {
  259. //
  260. // Return version 0 for files without a version resource
  261. //
  262. bRetValue = TRUE;
  263. }
  264. else if ((pMem = AllocSplMem(dwSize)) &&
  265. GetFileVersionInfo((LPWSTR)pszFileName, 0, dwSize, pMem) &&
  266. VerQueryValue(pMem, L"\\", &pFileVersion, &uLen))
  267. {
  268. dwFileVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionMS;
  269. dwFileVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionLS;
  270. *pdwFileMinorVersion = dwFileVersionLS;
  271. *pdwFileMajorVersion = dwFileVersionMS;
  272. bRetValue = TRUE;
  273. }
  274. }
  275. finally
  276. {
  277. FreeSplMem(pMem);
  278. }
  279. }
  280. else
  281. {
  282. SetLastError(ERROR_INVALID_PARAMETER);
  283. }
  284. return bRetValue;
  285. }
  286. typedef struct
  287. {
  288. PCWSTR pszPrintProcFile;
  289. DWORD PrintProcMajVer;
  290. DWORD PrintProcMinVer;
  291. } NOIMPERSONATEPRINTPROCS;
  292. NOIMPERSONATEPRINTPROCS NoImpPrintProcs[] =
  293. {
  294. {L"lxaspp.dll", 0x00010000, 0x00000001},
  295. {L"lxarpp.dll", 0x00010000, 0x00000001},
  296. {L"lxampp.dll", 0x00010000, 0x00000001},
  297. {L"lxaupp.dll", 0x00010000, 0x00000001},
  298. {L"lxatpp.dll", 0x00010000, 0x00000001},
  299. {L"lxacpp.dll", 0x00010000, 0x00000001},
  300. {L"lxaapp.dll", 0x00010000, 0x00000001},
  301. {L"lxaepp.dll", 0x00010000, 0x00000001},
  302. {L"lxadpp.dll", 0x00010000, 0x00000001},
  303. {L"lxcapp.dll", 0x00010000, 0x00000001},
  304. {L"lexepp.dll", 0x00010000, 0x00000001},
  305. {L"lexfpp.dll", 0x00010000, 0x00000001},
  306. {L"jw61pp.dll", 0x00010000, 0x00000001},
  307. {L"fxj4pp.dll", 0x00010000, 0x00000001},
  308. {L"lxalpp5c.dll", 0x00020000, 0x00020000},
  309. {L"lxalpp5c.dll", 0x00010000, 0x00060000},
  310. {L"lxalpp5c.dll", 0x00020000, 0x00010000},
  311. {L"lxalpp5c.dll", 0x00010000, 0x00050000},
  312. {L"lxakpp5c.dll", 0x00020000, 0x00010000},
  313. {L"lxakpp5c.dll", 0x00010000, 0x00050001},
  314. {L"lxazpp5c.dll", 0x00010000, 0x00040002},
  315. {L"lxazpp5c.dll", 0x00010000, 0x00050001},
  316. {L"lxaxpp5c.dll", 0x00010000, 0x00060008},
  317. {L"lxaipp5c.dll", 0x00020000, 0x00020002},
  318. {L"lxaipp5c.dll", 0x00030000, 0x00020001},
  319. {L"lxajpp5c.dll", 0x00030000, 0x00010000},
  320. {L"lxajpp5c.dll", 0x00010000, 0x00020001},
  321. {L"lxavpp5c.dll", 0x00010000, 0x000A0000},
  322. {L"lxavpp5c.dll", 0x00010000, 0x00060000},
  323. {L"lg24pp5c.dll", 0x00010000, 0x00010008},
  324. {L"lg24pp5c.dll", 0x00010000, 0x00070002},
  325. {L"lgl2pp5c.dll", 0x00010000, 0x00010006},
  326. {L"lgaxpp5c.dll", 0x00010000, 0x00020001},
  327. {L"smaxpp5c.dll", 0x00010000, 0x00030000},
  328. {L"smazpp5c.dll", 0x00010000, 0x00020000},
  329. {L"lxbhpp5c.dll", 0x00010000, 0x00050000},
  330. };
  331. PCWSTR ArraySpecialDriversInbox[] =
  332. {
  333. L"Lexmark 3200 Color Jetprinter",
  334. L"Lexmark 5700 Color Jetprinter",
  335. L"Lexmark Z11 Color Jetprinter",
  336. L"Lexmark Z12 Color Jetprinter",
  337. L"Lexmark Z22-Z32 Color Jetprinter",
  338. L"Lexmark Z31 Color Jetprinter",
  339. L"Lexmark Z42 Color Jetprinter",
  340. L"Lexmark Z51 Color Jetprinter",
  341. L"Lexmark Z52 Color Jetprinter",
  342. L"Compaq IJ300 Inkjet Printer",
  343. L"Compaq IJ600 Inkjet Printer",
  344. L"Compaq IJ700 Inkjet Printer",
  345. L"Compaq IJ750 Inkjet Printer",
  346. L"Compaq IJ900 Inkjet Printer",
  347. L"Compaq IJ1200 Inkjet Printer"
  348. };
  349. /*++
  350. Name:
  351. IsSpecialDriver
  352. Description:
  353. Checks whether a printer driver (and print processor) needs to be special
  354. cased. Some print processors want to be loaded in local system context.
  355. The are listed in the tables above. some are inbox, some are IHV.
  356. Arguments:
  357. pIniDriver - pinidriver for the current job
  358. pIniProc - piniprintproc for the current job
  359. pIniSpooler - pinispooler for current job
  360. Return Value:
  361. TRUE - this print processor needs to be loaded in local system context
  362. FALSE - load print processor in impersonation context
  363. --*/
  364. BOOL
  365. IsSpecialDriver(
  366. IN PINIDRIVER pIniDriver,
  367. IN PINIPRINTPROC pIniProc,
  368. IN PINISPOOLER pIniSpooler
  369. )
  370. {
  371. BOOL bSpecial = FALSE;
  372. DWORD i;
  373. //
  374. // Check if it is an inbox driver that needs to be special cased
  375. //
  376. for (i = 0; i < COUNTOF(ArraySpecialDriversInbox); i++)
  377. {
  378. if (!_wcsicmp(pIniDriver->pName, ArraySpecialDriversInbox[i]))
  379. {
  380. bSpecial = TRUE;
  381. break;
  382. }
  383. }
  384. //
  385. // Check if it is an IHV driver that needs to be special cased
  386. //
  387. if (!bSpecial)
  388. {
  389. for (i = 0; i < COUNTOF(NoImpPrintProcs); i++)
  390. {
  391. if (!_wcsicmp(pIniProc->pDLLName, NoImpPrintProcs[i].pszPrintProcFile) &&
  392. pIniProc->FileMajorVersion == NoImpPrintProcs[i].PrintProcMajVer &&
  393. pIniProc->FileMinorVersion == NoImpPrintProcs[i].PrintProcMinVer)
  394. {
  395. bSpecial = TRUE;
  396. break;
  397. }
  398. }
  399. }
  400. return bSpecial;
  401. }