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.

453 lines
10 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. osffread.c
  5. Abstract:
  6. Functions to assist processing of the data of NT 4.0 soft font
  7. installer file format.
  8. Environment:
  9. Windows NT Unidrv driver
  10. Revision History:
  11. 12/02/96 -ganeshp-
  12. Created
  13. --*/
  14. #include "precomp.h"
  15. #ifndef WINNT_40
  16. // NT 5.0 only
  17. //
  18. // Local function prototypes.
  19. //
  20. INT
  21. IFIOpenRead(
  22. FI_MEM *pFIMem, /* Output goes here */
  23. PWSTR pwstrName /* Name of printer data file */
  24. )
  25. /*++
  26. Routine Description:
  27. Makes the font installer file accessible & memory mapped. Called
  28. by a driver to gain access to the fonts in the font installer's
  29. output file.
  30. Arguments:
  31. FI_MEM : Font Installer Header
  32. PWSTR : Font file.
  33. Return Value:
  34. Number of records in the file; 0 for an empty/non-existant file.
  35. Note:
  36. 12-02-96: Created it -ganeshp-
  37. --*/
  38. {
  39. INT iRet;
  40. DWORD dwSize; /* Size of buffer needed for file name */
  41. PWSTR pwstrLocal;
  42. //
  43. // Initiazlie to ZERO.
  44. //
  45. iRet = 0;
  46. //
  47. // Initalize pFIMem
  48. //
  49. pFIMem->hFile = NULL; /* No data until we have it */
  50. pFIMem->pbBase = NULL;
  51. //
  52. // First map the file to memory. However,we do need firstly to
  53. // generate the file name of interest. This is based on the data
  54. // file name for this type of printer.
  55. // Allocate more storage than is indicated: we MAY want to add
  56. // a prefix to the file name rather than replace the existing one.
  57. //
  58. //
  59. // Filename + ".fi_" + NULL
  60. //
  61. dwSize = sizeof( WCHAR ) * (wcslen( pwstrName ) + 4 + 1);
  62. if( pwstrLocal = (PWSTR)MemAllocZ( dwSize ) )
  63. {
  64. /* Got the memory, so fiddle the file name to our standard */
  65. int iPtOff; /* Location of '.' */
  66. DWORD dwAttributes;
  67. StringCchCopyW(pwstrLocal, dwSize / sizeof(WCHAR), pwstrName);
  68. //
  69. // Go looking for a '.' - if not found, append to string.
  70. //
  71. iPtOff = wcslen( pwstrLocal );
  72. while( --iPtOff > 0 )
  73. {
  74. if( *(pwstrLocal + iPtOff) == (WCHAR)'.' )
  75. break;
  76. }
  77. if( iPtOff <= 0 )
  78. {
  79. iPtOff = wcslen( pwstrLocal ); /* Presume none! */
  80. *(pwstrLocal + iPtOff) = L'.';
  81. }
  82. ++iPtOff; /* Skip the period */
  83. //
  84. // Generate the name and map the file
  85. //
  86. StringCchCopyW(pwstrLocal + iPtOff,
  87. dwSize / sizeof(WCHAR) - iPtOff,
  88. FILE_FONTS);
  89. //
  90. // Check the existence of soft font file.
  91. //
  92. dwAttributes = GetFileAttributes(pwstrLocal);
  93. //
  94. // If the function succeeds, open file. Otherwise return 0.
  95. //
  96. if (dwAttributes != 0xffffffff)
  97. {
  98. pFIMem->hFile = MapFile( pwstrLocal);
  99. if (pFIMem->hFile)
  100. {
  101. pFIMem->pbBase = pFIMem->hFile;
  102. iRet = IFIRewind( pFIMem );
  103. }
  104. }
  105. MemFree( pwstrLocal ); /* No longer needed */
  106. }
  107. return iRet;
  108. }
  109. BOOL
  110. BFINextRead(
  111. FI_MEM *pFIMem
  112. )
  113. /*++
  114. Routine Description:
  115. Updates pFIMem to the next entry in the font installer file.
  116. Returns TRUE if OK, and updates the pointers in pFIMem.
  117. Arguments:
  118. FI_MEM : Font Installer Header
  119. Return Value:
  120. TRUE/FALSE. FALSE for EOF, otherwise pFIMem updated.
  121. Note:
  122. 12-02-96: Created it -ganeshp-
  123. --*/
  124. {
  125. FF_HEADER *pFFH; /* Overall file header */
  126. FF_REC_HEADER *pFFRH; /* Per record header */
  127. /*
  128. * Validate that we have valid data.
  129. */
  130. if( pFIMem == 0 || pFIMem->hFile == NULL )
  131. return FALSE; /* Empty file */
  132. pFFH = (FF_HEADER *)pFIMem->pbBase;
  133. if( pFFH->ulID != FF_ID )
  134. {
  135. ERR(( "UnidrvUI!bFINextRead: FF_HEADER has invalid ID\n" ));
  136. return FALSE;
  137. }
  138. /*
  139. * If pFIMem->pvFix == 0, we should return the data from the
  140. * first record. Otherwise, return the next record in the chain.
  141. * This is done to avoid the need to have a ReadFirst()/ReadNext()
  142. * pair of functions.
  143. */
  144. if( pFIMem->pvFix )
  145. {
  146. /*
  147. * The header is located immediately before the data we last
  148. * returned for the fixed portion of the record. SO, we back
  149. * over it to get the header which then gives us the address
  150. * of the next header.
  151. */
  152. pFFRH = (FF_REC_HEADER *)((BYTE *)pFIMem->pvFix -
  153. sizeof( FF_REC_HEADER ));
  154. if( pFFRH->ulRID != FR_ID )
  155. {
  156. ERR(( "UnidrvUI!bFINextRead: Invalid FF_REC_HEADER ID\n" ));
  157. return FALSE;
  158. }
  159. /*
  160. * We could check here for EOF on the existing structure, but this
  161. * is not required BECAUSE THE ulNextOff field will be 0, so when
  162. * it is added to our current address, we don't move. Hence, the
  163. * check for the NEW address is OK to detect EOF.
  164. */
  165. (BYTE *)pFFRH += pFFRH->ulNextOff; /* Next entry */
  166. }
  167. else
  168. {
  169. /* Point to the first record. */
  170. pFFRH = (FF_REC_HEADER *)(pFIMem->pbBase + pFFH->ulFixData);
  171. }
  172. if( pFFRH->ulNextOff == 0 )
  173. return FALSE;
  174. pFIMem->pvFix = (BYTE *)pFFRH + sizeof( FF_REC_HEADER );
  175. pFIMem->ulFixSize = pFFRH->ulSize;
  176. if( pFIMem->ulVarSize = pFFRH->ulVarSize )
  177. pFIMem->ulVarOff = pFFRH->ulVarOff + pFFH->ulVarData;
  178. else
  179. pFIMem->ulVarOff = 0; /* None here */
  180. return TRUE;
  181. }
  182. INT
  183. IFIRewind(
  184. FI_MEM *pFIMem /* File of importance */
  185. )
  186. /*++
  187. Routine Description:
  188. Reset pFIMem to the first font in the file.
  189. Arguments:
  190. FI_MEM : Font Installer Header
  191. Return Value:
  192. Number of entries in the file.
  193. Note:
  194. 12-02-96: Created it -ganeshp-
  195. --*/
  196. {
  197. /*
  198. * Not hard! The pFIMem contains the base address of the file, so we
  199. * use this to find the address of the first record, and any variable
  200. * data that corresponds with it.
  201. */
  202. FF_HEADER *pFFH;
  203. FF_REC_HEADER *pFFRH;
  204. if( pFIMem == 0 || pFIMem->hFile == NULL )
  205. return 0; /* None! */
  206. /*
  207. * The location of the first record is specified in the header.
  208. */
  209. pFFH = (FF_HEADER *)pFIMem->pbBase;
  210. if( pFFH->ulID != FF_ID )
  211. {
  212. ERR(( "UnidrvUI!iFIRewind: FF_HEADER has invalid ID\n" ));
  213. return 0;
  214. }
  215. pFFRH = (FF_REC_HEADER *)(pFIMem->pbBase + pFFH->ulFixData);
  216. if( pFFRH->ulRID != FR_ID )
  217. {
  218. ERR(( "UnidrvUI!iFIRewind: Invalid FF_REC_HEADER ID\n" ));
  219. return 0;
  220. }
  221. /*
  222. * Set the pvFix field in the header to 0. This is used in bFINextRead
  223. * to mean that the data for the first record should be supplied.
  224. */
  225. pFIMem->pvFix = 0; /* MEANS USE FIRST NEXT READ */
  226. pFIMem->ulFixSize = 0;
  227. pFIMem->ulVarOff = 0; /* None here */
  228. return pFFH->ulRecCount;
  229. }
  230. BOOL
  231. BFICloseRead(
  232. FI_MEM *pFIMem /* File/memory we are finished with */
  233. )
  234. /*++
  235. Routine Description:
  236. Called when finished with this font file.
  237. Arguments:
  238. FI_MEM : Font Installer Header
  239. PDEV: Pointer to PDEV
  240. Return Value:
  241. TRUE for success and FALSE for failure.
  242. Note:
  243. 12-02-96: Created it -ganeshp-
  244. --*/
  245. {
  246. /*
  247. * Easy! All we need do is unmap the file. We have the address too!
  248. */
  249. BOOL bRet; /* Return code */
  250. if( pFIMem == 0 || pFIMem->hFile == NULL )
  251. return TRUE; // Nothing there to Free.
  252. bRet = FREEMODULE( pFIMem->hFile);
  253. pFIMem->hFile = NULL; // Stops freeing more than once
  254. return bRet;
  255. }
  256. PVOID
  257. MapFile(
  258. PWSTR pwstr
  259. )
  260. /*++
  261. Routine Description:
  262. Returns a pointer to the mapped file defined by pwstr.
  263. Arguments:
  264. pwstr UNICODE string containing fully qualified pathname of the
  265. file to map.
  266. Return Value:
  267. Pointer to mapped memory if success, NULL if error.
  268. Note:
  269. UnmapViewOfFile will have to be called by the user at some point to free up
  270. this allocation.Macro FREEMODULE can be used for this purpose.
  271. 11/3/1997 -ganeshp-
  272. Created it.
  273. --*/
  274. {
  275. PVOID pv;
  276. HANDLE hFile, hFileMap;
  277. //
  278. // open the file we are interested in mapping.
  279. //
  280. pv = NULL;
  281. if ((hFile = CreateFileW(pwstr,
  282. GENERIC_READ,
  283. FILE_SHARE_READ,
  284. NULL,
  285. OPEN_EXISTING,
  286. FILE_ATTRIBUTE_NORMAL,
  287. NULL))
  288. != INVALID_HANDLE_VALUE)
  289. {
  290. //
  291. // create the mapping object.
  292. //
  293. if (hFileMap = CreateFileMappingW(hFile,
  294. NULL,
  295. PAGE_READONLY,
  296. 0,
  297. 0,
  298. (PWSTR)NULL))
  299. {
  300. //
  301. // get the pointer mapped to the desired file.
  302. //
  303. if (!(pv = (PVOID)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0)))
  304. {
  305. ERR(("Unidrvui!MapFile: MapViewOfFile failed.\n"));
  306. }
  307. //
  308. // now that we have our pointer, we can close the file and the
  309. // mapping object.
  310. //
  311. if (!CloseHandle(hFileMap))
  312. ERR(("Unidrvui!MapFile: CloseHandle(hFileMap) failed.\n"));
  313. }
  314. else
  315. ERR(("Unidrvui!MapFile:CreateFileMappingW failed: %s\n",pwstr));
  316. if (!CloseHandle(hFile))
  317. ERR(("Unidrvui!MapFile: CloseHandle(hFile) failed.\n"));
  318. }
  319. else
  320. ERR(("Unidrvui!Mapfile:CreateFileW failed for %s\n",pwstr));
  321. return(pv);
  322. }
  323. #endif //ifndef WINNT_40