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.

959 lines
19 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name :
  4. pe_supp.hxx
  5. Abstract:
  6. This module defines the support classes for outbound
  7. protocol events
  8. Author:
  9. Keith Lau (KeithLau) 6/23/98
  10. Project:
  11. SMTP Server DLL
  12. Revision History:
  13. --*/
  14. #ifndef _PE_SUPP_HXX_
  15. #define _PE_SUPP_HXX_
  16. // =================================================================
  17. // Defines
  18. //
  19. #define _VALID_INBOUND_CONTEXT ((DWORD)'CNIv')
  20. #define _VALID_OUTBOUND_CONTEXT ((DWORD)'CUOv')
  21. #define _VALID_RESPONSE_CONTEXT ((DWORD)'CERv')
  22. // =================================================================
  23. // Forward definitions
  24. //
  25. // =================================================================
  26. // Define the inbound context classes
  27. //
  28. class CInboundContext :
  29. public ISmtpInCommandContext,
  30. public ISmtpInCallbackContext
  31. {
  32. public:
  33. CInboundContext()
  34. {
  35. m_pbBlob = NULL;
  36. m_cbBlob = 0;
  37. ResetInboundContext();
  38. m_dwSignature = _VALID_INBOUND_CONTEXT;
  39. }
  40. BOOL IsValid() { return(m_dwSignature == _VALID_INBOUND_CONTEXT); }
  41. void ResetInboundContext()
  42. {
  43. m_cabCommand.Reset();
  44. m_cabResponse.Reset();
  45. m_cabNativeResponse.Reset();
  46. m_pCurrentBinding = NULL;
  47. m_pPreviousBinding = NULL;
  48. m_dwCommandStatus = EXPE_UNHANDLED;
  49. m_dwSmtpStatus = 0;
  50. m_fProtocolError = FALSE;
  51. m_dwWin32Status = NO_ERROR;
  52. m_pICallback = NULL;
  53. m_pbBlob = NULL;
  54. m_cbBlob = 0;
  55. }
  56. void SetWin32Status(DWORD dwWin32Status) { m_dwWin32Status = dwWin32Status; }
  57. DWORD QueryWin32Status() { return m_dwWin32Status; }
  58. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
  59. {
  60. if (riid == IID_IUnknown)
  61. *ppvObj = (IUnknown *)(ISmtpInCommandContext *)this;
  62. else if (riid == IID_ISmtpInCommandContext)
  63. *ppvObj = (ISmtpInCommandContext *)this;
  64. else if (riid == IID_ISmtpInCallbackContext)
  65. *ppvObj = (ISmtpInCallbackContext *)this;
  66. else
  67. return(E_NOINTERFACE);
  68. AddRef();
  69. return(S_OK);
  70. }
  71. unsigned long STDMETHODCALLTYPE AddRef() { return(0); }
  72. unsigned long STDMETHODCALLTYPE Release() { return(0); }
  73. // Query methods
  74. HRESULT STDMETHODCALLTYPE QueryCommand(
  75. LPSTR pszCommand,
  76. DWORD *pdwSize
  77. )
  78. {
  79. if (!pdwSize)
  80. return(E_POINTER);
  81. if (!pszCommand)
  82. {
  83. *pdwSize = 0;
  84. return(E_POINTER);
  85. }
  86. if (*pdwSize < m_cabCommand.Length())
  87. {
  88. *pdwSize = 0;
  89. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  90. }
  91. *pdwSize = m_cabCommand.Length();
  92. memcpy(pszCommand, m_cabCommand.Buffer(), *pdwSize);
  93. return(S_OK);
  94. }
  95. HRESULT STDMETHODCALLTYPE QueryBlob(
  96. PBYTE *ppbBlob,
  97. DWORD *pdwSize
  98. )
  99. {
  100. *ppbBlob = m_pbBlob;
  101. *pdwSize = m_cbBlob;
  102. return S_OK;
  103. }
  104. HRESULT STDMETHODCALLTYPE QueryCommandKeyword(
  105. LPSTR pszKeyword,
  106. DWORD *pdwSize
  107. )
  108. {
  109. if (!pdwSize)
  110. return(E_POINTER);
  111. if (!pszKeyword)
  112. {
  113. *pdwSize = 0;
  114. return(E_POINTER);
  115. }
  116. if (!m_pCurrentCommandContext ||
  117. !m_pCurrentCommandContext->pszCommandKeyword)
  118. {
  119. *pdwSize = 0;
  120. return(E_POINTER);
  121. }
  122. DWORD dwLength = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
  123. if (*pdwSize < dwLength)
  124. {
  125. *pdwSize = 0;
  126. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  127. }
  128. *pdwSize = dwLength;
  129. memcpy(pszKeyword,
  130. m_pCurrentCommandContext->pszCommandKeyword,
  131. dwLength);
  132. return(S_OK);
  133. }
  134. HRESULT STDMETHODCALLTYPE QueryNativeResponse(
  135. LPSTR pszNativeResponse,
  136. DWORD *pdwSize
  137. )
  138. {
  139. if (!pdwSize)
  140. return(E_POINTER);
  141. if (!pszNativeResponse)
  142. {
  143. *pdwSize = 0;
  144. return(E_POINTER);
  145. }
  146. if (*pdwSize < m_cabNativeResponse.Length())
  147. {
  148. *pdwSize = 0;
  149. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  150. }
  151. *pdwSize = m_cabNativeResponse.Length();
  152. memcpy(pszNativeResponse,
  153. m_cabNativeResponse.Buffer(),
  154. *pdwSize);
  155. return(S_OK);
  156. }
  157. HRESULT STDMETHODCALLTYPE QueryResponse(
  158. LPSTR pszResponse,
  159. DWORD *pdwSize
  160. )
  161. {
  162. if (!pdwSize)
  163. return(E_POINTER);
  164. if (!pszResponse)
  165. {
  166. *pdwSize = 0;
  167. return(E_POINTER);
  168. }
  169. if (*pdwSize < m_cabResponse.Length())
  170. {
  171. *pdwSize = 0;
  172. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  173. }
  174. *pdwSize = m_cabResponse.Length();
  175. memcpy(pszResponse,
  176. m_cabResponse.Buffer(),
  177. *pdwSize);
  178. return(S_OK);
  179. }
  180. HRESULT STDMETHODCALLTYPE QueryCommandSize(
  181. DWORD *pdwSize
  182. )
  183. {
  184. if (!pdwSize)
  185. return(E_POINTER);
  186. *pdwSize = m_cabCommand.Length();
  187. return(S_OK);
  188. }
  189. HRESULT STDMETHODCALLTYPE QueryBlobSize(
  190. DWORD *pdwSize
  191. )
  192. {
  193. *pdwSize = m_cbBlob;
  194. return S_OK;
  195. }
  196. HRESULT STDMETHODCALLTYPE QueryCommandKeywordSize(
  197. DWORD *pdwSize
  198. )
  199. {
  200. if (!pdwSize)
  201. return(E_POINTER);
  202. if (!m_pCurrentCommandContext ||
  203. !m_pCurrentCommandContext->pszCommandKeyword)
  204. return(E_POINTER);
  205. *pdwSize = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
  206. return(S_OK);
  207. }
  208. HRESULT STDMETHODCALLTYPE QueryNativeResponseSize(
  209. DWORD *pdwSize
  210. )
  211. {
  212. if (!pdwSize)
  213. return(E_POINTER);
  214. *pdwSize = m_cabNativeResponse.Length();
  215. return(S_OK);
  216. }
  217. HRESULT STDMETHODCALLTYPE QueryResponseSize(
  218. DWORD *pdwSize
  219. )
  220. {
  221. if (!pdwSize)
  222. return(E_POINTER);
  223. *pdwSize = m_cabResponse.Length();
  224. return(S_OK);
  225. }
  226. HRESULT STDMETHODCALLTYPE QueryCommandStatus(
  227. DWORD *pdwCommandStatus
  228. )
  229. {
  230. if (!pdwCommandStatus)
  231. return(E_POINTER);
  232. *pdwCommandStatus = m_dwCommandStatus;
  233. return(S_OK);
  234. }
  235. HRESULT STDMETHODCALLTYPE QuerySmtpStatusCode(
  236. DWORD *pdwSmtpStatus
  237. )
  238. {
  239. if (!pdwSmtpStatus)
  240. return(E_POINTER);
  241. *pdwSmtpStatus = m_dwSmtpStatus;
  242. return(S_OK);
  243. }
  244. HRESULT STDMETHODCALLTYPE QueryProtocolErrorFlag(
  245. BOOL *pfProtocolError
  246. )
  247. {
  248. if (!pfProtocolError)
  249. return(E_POINTER);
  250. *pfProtocolError = m_fProtocolError;
  251. return(S_OK);
  252. }
  253. // Set methods
  254. HRESULT STDMETHODCALLTYPE SetResponse(
  255. LPSTR szResponse,
  256. DWORD dwSize
  257. )
  258. {
  259. if (!szResponse)
  260. return(E_POINTER);
  261. m_cabResponse.Reset();
  262. return(m_cabResponse.Append(szResponse, dwSize, NULL));
  263. }
  264. HRESULT STDMETHODCALLTYPE AppendResponse(
  265. LPSTR szResponse,
  266. DWORD dwSize
  267. )
  268. {
  269. if (!szResponse)
  270. return(E_POINTER);
  271. return(m_cabResponse.Append(szResponse, dwSize, NULL));
  272. }
  273. HRESULT STDMETHODCALLTYPE SetNativeResponse(
  274. LPSTR szNativeResponse,
  275. DWORD dwSize
  276. )
  277. {
  278. if (!szNativeResponse)
  279. return(E_POINTER);
  280. m_cabNativeResponse.Reset();
  281. return(m_cabNativeResponse.Append(szNativeResponse, dwSize, NULL));
  282. }
  283. HRESULT STDMETHODCALLTYPE AppendNativeResponse(
  284. LPSTR szNativeResponse,
  285. DWORD dwSize
  286. )
  287. {
  288. if (!szNativeResponse)
  289. return(E_POINTER);
  290. return(m_cabNativeResponse.Append(szNativeResponse, dwSize, NULL));
  291. }
  292. HRESULT STDMETHODCALLTYPE SetCommandStatus(
  293. DWORD dwCommandStatus
  294. )
  295. {
  296. m_dwCommandStatus = dwCommandStatus;
  297. return(S_OK);
  298. }
  299. HRESULT STDMETHODCALLTYPE SetProtocolErrorFlag(
  300. BOOL fProtocolError
  301. )
  302. {
  303. m_fProtocolError = fProtocolError;
  304. return(S_OK);
  305. }
  306. HRESULT STDMETHODCALLTYPE SetSmtpStatusCode(
  307. DWORD dwSmtpStatus
  308. )
  309. {
  310. m_dwSmtpStatus = dwSmtpStatus;
  311. return(S_OK);
  312. }
  313. HRESULT STDMETHODCALLTYPE SetCallback(
  314. ISmtpInCallbackSink * pCallback
  315. )
  316. {
  317. if ( NULL != m_pICallback) {
  318. m_pICallback->Release();
  319. }
  320. if ( NULL != pCallback) {
  321. pCallback->AddRef();
  322. }
  323. m_pICallback = pCallback;
  324. return S_OK;
  325. }
  326. HRESULT STDMETHODCALLTYPE NotifyAsyncCompletion(
  327. HRESULT hrResult
  328. );
  329. public:
  330. DWORD m_dwSignature;
  331. CAppendBuffer m_cabCommand;
  332. CAppendBuffer m_cabResponse;
  333. CAppendBuffer m_cabNativeResponse;
  334. LPPE_COMMAND_NODE m_pCurrentCommandContext;
  335. LPPE_BINDING_NODE m_pPreviousBinding;
  336. LPPE_BINDING_NODE m_pCurrentBinding;
  337. PBYTE m_pbBlob;
  338. DWORD m_cbBlob;
  339. ISmtpInCallbackSink * m_pICallback;
  340. DWORD m_dwCommandStatus;
  341. DWORD m_dwSmtpStatus;
  342. DWORD m_dwWin32Status;
  343. BOOL m_fProtocolError;
  344. };
  345. // =================================================================
  346. // Define the outbound context classes
  347. //
  348. class COutboundContext :
  349. public ISmtpOutCommandContext
  350. {
  351. public:
  352. COutboundContext()
  353. {
  354. m_pbBlob = NULL;
  355. m_cbBlob = 0;
  356. ResetOutboundContext();
  357. m_pCurrentCommandContext = NULL;
  358. m_pCurrentBinding = NULL;
  359. m_dwSignature = _VALID_OUTBOUND_CONTEXT;
  360. }
  361. ~COutboundContext()
  362. {
  363. if ( NULL != m_pbBlob) {
  364. delete [] m_pbBlob;
  365. m_pbBlob = NULL;
  366. }
  367. m_cbBlob = 0;
  368. }
  369. BOOL IsValid() { return(m_dwSignature == _VALID_OUTBOUND_CONTEXT); }
  370. void ResetOutboundContext()
  371. {
  372. m_cabCommand.Reset();
  373. m_cabNativeCommand.Reset();
  374. m_dwCommandStatus = EXPE_UNHANDLED;
  375. m_dwCurrentRecipient = 0;
  376. if ( NULL != m_pbBlob) {
  377. delete [] m_pbBlob;
  378. m_pbBlob = NULL;
  379. }
  380. m_cbBlob = 0;
  381. }
  382. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
  383. {
  384. if (riid == IID_IUnknown)
  385. *ppvObj = (IUnknown *)(ISmtpOutCommandContext *)this;
  386. else if (riid == IID_ISmtpOutCommandContext)
  387. *ppvObj = (ISmtpOutCommandContext *)this;
  388. else
  389. return(E_NOINTERFACE);
  390. AddRef();
  391. return(S_OK);
  392. }
  393. unsigned long STDMETHODCALLTYPE AddRef() { return(0); }
  394. unsigned long STDMETHODCALLTYPE Release() { return(0); }
  395. HRESULT STDMETHODCALLTYPE QueryCommand(
  396. LPSTR pszCommand,
  397. DWORD *pdwSize
  398. )
  399. {
  400. if (!pdwSize)
  401. return(E_POINTER);
  402. if (!pszCommand)
  403. {
  404. *pdwSize = 0;
  405. return(E_POINTER);
  406. }
  407. if (*pdwSize < m_cabCommand.Length())
  408. {
  409. *pdwSize = 0;
  410. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  411. }
  412. *pdwSize = m_cabCommand.Length();
  413. memcpy(pszCommand, m_cabCommand.Buffer(), *pdwSize);
  414. return(S_OK);
  415. }
  416. HRESULT STDMETHODCALLTYPE QueryCommandKeyword(
  417. LPSTR pszKeyword,
  418. DWORD *pdwSize
  419. )
  420. {
  421. if (!pdwSize)
  422. return(E_POINTER);
  423. if (!pszKeyword)
  424. {
  425. *pdwSize = 0;
  426. return(E_POINTER);
  427. }
  428. if (!m_pCurrentCommandContext ||
  429. !m_pCurrentCommandContext->pszCommandKeyword)
  430. {
  431. *pdwSize = 0;
  432. return(E_POINTER);
  433. }
  434. DWORD dwLength = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
  435. if (*pdwSize < dwLength)
  436. {
  437. *pdwSize = 0;
  438. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  439. }
  440. *pdwSize = dwLength;
  441. memcpy(pszKeyword,
  442. m_pCurrentCommandContext->pszCommandKeyword,
  443. dwLength);
  444. return(S_OK);
  445. }
  446. HRESULT STDMETHODCALLTYPE QueryNativeCommand(
  447. LPSTR pszNativeCommand,
  448. DWORD *pdwSize
  449. )
  450. {
  451. if(!pdwSize)
  452. return(E_POINTER);
  453. if (!pszNativeCommand)
  454. {
  455. *pdwSize = 0;
  456. return(E_POINTER);
  457. }
  458. if (*pdwSize < m_cabNativeCommand.Length())
  459. {
  460. *pdwSize = 0;
  461. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  462. }
  463. *pdwSize = m_cabNativeCommand.Length();
  464. memcpy(pszNativeCommand,
  465. m_cabNativeCommand.Buffer(),
  466. *pdwSize);
  467. return(S_OK);
  468. }
  469. HRESULT STDMETHODCALLTYPE QueryCommandSize(
  470. DWORD *pdwSize
  471. )
  472. {
  473. if (!pdwSize)
  474. return(E_POINTER);
  475. *pdwSize = m_cabCommand.Length();
  476. return(S_OK);
  477. }
  478. HRESULT STDMETHODCALLTYPE QueryCommandKeywordSize(
  479. DWORD *pdwSize
  480. )
  481. {
  482. if (!pdwSize)
  483. return(E_POINTER);
  484. if (!m_pCurrentCommandContext ||
  485. !m_pCurrentCommandContext->pszCommandKeyword)
  486. return(E_POINTER);
  487. *pdwSize = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
  488. return(S_OK);
  489. }
  490. HRESULT STDMETHODCALLTYPE QueryNativeCommandSize(
  491. DWORD *pdwSize
  492. )
  493. {
  494. if (!pdwSize)
  495. return(E_POINTER);
  496. *pdwSize = m_cabNativeCommand.Length();
  497. return(S_OK);
  498. }
  499. HRESULT STDMETHODCALLTYPE QueryCurrentRecipientIndex(
  500. DWORD *pdwRecipientIndex
  501. )
  502. {
  503. if (!pdwRecipientIndex)
  504. return(E_POINTER);
  505. *pdwRecipientIndex = m_dwCurrentRecipient;
  506. return(S_OK);
  507. }
  508. HRESULT STDMETHODCALLTYPE QueryCommandStatus(
  509. DWORD *pdwCommandStatus
  510. )
  511. {
  512. if (!pdwCommandStatus)
  513. return(E_POINTER);
  514. *pdwCommandStatus = m_dwCommandStatus;
  515. return(S_OK);
  516. }
  517. HRESULT STDMETHODCALLTYPE SetCommand(
  518. LPSTR szCommand,
  519. DWORD dwSize
  520. )
  521. {
  522. if (!szCommand)
  523. return(E_POINTER);
  524. m_cabCommand.Reset();
  525. return(m_cabCommand.Append(szCommand, dwSize, NULL));
  526. }
  527. HRESULT STDMETHODCALLTYPE SetBlob(
  528. BYTE * pbBlob,
  529. DWORD dwSize
  530. )
  531. {
  532. BYTE * pbTempBlob;
  533. if (!pbBlob) {
  534. return(E_POINTER);
  535. }
  536. pbTempBlob = new BYTE[ dwSize];
  537. if ( NULL == pbTempBlob) {
  538. return E_OUTOFMEMORY;
  539. }
  540. if ( NULL != m_pbBlob) {
  541. delete [] m_pbBlob;
  542. }
  543. m_pbBlob = pbTempBlob;
  544. memcpy(m_pbBlob, pbBlob, dwSize);
  545. m_cbBlob = dwSize;
  546. return S_OK;
  547. }
  548. HRESULT STDMETHODCALLTYPE AppendCommand(
  549. LPSTR szCommand,
  550. DWORD dwSize
  551. )
  552. {
  553. if (!szCommand)
  554. return(E_POINTER);
  555. return(m_cabCommand.Append(szCommand, dwSize, NULL));
  556. }
  557. HRESULT STDMETHODCALLTYPE SetCommandStatus(
  558. DWORD dwCommandStatus
  559. )
  560. {
  561. m_dwCommandStatus = dwCommandStatus;
  562. return(S_OK);
  563. }
  564. HRESULT STDMETHODCALLTYPE NotifyAsyncCompletion(
  565. HRESULT hrResult
  566. );
  567. public:
  568. DWORD m_dwSignature;
  569. CAppendBuffer m_cabCommand;
  570. CAppendBuffer m_cabNativeCommand;
  571. LPPE_COMMAND_NODE m_pCurrentCommandContext;
  572. LPPE_BINDING_NODE m_pCurrentBinding;
  573. DWORD m_dwCommandStatus;
  574. DWORD m_dwCurrentRecipient;
  575. PBYTE m_pbBlob;
  576. DWORD m_cbBlob;
  577. };
  578. // =================================================================
  579. // Define the response context classes
  580. //
  581. class CResponseContext :
  582. public ISmtpServerResponseContext
  583. {
  584. public:
  585. CResponseContext()
  586. {
  587. ResetResponseContext();
  588. m_dwSignature = _VALID_RESPONSE_CONTEXT;
  589. }
  590. BOOL IsValid() { return(m_dwSignature == _VALID_RESPONSE_CONTEXT); }
  591. void ResetResponseContext()
  592. {
  593. m_cabResponse.Reset();
  594. m_pCommand = NULL;
  595. m_dwResponseStatus = EXPE_UNHANDLED;
  596. m_pCurrentBinding = NULL;
  597. m_dwSmtpStatus = 0;
  598. m_dwNextState = PE_STATE_DEFAULT;
  599. }
  600. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
  601. {
  602. if (riid == IID_IUnknown)
  603. *ppvObj = (IUnknown *)(ISmtpServerResponseContext *)this;
  604. else if (riid == IID_ISmtpServerResponseContext)
  605. *ppvObj = (ISmtpServerResponseContext *)this;
  606. else
  607. return(E_NOINTERFACE);
  608. AddRef();
  609. return(S_OK);
  610. }
  611. unsigned long STDMETHODCALLTYPE AddRef() { return(0); }
  612. unsigned long STDMETHODCALLTYPE Release() { return(0); }
  613. HRESULT STDMETHODCALLTYPE QueryCommand(
  614. LPSTR pszCommand,
  615. DWORD *pdwSize
  616. )
  617. {
  618. if (!pdwSize)
  619. return(E_POINTER);
  620. if (!pszCommand || !m_pCommand)
  621. {
  622. *pdwSize = 0;
  623. return(E_POINTER);
  624. }
  625. if (!m_pCommand->pszFullCommand)
  626. {
  627. *pdwSize = 0;
  628. return(E_POINTER);
  629. }
  630. DWORD dwLength = strlen(m_pCommand->pszFullCommand) + 1;
  631. if (*pdwSize < dwLength)
  632. {
  633. *pdwSize = 0;
  634. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  635. }
  636. *pdwSize = dwLength;
  637. memcpy(pszCommand,
  638. m_pCommand->pszFullCommand,
  639. dwLength);
  640. return(S_OK);
  641. }
  642. HRESULT STDMETHODCALLTYPE QueryCommandKeyword(
  643. LPSTR pszKeyword,
  644. DWORD *pdwSize
  645. )
  646. {
  647. if (!pdwSize)
  648. return(E_POINTER);
  649. if(!pszKeyword)
  650. {
  651. *pdwSize = 0;
  652. return(E_POINTER);
  653. }
  654. if (!m_pCommand || !m_pCommand->pszCommandKeyword)
  655. {
  656. *pdwSize = 0;
  657. return(E_POINTER);
  658. }
  659. DWORD dwLength = strlen(m_pCommand->pszCommandKeyword) + 1;
  660. if (*pdwSize < dwLength)
  661. {
  662. *pdwSize = 0;
  663. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  664. }
  665. *pdwSize = dwLength;
  666. memcpy(pszKeyword,
  667. m_pCommand->pszCommandKeyword,
  668. dwLength);
  669. return(S_OK);
  670. }
  671. HRESULT STDMETHODCALLTYPE QueryResponse(
  672. LPSTR pszResponse,
  673. DWORD *pdwSize
  674. )
  675. {
  676. if (!pdwSize)
  677. return(E_POINTER);
  678. if (!pszResponse)
  679. {
  680. *pdwSize = 0;
  681. return(E_POINTER);
  682. }
  683. if (*pdwSize < m_cabResponse.Length())
  684. {
  685. *pdwSize = 0;
  686. return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  687. }
  688. *pdwSize = m_cabResponse.Length();
  689. memcpy(pszResponse,
  690. m_cabResponse.Buffer(),
  691. *pdwSize);
  692. return(S_OK);
  693. }
  694. HRESULT STDMETHODCALLTYPE QueryCommandSize(
  695. DWORD *pdwSize
  696. )
  697. {
  698. if (!pdwSize)
  699. return(E_POINTER);
  700. *pdwSize = 0;
  701. if (!m_pCommand || !m_pCommand->pszFullCommand)
  702. return(E_POINTER);
  703. *pdwSize = strlen(m_pCommand->pszFullCommand) + 1;
  704. return(S_OK);
  705. }
  706. HRESULT STDMETHODCALLTYPE QueryCommandKeywordSize(
  707. DWORD *pdwSize
  708. )
  709. {
  710. if (!pdwSize)
  711. return(E_POINTER);
  712. *pdwSize = 0;
  713. if (!m_pCommand || !m_pCommand->pszCommandKeyword)
  714. return(E_POINTER);
  715. *pdwSize = strlen(m_pCommand->pszCommandKeyword) + 1;
  716. return(S_OK);
  717. }
  718. HRESULT STDMETHODCALLTYPE QueryResponseSize(
  719. DWORD *pdwSize
  720. )
  721. {
  722. if (!pdwSize)
  723. return(E_POINTER);
  724. *pdwSize = m_cabResponse.Length();
  725. return(S_OK);
  726. }
  727. HRESULT STDMETHODCALLTYPE QuerySmtpStatusCode(
  728. DWORD *pdwSmtpStatus
  729. )
  730. {
  731. if (!pdwSmtpStatus)
  732. return(E_POINTER);
  733. *pdwSmtpStatus = m_dwSmtpStatus;
  734. return(S_OK);
  735. }
  736. HRESULT STDMETHODCALLTYPE QueryResponseStatus(
  737. DWORD *pdwResponseStatus
  738. )
  739. {
  740. if (!pdwResponseStatus)
  741. return(E_POINTER);
  742. *pdwResponseStatus = m_dwResponseStatus;
  743. return(S_OK);
  744. }
  745. HRESULT STDMETHODCALLTYPE QueryPipelinedFlag(
  746. BOOL *pfResponseIsPipelined
  747. )
  748. {
  749. if (!pfResponseIsPipelined)
  750. return(E_POINTER);
  751. _ASSERT(m_pCommand);
  752. *pfResponseIsPipelined =
  753. ((m_pCommand->dwFlags & PECQ_PIPELINED)?TRUE:FALSE);
  754. return(S_OK);
  755. }
  756. HRESULT STDMETHODCALLTYPE QueryNextEventState(
  757. DWORD *pdwNextState
  758. )
  759. {
  760. if (!pdwNextState)
  761. return(E_POINTER);
  762. *pdwNextState = m_dwNextState;
  763. return(S_OK);
  764. }
  765. HRESULT STDMETHODCALLTYPE SetSmtpStatus(
  766. DWORD dwSmtpStatus
  767. )
  768. {
  769. m_dwSmtpStatus = dwSmtpStatus;
  770. return(S_OK);
  771. }
  772. HRESULT STDMETHODCALLTYPE SetResponseStatus(
  773. DWORD dwResponseStatus
  774. )
  775. {
  776. m_dwResponseStatus = dwResponseStatus;
  777. return(S_OK);
  778. }
  779. HRESULT STDMETHODCALLTYPE SetNextEventState(
  780. DWORD dwNextState
  781. )
  782. {
  783. // Note PE_STATE_MAX_STATES is valid!
  784. if (dwNextState > PE_STATE_MAX_STATES)
  785. return(E_INVALIDARG);
  786. m_dwNextState = dwNextState;
  787. return(S_OK);
  788. }
  789. HRESULT STDMETHODCALLTYPE NotifyAsyncCompletion(
  790. HRESULT hrResult
  791. );
  792. public:
  793. DWORD m_dwSignature;
  794. LPOUTBOUND_COMMAND_Q_ENTRY m_pCommand;
  795. LPPE_BINDING_NODE m_pCurrentBinding;
  796. CAppendBuffer m_cabResponse;
  797. DWORD m_dwResponseStatus;
  798. DWORD m_dwSmtpStatus;
  799. DWORD m_dwNextState;
  800. };
  801. #endif