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

📄 samp_svc.c

📁 OPC toolkit freeware to develop opc apps. Sorce code and bin. It s free.
💻 C
📖 第 1 页 / 共 2 页
字号:
 */
void svcSignal(svcHandle *ctx, unsigned ctl)
{
  EnterCriticalSection(&ctx->shLock);
  if (ctl) ctx->shCommand = ctl;
  if (!ctx->shSignal) 
    { 
      ctx->shSignal = 1;
      SetEvent(ctx->shCond);
    }
  LeaveCriticalSection(&ctx->shLock);
}

static void svc_main(ntseHandle nh, int argc, const char *argv[])
{
  int ctl;
/* Return if hasn't initialized properly */
  if (!svcState.shCond) 
    {
      svcState.shStatus.dwCurrentState = SERVICE_STOPPED;
      ntseSetStatus(svcState.shHndl, &svcState.shStatus);
      return;
    }

  EnterCriticalSection(&svcState.shLock);
//svcState.shHndl = nh;
  svcState.shStatus.dwCurrentState = SERVICE_START_PENDING;
  svcState.shStatus.dwControlsAccepted = svcAcceptCtl;
  svcState.shStatus.dwCheckPoint++;
  ctl = ntseSetStatus(svcState.shHndl, &svcState.shStatus);
  LeaveCriticalSection(&svcState.shLock);

  if (ctl) return;

#if 0 == TEST_SVC
  ctl = svcRun(&svcState, svcName);

  EnterCriticalSection(&svcState.shLock);
  svcState.shStatus.dwCurrentState = SERVICE_STOPPED;
  svcState.shStatus.dwControlsAccepted = 0;
  svcState.shStatus.dwWin32ExitCode = ctl;
  ntseSetStatus(svcState.shHndl, &svcState.shStatus);
  LeaveCriticalSection(&svcState.shLock);
  change_icon(SERVICE_STOPPED);
#else
{
 int state = SERVICE_RUNNING;
  /* There are several ways to implement this loop
     for various kinds of services. */
  for(ctl = svcControlAndSleep(&svcState, 0, SERVICE_RUNNING, 0, 0);
      ctl != SERVICE_CONTROL_STOP;
      ctl = svcControlAndSleep(&svcState, 1000, /* timeout (ms)*/
                               ctl, 0, 0))
    {
      switch(ctl)
        {
      case SERVICE_CONTROL_PAUSE:    ctl = state = SERVICE_PAUSED;  break;
      case SERVICE_CONTROL_CONTINUE: ctl = state = SERVICE_RUNNING; break;
      case SERVICE_CONTROL_STOP:
      case SERVICE_CONTROL_SHUTDOWN: goto BREAK;
      default: ctl = 0;
        /* Blinking icon */
            change_icon((GetTickCount() / 1000 & 1)? 0: state);
            break;
        }
    }
BREAK:
  svcControlAndSleep(&svcState, 0, SERVICE_STOPPED, 0, 0);
}
#endif
} /* end of svc_main() */

static void WINAPI svc_handler(DWORD opcode)
{
    EnterCriticalSection(&svcState.shLock);

    switch (opcode)
    {
    case SERVICE_CONTROL_PAUSE:
        if (svcState.shStatus.dwCurrentState != SERVICE_PAUSED &&
            svcState.shStatus.dwCurrentState != SERVICE_STOP_PENDING &&
            svcState.shStatus.dwCurrentState != SERVICE_STOPPED)
            svcState.shStatus.dwCurrentState = SERVICE_PAUSE_PENDING;
        else opcode = 0;
        break;

    case SERVICE_CONTROL_CONTINUE:
        if (svcState.shStatus.dwCurrentState == SERVICE_PAUSED ||
            svcState.shStatus.dwCurrentState == SERVICE_PAUSE_PENDING)
            svcState.shStatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
        else opcode = 0;
        break;

    case SERVICE_CONTROL_STOP:
        if (svcState.shStatus.dwCurrentState != SERVICE_STOPPED)
        {
            svcState.shStatus.dwCurrentState = SERVICE_STOP_PENDING;
            svcState.shStatus.dwControlsAccepted = 0;
        }
        else opcode = 0;
        break;

    case SERVICE_CONTROL_SHUTDOWN:
        if (svcState.shStatus.dwCurrentState != SERVICE_STOPPED)
        {
            svcState.shStatus.dwCurrentState = SERVICE_STOP_PENDING;
            svcState.shStatus.dwControlsAccepted = 0;
        }
        else opcode = 0;
        break;

    case SERVICE_CONTROL_INTERROGATE:
        opcode = 0;
        // Fall through to send current status.
        break;

    default:
        break;
    }

    svcState.shStatus.dwCheckPoint++;
    ntseSetStatus(svcState.shHndl, &svcState.shStatus);
    change_icon((int)svcState.shStatus.dwCurrentState);

    if (opcode)
      {
        svcState.shCommand = opcode;
        if (!svcState.shSignal) 
          { 
           svcState.shSignal = 1;
           SetEvent(svcState.shCond);
          }
      }

    LeaveCriticalSection(&svcState.shLock);
    return;
}

