Leaked source code of windows server 2003
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.

398 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. write.cxx
  5. Abstract:
  6. This file contains the implementation of the HttpWriteData API.
  7. Contents:
  8. HttpWriteData
  9. HTTP_REQUEST_HANDLE_OBJECT::WriteData
  10. Author:
  11. Arthur Bierer (arthurbi) 07-Apr-1997
  12. Revision History:
  13. --*/
  14. #include <wininetp.h>
  15. #include "httpp.h"
  16. //
  17. // functions
  18. //
  19. #if !defined(THREAD_POOL)
  20. INTERNETAPI_(BOOL) HttpWriteData(
  21. IN HINTERNET hRequest,
  22. IN LPVOID lpBuffer,
  23. IN DWORD dwNumberOfBytesToWrite,
  24. OUT LPDWORD lpdwNumberOfBytesWritten
  25. )
  26. /*++
  27. Routine Description:
  28. Writes a block of data for an outstanding HTTP request
  29. Assumes: 1. this function can only be called from InternetWriteFile() which
  30. globally validates parameters for all Internet data write
  31. functions
  32. 2. That we the caller has called HttpBeginSendRequest but not HttpEndSendRequest
  33. Arguments:
  34. hRequest - an open HTTP request handle returned by
  35. HttpOpenRequest()
  36. lpBuffer - pointer to the buffer to receive the data
  37. dwNumberOfBytesToWrite - number of bytes to write from user's buffer
  38. lpdwNumberOfBytesWritten - number of bytes actually written
  39. Return Value:
  40. TRUE - The data was written successfully. lpdwNumberOfBytesRead points to the
  41. number of BYTEs actually read. This value will be set to zero
  42. when the transfer has completed.
  43. FALSE - The operation failed. Error status is available by calling
  44. GetLastError().
  45. --*/
  46. {
  47. DEBUG_ENTER((DBG_HTTP,
  48. Dword,
  49. "HttpWriteData",
  50. "%#x, %#x, %d, %#x",
  51. hRequest,
  52. lpBuffer,
  53. dwNumberOfBytesToWrite,
  54. lpdwNumberOfBytesWritten
  55. ));
  56. DWORD error;
  57. //
  58. // find path from internet handle
  59. //
  60. BOOL isLocal;
  61. BOOL isAsync;
  62. error = RIsHandleLocal(hRequest,
  63. &isLocal,
  64. &isAsync,
  65. TypeHttpRequestHandle
  66. );
  67. if (error != ERROR_SUCCESS) {
  68. goto quit;
  69. }
  70. //
  71. // need to set these for both local and remote paths, in case we're in async
  72. // mode
  73. //
  74. DWORD context;
  75. error = RGetContext(hRequest, &context);
  76. if (error != ERROR_SUCCESS) {
  77. goto quit;
  78. }
  79. //InternetSetObjectHandle(hRequest);
  80. //InternetSetContext(context);
  81. //
  82. // Cast it to the object that we know. We are going to do call
  83. // into the method to do the work.
  84. //
  85. HTTP_REQUEST_HANDLE_OBJECT *pRequest;
  86. pRequest = (HTTP_REQUEST_HANDLE_OBJECT *)hRequest;
  87. if (!IS_VALID_HTTP_STATE(pRequest, WRITE, TRUE)) {
  88. error = ERROR_INTERNET_INCORRECT_HANDLE_STATE;
  89. } else {
  90. // This request needs a special CR-LF added to the end at EndRequest
  91. pRequest->SetAddCRLF(TRUE);
  92. error = pRequest->WriteData(lpBuffer,
  93. dwNumberOfBytesToWrite,
  94. lpdwNumberOfBytesWritten
  95. );
  96. }
  97. quit:
  98. DEBUG_LEAVE(error);
  99. return error;
  100. }
  101. DWORD
  102. HTTP_REQUEST_HANDLE_OBJECT::WriteData(
  103. OUT LPVOID lpBuffer,
  104. IN DWORD dwNumberOfBytesToWrite,
  105. OUT LPDWORD lpdwNumberOfBytesWritten
  106. )
  107. /*++
  108. Routine Description:
  109. HTTP_REQUEST_HANDLE_OBJECT WriteData method
  110. Writes data from users buffer. Writes the data to the currently open
  111. socket.
  112. Arguments:
  113. lpBuffer - pointer to users buffer
  114. dwNumberOfBytesToWrite - number of bytes to write from user's buffer
  115. lpdwNumberOfBytesWritten - number of bytes actually written
  116. Return Value:
  117. DWORD
  118. Success - ERROR_SUCCESS
  119. Failure - WSA error
  120. --*/
  121. {
  122. DEBUG_ENTER((DBG_HTTP,
  123. Dword,
  124. "HTTP_REQUEST_HANDLE_OBJECT::WriteData",
  125. "%#x, %d, %#x",
  126. lpBuffer,
  127. dwNumberOfBytesToWrite,
  128. lpdwNumberOfBytesWritten
  129. ));
  130. DWORD error = ERROR_SUCCESS;
  131. if ( _Socket == NULL )
  132. {
  133. error = ERROR_INTERNET_INTERNAL_ERROR;
  134. goto quit;
  135. }
  136. error = _Socket->Send(lpBuffer, dwNumberOfBytesToWrite, SF_INDICATE);
  137. if (error == ERROR_SUCCESS)
  138. {
  139. *lpdwNumberOfBytesWritten = dwNumberOfBytesToWrite;
  140. }
  141. else
  142. {
  143. goto quit;
  144. }
  145. quit:
  146. DEBUG_LEAVE(error);
  147. return error;
  148. }
  149. #else
  150. DWORD
  151. HttpWriteData(
  152. IN HINTERNET hRequest,
  153. IN LPVOID lpBuffer,
  154. IN DWORD dwNumberOfBytesToWrite,
  155. OUT LPDWORD lpdwNumberOfBytesWritten,
  156. IN DWORD dwSocketFlags
  157. )
  158. /*++
  159. Routine Description:
  160. Writes a block of data for an outstanding HTTP request
  161. Assumes: 1. this function can only be called from InternetWriteFile() which
  162. globally validates parameters for all Internet data write
  163. functions
  164. 2. That we the caller has called HttpBeginSendRequest but not HttpEndSendRequest
  165. Arguments:
  166. hRequest - an open HTTP request handle returned by
  167. HttpOpenRequest()
  168. lpBuffer - pointer to the buffer to receive the data
  169. dwNumberOfBytesToWrite - number of bytes to write from user's buffer
  170. lpdwNumberOfBytesWritten - number of bytes actually written
  171. dwSocketFlags - controlling socket operation
  172. Return Value:
  173. TRUE - The data was written successfully. lpdwNumberOfBytesRead points to the
  174. number of BYTEs actually read. This value will be set to zero
  175. when the transfer has completed.
  176. FALSE - The operation failed. Error status is available by calling
  177. GetLastError().
  178. --*/
  179. {
  180. DEBUG_ENTER((DBG_HTTP,
  181. Dword,
  182. "HttpWriteData",
  183. "%#x, %#x, %d, %#x, %#x",
  184. hRequest,
  185. lpBuffer,
  186. dwNumberOfBytesToWrite,
  187. lpdwNumberOfBytesWritten,
  188. dwSocketFlags
  189. ));
  190. DWORD error = DoFsm(new CFsm_HttpWriteData(lpBuffer,
  191. dwNumberOfBytesToWrite,
  192. lpdwNumberOfBytesWritten,
  193. dwSocketFlags,
  194. (HTTP_REQUEST_HANDLE_OBJECT *)hRequest
  195. ));
  196. DEBUG_LEAVE(error);
  197. return error;
  198. }
  199. DWORD
  200. CFsm_HttpWriteData::RunSM(
  201. IN CFsm * Fsm
  202. )
  203. {
  204. DEBUG_ENTER((DBG_HTTP,
  205. Dword,
  206. "CFsm_HttpWriteData::RunSM",
  207. "%#x",
  208. Fsm
  209. ));
  210. DWORD error;
  211. HTTP_REQUEST_HANDLE_OBJECT * pRequest;
  212. CFsm_HttpWriteData * stateMachine = (CFsm_HttpWriteData *)Fsm;
  213. pRequest = (HTTP_REQUEST_HANDLE_OBJECT *)Fsm->GetContext();
  214. switch (Fsm->GetState()) {
  215. case FSM_STATE_INIT:
  216. pRequest->SetAddCRLF(TRUE);
  217. //
  218. // Fall through
  219. //
  220. case FSM_STATE_CONTINUE:
  221. error = pRequest->HttpWriteData_Fsm(stateMachine);
  222. break;
  223. default:
  224. error = ERROR_INTERNET_INTERNAL_ERROR;
  225. Fsm->SetDone(ERROR_INTERNET_INTERNAL_ERROR);
  226. INET_ASSERT(FALSE);
  227. break;
  228. }
  229. DEBUG_LEAVE(error);
  230. return error;
  231. }
  232. DWORD
  233. HTTP_REQUEST_HANDLE_OBJECT::HttpWriteData_Fsm(
  234. IN CFsm_HttpWriteData * Fsm
  235. )
  236. {
  237. DEBUG_ENTER((DBG_HTTP,
  238. Dword,
  239. "HTTP_REQUEST_HANDLE_OBJECT::HttpWriteData_Fsm",
  240. "%#x",
  241. Fsm
  242. ));
  243. CFsm_HttpWriteData & fsm = *Fsm;
  244. DWORD error = fsm.GetError();
  245. if (fsm.GetState() == FSM_STATE_INIT) {
  246. if (!IsValidHttpState(WRITE)) {
  247. error = ERROR_INTERNET_INCORRECT_HANDLE_STATE;
  248. goto quit;
  249. }
  250. error = _Socket->Send(
  251. fsm.m_lpBuffer,
  252. fsm.m_dwNumberOfBytesToWrite,
  253. SF_INDICATE
  254. );
  255. }
  256. if (error == ERROR_SUCCESS)
  257. {
  258. *fsm.m_lpdwNumberOfBytesWritten = fsm.m_dwNumberOfBytesToWrite;
  259. }
  260. quit:
  261. if (error != ERROR_IO_PENDING) {
  262. fsm.SetDone();
  263. }
  264. DEBUG_LEAVE(error);
  265. return error;
  266. }
  267. #endif // defined(THREAD_POOL)