Сбой CreateFile с восточноазиатскими именами путей с неверным путем тома или именем файла - PullRequest
1 голос
/ 14 февраля 2012
  1. У меня есть старое приложение, работающее в Windows с языковым стандартом, установленным в Корея (Hangul)
  2. Я создал оболочку GDIPLUS C ++ для сжатия изображений (png, jpg и т. Д.) Для использования в устаревшем приложении.
  3. Приложение имеет 2 процесса A и B. Процесс B является дочерним по отношению к A.
  4. Процесс B генерирует растровое изображение и сжимает его с помощью оболочки: Bitmap-> Save (Hangul-file-name.png).
  5. Процесс A пытается открыть Hangul-file-name.png и завершается неудачно с кодом ошибки 123 (том, путь или имя файла неверны).
  6. Что такое WIN APIиспользуется Bitmap-> Save (), что позволяет ему успешно создать Hangul-file-name.png?Я думаю, что Bitmap-> Save () должен в конечном итоге вызывать CreateFile () ??
  7. Есть ли какие-либо флаги, которые я могу добавить к CreateFile (), чтобы решить эту проблему?

// 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 голосов
/ 14 февраля 2012

Нет никакой магии. Bitmap->Save() в конечном итоге вызовет CreateFileW (Unicode-версия CreateFile).

У вас есть код для преобразования имени файла MBCS в Unicode в SavePng и OpenReadOnly, и он не работает одинаково. Создайте одну функцию для преобразования имени файла, и вы должны получить согласованные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...