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.

335 lines
13 KiB

  1. //---------------------------------------------------------------------------
  2. // Loader.h - loads the theme data into shared memory
  3. //---------------------------------------------------------------------------
  4. #pragma once
  5. //---------------------------------------------------------------------------
  6. #include "Parser.h"
  7. #include "TmSchema.h"
  8. #include "ThemeFile.h"
  9. //---------------------------------------------------------------------------
  10. #define THEMEDATA_VERSION 0x00010006
  11. //---------------------------------------------------------------------------
  12. #define TM_FONTCOUNT (TMT_LASTFONT - TMT_FIRSTFONT + 1)
  13. #define TM_SIZECOUNT (TMT_LASTSIZE - TMT_FIRSTSIZE + 1)
  14. #define TM_BOOLCOUNT (TMT_LASTBOOL - TMT_FIRSTBOOL + 1)
  15. #define TM_STRINGCOUNT (TMT_LASTSTRING - TMT_FIRSTSTRING + 1)
  16. #define TM_INTCOUNT (TMT_LASTINT - TMT_FIRSTINT + 1)
  17. //---------------------------------------------------------------------------
  18. class CRenderObj; // forward
  19. class CImageFile; // forward
  20. struct DIBINFO; // forward
  21. //---------------------------------------------------------------------------
  22. struct THEMEMETRICS
  23. {
  24. //---- subset of system metrics ----
  25. LOGFONT lfFonts[TM_FONTCOUNT];
  26. COLORREF crColors[TM_COLORCOUNT];
  27. int iSizes[TM_SIZECOUNT];
  28. BOOL fBools[TM_BOOLCOUNT];
  29. //---- special theme metrics ----
  30. int iStringOffsets[TM_STRINGCOUNT];
  31. int iInts[TM_INTCOUNT];
  32. };
  33. //---------------------------------------------------------------------------
  34. struct LOADTHEMEMETRICS : THEMEMETRICS
  35. {
  36. CWideString wsStrings[TM_STRINGCOUNT];
  37. };
  38. //---------------------------------------------------------------------------
  39. // Signatures for quick cache file validation
  40. const CHAR kszBeginCacheFileSignature[] = "BEGINTHM";
  41. const CHAR kszEndCacheFileSignature[] = "ENDTHEME";
  42. const UINT kcbBeginSignature = sizeof kszBeginCacheFileSignature - 1;
  43. const UINT kcbEndSignature = sizeof kszEndCacheFileSignature - 1;
  44. //---------------------------------------------------------------------------
  45. // Theme section flags
  46. #define SECTION_READY 1
  47. #define SECTION_GLOBAL 2
  48. #define SECTION_HASSTOCKOBJECTS 4
  49. //---------------------------------------------------------------------------
  50. struct THEMEHDR
  51. {
  52. //---- theme validity ----
  53. CHAR szSignature[kcbBeginSignature]; // "BEGINTHM"
  54. DWORD dwVersion; // THEMEDATA_VERSION
  55. DWORD dwFlags; // must have SECTION_READY to be usable
  56. DWORD dwCheckSum; // byte-additive total of all bytes following THEMEHDR
  57. FILETIME ftModifTimeStamp; // Last modification time of the .msstyles file
  58. DWORD dwTotalLength; // total number of bytes of all data (incl. header & begin/end sigs)
  59. //---- theme id ----
  60. int iDllNameOffset; // dll filename of this theme
  61. int iColorParamOffset; // color param theme was loaded with
  62. int iSizeParamOffset; // size param theme was loaded with
  63. DWORD dwLangID; // User lang ID theme was loaded with
  64. int iLoadId; // sequential number for each loaded file (workstation local)
  65. //---- main sections ----
  66. DWORD iStringsOffset; // offset to strings
  67. DWORD iStringsLength; // total bytes in string section
  68. DWORD iSectionIndexOffset; // offset to Section Index
  69. DWORD iSectionIndexLength; // length of section indexes
  70. DWORD iGlobalsOffset; // offset to [globals] section (for globals parts)
  71. DWORD iGlobalsTextObjOffset; // offset to text obj for [globals] section
  72. DWORD iGlobalsDrawObjOffset; // offset to draw obj for [globals] section
  73. DWORD iSysMetricsOffset; // offset to [SysMetrics] section (for theme metrics API support)
  74. };
  75. //---------------------------------------------------------------------------
  76. struct DRAWOBJHDR // preceeds each draw obj
  77. {
  78. int iPartNum;
  79. int iStateNum;
  80. };
  81. //---------------------------------------------------------------------------
  82. struct RGNDATAHDR // preceeds each draw obj
  83. {
  84. int iPartNum;
  85. int iStateNum;
  86. int iFileIndex; // for multiple image selection (HDC scaling)
  87. };
  88. //---------------------------------------------------------------------------
  89. // Shared Theme Data layout:
  90. //
  91. // // ----- header ----
  92. // THEMEHDR ThemeHdr;
  93. //
  94. // // ----- string section ----
  95. // DWORD dwStringsLength; // length of string section
  96. // WCHAR []; // strings
  97. //
  98. // // ----- index section ----
  99. // DWORD dwIndexLengh; // length of index section
  100. // DWORD dwIndexCount; // count of APPCLASSLIVE entries
  101. // APPCLASSLIVE [];
  102. //
  103. // // ----- theme data section ----
  104. // DWORD dwDataLength; // length of theme data section
  105. // BYTE []; // actual theme data
  106. //
  107. // // ----- end signature
  108. // CHAR[8]; // ENDTHEME signature
  109. //---------------------------------------------------------------------------
  110. // A class section within the "theme data section" consists of the
  111. // following ENTRYs:
  112. //
  113. // <part jump table>
  114. //
  115. // <optional state jump table>
  116. // <property/value entries>
  117. //
  118. // for each packed drawobject:
  119. //
  120. // <TMT_RGNLIST entries> (associated with each DIB)
  121. // <TMT_STOCKBRUSH entries> (associated with each DIB)
  122. // <TMT_DRAWOBJ entry>
  123. //
  124. // <TMT_TEXTOBJ entries>
  125. //
  126. // <end of class marker>
  127. //---------------------------------------------------------------------------
  128. // an ENTRY consists of (all 1-byte aligned):
  129. //
  130. // WORD usTypeNum; // declared type id
  131. // BYTE ePrimVal; // equiv. primitive type
  132. // BYTE bFiller; // # of bytes added after data to align it
  133. // DWORD dwDataLen; // includes filler bytes
  134. // //---- entry data follows ----
  135. //
  136. //---------------------------------------------------------------------------
  137. // The data for a part jump table ENTRY (TMT_PARTJUMPTABLE) consists of:
  138. //
  139. // <offset of first drawobj: long>
  140. // <PartCount (1 + MaxPart): BYTE>
  141. // <offset to each part's entries: long[]>
  142. //---------------------------------------------------------------------------
  143. // The data for a state jump table ENTRY (TMT_STATEJUMPTABLE) consists of:
  144. //
  145. // <StateCount (1 + MaxState): BYTE>
  146. // <offset to each state's entries: long[]>
  147. //---------------------------------------------------------------------------
  148. // The data for a rgn list ENTRY (TMT_RGNLIST) consists of:
  149. //
  150. // <StateCount (1 + MaxState): BYTE>
  151. // <offset to each state's custom rgn data: long[]>
  152. //---------------------------------------------------------------------------
  153. // The custom rgn data ENTRY (TMT_RGNDATA) consists of:
  154. //
  155. // RGNDATAHDR RgnDataHdr;
  156. // BYTE Data[];
  157. //---------------------------------------------------------------------------
  158. // The TMT_STOCKBRUSHES ENTRY consists of:
  159. //
  160. // int iBrushCount; // number of brush slots (5*ImageCount)
  161. // HBRUSHES hBrushes[iBrushCount];
  162. //---------------------------------------------------------------------------
  163. #define MAX_SHAREDMEM_SIZE (3000*1000) // 1.5 meg (yikes!)
  164. //---------------------------------------------------------------------------
  165. #ifdef _WIN64
  166. #define ALIGN_FACTOR 8
  167. #else
  168. #define ALIGN_FACTOR 4
  169. #endif
  170. //---------------------------------------------------------------------------
  171. #define MAX_ENTRY_NESTING 5 // max # of nested entry levels
  172. //---------------------------------------------------------------------------
  173. #define ENTRYHDR_SIZE (sizeof(SHORT) + sizeof(BYTE) + sizeof(BYTE) + sizeof(int))
  174. //---------------------------------------------------------------------------
  175. struct UNPACKED_ENTRYHDR // (hdr's in theme are PACKED)
  176. {
  177. WORD usTypeNum; // declared type id
  178. BYTE ePrimVal; // equiv. primitive type
  179. BYTE bFiller; // # of bytes added after data to align it
  180. DWORD dwDataLen; // includes filler bytes
  181. };
  182. //---------------------------------------------------------------------------
  183. inline void FillAndSkipHdr(MIXEDPTRS &u, UNPACKED_ENTRYHDR *pHdr)
  184. {
  185. pHdr->usTypeNum = *u.ps++;
  186. pHdr->ePrimVal = *u.pb++;
  187. pHdr->bFiller = *u.pb++;
  188. pHdr->dwDataLen = *u.pi++;
  189. }
  190. //---------------------------------------------------------------------------
  191. struct PART_STATE_INDEX
  192. {
  193. int iPartNum; // 0=parent part
  194. int iStateNum;
  195. int iIndex;
  196. int iLen;
  197. };
  198. //---------------------------------------------------------------------------
  199. struct APPCLASSLIVE
  200. {
  201. //---- note: cannot use ptrs since image shared by diff addr-mapping processes ----
  202. DWORD dwAppNameIndex;
  203. DWORD dwClassNameIndex;
  204. int iIndex;
  205. int iLen;
  206. };
  207. //---------------------------------------------------------------------------
  208. struct APPCLASSLOCAL
  209. {
  210. CWideString csAppName;
  211. CWideString csClassName;
  212. int iMaxPartNum;
  213. CSimpleArray<PART_STATE_INDEX> PartStateIndexes;
  214. int iPackedSize; // total size of section (incl strings) if packed
  215. APPCLASSLIVE LiveIndex; // updated during copy to live
  216. };
  217. //---------------------------------------------------------------------------
  218. HRESULT InitThemeMetrics(LOADTHEMEMETRICS *tm);
  219. void SetSystemMetrics(THEMEMETRICS *tm, BOOL fSyncLoad);
  220. HRESULT PersistSystemColors(THEMEMETRICS *tm);
  221. //---------------------------------------------------------------------------
  222. class CThemeLoader : IParserCallBack
  223. {
  224. public:
  225. CThemeLoader();
  226. ~CThemeLoader();
  227. HRESULT LoadTheme(LPCWSTR pszThemeName, LPCWSTR pszColorParam,
  228. LPCWSTR pszSizeParam, OUT HANDLE *pHandle, BOOL fGlobalTheme);
  229. BOOL GetThemeName(LPTSTR NameBuff, int BuffSize);
  230. HRESULT SetWindowThemeInfo(HWND hwnd, LPCWSTR pszThemeIdList);
  231. HRESULT LoadClassDataIni(HINSTANCE hInst, LPCWSTR pszColorName,
  232. LPCWSTR pszSizeName, LPWSTR pszFoundIniName, DWORD dwMaxIniNameChars, LPWSTR *ppIniData);
  233. //---- IParserCallBack ----
  234. HRESULT AddIndex(LPCWSTR pszAppName, LPCWSTR pszClassName,
  235. int iPartNum, int iStateNum, int iIndex, int iLen);
  236. HRESULT AddData(SHORT sTypeNum, PRIMVAL ePrimVal, const void *pData, DWORD dwLen);
  237. int GetNextDataIndex();
  238. protected:
  239. //---- helpers ----
  240. HRESULT PackAndLoadTheme(LPCWSTR pszThemeName, LPCWSTR pszColorParam,
  241. LPCWSTR pszSizeParam, HINSTANCE hInst);
  242. HRESULT CopyLocalThemeToLive(int iTotalLength, LPCWSTR pszThemeName,
  243. LPCWSTR pszColorParam, LPCWSTR pszSizeParam);
  244. void FreeLocalTheme();
  245. HRESULT PackMetrics();
  246. HRESULT PackThemeStructs();
  247. BOOL KeyDrawPropertyFound(int iStateDataOffset);
  248. BOOL KeyTextPropertyFound(int iStateDataOffset);
  249. HRESULT PackDrawObject(MIXEDPTRS &u, CRenderObj *pRender, int iPartId, int iStateId);
  250. HRESULT PackTextObject(MIXEDPTRS &u, CRenderObj *pRender, int iPartId, int iStateId);
  251. HRESULT PackDrawObjects(MIXEDPTRS &u, CRenderObj *pRender, int iMaxPart, BOOL fGlobals);
  252. HRESULT PackTextObjects(MIXEDPTRS &u, CRenderObj *pRender, int iMaxPart, BOOL fGlobals);
  253. HRESULT CopyPartGroup(APPCLASSLOCAL *ac, MIXEDPTRS &u, int iPartNum,
  254. int *piPartJumpTable, int iPartZeroIndex, int iGlobalsIndex, BOOL fGlobalsGroup);
  255. int GetPartOffset(CRenderObj *pRender, int iPartNum);
  256. HRESULT CopyClassGroup(APPCLASSLOCAL *ac, MIXEDPTRS &u, int iGlobalsIndex, int iClassNameOffset);
  257. int GetMaxState(APPCLASSLOCAL *ac, int iPartNum);
  258. HRESULT AddIndexInternal(LPCWSTR pszAppName, LPCWSTR pszClassName,
  259. int iPartNum, int iStateNum, int iIndex, int iLen);
  260. BOOL IndexExists(LPCWSTR pszAppName, LPCWSTR pszClassName,
  261. int iPartNum, int iStateNum);
  262. HRESULT AddMissingParent(LPCWSTR pszAppName, LPCWSTR pszClassName,
  263. int iPartNum, int iStateNum);
  264. HRESULT EmitEntryHdr(MIXEDPTRS &u, SHORT propnum, BYTE privnum);
  265. int EndEntry(MIXEDPTRS &u);
  266. HRESULT PackImageFileInfo(DIBINFO *pdi, CImageFile *pImageObj, MIXEDPTRS &u,
  267. CRenderObj *pRender, int iPartId, int iStateId);
  268. HRESULT AllocateThemeFileBytes(BYTE *upb, DWORD dwAdditionalLen);
  269. // Helper functions to alloc and emit sized data
  270. HRESULT EmitAndCopyBlock(MIXEDPTRS &u, void *pSrc, DWORD dwLen);
  271. HRESULT EmitString(MIXEDPTRS &u, LPCWSTR pSrc, DWORD dwLen, int *piOffSet);
  272. HRESULT EmitObject(MIXEDPTRS &u, SHORT propnum, BYTE privnum, void *pHdr, DWORD dwHdrLen, void *pObj, DWORD dwObjLen);
  273. //---- private data ----
  274. CWideString _wsThemeFileName;
  275. int _iGlobalsOffset;
  276. int _iSysMetricsOffset;
  277. //---- ptrs to packed objs for [globals] section ----
  278. int _iGlobalsTextObj; // we always create this obj
  279. int _iGlobalsDrawObj; // we always create this obj
  280. //---- local copy of theme data while being built ----
  281. BYTE *_pbLocalData;
  282. int _iLocalLen;
  283. CSimpleArray<APPCLASSLOCAL> _LocalIndexes;
  284. //---- used for updating entry hdrs ----
  285. BYTE *_pbEntryHdrs[MAX_ENTRY_NESTING]; // points to current hdr
  286. int _iEntryHdrLevel;
  287. //---- shared memory copy of theme data ----
  288. CUxThemeFile _LoadingThemeFile;
  289. //---- theme metrics ----
  290. LOADTHEMEMETRICS _LoadThemeMetrics;
  291. //---- Global creation flag
  292. BOOL _fGlobalTheme;
  293. //---- Machine page size for VirtualAlloc optimization
  294. DWORD _dwPageSize;
  295. };
  296. //---------------------------------------------------------------------------