Создание списка ресурсов


Пример ниже создает список каждого ресурса в файле 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 указывает на символьную) строку, содержащую имя ресурса, тогда сделайте следующее:

  1. вызовите FindResource или FindResourceEx с именем ресурса, чтобы получить дескриптор ресурса;
  2. вызовите LoadResource с дескриптором ресурса, чтобы получить глобальный дескриптор;
  3. вызовите LockResource с глобальным дескриптором, чтобы получить указатель на данные ресурса.

Код корректировки ресурсов следует за похожим шаблоном для ресурса диалогового окна.

Обратите внимание! на то, что неправильное использование 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; 
}  


Назад в оглавление
На главную страницу

Hosted by uCoz