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
a4fb1c94
Commit
a4fb1c94
authored
Aug 25, 2006
by
Mike McCormack
Committed by
Alexandre Julliard
Aug 25, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Store properties in a hash table, not the database.
Use string insensitive comparisons for property names.
parent
0de9cf4d
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
144 additions
and
117 deletions
+144
-117
msipriv.h
dlls/msi/msipriv.h
+6
-2
package.c
dlls/msi/package.c
+138
-115
No files found.
dlls/msi/msipriv.h
View file @
a4fb1c94
...
@@ -201,6 +201,8 @@ struct tagMSIVIEW
...
@@ -201,6 +201,8 @@ struct tagMSIVIEW
struct
msi_dialog_tag
;
struct
msi_dialog_tag
;
typedef
struct
msi_dialog_tag
msi_dialog
;
typedef
struct
msi_dialog_tag
msi_dialog
;
#define PROPERTY_HASH_SIZE 67
typedef
struct
tagMSIPACKAGE
typedef
struct
tagMSIPACKAGE
{
{
MSIOBJECTHDR
hdr
;
MSIOBJECTHDR
hdr
;
...
@@ -218,7 +220,7 @@ typedef struct tagMSIPACKAGE
...
@@ -218,7 +220,7 @@ typedef struct tagMSIPACKAGE
struct
list
progids
;
struct
list
progids
;
struct
list
mimes
;
struct
list
mimes
;
struct
list
appids
;
struct
list
appids
;
struct
tagMSISCRIPT
*
script
;
struct
tagMSISCRIPT
*
script
;
struct
list
RunningActions
;
struct
list
RunningActions
;
...
@@ -231,7 +233,9 @@ typedef struct tagMSIPACKAGE
...
@@ -231,7 +233,9 @@ typedef struct tagMSIPACKAGE
LPWSTR
next_dialog
;
LPWSTR
next_dialog
;
UINT
WordCount
;
UINT
WordCount
;
struct
list
props
[
PROPERTY_HASH_SIZE
];
struct
list
subscriptions
;
struct
list
subscriptions
;
}
MSIPACKAGE
;
}
MSIPACKAGE
;
...
...
dlls/msi/package.c
View file @
a4fb1c94
...
@@ -49,6 +49,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
...
@@ -49,6 +49,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
extern
void
msi_ui_error
(
DWORD
msg_id
,
DWORD
type
);
extern
void
msi_ui_error
(
DWORD
msg_id
,
DWORD
type
);
static
void
msi_free_properties
(
MSIPACKAGE
*
package
);
static
void
MSI_FreePackage
(
MSIOBJECTHDR
*
arg
)
static
void
MSI_FreePackage
(
MSIOBJECTHDR
*
arg
)
{
{
MSIPACKAGE
*
package
=
(
MSIPACKAGE
*
)
arg
;
MSIPACKAGE
*
package
=
(
MSIPACKAGE
*
)
arg
;
...
@@ -57,42 +59,21 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
...
@@ -57,42 +59,21 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
msi_dialog_destroy
(
package
->
dialog
);
msi_dialog_destroy
(
package
->
dialog
);
ACTION_free_package_structures
(
package
);
ACTION_free_package_structures
(
package
);
msi_free_properties
(
package
);
msiobj_release
(
&
package
->
db
->
hdr
);
msiobj_release
(
&
package
->
db
->
hdr
);
}
}
static
UINT
clone_properties
(
MSIDATABASE
*
db
)
static
UINT
clone_properties
(
MSIPACKAGE
*
package
)
{
{
MSIQUERY
*
view
=
NULL
;
MSIQUERY
*
view
=
NULL
;
UINT
rc
;
UINT
rc
;
static
const
WCHAR
CreateSql
[]
=
{
'C'
,
'R'
,
'E'
,
'A'
,
'T'
,
'E'
,
' '
,
'T'
,
'A'
,
'B'
,
'L'
,
'E'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
' '
,
'('
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
' '
,
'C'
,
'H'
,
'A'
,
'R'
,
'('
,
'5'
,
'6'
,
')'
,
' '
,
'N'
,
'O'
,
'T'
,
' '
,
'N'
,
'U'
,
'L'
,
'L'
,
','
,
' '
,
'`'
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
,
'`'
,
' '
,
'C'
,
'H'
,
'A'
,
'R'
,
'('
,
'9'
,
'8'
,
')'
,
' '
,
'N'
,
'O'
,
'T'
,
' '
,
'N'
,
'U'
,
'L'
,
'L'
,
' '
,
'P'
,
'R'
,
'I'
,
'M'
,
'A'
,
'R'
,
'Y'
,
' '
,
'K'
,
'E'
,
'Y'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
')'
,
0
};
static
const
WCHAR
Query
[]
=
{
static
const
WCHAR
Query
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'*'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'`'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
0
};
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'`'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
0
};
static
const
WCHAR
Insert
[]
=
{
'I'
,
'N'
,
'S'
,
'E'
,
'R'
,
'T'
,
' '
,
'i'
,
'n'
,
't'
,
'o'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
' '
,
'('
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
','
,
'`'
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
,
'`'
,
')'
,
' '
,
'V'
,
'A'
,
'L'
,
'U'
,
'E'
,
'S'
,
' '
,
'('
,
'?'
,
','
,
'?'
,
')'
,
0
};
/* create the temporary properties table */
rc
=
MSI_DatabaseOpenViewW
(
db
,
CreateSql
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
rc
=
MSI_ViewExecute
(
view
,
0
);
MSI_ViewClose
(
view
);
msiobj_release
(
&
view
->
hdr
);
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
/* clone the existing properties */
/* clone the existing properties */
rc
=
MSI_DatabaseOpenViewW
(
db
,
Query
,
&
view
);
rc
=
MSI_DatabaseOpenViewW
(
package
->
db
,
Query
,
&
view
);
if
(
rc
!=
ERROR_SUCCESS
)
if
(
rc
!=
ERROR_SUCCESS
)
return
rc
;
return
rc
;
...
@@ -100,31 +81,27 @@ static UINT clone_properties(MSIDATABASE *db)
...
@@ -100,31 +81,27 @@ static UINT clone_properties(MSIDATABASE *db)
if
(
rc
!=
ERROR_SUCCESS
)
if
(
rc
!=
ERROR_SUCCESS
)
{
{
MSI_ViewClose
(
view
);
MSI_ViewClose
(
view
);
msiobj_release
(
&
view
->
hdr
);
msiobj_release
(
&
view
->
hdr
);
return
rc
;
return
rc
;
}
}
while
(
1
)
while
(
1
)
{
{
MSIRECORD
*
row
;
MSIRECORD
*
row
;
MSIQUERY
*
view2
;
LPCWSTR
name
,
value
;
rc
=
MSI_ViewFetch
(
view
,
&
row
);
rc
=
MSI_ViewFetch
(
view
,
&
row
);
if
(
rc
!=
ERROR_SUCCESS
)
if
(
rc
!=
ERROR_SUCCESS
)
break
;
break
;
rc
=
MSI_DatabaseOpenViewW
(
db
,
Insert
,
&
view2
);
name
=
MSI_RecordGetString
(
row
,
1
);
if
(
rc
!=
ERROR_SUCCESS
)
value
=
MSI_RecordGetString
(
row
,
2
);
continue
;
MSI_SetPropertyW
(
package
,
name
,
value
);
rc
=
MSI_ViewExecute
(
view2
,
row
);
MSI_ViewClose
(
view2
);
msiobj_release
(
&
row
->
hdr
);
msiobj_release
(
&
view2
->
hdr
);
if
(
rc
==
ERROR_SUCCESS
)
msiobj_release
(
&
row
->
hdr
);
}
}
MSI_ViewClose
(
view
);
MSI_ViewClose
(
view
);
msiobj_release
(
&
view
->
hdr
);
msiobj_release
(
&
view
->
hdr
);
return
rc
;
return
rc
;
}
}
...
@@ -415,6 +392,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
...
@@ -415,6 +392,7 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
'P'
,
'r'
,
'o'
,
'd'
,
'u'
,
'c'
,
't'
,
'C'
,
'o'
,
'd'
,
'e'
,
0
};
'P'
,
'r'
,
'o'
,
'd'
,
'u'
,
'c'
,
't'
,
'C'
,
'o'
,
'd'
,
'e'
,
0
};
MSIPACKAGE
*
package
=
NULL
;
MSIPACKAGE
*
package
=
NULL
;
WCHAR
uilevel
[
10
];
WCHAR
uilevel
[
10
];
int
i
;
TRACE
(
"%p
\n
"
,
db
);
TRACE
(
"%p
\n
"
,
db
);
...
@@ -447,7 +425,10 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
...
@@ -447,7 +425,10 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
/* OK, here is where we do a slew of things to the database to
/* OK, here is where we do a slew of things to the database to
* prep for all that is to come as a package */
* prep for all that is to come as a package */
clone_properties
(
db
);
for
(
i
=
0
;
i
<
PROPERTY_HASH_SIZE
;
i
++
)
list_init
(
&
package
->
props
[
i
]
);
clone_properties
(
package
);
set_installer_properties
(
package
);
set_installer_properties
(
package
);
sprintfW
(
uilevel
,
szpi
,
gUILevel
);
sprintfW
(
uilevel
,
szpi
,
gUILevel
);
MSI_SetPropertyW
(
package
,
szLevel
,
uilevel
);
MSI_SetPropertyW
(
package
,
szLevel
,
uilevel
);
...
@@ -847,6 +828,79 @@ out:
...
@@ -847,6 +828,79 @@ out:
}
}
/* property code */
/* property code */
typedef
struct
msi_property
{
struct
list
entry
;
LPWSTR
key
;
LPWSTR
value
;
}
msi_property
;
static
UINT
msi_prop_makehash
(
const
WCHAR
*
str
)
{
UINT
hash
=
0
;
if
(
str
==
NULL
)
return
hash
;
while
(
*
str
)
{
hash
^=
tolowerW
(
*
str
++
);
hash
*=
53
;
hash
=
(
hash
<<
5
)
|
(
hash
>>
27
);
}
return
hash
%
PROPERTY_HASH_SIZE
;
}
static
msi_property
*
msi_prop_find
(
MSIPACKAGE
*
package
,
LPCWSTR
key
)
{
UINT
hash
=
msi_prop_makehash
(
key
);
msi_property
*
prop
;
LIST_FOR_EACH_ENTRY
(
prop
,
&
package
->
props
[
hash
],
msi_property
,
entry
)
if
(
!
lstrcmpiW
(
prop
->
key
,
key
))
return
prop
;
return
NULL
;
}
static
msi_property
*
msi_prop_add
(
MSIPACKAGE
*
package
,
LPCWSTR
key
)
{
UINT
hash
=
msi_prop_makehash
(
key
);
msi_property
*
prop
;
prop
=
msi_alloc
(
sizeof
*
prop
);
if
(
prop
)
{
prop
->
key
=
strdupW
(
key
);
prop
->
value
=
NULL
;
list_add_head
(
&
package
->
props
[
hash
],
&
prop
->
entry
);
}
return
prop
;
}
static
void
msi_delete_property
(
msi_property
*
prop
)
{
list_remove
(
&
prop
->
entry
);
msi_free
(
prop
->
key
);
msi_free
(
prop
->
value
);
msi_free
(
prop
);
}
static
void
msi_free_properties
(
MSIPACKAGE
*
package
)
{
int
i
;
for
(
i
=
0
;
i
<
PROPERTY_HASH_SIZE
;
i
++
)
{
while
(
!
list_empty
(
&
package
->
props
[
i
])
)
{
msi_property
*
prop
;
prop
=
LIST_ENTRY
(
list_head
(
&
package
->
props
[
i
]
),
msi_property
,
entry
);
msi_delete_property
(
prop
);
}
}
}
UINT
WINAPI
MsiSetPropertyA
(
MSIHANDLE
hInstall
,
LPCSTR
szName
,
LPCSTR
szValue
)
UINT
WINAPI
MsiSetPropertyA
(
MSIHANDLE
hInstall
,
LPCSTR
szName
,
LPCSTR
szValue
)
{
{
LPWSTR
szwName
=
NULL
,
szwValue
=
NULL
;
LPWSTR
szwName
=
NULL
,
szwValue
=
NULL
;
...
@@ -871,21 +925,7 @@ end:
...
@@ -871,21 +925,7 @@ end:
UINT
MSI_SetPropertyW
(
MSIPACKAGE
*
package
,
LPCWSTR
szName
,
LPCWSTR
szValue
)
UINT
MSI_SetPropertyW
(
MSIPACKAGE
*
package
,
LPCWSTR
szName
,
LPCWSTR
szValue
)
{
{
MSIQUERY
*
view
;
msi_property
*
prop
;
MSIRECORD
*
row
;
UINT
rc
;
DWORD
sz
=
0
;
static
const
WCHAR
Insert
[]
=
{
'I'
,
'N'
,
'S'
,
'E'
,
'R'
,
'T'
,
' '
,
'i'
,
'n'
,
't'
,
'o'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
' '
,
'('
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
','
,
'`'
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
,
'`'
,
')'
,
' '
,
'V'
,
'A'
,
'L'
,
'U'
,
'E'
,
'S'
,
' '
,
'('
,
'?'
,
','
,
'?'
,
')'
,
0
};
static
const
WCHAR
Update
[]
=
{
'U'
,
'P'
,
'D'
,
'A'
,
'T'
,
'E'
,
' '
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
' '
,
's'
,
'e'
,
't'
,
' '
,
'`'
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
,
'`'
,
' '
,
'='
,
' '
,
'?'
,
' '
,
'w'
,
'h'
,
'e'
,
'r'
,
'e'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
' '
,
'='
,
' '
,
'\''
,
'%'
,
's'
,
'\''
,
0
};
WCHAR
Query
[
1024
];
TRACE
(
"%p %s %s
\n
"
,
package
,
debugstr_w
(
szName
),
debugstr_w
(
szValue
));
TRACE
(
"%p %s %s
\n
"
,
package
,
debugstr_w
(
szName
),
debugstr_w
(
szValue
));
...
@@ -896,35 +936,22 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
...
@@ -896,35 +936,22 @@ UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
if
(
!
szName
[
0
])
if
(
!
szName
[
0
])
return
szValue
?
ERROR_FUNCTION_FAILED
:
ERROR_SUCCESS
;
return
szValue
?
ERROR_FUNCTION_FAILED
:
ERROR_SUCCESS
;
rc
=
MSI_GetPropertyW
(
package
,
szName
,
0
,
&
sz
);
prop
=
msi_prop_find
(
package
,
szName
);
if
(
rc
==
ERROR_MORE_DATA
||
rc
==
ERROR_SUCCESS
)
if
(
!
prop
)
{
prop
=
msi_prop_add
(
package
,
szName
);
sprintfW
(
Query
,
Update
,
szName
);
row
=
MSI_CreateRecord
(
1
);
MSI_RecordSetStringW
(
row
,
1
,
szValue
);
}
else
{
strcpyW
(
Query
,
Insert
);
row
=
MSI_CreateRecord
(
2
);
if
(
!
prop
)
MSI_RecordSetStringW
(
row
,
1
,
szName
);
return
ERROR_OUTOFMEMORY
;
MSI_RecordSetStringW
(
row
,
2
,
szValue
);
}
rc
=
MSI_DatabaseOpenViewW
(
package
->
db
,
Query
,
&
view
);
if
(
szValue
)
if
(
rc
==
ERROR_SUCCESS
)
{
{
rc
=
MSI_ViewExecute
(
view
,
row
);
msi_free
(
prop
->
value
);
prop
->
value
=
strdupW
(
szValue
);
MSI_ViewClose
(
view
);
msiobj_release
(
&
view
->
hdr
);
}
}
msiobj_release
(
&
row
->
hdr
);
else
msi_delete_property
(
prop
);
return
rc
;
return
ERROR_SUCCESS
;
}
}
UINT
WINAPI
MsiSetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPCWSTR
szValue
)
UINT
WINAPI
MsiSetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPCWSTR
szValue
)
...
@@ -940,59 +967,57 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue
...
@@ -940,59 +967,57 @@ UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue
return
ret
;
return
ret
;
}
}
static
MSIRECORD
*
MSI_GetPropertyRow
(
MSIPACKAGE
*
package
,
LPCWSTR
name
)
{
static
const
WCHAR
query
[]
=
{
'S'
,
'E'
,
'L'
,
'E'
,
'C'
,
'T'
,
' '
,
'`'
,
'V'
,
'a'
,
'l'
,
'u'
,
'e'
,
'`'
,
' '
,
'F'
,
'R'
,
'O'
,
'M'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
' '
,
'W'
,
'H'
,
'E'
,
'R'
,
'E'
,
' '
,
'`'
,
'_'
,
'P'
,
'r'
,
'o'
,
'p'
,
'e'
,
'r'
,
't'
,
'y'
,
'`'
,
'='
,
'\''
,
'%'
,
's'
,
'\''
,
0
};
if
(
!
name
||
!
name
[
0
])
return
NULL
;
return
MSI_QueryGetRecord
(
package
->
db
,
query
,
name
);
}
/* internal function, not compatible with MsiGetPropertyW */
/* internal function, not compatible with MsiGetPropertyW */
UINT
MSI_GetPropertyW
(
MSIPACKAGE
*
package
,
LPCWSTR
szName
,
UINT
MSI_GetPropertyW
(
MSIPACKAGE
*
package
,
LPCWSTR
szName
,
LPWSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
LPWSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
{
{
MSIRECORD
*
row
;
msi_property
*
prop
;
UINT
rc
=
ERROR_FUNCTION_FAILED
;
UINT
r
,
len
;
row
=
MSI_GetPropertyRow
(
package
,
szName
);
if
(
*
pchValueBuf
>
0
)
if
(
*
pchValueBuf
>
0
)
szValueBuf
[
0
]
=
0
;
szValueBuf
[
0
]
=
0
;
if
(
row
)
prop
=
msi_prop_find
(
package
,
szName
);
if
(
!
prop
)
{
{
rc
=
MSI_RecordGetStringW
(
row
,
1
,
szValueBuf
,
pchValueBuf
);
*
pchValueBuf
=
0
;
msiobj_release
(
&
row
->
hdr
);
TRACE
(
"property %s not found
\n
"
,
debugstr_w
(
szName
));
return
ERROR_FUNCTION_FAILED
;
}
}
if
(
rc
==
ERROR_SUCCESS
)
if
(
prop
->
value
)
TRACE
(
"returning %s for property %s
\n
"
,
debugstr_w
(
szValueBuf
),
{
debugstr_w
(
szName
));
len
=
lstrlenW
(
prop
->
value
);
else
if
(
rc
==
ERROR_MORE_DATA
)
lstrcpynW
(
szValueBuf
,
prop
->
value
,
*
pchValueBuf
);
TRACE
(
"need %li sized buffer for %s
\n
"
,
*
pchValueBuf
,
}
debugstr_w
(
szName
));
else
else
{
{
*
pchValueBuf
=
0
;
len
=
1
;
TRACE
(
"property %s not found
\n
"
,
debugstr_w
(
szName
));
if
(
*
pchValueBuf
>
0
)
szValueBuf
[
0
]
=
0
;
}
}
return
rc
;
TRACE
(
"%s -> %s
\n
"
,
debugstr_w
(
szName
),
debugstr_w
(
szValueBuf
));
if
(
*
pchValueBuf
<=
len
)
{
TRACE
(
"have %lu, need %lu -> ERROR_MORE_DATA
\n
"
,
*
pchValueBuf
,
len
);
r
=
ERROR_MORE_DATA
;
}
else
r
=
ERROR_SUCCESS
;
*
pchValueBuf
=
len
;
return
r
;
}
}
static
UINT
MSI_GetProperty
(
MSIHANDLE
handle
,
LPCWSTR
name
,
static
UINT
MSI_GetProperty
(
MSIHANDLE
handle
,
LPCWSTR
name
,
awstring
*
szValueBuf
,
DWORD
*
pchValueBuf
)
awstring
*
szValueBuf
,
DWORD
*
pchValueBuf
)
{
{
static
const
WCHAR
empty
[]
=
{
0
};
static
const
WCHAR
empty
[]
=
{
0
};
msi_property
*
prop
;
MSIPACKAGE
*
package
;
MSIPACKAGE
*
package
;
MSIRECORD
*
row
=
NULL
;
UINT
r
;
UINT
r
;
LPCWSTR
val
=
NULL
;
LPCWSTR
val
=
NULL
;
...
@@ -1006,17 +1031,15 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
...
@@ -1006,17 +1031,15 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
if
(
!
package
)
if
(
!
package
)
return
ERROR_INVALID_HANDLE
;
return
ERROR_INVALID_HANDLE
;
row
=
MSI_GetPropertyRow
(
package
,
name
);
prop
=
msi_prop_find
(
package
,
name
);
if
(
row
)
if
(
prop
)
val
=
MSI_RecordGetString
(
row
,
1
)
;
val
=
prop
->
value
;
if
(
!
val
)
if
(
!
val
)
val
=
empty
;
val
=
empty
;
r
=
msi_strcpy_to_awstring
(
val
,
szValueBuf
,
pchValueBuf
);
r
=
msi_strcpy_to_awstring
(
val
,
szValueBuf
,
pchValueBuf
);
if
(
row
)
msiobj_release
(
&
row
->
hdr
);
msiobj_release
(
&
package
->
hdr
);
msiobj_release
(
&
package
->
hdr
);
return
r
;
return
r
;
...
@@ -1040,7 +1063,7 @@ UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
...
@@ -1040,7 +1063,7 @@ UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
msi_free
(
name
);
msi_free
(
name
);
return
r
;
return
r
;
}
}
UINT
WINAPI
MsiGetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
UINT
WINAPI
MsiGetPropertyW
(
MSIHANDLE
hInstall
,
LPCWSTR
szName
,
LPWSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
LPWSTR
szValueBuf
,
DWORD
*
pchValueBuf
)
{
{
...
...
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