c ++ - Oprettelse af en Service DLL (svchost) og erstatning af en eksisterende

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil skrive min egen dll og køre den under svchost i stedet for en eksisterende.
Jeg skrev en kode, der skal køre, men når jeg starter tjenesten, fortsætter jeg med at få fejl 193: 0xc1 - som siger, at den ikke kan finde filen - men jeg lagde den i 'C: \ windows \ system32 \ mydll.dll' og ændrede registreringsdatabasen værdier, der henvender sig til den dll af tjenesten hidserv.


det er min kode:


#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include "Header.h"

\_\_declspec(dllexport) VOID ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
#pragma comment(lib, "advapi32.lib")

#define SVCNAME TEXT("text\_dll")

SERVICE\_STATUS          gSvcStatus;
SERVICE\_STATUS\_HANDLE   gSvcStatusHandle;
HANDLE                  ghSvcStopEvent = NULL;

VOID SvcInstall(void);
VOID WINAPI SvcCtrlHandler(DWORD);
VOID ServiceMain(DWORD, LPTSTR *);

VOID ReportSvcStatus(DWORD, DWORD, DWORD);
VOID SvcInit(DWORD, LPTSTR *);
VOID SvcReportEvent(LPTSTR);

//
// Purpose: 
//   Entry point for the service
//
// Parameters:
//   dwArgc - Number of arguments in the lpszArgv array
//   lpszArgv - Array of strings. The first string is the name of
//     the service and subsequent strings are passed by the process
//     that called the StartService function to start the service.
// 
// Return value:
//   None.
//


int \_\_stdcall DllMain()
{
    return 0;
}

VOID ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
    // Register the handler function for the service

    gSvcStatusHandle = RegisterServiceCtrlHandler(
        SVCNAME,
        SvcCtrlHandler);

    if (!gSvcStatusHandle)
    {
        SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
        return;
    }

    // These SERVICE\_STATUS members remain as set here

    gSvcStatus.dwServiceType = SERVICE\_WIN32\_SHARE\_PROCESS;
    gSvcStatus.dwServiceSpecificExitCode = 0;

    // Report initial status to the SCM

    ReportSvcStatus(SERVICE\_START\_PENDING, NO\_ERROR, 3000);

    // Perform service-specific initialization and work.

    SvcInit(dwArgc, lpszArgv);
}

//
// Purpose: 
//   The service code
//
// Parameters:
//   dwArgc - Number of arguments in the lpszArgv array
//   lpszArgv - Array of strings. The first string is the name of
//     the service and subsequent strings are passed by the process
//     that called the StartService function to start the service.
// 
// Return value:
//   None
//
VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv)
{
    // TO\_DO: Declare and set any required variables.
    //   Be sure to periodically call ReportSvcStatus() with 
    //   SERVICE\_START\_PENDING. If initialization fails, call
    //   ReportSvcStatus with SERVICE\_STOPPED.

    // Create an event. The control handler function, SvcCtrlHandler,
    // signals this event when it receives the stop control code.

    ghSvcStopEvent = CreateEvent(
        NULL,    // default security attributes
        TRUE,    // manual reset event
        FALSE,   // not signaled
        NULL);   // no name

    if (ghSvcStopEvent == NULL)
    {
        ReportSvcStatus(SERVICE\_STOPPED, NO\_ERROR, 0);
        return;
    }

    // Report running status when initialization is complete.

    ReportSvcStatus(SERVICE\_RUNNING, NO\_ERROR, 0);

    // TO\_DO: Perform work until service stops.

    while (1)
    {
        // Check whether to stop the service.
        HANDLE t = CreateFileA("C:\temp\test.txt", GENERIC\_WRITE, 0, NULL, CREATE\_NEW, FILE\_ATTRIBUTE\_NORMAL, NULL);
        CloseHandle(t);
        Sleep(5000);
        WaitForSingleObject(ghSvcStopEvent, INFINITE);

        ReportSvcStatus(SERVICE\_STOPPED, NO\_ERROR, 0);
        return;
    }
}

