11.2.2 Creating a Resource List

The following code fragment creates a list of every resource in the file hand.exe. The list is written to the file resinfo.txt.

The fragment loads the executable file, creates a file in which to write resource information, and calls EnumResourceTypes. This function sends each resource type found in the module to EnumTypesFunc, a user-defined callback function. This callback function uses EnumResourceNames, which passes the name of every resource of the specified type to EnumNamesFunc, another user-defined callback function. The EnumNamesFunc callback uses EnumResourceLanguages, which passes the language of every resource of the specified type and name to EnumLangsFunc, a third callback function. The EnumLangsFunc callback function writes information about the resource of the specified type, name, and language to the file resinfo.txt.

char szBuffer[80]; /* print buffer for EnumResourceTypes */

DWORD dwBytesWritten; /* # bytes written to resinfo file */

int iLength; /* length of string in sprintf */

/* Declare Enum* callback functions. */

BOOL EnumTypesFunc(

HANDLE hModule,

LPTSTR lpType,

LONG lParam);

BOOL EnumNamesFunc(

HANDLE hModule,

LPCTSTR lpType,

LPTSTR lpName,

LONG lParam);

BOOL EnumLangsFunc(

HANDLE hModule,

LPCTSTR lpType,

LPCTSTR lpName,

WORD wLang,

LONG lParam);

/* Load the exe whose resources you want to list. */

hExe = LoadLibrary("hand.exe");

if (hExe == NULL) {

ErrorHandler("Could not load exe.");

}

/* Create a file to contain the resource info. */

hFile = CreateFile("resinfo.txt", /* name of file */

GENERIC_READ | GENERIC_WRITE, /* access mode */

0, /* share mode */

(LPSECURITY_ATTRIBUTES) NULL, /* no security */

CREATE_ALWAYS, /* create flags */

FILE_ATTRIBUTE_NORMAL, /* file attrs */

(HANDLE) NULL); /* no template */

if (hFile == (HANDLE)0xFFFFFFFF) {

ErrorHandler("Could not open file.");

}

/* Find all of the loaded file's resources. */

iLength = sprintf(szBuffer,

"The file contains the following resources:\n\n");

WriteFile(hFile, /* file to hold resource info */

szBuffer, /* what to write to the file */

(DWORD) iLength, /* number of bytes in szBuffer*/

&dwBytesWritten, /* number of bytes written */

NULL); /* no overlapped i/o */

EnumResourceTypes(hExe, /* module handle */

(FARPROC)EnumTypesFunc, /* callback function */

NULL); /* extra parameter */

/*

* Unload the executable file whose resources were

* enumerated and close the file created to contain

* the resource info.

*/

FreeLibrary(hExe);

CloseHandle(hFile);

/********************************************************

FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)

PURPOSE: Resource type callback

*********************************************************/

BOOL EnumTypesFunc(

HANDLE hModule, /* module handle */

LPTSTR lpType, /* resource type */

LONG lParam) /* extra param; could be

used for error checking */

{

int iLength;

/* Write resource type to resource info file. */

if ((ULONG)lpType & 0xFFFF0000) {

iLength = sprintf(szBuffer, "Type: %s\n", lpType);

}

else {

iLength = sprintf(szBuffer, "Type: %u\n", (USHORT)lpType);

}

WriteFile(hFile, szBuffer, (DWORD) iLength,

&dwBytesWritten, NULL);

/* Find the names of all resources of type lpType. */

EnumResourceNames(hModule,

lpType,

(FARPROC)EnumNamesFunc,

NULL);

return TRUE;

}

/********************************************************

FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)

PURPOSE: Resource name callback

*********************************************************/

BOOL EnumNamesFunc(

HANDLE hModule, /* module handle */

LPCTSTR lpType, /* resource type */

LPTSTR lpName, /* resource name */

LONG lParam) /* extra param; could be

used for error checking */

{

int iLength;

/* Write resource name to resource info file. */

if ((ULONG)lpName & 0xFFFF0000) {

iLength = sprintf(szBuffer, "\tName: %s\n", lpName);

}

else {

iLength = sprintf(szBuffer, "\tName: %u\n",

(USHORT)lpName);

}

WriteFile(hFile, szBuffer, (DWORD) iLength,

&dwBytesWritten, NULL);

/*

* Find the languages of all resources of type

* lpType and name lpName.

*/

EnumResourceLanguages(hModule,

lpType,

lpName,

(FARPROC)EnumLangsFunc,

NULL);

return TRUE;

}

/*************************************************************

FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)

PURPOSE: Resource language callback

**************************************************************/

BOOL EnumLangsFunc(

HANDLE hModule, /* module handle */

LPCTSTR lpType, /* resource type */

LPCTSTR lpName, /* resource name */

WORD wLang, /* resource language */

LONG lParam) /* extra param; could be

used for error checking */

{

HANDLE hResInfo;

char szBuffer[80];

int iLength = 0;

hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);

if (hResInfo == NULL) {

ErrorHandler("Could not locate resource.");

}

else {

/* Write resource language to resource info file. */

iLength = sprintf(szBuffer, "\t\tLanguage: %u\n",

(USHORT)wLang);

WriteFile(hFile, szBuffer, (DWORD) iLength,

&dwBytesWritten, NULL);

/* Write resource handle and size to buffer. */

iLength = sprintf(szBuffer,

"\t\thResInfo == %lx, Size == %lu\n\n",

hResInfo,

SizeofResource(hModule, hResInfo));

WriteFile(hFile, szBuffer, (DWORD) iLength,

&dwBytesWritten, NULL);

}

return TRUE;