Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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