#include "pch.h" #include #include #include #include #include #include #include #include #include #include #include "..\..\w95upg\migapp\migdbp.h" typedef BOOL (WINAPI INITROUTINE_PROTOTYPE)(HINSTANCE, DWORD, LPVOID); INITROUTINE_PROTOTYPE MigUtil_Entry; INITROUTINE_PROTOTYPE MemDb_Entry; INITROUTINE_PROTOTYPE MigApp_Entry; INITROUTINE_PROTOTYPE FileEnum_Entry; HINSTANCE g_hInst; HANDLE g_hHeap; BOOL g_CancelFlag = FALSE; #define ATTR_FILESIZE 0x1 #define ATTR_CHECKSUM 0x2 #define ATTR_COMPNAME 0x4 #define ATTR_FILEDESC 0x8 #define ATTR_FILEVER 0x10 #define ATTR_INTNAME 0x20 #define ATTR_LEGAL 0x40 #define ATTR_ORIGNAME 0x80 #define ATTR_PRODNAME 0x100 #define ATTR_PRODVER 0x200 #define ATTR_EXETYPE 0x400 #define ATTR_DESCR16 0x800 #ifdef DEBUG extern BOOL g_DoLog; #endif extern POOLHANDLE g_MigDbPool; extern PMIGDB_CONTEXT g_ContextList; extern VOID *g_FileTable; extern BOOL *g_CancelFlagPtr = &g_CancelFlag; extern POOLHANDLE g_PathsPool; extern PMIGDB_HOOK_PROTOTYPE g_MigDbHook; typedef struct _PATTERN_FILE { PCTSTR Pattern; PMIGDB_ATTRIB PatternAttr; struct _PATTERN_FILE *Next; } PATTERN_FILE, *PPATTERN_FILE; PPATTERN_FILE g_AttrPatterns = NULL; BOOL pScanForFile ( IN PINFCONTEXT Context, IN DWORD FieldIndex ); PMIGDB_ATTRIB pLoadAttribData ( IN PCSTR MultiSzStr ); BOOL CallAttribute ( IN PMIGDB_ATTRIB MigDbAttrib, IN PDBATTRIB_PARAMS AttribParams ); BOOL pWorkerFn ( VOID ); BOOL pLoadGoodFiles ( IN HINF ConfigHandle ); BOOL pLoadAttributes ( IN HINF ConfigHandle ); BOOL pLoadPatterns ( IN HINF ConfigHandle ); BOOL pHandleSection ( IN PCTSTR SectionName, IN HINF ConfigHandle ); BOOL pWriteMemdbSection ( IN PCTSTR FileName, IN PCTSTR MemDbCategory, IN PCTSTR SectName, IN BOOL WriteByValue ); BOOL pArrangeMigDbFile ( IN PCTSTR SrcFile, IN PCTSTR DestFile ); VOID pUsage ( VOID ) { _tprintf (TEXT ("\nCommand line syntax:\n\n" "migfiles [/B:BaseDir] [/T:TempDir] [/F[:SectionName]]\n\n" "/B Specifies the base directory where all migdb files are\n" " located. (migdb.inx, migdb.cfg)\n" "/L Specifies full path to FILELIST.DAT\n" "/T Specifies the temporary directory used for unpacking\n" " cabinet files\n" "/F Forces rescanning a particular section or all sections\n")); } PTSTR g_ConfigFile = NULL; PTSTR g_TempDir = NULL; PTSTR g_BaseDir = NULL; PTSTR g_MessageFile= NULL; PTSTR g_MigdbSrc = NULL; PTSTR g_MigdbDest = NULL; PTSTR g_MigdbDump = NULL; PTSTR g_HistoryFile= NULL; PTSTR g_RescanSect = NULL; BOOL g_RescanFlag = FALSE; extern HINF g_MigDbInf; GROWBUFFER g_SectFiles = GROWBUF_INIT; PTSTR g_FileListName = NULL; #define MEMDB_CATEGORY_SECTFILES TEXT("SectFiles") #define MEMDB_CATEGORY_GOODFILES TEXT("GoodFiles") #define MEMDB_CATEGORY_WARNFILES TEXT("WarnFiles") #define MEMDB_CATEGORY_DUPLFILES TEXT("DuplFiles") #define MEMDB_CATEGORY_ACTION TEXT("Action") #define MEMDB_CATEGORY_ATTRIBUTES TEXT("Attributes") #define MEMDB_CATEGORY_RENAME_SRC TEXT("RenameSrc") #define MEMDB_CATEGORY_RENAME_DEST TEXT("RenameDest") #define MEMDB_CATEGORY_REQFILES TEXT("RequiredFiles") void __cdecl main ( int argc, CHAR *argv[] ) { INT argidx, index; INT nextArg = 0; LONG rc; #ifdef DEBUG g_DoLog = TRUE; #endif g_hInst = GetModuleHandle (NULL); g_hHeap = GetProcessHeap(); if (!MigUtil_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) { _tprintf (TEXT("MigUtil failed initializing\n")); exit (1); } if (!MemDb_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) { _tprintf (TEXT("MemDb failed initializing\n")); exit(1); } if (!MigApp_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) { _tprintf (TEXT("MigApp failed initializing\n")); exit (1); } for (argidx = 1; argidx < argc; argidx++) { if ((argv[argidx][0] != '-') && (argv[argidx][0] != '/') ) { if (nextArg == 0) { pUsage (); exit (1); } switch (nextArg) { case 1: index = 0; goto label1; case 2: index = 0; goto label2; case 3: index = 0; goto label3; case 4: index = 0; goto label4; } } switch (toupper(argv[argidx][1])) { case 'B': if (argv[argidx][2] == 0) { nextArg = 1; } else { if (argv[argidx][2] != ':') { index = 2; } else { index = 3; } label1: nextArg = 0; g_BaseDir = AllocPathString (MAX_TCHAR_PATH); #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_BaseDir, MAX_TCHAR_PATH); #else _tcsncpy (g_BaseDir, argv[argidx]+index, MAX_TCHAR_PATH); #endif } break; case 'T': if (argv[argidx][2] == 0) { nextArg = 2; } else { if (argv[argidx][2] != ':') { index = 2; } else { index = 3; } label2: nextArg = 0; g_TempDir = AllocPathString (MAX_TCHAR_PATH); #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_TempDir, MAX_TCHAR_PATH); #else _tcsncpy (g_TempDir, argv[argidx]+index, MAX_TCHAR_PATH); #endif } break; case 'F': g_RescanFlag = TRUE; if (argv[argidx][2] == 0) { nextArg = 3; } else { if (argv[argidx][2] != ':') { index = 2; } else { index = 3; } label3: nextArg = 0; g_RescanSect = AllocPathString (MAX_TCHAR_PATH); #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_RescanSect, MAX_TCHAR_PATH); #else _tcsncpy (g_RescanSect, argv[argidx]+index, MAX_TCHAR_PATH); #endif } break; case 'L': if (argv[argidx][2] == 0) { nextArg = 4; } else { if (argv[argidx][2] != ':') { index = 2; } else { index = 3; } label4: nextArg = 0; g_FileListName = AllocPathString (MAX_TCHAR_PATH); #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_FileListName, MAX_TCHAR_PATH); #else _tcsncpy (g_FileListName, argv[argidx]+index, MAX_TCHAR_PATH); #endif } break; default: pUsage (); exit (1); } } if (g_BaseDir == NULL) { g_BaseDir = AllocPathString (MAX_TCHAR_PATH); _tcsncpy (g_BaseDir, TEXT(".\\"), MAX_TCHAR_PATH); } if (g_TempDir == NULL) { g_TempDir = AllocPathString (MAX_TCHAR_PATH); if (GetEnvironmentVariable (TEXT("TEMP"), g_TempDir, MAX_TCHAR_PATH) == 0) { GetTempPath (MAX_TCHAR_PATH, g_TempDir); } } g_ConfigFile = JoinPaths (g_BaseDir, TEXT("migdb.cfg")); g_MessageFile = JoinPaths (g_BaseDir, TEXT("migdb.msg")); g_HistoryFile = JoinPaths (g_BaseDir, TEXT("migdb.hst")); g_MigdbSrc = JoinPaths (g_BaseDir, TEXT("migdb.inx")); g_MigdbDest = JoinPaths (g_BaseDir, TEXT("migdb.tmp")); g_MigdbDump = JoinPaths (g_BaseDir, TEXT("migdb.dmp")); if (!DoesFileExist (g_FileListName)) { _tprintf (TEXT("\nNT file list file not found. Exiting.\n")); exit (1); } if (!DoesFileExist (g_MigdbSrc)) { _tprintf (TEXT("\nSource file not found. Exiting.\n")); exit (1); } if (!DoesFileExist (g_ConfigFile)) { _tprintf (TEXT("\nConfiguration file not found. Exiting.\n")); exit (1); } if (SearchPath (NULL, TEXT("extract.exe"), NULL, 0, NULL, NULL) == 0) { _tprintf (TEXT("\nCannot find extract.exe. Exiting.\n")); exit (1); } CopyFile (g_MigdbSrc, g_MigdbDest, FALSE); DeleteFile (g_MessageFile); DeleteFile (g_MigdbDump); DISABLETRACKCOMMENT(); g_InAnyDir = TRUE; _tprintf (TEXT("\nReading NT file list: %s"), g_FileListName); if (!ReadNtFilesEx (g_FileListName, FALSE)) { rc = GetLastError(); printf ("Could not read %s. Win32 Error Code: %x\n", g_FileListName, rc); exit (1); } _tprintf (TEXT("\nReading configuration files...")); if (!InitMigDbEx (g_MigdbSrc)) { rc = GetLastError(); printf ("Could not read %s. Win32 Error Code: %x\n", g_MigdbSrc, rc); exit (1); } DEBUGMSG ((DBG_ERROR , "TEST")); DEBUGMSG ((DBG_WHOOPS, "TEST")); pWorkerFn (); if (g_MigDbInf != INVALID_HANDLE_VALUE) { SetupCloseInfFile (g_MigDbInf); } pWriteMemdbSection (g_MessageFile, MEMDB_CATEGORY_GOODFILES, TEXT("KNOWN GOOD - FILES FOUND"), FALSE); pWriteMemdbSection (g_MessageFile, MEMDB_CATEGORY_WARNFILES, TEXT("KNOWN GOOD - NAME COLLISIONS"), FALSE); pWriteMemdbSection (g_MessageFile, MEMDB_CATEGORY_DUPLFILES, TEXT("DUPLICATE FILES"), FALSE); // we need now to arrange a little bit the MIGDB.INX file pArrangeMigDbFile (g_MigdbDest, g_MigdbSrc); DeleteFile (g_MigdbDest); if (g_FileTable != NULL) { HtFree (g_FileTable); } if (g_MigDbPool != NULL) { PoolMemDestroyPool (g_MigDbPool); } FreePathString (g_ConfigFile); FreePathString (g_TempDir); FreePathString (g_BaseDir); FreePathString (g_MessageFile); FreePathString (g_MigdbSrc); FreePathString (g_MigdbDest); FreePathString (g_MigdbDump); FreePathString (g_HistoryFile); g_InAnyDir = FALSE; ENABLETRACKCOMMENT(); if (!MigApp_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) { _tprintf (TEXT("MigApp failed initializing\n")); exit(1); } if (!MemDb_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) { _tprintf (TEXT("MemDb failed initializing\n")); exit(1); } if (!MigUtil_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) { _tprintf (TEXT("MigUtil failed initializing\n")); exit (1); } } UINT CALLBACK pCabinetCallback ( IN PVOID Context, //context used by the callback routine IN UINT Notification, //notification sent to callback routine IN UINT Param1, //additional notification information IN UINT Param2 //additional notification information ); ) { PCTSTR tempDir = Context; PCTSTR fileName = (PCTSTR)Param2 ; PFILE_IN_CABINET_INFO fileInfo = (PFILE_IN_CABINET_INFO)Param1; PCTSTR fromPtr, toPtr; TCHAR tempStr [MEMDB_MAX]; if (Notification == SPFILENOTIFY_FILEINCABINET) { if (toPtr = _tcschr (fileInfo->NameInCabinet, TEXT('\\'))) { _tcscpy (fileInfo->FullTargetName, tempDir); fromPtr = fileInfo->NameInCabinet; while (toPtr) { StringCopyAB (tempStr, fromPtr, toPtr); _tcscat (fileInfo->FullTargetName, TEXT("\\")); _tcscat (fileInfo->FullTargetName, tempStr); CreateDirectory (fileInfo->FullTargetName, NULL); toPtr = _tcsinc (toPtr); fromPtr = toPtr; toPtr = _tcschr (toPtr, TEXT('\\')); } } _stprintf (fileInfo->FullTargetName, TEXT("%s\\%s"), tempDir, fileInfo->NameInCabinet); return FILEOP_DOIT; } return NO_ERROR; } BOOL pWorkerFn ( VOID ) { HINF configHandle = INVALID_HANDLE_VALUE; INFCONTEXT context; TCHAR fileName [MAX_TCHAR_PATH] = ""; TCHAR sectName [MAX_TCHAR_PATH]; PTSTR dontCare; configHandle = SetupOpenInfFile (g_ConfigFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL); if (configHandle == INVALID_HANDLE_VALUE) { SearchPath (NULL, g_ConfigFile, NULL, MAX_TCHAR_PATH, fileName, &dontCare); configHandle = SetupOpenInfFile (fileName, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL); if (configHandle == INVALID_HANDLE_VALUE) { _tprintf (TEXT("\nCannot open configuration file %s. Exiting.\n"), g_ConfigFile); return FALSE; } } g_ContextList = (PMIGDB_CONTEXT) PoolMemGetMemory (g_MigDbPool, sizeof (MIGDB_CONTEXT)); if (g_ContextList == NULL) { DEBUGMSG ((DBG_ERROR, "Unable to create empty context")); return FALSE; } ZeroMemory (g_ContextList, sizeof (MIGDB_CONTEXT)); if (!pLoadGoodFiles (configHandle)) { _tprintf (TEXT("\nUnable to load good files section. Exiting.\n")); return FALSE; } if (!pLoadAttributes (configHandle)) { _tprintf (TEXT("\nUnable to load attributes section.\n")); } if (!pLoadPatterns (configHandle)) { _tprintf (TEXT("\nUnable to load patterns section.\n")); } else { _tprintf (TEXT("done\n\n")); } if (SetupFindFirstLine (configHandle, TEXT("sections"), NULL, &context)) { do { if (!SetupGetStringField (&context, 1, sectName, MAX_TCHAR_PATH, NULL)) { _tprintf (TEXT("\nBad section [SECTIONS] in %s. Exiting.\n"), g_ConfigFile); return FALSE; } if (!pHandleSection (sectName, configHandle)) { return FALSE; } } while (SetupFindNextLine (&context, &context)); } return TRUE; } BOOL pLoadGoodFiles ( IN HINF ConfigHandle ) { INFCONTEXT context; if (SetupFindFirstLine (ConfigHandle, TEXT("good files"), NULL, &context)) { do { if (!pScanForFile (&context, 1)) { DEBUGMSG ((DBG_WARNING, "Scan for file failed:%d", GetLastError())); return FALSE; } } while (SetupFindNextLine (&context, &context)); } return TRUE; } BOOL pLoadAttributes ( IN HINF ConfigHandle ) { TCHAR fileName [MEMDB_MAX]; TCHAR attribStr [MEMDB_MAX]; PCTSTR currAttr; DWORD attributes; DWORD dontCare; INFCONTEXT context; if (SetupFindFirstLine (ConfigHandle, TEXT("Attributes"), NULL, &context)) { do { if (SetupGetStringField (&context, 1, fileName, MAX_TCHAR_PATH, NULL)) { if (!SetupGetStringField (&context, 2, attribStr, MAX_TCHAR_PATH, NULL)) { attribStr [0] = 0; } currAttr = attribStr; attributes = 0; while (*currAttr) { switch (toupper(*currAttr)) { case 'S': attributes |= ATTR_FILESIZE; break; case 'C': attributes |= ATTR_CHECKSUM; break; case 'N': attributes |= ATTR_COMPNAME; break; case 'F': attributes |= ATTR_FILEDESC; break; case 'V': attributes |= ATTR_FILEVER; break; case 'I': attributes |= ATTR_INTNAME; break; case 'L': attributes |= ATTR_LEGAL; break; case 'O': attributes |= ATTR_ORIGNAME; break; case 'P': attributes |= ATTR_PRODNAME; break; case 'E': attributes |= ATTR_PRODVER; break; case 'T': attributes |= ATTR_EXETYPE; break; case 'D': attributes |= ATTR_DESCR16; break; default: _tprintf (TEXT("\nInvalid attributes:%s\n"), currAttr); } currAttr = _tcsinc (currAttr); } MemDbSetValueEx ( MEMDB_CATEGORY_ATTRIBUTES, fileName, NULL, NULL, attributes, &dontCare ); } } while (SetupFindNextLine (&context, &context)); } return TRUE; } BOOL pLoadPatterns ( IN HINF ConfigHandle ) { TCHAR patternFile [MEMDB_MAX]; TCHAR patternStr [MEMDB_MAX]; INFCONTEXT context; PPATTERN_FILE fileStruct; if (SetupFindFirstLine (ConfigHandle, TEXT("Patterns"), NULL, &context)) { do { if (SetupGetStringField (&context, 1, patternFile, MAX_TCHAR_PATH, NULL) && SetupGetMultiSzField (&context, 2, patternStr, MAX_TCHAR_PATH, NULL) ) { fileStruct = (PPATTERN_FILE) PoolMemGetMemory (g_MigDbPool, sizeof (PATTERN_FILE)); fileStruct->Pattern = PoolMemDuplicateString (g_MigDbPool, patternFile); fileStruct->PatternAttr = pLoadAttribData (patternStr); fileStruct->Next = g_AttrPatterns; g_AttrPatterns = fileStruct; } } while (SetupFindNextLine (&context, &context)); } return TRUE; } BOOL pDeleteAllFiles ( IN PCTSTR DirPath ) { TREE_ENUM e; BOOL dirsFirst = FALSE; if (EnumFirstFileInTree (&e, DirPath, TEXT("*"), dirsFirst)) { do { if (e.Directory) { pDeleteAllFiles (e.FullPath); SetFileAttributes (e.FullPath, FILE_ATTRIBUTE_NORMAL); RemoveDirectory (e.FullPath); } else { SetFileAttributes (e.FullPath, FILE_ATTRIBUTE_NORMAL); DeleteFile (e.FullPath); } } while (EnumNextFileInTree (&e)); } return TRUE; } BOOL pSelected ( IN PCTSTR FileName ) { MULTISZ_ENUM patternEnum; if (EnumFirstMultiSz (&patternEnum, g_SectFiles.Buf)) { do { if (IsPatternMatch (patternEnum.CurrentString, FileName)) { return TRUE; } } while (EnumNextMultiSz (&patternEnum)); } return FALSE; } BOOL pSpecialSelected ( IN PCTSTR FileName, OUT PTSTR NewName ) { MULTISZ_ENUM patternEnum; PTSTR endPtr, endPtr1; TCHAR savedVal; if (EnumFirstMultiSz (&patternEnum, g_SectFiles.Buf)) { do { endPtr = _tcsdec (patternEnum.CurrentString, GetEndOfString (patternEnum.CurrentString)); savedVal = *endPtr; *endPtr = TEXT('_'); if (IsPatternMatch (patternEnum.CurrentString, FileName)) { StringCopy (NewName, FileName); endPtr1 = _tcsdec (NewName, GetEndOfString (NewName)); *endPtr1 = savedVal; *endPtr = savedVal; return TRUE; } *endPtr = savedVal; } while (EnumNextMultiSz (&patternEnum)); } StringCopy (NewName, FileName); endPtr = _tcsdec (NewName, GetEndOfString (NewName)); *endPtr = TEXT('-'); return FALSE; } DWORD g_DirSequencer = 0; DWORD g_FileSequencer = 0; BOOL pCabinetFile ( IN PCTSTR FileName ) { PCTSTR extPtr; extPtr = GetFileExtensionFromPath (FileName); if ((extPtr != NULL) && StringIMatch (extPtr, TEXT("CAB")) ) { return TRUE; } return FALSE; } #define ATTR_FILESIZE 0x1 #define ATTR_CHECKSUM 0x2 #define ATTR_COMPNAME 0x4 #define ATTR_FILEDESC 0x8 #define ATTR_FILEVER 0x10 #define ATTR_INTNAME 0x20 #define ATTR_LEGAL 0x40 #define ATTR_ORIGNAME 0x80 #define ATTR_PRODNAME 0x100 #define ATTR_PRODVER 0x200 #define ATTR_EXETYPE 0x400 #define ATTR_DESCR16 0x800 typedef struct _VERSION_DATA { PCSTR versionValue; PCSTR versionName; DWORD attrib; } VERSION_DATA, *PVERSION_DATA; VERSION_DATA verData [] = {{NULL, "COMPANYNAME", ATTR_COMPNAME}, {NULL, "FILEDESCRIPTION", ATTR_FILEDESC}, {NULL, "FILEVERSION", ATTR_FILEVER}, {NULL, "INTERNALNAME", ATTR_INTNAME}, {NULL, "LEGALCOPYRIGHT", ATTR_LEGAL}, {NULL, "ORIGINALFILENAME", ATTR_ORIGNAME}, {NULL, "PRODUCTNAME", ATTR_PRODNAME}, {NULL, "PRODUCTVERSION", ATTR_PRODVER}, {NULL, NULL, 0}}; extern PSTR g_ExeTypes[4]; BOOL pCheckForPattern ( IN PCTSTR FileName, PFILE_HELPER_PARAMS Params, OUT PTSTR FileAttr, IN OUT PGROWBUFFER AttrList ) { PPATTERN_FILE patternFile; PMIGDB_ATTRIB migDbAttrib; DBATTRIB_PARAMS attribParams; BOOL fileSelected; BOOL found; TCHAR temp [MEMDB_MAX]; MULTISZ_ENUMA multiSzEnum; BOOL first; patternFile = g_AttrPatterns; found = FALSE; while (patternFile) { if (IsPatternMatch (patternFile->Pattern, FileName)) { fileSelected = TRUE; migDbAttrib = patternFile->PatternAttr; while (migDbAttrib) { attribParams.FileParams = Params; attribParams.ExtraData = NULL; if (!CallAttribute (migDbAttrib, &attribParams)) { fileSelected = FALSE; break; } migDbAttrib = migDbAttrib->Next; } if (fileSelected) { found = TRUE; break; } } patternFile = patternFile->Next; } if (found) { migDbAttrib = patternFile->PatternAttr; while (migDbAttrib) { _tcscpy (temp, MigDb_GetAttributeName (migDbAttrib->AttribIndex)); first = TRUE; if (EnumFirstMultiSz (&multiSzEnum, migDbAttrib->Arguments)) { _tcscat (temp, TEXT("(")); do { if (!first) { _tcscat (FileAttr, TEXT(",")); _tcscat (FileAttr, temp); if (AttrList) { MultiSzAppend (AttrList, temp); } *temp = 0; } first = FALSE; _tcscat (temp, TEXT("\"")); _tcscat (temp, multiSzEnum.CurrentString); _tcscat (temp, TEXT("\"")); } while (EnumNextMultiSz (&multiSzEnum)); _tcscat (temp, TEXT(")")); } _tcscat (FileAttr, TEXT(",")); _tcscat (FileAttr, temp); if (AttrList) { MultiSzAppend (AttrList, temp); } migDbAttrib = migDbAttrib->Next; } return TRUE; } return FALSE; } PSTR MyQueryVersionEntry ( IN PCSTR FileName, IN PCSTR VersionEntry ) { VERSION_STRUCTW Version; PCWSTR CurrentStr; PSTR ConvCurrentStr = NULL; PSTR result = NULL; PCWSTR ConvFileName = NULL; PCWSTR ConvVerEntry = NULL; MYASSERT (VersionEntry); ConvFileName = ConvertAtoW (FileName); ConvVerEntry = ConvertAtoW (VersionEntry); if (CreateVersionStructW (&Version, ConvFileName)) { __try { CurrentStr = EnumFirstVersionValueW (&Version, ConvVerEntry); if (CurrentStr) { CurrentStr = SkipSpaceW (CurrentStr); ConvCurrentStr = UnicodeToCcs (CurrentStr); TruncateTrailingSpace ((PSTR) ConvCurrentStr); result = ConvCurrentStr; } else { __leave; } } __finally { DestroyVersionStructW (&Version); } } if (ConvVerEntry) { FreeConvertedStr (ConvVerEntry); } if (ConvFileName) { FreeConvertedStr (ConvFileName); } return result; } BOOL pPrintLine ( IN PTREE_ENUM e, OUT PTSTR FileAttr, IN OUT PGROWBUFFER AttrList ) { FILE_HELPER_PARAMS Params; UINT checkSum; DWORD exeType; PCSTR fileDesc16; INT numAttribs; DWORD listedAttr; TCHAR ekey [MEMDB_MAX]; TCHAR temp [MEMDB_MAX]; PVERSION_DATA p; Params.Handled = 0; Params.FullFileSpec = e->FullPath; _tcsncpy (Params.DirSpec, e->RootPath, MAX_TCHAR_PATH); Params.IsDirectory = FALSE; Params.Extension = GetFileExtensionFromPath (e->Name); Params.FindData = e->FindData; Params.VirtualFile = FALSE; Params.CurrentDirData = NULL; FileAttr [0] = 0; if (!StringIMatch (e->Name, TEXT("kernel32.dll"))) { if (pCheckForPattern (e->Name, &Params, FileAttr, AttrList)) { return TRUE; } } numAttribs = 0; MemDbBuildKey (ekey, MEMDB_CATEGORY_ATTRIBUTES, e->Name, NULL, NULL); if (!MemDbGetPatternValue (ekey, &listedAttr)) { listedAttr = ATTR_COMPNAME | ATTR_PRODVER; } if (listedAttr & ATTR_FILESIZE) { _stprintf ( temp, TEXT(",FILESIZE(0x%08lX)"), e->FindData->nFileSizeLow); _tcscat (FileAttr, temp); if (AttrList) { _stprintf ( temp, TEXT("FILESIZE(0x%08lX)"), e->FindData->nFileSizeLow); MultiSzAppend (AttrList, temp); } numAttribs ++; } if (listedAttr & ATTR_CHECKSUM) { checkSum = ComputeCheckSum (&Params); _stprintf ( temp, TEXT(",CHECKSUM(0x%08lX)"), checkSum); _tcscat (FileAttr, temp); if (AttrList) { _stprintf ( temp, TEXT("CHECKSUM(0x%08lX)"), checkSum); MultiSzAppend (AttrList, temp); } numAttribs ++; } if (listedAttr & ATTR_EXETYPE) { exeType = GetModuleType (e->FullPath); _stprintf ( temp, TEXT(",EXETYPE(\"%s\")"), g_ExeTypes[exeType]); _tcscat (FileAttr, temp); if (AttrList) { _stprintf ( temp, TEXT("EXETYPE(%s)"), g_ExeTypes[exeType]); MultiSzAppend (AttrList, temp); } numAttribs ++; } if (listedAttr & ATTR_DESCR16) { fileDesc16 = Get16ModuleDescription (e->FullPath); if (fileDesc16 != NULL) { _stprintf ( temp, TEXT(",DESCRIPTION(\"%s\")"), fileDesc16); _tcscat (FileAttr, temp); if (AttrList) { _stprintf ( temp, TEXT("DESCRIPTION(%s)"), fileDesc16); MultiSzAppend (AttrList, temp); } numAttribs ++; FreePathString (fileDesc16); } } p = verData; while (p->versionName) { if (listedAttr & p->attrib) { p->versionValue = MyQueryVersionEntry (e->FullPath, p->versionName); } p++; } p = verData; while (p->versionName) { if ((listedAttr & p->attrib) && (p->versionValue)) { _stprintf ( temp, TEXT(",%s(\"%s\")"), p->versionName, p->versionValue); _tcscat (FileAttr, temp); if (AttrList) { _stprintf ( temp, TEXT("%s(%s)"), p->versionName, p->versionValue); MultiSzAppend (AttrList, temp); } FreePathString (p->versionValue); numAttribs ++; } p++; } if (numAttribs == 0) { checkSum = ComputeCheckSum (&Params); _stprintf ( temp, TEXT(",FC(%ld,%lX)"), e->FindData->nFileSizeLow, checkSum ); _tcscat (FileAttr, temp); if (AttrList) { _stprintf ( temp, TEXT("FC(%ld"), e->FindData->nFileSizeLow ); MultiSzAppend (AttrList, temp); _stprintf ( temp, TEXT("%lX)"), checkSum ); MultiSzAppend (AttrList, temp); } } return TRUE; } BOOL pHandleAppFile ( IN PTREE_ENUM e, IN PCTSTR Action, IN PCTSTR Section, IN PCTSTR Message, IN PCTSTR SrcPath ) { TCHAR msgStr [MEMDB_MAX] = ""; FILE_HELPER_PARAMS Params; TCHAR line [MEMDB_MAX]; TCHAR key [MEMDB_MAX] = ""; DWORD offset; Params.Handled = 0; Params.FullFileSpec = e->FullPath; _tcsncpy (Params.DirSpec, SrcPath, MAX_TCHAR_PATH); Params.IsDirectory = FALSE; Params.Extension = GetFileExtensionFromPath (e->Name); Params.FindData = e->FindData; Params.VirtualFile = FALSE; Params.CurrentDirData = NULL; pPrintLine (e, line, NULL); MemDbBuildKey (key, MEMDB_CATEGORY_RENAME_SRC, e->Name, NULL, NULL); if (MemDbGetValue (key, &offset)) { if (!MemDbBuildKeyFromOffset (offset, key, 1, NULL)) { *key = 0; } } else { *key = 0; } _stprintf ( msgStr, TEXT("%s\\%s%s)"), MEMDB_CATEGORY_SECTFILES, *key?key:e->Name, line); MemDbSetValue (msgStr, 0); return TRUE; } BOOL pHandleSysFile ( IN PTREE_ENUM e, IN PCTSTR Action, IN PCTSTR Section, IN PCTSTR Message, IN PCTSTR SrcPath ) { TCHAR msgStr [MEMDB_MAX] = ""; FILE_HELPER_PARAMS Params; HASHITEM stringId; PMIGDB_FILE migDbFile; FILE_LIST_STRUCT fileList; PMIGDB_ATTRIB migDbAttrib; DBATTRIB_PARAMS attribParams; BOOL fileSelected = FALSE; PCTSTR actionTmp; TCHAR line [MEMDB_MAX]; TCHAR key [MEMDB_MAX] = ""; DWORD offset; GROWBUFFER attrList = GROWBUF_INIT; // this is not a cabinet file, let's do something with it. Params.Handled = 0; Params.FullFileSpec = e->FullPath; _tcsncpy (Params.DirSpec, SrcPath, MAX_TCHAR_PATH); Params.IsDirectory = FALSE; Params.Extension = GetFileExtensionFromPath (e->Name); Params.FindData = e->FindData; Params.VirtualFile = FALSE; Params.CurrentDirData = NULL; pPrintLine (e, line, &attrList); if (StringIMatch (e->Name, TEXT("kernel32.dll"))) { _stprintf ( msgStr, TEXT("%s\\%s%s"), MEMDB_CATEGORY_REQFILES, e->Name, line); MemDbSetValue (msgStr, fileSelected); }; // first check if this file is in "known good" list or is already listed in migdb.inx // with same action stringId = HtFindString (g_FileTable, e->Name); if (stringId) { //The string table has extra data (a pointer to a FILE_LIST_STRUCT node) HtCopyStringData (g_FileTable, stringId, &fileList); migDbFile = fileList.First; while (migDbFile) { //check all attributes for this file migDbAttrib = migDbFile->Attributes; fileSelected = TRUE; while (migDbAttrib != NULL) { attribParams.FileParams = &Params; attribParams.ExtraData = NULL; if (!CallAttribute (migDbAttrib, &attribParams)) { fileSelected = FALSE; break; } migDbAttrib = migDbAttrib->Next; } if ((!fileSelected) && (migDbFile->Section == NULL) ) { // there was a name collision with a "known good" file. We will send a message _stprintf (msgStr, TEXT("%s\\%s"), MEMDB_CATEGORY_WARNFILES, e->Name); MemDbSetValue (msgStr, 0); } if ((fileSelected) && (migDbFile->Section == NULL) ) { // this file is "known good". We will send a message _stprintf (msgStr, TEXT("%s\\%s"), MEMDB_CATEGORY_GOODFILES, e->Name); MemDbSetValue (msgStr, 0); break; } if ((fileSelected) && (!StringIMatch (Section, migDbFile->Section->Context->SectName))){ actionTmp = MigDb_GetActionName (migDbFile->Section->Context->ActionIndex); if ((actionTmp != NULL) && StringIMatch (actionTmp, Action)) { // this file was already listed in migdb.inx with the same action _stprintf ( msgStr, TEXT("%s\\%s\\%-14s%s"), MEMDB_CATEGORY_DUPLFILES, Action, e->Name, line); MemDbSetValue (msgStr, 0); break; } } fileSelected = FALSE; migDbFile = migDbFile->Next; } } if (!fileSelected) { // one more check. If this file is in FILELIST.DAT (but not in the EXCEPTED section) // and COMPANYNAME attribute has Microsoft somewhere inside we'll put it in a different // place MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, e->Name, NULL, NULL); if (MemDbGetValue (key, NULL)) { MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES_EXCEPT, e->Name, NULL, NULL); if (!MemDbGetValue (key, NULL)) { if (GlobalVersionCheck (e->FullPath, "COMPANYNAME", "*MICROSOFT*")) { fileSelected = TRUE; } } } // this file is not in the list or attributes do not match // we will add in incompatibility list. //creating MIGDB_FILE structure for current file migDbFile = (PMIGDB_FILE) PoolMemGetMemory (g_MigDbPool, sizeof (MIGDB_FILE)); if (migDbFile != NULL) { ZeroMemory (migDbFile, sizeof (MIGDB_FILE)); migDbFile->Section = g_ContextList->Sections; migDbFile->Attributes = pLoadAttribData (attrList.Buf); if (g_MigDbHook != NULL) { migDbAttrib = migDbFile->Attributes; while (migDbAttrib) { g_MigDbHook (e->Name, g_ContextList, g_ContextList->Sections, migDbFile, migDbAttrib); migDbAttrib = migDbAttrib->Next; } } //adding this file into string table and create a MIGDB_FILE node. If file //already exists in string table then just create another MIGDB_FILE node //chained with already existing ones. stringId = HtFindString (g_FileTable, e->Name); if (stringId) { HtCopyStringData (g_FileTable, stringId, &fileList); fileList.Last->Next = migDbFile; fileList.Last = migDbFile; HtSetStringData (g_FileTable, stringId, &fileList); } else { fileList.First = fileList.Last = migDbFile; HtAddStringAndData (g_FileTable, e->Name, &fileList); } } else { DEBUGMSG ((DBG_ERROR, "Unable to allocate file node for %s", e->Name)); } MemDbBuildKey (key, MEMDB_CATEGORY_RENAME_SRC, e->Name, NULL, NULL); if (MemDbGetValue (key, &offset)) { if (!MemDbBuildKeyFromOffset (offset, key, 1, NULL)) { *key = 0; } } else { *key = 0; } _stprintf ( msgStr, TEXT("%s\\%s%s"), MEMDB_CATEGORY_SECTFILES, *key?key:e->Name, line); MemDbSetValue (msgStr, fileSelected); } FreeGrowBuffer (&attrList); return TRUE; } BOOL pCompressedFile ( IN PTREE_ENUM e ) { PCTSTR extPtr; extPtr = GetFileExtensionFromPath (e->FullPath); if (extPtr == NULL) { return FALSE; } if (_tcslen (extPtr) != 3) { return FALSE; } return (extPtr [2] == TEXT('_')); } BOOL pExeFile ( IN PTREE_ENUM e ) { PCTSTR extPtr; extPtr = GetFileExtensionFromPath (e->FullPath); if ((extPtr != NULL) && (StringIMatch (extPtr, TEXT("EXE"))) ) { return TRUE; } return FALSE; } BOOL pCopyAndHandleCabResource ( IN PVOID Source, IN DWORD Size, IN PCTSTR DirName ) { TCHAR cabDir [MAX_TCHAR_PATH] = ""; HANDLE hFile; DWORD dontCare; if (Size < 4) { return TRUE; } if (*((PDWORD)Source) != 0x4643534D) { return TRUE; } g_FileSequencer ++; _stprintf (cabDir, TEXT("%s\\MIGDB%03u.CAB"), DirName, g_FileSequencer); hFile = CreateFile (cabDir, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { DEBUGMSG ((DBG_ERROR, "Cannot create file %s", cabDir)); return FALSE; } if (!WriteFile (hFile, Source, Size, &dontCare, NULL)) { DEBUGMSG ((DBG_ERROR, "Cannot write to file %s", cabDir)); return FALSE; } CloseHandle (hFile); return TRUE; } BOOL CALLBACK EnumResNameProc ( IN HANDLE hModule, // module handle IN LPCTSTR lpszType, // pointer to resource type IN LPTSTR lpszName, // pointer to resource name IN LONG lParam // application-defined parameter ) { HRSRC hResource; DWORD size; HGLOBAL hGlobal; PVOID srcBytes; hResource = FindResource (hModule, lpszName, lpszType); if (hResource) { size = SizeofResource (hModule, hResource); if (size) { hGlobal = LoadResource (hModule, hResource); if (hGlobal) { srcBytes = LockResource (hGlobal); if (srcBytes) { pCopyAndHandleCabResource (srcBytes, size, (PCTSTR)lParam); } } } } return TRUE; } BOOL CALLBACK EnumResTypeProc ( IN HANDLE hModule, // resource-module handle IN LPTSTR lpszType, // pointer to resource type IN LONG lParam // application-defined parameter ) { if ((lpszType != RT_ACCELERATOR ) && (lpszType != RT_ANICURSOR ) && (lpszType != RT_ANIICON ) && (lpszType != RT_BITMAP ) && (lpszType != RT_CURSOR ) && (lpszType != RT_DIALOG ) && (lpszType != RT_FONT ) && (lpszType != RT_FONTDIR ) && (lpszType != RT_GROUP_CURSOR ) && (lpszType != RT_GROUP_ICON ) && (lpszType != RT_HTML ) && (lpszType != RT_ICON ) && (lpszType != RT_MENU ) && (lpszType != RT_MESSAGETABLE ) && (lpszType != RT_PLUGPLAY ) && (lpszType != RT_STRING ) && (lpszType != RT_VERSION ) && (lpszType != RT_VXD ) && (lpszType != RT_HTML ) ) { // we found an unknown type. Let's enumerate all resources of this type if (EnumResourceNames (hModule, lpszType, EnumResNameProc, lParam) == 0) { DEBUGMSG ((DBG_ERROR, "Error enumerating names:%ld", GetLastError ())); } } return TRUE; } BOOL pHandleAllFiles ( IN BOOL AppMode, IN PCTSTR Action, IN PCTSTR Section, IN PCTSTR Message, IN PCTSTR SrcPath ) { TCHAR tempDir [MAX_TCHAR_PATH] = ""; TCHAR cmdLine [MAX_TCHAR_PATH] = ""; TCHAR newName [MAX_TCHAR_PATH] = ""; TREE_ENUM e; DWORD error; HMODULE exeModule; PROCESS_INFORMATION processInfo; STARTUPINFO startupInfo; if (EnumFirstFileInTree (&e, SrcPath, TEXT("*"), FALSE)) { do { if (!e.Directory) { if (pCabinetFile (e.Name)) { if ((AppMode) || (!pSelected (e.Name)) ) { // cabinet file g_DirSequencer++; _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer); if (CreateDirectory (tempDir, NULL) == 0) { error = GetLastError (); if (error == ERROR_ALREADY_EXISTS) { pDeleteAllFiles (tempDir); } ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir)); } _tprintf (TEXT(" Extracting cabinet file ... %s"), e.Name); // we need to expand the cabinet file SetLastError (0); if (!SetupIterateCabinet (e.FullPath, 0, pCabinetCallback, tempDir)) { _tprintf (TEXT("...error %ld\n"), GetLastError()); DEBUGMSG((DBG_ERROR, "Could not iterate cabinet file:%s\nError:%ld", e.FullPath, GetLastError ())); } else { _tprintf (TEXT("...done\n")); } if (!pHandleAllFiles (AppMode, Action, Section, Message, tempDir)) { return FALSE; } pDeleteAllFiles (tempDir); RemoveDirectory (tempDir); g_DirSequencer--; } } else if (pCompressedFile (&e)) { if (AppMode) { if (!pSpecialSelected (e.Name, newName)) { continue; } } else { if (pSpecialSelected (e.Name, newName)) { continue; } } // compressed file g_DirSequencer++; _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer); if (CreateDirectory (tempDir, NULL) == 0) { error = GetLastError (); if (error == ERROR_ALREADY_EXISTS) { pDeleteAllFiles (tempDir); } ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir)); } _stprintf (cmdLine, TEXT("expand /r %s %s"), e.FullPath, tempDir); ZeroMemory (&startupInfo, sizeof (STARTUPINFO)); startupInfo.cb = sizeof (STARTUPINFO); if (CreateProcess (NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInfo)) { WaitForSingleObject (processInfo.hProcess, INFINITE); CloseHandle (processInfo.hProcess); CloseHandle (processInfo.hThread); if (!pHandleAllFiles (AppMode, Action, Section, Message, tempDir)) { return FALSE; } pDeleteAllFiles (tempDir); } else { DEBUGMSG ((DBG_ERROR, "Could not decompress:%s, Error:%ld", e.Name, GetLastError())); } RemoveDirectory (tempDir); g_DirSequencer--; } else { if (pExeFile (&e)) { g_FileSequencer = 0; g_DirSequencer++; _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer); if (CreateDirectory (tempDir, NULL) == 0) { error = GetLastError (); if (error == ERROR_ALREADY_EXISTS) { pDeleteAllFiles (tempDir); } ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir)); } exeModule = LoadLibraryEx (e.FullPath, NULL, LOAD_LIBRARY_AS_DATAFILE); EnumResourceTypes (exeModule, EnumResTypeProc, (LONG)tempDir); FreeLibrary (exeModule); if (!pHandleAllFiles (AppMode, Action, Section, Message, tempDir)) { return FALSE; } pDeleteAllFiles (tempDir); RemoveDirectory (tempDir); g_DirSequencer--; } if (AppMode) { if (pSelected (e.Name)) { if (!pHandleAppFile (&e, Action, Section, Message, SrcPath)) { return FALSE; } } } else { if (!pSelected (e.Name)) { if (!pHandleSysFile (&e, Action, Section, Message, SrcPath)) { return FALSE; } } } } } } while (EnumNextFileInTree (&e)); } return TRUE; } BOOL pHandleSection ( IN PCTSTR SectionName, IN HINF ConfigHandle ) { PMIGDB_CONTEXT migDbContext = NULL; INFCONTEXT context; TCHAR action [MAX_TCHAR_PATH] = ""; TCHAR section [MAX_TCHAR_PATH] = ""; TCHAR message [MAX_TCHAR_PATH] = ""; TCHAR srcPath [MAX_TCHAR_PATH] = ""; TCHAR msgStr [MAX_TCHAR_PATH] = ""; TCHAR sectTmp [MAX_TCHAR_PATH] = ""; TCHAR renSect [MAX_TCHAR_PATH] = ""; TCHAR srcFile [MAX_TCHAR_PATH] = ""; TCHAR destFile[MAX_TCHAR_PATH] = ""; BOOL forced = FALSE; INT field; TCHAR excludePattern [MAX_TCHAR_PATH] = ""; BOOL appMode = FALSE; TCHAR sectPatterns [MAX_TCHAR_PATH] = ""; DWORD offset; _tprintf (TEXT("Processing section : %s ... "), SectionName); if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("action"), &context)) { _tprintf (TEXT("\nCannot find Action= line in %s.\n"), SectionName); return FALSE; } if (!SetupGetStringField (&context, 1, action, MAX_TCHAR_PATH, NULL)) { _tprintf (TEXT("\nCannot read action name in %s.\n"), SectionName); return FALSE; } if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("section"), &context)) { _tprintf (TEXT("\nCannot find Section= line in %s.\n"), SectionName); return FALSE; } if (!SetupGetStringField (&context, 1, section, MAX_TCHAR_PATH, NULL)) { _tprintf (TEXT("\nCannot read section name in %s.\n"), SectionName); return FALSE; } if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("sourcepath"), &context)) { _tprintf (TEXT("\nCannot find SourcePath= line in %s.\n"), SectionName); return FALSE; } if (!SetupGetStringField (&context, 1, srcPath, MAX_TCHAR_PATH, NULL)) { _tprintf (TEXT("\nCannot read source path name in %s.\n"), SectionName); return FALSE; } if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("message"), &context)) { SetupGetStringField (&context, 1, message, MAX_TCHAR_PATH, NULL); } if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("RenameSection"), &context)) { SetupGetStringField (&context, 1, renSect, MAX_TCHAR_PATH, NULL); } g_SectFiles.Buf = NULL; g_SectFiles.Size = 0; g_SectFiles.End = 0; g_SectFiles.GrowSize = 0; g_SectFiles.UserIndex = 0; if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("ExcludeFiles"), &context)) { field = 1; while (SetupGetStringField (&context, field, excludePattern, MAX_TCHAR_PATH, NULL)) { MultiSzAppend (&g_SectFiles, excludePattern); field ++; } appMode = FALSE; } if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("SpecifiedFiles"), &context)) { field = 1; while (SetupGetStringField (&context, field, excludePattern, MAX_TCHAR_PATH, NULL)) { MultiSzAppend (&g_SectFiles, excludePattern); field ++; } appMode = TRUE; } // let's try to find if this section was already processed in migdb.inx if (SetupFindFirstLine (g_MigDbInf, action, NULL, &context)) { do { if (SetupGetStringField (&context, 1, sectTmp, MAX_TCHAR_PATH, NULL) && (StringIMatch (section, sectTmp)) ) { if ((!g_RescanFlag) || ((g_RescanSect != NULL) && (!StringIMatch (g_RescanSect, section))) ) { _tprintf (TEXT("skipped\n")); return TRUE; } WritePrivateProfileString (section, NULL, NULL, g_MigdbDest); WritePrivateProfileString (NULL, NULL, NULL, g_MigdbDest); _tprintf (TEXT("forced ...")); forced = TRUE; } } while (SetupFindNextLine (&context, &context)); } if (SetupFindFirstLine (ConfigHandle, renSect, NULL, &context)) { do { if (SetupGetStringField (&context, 0, srcFile, MAX_TCHAR_PATH, NULL) && SetupGetStringField (&context, 1, destFile, MAX_TCHAR_PATH, NULL) ) { MemDbSetValueEx (MEMDB_CATEGORY_RENAME_DEST, destFile, NULL, NULL, 0, &offset); MemDbSetValueEx (MEMDB_CATEGORY_RENAME_SRC, srcFile, NULL, NULL, offset, NULL); } } while (SetupFindNextLine (&context, &context)); } _tprintf (TEXT("\n")); migDbContext = (PMIGDB_CONTEXT) PoolMemGetMemory (g_MigDbPool, sizeof (MIGDB_CONTEXT)); if (migDbContext == NULL) { DEBUGMSG ((DBG_ERROR, "Unable to create context for %s", action)); return FALSE; } ZeroMemory (migDbContext, sizeof (MIGDB_CONTEXT)); migDbContext->Next = g_ContextList; g_ContextList = migDbContext; // update ActionIndex with known value migDbContext->ActionIndex = MigDb_GetActionIdx (action); DEBUGMSG_IF(((migDbContext->ActionIndex == -1), DBG_ERROR, "Unable to identify action index for %s", action)); // update SectName field migDbContext->SectName = PoolMemDuplicateString (g_MigDbPool, section); if (!pHandleAllFiles (appMode, action, section, message, srcPath)) { return FALSE; } FreeGrowBuffer (&g_SectFiles); if (!forced) { // now let's add the action section and the line within it _stprintf (msgStr, TEXT("%s\\%s,%s"), MEMDB_CATEGORY_ACTION, section, message); MemDbSetValue (msgStr, 0); pWriteMemdbSection (g_MigdbDest, MEMDB_CATEGORY_ACTION, action, FALSE); } pWriteMemdbSection (g_MigdbDest, MEMDB_CATEGORY_SECTFILES, section, TRUE); pWriteMemdbSection (g_MigdbDest, MEMDB_CATEGORY_REQFILES, TEXT("Windows 9x Required Files"), TRUE); MemDbDeleteTree (MEMDB_CATEGORY_SECTFILES); MemDbDeleteTree (MEMDB_CATEGORY_ACTION); MemDbDeleteTree (MEMDB_CATEGORY_RENAME_SRC); MemDbDeleteTree (MEMDB_CATEGORY_RENAME_DEST); MemDbDeleteTree (MEMDB_CATEGORY_REQFILES); return TRUE; } BOOL pWriteMemdbSection ( IN PCTSTR FileName, IN PCTSTR MemDbCategory, IN PCTSTR SectName, IN BOOL WriteByValue ) { HANDLE fileHandle = INVALID_HANDLE_VALUE; TCHAR line [MAX_TCHAR_PATH] = ""; DWORD dontCare; MEMDB_ENUM e; PCTSTR pattern; fileHandle = CreateFile (FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); if (fileHandle == INVALID_HANDLE_VALUE) { _tprintf (TEXT("\nCannot open %s.\n"), FileName); return FALSE; } SetFilePointer (fileHandle, 0, 0, FILE_END); _stprintf (line, TEXT("[%s]\r\n"), SectName); WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL); pattern = JoinPaths (MemDbCategory, TEXT("\\*")); if (MemDbEnumFirstValue (&e, pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) { do { if (!WriteByValue || !e.dwValue) { _stprintf (line, TEXT("%s\r\n"), e.szName); if (!WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL)) { DEBUGMSG ((DBG_ERROR, "Error while writing information.")); } } } while (MemDbEnumNextValue (&e)); } _stprintf (line, TEXT("\r\n\r\n"), SectName); WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL); if (!CloseHandle (fileHandle)) { DEBUGMSG ((DBG_ERROR, "Error while closing file %s.", FileName)); } if (WriteByValue) { fileHandle = CreateFile (g_MigdbDump, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); if (fileHandle == INVALID_HANDLE_VALUE) { _tprintf (TEXT("\nCannot open %s.\n"), g_MigdbDump); return FALSE; } SetFilePointer (fileHandle, 0, 0, FILE_END); _stprintf (line, TEXT("[\n%s.obsolete]\r\n"), SectName); WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL); if (MemDbEnumFirstValue (&e, pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) { do { if (e.dwValue) { _stprintf (line, TEXT("%s\r\n"), e.szName); if (!WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL)) { DEBUGMSG ((DBG_ERROR, "Error while writing information.")); } } } while (MemDbEnumNextValue (&e)); } if (!CloseHandle (fileHandle)) { DEBUGMSG ((DBG_ERROR, "Error while closing file %s.", FileName)); } } FreePathString (pattern); return TRUE; } BOOL pArrangeMigDbFile ( IN PCTSTR SrcFile, IN PCTSTR DestFile ) { return CopyFile (SrcFile, DestFile, FALSE); }