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.

1019 lines
30 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. massupdt.cpp
  5. Abstract:
  6. functions to udpate bunches of properties at once
  7. Author:
  8. Boyd Multerer (boydm)
  9. Project:
  10. IIS Setup
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include <iis64.h>
  18. #include "iadmw.h"
  19. #include "iiscnfg.h"
  20. #include "strfn.h"
  21. #include "mdkey.h"
  22. #include "mdentry.h"
  23. #include "massupdt.h"
  24. //============================================================
  25. // first the Abstract CMassPropertyUpdater class
  26. //============================================================
  27. //=================== CMassPropertyUpdater ===================
  28. //============================================================
  29. //------------------------------------------------------------
  30. CMassPropertyUpdater::CMassPropertyUpdater(
  31. DWORD dwMDIdentifier,
  32. DWORD dwMDDataType ) :
  33. m_dwMDIdentifier( dwMDIdentifier ),
  34. m_dwMDDataType( dwMDDataType )
  35. {
  36. }
  37. //------------------------------------------------------------
  38. CMassPropertyUpdater::~CMassPropertyUpdater()
  39. {
  40. }
  41. //------------------------------------------------------------
  42. HRESULT CMassPropertyUpdater::Update(
  43. LPCTSTR strStartNode,
  44. BOOL fStopOnErrors OPTIONAL )
  45. {
  46. HRESULT hRes;
  47. CString szPath;
  48. POSITION pos;
  49. LPWSTR pwstr;
  50. // start by getting the list of nodes with script maps on them
  51. // first open the node that we will start searching on
  52. hRes = OpenNode( strStartNode );
  53. if ( FAILED(hRes) )
  54. {
  55. iisDebugOut((LOG_TYPE_ERROR, _T("CMassPropertyUpdater::Update()-OpenNode failed. err=%x.\n"), hRes));
  56. return hRes;
  57. }
  58. // get the sub-paths that have the data on them
  59. hRes = GetDataPaths( m_dwMDIdentifier, m_dwMDDataType, m_pathList );
  60. if ( FAILED(hRes) )
  61. {
  62. iisDebugOut((LOG_TYPE_ERROR, _T("CMassPropertyUpdater::Update()-GetDataPaths failed. err=%x.\n"), hRes));
  63. goto cleanup;
  64. }
  65. // we now have the cstringlist of paths that need to be updated. Loop through the
  66. // list and update them all.
  67. // get the list's head position
  68. pos = m_pathList.GetHeadPosition();
  69. while ( NULL != pos )
  70. {
  71. // get the next path in question
  72. szPath = m_pathList.GetNext( pos );
  73. // make a special case of the "/" path
  74. if ( szPath == _T("/") )
  75. szPath.Empty();
  76. // drat. ANSI stuff is a mess so deal with it here
  77. #ifdef UNICODE
  78. pwstr = (LPWSTR)(LPCTSTR)szPath;
  79. #else
  80. pwstr = AllocWideString( szPath );
  81. #endif
  82. // operate on it
  83. hRes = UpdateOne( pwstr );
  84. #ifndef UNICODE
  85. FreeMem( pwstr );
  86. #endif
  87. // if we are stopping of failures, then check
  88. if ( FAILED(hRes) )
  89. {
  90. iisDebugOut((LOG_TYPE_ERROR, _T("CMassPropertyUpdater::Update():FAILED: update path =%s.\n"), szPath));
  91. //if requested to stop the loop, then do so
  92. if ( fStopOnErrors )
  93. break;
  94. }
  95. }
  96. // cleanup - close the node once and for all
  97. cleanup:
  98. Close();
  99. // return the answer
  100. return hRes;
  101. }
  102. //============================================================
  103. //==================== CInvertScriptMaps =====================
  104. //============================================================
  105. //------------------------------------------------------------
  106. HRESULT CInvertScriptMaps::UpdateOne( LPWSTR strPath )
  107. {
  108. HRESULT hRes;
  109. POSITION pos;
  110. POSITION posCurrent;
  111. CString szMap;
  112. DWORD dwattributes = 0;
  113. CStringList cslScriptMaps;
  114. // get the full script map in question.
  115. hRes = GetMultiSzAsStringList (
  116. m_dwMDIdentifier,
  117. &m_dwMDDataType,
  118. &dwattributes,
  119. cslScriptMaps,
  120. strPath );
  121. //iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne() GetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
  122. if ( FAILED(hRes) )
  123. {
  124. iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
  125. return hRes;
  126. }
  127. // HACK. The first thing we need to do is make sure we haven't already inverted this script
  128. // map during a previous build-to-build upgrade. If we invert it twice, then we are back
  129. // to an exclusion list and that would not be desirable. The way to detect this is to see
  130. // if the GET verb is listed for the ASP script map or not. If it is there, then it has been
  131. // inverted. This will only be a problem when doing build-to-build upgrades in IIS5.
  132. pos = cslScriptMaps.GetHeadPosition();
  133. while ( NULL != pos )
  134. {
  135. // get the next path in question
  136. szMap = cslScriptMaps.GetNext( pos );
  137. // if it is the .asp scriptmap, then finish the test
  138. if ( szMap.Left(4) == _T(".asp") )
  139. {
  140. if ( szMap.Find(_T("GET")) >= 0 )
  141. {
  142. return ERROR_SUCCESS;
  143. }
  144. else
  145. {
  146. break;
  147. }
  148. }
  149. }
  150. // we now have the cstringlist of paths that need to be updated. Loop through the
  151. // list and update them all.
  152. // get the list's head position
  153. pos = cslScriptMaps.GetHeadPosition();
  154. while ( NULL != pos )
  155. {
  156. // store the current position
  157. posCurrent = pos;
  158. // get the next path in question
  159. szMap = cslScriptMaps.GetNext( pos );
  160. // operate on it
  161. hRes = InvertOneScriptMap( szMap );
  162. // if that worked, put it back in place
  163. if ( SUCCEEDED(hRes) )
  164. {
  165. cslScriptMaps.SetAt ( posCurrent, szMap );
  166. }
  167. }
  168. //iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne() SetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
  169. // Put it back.
  170. hRes = SetMultiSzAsStringList (
  171. m_dwMDIdentifier,
  172. m_dwMDDataType,
  173. dwattributes,
  174. cslScriptMaps,
  175. strPath );
  176. if ( FAILED(hRes) )
  177. {
  178. iisDebugOut((LOG_TYPE_ERROR, _T("CInvertScriptMaps::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
  179. return hRes;
  180. }
  181. return hRes;
  182. }
  183. //------------------------------------------------------------
  184. HRESULT CInvertScriptMaps::InvertOneScriptMap( CString& csMap )
  185. {
  186. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CInvertScriptMaps::InvertOneScriptMap():%s.start.\n"), csMap));
  187. // the script mapping is yet another list. This time seperated
  188. // by commas. The first 4 items are standard and don't get messed
  189. // with. The n last items are all verbs that need to be inverted.
  190. int numParts;
  191. int numVerbs;
  192. CStringList cslMapParts;
  193. CStringList cslVerbs;
  194. CString szComma = _T(",");
  195. CString szVerb;
  196. POSITION posMap;
  197. POSITION posVerb;
  198. // break the source map into a string list
  199. numParts = ConvertSepLineToStringList(
  200. csMap,
  201. cslMapParts,
  202. szComma
  203. );
  204. CString szAllVerbs;
  205. if (!GetScriptMapAllInclusionVerbs(szAllVerbs))
  206. {
  207. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetScriptMapAllInclusionVerbs():FAIL.WARNING.UseDefaults\n")));
  208. szAllVerbs = SZ_INVERT_ALL_VERBS;
  209. }
  210. // start by making a string list with all the verbs to invert against
  211. numVerbs = ConvertSepLineToStringList(
  212. SZ_INVERT_ALL_VERBS,
  213. cslVerbs,
  214. szComma
  215. );
  216. // start with the 3rd indexed item in the source list. This should be the
  217. // first verb in the old "exclusion" list. Then use it and scan
  218. // the new "Inclusion" list of verbs. If it is there, rememove it.
  219. posMap = cslMapParts.FindIndex( 3 );
  220. while ( NULL != posMap )
  221. {
  222. // set to the next verb in the map list
  223. szVerb = cslMapParts.GetNext( posMap );
  224. // make sure the verb is normalized to capitals and
  225. // no whitespace before or after
  226. szVerb.MakeUpper();
  227. szVerb.TrimLeft();
  228. szVerb.TrimRight();
  229. // try to find the verb in the invertion list
  230. posVerb = cslVerbs.Find( szVerb );
  231. // if we found it, remove it
  232. if ( NULL != posVerb )
  233. {
  234. cslVerbs.RemoveAt( posVerb );
  235. }
  236. }
  237. // strip all the verbs off the source list
  238. while ( cslMapParts.GetCount() > 3 )
  239. {
  240. cslMapParts.RemoveTail();
  241. }
  242. // combine the lists
  243. cslMapParts.AddTail( &cslVerbs );
  244. // put it back into the comma list
  245. ConvertStringListToSepLine(
  246. cslMapParts,
  247. csMap,
  248. szComma
  249. );
  250. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CInvertScriptMaps::InvertOneScriptMap():%s.End.\n"), csMap));
  251. return ERROR_SUCCESS;
  252. }
  253. //============================================================
  254. //================= CIPSecPhysicalPathFixer ==================
  255. //============================================================
  256. //------------------------------------------------------------
  257. CPhysicalPathFixer::CPhysicalPathFixer( CString& szOldSysPath, CString &szNewSysPath ):
  258. CMassPropertyUpdater(0, 0), // bad values on purpose - see Update below...
  259. m_szOldSysPath( szOldSysPath ),
  260. m_szNewSysPath( szNewSysPath )
  261. {
  262. m_szOldSysPath.MakeUpper();
  263. }
  264. //------------------------------------------------------------
  265. HRESULT CPhysicalPathFixer::Update( LPCTSTR strStartNode, BOOL fStopOnErrors )
  266. {
  267. HRESULT hRes;
  268. // vrpath -- should we do this too? yes.
  269. m_dwMDIdentifier = MD_VR_PATH;
  270. m_dwMDDataType = STRING_METADATA;
  271. hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
  272. // inproc isapi apps.
  273. m_dwMDIdentifier = MD_IN_PROCESS_ISAPI_APPS;
  274. m_dwMDDataType = MULTISZ_METADATA;
  275. hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
  276. // prepare and update the scriptmappings multi sz strings
  277. m_dwMDIdentifier = MD_SCRIPT_MAPS;
  278. m_dwMDDataType = MULTISZ_METADATA;
  279. hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
  280. // prepare to update the FilterImagePath multi sz strings
  281. m_dwMDIdentifier = MD_FILTER_IMAGE_PATH;
  282. m_dwMDDataType = STRING_METADATA;
  283. hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
  284. // prepare to update the FilterImagePath multi sz strings
  285. m_dwMDIdentifier = MD_LOGFILE_DIRECTORY;
  286. m_dwMDDataType = EXPANDSZ_METADATA;
  287. hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
  288. return hRes;
  289. }
  290. //MD_FILTER_LOAD_ORDER
  291. // in process isapi apps
  292. // custom errors
  293. //------------------------------------------------------------
  294. HRESULT CPhysicalPathFixer2::Update( LPCTSTR strStartNode, BOOL fStopOnErrors )
  295. {
  296. HRESULT hRes;
  297. // prepare and update the scriptmappings multi sz strings
  298. m_dwMDIdentifier = MD_CUSTOM_ERROR;
  299. m_dwMDDataType = MULTISZ_METADATA;
  300. hRes = CMassPropertyUpdater::Update( strStartNode, fStopOnErrors );
  301. return hRes;
  302. }
  303. //------------------------------------------------------------
  304. HRESULT CPhysicalPathFixer::UpdateOne( LPWSTR strPath )
  305. {
  306. HRESULT hRes = 0xFFFFFFFF;
  307. if ( m_dwMDDataType == STRING_METADATA )
  308. {
  309. hRes = UpdateOneSTRING_DATA( strPath );
  310. }
  311. else if ( m_dwMDDataType == MULTISZ_METADATA )
  312. {
  313. hRes = UpdateOneMULTISZ_DATA( strPath );
  314. }
  315. else if ( m_dwMDDataType == EXPANDSZ_METADATA )
  316. {
  317. hRes = UpdateOneSTRING_DATA_EXPAND( strPath );
  318. }
  319. return hRes;
  320. }
  321. //------------------------------------------------------------
  322. HRESULT CPhysicalPathFixer::UpdateOneMULTISZ_DATA( LPWSTR strPath )
  323. {
  324. HRESULT hRes;
  325. POSITION pos;
  326. POSITION posCurrent;
  327. CString csPath;
  328. CStringList cslPaths;
  329. BOOL fSomethingChanged = FALSE;
  330. DWORD dwattributes = 0;
  331. // get the full script map in question.
  332. hRes = GetMultiSzAsStringList (
  333. m_dwMDIdentifier,
  334. &m_dwMDDataType,
  335. &dwattributes,
  336. cslPaths,
  337. strPath );
  338. if ( FAILED(hRes) )
  339. {
  340. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
  341. return hRes;
  342. }
  343. // we now have the cstringlist of paths that need to be updated. Loop through the
  344. // list and update them all.
  345. // get the list's head position
  346. pos = cslPaths.GetHeadPosition();
  347. while ( NULL != pos )
  348. {
  349. // store the current position
  350. posCurrent = pos;
  351. // get the next path in question
  352. csPath = cslPaths.GetNext( pos );
  353. // operate on it
  354. hRes = UpdateOnePath( csPath );
  355. // if that worked, put it back in place
  356. if ( SUCCEEDED(hRes) )
  357. {
  358. cslPaths.SetAt ( posCurrent, csPath );
  359. fSomethingChanged = TRUE;
  360. }
  361. // if there was nothing to update..
  362. if (hRes == 0xFFFFFFFF)
  363. {hRes = ERROR_SUCCESS;}
  364. }
  365. // Put it back. - unless nothing changed
  366. if ( fSomethingChanged )
  367. {
  368. hRes = SetMultiSzAsStringList (
  369. m_dwMDIdentifier,
  370. m_dwMDDataType,
  371. dwattributes,
  372. cslPaths,
  373. strPath );
  374. if ( FAILED(hRes) )
  375. {
  376. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
  377. return hRes;
  378. }
  379. }
  380. return hRes;
  381. }
  382. //------------------------------------------------------------
  383. HRESULT CPhysicalPathFixer::UpdateOneSTRING_DATA_EXPAND( LPWSTR strPath )
  384. {
  385. HRESULT hRes;
  386. CString csPath;
  387. BOOL fSomethingChanged = FALSE;
  388. // get the full script map in question.
  389. hRes = GetStringAsCString (
  390. m_dwMDIdentifier,
  391. m_dwMDDataType,
  392. NULL,
  393. csPath,
  394. strPath,
  395. 1);
  396. if ( MD_ERROR_DATA_NOT_FOUND == hRes)
  397. {
  398. hRes = ERROR_SUCCESS;
  399. return hRes;
  400. }
  401. if ( FAILED(hRes) )
  402. {
  403. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
  404. return hRes;
  405. }
  406. //iisDebugOut((LOG_TYPE_TRACE, _T("GetStringAsCString:Read.%S\n"), csPath));
  407. // operate on it
  408. hRes = UpdateOnePath( csPath );
  409. // if that worked, put it back in place
  410. if ( SUCCEEDED(hRes) )
  411. {
  412. fSomethingChanged = TRUE;
  413. }
  414. // if there was nothing to update..
  415. if (hRes == 0xFFFFFFFF)
  416. {hRes = ERROR_SUCCESS;}
  417. // Put it back. - unless nothing changed
  418. if ( fSomethingChanged )
  419. {
  420. //iisDebugOut((LOG_TYPE_TRACE, _T("GetStringAsCString:write.%S\n"), csPath));
  421. hRes = SetCStringAsString (
  422. m_dwMDIdentifier,
  423. m_dwMDDataType,
  424. NULL,
  425. csPath,
  426. strPath,
  427. 1);
  428. if ( FAILED(hRes) )
  429. {
  430. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
  431. return hRes;
  432. }
  433. }
  434. return hRes;
  435. }
  436. //------------------------------------------------------------
  437. HRESULT CPhysicalPathFixer::UpdateOneSTRING_DATA( LPWSTR strPath )
  438. {
  439. HRESULT hRes;
  440. CString csPath;
  441. BOOL fSomethingChanged = FALSE;
  442. // get the full script map in question.
  443. hRes = GetStringAsCString (
  444. m_dwMDIdentifier,
  445. m_dwMDDataType,
  446. NULL,
  447. csPath,
  448. strPath,
  449. 0);
  450. if ( MD_ERROR_DATA_NOT_FOUND == hRes)
  451. {
  452. hRes = ERROR_SUCCESS;
  453. return hRes;
  454. }
  455. if ( FAILED(hRes) )
  456. {
  457. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
  458. return hRes;
  459. }
  460. // operate on it
  461. hRes = UpdateOnePath( csPath );
  462. // if that worked, put it back in place
  463. if ( SUCCEEDED(hRes) )
  464. {
  465. fSomethingChanged = TRUE;
  466. }
  467. // if there was nothing to update..
  468. if (hRes == 0xFFFFFFFF)
  469. {hRes = ERROR_SUCCESS;}
  470. // Put it back. - unless nothing changed
  471. if ( fSomethingChanged )
  472. {
  473. hRes = SetCStringAsString (
  474. m_dwMDIdentifier,
  475. m_dwMDDataType,
  476. NULL,
  477. csPath,
  478. strPath,
  479. 0);
  480. if ( FAILED(hRes) )
  481. {
  482. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecPhysicalPathFixer::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
  483. return hRes;
  484. }
  485. }
  486. return hRes;
  487. }
  488. //------------------------------------------------------------
  489. // note: returns 0xFFFFFFFF if nothing changed
  490. HRESULT CPhysicalPathFixer::UpdateOnePath( CString& csPath )
  491. {
  492. // buffer the incoming string and make it upper case for the find
  493. CString csUpper = csPath;
  494. csUpper.MakeUpper();
  495. // first, find the old syspath in the csPath
  496. int iOldPath = csUpper.Find( m_szOldSysPath );
  497. // if it wasn't there, then return with 0xFFFFFFFF
  498. if ( iOldPath == -1 )
  499. {
  500. return 0xFFFFFFFF;
  501. }
  502. // the plan is the build a new string from the old one.
  503. CString csNewPath;
  504. // start by copying everything to the left of the substring
  505. csNewPath = csPath.Left( iOldPath );
  506. // now add to it the new path
  507. csNewPath += m_szNewSysPath;
  508. // now add to that the rest of the string
  509. csNewPath += csPath.Right( csPath.GetLength() - (iOldPath + m_szOldSysPath.GetLength()) );
  510. // finally, put the new string into place
  511. csPath = csNewPath;
  512. return 0;
  513. }
  514. //============================================================
  515. //==================== CIPSecRefBitAdder =====================
  516. //============================================================
  517. //------------------------------------------------------------
  518. //MD_IP_SEC, BINARY_METADATA
  519. // Unfortunately, at this time there is no way to directly manipulate the
  520. // attribuites on a property in the metabase without reading in
  521. // the actual property data. This could be made much simpler if a IADM level
  522. // method to do this is added to the metabase interface at some point in the
  523. // future.
  524. HRESULT CIPSecRefBitAdder::UpdateOne( LPWSTR strPath )
  525. {
  526. HRESULT hRes = ERROR_SUCCESS;
  527. METADATA_RECORD mdrData;
  528. // get the ipsec data. The loop accounts for a buffer that is too small...
  529. DWORD dwMDBufferSize = 1024;
  530. PWCHAR pwchBuffer = NULL;
  531. do
  532. {
  533. if ( pwchBuffer )
  534. {
  535. delete pwchBuffer;
  536. pwchBuffer = NULL;
  537. }
  538. pwchBuffer = new WCHAR[dwMDBufferSize];
  539. if (pwchBuffer == NULL)
  540. {
  541. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  542. }
  543. // prepare the metadata parameter block
  544. MD_SET_DATA_RECORD(&mdrData, MD_IP_SEC, 0,
  545. IIS_MD_UT_FILE, BINARY_METADATA, dwMDBufferSize, pwchBuffer);
  546. // make the call to get the data
  547. // If the buffer is too small, the correct size will be put into dwMDBufferSize
  548. hRes = m_pcCom->GetData(
  549. m_hKey,
  550. strPath,
  551. &mdrData,
  552. &dwMDBufferSize
  553. );
  554. }
  555. while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
  556. // if there were any failures, go to the cleanup code now...
  557. if ( SUCCEEDED(hRes) )
  558. {
  559. // at this point we can check to see if the reference bit is part of the attributes.
  560. // if it is, then we can just clean up. If it isn't, we should add it and write it
  561. // back out.
  562. if ( (mdrData.dwMDAttributes & METADATA_REFERENCE) == 0 )
  563. {
  564. // the attributes flag is not set. Set it.
  565. mdrData.dwMDAttributes |= METADATA_REFERENCE;
  566. // write it back out to the metabase
  567. hRes = m_pcCom->SetData(
  568. m_hKey,
  569. strPath,
  570. &mdrData
  571. );
  572. }
  573. }
  574. // clean up
  575. if ( pwchBuffer )
  576. delete pwchBuffer;
  577. if ( FAILED(hRes) )
  578. {
  579. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecRefBitAdder::UpdateOne() failed. err=%x.\n"), hRes));
  580. }
  581. return hRes;
  582. }
  583. //============================================================
  584. //==================== CFixCustomErrors ======================
  585. //============================================================
  586. HRESULT CustomErrorProcessOneLine(CString& csInputOneBlobEntry)
  587. {
  588. HRESULT hReturn = E_FAIL;
  589. CStringList cslBlobEntryParts;
  590. CString csComma = _T(",");
  591. TCHAR szDrive_only[_MAX_DRIVE];
  592. TCHAR szPath_only[_MAX_PATH];
  593. TCHAR szPath_only2[_MAX_PATH];
  594. TCHAR szFilename_only[_MAX_PATH];
  595. TCHAR szFilename_ext_only[_MAX_EXT];
  596. CString csFilePath;
  597. CString csFilePathNew;
  598. CString csFilePath2;
  599. CString csEntry;
  600. CString csEntry0;
  601. CString csEntry1;
  602. CString csEntry2;
  603. CString csEntry3;
  604. TCHAR szNewFileName[_MAX_PATH];
  605. POSITION pos;
  606. //"500,15,FILE,D:\WINNT\help\iisHelp\common\500-15.htm"
  607. //"500,100,URL,/iisHelp/common/500-100.asp"
  608. // break the source map into a string list
  609. ConvertSepLineToStringList(csInputOneBlobEntry,cslBlobEntryParts,csComma);
  610. // we now have the cstringlist. Loop through the list
  611. // which should look like this:
  612. // 0:500
  613. // 1:15
  614. // 2:FILE
  615. // 3:D:\WINNT\help\iisHelp\common\500-15.htm
  616. pos = cslBlobEntryParts.GetHeadPosition();
  617. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  618. // 0:500
  619. csEntry = cslBlobEntryParts.GetAt(pos);
  620. csEntry0 = csEntry;
  621. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  622. // 1:15
  623. cslBlobEntryParts.GetNext(pos);
  624. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  625. csEntry = cslBlobEntryParts.GetAt(pos);
  626. csEntry1 = csEntry;
  627. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  628. // 2:FILE
  629. // Check to make sure this is the "file" type
  630. // that we will act upon. if it's not then get out
  631. cslBlobEntryParts.GetNext(pos);
  632. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  633. csEntry = cslBlobEntryParts.GetAt(pos);
  634. if ( csEntry.Left(4) != _T("FILE") )
  635. {goto CustomErrorProcessOneLine_Exit;}
  636. csEntry2 = csEntry;
  637. // 3:D:\WINNT\help\iisHelp\common\500-15.htm
  638. cslBlobEntryParts.GetNext(pos);
  639. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  640. csEntry = cslBlobEntryParts.GetAt(pos);
  641. csEntry3 = csEntry;
  642. // KOOL, this is one we need to process.
  643. // D:\WINNT\help\iisHelp\common\500-15.htm
  644. // Get the filename
  645. // Trim off the filename and return only the path
  646. _tsplitpath(csEntry, szDrive_only, szPath_only, szFilename_only, szFilename_ext_only);
  647. // Check if the path points to the old place...
  648. csFilePath.Format(_T("%s\\help\\common\\fakefile"), g_pTheApp->m_csWinDir);
  649. _tsplitpath( csFilePath, NULL, szPath_only2, NULL, NULL);
  650. if (_tcsicmp(szPath_only, szPath_only2) != 0)
  651. {
  652. // nope this one does not point to the old place so we can get out
  653. goto CustomErrorProcessOneLine_Exit;
  654. }
  655. // yes, it points to the old place.
  656. // let's see if it exists in the new place first...
  657. csFilePathNew.Format(_T("%s\\help\\iishelp\\common"), g_pTheApp->m_csWinDir);
  658. csFilePath.Format(_T("%s\\%s%s"), csFilePathNew, szFilename_only, szFilename_ext_only);
  659. if (IsFileExist(csFilePath))
  660. {
  661. // yes, it does, then let's replace it.
  662. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s\\%s%s"), csEntry0, csEntry1, csEntry2, csFilePathNew, szFilename_only, szFilename_ext_only);
  663. // return
  664. hReturn = ERROR_SUCCESS;
  665. goto CustomErrorProcessOneLine_Exit;
  666. }
  667. // no it does not exist...
  668. // see if there is a *.bak file with that name...
  669. csFilePath2 = csFilePath;
  670. csFilePath2 += _T(".bak");
  671. if (IsFileExist(csFilePath2))
  672. {
  673. // yes, it does, then let's replace it.
  674. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s\\%s%s.bak"), csEntry0, csEntry1, csEntry2, csFilePathNew, szFilename_only, szFilename_ext_only);
  675. // return
  676. hReturn = ERROR_SUCCESS;
  677. goto CustomErrorProcessOneLine_Exit;
  678. }
  679. // They must be pointing to some other file which we don't have.
  680. // let's try to copy the old file from the old directory...
  681. // rename file to *.bak and move it to the new location..
  682. _stprintf(szNewFileName, _T("%s\\%s%s"), csFilePathNew, szFilename_only, szFilename_ext_only);
  683. // move it
  684. if (IsFileExist(csEntry3))
  685. {
  686. //iisDebugOut((LOG_TYPE_TRACE, _T("CustomErrorProcessOneLine: MoveFileEx:%s,%s.\n"),csEntry3, szNewFileName));
  687. if (MoveFileEx(csEntry3, szNewFileName, MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH|MOVEFILE_REPLACE_EXISTING))
  688. {
  689. // yes, it does, then let's replace it.
  690. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s"), csEntry0, csEntry1, csEntry2, szNewFileName);
  691. hReturn = ERROR_SUCCESS;
  692. }
  693. // we were not able to move it so don't make it poiint to the new place.
  694. }
  695. else
  696. {
  697. // Check if the file was renamed...
  698. // rename file to *.bak and move it to the new location..
  699. _stprintf(szNewFileName, _T("%s\\%s%s.bak"), csFilePathNew, szFilename_only, szFilename_ext_only);
  700. // yes, it does, then let's replace it.
  701. if (IsFileExist(szNewFileName))
  702. {
  703. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s"), csEntry0, csEntry1, csEntry2, szNewFileName);
  704. hReturn = ERROR_SUCCESS;
  705. }
  706. else
  707. {
  708. // they must be pointing to some other file which we don't install.
  709. // so don't change this entry...
  710. }
  711. }
  712. CustomErrorProcessOneLine_Exit:
  713. if (hReturn == ERROR_SUCCESS)
  714. {
  715. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CustomErrorProcessOneLine:End.value=%s.\n"),csInputOneBlobEntry));
  716. }
  717. return hReturn;
  718. }
  719. //------------------------------------------------------------
  720. HRESULT CFixCustomErrors::UpdateOne( LPWSTR strPath )
  721. {
  722. HRESULT hRes = ERROR_SUCCESS;
  723. POSITION pos;
  724. POSITION posCurrent;
  725. CString szMap;
  726. DWORD dwattributes = 0;
  727. CStringList cslScriptMaps;
  728. //iisDebugOut((LOG_TYPE_TRACE, _T("CFixCustomErrors::UpdateOne() %s.\n"), strPath));
  729. CString csTheNode;
  730. csTheNode = _T("LM/W3SVC");
  731. csTheNode += strPath;
  732. // get the full script map in question.
  733. hRes = GetMultiSzAsStringList (
  734. m_dwMDIdentifier,
  735. &m_dwMDDataType,
  736. &dwattributes,
  737. cslScriptMaps,
  738. strPath );
  739. //iisDebugOut((LOG_TYPE_TRACE, _T("CFixCustomErrors::UpdateOne() GetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
  740. if ( FAILED(hRes) )
  741. {
  742. iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
  743. return hRes;
  744. }
  745. // we now have the cstringlist of paths that need to be updated. Loop through the
  746. // list and update them all.
  747. // get the list's head position
  748. pos = cslScriptMaps.GetHeadPosition();
  749. while ( NULL != pos )
  750. {
  751. // store the current position
  752. posCurrent = pos;
  753. // get the next path in question
  754. szMap = cslScriptMaps.GetNext( pos );
  755. // print it out to the screen for debug purposes
  756. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CFixCustomErrors::UpdateOne().Data=%s.\n"), szMap));
  757. // operate on it
  758. hRes = CustomErrorProcessOneLine( szMap );
  759. // if that worked, put it back in place
  760. if ( SUCCEEDED(hRes) ){cslScriptMaps.SetAt ( posCurrent, szMap );}
  761. }
  762. //iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne() SetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
  763. // Put it back.
  764. hRes = SetMultiSzAsStringList (
  765. m_dwMDIdentifier,
  766. m_dwMDDataType,
  767. dwattributes,
  768. cslScriptMaps,
  769. strPath );
  770. if ( FAILED(hRes) )
  771. {
  772. iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
  773. return hRes;
  774. }
  775. return hRes;
  776. }
  777. HRESULT CEnforceMaxConnection::UpdateOne( LPWSTR strPath )
  778. {
  779. HRESULT hRes = 0xFFFFFFFF;
  780. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne(%s).start\n"), strPath));
  781. DWORD theDword;
  782. BOOL fSomethingChanged = FALSE;
  783. if ( m_dwMDDataType == DWORD_METADATA )
  784. {
  785. // Get the value into a dword
  786. // get the full script map in question.
  787. hRes = GetDword(m_dwMDIdentifier,m_dwMDDataType,NULL,theDword,strPath);
  788. if ( MD_ERROR_DATA_NOT_FOUND == hRes)
  789. {
  790. hRes = ERROR_SUCCESS;
  791. return hRes;
  792. }
  793. if ( FAILED(hRes) )
  794. {
  795. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne()-GetDword failed. err=%x.\n"), hRes));
  796. return hRes;
  797. }
  798. if (theDword > 10)
  799. {
  800. theDword = 10;
  801. fSomethingChanged = TRUE;
  802. }
  803. else
  804. {
  805. hRes = ERROR_SUCCESS;
  806. }
  807. // Put it back. - unless nothing changed
  808. if ( fSomethingChanged )
  809. {
  810. //hRes = SetDword(m_dwMDIdentifier,m_dwMDDataType,NULL,theDword,strPath);
  811. if ( FAILED(hRes) )
  812. {
  813. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne()-GetDword failed. err=%x.\n"), hRes));
  814. return hRes;
  815. }
  816. }
  817. }
  818. else
  819. {
  820. hRes = ERROR_SUCCESS;
  821. }
  822. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne(%s).End.ret=0x%x\n"), strPath,hRes));
  823. return hRes;
  824. }