- Timestamp:
- Jan 21, 2022 2:18:28 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r93115 r93398 574 574 * EndFragment = Header length + fragment length - 38(ending length) 575 575 * 576 * @return IPRT status code. 576 * For more format details, check out: 577 * https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767917(v=vs.85) 578 * 579 * @returns VBox status code. 577 580 * @param pszSource Source buffer that contains utf-16 string in mime html format 578 581 * @param cb Size of source buffer in bytes … … 586 589 int SharedClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput) 587 590 { 588 /**589 * CF_HTML format description (see also, https://docs.microsoft.com/en-us/previous-versions/590 * windows/internet-explorer/ie-developer/platform-apis/aa767917(v=vs.85)?redirectedfrom=MSDN):591 *592 * @StartHtml - pos before <html>593 * @EndHtml - whole size of text excluding ending zero char (pos after </html>)594 * @StartFragment - pos after <!--StartFragment-->595 * @EndFragment - pos before <!--EndFragment-->596 * @note: all values includes CR\LF inserted into text597 */598 599 #define VBOX_CLIP_CF_HTML_HEADER \600 "Version:1.0\r\n" \601 "StartHTML:000000101\r\n" \602 "EndHTML:%0000009u\r\n" \603 "StartFragment:000000137\r\n" \604 "EndFragment:%0000009u\r\n" \605 "<html>\r\n" \606 "<body>\r\n" \607 "<!--StartFragment-->"608 609 #define VBOX_CLIP_CF_HTML_FOOTER \610 "<!--EndFragment-->\r\n" \611 "</body>\r\n" \612 "</html>\r\n"613 614 591 Assert(ppszOutput); 615 592 Assert(pcbOutput); … … 617 594 Assert(cb); 618 595 619 size_t cchFragment; 620 int rc; 621 622 char *szFormat = VBOX_CLIP_CF_HTML_HEADER "%s" VBOX_CLIP_CF_HTML_FOOTER; 623 size_t offEndFragment = sizeof(VBOX_CLIP_CF_HTML_HEADER) - 2 /* '%' chars */ + cb; 624 size_t offEndHTML = offEndFragment + sizeof(VBOX_CLIP_CF_HTML_FOOTER); 625 char *pszResult = NULL; 626 size_t cbResult = sizeof(VBOX_CLIP_CF_HTML_HEADER) + cb + sizeof(VBOX_CLIP_CF_HTML_FOOTER); 627 628 /* Make sure input string is '\0' terminated. */ 629 rc = RTStrNLenEx(pszSource, cb, &cchFragment); 630 if (RT_FAILURE(rc)) 596 /* construct CF_HTML formatted string */ 597 598 /* Check that input is zero terminated. */ 599 /** @todo r=bird: Check that it's valid UTF-8 encoded too. */ 600 size_t cchFragment; 601 int rc = RTStrNLenEx(pszSource, cb, &cchFragment); 602 if (!RT_SUCCESS(rc)) 631 603 { 632 604 LogRelFlowFunc(("Error: invalid source fragment. rc = %Rrc\n", rc)); 633 return rc; 634 } 635 636 pszResult = (char *)RTMemAllocZ(cbResult); 605 return VERR_INVALID_PARAMETER; 606 } 607 608 /* 609 @StartHtml - pos before <html> 610 @EndHtml - whole size of text excluding ending zero char 611 @StartFragment - pos after <!--StartFragment--> 612 @EndFragment - pos before <!--EndFragment--> 613 @note: all values includes CR\LF inserted into text 614 Calculations: 615 Header length = format Length + (3*6('digits')) - 2('%s') = format length + 16 (control value - 183) 616 EndHtml = Header length + fragment length 617 StartHtml = 105(constant) 618 StartFragment = 143(constant) 619 EndFragment = Header length + fragment length - 40(ending length) 620 */ 621 static const char s_szFormatSample[] = 622 /* 0: */ "Version:1.0\r\n" 623 /* 13: */ "StartHTML:000000101\r\n" 624 /* 34: */ "EndHTML:%0000009u\r\n" // END HTML = Header length + fragment length 625 /* 53: */ "StartFragment:000000137\r\n" 626 /* 78: */ "EndFragment:%0000009u\r\n" 627 /* 101: */ "<html>\r\n" 628 /* 109: */ "<body>\r\n" 629 /* 117: */ "<!--StartFragment-->" 630 /* 137: */ "%s" 631 /* 137+2: */ "<!--EndFragment-->\r\n" 632 /* 157+2: */ "</body>\r\n" 633 /* 166+2: */ "</html>\r\n"; 634 /* 175+2: */ 635 AssertCompile(sizeof(s_szFormatSample) == 175 + 2 + 1); 636 637 /* calculate parameters of CF_HTML header */ 638 size_t cchHeader = sizeof(s_szFormatSample) - 1; 639 size_t offEndHtml = cchHeader + cchFragment; 640 size_t offEndFragment = cchHeader + cchFragment - 38; /* 175-137 = 38 */ 641 char *pszResult = (char *)RTMemAlloc(offEndHtml + 1); 637 642 if (pszResult == NULL) 638 643 { 639 LogRel (("Shared Clipboard: cannot allocate memory for HTML clipboard conversion, rc = %Rrc\n", rc));644 LogRelFlowFunc(("Error: Cannot allocate memory for result buffer. rc = %Rrc\n")); 640 645 return VERR_NO_MEMORY; 641 646 } 642 647 643 648 /* format result CF_HTML string */ 644 size_t cchFormatted = RTStrPrintf2(pszResult, cbResult, szFormat, offEndHTML, offEndFragment, pszSource); 645 if (cchFormatted > 0) 646 { 647 *ppszOutput = pszResult; 648 *pcbOutput = (uint32_t)cchFormatted + 1; 649 return VINF_SUCCESS; 650 } 651 else 652 LogRel(("Shared Clipboard: cannot format CF_HTML content\n")); 653 654 return VERR_INVALID_PARAMETER; 649 size_t cchFormatted = RTStrPrintf(pszResult, offEndHtml + 1, 650 s_szFormatSample, offEndHtml, offEndFragment, pszSource); 651 Assert(offEndHtml == cchFormatted); 652 653 #ifdef VBOX_STRICT 654 /* Control calculations. check consistency.*/ 655 static const char s_szStartFragment[] = "<!--StartFragment-->"; 656 static const char s_szEndFragment[] = "<!--EndFragment-->"; 657 658 /* check 'StartFragment:' value */ 659 const char *pszRealStartFragment = RTStrStr(pszResult, s_szStartFragment); 660 Assert(&pszRealStartFragment[sizeof(s_szStartFragment) - 1] - pszResult == 137); 661 662 /* check 'EndFragment:' value */ 663 const char *pszRealEndFragment = RTStrStr(pszResult, s_szEndFragment); 664 Assert((size_t)(pszRealEndFragment - pszResult) == offEndFragment); 665 #endif 666 667 *ppszOutput = pszResult; 668 *pcbOutput = (uint32_t)cchFormatted + 1; 669 Assert(*pcbOutput == cchFormatted + 1); 670 671 return VINF_SUCCESS; 655 672 } 656 673
Note:
See TracChangeset
for help on using the changeset viewer.