OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |