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.

347 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. group16.c
  5. Abstract:
  6. This module contains routines for reading 16-bit Windows 3.1
  7. group files.
  8. Author:
  9. Steve Wood (stevewo) 22-Feb-1993
  10. Revision History:
  11. --*/
  12. #include "advapi.h"
  13. #include <stdio.h>
  14. #include <winbasep.h>
  15. #include "win31io.h"
  16. #define ROUND_UP( X, A ) (((ULONG_PTR)(X) + (A) - 1) & ~((A) - 1))
  17. #define PAGE_SIZE 4096
  18. #define PAGE_NUMBER( A ) ((DWORD)(A) / PAGE_SIZE)
  19. PGROUP_DEF16
  20. LoadGroup16(
  21. PWSTR GroupFileName
  22. )
  23. {
  24. HANDLE File, Mapping;
  25. LPVOID Base;
  26. File = CreateFileW( GroupFileName,
  27. GENERIC_READ,
  28. FILE_SHARE_READ,
  29. NULL,
  30. OPEN_EXISTING,
  31. 0,
  32. NULL
  33. );
  34. if (File == INVALID_HANDLE_VALUE) {
  35. return NULL;
  36. }
  37. Mapping = CreateFileMapping( File,
  38. NULL,
  39. PAGE_WRITECOPY,
  40. 0,
  41. 0,
  42. NULL
  43. );
  44. CloseHandle( File );
  45. if (Mapping == NULL) {
  46. return NULL;
  47. }
  48. Base = MapViewOfFile( Mapping,
  49. FILE_MAP_COPY,
  50. 0,
  51. 0,
  52. 0
  53. );
  54. CloseHandle( Mapping );
  55. return (PGROUP_DEF16)Base;
  56. }
  57. BOOL
  58. UnloadGroup16(
  59. PGROUP_DEF16 Group
  60. )
  61. {
  62. return UnmapViewOfFile( (LPVOID)Group );
  63. }
  64. BOOL
  65. ExtendGroup16(
  66. PGROUP_DEF16 Group,
  67. BOOL AppendToGroup,
  68. DWORD cb
  69. )
  70. {
  71. PBYTE Start, Commit, End;
  72. if (((DWORD)Group->wReserved + cb) > 0xFFFF) {
  73. return FALSE;
  74. }
  75. Start = (PBYTE)Group + Group->cbGroup;
  76. End = Start + cb;
  77. if (PAGE_NUMBER( Group->wReserved ) != PAGE_NUMBER( Group->wReserved + cb )) {
  78. Commit = (PBYTE)ROUND_UP( (PBYTE)Group + Group->wReserved, PAGE_SIZE );
  79. if (!VirtualAlloc( Commit, ROUND_UP( cb, PAGE_SIZE ), MEM_COMMIT, PAGE_READWRITE )) {
  80. return FALSE;
  81. }
  82. }
  83. if (!AppendToGroup) {
  84. memmove( End, Start, Group->wReserved - Group->cbGroup );
  85. }
  86. Group->wReserved += (WORD)cb;
  87. return TRUE;
  88. }
  89. WORD
  90. AddDataToGroup16(
  91. PGROUP_DEF16 Group,
  92. PBYTE Data,
  93. DWORD cb
  94. )
  95. {
  96. WORD Offset;
  97. if (cb == 0) {
  98. cb = strlen( Data ) + 1;
  99. }
  100. cb = (DWORD)ROUND_UP( cb, sizeof( WORD ) );
  101. if (!ExtendGroup16( Group, FALSE, cb )) {
  102. return 0;
  103. }
  104. if (((DWORD)Group->cbGroup + cb) > 0xFFFF) {
  105. return 0;
  106. }
  107. Offset = Group->cbGroup;
  108. Group->cbGroup += (WORD)cb;
  109. if (Data != NULL) {
  110. memmove( (PBYTE)Group + Offset, Data, cb );
  111. }
  112. else {
  113. memset( (PBYTE)Group + Offset, 0, cb );
  114. }
  115. return Offset;
  116. }
  117. BOOL
  118. AddTagToGroup16(
  119. PGROUP_DEF16 Group,
  120. WORD wID,
  121. WORD wItem,
  122. WORD cb,
  123. PBYTE rgb
  124. )
  125. {
  126. WORD Offset;
  127. PTAG_DEF16 Tag;
  128. cb = (WORD)(ROUND_UP( cb, sizeof( WORD ) ));
  129. Offset = Group->wReserved;
  130. if (!ExtendGroup16( Group, TRUE, FIELD_OFFSET( TAG_DEF16, rgb[ 0 ] ) + cb )) {
  131. return FALSE;
  132. }
  133. Tag = (PTAG_DEF16)PTR( Group, Offset );
  134. Tag->wID = wID;
  135. Tag->wItem = (int)wItem;
  136. if (cb) {
  137. Tag->cb = (WORD)(cb + FIELD_OFFSET( TAG_DEF16, rgb[ 0 ] ));
  138. memmove( &Tag->rgb[ 0 ], rgb, cb );
  139. }
  140. else {
  141. Tag->cb = (WORD)(FIELD_OFFSET( TAG_DEF16, rgb[ 0 ] ));
  142. }
  143. return TRUE;
  144. }
  145. #if DBG
  146. BOOL
  147. DumpGroup16(
  148. PWSTR GroupFileName,
  149. PGROUP_DEF16 Group
  150. )
  151. {
  152. PICON_HEADER16 Icon;
  153. PITEM_DEF16 Item;
  154. PTAG_DEF16 Tag;
  155. UINT i;
  156. PULONG p;
  157. int cb;
  158. DbgPrint( "%ws - Group at %08x\n", GroupFileName, Group );
  159. DbgPrint( " dwMagic: %08x\n", Group->dwMagic );
  160. DbgPrint( " wCheckSum: %04x\n", Group->wCheckSum );
  161. DbgPrint( " cbGroup: %04x\n", Group->cbGroup );
  162. DbgPrint( " nCmdShow: %04x\n", Group->nCmdShow );
  163. DbgPrint( " rcNormal: [%04x,%04x,%04x,%04x]\n",
  164. Group->rcNormal.Left,
  165. Group->rcNormal.Top,
  166. Group->rcNormal.Right,
  167. Group->rcNormal.Bottom
  168. );
  169. DbgPrint( " ptMin: [%04x,%04x]\n",
  170. Group->ptMin.x,
  171. Group->ptMin.y
  172. );
  173. DbgPrint( " pName: [%04x] %s\n",
  174. Group->pName,
  175. (PSZ)PTR( Group, Group->pName )
  176. );
  177. DbgPrint( " cxIcon: %04x\n", Group->cxIcon );
  178. DbgPrint( " cyIcon: %04x\n", Group->cyIcon );
  179. DbgPrint( " wIconFormat: %04x\n", Group->wIconFormat );
  180. DbgPrint( " cItems: %04x\n", Group->cItems );
  181. for (i=0; i<Group->cItems; i++) {
  182. DbgPrint( " Item[ %02x ] at %04x\n", i, Group->rgiItems[ i ] );
  183. if (Group->rgiItems[ i ] != 0) {
  184. Item = ITEM16( Group, i );
  185. DbgPrint( " pt: [%04x, %04x]\n",
  186. Item->pt.x,
  187. Item->pt.y
  188. );
  189. DbgPrint( " iIcon: %04x\n", Item->iIcon );
  190. DbgPrint( " cbHeader: %04x\n", Item->cbHeader );
  191. DbgPrint( " cbANDPln: %04x\n", Item->cbANDPlane );
  192. DbgPrint( " cbXORPln: %04x\n", Item->cbXORPlane );
  193. DbgPrint( " pHeader: %04x\n", Item->pHeader );
  194. Icon = (PICON_HEADER16)PTR( Group, Item->pHeader );
  195. DbgPrint( " xHot: %04x\n", Icon->xHotSpot );
  196. DbgPrint( " yHot: %04x\n", Icon->yHotSpot );
  197. DbgPrint( " cx: %04x\n", Icon->cx );
  198. DbgPrint( " cy: %04x\n", Icon->cy );
  199. DbgPrint( " cbWid:%04x\n", Icon->cbWidth );
  200. DbgPrint( " Plane:%04x\n", Icon->Planes );
  201. DbgPrint( " BPP: %04x\n", Icon->BitsPixel );
  202. DbgPrint( " pANDPln: %04x\n", Item->pANDPlane );
  203. DbgPrint( " pXORPln: %04x\n", Item->pXORPlane );
  204. DbgPrint( " pName: [%04x] %s\n", Item->pName, PTR( Group, Item->pName ) );
  205. DbgPrint( " pCommand:[%04x] %s\n", Item->pCommand, PTR( Group, Item->pCommand ) );
  206. DbgPrint( " pIconPth:[%04x] %s\n", Item->pIconPath, PTR( Group, Item->pIconPath ) );
  207. DbgPrint( " AND bits:\n" );
  208. p = (PULONG)PTR( Group, Item->pANDPlane );
  209. cb = Item->cbANDPlane;
  210. while (cb > 0) {
  211. DbgPrint( " %08x", *p++ );
  212. cb -= sizeof( *p );
  213. if (cb >= sizeof( *p )) {
  214. cb -= sizeof( *p );
  215. DbgPrint( " %08x", *p++ );
  216. if (cb >= sizeof( *p )) {
  217. cb -= sizeof( *p );
  218. DbgPrint( " %08x", *p++ );
  219. if (cb >= sizeof( *p )) {
  220. cb -= sizeof( *p );
  221. DbgPrint( " %08x", *p++ );
  222. }
  223. }
  224. }
  225. DbgPrint( "\n" );
  226. }
  227. DbgPrint( " XOR bits:\n" );
  228. p = (PULONG)PTR( Group, Item->pXORPlane );
  229. cb = Item->cbXORPlane;
  230. while (cb > 0) {
  231. DbgPrint( " %08x", *p++ );
  232. cb -= sizeof( *p );
  233. if (cb >= sizeof( *p )) {
  234. cb -= sizeof( *p );
  235. DbgPrint( " %08x", *p++ );
  236. if (cb >= sizeof( *p )) {
  237. cb -= sizeof( *p );
  238. DbgPrint( " %08x", *p++ );
  239. if (cb >= sizeof( *p )) {
  240. cb -= sizeof( *p );
  241. DbgPrint( " %08x", *p++ );
  242. }
  243. }
  244. }
  245. DbgPrint( "\n" );
  246. }
  247. }
  248. }
  249. Tag = (PTAG_DEF16)((PBYTE)Group + Group->cbGroup);
  250. if (Tag->wID == ID_MAGIC && Tag->wItem == ID_LASTTAG &&
  251. *(UNALIGNED DWORD *)&Tag->rgb == PMTAG_MAGIC
  252. ) {
  253. while (Tag->wID != ID_LASTTAG) {
  254. DbgPrint( " Tag at %04x\n", (PBYTE)Tag - (PBYTE)Group );
  255. DbgPrint( " wID: %04x\n", Tag->wID );
  256. DbgPrint( " wItem: %04x\n", Tag->wItem );
  257. DbgPrint( " cb: %04x\n", Tag->cb );
  258. switch( Tag->wID ) {
  259. case ID_MAGIC:
  260. DbgPrint( " rgb: ID_MAGIC( %.4s )\n", Tag->rgb );
  261. break;
  262. case ID_WRITERVERSION:
  263. DbgPrint( " rgb: ID_WRITERVERSION( %s )\n", Tag->rgb );
  264. break;
  265. case ID_APPLICATIONDIR:
  266. DbgPrint( " rgb: ID_APPLICATIONDIR( %s )\n", Tag->rgb );
  267. break;
  268. case ID_HOTKEY:
  269. DbgPrint( " rgb: ID_HOTKEY( %04x )\n", *(LPWORD)Tag->rgb );
  270. break;
  271. case ID_MINIMIZE:
  272. DbgPrint( " rgb: ID_MINIMIZE()\n" );
  273. break;
  274. case ID_LASTTAG:
  275. DbgPrint( " rgb: ID_LASTTAG()\n" );
  276. break;
  277. default:
  278. DbgPrint( " rgb: unknown data format for this ID\n" );
  279. break;
  280. }
  281. Tag = (PTAG_DEF16)((PBYTE)Tag + Tag->cb);
  282. }
  283. }
  284. return TRUE;
  285. }
  286. #endif // DBG