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 [email protected] http://vbox.innotek.de/mailman/listinfo/vbox-dev
