⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntse.c

📁 OPC toolkit freeware to develop opc apps. Sorce code and bin. It s free.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************

 NT-Service helper library.

 Copyright (c) 2000,2002  Timofei Bondarenko, Kostya Volovich.
 ****************************************************************************/

#include <windows.h>
#include <winsvc.h>

#include <stdlib.h>

#include "ntse.h"
#include "ntsepriv.h"

#if defined(USE_LOG) && USE_LOG >= 0
unilog *ntse_log;
#endif

/*****************************************************************************/

ntseContext ntse_ctx_NT = { 0, 0,  1 },
            ntse_ctx_95 = { 0, 0, -1 };
ntseContext *ntseCtxNT = &ntse_ctx_NT,
            *ntseCtx95 = &ntse_ctx_95;

/*****************************************************************************

 All functions return 0 if Ok appropriate GetLastError() otherwise.

 *****************************************************************************/

ntseContext ntse_null_context;

/* return Non-zero nc->ncNT95 >0 on NT, <0 on 95/8 */
int ntseSwitch95(ntseContext *nc, int rv)
{
  if (0 == nc->ncNT95)
    {
      if (rv == ERROR_CALL_NOT_IMPLEMENTED)
        {
          UL_INFO((NSLOG, "ntse: Switched to Win95 mode"));
          nc->ncNT95 = -1;
        }
      else nc->ncNT95 = 1;
    }
  return nc->ncNT95;
}

static int ntse_control(SC_HANDLE scm,
                        const char *name, int command, SERVICE_STATUS *stat)
{
 int rv;
 SC_HANDLE svc;
 DWORD sec_svc;
 BOOL rvb;
 int mcmd = command;
 const char *debug = "";

 switch(command)
   {
 case ntseOP_DELETE:
     sec_svc = DELETE;
     debug = "DELETE";
     break;

 case ntseOP_START:
     sec_svc = SERVICE_START;
     debug = "START";
     break;

 case ntseOP_STOP:
 case SERVICE_CONTROL_STOP:
     command = SERVICE_CONTROL_STOP;
     sec_svc = SERVICE_STOP;
     debug = "STOP";
     break;

 case ntseOP_PAUSE:
 case SERVICE_CONTROL_PAUSE:
     command = SERVICE_CONTROL_PAUSE;
     sec_svc = SERVICE_PAUSE_CONTINUE;
     debug = "PAUSE";
     break;

 case ntseOP_CONTINUE:
 case SERVICE_CONTROL_CONTINUE:
     command = SERVICE_CONTROL_CONTINUE;
     sec_svc = SERVICE_PAUSE_CONTINUE;
     debug = "CONTINUE";
     break;

 case SERVICE_CONTROL_INTERROGATE:
     sec_svc = SERVICE_INTERROGATE;
     debug = "INTERROGATE";
     break;

 case ntseOP_QUERY:
     sec_svc = SERVICE_QUERY_STATUS;
     debug = "QUERY_STATUS";
     break;

 default:
     if (command >= 128 && command <= 255)
       {
        sec_svc = SERVICE_USER_DEFINED_CONTROL;
        debug = "USER_DEFINED";
       }
     else sec_svc = SERVICE_ALL_ACCESS;
     break;
   }

 svc = OpenService(scm, name, sec_svc);
 if (!svc)
   {
    rv = GetLastError();
    UL_INFO((NSLOG, "%!l ntseControl(%s):%s{%d}OpenService() FAILED",
        rv, name, debug, mcmd));
    return rv? rv: -1;
   }

 switch(command)
   {
 case ntseOP_DELETE:
    rvb = DeleteService(svc);
    break;

 case ntseOP_START:
    rvb = StartService(svc, 0/*argc*/, NULL/*argv*/);
    break;

 case ntseOP_QUERY:
    rvb = QueryServiceStatus(svc, stat);
    break;

 default:
    rvb = ControlService(svc, command, stat);
    break;
   }

 if (rvb) rv = 0;
 else if (!(rv = GetLastError())) rv = -1;

 CloseServiceHandle(svc);

 if (rv)
    UL_INFO((NSLOG, "%!l ntseControl(%s) %s{%d} FAILED", rv, name, debug, mcmd));
 else UL_TRACE((NSLOG, "%!l ntseControl(%s) %s{%d} Finished", rv, name, debug, mcmd));

 return rv;
}

