1 static char RCSId
[] = "$Id: ne_resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
18 /* #define DEBUG_RESOURCE */
20 static int ResourceFd
= -1;
21 static HANDLE ResourceInst
= 0;
22 static struct w_files
*ResourceFileInfo
;
24 /**********************************************************************
27 void RSC_LoadNameTable(void)
29 struct resource_typeinfo_s typeinfo
;
30 struct resource_nameinfo_s nameinfo
;
31 unsigned short size_shift
;
43 * Move to beginning of resource table.
45 rtoff
= (ResourceFileInfo
->mz_header
->ne_offset
+
46 ResourceFileInfo
->ne
->ne_header
->resource_tab_offset
);
47 lseek(ResourceFd
, rtoff
, SEEK_SET
);
52 if (read(ResourceFd
, &size_shift
, sizeof(size_shift
)) !=
57 size_shift
= CONV_SHORT(size_shift
);
62 typeinfo
.type_id
= 0xffff;
63 while (typeinfo
.type_id
!= 0)
65 if (!load_typeinfo (ResourceFd
, &typeinfo
))
68 if (typeinfo
.type_id
== 0)
70 if (typeinfo
.type_id
== 0x800f)
72 for (i
= 0; i
< typeinfo
.count
; i
++)
74 if (read(ResourceFd
, &nameinfo
, sizeof(nameinfo
)) !=
80 saved_pos
= lseek(ResourceFd
, 0, SEEK_CUR
);
81 lseek(ResourceFd
, (long) nameinfo
.offset
<< size_shift
,
83 read(ResourceFd
, &len
, sizeof(len
));
86 new = (RESNAMTAB
*) GlobalQuickAlloc(sizeof(*new));
90 read(ResourceFd
, &new->type_ord
, 2);
91 read(ResourceFd
, &new->id_ord
, 2);
92 read(ResourceFd
, read_buf
, len
- 6);
94 p
= read_buf
+ strlen(read_buf
) + 1;
95 strncpy(new->id
, p
, MAX_NAME_LENGTH
);
96 new->id
[MAX_NAME_LENGTH
- 1] = '\0';
98 read(ResourceFd
, &len
, sizeof(len
));
101 lseek(ResourceFd
, saved_pos
, SEEK_SET
);
107 lseek(ResourceFd
, (typeinfo
.count
* sizeof(nameinfo
)), SEEK_CUR
);
110 ResourceFileInfo
->ne
->resnamtab
= top
;
113 /**********************************************************************
117 OpenResourceFile(HANDLE instance
)
122 if (ResourceInst
== instance
)
125 w
= GetFileInfo(instance
);
128 ResourceFileInfo
= w
;
129 res_file
= w
->filename
;
134 ResourceInst
= instance
;
135 ResourceFd
= open (res_file
, O_RDONLY
);
138 if (w
->ne
->resnamtab
== (RESNAMTAB
*) -1)
145 #ifdef DEBUG_RESOURCE
146 printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
147 instance
, w
->filename
, ResourceFd
);
152 int load_typeinfo (int fd
, struct resource_typeinfo_s
*typeinfo
)
154 return read (fd
, typeinfo
, sizeof (*typeinfo
)) == sizeof (*typeinfo
);
157 int type_match(int type_id1
, int type_id2
, int fd
, off_t off
)
166 if ((type_id1
& 0xffff0000) == 0) {
167 if ((type_id2
& 0x8000) == 0)
169 return (type_id1
& 0x000f) == (type_id2
& 0x000f);
171 if ((type_id2
& 0x8000) != 0)
173 #ifdef DEBUG_RESOURCE
174 printf("type_compare: type_id2=%04X !\n", type_id2
);
176 old_pos
= lseek(fd
, 0, SEEK_CUR
);
177 lseek(fd
, off
+ type_id2
, SEEK_SET
);
179 nbytes
= CONV_CHAR_TO_LONG (c
);
180 #ifdef DEBUG_RESOURCE
181 printf("type_compare: namesize=%d\n", nbytes
);
183 read(fd
, name
, nbytes
);
184 lseek(fd
, old_pos
, SEEK_SET
);
186 #ifdef DEBUG_RESOURCE
187 printf("type_compare: name=`%s'\n", name
);
189 return strcasecmp((char *) type_id1
, name
) == 0;
192 /**********************************************************************
193 * FindResourceByNumber
196 FindResourceByNumber(struct resource_nameinfo_s
*result_p
,
197 int type_id
, int resource_id
)
199 struct resource_typeinfo_s typeinfo
;
200 struct resource_nameinfo_s nameinfo
;
201 unsigned short size_shift
;
206 * Move to beginning of resource table.
208 rtoff
= (ResourceFileInfo
->mz_header
->ne_offset
+
209 ResourceFileInfo
->ne
->ne_header
->resource_tab_offset
);
210 lseek(ResourceFd
, rtoff
, SEEK_SET
);
215 if (read(ResourceFd
, &size_shift
, sizeof(size_shift
)) !=
218 printf("FindResourceByNumber (%d) bad block size !\n",(int) resource_id
);
221 size_shift
= CONV_SHORT(size_shift
);
226 if (!load_typeinfo (ResourceFd
, &typeinfo
)){
227 printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id
);
230 #ifdef DEBUG_RESOURCE
231 printf("FindResourceByNumber type=%X count=%d ?=%d searched=%08X\n",
232 typeinfo
.type_id
, typeinfo
.count
, typeinfo
.reserved
, type_id
);
234 if (typeinfo
.type_id
== 0) break;
235 if (type_match(type_id
, typeinfo
.type_id
, ResourceFd
, rtoff
)) {
237 for (i
= 0; i
< typeinfo
.count
; i
++) {
239 if (read(ResourceFd
, &nameinfo
, sizeof(nameinfo
)) !=
242 if (!load_nameinfo (ResourceFd
, &nameinfo
))
245 printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id
);
248 #ifdef DEBUG_RESOURCE
249 printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
250 type_id
, resource_id
, typeinfo
.type_id
, nameinfo
.id
);
252 if (nameinfo
.id
== resource_id
) {
253 memcpy(result_p
, &nameinfo
, sizeof(nameinfo
));
259 lseek(ResourceFd
, (typeinfo
.count
* sizeof(nameinfo
)), SEEK_CUR
);
265 /**********************************************************************
269 FindResourceByName(struct resource_nameinfo_s
*result_p
,
270 int type_id
, char *resource_name
)
272 struct resource_typeinfo_s typeinfo
;
273 struct resource_nameinfo_s nameinfo
;
274 unsigned short size_shift
;
275 off_t old_pos
, new_pos
;
276 unsigned char nbytes
;
282 * Check for loaded name table.
284 if (ResourceFileInfo
->ne
->resnamtab
!= NULL
)
288 for (e
= ResourceFileInfo
->ne
->resnamtab
; e
!= NULL
; e
= e
->next
)
290 if (e
->type_ord
== (type_id
& 0x000f) &&
291 strcasecmp(e
->id
, resource_name
) == 0)
293 return FindResourceByNumber(result_p
, type_id
, e
->id_ord
);
301 * Move to beginning of resource table.
303 rtoff
= (ResourceFileInfo
->mz_header
->ne_offset
+
304 ResourceFileInfo
->ne
->ne_header
->resource_tab_offset
);
305 lseek(ResourceFd
, rtoff
, SEEK_SET
);
310 if (read(ResourceFd
, &size_shift
, sizeof(size_shift
)) !=
313 printf("FindResourceByName (%s) bad block size !\n", resource_name
);
316 size_shift
= CONV_SHORT (size_shift
);
323 if (!load_typeinfo (ResourceFd
, &typeinfo
))
325 printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name
);
328 #ifdef DEBUG_RESOURCE
329 printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
330 typeinfo
.type_id
, typeinfo
.count
, type_id
);
332 if (typeinfo
.type_id
== 0) break;
333 if (type_match(type_id
, typeinfo
.type_id
, ResourceFd
, rtoff
))
335 for (i
= 0; i
< typeinfo
.count
; i
++)
338 if (read(ResourceFd
, &nameinfo
, sizeof(nameinfo
)) !=
341 if (!load_nameinfo (ResourceFd
, &nameinfo
))
344 printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name
);
348 if ((nameinfo.id & 0x8000) != 0) continue;
350 #ifdef DEBUG_RESOURCE
351 printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo
.id
);
353 old_pos
= lseek(ResourceFd
, 0, SEEK_CUR
);
354 new_pos
= rtoff
+ nameinfo
.id
;
355 lseek(ResourceFd
, new_pos
, SEEK_SET
);
356 read(ResourceFd
, &nbytes
, 1);
357 #ifdef DEBUG_RESOURCE
358 printf("FindResourceByName // namesize=%d !\n", nbytes
);
360 nbytes
= CONV_CHAR_TO_LONG (nbytes
);
361 read(ResourceFd
, name
, nbytes
);
362 lseek(ResourceFd
, old_pos
, SEEK_SET
);
364 #ifdef DEBUG_RESOURCE
365 printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
366 typeinfo
.type_id
, i
+ 1, typeinfo
.count
,
367 name
, resource_name
);
369 if (strcasecmp(name
, resource_name
) == 0)
371 memcpy(result_p
, &nameinfo
, sizeof(nameinfo
));
377 lseek(ResourceFd
, (typeinfo
.count
* sizeof(nameinfo
)), SEEK_CUR
);
384 /**********************************************************************
385 * GetRsrcCount [internal]
387 int GetRsrcCount(HINSTANCE hInst
, int type_id
)
389 struct resource_typeinfo_s typeinfo
;
390 struct resource_nameinfo_s nameinfo
;
391 unsigned short size_shift
;
394 if (hInst
== 0) return 0;
395 #ifdef DEBUG_RESOURCE
396 printf("GetRsrcCount hInst=%04X typename=%08X\n", hInst
, type_id
);
398 if (OpenResourceFile(hInst
) < 0) return 0;
401 * Move to beginning of resource table.
403 rtoff
= (ResourceFileInfo
->mz_header
->ne_offset
+
404 ResourceFileInfo
->ne
->ne_header
->resource_tab_offset
);
405 lseek(ResourceFd
, rtoff
, SEEK_SET
);
409 if (read(ResourceFd
, &size_shift
, sizeof(size_shift
)) != sizeof(size_shift
)) {
410 printf("GetRsrcCount // bad block size !\n");
413 size_shift
= CONV_SHORT (size_shift
);
415 if (!load_typeinfo (ResourceFd
, &typeinfo
)) {
416 printf("GetRsrcCount // bad typeinfo size !\n");
419 #ifdef DEBUG_RESOURCE
420 printf("GetRsrcCount // typeinfo.type_id=%X count=%d type_id=%X\n",
421 typeinfo
.type_id
, typeinfo
.count
, type_id
);
423 if (typeinfo
.type_id
== 0) break;
424 if (type_match(type_id
, typeinfo
.type_id
, ResourceFd
, rtoff
)) {
425 return typeinfo
.count
;
428 lseek(ResourceFd
, (typeinfo
.count
* sizeof(nameinfo
)), SEEK_CUR
);
434 /**********************************************************************
435 * NE_FindResource [KERNEL.60]
438 NE_FindResource(HANDLE instance
, LPSTR resource_name
, LPSTR type_name
,
443 #ifdef DEBUG_RESOURCE
444 printf("NE_FindResource hInst=%04X typename=%08X resname=%08X\n",
445 instance
, type_name
, resource_name
);
449 ResourceFileInfo
= r
->wpnt
;
451 /* nametable loaded ? */
452 if (r
->wpnt
->ne
->resnamtab
== NULL
)
455 if (((int) type_name
& 0xffff0000) == 0)
457 type
= (int) type_name
;
459 else if (type_name
[0] == '\0')
463 else if (type_name
[0] == '#')
465 type
= atoi(type_name
+ 1);
469 type
= (int) type_name
;
471 if (((int) resource_name
& 0xffff0000) == 0)
473 r
->size_shift
= FindResourceByNumber(&r
->nameinfo
, type
,
474 (int) resource_name
| 0x8000);
476 else if (resource_name
[0] == '\0')
478 r
->size_shift
= FindResourceByNumber(&r
->nameinfo
, type
, -1);
480 else if (resource_name
[0] == '#')
482 r
->size_shift
= FindResourceByNumber(&r
->nameinfo
, type
,
483 atoi(resource_name
+ 1));
487 r
->size_shift
= FindResourceByName(&r
->nameinfo
, type
, resource_name
);
490 if (r
->size_shift
== -1)
492 printf("NE_FindResource hInst=%04X typename=%08X resname=%08X not found!\n",
493 instance
, (int) type_name
, (int) resource_name
);
496 r
->size
= r
->nameinfo
.length
<< r
->size_shift
;
497 r
->offset
= r
->nameinfo
.offset
<< r
->size_shift
;