Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: app/os_exchange_data_provider_win.cc

Issue 351029: Support dragging a virtual file out of the browser. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « app/os_exchange_data_provider_win.h ('k') | app/os_exchange_data_win_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "app/os_exchange_data_provider_win.h" 5 #include "app/os_exchange_data_provider_win.h"
6 6
7 #include "app/clipboard/clipboard_util_win.h" 7 #include "app/clipboard/clipboard_util_win.h"
8 #include "app/l10n_util.h" 8 #include "app/l10n_util.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/i18n/file_util_icu.h" 10 #include "base/i18n/file_util_icu.h"
(...skipping 11 matching lines...) Expand all
22 // string version does. 22 // string version does.
23 static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes); 23 static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes);
24 static STGMEDIUM* GetStorageForWString(const std::wstring& data); 24 static STGMEDIUM* GetStorageForWString(const std::wstring& data);
25 static STGMEDIUM* GetStorageForString(const std::string& data); 25 static STGMEDIUM* GetStorageForString(const std::string& data);
26 // Creates the contents of an Internet Shortcut file for the given URL. 26 // Creates the contents of an Internet Shortcut file for the given URL.
27 static void GetInternetShortcutFileContents(const GURL& url, std::string* data); 27 static void GetInternetShortcutFileContents(const GURL& url, std::string* data);
28 // Creates a valid file name given a suggested title and URL. 28 // Creates a valid file name given a suggested title and URL.
29 static void CreateValidFileNameFromTitle(const GURL& url, 29 static void CreateValidFileNameFromTitle(const GURL& url,
30 const std::wstring& title, 30 const std::wstring& title,
31 std::wstring* validated); 31 std::wstring* validated);
32 // Creates a new STGMEDIUM object to hold a file.
33 static STGMEDIUM* GetStorageForFileName(const std::wstring& full_path);
32 // Creates a File Descriptor for the creation of a file to the given URL and 34 // Creates a File Descriptor for the creation of a file to the given URL and
33 // returns a handle to it. 35 // returns a handle to it.
34 static STGMEDIUM* GetStorageForFileDescriptor( 36 static STGMEDIUM* GetStorageForFileDescriptor(
35 const std::wstring& valid_file_name); 37 const std::wstring& valid_file_name);
36 38
37 /////////////////////////////////////////////////////////////////////////////// 39 ///////////////////////////////////////////////////////////////////////////////
38 // FormatEtcEnumerator 40 // FormatEtcEnumerator
39 41
40 // 42 //
41 // This object implements an enumeration interface. The existence of an 43 // This object implements an enumeration interface. The existence of an
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 GURL gurl(plain_text); 221 GURL gurl(plain_text);
220 if (gurl.is_valid()) { 222 if (gurl.is_valid()) {
221 *url = gurl; 223 *url = gurl;
222 return true; 224 return true;
223 } 225 }
224 } 226 }
225 return false; 227 return false;
226 } 228 }
227 229
228 // static 230 // static
231 DataObjectImpl* OSExchangeDataProviderWin::GetDataObjectImpl(
232 const OSExchangeData& data) {
233 return static_cast<const OSExchangeDataProviderWin*>(&data.provider())->
234 data_.get();
235 }
236
237 // static
229 IDataObject* OSExchangeDataProviderWin::GetIDataObject( 238 IDataObject* OSExchangeDataProviderWin::GetIDataObject(
230 const OSExchangeData& data) { 239 const OSExchangeData& data) {
231 return static_cast<const OSExchangeDataProviderWin&>(data.provider()). 240 return static_cast<const OSExchangeDataProviderWin*>(&data.provider())->
232 data_object(); 241 data_object();
233 } 242 }
234 243
244 // static
245 IAsyncOperation* OSExchangeDataProviderWin::GetIAsyncOperation(
246 const OSExchangeData& data) {
247 return static_cast<const OSExchangeDataProviderWin*>(&data.provider())->
248 async_operation();
249 }
250
235 OSExchangeDataProviderWin::OSExchangeDataProviderWin(IDataObject* source) 251 OSExchangeDataProviderWin::OSExchangeDataProviderWin(IDataObject* source)
236 : data_(new DataObjectImpl()), 252 : data_(new DataObjectImpl()),
237 source_object_(source) { 253 source_object_(source) {
238 } 254 }
239 255
240 OSExchangeDataProviderWin::OSExchangeDataProviderWin() 256 OSExchangeDataProviderWin::OSExchangeDataProviderWin()
241 : data_(new DataObjectImpl()), 257 : data_(new DataObjectImpl()),
242 source_object_(data_.get()) { 258 source_object_(data_.get()) {
243 } 259 }
244 260
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // least preferable). 309 // least preferable).
294 storage = GetStorageForWString(UTF8ToWide(url.spec())); 310 storage = GetStorageForWString(UTF8ToWide(url.spec()));
295 data_->contents_.push_back( 311 data_->contents_.push_back(
296 new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage)); 312 new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage));
297 storage = GetStorageForString(url.spec()); 313 storage = GetStorageForString(url.spec());
298 data_->contents_.push_back( 314 data_->contents_.push_back(
299 new DataObjectImpl::StoredDataInfo(CF_TEXT, storage)); 315 new DataObjectImpl::StoredDataInfo(CF_TEXT, storage));
300 } 316 }
301 317
302 void OSExchangeDataProviderWin::SetFilename(const std::wstring& full_path) { 318 void OSExchangeDataProviderWin::SetFilename(const std::wstring& full_path) {
303 const size_t drop_size = sizeof(DROPFILES); 319 STGMEDIUM* storage = GetStorageForFileName(full_path);
304 const size_t bytes = drop_size + (full_path.length() + 2) * sizeof(wchar_t);
305 HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes);
306 if (!hdata)
307 return;
308
309 ScopedHGlobal<DROPFILES> locked_mem(hdata);
310 DROPFILES* drop_files = locked_mem.get();
311 drop_files->pFiles = sizeof(DROPFILES);
312 drop_files->fWide = TRUE;
313 wchar_t* data = reinterpret_cast<wchar_t*>((BYTE*)(drop_files) + drop_size);
314 const size_t copy_size = (full_path.length() + 1) * sizeof(wchar_t);
315 memcpy(data, full_path.c_str(), copy_size);
316 data[full_path.length() + 1] = L'\0'; // Double NULL
317
318 // Set up the STGMEDIUM
319 STGMEDIUM* storage = new STGMEDIUM;
320 storage->tymed = TYMED_HGLOBAL;
321 storage->hGlobal = drop_files;
322 storage->pUnkForRelease = NULL;
323
324 // Set up the StoredDataInfo
325 DataObjectImpl::StoredDataInfo* info = 320 DataObjectImpl::StoredDataInfo* info =
326 new DataObjectImpl::StoredDataInfo(CF_HDROP, storage); 321 new DataObjectImpl::StoredDataInfo(CF_HDROP, storage);
327 data_->contents_.push_back(info); 322 data_->contents_.push_back(info);
328 } 323 }
329 324
330 void OSExchangeDataProviderWin::SetPickledData(CLIPFORMAT format, 325 void OSExchangeDataProviderWin::SetPickledData(CLIPFORMAT format,
331 const Pickle& data) { 326 const Pickle& data) {
332 STGMEDIUM* storage = GetStorageForString( 327 STGMEDIUM* storage = GetStorageForString(
333 std::string(static_cast<const char *>(data.data()), 328 std::string(static_cast<const char *>(data.data()),
334 static_cast<size_t>(data.size()))); 329 static_cast<size_t>(data.size())));
335 data_->contents_.push_back( 330 data_->contents_.push_back(
336 new DataObjectImpl::StoredDataInfo(format, storage)); 331 new DataObjectImpl::StoredDataInfo(format, storage));
337 } 332 }
338 333
339 void OSExchangeDataProviderWin::SetFileContents( 334 void OSExchangeDataProviderWin::SetFileContents(
340 const std::wstring& filename, 335 const std::wstring& filename,
341 const std::string& file_contents) { 336 const std::string& file_contents) {
342 // Add CFSTR_FILEDESCRIPTOR 337 // Add CFSTR_FILEDESCRIPTOR
343 STGMEDIUM* storage = GetStorageForFileDescriptor(filename); 338 STGMEDIUM* storage = GetStorageForFileDescriptor(filename);
344 data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( 339 data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
345 ClipboardUtil::GetFileDescriptorFormat()->cfFormat, storage)); 340 ClipboardUtil::GetFileDescriptorFormat()->cfFormat, storage));
346 341
347 // Add CFSTR_FILECONTENTS 342 // Add CFSTR_FILECONTENTS
348 storage = GetStorageForBytes(file_contents.data(), file_contents.length()); 343 storage = GetStorageForBytes(file_contents.data(), file_contents.length());
349 data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( 344 data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
350 ClipboardUtil::GetFileContentFormatZero()->cfFormat, storage)); 345 ClipboardUtil::GetFileContentFormatZero(), storage));
351 } 346 }
352 347
353 void OSExchangeDataProviderWin::SetHtml(const std::wstring& html, 348 void OSExchangeDataProviderWin::SetHtml(const std::wstring& html,
354 const GURL& base_url) { 349 const GURL& base_url) {
355 // Add both MS CF_HTML and text/html format. CF_HTML should be in utf-8. 350 // Add both MS CF_HTML and text/html format. CF_HTML should be in utf-8.
356 std::string utf8_html = WideToUTF8(html); 351 std::string utf8_html = WideToUTF8(html);
357 std::string url = base_url.is_valid() ? base_url.spec() : std::string(); 352 std::string url = base_url.is_valid() ? base_url.spec() : std::string();
358 353
359 std::string cf_html = ClipboardUtil::HtmlToCFHtml(utf8_html, url); 354 std::string cf_html = ClipboardUtil::HtmlToCFHtml(utf8_html, url);
360 STGMEDIUM* storage = GetStorageForBytes(cf_html.c_str(), cf_html.size()); 355 STGMEDIUM* storage = GetStorageForBytes(cf_html.c_str(), cf_html.size());
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 bool OSExchangeDataProviderWin::HasHtml() const { 447 bool OSExchangeDataProviderWin::HasHtml() const {
453 return ClipboardUtil::HasHtml(source_object_); 448 return ClipboardUtil::HasHtml(source_object_);
454 } 449 }
455 450
456 bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const { 451 bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const {
457 FORMATETC format_etc = 452 FORMATETC format_etc =
458 { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 453 { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
459 return (source_object_->QueryGetData(&format_etc) == S_OK); 454 return (source_object_->QueryGetData(&format_etc) == S_OK);
460 } 455 }
461 456
457 void OSExchangeDataProviderWin::SetDownloadFileInfo(
458 OSExchangeData::DownloadFileInfo* download) {
459 // If the filename is not provided, set stoarge to NULL to indicate that
460 // the delay rendering will be used.
461 STGMEDIUM* storage = NULL;
462 if (!download->filename.empty())
463 storage = GetStorageForFileName(download->filename.value());
464
465 // Add CF_HDROP.
466 DataObjectImpl::StoredDataInfo* info = new DataObjectImpl::StoredDataInfo(
467 ClipboardUtil::GetCFHDropFormat()->cfFormat, storage);
468 info->downloads.push_back(download);
469 data_->contents_.push_back(info);
470 }
471
462 /////////////////////////////////////////////////////////////////////////////// 472 ///////////////////////////////////////////////////////////////////////////////
463 // DataObjectImpl, IDataObject implementation: 473 // DataObjectImpl, IDataObject implementation:
464 474
465 // The following function, DuplicateMedium, is derived from WCDataObject.cpp 475 // The following function, DuplicateMedium, is derived from WCDataObject.cpp
466 // in the WebKit source code. This is the license information for the file: 476 // in the WebKit source code. This is the license information for the file:
467 /* 477 /*
468 * Copyright (C) 2007 Apple Inc. All rights reserved. 478 * Copyright (C) 2007 Apple Inc. All rights reserved.
469 * 479 *
470 * Redistribution and use in source and binary forms, with or without 480 * Redistribution and use in source and binary forms, with or without
471 * modification, are permitted provided that the following conditions 481 * modification, are permitted provided that the following conditions
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 destination->pstg->AddRef(); 536 destination->pstg->AddRef();
527 break; 537 break;
528 } 538 }
529 539
530 destination->tymed = source->tymed; 540 destination->tymed = source->tymed;
531 destination->pUnkForRelease = source->pUnkForRelease; 541 destination->pUnkForRelease = source->pUnkForRelease;
532 if (destination->pUnkForRelease) 542 if (destination->pUnkForRelease)
533 destination->pUnkForRelease->AddRef(); 543 destination->pUnkForRelease->AddRef();
534 } 544 }
535 545
536 DataObjectImpl::DataObjectImpl() : ref_count_(0) { 546 DataObjectImpl::DataObjectImpl()
537 STLDeleteContainerPointers(contents_.begin(), contents_.end()); 547 : is_aborting_(false),
548 in_async_mode_(false),
549 async_operation_started_(false),
550 observer_(NULL) {
538 } 551 }
539 552
540 DataObjectImpl::~DataObjectImpl() { 553 DataObjectImpl::~DataObjectImpl() {
554 StopDownloads();
541 STLDeleteContainerPointers(contents_.begin(), contents_.end()); 555 STLDeleteContainerPointers(contents_.begin(), contents_.end());
556 if (observer_)
557 observer_->OnDataObjectDisposed();
558 }
559
560 void DataObjectImpl::StopDownloads() {
561 for (StoredData::iterator iter = contents_.begin();
562 iter != contents_.end(); ++iter) {
563 for (size_t i = 0; i < (*iter)->downloads.size(); ++i) {
564 if ((*iter)->downloads[i]->downloader) {
565 (*iter)->downloads[i]->downloader->Stop();
566 (*iter)->downloads[i]->downloader = 0;
567 }
568 delete (*iter)->downloads[i];
569 }
570 (*iter)->downloads.clear();
571 }
572 }
573
574 void DataObjectImpl::OnDataReady(
575 int format,
576 const std::vector<OSExchangeData::DownloadFileInfo*>& downloads) {
577 // Find and update the data corresponding to the format.
578 CLIPFORMAT clip_format = static_cast<CLIPFORMAT>(format);
579 DCHECK(clip_format == ClipboardUtil::GetCFHDropFormat()->cfFormat);
580 DataObjectImpl::StoredData::iterator iter = contents_.begin();
581 for (; iter != contents_.end(); ++iter) {
582 if ((*iter)->format_etc.cfFormat == clip_format) {
583 // Update the downloads.
584 DCHECK(downloads.size() == (*iter)->downloads.size());
585 for (size_t i = 0; i < (*iter)->downloads.size(); ++i) {
586 OSExchangeData::DownloadFileInfo* old_download = (*iter)->downloads[i];
587 (*iter)->downloads[i] = downloads[i];
588 (*iter)->downloads[i]->downloader = old_download->downloader;
589 delete old_download;
590 }
591
592 // Release the old storage.
593 if ((*iter)->owns_medium) {
594 ReleaseStgMedium((*iter)->medium);
595 delete (*iter)->medium;
596 }
597
598 // Update the storage.
599 (*iter)->owns_medium = true;
600 (*iter)->medium = GetStorageForFileName(downloads[0]->filename.value());
601
602 break;
603 }
604 }
605 DCHECK(iter != contents_.end());
542 } 606 }
543 607
544 HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { 608 HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) {
545 StoredData::const_iterator iter = contents_.begin(); 609 if (is_aborting_)
610 return DV_E_FORMATETC;
611
612 StoredData::iterator iter = contents_.begin();
546 while (iter != contents_.end()) { 613 while (iter != contents_.end()) {
547 if ((*iter)->format_etc.cfFormat == format_etc->cfFormat) { 614 if ((*iter)->format_etc.cfFormat == format_etc->cfFormat &&
548 DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium); 615 (*iter)->format_etc.lindex == format_etc->lindex &&
616 ((*iter)->format_etc.tymed & format_etc->tymed)) {
617 // If medium is NULL, delay-rendering will be used.
618 if ((*iter)->medium) {
619 DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium);
620 } else {
621 // Check if the left button is down.
622 bool is_left_button_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
623
624 bool wait_for_data = false;
625 if ((*iter)->in_delay_rendering) {
626 // Make sure the left button is up. Sometimes the drop target, like
627 // Shell, might be too aggresive in calling GetData when the left
628 // button is not released.
629 if (is_left_button_down)
630 return DV_E_FORMATETC;
631
632 wait_for_data = true;
633 } else {
634 // If the left button is up and the target has not requested the data
635 // yet, it probably means that the target does not support delay-
636 // rendering. So instead, we wait for the data.
637 if (is_left_button_down) {
638 (*iter)->in_delay_rendering = true;
639 memset(medium, 0, sizeof(STGMEDIUM));
640 } else {
641 wait_for_data = true;
642 }
643 }
644
645 if (wait_for_data) {
646 // Notify the observer we start waiting for the data. This gives
647 // an observer a chance to end the drag and drop.
648 if (observer_)
649 observer_->OnWaitForData();
650
651 // Now we can start the downloads. Each download will wait till the
652 // necessary data is ready and then return the control.
653 for (size_t i = 0; i < (*iter)->downloads.size(); ++i) {
654 if ((*iter)->downloads[i]->downloader) {
655 if (!(*iter)->downloads[i]->downloader->Start(
656 this, format_etc->cfFormat)) {
657 // If any of the download fails to start, abort the whole
658 // process.
659 is_aborting_ = true;
660 StopDownloads();
661 return DV_E_FORMATETC;
662 }
663 }
664 }
665
666 // The stored data should have been updated with the final version.
667 // So we just need to call this function again to retrieve it.
668 return GetData(format_etc, medium);
669 }
670 }
549 return S_OK; 671 return S_OK;
550 } 672 }
551 ++iter; 673 ++iter;
552 } 674 }
553 675
554 return DV_E_FORMATETC; 676 return DV_E_FORMATETC;
555 } 677 }
556 678
557 HRESULT DataObjectImpl::GetDataHere(FORMATETC* format_etc, 679 HRESULT DataObjectImpl::GetDataHere(FORMATETC* format_etc,
558 STGMEDIUM* medium) { 680 STGMEDIUM* medium) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 734
613 HRESULT DataObjectImpl::DUnadvise(DWORD connection) { 735 HRESULT DataObjectImpl::DUnadvise(DWORD connection) {
614 return OLE_E_ADVISENOTSUPPORTED; 736 return OLE_E_ADVISENOTSUPPORTED;
615 } 737 }
616 738
617 HRESULT DataObjectImpl::EnumDAdvise(IEnumSTATDATA** enumerator) { 739 HRESULT DataObjectImpl::EnumDAdvise(IEnumSTATDATA** enumerator) {
618 return OLE_E_ADVISENOTSUPPORTED; 740 return OLE_E_ADVISENOTSUPPORTED;
619 } 741 }
620 742
621 /////////////////////////////////////////////////////////////////////////////// 743 ///////////////////////////////////////////////////////////////////////////////
744 // DataObjectImpl, IAsyncOperation implementation:
745
746 HRESULT DataObjectImpl::EndOperation(
747 HRESULT result, IBindCtx* reserved, DWORD effects) {
748 async_operation_started_ = false;
749 return S_OK;
750 }
751
752 HRESULT DataObjectImpl::GetAsyncMode(BOOL* is_op_async) {
753 *is_op_async = in_async_mode_ ? TRUE : FALSE;
754 return S_OK;
755 }
756
757 HRESULT DataObjectImpl::InOperation(BOOL* in_async_op) {
758 *in_async_op = async_operation_started_ ? TRUE : FALSE;
759 return S_OK;
760 }
761
762 HRESULT DataObjectImpl::SetAsyncMode(BOOL do_op_async) {
763 in_async_mode_ = (do_op_async == TRUE);
764 return S_OK;
765 }
766
767 HRESULT DataObjectImpl::StartOperation(IBindCtx* reserved) {
768 async_operation_started_ = true;
769 return S_OK;
770 }
771
772 ///////////////////////////////////////////////////////////////////////////////
622 // DataObjectImpl, IUnknown implementation: 773 // DataObjectImpl, IUnknown implementation:
623 774
624 HRESULT DataObjectImpl::QueryInterface(const IID& iid, void** object) { 775 HRESULT DataObjectImpl::QueryInterface(const IID& iid, void** object) {
625 *object = NULL; 776 if (!object)
626 if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDataObject)) { 777 return E_POINTER;
627 *object = this; 778 if (IsEqualIID(iid, IID_IDataObject) || IsEqualIID(iid, IID_IUnknown)) {
779 *object = static_cast<IDataObject*>(this);
780 } else if (in_async_mode_ && IsEqualIID(iid, IID_IAsyncOperation)) {
781 *object = static_cast<IAsyncOperation*>(this);
628 } else { 782 } else {
783 *object = NULL;
629 return E_NOINTERFACE; 784 return E_NOINTERFACE;
630 } 785 }
631 AddRef(); 786 AddRef();
632 return S_OK; 787 return S_OK;
633 } 788 }
634 789
635 ULONG DataObjectImpl::AddRef() { 790 ULONG DataObjectImpl::AddRef() {
636 return InterlockedIncrement(&ref_count_); 791 base::RefCounted<OSExchangeData::DownloadFileObserver>::AddRef();
792 return 0;
637 } 793 }
638 794
639 ULONG DataObjectImpl::Release() { 795 ULONG DataObjectImpl::Release() {
640 if (InterlockedDecrement(&ref_count_) == 0) { 796 base::RefCounted<OSExchangeData::DownloadFileObserver>::Release();
641 ULONG copied_refcnt = ref_count_; 797 return 0;
642 delete this;
643 return copied_refcnt;
644 }
645 return ref_count_;
646 } 798 }
647 799
648 /////////////////////////////////////////////////////////////////////////////// 800 ///////////////////////////////////////////////////////////////////////////////
649 // DataObjectImpl, private: 801 // DataObjectImpl, private:
650 802
651 static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes) { 803 static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes) {
652 HANDLE handle = GlobalAlloc(GPTR, static_cast<int>(bytes)); 804 HANDLE handle = GlobalAlloc(GPTR, static_cast<int>(bytes));
653 ScopedHGlobal<char> scoped(handle); 805 ScopedHGlobal<char> scoped(handle);
654 size_t allocated = static_cast<size_t>(GlobalSize(handle)); 806 size_t allocated = static_cast<size_t>(GlobalSize(handle));
655 memcpy(scoped.get(), data, allocated); 807 memcpy(scoped.get(), data, allocated);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 *validated = title; 866 *validated = title;
715 file_util::ReplaceIllegalCharactersInPath(validated, '-'); 867 file_util::ReplaceIllegalCharactersInPath(validated, '-');
716 } 868 }
717 static const wchar_t extension[] = L".url"; 869 static const wchar_t extension[] = L".url";
718 static const size_t max_length = MAX_PATH - arraysize(extension); 870 static const size_t max_length = MAX_PATH - arraysize(extension);
719 if (validated->size() > max_length) 871 if (validated->size() > max_length)
720 validated->erase(max_length); 872 validated->erase(max_length);
721 *validated += extension; 873 *validated += extension;
722 } 874 }
723 875
876 static STGMEDIUM* GetStorageForFileName(const std::wstring& full_path) {
877 const size_t kDropSize = sizeof(DROPFILES);
878 const size_t kTotalBytes =
879 kDropSize + (full_path.length() + 2) * sizeof(wchar_t);
880 HANDLE hdata = GlobalAlloc(GMEM_MOVEABLE, kTotalBytes);
881
882 ScopedHGlobal<DROPFILES> locked_mem(hdata);
883 DROPFILES* drop_files = locked_mem.get();
884 drop_files->pFiles = sizeof(DROPFILES);
885 drop_files->fWide = TRUE;
886 wchar_t* data = reinterpret_cast<wchar_t*>(
887 reinterpret_cast<BYTE*>(drop_files) + kDropSize);
888 const size_t copy_size = (full_path.length() + 1) * sizeof(wchar_t);
889 memcpy(data, full_path.c_str(), copy_size);
890 data[full_path.length() + 1] = L'\0'; // Double NULL
891
892 STGMEDIUM* storage = new STGMEDIUM;
893 storage->tymed = TYMED_HGLOBAL;
894 storage->hGlobal = drop_files;
895 storage->pUnkForRelease = NULL;
896 return storage;
897 }
898
724 static STGMEDIUM* GetStorageForFileDescriptor( 899 static STGMEDIUM* GetStorageForFileDescriptor(
725 const std::wstring& valid_file_name) { 900 const std::wstring& valid_file_name) {
726 DCHECK(!valid_file_name.empty() && valid_file_name.size() + 1 <= MAX_PATH); 901 DCHECK(!valid_file_name.empty() && valid_file_name.size() + 1 <= MAX_PATH);
727 HANDLE handle = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); 902 HANDLE handle = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
728 FILEGROUPDESCRIPTOR* descriptor = 903 FILEGROUPDESCRIPTOR* descriptor =
729 reinterpret_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(handle)); 904 reinterpret_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(handle));
730 905
731 descriptor->cItems = 1; 906 descriptor->cItems = 1;
732 wcscpy_s(descriptor->fgd[0].cFileName, 907 wcscpy_s(descriptor->fgd[0].cFileName,
733 valid_file_name.size() + 1, 908 valid_file_name.size() + 1,
(...skipping 15 matching lines...) Expand all
749 // static 924 // static
750 OSExchangeData::Provider* OSExchangeData::CreateProvider() { 925 OSExchangeData::Provider* OSExchangeData::CreateProvider() {
751 return new OSExchangeDataProviderWin(); 926 return new OSExchangeDataProviderWin();
752 } 927 }
753 928
754 // static 929 // static
755 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat( 930 OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat(
756 const std::string& type) { 931 const std::string& type) {
757 return RegisterClipboardFormat(ASCIIToWide(type).c_str()); 932 return RegisterClipboardFormat(ASCIIToWide(type).c_str());
758 } 933 }
OLDNEW
« no previous file with comments | « app/os_exchange_data_provider_win.h ('k') | app/os_exchange_data_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698