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.

663 lines
18 KiB

  1. // Standard defines used by the application.
  2. #define MEM_ERR MessageBox(NULL,TEXT("The System is running low on memory ! Please close some programs and try again."),TEXT("Error"),MB_ICONWARNING|MB_OK);
  3. #include "afxres.h"
  4. #define LIMIT_APP_NAME 150 // Maximum size of app names, to be restricted on the UI Text box
  5. #define MAX_PATH_BUFFSIZE (MAX_PATH+1)
  6. #define UNICODE
  7. #define _UNICODE
  8. #include <tchar.h>
  9. #define STRICT
  10. #include <windows.h>
  11. #include <commctrl.h>
  12. #include <Commdlg.h>
  13. #include <stdarg.h>
  14. #include <stdio.h>
  15. #include <shellapi.h>
  16. #include <objbase.h>
  17. #include <exception>
  18. #include <Shlwapi.h>
  19. #include <cassert>
  20. #define AUTOCOMPLETE SHACF_FILESYSTEM | SHACF_AUTOSUGGEST_FORCE_ON
  21. extern "C"
  22. {
  23. #include "shimdb.h"
  24. BOOL ShimdbcExecute(LPCWSTR lpszCmdLine);
  25. }
  26. #include "resource.h"
  27. #include "utils.h"
  28. #ifndef STDCALL
  29. #define STDCALL _cdecl
  30. #endif
  31. #ifndef MSGAPI
  32. #define MSGAPI virtual void STDCALL
  33. #endif
  34. #include "CDatabase.h"
  35. #include "CDatabaseGlobal.h"
  36. #include "CDatabaseLocal.h"
  37. // For stability purposes, we use RTTI to verify values returned by Windows
  38. // when they are cast to pointers. Use of dynamic_cast<> not only pre-validates
  39. // the pointer, it validates the type of pointer for polymorphic types.
  40. //#ifndef _CPPRTTI
  41. // #error Build error: Must be compiled with RTTI enabled. (/GR-)
  42. //#endif
  43. #define APP_KEY TEXT("Software\\Microsoft\\CompatConsole")
  44. #define APPCOMPAT_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags")
  45. //*****************************************************************************
  46. // Global Variables
  47. //*****************************************************************************
  48. // g_hInstance: Defined in CompatAdmin.CPP
  49. extern BOOL g_bWin2K; // Is the OS WIN2K
  50. extern HINSTANCE g_hInstance;
  51. extern HSDB g_hSDB;
  52. extern HWND g_hWndLastFocus;
  53. DWORD WIN_MSG(); // Formats and prints last error
  54. // g_uDPFLevel: Defined in CApplication.CPP
  55. extern UINT g_uDPFLevel;
  56. // g_uProfileDPFLevel: Defined in CApplication.CPP
  57. extern UINT g_uProfileDPFLevel;
  58. class CApplication;
  59. // g_theApp: Defined in CompatAdmin.CPP
  60. extern CApplication g_theApp;
  61. // The number of views used by the app
  62. enum {
  63. VIEW_DATABASE=0,
  64. VIEW_SEARCHDB,
  65. VIEW_FORCEDWORD=0xFFFFFFFF
  66. };
  67. #define MAX_VIEWS 15
  68. // Child Window ID's used by the app
  69. #define BASE_ID (MAX_VIEWS+1)
  70. #define STATUS_ID (BASE_ID)
  71. #define TOOLBAR_ID (BASE_ID+1)
  72. // Slider window define
  73. #define SLIDER_WIDTH 5
  74. // Main toolbar info
  75. #define MAINBUTTONS 11
  76. #define IMAGE_NEWFILE 0
  77. #define IMAGE_OPENFILE 1
  78. #define IMAGE_SAVEFILE 2
  79. #define IMAGE_EMAIL 3
  80. #define IMAGE_PRINT 4
  81. #define IMAGE_PRINTPREVIEW 5
  82. #define IMAGE_DISABLEUSER 6
  83. #define IMAGE_DISABLEGLOBAL 7
  84. #define IMAGE_DLL 8
  85. #define IMAGE_APPHELP 24
  86. #define IMAGE_APPLICATION 10
  87. #define IMAGE_SHIM 23
  88. #define IMAGE_WARNING 12
  89. #define IMAGE_VIEWHELP 13
  90. #define IMAGE_VIEWSHIM 14
  91. #define IMAGE_SHIMWIZARD 15
  92. #define IMAGE_SHOWXML 16
  93. #define IMAGE_VIEWGLOBAL 17
  94. #define IMAGE_VIEWPATCH 18
  95. #define IMAGE_DRIVESEARCH 19
  96. #define IMAGE_GUID 20
  97. #define IMAGE_SHOWLAYERS 21
  98. #define IMAGE_VIEWDISABLED 22
  99. #define IMAGE_LAYERS 25
  100. #define IMAGE_PROPERTIES (CDatabase::m_uStandardImages + STD_PROPERTIES)
  101. #define IMAGE_DELETE (CDatabase::m_uStandardImages + STD_DELETE)
  102. void FormatVersion(LARGE_INTEGER liVer, LPTSTR szText);
  103. //*****************************************************************************
  104. //
  105. // Class: CWindow
  106. //
  107. // Purpose: CWindow is the core class for the application. It wraps the Win32
  108. // User related APIs that govern window management, into a small and
  109. // easy to use class. The functionality is purposefully small, and
  110. // limited in scope. This provides the framework for building the
  111. // rest of the windows classes, simplifying the rest of the code
  112. // and reusing as much code as possible.
  113. //
  114. // Additional: For additional information, see CompatAdmin.DOC.
  115. //
  116. // History
  117. //
  118. // A-COWEN Nov 7, 2000 Wrote it.
  119. //
  120. //*****************************************************************************
  121. class CWindow {
  122. // Class variables
  123. public:
  124. HWND m_hWnd;
  125. // Class support functions.
  126. private:
  127. static LRESULT CALLBACK MsgProc(HWND hWnd,
  128. UINT uMsg,
  129. WPARAM wParam,
  130. LPARAM lParam);
  131. // Public access functions.
  132. public:
  133. virtual BOOL STDCALL Create (LPCTSTR szClassName,
  134. LPCTSTR szWindowTitle,
  135. int nX,
  136. int nY,
  137. int nWidth,
  138. int nHeight,
  139. CWindow * pParent,
  140. HMENU nMenuID,
  141. DWORD dwExFlags,
  142. DWORD dwFlags);
  143. virtual LRESULT STDCALL MsgProc(UINT uMsg,
  144. WPARAM wParam,
  145. LPARAM lParam);
  146. virtual void STDCALL Refresh (void);
  147. // Message pump callbacks.
  148. public:
  149. MSGAPI msgCreate (void);
  150. MSGAPI msgClose (void);
  151. MSGAPI msgCommand (UINT uID,
  152. HWND hSender);
  153. MSGAPI msgChar (TCHAR chChar);
  154. MSGAPI msgNotify (LPNMHDR pHdr);
  155. MSGAPI msgResize (UINT uWidth,
  156. UINT uHeight);
  157. MSGAPI msgPaint (HDC hDC);
  158. MSGAPI msgEraseBackground (HDC hDC);
  159. };
  160. typedef struct {
  161. NMHDR Hdr;
  162. PVOID pData;
  163. } LISTVIEWNOTIFY, *PLISTVIEWNOTIFY;
  164. #define LVN_SELCHANGED (WM_USER+1024)
  165. typedef struct _tagList {
  166. //CSTRING szText;
  167. TCHAR szText[MAX_PATH_BUFFSIZE*2];
  168. UINT uImageIndex;
  169. PVOID pData;
  170. struct _tagList * pNext;
  171. _tagList()
  172. {
  173. //szText.Init();
  174. }
  175. ~_tagList()
  176. {
  177. //szText.Release();
  178. }
  179. } LIST, *PLIST;
  180. class CListView: public CWindow {
  181. private:
  182. UINT m_nEntries;
  183. UINT m_uCaptionBottom;
  184. UINT m_uTextHeight;
  185. PLIST m_pList;
  186. PLIST m_pSelected;
  187. PLIST m_pFreeList;
  188. PLIST m_pTail;// Points to the tail of the free list.
  189. UINT m_uTop;
  190. UINT m_uPageSize;
  191. PLIST m_pCurrent;
  192. UINT m_uCurrent;
  193. HFONT m_hCaptionFont;
  194. HFONT m_hListFont;
  195. HBRUSH m_hGrayBrush;
  196. HBRUSH m_hWindowBrush;
  197. HBRUSH m_hSelectedBrush;
  198. HPEN m_hLinePen;
  199. BOOL m_bHilight;
  200. BOOL FindEntry(UINT uIndex);
  201. public:
  202. PLIST getSelected();
  203. CListView();
  204. ~CListView();
  205. // List view procedures
  206. BOOL STDCALL AddEntry(CSTRING &, UINT uImage, PVOID pData);
  207. BOOL STDCALL RemoveEntry(UINT);
  208. BOOL STDCALL RemoveAllEntries(void);
  209. UINT STDCALL GetNumEntries(void);
  210. CSTRING STDCALL GetEntryName(UINT);
  211. UINT STDCALL GetEntryImage(UINT);
  212. PVOID STDCALL GetEntryData(UINT);
  213. UINT STDCALL GetSelectedEntry(void);
  214. void STDCALL ShowHilight(BOOL);
  215. // Window procedures
  216. MSGAPI msgCreate (void);
  217. virtual LRESULT STDCALL MsgProc(UINT uMsg,
  218. WPARAM wParam,
  219. LPARAM lParam);
  220. MSGAPI msgChar (TCHAR chChar);
  221. MSGAPI msgPaint (HDC hDC);
  222. MSGAPI msgEraseBackground (HDC hDC);
  223. };
  224. class CView;
  225. BOOL CALLBACK TestRunDlg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  226. BOOL CALLBACK TestRunWait(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  227. typedef struct {
  228. CSTRING szCommandLine;
  229. BOOL bNTSD;
  230. BOOL bLogging;
  231. BOOL bMSDEV;
  232. } TESTRUN, *PTESTRUN;
  233. class CApplication: public CWindow {
  234. typedef struct {
  235. CView * pView;
  236. } VIEWLIST, *PVIEWLIST;
  237. private:
  238. CDatabaseGlobal m_DBGlobal;
  239. CDatabaseLocal m_DBLocal;
  240. CDatabase *m_pDBCurrent;
  241. HWND m_hDialog;
  242. HKEY m_hKey;
  243. HACCEL m_hAccelerator;
  244. CView * m_pCurrentView;
  245. VIEWLIST m_ViewList[MAX_VIEWS];
  246. protected:
  247. friend class CView;
  248. friend class CDBView;
  249. TBBUTTON m_MainButtons[MAINBUTTONS];
  250. UINT g_uButtons;
  251. HWND m_hStatusBar;
  252. HWND m_hToolBar;
  253. HMENU m_hMenu;
  254. HBITMAP m_hToolBitmap;
  255. public:
  256. CApplication();
  257. CDatabase& GetDBLocal() ;
  258. CDatabase& GetDBGlobal();
  259. virtual LRESULT STDCALL MsgProc(UINT uMsg,
  260. WPARAM wParam,
  261. LPARAM lParam);
  262. // Utility
  263. BOOL GetFilename(LPCTSTR szTitle, LPCTSTR szFilter, LPCTSTR szDefaultFile, LPCTSTR szDefExt, DWORD dwFlags, BOOL bOpen, CSTRING & szStr);
  264. BOOL InvokeEXE(LPCTSTR szEXE, LPCTSTR szCommandLine, BOOL bWait, BOOL bDialog = TRUE, BOOL bConsole = FALSE);
  265. BOOL TestRun(PDBRECORD, CSTRING * szFile, CSTRING * szCommandLine, HWND hParent);
  266. // BOOL InsertRecord(PDBRECORD pRecord);
  267. // BOOL InvokeCompiler(LPTSTR szCommandLine);
  268. // Database Management
  269. /*
  270. virtual DWORD STDCALL GetEntryFlags(HKEY,GUID &);
  271. virtual BOOL STDCALL SetEntryFlags(HKEY,GUID &,DWORD);
  272. virtual BOOL STDCALL OpenDatabase(LPTSTR szFilename, BOOL bGlobal);
  273. virtual BOOL STDCALL SaveDatabase(LPTSTR szFilename);
  274. virtual void STDCALL AddShim(TAGID, BOOL, BOOL, BOOL);
  275. virtual void STDCALL ReadShims(BOOL);
  276. virtual BOOL STDCALL ReadRecord(TAGID, PDBRECORD);
  277. virtual CSTRING STDCALL ReadDBString(TAGID);
  278. */
  279. // Toolbar access
  280. virtual BOOL STDCALL AddToolbarButton(UINT uBmp, UINT uCmd, UINT uState, UINT uStyle);
  281. virtual BOOL STDCALL SetButtonState(UINT uCmd, UINT uState);
  282. // Status bar access
  283. virtual BOOL STDCALL SetStatusText(UINT uSpace, CSTRING & szText);
  284. // The main application message pump.
  285. virtual int STDCALL MessagePump(void);
  286. // View management
  287. void STDCALL ActivateView(CView *, BOOL fNewCreate = TRUE);
  288. void STDCALL UpdateView(BOOL bWindowOnly = FALSE);
  289. // Profile management.
  290. UINT STDCALL ReadReg (LPCTSTR szKey,
  291. PVOID pData,
  292. UINT uSize);
  293. UINT STDCALL WriteReg (LPCTSTR szKey,
  294. UINT uType,
  295. PVOID pData,
  296. UINT uSize);
  297. // Overloaded message procs
  298. MSGAPI msgCreate (void);
  299. MSGAPI msgClose (void);
  300. MSGAPI msgNotify (LPNMHDR pHdr);
  301. MSGAPI msgChar (TCHAR chChar);
  302. MSGAPI msgResize (UINT uWidth,
  303. UINT uHeight);
  304. MSGAPI msgCommand (UINT uID,
  305. HWND hSender);
  306. };
  307. class CView: public CWindow {
  308. public:
  309. HMENU m_hMenu;
  310. public:
  311. CView();
  312. virtual BOOL Initialize (void);
  313. // Activate/Deactivate code. Overload to update the toolbar,
  314. // menus.. etc.
  315. virtual BOOL Activate (BOOL fNewCreate =TRUE);
  316. virtual BOOL Deactivate (void);
  317. // Update: Tells the view that something in the database has
  318. // changed. It should update the screen if appropriate.
  319. virtual void Update (BOOL fNewCreate =TRUE);
  320. };
  321. //*****************************************************************************
  322. //
  323. // Support Class: CGrabException
  324. //
  325. // Purpose: Record the current exception handler, and compare against
  326. // at a future date.
  327. //
  328. // Notes: Practically speaking the class grabs the exception handler
  329. // immediately when the application starts, and before the
  330. // user has a chance to setup any exception handling. The
  331. // assertion macro can then compare against the current value.
  332. // if they're the same there's no exception handler, so hide
  333. // the exception button. Otherwise throwing the exception will
  334. // throw to the kernel's exception handler and crash the app.
  335. //
  336. // History
  337. //
  338. // A-COWEN Nov 7, 2000 Wrote it.
  339. //
  340. //*****************************************************************************
  341. /*
  342. class CGrabException {
  343. private:
  344. PVOID m_pDefaultHandler;
  345. public:
  346. CGrabException()
  347. {
  348. PVOID pCurrent;
  349. __asm
  350. {
  351. mov eax,fs:[0]
  352. mov pCurrent,eax
  353. }
  354. m_pDefaultHandler = pCurrent;
  355. }
  356. BOOL InHandler(void)
  357. {
  358. PVOID pCurrent;
  359. __asm
  360. {
  361. mov eax,fs:[0]
  362. mov pCurrent,eax
  363. }
  364. return(pCurrent == m_pDefaultHandler) ? FALSE:TRUE;
  365. }
  366. };
  367. */
  368. //*****************************************************************************
  369. //
  370. // Support macro: assert_s, assert, ASSERT, ASSERT_S
  371. //
  372. // Purpose: Updates the standard assert macro to provide additional
  373. // debugging information.
  374. //
  375. // Notes: For more information, see CompatAdmin.DOC
  376. //
  377. // History
  378. //
  379. // A-COWEN Nov 7, 2000 Wrote it.
  380. //
  381. //*****************************************************************************
  382. #define ASSERT_BREAK 0
  383. #define ASSERT_EXCEPT 1
  384. #define ASSERT_ABORT 2
  385. #define ASSERT_IGNORE 3
  386. /*
  387. int _ASSERT(int nLine, LPCTSTR szFile, LPCTSTR szCause, LPCTSTR szDesc);
  388. #ifdef _DEBUG
  389. #define assert_s(x,y) if (!(x)) \
  390. { \
  391. int nResult = _ASSERT(__LINE__,__FILE__,#x,y); \
  392. \
  393. if (ASSERT_BREAK == nResult) \
  394. __asm {int 3}; \
  395. \
  396. if (ASSERT_EXCEPT == nResult) \
  397. throw; \
  398. \
  399. if (ASSERT_ABORT == nResult) \
  400. ExitProcess(-1); \
  401. }
  402. #ifndef assert
  403. #define assert(x) assert_s(x,TEXT(""))
  404. #endif // assert
  405. #else // _DEBUG
  406. #define assert_s(x,y)
  407. #ifndef assert
  408. #define assert(x) assert_s(x,TEXT(""))
  409. #endif // assert
  410. #endif // _DEBUG
  411. #define ASSERT(x) assert(x)
  412. #define ASSERT_S(x,y) assert_s(x,y)
  413. */
  414. //*****************************************************************************
  415. //
  416. // Support macro: DPF
  417. //
  418. // Purpose: Inline function implementation of a common macro, DPF.
  419. // DPF stands for DebugPrintF. This implementation has a
  420. // limit of 512 byte final constructed string, and will
  421. // append a \n only if one doesn't already exist. Variable
  422. // arguments are fully supported.
  423. //
  424. // Notes: For more information, see CompatAdmin.DOC
  425. //
  426. // History
  427. //
  428. // A-COWEN Nov 8, 2000 Wrote it.
  429. //
  430. //*****************************************************************************
  431. #ifndef DPF_LEVEL
  432. #define DPF_LEVEL 1
  433. #endif
  434. inline void _cdecl DPF(UINT nLevel, LPCTSTR szFormat, ...)
  435. {
  436. #ifdef NODPF
  437. if ( nLevel > g_uDPFLevel )
  438. return;
  439. TCHAR szString[512];
  440. va_list list;
  441. va_start(list,szFormat);
  442. vsprintf(szString,szFormat,list);
  443. if ( TEXT('\n') != szString[::lstrlen(szString)-1] )
  444. lstrcat(szString,TEXT("\n"));
  445. ::OutputDebugString(szString);
  446. #endif
  447. }
  448. //*****************************************************************************
  449. //
  450. // Support macro: BEGIN_PROFILE/END_PROFILE
  451. //
  452. // Purpose: Profile basic profiling macros for tracing performance
  453. // problems.
  454. //
  455. // Notes: These macros are fully nestable. For each BEGIN_PROFILE,
  456. // one of the END_PROFILE macros must be used.
  457. //
  458. // For more information, see CompatAdmin.DOC
  459. //
  460. // History
  461. //
  462. // A-COWEN Nov 8, 2000 Wrote it.
  463. //
  464. //*****************************************************************************
  465. #ifndef PROFILE_DPF
  466. #define PROFILE_DPF 1
  467. #endif
  468. #ifndef NOPROFILE
  469. #define BEGIN_PROFILE(x) { \
  470. LARGE_INTEGER liStart; \
  471. LARGE_INTEGER liStop; \
  472. LPTSTR szProfileName = x; \
  473. \
  474. QueryPerformanceCounter(&liStart);
  475. #define END_PROFILE QueryPerformanceCounter(&liStop); \
  476. \
  477. LARGE_INTEGER liFreq; \
  478. \
  479. QueryPerformanceFrequency(&liFreq);\
  480. \
  481. DPF(g_uProfileDPFLevel,TEXT("Profile: %s (%d ticks, %f seconds)"),szProfileName,(int)(liStop.QuadPart - liStart.QuadPart),(float)(liStop.QuadPart - liStart.QuadPart)/(float)liFreq.QuadPart); \
  482. }
  483. #else
  484. #define BEGIN_PROFILE(x)
  485. #define END_PROFILE
  486. #endif