Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 1 | /* |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 2 | * Resources |
| 3 | * |
| 4 | * Copyright 1993 Robert J. Amstadt |
| 5 | * Copyright 1995 Alexandre Julliard |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 6 | * |
| 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 Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 20 | */ |
| 21 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 22 | #include <assert.h> |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 23 | #include <stdlib.h> |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 24 | #include <string.h> |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 25 | #include <sys/types.h> |
| 26 | #include <sys/stat.h> |
| 27 | #include <fcntl.h> |
| 28 | #include <unistd.h> |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 29 | #include "windef.h" |
Alexandre Julliard | 58d5a0a | 2000-07-29 21:58:17 +0000 | [diff] [blame] | 30 | #include "winbase.h" |
Marcus Meissner | 04c3e1d | 1999-02-19 10:37:02 +0000 | [diff] [blame] | 31 | #include "wine/winbase16.h" |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 32 | #include "wine/exception.h" |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 33 | #include "heap.h" |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 34 | #include "cursoricon.h" |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 35 | #include "module.h" |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 36 | #include "file.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 37 | #include "wine/debug.h" |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 38 | #include "winerror.h" |
Joshua Thielen | a49bb26 | 1999-07-04 12:55:10 +0000 | [diff] [blame] | 39 | #include "winnls.h" |
Peter Hunnisett | 73ab649 | 2002-02-25 20:10:35 +0000 | [diff] [blame] | 40 | #include "msvcrt/excpt.h" |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 41 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 42 | WINE_DEFAULT_DEBUG_CHANNEL(resource); |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 43 | |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 44 | #define HRSRC_MAP_BLOCKSIZE 16 |
| 45 | |
| 46 | typedef struct _HRSRC_ELEM |
| 47 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 48 | HANDLE hRsrc; |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 49 | WORD type; |
| 50 | } HRSRC_ELEM; |
| 51 | |
| 52 | typedef struct _HRSRC_MAP |
| 53 | { |
| 54 | int nAlloc; |
| 55 | int nUsed; |
| 56 | HRSRC_ELEM *elem; |
| 57 | } HRSRC_MAP; |
| 58 | |
| 59 | /********************************************************************** |
| 60 | * MapHRsrc32To16 |
| 61 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 62 | static HRSRC16 MapHRsrc32To16( NE_MODULE *pModule, HANDLE hRsrc32, WORD type ) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 63 | { |
| 64 | HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; |
| 65 | HRSRC_ELEM *newElem; |
| 66 | int i; |
| 67 | |
| 68 | /* On first call, initialize HRSRC map */ |
| 69 | if ( !map ) |
| 70 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 71 | if ( !(map = (HRSRC_MAP *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 72 | sizeof(HRSRC_MAP) ) ) ) |
| 73 | { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 74 | ERR("Cannot allocate HRSRC map\n" ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 75 | return 0; |
| 76 | } |
| 77 | pModule->hRsrcMap = (LPVOID)map; |
| 78 | } |
| 79 | |
| 80 | /* Check whether HRSRC32 already in map */ |
| 81 | for ( i = 0; i < map->nUsed; i++ ) |
| 82 | if ( map->elem[i].hRsrc == hRsrc32 ) |
| 83 | return (HRSRC16)(i + 1); |
| 84 | |
| 85 | /* If no space left, grow table */ |
| 86 | if ( map->nUsed == map->nAlloc ) |
| 87 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 88 | if ( !(newElem = (HRSRC_ELEM *)HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, |
| 89 | map->elem, |
| 90 | (map->nAlloc + HRSRC_MAP_BLOCKSIZE) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 91 | * sizeof(HRSRC_ELEM) ) )) |
| 92 | { |
Dimitrie O. Paun | dd03cc1 | 1999-12-08 03:56:23 +0000 | [diff] [blame] | 93 | ERR("Cannot grow HRSRC map\n" ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 94 | return 0; |
| 95 | } |
| 96 | map->elem = newElem; |
| 97 | map->nAlloc += HRSRC_MAP_BLOCKSIZE; |
| 98 | } |
| 99 | |
| 100 | /* Add HRSRC32 to table */ |
| 101 | map->elem[map->nUsed].hRsrc = hRsrc32; |
| 102 | map->elem[map->nUsed].type = type; |
| 103 | map->nUsed++; |
| 104 | |
| 105 | return (HRSRC16)map->nUsed; |
| 106 | } |
| 107 | |
| 108 | /********************************************************************** |
| 109 | * MapHRsrc16To32 |
| 110 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 111 | static HANDLE MapHRsrc16To32( NE_MODULE *pModule, HRSRC16 hRsrc16 ) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 112 | { |
| 113 | HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; |
| 114 | if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0; |
| 115 | |
| 116 | return map->elem[(int)hRsrc16-1].hRsrc; |
| 117 | } |
| 118 | |
| 119 | /********************************************************************** |
| 120 | * MapHRsrc16ToType |
| 121 | */ |
| 122 | static WORD MapHRsrc16ToType( NE_MODULE *pModule, HRSRC16 hRsrc16 ) |
| 123 | { |
| 124 | HRSRC_MAP *map = (HRSRC_MAP *)pModule->hRsrcMap; |
| 125 | if ( !map || !hRsrc16 || (int)hRsrc16 > map->nUsed ) return 0; |
| 126 | |
| 127 | return map->elem[(int)hRsrc16-1].type; |
| 128 | } |
| 129 | |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 130 | |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 131 | /* filter for page-fault exceptions */ |
| 132 | static WINE_EXCEPTION_FILTER(page_fault) |
| 133 | { |
| 134 | if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) |
| 135 | return EXCEPTION_EXECUTE_HANDLER; |
| 136 | return EXCEPTION_CONTINUE_SEARCH; |
| 137 | } |
| 138 | |
| 139 | static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 140 | LPCSTR name, WORD lang, |
Alexandre Julliard | fd8a6de | 2000-07-31 20:59:59 +0000 | [diff] [blame] | 141 | BOOL bUnicode, BOOL bRet16 ) |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 142 | { |
| 143 | HRSRC hRsrc = 0; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 144 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 145 | TRACE("(%08x, %08x%s, %08x%s, %04x, %s, %s)\n", |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 146 | hModule, |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 147 | (UINT)type, HIWORD(type)? (bUnicode? debugstr_w((LPWSTR)type) : debugstr_a(type)) : "", |
| 148 | (UINT)name, HIWORD(name)? (bUnicode? debugstr_w((LPWSTR)name) : debugstr_a(name)) : "", |
| 149 | lang, |
| 150 | bUnicode? "W" : "A", |
Alexandre Julliard | fd8a6de | 2000-07-31 20:59:59 +0000 | [diff] [blame] | 151 | bRet16? "NE" : "PE" ); |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 152 | |
| 153 | if (!HIWORD(hModule)) |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 154 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 155 | HMODULE16 hMod16 = MapHModuleLS( hModule ); |
| 156 | NE_MODULE *pModule = NE_GetPtr( hMod16 ); |
| 157 | if (!pModule) return 0; |
| 158 | if (!pModule->module32) |
| 159 | { |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 160 | /* 16-bit NE module */ |
| 161 | LPSTR typeStr, nameStr; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 162 | |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 163 | if ( HIWORD( type ) && bUnicode ) |
| 164 | typeStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)type ); |
| 165 | else |
| 166 | typeStr = (LPSTR)type; |
| 167 | if ( HIWORD( name ) && bUnicode ) |
| 168 | nameStr = HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)name ); |
| 169 | else |
| 170 | nameStr = (LPSTR)name; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 171 | |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 172 | hRsrc = NE_FindResource( pModule, nameStr, typeStr ); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 173 | |
| 174 | if ( HIWORD( type ) && bUnicode ) |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 175 | HeapFree( GetProcessHeap(), 0, typeStr ); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 176 | if ( HIWORD( name ) && bUnicode ) |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 177 | HeapFree( GetProcessHeap(), 0, nameStr ); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 178 | |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 179 | /* If we need to return 32-bit HRSRC, no conversion is necessary, |
| 180 | we simply use the 16-bit HRSRC as 32-bit HRSRC */ |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 181 | } |
| 182 | else |
| 183 | { |
| 184 | /* 32-bit PE module */ |
| 185 | hRsrc = RES_FindResource2( pModule->module32, type, name, lang, bUnicode, FALSE ); |
| 186 | /* If we need to return 16-bit HRSRC, perform conversion */ |
| 187 | if ( bRet16 ) |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 188 | hRsrc = MapHRsrc32To16( pModule, hRsrc, |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 189 | HIWORD( type )? 0 : LOWORD( type ) ); |
| 190 | } |
| 191 | } |
| 192 | else |
| 193 | { |
| 194 | /* 32-bit PE module */ |
| 195 | LPWSTR typeStr, nameStr; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 196 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 197 | if ( HIWORD( type ) && !bUnicode ) |
| 198 | typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type ); |
| 199 | else |
| 200 | typeStr = (LPWSTR)type; |
| 201 | if ( HIWORD( name ) && !bUnicode ) |
| 202 | nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); |
| 203 | else |
| 204 | nameStr = (LPWSTR)name; |
| 205 | |
Dmitry Timoshkov | 05c88fa | 2000-08-11 12:50:56 +0000 | [diff] [blame] | 206 | /* Here is the real difference between FindResouce and FindResourceEx */ |
| 207 | if(lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) || |
| 208 | lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) || |
| 209 | lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT) || |
| 210 | lang == MAKELANGID(LANG_NEUTRAL, 3)) /* FIXME: real name? */ |
| 211 | hRsrc = PE_FindResourceW( hModule, nameStr, typeStr ); |
| 212 | else |
| 213 | hRsrc = PE_FindResourceExW( hModule, nameStr, typeStr, lang ); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 214 | |
| 215 | if ( HIWORD( type ) && !bUnicode ) |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 216 | HeapFree( GetProcessHeap(), 0, typeStr ); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 217 | if ( HIWORD( name ) && !bUnicode ) |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 218 | HeapFree( GetProcessHeap(), 0, nameStr ); |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 219 | } |
| 220 | return hRsrc; |
| 221 | } |
| 222 | |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 223 | /********************************************************************** |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 224 | * RES_FindResource |
| 225 | */ |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 226 | |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 227 | static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 228 | LPCSTR name, WORD lang, |
Alexandre Julliard | fd8a6de | 2000-07-31 20:59:59 +0000 | [diff] [blame] | 229 | BOOL bUnicode, BOOL bRet16 ) |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 230 | { |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 231 | HRSRC hRsrc; |
| 232 | __TRY |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 233 | { |
Alexandre Julliard | fd8a6de | 2000-07-31 20:59:59 +0000 | [diff] [blame] | 234 | hRsrc = RES_FindResource2(hModule, type, name, lang, bUnicode, bRet16); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 235 | } |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 236 | __EXCEPT(page_fault) |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 237 | { |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 238 | WARN("page fault\n"); |
| 239 | SetLastError(ERROR_INVALID_PARAMETER); |
| 240 | return 0; |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 241 | } |
Richard Cohen | c775e1e | 2000-04-16 20:27:51 +0000 | [diff] [blame] | 242 | __ENDTRY |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 243 | return hRsrc; |
| 244 | } |
| 245 | |
| 246 | /********************************************************************** |
| 247 | * RES_SizeofResource |
| 248 | */ |
| 249 | static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) |
| 250 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 251 | if (!hRsrc) return 0; |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 252 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 253 | TRACE("(%08x, %08x, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" ); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 254 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 255 | if (!HIWORD(hModule)) |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 256 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 257 | HMODULE16 hMod16 = MapHModuleLS( hModule ); |
| 258 | NE_MODULE *pModule = NE_GetPtr( hMod16 ); |
| 259 | if (!pModule) return 0; |
| 260 | |
| 261 | if (!pModule->module32) /* 16-bit NE module */ |
| 262 | { |
| 263 | /* If we got a 32-bit hRsrc, we don't need to convert it */ |
| 264 | return NE_SizeofResource( pModule, hRsrc ); |
| 265 | } |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 266 | |
| 267 | /* If we got a 16-bit hRsrc, convert it */ |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 268 | if (!HIWORD(hRsrc)) hRsrc = MapHRsrc16To32( pModule, hRsrc ); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 269 | } |
| 270 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 271 | /* 32-bit PE module */ |
| 272 | return PE_SizeofResource( hRsrc ); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 273 | } |
| 274 | |
| 275 | /********************************************************************** |
| 276 | * RES_LoadResource |
| 277 | */ |
| 278 | static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 ) |
| 279 | { |
| 280 | HGLOBAL hMem = 0; |
| 281 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 282 | TRACE("(%08x, %08x, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" ); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 283 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 284 | if (!hRsrc) return 0; |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 285 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 286 | if (!HIWORD(hModule)) |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 287 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 288 | HMODULE16 hMod16 = MapHModuleLS( hModule ); |
| 289 | NE_MODULE *pModule = NE_GetPtr( hMod16 ); |
| 290 | if (!pModule) return 0; |
| 291 | if (!pModule->module32) |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 292 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 293 | /* 16-bit NE module */ |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 294 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 295 | /* If we got a 32-bit hRsrc, we don't need to convert it */ |
| 296 | hMem = NE_LoadResource( pModule, hRsrc ); |
| 297 | |
| 298 | /* If we are to return a 32-bit resource, we should probably |
| 299 | convert it but we don't for now. FIXME !!! */ |
| 300 | return hMem; |
| 301 | } |
| 302 | else |
| 303 | { |
| 304 | /* If we got a 16-bit hRsrc, convert it */ |
| 305 | HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); |
| 306 | |
| 307 | hMem = PE_LoadResource( pModule->module32, hRsrc32 ); |
| 308 | |
| 309 | /* If we need to return a 16-bit resource, convert it */ |
| 310 | if ( bRet16 ) |
| 311 | { |
| 312 | WORD type = MapHRsrc16ToType( pModule, hRsrc ); |
| 313 | DWORD size = SizeofResource( hModule, hRsrc ); |
| 314 | LPVOID bits = LockResource( hMem ); |
| 315 | |
| 316 | hMem = NE_LoadPEResource( pModule, type, bits, size ); |
| 317 | } |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 318 | } |
| 319 | } |
| 320 | else |
| 321 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 322 | /* 32-bit PE module */ |
| 323 | hMem = PE_LoadResource( hModule, hRsrc ); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 324 | } |
| 325 | |
| 326 | return hMem; |
| 327 | } |
| 328 | |
| 329 | /********************************************************************** |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 330 | * FindResource (KERNEL.60) |
| 331 | * FindResource16 (KERNEL32.@) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 332 | */ |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 333 | HRSRC16 WINAPI FindResource16( HMODULE16 hModule, LPCSTR name, LPCSTR type ) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 334 | { |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 335 | return RES_FindResource( hModule, type, name, |
Dmitry Timoshkov | 05c88fa | 2000-08-11 12:50:56 +0000 | [diff] [blame] | 336 | MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, TRUE ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 337 | } |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 338 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 339 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 340 | * FindResourceA (KERNEL32.@) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 341 | */ |
François Gouget | 55146db | 2000-12-24 20:33:01 +0000 | [diff] [blame] | 342 | HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 343 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 344 | return RES_FindResource( hModule, type, name, |
Dmitry Timoshkov | 05c88fa | 2000-08-11 12:50:56 +0000 | [diff] [blame] | 345 | MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE ); |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 346 | } |
| 347 | |
| 348 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 349 | * FindResourceExA (KERNEL32.@) |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 350 | */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 351 | HRSRC WINAPI FindResourceExA( HMODULE hModule, |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 352 | LPCSTR type, LPCSTR name, WORD lang ) |
Ulrich Weigand | 7df1fbb | 1998-11-01 18:01:53 +0000 | [diff] [blame] | 353 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 354 | return RES_FindResource( hModule, type, name, |
Alexandre Julliard | fd8a6de | 2000-07-31 20:59:59 +0000 | [diff] [blame] | 355 | lang, FALSE, FALSE ); |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 356 | } |
| 357 | |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 358 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 359 | * FindResourceExW (KERNEL32.@) |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 360 | */ |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 361 | HRSRC WINAPI FindResourceExW( HMODULE hModule, |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 362 | LPCWSTR type, LPCWSTR name, WORD lang ) |
| 363 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 364 | return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, |
Alexandre Julliard | fd8a6de | 2000-07-31 20:59:59 +0000 | [diff] [blame] | 365 | lang, TRUE, FALSE ); |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 366 | } |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 367 | |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 368 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 369 | * FindResourceW (KERNEL32.@) |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 370 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 371 | HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type) |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 372 | { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 373 | return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, |
Dmitry Timoshkov | 05c88fa | 2000-08-11 12:50:56 +0000 | [diff] [blame] | 374 | MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE ); |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 375 | } |
| 376 | |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 377 | /********************************************************************** |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 378 | * LoadResource (KERNEL.61) |
| 379 | * LoadResource16 (KERNEL32.@) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 380 | */ |
| 381 | HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) |
| 382 | { |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 383 | return RES_LoadResource( hModule, hRsrc, TRUE ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 384 | } |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 385 | |
| 386 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 387 | * LoadResource (KERNEL32.@) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 388 | */ |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 389 | HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 390 | { |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 391 | return RES_LoadResource( hModule, hRsrc, FALSE ); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 392 | } |
| 393 | |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 394 | /********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 395 | * LockResource (KERNEL.62) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 396 | */ |
| 397 | SEGPTR WINAPI WIN16_LockResource16( HGLOBAL16 handle ) |
| 398 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 399 | TRACE("(%04x)\n", handle ); |
| 400 | /* May need to reload the resource if discarded */ |
Alexandre Julliard | 5801723 | 2000-12-22 01:09:26 +0000 | [diff] [blame] | 401 | return K32WOWGlobalLock16( handle ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 402 | } |
Patrik Stridvall | 697bf65 | 2000-12-02 23:44:59 +0000 | [diff] [blame] | 403 | |
| 404 | /********************************************************************** |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 405 | * LockResource16 (KERNEL32.@) |
Patrik Stridvall | 697bf65 | 2000-12-02 23:44:59 +0000 | [diff] [blame] | 406 | */ |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 407 | LPVOID WINAPI LockResource16( HGLOBAL16 handle ) |
| 408 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 409 | return MapSL( WIN16_LockResource16(handle) ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 410 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 411 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 412 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 413 | * LockResource (KERNEL32.@) |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 414 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 415 | LPVOID WINAPI LockResource( HGLOBAL handle ) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 416 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 417 | TRACE("(%08x)\n", handle ); |
| 418 | |
| 419 | if (HIWORD( handle )) /* 32-bit memory handle */ |
| 420 | return (LPVOID)handle; |
| 421 | |
| 422 | /* 16-bit memory handle */ |
| 423 | return LockResource16( handle ); |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 424 | } |
| 425 | |
Patrik Stridvall | 57e5784 | 2002-02-02 18:42:11 +0000 | [diff] [blame] | 426 | typedef WORD (WINAPI *pDestroyIcon32Proc)( HGLOBAL16 handle, UINT16 flags ); |
Alexandre Julliard | 8eeed94 | 2001-12-17 21:40:56 +0000 | [diff] [blame] | 427 | |
| 428 | |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 429 | /********************************************************************** |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 430 | * FreeResource (KERNEL.63) |
| 431 | * FreeResource16 (KERNEL32.@) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 432 | */ |
| 433 | BOOL16 WINAPI FreeResource16( HGLOBAL16 handle ) |
| 434 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 435 | HGLOBAL retv = handle; |
| 436 | NE_MODULE *pModule = NE_GetPtr( FarGetOwner16( handle ) ); |
| 437 | |
| 438 | TRACE("(%04x)\n", handle ); |
| 439 | |
| 440 | /* Try NE resource first */ |
| 441 | retv = NE_FreeResource( pModule, handle ); |
| 442 | |
| 443 | /* If this failed, call USER.DestroyIcon32; this will check |
| 444 | whether it is a shared cursor/icon; if not it will call |
| 445 | GlobalFree16() */ |
| 446 | if ( retv ) |
| 447 | { |
Alexandre Julliard | 8eeed94 | 2001-12-17 21:40:56 +0000 | [diff] [blame] | 448 | pDestroyIcon32Proc proc; |
| 449 | HMODULE user = GetModuleHandleA( "user32.dll" ); |
| 450 | |
| 451 | if (user && (proc = (pDestroyIcon32Proc)GetProcAddress( user, "DestroyIcon32" ))) |
| 452 | retv = proc( handle, CID_RESOURCE ); |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 453 | else |
| 454 | retv = GlobalFree16( handle ); |
| 455 | } |
| 456 | return (BOOL)retv; |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 457 | } |
| 458 | |
| 459 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 460 | * FreeResource (KERNEL32.@) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 461 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 462 | BOOL WINAPI FreeResource( HGLOBAL handle ) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 463 | { |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 464 | if (HIWORD(handle)) return 0; /* 32-bit memory handle: nothing to do */ |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 465 | |
Alexandre Julliard | 32936f0 | 2000-08-07 23:50:00 +0000 | [diff] [blame] | 466 | return FreeResource16( handle ); |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 467 | } |
| 468 | |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 469 | /********************************************************************** |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 470 | * SizeofResource (KERNEL.65) |
| 471 | * SizeofResource16 (KERNEL32.@) |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 472 | */ |
| 473 | DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) |
| 474 | { |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 475 | return RES_SizeofResource( hModule, hRsrc, TRUE ); |
Ulrich Weigand | 80a69b6 | 1998-11-25 17:58:51 +0000 | [diff] [blame] | 476 | } |
| 477 | |
| 478 | /********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 479 | * SizeofResource (KERNEL32.@) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 480 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 481 | DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 482 | { |
Ulrich Weigand | 0511282 | 1999-03-10 14:02:06 +0000 | [diff] [blame] | 483 | return RES_SizeofResource( hModule, hRsrc, FALSE ); |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 484 | } |