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

📄 svcproc.cxx

📁 开源代码的pwlib的1.10.0版本,使用openh323的1.18.0版本毕备
💻 CXX
📖 第 1 页 / 共 4 页
字号:
{
  return Current().WndProc(hWnd, msg, wParam, lParam);
}


static void SaveWindowPosition(HWND hWnd)
{
  RECT r;
  GetWindowRect(hWnd, &r);
  PConfig cfg(ServiceSimulationSectionName);
  cfg.SetInteger(WindowLeftKey, r.left);
  cfg.SetInteger(WindowTopKey, r.top);
  cfg.SetInteger(WindowRightKey, r.right);
  cfg.SetInteger(WindowBottomKey, r.bottom);
}


LPARAM PServiceProcess::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
#ifdef _DEBUG
  static DWORD allocationNumber;
#endif

  switch (msg) {
    case WM_CREATE :
      controlWindow = hWnd;
      break;

    case WM_DESTROY :
      if (debugWindow == (HWND)-1) {
        PNotifyIconData nid(hWnd, NIF_TIP);
        nid.Delete(); // This removes the systray icon
      }

      controlWindow = debugWindow = NULL;

      PostQuitMessage(0);
      break;

    case WM_ENDSESSION :
      if (wParam && (debugMode || lParam != ENDSESSION_LOGOFF) && debugWindow != (HWND)-1)
        OnStop();
      return 0;

    case WM_MOVE :
      if (debugWindow != NULL)
        SaveWindowPosition(hWnd);
      break;

    case WM_SIZE :
      if (debugWindow != NULL && debugWindow != (HWND)-1) {
        SaveWindowPosition(hWnd);
        MoveWindow(debugWindow, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
      }
      break;

    case WM_INITMENUPOPUP :
    {
      int enableItems = MF_BYCOMMAND|(debugMode ? MF_ENABLED : MF_GRAYED);
      for (int i = PSystemLog::Fatal; i < PSystemLog::NumLogLevels; i++) {
        CheckMenuItem((HMENU)wParam, LogLevelBaseMenuID+i, MF_BYCOMMAND|MF_UNCHECKED);
        EnableMenuItem((HMENU)wParam, LogLevelBaseMenuID+i, enableItems);
      }
      CheckMenuItem((HMENU)wParam, LogLevelBaseMenuID+GetLogLevel(), MF_BYCOMMAND|MF_CHECKED);

      enableItems = MF_BYCOMMAND|(debugMode ? MF_GRAYED : MF_ENABLED);
      EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdStart, enableItems);
      EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdStop, enableItems);
      EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdPause, enableItems);
      EnableMenuItem((HMENU)wParam, SvcCmdBaseMenuID+SvcCmdResume, enableItems);

      DWORD start, finish;
      if (debugWindow != NULL && debugWindow != (HWND)-1)
        SendMessage(debugWindow, EM_GETSEL, (WPARAM)&start, (LPARAM)&finish);
      else
        start = finish = 0;
      enableItems = MF_BYCOMMAND|(start == finish ? MF_GRAYED : MF_ENABLED);
      EnableMenuItem((HMENU)wParam, CopyMenuID, enableItems);
      EnableMenuItem((HMENU)wParam, CutMenuID, enableItems);
      EnableMenuItem((HMENU)wParam, DeleteMenuID, enableItems);

      enableItems = MF_BYCOMMAND|(IsServiceRunning(this) ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem((HMENU)wParam, ControlMenuID, enableItems);
      break;
    }

    case WM_COMMAND :
      switch (wParam) {
        case ExitMenuID :
          DestroyWindow(hWnd);
          break;

        case ControlMenuID :
          if (IsServiceRunning(this))
            OnControl();
          break;

        case HideMenuID :
          ShowWindow(hWnd, SW_HIDE);
          break;

#if PMEMORY_CHECK
        case MarkMenuID :
          allocationNumber = PMemoryHeap::GetAllocationRequest();
          break;

        case DumpMenuID :
          PMemoryHeap::DumpObjectsSince(allocationNumber);
          break;

        case StatsMenuID :
          PMemoryHeap::DumpStatistics();
          break;
        case ValidateMenuID :
          PMemoryHeap::ValidateHeap();
          break;
#endif

        case CopyMenuID :
          if (debugWindow != NULL && debugWindow != (HWND)-1)
            SendMessage(debugWindow, WM_COPY, 0, 0);
          break;

        case CutMenuID :
          if (debugWindow != NULL && debugWindow != (HWND)-1)
            SendMessage(debugWindow, WM_CUT, 0, 0);
          break;

        case DeleteMenuID :
          if (debugWindow != NULL && debugWindow != (HWND)-1)
            SendMessage(debugWindow, WM_CLEAR, 0, 0);
          break;

        case SelectAllMenuID :
          if (debugWindow != NULL && debugWindow != (HWND)-1)
            SendMessage(debugWindow, EM_SETSEL, 0, -1);
          break;

        case OutputToMenuID :
          if (debugWindow != NULL && debugWindow != (HWND)-1) {
            char fileBuffer[_MAX_PATH];
            OPENFILENAME fileDlgInfo;
            memset(&fileDlgInfo, 0, sizeof(fileDlgInfo));
            fileDlgInfo.lStructSize = sizeof(fileDlgInfo);
            fileDlgInfo.hwndOwner = hWnd;
            fileDlgInfo.hInstance = hInstance;
            fileBuffer[0] = '\0';
            fileDlgInfo.lpstrFile = fileBuffer;
            char customFilter[100];
            strcpy(customFilter, "All Files");
            memcpy(&customFilter[strlen(customFilter)+1], "*.*\0", 5);
            fileDlgInfo.lpstrCustomFilter = customFilter;
            fileDlgInfo.nMaxCustFilter = sizeof(customFilter);
            fileDlgInfo.nMaxFile = sizeof(fileBuffer);
            fileDlgInfo.Flags = OFN_ENABLEHOOK|OFN_HIDEREADONLY|OFN_NOVALIDATE|OFN_EXPLORER|OFN_CREATEPROMPT;
            fileDlgInfo.lCustData = (DWORD)this;
            if (GetSaveFileName(&fileDlgInfo)) {
              if (systemLogFileName != fileBuffer) {
                systemLogFileName = fileBuffer;
                PFile::Remove(systemLogFileName);
                PConfig cfg(ServiceSimulationSectionName);
                cfg.SetString(SystemLogFileNameKey, systemLogFileName);
                DebugOutput("Sending all system log output to \"" + systemLogFileName + "\".\n");
                PError << "Logging started for \"" << GetName() << "\" version " << GetVersion(TRUE) << endl;
              }
            }
          }
          break;

        case WindowOutputMenuID :
          if (!systemLogFileName) {
            PError << "Logging stopped." << endl;
            DebugOutput("System log output to \"" + systemLogFileName + "\" stopped.\n");
            systemLogFileName = PString();
            PConfig cfg(ServiceSimulationSectionName);
            cfg.SetString(SystemLogFileNameKey, "");
          }
          break;

        default :
          if (wParam >= LogLevelBaseMenuID+PSystemLog::Fatal && wParam < LogLevelBaseMenuID+PSystemLog::NumLogLevels) {
            SetLogLevel((PSystemLog::Level)(wParam-LogLevelBaseMenuID));
#if PTRACING
            PTrace::SetLevel(wParam-LogLevelBaseMenuID-PSystemLog::Warning);
#endif
          }
          else if (wParam >= SvcCmdBaseMenuID && wParam < SvcCmdBaseMenuID+NumSvcCmds) {
            const char * cmdname = ServiceCommandNames[wParam-SvcCmdBaseMenuID];
            if (wParam == SvcCmdBaseMenuID+SvcCmdVersion ||
                MessageBox(hWnd, cmdname & GetName() & "?", GetName(),
                           MB_ICONQUESTION|MB_YESNO) == IDYES)
              ProcessCommand(cmdname);
          }
      }
      break;

    // Notification of event over sysTray icon
    case UWM_SYSTRAY :
      switch (lParam) {
        case WM_MOUSEMOVE :
          // update status of process for tool tips if no buttons down
          if (wParam == SYSTRAY_ICON_ID) {
            PNotifyIconData nid(hWnd, NIF_TIP,
                          GetName() & (IsServiceRunning(this) ? "is" : "not") & "running.");
            nid.Modify(); // Modify tooltip
          }
          break;

        // Click on icon - display message
        case WM_LBUTTONDBLCLK :
          if (IsServiceRunning(this))
            OnControl();
          else {
            SetForegroundWindow(hWnd); // Our MessageBox pops up in front
            MessageBox(hWnd, "Service is not running!", GetName(), MB_TASKMODAL);
          }
          break;

        // Popup menu
        case WM_RBUTTONUP :
          POINT pt;
          GetCursorPos(&pt);

          HMENU menu = CreatePopupMenu();
          AppendMenu(menu, MF_STRING, ControlMenuID, "&Open Properties");
          AppendMenu(menu, MF_SEPARATOR, 0, NULL);
          AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdVersion, "&Version");
          if (IsServiceRunning(this)) {
            MENUITEMINFO inf;
            inf.cbSize = sizeof(inf);
            inf.fMask = MIIM_STATE;
            inf.fState = MFS_DEFAULT;
            SetMenuItemInfo(menu, ControlMenuID, FALSE, &inf);
            AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdStop, "&Stop Service");
          }
          else {
            EnableMenuItem(menu, ControlMenuID, MF_GRAYED);
            AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdStart, "&Start Service");
          }
          AppendMenu(menu, MF_STRING, SvcCmdBaseMenuID+SvcCmdNoTray, "&Tray Icon");
          CheckMenuItem(menu, SvcCmdBaseMenuID+SvcCmdNoTray,
                        TrayIconRegistry(this, CheckTrayIcon) ? MF_CHECKED : MF_UNCHECKED);
          AppendMenu(menu, MF_SEPARATOR, 0, NULL);
          AppendMenu(menu, MF_STRING, ExitMenuID, "&Close");

          /* SetForegroundWindow and the ensuing null PostMessage is a
             workaround for a Windows 95 bug (see MSKB article Q135788,
             http://www.microsoft.com/kb/articles/q135/7/88.htm, I think).
             In typical Microsoft style this bug is listed as "by design".
             SetForegroundWindow also causes our MessageBox to pop up in front
             of any other application's windows. */
          SetForegroundWindow(hWnd);

          /* We specifiy TPM_RETURNCMD, so TrackPopupMenu returns the menu
             selection instead of returning immediately and our getting a
             WM_COMMAND with the selection. You don't have to do it this way.
          */
          WndProc(hWnd, WM_COMMAND, TrackPopupMenu(menu,            // Popup menu to track
                                                   TPM_RETURNCMD |  // Return menu code
                                                   TPM_RIGHTBUTTON, // Track right mouse button?
                                                   pt.x, pt.y,      // screen coordinates
                                                   0,               // reserved
                                                   hWnd,            // owner
                                                   NULL),           // LPRECT user can click in without dismissing menu
                                                   0);
          PostMessage(hWnd, 0, 0, 0); // see above
          DestroyMenu(menu); // Delete loaded menu and reclaim its resources
          break;
      }
  }

  return DefWindowProc(hWnd, msg, wParam, lParam);
}


