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.

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