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.

367 lines
9.8 KiB

  1. //--------------------------------------------------------------------
  2. // Copyright (C)1998 Microsoft Corporation, All Rights Reserved.
  3. //
  4. // io.cpp
  5. //
  6. // Author:
  7. //
  8. // Edward Reus (edwardr) 02-27-98 Initial coding.
  9. //
  10. //--------------------------------------------------------------------
  11. #include "precomp.h"
  12. #ifdef DBG_MEM
  13. static LONG g_lCIoPacketCount = 0;
  14. #endif
  15. //--------------------------------------------------------------------
  16. // CIOPACKET::CIOPACKET()
  17. //
  18. //--------------------------------------------------------------------
  19. CIOPACKET::CIOPACKET()
  20. {
  21. m_dwKind = PACKET_KIND_LISTEN;
  22. m_hIoCompletionPort = INVALID_HANDLE_VALUE;
  23. m_ListenSocket = INVALID_SOCKET;
  24. m_Socket = INVALID_SOCKET;
  25. m_hFile = INVALID_HANDLE_VALUE;
  26. m_pLocalAddr = 0;
  27. m_pFromAddr = 0;
  28. m_pAcceptBuffer = 0;
  29. m_pReadBuffer = 0;
  30. m_pvWritePdu = 0;
  31. m_dwReadBufferSize = 0;
  32. }
  33. //--------------------------------------------------------------------
  34. // CIOPACKET::~CIOPACKET()
  35. //
  36. //--------------------------------------------------------------------
  37. CIOPACKET::~CIOPACKET()
  38. {
  39. // NOTE: Don't free m_pLocalAddr or m_pFromAddr, they just point
  40. // into m_pAcceptBuffer.
  41. if (m_pAcceptBuffer)
  42. {
  43. FreeMemory(m_pAcceptBuffer);
  44. }
  45. if (m_pReadBuffer)
  46. {
  47. FreeMemory(m_pReadBuffer);
  48. }
  49. // NOTE: Don't delete the write PDU (m_pvWritePdu), its free'd by
  50. // somebody else (when the IO completes)...
  51. }
  52. //------------------------------------------------------------------------
  53. // CIOPACKET::operator new()
  54. //
  55. //------------------------------------------------------------------------
  56. void *CIOPACKET::operator new( IN size_t Size )
  57. {
  58. void *pObj = AllocateMemory(Size);
  59. #ifdef DBG_MEM
  60. if (pObj)
  61. {
  62. InterlockedIncrement(&g_lCIoPacketCount);
  63. }
  64. DbgPrint("new CIOPACKET: Count: %d\n",g_lCIoPacketCount);
  65. #endif
  66. return pObj;
  67. }
  68. //------------------------------------------------------------------------
  69. // CIOPACKET::operator delete()
  70. //
  71. //------------------------------------------------------------------------
  72. void CIOPACKET::operator delete( IN void *pObj,
  73. IN size_t Size )
  74. {
  75. if (pObj)
  76. {
  77. DWORD dwStatus = FreeMemory(pObj);
  78. #ifdef DBG_MEM
  79. if (dwStatus)
  80. {
  81. DbgPrint("IrXfer: IrTran-P: CIOPACKET::delete: FreeMemory Failed: %d\n",dwStatus);
  82. }
  83. InterlockedDecrement(&g_lCIoPacketCount);
  84. if (g_lCIoPacketCount < 0)
  85. {
  86. DbgPrint("IrXfer: IrTran-P: CIOPACKET::delete Count: %d\n",
  87. g_lCIoPacketCount);
  88. }
  89. #endif
  90. }
  91. }
  92. //--------------------------------------------------------------------
  93. // CIOPACKET::Initialize()
  94. //
  95. //--------------------------------------------------------------------
  96. DWORD CIOPACKET::Initialize( IN DWORD dwKind,
  97. IN SOCKET ListenSocket,
  98. IN SOCKET Socket,
  99. IN HANDLE hIoCP )
  100. {
  101. DWORD dwStatus = NO_ERROR;
  102. m_dwKind = dwKind;
  103. m_hIoCompletionPort = hIoCP;
  104. if (dwKind == PACKET_KIND_LISTEN)
  105. {
  106. // The accept buffer needs to be large enough to hold
  107. // the "from" and "to" addresses:
  108. m_pAcceptBuffer = AllocateMemory(2*(16+sizeof(SOCKADDR_IRDA)));
  109. if (!m_pAcceptBuffer)
  110. {
  111. return ERROR_IRTRANP_OUT_OF_MEMORY;
  112. }
  113. }
  114. m_ListenSocket = ListenSocket;
  115. m_Socket = Socket;
  116. return dwStatus;
  117. }
  118. //--------------------------------------------------------------------
  119. // CIOPACKET::PostIoListen()
  120. //
  121. //--------------------------------------------------------------------
  122. DWORD CIOPACKET::PostIoListen()
  123. {
  124. DWORD dwStatus = NO_ERROR;
  125. DWORD dwBytes;
  126. HANDLE hIoCP;
  127. m_Socket = WSASocketW( AF_IRDA,
  128. SOCK_STREAM,
  129. IPPROTO_IP,
  130. 0,
  131. 0,
  132. WSA_FLAG_OVERLAPPED );
  133. if (m_Socket == INVALID_SOCKET)
  134. {
  135. dwStatus = WSAGetLastError();
  136. return dwStatus;
  137. }
  138. hIoCP = CreateIoCompletionPort( (void*)m_Socket,
  139. m_hIoCompletionPort,
  140. m_Socket,
  141. 0 );
  142. if (!hIoCP)
  143. {
  144. dwStatus = GetLastError();
  145. #ifdef DBG_ERROR
  146. DbgPrint("CIOPACKET::PostIoListen(): CreateIoCompletionPort() failed: %d\n",dwStatus);
  147. #endif
  148. closesocket(m_Socket);
  149. m_Socket = INVALID_SOCKET;
  150. return dwStatus;
  151. }
  152. memset(&m_Overlapped,0,sizeof(m_Overlapped));
  153. if (!AcceptEx(m_ListenSocket,
  154. m_Socket,
  155. m_pAcceptBuffer,
  156. 0,
  157. 16 + sizeof(SOCKADDR_IRDA),
  158. 16 + sizeof(SOCKADDR_IRDA),
  159. &dwBytes, // Never actually used in this case...
  160. &m_Overlapped ))
  161. {
  162. // This is the normal execution path, with dwStatus == ERROR_IO_PENDING
  163. dwStatus = WSAGetLastError();
  164. if (dwStatus == ERROR_IO_PENDING)
  165. {
  166. dwStatus = NO_ERROR;
  167. }
  168. }
  169. else
  170. {
  171. // Should get here only if a client is trying to connect just as
  172. // the AcceptEx() is called...
  173. dwStatus = NO_ERROR;
  174. }
  175. #ifdef DBG_IO
  176. DbgPrint("CIOPACKET::PostIoListen(): AcceptEx(): Socket: %d\n",
  177. m_ListenSocket );
  178. #endif
  179. return dwStatus;
  180. }
  181. //--------------------------------------------------------------------
  182. // CIOPACKET::PostIoRead()
  183. //
  184. //--------------------------------------------------------------------
  185. DWORD CIOPACKET::PostIoRead()
  186. {
  187. DWORD dwStatus = NO_ERROR;
  188. DWORD dwBytes;
  189. if (!m_pReadBuffer)
  190. {
  191. m_pReadBuffer = AllocateMemory(DEFAULT_READ_BUFFER_SIZE);
  192. m_dwReadBufferSize = DEFAULT_READ_BUFFER_SIZE;
  193. if (!m_pReadBuffer)
  194. {
  195. return ERROR_IRTRANP_OUT_OF_MEMORY;
  196. }
  197. }
  198. memset(&m_Overlapped,0,sizeof(m_Overlapped));
  199. BOOL b = ReadFile( (HANDLE)m_Socket,
  200. m_pReadBuffer,
  201. m_dwReadBufferSize,
  202. 0, // Can be zero for overlapped IO.
  203. &m_Overlapped );
  204. if (!b)
  205. {
  206. dwStatus = GetLastError();
  207. if ((dwStatus == ERROR_HANDLE_EOF)||(dwStatus == ERROR_IO_PENDING))
  208. {
  209. dwStatus = NO_ERROR;
  210. }
  211. }
  212. #ifdef DBG_IO
  213. DbgPrint("CIOPACKET::PostIoListen(): ReadFile(): Socket: %d\n",
  214. m_Socket );
  215. #endif
  216. return dwStatus;
  217. }
  218. //--------------------------------------------------------------------
  219. // CIOPACKET::PostIoWrite()
  220. //
  221. //--------------------------------------------------------------------
  222. DWORD CIOPACKET::PostIoWrite( IN void *pvBuffer,
  223. IN DWORD dwBufferSize,
  224. IN DWORD dwOffset )
  225. {
  226. DWORD dwStatus = NO_ERROR;
  227. DWORD dwBytes;
  228. HANDLE hFile;
  229. memset(&m_Overlapped,0,sizeof(m_Overlapped));
  230. if (m_dwKind == PACKET_KIND_WRITE_SOCKET)
  231. {
  232. hFile = (HANDLE)m_Socket;
  233. }
  234. else if (m_dwKind == PACKET_KIND_WRITE_FILE)
  235. {
  236. hFile = m_hFile;
  237. m_Overlapped.Offset = dwOffset;
  238. }
  239. else
  240. {
  241. #ifdef DBG_ERROR
  242. DbgPrint("CIOPACKET::PostIoWrite(): Invalid m_dwKind: %d.\n",m_dwKind);
  243. #endif
  244. dwStatus = ERROR_INVALID_PARAMETER;
  245. }
  246. BOOL b = WriteFile( hFile,
  247. pvBuffer,
  248. dwBufferSize,
  249. 0, // Can be zero for overlapped IO.
  250. &m_Overlapped );
  251. if (!b)
  252. {
  253. dwStatus = GetLastError();
  254. if (dwStatus == ERROR_IO_PENDING)
  255. {
  256. dwStatus = NO_ERROR;
  257. }
  258. }
  259. #ifdef DBG_IO
  260. DbgPrint("CIOPACKET::PostIoWrite(): WriteFile(): Handle: %d Bytes: %d\n",
  261. hFile, dwBufferSize );
  262. #endif
  263. return dwStatus;
  264. }
  265. //--------------------------------------------------------------------
  266. // CIOPACKET::PostIo()
  267. //
  268. //--------------------------------------------------------------------
  269. DWORD CIOPACKET::PostIo()
  270. {
  271. DWORD dwStatus = NO_ERROR;
  272. DWORD dwBytes;
  273. if (m_dwKind == PACKET_KIND_LISTEN)
  274. {
  275. dwStatus = PostIoListen();
  276. }
  277. else if (m_dwKind == PACKET_KIND_READ)
  278. {
  279. dwStatus = PostIoRead();
  280. }
  281. else
  282. {
  283. // Packet writes back to the camera (via socket) and writes to
  284. // the image (jpeg) file are posted only when data is ready to
  285. // send...
  286. ASSERT( (m_dwKind == PACKET_KIND_WRITE_SOCKET)
  287. || (m_dwKind == PACKET_KIND_WRITE_FILE) );
  288. }
  289. return dwStatus;
  290. }
  291. //--------------------------------------------------------------------
  292. // CIOPACKET::GetSockAddrs()
  293. //
  294. // NOTE: Don't free the memory addresses returned, they point into
  295. // m_AcceptBuffer.
  296. //--------------------------------------------------------------------
  297. void CIOPACKET::GetSockAddrs( OUT SOCKADDR_IRDA **ppLocalAddr,
  298. OUT SOCKADDR_IRDA **ppFromAddr )
  299. {
  300. int iLocalAddrSize;
  301. int iFromAddrSize;
  302. if (!m_pLocalAddr)
  303. {
  304. GetAcceptExSockaddrs(m_pAcceptBuffer,
  305. 0,
  306. 16 + sizeof(SOCKADDR_IRDA),
  307. 16 + sizeof(SOCKADDR_IRDA),
  308. (struct sockaddr **)&m_pLocalAddr,
  309. &iLocalAddrSize,
  310. (struct sockaddr **)&m_pFromAddr,
  311. &iFromAddrSize );
  312. }
  313. *ppLocalAddr = m_pLocalAddr;
  314. *ppFromAddr = m_pFromAddr;
  315. }