Example #1
0
void MainWindow::SocketReader()
{
	Sleep(2000);
	PLOTDATA *pPlotData = new PLOTDATA;
	pPlotData->DataSize = 0;
	pPlotData->pPointData = new D2D1_POINT_2F[200];

	sprintf_s(LatestPacket, "Socket reader (sort of) got u!");
	SendMessageCallback(m_hwnd, AM_UPDATE, 0, 0, NULL, NULL);
	//Edit_SetText(pAppData->hWndEdit, (LPTSTR) L"Socket reader got u!");
	Sleep(2000);
	for(int i = 0;i < 200;i++)
	{
		sprintf_s(LatestPacket, "Count is now at: %i.", i);
		SendMessageCallback(m_hwnd, AM_UPDATE, 0, 0, NULL, NULL);
		pPlotData->pPointData[i].x = (float) i;
		pPlotData->pPointData[i].y = (float) i;
		pPlotData->DataSize = i;
		SendMessage(hWndPlot, GP_UPDATE, (WPARAM) i, (LPARAM) pPlotData);
		Sleep(200);
		//pAppData->TCPListenPort.GetPacket(&(pAppData->LatestPacket), &(pAppData->PacketSize));
		//Edit_SetText(pAppData->hWndEdit,  (LPTSTR) pAppData->LatestPacket);
	}
	sprintf_s(LatestPacket, "Socket reader exited.");
	SendMessageCallback(m_hwnd, AM_UPDATE, 0, 0, NULL, NULL);
}
Example #2
0
static void UpdateWindowData(HWND window) {
  ULONGLONG time = GetTickCount64();
  WindowData &data = sWindowData[window];
  if (time - data.lastUpdateTime < MAX_UPDATE_FREQUENCY) {
    data.updateDuringMaintenance = true;
    return;
  }
  data.lastUpdateTime = time;
  data.updateDuringMaintenance = false;
  SendMessageCallback(window, WM_GETICON, ICON_BIG, NULL, GetIconCallback, ICON_BIG);
}
Example #3
0
static void CALLBACK GetIconCallback(HWND window, UINT message, ULONG_PTR data, LRESULT result) {
  assert(message == WM_GETICON);

  switch (data) {
  case ICON_BIG:
    if (result != NULL) {
      sWindowData[window].largeIcon = (HICON)result;
    } else {
      HICON icon = (HICON)GetClassLongPtr(window, GCLP_HICON);
      if (!icon) {
        icon = sDefaultIcon;
      }
      sWindowData[window].largeIcon = icon;
    }
    SendMessageCallback(window, WM_GETICON, ICON_SMALL, NULL, GetIconCallback, ICON_SMALL);
    break;

  case ICON_SMALL:
    if (result != NULL) {
      sWindowData[window].smallIcon = (HICON)result;
      SendMessage(gWindow, NCORE_WINDOW_ICON_CHANGED, (WPARAM)window, NULL);
    } else {
      SendMessageCallback(window, WM_GETICON, ICON_SMALL2, NULL, GetIconCallback, ICON_SMALL2);
    }
    break;

  case ICON_SMALL2:
    if (result != NULL) {
      sWindowData[window].smallIcon = (HICON)result;
    } else {
      HICON icon = (HICON)GetClassLongPtr(window, GCLP_HICONSM);
      if (!icon) {
        icon = sDefaultIcon;
      }
      sWindowData[window].smallIcon = icon;
    }
    SendMessage(gWindow, NCORE_WINDOW_ICON_CHANGED, (WPARAM)window, NULL);
    break;
  }
}
Example #4
0
//=================================================================
//--------------------------+++--> toggle calendar (close or open):
void ToggleCalendar(int type)   //---------------------------+++-->
{
	HWND calendar = api.GetCalendar();
	int is_custom = api.GetInt("Calendar", "bCustom", 0);
	if(calendar){
		if(is_custom)
			SetForegroundWindow(calendar);
		return;
	}
	if(api.OS >= TOS_VISTA && (!is_custom && type!=1)){
		// Windows 10 workaround as SendMessage doesn't work any longer (no error given)
		SendMessageCallback(g_hwndClock, WM_USER+102, 1, 0, ToggleCalendar_done, 0);//1=open, 0=close
	}else{
		char cal[MAX_PATH];
		memcpy(cal, api.root, api.root_len+1);
		add_title(cal,"misc\\XPCalendar.exe");
		api.Exec(cal,NULL,g_hwndTClockMain);
	}
}
Example #5
0
void
do_test(int count)
{
    MSG msg;
    int total_slept = 0;

    did_send_callback[count] = FALSE;
    if (!SendMessageCallback(hwnd, WM_NULL, 0, 0, &SendAsyncProc, count)) {
        print("SendMsg failed.\n");
        return;
    }

    while (!did_send_callback[count] && total_slept < MAX_SLEEP) {
        Sleep(100);
        total_slept += 100;
        /* FIXME - all callbacks will have the same after address, need to mix in a
         * GetMessage or some such so can verify order of callback stack.  */
        PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
    }
    if (total_slept >= MAX_SLEEP) {
        print("Callback never delivered.\n");
    }
}
Example #6
0
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    AssertPtr(pCtx);

    LRESULT rc = 0;

    switch (msg)
    {
        case WM_CLIPBOARDUPDATE:
        {
            Log(("WM_CLIPBOARDUPDATE\n"));

            if (GetClipboardOwner() != hwnd)
            {
                /* Clipboard was updated by another application. */
                vboxClipboardChanged(pCtx);
            }
        } break;

        case WM_CHANGECBCHAIN:
        {
            if (vboxClipboardIsNewAPI(pCtx))
            {
                rc = DefWindowProc(hwnd, msg, wParam, lParam);
                break;
            }

            HWND hwndRemoved = (HWND)wParam;
            HWND hwndNext    = (HWND)lParam;

            LogFlowFunc(("WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));

            if (hwndRemoved == pCtx->hwndNextInChain)
            {
                /* The window that was next to our in the chain is being removed.
                 * Relink to the new next window. */
                pCtx->hwndNextInChain = hwndNext;
            }
            else
            {
                if (pCtx->hwndNextInChain)
                {
                    /* Pass the message further. */
                    DWORD_PTR dwResult;
                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                    if (!rc)
                        rc = (LRESULT) dwResult;
                }
            }
        } break;

        case WM_DRAWCLIPBOARD:
        {
            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd));

            if (GetClipboardOwner() != hwnd)
            {
                /* Clipboard was updated by another application. */
                /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
                int vboxrc = vboxClipboardChanged(pCtx);
                if (RT_FAILURE(vboxrc))
                    LogFlowFunc(("vboxClipboardChanged failed, rc = %Rrc\n", vboxrc));
            }

            if (pCtx->hwndNextInChain)
            {
                /* Pass the message to next windows in the clipboard chain. */
                SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL);
            }
        } break;

        case WM_TIMER:
        {
            if (vboxClipboardIsNewAPI(pCtx))
                break;

            HWND hViewer = GetClipboardViewer();

            /* Re-register ourselves in the clipboard chain if our last ping
             * timed out or there seems to be no valid chain. */
            if (!hViewer || pCtx->fCBChainPingInProcess)
            {
                vboxClipboardRemoveFromCBChain(pCtx);
                vboxClipboardAddToCBChain(pCtx);
            }
            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
             * processed by ourselves to the chain. */
            pCtx->fCBChainPingInProcess = TRUE;
            hViewer = GetClipboardViewer();
            if (hViewer)
                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx);
        } break;

        case WM_CLOSE:
        {
            /* Do nothing. Ignore the message. */
        } break;

        case WM_RENDERFORMAT:
        {
            /* Insert the requested clipboard format data into the clipboard. */
            uint32_t u32Format = 0;
            UINT format = (UINT)wParam;

            LogFlowFunc(("WM_RENDERFORMAT, format = %x\n", format));
            switch (format)
            {
                case CF_UNICODETEXT:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                    break;

                case CF_DIB:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                    break;

                default:
                    if (format >= 0xC000)
                    {
                        TCHAR szFormatName[256];

                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
                        if (cActual)
                        {
                            if (strcmp (szFormatName, "HTML Format") == 0)
                            {
                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
                            }
                        }
                    }
                    break;
            }

            if (u32Format == 0)
            {
                /* Unsupported clipboard format is requested. */
                LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format));
                EmptyClipboard();
            }
            else
            {
                const uint32_t cbPrealloc = 4096; /** @todo r=andy Make it dynamic for supporting larger text buffers! */
                uint32_t cb = 0;

                /* Preallocate a buffer, most of small text transfers will fit into it. */
                HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
                LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));

                if (hMem)
                {
                    void *pMem = GlobalLock(hMem);
                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                    if (pMem)
                    {
                        /* Read the host data to the preallocated buffer. */
                        int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cbPrealloc, &cb);
                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));

                        if (RT_SUCCESS(vboxrc))
                        {
                            if (cb == 0)
                            {
                                /* 0 bytes returned means the clipboard is empty.
                                 * Deallocate the memory and set hMem to NULL to get to
                                 * the clipboard empty code path. */
                                GlobalUnlock(hMem);
                                GlobalFree(hMem);
                                hMem = NULL;
                            }
                            else if (cb > cbPrealloc)
                            {
                                GlobalUnlock(hMem);

                                /* The preallocated buffer is too small, adjust the size. */
                                hMem = GlobalReAlloc(hMem, cb, 0);
                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                                if (hMem)
                                {
                                    pMem = GlobalLock(hMem);
                                    LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                                    if (pMem)
                                    {
                                        /* Read the host data to the preallocated buffer. */
                                        uint32_t cbNew = 0;
                                        vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, u32Format, pMem, cb, &cbNew);
                                        LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));

                                        if (RT_SUCCESS (vboxrc) && cbNew <= cb)
                                        {
                                            cb = cbNew;
                                        }
                                        else
                                        {
                                            GlobalUnlock(hMem);
                                            GlobalFree(hMem);
                                            hMem = NULL;
                                        }
                                    }
                                    else
                                    {
                                        GlobalFree(hMem);
                                        hMem = NULL;
                                    }
                                }
                            }

                            if (hMem)
                            {
                                /* pMem is the address of the data. cb is the size of returned data. */
                                /* Verify the size of returned text, the memory block for clipboard
                                 * must have the exact string size.
                                 */
                                if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                                {
                                    size_t cbActual = 0;
                                    HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
                                    if (FAILED (hrc))
                                    {
                                        /* Discard invalid data. */
                                        GlobalUnlock(hMem);
                                        GlobalFree(hMem);
                                        hMem = NULL;
                                    }
                                    else
                                    {
                                        /* cbActual is the number of bytes, excluding those used
                                         * for the terminating null character.
                                         */
                                        cb = (uint32_t)(cbActual + 2);
                                    }
                                }
                            }

                            if (hMem)
                            {
                                GlobalUnlock(hMem);

                                hMem = GlobalReAlloc(hMem, cb, 0);
                                LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                                if (hMem)
                                {
                                    /* 'hMem' contains the host clipboard data.
                                     * size is 'cb' and format is 'format'. */
                                    HANDLE hClip = SetClipboardData(format, hMem);
                                    LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));

                                    if (hClip)
                                    {
                                        /* The hMem ownership has gone to the system. Finish the processing. */
                                        break;
                                    }

                                    /* Cleanup follows. */
                                }
                            }
                        }
                        if (hMem)
                            GlobalUnlock(hMem);
                    }
                    if (hMem)
                        GlobalFree(hMem);
                }

                /* Something went wrong. */
                EmptyClipboard();
            }
        } break;

        case WM_RENDERALLFORMATS:
        {
            /* Do nothing. The clipboard formats will be unavailable now, because the
             * windows is to be destroyed and therefore the guest side becomes inactive.
             */
            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                EmptyClipboard();
                CloseClipboard();
            }
            else
            {
                LogFlowFunc(("WM_RENDERALLFORMATS: Failed to open clipboard! rc: %Rrc\n", vboxrc));
            }
        } break;

        case WM_USER:
        {
            /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
            uint32_t u32Formats = (uint32_t)lParam;

            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                EmptyClipboard();

                HANDLE hClip = NULL;

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
                    hClip = SetClipboardData(CF_UNICODETEXT, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
                    hClip = SetClipboardData(CF_DIB, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    LogFlowFunc(("WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
                    if (format != 0)
                    {
                        hClip = SetClipboardData(format, NULL);
                    }
                }

                CloseClipboard();
                LogFlowFunc(("WM_USER: hClip = %p, err = %ld\n", hClip, GetLastError ()));
            }
            else
            {
                LogFlowFunc(("WM_USER: Failed to open clipboard! error = %Rrc\n", vboxrc));
            }
        } break;

        case WM_USER + 1:
        {
            /* Send data in the specified format to the host. */
            uint32_t u32Formats = (uint32_t)lParam;
            HANDLE hClip = NULL;

            int vboxrc = vboxOpenClipboard(hwnd);
            if (RT_SUCCESS(vboxrc))
            {
                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    hClip = GetClipboardData(CF_DIB);

                    if (hClip != NULL)
                    {
                        LPVOID lp = GlobalLock(hClip);
                        if (lp != NULL)
                        {
                            LogFlowFunc(("WM_USER + 1: CF_DIB\n"));
                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
                                                              lp, GlobalSize(hClip));
                            GlobalUnlock(hClip);
                        }
                        else
                        {
                            hClip = NULL;
                        }
                    }
                }
                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    hClip = GetClipboardData(CF_UNICODETEXT);

                    if (hClip != NULL)
                    {
                        LPWSTR uniString = (LPWSTR)GlobalLock(hClip);

                        if (uniString != NULL)
                        {
                            LogFlowFunc(("WM_USER + 1: CF_UNICODETEXT\n"));
                            vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
                                                              uniString, (lstrlenW(uniString) + 1) * 2);
                            GlobalUnlock(hClip);
                        }
                        else
                        {
                            hClip = NULL;
                        }
                    }
                }
                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    if (format != 0)
                    {
                        hClip = GetClipboardData(format);
                        if (hClip != NULL)
                        {
                            LPVOID lp = GlobalLock(hClip);

                            if (lp != NULL)
                            {
                                LogFlowFunc(("WM_USER + 1: CF_HTML\n"));
                                vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML,
                                                                  lp, GlobalSize(hClip));
                                GlobalUnlock(hClip);
                            }
                            else
                            {
                                hClip = NULL;
                            }
                        }
                    }
                }

                CloseClipboard();
            }
            else
            {
                LogFlowFunc(("WM_USER: Failed to open clipboard! rc: %Rrc\n", vboxrc));
            }

            if (hClip == NULL)
            {
                /* Requested clipboard format is not available, send empty data. */
                VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0);
            }
        } break;

        case WM_DESTROY:
        {
            vboxClipboardRemoveFromCBChain(pCtx);
            if (pCtx->timerRefresh)
                KillTimer(pCtx->hwnd, 0);
            /*
             * don't need to call PostQuitMessage cause
             * the VBoxTray already finished a message loop
             */
        } break;

        default:
        {
            rc = DefWindowProc(hwnd, msg, wParam, lParam);
        }
    }

