348 lines
9.7 KiB
C
348 lines
9.7 KiB
C
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
group16.c
|
|
|
|
Abstract:
|
|
|
|
This module contains routines for reading 16-bit Windows 3.1
|
|
group files.
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 22-Feb-1993
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "advapi.h"
|
|
#include <stdio.h>
|
|
|
|
#include <winbasep.h>
|
|
#include "win31io.h"
|
|
|
|
#define ROUND_UP( X, A ) (((ULONG_PTR)(X) + (A) - 1) & ~((A) - 1))
|
|
#define PAGE_SIZE 4096
|
|
#define PAGE_NUMBER( A ) ((DWORD)(A) / PAGE_SIZE)
|
|
|
|
PGROUP_DEF16
|
|
LoadGroup16(
|
|
PWSTR GroupFileName
|
|
)
|
|
{
|
|
HANDLE File, Mapping;
|
|
LPVOID Base;
|
|
|
|
File = CreateFileW( GroupFileName,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if (File == INVALID_HANDLE_VALUE) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Mapping = CreateFileMapping( File,
|
|
NULL,
|
|
PAGE_WRITECOPY,
|
|
0,
|
|
0,
|
|
NULL
|
|
);
|
|
CloseHandle( File );
|
|
if (Mapping == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Base = MapViewOfFile( Mapping,
|
|
FILE_MAP_COPY,
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
CloseHandle( Mapping );
|
|
return (PGROUP_DEF16)Base;
|
|
}
|
|
|
|
|
|
BOOL
|
|
UnloadGroup16(
|
|
PGROUP_DEF16 Group
|
|
)
|
|
{
|
|
return UnmapViewOfFile( (LPVOID)Group );
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtendGroup16(
|
|
PGROUP_DEF16 Group,
|
|
BOOL AppendToGroup,
|
|
DWORD cb
|
|
)
|
|
{
|
|
PBYTE Start, Commit, End;
|
|
|
|
if (((DWORD)Group->wReserved + cb) > 0xFFFF) {
|
|
return FALSE;
|
|
}
|
|
|
|
Start = (PBYTE)Group + Group->cbGroup;
|
|
End = Start + cb;
|
|
|
|
if (PAGE_NUMBER( Group->wReserved ) != PAGE_NUMBER( Group->wReserved + cb )) {
|
|
Commit = (PBYTE)ROUND_UP( (PBYTE)Group + Group->wReserved, PAGE_SIZE );
|
|
if (!VirtualAlloc( Commit, ROUND_UP( cb, PAGE_SIZE ), MEM_COMMIT, PAGE_READWRITE )) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (!AppendToGroup) {
|
|
memmove( End, Start, Group->wReserved - Group->cbGroup );
|
|
}
|
|
|
|
Group->wReserved += (WORD)cb;
|
|
return TRUE;
|
|
}
|
|
|
|
WORD
|
|
AddDataToGroup16(
|
|
PGROUP_DEF16 Group,
|
|
PBYTE Data,
|
|
DWORD cb
|
|
)
|
|
{
|
|
WORD Offset;
|
|
|
|
if (cb == 0) {
|
|
cb = strlen( Data ) + 1;
|
|
}
|
|
cb = (DWORD)ROUND_UP( cb, sizeof( WORD ) );
|
|
|
|
if (!ExtendGroup16( Group, FALSE, cb )) {
|
|
return 0;
|
|
}
|
|
|
|
if (((DWORD)Group->cbGroup + cb) > 0xFFFF) {
|
|
return 0;
|
|
}
|
|
|
|
Offset = Group->cbGroup;
|
|
Group->cbGroup += (WORD)cb;
|
|
|
|
if (Data != NULL) {
|
|
memmove( (PBYTE)Group + Offset, Data, cb );
|
|
}
|
|
else {
|
|
memset( (PBYTE)Group + Offset, 0, cb );
|
|
}
|
|
|
|
return Offset;
|
|
}
|
|
|
|
BOOL
|
|
AddTagToGroup16(
|
|
PGROUP_DEF16 Group,
|
|
WORD wID,
|
|
WORD wItem,
|
|
WORD cb,
|
|
PBYTE rgb
|
|
)
|
|
{
|
|
WORD Offset;
|
|
PTAG_DEF16 Tag;
|
|
|
|
cb = (WORD)(ROUND_UP( cb, sizeof( WORD ) ));
|
|
|
|
Offset = Group->wReserved;
|
|
if (!ExtendGroup16( Group, TRUE, FIELD_OFFSET( TAG_DEF16, rgb[ 0 ] ) + cb )) {
|
|
return FALSE;
|
|
}
|
|
|
|
Tag = (PTAG_DEF16)PTR( Group, Offset );
|
|
Tag->wID = wID;
|
|
Tag->wItem = (int)wItem;
|
|
if (cb) {
|
|
Tag->cb = (WORD)(cb + FIELD_OFFSET( TAG_DEF16, rgb[ 0 ] ));
|
|
memmove( &Tag->rgb[ 0 ], rgb, cb );
|
|
}
|
|
else {
|
|
Tag->cb = (WORD)(FIELD_OFFSET( TAG_DEF16, rgb[ 0 ] ));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
#if DBG
|
|
BOOL
|
|
DumpGroup16(
|
|
PWSTR GroupFileName,
|
|
PGROUP_DEF16 Group
|
|
)
|
|
{
|
|
PICON_HEADER16 Icon;
|
|
PITEM_DEF16 Item;
|
|
PTAG_DEF16 Tag;
|
|
UINT i;
|
|
PULONG p;
|
|
int cb;
|
|
|
|
DbgPrint( "%ws - Group at %08x\n", GroupFileName, Group );
|
|
DbgPrint( " dwMagic: %08x\n", Group->dwMagic );
|
|
DbgPrint( " wCheckSum: %04x\n", Group->wCheckSum );
|
|
DbgPrint( " cbGroup: %04x\n", Group->cbGroup );
|
|
DbgPrint( " nCmdShow: %04x\n", Group->nCmdShow );
|
|
DbgPrint( " rcNormal: [%04x,%04x,%04x,%04x]\n",
|
|
Group->rcNormal.Left,
|
|
Group->rcNormal.Top,
|
|
Group->rcNormal.Right,
|
|
Group->rcNormal.Bottom
|
|
);
|
|
DbgPrint( " ptMin: [%04x,%04x]\n",
|
|
Group->ptMin.x,
|
|
Group->ptMin.y
|
|
);
|
|
DbgPrint( " pName: [%04x] %s\n",
|
|
Group->pName,
|
|
(PSZ)PTR( Group, Group->pName )
|
|
);
|
|
DbgPrint( " cxIcon: %04x\n", Group->cxIcon );
|
|
DbgPrint( " cyIcon: %04x\n", Group->cyIcon );
|
|
DbgPrint( " wIconFormat: %04x\n", Group->wIconFormat );
|
|
DbgPrint( " cItems: %04x\n", Group->cItems );
|
|
|
|
for (i=0; i<Group->cItems; i++) {
|
|
DbgPrint( " Item[ %02x ] at %04x\n", i, Group->rgiItems[ i ] );
|
|
if (Group->rgiItems[ i ] != 0) {
|
|
Item = ITEM16( Group, i );
|
|
DbgPrint( " pt: [%04x, %04x]\n",
|
|
Item->pt.x,
|
|
Item->pt.y
|
|
);
|
|
DbgPrint( " iIcon: %04x\n", Item->iIcon );
|
|
DbgPrint( " cbHeader: %04x\n", Item->cbHeader );
|
|
DbgPrint( " cbANDPln: %04x\n", Item->cbANDPlane );
|
|
DbgPrint( " cbXORPln: %04x\n", Item->cbXORPlane );
|
|
DbgPrint( " pHeader: %04x\n", Item->pHeader );
|
|
Icon = (PICON_HEADER16)PTR( Group, Item->pHeader );
|
|
DbgPrint( " xHot: %04x\n", Icon->xHotSpot );
|
|
DbgPrint( " yHot: %04x\n", Icon->yHotSpot );
|
|
DbgPrint( " cx: %04x\n", Icon->cx );
|
|
DbgPrint( " cy: %04x\n", Icon->cy );
|
|
DbgPrint( " cbWid:%04x\n", Icon->cbWidth );
|
|
DbgPrint( " Plane:%04x\n", Icon->Planes );
|
|
DbgPrint( " BPP: %04x\n", Icon->BitsPixel );
|
|
DbgPrint( " pANDPln: %04x\n", Item->pANDPlane );
|
|
DbgPrint( " pXORPln: %04x\n", Item->pXORPlane );
|
|
DbgPrint( " pName: [%04x] %s\n", Item->pName, PTR( Group, Item->pName ) );
|
|
DbgPrint( " pCommand:[%04x] %s\n", Item->pCommand, PTR( Group, Item->pCommand ) );
|
|
DbgPrint( " pIconPth:[%04x] %s\n", Item->pIconPath, PTR( Group, Item->pIconPath ) );
|
|
|
|
DbgPrint( " AND bits:\n" );
|
|
p = (PULONG)PTR( Group, Item->pANDPlane );
|
|
cb = Item->cbANDPlane;
|
|
while (cb > 0) {
|
|
DbgPrint( " %08x", *p++ );
|
|
cb -= sizeof( *p );
|
|
if (cb >= sizeof( *p )) {
|
|
cb -= sizeof( *p );
|
|
DbgPrint( " %08x", *p++ );
|
|
if (cb >= sizeof( *p )) {
|
|
cb -= sizeof( *p );
|
|
DbgPrint( " %08x", *p++ );
|
|
if (cb >= sizeof( *p )) {
|
|
cb -= sizeof( *p );
|
|
DbgPrint( " %08x", *p++ );
|
|
}
|
|
}
|
|
}
|
|
|
|
DbgPrint( "\n" );
|
|
}
|
|
|
|
DbgPrint( " XOR bits:\n" );
|
|
p = (PULONG)PTR( Group, Item->pXORPlane );
|
|
cb = Item->cbXORPlane;
|
|
while (cb > 0) {
|
|
DbgPrint( " %08x", *p++ );
|
|
cb -= sizeof( *p );
|
|
if (cb >= sizeof( *p )) {
|
|
cb -= sizeof( *p );
|
|
DbgPrint( " %08x", *p++ );
|
|
if (cb >= sizeof( *p )) {
|
|
cb -= sizeof( *p );
|
|
DbgPrint( " %08x", *p++ );
|
|
if (cb >= sizeof( *p )) {
|
|
cb -= sizeof( *p );
|
|
DbgPrint( " %08x", *p++ );
|
|
}
|
|
}
|
|
}
|
|
|
|
DbgPrint( "\n" );
|
|
}
|
|
}
|
|
}
|
|
|
|
Tag = (PTAG_DEF16)((PBYTE)Group + Group->cbGroup);
|
|
if (Tag->wID == ID_MAGIC && Tag->wItem == ID_LASTTAG &&
|
|
*(UNALIGNED DWORD *)&Tag->rgb == PMTAG_MAGIC
|
|
) {
|
|
while (Tag->wID != ID_LASTTAG) {
|
|
DbgPrint( " Tag at %04x\n", (PBYTE)Tag - (PBYTE)Group );
|
|
DbgPrint( " wID: %04x\n", Tag->wID );
|
|
DbgPrint( " wItem: %04x\n", Tag->wItem );
|
|
DbgPrint( " cb: %04x\n", Tag->cb );
|
|
|
|
|
|
switch( Tag->wID ) {
|
|
case ID_MAGIC:
|
|
DbgPrint( " rgb: ID_MAGIC( %.4s )\n", Tag->rgb );
|
|
break;
|
|
|
|
case ID_WRITERVERSION:
|
|
DbgPrint( " rgb: ID_WRITERVERSION( %s )\n", Tag->rgb );
|
|
break;
|
|
|
|
case ID_APPLICATIONDIR:
|
|
DbgPrint( " rgb: ID_APPLICATIONDIR( %s )\n", Tag->rgb );
|
|
break;
|
|
|
|
case ID_HOTKEY:
|
|
DbgPrint( " rgb: ID_HOTKEY( %04x )\n", *(LPWORD)Tag->rgb );
|
|
break;
|
|
|
|
case ID_MINIMIZE:
|
|
DbgPrint( " rgb: ID_MINIMIZE()\n" );
|
|
break;
|
|
|
|
case ID_LASTTAG:
|
|
DbgPrint( " rgb: ID_LASTTAG()\n" );
|
|
break;
|
|
|
|
default:
|
|
DbgPrint( " rgb: unknown data format for this ID\n" );
|
|
break;
|
|
}
|
|
|
|
|
|
Tag = (PTAG_DEF16)((PBYTE)Tag + Tag->cb);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
#endif // DBG
|