blob: 5b8f9a1d3a0704f125741794c4d355fcf5dc1c99 [file] [log] [blame]
Alexandre Julliard234bc241994-12-10 13:02:28 +00001/*
Alexandre Julliard594997c1995-04-30 10:05:20 +00002 * Resources
3 *
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Alexandre Julliard594997c1995-04-30 10:05:20 +000020 */
21
Patrik Stridvalld016f812002-08-17 00:43:16 +000022#include "config.h"
Patrik Stridvall9aab47e2002-08-28 23:42:34 +000023#include "wine/port.h"
Patrik Stridvalld016f812002-08-17 00:43:16 +000024
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000025#include <assert.h>
Alexandre Julliard401710d1993-09-04 10:09:32 +000026#include <stdlib.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000027#include <string.h>
Alexandre Julliardf0b23541993-09-29 12:21:49 +000028#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
Patrik Stridvalld016f812002-08-17 00:43:16 +000031#ifdef HAVE_UNISTD_H
32# include <unistd.h>
33#endif
Ulrich Weigand05112821999-03-10 14:02:06 +000034#include "windef.h"
Alexandre Julliard58d5a0a2000-07-29 21:58:17 +000035#include "winbase.h"
Marcus Meissner04c3e1d1999-02-19 10:37:02 +000036#include "wine/winbase16.h"
Richard Cohenc775e1e2000-04-16 20:27:51 +000037#include "wine/exception.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000038#include "heap.h"
Ulrich Weigand05112821999-03-10 14:02:06 +000039#include "cursoricon.h"
Alexandre Julliard594997c1995-04-30 10:05:20 +000040#include "module.h"
Ulrich Weigand80a69b61998-11-25 17:58:51 +000041#include "file.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000042#include "wine/debug.h"
Alexandre Julliard54c27111998-03-29 19:44:57 +000043#include "winerror.h"
Joshua Thielena49bb261999-07-04 12:55:10 +000044#include "winnls.h"
Dimitrie O. Paun737d4be2002-12-12 23:34:01 +000045#include "excpt.h"
Matthew Davison60009b92003-01-23 23:07:38 +000046#include "winternl.h"
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000047
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000048WINE_DEFAULT_DEBUG_CHANNEL(resource);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000049
Ulrich Weigand80a69b61998-11-25 17:58:51 +000050#define HRSRC_MAP_BLOCKSIZE 16
51
Michael Stefaniuc9d2b8622002-09-16 22:47:05 +000052/* handle conversions */
53#define HRSRC_32(h16) ((HRSRC)(ULONG_PTR)(h16))
Andrew John Hughesed800c62002-11-21 03:45:01 +000054#define HGLOBAL_32(h16) ((HGLOBAL)(ULONG_PTR)(h16))
55#define HGLOBAL_16(h32) (LOWORD(h32))
56#define HMODULE_32(h16) ((HMODULE)(ULONG_PTR)(h16))
Michael Stefaniuc9d2b8622002-09-16 22:47:05 +000057
Ulrich Weigand80a69b61998-11-25 17:58:51 +000058typedef struct _HRSRC_ELEM
59{
Michael Stefaniuc9d2b8622002-09-16 22:47:05 +000060 HRSRC hRsrc;
61 WORD type;
Ulrich Weigand80a69b61998-11-25 17:58:51 +000062} HRSRC_ELEM;
63
64typedef struct _HRSRC_MAP
65{
66 int nAlloc;
67 int nUsed;
68 HRSRC_ELEM *elem;
69} HRSRC_MAP;
70
71/**********************************************************************
72 * MapHRsrc32To16
73 */
Michael Stefaniuc9d2b8622002-09-16 22:47:05 +000074static HRSRC MapHRsrc32To16( NE_MODULE *pModule, HRSRC hRsrc32, WORD type )
Ulrich Weigand80a69b61998-11-25 17:58:51 +000075{
76 HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap;
77 HRSRC_ELEM *newElem;
78 int i;
79
80 /* On first call, initialize HRSRC map */
81 if ( !map )
82 {
Vincent Béron9a624912002-05-31 23:06:46 +000083 if ( !(map = (HRSRC_MAP *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
Ulrich Weigand80a69b61998-11-25 17:58:51 +000084 sizeof(HRSRC_MAP) ) ) )
85 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +000086 ERR("Cannot allocate HRSRC map\n" );
Ulrich Weigand80a69b61998-11-25 17:58:51 +000087 return 0;
88 }
89 pModule->hRsrcMap = (LPVOID)map;
90 }
91
92 /* Check whether HRSRC32 already in map */
93 for ( i = 0; i < map->nUsed; i++ )
94 if ( map->elem[i].hRsrc == hRsrc32 )
Alexandre Julliard267ca682002-07-31 17:20:00 +000095 return (HRSRC)(i + 1);
Ulrich Weigand80a69b61998-11-25 17:58:51 +000096
97 /* If no space left, grow table */
98 if ( map->nUsed == map->nAlloc )
99 {
Vincent Béron9a624912002-05-31 23:06:46 +0000100 if ( !(newElem = (HRSRC_ELEM *)HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
101 map->elem,
102 (map->nAlloc + HRSRC_MAP_BLOCKSIZE)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000103 * sizeof(HRSRC_ELEM) ) ))
104 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000105 ERR("Cannot grow HRSRC map\n" );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000106 return 0;
107 }
108 map->elem = newElem;
109 map->nAlloc += HRSRC_MAP_BLOCKSIZE;
110 }
111
112 /* Add HRSRC32 to table */
113 map->elem[map->nUsed].hRsrc = hRsrc32;
114 map->elem[map->nUsed].type = type;
115 map->nUsed++;
116
Alexandre Julliard267ca682002-07-31 17:20:00 +0000117 return (HRSRC)map->nUsed;
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000118}
119
120/**********************************************************************
121 * MapHRsrc16To32
122 */
Alexandre Julliard267ca682002-07-31 17:20:00 +0000123static HRSRC MapHRsrc16To32( NE_MODULE *pModule, HRSRC hRsrc16 )
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000124{
125 HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap;
126 if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0;
127
128 return map->elem[(int)hRsrc16-1].hRsrc;
129}
130
131/**********************************************************************
132 * MapHRsrc16ToType
133 */
Alexandre Julliard267ca682002-07-31 17:20:00 +0000134static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC hRsrc16 )
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000135{
136 HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap;
137 if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0;
138
139 return map->elem[(int)hRsrc16-1].type;
140}
141
Ulrich Weigand05112821999-03-10 14:02:06 +0000142
Richard Cohenc775e1e2000-04-16 20:27:51 +0000143/* filter for page-fault exceptions */
144static WINE_EXCEPTION_FILTER(page_fault)
145{
146 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
147 return EXCEPTION_EXECUTE_HANDLER;
148 return EXCEPTION_CONTINUE_SEARCH;
149}
150
151static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
Vincent Béron9a624912002-05-31 23:06:46 +0000152 LPCSTR name, WORD lang,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000153 BOOL bUnicode, BOOL bRet16 )
Richard Cohenc775e1e2000-04-16 20:27:51 +0000154{
155 HRSRC hRsrc = 0;
Vincent Béron9a624912002-05-31 23:06:46 +0000156
Andrew John Hughesed800c62002-11-21 03:45:01 +0000157 TRACE("(%p, %08x%s, %08x%s, %04x, %s, %s)\n",
Richard Cohenc775e1e2000-04-16 20:27:51 +0000158 hModule,
Richard Cohenc775e1e2000-04-16 20:27:51 +0000159 (UINT)type, HIWORD(type)? (bUnicode? debugstr_w((LPWSTR)type) : debugstr_a(type)) : "",
160 (UINT)name, HIWORD(name)? (bUnicode? debugstr_w((LPWSTR)name) : debugstr_a(name)) : "",
161 lang,
162 bUnicode? "W" : "A",
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000163 bRet16? "NE" : "PE" );
Alexandre Julliard32936f02000-08-07 23:50:00 +0000164
165 if (!HIWORD(hModule))
Richard Cohenc775e1e2000-04-16 20:27:51 +0000166 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000167 HMODULE16 hMod16 = MapHModuleLS( hModule );
168 NE_MODULE *pModule = NE_GetPtr( hMod16 );
169 if (!pModule) return 0;
170 if (!pModule->module32)
171 {
Richard Cohenc775e1e2000-04-16 20:27:51 +0000172 /* 16-bit NE module */
173 LPSTR typeStr, nameStr;
Vincent Béron9a624912002-05-31 23:06:46 +0000174
Richard Cohenc775e1e2000-04-16 20:27:51 +0000175 if ( HIWORD( type ) && bUnicode )
176 typeStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)type );
177 else
178 typeStr = (LPSTR)type;
179 if ( HIWORD( name ) && bUnicode )
180 nameStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)name );
181 else
182 nameStr = (LPSTR)name;
Vincent Béron9a624912002-05-31 23:06:46 +0000183
Richard Cohenc775e1e2000-04-16 20:27:51 +0000184 hRsrc = NE_FindResource( pModule, nameStr, typeStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000185
186 if ( HIWORD( type ) && bUnicode )
Richard Cohenc775e1e2000-04-16 20:27:51 +0000187 HeapFree( GetProcessHeap(), 0, typeStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000188 if ( HIWORD( name ) && bUnicode )
Richard Cohenc775e1e2000-04-16 20:27:51 +0000189 HeapFree( GetProcessHeap(), 0, nameStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000190
Richard Cohenc775e1e2000-04-16 20:27:51 +0000191 /* If we need to return 32-bit HRSRC, no conversion is necessary,
192 we simply use the 16-bit HRSRC as 32-bit HRSRC */
Alexandre Julliard32936f02000-08-07 23:50:00 +0000193 }
194 else
195 {
196 /* 32-bit PE module */
197 hRsrc = RES_FindResource2( pModule->module32, type, name, lang, bUnicode, FALSE );
198 /* If we need to return 16-bit HRSRC, perform conversion */
199 if ( bRet16 )
Vincent Béron9a624912002-05-31 23:06:46 +0000200 hRsrc = MapHRsrc32To16( pModule, hRsrc,
Alexandre Julliard32936f02000-08-07 23:50:00 +0000201 HIWORD( type )? 0 : LOWORD( type ) );
202 }
203 }
204 else
205 {
206 /* 32-bit PE module */
207 LPWSTR typeStr, nameStr;
Vincent Béron9a624912002-05-31 23:06:46 +0000208
Alexandre Julliard32936f02000-08-07 23:50:00 +0000209 if ( HIWORD( type ) && !bUnicode )
Matthew Davison60009b92003-01-23 23:07:38 +0000210 {
211 UNICODE_STRING usBuffer;
212 RtlCreateUnicodeStringFromAsciiz(&usBuffer,type);
213 typeStr = usBuffer.Buffer;
214 }
Alexandre Julliard32936f02000-08-07 23:50:00 +0000215 else
216 typeStr = (LPWSTR)type;
217 if ( HIWORD( name ) && !bUnicode )
Matthew Davison60009b92003-01-23 23:07:38 +0000218 {
219 UNICODE_STRING usBuffer;
220 RtlCreateUnicodeStringFromAsciiz(&usBuffer,name);
221 nameStr = usBuffer.Buffer;
222 }
Alexandre Julliard32936f02000-08-07 23:50:00 +0000223 else
224 nameStr = (LPWSTR)name;
225
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000226 /* Here is the real difference between FindResouce and FindResourceEx */
227 if(lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) ||
228 lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) ||
229 lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT) ||
230 lang == MAKELANGID(LANG_NEUTRAL, 3)) /* FIXME: real name? */
231 hRsrc = PE_FindResourceW( hModule, nameStr, typeStr );
232 else
233 hRsrc = PE_FindResourceExW( hModule, nameStr, typeStr, lang );
Vincent Béron9a624912002-05-31 23:06:46 +0000234
235 if ( HIWORD( type ) && !bUnicode )
Alexandre Julliard32936f02000-08-07 23:50:00 +0000236 HeapFree( GetProcessHeap(), 0, typeStr );
Vincent Béron9a624912002-05-31 23:06:46 +0000237 if ( HIWORD( name ) && !bUnicode )
Alexandre Julliard32936f02000-08-07 23:50:00 +0000238 HeapFree( GetProcessHeap(), 0, nameStr );
Richard Cohenc775e1e2000-04-16 20:27:51 +0000239 }
240 return hRsrc;
241}
242
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000243/**********************************************************************
Ulrich Weigand05112821999-03-10 14:02:06 +0000244 * RES_FindResource
245 */
Richard Cohenc775e1e2000-04-16 20:27:51 +0000246
Ulrich Weigand05112821999-03-10 14:02:06 +0000247static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
Vincent Béron9a624912002-05-31 23:06:46 +0000248 LPCSTR name, WORD lang,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000249 BOOL bUnicode, BOOL bRet16 )
Ulrich Weigand05112821999-03-10 14:02:06 +0000250{
Richard Cohenc775e1e2000-04-16 20:27:51 +0000251 HRSRC hRsrc;
252 __TRY
Ulrich Weigand05112821999-03-10 14:02:06 +0000253 {
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000254 hRsrc = RES_FindResource2(hModule, type, name, lang, bUnicode, bRet16);
Ulrich Weigand05112821999-03-10 14:02:06 +0000255 }
Richard Cohenc775e1e2000-04-16 20:27:51 +0000256 __EXCEPT(page_fault)
Ulrich Weigand05112821999-03-10 14:02:06 +0000257 {
Richard Cohenc775e1e2000-04-16 20:27:51 +0000258 WARN("page fault\n");
259 SetLastError(ERROR_INVALID_PARAMETER);
260 return 0;
Ulrich Weigand05112821999-03-10 14:02:06 +0000261 }
Richard Cohenc775e1e2000-04-16 20:27:51 +0000262 __ENDTRY
Ulrich Weigand05112821999-03-10 14:02:06 +0000263 return hRsrc;
264}
265
266/**********************************************************************
267 * RES_SizeofResource
268 */
269static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
270{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000271 if (!hRsrc) return 0;
Ulrich Weigand05112821999-03-10 14:02:06 +0000272
Andrew John Hughesed800c62002-11-21 03:45:01 +0000273 TRACE("(%p, %p, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" );
Ulrich Weigand05112821999-03-10 14:02:06 +0000274
Alexandre Julliard32936f02000-08-07 23:50:00 +0000275 if (!HIWORD(hModule))
Ulrich Weigand05112821999-03-10 14:02:06 +0000276 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000277 HMODULE16 hMod16 = MapHModuleLS( hModule );
278 NE_MODULE *pModule = NE_GetPtr( hMod16 );
279 if (!pModule) return 0;
280
281 if (!pModule->module32) /* 16-bit NE module */
282 {
283 /* If we got a 32-bit hRsrc, we don't need to convert it */
284 return NE_SizeofResource( pModule, hRsrc );
285 }
Ulrich Weigand05112821999-03-10 14:02:06 +0000286
287 /* If we got a 16-bit hRsrc, convert it */
Alexandre Julliard32936f02000-08-07 23:50:00 +0000288 if (!HIWORD(hRsrc)) hRsrc = MapHRsrc16To32( pModule, hRsrc );
Ulrich Weigand05112821999-03-10 14:02:06 +0000289 }
290
Alexandre Julliard32936f02000-08-07 23:50:00 +0000291 /* 32-bit PE module */
292 return PE_SizeofResource( hRsrc );
Ulrich Weigand05112821999-03-10 14:02:06 +0000293}
294
295/**********************************************************************
296 * RES_LoadResource
297 */
298static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
299{
300 HGLOBAL hMem = 0;
301
Andrew John Hughesed800c62002-11-21 03:45:01 +0000302 TRACE("(%p, %p, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" );
Ulrich Weigand05112821999-03-10 14:02:06 +0000303
Alexandre Julliard32936f02000-08-07 23:50:00 +0000304 if (!hRsrc) return 0;
Ulrich Weigand05112821999-03-10 14:02:06 +0000305
Alexandre Julliard32936f02000-08-07 23:50:00 +0000306 if (!HIWORD(hModule))
Ulrich Weigand05112821999-03-10 14:02:06 +0000307 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000308 HMODULE16 hMod16 = MapHModuleLS( hModule );
309 NE_MODULE *pModule = NE_GetPtr( hMod16 );
310 if (!pModule) return 0;
311 if (!pModule->module32)
Ulrich Weigand05112821999-03-10 14:02:06 +0000312 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000313 /* 16-bit NE module */
Ulrich Weigand05112821999-03-10 14:02:06 +0000314
Alexandre Julliard32936f02000-08-07 23:50:00 +0000315 /* If we got a 32-bit hRsrc, we don't need to convert it */
Andrew John Hughesed800c62002-11-21 03:45:01 +0000316 hMem = HGLOBAL_32(NE_LoadResource( pModule, LOWORD(hRsrc) ));
Alexandre Julliard32936f02000-08-07 23:50:00 +0000317
318 /* If we are to return a 32-bit resource, we should probably
319 convert it but we don't for now. FIXME !!! */
320 return hMem;
321 }
322 else
323 {
324 /* If we got a 16-bit hRsrc, convert it */
325 HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
326
327 hMem = PE_LoadResource( pModule->module32, hRsrc32 );
328
329 /* If we need to return a 16-bit resource, convert it */
330 if ( bRet16 )
331 {
332 WORD type = MapHRsrc16ToType( pModule, hRsrc );
333 DWORD size = SizeofResource( hModule, hRsrc );
334 LPVOID bits = LockResource( hMem );
335
Andrew John Hughesed800c62002-11-21 03:45:01 +0000336 hMem = HGLOBAL_32(NE_LoadPEResource( pModule, type, bits, size ));
Alexandre Julliard32936f02000-08-07 23:50:00 +0000337 }
Ulrich Weigand05112821999-03-10 14:02:06 +0000338 }
339 }
340 else
341 {
Alexandre Julliard32936f02000-08-07 23:50:00 +0000342 /* 32-bit PE module */
343 hMem = PE_LoadResource( hModule, hRsrc );
Ulrich Weigand05112821999-03-10 14:02:06 +0000344 }
345
346 return hMem;
347}
348
349/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000350 * FindResource (KERNEL.60)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000351 */
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000352HRSRC16 WINAPI FindResource16( HMODULE16 hModule, LPCSTR name, LPCSTR type )
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000353{
Andrew John Hughesed800c62002-11-21 03:45:01 +0000354 return LOWORD( RES_FindResource( HMODULE_32(hModule), type, name,
Alexandre Julliard267ca682002-07-31 17:20:00 +0000355 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, TRUE ) );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000356}
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000357
Alexandre Julliard594997c1995-04-30 10:05:20 +0000358/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000359 * FindResourceA (KERNEL32.@)
Alexandre Julliard594997c1995-04-30 10:05:20 +0000360 */
François Gouget55146db2000-12-24 20:33:01 +0000361HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000362{
Vincent Béron9a624912002-05-31 23:06:46 +0000363 return RES_FindResource( hModule, type, name,
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000364 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE );
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000365}
366
367/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000368 * FindResourceExA (KERNEL32.@)
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000369 */
Vincent Béron9a624912002-05-31 23:06:46 +0000370HRSRC WINAPI FindResourceExA( HMODULE hModule,
Ulrich Weigand05112821999-03-10 14:02:06 +0000371 LPCSTR type, LPCSTR name, WORD lang )
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +0000372{
Vincent Béron9a624912002-05-31 23:06:46 +0000373 return RES_FindResource( hModule, type, name,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000374 lang, FALSE, FALSE );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000375}
376
Ulrich Weigand05112821999-03-10 14:02:06 +0000377/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000378 * FindResourceExW (KERNEL32.@)
Ulrich Weigand05112821999-03-10 14:02:06 +0000379 */
Vincent Béron9a624912002-05-31 23:06:46 +0000380HRSRC WINAPI FindResourceExW( HMODULE hModule,
Ulrich Weigand05112821999-03-10 14:02:06 +0000381 LPCWSTR type, LPCWSTR name, WORD lang )
382{
Vincent Béron9a624912002-05-31 23:06:46 +0000383 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
Alexandre Julliardfd8a6de2000-07-31 20:59:59 +0000384 lang, TRUE, FALSE );
Ulrich Weigand05112821999-03-10 14:02:06 +0000385}
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000386
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000387/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000388 * FindResourceW (KERNEL32.@)
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000389 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000390HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000391{
Vincent Béron9a624912002-05-31 23:06:46 +0000392 return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
Dmitry Timoshkov05c88fa2000-08-11 12:50:56 +0000393 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE );
Alexandre Julliard8cc3a5e1996-08-11 15:49:51 +0000394}
395
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000396/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000397 * LoadResource (KERNEL.61)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000398 */
399HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
400{
Andrew John Hughesed800c62002-11-21 03:45:01 +0000401 return HGLOBAL_16(RES_LoadResource( HMODULE_32(hModule), HRSRC_32(hRsrc), TRUE ));
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000402}
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000403
404/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000405 * LoadResource (KERNEL32.@)
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000406 */
Ulrich Weigand05112821999-03-10 14:02:06 +0000407HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000408{
Ulrich Weigand05112821999-03-10 14:02:06 +0000409 return RES_LoadResource( hModule, hRsrc, FALSE );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000410}
411
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000412/**********************************************************************
Patrik Stridvall01d5e5b2001-07-02 19:59:40 +0000413 * LockResource (KERNEL.62)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000414 */
415SEGPTR WINAPI WIN16_LockResource16( HGLOBAL16 handle )
416{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000417 TRACE("(%04x)\n", handle );
418 /* May need to reload the resource if discarded */
Alexandre Julliard58017232000-12-22 01:09:26 +0000419 return K32WOWGlobalLock16( handle );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000420}
Patrik Stridvall697bf652000-12-02 23:44:59 +0000421
422/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000423 * LockResource16 (KERNEL32.@)
Patrik Stridvall697bf652000-12-02 23:44:59 +0000424 */
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000425LPVOID WINAPI LockResource16( HGLOBAL16 handle )
426{
Alexandre Julliard982a2232000-12-13 20:20:09 +0000427 return MapSL( WIN16_LockResource16(handle) );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000428}
Alexandre Julliard594997c1995-04-30 10:05:20 +0000429
Alexandre Julliardaca05781994-10-17 18:12:41 +0000430/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000431 * LockResource (KERNEL32.@)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000432 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000433LPVOID WINAPI LockResource( HGLOBAL handle )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000434{
Andrew John Hughesed800c62002-11-21 03:45:01 +0000435 TRACE("(%p)\n", handle );
Alexandre Julliard32936f02000-08-07 23:50:00 +0000436
437 if (HIWORD( handle )) /* 32-bit memory handle */
438 return (LPVOID)handle;
439
440 /* 16-bit memory handle */
Alexandre Julliard267ca682002-07-31 17:20:00 +0000441 return LockResource16( LOWORD(handle) );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000442}
443
Patrik Stridvall57e57842002-02-02 18:42:11 +0000444typedef WORD (WINAPI *pDestroyIcon32Proc)( HGLOBAL16 handle, UINT16 flags );
Alexandre Julliard8eeed942001-12-17 21:40:56 +0000445
446
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000447/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000448 * FreeResource (KERNEL.63)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000449 */
450BOOL16 WINAPI FreeResource16( HGLOBAL16 handle )
451{
Alexandre Julliard267ca682002-07-31 17:20:00 +0000452 HGLOBAL16 retv = handle;
Alexandre Julliard32936f02000-08-07 23:50:00 +0000453 NE_MODULE *pModule = NE_GetPtr( FarGetOwner16( handle ) );
454
455 TRACE("(%04x)\n", handle );
456
457 /* Try NE resource first */
458 retv = NE_FreeResource( pModule, handle );
459
460 /* If this failed, call USER.DestroyIcon32; this will check
461 whether it is a shared cursor/icon; if not it will call
462 GlobalFree16() */
463 if ( retv )
464 {
Alexandre Julliard8eeed942001-12-17 21:40:56 +0000465 pDestroyIcon32Proc proc;
466 HMODULE user = GetModuleHandleA( "user32.dll" );
467
468 if (user && (proc = (pDestroyIcon32Proc)GetProcAddress( user, "DestroyIcon32" )))
469 retv = proc( handle, CID_RESOURCE );
Alexandre Julliard32936f02000-08-07 23:50:00 +0000470 else
471 retv = GlobalFree16( handle );
472 }
473 return (BOOL)retv;
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000474}
475
476/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000477 * FreeResource (KERNEL32.@)
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000478 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000479BOOL WINAPI FreeResource( HGLOBAL handle )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000480{
Alexandre Julliard32936f02000-08-07 23:50:00 +0000481 if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000482
Alexandre Julliard267ca682002-07-31 17:20:00 +0000483 return FreeResource16( LOWORD(handle) );
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000484}
485
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000486/**********************************************************************
Patrik Stridvall044855c2001-07-11 18:56:41 +0000487 * SizeofResource (KERNEL.65)
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000488 */
489DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
490{
Andrew John Hughesed800c62002-11-21 03:45:01 +0000491 return RES_SizeofResource( HMODULE_32(hModule), HRSRC_32(hRsrc), TRUE );
Ulrich Weigand80a69b61998-11-25 17:58:51 +0000492}
493
494/**********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000495 * SizeofResource (KERNEL32.@)
Alexandre Julliard594997c1995-04-30 10:05:20 +0000496 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000497DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
Alexandre Julliard18f92e71996-07-17 20:02:21 +0000498{
Ulrich Weigand05112821999-03-10 14:02:06 +0000499 return RES_SizeofResource( hModule, hRsrc, FALSE );
Alexandre Julliarda2f2e011995-06-06 16:40:35 +0000500}