📄 charset_macosxfs.c
字号:
(0 != (*outbuf)[outsize*2-1] || 0 != (*outbuf)[outsize*2-2])) { if ((outsize*2+2) > *outbytesleft) { debug_out("String conversion: " "Output buffer too small\n"); hexdump("UTF8->UTF16LE (old) input", *inbuf, *inbytesleft); errno = E2BIG; return -1; } (*outbuf)[outsize*2] = (*outbuf)[outsize*2+1] = 0; outsize += 2; } *inbuf += *inbytesleft; *inbytesleft = 0; *outbuf += outsize*2; *outbytesleft -= outsize*2; return 0;}static size_t macosxfs_encoding_push( void *cd, /* Encoder handle */ char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */ char **outbuf, size_t *outbytesleft) /* Script string */{ static const int script_code = kCFStringEncodingUTF8; static CFMutableStringRef cfstring = NULL; static UniChar *buffer = NULL; static size_t buflen = 0; CFIndex outsize, cfsize, charsconverted; (void) cd; /* UNUSED */ if (0 == *inbytesleft) { return 0; } /* * We need a buffer that can hold 4 times the original data, * because that is the theoretical maximum that decomposition * can create currently (in Unicode 4.0). */ buffer = set_ucbuffer_with_le_copy( buffer, &buflen, *inbuf, *inbytesleft, 3 * *inbytesleft); if (NULL == cfstring) { cfstring = CFStringCreateMutableWithExternalCharactersNoCopy( kCFAllocatorDefault, buffer, *inbytesleft/2, buflen/2, kCFAllocatorNull); } else { CFStringSetExternalCharactersNoCopy( cfstring, buffer, *inbytesleft/2, buflen/2); } /* * Decompose characters, using the non-canonical decomposition * form. * * NB: This isn't exactly what HFS+ wants (see note on * kCFStringEncodingUseHFSPlusCanonical in * CFStringEncodingConverter.h), but AFAIK it's the best that * the official API can do. */ CFStringNormalize(cfstring, kCFStringNormalizationFormD); cfsize = CFStringGetLength(cfstring); charsconverted = CFStringGetBytes( cfstring, CFRangeMake(0,cfsize), script_code, 0, False, *outbuf, *outbytesleft, &outsize); if (0 == charsconverted) { debug_out("String conversion: " "Buffer too small or not convertable\n"); hexdump("UTF16LE->UTF8 (old) input", *inbuf, *inbytesleft); errno = EILSEQ; /* Probably more likely. */ return -1; } /* * Add a converted null byte, if the CFString conversions * prevented that until now. */ if (0 == (*inbuf)[*inbytesleft-1] && 0 == (*inbuf)[*inbytesleft-2] && (0 != (*outbuf)[outsize-1])) { if (((size_t)outsize+1) > *outbytesleft) { debug_out("String conversion: " "Output buffer too small\n"); hexdump("UTF16LE->UTF8 (old) input", *inbuf, *inbytesleft); errno = E2BIG; return -1; } (*outbuf)[outsize] = 0; ++outsize; } *inbuf += *inbytesleft; *inbytesleft = 0; *outbuf += outsize; *outbytesleft -= outsize; return 0;}#else /* USE_INTERNAL_API *//* * An implementation based on internal code as known from the * OpenDarwin CVS. * * This code doesn't need much memory management because it uses * functions that operate on the raw memory directly. * * The push routine here is faster and more compatible with HFS+ than * the other implementation above. The pull routine is only faster * for some strings, slightly slower for others. The pull routine * looses because it has to iterate over the data twice, once to * decode UTF-8 and than to do the character composition required by * Windows. */static size_t macosxfs_encoding_pull( void *cd, /* Encoder handle */ char **inbuf, size_t *inbytesleft, /* Script string */ char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */{ static const int script_code = kCFStringEncodingUTF8; UInt32 srcCharsUsed = 0; UInt32 dstCharsUsed = 0; UInt32 result; uint32_t dstDecomposedUsed = 0; uint32_t dstPrecomposedUsed = 0; (void) cd; /* UNUSED */ if (0 == *inbytesleft) { return 0; } result = CFStringEncodingBytesToUnicode( script_code, kCFStringEncodingComposeCombinings, *inbuf, *inbytesleft, &srcCharsUsed, (UniChar*)*outbuf, *outbytesleft, &dstCharsUsed); switch(result) { case kCFStringEncodingConversionSuccess: if (*inbytesleft == srcCharsUsed) break; else ; /*fall through*/ case kCFStringEncodingInsufficientOutputBufferLength: debug_out("String conversion: " "Output buffer too small\n"); hexdump("UTF8->UTF16LE (new) input", *inbuf, *inbytesleft); errno = E2BIG; return -1; case kCFStringEncodingInvalidInputStream: /* * HACK: smbd/mangle_hash2.c:is_legal_name() expects * errors here. That function will always pass 2 * characters. smbd/open.c:check_for_pipe() cuts a * patchname to 10 characters blindly. Suppress the * debug output in those cases. */ if(2 != *inbytesleft && 10 != *inbytesleft) { debug_out("String conversion: " "Invalid input sequence\n"); hexdump("UTF8->UTF16LE (new) input", *inbuf, *inbytesleft); } errno = EILSEQ; return -1; case kCFStringEncodingConverterUnavailable: debug_out("String conversion: " "Unknown encoding\n"); hexdump("UTF8->UTF16LE (new) input", *inbuf, *inbytesleft); errno = EINVAL; return -1; } /* * It doesn't look like CFStringEncodingBytesToUnicode() can * produce precomposed characters (flags=ComposeCombinings * doesn't do it), so we need another pass over the data here. * We can do this in-place, as the string can only get * shorter. * * (Actually in theory there should be an internal * decomposition and reordering before the actual composition * step. But we should be able to rely on that we always get * fully decomposed strings for input, so this can't create * problems in reality.) */ CFUniCharPrecompose( (const UTF16Char *)*outbuf, dstCharsUsed, &dstDecomposedUsed, (UTF16Char *)*outbuf, dstCharsUsed, &dstPrecomposedUsed); native_to_le(*outbuf, dstPrecomposedUsed*2); *inbuf += srcCharsUsed; *inbytesleft -= srcCharsUsed; *outbuf += dstPrecomposedUsed*2; *outbytesleft -= dstPrecomposedUsed*2; return 0;}static size_t macosxfs_encoding_push( void *cd, /* Encoder handle */ char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */ char **outbuf, size_t *outbytesleft) /* Script string */{ static const int script_code = kCFStringEncodingUTF8; static UniChar *buffer = NULL; static size_t buflen = 0; UInt32 srcCharsUsed=0, dstCharsUsed=0, result; (void) cd; /* UNUSED */ if (0 == *inbytesleft) { return 0; } buffer = set_ucbuffer_with_le( buffer, &buflen, *inbuf, *inbytesleft); result = CFStringEncodingUnicodeToBytes( script_code, kCFStringEncodingUseHFSPlusCanonical, buffer, *inbytesleft/2, &srcCharsUsed, *outbuf, *outbytesleft, &dstCharsUsed); switch(result) { case kCFStringEncodingConversionSuccess: if (*inbytesleft/2 == srcCharsUsed) break; else ; /*fall through*/ case kCFStringEncodingInsufficientOutputBufferLength: debug_out("String conversion: " "Output buffer too small\n"); hexdump("UTF16LE->UTF8 (new) input", *inbuf, *inbytesleft); errno = E2BIG; return -1; case kCFStringEncodingInvalidInputStream: /* * HACK: smbd/open.c:check_for_pipe():is_legal_name() * cuts a pathname to 10 characters blindly. Suppress * the debug output in those cases. */ if(10 != *inbytesleft) { debug_out("String conversion: " "Invalid input sequence\n"); hexdump("UTF16LE->UTF8 (new) input", *inbuf, *inbytesleft); } errno = EILSEQ; return -1; case kCFStringEncodingConverterUnavailable: debug_out("String conversion: " "Unknown encoding\n"); hexdump("UTF16LE->UTF8 (new) input", *inbuf, *inbytesleft); errno = EINVAL; return -1; } *inbuf += srcCharsUsed*2; *inbytesleft -= srcCharsUsed*2; *outbuf += dstCharsUsed; *outbytesleft -= dstCharsUsed; return 0;}#endif /* USE_INTERNAL_API *//* * For initialization, actually install the encoding as "macosxfs". */static struct charset_functions macosxfs_encoding_functions = { "MACOSXFS", macosxfs_encoding_pull, macosxfs_encoding_push};NTSTATUS init_module(void){ return smb_register_charset(&macosxfs_encoding_functions);}/* eof */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -