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.

556 lines
15 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: sofile.c
  3. *
  4. * Copyright (c) 1985-96, Microsoft Corporation
  5. *
  6. * 04/09/96 GerardoB Created
  7. \***************************************************************************/
  8. #include "structo.h"
  9. /*********************************************************************
  10. * soWriteOutputFileHeader
  11. *
  12. \***************************************************************************/
  13. BOOL soWriteOutputFileHeader (PWORKINGFILES pwf)
  14. {
  15. char ** ppszHeader;
  16. /*
  17. * If building list only, done
  18. */
  19. if (pwf->dwOptions & SOWF_LISTONLY) {
  20. return TRUE;
  21. }
  22. if ( !soWriteFile(pwf->hfileOutput, "/*********************************************************************\\\r\n")
  23. || !soWriteFile(pwf->hfileOutput, "* File: %s\r\n", pwf->pszOutputFile)
  24. || !soWriteFile(pwf->hfileOutput, "* Generated by StructO on %s at %s\r\n", __DATE__, __TIME__)
  25. || !soWriteFile(pwf->hfileOutput, "\\*********************************************************************/\r\n\r\n")) {
  26. return FALSE;
  27. }
  28. if (pwf->dwOptions & SOWF_INLCLUDEPRECOMPH) {
  29. if (!soWriteFile(pwf->hfileOutput, gszPrecomph)) {
  30. return FALSE;
  31. }
  32. }
  33. /*
  34. * structure definitions for generated tables
  35. */
  36. ppszHeader = gpszHeader;
  37. while (*ppszHeader != NULL) {
  38. if (!soWriteFile(pwf->hfileOutput, *ppszHeader)
  39. || !soWriteFile(pwf->hfileOutput, "\r\n")) {
  40. return FALSE;
  41. }
  42. ppszHeader++;
  43. }
  44. return TRUE;
  45. }
  46. /*********************************************************************
  47. * soUnmapFile
  48. *
  49. \***************************************************************************/
  50. void soUnmapFile (PFILEMAP pfm)
  51. {
  52. if (pfm->pmapStart != NULL) {
  53. UnmapViewOfFile(pfm->pmap);
  54. pfm->pmapStart = NULL;
  55. pfm->pmap = NULL;
  56. pfm->pmapEnd = NULL;
  57. }
  58. if (pfm->hmap != NULL) {
  59. CloseHandle(pfm->hmap);
  60. pfm->hmap = NULL;
  61. }
  62. if (pfm->hfile != INVALID_HANDLE_VALUE) {
  63. CloseHandle(pfm->hfile);
  64. pfm->hfile = INVALID_HANDLE_VALUE;
  65. }
  66. }
  67. /*********************************************************************
  68. * soMapFile
  69. *
  70. \***************************************************************************/
  71. BOOL soMapFile (char * pszFile, PFILEMAP pfm)
  72. {
  73. DWORD dwFileSize;
  74. pfm->hfile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL,
  75. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
  76. if (pfm->hfile == INVALID_HANDLE_VALUE) {
  77. soLogMsg(SOLM_APIERROR, "CreateFile");
  78. goto CleanupAndFail;
  79. }
  80. dwFileSize = GetFileSize(pfm->hfile, NULL);
  81. if (dwFileSize == 0xFFFFFFFF) {
  82. soLogMsg(SOLM_APIERROR, "GetFileSize");
  83. goto CleanupAndFail;
  84. }
  85. pfm->hmap = CreateFileMapping(pfm->hfile, NULL, PAGE_READONLY, 0, 0, NULL);
  86. if (pfm->hmap == NULL) {
  87. soLogMsg(SOLM_APIERROR, "CreateFileMapping");
  88. goto CleanupAndFail;
  89. }
  90. pfm->pmapStart = MapViewOfFile(pfm->hmap, FILE_MAP_READ, 0, 0, 0);
  91. if (pfm->pmapStart == NULL) {
  92. soLogMsg(SOLM_APIERROR, "MapViewOfFile");
  93. goto CleanupAndFail;
  94. }
  95. pfm->pmap = pfm->pmapStart;
  96. pfm->pmapEnd = pfm->pmapStart + dwFileSize;
  97. return TRUE;
  98. CleanupAndFail:
  99. soLogMsg(SOLM_ERROR, "soMapFile failed. File: '%s'", pszFile);
  100. soUnmapFile (pfm);
  101. return FALSE;
  102. }
  103. /*********************************************************************
  104. * soBuildStructsList
  105. *
  106. \***************************************************************************/
  107. BOOL soBuildStructsList (PWORKINGFILES pwf)
  108. {
  109. static char gszEOL [] = "\r\n";
  110. char * pmap, * pStruct;
  111. FILEMAP fm;
  112. PSTRUCTLIST psl;
  113. PVOID pTemp;
  114. UINT uAlloc, uCount, uSize;
  115. soLogMsg (SOLM_NOEOL, "Building structs list from %s ...", pwf->pszStructsFile);
  116. if (!soMapFile (pwf->pszStructsFile, &fm)) {
  117. goto CleanupAndFail;
  118. }
  119. /*
  120. * Let's guess a number of structures
  121. */
  122. #define SO_LISTSIZE 20
  123. uAlloc = SO_LISTSIZE;
  124. /*
  125. * Allocate list
  126. */
  127. pwf->psl = (PSTRUCTLIST) LocalAlloc(LPTR, sizeof(STRUCTLIST) * (uAlloc + 1));
  128. if (pwf->psl == NULL) {
  129. soLogMsg(SOLM_APIERROR, "LocalAlloc");
  130. goto CleanupAndFail;
  131. }
  132. /*
  133. * Load structure names
  134. */
  135. pmap = fm.pmapStart;
  136. psl = pwf->psl;
  137. uCount = 0;
  138. while (pmap < fm.pmapEnd) {
  139. /*
  140. * Name should start at first column
  141. */
  142. if (!soIsIdentifierChar(*pmap)) {
  143. /*
  144. * Skip this line
  145. */
  146. pmap = soFindTag(pmap, fm.pmapEnd, gszEOL);
  147. if (pmap == NULL) {
  148. break;
  149. }
  150. pmap += sizeof(gszEOL) - 1;
  151. continue;
  152. }
  153. /*
  154. * Find the name
  155. */
  156. pStruct = soGetIdentifier (pmap, fm.pmapEnd, &uSize);
  157. if (pStruct == NULL) {
  158. soLogMsg(SOLM_ERROR, "soGetIdentifier failed.");
  159. goto CleanupAndFail;
  160. }
  161. /*
  162. * Grow the list if needed
  163. */
  164. if (uCount >= uAlloc) {
  165. soLogMsg (SOLM_APPEND, ".");
  166. uAlloc += SO_LISTSIZE;
  167. pTemp = LocalReAlloc(pwf->psl, sizeof(STRUCTLIST) * (uAlloc + 1), LMEM_MOVEABLE | LMEM_ZEROINIT);
  168. if (pTemp == NULL) {
  169. soLogMsg(SOLM_APIERROR, "LocalReAlloc");
  170. goto CleanupAndFail;
  171. }
  172. pwf->psl = (PSTRUCTLIST)pTemp;
  173. psl = pwf->psl + uCount;
  174. }
  175. /*
  176. * Copy it
  177. */
  178. psl->uSize = uSize;
  179. psl->pszName = soCopyTagName (pStruct, uSize);
  180. if (psl->pszName == NULL) {
  181. goto CleanupAndFail;
  182. }
  183. psl++;
  184. uCount++;
  185. pmap = pStruct + uSize;
  186. }
  187. /*
  188. * Make sure it found at least one struct
  189. */
  190. if (uCount == 0) {
  191. soLogMsg(SOLM_ERROR, "Failed to get structure name");
  192. goto CleanupAndFail;
  193. }
  194. /*
  195. * Let's save some memory
  196. */
  197. if (uCount < uAlloc) {
  198. pTemp = LocalReAlloc(pwf->psl, sizeof(STRUCTLIST) * (uCount + 1), LMEM_MOVEABLE | LMEM_ZEROINIT);
  199. if (pTemp == NULL) {
  200. soLogMsg(SOLM_APIERROR, "LocalReAlloc");
  201. goto CleanupAndFail;
  202. }
  203. pwf->psl = (PSTRUCTLIST)pTemp;
  204. }
  205. soUnmapFile (&fm);
  206. soLogMsg (SOLM_NOLABEL, ".");
  207. return TRUE;
  208. CleanupAndFail:
  209. soLogMsg(SOLM_ERROR, "soBuildStructsList failed. File: '%s'", pwf->pszStructsFile);
  210. soUnmapFile (&fm);
  211. /*
  212. * The process is going away so never mind the heap
  213. */
  214. return FALSE;
  215. }
  216. /*********************************************************************
  217. * soIncludeInputFile
  218. *
  219. * Add #include <pszInputFile Name>.<pszIncInputFileExt> to output file
  220. \***************************************************************************/
  221. BOOL soIncludeInputFile (PWORKINGFILES pwf)
  222. {
  223. BOOL fRet;
  224. char * pszIncFile, * pDot;
  225. UINT uInputFileNameSize;
  226. /*
  227. * If building list only, done
  228. */
  229. if (pwf->dwOptions & SOWF_LISTONLY) {
  230. return TRUE;
  231. }
  232. /*
  233. * Allocate a buffer to build the name
  234. */
  235. uInputFileNameSize = lstrlen(pwf->pszInputFile);
  236. pszIncFile = (char *) LocalAlloc(LPTR,
  237. uInputFileNameSize + lstrlen(pwf->pszIncInputFileExt) + 2);
  238. if (pszIncFile == NULL) {
  239. soLogMsg(SOLM_APIERROR, "LocalAlloc");
  240. return FALSE;
  241. }
  242. /*
  243. * Copy file name
  244. */
  245. pDot = soFindChar (pwf->pszInputFile, pwf->pszInputFile + uInputFileNameSize, '.');
  246. if (pDot == NULL) {
  247. strcpy(pszIncFile, pwf->pszInputFile);
  248. strcat(pszIncFile, ".");
  249. } else {
  250. strncpy(pszIncFile, pwf->pszInputFile, (UINT)(pDot - pwf->pszInputFile + 1));
  251. }
  252. /*
  253. * Copy extension and write it to output file
  254. */
  255. strcat(pszIncFile, pwf->pszIncInputFileExt);
  256. fRet = soWriteFile(pwf->hfileOutput, gszIncInput, pszIncFile);
  257. LocalFree(pszIncFile);
  258. return fRet;
  259. }
  260. /*********************************************************************
  261. * soOpenWorkingFiles
  262. *
  263. \***************************************************************************/
  264. BOOL soOpenWorkingFiles (PWORKINGFILES pwf)
  265. {
  266. char szTempPath [MAX_PATH];
  267. char szTempFile [MAX_PATH];
  268. DWORD dwFileSize;
  269. /*
  270. * Load the structures list if provided and not built already
  271. */
  272. if ((pwf->pszStructsFile != NULL) && (pwf->psl == NULL)) {
  273. if (!soBuildStructsList(pwf)) {
  274. goto CleanupAndFail;
  275. }
  276. }
  277. /*
  278. * Map input file
  279. */
  280. if (!soMapFile (pwf->pszInputFile, (PFILEMAP) &(pwf->hfileInput))) {
  281. goto CleanupAndFail;
  282. }
  283. /*
  284. * Open output file if not open already
  285. */
  286. if (pwf->hfileOutput == INVALID_HANDLE_VALUE) {
  287. pwf->hfileOutput = CreateFile(pwf->pszOutputFile, GENERIC_WRITE, 0, NULL,
  288. (pwf->dwOptions & SOWF_APPENDOUTPUT ? OPEN_EXISTING : CREATE_ALWAYS),
  289. FILE_ATTRIBUTE_NORMAL, NULL);
  290. if (pwf->hfileOutput == INVALID_HANDLE_VALUE) {
  291. soLogMsg(SOLM_APIERROR, "CreateFile");
  292. soLogMsg(SOLM_ERROR, "Failed to open output file: %s", pwf->pszOutputFile);
  293. goto CleanupAndFail;
  294. }
  295. if (pwf->dwOptions & SOWF_APPENDOUTPUT) {
  296. if (0xFFFFFFFF == SetFilePointer (pwf->hfileOutput, 0, 0, FILE_END)) {
  297. soLogMsg(SOLM_APIERROR, "SetFilePointer");
  298. goto CleanupAndFail;
  299. }
  300. } else {
  301. if (!soWriteOutputFileHeader(pwf)) {
  302. goto CleanupAndFail;
  303. }
  304. }
  305. }
  306. /*
  307. * #include input file if requested
  308. */
  309. if (pwf->dwOptions & SOWF_INCLUDEINPUTFILE) {
  310. if (!soIncludeInputFile(pwf)) {
  311. goto CleanupAndFail;
  312. }
  313. }
  314. /*
  315. * Create temp file if not created already
  316. */
  317. if (pwf->hfileTemp == INVALID_HANDLE_VALUE) {
  318. if (!GetTempPath(sizeof(szTempPath) - 1, szTempPath)) {
  319. soLogMsg(SOLM_APIERROR, "GetTempPath");
  320. goto CleanupAndFail;
  321. }
  322. if (!GetTempFileName(szTempPath, "sot", 0, szTempFile)) {
  323. soLogMsg(SOLM_APIERROR, "GetTempFileName");
  324. soLogMsg(SOLM_ERROR, "Failed to get temp file name. szTempPath: %s.", szTempPath);
  325. goto CleanupAndFail;
  326. }
  327. pwf->hfileTemp = CreateFile(szTempFile, GENERIC_WRITE | GENERIC_READ, 0, NULL,
  328. CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
  329. if (pwf->hfileTemp == INVALID_HANDLE_VALUE) {
  330. soLogMsg(SOLM_APIERROR, "CreateFile");
  331. soLogMsg(SOLM_ERROR, "Failed to create temp file: '%s'", szTempFile);
  332. goto CleanupAndFail;
  333. }
  334. if (!soWriteFile(pwf->hfileTemp, "%s", gszTableDef)) {
  335. goto CleanupAndFail;
  336. }
  337. }
  338. return TRUE;
  339. CleanupAndFail:
  340. soLogMsg(SOLM_ERROR, "soOpenWorkingFiles Failed");
  341. soCloseWorkingFiles (pwf, SOCWF_CLEANUP);
  342. return FALSE;
  343. }
  344. /*********************************************************************
  345. * soCloseWorkingFiles
  346. *
  347. \***************************************************************************/
  348. BOOL soCloseWorkingFiles (PWORKINGFILES pwf, DWORD dwFlags)
  349. {
  350. if (dwFlags & SOCWF_CLEANUP) {
  351. if (pwf->hfileTemp != INVALID_HANDLE_VALUE) {
  352. CloseHandle(pwf->hfileTemp);
  353. pwf->hfileTemp = INVALID_HANDLE_VALUE;
  354. }
  355. if (pwf->hfileOutput != INVALID_HANDLE_VALUE) {
  356. CloseHandle(pwf->hfileOutput);
  357. pwf->hfileOutput = INVALID_HANDLE_VALUE;
  358. }
  359. if (pwf->psl != NULL) {
  360. // Never mind cleanning the heap. The process is going away.
  361. }
  362. }
  363. soUnmapFile((PFILEMAP) &(pwf->hfileInput));
  364. return TRUE;
  365. }
  366. /*********************************************************************
  367. * soWriteFile
  368. *
  369. \***************************************************************************/
  370. BOOL __cdecl soWriteFile(HANDLE hfile, char *pszfmt, ...)
  371. {
  372. static char gszbuff [1024+1];
  373. BOOL fRet = TRUE;
  374. va_list va;
  375. DWORD dwWritten;
  376. va_start(va, pszfmt);
  377. vsprintf(gszbuff, pszfmt, va);
  378. if (!WriteFile(hfile, gszbuff, strlen(gszbuff), &dwWritten, NULL)) {
  379. soLogMsg(SOLM_APIERROR, "WriteFile");
  380. soLogMsg(SOLM_ERROR, "buffer not written: %s.", gszbuff);
  381. fRet = FALSE;
  382. }
  383. va_end(va);
  384. return fRet;
  385. }
  386. /*********************************************************************
  387. * soCopyStructuresTable
  388. *
  389. \***************************************************************************/
  390. BOOL soCopyStructuresTable (PWORKINGFILES pwf)
  391. {
  392. static char szTemp[1024];
  393. char ** ppszTail;
  394. DWORD dwFileSize, dwRead, dwWritten;
  395. PSTRUCTLIST psl;
  396. UINT uLoops;
  397. soLogMsg (SOLM_NOEOL, "Writting structs table ...");
  398. /*
  399. * If there are no structures, bail.
  400. * If there was a struct list, fail
  401. */
  402. if (pwf->uTablesCount == 0) {
  403. if (pwf->psl != NULL) {
  404. soLogMsg(SOLM_ERROR, "None of the structures in '%s' was found", pwf->pszStructsFile);
  405. return FALSE;
  406. } else {
  407. return TRUE;
  408. }
  409. }
  410. /*
  411. * If building list only, done
  412. */
  413. if (pwf->dwOptions & SOWF_LISTONLY) {
  414. soLogMsg (SOLM_DEFAULT, "%d Structures found.", pwf->uTablesCount);
  415. return TRUE;
  416. }
  417. /*
  418. * Let them know if we didn't find any of the structures in the list
  419. */
  420. if (pwf->psl != NULL) {
  421. psl = pwf->psl;
  422. while (psl->uSize != 0) {
  423. if (psl->uCount == 0) {
  424. soLogMsg(SOLM_WARNING, "Structure not found: %s", psl->pszName);
  425. }
  426. psl++;
  427. }
  428. }
  429. if (!soWriteFile(pwf->hfileTemp, "%s", gszTableEnd)) {
  430. goto MsgAndFail;
  431. }
  432. /*
  433. * Move to beginning of temp file
  434. */
  435. dwFileSize = GetFileSize(pwf->hfileTemp, NULL);
  436. if (dwFileSize == 0xFFFFFFFF) {
  437. soLogMsg(SOLM_APIERROR, "GetFileSize");
  438. goto MsgAndFail;
  439. }
  440. if (0xFFFFFFFF == SetFilePointer (pwf->hfileTemp, 0, 0, FILE_BEGIN)) {
  441. soLogMsg(SOLM_APIERROR, "SetFilePointer");
  442. goto MsgAndFail;
  443. }
  444. /*
  445. * Append temp file to output file
  446. */
  447. uLoops = 0;
  448. while (dwFileSize != 0) {
  449. if (!ReadFile(pwf->hfileTemp, szTemp, sizeof(szTemp), &dwRead, NULL)) {
  450. soLogMsg(SOLM_APIERROR, "ReadFile");
  451. goto MsgAndFail;
  452. }
  453. if (!WriteFile(pwf->hfileOutput, szTemp, dwRead, &dwWritten, NULL)) {
  454. soLogMsg(SOLM_APIERROR, "WriteFile");
  455. goto MsgAndFail;
  456. }
  457. dwFileSize -= dwRead;
  458. if (++uLoops == 50) {
  459. uLoops = 0;
  460. soLogMsg (SOLM_APPEND, ".");
  461. }
  462. }
  463. soLogMsg (SOLM_NOLABEL, ".");
  464. soLogMsg (SOLM_DEFAULT, "%d Tables generated.", pwf->uTablesCount);
  465. /*
  466. * Write file tail (code)
  467. */
  468. ppszTail = gpszTail;
  469. while (*ppszTail != NULL) {
  470. if (!soWriteFile(pwf->hfileOutput, *ppszTail)
  471. || !soWriteFile(pwf->hfileOutput, "\r\n")) {
  472. return FALSE;
  473. }
  474. ppszTail++;
  475. }
  476. return TRUE;
  477. MsgAndFail:
  478. soLogMsg(SOLM_ERROR, "soCopyStructuresTable failed.");
  479. return FALSE;
  480. }