#ifndef DEBUG_andy
    LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc));
#endif
    return rc;
}
static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    AssertPtr(pCtx);

    const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win;

    LRESULT rc = 0;

    switch (msg)
    {
        case WM_CLIPBOARDUPDATE:
        {
           Log(("WM_CLIPBOARDUPDATE\n"));

           if (GetClipboardOwner() != hwnd)
           {
               /* Clipboard was updated by another application. */
               uint32_t uFormats;
               int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
               if (RT_SUCCESS(vboxrc))
                   vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
           }
        }
        break;

        case WM_CHANGECBCHAIN:
        {
           if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
           {
               rc = DefWindowProc(hwnd, msg, wParam, lParam);
               break;
           }

           HWND hWndRemoved = (HWND)wParam;
           HWND hWndNext    = (HWND)lParam;

           LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd));

           if (hWndRemoved == pWinCtx->hWndNextInChain)
           {
               /* The window that was next to our in the chain is being removed.
                * Relink to the new next window. */
               pWinCtx->hWndNextInChain = hWndNext;
           }
           else
           {
               if (pWinCtx->hWndNextInChain)
               {
                   /* Pass the message further. */
                   DWORD_PTR dwResult;
                   rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,
                                           VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult);
                   if (!rc)
                       rc = (LRESULT)dwResult;
               }
           }
        }
        break;

        case WM_DRAWCLIPBOARD:
        {
           LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));

           if (GetClipboardOwner() != hwnd)
           {
               /* Clipboard was updated by another application. */
               /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
               uint32_t uFormats;
               int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats);
               if (RT_SUCCESS(vboxrc))
                   vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
           }

           if (pWinCtx->hWndNextInChain)
           {
               /* Pass the message to next windows in the clipboard chain. */
               SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL);
           }
        }
        break;

        case WM_TIMER:
        {
           if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
               break;

           HWND hViewer = GetClipboardViewer();

           /* Re-register ourselves in the clipboard chain if our last ping
            * timed out or there seems to be no valid chain. */
           if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
           {
               VBoxClipboardWinRemoveFromCBChain(pWinCtx);
               VBoxClipboardWinAddToCBChain(pWinCtx);
           }

           /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
            * processed by ourselves to the chain. */
           pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;

           hViewer = GetClipboardViewer();
           if (hViewer)
               SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
                                   VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
        }
        break;

        case WM_CLOSE:
        {
           /* Do nothing. Ignore the message. */
        }
        break;

        case WM_RENDERFORMAT:
        {
           /* Insert the requested clipboard format data into the clipboard. */
           uint32_t fFormat = VBOX_SHARED_CLIPBOARD_FMT_NONE;

           const UINT cfFormat = (UINT)wParam;
           switch (cfFormat)
           {
              case CF_UNICODETEXT:
                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                  break;

              case CF_DIB:
                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                  break;

#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
              case CF_HDROP:
                  fFormat = VBOX_SHARED_CLIPBOARD_FMT_URI_LIST;
                  break;
#endif
              default:
                  if (cfFormat >= 0xC000) /** @todo r=andy Explain. */
                  {
                      TCHAR szFormatName[256]; /** @todo r=andy Do we need Unicode support here as well? */

                      int cActual = GetClipboardFormatName(cfFormat, szFormatName, sizeof(szFormatName) / sizeof(TCHAR));
                      if (cActual)
                      {
                          if (strcmp(szFormatName, "HTML Format") == 0)
                              fFormat = VBOX_SHARED_CLIPBOARD_FMT_HTML;
                      }
                  }
                  break;
           }

           LogFunc(("WM_RENDERFORMAT: format=%u -> fFormat=0x%x\n", cfFormat, fFormat));

           if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE)
           {
               /* Unsupported clipboard format is requested. */
               LogRel(("Clipboard: Unsupported clipboard format requested (0x%x)\n", fFormat));
               VBoxClipboardWinClear();
           }
