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.

889 lines
20 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. memdbfile.c
  5. Abstract:
  6. file operations for memdb saving/loading/exporting/importing
  7. Author:
  8. Jim Schmidt (jimschm) 8-Aug-1996
  9. Revision History:
  10. mvander 13-Aug-1999 split from memdb.c
  11. --*/
  12. #include "pch.h"
  13. #include "memdbp.h"
  14. //
  15. // This is our version stamp. Change MEMDB_VERSION_STAMP only.
  16. //
  17. #define MEMDB_VERSION_STAMP L"v9 "
  18. #define VERSION_BASE_SIGNATURE L"memdb dat file "
  19. #define MEMDB_DEBUG_SIGNATURE L"debug"
  20. #define MEMDB_NODBG_SIGNATURE L"nodbg"
  21. #define VERSION_SIGNATURE VERSION_BASE_SIGNATURE MEMDB_VERSION_STAMP
  22. #define DEBUG_FILE_SIGNATURE VERSION_SIGNATURE MEMDB_DEBUG_SIGNATURE
  23. #define RETAIL_FILE_SIGNATURE VERSION_SIGNATURE MEMDB_NODBG_SIGNATURE
  24. #ifdef DEBUG
  25. #define FILE_SIGNATURE DEBUG_FILE_SIGNATURE
  26. #else
  27. #define FILE_SIGNATURE RETAIL_FILE_SIGNATURE
  28. #endif
  29. PBYTE
  30. MapFileFromHandle (
  31. HANDLE hFile,
  32. PHANDLE hMap
  33. )
  34. {
  35. MYASSERT(hMap);
  36. if (!hFile || hFile == INVALID_HANDLE_VALUE) {
  37. return NULL;
  38. }
  39. *hMap = CreateFileMappingA (
  40. hFile,
  41. NULL,
  42. PAGE_READWRITE,
  43. 0,
  44. 0,
  45. NULL
  46. );
  47. if (*hMap == NULL) {
  48. return NULL;
  49. }
  50. return MapViewOfFile (*hMap, FILE_MAP_WRITE, 0, 0, 0);
  51. }
  52. BOOL
  53. SetSizeOfFile (
  54. HANDLE hFile,
  55. LONGLONG Size
  56. )
  57. {
  58. LONG a;
  59. LONG b;
  60. PLONG sizeHi;
  61. a = (LONG) Size;
  62. b = (LONG) (SHIFTRIGHT32(Size));
  63. if (b) {
  64. sizeHi = &b;
  65. } else {
  66. sizeHi = NULL;
  67. }
  68. if (SetFilePointer (hFile, a, sizeHi, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
  69. return FALSE;
  70. }
  71. if (!SetEndOfFile (hFile)) {
  72. return FALSE;
  73. }
  74. return TRUE;
  75. }
  76. BOOL
  77. WriteBlocks (
  78. IN OUT PBYTE *Buf,
  79. IN PMEMDBHASH pHashTable,
  80. IN PGROWBUFFER pOffsetBuffer
  81. )
  82. {
  83. MYASSERT(Buf);
  84. MYASSERT(pHashTable);
  85. MYASSERT(pOffsetBuffer);
  86. if (!WriteHashBlock (pHashTable, Buf)) {
  87. return FALSE;
  88. }
  89. if (!WriteOffsetBlock (pOffsetBuffer, Buf)) {
  90. return FALSE;
  91. }
  92. return TRUE;
  93. }
  94. BOOL
  95. ReadBlocks (
  96. IN OUT PBYTE *Buf,
  97. OUT PMEMDBHASH *ppHashTable,
  98. OUT PGROWBUFFER pOffsetBuffer
  99. )
  100. {
  101. MYASSERT(Buf);
  102. MYASSERT(ppHashTable);
  103. MYASSERT(pOffsetBuffer);
  104. //
  105. // fill hash block
  106. //
  107. if (!*ppHashTable) {
  108. return FALSE;
  109. }
  110. if (!ReadHashBlock (*ppHashTable, Buf)) {
  111. return FALSE;
  112. }
  113. if (!ReadOffsetBlock (pOffsetBuffer, Buf)) {
  114. return FALSE;
  115. }
  116. return TRUE;
  117. }
  118. BOOL
  119. pPrivateMemDbSave (
  120. PCSTR FileName
  121. )
  122. {
  123. HANDLE FileHandle = NULL;
  124. HANDLE hMap = INVALID_HANDLE_VALUE;
  125. PBYTE Buf = NULL;
  126. PBYTE MapPtr = NULL;
  127. BOOL result = FALSE;
  128. EnterCriticalSection (&g_MemDbCs);
  129. __try {
  130. if (!SelectDatabase (DB_PERMANENT)) {
  131. __leave;
  132. }
  133. //
  134. // now we resize file to fit everything in it.
  135. //
  136. FileHandle = BfCreateFileA (FileName);
  137. if (!FileHandle) {
  138. __leave;
  139. }
  140. if (!SetSizeOfFile (
  141. FileHandle,
  142. (LONGLONG)(sizeof (FILE_SIGNATURE)) +
  143. g_CurrentDatabase->AllocSize +
  144. GetHashTableBlockSize (g_CurrentDatabase->HashTable) +
  145. GetOffsetBufferBlockSize (&g_CurrentDatabase->OffsetBuffer)
  146. )) {
  147. __leave;
  148. }
  149. Buf = MapFileFromHandle (FileHandle, &hMap);
  150. if (Buf == NULL) {
  151. __leave;
  152. }
  153. MapPtr = Buf;
  154. CopyMemory (Buf, FILE_SIGNATURE, sizeof (FILE_SIGNATURE));
  155. Buf += sizeof (FILE_SIGNATURE);
  156. CopyMemory (Buf, g_CurrentDatabase, g_CurrentDatabase->AllocSize);
  157. Buf += g_CurrentDatabase->AllocSize;
  158. if (!WriteBlocks (
  159. &Buf,
  160. g_CurrentDatabase->HashTable,
  161. &g_CurrentDatabase->OffsetBuffer
  162. )) {
  163. __leave;
  164. }
  165. result = TRUE;
  166. }
  167. __finally {
  168. UnmapFile (MapPtr, hMap, FileHandle);
  169. PushError();
  170. // lint is not familiar with __finally so...
  171. if (!result) { //lint !e774
  172. if (FileHandle) {
  173. CloseHandle (FileHandle);
  174. }
  175. DeleteFileA (FileName);
  176. }
  177. LeaveCriticalSection (&g_MemDbCs);
  178. PopError();
  179. }
  180. return result;
  181. }
  182. BOOL
  183. MemDbSaveA (
  184. PCSTR FileName
  185. )
  186. {
  187. return pPrivateMemDbSave (FileName); // TRUE=UNICODE
  188. }
  189. BOOL
  190. MemDbSaveW (
  191. PCWSTR FileName
  192. )
  193. {
  194. PCSTR p;
  195. BOOL b = FALSE;
  196. p = ConvertWtoA (FileName);
  197. if (p) {
  198. b = pPrivateMemDbSave (p);
  199. FreeConvertedStr (p);
  200. }
  201. return b;
  202. }
  203. BOOL
  204. pPrivateMemDbLoad (
  205. IN PCSTR AnsiFileName,
  206. IN PCWSTR UnicodeFileName,
  207. OUT PMEMDB_VERSION Version, OPTIONAL
  208. IN BOOL QueryVersionOnly
  209. )
  210. {
  211. HANDLE FileHandle = NULL;
  212. HANDLE hMap = INVALID_HANDLE_VALUE;
  213. WCHAR FileSig[sizeof(FILE_SIGNATURE)];
  214. PCWSTR VerPtr;
  215. UINT DbSize;
  216. PMEMDBHASH pHashTable;
  217. PBYTE Buf = NULL;
  218. PBYTE SavedBuf = NULL;
  219. PCSTR databaseLocation = NULL;
  220. BOOL result = FALSE;
  221. EnterCriticalSection (&g_MemDbCs);
  222. __try {
  223. __try {
  224. if (Version) {
  225. ZeroMemory (Version, sizeof (MEMDB_VERSION));
  226. }
  227. //
  228. // Blow away existing resources
  229. //
  230. if (!QueryVersionOnly) {
  231. databaseLocation = DuplicatePathStringA (DatabasesGetBasePath (), 0);
  232. DatabasesTerminate (FALSE);
  233. DatabasesInitializeA (databaseLocation);
  234. FreePathStringA (databaseLocation);
  235. if (!SelectDatabase (DB_PERMANENT)) {
  236. __leave;
  237. }
  238. }
  239. if (AnsiFileName) {
  240. Buf = MapFileIntoMemoryA (AnsiFileName, &FileHandle, &hMap);
  241. } else {
  242. Buf = MapFileIntoMemoryW (UnicodeFileName, &FileHandle, &hMap);
  243. }
  244. if (Buf == NULL) {
  245. __leave;
  246. }
  247. SavedBuf = Buf;
  248. //
  249. // Obtain the file signature
  250. //
  251. // NOTE: Entire file read is in UNICODE char set
  252. //
  253. CopyMemory (FileSig, Buf, sizeof(FILE_SIGNATURE));
  254. if (Version) {
  255. if (StringMatchByteCountW (
  256. VERSION_BASE_SIGNATURE,
  257. FileSig,
  258. sizeof (VERSION_BASE_SIGNATURE) - sizeof (WCHAR)
  259. )) {
  260. Version->Valid = TRUE;
  261. //
  262. // Identify version number
  263. //
  264. VerPtr = (PCWSTR) ((PBYTE)FileSig + sizeof (VERSION_BASE_SIGNATURE) - sizeof (WCHAR));
  265. if (StringMatchByteCountW (
  266. MEMDB_VERSION_STAMP,
  267. VerPtr,
  268. sizeof (MEMDB_VERSION_STAMP) - sizeof (WCHAR)
  269. )) {
  270. Version->CurrentVersion = TRUE;
  271. }
  272. Version->Version = (UINT) _wtoi (VerPtr + 1);
  273. //
  274. // Identify checked or free build
  275. //
  276. VerPtr += (sizeof (MEMDB_VERSION_STAMP) / sizeof (WCHAR)) - 1;
  277. if (StringMatchByteCountW (
  278. MEMDB_DEBUG_SIGNATURE,
  279. VerPtr,
  280. sizeof (MEMDB_DEBUG_SIGNATURE) - sizeof (WCHAR)
  281. )) {
  282. Version->Debug = TRUE;
  283. } else if (!StringMatchByteCountW (
  284. VerPtr,
  285. MEMDB_NODBG_SIGNATURE,
  286. sizeof (MEMDB_NODBG_SIGNATURE) - sizeof (WCHAR)
  287. )) {
  288. Version->Valid = FALSE;
  289. }
  290. }
  291. }
  292. if (!QueryVersionOnly) {
  293. if (!StringMatchW (FileSig, FILE_SIGNATURE)) {
  294. #ifdef DEBUG
  295. if (StringMatchW (FileSig, DEBUG_FILE_SIGNATURE)) {
  296. g_UseDebugStructs = TRUE;
  297. } else if (StringMatchW (FileSig, RETAIL_FILE_SIGNATURE)) {
  298. DEBUGMSG ((DBG_ERROR, "memdb dat file is from free build; checked version expected"));
  299. g_UseDebugStructs = FALSE;
  300. } else {
  301. #endif
  302. SetLastError (ERROR_BAD_FORMAT);
  303. LOG ((LOG_WARNING, "Warning: data file could be from checked build; free version expected"));
  304. __leave;
  305. #ifdef DEBUG
  306. }
  307. #endif
  308. }
  309. Buf += sizeof(FILE_SIGNATURE);
  310. DbSize = *((PUINT)Buf);
  311. //
  312. // resize the database. SizeDatabaseBuffer also fixes g_CurrentDatabase
  313. // and other global variables, so we dont have to worry.
  314. //
  315. if (!SizeDatabaseBuffer(g_CurrentDatabaseIndex, DbSize)) {
  316. __leave;
  317. }
  318. MYASSERT (g_CurrentDatabase);
  319. //
  320. // save hashtable pointer (which points to hashtable created
  321. // in InitializeDatabases (above)), then load database, then
  322. // fix hashtable pointer.
  323. //
  324. pHashTable = g_CurrentDatabase->HashTable;
  325. CopyMemory (g_CurrentDatabase, Buf, DbSize);
  326. g_CurrentDatabase->HashTable = pHashTable;
  327. Buf += DbSize;
  328. if (!ReadBlocks (
  329. &Buf,
  330. &g_CurrentDatabase->HashTable,
  331. &g_CurrentDatabase->OffsetBuffer
  332. )) {
  333. __leave;
  334. }
  335. result = TRUE;
  336. }
  337. UnmapFile (SavedBuf, hMap, FileHandle);
  338. }
  339. __except (TRUE) {
  340. result = FALSE;
  341. PushError();
  342. #ifdef DEBUG
  343. if (AnsiFileName) {
  344. LOGA ((LOG_ERROR, "MemDb dat file %s could not be loaded because of an exception", AnsiFileName));
  345. } else {
  346. LOGW ((LOG_ERROR, "MemDb dat file %s could not be loaded because of an exception", UnicodeFileName));
  347. }
  348. #endif
  349. PopError();
  350. }
  351. }
  352. __finally {
  353. PushError();
  354. if (!result && !QueryVersionOnly) {
  355. databaseLocation = DuplicatePathStringA (DatabasesGetBasePath (), 0);
  356. DatabasesTerminate (FALSE);
  357. DatabasesInitializeA (databaseLocation);
  358. FreePathStringA (databaseLocation);
  359. }
  360. LeaveCriticalSection (&g_MemDbCs);
  361. PopError();
  362. }
  363. return result;
  364. }
  365. BOOL
  366. MemDbLoadA (
  367. IN PCSTR FileName
  368. )
  369. {
  370. return pPrivateMemDbLoad (FileName, NULL, NULL, FALSE);
  371. }
  372. BOOL
  373. MemDbLoadW (
  374. IN PCWSTR FileName
  375. )
  376. {
  377. return pPrivateMemDbLoad (NULL, FileName, NULL, FALSE);
  378. }
  379. BOOL
  380. MemDbQueryVersionA (
  381. PCSTR FileName,
  382. PMEMDB_VERSION Version
  383. )
  384. {
  385. BOOL b;
  386. b = pPrivateMemDbLoad (FileName, NULL, Version, TRUE);
  387. return b ? Version->Valid : FALSE;
  388. }
  389. BOOL
  390. MemDbQueryVersionW (
  391. PCWSTR FileName,
  392. PMEMDB_VERSION Version
  393. )
  394. {
  395. pPrivateMemDbLoad (NULL, FileName, Version, TRUE);
  396. return Version->Valid;
  397. }
  398. /* format for binary file export
  399. DWORD Signature
  400. UINT Version
  401. UINT GlobalFlags// 0x00000001 mask for Ansi format
  402. // 0x00000002 mask for debug mode
  403. //
  404. // each _KEY block is followed by its children,
  405. // and each of those is followed by its children,
  406. // etc., so it is easy to recurse to gather
  407. // the whole tree.
  408. //
  409. struct _KEY {
  410. #if (GlobalFlags & MEMDB_EXPORT_FLAGS_DEBUG)
  411. WORD DebugSig // signature for each keystruct block.
  412. #endif
  413. WORD StructSize; // total number of bytes including this member
  414. WORD NameSize; // total number of bytes in Key[]
  415. WORD DataSize; // total number of bytes in Data[]
  416. WORD NumChildren // number of children, whose data structures will follow
  417. // this one (though not necessarily one after another, if
  418. // any of them have children themselves)
  419. BYTE Key[]; // Should be PCSTR or PCWSTR (not zero terminated).
  420. // the first key in the exported file will have the full
  421. // key path as its key name.
  422. BYTE Data[]; // block of data pieces, all in same format as in datablock.c
  423. }
  424. */
  425. #define MEMDB_EXPORT_SIGNATURE ('M'+('D'<<8)+('B'<<16)+('X'<<24))
  426. // NTRAID#NTBUG9-153308-2000/08/01-jimschm reenable the line below when implementing export and import functions
  427. //#define MEMDB_EXPORT_DEBUG_SIG ('K'+('Y'<<8))
  428. #define MEMDB_EXPORT_VERSION 0x00000003
  429. #define MEMDB_EXPORT_FLAGS_ANSI 0x00000001
  430. #define MEMDB_EXPORT_FLAGS_DEBUG 0x00000002
  431. // NTRAID#NTBUG9-153308-2000/08/01-jimschm Implement the function and remove lint comments
  432. //lint -save -e713 -e715
  433. BOOL
  434. pMemDbExportWorker (
  435. IN HANDLE FileHandle,
  436. IN UINT KeyIndex,
  437. IN BOOL AnsiFormat,
  438. IN PCWSTR FullKeyPath
  439. )
  440. /*++
  441. Routine Description:
  442. exports a key to a file, and then recurses through
  443. that key's children.
  444. Arguments:
  445. FileHandle - already opened handle to write to
  446. KeyIndex - index of key to write
  447. AnsiFormat - if TRUE, then FullKeyPath (above) and KeyName
  448. (below) are actually ANSI strings (not unicode).
  449. FullKeyPath - only used for first keystruct to be written
  450. to file. it specifies the full path of the root key.
  451. for all others, this argument should be NULL.
  452. Return Value:
  453. TRUE if successful, FALSE otherwise.
  454. --*/
  455. {
  456. return TRUE;
  457. }
  458. //lint -restore
  459. BOOL
  460. pMemDbExport (
  461. IN PCWSTR RootTree,
  462. IN PCSTR FileName,
  463. IN BOOL AnsiFormat
  464. )
  465. /*++
  466. Routine Description:
  467. exports a MemDb tree to a file
  468. Arguments:
  469. RootTree - full key path of the top level key to write
  470. to the file.
  471. FileName - file to write to.
  472. AnsiFormat - if TRUE, then RootTree and FileName are
  473. actually ANSI strings (not unicode).
  474. Return Value:
  475. TRUE if successful, FALSE otherwise.
  476. --*/
  477. {
  478. HANDLE FileHandle = NULL;
  479. UINT Flags;
  480. DWORD written;
  481. UINT RootIndex = INVALID_OFFSET;
  482. PCWSTR SubRootTreeW, RootTreeW;
  483. BOOL b;
  484. if (AnsiFormat) {
  485. //
  486. // if we are in ansi mode, everything is ANSI strings,
  487. // but we still need unicode string for SelectHiveW ()
  488. //
  489. RootTreeW = ConvertAtoW ((PCSTR)RootTree);
  490. if (!RootTreeW) {
  491. return FALSE;
  492. }
  493. } else {
  494. RootTreeW = RootTree;
  495. }
  496. SubRootTreeW = SelectHiveW (RootTreeW);
  497. if (SubRootTreeW) {
  498. RootIndex = FindKeyStruct (SubRootTreeW);
  499. }
  500. if (AnsiFormat) {
  501. FreeConvertedStr(RootTreeW);
  502. }
  503. if (RootIndex == INVALID_OFFSET) {
  504. return FALSE;
  505. }
  506. FileHandle = BfCreateFileA (FileName);
  507. if (!FileHandle) {
  508. return FALSE;
  509. }
  510. Flags = MEMDB_EXPORT_SIGNATURE;
  511. WriteFile (FileHandle, &Flags, sizeof (DWORD), &written, NULL);
  512. Flags = MEMDB_EXPORT_VERSION;
  513. WriteFile (FileHandle, &Flags, sizeof (UINT), &written, NULL);
  514. Flags = AnsiFormat ? MEMDB_EXPORT_FLAGS_ANSI : 0;
  515. #ifdef DEBUG
  516. Flags |= MEMDB_EXPORT_FLAGS_DEBUG;
  517. #endif
  518. WriteFile (FileHandle, &Flags, sizeof (UINT), &written, NULL);
  519. //
  520. // write root index key and all children to file.
  521. //
  522. b = pMemDbExportWorker(FileHandle, RootIndex, AnsiFormat, RootTree);
  523. //
  524. // finally write the zero terminator
  525. //
  526. Flags = 0;
  527. WriteFile (FileHandle, &Flags, sizeof (WORD), &written, NULL);
  528. CloseHandle (FileHandle);
  529. return b;
  530. }
  531. BOOL
  532. MemDbExportA (
  533. IN PCSTR RootTree,
  534. IN PCSTR FileName,
  535. IN BOOL AnsiFormat
  536. )
  537. {
  538. PCWSTR p;
  539. BOOL b;
  540. if (!AnsiFormat) {
  541. p = ConvertAtoW (RootTree);
  542. if (!p) {
  543. return FALSE;
  544. }
  545. b = pMemDbExport (p, FileName, FALSE);
  546. FreeConvertedStr (p);
  547. } else {
  548. b = pMemDbExport ((PCWSTR)RootTree, FileName, TRUE);
  549. }
  550. return b;
  551. }
  552. BOOL
  553. MemDbExportW (
  554. IN PCWSTR RootTree,
  555. IN PCWSTR FileName,
  556. IN BOOL AnsiFormat
  557. )
  558. {
  559. PCSTR p, FileNameA;
  560. BOOL b;
  561. FileNameA = ConvertWtoA (FileName);
  562. if (!FileNameA) {
  563. return FALSE;
  564. }
  565. if (AnsiFormat) {
  566. p = ConvertWtoA (RootTree);
  567. if (!p) {
  568. FreeConvertedStr (FileNameA);
  569. return FALSE;
  570. }
  571. b = pMemDbExport ((PCWSTR)p, FileNameA, TRUE);
  572. FreeConvertedStr (p);
  573. } else {
  574. b = pMemDbExport (RootTree, FileNameA, FALSE);
  575. }
  576. FreeConvertedStr (FileNameA);
  577. return b;
  578. }
  579. // NTRAID#NTBUG9-153308-2000/08/01-jimschm Implement the function and remove lint comments
  580. //lint -save -e713 -e715
  581. BOOL
  582. pMemDbImportWorker (
  583. IN PBYTE *FileBuffer,
  584. IN BOOL AnsiFormat,
  585. IN BOOL DebugMode,
  586. IN BOOL ExportRoot
  587. )
  588. /*++
  589. Routine Description:
  590. imports a key from a file, and then recurses through
  591. that key's children.
  592. Arguments:
  593. FileBuffer - pointer to a memory pointer, which should
  594. initially point to the beginning of the
  595. memory-mapped file to read. this will be updated
  596. as the function runs
  597. AnsiFormat - TRUE if the file is in ANSI mode (determined
  598. by file header)
  599. DebugMode - TRUE if the file is in debug mode (determined
  600. by file header)
  601. ExportRoot - TRUE if this is the first call to this function
  602. for a file (the name of the first keystruct in a file
  603. is the full key path for that keystruct, all other keys
  604. in the file have only the relative name).
  605. Return Value:
  606. TRUE if successful, FALSE otherwise.
  607. --*/
  608. {
  609. return TRUE;
  610. }
  611. //lint -restore
  612. BOOL
  613. MemDbImportA (
  614. IN PCSTR FileName
  615. )
  616. {
  617. PCWSTR FileNameW;
  618. BOOL b = FALSE;
  619. FileNameW = ConvertAtoW (FileName);
  620. if (FileNameW) {
  621. b = MemDbImportW (FileNameW);
  622. FreeConvertedStr (FileNameW);
  623. }
  624. return b;
  625. }
  626. BOOL
  627. MemDbImportW (
  628. IN PCWSTR FileName
  629. )
  630. /*++
  631. Routine Description:
  632. MemDbImportW imports a tree from a private binary format. The format is described above.
  633. Arguments:
  634. FileName - Name of the binary format file to import from.
  635. Return Value:
  636. TRUE is successfull, FALSE if not.
  637. --*/
  638. {
  639. PBYTE fileBuff, BufferPtr;
  640. HANDLE fileHandle;
  641. HANDLE mapHandle;
  642. BOOL b = FALSE;
  643. UINT Flags;
  644. fileBuff = MapFileIntoMemoryW (FileName, &fileHandle, &mapHandle);
  645. if (fileBuff == NULL) {
  646. DEBUGMSGW ((DBG_ERROR, "Could not execute MemDbImport for %s", FileName));
  647. return FALSE;
  648. }
  649. __try {
  650. BufferPtr = fileBuff;
  651. if (*((PDWORD) BufferPtr) != MEMDB_EXPORT_SIGNATURE) {
  652. DEBUGMSGW ((DBG_ERROR, "Unknown signature for file to import: %s", FileName));
  653. b = FALSE;
  654. } else {
  655. BufferPtr += sizeof (DWORD);
  656. if (*((PUINT) BufferPtr) != MEMDB_EXPORT_VERSION) {
  657. DEBUGMSGW ((DBG_ERROR, "Unknown or outdated version for file to import: %s", FileName));
  658. b = FALSE;
  659. } else {
  660. BufferPtr += sizeof (UINT);
  661. Flags = *((PUINT) BufferPtr);
  662. BufferPtr += sizeof (UINT);
  663. b = pMemDbImportWorker (
  664. &BufferPtr,
  665. Flags & MEMDB_EXPORT_FLAGS_ANSI,
  666. Flags & MEMDB_EXPORT_FLAGS_DEBUG,
  667. TRUE
  668. );
  669. }
  670. }
  671. }
  672. __except (1) {
  673. DEBUGMSGW ((DBG_ERROR, "Access violation while importing: %s", FileName));
  674. }
  675. UnmapFile (fileBuff, mapHandle, fileHandle);
  676. return b;
  677. }