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.

1020 lines
29 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. DWORD cbBuffer;
  529. // get the ipsec data. The loop accounts for a buffer that is too small...
  530. DWORD dwMDBufferSize = 1024;
  531. PWCHAR pwchBuffer = NULL;
  532. do
  533. {
  534. if ( pwchBuffer )
  535. {
  536. delete pwchBuffer;
  537. pwchBuffer = NULL;
  538. }
  539. pwchBuffer = new WCHAR[dwMDBufferSize];
  540. if (pwchBuffer == NULL)
  541. {
  542. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  543. }
  544. // prepare the metadata parameter block
  545. MD_SET_DATA_RECORD(&mdrData, MD_IP_SEC, 0,
  546. IIS_MD_UT_FILE, BINARY_METADATA, dwMDBufferSize, pwchBuffer);
  547. // make the call to get the data
  548. // If the buffer is too small, the correct size will be put into dwMDBufferSize
  549. hRes = m_pcCom->GetData(
  550. m_hKey,
  551. strPath,
  552. &mdrData,
  553. &dwMDBufferSize
  554. );
  555. }
  556. while( HRESULT_CODE(hRes) == ERROR_INSUFFICIENT_BUFFER);
  557. // if there were any failures, go to the cleanup code now...
  558. if ( SUCCEEDED(hRes) )
  559. {
  560. // at this point we can check to see if the reference bit is part of the attributes.
  561. // if it is, then we can just clean up. If it isn't, we should add it and write it
  562. // back out.
  563. if ( (mdrData.dwMDAttributes & METADATA_REFERENCE) == 0 )
  564. {
  565. // the attributes flag is not set. Set it.
  566. mdrData.dwMDAttributes |= METADATA_REFERENCE;
  567. // write it back out to the metabase
  568. hRes = m_pcCom->SetData(
  569. m_hKey,
  570. strPath,
  571. &mdrData
  572. );
  573. }
  574. }
  575. // clean up
  576. if ( pwchBuffer )
  577. delete pwchBuffer;
  578. if ( FAILED(hRes) )
  579. {
  580. iisDebugOut((LOG_TYPE_ERROR, _T("CIPSecRefBitAdder::UpdateOne() failed. err=%x.\n"), hRes));
  581. }
  582. return hRes;
  583. }
  584. //============================================================
  585. //==================== CFixCustomErrors ======================
  586. //============================================================
  587. HRESULT CustomErrorProcessOneLine(CString& csInputOneBlobEntry)
  588. {
  589. HRESULT hReturn = E_FAIL;
  590. CStringList cslBlobEntryParts;
  591. CString csComma = _T(",");
  592. TCHAR szDrive_only[_MAX_DRIVE];
  593. TCHAR szPath_only[_MAX_PATH];
  594. TCHAR szPath_only2[_MAX_PATH];
  595. TCHAR szFilename_only[_MAX_PATH];
  596. TCHAR szFilename_ext_only[_MAX_EXT];
  597. CString csFilePath;
  598. CString csFilePathNew;
  599. CString csFilePath2;
  600. CString csEntry;
  601. CString csEntry0;
  602. CString csEntry1;
  603. CString csEntry2;
  604. CString csEntry3;
  605. TCHAR szNewFileName[_MAX_PATH];
  606. POSITION pos;
  607. //"500,15,FILE,D:\WINNT\help\iisHelp\common\500-15.htm"
  608. //"500,100,URL,/iisHelp/common/500-100.asp"
  609. // break the source map into a string list
  610. ConvertSepLineToStringList(csInputOneBlobEntry,cslBlobEntryParts,csComma);
  611. // we now have the cstringlist. Loop through the list
  612. // which should look like this:
  613. // 0:500
  614. // 1:15
  615. // 2:FILE
  616. // 3:D:\WINNT\help\iisHelp\common\500-15.htm
  617. pos = cslBlobEntryParts.GetHeadPosition();
  618. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  619. // 0:500
  620. csEntry = cslBlobEntryParts.GetAt(pos);
  621. csEntry0 = csEntry;
  622. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  623. // 1:15
  624. cslBlobEntryParts.GetNext(pos);
  625. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  626. csEntry = cslBlobEntryParts.GetAt(pos);
  627. csEntry1 = csEntry;
  628. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  629. // 2:FILE
  630. // Check to make sure this is the "file" type
  631. // that we will act upon. if it's not then get out
  632. cslBlobEntryParts.GetNext(pos);
  633. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  634. csEntry = cslBlobEntryParts.GetAt(pos);
  635. if ( csEntry.Left(4) != _T("FILE") )
  636. {goto CustomErrorProcessOneLine_Exit;}
  637. csEntry2 = csEntry;
  638. // 3:D:\WINNT\help\iisHelp\common\500-15.htm
  639. cslBlobEntryParts.GetNext(pos);
  640. if (!pos) {goto CustomErrorProcessOneLine_Exit;}
  641. csEntry = cslBlobEntryParts.GetAt(pos);
  642. csEntry3 = csEntry;
  643. // KOOL, this is one we need to process.
  644. // D:\WINNT\help\iisHelp\common\500-15.htm
  645. // Get the filename
  646. // Trim off the filename and return only the path
  647. _tsplitpath(csEntry, szDrive_only, szPath_only, szFilename_only, szFilename_ext_only);
  648. // Check if the path points to the old place...
  649. csFilePath.Format(_T("%s\\help\\common\\fakefile"), g_pTheApp->m_csWinDir);
  650. _tsplitpath( csFilePath, NULL, szPath_only2, NULL, NULL);
  651. if (_tcsicmp(szPath_only, szPath_only2) != 0)
  652. {
  653. // nope this one does not point to the old place so we can get out
  654. goto CustomErrorProcessOneLine_Exit;
  655. }
  656. // yes, it points to the old place.
  657. // let's see if it exists in the new place first...
  658. csFilePathNew.Format(_T("%s\\help\\iishelp\\common"), g_pTheApp->m_csWinDir);
  659. csFilePath.Format(_T("%s\\%s%s"), csFilePathNew, szFilename_only, szFilename_ext_only);
  660. if (IsFileExist(csFilePath))
  661. {
  662. // yes, it does, then let's replace it.
  663. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s\\%s%s"), csEntry0, csEntry1, csEntry2, csFilePathNew, szFilename_only, szFilename_ext_only);
  664. // return
  665. hReturn = ERROR_SUCCESS;
  666. goto CustomErrorProcessOneLine_Exit;
  667. }
  668. // no it does not exist...
  669. // see if there is a *.bak file with that name...
  670. csFilePath2 = csFilePath;
  671. csFilePath2 += _T(".bak");
  672. if (IsFileExist(csFilePath2))
  673. {
  674. // yes, it does, then let's replace it.
  675. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s\\%s%s.bak"), csEntry0, csEntry1, csEntry2, csFilePathNew, szFilename_only, szFilename_ext_only);
  676. // return
  677. hReturn = ERROR_SUCCESS;
  678. goto CustomErrorProcessOneLine_Exit;
  679. }
  680. // They must be pointing to some other file which we don't have.
  681. // let's try to copy the old file from the old directory...
  682. // rename file to *.bak and move it to the new location..
  683. _stprintf(szNewFileName, _T("%s\\%s%s"), csFilePathNew, szFilename_only, szFilename_ext_only);
  684. // move it
  685. if (IsFileExist(csEntry3))
  686. {
  687. //iisDebugOut((LOG_TYPE_TRACE, _T("CustomErrorProcessOneLine: MoveFileEx:%s,%s.\n"),csEntry3, szNewFileName));
  688. if (MoveFileEx(csEntry3, szNewFileName, MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH|MOVEFILE_REPLACE_EXISTING))
  689. {
  690. // yes, it does, then let's replace it.
  691. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s"), csEntry0, csEntry1, csEntry2, szNewFileName);
  692. hReturn = ERROR_SUCCESS;
  693. }
  694. // we were not able to move it so don't make it poiint to the new place.
  695. }
  696. else
  697. {
  698. // Check if the file was renamed...
  699. // rename file to *.bak and move it to the new location..
  700. _stprintf(szNewFileName, _T("%s\\%s%s.bak"), csFilePathNew, szFilename_only, szFilename_ext_only);
  701. // yes, it does, then let's replace it.
  702. if (IsFileExist(szNewFileName))
  703. {
  704. csInputOneBlobEntry.Format(_T("%s,%s,%s,%s"), csEntry0, csEntry1, csEntry2, szNewFileName);
  705. hReturn = ERROR_SUCCESS;
  706. }
  707. else
  708. {
  709. // they must be pointing to some other file which we don't install.
  710. // so don't change this entry...
  711. }
  712. }
  713. CustomErrorProcessOneLine_Exit:
  714. if (hReturn == ERROR_SUCCESS)
  715. {
  716. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CustomErrorProcessOneLine:End.value=%s.\n"),csInputOneBlobEntry));
  717. }
  718. return hReturn;
  719. }
  720. //------------------------------------------------------------
  721. HRESULT CFixCustomErrors::UpdateOne( LPWSTR strPath )
  722. {
  723. HRESULT hRes = ERROR_SUCCESS;
  724. POSITION pos;
  725. POSITION posCurrent;
  726. CString szMap;
  727. DWORD dwattributes = 0;
  728. CStringList cslScriptMaps;
  729. //iisDebugOut((LOG_TYPE_TRACE, _T("CFixCustomErrors::UpdateOne() %s.\n"), strPath));
  730. CString csTheNode;
  731. csTheNode = _T("LM/W3SVC");
  732. csTheNode += strPath;
  733. // get the full script map in question.
  734. hRes = GetMultiSzAsStringList (
  735. m_dwMDIdentifier,
  736. &m_dwMDDataType,
  737. &dwattributes,
  738. cslScriptMaps,
  739. strPath );
  740. //iisDebugOut((LOG_TYPE_TRACE, _T("CFixCustomErrors::UpdateOne() GetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
  741. if ( FAILED(hRes) )
  742. {
  743. iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne()-GetMultiSzAsStringList failed. err=%x.\n"), hRes));
  744. return hRes;
  745. }
  746. // we now have the cstringlist of paths that need to be updated. Loop through the
  747. // list and update them all.
  748. // get the list's head position
  749. pos = cslScriptMaps.GetHeadPosition();
  750. while ( NULL != pos )
  751. {
  752. // store the current position
  753. posCurrent = pos;
  754. // get the next path in question
  755. szMap = cslScriptMaps.GetNext( pos );
  756. // print it out to the screen for debug purposes
  757. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("CFixCustomErrors::UpdateOne().Data=%s.\n"), szMap));
  758. // operate on it
  759. hRes = CustomErrorProcessOneLine( szMap );
  760. // if that worked, put it back in place
  761. if ( SUCCEEDED(hRes) ){cslScriptMaps.SetAt ( posCurrent, szMap );}
  762. }
  763. //iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne() SetMultiSzAsStringList. Attrib=0x%x.\n"), dwattributes));
  764. // Put it back.
  765. hRes = SetMultiSzAsStringList (
  766. m_dwMDIdentifier,
  767. m_dwMDDataType,
  768. dwattributes,
  769. cslScriptMaps,
  770. strPath );
  771. if ( FAILED(hRes) )
  772. {
  773. iisDebugOut((LOG_TYPE_ERROR, _T("CFixCustomErrors::UpdateOne()-SetMultiSzAsStringList failed. err=%x.\n"), hRes));
  774. return hRes;
  775. }
  776. return hRes;
  777. }
  778. HRESULT CEnforceMaxConnection::UpdateOne( LPWSTR strPath )
  779. {
  780. HRESULT hRes = 0xFFFFFFFF;
  781. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne(%s).start\n"), strPath));
  782. DWORD theDword;
  783. BOOL fSomethingChanged = FALSE;
  784. if ( m_dwMDDataType == DWORD_METADATA )
  785. {
  786. // Get the value into a dword
  787. // get the full script map in question.
  788. hRes = GetDword(m_dwMDIdentifier,m_dwMDDataType,NULL,theDword,strPath);
  789. if ( MD_ERROR_DATA_NOT_FOUND == hRes)
  790. {
  791. hRes = ERROR_SUCCESS;
  792. return hRes;
  793. }
  794. if ( FAILED(hRes) )
  795. {
  796. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne()-GetDword failed. err=%x.\n"), hRes));
  797. return hRes;
  798. }
  799. if (theDword > 10)
  800. {
  801. theDword = 10;
  802. fSomethingChanged = TRUE;
  803. }
  804. else
  805. {
  806. hRes = ERROR_SUCCESS;
  807. }
  808. // Put it back. - unless nothing changed
  809. if ( fSomethingChanged )
  810. {
  811. //hRes = SetDword(m_dwMDIdentifier,m_dwMDDataType,NULL,theDword,strPath);
  812. if ( FAILED(hRes) )
  813. {
  814. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne()-GetDword failed. err=%x.\n"), hRes));
  815. return hRes;
  816. }
  817. }
  818. }
  819. else
  820. {
  821. hRes = ERROR_SUCCESS;
  822. }
  823. iisDebugOut((LOG_TYPE_ERROR, _T("CEnforceMaxConnection::UpdateOne(%s).End.ret=0x%x\n"), strPath,hRes));
  824. return hRes;
  825. }