#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
           else if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
           {

           }
#endif
           else
           {
               const uint32_t cbPrealloc = _4K;
               uint32_t cb = 0;

               /* Preallocate a buffer, most of small text transfers will fit into it. */
               HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
               LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));

               if (hMem)
               {
                   void *pMem = GlobalLock(hMem);
                   LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                   if (pMem)
                   {
                       /* Read the host data to the preallocated buffer. */
                       int vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);
                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  vboxrc));

                       if (RT_SUCCESS(vboxrc))
                       {
                           if (cb == 0)
                           {
                               /* 0 bytes returned means the clipboard is empty.
                                * Deallocate the memory and set hMem to NULL to get to
                                * the clipboard empty code path. */
                               GlobalUnlock(hMem);
                               GlobalFree(hMem);
                               hMem = NULL;
                           }
                           else if (cb > cbPrealloc)
                           {
                               GlobalUnlock(hMem);

                               /* The preallocated buffer is too small, adjust the size. */
                               hMem = GlobalReAlloc(hMem, cb, 0);
                               LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                               if (hMem)
                               {
                                   pMem = GlobalLock(hMem);
                                   LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));

                                   if (pMem)
                                   {
                                       /* Read the host data to the preallocated buffer. */
                                       uint32_t cbNew = 0;
                                       vboxrc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
                                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));

                                       if (RT_SUCCESS(vboxrc) && cbNew <= cb)
                                       {
                                           cb = cbNew;
                                       }
                                       else
                                       {
                                           GlobalUnlock(hMem);
                                           GlobalFree(hMem);
                                           hMem = NULL;
                                       }
                                   }
                                   else
                                   {
                                       GlobalFree(hMem);
                                       hMem = NULL;
                                   }
                               }
                           }

                           if (hMem)
                           {
                               /* pMem is the address of the data. cb is the size of returned data. */
                               /* Verify the size of returned text, the memory block for clipboard
                                * must have the exact string size.
                                */
                               if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                               {
                                   size_t cbActual = 0;
                                   HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
                                   if (FAILED(hrc))
                                   {
                                       /* Discard invalid data. */
                                       GlobalUnlock(hMem);
                                       GlobalFree(hMem);
                                       hMem = NULL;
                                   }
                                   else
                                   {
                                       /* cbActual is the number of bytes, excluding those used
                                        * for the terminating null character.
                                        */
                                       cb = (uint32_t)(cbActual + 2);
                                   }
                               }
                           }

                           if (hMem)
                           {
                               GlobalUnlock(hMem);

                               hMem = GlobalReAlloc(hMem, cb, 0);
                               LogFlowFunc(("Reallocated hMem = %p\n", hMem));

                               if (hMem)
                               {
                                   /* 'hMem' contains the host clipboard data.
                                    * size is 'cb' and format is 'format'. */
                                   HANDLE hClip = SetClipboardData(cfFormat, hMem);
                                   LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));

                                   if (hClip)
                                   {
                                       /* The hMem ownership has gone to the system. Finish the processing. */
                                       break;
                                   }

                                   /* Cleanup follows. */
                               }
                           }
                       }
                       if (hMem)
                           GlobalUnlock(hMem);
                   }
                   if (hMem)
                       GlobalFree(hMem);
               }

               /* Something went wrong. */
               VBoxClipboardWinClear();
           }
        }
        break;

        case WM_RENDERALLFORMATS:
        {
           /* Do nothing. The clipboard formats will be unavailable now, because the
            * windows is to be destroyed and therefore the guest side becomes inactive.
            */
           int vboxrc = VBoxClipboardWinOpen(hwnd);
           if (RT_SUCCESS(vboxrc))
           {
               VBoxClipboardWinClear();
               VBoxClipboardWinClose();
           }
        }
        break;

        case VBOX_CLIPBOARD_WM_SET_FORMATS:
        {
           /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
           VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;

           LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: fFormats=0x%x\n", fFormats));

           int vboxrc = VBoxClipboardWinOpen(hwnd);
           if (RT_SUCCESS(vboxrc))
           {
               VBoxClipboardWinClear();

               HANDLE hClip = NULL;

               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                   hClip = SetClipboardData(CF_UNICODETEXT, NULL);

               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                   hClip = SetClipboardData(CF_DIB, NULL);

               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
               {
                   UINT format = RegisterClipboardFormat("HTML Format");
                   if (format != 0)
                       hClip = SetClipboardData(format, NULL);
               }

#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
               if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
                   hClip = SetClipboardData(CF_HDROP, NULL);
#endif

               /** @todo Implement more flexible clipboard precedence for supported formats. */

               if (hClip == NULL)
                   LogRel(("Clipboard: Unsupported format(s) from host (0x%x), ignoring\n", fFormats));

               VBoxClipboardWinClose();

               LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError()));
           }
        }
        break;

        case VBOX_CLIPBOARD_WM_READ_DATA:
        {
           /* Send data in the specified format to the host. */
           uint32_t u32Formats = (uint32_t)lParam;
           HANDLE hClip = NULL;

           LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats));

           int vboxrc = VBoxClipboardWinOpen(hwnd);
           if (RT_SUCCESS(vboxrc))
           {
               if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
               {
                   hClip = GetClipboardData(CF_DIB);

                   if (hClip != NULL)
                   {
                       LPVOID lp = GlobalLock(hClip);
                       if (lp != NULL)
                       {
                           vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
                                                             lp, GlobalSize(hClip));
                           GlobalUnlock(hClip);
                       }
                       else
                       {
                           hClip = NULL;
                       }
                   }
               }
               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
               {
                   hClip = GetClipboardData(CF_UNICODETEXT);

                   if (hClip != NULL)
                   {
                       LPWSTR uniString = (LPWSTR)GlobalLock(hClip);

                       if (uniString != NULL)
                       {
                           vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
                                                             uniString, (lstrlenW(uniString) + 1) * 2);
                           GlobalUnlock(hClip);
                       }
                       else
                       {
                           hClip = NULL;
                       }
                   }
               }
               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
               {
                   UINT format = RegisterClipboardFormat("HTML Format");
                   if (format != 0)
                   {
                       hClip = GetClipboardData(format);
                       if (hClip != NULL)
                       {
                           LPVOID lp = GlobalLock(hClip);

                           if (lp != NULL)
                           {
                               vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_HTML,
                                                                 lp, GlobalSize(hClip));
                               GlobalUnlock(hClip);
                           }
                           else
                           {
                               hClip = NULL;
                           }
                       }
                   }
               }
