CreateFile() возвращает недопустимый указатель с адресом FFFFFF

Я просто хочу прочитать файл, используя функцию CreateFile, например:

#include <iostream>
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    PIMAGE_DOS_HEADER pImageDosHeader;
    HANDLE hFile = NULL;
    HANDLE hMapObject;
    PUCHAR uFileMap;
    if (argc < 2)
        return (-1);
    std::cout << "hFile=" << hFile << std::endl;
    if (!(hFile = CreateFile((LPCWSTR)argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
    {
        return (-1);
    } else {
        std::cout << argv[1] << std::endl;
        std::cout << "hFile=" << hFile << std::endl;
        getchar();
    }
    return (0);
}

Проблема в том, что вывод выглядит следующим образом:

hFile=000000 (указатель инициализируется значением NULL -> OK)

hFile=FFFFFF (неверный указатель)

Кто-нибудь может мне помочь, пожалуйста? Заранее спасибо за вашу помощь.


person user1364743    schedule 07.03.2013    source источник
comment
Я думаю, вы обнаружите, что на самом деле это 8 F. Это значение для INVALID_HANDLE_VALUE. hFile=0 является допустимым результатом, -1 недопустимым. Вы должны позвонить GetLastError(), чтобы дать ответ, почему он недействителен - это может быть много вещей, наиболее вероятно, что вы пытаетесь открыть существующий файл, который не существует (например, вы находитесь в неправильном каталоге, возможно?)   -  person Mats Petersson    schedule 07.03.2013
comment
MSDN — ваш друг. Прочтите документацию.   -  person Alexey Frunze    schedule 07.03.2013
comment
Я бы порекомендовал вам запустить его через отладчик и поставить точку останова перед CreateFile и посмотреть, является ли argv[1] тем значением, которое вы ожидаете, а также проверить, существует ли файл. Как упоминалось выше, msdn — ваш друг, поэтому посмотрите здесь msdn.microsoft.com/en-gb/library/windows/desktop/   -  person Rich    schedule 07.03.2013
comment
Другие указали на проблему с 0, являющимся допустимым дескриптором (где вы ожидаете, что это не так). Я считаю, что причиной получения недопустимого дескриптора является приведение argv[1] к (LPCWSTR). Это говорит программе взять этот массив символов ASCII и интерпретировать содержащиеся в нем байты как расширенные символы. Не то, что вы хотите, я полагаю. Либо используйте wmain(), либо позвоните CreateFileA().   -  person Angew is no longer proud of SO    schedule 07.03.2013
comment
Здравствуйте, да, getLastError() возвращает значение 2. Мой файл находится в моем проекте VS. Поэтому я просто добавил имя своего файла (test1.txt, содержащий строку Hello world). Чтобы быть уверенным, я добавил в свой код std::ifstream ifs(argv[1]) + чуть ниже цикла с getline. После выполнения я печатаю буфер, содержащий строку Hello world. Так что это не проблема пути к файлу.   -  person user1364743    schedule 07.03.2013
comment
Совет: когда вы отлаживаете, добавьте это в окно просмотра @err,hr, оно будет автоматически отображать сообщение об ошибке после каждого вызова API, поэтому вам не нужно будет расшифровывать код ошибки.   -  person    schedule 07.03.2013


Ответы (2)


Следующее:

if (!(hFile = CreateFile(...)))

это не то, как вы проверяете ошибки.

Из документации :

Если функция завершается ошибкой, возвращается значение INVALID_HANDLE_VALUE. Чтобы получить расширенную информацию об ошибке, позвоните по номеру GetLastError.

INVALID_HANDLE_VALUE равно -1 или 0xFFFFFFFFF в шестнадцатеричном формате. Вам нужно позвонить GetLastError(), чтобы узнать, что произошло.

person NPE    schedule 07.03.2013
comment
Здравствуйте, да, getLastError() возвращает значение 2. Мой файл находится в моем проекте VS. Поэтому я просто добавил имя своего файла (test1.txt, содержащий строку Hello world). Чтобы быть уверенным, я добавил в свой код std::ifstream ifs(argv[1]) + чуть ниже цикла с getline. После выполнения я печатаю буфер, содержащий строку Hello world. Так что это не проблема пути к файлу. Что означает ошибка 2? - person user1364743; 07.03.2013
comment
@user1364743: msdn.microsoft. com/en-gb/library/windows/desktop/ - person NPE; 07.03.2013

Когда вы получаете сообщение об ошибке от большинства API-интерфейсов Win32, вы можете вызвать GetLastError(), чтобы узнать, что пошло не так. Возьми оттуда.

Этот тип защитного программирования необходим для продуктивного программирования Win32. Фактические условия сбоя зависят от API, поэтому используйте ссылку MSDN, чтобы проверить, что вы должны искать в кодовых путях ошибок.

person Steve Townsend    schedule 07.03.2013