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.

574 lines
13 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. ftp.cxx
  5. Abstract:
  6. Contains methods for FTP_FIND_HANDLE_OBJECT and FTP_FILE_HANDLE_OBJECT classes
  7. Contents:
  8. RMakeFtpFindObjectHandle
  9. RMakeFtpFileObjectHandle
  10. RMakeFtpErrorObjectHandle
  11. FTP_ERROR_HANDLE_OBJECT::SetErrorText
  12. FTP_ERROR_HANDLE_OBJECT::QueryHtmlDataAvailable
  13. Author:
  14. Madan Appiah (madana) 16-Nov-1994
  15. Environment:
  16. User Mode - Win32
  17. Revision History:
  18. Sophia Chung (sophiac) 14-Feb-1995 (added FTP and Archie class impl.)
  19. (code adopted from madana)
  20. --*/
  21. #include <wininetp.h>
  22. //
  23. // functions
  24. //
  25. DWORD
  26. RMakeFtpFindObjectHandle(
  27. IN HINTERNET ParentHandle,
  28. IN OUT HINTERNET * ChildHandle,
  29. IN CLOSE_HANDLE_FUNC wCloseFunc,
  30. IN DWORD_PTR dwContext
  31. )
  32. /*++
  33. Routine Description:
  34. C-callable wrapper for creating an FTP_FIND_HANDLE_OBJECT
  35. Arguments:
  36. ParentHandle - mapped address of parent (connect) handle
  37. ChildHandle - IN: protocol-specific handle value associated with object
  38. OUT: mapped address of FTP_FIND_HANDLE_OBJECT
  39. wCloseFunc - address of protocol-specific function to be called when
  40. object is closed
  41. dwContext - app-supplied context value
  42. Return Value:
  43. DWORD
  44. Success - ERROR_SUCCESS
  45. Failure - ERROR_NOT_ENOUGH_MEMORY
  46. --*/
  47. {
  48. DWORD error;
  49. FTP_FIND_HANDLE_OBJECT * hFind;
  50. hFind = new FTP_FIND_HANDLE_OBJECT(
  51. (INTERNET_CONNECT_HANDLE_OBJECT *)ParentHandle,
  52. *ChildHandle,
  53. wCloseFunc,
  54. dwContext
  55. );
  56. if (hFind != NULL) {
  57. error = hFind->GetStatus();
  58. if (error == ERROR_SUCCESS) {
  59. //
  60. // inform the app of the new handle
  61. //
  62. error = InternetIndicateStatusNewHandle((LPVOID)hFind);
  63. //
  64. // ERROR_INTERNET_OPERATION_CANCELLED is the only error that we are
  65. // expecting here. If we get this error then the app has cancelled
  66. // the operation. Either way, the handle we just generated will be
  67. // already deleted
  68. //
  69. if (error != ERROR_SUCCESS) {
  70. INET_ASSERT(error == ERROR_INTERNET_OPERATION_CANCELLED);
  71. hFind = NULL;
  72. }
  73. } else {
  74. delete hFind;
  75. hFind = NULL;
  76. }
  77. } else {
  78. error = ERROR_NOT_ENOUGH_MEMORY;
  79. }
  80. *ChildHandle = (HINTERNET)hFind;
  81. return error;
  82. }
  83. DWORD
  84. RMakeFtpFileObjectHandle(
  85. IN HINTERNET ParentHandle,
  86. IN OUT HINTERNET * ChildHandle,
  87. IN CLOSE_HANDLE_FUNC wCloseFunc,
  88. IN DWORD_PTR dwContext
  89. )
  90. /*++
  91. Routine Description:
  92. C-callable wrapper for creating an FTP_FILE_HANDLE_OBJECT
  93. Arguments:
  94. ParentHandle - mapped address of parent (connect) handle
  95. ChildHandle - IN: protocol-specific handle value associated with object
  96. OUT: mapped address of FTP_FILE_HANDLE_OBJECT
  97. wCloseFunc - address of protocol-specific function to be called when
  98. object is closed
  99. dwContext - app-supplied context value
  100. Return Value:
  101. DWORD
  102. Success - ERROR_SUCCESS
  103. Failure - ERROR_NOT_ENOUGH_MEMORY
  104. --*/
  105. {
  106. DWORD error;
  107. FTP_FILE_HANDLE_OBJECT * hFile;
  108. DEBUG_PRINT(FTP,
  109. INFO,
  110. ("RMakeFtpFileObject(0x%x 0x%x 0x%x 0x%x)\r\n",
  111. ParentHandle, ChildHandle, wCloseFunc, dwContext));
  112. hFile = new FTP_FILE_HANDLE_OBJECT(
  113. (INTERNET_CONNECT_HANDLE_OBJECT *)ParentHandle,
  114. *ChildHandle,
  115. wCloseFunc,
  116. dwContext
  117. );
  118. if (hFile != NULL) {
  119. error = hFile->GetStatus();
  120. if (error == ERROR_SUCCESS) {
  121. //
  122. // inform the app of the new handle
  123. //
  124. error = InternetIndicateStatusNewHandle((LPVOID)hFile);
  125. //
  126. // ERROR_INTERNET_OPERATION_CANCELLED is the only error that we are
  127. // expecting here. If we get this error then the app has cancelled
  128. // the operation. Either way, the handle we just generated will be
  129. // already deleted
  130. //
  131. if (error != ERROR_SUCCESS) {
  132. INET_ASSERT(error == ERROR_INTERNET_OPERATION_CANCELLED);
  133. hFile = NULL;
  134. }
  135. } else {
  136. delete hFile;
  137. hFile = NULL;
  138. }
  139. } else {
  140. error = ERROR_NOT_ENOUGH_MEMORY;
  141. }
  142. *ChildHandle = (HINTERNET)hFile;
  143. return error;
  144. }
  145. #ifdef EXTENDED_ERROR_HTML
  146. DWORD
  147. RMakeFtpErrorObjectHandle(
  148. IN HINTERNET hConnect,
  149. OUT LPHINTERNET lphError
  150. )
  151. /*++
  152. Routine Description:
  153. Creates an FTP_ERROR_HANDLE_OBJECT. Used to return extended error info as
  154. HTML
  155. Arguments:
  156. hConnect - pointer to INTERNET_CONNECT_HANDLE_OBJECT
  157. lphError - pointer to returned FTP_ERROR_HANDLE_OBJECT
  158. Return Value:
  159. DWORD
  160. --*/
  161. {
  162. FTP_ERROR_HANDLE_OBJECT * hError;
  163. hError = new FTP_ERROR_HANDLE_OBJECT(
  164. (INTERNET_CONNECT_HANDLE_OBJECT *)hConnect
  165. );
  166. DWORD error;
  167. if (hError != NULL) {
  168. error = hError->GetStatus();
  169. if (error == ERROR_SUCCESS) {
  170. //
  171. // inform the app of the new handle
  172. //
  173. error = InternetIndicateStatusNewHandle((LPVOID)hError);
  174. //
  175. // ERROR_INTERNET_OPERATION_CANCELLED is the only error that we are
  176. // expecting here. If we get this error then the app has cancelled
  177. // the operation. Either way, the handle we just generated will be
  178. // already deleted
  179. //
  180. if (error != ERROR_SUCCESS) {
  181. INET_ASSERT(error == ERROR_INTERNET_OPERATION_CANCELLED);
  182. hError = NULL;
  183. }
  184. } else {
  185. delete hError;
  186. hError = NULL;
  187. }
  188. } else {
  189. error = ERROR_NOT_ENOUGH_MEMORY;
  190. }
  191. *lphError = (HINTERNET)hError;
  192. return error;
  193. }
  194. #endif
  195. //
  196. // FTP_FIND_HANDLE_OJBECT class implementation
  197. //
  198. FTP_FIND_HANDLE_OBJECT::FTP_FIND_HANDLE_OBJECT(
  199. INTERNET_CONNECT_HANDLE_OBJECT *Parent,
  200. HINTERNET Child,
  201. CLOSE_HANDLE_FUNC wCloseFunc,
  202. DWORD_PTR dwContext
  203. ) : INTERNET_CONNECT_HANDLE_OBJECT(Parent)
  204. {
  205. _FindHandle = Child;
  206. _wCloseFunction = wCloseFunc;
  207. _dwFtpFindBools = 0;
  208. _lpszUrl = NULL;
  209. _lpszDirEntry = NULL;
  210. _QueryBuffer = NULL;
  211. _QueryBufferLength = 0;
  212. _QueryOffset = 0;
  213. _QueryBytesAvailable = 0;
  214. _Context = dwContext;
  215. SetObjectType(TypeFtpFindHandle);
  216. }
  217. FTP_FIND_HANDLE_OBJECT::~FTP_FIND_HANDLE_OBJECT(
  218. VOID
  219. )
  220. {
  221. //
  222. // if local internet handle, closed by local close function
  223. //
  224. if (_FindHandle != NULL) {
  225. _Status = _wCloseFunction(_FindHandle);
  226. //INET_ASSERT(_Status == ERROR_SUCCESS);
  227. } else {
  228. _Status = ERROR_SUCCESS;
  229. }
  230. //
  231. // clear out any strings we allocated
  232. //
  233. if (_lpszUrl != NULL) {
  234. DEL_STRING(_lpszUrl);
  235. }
  236. if (_lpszDirEntry != NULL) {
  237. DEL_STRING(_lpszDirEntry);
  238. }
  239. //
  240. // and the query buffer
  241. //
  242. FreeQueryBuffer();
  243. }
  244. HANDLE
  245. FTP_FIND_HANDLE_OBJECT::GetHandle(
  246. VOID
  247. )
  248. {
  249. return _FindHandle;
  250. }
  251. DWORD
  252. FTP_FIND_HANDLE_OBJECT::QueryHtmlDataAvailable(
  253. OUT LPDWORD lpdwNumberOfBytesAvailable
  254. )
  255. {
  256. DWORD error;
  257. if (_QueryBuffer != NULL) {
  258. error = ERROR_SUCCESS;
  259. } else {
  260. error = AllocateQueryBuffer();
  261. }
  262. INET_ASSERT(_QueryBytesAvailable == 0);
  263. if (error == ERROR_SUCCESS) {
  264. _QueryOffset = 0;
  265. if (ReadHtmlUrlData((HINTERNET)this,
  266. _QueryBuffer,
  267. _QueryBufferLength,
  268. lpdwNumberOfBytesAvailable
  269. )) {
  270. _QueryBytesAvailable = *lpdwNumberOfBytesAvailable;
  271. //SetAvailableDataLength(_QueryBytesAvailable);
  272. if (_QueryBytesAvailable == 0) {
  273. SetEndOfFile();
  274. }
  275. } else {
  276. error = GetLastError();
  277. }
  278. }
  279. return error;
  280. }
  281. //
  282. // FTP_FILE_HANDLE_OJBECT class implementation
  283. //
  284. FTP_FILE_HANDLE_OBJECT::FTP_FILE_HANDLE_OBJECT(
  285. INTERNET_CONNECT_HANDLE_OBJECT *Parent,
  286. HINTERNET Child,
  287. CLOSE_HANDLE_FUNC wCloseFunc,
  288. DWORD_PTR dwContext
  289. ) : INTERNET_CONNECT_HANDLE_OBJECT(Parent)
  290. {
  291. _FileHandle = Child;
  292. _wCloseFunction = wCloseFunc;
  293. _IsHtml = FALSE;
  294. _lpszFileName = NULL;
  295. _lpszUrl = NULL;
  296. _lpszDirEntry = NULL;
  297. _Context = dwContext;
  298. SetObjectType(TypeFtpFileHandle);
  299. }
  300. FTP_FILE_HANDLE_OBJECT::~FTP_FILE_HANDLE_OBJECT(
  301. VOID
  302. )
  303. {
  304. //
  305. // if local internet handle, closed by local close function
  306. //
  307. if (_FileHandle != NULL) {
  308. _Status = _wCloseFunction(_FileHandle);
  309. //INET_ASSERT(_Status == ERROR_SUCCESS);
  310. } else {
  311. _Status = ERROR_INVALID_HANDLE;
  312. }
  313. //
  314. // clear out any strings we allocated
  315. //
  316. if (_lpszUrl != NULL) {
  317. DEL_STRING(_lpszUrl);
  318. }
  319. if (_lpszDirEntry != NULL) {
  320. DEL_STRING(_lpszDirEntry);
  321. }
  322. if (_lpszFileName != NULL) {
  323. DEL_STRING(_lpszFileName);
  324. }
  325. }
  326. HINTERNET
  327. FTP_FILE_HANDLE_OBJECT::GetHandle(
  328. VOID
  329. )
  330. {
  331. return _FileHandle;
  332. }
  333. #ifdef EXTENDED_ERROR_HTML
  334. //
  335. // FTP_ERROR_HANDLE_OBJECT class implementation
  336. //
  337. FTP_ERROR_HANDLE_OBJECT::FTP_ERROR_HANDLE_OBJECT(
  338. INTERNET_CONNECT_HANDLE_OBJECT* hConnect
  339. ) : INTERNET_CONNECT_HANDLE_OBJECT(hConnect)
  340. {
  341. m_lpszErrorText = NULL;
  342. m_dwErrorTextLength = 0;
  343. m_QueryBuffer = NULL;
  344. m_QueryBufferLength = 0;
  345. m_QueryOffset = 0;
  346. m_QueryBytesAvailable = 0;
  347. m_HtmlState = HTML_STATE_START;
  348. SetObjectType(TypeFtpFileHandle);
  349. SetErrorText();
  350. }
  351. FTP_ERROR_HANDLE_OBJECT::~FTP_ERROR_HANDLE_OBJECT(
  352. VOID
  353. )
  354. {
  355. //
  356. // clear out any strings we allocated
  357. //
  358. if (m_lpszErrorText != NULL) {
  359. DEL_STRING(m_lpszErrorText);
  360. }
  361. //
  362. // and the query buffer
  363. //
  364. FreeQueryBuffer();
  365. }
  366. DWORD
  367. FTP_ERROR_HANDLE_OBJECT::SetErrorText(
  368. VOID
  369. )
  370. /*++
  371. Routine Description:
  372. Copies last error info to this handle object
  373. Arguments:
  374. None.
  375. Return Value:
  376. DWORD
  377. Success - ERROR_SUCCESS
  378. Failure -
  379. --*/
  380. {
  381. INET_ASSERT(m_lpszErrorText == NULL);
  382. INET_ASSERT(m_dwErrorTextLength == 0);
  383. DWORD error;
  384. DWORD category;
  385. if (!InternetGetLastResponseInfo(&category, NULL, &m_dwErrorTextLength)) {
  386. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  387. m_lpszErrorText = (LPSTR)ALLOCATE_MEMORY(
  388. LMEM_FIXED,
  389. m_dwErrorTextLength
  390. );
  391. if (m_lpszErrorText != NULL) {
  392. if (!InternetGetLastResponseInfo(&category,
  393. m_lpszErrorText,
  394. &m_dwErrorTextLength)) {
  395. m_lpszErrorText[0] = '\0';
  396. m_dwErrorTextLength = 0;
  397. }
  398. error = ERROR_SUCCESS;
  399. } else {
  400. error = ERROR_NOT_ENOUGH_MEMORY;
  401. }
  402. }
  403. }
  404. return error;
  405. }
  406. DWORD
  407. FTP_ERROR_HANDLE_OBJECT::QueryHtmlDataAvailable(
  408. OUT LPDWORD lpdwNumberOfBytesAvailable
  409. )
  410. {
  411. DWORD error;
  412. if (m_QueryBuffer != NULL) {
  413. error = ERROR_SUCCESS;
  414. } else {
  415. error = AllocateQueryBuffer();
  416. }
  417. INET_ASSERT(m_QueryBytesAvailable == 0);
  418. if (error == ERROR_SUCCESS) {
  419. m_QueryOffset = 0;
  420. if (ReadHtmlUrlData((HINTERNET)this,
  421. m_QueryBuffer,
  422. m_QueryBufferLength,
  423. lpdwNumberOfBytesAvailable
  424. )) {
  425. m_QueryBytesAvailable = *lpdwNumberOfBytesAvailable;
  426. if (m_QueryBytesAvailable == 0) {
  427. SetEndOfFile();
  428. }
  429. } else {
  430. error = GetLastError();
  431. }
  432. }
  433. return error;
  434. }
  435. #endif