//#define __DEBUG 1 #include "compatadmin.h" #include "dbviewer.h" #include "dbsearch.h" #include "xmldialog.h" #include "psapi.h" BOOL g_bWin2K = FALSE; void __cdecl Terminate_Handler() { MessageBox(NULL,TEXT("Uncaught Exception raised!"),TEXT("Error"),MB_ICONERROR); WIN_MSG(); abort(); } /*....................................................................................*/ BOOL SearchGroupForSID( DWORD dwGroup, BOOL* pfIsMember ) { PSID pSID = NULL; SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; BOOL fRes = TRUE; if ( !AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, dwGroup, 0, 0, 0, 0, 0, 0, &pSID) ) { fRes = FALSE; } if ( !CheckTokenMembership(NULL, pSID, pfIsMember) ) { fRes = FALSE; } if (pSID) FreeSid(pSID); return fRes; } BOOL IsAdmin( void ) { BOOL fIsUser, fIsAdmin; if ( !SearchGroupForSID(DOMAIN_ALIAS_RID_USERS, &fIsUser) || !SearchGroupForSID(DOMAIN_ALIAS_RID_ADMINS, &fIsAdmin) // || !SearchGroupForSID(DOMAIN_ALIAS_RID_POWER_USERS, &fIsPowerUser) ) { return FALSE; } return(fIsUser && fIsAdmin ); } /*....................................................................................*/ CDatabase& CApplication::GetDBGlobal() { return (this->m_DBGlobal); } CDatabase& CApplication::GetDBLocal() { return (this->m_DBLocal); } //***************************************************************************** // // Global Variables // //***************************************************************************** UINT g_uDPFLevel = DPF_LEVEL; UINT g_uProfileDPFLevel = DPF_LEVEL; TESTRUN g_TestRun; HANDLE g_hTestRunExec; CSTRING g_szTestFile; BOOL CALLBACK SplashProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //***************************************************************************** // Class: CApplication // // Function: Constructor // // Notes: None // // History: // // A-COWEN Nov 8, 2000 Implemented it. //***************************************************************************** CApplication::CApplication() { if ( !IsAdmin() ) {// Admin rights MessageBox(NULL,TEXT("You need administrative rights to run this program. Please contact your system administrator"),TEXT("CompatAdmin"),MB_ICONERROR); #ifndef __DEBUG ExitThread(1); #endif } // //Check if the OS is Win2k // OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx (&osvi); if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0)) { g_bWin2K = TRUE; } set_terminate(Terminate_Handler); CDatabase::CleanUp(); g_uButtons = 0; m_hDialog = NULL; m_hAccelerator = NULL; m_hKey = NULL; m_pCurrentView = NULL; m_hMenu = NULL; /* Moved to CDatabase::CDatabase m_pDB = NULL; m_pRecordHead = NULL; m_pShimList = NULL; m_pLayerList = NULL; */ m_MainButtons[g_uButtons].iBitmap = 0; m_MainButtons[g_uButtons].idCommand = ID_FILE_NEWDATABASE; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; m_MainButtons[g_uButtons].iBitmap = 1; m_MainButtons[g_uButtons].idCommand = ID_FILE_OPENDATABASE; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; m_MainButtons[g_uButtons].iBitmap = 2; m_MainButtons[g_uButtons].idCommand = ID_FILE_SAVEDATABASE; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; /* // Email m_MainButtons[g_uButtons].iBitmap = 3; m_MainButtons[g_uButtons].idCommand = 3; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; // Print m_MainButtons[g_uButtons].iBitmap = 6; m_MainButtons[g_uButtons].idCommand = 0; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_SEP; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; m_MainButtons[g_uButtons].iBitmap = 4; m_MainButtons[g_uButtons].idCommand = 4; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; // Print preview m_MainButtons[g_uButtons].iBitmap = 5; m_MainButtons[g_uButtons].idCommand = 5; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; */ m_MainButtons[g_uButtons].iBitmap = 6; m_MainButtons[g_uButtons].idCommand = 0; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_SEP; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; m_MainButtons[g_uButtons].iBitmap = 20; m_MainButtons[g_uButtons].idCommand = ID_WINDOWS_SEARCHFORFIXES; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; m_MainButtons[g_uButtons].iBitmap = 14; m_MainButtons[g_uButtons].idCommand = ID_WINDOWS_DATABASEVIEWER; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; m_MainButtons[g_uButtons].iBitmap = 6; m_MainButtons[g_uButtons].idCommand = 0; m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED; m_MainButtons[g_uButtons].fsStyle = TBSTYLE_SEP; m_MainButtons[g_uButtons].dwData = 0; m_MainButtons[g_uButtons].iString = 0; ++g_uButtons; } //***************************************************************************** // Class: CApplication // // Function: msgCreate // // Notes: Perform application initialization. // // History: // // A-COWEN Nov 8, 2000 Initial Implementation: Center // window and open registry. //***************************************************************************** void CApplication::msgCreate(void) { RECT rRect; int nX; int nY; m_hAccelerator = LoadAccelerators(g_hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1) ); m_hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MAINMENU)); m_hToolBitmap = LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDR_MAINTOOLBAR)); SetMenu(m_hWnd,m_hMenu); WINDOWPLACEMENT Place; Place.length = sizeof(WINDOWPLACEMENT); Place.flags = 0; Place.showCmd = SW_SHOW; // Center the application window on the screen. GetWindowRect(m_hWnd,&rRect); // Compute actual width and height rRect.right -= rRect.left; rRect.bottom -= rRect.top; // Resolve X,Y location required to center whole window. nX = (GetSystemMetrics(SM_CXSCREEN) - rRect.right) / 2; nY = (GetSystemMetrics(SM_CYSCREEN) - rRect.bottom) / 2; // Move the window to the center location. ::MoveWindow(m_hWnd,nX,nY,rRect.right,rRect.bottom,TRUE); Place.showCmd = SW_SHOW; Place.rcNormalPosition.left = nX; Place.rcNormalPosition.top = nY; Place.rcNormalPosition.right = rRect.right; Place.rcNormalPosition.bottom = rRect.top; ReadReg(TEXT("WNDPLACE"),&Place,sizeof(WINDOWPLACEMENT)); // Open the registry. if ( ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_CURRENT_USER,APP_KEY,0,KEY_ALL_ACCESS, &m_hKey) ) { if ( ::RegCreateKeyEx(HKEY_CURRENT_USER,APP_KEY,0,TEXT(""),REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_hKey, NULL) != ERROR_SUCCESS ) { MessageBox(NULL,TEXT("There was an error while launching the program. The program will now terminate"),TEXT("Error"),MB_ICONERROR); ExitThread(1); } } // Read default profile information for the application. ReadReg(TEXT("DPFLEVEL"),&g_uDPFLevel,sizeof(UINT)); ReadReg(TEXT("PROFILEDPF"),&g_uProfileDPFLevel,sizeof(UINT)); // Create the status bar InitCommonControls(); m_hStatusBar = CreateStatusWindow( WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP | WS_CLIPSIBLINGS, TEXT(""), m_hWnd, STATUS_ID); // Create the toolbar /* m_hToolBar = CreateToolbarEx( m_hWnd, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, TOOLBAR_ID, 23, g_hInstance, IDR_MAINTOOLBAR, m_MainButtons, g_uButtons, 16, 16, 16, 16, sizeof(TBBUTTON)); // Add common control system images to the toolbar TBADDBITMAP Bmp; Bmp.hInst = HINST_COMMCTRL; Bmp.nID = IDB_STD_SMALL_COLOR; m_uStandardImages = SendMessage(g_theApp.m_hToolBar,TB_ADDBITMAP,1,(LPARAM) &Bmp); */ // Create the views used in the app m_ViewList[VIEW_DATABASE].pView = new CDBView; if ( NULL != m_ViewList[VIEW_DATABASE].pView ) if ( !m_ViewList[VIEW_DATABASE].pView->Initialize() ) { DPF(1,TEXT("Creating the DB View failed")); } /// dddd what is happening here.... m_ViewList[VIEW_SEARCHDB].pView = new CDBSearch; if ( NULL != m_ViewList[VIEW_SEARCHDB].pView ) if ( !m_ViewList[VIEW_SEARCHDB].pView->Initialize() ) { DPF(1,TEXT("Creating the DB Search View failed")); } m_DBLocal.NewDatabase(FALSE); // The above function swith FALSE paramter closes the databases and makes other changes such as // activates the view etc, so that the cahnges are seen in the window heading TCHAR szShimDB[MAX_PATH_BUFFSIZE]; GetSystemWindowsDirectory(szShimDB, MAX_PATH); lstrcat(szShimDB,TEXT("\\AppPatch\\sysmain.sdb")); //Create the opening Modeless Dlg box HWND hSplash = CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_SPLASH),m_hWnd,(DLGPROC)SplashProc); ShowWindow(hSplash,SW_SHOWNORMAL); UpdateWindow(hSplash); if ( !m_DBGlobal.OpenDatabase( CSTRING(szShimDB),TRUE) ){ MessageBox(NULL,szShimDB,TEXT("Failed to open the data base !"),MB_OK); } if ( NULL != m_DBGlobal.m_pDB ) { SdbCloseDatabase(m_DBGlobal.m_pDB); } DestroyWindow(hSplash); GetDBGlobal().m_pDB = NULL; // Activate the default view. ActivateView(m_ViewList[VIEW_DATABASE].pView); //SetWindowPlacement(m_hWnd,&Place); } //***************************************************************************** // Class: CApplication // // Function: ActivateView // // Notes: Deactivate the current view and activate the view specified. // // History: // // A-COWEN Nov 29, 2000 Implemented it. //***************************************************************************** void CApplication::ActivateView(CView * pView, BOOL fNewCreate ) { if ( NULL != m_pCurrentView ) { ShowWindow(m_pCurrentView->m_hWnd,SW_HIDE); m_pCurrentView->Deactivate();//Does nothing !! } // Make sure only the main toolbar buttons are active /* while (TRUE == SendMessage(m_hToolBar,TB_DELETEBUTTON,g_uButtons,0)); */ m_pCurrentView = pView; RECT rRect; GetWindowRect(m_hWnd,&rRect); if ( NULL != pView ) { ShowWindow(pView->m_hWnd,SW_SHOW); UpdateWindow(pView->m_hWnd); pView->Activate(fNewCreate); if ( NULL == pView->m_hMenu ) SetMenu(m_hWnd,m_hMenu); else SetMenu(m_hWnd,pView->m_hMenu); } // Cause the views to be resized to fit in the current parent window. msgResize(rRect.right - rRect.left, rRect.bottom - rRect.top); } //***************************************************************************** // Class: CApplication // // Function: ReadReg // // Notes: Simplified registry profile routine. This is only // valid after msgCreate is called. ReadReg always references // the application's registry profile. // // History: // // A-COWEN Nov 8, 2000 Implemented it. //***************************************************************************** UINT CApplication::ReadReg( LPCTSTR szKey, PVOID pData, UINT uSize) { ULONG uBytes = uSize; ULONG uType; // // we are calling registry fns here with no regard for an underlying type // if ( FAILED(::RegQueryValueEx(m_hKey,szKey,NULL,&uType,(LPBYTE) pData, &uBytes)) ) return(UINT) -1; // Return the number of bytes read. return uBytes; } //***************************************************************************** // Class: CApplication // // Function: WriteReg // // Notes: Simplified registry profile writing routine. This is only // valid after msgCreate is called. WriteReg always references // the application's registry profile. // // History: // // A-COWEN Nov 8, 2000 Implemented it. //***************************************************************************** UINT CApplication::WriteReg( LPCTSTR szKey, UINT uType, PVOID pData, UINT uSize) { if ( FAILED(::RegSetValueEx(m_hKey,szKey,0,uType,(const BYTE *) pData, uSize)) ) return(UINT) -1; // Return the number of bytes written. return uSize; } //***************************************************************************** // Class: CApplication // // Function: msgClose // // Notes: Monitor for application shutdown. When a close was requested, // at the application level, it's time to shutdown the application. // Also close registry profile. // // History: // // A-COWEN Nov 8, 2000 Implemented it. //***************************************************************************** void CApplication::msgClose(void) { // Post WM_QUIT to the message queue. SendMessage(m_hWnd,WM_COMMAND,ID_FILE_EXIT,(LPARAM)m_hWnd); } //***************************************************************************** // Class: CApplication // // Function: msgResize // // Notes: Watch for notifications to resize the main window. Update child // windows appropriately. // // History: // // A-COWEN Nov 8, 2000 Implemented it. //***************************************************************************** void CApplication::msgResize(UINT uWidth, UINT uHeight) { // Resize the current view. if ( NULL != m_pCurrentView ) { RECT rRect; UINT uToolSize = 0; UINT uStatusSize; //GetWindowRect(m_hToolBar,&rRect); //uToolSize = rRect.bottom - rRect.top; GetWindowRect(m_hStatusBar,&rRect); uStatusSize = rRect.bottom - rRect.top; GetClientRect(m_hWnd,&rRect); MoveWindow( m_pCurrentView->m_hWnd, 0, uToolSize, rRect.right, rRect.bottom - (uToolSize + uStatusSize), TRUE); } UINT uWidths[] = {uWidth - 300, uWidth - 100, -1}; SendMessage(m_hStatusBar,SB_SETPARTS,sizeof(uWidths)/sizeof(UINT),(LPARAM) uWidths); SendMessage(m_hStatusBar,SB_SETTEXTW,(sizeof(uWidths)/sizeof(UINT)) | SBT_NOBORDERS,(LPARAM)TEXT("")); // Move and resize the status bar, then force repaint. SendMessage(m_hStatusBar,WM_SIZE,0,0); // Resize the toolbar //SendMessage(m_hToolBar,WM_SIZE,0,0); } //***************************************************************************** // Class: CApplication // // Function: msgNotify // // Notes: Watch for notifications to the parent. If the notifications // are not handled by the main application class, they are passed // to the current viewport for processing. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** void CApplication::msgNotify(LPNMHDR pHdr) { // Send any unprocessed notifications to the view. // // BUGBUG : Please move all the strings to the .rc file // let's write a method in CSTRING that allows you to load them // from the resource file // switch ( pHdr->code ) { case TBN_GETINFOTIP: { LPNMTBGETINFOTIP pTip = (LPNMTBGETINFOTIP) pHdr; static TCHAR * szTips[] = { TEXT("New Database"), TEXT("Open Database"), TEXT("Save Database"), TEXT("Send Database via Email"), TEXT("Print"), TEXT("Print Preview"), TEXT("Search for fixes"), TEXT("Database View")}; switch ( pTip->iItem ) { case ID_FILE_NEWDATABASE: lstrcpy(pTip->pszText,TEXT("New Database")); break; case ID_FILE_OPENDATABASE: lstrcpy(pTip->pszText,TEXT("Open Database")); break; case ID_FILE_SAVEDATABASE: lstrcpy(pTip->pszText,TEXT("Save Database")); break; case ID_WINDOWS_SEARCHFORFIXES: lstrcpy(pTip->pszText,TEXT("Search for fixes")); break; case ID_WINDOWS_DATABASEVIEWER: lstrcpy(pTip->pszText,TEXT("Database View")); break; } } break; } if ( NULL != m_pCurrentView ) m_pCurrentView->msgNotify(pHdr); } void CApplication::msgChar(TCHAR chChar) { // Send any unprocessed notifications to the view. if ( NULL != m_pCurrentView ) m_pCurrentView->msgChar(chChar); } //***************************************************************************** // Class: CApplication // // Function: msgCommand // // Notes: Watch for user input that indicates an action we should take. // If it's not a global action, pass the command on to the current // view to handle it. // // History: // // A-COWEN Nov 31, 2000 Implemented it. //***************************************************************************** void CApplication::msgCommand(UINT uID, HWND hSender) { switch ( uID ) { case ID_FILE_NEWDATABASE: { HWND hWnd = GetFocus(); if ( GetDBLocal().m_bDirty ) { int nResult = MessageBox(m_hWnd,TEXT("The current database has changed\nWould you like to save the current database changes?"),TEXT("CompatAdmin"),MB_YESNOCANCEL | MB_ICONWARNING); if ( IDCANCEL == nResult ) break; if ( IDYES == nResult ) SendMessage(m_hWnd,WM_COMMAND,ID_FILE_SAVEDATABASE,(LPARAM)m_hWnd); } GetDBLocal().NewDatabase(TRUE); UpdateView(); SetFocus(hWnd); } break; case ID_HELP_ABOUT: { ShellAbout(m_hWnd,TEXT("Application Compatibility Administrator"),TEXT(""),LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_COMPATADMIN))); } break; case ID_FILE_EXIT: { if ( m_DBLocal.m_bDirty ) { int nResult = MessageBox(m_hWnd,TEXT("The current database has changed\nWould you like to save the current database changes?"),TEXT("CompatAdmin"),MB_YESNOCANCEL | MB_ICONWARNING); if ( IDCANCEL == nResult ) break; if ( IDYES == nResult ) SendMessage(m_hWnd,WM_COMMAND,ID_FILE_SAVEDATABASE,(LPARAM)m_hWnd); } WINDOWPLACEMENT Place; Place.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(m_hWnd,&Place); WriteReg(TEXT("WNDPLACE"),REG_BINARY,&Place,sizeof(WINDOWPLACEMENT)); CDatabase::CleanUp(); PostQuitMessage(0); m_ViewList[VIEW_DATABASE].pView->msgClose(); m_ViewList[VIEW_SEARCHDB].pView->msgClose(); // Close the registry ::RegCloseKey(m_hKey); } break; case ID_FILE_OPENDATABASE: { OPENFILENAME ofn; TCHAR szFilename[MAX_PATH_BUFFSIZE]; TCHAR szShimDB[MAX_PATH_BUFFSIZE]; HWND hWnd = GetFocus(); *szFilename = *szShimDB = 0; if ( GetDBLocal().m_bDirty ) { int nResult = MessageBox(m_hWnd,TEXT("The current database has changed\nWould you like to save the current database changes?"),TEXT("CompatAdmin"),MB_YESNOCANCEL | MB_ICONWARNING); if ( IDCANCEL == nResult ) break; if ( IDYES == nResult ) SendMessage(m_hWnd,WM_COMMAND,ID_FILE_SAVEDATABASE,(LPARAM)m_hWnd); } GetSystemWindowsDirectory(szShimDB, MAX_PATH); lstrcat(szShimDB, TEXT("\\AppPatch")); ZeroMemory(&ofn,sizeof(OPENFILENAME)); ZeroMemory(szFilename,sizeof(szFilename)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = m_hWnd; ofn.hInstance = g_hInstance; ofn.lpstrFilter = TEXT("Compatibility DB (*.SDB)\0*.SDB\0\0"); ofn.lpstrFile = szFilename; ofn.nMaxFile = MAX_PATH; //ofn.lpstrInitialDir = szShimDB; ofn.lpstrTitle = TEXT("Open Compatibility Database"); ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST| OFN_HIDEREADONLY; ofn.lpstrDefExt = TEXT("SDB"); if ( GetOpenFileName(&ofn) ) { CSTRING szFileCheck = szFilename; szFileCheck.ShortFilename(); if ( CDatabase::SystemDB(szFilename) ) { MessageBox(m_hWnd,TEXT("Access to this database is restricted. \nIf you have created this custom database, please change the name of the database or contact the provider of this database"),TEXT("Access violation"),MB_ICONERROR); } if ( ! m_DBLocal.OpenDatabase(CSTRING(szFilename),FALSE) ) { MessageBox(m_hWnd,TEXT("An error occured attempting to open the database specified."),TEXT("Unable to open database"),MB_OK | MB_ICONERROR); } } SetFocus(hWnd); } break; case ID_FILE_SAVEDATABASE: { CSTRING szFilename; HWND hWnd = GetFocus(); if ( GetDBLocal().m_szCurrentDatabase.Length() == 0 ) { if ( GetFilename(TEXT("Save Database"),TEXT("Compatibility DB (*.SDB)\0*.SDB\0\0"), TEXT(""), TEXT("SDB"), OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, FALSE, szFilename) ) GetDBLocal().SaveDatabase(szFilename); } else m_DBLocal.SaveDatabase(GetDBLocal().m_szCurrentDatabase); SetFocus(hWnd); UpdateView(); } break; case ID_FILE_SAVEDATABASEAS: { CSTRING szFilename; HWND hWnd = GetFocus(); if ( GetFilename(TEXT("Save Database As"),TEXT("Compatibility DB (*.SDB)\0*.SDB\0\0"), TEXT(""), TEXT("SDB"), OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, FALSE, szFilename) ) { m_DBLocal.SaveDatabase(szFilename); SetFocus(hWnd); UpdateView(); } } break; case ID_WINDOWS_SEARCHFORFIXES: { SetStatusText(0,CSTRING(TEXT("Search for fixes"))); SetStatusText(2,CSTRING(TEXT(""))); ActivateView(m_ViewList[VIEW_SEARCHDB].pView); } break; case ID_WINDOWS_DATABASEVIEWER: { ActivateView(m_ViewList[VIEW_DATABASE].pView,FALSE); } break; default: if ( NULL != m_pCurrentView ) m_pCurrentView->msgCommand(uID,hSender); } } //***************************************************************************** // Class: CApplication // // Function: MessagePump // // Notes: The main application message pump. // // History: // // A-COWEN Nov 8, 2000 Implemented it. //***************************************************************************** int CApplication::MessagePump(void) { MSG msg; while ( GetMessage(&msg,NULL,0,0) ) { // Support modeless dialog message processing. If the message // is destined for a modeless dialog, do not translate and dispatch // as IsDialogMessage() will do that automatically. if ( NULL == m_hDialog || !IsDialogMessage(m_hDialog,&msg) ) { // Provide accelerator support. If an accelerator // is translated, do not call TranslateMessage(). if ( NULL == m_hAccelerator || !TranslateAccelerator(this->m_hWnd,m_hAccelerator,&msg) ) TranslateMessage(&msg); // Finally, dispatch the message to the window procedure. DispatchMessage(&msg); } } // GetMessage() returns FALSE when WM_QUIT is received. // Return the value from WM_QUIT, which is provided in WPARAM // from PostQuitMessage(); return msg.wParam; } //***************************************************************************** // Class: CApplication // // Function: AddToolbarButton // // Notes: Adds a button to the toolbar // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CApplication::AddToolbarButton(UINT uBmp, UINT uCmd, UINT uState, UINT uStyle) { /* TBBUTTON Button; Button.iBitmap = uBmp; Button.idCommand = uCmd; Button.fsState = (BYTE) uState; Button.fsStyle = (BYTE) uStyle; Button.dwData = 0; Button.iString = 0; if (0 == SendMessage(g_theApp.m_hToolBar,TB_ADDBUTTONS,1,(LPARAM) &Button)) return FALSE; */ return TRUE; } //***************************************************************************** // Class: CApplication // // Function: SetButtonState // // Notes: Sets the button state for a toolbar button. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CApplication::SetButtonState(UINT uCmd, UINT uState) { /* TBBUTTONINFO Info; Info.cbSize = sizeof(Info); Info.dwMask = TBIF_STATE; Info.fsState = (BYTE) uState; return SendMessage(g_theApp.m_hToolBar,TB_SETBUTTONINFO,uCmd,(LPARAM) &Info) ? TRUE:FALSE; */ return FALSE; } //***************************************************************************** // Class: CApplication // // Function: GetFilename // // Notes: General purpose function used for OpenFileName and GetSaveFileName // common control functions. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CApplication::GetFilename(LPCTSTR szTitle, LPCTSTR szFilter, LPCTSTR szDefaultFile, LPCTSTR szDefExt, DWORD dwFlags, BOOL bOpen, CSTRING & szStr) { OPENFILENAME ofn; TCHAR szFilename[MAX_PATH_BUFFSIZE]; BOOL bResult; ZeroMemory(&ofn,sizeof(OPENFILENAME)); ZeroMemory(szFilename,sizeof(szFilename)); //Used lstrcpyn to satisfy PREFast lstrcpyn(szFilename,szDefaultFile,sizeof(szFilename)/sizeof(TCHAR)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = m_hWnd; ofn.hInstance = g_hInstance; ///iii Perhaps this too is incorrect ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFilename; ofn.nMaxFile = MAX_PATH; ofn.lpstrInitialDir = szDefaultFile; ofn.lpstrTitle = szTitle; ofn.Flags = dwFlags | OFN_NOREADONLYRETURN | OFN_HIDEREADONLY; ofn.lpstrDefExt = szDefExt; BOOL valid = FALSE; //whether path is too long / ends with .SDB or not applicable for save mode only while (valid == FALSE) { if ( bOpen ) bResult = GetOpenFileName(&ofn); else bResult = GetSaveFileName(&ofn); if ( !bResult ) return FALSE; szStr = szFilename; if (bOpen) { return TRUE; } // //Do stuff to make sure that the file being saved has a .SDB extension and the filename is not //too long so that a .SDB file name does not get appended to it. // if ( szStr.isNULL() ) { continue; } if (!szStr.EndsWith(TEXT(".sdb"))){ if (szStr.Length() <= (MAX_PATH - 1 - 4)) { szStr.strcat(TEXT(".sdb")); valid = TRUE; } }else{ valid = TRUE; } if (valid == FALSE) { CSTRING message =TEXT("The path you entered: "); message.strcat(szStr); message.strcat(TEXT("\nis too long. Please enter a shorter path")); MessageBox(m_hWnd, message,TEXT("CompatAdmin"),MB_ICONWARNING); } }//while return TRUE; } //***************************************************************************** // Class: CApplication // // Function: InvokeEXE // // Notes: Invoke an executable with the specified command line. Then // wait for the executable to finish if desired. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CApplication::InvokeEXE(LPCTSTR szEXE, LPCTSTR szCommandLine, BOOL bWait, BOOL bDialog, BOOL bConsole) { BOOL bCreate; STARTUPINFO Start; PROCESS_INFORMATION Out; ZeroMemory(&Start,sizeof(STARTUPINFO)); Start.cb = sizeof(STARTUPINFO); bCreate = CreateProcess( szEXE, (LPWSTR)szCommandLine, NULL, NULL, FALSE, ((bConsole) ? 0:CREATE_NO_WINDOW) | NORMAL_PRIORITY_CLASS, NULL, NULL, &Start, &Out); if ( bCreate && bWait ) { CloseHandle(Out.hThread); g_hTestRunExec = Out.hProcess; DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_WAIT),m_hWnd,(DLGPROC)TestRunWait,(LPARAM)bDialog); } CloseHandle(Out.hProcess); return bCreate ? TRUE:FALSE; } // FlushCache code taken from SDBInst. typedef void (CALLBACK *pfn_ShimFlushCache)(HWND, HINSTANCE, LPSTR, int); void FlushCache(void) { HMODULE hAppHelp; pfn_ShimFlushCache pShimFlushCache; hAppHelp = LoadLibraryW(L"apphelp.dll"); if ( hAppHelp ) { pShimFlushCache = (pfn_ShimFlushCache)GetProcAddress(hAppHelp, "ShimFlushCache");//PARAMS(HMODULE,LPCSTR) if ( pShimFlushCache ) { pShimFlushCache(NULL, NULL, NULL, 0); } } } //***************************************************************************** // Class: CApplication // // Function: TestRun // // Notes: Execute the application defined by the specified record, with // the shim or layer information defined in that record. The // filename and commandline are overridable. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CApplication::TestRun(PDBRECORD pRecord, CSTRING * pszFile, CSTRING * pszCommandLine, HWND hParent) { CSTRING szCommandLine; BOOL bResult; TCHAR szPath[MAX_PATH_BUFFSIZE]; TCHAR szSystemDir[MAX_PATH_BUFFSIZE]; if ( NULL != pszFile ) g_szTestFile = *pszFile; else g_szTestFile = pRecord->szEXEName; if ( NULL == pszCommandLine ) { if ( 0 == DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_TESTRUN),hParent,(DLGPROC)TestRunDlg) ) return FALSE; } // // UnInstall and remove the earlier Test.SDB file // CDatabase::CleanUp(); // // Now make the XML, ,SDB and call InVokeExe // CSTRINGList * pXML = m_DBLocal.DisassembleRecord(pRecord,FALSE,FALSE,TRUE,TRUE,FALSE, TRUE); if ( GetCurrentDirectory(MAX_PATH,szPath) == 0 ) { #ifdef __DEBUG MessageBox(NULL,TEXT("Unable to execute GetCurrentDirectory(...)"), TEXT("Error"),MB_ICONWARNING); #endif return FALSE; } if ( GetWindowsDirectory(szSystemDir,MAX_PATH) == 0 ) { #ifdef __DEBUG MessageBox(NULL,TEXT("Unable to execute GetWindowsDirectory(...)"), TEXT("Error"),MB_ICONWARNING); #endif return FALSE; } if ( NULL != pXML ) { CSTRING szFile; lstrcpy(szPath,szSystemDir); szFile.sprintf(TEXT("%s\\AppPatch\\SysTest.XML"),szPath); if ( !m_DBLocal.WriteXML(szFile,pXML) ) { MessageBox(g_theApp.m_hWnd,TEXT("Unable to save temporary file."),TEXT("File save error"),MB_OK); return FALSE; } delete pXML; } else return FALSE; if ( lstrlen(szPath) == 3 ) szPath[2] = 0; szCommandLine.sprintf(TEXT("custom \"%s\\AppPatch\\SysTest.XML\" \"%s\\AppPatch\\Test.SDB\""),szPath,szSystemDir); bResult = CDatabase::InvokeCompiler(szCommandLine); if ( bResult ) { CSTRING szCommandLine; // // BUGBUG why no windbg? // if ( g_TestRun.bNTSD ) szCommandLine = TEXT("NTSD.EXE "); else if ( g_TestRun.bMSDEV ) szCommandLine = TEXT("MSDEV.EXE "); // Invoke the application szCommandLine.strcat(g_szTestFile); szCommandLine.strcat(TEXT(" ")); if ( NULL != pszCommandLine ) szCommandLine.strcat(*pszCommandLine); else szCommandLine.strcat(g_TestRun.szCommandLine); // If there's a layer, set the environment /* if (pRecord->szLayerName.Length() > 0) //SetEnvironmentVariable(TEXT("__COMPAT_LAYER"),pRecord->szLayerName); */ FlushCache(); CSTRING strSdbInstCommandLine; strSdbInstCommandLine.sprintf(TEXT("%s\\System32\\sdbInst.exe -q %s\\AppPatch\\Test.SDB "),(LPCTSTR)szSystemDir,(LPCTSTR)szSystemDir); if ( !InvokeEXE(NULL,strSdbInstCommandLine.pszString,TRUE,TRUE,TRUE) ) { MessageBox(m_hWnd,TEXT("There was a problem In executing the data base installer."),TEXT("CompatAdmin"),MB_ICONERROR); } if ( !InvokeEXE(NULL,szCommandLine.pszString,TRUE,TRUE,TRUE) ) { MessageBox(m_hWnd,TEXT("There was a problem executing the specified program.\nPlease provide the complete path of the executable and try again.\nPlease check that this is a executable file"),TEXT("Execution Failure"),MB_ICONERROR); } /* strSdbInstCommandLine.sprintf(TEXT("%s\\System32\\sdbInst.exe -u %s\\AppPatch\\Test.SDB "),(LPCTSTR)szSystemDir,(LPCTSTR)szSystemDir); if ( !InvokeEXE(NULL,strSdbInstCommandLine.pszString,TRUE,TRUE,TRUE) ) { MessageBox(m_hWnd,TEXT("There was a problem In executing the data base installer."),TEXT("CompatAdmin"),MB_ICONERROR); } */ //SetEnvironmentVariable(TEXT("__COMPAT_LAYER"),NULL); } #ifdef __DEBUG MessageBox(g_theApp.m_hWnd,TEXT("Now about to delete the SysTest.* files "),TEXT("Now"),MB_OK); #endif szCommandLine.sprintf(TEXT("%s\\AppPatch\\SysTest.XML"),szPath); BOOL bReturnCode; bReturnCode = DeleteFile(szCommandLine); /* szCommandLine.sprintf(TEXT("%s\\AppPatch\\Test.SDB"),szSystemDir); bReturnCode = DeleteFile(szCommandLine); */ return bResult; } //***************************************************************************** // Class: CApplication // // Function: TestRunWait // // Notes: Basic dialog that is displayed while waiting for an application // to complete. The dialog is invoked by the InvokeEXE function. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CALLBACK TestRunWait( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { // // BUGBUG: I had to use WM_USER+1024 when lParam == 0, WE do not want to show the dialog, because the dialog is // getting showed even if we call ShowWindow(hWnd,SW_HIDE); calling this seems to have no effect !! // switch (uMsg) { case WM_INITDIALOG: if (lParam == 0) { SendMessage(hWnd, WM_USER + 1024, 0, 0); ShowWindow(hWnd, SW_HIDE); } else { ShowWindow(hWnd,SW_SHOW); SetTimer(hWnd, 0, 50, NULL); } return TRUE; case WM_TIMER: { DWORD dwResult = WaitForSingleObject(g_hTestRunExec,10); if (dwResult != WAIT_TIMEOUT) { KillTimer(hWnd,0); EndDialog(hWnd,0); } break; } case WM_USER + 1024: { // // NOTE: This will not return to the dialog, and it will not get shown. // But if the process takes a long time to execute the background // might get white-washed :-( [Theoretically] // Please explore this one. // DWORD dwResult = WaitForSingleObject(g_hTestRunExec, INFINITE); EndDialog(hWnd,0); } break; } return FALSE; } //***************************************************************************** // Class: CApplication // // Function: TestRunDlg // // Notes: Dialog handling procedure that queries the user for the command // line and debugging options for a test run. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** BOOL CALLBACK TestRunDlg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch ( uMsg ) { case WM_INITDIALOG: { SetWindowText(GetDlgItem(hWnd,IDC_EXE),g_szTestFile); SendDlgItemMessage(hWnd,IDC_NONE,BM_SETCHECK,BST_CHECKED,0); } break; case WM_COMMAND: switch ( LOWORD(wParam) ) { case IDC_BROWSE: { HWND hwndFocus = GetFocus(); CSTRING szFilename; if ( g_theApp.GetFilename(TEXT("Find Program"), TEXT("Executable (*.EXE)\0*.EXE\0All Files (*.*)\0*.*\0\0"), g_szTestFile, TEXT(""), OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, TRUE, szFilename) ) { g_szTestFile = szFilename; SetWindowText(GetDlgItem(hWnd,IDC_EXE),g_szTestFile); } SetFocus( hwndFocus ); } break; case IDOK: { TCHAR szCmdLine[MAX_PATH_BUFFSIZE]; if ( BST_CHECKED == SendDlgItemMessage(hWnd,IDC_NTSD,BM_GETCHECK,0,0) ) g_TestRun.bNTSD = TRUE; else g_TestRun.bNTSD = FALSE; if ( BST_CHECKED == SendDlgItemMessage(hWnd,IDC_MSDEV,BM_GETCHECK,0,0) ) g_TestRun.bMSDEV = TRUE; else g_TestRun.bMSDEV = FALSE; GetWindowText(GetDlgItem(hWnd,IDC_COMMANDLINE),szCmdLine,MAX_PATH); g_TestRun.szCommandLine = szCmdLine; GetWindowText(GetDlgItem(hWnd,IDC_EXE),szCmdLine,MAX_PATH); g_szTestFile = szCmdLine; EndDialog(hWnd,1); } break; case IDCANCEL: EndDialog(hWnd,0); break; } } return FALSE; } //***************************************************************************** // Class: CApplication // // Function: SetStatusText // // Notes: Provides basic functionality to access the status bar for the // main application window. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** LRESULT CApplication::MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam) { switch ( uMsg ) { case WM_SETFOCUS:{ if (m_pCurrentView == NULL ) break; if ( m_pCurrentView == m_ViewList[VIEW_DATABASE].pView ){ if ( g_hWndLastFocus ) SetFocus(g_hWndLastFocus); }else{ if (m_pCurrentView == m_ViewList[VIEW_SEARCHDB].pView) { SetFocus( ((CDBSearch*)m_pCurrentView)->m_hListView ); } } break; } } return CWindow::MsgProc(uMsg,wParam,lParam); } BOOL CApplication::SetStatusText(UINT uTab, CSTRING & szText) { SendMessage(m_hStatusBar,SB_SETTEXT,uTab,(LPARAM)(szText.pszString)); return TRUE; } //***************************************************************************** // Class: CApplication // // Function: UpdateView // // Notes: Provides basic functionality to force the application to update // the current view. // // History: // // A-COWEN Jan 23, 2000 Added comment. //***************************************************************************** void CApplication::UpdateView(BOOL bWindowOnly) { TCHAR szWindowTitle[1024]; CSTRING szName; if ( (CDatabase::m_szCurrentDatabase != NULL) && (CDatabase::m_szCurrentDatabase.Length() > 0 )) szName = CDatabase::m_szCurrentDatabase; else szName = TEXT("Untitled.SDB"); if ( szName.Length() == 0 ) { MEM_ERR; return; } szName.ShortFilename(); wsprintf(szWindowTitle, TEXT("Application Fix Management Console (%s) %s"), (LPCTSTR)szName, GetDBLocal().m_bDirty ? TEXT("*"):TEXT("")); SetWindowText(g_theApp.m_hWnd,szWindowTitle); // what is the meaning of bWindowOnly ?? if ( NULL != m_pCurrentView && !bWindowOnly ) m_pCurrentView->Update(); } BOOL CALLBACK SplashProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return FALSE; } DWORD WIN_MSG() { LPVOID lpMsgBuf = NULL; DWORD returnVal; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, returnVal = GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the string. MessageBox( NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION ); // Free the buffer. LocalFree( lpMsgBuf ); return returnVal; }