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

  1. //#define __DEBUG 1
  2. #include "compatadmin.h"
  3. #include "dbviewer.h"
  4. #include "dbsearch.h"
  5. #include "xmldialog.h"
  6. #include "psapi.h"
  7. BOOL g_bWin2K = FALSE;
  8. void __cdecl Terminate_Handler()
  9. {
  10. MessageBox(NULL,TEXT("Uncaught Exception raised!"),TEXT("Error"),MB_ICONERROR);
  11. WIN_MSG();
  12. abort();
  13. }
  14. /*....................................................................................*/
  15. BOOL
  16. SearchGroupForSID(
  17. DWORD dwGroup,
  18. BOOL* pfIsMember
  19. )
  20. {
  21. PSID pSID = NULL;
  22. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  23. BOOL fRes = TRUE;
  24. if ( !AllocateAndInitializeSid(&SIDAuth,
  25. 2,
  26. SECURITY_BUILTIN_DOMAIN_RID,
  27. dwGroup,
  28. 0,
  29. 0,
  30. 0,
  31. 0,
  32. 0,
  33. 0,
  34. &pSID) ) {
  35. fRes = FALSE;
  36. }
  37. if ( !CheckTokenMembership(NULL, pSID, pfIsMember) ) {
  38. fRes = FALSE;
  39. }
  40. if (pSID)
  41. FreeSid(pSID);
  42. return fRes;
  43. }
  44. BOOL
  45. IsAdmin(
  46. void
  47. )
  48. {
  49. BOOL fIsUser, fIsAdmin;
  50. if ( !SearchGroupForSID(DOMAIN_ALIAS_RID_USERS, &fIsUser) ||
  51. !SearchGroupForSID(DOMAIN_ALIAS_RID_ADMINS, &fIsAdmin)
  52. // || !SearchGroupForSID(DOMAIN_ALIAS_RID_POWER_USERS, &fIsPowerUser)
  53. ) {
  54. return FALSE;
  55. }
  56. return(fIsUser && fIsAdmin );
  57. }
  58. /*....................................................................................*/
  59. CDatabase& CApplication::GetDBGlobal()
  60. {
  61. return (this->m_DBGlobal);
  62. }
  63. CDatabase& CApplication::GetDBLocal()
  64. {
  65. return (this->m_DBLocal);
  66. }
  67. //*****************************************************************************
  68. //
  69. // Global Variables
  70. //
  71. //*****************************************************************************
  72. UINT g_uDPFLevel = DPF_LEVEL;
  73. UINT g_uProfileDPFLevel = DPF_LEVEL;
  74. TESTRUN g_TestRun;
  75. HANDLE g_hTestRunExec;
  76. CSTRING g_szTestFile;
  77. BOOL CALLBACK SplashProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  78. //*****************************************************************************
  79. // Class: CApplication
  80. //
  81. // Function: Constructor
  82. //
  83. // Notes: None
  84. //
  85. // History:
  86. //
  87. // A-COWEN Nov 8, 2000 Implemented it.
  88. //*****************************************************************************
  89. CApplication::CApplication()
  90. {
  91. if ( !IsAdmin() ) {// Admin rights
  92. MessageBox(NULL,TEXT("You need administrative rights to run this program. Please contact your system administrator"),TEXT("CompatAdmin"),MB_ICONERROR);
  93. #ifndef __DEBUG
  94. ExitThread(1);
  95. #endif
  96. }
  97. //
  98. //Check if the OS is Win2k
  99. //
  100. OSVERSIONINFO osvi;
  101. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  102. GetVersionEx (&osvi);
  103. if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0)) {
  104. g_bWin2K = TRUE;
  105. }
  106. set_terminate(Terminate_Handler);
  107. CDatabase::CleanUp();
  108. g_uButtons = 0;
  109. m_hDialog = NULL;
  110. m_hAccelerator = NULL;
  111. m_hKey = NULL;
  112. m_pCurrentView = NULL;
  113. m_hMenu = NULL;
  114. /* Moved to CDatabase::CDatabase
  115. m_pDB = NULL;
  116. m_pRecordHead = NULL;
  117. m_pShimList = NULL;
  118. m_pLayerList = NULL;
  119. */
  120. m_MainButtons[g_uButtons].iBitmap = 0;
  121. m_MainButtons[g_uButtons].idCommand = ID_FILE_NEWDATABASE;
  122. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  123. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  124. m_MainButtons[g_uButtons].dwData = 0;
  125. m_MainButtons[g_uButtons].iString = 0;
  126. ++g_uButtons;
  127. m_MainButtons[g_uButtons].iBitmap = 1;
  128. m_MainButtons[g_uButtons].idCommand = ID_FILE_OPENDATABASE;
  129. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  130. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  131. m_MainButtons[g_uButtons].dwData = 0;
  132. m_MainButtons[g_uButtons].iString = 0;
  133. ++g_uButtons;
  134. m_MainButtons[g_uButtons].iBitmap = 2;
  135. m_MainButtons[g_uButtons].idCommand = ID_FILE_SAVEDATABASE;
  136. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  137. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  138. m_MainButtons[g_uButtons].dwData = 0;
  139. m_MainButtons[g_uButtons].iString = 0;
  140. ++g_uButtons;
  141. /*
  142. // Email
  143. m_MainButtons[g_uButtons].iBitmap = 3;
  144. m_MainButtons[g_uButtons].idCommand = 3;
  145. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  146. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  147. m_MainButtons[g_uButtons].dwData = 0;
  148. m_MainButtons[g_uButtons].iString = 0;
  149. ++g_uButtons;
  150. // Print
  151. m_MainButtons[g_uButtons].iBitmap = 6;
  152. m_MainButtons[g_uButtons].idCommand = 0;
  153. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  154. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_SEP;
  155. m_MainButtons[g_uButtons].dwData = 0;
  156. m_MainButtons[g_uButtons].iString = 0;
  157. ++g_uButtons;
  158. m_MainButtons[g_uButtons].iBitmap = 4;
  159. m_MainButtons[g_uButtons].idCommand = 4;
  160. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  161. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  162. m_MainButtons[g_uButtons].dwData = 0;
  163. m_MainButtons[g_uButtons].iString = 0;
  164. ++g_uButtons;
  165. // Print preview
  166. m_MainButtons[g_uButtons].iBitmap = 5;
  167. m_MainButtons[g_uButtons].idCommand = 5;
  168. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  169. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  170. m_MainButtons[g_uButtons].dwData = 0;
  171. m_MainButtons[g_uButtons].iString = 0;
  172. ++g_uButtons;
  173. */
  174. m_MainButtons[g_uButtons].iBitmap = 6;
  175. m_MainButtons[g_uButtons].idCommand = 0;
  176. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  177. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_SEP;
  178. m_MainButtons[g_uButtons].dwData = 0;
  179. m_MainButtons[g_uButtons].iString = 0;
  180. ++g_uButtons;
  181. m_MainButtons[g_uButtons].iBitmap = 20;
  182. m_MainButtons[g_uButtons].idCommand = ID_WINDOWS_SEARCHFORFIXES;
  183. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  184. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  185. m_MainButtons[g_uButtons].dwData = 0;
  186. m_MainButtons[g_uButtons].iString = 0;
  187. ++g_uButtons;
  188. m_MainButtons[g_uButtons].iBitmap = 14;
  189. m_MainButtons[g_uButtons].idCommand = ID_WINDOWS_DATABASEVIEWER;
  190. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  191. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_BUTTON;
  192. m_MainButtons[g_uButtons].dwData = 0;
  193. m_MainButtons[g_uButtons].iString = 0;
  194. ++g_uButtons;
  195. m_MainButtons[g_uButtons].iBitmap = 6;
  196. m_MainButtons[g_uButtons].idCommand = 0;
  197. m_MainButtons[g_uButtons].fsState = TBSTATE_ENABLED;
  198. m_MainButtons[g_uButtons].fsStyle = TBSTYLE_SEP;
  199. m_MainButtons[g_uButtons].dwData = 0;
  200. m_MainButtons[g_uButtons].iString = 0;
  201. ++g_uButtons;
  202. }
  203. //*****************************************************************************
  204. // Class: CApplication
  205. //
  206. // Function: msgCreate
  207. //
  208. // Notes: Perform application initialization.
  209. //
  210. // History:
  211. //
  212. // A-COWEN Nov 8, 2000 Initial Implementation: Center
  213. // window and open registry.
  214. //*****************************************************************************
  215. void CApplication::msgCreate(void)
  216. {
  217. RECT rRect;
  218. int nX;
  219. int nY;
  220. m_hAccelerator = LoadAccelerators(g_hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1) );
  221. m_hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MAINMENU));
  222. m_hToolBitmap = LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDR_MAINTOOLBAR));
  223. SetMenu(m_hWnd,m_hMenu);
  224. WINDOWPLACEMENT Place;
  225. Place.length = sizeof(WINDOWPLACEMENT);
  226. Place.flags = 0;
  227. Place.showCmd = SW_SHOW;
  228. // Center the application window on the screen.
  229. GetWindowRect(m_hWnd,&rRect);
  230. // Compute actual width and height
  231. rRect.right -= rRect.left;
  232. rRect.bottom -= rRect.top;
  233. // Resolve X,Y location required to center whole window.
  234. nX = (GetSystemMetrics(SM_CXSCREEN) - rRect.right) / 2;
  235. nY = (GetSystemMetrics(SM_CYSCREEN) - rRect.bottom) / 2;
  236. // Move the window to the center location.
  237. ::MoveWindow(m_hWnd,nX,nY,rRect.right,rRect.bottom,TRUE);
  238. Place.showCmd = SW_SHOW;
  239. Place.rcNormalPosition.left = nX;
  240. Place.rcNormalPosition.top = nY;
  241. Place.rcNormalPosition.right = rRect.right;
  242. Place.rcNormalPosition.bottom = rRect.top;
  243. ReadReg(TEXT("WNDPLACE"),&Place,sizeof(WINDOWPLACEMENT));
  244. // Open the registry.
  245. if ( ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_CURRENT_USER,APP_KEY,0,KEY_ALL_ACCESS, &m_hKey) ) {
  246. if ( ::RegCreateKeyEx(HKEY_CURRENT_USER,APP_KEY,0,TEXT(""),REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_hKey, NULL) != ERROR_SUCCESS ) {
  247. MessageBox(NULL,TEXT("There was an error while launching the program. The program will now terminate"),TEXT("Error"),MB_ICONERROR);
  248. ExitThread(1);
  249. }
  250. }
  251. // Read default profile information for the application.
  252. ReadReg(TEXT("DPFLEVEL"),&g_uDPFLevel,sizeof(UINT));
  253. ReadReg(TEXT("PROFILEDPF"),&g_uProfileDPFLevel,sizeof(UINT));
  254. // Create the status bar
  255. InitCommonControls();
  256. m_hStatusBar = CreateStatusWindow( WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP | WS_CLIPSIBLINGS,
  257. TEXT(""),
  258. m_hWnd,
  259. STATUS_ID);
  260. // Create the toolbar
  261. /*
  262. m_hToolBar = CreateToolbarEx( m_hWnd,
  263. WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
  264. TOOLBAR_ID,
  265. 23,
  266. g_hInstance,
  267. IDR_MAINTOOLBAR,
  268. m_MainButtons,
  269. g_uButtons,
  270. 16, 16,
  271. 16, 16,
  272. sizeof(TBBUTTON));
  273. // Add common control system images to the toolbar
  274. TBADDBITMAP Bmp;
  275. Bmp.hInst = HINST_COMMCTRL;
  276. Bmp.nID = IDB_STD_SMALL_COLOR;
  277. m_uStandardImages = SendMessage(g_theApp.m_hToolBar,TB_ADDBITMAP,1,(LPARAM) &Bmp);
  278. */
  279. // Create the views used in the app
  280. m_ViewList[VIEW_DATABASE].pView = new CDBView;
  281. if ( NULL != m_ViewList[VIEW_DATABASE].pView )
  282. if ( !m_ViewList[VIEW_DATABASE].pView->Initialize() ) {
  283. DPF(1,TEXT("Creating the DB View failed"));
  284. }
  285. /// dddd what is happening here....
  286. m_ViewList[VIEW_SEARCHDB].pView = new CDBSearch;
  287. if ( NULL != m_ViewList[VIEW_SEARCHDB].pView )
  288. if ( !m_ViewList[VIEW_SEARCHDB].pView->Initialize() ) {
  289. DPF(1,TEXT("Creating the DB Search View failed"));
  290. }
  291. m_DBLocal.NewDatabase(FALSE);
  292. // The above function swith FALSE paramter closes the databases and makes other changes such as
  293. // activates the view etc, so that the cahnges are seen in the window heading
  294. TCHAR szShimDB[MAX_PATH_BUFFSIZE];
  295. GetSystemWindowsDirectory(szShimDB, MAX_PATH);
  296. lstrcat(szShimDB,TEXT("\\AppPatch\\sysmain.sdb"));
  297. //Create the opening Modeless Dlg box
  298. HWND hSplash = CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_SPLASH),m_hWnd,(DLGPROC)SplashProc);
  299. ShowWindow(hSplash,SW_SHOWNORMAL);
  300. UpdateWindow(hSplash);
  301. if ( !m_DBGlobal.OpenDatabase( CSTRING(szShimDB),TRUE) ){
  302. MessageBox(NULL,szShimDB,TEXT("Failed to open the data base !"),MB_OK);
  303. }
  304. if ( NULL != m_DBGlobal.m_pDB ) {
  305. SdbCloseDatabase(m_DBGlobal.m_pDB);
  306. }
  307. DestroyWindow(hSplash);
  308. GetDBGlobal().m_pDB = NULL;
  309. // Activate the default view.
  310. ActivateView(m_ViewList[VIEW_DATABASE].pView);
  311. //SetWindowPlacement(m_hWnd,&Place);
  312. }
  313. //*****************************************************************************
  314. // Class: CApplication
  315. //
  316. // Function: ActivateView
  317. //
  318. // Notes: Deactivate the current view and activate the view specified.
  319. //
  320. // History:
  321. //
  322. // A-COWEN Nov 29, 2000 Implemented it.
  323. //*****************************************************************************
  324. void CApplication::ActivateView(CView * pView, BOOL fNewCreate )
  325. {
  326. if ( NULL != m_pCurrentView ) {
  327. ShowWindow(m_pCurrentView->m_hWnd,SW_HIDE);
  328. m_pCurrentView->Deactivate();//Does nothing !!
  329. }
  330. // Make sure only the main toolbar buttons are active
  331. /*
  332. while (TRUE == SendMessage(m_hToolBar,TB_DELETEBUTTON,g_uButtons,0));
  333. */
  334. m_pCurrentView = pView;
  335. RECT rRect;
  336. GetWindowRect(m_hWnd,&rRect);
  337. if ( NULL != pView ) {
  338. ShowWindow(pView->m_hWnd,SW_SHOW);
  339. UpdateWindow(pView->m_hWnd);
  340. pView->Activate(fNewCreate);
  341. if ( NULL == pView->m_hMenu )
  342. SetMenu(m_hWnd,m_hMenu);
  343. else
  344. SetMenu(m_hWnd,pView->m_hMenu);
  345. }
  346. // Cause the views to be resized to fit in the current parent window.
  347. msgResize(rRect.right - rRect.left, rRect.bottom - rRect.top);
  348. }
  349. //*****************************************************************************
  350. // Class: CApplication
  351. //
  352. // Function: ReadReg
  353. //
  354. // Notes: Simplified registry profile routine. This is only
  355. // valid after msgCreate is called. ReadReg always references
  356. // the application's registry profile.
  357. //
  358. // History:
  359. //
  360. // A-COWEN Nov 8, 2000 Implemented it.
  361. //*****************************************************************************
  362. UINT CApplication::ReadReg(
  363. LPCTSTR szKey,
  364. PVOID pData,
  365. UINT uSize)
  366. {
  367. ULONG uBytes = uSize;
  368. ULONG uType;
  369. //
  370. // we are calling registry fns here with no regard for an underlying type
  371. //
  372. if ( FAILED(::RegQueryValueEx(m_hKey,szKey,NULL,&uType,(LPBYTE) pData, &uBytes)) )
  373. return(UINT) -1;
  374. // Return the number of bytes read.
  375. return uBytes;
  376. }
  377. //*****************************************************************************
  378. // Class: CApplication
  379. //
  380. // Function: WriteReg
  381. //
  382. // Notes: Simplified registry profile writing routine. This is only
  383. // valid after msgCreate is called. WriteReg always references
  384. // the application's registry profile.
  385. //
  386. // History:
  387. //
  388. // A-COWEN Nov 8, 2000 Implemented it.
  389. //*****************************************************************************
  390. UINT CApplication::WriteReg(
  391. LPCTSTR szKey,
  392. UINT uType,
  393. PVOID pData,
  394. UINT uSize)
  395. {
  396. if ( FAILED(::RegSetValueEx(m_hKey,szKey,0,uType,(const BYTE *) pData, uSize)) )
  397. return(UINT) -1;
  398. // Return the number of bytes written.
  399. return uSize;
  400. }
  401. //*****************************************************************************
  402. // Class: CApplication
  403. //
  404. // Function: msgClose
  405. //
  406. // Notes: Monitor for application shutdown. When a close was requested,
  407. // at the application level, it's time to shutdown the application.
  408. // Also close registry profile.
  409. //
  410. // History:
  411. //
  412. // A-COWEN Nov 8, 2000 Implemented it.
  413. //*****************************************************************************
  414. void CApplication::msgClose(void)
  415. {
  416. // Post WM_QUIT to the message queue.
  417. SendMessage(m_hWnd,WM_COMMAND,ID_FILE_EXIT,(LPARAM)m_hWnd);
  418. }
  419. //*****************************************************************************
  420. // Class: CApplication
  421. //
  422. // Function: msgResize
  423. //
  424. // Notes: Watch for notifications to resize the main window. Update child
  425. // windows appropriately.
  426. //
  427. // History:
  428. //
  429. // A-COWEN Nov 8, 2000 Implemented it.
  430. //*****************************************************************************
  431. void CApplication::msgResize(UINT uWidth, UINT uHeight)
  432. {
  433. // Resize the current view.
  434. if ( NULL != m_pCurrentView ) {
  435. RECT rRect;
  436. UINT uToolSize = 0;
  437. UINT uStatusSize;
  438. //GetWindowRect(m_hToolBar,&rRect);
  439. //uToolSize = rRect.bottom - rRect.top;
  440. GetWindowRect(m_hStatusBar,&rRect);
  441. uStatusSize = rRect.bottom - rRect.top;
  442. GetClientRect(m_hWnd,&rRect);
  443. MoveWindow( m_pCurrentView->m_hWnd,
  444. 0, uToolSize,
  445. rRect.right, rRect.bottom - (uToolSize + uStatusSize),
  446. TRUE);
  447. }
  448. UINT uWidths[] = {uWidth - 300, uWidth - 100, -1};
  449. SendMessage(m_hStatusBar,SB_SETPARTS,sizeof(uWidths)/sizeof(UINT),(LPARAM) uWidths);
  450. SendMessage(m_hStatusBar,SB_SETTEXTW,(sizeof(uWidths)/sizeof(UINT)) | SBT_NOBORDERS,(LPARAM)TEXT(""));
  451. // Move and resize the status bar, then force repaint.
  452. SendMessage(m_hStatusBar,WM_SIZE,0,0);
  453. // Resize the toolbar
  454. //SendMessage(m_hToolBar,WM_SIZE,0,0);
  455. }
  456. //*****************************************************************************
  457. // Class: CApplication
  458. //
  459. // Function: msgNotify
  460. //
  461. // Notes: Watch for notifications to the parent. If the notifications
  462. // are not handled by the main application class, they are passed
  463. // to the current viewport for processing.
  464. //
  465. // History:
  466. //
  467. // A-COWEN Jan 23, 2000 Added comment.
  468. //*****************************************************************************
  469. void CApplication::msgNotify(LPNMHDR pHdr)
  470. {
  471. // Send any unprocessed notifications to the view.
  472. //
  473. // BUGBUG : Please move all the strings to the .rc file
  474. // let's write a method in CSTRING that allows you to load them
  475. // from the resource file
  476. //
  477. switch ( pHdr->code ) {
  478. case TBN_GETINFOTIP:
  479. {
  480. LPNMTBGETINFOTIP pTip = (LPNMTBGETINFOTIP) pHdr;
  481. static TCHAR * szTips[] = { TEXT("New Database"),
  482. TEXT("Open Database"),
  483. TEXT("Save Database"),
  484. TEXT("Send Database via Email"),
  485. TEXT("Print"),
  486. TEXT("Print Preview"),
  487. TEXT("Search for fixes"),
  488. TEXT("Database View")};
  489. switch ( pTip->iItem ) {
  490. case ID_FILE_NEWDATABASE:
  491. lstrcpy(pTip->pszText,TEXT("New Database"));
  492. break;
  493. case ID_FILE_OPENDATABASE:
  494. lstrcpy(pTip->pszText,TEXT("Open Database"));
  495. break;
  496. case ID_FILE_SAVEDATABASE:
  497. lstrcpy(pTip->pszText,TEXT("Save Database"));
  498. break;
  499. case ID_WINDOWS_SEARCHFORFIXES:
  500. lstrcpy(pTip->pszText,TEXT("Search for fixes"));
  501. break;
  502. case ID_WINDOWS_DATABASEVIEWER:
  503. lstrcpy(pTip->pszText,TEXT("Database View"));
  504. break;
  505. }
  506. }
  507. break;
  508. }
  509. if ( NULL != m_pCurrentView )
  510. m_pCurrentView->msgNotify(pHdr);
  511. }
  512. void CApplication::msgChar(TCHAR chChar)
  513. {
  514. // Send any unprocessed notifications to the view.
  515. if ( NULL != m_pCurrentView )
  516. m_pCurrentView->msgChar(chChar);
  517. }
  518. //*****************************************************************************
  519. // Class: CApplication
  520. //
  521. // Function: msgCommand
  522. //
  523. // Notes: Watch for user input that indicates an action we should take.
  524. // If it's not a global action, pass the command on to the current
  525. // view to handle it.
  526. //
  527. // History:
  528. //
  529. // A-COWEN Nov 31, 2000 Implemented it.
  530. //*****************************************************************************
  531. void CApplication::msgCommand(UINT uID, HWND hSender)
  532. {
  533. switch ( uID ) {
  534. case ID_FILE_NEWDATABASE:
  535. {
  536. HWND hWnd = GetFocus();
  537. if ( GetDBLocal().m_bDirty ) {
  538. 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);
  539. if ( IDCANCEL == nResult )
  540. break;
  541. if ( IDYES == nResult )
  542. SendMessage(m_hWnd,WM_COMMAND,ID_FILE_SAVEDATABASE,(LPARAM)m_hWnd);
  543. }
  544. GetDBLocal().NewDatabase(TRUE);
  545. UpdateView();
  546. SetFocus(hWnd);
  547. }
  548. break;
  549. case ID_HELP_ABOUT:
  550. {
  551. ShellAbout(m_hWnd,TEXT("Application Compatibility Administrator"),TEXT(""),LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_COMPATADMIN)));
  552. }
  553. break;
  554. case ID_FILE_EXIT:
  555. {
  556. if ( m_DBLocal.m_bDirty ) {
  557. 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);
  558. if ( IDCANCEL == nResult )
  559. break;
  560. if ( IDYES == nResult )
  561. SendMessage(m_hWnd,WM_COMMAND,ID_FILE_SAVEDATABASE,(LPARAM)m_hWnd);
  562. }
  563. WINDOWPLACEMENT Place;
  564. Place.length = sizeof(WINDOWPLACEMENT);
  565. GetWindowPlacement(m_hWnd,&Place);
  566. WriteReg(TEXT("WNDPLACE"),REG_BINARY,&Place,sizeof(WINDOWPLACEMENT));
  567. CDatabase::CleanUp();
  568. PostQuitMessage(0);
  569. m_ViewList[VIEW_DATABASE].pView->msgClose();
  570. m_ViewList[VIEW_SEARCHDB].pView->msgClose();
  571. // Close the registry
  572. ::RegCloseKey(m_hKey);
  573. }
  574. break;
  575. case ID_FILE_OPENDATABASE:
  576. {
  577. OPENFILENAME ofn;
  578. TCHAR szFilename[MAX_PATH_BUFFSIZE];
  579. TCHAR szShimDB[MAX_PATH_BUFFSIZE];
  580. HWND hWnd = GetFocus();
  581. *szFilename = *szShimDB = 0;
  582. if ( GetDBLocal().m_bDirty ) {
  583. 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);
  584. if ( IDCANCEL == nResult )
  585. break;
  586. if ( IDYES == nResult )
  587. SendMessage(m_hWnd,WM_COMMAND,ID_FILE_SAVEDATABASE,(LPARAM)m_hWnd);
  588. }
  589. GetSystemWindowsDirectory(szShimDB, MAX_PATH);
  590. lstrcat(szShimDB, TEXT("\\AppPatch"));
  591. ZeroMemory(&ofn,sizeof(OPENFILENAME));
  592. ZeroMemory(szFilename,sizeof(szFilename));
  593. ofn.lStructSize = sizeof(OPENFILENAME);
  594. ofn.hwndOwner = m_hWnd;
  595. ofn.hInstance = g_hInstance;
  596. ofn.lpstrFilter = TEXT("Compatibility DB (*.SDB)\0*.SDB\0\0");
  597. ofn.lpstrFile = szFilename;
  598. ofn.nMaxFile = MAX_PATH;
  599. //ofn.lpstrInitialDir = szShimDB;
  600. ofn.lpstrTitle = TEXT("Open Compatibility Database");
  601. ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST| OFN_HIDEREADONLY;
  602. ofn.lpstrDefExt = TEXT("SDB");
  603. if ( GetOpenFileName(&ofn) ) {
  604. CSTRING szFileCheck = szFilename;
  605. szFileCheck.ShortFilename();
  606. if ( CDatabase::SystemDB(szFilename) ) {
  607. 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);
  608. }
  609. if ( ! m_DBLocal.OpenDatabase(CSTRING(szFilename),FALSE) ) {
  610. MessageBox(m_hWnd,TEXT("An error occured attempting to open the database specified."),TEXT("Unable to open database"),MB_OK | MB_ICONERROR);
  611. }
  612. }
  613. SetFocus(hWnd);
  614. }
  615. break;
  616. case ID_FILE_SAVEDATABASE:
  617. {
  618. CSTRING szFilename;
  619. HWND hWnd = GetFocus();
  620. if ( GetDBLocal().m_szCurrentDatabase.Length() == 0 ) {
  621. if ( GetFilename(TEXT("Save Database"),TEXT("Compatibility DB (*.SDB)\0*.SDB\0\0"), TEXT(""), TEXT("SDB"), OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, FALSE, szFilename) )
  622. GetDBLocal().SaveDatabase(szFilename);
  623. } else
  624. m_DBLocal.SaveDatabase(GetDBLocal().m_szCurrentDatabase);
  625. SetFocus(hWnd);
  626. UpdateView();
  627. }
  628. break;
  629. case ID_FILE_SAVEDATABASEAS:
  630. {
  631. CSTRING szFilename;
  632. HWND hWnd = GetFocus();
  633. if ( GetFilename(TEXT("Save Database As"),TEXT("Compatibility DB (*.SDB)\0*.SDB\0\0"), TEXT(""), TEXT("SDB"), OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, FALSE, szFilename) ) {
  634. m_DBLocal.SaveDatabase(szFilename);
  635. SetFocus(hWnd);
  636. UpdateView();
  637. }
  638. }
  639. break;
  640. case ID_WINDOWS_SEARCHFORFIXES:
  641. {
  642. SetStatusText(0,CSTRING(TEXT("Search for fixes")));
  643. SetStatusText(2,CSTRING(TEXT("")));
  644. ActivateView(m_ViewList[VIEW_SEARCHDB].pView);
  645. }
  646. break;
  647. case ID_WINDOWS_DATABASEVIEWER:
  648. {
  649. ActivateView(m_ViewList[VIEW_DATABASE].pView,FALSE);
  650. }
  651. break;
  652. default:
  653. if ( NULL != m_pCurrentView )
  654. m_pCurrentView->msgCommand(uID,hSender);
  655. }
  656. }
  657. //*****************************************************************************
  658. // Class: CApplication
  659. //
  660. // Function: MessagePump
  661. //
  662. // Notes: The main application message pump.
  663. //
  664. // History:
  665. //
  666. // A-COWEN Nov 8, 2000 Implemented it.
  667. //*****************************************************************************
  668. int CApplication::MessagePump(void)
  669. {
  670. MSG msg;
  671. while ( GetMessage(&msg,NULL,0,0) ) {
  672. // Support modeless dialog message processing. If the message
  673. // is destined for a modeless dialog, do not translate and dispatch
  674. // as IsDialogMessage() will do that automatically.
  675. if ( NULL == m_hDialog || !IsDialogMessage(m_hDialog,&msg) ) {
  676. // Provide accelerator support. If an accelerator
  677. // is translated, do not call TranslateMessage().
  678. if ( NULL == m_hAccelerator || !TranslateAccelerator(this->m_hWnd,m_hAccelerator,&msg) )
  679. TranslateMessage(&msg);
  680. // Finally, dispatch the message to the window procedure.
  681. DispatchMessage(&msg);
  682. }
  683. }
  684. // GetMessage() returns FALSE when WM_QUIT is received.
  685. // Return the value from WM_QUIT, which is provided in WPARAM
  686. // from PostQuitMessage();
  687. return msg.wParam;
  688. }
  689. //*****************************************************************************
  690. // Class: CApplication
  691. //
  692. // Function: AddToolbarButton
  693. //
  694. // Notes: Adds a button to the toolbar
  695. //
  696. // History:
  697. //
  698. // A-COWEN Jan 23, 2000 Added comment.
  699. //*****************************************************************************
  700. BOOL CApplication::AddToolbarButton(UINT uBmp, UINT uCmd, UINT uState, UINT uStyle)
  701. {
  702. /*
  703. TBBUTTON Button;
  704. Button.iBitmap = uBmp;
  705. Button.idCommand = uCmd;
  706. Button.fsState = (BYTE) uState;
  707. Button.fsStyle = (BYTE) uStyle;
  708. Button.dwData = 0;
  709. Button.iString = 0;
  710. if (0 == SendMessage(g_theApp.m_hToolBar,TB_ADDBUTTONS,1,(LPARAM) &Button))
  711. return FALSE;
  712. */
  713. return TRUE;
  714. }
  715. //*****************************************************************************
  716. // Class: CApplication
  717. //
  718. // Function: SetButtonState
  719. //
  720. // Notes: Sets the button state for a toolbar button.
  721. //
  722. // History:
  723. //
  724. // A-COWEN Jan 23, 2000 Added comment.
  725. //*****************************************************************************
  726. BOOL CApplication::SetButtonState(UINT uCmd, UINT uState)
  727. {
  728. /*
  729. TBBUTTONINFO Info;
  730. Info.cbSize = sizeof(Info);
  731. Info.dwMask = TBIF_STATE;
  732. Info.fsState = (BYTE) uState;
  733. return SendMessage(g_theApp.m_hToolBar,TB_SETBUTTONINFO,uCmd,(LPARAM) &Info) ? TRUE:FALSE;
  734. */
  735. return FALSE;
  736. }
  737. //*****************************************************************************
  738. // Class: CApplication
  739. //
  740. // Function: GetFilename
  741. //
  742. // Notes: General purpose function used for OpenFileName and GetSaveFileName
  743. // common control functions.
  744. //
  745. // History:
  746. //
  747. // A-COWEN Jan 23, 2000 Added comment.
  748. //*****************************************************************************
  749. BOOL CApplication::GetFilename(LPCTSTR szTitle, LPCTSTR szFilter, LPCTSTR szDefaultFile, LPCTSTR szDefExt, DWORD dwFlags, BOOL bOpen, CSTRING & szStr)
  750. {
  751. OPENFILENAME ofn;
  752. TCHAR szFilename[MAX_PATH_BUFFSIZE];
  753. BOOL bResult;
  754. ZeroMemory(&ofn,sizeof(OPENFILENAME));
  755. ZeroMemory(szFilename,sizeof(szFilename));
  756. //Used lstrcpyn to satisfy PREFast
  757. lstrcpyn(szFilename,szDefaultFile,sizeof(szFilename)/sizeof(TCHAR));
  758. ofn.lStructSize = sizeof(OPENFILENAME);
  759. ofn.hwndOwner = m_hWnd;
  760. ofn.hInstance = g_hInstance;
  761. ///iii Perhaps this too is incorrect
  762. ofn.lpstrFilter = szFilter;
  763. ofn.lpstrFile = szFilename;
  764. ofn.nMaxFile = MAX_PATH;
  765. ofn.lpstrInitialDir = szDefaultFile;
  766. ofn.lpstrTitle = szTitle;
  767. ofn.Flags = dwFlags | OFN_NOREADONLYRETURN | OFN_HIDEREADONLY;
  768. ofn.lpstrDefExt = szDefExt;
  769. BOOL valid = FALSE; //whether path is too long / ends with .SDB or not applicable for save mode only
  770. while (valid == FALSE) {
  771. if ( bOpen )
  772. bResult = GetOpenFileName(&ofn);
  773. else
  774. bResult = GetSaveFileName(&ofn);
  775. if ( !bResult )
  776. return FALSE;
  777. szStr = szFilename;
  778. if (bOpen) {
  779. return TRUE;
  780. }
  781. //
  782. //Do stuff to make sure that the file being saved has a .SDB extension and the filename is not
  783. //too long so that a .SDB file name does not get appended to it.
  784. //
  785. if ( szStr.isNULL() ) {
  786. continue;
  787. }
  788. if (!szStr.EndsWith(TEXT(".sdb"))){
  789. if (szStr.Length() <= (MAX_PATH - 1 - 4)) {
  790. szStr.strcat(TEXT(".sdb"));
  791. valid = TRUE;
  792. }
  793. }else{
  794. valid = TRUE;
  795. }
  796. if (valid == FALSE) {
  797. CSTRING message =TEXT("The path you entered: ");
  798. message.strcat(szStr);
  799. message.strcat(TEXT("\nis too long. Please enter a shorter path"));
  800. MessageBox(m_hWnd, message,TEXT("CompatAdmin"),MB_ICONWARNING);
  801. }
  802. }//while
  803. return TRUE;
  804. }
  805. //*****************************************************************************
  806. // Class: CApplication
  807. //
  808. // Function: InvokeEXE
  809. //
  810. // Notes: Invoke an executable with the specified command line. Then
  811. // wait for the executable to finish if desired.
  812. //
  813. // History:
  814. //
  815. // A-COWEN Jan 23, 2000 Added comment.
  816. //*****************************************************************************
  817. BOOL CApplication::InvokeEXE(LPCTSTR szEXE, LPCTSTR szCommandLine, BOOL bWait, BOOL bDialog, BOOL bConsole)
  818. {
  819. BOOL bCreate;
  820. STARTUPINFO Start;
  821. PROCESS_INFORMATION Out;
  822. ZeroMemory(&Start,sizeof(STARTUPINFO));
  823. Start.cb = sizeof(STARTUPINFO);
  824. bCreate = CreateProcess( szEXE,
  825. (LPWSTR)szCommandLine,
  826. NULL,
  827. NULL,
  828. FALSE,
  829. ((bConsole) ? 0:CREATE_NO_WINDOW) | NORMAL_PRIORITY_CLASS,
  830. NULL,
  831. NULL,
  832. &Start,
  833. &Out);
  834. if ( bCreate && bWait ) {
  835. CloseHandle(Out.hThread);
  836. g_hTestRunExec = Out.hProcess;
  837. DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_WAIT),m_hWnd,(DLGPROC)TestRunWait,(LPARAM)bDialog);
  838. }
  839. CloseHandle(Out.hProcess);
  840. return bCreate ? TRUE:FALSE;
  841. }
  842. // FlushCache code taken from SDBInst.
  843. typedef void (CALLBACK *pfn_ShimFlushCache)(HWND, HINSTANCE, LPSTR, int);
  844. void FlushCache(void)
  845. {
  846. HMODULE hAppHelp;
  847. pfn_ShimFlushCache pShimFlushCache;
  848. hAppHelp = LoadLibraryW(L"apphelp.dll");
  849. if ( hAppHelp ) {
  850. pShimFlushCache = (pfn_ShimFlushCache)GetProcAddress(hAppHelp, "ShimFlushCache");//PARAMS(HMODULE,LPCSTR)
  851. if ( pShimFlushCache ) {
  852. pShimFlushCache(NULL, NULL, NULL, 0);
  853. }
  854. }
  855. }
  856. //*****************************************************************************
  857. // Class: CApplication
  858. //
  859. // Function: TestRun
  860. //
  861. // Notes: Execute the application defined by the specified record, with
  862. // the shim or layer information defined in that record. The
  863. // filename and commandline are overridable.
  864. //
  865. // History:
  866. //
  867. // A-COWEN Jan 23, 2000 Added comment.
  868. //*****************************************************************************
  869. BOOL CApplication::TestRun(PDBRECORD pRecord, CSTRING * pszFile, CSTRING * pszCommandLine, HWND hParent)
  870. {
  871. CSTRING szCommandLine;
  872. BOOL bResult;
  873. TCHAR szPath[MAX_PATH_BUFFSIZE];
  874. TCHAR szSystemDir[MAX_PATH_BUFFSIZE];
  875. if ( NULL != pszFile )
  876. g_szTestFile = *pszFile;
  877. else
  878. g_szTestFile = pRecord->szEXEName;
  879. if ( NULL == pszCommandLine ) {
  880. if ( 0 == DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_TESTRUN),hParent,(DLGPROC)TestRunDlg) )
  881. return FALSE;
  882. }
  883. //
  884. // UnInstall and remove the earlier Test.SDB file
  885. //
  886. CDatabase::CleanUp();
  887. //
  888. // Now make the XML, ,SDB and call InVokeExe
  889. //
  890. CSTRINGList * pXML = m_DBLocal.DisassembleRecord(pRecord,FALSE,FALSE,TRUE,TRUE,FALSE, TRUE);
  891. if ( GetCurrentDirectory(MAX_PATH,szPath) == 0 ) {
  892. #ifdef __DEBUG
  893. MessageBox(NULL,TEXT("Unable to execute GetCurrentDirectory(...)"), TEXT("Error"),MB_ICONWARNING);
  894. #endif
  895. return FALSE;
  896. }
  897. if ( GetWindowsDirectory(szSystemDir,MAX_PATH) == 0 ) {
  898. #ifdef __DEBUG
  899. MessageBox(NULL,TEXT("Unable to execute GetWindowsDirectory(...)"), TEXT("Error"),MB_ICONWARNING);
  900. #endif
  901. return FALSE;
  902. }
  903. if ( NULL != pXML ) {
  904. CSTRING szFile;
  905. lstrcpy(szPath,szSystemDir);
  906. szFile.sprintf(TEXT("%s\\AppPatch\\SysTest.XML"),szPath);
  907. if ( !m_DBLocal.WriteXML(szFile,pXML) ) {
  908. MessageBox(g_theApp.m_hWnd,TEXT("Unable to save temporary file."),TEXT("File save error"),MB_OK);
  909. return FALSE;
  910. }
  911. delete pXML;
  912. } else
  913. return FALSE;
  914. if ( lstrlen(szPath) == 3 )
  915. szPath[2] = 0;
  916. szCommandLine.sprintf(TEXT("custom \"%s\\AppPatch\\SysTest.XML\" \"%s\\AppPatch\\Test.SDB\""),szPath,szSystemDir);
  917. bResult = CDatabase::InvokeCompiler(szCommandLine);
  918. if ( bResult ) {
  919. CSTRING szCommandLine;
  920. //
  921. // BUGBUG why no windbg?
  922. //
  923. if ( g_TestRun.bNTSD )
  924. szCommandLine = TEXT("NTSD.EXE ");
  925. else
  926. if ( g_TestRun.bMSDEV )
  927. szCommandLine = TEXT("MSDEV.EXE ");
  928. // Invoke the application
  929. szCommandLine.strcat(g_szTestFile);
  930. szCommandLine.strcat(TEXT(" "));
  931. if ( NULL != pszCommandLine )
  932. szCommandLine.strcat(*pszCommandLine);
  933. else
  934. szCommandLine.strcat(g_TestRun.szCommandLine);
  935. // If there's a layer, set the environment
  936. /*
  937. if (pRecord->szLayerName.Length() > 0)
  938. //SetEnvironmentVariable(TEXT("__COMPAT_LAYER"),pRecord->szLayerName);
  939. */
  940. FlushCache();
  941. CSTRING strSdbInstCommandLine;
  942. strSdbInstCommandLine.sprintf(TEXT("%s\\System32\\sdbInst.exe -q %s\\AppPatch\\Test.SDB "),(LPCTSTR)szSystemDir,(LPCTSTR)szSystemDir);
  943. if ( !InvokeEXE(NULL,strSdbInstCommandLine.pszString,TRUE,TRUE,TRUE) ) {
  944. MessageBox(m_hWnd,TEXT("There was a problem In executing the data base installer."),TEXT("CompatAdmin"),MB_ICONERROR);
  945. }
  946. if ( !InvokeEXE(NULL,szCommandLine.pszString,TRUE,TRUE,TRUE) ) {
  947. 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);
  948. }
  949. /*
  950. strSdbInstCommandLine.sprintf(TEXT("%s\\System32\\sdbInst.exe -u %s\\AppPatch\\Test.SDB "),(LPCTSTR)szSystemDir,(LPCTSTR)szSystemDir);
  951. if ( !InvokeEXE(NULL,strSdbInstCommandLine.pszString,TRUE,TRUE,TRUE) ) {
  952. MessageBox(m_hWnd,TEXT("There was a problem In executing the data base installer."),TEXT("CompatAdmin"),MB_ICONERROR);
  953. }
  954. */
  955. //SetEnvironmentVariable(TEXT("__COMPAT_LAYER"),NULL);
  956. }
  957. #ifdef __DEBUG
  958. MessageBox(g_theApp.m_hWnd,TEXT("Now about to delete the SysTest.* files "),TEXT("Now"),MB_OK);
  959. #endif
  960. szCommandLine.sprintf(TEXT("%s\\AppPatch\\SysTest.XML"),szPath);
  961. BOOL bReturnCode;
  962. bReturnCode = DeleteFile(szCommandLine);
  963. /*
  964. szCommandLine.sprintf(TEXT("%s\\AppPatch\\Test.SDB"),szSystemDir);
  965. bReturnCode = DeleteFile(szCommandLine);
  966. */
  967. return bResult;
  968. }
  969. //*****************************************************************************
  970. // Class: CApplication
  971. //
  972. // Function: TestRunWait
  973. //
  974. // Notes: Basic dialog that is displayed while waiting for an application
  975. // to complete. The dialog is invoked by the InvokeEXE function.
  976. //
  977. // History:
  978. //
  979. // A-COWEN Jan 23, 2000 Added comment.
  980. //*****************************************************************************
  981. BOOL CALLBACK
  982. TestRunWait(
  983. HWND hWnd,
  984. UINT uMsg,
  985. WPARAM wParam,
  986. LPARAM lParam
  987. )
  988. {
  989. //
  990. // BUGBUG: I had to use WM_USER+1024 when lParam == 0, WE do not want to show the dialog, because the dialog is
  991. // getting showed even if we call ShowWindow(hWnd,SW_HIDE); calling this seems to have no effect !!
  992. //
  993. switch (uMsg) {
  994. case WM_INITDIALOG:
  995. if (lParam == 0) {
  996. SendMessage(hWnd, WM_USER + 1024, 0, 0);
  997. ShowWindow(hWnd, SW_HIDE);
  998. } else {
  999. ShowWindow(hWnd,SW_SHOW);
  1000. SetTimer(hWnd, 0, 50, NULL);
  1001. }
  1002. return TRUE;
  1003. case WM_TIMER:
  1004. {
  1005. DWORD dwResult = WaitForSingleObject(g_hTestRunExec,10);
  1006. if (dwResult != WAIT_TIMEOUT) {
  1007. KillTimer(hWnd,0);
  1008. EndDialog(hWnd,0);
  1009. }
  1010. break;
  1011. }
  1012. case WM_USER + 1024:
  1013. {
  1014. //
  1015. // NOTE: This will not return to the dialog, and it will not get shown.
  1016. // But if the process takes a long time to execute the background
  1017. // might get white-washed :-( [Theoretically]
  1018. // Please explore this one.
  1019. //
  1020. DWORD dwResult = WaitForSingleObject(g_hTestRunExec, INFINITE);
  1021. EndDialog(hWnd,0);
  1022. }
  1023. break;
  1024. }
  1025. return FALSE;
  1026. }
  1027. //*****************************************************************************
  1028. // Class: CApplication
  1029. //
  1030. // Function: TestRunDlg
  1031. //
  1032. // Notes: Dialog handling procedure that queries the user for the command
  1033. // line and debugging options for a test run.
  1034. //
  1035. // History:
  1036. //
  1037. // A-COWEN Jan 23, 2000 Added comment.
  1038. //*****************************************************************************
  1039. BOOL CALLBACK TestRunDlg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1040. {
  1041. switch ( uMsg ) {
  1042. case WM_INITDIALOG:
  1043. {
  1044. SetWindowText(GetDlgItem(hWnd,IDC_EXE),g_szTestFile);
  1045. SendDlgItemMessage(hWnd,IDC_NONE,BM_SETCHECK,BST_CHECKED,0);
  1046. }
  1047. break;
  1048. case WM_COMMAND:
  1049. switch ( LOWORD(wParam) ) {
  1050. case IDC_BROWSE:
  1051. {
  1052. HWND hwndFocus = GetFocus();
  1053. CSTRING szFilename;
  1054. if ( g_theApp.GetFilename(TEXT("Find Program"),
  1055. TEXT("Executable (*.EXE)\0*.EXE\0All Files (*.*)\0*.*\0\0"),
  1056. g_szTestFile,
  1057. TEXT(""),
  1058. OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
  1059. TRUE,
  1060. szFilename) ) {
  1061. g_szTestFile = szFilename;
  1062. SetWindowText(GetDlgItem(hWnd,IDC_EXE),g_szTestFile);
  1063. }
  1064. SetFocus( hwndFocus );
  1065. }
  1066. break;
  1067. case IDOK:
  1068. {
  1069. TCHAR szCmdLine[MAX_PATH_BUFFSIZE];
  1070. if ( BST_CHECKED == SendDlgItemMessage(hWnd,IDC_NTSD,BM_GETCHECK,0,0) )
  1071. g_TestRun.bNTSD = TRUE;
  1072. else
  1073. g_TestRun.bNTSD = FALSE;
  1074. if ( BST_CHECKED == SendDlgItemMessage(hWnd,IDC_MSDEV,BM_GETCHECK,0,0) )
  1075. g_TestRun.bMSDEV = TRUE;
  1076. else
  1077. g_TestRun.bMSDEV = FALSE;
  1078. GetWindowText(GetDlgItem(hWnd,IDC_COMMANDLINE),szCmdLine,MAX_PATH);
  1079. g_TestRun.szCommandLine = szCmdLine;
  1080. GetWindowText(GetDlgItem(hWnd,IDC_EXE),szCmdLine,MAX_PATH);
  1081. g_szTestFile = szCmdLine;
  1082. EndDialog(hWnd,1);
  1083. }
  1084. break;
  1085. case IDCANCEL:
  1086. EndDialog(hWnd,0);
  1087. break;
  1088. }
  1089. }
  1090. return FALSE;
  1091. }
  1092. //*****************************************************************************
  1093. // Class: CApplication
  1094. //
  1095. // Function: SetStatusText
  1096. //
  1097. // Notes: Provides basic functionality to access the status bar for the
  1098. // main application window.
  1099. //
  1100. // History:
  1101. //
  1102. // A-COWEN Jan 23, 2000 Added comment.
  1103. //*****************************************************************************
  1104. LRESULT CApplication::MsgProc(
  1105. UINT uMsg,
  1106. WPARAM wParam,
  1107. LPARAM lParam)
  1108. {
  1109. switch ( uMsg ) {
  1110. case WM_SETFOCUS:{
  1111. if (m_pCurrentView == NULL ) break;
  1112. if ( m_pCurrentView == m_ViewList[VIEW_DATABASE].pView ){
  1113. if ( g_hWndLastFocus ) SetFocus(g_hWndLastFocus);
  1114. }else{
  1115. if (m_pCurrentView == m_ViewList[VIEW_SEARCHDB].pView) {
  1116. SetFocus( ((CDBSearch*)m_pCurrentView)->m_hListView );
  1117. }
  1118. }
  1119. break;
  1120. }
  1121. }
  1122. return CWindow::MsgProc(uMsg,wParam,lParam);
  1123. }
  1124. BOOL CApplication::SetStatusText(UINT uTab, CSTRING & szText)
  1125. {
  1126. SendMessage(m_hStatusBar,SB_SETTEXT,uTab,(LPARAM)(szText.pszString));
  1127. return TRUE;
  1128. }
  1129. //*****************************************************************************
  1130. // Class: CApplication
  1131. //
  1132. // Function: UpdateView
  1133. //
  1134. // Notes: Provides basic functionality to force the application to update
  1135. // the current view.
  1136. //
  1137. // History:
  1138. //
  1139. // A-COWEN Jan 23, 2000 Added comment.
  1140. //*****************************************************************************
  1141. void CApplication::UpdateView(BOOL bWindowOnly)
  1142. {
  1143. TCHAR szWindowTitle[1024];
  1144. CSTRING szName;
  1145. if ( (CDatabase::m_szCurrentDatabase != NULL) && (CDatabase::m_szCurrentDatabase.Length() > 0 ))
  1146. szName = CDatabase::m_szCurrentDatabase;
  1147. else
  1148. szName = TEXT("Untitled.SDB");
  1149. if ( szName.Length() == 0 ) {
  1150. MEM_ERR;
  1151. return;
  1152. }
  1153. szName.ShortFilename();
  1154. wsprintf(szWindowTitle,
  1155. TEXT("Application Fix Management Console (%s) %s"),
  1156. (LPCTSTR)szName,
  1157. GetDBLocal().m_bDirty ? TEXT("*"):TEXT(""));
  1158. SetWindowText(g_theApp.m_hWnd,szWindowTitle);
  1159. // what is the meaning of bWindowOnly ??
  1160. if ( NULL != m_pCurrentView && !bWindowOnly )
  1161. m_pCurrentView->Update();
  1162. }
  1163. BOOL CALLBACK SplashProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1164. {
  1165. return FALSE;
  1166. }
  1167. DWORD WIN_MSG()
  1168. {
  1169. LPVOID lpMsgBuf = NULL;
  1170. DWORD returnVal;
  1171. FormatMessage(
  1172. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1173. FORMAT_MESSAGE_FROM_SYSTEM |
  1174. FORMAT_MESSAGE_IGNORE_INSERTS,
  1175. NULL,
  1176. returnVal = GetLastError(),
  1177. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  1178. (LPTSTR) &lpMsgBuf,
  1179. 0,
  1180. NULL
  1181. );
  1182. // Display the string.
  1183. MessageBox( NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION );
  1184. // Free the buffer.
  1185. LocalFree( lpMsgBuf );
  1186. return returnVal;
  1187. }