diff options
author | Thomas Martitz <kugel@rockbox.org> | 2010-09-09 16:17:21 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2010-09-09 16:17:21 +0000 |
commit | 0d4585b28ffcac1b62ed37cee2c34de0515df468 (patch) | |
tree | 70ace8b78a4d0a44da50d692e893fadd93f85878 /apps/plugins/lib | |
parent | cec7c99613b3c11deb8a05deecd7ee9d16b5ea8a (diff) | |
download | rockbox-0d4585b28ffcac1b62ed37cee2c34de0515df468.tar.gz rockbox-0d4585b28ffcac1b62ed37cee2c34de0515df468.zip |
Extend lc_open() to also being able to load overlay plugins.
For this it needs to look at the plugin header. Since lc_open() doesn't know
it's a plugin, the header needs to be changed slightly to include the new lc_header (which needs to be the first element in plugin_header so it can be casted savely).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28054 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib')
-rw-r--r-- | apps/plugins/lib/overlay.c | 76 |
1 files changed, 34 insertions, 42 deletions
diff --git a/apps/plugins/lib/overlay.c b/apps/plugins/lib/overlay.c index 8a04cf8aa7..f64df29823 100644 --- a/apps/plugins/lib/overlay.c +++ b/apps/plugins/lib/overlay.c | |||
@@ -47,64 +47,56 @@ | |||
47 | enum plugin_status run_overlay(const void* parameter, | 47 | enum plugin_status run_overlay(const void* parameter, |
48 | unsigned char *filename, unsigned char *name) | 48 | unsigned char *filename, unsigned char *name) |
49 | { | 49 | { |
50 | int fd, readsize; | ||
51 | size_t audiobuf_size; | 50 | size_t audiobuf_size; |
52 | unsigned char *audiobuf; | 51 | unsigned char *audiobuf; |
53 | static struct plugin_header header; | 52 | void *handle; |
53 | struct plugin_header *p_hdr; | ||
54 | struct lc_header *hdr; | ||
54 | 55 | ||
55 | fd = rb->open(filename, O_RDONLY); | 56 | audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size); |
56 | if (fd < 0) | 57 | if (!audiobuf) |
57 | { | 58 | { |
58 | rb->splashf(2*HZ, "Can't open %s", filename); | 59 | rb->splash(2*HZ, "Can't optain memory"); |
59 | return PLUGIN_ERROR; | 60 | goto error; |
60 | } | 61 | } |
61 | readsize = rb->read(fd, &header, sizeof(header)); | ||
62 | rb->close(fd); | ||
63 | /* Close for now. Less code than doing it in all error checks. | ||
64 | * Would need to seek back anyway. */ | ||
65 | 62 | ||
66 | if (readsize != sizeof(header)) | 63 | handle = rb->lc_open(filename, audiobuf, audiobuf_size); |
67 | { | 64 | if (!handle) |
68 | rb->splashf(2*HZ, "Reading %s overlay failed.", name); | ||
69 | return PLUGIN_ERROR; | ||
70 | } | ||
71 | if (header.magic != PLUGIN_MAGIC || header.target_id != TARGET_ID) | ||
72 | { | 65 | { |
73 | rb->splashf(2*HZ, "%s overlay: Incompatible model.", name); | 66 | rb->splashf(2*HZ, "Can't open %s", filename); |
74 | return PLUGIN_ERROR; | 67 | goto error; |
75 | } | ||
76 | if (header.api_version != PLUGIN_API_VERSION) | ||
77 | { | ||
78 | rb->splashf(2*HZ, "%s overlay: Incompatible version.", name); | ||
79 | return PLUGIN_ERROR; | ||
80 | } | 68 | } |
81 | 69 | ||
82 | audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size); | 70 | p_hdr = rb->lc_get_header(handle); |
83 | if (header.load_addr < audiobuf || | 71 | if (!p_hdr) |
84 | header.end_addr > audiobuf + audiobuf_size) | ||
85 | { | 72 | { |
86 | rb->splashf(2*HZ, "%s overlay doesn't fit into memory.", name); | 73 | rb->splash(2*HZ, "Can't get header"); |
87 | return PLUGIN_ERROR; | 74 | goto error_close; |
88 | } | 75 | } |
76 | else | ||
77 | hdr = &p_hdr->lc_hdr; | ||
89 | 78 | ||
90 | fd = rb->open(filename, O_RDONLY); | 79 | if (hdr->magic != PLUGIN_MAGIC || hdr->target_id != TARGET_ID) |
91 | if (fd < 0) | ||
92 | { | 80 | { |
93 | rb->splashf(2*HZ, "Can't open %s", filename); | 81 | rb->splashf(2*HZ, "%s overlay: Incompatible model.", name); |
94 | return PLUGIN_ERROR; | 82 | goto error_close; |
95 | } | 83 | } |
96 | readsize = rb->read(fd, header.load_addr, header.end_addr - header.load_addr); | ||
97 | rb->close(fd); | ||
98 | 84 | ||
99 | if (readsize < 0) | 85 | |
86 | if (hdr->api_version > PLUGIN_API_VERSION | ||
87 | || hdr->api_version < PLUGIN_MIN_API_VERSION) | ||
100 | { | 88 | { |
101 | rb->splashf(2*HZ, "Reading %s overlay failed.", name); | 89 | rb->splashf(2*HZ, "%s overlay: Incompatible version.", name); |
102 | return PLUGIN_ERROR; | 90 | goto error_close; |
103 | } | 91 | } |
104 | /* Zero out bss area */ | ||
105 | rb->memset(header.load_addr + readsize, 0, | ||
106 | header.end_addr - (header.load_addr + readsize)); | ||
107 | 92 | ||
108 | *(header.api) = rb; | 93 | rb->lc_close(handle); |
109 | return header.entry_point(parameter); | 94 | |
95 | *(p_hdr->api) = rb; | ||
96 | return p_hdr->entry_point(parameter); | ||
97 | |||
98 | error_close: | ||
99 | rb->lc_close(handle); | ||
100 | error: | ||
101 | return PLUGIN_ERROR; | ||
110 | } | 102 | } |