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.

358 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. pfbdump.c
  5. Abstract:
  6. dump out PFB files as ASCII text
  7. Revision History:
  8. 12/30/96 -davidx-
  9. Created it.
  10. --*/
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <windows.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. char *progname;
  17. char hexdigits[] = "0123456789ABCDEF";
  18. PBYTE pOutputBuffer;
  19. #define MAX_OUTPUT_SIZE 0x400000
  20. PVOID
  21. MapFileIntoMemory(
  22. PSTR pFilename,
  23. PDWORD pFileSize
  24. )
  25. {
  26. HANDLE hFile, hFileMap;
  27. PVOID pData;
  28. // Open a handle to the specified file
  29. hFile = CreateFile(pFilename,
  30. GENERIC_READ,
  31. FILE_SHARE_READ,
  32. NULL,
  33. OPEN_EXISTING,
  34. FILE_ATTRIBUTE_NORMAL,
  35. NULL);
  36. if (hFile == INVALID_HANDLE_VALUE)
  37. return NULL;
  38. // Obtain the file size if requested
  39. if (pFileSize != NULL)
  40. {
  41. *pFileSize = GetFileSize(hFile, NULL);
  42. if (*pFileSize == 0xFFFFFFFF)
  43. {
  44. CloseHandle(hFile);
  45. return NULL;
  46. }
  47. }
  48. // Map the file into memory
  49. hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  50. if (hFileMap != NULL)
  51. {
  52. pData = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
  53. CloseHandle(hFileMap);
  54. }
  55. else
  56. pData = NULL;
  57. // We can safely close both the file mapping object and the file object itself.
  58. CloseHandle(hFile);
  59. return pData;
  60. }
  61. BOOL
  62. WriteOutputData(
  63. PSTR pFilename,
  64. PBYTE pData,
  65. DWORD size
  66. )
  67. {
  68. HANDLE hFile;
  69. // open a handle to the specified file
  70. hFile = CreateFile(pFilename,
  71. GENERIC_WRITE,
  72. 0,
  73. NULL,
  74. CREATE_ALWAYS,
  75. FILE_ATTRIBUTE_NORMAL,
  76. NULL);
  77. if (hFile == INVALID_HANDLE_VALUE)
  78. { fprintf(stderr, "last error = %d\n", GetLastError());
  79. return FALSE;
  80. }
  81. // write data to file
  82. if (WriteFile(hFile, pData, size, &size, NULL))
  83. {
  84. CloseHandle(hFile);
  85. return TRUE;
  86. }
  87. else
  88. {
  89. CloseHandle(hFile);
  90. DeleteFile(pFilename);
  91. return FALSE;
  92. }
  93. }
  94. BOOL
  95. DecodePFBData(
  96. PBYTE pInput,
  97. DWORD inputSize,
  98. PBYTE pOutput,
  99. PDWORD pOutputSize
  100. )
  101. {
  102. PBYTE pin, pend, pout;
  103. pin = pInput;
  104. pend = pInput + inputSize;
  105. pout = pOutput;
  106. while (pin < pend)
  107. {
  108. INT seglen, index;
  109. BYTE segtype;
  110. // each segment must start with 0x80
  111. if ((pend - pin) < 2 || *pin++ != 128)
  112. return FALSE;
  113. // check segment type
  114. segtype = *pin++;
  115. if (segtype == 3) // EOF segment
  116. break;
  117. if ((pend - pin) < 4)
  118. return FALSE;
  119. seglen = ((DWORD) pin[0] ) |
  120. ((DWORD) pin[1] << 8) |
  121. ((DWORD) pin[2] << 16) |
  122. ((DWORD) pin[3] << 24);
  123. pin += 4;
  124. if ((pend - pin) < seglen)
  125. return FALSE;
  126. if (segtype == 1) // ASCII segment
  127. {
  128. // copy input data to output and
  129. // convert CR to CR/LF combination
  130. while (seglen--)
  131. {
  132. if ((*pout++ = *pin++) == '\r')
  133. *pout++ = '\n';
  134. }
  135. }
  136. else if (segtype == 2) // binary segment
  137. {
  138. // copy binary data to hex
  139. for (index=1; index <= seglen; index++)
  140. {
  141. *pout++ = hexdigits[*pin >> 4];
  142. *pout++ = hexdigits[*pin & 15];
  143. pin++;
  144. if (index%32 == 0 || index == seglen)
  145. {
  146. *pout++ = '\r';
  147. *pout++ = '\n';
  148. }
  149. }
  150. }
  151. else
  152. return FALSE;
  153. }
  154. *pOutputSize = (pout - pOutput);
  155. return TRUE;
  156. }
  157. BOOL
  158. PFBDump(
  159. PSTR pFilename
  160. )
  161. {
  162. BOOL result = FALSE;
  163. PBYTE pInputData = NULL;
  164. CHAR outputFilenameBuffer[MAX_PATH];
  165. PSTR p, pEnd;
  166. DWORD inputDataSize, outputDataSize;
  167. // make sure the input filename ends with .pfb extension
  168. if ((p = strrchr(pFilename, '.')) == NULL || _stricmp(p, ".pfb") != 0)
  169. {
  170. fprintf(stderr,
  171. "%s: file '%s' ignored because it doesn't have .PFB extension\n",
  172. progname,
  173. pFilename);
  174. return FALSE;
  175. }
  176. // map the input file into memory
  177. if (! (pInputData = MapFileIntoMemory(pFilename, &inputDataSize)))
  178. {
  179. fprintf(stderr,
  180. "%s: couldn't open input file '%s'\n",
  181. progname,
  182. pFilename);
  183. return FALSE;
  184. }
  185. // decode PFB data
  186. if (! DecodePFBData(pInputData, inputDataSize, pOutputBuffer, &outputDataSize))
  187. {
  188. fprintf(stderr,
  189. "%s: file '%s' doesn't seem to contain valid PFB data\n",
  190. progname,
  191. pFilename);
  192. goto exitdump;
  193. }
  194. if (outputDataSize > MAX_OUTPUT_SIZE)
  195. {
  196. fprintf(stderr,
  197. "%s: choked on '%s' because the output file is too big\n",
  198. progname,
  199. pFilename);
  200. exit(-1);
  201. }
  202. // name the output file with /FontName information in the PFB file
  203. // is there something similar to strstr() for searching a memory block?
  204. p = pOutputBuffer;
  205. pEnd = p + outputDataSize;
  206. while (p < pEnd)
  207. {
  208. if ((*p++ == '/') &&
  209. (pEnd - p) >= 8 &&
  210. memcmp(p, "FontName", 8) == 0)
  211. {
  212. p += 8;
  213. while (p < pEnd && isspace(*p))
  214. p++;
  215. if (p < pEnd && *p++ == '/')
  216. {
  217. PSTR s;
  218. INT len;
  219. for (s=p; s < pEnd && !isspace(*s); s++)
  220. ;
  221. len = s - p;
  222. if (len > 0 && len < MAX_PATH)
  223. {
  224. CopyMemory(outputFilenameBuffer, p, len);
  225. outputFilenameBuffer[len] = '\0';
  226. break;
  227. }
  228. }
  229. p = pEnd;
  230. }
  231. }
  232. if (p == pEnd)
  233. {
  234. fprintf(stderr,
  235. "%s: couldn't find FontName in PFB file '%s'\n",
  236. progname,
  237. pFilename);
  238. goto exitdump;
  239. }
  240. // write data to output file
  241. if (! (result = WriteOutputData(outputFilenameBuffer, pOutputBuffer, outputDataSize)))
  242. {
  243. fprintf(stderr,
  244. "%s: couldn't write to output file '%s'\n",
  245. progname,
  246. outputFilenameBuffer);
  247. }
  248. exitdump:
  249. UnmapViewOfFile(pInputData);
  250. return result;
  251. }
  252. int _cdecl
  253. main(
  254. int argc,
  255. char **argv
  256. )
  257. {
  258. progname = *argv++;
  259. argc--;
  260. if (argc == 0)
  261. {
  262. fprintf(stderr, "usage: %s filename ...\n", progname);
  263. return -1;
  264. }
  265. if (! (pOutputBuffer = malloc(MAX_OUTPUT_SIZE)))
  266. {
  267. fprintf(stderr, "%s: not enough memory\n");
  268. return -1;
  269. }
  270. while (argc--)
  271. PFBDump(*argv++);
  272. free(pOutputBuffer);
  273. return 0;
  274. }