msi: Implement MsiSourceListGetInfoA.
[wine/dibdrv.git] / dlls / msi / source.c
blob49b7e4e642b05d15f37d55adf8a244e939b2d262
1 /*
2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2005 Aric Stewart for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winnls.h"
30 #include "shlwapi.h"
31 #include "wine/debug.h"
32 #include "msi.h"
33 #include "msiquery.h"
34 #include "msipriv.h"
35 #include "wincrypt.h"
36 #include "winver.h"
37 #include "winuser.h"
38 #include "wine/unicode.h"
39 #include "sddl.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 * These apis are defined in MSI 3.0
47 typedef struct tagMediaInfo
49 LPWSTR path;
50 WCHAR szIndex[10];
51 WCHAR type;
52 } media_info;
54 static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, BOOL user, BOOL create)
56 HKEY rootkey = 0;
57 UINT rc;
58 static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};
60 if (user)
61 rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
62 else
63 rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);
65 if (rc)
66 return rc;
68 if (create)
69 rc = RegCreateKeyW(rootkey, szSourceList, key);
70 else
71 rc = RegOpenKeyW(rootkey,szSourceList, key);
73 return rc;
76 static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
78 UINT rc;
79 static const WCHAR media[] = {'M','e','d','i','a',0};
81 if (create)
82 rc = RegCreateKeyW(rootkey, media, key);
83 else
84 rc = RegOpenKeyW(rootkey,media, key);
86 return rc;
89 static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
91 UINT rc;
92 static const WCHAR net[] = {'N','e','t',0};
94 if (create)
95 rc = RegCreateKeyW(rootkey, net, key);
96 else
97 rc = RegOpenKeyW(rootkey, net, key);
99 return rc;
102 static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
104 UINT rc;
105 static const WCHAR URL[] = {'U','R','L',0};
107 if (create)
108 rc = RegCreateKeyW(rootkey, URL, key);
109 else
110 rc = RegOpenKeyW(rootkey, URL, key);
112 return rc;
116 static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss)
118 DWORD index = 0;
119 WCHAR szIndex[10];
120 DWORD size;
121 DWORD val_size;
122 LPWSTR val;
123 UINT rc = ERROR_SUCCESS;
125 while (rc == ERROR_SUCCESS)
127 val = NULL;
128 val_size = 0;
129 size = sizeof(szIndex)/sizeof(szIndex[0]);
130 rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
131 if (rc != ERROR_NO_MORE_ITEMS)
133 val = msi_alloc(val_size);
134 RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val,
135 &val_size);
136 if (lstrcmpiW(szSource,val)==0)
138 ss->path = val;
139 strcpyW(ss->szIndex,szIndex);
140 break;
142 else
143 strcpyW(ss->szIndex,szIndex);
145 msi_free(val);
146 index ++;
149 return rc;
152 /******************************************************************
153 * MsiSourceListGetInfoA (MSI.@)
155 UINT WINAPI MsiSourceListGetInfoA( LPCSTR szProduct, LPCSTR szUserSid,
156 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
157 LPCSTR szProperty, LPSTR szValue,
158 LPDWORD pcchValue)
160 UINT ret;
161 LPWSTR product = NULL;
162 LPWSTR usersid = NULL;
163 LPWSTR property = NULL;
164 LPWSTR value = NULL;
165 DWORD len = 0;
167 if (szValue && !pcchValue)
168 return ERROR_INVALID_PARAMETER;
170 if (szProduct) product = strdupAtoW(szProduct);
171 if (szUserSid) usersid = strdupAtoW(szUserSid);
172 if (szProperty) property = strdupAtoW(szProperty);
174 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions,
175 property, NULL, &len);
176 if (ret != ERROR_SUCCESS)
177 goto done;
179 value = msi_alloc(++len * sizeof(WCHAR));
180 if (!value)
181 return ERROR_OUTOFMEMORY;
183 ret = MsiSourceListGetInfoW(product, usersid, dwContext, dwOptions,
184 property, value, &len);
185 if (ret != ERROR_SUCCESS)
186 goto done;
188 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
189 if (*pcchValue >= len)
190 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
191 else if (szValue)
192 ret = ERROR_MORE_DATA;
194 *pcchValue = len - 1;
196 done:
197 msi_free(product);
198 msi_free(usersid);
199 msi_free(property);
200 msi_free(value);
201 return ret;
204 /******************************************************************
205 * MsiSourceListGetInfoW (MSI.@)
207 UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
208 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
209 LPCWSTR szProperty, LPWSTR szValue,
210 LPDWORD pcchValue)
212 HKEY sourcekey;
213 UINT rc;
215 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty));
217 if (!szProduct || lstrlenW(szProduct) > 39)
218 return ERROR_INVALID_PARAMETER;
220 if (szValue && !pcchValue)
221 return ERROR_INVALID_PARAMETER;
223 if (dwOptions == MSICODE_PATCH)
225 FIXME("Unhandled options MSICODE_PATCH\n");
226 return ERROR_FUNCTION_FAILED;
229 if (szUserSid)
230 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
232 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
233 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
235 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
236 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, FALSE);
237 else
238 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, FALSE);
240 if (rc != ERROR_SUCCESS)
241 return ERROR_UNKNOWN_PRODUCT;
243 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
245 HKEY key;
246 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
247 if (rc == ERROR_SUCCESS)
248 rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW,
249 0, 0, (LPBYTE)szValue, pcchValue);
250 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
251 rc = ERROR_UNKNOWN_PROPERTY;
252 RegCloseKey(key);
254 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) ==0)
256 HKEY key;
257 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
258 if (rc == ERROR_SUCCESS)
259 rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0, 0,
260 (LPBYTE)szValue, pcchValue);
261 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
262 rc = ERROR_UNKNOWN_PROPERTY;
263 RegCloseKey(key);
265 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
267 LPWSTR buffer;
268 DWORD size = 0;
270 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
271 NULL, &size);
272 if (size == 0)
273 rc = ERROR_UNKNOWN_PROPERTY;
274 else
276 LPWSTR ptr;
277 buffer = msi_alloc(size);
278 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
279 0, 0, (LPBYTE)buffer,&size);
280 ptr = strchrW(buffer,';');
281 if (ptr) ptr = strchrW(ptr+1,';');
282 if (!ptr)
283 rc = ERROR_UNKNOWN_PROPERTY;
284 else
286 ptr ++;
287 lstrcpynW(szValue, ptr, *pcchValue);
288 if (lstrlenW(ptr) > *pcchValue)
290 *pcchValue = lstrlenW(ptr)+1;
291 rc = ERROR_MORE_DATA;
293 else
294 rc = ERROR_SUCCESS;
296 msi_free(buffer);
299 else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
301 LPWSTR buffer;
302 DWORD size = 0;
304 RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
305 NULL, &size);
306 if (size == 0)
307 rc = ERROR_UNKNOWN_PROPERTY;
308 else
310 buffer = msi_alloc(size);
311 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
312 0, 0, (LPBYTE)buffer,&size);
313 if (*pcchValue < 1)
315 rc = ERROR_MORE_DATA;
316 *pcchValue = 1;
318 else
320 szValue[0] = buffer[0];
321 rc = ERROR_SUCCESS;
323 msi_free(buffer);
326 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
328 rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0,
329 (LPBYTE)szValue, pcchValue);
330 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
331 rc = ERROR_UNKNOWN_PROPERTY;
333 else
335 FIXME("Unknown property %s\n",debugstr_w(szProperty));
336 rc = ERROR_UNKNOWN_PROPERTY;
339 RegCloseKey(sourcekey);
340 return rc;
343 /******************************************************************
344 * MsiSourceListSetInfoW (MSI.@)
346 UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
347 MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
348 LPCWSTR szProperty, LPCWSTR szValue)
350 HKEY sourcekey;
351 UINT rc;
353 TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
354 dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));
356 if (!szProduct || lstrlenW(szProduct) > 39)
357 return ERROR_INVALID_PARAMETER;
359 if (dwOptions & MSICODE_PATCH)
361 FIXME("Unhandled options MSICODE_PATCH\n");
362 return ERROR_FUNCTION_FAILED;
365 if (szUserSid)
366 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
368 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
369 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
371 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
372 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
373 else
374 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
376 if (rc != ERROR_SUCCESS)
377 return ERROR_UNKNOWN_PRODUCT;
380 if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
382 HKEY key;
383 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
384 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
385 if (rc == ERROR_SUCCESS)
386 rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW, 0,
387 REG_SZ, (const BYTE *)szValue, size);
388 if (rc != ERROR_SUCCESS)
389 rc = ERROR_UNKNOWN_PROPERTY;
390 RegCloseKey(key);
392 else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) == 0)
394 HKEY key;
395 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
396 rc = OpenMediaSubkey(sourcekey, &key, FALSE);
397 if (rc == ERROR_SUCCESS)
398 rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0,
399 REG_SZ, (const BYTE *)szValue, size);
400 if (rc != ERROR_SUCCESS)
401 rc = ERROR_UNKNOWN_PROPERTY;
402 RegCloseKey(key);
404 else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
406 LPWSTR buffer = NULL;
407 DWORD size;
408 WCHAR typechar = 'n';
409 static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};
411 /* make sure the source is registered */
412 MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext,
413 dwOptions, szValue, 0);
415 if (dwOptions & MSISOURCETYPE_NETWORK)
416 typechar = 'n';
417 else if (dwOptions & MSISOURCETYPE_URL)
418 typechar = 'u';
419 else if (dwOptions & MSISOURCETYPE_MEDIA)
420 typechar = 'm';
421 else
422 ERR("Unknown source type! %x\n", dwOptions);
424 size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
425 buffer = msi_alloc(size);
426 sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
427 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
428 REG_EXPAND_SZ, (LPBYTE)buffer, size);
429 if (rc != ERROR_SUCCESS)
430 rc = ERROR_UNKNOWN_PROPERTY;
431 msi_free( buffer );
433 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
435 DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
436 rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
437 REG_SZ, (const BYTE *)szValue, size);
438 if (rc != ERROR_SUCCESS)
439 rc = ERROR_UNKNOWN_PROPERTY;
441 else
443 FIXME("Unknown property %s\n",debugstr_w(szProperty));
444 rc = ERROR_UNKNOWN_PROPERTY;
447 RegCloseKey(sourcekey);
448 return rc;
452 /******************************************************************
453 * MsiSourceListAddSourceW (MSI.@)
455 UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
456 DWORD dwReserved, LPCWSTR szSource)
458 INT ret;
459 LPWSTR sidstr = NULL;
460 DWORD sidsize = 0;
461 DWORD domsize = 0;
463 TRACE("%s %s %s\n", debugstr_w(szProduct), debugstr_w(szUserName), debugstr_w(szSource));
465 if (LookupAccountNameW(NULL, szUserName, NULL, &sidsize, NULL, &domsize, NULL))
467 PSID psid = msi_alloc(sidsize);
469 if (LookupAccountNameW(NULL, szUserName, psid, &sidsize, NULL, &domsize, NULL))
470 ConvertSidToStringSidW(psid, &sidstr);
472 msi_free(psid);
475 ret = MsiSourceListAddSourceExW(szProduct, sidstr,
476 MSIINSTALLCONTEXT_USERMANAGED, MSISOURCETYPE_NETWORK, szSource, 0);
478 if (sidstr)
479 LocalFree(sidstr);
481 return ret;
484 /******************************************************************
485 * MsiSourceListAddSourceA (MSI.@)
487 UINT WINAPI MsiSourceListAddSourceA( LPCSTR szProduct, LPCSTR szUserName,
488 DWORD dwReserved, LPCSTR szSource)
490 INT ret;
491 LPWSTR szwproduct;
492 LPWSTR szwusername;
493 LPWSTR szwsource;
495 szwproduct = strdupAtoW( szProduct );
496 szwusername = strdupAtoW( szUserName );
497 szwsource = strdupAtoW( szSource );
499 ret = MsiSourceListAddSourceW(szwproduct, szwusername, 0, szwsource);
501 msi_free(szwproduct);
502 msi_free(szwusername);
503 msi_free(szwsource);
505 return ret;
508 /******************************************************************
509 * MsiSourceListAddSourceExW (MSI.@)
511 UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
512 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
513 DWORD dwIndex)
515 HKEY sourcekey;
516 HKEY typekey;
517 UINT rc;
518 media_info source_struct;
520 TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct), debugstr_w(szUserSid),
521 dwContext, dwOptions, debugstr_w(szSource), dwIndex);
523 if (!szProduct)
524 return ERROR_INVALID_PARAMETER;
526 if (!szSource)
527 return ERROR_INVALID_PARAMETER;
529 if (dwOptions & MSICODE_PATCH)
531 FIXME("Unhandled options MSICODE_PATCH\n");
532 return ERROR_FUNCTION_FAILED;
535 if (szUserSid)
536 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
538 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
539 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
541 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
542 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
543 else
544 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
546 if (rc != ERROR_SUCCESS)
547 return ERROR_UNKNOWN_PRODUCT;
549 if (dwOptions & MSISOURCETYPE_NETWORK)
550 rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
551 else if (dwOptions & MSISOURCETYPE_URL)
552 rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
553 else if (dwOptions & MSISOURCETYPE_MEDIA)
554 rc = OpenMediaSubkey(sourcekey, &typekey, TRUE);
555 else
557 ERR("unknown media type: %08x\n", dwOptions);
558 RegCloseKey(sourcekey);
559 return ERROR_FUNCTION_FAILED;
562 source_struct.szIndex[0] = 0;
563 if (find_given_source(typekey, szSource, &source_struct)==ERROR_SUCCESS)
565 DWORD current_index = atoiW(source_struct.szIndex);
566 /* found the source */
567 if (dwIndex > 0 && current_index != dwIndex)
568 FIXME("Need to reorder the sources!\n");
569 msi_free( source_struct.path );
571 else
573 DWORD current_index = 0;
574 static const WCHAR fmt[] = {'%','i',0};
575 DWORD size = lstrlenW(szSource)*sizeof(WCHAR);
577 if (source_struct.szIndex[0])
578 current_index = atoiW(source_struct.szIndex);
579 /* new source */
580 if (dwIndex > 0 && dwIndex < current_index)
581 FIXME("Need to reorder the sources!\n");
583 current_index ++;
584 sprintfW(source_struct.szIndex,fmt,current_index);
585 rc = RegSetValueExW(typekey, source_struct.szIndex, 0, REG_EXPAND_SZ,
586 (const BYTE *)szSource, size);
589 RegCloseKey(typekey);
590 RegCloseKey(sourcekey);
591 return rc;
594 /******************************************************************
595 * MsiSourceListAddMediaDisk(MSI.@)
597 UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
598 MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
599 LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
601 HKEY sourcekey;
602 HKEY mediakey;
603 UINT rc;
604 WCHAR szIndex[10];
605 static const WCHAR fmt[] = {'%','i',0};
606 static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
607 static const WCHAR empty[1] = {0};
608 LPCWSTR pt1,pt2;
609 LPWSTR buffer;
610 DWORD size;
612 TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct),
613 debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
614 debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));
616 if (!szProduct || lstrlenW(szProduct) > 39)
617 return ERROR_INVALID_PARAMETER;
619 if (dwOptions & MSICODE_PATCH)
621 FIXME("Unhandled options MSICODE_PATCH\n");
622 return ERROR_FUNCTION_FAILED;
625 if (szUserSid)
626 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
628 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
629 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
631 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
632 rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
633 else
634 rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
636 if (rc != ERROR_SUCCESS)
637 return ERROR_UNKNOWN_PRODUCT;
639 OpenMediaSubkey(sourcekey,&mediakey,TRUE);
641 sprintfW(szIndex,fmt,dwDiskId);
643 size = 2;
644 if (szVolumeLabel)
646 size +=lstrlenW(szVolumeLabel);
647 pt1 = szVolumeLabel;
649 else
650 pt1 = empty;
651 if (szDiskPrompt)
653 size +=lstrlenW(szDiskPrompt);
654 pt2 = szDiskPrompt;
656 else
657 pt2 = empty;
659 size *=sizeof(WCHAR);
661 buffer = msi_alloc(size);
662 sprintfW(buffer,disk_fmt,pt1,pt2);
664 RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
665 msi_free( buffer );
667 RegCloseKey(sourcekey);
668 RegCloseKey(mediakey);
670 return ERROR_SUCCESS;
673 /******************************************************************
674 * MsiSourceListAddSourceExA (MSI.@)
676 UINT WINAPI MsiSourceListClearAllA( LPCSTR szProduct, LPCSTR szUserName, DWORD dwReserved )
678 FIXME("(%s %s %d)\n", debugstr_a(szProduct), debugstr_a(szUserName), dwReserved);
679 return ERROR_SUCCESS;
682 /******************************************************************
683 * MsiSourceListAddSourceExW (MSI.@)
685 UINT WINAPI MsiSourceListClearAllW( LPCWSTR szProduct, LPCWSTR szUserName, DWORD dwReserved )
687 FIXME("(%s %s %d)\n", debugstr_w(szProduct), debugstr_w(szUserName), dwReserved);
688 return ERROR_SUCCESS;