Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a884d98e
Commit
a884d98e
authored
Jan 21, 2015
by
Hans Leidekker
Committed by
Alexandre Julliard
Jan 21, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Add a partial implementation of MsiProvideComponent.
parent
b24b8a50
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
193 additions
and
2 deletions
+193
-2
msi.c
dlls/msi/msi.c
+86
-0
msi.spec
dlls/msi/msi.spec
+2
-2
msi.c
dlls/msi/tests/msi.c
+101
-0
msi.h
include/msi.h
+4
-0
No files found.
dlls/msi/msi.c
View file @
a884d98e
...
...
@@ -4198,6 +4198,92 @@ UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent,
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiProvideComponentA
(
LPCSTR
product
,
LPCSTR
feature
,
LPCSTR
component
,
DWORD
mode
,
LPSTR
buf
,
LPDWORD
buflen
)
{
WCHAR
*
productW
=
NULL
,
*
componentW
=
NULL
,
*
featureW
=
NULL
,
*
bufW
=
NULL
;
UINT
r
=
ERROR_OUTOFMEMORY
;
DWORD
lenW
;
int
len
;
TRACE
(
"%s, %s, %s, %x, %p, %p
\n
"
,
debugstr_a
(
product
),
debugstr_a
(
component
),
debugstr_a
(
feature
),
mode
,
buf
,
buflen
);
if
(
product
&&
!
(
productW
=
strdupAtoW
(
product
)))
goto
done
;
if
(
feature
&&
!
(
featureW
=
strdupAtoW
(
feature
)))
goto
done
;
if
(
component
&&
!
(
componentW
=
strdupAtoW
(
component
)))
goto
done
;
r
=
MsiProvideComponentW
(
productW
,
featureW
,
componentW
,
mode
,
NULL
,
&
lenW
);
if
(
r
!=
ERROR_SUCCESS
)
goto
done
;
if
(
!
(
bufW
=
msi_alloc
(
++
lenW
*
sizeof
(
WCHAR
)
)))
{
r
=
ERROR_OUTOFMEMORY
;
goto
done
;
}
r
=
MsiProvideComponentW
(
productW
,
featureW
,
componentW
,
mode
,
bufW
,
&
lenW
);
if
(
r
!=
ERROR_SUCCESS
)
goto
done
;
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
bufW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
buf
)
{
if
(
len
>
*
buflen
)
r
=
ERROR_MORE_DATA
;
else
WideCharToMultiByte
(
CP_ACP
,
0
,
bufW
,
-
1
,
buf
,
*
buflen
,
NULL
,
NULL
);
}
*
buflen
=
len
-
1
;
done:
msi_free
(
productW
);
msi_free
(
featureW
);
msi_free
(
componentW
);
msi_free
(
bufW
);
return
r
;
}
UINT
WINAPI
MsiProvideComponentW
(
LPCWSTR
product
,
LPCWSTR
feature
,
LPCWSTR
component
,
DWORD
mode
,
LPWSTR
buf
,
LPDWORD
buflen
)
{
INSTALLSTATE
state
;
TRACE
(
"%s, %s, %s, %x, %p, %p
\n
"
,
debugstr_w
(
product
),
debugstr_w
(
component
),
debugstr_w
(
feature
),
mode
,
buf
,
buflen
);
state
=
MsiQueryFeatureStateW
(
product
,
feature
);
TRACE
(
"feature state: %d
\n
"
,
state
);
switch
(
mode
)
{
case
INSTALLMODE_NODETECTION
:
break
;
default:
FIXME
(
"mode %x not implemented
\n
"
,
mode
);
return
ERROR_INSTALL_FAILURE
;
}
state
=
MsiGetComponentPathW
(
product
,
component
,
buf
,
buflen
);
TRACE
(
"component state: %d
\n
"
,
state
);
switch
(
state
)
{
case
INSTALLSTATE_INVALIDARG
:
return
ERROR_INVALID_PARAMETER
;
case
INSTALLSTATE_MOREDATA
:
return
ERROR_MORE_DATA
;
case
INSTALLSTATE_ADVERTISED
:
case
INSTALLSTATE_LOCAL
:
case
INSTALLSTATE_SOURCE
:
MsiUseFeatureW
(
product
,
feature
);
return
ERROR_SUCCESS
;
default:
TRACE
(
"MsiGetComponentPathW returned %d
\n
"
,
state
);
return
ERROR_INSTALL_FAILURE
;
}
}
/***********************************************************************
* MsiBeginTransactionA [MSI.@]
*/
...
...
dlls/msi/msi.spec
View file @
a884d98e
...
...
@@ -97,10 +97,10 @@
101 stub MsiProcessAdvertiseScriptA
102 stub MsiProcessAdvertiseScriptW
103 stdcall MsiProcessMessage(long long long)
104 st
ub MsiProvideComponentA
104 st
dcall MsiProvideComponentA(str str str long ptr ptr)
105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr)
106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr)
107 st
ub MsiProvideComponentW
107 st
dcall MsiProvideComponentW(wstr wstr wstr long ptr ptr)
108 stdcall MsiProvideQualifiedComponentA(str str long ptr ptr)
109 stdcall MsiProvideQualifiedComponentW(wstr wstr long ptr ptr)
110 stdcall MsiQueryFeatureStateA(str str)
...
...
dlls/msi/tests/msi.c
View file @
a884d98e
...
...
@@ -50,6 +50,10 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static
INSTALLSTATE
(
WINAPI
*
pMsiGetComponentPathA
)
(
LPCSTR
,
LPCSTR
,
LPSTR
,
DWORD
*
);
static
INSTALLSTATE
(
WINAPI
*
pMsiProvideComponentA
)
(
LPCSTR
,
LPCSTR
,
LPCSTR
,
DWORD
,
LPSTR
,
LPDWORD
);
static
INSTALLSTATE
(
WINAPI
*
pMsiProvideComponentW
)
(
LPCWSTR
,
LPCWSTR
,
LPCWSTR
,
DWORD
,
LPWSTR
,
LPDWORD
);
static
UINT
(
WINAPI
*
pMsiGetFileHashA
)
(
LPCSTR
,
DWORD
,
PMSIFILEHASHINFO
);
static
UINT
(
WINAPI
*
pMsiGetProductInfoExA
)
...
...
@@ -88,6 +92,8 @@ static void init_functionpointers(void)
trace("GetProcAddress(%s) failed\n", #func);
GET_PROC
(
hmsi
,
MsiGetComponentPathA
)
GET_PROC
(
hmsi
,
MsiProvideComponentA
)
GET_PROC
(
hmsi
,
MsiProvideComponentW
)
GET_PROC
(
hmsi
,
MsiGetFileHashA
)
GET_PROC
(
hmsi
,
MsiGetProductInfoExA
)
GET_PROC
(
hmsi
,
MsiOpenPackageExA
)
...
...
@@ -3404,6 +3410,100 @@ static void test_MsiGetComponentPath(void)
LocalFree
(
usersid
);
}
static
void
test_MsiProvideComponent
(
void
)
{
static
const
WCHAR
sourcedirW
[]
=
{
's'
,
'o'
,
'u'
,
'r'
,
'c'
,
'e'
,
'd'
,
'i'
,
'r'
,
0
};
static
const
WCHAR
productW
[]
=
{
'{'
,
'3'
,
'8'
,
'8'
,
'4'
,
'7'
,
'3'
,
'3'
,
'8'
,
'-'
,
'1'
,
'B'
,
'B'
,
'C'
,
'-'
,
'4'
,
'1'
,
'0'
,
'4'
,
'-'
,
'8'
,
'1'
,
'A'
,
'C'
,
'-'
,
'2'
,
'F'
,
'A'
,
'A'
,
'C'
,
'7'
,
'E'
,
'C'
,
'D'
,
'D'
,
'C'
,
'D'
,
'}'
,
0
};
static
const
WCHAR
componentW
[]
=
{
'{'
,
'D'
,
'D'
,
'4'
,
'2'
,
'2'
,
'F'
,
'9'
,
'2'
,
'-'
,
'3'
,
'E'
,
'D'
,
'8'
,
'-'
,
'4'
,
'9'
,
'B'
,
'5'
,
'-'
,
'A'
,
'0'
,
'B'
,
'7'
,
'-'
,
'F'
,
'2'
,
'6'
,
'6'
,
'F'
,
'9'
,
'8'
,
'3'
,
'5'
,
'7'
,
'D'
,
'F'
,
'}'
,
0
};
INSTALLSTATE
state
;
char
buf
[
0x100
];
WCHAR
bufW
[
0x100
];
DWORD
len
,
len2
;
UINT
r
;
if
(
is_process_limited
())
{
skip
(
"process is limited
\n
"
);
return
;
}
create_test_files
();
create_file
(
"msitest
\\
sourcedir.txt"
,
"msitest
\\
sourcedir.txt"
,
1000
);
create_database
(
msifile
,
sd_tables
,
sizeof
(
sd_tables
)
/
sizeof
(
msi_table
));
MsiSetInternalUI
(
INSTALLUILEVEL_NONE
,
NULL
);
buf
[
0
]
=
0
;
len
=
sizeof
(
buf
);
r
=
pMsiProvideComponentA
(
"{90120000-0070-0000-0000-4000000FF1CE}"
,
"{17961602-C4E2-482E-800A-DF6E627549CF}"
,
"ProductFiles"
,
INSTALLMODE_NODETECTION
,
buf
,
&
len
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"got %u
\n
"
,
r
);
r
=
MsiInstallProductA
(
msifile
,
NULL
);
ok
(
r
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %u
\n
"
,
r
);
state
=
MsiQueryFeatureStateA
(
"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}"
,
"sourcedir"
);
ok
(
state
==
INSTALLSTATE_LOCAL
,
"got %d
\n
"
,
state
);
buf
[
0
]
=
0
;
len
=
sizeof
(
buf
);
r
=
pMsiProvideComponentA
(
"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}"
,
"sourcedir"
,
"{DD422F92-3ED8-49B5-A0B7-F266F98357DF}"
,
INSTALLMODE_NODETECTION
,
buf
,
&
len
);
ok
(
r
==
ERROR_SUCCESS
,
"got %u
\n
"
,
r
);
ok
(
buf
[
0
],
"empty path
\n
"
);
ok
(
len
==
lstrlenA
(
buf
),
"got %u
\n
"
,
len
);
len2
=
0
;
r
=
pMsiProvideComponentA
(
"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}"
,
"sourcedir"
,
"{DD422F92-3ED8-49B5-A0B7-F266F98357DF}"
,
INSTALLMODE_NODETECTION
,
NULL
,
&
len2
);
ok
(
r
==
ERROR_SUCCESS
,
"got %u
\n
"
,
r
);
ok
(
len2
==
len
,
"got %u
\n
"
,
len2
);
len2
=
0
;
r
=
pMsiProvideComponentA
(
"{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}"
,
"sourcedir"
,
"{DD422F92-3ED8-49B5-A0B7-F266F98357DF}"
,
INSTALLMODE_NODETECTION
,
buf
,
&
len2
);
ok
(
r
==
ERROR_MORE_DATA
,
"got %u
\n
"
,
r
);
ok
(
len2
==
len
,
"got %u
\n
"
,
len2
);
/* wide version */
bufW
[
0
]
=
0
;
len
=
sizeof
(
buf
);
r
=
pMsiProvideComponentW
(
productW
,
sourcedirW
,
componentW
,
INSTALLMODE_NODETECTION
,
bufW
,
&
len
);
ok
(
r
==
ERROR_SUCCESS
,
"got %u
\n
"
,
r
);
ok
(
bufW
[
0
],
"empty path
\n
"
);
ok
(
len
==
lstrlenW
(
bufW
),
"got %u
\n
"
,
len
);
len2
=
0
;
r
=
pMsiProvideComponentW
(
productW
,
sourcedirW
,
componentW
,
INSTALLMODE_NODETECTION
,
NULL
,
&
len2
);
ok
(
r
==
ERROR_SUCCESS
,
"got %u
\n
"
,
r
);
ok
(
len2
==
len
,
"got %u
\n
"
,
len2
);
len2
=
0
;
r
=
pMsiProvideComponentW
(
productW
,
sourcedirW
,
componentW
,
INSTALLMODE_NODETECTION
,
bufW
,
&
len2
);
ok
(
r
==
ERROR_MORE_DATA
,
"got %u
\n
"
,
r
);
ok
(
len2
==
len
,
"got %u
\n
"
,
len2
);
r
=
MsiInstallProductA
(
msifile
,
"REMOVE=ALL"
);
ok
(
r
==
ERROR_SUCCESS
,
"got %u
\n
"
,
r
);
DeleteFileA
(
"msitest
\\
sourcedir.txt"
);
delete_test_files
();
DeleteFileA
(
msifile
);
}
static
void
test_MsiGetProductCode
(
void
)
{
HKEY
compkey
,
prodkey
;
...
...
@@ -14300,6 +14400,7 @@ START_TEST(msi)
test_MsiQueryFeatureState
();
test_MsiQueryComponentState
();
test_MsiGetComponentPath
();
test_MsiProvideComponent
();
test_MsiGetProductCode
();
test_MsiEnumClients
();
test_MsiGetProductInfo
();
...
...
include/msi.h
View file @
a884d98e
...
...
@@ -583,6 +583,10 @@ USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR, LPSTR, LPDWORD, LPSTR, LPDWORD, LPS
USERINFOSTATE
WINAPI
MsiGetUserInfoW
(
LPCWSTR
,
LPWSTR
,
LPDWORD
,
LPWSTR
,
LPDWORD
,
LPWSTR
,
LPDWORD
);
#define MsiGetUserInfo WINELIB_NAME_AW(MsiGetUserInfo)
UINT
WINAPI
MsiProvidedComponentA
(
LPCSTR
,
LPCSTR
,
LPCSTR
,
DWORD
,
LPSTR
,
LPDWORD
);
UINT
WINAPI
MsiProvideComponentW
(
LPCWSTR
,
LPCWSTR
,
LPCWSTR
,
DWORD
,
LPWSTR
,
LPDWORD
);
#define MsiProvideComponent WINELIB_NAME_AW(MsiProvideComponent)
UINT
WINAPI
MsiCollectUserInfoA
(
LPCSTR
);
UINT
WINAPI
MsiCollectUserInfoW
(
LPCWSTR
);
#define MsiCollectUserInfo WINELIB_NAME_AW(MsiCollectUserInfo)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment