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.

1005 lines
37 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. source.c
  5. Abstract:
  6. Implements the source side of the home networking transport
  7. Author:
  8. Jim Schmidt (jimschm) 01-Jul-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include <winsock.h>
  17. #include <wsipx.h>
  18. #include <wsnwlink.h>
  19. #include <wsnetbs.h>
  20. #include "homenetp.h"
  21. #define DBG_HOMENET "HomeNet"
  22. //
  23. // Strings
  24. //
  25. #define S_TRANSPORT_DSK_FILE TEXT("DSK%05X")
  26. #define S_DETAILS_PREFIX TEXT("details-")
  27. //
  28. // Constants
  29. //
  30. //
  31. // Macros
  32. //
  33. // None
  34. //
  35. // Types
  36. //
  37. // none
  38. //
  39. // Globals
  40. //
  41. MIG_PROGRESSSLICEID g_PersistentSlice;
  42. //
  43. // Macro expansion list
  44. //
  45. // None
  46. //
  47. // Private function prototypes
  48. //
  49. // none
  50. //
  51. // Macro expansion definition
  52. //
  53. // None
  54. //
  55. // Code
  56. //
  57. BOOL
  58. pSetTransportStatus (
  59. IN HANDLE TrJournalHandle,
  60. IN BOOL Compressed,
  61. IN DWORD Status
  62. )
  63. {
  64. DWORD signature = HOMENETTR_SIG;
  65. if (BfSetFilePointer (TrJournalHandle, 0)) {
  66. BfWriteFile (TrJournalHandle, (PBYTE)(&signature), sizeof (DWORD));
  67. BfWriteFile (TrJournalHandle, (PBYTE)(&Compressed), sizeof (BOOL));
  68. BfWriteFile (TrJournalHandle, (PBYTE)(&Status), sizeof (DWORD));
  69. }
  70. FlushFileBuffers (TrJournalHandle);
  71. return TRUE;
  72. }
  73. BOOL
  74. pTransportFile (
  75. IN PCTSTR LocalPath,
  76. IN PCTSTR StoragePath
  77. )
  78. {
  79. static UINT tcharsToSkip;
  80. BOOL b;
  81. if (!tcharsToSkip) {
  82. tcharsToSkip = TcharCount (g_TransportTempDir);
  83. }
  84. StoragePath += tcharsToSkip;
  85. MYASSERT (*StoragePath == TEXT('\\'));
  86. StoragePath++;
  87. b = SendFileToDestination (&g_Connection, LocalPath, StoragePath);
  88. DEBUGMSG_IF ((!b, DBG_ERROR, "Can't send %s to destination", LocalPath));
  89. return b;
  90. }
  91. BOOL
  92. pHomeNetSaveDetails (
  93. IN PCTSTR DecoratedObject,
  94. IN PMIG_DETAILS Details
  95. )
  96. {
  97. PCTSTR key;
  98. BOOL b = FALSE;
  99. if ((!Details) || (!Details->DetailsSize)) {
  100. return TRUE;
  101. }
  102. key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
  103. if (key) {
  104. b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
  105. FreeText (key);
  106. }
  107. return b;
  108. }
  109. BOOL
  110. pHomeNetAddFileToImage (
  111. IN PCTSTR FileName,
  112. IN PCTSTR CabName,
  113. IN OUT CCABHANDLE CabHandle
  114. )
  115. {
  116. return CabAddFileToCabinet (CabHandle, FileName, CabName);
  117. }
  118. BOOL
  119. pHomeNetSaveContentInFile (
  120. IN MIG_OBJECTTYPEID ObjectTypeId,
  121. IN PCTSTR EncodedFileName,
  122. IN PCTSTR DecoratedObject,
  123. IN PMIG_CONTENT Content,
  124. IN OUT CCABHANDLE CabHandle OPTIONAL
  125. )
  126. {
  127. BOOL result = FALSE;
  128. PCTSTR destPath = NULL;
  129. DWORD attributes = INVALID_ATTRIBUTES;
  130. MYASSERT (Content->ContentInFile);
  131. if (!Content->ContentInFile) {
  132. return FALSE;
  133. }
  134. //
  135. // Use sockets to move the file from local to storage.
  136. //
  137. __try {
  138. if (Content && (Content->Details.DetailsSize == sizeof (WIN32_FIND_DATAW)) && Content->Details.DetailsData) {
  139. attributes = ((PWIN32_FIND_DATAW)Content->Details.DetailsData)->dwFileAttributes;
  140. }
  141. if ((attributes != INVALID_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
  142. // this must be a directory, let's just write the key
  143. // BUGBUG - what about zero-length files?
  144. if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
  145. __leave;
  146. }
  147. } else {
  148. //
  149. // Get a temp file, assemble the src path, copy the file
  150. //
  151. destPath = AllocStorageFileName (NULL);
  152. if (!destPath) {
  153. DEBUGMSG ((DBG_ERROR, "Can't get storage path"));
  154. __leave;
  155. }
  156. if (CabHandle) {
  157. if (!pHomeNetAddFileToImage (
  158. Content->FileContent.ContentPath,
  159. GetFileNameFromPath (destPath),
  160. CabHandle
  161. )) {
  162. __leave;
  163. }
  164. } else {
  165. if (!pTransportFile (Content->FileContent.ContentPath, destPath)) {
  166. __leave;
  167. }
  168. }
  169. //
  170. // Keep track of where the file went
  171. //
  172. if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
  173. __leave;
  174. }
  175. if (!MemDbAddSingleLinkage (DecoratedObject, GetFileNameFromPath (destPath), 0)) {
  176. __leave;
  177. }
  178. }
  179. //
  180. // Save details
  181. //
  182. result = pHomeNetSaveDetails (DecoratedObject, &(Content->Details));
  183. }
  184. __finally {
  185. FreeStorageFileName (destPath);
  186. INVALID_POINTER (destPath);
  187. }
  188. return result;
  189. }
  190. BOOL
  191. pHomeNetSaveContentInMemory (
  192. IN MIG_OBJECTTYPEID ObjectTypeId,
  193. IN PCTSTR EncodedObjectName,
  194. IN PCTSTR DecoratedObject,
  195. IN PMIG_CONTENT Content
  196. )
  197. {
  198. BOOL result = FALSE;
  199. MYASSERT (!Content->ContentInFile);
  200. if (Content->ContentInFile) {
  201. return FALSE;
  202. }
  203. MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
  204. if (Content->MemoryContent.ContentBytes && Content->MemoryContent.ContentSize) {
  205. MemDbSetUnorderedBlob (
  206. DecoratedObject,
  207. 0,
  208. Content->MemoryContent.ContentBytes,
  209. Content->MemoryContent.ContentSize
  210. );
  211. }
  212. result = pHomeNetSaveDetails (DecoratedObject, &(Content->Details));
  213. return result;
  214. }
  215. BOOL
  216. pHomeNetWriteAllImages (
  217. VOID
  218. )
  219. {
  220. UINT imageIdx = 1;
  221. PCTSTR imageFile;
  222. BOOL result = FALSE;
  223. for (;;) {
  224. imageFile = BuildImageFileName (imageIdx);
  225. if (DoesFileExist (imageFile)) {
  226. if (!pTransportFile (imageFile, imageFile)) {
  227. break;
  228. }
  229. } else {
  230. result = TRUE;
  231. break;
  232. }
  233. FreeImageFileName (imageFile);
  234. imageIdx ++;
  235. }
  236. return result;
  237. }
  238. BOOL
  239. pAskForPassword (
  240. OUT PSTR Key,
  241. IN UINT KeySize
  242. )
  243. {
  244. INT_PTR appReply;
  245. PASSWORD_DATA passwordData;
  246. passwordData.Key = (PSTR)Key;
  247. passwordData.KeySize = KeySize;
  248. passwordData.Event = NULL;
  249. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_NET_GATHER_PASSWORD, (ULONG_PTR)&passwordData);
  250. return (appReply == APPRESPONSE_SUCCESS);
  251. }
  252. BOOL
  253. pSaveAllState (
  254. IN BOOL Compressed
  255. )
  256. {
  257. MIG_APPINFO appInfo;
  258. MIG_CONTENT value;
  259. PMIG_CONTENT convValue;
  260. ULONGLONG size;
  261. MIG_OBJECTWITHATTRIBUTE_ENUM objEnum;
  262. PCTSTR ourDbFile = NULL;
  263. PCTSTR decoratedObject = NULL;
  264. ULONGLONG bytesSaved = 0;
  265. UINT lastTick = GetTickCount();
  266. UINT fraction;
  267. CCABHANDLE cabHandle = NULL;
  268. CONNECTADDRESS destination;
  269. DWORD nameSize;
  270. UINT fileCount;
  271. LONGLONG fileSize;
  272. UINT nextKeepAlive = lastTick + 60000;
  273. INT_PTR appReply;
  274. BOOL okSave = FALSE;
  275. TRANSCOPY_ERROR transCopyError;
  276. BOOL result = FALSE;
  277. PCTSTR statusMsg;
  278. PCTSTR argArray[2];
  279. ERRUSER_EXTRADATA extraData;
  280. UINT message;
  281. UINT numTry = 0;
  282. ZeroMemory (&g_Connection, sizeof (g_Connection));
  283. g_Connection.Socket = INVALID_SOCKET;
  284. ZeroMemory (&g_Metrics, sizeof (g_Metrics));
  285. g_Metrics.Signature = HOMENETTR_SIG;
  286. __try {
  287. nameSize = ARRAYSIZE(g_Metrics.SourceName);
  288. GetComputerName (g_Metrics.SourceName, &nameSize);
  289. if (Compressed) {
  290. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  291. appInfo.Phase = MIG_TRANSPORT_PHASE;
  292. appInfo.SubPhase = SUBPHASE_PREPARING;
  293. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  294. cabHandle = CabCreateCabinet (g_TransportTempDir, S_TRANSPORT_IMG_FILE, S_TRANSPORT_DSK_FILE, IsmGetTempFile, 0);
  295. if (!cabHandle) {
  296. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  297. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  298. extraData.ObjectTypeId = 0;
  299. extraData.ObjectName = NULL;
  300. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  301. __leave;
  302. }
  303. } else {
  304. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  305. appInfo.Phase = MIG_TRANSPORT_PHASE;
  306. appInfo.SubPhase = SUBPHASE_CONNECTING1;
  307. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  308. //
  309. // Connect to the destination
  310. //
  311. // NOTE: This is designed such that FindDestination can run in a background
  312. // thread, allowing us to estimate the number of files at the same time
  313. //
  314. if (IsmEnumFirstPersistentObject (&objEnum)) {
  315. do {
  316. okSave = FALSE;
  317. while (!okSave) {
  318. if (!IsmAcquireObjectEx (
  319. objEnum.ObjectTypeId,
  320. objEnum.ObjectName,
  321. &value,
  322. CONTENTTYPE_DETAILS_ONLY,
  323. 0
  324. )) {
  325. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  326. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  327. transCopyError.Error = GetLastError ();
  328. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  329. appReply = APPRESPONSE_IGNORE;
  330. } else {
  331. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  332. if ((appReply == APPRESPONSE_NONE) ||
  333. (appReply == APPRESPONSE_FAIL)
  334. ) {
  335. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  336. IsmReleaseMemory (transCopyError.ObjectName);
  337. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  338. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  339. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  340. extraData.ObjectName = objEnum.ObjectName;
  341. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  342. IsmAbortPersistentObjectEnum (&objEnum);
  343. __leave;
  344. }
  345. }
  346. if (appReply == APPRESPONSE_IGNORE) {
  347. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  348. IsmReleaseMemory (transCopyError.ObjectName);
  349. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  350. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  351. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  352. extraData.ObjectName = objEnum.ObjectName;
  353. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  354. break;
  355. }
  356. IsmReleaseMemory (transCopyError.ObjectName);
  357. continue;
  358. }
  359. okSave = TRUE;
  360. }
  361. if (value.ContentInFile) {
  362. g_Metrics.FileCount++;
  363. g_Metrics.TotalSize += value.FileContent.ContentSize; // estimated
  364. }
  365. } while (IsmEnumNextPersistentObject (&objEnum));
  366. }
  367. g_Metrics.FileCount++; // our memdb
  368. if (!FindDestination (&destination, 60, FALSE)) {
  369. if (!IsmCheckCancel()) {
  370. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_DESTINATION));
  371. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  372. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  373. extraData.ObjectTypeId = 0;
  374. extraData.ObjectName = NULL;
  375. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  376. }
  377. __leave;
  378. }
  379. if (!ConnectToDestination (&destination, &g_Metrics, &g_Connection)) {
  380. if (!IsmCheckCancel()) {
  381. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  382. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  383. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  384. extraData.ObjectTypeId = 0;
  385. extraData.ObjectName = NULL;
  386. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  387. }
  388. __leave;
  389. }
  390. numTry = 0;
  391. do {
  392. // now we connected to the destination. Let's pop up a dialog asking the user to
  393. // type in the password that the destination has.
  394. if (!pAskForPassword (g_GlobalKey, 33)) {
  395. // let's tell the destination computer that we are bailing out.
  396. SendMessageToDestination (&g_Connection, MESSAGE_CANCEL);
  397. // BUGBUG - better error message
  398. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  399. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  400. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  401. extraData.ObjectTypeId = 0;
  402. extraData.ObjectName = NULL;
  403. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  404. __leave;
  405. }
  406. if (!SendDataToDestination (&g_Connection, g_GlobalKey, SizeOfStringA (g_GlobalKey))) {
  407. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  408. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  409. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  410. extraData.ObjectTypeId = 0;
  411. extraData.ObjectName = NULL;
  412. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  413. __leave;
  414. }
  415. message = ReceiveFromSource (&g_Connection, NULL, NULL, 0);
  416. if (message == MESSAGE_PASSWORDWRONG) {
  417. numTry ++;
  418. if (numTry >= 3) {
  419. // let's tell the destination computer that we are bailing out.
  420. SendMessageToDestination (&g_Connection, MESSAGE_CANCEL);
  421. // BUGBUG - better error message
  422. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  423. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  424. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  425. extraData.ObjectTypeId = 0;
  426. extraData.ObjectName = NULL;
  427. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  428. __leave;
  429. }
  430. }
  431. } while (message == MESSAGE_PASSWORDWRONG);
  432. if (message != MESSAGE_PASSWORDOK) {
  433. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  434. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  435. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  436. extraData.ObjectTypeId = 0;
  437. extraData.ObjectName = NULL;
  438. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  439. __leave;
  440. }
  441. }
  442. //
  443. // Enumerate all objects with "save" attribute
  444. //
  445. if (IsmEnumFirstPersistentObject (&objEnum)) {
  446. do {
  447. //
  448. // Send keep-alive to connection every 30 seconds of idle time
  449. //
  450. if (!Compressed) {
  451. if (GetTickCount() - g_Connection.LastSend > g_Connection.KeepAliveSpacing) {
  452. SendMessageToDestination (&g_Connection, MESSAGE_KEEP_ALIVE);
  453. }
  454. }
  455. //
  456. // For each object to be saved, do the appropriate
  457. // data copy action
  458. //
  459. okSave = FALSE;
  460. while (!okSave) {
  461. if (!IsmAcquireObjectEx (
  462. objEnum.ObjectTypeId,
  463. objEnum.ObjectName,
  464. &value,
  465. CONTENTTYPE_ANY,
  466. 0
  467. )) {
  468. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  469. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  470. transCopyError.Error = GetLastError ();
  471. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  472. appReply = APPRESPONSE_IGNORE;
  473. } else {
  474. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  475. if ((appReply == APPRESPONSE_NONE) ||
  476. (appReply == APPRESPONSE_FAIL)
  477. ) {
  478. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  479. IsmReleaseMemory (transCopyError.ObjectName);
  480. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  481. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  482. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  483. extraData.ObjectName = objEnum.ObjectName;
  484. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  485. IsmAbortPersistentObjectEnum (&objEnum);
  486. __leave;
  487. }
  488. }
  489. if (appReply == APPRESPONSE_IGNORE) {
  490. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  491. IsmReleaseMemory (transCopyError.ObjectName);
  492. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  493. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  494. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  495. extraData.ObjectName = objEnum.ObjectName;
  496. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  497. break;
  498. }
  499. IsmReleaseMemory (transCopyError.ObjectName);
  500. continue;
  501. }
  502. okSave = TRUE;
  503. }
  504. if (okSave) {
  505. #ifdef UNICODE
  506. convValue = &value;
  507. #else
  508. // now let's convert this object content to UNICODE
  509. convValue = IsmConvertObjectContentToUnicode (objEnum.ObjectTypeId, objEnum.ObjectName, &value);
  510. if (!convValue) {
  511. convValue = &value;
  512. }
  513. #endif
  514. decoratedObject = BuildDecoratedObject (objEnum.ObjectTypeId, objEnum.ObjectName);
  515. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  516. appInfo.Phase = MIG_TRANSPORT_PHASE;
  517. if (Compressed) {
  518. appInfo.SubPhase = SUBPHASE_COMPRESSING;
  519. } else {
  520. appInfo.SubPhase = SUBPHASE_TRANSPORTING;
  521. }
  522. appInfo.ObjectTypeId = (objEnum.ObjectTypeId & (~PLATFORM_MASK));
  523. appInfo.ObjectName = objEnum.ObjectName;
  524. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  525. if (convValue->ContentInFile) {
  526. okSave = FALSE;
  527. while (!okSave) {
  528. if (!pHomeNetSaveContentInFile (
  529. objEnum.ObjectTypeId,
  530. objEnum.ObjectName,
  531. decoratedObject,
  532. convValue,
  533. cabHandle
  534. )) {
  535. if (GetLastError () == ERROR_NETWORK_UNREACHABLE) {
  536. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  537. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  538. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  539. extraData.ObjectTypeId = 0;
  540. extraData.ObjectName = NULL;
  541. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  542. IsmAbortPersistentObjectEnum (&objEnum);
  543. __leave;
  544. }
  545. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  546. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  547. transCopyError.Error = GetLastError ();
  548. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  549. appReply = APPRESPONSE_IGNORE;
  550. } else {
  551. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  552. if ((appReply == APPRESPONSE_NONE) ||
  553. (appReply == APPRESPONSE_FAIL)
  554. ) {
  555. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  556. IsmReleaseMemory (transCopyError.ObjectName);
  557. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  558. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  559. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  560. extraData.ObjectName = objEnum.ObjectName;
  561. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  562. IsmAbortPersistentObjectEnum (&objEnum);
  563. __leave;
  564. }
  565. }
  566. if (appReply == APPRESPONSE_IGNORE) {
  567. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  568. IsmReleaseMemory (transCopyError.ObjectName);
  569. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  570. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  571. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  572. extraData.ObjectName = objEnum.ObjectName;
  573. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  574. break;
  575. }
  576. IsmReleaseMemory (transCopyError.ObjectName);
  577. continue;
  578. }
  579. okSave = TRUE;
  580. }
  581. size = convValue->FileContent.ContentSize;
  582. } else {
  583. okSave = FALSE;
  584. while (!okSave) {
  585. if (!pHomeNetSaveContentInMemory (objEnum.ObjectTypeId, objEnum.ObjectName, decoratedObject, convValue)) {
  586. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  587. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  588. transCopyError.Error = GetLastError ();
  589. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  590. appReply = APPRESPONSE_IGNORE;
  591. } else {
  592. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  593. if ((appReply == APPRESPONSE_NONE) ||
  594. (appReply == APPRESPONSE_FAIL)
  595. ) {
  596. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  597. IsmReleaseMemory (transCopyError.ObjectName);
  598. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  599. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  600. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  601. extraData.ObjectName = objEnum.ObjectName;
  602. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  603. IsmAbortPersistentObjectEnum (&objEnum);
  604. __leave;
  605. }
  606. }
  607. if (appReply == APPRESPONSE_IGNORE) {
  608. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  609. IsmReleaseMemory (transCopyError.ObjectName);
  610. extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
  611. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  612. extraData.ObjectTypeId = objEnum.ObjectTypeId;
  613. extraData.ObjectName = objEnum.ObjectName;
  614. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
  615. break;
  616. }
  617. IsmReleaseMemory (transCopyError.ObjectName);
  618. continue;
  619. }
  620. okSave = TRUE;
  621. }
  622. size = convValue->MemoryContent.ContentSize;
  623. }
  624. #ifndef UNICODE
  625. if (convValue != (&value)) {
  626. IsmFreeConvertedObjectContent (objEnum.ObjectTypeId, convValue);
  627. }
  628. #endif
  629. IsmReleaseObject (&value);
  630. DestroyDecoratedObject (decoratedObject);
  631. decoratedObject = NULL;
  632. }
  633. IsmTickProgressBar (g_PersistentSlice, 1);
  634. //
  635. // Send bytes saved to app every 3 seconds
  636. //
  637. bytesSaved += size;
  638. if (GetTickCount() - lastTick > 3000) {
  639. if (bytesSaved < 1048576) {
  640. argArray[0] = (PCTSTR) (UINT_PTR) (bytesSaved / 1024);
  641. statusMsg = ParseMessageID (MSG_SAVED_K, argArray);
  642. } else if (bytesSaved < 8388608) {
  643. fraction = (UINT) (bytesSaved / 10485);
  644. argArray[0] = (PCTSTR) (UINT_PTR) (fraction / 100);
  645. argArray[1] = (PCTSTR) (UINT_PTR) (fraction % 100);
  646. statusMsg = ParseMessageID (MSG_SAVED_M, argArray);
  647. } else if (bytesSaved < 1073741824) {
  648. argArray[0] = (PCTSTR) (UINT_PTR) (bytesSaved / 1048576);
  649. statusMsg = ParseMessageID (MSG_SAVED_M2, argArray);
  650. } else {
  651. fraction = (UINT) (bytesSaved / 10737418);
  652. argArray[0] = (PCTSTR) (UINT_PTR) (fraction / 100);
  653. argArray[1] = (PCTSTR) (UINT_PTR) (fraction % 100);
  654. statusMsg = ParseMessageID (MSG_SAVED_G, argArray);
  655. }
  656. IsmSendMessageToApp (TRANSPORTMESSAGE_SIZE_SAVED, (ULONG_PTR) statusMsg);
  657. FreeStringResource (statusMsg);
  658. lastTick = GetTickCount();
  659. }
  660. } while (IsmEnumNextPersistentObject (&objEnum));
  661. }
  662. ourDbFile = AllocStorageFileName (S_TRANSPORT_DAT_FILE);
  663. if (!ourDbFile) {
  664. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  665. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  666. extraData.ObjectTypeId = 0;
  667. extraData.ObjectName = NULL;
  668. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  669. __leave;
  670. }
  671. DEBUGMSG ((DBG_HOMENET, "Saving memdb"));
  672. BfCreateDirectory (g_TransportTempDir);
  673. if (!MemDbSave (ourDbFile)) {
  674. DEBUGMSG ((DBG_ERROR, "Can't save our database to %s", ourDbFile));
  675. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  676. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  677. extraData.ObjectTypeId = 0;
  678. extraData.ObjectName = NULL;
  679. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  680. __leave;
  681. }
  682. if (Compressed) {
  683. if (!pHomeNetAddFileToImage (ourDbFile, S_TRANSPORT_DAT_FILE, cabHandle)) {
  684. extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
  685. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  686. extraData.ObjectTypeId = 0;
  687. extraData.ObjectName = NULL;
  688. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  689. __leave;
  690. }
  691. if (!CabFlushAndCloseCabinetEx (cabHandle, NULL, NULL, &fileCount, &fileSize)) {
  692. extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
  693. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  694. extraData.ObjectTypeId = 0;
  695. extraData.ObjectName = NULL;
  696. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  697. __leave;
  698. }
  699. DEBUGMSG ((DBG_HOMENET, "Compression results: files=%u size=%u", fileCount, (UINT) fileSize));
  700. g_Metrics.FileCount += fileCount;
  701. g_Metrics.TotalSize += fileSize;
  702. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  703. appInfo.Phase = MIG_TRANSPORT_PHASE;
  704. appInfo.SubPhase = SUBPHASE_CONNECTING1;
  705. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  706. if (!FindDestination (&destination, 0, FALSE)) {
  707. if (!IsmCheckCancel()) {
  708. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_DESTINATION));
  709. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  710. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  711. extraData.ObjectTypeId = 0;
  712. extraData.ObjectName = NULL;
  713. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  714. }
  715. __leave;
  716. }
  717. if (!ConnectToDestination (&destination, &g_Metrics, &g_Connection)) {
  718. if (!IsmCheckCancel()) {
  719. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
  720. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  721. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  722. extraData.ObjectTypeId = 0;
  723. extraData.ObjectName = NULL;
  724. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  725. }
  726. __leave;
  727. }
  728. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  729. appInfo.Phase = MIG_TRANSPORT_PHASE;
  730. appInfo.SubPhase = SUBPHASE_FINISHING;
  731. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  732. if (!pHomeNetWriteAllImages ()) {
  733. extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
  734. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  735. extraData.ObjectTypeId = 0;
  736. extraData.ObjectName = NULL;
  737. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  738. __leave;
  739. }
  740. } else {
  741. ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
  742. appInfo.Phase = MIG_TRANSPORT_PHASE;
  743. appInfo.SubPhase = SUBPHASE_FINISHING;
  744. IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
  745. DEBUGMSG ((DBG_HOMENET, "Transporting memdb"));
  746. if (!pTransportFile (ourDbFile, ourDbFile)) {
  747. if (GetLastError () == ERROR_NETWORK_UNREACHABLE) {
  748. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  749. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  750. extraData.ObjectTypeId = 0;
  751. extraData.ObjectName = NULL;
  752. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  753. __leave;
  754. } else {
  755. extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
  756. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  757. extraData.ObjectTypeId = 0;
  758. extraData.ObjectName = NULL;
  759. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  760. __leave;
  761. }
  762. }
  763. }
  764. DEBUGMSG ((DBG_HOMENET, "Transporting status file"));
  765. pSetTransportStatus (g_StatusFileHandle, g_CompressData, TRSTATUS_READY);
  766. CloseHandle (g_StatusFileHandle);
  767. g_StatusFileHandle = INVALID_HANDLE_VALUE;
  768. if (!pTransportFile (g_StatusFile, g_StatusFile)) {
  769. if (GetLastError () == ERROR_NETWORK_UNREACHABLE) {
  770. extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
  771. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  772. extraData.ObjectTypeId = 0;
  773. extraData.ObjectName = NULL;
  774. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  775. __leave;
  776. } else {
  777. extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
  778. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  779. extraData.ObjectTypeId = 0;
  780. extraData.ObjectName = NULL;
  781. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  782. __leave;
  783. }
  784. }
  785. DEBUGMSG ((DBG_HOMENET, "Done sending files"));
  786. SendMessageToDestination (&g_Connection, MESSAGE_DONE);
  787. if (MESSAGE_DONE != ReceiveFromSource (&g_Connection, NULL, NULL, 0)) {
  788. if (GetLastError() != WSAECONNRESET) {
  789. DEBUGMSG ((DBG_ERROR, "No acknowledgement from the destination"));
  790. extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
  791. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  792. extraData.ObjectTypeId = 0;
  793. extraData.ObjectName = NULL;
  794. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  795. __leave;
  796. }
  797. }
  798. IsmSendMessageToApp (TRANSPORTMESSAGE_SIZE_SAVED, 0);
  799. result = TRUE;
  800. }
  801. __finally {
  802. PushError ();
  803. FreeStorageFileName (ourDbFile);
  804. INVALID_POINTER (ourDbFile);
  805. DestroyDecoratedObject (decoratedObject);
  806. INVALID_POINTER (decoratedObject);
  807. CloseConnection (&g_Connection);
  808. PopError ();
  809. }
  810. return result;
  811. }
  812. BOOL
  813. WINAPI
  814. HomeNetTransportSaveState (
  815. VOID
  816. )
  817. {
  818. ERRUSER_EXTRADATA extraData;
  819. g_Platform = PLATFORM_SOURCE;
  820. ZeroMemory (&extraData, sizeof (ERRUSER_EXTRADATA));
  821. extraData.Error = ERRUSER_ERROR_UNKNOWN;
  822. g_StatusFileHandle = BfCreateFile (g_StatusFile);
  823. if (g_StatusFileHandle == INVALID_HANDLE_VALUE) {
  824. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_NET_STATUS_FILE));
  825. extraData.Error = ERRUSER_ERROR_NOTRANSPORTPATH;
  826. extraData.ErrorArea = ERRUSER_AREA_SAVE;
  827. IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
  828. return FALSE;
  829. }
  830. return pSaveAllState (g_CompressData);
  831. }