windows-nt/Source/XPSP1/NT/shell/themes/inc/loader.h
2020-09-26 16:20:57 +08:00

336 lines
13 KiB
C++

//---------------------------------------------------------------------------
// Loader.h - loads the theme data into shared memory
//---------------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------------
#include "Parser.h"
#include "TmSchema.h"
#include "ThemeFile.h"
//---------------------------------------------------------------------------
#define THEMEDATA_VERSION 0x00010006
//---------------------------------------------------------------------------
#define TM_FONTCOUNT (TMT_LASTFONT - TMT_FIRSTFONT + 1)
#define TM_SIZECOUNT (TMT_LASTSIZE - TMT_FIRSTSIZE + 1)
#define TM_BOOLCOUNT (TMT_LASTBOOL - TMT_FIRSTBOOL + 1)
#define TM_STRINGCOUNT (TMT_LASTSTRING - TMT_FIRSTSTRING + 1)
#define TM_INTCOUNT (TMT_LASTINT - TMT_FIRSTINT + 1)
//---------------------------------------------------------------------------
class CRenderObj; // forward
class CImageFile; // forward
struct DIBINFO; // forward
//---------------------------------------------------------------------------
struct THEMEMETRICS
{
//---- subset of system metrics ----
LOGFONT lfFonts[TM_FONTCOUNT];
COLORREF crColors[TM_COLORCOUNT];
int iSizes[TM_SIZECOUNT];
BOOL fBools[TM_BOOLCOUNT];
//---- special theme metrics ----
int iStringOffsets[TM_STRINGCOUNT];
int iInts[TM_INTCOUNT];
};
//---------------------------------------------------------------------------
struct LOADTHEMEMETRICS : THEMEMETRICS
{
CWideString wsStrings[TM_STRINGCOUNT];
};
//---------------------------------------------------------------------------
// Signatures for quick cache file validation
const CHAR kszBeginCacheFileSignature[] = "BEGINTHM";
const CHAR kszEndCacheFileSignature[] = "ENDTHEME";
const UINT kcbBeginSignature = sizeof kszBeginCacheFileSignature - 1;
const UINT kcbEndSignature = sizeof kszEndCacheFileSignature - 1;
//---------------------------------------------------------------------------
// Theme section flags
#define SECTION_READY 1
#define SECTION_GLOBAL 2
#define SECTION_HASSTOCKOBJECTS 4
//---------------------------------------------------------------------------
struct THEMEHDR
{
//---- theme validity ----
CHAR szSignature[kcbBeginSignature]; // "BEGINTHM"
DWORD dwVersion; // THEMEDATA_VERSION
DWORD dwFlags; // must have SECTION_READY to be usable
DWORD dwCheckSum; // byte-additive total of all bytes following THEMEHDR
FILETIME ftModifTimeStamp; // Last modification time of the .msstyles file
DWORD dwTotalLength; // total number of bytes of all data (incl. header & begin/end sigs)
//---- theme id ----
int iDllNameOffset; // dll filename of this theme
int iColorParamOffset; // color param theme was loaded with
int iSizeParamOffset; // size param theme was loaded with
DWORD dwLangID; // User lang ID theme was loaded with
int iLoadId; // sequential number for each loaded file (workstation local)
//---- main sections ----
DWORD iStringsOffset; // offset to strings
DWORD iStringsLength; // total bytes in string section
DWORD iSectionIndexOffset; // offset to Section Index
DWORD iSectionIndexLength; // length of section indexes
DWORD iGlobalsOffset; // offset to [globals] section (for globals parts)
DWORD iGlobalsTextObjOffset; // offset to text obj for [globals] section
DWORD iGlobalsDrawObjOffset; // offset to draw obj for [globals] section
DWORD iSysMetricsOffset; // offset to [SysMetrics] section (for theme metrics API support)
};
//---------------------------------------------------------------------------
struct DRAWOBJHDR // preceeds each draw obj
{
int iPartNum;
int iStateNum;
};
//---------------------------------------------------------------------------
struct RGNDATAHDR // preceeds each draw obj
{
int iPartNum;
int iStateNum;
int iFileIndex; // for multiple image selection (HDC scaling)
};
//---------------------------------------------------------------------------
// Shared Theme Data layout:
//
// // ----- header ----
// THEMEHDR ThemeHdr;
//
// // ----- string section ----
// DWORD dwStringsLength; // length of string section
// WCHAR []; // strings
//
// // ----- index section ----
// DWORD dwIndexLengh; // length of index section
// DWORD dwIndexCount; // count of APPCLASSLIVE entries
// APPCLASSLIVE [];
//
// // ----- theme data section ----
// DWORD dwDataLength; // length of theme data section
// BYTE []; // actual theme data
//
// // ----- end signature
// CHAR[8]; // ENDTHEME signature
//---------------------------------------------------------------------------
// A class section within the "theme data section" consists of the
// following ENTRYs:
//
// <part jump table>
//
// <optional state jump table>
// <property/value entries>
//
// for each packed drawobject:
//
// <TMT_RGNLIST entries> (associated with each DIB)
// <TMT_STOCKBRUSH entries> (associated with each DIB)
// <TMT_DRAWOBJ entry>
//
// <TMT_TEXTOBJ entries>
//
// <end of class marker>
//---------------------------------------------------------------------------
// an ENTRY consists of (all 1-byte aligned):
//
// WORD usTypeNum; // declared type id
// BYTE ePrimVal; // equiv. primitive type
// BYTE bFiller; // # of bytes added after data to align it
// DWORD dwDataLen; // includes filler bytes
// //---- entry data follows ----
//
//---------------------------------------------------------------------------
// The data for a part jump table ENTRY (TMT_PARTJUMPTABLE) consists of:
//
// <offset of first drawobj: long>
// <PartCount (1 + MaxPart): BYTE>
// <offset to each part's entries: long[]>
//---------------------------------------------------------------------------
// The data for a state jump table ENTRY (TMT_STATEJUMPTABLE) consists of:
//
// <StateCount (1 + MaxState): BYTE>
// <offset to each state's entries: long[]>
//---------------------------------------------------------------------------
// The data for a rgn list ENTRY (TMT_RGNLIST) consists of:
//
// <StateCount (1 + MaxState): BYTE>
// <offset to each state's custom rgn data: long[]>
//---------------------------------------------------------------------------
// The custom rgn data ENTRY (TMT_RGNDATA) consists of:
//
// RGNDATAHDR RgnDataHdr;
// BYTE Data[];
//---------------------------------------------------------------------------
// The TMT_STOCKBRUSHES ENTRY consists of:
//
// int iBrushCount; // number of brush slots (5*ImageCount)
// HBRUSHES hBrushes[iBrushCount];
//---------------------------------------------------------------------------
#define MAX_SHAREDMEM_SIZE (3000*1000) // 1.5 meg (yikes!)
//---------------------------------------------------------------------------
#ifdef _WIN64
#define ALIGN_FACTOR 8
#else
#define ALIGN_FACTOR 4
#endif
//---------------------------------------------------------------------------
#define MAX_ENTRY_NESTING 5 // max # of nested entry levels
//---------------------------------------------------------------------------
#define ENTRYHDR_SIZE (sizeof(SHORT) + sizeof(BYTE) + sizeof(BYTE) + sizeof(int))
//---------------------------------------------------------------------------
struct UNPACKED_ENTRYHDR // (hdr's in theme are PACKED)
{
WORD usTypeNum; // declared type id
BYTE ePrimVal; // equiv. primitive type
BYTE bFiller; // # of bytes added after data to align it
DWORD dwDataLen; // includes filler bytes
};
//---------------------------------------------------------------------------
inline void FillAndSkipHdr(MIXEDPTRS &u, UNPACKED_ENTRYHDR *pHdr)
{
pHdr->usTypeNum = *u.ps++;
pHdr->ePrimVal = *u.pb++;
pHdr->bFiller = *u.pb++;
pHdr->dwDataLen = *u.pi++;
}
//---------------------------------------------------------------------------
struct PART_STATE_INDEX
{
int iPartNum; // 0=parent part
int iStateNum;
int iIndex;
int iLen;
};
//---------------------------------------------------------------------------
struct APPCLASSLIVE
{
//---- note: cannot use ptrs since image shared by diff addr-mapping processes ----
DWORD dwAppNameIndex;
DWORD dwClassNameIndex;
int iIndex;
int iLen;
};
//---------------------------------------------------------------------------
struct APPCLASSLOCAL
{
CWideString csAppName;
CWideString csClassName;
int iMaxPartNum;
CSimpleArray<PART_STATE_INDEX> PartStateIndexes;
int iPackedSize; // total size of section (incl strings) if packed
APPCLASSLIVE LiveIndex; // updated during copy to live
};
//---------------------------------------------------------------------------
HRESULT InitThemeMetrics(LOADTHEMEMETRICS *tm);
void SetSystemMetrics(THEMEMETRICS *tm, BOOL fSyncLoad);
HRESULT PersistSystemColors(THEMEMETRICS *tm);
//---------------------------------------------------------------------------
class CThemeLoader : IParserCallBack
{
public:
CThemeLoader();
~CThemeLoader();
HRESULT LoadTheme(LPCWSTR pszThemeName, LPCWSTR pszColorParam,
LPCWSTR pszSizeParam, OUT HANDLE *pHandle, BOOL fGlobalTheme);
BOOL GetThemeName(LPTSTR NameBuff, int BuffSize);
HRESULT SetWindowThemeInfo(HWND hwnd, LPCWSTR pszThemeIdList);
HRESULT LoadClassDataIni(HINSTANCE hInst, LPCWSTR pszColorName,
LPCWSTR pszSizeName, LPWSTR pszFoundIniName, DWORD dwMaxIniNameChars, LPWSTR *ppIniData);
//---- IParserCallBack ----
HRESULT AddIndex(LPCWSTR pszAppName, LPCWSTR pszClassName,
int iPartNum, int iStateNum, int iIndex, int iLen);
HRESULT AddData(SHORT sTypeNum, PRIMVAL ePrimVal, const void *pData, DWORD dwLen);
int GetNextDataIndex();
protected:
//---- helpers ----
HRESULT PackAndLoadTheme(LPCWSTR pszThemeName, LPCWSTR pszColorParam,
LPCWSTR pszSizeParam, HINSTANCE hInst);
HRESULT CopyLocalThemeToLive(int iTotalLength, LPCWSTR pszThemeName,
LPCWSTR pszColorParam, LPCWSTR pszSizeParam);
void FreeLocalTheme();
HRESULT PackMetrics();
HRESULT PackThemeStructs();
BOOL KeyDrawPropertyFound(int iStateDataOffset);
BOOL KeyTextPropertyFound(int iStateDataOffset);
HRESULT PackDrawObject(MIXEDPTRS &u, CRenderObj *pRender, int iPartId, int iStateId);
HRESULT PackTextObject(MIXEDPTRS &u, CRenderObj *pRender, int iPartId, int iStateId);
HRESULT PackDrawObjects(MIXEDPTRS &u, CRenderObj *pRender, int iMaxPart, BOOL fGlobals);
HRESULT PackTextObjects(MIXEDPTRS &u, CRenderObj *pRender, int iMaxPart, BOOL fGlobals);
HRESULT CopyPartGroup(APPCLASSLOCAL *ac, MIXEDPTRS &u, int iPartNum,
int *piPartJumpTable, int iPartZeroIndex, int iGlobalsIndex, BOOL fGlobalsGroup);
int GetPartOffset(CRenderObj *pRender, int iPartNum);
HRESULT CopyClassGroup(APPCLASSLOCAL *ac, MIXEDPTRS &u, int iGlobalsIndex, int iClassNameOffset);
int GetMaxState(APPCLASSLOCAL *ac, int iPartNum);
HRESULT AddIndexInternal(LPCWSTR pszAppName, LPCWSTR pszClassName,
int iPartNum, int iStateNum, int iIndex, int iLen);
BOOL IndexExists(LPCWSTR pszAppName, LPCWSTR pszClassName,
int iPartNum, int iStateNum);
HRESULT AddMissingParent(LPCWSTR pszAppName, LPCWSTR pszClassName,
int iPartNum, int iStateNum);
HRESULT EmitEntryHdr(MIXEDPTRS &u, SHORT propnum, BYTE privnum);
int EndEntry(MIXEDPTRS &u);
HRESULT PackImageFileInfo(DIBINFO *pdi, CImageFile *pImageObj, MIXEDPTRS &u,
CRenderObj *pRender, int iPartId, int iStateId);
HRESULT AllocateThemeFileBytes(BYTE *upb, DWORD dwAdditionalLen);
// Helper functions to alloc and emit sized data
HRESULT EmitAndCopyBlock(MIXEDPTRS &u, void *pSrc, DWORD dwLen);
HRESULT EmitString(MIXEDPTRS &u, LPCWSTR pSrc, DWORD dwLen, int *piOffSet);
HRESULT EmitObject(MIXEDPTRS &u, SHORT propnum, BYTE privnum, void *pHdr, DWORD dwHdrLen, void *pObj, DWORD dwObjLen);
//---- private data ----
CWideString _wsThemeFileName;
int _iGlobalsOffset;
int _iSysMetricsOffset;
//---- ptrs to packed objs for [globals] section ----
int _iGlobalsTextObj; // we always create this obj
int _iGlobalsDrawObj; // we always create this obj
//---- local copy of theme data while being built ----
BYTE *_pbLocalData;
int _iLocalLen;
CSimpleArray<APPCLASSLOCAL> _LocalIndexes;
//---- used for updating entry hdrs ----
BYTE *_pbEntryHdrs[MAX_ENTRY_NESTING]; // points to current hdr
int _iEntryHdrLevel;
//---- shared memory copy of theme data ----
CUxThemeFile _LoadingThemeFile;
//---- theme metrics ----
LOADTHEMEMETRICS _LoadThemeMetrics;
//---- Global creation flag
BOOL _fGlobalTheme;
//---- Machine page size for VirtualAlloc optimization
DWORD _dwPageSize;
};
//---------------------------------------------------------------------------