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.

626 lines
17 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. Component: Request object
  6. File: Request.h
  7. Owner: CGrant, DGottner
  8. This file contains the header info for defining the Request object.
  9. Note: This was largely stolen from Kraig Brocjschmidt's Inside OLE2
  10. second edition, chapter 14 Beeper v5.
  11. ===================================================================*/
  12. #ifndef _Request_H
  13. #define _Request_H
  14. #include "debug.h"
  15. #include "util.h"
  16. #include "hashing.h"
  17. #include "dispatch.h"
  18. #include "strlist.h"
  19. #include "asptlb.h"
  20. #include "response.h"
  21. #include "memcls.h"
  22. #include "ftm.h"
  23. #ifdef USE_LOCALE
  24. extern DWORD g_dwTLS;
  25. #endif
  26. class CCookie;
  27. class CClCert;
  28. class CRequestHit;
  29. class CServVarsIterator;
  30. // Type for an object-destroyed callback
  31. typedef void (*PFNDESTROYED)(void);
  32. enum CollectionType {NONE, SERVERVARIABLE, QUERYSTRING, FORM, COOKIE, CLCERT };
  33. enum FormDataStatus {AVAILABLE, BINARYREADONLY, FORMCOLLECTIONONLY, ISTREAMONLY};
  34. class CRequest;
  35. #define NUM_REQUEST_HITS 32
  36. /*
  37. * C R e q u e s t H i t s A r r a y
  38. *
  39. * Base class for:
  40. * CQueryString
  41. * CFormInputs
  42. * CCookies
  43. * CClCerts
  44. *
  45. * Implements self-reallocating array of CRequestHit
  46. */
  47. class CRequestHitsArray
  48. {
  49. protected:
  50. DWORD m_dwCount; // How many Request hits there are
  51. DWORD m_dwHitMax; // Number of slots available to store Request hits
  52. CRequestHit** m_rgRequestHit; // Array of Request hits
  53. CRequestHitsArray();
  54. ~CRequestHitsArray();
  55. inline HRESULT Init()
  56. {
  57. m_dwCount = 0;
  58. m_dwHitMax = 0;
  59. m_rgRequestHit = NULL;
  60. return S_OK;
  61. }
  62. inline HRESULT ReInit()
  63. {
  64. m_dwCount = 0;
  65. return S_OK;
  66. }
  67. public:
  68. BOOL AddRequestHit(CRequestHit *pHit);
  69. };
  70. /*
  71. * C Q u e r y S t r i n g
  72. *
  73. * Implements the QueryString object (interface derived from IRequestDictionary)
  74. */
  75. class CQueryString : public IRequestDictionaryImpl, public CRequestHitsArray
  76. {
  77. private:
  78. IUnknown * m_punkOuter; // object to do ref count
  79. CRequest * m_pRequest; // pointer to parent object
  80. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  81. public:
  82. CQueryString(CRequest *, IUnknown *);
  83. // The Big Three
  84. STDMETHODIMP QueryInterface(const GUID &, void **);
  85. STDMETHODIMP_(ULONG) AddRef();
  86. STDMETHODIMP_(ULONG) Release();
  87. // OLE Automation Interface
  88. STDMETHODIMP get_Item(VARIANT varKey, VARIANT *pvarReturn);
  89. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  90. STDMETHODIMP get_Count(int *pcValues);
  91. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  92. HRESULT Init();
  93. HRESULT ReInit();
  94. ~CQueryString();
  95. };
  96. /*
  97. * C S e r v e r V a r i a b l e s
  98. *
  99. * Implements the ServerVariables object (interface derived from IRequestDictionary)
  100. */
  101. class CServerVariables : public IRequestDictionaryImpl
  102. {
  103. private:
  104. IUnknown * m_punkOuter; // object to do ref count
  105. CRequest * m_pRequest; // pointer to parent object
  106. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  107. CServVarsIterator * m_pIterator; // we use an iterator to support integer index
  108. public:
  109. CServerVariables(CRequest *, IUnknown *);
  110. HRESULT Init()
  111. {
  112. return S_OK;
  113. }
  114. // The Big Three
  115. STDMETHODIMP QueryInterface(const GUID &, void **);
  116. STDMETHODIMP_(ULONG) AddRef();
  117. STDMETHODIMP_(ULONG) Release();
  118. // OLE Automation Interface
  119. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  120. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  121. STDMETHODIMP get_Count(int *pcValues);
  122. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  123. // We've added a destructor, but didn't want to change the
  124. // order of the existing vtbl entries.
  125. ~CServerVariables();
  126. };
  127. /*
  128. * C F o r m I n p u t s
  129. *
  130. * Implements the Form object (interface derived from IRequestDictionary)
  131. */
  132. class CFormInputs : public IRequestDictionaryImpl, public CRequestHitsArray
  133. {
  134. private:
  135. IUnknown * m_punkOuter; // object to do ref count
  136. CRequest * m_pRequest; // pointer to parent object
  137. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  138. public:
  139. CFormInputs(CRequest *, IUnknown *);
  140. HRESULT Init();
  141. HRESULT ReInit();
  142. // The Big Three
  143. STDMETHODIMP QueryInterface(const GUID &, void **);
  144. STDMETHODIMP_(ULONG) AddRef();
  145. STDMETHODIMP_(ULONG) Release();
  146. // OLE Automation Interface
  147. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  148. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  149. STDMETHODIMP get_Count(int *pcValues);
  150. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  151. ~CFormInputs();
  152. };
  153. /*
  154. * C C o o k i e s
  155. *
  156. * Implements the Cookies object (interface derived from IRequestDictionary)
  157. */
  158. class CCookies : public IRequestDictionaryImpl, public CRequestHitsArray
  159. {
  160. friend CResponseCookies;
  161. private:
  162. IUnknown * m_punkOuter; // object to do ref count
  163. CRequest * m_pRequest; // pointer to parent object
  164. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  165. CCookie * m_pEmptyCookie; // for when the cookie is not there
  166. public:
  167. CCookies(CRequest *, IUnknown *);
  168. ~CCookies();
  169. HRESULT Init();
  170. HRESULT ReInit();
  171. // The Big Three
  172. STDMETHODIMP QueryInterface(const GUID &, void **);
  173. STDMETHODIMP_(ULONG) AddRef();
  174. STDMETHODIMP_(ULONG) Release();
  175. // OLE Automation Interface
  176. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  177. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  178. STDMETHODIMP get_Count(int *pcValues);
  179. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  180. };
  181. /*
  182. * C C l C e r t s
  183. *
  184. * Implements the ClCerts object (interface derived from IRequestDictionary)
  185. */
  186. class CClCerts : public IRequestDictionaryImpl, public CRequestHitsArray
  187. {
  188. private:
  189. IUnknown * m_punkOuter; // object to do ref count
  190. CRequest * m_pRequest; // pointer to parent object
  191. CSupportErrorInfo m_ISupportErrImp; // implementation of ISupportErr
  192. CClCert * m_pEmptyClCert; // for when the clcert is not there
  193. public:
  194. CClCerts(CRequest *, IUnknown *);
  195. ~CClCerts();
  196. HRESULT Init();
  197. HRESULT ReInit();
  198. // The Big Three
  199. STDMETHODIMP QueryInterface(const GUID &, void **);
  200. STDMETHODIMP_(ULONG) AddRef();
  201. STDMETHODIMP_(ULONG) Release();
  202. // OLE Automation Interface
  203. STDMETHODIMP get_Item(VARIANT Var, VARIANT *pVariantReturn);
  204. STDMETHODIMP get__NewEnum(IUnknown **ppEnumReturn);
  205. STDMETHODIMP get_Count(int *pcValues);
  206. STDMETHODIMP get_Key(VARIANT VarKey, VARIANT *pvar);
  207. };
  208. /*
  209. * C R e q u e s t H i t
  210. *
  211. * Implements the RequestHit object
  212. */
  213. class CRequestHit : private CLinkElem
  214. {
  215. friend class CRequest;
  216. friend class CRequestData;
  217. friend class CQueryString;
  218. friend class CFormInputs;
  219. friend class CCookies;
  220. friend class CClCerts;
  221. friend class CCertRequest;
  222. friend class CResponseCookies;
  223. friend class CRequestIterator;
  224. private:
  225. BOOL m_fInited:1;
  226. BOOL m_fDuplicate:1;
  227. CStringList *m_pQueryData, *m_pFormData;
  228. CCookie *m_pCookieData;
  229. CClCert *m_pClCertData;
  230. public:
  231. CRequestHit();
  232. ~CRequestHit();
  233. HRESULT Init(char *szName, BOOL fDuplicate = FALSE);
  234. HRESULT AddValue(CollectionType source, char *szValue, CIsapiReqInfo *, UINT lCodePage);
  235. HRESULT AddCertValue(VARENUM ve, LPBYTE pValue, UINT cLen );
  236. HRESULT AddKeyAndValue(CollectionType source, char *szKey, char *szValue, CIsapiReqInfo *, UINT lCodePage);
  237. // Cache on per-class basis
  238. ACACHE_INCLASS_DEFINITIONS()
  239. };
  240. /*
  241. * C R e q u e s t D a t a
  242. *
  243. * Structure that holds the intrinsic's properties.
  244. * The instrinsic keeps pointer to it (NULL when lightweight)
  245. */
  246. class CRequestData : public IUnknown
  247. {
  248. friend class CRequest;
  249. friend class CResponse;
  250. friend class CQueryString;
  251. friend class CServerVariables;
  252. friend class CFormInputs;
  253. friend class CCookies;
  254. friend class CClCerts;
  255. friend class CResponseCookies;
  256. friend class CRequestIterator;
  257. friend class CCertRequest;
  258. private:
  259. // constructor to pass params to members and init members
  260. CRequestData(CRequest *pRequest);
  261. ~CRequestData();
  262. HRESULT Init();
  263. HRESULT ReInit(CIsapiReqInfo *pIReq, CHitObj *pHitObj);
  264. HRESULT GetEmptyStringList(IDispatch **ppdisp);
  265. CSupportErrorInfo m_ISupportErrImp; // Implementation of ISupportErrorInfo for this object
  266. CIsapiReqInfo * m_pIReq; // CIsapiReqInfo block for HTTP info
  267. CHitObj * m_pHitObj; // pointer to hitobj for this request
  268. CHashTableMBStr m_mpszStrings; // map sz's to string lists
  269. BOOL m_fLoadForm:1; // do we need to load the body?
  270. BOOL m_fLoadQuery:1; // do we need to load QueryString?
  271. BOOL m_fLoadCookies:1; // do we need to load Cookies?
  272. BOOL m_fLoadClCerts:1; // do we need to load ClCerts?
  273. FormDataStatus m_FormDataStatus; // Is form data available for BinaryRead or Form Collection?
  274. BYTE * m_pbAvailableData; // pointer to available data in CIsapiReqInfo
  275. size_t m_cbAvailable; // number of bytes available in CIsapiReqInfo
  276. size_t m_cbTotal; // Total number of bytes remaining in request
  277. char * m_szFormData; // pointer to form data (allocted or CIsapiReqInfo)
  278. size_t m_cbFormData; // number of bytes allocated for form data
  279. char * m_szFormClone; // clone of form data (LoadVariables clobbers)
  280. char * m_szCookie; // clone of cookie data (this one gets trashed)
  281. size_t m_cbCookie; // number of bytes allocated for the cookie data
  282. char * m_szClCert; // clone of clcert data (this one gets trashed)
  283. size_t m_cbClCert; // number of bytes allocated for the clcert data
  284. CStringList * m_pEmptyString; // all empty results share the same object
  285. CQueryString m_QueryString; // pointer to the "QueryString" object
  286. CServerVariables m_ServerVariables; // pointer to the "ServerVariables" object
  287. CFormInputs m_FormInputs; // pointer to the "Form" object
  288. CCookies m_Cookies; // pointer to the "Cookies" object
  289. CClCerts m_ClCerts; // pointer to the "ClCert" object
  290. ULONG m_cRefs; // ref count
  291. public:
  292. STDMETHODIMP QueryInterface(const GUID &, void **);
  293. STDMETHODIMP_(ULONG) AddRef();
  294. STDMETHODIMP_(ULONG) Release();
  295. // Cache on per-class basis
  296. ACACHE_INCLASS_DEFINITIONS()
  297. };
  298. /*
  299. * C R e q u e s t
  300. *
  301. * Implements the Request object
  302. */
  303. class CRequest : public IRequestImpl, public CFTMImplementation, public IStream
  304. {
  305. friend class CQueryString;
  306. friend class CServerVariables;
  307. friend class CFormInputs;
  308. friend class CCookies;
  309. friend class CClCerts;
  310. friend class CResponseCookies;
  311. friend class CRequestIterator;
  312. friend class CCertRequest;
  313. private:
  314. // Flags
  315. DWORD m_fInited : 1; // Is initialized?
  316. DWORD m_fDiagnostics : 1; // Display ref count in debug output
  317. DWORD m_fOuterUnknown : 1; // Ref count outer unknown?
  318. // Ref count / Outer unknown
  319. union
  320. {
  321. DWORD m_cRefs;
  322. IUnknown *m_punkOuter;
  323. };
  324. // Properties
  325. CRequestData *m_pData; // pointer to structure that holds
  326. // CRequest properties
  327. UINT GetCodePage();
  328. HRESULT LoadVariables(CollectionType Source, char *szURL, UINT lCodePage);
  329. HRESULT LoadCookies(char *szCookies);
  330. HRESULT LoadClCerts(char *szClCerts, UINT lCodePage);
  331. HRESULT LoadCertList( LPSTR pszPrefix, LPSTR* pszCertList);
  332. HRESULT CopyClientData();
  333. HRESULT GetRequestEnumerator(CollectionType, IUnknown **ppEnumReturn);
  334. // Added support for chunked Transfer in Request.form
  335. HRESULT CopyChunkedClientData();
  336. HRESULT CopyNonChunkedClientData();
  337. #ifdef DBG
  338. inline void TurnDiagsOn() { m_fDiagnostics = TRUE; }
  339. inline void TurnDiagsOff() { m_fDiagnostics = FALSE; }
  340. void AssertValid() const;
  341. #else
  342. inline void TurnDiagsOn() {}
  343. inline void TurnDiagsOff() {}
  344. inline void AssertValid() const {}
  345. #endif
  346. public:
  347. CRequest(IUnknown *punkOuter = NULL);
  348. ~CRequest();
  349. HRESULT CleanUp();
  350. HRESULT Init();
  351. HRESULT UnInit();
  352. HRESULT ReInit(CIsapiReqInfo *pIReq, CHitObj *pHitObj);
  353. inline CIsapiReqInfo *GetIReq()
  354. {
  355. Assert(m_fInited);
  356. Assert(m_pData);
  357. return m_pData->m_pIReq;
  358. }
  359. inline CLinkElem* CertStoreFindElem(LPSTR pV, int cV)
  360. {
  361. Assert(m_fInited);
  362. Assert(m_pData);
  363. return m_pData->m_mpszStrings.FindElem( pV, cV );
  364. }
  365. inline CLinkElem* CertStoreAddElem(CLinkElem* pH)
  366. {
  367. Assert(m_fInited);
  368. Assert(m_pData);
  369. return m_pData->m_mpszStrings.AddElem( pH );
  370. }
  371. inline LPSTR GetCertStoreBuf()
  372. {
  373. Assert(m_fInited);
  374. Assert(m_pData);
  375. return m_pData->m_szClCert;
  376. }
  377. inline size_t GetCertStoreSize()
  378. {
  379. Assert(m_fInited);
  380. Assert(m_pData);
  381. return m_pData->m_cbClCert;
  382. }
  383. inline void SetCertStore(LPSTR p, size_t s)
  384. {
  385. Assert(m_fInited);
  386. Assert(m_pData);
  387. m_pData->m_szClCert = p;
  388. m_pData->m_cbClCert = s;
  389. }
  390. inline CHashTable *GetStrings()
  391. {
  392. Assert(m_fInited);
  393. Assert(m_pData);
  394. return &(m_pData->m_mpszStrings);
  395. }
  396. // Non-delegating object IUnknown
  397. //
  398. STDMETHODIMP QueryInterface(const IID &Iid, void **ppvObj);
  399. STDMETHODIMP_(ULONG) AddRef();
  400. STDMETHODIMP_(ULONG) Release();
  401. // Tombstone stub
  402. HRESULT CheckForTombstone();
  403. // IRequest functions
  404. //
  405. STDMETHODIMP get_Item(BSTR bstrVar, IDispatch **ppDispReturn);
  406. STDMETHODIMP get_QueryString(IRequestDictionary **ppDictReturn);
  407. STDMETHODIMP get_Form(IRequestDictionary **ppDictReturn);
  408. STDMETHODIMP get_Body(IRequestDictionary **ppDictReturn);
  409. STDMETHODIMP get_ServerVariables(IRequestDictionary **ppDictReturn);
  410. STDMETHODIMP get_ClientCertificate(IRequestDictionary **ppDictReturn);
  411. STDMETHODIMP get_Cookies(IRequestDictionary **ppDictReturn);
  412. STDMETHODIMP get_TotalBytes(long *pcbTotal);
  413. STDMETHODIMP BinaryRead(VARIANT *pvarCount, VARIANT *pvarReturn);
  414. // IStream implementation
  415. STDMETHODIMP Read(void *pv, ULONG cb, ULONG *pcbRead);
  416. STDMETHODIMP Write(const void *pv, ULONG cb, ULONG *pcbWritten);
  417. STDMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
  418. ULARGE_INTEGER *plibNewPosition);
  419. STDMETHODIMP SetSize(ULARGE_INTEGER libNewSize);
  420. STDMETHODIMP CopyTo(IStream *pstm, ULARGE_INTEGER cb,
  421. ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
  422. STDMETHODIMP Commit(DWORD grfCommitFlags);
  423. STDMETHODIMP Revert();
  424. STDMETHODIMP LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  425. DWORD dwLockType);
  426. STDMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  427. DWORD dwLockType);
  428. STDMETHODIMP Stat(STATSTG *pstatstg, DWORD grfStatFlag);
  429. STDMETHODIMP Clone(IStream **ppstm);
  430. // Cache on per-class basis
  431. ACACHE_INCLASS_DEFINITIONS()
  432. };
  433. /*===================================================================
  434. ITERATORS:
  435. There are two iterators used for Request - a general purpose
  436. iterator which will iterate through the keys of Cookies, QueryString,
  437. Form. A special iterator is used for ServerVariables
  438. ===================================================================*/
  439. /*
  440. * C S e r v V a r s I t e r a t o r
  441. *
  442. * IEnumVariant implementation for Request.ServerVariables
  443. */
  444. class CServVarsIterator : public IEnumVARIANT
  445. {
  446. friend CServerVariables;
  447. public:
  448. CServVarsIterator();
  449. ~CServVarsIterator();
  450. HRESULT Init(CIsapiReqInfo *pIReq);
  451. // The Big Three
  452. STDMETHODIMP QueryInterface(const GUID &, void **);
  453. STDMETHODIMP_(ULONG) AddRef();
  454. STDMETHODIMP_(ULONG) Release();
  455. // standard methods for iterators
  456. STDMETHODIMP Clone(IEnumVARIANT **ppEnumReturn);
  457. STDMETHODIMP Next(unsigned long cElements, VARIANT *rgVariant, unsigned long *pcElementsFetched);
  458. STDMETHODIMP Skip(unsigned long cElements);
  459. STDMETHODIMP Reset();
  460. private:
  461. ULONG m_cRefs; // reference count
  462. wchar_t **m_rgwszKeys; // array of ISAPI keys
  463. wchar_t **m_pwszKey; // current key in gm_rgwszKeys
  464. wchar_t *m_pwchAllHttp; // extra keys in ALL_HTTP server variable
  465. ULONG m_cKeys; // total number of keys
  466. BOOL CreateKeys(wchar_t *pwchKeys, int *pcwchAlloc, int *pcRequestHeaders);
  467. };
  468. /*
  469. * C R e q u e s t I t e r a t o r
  470. *
  471. * IEnumVariant implementation for all Request collections except
  472. * ServerVariables
  473. */
  474. class CRequestIterator : public IEnumVARIANT
  475. {
  476. public:
  477. CRequestIterator(CRequest *, CollectionType);
  478. ~CRequestIterator();
  479. HRESULT Init();
  480. // The Big Three
  481. STDMETHODIMP QueryInterface(const GUID &, void **);
  482. STDMETHODIMP_(ULONG) AddRef();
  483. STDMETHODIMP_(ULONG) Release();
  484. // standard methods for iterators
  485. STDMETHODIMP Clone(IEnumVARIANT **ppEnumReturn);
  486. STDMETHODIMP Next(unsigned long cElements, VARIANT *rgVariant, unsigned long *pcElementsFetched);
  487. STDMETHODIMP Skip(unsigned long cElements);
  488. STDMETHODIMP Reset();
  489. private:
  490. ULONG m_cRefs; // reference count
  491. CollectionType m_Collection; // which collection to iterate over?
  492. CRequest *m_pRequest; // pointer to the request object
  493. CRequestHit *m_pRequestHit; // current bookmark for iteration
  494. };
  495. BOOL RequestSupportInit();
  496. VOID RequestSupportTerminate();
  497. #endif //_Request_H