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.

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