msi: Implement MsiEnumComponentsEx.
This commit is contained in:
parent
e7a3392d50
commit
8cebf01702
|
@ -282,8 +282,8 @@
|
||||||
286 stdcall MsiEndTransaction(long)
|
286 stdcall MsiEndTransaction(long)
|
||||||
287 stub MsiJoinTransaction
|
287 stub MsiJoinTransaction
|
||||||
288 stub MsiSetOfflineContextW
|
288 stub MsiSetOfflineContextW
|
||||||
289 stub MsiEnumComponentsExA
|
289 stdcall MsiEnumComponentsExA(str long long ptr ptr ptr ptr)
|
||||||
290 stub MsiEnumComponentsExW
|
290 stdcall MsiEnumComponentsExW(wstr long long ptr ptr ptr ptr)
|
||||||
291 stub MsiEnumClientsExA
|
291 stub MsiEnumClientsExA
|
||||||
292 stub MsiEnumClientsExW
|
292 stub MsiEnumClientsExW
|
||||||
293 stub MsiGetComponentPathExA
|
293 stub MsiGetComponentPathExA
|
||||||
|
|
|
@ -1235,6 +1235,218 @@ UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiEnumComponentsExA( LPCSTR user_sid, DWORD ctx, DWORD index, CHAR guid[39],
|
||||||
|
MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len )
|
||||||
|
{
|
||||||
|
UINT r;
|
||||||
|
WCHAR *user_sidW = NULL, *sidW = NULL, guidW[GUID_SIZE];
|
||||||
|
|
||||||
|
TRACE("%s, %u, %u, %p, %p, %p, %p\n", debugstr_a(user_sid), ctx, index, guid, installed_ctx,
|
||||||
|
sid, sid_len);
|
||||||
|
|
||||||
|
if (sid && !sid_len) return ERROR_INVALID_PARAMETER;
|
||||||
|
if (user_sid && !(user_sidW = strdupAtoW( user_sid ))) return ERROR_OUTOFMEMORY;
|
||||||
|
if (sid && !(sidW = msi_alloc( *sid_len * sizeof(WCHAR) )))
|
||||||
|
{
|
||||||
|
msi_free( user_sidW );
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
r = MsiEnumComponentsExW( user_sidW, ctx, index, guidW, installed_ctx, sidW, sid_len );
|
||||||
|
if (r == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (guid) WideCharToMultiByte( CP_ACP, 0, guidW, GUID_SIZE, guid, GUID_SIZE, NULL, NULL );
|
||||||
|
if (sid) WideCharToMultiByte( CP_ACP, 0, sidW, *sid_len + 1, sid, *sid_len + 1, NULL, NULL );
|
||||||
|
}
|
||||||
|
msi_free( user_sidW );
|
||||||
|
msi_free( sidW );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT fetch_machine_component( DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39],
|
||||||
|
MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
|
||||||
|
{
|
||||||
|
static const WCHAR componentsW[] =
|
||||||
|
{'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
|
||||||
|
'S','-','1','-','5','-','1','8','\\','C','o','m','p','o','n','e','n','t','s',0};
|
||||||
|
UINT r = ERROR_SUCCESS;
|
||||||
|
WCHAR component[GUID_SIZE];
|
||||||
|
DWORD i = 0, len_component;
|
||||||
|
REGSAM access = KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY;
|
||||||
|
HKEY key_components;
|
||||||
|
|
||||||
|
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, componentsW, 0, access, &key_components ))
|
||||||
|
return ERROR_NO_MORE_ITEMS;
|
||||||
|
|
||||||
|
len_component = sizeof(component)/sizeof(component[0]);
|
||||||
|
while (!RegEnumKeyExW( key_components, i, component, &len_component, NULL, NULL, NULL, NULL ))
|
||||||
|
{
|
||||||
|
if (*idx == index) goto found;
|
||||||
|
(*idx)++;
|
||||||
|
len_component = sizeof(component)/sizeof(component[0]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
RegCloseKey( key_components );
|
||||||
|
return ERROR_NO_MORE_ITEMS;
|
||||||
|
|
||||||
|
found:
|
||||||
|
if (sid_len)
|
||||||
|
{
|
||||||
|
if (*sid_len < 1)
|
||||||
|
{
|
||||||
|
*sid_len = 1;
|
||||||
|
r = ERROR_MORE_DATA;
|
||||||
|
}
|
||||||
|
else if (sid)
|
||||||
|
{
|
||||||
|
*sid_len = 0;
|
||||||
|
sid[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (guid) unsquash_guid( component, guid );
|
||||||
|
if (installed_ctx) *installed_ctx = MSIINSTALLCONTEXT_MACHINE;
|
||||||
|
RegCloseKey( key_components );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT fetch_user_component( const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx,
|
||||||
|
WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid,
|
||||||
|
LPDWORD sid_len )
|
||||||
|
{
|
||||||
|
static const WCHAR userdataW[] =
|
||||||
|
{'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a',0};
|
||||||
|
static const WCHAR componentsW[] = {'\\','C','o','m','p','o','n','e','n','t','s',0};
|
||||||
|
UINT r = ERROR_SUCCESS;
|
||||||
|
WCHAR path[MAX_PATH], component[GUID_SIZE], user[128];
|
||||||
|
DWORD i = 0, j = 0, len_component, len_user;
|
||||||
|
REGSAM access = KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY;
|
||||||
|
HKEY key_users, key_components;
|
||||||
|
|
||||||
|
if (ctx == MSIINSTALLCONTEXT_USERMANAGED) /* FIXME: were to find these? */
|
||||||
|
return ERROR_NO_MORE_ITEMS;
|
||||||
|
|
||||||
|
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, userdataW, 0, access, &key_users ))
|
||||||
|
return ERROR_NO_MORE_ITEMS;
|
||||||
|
|
||||||
|
len_user = sizeof(user)/sizeof(user[0]);
|
||||||
|
while (!RegEnumKeyExW( key_users, i, user, &len_user, NULL, NULL, NULL, NULL ))
|
||||||
|
{
|
||||||
|
if ((strcmpW( usersid, szAllSid ) && strcmpW( usersid, user )) ||
|
||||||
|
!strcmpW( szLocalSid, user ))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
len_user = sizeof(user)/sizeof(user[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
strcpyW( path, user );
|
||||||
|
strcatW( path, componentsW );
|
||||||
|
if (RegOpenKeyExW( key_users, path, 0, access, &key_components ))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
len_user = sizeof(user)/sizeof(user[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len_component = sizeof(component)/sizeof(component[0]);
|
||||||
|
while (!RegEnumKeyExW( key_components, j, component, &len_component, NULL, NULL, NULL, NULL ))
|
||||||
|
{
|
||||||
|
if (*idx == index) goto found;
|
||||||
|
(*idx)++;
|
||||||
|
len_component = sizeof(component)/sizeof(component[0]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
RegCloseKey( key_components );
|
||||||
|
len_user = sizeof(user)/sizeof(user[0]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
RegCloseKey( key_users );
|
||||||
|
return ERROR_NO_MORE_ITEMS;
|
||||||
|
|
||||||
|
found:
|
||||||
|
if (sid_len)
|
||||||
|
{
|
||||||
|
if (*sid_len < len_user + 1)
|
||||||
|
{
|
||||||
|
*sid_len = len_user + 1;
|
||||||
|
r = ERROR_MORE_DATA;
|
||||||
|
}
|
||||||
|
else if (sid)
|
||||||
|
{
|
||||||
|
*sid_len = len_user;
|
||||||
|
strcpyW( sid, user );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (guid) unsquash_guid( component, guid );
|
||||||
|
if (installed_ctx) *installed_ctx = ctx;
|
||||||
|
RegCloseKey( key_components );
|
||||||
|
RegCloseKey( key_users );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT enum_components( const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39],
|
||||||
|
MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
|
||||||
|
{
|
||||||
|
UINT r = ERROR_NO_MORE_ITEMS;
|
||||||
|
WCHAR *user = NULL;
|
||||||
|
|
||||||
|
if (!usersid)
|
||||||
|
{
|
||||||
|
usersid = user = get_user_sid();
|
||||||
|
if (!user) return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
if (ctx & MSIINSTALLCONTEXT_USERMANAGED)
|
||||||
|
{
|
||||||
|
r = fetch_user_component( usersid, MSIINSTALLCONTEXT_USERMANAGED, index, idx, guid,
|
||||||
|
installed_ctx, sid, sid_len );
|
||||||
|
if (r != ERROR_NO_MORE_ITEMS) goto done;
|
||||||
|
}
|
||||||
|
if (ctx & MSIINSTALLCONTEXT_USERUNMANAGED)
|
||||||
|
{
|
||||||
|
r = fetch_user_component( usersid, MSIINSTALLCONTEXT_USERUNMANAGED, index, idx, guid,
|
||||||
|
installed_ctx, sid, sid_len );
|
||||||
|
if (r != ERROR_NO_MORE_ITEMS) goto done;
|
||||||
|
}
|
||||||
|
if (ctx & MSIINSTALLCONTEXT_MACHINE)
|
||||||
|
{
|
||||||
|
r = fetch_machine_component( MSIINSTALLCONTEXT_MACHINE, index, idx, guid, installed_ctx,
|
||||||
|
sid, sid_len );
|
||||||
|
if (r != ERROR_NO_MORE_ITEMS) goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
LocalFree( user );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiEnumComponentsExW( LPCWSTR user_sid, DWORD ctx, DWORD index, WCHAR guid[39],
|
||||||
|
MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
|
||||||
|
{
|
||||||
|
UINT r;
|
||||||
|
DWORD idx = 0;
|
||||||
|
static DWORD last_index;
|
||||||
|
|
||||||
|
TRACE("%s, %u, %u, %p, %p, %p, %p\n", debugstr_w(user_sid), ctx, index, guid, installed_ctx,
|
||||||
|
sid, sid_len);
|
||||||
|
|
||||||
|
if ((sid && !sid_len) || !ctx || (user_sid && ctx == MSIINSTALLCONTEXT_MACHINE))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (index && index - last_index != 1)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (!index) last_index = 0;
|
||||||
|
|
||||||
|
r = enum_components( user_sid, ctx, index, &idx, guid, installed_ctx, sid, sid_len );
|
||||||
|
if (r == ERROR_SUCCESS)
|
||||||
|
last_index = index;
|
||||||
|
else
|
||||||
|
last_index = 0;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
|
UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
|
||||||
{
|
{
|
||||||
DWORD r;
|
DWORD r;
|
||||||
|
|
|
@ -453,6 +453,12 @@ UINT WINAPI MsiEnumComponentsA(DWORD, LPSTR);
|
||||||
UINT WINAPI MsiEnumComponentsW(DWORD, LPWSTR);
|
UINT WINAPI MsiEnumComponentsW(DWORD, LPWSTR);
|
||||||
#define MsiEnumComponents WINELIB_NAME_AW(MsiEnumComponents)
|
#define MsiEnumComponents WINELIB_NAME_AW(MsiEnumComponents)
|
||||||
|
|
||||||
|
UINT WINAPI MsiEnumComponentsExA(LPCSTR, DWORD, DWORD, CHAR[39],
|
||||||
|
MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
|
||||||
|
UINT WINAPI MsiEnumComponentsExW(LPCWSTR, DWORD, DWORD, WCHAR[39],
|
||||||
|
MSIINSTALLCONTEXT *, LPWSTR, LPDWORD);
|
||||||
|
#define MsiEnumComponentsEx WINELIB_NAME_AW(MsiEnumComponentsEx)
|
||||||
|
|
||||||
UINT WINAPI MsiEnumClientsA(LPCSTR, DWORD, LPSTR);
|
UINT WINAPI MsiEnumClientsA(LPCSTR, DWORD, LPSTR);
|
||||||
UINT WINAPI MsiEnumClientsW(LPCWSTR, DWORD, LPWSTR);
|
UINT WINAPI MsiEnumClientsW(LPCWSTR, DWORD, LPWSTR);
|
||||||
#define MsiEnumClients WINELIB_NAME_AW(MsiEnumClients)
|
#define MsiEnumClients WINELIB_NAME_AW(MsiEnumClients)
|
||||||
|
|
Loading…
Reference in New Issue