int ntseControl(ntseContext *nc, const char *name, int command, SERVICE_STATUS *stat)
{
 DWORD rv;
 SC_HANDLE scm;
 static SERVICE_STATUS fake_stat;

 if (!nc) nc = &ntse_null_context;

/*	SC_MANAGER_CREATE_SERVICE
	SC_MANAGER_CONNECT
	SC_MANAGER_ENUMERATE_SERVICE
	SC_MANAGER_LOCK
	SC_MANAGER_QUERY_LOCK_STATUS

	GENERIC_READ = STANDARD_RIGHTS_READ SC_MANAGER_ENUMERATE_SERVICE
				   SC_MANAGER_QUERY_LOCK_STATUS
	GENERIC_WRITE = STANDARD_RIGHTS_WRITE SC_MANAGER_CREATE_SERVICE
	GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE SC_MANAGER_CONNECT SC_MANAGER_LOCK.
*/
 if (0 > nc->ncNT95) return ntseControl95(nc, name, command, stat);
 scm = OpenSCManager(nc->ncHostname, nc->ncDatabase, SC_MANAGER_CONNECT);
 if (!scm)
   {
    rv = GetLastError();
    if (0 > ntseSwitch95(nc, rv))
      {
         return ntseControl95(nc, name, command, stat);
      }
    UL_INFO((NSLOG, "%!l ntseControl(%s):{%d}OpenSCManager() FAILED",
        rv, name, command));
    return rv? rv: -1;
   }

 if (!stat) stat = &fake_stat;
// else memset(stat, 0, sizeof(*stat));

 rv = ntse_control(scm, name, command, stat);

 if (rv)
   switch(command)
     {
   case ntseOP_QUERY:
      rv = ntse_control(scm, name, SERVICE_CONTROL_INTERROGATE, stat);
      break;
   case SERVICE_CONTROL_INTERROGATE:
      rv = ntse_control(scm, name, ntseOP_QUERY, stat);
      break;
   default:
      break;
     }
 CloseServiceHandle(scm);

 return rv;
}

int ntseCommand(ntseContext *nc, const char *name, int command)
{
    return ntseControl(nc, name, command, NULL);
}

int ntseFree(ntseContext *nc, void *buf)
{
    if (!buf) return ERROR_INVALID_PARAMETER;
    free(buf);
    return 0;
}

/* Allocates the buffer for *cfg. This buffer have to be freed by ntseFree() */
int ntseQueryConfig(ntseContext *nc, const char *name, QUERY_SERVICE_CONFIG **cfg)
{
 DWORD rv;
 SC_HANDLE scm, svc;
 QUERY_SERVICE_CONFIG *scfg = 0;

 if (cfg) *cfg = 0;
//     return ERROR_INVALID_PARAMETER;

 if (!nc) nc = &ntse_null_context;

 if (0 > nc->ncNT95) return ntseQueryConf95(nc, name, cfg); 
 scm = OpenSCManager(nc->ncHostname, nc->ncDatabase, SC_MANAGER_CONNECT);
 if (!scm)
   {
    rv = GetLastError();
    if (0 > ntseSwitch95(nc, rv))
      {
         return ntseQueryConf95(nc, name, cfg);
      }
    UL_INFO((NSLOG, "%!l ntseQueryConfig(%s):OpenSCManager() FAILED", rv, name));
    return rv? rv: -1;
   }
 svc = OpenService(scm, name, SERVICE_QUERY_CONFIG);
 if (!svc)
   {
    rv = GetLastError();
    CloseServiceHandle(scm);
    UL_INFO((NSLOG, "%!l ntseQueryConfig(%s):OpenService() FAILED", rv, name));
    return rv? rv: -1;
   }

 rv = 0;
 scfg = 0;
 if (cfg)
 {
    DWORD bufsize = sizeof(QUERY_SERVICE_CONFIG) + 200;
    do {
         void *buf;
         DWORD bsize;
         bufsize += 64;
         buf = realloc(scfg, bufsize);
         if (!buf)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -