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.
 
 
 
 
 
 

1184 lines
40 KiB

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
inftrans.c
Abstract:
Implements a basic secure server transport module
Author:
Jim Schmidt (jimschm) 08-Mar-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "logmsg.h"
#define DBG_INFTRANS "InfTrans"
//
// Strings
//
#define S_TRANSPORT_DIR TEXT("USMT2I.UNC")
#define S_TRANSPORT_INF_FILE TEXT("migration.inf")
#define S_TRANSPORT_STATUS_FILE TEXT("status")
#define S_DETAILS_PREFIX TEXT("details")
#define S_DATABASEFILE_LITE TEXT("|MainDatabaseFile\\LITE") // pipe is to decorate for uniqueness
//
// Constants
//
#define TRFLAG_FILE 0x01
#define TRFLAG_MEMORY 0x02
#define INFTR_SIG 0x55534D32 //USM2
#define TRSTATUS_DIRTY 0x00000001
#define TRSTATUS_READY 0x00000002
#define TRSTATUS_LOCKED 0x00000003
//
// Macros
//
// None
//
// Types
//
typedef struct {
TCHAR TempFile [MAX_PATH];
PCVOID AllocPtr;
PCVOID DetailsPtr;
HANDLE FileHandle;
HANDLE MapHandle;
} ALLOCSTATE, *PALLOCSTATE;
//
// Globals
//
MIG_TRANSPORTSTORAGEID g_ReliableStorageId;
PCTSTR g_InfTransTransportPath = NULL;
PCTSTR g_InfTransTransportStatus = NULL;
HANDLE g_InfTransTransportStatusHandle = NULL;
UINT g_Platform;
MIG_PROGRESSSLICEID g_DatabaseSlice;
MIG_PROGRESSSLICEID g_PersistentSlice;
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// see unctrans.h
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL
pSetInfTransStatus (
IN HANDLE TrJournalHandle,
IN DWORD Status
)
{
DWORD signature = INFTR_SIG;
BOOL result = FALSE;
if (BfSetFilePointer (TrJournalHandle, 0)) {
result = TRUE;
result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&signature), sizeof (DWORD));
result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&Status), sizeof (DWORD));
result = result && FlushFileBuffers (TrJournalHandle);
}
return TRUE;
}
DWORD
pGetInfTransStatus (
IN PCTSTR TrJournal
)
{
HANDLE trJrnHandle;
DWORD signature = 0;
DWORD result = 0;
if (TrJournal && TrJournal [0]) {
trJrnHandle = BfOpenReadFile (TrJournal);
if (trJrnHandle) {
if (BfSetFilePointer (trJrnHandle, 0)) {
if (BfReadFile (trJrnHandle, (PBYTE)(&signature), sizeof (DWORD))) {
if (signature == INFTR_SIG) {
if (!BfReadFile (trJrnHandle, (PBYTE)(&result), sizeof (DWORD))) {
result = 0;
}
}
}
}
CloseHandle (trJrnHandle);
} else {
if (GetLastError () == ERROR_ACCESS_DENIED) {
result = TRSTATUS_LOCKED;
}
}
}
return result;
}
BOOL
WINAPI
InfTransTransportInitialize (
IN PMIG_LOGCALLBACK LogCallback
)
{
//
// Initialize globals
//
LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
g_ReliableStorageId = IsmRegisterTransport (S_RELIABLE_STORAGE_TRANSPORT);
return TRUE;
}
VOID
WINAPI
InfTransTransportEstimateProgressBar (
MIG_PLATFORMTYPEID PlatformTypeId
)
{
DEBUGMSG ((DBG_VERBOSE, "Assuming transport download has no progress impact"));
}
BOOL
WINAPI
InfTransTransportQueryCapabilities (
IN MIG_TRANSPORTSTORAGEID TransportStorageId,
OUT PMIG_TRANSPORTTYPE TransportType,
OUT PMIG_TRANSPORTCAPABILITIES Capabilities,
OUT PCTSTR *FriendlyDescription
)
{
if (TransportStorageId != g_ReliableStorageId) {
return FALSE;
}
*TransportType = TRANSPORTTYPE_LIGHT;
*Capabilities = 0;
*FriendlyDescription = TEXT("Another Computer on the Network");
return TRUE;
}
BOOL
WINAPI
InfTransTransportSetStorage (
IN MIG_PLATFORMTYPEID Platform,
IN MIG_TRANSPORTSTORAGEID TransportStorageId,
IN MIG_TRANSPORTCAPABILITIES RequiredCapabilities,
IN PCTSTR StoragePath,
OUT PBOOL Valid,
OUT PBOOL ImageExists
)
{
PCTSTR transportPath;
PCTSTR transportStatus;
MIG_OBJECTSTRINGHANDLE encodedPath;
DWORD status;
BOOL result = FALSE;
if (Valid) {
*Valid = FALSE;
}
if (ImageExists) {
*ImageExists = FALSE;
}
if (TransportStorageId == g_ReliableStorageId && !RequiredCapabilities) {
transportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
transportStatus = JoinPaths (transportPath, S_TRANSPORT_STATUS_FILE);
if (!DoesFileExist (transportPath)) {
// we require UNC path or a full path (like c:\...)
if (transportPath[0] == '\\' && transportPath[1] == '\\') {
// this is a UNC path
*Valid = TRUE;
} else if (transportPath[1] == ':') {
// this is a normal full path
*Valid = TRUE;
} else {
*Valid = FALSE;
}
*ImageExists = FALSE;
} else {
status = pGetInfTransStatus (transportStatus);
switch (status) {
case TRSTATUS_LOCKED:
*ImageExists = TRUE;
*Valid = FALSE;
break;
case TRSTATUS_READY:
*ImageExists = TRUE;
*Valid = TRUE;
break;
case TRSTATUS_DIRTY:
*ImageExists = FALSE;
*Valid = TRUE;
break;
default:
*ImageExists = FALSE;
*Valid = TRUE;
}
}
FreePathString (transportStatus);
FreePathString (transportPath);
result = TRUE;
}
if (result && *Valid) {
if (g_InfTransTransportPath) {
FreePathString (g_InfTransTransportPath);
g_InfTransTransportPath = NULL;
}
g_InfTransTransportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
g_InfTransTransportStatus = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_STATUS_FILE);
encodedPath = IsmCreateSimpleObjectPattern (g_InfTransTransportPath, FALSE, NULL, FALSE);
if (encodedPath) {
IsmRegisterStaticExclusion (MIG_FILE_TYPE, encodedPath);
IsmDestroyObjectHandle (encodedPath);
}
}
return result;
}
BOOL
pInfTransSaveDetails (
IN PCTSTR DecoratedObject,
IN PMIG_DETAILS Details
)
{
PCTSTR key;
BOOL b;
if ((!Details) || (!Details->DetailsSize)) {
return TRUE;
}
key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
FreeText (key);
return b;
}
PCTSTR
pInfTransBuildDecoratedObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE ObjectName
)
{
TCHAR prefix[32];
wsprintf (prefix, TEXT("%u"), ObjectTypeId & (~PLATFORM_MASK));
return JoinPaths (prefix, ObjectName);
}
VOID
pInfTransDestroyDecoratedObject (
IN PCTSTR String
)
{
FreePathString (String);
}
BOOL
pObjectNameToFileName (
IN MIG_OBJECTSTRINGHANDLE ObjectName,
OUT PCTSTR *FileName,
OUT PCTSTR *DirName OPTIONAL
)
{
PCTSTR node, leaf;
PCTSTR newNode, dirName;
BOOL result = FALSE;
if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
newNode = StringSearchAndReplace (node, TEXT(":"), TEXT(""));
if (newNode) {
result = TRUE;
if (leaf) {
dirName = JoinPaths (g_InfTransTransportPath, newNode);
*FileName = JoinPaths (dirName, leaf);
if (!DirName) {
FreePathString (dirName);
} else {
*DirName = dirName;
}
FreePathString (newNode);
} else {
*FileName = JoinPaths (g_InfTransTransportPath, newNode);
if (DirName) {
*DirName = *FileName;
}
FreePathString (newNode);
}
} else {
dirName = JoinPaths (g_InfTransTransportPath, node);
*FileName = JoinPaths (dirName, leaf);
FreePathString (dirName);
if (DirName) {
*DirName = JoinPaths (g_InfTransTransportPath, node);
}
result = TRUE;
}
IsmDestroyObjectString (node);
IsmDestroyObjectString (leaf);
}
return result;
}
BOOL
pIsShortFileName (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN MIG_OBJECTSTRINGHANDLE ObjectName,
IN PCTSTR TempDir
)
{
PCTSTR nativeFileName;
PCTSTR fileNamePtr;
PCTSTR testFileName;
HANDLE fileHandle;
WIN32_FIND_DATA fileInfo;
BOOL result = FALSE;
nativeFileName = IsmGetNativeObjectName (ObjectTypeId, ObjectName);
if (nativeFileName) {
fileNamePtr = GetFileNameFromPath (nativeFileName);
if (fileNamePtr) {
testFileName = JoinPaths (TempDir, fileNamePtr);
fileHandle = BfCreateFile (testFileName);
if (fileHandle) {
CloseHandle (fileHandle);
if (DoesFileExistEx (testFileName, &fileInfo)) {
result = (fileInfo.cAlternateFileName [0] == 0) ||
StringIMatch (fileInfo.cFileName, fileInfo.cAlternateFileName);
}
DeleteFile (testFileName);
}
}
IsmReleaseMemory (nativeFileName);
}
return result;
}
BOOL
WINAPI
InfTransTransportSaveState (
VOID
)
{
MIG_OBJECTTYPEID objectTypeId;
MIG_OBJECT_ENUM objEnum;
MIG_OBJECTSTRINGHANDLE objectPattern = NULL;
MIG_OBJECTSTRINGHANDLE objectName = NULL;
MIG_CONTENT objectContent;
PCTSTR infFile = NULL;
HANDLE infFileHandle = NULL;
PCTSTR objMultiSz;
MULTISZ_ENUM multiSzEnum;
BOOL firstMultiSz;
PCTSTR fileName;
PCTSTR dirName;
DWORD status;
MIG_OBJECTTYPEID dataTypeId;
MIG_OBJECTTYPEID fileTypeId;
TCHAR tempDir [MAX_PATH] = TEXT("");
BOOL firstPass = TRUE;
BOOL process = TRUE;
#ifdef DEBUG
PCTSTR nativeObjectName;
#endif
INT_PTR appReply;
BOOL okSave = FALSE;
TRANSCOPY_ERROR transCopyError;
PTSTR encodedString = NULL;
BOOL result = FALSE;
GROWBUFFER writeBuffer = INIT_GROWBUFFER;
if (DoesFileExist (g_InfTransTransportPath)) {
status = pGetInfTransStatus (g_InfTransTransportStatus);
switch (status) {
case TRSTATUS_LOCKED:
SetLastError (ERROR_ACCESS_DENIED);
LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, g_InfTransTransportPath));
return FALSE;
case TRSTATUS_DIRTY:
result = FiRemoveAllFilesInTree (g_InfTransTransportPath);
if (!result) {
PushError ();
SetLastError (ERROR_ACCESS_DENIED);
LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, g_InfTransTransportPath));
PopError ();
return FALSE;
}
break;
case TRSTATUS_READY:
default:
if (IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_EXISTS, 0)) {
result = FiRemoveAllFilesInTree (g_InfTransTransportPath);
if (!result) {
PushError ();
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_EMPTY_DIR , g_InfTransTransportPath));
PopError ();
return FALSE;
}
} else {
LOG ((LOG_ERROR, (PCSTR) MSG_NOT_EMPTY, g_InfTransTransportPath));
SetLastError (ERROR_ALREADY_EXISTS);
return FALSE;
}
break;
}
}
if (!BfCreateDirectory (g_InfTransTransportPath)) {
PushError ();
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_DIR, g_InfTransTransportPath));
PopError ();
return FALSE;
}
g_InfTransTransportStatusHandle = BfCreateFile (g_InfTransTransportStatus);
if (!g_InfTransTransportStatusHandle) {
PushError ();
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_STATUS_FILE, g_InfTransTransportStatus));
PopError ();
return FALSE;
}
pSetInfTransStatus (g_InfTransTransportStatusHandle, TRSTATUS_DIRTY);
__try {
IsmGetTempDirectory (tempDir, MAX_PATH);
g_Platform = PLATFORM_SOURCE;
objectName = IsmCreateObjectHandle (S_DATABASEFILE_LITE, NULL);
if (IsmAcquireObjectEx (
MIG_DATA_TYPE | PLATFORM_SOURCE,
objectName,
&objectContent,
CONTENTTYPE_FILE,
0
)) {
// we have the database file, we assume it's an INF file
// and we copy it to our transport location with the
// migration.inf name.
infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
if (!CopyFile (objectContent.FileContent.ContentPath, infFile, FALSE)) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_SAVE_ISM_INF));
__leave;
}
IsmReleaseObject (&objectContent);
} else {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
__leave;
}
infFileHandle = BfOpenFile (infFile);
if (!infFileHandle) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
__leave;
}
BfGoToEndOfFile (infFileHandle, 0);
objectPattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
objectTypeId = IsmGetFirstObjectTypeId ();
dataTypeId = MIG_DATA_TYPE;
fileTypeId = MIG_FILE_TYPE;
while (objectTypeId) {
if (firstPass) {
WriteFileString (infFileHandle, TEXT("["));
WriteFileString (infFileHandle, IsmGetObjectTypeName (objectTypeId));
WriteFileString (infFileHandle, TEXT("]\r\n"));
}
if (IsmEnumFirstSourceObjectEx (&objEnum, objectTypeId, objectPattern, TRUE)) {
do {
writeBuffer.End = 0;
if (IsmCheckCancel()) {
IsmAbortObjectEnum (&objEnum);
__leave;
}
if (objectTypeId == dataTypeId && StringIMatch(objEnum.ObjectName, objectName)) {
continue;
}
if (IsmIsPersistentObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
process = TRUE;
if (objectTypeId == fileTypeId) {
if (firstPass) {
process = pIsShortFileName (objectTypeId, objEnum.ObjectName, tempDir);
} else {
process = !pIsShortFileName (objectTypeId, objEnum.ObjectName, tempDir);
}
}
if (process) {
#ifdef DEBUG
nativeObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
DEBUGMSG ((DBG_INFTRANS, "Transporting: %s", nativeObjectName));
IsmReleaseMemory (nativeObjectName);
#endif
okSave = FALSE;
while (!okSave) {
if (!IsmAcquireObjectEx (
objEnum.ObjectTypeId,
objEnum.ObjectName,
&objectContent,
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)
) {
IsmAbortObjectEnum (&objEnum);
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
IsmAbortObjectEnum (&objEnum);
__leave;
}
}
if (appReply == APPRESPONSE_IGNORE) {
LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
break;
}
IsmReleaseMemory (transCopyError.ObjectName);
continue;
}
okSave = TRUE;
}
if (okSave) {
// we have an object let's write it to the migration.inf
objMultiSz = IsmConvertObjectToMultiSz (
objEnum.ObjectName,
&objectContent
);
if (objMultiSz) {
if (EnumFirstMultiSz (&multiSzEnum, objMultiSz)) {
firstMultiSz = TRUE;
do {
if (firstMultiSz) {
firstMultiSz = FALSE;
} else {
GbAppendString (&writeBuffer, TEXT(","));
}
encodedString = AllocPathString (SizeOfString (multiSzEnum.CurrentString) * 6);
if (EncodeRuleCharsEx (encodedString, multiSzEnum.CurrentString, TEXT("~\r\n")) != NULL) {
GbAppendString (&writeBuffer, encodedString);
} else {
GbAppendString (&writeBuffer, multiSzEnum.CurrentString);
}
FreePathString (encodedString);
} while (EnumNextMultiSz (&multiSzEnum));
GbAppendString (&writeBuffer, TEXT("\r\n"));
}
IsmReleaseMemory (objMultiSz);
if (objectContent.ContentInFile) {
if (objectContent.FileContent.ContentPath) {
// transform the object name into a file name and copy the
// content file there
if (!pObjectNameToFileName (objEnum.ObjectName, &fileName, &dirName)) {
LOG ((
LOG_ERROR,
(PCSTR) MSG_COPYFILE_FAILURE,
objectContent.FileContent.ContentPath,
fileName
));
IsmAbortObjectEnum (&objEnum);
__leave;
}
if (!BfCreateDirectory (dirName)) {
LOG ((
LOG_ERROR,
(PCSTR) MSG_CREATE_FAILURE,
dirName,
objectContent.FileContent.ContentPath
));
IsmAbortObjectEnum (&objEnum);
__leave;
}
okSave = FALSE;
while (!okSave) {
if (!CopyFile (objectContent.FileContent.ContentPath, fileName, TRUE)) {
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);
IsmAbortObjectEnum (&objEnum);
__leave;
}
}
if (appReply == APPRESPONSE_IGNORE) {
LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
IsmReleaseMemory (transCopyError.ObjectName);
break;
}
IsmReleaseMemory (transCopyError.ObjectName);
continue;
}
okSave = TRUE;
}
if (dirName != fileName) {
FreePathString (dirName);
}
FreePathString (fileName);
}
}
} else {
GbAppendString (&writeBuffer, TEXT("\r\n"));
}
IsmReleaseObject (&objectContent);
}
WriteFileString (infFileHandle, (PTSTR) writeBuffer.Buf);
}
}
} while (IsmEnumNextObject (&objEnum));
}
if (!firstPass || objectTypeId != fileTypeId) {
WriteFileString (infFileHandle, TEXT("\r\n\r\n"));
}
if ((objectTypeId == fileTypeId) && firstPass) {
firstPass = FALSE;
} else {
objectTypeId = IsmGetNextObjectTypeId (objectTypeId);
firstPass = TRUE;
}
}
result = TRUE;
}
__finally {
if (tempDir [0]) {
FiRemoveAllFilesInTree (tempDir);
}
IsmDestroyObjectHandle (objectName);
if (infFileHandle != NULL) {
CloseHandle (infFileHandle);
}
IsmDestroyObjectHandle (objectPattern);
FreePathString (infFile);
INVALID_POINTER (infFile);
}
if (result) {
pSetInfTransStatus (g_InfTransTransportStatusHandle, TRSTATUS_READY);
}
CloseHandle (g_InfTransTransportStatusHandle);
g_InfTransTransportStatusHandle = NULL;
GbFree (&writeBuffer);
if (!result) {
FiRemoveAllFilesInTree (g_InfTransTransportPath);
}
return result;
}
BOOL
pSaveObjectContent (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN PCTSTR ObjectName,
IN PCTSTR DecoratedObject,
IN PMIG_CONTENT ObjectContent
)
{
PCTSTR fileName;
BOOL result = FALSE;
if (ObjectContent->ContentInFile) {
MemDbSetValue (DecoratedObject, TRFLAG_FILE);
if (pObjectNameToFileName (ObjectName, &fileName, NULL)) {
if (DoesFileExist (fileName)) {
MemDbAddSingleLinkage (DecoratedObject, fileName, 0);
}
FreePathString (fileName);
}
} else {
MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
if (ObjectContent->MemoryContent.ContentSize &&
ObjectContent->MemoryContent.ContentBytes
) {
MemDbSetUnorderedBlob (
DecoratedObject,
0,
ObjectContent->MemoryContent.ContentBytes,
ObjectContent->MemoryContent.ContentSize
);
}
}
result = pInfTransSaveDetails (DecoratedObject, &(ObjectContent->Details));
return result;
}
BOOL
WINAPI
InfTransTransportBeginApply (
VOID
)
{
PCTSTR infFile;
HINF infHandle;
INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
MIG_OBJECTTYPEID objectTypeId;
GROWBUFFER buff = INIT_GROWBUFFER;
PCTSTR field;
MIG_CONTENT objectContent;
MIG_OBJECTSTRINGHANDLE objectName;
UINT index;
PCTSTR decoratedObject = NULL;
DWORD status = 0;
PTSTR decodedString = NULL;
g_Platform = PLATFORM_DESTINATION;
while (status != TRSTATUS_READY) {
status = pGetInfTransStatus (g_InfTransTransportStatus);
switch (status) {
case TRSTATUS_LOCKED:
if (!IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_LOCKED, 0)) {
LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY , g_InfTransTransportPath));
SetLastError (ERROR_ACCESS_DENIED);
return FALSE;
}
break;
case TRSTATUS_DIRTY:
SetLastError (ERROR_ACCESS_DENIED);
LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_InfTransTransportPath));
return FALSE;
case TRSTATUS_READY:
break;
default:
SetLastError (ERROR_INVALID_DATA);
LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_InfTransTransportPath));
return FALSE;
}
}
g_InfTransTransportStatusHandle = BfOpenReadFile (g_InfTransTransportStatus);
if (!g_InfTransTransportStatusHandle) {
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_STATUS_FILE, g_InfTransTransportStatus));
return FALSE;
}
infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
// add the database file in memdb so we can serve AcquireObject from the ISM
objectName = IsmCreateObjectHandle (S_DATABASEFILE_LITE, NULL);
decoratedObject = pInfTransBuildDecoratedObject (MIG_DATA_TYPE | PLATFORM_SOURCE, objectName);
MemDbSetValue (decoratedObject, TRFLAG_FILE);
MemDbAddSingleLinkage (decoratedObject, infFile, 0);
pInfTransDestroyDecoratedObject (decoratedObject);
IsmDestroyObjectHandle (objectName);
infHandle = InfOpenInfFile (infFile);
if (infHandle == INVALID_HANDLE_VALUE) {
SetLastError (ERROR_FILE_NOT_FOUND);
LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_ISM_INF, infFile));
FreePathString (infFile);
return FALSE;
}
objectTypeId = IsmGetFirstObjectTypeId ();
while (objectTypeId) {
if (InfFindFirstLine (infHandle, IsmGetObjectTypeName (objectTypeId), NULL, &is)) {
do {
index = 1;
buff.End = 0;
for (;;) {
field = InfGetStringField (&is, index);
if (!field) {
break;
}
if (*field) {
decodedString = DuplicatePathString (field, 0);
if (DecodeRuleChars (decodedString, field) != NULL) {
GbCopyString (&buff, decodedString);
} else {
GbCopyString (&buff, field);
}
FreePathString (decodedString);
} else {
GbCopyString (&buff, TEXT("<empty>"));
}
index ++;
}
if (buff.End) {
GbCopyString (&buff, TEXT(""));
if (IsmConvertMultiSzToObject (
objectTypeId,
(PCTSTR)buff.Buf,
&objectName,
&objectContent
)) {
// now save the object data into our database
// for future reference
decoratedObject = pInfTransBuildDecoratedObject (objectTypeId | PLATFORM_SOURCE, objectName);
pSaveObjectContent (objectTypeId | g_Platform, objectName, decoratedObject, &objectContent);
pInfTransDestroyDecoratedObject (decoratedObject);
IsmDestroyObjectHandle (objectName);
if ((objectContent.Details.DetailsSize) &&
(objectContent.Details.DetailsData)
) {
IsmReleaseMemory (objectContent.Details.DetailsData);
}
if (objectContent.ContentInFile) {
if (objectContent.FileContent.ContentPath) {
IsmReleaseMemory (objectContent.FileContent.ContentPath);
}
} else {
if ((objectContent.MemoryContent.ContentSize) &&
(objectContent.MemoryContent.ContentBytes)
) {
IsmReleaseMemory (objectContent.MemoryContent.ContentBytes);
}
}
}
}
} while (InfFindNextLine (&is));
}
objectTypeId = IsmGetNextObjectTypeId (objectTypeId);
}
GbFree (&buff);
InfCleanUpInfStruct (&is);
InfCloseInfFile (infHandle);
FreePathString (infFile);
return TRUE;
}
VOID
WINAPI
InfTransTransportEndApply (
VOID
)
{
MYASSERT (g_Platform == PLATFORM_DESTINATION);
CloseHandle (g_InfTransTransportStatusHandle);
g_InfTransTransportStatusHandle = NULL;
}
VOID
WINAPI
InfTransTransportTerminate (
VOID
)
{
if (g_InfTransTransportPath) {
FreePathString (g_InfTransTransportPath);
g_InfTransTransportPath = NULL;
}
if (g_InfTransTransportStatus) {
FreePathString (g_InfTransTransportStatus);
g_InfTransTransportStatus = NULL;
}
}
BOOL
WINAPI
InfTransTransportAcquireObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN MIG_OBJECTSTRINGHANDLE ObjectName,
OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
IN MIG_CONTENTTYPE ContentType,
IN UINT MemoryContentLimit
)
{
UINT value;
PCBYTE memValue;
UINT memValueSize;
PCTSTR fileValue = NULL;
BOOL valueInFile;
KEYHANDLE keyHandle;
PALLOCSTATE allocState;
PCTSTR detailsKey = NULL;
PBYTE details;
UINT detailsSize;
PCTSTR decoratedObject = NULL;
HANDLE fileHandle;
BOOL result = FALSE;
if (!ObjectContent) {
return FALSE;
}
MYASSERT (g_Platform == PLATFORM_DESTINATION);
MYASSERT ((ObjectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE);
decoratedObject = pInfTransBuildDecoratedObject (ObjectTypeId, ObjectName);
allocState = (PALLOCSTATE) MemAllocZeroed (sizeof (ALLOCSTATE));
if (MemDbGetValue (decoratedObject, &value)) {
if (value == TRFLAG_FILE) {
valueInFile = TRUE;
keyHandle = MemDbGetSingleLinkage (decoratedObject, 0, 0);
if (keyHandle) {
fileValue = MemDbGetKeyFromHandle (keyHandle, 0);
result = fileValue != NULL;
} else {
fileValue = NULL;
result = TRUE;
}
} else if (value == TRFLAG_MEMORY) {
valueInFile = FALSE;
memValueSize = 0;
memValue = MemDbGetUnorderedBlob (decoratedObject, 0, &memValueSize);
result = TRUE;
} else {
LOG ((LOG_ERROR, (PCSTR) MSG_UNSUPPORTED_DATA, value));
SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
}
if (result) {
result = FALSE;
if (valueInFile) {
if ((ContentType == CONTENTTYPE_ANY) ||
(ContentType == CONTENTTYPE_FILE) ||
(ContentType == CONTENTTYPE_DETAILS_ONLY)
) {
// this is stored as a file and it's wanted as a file
ObjectContent->ObjectTypeId = ObjectTypeId;
ObjectContent->ContentInFile = TRUE;
if (fileValue) {
ObjectContent->FileContent.ContentPath = DuplicatePathString (fileValue, 0);
ObjectContent->FileContent.ContentSize = BfGetFileSize (ObjectContent->FileContent.ContentPath);
} else {
ObjectContent->FileContent.ContentSize = 0;
ObjectContent->FileContent.ContentPath = NULL;
}
result = TRUE;
} else {
// this is stored as a file and it's wanted as memory
ObjectContent->ObjectTypeId = ObjectTypeId;
ObjectContent->ContentInFile = FALSE;
if (fileValue) {
ObjectContent->MemoryContent.ContentSize = (UINT) BfGetFileSize (fileValue);
ObjectContent->MemoryContent.ContentBytes = MapFileIntoMemory (
fileValue,
&allocState->FileHandle,
&allocState->MapHandle
);
result = (ObjectContent->MemoryContent.ContentBytes != NULL);
} else {
ObjectContent->MemoryContent.ContentSize = 0;
ObjectContent->MemoryContent.ContentBytes = NULL;
result = TRUE;
}
}
MemDbReleaseMemory (fileValue);
} else {
if ((ContentType == CONTENTTYPE_ANY) ||
(ContentType == CONTENTTYPE_MEMORY) ||
(ContentType == CONTENTTYPE_DETAILS_ONLY)
) {
// this is stored as memory and it's wanted as memory
ObjectContent->ObjectTypeId = ObjectTypeId;
ObjectContent->ContentInFile = FALSE;
ObjectContent->MemoryContent.ContentSize = memValueSize;
ObjectContent->MemoryContent.ContentBytes = memValue;
result = TRUE;
} else {
// this is stored as memory and it's wanted as a file
if (memValue) {
if (IsmGetTempFile (allocState->TempFile, ARRAYSIZE(allocState->TempFile))) {
fileHandle = BfCreateFile (allocState->TempFile);
if (fileHandle) {
if (BfWriteFile (fileHandle, memValue, memValueSize)) {
ObjectContent->ObjectTypeId = ObjectTypeId;
ObjectContent->ContentInFile = TRUE;
ObjectContent->FileContent.ContentSize = memValueSize;
ObjectContent->FileContent.ContentPath = DuplicatePathString (allocState->TempFile, 0);
result = TRUE;
}
CloseHandle (fileHandle);
}
}
MemDbReleaseMemory (memValue);
} else {
ObjectContent->ObjectTypeId = ObjectTypeId;
ObjectContent->ContentInFile = TRUE;
ObjectContent->FileContent.ContentSize = 0;
ObjectContent->FileContent.ContentPath = NULL;
}
}
}
}
} else {
SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
}
if (result) {
//
// Fill the details
//
detailsKey = JoinText (S_DETAILS_PREFIX, decoratedObject);
details = MemDbGetUnorderedBlob (detailsKey, 0, &detailsSize);
if (!details) {
detailsSize = 0;
}
allocState->DetailsPtr = details;
ObjectContent->Details.DetailsSize = detailsSize;
ObjectContent->Details.DetailsData = details;
FreeText (detailsKey);
ObjectContent->TransHandle = allocState;
}
if (!result) {
FreeAlloc (allocState);
}
FreePathString (decoratedObject);
return result;
}
BOOL
WINAPI
InfTransTransportReleaseObject (
IN OUT PMIG_CONTENT ObjectContent
)
{
PALLOCSTATE allocState;
MYASSERT (g_Platform == PLATFORM_DESTINATION);
allocState = (PALLOCSTATE) ObjectContent->TransHandle;
if (ObjectContent->ContentInFile) {
FreePathString (ObjectContent->FileContent.ContentPath);
if (allocState && allocState->TempFile[0]) {
DeleteFile (allocState->TempFile);
}
} else {
if (allocState && allocState->FileHandle && allocState->MapHandle) {
UnmapFile (
ObjectContent->MemoryContent.ContentBytes,
allocState->MapHandle,
allocState->FileHandle
);
} else {
MemDbReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
}
}
if (allocState && allocState->DetailsPtr) {
MemDbReleaseMemory (allocState->DetailsPtr);
}
FreeAlloc (allocState);
return TRUE;
}