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
a277ab8e
Commit
a277ab8e
authored
Mar 05, 2024
by
Zebediah Figura
Committed by
Alexandre Julliard
Mar 07, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Reimplement pasting from a CIDA without ISFHelper.
parent
1c95001f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
86 additions
and
86 deletions
+86
-86
shlview_cmenu.c
dlls/shell32/shlview_cmenu.c
+86
-86
No files found.
dlls/shell32/shlview_cmenu.c
View file @
a277ab8e
...
...
@@ -345,60 +345,65 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut)
}
}
static
HRESULT
paste_pidls
(
IShellFolder
*
dst_folder
,
const
ITEMIDLIST
*
src_parent
,
ITEMIDLIST
**
pidls
,
unsigned
int
count
)
static
HRESULT
get_data_format
(
IDataObject
*
data
,
UINT
cf
,
STGMEDIUM
*
medium
)
{
IShellFolder
*
src_folder
;
HRESULT
hr
=
S_OK
;
FORMATETC
format
;
InitFormatEtc
(
format
,
cf
,
TYMED_HGLOBAL
);
return
IDataObject_GetData
(
data
,
&
format
,
medium
);
}
static
WCHAR
*
build_source_paths
(
ITEMIDLIST
*
root_pidl
,
ITEMIDLIST
**
pidls
,
unsigned
int
count
)
{
WCHAR
root_path
[
MAX_PATH
],
pidl_path
[
MAX_PATH
];
size_t
size
=
1
,
pos
=
0
,
root_len
;
WCHAR
*
paths
;
if
(
FAILED
(
hr
=
SHBindToObject
(
NULL
,
src_parent
,
NULL
,
&
IID_IShellFolder
,
(
void
**
)
&
src_folder
)
))
if
(
!
SHGetPathFromIDListW
(
root_pidl
,
root_path
))
{
ERR
(
"Failed to get
folder from source PIDL, hr %#lx.
\n
"
,
hr
);
return
hr
;
ERR
(
"Failed to get
source root path.
\n
"
);
return
NULL
;
}
root_len
=
wcslen
(
root_path
);
for
(
unsigned
int
i
=
0
;
SUCCEEDED
(
hr
)
&&
i
<
count
;
i
++
)
for
(
unsigned
int
i
=
0
;
i
<
count
;
++
i
)
{
ISFHelper
*
psfhlpdst
=
NULL
,
*
psfhlpsrc
=
NULL
;
if
(
!
_ILIsValue
(
pidls
[
i
])
&&
!
_ILIsFolder
(
pidls
[
i
]))
ERR
(
"Unexpected child pidl type.
\n
"
);
hr
=
IShellFolder_QueryInterface
(
dst_folder
,
&
IID_ISFHelper
,
(
void
**
)
&
psfhlpdst
);
if
(
SUCCEEDED
(
hr
))
hr
=
IShellFolder_QueryInterface
(
src_folder
,
&
IID_ISFHelper
,
(
void
**
)
&
psfhlpsrc
);
if
(
psfhlpdst
&&
psfhlpsrc
)
{
hr
=
ISFHelper_CopyItems
(
psfhlpdst
,
src_folder
,
1
,
(
LPCITEMIDLIST
*
)
&
pidls
[
i
]);
/* FIXME handle move
ISFHelper_DeleteItems(psfhlpsrc, 1, &pidl_item);
*/
}
if
(
psfhlpdst
)
ISFHelper_Release
(
psfhlpdst
);
if
(
psfhlpsrc
)
ISFHelper_Release
(
psfhlpsrc
);
_ILSimpleGetTextW
(
pidls
[
i
],
pidl_path
,
ARRAY_SIZE
(
pidl_path
));
size
+=
root_len
+
1
+
wcslen
(
pidl_path
)
+
1
;
}
IShellFolder_Release
(
src_folder
);
return
hr
;
}
paths
=
malloc
(
size
*
sizeof
(
WCHAR
));
static
HRESULT
get_data_format
(
IDataObject
*
data
,
UINT
cf
,
STGMEDIUM
*
medium
)
{
FORMATETC
format
;
for
(
unsigned
int
i
=
0
;
i
<
count
;
++
i
)
{
if
(
!
_ILIsValue
(
pidls
[
i
])
&&
!
_ILIsFolder
(
pidls
[
i
]))
ERR
(
"Unexpected child pidl type.
\n
"
);
memcpy
(
paths
+
pos
,
root_path
,
root_len
*
sizeof
(
WCHAR
));
pos
+=
root_len
;
paths
[
pos
++
]
=
'\\'
;
_ILSimpleGetTextW
(
pidls
[
i
],
paths
+
pos
,
size
-
pos
);
pos
+=
wcslen
(
paths
+
pos
)
+
1
;
}
paths
[
pos
++
]
=
0
;
InitFormatEtc
(
format
,
cf
,
TYMED_HGLOBAL
);
return
IDataObject_GetData
(
data
,
&
format
,
medium
);
return
paths
;
}
static
HRESULT
do_paste
(
ContextMenu
*
menu
,
HWND
hwnd
)
{
IPersistFolder2
*
dst_persist
;
IShellFolder
*
dst_folder
;
WCHAR
dst_path
[
MAX_PATH
];
SHFILEOPSTRUCTW
op
=
{
0
};
ITEMIDLIST
*
dst_pidl
;
IDataObject
*
data
;
HRESULT
hr
;
STGMEDIUM
medium
;
if
(
FAILED
(
hr
=
OleGetClipboard
(
&
data
)))
return
hr
;
int
ret
;
if
(
menu
->
cidl
)
{
...
...
@@ -415,71 +420,66 @@ static HRESULT do_paste(ContextMenu *menu, HWND hwnd)
IShellFolder_AddRef
(
dst_folder
);
}
if
(
FAILED
(
hr
=
IShellFolder_QueryInterface
(
dst_folder
,
&
IID_IPersistFolder2
,
(
void
**
)
&
dst_persist
)))
{
WARN
(
"Failed to get IPersistFolder2, hr %#lx.
\n
"
,
hr
);
return
hr
;
}
hr
=
IPersistFolder2_GetCurFolder
(
dst_persist
,
&
dst_pidl
);
IPersistFolder2_Release
(
dst_persist
);
if
(
FAILED
(
hr
))
{
ERR
(
"Failed to get dst folder pidl, hr %#lx.
\n
"
,
hr
);
return
hr
;
}
if
(
!
SHGetPathFromIDListW
(
dst_pidl
,
dst_path
))
{
ERR
(
"Failed to get path, hr %#lx.
\n
"
,
hr
);
ILFree
(
dst_pidl
);
return
E_FAIL
;
}
ILFree
(
dst_pidl
);
op
.
hwnd
=
hwnd
;
op
.
wFunc
=
FO_COPY
;
op
.
pTo
=
dst_path
;
op
.
fFlags
=
FOF_ALLOWUNDO
;
if
(
FAILED
(
hr
=
OleGetClipboard
(
&
data
)))
return
hr
;
if
(
SUCCEEDED
(
get_data_format
(
data
,
RegisterClipboardFormatW
(
CFSTR_SHELLIDLISTW
),
&
medium
)))
{
CIDA
*
cida
=
GlobalLock
(
medium
.
hGlobal
);
ITEMIDLIST
**
pidls
;
ITEMIDLIST
*
pidl
;
const
CIDA
*
cida
=
GlobalLock
(
medium
.
hGlobal
);
ITEMIDLIST
**
pidls
,
*
root_pidl
;
WCHAR
*
src_paths
;
pidls
=
_ILCopyCidaToaPidl
(
&
root_pidl
,
cida
);
if
(
cida
)
if
(
(
src_paths
=
build_source_paths
(
root_pidl
,
pidls
,
cida
->
cidl
))
)
{
pidls
=
_ILCopyCidaToaPidl
(
&
pidl
,
cida
);
if
(
pidls
)
{
hr
=
paste_pidls
(
dst_folder
,
pidl
,
pidls
,
cida
->
cidl
);
_ILFreeaPidl
(
pidls
,
cida
->
cidl
);
SHFree
(
pidl
);
}
else
op
.
pFrom
=
src_paths
;
if
((
ret
=
SHFileOperationW
(
&
op
)))
{
hr
=
HRESULT_FROM_WIN32
(
GetLastError
());
WARN
(
"Failed to copy, ret %d.
\n
"
,
ret
);
hr
=
E_FAIL
;
}
GlobalUnlock
(
medium
.
hGlobal
);
}
else
{
hr
=
HRESULT_FROM_WIN32
(
GetLastError
());
}
free
(
src_paths
);
_ILFreeaPidl
(
pidls
,
cida
->
cidl
);
ILFree
(
root_pidl
);
GlobalUnlock
(
medium
.
hGlobal
);
ReleaseStgMedium
(
&
medium
);
}
else
if
(
SUCCEEDED
(
get_data_format
(
data
,
CF_HDROP
,
&
medium
)))
{
const
DROPFILES
*
dropfiles
=
GlobalLock
(
medium
.
hGlobal
);
IPersistFolder2
*
dst_persist
;
SHFILEOPSTRUCTW
op
=
{
0
};
WCHAR
dst_path
[
MAX_PATH
];
ITEMIDLIST
*
dst_pidl
;
int
ret
;
if
(
FAILED
(
hr
=
IShellFolder_QueryInterface
(
dst_folder
,
&
IID_IPersistFolder2
,
(
void
**
)
&
dst_persist
)))
{
WARN
(
"Failed to get IPersistFolder2, hr %#lx.
\n
"
,
hr
);
IDataObject_Release
(
data
);
return
hr
;
}
hr
=
IPersistFolder2_GetCurFolder
(
dst_persist
,
&
dst_pidl
);
IPersistFolder2_Release
(
dst_persist
);
if
(
FAILED
(
hr
))
{
ERR
(
"Failed to get dst folder pidl, hr %#lx.
\n
"
,
hr
);
IDataObject_Release
(
data
);
return
hr
;
}
if
(
!
SHGetPathFromIDListW
(
dst_pidl
,
dst_path
))
{
ERR
(
"Failed to get path, hr %#lx.
\n
"
,
hr
);
ILFree
(
dst_pidl
);
IDataObject_Release
(
data
);
return
E_FAIL
;
}
op
.
hwnd
=
hwnd
;
op
.
wFunc
=
FO_COPY
;
op
.
pFrom
=
(
const
WCHAR
*
)((
const
char
*
)
dropfiles
+
dropfiles
->
pFiles
);
op
.
pTo
=
dst_path
;
op
.
fFlags
=
FOF_ALLOWUNDO
;
if
((
ret
=
SHFileOperationW
(
&
op
)))
{
WARN
(
"Failed to copy, ret %d.
\n
"
,
ret
);
...
...
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