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

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
source.c
Abstract:
Implements the source side of the home networking transport
Author:
Jim Schmidt (jimschm) 01-Jul-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include <winsock.h>
#include <wsipx.h>
#include <wsnwlink.h>
#include <wsnetbs.h>
#include "homenetp.h"
#define DBG_HOMENET "HomeNet"
//
// Strings
//
#define S_TRANSPORT_DSK_FILE TEXT("DSK%05X")
#define S_DETAILS_PREFIX TEXT("details-")
//
// Constants
//
//
// Macros
//
// None
//
// Types
//
// none
//
// Globals
//
MIG_PROGRESSSLICEID g_PersistentSlice;
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// none
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL
pSetTransportStatus (
IN HANDLE TrJournalHandle,
IN BOOL Compressed,
IN DWORD Status
)
{
DWORD signature = HOMENETTR_SIG;
if (BfSetFilePointer (TrJournalHandle, 0)) {
BfWriteFile (TrJournalHandle, (PBYTE)(&signature), sizeof (DWORD));
BfWriteFile (TrJournalHandle, (PBYTE)(&Compressed), sizeof (BOOL));
BfWriteFile (TrJournalHandle, (PBYTE)(&Status), sizeof (DWORD));
}
FlushFileBuffers (TrJournalHandle);
return TRUE;
}
BOOL
pTransportFile (
IN PCTSTR LocalPath,
IN PCTSTR StoragePath
)
{
static UINT tcharsToSkip;
BOOL b;
if (!tcharsToSkip) {
tcharsToSkip = TcharCount (g_TransportTempDir);
}
StoragePath += tcharsToSkip;
MYASSERT (*StoragePath == TEXT('\\'));
StoragePath++;
b = SendFileToDestination (&g_Connection, LocalPath, StoragePath);
DEBUGMSG_IF ((!b, DBG_ERROR, "Can't send %s to destination", LocalPath));
return b;
}
BOOL
pHomeNetSaveDetails (
IN PCTSTR DecoratedObject,
IN PMIG_DETAILS Details
)
{
PCTSTR key;
BOOL b = FALSE;
if ((!Details) || (!Details->DetailsSize)) {
return TRUE;
}
key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
if (key) {
b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
FreeText (key);
}
return b;
}
BOOL
pHomeNetAddFileToImage (
IN PCTSTR FileName,
IN PCTSTR CabName,
IN OUT CCABHANDLE CabHandle
)
{
return CabAddFileToCabinet (CabHandle, FileName, CabName);
}
BOOL
pHomeNetSaveContentInFile (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN PCTSTR EncodedFileName,
IN PCTSTR DecoratedObject,
IN PMIG_CONTENT Content,
IN OUT CCABHANDLE CabHandle OPTIONAL
)
{
BOOL result = FALSE;
PCTSTR destPath = NULL;
DWORD attributes = INVALID_ATTRIBUTES;
MYASSERT (Content->ContentInFile);
if (!Content->ContentInFile) {
return FALSE;
}
//
// Use sockets to move the file from local to storage.
//
__try {
if (Content && (Content->Details.DetailsSize == sizeof (WIN32_FIND_DATAW)) && Content->Details.DetailsData) {
attributes = ((PWIN32_FIND_DATAW)Content->Details.DetailsData)->dwFileAttributes;
}
if ((attributes != INVALID_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
// this must be a directory, let's just write the key
// BUGBUG - what about zero-length files?
if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
__leave;
}
} else {
//
// Get a temp file, assemble the src path, copy the file
//
destPath = AllocStorageFileName (NULL);
if (!destPath) {
DEBUGMSG ((DBG_ERROR, "Can't get storage path"));
__leave;
}
if (CabHandle) {
if (!pHomeNetAddFileToImage (
Content->FileContent.ContentPath,
GetFileNameFromPath (destPath),
CabHandle
)) {
__leave;
}
} else {
if (!pTransportFile (Content->FileContent.ContentPath, destPath)) {
__leave;
}
}
//
// Keep track of where the file went
//
if (!MemDbSetValue (DecoratedObject, TRFLAG_FILE)) {
__leave;
}
if (!MemDbAddSingleLinkage (DecoratedObject, GetFileNameFromPath (destPath), 0)) {
__leave;
}
}
//
// Save details
//
result = pHomeNetSaveDetails (DecoratedObject, &(Content->Details));
}
__finally {
FreeStorageFileName (destPath);
INVALID_POINTER (destPath);
}
return result;
}
BOOL
pHomeNetSaveContentInMemory (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN PCTSTR EncodedObjectName,
IN PCTSTR DecoratedObject,
IN PMIG_CONTENT Content
)
{
BOOL result = FALSE;
MYASSERT (!Content->ContentInFile);
if (Content->ContentInFile) {
return FALSE;
}
MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
if (Content->MemoryContent.ContentBytes && Content->MemoryContent.ContentSize) {
MemDbSetUnorderedBlob (
DecoratedObject,
0,
Content->MemoryContent.ContentBytes,
Content->MemoryContent.ContentSize
);
}
result = pHomeNetSaveDetails (DecoratedObject, &(Content->Details));
return result;
}
BOOL
pHomeNetWriteAllImages (
VOID
)
{
UINT imageIdx = 1;
PCTSTR imageFile;
BOOL result = FALSE;
for (;;) {
imageFile = BuildImageFileName (imageIdx);
if (DoesFileExist (imageFile)) {
if (!pTransportFile (imageFile, imageFile)) {
break;
}
} else {
result = TRUE;
break;
}
FreeImageFileName (imageFile);
imageIdx ++;
}
return result;
}
BOOL
pAskForPassword (
OUT PSTR Key,
IN UINT KeySize
)
{
INT_PTR appReply;
PASSWORD_DATA passwordData;
passwordData.Key = (PSTR)Key;
passwordData.KeySize = KeySize;
passwordData.Event = NULL;
appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_NET_GATHER_PASSWORD, (ULONG_PTR)&passwordData);
return (appReply == APPRESPONSE_SUCCESS);
}
BOOL
pSaveAllState (
IN BOOL Compressed
)
{
MIG_APPINFO appInfo;
MIG_CONTENT value;
PMIG_CONTENT convValue;
ULONGLONG size;
MIG_OBJECTWITHATTRIBUTE_ENUM objEnum;
PCTSTR ourDbFile = NULL;
PCTSTR decoratedObject = NULL;
ULONGLONG bytesSaved = 0;
UINT lastTick = GetTickCount();
UINT fraction;
CCABHANDLE cabHandle = NULL;
CONNECTADDRESS destination;
DWORD nameSize;
UINT fileCount;
LONGLONG fileSize;
UINT nextKeepAlive = lastTick + 60000;
INT_PTR appReply;
BOOL okSave = FALSE;
TRANSCOPY_ERROR transCopyError;
BOOL result = FALSE;
PCTSTR statusMsg;
PCTSTR argArray[2];
ERRUSER_EXTRADATA extraData;
UINT message;
UINT numTry = 0;
ZeroMemory (&g_Connection, sizeof (g_Connection));
g_Connection.Socket = INVALID_SOCKET;
ZeroMemory (&g_Metrics, sizeof (g_Metrics));
g_Metrics.Signature = HOMENETTR_SIG;
__try {
nameSize = ARRAYSIZE(g_Metrics.SourceName);
GetComputerName (g_Metrics.SourceName, &nameSize);
if (Compressed) {
ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
appInfo.Phase = MIG_TRANSPORT_PHASE;
appInfo.SubPhase = SUBPHASE_PREPARING;
IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
cabHandle = CabCreateCabinet (g_TransportTempDir, S_TRANSPORT_IMG_FILE, S_TRANSPORT_DSK_FILE, IsmGetTempFile, 0);
if (!cabHandle) {
extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
} else {
ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
appInfo.Phase = MIG_TRANSPORT_PHASE;
appInfo.SubPhase = SUBPHASE_CONNECTING1;
IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
//
// Connect to the destination
//
// NOTE: This is designed such that FindDestination can run in a background
// thread, allowing us to estimate the number of files at the same time
//
if (IsmEnumFirstPersistentObject (&objEnum)) {
do {
okSave = FALSE;
while (!okSave) {
if (!IsmAcquireObjectEx (
objEnum.ObjectTypeId,
objEnum.ObjectName,
&value,
CONTENTTYPE_DETAILS_ONLY,
0
)) {
transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
transCopyError.Error = GetLastError ();
if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
appReply = APPRESPONSE_IGNORE;
} else {
appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
if ((appReply == APPRESPONSE_NONE) ||
(appReply == APPRESPONSE_FAIL)
) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
IsmAbortPersistentObjectEnum (&objEnum);
__leave;
}
}
if (appReply == APPRESPONSE_IGNORE) {
LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
break;
}
IsmReleaseMemory (transCopyError.ObjectName);
continue;
}
okSave = TRUE;
}
if (value.ContentInFile) {
g_Metrics.FileCount++;
g_Metrics.TotalSize += value.FileContent.ContentSize; // estimated
}
} while (IsmEnumNextPersistentObject (&objEnum));
}
g_Metrics.FileCount++; // our memdb
if (!FindDestination (&destination, 60, FALSE)) {
if (!IsmCheckCancel()) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
}
__leave;
}
if (!ConnectToDestination (&destination, &g_Metrics, &g_Connection)) {
if (!IsmCheckCancel()) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
}
__leave;
}
numTry = 0;
do {
// now we connected to the destination. Let's pop up a dialog asking the user to
// type in the password that the destination has.
if (!pAskForPassword (g_GlobalKey, 33)) {
// let's tell the destination computer that we are bailing out.
SendMessageToDestination (&g_Connection, MESSAGE_CANCEL);
// BUGBUG - better error message
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
if (!SendDataToDestination (&g_Connection, g_GlobalKey, SizeOfStringA (g_GlobalKey))) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
message = ReceiveFromSource (&g_Connection, NULL, NULL, 0);
if (message == MESSAGE_PASSWORDWRONG) {
numTry ++;
if (numTry >= 3) {
// let's tell the destination computer that we are bailing out.
SendMessageToDestination (&g_Connection, MESSAGE_CANCEL);
// BUGBUG - better error message
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
}
} while (message == MESSAGE_PASSWORDWRONG);
if (message != MESSAGE_PASSWORDOK) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
}
//
// Enumerate all objects with "save" attribute
//
if (IsmEnumFirstPersistentObject (&objEnum)) {
do {
//
// Send keep-alive to connection every 30 seconds of idle time
//
if (!Compressed) {
if (GetTickCount() - g_Connection.LastSend > g_Connection.KeepAliveSpacing) {
SendMessageToDestination (&g_Connection, MESSAGE_KEEP_ALIVE);
}
}
//
// For each object to be saved, do the appropriate
// data copy action
//
okSave = FALSE;
while (!okSave) {
if (!IsmAcquireObjectEx (
objEnum.ObjectTypeId,
objEnum.ObjectName,
&value,
CONTENTTYPE_ANY,
0
)) {
transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
transCopyError.Error = GetLastError ();
if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
appReply = APPRESPONSE_IGNORE;
} else {
appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
if ((appReply == APPRESPONSE_NONE) ||
(appReply == APPRESPONSE_FAIL)
) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
IsmAbortPersistentObjectEnum (&objEnum);
__leave;
}
}
if (appReply == APPRESPONSE_IGNORE) {
LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
break;
}
IsmReleaseMemory (transCopyError.ObjectName);
continue;
}
okSave = TRUE;
}
if (okSave) {
#ifdef UNICODE
convValue = &value;
#else
// now let's convert this object content to UNICODE
convValue = IsmConvertObjectContentToUnicode (objEnum.ObjectTypeId, objEnum.ObjectName, &value);
if (!convValue) {
convValue = &value;
}
#endif
decoratedObject = BuildDecoratedObject (objEnum.ObjectTypeId, objEnum.ObjectName);
ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
appInfo.Phase = MIG_TRANSPORT_PHASE;
if (Compressed) {
appInfo.SubPhase = SUBPHASE_COMPRESSING;
} else {
appInfo.SubPhase = SUBPHASE_TRANSPORTING;
}
appInfo.ObjectTypeId = (objEnum.ObjectTypeId & (~PLATFORM_MASK));
appInfo.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
if (convValue->ContentInFile) {
okSave = FALSE;
while (!okSave) {
if (!pHomeNetSaveContentInFile (
objEnum.ObjectTypeId,
objEnum.ObjectName,
decoratedObject,
convValue,
cabHandle
)) {
if (GetLastError () == ERROR_NETWORK_UNREACHABLE) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
IsmAbortPersistentObjectEnum (&objEnum);
__leave;
}
transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
transCopyError.Error = GetLastError ();
if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
appReply = APPRESPONSE_IGNORE;
} else {
appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
if ((appReply == APPRESPONSE_NONE) ||
(appReply == APPRESPONSE_FAIL)
) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
IsmAbortPersistentObjectEnum (&objEnum);
__leave;
}
}
if (appReply == APPRESPONSE_IGNORE) {
LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
break;
}
IsmReleaseMemory (transCopyError.ObjectName);
continue;
}
okSave = TRUE;
}
size = convValue->FileContent.ContentSize;
} else {
okSave = FALSE;
while (!okSave) {
if (!pHomeNetSaveContentInMemory (objEnum.ObjectTypeId, objEnum.ObjectName, decoratedObject, convValue)) {
transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
transCopyError.Error = GetLastError ();
if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
appReply = APPRESPONSE_IGNORE;
} else {
appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
if ((appReply == APPRESPONSE_NONE) ||
(appReply == APPRESPONSE_FAIL)
) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
IsmAbortPersistentObjectEnum (&objEnum);
__leave;
}
}
if (appReply == APPRESPONSE_IGNORE) {
LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
extraData.Error = ERRUSER_ERROR_CANTSAVEOBJECT;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = objEnum.ObjectTypeId;
extraData.ObjectName = objEnum.ObjectName;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYWARNING, (ULONG_PTR)(&extraData));
break;
}
IsmReleaseMemory (transCopyError.ObjectName);
continue;
}
okSave = TRUE;
}
size = convValue->MemoryContent.ContentSize;
}
#ifndef UNICODE
if (convValue != (&value)) {
IsmFreeConvertedObjectContent (objEnum.ObjectTypeId, convValue);
}
#endif
IsmReleaseObject (&value);
DestroyDecoratedObject (decoratedObject);
decoratedObject = NULL;
}
IsmTickProgressBar (g_PersistentSlice, 1);
//
// Send bytes saved to app every 3 seconds
//
bytesSaved += size;
if (GetTickCount() - lastTick > 3000) {
if (bytesSaved < 1048576) {
argArray[0] = (PCTSTR) (UINT_PTR) (bytesSaved / 1024);
statusMsg = ParseMessageID (MSG_SAVED_K, argArray);
} else if (bytesSaved < 8388608) {
fraction = (UINT) (bytesSaved / 10485);
argArray[0] = (PCTSTR) (UINT_PTR) (fraction / 100);
argArray[1] = (PCTSTR) (UINT_PTR) (fraction % 100);
statusMsg = ParseMessageID (MSG_SAVED_M, argArray);
} else if (bytesSaved < 1073741824) {
argArray[0] = (PCTSTR) (UINT_PTR) (bytesSaved / 1048576);
statusMsg = ParseMessageID (MSG_SAVED_M2, argArray);
} else {
fraction = (UINT) (bytesSaved / 10737418);
argArray[0] = (PCTSTR) (UINT_PTR) (fraction / 100);
argArray[1] = (PCTSTR) (UINT_PTR) (fraction % 100);
statusMsg = ParseMessageID (MSG_SAVED_G, argArray);
}
IsmSendMessageToApp (TRANSPORTMESSAGE_SIZE_SAVED, (ULONG_PTR) statusMsg);
FreeStringResource (statusMsg);
lastTick = GetTickCount();
}
} while (IsmEnumNextPersistentObject (&objEnum));
}
ourDbFile = AllocStorageFileName (S_TRANSPORT_DAT_FILE);
if (!ourDbFile) {
extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
DEBUGMSG ((DBG_HOMENET, "Saving memdb"));
BfCreateDirectory (g_TransportTempDir);
if (!MemDbSave (ourDbFile)) {
DEBUGMSG ((DBG_ERROR, "Can't save our database to %s", ourDbFile));
extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
if (Compressed) {
if (!pHomeNetAddFileToImage (ourDbFile, S_TRANSPORT_DAT_FILE, cabHandle)) {
extraData.Error = ERRUSER_ERROR_CANTSAVEINTERNALDATA;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
if (!CabFlushAndCloseCabinetEx (cabHandle, NULL, NULL, &fileCount, &fileSize)) {
extraData.Error = ERRUSER_ERROR_CANTCREATECABFILE;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
DEBUGMSG ((DBG_HOMENET, "Compression results: files=%u size=%u", fileCount, (UINT) fileSize));
g_Metrics.FileCount += fileCount;
g_Metrics.TotalSize += fileSize;
ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
appInfo.Phase = MIG_TRANSPORT_PHASE;
appInfo.SubPhase = SUBPHASE_CONNECTING1;
IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
if (!FindDestination (&destination, 0, FALSE)) {
if (!IsmCheckCancel()) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
}
__leave;
}
if (!ConnectToDestination (&destination, &g_Metrics, &g_Connection)) {
if (!IsmCheckCancel()) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CONNECT_TO_DESTINATION));
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
}
__leave;
}
ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
appInfo.Phase = MIG_TRANSPORT_PHASE;
appInfo.SubPhase = SUBPHASE_FINISHING;
IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
if (!pHomeNetWriteAllImages ()) {
extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
} else {
ZeroMemory (&appInfo, sizeof (MIG_APPINFO));
appInfo.Phase = MIG_TRANSPORT_PHASE;
appInfo.SubPhase = SUBPHASE_FINISHING;
IsmSendMessageToApp (ISMMESSAGE_APP_INFO, (ULONG_PTR)(&appInfo));
DEBUGMSG ((DBG_HOMENET, "Transporting memdb"));
if (!pTransportFile (ourDbFile, ourDbFile)) {
if (GetLastError () == ERROR_NETWORK_UNREACHABLE) {
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
} else {
extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
}
}
DEBUGMSG ((DBG_HOMENET, "Transporting status file"));
pSetTransportStatus (g_StatusFileHandle, g_CompressData, TRSTATUS_READY);
CloseHandle (g_StatusFileHandle);
g_StatusFileHandle = INVALID_HANDLE_VALUE;
if (!pTransportFile (g_StatusFile, g_StatusFile)) {
if (GetLastError () == ERROR_NETWORK_UNREACHABLE) {
extraData.Error = ERRUSER_ERROR_CANTFINDDESTINATION;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
} else {
extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
}
DEBUGMSG ((DBG_HOMENET, "Done sending files"));
SendMessageToDestination (&g_Connection, MESSAGE_DONE);
if (MESSAGE_DONE != ReceiveFromSource (&g_Connection, NULL, NULL, 0)) {
if (GetLastError() != WSAECONNRESET) {
DEBUGMSG ((DBG_ERROR, "No acknowledgement from the destination"));
extraData.Error = ERRUSER_ERROR_CANTSENDTODEST;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
extraData.ObjectTypeId = 0;
extraData.ObjectName = NULL;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
__leave;
}
}
IsmSendMessageToApp (TRANSPORTMESSAGE_SIZE_SAVED, 0);
result = TRUE;
}
__finally {
PushError ();
FreeStorageFileName (ourDbFile);
INVALID_POINTER (ourDbFile);
DestroyDecoratedObject (decoratedObject);
INVALID_POINTER (decoratedObject);
CloseConnection (&g_Connection);
PopError ();
}
return result;
}
BOOL
WINAPI
HomeNetTransportSaveState (
VOID
)
{
ERRUSER_EXTRADATA extraData;
g_Platform = PLATFORM_SOURCE;
ZeroMemory (&extraData, sizeof (ERRUSER_EXTRADATA));
extraData.Error = ERRUSER_ERROR_UNKNOWN;
g_StatusFileHandle = BfCreateFile (g_StatusFile);
if (g_StatusFileHandle == INVALID_HANDLE_VALUE) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_NET_STATUS_FILE));
extraData.Error = ERRUSER_ERROR_NOTRANSPORTPATH;
extraData.ErrorArea = ERRUSER_AREA_SAVE;
IsmSendMessageToApp (MODULEMESSAGE_DISPLAYERROR, (ULONG_PTR)(&extraData));
return FALSE;
}
return pSaveAllState (g_CompressData);
}