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.

1708 lines
56 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. opaque.c
  5. Abstract:
  6. Implements a basic secure server transport module
  7. Author:
  8. Jim Schmidt (jimschm) 08-Mar-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_OPAQUE "OpaqueUnc"
  19. //
  20. // Strings
  21. //
  22. #define S_TRANSPORT_DIR TEXT("USMT2.UNC")
  23. #define S_TRANSPORT_DAT_FILE TEXT("TRANSDB.DAT")
  24. #define S_TRANSPORT_IMG_FILE TEXT("IMG%05X.DAT")
  25. #define S_TRANSPORT_STATUS_FILE TEXT("status")
  26. #define S_FILEOBJECT_NAME TEXT("File")
  27. #define S_REGOBJECT_NAME TEXT("Registry")
  28. #define S_DATABASEOBJECT_NAME TEXT("Database")
  29. #define S_DETAILS_PREFIX TEXT("details-")
  30. //
  31. // Constants
  32. //
  33. #define TRFLAG_FILE 0x01
  34. #define TRFLAG_MEMORY 0x02
  35. #define COPY_BUFFER_SIZE 32768
  36. #define OPAQUETR_OLDSIG1 0x55534D31 //USM1
  37. #define OPAQUETR_OLDSIG2 0x55534D32 //USM2
  38. #define OPAQUETR_OLDSIG3 0x55534D33 //USM3
  39. #define OPAQUETR_CONVSIG 0x55534D33 //USM3
  40. #define OPAQUETR_SIG 0x55534D34 //USM4
  41. #define TRSTATUS_DIRTY 0x00000001
  42. #define TRSTATUS_READY 0x00000002
  43. #define TRSTATUS_LOCKED 0x00000003
  44. //
  45. // Macros
  46. //
  47. // None
  48. //
  49. // Types
  50. //
  51. typedef struct {
  52. TCHAR TempFile [MAX_PATH];
  53. PCVOID AllocPtr;
  54. PCVOID DetailsPtr;
  55. HANDLE FileHandle;
  56. HANDLE MapHandle;
  57. } ALLOCSTATE, *PALLOCSTATE;
  58. //
  59. // Globals
  60. //
  61. MIG_TRANSPORTSTORAGEID g_ReliableStorageId;
  62. PCTSTR g_TransportPath = NULL;
  63. PCTSTR g_TransportTempPath = NULL;
  64. PCTSTR g_TransportStatus = NULL;
  65. HANDLE g_TransportStatusHandle = NULL;
  66. BOOL g_OtCompressData = FALSE;
  67. BOOL g_OtOldFormat = FALSE;
  68. UINT g_Platform;
  69. MIG_PROGRESSSLICEID g_PersistentSlice;
  70. MIG_PROGRESSSLICEID g_DatabaseSlice;
  71. UINT g_CompressedTicks;
  72. UINT g_CompressedTicked;
  73. MIG_PROGRESSSLICEID g_CompressedSlice;
  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. BOOL
  87. pOtSaveAllState (
  88. IN BOOL Compressed
  89. );
  90. //
  91. // Macro expansion definition
  92. //
  93. // None
  94. //
  95. // Code
  96. //
  97. BOOL
  98. pSetOpaqueTransportStatus (
  99. IN HANDLE TrJournalHandle,
  100. IN BOOL Compressed,
  101. IN DWORD Status
  102. )
  103. {
  104. DWORD signature = OPAQUETR_SIG;
  105. BOOL result = FALSE;
  106. if (BfSetFilePointer (TrJournalHandle, 0)) {
  107. result = TRUE;
  108. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&signature), sizeof (DWORD));
  109. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&Compressed), sizeof (BOOL));
  110. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&Status), sizeof (DWORD));
  111. result = result && FlushFileBuffers (TrJournalHandle);
  112. }
  113. return result;
  114. }
  115. DWORD
  116. pGetOpaqueTransportStatus (
  117. IN PCTSTR TrJournal,
  118. OUT PBOOL Compressed, OPTIONAL
  119. OUT PBOOL OldStorage, OPTIONAL
  120. IN BOOL OpenReadOnly
  121. )
  122. {
  123. HANDLE trJrnHandle;
  124. BOOL compressed = FALSE;
  125. DWORD signature = 0;
  126. DWORD fileSize = 0;
  127. DWORD error;
  128. DWORD result = 0;
  129. if (OldStorage) {
  130. *OldStorage = FALSE;
  131. }
  132. if (TrJournal && TrJournal [0]) {
  133. if (OpenReadOnly) {
  134. trJrnHandle = BfOpenReadFile (TrJournal);
  135. } else {
  136. trJrnHandle = BfOpenFile (TrJournal);
  137. }
  138. if (trJrnHandle) {
  139. if (BfSetFilePointer (trJrnHandle, 0)) {
  140. fileSize = GetFileSize (trJrnHandle, NULL);
  141. if (fileSize == (sizeof (BOOL) + sizeof (DWORD))) {
  142. if (OldStorage) {
  143. *OldStorage = TRUE;
  144. }
  145. if (BfReadFile (trJrnHandle, (PBYTE)(&compressed), sizeof (BOOL))) {
  146. BfReadFile (trJrnHandle, (PBYTE)(&result), sizeof (DWORD));
  147. }
  148. }
  149. if (fileSize == (sizeof (BOOL) + sizeof (DWORD) + sizeof (DWORD))) {
  150. if (BfReadFile (trJrnHandle, (PBYTE)(&signature), sizeof (DWORD))) {
  151. if (signature == OPAQUETR_SIG) {
  152. if (BfReadFile (trJrnHandle, (PBYTE)(&compressed), sizeof (BOOL))) {
  153. BfReadFile (trJrnHandle, (PBYTE)(&result), sizeof (DWORD));
  154. }
  155. }
  156. if ((signature == OPAQUETR_OLDSIG1) ||
  157. (signature == OPAQUETR_OLDSIG2) ||
  158. (signature == OPAQUETR_OLDSIG3)
  159. ) {
  160. if (OldStorage) {
  161. *OldStorage = TRUE;
  162. }
  163. if (BfReadFile (trJrnHandle, (PBYTE)(&compressed), sizeof (BOOL))) {
  164. BfReadFile (trJrnHandle, (PBYTE)(&result), sizeof (DWORD));
  165. }
  166. }
  167. }
  168. }
  169. }
  170. CloseHandle (trJrnHandle);
  171. } else {
  172. error = GetLastError ();
  173. if ((error == ERROR_ACCESS_DENIED) ||
  174. (error == ERROR_SHARING_VIOLATION)
  175. ) {
  176. result = TRSTATUS_LOCKED;
  177. }
  178. }
  179. }
  180. if (Compressed) {
  181. *Compressed = compressed;
  182. }
  183. return result;
  184. }
  185. PCTSTR
  186. pGetOpaqueImageFile (
  187. IN PCTSTR BasePath,
  188. IN UINT ImageIdx
  189. )
  190. {
  191. TCHAR imageFileName [13];
  192. PCTSTR imageFile = NULL;
  193. HANDLE imageFileHandle = NULL;
  194. wsprintf (imageFileName, S_TRANSPORT_IMG_FILE, ImageIdx);
  195. return JoinPaths (BasePath, imageFileName);
  196. }
  197. PCTSTR
  198. pGetRealTransportPath (
  199. VOID
  200. )
  201. {
  202. return g_OtCompressData?g_TransportTempPath:g_TransportPath;
  203. }
  204. BOOL
  205. WINAPI
  206. OpaqueTransportInitialize (
  207. IN PMIG_LOGCALLBACK LogCallback
  208. )
  209. {
  210. //
  211. // Initialize globals
  212. //
  213. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  214. g_ReliableStorageId = IsmRegisterTransport (S_RELIABLE_STORAGE_TRANSPORT);
  215. return TRUE;
  216. }
  217. VOID
  218. WINAPI
  219. OpaqueTransportEstimateProgressBar (
  220. MIG_PLATFORMTYPEID PlatformTypeId
  221. )
  222. {
  223. UINT ticks;
  224. PMIG_OBJECTCOUNT objectCount;
  225. if (PlatformTypeId == PLATFORM_SOURCE) {
  226. //
  227. // If saving, we know the number of ticks based on the count of the
  228. // persistent attribute.
  229. //
  230. objectCount = IsmGetObjectsStatistics (PLATFORM_SOURCE);
  231. if (objectCount) {
  232. ticks = objectCount->PersistentObjects;
  233. } else {
  234. ticks = 0;
  235. }
  236. g_PersistentSlice = IsmRegisterProgressSlice (ticks, max (1, ticks / 5));
  237. if (g_OtCompressData) {
  238. g_DatabaseSlice = IsmRegisterProgressSlice (3, 1);
  239. } else {
  240. g_DatabaseSlice = IsmRegisterProgressSlice (1, 1);
  241. }
  242. } else {
  243. if (g_OtCompressData) {
  244. g_UncompressTicked = 0;
  245. g_UncompressTicks = 1000;
  246. g_UncompressSlice = IsmRegisterProgressSlice (g_UncompressTicks, 180);
  247. } else {
  248. //
  249. // If restoring, we have almost no work to account for, since
  250. // we download from the secure server file-by-file.
  251. //
  252. DEBUGMSG ((DBG_VERBOSE, "Assuming transport download has no progress impact"));
  253. }
  254. }
  255. }
  256. BOOL
  257. WINAPI
  258. OpaqueTransportQueryCapabilities (
  259. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  260. OUT PMIG_TRANSPORTTYPE TransportType,
  261. OUT PMIG_TRANSPORTCAPABILITIES Capabilities,
  262. OUT PCTSTR *FriendlyDescription
  263. )
  264. {
  265. if (TransportStorageId != g_ReliableStorageId) {
  266. return FALSE;
  267. }
  268. *TransportType = TRANSPORTTYPE_FULL;
  269. *Capabilities = CAPABILITY_COMPRESSED;
  270. *FriendlyDescription = TEXT("Local computer or another computer on the Network");
  271. return TRUE;
  272. }
  273. VOID
  274. pOtCleanUpTempDir (
  275. VOID
  276. )
  277. {
  278. if (g_TransportTempPath) {
  279. FiRemoveAllFilesInTree (g_TransportTempPath);
  280. }
  281. }
  282. PCTSTR
  283. pOtCreateTemporaryDir (
  284. VOID
  285. )
  286. {
  287. TCHAR tempFile[MAX_PATH];
  288. if (!IsmGetTempDirectory (tempFile, ARRAYSIZE(tempFile))) {
  289. return NULL;
  290. }
  291. return DuplicatePathString (tempFile, 0);
  292. }
  293. BOOL
  294. WINAPI
  295. OpaqueTransportSetStorage (
  296. IN MIG_PLATFORMTYPEID Platform,
  297. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  298. IN MIG_TRANSPORTCAPABILITIES RequiredCapabilities,
  299. IN PCTSTR StoragePath,
  300. OUT PBOOL Valid,
  301. OUT PBOOL ImageExists
  302. )
  303. {
  304. PCTSTR lastDirPtr = NULL;
  305. PCTSTR transportPath = NULL;
  306. PCTSTR transportStatus = NULL;
  307. HANDLE transportStatusHandle = INVALID_HANDLE_VALUE;
  308. MIG_OBJECTSTRINGHANDLE encodedPath;
  309. DWORD status;
  310. BOOL result = FALSE;
  311. if (Valid) {
  312. *Valid = FALSE;
  313. }
  314. if (ImageExists) {
  315. *ImageExists = FALSE;
  316. }
  317. if (TransportStorageId == g_ReliableStorageId) {
  318. if ((!RequiredCapabilities) || (RequiredCapabilities == CAPABILITY_COMPRESSED)) {
  319. if (RequiredCapabilities == CAPABILITY_COMPRESSED) {
  320. g_OtCompressData = TRUE;
  321. } else {
  322. g_OtCompressData = FALSE;
  323. }
  324. // If this is the destination, let's check if the user included USMT2.UNC in
  325. // the path by mistake. If he did (the StoragePath ends in USMT2.UNC and
  326. // StoragePath has our transport status) we will accept it.
  327. if (Platform == PLATFORM_DESTINATION) {
  328. lastDirPtr = _tcsrchr (StoragePath, TEXT('\\'));
  329. if (lastDirPtr) {
  330. lastDirPtr = _tcsinc (lastDirPtr);
  331. if (lastDirPtr) {
  332. if (StringIMatch (lastDirPtr, S_TRANSPORT_DIR)) {
  333. transportPath = DuplicatePathString (StoragePath, 0);
  334. transportStatus = JoinPaths (transportPath, S_TRANSPORT_STATUS_FILE);
  335. if ((!DoesFileExist (transportPath)) ||
  336. (pGetOpaqueTransportStatus (transportStatus, NULL, NULL, TRUE) != TRSTATUS_READY)
  337. ) {
  338. FreePathString (transportPath);
  339. transportPath = NULL;
  340. FreePathString (transportStatus);
  341. transportStatus = NULL;
  342. }
  343. }
  344. }
  345. }
  346. }
  347. if (!transportPath) {
  348. transportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
  349. }
  350. if (!transportStatus) {
  351. transportStatus = JoinPaths (transportPath, S_TRANSPORT_STATUS_FILE);
  352. }
  353. if (!DoesFileExist (transportPath)) {
  354. // we require UNC path or a full path (like c:\...)
  355. if (transportPath[0] == '\\' && transportPath[1] == '\\') {
  356. // this is a UNC path
  357. *Valid = TRUE;
  358. } else if (transportPath[1] == ':') {
  359. // this is a normal full path
  360. *Valid = TRUE;
  361. } else {
  362. *Valid = FALSE;
  363. }
  364. if ((*Valid) && (Platform == PLATFORM_SOURCE)) {
  365. // we need to actually try to create our transport directory and the status file
  366. // After that we will remove them but this is just the way for us to validate the
  367. // store
  368. *Valid = FALSE;
  369. if (BfCreateDirectory (transportPath)) {
  370. transportStatusHandle = BfCreateFile (transportStatus);
  371. if (transportStatusHandle) {
  372. *Valid = TRUE;
  373. CloseHandle (transportStatusHandle);
  374. }
  375. PushError ();
  376. FiRemoveAllFilesInTree (transportPath);
  377. PopError ();
  378. }
  379. }
  380. *ImageExists = FALSE;
  381. } else {
  382. // we try to open this transport status file with Read/Write. If we
  383. // fail this is either because somebody has it opened or we don't
  384. // have access rights. In both cases we should get back TRSTATUS_LOCKED
  385. status = pGetOpaqueTransportStatus (transportStatus, NULL, NULL, TRUE);
  386. switch (status) {
  387. case TRSTATUS_LOCKED:
  388. *ImageExists = TRUE;
  389. *Valid = FALSE;
  390. break;
  391. case TRSTATUS_READY:
  392. *ImageExists = TRUE;
  393. *Valid = TRUE;
  394. break;
  395. case TRSTATUS_DIRTY:
  396. *ImageExists = FALSE;
  397. *Valid = TRUE;
  398. break;
  399. default:
  400. *ImageExists = FALSE;
  401. *Valid = TRUE;
  402. }
  403. }
  404. result = TRUE;
  405. }
  406. }
  407. if (result && *Valid) {
  408. if (g_TransportPath) {
  409. FreePathString (g_TransportPath);
  410. g_TransportPath = NULL;
  411. }
  412. if (g_TransportStatus) {
  413. FreePathString (g_TransportStatus);
  414. g_TransportStatus = NULL;
  415. }
  416. if (transportPath) {
  417. g_TransportPath = transportPath;
  418. } else {
  419. g_TransportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
  420. }
  421. if (transportStatus) {
  422. g_TransportStatus = transportStatus;
  423. } else {
  424. g_TransportStatus = JoinPaths (g_TransportPath, S_TRANSPORT_STATUS_FILE);
  425. }
  426. encodedPath = IsmCreateSimpleObjectPattern (g_TransportPath, FALSE, NULL, FALSE);
  427. if (encodedPath) {
  428. IsmRegisterStaticExclusion (MIG_FILE_TYPE, encodedPath);
  429. IsmDestroyObjectHandle (encodedPath);
  430. }
  431. }
  432. return result;
  433. }
  434. BOOL
  435. WINAPI
  436. OpaqueTransportSaveState (
  437. VOID
  438. )
  439. {
  440. MIG_APPINFO appInfo;
  441. ERRUSER_EXTRADATA extraData;
  442. DWORD status;
  443. BOOL result = FALSE;
  444. BOOL allowDelete = FALSE;
  445. ZeroMemory (&extraData, sizeof (ERRUSER_EXTRADATA));
  446. extraData.Error = ERRUSER_ERROR_UNKNOWN;
  447. __try {
  448. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  449. appInfo.Phase = MIG_TRANSPORT_PHASE;
  450. appInfo.SubPhase = SUBPHASE_PREPARING;
  451. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  452. if (!g_TransportPath) {
  453. DEBUGMSG ((DBG_ERROR, "Transport Path is not selected"));
  454. extraData.Error = ERRUSER_ERROR_NOTRANSPORTPATH;
  455. __leave;
  456. }
  457. if (DoesFileExist (g_TransportPath)) {
  458. status = pGetOpaqueTransportStatus (g_TransportStatus, NULL, NULL, FALSE);
  459. switch (status) {
  460. case TRSTATUS_LOCKED:
  461. SetLastError (ERROR_ACCESS_DENIED);
  462. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, g_TransportPath));
  463. extraData.Error = ERRUSER_ERROR_TRANSPORTPATHBUSY;
  464. __leave;
  465. case TRSTATUS_DIRTY:
  466. result = FiRemoveAllFilesInTree (g_TransportPath);
  467. if (!result) {
  468. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_EMPTY_DIR, g_TransportPath));
  469. extraData.Error = ERRUSER_ERROR_CANTEMPTYDIR;
  470. __leave;
  471. }
  472. break;
  473. case TRSTATUS_READY:
  474. default:
  475. if (IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_EXISTS, 0)) {
  476. if (!FiRemoveAllFilesInTree (g_TransportPath)) {
  477. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_EMPTY_DIR, g_TransportPath));
  478. extraData.Error = ERRUSER_ERROR_CANTEMPTYDIR;
  479. __leave;
  480. }
  481. } else {
  482. LOG ((LOG_ERROR, (PCSTR) MSG_NOT_EMPTY, g_TransportPath));
  483. SetLastError (ERROR_ALREADY_EXISTS);
  484. extraData.Error = ERRUSER_ERROR_ALREADYEXISTS;
  485. __leave;
  486. }
  487. break;
  488. }
  489. }
  490. allowDelete = TRUE;
  491. if (!BfCreateDirectory (g_TransportPath)) {
  492. PushError ();
  493. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_DIR, g_TransportPath));
  494. PopError ();
  495. extraData.Error = ERRUSER_ERROR_CANTCREATEDIR;
  496. __leave;
  497. }
  498. g_TransportStatusHandle = BfCreateFile (g_TransportStatus);
  499. if (!g_TransportStatusHandle) {
  500. PushError ();
  501. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_STATUS_FILE, g_TransportStatus));
  502. PopError ();
  503. extraData.Error = ERRUSER_ERROR_CANTCREATESTATUS;
  504. __leave;
  505. }
  506. result = pSetOpaqueTransportStatus (g_TransportStatusHandle, g_OtCompressData, TRSTATUS_DIRTY);
  507. if (!result) {
  508. PushError ();
  509. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_STATUS_FILE, g_TransportStatus));
  510. PopError ();
  511. extraData.Error = ERRUSER_ERROR_CANTCREATESTATUS;
  512. __leave;
  513. }
  514. g_Platform = PLATFORM_SOURCE;
  515. result = pOtSaveAllState (g_OtCompressData);
  516. if (result) {
  517. result = result && pSetOpaqueTransportStatus (g_TransportStatusHandle, g_OtCompressData, TRSTATUS_READY);
  518. }
  519. result = result && FlushFileBuffers (g_TransportStatusHandle);
  520. result = result && CloseHandle (g_TransportStatusHandle);
  521. if (result) {
  522. g_TransportStatusHandle = NULL;
  523. }
  524. }
  525. __finally {
  526. PushError ();
  527. if (g_TransportStatusHandle) {
  528. // if we got here there was some error. Let's just close the handle
  529. CloseHandle (g_TransportStatusHandle);
  530. }
  531. if (allowDelete && (!result)) {
  532. FiRemoveAllFilesInTree (g_TransportPath);
  533. }
  534. PopError ();
  535. }
  536. PushError ();
  537. if (!result) {
  538. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  539. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  540. }
  541. PopError ();
  542. return result;
  543. }
  544. PCTSTR
  545. pOpaqueGetNewFileName (
  546. IN PCTSTR FileName
  547. )
  548. {
  549. PCTSTR newFileName = NULL;
  550. PTSTR tempPtr1 = NULL;
  551. PCTSTR endStr1 = NULL;
  552. PCTSTR tempPtr2 = NULL;
  553. PCTSTR endStr2 = NULL;
  554. INT i;
  555. // let's modify the file to extract. The file name will
  556. // be split in 2 after the first 5 characters
  557. newFileName = DuplicatePathString (FileName, 1);
  558. if (!newFileName) {
  559. return NULL;
  560. }
  561. tempPtr1 = (PTSTR) GetFileNameFromPath (newFileName);
  562. if (!tempPtr1) {
  563. FreePathString (newFileName);
  564. return NULL;
  565. }
  566. endStr1 = GetEndOfString (newFileName);
  567. if (!endStr1) {
  568. FreePathString (newFileName);
  569. return NULL;
  570. }
  571. tempPtr2 = GetFileNameFromPath (FileName);
  572. if (!tempPtr2) {
  573. FreePathString (newFileName);
  574. return NULL;
  575. }
  576. endStr2 = GetEndOfString (FileName);
  577. if (!endStr2) {
  578. FreePathString (newFileName);
  579. return NULL;
  580. }
  581. for (i = 0; i < 5; i ++) {
  582. tempPtr1 = _tcsinc (tempPtr1);
  583. tempPtr2 = _tcsinc (tempPtr2);
  584. }
  585. if ((tempPtr1 < endStr1) &&
  586. (tempPtr2 < endStr2)
  587. ) {
  588. StringCopy (tempPtr1, TEXT("\\"));
  589. tempPtr1 = _tcsinc (tempPtr1);
  590. StringCopy (tempPtr1, tempPtr2);
  591. } else {
  592. FreePathString (newFileName);
  593. newFileName = NULL;
  594. }
  595. return newFileName;
  596. }
  597. BOOL
  598. pOpaqueCallback (
  599. IN PCTSTR FileToExtract,
  600. IN LONGLONG FileSize,
  601. OUT PBOOL ExtractFile,
  602. IN OUT PCTSTR *NewFileName
  603. )
  604. {
  605. LONGLONG numerator;
  606. LONGLONG divisor;
  607. LONGLONG tick;
  608. UINT delta;
  609. if (NewFileName) {
  610. *NewFileName = pOpaqueGetNewFileName (FileToExtract);
  611. }
  612. g_FilesRead ++;
  613. // now update the progress bar
  614. numerator = (LONGLONG) g_FilesRead * (LONGLONG) g_UncompressTicks;
  615. divisor = (LONGLONG) g_TotalFiles;
  616. if (divisor) {
  617. tick = numerator / divisor;
  618. } else {
  619. tick = 0;
  620. }
  621. delta = (UINT) tick - g_UncompressTicked;
  622. if (delta) {
  623. IsmTickProgressBar (g_UncompressSlice, delta);
  624. g_UncompressTicked += delta;
  625. }
  626. if (ExtractFile) {
  627. *ExtractFile = TRUE;
  628. }
  629. return (!IsmCheckCancel());
  630. }
  631. BOOL
  632. pOtReadAllImages (
  633. VOID
  634. )
  635. {
  636. COMPRESS_HANDLE compressedHandle;
  637. BOOL result = FALSE;
  638. if (CompressOpenHandle (g_TransportPath, S_TRANSPORT_IMG_FILE, 1, &compressedHandle)) {
  639. g_TotalFiles = compressedHandle.FilesStored;
  640. if (CompressExtractAllFiles (g_TransportTempPath, &compressedHandle, pOpaqueCallback)) {
  641. result = TRUE;
  642. }
  643. CompressCleanupHandle (&compressedHandle);
  644. }
  645. return result;
  646. }
  647. BOOL
  648. WINAPI
  649. OpaqueTransportBeginApply (
  650. VOID
  651. )
  652. {
  653. ERRUSER_EXTRADATA extraData;
  654. DWORD status = 0;
  655. PCTSTR memDbFile;
  656. INT_PTR appReply;
  657. PCTSTR newTransDbFile = NULL;
  658. BOOL result = FALSE;
  659. g_Platform = PLATFORM_DESTINATION;
  660. ZeroMemory (&extraData, sizeof (ERRUSER_EXTRADATA));
  661. extraData.Error = ERRUSER_ERROR_UNKNOWN;
  662. __try {
  663. if (!g_TransportPath) {
  664. DEBUGMSG ((DBG_ERROR, "Transport Path is not selected"));
  665. extraData.Error = ERRUSER_ERROR_NOTRANSPORTPATH;
  666. __leave;
  667. }
  668. while (status != TRSTATUS_READY) {
  669. status = pGetOpaqueTransportStatus (g_TransportStatus, &g_OtCompressData, &g_OtOldFormat, TRUE);
  670. switch (status) {
  671. case TRSTATUS_LOCKED:
  672. if (!IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_LOCKED, 0)) {
  673. SetLastError (ERROR_ACCESS_DENIED);
  674. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, g_TransportPath));
  675. extraData.Error = ERRUSER_ERROR_TRANSPORTPATHBUSY;
  676. __leave;
  677. }
  678. break;
  679. case TRSTATUS_DIRTY:
  680. SetLastError (ERROR_INVALID_DATA);
  681. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_TransportPath));
  682. extraData.Error = ERRUSER_ERROR_TRANSPORTINVALIDIMAGE;
  683. __leave;
  684. case TRSTATUS_READY:
  685. break;
  686. default:
  687. SetLastError (ERROR_INVALID_DATA);
  688. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_TransportPath));
  689. extraData.Error = ERRUSER_ERROR_TRANSPORTINVALIDIMAGE;
  690. __leave;
  691. }
  692. }
  693. if (g_OtOldFormat) {
  694. IsmSendMessageToApp (TRANSPORTMESSAGE_OLD_STORAGE, 0);
  695. SetLastError (ERROR_INVALID_DATA);
  696. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_TransportPath));
  697. extraData.Error = ERRUSER_ERROR_TRANSPORTINVALIDIMAGE;
  698. __leave;
  699. }
  700. g_TransportStatusHandle = BfOpenReadFile (g_TransportStatus);
  701. if (!g_TransportStatusHandle) {
  702. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_STATUS_FILE, g_TransportStatus));
  703. extraData.Error = ERRUSER_ERROR_CANTOPENSTATUS;
  704. __leave;
  705. }
  706. if (g_OtCompressData) {
  707. g_TransportTempPath = pOtCreateTemporaryDir ();
  708. if (!g_TransportTempPath) {
  709. CloseHandle (g_TransportStatusHandle);
  710. g_TransportStatusHandle = NULL;
  711. extraData.Error = ERRUSER_ERROR_CANTCREATETEMPDIR;
  712. __leave;
  713. }
  714. if (!pOtReadAllImages ()) {
  715. CloseHandle (g_TransportStatusHandle);
  716. g_TransportStatusHandle = NULL;
  717. extraData.Error = ERRUSER_ERROR_CANTUNPACKIMAGE;
  718. __leave;
  719. }
  720. CloseHandle (g_TransportStatusHandle);
  721. g_TransportStatusHandle = NULL;
  722. }
  723. newTransDbFile = pOpaqueGetNewFileName (S_TRANSPORT_DAT_FILE);
  724. memDbFile = JoinPaths (pGetRealTransportPath (), newTransDbFile?newTransDbFile:S_TRANSPORT_DAT_FILE);
  725. if (newTransDbFile) {
  726. FreePathString (newTransDbFile);
  727. newTransDbFile = NULL;
  728. }
  729. result = MemDbLoad (memDbFile);
  730. if (!result) {
  731. extraData.Error = ERRUSER_ERROR_CANTREADIMAGE;
  732. }
  733. FreePathString (memDbFile);
  734. }
  735. __finally {
  736. }
  737. if (!result) {
  738. extraData.ErrorArea = ERRUSER_AREA_LOAD;
  739. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  740. }
  741. return result;
  742. }
  743. VOID
  744. WINAPI
  745. OpaqueTransportEndApply (
  746. VOID
  747. )
  748. {
  749. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  750. if (g_OtCompressData) {
  751. pOtCleanUpTempDir ();
  752. } else {
  753. CloseHandle (g_TransportStatusHandle);
  754. g_TransportStatusHandle = NULL;
  755. }
  756. }
  757. VOID
  758. WINAPI
  759. OpaqueTransportTerminate (
  760. VOID
  761. )
  762. {
  763. pOtCleanUpTempDir();
  764. if (g_TransportTempPath) {
  765. FreePathString (g_TransportTempPath);
  766. g_TransportTempPath = NULL;
  767. }
  768. if (g_TransportStatus) {
  769. FreePathString (g_TransportStatus);
  770. g_TransportStatus = NULL;
  771. }
  772. if (g_TransportPath) {
  773. FreePathString (g_TransportPath);
  774. g_TransportPath = NULL;
  775. }
  776. }
  777. static
  778. VOID
  779. pGetTempFileName (
  780. OUT PTSTR Buffer
  781. )
  782. {
  783. static fileIndex = 0;
  784. fileIndex ++;
  785. wsprintf (Buffer, TEXT("%08X.DAT"), fileIndex);
  786. }
  787. PCTSTR
  788. pOpaqueAllocStorageFileName (
  789. IN PCTSTR FileName OPTIONAL
  790. )
  791. {
  792. TCHAR buffer[32];
  793. if (FileName) {
  794. StringCopy (buffer, FileName);
  795. } else {
  796. pGetTempFileName (buffer);
  797. }
  798. return JoinPaths (g_TransportPath, buffer);
  799. }
  800. VOID
  801. pFreeStorageFileName (
  802. IN PCTSTR FileName
  803. )
  804. {
  805. FreePathString (FileName);
  806. }
  807. BOOL
  808. pOpaqueSaveDetails (
  809. IN PCTSTR DecoratedObject,
  810. IN PMIG_DETAILS Details
  811. )
  812. {
  813. PCTSTR key;
  814. BOOL b = FALSE;
  815. if ((!Details) || (!Details->DetailsSize)) {
  816. return TRUE;
  817. }
  818. key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
  819. if (key) {
  820. b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
  821. FreeText (key);
  822. }
  823. return b;
  824. }
  825. BOOL
  826. pOtAddFileToImage (
  827. IN PCTSTR FileName,
  828. IN PCTSTR StoredName,
  829. IN OUT PCOMPRESS_HANDLE CompressedHandle
  830. )
  831. {
  832. return CompressAddFileToHandle (FileName, StoredName, CompressedHandle);
  833. }
  834. BOOL
  835. pOtSaveContentInFile (
  836. IN MIG_OBJECTTYPEID ObjectTypeId,
  837. IN PCTSTR EncodedFileName,
  838. IN PCTSTR DecoratedObject,
  839. IN PMIG_CONTENT Content,
  840. IN OUT PCOMPRESS_HANDLE CompressedHandle OPTIONAL
  841. )
  842. {
  843. BOOL result = FALSE;
  844. PCTSTR destPath = NULL;
  845. DWORD attributes = INVALID_ATTRIBUTES;
  846. MYASSERT (Content->ContentInFile);
  847. if (!Content->ContentInFile) {
  848. return FALSE;
  849. }
  850. //
  851. // Use the CopyFile API to move the file from local to storage.
  852. //
  853. __try {
  854. if (Content && (Content->Details.DetailsSize == sizeof (WIN32_FIND_DATAW)) && Content->Details.DetailsData) {
  855. attributes = ((PWIN32_FIND_DATAW)Content->Details.DetailsData)->dwFileAttributes;
  856. }
  857. if ((attributes != INVALID_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
  858. // this must be a directory, let's just write the key
  859. if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
  860. __leave;
  861. }
  862. } else {
  863. //
  864. // Get a temp file, assemble the src path, copy the file
  865. //
  866. destPath = pOpaqueAllocStorageFileName (NULL);
  867. if (!destPath) {
  868. __leave;
  869. }
  870. if (CompressedHandle) {
  871. if (!pOtAddFileToImage (Content->FileContent.ContentPath, GetFileNameFromPath (destPath), CompressedHandle)) {
  872. __leave;
  873. }
  874. } else {
  875. if (!CopyFile (Content->FileContent.ContentPath, destPath, FALSE)) {
  876. __leave;
  877. }
  878. }
  879. //
  880. // Keep track of where the file went
  881. //
  882. if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
  883. __leave;
  884. }
  885. if (!MemDbAddSingleLinkage (DecoratedObject, GetFileNameFromPath (destPath), 0)) {
  886. __leave;
  887. }
  888. }
  889. //
  890. // Save details
  891. //
  892. result = pOpaqueSaveDetails (DecoratedObject, &(Content->Details));
  893. }
  894. __finally {
  895. pFreeStorageFileName (destPath);
  896. INVALID_POINTER (destPath);
  897. }
  898. return result;
  899. }
  900. BOOL
  901. pOtSaveContentInMemory (
  902. IN MIG_OBJECTTYPEID ObjectTypeId,
  903. IN PCTSTR EncodedObjectName,
  904. IN PCTSTR DecoratedObject,
  905. IN PMIG_CONTENT Content
  906. )
  907. {
  908. BOOL result = FALSE;
  909. MYASSERT (!Content->ContentInFile);
  910. if (Content->ContentInFile) {
  911. return FALSE;
  912. }
  913. MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
  914. if (Content->MemoryContent.ContentBytes && Content->MemoryContent.ContentSize) {
  915. MemDbSetUnorderedBlob (
  916. DecoratedObject,
  917. 0,
  918. Content->MemoryContent.ContentBytes,
  919. Content->MemoryContent.ContentSize
  920. );
  921. }
  922. result = pOpaqueSaveDetails (DecoratedObject, &(Content->Details));
  923. return result;
  924. }
  925. PCTSTR
  926. pOpaqueBuildDecoratedObject (
  927. IN MIG_OBJECTTYPEID ObjectTypeId,
  928. IN ENCODEDSTRHANDLE ObjectName
  929. )
  930. {
  931. PCTSTR typeStr;
  932. typeStr = IsmGetObjectTypeName (ObjectTypeId);
  933. if (!typeStr) {
  934. return NULL;
  935. }
  936. return JoinPaths (typeStr, ObjectName);
  937. }
  938. VOID
  939. pOtDestroyDecoratedObject (
  940. IN PCTSTR String
  941. )
  942. {
  943. FreePathString (String);
  944. }
  945. BOOL
  946. pOtSaveAllState (
  947. IN BOOL Compressed
  948. )
  949. {
  950. MIG_APPINFO appInfo;
  951. MIG_CONTENT value;
  952. PMIG_CONTENT convValue;
  953. ULONGLONG size;
  954. MIG_OBJECTWITHATTRIBUTE_ENUM objEnum;
  955. PCTSTR ourDbFile = NULL;
  956. PCTSTR decoratedObject = NULL;
  957. ULONGLONG bytesSaved = 0;
  958. UINT lastTick = GetTickCount();
  959. TCHAR text[64];
  960. UINT fraction;
  961. COMPRESS_HANDLE compressedHandle;
  962. INT_PTR appReply;
  963. BOOL okSave = FALSE;
  964. TRANSCOPY_ERROR transCopyError;
  965. ERRUSER_EXTRADATA extraData;
  966. BOOL result = FALSE;
  967. __try {
  968. ZeroMemory (&compressedHandle, sizeof (COMPRESS_HANDLE));
  969. if (Compressed) {
  970. g_TransportTempPath = pOtCreateTemporaryDir ();
  971. if (!g_TransportTempPath) {
  972. extraData.Error = ERRUSER_ERROR_CANTCREATETEMPDIR;
  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. if (!CompressCreateHandle (g_TransportPath, S_TRANSPORT_IMG_FILE, 1, 0, &compressedHandle)) {
  980. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  981. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  982. extraData.ObjectTypeId = 0;
  983. extraData.ObjectName = NULL;
  984. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  985. __leave;
  986. }
  987. }
  988. //
  989. // Enumerate all objects with "save" attribute
  990. //
  991. if (IsmEnumFirstPersistentObject (&objEnum)) {
  992. do {
  993. //
  994. // For each object to be saved, do the appropriate
  995. // data copy action
  996. //
  997. okSave = FALSE;
  998. while (!okSave) {
  999. if (!IsmAcquireObjectEx (
  1000. objEnum.ObjectTypeId,
  1001. objEnum.ObjectName,
  1002. &value,
  1003. CONTENTTYPE_ANY,
  1004. 0
  1005. )) {
  1006. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  1007. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  1008. transCopyError.Error = GetLastError ();
  1009. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  1010. appReply = APPRESPONSE_IGNORE;
  1011. } else {
  1012. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  1013. if ((appReply == APPRESPONSE_NONE) ||
  1014. (appReply == APPRESPONSE_FAIL)
  1015. ) {
  1016. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  1017. IsmReleaseMemory (transCopyError.ObjectName);
  1018. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1019. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1020. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1021. extraData.ObjectName = objEnum.ObjectName;
  1022. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1023. IsmAbortPersistentObjectEnum (&objEnum);
  1024. __leave;
  1025. }
  1026. }
  1027. if (appReply == APPRESPONSE_IGNORE) {
  1028. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  1029. IsmReleaseMemory (transCopyError.ObjectName);
  1030. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1031. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1032. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1033. extraData.ObjectName = objEnum.ObjectName;
  1034. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  1035. break;
  1036. }
  1037. IsmReleaseMemory (transCopyError.ObjectName);
  1038. continue;
  1039. }
  1040. okSave = TRUE;
  1041. }
  1042. if (okSave) {
  1043. #ifdef UNICODE
  1044. convValue = &value;
  1045. #else
  1046. // now let's convert this object content to UNICODE
  1047. convValue = IsmConvertObjectContentToUnicode (objEnum.ObjectTypeId, objEnum.ObjectName, &value);
  1048. if (!convValue) {
  1049. convValue = &value;
  1050. }
  1051. #endif
  1052. decoratedObject = pOpaqueBuildDecoratedObject (objEnum.ObjectTypeId, objEnum.ObjectName);
  1053. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  1054. appInfo.Phase = MIG_TRANSPORT_PHASE;
  1055. appInfo.SubPhase = SUBPHASE_COMPRESSING;
  1056. appInfo.ObjectTypeId = (objEnum.ObjectTypeId & (~PLATFORM_MASK));
  1057. appInfo.ObjectName = objEnum.ObjectName;
  1058. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  1059. if (convValue->ContentInFile) {
  1060. okSave = FALSE;
  1061. while (!okSave) {
  1062. if (!pOtSaveContentInFile (objEnum.ObjectTypeId, objEnum.ObjectName, decoratedObject, convValue, &compressedHandle)) {
  1063. if (GetLastError () == ERROR_DISK_FULL) {
  1064. // we just failed because we don't have enough space on the destination
  1065. // path. Let's tell that to the user
  1066. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  1067. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1068. extraData.ObjectTypeId = 0;
  1069. extraData.ObjectName = NULL;
  1070. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1071. __leave;
  1072. }
  1073. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  1074. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  1075. transCopyError.Error = GetLastError ();
  1076. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  1077. appReply = APPRESPONSE_IGNORE;
  1078. } else {
  1079. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  1080. if ((appReply == APPRESPONSE_NONE) ||
  1081. (appReply == APPRESPONSE_FAIL)
  1082. ) {
  1083. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  1084. IsmReleaseMemory (transCopyError.ObjectName);
  1085. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1086. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1087. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1088. extraData.ObjectName = objEnum.ObjectName;
  1089. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1090. IsmAbortPersistentObjectEnum (&objEnum);
  1091. __leave;
  1092. }
  1093. }
  1094. if (appReply == APPRESPONSE_IGNORE) {
  1095. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  1096. IsmReleaseMemory (transCopyError.ObjectName);
  1097. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1098. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1099. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1100. extraData.ObjectName = objEnum.ObjectName;
  1101. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  1102. break;
  1103. }
  1104. IsmReleaseMemory (transCopyError.ObjectName);
  1105. continue;
  1106. }
  1107. okSave = TRUE;
  1108. }
  1109. size = convValue->FileContent.ContentSize;
  1110. } else {
  1111. okSave = FALSE;
  1112. while (!okSave) {
  1113. if (!pOtSaveContentInMemory (objEnum.ObjectTypeId, objEnum.ObjectName, decoratedObject, convValue)) {
  1114. if (GetLastError () == ERROR_DISK_FULL) {
  1115. // we just failed because we don't have enough space on the destination
  1116. // path. Let's tell that to the user
  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. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  1125. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  1126. transCopyError.Error = GetLastError ();
  1127. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  1128. appReply = APPRESPONSE_IGNORE;
  1129. } else {
  1130. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  1131. if ((appReply == APPRESPONSE_NONE) ||
  1132. (appReply == APPRESPONSE_FAIL)
  1133. ) {
  1134. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  1135. IsmReleaseMemory (transCopyError.ObjectName);
  1136. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1137. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1138. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1139. extraData.ObjectName = objEnum.ObjectName;
  1140. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1141. IsmAbortPersistentObjectEnum (&objEnum);
  1142. __leave;
  1143. }
  1144. }
  1145. if (appReply == APPRESPONSE_IGNORE) {
  1146. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  1147. IsmReleaseMemory (transCopyError.ObjectName);
  1148. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  1149. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1150. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  1151. extraData.ObjectName = objEnum.ObjectName;
  1152. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  1153. break;
  1154. }
  1155. IsmReleaseMemory (transCopyError.ObjectName);
  1156. continue;
  1157. }
  1158. okSave = TRUE;
  1159. }
  1160. size = convValue->MemoryContent.ContentSize;
  1161. }
  1162. #ifndef UNICODE
  1163. if (convValue != (&value)) {
  1164. IsmFreeConvertedObjectContent (objEnum.ObjectTypeId, convValue);
  1165. }
  1166. #endif
  1167. IsmReleaseObject (&value);
  1168. pOtDestroyDecoratedObject (decoratedObject);
  1169. decoratedObject = NULL;
  1170. }
  1171. IsmTickProgressBar (g_PersistentSlice, 1);
  1172. if (IsmCheckCancel()) {
  1173. __leave;
  1174. }
  1175. //
  1176. // Send bytes saved to app every 3 seconds
  1177. //
  1178. bytesSaved += size;
  1179. if (GetTickCount() - lastTick > 3000) {
  1180. if (bytesSaved < 1048576) {
  1181. wsprintf (text, TEXT("Saved: %u K"), (UINT) (bytesSaved / 1024));
  1182. } else if (bytesSaved < 8388608) {
  1183. fraction = (UINT) (bytesSaved / 10485);
  1184. wsprintf (text, TEXT("Saved: %u.%02u M"), fraction / 100, fraction % 100);
  1185. } else if (bytesSaved < 1073741824) {
  1186. wsprintf (text, TEXT("Saved: %u M"), (UINT) (bytesSaved / 1048576));
  1187. } else {
  1188. fraction = (UINT) (bytesSaved / 10737418);
  1189. wsprintf (text, TEXT("Saved: %u.%02u G"), fraction / 100, fraction % 100);
  1190. }
  1191. IsmSendMessageToApp (TRANSPORTMESSAGE_SIZE_SAVED, (ULONG_PTR) text);
  1192. lastTick = GetTickCount();
  1193. }
  1194. } while (IsmEnumNextPersistentObject (&objEnum));
  1195. }
  1196. if (IsmCheckCancel()) {
  1197. __leave;
  1198. }
  1199. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  1200. appInfo.Phase = MIG_TRANSPORT_PHASE;
  1201. appInfo.SubPhase = SUBPHASE_FINISHING;
  1202. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  1203. if (Compressed) {
  1204. ourDbFile = JoinPaths (g_TransportTempPath, S_TRANSPORT_DAT_FILE);
  1205. } else {
  1206. ourDbFile = pOpaqueAllocStorageFileName (S_TRANSPORT_DAT_FILE);
  1207. if (!ourDbFile) {
  1208. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  1209. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1210. extraData.ObjectTypeId = 0;
  1211. extraData.ObjectName = NULL;
  1212. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1213. __leave;
  1214. }
  1215. }
  1216. if (!MemDbSave (ourDbFile)) {
  1217. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  1218. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1219. extraData.ObjectTypeId = 0;
  1220. extraData.ObjectName = NULL;
  1221. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1222. __leave;
  1223. }
  1224. IsmTickProgressBar (g_DatabaseSlice, 1);
  1225. if (Compressed) {
  1226. if (IsmCheckCancel()) {
  1227. __leave;
  1228. }
  1229. if (!pOtAddFileToImage (ourDbFile, S_TRANSPORT_DAT_FILE, &compressedHandle)) {
  1230. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  1231. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1232. extraData.ObjectTypeId = 0;
  1233. extraData.ObjectName = NULL;
  1234. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1235. __leave;
  1236. }
  1237. IsmTickProgressBar (g_DatabaseSlice, 1);
  1238. if (IsmCheckCancel()) {
  1239. __leave;
  1240. }
  1241. if (!CompressFlushAndCloseHandle (&compressedHandle)) {
  1242. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  1243. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  1244. extraData.ObjectTypeId = 0;
  1245. extraData.ObjectName = NULL;
  1246. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  1247. __leave;
  1248. }
  1249. IsmTickProgressBar (g_DatabaseSlice, 1);
  1250. if (IsmCheckCancel()) {
  1251. __leave;
  1252. }
  1253. }
  1254. IsmSendMessageToApp (TRANSPORTMESSAGE_SIZE_SAVED, 0);
  1255. result = TRUE;
  1256. }
  1257. __finally {
  1258. PushError ();
  1259. CompressCleanupHandle (&compressedHandle);
  1260. pFreeStorageFileName (ourDbFile);
  1261. INVALID_POINTER (ourDbFile);
  1262. pOtDestroyDecoratedObject (decoratedObject);
  1263. INVALID_POINTER (decoratedObject);
  1264. if (g_OtCompressData && g_TransportTempPath) {
  1265. pOtCleanUpTempDir ();
  1266. }
  1267. PopError ();
  1268. }
  1269. return result;
  1270. }
  1271. BOOL
  1272. WINAPI
  1273. OpaqueTransportAcquireObject (
  1274. IN MIG_OBJECTTYPEID ObjectTypeId,
  1275. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1276. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  1277. IN MIG_CONTENTTYPE ContentType,
  1278. IN UINT MemoryContentLimit
  1279. )
  1280. {
  1281. UINT value;
  1282. PCBYTE memValue;
  1283. UINT memValueSize;
  1284. PCTSTR fileValue = NULL;
  1285. PCTSTR newFileValue = NULL;
  1286. BOOL valueInFile;
  1287. KEYHANDLE keyHandle;
  1288. PALLOCSTATE allocState;
  1289. PCTSTR detailsKey = NULL;
  1290. PBYTE details;
  1291. UINT detailsSize;
  1292. PCTSTR sourceFile;
  1293. PCTSTR decoratedObject = NULL;
  1294. HANDLE fileHandle;
  1295. BOOL result = FALSE;
  1296. if (!ObjectContent) {
  1297. return FALSE;
  1298. }
  1299. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  1300. MYASSERT ((ObjectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE);
  1301. decoratedObject = pOpaqueBuildDecoratedObject (ObjectTypeId, ObjectName);
  1302. allocState = (PALLOCSTATE) MemAllocZeroed (sizeof (ALLOCSTATE));
  1303. if (MemDbGetValue (decoratedObject, &value)) {
  1304. if (value == TRFLAG_FILE) {
  1305. valueInFile = TRUE;
  1306. keyHandle = MemDbGetSingleLinkage (decoratedObject, 0, 0);
  1307. if (keyHandle) {
  1308. fileValue = MemDbGetKeyFromHandle (keyHandle, 0);
  1309. newFileValue = pOpaqueGetNewFileName (fileValue);
  1310. result = fileValue != NULL;
  1311. } else {
  1312. fileValue = NULL;
  1313. result = TRUE;
  1314. }
  1315. } else if (value == TRFLAG_MEMORY) {
  1316. valueInFile = FALSE;
  1317. memValueSize = 0;
  1318. memValue = MemDbGetUnorderedBlob (decoratedObject, 0, &memValueSize);
  1319. result = TRUE;
  1320. } else {
  1321. LOG ((LOG_ERROR, (PCSTR) MSG_UNSUPPORTED_DATA, value));
  1322. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  1323. }
  1324. if (result) {
  1325. result = FALSE;
  1326. if (valueInFile) {
  1327. if ((ContentType == CONTENTTYPE_ANY) ||
  1328. (ContentType == CONTENTTYPE_FILE) ||
  1329. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  1330. ) {
  1331. // this is stored as a file and it's wanted as a file
  1332. ObjectContent->ObjectTypeId = ObjectTypeId;
  1333. ObjectContent->ContentInFile = TRUE;
  1334. if (fileValue) {
  1335. ObjectContent->FileContent.ContentPath = JoinPaths (pGetRealTransportPath (), newFileValue?newFileValue:fileValue);
  1336. ObjectContent->FileContent.ContentSize = BfGetFileSize (ObjectContent->FileContent.ContentPath);
  1337. } else {
  1338. ObjectContent->FileContent.ContentSize = 0;
  1339. ObjectContent->FileContent.ContentPath = NULL;
  1340. }
  1341. result = TRUE;
  1342. } else {
  1343. // this is stored as a file and it's wanted as memory
  1344. ObjectContent->ObjectTypeId = ObjectTypeId;
  1345. ObjectContent->ContentInFile = FALSE;
  1346. if (fileValue) {
  1347. sourceFile = JoinPaths (pGetRealTransportPath (), newFileValue?newFileValue:fileValue);
  1348. ObjectContent->MemoryContent.ContentSize = (UINT) BfGetFileSize (sourceFile);
  1349. ObjectContent->MemoryContent.ContentBytes = MapFileIntoMemory (
  1350. sourceFile,
  1351. &allocState->FileHandle,
  1352. &allocState->MapHandle
  1353. );
  1354. FreePathString (sourceFile);
  1355. result = (ObjectContent->MemoryContent.ContentBytes != NULL);
  1356. } else {
  1357. ObjectContent->MemoryContent.ContentSize = 0;
  1358. ObjectContent->MemoryContent.ContentBytes = NULL;
  1359. result = TRUE;
  1360. }
  1361. }
  1362. if (newFileValue) {
  1363. FreePathString (newFileValue);
  1364. newFileValue = NULL;
  1365. }
  1366. if (fileValue) {
  1367. MemDbReleaseMemory (fileValue);
  1368. fileValue = NULL;
  1369. }
  1370. } else {
  1371. if ((ContentType == CONTENTTYPE_ANY) ||
  1372. (ContentType == CONTENTTYPE_MEMORY) ||
  1373. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  1374. ) {
  1375. // this is stored as memory and it's wanted as memory
  1376. ObjectContent->ObjectTypeId = ObjectTypeId;
  1377. ObjectContent->ContentInFile = FALSE;
  1378. ObjectContent->MemoryContent.ContentSize = memValueSize;
  1379. ObjectContent->MemoryContent.ContentBytes = memValue;
  1380. result = TRUE;
  1381. } else {
  1382. // this is stored as memory and it's wanted as a file
  1383. if (memValue) {
  1384. if (IsmGetTempFile (allocState->TempFile, ARRAYSIZE(allocState->TempFile))) {
  1385. fileHandle = BfCreateFile (allocState->TempFile);
  1386. if (fileHandle) {
  1387. if (BfWriteFile (fileHandle, memValue, memValueSize)) {
  1388. ObjectContent->ObjectTypeId = ObjectTypeId;
  1389. ObjectContent->ContentInFile = TRUE;
  1390. ObjectContent->FileContent.ContentSize = memValueSize;
  1391. ObjectContent->FileContent.ContentPath = DuplicatePathString (allocState->TempFile, 0);
  1392. result = TRUE;
  1393. }
  1394. CloseHandle (fileHandle);
  1395. }
  1396. }
  1397. MemDbReleaseMemory (memValue);
  1398. } else {
  1399. ObjectContent->ObjectTypeId = ObjectTypeId;
  1400. ObjectContent->ContentInFile = TRUE;
  1401. ObjectContent->FileContent.ContentSize = 0;
  1402. ObjectContent->FileContent.ContentPath = NULL;
  1403. }
  1404. }
  1405. }
  1406. }
  1407. } else {
  1408. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  1409. }
  1410. if (result) {
  1411. //
  1412. // Fill the details
  1413. //
  1414. detailsKey = JoinText (S_DETAILS_PREFIX, decoratedObject);
  1415. details = MemDbGetUnorderedBlob (detailsKey, 0, &detailsSize);
  1416. if (!details) {
  1417. detailsSize = 0;
  1418. }
  1419. allocState->DetailsPtr = details;
  1420. ObjectContent->Details.DetailsSize = detailsSize;
  1421. ObjectContent->Details.DetailsData = details;
  1422. FreeText (detailsKey);
  1423. ObjectContent->TransHandle = allocState;
  1424. }
  1425. if (!result) {
  1426. FreeAlloc (allocState);
  1427. }
  1428. FreePathString (decoratedObject);
  1429. return result;
  1430. }
  1431. BOOL
  1432. WINAPI
  1433. OpaqueTransportReleaseObject (
  1434. IN OUT PMIG_CONTENT ObjectContent
  1435. )
  1436. {
  1437. PALLOCSTATE allocState;
  1438. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  1439. allocState = (PALLOCSTATE) ObjectContent->TransHandle;
  1440. if (ObjectContent->ContentInFile) {
  1441. FreePathString (ObjectContent->FileContent.ContentPath);
  1442. if (allocState && allocState->TempFile[0]) {
  1443. DeleteFile (allocState->TempFile);
  1444. }
  1445. } else {
  1446. if (allocState && allocState->FileHandle && allocState->MapHandle) {
  1447. UnmapFile (
  1448. ObjectContent->MemoryContent.ContentBytes,
  1449. allocState->MapHandle,
  1450. allocState->FileHandle
  1451. );
  1452. } else {
  1453. MemDbReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1454. }
  1455. }
  1456. if (allocState && allocState->DetailsPtr) {
  1457. MemDbReleaseMemory (allocState->DetailsPtr);
  1458. }
  1459. FreeAlloc (allocState);
  1460. return TRUE;
  1461. }