void PServiceProcess::DebugOutput(const char * out)
{
  if (controlWindow == NULL)
    return;

  if (debugWindow == NULL || debugWindow == (HWND)-1) {
    for (PINDEX i = 0; i < 3; i++) {
      const char * tab = strchr(out, '\t');
      if (tab == NULL)
        break;
      out = tab+1;
    }
    MessageBox(controlWindow, out, GetName(), MB_TASKMODAL);
    return;
  }


  if (!IsWindowVisible(controlWindow))
    ShowWindow(controlWindow, SW_SHOWDEFAULT);

  int len = strlen(out);
  int max = isWin95 ? 32000 : 128000;
  while (GetWindowTextLength(debugWindow)+len >= max) {
    SendMessage(debugWindow, WM_SETREDRAW, FALSE, 0);
    DWORD start, finish;
    SendMessage(debugWindow, EM_GETSEL, (WPARAM)&start, (LPARAM)&finish);
    SendMessage(debugWindow, EM_SETSEL, 0,
                SendMessage(debugWindow, EM_LINEINDEX, 1, 0));
    SendMessage(debugWindow, EM_REPLACESEL, FALSE, (DWORD)"");
    SendMessage(debugWindow, EM_SETSEL, start, finish);
    SendMessage(debugWindow, WM_SETREDRAW, TRUE, 0);
  }

  SendMessage(debugWindow, EM_SETSEL, max, max);
  char * lf;
  char * prev = (char *)out;
  while ((lf = strchr(prev, '\n')) != NULL) {
    if (*(lf-1) == '\r')
      prev = lf+1;
    else {
      *lf++ = '\0';
      SendMessage(debugWindow, EM_REPLACESEL, FALSE, (DWORD)out);
      SendMessage(debugWindow, EM_REPLACESEL, FALSE, (DWORD)"\r\n");
      out = (const char *)lf;
      prev = lf;
    }
  }
  if (*out != '\0')
    SendMessage(debugWindow, EM_REPLACESEL, FALSE, (DWORD)out);
}


