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.

538 lines
14 KiB

  1. #ifndef _ECB_H_
  2. #define _ECB_H_
  3. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4. //
  5. // ECB.H
  6. //
  7. // Header for IEcb interface class.
  8. //
  9. // Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  10. //
  11. #include <autoptr.h> // For CMTRefCounted parent
  12. #include <cvroot.h>
  13. #include <davmb.h> // For IMDData
  14. #include <url.h> // For HttpUriEscape
  15. // ========================================================================
  16. //
  17. // ENUM TRANSFER_CODINGS
  18. //
  19. // Valid transfer codings. See HTTP/1.1 draft section 3.5.
  20. //
  21. // TC_UNKNOWN - Unknown value.
  22. // TC_IDENTITY - Identity encoding (i.e. no encoding).
  23. // TC_CHUNKED - Chunked encoding.
  24. //
  25. enum TRANSFER_CODINGS
  26. {
  27. TC_UNKNOWN,
  28. TC_IDENTITY,
  29. TC_CHUNKED
  30. };
  31. typedef struct _HSE_EXEC_URL_INFO_WIDE {
  32. LPCWSTR pwszUrl; // URL to execute
  33. DWORD dwExecUrlFlags; // Flags
  34. } HSE_EXEC_URL_INFO_WIDE, * LPHSE_EXEC_URL_INFO_WIDE;
  35. // ========================================================================
  36. //
  37. // CLASS IIISAsyncIOCompleteObserver
  38. //
  39. // Passed to IEcb async I/O methods
  40. //
  41. class IIISAsyncIOCompleteObserver
  42. {
  43. // NOT IMPLEMENTED
  44. //
  45. IIISAsyncIOCompleteObserver& operator=( const IIISAsyncIOCompleteObserver& );
  46. public:
  47. // CREATORS
  48. //
  49. virtual ~IIISAsyncIOCompleteObserver() = 0;
  50. // MANIPULATORS
  51. //
  52. virtual VOID IISIOComplete( DWORD dwcbIO, DWORD dwLastError ) = 0;
  53. };
  54. // ========================================================================
  55. //
  56. // CLASS IEcb
  57. //
  58. // Provides a clean interface to the EXTENSION_CONTROL_BLOCK passed
  59. // to us by IIS.
  60. //
  61. class CInstData;
  62. class IEcbBase : public CMTRefCounted
  63. {
  64. private:
  65. // NOT IMPLEMENTED
  66. //
  67. IEcbBase( const IEcbBase& );
  68. IEcbBase& operator=( const IEcbBase& );
  69. // Private URL mapping helpers
  70. //
  71. SCODE ScReqMapUrlToPathEx60After(
  72. /* [in] */ LPCWSTR pwszUrl,
  73. /* [out] */ HSE_UNICODE_URL_MAPEX_INFO * pmi ) const
  74. {
  75. SCODE sc = S_OK;
  76. UINT cbPath = sizeof(pmi->lpszPath);
  77. Assert( m_pecb );
  78. Assert( pwszUrl );
  79. Assert( pmi );
  80. if (!m_pecb->ServerSupportFunction( m_pecb->ConnID,
  81. HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX,
  82. const_cast<LPWSTR>(pwszUrl),
  83. reinterpret_cast<DWORD*>(&cbPath),
  84. reinterpret_cast<DWORD*>(pmi) ))
  85. {
  86. // There is a fix for Windows Bugs 156176 that we need to do the
  87. // following check for. It applies to IIS 6.0 (+) path only. In IIS 5.0
  88. // the maping functions were silently succeeding, and truncating the
  89. // buffer that contained the mapped path if it exceeded MAX_PATH.
  90. // That behaviour suited us, but is not very nice, so IIS 6.0 chose
  91. // to still fill in the buffer as before, but fail with special error
  92. // (ERROR_INSUFFICIENT_BUFFER). That error still means success to us,
  93. // so fail only if we see something different
  94. //
  95. if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
  96. {
  97. // Function does not allow to return failures, so the only option
  98. // is to throw. We cannot proceed if we did not get the data anyway.
  99. // If this function succeeds once, subsequent calls to it are non
  100. // failing.
  101. //
  102. sc = HRESULT_FROM_WIN32(GetLastError());
  103. Assert(FAILED(sc));
  104. DebugTrace("IEcbBase::ScReqMapUrlToPathEx60After() - ServerSupportFunction(HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX) failed 0x%08lX\n", sc);
  105. goto ret;
  106. }
  107. }
  108. DebugTrace ("IEcbBase::ScReqMapUrlToPathEx60After() - ServerSupportFunction"
  109. "(HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX) succeded!\n"
  110. "mapinfo:\n"
  111. "- url \"%ls\" maps to \"%ls\"\n"
  112. "- dwFlags = 0x%08x\n"
  113. "- cchMatchingPath = %d\n"
  114. "- cchMatchingURL = %d\n",
  115. pwszUrl,
  116. pmi->lpszPath,
  117. pmi->dwFlags,
  118. pmi->cchMatchingPath,
  119. pmi->cchMatchingURL);
  120. // The value for cbPath, at this point, should include the L'\0'
  121. // termination, and for that reason cbPath will always be more
  122. // than the length of the matching path.
  123. //
  124. Assert (0 == cbPath % sizeof(WCHAR));
  125. Assert (pmi->cchMatchingPath < cbPath/sizeof(WCHAR));
  126. ret:
  127. return sc;
  128. }
  129. SCODE ScReqMapUrlToPathEx60Before(
  130. /* [in] */ LPCWSTR pwszUrl,
  131. /* [out] */ HSE_UNICODE_URL_MAPEX_INFO * pmi ) const
  132. {
  133. SCODE sc = S_OK;
  134. HSE_URL_MAPEX_INFO mi;
  135. CStackBuffer<CHAR, MAX_PATH> pszUrl;
  136. UINT cchUrl;
  137. UINT cbUrl;
  138. UINT cbPath;
  139. UINT cchPath;
  140. Assert( m_pecb );
  141. Assert( pwszUrl );
  142. Assert( pmi );
  143. // Find out the length of the URL
  144. //
  145. cchUrl = static_cast<UINT>(wcslen(pwszUrl));
  146. cbUrl = cchUrl * 3;
  147. // Resize the buffer to the sufficient size, leave place for '\0' termination
  148. //
  149. if (!pszUrl.resize(cbUrl + 1))
  150. {
  151. sc = E_OUTOFMEMORY;
  152. DebugTrace("IEcbBase::ScReqMapUrlToPathEx60Before() - Error while allocating memory 0x%08lX\n", sc);
  153. goto ret;
  154. }
  155. // Convert to skinny including '\0' termination
  156. //
  157. cbUrl = WideCharToMultiByte(CP_ACP,
  158. 0,
  159. pwszUrl,
  160. cchUrl + 1,
  161. pszUrl.get(),
  162. cbUrl + 1,
  163. 0,
  164. 0);
  165. if (0 == cbUrl)
  166. {
  167. sc = HRESULT_FROM_WIN32(GetLastError());
  168. DebugTrace("IEcbBase::ScSSFReqMapUrlToPathEx() - WideCharToMultiByte() failed 0x%08lX\n", sc);
  169. goto ret;
  170. }
  171. cbPath = MAX_PATH;
  172. // Get the skinny mappings from IIS
  173. //
  174. if (!m_pecb->ServerSupportFunction( m_pecb->ConnID,
  175. HSE_REQ_MAP_URL_TO_PATH_EX,
  176. pszUrl.get(),
  177. reinterpret_cast<DWORD*>(&cbPath),
  178. reinterpret_cast<DWORD*>(&mi)))
  179. {
  180. sc = HRESULT_FROM_WIN32(GetLastError());
  181. DebugTrace("IEcbBase::ScSSFReqMapUrlToPathEx() - ServerSupportFunction() failed 0x%08lX\n", sc);
  182. goto ret;
  183. }
  184. DebugTrace ("IEcbBase::ScSSFReqMapUrlToPathEx() - ServerSupportFunction"
  185. "(HSE_REQ_MAP_URL_TO_PATH_EX) succeded!\n"
  186. "mapinfo:\n"
  187. "- url \"%hs\" maps to \"%hs\"\n"
  188. "- dwFlags = 0x%08x\n"
  189. "- cchMatchingPath = %d\n"
  190. "- cchMatchingURL = %d\n",
  191. pszUrl.get(),
  192. mi.lpszPath,
  193. mi.dwFlags,
  194. mi.cchMatchingPath,
  195. mi.cchMatchingURL);
  196. // The value for cbPath, at this point, should include the null
  197. // termination, and for that reason cbPath will always be more
  198. // than the length of the matching path.
  199. //
  200. Assert (mi.cchMatchingPath < cbPath);
  201. Assert (mi.cchMatchingURL < cbUrl);
  202. // First translate the matching path so we would know its
  203. // length and would be able to pass it back
  204. //
  205. if (mi.cchMatchingPath)
  206. {
  207. // Converting will never yield the buffer bigger than one we already have
  208. //
  209. pmi->cchMatchingPath = MultiByteToWideChar(CP_ACP,
  210. MB_ERR_INVALID_CHARS,
  211. mi.lpszPath,
  212. mi.cchMatchingPath,
  213. pmi->lpszPath,
  214. MAX_PATH);
  215. if (0 == pmi->cchMatchingPath)
  216. {
  217. sc = HRESULT_FROM_WIN32(GetLastError());
  218. DebugTrace("IEcbBase::ScSSFReqMapUrlToPathEx() - MultiByteToWideChar() failed 0x%08lX\n", sc);
  219. goto ret;
  220. }
  221. }
  222. else
  223. {
  224. pmi->cchMatchingPath = 0;
  225. }
  226. // Convert the remainder of the path including the '\0' termination
  227. //
  228. cchPath = MultiByteToWideChar(CP_ACP,
  229. MB_ERR_INVALID_CHARS,
  230. mi.lpszPath + mi.cchMatchingPath,
  231. min(cbPath, MAX_PATH) - mi.cchMatchingPath,
  232. pmi->lpszPath + pmi->cchMatchingPath,
  233. MAX_PATH - pmi->cchMatchingPath);
  234. if (0 == cchPath)
  235. {
  236. sc = HRESULT_FROM_WIN32(GetLastError());
  237. DebugTrace("IEcbBase::ScReqMapUrlToPathEx() - MultiByteToWideChar() failed 0x%08lX\n", sc);
  238. goto ret;
  239. }
  240. // Find the matching URL length for wide version
  241. //
  242. if (mi.cchMatchingURL)
  243. {
  244. pmi->cchMatchingURL = MultiByteToWideChar(CP_ACP,
  245. MB_ERR_INVALID_CHARS,
  246. pszUrl.get(),
  247. mi.cchMatchingURL,
  248. 0,
  249. 0);
  250. if (0 == pmi->cchMatchingURL)
  251. {
  252. sc = HRESULT_FROM_WIN32(GetLastError());
  253. DebugTrace("IEcbBase::ScReqMapUrlToPathEx() - MultiByteToWideChar() failed 0x%08lX\n", sc);
  254. goto ret;
  255. }
  256. }
  257. else
  258. {
  259. pmi->cchMatchingURL = 0;
  260. }
  261. ret:
  262. return sc;
  263. }
  264. protected:
  265. // Declare the version constant
  266. //
  267. enum
  268. {
  269. IIS_VERSION_6_0 = 0x60000
  270. };
  271. // A POINTER to the original EXTENSION_CONTROL_BLOCK.
  272. // Using a reference would make it impossible for us
  273. // to tell if IIS ever requires that we use the
  274. // EXTENSION_CONTROL_BLOCK passed into async I/O
  275. // completion routines for subsequent I/O.
  276. //
  277. EXTENSION_CONTROL_BLOCK * m_pecb;
  278. IEcbBase( EXTENSION_CONTROL_BLOCK& ecb) :
  279. m_pecb(&ecb)
  280. {
  281. m_cRef = 1; //$HACK Until we have 1-based refcounting
  282. }
  283. public:
  284. virtual BOOL FSsl() const = 0;
  285. virtual BOOL FFrontEndSecured() const = 0;
  286. virtual BOOL FBrief() const = 0;
  287. virtual ULONG LcidAccepted() const = 0;
  288. virtual VOID SetLcidAccepted(LCID lcid) = 0;
  289. virtual LPCSTR LpszRequestUrl() const = 0;
  290. virtual LPCWSTR LpwszRequestUrl() const = 0;
  291. virtual UINT CchUrlPrefix( LPCSTR * ppszPrefix ) const = 0;
  292. virtual UINT CchUrlPrefixW( LPCWSTR * ppwszPrefix ) const = 0;
  293. virtual UINT CchGetServerName( LPCSTR * ppszServer ) const = 0;
  294. virtual UINT CchGetServerNameW( LPCWSTR * ppwszServer ) const = 0;
  295. virtual UINT CchGetVirtualRoot( LPCSTR * ppszVroot ) const = 0;
  296. virtual UINT CchGetVirtualRootW( LPCWSTR * ppwszVroot ) const = 0;
  297. virtual UINT CchGetMatchingPathW( LPCWSTR * ppwszMatching ) const = 0;
  298. virtual LPCWSTR LpwszPathTranslated() const = 0;
  299. virtual CInstData& InstData() const = 0;
  300. virtual BOOL FGetServerVariable( LPCSTR lpszName,
  301. LPSTR lpszValue,
  302. DWORD * pcbValue ) const = 0;
  303. virtual BOOL FGetServerVariable( LPCSTR lpszName,
  304. LPWSTR lpwszValue,
  305. DWORD * pcchValue ) const = 0;
  306. BOOL
  307. WriteClient( LPVOID lpvBuf,
  308. LPDWORD lpdwcbBuf,
  309. DWORD dwFlags ) const
  310. {
  311. Assert( m_pecb );
  312. return m_pecb->WriteClient( m_pecb->ConnID,
  313. lpvBuf,
  314. lpdwcbBuf,
  315. dwFlags );
  316. }
  317. BOOL
  318. ReadClient( LPVOID lpvBuf,
  319. LPDWORD lpdwcbBuf ) const
  320. {
  321. Assert( m_pecb );
  322. return m_pecb->ReadClient( m_pecb->ConnID,
  323. lpvBuf,
  324. lpdwcbBuf );
  325. }
  326. BOOL
  327. ServerSupportFunction( DWORD dwHSERequest,
  328. LPVOID lpvBuffer,
  329. LPDWORD lpdwSize,
  330. LPDWORD lpdwDataType ) const
  331. {
  332. Assert( m_pecb );
  333. return m_pecb->ServerSupportFunction( m_pecb->ConnID,
  334. dwHSERequest,
  335. lpvBuffer,
  336. lpdwSize,
  337. lpdwDataType );
  338. }
  339. SCODE
  340. ScReqMapUrlToPathEx( LPCWSTR pwszUrl,
  341. HSE_UNICODE_URL_MAPEX_INFO * pmi ) const
  342. {
  343. Assert (m_pecb);
  344. if ( m_pecb->dwVersion >= IIS_VERSION_6_0 )
  345. return ScReqMapUrlToPathEx60After( pwszUrl, pmi );
  346. return ScReqMapUrlToPathEx60Before( pwszUrl, pmi );
  347. }
  348. };
  349. class IEcb : public IEcbBase
  350. {
  351. // NOT IMPLEMENTED
  352. //
  353. IEcb( const IEcb& );
  354. IEcb& operator=( const IEcb& );
  355. protected:
  356. // CREATORS
  357. // Only create this object through it's descendents!
  358. //
  359. IEcb( EXTENSION_CONTROL_BLOCK& ecb ) :
  360. IEcbBase(ecb)
  361. {}
  362. ~IEcb();
  363. public:
  364. // ACCESSORS
  365. //
  366. LPCSTR
  367. LpszMethod() const
  368. {
  369. Assert( m_pecb );
  370. return m_pecb->lpszMethod;
  371. }
  372. LPCSTR
  373. LpszQueryString() const
  374. {
  375. Assert( m_pecb );
  376. return m_pecb->lpszQueryString;
  377. }
  378. DWORD
  379. CbTotalBytes() const
  380. {
  381. Assert( m_pecb );
  382. return m_pecb->cbTotalBytes;
  383. }
  384. DWORD
  385. CbAvailable() const
  386. {
  387. Assert( m_pecb );
  388. return m_pecb->cbAvailable;
  389. }
  390. const BYTE *
  391. LpbData() const
  392. {
  393. Assert( m_pecb );
  394. return m_pecb->lpbData;
  395. }
  396. virtual LPCWSTR LpwszMethod() const = 0;
  397. virtual UINT CbGetRawURL( LPCSTR * ppszRawURL ) const = 0;
  398. virtual LPCSTR LpszUrlPrefix() const = 0;
  399. virtual LPCWSTR LpwszUrlPrefix() const = 0;
  400. virtual UINT CchUrlPortW( LPCWSTR * ppwszPort ) const = 0;
  401. virtual HANDLE HitUser() const = 0;
  402. virtual BOOL FKeepAlive() const = 0;
  403. virtual BOOL FCanChunkResponse() const = 0;
  404. virtual BOOL FAuthenticated() const = 0;
  405. virtual BOOL FProcessingCEUrl() const = 0;
  406. virtual BOOL FIIS60OrAfter() const = 0;
  407. virtual LPCSTR LpszVersion() const = 0;
  408. virtual BOOL FSyncTransmitHeaders( const HSE_SEND_HEADER_EX_INFO& shei ) = 0;
  409. virtual SCODE ScAsyncRead( BYTE * pbBuf,
  410. UINT * pcbBuf,
  411. IIISAsyncIOCompleteObserver& obs ) = 0;
  412. virtual SCODE ScAsyncWrite( BYTE * pbBuf,
  413. DWORD dwcbBuf,
  414. IIISAsyncIOCompleteObserver& obs ) = 0;
  415. virtual SCODE ScAsyncTransmitFile( const HSE_TF_INFO& tfi,
  416. IIISAsyncIOCompleteObserver& obs ) = 0;
  417. virtual SCODE ScAsyncCustomError60After( const HSE_CUSTOM_ERROR_INFO& cei,
  418. LPSTR pszStatus ) = 0;
  419. virtual SCODE ScExecuteChild( LPCWSTR pwszURI, LPCSTR pszQueryString, BOOL fCustomErrorUrl ) = 0;
  420. virtual SCODE ScSendRedirect( LPCSTR lpszURI ) = 0;
  421. virtual IMDData& MetaData() const = 0;
  422. virtual LPCWSTR PwszMDPathVroot() const = 0;
  423. #ifdef DBG
  424. virtual void LogString( LPCSTR szLocation ) const = 0;
  425. #else
  426. void LogString( LPCSTR ) const {};
  427. #endif
  428. // MANIPULATORS
  429. //
  430. virtual VOID SendAsyncErrorResponse( DWORD dwStatusCode,
  431. LPCSTR pszBody,
  432. DWORD cchzBody,
  433. LPCSTR pszStatusDescription,
  434. DWORD cchzStatusDescription ) = 0;
  435. virtual DWORD HSEHandleException() = 0;
  436. // To be used ONLY by request/response.
  437. //
  438. virtual void SetStatusCode( UINT iStatusCode ) = 0;
  439. virtual void SetConnectionHeader( LPCWSTR pwszValue ) = 0;
  440. virtual void SetAcceptLanguageHeader( LPCSTR pszValue ) = 0;
  441. virtual void CloseConnection() = 0;
  442. };
  443. IEcb * NewEcb( EXTENSION_CONTROL_BLOCK& ecb,
  444. BOOL fUseRawUrlMappings,
  445. DWORD * pdwHSEStatusRet );
  446. #ifdef DBG
  447. void InitECBLogging();
  448. void DeinitECBLogging();
  449. #endif
  450. //
  451. // Routines to manipulate metadata (metabase) paths
  452. //
  453. ULONG CbMDPathW( const IEcb& ecb, LPCWSTR pwszURI );
  454. VOID MDPathFromURIW( const IEcb& ecb, LPCWSTR pwszURI, LPWSTR pwszMDPath );
  455. #endif // !defined(_ECB_H_)