Создание списка ресурсов
Пример ниже создает список каждого ресурса в файле Hand.exe. Список записывается в файл Resinfo.txt.
Код демонстрирует, как загрузить исполняемый файл, как создать файл в котором записывается информация о ресурсе, и как вызвать функцию EnumResourceTypes, чтобы отправить каждый тип ресурса, найденный в модуле в определяемую программой функцию повторного вызова EnumTypesFunc. Информацию о функции повторного вызова этого типа см. в описании EnumResTypeProc. Эта функция повторного вызова использует функцию EnumResourceNames, чтобы передавать имя каждого ресурса внутри заданного типа в другую определяемую программой функцию повторного вызова EnumNamesFunc. Информацию о функции повторного вызова этого типа см. в описании EnumResNameProc. EnumNamesFunc использует функцию EnumResourceLanguages, чтобы передать язык каждого ресурса заданного типа и имени в третью функцию повторного вызова, EnumLangsFunc. Информацию о функции повторного вызова этого типа см. в описании EnumResLangProc. EnumLangsFunc пишет информацию о ресурсе заданного типа, имени и языка в файл Resinfo.txt.
Обратите внимание! на то, что то, что параметр lpszType в EnumResTypeProc является или идентификатором ресурса (ID) или указателем на строку (содержащую ID ресурса или имя типа); параметры lpszType и lpszName в EnumResNameProc являются похожими. |
Чтобы использовать перечисленный ресурс, возьмите имя ресурса или ID и вызовите соответствующую функцию. Например, чтобы загрузить строковый ресурс (RT_STRING), если lpszName в EnumResNameProc дает ID ресурса (или непосредственно или в строке, которая начинается с символа номера (#)), вызовите LoadString. Если же, lpszName указывает на символьную) строку, содержащую имя ресурса, тогда сделайте следующее:
Код корректировки ресурсов следует за похожим шаблоном для ресурса диалогового окна.
| Обратите внимание! на то, что неправильное использование LoadLibrary может поставить под угрозу защиту вашего приложения, загружая неправильную DLL. Обратитесь к документации LoadLibrary за информацией о том, как правильно загружать DLLs в разных версиях Microsoft ® Windows ®. |
Демонстрационный пример
char szBuffer[80]; // буфер печати EnumResourceTypes
DWORD cbWritten; // число записанных байтов в файле ресурса инф.
size_t cbString; // длина строки в sprintf
HRESULT hResult;
// Объявление функций повторного вызова.
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);
// Загружаем .EXE, ресурсы которого хотим перечислить.
hExe = LoadLibrary("hand.exe");
if (hExe == NULL)
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
// Создадим файл для содержания информации о ресурсе.
hFile = CreateFile("resinfo.txt", // имя файла
GENERIC_READ | GENERIC_WRITE, // режим доступа
0, // режим совместного доступа
(LPSECURITY_ATTRIBUTES) NULL, // защита по умолчанию
CREATE_ALWAYS, // флажки создания
FILE_ATTRIBUTE_NORMAL, // атрибуты файла
(HANDLE) NULL); // шаблона нет
if (hFile == INVALID_HANDLE_VALUE) {
ErrorHandler("Could not open file.");
}
// Находим все загруженные файлы ресурсов.
hResult = StringCchPrintf(szBuffer, 80/sizeof(TCHAR),
// cbString = sprintf(szBuffer,
"The file contains the following resources:\n\n");
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
hResult = StringCchLength(szBuffer, 80/sizeof(TCHAR), cbString);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
WriteFile(hFile, // файл, удерживающий информацию о ресурсе.
szBuffer, // что записывать в файл
(DWORD) cbString, // число байтов в szBuffer
&cbWritten, // записанное число байтов
NULL); // не асинхронный ввод-вывод
EnumResourceTypes(hExe, // дескриптор модуля
(ENUMRESTYPEPROC)EnumTypesFunc, // функция повторного вызова
0); // дополнительный параметр
// Выгрузите исполняемый файл, ресурсы которого были
// перечислены и закройте файл, созданный, чтобы содержать
// информацию о ресурсе.
FreeLibrary(hExe);
CloseHandle(hFile);
// ФУНКЦИЯ: EnumTypesFunc(HANDLE, LPSTR, LONG)
//
// ПРЕДНАЗНАЧЕНИЕ: Повторный вызов типа ресурса
BOOL EnumTypesFunc(
HANDLE hModule, // дескриптор модуля
LPTSTR lpType, // адрес типа ресурса
LONG lParam) // дополнительный параметр, должен
// использоваться для проверки ошибок
{
size_t cbString;
HRESULT hResult;
// Запишите тип ресурса в файл информации ресурса.
// Тип может быть строкой или десятичным целым
// числом без знака, как проверка перед печатью.
if ((ULONG)lpType & 0xFFFF0000)
{
hResult = StringCchPrintf(szBuffer, 80/sizeof(TCHAR), "Type: %s\n", lpType);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
// cbString = sprintf(szBuffer, "Type: %s\n", lpType);
}
else
{
hResult = StringCchPrintf(szBuffer, 80/sizeof(TCHAR), "Type: %u\n", (USHORT)lpType);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
// cbString = sprintf(szBuffer, "Type: %u\n", (USHORT)lpType);
}
hResult = StringCchLength(szBuffer, 80/sizeof(TCHAR), cbString);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Найдите названия всех ресурсов типа lpType.
EnumResourceNames(hModule,
lpType,
(ENUMRESNAMEPROC)EnumNamesFunc,
0);
return TRUE;
}
// ФУНКЦИЯ: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)
//
// ПРЕДНАЗНАЧЕНИЕ: повторный вызов имени ресурса
BOOL EnumNamesFunc(
HANDLE hModule, // дескриптор модуля
LPCTSTR lpType, // адрес типа ресурса
LPTSTR lpName, // адрес имени ресурса
LONG lParam) // дополнительный параметр, должен
// использоваться для проверки ошибок
{
size_t cbString;
HRESULT hResult;
// Запишите имя ресурса в файл информации ресурса.
// Имя может быть строкой или десятичным целым
// числом без знака, как проверка перед печатью.
if ((ULONG)lpName & 0xFFFF0000)
{
hResult = StringCchPrintf(szBuffer, 80/sizeof(TCHAR), "\tName: %s\n", lpName);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
// cbString = sprintf(szBuffer, "\tName: %s\n", lpName);
}
else
{
hResult = StringCchPrintf(szBuffer, 80/sizeof(TCHAR), "\tName: %u\n", (USHORT)lpName);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
// cbString = sprintf(szBuffer, "\tName: %u\n",
(USHORT)lpName);
}
hResult = StringCchLength(szBuffer, 80/sizeof(TCHAR), cbString);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Найдем языки всех ресурсов типа
// lpType и имени lpName.
EnumResourceLanguages(hModule,
lpType,
lpName,
(ENUMRESLANGPROC)EnumLangsFunc,
0);
return TRUE;
}
// ФУНКЦИЯ: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)
//
// ПРЕДНАЗНАЧЕНИЕ: Повторный вызов языка Ресурса
BOOL EnumLangsFunc(
HANDLE hModule, // дескриптор модуля
LPCTSTR lpType, // адрес типа ресурса
LPCTSTR lpName, // адрес имени ресурса
WORD wLang, // язык ресурса
LONG lParam) // дополнительный параметр, который должен
// использоваться для выявления ошибок
{
HANDLE hResInfo;
char szBuffer[80];
size_t cbString = 0;
HRESULT hResult;
hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);
// Запишем язык ресурса в файл информации ресурса.
hResult = StringCchPrintf(szBuffer, 80/sizeof(TCHAR), "\t\tLanguage: %u\n", (USHORT) wLang);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
hResult = StringCchLength(szBuffer, 80/sizeof(TCHAR), cbString);
if (FAILED(hResult))
{
// Добавление кода защиты, насколько возможно, от ошибки.
return;
}
// cbString = sprintf(szBuffer, "\t\tLanguage: %u\n", (USHORT)wLang);
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Запишите дескриптор ресурса и размер буфера.
cbString = sprintf(szBuffer,
"\t\thResInfo == %lx, Size == %lu\n\n",
hResInfo,
SizeofResource(hModule, hResInfo));
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
return TRUE;
}
|