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.

1598 lines
41 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. inetprop.h
  5. Abstract:
  6. Internet Properties base classes definitions
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. #ifndef _INETPROP_H_
  15. #define _INETPROP_H_
  16. // Some useful macros to set edit control
  17. // and buddy spin control
  18. //
  19. // (s).SetPos((pos));\
  20. //
  21. #define SETUP_SPIN(s,min,max,pos)\
  22. (s).SetRange32((min),(max));\
  23. (s).SetAccel(3, toAcc)
  24. #define SETUP_EDIT_SPIN(f, e, s, min, max, pos)\
  25. (e).EnableWindow((f));\
  26. (s).EnableWindow((f));\
  27. SETUP_SPIN((s),(min),(max),(pos))
  28. //
  29. // InitializeAndFetch parameters
  30. //
  31. #define WITHOUT_INHERITANCE (FALSE)
  32. #define WITH_INHERITANCE (TRUE)
  33. //
  34. // SSL Port number to use if SSL is not enabled
  35. //
  36. #define SSL_NOT_ENABLED (0)
  37. //
  38. // Bandwidth and compression definitions
  39. //
  40. #define BANDWIDTH_MIN (1)
  41. #define BANDWIDTH_MAX (32767)
  42. #define INFINITE_BANDWIDTH (0xffffffff)
  43. #define KILOBYTE (1024L)
  44. #define MEGABYTE (1024L * KILOBYTE)
  45. #define DEF_BANDWIDTH (1 * MEGABYTE)
  46. #define DEF_MAX_COMPDIR_SIZE (1 * MEGABYTE)
  47. //
  48. // Private FILE_ATTRIBUTE used to designate a virtual directory
  49. //
  50. #define FILE_ATTRIBUTE_VIRTUAL_DIRECTORY (0x10000000)
  51. //
  52. // Attribute crackers
  53. //
  54. #define IS_VROOT(dwAttributes) ((dwAttributes & FILE_ATTRIBUTE_VIRTUAL_DIRECTORY) != 0)
  55. #define IS_DIR(dwAttributes) ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
  56. #define IS_FILE(dwAttributes) ((dwAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_VIRTUAL_DIRECTORY)) == 0)
  57. //
  58. // Metabase constants
  59. //
  60. //
  61. // TODO: From mdkeys?
  62. //
  63. extern const LPCTSTR g_cszTemplates;
  64. extern const LPCTSTR g_cszCompression;
  65. extern const LPCTSTR g_cszMachine;
  66. extern const LPCTSTR g_cszMimeMap;
  67. extern const LPCTSTR g_cszRoot;
  68. extern const LPCTSTR g_cszSep;
  69. extern const TCHAR g_chSep;
  70. //
  71. // Utility Functions
  72. //
  73. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  74. //
  75. // Forward Definitions
  76. //
  77. class CIPAddress;
  78. //
  79. // Determine if the currently logged-in user us an administrator
  80. // or operator in the virtual server provided
  81. //
  82. HRESULT
  83. DetermineIfAdministrator(
  84. IN CMetaInterface * pInterface,
  85. IN LPCTSTR lpszMetabasePath,
  86. OUT BOOL * pfAdministrator,
  87. IN OUT DWORD * pdwMetabaseSystemChangeNumber
  88. );
  89. //
  90. // Utility classes
  91. //
  92. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  93. class CMaskedDWORD
  94. /*++
  95. Class Description:
  96. A masked DWORD class. This class performs assignments and comparison
  97. on a masked range of the DWORD value. For example, if a mask of
  98. 0x000000FF is set, any comparisons or assignments will only involve
  99. the least significant byte. A comparison against another DWORD will
  100. only compare that least significant byte, and an assignment will only
  101. set the least significant byte, leaving the rest untouched.
  102. Public Interface:
  103. CMaskedDWORD : Constructor
  104. operator == : Comparison operator
  105. operator != : Comparison operator
  106. operator = : Assignment operator
  107. operator DWORD : Cast to the value
  108. void SetMask : Set the mask
  109. --*/
  110. {
  111. //
  112. // Constructor/Destructor
  113. //
  114. public:
  115. CMaskedDWORD(
  116. IN DWORD dwValue = 0L,
  117. IN DWORD dwMask = 0xFFFFFFFF
  118. )
  119. : m_dwValue(dwValue),
  120. m_dwMask(dwMask)
  121. {
  122. }
  123. public:
  124. BOOL operator ==(DWORD dwValue) const;
  125. BOOL operator !=(DWORD dwValue) const { return !(operator ==(dwValue)); }
  126. CMaskedDWORD & operator =(DWORD dwValue);
  127. operator DWORD() const { return m_dwValue; }
  128. operator DWORD &() { return m_dwValue; }
  129. void SetMask(DWORD dwMask) { m_dwMask = dwMask; }
  130. private:
  131. DWORD m_dwValue;
  132. DWORD m_dwMask;
  133. };
  134. //
  135. // Forward Definitions
  136. //
  137. class CIPAddress;
  138. template <class TYPE, class ARG_TYPE>
  139. class CMPProp
  140. {
  141. public:
  142. CMPProp(ARG_TYPE value);
  143. CMPProp();
  144. operator ARG_TYPE() const;
  145. CMPProp<TYPE, ARG_TYPE> & operator =(ARG_TYPE value);
  146. BOOL m_fDirty;
  147. TYPE m_value;
  148. };
  149. template <class TYPE, class ARG_TYPE>
  150. inline CMPProp<TYPE, ARG_TYPE>::CMPProp(ARG_TYPE value)
  151. : m_value(value),
  152. m_fDirty(FALSE)
  153. {
  154. }
  155. template <class TYPE, class ARG_TYPE>
  156. inline CMPProp<TYPE, ARG_TYPE>::CMPProp()
  157. : m_value(),
  158. m_fDirty(FALSE)
  159. {
  160. }
  161. template <class TYPE, class ARG_TYPE>
  162. inline CMPProp<TYPE, ARG_TYPE>::operator ARG_TYPE() const
  163. {
  164. return (ARG_TYPE)m_value;
  165. }
  166. template <class TYPE, class ARG_TYPE>
  167. inline CMPProp<TYPE, ARG_TYPE> & CMPProp<TYPE, ARG_TYPE>::operator =(ARG_TYPE value)
  168. {
  169. if (m_value != value)
  170. {
  171. m_value = value;
  172. m_fDirty = TRUE;
  173. }
  174. return *this;
  175. }
  176. //
  177. // MP Access (use operators where possible!)
  178. //
  179. #define MP_V(x) (x.m_value)
  180. #define MP_D(x) (x.m_fDirty)
  181. //
  182. // Common property types
  183. //
  184. typedef CMPProp<CBlob, CBlob&> MP_CBlob;
  185. typedef CMPProp<CString, LPCTSTR> MP_CString;
  186. typedef CMPProp<CStrPassword, CStrPassword&> MP_CStrPassword;
  187. typedef CMPProp<CStringListEx, CStringListEx &> MP_CStringListEx;
  188. typedef CMPProp<CILong, LONG> MP_CILong;
  189. typedef CMPProp<int, int> MP_int;
  190. typedef CMPProp<DWORD, DWORD> MP_DWORD;
  191. typedef CMPProp<BOOL, BOOL> MP_BOOL;
  192. typedef CMPProp<CMaskedDWORD, DWORD> MP_CMaskedDWORD;
  193. //
  194. // CODEWORK: Turns these into proper methods
  195. //
  196. #define BEGIN_META_WRITE()\
  197. { \
  198. HRESULT hr = S_OK; \
  199. do \
  200. { \
  201. m_dwaDirtyProps.RemoveAll(); \
  202. #define META_WRITE(id, value)\
  203. if(MP_D(value)) \
  204. { \
  205. if (!IsOpen()) \
  206. { \
  207. hr = OpenForWriting(); \
  208. if (FAILED(hr)) break; \
  209. } \
  210. hr = SetValue(id, MP_V(value)); \
  211. if (FAILED(hr)) break; \
  212. MP_D(value) = FALSE; \
  213. m_dwaDirtyProps.AddTail(id); \
  214. } \
  215. #define META_WRITE_INHERITANCE(id, value, foverride)\
  216. if(MP_D(value)) \
  217. { \
  218. if (!IsOpen()) \
  219. { \
  220. hr = OpenForWriting(); \
  221. if (FAILED(hr)) break; \
  222. } \
  223. hr = SetValue(id, MP_V(value), &foverride);\
  224. if (FAILED(hr)) break; \
  225. MP_D(value) = FALSE; \
  226. m_dwaDirtyProps.AddTail(id); \
  227. } \
  228. #define META_DELETE(id)\
  229. FlagPropertyForDeletion(id); \
  230. #define END_META_WRITE(err)\
  231. POSITION pos; \
  232. pos = m_dwaDeletedProps.GetHeadPosition();\
  233. while(pos != NULL) \
  234. { \
  235. DWORD dwID = m_dwaDeletedProps.GetNext(pos);\
  236. if (!IsOpen()) \
  237. { \
  238. hr = OpenForWriting(FALSE); \
  239. } \
  240. if (IsOpen() && SUCCEEDED(hr)) \
  241. { \
  242. TRACEEOLID("Deleting #" << dwID);\
  243. hr = DeleteValue(dwID); \
  244. m_dwaDirtyProps.AddTail(dwID); \
  245. } \
  246. } \
  247. m_dwaDeletedProps.RemoveAll(); \
  248. if (IsOpen()) Close(); \
  249. pos = m_dwaDirtyProps.GetHeadPosition();\
  250. hr = S_OK; \
  251. while(pos != NULL) \
  252. { \
  253. hr = CheckDescendants(m_dwaDirtyProps.GetNext(pos), &m_auth, m_strMetaRoot); \
  254. if (FAILED(hr)) break; \
  255. } \
  256. } \
  257. while(FALSE); \
  258. err = hr; \
  259. }
  260. /* ABSTRACT */ class CMetaProperties : public CMetaKey
  261. /*++
  262. Class Description:
  263. Abstract base class that reads all metadata at a specific
  264. metabase path.
  265. Public Interface:
  266. QueryResult : Get result code from construction
  267. QueryMetaPath : Get the metabase path
  268. Virtual Interface:
  269. ParseFields : Break up data into member variables
  270. --*/
  271. {
  272. //
  273. // Constructor/Destructor
  274. //
  275. protected:
  276. //
  277. // Constructor which creates new interface
  278. //
  279. CMetaProperties(
  280. IN CComAuthInfo * pAuthInfo,
  281. IN LPCTSTR lpszMDPath
  282. );
  283. //
  284. // Construct with existing interface
  285. //
  286. CMetaProperties(
  287. IN CMetaInterface * pInterface,
  288. IN LPCTSTR lpszMDPath
  289. );
  290. //
  291. // Construct with open key
  292. //
  293. CMetaProperties(
  294. IN CMetaKey * pKey,
  295. IN LPCTSTR lpszMDPath
  296. );
  297. //
  298. // Destructor
  299. //
  300. ~CMetaProperties();
  301. public:
  302. //
  303. // GetAllData()
  304. //
  305. virtual HRESULT LoadData();
  306. virtual HRESULT WriteDirtyProps();
  307. void FlagPropertyForDeletion(DWORD dwID);
  308. virtual HRESULT CMetaProperties::QueryResult() const;
  309. LPCTSTR QueryMetaRoot() const { return m_strMetaRoot; }
  310. protected:
  311. virtual void ParseFields() = 0;
  312. void Cleanup();
  313. HRESULT OpenForWriting(BOOL fCreate = TRUE);
  314. protected:
  315. BOOL m_fInherit;
  316. HRESULT m_hResult;
  317. CString m_strMetaRoot;
  318. DWORD m_dwMDUserType;
  319. DWORD m_dwMDDataType;
  320. CList<DWORD, DWORD> m_dwaDirtyProps;
  321. CList<DWORD, DWORD> m_dwaDeletedProps;
  322. //
  323. // Read all values
  324. //
  325. DWORD m_dwNumEntries;
  326. DWORD m_dwMDDataLen;
  327. PBYTE m_pbMDData;
  328. };
  329. //
  330. // Machine Properties object
  331. //
  332. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  333. class CMachineProps : public CMetaProperties
  334. /*++
  335. Class Description:
  336. Global machine properties
  337. Public Interface:
  338. CMachineProps : Constructor
  339. WriteDirtyProps : Write dirty properties
  340. --*/
  341. {
  342. public:
  343. CMachineProps(CComAuthInfo * pAuthInfo);
  344. CMachineProps(CMetaInterface * pInterface);
  345. public:
  346. HRESULT WriteDirtyProps();
  347. protected:
  348. virtual void ParseFields();
  349. public:
  350. MP_BOOL m_fEnableMetabaseEdit;
  351. MP_BOOL m_fUTF8Web;
  352. };
  353. //
  354. // Compression Properties Object
  355. //
  356. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  357. class CIISCompressionProps : public CMetaProperties
  358. /*++
  359. Class Description:
  360. Compression settings
  361. Public Interface:
  362. CIISCompressionProps : Constructor
  363. WriteIfDirty : Write data if dirty
  364. --*/
  365. {
  366. public:
  367. CIISCompressionProps(
  368. IN CComAuthInfo * pAuthInfo
  369. );
  370. public:
  371. //
  372. // Write Data if dirty
  373. //
  374. virtual HRESULT WriteDirtyProps();
  375. //
  376. // Load data
  377. //
  378. virtual HRESULT LoadData();
  379. public:
  380. MP_BOOL m_fEnableStaticCompression;
  381. MP_BOOL m_fEnableDynamicCompression;
  382. MP_BOOL m_fLimitDirectorySize;
  383. MP_DWORD m_dwDirectorySize;
  384. MP_CString m_strDirectory;
  385. protected:
  386. virtual void ParseFields();
  387. private:
  388. BOOL m_fPathDoesNotExist;
  389. };
  390. class CMimeTypes : public CMetaProperties
  391. /*++
  392. Class Description:
  393. A list of mime types.
  394. Public Interface:
  395. CMimeTypes : Constructor
  396. WriteIfDirty : Write properties if dirty
  397. --*/
  398. {
  399. public:
  400. //
  401. // Constructor that creates new interface
  402. //
  403. CMimeTypes(
  404. IN CComAuthInfo * pAuthInfo,
  405. IN LPCTSTR lpszMDPath
  406. );
  407. //
  408. // Constructor that uses an existing interface
  409. //
  410. CMimeTypes(
  411. IN CMetaInterface * pInterface,
  412. IN LPCTSTR lpszMDPath
  413. );
  414. public:
  415. //
  416. // Write the data;
  417. //
  418. virtual HRESULT WriteDirtyProps();
  419. protected:
  420. virtual void ParseFields();
  421. public:
  422. MP_CStringListEx m_strlMimeTypes;
  423. };
  424. class CServerCapabilities : public CMetaProperties
  425. /*++
  426. Class Description:
  427. Server capabilities object
  428. Public Interface:
  429. CServerCapabilities : Constructor
  430. --*/
  431. {
  432. public:
  433. //
  434. // Constructor that creates a new interface
  435. //
  436. CServerCapabilities(
  437. IN CComAuthInfo * pAuthInfo,
  438. IN LPCTSTR lpszMDPath // e.g. "lm/w3svc/info"
  439. );
  440. //
  441. // Constructor that uses an existing interface
  442. //
  443. CServerCapabilities(
  444. IN CMetaInterface * pInterface,
  445. IN LPCTSTR lpszMDPath // e.g. "lm/w3svc/info"
  446. );
  447. public:
  448. BOOL IsSSLSupported() const { return (m_dwCapabilities & IIS_CAP1_SSL_SUPPORT) != 0L; }
  449. BOOL IsSSL128Supported() const
  450. {
  451. if (m_dwVersionMajor >= 6)
  452. {
  453. // We have this feature ALWAYS enabled in iis6 and iis5.1
  454. return TRUE;
  455. }
  456. else if (m_dwVersionMajor == 5 && m_dwVersionMinor == 1)
  457. {
  458. return TRUE;
  459. }
  460. else
  461. {
  462. return (m_dwConfiguration & MD_SERVER_CONFIG_SSL_128) != 0L;
  463. }
  464. }
  465. BOOL HasMultipleSites() const { return (m_dwCapabilities & IIS_CAP1_MULTIPLE_INSTANCE) != 0L; }
  466. BOOL HasBwThrottling() const { return (m_dwCapabilities & IIS_CAP1_BW_THROTTLING) != 0L; }
  467. BOOL Has10ConnectionLimit() const { return (m_dwCapabilities & IIS_CAP1_10_CONNECTION_LIMIT) != 0L; }
  468. BOOL HasIPAccessCheck() const { return (m_dwCapabilities & IIS_CAP1_IP_ACCESS_CHECK) != 0L; }
  469. BOOL HasOperatorList() const { return (m_dwCapabilities & IIS_CAP1_OPERATORS_LIST) != 0L; }
  470. BOOL HasFrontPage() const { return (m_dwCapabilities & IIS_CAP1_FP_INSTALLED) != 0L; }
  471. BOOL HasCompression() const { return (m_dwCapabilities & IIS_CAP1_SERVER_COMPRESSION) != 0L; }
  472. BOOL HasCPUThrottling() const { return (m_dwCapabilities & IIS_CAP1_CPU_AUDITING) != 0L; }
  473. BOOL HasDigest() const { return (m_dwCapabilities & IIS_CAP1_DIGEST_SUPPORT) != 0L; }
  474. BOOL HasNTCertMapper() const { return (m_dwCapabilities & IIS_CAP1_NT_CERTMAP_SUPPORT) != 0L; }
  475. BOOL IsWorkstationLegacyCode() const
  476. {
  477. // workstation was determined this way in iis4/5/51
  478. if (Has10ConnectionLimit())
  479. {
  480. return TRUE;
  481. }
  482. else
  483. {
  484. return FALSE;
  485. }
  486. }
  487. BOOL IsWorkstation() const
  488. {
  489. if (m_dwVersionMajor >= 6)
  490. {
  491. if (INET_INFO_PRODUCT_NTWKSTA == m_dwPlatform)
  492. {
  493. return TRUE;
  494. }
  495. else
  496. {
  497. return FALSE;
  498. }
  499. }
  500. else
  501. {
  502. return IsWorkstationLegacyCode();
  503. }
  504. }
  505. BOOL IsCompressionConfigurable() const
  506. {
  507. if (m_dwVersionMajor >= 6)
  508. {
  509. // Compression is configurable for workstation and server in iis6
  510. if (IsWorkstation())
  511. {
  512. return TRUE;
  513. }
  514. else
  515. {
  516. return TRUE;
  517. }
  518. }
  519. else
  520. {
  521. // Compression is not configurable for workstation in pre iis6
  522. if (IsWorkstationLegacyCode())
  523. {
  524. return FALSE;
  525. }
  526. else
  527. {
  528. return TRUE;
  529. }
  530. }
  531. }
  532. BOOL IsPerformanceConfigurable() const
  533. {
  534. if (m_dwVersionMajor >= 6)
  535. {
  536. // Performance is not configurable for workstation in iis6
  537. if (IsWorkstation())
  538. {
  539. return FALSE;
  540. }
  541. else
  542. {
  543. return TRUE;
  544. }
  545. }
  546. else
  547. {
  548. // Performance is not configurable for workstation in pre iis6
  549. if (IsWorkstationLegacyCode())
  550. {
  551. return FALSE;
  552. }
  553. else
  554. {
  555. return TRUE;
  556. }
  557. }
  558. }
  559. BOOL IsServiceLevelConfigurable() const
  560. {
  561. if (m_dwVersionMajor >= 6)
  562. {
  563. // service level is configurable for workstation and server in iis6
  564. if (IsWorkstation())
  565. {
  566. return TRUE;
  567. }
  568. else
  569. {
  570. return TRUE;
  571. }
  572. }
  573. else
  574. {
  575. // Performance is not configurable for workstation in pre iis6
  576. if (IsWorkstationLegacyCode())
  577. {
  578. return FALSE;
  579. }
  580. else
  581. {
  582. return TRUE;
  583. }
  584. }
  585. }
  586. DWORD QueryMajorVersion() const { return m_dwVersionMajor; }
  587. DWORD QueryMinorVersion() const { return m_dwVersionMinor; }
  588. protected:
  589. virtual void ParseFields();
  590. private:
  591. //
  592. // Capabilities fields
  593. //
  594. MP_DWORD m_dwPlatform;
  595. MP_DWORD m_dwVersionMajor;
  596. MP_DWORD m_dwVersionMinor;
  597. MP_DWORD m_dwCapabilities;
  598. MP_DWORD m_dwConfiguration;
  599. };
  600. class CInstanceProps : public CMetaProperties
  601. /*++
  602. Class Description:
  603. Generic instance properties. Construct with lightweight = TRUE
  604. to fetch enough information for enumeration only.
  605. Public Interface:
  606. CInstanceProps: : Constructor
  607. Add : static method to create new instance
  608. Remove : static method to remove instance
  609. ChangeState : Change the state of a property
  610. QueryError : Get the win32 error
  611. GetDisplayText : Generate display name of instance
  612. --*/
  613. {
  614. public:
  615. //
  616. // Public method to convert instance info to display text
  617. //
  618. static LPCTSTR GetDisplayText(
  619. OUT CString & strName,
  620. IN LPCTSTR szComment,
  621. IN LPCTSTR szHostHeaderName,
  622. //IN LPCTSTR szServiceName,
  623. IN CIPAddress & ia,
  624. IN UINT uPort,
  625. IN DWORD dwID
  626. );
  627. public:
  628. //
  629. // Constructor that creates an interface
  630. //
  631. CInstanceProps(
  632. IN CComAuthInfo * pAuthInfo,
  633. IN LPCTSTR lpszMDPath,
  634. IN UINT nDefPort = 0U
  635. );
  636. //
  637. // Constructor that reuses existing interface
  638. //
  639. CInstanceProps(
  640. IN CMetaInterface * pInterface,
  641. IN LPCTSTR lpszMDPath,
  642. IN UINT nDefPort = 0U
  643. );
  644. //
  645. // Special constructor that uses an open parent key,
  646. // and uses a relative path off the open key.
  647. //
  648. CInstanceProps(
  649. IN CMetaKey * pKey,
  650. IN LPCTSTR lpszMDPath,
  651. IN DWORD dwInstance,
  652. IN UINT nDefPort = 0U
  653. );
  654. public:
  655. //
  656. // Parse the binding string into component parts
  657. //
  658. static void CrackBinding(
  659. IN CString lpszBinding,
  660. OUT CIPAddress & iaIpAddress,
  661. OUT UINT & nTCPPort,
  662. OUT CString & strDomainName
  663. );
  664. //
  665. // Parse the secure binding string into component parts
  666. //
  667. static void CrackSecureBinding(
  668. IN CString lpszBinding,
  669. OUT CIPAddress & iaIpAddress,
  670. OUT UINT & nSSLPort
  671. );
  672. //
  673. // Find the SSL port applicable to the given
  674. // IP Address. Return the index where this SSL port
  675. // was found, or -1 if it was not found.
  676. //
  677. static int FindMatchingSecurePort(
  678. IN CStringList & strlBindings,
  679. IN CIPAddress & iaIpAddress,
  680. OUT UINT & m_nSSLPort
  681. );
  682. //
  683. // Find ip address/port combo
  684. //
  685. static BOOL IsPortInUse(
  686. IN CStringList & strlBindings,
  687. IN CIPAddress & iaIPAddress,
  688. IN UINT nPort
  689. );
  690. //
  691. // Build binding string
  692. //
  693. static void BuildBinding(
  694. OUT CString & strBinding,
  695. IN CIPAddress & iaIpAddress,
  696. IN UINT & nTCPPort,
  697. IN CString & lpszDomainName
  698. );
  699. //
  700. // Build secure binding string
  701. //
  702. static void BuildSecureBinding(
  703. OUT CString & strBinding,
  704. IN CIPAddress & iaIpAddress,
  705. IN UINT & nSSLPort
  706. );
  707. //
  708. // Create new instance
  709. //
  710. static HRESULT Add(
  711. IN CMetaInterface * pInterface,
  712. IN LPCTSTR lpszService,
  713. IN LPCTSTR lpszHomePath,
  714. IN LPCTSTR lpszUserName = NULL,
  715. IN LPCTSTR lpszPassword = NULL,
  716. IN LPCTSTR lpszDescription = NULL,
  717. IN LPCTSTR lpszBinding = NULL,
  718. IN LPCTSTR lpszSecureBinding = NULL,
  719. IN DWORD * pdwPermissions = NULL,
  720. IN DWORD * pdwDirBrowsing = NULL,
  721. IN DWORD * pwdAuthFlags = NULL,
  722. OUT DWORD * pdwInstance = NULL
  723. );
  724. //
  725. // Remove existing instance
  726. //
  727. static HRESULT Delete(
  728. IN CMetaInterface * pInterface,
  729. IN LPCTSTR lpszService,
  730. IN DWORD dwInstance
  731. );
  732. //
  733. // Access
  734. //
  735. public:
  736. //
  737. // Change the running state of the instance
  738. //
  739. HRESULT ChangeState(
  740. IN DWORD dwCommand
  741. );
  742. //
  743. // Get the WIN32 error
  744. //
  745. DWORD QueryError() const { return m_dwWin32Error; }
  746. //
  747. // Get the instance number
  748. //
  749. DWORD QueryInstance() const { return m_dwInstance; }
  750. //
  751. // Check to see if this is a cluster enabled instance
  752. //
  753. BOOL IsClusterEnabled() const { return m_fCluster; }
  754. //
  755. // Get the friendly name for this instance
  756. //
  757. LPCTSTR GetDisplayText(
  758. OUT CString & strName
  759. //IN LPCTSTR szServiceName
  760. );
  761. //
  762. // Get the complete metabase path to the home directory
  763. //
  764. LPCTSTR GetHomePath(OUT CString & str);
  765. //
  766. // Write Data if dirty
  767. //
  768. virtual HRESULT WriteDirtyProps();
  769. protected:
  770. virtual void ParseFields();
  771. public:
  772. //
  773. // Meta values
  774. //
  775. MP_BOOL m_fCluster;
  776. MP_CStringListEx m_strlBindings;
  777. MP_CString m_strComment;
  778. MP_DWORD m_dwState;
  779. MP_DWORD m_dwWin32Error;
  780. //
  781. // Derived Values
  782. //
  783. UINT m_nTCPPort;
  784. CIPAddress m_iaIpAddress;
  785. CString m_strDomainName;
  786. private:
  787. DWORD m_dwInstance;
  788. };
  789. class CChildNodeProps : public CMetaProperties
  790. /*++
  791. Class Description:
  792. Generic child node properties. Could be a vdir, a dir
  793. or a file.
  794. Public Interface:
  795. CChildNodeProps : Constructor
  796. Add : Create new virtual directory
  797. Delete : Delete virtual directory
  798. Rename : Rename virtual directory
  799. QueryError : Get the win32 error
  800. IsPathInherited : Return TRUE if the path was inherited
  801. FillInstanceInfo : Fill instance info structure
  802. FillChildInfo : Fill child info structure
  803. --*/
  804. {
  805. public:
  806. //
  807. // Constructors
  808. //
  809. CChildNodeProps(
  810. IN CComAuthInfo * pAuthInfo,
  811. IN LPCTSTR lpszMDPath,
  812. IN BOOL fInherit = WITHOUT_INHERITANCE,
  813. IN BOOL fPathOnly = FALSE
  814. );
  815. CChildNodeProps(
  816. IN CMetaInterface * pInterface,
  817. IN LPCTSTR lpszMDPath,
  818. IN BOOL fInherit = WITHOUT_INHERITANCE,
  819. IN BOOL fPathOnly = FALSE
  820. );
  821. CChildNodeProps(
  822. IN CMetaKey * pKey,
  823. IN LPCTSTR lpszPath = NULL,
  824. IN BOOL fInherit = WITHOUT_INHERITANCE,
  825. IN BOOL fPathOnly = FALSE
  826. );
  827. public:
  828. //
  829. // Create new virtual directory
  830. //
  831. static HRESULT Add(
  832. IN CMetaInterface * pInterface,
  833. IN LPCTSTR lpszParentPath,
  834. /*
  835. IN LPCTSTR lpszService,
  836. IN DWORD dwInstance,
  837. IN LPCTSTR lpszParentPath,
  838. */
  839. IN LPCTSTR lpszAlias,
  840. OUT CString & strAliasCreated,
  841. IN DWORD * pdwPermissions = NULL,
  842. IN DWORD * pdwDirBrowsing = NULL,
  843. IN LPCTSTR lpszVrPath = NULL,
  844. IN LPCTSTR lpszUserName = NULL,
  845. IN LPCTSTR lpszPassword = NULL,
  846. IN BOOL fExactName = TRUE
  847. );
  848. //
  849. // Delete virtual directory
  850. //
  851. static HRESULT Delete(
  852. IN CMetaInterface * pInterface,
  853. IN LPCTSTR lpszParentPath, OPTIONAL
  854. IN LPCTSTR lpszNode
  855. );
  856. //
  857. // Rename virtual directory
  858. //
  859. static HRESULT Rename(
  860. IN CMetaInterface * pInterface,
  861. IN LPCTSTR lpszParentPath, OPTIONAL
  862. IN LPCTSTR lpszOldName,
  863. IN LPCTSTR lpszNewName
  864. );
  865. public:
  866. //
  867. // TRUE, if this is an enabled application
  868. //
  869. BOOL IsEnabledApplication() { return m_fIsAppRoot; }
  870. //
  871. // Get the alias name
  872. //
  873. LPCTSTR QueryAlias() const { return m_strAlias; }
  874. //CString & GetAlias() { return m_strAlias; }
  875. //
  876. // Get the error
  877. //
  878. DWORD QueryWin32Error() const { return m_dwWin32Error; }
  879. //
  880. // This is how to separate file/dir props from vdirs
  881. //
  882. BOOL IsPathInherited() const { return m_fPathInherited; }
  883. //
  884. // Empty the path if it was inherited
  885. //
  886. void RemovePathIfInherited();
  887. //
  888. // CODEWORK: Ugly solution.
  889. //
  890. // Call this method to override the inheritance status of the
  891. // http redirect path
  892. //
  893. void MarkRedirAsInherit(BOOL fInherit) { m_fInheritRedirect = fInherit; }
  894. //
  895. // Get the path
  896. //
  897. CString & GetPath() { return MP_V(m_strPath); }
  898. //
  899. // Get the redirected path
  900. //
  901. CString & GetRedirectedPath() { return m_strRedirectPath; }
  902. //
  903. // Get the access perms
  904. //
  905. DWORD QueryAccessPerms() const { return m_dwAccessPerms; }
  906. //
  907. // Get dir browsing bits
  908. //
  909. DWORD QueryDirBrowsing() const { return m_dwDirBrowsing; }
  910. //
  911. // True if the child is redirected
  912. //
  913. BOOL IsRedirected() const { return !m_strRedirectPath.IsEmpty(); }
  914. //
  915. // Write Data if dirty
  916. //
  917. virtual HRESULT WriteDirtyProps();
  918. protected:
  919. //
  920. // Break out GetAllData() data to data fields
  921. //
  922. virtual void ParseFields();
  923. //
  924. // Break down redirect statement into component paths
  925. //
  926. void ParseRedirectStatement();
  927. //
  928. // Reverse the above -- reassemble the redirect statement
  929. //
  930. void BuildRedirectStatement();
  931. protected:
  932. //
  933. // Redirect tags
  934. //
  935. static const TCHAR _chTagSep;
  936. static const LPCTSTR _cszExactDestination;
  937. static const LPCTSTR _cszChildOnly;
  938. static const LPCTSTR _cszPermanent;
  939. public:
  940. BOOL m_fIsAppRoot;
  941. BOOL m_fPathInherited;
  942. BOOL m_fInheritRedirect;
  943. BOOL m_fExact; // Redirect tag
  944. BOOL m_fChild; // Redirect tag
  945. BOOL m_fPermanent; // Redirect tag
  946. CString m_strAlias;
  947. CString m_strFullMetaPath;
  948. CString m_strRedirectPath; // Redirect _path_
  949. public:
  950. MP_BOOL m_fAppIsolated;
  951. MP_DWORD m_dwWin32Error;
  952. MP_DWORD m_dwDirBrowsing;
  953. MP_CString m_strPath;
  954. MP_CString m_strRedirectStatement; // Path + tags
  955. MP_CString m_strAppRoot;
  956. MP_CMaskedDWORD m_dwAccessPerms;
  957. };
  958. inline CMetaKey * GetMetaKeyFromHandle(IN HANDLE hServer)
  959. {
  960. ASSERT(hServer != NULL);
  961. return (CMetaKey *)hServer;
  962. }
  963. inline LPCTSTR GetServerNameFromHandle(IN HANDLE hServer)
  964. {
  965. ASSERT(hServer != NULL);
  966. return ((CMetaKey *)hServer)->QueryServerName();
  967. }
  968. //
  969. // Metabase Helpers
  970. //
  971. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  972. //
  973. // Get record data size
  974. //
  975. inline DWORD RecordDataSize(
  976. IN METADATA_GETALL_RECORD * pAllRecord,
  977. IN int iIndex
  978. )
  979. {
  980. return pAllRecord[iIndex].dwMDDataLen;
  981. }
  982. //
  983. // Fetch data at index as DWORD
  984. //
  985. inline void FetchMetaValue(
  986. IN METADATA_GETALL_RECORD * pAllRecord,
  987. IN int iIndex,
  988. OUT DWORD & dwValue
  989. )
  990. {
  991. ASSERT(RecordDataSize(pAllRecord, iIndex) == sizeof(DWORD));
  992. dwValue = *((UNALIGNED DWORD *)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset));
  993. }
  994. //
  995. // Fetch data at index as UINT
  996. //
  997. inline void FetchMetaValue(
  998. IN METADATA_GETALL_RECORD * pAllRecord,
  999. IN int iIndex,
  1000. OUT UINT & uValue
  1001. )
  1002. {
  1003. ASSERT(RecordDataSize(pAllRecord, iIndex) == sizeof(DWORD));
  1004. uValue = (UINT)*((UNALIGNED DWORD *)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset));
  1005. }
  1006. //
  1007. // Fetch data at index as int
  1008. //
  1009. inline void FetchMetaValue(
  1010. IN METADATA_GETALL_RECORD * pAllRecord,
  1011. IN int iIndex,
  1012. OUT int & iValue
  1013. )
  1014. {
  1015. ASSERT(RecordDataSize(pAllRecord, iIndex) == sizeof(DWORD));
  1016. iValue = (int)*((UNALIGNED DWORD *)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset));
  1017. }
  1018. //
  1019. // Fetch data at index as a CString
  1020. //
  1021. inline void FetchMetaValue(
  1022. IN METADATA_GETALL_RECORD * pAllRecord,
  1023. IN int iIndex,
  1024. OUT CString & strValue
  1025. )
  1026. {
  1027. strValue = (LPTSTR)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset);
  1028. }
  1029. //
  1030. // Fetch data at index as a CStrPassword
  1031. //
  1032. inline void FetchMetaValue(
  1033. IN METADATA_GETALL_RECORD * pAllRecord,
  1034. IN int iIndex,
  1035. OUT CStrPassword & strValue
  1036. )
  1037. {
  1038. strValue = (LPTSTR)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset);
  1039. }
  1040. //
  1041. // Fetch data at index as a CStringList
  1042. //
  1043. inline void FetchMetaValue(
  1044. IN METADATA_GETALL_RECORD * pAllRecord,
  1045. IN int iIndex,
  1046. OUT CStringList & strlValue
  1047. )
  1048. {
  1049. ConvertDoubleNullListToStringList(
  1050. ((LPCTSTR)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset)),
  1051. strlValue,
  1052. (RecordDataSize(pAllRecord, iIndex)) / sizeof(TCHAR)
  1053. );
  1054. }
  1055. //
  1056. // Fetch binary data as a blob
  1057. //
  1058. inline void FetchMetaValue(
  1059. IN METADATA_GETALL_RECORD * pAllRecord,
  1060. IN int iIndex,
  1061. OUT CBlob & blob
  1062. )
  1063. {
  1064. blob.SetValue(
  1065. RecordDataSize(pAllRecord, iIndex),
  1066. ((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset));
  1067. }
  1068. inline void FetchMetaValue(
  1069. IN METADATA_GETALL_RECORD * pAllRecord,
  1070. IN int iIndex,
  1071. OUT CILong & ilValue
  1072. )
  1073. {
  1074. ilValue = (LONG)*((UNALIGNED DWORD *)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset));
  1075. }
  1076. //
  1077. // Fetch data at index as CString, and check inheritance status
  1078. //
  1079. inline void FetchInheritedMetaValue(
  1080. IN METADATA_GETALL_RECORD * pAllRecord,
  1081. IN int iIndex,
  1082. OUT CString & strValue,
  1083. OUT BOOL & fIsInherited
  1084. )
  1085. {
  1086. strValue = (LPTSTR)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset);
  1087. fIsInherited = (pAllRecord[iIndex].dwMDAttributes & METADATA_ISINHERITED) != 0;
  1088. }
  1089. //
  1090. // Fetch data at index as CStrPassword, and check inheritance status
  1091. //
  1092. inline void FetchInheritedMetaValue(
  1093. IN METADATA_GETALL_RECORD * pAllRecord,
  1094. IN int iIndex,
  1095. OUT CStrPassword & strValue,
  1096. OUT BOOL & fIsInherited
  1097. )
  1098. {
  1099. strValue = (LPTSTR)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset);
  1100. fIsInherited = (pAllRecord[iIndex].dwMDAttributes & METADATA_ISINHERITED) != 0;
  1101. }
  1102. //
  1103. // Fetch data at index as CStringListEx, and check inheritance status
  1104. //
  1105. inline void FetchInheritedMetaValue(
  1106. IN METADATA_GETALL_RECORD * pAllRecord,
  1107. IN int iIndex,
  1108. OUT CStringListEx & strlValue,
  1109. OUT BOOL & fIsInherited
  1110. )
  1111. {
  1112. ConvertDoubleNullListToStringList(
  1113. ((LPCTSTR)((PBYTE)pAllRecord + pAllRecord[iIndex].dwMDDataOffset)),
  1114. strlValue,
  1115. (RecordDataSize(pAllRecord, iIndex)) / sizeof(TCHAR)
  1116. );
  1117. fIsInherited = (pAllRecord[iIndex].dwMDAttributes & METADATA_ISINHERITED) != 0;
  1118. }
  1119. //
  1120. // Flag Operations
  1121. //
  1122. #define IS_FLAG_SET(dw, flag) ((((dw) & (flag)) != 0) ? TRUE : FALSE)
  1123. #define SET_FLAG(dw, flag) dw |= (flag)
  1124. #define RESET_FLAG(dw, flag) dw &= ~(flag)
  1125. #define SET_FLAG_IF(cond, dw, flag)\
  1126. if (cond) \
  1127. { \
  1128. SET_FLAG(dw, flag); \
  1129. } \
  1130. else \
  1131. { \
  1132. RESET_FLAG(dw, flag); \
  1133. }
  1134. //
  1135. // Meta record crackers
  1136. //
  1137. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1138. #define BEGIN_PARSE_META_RECORDS(dwNumEntries, pbMDData)\
  1139. { \
  1140. METADATA_GETALL_RECORD * pAllRecords = \
  1141. (METADATA_GETALL_RECORD *)pbMDData; \
  1142. ASSERT(pAllRecords != NULL); \
  1143. \
  1144. for (DWORD i = 0; i < dwNumEntries; ++i) \
  1145. { \
  1146. METADATA_GETALL_RECORD * pRec = &pAllRecords[i];\
  1147. switch(pRec->dwMDIdentifier) \
  1148. {
  1149. #define HANDLE_META_RECORD(id, value)\
  1150. case id: \
  1151. FetchMetaValue(pAllRecords, i, MP_V(value));\
  1152. break;
  1153. #define HANDLE_INHERITED_META_RECORD(id, value, fIsInherited)\
  1154. case id: \
  1155. FetchInheritedMetaValue(pAllRecords, i, MP_V(value), fIsInherited);\
  1156. break;
  1157. #define END_PARSE_META_RECORDS\
  1158. } \
  1159. } \
  1160. }
  1161. //
  1162. // Sheet -> page crackers
  1163. //
  1164. #define BEGIN_META_INST_READ(sheet)\
  1165. { \
  1166. sheet * pSheet = (sheet *)GetSheet(); \
  1167. do \
  1168. { \
  1169. if (FAILED(pSheet->QueryInstanceResult())) \
  1170. { \
  1171. break; \
  1172. }
  1173. #define FETCH_INST_DATA_FROM_SHEET(value)\
  1174. value = pSheet->GetInstanceProperties().value; \
  1175. TRACEEOLID(value);
  1176. #define FETCH_INST_DATA_FROM_SHEET_PASSWORD(value)\
  1177. value = pSheet->GetInstanceProperties().value;
  1178. #define END_META_INST_READ(err)\
  1179. \
  1180. } \
  1181. while(FALSE); \
  1182. }
  1183. #define BEGIN_META_DIR_READ(sheet)\
  1184. { \
  1185. sheet * pSheet = (sheet *)GetSheet(); \
  1186. do \
  1187. { \
  1188. if (FAILED(pSheet->QueryDirectoryResult())) \
  1189. { \
  1190. break; \
  1191. }
  1192. #define FETCH_DIR_DATA_FROM_SHEET(value)\
  1193. value = pSheet->GetDirectoryProperties().value; \
  1194. TRACEEOLID(value);
  1195. #define FETCH_DIR_DATA_FROM_SHEET_PASSWORD(value)\
  1196. value = pSheet->GetDirectoryProperties().value;
  1197. #define END_META_DIR_READ(err)\
  1198. \
  1199. } \
  1200. while(FALSE); \
  1201. }
  1202. #define BEGIN_META_INST_WRITE(sheet)\
  1203. { \
  1204. sheet * pSheet = (sheet *)GetSheet(); \
  1205. \
  1206. do \
  1207. { \
  1208. #define STORE_INST_DATA_ON_SHEET(value)\
  1209. pSheet->GetInstanceProperties().value = value;
  1210. #define STORE_INST_DATA_ON_SHEET_REMEMBER(value, dirty)\
  1211. pSheet->GetInstanceProperties().value = value; \
  1212. dirty = MP_D(((sheet *)GetSheet())->GetInstanceProperties().value);
  1213. #define FLAG_INST_DATA_FOR_DELETION(id)\
  1214. pSheet->GetInstanceProperties().FlagPropertyForDeletion(id);
  1215. #define END_META_INST_WRITE(err)\
  1216. \
  1217. } \
  1218. while(FALSE); \
  1219. \
  1220. err = pSheet->GetInstanceProperties().WriteDirtyProps(); \
  1221. }
  1222. #define BEGIN_META_DIR_WRITE(sheet)\
  1223. { \
  1224. sheet * pSheet = (sheet *)GetSheet(); \
  1225. \
  1226. do \
  1227. { \
  1228. #define STORE_DIR_DATA_ON_SHEET(value)\
  1229. pSheet->GetDirectoryProperties().value = value;
  1230. #define STORE_DIR_DATA_ON_SHEET_REMEMBER(value, dirty)\
  1231. pSheet->GetDirectoryProperties().value = value; \
  1232. dirty = MP_D(pSheet->GetDirectoryProperties().value);
  1233. #define INIT_DIR_DATA_MASK(value, mask)\
  1234. MP_V(pSheet->GetDirectoryProperties().value).SetMask(mask);
  1235. #define FLAG_DIR_DATA_FOR_DELETION(id)\
  1236. pSheet->GetDirectoryProperties().FlagPropertyForDeletion(id);
  1237. #define END_META_DIR_WRITE(err)\
  1238. \
  1239. } \
  1240. while(FALSE); \
  1241. \
  1242. err = pSheet->GetDirectoryProperties().WriteDirtyProps(); \
  1243. }
  1244. //
  1245. // Inline Expansion
  1246. //
  1247. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1248. inline BOOL CMaskedDWORD::operator ==(DWORD dwValue) const
  1249. {
  1250. return (m_dwValue & m_dwMask) == (dwValue & m_dwMask);
  1251. }
  1252. inline CMaskedDWORD & CMaskedDWORD::operator =(DWORD dwValue)
  1253. {
  1254. m_dwValue = ((m_dwValue &= ~m_dwMask) |= (dwValue & m_dwMask));
  1255. return *this;
  1256. }
  1257. inline /*virtual */ HRESULT CMetaProperties::WriteDirtyProps()
  1258. {
  1259. ASSERT_MSG("Not implemented");
  1260. return E_NOTIMPL;
  1261. }
  1262. inline void CMetaProperties::FlagPropertyForDeletion(DWORD dwID)
  1263. {
  1264. m_dwaDeletedProps.AddTail(dwID);
  1265. }
  1266. inline LPCTSTR CInstanceProps::GetDisplayText(
  1267. OUT CString & strName
  1268. //IN LPCTSTR szServiceName
  1269. )
  1270. {
  1271. return CInstanceProps::GetDisplayText(
  1272. strName,
  1273. m_strComment,
  1274. m_strDomainName,
  1275. //szServiceName,
  1276. m_iaIpAddress,
  1277. m_nTCPPort,
  1278. QueryInstance()
  1279. );
  1280. }
  1281. inline LPCTSTR CInstanceProps::GetHomePath(CString & str)
  1282. {
  1283. str = m_strMetaRoot + SZ_MBN_SEP_STR + g_cszRoot;
  1284. return str;
  1285. }
  1286. inline void CChildNodeProps::RemovePathIfInherited()
  1287. {
  1288. if (IsPathInherited())
  1289. {
  1290. MP_V(m_strPath).Empty();
  1291. }
  1292. }
  1293. /*
  1294. inline void CChildNodeProps::FillInstanceInfo(ISMINSTANCEINFO * pii)
  1295. {
  1296. _tcsncpy(pii->szPath, GetPath(), STRSIZE(pii->szPath));
  1297. _tcsncpy(pii->szRedirPath, GetRedirectedPath(), STRSIZE(pii->szRedirPath));
  1298. pii->fChildOnlyRedir = m_fChild;
  1299. }
  1300. inline void CChildNodeProps::FillChildInfo(ISMCHILDINFO * pii)
  1301. {
  1302. //
  1303. // Set the output structure
  1304. //
  1305. pii->fInheritedPath = IsPathInherited();
  1306. pii->fEnabledApplication = IsEnabledApplication();
  1307. pii->dwError = QueryWin32Error();
  1308. _tcsncpy(
  1309. pii->szAlias,
  1310. GetAlias(),
  1311. STRSIZE(pii->szAlias)
  1312. );
  1313. _tcsncpy(
  1314. pii->szPath,
  1315. GetPath(),
  1316. STRSIZE(pii->szPath)
  1317. );
  1318. _tcsncpy(
  1319. pii->szRedirPath,
  1320. IsRedirected() ? GetRedirectedPath() : _T(""),
  1321. STRSIZE(pii->szRedirPath)
  1322. );
  1323. pii->fChildOnlyRedir = m_fChild;
  1324. }
  1325. */
  1326. #endif // _INETPROP_H_