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
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
38 #include "wine/unicode.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
44 * These apis are defined in MSI 3.0
47 typedef struct tagMediaInfo
54 static UINT
OpenSourceKey(LPCWSTR szProduct
, HKEY
* key
, DWORD dwOptions
, BOOL user
, BOOL create
)
58 static const WCHAR szSourceList
[] = {'S','o','u','r','c','e','L','i','s','t',0};
62 if (dwOptions
== MSICODE_PATCH
)
63 rc
= MSIREG_OpenUserPatchesKey(szProduct
, &rootkey
, create
);
65 rc
= MSIREG_OpenUserProductsKey(szProduct
, &rootkey
, create
);
69 if (dwOptions
== MSICODE_PATCH
)
70 rc
= MSIREG_OpenPatchesKey(szProduct
, &rootkey
, create
);
72 rc
= MSIREG_OpenProductsKey(szProduct
, &rootkey
, create
);
77 if (dwOptions
== MSICODE_PATCH
)
78 return ERROR_UNKNOWN_PATCH
;
80 return ERROR_UNKNOWN_PRODUCT
;
84 rc
= RegCreateKeyW(rootkey
, szSourceList
, key
);
87 rc
= RegOpenKeyW(rootkey
,szSourceList
, key
);
88 if (rc
!= ERROR_SUCCESS
)
89 rc
= ERROR_BAD_CONFIGURATION
;
95 static UINT
OpenMediaSubkey(HKEY rootkey
, HKEY
*key
, BOOL create
)
98 static const WCHAR media
[] = {'M','e','d','i','a',0};
101 rc
= RegCreateKeyW(rootkey
, media
, key
);
103 rc
= RegOpenKeyW(rootkey
,media
, key
);
108 static UINT
OpenNetworkSubkey(HKEY rootkey
, HKEY
*key
, BOOL create
)
111 static const WCHAR net
[] = {'N','e','t',0};
114 rc
= RegCreateKeyW(rootkey
, net
, key
);
116 rc
= RegOpenKeyW(rootkey
, net
, key
);
121 static UINT
OpenURLSubkey(HKEY rootkey
, HKEY
*key
, BOOL create
)
124 static const WCHAR URL
[] = {'U','R','L',0};
127 rc
= RegCreateKeyW(rootkey
, URL
, key
);
129 rc
= RegOpenKeyW(rootkey
, URL
, key
);
135 static UINT
find_given_source(HKEY key
, LPCWSTR szSource
, media_info
*ss
)
142 UINT rc
= ERROR_SUCCESS
;
144 while (rc
== ERROR_SUCCESS
)
148 size
= sizeof(szIndex
)/sizeof(szIndex
[0]);
149 rc
= RegEnumValueW(key
, index
, szIndex
, &size
, NULL
, NULL
, NULL
, &val_size
);
150 if (rc
!= ERROR_NO_MORE_ITEMS
)
152 val
= msi_alloc(val_size
);
153 RegEnumValueW(key
, index
, szIndex
, &size
, NULL
, NULL
, (LPBYTE
)val
,
155 if (lstrcmpiW(szSource
,val
)==0)
158 strcpyW(ss
->szIndex
,szIndex
);
162 strcpyW(ss
->szIndex
,szIndex
);
171 /******************************************************************
172 * MsiSourceListEnumSourcesA (MSI.@)
174 UINT WINAPI
MsiSourceListEnumSourcesA(LPCSTR szProductCodeOrPatch
, LPCSTR szUserSid
,
175 MSIINSTALLCONTEXT dwContext
,
176 DWORD dwOptions
, DWORD dwIndex
,
177 LPSTR szSource
, LPDWORD pcchSource
)
179 FIXME("(%s, %s, %d, %d, %d, %p, %p): stub!\n", szProductCodeOrPatch
, szUserSid
,
180 dwContext
, dwOptions
, dwIndex
, szSource
, pcchSource
);
181 return ERROR_CALL_NOT_IMPLEMENTED
;
184 /******************************************************************
185 * MsiSourceListGetInfoA (MSI.@)
187 UINT WINAPI
MsiSourceListGetInfoA( LPCSTR szProduct
, LPCSTR szUserSid
,
188 MSIINSTALLCONTEXT dwContext
, DWORD dwOptions
,
189 LPCSTR szProperty
, LPSTR szValue
,
193 LPWSTR product
= NULL
;
194 LPWSTR usersid
= NULL
;
195 LPWSTR property
= NULL
;
199 if (szValue
&& !pcchValue
)
200 return ERROR_INVALID_PARAMETER
;
202 if (szProduct
) product
= strdupAtoW(szProduct
);
203 if (szUserSid
) usersid
= strdupAtoW(szUserSid
);
204 if (szProperty
) property
= strdupAtoW(szProperty
);
206 ret
= MsiSourceListGetInfoW(product
, usersid
, dwContext
, dwOptions
,
207 property
, NULL
, &len
);
208 if (ret
!= ERROR_SUCCESS
)
211 value
= msi_alloc(++len
* sizeof(WCHAR
));
213 return ERROR_OUTOFMEMORY
;
216 ret
= MsiSourceListGetInfoW(product
, usersid
, dwContext
, dwOptions
,
217 property
, value
, &len
);
218 if (ret
!= ERROR_SUCCESS
)
221 len
= WideCharToMultiByte(CP_ACP
, 0, value
, -1, NULL
, 0, NULL
, NULL
);
222 if (*pcchValue
>= len
)
223 WideCharToMultiByte(CP_ACP
, 0, value
, -1, szValue
, len
, NULL
, NULL
);
225 ret
= ERROR_MORE_DATA
;
227 *pcchValue
= len
- 1;
237 /******************************************************************
238 * MsiSourceListGetInfoW (MSI.@)
240 UINT WINAPI
MsiSourceListGetInfoW( LPCWSTR szProduct
, LPCWSTR szUserSid
,
241 MSIINSTALLCONTEXT dwContext
, DWORD dwOptions
,
242 LPCWSTR szProperty
, LPWSTR szValue
,
248 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szProperty
));
250 if (!szProduct
|| !*szProduct
)
251 return ERROR_INVALID_PARAMETER
;
253 if (lstrlenW(szProduct
) != GUID_SIZE
- 1 ||
254 (szProduct
[0] != '{' && szProduct
[GUID_SIZE
- 2] != '}'))
255 return ERROR_INVALID_PARAMETER
;
257 if (szValue
&& !pcchValue
)
258 return ERROR_INVALID_PARAMETER
;
260 if (dwContext
!= MSIINSTALLCONTEXT_USERMANAGED
&&
261 dwContext
!= MSIINSTALLCONTEXT_USERUNMANAGED
&&
262 dwContext
!= MSIINSTALLCONTEXT_MACHINE
)
263 return ERROR_INVALID_PARAMETER
;
266 return ERROR_INVALID_PARAMETER
;
269 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid
));
271 if (dwContext
== MSIINSTALLCONTEXT_USERUNMANAGED
)
272 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
274 if (dwContext
== MSIINSTALLCONTEXT_MACHINE
)
275 rc
= OpenSourceKey(szProduct
, &sourcekey
, dwOptions
, FALSE
, FALSE
);
277 rc
= OpenSourceKey(szProduct
, &sourcekey
, dwOptions
, TRUE
, FALSE
);
279 if (rc
!= ERROR_SUCCESS
)
282 if (strcmpW(szProperty
, INSTALLPROPERTY_MEDIAPACKAGEPATHW
) == 0)
285 rc
= OpenMediaSubkey(sourcekey
, &key
, FALSE
);
286 if (rc
== ERROR_SUCCESS
)
287 rc
= RegQueryValueExW(key
, INSTALLPROPERTY_MEDIAPACKAGEPATHW
,
288 0, 0, (LPBYTE
)szValue
, pcchValue
);
289 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
)
290 rc
= ERROR_UNKNOWN_PROPERTY
;
293 else if (strcmpW(szProperty
, INSTALLPROPERTY_DISKPROMPTW
) ==0)
296 rc
= OpenMediaSubkey(sourcekey
, &key
, FALSE
);
297 if (rc
== ERROR_SUCCESS
)
298 rc
= RegQueryValueExW(key
, INSTALLPROPERTY_DISKPROMPTW
, 0, 0,
299 (LPBYTE
)szValue
, pcchValue
);
300 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
)
301 rc
= ERROR_UNKNOWN_PROPERTY
;
304 else if (strcmpW(szProperty
, INSTALLPROPERTY_LASTUSEDSOURCEW
)==0)
309 RegQueryValueExW(sourcekey
, INSTALLPROPERTY_LASTUSEDSOURCEW
, 0, 0,
312 rc
= ERROR_UNKNOWN_PROPERTY
;
316 buffer
= msi_alloc(size
);
317 rc
= RegQueryValueExW(sourcekey
, INSTALLPROPERTY_LASTUSEDSOURCEW
,
318 0, 0, (LPBYTE
)buffer
,&size
);
319 ptr
= strchrW(buffer
,';');
320 if (ptr
) ptr
= strchrW(ptr
+1,';');
322 rc
= ERROR_UNKNOWN_PROPERTY
;
326 lstrcpynW(szValue
, ptr
, *pcchValue
);
327 if (lstrlenW(ptr
) > *pcchValue
)
329 *pcchValue
= lstrlenW(ptr
)+1;
330 rc
= ERROR_MORE_DATA
;
338 else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW
, szProperty
)==0)
343 RegQueryValueExW(sourcekey
, INSTALLPROPERTY_LASTUSEDSOURCEW
, 0, 0,
346 rc
= ERROR_UNKNOWN_PROPERTY
;
349 buffer
= msi_alloc(size
);
350 rc
= RegQueryValueExW(sourcekey
, INSTALLPROPERTY_LASTUSEDSOURCEW
,
351 0, 0, (LPBYTE
)buffer
,&size
);
354 rc
= ERROR_MORE_DATA
;
359 szValue
[0] = buffer
[0];
365 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW
, szProperty
)==0)
367 *pcchValue
= *pcchValue
* sizeof(WCHAR
);
368 rc
= RegQueryValueExW(sourcekey
, INSTALLPROPERTY_PACKAGENAMEW
, 0, 0,
369 (LPBYTE
)szValue
, pcchValue
);
370 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
)
378 *pcchValue
= (*pcchValue
- 1) / sizeof(WCHAR
);
380 szValue
[*pcchValue
] = '\0';
385 FIXME("Unknown property %s\n",debugstr_w(szProperty
));
386 rc
= ERROR_UNKNOWN_PROPERTY
;
389 RegCloseKey(sourcekey
);
393 /******************************************************************
394 * MsiSourceListSetInfoW (MSI.@)
396 UINT WINAPI
MsiSourceListSetInfoW( LPCWSTR szProduct
, LPCWSTR szUserSid
,
397 MSIINSTALLCONTEXT dwContext
, DWORD dwOptions
,
398 LPCWSTR szProperty
, LPCWSTR szValue
)
403 TRACE("%s %s %x %x %s %s\n", debugstr_w(szProduct
), debugstr_w(szUserSid
),
404 dwContext
, dwOptions
, debugstr_w(szProperty
), debugstr_w(szValue
));
406 if (!szProduct
|| lstrlenW(szProduct
) > 39)
407 return ERROR_INVALID_PARAMETER
;
409 if (dwOptions
& MSICODE_PATCH
)
411 FIXME("Unhandled options MSICODE_PATCH\n");
412 return ERROR_FUNCTION_FAILED
;
416 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid
));
418 if (dwContext
== MSIINSTALLCONTEXT_USERUNMANAGED
)
419 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
421 if (dwContext
== MSIINSTALLCONTEXT_MACHINE
)
422 rc
= OpenSourceKey(szProduct
, &sourcekey
, MSICODE_PRODUCT
, FALSE
, TRUE
);
424 rc
= OpenSourceKey(szProduct
, &sourcekey
, MSICODE_PRODUCT
, TRUE
, TRUE
);
426 if (rc
!= ERROR_SUCCESS
)
427 return ERROR_UNKNOWN_PRODUCT
;
430 if (strcmpW(szProperty
, INSTALLPROPERTY_MEDIAPACKAGEPATHW
) == 0)
433 DWORD size
= lstrlenW(szValue
)*sizeof(WCHAR
);
434 rc
= OpenMediaSubkey(sourcekey
, &key
, FALSE
);
435 if (rc
== ERROR_SUCCESS
)
436 rc
= RegSetValueExW(key
, INSTALLPROPERTY_MEDIAPACKAGEPATHW
, 0,
437 REG_SZ
, (const BYTE
*)szValue
, size
);
438 if (rc
!= ERROR_SUCCESS
)
439 rc
= ERROR_UNKNOWN_PROPERTY
;
442 else if (strcmpW(szProperty
, INSTALLPROPERTY_DISKPROMPTW
) == 0)
445 DWORD size
= lstrlenW(szValue
)*sizeof(WCHAR
);
446 rc
= OpenMediaSubkey(sourcekey
, &key
, FALSE
);
447 if (rc
== ERROR_SUCCESS
)
448 rc
= RegSetValueExW(key
, INSTALLPROPERTY_DISKPROMPTW
, 0,
449 REG_SZ
, (const BYTE
*)szValue
, size
);
450 if (rc
!= ERROR_SUCCESS
)
451 rc
= ERROR_UNKNOWN_PROPERTY
;
454 else if (strcmpW(szProperty
, INSTALLPROPERTY_LASTUSEDSOURCEW
)==0)
456 LPWSTR buffer
= NULL
;
458 WCHAR typechar
= 'n';
459 static const WCHAR LastUsedSource_Fmt
[] = {'%','c',';','%','i',';','%','s',0};
461 /* make sure the source is registered */
462 MsiSourceListAddSourceExW(szProduct
, szUserSid
, dwContext
,
463 dwOptions
, szValue
, 0);
465 if (dwOptions
& MSISOURCETYPE_NETWORK
)
467 else if (dwOptions
& MSISOURCETYPE_URL
)
469 else if (dwOptions
& MSISOURCETYPE_MEDIA
)
472 ERR("Unknown source type! %x\n", dwOptions
);
474 size
= (lstrlenW(szValue
)+5)*sizeof(WCHAR
);
475 buffer
= msi_alloc(size
);
476 sprintfW(buffer
, LastUsedSource_Fmt
, typechar
, 1, szValue
);
477 rc
= RegSetValueExW(sourcekey
, INSTALLPROPERTY_LASTUSEDSOURCEW
, 0,
478 REG_EXPAND_SZ
, (LPBYTE
)buffer
, size
);
479 if (rc
!= ERROR_SUCCESS
)
480 rc
= ERROR_UNKNOWN_PROPERTY
;
483 else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW
, szProperty
)==0)
485 DWORD size
= lstrlenW(szValue
)*sizeof(WCHAR
);
486 rc
= RegSetValueExW(sourcekey
, INSTALLPROPERTY_PACKAGENAMEW
, 0,
487 REG_SZ
, (const BYTE
*)szValue
, size
);
488 if (rc
!= ERROR_SUCCESS
)
489 rc
= ERROR_UNKNOWN_PROPERTY
;
493 FIXME("Unknown property %s\n",debugstr_w(szProperty
));
494 rc
= ERROR_UNKNOWN_PROPERTY
;
497 RegCloseKey(sourcekey
);
502 /******************************************************************
503 * MsiSourceListAddSourceW (MSI.@)
505 UINT WINAPI
MsiSourceListAddSourceW( LPCWSTR szProduct
, LPCWSTR szUserName
,
506 DWORD dwReserved
, LPCWSTR szSource
)
509 LPWSTR sidstr
= NULL
;
513 TRACE("%s %s %s\n", debugstr_w(szProduct
), debugstr_w(szUserName
), debugstr_w(szSource
));
515 if (LookupAccountNameW(NULL
, szUserName
, NULL
, &sidsize
, NULL
, &domsize
, NULL
))
517 PSID psid
= msi_alloc(sidsize
);
519 if (LookupAccountNameW(NULL
, szUserName
, psid
, &sidsize
, NULL
, &domsize
, NULL
))
520 ConvertSidToStringSidW(psid
, &sidstr
);
525 ret
= MsiSourceListAddSourceExW(szProduct
, sidstr
,
526 MSIINSTALLCONTEXT_USERMANAGED
, MSISOURCETYPE_NETWORK
, szSource
, 0);
534 /******************************************************************
535 * MsiSourceListAddSourceA (MSI.@)
537 UINT WINAPI
MsiSourceListAddSourceA( LPCSTR szProduct
, LPCSTR szUserName
,
538 DWORD dwReserved
, LPCSTR szSource
)
545 szwproduct
= strdupAtoW( szProduct
);
546 szwusername
= strdupAtoW( szUserName
);
547 szwsource
= strdupAtoW( szSource
);
549 ret
= MsiSourceListAddSourceW(szwproduct
, szwusername
, 0, szwsource
);
551 msi_free(szwproduct
);
552 msi_free(szwusername
);
558 /******************************************************************
559 * MsiSourceListAddSourceExW (MSI.@)
561 UINT WINAPI
MsiSourceListAddSourceExW( LPCWSTR szProduct
, LPCWSTR szUserSid
,
562 MSIINSTALLCONTEXT dwContext
, DWORD dwOptions
, LPCWSTR szSource
,
568 media_info source_struct
;
570 TRACE("%s %s %x %x %s %i\n", debugstr_w(szProduct
), debugstr_w(szUserSid
),
571 dwContext
, dwOptions
, debugstr_w(szSource
), dwIndex
);
574 return ERROR_INVALID_PARAMETER
;
577 return ERROR_INVALID_PARAMETER
;
579 if (dwOptions
& MSICODE_PATCH
)
581 FIXME("Unhandled options MSICODE_PATCH\n");
582 return ERROR_FUNCTION_FAILED
;
586 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid
));
588 if (dwContext
== MSIINSTALLCONTEXT_USERUNMANAGED
)
589 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
591 if (dwContext
== MSIINSTALLCONTEXT_MACHINE
)
592 rc
= OpenSourceKey(szProduct
, &sourcekey
, MSICODE_PRODUCT
, FALSE
, TRUE
);
594 rc
= OpenSourceKey(szProduct
, &sourcekey
, MSICODE_PRODUCT
, TRUE
, TRUE
);
596 if (rc
!= ERROR_SUCCESS
)
597 return ERROR_UNKNOWN_PRODUCT
;
599 if (dwOptions
& MSISOURCETYPE_NETWORK
)
600 rc
= OpenNetworkSubkey(sourcekey
, &typekey
, TRUE
);
601 else if (dwOptions
& MSISOURCETYPE_URL
)
602 rc
= OpenURLSubkey(sourcekey
, &typekey
, TRUE
);
603 else if (dwOptions
& MSISOURCETYPE_MEDIA
)
604 rc
= OpenMediaSubkey(sourcekey
, &typekey
, TRUE
);
607 ERR("unknown media type: %08x\n", dwOptions
);
608 RegCloseKey(sourcekey
);
609 return ERROR_FUNCTION_FAILED
;
612 source_struct
.szIndex
[0] = 0;
613 if (find_given_source(typekey
, szSource
, &source_struct
)==ERROR_SUCCESS
)
615 DWORD current_index
= atoiW(source_struct
.szIndex
);
616 /* found the source */
617 if (dwIndex
> 0 && current_index
!= dwIndex
)
618 FIXME("Need to reorder the sources!\n");
619 msi_free( source_struct
.path
);
623 DWORD current_index
= 0;
624 static const WCHAR fmt
[] = {'%','i',0};
625 DWORD size
= lstrlenW(szSource
)*sizeof(WCHAR
);
627 if (source_struct
.szIndex
[0])
628 current_index
= atoiW(source_struct
.szIndex
);
630 if (dwIndex
> 0 && dwIndex
< current_index
)
631 FIXME("Need to reorder the sources!\n");
634 sprintfW(source_struct
.szIndex
,fmt
,current_index
);
635 rc
= RegSetValueExW(typekey
, source_struct
.szIndex
, 0, REG_EXPAND_SZ
,
636 (const BYTE
*)szSource
, size
);
639 RegCloseKey(typekey
);
640 RegCloseKey(sourcekey
);
644 /******************************************************************
645 * MsiSourceListAddMediaDisk(MSI.@)
647 UINT WINAPI
MsiSourceListAddMediaDiskW(LPCWSTR szProduct
, LPCWSTR szUserSid
,
648 MSIINSTALLCONTEXT dwContext
, DWORD dwOptions
, DWORD dwDiskId
,
649 LPCWSTR szVolumeLabel
, LPCWSTR szDiskPrompt
)
655 static const WCHAR fmt
[] = {'%','i',0};
656 static const WCHAR disk_fmt
[] = {'%','s',';','%','s',0};
657 static const WCHAR empty
[1] = {0};
662 TRACE("%s %s %x %x %i %s %s\n", debugstr_w(szProduct
),
663 debugstr_w(szUserSid
), dwContext
, dwOptions
, dwDiskId
,
664 debugstr_w(szVolumeLabel
), debugstr_w(szDiskPrompt
));
666 if (!szProduct
|| lstrlenW(szProduct
) > 39)
667 return ERROR_INVALID_PARAMETER
;
669 if (dwOptions
& MSICODE_PATCH
)
671 FIXME("Unhandled options MSICODE_PATCH\n");
672 return ERROR_FUNCTION_FAILED
;
676 FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid
));
678 if (dwContext
== MSIINSTALLCONTEXT_USERUNMANAGED
)
679 FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
681 if (dwContext
== MSIINSTALLCONTEXT_MACHINE
)
682 rc
= OpenSourceKey(szProduct
, &sourcekey
, MSICODE_PRODUCT
, FALSE
, TRUE
);
684 rc
= OpenSourceKey(szProduct
, &sourcekey
, MSICODE_PRODUCT
, TRUE
, TRUE
);
686 if (rc
!= ERROR_SUCCESS
)
687 return ERROR_UNKNOWN_PRODUCT
;
689 OpenMediaSubkey(sourcekey
,&mediakey
,TRUE
);
691 sprintfW(szIndex
,fmt
,dwDiskId
);
696 size
+=lstrlenW(szVolumeLabel
);
703 size
+=lstrlenW(szDiskPrompt
);
709 size
*=sizeof(WCHAR
);
711 buffer
= msi_alloc(size
);
712 sprintfW(buffer
,disk_fmt
,pt1
,pt2
);
714 RegSetValueExW(mediakey
, szIndex
, 0, REG_SZ
, (LPBYTE
)buffer
, size
);
717 RegCloseKey(sourcekey
);
718 RegCloseKey(mediakey
);
720 return ERROR_SUCCESS
;
723 /******************************************************************
724 * MsiSourceListClearAllA (MSI.@)
726 UINT WINAPI
MsiSourceListClearAllA( LPCSTR szProduct
, LPCSTR szUserName
, DWORD dwReserved
)
728 FIXME("(%s %s %d)\n", debugstr_a(szProduct
), debugstr_a(szUserName
), dwReserved
);
729 return ERROR_SUCCESS
;
732 /******************************************************************
733 * MsiSourceListClearAllW (MSI.@)
735 UINT WINAPI
MsiSourceListClearAllW( LPCWSTR szProduct
, LPCWSTR szUserName
, DWORD dwReserved
)
737 FIXME("(%s %s %d)\n", debugstr_w(szProduct
), debugstr_w(szUserName
), dwReserved
);
738 return ERROR_SUCCESS
;