//
// Purpose: 
//   Sets the current service status and reports it to the SCM.
//
// Parameters:
//   dwCurrentState - The current state (see SERVICE\_STATUS)
//   dwWin32ExitCode - The system error code
//   dwWaitHint - Estimated time for pending operation, 
//     in milliseconds
// 
// Return value:
//   None
//
VOID ReportSvcStatus(DWORD dwCurrentState,
    DWORD dwWin32ExitCode,
    DWORD dwWaitHint)
{
    static DWORD dwCheckPoint = 1;

    // Fill in the SERVICE\_STATUS structure.

    gSvcStatus.dwCurrentState = dwCurrentState;
    gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
    gSvcStatus.dwWaitHint = dwWaitHint;

    if (dwCurrentState == SERVICE\_START\_PENDING)
        gSvcStatus.dwControlsAccepted = 0;
    else gSvcStatus.dwControlsAccepted = SERVICE\_ACCEPT\_STOP;

    if ((dwCurrentState == SERVICE\_RUNNING) ||
        (dwCurrentState == SERVICE\_STOPPED))
        gSvcStatus.dwCheckPoint = 0;
    else gSvcStatus.dwCheckPoint = dwCheckPoint++;

    // Report the status of the service to the SCM.
    SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}



//
// Purpose: 
//   Entry point for the process
//
// Parameters:
//   None
// 
// Return value:
//   None
//
void \_\_cdecl \_tmain(int argc, TCHAR *argv[])
{
    // If command-line parameter is "install", install the service. 
    // Otherwise, the service is probably being started by the SCM.

    if (lstrcmpi(argv[1], TEXT("install")) == 0)
    {
        SvcInstall();
        return;
    }
    // TO\_DO: Add any additional services for the process to this table.
    SERVICE\_TABLE\_ENTRY DispatchTable[] =
    {
        { SVCNAME, (LPSERVICE\_MAIN\_FUNCTION)ServiceMain },
        { NULL, NULL }
    };

    // This call returns when the service has stopped. 
    // The process should simply terminate when the call returns.

    if (!StartServiceCtrlDispatcher(DispatchTable))
    {
        SvcReportEvent(TEXT("StartServiceCtrlDispatcher"));
    }
}


