Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1634 lines
45 KiB

//#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;
}