Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

555 lines
12 KiB

  1. //#define UNICODE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <windows.h>
  5. #include <shellapi.h>
  6. #include <winsock.h>
  7. #include <af_irda.h>
  8. #include <resource.h>
  9. #include <resrc1.h>
  10. #define DEVICE_LIST_LEN 5
  11. #define WSBUF_SIZE 128
  12. #define RXBUF_SIZE 2045*8 // max pdu * max window + 1
  13. #define DEF_SENDBUF_SIZE 2045*7 // max pdu * max window
  14. #define DEF_SENDCNT 100
  15. int TotalRecvBytes;
  16. HWND vhWnd;
  17. PDEVICELIST pDevList;
  18. BYTE DevListBuff[sizeof(DEVICELIST) - sizeof(IRDA_DEVICE_INFO) +
  19. (sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
  20. TCHAR *
  21. GetLastErrorText();
  22. void
  23. StatusMsg(TCHAR *pFormat, ...)
  24. {
  25. TCHAR Buf[128];
  26. va_list ArgList;
  27. va_start(ArgList, pFormat);
  28. wvsprintf(Buf, pFormat, ArgList);
  29. SendMessage(GetDlgItem(vhWnd, IDC_STATUS), EM_REPLACESEL, 0,
  30. (LPARAM) Buf);
  31. va_end(ArgList);
  32. }
  33. void
  34. RecvThread(PVOID Arg)
  35. {
  36. SOCKADDR_IRDA ServSockAddr = { AF_IRDA, 0, 0, 0, 0, "Blaster" };
  37. SOCKADDR_IRDA PeerSockAddr;
  38. SOCKET NewSock, Sock;
  39. int sizeofSockAddr = sizeof(SOCKADDR_IRDA);
  40. int RecvSize;
  41. TCHAR wsBuf[WSBUF_SIZE];
  42. char *RecvBuf;
  43. int BytesRecvd;
  44. StatusMsg(TEXT("socket(AF_IRDA)\r\n"));
  45. if ((Sock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
  46. {
  47. StatusMsg(TEXT(" error: %s\r\n"), GetLastErrorText());
  48. return;
  49. }
  50. else
  51. StatusMsg(TEXT(" socket created (%d).\r\n"), Sock);
  52. StatusMsg(TEXT("bind(%s)\r\n"), ServSockAddr.irdaServiceName);
  53. if (bind(Sock, (const struct sockaddr *) &ServSockAddr,
  54. sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
  55. {
  56. StatusMsg(TEXT(" error: %s\r\n"), GetLastErrorText());
  57. return;
  58. }
  59. StatusMsg(TEXT(" bind() succeeded\r\n"));
  60. StatusMsg(TEXT("listen()\r\n"));
  61. if (listen(Sock, 5) == SOCKET_ERROR)
  62. {
  63. StatusMsg(TEXT(" error: %s\r\n"), GetLastErrorText());
  64. return;
  65. }
  66. StatusMsg(TEXT(" listen() succeeded\r\n"));
  67. RecvBuf = LocalAlloc(0, RXBUF_SIZE);
  68. while(1)
  69. {
  70. StatusMsg(TEXT("accept() - waiting for connection...\r\n"));
  71. if ((NewSock = accept(Sock, (struct sockaddr *) &PeerSockAddr,
  72. &sizeofSockAddr)) == INVALID_SOCKET)
  73. {
  74. StatusMsg(TEXT(" error: %s\r\n"), GetLastErrorText());
  75. return;
  76. }
  77. StatusMsg(TEXT("accept(), new connection\r\n"));
  78. TotalRecvBytes = 0;
  79. while(1)
  80. {
  81. if ((BytesRecvd = recv(NewSock, RecvBuf, RXBUF_SIZE, 0)) ==
  82. SOCKET_ERROR)
  83. {
  84. StatusMsg(TEXT("recv() failed\r\n"));
  85. return;
  86. }
  87. TotalRecvBytes += BytesRecvd;
  88. if (BytesRecvd == 0)
  89. {
  90. StatusMsg(TEXT("recv() = 0, connection closed\r\n"));
  91. break;
  92. }
  93. }
  94. closesocket(NewSock);
  95. }
  96. return;
  97. }
  98. void
  99. SendThread(PVOID Arg)
  100. {
  101. int DevListLen = sizeof(DevListBuff);
  102. int SendSize, SendCnt, i, Sent;
  103. TCHAR wsBuf[WSBUF_SIZE];
  104. char *pSendBuf;
  105. SOCKET Sock;
  106. SOCKADDR_IRDA DstAddrIR = { AF_IRDA, 0, 0, 0, 0, "Blaster" };
  107. StatusMsg(TEXT("socket(AF_IRDA)\r\n"));
  108. if ((Sock = socket(AF_IRDA, SOCK_STREAM, 0)) == INVALID_SOCKET)
  109. {
  110. StatusMsg(TEXT(" error: %s\r\n"), GetLastErrorText());
  111. goto done;
  112. }
  113. else
  114. StatusMsg(TEXT(" socket created (%d).\r\n"), Sock);
  115. StatusMsg(TEXT("getsockopt(IRLMP_ENUMDEVICES)\r\n"));
  116. if (getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
  117. (char *) pDevList, &DevListLen) == SOCKET_ERROR)
  118. {
  119. StatusMsg(TEXT(" error: %s.\r\n"), GetLastErrorText());
  120. goto done;
  121. }
  122. StatusMsg(TEXT("%d device(s) found.\r\n"),
  123. pDevList->numDevice);
  124. if (pDevList->numDevice == 0)
  125. {
  126. StatusMsg(TEXT(" NO DEVICES FOUND\r\n"));
  127. goto done;
  128. }
  129. memcpy(DstAddrIR.irdaDeviceID,
  130. pDevList->Device[0].irdaDeviceID, 4);
  131. #ifdef UNICODE
  132. mbstowcs(wsBuf, pDevList->Device[0].irdaDeviceName, WSBUF_SIZE);
  133. #else
  134. strcpy(wsBuf, pDevList->Device[0].irdaDeviceName);
  135. #endif
  136. StatusMsg(TEXT("connect() to %s...\r\n"), wsBuf);
  137. if (connect(Sock, (const struct sockaddr *) &DstAddrIR,
  138. sizeof(SOCKADDR_IRDA)) == SOCKET_ERROR)
  139. {
  140. StatusMsg(TEXT(" connect() error: %s\r\n"), GetLastErrorText());
  141. goto done;
  142. }
  143. GetWindowText(GetDlgItem(vhWnd, IDC_SENDSIZE), wsBuf, WSBUF_SIZE);
  144. SendSize = atoi(wsBuf);
  145. GetWindowText(GetDlgItem(vhWnd, IDC_SENDCNT), wsBuf, WSBUF_SIZE);
  146. SendCnt = atoi(wsBuf);
  147. StatusMsg(TEXT("connected, sending %d\r\n"), SendCnt*SendSize);
  148. pSendBuf = LocalAlloc(0, SendSize);
  149. if (pSendBuf == NULL) {
  150. StatusMsg(TEXT(" Could not allocate buffer\r\n"));
  151. goto done;
  152. }
  153. for (i=0; i < SendSize; i++)
  154. {
  155. pSendBuf[i] = (char) i;
  156. }
  157. for (i=0; i < SendCnt; i++)
  158. {
  159. Sent = send(Sock, pSendBuf, SendSize,0);
  160. if (Sent == SOCKET_ERROR)
  161. {
  162. StatusMsg(TEXT("send() failed %s\r\n"),
  163. GetLastErrorText());
  164. break;
  165. }
  166. }
  167. StatusMsg(TEXT("done sending\r\n"));
  168. LocalFree(pSendBuf);
  169. closesocket(Sock);
  170. done:
  171. EnableWindow(GetDlgItem(vhWnd, IDC_SEND), 1);
  172. }
  173. void
  174. DisplayThread(PVOID Args)
  175. {
  176. TCHAR PBuf[32];
  177. int Last, Curr;
  178. int cnt = 1;
  179. while(1)
  180. {
  181. Last = TotalRecvBytes;
  182. Sleep(1000);
  183. Curr = TotalRecvBytes;
  184. wsprintf(PBuf, "%u", TotalRecvBytes);
  185. SetWindowText(GetDlgItem(vhWnd, IDC_RXCNT), PBuf);
  186. wsprintf(PBuf, "%u", Curr-Last);
  187. SetWindowText(GetDlgItem(vhWnd, IDC_BYTESEC), PBuf);
  188. }
  189. }
  190. LRESULT CALLBACK
  191. DialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
  192. {
  193. HANDLE hThread;
  194. DWORD ThreadId;
  195. switch (message)
  196. {
  197. case WM_INITDIALOG:
  198. {
  199. TCHAR pBuf[32];
  200. SetFocus(GetDlgItem(hDlg, IDC_SENDSIZE));
  201. vhWnd = hDlg;
  202. wsprintf(pBuf, "%d", DEF_SENDBUF_SIZE);
  203. SetWindowText(GetDlgItem(hDlg, IDC_SENDSIZE), pBuf);
  204. wsprintf(pBuf, "%d", DEF_SENDCNT);
  205. SetWindowText(GetDlgItem(hDlg, IDC_SENDCNT), pBuf);
  206. CloseHandle(CreateThread(NULL, 0,
  207. (LPTHREAD_START_ROUTINE) RecvThread, NULL, 0, &ThreadId));
  208. CloseHandle(CreateThread(NULL, 0,
  209. (LPTHREAD_START_ROUTINE) DisplayThread, NULL, 0, &ThreadId));
  210. break;
  211. }
  212. case WM_COMMAND:
  213. switch (LOWORD(wParam))
  214. {
  215. case IDC_SEND:
  216. EnableWindow(GetDlgItem(hDlg, IDC_SEND), 0);
  217. CloseHandle(CreateThread(NULL, 0,
  218. (LPTHREAD_START_ROUTINE) SendThread,
  219. NULL, 0, &ThreadId));
  220. break;
  221. case IDCANCEL:
  222. DestroyWindow(hDlg);
  223. break;
  224. }
  225. break;
  226. case WM_DESTROY:
  227. PostQuitMessage(0);
  228. break;
  229. }
  230. return 0;
  231. }
  232. WinMain(HINSTANCE hInstance, HINSTANCE hInstPrev, LPSTR pCmdLine,
  233. int nCmdShow)
  234. {
  235. WSADATA WSAData;
  236. WORD WSAVerReq = MAKEWORD(1,1);
  237. MSG msg;
  238. HWND hWnd;
  239. if (WSAStartup(WSAVerReq, &WSAData) != 0)
  240. {
  241. return 1;
  242. }
  243. pDevList = (PDEVICELIST) DevListBuff;
  244. pDevList->numDevice = 0;
  245. hWnd = CreateDialog(hInstance,
  246. MAKEINTRESOURCE( IDD_DIALOG1), NULL,
  247. DialogProc);
  248. if (hWnd)
  249. {
  250. ShowWindow(hWnd, SW_SHOWNORMAL);
  251. UpdateWindow(hWnd);
  252. }
  253. else
  254. {
  255. return 1;
  256. }
  257. while( GetMessage( &msg, NULL, 0, 0) != FALSE )
  258. {
  259. if (hWnd == 0 || !IsDialogMessage(hWnd, &msg))
  260. {
  261. TranslateMessage( &msg );
  262. DispatchMessage( &msg );
  263. }
  264. }
  265. return 0;
  266. }
  267. TCHAR *
  268. GetLastErrorText()
  269. {
  270. switch (WSAGetLastError())
  271. {
  272. case WSAEINTR:
  273. return (TEXT("WSAEINTR"));
  274. break;
  275. case WSAEBADF:
  276. return(TEXT("WSAEBADF"));
  277. break;
  278. case WSAEACCES:
  279. return(TEXT("WSAEACCES"));
  280. break;
  281. case WSAEFAULT:
  282. return(TEXT("WSAEFAULT"));
  283. break;
  284. case WSAEINVAL:
  285. return(TEXT("WSAEINVAL"));
  286. break;
  287. case WSAEMFILE:
  288. return(TEXT("WSAEMFILE"));
  289. break;
  290. case WSAEWOULDBLOCK:
  291. return(TEXT("WSAEWOULDBLOCK"));
  292. break;
  293. case WSAEINPROGRESS:
  294. return(TEXT("WSAEINPROGRESS"));
  295. break;
  296. case WSAEALREADY:
  297. return(TEXT("WSAEALREADY"));
  298. break;
  299. case WSAENOTSOCK:
  300. return(TEXT("WSAENOTSOCK"));
  301. break;
  302. case WSAEDESTADDRREQ:
  303. return(TEXT("WSAEDESTADDRREQ"));
  304. break;
  305. case WSAEMSGSIZE:
  306. return(TEXT("WSAEMSGSIZE"));
  307. break;
  308. case WSAEPROTOTYPE:
  309. return(TEXT("WSAEPROTOTYPE"));
  310. break;
  311. case WSAENOPROTOOPT:
  312. return(TEXT("WSAENOPROTOOPT"));
  313. break;
  314. case WSAEPROTONOSUPPORT:
  315. return(TEXT("WSAEPROTONOSUPPORT"));
  316. break;
  317. case WSAESOCKTNOSUPPORT:
  318. return(TEXT("WSAESOCKTNOSUPPORT"));
  319. break;
  320. case WSAEOPNOTSUPP:
  321. return(TEXT("WSAEOPNOTSUPP"));
  322. break;
  323. case WSAEPFNOSUPPORT:
  324. return(TEXT("WSAEPFNOSUPPORT"));
  325. break;
  326. case WSAEAFNOSUPPORT:
  327. return(TEXT("WSAEAFNOSUPPORT"));
  328. break;
  329. case WSAEADDRINUSE:
  330. return(TEXT("WSAEADDRINUSE"));
  331. break;
  332. case WSAEADDRNOTAVAIL:
  333. return(TEXT("WSAEADDRNOTAVAIL"));
  334. break;
  335. case WSAENETDOWN:
  336. return(TEXT("WSAENETDOWN"));
  337. break;
  338. case WSAENETUNREACH:
  339. return(TEXT("WSAENETUNREACH"));
  340. break;
  341. case WSAENETRESET:
  342. return(TEXT("WSAENETRESET"));
  343. break;
  344. case WSAECONNABORTED:
  345. return(TEXT("WSAECONNABORTED"));
  346. break;
  347. case WSAECONNRESET:
  348. return(TEXT("WSAECONNRESET"));
  349. break;
  350. case WSAENOBUFS:
  351. return(TEXT("WSAENOBUFS"));
  352. break;
  353. case WSAEISCONN:
  354. return(TEXT("WSAEISCONN"));
  355. break;
  356. case WSAENOTCONN:
  357. return(TEXT("WSAENOTCONN"));
  358. break;
  359. case WSAESHUTDOWN:
  360. return(TEXT("WSAESHUTDOWN"));
  361. break;
  362. case WSAETOOMANYREFS:
  363. return(TEXT("WSAETOOMANYREFS"));
  364. break;
  365. case WSAETIMEDOUT:
  366. return(TEXT("WSAETIMEDOUT"));
  367. break;
  368. case WSAECONNREFUSED:
  369. return(TEXT("WSAECONNREFUSED"));
  370. break;
  371. case WSAELOOP:
  372. return(TEXT("WSAELOOP"));
  373. break;
  374. case WSAENAMETOOLONG:
  375. return(TEXT("WSAENAMETOOLONG"));
  376. break;
  377. case WSAEHOSTDOWN:
  378. return(TEXT("WSAEHOSTDOWN"));
  379. break;
  380. case WSAEHOSTUNREACH:
  381. return(TEXT("WSAEHOSTUNREACH"));
  382. break;
  383. case WSAENOTEMPTY:
  384. return(TEXT("WSAENOTEMPTY"));
  385. break;
  386. case WSAEPROCLIM:
  387. return(TEXT("WSAEPROCLIM"));
  388. break;
  389. case WSAEUSERS:
  390. return(TEXT("WSAEUSERS"));
  391. break;
  392. case WSAEDQUOT:
  393. return(TEXT("WSAEDQUOT"));
  394. break;
  395. case WSAESTALE:
  396. return(TEXT("WSAESTALE"));
  397. break;
  398. case WSAEREMOTE:
  399. return(TEXT("WSAEREMOTE"));
  400. break;
  401. case WSAEDISCON:
  402. return(TEXT("WSAEDISCON"));
  403. break;
  404. case WSASYSNOTREADY:
  405. return(TEXT("WSASYSNOTREADY"));
  406. break;
  407. case WSAVERNOTSUPPORTED:
  408. return(TEXT("WSAVERNOTSUPPORTED"));
  409. break;
  410. case WSANOTINITIALISED:
  411. return(TEXT("WSANOTINITIALISED"));
  412. break;
  413. /*
  414. case WSAHOST:
  415. return(TEXT("WSAHOST"));
  416. break;
  417. case WSATRY:
  418. return(TEXT("WSATRY"));
  419. break;
  420. case WSANO:
  421. return(TEXT("WSANO"));
  422. break;
  423. */
  424. default:
  425. return(TEXT("Unknown Error"));
  426. }
  427. }