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
3d5b3ef9
Commit
3d5b3ef9
authored
Nov 05, 2007
by
James Hawkins
Committed by
Alexandre Julliard
Nov 05, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Reimplement MsiSourceListAddSourceEx to handle reordering the source list.
parent
d9a8f0b5
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
133 additions
and
86 deletions
+133
-86
source.c
dlls/msi/source.c
+133
-59
source.c
dlls/msi/tests/source.c
+0
-27
No files found.
dlls/msi/source.c
View file @
3d5b3ef9
...
...
@@ -46,9 +46,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
typedef
struct
tagMediaInfo
{
struct
list
entry
;
LPWSTR
path
;
WCHAR
szIndex
[
10
];
WCHAR
type
;
DWORD
index
;
}
media_info
;
static
UINT
OpenSourceKey
(
LPCWSTR
szProduct
,
HKEY
*
key
,
DWORD
dwOptions
,
BOOL
user
,
BOOL
create
)
...
...
@@ -131,43 +132,6 @@ static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
return
rc
;
}
static
UINT
find_given_source
(
HKEY
key
,
LPCWSTR
szSource
,
media_info
*
ss
)
{
DWORD
index
=
0
;
WCHAR
szIndex
[
10
];
DWORD
size
;
DWORD
val_size
;
LPWSTR
val
;
UINT
rc
=
ERROR_SUCCESS
;
while
(
rc
==
ERROR_SUCCESS
)
{
val
=
NULL
;
val_size
=
0
;
size
=
sizeof
(
szIndex
)
/
sizeof
(
szIndex
[
0
]);
rc
=
RegEnumValueW
(
key
,
index
,
szIndex
,
&
size
,
NULL
,
NULL
,
NULL
,
&
val_size
);
if
(
rc
!=
ERROR_NO_MORE_ITEMS
)
{
val
=
msi_alloc
(
val_size
);
RegEnumValueW
(
key
,
index
,
szIndex
,
&
size
,
NULL
,
NULL
,
(
LPBYTE
)
val
,
&
val_size
);
if
(
lstrcmpiW
(
szSource
,
val
)
==
0
)
{
ss
->
path
=
val
;
strcpyW
(
ss
->
szIndex
,
szIndex
);
break
;
}
else
strcpyW
(
ss
->
szIndex
,
szIndex
);
msi_free
(
val
);
index
++
;
}
}
return
rc
;
}
/******************************************************************
* MsiSourceListEnumSourcesA (MSI.@)
*/
...
...
@@ -578,6 +542,90 @@ UINT WINAPI MsiSourceListAddSourceExA(LPCSTR szProduct, LPCSTR szUserSid,
return
ret
;
}
static
void
free_source_list
(
struct
list
*
sourcelist
)
{
while
(
!
list_empty
(
sourcelist
))
{
media_info
*
info
=
LIST_ENTRY
(
list_head
(
sourcelist
),
media_info
,
entry
);
list_remove
(
&
info
->
entry
);
msi_free
(
info
->
path
);
msi_free
(
info
);
}
}
static
void
add_source_to_list
(
struct
list
*
sourcelist
,
media_info
*
info
)
{
media_info
*
iter
;
BOOL
found
=
FALSE
;
static
const
WCHAR
fmt
[]
=
{
'%'
,
'i'
,
0
};
if
(
list_empty
(
sourcelist
))
{
list_add_head
(
sourcelist
,
&
info
->
entry
);
return
;
}
LIST_FOR_EACH_ENTRY
(
iter
,
sourcelist
,
media_info
,
entry
)
{
if
(
!
found
&&
info
->
index
<
iter
->
index
)
{
found
=
TRUE
;
list_add_before
(
&
iter
->
entry
,
&
info
->
entry
);
}
/* update the rest of the list */
if
(
found
)
sprintfW
(
iter
->
szIndex
,
fmt
,
++
iter
->
index
);
}
if
(
!
found
)
list_add_after
(
&
iter
->
entry
,
&
info
->
entry
);
}
static
UINT
fill_source_list
(
struct
list
*
sourcelist
,
HKEY
sourcekey
,
DWORD
*
count
)
{
UINT
r
=
ERROR_SUCCESS
;
DWORD
index
=
0
;
WCHAR
name
[
10
];
DWORD
size
,
val_size
;
media_info
*
entry
;
*
count
=
0
;
while
(
r
==
ERROR_SUCCESS
)
{
size
=
sizeof
(
name
)
/
sizeof
(
name
[
0
]);
r
=
RegEnumValueW
(
sourcekey
,
index
,
name
,
&
size
,
NULL
,
NULL
,
NULL
,
&
val_size
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
entry
=
msi_alloc
(
sizeof
(
media_info
));
if
(
!
entry
)
goto
error
;
entry
->
path
=
msi_alloc
(
val_size
);
if
(
!
entry
->
path
)
goto
error
;
lstrcpyW
(
entry
->
szIndex
,
name
);
entry
->
index
=
atoiW
(
name
);
size
++
;
r
=
RegEnumValueW
(
sourcekey
,
index
,
name
,
&
size
,
NULL
,
NULL
,
(
LPBYTE
)
entry
->
path
,
&
val_size
);
if
(
r
!=
ERROR_SUCCESS
)
goto
error
;
index
=
++
(
*
count
);
add_source_to_list
(
sourcelist
,
entry
);
}
error:
*
count
=
-
1
;
free_source_list
(
sourcelist
);
return
ERROR_OUTOFMEMORY
;
}
/******************************************************************
* MsiSourceListAddSourceExW (MSI.@)
*/
...
...
@@ -588,12 +636,16 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
HKEY
sourcekey
;
HKEY
typekey
;
UINT
rc
;
media_info
source_struct
;
struct
list
sourcelist
;
media_info
*
info
;
WCHAR
squished_pc
[
GUID_SIZE
];
WCHAR
name
[
10
];
LPWSTR
source
;
LPCWSTR
postfix
;
DWORD
size
;
DWORD
size
,
count
;
static
const
WCHAR
fmt
[]
=
{
'%'
,
'i'
,
0
};
static
const
WCHAR
one
[]
=
{
'1'
,
0
};
static
const
WCHAR
backslash
[]
=
{
'\\'
,
0
};
static
const
WCHAR
forwardslash
[]
=
{
'/'
,
0
};
...
...
@@ -653,33 +705,55 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
lstrcatW
(
source
,
postfix
);
}
source_struct
.
szIndex
[
0
]
=
0
;
if
(
find_given_source
(
typekey
,
source
,
&
source_struct
)
==
ERROR_SUCCESS
)
list_init
(
&
sourcelist
);
rc
=
fill_source_list
(
&
sourcelist
,
typekey
,
&
count
);
if
(
rc
!=
ERROR_NO_MORE_ITEMS
)
return
rc
;
size
=
(
lstrlenW
(
source
)
+
1
)
*
sizeof
(
WCHAR
);
if
(
count
==
0
)
{
DWORD
current_index
=
atoiW
(
source_struct
.
szIndex
);
/* found the source */
if
(
dwIndex
>
0
&&
current_index
!=
dwIndex
)
FIXME
(
"Need to reorder the sources!
\n
"
);
msi_free
(
source_struct
.
path
);
rc
=
RegSetValueExW
(
typekey
,
one
,
0
,
REG_EXPAND_SZ
,
(
LPBYTE
)
source
,
size
);
goto
done
;
}
else
if
(
dwIndex
>
count
)
{
sprintfW
(
name
,
fmt
,
count
+
1
);
rc
=
RegSetValueExW
(
typekey
,
name
,
0
,
REG_EXPAND_SZ
,
(
LPBYTE
)
source
,
size
);
goto
done
;
}
else
{
DWORD
current_index
=
0
;
static
const
WCHAR
fmt
[]
=
{
'%'
,
'i'
,
0
};
DWORD
size
=
lstrlenW
(
source
)
*
sizeof
(
WCHAR
)
;
/* add to the end of the list */
if
(
dwIndex
==
0
)
dwIndex
=
count
+
1
;
if
(
source_struct
.
szIndex
[
0
])
current_index
=
atoiW
(
source_struct
.
szIndex
);
/* new source */
if
(
dwIndex
>
0
&&
dwIndex
<
current_index
)
FIXME
(
"Need to reorder the sources!
\n
"
);
sprintfW
(
name
,
fmt
,
dwIndex
);
info
=
msi_alloc
(
sizeof
(
media_info
));
if
(
!
info
)
{
rc
=
ERROR_OUTOFMEMORY
;
goto
done
;
}
current_index
++
;
sprintfW
(
source_struct
.
szIndex
,
fmt
,
current_index
);
rc
=
RegSetValueExW
(
typekey
,
source_struct
.
szIndex
,
0
,
REG_EXPAND_SZ
,
(
const
BYTE
*
)
source
,
size
);
info
->
path
=
strdupW
(
source
);
lstrcpyW
(
info
->
szIndex
,
name
);
info
->
index
=
dwIndex
;
add_source_to_list
(
&
sourcelist
,
info
);
LIST_FOR_EACH_ENTRY
(
info
,
&
sourcelist
,
media_info
,
entry
)
{
size
=
(
lstrlenW
(
info
->
path
)
+
1
)
*
sizeof
(
WCHAR
);
rc
=
RegSetValueExW
(
typekey
,
info
->
szIndex
,
0
,
REG_EXPAND_SZ
,
(
LPBYTE
)
info
->
path
,
size
);
if
(
rc
!=
ERROR_SUCCESS
)
goto
done
;
}
}
done:
free_source_list
(
&
sourcelist
);
msi_free
(
source
);
RegCloseKey
(
typekey
);
RegCloseKey
(
sourcekey
);
...
...
dlls/msi/tests/source.c
View file @
3d5b3ef9
...
...
@@ -449,29 +449,20 @@ static void test_MsiSourceListAddSourceEx(void)
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"1"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"third/"
),
"Expected 'third/', got %s
\n
"
,
value
);
ok
(
size
==
7
,
"Expected 7, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"2"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"C:
\\
source/"
),
"Expected 'C:
\\
source/', got %s
\n
"
,
value
);
ok
(
size
==
11
,
"Expected 11, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"3"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"another/"
),
"Expected 'another/', got %s
\n
"
,
value
);
ok
(
size
==
9
,
"Expected 9, got %d
\n
"
,
size
);
}
/* add another source, index > N */
r
=
pMsiSourceListAddSourceExA
(
prodcode
,
usersid
,
...
...
@@ -482,29 +473,20 @@ static void test_MsiSourceListAddSourceEx(void)
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"1"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"third/"
),
"Expected 'third/', got %s
\n
"
,
value
);
ok
(
size
==
7
,
"Expected 7, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"2"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"C:
\\
source/"
),
"Expected 'C:
\\
source/', got %s
\n
"
,
value
);
ok
(
size
==
11
,
"Expected 11, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"3"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"another/"
),
"Expected 'another/', got %s
\n
"
,
value
);
ok
(
size
==
9
,
"Expected 9, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"4"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
...
...
@@ -536,29 +518,20 @@ static void test_MsiSourceListAddSourceEx(void)
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"1"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"third/"
),
"Expected 'third/', got %s
\n
"
,
value
);
ok
(
size
==
7
,
"Expected 7, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"2"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"C:
\\
source/"
),
"Expected 'C:
\\
source/', got %s
\n
"
,
value
);
ok
(
size
==
11
,
"Expected 11, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"3"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
ok
(
res
==
ERROR_SUCCESS
,
"Expected ERROR_SUCCESS, got %d
\n
"
,
res
);
todo_wine
{
ok
(
!
lstrcmpA
(
value
,
"another/"
),
"Expected 'another/', got %s
\n
"
,
value
);
ok
(
size
==
9
,
"Expected 9, got %d
\n
"
,
size
);
}
size
=
MAX_PATH
;
res
=
RegQueryValueExA
(
url
,
"4"
,
NULL
,
NULL
,
(
LPBYTE
)
value
,
&
size
);
...
...
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