/*++ 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: --*/ // // 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("")); } 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; }