Index: ui/base/clipboard/clipboard_util_win.cc |
diff --git a/ui/base/clipboard/clipboard_util_win.cc b/ui/base/clipboard/clipboard_util_win.cc |
index aa61e6a43d60cc1de330524c2d231c4d1bca3502..77da99c465811383df61494d9d3ac80c7475a207 100644 |
--- a/ui/base/clipboard/clipboard_util_win.cc |
+++ b/ui/base/clipboard/clipboard_util_win.cc |
@@ -12,10 +12,13 @@ |
#include "base/logging.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
+#include "base/strings/sys_string_conversions.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/win/scoped_hglobal.h" |
+#include "net/base/filename_util.h" |
#include "ui/base/clipboard/clipboard.h" |
#include "ui/base/clipboard/custom_data_helper.h" |
+#include "url/gurl.h" |
namespace ui { |
@@ -34,103 +37,57 @@ bool GetData(IDataObject* data_object, |
} |
bool GetUrlFromHDrop(IDataObject* data_object, |
- base::string16* url, |
+ GURL* url, |
base::string16* title) { |
DCHECK(data_object && url && title); |
+ bool success = false; |
STGMEDIUM medium; |
if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) |
return false; |
- HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); |
- |
- if (!hdrop) |
- return false; |
- |
- bool success = false; |
- wchar_t filename[MAX_PATH]; |
- if (DragQueryFileW(hdrop, 0, filename, arraysize(filename))) { |
- wchar_t url_buffer[INTERNET_MAX_URL_LENGTH]; |
- if (0 == _wcsicmp(PathFindExtensionW(filename), L".url") && |
- GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, url_buffer, |
- arraysize(url_buffer), filename)) { |
- url->assign(url_buffer); |
- PathRemoveExtension(filename); |
- title->assign(PathFindFileName(filename)); |
- success = true; |
+ { |
+ base::win::ScopedHGlobal<HDROP> hdrop(medium.hGlobal); |
+ |
+ if (!hdrop.get()) |
+ return false; |
+ |
+ wchar_t filename[MAX_PATH]; |
+ if (DragQueryFileW(hdrop.get(), 0, filename, arraysize(filename))) { |
+ wchar_t url_buffer[INTERNET_MAX_URL_LENGTH]; |
+ if (0 == _wcsicmp(PathFindExtensionW(filename), L".url") && |
+ GetPrivateProfileStringW(L"InternetShortcut", |
+ L"url", |
+ 0, |
+ url_buffer, |
+ arraysize(url_buffer), |
+ filename)) { |
+ *url = GURL(url_buffer); |
+ PathRemoveExtension(filename); |
+ title->assign(PathFindFileName(filename)); |
+ success = url->is_valid(); |
+ } |
} |
} |
- DragFinish(hdrop); |
- GlobalUnlock(medium.hGlobal); |
- // We don't need to call ReleaseStgMedium here because as far as I can tell, |
- // DragFinish frees the hGlobal for us. |
+ ReleaseStgMedium(&medium); |
return success; |
} |
void SplitUrlAndTitle(const base::string16& str, |
- base::string16* url, |
+ GURL* url, |
base::string16* title) { |
DCHECK(url && title); |
size_t newline_pos = str.find('\n'); |
if (newline_pos != base::string16::npos) { |
- url->assign(str, 0, newline_pos); |
+ *url = GURL(base::string16(str, 0, newline_pos)); |
title->assign(str, newline_pos + 1, base::string16::npos); |
} else { |
- url->assign(str); |
+ *url = GURL(str); |
title->assign(str); |
} |
} |
-bool GetFileUrl(IDataObject* data_object, base::string16* url, |
- base::string16* title) { |
- STGMEDIUM store; |
- if (GetData(data_object, Clipboard::GetFilenameWFormatType(), &store)) { |
- bool success = false; |
- { |
- // filename using unicode |
- base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
- if (data.get() && data.get()[0] && |
- (PathFileExists(data.get()) || PathIsUNC(data.get()))) { |
- wchar_t file_url[INTERNET_MAX_URL_LENGTH]; |
- DWORD file_url_len = arraysize(file_url); |
- if (SUCCEEDED(::UrlCreateFromPathW(data.get(), file_url, &file_url_len, |
- 0))) { |
- url->assign(file_url); |
- title->assign(file_url); |
- success = true; |
- } |
- } |
- } |
- ReleaseStgMedium(&store); |
- if (success) |
- return true; |
- } |
- |
- if (GetData(data_object, Clipboard::GetFilenameFormatType(), &store)) { |
- bool success = false; |
- { |
- // filename using ascii |
- base::win::ScopedHGlobal<char> data(store.hGlobal); |
- if (data.get() && data.get()[0] && (PathFileExistsA(data.get()) || |
- PathIsUNCA(data.get()))) { |
- char file_url[INTERNET_MAX_URL_LENGTH]; |
- DWORD file_url_len = arraysize(file_url); |
- if (SUCCEEDED(::UrlCreateFromPathA(data.get(), file_url, &file_url_len, |
- 0))) { |
- url->assign(base::UTF8ToWide(file_url)); |
- title->assign(*url); |
- success = true; |
- } |
- } |
- } |
- ReleaseStgMedium(&store); |
- if (success) |
- return true; |
- } |
- return false; |
-} |
- |
} // namespace |
bool ClipboardUtil::HasUrl(IDataObject* data_object, bool convert_filenames) { |
@@ -138,14 +95,14 @@ bool ClipboardUtil::HasUrl(IDataObject* data_object, bool convert_filenames) { |
return HasData(data_object, Clipboard::GetMozUrlFormatType()) || |
HasData(data_object, Clipboard::GetUrlWFormatType()) || |
HasData(data_object, Clipboard::GetUrlFormatType()) || |
- (convert_filenames && ( |
- HasData(data_object, Clipboard::GetFilenameWFormatType()) || |
- HasData(data_object, Clipboard::GetFilenameFormatType()))); |
+ (convert_filenames && HasFilenames(data_object)); |
} |
bool ClipboardUtil::HasFilenames(IDataObject* data_object) { |
DCHECK(data_object); |
- return HasData(data_object, Clipboard::GetCFHDropFormatType()); |
+ return HasData(data_object, Clipboard::GetCFHDropFormatType()) || |
+ HasData(data_object, Clipboard::GetFilenameWFormatType()) || |
+ HasData(data_object, Clipboard::GetFilenameFormatType()); |
} |
bool ClipboardUtil::HasFileContents(IDataObject* data_object) { |
@@ -166,7 +123,9 @@ bool ClipboardUtil::HasPlainText(IDataObject* data_object) { |
} |
bool ClipboardUtil::GetUrl(IDataObject* data_object, |
- base::string16* url, base::string16* title, bool convert_filenames) { |
+ GURL* url, |
+ base::string16* title, |
+ bool convert_filenames) { |
DCHECK(data_object && url && title); |
if (!HasUrl(data_object, convert_filenames)) |
return false; |
@@ -180,28 +139,33 @@ bool ClipboardUtil::GetUrl(IDataObject* data_object, |
GetData(data_object, Clipboard::GetUrlWFormatType(), &store)) { |
{ |
// Mozilla URL format or unicode URL |
- base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
+ base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal); |
SplitUrlAndTitle(data.get(), url, title); |
} |
ReleaseStgMedium(&store); |
- return true; |
+ return url->is_valid(); |
} |
if (GetData(data_object, Clipboard::GetUrlFormatType(), &store)) { |
{ |
// URL using ascii |
- base::win::ScopedHGlobal<char> data(store.hGlobal); |
+ base::win::ScopedHGlobal<char*> data(store.hGlobal); |
SplitUrlAndTitle(base::UTF8ToWide(data.get()), url, title); |
} |
ReleaseStgMedium(&store); |
- return true; |
+ return url->is_valid(); |
} |
if (convert_filenames) { |
- return GetFileUrl(data_object, url, title); |
- } else { |
- return false; |
+ std::vector<base::string16> filenames; |
+ if (!GetFilenames(data_object, &filenames)) |
+ return false; |
+ DCHECK_GT(filenames.size(), 0U); |
+ *url = net::FilePathToFileURL(base::FilePath(filenames[0])); |
+ return url->is_valid(); |
} |
+ |
+ return false; |
} |
bool ClipboardUtil::GetFilenames(IDataObject* data_object, |
@@ -211,27 +175,48 @@ bool ClipboardUtil::GetFilenames(IDataObject* data_object, |
return false; |
STGMEDIUM medium; |
- if (!GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) |
- return false; |
+ if (GetData(data_object, Clipboard::GetCFHDropFormatType(), &medium)) { |
+ { |
+ base::win::ScopedHGlobal<HDROP> hdrop(medium.hGlobal); |
+ if (!hdrop.get()) |
+ return false; |
+ |
+ const int kMaxFilenameLen = 4096; |
+ const unsigned num_files = DragQueryFileW(hdrop.get(), 0xffffffff, 0, 0); |
+ for (unsigned int i = 0; i < num_files; ++i) { |
+ wchar_t filename[kMaxFilenameLen]; |
+ if (!DragQueryFileW(hdrop.get(), i, filename, kMaxFilenameLen)) |
+ continue; |
+ filenames->push_back(filename); |
+ } |
+ } |
+ ReleaseStgMedium(&medium); |
+ return true; |
+ } |
- HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); |
- if (!hdrop) |
- return false; |
+ if (GetData(data_object, Clipboard::GetFilenameWFormatType(), &medium)) { |
+ { |
+ // filename using unicode |
+ base::win::ScopedHGlobal<wchar_t*> data(medium.hGlobal); |
+ if (data.get() && data.get()[0]) |
+ filenames->push_back(data.get()); |
+ } |
+ ReleaseStgMedium(&medium); |
+ return true; |
+ } |
- const int kMaxFilenameLen = 4096; |
- const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0); |
- for (unsigned int i = 0; i < num_files; ++i) { |
- wchar_t filename[kMaxFilenameLen]; |
- if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen)) |
- continue; |
- filenames->push_back(filename); |
+ if (GetData(data_object, Clipboard::GetFilenameFormatType(), &medium)) { |
+ { |
+ // filename using ascii |
+ base::win::ScopedHGlobal<char*> data(medium.hGlobal); |
+ if (data.get() && data.get()[0]) |
+ filenames->push_back(base::SysNativeMBToWide(data.get())); |
+ } |
+ ReleaseStgMedium(&medium); |
+ return true; |
} |
- DragFinish(hdrop); |
- GlobalUnlock(medium.hGlobal); |
- // We don't need to call ReleaseStgMedium here because as far as I can tell, |
- // DragFinish frees the hGlobal for us. |
- return true; |
+ return false; |
} |
bool ClipboardUtil::GetPlainText(IDataObject* data_object, |
@@ -244,7 +229,7 @@ bool ClipboardUtil::GetPlainText(IDataObject* data_object, |
if (GetData(data_object, Clipboard::GetPlainTextWFormatType(), &store)) { |
{ |
// Unicode text |
- base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
+ base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal); |
plain_text->assign(data.get()); |
} |
ReleaseStgMedium(&store); |
@@ -254,7 +239,7 @@ bool ClipboardUtil::GetPlainText(IDataObject* data_object, |
if (GetData(data_object, Clipboard::GetPlainTextFormatType(), &store)) { |
{ |
// ascii text |
- base::win::ScopedHGlobal<char> data(store.hGlobal); |
+ base::win::ScopedHGlobal<char*> data(store.hGlobal); |
plain_text->assign(base::UTF8ToWide(data.get())); |
} |
ReleaseStgMedium(&store); |
@@ -263,8 +248,13 @@ bool ClipboardUtil::GetPlainText(IDataObject* data_object, |
// If a file is dropped on the window, it does not provide either of the |
// plain text formats, so here we try to forcibly get a url. |
+ GURL url; |
base::string16 title; |
- return GetUrl(data_object, plain_text, &title, false); |
+ if (GetUrl(data_object, &url, &title, false)) { |
+ *plain_text = base::UTF8ToUTF16(url.spec()); |
+ return true; |
+ } |
+ return false; |
} |
bool ClipboardUtil::GetHtml(IDataObject* data_object, |
@@ -276,7 +266,7 @@ bool ClipboardUtil::GetHtml(IDataObject* data_object, |
GetData(data_object, Clipboard::GetHtmlFormatType(), &store)) { |
{ |
// MS CF html |
- base::win::ScopedHGlobal<char> data(store.hGlobal); |
+ base::win::ScopedHGlobal<char*> data(store.hGlobal); |
std::string html_utf8; |
CFHtmlToHtml(std::string(data.get(), data.Size()), &html_utf8, base_url); |
@@ -294,7 +284,7 @@ bool ClipboardUtil::GetHtml(IDataObject* data_object, |
{ |
// text/html |
- base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); |
+ base::win::ScopedHGlobal<wchar_t*> data(store.hGlobal); |
html->assign(data.get()); |
} |
ReleaseStgMedium(&store); |
@@ -314,7 +304,7 @@ bool ClipboardUtil::GetFileContents(IDataObject* data_object, |
if (GetData( |
data_object, Clipboard::GetFileContentZeroFormatType(), &content)) { |
if (TYMED_HGLOBAL == content.tymed) { |
- base::win::ScopedHGlobal<char> data(content.hGlobal); |
+ base::win::ScopedHGlobal<char*> data(content.hGlobal); |
file_contents->assign(data.get(), data.Size()); |
} |
ReleaseStgMedium(&content); |
@@ -325,7 +315,7 @@ bool ClipboardUtil::GetFileContents(IDataObject* data_object, |
Clipboard::GetFileDescriptorFormatType(), |
&description)) { |
{ |
- base::win::ScopedHGlobal<FILEGROUPDESCRIPTOR> fgd(description.hGlobal); |
+ base::win::ScopedHGlobal<FILEGROUPDESCRIPTOR*> fgd(description.hGlobal); |
// We expect there to be at least one file in here. |
DCHECK_GE(fgd->cItems, 1u); |
filename->assign(fgd->fgd[0].cFileName); |
@@ -346,7 +336,7 @@ bool ClipboardUtil::GetWebCustomData( |
STGMEDIUM store; |
if (GetData(data_object, Clipboard::GetWebCustomDataFormatType(), &store)) { |
{ |
- base::win::ScopedHGlobal<char> data(store.hGlobal); |
+ base::win::ScopedHGlobal<char*> data(store.hGlobal); |
ReadCustomDataIntoMap(data.get(), data.Size(), custom_data); |
} |
ReleaseStgMedium(&store); |