windows - CreateFile med østasiatiske stienavne fejler med ugyldig volumensti eller filnavn

Indlæg af Hanne Mølgaard Plasc

Problem




  1. Jeg har en gammel applikation, der kører på Windows med lokalvalg til Korea (Hangul)

  2. Jeg oprettede en GDIPLUS C ++-indpakning til billedkomprimering (png, jpg osv.) til at bruge i den gamle app.

  3. Ansøgningen har 2 processer A og B. Proces B er et barn af A.

  4. Proces B genererer en bitmappe og komprimerer den via indpakningen: Bitmap-> Gem (Hangul-fil-navn.png).

  5. Proces En forsøger at åbne Hangul-filen-name.png og fejler med fejlkode 123 (volumen, sti eller filnavn er ugyldigt).

  6. Hvad er WIN API'en, der bruges af Bitmap-> Save (), der gør det muligt at oprette Hangul-file-name.png? Jeg ville tænke
    at Bitmap-> Save () skal til sidst kalde CreateFile () ??

  7. Er der nogen flag, jeg kan tilføje til CreateFile (), der ville løse dette problem?






// 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'';
    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:CORE2net80usersAdministrator자동연결기능수행\_(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'';

        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;
}

Bedste reference


Der er ikke nogen magi. Bitmap->Save() vil til sidst kalde CreateFileW (Unicode-versionen af ​​CreateFile).


Du har kode til at konvertere MBCS filnavnet til Unicode i både SavePng og OpenReadOnly, og det virker ikke det samme. Opret en enkelt funktion for at gøre filnavnet konvertering, og du skal få ensartede resultater.