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.
 
 
 
 
 
 

296 lines
8.8 KiB

//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 2001.
//
// File: msibase.h
//
// Contents: msi database abstractions
//
// History: 4-14-2000 adamed Created
//
//---------------------------------------------------------------------------
#if !defined(__MSIBASE_H__)
#define __MSIBASE_H__
//
// Module Notes
//
// Class Relational Overview
//
// Below we describe how the classes declared in this module
// relate to each other -- the --> notation indicates the "yields" relation:
//
// - A path to an MSI package --> CMsiDatabase: A path to an MSI package, along
// with a set of transforms, can be used to instantiate a CMsiDatabase
// object that abstracts the package with a database style view.
//
// - CMsiDatabase --> CMsiQuery: a CMsiDatabase allows one to retrieve
// queries against the database (MSI package).
//
// - CMsiQuery --> CMsiRecord: a CMsiQuery allows one to retrieve or
// alter records that are part of the results of the msi database query.
//
// - CMsiRecord --> CMsiValue: a CMsiValue allows the retrieval of
// individual values of an MSI database record.
//
// -CMsiState is a base class for the classes above that maintain
// MSI database engine state (e.g. msi handles) -- this class
// has no direct utility to classes outside this module
//
//-------------------------------------------------------------------------------------
//
// Class sequential Overview:
//
// The following sequence is typical of the use of the classes envisioned
// in the design of this module:
//
// 1. CMsiDatabase: Instantiate a CMsiDatabase object, and call its Open method
// in order to get a database view of a particular package.
// 2. CMsiQuery: Use the GetQueryResults method to place the results of a query into
// a CMsiQuery which was passed into the call as an out parameter,
// or use the OpenQuery method to start a query without retrieving results
// immediately (they can be retrieved later). The latter is useful
// when performing queries that need to update a single record -- you
// use OpenQuery with a query string that allows the results records to be changed,
// then call the UpdateQueryFromFilter method of CMsiQuery in order to
// alter a record.
// 3. CMsiRecord: Use the GetNextRecord methods of CMsiQuery to retrieve a
// CMsiRecord that represents a record from the query.
// 4. CMsiValue: Use the GetValue method of CMsiRecord to retrieve a particular
// value of the msi record.
//
//
// For information on the individual methods of each class, please see the source
// file where the methods are implemented.
//
#if defined(DBG)
#define DEFAULT_STRING_SIZE 16
#else // defined(DBG)
#define DEFAULT_STRING_SIZE 256
#endif // defined(DBG)
//+--------------------------------------------------------------------------
//
// Class: CMsiState
//
// Synopsis: class that encapsulates an msi handle. It ensures that
// the handle is freed when instances of the class are destroyed.
//
// Notes: this class is generally only needed by classes in this module --
// it has no useful methods for classes outside this module
//
//---------------------------------------------------------------------------
class CMsiState
{
public:
CMsiState();
~CMsiState();
void
SetState( MSIHANDLE pMsiHandle );
MSIHANDLE
GetState();
private:
MSIHANDLE _MsiHandle;
};
//+--------------------------------------------------------------------------
//
// Class: CMsiValue
//
// Synopsis: Class that encapsulates values that can be returned by
// a record of an msi database. It ensures that resources (e.g. memory)
// associated with instances of the class are freed when the class is
// destroyed. It also attempts to avoid heap allocation in favor of
// stack allocation when possible -- this is abstracted from the consumer
//
// Notes: This class is designed to be used as follows:
// 1. Declare an instance of this class on the stack
// 2. Pass a reference to the instance to a function which takes
// a reference to this class as an out parameter.
// 3. The function that is called will "fill in" the value using
// the Set methods of this class.
// 4. The caller may then use Get methods to retrieve the value
// in a useful form (such as DWORD or WCHAR*).
//
//---------------------------------------------------------------------------
class CMsiValue
{
public:
enum
{
TYPE_NOT_SET,
TYPE_DWORD,
TYPE_STRING
};
CMsiValue();
~CMsiValue();
DWORD
GetDWORDValue();
WCHAR*
GetStringValue();
DWORD
GetStringSize();
WCHAR*
DuplicateString();
void
SetDWORDValue( DWORD dwValue );
LONG
SetStringValue( WCHAR* wszValue );
LONG
SetStringSize( DWORD cchSize );
void
SetType( DWORD dwType );
private:
WCHAR _wszDefaultBuf[DEFAULT_STRING_SIZE];
DWORD _dwDiscriminant;
WCHAR* _wszValue;
DWORD _cchSize;
DWORD _dwValue;
};
//+--------------------------------------------------------------------------
//
// Class: CMsiRecord
//
// Synopsis: Class that encapsulates msi database records. It ensures
// that any state (e.g. msi handle) associated with an instance of
// this class will be freed when the instance is destroyed.
//
// Notes: This class is designed to be used as follows:
// 1. Declare an instance of this class on the stack
// 2. Pass a reference to the instance to a function which takes
// a reference to this class as an out parameter.
// 3. The function that is called will "fill in" the value using
// the SetState method of this class.
// 4. The caller may then use the GetValue method to retrieve individual
// values of the record, which in turn may be converted into
// concrete data types (see the CMsiValue class).
//
//---------------------------------------------------------------------------
class CMsiRecord : public CMsiState
{
public:
LONG
GetValue(
DWORD dwType,
DWORD dwValue,
CMsiValue* pMsiValue);
};
//+--------------------------------------------------------------------------
//
// Class: CMsiQuery
//
// Synopsis: Class that encapsulates msi database queries. It ensures
// that any state (e.g. msi handle) associated with an instance of
// this class will be freed when the instance is destroyed.
//
// Notes: This class is designed to be used as follows:
// 1. Declare an instance of this class on the stack
// 2. Pass a reference to the instance to a function which takes
// a reference to this class as an out parameter.
// 3. The function that is called will "fill in" the value using
// the SetState method of this class.
// 4. The caller may then use the GetNextRecord method to retrieve a
// record from the results of the query, or use the
// UpdateQueryFromFilter method to alter one of the records in
// the query.
//
//---------------------------------------------------------------------------
class CMsiQuery : public CMsiState
{
public:
LONG
GetNextRecord( CMsiRecord* pMsiRecord );
LONG
UpdateQueryFromFilter( CMsiRecord* pFilterRecord );
};
//+--------------------------------------------------------------------------
//
// Class: CMsiDatabase
//
// Synopsis: Class that an msi database (package). It ensures
// that any state (e.g. msi handle) associated with an instance of
// this class will be freed when the instance is destroyed.
//
// Notes: This class is designed to be used as follows:
// 1. Create an instance of this class
// 2. Use the Open method to gain access to a package + set of transforms
// as a database that can be queried
// 3. To create and retrieve results of a query on an opened database,
// Use the GetQueryResults method
// 4. To create a query (but not retrieve its results), use the OpenQuery
// method. This is useful with when the query's UpdateQueryFromFilter
// method is used to change an individual record, rather than retrieving
// a result set (a la GetQueryResults).
//
//---------------------------------------------------------------------------
class CMsiDatabase : public CMsiState
{
public:
LONG
Open(
WCHAR* wszPath,
DWORD cTransforms,
WCHAR** rgwszTransforms);
LONG
GetQueryResults(
WCHAR* wszQuery,
CMsiQuery* pQuery );
LONG
OpenQuery(
WCHAR* wszQuery,
CMsiQuery* pQuery);
LONG
TableExists(
WCHAR* wszTableName,
BOOL* pbTableExists );
};
#endif // __MSIBASE_H__