Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2204 lines
68 KiB

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