Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

515 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: bsscript.h
  7. //
  8. // Contents: Script engine classes
  9. //
  10. //----------------------------------------------------------------------------
  11. class CScriptHost;
  12. class CProcessThread;
  13. // Helper class to make initialization
  14. // and freeing of VARIANTARGs foolproof.
  15. // Can be used anywhere a VARIANTARG
  16. // would be used.
  17. class AutoVariant : public VARIANTARG
  18. {
  19. public:
  20. AutoVariant()
  21. {
  22. VariantInit( (VARIANTARG *) this);
  23. }
  24. BOOL Set(long value)
  25. {
  26. V_VT(this) = VT_I4;
  27. V_I4(this) = value;
  28. return TRUE;
  29. }
  30. BOOL Set(TCHAR *value)
  31. {
  32. V_VT(this) = VT_BSTR;
  33. V_BSTR(this) = SysAllocString(value); // NULL is a valid value for BSTR
  34. if (value && !V_BSTR(this))
  35. return FALSE;
  36. return TRUE;
  37. }
  38. ~AutoVariant()
  39. {
  40. VariantClear( (VARIANTARG *) this);
  41. }
  42. };
  43. //+------------------------------------------------------------------------
  44. //
  45. // Class: CScriptSite
  46. //
  47. // Purpose: Active scripting site
  48. //
  49. //-------------------------------------------------------------------------
  50. class CScriptSite :
  51. public IActiveScriptSite,
  52. public IActiveScriptSiteWindow,
  53. public IActiveScriptSiteDebug,
  54. public IProvideMultipleClassInfo,
  55. public IConnectionPointContainer,
  56. public IGlobalMTScript
  57. {
  58. public:
  59. DECLARE_MEMCLEAR_NEW_DELETE();
  60. CScriptSite(CScriptHost * pSH);
  61. ~CScriptSite();
  62. HRESULT Init(LPWSTR pszName);
  63. void Close();
  64. void Abort();
  65. // IUnknown methods
  66. STDMETHOD_(ULONG, AddRef)();
  67. STDMETHOD_(ULONG, Release)();
  68. STDMETHOD(QueryInterface)(REFIID, void **);
  69. // IActiveScriptSite methods
  70. STDMETHOD(GetLCID)(LCID *plcid);
  71. STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti);
  72. STDMETHOD(GetDocVersionString)(BSTR *pszVersion);
  73. STDMETHOD(RequestItems)(void);
  74. STDMETHOD(RequestTypeLibs)(void);
  75. STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo);
  76. STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState);
  77. STDMETHOD(OnScriptError)(IActiveScriptError *pscripterror);
  78. STDMETHOD(OnEnterScript)(void);
  79. STDMETHOD(OnLeaveScript)(void);
  80. // IActiveScriptSiteWindow methods
  81. STDMETHOD(GetWindow)(HWND *phwnd);
  82. STDMETHOD(EnableModeless)(BOOL fEnable);
  83. // IActiveScriptSiteDebug methods
  84. STDMETHOD(GetDocumentContextFromPosition)(DWORD dwSourceContext,
  85. ULONG uCharacterOffset,
  86. ULONG uNumChars,
  87. IDebugDocumentContext **ppsc);
  88. STDMETHOD(GetApplication)(IDebugApplication **ppda);
  89. STDMETHOD(GetRootApplicationNode)(IDebugApplicationNode **ppdanRoot);
  90. STDMETHOD(OnScriptErrorDebug)(IActiveScriptErrorDebug *pErrorDebug,
  91. BOOL *pfEnterDebugger,
  92. BOOL *pfCallOnScriptErrorWhenContinuing);
  93. // IProvideClassInfo methods
  94. STDMETHOD(GetClassInfo)(ITypeInfo **);
  95. STDMETHOD(GetGUID)(DWORD dwGuidKind, GUID * pGUID);
  96. // IProvideMultipleClassInfo methods
  97. STDMETHOD(GetMultiTypeInfoCount)(ULONG *pcti);
  98. STDMETHOD(GetInfoOfIndex)(ULONG iti, DWORD dwFlags, ITypeInfo** pptiCoClass, DWORD* pdwTIFlags, ULONG* pcdispidReserved, IID* piidPrimary, IID* piidSource);
  99. // IConnectionPointContainer methods
  100. STDMETHOD(EnumConnectionPoints)(LPENUMCONNECTIONPOINTS*);
  101. STDMETHOD(FindConnectionPoint)(REFIID, LPCONNECTIONPOINT*);
  102. // IBServer methods
  103. // We need to implement these on a separate identity from
  104. // the main pad object in order to prevent ref count loops
  105. // with the script engine.
  106. STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo);
  107. STDMETHOD(GetTypeInfo)(
  108. UINT itinfo,
  109. LCID lcid,
  110. ITypeInfo FAR* FAR* pptinfo);
  111. STDMETHOD(GetIDsOfNames)(
  112. REFIID riid,
  113. OLECHAR FAR* FAR* rgszNames,
  114. UINT cNames,
  115. LCID lcid,
  116. DISPID FAR* rgdispid);
  117. STDMETHOD(Invoke)(
  118. DISPID dispidMember,
  119. REFIID riid,
  120. LCID lcid,
  121. WORD wFlags,
  122. DISPPARAMS FAR* pdispparams,
  123. VARIANT FAR* pvarResult,
  124. EXCEPINFO FAR* pexcepinfo,
  125. UINT FAR* puArgErr);
  126. STDMETHOD(get_PublicData)(VARIANT *);
  127. STDMETHOD(put_PublicData)(VARIANT);
  128. STDMETHOD(get_PrivateData)(VARIANT *);
  129. STDMETHOD(put_PrivateData)(VARIANT);
  130. STDMETHOD(ExitProcess)();
  131. STDMETHOD(Restart)();
  132. STDMETHOD(get_LocalMachine)(BSTR *);
  133. STDMETHOD(Include)(BSTR);
  134. STDMETHOD(CallScript)(BSTR, VARIANT *);
  135. STDMETHOD(SpawnScript)(BSTR, VARIANT *);
  136. STDMETHOD(get_ScriptParam)(VARIANT *);
  137. STDMETHOD(get_ScriptPath)(BSTR *);
  138. STDMETHOD(CallExternal)(BSTR, BSTR, VARIANT *, long *);
  139. STDMETHOD(ResetSync)(const BSTR);
  140. STDMETHOD(WaitForSync)(BSTR, long, VARIANT_BOOL *);
  141. STDMETHOD(WaitForMultipleSyncs)(const BSTR, VARIANT_BOOL, long, long *);
  142. STDMETHOD(SignalThreadSync)(BSTR);
  143. STDMETHOD(TakeThreadLock)(BSTR);
  144. STDMETHOD(ReleaseThreadLock)(BSTR);
  145. STDMETHOD(DoEvents)();
  146. STDMETHOD(MessageBoxTimeout)(BSTR, long, BSTR, long, long, VARIANT_BOOL, VARIANT_BOOL, long *);
  147. STDMETHOD(RunLocalCommand)(BSTR, BSTR, BSTR, VARIANT_BOOL, VARIANT_BOOL, VARIANT_BOOL, VARIANT_BOOL, VARIANT_BOOL, long *);
  148. STDMETHOD(GetLastRunLocalError)(long *);
  149. STDMETHOD(GetProcessOutput)(long, BSTR *);
  150. STDMETHOD(GetProcessExitCode)(long, long *);
  151. STDMETHOD(TerminateProcess)(long);
  152. STDMETHOD(SendToProcess)(long, BSTR, BSTR, long *);
  153. STDMETHOD(SendMail)(BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, long *);
  154. STDMETHOD(SendSMTPMail)(BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, long *);
  155. STDMETHOD(ASSERT)(VARIANT_BOOL, BSTR);
  156. STDMETHOD(OUTPUTDEBUGSTRING)(BSTR);
  157. STDMETHOD(UnevalString)(BSTR, BSTR*);
  158. STDMETHOD(CopyOrAppendFile)(BSTR bstrSrc,BSTR bstrDst,long nSrcOffset,long nSrcLength,VARIANT_BOOL fAppend,long *nSrcFilePosition);
  159. STDMETHOD(Sleep)(int);
  160. STDMETHOD(Reboot)();
  161. STDMETHOD(NotifyScript)(BSTR, VARIANT);
  162. STDMETHOD(RegisterEventSource)(IDispatch *pDisp, BSTR bstrProgID);
  163. STDMETHOD(UnregisterEventSource)(IDispatch *pDisp);
  164. STDMETHOD(get_HostMajorVer)(long *pVer);
  165. STDMETHOD(get_HostMinorVer)(long *pVer);
  166. STDMETHOD(get_StatusValue)(long nIndex, long *pnStatus);
  167. STDMETHOD(put_StatusValue)(long nIndex, long nStatus);
  168. // Other methods
  169. HRESULT ExecuteScriptStr(TCHAR * pchScript);
  170. HRESULT ExecuteScriptFile(TCHAR *pchPath);
  171. HRESULT SetScriptState(SCRIPTSTATE ss);
  172. CScriptHost * ScriptHost() { return _pSH; }
  173. // Member variables
  174. CStr _cstrName;
  175. ULONG _ulRefs;
  176. CScriptSite * _pScriptSitePrev;
  177. IActiveScript * _pScript;
  178. CScriptHost* _pSH;
  179. TCHAR _achPath[MAX_PATH];
  180. VARIANT _varParam;
  181. IDispatch * _pDispSink;
  182. IDebugDocumentHelper * _pDDH; // Script Debugging helper
  183. DWORD _dwSourceContext;
  184. BOOL _fInDebugError;
  185. private:
  186. BOOL _fInScriptError;
  187. };
  188. class AutoCriticalSection : public CRITICAL_SECTION
  189. {
  190. public:
  191. AutoCriticalSection()
  192. {
  193. InitializeCriticalSection(this);
  194. }
  195. ~AutoCriticalSection()
  196. {
  197. DeleteCriticalSection(this);
  198. }
  199. };
  200. class CScriptHost :
  201. public CThreadComm,
  202. public IGlobalMTScript
  203. {
  204. friend class CScriptEventSink;
  205. public:
  206. DECLARE_MEMCLEAR_NEW_DELETE();
  207. CScriptHost(CMTScript * pBS,
  208. BOOL fPrimary,
  209. BOOL fDispatchOnly);
  210. ~CScriptHost();
  211. DECLARE_STANDARD_IUNKNOWN(CScriptHost);
  212. // Script management
  213. HRESULT LoadTypeLibrary();
  214. HRESULT PushScript(TCHAR *pchType);
  215. HRESULT PopScript();
  216. HRESULT CloseScripts();
  217. HRESULT AbortScripts();
  218. HRESULT ExecuteTopLevelScript(TCHAR *pchPath, VARIANT *pvarParams);
  219. HRESULT ExecuteTopLevelScriptlet(TCHAR *pchScript);
  220. long FireScriptErrorEvent(
  221. TCHAR *bstrFile,
  222. long nLine,
  223. long nChar,
  224. TCHAR *bstrText,
  225. long sCode,
  226. TCHAR *bstrSource,
  227. TCHAR *bstrDescription);
  228. long FireScriptErrorEvent(TCHAR *szMsg);
  229. void FireProcessEvent(THREADMSG mt, CProcessThread *pProc);
  230. void FireMachineEvent(MACHPROC_EVENT_DATA *pmed, BOOL fExec);
  231. void FireEvent(DISPID, UINT cArg, VARIANTARG *pvararg, VARIANTARG *pvarResult);
  232. void FireEvent(DISPID, UINT cArg, VARIANTARG *pvararg);
  233. void FireEvent(DISPID, LPCTSTR);
  234. void FireEvent(DISPID, BOOL);
  235. void FireEvent(DISPID, IDispatch *pDisp);
  236. BOOL GetMachineDispatch(LPSTR achName,
  237. IConnectedMachine **ppMach);
  238. static HRESULT GetSyncEventName(int nEvent, CStr *pCStr, HANDLE *phEvent);
  239. static HRESULT GetSyncEvent(LPCTSTR pszName, HANDLE *phEvent);
  240. // IDispatch interface
  241. STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo);
  242. STDMETHOD(GetTypeInfo)(
  243. UINT itinfo,
  244. LCID lcid,
  245. ITypeInfo FAR* FAR* pptinfo);
  246. STDMETHOD(GetIDsOfNames)(
  247. REFIID riid,
  248. OLECHAR FAR* FAR* rgszNames,
  249. UINT cNames,
  250. LCID lcid,
  251. DISPID FAR* rgdispid);
  252. STDMETHOD(Invoke)(
  253. DISPID dispidMember,
  254. REFIID riid,
  255. LCID lcid,
  256. WORD wFlags,
  257. DISPPARAMS FAR* pdispparams,
  258. VARIANT FAR* pvarResult,
  259. EXCEPINFO FAR* pexcepinfo,
  260. UINT FAR* puArgErr);
  261. // IGlobalMTScript interface
  262. STDMETHOD(get_PublicData)(VARIANT *);
  263. STDMETHOD(put_PublicData)(VARIANT);
  264. STDMETHOD(get_PrivateData)(VARIANT *);
  265. STDMETHOD(put_PrivateData)(VARIANT);
  266. STDMETHOD(ExitProcess)();
  267. STDMETHOD(Restart)();
  268. STDMETHOD(get_LocalMachine)(BSTR *);
  269. STDMETHOD(Include)(BSTR);
  270. STDMETHOD(CallScript)(BSTR, VARIANT *);
  271. STDMETHOD(SpawnScript)(BSTR, VARIANT *);
  272. STDMETHOD(get_ScriptParam)(VARIANT *);
  273. STDMETHOD(get_ScriptPath)(BSTR *);
  274. STDMETHOD(CallExternal)(BSTR, BSTR, VARIANT *, long *);
  275. STDMETHOD(ResetSync)(const BSTR);
  276. STDMETHOD(WaitForSync)(BSTR, long, VARIANT_BOOL *);
  277. STDMETHOD(WaitForMultipleSyncs)(const BSTR, VARIANT_BOOL, long, long *);
  278. STDMETHOD(SignalThreadSync)(BSTR);
  279. STDMETHOD(TakeThreadLock)(BSTR);
  280. STDMETHOD(ReleaseThreadLock)(BSTR);
  281. STDMETHOD(DoEvents)();
  282. STDMETHOD(MessageBoxTimeout)(BSTR, long, BSTR, long, long, VARIANT_BOOL, VARIANT_BOOL, long *);
  283. STDMETHOD(RunLocalCommand)(BSTR, BSTR, BSTR, VARIANT_BOOL, VARIANT_BOOL, VARIANT_BOOL, VARIANT_BOOL, VARIANT_BOOL, long *);
  284. STDMETHOD(GetLastRunLocalError)(long *);
  285. STDMETHOD(GetProcessOutput)(long, BSTR *);
  286. STDMETHOD(GetProcessExitCode)(long, long *);
  287. STDMETHOD(TerminateProcess)(long);
  288. STDMETHOD(SendToProcess)(long, BSTR, BSTR, long *);
  289. STDMETHOD(SendMail)(BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, long *);
  290. STDMETHOD(SendSMTPMail)(BSTR, BSTR, BSTR, BSTR, BSTR, BSTR, long *);
  291. STDMETHOD(ASSERT)(VARIANT_BOOL, BSTR);
  292. STDMETHOD(OUTPUTDEBUGSTRING)(BSTR);
  293. STDMETHOD(UnevalString)(BSTR, BSTR*);
  294. STDMETHOD(CopyOrAppendFile)(BSTR bstrSrc,BSTR bstrDst,long nSrcOffset,long nSrcLength,VARIANT_BOOL fAppend,long *nSrcFilePosition);
  295. STDMETHOD(Sleep)(int);
  296. STDMETHOD(Reboot)();
  297. STDMETHOD(NotifyScript)(BSTR, VARIANT);
  298. STDMETHOD(RegisterEventSource)(IDispatch *pDisp, BSTR bstrProgID);
  299. STDMETHOD(UnregisterEventSource)(IDispatch *pDisp);
  300. STDMETHOD(get_HostMajorVer)(long *pVer);
  301. STDMETHOD(get_HostMinorVer)(long *pVer);
  302. STDMETHOD(get_StatusValue)(long nIndex, long *pnStatus);
  303. STDMETHOD(put_StatusValue)(long nIndex, long nStatus);
  304. CScriptSite * GetSite() { return _pScriptSite; }
  305. void GetScriptPath(CStr *pcstrPath);
  306. CMTScript * _pMT;
  307. CScriptSite * _pScriptSite;
  308. BOOL _fIsPrimaryScript;
  309. BOOL _fMustExitThread;
  310. BOOL _fDontHandleEvents;
  311. ITypeInfo * _pTypeInfoIGlobalMTScript;
  312. ITypeInfo * _pTypeInfoCMTScript;
  313. ITypeLib * _pTypeLibEXE;
  314. VARIANT _vPubCache;
  315. VARIANT _vPrivCache;
  316. DWORD _dwPublicSN;
  317. DWORD _dwPrivateSN;
  318. long _lTimerInterval;
  319. HRESULT _hrLastRunLocalError;
  320. CStackPtrAry<CScriptEventSink*, 5> _aryEvtSinks;
  321. protected:
  322. virtual DWORD ThreadMain();
  323. void HandleThreadMessage();
  324. enum MEP_RETURN
  325. {
  326. MEP_TIMEOUT, // Timeout period expired
  327. MEP_EXIT, // Thread is terminating
  328. MEP_FALLTHROUGH, // No event occurred (fWait==FALSE only)
  329. MEP_EVENT_0, // The given event(s) are signaled
  330. };
  331. DWORD MessageEventPump(BOOL fWait,
  332. UINT cEvents = 0,
  333. HANDLE * pEvents = NULL,
  334. BOOL fAll = FALSE,
  335. DWORD dwTimeout = INFINITE,
  336. BOOL fNoEvents = FALSE);
  337. HRESULT StringToEventArray(const wchar_t *pszNameList, CStackPtrAry<HANDLE, 5> *aryEvents);
  338. HRESULT GetLockCritSec(LPTSTR pszName,
  339. CRITICAL_SECTION **ppcs,
  340. DWORD **ppdwOwner);
  341. struct SYNCEVENT
  342. {
  343. CStr _cstrName;
  344. HANDLE _hEvent;
  345. };
  346. struct THREADLOCK
  347. {
  348. CStr _cstrName;
  349. CRITICAL_SECTION _csLock;
  350. DWORD _dwOwner;
  351. };
  352. // MAX_LOCKS is used because you can't move critical section objects
  353. // in memory once you've initialized them, thus making it impossible to
  354. // use the dynamic array class.
  355. #define MAX_LOCKS 10
  356. // The primary thread owns initialization and cleanup of these objects.
  357. static CStackDataAry<SYNCEVENT, 5> s_arySyncEvents;
  358. static THREADLOCK s_aThreadLocks[MAX_LOCKS];
  359. static UINT s_cThreadLocks;
  360. static AutoCriticalSection s_csSync;
  361. };
  362. //+---------------------------------------------------------------------------
  363. //
  364. // Class: CConnectionPoint (ccp)
  365. //
  366. // Purpose: Implements IConnectionPoint for the script site
  367. //
  368. //----------------------------------------------------------------------------
  369. class CConnectionPoint : public IConnectionPoint
  370. {
  371. public:
  372. CConnectionPoint(CScriptSite *pSite);
  373. ~CConnectionPoint();
  374. DECLARE_STANDARD_IUNKNOWN(CConnectionPoint);
  375. STDMETHOD(GetConnectionInterface)(IID * pIID);
  376. STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer ** ppCPC);
  377. STDMETHOD(Advise)(LPUNKNOWN pUnkSink, DWORD * pdwCookie);
  378. STDMETHOD(Unadvise)(DWORD dwCookie);
  379. STDMETHOD(EnumConnections)(LPENUMCONNECTIONS * ppEnum);
  380. CScriptSite *_pSite;
  381. };
  382. //+---------------------------------------------------------------------------
  383. //
  384. // Class: CMTEventSink (ces)
  385. //
  386. // Purpose: Class which sinks events from objects registered with
  387. // RegisterEventSource().
  388. //
  389. //----------------------------------------------------------------------------
  390. class CScriptEventSink : public IDispatch
  391. {
  392. public:
  393. DECLARE_MEMCLEAR_NEW_DELETE();
  394. CScriptEventSink(CScriptHost *pSH);
  395. ~CScriptEventSink();
  396. // IUnknown methods
  397. DECLARE_STANDARD_IUNKNOWN(CScriptEventSink);
  398. HRESULT Connect(IDispatch *pSource, BSTR bstrProgID);
  399. void Disconnect();
  400. BOOL IsThisYourSource(IDispatch * pSource)
  401. { return pSource == _pDispSource; }
  402. // IDispatch interface
  403. STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo);
  404. STDMETHOD(GetTypeInfo)(
  405. UINT itinfo,
  406. LCID lcid,
  407. ITypeInfo FAR* FAR* pptinfo);
  408. STDMETHOD(GetIDsOfNames)(
  409. REFIID riid,
  410. OLECHAR FAR* FAR* rgszNames,
  411. UINT cNames,
  412. LCID lcid,
  413. DISPID FAR* rgdispid);
  414. STDMETHOD(Invoke)(
  415. DISPID dispidMember,
  416. REFIID riid,
  417. LCID lcid,
  418. WORD wFlags,
  419. DISPPARAMS FAR* pdispparams,
  420. VARIANT FAR* pvarResult,
  421. EXCEPINFO FAR* pexcepinfo,
  422. UINT FAR* puArgErr);
  423. private:
  424. CScriptHost * _pSH;
  425. IDispatch * _pDispSource;
  426. DWORD _dwSinkCookie;
  427. IID _clsidEvents;
  428. };