mirror of https://github.com/tongzx/nt5src
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.
3515 lines
87 KiB
3515 lines
87 KiB
/*++
|
|
|
|
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;
|
|
}
|