4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
26 typedef struct resource_typeinfo_s NE_TYPEINFO
;
27 typedef struct resource_nameinfo_s NE_NAMEINFO
;
30 /***********************************************************************
33 * Find the type and resource id from their names.
34 * Return value is MAKELONG( typeId, resId ), or 0 if not found.
36 static DWORD
NE_FindNameTableId( HMODULE hModule
, SEGPTR typeId
, SEGPTR resId
)
39 NE_TYPEINFO
*pTypeInfo
;
40 NE_NAMEINFO
*pNameInfo
;
46 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
47 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
48 for (; pTypeInfo
->type_id
!= 0;
49 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
50 pTypeInfo
->count
* sizeof(NE_NAMEINFO
)))
52 if (pTypeInfo
->type_id
!= 0x800f) continue;
53 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
54 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
56 dprintf_resource( stddeb
, "NameTable entry: type=%04x id=%04x\n",
57 pTypeInfo
->type_id
, pNameInfo
->id
);
58 handle
= LoadResource( hModule
,
59 (HANDLE
)((int)pNameInfo
- (int)pModule
) );
60 for(p
= (WORD
*)LockResource(handle
); p
&& *p
; p
= (WORD
*)((char*)p
+*p
))
62 dprintf_resource( stddeb
," type=%04x '%s' id=%04x '%s'\n",
63 p
[1], (char *)(p
+3), p
[2],
64 (char *)(p
+3)+strlen((char *)(p
+3))+1 );
65 /* Check for correct type */
69 if (!HIWORD(typeId
)) continue;
70 if (strcasecmp( (char *)PTR_SEG_TO_LIN(typeId
),
71 (char *)(p
+ 3) )) continue;
73 else if (HIWORD(typeId
) || ((typeId
& ~0x8000)!= p
[1]))
76 /* Now check for the id */
80 if (!HIWORD(resId
)) continue;
81 if (strcasecmp( (char *)PTR_SEG_TO_LIN(resId
),
82 (char*)(p
+3)+strlen((char*)(p
+3))+1 )) continue;
85 else if (HIWORD(resId
) || ((resId
& ~0x8000) != p
[2]))
88 /* If we get here, we've found the entry */
90 dprintf_resource( stddeb
, " Found!\n" );
91 ret
= MAKELONG( p
[1], p
[2] );
94 FreeResource( handle
);
102 /***********************************************************************
103 * NE_FindResourceFromType
105 * Find a resource once the type info structure has been found.
107 static HRSRC
NE_FindResourceFromType( NE_MODULE
*pModule
,
108 NE_TYPEINFO
*pTypeInfo
, SEGPTR resId
)
112 NE_NAMEINFO
*pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
114 if (HIWORD(resId
) != 0) /* Named resource */
116 char *str
= (char *)PTR_SEG_TO_LIN( resId
);
117 BYTE len
= strlen( str
);
118 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
120 if (pNameInfo
->id
& 0x8000) continue;
121 p
= (BYTE
*)pModule
+ pModule
->res_table
+ pNameInfo
->id
;
122 if ((*p
== len
) && !strncasecmp( p
+1, str
, len
))
123 return (HRSRC
)((int)pNameInfo
- (int)pModule
);
126 else /* Numeric resource id */
128 WORD id
= LOWORD(resId
) | 0x8000;
129 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
130 if (pNameInfo
->id
== id
)
131 return (HRSRC
)((int)pNameInfo
- (int)pModule
);
137 /***********************************************************************
140 HRSRC
NE_FindResource( HMODULE hModule
, SEGPTR typeId
, SEGPTR resId
)
143 NE_TYPEINFO
*pTypeInfo
;
146 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
147 if (!pModule
|| !pModule
->res_table
) return 0;
148 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
150 if (HIWORD(typeId
) || HIWORD(resId
))
152 /* Search the names in the nametable */
153 DWORD id
= NE_FindNameTableId( hModule
, typeId
, resId
);
161 if (HIWORD(typeId
) != 0) /* Named type */
163 char *str
= (char *)PTR_SEG_TO_LIN( typeId
);
164 BYTE len
= strlen( str
);
165 while (pTypeInfo
->type_id
)
167 if (!(pTypeInfo
->type_id
& 0x8000))
169 BYTE
*p
= (BYTE
*)pModule
+pModule
->res_table
+pTypeInfo
->type_id
;
170 if ((*p
== len
) && !strncasecmp( p
+1, str
, len
))
172 dprintf_resource( stddeb
, " Found type '%s'\n", str
);
173 hRsrc
= NE_FindResourceFromType(pModule
, pTypeInfo
, resId
);
176 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
179 dprintf_resource( stddeb
, " Not found, going on\n" );
182 dprintf_resource( stddeb
, " Skipping type %04x\n",
183 pTypeInfo
->type_id
);
184 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
185 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
188 else /* Numeric type id */
190 WORD id
= LOWORD(typeId
) | 0x8000;
191 while (pTypeInfo
->type_id
)
193 if (pTypeInfo
->type_id
== id
)
195 dprintf_resource( stddeb
, " Found type %04x\n", id
);
196 hRsrc
= NE_FindResourceFromType( pModule
, pTypeInfo
, resId
);
199 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
202 dprintf_resource( stddeb
, " Not found, going on\n" );
204 dprintf_resource( stddeb
, " Skipping type %04x\n",
205 pTypeInfo
->type_id
);
206 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
207 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
215 /***********************************************************************
218 HGLOBAL
NE_AllocResource( HMODULE hModule
, HRSRC hRsrc
, DWORD size
)
221 NE_NAMEINFO
*pNameInfo
=NULL
;
224 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
225 if (!pModule
|| !pModule
->res_table
) return 0;
226 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
228 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
230 if (size
< (DWORD
)pNameInfo
->length
<< sizeShift
)
231 size
= (DWORD
)pNameInfo
->length
<< sizeShift
;
232 return GLOBAL_Alloc( GMEM_FIXED
, size
, hModule
, FALSE
, FALSE
, FALSE
);
236 /***********************************************************************
239 int NE_AccessResource( HMODULE hModule
, HRSRC hRsrc
)
242 NE_NAMEINFO
*pNameInfo
=NULL
;
247 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
248 if (!pModule
|| !pModule
->res_table
) return 0;
250 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
253 name
= ((LOADEDFILEINFO
*)((char*)pModule
+ pModule
->fileinfo
))->filename
;
254 fd
= open( DOS_GetUnixFileName(name
), O_RDONLY
);
255 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
256 lseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
261 /***********************************************************************
264 DWORD
NE_SizeofResource( HMODULE hModule
, HRSRC hRsrc
)
267 NE_NAMEINFO
*pNameInfo
=NULL
;
270 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
271 if (!pModule
|| !pModule
->res_table
) return 0;
272 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
274 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
276 return (DWORD
)pNameInfo
->length
<< sizeShift
;
280 /***********************************************************************
283 HGLOBAL
NE_LoadResource( HMODULE hModule
, HRSRC hRsrc
)
286 NE_NAMEINFO
*pNameInfo
=NULL
;
290 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
291 if (!pModule
|| !pModule
->res_table
) return 0;
293 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
295 if (pNameInfo
->handle
)
298 dprintf_resource( stddeb
, " Already loaded, new count=%d\n",
300 return pNameInfo
->handle
;
302 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
303 dprintf_resource( stddeb
, " Loading, pos=%d, len=%d\n",
304 (int)pNameInfo
->offset
<< sizeShift
,
305 (int)pNameInfo
->length
<< sizeShift
);
306 if ((fd
= MODULE_OpenFile( hModule
)) == -1) return 0;
307 pNameInfo
->handle
= NE_AllocResource( hModule
, hRsrc
, 0 );
308 pNameInfo
->usage
= 1;
309 lseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
310 read( fd
, GlobalLock( pNameInfo
->handle
),
311 (int)pNameInfo
->length
<< sizeShift
);
312 return pNameInfo
->handle
;
316 /***********************************************************************
319 SEGPTR
NE_LockResource( HMODULE hModule
, HGLOBAL handle
)
321 /* May need to reload the resource if discarded */
323 return (SEGPTR
)WIN16_GlobalLock( handle
);
327 /***********************************************************************
330 BOOL
NE_FreeResource( HMODULE hModule
, HGLOBAL handle
)
333 NE_TYPEINFO
*pTypeInfo
;
334 NE_NAMEINFO
*pNameInfo
;
337 pModule
= (NE_MODULE
*)GlobalLock( hModule
);
338 if (!pModule
|| !pModule
->res_table
) return FALSE
;
339 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
340 while (pTypeInfo
->type_id
)
342 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
343 for (count
= pTypeInfo
->count
; count
> 0; count
--)
345 if (pNameInfo
->handle
== handle
)
347 if (pNameInfo
->usage
> 0) pNameInfo
->usage
--;
348 if (pNameInfo
->usage
== 0)
350 GlobalFree( pNameInfo
->handle
);
351 pNameInfo
->handle
= 0;
357 pTypeInfo
= (NE_TYPEINFO
*)pNameInfo
;
359 fprintf( stderr
, "FreeResource: "NPFMT
" "NPFMT
" not found!\n", hModule
, handle
);