Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Загрузка драйвера


Автор: Fobos 2.2.2009, 15:32
Помогите пожалуйста решить такую проблему: написал драйвер и пытаюсь запустить его с помощью диспетчера управления службами SCM. Все время выскакивает ошибка 123 ERROR_INVALID_NAME в инете пишут что причина это "Не правильное имя сервиса", никак не пойму почему оно не правильное. Вот код:
Код

            wchar_t* aPath = L"C:\\MYROOT.SYS";                       \\пробовал и       L"\\??\\C:\\MYROOT.SYS"
    SC_HANDLE sh = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if(!sh){
        return false;
    }
    SC_HANDLE rh = CreateService(sh,    L"Driv",
                        L"My",
                        SERVICE_ALL_ACCESS,
                        SERVICE_KERNEL_DRIVER,
                        SERVICE_DEMAND_START,
                        SERVICE_ERROR_NORMAL,
                        aPath,
                        NULL, 
                        NULL,
                        NULL,
                        NULL,
                        NULL);
    if(!rh)
    {
        int err = GetLastError();
        if(GetLastError() == ERROR_SERVICE_EXISTS)
        {
            //служба уже существует
            rh = OpenService(sh,    L"Driv",    SERVICE_ALL_ACCESS);
            if(!rh)
            {
                CloseServiceHandle(sh);
                return false;
            }
        }
        else
        {
            CloseServiceHandle(sh);
            return false;
        }
    }
    //запуск драйвера
    if(rh)
    {
        int a = GetLastError();
        if( 0 == StartService(rh, 0, NULL)) // здесь всегда 123 ошибка
        {
            a = GetLastError();
            if(ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
            {
                //реальных проблем нет
            }
            else
            {
                CloseServiceHandle(sh);
                CloseServiceHandle(rh);
                return false;
            }
            
        }
        getch();
        CloseServiceHandle(sh);
        CloseServiceHandle(rh);
    }

В инете не могу найти похожий случай. Сам перепробовал кучу вариантов. Ничего не помогает. Заранее благодарен.

Автор: EnergoHokum 2.2.2009, 16:04
Код

#include <windows.h>
#include <cstring>
#include <cstdio>
//-------------------------------------------------------------------------
/*
    mingw32-g++ -Wall -o ./driver_install ./main.cpp
 */
//-------------------------------------------------------------------------
void PrintError(DWORD errorCode)
{
    LPVOID lpMsgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |                    \
                FORMAT_MESSAGE_FROM_SYSTEM,                                \
                NULL,errorCode,                                            \
                MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),    \
                (LPTSTR)&lpMsgBuf,0,NULL                                    \
                );
    printf("Error number %li: %s",errorCode,(char*)lpMsgBuf);
    LocalFree(lpMsgBuf);
    return;
}
//-------------------------------------------------------------------------
int main(int argc,char** argv)
{
    if(argc != 2)
    {
        printf("Argument is: \'install\' or \'uninstall\'");
        return 1;
    }
    char pathToDriver[0xFF];
    if(!::GetWindowsDirectory(&pathToDriver[0],0xFF))
    {
        PrintError(::GetLastError());
        return 1;
    }
    strcat(&pathToDriver[0],"\\system32\\drivers\\dlportio.sys");
    
    SC_HANDLE database;
    if(!(database=::OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE)))
    {
        PrintError(::GetLastError());
        return 1;
    }
    SC_HANDLE driver;
    if(!strcmp(argv[1],"install"))
    {
        if((driver=::OpenService(database,"DLPORTIO",DELETE)))
        {
            printf("Driver already installed\n");
            ::CloseServiceHandle(driver);
            ::CloseServiceHandle(database);
            return 2;
        }
        if(!(driver=::CreateService(database,"DLPORTIO",                    \
                            "DriverLINX Port I/O Driver",    \
                            SC_MANAGER_CREATE_SERVICE,        \
                            SERVICE_KERNEL_DRIVER,                \
                            SERVICE_SYSTEM_START,                    \
                            SERVICE_ERROR_IGNORE,                    \
                            &pathToDriver[0],                            \
                            NULL,NULL,NULL,NULL,NULL))        \
             )
        {
            PrintError(::GetLastError());
            ::CloseServiceHandle(database);
            return 1;
        }
    }
    else if(!strcmp(argv[1],"uninstall"))
    {
        if(!(driver=::OpenService(database,"DLPORTIO",DELETE)))
        {
            PrintError(::GetLastError());
            ::CloseServiceHandle(database);
            return 1;
        }
        if(!::DeleteService(driver))
        {
            PrintError(::GetLastError());
            ::CloseServiceHandle(driver);
            ::CloseServiceHandle(database);
            return 1;
        }
    }
    else
    {
        printf("Argument is: \'install\' or \'uninstall\'");
        return 1;
    }
    ::CloseServiceHandle(driver);
    ::CloseServiceHandle(database);
    return 0;
}