//
// Purpose: 
//   Installs a service in the SCM database
//
// Parameters:
//   None
// 
// Return value:
//   None
//
VOID SvcInstall()
{
    SC\_HANDLE schSCManager;
    SC\_HANDLE schService;
    TCHAR szPath[MAX\_PATH];

    if (!GetModuleFileName(NULL, szPath, MAX\_PATH))
    {
        printf("Cannot install service (\%d)
", GetLastError());
        return;
    }

    // Get a handle to the SCM database. 

    schSCManager = OpenSCManager(
        NULL,                    // local computer
        NULL,                    // ServicesActive database 
        SC\_MANAGER\_ALL\_ACCESS);  // full access rights 

    if (NULL == schSCManager)
    {
        printf("OpenSCManager failed (\%d)
", GetLastError());
        return;
    }

    // Create the service

    schService = CreateService(
        schSCManager,              // SCM database 
        SVCNAME,                   // name of service 
        SVCNAME,                   // service name to display 
        SERVICE\_ALL\_ACCESS,        // desired access 
        SERVICE\_WIN32\_OWN\_PROCESS, // service type 
        SERVICE\_DEMAND\_START,      // start type 
        SERVICE\_ERROR\_NORMAL,      // error control type 
        szPath,                    // path to service's binary 
        NULL,                      // no load ordering group 
        NULL,                      // no tag identifier 
        NULL,                      // no dependencies 
        NULL,                      // LocalSystem account 
        NULL);                     // no password 

    if (schService == NULL)
    {
        printf("CreateService failed (\%d)
", GetLastError());
        CloseServiceHandle(schSCManager);
        return;
    }
    else printf("Service installed successfully
");

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
}


//
// Purpose: 
//   Called by SCM whenever a control code is sent to the service
//   using the ControlService function.
//
// Parameters:
//   dwCtrl - control code
// 
// Return value:
//   None
//
VOID WINAPI SvcCtrlHandler(DWORD dwCtrl)
{
    // Handle the requested control code. 

    switch (dwCtrl)
    {
    case SERVICE\_CONTROL\_STOP:
        ReportSvcStatus(SERVICE\_STOP\_PENDING, NO\_ERROR, 0);

        // Signal the service to stop.

        SetEvent(ghSvcStopEvent);
        ReportSvcStatus(gSvcStatus.dwCurrentState, NO\_ERROR, 0);

        return;

    case SERVICE\_CONTROL\_INTERROGATE:
        break;

    default:
        break;
    }

}
//
// Purpose: 
//   Logs messages to the event log
//
// Parameters:
//   szFunction - name of function that failed
// 
// Return value:
//   None
//
// Remarks:
//   The service must have an entry in the Application event log.
//
VOID SvcReportEvent(LPTSTR szFunction)
{
    HANDLE hEventSource;
    LPCTSTR lpszStrings[2];
    TCHAR Buffer[80];

    hEventSource = RegisterEventSource(NULL, SVCNAME);

    if (NULL != hEventSource)
    {
        StringCchPrintf(Buffer, 80, TEXT("\%s failed with \%d"), szFunction, GetLastError());

        lpszStrings[0] = SVCNAME;
        lpszStrings[1] = Buffer;

        ReportEvent(hEventSource,        // event log handle
            EVENTLOG\_ERROR\_TYPE, // event type
            0,                   // event category
            SVC\_ERROR,           // event identifier
            NULL,                // no security identifier
            2,                   // size of lpszStrings array
            0,                   // no binary data
            lpszStrings,         // array of strings
            NULL);               // no binary data

        DeregisterEventSource(hEventSource);
    }
}


og det er min overskrift:


    // The following are message definitions.
//
//  Values are 32 bit values layed out as follows:
//
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +---+-+-+-----------------------+-------------------------------+
//  |Sev|C|R|     Facility          |               Code            |
//  +---+-+-+-----------------------+-------------------------------+
//
//  where
//
//      Sev - is the severity code
//
//          00 - Success
//          01 - Informational
//          10 - Warning
//          11 - Error
//
//      C - is the Customer code flag
//
//      R - is a reserved bit
//
//      Facility - is the facility code
//
//      Code - is the facility's status code
//
//
// Define the facility codes
//


#define FACILITY\_SYSTEM                  0x0
#define FACILITY\_STUBS                   0x3
#define FACILITY\_RUNTIME                 0x2
#define FACILITY\_IO\_ERROR\_CODE           0x4


//
// Define the severity codes
//
#define STATUS\_SEVERITY\_WARNING          0x2
#define STATUS\_SEVERITY\_SUCCESS          0x0
#define STATUS\_SEVERITY\_INFORMATIONAL    0x1
#define STATUS\_SEVERITY\_ERROR            0x3


//
// MessageId: SVC\_ERROR
//
// MessageText:
//
//  An error has occurred (\%2).
//  
//
#define SVC\_ERROR                        ((DWORD)0xC0020001L)


hvad laver jeg forkert
forresten jeg kørte det på Windows 7 x64, prøvede både 32bit og 64bit compiled dll'er og begge arbejdede ikke.


Jeg har også tilføjet en def-fil, der eksporterer ServiceMain.


Jeg fandt dette forum indlæg:
https://forum.sysinternals.com/writing-a-service-that-runs-under-svchost\_topic11974.html
men selv da jeg forsøgte at kopiere koden fra deres kommentarer - det fungerede ikke!
[3]


Tak!

Bedste reference