列出使用Win32 API存储在仅资源库(DLL)中的消息标识和符号名称 [英] Listing message IDs and symbolic names stored in a resource-only library (DLL) using Win32 API
问题描述
我们想列出嵌入在仅资源库(DLL)中的消息的内容(键/值对)
资源库定义为指定的在MSDN 。
mc -s EventLogMsgs.mc
rc EventLogMsgs.rc
link / DLL / SUBSYSTEM:WINDOWS / NOENTRY / MACHINE:x86 EventLogMsgs.Res
示例EventLogMsgs.mc可能是:
; // - Event categories -
; //类别必须从1开始连续编号。
; // ************************************************ ********
MessageId = 0x1
严重性=成功
SymbolicName = INSTALL_CATEGORY
语言=英语
安装
。
MessageId = 0x2
严重性=成功
SymbolicName = QUERY_CATEGORY
语言=英语
数据库查询
。
...
我们尝试使用EnumResourceTypes
...
HMODULE hMod = NULL;
hMod = LoadLibraryA(C:\\temp\\EventLogMsgs.dll);
if(hMod!= NULL)
{
EnumResourceTypes(hMod,(ENUMRESTYPEPROC)TypesCallback,0);
FreeLibrary(hMod);
}
...
BOOL WINAPI TypesCallback(HMODULE hModule,LPTSTR lpType,LONG lParam)
{
char buffer [100]
if((ULONG)lpType& 0xFFFF0000)
sprintf(buffer,%s\\\
,lpType);
else
sprintf(buffer,%u\\\
,(USHORT)lpType);
cout<< Type:<<缓冲液< std :: endl;
EnumResourceNames(hModule,lpType,(ENUMRESNAMEPROC)NamesCallback,0);
return true;
}
BOOL WINAPI NamesCallback(HMODULE hModule,LPCTSTR lpType,LPTSTR lpName,LONG lParam)
{
char buffer [100]
if((ULONG)lpName& 0xFFFF0000)
sprintf(buffer,%s\\\
,lpName);
else
sprintf(buffer,%u\\\
,(USHORT)lpName);
cout<< Name:<<缓冲液< std :: endl;
return true;
}
结果是高级别的资源类型列表及其标识符,例如
...
类型:11
名称:1
类型:16
名称:1
类型:24
名称:2
...
11(RT_MESSAGETABLE)是消息表资源类型(查看所有资源类型)
理想情况下,我们希望列出 ALL 资源库中的实际消息的符号名称和标识符。
感谢
您枚举了模块中的资源它告诉你一个特定类型的每个资源的名称。完成后,您需要加载资源以检查其内容。在你的case你需要类型 RT_MESSAGETABLE
的资源,名为 1
。
现在需要使用 这里是一个naff C程序,枚举你的消息表: 输出 请原谅我骇人听闻的C.无论是C还是C ++都是我不熟悉的语言。但是,代码将至少显示如何提取您所需的信息。 We would like to list the contents (key/value pairs) of messages embedded in a resource-only library (DLL) The resource library is defined as specified in MSDN. A sample EventLogMsgs.mc may be: We tried to use EnumResourceTypes() Win32 API as following: The result is a high level listing of the resource types and their "names/identifiers", e.g., 11 (RT_MESSAGETABLE) is the message table resource type (See all resource types) Ideally we would want to list ALL the actual messages' symbolic names and identifiers in the resource library. Thanks You've enumerated the resources in the module which tells you the name of each resource of a specific type. Once you've done that you need to load the resource to examine its content. In your case you need the resource of type You now need to use Here's a rather naff C program that enumerates your message table: Output Please excuse my appalling C. Neither C nor C++ are languages that I am remotely fluent in. However, the code will at least show you how to extract the information you desire. 这篇关于列出使用Win32 API存储在仅资源库(DLL)中的消息标识和符号名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! FindResource
, LoadResource
和 LockResource
获取指向消息表结构开头的指针。然后,您可以使用
MESSAGE_RESOURCE_DATA
结构,依次 MESSAGE_RESOURCE_BLOCK
和 MESSAGE_RESOURCE_ENTRY
解包消息表的内容。本代码项目文章详细介绍了此过程。 / p>
#include< windows.h>
#include< stdio.h>
int ProcessBlock(MESSAGE_RESOURCE_DATA * data,MESSAGE_RESOURCE_BLOCK * block)
{
MESSAGE_RESOURCE_ENTRY * entry =(MESSAGE_RESOURCE_ENTRY *)((unsigned char *)data + block-> OffsetToEntries) ;
for(DWORD id = block-> LowId; id <= block-> HighId; id ++)
{
if(entry-> Flags == 0x0001)// wide char
printf(%d,%ls,id,entry-> Text);
else if(entry-> Flags == 0x0000)// ANSI
printf(%d,%s,id,entry-> Text);
entry =(MESSAGE_RESOURCE_ENTRY *)((unsigned char *)entry + entry-> Length);
}
return 1;
}
int main(void)
{
HMODULE hMod = LoadLibrary(C:\\desktop\\EventLogMsgs.dll);
if(hMod == NULL)return 1;
HRSRC hRsrc = FindResource(hMod,MAKEINTRESOURCE(1),RT_MESSAGETABLE);
if(hRsrc == NULL)return 1;
HGLOBAL hGlobal = LoadResource(hMod,hRsrc);
if(hGlobal == NULL)return 1;
MESSAGE_RESOURCE_DATA * data =(MESSAGE_RESOURCE_DATA *)LockResource(hGlobal);
if(data == NULL)return 1;
for(DWORD block = 0; block< data-> NumberOfBlocks; block ++)
if(!ProcessBlock(data,& data-& b $ b return 1;
return 0;
}
1,安装
2,数据库查询
3,数据刷新
1000,我的应用程序消息文本1000,从%1调用。
1002,我的英文通用信息消息,消息ID为1002.
1004,%% 5002的更新周期已完成。
5001,示例事件日志
5002,SVC_UPDATE.EXE
-2147482647,我的应用程序消息文本,英语,消息标识1001,从%1调用。
-2147482645,我的英文通用警告消息,消息ID为1003,从%1调用。
-2147482643,刷新操作未完成,因为无法建立与服务器%1的连接。
mc -s EventLogMsgs.mc
rc EventLogMsgs.rc
link /DLL /SUBSYSTEM:WINDOWS /NOENTRY /MACHINE:x86 EventLogMsgs.Res
; // - Event categories -
; // Categories must be numbered consecutively starting at 1.
; // ********************************************************
MessageId=0x1
Severity=Success
SymbolicName=INSTALL_CATEGORY
Language=English
Installation
.
MessageId=0x2
Severity=Success
SymbolicName=QUERY_CATEGORY
Language=English
Database Query
.
...
...
HMODULE hMod=NULL;
hMod = LoadLibraryA( "C:\\temp\\EventLogMsgs.dll" );
if (hMod != NULL)
{
EnumResourceTypes( hMod, (ENUMRESTYPEPROC)TypesCallback, 0) ;
FreeLibrary(hMod);
}
...
BOOL WINAPI TypesCallback( HMODULE hModule, LPTSTR lpType, LONG lParam )
{
char buffer[100];
if ((ULONG)lpType & 0xFFFF0000)
sprintf( buffer, "%s\n", lpType);
else
sprintf(buffer, "%u\n", (USHORT)lpType);
cout << "Type: " << buffer << std::endl;
EnumResourceNames( hModule, lpType, (ENUMRESNAMEPROC)NamesCallback, 0 );
return true;
}
BOOL WINAPI NamesCallback( HMODULE hModule, LPCTSTR lpType, LPTSTR lpName, LONG lParam )
{
char buffer[100];
if ((ULONG)lpName & 0xFFFF0000)
sprintf(buffer,"%s\n", lpName);
else
sprintf(buffer, "%u\n",(USHORT)lpName);
cout << "Name: " << buffer << std::endl;
return true;
}
...
Type: 11
Name: 1
Type: 16
Name: 1
Type: 24
Name: 2
...
RT_MESSAGETABLE
that is named 1
.FindResource
, LoadResource
and LockResource
to get a pointer to the beginning of the message table structures. You can then use the MESSAGE_RESOURCE_DATA
struct , and in turn MESSAGE_RESOURCE_BLOCK
and MESSAGE_RESOURCE_ENTRY
to unpack the content of the message table. This Code Project article goes into more detail on the process.#include <windows.h>
#include <stdio.h>
int ProcessBlock(MESSAGE_RESOURCE_DATA* data, MESSAGE_RESOURCE_BLOCK* block)
{
MESSAGE_RESOURCE_ENTRY* entry = (MESSAGE_RESOURCE_ENTRY*) ((unsigned char*)data + block->OffsetToEntries);
for (DWORD id = block->LowId; id <= block->HighId; id++)
{
if (entry->Flags == 0x0001) // wide char
printf("%d, %ls", id, entry->Text);
else if (entry->Flags == 0x0000) // ANSI
printf("%d, %s", id, entry->Text);
entry = (MESSAGE_RESOURCE_ENTRY*) ((unsigned char*)entry + entry->Length);
}
return 1;
}
int main(void)
{
HMODULE hMod = LoadLibrary("C:\\desktop\\EventLogMsgs.dll");
if (hMod == NULL) return 1;
HRSRC hRsrc = FindResource(hMod, MAKEINTRESOURCE(1), RT_MESSAGETABLE);
if (hRsrc == NULL) return 1;
HGLOBAL hGlobal = LoadResource(hMod, hRsrc);
if (hGlobal == NULL) return 1;
MESSAGE_RESOURCE_DATA* data = (MESSAGE_RESOURCE_DATA*)LockResource(hGlobal);
if (data == NULL) return 1;
for (DWORD block = 0; block < data->NumberOfBlocks; block++)
if (!ProcessBlock(data, &data->Blocks[block]))
return 1;
return 0;
}
1, Installation
2, Database Query
3, Data Refresh
1000, My application message text, in English, for message id 1000, called from %1.
1002, My generic information message in English, for message id 1002.
1004, The update cycle is complete for %%5002.
5001, Sample Event Log
5002, SVC_UPDATE.EXE
-2147482647, My application message text, in English, for message id 1001, called from %1.
-2147482645, My generic warning message in English, for message id 1003, called from %1.
-2147482643, The refresh operation did not complete because the connection to server %1 could not be established.