ВотЪ, как-то так. У меня всё работает.

Автор: Dem_max 2.2.2009, 16:10
Вот еще
Код

AnsiString StartDriver(void)
{
char szDriverFileName[MAX_PATH];
char DriverName[]="Mydriver";
SC_HANDLE  schService;
SC_HANDLE   schSCManager;
DWORD LastError;
char szMess[300];
char szTmp[MAX_PATH];
lstrcpy(szDriverFileName,"\\SystemRoot\\System32\\Drivers\\MyDriver.sys");
lstrcpy(szTmp,szDriverFileName);
szTmp[12] = '\0';
if(lstrcmpi(szTmp,"\\SystemRoot\\")==0)
{
  GetWindowsDirectory(szTmp,sizeof(szTmp));
  lstrcat(szTmp,szDriverFileName+11);
}

if(!FileExists(szTmp))
{
  return "DRIVER_NOT_EXIST";
}

schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schSCManager==NULL)
{
   if(GetLastError()==ERROR_ACCESS_DENIED) return "INSTALL_ACCESS_DENIED";
    else return "UNABLE_START_DRIVER";
}
schService = CreateService(schSCManager,DriverName,DriverName,
                  SERVICE_START,SERVICE_KERNEL_DRIVER,
                              SERVICE_SYSTEM_START,
                              SERVICE_ERROR_NORMAL,  // error control type
                              szDriverFileName,            // service's binary
                              NULL,                  // no load ordering group
                              NULL,                  // no tag identifier
                              NULL,                  // no dependencies
                              NULL,                  // LocalSystem account
                              NULL                   // no password
                              );

if(schService==NULL)
{
  LastError = GetLastError();
  if(LastError==ERROR_SERVICE_EXISTS)
  {
    CloseServiceHandle(schSCManager);
    return "DRIVER_ALREADY_STARTED";
  }
  else
    if(LastError==ERROR_ACCESS_DENIED)
    {
      CloseServiceHandle(schSCManager);
      return "INSTALL_ACCESS_DENIED";
    }
    else
    {
      CloseServiceHandle(schSCManager);
      return "UNABLE_START_DRIVER";
    }
}
StartService(schService,0,NULL);
CloseServiceHandle (schService);
CloseServiceHandle (schSCManager);
return "DRIVER_START_OK";
}

Автор: Fobos 2.2.2009, 16:47
не работает хоть убей

Автор: EnergoHokum 2.2.2009, 16:54
Цитата

не работает хоть убей 


Прозреваю ошибку в самом драйвере. В конце концов, http://wasm.ru/baixado.php?mode=tool&id=221, в нём есть загружалка/выгружалка драйверов, которая в графическом режиме работает. И код ошибки там, вроде, поясняет немного.

Кстати, мой вариант что за ошибку кажет?

Автор: Fobos 2.2.2009, 16:59
в том-то и дело что он вполне грузится с помощью InstDrv, а его отладочные сообщения перехватываются DebugView и при загрузке и при выгрузке.

Добавлено через 10 минут и 16 секунд
а твой вариант работает нормальн как и мой до определенного момента, но у меня проблема именно в запуске сервиса, т.е. функции StartService ( в твоем примере ее нет). А создает и открывает сервис моя программа нормально.

Автор: Dem_max 2.2.2009, 17:53
Я обновил свой пример выше, не все выделил когда копировал

Автор: EnergoHokum 2.2.2009, 18:23
Насколько я понял, процедура DriverEntry вызывается в момент установки драйвера в систему, и функция StartService не нужна.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)