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.

1321 lines
33 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name :
  4. restrlst.cxx
  5. Abstract:
  6. Classes that are used to modify the restriction list and application
  7. dependency list in the metabase
  8. Author:
  9. Christopher Achille (cachille)
  10. Project:
  11. Internet Services Setup
  12. Revision History:
  13. April 2002: Created
  14. --*/
  15. #include "stdafx.h"
  16. #include "restrlst.hxx"
  17. #include "xmlupgrade.hxx"
  18. // Constructor
  19. //
  20. CApplicationDependencies::CApplicationDependencies()
  21. {
  22. m_bMetabaseOpened = FALSE;
  23. }
  24. // InitMetabase
  25. //
  26. // Open the metabase, at the correct location for the Application Dependecies,
  27. // so that we can read and write to it
  28. //
  29. BOOL
  30. CApplicationDependencies::InitMetabase()
  31. {
  32. if ( m_bMetabaseOpened )
  33. {
  34. return TRUE;
  35. }
  36. m_bMetabaseOpened = SUCCEEDED( m_Metabase.OpenNode( METABASEPATH_WWW_ROOT, TRUE ) );
  37. return m_bMetabaseOpened;
  38. }
  39. // LoadCurrentSettings
  40. //
  41. // Load the current settings from the metabase
  42. //
  43. BOOL
  44. CApplicationDependencies::LoadCurrentSettings()
  45. {
  46. CMDValue mbValue;
  47. BOOL bRet = TRUE;
  48. if ( !InitMetabase() )
  49. {
  50. return FALSE;
  51. }
  52. if ( !m_Metabase.GetData( mbValue, MD_APP_DEPENDENCIES ) )
  53. {
  54. m_mstrDependencies.Empty();
  55. }
  56. else
  57. {
  58. if ( ( mbValue.GetDataType() != MULTISZ_METADATA ) ||
  59. !m_mstrDependencies.Copy( (LPWSTR) mbValue.GetData() )
  60. )
  61. {
  62. // Either wrong type, or the copy failed
  63. bRet = FALSE;
  64. }
  65. }
  66. return bRet;
  67. }
  68. // SaveSettings
  69. //
  70. // Save the settings to the metabase
  71. //
  72. BOOL
  73. CApplicationDependencies::SaveSettings()
  74. {
  75. CMDValue mbValue;
  76. if ( !InitMetabase() )
  77. {
  78. return FALSE;
  79. }
  80. if ( !mbValue.SetValue( MD_APP_DEPENDENCIES, // Metabase property
  81. 0, // Attributes
  82. IIS_MD_UT_SERVER, // User Type
  83. MULTISZ_METADATA, // Data Type
  84. m_mstrDependencies.QueryLen() * sizeof(TCHAR), // Length
  85. (LPVOID) m_mstrDependencies.QueryMultiSz() ) ) // Data
  86. {
  87. return FALSE;
  88. }
  89. return m_Metabase.SetData( mbValue, MD_APP_DEPENDENCIES );
  90. }
  91. // AddUnattendSettings
  92. //
  93. // Read the unattend settings from the file, and
  94. // put them in the list
  95. //
  96. // It expects the lines in the unattend to be in the form
  97. // [InternetServer]
  98. // ApplicationDependency=CommerceServer,ASP60,INDEX99
  99. // ApplicationDependency=ExchangeServer,ASP60
  100. // ApplicationDependency=MyApp,ASPNET20
  101. //
  102. // And will product in the m_mstrDependencies:
  103. // CommerceServer;ASP60,INDEX99\0
  104. // ExchangeServer;ASP60\0
  105. // MyApp;ASPNET20\0
  106. // \0
  107. //
  108. // Return:
  109. // TRUE - Successfully imported all settings
  110. // FAILED - Failed to import settings
  111. //
  112. BOOL
  113. CApplicationDependencies::AddUnattendSettings()
  114. {
  115. BOOL bContinue;
  116. INFCONTEXT Context;
  117. TSTR strLine;
  118. DWORD dwRequiredSize;
  119. LPTSTR szFirstComma;
  120. if ( g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE )
  121. {
  122. // Since there is no unattend file, return success
  123. return TRUE;
  124. }
  125. bContinue = SetupFindFirstLine( g_pTheApp->m_hUnattendFile,
  126. UNATTEND_FILE_SECTION,
  127. UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
  128. &Context);
  129. while ( bContinue )
  130. {
  131. if ( !SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
  132. strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
  133. {
  134. // Need to resize for larger buffer
  135. if ( ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) ||
  136. ( dwRequiredSize <= strLine.QuerySize() ) ||
  137. !strLine.Resize( dwRequiredSize ) ||
  138. !SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
  139. strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
  140. {
  141. // Failure to either resize, or read in data
  142. return FALSE;
  143. }
  144. }
  145. szFirstComma = _tcschr( strLine.QueryStr(), ',' );
  146. if ( !szFirstComma )
  147. {
  148. iisDebugOut((LOG_TYPE_ERROR,
  149. _T("Failed to import Application Dependencies unattend \
  150. setting '%s=%s' because it is in the wrong format"),
  151. UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
  152. strLine.QueryStr() ) );
  153. return FALSE;
  154. }
  155. // Change the first comma to a ';', since the format in the unattend file,
  156. //and the metabase are different
  157. *szFirstComma = _T(';');
  158. // Remove the old line, if one existed for this Application
  159. if ( !RemoveOldAppDendency( strLine.QueryStr() ) )
  160. {
  161. return FALSE;
  162. }
  163. if ( !m_mstrDependencies.Add( strLine.QueryStr() ) )
  164. {
  165. return FALSE;
  166. }
  167. bContinue = SetupFindNextMatchLine( &Context,
  168. UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
  169. &Context);
  170. }
  171. return TRUE;
  172. }
  173. // RemoveOldAppDendency
  174. //
  175. // Since a New Application Dependency line is being added, make sure to
  176. // remove anylines that are already in the list for an Application
  177. // with the same name
  178. //
  179. // Parameters:
  180. // szNewLine - The New line to be added
  181. //
  182. // Return
  183. // TRUE - It was removed if necessary
  184. // FALSE - Failure to remove old Line
  185. BOOL
  186. CApplicationDependencies::RemoveOldAppDendency( LPTSTR szNewLine )
  187. {
  188. LPTSTR szDelimeter = _tcschr( szNewLine, _T(';') );
  189. DWORD dwLength;
  190. DWORD dwCurrent;
  191. LPTSTR szCurrent;
  192. if ( !szDelimeter )
  193. {
  194. // This should be in the correct format by the time it gets to us
  195. ASSERT( szDelimeter );
  196. return FALSE;
  197. }
  198. // The length on the name, including the ';'
  199. dwLength = (DWORD) ( szDelimeter + 1 - szNewLine );
  200. for ( dwCurrent = 0;
  201. ( szCurrent = m_mstrDependencies.QueryString( dwCurrent ) ) != NULL;
  202. dwCurrent++ )
  203. {
  204. // Compare Strings
  205. if ( _tcsnicmp( szCurrent, szNewLine, dwLength ) == 0 )
  206. {
  207. // This already exists in the list. If the list is correct then
  208. // it can only be in the list once, so return
  209. return m_mstrDependencies.Remove( szCurrent, TRUE );
  210. }
  211. }
  212. // Not found, so no need to remove
  213. return TRUE;
  214. }
  215. // DoUnattendSettingsExist
  216. //
  217. // Do a simple check to see if unattend settings for this
  218. // property exist. Because if they don't, there is nothing
  219. // to do.
  220. //
  221. BOOL
  222. CApplicationDependencies::DoUnattendSettingsExist()
  223. {
  224. INFCONTEXT Context;
  225. if ( g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE )
  226. {
  227. return FALSE;
  228. }
  229. return SetupFindFirstLine( g_pTheApp->m_hUnattendFile,
  230. UNATTEND_FILE_SECTION,
  231. UNATTEND_INETSERVER_APPLICATIONDEPENDENCIES,
  232. &Context);
  233. }
  234. // FindApplication
  235. //
  236. // Find the application in the list
  237. //
  238. // Parameters:
  239. // szApplicationName [in] - The name of the application to look for
  240. //
  241. // Return Values:
  242. // NULL - Not found
  243. // pointer - Pointer to item in list
  244. //
  245. LPTSTR
  246. CApplicationDependencies::FindApplication( LPTSTR szApplicationName )
  247. {
  248. DWORD dwCurrent;
  249. LPTSTR szCurrent;
  250. DWORD dwLength = _tcslen( szApplicationName );
  251. ASSERT( szApplicationName );
  252. for ( dwCurrent = 0;
  253. ( szCurrent = m_mstrDependencies.QueryString( dwCurrent ) ) != NULL;
  254. dwCurrent++ )
  255. {
  256. // Compare Strings
  257. if ( ( _tcsnicmp( szCurrent, szApplicationName, dwLength ) == 0 ) &&
  258. ( ( *( szCurrent + dwLength ) == _T('\0') ) ||
  259. ( *( szCurrent + dwLength ) == _T(';') )
  260. )
  261. )
  262. {
  263. // It has been found
  264. return szCurrent;
  265. }
  266. }
  267. // Not found
  268. return NULL;
  269. }
  270. // DoesApplicationExist
  271. //
  272. // Determine if the application extst in the list
  273. //
  274. // Parameters:
  275. // szApplicationName [in] - The name of the application to look for
  276. //
  277. // Return Values:
  278. // TRUE - It exists
  279. // FALSE - It does not exist
  280. //
  281. BOOL
  282. CApplicationDependencies::DoesApplicationExist( LPTSTR szApplicationName )
  283. {
  284. return ( FindApplication( szApplicationName ) != NULL );
  285. }
  286. // AddApplication
  287. //
  288. // Add an application to the Application Dependencies list
  289. //
  290. // Parameters:
  291. // szApplication [in] - The name of the Application
  292. // (ie. "Active Server Pages")
  293. // Should contain no ';' or ','
  294. // szDependencies [in] - The dependencies seperated by comma's
  295. // bReplaceExisting [in] - If an application by the same name is in the
  296. // list, should we replace it?
  297. BOOL
  298. CApplicationDependencies::AddApplication( LPTSTR szApplication,
  299. LPTSTR szDependencies,
  300. BOOL bReplaceExisting )
  301. {
  302. LPTSTR szOldApplication;
  303. TSTR strNewApplication;
  304. ASSERT( szApplication );
  305. ASSERT( szDependencies );
  306. szOldApplication = FindApplication( szApplication );
  307. if ( szOldApplication )
  308. {
  309. if ( bReplaceExisting )
  310. {
  311. // Remove old item
  312. if ( !m_mstrDependencies.Remove( szOldApplication, TRUE ) )
  313. {
  314. // Failed to remove old item
  315. return FALSE;
  316. }
  317. }
  318. else
  319. {
  320. // Since we don't want to replace, lets exit
  321. return TRUE;
  322. }
  323. }
  324. if ( !strNewApplication.Copy( szApplication ) ||
  325. !strNewApplication.Append( _T(";") ) ||
  326. !strNewApplication.Append( szDependencies ) ||
  327. !m_mstrDependencies.Add( strNewApplication.QueryStr() )
  328. )
  329. {
  330. // Failed to construct name, and add it
  331. return FALSE;
  332. }
  333. return TRUE;
  334. }
  335. // AddDefaults
  336. //
  337. // Add the defaults to the list
  338. //
  339. BOOL
  340. CApplicationDependencies::AddDefaults()
  341. {
  342. DWORD dwCurrent;
  343. TSTR strApplicationName;
  344. for ( dwCurrent = 0;
  345. dwCurrent < EXTENSION_ENDOFLIST;
  346. dwCurrent ++)
  347. {
  348. if ( !strApplicationName.LoadString( g_OurExtensions[dwCurrent].dwProductName ) )
  349. {
  350. // Failed to add application
  351. return FALSE;
  352. }
  353. if ( !AddApplication( strApplicationName.QueryStr(),
  354. g_OurExtensions[dwCurrent].szNotLocalizedGroupName,
  355. FALSE ) )
  356. {
  357. // Failed to add defaults
  358. return FALSE;
  359. }
  360. }
  361. return TRUE;
  362. }
  363. // Constructor
  364. //
  365. CRestrictionList::CRestrictionList()
  366. {
  367. m_bMetabaseOpened = FALSE;
  368. }
  369. // InitMetabase
  370. //
  371. // Open the metabase, at the correct location for the Restriction List,
  372. // so that we can read and write to it
  373. //
  374. BOOL
  375. CRestrictionList::InitMetabase()
  376. {
  377. if ( m_bMetabaseOpened )
  378. {
  379. return TRUE;
  380. }
  381. m_bMetabaseOpened = SUCCEEDED( m_Metabase.OpenNode( METABASEPATH_WWW_ROOT, TRUE ) );
  382. return m_bMetabaseOpened;
  383. }
  384. // LoadMSZFromPhysicalMetabase
  385. //
  386. // Load a multisz from the physical metabase at /lm/w3svc node
  387. //
  388. BOOL
  389. CRestrictionList::LoadMSZFromPhysicalMetabase( TSTR_MSZ *pmszProperty,
  390. LPCTSTR szPropertyName )
  391. {
  392. TSTR_PATH strMbPath;
  393. CXMLEdit XMLFile;
  394. TSTR strTemp;
  395. if ( !strMbPath.RetrieveSystemDir() ||
  396. !strMbPath.PathAppend( CXMLBASE_METABASEPATH ) )
  397. {
  398. // Could not construct path, fail
  399. return FALSE;
  400. }
  401. if ( !XMLFile.Open( strMbPath.QueryStr(), FALSE ) )
  402. {
  403. // Could not open file, this might be okay, since
  404. // it might be a IIS 6.0 upgrade before XML was used
  405. return TRUE;
  406. }
  407. while ( XMLFile.MovetoNextItem() )
  408. {
  409. // Find the IISWeb service node with Location=/LM/W3SVC
  410. if ( XMLFile.IsEqualItem( METABASE_PHYS_RESTR_UPG_NODETYPE ) &&
  411. XMLFile.MovetoFirstProperty() &&
  412. XMLFile.IsEqualProperty( METABASE_PHYS_RESTR_UPG_PROPTYPE ) &&
  413. XMLFile.IsEqualValue( METABASE_PHYS_RESTR_UPG_PROPVALUE ) )
  414. {
  415. // We found it, now lets get the read property
  416. XMLFile.MovetoFirstProperty();
  417. do
  418. {
  419. if ( XMLFile.IsEqualProperty( szPropertyName ) )
  420. {
  421. // We found the right property, now lets get the value
  422. if ( !XMLFile.RetrieveCurrentValue( &strTemp ) )
  423. {
  424. return FALSE;
  425. }
  426. return LoadMSZFromMultiLineSz( pmszProperty, (LPTSTR) strTemp.QueryStr() );
  427. }
  428. } while ( XMLFile.MovetoNextProperty() );
  429. // We found the right node, but it did not exist, that is okay, we will just
  430. // ignore it
  431. return TRUE;
  432. }
  433. }
  434. XMLFile.Close();
  435. return TRUE;
  436. }
  437. // LoadMSZFromMultiLineSz
  438. //
  439. // Load a MultiSZ from a Multi Line String with either \r\n or \r
  440. // seperating them
  441. //
  442. BOOL
  443. CRestrictionList::LoadMSZFromMultiLineSz( TSTR_MSZ *pmszProperty, LPTSTR szSource )
  444. {
  445. LPTSTR szCurrent = szSource;
  446. LPTSTR szTemp;
  447. TCHAR cTempChar;
  448. while ( *szCurrent != '\0' )
  449. {
  450. // Skip Spaces at begining
  451. while ( ( *szCurrent == ' ' ) ||
  452. ( *szCurrent == '\t' ) )
  453. {
  454. szCurrent++;
  455. }
  456. szTemp = szCurrent;
  457. while ( ( *szTemp != '\0' ) &&
  458. ( *szTemp != '\r' ) &&
  459. ( *szTemp != '\n' ) )
  460. {
  461. szTemp++;
  462. }
  463. // Temprorarily NULL Terminate
  464. cTempChar = *szTemp;
  465. *szTemp = '\0';
  466. if ( !pmszProperty->Add( szCurrent ) )
  467. {
  468. // Failed to construct list
  469. return FALSE;
  470. }
  471. *szTemp = cTempChar;
  472. if ( ( *szTemp == '\r' ) &&
  473. ( *(szTemp+1) == '\n' ) )
  474. {
  475. // Move past \n
  476. szTemp++;
  477. }
  478. if ( *szTemp != '\0' )
  479. {
  480. // Increment one char, to get to next line
  481. szTemp++;
  482. }
  483. // Start at new line
  484. szCurrent = szTemp;
  485. }
  486. return TRUE;
  487. }
  488. // LoadMSZFromMetabase
  489. //
  490. // Load a multisz from the metabase
  491. //
  492. // Parameters:
  493. // [out] pmszProperty - The Property that is being extracted
  494. // [in] dwPropertyID - The ID of the property to be retrieved
  495. // [in] szMBPath - The sub path to look in
  496. //
  497. // Return Values:
  498. // FALSE - Failed to retrieve
  499. // TRUE - Retrieved successfully, or it did not exist and we are returning
  500. // an empty list
  501. //
  502. BOOL
  503. CRestrictionList::LoadMSZFromMetabase( TSTR_MSZ *pmszProperty, DWORD dwPropertyID, LPWSTR szMBPath )
  504. {
  505. CMDValue mbValue;
  506. BOOL bRet = TRUE;
  507. if ( !InitMetabase() )
  508. {
  509. return FALSE;
  510. }
  511. if ( !m_Metabase.GetData( mbValue, dwPropertyID, szMBPath ) )
  512. {
  513. pmszProperty->Empty();
  514. }
  515. else
  516. {
  517. if ( ( mbValue.GetDataType() != MULTISZ_METADATA ) ||
  518. !pmszProperty->Copy( (LPWSTR) mbValue.GetData() )
  519. )
  520. {
  521. // Either wrong type, or the copy failed
  522. bRet = FALSE;
  523. }
  524. }
  525. return bRet;
  526. }
  527. // LoadCurrentSettings
  528. //
  529. // Load the current Restriction List Properties.
  530. //
  531. // Note: This loads them from the new location, not the old
  532. // ISAPIRestrictionLiad and CGIRestrictionList locations.
  533. // There is a seperate function to merge those in.
  534. //
  535. BOOL
  536. CRestrictionList::LoadCurrentSettings()
  537. {
  538. return LoadMSZFromMetabase( &m_mstrRestrictionList,
  539. MD_WEB_SVC_EXT_RESTRICTION_LIST );
  540. }
  541. // LoadOldFormatSettings
  542. //
  543. // Load the old CGIRestrictionList and ISAPIRestrictionList and import
  544. // them into our new variable
  545. //
  546. BOOL
  547. CRestrictionList::LoadOldFormatSettings( TSTR_MSZ *pmstrCgiRestList, TSTR_MSZ *pmstrIsapiRestList )
  548. {
  549. // Load old metabase values
  550. if ( !LoadMSZFromPhysicalMetabase( pmstrCgiRestList,
  551. METABASE_PHYS_RESTR_CGI ) ||
  552. !LoadMSZFromPhysicalMetabase( pmstrIsapiRestList,
  553. METABASE_PHYS_RESTR_ISAPI ) )
  554. {
  555. // Could not load errors
  556. return FALSE;
  557. }
  558. return TRUE;
  559. }
  560. // ImportOldLists
  561. //
  562. // Import the Old Restriction Lists into the new list
  563. // This is only needed for IIS6->IIS6 upgrades, where
  564. // the old settings were in the CGI/ISAPIRestrictionList
  565. BOOL
  566. CRestrictionList::ImportOldLists( TSTR_MSZ &mstrCgiRestList, TSTR_MSZ &mstrIsapiRestList )
  567. {
  568. // Import old values into new list
  569. if ( !ImportOldList( mstrCgiRestList,
  570. TRUE ) ||
  571. !ImportOldList( mstrIsapiRestList,
  572. FALSE )
  573. )
  574. {
  575. // Could not import new values
  576. return FALSE;
  577. }
  578. return TRUE;
  579. }
  580. // SaveSettings
  581. //
  582. // Save the settings to the metabase
  583. //
  584. BOOL
  585. CRestrictionList::SaveSettings()
  586. {
  587. CMDValue mbValue;
  588. if ( !InitMetabase() )
  589. {
  590. return FALSE;
  591. }
  592. if ( !mbValue.SetValue( MD_WEB_SVC_EXT_RESTRICTION_LIST, // Metabase property
  593. 0, // Attributes
  594. IIS_MD_UT_SERVER, // User Type
  595. MULTISZ_METADATA, // Data Type
  596. m_mstrRestrictionList.QueryLen() * sizeof(TCHAR), // Length
  597. (LPVOID) m_mstrRestrictionList.QueryMultiSz() ) ) // Data
  598. {
  599. return FALSE;
  600. }
  601. return m_Metabase.SetData( mbValue, MD_WEB_SVC_EXT_RESTRICTION_LIST );
  602. }
  603. // AddItem
  604. //
  605. // Add an Item to the list
  606. //
  607. // Parameters:
  608. // szInfo [in] - The line containing all the info for the path
  609. // Format: ExtensionFile=access,path,<UI deleteable>,
  610. // <short description>,<long description>
  611. // ie: 1,%windir%\system32\testisapi.dll,TRUE,Test Isapi,My Test Isapi for Foo.com
  612. // bReplaceExistiing - Should we replace existing
  613. //
  614. BOOL
  615. CRestrictionList::AddItem( LPTSTR szInfo, BOOL bReplaceExisting)
  616. {
  617. TSTR strCopy( MAX_PATH );
  618. LPTSTR pPhysicalPath = NULL;
  619. LPTSTR pShortDescription = NULL;
  620. LPTSTR pLongDescription = NULL;
  621. LPTSTR pCurrent;
  622. BOOL bAllow = FALSE;
  623. BOOL bUIDeletable = TRUE; // Different default for Unattend
  624. if ( !strCopy.Copy( szInfo ) )
  625. {
  626. // Could not copy line
  627. return FALSE;
  628. }
  629. pCurrent = strCopy.QueryStr();
  630. // Set access
  631. bAllow = ( *( pCurrent ) == _T('1') ) &&
  632. ( *( pCurrent + 1 ) == _T(',') );
  633. pCurrent = _tcschr( pCurrent, _T(',') );
  634. if ( !pCurrent )
  635. {
  636. // Without even a path, there is nothing we can do
  637. return FALSE;
  638. }
  639. // Set Physcial Path
  640. pCurrent++; // Move past ','
  641. pPhysicalPath = pCurrent;
  642. // Find UI deletable
  643. pCurrent = _tcschr( pCurrent, _T(',') );
  644. if ( pCurrent )
  645. {
  646. // Found UI Deletable
  647. // Null terminate path
  648. *(pCurrent++) = _T('\0');
  649. bUIDeletable = ( *( pCurrent ) == _T('1') ) &&
  650. ( *( pCurrent + 1 ) == _T(',') );
  651. // Jump to next field
  652. pCurrent = _tcschr( pCurrent, _T(',') );
  653. }
  654. if ( pCurrent )
  655. {
  656. // Found Short Description
  657. pCurrent++;
  658. pShortDescription = pCurrent;
  659. // Jump to next field
  660. pCurrent = _tcschr( pCurrent, _T(',') );
  661. }
  662. if ( pCurrent )
  663. {
  664. // Found Long Description
  665. // Null terminal Short Description
  666. *(pCurrent++) = _T('\0');
  667. pLongDescription = pCurrent;
  668. }
  669. return AddItem( pPhysicalPath,
  670. pShortDescription,
  671. pLongDescription,
  672. bAllow,
  673. bUIDeletable,
  674. bReplaceExisting );
  675. }
  676. // RetrieveDefaultsifKnow
  677. //
  678. // Retrieve defaults for the physical image if they are known
  679. //
  680. BOOL
  681. CRestrictionList::RetrieveDefaultsifKnow( LPTSTR szPhysicalPath,
  682. LPTSTR *pszGroupId,
  683. TSTR *pstrDescription,
  684. LPBOOL pbDeleteable )
  685. {
  686. DWORD dwIndex;
  687. TSTR_PATH strFullPath( MAX_PATH );
  688. ASSERT( szPhysicalPath );
  689. ASSERT( pszGroupId );
  690. ASSERT( pstrDescription );
  691. ASSERT( pbDeleteable );
  692. for ( dwIndex = 0;
  693. dwIndex < EXTENSION_ENDOFLIST;
  694. dwIndex++ )
  695. {
  696. if ( !strFullPath.Copy( g_pTheApp->m_csPathInetsrv.GetBuffer(0) ) ||
  697. !strFullPath.PathAppend( g_OurExtensions[dwIndex].szFileName ) )
  698. {
  699. // Failed to create full path, so skip to next one
  700. continue;
  701. }
  702. if ( strFullPath.IsEqual( szPhysicalPath, FALSE ) )
  703. {
  704. *pszGroupId = g_OurExtensions[dwIndex].szNotLocalizedGroupName;
  705. *pbDeleteable = g_OurExtensions[dwIndex].bUIDeletable;
  706. if ( !pstrDescription->LoadString( g_OurExtensions[dwIndex].dwProductName ) )
  707. {
  708. return FALSE;
  709. }
  710. // Done seaching
  711. return TRUE;
  712. }
  713. } // for ( dwIndex = ...
  714. // Return TRUE because we didn't fail
  715. return TRUE;
  716. } // RetrieveDefaultsifKnow
  717. // AddItem
  718. //
  719. // Add an item to the list.
  720. //
  721. // Parameters:
  722. // szPhysicalPath - The path of the executable
  723. // szGroupId - The group name
  724. // szDescription - The description for the executable
  725. // bAllow - TRUE==allow, FALSE==deny
  726. // bDeleteable - TRUE==UI deletable, FALSE==not UI deletable
  727. // bReplaceExisting - If it is already in the list, do we update it?
  728. //
  729. BOOL
  730. CRestrictionList::AddItem( LPTSTR szPhysicalPath,
  731. LPTSTR szGroupId,
  732. LPTSTR szDescription,
  733. BOOL bAllow,
  734. BOOL bDeleteable,
  735. BOOL bReplaceExisting)
  736. {
  737. LPTSTR szCurrentItem;
  738. LPTSTR szCurentPath;
  739. DWORD dwCurrentIndex = 0;
  740. TSTR strNewItem;
  741. TSTR_PATH strPhysicalPath;
  742. TSTR strDescription;
  743. ASSERT( szPhysicalPath );
  744. if ( !strPhysicalPath.Copy( szPhysicalPath ) ||
  745. !strPhysicalPath.ExpandEnvironmentVariables() )
  746. {
  747. return FALSE;
  748. }
  749. if ( szDescription &&
  750. !strDescription.Copy( szDescription) )
  751. {
  752. // Failed to do copy
  753. return FALSE;
  754. }
  755. // Fill in the Default valus if this is one of our isapi's
  756. if ( !RetrieveDefaultsifKnow( szPhysicalPath, &szGroupId, &strDescription, &bDeleteable ) )
  757. {
  758. return FALSE;
  759. }
  760. while ( ( szCurrentItem =
  761. m_mstrRestrictionList.QueryString( dwCurrentIndex++ ) ) != NULL )
  762. {
  763. szCurentPath = _tcschr( szCurrentItem, L',' );
  764. if ( szCurentPath == NULL )
  765. {
  766. continue;
  767. }
  768. szCurentPath++;
  769. if ( ( _tcsnicmp( szCurentPath,
  770. strPhysicalPath.QueryStr(),
  771. strPhysicalPath.QueryLen() ) == 0 ) &&
  772. ( ( *( szCurentPath + strPhysicalPath.QueryLen() ) == ',' ) ||
  773. ( *( szCurentPath + strPhysicalPath.QueryLen() ) == '\0' ) )
  774. )
  775. {
  776. if ( bReplaceExisting )
  777. {
  778. if ( !m_mstrRestrictionList.Remove( szCurrentItem, TRUE ) )
  779. {
  780. // Failed to remove item
  781. return FALSE;
  782. }
  783. }
  784. else
  785. {
  786. // It succeeded, because we didn't want to replace existing
  787. return TRUE;
  788. }
  789. break;
  790. }
  791. } // while ( ... )
  792. // Copy <allow/deny>,<physical path>,<ui deletable>
  793. if ( !strNewItem.Copy( bAllow ? _T("1") : _T("0") ) ||
  794. !strNewItem.Append( _T(",") ) ||
  795. !strNewItem.Append( strPhysicalPath.QueryStr() ) )
  796. {
  797. return FALSE;
  798. }
  799. // Append Group
  800. if ( ( szGroupId || ( strDescription.QueryLen() != 0 ) ) &&
  801. ( !strNewItem.Append( _T(",") ) ||
  802. !strNewItem.Append( bDeleteable ? _T("1") : _T("0") ) ||
  803. !strNewItem.Append( _T(",") ) ||
  804. !strNewItem.Append( szGroupId ? szGroupId : _T("") )
  805. )
  806. )
  807. {
  808. return FALSE;
  809. }
  810. // Append Description
  811. if ( ( strDescription.QueryLen() != 0 ) &&
  812. ( !strNewItem.Append( _T(",") ) ||
  813. !strNewItem.Append( strDescription.QueryStr() )
  814. )
  815. )
  816. {
  817. return FALSE;
  818. }
  819. // Add it to the list
  820. return m_mstrRestrictionList.Add( strNewItem.QueryStr() );
  821. }
  822. // ImportOldList
  823. //
  824. // Import settings from the old format to the new format
  825. //
  826. // Old Format:
  827. // AllowDenyFlagforAll - Inidcates if default is to allow or deny
  828. // ExtensionPhysicalPath - Exe to do opposite of default
  829. // ExtensionPhysicalPath - Exe to do opposite of default
  830. //
  831. // New Format:
  832. // AllowDenyFlag,*.dll
  833. // AllowDenyFlag,*.exe
  834. // AllowDenyFlag,ExtensionPhysicalPath,UIDeletableFlag,GroupID,Description
  835. //
  836. // AllowDenyFlag - 0 or 1 depending on allowed (1) or not allowed (0)
  837. // ExtensionPhysicalPath - Physical Path to dll
  838. // UIDeletableFlag - 0 for not ui deletable, 1 for UI deletable
  839. // GroupID - Id of the group
  840. // Descrition - Locallized Description
  841. //
  842. BOOL
  843. CRestrictionList::ImportOldList( TSTR_MSZ &mstrOldStyleRestrictionList,
  844. BOOL bCgiList)
  845. {
  846. LPTSTR szCurrentItem;
  847. DWORD dwIndex = 1;
  848. BOOL bDefaultAllow = TRUE;
  849. LPTSTR szDefault;
  850. // Take the first string as the default
  851. szDefault = mstrOldStyleRestrictionList.QueryString( 0 );
  852. bDefaultAllow = szDefault ? ( *szDefault == '1' ? TRUE : FALSE ) : FALSE;
  853. if ( *szDefault == '\0' )
  854. {
  855. // There is nothing to import since the list is empty,
  856. // so lets quit
  857. return TRUE;
  858. }
  859. if ( !AddItem( bCgiList ? _T("*.exe") : _T("*.dll"),
  860. NULL, NULL, bDefaultAllow, FALSE, FALSE ) )
  861. {
  862. // Could not set default for Restriction List
  863. return FALSE;
  864. }
  865. // Start importing starting at item[1]
  866. while ( ( szCurrentItem =
  867. mstrOldStyleRestrictionList.QueryString( dwIndex++ ) ) != NULL )
  868. {
  869. if ( *szCurrentItem == _T('\0') )
  870. {
  871. // Empty line
  872. continue;
  873. }
  874. if ( !AddItem( szCurrentItem, // Path
  875. NULL, // Group
  876. NULL, // Description
  877. !bDefaultAllow, // bAllow
  878. TRUE,
  879. FALSE ) )
  880. {
  881. // Failed to add item
  882. return FALSE;
  883. }
  884. }
  885. if ( !bCgiList )
  886. {
  887. // Since we have imported all the ones we can. We should now add all IIS's
  888. // defaults, or they will be added later with the wrong default
  889. // BUGBUG:: Right now this assumes the defaults are all ISAPI's, which they
  890. // are for now
  891. if ( !AddDefaults( bDefaultAllow ) )
  892. {
  893. return FALSE;
  894. }
  895. }
  896. return TRUE;
  897. }
  898. // AddDefaults
  899. //
  900. // Add the defaults to the restriction list
  901. // If we fail, then try to add as many as possible
  902. //
  903. // Parameters
  904. // bAllOthersDefault - Should *.dll and *.exe be allowed or
  905. // denied by default?
  906. //
  907. BOOL
  908. CRestrictionList::AddDefaults( BOOL bAllOthersDefault )
  909. {
  910. DWORD dwIndex;
  911. BOOL bRet = TRUE;
  912. TSTR_PATH strFullPath;
  913. if ( !AddItem( _T("*.dll"), NULL, NULL, bAllOthersDefault,
  914. FALSE, FALSE ) ||
  915. !AddItem( _T("*.exe"), NULL, NULL, bAllOthersDefault,
  916. FALSE, FALSE ) )
  917. {
  918. // Failed to add dll and exe defaults
  919. bRet = FALSE;
  920. }
  921. for ( dwIndex = 0;
  922. dwIndex < EXTENSION_ENDOFLIST;
  923. dwIndex++ )
  924. {
  925. if ( !strFullPath.Copy( g_pTheApp->m_csPathInetsrv.GetBuffer(0) ) ||
  926. !strFullPath.PathAppend( g_OurExtensions[dwIndex].szFileName ) )
  927. {
  928. // Failed to create full path, so skip to next one
  929. bRet = FALSE;
  930. continue;
  931. }
  932. // The Group and Description are sent in as NULL, because they will
  933. // be filled in automatically by AddItem
  934. if ( !AddItem( strFullPath.QueryStr(), // Physical Path
  935. NULL, // Group Name
  936. NULL, // Description
  937. bAllOthersDefault, // Allowed/Denied
  938. FALSE, // Not UI Deletable
  939. FALSE ) ) // Do not replace existing
  940. {
  941. bRet = FALSE;
  942. }
  943. }
  944. return bRet;
  945. }
  946. // IsEmpty
  947. //
  948. // Is the restrictionList Empty?
  949. //
  950. BOOL
  951. CRestrictionList::IsEmpty()
  952. {
  953. return m_mstrRestrictionList.QueryLen() == 1;
  954. }
  955. // AddUnattendSettings
  956. //
  957. // Read the unattend settings from the file, and
  958. // put them in the list
  959. //
  960. // It expects the lines in the unattend to be in the form
  961. // [InternetServer]
  962. // ExtensionFile=0,*.dll
  963. // ExtensionFile=1,*.exe
  964. // ExtensionFile=1,%windir%\system32\testisapi.dll,0,Test Isapi,My Test Isapi for Foo.com
  965. //
  966. // And will product in the m_mstrDependencies:
  967. // 0,*.dll\0
  968. // 1,*,exe\0
  969. // d:\whistler\system32\testisapi.dll,TRUE,Test Isapi,My Test Isapi for Foo.com\0
  970. // \0
  971. //
  972. // Return:
  973. // TRUE - Successfully imported all settings
  974. // FAILED - Failed to import settings
  975. //
  976. BOOL
  977. CRestrictionList::AddUnattendSettings()
  978. {
  979. BOOL bContinue;
  980. INFCONTEXT Context;
  981. TSTR strLine;
  982. DWORD dwRequiredSize;
  983. if ( g_pTheApp->m_hUnattendFile == INVALID_HANDLE_VALUE )
  984. {
  985. // Since there is no unattend file, return success
  986. return TRUE;
  987. }
  988. bContinue = SetupFindFirstLine( g_pTheApp->m_hUnattendFile,
  989. UNATTEND_FILE_SECTION,
  990. UNATTEND_INETSERVER_EXTENSIONRESTRICTIONLIST,
  991. &Context);
  992. while ( bContinue )
  993. {
  994. if ( !SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
  995. strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
  996. {
  997. // Need to resize for larger buffer
  998. if ( ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) ||
  999. ( dwRequiredSize <= strLine.QuerySize() ) ||
  1000. !strLine.Resize( dwRequiredSize ) ||
  1001. !SetupGetLineText( &Context, INVALID_HANDLE_VALUE, NULL, NULL,
  1002. strLine.QueryStr(), strLine.QuerySize(), &dwRequiredSize) )
  1003. {
  1004. // Failure to either resize, or read in data
  1005. return FALSE;
  1006. }
  1007. }
  1008. if ( !AddItem( strLine.QueryStr(), TRUE ) )
  1009. {
  1010. // Failed to add item
  1011. return FALSE;
  1012. }
  1013. bContinue = SetupFindNextMatchLine( &Context,
  1014. UNATTEND_INETSERVER_EXTENSIONRESTRICTIONLIST,
  1015. &Context);
  1016. }
  1017. return TRUE;
  1018. }
  1019. // UpdateItem
  1020. //
  1021. // Update an Item with the right value
  1022. //
  1023. BOOL
  1024. CRestrictionList::UpdateItem( LPTSTR szPhysicalPath,
  1025. LPTSTR szGroupId,
  1026. LPTSTR szDescription,
  1027. BOOL bAllow,
  1028. BOOL bDeleteable )
  1029. {
  1030. return AddItem( szPhysicalPath, szGroupId, szDescription,
  1031. bAllow, bDeleteable, TRUE );
  1032. }
  1033. // FindItemByGroup
  1034. //
  1035. // Find an Item by the Group ID
  1036. //
  1037. LPTSTR
  1038. CRestrictionList::FindItemByGroup( LPTSTR szGroupId )
  1039. {
  1040. LPTSTR szCurrent;
  1041. LPTSTR szCurrentItem;
  1042. DWORD dwLength;
  1043. DWORD dwCurrentIndex = 0;
  1044. dwLength = _tcslen( szGroupId );
  1045. while ( ( szCurrentItem =
  1046. m_mstrRestrictionList.QueryString( dwCurrentIndex++ ) ) != NULL )
  1047. {
  1048. // Get Physical Path
  1049. szCurrent = _tcschr( szCurrentItem, L',' );
  1050. if ( szCurrent )
  1051. {
  1052. // Get UI Deletable
  1053. szCurrent++;
  1054. szCurrent = _tcschr( szCurrent, L',' );
  1055. }
  1056. if ( szCurrent )
  1057. {
  1058. // Get Group ID
  1059. szCurrent++;
  1060. szCurrent = _tcschr( szCurrent, L',' );
  1061. }
  1062. if ( szCurrent )
  1063. {
  1064. // Since we found the group id, lets compare
  1065. szCurrent++;
  1066. if ( ( _tcsnicmp( szGroupId,
  1067. szCurrent,
  1068. dwLength ) == 0 ) &&
  1069. ( ( *( szCurrent + dwLength ) == ',' ) ||
  1070. ( *( szCurrent + dwLength ) == '\0' ) )
  1071. )
  1072. {
  1073. // Found a match, return the item
  1074. return szCurrentItem;
  1075. }
  1076. }
  1077. } // while ( ... )
  1078. // Could not find
  1079. return NULL;
  1080. }
  1081. // Find an item
  1082. LPTSTR
  1083. CRestrictionList::FindItemByPhysicalPath( LPTSTR szPhysicalPath )
  1084. {
  1085. LPTSTR szCurrent;
  1086. LPTSTR szCurrentItem;
  1087. DWORD dwLength;
  1088. DWORD dwCurrentIndex = 0;
  1089. dwLength = _tcslen( szPhysicalPath );
  1090. while ( ( szCurrentItem =
  1091. m_mstrRestrictionList.QueryString( dwCurrentIndex++ ) ) != NULL )
  1092. {
  1093. // Get Physical Path
  1094. szCurrent = _tcschr( szCurrentItem, L',' );
  1095. if ( szCurrent )
  1096. {
  1097. // Since we found the group id, lets compare
  1098. szCurrent++;
  1099. if ( ( _tcsnicmp( szPhysicalPath,
  1100. szCurrent,
  1101. dwLength ) == 0 ) &&
  1102. ( ( *( szCurrent + dwLength ) == ',' ) ||
  1103. ( *( szCurrent + dwLength ) == '\0' ) )
  1104. )
  1105. {
  1106. // Found a match, return the item
  1107. return szCurrentItem;
  1108. }
  1109. }
  1110. } // while ( ... )
  1111. // Could not find
  1112. return NULL;
  1113. }
  1114. // IsEnabled
  1115. //
  1116. // Check to see if the particular item is enabled
  1117. // Note: Only works for dll's right now
  1118. //
  1119. // Return Values:
  1120. // TRUE - It is enabled
  1121. // FALSE - Not enabled ( default if could not determine )
  1122. //
  1123. // Note: Since Core defaults to denied, we init bEnabled to FALSE
  1124. //
  1125. BOOL
  1126. CRestrictionList::IsEnabled( LPTSTR szGroupId, LPBOOL pbIsEnabled )
  1127. {
  1128. BOOL bEnabled = FALSE;
  1129. LPTSTR szItem = FindItemByGroup( szGroupId );
  1130. if ( szItem )
  1131. {
  1132. // See if that item is enabled
  1133. bEnabled = ( *szItem == _T('1') );
  1134. }
  1135. else
  1136. {
  1137. // Since this item was not found, lets take the default
  1138. szItem = FindItemByPhysicalPath( _T("*.dll") );
  1139. if ( szItem )
  1140. {
  1141. bEnabled = ( *szItem == _T('1') );
  1142. }
  1143. }
  1144. *pbIsEnabled = bEnabled;
  1145. return TRUE;
  1146. }