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.

1076 lines
34 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. Component: CIsapiReqInfo implementation....
  6. File: IsapiReq.cpp
  7. Owner: AndyMorr
  8. ===================================================================*/
  9. #include "denpre.h"
  10. #pragma hdrstop
  11. // undef these here so that we can call the WXI and ECB functions with
  12. // the same name and not be victims of the substituition.
  13. #undef MapUrlToPath
  14. #undef GetCustomError
  15. #undef GetAspMDData
  16. #undef GetAspMDAllData
  17. #undef GetServerVariable
  18. VOID AspDoRevertHack( HANDLE * phToken );
  19. VOID AspUndoRevertHack( HANDLE * phToken );
  20. /*===================================================================
  21. CIsapiReqInfo::QueryPszQueryString
  22. ===================================================================*/
  23. LPSTR CIsapiReqInfo::QueryPszQueryString()
  24. {
  25. return m_pECB->lpszQueryString;
  26. }
  27. /*===================================================================
  28. CIsapiReqInfo::QueryCchQueryString
  29. ===================================================================*/
  30. DWORD CIsapiReqInfo::QueryCchQueryString()
  31. {
  32. if (m_cchQueryString == -1) {
  33. m_cchQueryString = QueryPszQueryString() ? strlen(QueryPszQueryString()) : 0;
  34. }
  35. return m_cchQueryString;
  36. }
  37. /*===================================================================
  38. CIsapiReqInfo::QueryPszApplnMDPathA
  39. ===================================================================*/
  40. LPSTR CIsapiReqInfo::QueryPszApplnMDPathA()
  41. {
  42. if (m_fApplnMDPathAInited == FALSE) {
  43. *((LPSTR)m_ApplnMDPathA.QueryPtr()) = '\0';
  44. m_fApplnMDPathAInited = InternalGetServerVariable("APPL_MD_PATH", &m_ApplnMDPathA);
  45. }
  46. ASSERT(m_fApplnMDPathAInited);
  47. return (LPSTR)m_ApplnMDPathA.QueryPtr();
  48. }
  49. /*===================================================================
  50. CIsapiReqInfo::QueryCchApplnMDPathA
  51. ===================================================================*/
  52. DWORD CIsapiReqInfo::QueryCchApplnMDPathA()
  53. {
  54. if (m_cchApplnMDPathA == -1) {
  55. m_cchApplnMDPathA = QueryPszApplnMDPathA()
  56. ? strlen(QueryPszApplnMDPathA())
  57. : 0;
  58. }
  59. return(m_cchApplnMDPathA);
  60. }
  61. /*===================================================================
  62. CIsapiReqInfo::QueryPszApplnMDPathW
  63. ===================================================================*/
  64. LPWSTR CIsapiReqInfo::QueryPszApplnMDPathW()
  65. {
  66. if (m_fApplnMDPathWInited == FALSE) {
  67. *((LPWSTR)m_ApplnMDPathW.QueryPtr()) = L'\0';
  68. m_fApplnMDPathWInited = InternalGetServerVariable("UNICODE_APPL_MD_PATH", &m_ApplnMDPathW);
  69. }
  70. ASSERT(m_fApplnMDPathWInited);
  71. return (LPWSTR)m_ApplnMDPathW.QueryPtr();
  72. }
  73. /*===================================================================
  74. CIsapiReqInfo::QueryCchApplnMDPathW
  75. ===================================================================*/
  76. DWORD CIsapiReqInfo::QueryCchApplnMDPathW()
  77. {
  78. if (m_cchApplnMDPathW == -1) {
  79. m_cchApplnMDPathW = QueryPszApplnMDPathW()
  80. ? wcslen(QueryPszApplnMDPathW())
  81. : 0;
  82. }
  83. return(m_cchApplnMDPathW);
  84. }
  85. /*===================================================================
  86. CIsapiReqInfo::QueryPszPathInfoA
  87. ===================================================================*/
  88. LPSTR CIsapiReqInfo::QueryPszPathInfoA()
  89. {
  90. return m_pECB->lpszPathInfo;
  91. }
  92. /*===================================================================
  93. CIsapiReqInfo::QueryCchPathInfoA
  94. ===================================================================*/
  95. DWORD CIsapiReqInfo::QueryCchPathInfoA()
  96. {
  97. if (m_cchPathInfoA == -1) {
  98. m_cchPathInfoA = QueryPszPathInfoA()
  99. ? strlen(QueryPszPathInfoA())
  100. : 0;
  101. }
  102. return m_cchPathInfoA;
  103. }
  104. /*===================================================================
  105. CIsapiReqInfo::QueryPszPathInfoW
  106. ===================================================================*/
  107. LPWSTR CIsapiReqInfo::QueryPszPathInfoW()
  108. {
  109. if (m_fPathInfoWInited == FALSE) {
  110. *((LPWSTR)m_PathInfoW.QueryPtr()) = L'\0';
  111. m_fPathInfoWInited = InternalGetServerVariable("UNICODE_PATH_INFO", &m_PathInfoW);
  112. }
  113. ASSERT(m_fPathInfoWInited);
  114. return (LPWSTR)m_PathInfoW.QueryPtr();
  115. }
  116. /*===================================================================
  117. CIsapiReqInfo::QueryCchPathInfoW
  118. ===================================================================*/
  119. DWORD CIsapiReqInfo::QueryCchPathInfoW()
  120. {
  121. if (m_cchPathInfoW == -1) {
  122. m_cchPathInfoW = QueryPszPathInfoW()
  123. ? wcslen(QueryPszPathInfoW())
  124. : 0;
  125. }
  126. return m_cchPathInfoW;
  127. }
  128. /*===================================================================
  129. CIsapiReqInfo::QueryPszPathTranslatedA
  130. ===================================================================*/
  131. LPSTR CIsapiReqInfo::QueryPszPathTranslatedA()
  132. {
  133. return m_pECB->lpszPathTranslated;
  134. }
  135. /*===================================================================
  136. CIsapiReqInfo::QueryCchPathTranslatedA
  137. ===================================================================*/
  138. DWORD CIsapiReqInfo::QueryCchPathTranslatedA()
  139. {
  140. if (m_cchPathTranslatedA == -1) {
  141. m_cchPathTranslatedA = QueryPszPathTranslatedA()
  142. ? strlen(QueryPszPathTranslatedA())
  143. : 0;
  144. }
  145. return m_cchPathTranslatedA;
  146. }
  147. /*===================================================================
  148. CIsapiReqInfo::QueryPszPathTranslatedW
  149. ===================================================================*/
  150. LPWSTR CIsapiReqInfo::QueryPszPathTranslatedW()
  151. {
  152. if (m_fPathTranslatedWInited == FALSE) {
  153. *((LPWSTR)m_PathTranslatedW.QueryPtr()) = L'\0';
  154. m_fPathTranslatedWInited = InternalGetServerVariable("UNICODE_PATH_TRANSLATED", &m_PathTranslatedW);
  155. }
  156. ASSERT(m_fPathTranslatedWInited);
  157. return (LPWSTR)m_PathTranslatedW.QueryPtr();
  158. }
  159. /*===================================================================
  160. CIsapiReqInfo::QueryCchPathTranslatedW
  161. ===================================================================*/
  162. DWORD CIsapiReqInfo::QueryCchPathTranslatedW()
  163. {
  164. if (m_cchPathTranslatedW == -1) {
  165. m_cchPathTranslatedW = QueryPszPathTranslatedW()
  166. ? wcslen(QueryPszPathTranslatedW())
  167. : 0;
  168. }
  169. return m_cchPathTranslatedW;
  170. }
  171. /*===================================================================
  172. CIsapiReqInfo::QueryPszCookie
  173. ===================================================================*/
  174. LPSTR CIsapiReqInfo::QueryPszCookie()
  175. {
  176. if (m_fCookieInited == FALSE) {
  177. *((LPSTR)m_Cookie.QueryPtr()) = '\0';
  178. InternalGetServerVariable("HTTP_COOKIE", &m_Cookie);
  179. m_fCookieInited = TRUE;
  180. }
  181. return (LPSTR)m_Cookie.QueryPtr();
  182. }
  183. /*===================================================================
  184. CIsapiReqInfo::SetDwHttpStatusCode
  185. ===================================================================*/
  186. VOID CIsapiReqInfo::SetDwHttpStatusCode(DWORD dwStatus)
  187. {
  188. m_pECB->dwHttpStatusCode = dwStatus;
  189. }
  190. /*===================================================================
  191. CIsapiReqInfo::QueryPbData
  192. ===================================================================*/
  193. LPBYTE CIsapiReqInfo::QueryPbData()
  194. {
  195. return m_pECB->lpbData;
  196. }
  197. /*===================================================================
  198. CIsapiReqInfo::QueryCbAvailable
  199. ===================================================================*/
  200. DWORD CIsapiReqInfo::QueryCbAvailable()
  201. {
  202. return m_pECB->cbAvailable;
  203. }
  204. /*===================================================================
  205. CIsapiReqInfo::QueryCbTotalBytes
  206. ===================================================================*/
  207. DWORD CIsapiReqInfo::QueryCbTotalBytes()
  208. {
  209. return m_pECB->cbTotalBytes;
  210. }
  211. /*===================================================================
  212. CIsapiReqInfo::QueryPszContentType
  213. ===================================================================*/
  214. LPSTR CIsapiReqInfo::QueryPszContentType()
  215. {
  216. return m_pECB->lpszContentType;
  217. }
  218. /*===================================================================
  219. CIsapiReqInfo::QueryPszMethod
  220. ===================================================================*/
  221. LPSTR CIsapiReqInfo::QueryPszMethod()
  222. {
  223. return m_pECB->lpszMethod;
  224. }
  225. /*===================================================================
  226. CIsapiReqInfo::QueryPszUserAgent
  227. ===================================================================*/
  228. LPSTR CIsapiReqInfo::QueryPszUserAgent()
  229. {
  230. if (m_fUserAgentInited == FALSE) {
  231. *((LPSTR)m_UserAgent.QueryPtr()) = '\0';
  232. InternalGetServerVariable("HTTP_USER_AGENT", &m_UserAgent);
  233. }
  234. return (LPSTR)m_UserAgent.QueryPtr();
  235. }
  236. /*===================================================================
  237. CIsapiReqInfo::QueryInstanceId
  238. ===================================================================*/
  239. DWORD CIsapiReqInfo::QueryInstanceId()
  240. {
  241. if (m_fInstanceIDInited == FALSE) {
  242. BUFFER instanceID;
  243. m_fInstanceIDInited = InternalGetServerVariable("INSTANCE_ID", &instanceID);
  244. if (m_fInstanceIDInited == TRUE) {
  245. m_dwInstanceID = atoi((char *)instanceID.QueryPtr());
  246. }
  247. else {
  248. m_dwInstanceID = 1;
  249. }
  250. }
  251. return m_dwInstanceID;
  252. }
  253. /*===================================================================
  254. CIsapiReqInfo::IsChild
  255. ===================================================================*/
  256. BOOL CIsapiReqInfo::IsChild()
  257. {
  258. #if _IIS_5_1
  259. return m_pWXI->IsChild();
  260. #else
  261. // BUGBUG: This needs to be implemented
  262. #endif
  263. return FALSE;
  264. }
  265. /*===================================================================
  266. CIsapiReqInfo::FInPool
  267. ===================================================================*/
  268. BOOL CIsapiReqInfo::FInPool()
  269. {
  270. #if _IIS_5_1
  271. return m_pWXI->FInPool();
  272. #else
  273. DWORD dwAppFlag;
  274. if (ServerSupportFunction(HSE_REQ_IS_IN_PROCESS,
  275. &dwAppFlag,
  276. NULL,
  277. NULL) == FALSE) {
  278. // BUGBUG: Need to enable this Assert in future builds.
  279. //Assert(0);
  280. // if error, the best we can do is return TRUE here so
  281. // that ASP picks up its settings from the service level
  282. return TRUE;
  283. }
  284. return !(dwAppFlag == HSE_APP_FLAG_ISOLATED_OOP);
  285. #endif
  286. }
  287. /*===================================================================
  288. CIsapiReqInfo::QueryHttpVersionMajor
  289. ===================================================================*/
  290. DWORD CIsapiReqInfo::QueryHttpVersionMajor()
  291. {
  292. InitVersionInfo();
  293. return m_dwVersionMajor;
  294. }
  295. /*===================================================================
  296. CIsapiReqInfo::QueryHttpVersionMinor
  297. ===================================================================*/
  298. DWORD CIsapiReqInfo::QueryHttpVersionMinor()
  299. {
  300. InitVersionInfo();
  301. return m_dwVersionMinor;
  302. }
  303. /*===================================================================
  304. CIsapiReqInfo::ISAThreadNotify
  305. ===================================================================*/
  306. HRESULT CIsapiReqInfo::ISAThreadNotify(BOOL fStart)
  307. {
  308. #if _IIS_5_1
  309. return m_pWXI->ISAThreadNotify(fStart);
  310. #else
  311. //BUGBUG: Obsolete?
  312. return S_OK;
  313. #endif
  314. }
  315. /*===================================================================
  316. CIsapiReqInfo::GetAspMDData
  317. ===================================================================*/
  318. HRESULT CIsapiReqInfo::GetAspMDDataA(CHAR * pszMDPath,
  319. DWORD dwMDIdentifier,
  320. DWORD dwMDAttributes,
  321. DWORD dwMDUserType,
  322. DWORD dwMDDataType,
  323. DWORD dwMDDataLen,
  324. DWORD dwMDDataTag,
  325. unsigned char * pbMDData,
  326. DWORD * pdwRequiredBufferSize)
  327. {
  328. #if _IIS_5_1
  329. return m_pWXI->GetAspMDData((UCHAR *)pszMDPath,
  330. dwMDIdentifier,
  331. dwMDAttributes,
  332. dwMDUserType,
  333. dwMDDataType,
  334. dwMDDataLen,
  335. dwMDDataTag,
  336. pbMDData,
  337. pdwRequiredBufferSize);
  338. #else
  339. return E_NOTIMPL;
  340. #endif
  341. }
  342. /*===================================================================
  343. CIsapiReqInfo::GetAspMDData
  344. ===================================================================*/
  345. HRESULT CIsapiReqInfo::GetAspMDDataW(WCHAR * pszMDPath,
  346. DWORD dwMDIdentifier,
  347. DWORD dwMDAttributes,
  348. DWORD dwMDUserType,
  349. DWORD dwMDDataType,
  350. DWORD dwMDDataLen,
  351. DWORD dwMDDataTag,
  352. unsigned char * pbMDData,
  353. DWORD * pdwRequiredBufferSize)
  354. {
  355. IMSAdminBase *pMetabase;
  356. METADATA_HANDLE hKey = NULL;
  357. METADATA_RECORD MetadataRecord;
  358. DWORD dwTimeout = 2000;
  359. HRESULT hr;
  360. HANDLE hCurrentUser = INVALID_HANDLE_VALUE;
  361. AspDoRevertHack( &hCurrentUser );
  362. pMetabase = GetMetabaseIF();
  363. ASSERT(pMetabase);
  364. hr = pMetabase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  365. pszMDPath,
  366. METADATA_PERMISSION_READ,
  367. dwTimeout,
  368. &hKey
  369. );
  370. ASSERT(SUCCEEDED(hr));
  371. if( SUCCEEDED(hr) )
  372. {
  373. MetadataRecord.dwMDIdentifier = dwMDIdentifier;
  374. MetadataRecord.dwMDAttributes = dwMDAttributes;
  375. MetadataRecord.dwMDUserType = dwMDUserType;
  376. MetadataRecord.dwMDDataType = dwMDDataType;
  377. MetadataRecord.dwMDDataLen = dwMDDataLen;
  378. MetadataRecord.pbMDData = pbMDData;
  379. MetadataRecord.dwMDDataTag = dwMDDataTag;
  380. hr = pMetabase->GetData( hKey,
  381. L"",
  382. &MetadataRecord,
  383. pdwRequiredBufferSize);
  384. ASSERT(SUCCEEDED(hr));
  385. pMetabase->CloseKey( hKey );
  386. }
  387. AspUndoRevertHack( &hCurrentUser );
  388. return hr;
  389. }
  390. /*===================================================================
  391. CIsapiReqInfo::GetAspMDAllData
  392. ===================================================================*/
  393. HRESULT CIsapiReqInfo::GetAspMDAllDataA(LPSTR pszMDPath,
  394. DWORD dwMDUserType,
  395. DWORD dwDefaultBufferSize,
  396. LPVOID pvBuffer,
  397. DWORD * pdwRequiredBufferSize,
  398. DWORD * pdwNumDataEntries)
  399. {
  400. #if _IIS_5_1
  401. return m_pWXI->GetAspMDAllData(pszMDPath,
  402. dwMDUserType,
  403. dwDefaultBufferSize,
  404. pvBuffer,
  405. pdwRequiredBufferSize,
  406. pdwNumDataEntries);
  407. #else
  408. return E_NOTIMPL;
  409. #endif
  410. }
  411. /*===================================================================
  412. CIsapiReqInfo::GetAspMDAllData
  413. ===================================================================*/
  414. HRESULT CIsapiReqInfo::GetAspMDAllDataW(LPWSTR pwszMDPath,
  415. DWORD dwMDUserType,
  416. DWORD dwDefaultBufferSize,
  417. LPVOID pvBuffer,
  418. DWORD * pdwRequiredBufferSize,
  419. DWORD * pdwNumDataEntries)
  420. {
  421. HRESULT hr = S_OK;
  422. IMSAdminBase *pMetabase;
  423. METADATA_HANDLE hKey = NULL;
  424. DWORD dwTimeout = 2000;
  425. DWORD dwDataSet;
  426. HANDLE hCurrentUser = INVALID_HANDLE_VALUE;
  427. AspDoRevertHack( &hCurrentUser );
  428. //
  429. // Wide-ize the metabase path
  430. //
  431. pMetabase = GetMetabaseIF();
  432. ASSERT(pMetabase);
  433. hr = pMetabase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  434. pwszMDPath,
  435. METADATA_PERMISSION_READ,
  436. dwTimeout,
  437. &hKey);
  438. if( SUCCEEDED(hr) ) {
  439. hr = pMetabase->GetAllData( hKey,
  440. L"",
  441. METADATA_INHERIT,
  442. dwMDUserType,
  443. ALL_METADATA,
  444. pdwNumDataEntries,
  445. &dwDataSet,
  446. dwDefaultBufferSize,
  447. (UCHAR *)pvBuffer,
  448. pdwRequiredBufferSize);
  449. ASSERT(SUCCEEDED(hr));
  450. pMetabase->CloseKey( hKey );
  451. }
  452. AspUndoRevertHack( &hCurrentUser );
  453. return hr;
  454. }
  455. /*===================================================================
  456. CIsapiReqInfo::GetCustomErrorA
  457. ===================================================================*/
  458. BOOL CIsapiReqInfo::GetCustomErrorA(DWORD dwError,
  459. DWORD dwSubError,
  460. DWORD dwBufferSize,
  461. CHAR *pvBuffer,
  462. DWORD *pdwRequiredBufferSize,
  463. BOOL *pfIsFileError)
  464. {
  465. #if _IIS_5_1
  466. return m_pWXI->GetCustomError(dwError,
  467. dwSubError,
  468. dwBufferSize,
  469. pvBuffer,
  470. pdwRequiredBufferSize,
  471. pfIsFileError);
  472. #else
  473. return E_NOTIMPL;
  474. #endif
  475. }
  476. /*===================================================================
  477. CIsapiReqInfo::GetCustomErrorW
  478. ===================================================================*/
  479. BOOL CIsapiReqInfo::GetCustomErrorW(DWORD dwError,
  480. DWORD dwSubError,
  481. DWORD dwBufferSize,
  482. WCHAR *pvBuffer,
  483. DWORD *pdwRequiredBufferSize,
  484. BOOL *pfIsFileError)
  485. {
  486. #if _IIS_5_1
  487. SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
  488. return FALSE;
  489. #else
  490. BOOL fRet;
  491. HSE_CUSTOM_ERROR_PAGE_INFO cei;
  492. STACK_BUFFER(ansiBuf, 1024);
  493. cei.dwError = dwError;
  494. cei.dwSubError = dwSubError;
  495. cei.dwBufferSize = ansiBuf.QuerySize();
  496. cei.pBuffer = (CHAR *)ansiBuf.QueryPtr();
  497. cei.pdwBufferRequired = pdwRequiredBufferSize;
  498. cei.pfIsFileError = pfIsFileError;
  499. fRet = ServerSupportFunction(HSE_REQ_GET_CUSTOM_ERROR_PAGE,
  500. &cei,
  501. NULL,
  502. NULL);
  503. if (!fRet) {
  504. DWORD dwErr = GetLastError();
  505. if (dwErr == ERROR_INSUFFICIENT_BUFFER) {
  506. if (ansiBuf.Resize(*pdwRequiredBufferSize) == FALSE) {
  507. SetLastError(ERROR_OUTOFMEMORY);
  508. return FALSE;
  509. }
  510. cei.dwBufferSize = ansiBuf.QuerySize();
  511. cei.pBuffer = (CHAR *)ansiBuf.QueryPtr();
  512. fRet = ServerSupportFunction(HSE_REQ_GET_CUSTOM_ERROR_PAGE,
  513. &cei,
  514. NULL,
  515. NULL);
  516. }
  517. if (!fRet) {
  518. SetLastError(ERROR_OUTOFMEMORY);
  519. return FALSE;
  520. }
  521. }
  522. CMBCSToWChar convError;
  523. if (FAILED(convError.Init((LPCSTR)ansiBuf.QueryPtr()))) {
  524. SetLastError(ERROR_OUTOFMEMORY);
  525. return FALSE;
  526. }
  527. *pdwRequiredBufferSize = (convError.GetStringLen()+1)*sizeof(WCHAR);
  528. if (*pdwRequiredBufferSize > dwBufferSize) {
  529. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  530. return FALSE;
  531. }
  532. memcpy(pvBuffer, convError.GetString(), *pdwRequiredBufferSize);
  533. if (*pfIsFileError) {
  534. CMBCSToWChar convMime;
  535. DWORD fileNameLen = *pdwRequiredBufferSize;
  536. if (FAILED(convMime.Init((LPCSTR)ansiBuf.QueryPtr()+strlen((LPCSTR)ansiBuf.QueryPtr())+1))) {
  537. SetLastError(ERROR_OUTOFMEMORY);
  538. return FALSE;
  539. }
  540. *pdwRequiredBufferSize += (convMime.GetStringLen()+1)*sizeof(WCHAR);
  541. if (*pdwRequiredBufferSize > dwBufferSize) {
  542. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  543. return FALSE;
  544. }
  545. memcpy(&((BYTE *)pvBuffer)[fileNameLen], convMime.GetString(), (convMime.GetStringLen()+1)*sizeof(WCHAR));
  546. }
  547. return TRUE;
  548. #endif // _IIS_5_1
  549. }
  550. /*===================================================================
  551. CIsapiReqInfo::QueryImpersonationToken
  552. ===================================================================*/
  553. HANDLE CIsapiReqInfo::QueryImpersonationToken()
  554. {
  555. HANDLE hToken = INVALID_HANDLE_VALUE;
  556. ServerSupportFunction(HSE_REQ_GET_IMPERSONATION_TOKEN,
  557. &hToken,
  558. NULL,
  559. NULL);
  560. return hToken;
  561. }
  562. /*===================================================================
  563. CIsapiReqInfo::AppendLogParameter
  564. ===================================================================*/
  565. HRESULT CIsapiReqInfo::AppendLogParameter(LPSTR extraParam)
  566. {
  567. if (ServerSupportFunction(HSE_APPEND_LOG_PARAMETER,
  568. extraParam,
  569. NULL,
  570. NULL) == FALSE) {
  571. return HRESULT_FROM_WIN32(GetLastError());
  572. }
  573. return S_OK;
  574. }
  575. /*===================================================================
  576. CIsapiReqInfo::SendHeader
  577. ===================================================================*/
  578. BOOL CIsapiReqInfo::SendHeader(LPVOID pvStatus,
  579. DWORD cchStatus,
  580. LPVOID pvHeader,
  581. DWORD cchHeader,
  582. BOOL fIsaKeepConn)
  583. {
  584. HSE_SEND_HEADER_EX_INFO HeaderInfo;
  585. HeaderInfo.pszStatus = (LPCSTR)pvStatus;
  586. HeaderInfo.cchStatus = cchStatus;
  587. HeaderInfo.pszHeader = (LPCSTR) pvHeader;
  588. HeaderInfo.cchHeader = cchHeader;
  589. HeaderInfo.fKeepConn = fIsaKeepConn;
  590. return ServerSupportFunction( HSE_REQ_SEND_RESPONSE_HEADER_EX,
  591. &HeaderInfo,
  592. NULL,
  593. NULL );
  594. }
  595. /*===================================================================
  596. CIsapiReqInfo::GetServerVariableA
  597. ===================================================================*/
  598. BOOL CIsapiReqInfo::GetServerVariableA(LPSTR szVarName,
  599. LPSTR pBuffer,
  600. LPDWORD pdwSize )
  601. {
  602. return m_pECB->GetServerVariable( (HCONN)m_pECB->ConnID,
  603. szVarName,
  604. pBuffer,
  605. pdwSize );
  606. }
  607. /*===================================================================
  608. CIsapiReqInfo::GetServerVariableW
  609. ===================================================================*/
  610. BOOL CIsapiReqInfo::GetServerVariableW(LPSTR szVarName,
  611. LPWSTR pBuffer,
  612. LPDWORD pdwSize )
  613. {
  614. return m_pECB->GetServerVariable( (HCONN)m_pECB->ConnID,
  615. szVarName,
  616. pBuffer,
  617. pdwSize );
  618. }
  619. /*===================================================================
  620. CIsapiReqInfo::ServerSupportFunction
  621. ===================================================================*/
  622. BOOL CIsapiReqInfo::ServerSupportFunction(DWORD dwHSERequest,
  623. LPVOID pvData,
  624. LPDWORD pdwSize,
  625. LPDWORD pdwDataType)
  626. {
  627. return m_pECB->ServerSupportFunction( (HCONN)m_pECB->ConnID,
  628. dwHSERequest,
  629. pvData,
  630. pdwSize,
  631. pdwDataType );
  632. }
  633. /*===================================================================
  634. CIsapiReqInfo::SendEntireResponseOop
  635. ===================================================================*/
  636. BOOL CIsapiReqInfo::SendEntireResponseOop(IN HSE_SEND_ENTIRE_RESPONSE_INFO * pHseResponseInfo)
  637. {
  638. #if _IIS_5_1
  639. return m_pWXI->SendEntireResponseOop(pHseResponseInfo);
  640. #elif _IIS_6_0
  641. return SendEntireResponse(pHseResponseInfo);
  642. #else
  643. #error "Neither _IIS_5_1 nor _IIS_6_0 is defined"
  644. #endif
  645. }
  646. /*===================================================================
  647. CIsapiReqInfo::SendEntireResponse
  648. ===================================================================*/
  649. BOOL CIsapiReqInfo::SendEntireResponse(IN HSE_SEND_ENTIRE_RESPONSE_INFO * pResponseInfo)
  650. {
  651. #if _IIS_5_1
  652. return m_pWXI->SendEntireResponse(pResponseInfo);
  653. #elif _IIS_6_0
  654. HRESULT hr = S_OK;
  655. DWORD nElementCount;
  656. HSE_VECTOR_ELEMENT *pVectorElement = NULL;
  657. HSE_RESPONSE_VECTOR respVector;
  658. HANDLE hCurrentUser = INVALID_HANDLE_VALUE;
  659. BOOL fKeepConn;
  660. STACK_BUFFER ( buffResp, 512);
  661. //
  662. // Set the keep connection flag. It can only be TRUE if the
  663. // ISAPI and the client both want keep alive.
  664. //
  665. fKeepConn = FKeepConn() && pResponseInfo->HeaderInfo.fKeepConn;
  666. //
  667. // Munge the input structure into something that IIsapiCore can
  668. // understand. Note that ASP sets the number of buffer to be one more
  669. // than actual and the first buffer is not valid
  670. //
  671. nElementCount = pResponseInfo->cWsaBuf - 1;
  672. if (!buffResp.Resize(nElementCount * sizeof(HSE_VECTOR_ELEMENT)))
  673. {
  674. hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  675. goto Exit;
  676. }
  677. ZeroMemory(buffResp.QueryPtr(),
  678. nElementCount * sizeof(HSE_VECTOR_ELEMENT));
  679. pVectorElement = (HSE_VECTOR_ELEMENT *)buffResp.QueryPtr();
  680. for (DWORD i = 0; i < nElementCount; i++)
  681. {
  682. pVectorElement[i].pBuffer = (LPBYTE)pResponseInfo->rgWsaBuf[i+1].buf;
  683. pVectorElement[i].cbSize = pResponseInfo->rgWsaBuf[i+1].len;
  684. }
  685. respVector.dwFlags = HSE_IO_SYNC
  686. | (!fKeepConn ? HSE_IO_DISCONNECT_AFTER_SEND : 0)
  687. | HSE_IO_SEND_HEADERS;
  688. respVector.pszStatus = (LPSTR)pResponseInfo->HeaderInfo.pszStatus;
  689. respVector.pszHeaders = (LPSTR)pResponseInfo->HeaderInfo.pszHeader;
  690. respVector.nElementCount = nElementCount;
  691. respVector.lpElementArray = pVectorElement;
  692. //
  693. // Send it
  694. //
  695. if (ServerSupportFunction(HSE_REQ_VECTOR_SEND,
  696. &respVector,
  697. NULL,
  698. NULL) == FALSE) {
  699. hr = HRESULT_FROM_WIN32(GetLastError());
  700. }
  701. Exit:
  702. if (FAILED(hr))
  703. {
  704. SetLastError((HRESULT_FACILITY(hr) == (HRESULT)FACILITY_WIN32)
  705. ? HRESULT_CODE(hr)
  706. : ERROR_INVALID_PARAMETER);
  707. return FALSE;
  708. }
  709. return TRUE;
  710. #else
  711. #error "Neither _IIS_5_1 nor _IIS_6_0 is defined"
  712. #endif
  713. }
  714. /*===================================================================
  715. CIsapiReqInfo::TestConnection
  716. ===================================================================*/
  717. BOOL CIsapiReqInfo::TestConnection(BOOL *pfIsConnected)
  718. {
  719. BOOL bRet = TRUE;
  720. ServerSupportFunction(HSE_REQ_IS_CONNECTED,
  721. &bRet,
  722. NULL,
  723. NULL);
  724. return bRet;
  725. }
  726. /*===================================================================
  727. CIsapiReqInfo::MapUrlToPathA
  728. ===================================================================*/
  729. BOOL CIsapiReqInfo::MapUrlToPathA(LPSTR pBuffer, LPDWORD pdwBytes)
  730. {
  731. return ServerSupportFunction( HSE_REQ_MAP_URL_TO_PATH,
  732. pBuffer,
  733. pdwBytes,
  734. NULL );
  735. }
  736. /*===================================================================
  737. CIsapiReqInfo::MapUrlToPathW
  738. ===================================================================*/
  739. BOOL CIsapiReqInfo::MapUrlToPathW(LPWSTR pBuffer, LPDWORD pdwBytes)
  740. {
  741. return ServerSupportFunction( HSE_REQ_MAP_UNICODE_URL_TO_PATH,
  742. pBuffer,
  743. pdwBytes,
  744. NULL );
  745. }
  746. /*===================================================================
  747. CIsapiReqInfo::SyncReadClient
  748. ===================================================================*/
  749. BOOL CIsapiReqInfo::SyncReadClient(LPVOID pvBuffer, LPDWORD pdwBytes )
  750. {
  751. return m_pECB->ReadClient(m_pECB->ConnID, pvBuffer, pdwBytes);
  752. }
  753. /*===================================================================
  754. CIsapiReqInfo::SyncWriteClient
  755. ===================================================================*/
  756. BOOL CIsapiReqInfo::SyncWriteClient(LPVOID pvBuffer, LPDWORD pdwBytes)
  757. {
  758. return m_pECB->WriteClient(m_pECB->ConnID, pvBuffer, pdwBytes, HSE_IO_SYNC);
  759. }
  760. /*********************************************************************
  761. PRIVATE FUNCTIONS
  762. *********************************************************************/
  763. /*===================================================================
  764. CIsapiReqInfo::InitVersionInfo
  765. ===================================================================*/
  766. void CIsapiReqInfo::InitVersionInfo()
  767. {
  768. if (m_fVersionInited == FALSE) {
  769. BUFFER version;
  770. m_fVersionInited = TRUE;
  771. m_dwVersionMajor = 1;
  772. m_dwVersionMinor = 0;
  773. if (InternalGetServerVariable("SERVER_PROTOCOL", &version)) {
  774. char *pVersionStr = (char *)version.QueryPtr();
  775. if ((strlen(pVersionStr) >= 8)
  776. && (isdigit((UCHAR)pVersionStr[5]))
  777. && (isdigit((UCHAR)pVersionStr[7]))) {
  778. m_dwVersionMajor = pVersionStr[5] - '0';
  779. m_dwVersionMinor = pVersionStr[7] - '0';
  780. }
  781. }
  782. }
  783. }
  784. /*===================================================================
  785. CIsapiReqInfo::InternalGetServerVariable
  786. ===================================================================*/
  787. BOOL CIsapiReqInfo::InternalGetServerVariable(LPSTR pszVarName, BUFFER *pBuf)
  788. {
  789. BOOL bRet;
  790. DWORD dwRequiredBufSize = pBuf->QuerySize();
  791. bRet = m_pECB->GetServerVariable(m_pECB->ConnID,
  792. pszVarName,
  793. pBuf->QueryPtr(),
  794. &dwRequiredBufSize);
  795. if ((bRet == FALSE) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  796. if (!pBuf->Resize(dwRequiredBufSize)) {
  797. SetLastError(ERROR_OUTOFMEMORY);
  798. return FALSE;
  799. }
  800. bRet = m_pECB->GetServerVariable(m_pECB->ConnID,
  801. pszVarName,
  802. pBuf->QueryPtr(),
  803. &dwRequiredBufSize);
  804. }
  805. return(bRet);
  806. }
  807. /*===================================================================
  808. CIsapiReqInfo::FKeepConn
  809. ===================================================================*/
  810. BOOL CIsapiReqInfo::FKeepConn()
  811. {
  812. if (m_fFKeepConnInited == FALSE) {
  813. m_fFKeepConnInited = TRUE;
  814. m_fKeepConn = FALSE;
  815. InitVersionInfo();
  816. if (m_dwVersionMajor == 1) {
  817. if (m_dwVersionMinor == 1) {
  818. m_fKeepConn = TRUE;
  819. }
  820. BUFFER connectStr;
  821. if (InternalGetServerVariable("HTTP_CONNECTION", &connectStr)) {
  822. if (m_dwVersionMinor == 0) {
  823. m_fKeepConn = !(_stricmp((char *)connectStr.QueryPtr(), "keep-alive"));
  824. }
  825. else if (m_dwVersionMinor == 1) {
  826. m_fKeepConn = !!(_stricmp((char *)connectStr.QueryPtr(), "close"));
  827. }
  828. }
  829. }
  830. }
  831. return m_fKeepConn;
  832. }
  833. /*===================================================================
  834. CIsapiReqInfo::GetMetabaseIF
  835. ===================================================================*/
  836. IMSAdminBase *CIsapiReqInfo::GetMetabaseIF()
  837. {
  838. if (m_pIAdminBase == NULL) {
  839. HRESULT hr = CoCreateInstance(CLSID_MSAdminBase,
  840. NULL,
  841. CLSCTX_ALL,
  842. IID_IMSAdminBase,
  843. (void**)&m_pIAdminBase);
  844. ASSERT(SUCCEEDED(hr));
  845. }
  846. return m_pIAdminBase;
  847. }
  848. //
  849. // Lifted directly from IIS 5.x...
  850. //
  851. // (Un)DoRevertHack
  852. //
  853. // To prevent RPC token cache from growing without limit (and aging), we
  854. // need to revert to self before calling back to inetinfo.exe.
  855. //
  856. // Now there is a new need to do this. As it turns out the performance
  857. // hit we take from RPC caching these tokens is very significant.
  858. // Ultimately we might want to implement a caching scheme ourselves so
  859. // that the token we use is always the same for the same user identity,
  860. // but that is a big change and this (although ugly as hell) works
  861. // and has been tested for months.
  862. //
  863. VOID AspDoRevertHack( HANDLE * phToken )
  864. {
  865. if ( OpenThreadToken( GetCurrentThread(),
  866. TOKEN_IMPERSONATE,
  867. TRUE,
  868. phToken ) )
  869. {
  870. RevertToSelf();
  871. }
  872. else
  873. {
  874. /*
  875. DBGPRINTF((
  876. DBG_CONTEXT,
  877. "[DoRevertHack] OpenThreadToken failed. Error %d.\r\n",
  878. GetLastError()
  879. ));
  880. */
  881. *phToken = INVALID_HANDLE_VALUE;
  882. }
  883. }
  884. VOID AspUndoRevertHack( HANDLE * phToken )
  885. {
  886. if ( !*phToken || ( *phToken == INVALID_HANDLE_VALUE ) )
  887. {
  888. return;
  889. }
  890. SetThreadToken( NULL,
  891. *phToken );
  892. CloseHandle( *phToken );
  893. *phToken = INVALID_HANDLE_VALUE;
  894. }