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

304 lines
7.1 KiB

//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 2001.
//
// File: msiclass.h
//
// Contents: msi class collection abstraction
//
// Classes:
//
//
// History: 4-14-2000 adamed Created
//
//---------------------------------------------------------------------------
#if !defined(__MSICLASS_H__)
#define __MSICLASS_H__
//
// MSI Tables containing classes
//
#define TABLE_FILE_EXTENSIONS L"Extension"
#define TABLE_CLSIDS L"Class"
#define TABLE_PROGIDS L"ProgId"
//
// Package metadata queries
//
//
// Property table queries -- used to find out global information about the package
//
//
// This query is used to determine the package's global install level
//
#define QUERY_INSTALLLEVEL L"SELECT DISTINCT `Value` FROM `Property` WHERE `Property`=\'INSTALLLEVEL\'"
// This query is used to determine the package's friendly name
//
#define QUERY_FRIENDLYNAME L"SELECT DISTINCT `Value` FROM `Property` WHERE `Property`=\'ProductName\'"
//
// Feature table queries -- these are used to find out which features will be
// advertised so that we can later determine if the classes associated with the
// features should be advertised
//
//
// This query is less a query and more a modification operation. It adds an additional
// temporary "_IsAdvertised" column to the table. We use this to perform joins in
// subsequent queries.
//
#define QUERY_ADVERTISED_FEATURES_CREATE L"ALTER TABLE `Feature` ADD `_IsAdvertised` INT TEMPORARY HOLD"
//
// Again, this query really serves as a modification operation. This one initializes the
// temporary "_IsAdvertised" column to 0, which in our parlance is the same as initializing
// the column to "not advertised."
//
#define QUERY_ADVERTISED_FEATURES_INIT L"UPDATE `Feature` SET `_IsAdvertised`=0"
//
// This is a conventional query -- this returns all the features in the package
//
#define QUERY_ADVERTISED_FEATURES_RESULT L"SELECT `Feature`, `Level`, `Attributes` FROM `Feature`"
//
// Another modification query -- this eliminates the temporary changes (the additional
// column) we made to the table in the create query.
//
#define QUERY_ADVERTISED_FEATURES_DESTROY L"ALTER TABLE `Feature` FREE"
//
// The last modification query -- this allows us to set a particular feature's "_IsAdvertised"
// column to 1, which will indicate that the feature should be advertised.
//
#define QUERY_FEATURES_SET L"UPDATE `Feature` SET `_IsAdvertised`=1 WHERE `Feature`=?"
//
// Classes queries -- retrieves file extensions, clsid's, and progid's of the package
//
//
// The rest of these queries are straightforward "read-only" queries. They are all joins
// to the feature table, requiring that the feature table's "_IsAdvertised" property
// is set to the advertised state (1). Thus, these queries will only give us classes that
// should be advertised
//
//
// File extensions query
//
#define QUERY_EXTENSIONS L"SELECT DISTINCT `Extension` FROM `Extension`, `Feature` WHERE `Extension` IS NOT NULL " \
L"AND `Extension`.`Feature_`=`Feature`.`Feature` AND `Feature`.`_IsAdvertised`=1"
//
// Clsid query
//
#define QUERY_CLSIDS L"SELECT DISTINCT `CLSID`, `Context`, `Component`.`Attributes` FROM `Class`, `Feature`, " \
L"`Component` WHERE `CLSID` IS NOT NULL AND `Class`.`Feature_`=`Feature`.`Feature` " \
L"AND `Feature`.`_IsAdvertised`=1 AND `Component`.`Component`=`Class`.`Component_`"
//
// ProgId query
//
#define QUERY_VERSION_INDEPENDENT_PROGIDS L"SELECT DISTINCT `ProgId`,`CLSID` FROM `ProgId`, `Class`, `Feature` WHERE `ProgId` IS NOT NULL " \
L"AND `ProgId`.`Class_`=`Class`.`CLSID` AND `Class`.`Feature_`=`Feature`.`Feature` " \
L"AND `Feature`.`_IsAdvertised`=1"
//
// COM clsctx values as they are stored in the package's class (clsid) table
//
#define COM_INPROC_CONTEXT L"InprocServer32"
#define COM_INPROCHANDLER_CONTEXT L"InprocHandler32"
#define COM_LOCALSERVER_CONTEXT L"LocalServer32"
#define COM_REMOTESERVER_CONTEXT L"RemoteServer"
//
// MSI attribute flags
//
#define MSI_64BIT_CLASS msidbComponentAttributes64bit
#define MSI_DISABLEADVERTISE msidbFeatureAttributesDisallowAdvertise
#define CLASS_ALLOC_SIZE 256
//
// Indices of colums for each read-only query
//
enum
{
PROPERTY_COLUMN_VALUE = 1
};
enum
{
FEATURE_COLUMN_FEATURE = 1,
FEATURE_COLUMN_LEVEL,
FEATURE_COLUMN_ATTRIBUTES
};
enum
{
EXTENSION_COLUMN_EXTENSION = 1
};
enum
{
CLSID_COLUMN_CLSID = 1,
CLSID_COLUMN_CONTEXT,
CLSID_COLUMN_ATTRIBUTES
};
enum
{
PROGID_COLUMN_PROGID = 1,
PROGID_COLUMN_CLSID
};
enum
{
TYPE_EXTENSION,
TYPE_CLSID,
TYPE_PROGID,
TYPE_COUNT
};
//
// Structure describing where to write an atom
// of class information. It is also used as
// an intermediate scratch pad by CClassCollection
// in between private method calls to keep track
// of when and where to allocate new memory
// for retrieved classes.
//
struct DataDestination
{
DataDestination(
DWORD dwType,
void** prgpvDestination,
UINT* pcCurrent,
UINT* pcMax);
DWORD _cbElementSize;
UINT* _pcCurrent;
UINT* _pcMax;
void** _ppvData;
};
//
// Class that uses queries to create a collection of
// a package's class data
//
class CClassCollection
{
public:
CClassCollection( PACKAGEDETAIL* pPackageDetail );
HRESULT
GetClasses( BOOL bFileExtensionsOnly );
private:
LONG
GetClsids();
LONG
GetProgIds();
LONG
GetExtensions();
LONG
GetElements(
DWORD dwType,
DataDestination* pDestination);
LONG
FlagAdvertisableFeatures();
LONG
RemoveAdvertisableFeatureFlags();
LONG
GetInstallLevel();
LONG
GetFriendlyName();
LONG
GetFeatureAdvertiseState(
CMsiRecord* pFeatureRecord,
BOOL* pbAdvertised );
LONG
AddElement(
void* pvDataSource,
DataDestination* pDataDestination);
LONG
ProcessElement(
DWORD dwType,
CMsiRecord* pRecord,
DataDestination* pDataDestination);
LONG
ProcessExtension(
CMsiRecord* pRecord,
WCHAR** ppwszExtension);
LONG
ProcessClsid(
CMsiRecord* pRecord,
CLASSDETAIL* pClsid,
BOOL* pbIgnoreClsid);
LONG
ProcessProgId(
CMsiRecord* pRecord,
DataDestination* pDataDestination,
WCHAR** ppwszProgId);
LONG
FindClass(
WCHAR* wszClsid,
CLASSDETAIL** ppClass );
void
FreeClassDetail( CLASSDETAIL* pClass );
CMsiDatabase _Database;
PACKAGEDETAIL* _pPackageDetail;
DWORD _cMaxClsids;
DWORD _cMaxExtensions;
UINT _InstallLevel;
static WCHAR* _wszQueries[ TYPE_COUNT ];
};
#endif // __MSICLASS_H__