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
2266 lines
60 KiB
/*++
|
|
|
|
Copyright (c) 1989-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
CompatAdmin.h
|
|
|
|
Abstract:
|
|
|
|
Main Header for the application
|
|
|
|
Author:
|
|
|
|
kinshu created July 2, 2001
|
|
|
|
--*/
|
|
|
|
#ifndef _COMPATADMIN_H
|
|
#define _COMPATADMIN_H
|
|
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <Shlwapi.h>
|
|
#include <Shellapi.h>
|
|
#include <commctrl.h>
|
|
#include <Commdlg.h>
|
|
#include <Sddl.h>
|
|
#include <Winbase.h>
|
|
#include "resource.h"
|
|
#include "HtmlHelp.h"
|
|
#include <strsafe.h>
|
|
|
|
extern "C" {
|
|
#include "shimdb.h"
|
|
}
|
|
|
|
//////////////////////// Externs //////////////////////////////////////////////
|
|
|
|
class DatabaseTree;
|
|
|
|
extern TCHAR g_szAppName[];
|
|
extern HWND g_hDlg;
|
|
extern DWORD ATTRIBUTE_COUNT;
|
|
extern BOOL g_bUpdateInstalledRequired;
|
|
extern HWND g_hdlgQueryDB;
|
|
extern HWND g_hdlgSearchDB;
|
|
extern BOOL g_bExpert;
|
|
extern BOOL g_bAdmin;
|
|
extern DatabaseTree DBTree;
|
|
extern struct _tagClipBoard gClipBoard;
|
|
extern struct tagDataBaseList DataBaseList;
|
|
extern struct tagDataBaseList InstalledDataBaseList;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////// Defines //////////////////////////////////////////////
|
|
|
|
// The type of module. Will specify either inclusion or exclusion
|
|
#define INCLUDE 1
|
|
#define EXCLUDE 0
|
|
|
|
//
|
|
// Indexes for HKEY array on which we are listening for events. The events are used for automatically refreshing
|
|
// the list of installed and per-user
|
|
#define IND_PERUSER 0
|
|
#define IND_ALLUSERS 1
|
|
|
|
// Number of spaces that a tab corresponds to. This is used when we are formatting the XML
|
|
// before writing it to the disk.
|
|
#define TAB_SIZE 4
|
|
|
|
// Make sure that both LIMIT_APP_NAME and LIMIT_LAYER_NAME have the same value
|
|
// Used for limiting the text filed in the UI
|
|
#define LIMIT_APP_NAME 128
|
|
#define LIMIT_LAYER_NAME 128
|
|
#define MAX_VENDOR_LENGTH 100
|
|
|
|
|
|
// Defines for the event types. These are the events which are shown in the event window. Main-menu>View>Events
|
|
#define EVENT_ENTRY_COPYOK 0
|
|
#define EVENT_SYSTEM_RENAME 1
|
|
#define EVENT_CONFLICT_ENTRY 2
|
|
#define EVENT_LAYER_COPYOK 3
|
|
|
|
// The number of file names that we will show in the MRU list
|
|
#define MAX_MRU_COUNT 5
|
|
|
|
//
|
|
// The file name where we are going to save the shim log.
|
|
// This is created in %windir%/AppPatch
|
|
#define SHIM_FILE_LOG_NAME TEXT("CompatAdmin.log")
|
|
|
|
// Auto-complete flag passed on to SHAutoComplete()
|
|
#define AUTOCOMPLETE SHACF_FILESYSTEM | SHACF_AUTOSUGGEST_FORCE_ON
|
|
|
|
// Select style passed to TREEVIEW_SHOW
|
|
#define TVSELECT_STYLE TVGN_CARET
|
|
|
|
// Select and show the tree item
|
|
//*******************************************************************************
|
|
#define TREEVIEW_SHOW(hwndTree, hItem, flags) \
|
|
{ \
|
|
TreeView_Select(hwndTree, hItem, TVSELECT_STYLE); \
|
|
TreeView_EnsureVisible(hwndTree, hItem); \
|
|
}
|
|
//*******************************************************************************
|
|
|
|
//
|
|
// Add a trailing '\'to a path, if it does not exist
|
|
//*******************************************************************************
|
|
#define ADD_PATH_SEPARATOR(szStr, nSize) \
|
|
{ \
|
|
INT iLength = lstrlen(szStr); \
|
|
if ((iLength < nSize - 1 && iLength > 0) \
|
|
&& szStr[iLength - 1] != TEXT('\\')) { \
|
|
StringCchCat(szStr, nSize, TEXT("\\")); \
|
|
} \
|
|
}
|
|
//*******************************************************************************
|
|
|
|
// Enable or disable a tool bar button
|
|
//*******************************************************************************
|
|
#define EnableToolBarButton(hwndTB, id, bEnable) \
|
|
SendMessage(hwndTB, TB_ENABLEBUTTON, (WPARAM)id, (LPARAM) MAKELONG(bEnable, 0));
|
|
//******************************************************************************
|
|
|
|
//
|
|
// Gets the size of a file when we already have PATTRINFO. This is needed
|
|
// when we have to sort the files generated while using "Auto-Generate" matching
|
|
// files option in the fix or app help wizard. We sort the files are use only the
|
|
// first MAX_AUTO_MATCH files
|
|
//*******************************************************************************
|
|
#define GET_SIZE_ATTRIBUTE(pAttrInfo, dwAttrCount, dwSize) \
|
|
{ \
|
|
for (DWORD dwIndex = 0; dwIndex < dwAttrCount; dwIndex++) { \
|
|
\
|
|
if (pAttrInfo[dwIndex].tAttrID == TAG_SIZE \
|
|
&& (pAttrInfo[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE)) { \
|
|
\
|
|
dwSize = pAttrInfo[dwIndex].dwAttr; \
|
|
break; \
|
|
} \
|
|
} \
|
|
}
|
|
//*******************************************************************************
|
|
|
|
//*******************************************************************************
|
|
#define REGCLOSEKEY(hKey) \
|
|
{ \
|
|
if (hKey) { \
|
|
RegCloseKey(hKey); \
|
|
hKey = NULL; \
|
|
} \
|
|
}
|
|
//*******************************************************************************
|
|
|
|
//*******************************************************************************
|
|
#define ENABLEWINDOW(hwnd,bEnable) \
|
|
{ \
|
|
HWND hWndTemp = hwnd; \
|
|
if (hWndTemp) { \
|
|
EnableWindow(hWndTemp, bEnable); \
|
|
} else { \
|
|
assert(FALSE); \
|
|
} \
|
|
}
|
|
//*******************************************************************************
|
|
|
|
// IDs for the MRU items. Make sure that we do not get any control or menu with these ids
|
|
#define ID_FILE_FIRST_MRU 351
|
|
#define ID_FILE_MRU1 ID_FILE_FIRST_MRU
|
|
#define ID_FILE_MRU2 (ID_FILE_FIRST_MRU + 1)
|
|
#define ID_FILE_MRU3 (ID_FILE_FIRST_MRU + 2)
|
|
#define ID_FILE_MRU4 (ID_FILE_FIRST_MRU + 3)
|
|
#define ID_FILE_MRU5 (ID_FILE_FIRST_MRU + 4)
|
|
|
|
// The key in the registry where we store our display settings
|
|
#define DISPLAY_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\CompatAdmin\\Display")
|
|
|
|
// The key in the registry where we store our MRU file names
|
|
#define MRU_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\CompatAdmin\\MRU")
|
|
|
|
// The base key. At least this should be present on all systems, even if we just loaded the OS
|
|
#define KEY_BASE TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion")
|
|
|
|
//
|
|
// The default mask for attributes that we choose. By default we choose these attributes:
|
|
// TAG_BIN_FILE_VERSION, TAG_BIN_PRODUCT_VERSION, TAG_PRODUCT_VERSION, TAG_FILE_VERSION, TAG_COMPANY_NAME,TAG_PRODUCT_NAME
|
|
#define DEFAULT_MASK 0x3B8L
|
|
|
|
// The various user defined message types
|
|
#define WM_USER_MATCHINGTREE_REFRESH WM_USER + 1024
|
|
#define WM_USER_DOTHESEARCH WM_USER + 1025
|
|
#define WM_USER_ACTIVATE WM_USER + 1026
|
|
#define WM_USER_REPAINT_TREEITEM WM_USER + 1030
|
|
#define WM_USER_LOAD_COMMANDLINE_DATABASES WM_USER + 1031
|
|
#define WM_USER_POPULATECONTENTSLIST WM_USER + 1032
|
|
#define WM_USER_REPAINT_LISTITEM WM_USER + 1034
|
|
#define WM_USER_UPDATEINSTALLED WM_USER + 1035
|
|
#define WM_USER_UPDATEPERUSER WM_USER + 1036
|
|
#define WM_USER_GETSQL WM_USER + 1037
|
|
#define WM_USER_NEWMATCH WM_USER + 1038
|
|
#define WM_USER_NEWFILE WM_USER + 1039
|
|
#define WM_USER_NEWQDB WM_USER + 1041
|
|
#define WM_USER_TESTRUN_NODIALOG WM_USER + 1042
|
|
|
|
|
|
// Defines for the Images
|
|
#define IMAGE_SHIM 0
|
|
#define IMAGE_APPHELP 1
|
|
#define IMAGE_LAYERS 2
|
|
#define IMAGE_PATCHES 3
|
|
#define IMAGE_MATCHINFO 4
|
|
#define IMAGE_MATCHGROUP 5
|
|
#define IMAGE_WARNING 6
|
|
#define IMAGE_GLOBAL 7
|
|
#define IMAGE_WORKING 8
|
|
#define IMAGE_COMMANDLINE 9
|
|
#define IMAGE_INCLUDE 10
|
|
#define IMAGE_EXCLUDE 11
|
|
#define IMAGE_APP 12
|
|
#define IMAGE_INSTALLED 13
|
|
#define IMAGE_DATABASE 14
|
|
#define IMAGE_SINGLEAPP 15
|
|
#define IMAGE_ALLUSERS 16
|
|
#define IMAGE_SINGLEUSER 17
|
|
#define IMAGE_APPLICATION 18
|
|
#define IMAGE_EVENT_ERROR 19
|
|
#define IMAGE_EVENT_WARNING 20
|
|
#define IMAGE_EVENT_INFO 21
|
|
#define IMAGE_LAST 24 //Last global image index.
|
|
|
|
// Images for the tool bar
|
|
#define IMAGE_TB_NEW 0
|
|
#define IMAGE_TB_OPEN 1
|
|
#define IMAGE_TB_SAVE 2
|
|
#define IMAGE_TB_NEWFIX 3
|
|
#define IMAGE_TB_NEWAPPHELP 4
|
|
#define IMAGE_TB_NEWMODE 5
|
|
#define IMAGE_TB_RUN 6
|
|
#define IMAGE_TB_SEARCH 7
|
|
#define IMAGE_TB_QUERY 8
|
|
|
|
// Id for the tool bar in the main window, which we create dynamically
|
|
#define ID_TOOLBAR 5555
|
|
|
|
//
|
|
// Max. length of the SQL. This string is of the form 'SELECT ... FROM ... [WHERE ...]'
|
|
// Note that the actual length of the final SQL will be more than the sum of the text in the
|
|
// select and the where text fields, because it will include the key words like SELECT, WHERE, FROM
|
|
// and also the name of the databases like SYSTEM_DB etc.
|
|
// So we made it as 2096
|
|
#define MAX_SQL_LENGTH 2096
|
|
|
|
//
|
|
// Debugging spew
|
|
typedef enum
|
|
{
|
|
dlNone = 0,
|
|
dlPrint,
|
|
dlError,
|
|
dlWarning,
|
|
dlInfo
|
|
|
|
} DEBUGLEVEL;
|
|
|
|
//
|
|
// Defines for mapping into strsafe functions
|
|
//
|
|
#define SafeCpyN(pszDest, pszSource, nDestSize) StringCchCopy(pszDest, nDestSize, pszSource)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*++
|
|
!!!!!!!!!!!!!!! Warning !!!!!!!!!!!!!!!!!!
|
|
|
|
Do not change the values for the DATABASE_TYPE_* enums. They should be powers of 2
|
|
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
The types of various data structures and some GUI tree items. In tree views
|
|
we have lParams associated with the tree items. All data structures have
|
|
a type field, which is the first field. So that if we have a pointer/lParam
|
|
and if the value of the pointer is greater than TYPE_NULL, then we typecast
|
|
it to PDS_TYPE and see if the type field is any of our known data structures
|
|
|
|
--*/
|
|
|
|
typedef unsigned (__stdcall *PTHREAD_START)(PVOID);
|
|
|
|
typedef const size_t K_SIZE;
|
|
|
|
typedef enum {
|
|
|
|
TYPE_UNKNOWN = 0,
|
|
DATABASE_TYPE_GLOBAL = 0x01, // The global/system database i.e. %windir%\AppPatch\Sysmain.sdb
|
|
DATABASE_TYPE_INSTALLED = 0x02, // An installed database
|
|
DATABASE_TYPE_WORKING = 0x04, // A working/custom database
|
|
|
|
FIX_SHIM, // Type for SHIM_FIX
|
|
FIX_PATCH, // Type for PATCH_FIX
|
|
FIX_LAYER, // Type for LAYER_FIX
|
|
FIX_FLAG, // Type for FLAG_FIX
|
|
|
|
FIX_LIST_SHIM, // Type for SHIM_FIX_LIST
|
|
FIX_LIST_PATCH, // Type for PATCH_FIX_LIST
|
|
FIX_LIST_LAYER, // Type for LAYER_FIX_LIST
|
|
FIX_LIST_FLAG, // Type for FLAG_FIX_LIST
|
|
|
|
TYPE_GUI_APPS, // lParam for "Applications" Tree item
|
|
TYPE_GUI_SHIMS, // lParam for "Compatibility Fixes" Tree item
|
|
TYPE_GUI_MATCHING_FILES, // lParam for "Compatibility Modes" Tree item
|
|
TYPE_GUI_LAYERS, // lParam for "Compatibility Modes" Tree item
|
|
TYPE_GUI_PATCHES, // lParam for "Compatibility Patches" Tree item
|
|
|
|
TYPE_GUI_COMMANDLINE, // lParam for "Commandline" Tree item
|
|
TYPE_GUI_INCLUDE, // lParam for an included module tree item
|
|
TYPE_GUI_EXCLUDE, // lParam for an excluded module tree item
|
|
|
|
TYPE_GUI_DATABASE_WORKING_ALL, // lParam for "Custom Database" Tree item
|
|
TYPE_GUI_DATABASE_INSTALLED_ALL, // lParam for "Installed Database" Tree item
|
|
|
|
TYPE_APPHELP_ENTRY, // Type for APPHELP
|
|
TYPE_ENTRY, // Type for DBENTRY
|
|
TYPE_MATCHING_FILE, // Type for MATCHINGFILE
|
|
TYPE_MATCHING_ATTRIBUTE, // An attribute item that appears under the matching file tree item
|
|
|
|
TYPE_NULL //NOTE: This should be the last in the enum !!
|
|
|
|
} TYPE;
|
|
|
|
typedef enum {
|
|
|
|
FLAG_USER,
|
|
FLAG_KERNEL
|
|
|
|
} FLAGTYPE;
|
|
|
|
//
|
|
// Source type where the cut or copy was performed
|
|
//
|
|
typedef enum {
|
|
|
|
LIB_TREE = 0, // The data base tree (LHS)
|
|
ENTRY_TREE, // The entry tree (RHS)
|
|
ENTRY_LIST // The contents list (RHS)
|
|
|
|
}SOURCE_TYPE;
|
|
|
|
typedef enum {
|
|
APPTYPE_NONE, // No apphelp has been added
|
|
APPTYPE_INC_NOBLOCK, // Soft blocked
|
|
APPTYPE_INC_HARDBLOCK, // Hard blocked
|
|
APPTYPE_MINORPROBLEM, // <Not used at the moment>
|
|
APPTYPE_REINSTALL // <Not used at the moment>
|
|
|
|
} SEVERITY;
|
|
|
|
/*++
|
|
|
|
All data structures are sub classed from this, so all have a TYPE type member
|
|
as their first member
|
|
|
|
--*/
|
|
typedef struct tagTYPE {
|
|
TYPE type;
|
|
} DS_TYPE, *PDS_TYPE;
|
|
|
|
/*++
|
|
|
|
Used for setting the background of controls that we show in a tab control
|
|
|
|
--*/
|
|
typedef HRESULT (*PFNEnableThemeDialogTexture)(HWND hwnd, DWORD dwFlags);
|
|
|
|
/*++
|
|
|
|
Used when we are using the disk search option. MainMenu>Search>Search for fixed programs
|
|
|
|
--*/
|
|
typedef struct _MatchedEntry {
|
|
|
|
CSTRING strAppName; // Name of the application
|
|
CSTRING strPath; // The complete path of the program
|
|
CSTRING strDatabase; // Name of the database
|
|
CSTRING strAction; // Action type. Fixed with fixes, layers, or apphelp
|
|
TCHAR szGuid[128]; // Guid of the database in which the fixed program entry was found
|
|
TAGID tiExe; // Tag id for the fixed program entry in the database in which it was found
|
|
|
|
} MATCHEDENTRY, *PMATCHEDENTRY;
|
|
|
|
/*++
|
|
|
|
Used for customizing LUA shim
|
|
|
|
--*/
|
|
typedef struct tagLUAData
|
|
{
|
|
CSTRING strAllUserDir;
|
|
CSTRING strPerUserDir;
|
|
CSTRING strStaticList;
|
|
CSTRING strDynamicList;
|
|
CSTRING strExcludedExtensions;
|
|
|
|
BOOL IsEmpty()
|
|
{
|
|
return (strAllUserDir == NULL &&
|
|
strPerUserDir == NULL &&
|
|
strStaticList == NULL &&
|
|
strDynamicList == NULL &&
|
|
strExcludedExtensions == NULL);
|
|
}
|
|
|
|
BOOL IsEqual(tagLUAData & other) {
|
|
|
|
return (strAllUserDir == other.strAllUserDir &&
|
|
strPerUserDir == other.strPerUserDir &&
|
|
strStaticList == other.strStaticList &&
|
|
strDynamicList == other.strDynamicList &&
|
|
strExcludedExtensions == other.strExcludedExtensions);
|
|
}
|
|
|
|
void Copy(tagLUAData & other) {
|
|
|
|
strAllUserDir = other.strAllUserDir;
|
|
strPerUserDir = other.strPerUserDir;
|
|
strStaticList = other.strStaticList;
|
|
strDynamicList = other.strDynamicList;
|
|
strExcludedExtensions = other.strExcludedExtensions;
|
|
}
|
|
|
|
void Copy(tagLUAData* pLuaDataOther)
|
|
{
|
|
assert(pLuaDataOther);
|
|
|
|
if (pLuaDataOther == NULL) {
|
|
return;
|
|
}
|
|
|
|
strAllUserDir = pLuaDataOther->strAllUserDir;
|
|
strPerUserDir = pLuaDataOther->strPerUserDir;
|
|
strStaticList = pLuaDataOther->strStaticList;
|
|
strDynamicList = pLuaDataOther->strDynamicList;
|
|
strExcludedExtensions = pLuaDataOther->strExcludedExtensions;
|
|
}
|
|
|
|
void Free()
|
|
{
|
|
strStaticList.Release();
|
|
strDynamicList.Release();
|
|
strAllUserDir.Release();
|
|
strPerUserDir.Release();
|
|
strExcludedExtensions.Release();
|
|
}
|
|
|
|
} LUADATA, *PLUADATA;
|
|
|
|
/*++
|
|
|
|
A shim also known as a compatibility fix. In fact compatibility fix means any of
|
|
shims, flags or patches. In the entry tree (RHS), if some exe has a patch, it is shown
|
|
differently under "Compatibility Patches" tree item
|
|
|
|
--*/
|
|
typedef struct tagSHIM_FIX : public DS_TYPE {
|
|
|
|
struct tagSHIM_FIX* pNext; // The next shim
|
|
CSTRING strName; // The name of the shim
|
|
CSTRING strDescription; // The desciption of the shim
|
|
CSTRING strCommandLine; // The commandline for the shim
|
|
BOOL bGeneral; // Is this a general or a specific shim
|
|
CSTRINGLIST strlInExclude; // List of include and exclude modules
|
|
|
|
tagSHIM_FIX()
|
|
{
|
|
pNext = NULL;
|
|
bGeneral = FALSE;
|
|
type = FIX_SHIM;
|
|
}
|
|
|
|
} SHIM_FIX, *PSHIM_FIX;
|
|
|
|
/*++
|
|
|
|
Contains a pointer to a shim and a pointer to a tagSHIM_FIX_LIST
|
|
|
|
--*/
|
|
typedef struct tagSHIM_FIX_LIST : public DS_TYPE {
|
|
|
|
struct tagSHIM_FIX_LIST* pNext; // The next tagSHIM_FIX_LIST
|
|
PSHIM_FIX pShimFix; // Pointer to a shim
|
|
CSTRING strCommandLine; // Any command line
|
|
CSTRINGLIST strlInExclude; // Any include-exclude modules
|
|
PLUADATA pLuaData; // Lua data
|
|
|
|
tagSHIM_FIX_LIST()
|
|
{
|
|
pNext = NULL;
|
|
pShimFix = NULL;
|
|
pLuaData = NULL;
|
|
type = FIX_LIST_SHIM;
|
|
}
|
|
|
|
} SHIM_FIX_LIST, *PSHIM_FIX_LIST;
|
|
|
|
void
|
|
DeleteShimFixList(
|
|
PSHIM_FIX_LIST psl
|
|
);
|
|
|
|
/*++
|
|
|
|
A compatibility flag
|
|
|
|
--*/
|
|
typedef struct tagFLAG_FIX : public DS_TYPE {
|
|
|
|
struct tagFLAG_FIX* pNext; // Pointer to the next flag
|
|
CSTRING strName; // Name of the flag
|
|
CSTRING strDescription; // Description for the flag
|
|
CSTRING strCommandLine; // Command line for the flag
|
|
ULONGLONG ullMask; // <Not used at the moment>
|
|
FLAGTYPE flagType; // Type, one of: FLAG_USER, FLAG_KERNEL
|
|
BOOL bGeneral; // General or specific
|
|
|
|
tagFLAG_FIX()
|
|
{
|
|
pNext = NULL;
|
|
type = FIX_FLAG;
|
|
bGeneral = FALSE;
|
|
}
|
|
|
|
} FLAG_FIX, *PFLAG_FIX;
|
|
|
|
/*++
|
|
|
|
Contains a pointer to a flag and a pointer to a tagFLAG_FIX_LIST
|
|
|
|
--*/
|
|
typedef struct tagFLAG_FIX_LIST : public DS_TYPE {
|
|
|
|
struct tagFLAG_FIX_LIST* pNext; // The next tagFLAG_FIX_LIST
|
|
PFLAG_FIX pFlagFix; // Pointer to a flag
|
|
CSTRING strCommandLine; // Any command lines for this flag
|
|
|
|
tagFLAG_FIX_LIST()
|
|
{
|
|
pNext = NULL;
|
|
pFlagFix = NULL;
|
|
type = FIX_LIST_FLAG;
|
|
}
|
|
|
|
} FLAG_FIX_LIST, *PFLAG_FIX_LIST;
|
|
|
|
void
|
|
DeleteFlagFixList(
|
|
PFLAG_FIX_LIST pfl
|
|
);
|
|
|
|
/*++
|
|
|
|
A layer. Also known as a compatibility mode. A layer is a collection of shims and
|
|
flags. Shims and flags when they appear in a layer can have a different command lines
|
|
and include-exclude paramteres than what they originallyy have. Note that flags do
|
|
not have include-exclude parameters. That is why SHIM_FIX_LIST has a strCommandLine
|
|
and a strlInExclude and FLAG_FIX_LIST has a strCommandLine
|
|
|
|
--*/
|
|
|
|
typedef struct tagLAYER_FIX : public DS_TYPE {
|
|
|
|
struct tagLAYER_FIX* pNext; // The next layer
|
|
CSTRING strName; // The name of the layer
|
|
PSHIM_FIX_LIST pShimFixList; // List of shims for this layer
|
|
PFLAG_FIX_LIST pFlagFixList; // List of flags for this layer
|
|
BOOL bCustom; // Is this a custom layer (created in a custom database), or does it live in the system database
|
|
UINT uShimCount; // Number of shims and flags in this layer
|
|
|
|
tagLAYER_FIX(BOOL bCustomType)
|
|
{
|
|
pFlagFixList = NULL;
|
|
pNext = NULL;
|
|
pShimFixList = NULL;
|
|
type = FIX_LAYER;
|
|
bCustom = bCustomType;
|
|
uShimCount = 0;
|
|
}
|
|
|
|
tagLAYER_FIX& operator = (tagLAYER_FIX& temp)
|
|
{
|
|
//
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
// CAUTION: DO NOT MODIFY THE pNext MEMBER.
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
//
|
|
|
|
strName = temp.strName;
|
|
|
|
//
|
|
// First copy the flags
|
|
//
|
|
DeleteFlagFixList(pFlagFixList);
|
|
pFlagFixList = NULL;
|
|
|
|
DeleteShimFixList(pShimFixList);
|
|
pShimFixList = NULL;
|
|
|
|
PFLAG_FIX_LIST pfl = temp.pFlagFixList;
|
|
|
|
while (pfl) {
|
|
|
|
PFLAG_FIX_LIST pflNew = new FLAG_FIX_LIST;
|
|
|
|
if (pflNew == NULL) {
|
|
|
|
MEM_ERR;
|
|
return *this;
|
|
}
|
|
|
|
pflNew->pFlagFix = pfl->pFlagFix;
|
|
pflNew->strCommandLine = pfl->strCommandLine;
|
|
|
|
pflNew->pNext = pFlagFixList;
|
|
pFlagFixList = pflNew;
|
|
|
|
pfl = pfl->pNext;
|
|
}
|
|
|
|
//
|
|
// Now copy the shims
|
|
//
|
|
PSHIM_FIX_LIST psfl = temp.pShimFixList;
|
|
|
|
while (psfl) {
|
|
|
|
PSHIM_FIX_LIST pNew = new SHIM_FIX_LIST;
|
|
|
|
if (pNew == NULL) {
|
|
|
|
MEM_ERR;
|
|
return *this;
|
|
}
|
|
|
|
pNew->pShimFix = psfl->pShimFix;
|
|
pNew->strCommandLine = psfl->strCommandLine;
|
|
pNew->strlInExclude = psfl->strlInExclude;
|
|
|
|
if (psfl->pLuaData) {
|
|
|
|
pNew->pLuaData = new LUADATA;
|
|
|
|
if (pNew->pLuaData) {
|
|
pNew->pLuaData->Copy(psfl->pLuaData);
|
|
} else {
|
|
MEM_ERR;
|
|
}
|
|
}
|
|
|
|
pNew->pNext = pShimFixList;
|
|
pShimFixList = pNew;
|
|
|
|
psfl = psfl->pNext;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
} LAYER_FIX, *PLAYER_FIX;
|
|
|
|
/*++
|
|
|
|
Contains a pointer to a layer and a pointer to a tagLAYER_FIX_LIST
|
|
|
|
--*/
|
|
|
|
typedef struct tagLAYER_FIX_LIST : public DS_TYPE {
|
|
|
|
struct tagLAYER_FIX_LIST* pNext; // The next tagLAYER_FIX_LIST
|
|
PLAYER_FIX pLayerFix; // The layer to which this tagLAYER_FIX_LIST points
|
|
|
|
tagLAYER_FIX_LIST()
|
|
{
|
|
pLayerFix = NULL;
|
|
pNext = NULL;
|
|
type = FIX_LIST_LAYER;
|
|
}
|
|
|
|
} LAYER_FIX_LIST, *PLAYER_FIX_LIST;
|
|
|
|
/*++
|
|
|
|
A compatibility patch
|
|
|
|
--*/
|
|
typedef struct tagPATCH_FIX : public DS_TYPE {
|
|
|
|
struct tagPATCH_FIX* pNext; // The next patch
|
|
CSTRING strName; // Name of this patch
|
|
CSTRING strDescription; // Description for this patch
|
|
|
|
tagPATCH_FIX()
|
|
{
|
|
pNext = NULL;
|
|
type = FIX_PATCH;
|
|
}
|
|
|
|
} PATCH_FIX, *PPATCH_FIX;
|
|
|
|
/*++
|
|
|
|
Contains a pointer to a patch and a pointer to a tagPATCH_FIX_LIST
|
|
|
|
--*/
|
|
typedef struct tagPATCH_FIX_LIST : public DS_TYPE {
|
|
|
|
struct tagPATCH_FIX_LIST* pNext;
|
|
PPATCH_FIX pPatchFix;
|
|
|
|
tagPATCH_FIX_LIST()
|
|
{
|
|
pNext = NULL;
|
|
pPatchFix = NULL;
|
|
type = FIX_LIST_PATCH;
|
|
}
|
|
|
|
} PATCH_FIX_LIST, *PPATCH_FIX_LIST;
|
|
|
|
/*++
|
|
|
|
NOTE: The same APPHELP strcuture is used by the apphelp in the Library and the one in the
|
|
DBENTRY. This structure represents the union of the fields used at these two different
|
|
places.
|
|
|
|
Before the comments you will see E, D, B.
|
|
|
|
E: Used when in the context of an entry
|
|
D: Used when in the context of a database
|
|
B: Applicable to both
|
|
--*/
|
|
|
|
typedef struct tagAPPHELP : public DS_TYPE {
|
|
|
|
union{
|
|
struct tagAPPHELP *pNext; // D: Pointer to the next apphelp message in the database
|
|
struct tagAPPHELP *pAppHelpinLib; // E: Pointer to the apphelp message in the database for this entry
|
|
};
|
|
|
|
BOOL bPresent; // E: Is the entry apphelped. If this is false, all other fields have invalid value
|
|
SEVERITY severity; // E: The severity
|
|
CSTRING strMsgName; // D: The name of the message
|
|
CSTRING strMessage; // D: The text for the apphelp message
|
|
CSTRING strURL; // D: The URL for this apphelp message
|
|
UINT HTMLHELPID; // B: The id for this message
|
|
BOOL bBlock; // E: Whether no block or hard block. This is determined by the type of severity
|
|
|
|
tagAPPHELP()
|
|
{
|
|
type = TYPE_APPHELP_ENTRY;
|
|
}
|
|
|
|
} APPHELP, *PAPPHELP;
|
|
|
|
/*++
|
|
Extended ATTRINFO so that we can use CSTRING
|
|
--*/
|
|
typedef struct tagATTRINFO_NEW : public ATTRINFO
|
|
{
|
|
CSTRING strValue;
|
|
|
|
tagATTRINFO_NEW()
|
|
{
|
|
this->dwFlags = 0;
|
|
this->ullAttr = 0;
|
|
}
|
|
|
|
} ATTRINFO_NEW, *PATTRINFO_NEW;
|
|
|
|
/*++
|
|
Array of PATTRINFO_NEW. Each matching file has a set of attributes and this is
|
|
specified by this data structure
|
|
--*/
|
|
typedef struct tagATTRIBUTE_LIST
|
|
{
|
|
|
|
PATTRINFO_NEW pAttribute;
|
|
|
|
tagATTRIBUTE_LIST()
|
|
{
|
|
pAttribute = new ATTRINFO_NEW[ATTRIBUTE_COUNT];
|
|
|
|
if (pAttribute == NULL) {
|
|
MEM_ERR;
|
|
return;
|
|
}
|
|
|
|
ZeroMemory(pAttribute, sizeof (ATTRINFO_NEW) * ATTRIBUTE_COUNT);
|
|
}
|
|
|
|
tagATTRIBUTE_LIST& operator =(tagATTRIBUTE_LIST& SecondList)
|
|
{
|
|
PATTRINFO_NEW pSecondList = SecondList.pAttribute;
|
|
|
|
for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
|
|
|
|
pAttribute[dwIndex].tAttrID = pSecondList[dwIndex].tAttrID;
|
|
pAttribute[dwIndex].dwFlags = pSecondList[dwIndex].dwFlags;
|
|
pAttribute[dwIndex].ullAttr = pSecondList[dwIndex].ullAttr;
|
|
|
|
if (GETTAGTYPE(pAttribute[dwIndex].tAttrID) == TAG_TYPE_STRINGREF
|
|
&& (pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE)) {
|
|
|
|
if (pSecondList[dwIndex].lpAttr) {
|
|
pAttribute[dwIndex].strValue = pSecondList[dwIndex].lpAttr;
|
|
pAttribute[dwIndex].lpAttr = pAttribute[dwIndex].strValue.pszString;
|
|
}
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
tagATTRIBUTE_LIST& operator =(PATTRINFO pSecondList)
|
|
{
|
|
for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
|
|
|
|
pAttribute[dwIndex].tAttrID = pSecondList[dwIndex].tAttrID;
|
|
pAttribute[dwIndex].dwFlags = pSecondList[dwIndex].dwFlags;
|
|
pAttribute[dwIndex].ullAttr = pSecondList[dwIndex].ullAttr;
|
|
|
|
if (GETTAGTYPE(pAttribute[dwIndex].tAttrID) == TAG_TYPE_STRINGREF
|
|
&& (pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE)) {
|
|
|
|
if (pSecondList[dwIndex].lpAttr) {
|
|
pAttribute[dwIndex].strValue = pSecondList[dwIndex].lpAttr;
|
|
pAttribute[dwIndex].lpAttr = pAttribute[dwIndex].strValue.pszString;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return *this;
|
|
}
|
|
|
|
~tagATTRIBUTE_LIST()
|
|
{
|
|
if (pAttribute) {
|
|
delete[] pAttribute;
|
|
}
|
|
|
|
pAttribute = NULL;
|
|
}
|
|
|
|
|
|
|
|
} ATTRIBUTELIST, *PATTRIBUTELIST;
|
|
|
|
int
|
|
TagToIndex(
|
|
IN TAG tag
|
|
);
|
|
|
|
/*++
|
|
A matching file. Each entry can contain a list of matching files that are used
|
|
to uniquely identify this entry
|
|
--*/
|
|
|
|
typedef struct tagMATCHINGFILE : public DS_TYPE {
|
|
|
|
struct tagMATCHINGFILE* pNext; // The next matching file
|
|
DWORD dwMask; // Which attributes have been selected to be used.
|
|
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.
|
|
CSTRING strFullName; // The full name if available.
|
|
ATTRIBUTELIST attributeList; // The attribute list for the matching file. The dwMask will determine which one of them are actually used
|
|
|
|
tagMATCHINGFILE()
|
|
{
|
|
pNext = NULL;
|
|
type = TYPE_MATCHING_FILE;
|
|
dwMask = DEFAULT_MASK;
|
|
}
|
|
|
|
BOOL operator == (struct tagMATCHINGFILE &val)
|
|
/*++
|
|
Desc:
|
|
|
|
Two matching files are said to be similar if there does not any exist any attribute
|
|
that has different values in these two matching files
|
|
--*/
|
|
{
|
|
BOOL bEqual = TRUE;
|
|
|
|
if (strMatchName != val.strMatchName) {
|
|
return FALSE;
|
|
}
|
|
|
|
for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
|
|
|
|
int iPos = TagToIndex(attributeList.pAttribute[dwIndex].tAttrID);
|
|
|
|
if (iPos == -1) {
|
|
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Do both the files use these attributes ?
|
|
//
|
|
if ((dwMask & (1 << (iPos + 1)))
|
|
&& (val.dwMask & (1 << (iPos + 1)))
|
|
&& attributeList.pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE
|
|
&& val.attributeList.pAttribute[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE) {
|
|
|
|
//
|
|
// Both of them use this attribute
|
|
//
|
|
switch (GETTAGTYPE(attributeList.pAttribute[dwIndex].tAttrID)) {
|
|
case TAG_TYPE_DWORD:
|
|
|
|
bEqual = (attributeList.pAttribute[dwIndex].dwAttr == val.attributeList.pAttribute[dwIndex].dwAttr);
|
|
break;
|
|
|
|
case TAG_TYPE_QWORD:
|
|
|
|
bEqual = (attributeList.pAttribute[dwIndex].ullAttr == val.attributeList.pAttribute[dwIndex].ullAttr);
|
|
break;
|
|
|
|
case TAG_TYPE_STRINGREF:
|
|
|
|
bEqual = (lstrcmpi(attributeList.pAttribute[dwIndex].lpAttr,
|
|
val.attributeList.pAttribute[dwIndex].lpAttr) == 0);
|
|
break;
|
|
}
|
|
|
|
if (bEqual == FALSE) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// everything matches.
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
} MATCHINGFILE, *PMATCHINGFILE;
|
|
|
|
void
|
|
DeletePatchFixList(
|
|
PPATCH_FIX_LIST pPat
|
|
);
|
|
|
|
void
|
|
DeleteLayerFixList(
|
|
PLAYER_FIX_LIST pll
|
|
);
|
|
|
|
void
|
|
DeleteFlagFixList(
|
|
PFLAG_FIX_LIST pfl
|
|
);
|
|
|
|
void
|
|
DeleteMatchingFiles(
|
|
PMATCHINGFILE pMatch
|
|
);
|
|
|
|
|
|
/*++
|
|
Data strcuture to represent a fixed program
|
|
|
|
We keep the data structure in this way:
|
|
|
|
There is a linked list of applications. An application is a DBENTRY. Each
|
|
application contains a pointer to the next application as well (through
|
|
pNext) as a pointer to a DBENTRY that has the same strAppName (through
|
|
pSameAppExe). This second DBENTRY is now called as an entry in this application
|
|
and will contain a pointer to the next entry. So we have effectively a linked
|
|
list of linked lists. So an application is the first member of a linked list B.
|
|
All such linked lists of type B are linked together (through pNext)to create a
|
|
linked list A which is the linked list of applications
|
|
|
|
--*/
|
|
typedef struct tagDBENTRY : public DS_TYPE {
|
|
|
|
struct tagDBENTRY* pNext; // Pointer to the next application, in case this entry is an application
|
|
struct tagDBENTRY* pSameAppExe; // Pointer to the next entry for this application.
|
|
|
|
TAGID tiExe; // TAGID for the entry as in the database
|
|
|
|
CSTRING strExeName; // The name of the exe being fixed. This will be file name only
|
|
CSTRING strFullpath; // Full path, if available
|
|
CSTRING strAppName; // Application name
|
|
CSTRING strVendor; // Vendor name, can be NULL
|
|
TCHAR szGUID[128]; // GUID for this entry
|
|
|
|
PSHIM_FIX_LIST pFirstShim; // The list of shims that have been applied to this entry
|
|
PPATCH_FIX_LIST pFirstPatch; // The list of patches that have been applied to this entry
|
|
PLAYER_FIX_LIST pFirstLayer; // The list of layers that have been applied to this entry
|
|
PFLAG_FIX_LIST pFirstFlag; // The list of flags that have been applied to this entry
|
|
|
|
APPHELP appHelp; // Apphelp information for this entry
|
|
|
|
PMATCHINGFILE pFirstMatchingFile; // The first matching file for this entry
|
|
int nMatchingFiles; // Number of matching files for this entry
|
|
|
|
BOOL bDisablePerUser; // Not used at the moment. Is this fix entry disabled for the present user?
|
|
BOOL bDisablePerMachine; // Is this fix entry disabled on this machine
|
|
|
|
HTREEITEM hItemExe; // HITEM for the exe as in the entry tree
|
|
|
|
tagDBENTRY()
|
|
{
|
|
tiExe = TAGID_NULL;
|
|
|
|
pFirstFlag = NULL;
|
|
pFirstLayer = NULL;
|
|
pFirstMatchingFile = NULL;
|
|
pFirstPatch = NULL;
|
|
pFirstShim = NULL;
|
|
pNext = NULL;
|
|
pSameAppExe = NULL;
|
|
|
|
*szGUID = 0;
|
|
|
|
appHelp.bPresent = FALSE;
|
|
appHelp.pAppHelpinLib = NULL;
|
|
appHelp.severity = APPTYPE_NONE;
|
|
|
|
type = TYPE_ENTRY;
|
|
hItemExe = NULL;
|
|
bDisablePerMachine = FALSE;
|
|
bDisablePerUser = FALSE;
|
|
nMatchingFiles = 0;
|
|
}
|
|
|
|
~tagDBENTRY()
|
|
{
|
|
Delete();
|
|
}
|
|
|
|
void
|
|
Delete()
|
|
{
|
|
DeleteFlagFixList(pFirstFlag);
|
|
pFirstFlag = NULL;
|
|
|
|
DeleteLayerFixList(pFirstLayer);
|
|
pFirstLayer = NULL;
|
|
|
|
DeleteMatchingFiles(pFirstMatchingFile);
|
|
pFirstMatchingFile = NULL;
|
|
|
|
DeleteShimFixList(pFirstShim);
|
|
pFirstShim = NULL;
|
|
|
|
DeletePatchFixList(pFirstPatch);
|
|
pFirstPatch = NULL;
|
|
}
|
|
|
|
struct tagDBENTRY& operator = (struct tagDBENTRY& temp)
|
|
{
|
|
Delete();
|
|
|
|
//
|
|
//********************************************************************************
|
|
// Note that we are assuming that both the entries are in the same database.
|
|
// So we do not move the layers and the apphelp, because they actually belong to the
|
|
// database. If we want to assign one DBENTRY to a DBENTRY in a different database
|
|
// we will have to copy the apphelp from one database to another and set the pointes
|
|
// of the apphelp in the entry correctly.
|
|
// Also we will need to copy any custom layers and set the pointers correctly.
|
|
//********************************************************************************
|
|
//
|
|
appHelp = temp.appHelp;
|
|
|
|
bDisablePerMachine = temp.bDisablePerMachine;
|
|
bDisablePerUser = temp.bDisablePerUser;
|
|
nMatchingFiles = temp.nMatchingFiles;
|
|
|
|
//
|
|
// Copy flag list
|
|
//
|
|
PFLAG_FIX_LIST pffl = temp.pFirstFlag;
|
|
|
|
while (pffl) {
|
|
|
|
PFLAG_FIX_LIST pfflNew = new FLAG_FIX_LIST;
|
|
|
|
if (pfflNew == NULL) {
|
|
MEM_ERR;
|
|
return *this;
|
|
}
|
|
|
|
pfflNew->pFlagFix = pffl->pFlagFix;
|
|
pfflNew->strCommandLine = pffl->strCommandLine;
|
|
pfflNew->pNext = pFirstFlag;
|
|
|
|
pFirstFlag = pfflNew;
|
|
|
|
pffl = pffl->pNext;
|
|
}
|
|
|
|
//
|
|
// Copy the layers list
|
|
//
|
|
PLAYER_FIX_LIST plfl = temp.pFirstLayer;
|
|
|
|
while (plfl) {
|
|
|
|
PLAYER_FIX_LIST pNew = new LAYER_FIX_LIST;
|
|
|
|
if (pNew == NULL) {
|
|
MEM_ERR;
|
|
return *this;
|
|
}
|
|
|
|
assert(plfl->pLayerFix);
|
|
pNew->pLayerFix = plfl->pLayerFix;
|
|
assert(pNew->pLayerFix);
|
|
|
|
pNew->pNext = pFirstLayer;
|
|
|
|
pFirstLayer = pNew;
|
|
|
|
plfl = plfl->pNext;
|
|
}
|
|
|
|
//
|
|
// Copy the matching files
|
|
//
|
|
PMATCHINGFILE pMatch = temp.pFirstMatchingFile;
|
|
|
|
while (pMatch) {
|
|
|
|
PMATCHINGFILE pNew = new MATCHINGFILE;
|
|
|
|
if (pNew == NULL) {
|
|
MEM_ERR;
|
|
return *this;
|
|
}
|
|
|
|
pNew->strMatchName = pMatch->strMatchName;
|
|
pNew->strFullName = pMatch->strFullName;
|
|
pNew->dwMask = pMatch->dwMask;
|
|
|
|
pNew->attributeList = pMatch->attributeList;
|
|
|
|
pNew->pNext = pFirstMatchingFile;
|
|
|
|
pFirstMatchingFile= pNew;
|
|
|
|
pMatch = pMatch->pNext;
|
|
}
|
|
|
|
//
|
|
// Copy the patches
|
|
//
|
|
PPATCH_FIX_LIST ppfl = temp.pFirstPatch;
|
|
|
|
while (ppfl) {
|
|
|
|
PPATCH_FIX_LIST pNew = new PATCH_FIX_LIST;
|
|
|
|
if (pNew == NULL) {
|
|
MEM_ERR;
|
|
return *this;
|
|
}
|
|
|
|
pNew->pPatchFix = ppfl->pPatchFix;
|
|
pNew->pNext = pFirstPatch;
|
|
|
|
pFirstPatch = pNew;
|
|
|
|
ppfl = ppfl->pNext;
|
|
}
|
|
|
|
//
|
|
// Copy the shims
|
|
//
|
|
PSHIM_FIX_LIST psfl = temp.pFirstShim;
|
|
|
|
while (psfl) {
|
|
|
|
PSHIM_FIX_LIST pNew = new SHIM_FIX_LIST;
|
|
|
|
pNew->pShimFix = psfl->pShimFix;
|
|
pNew->strCommandLine = psfl->strCommandLine;
|
|
pNew->strlInExclude = psfl->strlInExclude;
|
|
|
|
if (psfl->pLuaData) {
|
|
|
|
pNew->pLuaData = new LUADATA;
|
|
pNew->pLuaData->Copy(* (psfl->pLuaData));
|
|
}
|
|
|
|
pNew->pNext = pFirstShim;
|
|
pFirstShim = pNew;
|
|
|
|
psfl = psfl->pNext;
|
|
}
|
|
|
|
strAppName = temp.strAppName;
|
|
strExeName = temp.strExeName;
|
|
strFullpath = temp.strFullpath;
|
|
strVendor = temp.strVendor;
|
|
|
|
SafeCpyN(szGUID, temp.szGUID, ARRAYSIZE(szGUID));
|
|
|
|
return *this;
|
|
}
|
|
|
|
} DBENTRY, *PDBENTRY;
|
|
|
|
void
|
|
GetNextSDBFileName(
|
|
CSTRING &strFileName,
|
|
CSTRING &strDBName
|
|
);
|
|
LPTSTR
|
|
GetString(
|
|
UINT iResource,
|
|
TCHAR* szStr = NULL,
|
|
int nLength = 0
|
|
);
|
|
|
|
/*++
|
|
A data base
|
|
--*/
|
|
typedef struct DataBase : public DS_TYPE {
|
|
|
|
|
|
struct DataBase* pNext; // The next database. (If this is a part of a list)
|
|
|
|
CSTRING strName; // The name of this database
|
|
CSTRING strPath; // The complete path for this database
|
|
TCHAR szGUID[128]; // The GUID for this database
|
|
PDBENTRY pEntries; // Pointer to the first DBENTRY for this database
|
|
BOOL bChanged; // Has it changed since it was opened?
|
|
BOOL bReadOnly; // Is this a read-only database?
|
|
|
|
PLAYER_FIX pLayerFixes; // Pointer to the first layer
|
|
PSHIM_FIX pShimFixes; // Pointer to the first shim. Note that only the system database can have shims
|
|
PPATCH_FIX pPatchFixes; // Pointer to the first patch. Note that only the system database can have patches
|
|
PFLAG_FIX pFlagFixes; // Pointer to the first flag. Note that only the system database can have flags
|
|
PAPPHELP pAppHelp; // Pointer to the first apphelp message in the database. Valid only for custom databases
|
|
|
|
HTREEITEM hItemDB; // HTREEITEM for this database in the db tree
|
|
HTREEITEM hItemAllApps; // HTREEITEM for the "Applications" child tree item
|
|
HTREEITEM hItemAllLayers; // HTREEITEM for the "Compatibility Modes" child tree item
|
|
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.
|
|
|
|
UINT uAppCount; // Number of applications in this database
|
|
UINT uLayerCount; // Number of layers in this database
|
|
UINT uShimCount; // Number of shims and flags in this database
|
|
|
|
|
|
DataBase(TYPE typeDB)
|
|
{
|
|
Init(typeDB);
|
|
}
|
|
|
|
void
|
|
Init(TYPE typeDB)
|
|
{
|
|
type = typeDB;
|
|
|
|
pEntries = NULL;
|
|
pNext = NULL;
|
|
pFlagFixes = NULL;
|
|
pLayerFixes = NULL;
|
|
pPatchFixes = NULL;
|
|
pShimFixes = NULL;
|
|
pAppHelp = NULL;
|
|
|
|
uAppCount = 0;
|
|
uLayerCount = 0;
|
|
uShimCount = 0;
|
|
|
|
*szGUID = 0;
|
|
bChanged = FALSE;
|
|
|
|
if (typeDB == DATABASE_TYPE_INSTALLED) {
|
|
bReadOnly = TRUE;
|
|
} else {
|
|
bReadOnly = FALSE;
|
|
}
|
|
|
|
if (type == DATABASE_TYPE_WORKING) {
|
|
GetNextSDBFileName(strPath, strName);
|
|
|
|
} else if (type == DATABASE_TYPE_GLOBAL) {
|
|
|
|
TCHAR szShimDB[MAX_PATH * 2];
|
|
UINT uResult = 0;
|
|
|
|
*szShimDB = 0;
|
|
|
|
uResult = GetSystemWindowsDirectory(szShimDB, MAX_PATH);
|
|
|
|
if (uResult > 0 && uResult < MAX_PATH) {
|
|
|
|
ADD_PATH_SEPARATOR(szShimDB, ARRAYSIZE(szShimDB));
|
|
StringCchCat(szShimDB, ARRAYSIZE(szShimDB), TEXT("AppPatch\\sysmain.sdb"));
|
|
|
|
strName = GetString(IDS_CAPTION3);
|
|
} else {
|
|
assert(FALSE);
|
|
}
|
|
|
|
strPath = szShimDB;
|
|
//
|
|
// {11111111-1111-1111-1111-111111111111} is the GUID for the sysmain.sdb in XP
|
|
// but not on win2k
|
|
//
|
|
SafeCpyN(szGUID, _T("{11111111-1111-1111-1111-111111111111}"), ARRAYSIZE(szGUID));
|
|
}
|
|
|
|
hItemDB = NULL;
|
|
hItemAllApps = NULL;
|
|
hItemAllLayers = NULL;
|
|
m_nMAXHELPID = 0;
|
|
}
|
|
|
|
} DATABASE, *PDATABASE;
|
|
|
|
void
|
|
CleanupDbSupport(
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
void
|
|
ValidateClipBoard(
|
|
PDATABASE pDataBase,
|
|
LPVOID pElementTobeDeleted // Should be a PDBENTRY or a PLAYER_FIX
|
|
);
|
|
|
|
|
|
/*++
|
|
Linked list of databases
|
|
--*/
|
|
typedef struct tagDataBaseList {
|
|
|
|
|
|
PDATABASE pDataBaseHead; // The first database in the list
|
|
|
|
tagDataBaseList()
|
|
{
|
|
pDataBaseHead = NULL;
|
|
}
|
|
|
|
void
|
|
Add(
|
|
PDATABASE pDataBaseNew
|
|
)
|
|
{
|
|
if (pDataBaseNew == NULL) {
|
|
return;
|
|
}
|
|
|
|
pDataBaseNew->pNext = pDataBaseHead;
|
|
pDataBaseHead = pDataBaseNew;
|
|
}
|
|
|
|
BOOL
|
|
Remove(
|
|
PDATABASE pDataBaseToRemove
|
|
)
|
|
{
|
|
PDATABASE pPrev = NULL;
|
|
|
|
for (PDATABASE pTemp = pDataBaseHead; pTemp; pPrev = pTemp, pTemp = pTemp->pNext){
|
|
|
|
if (pTemp == pDataBaseToRemove) {
|
|
|
|
if (pPrev == NULL) {
|
|
//First Entry
|
|
pDataBaseHead = pTemp->pNext;
|
|
} else {
|
|
pPrev->pNext = pTemp->pNext;
|
|
}
|
|
|
|
//
|
|
// Remove any entries for this database that might be in our CLIPBOARD
|
|
//
|
|
ValidateClipBoard(pDataBaseToRemove, NULL);
|
|
|
|
CleanupDbSupport(pTemp);
|
|
delete pTemp;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pTemp == NULL){
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
RemoveAll()
|
|
{
|
|
PDATABASE pDBNext = NULL;
|
|
|
|
while (pDataBaseHead) {
|
|
|
|
pDBNext = pDataBaseHead->pNext;
|
|
|
|
//
|
|
// Remove any entries for this database that might be in our CLIPBOARD
|
|
//
|
|
ValidateClipBoard(pDataBaseHead, NULL);
|
|
|
|
CleanupDbSupport(pDataBaseHead);
|
|
delete pDataBaseHead;
|
|
pDataBaseHead = pDBNext;
|
|
}
|
|
}
|
|
|
|
PDATABASE
|
|
FindDB(
|
|
IN PDATABASE pDatabase
|
|
)
|
|
{
|
|
PDATABASE pDatabaseIndex = pDataBaseHead;
|
|
|
|
while (pDatabaseIndex) {
|
|
|
|
if (pDatabaseIndex == pDatabase) {
|
|
break;
|
|
}
|
|
|
|
pDatabaseIndex = pDatabaseIndex->pNext;
|
|
}
|
|
|
|
return pDatabaseIndex;
|
|
}
|
|
|
|
PDATABASE
|
|
FindDBByGuid(
|
|
IN PCTSTR pszGuid
|
|
)
|
|
{
|
|
PDATABASE pDatabaseIndex = pDataBaseHead;
|
|
|
|
while (pDatabaseIndex) {
|
|
|
|
if (lstrcmp(pDatabaseIndex->szGUID, pszGuid) == 0) {
|
|
break;
|
|
}
|
|
|
|
pDatabaseIndex = pDatabaseIndex->pNext;
|
|
}
|
|
|
|
return pDatabaseIndex;
|
|
}
|
|
|
|
|
|
}DATABASELIST, * PDATABASELIST;
|
|
|
|
/*++
|
|
Item in our clip-board data structure are of this type
|
|
--*/
|
|
typedef struct tagCopyStruct{
|
|
|
|
|
|
BOOL bRemoveEntry; // Should the entry be actually removed. Not used as yet
|
|
LPVOID lpData; // The pointer to the data structure that has been copied/cut
|
|
HTREEITEM hItem; // The tree item for the above
|
|
|
|
tagCopyStruct* pNext;
|
|
|
|
tagCopyStruct()
|
|
{
|
|
hItem = NULL;
|
|
bRemoveEntry = FALSE;
|
|
}
|
|
|
|
} CopyStruct;
|
|
|
|
/*++
|
|
Our clipboard data structure
|
|
--*/
|
|
typedef struct _tagClipBoard {
|
|
|
|
PDATABASE pDataBase; // The database from where we did some cut-copy. This will be the active database when we did cut or copy
|
|
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
|
|
SOURCE_TYPE SourceType; // Either of LIB_TREE, ENTRY_TREE, ENTRY_LIST.
|
|
CopyStruct* pClipBoardHead; // The pointer to the first element in the clipboard
|
|
|
|
_tagClipBoard()
|
|
{
|
|
pClipBoardHead = NULL;
|
|
}
|
|
|
|
void
|
|
Add(CopyStruct* pNew)
|
|
{
|
|
pNew->pNext = pClipBoardHead;
|
|
pClipBoardHead = pNew;
|
|
}
|
|
|
|
void
|
|
RemoveAll()
|
|
{
|
|
CopyStruct* pTemp = NULL;
|
|
|
|
while (pClipBoardHead) {
|
|
|
|
pTemp = pClipBoardHead->pNext;
|
|
delete pClipBoardHead;
|
|
pClipBoardHead = pTemp;
|
|
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CheckAndRemove(LPVOID lpData)
|
|
{
|
|
/*++
|
|
Return:
|
|
TRUE if the param was found in the clipboard.
|
|
FALSE otherwise
|
|
--*/
|
|
CopyStruct* pTemp = pClipBoardHead;
|
|
CopyStruct* pPrev = NULL;
|
|
|
|
while (pTemp) {
|
|
|
|
if (pTemp->lpData == lpData) {
|
|
|
|
if (pPrev == NULL) {
|
|
pClipBoardHead = pTemp->pNext;
|
|
} else {
|
|
pPrev->pNext = pTemp->pNext;
|
|
}
|
|
|
|
delete pTemp;
|
|
return TRUE;
|
|
}
|
|
|
|
pPrev = pTemp;
|
|
pTemp = pTemp->pNext;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
} CLIPBOARD;
|
|
|
|
//
|
|
// Used for sorting of columns in some list view
|
|
//
|
|
typedef struct _tagColSort
|
|
{
|
|
HWND hwndList; // The handle to the list view, in which we want to perform the sort
|
|
INT iCol; // The column that we want to do the sort on
|
|
LONG lSortColMask; // The mask that specifies what columns are sorted in what manner, so that we can toggle the sorting
|
|
|
|
} COLSORT;
|
|
|
|
TYPE
|
|
ConvertLparam2Type(
|
|
LPARAM lParam
|
|
);
|
|
|
|
TYPE
|
|
ConvertLpVoid2Type(
|
|
LPVOID lpVoid
|
|
);
|
|
|
|
|
|
TYPE
|
|
GetItemType(
|
|
HWND hwndTree,
|
|
HTREEITEM hItem
|
|
);
|
|
|
|
BOOL
|
|
RemoveLayer(
|
|
PDATABASE pDataBase,
|
|
PLAYER_FIX pLayerToRemove,
|
|
HTREEITEM* pHItem
|
|
);
|
|
|
|
void
|
|
DoTheCut(
|
|
PDATABASE pDataBase,
|
|
TYPE type,
|
|
SOURCE_TYPE SourceType,
|
|
LPVOID lpData, // To be removed
|
|
HTREEITEM hItem,
|
|
BOOL bDelete
|
|
);
|
|
|
|
BOOL
|
|
RemoveApp(
|
|
PDATABASE pDataBase,
|
|
PDBENTRY pApp
|
|
);
|
|
|
|
void
|
|
RemoveAllApps(
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
void
|
|
RemoveAllLayers(
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
DWORD
|
|
WIN_MSG(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
CheckForSDB(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
PasteMultipleLayers(
|
|
PDATABASE pDataBaseTo
|
|
);
|
|
|
|
BOOL
|
|
PasteShimsFlags(
|
|
PDATABASE pDataBaseTo
|
|
);
|
|
|
|
BOOL
|
|
PasteMultipleApps(
|
|
PDATABASE pDataBaseTo
|
|
);
|
|
|
|
void
|
|
ListViewSelectAll(
|
|
HWND hwndList
|
|
);
|
|
|
|
void
|
|
ListViewInvertSelection(
|
|
HWND hwndList
|
|
);
|
|
|
|
BOOL
|
|
DeleteMatchingFile(
|
|
PMATCHINGFILE* ppMatchFirst,
|
|
PMATCHINGFILE pMatchToDelete,
|
|
HWND hwndTree,
|
|
HTREEITEM hItem
|
|
);
|
|
|
|
BOOL
|
|
CheckInstalled(
|
|
PCTSTR szPath,
|
|
PCTSTR szGUID
|
|
);
|
|
|
|
void
|
|
SetStatus(
|
|
PCTSTR pszMessage
|
|
);
|
|
|
|
void
|
|
SetStatus(
|
|
INT iCode
|
|
);
|
|
|
|
|
|
void
|
|
SetStatusStringDBTree(
|
|
HTREEITEM hItem
|
|
);
|
|
|
|
void
|
|
SetStatusStringEntryTree(
|
|
HTREEITEM hItem
|
|
);
|
|
|
|
void
|
|
GetDescriptionString(
|
|
LPARAM lParam,
|
|
CSTRING& strDesc,
|
|
HWND hwndToolTip,
|
|
PCTSTR pszCaption = NULL,
|
|
HTREEITEM hItem = NULL,
|
|
HWND hwnd = NULL,
|
|
INT iIndexListView = -1
|
|
);
|
|
|
|
BOOL
|
|
SaveDisplaySettings(
|
|
void
|
|
);
|
|
|
|
UINT
|
|
GetAppEntryCount(
|
|
PDBENTRY pEntry
|
|
);
|
|
|
|
void
|
|
AddToMRU(
|
|
CSTRING& strPath
|
|
);
|
|
|
|
TCHAR*
|
|
FormatMRUString(
|
|
PCTSTR pszPath,
|
|
INT iIndex,
|
|
PTSTR szRetPath,
|
|
UINT cchRetPath
|
|
);
|
|
|
|
void
|
|
RefreshMRUMenu(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
LoadDataBase(
|
|
TCHAR* szPath
|
|
);
|
|
|
|
INT
|
|
GetLayerCount(
|
|
LPARAM lp,
|
|
TYPE type
|
|
);
|
|
INT
|
|
GetPatchCount(
|
|
LPARAM lp,
|
|
TYPE type
|
|
);
|
|
|
|
BOOL
|
|
GetFileContents(
|
|
PCTSTR pszFileName,
|
|
PWSTR* ppwszFileContents
|
|
);
|
|
|
|
INT
|
|
GetShimFlagCount(
|
|
LPARAM lp,
|
|
TYPE type
|
|
);
|
|
|
|
INT
|
|
GetMatchCount(
|
|
PDBENTRY pEntry
|
|
);
|
|
|
|
LPWSTR
|
|
GetNextLine(
|
|
LPWSTR pwszBuffer
|
|
);
|
|
|
|
INT
|
|
Atoi(
|
|
PCTSTR pszStr,
|
|
BOOL* bValid
|
|
);
|
|
|
|
BOOL
|
|
CheckIfInstalledDB(
|
|
PCTSTR szGuid
|
|
);
|
|
|
|
BOOL
|
|
CheckIfContains(
|
|
PCTSTR pszString,
|
|
PTSTR pszMatch
|
|
);
|
|
|
|
INT
|
|
ShowMainEntries(
|
|
HWND hdlg
|
|
);
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
HandleConflictEntry(
|
|
HWND hdlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
BOOL
|
|
IsUnique(
|
|
PDATABASE pDatabase,
|
|
PCTSTR szName,
|
|
UINT uType
|
|
);
|
|
|
|
PTSTR
|
|
GetUniqueName(
|
|
PDATABASE pDatabase,
|
|
PCTSTR szExistingName,
|
|
PTSTR szBuffer,
|
|
INT cchBuffer,
|
|
TYPE type
|
|
);
|
|
|
|
BOOL
|
|
NotCompletePath(
|
|
PCTSTR pszFileName
|
|
);
|
|
|
|
void
|
|
TreeDeleteAll(
|
|
HWND hwndTree
|
|
);
|
|
void
|
|
AddSingleEntry(
|
|
HWND hwndTree,
|
|
PDBENTRY pEntry
|
|
);
|
|
|
|
BOOL
|
|
FormatDate(
|
|
PSYSTEMTIME pSysTime,
|
|
TCHAR* szDate,
|
|
UINT cchDate
|
|
);
|
|
|
|
void
|
|
TrimLeadingSpaces(
|
|
LPCWSTR& pwsz
|
|
);
|
|
|
|
void
|
|
TrimTrailingSpaces(
|
|
LPWSTR pwsz
|
|
);
|
|
|
|
LPWSTR GetNextToken(
|
|
LPWSTR pwsz
|
|
);
|
|
|
|
PDBENTRY
|
|
GetAppForEntry(
|
|
PDATABASE pDatabase,
|
|
PDBENTRY pEntryToCheck
|
|
);
|
|
|
|
void
|
|
SetStatus(
|
|
HWND hwndStatus,
|
|
PCTSTR pszMessage
|
|
);
|
|
|
|
void
|
|
SetStatus(
|
|
HWND hwndStatus,
|
|
INT iCode
|
|
);
|
|
void
|
|
UpdateEntryTreeView(
|
|
PDBENTRY pEntry,
|
|
HWND hwndTree
|
|
);
|
|
|
|
void
|
|
GetDescription(
|
|
HWND hwndTree,
|
|
HTREEITEM hItem,
|
|
LPARAM itemlParam,
|
|
CSTRING& strDesc
|
|
);
|
|
|
|
BOOL
|
|
AppendEvent(
|
|
INT iType,
|
|
TCHAR* szTimestamp,
|
|
TCHAR* szMsg,
|
|
BOOL bAddToFile = FALSE
|
|
);
|
|
|
|
PSHIM_FIX_LIST
|
|
IsLUARedirectFSPresent(
|
|
PDBENTRY pEntry
|
|
);
|
|
|
|
BOOL
|
|
GetDbGuid(
|
|
OUT TCHAR* pszGuid,
|
|
IN INT cchpszGuid,
|
|
IN PDB pdb
|
|
);
|
|
|
|
BOOL
|
|
LookUpEntryProperties(
|
|
PDB pdb,
|
|
TAGID tiExe,
|
|
BOOL* pbLayers,
|
|
BOOL* pbShims,
|
|
BOOL* pbPatches,
|
|
BOOL* pbFlags,
|
|
BOOL* pbAppHelp,
|
|
CSTRING& strAppName
|
|
);
|
|
|
|
void
|
|
UpdateControls(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
ShimFlagExistsInLayer(
|
|
LPVOID lpData,
|
|
PLAYER_FIX plf,
|
|
TYPE type
|
|
);
|
|
|
|
BOOL
|
|
IsShimInlayer(
|
|
PLAYER_FIX plf,
|
|
PSHIM_FIX psf,
|
|
CSTRING* pstrCommandLine,
|
|
CSTRINGLIST* pstrlInEx
|
|
);
|
|
|
|
BOOL
|
|
IsFlagInlayer(
|
|
PLAYER_FIX plf,
|
|
PFLAG_FIX pff,
|
|
CSTRING* pstrCommandLine
|
|
);
|
|
|
|
int CALLBACK
|
|
CompareItemsEx(
|
|
LPARAM lParam1,
|
|
LPARAM lParam2,
|
|
LPARAM lParam
|
|
);
|
|
|
|
void
|
|
PreprocessForSaveAs(
|
|
PDATABASE pDatabase
|
|
);
|
|
|
|
BOOL
|
|
SaveListViewToFile(
|
|
HWND hwndList,
|
|
INT iCols,
|
|
PCTSTR pszFile,
|
|
PCTSTR pszHeader
|
|
);
|
|
|
|
BOOL
|
|
IsShimInEntry(
|
|
PCTSTR szShimName,
|
|
PDBENTRY pEntry
|
|
);
|
|
|
|
void
|
|
ShowShimLog(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
ReplaceChar(
|
|
PTSTR pszString,
|
|
TCHAR chCharToFind,
|
|
TCHAR chReplaceBy
|
|
);
|
|
|
|
int
|
|
CDECL
|
|
MSGF(
|
|
HWND hwndParent,
|
|
PCTSTR pszCaption,
|
|
UINT uType,
|
|
PCTSTR pszFormat,
|
|
...
|
|
);
|
|
|
|
void
|
|
Dbg(DEBUGLEVEL debugLevel,
|
|
LPSTR pszFmt
|
|
...);
|
|
|
|
BOOL
|
|
GetDatabaseEntries(
|
|
LPCTSTR szFullPath,
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
|
|
BOOL ReadMainDataBase();
|
|
|
|
BOOL SaveDataBase(
|
|
PDATABASE pDataBase,
|
|
CSTRING& strFileName);
|
|
|
|
LPVOID
|
|
FindFix(
|
|
PCTSTR pszFixName,
|
|
TYPE fixType,
|
|
PDATABASE pDataBase = NULL
|
|
);
|
|
|
|
|
|
BOOL
|
|
GetFileName(
|
|
HWND hWnd,
|
|
LPCTSTR szTitle,
|
|
LPCTSTR szFilter,
|
|
LPCTSTR szDefaultFile,
|
|
LPCTSTR szDefExt,
|
|
DWORD dwFlags,
|
|
BOOL bOpen,
|
|
CSTRING& szStr,
|
|
BOOL bDoNotVerifySDB = FALSE
|
|
);
|
|
|
|
BOOL
|
|
TestRun(
|
|
PDBENTRY pEntry,
|
|
CSTRING* pszFile,
|
|
CSTRING* pszCommandLine,
|
|
HWND hwndParent,
|
|
CSTRINGLIST* strlXML = NULL
|
|
);
|
|
|
|
UINT
|
|
LookupFileImage(
|
|
HIMAGELIST g_hImageList,
|
|
LPCTSTR szFilename,
|
|
UINT uDefault,
|
|
UINT* puArray,
|
|
UINT uArrayCount // No. of elements it can hold
|
|
);
|
|
|
|
BOOL
|
|
InvokeCompiler(
|
|
CSTRING& szInCommandLine
|
|
);
|
|
|
|
BOOL
|
|
GetXML(
|
|
PDBENTRY pEntry,
|
|
BOOL bComplete, // Save just this entry or all entries following this.
|
|
CSTRINGLIST* strlXML,
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
VOID
|
|
FormatVersion(
|
|
ULONGLONG ullBinVer,
|
|
PTSTR pszText,
|
|
INT chBuffSize
|
|
);
|
|
|
|
BOOL
|
|
SaveDataBaseAs(
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
|
|
BOOL
|
|
SetDisabledStatus(
|
|
HKEY hKeyRoot,
|
|
PCTSTR pszGuid,
|
|
BOOL bDisable
|
|
);
|
|
|
|
BOOL
|
|
RemoveEntry(
|
|
PDATABASE pDataBase,
|
|
PDBENTRY pEntryToRemove,
|
|
PDBENTRY pApp,
|
|
BOOL bRepaint = TRUE
|
|
);
|
|
|
|
void
|
|
SetCaption(
|
|
BOOL bIncludeDataBaseName = TRUE,
|
|
PDATABASE pDataBase = NULL,
|
|
BOOL bOnlyTreeItem = FALSE
|
|
);
|
|
|
|
void
|
|
InsertColumnIntoListView(
|
|
HWND hWnd,
|
|
LPTSTR lpszColumn,
|
|
INT iCol,
|
|
DWORD widthPercent
|
|
);
|
|
|
|
BOOL
|
|
InstallDatabase(
|
|
CSTRING& strPath,
|
|
PCTSTR szOptions,
|
|
BOOL bShowDialog
|
|
);
|
|
|
|
void
|
|
FlushCache(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
DeleteAppHelp(
|
|
PDATABASE pDatabase,
|
|
DWORD nHelpID
|
|
);
|
|
|
|
void
|
|
CenterWindow(
|
|
HWND hParent,
|
|
HWND hWnd
|
|
);
|
|
BOOL
|
|
CheckIfConflictingEntry(
|
|
PDATABASE pDataBase,
|
|
PDBENTRY pEntry,
|
|
PDBENTRY pEntryBeingEdited,
|
|
PDBENTRY* ppEntryFound = NULL,
|
|
PDBENTRY* ppAppFound = NULL
|
|
);
|
|
|
|
PDBENTRY
|
|
AddExeInApp(
|
|
PDBENTRY pEntry,
|
|
BOOL* pbNew,
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
|
|
BOOL
|
|
CloseDataBase(
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
BOOL
|
|
CheckAndSave(
|
|
PDATABASE pDataBase
|
|
);
|
|
|
|
void
|
|
EnableTabBackground(
|
|
HWND hDlg
|
|
);
|
|
|
|
|
|
void
|
|
TreeDeleteAll(
|
|
HWND hwndTree
|
|
);
|
|
|
|
BOOL
|
|
CloseAllDatabases(
|
|
void
|
|
);
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
HandlePromptLayer(
|
|
HWND hdlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
HandleConflictAppLayer(
|
|
HWND hdlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
BOOL
|
|
PasteSingleEntry(
|
|
PDBENTRY pEntryToPaste,
|
|
PDATABASE pDataBaseTo
|
|
);
|
|
|
|
BOOL
|
|
PasteAllApps(
|
|
PDATABASE pDataBaseTo
|
|
);
|
|
|
|
INT
|
|
PasteSingleApp(
|
|
PDBENTRY pApptoPaste,
|
|
PDATABASE pDataBaseTo,
|
|
PDATABASE pDataBaseFrom,
|
|
BOOL bAllExes,
|
|
PCTSTR szNewAppName = NULL
|
|
);
|
|
|
|
BOOL
|
|
PasteAllLayers(
|
|
PDATABASE pDataBaseTo
|
|
);
|
|
|
|
INT
|
|
PasteLayer(
|
|
PLAYER_FIX plf,
|
|
PDATABASE pDataBaseTo,
|
|
BOOL bForcePaste = FALSE,
|
|
OUT PLAYER_FIX* pplfNewInserted = NULL,
|
|
BOOL bShow = FALSE
|
|
);
|
|
|
|
BOOL
|
|
PasteAppHelpMessage(
|
|
PAPPHELP pAppHelp,
|
|
PDATABASE pDataBaseTo,
|
|
PAPPHELP* ppAppHelpInLib = NULL
|
|
);
|
|
|
|
INT
|
|
Tokenize(
|
|
PCTSTR szString,
|
|
INT cchLength,
|
|
PCTSTR szDelims,
|
|
CSTRINGLIST& strlTokens
|
|
);
|
|
|
|
INT
|
|
CopyShimFixList(
|
|
PSHIM_FIX_LIST* ppsflDest,
|
|
PSHIM_FIX_LIST* ppsflSrc
|
|
);
|
|
|
|
void
|
|
ShowInlineHelp(
|
|
LPCTSTR pszInlineHelpHtmlFile
|
|
);
|
|
|
|
PTSTR
|
|
GetSpace(
|
|
PTSTR pszSpace,
|
|
INT iSpaces,
|
|
INT iBufSzie
|
|
);
|
|
|
|
BOOL
|
|
ValidInput(
|
|
PCTSTR pszStr
|
|
);
|
|
|
|
PDATABASE
|
|
GetCurrentDB(
|
|
void
|
|
);
|
|
|
|
BOOL
|
|
IsValidAppName(
|
|
PCTSTR pszAppName
|
|
);
|
|
|
|
void
|
|
DisplayInvalidAppNameMessage(
|
|
HWND hdlg
|
|
);
|
|
|
|
#endif // _COMPATADMIN_H
|
|
|