ntse95cf.c

来自「OPC toolkit freeware to develop opc apps」· C语言 代码 · 共 313 行

C
313
字号
/****************************************************************************

 NT-Service helper library.

 SCM Emulation on Win95.
 Configuring the services.

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

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

#include <stdlib.h>

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

//#define BUFKEYNAME  (128)
#define BUFKEYVALUE (272)  /* In real, both limit are 255 in 98/98/ME */

/* Placing into "RunServices" is sufficient to start service,
   but it will not appear in taskbar...

  AUTO-start can be implemented by writing to both keys:
  Service is actually started via "RunServices" and then
  inserted into taskbar by its own reinvocation via "Run".

  For DEMAND-start we simply put it in "Run".

  Summary: AUTO should be in at least "RunServices",
                then it will replicate itself to "Run".
           DEMAND may be in "Run" only.

  On another hand, you may decide not to place it in taskbar at all...
  Then no to write it to "Run" group.
 */

static const char ntseRegRunAUTO[] =
    "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices";
static const char ntseRegRunDEMAND[] =
    "Software\\Microsoft\\Windows\\CurrentVersion\\Run";

#if 1
#define RegCrOpenKey(path, rights, phk) \
        RegCreateKeyEx(HKEY_LOCAL_MACHINE, (path), 0, /*NULL*/"", 0, (rights), NULL, (phk), NULL)
#else
#define RegCrOpenKey(path, rights, phk) \
        RegOpenKeyEx(HKEY_LOCAL_MACHINE, (path), 0, (rights), (phk))
#endif

static int ntseReadKey(const char *path, const char *name, char *buf, unsigned size)
{
  int rv;
  HKEY hk;
  DWORD len = size;
        /*KEY_READ | KEY_WRITE*/

  rv = RegCrOpenKey(path, KEY_QUERY_VALUE, &hk);
  if (!rv)
    {
      rv = RegQueryValueEx(hk, name, NULL, NULL, buf, &len);
      RegCloseKey(hk);
      if (buf && size) buf[size-1] = '\0';
    }

  UL_DEBUG((NSLOG, "%!l ntseReadKey95(%s::%s)=%s", rv, path, name,
    !rv && buf && size? buf: ""));
  return rv;
}

static int ntseWriteKey(const char *path, const char *name, const char *buf)
{
  int rv;
  HKEY hk;

  rv = RegCrOpenKey(path, KEY_SET_VALUE, &hk);
  if (!rv)
    {
      rv = RegSetValueEx(hk, name, 0, REG_SZ, buf, strlen(buf)+1);
      RegCloseKey(hk);
    }
  UL_DEBUG((NSLOG, "%!l ntseWriteKey95(%s::%s)=%s", rv, path, name, buf));

  return rv;
}

static int ntseDeleteKey(const char *path, const char *name)
{
  int rv;
  HKEY hk;

  rv = RegCrOpenKey(path, KEY_SET_VALUE, &hk);
  if (!rv)
    {
      rv = RegDeleteValue(hk, name);
      RegCloseKey(hk);
    }
  UL_DEBUG((NSLOG, "%!l ntseDeleteKey95(%s::%s)", rv, path, name));
//  if (rv == ERROR_FILE_NOT_FOUND) rv = 0;
  return rv;
}

int ntseCreate95(ntseContext *nc,
               const char *serviceName,   /* name of service */
                     int   serviceType,   /* type of service: */
                     int   startType,     /* when to start service */
               const char *commandline)   /* name of binary file */
{
  int rv;

  if (!serviceName || !commandline)
    {
      rv = ERROR_INVALID_PARAMETER;
      goto Return;
    }
  if (!(serviceType & SERVICE_WIN32))
    {
      rv = ERROR_CALL_NOT_IMPLEMENTED;
      goto Return;
    }

  if (0 == ntseReadKey(ntseRegRunAUTO, serviceName, NULL, 0) ||
      0 == ntseReadKey(ntseRegRunDEMAND, serviceName, NULL, 0))
    {
      rv = ERROR_SERVICE_EXISTS;
      goto Return;
    }

  switch(startType)
    {
  case SERVICE_AUTO_START:
      rv = ntseWriteKey(ntseRegRunAUTO, serviceName, commandline);
      ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline); /* optional */
      break;
  case SERVICE_DEMAND_START:
      ntseDeleteKey(ntseRegRunAUTO, serviceName);
      rv = ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline);
      break;
  case SERVICE_DISABLED:
      rv = 0;
      break;
  default:
      rv = ERROR_CALL_NOT_IMPLEMENTED;
      break;
    }
Return:
  if (rv)
    UL_INFO((NSLOG, "%!l ntseCreate95(%s) FAILED", rv, serviceName));
  else UL_TRACE((NSLOG, "%!l ntseCreate95(%s) Finished", rv, serviceName));

  return rv;
}

