msi/tests: Delete the temp .msi file in all failure cases.
[wine.git] / dlls / user32 / resource.c
blobb050e1eba8cc3828122fb4e21ec8864db75f55b6
1 /*
2 * USER resource functions
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995, 2009 Alexandre Julliard
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winnls.h"
27 #include "ntuser.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(resource);
31 WINE_DECLARE_DEBUG_CHANNEL(accel);
33 /* this is the 8 byte accel struct used in Win32 resources (internal only) */
34 typedef struct
36 WORD fVirt;
37 WORD key;
38 WORD cmd;
39 WORD pad;
40 } PE_ACCEL;
42 /**********************************************************************
43 * LoadAcceleratorsW (USER32.@)
45 HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance, LPCWSTR name)
47 const PE_ACCEL *pe_table;
48 ACCEL *table;
49 unsigned int i;
50 HRSRC rsrc;
51 HACCEL handle;
52 DWORD count;
54 if (!(rsrc = FindResourceW( instance, name, (LPWSTR)RT_ACCELERATOR ))) return 0;
55 pe_table = LoadResource( instance, rsrc );
56 count = SizeofResource( instance, rsrc ) / sizeof(*pe_table);
57 if (!count) return 0;
58 table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
59 if (!table) return 0;
60 for (i = 0; i < count; i++)
62 table[i].fVirt = pe_table[i].fVirt;
63 table[i].key = pe_table[i].key;
64 table[i].cmd = pe_table[i].cmd;
66 handle = NtUserCreateAcceleratorTable( table, count );
67 HeapFree( GetProcessHeap(), 0, table );
68 TRACE_(accel)("%p %s returning %p\n", instance, debugstr_w(name), handle );
69 return handle;
72 /***********************************************************************
73 * LoadAcceleratorsA (USER32.@)
75 HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
77 INT len;
78 LPWSTR uni;
79 HACCEL result = 0;
81 if (IS_INTRESOURCE(lpTableName)) return LoadAcceleratorsW( instance, (LPCWSTR)lpTableName );
83 len = MultiByteToWideChar( CP_ACP, 0, lpTableName, -1, NULL, 0 );
84 if ((uni = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
86 MultiByteToWideChar( CP_ACP, 0, lpTableName, -1, uni, len );
87 result = LoadAcceleratorsW(instance,uni);
88 HeapFree( GetProcessHeap(), 0, uni);
90 return result;
93 /**********************************************************************
94 * CopyAcceleratorTableA (USER32.@)
96 INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT count)
98 char ch;
99 int i, ret = NtUserCopyAcceleratorTable( src, dst, count );
101 if (ret && dst)
103 for (i = 0; i < ret; i++)
105 if (dst[i].fVirt & FVIRTKEY) continue;
106 WideCharToMultiByte( CP_ACP, 0, &dst[i].key, 1, &ch, 1, NULL, NULL );
107 dst[i].key = ch;
110 return ret;
113 /*********************************************************************
114 * CreateAcceleratorTableA (USER32.@)
116 HACCEL WINAPI CreateAcceleratorTableA( ACCEL *accel, INT count )
118 HACCEL handle;
119 ACCEL *table;
120 int i;
122 if (count < 1)
124 SetLastError( ERROR_INVALID_PARAMETER );
125 return 0;
127 table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
128 if (!table) return 0;
129 for (i = 0; i < count; i++)
131 table[i].fVirt = accel[i].fVirt;
132 table[i].cmd = accel[i].cmd;
133 if (!(accel[i].fVirt & FVIRTKEY))
135 char ch = accel[i].key;
136 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &table[i].key, 1 );
138 else table[i].key = accel[i].key;
140 handle = NtUserCreateAcceleratorTable( table, count );
141 HeapFree( GetProcessHeap(), 0, table );
142 TRACE_(accel)("returning %p\n", handle );
143 return handle;
146 /**********************************************************************
147 * LoadStringW (USER32.@)
149 INT WINAPI DECLSPEC_HOTPATCH LoadStringW( HINSTANCE instance, UINT resource_id,
150 LPWSTR buffer, INT buflen )
152 HGLOBAL hmem;
153 HRSRC hrsrc;
154 WCHAR *p;
155 int string_num;
156 int i;
158 TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
159 instance, resource_id, buffer, buflen);
161 if(buffer == NULL)
162 return 0;
164 if (!(hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1), (LPWSTR)RT_STRING )) ||
165 !(hmem = LoadResource( instance, hrsrc )))
167 TRACE( "Failed to load string.\n" );
168 if (buflen > 0) buffer[0] = 0;
169 return 0;
172 p = LockResource(hmem);
173 string_num = resource_id & 0x000f;
174 for (i = 0; i < string_num; i++)
175 p += *p + 1;
177 TRACE("strlen = %d\n", (int)*p );
179 /*if buflen == 0, then return a read-only pointer to the resource itself in buffer
180 it is assumed that buffer is actually a (LPWSTR *) */
181 if(buflen == 0)
183 *((LPWSTR *)buffer) = p + 1;
184 return *p;
187 i = min(buflen - 1, *p);
188 memcpy(buffer, p + 1, i * sizeof(WCHAR));
189 buffer[i] = 0;
191 TRACE("returning %s\n", debugstr_w(buffer));
192 return i;
195 /**********************************************************************
196 * LoadStringA (USER32.@)
198 INT WINAPI DECLSPEC_HOTPATCH LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen )
200 HGLOBAL hmem;
201 HRSRC hrsrc;
202 DWORD retval = 0;
204 TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
205 instance, resource_id, buffer, buflen);
207 if (!buflen) return -1;
209 /* Use loword (incremented by 1) as resourceid */
210 if ((hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
211 (LPWSTR)RT_STRING )) &&
212 (hmem = LoadResource( instance, hrsrc )))
214 const WCHAR *p = LockResource(hmem);
215 unsigned int id = resource_id & 0x000f;
217 while (id--) p += *p + 1;
219 RtlUnicodeToMultiByteN( buffer, buflen - 1, &retval, p + 1, *p * sizeof(WCHAR) );
221 buffer[retval] = 0;
222 TRACE("returning %s\n", debugstr_a(buffer));
223 return retval;
226 /**********************************************************************
227 * GetGuiResources (USER32.@)
229 DWORD WINAPI GetGuiResources( HANDLE hProcess, DWORD uiFlags )
231 static BOOL warn = TRUE;
233 if (warn) {
234 FIXME("(%p,%lx): stub\n",hProcess,uiFlags);
235 warn = FALSE;
238 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
239 return 0;