void PServiceProcess::StaticMainEntry(DWORD argc, LPTSTR * argv)
{
  Current().MainEntry(argc, argv);
}


void PServiceProcess::MainEntry(DWORD argc, LPTSTR * argv)
{
  // SERVICE_STATUS members that don't change
  status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  status.dwServiceSpecificExitCode = 0;

  // register our service control handler:
  statusHandle = RegisterServiceCtrlHandler(GetName(), StaticControlEntry);
  if (statusHandle == NULL)
    return;

  // report the status to Service Control Manager.
  if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 1, 20000))
    return;

  // create the stop event object. The control handler function signals
  // this event when it receives the "stop" control code.
  terminationEvent = CreateEvent(NULL, TRUE, FALSE, (const char *)GetName());
  if (terminationEvent == NULL)
    return;

  startedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (startedEvent == NULL)
    return;

  GetArguments().SetArgs(argc, argv);

  // start the thread that performs the work of the service.
  threadHandle = (HANDLE)_beginthread(StaticThreadEntry, 0, this);
  if (threadHandle != (HANDLE)-1) {
    while (WaitForSingleObject(startedEvent, 10000) == WAIT_TIMEOUT) {
      if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 1, 20000))
        return;
    }
    // Wait here for the end
    WaitForSingleObject(terminationEvent, INFINITE);
  }

  CloseHandle(startedEvent);
  CloseHandle(terminationEvent);
  ReportStatus(SERVICE_STOPPED, 0);
}


