windows-nt/Source/XPSP1/NT/windows/winstate/cobra/utils/icons/icons.c
2020-09-26 16:20:57 +08:00

3516 lines
87 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
icons.c
Abstract:
Implements a set of routines for handling icons in ICO, PE and NE files
Author:
Calin Negreanu (calinn) 16-Jum-2000
Revision History:
--*/
//
// Includes
//
#include "pch.h"
//
// Debug constants
//
#define DBG_ICONS "Icons"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
// None
//
// Globals
//
// None
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
VOID
IcoReleaseResourceIdA (
PCSTR ResourceId
)
/*++
Routine Description:
IcoReleaseResourceId will either do nothing if the resource ID has the high WORD 0 or will
release the string from the paths pool.
Arguments:
ResourceId - Specifies the resource ID to be released.
Return value:
None
--*/
{
if ((ULONG_PTR) ResourceId > 0xffff) {
FreePathStringA (ResourceId);
}
}
VOID
IcoReleaseResourceIdW (
PCWSTR ResourceId
)
/*++
Routine Description:
IcoReleaseResourceId will either do nothing if the resource ID has the high WORD 0 or will
release the string from the paths pool.
Arguments:
ResourceId - Specifies the resource ID to be released.
Return value:
None
--*/
{
if ((ULONG_PTR) ResourceId > 0xffff) {
FreePathStringW (ResourceId);
}
}
VOID
IcoReleaseIconGroup (
IN PICON_GROUP IconGroup
)
/*++
Routine Description:
IcoReleaseIconGroup releases a previously allocated icon group.
Arguments:
IconGroup - Specifies the icon group to be released.
Return value:
None
--*/
{
if (IconGroup && IconGroup->Pool) {
PmEmptyPool (IconGroup->Pool);
PmDestroyPool (IconGroup->Pool);
}
}
VOID
IcoReleaseIconSGroup (
IN OUT PICON_SGROUP IconSGroup
)
/*++
Routine Description:
IcoReleaseIconSGroup releases a previously allocated serialized icon group.
Arguments:
IconSGroup - Specifies the serialized icon group to be released.
Return value:
None
--*/
{
if (IconSGroup->DataSize && IconSGroup->Data) {
MemFree (g_hHeap, 0, IconSGroup->Data);
}
ZeroMemory (IconSGroup, sizeof (ICON_SGROUP));
}
BOOL
IcoSerializeIconGroup (
IN PICON_GROUP IconGroup,
OUT PICON_SGROUP IconSGroup
)
/*++
Routine Description:
IcoSerializeIconGroup transforms a ICON_GROUP structure into a ICON_SGROUP structure.
Arguments:
IconGroup - Specifies the icon group to be serialized.
Return value:
None
--*/
{
GROWBUFFER buffer = INIT_GROWBUFFER;
DWORD iconsCount;
DWORD index;
DWORD size;
PICON_IMAGE iconImage;
if (IconGroup == NULL) {
return FALSE;
}
if (IconSGroup == NULL) {
return FALSE;
}
iconsCount = IconGroup->IconsCount;
GbAppendDword (&buffer, iconsCount);
size = sizeof (ICON_IMAGE) - sizeof (PBYTE);
index = 0;
while (index < iconsCount) {
iconImage = IconGroup->Icons[index];
CopyMemory (GbGrow (&buffer, size), iconImage, size);
CopyMemory (GbGrow (&buffer, iconImage->Size), iconImage->Image, iconImage->Size);
index ++;
}
MYASSERT (buffer.End);
IconSGroup->DataSize = buffer.End;
IconSGroup->Data = MemAlloc (g_hHeap, 0, buffer.End);
CopyMemory (IconSGroup->Data, buffer.Buf, buffer.End);
GbFree (&buffer);
return TRUE;
}
PICON_GROUP
IcoDeSerializeIconGroup (
IN PICON_SGROUP IconSGroup
)
/*++
Routine Description:
IcoDeSerializeIconGroup transforms a ICON_SGROUP structure into a ICON_GROUP structure.
Arguments:
IconSGroup - Specifies the icon sgroup to be transformed.
Return value:
None
--*/
{
PMHANDLE iconPool = NULL;
PICON_GROUP iconGroup = NULL;
DWORD iconGroupSize = 0;
PICON_IMAGE iconImage = NULL;
PICON_IMAGE iconSImage = NULL;
PDWORD iconsCount;
PBYTE currPtr = NULL;
DWORD i;
if (IconSGroup == NULL) {
return NULL;
}
currPtr = IconSGroup->Data;
iconsCount = (PDWORD) currPtr;
currPtr += sizeof (DWORD);
iconPool = PmCreateNamedPool ("Icon");
if (!iconPool) {
return NULL;
}
iconGroupSize = sizeof (ICON_GROUP) + *iconsCount * sizeof (PICON_IMAGE);
iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
ZeroMemory (iconGroup, iconGroupSize);
iconGroup->Pool = iconPool;
iconGroup->IconsCount = (WORD) (*iconsCount);
for (i = 0; i < *iconsCount; i ++) {
iconSImage = (PICON_IMAGE) currPtr;
currPtr += (sizeof (ICON_IMAGE) - sizeof (PBYTE));
iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
ZeroMemory (iconImage, sizeof (ICON_IMAGE));
iconImage->Width = iconSImage->Width;
iconImage->Height = iconSImage->Height;
iconImage->ColorCount = iconSImage->ColorCount;
iconImage->Planes = iconSImage->Planes;
iconImage->BitCount = iconSImage->BitCount;
iconImage->Size = iconSImage->Size;
iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
CopyMemory (iconImage->Image, currPtr, iconImage->Size);
currPtr += iconImage->Size;
iconGroup->Icons [i] = iconImage;
}
return iconGroup;
}
PICON_GROUP
IcoExtractIconGroupFromIcoFileEx (
IN HANDLE IcoFileHandle
)
/*++
Routine Description:
IcoExtractIconGroupFromIcoFileEx extracts the icon group from an ICO file.
Arguments:
IcoFile - Specifies the name of the ICO file to be processed.
IcoFileHandle - Specifies the handle to the ICO file to be processed.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PMHANDLE iconPool = NULL;
PICON_GROUP iconGroup = NULL;
DWORD iconGroupSize = 0;
PICON_IMAGE iconImage = NULL;
LONGLONG fileSize;
DWORD fileOffset;
ICONDIRBASE iconDirBase;
PICONDIR iconDir = NULL;
DWORD iconDirSize = 0;
PICONDIRENTRY iconDirEntry;
DWORD i;
BOOL result = FALSE;
__try {
fileSize = GetFileSize (IcoFileHandle, NULL);
if (!BfSetFilePointer (IcoFileHandle, 0)) {
__leave;
}
if (!BfReadFile (IcoFileHandle, (PBYTE)(&iconDirBase), sizeof (ICONDIRBASE))) {
__leave;
}
if (!BfSetFilePointer (IcoFileHandle, 0)) {
__leave;
}
iconDirSize = sizeof (ICONDIRBASE) + iconDirBase.Count * sizeof (ICONDIRENTRY);
// validation
if (iconDirBase.Count == 0) {
__leave;
}
if (iconDirSize > fileSize) {
__leave;
}
iconDir = (PICONDIR) MemAlloc (g_hHeap, 0, iconDirSize);
if (!BfReadFile (IcoFileHandle, (PBYTE)iconDir, iconDirSize)) {
__leave;
}
// validation
for (i = 0; i < iconDirBase.Count; i ++) {
iconDirEntry = &iconDir->Entries[i];
fileOffset = iconDirEntry->ImageOffset & 0x0fffffff;
if (fileOffset > fileSize) {
__leave;
}
if (iconDirEntry->Width == 0) {
__leave;
}
if (iconDirEntry->Height == 0) {
__leave;
}
if (iconDirEntry->BytesInRes == 0) {
__leave;
}
}
if (iconDirEntry->BytesInRes + fileOffset != fileSize) {
__leave;
}
iconPool = PmCreateNamedPool ("Icon");
if (!iconPool) {
__leave;
}
iconGroupSize = sizeof (ICON_GROUP) + iconDirBase.Count * sizeof (PICON_IMAGE);
iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
ZeroMemory (iconGroup, iconGroupSize);
iconGroup->Pool = iconPool;
iconGroup->IconsCount = iconDirBase.Count;
for (i = 0; i < iconDirBase.Count; i ++) {
iconDirEntry = &iconDir->Entries[i];
fileOffset = iconDirEntry->ImageOffset & 0x0fffffff;
if (!BfSetFilePointer (IcoFileHandle, fileOffset)) {
__leave;
}
iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
ZeroMemory (iconImage, sizeof (ICON_IMAGE));
iconImage->Width = iconDirEntry->Width;
iconImage->Height = iconDirEntry->Height;
iconImage->ColorCount = iconDirEntry->ColorCount;
iconImage->Planes = iconDirEntry->Planes;
iconImage->BitCount = iconDirEntry->BitCount;
iconImage->Size = iconDirEntry->BytesInRes;
iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
if (!BfReadFile (IcoFileHandle, iconImage->Image, iconImage->Size)) {
__leave;
}
iconGroup->Icons [i] = iconImage;
}
result = TRUE;
}
__finally {
if (iconDir) {
MemFree (g_hHeap, 0, iconDir);
iconDir = NULL;
}
if (!result) {
if (iconPool) {
PmEmptyPool (iconPool);
PmDestroyPool (iconPool);
iconPool = NULL;
}
iconGroup = NULL;
}
BfSetFilePointer (IcoFileHandle, 0);
}
return iconGroup;
}
PICON_GROUP
IcoExtractIconGroupFromIcoFileA (
IN PCSTR IcoFile
)
/*++
Routine Description:
IcoExtractIconGroupFromIcoFile extracts the icon group from an ICO file.
Arguments:
IcoFile - Specifies the name of the ICO file to be processed.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE icoFileHandle;
PICON_GROUP result = NULL;
icoFileHandle = BfOpenReadFileA (IcoFile);
if (!icoFileHandle) {
return NULL;
}
result = IcoExtractIconGroupFromIcoFileEx (icoFileHandle);
CloseHandle (icoFileHandle);
return result;
}
PICON_GROUP
IcoExtractIconGroupFromIcoFileW (
IN PCWSTR IcoFile
)
/*++
Routine Description:
IcoExtractIconGroupFromIcoFile extracts the icon group from an ICO file.
Arguments:
IcoFile - Specifies the name of the ICO file to be processed.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE icoFileHandle;
PICON_GROUP result = NULL;
icoFileHandle = BfOpenReadFileW (IcoFile);
if (!icoFileHandle) {
return NULL;
}
result = IcoExtractIconGroupFromIcoFileEx (icoFileHandle);
CloseHandle (icoFileHandle);
return result;
}
BOOL
IcoWriteIconGroupToIcoFileEx (
IN HANDLE IcoFileHandle,
IN PICON_GROUP IconGroup
)
/*++
Routine Description:
IcoWriteIconGroupToIcoFileEx writes an icon group to an ICO file. The file has to exist and it's
content will be overwritten.
Arguments:
IcoFileHandle - Specifies the handle of the ICO file to be processed.
IconGroup - Specifies the icon group to be written.
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
PICONDIR iconDir = NULL;
DWORD iconDirSize = 0;
DWORD elapsedSize = 0;
WORD i;
BOOL result = FALSE;
__try {
if (!BfSetFilePointer (IcoFileHandle, 0)) {
__leave;
}
iconDirSize = sizeof (ICONDIRBASE) + IconGroup->IconsCount * sizeof (ICONDIRENTRY);
iconDir = (PICONDIR) MemAlloc (g_hHeap, 0, iconDirSize);
ZeroMemory (iconDir, iconDirSize);
iconDir->Type = 1;
iconDir->Count = IconGroup->IconsCount;
elapsedSize = iconDirSize;
for (i = 0; i < IconGroup->IconsCount; i ++) {
iconDir->Entries[i].Width = (IconGroup->Icons [i])->Width;
iconDir->Entries[i].Height = (IconGroup->Icons [i])->Height;
iconDir->Entries[i].ColorCount = (IconGroup->Icons [i])->ColorCount;
iconDir->Entries[i].Planes = (IconGroup->Icons [i])->Planes;
iconDir->Entries[i].BitCount = (IconGroup->Icons [i])->BitCount;
iconDir->Entries[i].BytesInRes = (IconGroup->Icons [i])->Size;
iconDir->Entries[i].ImageOffset = elapsedSize;
elapsedSize += (IconGroup->Icons [i])->Size;
}
if (!BfWriteFile (IcoFileHandle, (PBYTE)iconDir, iconDirSize)) {
__leave;
}
for (i = 0; i < IconGroup->IconsCount; i ++) {
if (!BfWriteFile (IcoFileHandle, (IconGroup->Icons [i])->Image, (IconGroup->Icons [i])->Size)) {
__leave;
}
}
result = TRUE;
}
__finally {
}
return result;
}
BOOL
IcoWriteIconGroupToIcoFileA (
IN PCSTR IcoFile,
IN PICON_GROUP IconGroup,
IN BOOL OverwriteExisting
)
/*++
Routine Description:
IcoWriteIconGroupToIcoFile writes an icon group to an ICO file. The file is either created if
does not exist or it is overwritten if OverwriteExisting is TRUE.
Arguments:
IcoFile - Specifies the ICO file to be processed.
IconGroup - Specifies the icon group to be written.
OverwriteExisting - if TRUE and the IcoFile exists, it will be overwritten
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
HANDLE icoFileHandle;
BOOL result = FALSE;
if (DoesFileExistA (IcoFile)) {
if (!OverwriteExisting) {
return FALSE;
}
}
icoFileHandle = BfCreateFileA (IcoFile);
if (!icoFileHandle) {
return FALSE;
}
result = IcoWriteIconGroupToIcoFileEx (icoFileHandle, IconGroup);
CloseHandle (icoFileHandle);
if (!result) {
DeleteFileA (IcoFile);
}
return result;
}
BOOL
IcoWriteIconGroupToIcoFileW (
IN PCWSTR IcoFile,
IN PICON_GROUP IconGroup,
IN BOOL OverwriteExisting
)
/*++
Routine Description:
IcoWriteIconGroupToIcoFile writes an icon group to an ICO file. The file is either created if
does not exist or it is overwritten if OverwriteExisting is TRUE.
Arguments:
IcoFile - Specifies the ICO file to be processed.
IconGroup - Specifies the icon group to be written.
OverwriteExisting - if TRUE and the IcoFile exists, it will be overwritten
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
HANDLE icoFileHandle;
BOOL result = FALSE;
if (DoesFileExistW (IcoFile)) {
if (!OverwriteExisting) {
return FALSE;
}
}
icoFileHandle = BfCreateFileW (IcoFile);
if (!icoFileHandle) {
return FALSE;
}
result = IcoWriteIconGroupToIcoFileEx (icoFileHandle, IconGroup);
CloseHandle (icoFileHandle);
if (!result) {
DeleteFileW (IcoFile);
}
return result;
}
BOOL
CALLBACK
pPeEnumIconGroupA (
HANDLE ModuleHandle,
PCSTR Type,
PSTR Name,
LONG_PTR lParam
)
{
PGROWBUFFER Buf;
PCSTR Num;
CHAR NumBuf[32];
Buf = (PGROWBUFFER) lParam;
if ((ULONG_PTR) Name > 0xffff) {
Num = Name;
} else {
Num = NumBuf;
wsprintfA (NumBuf, "#%u", Name);
}
GbMultiSzAppendA (Buf, Num);
return TRUE;
}
BOOL
CALLBACK
pPeEnumIconGroupW (
HANDLE ModuleHandle,
PCWSTR Type,
PWSTR Name,
LONG_PTR lParam
)
{
PGROWBUFFER Buf;
PCWSTR Num;
WCHAR NumBuf[32];
Buf = (PGROWBUFFER) lParam;
if ((ULONG_PTR) Name > 0xffff) {
Num = Name;
} else {
Num = NumBuf;
wsprintfW (NumBuf, L"#%u", Name);
}
GbMultiSzAppendW (Buf, Num);
return TRUE;
}
INT
IcoGetIndexFromPeResourceIdExA (
IN HANDLE ModuleHandle,
IN PCSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromPeResourceIdEx returns the index of an icon group resource given the
resource ID. It knows how to process only PE files.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
GROWBUFFER buffer = INIT_GROWBUFFER;
MULTISZ_ENUMA multiSzEnum;
CHAR NumBuf[32];
INT index = 0;
BOOL result = FALSE;
if ((ULONG_PTR) GroupIconId < 0x10000) {
wsprintfA (NumBuf, "#%u", GroupIconId);
GroupIconId = NumBuf;
}
if (EnumResourceNamesA (ModuleHandle, (PCSTR) RT_GROUP_ICON, pPeEnumIconGroupA, (LONG_PTR) (&buffer))) {
GbMultiSzAppendA (&buffer, "");
if (EnumFirstMultiSzA (&multiSzEnum, (PCSTR)(buffer.Buf))) {
do {
if (StringIMatchA (multiSzEnum.CurrentString, GroupIconId)) {
result = TRUE;
break;
}
index ++;
} while (EnumNextMultiSzA (&multiSzEnum));
}
}
if (!result) {
index = -1;
}
return index;
}
INT
IcoGetIndexFromPeResourceIdExW (
IN HANDLE ModuleHandle,
IN PCWSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromPeResourceIdEx returns the index of an icon group resource given the
resource ID. It knows how to process only PE files.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
GROWBUFFER buffer = INIT_GROWBUFFER;
MULTISZ_ENUMW multiSzEnum;
WCHAR NumBuf[32];
INT index = 0;
BOOL result = FALSE;
if ((ULONG_PTR) GroupIconId < 0x10000) {
wsprintfW (NumBuf, L"#%u", GroupIconId);
GroupIconId = NumBuf;
}
if (EnumResourceNamesW (
ModuleHandle,
(PCWSTR) RT_GROUP_ICON,
pPeEnumIconGroupW,
(LONG_PTR) (&buffer)
)) {
GbMultiSzAppendW (&buffer, L"");
if (EnumFirstMultiSzW (&multiSzEnum, (PCWSTR)(buffer.Buf))) {
do {
if (StringIMatchW (multiSzEnum.CurrentString, GroupIconId)) {
result = TRUE;
break;
}
index ++;
} while (EnumNextMultiSzW (&multiSzEnum));
}
}
if (!result) {
index = -1;
}
return index;
}
INT
IcoGetIndexFromPeResourceIdA (
IN PCSTR ModuleName,
IN PCSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromPeResourceId returns the index of an icon group resource given the
resource ID. It knows how to process only PE files.
Arguments:
ModuleName - Specifies the PE file to be processed.
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
HANDLE moduleHandle;
INT result = -1;
moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoGetIndexFromPeResourceIdExA (moduleHandle, GroupIconId);
FreeLibrary (moduleHandle);
}
return result;
}
INT
IcoGetIndexFromPeResourceIdW (
IN PCWSTR ModuleName,
IN PCWSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromPeResourceId returns the index of an icon group resource given the
resource ID. It knows how to process only PE files.
Arguments:
ModuleName - Specifies the PE file to be processed.
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
HANDLE moduleHandle;
INT result = -1;
moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoGetIndexFromPeResourceIdExW (moduleHandle, GroupIconId);
FreeLibrary (moduleHandle);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupFromPeFileExA (
IN HANDLE ModuleHandle,
IN PCSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromPeFileEx extracts an icon group from a PE file.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PMHANDLE iconPool = NULL;
PICON_GROUP iconGroup = NULL;
DWORD iconGroupSize = 0;
PICON_IMAGE iconImage = NULL;
PGRPICONDIRENTRY iconDirEntry;
HRSRC resourceHandle;
HGLOBAL resourceBlock;
PBYTE resourceData;
DWORD resourceSize;
PGRPICONDIR groupIconDir;
WORD groupIconDirCount;
WORD gap;
WORD i;
BOOL result = FALSE;
__try {
resourceHandle = FindResourceA (ModuleHandle, GroupIconId, (PCSTR) RT_GROUP_ICON);
if (!resourceHandle) {
__leave;
}
resourceBlock = LoadResource (ModuleHandle, resourceHandle);
if (!resourceBlock) {
__leave;
}
groupIconDir = (PGRPICONDIR) LockResource (resourceBlock);
if (!groupIconDir) {
__leave;
}
iconPool = PmCreateNamedPool ("Icon");
if (!iconPool) {
__leave;
}
// First let's do some validation of all the icons from this icon group
groupIconDirCount = groupIconDir->Count;
for (i = 0; i < groupIconDir->Count; i ++) {
resourceHandle = FindResourceA (ModuleHandle, (PCSTR) (groupIconDir->Entries[i].ID), (PCSTR) RT_ICON);
if (!resourceHandle) {
groupIconDirCount --;
continue;
}
resourceBlock = LoadResource (ModuleHandle, resourceHandle);
if (!resourceBlock) {
groupIconDirCount --;
continue;
}
resourceData = (PBYTE) LockResource (resourceBlock);
if (!resourceData) {
FreeResource (resourceBlock);
groupIconDirCount --;
continue;
}
resourceSize = SizeofResource (ModuleHandle, resourceHandle);
if (!resourceSize) {
FreeResource (resourceBlock);
groupIconDirCount --;
continue;
}
}
iconGroupSize = sizeof (ICON_GROUP) + groupIconDirCount * sizeof (PICON_IMAGE);
iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
ZeroMemory (iconGroup, iconGroupSize);
iconGroup->Pool = iconPool;
iconGroup->IconsCount = groupIconDirCount;
gap = 0;
for (i = 0; i < groupIconDir->Count; i ++) {
resourceHandle = FindResourceA (ModuleHandle, (PCSTR) (groupIconDir->Entries[i].ID), (PCSTR) RT_ICON);
if (!resourceHandle) {
gap ++;
continue;
}
resourceBlock = LoadResource (ModuleHandle, resourceHandle);
if (!resourceBlock) {
gap ++;
continue;
}
resourceData = (PBYTE) LockResource (resourceBlock);
if (!resourceData) {
FreeResource (resourceBlock);
gap ++;
continue;
}
resourceSize = SizeofResource (ModuleHandle, resourceHandle);
if (!resourceSize) {
FreeResource (resourceBlock);
gap ++;
continue;
}
iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
ZeroMemory (iconImage, sizeof (ICON_IMAGE));
iconDirEntry = &groupIconDir->Entries[i];
iconImage->Width = iconDirEntry->Width;
iconImage->Height = iconDirEntry->Height;
iconImage->ColorCount = iconDirEntry->ColorCount;
iconImage->Planes = iconDirEntry->Planes;
iconImage->BitCount = iconDirEntry->BitCount;
iconImage->Size = iconDirEntry->BytesInRes;
if (iconImage->Size > resourceSize) {
iconImage->Size = resourceSize;
}
iconImage->Id = iconDirEntry->ID;
iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
CopyMemory (iconImage->Image, resourceData, iconImage->Size);
iconGroup->Icons [i - gap] = iconImage;
}
if (Index) {
*Index = IcoGetIndexFromPeResourceIdExA (ModuleHandle, GroupIconId);
}
result = TRUE;
}
__finally {
if (!result) {
if (iconPool) {
PmEmptyPool (iconPool);
PmDestroyPool (iconPool);
iconPool = NULL;
}
iconGroup = NULL;
}
}
return iconGroup;
}
PICON_GROUP
IcoExtractIconGroupFromPeFileExW (
IN HANDLE ModuleHandle,
IN PCWSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromPeFileEx extracts an icon group from a PE file.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PMHANDLE iconPool = NULL;
PICON_GROUP iconGroup = NULL;
DWORD iconGroupSize = 0;
PICON_IMAGE iconImage = NULL;
PGRPICONDIRENTRY iconDirEntry;
HRSRC resourceHandle;
HGLOBAL resourceBlock;
PBYTE resourceData;
DWORD resourceSize;
PGRPICONDIR groupIconDir;
WORD i;
BOOL result = FALSE;
__try {
resourceHandle = FindResourceW (ModuleHandle, GroupIconId, (PCWSTR) RT_GROUP_ICON);
if (!resourceHandle) {
__leave;
}
resourceBlock = LoadResource (ModuleHandle, resourceHandle);
if (!resourceBlock) {
__leave;
}
groupIconDir = (PGRPICONDIR) LockResource (resourceBlock);
if (!groupIconDir) {
__leave;
}
iconPool = PmCreateNamedPool ("Icon");
if (!iconPool) {
__leave;
}
iconGroupSize = sizeof (ICON_GROUP) + groupIconDir->Count * sizeof (PICON_IMAGE);
iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
ZeroMemory (iconGroup, iconGroupSize);
iconGroup->Pool = iconPool;
iconGroup->IconsCount = groupIconDir->Count;
for (i = 0; i < groupIconDir->Count; i ++) {
resourceHandle = FindResourceW (ModuleHandle, (PCWSTR) (groupIconDir->Entries[i].ID), (PCWSTR) RT_ICON);
if (!resourceHandle) {
__leave;
}
resourceBlock = LoadResource (ModuleHandle, resourceHandle);
if (!resourceBlock) {
__leave;
}
resourceData = (PBYTE) LockResource (resourceBlock);
if (!resourceData) {
__leave;
}
resourceSize = SizeofResource (ModuleHandle, resourceHandle);
if (!resourceSize) {
__leave;
}
iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
ZeroMemory (iconImage, sizeof (ICON_IMAGE));
iconDirEntry = &groupIconDir->Entries[i];
iconImage->Width = iconDirEntry->Width;
iconImage->Height = iconDirEntry->Height;
iconImage->ColorCount = iconDirEntry->ColorCount;
iconImage->Planes = iconDirEntry->Planes;
iconImage->BitCount = iconDirEntry->BitCount;
iconImage->Size = iconDirEntry->BytesInRes;
if (iconImage->Size > resourceSize) {
iconImage->Size = resourceSize;
}
iconImage->Id = iconDirEntry->ID;
iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
CopyMemory (iconImage->Image, resourceData, iconImage->Size);
iconGroup->Icons [i] = iconImage;
}
if (Index) {
*Index = IcoGetIndexFromPeResourceIdExW (ModuleHandle, GroupIconId);
}
result = TRUE;
}
__finally {
if (!result) {
if (iconPool) {
PmEmptyPool (iconPool);
PmDestroyPool (iconPool);
iconPool = NULL;
}
iconGroup = NULL;
}
}
return iconGroup;
}
PICON_GROUP
IcoExtractIconGroupFromPeFileA (
IN PCSTR ModuleName,
IN PCSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromPeFile extracts an icon group from a PE file.
Arguments:
ModuleName - Specifies the PE file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoExtractIconGroupFromPeFileExA (moduleHandle, GroupIconId, Index);
FreeLibrary (moduleHandle);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupFromPeFileW (
IN PCWSTR ModuleName,
IN PCWSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromPeFile extracts an icon group from a PE file.
Arguments:
ModuleName - Specifies the PE file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoExtractIconGroupFromPeFileExW (moduleHandle, GroupIconId, Index);
FreeLibrary (moduleHandle);
}
return result;
}
VOID
IcoAbortPeEnumIconGroupA (
IN OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoAbortPeEnumIconGroup terminates the icon group enumeration from a PE file.
Arguments:
IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
Return value:
None
--*/
{
GbFree (&IconEnum->Buffer);
if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
FreeLibrary (IconEnum->ModuleHandle);
}
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
}
if (IconEnum->ResourceId) {
FreePathStringA (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
}
VOID
IcoAbortPeEnumIconGroupW (
IN OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoAbortPeEnumIconGroup terminates the icon group enumeration from a PE file.
Arguments:
IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
Return value:
None
--*/
{
GbFree (&IconEnum->Buffer);
if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
FreeLibrary (IconEnum->ModuleHandle);
}
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
}
if (IconEnum->ResourceId) {
FreePathStringW (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
}
BOOL
pEnumFirstIconGroupInPeFileExA (
IN OUT PICON_ENUMA IconEnum
)
{
BOOL result = FALSE;
if (EnumResourceNamesA (
IconEnum->ModuleHandle,
(PCSTR) RT_GROUP_ICON,
pPeEnumIconGroupA,
(LONG_PTR) (&IconEnum->Buffer)
)) {
GbMultiSzAppendA (&IconEnum->Buffer, "");
if (EnumFirstMultiSzA (&IconEnum->MultiSzEnum, (PCSTR)(IconEnum->Buffer.Buf))) {
IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExA (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
}
}
}
if (!result) {
IcoAbortPeEnumIconGroupA (IconEnum);
}
return result;
}
BOOL
pEnumFirstIconGroupInPeFileExW (
IN OUT PICON_ENUMW IconEnum
)
{
BOOL result = FALSE;
if (EnumResourceNamesW (
IconEnum->ModuleHandle,
(PCWSTR) RT_GROUP_ICON,
pPeEnumIconGroupW,
(LONG_PTR) (&IconEnum->Buffer)
)) {
GbMultiSzAppendW (&IconEnum->Buffer, L"");
if (EnumFirstMultiSzW (&IconEnum->MultiSzEnum, (PCWSTR)(IconEnum->Buffer.Buf))) {
IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExW (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
}
}
}
if (!result) {
IcoAbortPeEnumIconGroupW (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInPeFileExA (
IN HANDLE ModuleHandle,
OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInPeFileEx starts the icon group enumeration from a PE file.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
IconEnum->FreeHandle = FALSE;
IconEnum->ModuleHandle = ModuleHandle;
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInPeFileExA (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInPeFileExW (
IN HANDLE ModuleHandle,
OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInPeFileEx starts the icon group enumeration from a PE file.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
IconEnum->FreeHandle = FALSE;
IconEnum->ModuleHandle = ModuleHandle;
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInPeFileExW (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInPeFileA (
IN PCSTR ModuleName,
OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInPeFile starts the icon group enumeration from a PE file.
Arguments:
ModuleName - Specifies the PE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
IconEnum->FreeHandle = TRUE;
IconEnum->ModuleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInPeFileExA (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInPeFileW (
IN PCWSTR ModuleName,
OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInPeFile starts the icon group enumeration from a PE file.
Arguments:
ModuleName - Specifies the PE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
IconEnum->FreeHandle = TRUE;
IconEnum->ModuleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInPeFileExW (IconEnum);
}
return result;
}
BOOL
IcoEnumNextIconGroupInPeFileA (
IN OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumNextIconGroupInPeFile continues the icon group enumeration from a PE file.
Arguments:
IconEnum - Specifies and receives the icon group enumeration structure.
Return value:
TRUE if one more icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
IconEnum->IconGroup = NULL;
}
if (IconEnum->ResourceId) {
FreePathStringA (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
if (EnumNextMultiSzA (&IconEnum->MultiSzEnum)) {
IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExA (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
IconEnum->Index ++;
}
}
if (!result) {
IcoAbortPeEnumIconGroupA (IconEnum);
}
return result;
}
BOOL
IcoEnumNextIconGroupInPeFileW (
IN OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumNextIconGroupInPeFile continues the icon group enumeration from a PE file.
Arguments:
IconEnum - Specifies and receives the icon group enumeration structure.
Return value:
TRUE if one more icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
IconEnum->IconGroup = NULL;
}
if (IconEnum->ResourceId) {
FreePathStringW (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
if (EnumNextMultiSzW (&IconEnum->MultiSzEnum)) {
IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExW (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
IconEnum->Index ++;
}
}
if (!result) {
IcoAbortPeEnumIconGroupW (IconEnum);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromPeFileExA (
IN HANDLE ModuleHandle,
IN INT Index,
OUT PCSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupByIndexFromPeFileEx extracts an icon group from a PE file
using the Index.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
ICON_ENUMA iconEnum;
PICON_GROUP result = NULL;
if (IcoEnumFirstIconGroupInPeFileExA (ModuleHandle, &iconEnum)) {
do {
if (iconEnum.Index == Index) {
result = iconEnum.IconGroup;
iconEnum.IconGroup = NULL;
if (GroupIconId) {
*GroupIconId = iconEnum.ResourceId;
iconEnum.ResourceId = NULL;
}
break;
}
} while (IcoEnumNextIconGroupInPeFileA (&iconEnum));
IcoAbortPeEnumIconGroupA (&iconEnum);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromPeFileExW (
IN HANDLE ModuleHandle,
IN INT Index,
OUT PCWSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupByIndexFromPeFileEx extracts an icon group from a PE file
using the Index.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
ICON_ENUMW iconEnum;
PICON_GROUP result = NULL;
if (IcoEnumFirstIconGroupInPeFileExW (ModuleHandle, &iconEnum)) {
do {
if (iconEnum.Index == Index) {
result = iconEnum.IconGroup;
iconEnum.IconGroup = NULL;
if (GroupIconId) {
*GroupIconId = iconEnum.ResourceId;
iconEnum.ResourceId = NULL;
}
break;
}
} while (IcoEnumNextIconGroupInPeFileW (&iconEnum));
IcoAbortPeEnumIconGroupW (&iconEnum);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromPeFileA (
IN PCSTR ModuleName,
IN INT Index,
OUT PCSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromPeFile extracts an icon group from a PE file
using the Index
Arguments:
ModuleName - Specifies the PE file to be processed.
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoExtractIconGroupByIndexFromPeFileExA (moduleHandle, Index, GroupIconId);
FreeLibrary (moduleHandle);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromPeFileW (
IN PCWSTR ModuleName,
IN INT Index,
OUT PCWSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromPeFile extracts an icon group from a PE file
using the Index
Arguments:
ModuleName - Specifies the PE file to be processed.
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoExtractIconGroupByIndexFromPeFileExW (moduleHandle, Index, GroupIconId);
FreeLibrary (moduleHandle);
}
return result;
}
WORD
pGetAvailableResourceA (
IN HANDLE ModuleHandle,
IN WORD StartIndex,
IN PCSTR ResourceType
)
{
WORD lastIndex = StartIndex;
HRSRC resourceHandle;
BOOL result = FALSE;
if (lastIndex == 0) {
lastIndex ++;
}
do {
resourceHandle = FindResourceA (ModuleHandle, MAKEINTRESOURCEA (lastIndex), ResourceType);
if (!resourceHandle) {
break;
}
lastIndex ++;
if (lastIndex == 0) {
break;
}
} while (TRUE);
return lastIndex;
}
WORD
pGetAvailableResourceW (
IN HANDLE ModuleHandle,
IN WORD StartIndex,
IN PCWSTR ResourceType
)
{
WORD lastIndex = StartIndex;
HRSRC resourceHandle;
BOOL result = FALSE;
if (lastIndex == 0) {
lastIndex ++;
}
do {
resourceHandle = FindResourceW (ModuleHandle, MAKEINTRESOURCEW (lastIndex), ResourceType);
if (!resourceHandle) {
break;
}
lastIndex ++;
if (lastIndex == 0) {
break;
}
} while (TRUE);
return lastIndex;
}
BOOL
IcoWriteIconGroupToPeFileExA (
IN HANDLE ModuleHandle,
IN HANDLE UpdateHandle,
IN PICON_GROUP IconGroup,
OUT PCSTR *ResourceId OPTIONAL
)
/*++
Routine Description:
IcoWriteIconGroupToPeFileEx writes an icon group resource to a PE file.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
UpdateHandle - Specifies the resource update handle (returned by BeginUpdateResource).
IconGroup - Specifies the icon group to be inserted.
ResourceId - Receives the resource ID allocated for the newly inserted icon group.
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
WORD lastIndex = 0;
WORD lastIconIndex = 0;
PGRPICONDIR groupIconDir = NULL;
DWORD groupIconDirSize;
WORD i;
BOOL result = FALSE;
__try {
lastIndex = pGetAvailableResourceA (ModuleHandle, lastIndex, (PCSTR) RT_GROUP_ICON);
if (lastIndex == 0) {
// no more room for resources
__leave;
}
groupIconDirSize = sizeof (GRPICONDIRBASE) + IconGroup->IconsCount * sizeof (GRPICONDIRENTRY);
groupIconDir = MemAlloc (g_hHeap, 0, groupIconDirSize);
ZeroMemory (groupIconDir, groupIconDirSize);
groupIconDir->Type = 1;
groupIconDir->Count = IconGroup->IconsCount;
for (i = 0; i < groupIconDir->Count; i ++) {
groupIconDir->Entries[i].Width = IconGroup->Icons[i]->Width;
groupIconDir->Entries[i].Height = IconGroup->Icons[i]->Height;
groupIconDir->Entries[i].ColorCount = IconGroup->Icons[i]->ColorCount;
groupIconDir->Entries[i].Planes = IconGroup->Icons[i]->Planes;
groupIconDir->Entries[i].BitCount = IconGroup->Icons[i]->BitCount;
groupIconDir->Entries[i].BytesInRes = IconGroup->Icons[i]->Size;
lastIconIndex = pGetAvailableResourceA (ModuleHandle, lastIconIndex, (PCSTR) RT_ICON);
groupIconDir->Entries[i].ID = lastIconIndex;
lastIconIndex ++;
}
for (i = 0; i < groupIconDir->Count; i ++) {
if (!UpdateResourceA (
UpdateHandle,
(PCSTR) RT_ICON,
MAKEINTRESOURCEA (groupIconDir->Entries[i].ID),
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
IconGroup->Icons[i]->Image,
IconGroup->Icons[i]->Size
)) {
__leave;
}
}
if (!UpdateResourceA (
UpdateHandle,
(PCSTR) RT_GROUP_ICON,
MAKEINTRESOURCEA (lastIndex),
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
groupIconDir,
groupIconDirSize
)) {
__leave;
}
if (ResourceId) {
*ResourceId = MAKEINTRESOURCEA (lastIndex);
}
result = TRUE;
}
__finally {
if (groupIconDir) {
MemFree (g_hHeap, 0, groupIconDir);
}
}
return result;
}
BOOL
IcoWriteIconGroupToPeFileExW (
IN HANDLE ModuleHandle,
IN HANDLE UpdateHandle,
IN PICON_GROUP IconGroup,
OUT PCWSTR *ResourceId OPTIONAL
)
/*++
Routine Description:
IcoWriteIconGroupToPeFileEx writes an icon group resource to a PE file.
Arguments:
ModuleHandle - Specifies the handle to the PE file to be processed.
UpdateHandle - Specifies the resource update handle (returned by BeginUpdateResource).
IconGroup - Specifies the icon group to be inserted.
ResourceId - Receives the resource ID allocated for the newly inserted icon group.
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
WORD lastIndex = 0;
WORD lastIconIndex = 0;
PGRPICONDIR groupIconDir = NULL;
DWORD groupIconDirSize;
WORD i;
BOOL result = FALSE;
__try {
lastIndex = pGetAvailableResourceW (ModuleHandle, lastIndex, (PCWSTR) RT_GROUP_ICON);
if (lastIndex == 0) {
// no more room for resources
__leave;
}
groupIconDirSize = sizeof (GRPICONDIRBASE) + IconGroup->IconsCount * sizeof (GRPICONDIRENTRY);
groupIconDir = MemAlloc (g_hHeap, 0, groupIconDirSize);
ZeroMemory (groupIconDir, groupIconDirSize);
groupIconDir->Type = 1;
groupIconDir->Count = IconGroup->IconsCount;
for (i = 0; i < groupIconDir->Count; i ++) {
groupIconDir->Entries[i].Width = IconGroup->Icons[i]->Width;
groupIconDir->Entries[i].Height = IconGroup->Icons[i]->Height;
groupIconDir->Entries[i].ColorCount = IconGroup->Icons[i]->ColorCount;
groupIconDir->Entries[i].Planes = IconGroup->Icons[i]->Planes;
groupIconDir->Entries[i].BitCount = IconGroup->Icons[i]->BitCount;
groupIconDir->Entries[i].BytesInRes = IconGroup->Icons[i]->Size;
lastIconIndex = pGetAvailableResourceW (ModuleHandle, lastIconIndex, (PCWSTR) RT_ICON);
groupIconDir->Entries[i].ID = lastIconIndex;
lastIconIndex ++;
}
for (i = 0; i < groupIconDir->Count; i ++) {
if (!UpdateResourceW (
UpdateHandle,
(PCWSTR) RT_ICON,
MAKEINTRESOURCEW (groupIconDir->Entries[i].ID),
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
IconGroup->Icons[i]->Image,
IconGroup->Icons[i]->Size
)) {
__leave;
}
}
if (!UpdateResourceW (
UpdateHandle,
(PCWSTR) RT_GROUP_ICON,
MAKEINTRESOURCEW (lastIndex),
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
groupIconDir,
groupIconDirSize
)) {
__leave;
}
if (ResourceId) {
*ResourceId = MAKEINTRESOURCEW (lastIndex);
}
result = TRUE;
}
__finally {
if (groupIconDir) {
MemFree (g_hHeap, 0, groupIconDir);
}
}
return result;
}
BOOL
IcoWriteIconGroupToPeFileA (
IN PCSTR ModuleName,
IN PICON_GROUP IconGroup,
OUT PCSTR *ResourceId, OPTIONAL
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoWriteIconGroupToPeFile writes an icon group resource to a PE file.
Arguments:
ModuleName - Specifies the PE file to be processed.
IconGroup - Specifies the icon group to be inserted.
ResourceId - Receives the resource ID allocated for the newly inserted icon group.
Index - Receives the index of the newly inserted icon group.
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
HANDLE moduleHandle = NULL;
HANDLE updateHandle = NULL;
PCSTR resourceId;
BOOL result = FALSE;
updateHandle = BeginUpdateResourceA (ModuleName, FALSE);
if (updateHandle) {
//printf ("BeginUpdateResource\n");
moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
//printf ("IcoWriteIconGroupToPeFileExA\n");
result = IcoWriteIconGroupToPeFileExA (moduleHandle, updateHandle, IconGroup, &resourceId);
FreeLibrary (moduleHandle);
}
if (result) {
//printf ("EndUpdateResource\n");
result = EndUpdateResource (updateHandle, FALSE);
if (result) {
if (ResourceId) {
*ResourceId = resourceId;
} else {
IcoReleaseResourceIdA (resourceId);
}
if (Index) {
*Index = IcoGetIndexFromPeResourceIdA (ModuleName, resourceId);
}
}
} else {
EndUpdateResource (updateHandle, TRUE);
}
}
//printf ("return\n");
return result;
}
BOOL
IcoWriteIconGroupToPeFileW (
IN PCWSTR ModuleName,
IN PICON_GROUP IconGroup,
OUT PCWSTR *ResourceId, OPTIONAL
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoWriteIconGroupToPeFile writes an icon group resource to a PE file.
Arguments:
ModuleName - Specifies the PE file to be processed.
IconGroup - Specifies the icon group to be inserted.
ResourceId - Receives the resource ID allocated for the newly inserted icon group.
Index - Receives the index of the newly inserted icon group.
Return value:
TRUE if successfull, FALSE otherwise.
--*/
{
HANDLE moduleHandle = NULL;
HANDLE updateHandle = NULL;
PCWSTR resourceId;
BOOL result = FALSE;
updateHandle = BeginUpdateResourceW (ModuleName, FALSE);
if (updateHandle) {
moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (moduleHandle) {
result = IcoWriteIconGroupToPeFileExW (moduleHandle, updateHandle, IconGroup, &resourceId);
FreeLibrary (moduleHandle);
}
if (result) {
result = EndUpdateResource (updateHandle, FALSE);
if (result) {
if (ResourceId) {
*ResourceId = resourceId;
} else {
IcoReleaseResourceIdW (resourceId);
}
if (Index) {
*Index = IcoGetIndexFromPeResourceIdW (ModuleName, resourceId);
}
}
} else {
EndUpdateResource (updateHandle, TRUE);
}
}
return result;
}
BOOL
pNeEnumIconGroupA (
IN HANDLE Handle,
IN PCSTR Type,
IN PCSTR Name,
IN LPARAM lParam
)
{
PGROWBUFFER Buf;
PCSTR Num;
CHAR NumBuf[32];
Buf = (PGROWBUFFER) lParam;
if ((ULONG_PTR) Name > 0xffff) {
Num = Name;
} else {
Num = NumBuf;
wsprintfA (NumBuf, "#%u", Name);
}
GbMultiSzAppendA (Buf, Num);
return TRUE;
}
BOOL
pNeEnumIconGroupW (
IN HANDLE Handle,
IN PCWSTR Type,
IN PCWSTR Name,
IN LPARAM lParam
)
{
PGROWBUFFER Buf;
PCWSTR Num;
WCHAR NumBuf[32];
Buf = (PGROWBUFFER) lParam;
if ((ULONG_PTR) Name > 0xffff) {
Num = Name;
} else {
Num = NumBuf;
wsprintfW (NumBuf, L"#%u", Name);
}
GbMultiSzAppendW (Buf, Num);
return TRUE;
}
INT
IcoGetIndexFromNeResourceIdExA (
IN HANDLE ModuleHandle,
IN PCSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromNeResourceIdEx returns the index of an icon group resource given the
resource ID. It knows how to process only NE files.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
GROWBUFFER buffer = INIT_GROWBUFFER;
MULTISZ_ENUMA multiSzEnum;
CHAR NumBuf[32];
INT index = 0;
BOOL result = FALSE;
if ((ULONG_PTR) GroupIconId < 0x10000) {
wsprintfA (NumBuf, "#%u", GroupIconId);
GroupIconId = NumBuf;
}
if (NeEnumResourceNamesA (
ModuleHandle,
(PCSTR) RT_GROUP_ICON,
pNeEnumIconGroupA,
(LONG_PTR) (&buffer)
)) {
GbMultiSzAppendA (&buffer, "");
if (EnumFirstMultiSzA (&multiSzEnum, (PCSTR)(buffer.Buf))) {
do {
if (StringIMatchA (multiSzEnum.CurrentString, GroupIconId)) {
result = TRUE;
break;
}
index ++;
} while (EnumNextMultiSzA (&multiSzEnum));
}
}
if (!result) {
index = -1;
}
return index;
}
INT
IcoGetIndexFromNeResourceIdExW (
IN HANDLE ModuleHandle,
IN PCWSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromNeResourceIdEx returns the index of an icon group resource given the
resource ID. It knows how to process only NE files.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
GROWBUFFER buffer = INIT_GROWBUFFER;
MULTISZ_ENUMW multiSzEnum;
WCHAR NumBuf[32];
INT index = 0;
BOOL result = FALSE;
if ((ULONG_PTR) GroupIconId < 0x10000) {
wsprintfW (NumBuf, L"#%u", GroupIconId);
GroupIconId = NumBuf;
}
if (NeEnumResourceNamesW (
ModuleHandle,
(PCWSTR) RT_GROUP_ICON,
pNeEnumIconGroupW,
(LONG_PTR) (&buffer)
)) {
GbMultiSzAppendW (&buffer, L"");
if (EnumFirstMultiSzW (&multiSzEnum, (PCWSTR)(buffer.Buf))) {
do {
if (StringIMatchW (multiSzEnum.CurrentString, GroupIconId)) {
result = TRUE;
break;
}
index ++;
} while (EnumNextMultiSzW (&multiSzEnum));
}
}
if (!result) {
index = -1;
}
return index;
}
INT
IcoGetIndexFromNeResourceIdA (
IN PCSTR ModuleName,
IN PCSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromNeResourceId returns the index of an icon group resource given the
resource ID. It knows how to process only NE files.
Arguments:
ModuleName - Specifies the NE file to be processed.
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
HANDLE moduleHandle;
INT result = -1;
moduleHandle = NeOpenFileA (ModuleName);
if (moduleHandle) {
result = IcoGetIndexFromNeResourceIdExA (moduleHandle, GroupIconId);
NeCloseFile (moduleHandle);
}
return result;
}
INT
IcoGetIndexFromNeResourceIdW (
IN PCWSTR ModuleName,
IN PCWSTR GroupIconId
)
/*++
Routine Description:
IcoGetIndexFromNeResourceId returns the index of an icon group resource given the
resource ID. It knows how to process only NE files.
Arguments:
ModuleName - Specifies the NE file to be processed.
GroupIconId - Specifies the resource ID.
Return value:
The index of GroupIconId resource if existent, -1 if not.
--*/
{
HANDLE moduleHandle;
INT result = -1;
moduleHandle = NeOpenFileW (ModuleName);
if (moduleHandle) {
result = IcoGetIndexFromNeResourceIdExW (moduleHandle, GroupIconId);
NeCloseFile (moduleHandle);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupFromNeFileExA (
IN HANDLE ModuleHandle,
IN PCSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromNeFileEx extracts an icon group from a NE file.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PMHANDLE iconPool = NULL;
PICON_GROUP iconGroup = NULL;
DWORD iconGroupSize = 0;
PICON_IMAGE iconImage = NULL;
PGRPICONDIRENTRY iconDirEntry;
PBYTE resourceData;
DWORD resourceSize;
PGRPICONDIR groupIconDir;
WORD i;
BOOL result = FALSE;
__try {
groupIconDir = (PGRPICONDIR) NeFindResourceExA (ModuleHandle, (PCSTR) RT_GROUP_ICON, GroupIconId);
if (!groupIconDir) {
__leave;
}
iconPool = PmCreateNamedPool ("Icon");
if (!iconPool) {
__leave;
}
iconGroupSize = sizeof (ICON_GROUP) + groupIconDir->Count * sizeof (PICON_IMAGE);
iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
ZeroMemory (iconGroup, iconGroupSize);
iconGroup->Pool = iconPool;
iconGroup->IconsCount = groupIconDir->Count;
for (i = 0; i < groupIconDir->Count; i ++) {
resourceData = NeFindResourceExA (
ModuleHandle,
(PCSTR) RT_ICON,
(PCSTR) groupIconDir->Entries[i].ID
);
if (!resourceData) {
__leave;
}
resourceSize = NeSizeofResourceA (
ModuleHandle,
(PCSTR) RT_ICON,
(PCSTR) groupIconDir->Entries[i].ID
);
if (!resourceSize) {
__leave;
}
iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
ZeroMemory (iconImage, sizeof (ICON_IMAGE));
iconDirEntry = &groupIconDir->Entries[i];
iconImage->Width = iconDirEntry->Width;
iconImage->Height = iconDirEntry->Height;
iconImage->ColorCount = iconDirEntry->ColorCount;
iconImage->Planes = iconDirEntry->Planes;
iconImage->BitCount = iconDirEntry->BitCount;
iconImage->Size = iconDirEntry->BytesInRes;
if (iconImage->Size > resourceSize) {
iconImage->Size = resourceSize;
}
iconImage->Id = iconDirEntry->ID;
iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
CopyMemory (iconImage->Image, resourceData, iconImage->Size);
iconGroup->Icons [i] = iconImage;
}
if (Index) {
*Index = IcoGetIndexFromNeResourceIdExA (ModuleHandle, GroupIconId);
}
result = TRUE;
}
__finally {
if (!result) {
if (iconPool) {
PmEmptyPool (iconPool);
PmDestroyPool (iconPool);
iconPool = NULL;
}
iconGroup = NULL;
}
}
return iconGroup;
}
PICON_GROUP
IcoExtractIconGroupFromNeFileExW (
IN HANDLE ModuleHandle,
IN PCWSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromNeFileEx extracts an icon group from a NE file.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PMHANDLE iconPool = NULL;
PICON_GROUP iconGroup = NULL;
DWORD iconGroupSize = 0;
PICON_IMAGE iconImage = NULL;
PGRPICONDIRENTRY iconDirEntry;
PBYTE resourceData;
DWORD resourceSize;
PGRPICONDIR groupIconDir;
WORD i;
BOOL result = FALSE;
__try {
groupIconDir = (PGRPICONDIR) NeFindResourceExW (ModuleHandle, (PCWSTR) RT_GROUP_ICON, GroupIconId);
if (!groupIconDir) {
__leave;
}
iconPool = PmCreateNamedPool ("Icon");
if (!iconPool) {
__leave;
}
iconGroupSize = sizeof (ICON_GROUP) + groupIconDir->Count * sizeof (PICON_IMAGE);
iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
ZeroMemory (iconGroup, iconGroupSize);
iconGroup->Pool = iconPool;
iconGroup->IconsCount = groupIconDir->Count;
for (i = 0; i < groupIconDir->Count; i ++) {
resourceData = NeFindResourceExW (
ModuleHandle,
(PCWSTR) RT_ICON,
(PCWSTR) groupIconDir->Entries[i].ID
);
if (!resourceData) {
__leave;
}
resourceSize = NeSizeofResourceW (
ModuleHandle,
(PCWSTR) RT_ICON,
(PCWSTR) groupIconDir->Entries[i].ID
);
if (!resourceSize) {
__leave;
}
iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
ZeroMemory (iconImage, sizeof (ICON_IMAGE));
iconDirEntry = &groupIconDir->Entries[i];
iconImage->Width = iconDirEntry->Width;
iconImage->Height = iconDirEntry->Height;
iconImage->ColorCount = iconDirEntry->ColorCount;
iconImage->Planes = iconDirEntry->Planes;
iconImage->BitCount = iconDirEntry->BitCount;
iconImage->Size = iconDirEntry->BytesInRes;
if (iconImage->Size > resourceSize) {
iconImage->Size = resourceSize;
}
iconImage->Id = iconDirEntry->ID;
iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
CopyMemory (iconImage->Image, resourceData, iconImage->Size);
iconGroup->Icons [i] = iconImage;
}
if (Index) {
*Index = IcoGetIndexFromNeResourceIdExW (ModuleHandle, GroupIconId);
}
result = TRUE;
}
__finally {
if (!result) {
if (iconPool) {
PmEmptyPool (iconPool);
PmDestroyPool (iconPool);
iconPool = NULL;
}
iconGroup = NULL;
}
}
return iconGroup;
}
PICON_GROUP
IcoExtractIconGroupFromNeFileA (
IN PCSTR ModuleName,
IN PCSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromNeFile extracts an icon group from a NE file.
Arguments:
ModuleName - Specifies the NE file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = NeOpenFileA (ModuleName);
if (moduleHandle) {
result = IcoExtractIconGroupFromNeFileExA (moduleHandle, GroupIconId, Index);
NeCloseFile (moduleHandle);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupFromNeFileW (
IN PCWSTR ModuleName,
IN PCWSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromNeFile extracts an icon group from a NE file.
Arguments:
ModuleName - Specifies the NE file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = NeOpenFileW (ModuleName);
if (moduleHandle) {
result = IcoExtractIconGroupFromNeFileExW (moduleHandle, GroupIconId, Index);
NeCloseFile (moduleHandle);
}
return result;
}
VOID
IcoAbortNeEnumIconGroupA (
IN OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoAbortNeEnumIconGroup terminates the icon group enumeration from a NE file.
Arguments:
IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
Return value:
None
--*/
{
GbFree (&IconEnum->Buffer);
if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
NeCloseFile (IconEnum->ModuleHandle);
}
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
}
if (IconEnum->ResourceId) {
FreePathStringA (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
}
VOID
IcoAbortNeEnumIconGroupW (
IN OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoAbortNeEnumIconGroup terminates the icon group enumeration from a NE file.
Arguments:
IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
Return value:
None
--*/
{
GbFree (&IconEnum->Buffer);
if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
NeCloseFile (IconEnum->ModuleHandle);
}
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
}
if (IconEnum->ResourceId) {
FreePathStringW (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
}
BOOL
pEnumFirstIconGroupInNeFileExA (
IN OUT PICON_ENUMA IconEnum
)
{
BOOL result = FALSE;
if (NeEnumResourceNamesA (
IconEnum->ModuleHandle,
(PCSTR) RT_GROUP_ICON,
pNeEnumIconGroupA,
(LONG_PTR) (&IconEnum->Buffer)
)) {
GbMultiSzAppendA (&IconEnum->Buffer, "");
if (EnumFirstMultiSzA (&IconEnum->MultiSzEnum, (PCSTR)(IconEnum->Buffer.Buf))) {
IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExA (
IconEnum->ModuleHandle,
IconEnum->MultiSzEnum.CurrentString,
NULL
);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
}
}
}
if (!result) {
IcoAbortNeEnumIconGroupA (IconEnum);
}
return result;
}
BOOL
pEnumFirstIconGroupInNeFileExW (
IN OUT PICON_ENUMW IconEnum
)
{
BOOL result = FALSE;
if (NeEnumResourceNamesW (
IconEnum->ModuleHandle,
(PCWSTR) RT_GROUP_ICON,
pNeEnumIconGroupW,
(LONG_PTR) (&IconEnum->Buffer)
)) {
GbMultiSzAppendW (&IconEnum->Buffer, L"");
if (EnumFirstMultiSzW (&IconEnum->MultiSzEnum, (PCWSTR)(IconEnum->Buffer.Buf))) {
IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExW (
IconEnum->ModuleHandle,
IconEnum->MultiSzEnum.CurrentString,
NULL
);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
}
}
}
if (!result) {
IcoAbortNeEnumIconGroupW (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInNeFileExA (
IN HANDLE ModuleHandle,
OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInNeFileEx starts the icon group enumeration from a NE file.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
IconEnum->FreeHandle = FALSE;
IconEnum->ModuleHandle = ModuleHandle;
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInNeFileExA (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInNeFileExW (
IN HANDLE ModuleHandle,
OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInNeFileEx starts the icon group enumeration from a NE file.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
IconEnum->FreeHandle = FALSE;
IconEnum->ModuleHandle = ModuleHandle;
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInNeFileExW (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInNeFileA (
IN PCSTR ModuleName,
OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInNeFile starts the icon group enumeration from a NE file.
Arguments:
ModuleName - Specifies the NE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
IconEnum->FreeHandle = TRUE;
IconEnum->ModuleHandle = NeOpenFileA (ModuleName);
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInNeFileExA (IconEnum);
}
return result;
}
BOOL
IcoEnumFirstIconGroupInNeFileW (
IN PCWSTR ModuleName,
OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInNeFile starts the icon group enumeration from a NE file.
Arguments:
ModuleName - Specifies the NE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
IconEnum->FreeHandle = TRUE;
IconEnum->ModuleHandle = NeOpenFileW (ModuleName);
if (IconEnum->ModuleHandle) {
result = pEnumFirstIconGroupInNeFileExW (IconEnum);
}
return result;
}
BOOL
IcoEnumNextIconGroupInNeFileA (
IN OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumNextIconGroupInNeFile continues the icon group enumeration from a NE file.
Arguments:
IconEnum - Specifies and receives the icon group enumeration structure.
Return value:
TRUE if one more icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
IconEnum->IconGroup = NULL;
}
if (IconEnum->ResourceId) {
FreePathStringA (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
if (EnumNextMultiSzA (&IconEnum->MultiSzEnum)) {
IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExA (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
IconEnum->Index ++;
}
}
if (!result) {
IcoAbortNeEnumIconGroupA (IconEnum);
}
return result;
}
BOOL
IcoEnumNextIconGroupInNeFileW (
IN OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumNextIconGroupInNeFile continues the icon group enumeration from a NE file.
Arguments:
IconEnum - Specifies and receives the icon group enumeration structure.
Return value:
TRUE if one more icon group exists, FALSE otherwise.
--*/
{
BOOL result = FALSE;
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
IconEnum->IconGroup = NULL;
}
if (IconEnum->ResourceId) {
FreePathStringW (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
if (EnumNextMultiSzW (&IconEnum->MultiSzEnum)) {
IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExW (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
result = (IconEnum->IconGroup != NULL);
if (result) {
IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
IconEnum->Index ++;
}
}
if (!result) {
IcoAbortNeEnumIconGroupW (IconEnum);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromNeFileExA (
IN HANDLE ModuleHandle,
IN INT Index,
OUT PCSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupByIndexFromNeFileEx extracts an icon group from a NE file
using the Index.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
ICON_ENUMA iconEnum;
PICON_GROUP result = NULL;
if (IcoEnumFirstIconGroupInNeFileExA (ModuleHandle, &iconEnum)) {
do {
if (iconEnum.Index == Index) {
result = iconEnum.IconGroup;
iconEnum.IconGroup = NULL;
if (GroupIconId) {
*GroupIconId = iconEnum.ResourceId;
iconEnum.ResourceId = NULL;
}
break;
}
} while (IcoEnumNextIconGroupInNeFileA (&iconEnum));
IcoAbortNeEnumIconGroupA (&iconEnum);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromNeFileExW (
IN HANDLE ModuleHandle,
IN INT Index,
OUT PCWSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupByIndexFromNeFileEx extracts an icon group from a NE file
using the Index.
Arguments:
ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
ICON_ENUMW iconEnum;
PICON_GROUP result = NULL;
if (IcoEnumFirstIconGroupInNeFileExW (ModuleHandle, &iconEnum)) {
do {
if (iconEnum.Index == Index) {
result = iconEnum.IconGroup;
iconEnum.IconGroup = NULL;
if (GroupIconId) {
*GroupIconId = iconEnum.ResourceId;
iconEnum.ResourceId = NULL;
}
break;
}
} while (IcoEnumNextIconGroupInNeFileW (&iconEnum));
IcoAbortNeEnumIconGroupW (&iconEnum);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromNeFileA (
IN PCSTR ModuleName,
IN INT Index,
OUT PCSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromNeFile extracts an icon group from a NE file
using the Index.
Arguments:
ModuleName - Specifies the NE file to be processed.
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = NeOpenFileA (ModuleName);
if (moduleHandle) {
result = IcoExtractIconGroupByIndexFromNeFileExA (moduleHandle, Index, GroupIconId);
NeCloseFile (moduleHandle);
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromNeFileW (
IN PCWSTR ModuleName,
IN INT Index,
OUT PCWSTR *GroupIconId OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromNeFile extracts an icon group from a NE file
using the Index.
Arguments:
ModuleName - Specifies the NE file to be processed.
Index - Specifies the index of the icon group to be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
HANDLE moduleHandle;
PICON_GROUP result = NULL;
moduleHandle = NeOpenFileW (ModuleName);
if (moduleHandle) {
result = IcoExtractIconGroupByIndexFromNeFileExW (moduleHandle, Index, GroupIconId);
NeCloseFile (moduleHandle);
}
return result;
}
VOID
IcoAbortEnumIconGroupA (
IN OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoAbortEnumIconGroup terminates the icon group enumeration from a ICO, PE or NE file.
Arguments:
IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
Return value:
None
--*/
{
GbFree (&IconEnum->Buffer);
if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
if (IconEnum->FileType == ICON_PEFILE) {
FreeLibrary (IconEnum->ModuleHandle);
}
if (IconEnum->FileType == ICON_NEFILE) {
NeCloseFile (IconEnum->ModuleHandle);
}
}
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
}
if (IconEnum->ResourceId) {
FreePathStringA (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
}
VOID
IcoAbortEnumIconGroupW (
IN OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoAbortEnumIconGroup terminates the icon group enumeration from a ICO, PE or NE file.
Arguments:
IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
Return value:
None
--*/
{
GbFree (&IconEnum->Buffer);
if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
if (IconEnum->FileType == ICON_PEFILE) {
FreeLibrary (IconEnum->ModuleHandle);
}
if (IconEnum->FileType == ICON_NEFILE) {
NeCloseFile (IconEnum->ModuleHandle);
}
}
if (IconEnum->IconGroup) {
IcoReleaseIconGroup (IconEnum->IconGroup);
}
if (IconEnum->ResourceId) {
FreePathStringW (IconEnum->ResourceId);
IconEnum->ResourceId = NULL;
}
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
}
BOOL
IcoEnumFirstIconGroupInFileA (
IN PCSTR FileName,
OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInFile starts the icon group enumeration from a ICO, PE or NE file.
Arguments:
ModuleName - Specifies the ICO, PE or NE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
if (IcoEnumFirstIconGroupInPeFileA (FileName, IconEnum)) {
IconEnum->FileType = ICON_PEFILE;
return TRUE;
}
if (IcoEnumFirstIconGroupInNeFileA (FileName, IconEnum)) {
IconEnum->FileType = ICON_NEFILE;
return TRUE;
}
IconEnum->IconGroup = IcoExtractIconGroupFromIcoFileA (FileName);
if (IconEnum->IconGroup) {
IconEnum->FileType = ICON_ICOFILE;
return TRUE;
}
return FALSE;
}
BOOL
IcoEnumFirstIconGroupInFileW (
IN PCWSTR FileName,
OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumFirstIconGroupInFile starts the icon group enumeration from a ICO, PE or NE file.
Arguments:
ModuleName - Specifies the ICO, PE or NE file to be processed.
IconEnum - Receives the icon group enumeration structure.
Return value:
TRUE if at least one icon group exists, FALSE otherwise.
--*/
{
ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
if (IcoEnumFirstIconGroupInPeFileW (FileName, IconEnum)) {
IconEnum->FileType = ICON_PEFILE;
return TRUE;
}
if (IcoEnumFirstIconGroupInNeFileW (FileName, IconEnum)) {
IconEnum->FileType = ICON_NEFILE;
return TRUE;
}
IconEnum->IconGroup = IcoExtractIconGroupFromIcoFileW (FileName);
if (IconEnum->IconGroup) {
IconEnum->FileType = ICON_ICOFILE;
return TRUE;
}
return FALSE;
}
BOOL
IcoEnumNextIconGroupInFileA (
IN OUT PICON_ENUMA IconEnum
)
/*++
Routine Description:
IcoEnumNextIconGroupInFile continues the icon group enumeration from a ICO, PE or NE file.
Arguments:
IconEnum - Specifies and receives the icon group enumeration structure.
Return value:
TRUE if one more icon group exists, FALSE otherwise.
--*/
{
if (IconEnum->FileType == ICON_ICOFILE) {
IcoAbortEnumIconGroupA (IconEnum);
return FALSE;
}
if (IconEnum->FileType == ICON_PEFILE) {
return IcoEnumNextIconGroupInPeFileA (IconEnum);
}
if (IconEnum->FileType == ICON_NEFILE) {
return IcoEnumNextIconGroupInNeFileA (IconEnum);
}
return FALSE;
}
BOOL
IcoEnumNextIconGroupInFileW (
IN OUT PICON_ENUMW IconEnum
)
/*++
Routine Description:
IcoEnumNextIconGroupInFile continues the icon group enumeration from a ICO, PE or NE file.
Arguments:
IconEnum - Specifies and receives the icon group enumeration structure.
Return value:
TRUE if one more icon group exists, FALSE otherwise.
--*/
{
if (IconEnum->FileType == ICON_ICOFILE) {
IcoAbortEnumIconGroupW (IconEnum);
return FALSE;
}
if (IconEnum->FileType == ICON_PEFILE) {
return IcoEnumNextIconGroupInPeFileW (IconEnum);
}
if (IconEnum->FileType == ICON_NEFILE) {
return IcoEnumNextIconGroupInNeFileW (IconEnum);
}
return FALSE;
}
PICON_GROUP
IcoExtractIconGroupFromFileA (
IN PCSTR ModuleName,
IN PCSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromFile extracts an icon group from a ICO, PE or NE file.
Arguments:
ModuleName - Specifies the file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PICON_GROUP result = NULL;
// assume that this is a PE file
result = IcoExtractIconGroupFromPeFileA (ModuleName, GroupIconId, Index);
if (result) {
return result;
}
// assume that this is a NE file
result = IcoExtractIconGroupFromNeFileA (ModuleName, GroupIconId, Index);
if (result) {
return result;
}
// finally, assume that this is a ICO file, verify that
// the GroupIconId is zero
if (GroupIconId == NULL) {
result = IcoExtractIconGroupFromIcoFileA (ModuleName);
if (result && Index) {
*Index = 0;
}
}
return result;
}
PICON_GROUP
IcoExtractIconGroupFromFileW (
IN PCWSTR ModuleName,
IN PCWSTR GroupIconId,
OUT PINT Index OPTIONAL
)
/*++
Routine Description:
IcoExtractIconGroupFromFile extracts an icon group from a ICO, PE or NE file.
Arguments:
ModuleName - Specifies the file to be processed.
GroupIconId - Specifies the resource ID of the icon group to be extracted.
Index - Receives the index of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PICON_GROUP result = NULL;
// assume that this is a PE file
result = IcoExtractIconGroupFromPeFileW (ModuleName, GroupIconId, Index);
if (result) {
return result;
}
// assume that this is a NE file
result = IcoExtractIconGroupFromNeFileW (ModuleName, GroupIconId, Index);
if (result) {
return result;
}
// finally, assume that this is a ICO file, verify that
// the GroupIconId is zero
if (GroupIconId == NULL) {
result = IcoExtractIconGroupFromIcoFileW (ModuleName);
if (result && Index) {
*Index = 0;
}
return result;
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromFileA (
IN PCSTR ModuleName,
IN INT Index,
OUT PCSTR *GroupIconId
)
/*++
Routine Description:
IcoExtractIconGroupByIndexFromFile extracts an icon group from a ICO, PE or NE file
using the Index.
Arguments:
ModuleName - Specifies the file to be processed.
Index - Specifies the index of the icon groupto be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PICON_GROUP result = NULL;
// assume that this is a PE file
result = IcoExtractIconGroupByIndexFromPeFileA (ModuleName, Index, GroupIconId);
if (result) {
return result;
}
// assume that this is a NE file
result = IcoExtractIconGroupByIndexFromNeFileA (ModuleName, Index, GroupIconId);
if (result) {
return result;
}
// finally, assume that this is a ICO file, verify that
// the Index is zero
if (Index == 0) {
result = IcoExtractIconGroupFromIcoFileA (ModuleName);
if (result && GroupIconId) {
*GroupIconId = NULL;
}
return result;
}
return result;
}
PICON_GROUP
IcoExtractIconGroupByIndexFromFileW (
IN PCWSTR ModuleName,
IN INT Index,
OUT PCWSTR *GroupIconId
)
/*++
Routine Description:
IcoExtractIconGroupByIndexFromFile extracts an icon group from a ICO, PE or NE file
using the Index.
Arguments:
ModuleName - Specifies the file to be processed.
Index - Specifies the index of the icon groupto be extracted.
GroupIconId - Receives the resource ID of the icon group extracted.
Return value:
An icon group if successfull, NULL otherwise.
--*/
{
PICON_GROUP result = NULL;
// assume that this is a PE file
result = IcoExtractIconGroupByIndexFromPeFileW (ModuleName, Index, GroupIconId);
if (result) {
return result;
}
// assume that this is a NE file
result = IcoExtractIconGroupByIndexFromNeFileW (ModuleName, Index, GroupIconId);
if (result) {
return result;
}
// finally, assume that this is a ICO file, verify that
// the Index is zero
if (Index == 0) {
result = IcoExtractIconGroupFromIcoFileW (ModuleName);
if (result && GroupIconId) {
*GroupIconId = NULL;
}
return result;
}
return result;
}