Использование функции ReadFile для чтения данных из процесса - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь прочитать данные из процесса, используя функцию Win32 API ReadFile(). Я не использую стандартную библиотечную функцию, потому что я использую исходный код из репозитория publi c. Здесь я предоставляю указанный c фрагмент, с которым у меня возникли проблемы ..

//Those are Globals
HANDLE pipin_w, pipin_r, pipout_w, pipout_r;
DWORD write, read, available;
BYTE buffer[2048];

std::string myFunction(){
    std::string out="";
    PeekNamedPipe ( pipout_r, buffer, sizeof(buffer), &read, &available, NULL);
    sleep(300);
    do {
        ZeroMemory(*buffer, sizeof(buffer));
        ReadFile( pipout_r, buffer, sizeof(buffer), &read, NULL);

        if (!read) { return std::string("error"); }
        buffer[read]=0;
        out += (char*)buffer;
    } while(read >= sizeof(buffer));
    return out;
}

Первые два вызова отвечают правильно, после чего возвращается "error".

Я не смог использовать и понимать стандартную библиотечную функцию, потому что у меня нет опыта программирования на C ++. Я пытаюсь заполнить буфер BYTE размером 2048.

Этот код работает для первых двух вызовов, затем переменная read повреждается. Я знаю, что моя инициализация правильная, потому что я могу подключиться к процессу, который открывается в диспетчере задач, а также получить данные из него, но после пары вызовов переменная read повреждается.

Это вызывает зависания или сбои в моем коде. Есть несколько вещей, которые мне не нравятся в этом коде. Например, я не смог использовать стандартные библиотечные функции, такие как fstream, поэтому я решил пока придерживаться этого параметра. Кроме того, я не знаю, правильно ли читать из процесса с помощью функции ReadFile(), но это работает. И while l oop чувствует себя тихо неудобно для меня, я не могу понять, зачем мне это нужно.

Любой, кто хочет знать, как я инициализировал этот код, не стесняйтесь спрашивать, я буду предоставить всю недостающую информацию, но я не думаю, что это проблема, потому что я могу сделать пару чтений из самого процесса. Я могу предоставить ссылку на исходный код, который я использую, так как это общедоступный c репозиторий исходного кода.

Возможно, задаваемые вопросы (от вас):

  1. Поддерживает ли ваш процесс чтение?

    Да Да

  2. У вас достаточно прав для запуска и чтения процесса?

    Да У меня есть

  3. Может быть, вам нужно написать некоторые данные, чтобы сообщить процессу, чтобы начать связь ..

    Это не так, у меня есть другая функция для записи данных, и я использую ее до этого вызова, но я все еще получаю данные, даже если я не пишу в них

  4. Как вы создаете свой процесс?

    Я могу предоставить этот фрагмент, просто спросите меня, но по сути я создаю два канала, один для чтения и другой для записи, затем я запускаю процесс, вызывая CreateProcess, и это работает.

  5. Что вы пытаетесь сделать с ваш код?

    Я пытаюсь создать класс, который может обрабатывать создание, написание и чтение процесса в среде Windows на платформе c ++, ничего более ..

Что может вызвать повреждение переменной read? Я изо всех сил пытаюсь понять это, и как я могу избежать этого. Кроме того, если кто-то может объяснить мне хорошие практики для подобных ситуаций, я действительно ценю это, или, по крайней мере, имею ссылку на некоторые ресурсы, на которые я могу посмотреть, или чтобы изучить, как это работает.

Ответы [ 2 ]

1 голос
/ 06 апреля 2020
  • ZeroMemory(*buffer, sizeof(buffer)); должно быть ZeroMemory(buffer, sizeof(buffer));
    В текущем состоянии вы читаете первый BYTE в buffer и используете его в качестве адреса, с которого нужно начинать обнуление. Это вызывает неопределенное поведение.
  • buffer[read]=0; потенциально записывает границы. Если вы прочитали 2048 BYTE s, у вас неопределенное поведение.
  • out += (char*)buffer; читает buffer, пока не найдет \0 - но в этом нет необходимости, поскольку вы уже знаете, сколько BYTE s, которые вы прочитали.

Исправления:

  • Удалить ZeroMemory - вы будете читать только память, заполненную ReadFile, так что это просто пустая трата времени, чтобы сначала обнулить его.
  • Заменить
    buffer[read]=0;
    out += (char*)buffer;
    
    на
    out.append(reinterpret_cast<char*>(buffer), read);
    

Кроме того, проверьте возвращаемое значение функций, которые вы вызываете. ReadFile может произойти сбой, например.

0 голосов
/ 18 апреля 2020

Сбои исчезли, после того, как я вернул приведение к указателю на символ, я не очень хорошо понял преобразование приведения, но так как я выделил память, сначала инициализировав указатель на значение nullptr, затем я использовал memset для выделения большего буфера каким-то образом мой подход работает с такой ситуацией, так как я не использую его где-либо еще в моем коде, если мне это нужно, я просто копирую его в новую инициализированную строку, используя std :: string, чтобы решить непрерывный cra sh проблема, и, по сути, я не могу придумать лучшего подхода к этому.

Далее, что я предположил, также было cra sh, это было действительно бесконечное l oop функцией ReadFile, и это происходит в двух ситуациях:

  1. , когда я передаю «неправильную» строку для связи с ней, какие-то специальные символы (такие как \ или /)

  2. Когда в буфере нечего читать из приложения, а приложение возвращает пустой вывод

Все еще не уверен, как обработать сек случай ond :( но по крайней мере я могу продолжить отладку ...:)

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