windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/common/migutil/ne.c
2020-09-26 16:20:57 +08:00

1262 lines
26 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
ne.c
Abstract:
New-Executable parsing routines
Author:
Jim Schmidt (jimschm) 04-May-1998
Revision History:
jimschm 23-Sep-1998 Named icon ID bug fix, error path fixes
--*/
#include "pch.h"
#include "migutilp.h"
//
// NE code
//
typedef struct {
HANDLE File;
DWORD HeaderOffset;
NE_INFO_BLOCK Header;
NE_RESOURCES Resources;
BOOL ResourcesLoaded;
POOLHANDLE ResourcePool;
} NE_HANDLE, *PNE_HANDLE;
typedef BOOL (CALLBACK* ENUMRESTYPEPROCEXA)(HMODULE hModule, PCSTR lpType, LONG_PTR lParam, PNE_RES_TYPEINFO TypeInfo);
typedef BOOL (CALLBACK* ENUMRESTYPEPROCEXW)(HMODULE hModule, PCWSTR lpType, LONG_PTR lParam, PNE_RES_TYPEINFO TypeInfo);
typedef BOOL (CALLBACK* ENUMRESNAMEPROCEXA)(HMODULE hModule, PCSTR lpType,
PSTR lpName, LONG_PTR lParam, PNE_RES_TYPEINFO TypeInfo, PNE_RES_NAMEINFO NameInfo);
typedef BOOL (CALLBACK* ENUMRESNAMEPROCEXW)(HMODULE hModule, PCWSTR lpType,
PWSTR lpName, LONG_PTR lParam, PNE_RES_TYPEINFO TypeInfo, PNE_RES_NAMEINFO NameInfo);
typedef struct {
PCSTR TypeToFind;
PNE_RES_TYPEINFO OutboundTypeInfo;
BOOL Found;
} TYPESEARCHDATAA, *PTYPESEARCHDATAA;
typedef struct {
PCSTR NameToFind;
PNE_RES_TYPEINFO OutboundTypeInfo;
PNE_RES_NAMEINFO OutboundNameInfo;
BOOL Found;
} NAMESEARCHDATAA, *PNAMESEARCHDATAA;
BOOL
LoadNeHeader (
IN HANDLE File,
OUT PNE_INFO_BLOCK Header
)
{
DOS_HEADER dh;
LONG rc = ERROR_BAD_FORMAT;
BOOL b = FALSE;
__try {
SetFilePointer (File, 0, NULL, FILE_BEGIN);
if (!ReadBinaryBlock (File, &dh, sizeof (DOS_HEADER))) {
__leave;
}
if (dh.e_magic != ('M' + 'Z' * 256)) {
__leave;
}
SetFilePointer (File, dh.e_lfanew, NULL, FILE_BEGIN);
if (!ReadBinaryBlock (File, Header, sizeof (NE_INFO_BLOCK))) {
__leave;
}
if (Header->Signature != ('N' + 'E' * 256) &&
Header->Signature != ('L' + 'E' * 256)
) {
if (Header->Signature == ('P' + 'E' * 256)) {
rc = ERROR_BAD_EXE_FORMAT;
} else {
rc = ERROR_INVALID_EXE_SIGNATURE;
}
DEBUGMSG ((DBG_NAUSEA, "Header signature is %c%c", Header->Signature & 0xff, Header->Signature >> 8));
__leave;
}
SetFilePointer (File, (DWORD) dh.e_lfanew, NULL, FILE_BEGIN);
b = TRUE;
}
__finally {
if (!b) {
SetLastError (rc);
}
}
return b;
}
DWORD
pComputeSizeOfTypeInfo (
IN PNE_RES_TYPEINFO TypeInfo
)
{
return sizeof (NE_RES_TYPEINFO) + TypeInfo->ResourceCount * sizeof (NE_RES_NAMEINFO);
}
PNE_RES_TYPEINFO
pReadNextTypeInfoStruct (
IN HANDLE File,
IN POOLHANDLE Pool
)
{
WORD Type;
WORD ResCount;
NE_RES_TYPEINFO TypeInfo;
PNE_RES_TYPEINFO ReturnInfo = NULL;
DWORD Size;
if (!ReadBinaryBlock (File, &Type, sizeof (WORD))) {
return NULL;
}
if (!Type) {
return NULL;
}
if (!ReadBinaryBlock (File, &ResCount, sizeof (WORD))) {
return NULL;
}
TypeInfo.TypeId = Type;
TypeInfo.ResourceCount = ResCount;
if (!ReadBinaryBlock (File, &TypeInfo.Reserved, sizeof (DWORD))) {
return NULL;
}
Size = sizeof (NE_RES_NAMEINFO) * ResCount;
ReturnInfo = (PNE_RES_TYPEINFO) PoolMemGetMemory (Pool, Size + sizeof (TypeInfo));
if (!ReturnInfo) {
return NULL;
}
CopyMemory (ReturnInfo, &TypeInfo, sizeof (TypeInfo));
if (!ReadBinaryBlock (File, (PBYTE) ReturnInfo + sizeof (TypeInfo), Size)) {
return NULL;
}
return ReturnInfo;
}
BOOL
pReadTypeInfoArray (
IN HANDLE File,
IN OUT PGROWLIST TypeInfoList
)
{
PNE_RES_TYPEINFO TypeInfo;
DWORD Size;
POOLHANDLE TempPool;
BOOL b = FALSE;
TempPool = PoolMemInitPool();
if (!TempPool) {
return FALSE;
}
__try {
TypeInfo = pReadNextTypeInfoStruct (File, TempPool);
while (TypeInfo) {
Size = pComputeSizeOfTypeInfo (TypeInfo);
if (!GrowListAppend (TypeInfoList, (PBYTE) TypeInfo, Size)) {
__leave;
}
TypeInfo = pReadNextTypeInfoStruct (File, TempPool);
}
b = TRUE;
}
__finally {
PoolMemDestroyPool (TempPool);
}
return b;
}
BOOL
pReadStringArrayA (
IN HANDLE File,
IN OUT PGROWLIST GrowList
)
{
BYTE Size;
CHAR Name[256];
if (!ReadBinaryBlock (File, &Size, sizeof (BYTE))) {
return FALSE;
}
while (Size) {
if (!ReadBinaryBlock (File, Name, (DWORD) Size)) {
return FALSE;
}
Name[Size] = 0;
GrowListAppendString (GrowList, Name);
if (!ReadBinaryBlock (File, &Size, sizeof (BYTE))) {
return FALSE;
}
}
return TRUE;
}
BOOL
LoadNeResources (
IN HANDLE File,
OUT PNE_RESOURCES Resources
)
{
NE_INFO_BLOCK Header;
ZeroMemory (Resources, sizeof (NE_RESOURCES));
if (!LoadNeHeader (File, &Header)) {
return FALSE;
}
//
// Read in NE_RESOURCES struct
//
SetFilePointer (File, (DWORD) Header.OffsetToResourceTable, NULL, FILE_CURRENT);
if (!ReadBinaryBlock (File, &Resources->AlignShift, sizeof (WORD))) {
return FALSE;
}
// Array of NE_RES_TYPEINFO structs
if (!pReadTypeInfoArray (File, &Resources->TypeInfoArray)) {
return FALSE;
}
// Resource names
if (!pReadStringArrayA (File, &Resources->ResourceNames)) {
return FALSE;
}
return TRUE;
}
VOID
FreeNeResources (
PNE_RESOURCES Resources
)
{
FreeGrowList (&Resources->TypeInfoArray);
FreeGrowList (&Resources->ResourceNames);
ZeroMemory (Resources, sizeof (NE_RESOURCES));
}
BOOL
LoadNeIcon (
HANDLE File,
INT IconIndex
)
{
NE_RESOURCES Resources;
INT Count;
INT i;
PNE_RES_TYPEINFO TypeInfo = NULL;
BOOL b = FALSE;
DWORD Offset;
WORD w;
PNE_RES_NAMEINFO NameInfo;
DWORD Length;
PBYTE Data;
if (!LoadNeResources (File, &Resources)) {
return FALSE;
}
__try {
//
// Search resources for RT_GROUPICON
//
Count = GrowListGetSize (&Resources.TypeInfoArray);
for (i = 0 ; i < Count ; i++) {
TypeInfo = (PNE_RES_TYPEINFO) GrowListGetItem (&Resources.TypeInfoArray, i);
if (TypeInfo->TypeId == (WORD) RT_GROUP_ICON) {
break;
}
}
if (i == Count) {
__leave;
}
//
// Identify which group icon
//
NameInfo = TypeInfo->NameInfo;
for (w = 0 ; w < TypeInfo->ResourceCount ; w++) {
if (IconIndex > 0) {
IconIndex--;
} else if (!IconIndex) {
break;
} else if (-IconIndex == (INT) NameInfo->Id) {
break;
}
NameInfo++;
}
if (w == TypeInfo->ResourceCount) {
__leave;
}
//
// Load the group icon resource
//
Offset = (DWORD) NameInfo->Offset << (DWORD) Resources.AlignShift;
Length = (DWORD) NameInfo->Length << (DWORD) Resources.AlignShift;
Data = MemAlloc (g_hHeap, 0, Length);
if (!Data) {
__leave;
}
SetFilePointer (File, Offset, NULL, FILE_BEGIN);
ReadBinaryBlock (File, Data, Length);
MemFree (g_hHeap, 0, Data);
b = TRUE;
}
__finally {
FreeNeResources (&Resources);
}
return b;
}
BOOL
LoadNeIconFromFileA (
PCSTR FileName,
INT IconIndex
)
{
HANDLE File;
BOOL b;
File = OpenNeFileA (FileName);
if (!File) {
return FALSE;
}
b = LoadNeIcon (File, IconIndex);
CloseNeFile (File);
return b;
}
HANDLE
OpenNeFileA (
PCSTR FileName
)
{
PNE_HANDLE NeHandle;
BOOL b = FALSE;
NeHandle = (PNE_HANDLE) MemAlloc (g_hHeap, HEAP_ZERO_MEMORY, sizeof (NE_HANDLE));
__try {
NeHandle->ResourcePool = PoolMemInitPool();
if (!NeHandle->ResourcePool) {
__leave;
}
NeHandle->File = CreateFileA (
FileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (NeHandle->File == INVALID_HANDLE_VALUE) {
__leave;
}
if (!LoadNeHeader (NeHandle->File, &NeHandle->Header)) {
__leave;
}
NeHandle->HeaderOffset = SetFilePointer (NeHandle->File, 0, NULL, FILE_CURRENT);
b = TRUE;
}
__finally {
if (!b) {
PushError();
if (NeHandle->ResourcePool) {
PoolMemDestroyPool (NeHandle->ResourcePool);
}
if (NeHandle->File != INVALID_HANDLE_VALUE) {
CloseHandle (NeHandle->File);
}
MemFree (g_hHeap, 0, NeHandle);
NeHandle = NULL;
PopError();
}
}
return (HANDLE) NeHandle;
}
HANDLE
OpenNeFileW (
PCWSTR FileName
)
{
PNE_HANDLE NeHandle;
BOOL b = FALSE;
NeHandle = (PNE_HANDLE) MemAlloc (g_hHeap, HEAP_ZERO_MEMORY, sizeof (NE_HANDLE));
__try {
NeHandle->ResourcePool = PoolMemInitPool();
if (!NeHandle->ResourcePool) {
__leave;
}
NeHandle->File = CreateFileW (
FileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (NeHandle->File == INVALID_HANDLE_VALUE) {
__leave;
}
if (!LoadNeHeader (NeHandle->File, &NeHandle->Header)) {
__leave;
}
NeHandle->HeaderOffset = SetFilePointer (NeHandle->File, 0, NULL, FILE_CURRENT);
b = TRUE;
}
__finally {
if (!b) {
PushError();
if (NeHandle->ResourcePool) {
PoolMemDestroyPool (NeHandle->ResourcePool);
}
if (NeHandle->File != INVALID_HANDLE_VALUE) {
CloseHandle (NeHandle->File);
}
MemFree (g_hHeap, 0, NeHandle);
NeHandle = NULL;
PopError();
}
}
return (HANDLE) NeHandle;
}
VOID
CloseNeFile (
HANDLE Handle
)
{
PNE_HANDLE NeHandle;
NeHandle = (PNE_HANDLE) Handle;
if (!NeHandle) {
return;
}
if (NeHandle->File != INVALID_HANDLE_VALUE) {
CloseHandle (NeHandle->File);
}
if (NeHandle->ResourcesLoaded) {
FreeNeResources (&NeHandle->Resources);
}
PoolMemDestroyPool (NeHandle->ResourcePool);
MemFree (g_hHeap, 0, NeHandle);
}
PCSTR
pConvertUnicodeResourceId (
IN PCWSTR ResId
)
{
if (HIWORD (ResId)) {
return ConvertWtoA (ResId);
}
return (PCSTR) ResId;
}
PCSTR
pDecodeIdReferenceInString (
IN PCSTR ResName
)
{
if (HIWORD (ResName) && ResName[0] == '#') {
return (PCSTR) atoi (&ResName[1]);
}
return ResName;
}
BOOL
pLoadNeResourcesFromHandle (
IN PNE_HANDLE NeHandle
)
{
if (NeHandle->ResourcesLoaded) {
return TRUE;
}
if (!LoadNeResources (NeHandle->File, &NeHandle->Resources)) {
return FALSE;
}
NeHandle->ResourcesLoaded = TRUE;
return TRUE;
}
BOOL
pLoadNeResourceName (
OUT PSTR ResName,
IN HANDLE File,
IN DWORD StringOffset
)
{
BYTE ResNameSize;
SetFilePointer (File, StringOffset, NULL, FILE_BEGIN);
if (!ReadBinaryBlock (File, &ResNameSize, 1)) {
return FALSE;
}
ResName[ResNameSize] = 0;
return ReadBinaryBlock (File, ResName, ResNameSize);
}
BOOL
pEnumNeResourceTypesEx (
IN HANDLE Handle,
IN ENUMRESTYPEPROCEXA EnumFunc,
IN LONG lParam,
IN BOOL ExFunctionality,
IN BOOL UnicodeProc
)
{
PNE_HANDLE NeHandle;
PNE_RES_TYPEINFO TypeInfo;
INT Count;
INT i;
DWORD StringOffset;
CHAR ResName[256];
ENUMRESTYPEPROCA EnumFunc2 = (ENUMRESTYPEPROCA) EnumFunc;
ENUMRESTYPEPROCEXW EnumFuncW = (ENUMRESTYPEPROCEXW) EnumFunc;
ENUMRESTYPEPROCW EnumFunc2W = (ENUMRESTYPEPROCW) EnumFunc;
PWSTR UnicodeResName = NULL;
//
// Make sure resources are loaded
//
NeHandle = (PNE_HANDLE) Handle;
if (!NeHandle || !EnumFunc) {
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!pLoadNeResourcesFromHandle (NeHandle)) {
return FALSE;
}
//
// Enumerate all resource types
//
Count = GrowListGetSize (&NeHandle->Resources.TypeInfoArray);
for (i = 0 ; i < Count ; i++) {
TypeInfo = (PNE_RES_TYPEINFO) GrowListGetItem (&NeHandle->Resources.TypeInfoArray, i);
if (TypeInfo->TypeId & 0x8000) {
if (ExFunctionality) {
if (UnicodeProc) {
if (!EnumFuncW (Handle, (PWSTR) (TypeInfo->TypeId & 0x7fff), lParam, TypeInfo)) {
break;
}
} else {
if (!EnumFunc (Handle, (PSTR) (TypeInfo->TypeId & 0x7fff), lParam, TypeInfo)) {
break;
}
}
} else {
if (UnicodeProc) {
if (!EnumFunc2W (Handle, (PWSTR) (TypeInfo->TypeId & 0x7fff), lParam)) {
break;
}
} else {
if (!EnumFunc2 (Handle, (PSTR) (TypeInfo->TypeId & 0x7fff), lParam)) {
break;
}
}
}
} else {
//
// TypeInfo->TypeId gives an offset to the resource string name,
// relative to the start of the resource table
//
StringOffset = NeHandle->HeaderOffset + NeHandle->Header.OffsetToResourceTable + TypeInfo->TypeId;
pLoadNeResourceName (ResName, NeHandle->File, StringOffset);
if (UnicodeProc) {
UnicodeResName = (PWSTR) ConvertAtoW (ResName);
}
if (ExFunctionality) {
if (UnicodeProc) {
if (!EnumFuncW (Handle, UnicodeResName, lParam, TypeInfo)) {
break;
}
} else {
if (!EnumFunc (Handle, ResName, lParam, TypeInfo)) {
break;
}
}
} else {
if (UnicodeProc) {
if (!EnumFunc2W (Handle, UnicodeResName, lParam)) {
break;
}
} else {
if (!EnumFunc2 (Handle, ResName, lParam)) {
break;
}
}
}
}
}
return TRUE;
}
BOOL
EnumNeResourceTypesA (
IN HANDLE Handle,
IN ENUMRESTYPEPROCA EnumFunc,
IN LONG lParam
)
{
return pEnumNeResourceTypesEx (
Handle,
(ENUMRESTYPEPROCEXA) EnumFunc,
lParam,
FALSE, // no ex functionality
FALSE // ANSI enum proc
);
}
BOOL
EnumNeResourceTypesW (
IN HANDLE Handle,
IN ENUMRESTYPEPROCW EnumFunc,
IN LONG lParam
)
{
return pEnumNeResourceTypesEx (
Handle,
(ENUMRESTYPEPROCEXA) EnumFunc,
lParam,
FALSE, // no ex functionality
TRUE // UNICODE enum proc
);
}
BOOL
pEnumTypeForNameSearchProcA (
IN HANDLE Handle,
IN PCSTR Type,
IN LONG lParam,
IN PNE_RES_TYPEINFO TypeInfo
)
{
PTYPESEARCHDATAA Data;
Data = (PTYPESEARCHDATAA) lParam;
//
// Compare type
//
if (HIWORD (Data->TypeToFind) == 0) {
if (Type != Data->TypeToFind) {
return TRUE;
}
} else {
if (HIWORD (Type) == 0) {
return TRUE;
}
if (!StringIMatchA (Type, Data->TypeToFind)) {
return TRUE;
}
}
//
// Type found
//
Data->OutboundTypeInfo = TypeInfo;
Data->Found = TRUE;
return FALSE;
}
BOOL
pEnumNeResourceNamesEx (
IN HANDLE Handle,
IN PCSTR Type,
IN ENUMRESNAMEPROCEXA EnumFunc,
IN LONG lParam,
IN BOOL ExFunctionality,
IN BOOL UnicodeProc
)
{
PNE_HANDLE NeHandle;
PNE_RES_TYPEINFO TypeInfo;
PNE_RES_NAMEINFO NameInfo;
TYPESEARCHDATAA Data;
WORD w;
DWORD StringOffset;
CHAR ResName[256];
ENUMRESNAMEPROCA EnumFunc2 = (ENUMRESNAMEPROCA) EnumFunc;
ENUMRESNAMEPROCEXW EnumFuncW = (ENUMRESNAMEPROCEXW) EnumFunc;
ENUMRESNAMEPROCW EnumFunc2W = (ENUMRESNAMEPROCW) EnumFunc;
PCWSTR UnicodeType = NULL;
PCWSTR UnicodeResName = NULL;
Type = pDecodeIdReferenceInString (Type);
//
// Make sure resources are loaded
//
NeHandle = (PNE_HANDLE) Handle;
if (!NeHandle || !EnumFunc) {
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!pLoadNeResourcesFromHandle (NeHandle)) {
return FALSE;
}
//
// Locate type
//
ZeroMemory (&Data, sizeof (Data));
Data.TypeToFind = Type;
if (!pEnumNeResourceTypesEx (
Handle,
pEnumTypeForNameSearchProcA,
(LONG) &Data,
TRUE, // ex functionality
FALSE // ANSI enum proc
)) {
SetLastError (ERROR_RESOURCE_TYPE_NOT_FOUND);
return FALSE;
}
if (!Data.Found) {
SetLastError (ERROR_RESOURCE_TYPE_NOT_FOUND);
return FALSE;
}
TypeInfo = Data.OutboundTypeInfo;
if (UnicodeProc) {
if (HIWORD (Type)) {
UnicodeType = ConvertAtoW (Type);
} else {
UnicodeType = (PCWSTR) Type;
}
}
//
// Enumerate the resource names
//
NameInfo = TypeInfo->NameInfo;
for (w = 0 ; w < TypeInfo->ResourceCount ; w++) {
if (NameInfo->Id & 0x8000) {
if (ExFunctionality) {
if (UnicodeProc) {
if (!EnumFuncW (Handle, UnicodeType, (PWSTR) (NameInfo->Id & 0x7fff), lParam, TypeInfo, NameInfo)) {
break;
}
} else {
if (!EnumFunc (Handle, Type, (PSTR) (NameInfo->Id & 0x7fff), lParam, TypeInfo, NameInfo)) {
break;
}
}
} else {
if (UnicodeProc) {
if (!EnumFunc2W (Handle, UnicodeType, (PWSTR) (NameInfo->Id & 0x7fff), lParam)) {
break;
}
} else {
if (!EnumFunc2 (Handle, Type, (PSTR) (NameInfo->Id & 0x7fff), lParam)) {
break;
}
}
}
} else {
//
// TypeInfo->TypeId gives an offset to the resource string name,
// relative to the start of the resource table
//
StringOffset = NeHandle->HeaderOffset + NeHandle->Header.OffsetToResourceTable + NameInfo->Id;
pLoadNeResourceName (ResName, NeHandle->File, StringOffset);
if (UnicodeProc) {
UnicodeResName = ConvertAtoW (ResName);
}
if (ExFunctionality) {
if (UnicodeProc) {
if (!EnumFuncW (Handle, UnicodeType, (PWSTR) UnicodeResName, lParam, TypeInfo, NameInfo)) {
break;
}
} else {
if (!EnumFunc (Handle, Type, ResName, lParam, TypeInfo, NameInfo)) {
break;
}
}
} else {
if (UnicodeProc) {
if (!EnumFunc2W (Handle, UnicodeType, (PWSTR) UnicodeResName, lParam)) {
break;
}
} else {
if (!EnumFunc2 (Handle, Type, ResName, lParam)) {
break;
}
}
}
if (UnicodeProc) {
FreeConvertedStr (UnicodeResName);
}
}
NameInfo++;
}
if (UnicodeProc) {
DestroyUnicodeResourceId (UnicodeType);
}
return TRUE;
}
BOOL
EnumNeResourceNamesA (
IN HANDLE Handle,
IN PCSTR Type,
IN ENUMRESNAMEPROCA EnumFunc,
IN LONG lParam
)
{
return pEnumNeResourceNamesEx (
Handle,
Type,
(ENUMRESNAMEPROCEXA) EnumFunc,
lParam,
FALSE, // no ex functionality
FALSE // ANSI enum proc
);
}
BOOL
EnumNeResourceNamesW (
IN HANDLE Handle,
IN PCWSTR Type,
IN ENUMRESNAMEPROCW EnumFunc,
IN LONG lParam
)
{
BOOL b;
PCSTR AnsiType;
AnsiType = pConvertUnicodeResourceId (Type);
b = pEnumNeResourceNamesEx (
Handle,
AnsiType,
(ENUMRESNAMEPROCEXA) EnumFunc,
lParam,
FALSE, // no ex functionality
TRUE // UNICODE enum proc
);
PushError();
DestroyAnsiResourceId (AnsiType);
PopError();
return b;
}
BOOL
pEnumTypeForResSearchProcA (
IN HANDLE Handle,
IN PCSTR Type,
IN PCSTR Name,
IN LPARAM lParam,
IN PNE_RES_TYPEINFO TypeInfo,
IN PNE_RES_NAMEINFO NameInfo
)
{
PNAMESEARCHDATAA Data;
Data = (PNAMESEARCHDATAA) lParam;
//
// Compare name
//
if (HIWORD (Data->NameToFind) == 0) {
if (Name != Data->NameToFind) {
return TRUE;
}
} else {
if (HIWORD (Name) == 0) {
return TRUE;
}
if (!StringIMatchA (Name, Data->NameToFind)) {
return TRUE;
}
}
//
// Name found
//
Data->OutboundTypeInfo = TypeInfo;
Data->OutboundNameInfo = NameInfo;
Data->Found = TRUE;
return FALSE;
}
PBYTE
FindNeResourceExA (
IN HANDLE Handle,
IN PCSTR Type,
IN PCSTR Name
)
{
PNE_HANDLE NeHandle;
NAMESEARCHDATAA Data;
DWORD Offset;
DWORD Length;
PNE_RES_NAMEINFO NameInfo;
PBYTE ReturnData;
Type = pDecodeIdReferenceInString (Type);
Name = pDecodeIdReferenceInString (Name);
ZeroMemory (&Data, sizeof (Data));
//
// Make sure resources are loaded
//
NeHandle = (PNE_HANDLE) Handle;
if (!NeHandle || !Type || !Name) {
SetLastError (ERROR_INVALID_PARAMETER);
return NULL;
}
if (!pLoadNeResourcesFromHandle (NeHandle)) {
return NULL;
}
//
// Find resource
//
Data.NameToFind = Name;
if (!pEnumNeResourceNamesEx (
Handle,
Type,
pEnumTypeForResSearchProcA,
(LONG) &Data,
TRUE,
FALSE
)) {
SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
return NULL;
}
if (!Data.Found) {
SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
return NULL;
}
NameInfo = Data.OutboundNameInfo;
Offset = (DWORD) NameInfo->Offset << (DWORD) NeHandle->Resources.AlignShift;
Length = (DWORD) NameInfo->Length << (DWORD) NeHandle->Resources.AlignShift;
ReturnData = PoolMemGetMemory (NeHandle->ResourcePool, Length);
if (!ReturnData) {
return NULL;
}
SetFilePointer (NeHandle->File, Offset, NULL, FILE_BEGIN);
if (!ReadBinaryBlock (NeHandle->File, ReturnData, Length)) {
PushError();
MemFree (g_hHeap, 0, ReturnData);
PopError();
return NULL;
}
return ReturnData;
}
PBYTE
FindNeResourceExW (
IN HANDLE Handle,
IN PCWSTR Type,
IN PCWSTR Name
)
{
PCSTR AnsiType;
PCSTR AnsiName;
PBYTE Resource;
AnsiType = pConvertUnicodeResourceId (Type);
AnsiName = pConvertUnicodeResourceId (Name);
Resource = FindNeResourceExA (
Handle,
AnsiType,
AnsiName
);
PushError();
DestroyAnsiResourceId (AnsiType);
DestroyAnsiResourceId (AnsiName);
PopError();
return Resource;
}
DWORD
SizeofNeResourceA (
IN HANDLE Handle,
IN PCSTR Type,
IN PCSTR Name
)
{
PNE_HANDLE NeHandle;
NAMESEARCHDATAA Data;
SetLastError (ERROR_SUCCESS);
Type = pDecodeIdReferenceInString (Type);
Name = pDecodeIdReferenceInString (Name);
ZeroMemory (&Data, sizeof (Data));
//
// Make sure resources are loaded
//
NeHandle = (PNE_HANDLE) Handle;
if (!NeHandle || !Type || !Name) {
SetLastError (ERROR_INVALID_PARAMETER);
return 0;
}
if (!pLoadNeResourcesFromHandle (NeHandle)) {
return 0;
}
//
// Find resource
//
if (!pEnumNeResourceNamesEx (
Handle,
Type,
pEnumTypeForResSearchProcA,
(LONG) &Data,
TRUE,
FALSE
)) {
SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
return 0;
}
if (!Data.Found) {
SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
return 0;
}
return Data.OutboundNameInfo->Length;
}
DWORD
SizeofNeResourceW (
IN HANDLE Handle,
IN PCWSTR Type,
IN PCWSTR Name
)
{
PCSTR AnsiType;
PCSTR AnsiName;
DWORD Size;
AnsiType = pConvertUnicodeResourceId (Type);
AnsiName = pConvertUnicodeResourceId (Name);
Size = SizeofNeResourceA (Handle, AnsiType, AnsiName);
PushError();
DestroyAnsiResourceId (AnsiType);
DestroyAnsiResourceId (AnsiName);
PopError();
return Size;
}