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.

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