[vbox-dev] Patch to resolve the unicode-composite character problem of the shared-folder in Mac OS X
Sander van Leeuwen
Sander.Vanleeuwen at Sun.COM
Fri Jun 20 00:39:20 PDT 2008
Hi,
Thanks a lot for your patch! Could you please state that you either
license this code under the MIT license
or our custom license? (see
http://www.virtualbox.org/wiki/Contributor_information)
Thanks,
Sander
Gi youl Kim wrote:
> Mac OS X deals with filename using unicode, especially
> NFD(Normalization Form D - Canonical Decomposition). Here is link
> about the topic.
>
> http://unicode.org/reports/tr15/
>
> Mac OS X understands NFD and NFC(Normalization Form C - Canonical
> Decomposition, followed by Canonical Composition), but uses NFD as
> filename. Windows XP understands NFC but not NFD.
>
> So, when you tries to access the files in the Mac OS X (host) via
> Shared Folder from Windows XP (guest), and if the filename is Korean,
> Japanese or any language which has form in NFC & NFC, The filename
> does not appear correctly. Windows Vista understands NFD, so it won't
> be matter with Vista (guest).
>
> To resolve this problem, you should normalize the filename to NFC(from
> Mac OS X to Windows XP) or NFD(from Windows XP to Mac OS X).
>
> Following patch does that. Tested with VB 1.6.2 and revision 9784
>
> Index: src/VBox/HostServices/SharedFolders/vbsf.cpp
> ===================================================================
> --- src/VBox/HostServices/SharedFolders/vbsf.cpp (revision 9784)
> +++ src/VBox/HostServices/SharedFolders/vbsf.cpp (working copy)
> @@ -33,6 +33,10 @@
> #include <iprt/string.h>
> #include <iprt/uni.h>
>
> +#ifdef RT_OS_DARWIN
> +#include <Carbon/Carbon.h>
> +#endif
> +
> #undef LogFlow
> #define LogFlow Log
>
> @@ -231,6 +235,36 @@
> }
> else
> {
> +#ifdef RT_OS_DARWIN
> + SHFLSTRING *pPathParameter = pPath;
> + size_t cbPathLength;
> + CFMutableStringRef inStr = ::CFStringCreateMutable(NULL, 0);
> + uint16_t ucs2Length;
> + CFRange rangeCharacters;
> +
> + // Is 8 times length enough for decomposed in worst case...?
> + cbPathLength = sizeof(SHFLSTRING) + pPathParameter->u16Length * 8 + 2;
> + pPath = (SHFLSTRING *)RTMemAllocZ (cbPathLength);
> + if (!pPath)
> + {
> + rc = VERR_NO_MEMORY;
> + Log(("RTMemAllocZ %x failed!!\n", cbPathLength));
> + return rc;
> + }
> +
> + ::CFStringAppendCharacters(inStr, (UniChar
> *)pPathParameter->String.ucs2, pPathParameter->u16Length /
> sizeof(pPathParameter->String.ucs2[0]));
> + ::CFStringNormalize(inStr, kCFStringNormalizationFormD);
> + ucs2Length = ::CFStringGetLength(inStr);
> +
> + rangeCharacters.location = 0;
> + rangeCharacters.length = ucs2Length;
> + ::CFStringGetCharacters(inStr, rangeCharacters, pPath->String.ucs2);
> + pPath->String.ucs2[ucs2Length] = 0x0000; // NULL terminated
> + pPath->u16Length = ucs2Length * sizeof(pPath->String.ucs2[0]);
> + pPath->u16Size = pPath->u16Length + sizeof(pPath->String.ucs2[0]);
> +
> + CFRelease(inStr);
> +#endif
> /* Client sends us UCS2, so convert it to UTF8. */
> Log(("Root %ls path %.*ls\n", pwszRoot,
> pPath->u16Length/sizeof(pPath->String.ucs2[0]), pPath->String.ucs2));
>
> @@ -255,6 +289,10 @@
> if (VBOX_FAILURE(rc))
> {
> AssertFailed();
> +#ifdef RT_OS_DARWIN
> + RTMemFree(pPath);
> + pPath = pPathParameter;
> +#endif
> return rc;
> }
>
> @@ -312,6 +350,10 @@
> /* Nul terminate the string */
> *dst = 0;
> }
> +#ifdef RT_OS_DARWIN
> + RTMemFree(pPath);
> + pPath = pPathParameter;
> +#endif
> }
>
> if (VBOX_SUCCESS (rc))
> @@ -1340,6 +1382,28 @@
> int rc2 = RTStrToUtf16Ex(pDirEntry->szName, RTSTR_MAX,
> &pwszString, pDirEntry->cbName+1, NULL);
> AssertRC(rc2);
>
> +#ifdef RT_OS_DARWIN
> + {
> + // Convert to
> + // Normalization Form C (composed Unicode). We need this because
> + // Mac OS X file system uses NFD (Normalization Form D :
> decomposed Unicode)
> + // while most other OS', server-side programs usually expect NFC.
> + uint16_t ucs2Length;
> + CFRange rangeCharacters;
> + CFMutableStringRef inStr = ::CFStringCreateMutable(NULL, 0);
> +
> + ::CFStringAppendCharacters(inStr, (UniChar *)pwszString,
> RTUtf16Len (pwszString));
> + ::CFStringNormalize(inStr, kCFStringNormalizationFormC);
> + ucs2Length = ::CFStringGetLength(inStr);
> +
> + rangeCharacters.location = 0;
> + rangeCharacters.length = ucs2Length;
> + ::CFStringGetCharacters(inStr, rangeCharacters, pwszString);
> + pwszString[ucs2Length] = 0x0000; // NULL terminated
> +
> + CFRelease(inStr);
> + }
> +#endif
> pSFDEntry->name.u16Length = RTUtf16Len
> (pSFDEntry->name.String.ucs2) * 2;
> pSFDEntry->name.u16Size = pSFDEntry->name.u16Length + 2;
>
> Index: src/VBox/HostServices/SharedFolders/Makefile.kmk
> ===================================================================
> --- src/VBox/HostServices/SharedFolders/Makefile.kmk (revision 9784)
> +++ src/VBox/HostServices/SharedFolders/Makefile.kmk (working copy)
> @@ -36,6 +36,9 @@
> VBoxSharedFolders_INCS.win = \
> $(PATH_TOOL_$(VBOX_VCC_TOOL)_ATLMFC_INC) \
> $(VBOX_PATH_SDK)
> +
> +VBoxSharedFolders_LDFLAGS.darwin = \
> + -framework Carbon
>
> VBoxSharedFolders_SOURCES = \
> service.cpp \
>
> _______________________________________________
> vbox-dev mailing list
> vbox-dev at virtualbox.org
> http://vbox.innotek.de/mailman/listinfo/vbox-dev
>
--
Kind regards / Mit freundlichen Gruessen / Met vriendelijke groet
--
Sun Microsystems GmbH Sander van Leeuwen
Werkstrasse 24 Senior Staff Engineer, VirtualBox
71384 Weinstadt, Germany mailto:Sander.Vanleeuwen at sun.com
================================================
Sitz der Gesellschaft: Sun Microsystems GmbH,
Sonnenallee 1, 85551 Kirchheim-Heimstetten
Amtsgericht Muenchen: HRB 161028
Geschaeftsfuehrer: Thomas Schroeder,
Wolfgang Engels, Dr. Roland Boehmer
Vorsitzender des Aufsichtsrates: Martin Haering
================================================
More information about the vbox-dev
mailing list