| 504 | } |
| 505 | |
| 506 | HRESULT BuildHDropList( |
| 507 | FORMATETC *pftc, STGMEDIUM *pstg, const std::list<std::wstring> &filenameList) |
| 508 | { |
| 509 | SetFORMATETC(pftc, CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
| 510 | |
| 511 | UINT uSize = 0; |
| 512 | |
| 513 | uSize = sizeof(DROPFILES); |
| 514 | |
| 515 | for (const auto &filename : filenameList) |
| 516 | { |
| 517 | uSize += static_cast<UINT>((filename.length() + 1) * sizeof(TCHAR)); |
| 518 | } |
| 519 | |
| 520 | /* The last string is double-null terminated. */ |
| 521 | uSize += (1 * sizeof(TCHAR)); |
| 522 | |
| 523 | HGLOBAL hglbHDrop = GlobalAlloc(GMEM_MOVEABLE, uSize); |
| 524 | |
| 525 | if (hglbHDrop == NULL) |
| 526 | { |
| 527 | return E_FAIL; |
| 528 | } |
| 529 | |
| 530 | auto pcidaData = static_cast<LPVOID>(GlobalLock(hglbHDrop)); |
| 531 | |
| 532 | auto *pdf = static_cast<DROPFILES *>(pcidaData); |
| 533 | |
| 534 | pdf->pFiles = sizeof(DROPFILES); |
| 535 | pdf->fNC = FALSE; |
| 536 | pdf->pt.x = 0; |
| 537 | pdf->pt.y = 0; |
| 538 | pdf->fWide = TRUE; |
| 539 | |
| 540 | LPBYTE pData; |
| 541 | UINT uOffset = 0; |
| 542 | |
| 543 | TCHAR chNull = '\0'; |
| 544 | |
| 545 | for (const auto &filename : filenameList) |
| 546 | { |
| 547 | pData = static_cast<LPBYTE>(pcidaData) + sizeof(DROPFILES) + uOffset; |
| 548 | |
| 549 | memcpy(pData, filename.c_str(), (filename.length() + 1) * sizeof(TCHAR)); |
| 550 | uOffset += static_cast<UINT>((filename.length() + 1) * sizeof(TCHAR)); |
| 551 | } |
| 552 | |
| 553 | /* Copy the last null byte. */ |
| 554 | pData = static_cast<LPBYTE>(pcidaData) + sizeof(DROPFILES) + uOffset; |
| 555 | memcpy(pData, &chNull, (1 * sizeof(TCHAR))); |
| 556 | |
| 557 | GlobalUnlock(hglbHDrop); |
| 558 | |
| 559 | pstg->pUnkForRelease = 0; |
| 560 | pstg->hGlobal = hglbHDrop; |
| 561 | pstg->tymed = TYMED_HGLOBAL; |
| 562 | |
| 563 | return S_OK; |
no test coverage detected