int ntseChange95(ntseContext *nc,
                 const char *serviceName,   /* name of service */
                       int   serviceType,   /* type of service: */
                       int   startType,     /* when to start service */
                 const char *commandline)   /* name of binary file */
{
  int rv;
  char ocmd[BUFKEYVALUE];
  int starttype;

  if (!serviceName)
    {
      rv = ERROR_INVALID_PARAMETER;
      goto Return;
    }
  if (!(serviceType & SERVICE_WIN32) &&
      serviceType != SERVICE_NO_CHANGE)
    {
      rv = ERROR_CALL_NOT_IMPLEMENTED;
      goto Return;
    }

  starttype = SERVICE_AUTO_START;
  rv = ntseReadKey(ntseRegRunAUTO, serviceName, ocmd, sizeof(ocmd));
  if (rv && rv != ERROR_MORE_DATA)
    {
     starttype = SERVICE_DEMAND_START;
     rv = ntseReadKey(ntseRegRunDEMAND, serviceName, ocmd, sizeof(ocmd));
     if (rv && rv != ERROR_MORE_DATA)
       {
         rv = ERROR_SERVICE_DOES_NOT_EXIST;
         goto Return;
       }
    }
  if (startType == SERVICE_NO_CHANGE)
    startType = starttype;

  if (rv && !commandline &&
      startType != SERVICE_DISABLED &&
      startType != starttype) goto Return;

  if (commandline) rv = 0;
  else commandline = ocmd;

  switch(startType)
    {
  case SERVICE_AUTO_START:
      if (rv)
        {
          if (startType == starttype) rv = 0;
          break;
        }
      rv = ntseWriteKey(ntseRegRunAUTO, serviceName, commandline);
      ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline);
      break;
  case SERVICE_DEMAND_START:
      if (rv)
        {
          if (startType == starttype) rv = 0;
          break;
        }
      rv = ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline);
      if (!rv)
        {
          rv = ntseDeleteKey(ntseRegRunAUTO, serviceName);
          if (rv == ERROR_FILE_NOT_FOUND) rv = 0;
        }
      break;

  case SERVICE_DISABLED:
      rv = ntseDelete95(serviceName);
      break;

  default:
      rv = ERROR_CALL_NOT_IMPLEMENTED;       
      break;
    }

Return:
  if (rv)
    UL_INFO((NSLOG, "%!l ntseChange95(%s) FAILED", rv, serviceName));
  else UL_TRACE((NSLOG, "%!l ntseChange95(%s) Finished", rv, serviceName));

  return rv;
}

int ntseQueryConf95(ntseContext *nc, const char *name, QUERY_SERVICE_CONFIG **cfg)
{
  char ocmd[BUFKEYVALUE];
  int starttype, rv;

  if (cfg) *cfg = NULL;

  starttype = SERVICE_AUTO_START;
  rv = ntseReadKey(ntseRegRunAUTO, name, ocmd, sizeof(ocmd));
  if (rv && rv != ERROR_MORE_DATA)
    {
     starttype = SERVICE_DEMAND_START;
     rv = ntseReadKey(ntseRegRunDEMAND, name, ocmd, sizeof(ocmd));
     if (rv && rv != ERROR_MORE_DATA)
       {
         rv = ERROR_SERVICE_DOES_NOT_EXIST;
         goto Return;
       }
    }
  if (cfg)
    {
      QUERY_SERVICE_CONFIG *sc;
      sc = (QUERY_SERVICE_CONFIG*)malloc(strlen(ocmd) + 1 +
                            sizeof(QUERY_SERVICE_CONFIG) );
      if (!sc)
        {
          rv = ERROR_NOT_ENOUGH_MEMORY;
          goto Return;
        }
      memset(sc, 0, sizeof(QUERY_SERVICE_CONFIG));
      sc->dwStartType = starttype;
      sc->dwServiceType = SERVICE_WIN32_OWN_PROCESS;
      sc->lpBinaryPathName = (char*)&sc[1];
      strcpy((char*)&sc[1], ocmd);
      sc->dwErrorControl = SERVICE_ERROR_IGNORE;
      *cfg = sc;
    }
  rv = 0;

Return:
  if (rv)
    UL_INFO((NSLOG, "%!l ntseQueryConf95(%s) FAILED", rv, name));
  else UL_TRACE((NSLOG, "%!l ntseQueryConf95(%s) Finished", rv, name));

  return rv;
}

int ntseDelete95(const char *name)
{
 int rv0, rv1;

 rv0 = ntseDeleteKey(ntseRegRunAUTO, name);
 rv1 = ntseDeleteKey(ntseRegRunDEMAND, name);
   
 if (rv0 == ERROR_FILE_NOT_FOUND ||
     rv1 != ERROR_FILE_NOT_FOUND && rv0 == 0) rv0 = rv1;
 if (rv0 == ERROR_FILE_NOT_FOUND)
     rv0 = ERROR_SERVICE_DOES_NOT_EXIST;
   
 if (rv0)
   UL_INFO((NSLOG, "%!l ntseDelete95(%s) FAILED", rv0, name));
 else UL_TRACE((NSLOG, "%!l ntseDelete95(%s) Finished", rv0, name));
 return rv0;
}

int ntseAutoRun95(ntseContext *nc, const char *name, const char *commandline)
{
  return commandline? ntseWriteKey(ntseRegRunDEMAND, name, commandline)
                    : ntseDeleteKey(ntseRegRunDEMAND, name);
}

/* end of ntse_95cf.c */

⌨️ 快捷键说明

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