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.

829 lines
37 KiB

  1. /*==============================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. File: template.h
  6. Maintained by: DaveK
  7. Component: include file for Denali Compiled Template object
  8. ==============================================================================*/
  9. #ifndef _TEMPLATE_H
  10. #define _TEMPLATE_H
  11. #include "vector.h"
  12. #include "LinkHash.h"
  13. #include "Compcol.h"
  14. #include "util.h"
  15. #include "activdbg.h"
  16. #include "ConnPt.h"
  17. #include "DblLink.h"
  18. #include "aspdmon.h"
  19. #include "ie449.h"
  20. #include "memcls.h"
  21. #define PER_TEMPLATE_REFLOG 0
  22. /* NOTE we ensure that C_COUNTS_IN_HEADER is a multiple of 4 because the offsets which follow
  23. the counts in template header are dword-aligned. It is easiest (and fastest at runtime)
  24. to make sure those offsets start on a dword-alignment point; thus no runtime alignment calc
  25. is needed in GetAddress().
  26. */
  27. #define C_REAL_COUNTS_IN_HEADER 3 // actual number of count fields in template header
  28. #define C_COUNTS_IN_HEADER (C_REAL_COUNTS_IN_HEADER/4 + 1) * 4 // allocated number of count fields in template header
  29. #define C_OFFOFFS_IN_HEADER 4 // number of 'ptr-to-ptr' fields in template header
  30. #define CB_TEMPLATE_DEFAULT 2500 // default memory allocation for new template
  31. #define C_TARGET_LINES_DEFAULT 50 // default count of target script lines per engine
  32. #define C_TEMPLATES_PER_INCFILE_DEFAULT 4 // default count of templates per inc-file
  33. #define SZ_NULL "\0"
  34. #define WSTR_NULL L"\0"
  35. #define SZ_NEWLINE "\r\n"
  36. #define WSZ_NEWLINE L"\r\n"
  37. const unsigned CB_NEWLINE = strlen(SZ_NEWLINE);
  38. const LPSTR g_szWriteBlockOpen = "Response.WriteBlock(";
  39. const LPSTR g_szWriteBlockClose = ")";
  40. const LPSTR g_szWriteOpen = "Response.Write(";
  41. const LPSTR g_szWriteClose = ")";
  42. // defaults for buffering interim compile results
  43. #define C_SCRIPTENGINESDEFAULT 2 // default count of script engines
  44. #define C_SCRIPTSEGMENTSDEFAULT 20 // default count of script segments
  45. #define C_OBJECTINFOS_DEFAULT 10 // default count of object-infos
  46. #define C_HTMLSEGMENTSDEFAULT 20 // default count of HTML segments
  47. #define C_INCLUDELINESDEFAULT 5 // default count of include lines
  48. #define CB_TOKENS_DEFAULT 400 // default byte count for tokens
  49. #define CH_ATTRIBUTE_SEPARATOR '=' // separator for attribute-value pair
  50. #define CH_SINGLE_QUOTE '\'' // single-quote character
  51. #define CH_DOUBLE_QUOTE '"' // double-quote character
  52. #define CH_ESCAPE '\\' // escape character - tells us to ignore following token
  53. // ACLs: the following code should in future be shared with IIS (see creatfil.cxx in IIS project)
  54. // NOTE we want SECURITY_DESC_DEFAULT_SIZE to be relatively small, since it affects template memory reqt dramatically
  55. #define SECURITY_DESC_GRANULARITY 128 // 'chunk' size for re-sizing file security descriptor
  56. #define SECURITY_DESC_DEFAULT_SIZE 256 // initial default size of file security descriptor
  57. #define SIZE_PRIVILEGE_SET 128 // size of privilege set
  58. // macros
  59. // use outside of CTokenList class
  60. #define SZ_TOKEN(i) (*gm_pTokenList).m_bufTokens.PszLocal(i)
  61. #define CCH_TOKEN(i) (*gm_pTokenList)[i]->m_cb
  62. #define _TOKEN CTemplate::CTokenList::TOKEN
  63. // use within CTokenList class
  64. #define CCH_TOKEN_X(i) (*this)[i]->m_cb
  65. #define BR_TOKEN_X(i) *((*this)[i])
  66. // Use to specify which source file name you want (pathInfo or pathTranslated)
  67. #ifndef _SRCPATHTYPE_DEFINED
  68. #define _SRCPATHTYPE_DEFINED
  69. enum SOURCEPATHTYPE
  70. {
  71. SOURCEPATHTYPE_VIRTUAL = 0,
  72. SOURCEPATHTYPE_PHYSICAL = 1
  73. };
  74. #endif
  75. // CTemplate error codes
  76. #define E_COULDNT_OPEN_SOURCE_FILE 0x8000D001L
  77. #define E_SOURCE_FILE_IS_EMPTY 0x8000D002L
  78. #define E_TEMPLATE_COMPILE_FAILED 0x8000D003L
  79. #define E_USER_LACKS_PERMISSIONS 0x8000D004L
  80. #define E_TEMPLATE_COMPILE_FAILED_DONT_CACHE 0x8000D005L
  81. #define E_TEMPLATE_MAGIC_FAILURE 0x8000D006L
  82. inline BOOL FIsPreprocessorError(HRESULT hr)
  83. {
  84. return
  85. (
  86. hr == E_SOURCE_FILE_IS_EMPTY ||
  87. hr == E_TEMPLATE_COMPILE_FAILED ||
  88. hr == E_TEMPLATE_COMPILE_FAILED_DONT_CACHE ||
  89. hr == E_TEMPLATE_MAGIC_FAILURE
  90. );
  91. }
  92. //Can not use same index as CErrorInfo anymore.
  93. //Index for lastErrorInfo in Template
  94. #define ILE_szFileName 0
  95. #define ILE_szLineNum 1
  96. #define ILE_szEngine 2
  97. #define ILE_szErrorCode 3
  98. #define ILE_szShortDes 4
  99. #define ILE_szLongDes 5
  100. #define ILE_MAX 6
  101. // forward references
  102. class CTemplate;
  103. class CTemplateCacheManager;
  104. class CHitObj;
  105. class CTokenList;
  106. class CIncFile;
  107. typedef CLSID PROGLANG_ID; // NOTE also defined in scrptmgr.h; we define here to avoid include file circularity
  108. /* ============================================================================
  109. Class: CByteRange
  110. Synopsis: A range of bytes
  111. NOTE fLocal member is only used if the byte range is stored in a CBuffer
  112. NOTE 2
  113. m_pfilemap is really a pointer to a CFileMap - however, it's impossible
  114. to declare that type here because the CFileMap struct is nested inside
  115. CTemplate, and C++ won't let you forward declare nested classes. Since
  116. the CTemplate definition depends on CByteRange, properly declaring the
  117. type of "m_pfilemap" is impossible.
  118. */
  119. class CByteRange
  120. {
  121. public:
  122. BYTE* m_pb; // ptr to bytes
  123. ULONG m_cb; // count of bytes
  124. ULONG m_fLocal:1; // whether bytes are stored in buffer (TRUE) or elsewhere (FALSE)
  125. UINT m_idSequence:31; // byte range's sequence id
  126. void* m_pfilemap; // file the byte range comes from
  127. CByteRange(): m_pb(NULL), m_cb(0), m_fLocal(FALSE), m_idSequence(0), m_pfilemap(NULL) {}
  128. CByteRange(BYTE* pb, ULONG cb): m_fLocal(FALSE), m_idSequence(0) {m_pb = pb; m_cb = cb;}
  129. BOOLB IsNull() { return((m_pb == NULL) || (m_cb == 0)) ; }
  130. void Nullify() { m_pb = NULL; m_cb = 0; }
  131. void operator=(const CByteRange& br)
  132. { m_pb = br.m_pb; m_cb = br.m_cb; m_fLocal = br.m_fLocal; m_idSequence = br.m_idSequence; }
  133. BOOLB FMatchesSz(LPCSTR psz);
  134. void Advance(UINT i);
  135. BYTE* PbString(LPSTR psz, LONG lCodePage);
  136. BYTE* PbOneOfAspOpenerStringTokens(LPSTR rgszTokens[], UINT rgcchTokens[],
  137. UINT nTokens, UINT *pidToken);
  138. BOOLB FEarlierInSourceThan(CByteRange& br);
  139. };
  140. /* ============================================================================
  141. Enum type: TEMPLATE_COMPONENT
  142. Synopsis: A component of a template, e.g. script block, html block, etc.
  143. */
  144. enum TEMPLATE_COMPONENT
  145. {
  146. // NOTE enum values and order are tightly coupled with template layout order
  147. // DO NOT CHANGE
  148. tcompScriptEngine = 0,
  149. tcompScriptBlock,
  150. tcompObjectInfo,
  151. tcompHTMLBlock,
  152. };
  153. /* ****************************************************************************
  154. Class: CTemplateConnPt
  155. Synopsis: Connection point for IDebugDocumentTextEvents
  156. */
  157. class CTemplateConnPt : public CConnectionPoint
  158. {
  159. public:
  160. // ctor
  161. CTemplateConnPt(IConnectionPointContainer *pContainer, const GUID &uidConnPt)
  162. : CConnectionPoint(pContainer, uidConnPt) {}
  163. // IUnknown methods
  164. STDMETHOD(QueryInterface)(const GUID &, void **);
  165. STDMETHOD_(ULONG, AddRef)();
  166. STDMETHOD_(ULONG, Release)();
  167. };
  168. /* ****************************************************************************
  169. Class: CTemplateKey
  170. Synopsis: Packaged data to locate template in hash table
  171. (instance ID, and template name)
  172. */
  173. #define MATCH_ALL_INSTANCE_IDS 0xFFFBAD1D // unlikely instance ID. sort of spells "BAD ID"
  174. struct CTemplateKey
  175. {
  176. const TCHAR * szPathTranslated;
  177. DWORD dwInstanceID;
  178. CTemplateKey(const TCHAR *_szPathTranslated = NULL, UINT _dwInstanceID = MATCH_ALL_INSTANCE_IDS)
  179. : szPathTranslated(_szPathTranslated),
  180. dwInstanceID(_dwInstanceID) {}
  181. };
  182. /* ****************************************************************************
  183. Class: CTemplate
  184. Synopsis: A Denali compiled template.
  185. NOTE: CTemplate's primary client is CTemplateCacheManager, which maintains
  186. a cache of compiled templates.
  187. USAGE
  188. -----
  189. The CTemplate class must be used as follows:
  190. CLASS INIT - InitClass must be called before any CTemplate can be created.
  191. NEW TEMPLATE - For each new template the client wants to create, the client
  192. must do the following, in order:
  193. 1) New a CTemplate
  194. 2) Initialize the CTemplate by calling Init, passing a source file name
  195. 3) Load the CTemplate by calling Load; when Load returns, the new CTemplate is ready for use.
  196. EXISTING TEMPLATE - To use an existing template, the client must:
  197. 1) Call Deliver; when Deliver returns, the existing CTemplate is ready for use.
  198. CLASS UNINIT - UnInitClass must be called after the last CTemplate has been destroyed.
  199. To ensure thread-safety, the client must implement a critical section
  200. around the call to Init. Init is designed to be as fast as possible,
  201. so the client can quickly learn that it has a pending template for a given
  202. source file, and queue up other requests for the same source file.
  203. CTemplate provides implementations for Debug documents, namely
  204. IDebugDocumentProvider & IDebugDocumentText
  205. */
  206. class CActiveScriptEngine;
  207. class CTemplate :
  208. public CDblLink,
  209. public IDebugDocumentProvider,
  210. public IDebugDocumentText,
  211. public IConnectionPointContainer // Source of IDebugDocumentTextEvents
  212. {
  213. private:
  214. #include "templcap.h" // 'captive' classes, only used internally within CTemplate
  215. friend HRESULT InitMemCls();
  216. friend HRESULT UnInitMemCls();
  217. friend class CTemplateCacheManager; // TODO: decouple CTemplate class from it's manager class
  218. friend class CFileMap;
  219. friend class CIncFile; // IncFiles are privy to debugging data structures
  220. // CScriptStore::Init() must access gm_brDefaultScriptLanguage, gm_progLangIdDefault
  221. friend HRESULT CTemplate::CScriptStore::Init(LPCSTR szDefaultScriptLanguage, CLSID *pCLSIDDefaultEngine);
  222. private:
  223. CWorkStore* m_pWorkStore; // ptr to working storage for source segments
  224. HANDLE m_hEventReadyForUse; // ready-for-use event handle
  225. public:
  226. BYTE* m_pbStart; // ptr to start of template memory
  227. ULONG m_cbTemplate; // bytes allocated for template
  228. LONG m_cRefs; // ref count - NOTE LONG required by InterlockedIncrement
  229. LONG m_cUseCount; // count of times template was used
  230. public:
  231. CTemplateConnPt m_CPTextEvents; // Connection point for IDebugDocumentTextEvents
  232. // support for compile-time errors
  233. BYTE* m_pbErrorLocation; // ptr to error location in source file
  234. UINT m_idErrMsg; // error message id
  235. UINT m_cMsgInserts; // count of insert strings for error msg
  236. char** m_ppszMsgInserts; // array of ptrs to error msg insert strings
  237. // support for run-time errors and debugging
  238. UINT m_cScriptEngines; // count of script engines
  239. CActiveScriptEngine **m_rgpDebugScripts;// array (indexed by engine) of scripts CURRENTLY BEING DEBUGGED
  240. vector<CSourceInfo> *m_rgrgSourceInfos; // array of arrays of script source line infos, one per script engine per target line
  241. ULONG m_cbTargetOffsetPrevT; // running total of last source offset processed
  242. CRITICAL_SECTION m_csDebuggerDetach; // CS needed to avoid race condition with detaching from debugger
  243. CDblLink m_listDocNodes; // list of document nodes we are attached to
  244. CFileMap** m_rgpFilemaps; // array of ptrs to filemaps of source files
  245. CTemplateKey m_LKHashKey; // bundled info for key (contains copy of m_rgpfilemaps[0] filename to make things simpler
  246. UINT m_cFilemaps; // count of filemaps of source files
  247. CFileMap** m_rgpSegmentFilemaps; // array of filemap ptrs per source segment
  248. UINT m_cSegmentFilemapSlots; // count of per-source-segment filemap ptrs
  249. LPSTR m_pszLastErrorInfo[6]; // text of last error - cached for new requests on this template
  250. // FileName, LineNum, Engine, ShortDes, LongDes
  251. DWORD m_dwLastErrorMask; // cached for new requests on this template
  252. DWORD m_hrOnNoCache; // HRESULT when don't cache is set.
  253. TCHAR* m_szApplnVirtPath; // application virtual path (substring of Application URL)
  254. TCHAR* m_szApplnURL; // application URL (starts with "http://")
  255. // for best structure packing we all boleans here as bitfields
  256. unsigned m_fGlobalAsa:1; // is template for global.asa file?
  257. unsigned m_fIsValid:1; // is template in valid state?
  258. unsigned m_fDontCache:1; // don't cache this template
  259. unsigned m_fReadyForUse:1; // is template ready for use?
  260. unsigned m_fDebuggerDetachCSInited:1;// has debugger attach critical section been initialized?
  261. unsigned m_fDontAttach:1; // should not be attached to debugger (not in cache)
  262. unsigned m_fSession:1; // does this page require session state
  263. unsigned m_fScriptless:1; // doesn't have any scripts
  264. unsigned m_fDebuggable:1; // is this page part of at least one debuggable app?
  265. unsigned m_fZombie:1; // File template is based on has changed since obtained from cache
  266. unsigned m_fCodePageSet:1; // Did template contain a code page directive
  267. unsigned m_fLCIDSet:1; // Did template contain an LCID directive
  268. unsigned m_fIsPersisted:1;
  269. unsigned m_fIsUNC:1;
  270. unsigned m_fIsEncrypted:1;
  271. unsigned m_fTemplateLockInited:1;
  272. TransType m_ttTransacted; // type of transaction support
  273. // class-wide support for compilation
  274. static CTokenList* gm_pTokenList; // array of tokens
  275. unsigned m_wCodePage; // Compiler Time CodePage
  276. long m_lLCID; // Compile Time LCID
  277. vector<ITypeLib *> m_rgpTypeLibs; // array of ptrs to typelibs
  278. IDispatch* m_pdispTypeLibWrapper; // typelib wrapper object
  279. vector<C449Cookie *> m_rgp449; // array of ptrs to 449 requests
  280. LPSTR m_szPersistTempName; // filename of persisted template, if any
  281. void *m_pHashTable; // CacheMgr hash table that this template is on
  282. IUnknown *m_pServicesConfig;
  283. static HANDLE sm_hSmallHeap;
  284. static HANDLE sm_hLargeHeap;
  285. // DirMon related fields.
  286. BOOL m_fNeedsMonitoring;
  287. BOOL m_fInCheck;
  288. DWORD m_dwLastMonitored;
  289. DWORD m_dwCacheTag;
  290. // UNC related last impersonation handle
  291. DWORD m_dwLastAccessCheck;
  292. LPVOID m_pMostRecentImpersonatedTokenUser;
  293. PSID m_pMostRecentImpersonatedSID;
  294. DWORD m_cbTokenUser;
  295. CRITICAL_SECTION m_csTemplateLock;
  296. public:
  297. /**
  298. ** Initialization and destruction public interfaces
  299. **/
  300. // Initializes CTemplate static members; must be called on denali.dll load
  301. static HRESULT InitClass();
  302. // Un-initilaizes CTemplate static members; must be called on denali.dll unload
  303. static void UnInitClass();
  304. // Inits template in preparation for compilation
  305. // Called by template cache mgr before calling Load
  306. HRESULT Init(CHitObj* pHitObj, BOOL fGlobalAsp, const CTemplateKey &rTemplateKey);
  307. // Compiles the template from its main source file (and include files, if any)
  308. HRESULT Compile(CHitObj* pHitObj);
  309. // Called by requestor of existing template to determine if template is ready for use
  310. HRESULT Deliver(CHitObj* pHitObj);
  311. // Given the Token Handle this function will return the pointer to the SID and the token buffer
  312. HRESULT GetSIDFromTokenHandle (HANDLE tokenHandle, PSID pSid, LPVOID pBuffer, DWORD *pcbSize);
  313. // Create this template's CServicesConfig object
  314. HRESULT CreateTransServiceConfig(BOOL fEnableTracker);
  315. CTemplate();
  316. ~CTemplate();
  317. void RemoveIncFile(CIncFile* pIncFile);
  318. // Trace Log info
  319. static PTRACE_LOG gm_pTraceLog;
  320. public:
  321. #if PER_TEMPLATE_REFLOG
  322. PTRACE_LOG m_pTraceLog;
  323. #endif
  324. /*
  325. 'Consumer' public interfaces
  326. Methods for getting info out of a CTemplate
  327. */
  328. // Returns name of source file on which this template is based
  329. LPTSTR GetSourceFileName(SOURCEPATHTYPE = SOURCEPATHTYPE_PHYSICAL);
  330. // Returns virtual path of the source file
  331. LPTSTR GetApplnPath(SOURCEPATHTYPE = SOURCEPATHTYPE_PHYSICAL);
  332. // Returns hashing key of the template
  333. const CTemplateKey *ExtractHashKey() const;
  334. // Returns version stamp of compiler by which this template was compiled
  335. LPSTR GetCompilerVersion();
  336. // Component counts
  337. USHORT Count(TEMPLATE_COMPONENT tcomp);
  338. USHORT CountScriptEngines() { return (USHORT)m_cScriptEngines; }
  339. // Returns i-th script block as ptr to prog lang id and ptr to script text
  340. void GetScriptBlock(UINT i, LPSTR* pszScriptEngine, PROGLANG_ID** ppProgLangId, LPCOLESTR* pwstrScriptText);
  341. // Returns i-th object-info as object name, clsid, scope, model
  342. HRESULT GetObjectInfo(UINT i, LPSTR* ppszObjectName,
  343. CLSID *pClsid, CompScope *pScope, CompModel *pcmModel);
  344. // Returns i-th HTML block as ptr, count of bytes, original offset, incl filename
  345. HRESULT GetHTMLBlock(UINT i, LPSTR* pszHTML, ULONG* pcbHTML, ULONG* pcbSrcOffs, LPSTR* pszSrcIncFile);
  346. // Returns line number and source file name a given target line in a given script engine.
  347. void GetScriptSourceInfo(UINT idEngine, int iTargetLine, LPTSTR* pszPathInfo, LPTSTR* pszPathTranslated, ULONG* piSourceLine, ULONG* pichSourceLine, BOOLB* pfGuessedLine);
  348. // Converts a character offset from the target script to the offset in the source
  349. void GetSourceOffset(ULONG idEngine, ULONG cchTargetOffset, TCHAR **pszSourceFile, ULONG *pcchSourceOffset, ULONG *pcchSourceText);
  350. // Converts a character offset from the source document to the offset in the target
  351. BOOL GetTargetOffset(TCHAR *szSourceFile, ULONG cchSourceOffset, ULONG *pidEngine, ULONG *pcchTargetOffset);
  352. // Get the character position of a line (directly implements debugging interface)
  353. HRESULT GetPositionOfLine(CFileMap *pFilemap, ULONG cLineNumber, ULONG *pcCharacterPosition);
  354. // Get the line # of a character position (directly implements debugging interface)
  355. HRESULT GetLineOfPosition(CFileMap *pFilemap, ULONG cCharacterPosition, ULONG *pcLineNumber, ULONG *pcCharacterOffsetInLine);
  356. // Return a RUNNING script based on the engine, or NULL if code context has never been requested yet
  357. CActiveScriptEngine *GetActiveScript(ULONG idEngine);
  358. // associate a running script for an engine ID (Use after you get the first code context)
  359. HRESULT AddScript(ULONG idEngine, CActiveScriptEngine *pScriptEngine);
  360. // attach the CTemplate object to an application (debugger tree view)
  361. HRESULT AttachTo(CAppln *pAppln);
  362. // detach the CTemplate object from an application (debugger tree view)
  363. HRESULT DetachFrom(CAppln *pAppln);
  364. // detach the CTemplate object all applications (and release script engines)
  365. HRESULT Detach();
  366. // Signifies last use of template as a recylable object. Any outstanding references
  367. // should be from currently executing scripts.
  368. ULONG End();
  369. // Let debugger know about page start/end
  370. HRESULT NotifyDebuggerOnPageEvent(BOOL fStart);
  371. // Generate 449 response in cookie negotiations with IE when needed
  372. HRESULT Do449Processing(CHitObj *pHitObj);
  373. HRESULT PersistData(char *pszTempFilePath);
  374. HRESULT UnPersistData();
  375. HRESULT PersistCleanup();
  376. ULONG TemplateSize() { return m_cbTemplate; }
  377. BOOL FTransacted();
  378. BOOL FSession();
  379. BOOL FScriptless();
  380. BOOL FDebuggable();
  381. BOOL FIsValid(); // determine if compilation succeeded
  382. BOOL FTemplateObsolete();
  383. BOOL FGlobalAsa();
  384. BOOL FIsZombie();
  385. BOOL FDontAttach();
  386. BOOL FIsPersisted();
  387. BOOL FIsUNC();
  388. BOOL FIsEncrypted();
  389. BOOL ValidateSourceFiles (CIsapiReqInfo *pIReq);
  390. BOOL FNeedsValidation();
  391. BOOL CheckTTLTimingWindow(DWORD dwLastMonitored, DWORD timeoutSecs);
  392. VOID Zombify();
  393. IUnknown *PServicesConfig() {return m_pServicesConfig;};
  394. IDispatch *PTypeLibWrapper();
  395. void SetHashTablePtr(void *pTable) { m_pHashTable = pTable; }
  396. void *GetHashTablePtr() { return m_pHashTable; }
  397. void IncrUseCount() { InterlockedIncrement(&m_cUseCount); }
  398. public:
  399. /*
  400. COM public interfaces
  401. Implementation of debugging documents.
  402. */
  403. // IUnknown methods
  404. STDMETHOD(QueryInterface)(const GUID &, void **);
  405. STDMETHOD_(ULONG, AddRef)();
  406. STDMETHOD_(ULONG, Release)();
  407. // IDebugDocumentProvider methods
  408. STDMETHOD(GetDocument)(/* [out] */ IDebugDocument **ppDebugDoc);
  409. // IDebugDocumentInfo (also IDebugDocumentProvider) methods
  410. STDMETHOD(GetName)(
  411. /* [in] */ DOCUMENTNAMETYPE dnt,
  412. /* [out] */ BSTR *pbstrName);
  413. STDMETHOD(GetDocumentClassId)(/* [out] */ CLSID *)
  414. {
  415. return E_NOTIMPL;
  416. }
  417. // IDebugDocumentText methods
  418. STDMETHOD(GetDocumentAttributes)(
  419. /* [out] */ TEXT_DOC_ATTR *ptextdocattr);
  420. STDMETHOD(GetSize)(
  421. /* [out] */ ULONG *pcLines,
  422. /* [out] */ ULONG *pcChars);
  423. STDMETHOD(GetPositionOfLine)(
  424. /* [in] */ ULONG cLineNumber,
  425. /* [out] */ ULONG *pcCharacterPosition);
  426. STDMETHOD(GetLineOfPosition)(
  427. /* [in] */ ULONG cCharacterPosition,
  428. /* [out] */ ULONG *pcLineNumber,
  429. /* [out] */ ULONG *pcCharacterOffsetInLine);
  430. STDMETHOD(GetText)(
  431. /* [in] */ ULONG cCharacterPosition,
  432. /* [size_is][length_is][out][in] */ WCHAR *pcharText,
  433. /* [size_is][length_is][out][in] */ SOURCE_TEXT_ATTR *pstaTextAttr,
  434. /* [out][in] */ ULONG *pcChars,
  435. /* [in] */ ULONG cMaxChars);
  436. STDMETHOD(GetPositionOfContext)(
  437. /* [in] */ IDebugDocumentContext *psc,
  438. /* [out] */ ULONG *pcCharacterPosition,
  439. /* [out] */ ULONG *cNumChars);
  440. STDMETHOD(GetContextOfPosition)(
  441. /* [in] */ ULONG cCharacterPosition,
  442. /* [in] */ ULONG cNumChars,
  443. /* [out] */ IDebugDocumentContext **ppsc);
  444. // IConnectionPointContainer methods
  445. STDMETHOD(EnumConnectionPoints)(
  446. /* [out] */ IEnumConnectionPoints __RPC_FAR *__RPC_FAR *ppEnum)
  447. {
  448. return E_NOTIMPL; // doubt we need this - client is expecting only TextEvents
  449. }
  450. STDMETHOD(FindConnectionPoint)(
  451. /* [in] */ const IID &iid,
  452. /* [out] */ IConnectionPoint **ppCP);
  453. private:
  454. /* NOTE Compile() works by calling GetSegmentsFromFile followed by WriteTemplate
  455. Most other private methods support one of these two workhorse functions
  456. */
  457. void AppendMapFile(LPCTSTR szFileSpec, CFileMap* pfilemapParent, BOOLB fVirtual,
  458. CHitObj* pHitObj, BOOLB fGlobalAsp);
  459. void GetSegmentsFromFile(CFileMap& filemap, CWorkStore& WorkStore, CHitObj* pHitObj, BOOL fIsHTML = TRUE);
  460. void GetLanguageEquivalents();
  461. void SetLanguageEquivalent(HANDLE hKeyScriptLanguage, LPSTR szLanguageItem, LPSTR* pszOpen, UINT* pcchOpen, LPSTR* pszClose, UINT* pcchClose);
  462. void ThrowError(BYTE* pbErrorLocation, UINT idErrMsg);
  463. void AppendErrorMessageInsert(BYTE* pbInsert, UINT cbInsert);
  464. void ThrowErrorSingleInsert(BYTE* pbErrorLocation, UINT idErrMsg, BYTE* pbInsert, UINT cbInsert);
  465. HRESULT ShowErrorInDebugger(CFileMap* pFilemap, UINT cchErrorLocation, char* szDescription, CHitObj* pHitObj, BOOL fAttachDocument);
  466. void ProcessSpecificError(CFileMap& filemap, CHitObj* pHitObj);
  467. void HandleCTemplateError(CFileMap* pfilemap, BYTE* pbErrorLocation,
  468. UINT idErrMsg, UINT cInserts, char** ppszInserts, CHitObj *pHitObj);
  469. void FreeGoodTemplateMemory();
  470. void UnmapFiles();
  471. // ExtractAndProcessSegment: gets and processes next source segment in search range
  472. void ExtractAndProcessSegment(CByteRange& brSearch, const SOURCE_SEGMENT& ssegLeading,
  473. _TOKEN* rgtknOpeners, UINT ctknOpeners, CFileMap* pfilemapCurrent, CWorkStore& WorkStore,
  474. CHitObj* pHitObj, BOOL fScriptTagProcessed = FALSE, BOOL fIsHTML = TRUE);
  475. // Support methods for ExtractAndProcessSegment()
  476. SOURCE_SEGMENT SsegFromHTMLComment(CByteRange& brSegment);
  477. void ProcessSegment(SOURCE_SEGMENT sseg, CByteRange& brSegment, CFileMap* pfilemapCurrent,
  478. CWorkStore& WorkStore, BOOL fScriptTagProcessed, CHitObj* pHitObj,
  479. BOOL fIsHTML);
  480. void ProcessHTMLSegment(CByteRange& brHTML, CBuffer& bufHTMLBlocks, UINT idSequence, CFileMap* pfilemapCurrent);
  481. void ProcessHTMLCommentSegment(CByteRange& brSegment, CFileMap* pfilemapCurrent, CWorkStore& WorkStore, CHitObj* pHitObj);
  482. void ProcessScriptSegment(SOURCE_SEGMENT sseg, CByteRange& brSegment, CFileMap* pfilemapCurrent,
  483. CWorkStore& WorkStore, UINT idSequence, BOOLB fScriptTagProcessed, CHitObj* pHitObj);
  484. HRESULT ProcessMetadataSegment(const CByteRange& brSegment, UINT *pidError, CHitObj* pHitObj);
  485. HRESULT ProcessMetadataTypelibSegment(const CByteRange& brSegment, UINT *pidError, CHitObj* pHitObj);
  486. HRESULT ProcessMetadataCookieSegment(const CByteRange& brSegment, UINT *pidError, CHitObj* pHitObj);
  487. void GetScriptEngineOfSegment(CByteRange& brSegment, CByteRange& brEngine, CByteRange& brInclude);
  488. void ProcessTaggedScriptSegment(CByteRange& brSegment, CFileMap* pfilemapCurrent, CWorkStore& WorkStore, CHitObj* pHitObj);
  489. void ProcessObjectSegment(CByteRange& brSegment, CFileMap* pfilemapCurrent, CWorkStore& WorkStore,
  490. UINT idSequence);
  491. void GetCLSIDFromBrClassIDText(CByteRange& brClassIDText, LPCLSID pclsid);
  492. void GetCLSIDFromBrProgIDText(CByteRange& brProgIDText, LPCLSID pclsid);
  493. BOOLB FValidObjectName(CByteRange& brName);
  494. void ProcessIncludeFile(CByteRange& brSegment, CFileMap* pfilemapCurrent, CWorkStore& WorkStore, UINT idSequence, CHitObj* pHitObj, BOOL fIsHTML);
  495. void ProcessIncludeFile2(CHAR* szFileSpec, CByteRange& brFileSpec, CFileMap* pfilemapCurrent, CWorkStore& WorkStore, UINT idSequence, CHitObj* pHitObj, BOOL fIsHTML);
  496. BYTE* GetOpenToken(CByteRange brSearch, SOURCE_SEGMENT ssegLeading, _TOKEN* rgtknOpeners, UINT ctknOpeners, _TOKEN* ptknOpen);
  497. BYTE* GetCloseToken(CByteRange brSearch, _TOKEN tknClose);
  498. _TOKEN GetComplementToken(_TOKEN tkn);
  499. SOURCE_SEGMENT GetSegmentOfOpenToken(_TOKEN tknOpen);
  500. CByteRange BrTagsFromSegment(CByteRange brSegment, _TOKEN tknClose, BYTE** ppbCloseTag);
  501. CByteRange BrValueOfTag(CByteRange brTags, _TOKEN tknTag);
  502. BYTE* GetTagName(CByteRange brTags, _TOKEN tknTagName);
  503. BOOL GetTag(CByteRange &brTags, int nIndex = 1);
  504. BOOL CompTagName(CByteRange &brTags, _TOKEN tknTagName);
  505. BOOLB FTagHasValue(const CByteRange& brTags, _TOKEN tknTag, _TOKEN tknValue);
  506. void CopySzAdv(char* pchWrite, LPSTR psz);
  507. // WriteTemplate: writes the template to a contiguous block of memory
  508. void WriteTemplate(CWorkStore& WorkStore, CHitObj* pHitObj);
  509. // Support methods for WriteTemplate()
  510. // NOTE Adv suffix on some function names == advance ptr after writing
  511. void WriteHeader(USHORT cScriptBlocks,USHORT cObjectInfos, USHORT cHTMLBlocks, UINT* pcbHeaderOffset, UINT* pcbOffsetToOffset);
  512. void WriteScriptBlockOfEngine(USHORT idEnginePrelim, USHORT idEngine, CWorkStore& WorkStore, UINT* pcbDataOffset,
  513. UINT* pcbOffsetToOffset, CHitObj* pHitObj);
  514. void WritePrimaryScriptProcedure(USHORT idEngine, CWorkStore& WorkStore, UINT* pcbDataOffset, UINT cbScriptBlockStart);
  515. void WriteScriptSegment(USHORT idEngine, CFileMap* pfilemap, CByteRange& brScript, UINT* pcbDataOffset, UINT cbScriptBlockStart,
  516. BOOL fAllowExprWrite);
  517. void WriteScriptMinusEscapeChars(CByteRange brScript, UINT* pcbDataOffset, UINT* pcbPtrOffset);
  518. BOOLB FVbsComment(CByteRange& brLine);
  519. BOOLB FExpression(CByteRange& brLine);
  520. void WriteOffsetToOffset(USHORT cBlocks, UINT* pcbHeaderOffset, UINT* pcbOffsetToOffset);
  521. void WriteSzAsBytesAdv(LPCSTR szSource, UINT* pcbDataOffset);
  522. void WriteByteRangeAdv(CByteRange& brSource, BOOLB fWriteAsBsz, UINT* pcbDataOffset, UINT* pcbPtrOffset);
  523. void WriteLongAdv(ULONG uSource, UINT* pcbOffset);
  524. void WriteShortAdv(USHORT uSource, UINT* pcbOffset);
  525. void MemCpyAdv(UINT* pcbOffset, void* pbSource, ULONG cbSource, UINT cbByteAlign = 0);
  526. // Memory access primitives
  527. // NOTE invalid until WriteTemplate() has succeeded
  528. BYTE* GetAddress(TEMPLATE_COMPONENT tcomp, USHORT i);
  529. // Debugging methods
  530. void AppendSourceInfo(USHORT idEngine, CFileMap* pfilemap, BYTE* pbSource,
  531. ULONG cbSourceOffset, ULONG cbScriptBlockOffset, ULONG cbTargetOffset,
  532. ULONG cchSourceText, BOOL fIsHTML);
  533. UINT SourceLineNumberFromPb(CFileMap* pfilemap, BYTE* pbSource);
  534. HRESULT CreateDocumentTree(CFileMap *pfilemapRoot, IDebugApplicationNode **ppDocRoot);
  535. BOOLB FIsLangVBScriptOrJScript(USHORT idEngine);
  536. #if 0
  537. void OutputDebugTables();
  538. void OutputIncludeHierarchy(CFileMap *pfilemap, int cchIndent);
  539. void GetScriptSnippets(ULONG cchSourceOffset, CFileMap *pFilemapSource, ULONG cchTargetOffset, ULONG idTargetEngine, wchar_t wszSourceText[], wchar_t wszTargetText[]);
  540. #endif
  541. void RemoveFromIncFiles();
  542. void ReleaseTypeLibs();
  543. void WrapTypeLibs(CHitObj *pHitObj);
  544. void Release449();
  545. HRESULT BuildPersistedDACL(PACL *ppRetDACL);
  546. // Cache on per-class basis
  547. ACACHE_INCLASS_DEFINITIONS()
  548. public:
  549. // memory allocation
  550. static void* SmallMalloc(SIZE_T dwBytes);
  551. static void* SmallReAlloc(void* pvMem, SIZE_T dwBytes);
  552. static void SmallFree(void* pvMem);
  553. static void* LargeMalloc(SIZE_T dwBytes);
  554. static void* LargeReAlloc(void* pvMem, SIZE_T dwBytes);
  555. static void LargeFree(void* pvMem);
  556. };
  557. ////////////////////////////////////////////////////////////////////////////////
  558. // Inline functions
  559. // Write a long or short to memory, then advance target-ptr
  560. inline void CTemplate::WriteLongAdv(ULONG uSource, UINT* pcbOffset)
  561. { MemCpyAdv(pcbOffset, &uSource, sizeof(ULONG), sizeof(ULONG)); }
  562. inline void CTemplate::WriteShortAdv(USHORT uSource, UINT* pcbOffset)
  563. { MemCpyAdv(pcbOffset, &uSource, sizeof(USHORT), sizeof(USHORT)); }
  564. inline const CTemplateKey * CTemplate::ExtractHashKey() const
  565. { return &m_LKHashKey; }
  566. inline BOOL CTemplate::FTransacted()
  567. { return (m_ttTransacted != ttUndefined); }
  568. inline BOOL CTemplate::FDebuggable()
  569. { return(m_fDebuggable); }
  570. inline BOOL CTemplate::FSession()
  571. { return(m_fSession); }
  572. inline BOOL CTemplate::FScriptless()
  573. { return m_fScriptless; }
  574. inline BOOL CTemplate::FIsValid()
  575. { return(m_fIsValid); }
  576. inline BOOL CTemplate::FGlobalAsa()
  577. { return(m_fGlobalAsa); }
  578. inline BOOL CTemplate::FIsZombie()
  579. { return m_fZombie; }
  580. inline VOID CTemplate::Zombify()
  581. { m_fZombie = TRUE; }
  582. inline BOOL CTemplate::FDontAttach()
  583. { return (m_fDontAttach); }
  584. inline BOOL CTemplate::FIsPersisted()
  585. { return (m_fIsPersisted); }
  586. inline BOOL CTemplate::FIsUNC()
  587. { return (m_fIsUNC); }
  588. inline BOOL CTemplate::FIsEncrypted()
  589. { return (m_fIsEncrypted); }
  590. inline LPTSTR CTemplate::GetApplnPath(SOURCEPATHTYPE pathtype)
  591. { Assert (pathtype == SOURCEPATHTYPE_VIRTUAL); return m_szApplnVirtPath; }
  592. inline IDispatch *CTemplate::PTypeLibWrapper()
  593. { return (m_pdispTypeLibWrapper); }
  594. /* ****************************************************************************
  595. Class: CIncFile
  596. Synopsis: A file included by one or more templates.
  597. NOTE: We store an incfile-template dependency by storing a template ptr in m_rgpTemplates.
  598. This is efficient but ***will break if we ever change Denali to move its memory around***
  599. */
  600. class CIncFile :
  601. private CLinkElem,
  602. public IDebugDocumentProvider,
  603. public IDebugDocumentText,
  604. public IConnectionPointContainer // Source of IDebugDocumentTextEvents
  605. {
  606. // CIncFileMap is a friend so that it can manipulate CLinkElem private members and to access m_ftLastWriteTime
  607. friend class CIncFileMap;
  608. private:
  609. LONG m_cRefs; // ref count - NOTE LONG required by InterlockedIncrement
  610. TCHAR * m_szIncFile; // include file name - NOTE we keep this as a stable ptr to hash table key
  611. CRITICAL_SECTION m_csUpdate; // CS for updating the template ptrs array
  612. vector<CTemplate *> m_rgpTemplates; // array of ptrs to templates which include this include file
  613. CTemplateConnPt m_CPTextEvents; // Connection point for IDebugDocumentTextEvents
  614. BOOLB m_fCsInited; // has CS been initialized yet?
  615. CTemplate::CFileMap *GetFilemap(); // Return the filemap pointer from a template
  616. public:
  617. CIncFile();
  618. HRESULT Init(const TCHAR* szIncFile);
  619. ~CIncFile();
  620. HRESULT AddTemplate(CTemplate* pTemplate);
  621. void RemoveTemplate(CTemplate* pTemplate);
  622. CTemplate* GetTemplate(int iTemplate);
  623. BOOL FlushTemplates();
  624. TCHAR * GetIncFileName() { return m_szIncFile; }
  625. void OnIncFileDecache();
  626. /*
  627. COM public interfaces
  628. Implementation of debugging documents.
  629. */
  630. // IUnknown methods
  631. STDMETHOD(QueryInterface)(const GUID &, void **);
  632. STDMETHOD_(ULONG, AddRef)();
  633. STDMETHOD_(ULONG, Release)();
  634. // IDebugDocumentProvider methods
  635. STDMETHOD(GetDocument)(/* [out] */ IDebugDocument **ppDebugDoc);
  636. // IDebugDocumentInfo (also IDebugDocumentProvider) methods
  637. STDMETHOD(GetName)(
  638. /* [in] */ DOCUMENTNAMETYPE dnt,
  639. /* [out] */ BSTR *pbstrName);
  640. STDMETHOD(GetDocumentClassId)(/* [out] */ CLSID *)
  641. {
  642. return E_NOTIMPL;
  643. }
  644. // IDebugDocumentText methods
  645. STDMETHOD(GetDocumentAttributes)(
  646. /* [out] */ TEXT_DOC_ATTR *ptextdocattr);
  647. STDMETHOD(GetSize)(
  648. /* [out] */ ULONG *pcLines,
  649. /* [out] */ ULONG *pcChars);
  650. STDMETHOD(GetPositionOfLine)(
  651. /* [in] */ ULONG cLineNumber,
  652. /* [out] */ ULONG *pcCharacterPosition);
  653. STDMETHOD(GetLineOfPosition)(
  654. /* [in] */ ULONG cCharacterPosition,
  655. /* [out] */ ULONG *pcLineNumber,
  656. /* [out] */ ULONG *pcCharacterOffsetInLine);
  657. STDMETHOD(GetText)(
  658. /* [in] */ ULONG cCharacterPosition,
  659. /* [size_is][length_is][out][in] */ WCHAR *pcharText,
  660. /* [size_is][length_is][out][in] */ SOURCE_TEXT_ATTR *pstaTextAttr,
  661. /* [out][in] */ ULONG *pcChars,
  662. /* [in] */ ULONG cMaxChars);
  663. STDMETHOD(GetPositionOfContext)(
  664. /* [in] */ IDebugDocumentContext *psc,
  665. /* [out] */ ULONG *pcCharacterPosition,
  666. /* [out] */ ULONG *cNumChars);
  667. STDMETHOD(GetContextOfPosition)(
  668. /* [in] */ ULONG cCharacterPosition,
  669. /* [in] */ ULONG cNumChars,
  670. /* [out] */ IDebugDocumentContext **ppsc);
  671. // IConnectionPointContainer methods
  672. STDMETHOD(EnumConnectionPoints)(
  673. /* [out] */ IEnumConnectionPoints __RPC_FAR *__RPC_FAR *ppEnum)
  674. {
  675. return E_NOTIMPL; // doubt we need this - client is expecting only TextEvents
  676. }
  677. STDMETHOD(FindConnectionPoint)(
  678. /* [in] */ const IID &iid,
  679. /* [out] */ IConnectionPoint **ppCP);
  680. };
  681. #endif /* _TEMPLATE_H */