/*++ Copyright (c) 1997 Microsoft Corporation Module Name: badappid.c Abstract: Implements a upgwiz wizard for obtaining various application information. Author: Calin Negreanu (calinn) 10-Oct-1998 Revision History: --*/ #include "pch.h" #include "..\inc\dgdll.h" #include "..\..\w95upg\migapp\migdbp.h" #include "dialogs.h" #include #include #include DATATYPE g_DataTypes[] = { {UPGWIZ_VERSION, "Generate AppsHelp entry", "You must specify the main EXE and a variable number of additional files.", 0, DTF_REQUIRE_DESCRIPTION, 1024, "&Application name:" }, }; typedef struct _ITEM_INFO { PSTR FilePath; PSTR VersionValue; UINT VersionIndex; } ITEM_INFO, *PITEM_INFO; PSTR g_MainFile = NULL; GROWBUFFER g_AddnlFiles = GROWBUF_INIT; UINT g_AppProblem = APPTYPE_INC_NOBLOCK; BOOL g_AppFlags = 0; BOOL g_SaveMigDb = TRUE; DWORD g_MsgId = 0; GROWBUFFER g_DataObjects = GROWBUF_INIT; POOLHANDLE g_DataObjectPool; HINSTANCE g_OurInst; BOOL Init ( VOID ) { #ifndef UPGWIZ4FLOPPY return InitToolMode (g_OurInst); #else return TRUE; #endif } VOID Terminate ( VOID ) { // // Local cleanup // FreeGrowBuffer (&g_DataObjects); if (g_DataObjectPool) { PoolMemDestroyPool (g_DataObjectPool); } #ifndef UPGWIZ4FLOPPY TerminateToolMode (g_OurInst); #endif } BOOL WINAPI DllMain ( IN HINSTANCE hInstance, IN DWORD dwReason, IN LPVOID lpReserved ) { if (dwReason == DLL_PROCESS_DETACH) { MYASSERT (g_OurInst == hInstance); Terminate(); } g_OurInst = hInstance; return TRUE; } UINT GiveVersion ( VOID ) { Init(); g_DataObjectPool = PoolMemInitNamedPool ("Data Objects"); return UPGWIZ_VERSION; } PDATATYPE GiveDataTypeList ( OUT PUINT Count ) { UINT u; *Count = sizeof (g_DataTypes) / sizeof (g_DataTypes[0]); for (u = 0 ; u < *Count ; u++) { g_DataTypes[u].DataTypeId = u; } return g_DataTypes; } BOOL CALLBACK pSetDefGuiFontProc( IN HWND hwnd, IN LPARAM lParam) { SendMessage(hwnd, WM_SETFONT, lParam, 0L); return TRUE; } void pSetDefGUIFont( IN HWND hdlg ) { EnumChildWindows(hdlg, pSetDefGuiFontProc, (LPARAM)GetStockObject(DEFAULT_GUI_FONT)); } BOOL CALLBACK pGetFilesUIProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { CHAR tempStr [MEMDB_MAX]; static CHAR lastDir [MEMDB_MAX] = ""; OPENFILENAME ofn; UINT Index; switch (uMsg) { case WM_INITDIALOG: pSetDefGUIFont(hdlg); CheckDlgButton (hdlg, IDC_SAVEMIGDB, BST_CHECKED); CheckDlgButton (hdlg, IDC_NONET, BST_UNCHECKED); CheckDlgButton (hdlg, IDC_APPTYPE1, BST_CHECKED); CheckDlgButton (hdlg, IDC_APPTYPE2, BST_UNCHECKED); CheckDlgButton (hdlg, IDC_APPTYPE3, BST_UNCHECKED); CheckDlgButton (hdlg, IDC_APPTYPE4, BST_UNCHECKED); CheckDlgButton (hdlg, IDC_APPTYPE5, BST_UNCHECKED); CheckDlgButton (hdlg, IDC_APPTYPE6, BST_UNCHECKED); sprintf (tempStr, "%d", g_MsgId); SendDlgItemMessage (hdlg, IDC_MSGID, WM_SETTEXT, 0, (LPARAM)tempStr); EnableWindow (GetDlgItem (hdlg, ID_CONTINUE), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_VERSION), FALSE); PostMessage (hdlg, WM_COMMAND, IDC_BROWSE, 0); return FALSE; case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_MAINFILE: if (HIWORD (wParam) == EN_CHANGE) { if (g_MainFile) { FreePathString (g_MainFile); g_MainFile = NULL; } SendDlgItemMessage (hdlg, IDC_MAINFILE, WM_GETTEXT, MEMDB_MAX, (LPARAM)tempStr); g_MainFile = DuplicatePathString (tempStr, 0); if (DoesFileExist (g_MainFile)) { EnableWindow (GetDlgItem (hdlg, ID_CONTINUE), TRUE); } else { EnableWindow (GetDlgItem (hdlg, ID_CONTINUE), FALSE); } } break; case IDC_BROWSE: if (g_MainFile) { StringCopy (tempStr, g_MainFile); } else { *tempStr = 0; } ZeroMemory (&ofn, sizeof (OPENFILENAME)); ofn.lStructSize = sizeof (OPENFILENAME); ofn.hwndOwner = hdlg; ofn.lpstrFile = tempStr; ofn.nMaxFile = MEMDB_MAX; ofn.lpstrInitialDir = lastDir; ofn.lpstrTitle = "Select Main File"; ofn.Flags = OFN_NOCHANGEDIR | OFN_NODEREFERENCELINKS | OFN_HIDEREADONLY; if (GetOpenFileName (&ofn)) { //let's copy the last directory StringCopyAB (lastDir, tempStr, _mbsdec (tempStr, tempStr + ofn.nFileOffset)); if (g_MainFile) { FreePathString (g_MainFile); } g_MainFile = DuplicatePathString (tempStr, 0); if (DoesFileExist (g_MainFile)) { EnableWindow (GetDlgItem (hdlg, ID_CONTINUE), TRUE); } else { EnableWindow (GetDlgItem (hdlg, ID_CONTINUE), FALSE); } SendDlgItemMessage (hdlg, IDC_MAINFILE, WM_SETTEXT, 0, (LPARAM)g_MainFile); } break; case IDC_ADDFILE: *tempStr = 0; ZeroMemory (&ofn, sizeof (OPENFILENAME)); ofn.lStructSize = sizeof (OPENFILENAME); ofn.hwndOwner = hdlg; ofn.lpstrFile = tempStr; ofn.nMaxFile = MEMDB_MAX; ofn.lpstrInitialDir = lastDir; ofn.lpstrTitle = "Add Required File"; ofn.Flags = OFN_NOCHANGEDIR | OFN_NODEREFERENCELINKS | OFN_HIDEREADONLY; if (GetOpenFileName (&ofn)) { //let's copy the last directory StringCopyAB (lastDir, tempStr, _mbsdec (tempStr, tempStr + ofn.nFileOffset)); Index = SendDlgItemMessage (hdlg, IDC_REQFILES, LB_ADDSTRING, 0, (LPARAM)tempStr); SendDlgItemMessage (hdlg, IDC_REQFILES, LB_SETCURSEL, Index, 0); } break; case IDC_REMOVEFILE: Index = SendDlgItemMessage (hdlg, IDC_REQFILES, LB_GETCURSEL, 0, 0); if (Index != LB_ERR) { SendDlgItemMessage (hdlg, IDC_REQFILES, LB_DELETESTRING, Index, 0); if (Index >= (UINT)SendDlgItemMessage (hdlg, IDC_REQFILES, LB_GETCOUNT, 0, 0)) { SendDlgItemMessage ( hdlg, IDC_REQFILES, LB_SETCURSEL, SendDlgItemMessage (hdlg, IDC_REQFILES, LB_GETCOUNT, 0, 0) - 1, 0 ); } else { SendDlgItemMessage (hdlg, IDC_REQFILES, LB_SETCURSEL, Index, 0); } } break; case IDC_APPTYPE1: case IDC_APPTYPE2: case IDC_APPTYPE3: case IDC_APPTYPE4: case IDC_APPTYPE5: case IDC_APPTYPE6: if (IsDlgButtonChecked (hdlg, IDC_APPTYPE5)) { EnableWindow (GetDlgItem (hdlg, IDC_FLAG1), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_FLAG2), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_FLAG3), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_SAVEMIGDB), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_MSGID), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_VERSION), TRUE); } else if (IsDlgButtonChecked (hdlg, IDC_APPTYPE6)) { EnableWindow (GetDlgItem (hdlg, IDC_FLAG1), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_FLAG2), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_FLAG3), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_SAVEMIGDB), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_MSGID), FALSE); EnableWindow (GetDlgItem (hdlg, IDC_VERSION), FALSE); } else { EnableWindow (GetDlgItem (hdlg, IDC_FLAG1), TRUE); EnableWindow (GetDlgItem (hdlg, IDC_FLAG2), TRUE); EnableWindow (GetDlgItem (hdlg, IDC_FLAG3), TRUE); EnableWindow (GetDlgItem (hdlg, IDC_SAVEMIGDB), TRUE); EnableWindow (GetDlgItem (hdlg, IDC_MSGID), TRUE); EnableWindow (GetDlgItem (hdlg, IDC_VERSION), FALSE); } break; case ID_CONTINUE: g_SaveMigDb = IsDlgButtonChecked (hdlg, IDC_SAVEMIGDB); if (IsDlgButtonChecked (hdlg, IDC_FLAG1)) { g_AppFlags |= APPTYPE_FLAG_NONET; } if (IsDlgButtonChecked (hdlg, IDC_FLAG2)) { g_AppFlags |= APPTYPE_FLAG_FAT32; } if (IsDlgButtonChecked (hdlg, IDC_FLAG3)) { g_AppFlags |= APPTYPE_FLAG_NTFS; } g_AppProblem = APPTYPE_INC_NOBLOCK; if (IsDlgButtonChecked (hdlg, IDC_APPTYPE1)) { g_AppProblem = APPTYPE_INC_NOBLOCK; } else if (IsDlgButtonChecked (hdlg, IDC_APPTYPE2)) { g_AppProblem = APPTYPE_INC_HARDBLOCK; } else if (IsDlgButtonChecked (hdlg, IDC_APPTYPE3)) { g_AppProblem = APPTYPE_MINORPROBLEM; } else if (IsDlgButtonChecked (hdlg, IDC_APPTYPE4)) { g_AppProblem = APPTYPE_REINSTALL; } else if (IsDlgButtonChecked (hdlg, IDC_APPTYPE5)) { g_AppProblem = APPTYPE_VERSIONSUB; } else if (IsDlgButtonChecked (hdlg, IDC_APPTYPE6)) { g_AppProblem = APPTYPE_SHIM; } if (g_AppProblem == APPTYPE_VERSIONSUB) { SendDlgItemMessage (hdlg, IDC_VERSION, WM_GETTEXT, MEMDB_MAX, (LPARAM)tempStr); g_SaveMigDb = FALSE; g_AppFlags = 0; } else if (g_AppProblem == APPTYPE_SHIM) { tempStr[0] = 0; g_SaveMigDb = FALSE; g_AppFlags = 0; } else { SendDlgItemMessage (hdlg, IDC_MSGID, WM_GETTEXT, MEMDB_MAX, (LPARAM)tempStr); } g_MsgId = strtoul (tempStr, NULL, 10); Index = (UINT)SendDlgItemMessage (hdlg, IDC_REQFILES, LB_GETCOUNT, 0, 0); while (Index) { if (SendDlgItemMessage (hdlg, IDC_REQFILES, LB_GETTEXT, Index - 1, (LPARAM) tempStr) != LB_ERR) { MultiSzAppend (&g_AddnlFiles, tempStr); } Index --; } EndDialog (hdlg, LOWORD (wParam)); break; case IDCANCEL: case ID_QUIT: EndDialog (hdlg, LOWORD (wParam)); break; } break; } return FALSE; } BOOL GatherInfoUI ( HINSTANCE LocalDllInstance, IN UINT DataTypeId ) { BOOL result = TRUE; switch (DataTypeId) { case 0: if (g_MainFile) { FreePathString (g_MainFile); g_MainFile = NULL; } if (g_AddnlFiles.Buf) { FreeGrowBuffer (&g_AddnlFiles); } g_AppFlags = 0; g_SaveMigDb = TRUE; g_MsgId = 0; result = (ID_CONTINUE == DialogBox (LocalDllInstance, MAKEINTRESOURCE(IDD_GETFILES), NULL, pGetFilesUIProc)); break; default: MessageBox (NULL, "Internal BadApps DLL error:00004. Please contact calinn.", "Error", MB_OK); result = FALSE; } return result; } PSTR g_ExeTypesStr[] = { "NONE", "DOS", "WIN16", "WIN32" }; PCTSTR QueryCompanyName ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "COMPANYNAME"); } PCTSTR QueryProductVersion ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "PRODUCTVERSION"); } PCTSTR QueryProductName ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "PRODUCTNAME"); } PCTSTR QueryFileDescription ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "FILEDESCRIPTION"); } PCTSTR QueryFileVersion ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "FILEVERSION"); } PCTSTR QueryOriginalFileName ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "ORIGINALFILENAME"); } PCTSTR QueryInternalName ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "INTERNALNAME"); } PCTSTR QueryLegalCopyright ( IN PCTSTR FilePath ) { return QueryVersionEntry (FilePath, "LEGALCOPYRIGHT"); } PCTSTR Query16BitDescription ( IN PCTSTR FilePath ) { return Get16ModuleDescription (FilePath); } PCTSTR QueryModuleType ( IN PCTSTR FilePath ) { return g_ExeTypesStr [GetModuleType (FilePath)]; } PCTSTR QueryFileSize ( IN PCSTR FilePath ) { HANDLE findHandle; WIN32_FIND_DATA findData; CHAR result[10]; findHandle = FindFirstFile (FilePath, &findData); if (findHandle == INVALID_HANDLE_VALUE) { return NULL; } sprintf (result, "0x%08lX", findData.nFileSizeLow); FindClose (findHandle); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryFileCheckSum ( IN PCTSTR FilePath ) { UINT checkSum; FILE_HELPER_PARAMS Params; WIN32_FIND_DATA findData; TCHAR result[10]; HANDLE findHandle; Params.Handled = 0; Params.FullFileSpec = FilePath; Params.IsDirectory = FALSE; Params.Extension = GetFileExtensionFromPath (FilePath); Params.CurrentDirData = NULL; findHandle = FindFirstFile (FilePath, &findData); if (findHandle == INVALID_HANDLE_VALUE) { return NULL; } Params.FindData = &findData; Params.VirtualFile = FALSE; checkSum = ComputeCheckSum (&Params); sprintf (result, "0x%08lX", checkSum); FindClose (findHandle); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryFilePECheckSum ( IN PCSTR FilePath ) { ULONG checkSum; TCHAR result[sizeof (ULONG) * 2 + 2]; checkSum = GetPECheckSum (FilePath); if (checkSum == 0) { return NULL; } sprintf (result, "0x%0lX", checkSum); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryBinFileVer ( IN PCSTR FilePath ) { ULONGLONG value; PWORD valueIdx; TCHAR result[24]; valueIdx = (PWORD) (&value); value = GetBinFileVer (FilePath); if (value == 0) { return NULL; } sprintf (result, "%d.%d.%d.%d", *(valueIdx + 3), *(valueIdx + 2), *(valueIdx + 1), *valueIdx); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryBinProductVer ( IN PCSTR FilePath ) { ULONGLONG value; PWORD valueIdx; TCHAR result[24]; valueIdx = (PWORD) (&value); value = GetBinProductVer (FilePath); if (value == 0) { return NULL; } sprintf (result, "%d.%d.%d.%d", *(valueIdx + 3), *(valueIdx + 2), *(valueIdx + 1), *valueIdx); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryFileDateHi ( IN PCSTR FilePath ) { DWORD value; TCHAR result[sizeof (ULONG) * 2 + 2]; value = GetFileDateHi (FilePath); if (value == 0) { return NULL; } sprintf (result, "0x%08lX", value); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryFileDateLo ( IN PCSTR FilePath ) { DWORD value; TCHAR result[sizeof (ULONG) * 2 + 2]; value = GetFileDateLo (FilePath); if (value == 0) { return NULL; } sprintf (result, "0x%08lX", value); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryFileVerOs ( IN PCSTR FilePath ) { DWORD value; TCHAR result[sizeof (ULONG) * 2 + 2]; value = GetFileVerOs (FilePath); if (value == 0) { return NULL; } sprintf (result, "0x%08lX", value); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryFileVerType ( IN PCSTR FilePath ) { DWORD value; TCHAR result[sizeof (ULONG) * 2 + 2]; value = GetFileVerType (FilePath); if (value == 0) { return NULL; } sprintf (result, "0x%08lX", value); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryPrevOsMajorVersion ( IN PCSTR FilePath ) { OSVERSIONINFO osInfo; TCHAR result[20]; ZeroMemory (&osInfo, sizeof (OSVERSIONINFO)); osInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&osInfo); sprintf (result, "%ld", osInfo.dwMajorVersion); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryPrevOsMinorVersion ( IN PCSTR FilePath ) { OSVERSIONINFO osInfo; TCHAR result[20]; ZeroMemory (&osInfo, sizeof (OSVERSIONINFO)); osInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&osInfo); sprintf (result, "%ld", osInfo.dwMinorVersion); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryPrevOsPlatformId ( IN PCSTR FilePath ) { OSVERSIONINFO osInfo; TCHAR result[20]; ZeroMemory (&osInfo, sizeof (OSVERSIONINFO)); osInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&osInfo); sprintf (result, "%ld", osInfo.dwPlatformId); return PoolMemDuplicateString (g_DataObjectPool, result); } PCTSTR QueryPrevOsBuildNo ( IN PCSTR FilePath ) { OSVERSIONINFO osInfo; TCHAR result[20]; ZeroMemory (&osInfo, sizeof (OSVERSIONINFO)); osInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&osInfo); sprintf (result, "%ld", osInfo.dwBuildNumber); return PoolMemDuplicateString (g_DataObjectPool, result); } BOOL OutputDecValue ( IN PCSTR VersionValue, OUT DWORD *Size, OUT PBYTE *Data ) { PDWORD result; result = MemAlloc (g_hHeap, 0, sizeof (DWORD)); if (!result) { return FALSE; } sscanf (VersionValue, "%ld", result); *Data = (PBYTE)result; *Size = sizeof (DWORD); return TRUE; } BOOL OutputHexValue ( IN PCSTR VersionValue, OUT DWORD *Size, OUT PBYTE *Data ) { PDWORD result; result = MemAlloc (g_hHeap, 0, sizeof (DWORD)); if (!result) { return FALSE; } sscanf (VersionValue, "%lx", result); *Data = (PBYTE)result; *Size = sizeof (DWORD); return TRUE; } BOOL OutputModuleTypeValue ( IN PCSTR VersionValue, OUT DWORD *Size, OUT PBYTE *Data ) { PDWORD result; result = MemAlloc (g_hHeap, 0, sizeof (DWORD)); if (!result) { return FALSE; } *result = 0; if (StringIMatch (VersionValue, "NONE")) { *result = 0; } if (StringIMatch (VersionValue, "DOS")) { *result = 1; } if (StringIMatch (VersionValue, "WIN16")) { *result = 2; } if (StringIMatch (VersionValue, "WIN32")) { *result = 3; } *Data = (PBYTE)result; *Size = sizeof (DWORD); return TRUE; } BOOL OutputStrValue ( IN PCSTR VersionValue, OUT DWORD *Size, OUT PBYTE *Data ) { PWSTR result; PCWSTR convStr; convStr = ConvertAtoW (VersionValue); *Size = (wcslen (convStr) + 1) * sizeof (WCHAR); result = MemAlloc (g_hHeap, 0, *Size); if (!result) { return FALSE; } StringCopyW (result, convStr); FreeConvertedStr (convStr); *Data = (PBYTE)result; return TRUE; } typedef struct { ULONGLONG Value; ULONGLONG Mask; } BINVER_DATA, *PBINVER_DATA; BOOL OutputBinVerValue ( IN PCSTR VersionValue, OUT DWORD *Size, OUT PBYTE *Data ) { PBINVER_DATA result; PWORD maskIdx; PWORD valueIdx; UINT index; result = MemAlloc (g_hHeap, 0, sizeof (BINVER_DATA)); if (!result) { return FALSE; } result->Value = 0; result->Mask = 0; *Size = sizeof (BINVER_DATA); maskIdx = (PWORD)&(result->Mask) + 3; valueIdx = (PWORD)&(result->Value) + 3; index = 0; while (VersionValue && *VersionValue) { *valueIdx = (WORD) strtoul ((PSTR)VersionValue, &((PSTR)VersionValue), 10); if (*VersionValue && (_mbsnextc (VersionValue) != '.')) { *Data = (PBYTE)result; return TRUE; } VersionValue = _mbsinc (VersionValue); *maskIdx = 0xFFFF; valueIdx --; maskIdx --; index ++; if (index >= 4) { break; } } *Data = (PBYTE)result; return TRUE; } BOOL OutputUpToBinVerValue ( IN PCSTR VersionValue, OUT DWORD *Size, OUT PBYTE *Data ) { PULONGLONG result; PWORD valueIdx; UINT index; result = MemAlloc (g_hHeap, 0, sizeof (ULONGLONG)); if (!result) { return FALSE; } *result = 0; *Size = sizeof (ULONGLONG); valueIdx = (PWORD)result + 3; index = 0; while (VersionValue && *VersionValue) { *valueIdx = (WORD) strtoul ((PSTR)VersionValue, &((PSTR)VersionValue), 10); if (*VersionValue && (_mbsnextc (VersionValue) != '.')) { *Data = (PBYTE)result; return TRUE; } VersionValue = _mbsinc (VersionValue); valueIdx --; index ++; if (index >= 4) { break; } } *Data = (PBYTE)result; return TRUE; } typedef PCTSTR (VERSION_QUERY_PROTOTYPE) (PCTSTR FilePath); typedef VERSION_QUERY_PROTOTYPE * PVERSION_QUERY_PROTOTYPE; typedef BOOL (VERSION_OUTPUT_PROTOTYPE) (PCTSTR VersionValue, DWORD *Size, PBYTE *Data); typedef VERSION_OUTPUT_PROTOTYPE * PVERSION_OUTPUT_PROTOTYPE; typedef struct _VERSION_DATA { DWORD VersionId; PCSTR VersionName; PCSTR DisplayName; PCSTR VersionValue; DWORD Allowance; BOOL Modifiable; PVERSION_QUERY_PROTOTYPE VersionQuery; PVERSION_OUTPUT_PROTOTYPE VersionOutput; } VERSION_DATA, *PVERSION_DATA; #define LIBARGS(id, fn) {id, #define TOOLARGS(name, dispName, allowance, edit, query, output) name,dispName,NULL,allowance,edit,query,output}, VERSION_DATA g_ToolVersionData [] = { VERSION_STAMPS {0, NULL, NULL, NULL, 0, FALSE, NULL, NULL} }; #undef TOOLARGS #undef LIBARGS VOID pGatherFilesAttributes ( VOID ) { PDATAOBJECT Data; MULTISZ_ENUM multiSzEnum; PSTR filePath; PVERSION_DATA p; PITEM_INFO info; UINT versionIdx; TCHAR buffer [MEMDB_MAX]; p = g_ToolVersionData; versionIdx = 0; while (p->VersionName) { p->VersionValue = p->VersionQuery(g_MainFile); if ((p->VersionValue) && (p->Allowance & VA_ALLOWMAINFILE)) { Data = (PDATAOBJECT) GrowBuffer (&g_DataObjects, sizeof (DATAOBJECT)); filePath = PoolMemDuplicateString (g_DataObjectPool, g_MainFile); ReplaceWacks (filePath); sprintf (buffer, "%s - %s", p->DisplayName, p->VersionValue); Data->NameOrPath = JoinPaths (filePath, buffer); Data->Version = UPGWIZ_VERSION; Data->Flags = DOF_NO_SORT; info = (PITEM_INFO) PoolMemGetMemory (g_DataObjectPool, sizeof (ITEM_INFO)); info->FilePath = PoolMemDuplicateString (g_DataObjectPool, g_MainFile); info->VersionValue = PoolMemDuplicateString (g_DataObjectPool, p->VersionValue); info->VersionIndex = versionIdx; Data->DllParam = info; } p++; versionIdx++; } if (EnumFirstMultiSz (&multiSzEnum, g_AddnlFiles.Buf)) { do { p = g_ToolVersionData; versionIdx = 0; while (p->VersionName) { p->VersionValue = p->VersionQuery(multiSzEnum.CurrentString); if ((p->VersionValue) && (p->Allowance & VA_ALLOWADDNLFILES)) { Data = (PDATAOBJECT) GrowBuffer (&g_DataObjects, sizeof (DATAOBJECT)); filePath = PoolMemDuplicateString (g_DataObjectPool, multiSzEnum.CurrentString); ReplaceWacks (filePath); sprintf (buffer, "%s - %s", p->DisplayName, p->VersionValue); Data->NameOrPath = JoinPaths (filePath, buffer); Data->Version = UPGWIZ_VERSION; Data->Flags = DOF_NO_SORT; info = (PITEM_INFO) PoolMemGetMemory (g_DataObjectPool, sizeof (ITEM_INFO)); info->FilePath = PoolMemDuplicateString (g_DataObjectPool, multiSzEnum.CurrentString); info->VersionValue = PoolMemDuplicateString (g_DataObjectPool, p->VersionValue); info->VersionIndex = versionIdx; Data->DllParam = info; } p++; versionIdx++; } } while (EnumNextMultiSz (&multiSzEnum)); } } PDATAOBJECT GiveDataObjectList ( IN UINT DataTypeId, OUT PUINT Count ) { switch (DataTypeId) { case 0: // Bad apps pGatherFilesAttributes (); break; default: MessageBox (NULL, "Internal BadApps DLL error:00001. Please contact calinn.", "Error", MB_OK); break; } *Count = g_DataObjects.End / sizeof (DATAOBJECT); return (PDATAOBJECT) g_DataObjects.Buf; } #define ID_EDITMENUITEM 200 BOOL CALLBACK pEditItemUIProc ( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static PSTR * editStr; CHAR tempStr [MEMDB_MAX]; switch (uMsg) { case WM_INITDIALOG: editStr = ((PSTR *) lParam); pSetDefGUIFont(hdlg); SendDlgItemMessage (hdlg, IDC_MAINEDIT, WM_SETTEXT, 0, (LPARAM)(*editStr)); return FALSE; case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_MAINEDIT: if (HIWORD (wParam) == EN_CHANGE) { if (*editStr) { FreePathString (*editStr); *editStr = NULL; } SendDlgItemMessage (hdlg, IDC_MAINEDIT, WM_GETTEXT, MEMDB_MAX, (LPARAM)tempStr); *editStr = DuplicatePathString (tempStr, 0); } break; case IDOK: EndDialog (hdlg, LOWORD (wParam)); break; case IDCANCEL: case ID_QUIT: EndDialog (hdlg, LOWORD (wParam)); break; } break; } return FALSE; } BOOL Handle_RMouse ( IN HINSTANCE LocalDllInstance, IN HWND Owner, IN PDATAOBJECT DataObject, IN PPOINT pt ) { PITEM_INFO info; TCHAR buffer [MEMDB_MAX]; PVERSION_DATA p; UINT versionIdx; HMENU menu; PSTR newVersion; info = (PITEM_INFO) DataObject->DllParam; p = g_ToolVersionData; versionIdx = 0; while (p->VersionName) { if (versionIdx == info->VersionIndex) { break; } versionIdx ++; p ++; } if (!p->VersionName) { return FALSE; } if (!p->Modifiable) { return FALSE; } menu = CreatePopupMenu (); AppendMenu (menu, MF_STRING, ID_EDITMENUITEM, "Edit"); if (TrackPopupMenu (menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt->x, pt->y, 0, Owner, NULL) == ID_EDITMENUITEM) { newVersion = DuplicatePathString (info->VersionValue, 0); if (DialogBoxParam (LocalDllInstance, MAKEINTRESOURCE(IDD_EDITITEM), NULL, pEditItemUIProc, (LPARAM)(&newVersion)) == IDOK) { FreePathString (DataObject->NameOrPath); PoolMemReleaseMemory (g_DataObjectPool, (PVOID)info->VersionValue); info->VersionValue = PoolMemDuplicateString (g_DataObjectPool, newVersion); sprintf (buffer, "%s - %s", p->DisplayName, newVersion); DataObject->NameOrPath = DuplicatePathString (buffer, 0); return TRUE; } FreePathString (newVersion); } return FALSE; } PSTR pGetRelativePath ( IN PCSTR MainFile, IN PCSTR AddnlFile ) { UINT Index = 0; PCSTR p,q; CHAR result [MEMDB_MAX] = ""; PSTR resultIdx = result; p = _mbschr (MainFile, '\\'); q = _mbschr (AddnlFile, '\\'); while (p && q) { if ((p - MainFile) != (q - AddnlFile)) { break; } if (!StringIMatchByteCount (MainFile, AddnlFile, p - MainFile)) { break; } if (!StringIMatchByteCount (MainFile, AddnlFile, q - AddnlFile)) { break; } Index += (p - MainFile); MainFile = _mbsinc (p); AddnlFile = _mbsinc (q); p = _mbschr (MainFile, '\\'); q = _mbschr (AddnlFile, '\\'); } if (Index > 0) { while (p) { StringCopy (resultIdx, "..\\"); resultIdx = GetEndOfString (resultIdx); MainFile = _mbsinc (p); p = _mbschr (MainFile, '\\'); } StringCopy (resultIdx, AddnlFile); return (DuplicatePathString (result, 0)); } return NULL; } BOOL pFilesAttribOutput_MigDb ( IN HANDLE File, IN POUTPUTARGS Args ) { PITEM_INFO info; UINT sectCount; CHAR sectName [MEMDB_MAX]; PSTR relPath; MULTISZ_ENUM multiSzEnum; PDATAOBJECT Data = NULL; switch (g_AppProblem) { case APPTYPE_INC_NOBLOCK: case APPTYPE_INC_HARDBLOCK: WizardWriteRealString (File, "[Incompatible]\r\n"); break; case APPTYPE_MINORPROBLEM: WizardWriteRealString (File, "[MinorProblems]\r\n"); break; case APPTYPE_REINSTALL: WizardWriteRealString (File, "[Reinstall]\r\n"); break; default: MessageBox (NULL, "Internal BadApps DLL error:00006. Please contact calinn.", "Error", MB_OK); } WizardWriteQuotedColumn (File, Args->OptionalDescription, 30); if (g_AppProblem == APPTYPE_MINORPROBLEM) { WizardWriteRealString (File, ", %"); WizardWriteInfString (File, Args->OptionalDescription, FALSE, FALSE, TRUE, '_', 0); WizardWriteRealString (File, "%"); } if (g_AddnlFiles.Buf) { // we have additional files. We will create as many sections as needed. Data = (PDATAOBJECT) g_DataObjects.Buf; WizardWriteRealString (File, ", "); WizardWriteRealString (File, GetFileNameFromPath (g_MainFile)); while ((DWORD)Data < (DWORD)g_DataObjects.Buf + g_DataObjects.End) { if (Data->Flags & DOF_SELECTED) { info = (PITEM_INFO)Data->DllParam; if (StringIMatch (g_MainFile, info->FilePath)) { WizardWriteRealString (File, ", "); WizardWriteRealString (File, g_ToolVersionData[info->VersionIndex].VersionName); WizardWriteRealString (File, "("); WizardWriteInfString (File, info->VersionValue, TRUE, FALSE, FALSE, 0, 0); WizardWriteRealString (File, ")"); } } Data++; } sectCount = 1; if (EnumFirstMultiSz (&multiSzEnum, g_AddnlFiles.Buf)) { do { sprintf (sectName, "REQFILE(%s.Req%d)", Args->OptionalDescription, sectCount); WizardWriteRealString (File, ", "); WizardWriteInfString (File, sectName, FALSE, FALSE, TRUE, '_', 0); sectCount ++; } while (EnumNextMultiSz (&multiSzEnum)); } WizardWriteRealString (File, "\r\n"); WizardWriteRealString (File, "\r\n"); sectCount = 1; if (EnumFirstMultiSz (&multiSzEnum, g_AddnlFiles.Buf)) { do { sprintf (sectName, "[%s.Req%d]\r\n", Args->OptionalDescription, sectCount); WizardWriteInfString (File, sectName, FALSE, FALSE, TRUE, '_', 0); relPath = pGetRelativePath (g_MainFile, multiSzEnum.CurrentString); if (!relPath) { sprintf (sectName, "Could not get relative path for:%s)", multiSzEnum.CurrentString); MessageBox (NULL, sectName, "Error", MB_OK); relPath = DuplicatePathString (multiSzEnum.CurrentString, 0); } WizardWriteRealString (File, relPath); FreePathString (relPath); Data = (PDATAOBJECT) g_DataObjects.Buf; while ((DWORD)Data < (DWORD)g_DataObjects.Buf + g_DataObjects.End) { if (Data->Flags & DOF_SELECTED) { info = (PITEM_INFO)Data->DllParam; if (StringIMatch (multiSzEnum.CurrentString, info->FilePath)) { WizardWriteRealString (File, ", "); WizardWriteRealString (File, g_ToolVersionData[info->VersionIndex].VersionName); WizardWriteRealString (File, "("); WizardWriteInfString (File, info->VersionValue, TRUE, FALSE, FALSE, 0, 0); WizardWriteRealString (File, ")"); } } Data++; } WizardWriteRealString (File, "\r\n"); WizardWriteRealString (File, "\r\n"); sectCount ++; } while (EnumNextMultiSz (&multiSzEnum)); } } else { // we have only one file. We will write it in the same line. Data = (PDATAOBJECT) g_DataObjects.Buf; WizardWriteRealString (File, ", "); WizardWriteRealString (File, GetFileNameFromPath (g_MainFile)); while ((DWORD)Data < (DWORD)g_DataObjects.Buf + g_DataObjects.End) { if (Data->Flags & DOF_SELECTED) { info = (PITEM_INFO)Data->DllParam; WizardWriteRealString (File, ", "); WizardWriteRealString (File, g_ToolVersionData[info->VersionIndex].VersionName); WizardWriteRealString (File, "("); WizardWriteInfString (File, info->VersionValue, TRUE, FALSE, FALSE, 0, 0); WizardWriteRealString (File, ")"); } Data++; } WizardWriteRealString (File, "\r\n"); WizardWriteRealString (File, "\r\n"); } if (g_AppProblem == APPTYPE_MINORPROBLEM) { WizardWriteRealString (File, "[Strings]\r\n"); WizardWriteInfString (File, Args->OptionalDescription, FALSE, FALSE, TRUE, '_', 0); WizardWriteRealString (File, "="); WizardWriteInfString (File, Args->OptionalText, TRUE, TRUE, FALSE, 0, 0); WizardWriteRealString (File, "\r\n"); WizardWriteRealString (File, "\r\n"); } return TRUE; } BOOL pWriteBlob ( IN HANDLE File, IN PBYTE Data, IN DWORD Size, IN DWORD LineLen ) { CHAR result[4]; DWORD lineLen = 0; while (Size>1) { sprintf (result, "%02X,", *Data); WizardWriteRealString (File, result); lineLen += 3; if (lineLen >= LineLen) { WizardWriteRealString (File, "\\\r\n"); lineLen = 0; } Size --; Data ++; } if (Size) { sprintf (result, "%02X", *Data); WizardWriteRealString (File, result); } return TRUE; } BOOL pFilesAttribOutput_BadApps ( IN HANDLE File, IN POUTPUTARGS Args ) { PSTR fullKey; GROWBUFFER Buffer = GROWBUF_INIT; BADAPP_PROP appProp; PDATAOBJECT DataObject = NULL; PITEM_INFO info; PVERSION_DATA p; UINT versionIdx; PBYTE Data; DWORD DataSize; DWORD TotalSize = 0; MULTISZ_ENUM multiSzEnum; PSTR relPath; CHAR tmpStr[MEMDB_MAX]; WizardWriteRealString (File, "HKLM,"); fullKey = JoinPaths ("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility", GetFileNameFromPath (g_MainFile)); WizardWriteQuotedColumn (File, fullKey, 0); FreePathString (fullKey); WizardWriteRealString (File, ","); WizardWriteQuotedColumn (File, "Sequencer", 0); WizardWriteRealString (File, ",0x00030003,\\\r\n"); //now it's a good time to generate the BLOB //first thing - add data about MsgId and the app problem appProp.Size = sizeof (BADAPP_PROP); appProp.MsgId = g_MsgId; appProp.AppType = 0; appProp.AppType = g_AppProblem | g_AppFlags; CopyMemory (GrowBuffer (&Buffer, sizeof (BADAPP_PROP)), &appProp, sizeof (BADAPP_PROP)); TotalSize += sizeof (BADAPP_PROP); //next - add data about main file attributes DataObject = (PDATAOBJECT) g_DataObjects.Buf; while ((DWORD)DataObject < (DWORD)g_DataObjects.Buf + g_DataObjects.End) { if (DataObject->Flags & DOF_SELECTED) { info = (PITEM_INFO)DataObject->DllParam; if (StringIMatch (g_MainFile, info->FilePath)) { p = g_ToolVersionData; versionIdx = 0; while (p->VersionName) { if (versionIdx == info->VersionIndex) { break; } versionIdx ++; p ++; } if (p->VersionName) { if (p->VersionOutput (info->VersionValue, &DataSize, &Data)) { CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &(p->VersionId), sizeof (DWORD)); TotalSize += sizeof (DWORD); CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &DataSize, sizeof (DWORD)); TotalSize += sizeof (DWORD); CopyMemory (GrowBuffer (&Buffer, DataSize), Data, DataSize); TotalSize += DataSize; MemFree (g_hHeap, 0, Data); } } } } DataObject++; } if (g_AddnlFiles.Buf) { // we have additional files. We will create as many sections as needed. if (EnumFirstMultiSz (&multiSzEnum, g_AddnlFiles.Buf)) { do { relPath = pGetRelativePath (g_MainFile, multiSzEnum.CurrentString); if (!relPath) { sprintf (tmpStr, "Could not get relative path for:%s)", multiSzEnum.CurrentString); MessageBox (NULL, tmpStr, "Error", MB_OK); relPath = DuplicatePathString (multiSzEnum.CurrentString, 0); } // now let's write the addnl file in UNICODE DataSize = VTID_REQFILE; CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &DataSize, sizeof (DWORD)); TotalSize += sizeof (DWORD); OutputStrValue (relPath, &DataSize, &Data); CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &DataSize, sizeof (DWORD)); TotalSize += sizeof (DWORD); CopyMemory (GrowBuffer (&Buffer, DataSize), Data, DataSize); TotalSize += DataSize; MemFree (g_hHeap, 0, Data); DataObject = (PDATAOBJECT) g_DataObjects.Buf; while ((DWORD)DataObject < (DWORD)g_DataObjects.Buf + g_DataObjects.End) { if (DataObject->Flags & DOF_SELECTED) { info = (PITEM_INFO)DataObject->DllParam; if (StringIMatch (multiSzEnum.CurrentString, info->FilePath)) { p = g_ToolVersionData; versionIdx = 0; while (p->VersionName) { if (versionIdx == info->VersionIndex) { break; } versionIdx ++; p ++; } if (p->VersionName) { if (p->VersionOutput (info->VersionValue, &DataSize, &Data)) { CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &(p->VersionId), sizeof (DWORD)); TotalSize += sizeof (DWORD); CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &DataSize, sizeof (DWORD)); TotalSize += sizeof (DWORD); CopyMemory (GrowBuffer (&Buffer, DataSize), Data, DataSize); TotalSize += DataSize; MemFree (g_hHeap, 0, Data); } } } } DataObject++; } } while (EnumNextMultiSz (&multiSzEnum)); } } DataSize = 0; CopyMemory (GrowBuffer (&Buffer, sizeof (DWORD)), &DataSize, sizeof (DWORD)); TotalSize += sizeof (DWORD); //now it's a good time to write the BLOB pWriteBlob (File, Buffer.Buf, TotalSize, 80); return TRUE; } BOOL GenerateOutput ( IN POUTPUTARGS Args ) { BOOL b = FALSE; HANDLE File; CHAR Path[MAX_MBCHAR_PATH]; switch (Args->DataTypeId) { case 0: // bad apps wsprintf (Path, "%s\\badapps.txt", Args->OutboundDir); break; default: MessageBox (NULL, "Internal BadApps DLL error:00002. Please contact calinn.", "Error", MB_OK); } printf ("Saving data to %s\n\n", Path); File = CreateFile ( Path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (File == INVALID_HANDLE_VALUE) { printf ("Can't open file for output.\n"); return FALSE; } __try { SetFilePointer (File, 0, NULL, FILE_END); // // Write user name and date/time // if (!WriteHeader (File)) { __leave; } switch (Args->DataTypeId) { case 0: // bad apps if (g_SaveMigDb) { b = pFilesAttribOutput_MigDb (File, Args); } else { b = TRUE; } b = b && pFilesAttribOutput_BadApps (File, Args); break; default: MessageBox (NULL, "Internal BadApps DLL error:00003. Please contact calinn.", "Error", MB_OK); } // // Write a final blank line // b = b && WizardWriteRealString (File, "\r\n"); } __finally { CloseHandle (File); } return b; } BOOL DisplayOptionalUI ( IN POUTPUTARGS Args ) { switch (Args->DataTypeId) { case 0: if (g_AppProblem == APPTYPE_MINORPROBLEM) { g_DataTypes[Args->DataTypeId].Flags |= (DTF_REQUIRE_TEXT); } break; default: MessageBox (NULL, "Internal BadApps DLL error:00005. Please contact calinn.", "Error", MB_OK); } return TRUE; }