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

📄 svcproc.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
}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;  const char * prev = 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");      prev = out = 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;  if (debugMode || isWin95)

⌨️ 快捷键说明

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