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.

2062 lines
64 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. removemed.c
  5. Abstract:
  6. Implements a transport module that works with removable media
  7. Author:
  8. Calin Negreanu (calinn) 24-Apr-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "logmsg.h"
  17. #include <compress.h>
  18. #define DBG_RMVMED "RmvMed"
  19. //
  20. // Strings
  21. //
  22. #define S_TRANSPORT_DAT_FILE TEXT("TRANSDB.DAT")
  23. #define S_TRANSPORT_DEST_FILE TEXT("USMT2IMG.DAT")
  24. #define S_TRANSPORT_IMG_FILE TEXT("IMG%05X.DAT")
  25. #define S_UNCOMPRESSED_FILE TEXT("TEMPFILE.DAT")
  26. #define S_DETAILS_PREFIX TEXT("details-")
  27. //
  28. // Constants
  29. //
  30. #define TRFLAG_FILE 0x01
  31. #define TRFLAG_MEMORY 0x02
  32. #define COPY_BUFFER_SIZE 32768
  33. #define RMVMEDTR_OLDSIG1 0x55534D31 //USM1
  34. #define RMVMEDTR_OLDSIG2 0x55534D32 //USM1
  35. #define RMVMEDTR_SIG 0x55534D33 //USM2
  36. //
  37. // Macros
  38. //
  39. // None
  40. //
  41. // Types
  42. //
  43. typedef struct {
  44. TCHAR TempFile [MAX_PATH];
  45. PCVOID AllocPtr;
  46. PCVOID DetailsPtr;
  47. HANDLE FileHandle;
  48. HANDLE MapHandle;
  49. } ALLOCSTATE, *PALLOCSTATE;
  50. typedef struct {
  51. DWORD Signature;
  52. DWORD LastImage;
  53. DWORD ImageNr;
  54. DWORD CheckSum;
  55. LONGLONG TotalImageSize;
  56. } IMAGE_HEADER, *PIMAGE_HEADER;
  57. //
  58. // Globals
  59. //
  60. MIG_TRANSPORTSTORAGEID g_RemovableMediaId;
  61. UINT g_RmvMedPlatform;
  62. PCTSTR g_RemovableMediaPath = NULL;
  63. PCTSTR g_RmvMedTempPath = NULL;
  64. MIG_PROGRESSSLICEID g_PersistentSlice;
  65. MIG_PROGRESSSLICEID g_DatabaseSlice;
  66. UINT g_CompressedTicks;
  67. UINT g_CompressedTicked;
  68. MIG_PROGRESSSLICEID g_CompressedSlice;
  69. UINT g_DownloadTicks;
  70. UINT g_DownloadTicked;
  71. MIG_PROGRESSSLICEID g_DownloadSlice;
  72. UINT g_UncompressTicks;
  73. UINT g_UncompressTicked;
  74. MIG_PROGRESSSLICEID g_UncompressSlice;
  75. LONGLONG g_TotalFiles;
  76. LONGLONG g_FilesRead;
  77. //
  78. // Macro expansion list
  79. //
  80. // None
  81. //
  82. // Private function prototypes
  83. //
  84. VOID
  85. pCleanupTempDir (
  86. VOID
  87. );
  88. //
  89. // Macro expansion definition
  90. //
  91. // None
  92. //
  93. // Code
  94. //
  95. BOOL
  96. WINAPI
  97. RmvMedTransportInitialize (
  98. PMIG_LOGCALLBACK LogCallback
  99. )
  100. {
  101. //
  102. // Initialize globals
  103. //
  104. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  105. g_RemovableMediaId = IsmRegisterTransport (S_REMOVABLE_MEDIA_TRANSPORT);
  106. return TRUE;
  107. }
  108. VOID
  109. WINAPI
  110. RmvMedTransportTerminate (
  111. VOID
  112. )
  113. {
  114. pCleanupTempDir ();
  115. if (g_RmvMedTempPath) {
  116. FreePathString (g_RmvMedTempPath);
  117. g_RmvMedTempPath = NULL;
  118. }
  119. if (g_RemovableMediaPath) {
  120. FreePathString (g_RemovableMediaPath);
  121. g_RemovableMediaPath = NULL;
  122. }
  123. }
  124. VOID
  125. WINAPI
  126. RmvMedTransportEstimateProgressBar (
  127. MIG_PLATFORMTYPEID PlatformTypeId
  128. )
  129. {
  130. UINT ticks;
  131. PMIG_OBJECTCOUNT objectCount;
  132. if (PlatformTypeId == PLATFORM_SOURCE) {
  133. //
  134. // If saving, we know the number of ticks based on the count of the
  135. // persistent attribute.
  136. //
  137. objectCount = IsmGetObjectsStatistics (PLATFORM_SOURCE);
  138. if (objectCount) {
  139. ticks = objectCount->PersistentObjects;
  140. } else {
  141. ticks = 0;
  142. }
  143. g_PersistentSlice = IsmRegisterProgressSlice (ticks, max (1, ticks / 5));
  144. g_DatabaseSlice = IsmRegisterProgressSlice (3, 1);
  145. g_CompressedTicks = ticks;
  146. g_CompressedSlice = IsmRegisterProgressSlice (g_CompressedTicks, max (1, g_CompressedTicks / 5));
  147. } else {
  148. g_DownloadTicked = 0;
  149. g_DownloadTicks = 1000;
  150. g_DownloadSlice = IsmRegisterProgressSlice (g_DownloadTicks, 180);
  151. g_UncompressTicked = 0;
  152. g_UncompressTicks = 1000;
  153. g_UncompressSlice = IsmRegisterProgressSlice (g_UncompressTicks, 180);
  154. }
  155. }
  156. BOOL
  157. WINAPI
  158. RmvMedTransportQueryCapabilities (
  159. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  160. OUT PMIG_TRANSPORTTYPE TransportType,
  161. OUT PMIG_TRANSPORTCAPABILITIES Capabilities,
  162. OUT PCTSTR *FriendlyDescription
  163. )
  164. {
  165. if (TransportStorageId != g_RemovableMediaId) {
  166. return FALSE;
  167. }
  168. *TransportType = TRANSPORTTYPE_FULL;
  169. *Capabilities = CAPABILITY_COMPRESSED;
  170. *FriendlyDescription = TEXT("Span Media");
  171. return TRUE;
  172. }
  173. VOID
  174. pCleanupTempDir (
  175. VOID
  176. )
  177. {
  178. if (g_RmvMedTempPath) {
  179. FiRemoveAllFilesInTree (g_RmvMedTempPath);
  180. }
  181. }
  182. PCTSTR
  183. pCreateTemporaryDir (
  184. VOID
  185. )
  186. {
  187. TCHAR tempFile[MAX_PATH];
  188. if (!IsmGetTempDirectory (tempFile, ARRAYSIZE(tempFile))) {
  189. return NULL;
  190. }
  191. return DuplicatePathString (tempFile, 0);
  192. }
  193. BOOL
  194. WINAPI
  195. RmvMedTransportSetStorage (
  196. IN MIG_PLATFORMTYPEID Platform,
  197. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  198. IN MIG_TRANSPORTCAPABILITIES RequiredCapabilities,
  199. IN PCTSTR StoragePath,
  200. OUT PBOOL Valid,
  201. OUT PBOOL ImageExists
  202. )
  203. {
  204. BOOL result = FALSE;
  205. if (Valid) {
  206. *Valid = FALSE;
  207. }
  208. if (ImageExists) {
  209. *ImageExists = FALSE;
  210. }
  211. if (TransportStorageId == g_RemovableMediaId) {
  212. if ((!RequiredCapabilities) || (RequiredCapabilities == CAPABILITY_COMPRESSED)) {
  213. if (g_RemovableMediaPath) {
  214. FreePathString (g_RemovableMediaPath);
  215. g_RemovableMediaPath = NULL;
  216. }
  217. g_RemovableMediaPath = DuplicatePathString (StoragePath, 0);
  218. if (Valid) {
  219. *Valid = TRUE;
  220. }
  221. if (ImageExists) {
  222. if (Platform == PLATFORM_SOURCE) {
  223. *ImageExists = FALSE;
  224. } else {
  225. *ImageExists = TRUE;
  226. }
  227. }
  228. result = TRUE;
  229. }
  230. }
  231. return result;
  232. }
  233. PCTSTR
  234. pBuildDecoratedObject (
  235. IN MIG_OBJECTTYPEID ObjectTypeId,
  236. IN ENCODEDSTRHANDLE ObjectName
  237. )
  238. {
  239. TCHAR prefix[32];
  240. wsprintf (prefix, TEXT("%u"), ObjectTypeId);
  241. return JoinPaths (prefix, ObjectName);
  242. }
  243. VOID
  244. pDestroyDecoratedObject (
  245. IN PCTSTR String
  246. )
  247. {
  248. FreePathString (String);
  249. }
  250. BOOL
  251. pSaveDetails (
  252. IN PCTSTR DecoratedObject,
  253. IN PMIG_DETAILS Details
  254. )
  255. {
  256. PCTSTR key;
  257. BOOL b = FALSE;
  258. if ((!Details) || (!Details->DetailsSize)) {
  259. return TRUE;
  260. }
  261. key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
  262. if (key) {
  263. b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
  264. FreeText (key);
  265. }
  266. return b;
  267. }
  268. PCTSTR
  269. pAllocStorageFileName (
  270. VOID
  271. )
  272. {
  273. static UINT fileIndex = 0;
  274. TCHAR buffer [32];
  275. fileIndex ++;
  276. wsprintf (buffer, TEXT("%08X.DAT"), fileIndex);
  277. return DuplicatePathString (buffer, 0);
  278. }
  279. BOOL
  280. pSaveContentInMemory (
  281. IN MIG_OBJECTTYPEID ObjectTypeId,
  282. IN ENCODEDSTRHANDLE ObjectName,
  283. IN PCTSTR DecoratedObject,
  284. IN PMIG_CONTENT ObjectValue
  285. )
  286. {
  287. BOOL result = FALSE;
  288. MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
  289. if (ObjectValue->MemoryContent.ContentBytes && ObjectValue->MemoryContent.ContentSize) {
  290. MemDbSetUnorderedBlob (
  291. DecoratedObject,
  292. 0,
  293. ObjectValue->MemoryContent.ContentBytes,
  294. ObjectValue->MemoryContent.ContentSize
  295. );
  296. }
  297. result = pSaveDetails (DecoratedObject, &ObjectValue->Details);
  298. return result;
  299. }
  300. BOOL
  301. pAddFileToImage (
  302. IN PCTSTR FileName,
  303. IN PCTSTR StoredName,
  304. IN OUT PCOMPRESS_HANDLE CompressedHandle
  305. )
  306. {
  307. return CompressAddFileToHandle (FileName, StoredName, CompressedHandle);
  308. }
  309. BOOL
  310. pSaveContentInFile (
  311. IN MIG_OBJECTTYPEID ObjectTypeId,
  312. IN PCTSTR EncodedFileName,
  313. IN PCTSTR DecoratedObject,
  314. IN PMIG_CONTENT Content,
  315. IN OUT PCOMPRESS_HANDLE CompressedHandle
  316. )
  317. {
  318. BOOL result = FALSE;
  319. PCTSTR destPath = NULL;
  320. DWORD attributes = INVALID_ATTRIBUTES;
  321. MYASSERT (Content->ContentInFile);
  322. if (!Content->ContentInFile) {
  323. return FALSE;
  324. }
  325. //
  326. // Use the CopyFile API to move the file from local to storage.
  327. //
  328. __try {
  329. if (Content && (Content->Details.DetailsSize == sizeof (WIN32_FIND_DATAW)) && Content->Details.DetailsData) {
  330. attributes = ((PWIN32_FIND_DATAW)Content->Details.DetailsData)->dwFileAttributes;
  331. }
  332. if ((attributes != INVALID_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
  333. // this must be a directory, let's just write the key
  334. if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
  335. __leave;
  336. }
  337. result = TRUE;
  338. } else {
  339. //
  340. // Get a temp file, assemble the src path, copy the file
  341. //
  342. destPath = pAllocStorageFileName ();
  343. if (!destPath) {
  344. __leave;
  345. }
  346. if (!pAddFileToImage (Content->FileContent.ContentPath, destPath, CompressedHandle)) {
  347. __leave;
  348. }
  349. //
  350. // Keep track of where the file went
  351. //
  352. if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
  353. __leave;
  354. }
  355. if (!MemDbAddSingleLinkage (DecoratedObject, destPath, 0)) {
  356. __leave;
  357. }
  358. FreePathString (destPath);
  359. destPath = NULL;
  360. }
  361. //
  362. // Save details
  363. //
  364. result = pSaveDetails (DecoratedObject, &(Content->Details));
  365. }
  366. __finally {
  367. if (destPath) {
  368. FreePathString (destPath);
  369. destPath = NULL;
  370. }
  371. }
  372. return result;
  373. }
  374. PCTSTR
  375. pGetImageFile (
  376. IN UINT ImageIdx
  377. )
  378. {
  379. TCHAR imageFileName [13];
  380. PCTSTR imageFile = NULL;
  381. HANDLE imageFileHandle = NULL;
  382. wsprintf (imageFileName, S_TRANSPORT_IMG_FILE, ImageIdx);
  383. return JoinPaths (g_RmvMedTempPath, imageFileName);
  384. }
  385. BOOL
  386. pIsOurMedia (
  387. IN PCTSTR MediaFile,
  388. IN DWORD CheckSum,
  389. IN UINT MediaIdx
  390. )
  391. {
  392. HANDLE mediaHandle = NULL;
  393. IMAGE_HEADER imageHeader;
  394. BOOL result = FALSE;
  395. mediaHandle = BfOpenReadFile (MediaFile);
  396. if (!mediaHandle) {
  397. return result;
  398. }
  399. if (BfReadFile (mediaHandle, (PBYTE)(&imageHeader), sizeof (imageHeader))) {
  400. if ((imageHeader.Signature == RMVMEDTR_SIG) &&
  401. (imageHeader.CheckSum == CheckSum) &&
  402. (imageHeader.ImageNr != MediaIdx)
  403. ) {
  404. result = TRUE;
  405. }
  406. }
  407. CloseHandle (mediaHandle);
  408. return result;
  409. }
  410. HANDLE
  411. pLocalCreateFile (
  412. IN PCTSTR FileName
  413. )
  414. {
  415. HANDLE h;
  416. h = CreateFile (
  417. FileName,
  418. GENERIC_READ|GENERIC_WRITE,
  419. 0,
  420. NULL,
  421. CREATE_ALWAYS,
  422. FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
  423. NULL
  424. );
  425. if (h == INVALID_HANDLE_VALUE) {
  426. h = NULL;
  427. }
  428. return h;
  429. }
  430. BOOL
  431. pWriteToMedia (
  432. IN HANDLE MediaHandle,
  433. IN PBYTE Data,
  434. IN DWORD DataSize,
  435. IN UINT MediaIdx,
  436. OUT RMEDIA_ERR *Error
  437. )
  438. {
  439. DWORD err;
  440. RMEDIA_EXTRADATA extraData;
  441. INT_PTR appReply;
  442. RMEDIA_ERR error = RMEDIA_ERR_NOERROR;
  443. if (!BfWriteFile (MediaHandle, Data, DataSize)) {
  444. error = RMEDIA_ERR_GENERALERROR;
  445. // let's see the error code
  446. err = GetLastError ();
  447. if (err == ERROR_DISK_FULL) {
  448. error = RMEDIA_ERR_DISKFULL;
  449. }
  450. if (err == ERROR_NOT_READY) {
  451. error = RMEDIA_ERR_NOTREADY;
  452. }
  453. if (Error) {
  454. *Error = error;
  455. }
  456. return FALSE;
  457. }
  458. if (Error) {
  459. *Error = RMEDIA_ERR_NOERROR;
  460. }
  461. return TRUE;
  462. }
  463. VOID
  464. pWriteImageToMedia (
  465. IN ULONGLONG TotalImageSize,
  466. IN DWORD CheckSum,
  467. IN OUT PUINT MediaIdx,
  468. IN OUT PUINT ImageIdx,
  469. IN OUT PULONGLONG ImagePtr,
  470. OUT PULONGLONG TotalImageWritten,
  471. OUT PRMEDIA_ERR Error,
  472. OUT PBOOL Done
  473. )
  474. {
  475. static ULONGLONG totalImageWritten = 0;
  476. ULONGLONG imageWrittenLast = totalImageWritten;
  477. PCTSTR imageFile = NULL;
  478. PCTSTR mediaFile = NULL;
  479. HANDLE imageHandle = NULL;
  480. HANDLE mediaHandle = NULL;
  481. IMAGE_HEADER imageHeader;
  482. UINT mediaIdx;
  483. UINT imageIdx;
  484. ULONGLONG imagePtr;
  485. ULONGLONG imageSize;
  486. RMEDIA_ERR error = RMEDIA_ERR_NOERROR;
  487. BOOL done = FALSE;
  488. PBYTE memImage = NULL;
  489. DWORD chunkSize;
  490. ULARGE_INTEGER thisMediaMaxSize;
  491. ULARGE_INTEGER dummy1, dummy2;
  492. FARPROC pGetDiskFreeSpaceEx;
  493. DWORD sectPerClust;
  494. DWORD bytesPerSect;
  495. DWORD freeClusters;
  496. DWORD totalClusters;
  497. DWORD err;
  498. BOOL deleteFile = FALSE;
  499. LONGLONG numerator;
  500. LONGLONG divisor;
  501. LONGLONG tick;
  502. UINT delta;
  503. mediaIdx = *MediaIdx;
  504. imageIdx = *ImageIdx;
  505. imagePtr = *ImagePtr;
  506. imageFile = pGetImageFile (imageIdx);
  507. imageSize = BfGetFileSize (imageFile);
  508. mediaFile = JoinPaths (g_RemovableMediaPath, S_TRANSPORT_DEST_FILE);
  509. __try {
  510. if (!DoesFileExist (imageFile)) {
  511. DEBUGMSG ((DBG_ERROR, "Image file does not exist: %s", imageFile));
  512. done = TRUE;
  513. __leave;
  514. }
  515. imageHandle = BfOpenReadFile (imageFile);
  516. if (!imageHandle) {
  517. DEBUGMSG ((DBG_ERROR, "Can't open image file %s", imageFile));
  518. error = RMEDIA_ERR_CRITICAL;
  519. done = TRUE;
  520. __leave;
  521. }
  522. if (!BfSetFilePointer (imageHandle, imagePtr)) {
  523. error = RMEDIA_ERR_CRITICAL;
  524. done = TRUE;
  525. __leave;
  526. }
  527. if (pIsOurMedia (mediaFile, CheckSum, mediaIdx)) {
  528. DEBUGMSG ((DBG_ERROR, "Cannot overwrite our own file %s", mediaFile));
  529. error = RMEDIA_ERR_USEDMEDIA;
  530. __leave;
  531. }
  532. mediaHandle = BfCreateFile (mediaFile);
  533. if (!mediaHandle) {
  534. error = RMEDIA_ERR_GENERALERROR;
  535. err = GetLastError ();
  536. if (err == ERROR_ACCESS_DENIED) {
  537. error = RMEDIA_ERR_WRONGMEDIA;
  538. }
  539. if (err == ERROR_WRITE_PROTECT) {
  540. error = RMEDIA_ERR_WRITEPROTECT;
  541. }
  542. if (err == ERROR_NOT_READY) {
  543. error = RMEDIA_ERR_NOTREADY;
  544. }
  545. DEBUGMSG ((DBG_ERROR, "Can't create media file %s", mediaFile));
  546. __leave;
  547. }
  548. deleteFile = TRUE;
  549. imageHeader.Signature = RMVMEDTR_SIG;
  550. imageHeader.LastImage = 0;
  551. imageHeader.ImageNr = mediaIdx;
  552. imageHeader.CheckSum = CheckSum;
  553. imageHeader.TotalImageSize = TotalImageSize;
  554. if (!pWriteToMedia (mediaHandle, (PBYTE)(&imageHeader), sizeof (imageHeader), mediaIdx, &error)) {
  555. DEBUGMSG ((DBG_ERROR, "Can't write header to media file %s", mediaFile));
  556. __leave;
  557. }
  558. memImage = HeapAlloc (g_hHeap, 0, COPY_BUFFER_SIZE);
  559. if (!memImage) {
  560. error = RMEDIA_ERR_CRITICAL;
  561. done = TRUE;
  562. __leave;
  563. }
  564. while (TRUE) {
  565. if (IsmCheckCancel()) {
  566. error = RMEDIA_ERR_CRITICAL;
  567. done = TRUE;
  568. }
  569. if (imagePtr == 0) {
  570. // let's write this image size to the file
  571. if (!pWriteToMedia (mediaHandle, (PBYTE)(&imageSize), sizeof (imageSize), mediaIdx, &error)) {
  572. DEBUGMSG ((DBG_ERROR, "Can't write image size to media file %s", mediaFile));
  573. __leave;
  574. }
  575. }
  576. while (imageSize > imagePtr) {
  577. if (IsmCheckCancel()) {
  578. error = RMEDIA_ERR_CRITICAL;
  579. done = TRUE;
  580. }
  581. chunkSize = COPY_BUFFER_SIZE;
  582. if ((ULONGLONG)chunkSize > (imageSize - imagePtr)) {
  583. chunkSize = (DWORD)(imageSize - imagePtr);
  584. }
  585. if (!BfReadFile (imageHandle, memImage, chunkSize)) {
  586. DEBUGMSG ((DBG_ERROR, "Can't read from image file %s", imageFile));
  587. error = RMEDIA_ERR_CRITICAL;
  588. done = TRUE;
  589. __leave;
  590. }
  591. if (!pWriteToMedia (mediaHandle, memImage, chunkSize, mediaIdx, &error)) {
  592. // write failed, let's see if we just ran out of space
  593. if (error == RMEDIA_ERR_DISKFULL) {
  594. // the disk is (almost) full
  595. // we will make an attempt to use the remaining space
  596. // either way we do not consider this an error
  597. done = FALSE;
  598. mediaIdx ++;
  599. // Find out if GetDiskFreeSpaceEx is supported
  600. #ifdef UNICODE
  601. pGetDiskFreeSpaceEx = GetProcAddress( GetModuleHandle (TEXT("kernel32.dll")), "GetDiskFreeSpaceExW");
  602. #else
  603. pGetDiskFreeSpaceEx = GetProcAddress( GetModuleHandle (TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
  604. #endif
  605. if (pGetDiskFreeSpaceEx) {
  606. if (!pGetDiskFreeSpaceEx (g_RemovableMediaPath, &dummy1, &dummy2, &thisMediaMaxSize)) {
  607. DEBUGMSG ((DBG_WHOOPS, "Can't get media free space of %s using EX routine", g_RemovableMediaPath));
  608. __leave;
  609. }
  610. } else {
  611. if (GetDiskFreeSpace (g_RemovableMediaPath, &sectPerClust, &bytesPerSect, &freeClusters, &totalClusters)) {
  612. thisMediaMaxSize.QuadPart = Int32x32To64 ((sectPerClust * bytesPerSect), freeClusters);
  613. } else {
  614. DEBUGMSG ((DBG_WHOOPS, "Can't get media free space of %s", g_RemovableMediaPath));
  615. __leave;
  616. }
  617. }
  618. // regardless of the outcome of the next write we don't want to report an error
  619. error = 0;
  620. if (thisMediaMaxSize.LowPart < chunkSize) {
  621. if (thisMediaMaxSize.LowPart) {
  622. // we attempt one more write with the
  623. // available media disk size
  624. if (!pWriteToMedia (mediaHandle, memImage, thisMediaMaxSize.LowPart, mediaIdx, &error)) {
  625. // this should have succeeded but...
  626. DEBUGMSG ((DBG_WHOOPS, "Can't write the remaining free bytes. Something is wrong with GetDiskFreeSpace %s", mediaFile));
  627. // regardless of the outcome of this write we don't want to report an error
  628. error = 0;
  629. __leave;
  630. }
  631. // let's adjust imagePtr
  632. imagePtr += thisMediaMaxSize.LowPart;
  633. totalImageWritten += thisMediaMaxSize.LowPart;
  634. }
  635. }
  636. } else {
  637. error = RMEDIA_ERR_GENERALERROR;
  638. }
  639. __leave;
  640. } else {
  641. imagePtr += chunkSize;
  642. totalImageWritten += chunkSize;
  643. }
  644. // now update the progress bar
  645. numerator = (LONGLONG) totalImageWritten * (LONGLONG) g_CompressedTicks;
  646. divisor = (LONGLONG) TotalImageSize;
  647. if (divisor) {
  648. tick = numerator / divisor;
  649. } else {
  650. tick = 0;
  651. }
  652. delta = (UINT) tick - g_CompressedTicked;
  653. if (delta) {
  654. if (!IsmTickProgressBar (g_CompressedSlice, delta)) {
  655. error = RMEDIA_ERR_CRITICAL;
  656. done = TRUE;
  657. __leave;
  658. }
  659. g_CompressedTicked += delta;
  660. }
  661. }
  662. // we just finished writing the image, let's see if there is some other image out there
  663. imageIdx ++;
  664. CloseHandle (imageHandle);
  665. imageHandle = NULL;
  666. FreePathString (imageFile);
  667. imageFile = pGetImageFile (imageIdx);
  668. if (!DoesFileExist (imageFile)) {
  669. imageSize = 0;
  670. imagePtr = 0;
  671. // let's go back and write that this is the last media
  672. if (!BfSetFilePointer (mediaHandle, 0)) {
  673. DEBUGMSG ((DBG_ERROR, "Can't update media file %s", mediaFile));
  674. error = RMEDIA_ERR_GENERALERROR;
  675. __leave;
  676. }
  677. imageHeader.LastImage = 1;
  678. if (!pWriteToMedia (mediaHandle, (PBYTE)(&imageHeader), sizeof (imageHeader), mediaIdx, &error)) {
  679. DEBUGMSG ((DBG_ERROR, "Can't update media file %s", mediaFile));
  680. __leave;
  681. }
  682. done = TRUE;
  683. __leave;
  684. }
  685. imageSize = BfGetFileSize (imageFile);
  686. imagePtr = 0;
  687. imageHandle = BfOpenReadFile (imageFile);
  688. if (!imageHandle) {
  689. DEBUGMSG ((DBG_ERROR, "Can't open next image file %s", imageFile));
  690. error = RMEDIA_ERR_CRITICAL;
  691. done = TRUE;
  692. __leave;
  693. }
  694. }
  695. }
  696. __finally {
  697. if (mediaHandle) {
  698. if (error == RMEDIA_ERR_NOERROR) {
  699. if (!FlushFileBuffers (mediaHandle)) {
  700. error = RMEDIA_ERR_GENERALERROR;
  701. // let's see the error code
  702. err = GetLastError ();
  703. if (err == ERROR_NOT_READY) {
  704. error = RMEDIA_ERR_NOTREADY;
  705. }
  706. done = FALSE;
  707. }
  708. }
  709. CloseHandle (mediaHandle);
  710. mediaHandle = NULL;
  711. }
  712. if ((error != RMEDIA_ERR_NOERROR) &&
  713. mediaFile &&
  714. deleteFile
  715. ) {
  716. DeleteFile (mediaFile);
  717. }
  718. if (memImage) {
  719. HeapFree (g_hHeap, 0, memImage);
  720. memImage = NULL;
  721. }
  722. if (imageHandle) {
  723. CloseHandle (imageHandle);
  724. imageHandle = NULL;
  725. }
  726. if (imageFile) {
  727. FreePathString (imageFile);
  728. imageFile = NULL;
  729. }
  730. if (mediaFile) {
  731. FreePathString (mediaFile);
  732. mediaFile = NULL;
  733. }
  734. }
  735. if (!error) {
  736. *MediaIdx = mediaIdx;
  737. *ImageIdx = imageIdx;
  738. *ImagePtr = imagePtr;
  739. } else {
  740. totalImageWritten = imageWrittenLast;
  741. }
  742. if (TotalImageWritten) {
  743. *TotalImageWritten = totalImageWritten;
  744. }
  745. *Error = error;
  746. *Done = done;
  747. }
  748. BOOL
  749. pWriteAllImages (
  750. VOID
  751. )
  752. {
  753. ULONGLONG totalImageSize = 0;
  754. ULONGLONG totalImageWritten = 0;
  755. ULONGLONG imageSize = 0;
  756. UINT mediaIdx = 1;
  757. UINT imageIdx = 1;
  758. ULONGLONG imagePtr = 0;
  759. PCTSTR imageFile;
  760. RMEDIA_ERR error = RMEDIA_ERR_NOERROR;
  761. BOOL done = FALSE;
  762. BOOL result = TRUE;
  763. BOOL diskFull = FALSE;
  764. INT_PTR appReply;
  765. INT r1,r2,r3;
  766. DWORD checkSum;
  767. RMEDIA_EXTRADATA extraData;
  768. // let's get the total image size for the progress bar
  769. imageIdx = 1;
  770. while (TRUE) {
  771. imageFile = pGetImageFile (imageIdx);
  772. imageSize = BfGetFileSize (imageFile);
  773. if (imageSize == 0) {
  774. FreePathString (imageFile);
  775. break;
  776. }
  777. totalImageSize += imageSize;
  778. FreePathString (imageFile);
  779. imageIdx ++;
  780. }
  781. imageIdx = 1;
  782. imageFile = pGetImageFile (imageIdx);
  783. srand( GetTickCount());
  784. r1 = rand();
  785. r2 = rand();
  786. r3 = rand();
  787. checkSum = r1 + r2 * 32768 + (r3 & 3) * 1073741824;
  788. FreePathString (imageFile);
  789. while (!done) {
  790. // send the proper message to the app
  791. extraData.LastError = error;
  792. extraData.MediaNumber = mediaIdx;
  793. extraData.TotalImageSize = totalImageSize;
  794. extraData.TotalImageWritten = totalImageWritten;
  795. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_RMEDIA_SAVE, (ULONG_PTR)&extraData);
  796. if (!appReply) {
  797. //
  798. // user cancelled
  799. //
  800. done = TRUE;
  801. result = FALSE;
  802. continue;
  803. }
  804. // write this disk and loop until we finish
  805. pWriteImageToMedia (totalImageSize, checkSum, &mediaIdx, &imageIdx, &imagePtr, &totalImageWritten, &error, &done);
  806. if (done) {
  807. result = !error;
  808. }
  809. }
  810. return result;
  811. }
  812. BOOL
  813. WINAPI
  814. RmvMedTransportSaveState (
  815. VOID
  816. )
  817. {
  818. MIG_APPINFO appInfo;
  819. ERRUSER_EXTRADATA extraData;
  820. MIG_OBJECTWITHATTRIBUTE_ENUM objEnum;
  821. PCTSTR databaseFile = NULL;
  822. PCTSTR decoratedObject = NULL;
  823. MIG_CONTENT value;
  824. PMIG_CONTENT convValue;
  825. COMPRESS_HANDLE compressedHandle;
  826. INT_PTR appReply;
  827. BOOL okSave = FALSE;
  828. TRANSCOPY_ERROR transCopyError;
  829. #ifdef DEBUG
  830. PCTSTR nativeObjectName;
  831. #endif
  832. BOOL result = FALSE;
  833. g_RmvMedPlatform = PLATFORM_SOURCE;
  834. __try {
  835. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  836. appInfo.Phase = MIG_TRANSPORT_PHASE;
  837. appInfo.SubPhase = SUBPHASE_PREPARING;
  838. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  839. ZeroMemory (&compressedHandle, sizeof (COMPRESS_HANDLE));
  840. g_RmvMedTempPath = pCreateTemporaryDir ();
  841. if (!g_RmvMedTempPath) {
  842. extraData.Error = ERRUSER_ERROR_CANTCREATETEMPDIR;
  843. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  844. extraData.ObjectTypeId = 0;
  845. extraData.ObjectName = NULL;
  846. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  847. __leave;
  848. }
  849. #ifdef PRERELEASE
  850. {
  851. HINF debugInfHandle;
  852. INFSTRUCT context = INITINFSTRUCT_PMHANDLE;
  853. DWORD maxSize = 0;
  854. debugInfHandle = InfOpenInfFile (TEXT("c:\\debug.inf"));
  855. if (debugInfHandle && (debugInfHandle != INVALID_HANDLE_VALUE)) {
  856. if (InfFindFirstLine (
  857. debugInfHandle,
  858. TEXT("RemovableMedia"),
  859. TEXT("LimitCabSize"),
  860. &context
  861. )
  862. ) {
  863. InfGetIntField (&context, 1, &maxSize);
  864. }
  865. InfCleanUpInfStruct (&context);
  866. }
  867. if (!CompressCreateHandle (g_RmvMedTempPath, S_TRANSPORT_IMG_FILE, 1, maxSize, &compressedHandle)) {
  868. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  869. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  870. extraData.ObjectTypeId = 0;
  871. extraData.ObjectName = NULL;
  872. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  873. __leave;
  874. }
  875. }
  876. #else
  877. if (!CompressCreateHandle (g_RmvMedTempPath, S_TRANSPORT_IMG_FILE, 1, 0, &compressedHandle)) {
  878. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  879. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  880. extraData.ObjectTypeId = 0;
  881. extraData.ObjectName = NULL;
  882. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  883. __leave;
  884. }
  885. #endif
  886. //
  887. // Enumerate all persistent objects
  888. //
  889. if (IsmEnumFirstPersistentObject (&objEnum)) {
  890. do {
  891. //
  892. // For each object to be saved, do the appropriate
  893. // data copy action
  894. //
  895. if (IsmCheckCancel()) {
  896. __leave;
  897. }
  898. #ifdef DEBUG
  899. nativeObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  900. DEBUGMSG ((DBG_RMVMED, "Transporting: %s", nativeObjectName));
  901. IsmReleaseMemory (nativeObjectName);
  902. #endif
  903. okSave = FALSE;
  904. while (!okSave) {
  905. if (!IsmAcquireObjectEx (
  906. objEnum.ObjectTypeId,
  907. objEnum.ObjectName,
  908. &value,
  909. CONTENTTYPE_ANY,
  910. 0
  911. )) {
  912. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  913. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  914. transCopyError.Error = GetLastError ();
  915. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  916. appReply = APPRESPONSE_IGNORE;
  917. } else {
  918. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  919. if ((appReply == APPRESPONSE_NONE) ||
  920. (appReply == APPRESPONSE_FAIL)
  921. ) {
  922. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  923. IsmReleaseMemory (transCopyError.ObjectName);
  924. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  925. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  926. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  927. extraData.ObjectName = objEnum.ObjectName;
  928. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  929. IsmAbortPersistentObjectEnum (&objEnum);
  930. __leave;
  931. }
  932. }
  933. if (appReply == APPRESPONSE_IGNORE) {
  934. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  935. IsmReleaseMemory (transCopyError.ObjectName);
  936. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  937. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  938. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  939. extraData.ObjectName = objEnum.ObjectName;
  940. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  941. break;
  942. }
  943. IsmReleaseMemory (transCopyError.ObjectName);
  944. continue;
  945. }
  946. okSave = TRUE;
  947. }
  948. if (okSave) {
  949. #ifdef UNICODE
  950. convValue = &value;
  951. #else
  952. // now let's convert this object content to UNICODE
  953. convValue = IsmConvertObjectContentToUnicode (objEnum.ObjectTypeId, objEnum.ObjectName, &value);
  954. if (!convValue) {
  955. convValue = &value;
  956. }
  957. #endif
  958. decoratedObject = pBuildDecoratedObject (objEnum.ObjectTypeId, objEnum.ObjectName);
  959. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  960. appInfo.Phase = MIG_TRANSPORT_PHASE;
  961. appInfo.SubPhase = SUBPHASE_COMPRESSING;
  962. appInfo.ObjectTypeId = (objEnum.ObjectTypeId & (~PLATFORM_MASK));
  963. appInfo.ObjectName = objEnum.ObjectName;
  964. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  965. if (convValue->ContentInFile) {
  966. okSave = FALSE;
  967. while (!okSave) {
  968. if (!pSaveContentInFile (objEnum.ObjectTypeId, objEnum.ObjectName, decoratedObject, convValue, &compressedHandle)) {
  969. if (GetLastError () == ERROR_DISK_FULL) {
  970. // we just failed because we don't have enough space on the destination
  971. // path. Let's tell that to the user
  972. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  973. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  974. extraData.ObjectTypeId = 0;
  975. extraData.ObjectName = NULL;
  976. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  977. __leave;
  978. }
  979. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  980. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  981. transCopyError.Error = GetLastError ();
  982. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  983. appReply = APPRESPONSE_IGNORE;
  984. } else {
  985. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  986. if ((appReply == APPRESPONSE_NONE) ||
  987. (appReply == APPRESPONSE_FAIL)
  988. ) {
  989. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  990. IsmReleaseMemory (transCopyError.ObjectName);
  991. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  992. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  993. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  994. extraData.ObjectName = objEnum.ObjectName;
  995. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  996. IsmAbortPersistentObjectEnum (&objEnum);
  997. __leave;
  998. }
  999. }
  1000. if (appReply == APPRESPONSE_IGNORE) {
  1001. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  1002. IsmReleaseMemory (transCopyError.ObjectName);
  1003. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1004. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1005. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1006. extraData.ObjectName = objEnum.ObjectName;
  1007. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  1008. break;
  1009. }
  1010. IsmReleaseMemory (transCopyError.ObjectName);
  1011. continue;
  1012. }
  1013. okSave = TRUE;
  1014. }
  1015. } else {
  1016. okSave = FALSE;
  1017. while (!okSave) {
  1018. if (!pSaveContentInMemory (objEnum.ObjectTypeId, objEnum.ObjectName, decoratedObject, convValue)) {
  1019. if (GetLastError () == ERROR_DISK_FULL) {
  1020. // we just failed because we don't have enough space on the destination
  1021. // path. Let's tell that to the user
  1022. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  1023. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1024. extraData.ObjectTypeId = 0;
  1025. extraData.ObjectName = NULL;
  1026. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1027. __leave;
  1028. }
  1029. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  1030. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  1031. transCopyError.Error = GetLastError ();
  1032. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  1033. appReply = APPRESPONSE_IGNORE;
  1034. } else {
  1035. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  1036. if ((appReply == APPRESPONSE_NONE) ||
  1037. (appReply == APPRESPONSE_FAIL)
  1038. ) {
  1039. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  1040. IsmReleaseMemory (transCopyError.ObjectName);
  1041. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1042. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1043. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1044. extraData.ObjectName = objEnum.ObjectName;
  1045. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1046. IsmAbortPersistentObjectEnum (&objEnum);
  1047. __leave;
  1048. }
  1049. }
  1050. if (appReply == APPRESPONSE_IGNORE) {
  1051. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  1052. IsmReleaseMemory (transCopyError.ObjectName);
  1053. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1054. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1055. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1056. extraData.ObjectName = objEnum.ObjectName;
  1057. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  1058. break;
  1059. }
  1060. IsmReleaseMemory (transCopyError.ObjectName);
  1061. continue;
  1062. }
  1063. okSave = TRUE;
  1064. }
  1065. }
  1066. #ifndef UNICODE
  1067. if (convValue != (&value)) {
  1068. IsmFreeConvertedObjectContent (objEnum.ObjectTypeId, convValue);
  1069. }
  1070. #endif
  1071. IsmReleaseObject (&value);
  1072. pDestroyDecoratedObject (decoratedObject);
  1073. decoratedObject = NULL;
  1074. }
  1075. IsmTickProgressBar (g_PersistentSlice, 1);
  1076. if (IsmCheckCancel()) {
  1077. __leave;
  1078. }
  1079. } while (IsmEnumNextPersistentObject (&objEnum));
  1080. IsmAbortPersistentObjectEnum (&objEnum);
  1081. }
  1082. if (IsmCheckCancel()) {
  1083. __leave;
  1084. }
  1085. databaseFile = JoinPaths (g_RmvMedTempPath, S_TRANSPORT_DAT_FILE);
  1086. if (!MemDbSave (databaseFile)) {
  1087. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  1088. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1089. extraData.ObjectTypeId = 0;
  1090. extraData.ObjectName = NULL;
  1091. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1092. __leave;
  1093. }
  1094. IsmTickProgressBar (g_DatabaseSlice, 1);
  1095. if (IsmCheckCancel()) {
  1096. __leave;
  1097. }
  1098. if (!pAddFileToImage (databaseFile, S_TRANSPORT_DAT_FILE, &compressedHandle)) {
  1099. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  1100. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1101. extraData.ObjectTypeId = 0;
  1102. extraData.ObjectName = NULL;
  1103. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1104. __leave;
  1105. }
  1106. IsmTickProgressBar (g_DatabaseSlice, 1);
  1107. FreePathString (databaseFile);
  1108. databaseFile = NULL;
  1109. if (!CompressFlushAndCloseHandle (&compressedHandle)) {
  1110. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  1111. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1112. extraData.ObjectTypeId = 0;
  1113. extraData.ObjectName = NULL;
  1114. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1115. __leave;
  1116. }
  1117. IsmTickProgressBar (g_DatabaseSlice, 1);
  1118. if (IsmCheckCancel()) {
  1119. __leave;
  1120. }
  1121. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  1122. appInfo.Phase = MIG_TRANSPORT_PHASE;
  1123. appInfo.SubPhase = SUBPHASE_MEDIAWRITING;
  1124. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  1125. if (!pWriteAllImages ()) {
  1126. extraData.Error = ERRUSER_ERROR_CANTWRITETODESTPATH;
  1127. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1128. extraData.ObjectTypeId = 0;
  1129. extraData.ObjectName = NULL;
  1130. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1131. __leave;
  1132. }
  1133. result = TRUE;
  1134. }
  1135. __finally {
  1136. PushError ();
  1137. CompressCleanupHandle (&compressedHandle);
  1138. if (databaseFile) {
  1139. FreePathString (databaseFile);
  1140. databaseFile = NULL;
  1141. }
  1142. PopError ();
  1143. }
  1144. PushError ();
  1145. pCleanupTempDir ();
  1146. PopError ();
  1147. return result;
  1148. }
  1149. VOID
  1150. pReadImageFromMedia (
  1151. IN PDWORD CheckSum,
  1152. IN OUT PUINT MediaIdx,
  1153. IN OUT PUINT ImageIdx,
  1154. IN OUT PULONGLONG ImageRemaining,
  1155. OUT PRMEDIA_ERR Error,
  1156. OUT PBOOL Done
  1157. )
  1158. {
  1159. static ULONGLONG totalImageSize = 0;
  1160. static ULONGLONG totalImageRead = 0;
  1161. ULONGLONG imageReadLast = totalImageRead;
  1162. PCTSTR imageFile = NULL;
  1163. PCTSTR mediaFile = NULL;
  1164. HANDLE imageHandle = NULL;
  1165. HANDLE mediaHandle = NULL;
  1166. IMAGE_HEADER imageHeader;
  1167. DWORD checkSum;
  1168. UINT mediaIdx;
  1169. UINT imageIdx;
  1170. ULONGLONG imageRemaining;
  1171. ULONGLONG imageSize;
  1172. RMEDIA_ERR error = RMEDIA_ERR_NOERROR;
  1173. RMEDIA_EXTRADATA extraData;
  1174. INT_PTR appReply;
  1175. BOOL done = FALSE;
  1176. PBYTE memImage = NULL;
  1177. DWORD chunkSize;
  1178. DWORD bytesRead;
  1179. LONGLONG numerator;
  1180. LONGLONG divisor;
  1181. LONGLONG tick;
  1182. UINT delta;
  1183. DWORD err;
  1184. checkSum = *CheckSum;
  1185. mediaIdx = *MediaIdx;
  1186. imageIdx = *ImageIdx;
  1187. imageRemaining = *ImageRemaining;
  1188. mediaFile = JoinPaths (g_RemovableMediaPath, S_TRANSPORT_DEST_FILE);
  1189. __try {
  1190. mediaHandle = BfOpenReadFile (mediaFile);
  1191. if (!mediaHandle) {
  1192. error = RMEDIA_ERR_WRONGMEDIA;
  1193. err = GetLastError ();
  1194. if (err == ERROR_NOT_READY) {
  1195. error = RMEDIA_ERR_NOTREADY;
  1196. }
  1197. DEBUGMSG ((DBG_ERROR, "Can't create media file %s", mediaFile));
  1198. __leave;
  1199. }
  1200. imageFile = pGetImageFile (imageIdx);
  1201. if (DoesFileExist (imageFile)) {
  1202. imageSize = BfGetFileSize (imageFile);
  1203. imageHandle = BfOpenFile (imageFile);
  1204. } else {
  1205. imageSize = 0;
  1206. imageHandle = BfCreateFile (imageFile);
  1207. }
  1208. if (!imageHandle) {
  1209. error = RMEDIA_ERR_CRITICAL;
  1210. done = TRUE;
  1211. __leave;
  1212. }
  1213. if (!BfSetFilePointer (imageHandle, imageSize)) {
  1214. error = RMEDIA_ERR_CRITICAL;
  1215. done = TRUE;
  1216. __leave;
  1217. }
  1218. if (!BfReadFile (mediaHandle, (PBYTE)(&imageHeader), sizeof (imageHeader))) {
  1219. error = RMEDIA_ERR_WRONGMEDIA;
  1220. err = GetLastError ();
  1221. if (err == ERROR_NOT_READY) {
  1222. error = RMEDIA_ERR_NOTREADY;
  1223. }
  1224. __leave;
  1225. }
  1226. if (imageHeader.Signature != RMVMEDTR_SIG) {
  1227. if ((imageHeader.Signature != RMVMEDTR_OLDSIG1) &&
  1228. (imageHeader.Signature != RMVMEDTR_OLDSIG2)
  1229. ) {
  1230. error = RMEDIA_ERR_WRONGMEDIA;
  1231. __leave;
  1232. }
  1233. error = RMEDIA_ERR_OLDMEDIA;
  1234. __leave;
  1235. }
  1236. if (imageHeader.ImageNr != mediaIdx) {
  1237. error = RMEDIA_ERR_WRONGMEDIA;
  1238. __leave;
  1239. }
  1240. if (checkSum) {
  1241. if (checkSum != imageHeader.CheckSum) {
  1242. error = RMEDIA_ERR_WRONGMEDIA;
  1243. __leave;
  1244. }
  1245. } else {
  1246. checkSum = imageHeader.CheckSum;
  1247. }
  1248. totalImageSize = imageHeader.TotalImageSize;
  1249. memImage = HeapAlloc (g_hHeap, 0, COPY_BUFFER_SIZE);
  1250. if (!memImage) {
  1251. error = RMEDIA_ERR_CRITICAL;
  1252. done = TRUE;
  1253. __leave;
  1254. }
  1255. while (TRUE) {
  1256. if (IsmCheckCancel()) {
  1257. error = RMEDIA_ERR_CRITICAL;
  1258. done = TRUE;
  1259. }
  1260. if (imageRemaining == 0) {
  1261. // let's read this image size to the file
  1262. if (!BfReadFile (mediaHandle, (PBYTE)(&imageRemaining), sizeof (imageRemaining))) {
  1263. error = RMEDIA_ERR_GENERALERROR;
  1264. err = GetLastError ();
  1265. if (err == ERROR_NOT_READY) {
  1266. error = RMEDIA_ERR_NOTREADY;
  1267. }
  1268. __leave;
  1269. }
  1270. }
  1271. while (imageRemaining) {
  1272. if (IsmCheckCancel()) {
  1273. error = RMEDIA_ERR_CRITICAL;
  1274. done = TRUE;
  1275. }
  1276. chunkSize = COPY_BUFFER_SIZE;
  1277. if ((ULONGLONG)chunkSize > imageRemaining) {
  1278. chunkSize = (DWORD)(imageRemaining);
  1279. }
  1280. while (TRUE) {
  1281. if (!ReadFile (mediaHandle, memImage, chunkSize, &bytesRead, NULL)) {
  1282. // let's see the error code
  1283. err = GetLastError ();
  1284. if (err == ERROR_NOT_READY) {
  1285. error = RMEDIA_ERR_NOTREADY;
  1286. extraData.LastError = error;
  1287. extraData.MediaNumber = mediaIdx;
  1288. extraData.TotalImageSize = 0;
  1289. extraData.TotalImageWritten = 0;
  1290. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_RMEDIA_LOAD, (ULONG_PTR)&extraData);
  1291. if (!appReply) {
  1292. //
  1293. // user cancelled
  1294. //
  1295. error = RMEDIA_ERR_CRITICAL;
  1296. done = TRUE;
  1297. __leave;
  1298. } else {
  1299. error = RMEDIA_ERR_NOERROR;
  1300. continue;
  1301. }
  1302. }
  1303. // read failed, major problem, exiting
  1304. error = RMEDIA_ERR_GENERALERROR;
  1305. __leave;
  1306. } else {
  1307. break;
  1308. }
  1309. }
  1310. if (!BfWriteFile (imageHandle, memImage, bytesRead)) {
  1311. // major problem, exiting
  1312. error = RMEDIA_ERR_CRITICAL;
  1313. done = TRUE;
  1314. __leave;
  1315. }
  1316. imageRemaining -= bytesRead;
  1317. totalImageRead += bytesRead;
  1318. // now update the progress bar
  1319. numerator = (LONGLONG) totalImageRead * (LONGLONG) g_DownloadTicks;
  1320. divisor = (LONGLONG) totalImageSize;
  1321. if (divisor) {
  1322. tick = numerator / divisor;
  1323. } else {
  1324. tick = 0;
  1325. }
  1326. delta = (UINT) tick - g_DownloadTicked;
  1327. if (delta) {
  1328. if (!IsmTickProgressBar (g_DownloadSlice, delta)) {
  1329. error = RMEDIA_ERR_CRITICAL;
  1330. done = TRUE;
  1331. __leave;
  1332. }
  1333. g_DownloadTicked += delta;
  1334. }
  1335. if (bytesRead != chunkSize) {
  1336. // our media image is done, let's get the new one
  1337. mediaIdx ++;
  1338. done = FALSE;
  1339. __leave;
  1340. }
  1341. }
  1342. // we just finished reading the image, let's see if there is some other image out there
  1343. // let's read this image size to the file
  1344. if (!BfReadFile (mediaHandle, (PBYTE)(&imageRemaining), sizeof (imageRemaining))) {
  1345. if (imageHeader.LastImage) {
  1346. done = TRUE;
  1347. } else {
  1348. error = RMEDIA_ERR_GENERALERROR;
  1349. err = GetLastError ();
  1350. if (err == ERROR_NOT_READY) {
  1351. error = RMEDIA_ERR_NOTREADY;
  1352. }
  1353. }
  1354. __leave;
  1355. }
  1356. CloseHandle (imageHandle);
  1357. FreePathString (imageFile);
  1358. imageIdx ++;
  1359. imageFile = pGetImageFile (imageIdx);
  1360. imageHandle = BfCreateFile (imageFile);
  1361. if (!imageHandle) {
  1362. error = RMEDIA_ERR_CRITICAL;
  1363. done = TRUE;
  1364. __leave;
  1365. }
  1366. }
  1367. }
  1368. __finally {
  1369. if (memImage) {
  1370. HeapFree (g_hHeap, 0, memImage);
  1371. memImage = NULL;
  1372. }
  1373. if (imageHandle) {
  1374. CloseHandle (imageHandle);
  1375. imageHandle = NULL;
  1376. }
  1377. if (imageFile) {
  1378. FreePathString (imageFile);
  1379. imageFile = NULL;
  1380. }
  1381. if (mediaHandle) {
  1382. CloseHandle (mediaHandle);
  1383. mediaHandle = NULL;
  1384. }
  1385. if (mediaFile) {
  1386. FreePathString (mediaFile);
  1387. mediaFile = NULL;
  1388. }
  1389. }
  1390. if (!error) {
  1391. *CheckSum = checkSum;
  1392. *MediaIdx = mediaIdx;
  1393. *ImageIdx = imageIdx;
  1394. *ImageRemaining = imageRemaining;
  1395. } else {
  1396. totalImageRead = imageReadLast;
  1397. }
  1398. *Error = error;
  1399. *Done = done;
  1400. }
  1401. BOOL
  1402. pReadAllImages (
  1403. VOID
  1404. )
  1405. {
  1406. UINT mediaIdx = 1;
  1407. UINT imageIdx = 1;
  1408. ULONGLONG imageRemaining = 0;
  1409. RMEDIA_ERR error = RMEDIA_ERR_NOERROR;
  1410. BOOL done = FALSE;
  1411. BOOL result = TRUE;
  1412. INT_PTR appReply;
  1413. DWORD checkSum = 0;
  1414. RMEDIA_EXTRADATA extraData;
  1415. while (!done) {
  1416. // send the proper message to the app
  1417. if (error == RMEDIA_ERR_OLDMEDIA) {
  1418. PushError ();
  1419. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_OLD_STORAGE, 0);
  1420. PopError ();
  1421. } else {
  1422. extraData.LastError = error;
  1423. extraData.MediaNumber = mediaIdx;
  1424. extraData.TotalImageSize = 0;
  1425. extraData.TotalImageWritten = 0;
  1426. PushError ();
  1427. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_RMEDIA_LOAD, (ULONG_PTR)&extraData);
  1428. PopError ();
  1429. }
  1430. if (!appReply) {
  1431. //
  1432. // user cancelled
  1433. //
  1434. done = TRUE;
  1435. result = FALSE;
  1436. continue;
  1437. }
  1438. pReadImageFromMedia (&checkSum, &mediaIdx, &imageIdx, &imageRemaining, &error, &done);
  1439. if (done) {
  1440. result = !error;
  1441. }
  1442. }
  1443. return result;
  1444. }
  1445. PCTSTR
  1446. pRmvMedGetNewFileName (
  1447. IN PCTSTR FileName
  1448. )
  1449. {
  1450. PCTSTR newFileName = NULL;
  1451. PTSTR tempPtr1 = NULL;
  1452. PCTSTR endStr1 = NULL;
  1453. PCTSTR tempPtr2 = NULL;
  1454. PCTSTR endStr2 = NULL;
  1455. INT i;
  1456. // let's modify the file to extract. The file name will
  1457. // be split in 2 after the first 5 characters
  1458. newFileName = DuplicatePathString (FileName, 1);
  1459. if (!newFileName) {
  1460. return NULL;
  1461. }
  1462. tempPtr1 = (PTSTR) GetFileNameFromPath (newFileName);
  1463. if (!tempPtr1) {
  1464. FreePathString (newFileName);
  1465. return NULL;
  1466. }
  1467. endStr1 = GetEndOfString (newFileName);
  1468. if (!endStr1) {
  1469. FreePathString (newFileName);
  1470. return NULL;
  1471. }
  1472. tempPtr2 = GetFileNameFromPath (FileName);
  1473. if (!tempPtr2) {
  1474. FreePathString (newFileName);
  1475. return NULL;
  1476. }
  1477. endStr2 = GetEndOfString (FileName);
  1478. if (!endStr2) {
  1479. FreePathString (newFileName);
  1480. return NULL;
  1481. }
  1482. for (i = 0; i < 5; i ++) {
  1483. tempPtr1 = _tcsinc (tempPtr1);
  1484. tempPtr2 = _tcsinc (tempPtr2);
  1485. }
  1486. if ((tempPtr1 < endStr1) &&
  1487. (tempPtr2 < endStr2)
  1488. ) {
  1489. StringCopy (tempPtr1, TEXT("\\"));
  1490. tempPtr1 = _tcsinc (tempPtr1);
  1491. StringCopy (tempPtr1, tempPtr2);
  1492. } else {
  1493. FreePathString (newFileName);
  1494. newFileName = NULL;
  1495. }
  1496. return newFileName;
  1497. }
  1498. BOOL
  1499. pRmvMedCallback (
  1500. IN PCTSTR FileToExtract,
  1501. IN LONGLONG FileSize,
  1502. OUT PBOOL ExtractFile,
  1503. IN OUT PCTSTR *NewFileName
  1504. )
  1505. {
  1506. LONGLONG numerator;
  1507. LONGLONG divisor;
  1508. LONGLONG tick;
  1509. UINT delta;
  1510. if (NewFileName) {
  1511. *NewFileName = pRmvMedGetNewFileName (FileToExtract);
  1512. }
  1513. g_FilesRead ++;
  1514. // now update the progress bar
  1515. numerator = (LONGLONG) g_FilesRead * (LONGLONG) g_UncompressTicks;
  1516. divisor = (LONGLONG) g_TotalFiles;
  1517. if (divisor) {
  1518. tick = numerator / divisor;
  1519. } else {
  1520. tick = 0;
  1521. }
  1522. delta = (UINT) tick - g_UncompressTicked;
  1523. if (delta) {
  1524. IsmTickProgressBar (g_UncompressSlice, delta);
  1525. g_UncompressTicked += delta;
  1526. }
  1527. if (ExtractFile) {
  1528. *ExtractFile = TRUE;
  1529. }
  1530. return (!IsmCheckCancel());
  1531. }
  1532. BOOL
  1533. pUnpackAllFiles (
  1534. VOID
  1535. )
  1536. {
  1537. COMPRESS_HANDLE compressedHandle;
  1538. BOOL result = FALSE;
  1539. if (CompressOpenHandle (g_RmvMedTempPath, S_TRANSPORT_IMG_FILE, 1, &compressedHandle)) {
  1540. g_TotalFiles = compressedHandle.FilesStored;
  1541. if (CompressExtractAllFiles (g_RmvMedTempPath, &compressedHandle, pRmvMedCallback)) {
  1542. result = TRUE;
  1543. }
  1544. CompressCleanupHandle (&compressedHandle);
  1545. }
  1546. return result;
  1547. }
  1548. BOOL
  1549. WINAPI
  1550. RmvMedTransportBeginApply (
  1551. VOID
  1552. )
  1553. {
  1554. MIG_APPINFO appInfo;
  1555. ERRUSER_EXTRADATA extraData;
  1556. PCTSTR imageFile = NULL;
  1557. PCTSTR newImageFile = NULL;
  1558. BOOL result = FALSE;
  1559. g_RmvMedPlatform = PLATFORM_DESTINATION;
  1560. ZeroMemory (&extraData, sizeof (ERRUSER_EXTRADATA));
  1561. extraData.Error = ERRUSER_ERROR_UNKNOWN;
  1562. __try {
  1563. g_RmvMedTempPath = pCreateTemporaryDir ();
  1564. if (!g_RmvMedTempPath) {
  1565. extraData.Error = ERRUSER_ERROR_CANTCREATETEMPDIR;
  1566. __leave;
  1567. }
  1568. if (!pReadAllImages ()) {
  1569. if (GetLastError () == ERROR_DISK_FULL) {
  1570. extraData.Error = ERRUSER_ERROR_DISKSPACE;
  1571. } else {
  1572. extraData.Error = ERRUSER_ERROR_CANTREADIMAGE;
  1573. }
  1574. __leave;
  1575. }
  1576. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  1577. appInfo.Phase = MIG_TRANSPORT_PHASE;
  1578. appInfo.SubPhase = SUBPHASE_UNCOMPRESSING;
  1579. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  1580. if (!pUnpackAllFiles ()) {
  1581. extraData.Error = ERRUSER_ERROR_CANTUNPACKIMAGE;
  1582. __leave;
  1583. }
  1584. newImageFile = pRmvMedGetNewFileName (S_TRANSPORT_DAT_FILE);
  1585. imageFile = JoinPaths (g_RmvMedTempPath, newImageFile?newImageFile:S_TRANSPORT_DAT_FILE);
  1586. if (newImageFile) {
  1587. FreePathString (newImageFile);
  1588. newImageFile = NULL;
  1589. }
  1590. if (!MemDbLoad (imageFile)) {
  1591. extraData.Error = ERRUSER_ERROR_CANTREADIMAGE;
  1592. __leave;
  1593. }
  1594. result = TRUE;
  1595. }
  1596. __finally {
  1597. if (imageFile) {
  1598. FreePathString (imageFile);
  1599. imageFile = NULL;
  1600. }
  1601. }
  1602. if (!result) {
  1603. extraData.ErrorArea = ERRUSER_AREA_LOAD;
  1604. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1605. }
  1606. return result;
  1607. }
  1608. VOID
  1609. WINAPI
  1610. RmvMedTransportEndApply (
  1611. VOID
  1612. )
  1613. {
  1614. MYASSERT (g_RmvMedPlatform == PLATFORM_DESTINATION);
  1615. pCleanupTempDir ();
  1616. }
  1617. BOOL
  1618. WINAPI
  1619. RmvMedTransportAcquireObject (
  1620. IN MIG_OBJECTTYPEID ObjectTypeId,
  1621. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1622. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  1623. IN MIG_CONTENTTYPE ContentType,
  1624. IN UINT MemoryContentLimit
  1625. )
  1626. {
  1627. UINT value;
  1628. PCBYTE memValue;
  1629. UINT memValueSize;
  1630. PCTSTR fileValue = NULL;
  1631. PCTSTR newFileValue = NULL;
  1632. BOOL valueInFile;
  1633. KEYHANDLE keyHandle;
  1634. PALLOCSTATE allocState;
  1635. PCTSTR detailsKey = NULL;
  1636. PBYTE details;
  1637. UINT detailsSize;
  1638. PCTSTR sourceFile;
  1639. PCTSTR decoratedObject = NULL;
  1640. HANDLE fileHandle;
  1641. BOOL result = FALSE;
  1642. if (!ObjectContent) {
  1643. return FALSE;
  1644. }
  1645. MYASSERT (g_RmvMedPlatform == PLATFORM_DESTINATION);
  1646. MYASSERT ((ObjectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE);
  1647. decoratedObject = pBuildDecoratedObject (ObjectTypeId, ObjectName);
  1648. allocState = (PALLOCSTATE) MemAllocZeroed (sizeof (ALLOCSTATE));
  1649. if (MemDbGetValue (decoratedObject, &value)) {
  1650. if (value == TRFLAG_FILE) {
  1651. valueInFile = TRUE;
  1652. keyHandle = MemDbGetSingleLinkage (decoratedObject, 0, 0);
  1653. if (keyHandle) {
  1654. fileValue = MemDbGetKeyFromHandle (keyHandle, 0);
  1655. newFileValue = pRmvMedGetNewFileName (fileValue);
  1656. result = fileValue != NULL;
  1657. } else {
  1658. fileValue = NULL;
  1659. result = TRUE;
  1660. }
  1661. } else if (value == TRFLAG_MEMORY) {
  1662. valueInFile = FALSE;
  1663. memValueSize = 0;
  1664. memValue = MemDbGetUnorderedBlob (decoratedObject, 0, &memValueSize);
  1665. result = TRUE;
  1666. } else {
  1667. LOG ((LOG_ERROR, (PCSTR) MSG_UNSUPPORTED_DATA, value));
  1668. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  1669. }
  1670. if (result) {
  1671. result = FALSE;
  1672. if (valueInFile) {
  1673. if ((ContentType == CONTENTTYPE_ANY) ||
  1674. (ContentType == CONTENTTYPE_FILE) ||
  1675. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  1676. ) {
  1677. // this is stored as a file and it's wanted as a file
  1678. ObjectContent->ObjectTypeId = ObjectTypeId;
  1679. ObjectContent->ContentInFile = TRUE;
  1680. if (fileValue) {
  1681. ObjectContent->FileContent.ContentPath = JoinPaths (g_RmvMedTempPath, newFileValue?newFileValue:fileValue);
  1682. ObjectContent->FileContent.ContentSize = BfGetFileSize (ObjectContent->FileContent.ContentPath);
  1683. } else {
  1684. ObjectContent->FileContent.ContentSize = 0;
  1685. ObjectContent->FileContent.ContentPath = NULL;
  1686. }
  1687. result = TRUE;
  1688. } else {
  1689. // this is stored as a file and it's wanted as memory
  1690. ObjectContent->ObjectTypeId = ObjectTypeId;
  1691. ObjectContent->ContentInFile = FALSE;
  1692. if (fileValue) {
  1693. sourceFile = JoinPaths (g_RmvMedTempPath, newFileValue?newFileValue:fileValue);
  1694. ObjectContent->MemoryContent.ContentSize = (UINT) BfGetFileSize (sourceFile);
  1695. ObjectContent->MemoryContent.ContentBytes = MapFileIntoMemory (
  1696. sourceFile,
  1697. &allocState->FileHandle,
  1698. &allocState->MapHandle
  1699. );
  1700. FreePathString (sourceFile);
  1701. result = (ObjectContent->MemoryContent.ContentBytes != NULL);
  1702. } else {
  1703. ObjectContent->MemoryContent.ContentSize = 0;
  1704. ObjectContent->MemoryContent.ContentBytes = NULL;
  1705. result = TRUE;
  1706. }
  1707. }
  1708. if (newFileValue) {
  1709. FreePathString (newFileValue);
  1710. newFileValue = NULL;
  1711. }
  1712. if (fileValue) {
  1713. MemDbReleaseMemory (fileValue);
  1714. fileValue = NULL;
  1715. }
  1716. } else {
  1717. if ((ContentType == CONTENTTYPE_ANY) ||
  1718. (ContentType == CONTENTTYPE_MEMORY) ||
  1719. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  1720. ) {
  1721. // this is stored as memory and it's wanted as memory
  1722. ObjectContent->ObjectTypeId = ObjectTypeId;
  1723. ObjectContent->ContentInFile = FALSE;
  1724. ObjectContent->MemoryContent.ContentSize = memValueSize;
  1725. ObjectContent->MemoryContent.ContentBytes = memValue;
  1726. result = TRUE;
  1727. } else {
  1728. // this is stored as memory and it's wanted as a file
  1729. if (memValue) {
  1730. if (IsmGetTempFile (allocState->TempFile, ARRAYSIZE(allocState->TempFile))) {
  1731. fileHandle = BfCreateFile (allocState->TempFile);
  1732. if (fileHandle) {
  1733. if (BfWriteFile (fileHandle, memValue, memValueSize)) {
  1734. ObjectContent->ObjectTypeId = ObjectTypeId;
  1735. ObjectContent->ContentInFile = TRUE;
  1736. ObjectContent->FileContent.ContentSize = memValueSize;
  1737. ObjectContent->FileContent.ContentPath = DuplicatePathString (allocState->TempFile, 0);
  1738. result = TRUE;
  1739. }
  1740. CloseHandle (fileHandle);
  1741. }
  1742. }
  1743. MemDbReleaseMemory (memValue);
  1744. } else {
  1745. ObjectContent->ObjectTypeId = ObjectTypeId;
  1746. ObjectContent->ContentInFile = TRUE;
  1747. ObjectContent->FileContent.ContentSize = 0;
  1748. ObjectContent->FileContent.ContentPath = NULL;
  1749. }
  1750. }
  1751. }
  1752. }
  1753. } else {
  1754. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  1755. }
  1756. if (result) {
  1757. //
  1758. // Fill the details
  1759. //
  1760. detailsKey = JoinText (S_DETAILS_PREFIX, decoratedObject);
  1761. details = MemDbGetUnorderedBlob (detailsKey, 0, &detailsSize);
  1762. if (!details) {
  1763. detailsSize = 0;
  1764. }
  1765. allocState->DetailsPtr = details;
  1766. ObjectContent->Details.DetailsSize = detailsSize;
  1767. ObjectContent->Details.DetailsData = details;
  1768. FreeText (detailsKey);
  1769. ObjectContent->TransHandle = allocState;
  1770. }
  1771. if (!result) {
  1772. FreeAlloc (allocState);
  1773. }
  1774. FreePathString (decoratedObject);
  1775. return result;
  1776. }
  1777. BOOL
  1778. WINAPI
  1779. RmvMedTransportReleaseObject (
  1780. IN OUT PMIG_CONTENT ObjectContent
  1781. )
  1782. {
  1783. PALLOCSTATE allocState;
  1784. MYASSERT (g_RmvMedPlatform == PLATFORM_DESTINATION);
  1785. allocState = (PALLOCSTATE) ObjectContent->TransHandle;
  1786. if (ObjectContent->ContentInFile) {
  1787. FreePathString (ObjectContent->FileContent.ContentPath);
  1788. if (allocState && allocState->TempFile[0]) {
  1789. DeleteFile (allocState->TempFile);
  1790. }
  1791. } else {
  1792. if (allocState && allocState->FileHandle && allocState->MapHandle) {
  1793. UnmapFile (
  1794. ObjectContent->MemoryContent.ContentBytes,
  1795. allocState->MapHandle,
  1796. allocState->FileHandle
  1797. );
  1798. } else {
  1799. MemDbReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1800. }
  1801. }
  1802. if (allocState && allocState->DetailsPtr) {
  1803. MemDbReleaseMemory (allocState->DetailsPtr);
  1804. }
  1805. FreeAlloc (allocState);
  1806. return TRUE;
  1807. }