4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
26 /***********************************************************************
29 * Find the type and resource id from their names.
30 * Return value is MAKELONG( typeId, resId ), or 0 if not found.
32 static DWORD
NE_FindNameTableId( HMODULE16 hModule
, SEGPTR typeId
, SEGPTR resId
)
35 NE_TYPEINFO
*pTypeInfo
;
36 NE_NAMEINFO
*pNameInfo
;
42 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
43 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
44 for (; pTypeInfo
->type_id
!= 0;
45 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
46 pTypeInfo
->count
* sizeof(NE_NAMEINFO
)))
48 if (pTypeInfo
->type_id
!= 0x800f) continue;
49 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
50 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
52 dprintf_resource( stddeb
, "NameTable entry: type=%04x id=%04x\n",
53 pTypeInfo
->type_id
, pNameInfo
->id
);
54 handle
= LoadResource16( hModule
,
55 (HRSRC16
)((int)pNameInfo
- (int)pModule
) );
56 for(p
= (WORD
*)LockResource16(handle
); p
&& *p
; p
= (WORD
*)((char*)p
+*p
))
58 dprintf_resource( stddeb
," type=%04x '%s' id=%04x '%s'\n",
59 p
[1], (char *)(p
+3), p
[2],
60 (char *)(p
+3)+strlen((char *)(p
+3))+1 );
61 /* Check for correct type */
65 if (!HIWORD(typeId
)) continue;
66 if (lstrcmpi32A( (char *)PTR_SEG_TO_LIN(typeId
),
67 (char *)(p
+ 3) )) continue;
69 else if (HIWORD(typeId
) || ((typeId
& ~0x8000)!= p
[1]))
72 /* Now check for the id */
76 if (!HIWORD(resId
)) continue;
77 if (lstrcmpi32A( (char *)PTR_SEG_TO_LIN(resId
),
78 (char*)(p
+3)+strlen((char*)(p
+3))+1 )) continue;
81 else if (HIWORD(resId
) || ((resId
& ~0x8000) != p
[2]))
84 /* If we get here, we've found the entry */
86 dprintf_resource( stddeb
, " Found!\n" );
87 ret
= MAKELONG( p
[1], p
[2] );
90 FreeResource16( handle
);
98 /***********************************************************************
99 * NE_FindResourceFromType
101 * Find a resource once the type info structure has been found.
103 static HRSRC16
NE_FindResourceFromType( NE_MODULE
*pModule
,
104 NE_TYPEINFO
*pTypeInfo
, SEGPTR resId
)
108 NE_NAMEINFO
*pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
110 if (HIWORD(resId
) != 0) /* Named resource */
112 char *str
= (char *)PTR_SEG_TO_LIN( resId
);
113 BYTE len
= strlen( str
);
114 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
116 if (pNameInfo
->id
& 0x8000) continue;
117 p
= (BYTE
*)pModule
+ pModule
->res_table
+ pNameInfo
->id
;
118 if ((*p
== len
) && !lstrncmpi32A( p
+1, str
, len
))
119 return (HRSRC16
)((int)pNameInfo
- (int)pModule
);
122 else /* Numeric resource id */
124 WORD id
= LOWORD(resId
) | 0x8000;
125 for (count
= pTypeInfo
->count
; count
> 0; count
--, pNameInfo
++)
126 if (pNameInfo
->id
== id
)
127 return (HRSRC16
)((int)pNameInfo
- (int)pModule
);
133 /***********************************************************************
136 HRSRC16
NE_FindResource( HMODULE16 hModule
, SEGPTR typeId
, SEGPTR resId
)
138 NE_TYPEINFO
*pTypeInfo
;
141 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
142 if (!pModule
|| !pModule
->res_table
) return 0;
143 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
145 if (HIWORD(typeId
) || HIWORD(resId
))
147 /* Search the names in the nametable */
148 DWORD id
= NE_FindNameTableId( hModule
, typeId
, resId
);
156 if (HIWORD(typeId
) != 0) /* Named type */
158 char *str
= (char *)PTR_SEG_TO_LIN( typeId
);
159 BYTE len
= strlen( str
);
160 while (pTypeInfo
->type_id
)
162 if (!(pTypeInfo
->type_id
& 0x8000))
164 BYTE
*p
= (BYTE
*)pModule
+pModule
->res_table
+pTypeInfo
->type_id
;
165 if ((*p
== len
) && !lstrncmpi32A( p
+1, str
, len
))
167 dprintf_resource( stddeb
, " Found type '%s'\n", str
);
168 hRsrc
= NE_FindResourceFromType(pModule
, pTypeInfo
, resId
);
171 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
174 dprintf_resource( stddeb
, " Not found, going on\n" );
177 dprintf_resource( stddeb
, " Skipping type %04x\n",
178 pTypeInfo
->type_id
);
179 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
180 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
183 else /* Numeric type id */
185 WORD id
= LOWORD(typeId
) | 0x8000;
186 while (pTypeInfo
->type_id
)
188 if (pTypeInfo
->type_id
== id
)
190 dprintf_resource( stddeb
, " Found type %04x\n", id
);
191 hRsrc
= NE_FindResourceFromType( pModule
, pTypeInfo
, resId
);
194 dprintf_resource( stddeb
, " Found id %08lx\n", resId
);
197 dprintf_resource( stddeb
, " Not found, going on\n" );
199 dprintf_resource( stddeb
, " Skipping type %04x\n",
200 pTypeInfo
->type_id
);
201 pTypeInfo
= (NE_TYPEINFO
*)((char*)(pTypeInfo
+1) +
202 pTypeInfo
->count
* sizeof(NE_NAMEINFO
));
210 /***********************************************************************
213 HGLOBAL16
NE_AllocResource( HMODULE16 hModule
, HRSRC16 hRsrc
, DWORD size
)
215 NE_NAMEINFO
*pNameInfo
=NULL
;
218 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
219 if (!pModule
|| !pModule
->res_table
) return 0;
220 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
222 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
224 if (size
< (DWORD
)pNameInfo
->length
<< sizeShift
)
225 size
= (DWORD
)pNameInfo
->length
<< sizeShift
;
226 return GLOBAL_Alloc( GMEM_FIXED
, size
, hModule
, FALSE
, FALSE
, FALSE
);
230 /***********************************************************************
233 int NE_AccessResource( HMODULE16 hModule
, HRSRC16 hRsrc
)
235 NE_NAMEINFO
*pNameInfo
=NULL
;
238 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
239 if (!pModule
|| !pModule
->res_table
) return -1;
241 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
244 if ((fd
= _lopen32( NE_MODULE_NAME(pModule
), OF_READ
)) != -1)
246 WORD sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
247 _llseek32( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
253 /***********************************************************************
256 DWORD
NE_SizeofResource( HMODULE16 hModule
, HRSRC16 hRsrc
)
258 NE_NAMEINFO
*pNameInfo
=NULL
;
261 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
262 if (!pModule
|| !pModule
->res_table
) return 0;
263 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
265 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
267 return (DWORD
)pNameInfo
->length
<< sizeShift
;
271 /***********************************************************************
274 HGLOBAL16
NE_LoadResource( HMODULE16 hModule
, HRSRC16 hRsrc
)
276 NE_NAMEINFO
*pNameInfo
=NULL
;
280 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
281 if (!pModule
|| !pModule
->res_table
) return 0;
283 pNameInfo
= (NE_NAMEINFO
*)((char*)pModule
+ hRsrc
);
285 if (pNameInfo
->handle
)
288 dprintf_resource( stddeb
, " Already loaded, new count=%d\n",
290 return pNameInfo
->handle
;
292 sizeShift
= *(WORD
*)((char *)pModule
+ pModule
->res_table
);
293 dprintf_resource( stddeb
, " Loading, pos=%d, len=%d\n",
294 (int)pNameInfo
->offset
<< sizeShift
,
295 (int)pNameInfo
->length
<< sizeShift
);
296 if ((fd
= MODULE_OpenFile( hModule
)) == -1) return 0;
297 pNameInfo
->handle
= NE_AllocResource( hModule
, hRsrc
, 0 );
298 pNameInfo
->usage
= 1;
299 lseek( fd
, (int)pNameInfo
->offset
<< sizeShift
, SEEK_SET
);
300 read( fd
, GlobalLock16( pNameInfo
->handle
),
301 (int)pNameInfo
->length
<< sizeShift
);
302 return pNameInfo
->handle
;
306 /***********************************************************************
309 SEGPTR
NE_LockResource( HMODULE16 hModule
, HGLOBAL16 handle
)
311 /* May need to reload the resource if discarded */
313 return (SEGPTR
)WIN16_GlobalLock16( handle
);
317 /***********************************************************************
320 BOOL32
NE_FreeResource( HMODULE16 hModule
, HGLOBAL16 handle
)
322 NE_TYPEINFO
*pTypeInfo
;
323 NE_NAMEINFO
*pNameInfo
;
326 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
327 if (!pModule
|| !pModule
->res_table
) return handle
;
328 pTypeInfo
= (NE_TYPEINFO
*)((char *)pModule
+ pModule
->res_table
+ 2);
329 while (pTypeInfo
->type_id
)
331 pNameInfo
= (NE_NAMEINFO
*)(pTypeInfo
+ 1);
332 for (count
= pTypeInfo
->count
; count
> 0; count
--)
334 if (pNameInfo
->handle
== handle
)
336 if (pNameInfo
->usage
> 0) pNameInfo
->usage
--;
337 if (pNameInfo
->usage
== 0)
339 GlobalFree16( pNameInfo
->handle
);
340 pNameInfo
->handle
= 0;
346 pTypeInfo
= (NE_TYPEINFO
*)pNameInfo
;
348 fprintf( stderr
, "NE_FreeResource: %04x %04x not found!\n", hModule
, handle
);