/************************ helpers ************************/

/* Translates MSGID to string.
   Returned string must be freed via LocalFree */

char *system_message(int msgid)
{
  char *buf = 0;
  unsigned len;
  len = FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL, msgid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (char*)&buf, 0, NULL);
  if (!buf || !len)
    {
     if (buf) LocalFree(buf);
     buf = (char*)LocalAlloc(LMEM_FIXED, 80);
     if (buf)
       wsprintf(buf, "GetLastError()=%d/0x%X/ ", msgid, msgid);
    }
  else
    {
      AnsiToOem(buf, buf);
      while(len--) /* strip cr-lf */
         if (' ' > (unsigned char)buf[len])
           buf[len] = ' ';
    }
 return buf;
}

void print_err(int ecode, const char *fmt, ...)
{
  char *msg = system_message(ecode);
  va_list ap; va_start(ap, fmt);
  vfprintf(stdout, fmt, ap);
  va_end(ap);
  fprintf(stdout, " [%s(%d)]\n", msg? msg: "null", ecode);
  LocalFree(msg);
}

/*********************************************************************
 [OPTIONAL] GUI stuff [ these additions do not required even on Win95]
 *********************************************************************/

unsigned ntseHideConsole(void)
{
  HWND hwndr = 0;
  HMODULE kernel;
  FARPROC getconsolewindow;

  if ((kernel = GetModuleHandle("KERNEL32.DLL")) && 
      (getconsolewindow = GetProcAddress(kernel, "GetConsoleWindow")))
    {
      hwndr = ((HWND (WINAPI *)(VOID))getconsolewindow)();
      if (hwndr) ShowWindowAsync(hwndr, SW_HIDE); /* SW_HIDE SW_MINIMIZE*/
//      UL_TRACE((NSLOG, "GetConsoleWindow()=%x", hwnd));
    }
  else
    {
      DWORD iam_pid = GetCurrentProcessId();
      int hope = 4;
      for(;;)
        {
          static const char *console_class[] = { "tty", "ConsoleWindowClass" };
          int icl;
          HWND hwnd = 0;
#ifndef SIZEOF_ARRAY
#define SIZEOF_ARRAY(XX) (sizeof(XX)/sizeof(XX[0]))
#endif
          for(icl = 0; icl < SIZEOF_ARRAY(console_class); icl++)
            while(hwnd = FindWindowEx(NULL, hwnd, console_class[icl], NULL))
              { /* An alternative is EnumThreadWindows() */
                DWORD win_pid = 0;
                DWORD win_thr = GetWindowThreadProcessId(hwnd, &win_pid);
                if (win_pid == iam_pid)
                  {
                    ShowWindowAsync(hwnd, SW_HIDE); /* SW_HIDE SW_MINIMIZE*/
//                    UL_TRACE((NSLOG, "Window Found(%s/%d): whd=%x pid=%d thrid=%d iam= %d %d", 
  //                    console_class[icl], hope, hwnd, win_pid, win_thr, iam_pid, GetCurrentThreadId()));
                    hope = 0;
                    hwndr = hwnd;
                  }
              }
          if (0 <= --hope) Sleep(333);
          else break;
        }
    }
  return (unsigned)hwndr;
}

#ifdef IDM_ABOUT /* have an additional commands? */

/* 'About' dialog proc. */

static LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
                SetFocus(hDlg);
                return TRUE;

        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
            }
            break;
    }
    return FALSE;
}

/* hooks */

static int hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  if (message == NTSE_WM_TASKBAR &&
      (//LOWORD(lParam) == WM_LBUTTONDOWN ||
       LOWORD(lParam) == WM_LBUTTONDBLCLK) )
    {
      PostMessage(hwnd, WM_COMMAND, IDM_ABOUT, 0);
    }
  else if (message == WM_COMMAND &&
           LOWORD(wParam) == IDM_ABOUT)
    {
        static int dlgON;
        if (!dlgON)
          {
            dlgON = 1;
            //SetForegroundWindow(hwnd);
            DialogBox(GetModuleHandle(NULL),
                  MAKEINTRESOURCE(IDD_ABOUTBOX),
                  hwnd, (DLGPROC)About);
            dlgON = 0;
            return 1;
        }
    }
  return 0;
}

