Skip to content

Commit 5614af1

Browse files
authored
Merge pull request #5 from sharkwouter/add-get-resource-types
Allow getting named resources
2 parents 8b77109 + 3671758 commit 5614af1

7 files changed

Lines changed: 235 additions & 1750 deletions

File tree

CMakeLists.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ endif(PE_STRING_LOADER AND (BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
5050

5151
option(PE_BITMAP_LOADER "If the pe_bitmap_loader program should be build as well" ON)
5252
if(PE_BITMAP_LOADER AND (BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
53-
add_executable(pe_bitmap_loader pe_bitmap_loader/main.c pe_bitmap_loader/stb_image_write.h)
53+
add_executable(pe_bitmap_loader pe_bitmap_loader/main.c)
5454
target_include_directories(pe_bitmap_loader PRIVATE
5555
include/
5656
)
@@ -61,6 +61,19 @@ if(PE_BITMAP_LOADER AND (BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
6161
endif()
6262
endif(PE_BITMAP_LOADER AND (BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
6363

64+
option(PE_RESOURCE_TYPES "If the pe_resource_types program should be build as well" OFF)
65+
if(PE_RESOURCE_TYPES AND (BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
66+
add_executable(pe_resource_types pe_resource_types/main.c)
67+
target_include_directories(pe_resource_types PRIVATE
68+
include/
69+
)
70+
if(BUILD_STATIC_LIBS)
71+
target_link_libraries(pe_resource_types pe_resource_loader_static)
72+
elseif(BUILD_SHARED_LIBS)
73+
target_link_libraries(pe_resource_types pe_resource_loader_shared)
74+
endif()
75+
endif(PE_RESOURCE_TYPES AND (BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
76+
6477
include(GNUInstallDirs)
6578
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pe-resource-loader.pc.in"
6679
"${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/pe-resource-loader.pc" @ONLY)
@@ -85,4 +98,8 @@ if (NOT WIN32)
8598
if(PE_BITMAP_LOADER)
8699
install(TARGETS pe_bitmap_loader DESTINATION bin)
87100
endif(PE_BITMAP_LOADER)
101+
102+
if(PE_RESOURCE_TYPES)
103+
install(TARGETS pe_resource_types DESTINATION bin)
104+
endif(PE_RESOURCE_TYPES)
88105
endif(NOT WIN32)

include/pe_resource_loader.h

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ typedef struct {
2020
uint32_t resource_offset;
2121
} PeResourceLoader;
2222

23+
/**
24+
* @brief Struct with the name and internal offset of a named resource.
25+
*
26+
* This struct should only be used to list names of resources and to pass along to other functions of pe-resource-loader.
27+
*
28+
* @param name_length The length of the name string.
29+
* @param name The name of the name resource as string.
30+
*
31+
*/
32+
typedef struct {
33+
uint16_t name_length;
34+
char * name;
35+
uint32_t name_offset_or_id;
36+
} PRL_ResourceName;
37+
2338
/**
2439
* @brief Open a PE file for retrieving resources.
2540
*
@@ -59,6 +74,7 @@ typedef enum {
5974
PRL_TYPE_ACCELERATOR=9,
6075
PRL_TYPE_RCDATA=10,
6176
PRL_TYPE_MESSAGETABLE=11,
77+
PRL_TYPE_GROUPCURSOR=12,
6278
PRL_TYPE_GROUPICON=14,
6379
PRL_TYPE_VERSION=16,
6480
PRL_TYPE_DLGINCLUDE=17,
@@ -89,7 +105,17 @@ uint32_t * PeResourceLoader_GetLanguageIds(PeResourceLoader * loader, uint16_t *
89105
* @param count Will contain the size of returned array not NULL.
90106
* @return An array of resource IDs.
91107
*/
92-
uint32_t * PeResourceLoader_GetResourceIds(PeResourceLoader *loader, PRL_Type resource_type, uint32_t * count);
108+
uint32_t * PeResourceLoader_GetResourceIds(PeResourceLoader *loader, PRL_Type resource_type, uint16_t * count);
109+
110+
/**
111+
* @brief Get a struct all resource IDs in the PE file.
112+
*
113+
* @param loader PeResourceLoader struct pointer created by PeResourceLoader_Open.
114+
* @param resource_type The type of resource of which IDs should be returned.
115+
* @param count Will contain the size of returned array not NULL.
116+
* @return An array of PRL_ResourceName structs, containing the length of the name, the name and the name offset that can also be used as an id in some cases.
117+
*/
118+
PRL_ResourceName * PeResourceLoader_GetResourceNames(PeResourceLoader *loader, PRL_Type resource_type, uint16_t * count);
93119

94120
/**
95121
* @brief Retrieve a resource from a PE file.
@@ -107,6 +133,31 @@ uint32_t * PeResourceLoader_GetResourceIds(PeResourceLoader *loader, PRL_Type re
107133
*/
108134
void * PeResourceLoader_GetResource(PeResourceLoader * loader, PRL_Type resource_type, uint32_t language_id, uint32_t resource_id, uint32_t * size);
109135

136+
/**
137+
* @brief Retrieve a resource with a name instead of an id from a PE file.
138+
*
139+
* Headers will automatically be added to bitmaps, icons and cursors, making it possible to write them to disk as is.
140+
* Strings will be automatically converted to UTF-8.
141+
* Other types of resources will be returned as is.
142+
*
143+
* @param loader PeResourceLoader struct pointer created by PeResourceLoader_Open.
144+
* @param resource_type The type of resource that is retrieved.
145+
* @param language_id The ID of the language the resource should be returned in.
146+
* @param resource_name The PRL_ResourceName struct returned by PeResourceLoader_GetResourceNames.
147+
* @param size Will contain the size of the resource retrieved.
148+
* @return The data contained in the resource as void pointer.
149+
*/
150+
void * PeResourceLoader_GetNamedResource(PeResourceLoader * loader, PRL_Type resource_type, uint32_t language_id, PRL_ResourceName * resource_name, uint32_t * size);
151+
152+
/**
153+
* @brief Get a list of all resource types found in a PE file.
154+
*
155+
* @param loader PeResourceLoader struct pointer created by PeResourceLoader_Open.
156+
* @param resource_type_count Will contain the amount of resource types in the returned array.
157+
* @return An array of resource type IDs.
158+
*/
159+
uint32_t * PeResourceLoader_GetResourceTypes(PeResourceLoader * loader, uint16_t * resource_type_count);
160+
110161
/**
111162
* @brief Language IDs found in PE files.
112163
*

pe_bitmap_loader/main.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
#include <pe_resource_loader.h>
55

6-
#define STB_IMAGE_WRITE_IMPLEMENTATION
7-
#include "stb_image_write.h"
8-
96
int main(int argc, char ** argv) {
107
if (argc < 2) {
118
printf("No file was defined\n");
@@ -22,14 +19,19 @@ int main(int argc, char ** argv) {
2219
continue;
2320
}
2421

25-
uint32_t bitmap_count = 0;
22+
uint16_t bitmap_count = 0;
2623
uint32_t * bitmap_ids = PeResourceLoader_GetResourceIds(loader, PRL_TYPE_BITMAP, &bitmap_count);
27-
if (bitmap_count == 0) {
24+
uint16_t bitmap_name_count = 0;
25+
PRL_ResourceName * bitmap_names = PeResourceLoader_GetResourceNames(loader, PRL_TYPE_BITMAP, &bitmap_name_count);
26+
if (bitmap_count == 0 && bitmap_name_count == 0) {
2827
printf("No bitmaps found in file %s\n", argv[i]);
2928
PeResourceLoader_Close(loader);
3029
if (bitmap_ids) {
3130
free(bitmap_ids);
3231
}
32+
if (bitmap_names) {
33+
free(bitmap_names);
34+
}
3335
return_value = 3;
3436
continue;
3537
}
@@ -42,6 +44,9 @@ int main(int argc, char ** argv) {
4244
if (bitmap_ids) {
4345
free(bitmap_ids);
4446
}
47+
if (bitmap_names) {
48+
free(bitmap_names);
49+
}
4550
if (languages) {
4651
free(languages);
4752
}
@@ -52,22 +57,39 @@ int main(int argc, char ** argv) {
5257
for (uint16_t li = 0; li < language_count; li++) {
5358
printf("Language with id %u:\n", languages[li]);
5459
for (uint16_t bi = 0; bi < bitmap_count; bi++) {
55-
printf("Found bitmap with id %u\n", bitmap_ids[bi]);
56-
char * file_name = calloc(34, sizeof(char));
57-
snprintf(file_name, 34, "%i_%u_%u.bmp", i, languages[li], bitmap_ids[bi]);
58-
FILE * file = fopen(file_name, "wb");
59-
free(file_name);
6060
uint32_t file_size = 0;
6161
void * data = PeResourceLoader_GetResource(loader, PRL_TYPE_BITMAP, languages[li], bitmap_ids[bi], &file_size);
62-
printf("File size is %u\n", file_size);
63-
fwrite(data, 1, file_size, file);
64-
fclose(file);
65-
free(data);
62+
if (file_size > 0) {
63+
char * file_name = calloc(32 + 32 + 5, sizeof(char));
64+
snprintf(file_name, 32 + 32 + 5, "%u_%u.bmp", bitmap_ids[bi], languages[li]);
65+
printf("Exporting file %s\n", file_name);
66+
FILE * file = fopen(file_name, "wb");
67+
free(file_name);
68+
fwrite(data, 1, file_size, file);
69+
fclose(file);
70+
}
71+
if (data != NULL)
72+
free(data);
73+
}
74+
for (uint16_t bi = 0; bi < bitmap_name_count; bi++) {
75+
uint32_t file_size = 0;
76+
void * data = PeResourceLoader_GetNamedResource(loader, PRL_TYPE_BITMAP, languages[li], &bitmap_names[bi], &file_size);
77+
if (file_size > 0) {
78+
char * file_name = calloc(bitmap_names[bi].name_length + 32 + 4, sizeof(char));
79+
snprintf(file_name, bitmap_names[bi].name_length + 32 + 4, "%s_%u.bmp", bitmap_names[bi].name, languages[li]);
80+
printf("Exporting file %s\n", file_name);
81+
FILE * file = fopen(file_name, "wb");
82+
free(file_name);
83+
fwrite(data, 1, file_size, file);
84+
fclose(file);
85+
}
86+
if (data != NULL)
87+
free(data);
6688
}
67-
printf("\n");
6889
}
6990
free(languages);
7091
free(bitmap_ids);
92+
free(bitmap_names);
7193

7294
PeResourceLoader_Close(loader);
7395
}

0 commit comments

Comments
 (0)