import "unknwn.idl";

cpp_quote("#ifndef _SERVICE_H_")
cpp_quote("#define _SERVICE_H_")

#define SERVICE_STATUS_HANDLE_MIDL

#ifndef DECLARE_HANDLE
#define DECLARE_HANDLE(name) \
    struct name##__ { DWORD_PTR unused; }; \
    typedef struct name##__ _far* name
#endif

[
    object,
    local,
    uuid(02506D0A-A7F5-419d-94D2-ED26F0753654),
    helpstring("Mini-Service Interface"),
    pointer_default(unique)
]
interface IService : IUnknown
{
cpp_quote("#ifdef SERVICE_STATUS_HANDLE_MIDL")
    DECLARE_HANDLE(SERVICE_STATUS_HANDLE);
cpp_quote("#endif")

    // pszEventRelinquishControl is the name of an event used to signal this
    // object (running on a diff thread than the main service thread) that some
    // service control events needs to be processed.  It is in a signaled
    // state as long as there is event(s) to process.
    // The Run method should return as soon as possible when the event is in a
    // signaled state.
	// Do minimum intialization in this fct.  After that fct is called and
	// InitDeviceEventHandler is called too (if applicable) the service will
	// be reported as running.  Then InitFinal will be called.
    HRESULT InitMinimum([in] DWORD cArg, [in] LPWSTR* ppszArgs,
        [in] LPCWSTR pszEventRelinquishControl,
        [out] DWORD* pdwCtrlAccept, [out] BOOL* pfWantsDeviceEvents);

	// Called after the service is declared running, to complete
	// initialization.
    HRESULT InitFinal();

    HRESULT Run();

    // - Will be called with dwControlCode set to one of the following
    //   depending on the value of *pdwCtrlAccept
    //      SERVICE_CONTROL_STOP
    //      SERVICE_CONTROL_PAUSE
    //      SERVICE_CONTROL_CONTINUE
    //      SERVICE_CONTROL_SHUTDOWN
    //      SERVICE_CONTROL_PARAMCHANGE
    //   should return S_FALSE and a non-zero dwWaitHint if pending
    //
    // - Shall not return S_FALSE for SERVICE_CONTROL_SHUTDOWN and
    //   SERVICE_CONTROL_PARAMCHANGE, or for unknown dwControl's
	//
	// - If returns FAILED for return value, then this service will be
	//   terminated
    HRESULT HandleServiceControl([in] DWORD dwControlCode, 
        [out]DWORD* pdwWaitHint);

    // will be called iff (TRUE == *pfWantsDeviceEvents)
    HRESULT InitDeviceEventHandler([in] SERVICE_STATUS_HANDLE ssh);

    // will be called iff (TRUE == *pfWantsDeviceEvents)
    HRESULT HandleDeviceEvent([in] DWORD dwEventType, [in] LPVOID pEventData);

    // will be called iff (SERVICE_ACCEPT_POWEREVENT & *pdwCtrlAccept)
    HRESULT HandlePowerEvent([in] DWORD dwEventType, [in] LPVOID pEventData);
    // will be called iff (SERVICE_ACCEPT_HARDWAREPROFILECHANGE &
    //  *pdwCtrlAccept)
    HRESULT HandleHWProfileEvent([in] DWORD dwEventType,
        [in] LPVOID pEventData);

    // will be called iff SERVICE_CONTROL_SESSIONCHANGE occured
    HRESULT HandleSessionChange([in] DWORD dwEventType, [in] LPVOID pvEventData);
};

cpp_quote("#endif")