static LRESULT CALLBACK
hook_CallWndRet(int hc, WPARAM wParam, LPARAM lParam)
{
    CWPRETSTRUCT *pcwps = (CWPRETSTRUCT*)lParam;
    if (hc >= 0 && pcwps && pcwps->hwnd)
      hook_proc(pcwps->hwnd, pcwps->message, pcwps->wParam, pcwps->lParam);
    return CallNextHookEx(NULL, hc, wParam, lParam);
}

static LRESULT CALLBACK
hook_GetMsg(int hc, WPARAM wParam, LPARAM lParam)
{
    MSG *pmsg = (MSG*)lParam;
    if (hc >= 0 && pmsg && pmsg->hwnd)
      hook_proc(pmsg->hwnd, pmsg->message, pmsg->wParam, pmsg->lParam);
    return CallNextHookEx(NULL, hc, wParam, lParam);
}

static HHOOK hook_ret = 0;
static HHOOK hook_get = 0;
#endif /*IDM_ABOUT*/

static HWND taskbar_hwnd = 0;

static int set_hooks(void *arg, HWND hwnd)
{
/* The hwnd can be obtained via ntseServiceWindow() too */
  if (hwnd) taskbar_hwnd = hwnd;
  svcIsFakeSCM = 1;
{
#if defined(IDM_ABOUT) || defined(IDI_RUNNING)
  DWORD thrid = GetWindowThreadProcessId(hwnd, NULL);
  HMENU menu = GetMenu(hwnd);

  fprintf(stdout, "Service [%s] Setting the HOOK [hwnd=%x: thr=%x]...\n",
      svcName, hwnd, thrid);

  change_icon(SERVICE_STOPPED);
#endif /*IDM_ABOUT || IDI_RUNNING*/
#ifdef IDM_ABOUT
  if (menu && (-1 == (int)GetMenuState(menu, IDM_ABOUT, MF_BYCOMMAND)))
    {
      AppendMenu(menu, MF_STRING,
                 IDM_ABOUT/*128...255*/, "About");
      DrawMenuBar(hwnd);
    }

  hook_ret = SetWindowsHookEx(WH_CALLWNDPROCRET,
          (HOOKPROC)hook_CallWndRet, //GetProcAddress(hmodHook, "SpyGetMsgProc"),
          GetModuleHandle(NULL), thrid);
  hook_get = SetWindowsHookEx(WH_GETMESSAGE,
          (HOOKPROC)hook_GetMsg, //GetProcAddress(hmodHook, "SpyGetMsgProc"),
          GetModuleHandle(NULL), thrid);
  if (!hook_get)
    print_err(GetLastError(), "Hook failed:");
#endif /*IDM_ABOUT*/
}
  return 0; /* !=0 cause abort */
}

static void unset_hooks(void)
{
#ifdef IDM_ABOUT
 if (hook_ret) UnhookWindowsHookEx(hook_ret), hook_ret = 0;
 if (hook_get) UnhookWindowsHookEx(hook_get), hook_get = 0;
#endif
 taskbar_hwnd = 0;
 svcIsFakeSCM = 0;
}

#ifdef IDI_RUNNING /* have icons? */
/* Change taskbar icon */
void change_icon(int state)
{
  int ico = 0;
  const char *sysico = IDI_INFORMATION;
  NOTIFYICONDATA pnid;

  if (!taskbar_hwnd) return;

  pnid.cbSize = sizeof (pnid);
  pnid.hWnd = taskbar_hwnd;
  pnid.uID   = NTSE_ID_TASKBAR;
  pnid.uFlags = NIF_ICON;
  switch(state)
    {
     case SERVICE_RUNNING: ico = IDI_RUNNING; 
                        sysico = IDI_APPLICATION; 
                        break;
     case SERVICE_STOPPED: ico = IDI_STOPPED; 
                        sysico = IDI_ERROR; 
                        break;
     case SERVICE_PAUSED:  ico = IDI_PAUSED; 
                        sysico = IDI_WARNING; 
                        break;
     case 0:               ico = IDI_BLANK;
                        sysico = IDI_WINLOGO;
                        break;
    }
  pnid.hIcon = ico? LoadImage(GetModuleHandle(NULL),
                              MAKEINTRESOURCE(ico),
                              IMAGE_ICON, 16, 16, LR_SHARED): 0;
  if (!pnid.hIcon)
    pnid.hIcon = LoadIcon(NULL, sysico);

  Shell_NotifyIcon(NIM_MODIFY,  &pnid);
  DrawMenuBar(taskbar_hwnd);
//  UpdateWindow(taskbar_hwnd);
}
#endif /*IDI_RUNNING*/

/**************************************************************************/
/* end of samp_svc.c */

⌨️ 快捷键说明

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