具有东亚路径名称的CreateFile因无效的卷路径或FileName而失败

时间:2012-02-14 13:15:53

标签: windows

  1. 我在Windows上运行了遗留应用程序,并将区域设置设置为韩国(韩语)
  2. 我创建了一个GDIPLUS C ++包装器,用于图像压缩(png,jpg等),以便在旧版App中使用。
  3. 该应用程序有2个进程A和B.进程B是A的子级。
  4. 进程B生成一个位图并通过包装器压缩它:Bitmap-> Save(Hangul-file-name.png)。
  5. 进程A尝试打开Hangul-file-name.png并失败,错误代码为123(卷,路径或文件名无效)。
  6. Bitmap使用的WIN API是什么?> Save()使它能够成功创建Hangul-file-name.png?我想 Bitmap-> Save()最终必须调用CreateFile()??
  7. 我可以添加任何可以解决此问题的CreateFile()标志吗?

  8. // Called from legacy application. 
    //  pszFileName - contains a DBCS ANSI Hangul path name "자동연결기능수행_(perform_autolink_functions)_ffbd"  volume info left out.
    BOOL SavePng(char * pszFileName, HBITMAP bmhandle, HPALETTE palette, int quality)
    {
        if(pszFileName == NULL)
            return FALSE;
        // Convert the smalltalk DBCS  ANSI string to unicode.
        int slength = strlen(pszFileName);
        wchar_t *uFilename = new wchar_t[slength + 1];
        uFilename[slength] = L'\0';
        MultiByteToWideChar(CP_ACP, 0, pszFileName, -1, uFilename, slength);
    
        BOOL result = SaveImage(uFilename, L"image/png", bmhandle, palette, quality);
        delete uFilename;
        return result;
    }
    
    // Create a compressed image file
    BOOL SaveImage(LPCWSTR pszFileName, LPCWSTR encoding, HBITMAP bmhandle, HPALETTE palette, int quality)
    {
        CLSID encoderClsid;
        if( GetEncoderClsid(encoding, &encoderClsid) > 0)
        {
            EncoderParameters encoderParameters;
            encoderParameters.Count = 1;
            encoderParameters.Parameter[0].Guid = EncoderQuality;
            encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
            encoderParameters.Parameter[0].NumberOfValues = 1;
            encoderParameters.Parameter[0].Value = &quality;
            Bitmap* bm = new Bitmap(bmhandle, palette);
            bm->Save(pszFileName,&encoderClsid, &encoderParameters);
            delete bm;
            return TRUE;
        }
        return FALSE;
    }
    
    // Attempt to open file for reading
    //  pszFileName: "C:\CORE2net80\users\Administrator\자동연결기능수행_(perform_autolink_functions).png" (sample)
    HANDLE OpenReadOnly(char * pszFileName)
    {
        // Convert the smalltalk DBCS ansi string to unicode.
        int slength = strlen(pszFileName);
    
        int lenw = MultiByteToWideChar(CP_ACP, 0, pszFileName, slength, 0, 0);
        if(lenw > 0)
        {
            wchar_t *uFilename = new wchar_t[lenw + 1];
            uFilename[lenw] = L'\0';
    
            MultiByteToWideChar(CP_ACP, 0, pszFileName, slength, uFilename, lenw);
    
            HANDLE h = CreateFile(uFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if( h ==  INVALID_HANDLE_VALUE)
            {
                DWORD en = GetLastError(); // Error 123 (volume, path or filename invalid)
                return 0;
            }
            return h;
        }
        return 0;
    }
    

1 个答案:

答案 0 :(得分:0)

没有任何魔法。 Bitmap->Save()最终会调用CreateFileWCreateFile的Unicode版本。)

您可以使用SavePngOpenReadOnly将MBCS文件名转换为Unicode的代码,但它的工作方式不同。创建一个单独的函数来进行文件名转换,你应该得到一致的结果。