Leaked source code of windows server 2003
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.

2266 lines
60 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. CompatAdmin.h
  5. Abstract:
  6. Main Header for the application
  7. Author:
  8. kinshu created July 2, 2001
  9. --*/
  10. #ifndef _COMPATADMIN_H
  11. #define _COMPATADMIN_H
  12. #include <windows.h>
  13. #include <tchar.h>
  14. #include <Shlwapi.h>
  15. #include <Shellapi.h>
  16. #include <commctrl.h>
  17. #include <Commdlg.h>
  18. #include <Sddl.h>
  19. #include <Winbase.h>
  20. #include "resource.h"
  21. #include "HtmlHelp.h"
  22. #include <strsafe.h>
  23. extern "C" {
  24. #include "shimdb.h"
  25. }
  26. //////////////////////// Externs //////////////////////////////////////////////
  27. class DatabaseTree;
  28. extern TCHAR g_szAppName[];
  29. extern HWND g_hDlg;
  30. extern DWORD ATTRIBUTE_COUNT;
  31. extern BOOL g_bUpdateInstalledRequired;
  32. extern HWND g_hdlgQueryDB;
  33. extern HWND g_hdlgSearchDB;
  34. extern BOOL g_bExpert;
  35. extern BOOL g_bAdmin;
  36. extern DatabaseTree DBTree;
  37. extern struct _tagClipBoard gClipBoard;
  38. extern struct tagDataBaseList DataBaseList;
  39. extern struct tagDataBaseList InstalledDataBaseList;
  40. ///////////////////////////////////////////////////////////////////////////////
  41. //////////////////////// Defines //////////////////////////////////////////////
  42. // The type of module. Will specify either inclusion or exclusion
  43. #define INCLUDE 1
  44. #define EXCLUDE 0
  45. //
  46. // Indexes for HKEY array on which we are listening for events. The events are used for automatically refreshing
  47. // the list of installed and per-user
  48. #define IND_PERUSER 0
  49. #define IND_ALLUSERS 1
  50. // Number of spaces that a tab corresponds to. This is used when we are formatting the XML
  51. // before writing it to the disk.
  52. #define TAB_SIZE 4
  53. // Make sure that both LIMIT_APP_NAME and LIMIT_LAYER_NAME have the same value
  54. // Used for limiting the text filed in the UI
  55. #define LIMIT_APP_NAME 128
  56. #define LIMIT_LAYER_NAME 128
  57. #define MAX_VENDOR_LENGTH 100
  58. // Defines for the event types. These are the events which are shown in the event window. Main-menu>View>Events
  59. #define EVENT_ENTRY_COPYOK 0
  60. #define EVENT_SYSTEM_RENAME 1
  61. #define EVENT_CONFLICT_ENTRY 2
  62. #define EVENT_LAYER_COPYOK 3
  63. // The number of file names that we will show in the MRU list
  64. #define MAX_MRU_COUNT 5
  65. //
  66. // The file name where we are going to save the shim log.
  67. // This is created in %windir%/AppPatch
  68. #define SHIM_FILE_LOG_NAME TEXT("CompatAdmin.log")
  69. // Auto-complete flag passed on to SHAutoComplete()
  70. #define AUTOCOMPLETE SHACF_FILESYSTEM | SHACF_AUTOSUGGEST_FORCE_ON
  71. // Select style passed to TREEVIEW_SHOW
  72. #define TVSELECT_STYLE TVGN_CARET
  73. // Select and show the tree item
  74. //*******************************************************************************
  75. #define TREEVIEW_SHOW(hwndTree, hItem, flags) \
  76. { \
  77. TreeView_Select(hwndTree, hItem, TVSELECT_STYLE); \
  78. TreeView_EnsureVisible(hwndTree, hItem); \
  79. }
  80. //*******************************************************************************
  81. //
  82. // Add a trailing '\'to a path, if it does not exist
  83. //*******************************************************************************
  84. #define ADD_PATH_SEPARATOR(szStr, nSize) \
  85. { \
  86. INT iLength = lstrlen(szStr); \
  87. if ((iLength < nSize - 1 && iLength > 0) \
  88. && szStr[iLength - 1] != TEXT('\\')) { \
  89. StringCchCat(szStr, nSize, TEXT("\\")); \
  90. } \
  91. }
  92. //*******************************************************************************
  93. // Enable or disable a tool bar button
  94. //*******************************************************************************
  95. #define EnableToolBarButton(hwndTB, id, bEnable) \
  96. SendMessage(hwndTB, TB_ENABLEBUTTON, (WPARAM)id, (LPARAM) MAKELONG(bEnable, 0));
  97. //******************************************************************************
  98. //
  99. // Gets the size of a file when we already have PATTRINFO. This is needed
  100. // when we have to sort the files generated while using "Auto-Generate" matching
  101. // files option in the fix or app help wizard. We sort the files are use only the
  102. // first MAX_AUTO_MATCH files
  103. //*******************************************************************************
  104. #define GET_SIZE_ATTRIBUTE(pAttrInfo, dwAttrCount, dwSize) \
  105. { \
  106. for (DWORD dwIndex = 0; dwIndex < dwAttrCount; dwIndex++) { \
  107. \
  108. if (pAttrInfo[dwIndex].tAttrID == TAG_SIZE \
  109. && (pAttrInfo[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE)) { \
  110. \
  111. dwSize = pAttrInfo[dwIndex].dwAttr; \
  112. break; \
  113. } \
  114. } \
  115. }
  116. //*******************************************************************************
  117. //*******************************************************************************
  118. #define REGCLOSEKEY(hKey) \
  119. { \
  120. if (hKey) { \
  121. RegCloseKey(hKey); \
  122. hKey = NULL; \
  123. } \
  124. }
  125. //*******************************************************************************
  126. //*******************************************************************************
  127. #define ENABLEWINDOW(hwnd,bEnable) \
  128. { \
  129. HWND hWndTemp = hwnd; \
  130. if (hWndTemp) { \
  131. EnableWindow(hWndTemp, bEnable); \
  132. } else { \
  133. assert(FALSE); \
  134. } \
  135. }
  136. //*******************************************************************************
  137. // IDs for the MRU items. Make sure that we do not get any control or menu with these ids
  138. #define ID_FILE_FIRST_MRU 351
  139. #define ID_FILE_MRU1 ID_FILE_FIRST_MRU
  140. #define ID_FILE_MRU2 (ID_FILE_FIRST_MRU + 1)
  141. #define ID_FILE_MRU3 (ID_FILE_FIRST_MRU + 2)
  142. #define ID_FILE_MRU4 (ID_FILE_FIRST_MRU + 3)
  143. #define ID_FILE_MRU5 (ID_FILE_FIRST_MRU + 4)
  144. // The key in the registry where we store our display settings
  145. #define DISPLAY_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\CompatAdmin\\Display")
  146. // The key in the registry where we store our MRU file names
  147. #define MRU_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\CompatAdmin\\MRU")
  148. // The base key. At least this should be present on all systems, even if we just loaded the OS
  149. #define KEY_BASE TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion")
  150. //
  151. // The default mask for attributes that we choose. By default we choose these attributes:
  152. // TAG_BIN_FILE_VERSION, TAG_BIN_PRODUCT_VERSION, TAG_PRODUCT_VERSION, TAG_FILE_VERSION, TAG_COMPANY_NAME,TAG_PRODUCT_NAME
  153. #define DEFAULT_MASK 0x3B8L
  154. // The various user defined message types
  155. #define WM_USER_MATCHINGTREE_REFRESH WM_USER + 1024
  156. #define WM_USER_DOTHESEARCH WM_USER + 1025
  157. #define WM_USER_ACTIVATE WM_USER + 1026
  158. #define WM_USER_REPAINT_TREEITEM WM_USER + 1030
  159. #define WM_USER_LOAD_COMMANDLINE_DATABASES WM_USER + 1031
  160. #define WM_USER_POPULATECONTENTSLIST WM_USER + 1032
  161. #define WM_USER_REPAINT_LISTITEM WM_USER + 1034
  162. #define WM_USER_UPDATEINSTALLED WM_USER + 1035
  163. #define WM_USER_UPDATEPERUSER WM_USER + 1036
  164. #define WM_USER_GETSQL WM_USER + 1037
  165. #define WM_USER_NEWMATCH WM_USER + 1038
  166. #define WM_USER_NEWFILE WM_USER + 1039
  167. #define WM_USER_NEWQDB WM_USER + 1041
  168. #define WM_USER_TESTRUN_NODIALOG WM_USER + 1042
  169. // Defines for the Images
  170. #define IMAGE_SHIM 0
  171. #define IMAGE_APPHELP 1
  172. #define IMAGE_LAYERS 2
  173. #define IMAGE_PATCHES 3
  174. #define IMAGE_MATCHINFO 4
  175. #define IMAGE_MATCHGROUP 5
  176. #define IMAGE_WARNING 6
  177. #define IMAGE_GLOBAL 7
  178. #define IMAGE_WORKING 8
  179. #define IMAGE_COMMANDLINE 9
  180. #define IMAGE_INCLUDE 10
  181. #define IMAGE_EXCLUDE 11
  182. #define IMAGE_APP 12
  183. #define IMAGE_INSTALLED 13
  184. #define IMAGE_DATABASE 14
  185. #define IMAGE_SINGLEAPP 15
  186. #define IMAGE_ALLUSERS 16
  187. #define IMAGE_SINGLEUSER 17
  188. #define IMAGE_APPLICATION 18
  189. #define IMAGE_EVENT_ERROR 19
  190. #define IMAGE_EVENT_WARNING 20
  191. #define IMAGE_EVENT_INFO 21
  192. #define IMAGE_LAST 24 //Last global image index.
  193. // Images for the tool bar
  194. #define IMAGE_TB_NEW 0
  195. #define IMAGE_TB_OPEN 1
  196. #define IMAGE_TB_SAVE 2
  197. #define IMAGE_TB_NEWFIX 3
  198. #define IMAGE_TB_NEWAPPHELP 4
  199. #define IMAGE_TB_NEWMODE 5
  200. #define IMAGE_TB_RUN 6
  201. #define IMAGE_TB_SEARCH 7
  202. #define IMAGE_TB_QUERY 8
  203. // Id for the tool bar in the main window, which we create dynamically
  204. #define ID_TOOLBAR 5555
  205. //
  206. // Max. length of the SQL. This string is of the form 'SELECT ... FROM ... [WHERE ...]'
  207. // Note that the actual length of the final SQL will be more than the sum of the text in the
  208. // select and the where text fields, because it will include the key words like SELECT, WHERE, FROM
  209. // and also the name of the databases like SYSTEM_DB etc.
  210. // So we made it as 2096
  211. #define MAX_SQL_LENGTH 2096
  212. //
  213. // Debugging spew
  214. typedef enum
  215. {
  216. dlNone = 0,
  217. dlPrint,
  218. dlError,
  219. dlWarning,
  220. dlInfo
  221. } DEBUGLEVEL;
  222. //
  223. // Defines for mapping into strsafe functions
  224. //
  225. #define SafeCpyN(pszDest, pszSource, nDestSize) StringCchCopy(pszDest, nDestSize, pszSource)
  226. ///////////////////////////////////////////////////////////////////////////////
  227. /*++
  228. !!!!!!!!!!!!!!! Warning !!!!!!!!!!!!!!!!!!
  229. Do not change the values for the DATABASE_TYPE_* enums. They should be powers of 2
  230. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  231. The types of various data structures and some GUI tree items. In tree views
  232. we have lParams associated with the tree items. All data structures have
  233. a type field, which is the first field. So that if we have a pointer/lParam
  234. and if the value of the pointer is greater than TYPE_NULL, then we typecast
  235. it to PDS_TYPE and see if the type field is any of our known data structures
  236. --*/
  237. typedef unsigned (__stdcall *PTHREAD_START)(PVOID);
  238. typedef const size_t K_SIZE;
  239. typedef enum {
  240. TYPE_UNKNOWN = 0,
  241. DATABASE_TYPE_GLOBAL = 0x01, // The global/system database i.e. %windir%\AppPatch\Sysmain.sdb
  242. DATABASE_TYPE_INSTALLED = 0x02, // An installed database
  243. DATABASE_TYPE_WORKING = 0x04, // A working/custom database
  244. FIX_SHIM, // Type for SHIM_FIX
  245. FIX_PATCH, // Type for PATCH_FIX
  246. FIX_LAYER, // Type for LAYER_FIX
  247. FIX_FLAG, // Type for FLAG_FIX
  248. FIX_LIST_SHIM, // Type for SHIM_FIX_LIST
  249. FIX_LIST_PATCH, // Type for PATCH_FIX_LIST
  250. FIX_LIST_LAYER, // Type for LAYER_FIX_LIST
  251. FIX_LIST_FLAG, // Type for FLAG_FIX_LIST
  252. TYPE_GUI_APPS, // lParam for "Applications" Tree item
  253. TYPE_GUI_SHIMS, // lParam for "Compatibility Fixes" Tree item
  254. TYPE_GUI_MATCHING_FILES, // lParam for "Compatibility Modes" Tree item
  255. TYPE_GUI_LAYERS, // lParam for "Compatibility Modes" Tree item
  256. TYPE_GUI_PATCHES, // lParam for "Compatibility Patches" Tree item
  257. TYPE_GUI_COMMANDLINE, // lParam for "Commandline" Tree item
  258. TYPE_GUI_INCLUDE, // lParam for an included module tree item
  259. TYPE_GUI_EXCLUDE, // lParam for an excluded module tree item
  260. TYPE_GUI_DATABASE_WORKING_ALL, // lParam for "Custom Database" Tree item
  261. TYPE_GUI_DATABASE_INSTALLED_ALL, // lParam for "Installed Database" Tree item
  262. TYPE_APPHELP_ENTRY, // Type for APPHELP
  263. TYPE_ENTRY, // Type for DBENTRY
  264. TYPE_MATCHING_FILE, // Type for MATCHINGFILE
  265. TYPE_MATCHING_ATTRIBUTE, // An attribute item that appears under the matching file tree item
  266. TYPE_NULL //NOTE: This should be the last in the enum !!
  267. } TYPE;
  268. typedef enum {
  269. FLAG_USER,
  270. FLAG_KERNEL
  271. } FLAGTYPE;
  272. //
  273. // Source type where the cut or copy was performed
  274. //
  275. typedef enum {
  276. LIB_TREE = 0, // The data base tree (LHS)
  277. ENTRY_TREE, // The entry tree (RHS)
  278. ENTRY_LIST // The contents list (RHS)
  279. }SOURCE_TYPE;
  280. typedef enum {
  281. APPTYPE_NONE, // No apphelp has been added
  282. APPTYPE_INC_NOBLOCK, // Soft blocked
  283. APPTYPE_INC_HARDBLOCK, // Hard blocked
  284. APPTYPE_MINORPROBLEM, // <Not used at the moment>
  285. APPTYPE_REINSTALL // <Not used at the moment>
  286. } SEVERITY;
  287. /*++
  288. All data structures are sub classed from this, so all have a TYPE type member
  289. as their first member
  290. --*/
  291. typedef struct tagTYPE {
  292. TYPE type;
  293. } DS_TYPE, *PDS_TYPE;
  294. /*++
  295. Used for setting the background of controls that we show in a tab control
  296. --*/
  297. typedef HRESULT (*PFNEnableThemeDialogTexture)(HWND hwnd, DWORD dwFlags);
  298. /*++
  299. Used when we are using the disk search option. MainMenu>Search>Search for fixed programs
  300. --*/
  301. typedef struct _MatchedEntry {
  302. CSTRING strAppName; // Name of the application
  303. CSTRING strPath; // The complete path of the program
  304. CSTRING strDatabase; // Name of the database
  305. CSTRING strAction; // Action type. Fixed with fixes, layers, or apphelp
  306. TCHAR szGuid[128]; // Guid of the database in which the fixed program entry was found
  307. TAGID tiExe; // Tag id for the fixed program entry in the database in which it was found
  308. } MATCHEDENTRY, *PMATCHEDENTRY;
  309. /*++
  310. Used for customizing LUA shim
  311. --*/
  312. typedef struct tagLUAData
  313. {
  314. CSTRING strAllUserDir;
  315. CSTRING strPerUserDir;
  316. CSTRING strStaticList;
  317. CSTRING strDynamicList;
  318. CSTRING strExcludedExtensions;
  319. BOOL IsEmpty()
  320. {
  321. return (strAllUserDir == NULL &&
  322. strPerUserDir == NULL &&
  323. strStaticList == NULL &&
  324. strDynamicList == NULL &&
  325. strExcludedExtensions == NULL);
  326. }
  327. BOOL IsEqual(tagLUAData & other) {
  328. return (strAllUserDir == other.strAllUserDir &&
  329. strPerUserDir == other.strPerUserDir &&
  330. strStaticList == other.strStaticList &&
  331. strDynamicList == other.strDynamicList &&
  332. strExcludedExtensions == other.strExcludedExtensions);
  333. }
  334. void Copy(tagLUAData & other) {
  335. strAllUserDir = other.strAllUserDir;
  336. strPerUserDir = other.strPerUserDir;
  337. strStaticList = other.strStaticList;
  338. strDynamicList = other.strDynamicList;
  339. strExcludedExtensions = other.strExcludedExtensions;
  340. }
  341. void Copy(tagLUAData* pLuaDataOther)
  342. {
  343. assert(pLuaDataOther);
  344. if (pLuaDataOther == NULL) {
  345. return;
  346. }
  347. strAllUserDir = pLuaDataOther->strAllUserDir;
  348. strPerUserDir = pLuaDataOther->strPerUserDir;
  349. strStaticList = pLuaDataOther->strStaticList;
  350. strDynamicList = pLuaDataOther->strDynamicList;
  351. strExcludedExtensions = pLuaDataOther->strExcludedExtensions;
  352. }
  353. void Free()
  354. {
  355. strStaticList.Release();
  356. strDynamicList.Release();
  357. strAllUserDir.Release();
  358. strPerUserDir.Release();
  359. strExcludedExtensions.Release();
  360. }
  361. } LUADATA, *PLUADATA;
  362. /*++
  363. A shim also known as a compatibility fix. In fact compatibility fix means any of
  364. shims, flags or patches. In the entry tree (RHS), if some exe has a patch, it is shown
  365. differently under "Compatibility Patches" tree item
  366. --*/
  367. typedef struct tagSHIM_FIX : public DS_TYPE {
  368. struct tagSHIM_FIX* pNext; // The next shim
  369. CSTRING strName; // The name of the shim
  370. CSTRING strDescription; // The desciption of the shim
  371. CSTRING strCommandLine; // The commandline for the shim
  372. BOOL bGeneral; // Is this a general or a specific shim
  373. CSTRINGLIST strlInExclude; // List of include and exclude modules
  374. tagSHIM_FIX()
  375. {
  376. pNext = NULL;
  377. bGeneral = FALSE;
  378. type = FIX_SHIM;
  379. }
  380. } SHIM_FIX, *PSHIM_FIX;
  381. /*++
  382. Contains a pointer to a shim and a pointer to a tagSHIM_FIX_LIST
  383. --*/
  384. typedef struct tagSHIM_FIX_LIST : public DS_TYPE {
  385. struct tagSHIM_FIX_LIST* pNext; // The next tagSHIM_FIX_LIST
  386. PSHIM_FIX pShimFix; // Pointer to a shim
  387. CSTRING strCommandLine; // Any command line
  388. CSTRINGLIST strlInExclude; // Any include-exclude modules
  389. PLUADATA pLuaData; // Lua data
  390. tagSHIM_FIX_LIST()
  391. {
  392. pNext = NULL;
  393. pShimFix = NULL;
  394. pLuaData = NULL;
  395. type = FIX_LIST_SHIM;
  396. }
  397. } SHIM_FIX_LIST, *PSHIM_FIX_LIST;
  398. void
  399. DeleteShimFixList(
  400. PSHIM_FIX_LIST psl
  401. );
  402. /*++
  403. A compatibility flag
  404. --*/
  405. typedef struct tagFLAG_FIX : public DS_TYPE {
  406. struct tagFLAG_FIX* pNext; // Pointer to the next flag
  407. CSTRING strName; // Name of the flag
  408. CSTRING strDescription; // Description for the flag
  409. CSTRING strCommandLine; // Command line for the flag
  410. ULONGLONG ullMask; // <Not used at the moment>
  411. FLAGTYPE flagType; // Type, one of: FLAG_USER, FLAG_KERNEL
  412. BOOL bGeneral; // General or specific
  413. tagFLAG_FIX()
  414. {
  415. pNext = NULL;
  416. type = FIX_FLAG;
  417. bGeneral = FALSE;
  418. }
  419. } FLAG_FIX, *PFLAG_FIX;
  420. /*++
  421. Contains a pointer to a flag and a pointer to a tagFLAG_FIX_LIST
  422. --*/
  423. typedef struct tagFLAG_FIX_LIST : public DS_TYPE {
  424. struct tagFLAG_FIX_LIST* pNext; // The next tagFLAG_FIX_LIST
  425. PFLAG_FIX pFlagFix; // Pointer to a flag
  426. CSTRING strCommandLine; // Any command lines for this flag
  427. tagFLAG_FIX_LIST()
  428. {
  429. pNext = NULL;
  430. pFlagFix = NULL;
  431. type = FIX_LIST_FLAG;
  432. }
  433. } FLAG_FIX_LIST, *PFLAG_FIX_LIST;
  434. void
  435. DeleteFlagFixList(
  436. PFLAG_FIX_LIST pfl
  437. );
  438. /*++
  439. A layer. Also known as a compatibility mode. A layer is a collection of shims and
  440. flags. Shims and flags when they appear in a layer can have a different command lines
  441. and include-exclude paramteres than what they originallyy have. Note that flags do
  442. not have include-exclude parameters. That is why SHIM_FIX_LIST has a strCommandLine
  443. and a strlInExclude and FLAG_FIX_LIST has a strCommandLine
  444. --*/
  445. typedef struct tagLAYER_FIX : public DS_TYPE {
  446. struct tagLAYER_FIX* pNext; // The next layer
  447. CSTRING strName; // The name of the layer
  448. PSHIM_FIX_LIST pShimFixList; // List of shims for this layer
  449. PFLAG_FIX_LIST pFlagFixList; // List of flags for this layer
  450. BOOL bCustom; // Is this a custom layer (created in a custom database), or does it live in the system database
  451. UINT uShimCount; // Number of shims and flags in this layer
  452. tagLAYER_FIX(BOOL bCustomType)
  453. {
  454. pFlagFixList = NULL;
  455. pNext = NULL;
  456. pShimFixList = NULL;
  457. type = FIX_LAYER;
  458. bCustom = bCustomType;
  459. uShimCount = 0;
  460. }
  461. tagLAYER_FIX& operator = (tagLAYER_FIX& temp)
  462. {
  463. //
  464. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  465. // CAUTION: DO NOT MODIFY THE pNext MEMBER.
  466. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  467. //
  468. strName = temp.strName;
  469. //
  470. // First copy the flags
  471. //
  472. DeleteFlagFixList(pFlagFixList);
  473. pFlagFixList = NULL;
  474. DeleteShimFixList(pShimFixList);
  475. pShimFixList = NULL;
  476. PFLAG_FIX_LIST pfl = temp.pFlagFixList;
  477. while (pfl) {
  478. PFLAG_FIX_LIST pflNew = new FLAG_FIX_LIST;
  479. if (pflNew == NULL) {
  480. MEM_ERR;
  481. return *this;
  482. }
  483. pflNew->pFlagFix = pfl->pFlagFix;
  484. pflNew->strCommandLine = pfl->strCommandLine;
  485. pflNew->pNext = pFlagFixList;
  486. pFlagFixList = pflNew;
  487. pfl = pfl->pNext;
  488. }
  489. //
  490. // Now copy the shims
  491. //
  492. PSHIM_FIX_LIST psfl = temp.pShimFixList;
  493. while (psfl) {
  494. PSHIM_FIX_LIST pNew = new SHIM_FIX_LIST;
  495. if (pNew == NULL) {
  496. MEM_ERR;
  497. return *this;
  498. }
  499. pNew->pShimFix = psfl->pShimFix;
  500. pNew->strCommandLine = psfl->strCommandLine;
  501. pNew->strlInExclude = psfl->strlInExclude;
  502. if (psfl->pLuaData) {
  503. pNew->pLuaData = new LUADATA;
  504. if (pNew->pLuaData) {
  505. pNew->pLuaData->Copy(psfl->pLuaData);
  506. } else {
  507. MEM_ERR;
  508. }
  509. }
  510. pNew->pNext = pShimFixList;
  511. pShimFixList = pNew;
  512. psfl = psfl->pNext;
  513. }
  514. return *this;
  515. }
  516. } LAYER_FIX, *PLAYER_FIX;
  517. /*++
  518. Contains a pointer to a layer and a pointer to a tagLAYER_FIX_LIST
  519. --*/
  520. typedef struct tagLAYER_FIX_LIST : public DS_TYPE {
  521. struct tagLAYER_FIX_LIST* pNext; // The next tagLAYER_FIX_LIST
  522. PLAYER_FIX pLayerFix; // The layer to which this tagLAYER_FIX_LIST points
  523. tagLAYER_FIX_LIST()
  524. {
  525. pLayerFix = NULL;
  526. pNext = NULL;
  527. type = FIX_LIST_LAYER;
  528. }
  529. } LAYER_FIX_LIST, *PLAYER_FIX_LIST;
  530. /*++
  531. A compatibility patch
  532. --*/
  533. typedef struct tagPATCH_FIX : public DS_TYPE {
  534. struct tagPATCH_FIX* pNext; // The next patch
  535. CSTRING strName; // Name of this patch
  536. CSTRING strDescription; // Description for this patch
  537. tagPATCH_FIX()
  538. {
  539. pNext = NULL;
  540. type = FIX_PATCH;
  541. }
  542. } PATCH_FIX, *PPATCH_FIX;
  543. /*++
  544. Contains a pointer to a patch and a pointer to a tagPATCH_FIX_LIST
  545. --*/
  546. typedef struct tagPATCH_FIX_LIST : public DS_TYPE {
  547. struct tagPATCH_FIX_LIST* pNext;
  548. PPATCH_FIX pPatchFix;
  549. tagPATCH_FIX_LIST()
  550. {
  551. pNext = NULL;
  552. pPatchFix = NULL;
  553. type = FIX_LIST_PATCH;
  554. }
  555. } PATCH_FIX_LIST, *PPATCH_FIX_LIST;
  556. /*++
  557. NOTE: The same APPHELP strcuture is used by the apphelp in the Library and the one in the
  558. DBENTRY. This structure represents the union of the fields used at these two different
  559. places.
  560. Before the comments you will see E, D, B.
  561. E: Used when in the context of an entry
  562. D: Used when in the context of a database
  563. B: Applicable to both
  564. --*/
  565. typedef struct tagAPPHELP : public DS_TYPE {
  566. union{
  567. struct tagAPPHELP *pNext; // D: Pointer to the next apphelp message in the database
  568. struct tagAPPHELP *pAppHelpinLib; // E: Pointer to the apphelp message in the database for this entry
  569. };
  570. BOOL bPresent; // E: Is the entry apphelped. If this is false, all other fields have invalid value
  571. SEVERITY severity; // E: The severity
  572. CSTRING strMsgName; // D: The name of the message
  573. CSTRING strMessage; // D: The text for the apphelp message
  574. CSTRING strURL; // D: The URL for this apphelp message
  575. UINT HTMLHELPID; // B: The id for this message
  576. BOOL bBlock; // E: Whether no block or hard block. This is determined by the type of severity
  577. tagAPPHELP()
  578. {
  579. type = TYPE_APPHELP_ENTRY;
  580. }
  581. } APPHELP, *PAPPHELP;
  582. /*++
  583. Extended ATTRINFO so that we can use CSTRING
  584. --*/
  585. typedef struct tagATTRINFO_NEW : public ATTRINFO
  586. {
  587. CSTRING strValue;
  588. tagATTRINFO_NEW()
  589. {
  590. this->dwFlags = 0;
  591. this->ullAttr = 0;
  592. }
  593. } ATTRINFO_NEW, *PATTRINFO_NEW;
  594. /*++
  595. Array of PATTRINFO_NEW. Each matching file has a set of attributes and this is
  596. specified by this data structure
  597. --*/
  598. typedef struct tagATTRIBUTE_LIST
  599. {
  600. PATTRINFO_NEW pAttribute;
  601. tagATTRIBUTE_LIST()
  602. {
  603. pAttribute = new ATTRINFO_NEW[ATTRIBUTE_COUNT];
  604. if (pAttribute == NULL) {
  605. MEM_ERR;
  606. return;
  607. }
  608. ZeroMemory(pAttribute, sizeof (ATTRINFO_NEW) * ATTRIBUTE_COUNT);
  609. }
  610. tagATTRIBUTE_LIST& operator =(tagATTRIBUTE_LIST& SecondList)
  611. {
  612. PATTRINFO_NEW pSecondList = SecondList.pAttribute;
  613. for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
  614. pAttribute[dwIndex].tAttrID = pSecondList[dwIndex].tAttrID;
  615. pAttribute[dwIndex].dwFlags = pSecondList[dwIndex].dwFlags;
  616. pAttribute[dwIndex].ullAttr = pSecondList[dwIndex].ullAttr;
  617. if (GETTAGTYPE(pAttribute[dwIndex].tAttrID) == TAG_TYPE_STRINGREF
  618. && (pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE)) {
  619. if (pSecondList[dwIndex].lpAttr) {
  620. pAttribute[dwIndex].strValue = pSecondList[dwIndex].lpAttr;
  621. pAttribute[dwIndex].lpAttr = pAttribute[dwIndex].strValue.pszString;
  622. }
  623. }
  624. }
  625. return *this;
  626. }
  627. tagATTRIBUTE_LIST& operator =(PATTRINFO pSecondList)
  628. {
  629. for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
  630. pAttribute[dwIndex].tAttrID = pSecondList[dwIndex].tAttrID;
  631. pAttribute[dwIndex].dwFlags = pSecondList[dwIndex].dwFlags;
  632. pAttribute[dwIndex].ullAttr = pSecondList[dwIndex].ullAttr;
  633. if (GETTAGTYPE(pAttribute[dwIndex].tAttrID) == TAG_TYPE_STRINGREF
  634. && (pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE)) {
  635. if (pSecondList[dwIndex].lpAttr) {
  636. pAttribute[dwIndex].strValue = pSecondList[dwIndex].lpAttr;
  637. pAttribute[dwIndex].lpAttr = pAttribute[dwIndex].strValue.pszString;
  638. }
  639. }
  640. }
  641. return *this;
  642. }
  643. ~tagATTRIBUTE_LIST()
  644. {
  645. if (pAttribute) {
  646. delete[] pAttribute;
  647. }
  648. pAttribute = NULL;
  649. }
  650. } ATTRIBUTELIST, *PATTRIBUTELIST;
  651. int
  652. TagToIndex(
  653. IN TAG tag
  654. );
  655. /*++
  656. A matching file. Each entry can contain a list of matching files that are used
  657. to uniquely identify this entry
  658. --*/
  659. typedef struct tagMATCHINGFILE : public DS_TYPE {
  660. struct tagMATCHINGFILE* pNext; // The next matching file
  661. DWORD dwMask; // Which attributes have been selected to be used.
  662. CSTRING strMatchName; // The name of the matching file. * means the file being fixed. Otherwise it will be only the file name and not the complete path.
  663. CSTRING strFullName; // The full name if available.
  664. ATTRIBUTELIST attributeList; // The attribute list for the matching file. The dwMask will determine which one of them are actually used
  665. tagMATCHINGFILE()
  666. {
  667. pNext = NULL;
  668. type = TYPE_MATCHING_FILE;
  669. dwMask = DEFAULT_MASK;
  670. }
  671. BOOL operator == (struct tagMATCHINGFILE &val)
  672. /*++
  673. Desc:
  674. Two matching files are said to be similar if there does not any exist any attribute
  675. that has different values in these two matching files
  676. --*/
  677. {
  678. BOOL bEqual = TRUE;
  679. if (strMatchName != val.strMatchName) {
  680. return FALSE;
  681. }
  682. for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
  683. int iPos = TagToIndex(attributeList.pAttribute[dwIndex].tAttrID);
  684. if (iPos == -1) {
  685. continue;
  686. }
  687. //
  688. // Do both the files use these attributes ?
  689. //
  690. if ((dwMask & (1 << (iPos + 1)))
  691. && (val.dwMask & (1 << (iPos + 1)))
  692. && attributeList.pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE
  693. && val.attributeList.pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE) {
  694. //
  695. // Both of them use this attribute
  696. //
  697. switch (GETTAGTYPE(attributeList.pAttribute[dwIndex].tAttrID)) {
  698. case TAG_TYPE_DWORD:
  699. bEqual = (attributeList.pAttribute[dwIndex].dwAttr == val.attributeList.pAttribute[dwIndex].dwAttr);
  700. break;
  701. case TAG_TYPE_QWORD:
  702. bEqual = (attributeList.pAttribute[dwIndex].ullAttr == val.attributeList.pAttribute[dwIndex].ullAttr);
  703. break;
  704. case TAG_TYPE_STRINGREF:
  705. bEqual = (lstrcmpi(attributeList.pAttribute[dwIndex].lpAttr,
  706. val.attributeList.pAttribute[dwIndex].lpAttr) == 0);
  707. break;
  708. }
  709. if (bEqual == FALSE) {
  710. return FALSE;
  711. }
  712. }
  713. }
  714. //
  715. // everything matches.
  716. //
  717. return TRUE;
  718. }
  719. } MATCHINGFILE, *PMATCHINGFILE;
  720. void
  721. DeletePatchFixList(
  722. PPATCH_FIX_LIST pPat
  723. );
  724. void
  725. DeleteLayerFixList(
  726. PLAYER_FIX_LIST pll
  727. );
  728. void
  729. DeleteFlagFixList(
  730. PFLAG_FIX_LIST pfl
  731. );
  732. void
  733. DeleteMatchingFiles(
  734. PMATCHINGFILE pMatch
  735. );
  736. /*++
  737. Data strcuture to represent a fixed program
  738. We keep the data structure in this way:
  739. There is a linked list of applications. An application is a DBENTRY. Each
  740. application contains a pointer to the next application as well (through
  741. pNext) as a pointer to a DBENTRY that has the same strAppName (through
  742. pSameAppExe). This second DBENTRY is now called as an entry in this application
  743. and will contain a pointer to the next entry. So we have effectively a linked
  744. list of linked lists. So an application is the first member of a linked list B.
  745. All such linked lists of type B are linked together (through pNext)to create a
  746. linked list A which is the linked list of applications
  747. --*/
  748. typedef struct tagDBENTRY : public DS_TYPE {
  749. struct tagDBENTRY* pNext; // Pointer to the next application, in case this entry is an application
  750. struct tagDBENTRY* pSameAppExe; // Pointer to the next entry for this application.
  751. TAGID tiExe; // TAGID for the entry as in the database
  752. CSTRING strExeName; // The name of the exe being fixed. This will be file name only
  753. CSTRING strFullpath; // Full path, if available
  754. CSTRING strAppName; // Application name
  755. CSTRING strVendor; // Vendor name, can be NULL
  756. TCHAR szGUID[128]; // GUID for this entry
  757. PSHIM_FIX_LIST pFirstShim; // The list of shims that have been applied to this entry
  758. PPATCH_FIX_LIST pFirstPatch; // The list of patches that have been applied to this entry
  759. PLAYER_FIX_LIST pFirstLayer; // The list of layers that have been applied to this entry
  760. PFLAG_FIX_LIST pFirstFlag; // The list of flags that have been applied to this entry
  761. APPHELP appHelp; // Apphelp information for this entry
  762. PMATCHINGFILE pFirstMatchingFile; // The first matching file for this entry
  763. int nMatchingFiles; // Number of matching files for this entry
  764. BOOL bDisablePerUser; // Not used at the moment. Is this fix entry disabled for the present user?
  765. BOOL bDisablePerMachine; // Is this fix entry disabled on this machine
  766. HTREEITEM hItemExe; // HITEM for the exe as in the entry tree
  767. tagDBENTRY()
  768. {
  769. tiExe = TAGID_NULL;
  770. pFirstFlag = NULL;
  771. pFirstLayer = NULL;
  772. pFirstMatchingFile = NULL;
  773. pFirstPatch = NULL;
  774. pFirstShim = NULL;
  775. pNext = NULL;
  776. pSameAppExe = NULL;
  777. *szGUID = 0;
  778. appHelp.bPresent = FALSE;
  779. appHelp.pAppHelpinLib = NULL;
  780. appHelp.severity = APPTYPE_NONE;
  781. type = TYPE_ENTRY;
  782. hItemExe = NULL;
  783. bDisablePerMachine = FALSE;
  784. bDisablePerUser = FALSE;
  785. nMatchingFiles = 0;
  786. }
  787. ~tagDBENTRY()
  788. {
  789. Delete();
  790. }
  791. void
  792. Delete()
  793. {
  794. DeleteFlagFixList(pFirstFlag);
  795. pFirstFlag = NULL;
  796. DeleteLayerFixList(pFirstLayer);
  797. pFirstLayer = NULL;
  798. DeleteMatchingFiles(pFirstMatchingFile);
  799. pFirstMatchingFile = NULL;
  800. DeleteShimFixList(pFirstShim);
  801. pFirstShim = NULL;
  802. DeletePatchFixList(pFirstPatch);
  803. pFirstPatch = NULL;
  804. }
  805. struct tagDBENTRY& operator = (struct tagDBENTRY& temp)
  806. {
  807. Delete();
  808. //
  809. //********************************************************************************
  810. // Note that we are assuming that both the entries are in the same database.
  811. // So we do not move the layers and the apphelp, because they actually belong to the
  812. // database. If we want to assign one DBENTRY to a DBENTRY in a different database
  813. // we will have to copy the apphelp from one database to another and set the pointes
  814. // of the apphelp in the entry correctly.
  815. // Also we will need to copy any custom layers and set the pointers correctly.
  816. //********************************************************************************
  817. //
  818. appHelp = temp.appHelp;
  819. bDisablePerMachine = temp.bDisablePerMachine;
  820. bDisablePerUser = temp.bDisablePerUser;
  821. nMatchingFiles = temp.nMatchingFiles;
  822. //
  823. // Copy flag list
  824. //
  825. PFLAG_FIX_LIST pffl = temp.pFirstFlag;
  826. while (pffl) {
  827. PFLAG_FIX_LIST pfflNew = new FLAG_FIX_LIST;
  828. if (pfflNew == NULL) {
  829. MEM_ERR;
  830. return *this;
  831. }
  832. pfflNew->pFlagFix = pffl->pFlagFix;
  833. pfflNew->strCommandLine = pffl->strCommandLine;
  834. pfflNew->pNext = pFirstFlag;
  835. pFirstFlag = pfflNew;
  836. pffl = pffl->pNext;
  837. }
  838. //
  839. // Copy the layers list
  840. //
  841. PLAYER_FIX_LIST plfl = temp.pFirstLayer;
  842. while (plfl) {
  843. PLAYER_FIX_LIST pNew = new LAYER_FIX_LIST;
  844. if (pNew == NULL) {
  845. MEM_ERR;
  846. return *this;
  847. }
  848. assert(plfl->pLayerFix);
  849. pNew->pLayerFix = plfl->pLayerFix;
  850. assert(pNew->pLayerFix);
  851. pNew->pNext = pFirstLayer;
  852. pFirstLayer = pNew;
  853. plfl = plfl->pNext;
  854. }
  855. //
  856. // Copy the matching files
  857. //
  858. PMATCHINGFILE pMatch = temp.pFirstMatchingFile;
  859. while (pMatch) {
  860. PMATCHINGFILE pNew = new MATCHINGFILE;
  861. if (pNew == NULL) {
  862. MEM_ERR;
  863. return *this;
  864. }
  865. pNew->strMatchName = pMatch->strMatchName;
  866. pNew->strFullName = pMatch->strFullName;
  867. pNew->dwMask = pMatch->dwMask;
  868. pNew->attributeList = pMatch->attributeList;
  869. pNew->pNext = pFirstMatchingFile;
  870. pFirstMatchingFile= pNew;
  871. pMatch = pMatch->pNext;
  872. }
  873. //
  874. // Copy the patches
  875. //
  876. PPATCH_FIX_LIST ppfl = temp.pFirstPatch;
  877. while (ppfl) {
  878. PPATCH_FIX_LIST pNew = new PATCH_FIX_LIST;
  879. if (pNew == NULL) {
  880. MEM_ERR;
  881. return *this;
  882. }
  883. pNew->pPatchFix = ppfl->pPatchFix;
  884. pNew->pNext = pFirstPatch;
  885. pFirstPatch = pNew;
  886. ppfl = ppfl->pNext;
  887. }
  888. //
  889. // Copy the shims
  890. //
  891. PSHIM_FIX_LIST psfl = temp.pFirstShim;
  892. while (psfl) {
  893. PSHIM_FIX_LIST pNew = new SHIM_FIX_LIST;
  894. pNew->pShimFix = psfl->pShimFix;
  895. pNew->strCommandLine = psfl->strCommandLine;
  896. pNew->strlInExclude = psfl->strlInExclude;
  897. if (psfl->pLuaData) {
  898. pNew->pLuaData = new LUADATA;
  899. pNew->pLuaData->Copy(* (psfl->pLuaData));
  900. }
  901. pNew->pNext = pFirstShim;
  902. pFirstShim = pNew;
  903. psfl = psfl->pNext;
  904. }
  905. strAppName = temp.strAppName;
  906. strExeName = temp.strExeName;
  907. strFullpath = temp.strFullpath;
  908. strVendor = temp.strVendor;
  909. SafeCpyN(szGUID, temp.szGUID, ARRAYSIZE(szGUID));
  910. return *this;
  911. }
  912. } DBENTRY, *PDBENTRY;
  913. void
  914. GetNextSDBFileName(
  915. CSTRING &strFileName,
  916. CSTRING &strDBName
  917. );
  918. LPTSTR
  919. GetString(
  920. UINT iResource,
  921. TCHAR* szStr = NULL,
  922. int nLength = 0
  923. );
  924. /*++
  925. A data base
  926. --*/
  927. typedef struct DataBase : public DS_TYPE {
  928. struct DataBase* pNext; // The next database. (If this is a part of a list)
  929. CSTRING strName; // The name of this database
  930. CSTRING strPath; // The complete path for this database
  931. TCHAR szGUID[128]; // The GUID for this database
  932. PDBENTRY pEntries; // Pointer to the first DBENTRY for this database
  933. BOOL bChanged; // Has it changed since it was opened?
  934. BOOL bReadOnly; // Is this a read-only database?
  935. PLAYER_FIX pLayerFixes; // Pointer to the first layer
  936. PSHIM_FIX pShimFixes; // Pointer to the first shim. Note that only the system database can have shims
  937. PPATCH_FIX pPatchFixes; // Pointer to the first patch. Note that only the system database can have patches
  938. PFLAG_FIX pFlagFixes; // Pointer to the first flag. Note that only the system database can have flags
  939. PAPPHELP pAppHelp; // Pointer to the first apphelp message in the database. Valid only for custom databases
  940. HTREEITEM hItemDB; // HTREEITEM for this database in the db tree
  941. HTREEITEM hItemAllApps; // HTREEITEM for the "Applications" child tree item
  942. HTREEITEM hItemAllLayers; // HTREEITEM for the "Compatibility Modes" child tree item
  943. DWORD m_nMAXHELPID; // This is the id of the message with the highest ID. Initially this is 0. Note that IDs start from 1 and not 0.
  944. UINT uAppCount; // Number of applications in this database
  945. UINT uLayerCount; // Number of layers in this database
  946. UINT uShimCount; // Number of shims and flags in this database
  947. DataBase(TYPE typeDB)
  948. {
  949. Init(typeDB);
  950. }
  951. void
  952. Init(TYPE typeDB)
  953. {
  954. type = typeDB;
  955. pEntries = NULL;
  956. pNext = NULL;
  957. pFlagFixes = NULL;
  958. pLayerFixes = NULL;
  959. pPatchFixes = NULL;
  960. pShimFixes = NULL;
  961. pAppHelp = NULL;
  962. uAppCount = 0;
  963. uLayerCount = 0;
  964. uShimCount = 0;
  965. *szGUID = 0;
  966. bChanged = FALSE;
  967. if (typeDB == DATABASE_TYPE_INSTALLED) {
  968. bReadOnly = TRUE;
  969. } else {
  970. bReadOnly = FALSE;
  971. }
  972. if (type == DATABASE_TYPE_WORKING) {
  973. GetNextSDBFileName(strPath, strName);
  974. } else if (type == DATABASE_TYPE_GLOBAL) {
  975. TCHAR szShimDB[MAX_PATH * 2];
  976. UINT uResult = 0;
  977. *szShimDB = 0;
  978. uResult = GetSystemWindowsDirectory(szShimDB, MAX_PATH);
  979. if (uResult > 0 && uResult < MAX_PATH) {
  980. ADD_PATH_SEPARATOR(szShimDB, ARRAYSIZE(szShimDB));
  981. StringCchCat(szShimDB, ARRAYSIZE(szShimDB), TEXT("AppPatch\\sysmain.sdb"));
  982. strName = GetString(IDS_CAPTION3);
  983. } else {
  984. assert(FALSE);
  985. }
  986. strPath = szShimDB;
  987. //
  988. // {11111111-1111-1111-1111-111111111111} is the GUID for the sysmain.sdb in XP
  989. // but not on win2k
  990. //
  991. SafeCpyN(szGUID, _T("{11111111-1111-1111-1111-111111111111}"), ARRAYSIZE(szGUID));
  992. }
  993. hItemDB = NULL;
  994. hItemAllApps = NULL;
  995. hItemAllLayers = NULL;
  996. m_nMAXHELPID = 0;
  997. }
  998. } DATABASE, *PDATABASE;
  999. void
  1000. CleanupDbSupport(
  1001. PDATABASE pDataBase
  1002. );
  1003. void
  1004. ValidateClipBoard(
  1005. PDATABASE pDataBase,
  1006. LPVOID pElementTobeDeleted // Should be a PDBENTRY or a PLAYER_FIX
  1007. );
  1008. /*++
  1009. Linked list of databases
  1010. --*/
  1011. typedef struct tagDataBaseList {
  1012. PDATABASE pDataBaseHead; // The first database in the list
  1013. tagDataBaseList()
  1014. {
  1015. pDataBaseHead = NULL;
  1016. }
  1017. void
  1018. Add(
  1019. PDATABASE pDataBaseNew
  1020. )
  1021. {
  1022. if (pDataBaseNew == NULL) {
  1023. return;
  1024. }
  1025. pDataBaseNew->pNext = pDataBaseHead;
  1026. pDataBaseHead = pDataBaseNew;
  1027. }
  1028. BOOL
  1029. Remove(
  1030. PDATABASE pDataBaseToRemove
  1031. )
  1032. {
  1033. PDATABASE pPrev = NULL;
  1034. for (PDATABASE pTemp = pDataBaseHead; pTemp; pPrev = pTemp, pTemp = pTemp->pNext){
  1035. if (pTemp == pDataBaseToRemove) {
  1036. if (pPrev == NULL) {
  1037. //First Entry
  1038. pDataBaseHead = pTemp->pNext;
  1039. } else {
  1040. pPrev->pNext = pTemp->pNext;
  1041. }
  1042. //
  1043. // Remove any entries for this database that might be in our CLIPBOARD
  1044. //
  1045. ValidateClipBoard(pDataBaseToRemove, NULL);
  1046. CleanupDbSupport(pTemp);
  1047. delete pTemp;
  1048. break;
  1049. }
  1050. }
  1051. if (pTemp == NULL){
  1052. return FALSE;
  1053. }
  1054. return TRUE;
  1055. }
  1056. void
  1057. RemoveAll()
  1058. {
  1059. PDATABASE pDBNext = NULL;
  1060. while (pDataBaseHead) {
  1061. pDBNext = pDataBaseHead->pNext;
  1062. //
  1063. // Remove any entries for this database that might be in our CLIPBOARD
  1064. //
  1065. ValidateClipBoard(pDataBaseHead, NULL);
  1066. CleanupDbSupport(pDataBaseHead);
  1067. delete pDataBaseHead;
  1068. pDataBaseHead = pDBNext;
  1069. }
  1070. }
  1071. PDATABASE
  1072. FindDB(
  1073. IN PDATABASE pDatabase
  1074. )
  1075. {
  1076. PDATABASE pDatabaseIndex = pDataBaseHead;
  1077. while (pDatabaseIndex) {
  1078. if (pDatabaseIndex == pDatabase) {
  1079. break;
  1080. }
  1081. pDatabaseIndex = pDatabaseIndex->pNext;
  1082. }
  1083. return pDatabaseIndex;
  1084. }
  1085. PDATABASE
  1086. FindDBByGuid(
  1087. IN PCTSTR pszGuid
  1088. )
  1089. {
  1090. PDATABASE pDatabaseIndex = pDataBaseHead;
  1091. while (pDatabaseIndex) {
  1092. if (lstrcmp(pDatabaseIndex->szGUID, pszGuid) == 0) {
  1093. break;
  1094. }
  1095. pDatabaseIndex = pDatabaseIndex->pNext;
  1096. }
  1097. return pDatabaseIndex;
  1098. }
  1099. }DATABASELIST, * PDATABASELIST;
  1100. /*++
  1101. Item in our clip-board data structure are of this type
  1102. --*/
  1103. typedef struct tagCopyStruct{
  1104. BOOL bRemoveEntry; // Should the entry be actually removed. Not used as yet
  1105. LPVOID lpData; // The pointer to the data structure that has been copied/cut
  1106. HTREEITEM hItem; // The tree item for the above
  1107. tagCopyStruct* pNext;
  1108. tagCopyStruct()
  1109. {
  1110. hItem = NULL;
  1111. bRemoveEntry = FALSE;
  1112. }
  1113. } CopyStruct;
  1114. /*++
  1115. Our clipboard data structure
  1116. --*/
  1117. typedef struct _tagClipBoard {
  1118. PDATABASE pDataBase; // The database from where we did some cut-copy. This will be the active database when we did cut or copy
  1119. TYPE type; // The type of the data structure that was copied or cut. There can be more than on item and all of them will be of the same type
  1120. SOURCE_TYPE SourceType; // Either of LIB_TREE, ENTRY_TREE, ENTRY_LIST.
  1121. CopyStruct* pClipBoardHead; // The pointer to the first element in the clipboard
  1122. _tagClipBoard()
  1123. {
  1124. pClipBoardHead = NULL;
  1125. }
  1126. void
  1127. Add(CopyStruct* pNew)
  1128. {
  1129. pNew->pNext = pClipBoardHead;
  1130. pClipBoardHead = pNew;
  1131. }
  1132. void
  1133. RemoveAll()
  1134. {
  1135. CopyStruct* pTemp = NULL;
  1136. while (pClipBoardHead) {
  1137. pTemp = pClipBoardHead->pNext;
  1138. delete pClipBoardHead;
  1139. pClipBoardHead = pTemp;
  1140. }
  1141. }
  1142. BOOL
  1143. CheckAndRemove(LPVOID lpData)
  1144. {
  1145. /*++
  1146. Return:
  1147. TRUE if the param was found in the clipboard.
  1148. FALSE otherwise
  1149. --*/
  1150. CopyStruct* pTemp = pClipBoardHead;
  1151. CopyStruct* pPrev = NULL;
  1152. while (pTemp) {
  1153. if (pTemp->lpData == lpData) {
  1154. if (pPrev == NULL) {
  1155. pClipBoardHead = pTemp->pNext;
  1156. } else {
  1157. pPrev->pNext = pTemp->pNext;
  1158. }
  1159. delete pTemp;
  1160. return TRUE;
  1161. }
  1162. pPrev = pTemp;
  1163. pTemp = pTemp->pNext;
  1164. }
  1165. return FALSE;
  1166. }
  1167. } CLIPBOARD;
  1168. //
  1169. // Used for sorting of columns in some list view
  1170. //
  1171. typedef struct _tagColSort
  1172. {
  1173. HWND hwndList; // The handle to the list view, in which we want to perform the sort
  1174. INT iCol; // The column that we want to do the sort on
  1175. LONG lSortColMask; // The mask that specifies what columns are sorted in what manner, so that we can toggle the sorting
  1176. } COLSORT;
  1177. TYPE
  1178. ConvertLparam2Type(
  1179. LPARAM lParam
  1180. );
  1181. TYPE
  1182. ConvertLpVoid2Type(
  1183. LPVOID lpVoid
  1184. );
  1185. TYPE
  1186. GetItemType(
  1187. HWND hwndTree,
  1188. HTREEITEM hItem
  1189. );
  1190. BOOL
  1191. RemoveLayer(
  1192. PDATABASE pDataBase,
  1193. PLAYER_FIX pLayerToRemove,
  1194. HTREEITEM* pHItem
  1195. );
  1196. void
  1197. DoTheCut(
  1198. PDATABASE pDataBase,
  1199. TYPE type,
  1200. SOURCE_TYPE SourceType,
  1201. LPVOID lpData, // To be removed
  1202. HTREEITEM hItem,
  1203. BOOL bDelete
  1204. );
  1205. BOOL
  1206. RemoveApp(
  1207. PDATABASE pDataBase,
  1208. PDBENTRY pApp
  1209. );
  1210. void
  1211. RemoveAllApps(
  1212. PDATABASE pDataBase
  1213. );
  1214. void
  1215. RemoveAllLayers(
  1216. PDATABASE pDataBase
  1217. );
  1218. DWORD
  1219. WIN_MSG(
  1220. void
  1221. );
  1222. BOOL
  1223. CheckForSDB(
  1224. void
  1225. );
  1226. BOOL
  1227. PasteMultipleLayers(
  1228. PDATABASE pDataBaseTo
  1229. );
  1230. BOOL
  1231. PasteShimsFlags(
  1232. PDATABASE pDataBaseTo
  1233. );
  1234. BOOL
  1235. PasteMultipleApps(
  1236. PDATABASE pDataBaseTo
  1237. );
  1238. void
  1239. ListViewSelectAll(
  1240. HWND hwndList
  1241. );
  1242. void
  1243. ListViewInvertSelection(
  1244. HWND hwndList
  1245. );
  1246. BOOL
  1247. DeleteMatchingFile(
  1248. PMATCHINGFILE* ppMatchFirst,
  1249. PMATCHINGFILE pMatchToDelete,
  1250. HWND hwndTree,
  1251. HTREEITEM hItem
  1252. );
  1253. BOOL
  1254. CheckInstalled(
  1255. PCTSTR szPath,
  1256. PCTSTR szGUID
  1257. );
  1258. void
  1259. SetStatus(
  1260. PCTSTR pszMessage
  1261. );
  1262. void
  1263. SetStatus(
  1264. INT iCode
  1265. );
  1266. void
  1267. SetStatusStringDBTree(
  1268. HTREEITEM hItem
  1269. );
  1270. void
  1271. SetStatusStringEntryTree(
  1272. HTREEITEM hItem
  1273. );
  1274. void
  1275. GetDescriptionString(
  1276. LPARAM lParam,
  1277. CSTRING& strDesc,
  1278. HWND hwndToolTip,
  1279. PCTSTR pszCaption = NULL,
  1280. HTREEITEM hItem = NULL,
  1281. HWND hwnd = NULL,
  1282. INT iIndexListView = -1
  1283. );
  1284. BOOL
  1285. SaveDisplaySettings(
  1286. void
  1287. );
  1288. UINT
  1289. GetAppEntryCount(
  1290. PDBENTRY pEntry
  1291. );
  1292. void
  1293. AddToMRU(
  1294. CSTRING& strPath
  1295. );
  1296. TCHAR*
  1297. FormatMRUString(
  1298. PCTSTR pszPath,
  1299. INT iIndex,
  1300. PTSTR szRetPath,
  1301. UINT cchRetPath
  1302. );
  1303. void
  1304. RefreshMRUMenu(
  1305. void
  1306. );
  1307. BOOL
  1308. LoadDataBase(
  1309. TCHAR* szPath
  1310. );
  1311. INT
  1312. GetLayerCount(
  1313. LPARAM lp,
  1314. TYPE type
  1315. );
  1316. INT
  1317. GetPatchCount(
  1318. LPARAM lp,
  1319. TYPE type
  1320. );
  1321. BOOL
  1322. GetFileContents(
  1323. PCTSTR pszFileName,
  1324. PWSTR* ppwszFileContents
  1325. );
  1326. INT
  1327. GetShimFlagCount(
  1328. LPARAM lp,
  1329. TYPE type
  1330. );
  1331. INT
  1332. GetMatchCount(
  1333. PDBENTRY pEntry
  1334. );
  1335. LPWSTR
  1336. GetNextLine(
  1337. LPWSTR pwszBuffer
  1338. );
  1339. INT
  1340. Atoi(
  1341. PCTSTR pszStr,
  1342. BOOL* bValid
  1343. );
  1344. BOOL
  1345. CheckIfInstalledDB(
  1346. PCTSTR szGuid
  1347. );
  1348. BOOL
  1349. CheckIfContains(
  1350. PCTSTR pszString,
  1351. PTSTR pszMatch
  1352. );
  1353. INT
  1354. ShowMainEntries(
  1355. HWND hdlg
  1356. );
  1357. INT_PTR
  1358. CALLBACK
  1359. HandleConflictEntry(
  1360. HWND hdlg,
  1361. UINT uMsg,
  1362. WPARAM wParam,
  1363. LPARAM lParam
  1364. );
  1365. BOOL
  1366. IsUnique(
  1367. PDATABASE pDatabase,
  1368. PCTSTR szName,
  1369. UINT uType
  1370. );
  1371. PTSTR
  1372. GetUniqueName(
  1373. PDATABASE pDatabase,
  1374. PCTSTR szExistingName,
  1375. PTSTR szBuffer,
  1376. INT cchBuffer,
  1377. TYPE type
  1378. );
  1379. BOOL
  1380. NotCompletePath(
  1381. PCTSTR pszFileName
  1382. );
  1383. void
  1384. TreeDeleteAll(
  1385. HWND hwndTree
  1386. );
  1387. void
  1388. AddSingleEntry(
  1389. HWND hwndTree,
  1390. PDBENTRY pEntry
  1391. );
  1392. BOOL
  1393. FormatDate(
  1394. PSYSTEMTIME pSysTime,
  1395. TCHAR* szDate,
  1396. UINT cchDate
  1397. );
  1398. void
  1399. TrimLeadingSpaces(
  1400. LPCWSTR& pwsz
  1401. );
  1402. void
  1403. TrimTrailingSpaces(
  1404. LPWSTR pwsz
  1405. );
  1406. LPWSTR GetNextToken(
  1407. LPWSTR pwsz
  1408. );
  1409. PDBENTRY
  1410. GetAppForEntry(
  1411. PDATABASE pDatabase,
  1412. PDBENTRY pEntryToCheck
  1413. );
  1414. void
  1415. SetStatus(
  1416. HWND hwndStatus,
  1417. PCTSTR pszMessage
  1418. );
  1419. void
  1420. SetStatus(
  1421. HWND hwndStatus,
  1422. INT iCode
  1423. );
  1424. void
  1425. UpdateEntryTreeView(
  1426. PDBENTRY pEntry,
  1427. HWND hwndTree
  1428. );
  1429. void
  1430. GetDescription(
  1431. HWND hwndTree,
  1432. HTREEITEM hItem,
  1433. LPARAM itemlParam,
  1434. CSTRING& strDesc
  1435. );
  1436. BOOL
  1437. AppendEvent(
  1438. INT iType,
  1439. TCHAR* szTimestamp,
  1440. TCHAR* szMsg,
  1441. BOOL bAddToFile = FALSE
  1442. );
  1443. PSHIM_FIX_LIST
  1444. IsLUARedirectFSPresent(
  1445. PDBENTRY pEntry
  1446. );
  1447. BOOL
  1448. GetDbGuid(
  1449. OUT TCHAR* pszGuid,
  1450. IN INT cchpszGuid,
  1451. IN PDB pdb
  1452. );
  1453. BOOL
  1454. LookUpEntryProperties(
  1455. PDB pdb,
  1456. TAGID tiExe,
  1457. BOOL* pbLayers,
  1458. BOOL* pbShims,
  1459. BOOL* pbPatches,
  1460. BOOL* pbFlags,
  1461. BOOL* pbAppHelp,
  1462. CSTRING& strAppName
  1463. );
  1464. void
  1465. UpdateControls(
  1466. void
  1467. );
  1468. BOOL
  1469. ShimFlagExistsInLayer(
  1470. LPVOID lpData,
  1471. PLAYER_FIX plf,
  1472. TYPE type
  1473. );
  1474. BOOL
  1475. IsShimInlayer(
  1476. PLAYER_FIX plf,
  1477. PSHIM_FIX psf,
  1478. CSTRING* pstrCommandLine,
  1479. CSTRINGLIST* pstrlInEx
  1480. );
  1481. BOOL
  1482. IsFlagInlayer(
  1483. PLAYER_FIX plf,
  1484. PFLAG_FIX pff,
  1485. CSTRING* pstrCommandLine
  1486. );
  1487. int CALLBACK
  1488. CompareItemsEx(
  1489. LPARAM lParam1,
  1490. LPARAM lParam2,
  1491. LPARAM lParam
  1492. );
  1493. void
  1494. PreprocessForSaveAs(
  1495. PDATABASE pDatabase
  1496. );
  1497. BOOL
  1498. SaveListViewToFile(
  1499. HWND hwndList,
  1500. INT iCols,
  1501. PCTSTR pszFile,
  1502. PCTSTR pszHeader
  1503. );
  1504. BOOL
  1505. IsShimInEntry(
  1506. PCTSTR szShimName,
  1507. PDBENTRY pEntry
  1508. );
  1509. void
  1510. ShowShimLog(
  1511. void
  1512. );
  1513. BOOL
  1514. ReplaceChar(
  1515. PTSTR pszString,
  1516. TCHAR chCharToFind,
  1517. TCHAR chReplaceBy
  1518. );
  1519. int
  1520. CDECL
  1521. MSGF(
  1522. HWND hwndParent,
  1523. PCTSTR pszCaption,
  1524. UINT uType,
  1525. PCTSTR pszFormat,
  1526. ...
  1527. );
  1528. void
  1529. Dbg(DEBUGLEVEL debugLevel,
  1530. LPSTR pszFmt
  1531. ...);
  1532. BOOL
  1533. GetDatabaseEntries(
  1534. LPCTSTR szFullPath,
  1535. PDATABASE pDataBase
  1536. );
  1537. BOOL ReadMainDataBase();
  1538. BOOL SaveDataBase(
  1539. PDATABASE pDataBase,
  1540. CSTRING& strFileName);
  1541. LPVOID
  1542. FindFix(
  1543. PCTSTR pszFixName,
  1544. TYPE fixType,
  1545. PDATABASE pDataBase = NULL
  1546. );
  1547. BOOL
  1548. GetFileName(
  1549. HWND hWnd,
  1550. LPCTSTR szTitle,
  1551. LPCTSTR szFilter,
  1552. LPCTSTR szDefaultFile,
  1553. LPCTSTR szDefExt,
  1554. DWORD dwFlags,
  1555. BOOL bOpen,
  1556. CSTRING& szStr,
  1557. BOOL bDoNotVerifySDB = FALSE
  1558. );
  1559. BOOL
  1560. TestRun(
  1561. PDBENTRY pEntry,
  1562. CSTRING* pszFile,
  1563. CSTRING* pszCommandLine,
  1564. HWND hwndParent,
  1565. CSTRINGLIST* strlXML = NULL
  1566. );
  1567. UINT
  1568. LookupFileImage(
  1569. HIMAGELIST g_hImageList,
  1570. LPCTSTR szFilename,
  1571. UINT uDefault,
  1572. UINT* puArray,
  1573. UINT uArrayCount // No. of elements it can hold
  1574. );
  1575. BOOL
  1576. InvokeCompiler(
  1577. CSTRING& szInCommandLine
  1578. );
  1579. BOOL
  1580. GetXML(
  1581. PDBENTRY pEntry,
  1582. BOOL bComplete, // Save just this entry or all entries following this.
  1583. CSTRINGLIST* strlXML,
  1584. PDATABASE pDataBase
  1585. );
  1586. VOID
  1587. FormatVersion(
  1588. ULONGLONG ullBinVer,
  1589. PTSTR pszText,
  1590. INT chBuffSize
  1591. );
  1592. BOOL
  1593. SaveDataBaseAs(
  1594. PDATABASE pDataBase
  1595. );
  1596. BOOL
  1597. SetDisabledStatus(
  1598. HKEY hKeyRoot,
  1599. PCTSTR pszGuid,
  1600. BOOL bDisable
  1601. );
  1602. BOOL
  1603. RemoveEntry(
  1604. PDATABASE pDataBase,
  1605. PDBENTRY pEntryToRemove,
  1606. PDBENTRY pApp,
  1607. BOOL bRepaint = TRUE
  1608. );
  1609. void
  1610. SetCaption(
  1611. BOOL bIncludeDataBaseName = TRUE,
  1612. PDATABASE pDataBase = NULL,
  1613. BOOL bOnlyTreeItem = FALSE
  1614. );
  1615. void
  1616. InsertColumnIntoListView(
  1617. HWND hWnd,
  1618. LPTSTR lpszColumn,
  1619. INT iCol,
  1620. DWORD widthPercent
  1621. );
  1622. BOOL
  1623. InstallDatabase(
  1624. CSTRING& strPath,
  1625. PCTSTR szOptions,
  1626. BOOL bShowDialog
  1627. );
  1628. void
  1629. FlushCache(
  1630. void
  1631. );
  1632. BOOL
  1633. DeleteAppHelp(
  1634. PDATABASE pDatabase,
  1635. DWORD nHelpID
  1636. );
  1637. void
  1638. CenterWindow(
  1639. HWND hParent,
  1640. HWND hWnd
  1641. );
  1642. BOOL
  1643. CheckIfConflictingEntry(
  1644. PDATABASE pDataBase,
  1645. PDBENTRY pEntry,
  1646. PDBENTRY pEntryBeingEdited,
  1647. PDBENTRY* ppEntryFound = NULL,
  1648. PDBENTRY* ppAppFound = NULL
  1649. );
  1650. PDBENTRY
  1651. AddExeInApp(
  1652. PDBENTRY pEntry,
  1653. BOOL* pbNew,
  1654. PDATABASE pDataBase
  1655. );
  1656. BOOL
  1657. CloseDataBase(
  1658. PDATABASE pDataBase
  1659. );
  1660. BOOL
  1661. CheckAndSave(
  1662. PDATABASE pDataBase
  1663. );
  1664. void
  1665. EnableTabBackground(
  1666. HWND hDlg
  1667. );
  1668. void
  1669. TreeDeleteAll(
  1670. HWND hwndTree
  1671. );
  1672. BOOL
  1673. CloseAllDatabases(
  1674. void
  1675. );
  1676. INT_PTR
  1677. CALLBACK
  1678. HandlePromptLayer(
  1679. HWND hdlg,
  1680. UINT uMsg,
  1681. WPARAM wParam,
  1682. LPARAM lParam
  1683. );
  1684. INT_PTR
  1685. CALLBACK
  1686. HandleConflictAppLayer(
  1687. HWND hdlg,
  1688. UINT uMsg,
  1689. WPARAM wParam,
  1690. LPARAM lParam
  1691. );
  1692. BOOL
  1693. PasteSingleEntry(
  1694. PDBENTRY pEntryToPaste,
  1695. PDATABASE pDataBaseTo
  1696. );
  1697. BOOL
  1698. PasteAllApps(
  1699. PDATABASE pDataBaseTo
  1700. );
  1701. INT
  1702. PasteSingleApp(
  1703. PDBENTRY pApptoPaste,
  1704. PDATABASE pDataBaseTo,
  1705. PDATABASE pDataBaseFrom,
  1706. BOOL bAllExes,
  1707. PCTSTR szNewAppName = NULL
  1708. );
  1709. BOOL
  1710. PasteAllLayers(
  1711. PDATABASE pDataBaseTo
  1712. );
  1713. INT
  1714. PasteLayer(
  1715. PLAYER_FIX plf,
  1716. PDATABASE pDataBaseTo,
  1717. BOOL bForcePaste = FALSE,
  1718. OUT PLAYER_FIX* pplfNewInserted = NULL,
  1719. BOOL bShow = FALSE
  1720. );
  1721. BOOL
  1722. PasteAppHelpMessage(
  1723. PAPPHELP pAppHelp,
  1724. PDATABASE pDataBaseTo,
  1725. PAPPHELP* ppAppHelpInLib = NULL
  1726. );
  1727. INT
  1728. Tokenize(
  1729. PCTSTR szString,
  1730. INT cchLength,
  1731. PCTSTR szDelims,
  1732. CSTRINGLIST& strlTokens
  1733. );
  1734. INT
  1735. CopyShimFixList(
  1736. PSHIM_FIX_LIST* ppsflDest,
  1737. PSHIM_FIX_LIST* ppsflSrc
  1738. );
  1739. void
  1740. ShowInlineHelp(
  1741. LPCTSTR pszInlineHelpHtmlFile
  1742. );
  1743. PTSTR
  1744. GetSpace(
  1745. PTSTR pszSpace,
  1746. INT iSpaces,
  1747. INT iBufSzie
  1748. );
  1749. BOOL
  1750. ValidInput(
  1751. PCTSTR pszStr
  1752. );
  1753. PDATABASE
  1754. GetCurrentDB(
  1755. void
  1756. );
  1757. BOOL
  1758. IsValidAppName(
  1759. PCTSTR pszAppName
  1760. );
  1761. void
  1762. DisplayInvalidAppNameMessage(
  1763. HWND hdlg
  1764. );
  1765. #endif // _COMPATADMIN_H