c ++ странная ошибка c0000005 - PullRequest
       13

c ++ странная ошибка c0000005

0 голосов
/ 10 августа 2009

Я работаю над проектом, который может запустить программу на рабочем столе winlogon. Программа отлично работает во время отладки, но когда я запускаю ее за пределами ide, она терпит неудачу с печально известной ошибкой c0000005. Самое странное, что, похоже, это не происходит ни в одной конкретной строке. Вот код:

#include "stdafx.h"
#include <windows.h>
#include "BinRes.h"
#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        return 0;
    }

std::string a;
a.append(BinRes::getAppLocation());
a.append("\\wls.exe");
BinRes::ExtractBinResource("EXE",102,"wls.exe");
Sleep(500);
SC_HANDLE schsm;
schsm = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
SC_HANDLE schs;
schs = CreateService(schsm,"WLS","WLS",SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,SERVICE_DEMAND_START,NULL,a.c_str(),0,0,0,0,0);
char* cd = argv[1];
LPCSTR* arg = (LPCSTR*)&cd;
StartService(schs,1,arg);
HANDLE endevent;
endevent = OpenEvent(EVENT_ALL_ACCESS,TRUE,"ENDWLS");
WaitForSingleObject(endevent,INFINITE);
SERVICE_STATUS ss;
QueryServiceStatus(schs,&ss);
if(ss.dwCurrentState != SERVICE_STOPPED)
{
    LPSERVICE_STATUS xyz = (LPSERVICE_STATUS)malloc(sizeof(LPSERVICE_STATUS));
    ControlService(schs,SERVICE_CONTROL_STOP,xyz);
}
DeleteService(schs);
//error occurs right here
DeleteFile(a.c_str());
return 0;
}

Ошибка всегда возникает после DeleteService и перед следующей строкой, но я уверен, что это не DeleteService, потому что служба удалена. Я пытался закомментировать DeleteService и DeleteFile, но он все еще падает. Я уверен, что совершил ошибку, и просто ослеп. Заранее спасибо за помощь!

Ответы [ 3 ]

6 голосов
/ 10 августа 2009

Я думаю, что проблема заключается в

LPSERVICE_STATUS xyz = (LPSERVICE_STATUS)malloc(sizeof(LPSERVICE_STATUS));
ControlService(schs,SERVICE_CONTROL_STOP,xyz);

часть. Последний аргумент xyz до ControlService используется этим API для возврата информации о состоянии службы. Вы на самом деле передаете указатель на область памяти размером указатель , которая слишком мала для хранения всех значений, которые ControlService хотели бы заполнить. -time, потому что выполнение вызова ControlService переопределит случайную память непосредственно после пространства для указателя, выделенного malloc .

Попробуйте

SERVICE_STATUS xyz;
memset(&xyz, 0, sizeof(xyz));
ControlService(schs, SERVICE_CONTROL_STOP, &xyz);

вместо этого. Здесь нет необходимости динамически размещать структуру. Согласно документации , ControlService будет использовать ее только для возврата информации о состоянии; он не будет храниться где-то во внутренних структурах данных Windows.

Подробнее о содержании структуры можно прочитать в документации MS . Понятия не имею, почему это может работать во время отладки. Возможно, malloc , связанный для отладки, ведет себя немного иначе по сравнению с рабочей версией malloc ?

4 голосов
/ 10 августа 2009

В Windows API-типы, начинающиеся с LP, являются указателями, поэтому LPSERVICE_STATUS является указателем на SERVICE_STATUS. Поэтому sizeof(LPSERVICE_STATUS) возвращает размер указателя, а не размер SERVICE_STATUS, и этот malloc не выделяет достаточно памяти:

LPSERVICE_STATUS xyz = (LPSERVICE_STATUS)malloc(sizeof(LPSERVICE_STATUS));
ControlService(schs,SERVICE_CONTROL_STOP,xyz);

Правильный размер будет sizeof(SERVICE_STATUS). Также вам не нужно выделять память динамически, указатель на локальную переменную также должен работать:

SERVICE_STATUS xyz;
ControlService(schs,SERVICE_CONTROL_STOP,&xyz);
1 голос
/ 19 октября 2010

Причина, по которой он обычно НЕ работает, - последняя часть:

"Менеджер управления службами заполняет структуру только тогда, когда ControlService возвращает один из следующих кодов ошибок: NO_ERROR, ERROR_INVALID_SERVICE_CONTROL, ERROR_SERVICE_CANNOT_ACCEPT_CTRL или ERROR_SERVICE_NOT_ACTIVE. В противном случае структура не заполнена.

из http://msdn.microsoft.com/en-us/library/ms682108%28VS.85%29.aspx

Так что он будет использовать указатель только когда что-то не получится ... :)

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