Загрузить изображение из HTTP-запроса, вызывающего точку останова

Я пытаюсь загрузить изображение на рабочий стол пользователя с URL-адреса, используя Win32. Я позаботился обо всех HTTP-запросах и точно знаю, что все работает хорошо. Когда я иду звонить CreateFile(), отладчик Visual Studio просто говорит: «Исключение: Application.exe вызвал точку останова» и что он возобновится в строке CreateFile(). Также появляется код ошибки "Обнаружена критическая ошибка c0000374"

Вот мой код:

VARIANT varResponse;
VariantInit(&varResponse);

...

hr = pIWinHttpRequest->get_ResponseBody(&varResponse);

...

if (SUCCEEDED(hr)) {
    
    long upperBounds;
    long lowerBounds;
    unsigned char* buff;
    //Make sure that varResponse is an array of unsigned bytes
    if (varResponse.vt == (VT_ARRAY | VT_UI1)) {
        long Dims = SafeArrayGetDim(varResponse.parray);
        
        //It should only have one dimension
        if (Dims == 1) {
            
            //Get Array lower and upper bounds
            SafeArrayGetLBound(varResponse.parray, 1, &lowerBounds);
            SafeArrayGetUBound(varResponse.parray, 1, &upperBounds);
            upperBounds++;

            SafeArrayAccessData(varResponse.parray, (void**)&buff);

            HANDLE hFile;
            DWORD dwBytesWritten;

            PWSTR filepath[MAX_PATH];
            HRESULT hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &*filepath);
            if (SUCCEEDED(hr)) {
                
                //PathCombine(filepathForImage, filepathToDesktop, L"\\todaysDailyImage.jpg");
                
                PathAppend(*filepath, L"todaysDailyImage.jpg");
                MessageBox(NULL, *filepath, L"Check if filepath works", MB_OK);
            }
            
            hFile = CreateFile(*filepath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE) {
                //File failed
                
            }
            else {
                WriteFile(hFile, buff, upperBounds - lowerBounds, &dwBytesWritten, NULL);
                //File was written
            }
            CloseHandle(hFile);
            CoTaskMemFree(filepath);
            SafeArrayUnaccessData(varResponse.parray);
            MessageBox(NULL, L"Everything was cleaned up", L"Update:", MB_OK);
        }
    }
}

Я делаю что-то не так?

Подозрительно ли добавление вещей к результату SHGetKnownFolderPath. Должно быть безопаснее скопировать строку в достаточно большой буфер, прежде чем объединять его.

MikeCAT 26.12.2020 00:14

@MikeCAT, как бы это выглядело, потому что я пытался wstringstream, но не мог этого понять

Da Mahdi03 26.12.2020 00:16

@DaMahdi03 примерно так: PWSTR folderpath; SHGetKnownFolderPath(..., &folderpath); wostringstream wos; wos << folderpath << L"\\todaysDailyImage.jpg"; wstring filepath = wos.str(); ... hFile = CreateFile(filepath.c_str(), ...); ...

Remy Lebeau 26.12.2020 20:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

То, как вы используете filepath, совершенно неправильно.

Вы объявляете его как массив из MAX_PATH (260) числа PWSTR указателей.

Когда вы обращаетесь к массиву только по его имени, вы получаете указатель на 1-й элемент массива. Итак, &*filepath — это то же самое, что &*(&filepath[0]), то есть фактически &filepath[0]. А *filepath — это то же самое, что *(&filepath[0]), то есть фактически filepath[0]. Итак, что касается SHGetKnownFolderPath() и MessageBox(), они работают только с 1-м указателем PWSTR в массиве, а остальные 259 элементов массива игнорируются. Эта часть в порядке, но расточительна.

Однако для PathAppend() требуется буфер назначения, который представляет собой массив из MAX_PATH числа WCHAR элементов. Вы добавляете к массиву WCHAR[], который SHGetKnownFolderPath() выделяет в качестве своего вывода, который недостаточно велик, чтобы содержать имя файла, которое вы пытаетесь добавить к нему. Итак, вы вызываете ошибки, потому что пытаетесь изменить память, которая не была выделена для хранения этой модификации.

Вам вообще не нужен массив PWSTR. Вместо этого попробуйте что-то вроде этого:

PWSTR folderpath;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &folderpath);
if (FAILED(hr)) {
    // ...
}
else {
    PWSTR filepath;
    hr = PathAllocCombine(folderpath,  L"todaysDailyImage.jpg", 0, &filepath);
    if (FAIlED(hr)) {
        // ...
    }
    else {
        MessageBoxW(NULL, filepath, L"Check if filepath works", MB_OK);
            
        hFile = CreateFileW(filepath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE) {
            //File failed
        }
        else {
            WriteFile(hFile, buff, upperBounds - lowerBounds, &dwBytesWritten, NULL);
            //File was written
            CloseHandle(hFile);
        }

        LocalFree(filepath);
    }

    CoTaskMemFree(folderpath);
}

Спасибо, это сработало! хотя не понимаю что я делал не так

Da Mahdi03 26.12.2020 01:54

Другие вопросы по теме