#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
               else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
               {
                   hClip = GetClipboardData(CF_HDROP);
                   if (hClip)
                   {
                       HDROP hDrop = (HDROP)GlobalLock(hClip);
                       if (hDrop)
                       {
       /*                    vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
                                                             );*/
                           GlobalUnlock(hClip);
                       }
                       else
                       {
                           hClip = NULL;
                       }
                   }
               }
#endif
               VBoxClipboardWinClose();
           }

           if (hClip == NULL)
           {
               /* Requested clipboard format is not available, send empty data. */
               VbglR3ClipboardWriteData(pCtx->u32ClientID, 0, NULL, 0);
           }
        }
        break;

        case WM_DESTROY:
        {
           VBoxClipboardWinRemoveFromCBChain(pWinCtx);
           if (pWinCtx->oldAPI.timerRefresh)
               KillTimer(pWinCtx->hWnd, 0);
           /*
            * don't need to call PostQuitMessage cause
            * the VBoxTray already finished a message loop
            */
        }
        break;

        default:
        {
           rc = DefWindowProc(hwnd, msg, wParam, lParam);
        }
        break;
    }

#ifndef DEBUG_andy
    LogFlowFunc(("vboxClipboardProcessMsg returned with rc = %ld\n", rc));
#endif
    return rc;
}
static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT rc = 0;

    VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;

    switch (msg)
    {
        case WM_CHANGECBCHAIN:
        {
            Log(("WM_CHANGECBCHAIN\n"));

            HWND hwndRemoved = (HWND)wParam;
            HWND hwndNext    = (HWND)lParam;

            if (hwndRemoved == pCtx->hwndNextInChain)
            {
                /* The window that was next to our in the chain is being removed.
                 * Relink to the new next window.
                 */
                pCtx->hwndNextInChain = hwndNext;
            }
            else
            {
                if (pCtx->hwndNextInChain)
                {
                    /* Pass the message further. */
                    DWORD_PTR dwResult;
                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                    if (!rc)
                        rc = (LRESULT)dwResult;
                }
            }
        } break;

        case WM_DRAWCLIPBOARD:
        {
            Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));

            if (GetClipboardOwner () != hwnd)
            {
                /* Clipboard was updated by another application. */
                vboxClipboardChanged (pCtx);
            }

            if (pCtx->hwndNextInChain)
            {
                /* Pass the message to next windows in the clipboard chain. */
                DWORD_PTR dwResult;
                rc = SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                if (!rc)
                    rc = dwResult;
            }
        } break;

        case WM_TIMER:
        {
            HWND hViewer = GetClipboardViewer();

            /* Re-register ourselves in the clipboard chain if our last ping
             * timed out or there seems to be no valid chain. */
            if (!hViewer || pCtx->fCBChainPingInProcess)
            {
                removeFromCBChain(pCtx);
                addToCBChain(pCtx);
            }
            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
             * processed by ourselves to the chain. */
            pCtx->fCBChainPingInProcess = TRUE;
            hViewer = GetClipboardViewer();
            if (hViewer)
                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
        } break;

        case WM_CLOSE:
        {
            /* Do nothing. Ignore the message. */
        } break;

        case WM_RENDERFORMAT:
        {
            /* Insert the requested clipboard format data into the clipboard. */
            uint32_t u32Format = 0;

            UINT format = (UINT)wParam;

            Log(("WM_RENDERFORMAT %d\n", format));

            switch (format)
            {
                case CF_UNICODETEXT:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                    break;

                case CF_DIB:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                    break;

                default:
                    if (format >= 0xC000)
                    {
                        TCHAR szFormatName[256];

                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));

                        if (cActual)
                        {
                            if (strcmp (szFormatName, "HTML Format") == 0)
                            {
                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
                            }
                        }
                    }
                    break;
            }

            if (u32Format == 0 || pCtx->pClient == NULL)
            {
                /* Unsupported clipboard format is requested. */
                Log(("WM_RENDERFORMAT unsupported format requested or client is not active.\n"));
                EmptyClipboard ();
            }
            else
            {
                int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format);

                dprintf(("vboxClipboardReadDataFromClient vboxrc = %d\n", vboxrc));

                if (   RT_SUCCESS (vboxrc)
                    && pCtx->pClient->data.pv != NULL
                    && pCtx->pClient->data.cb > 0
                    && pCtx->pClient->data.u32Format == u32Format)
                {
                    HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);

                    dprintf(("hMem %p\n", hMem));

                    if (hMem)
                    {
                        void *pMem = GlobalLock (hMem);

                        dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));

                        if (pMem)
                        {
                            Log(("WM_RENDERFORMAT setting data\n"));

                            if (pCtx->pClient->data.pv)
                            {
                                memcpy (pMem, pCtx->pClient->data.pv, pCtx->pClient->data.cb);

                                RTMemFree (pCtx->pClient->data.pv);
                                pCtx->pClient->data.pv        = NULL;
                            }

                            pCtx->pClient->data.cb        = 0;
                            pCtx->pClient->data.u32Format = 0;

                            /* The memory must be unlocked before inserting to the Clipboard. */
                            GlobalUnlock (hMem);

                            /* 'hMem' contains the host clipboard data.
                             * size is 'cb' and format is 'format'.
                             */
                            HANDLE hClip = SetClipboardData (format, hMem);

                            dprintf(("vboxClipboardHostEvent hClip %p\n", hClip));

                            if (hClip)
                            {
                                /* The hMem ownership has gone to the system. Nothing to do. */
                                break;
                            }
                        }

                        GlobalFree (hMem);
                    }
                }

                RTMemFree (pCtx->pClient->data.pv);
                pCtx->pClient->data.pv        = NULL;
                pCtx->pClient->data.cb        = 0;
                pCtx->pClient->data.u32Format = 0;

                /* Something went wrong. */
                EmptyClipboard ();
            }
        } break;

        case WM_RENDERALLFORMATS:
        {
            Log(("WM_RENDERALLFORMATS\n"));

            /* Do nothing. The clipboard formats will be unavailable now, because the
             * windows is to be destroyed and therefore the guest side becomes inactive.
             */
            if (OpenClipboard (hwnd))
            {
                EmptyClipboard();

                CloseClipboard();
            }
        } break;

        case WM_USER:
        {
            if (pCtx->pClient == NULL || pCtx->pClient->fMsgFormats)
            {
                /* Host has pending formats message. Ignore the guest announcement,
                 * because host clipboard has more priority.
                 */
                break;
            }

            /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
            uint32_t u32Formats = (uint32_t)lParam;

            Log(("WM_USER u32Formats = %02X\n", u32Formats));

            if (OpenClipboard (hwnd))
            {
                EmptyClipboard();

                Log(("WM_USER emptied clipboard\n"));

                HANDLE hClip = NULL;

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));

                    hClip = SetClipboardData (CF_UNICODETEXT, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));

                    hClip = SetClipboardData (CF_DIB, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
                    if (format != 0)
                    {
                        hClip = SetClipboardData (format, NULL);
                    }
                }

                CloseClipboard();

                dprintf(("window proc WM_USER: hClip %p, err %d\n", hClip, GetLastError ()));
            }
            else
            {
                dprintf(("window proc WM_USER: failed to open clipboard\n"));
            }
        } break;

        default:
        {
            Log(("WM_ %p\n", msg));
            rc = DefWindowProc (hwnd, msg, wParam, lParam);
        }
    }

    Log(("WM_ rc %d\n", rc));
    return rc;
}
DWORD WINAPI Hack( LPVOID lpVoid )
{
	TCHAR msg[ 4096 ];
	LPHACK_PARAMS lphp = (LPHACK_PARAMS) lpVoid;
	HWND hWnd = lphp -> myHwnd;
	const int iMyId = lphp -> iMyId;
	LPTARGETINFO lpTarget = lphp -> lpTarget;
	LPTSTR * lpszStatus = lphp -> lpszStatus;
	DWORD dwTargetProcessId = lpTarget -> dwProcessId;
	DWORD dwPrevSuspendCount;
	DWORD dwTotalChanges = 0;
	int iPrevThreadCount = 0;
	int errorflag = 0;

	const RECT minirect = { 20L, 20L + 90L * iMyId, 479L, 40L + 90L * iMyId };
	const RECT hackrect = { 20L, 20L + 90L * iMyId, 479L, 100L + 90L * iMyId };

	TCHAR lpszEnemyPath[ MAX_PATH * 2 ] = _T("");
	TCHAR lpszEnemyExe[ MAX_PATH * 2 ] = _T("");
	lstrcpy( lpszEnemyPath, lpTarget->szPath );
	lstrcpy( lpszEnemyExe, lpTarget->szExe );

	int i , j;

	HANDLE hProcess = NULL;
	DWORD dwOldPriority = NORMAL_PRIORITY_CLASS;
	int iOpenThreadRetry = 0;
	int iSuspendThreadRetry = 0;
	int iResumeThreadRetry = 0;
	SYSTEMTIME st;

	for( i = 0 + iMyId * 4; i < 4 + iMyId * 4; i++ )
	{
		lstrcpy( lpszStatus[ i ], TEXT( "" ) );
	}

	lstrcpy( lpszStatus[ 2 + iMyId * 4 ], lpszEnemyPath );

#if !defined( _UNICODE )
	// for watching...
	if( iMyId == 2 && lstrlen( lpszEnemyPath ) >= 19 )
	{
		lpszStatus[ 2 + iMyId * 4 ][ 15 ] = '\0';
		PathToExeEx( lpszStatus[ 2 + iMyId * 4 ], MAX_PATH * 2 );
	}
#endif

	AdjustLength( lpszStatus[ 2 + iMyId * 4 ] );
	
	for( DWORD dwOuterLoops = 0; 
		g_bHack[ iMyId ];
		dwOuterLoops++ )
	{
		if( dwOuterLoops == 0UL )
		{
			hProcess = OpenProcess(
				PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION ,
				FALSE,
				dwTargetProcessId
			);
			if( hProcess )
			{
				dwOldPriority = GetPriorityClass( hProcess );
				wsprintf( msg, TEXT( "Target #%d: \"%s\"\r\n\tProcess ID = 0x%08lX : hProcess = 0x%08lX (Priority: %lu)" ),
					iMyId + 1, lpszEnemyPath, dwTargetProcessId, hProcess, dwOldPriority
				);
				WriteDebugLog( msg );
				if( g_bRealTime )
				{
					WriteDebugLog( SetPriorityClass( hProcess, IDLE_PRIORITY_CLASS )?
						TEXT( "SetPriorityClass OK" ) : TEXT( "SetPriorityClass failed" ) );
				}
			}
			else
			{
				WriteDebugLog( TEXT( "OpenProcess failed." ) );

				GetLocalTime( &st );
				wsprintf( lpszStatus[ 1 + iMyId * 4 ], TEXT( "Process ID = n/a" ) );
				wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d Initial OpenThread failed" ),
					st.wHour, st.wMinute, st.wSecond
				);
				g_dwTargetProcessId[ iMyId ] = TARGET_PID_NOT_SET;

				// This is needed as a workaround
				UpdateStatus( hWnd );

				if( ReleaseSemaphore( hSemaphore[ iMyId ], 1L, (LPLONG) NULL ) )
				{
					wsprintf( msg, TEXT( "* ReleaseSemaphore #%d in Hack()" ), iMyId + 1 );
					WriteDebugLog( msg );
				}
				else
				{
					wsprintf( msg, TEXT( "[!] Target #%d : ReleaseSemaphore failed in Hack(): ErrCode %lu" ),
						iMyId + 1, GetLastError() );
					WriteDebugLog( msg );
				}
				lphp->lpTarget->dwProcessId = TARGET_PID_NOT_SET;


				if( PathToProcess( lpszEnemyPath ) == ( DWORD ) -1 )
				{
					SendMessageCallback( hWnd, WM_USER_STOP, (WPARAM) iMyId, (LPARAM) TARGET_MISSING,
						(SENDASYNCPROC) DummyCallback, (DWORD) hWnd );

					InvalidateRect( hWnd, NULL, TRUE );
					return TARGET_MISSING;
				}
				else
				{
					SendMessageCallback( hWnd, WM_USER_STOP, (WPARAM) iMyId, (LPARAM) THREAD_NOT_OPENED,
						(SENDASYNCPROC) DummyCallback, (DWORD) hWnd );

					
					InvalidateRect( hWnd, NULL, TRUE );
					return THREAD_NOT_OPENED;

				}

			}

			
			wsprintf( lpszStatus[ 0 + iMyId * 4 ],
				TEXT( "Target #%d [ -%d%% ]" ),
				iMyId + 1,
				g_Slider[ iMyId ]
			);
		
		} // endif( dwOuterLoops == 0 )



		DWORD dwThreadId[ MAX_THREAD_CNT ];
		int iThreadCount = ListProcessThreads( dwTargetProcessId, dwThreadId );


		// ----------------------- @@@
		if( iThreadCount == 0 )
		{
			GetLocalTime( &st );
			wsprintf( lpszStatus[ 1 + iMyId * 4 ], TEXT( "Process ID = n/a" ) );
			wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d No threads" ),
				st.wHour, st.wMinute, st.wSecond
			);
			g_dwTargetProcessId[ iMyId ] = TARGET_PID_NOT_SET;
			if( hProcess ) 
			{
				SetPriorityClass( hProcess, dwOldPriority );
				CloseHandle( hProcess );
			}

			if( ReleaseSemaphore( hSemaphore[ iMyId ], 1L, (LPLONG) NULL ) )
			{
				wsprintf( msg, TEXT( "* TARGET_MISSING #%d : ReleaseSemaphore in Hack()" ), iMyId + 1 );
				WriteDebugLog( msg );
			}
			else
			{
				wsprintf( msg, TEXT( "[!] Target #%d : ReleaseSemaphore failed in Hack(): ErrCode %lu" ),
					iMyId + 1, GetLastError() );
				WriteDebugLog( msg );
			}

			g_bBlock = TRUE;
			
			WriteDebugLog( TEXT("SendMessage Doing...") );

			SendMessageCallback( hWnd, WM_USER_STOP, (WPARAM) iMyId, (LPARAM) TARGET_MISSING,
				(SENDASYNCPROC) DummyCallback, (DWORD) hWnd );

			WriteDebugLog( TEXT("SendMessage Done!") );

			for( int z = 0; z < 10; z++ )
			{
				if( ! g_bBlock )
				{
					wsprintf( msg, TEXT("g_bBlock cleared at z=%d"), z );
					WriteDebugLog( msg );
					break;
				}
				Sleep( 10UL );
			}

			lphp->lpTarget->dwProcessId = TARGET_PID_NOT_SET;
// [email protected] beta
// This is not needed because WM_USER_STOP will do the same,
// and this thread will die (so thie order wil be probably void) anyway
//			InvalidateRect( hWnd, NULL, TRUE );
			return TARGET_MISSING;
		}

		if( dwOuterLoops == 0UL )
		{
			iPrevThreadCount = iThreadCount;
			wsprintf( msg, TEXT( "Target #%d : iThreadCount = %3d" ), iMyId + 1, iThreadCount );
			WriteDebugLog( msg );
		}
		else if( dwOuterLoops % 50UL == 0UL )
		{
			wsprintf( msg, TEXT( "Target #%d : Loops %5d, ThreadCnt %3d (Prev %3d)" ), 
				iMyId + 1, dwOuterLoops, iThreadCount, iPrevThreadCount );
			WriteDebugLog( msg );
		}

		wsprintf( lpszStatus[ 1 + iMyId * 4 ], TEXT( "Process ID = 0x%04X %04X [ %d %s ]" ),
			HIWORD( dwTargetProcessId ),
			LOWORD( dwTargetProcessId ),
			iThreadCount,
			( iThreadCount > 1 ? TEXT( "Threads" ) : TEXT( "Thread" ) )
		);
		GetLocalTime( &st );
		if( iThreadCount != iPrevThreadCount || errorflag )
		{
			dwTotalChanges++;
			wsprintf( msg, TEXT( "Target #%d : iThreadCount = %3d (Prev = %d)" ), iMyId + 1, iThreadCount, iPrevThreadCount );
			WriteDebugLog( msg );
			iPrevThreadCount = iThreadCount;
			errorflag = 0;
			wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d Target Re-Locked On: OK" ),
				st.wHour, st.wMinute, st.wSecond
			);
		}
		else
		{
			wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d %s: OK" ),
				st.wHour, st.wMinute, st.wSecond,
				dwOuterLoops == 0 ? TEXT( "Started" ) : TEXT( "Calm" )
			);
		}

		HANDLE hTarget[ MAX_THREAD_CNT ];
		ZeroMemory( hTarget, sizeof( HANDLE ) * MAX_THREAD_CNT );
		int iOpenedThread = 0;
		for( i = 0; i < iThreadCount; i++ )
		{
			hTarget[ i ] = OpenThread( THREAD_SUSPEND_RESUME, FALSE, dwThreadId[ i ] );
			if( hTarget[ i ] == NULL )
			{
				wsprintf( msg, TEXT( "[!] Target #%d : OpenThread failed: Thread #%03d, ThreadId 0x%08lX" ),
					iMyId + 1, i + 1, dwThreadId[ i ] );
				WriteDebugLog( msg );
			}
			else
			{
				iOpenedThread++;
			}
		}

		// ###----------------
		if( iOpenedThread == 0
			||
			iOpenedThread != iThreadCount && iOpenThreadRetry > 10
			||
			iSuspendThreadRetry > 100
			||
			iResumeThreadRetry > 50			
		)
		{
			GetLocalTime( &st );
			if( iResumeThreadRetry > 50 )
			{
				wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d ResumeThread Error" ),
					st.wHour, st.wMinute, st.wSecond
				);
				// to do
				// 'unfreeze'
			}
			else if( iSuspendThreadRetry > 100 )
			{
				wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d SuspendThread Error" ),
					st.wHour, st.wMinute, st.wSecond
				);
			}
			else
			{
				wsprintf( lpszStatus[ 3 + iMyId * 4 ], TEXT( "%02d:%02d:%02d OpenThread Error" ),
					st.wHour, st.wMinute, st.wSecond
				);
			}

			WriteDebugLog( lpszStatus[ 3 + iMyId * 4 ] );
			WriteDebugLog( TEXT( "### Giving up... ###" ) );

			lphp->lpTarget->dwProcessId = TARGET_PID_NOT_SET; //?
			g_dwTargetProcessId[ iMyId ] = TARGET_PID_NOT_SET;

			if( hProcess ) 
			{
				SetPriorityClass( hProcess, dwOldPriority );
				CloseHandle( hProcess );
			}

			// This is needed as a workaround ? (Possibly this works as a workaround) 1.0 beta6
			UpdateStatus( hWnd );

			if( ReleaseSemaphore( hSemaphore[ iMyId ], 1L, NULL ) )
			{
				wsprintf( msg, TEXT( "* THREAD_NOT_OPENED #%d : ReleaseSemaphore in Hack()" ), iMyId + 1 );
				WriteDebugLog( msg );
			}

			BOOL bMissing = ( PathToProcess( lpszEnemyPath ) == ( DWORD ) -1 );
			WriteDebugLog( TEXT("SendMessage Doing...") );

			SendMessageCallback( hWnd, WM_USER_STOP, (WPARAM) iMyId,
				bMissing? TARGET_MISSING : THREAD_NOT_OPENED,
				(SENDASYNCPROC) DummyCallback, (DWORD) hWnd );

			WriteDebugLog( TEXT("SendMessage Done!") );

			lphp->lpTarget->dwProcessId = TARGET_PID_NOT_SET;

			InvalidateRect( hWnd, NULL, TRUE );

			return ( bMissing ) ? TARGET_MISSING : THREAD_NOT_OPENED ;
		}
		else if( iOpenedThread != iThreadCount )
		{
			for( j = 0; j < i; j++ ) if( hTarget[ j ] ) CloseHandle( hTarget[ j ] );
			iOpenThreadRetry++;
			wsprintf( msg, TEXT( "@ Couldn't open some threads: Retrying #%d..." ), iOpenThreadRetry );
			WriteDebugLog( msg );
			Sleep( 100UL );
			continue;
		}

		iOpenThreadRetry = 0;

		if( g_bHack[ 0 ] || g_bHack[ 1 ] || g_bHack[ 2 ] )
		{
			TCHAR strStatus[ 1024 ] = TEXT( " Limiting CPU load:" );
#ifdef _UNICODE
			if( IS_JAPANESE )
			{
				MultiByteToWideChar( CP_UTF8, MB_CUTE, S_JPN_2000, -1, strStatus, 1023 );
			}
			else if( IS_FINNISH )
			{
				MultiByteToWideChar( CP_UTF8, MB_CUTE, S_FIN_2000, -1, strStatus, 1023 );
			}
			else if( IS_SPANISH )
			{
				MultiByteToWideChar( CP_UTF8, MB_CUTE, S_SPA_2000, -1, strStatus, 1023 );
			}
			else if( IS_CHINESE_T )
			{
				MultiByteToWideChar( CP_UTF8, MB_CUTE, S_CHI_2000T, -1, strStatus, 1023 );
			}
			else if( IS_CHINESE_S )
			{
				MultiByteToWideChar( CP_UTF8, MB_CUTE, S_CHI_2000S, -1, strStatus, 1023 );
			}
			else if( IS_FRENCH )
			{
				MultiByteToWideChar( CP_UTF8, MB_CUTE, S_FRE_2000, -1, strStatus, 1023 );
			}
#endif
				
			if( g_bHack[ 0 ] )
			{
				lstrcat( strStatus, TEXT( " #1" ) );
			}
				
			if( g_bHack[ 1 ] )
			{
				lstrcat( strStatus, TEXT( " #2" ) );
			}
				
			if( g_bHack[ 2 ] && g_dwTargetProcessId[ 2 ] != (DWORD) -1 )
			{
				lstrcat( strStatus, TEXT( " #3" ) );
			}
		
			wsprintf( lpszStatus[ 12 ], TEXT( "%s" ), strStatus );
		}
		else
		{
			lstrcpy( lpszStatus[ 12 ], TEXT( "" ) );
		}



		InvalidateRect( hWnd, &hackrect, FALSE );




		for( DWORD dwInnerLoops = 1; dwInnerLoops <= MAX_INNER_LOOPS; dwInnerLoops++ )
		{
			BYTE TimeRed = g_Slider[ iMyId ];
			BYTE TimeGreen = (BYTE)( 100 - TimeRed );
			
			for( i = 0; i < iThreadCount; i++ )
			{
				if( ! hTarget[ i ] ) continue;

				dwPrevSuspendCount = SuspendThread( hTarget[ i ] );
				if( ( DWORD ) -1 == dwPrevSuspendCount )
				{
					errorflag = 1;
					wsprintf( msg,
						TEXT( "Target #%d : SuspendThread failed (Thread #%03d) : Retry=%d" ),
						iMyId + 1, i + 1, iSuspendThreadRetry );
					WriteDebugLog( msg );
				}
//				else if( dwPrevSuspendCount != 0UL )
//				{
//					WriteDebugLog( TEXT( "### dwPrevSuspendCount != 0UL" ) );
//					do
//					{
//						dwPrevSuspendCount = ResumeThread( hTarget[ i ] );
//					}
//					while( dwPrevSuspendCount > 1UL );
//				}
			}

			if( errorflag == 1 )
			{
				iSuspendThreadRetry++;
			}
			else
			{
				iSuspendThreadRetry = 0;
			}

			Sleep( (DWORD) TimeRed );
			for( i = 0; i < iThreadCount; i++ )
			{
				if( ! hTarget[ i ] ) continue;
				DWORD dwPrevSuspendCount = ResumeThread( hTarget[ i ] );
				if( ( DWORD ) -1 == dwPrevSuspendCount )
				{
					errorflag = 2;
					wsprintf( msg,
						TEXT( "Target #%d : ResumeThread failed: Thread #%03d, ThreadId 0x%08lX, iResumeThreadRetry=%d" ),
						iMyId + 1, i + 1, dwThreadId[ i ], iResumeThreadRetry );
					WriteDebugLog( msg );
				}
//
//				else if( dwPrevSuspendCount != 1UL )
//				{
//					WriteDebugLog( TEXT( "### dwPrevSuspendCount != 1UL" ) );
//					do
//					{
//						dwPrevSuspendCount = ResumeThread( hTarget[ i ] );
//					}
//					while( dwPrevSuspendCount > 1UL );
//				}

			}

			if( errorflag == 2 )
			{
				iResumeThreadRetry++;
			}
			else
			{
				iResumeThreadRetry = 0;
			}

			if( g_bHack[ iMyId ] == FALSE || errorflag )
			{
				break;
			}
			Sleep( (DWORD) TimeGreen );
		
		
			if( dwInnerLoops % 10UL == 0UL )
			{
				wsprintf( lpszStatus[ 0 + iMyId * 4 ],
					TEXT( "Target #%d [ -%d%% ] %s" ),
					iMyId + 1,
					g_Slider[ iMyId ],
					( dwInnerLoops % 20UL == 0UL )?
						_T( " " ) :
#ifdef _UNICODE
						L"\x25CF"
#else
						"*"
#endif
				);
				InvalidateRect( hWnd, &minirect, 0 );
			}
		
		}

		for( i = 0; i < iThreadCount; i++ )
		{
			if( hTarget[ i ] ) CloseHandle( hTarget[ i ] );
		}
	}

	wsprintf( lpszStatus[ 1 + iMyId * 4 ], TEXT( "* Unlimited *" ) );

	if( ReleaseSemaphore( hSemaphore[ iMyId ], 1L, (LONG *) NULL ) )
	{
		wsprintf( msg, TEXT( "* Target #%d : ReleaseSemaphore in Hack()" ), iMyId + 1 );
		WriteDebugLog( msg );
	}
	else
	{
		wsprintf( msg, TEXT( "[!] Target #%d : ReleaseSemaphore failed in Hack(): ErrCode %lu" ),
			iMyId + 1, GetLastError() );
		WriteDebugLog( msg );
	}

	if( hProcess ) 
	{
		WriteDebugLog( SetPriorityClass( hProcess, dwOldPriority )? TEXT( "Set dwOldPriority: OK" ) : TEXT( "Set dwOldPriority: Failed" ) );
		CloseHandle( hProcess );
	}

	lstrcpy( lpszStatus[ 3 + iMyId * 4 ], TEXT( "" ) );
	return NORMAL_TERMINATION;
}