void PServiceProcess::StaticThreadEntry(void * arg)
{
  ((PServiceProcess *)arg)->ThreadEntry();
}


void PServiceProcess::ThreadEntry()
{
  activeThreadMutex.Wait();
  threadId = GetCurrentThreadId();
  threadHandle = GetCurrentThread();
  activeThreads.SetAt(threadId, this);
  activeThreadMutex.Signal();

  SetTerminationValue(1);
  if (OnStart()) {

    if (!debugMode)
      SetEvent(startedEvent);
    ReportStatus(SERVICE_RUNNING);
    SetTerminationValue(0);

    Main();

    ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 1, 30000);
  }

  SetEvent(terminationEvent);
}


void PServiceProcess::StaticControlEntry(DWORD code)
{
  Current().ControlEntry(code);
}


void PServiceProcess::ControlEntry(DWORD code)
{
  switch (code) {
    case SERVICE_CONTROL_PAUSE : // Pause the service if it is running.
      if (status.dwCurrentState != SERVICE_RUNNING)
        ReportStatus(status.dwCurrentState);
      else {
        if (OnPause())
          ReportStatus(SERVICE_PAUSED);
      }
      break;

    case SERVICE_CONTROL_CONTINUE : // Resume the paused service.
      if (status.dwCurrentState == SERVICE_PAUSED)
        OnContinue();
      ReportStatus(status.dwCurrentState);
      break;

    case SERVICE_CONTROL_STOP : // Stop the service.
      // Report the status, specifying the checkpoint and waithint, before
      // setting the termination event.
      ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 1, 30000);
      OnStop();
      SetEvent(terminationEvent);
      break;

    case SERVICE_CONTROL_INTERROGATE : // Update the service status.
    default :
      ReportStatus(status.dwCurrentState);
  }
}


BOOL PServiceProcess::ReportStatus(DWORD dwCurrentState,
                                   DWORD dwWin32ExitCode,
                                   DWORD dwCheckPoint,
                                   DWORD dwWaitHint)
{
  // Disable control requests until the service is started.
  if (dwCurrentState == SERVICE_START_PENDING)
    status.dwControlsAccepted = 0;
  else
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;

  // These SERVICE_STATUS members are set from parameters.
  status.dwCurrentState = dwCurrentState;
  status.dwWin32ExitCode = dwWin32ExitCode;
  status.dwCheckPoint = dwCheckPoint;
  status.dwWaitHint = dwWaitHint;

⌨️ 快捷键说明

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