Ignore:
Timestamp:
Apr 29, 2017, 4:33:37 PM (7 years ago)
Author:
coas-nagasima
Message:

ファイルを追加、更新。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/ntshell/fatfs/ff.c

    r278 r279  
    314314#endif
    315315#define _DF1S   0
     316
     317#elif _CODE_PAGE == 65001 /* UTF-8 */
     318#if _LFN_UNICODE
     319#error Cannot use LFN_UNICODE feature without valid code page.
     320#endif
     321#define _DF1S   0
     322
     323void Utf16_to_Utf8(unsigned char *ret_code, int *ret_size, UINT chr)
     324{
     325        ret_code[0] = ret_code[1] = ret_code[2] = ret_code[3] = 0;
     326
     327        if (chr <= 0x7f) {  // ASCII互換
     328                ret_code[0] = chr;
     329                *ret_size = 1;
     330                return;
     331        }
     332
     333        if (chr <= 0x7ff) {
     334                ret_code[1] = (0x80 | (chr & 0x3f));
     335                ret_code[0] = (0xc0 | (chr >> 6));
     336                *ret_size = 2;
     337                return;
     338        }
     339
     340        if (chr <= 0xffff) {
     341                ret_code[2] = (0x80 | (chr & 0x3f));
     342                ret_code[1] = (0x80 | ((chr >> 6) & 0x3f));
     343                ret_code[0] = (0xe0 | ((chr >> 12) & 0x0f));
     344                *ret_size = 3;
     345                return;
     346        }
     347
     348        if (chr <= 0x1fffff) {
     349                ret_code[3] = (0x80 | (chr & 0x3f));
     350                ret_code[2] = (0x80 | ((chr >> 6) & 0x3f));
     351                ret_code[1] = (0x80 | ((chr >> 12) & 0x3f));
     352                ret_code[0] = (0xf0 | ((chr >> 18) & 0x07));
     353                *ret_size = 4;
     354                return;
     355        }
     356
     357        if (chr <= 0x3ffffff) {
     358                ret_code[4] = (0x80 | (chr & 0x3f));
     359                ret_code[3] = (0x80 | ((chr >> 6) & 0x3f));
     360                ret_code[2] = (0x80 | ((chr >> 12) & 0x3f));
     361                ret_code[1] = (0x80 | ((chr >> 18) & 0x3f));
     362                ret_code[0] = (0xf8 | ((chr >> 24) & 0x03));
     363                *ret_size = 5;
     364                return;
     365        }
     366
     367        ret_code[5] = (0x80 | (chr & 0x3f));
     368        ret_code[4] = (0x80 | ((chr >> 6) & 0x3f));
     369        ret_code[3] = (0x80 | ((chr >> 12) & 0x3f));
     370        ret_code[2] = (0x80 | ((chr >> 18) & 0x3f));
     371        ret_code[1] = (0x80 | ((chr >> 24) & 0x3f));
     372        ret_code[0] = (0xfc | ((chr >> 30) & 0x01));
     373        *ret_size = 6;
     374        return;
     375}
     376
     377//2バイトのUTF-16コードが得られる
     378WCHAR Utf8_to_Utf16(const char *src, int *code_size)
     379{
     380        int i;
     381        unsigned int uc = 0;
     382        unsigned char len = 0;
     383
     384        len = 0;
     385        if ((src[0] & 0x80) == 0) { uc = src[0] & 0x7F; len = 0; }
     386        else if ((src[0] & 0xE0) == 0xC0) { uc = src[0] & 0x1F; len = 1; }
     387        else if ((src[0] & 0xF0) == 0xE0) { uc = src[0] & 0x0F; len = 2; }
     388        else if ((src[0] & 0xF8) == 0xF0) { uc = src[0] & 0x07; len = 3; }
     389        else if ((src[0] & 0xFC) == 0xF8) { uc = src[0] & 0x03; len = 4; }
     390        else if ((src[0] & 0xFE) == 0xFC) { uc = src[0] & 0x01; len = 5; }
     391
     392        i = 1;
     393        while ((i <= len) && ((src[i] & 0xC0) == 0x80)) {
     394                uc = (uc << 6) | (src[i] & 0x3F);
     395                i++;
     396        }
     397
     398        //消費文字数設定
     399        *code_size = i;
     400
     401        //現状、2バイト限定
     402        return uc;
     403}
    316404
    317405#else
     
    17121800        WCHAR w, *lfn;
    17131801#endif
     1802#if _CODE_PAGE == 65001
     1803        unsigned char utf8_code[6];
     1804        int code_size;
     1805#endif
    17141806
    17151807        p = fno->fname;
     
    17481840                        while ((w = *lfn++) != 0) {             /* Get an LFN character */
    17491841#if !_LFN_UNICODE
     1842#if _CODE_PAGE == 65001
     1843                                Utf16_to_Utf8(utf8_code, &code_size, w);
     1844                                for (int j = 0; j < code_size - 1; j++) {
     1845                                        p[i++] = utf8_code[j];
     1846                                }
     1847                                w = utf8_code[code_size - 1];
     1848#else
    17501849                                w = ff_convert(w, 0);           /* Unicode -> OEM */
    17511850                                if (!w) { i = 0; break; }       /* No LFN if it could not be converted */
     
    17531852                                        p[i++] = (TCHAR)(w >> 8);
    17541853#endif
     1854#endif
    17551855                                if (i >= fno->lfsize - 1) { i = 0; break; }     /* No LFN if buffer overflow */
    17561856                                p[i++] = (TCHAR)w;
     
    17781878
    17791879#if !_LFN_UNICODE
     1880#if _CODE_PAGE == 65001
     1881        int code_size;
     1882        chr = Utf8_to_Utf16(*ptr, &code_size);
     1883        (*ptr) += code_size;
     1884#else
    17801885        chr = (BYTE)*(*ptr)++;                                  /* Get a byte */
    17811886        if (IsLower(chr)) chr -= 0x20;                  /* To upper ASCII char */
    17821887        if (IsDBCS1(chr) && IsDBCS2(**ptr))             /* Get DBC 2nd byte if needed */
    17831888                chr = chr << 8 | (BYTE)*(*ptr)++;
     1889#endif
    17841890#ifdef _EXCVT
    17851891        if (chr >= 0x80) chr = ExCvt[chr - 0x80];       /* To upper SBCS extended char */
     
    18511957        UINT i, ni, si, di;
    18521958        const TCHAR *p;
    1853 
     1959#if _CODE_PAGE == 65001
     1960        char utf8_code[6];
     1961        int code_size;
     1962#endif
    18541963        /* Create LFN in Unicode */
    18551964        for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */
     
    18621971                        return FR_INVALID_NAME;
    18631972#if !_LFN_UNICODE
     1973#if _CODE_PAGE == 65001
     1974                w = Utf8_to_Utf16(&p[si - 1], &code_size);
     1975                si += code_size - 1;
     1976#else
    18641977                w &= 0xFF;
    18651978                if (IsDBCS1(w)) {                               /* Check if it is a DBC 1st byte (always false on SBCS cfg) */
     
    18711984                w = ff_convert(w, 1);                   /* Convert ANSI/OEM to Unicode */
    18721985                if (!w) return FR_INVALID_NAME; /* Reject invalid code */
     1986#endif
    18731987#endif
    18741988                if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal characters for LFN */
     
    19252039                        if (w) w = ExCvt[w - 0x80];     /* Convert extended character to upper (SBCS) */
    19262040#else
     2041#if _CODE_PAGE == 65001
     2042                        Utf16_to_Utf8(utf8_code, &code_size, ff_wtoupper(w));
     2043#else
    19272044                        w = ff_convert(ff_wtoupper(w), 0);      /* Upper converted Unicode -> OEM code */
    19282045#endif
     2046#endif
    19292047                        cf |= NS_LFN;                           /* Force create LFN entry */
    19302048                }
    1931 
     2049#if _CODE_PAGE == 65001
     2050                else
     2051                        code_size = 1;
     2052#endif
     2053
     2054#if _CODE_PAGE == 65001
     2055                if (code_size > 1) {            /* Is this DBC? (always false at SBCS cfg) */
     2056                        if (i >= ni - 1) {
     2057                                cf |= NS_LOSS | NS_LFN; i = ni; continue;
     2058                        }
     2059                        for (int j = 0; j < code_size; j++) {
     2060                                dp->fn[i++] = (BYTE)utf8_code[j];
     2061                        }
     2062                }
     2063                else {                                          /* SBC */
     2064                        if (!w || chk_chr("+,;=[]", w)) {       /* Replace illegal characters for SFN */
     2065                                w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
     2066                        }
     2067                        else {
     2068                                if (IsUpper(w)) {               /* ASCII large capital */
     2069                                        b |= 2;
     2070                                }
     2071                                else {
     2072                                        if (IsLower(w)) {       /* ASCII small capital */
     2073                                                b |= 1; w -= 0x20;
     2074                                        }
     2075                                }
     2076                        }
     2077                        dp->fn[i++] = (BYTE)w;
     2078                }
     2079#else
    19322080                if (_DF1S && w >= 0x100) {              /* Is this DBC? (always false at SBCS cfg) */
    19332081                        if (i >= ni - 1) {
     
    19492097                }
    19502098                dp->fn[i++] = (BYTE)w;
     2099#endif
    19512100        }
    19522101
     
    31783327}
    31793328
    3180 
     3329FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode)
     3330{
     3331  switch (mode) {
     3332  case F_SEEK_SET:
     3333    return f_lseek((fp), ofs);
     3334  case F_SEEK_CUR:
     3335    return f_lseek((fp), (fp)->fptr + ofs);
     3336  case F_SEEK_END:
     3337    return f_lseek((fp), (fp)->fsize - ofs);
     3338  default:
     3339    return FR_INVALID_PARAMETER;
     3340  }
     3341}
    31813342
    31823343#if _FS_MINIMIZE <= 1
     
    37193880        DWORD dw;
    37203881        DEFINE_NAMEBUF;
     3882        TCHAR *temp_new_path = 0;
    37213883
    37223884
     
    37423904                                else
    37433905                                        res = FR_INVALID_DRIVE;
    3744                                 if (res == FR_OK) res = FR_EXIST;               /* The new object name is already existing */
     3906                                if (res == FR_OK) {
     3907                                        res = FR_EXIST;         /* The new object name is already existing */
     3908                                        dir = djn.dir;
     3909                                        if (dir[DIR_Attr] & AM_DIR) {   /* The new object is a directory */
     3910                                                temp_new_path = (TCHAR *)ff_memalloc((_MAX_LFN + 1) * sizeof(WCHAR));
     3911                                                snprintf(temp_new_path, _MAX_LFN, "%s/%s", path_new, basename((char *)path_old));
     3912                                                res = follow_path(&djn, temp_new_path);
     3913                                        }
     3914                                }
    37453915                                if (res == FR_NO_FILE) {                                /* It is a valid path and no name collision */
    37463916                                        res = dir_register(&djn);                       /* Register the new entry */
     
    37773947        }
    37783948
     3949        if (temp_new_path != 0) ff_memfree(temp_new_path);
     3950
    37793951        LEAVE_FF(djo.fs, res);
    37803952}
     
    39124084        WCHAR w;
    39134085        DWORD tm;
    3914 
     4086#if _CODE_PAGE == 65001
     4087        int code_size;
     4088        char utf8_code[6];
     4089#endif
    39154090
    39164091        /* Get logical drive number */
     
    39254100                i = j = 0;
    39264101                do {
     4102#if _CODE_PAGE == 65001
     4103                        w = ff_wtoupper(Utf8_to_Utf16(&label[i], &code_size));
     4104                        i += code_size;
     4105                        Utf16_to_Utf8(utf8_code, &code_size, w);
     4106                        if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= sizeof(vn) - code_size) /* Reject invalid characters for volume label */
     4107                                LEAVE_FF(dj.fs, FR_INVALID_NAME);
     4108                        for (int k = 0; k < code_size; k++)
     4109                                vn[j++] = utf8_code[k];
     4110#else
    39274111#if _USE_LFN && _LFN_UNICODE
    39284112                        w = ff_convert(ff_wtoupper(label[i++]), 0);
     
    39464130                        if (w >= 0x100) vn[j++] = (BYTE)(w >> 8);
    39474131                        vn[j++] = (BYTE)w;
     4132#endif
    39484133                } while (i < sl);
    39494134                while (j < 11) vn[j++] = ' ';   /* Fill remaining name field */
Note: See TracChangeset for help on using the changeset viewer.