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.

429 lines
10 KiB

  1. //
  2. // CActiveScriptEngine.cpp
  3. //
  4. // Contains the definitions for the ActiveScriptEngine used in TBScript.
  5. //
  6. // Copyright (C) 2001 Microsoft Corporation
  7. //
  8. // Author: a-devjen (Devin Jenson)
  9. //
  10. #include "CActiveScriptEngine.h"
  11. #include <crtdbg.h>
  12. // CActiveScriptEngine::CActiveScriptEngine
  13. //
  14. // The constructor, simply grabs references to the dispatch objects
  15. // we are using in this object.
  16. //
  17. // No return value.
  18. CActiveScriptEngine::CActiveScriptEngine(CTBGlobal *TBGlobalPtr,
  19. CTBShell *TBShellPtr)
  20. {
  21. // Start out at a zero reference count
  22. RefCount = 0;
  23. // Grab the pointers
  24. TBGlobal = TBGlobalPtr;
  25. TBShell = TBShellPtr;
  26. // Ensure COM has been initialized
  27. CoInitialize(NULL);
  28. // Add a reference to the dispatches
  29. if (TBGlobal != NULL)
  30. TBGlobal->AddRef();
  31. if (TBShell != NULL)
  32. TBShell->AddRef();
  33. }
  34. // CActiveScriptEngine::~CActiveScriptEngine
  35. //
  36. // The destructor, release pointers from the dispatch objects.
  37. //
  38. // No return value.
  39. CActiveScriptEngine::~CActiveScriptEngine(void)
  40. {
  41. // Remove a reference from the dispatche
  42. if (TBGlobal != NULL)
  43. TBGlobal->Release();
  44. TBGlobal = NULL;
  45. // Remove a reference from the dispatche
  46. if (TBShell != NULL)
  47. TBShell->Release();
  48. TBShell = NULL;
  49. }
  50. //
  51. //
  52. // Begin the IUnknown inherited interface
  53. //
  54. //
  55. // CActiveScriptEngine::QueryInterface
  56. //
  57. // This is a COM exported method used for retrieving the interface.
  58. //
  59. // Returns S_OK on success, or E_NOINTERFACE on failure.
  60. STDMETHODIMP CActiveScriptEngine::QueryInterface(REFIID RefIID, void **vObject)
  61. {
  62. // This interface is either IUnknown or IActiveScriptSite - nothing else
  63. if (RefIID == IID_IUnknown || RefIID == IID_IActiveScriptSite)
  64. *vObject = (IActiveScriptSite *)this;
  65. // We received an unsupported RefIID
  66. else {
  67. // De-reference the passed in pointer and error out
  68. *vObject = NULL;
  69. return E_NOINTERFACE;
  70. }
  71. // Add a reference
  72. if (*vObject != NULL)
  73. ((IUnknown*)*vObject)->AddRef();
  74. return S_OK;
  75. }
  76. // CActiveScriptEngine::AddRef
  77. //
  78. // Simply increments a number indicating the number of objects that contain
  79. // a reference to this object.
  80. //
  81. // Returns the new reference count.
  82. STDMETHODIMP_(ULONG) CActiveScriptEngine::AddRef(void)
  83. {
  84. return InterlockedIncrement(&RefCount);
  85. }
  86. // CActiveScriptEngine::Release
  87. //
  88. // Simply decrements a number indicating the number of objects that contain
  89. // a reference to this object. If the resulting reference count is zero,
  90. // no objects contain a reference handle, therefore delete itself from
  91. // memory as it is no longer used.
  92. //
  93. // Returns the new reference count.
  94. STDMETHODIMP_(ULONG) CActiveScriptEngine::Release(void)
  95. {
  96. // Decrememt
  97. if (InterlockedDecrement(&RefCount) != 0)
  98. // Return the new value
  99. return RefCount;
  100. // It is 0, so delete itself
  101. delete this;
  102. return 0;
  103. }
  104. //
  105. //
  106. // Begin the IActiveScript inherited interface
  107. //
  108. //
  109. // CActiveScriptEngine::GetItemInfo
  110. //
  111. // Retreives a memory pointer to the specified (local) interface code or
  112. // a reference handle.
  113. //
  114. // Returns S_OK, E_INVALIDARG, E_POINTER, or TYPE_E_ELEMENTNOTFOUND.
  115. STDMETHODIMP CActiveScriptEngine::GetItemInfo(LPCOLESTR Name,
  116. DWORD ReturnMask, IUnknown **UnknownItem, ITypeInfo **TypeInfo)
  117. {
  118. // Initialize
  119. IUnknown *TBInterface = NULL;
  120. // If we are going to handle a specific item, NULL it's destination
  121. // pointer out. We also use this opportunity to validate some
  122. // argument pointers.
  123. __try {
  124. if (ReturnMask & SCRIPTINFO_IUNKNOWN)
  125. *UnknownItem = NULL;
  126. if (ReturnMask & SCRIPTINFO_ITYPEINFO)
  127. *TypeInfo = NULL;
  128. // This check is to make sure nothing else was passed into the mask
  129. if (ReturnMask & ~(SCRIPTINFO_ITYPEINFO | SCRIPTINFO_IUNKNOWN)) {
  130. // This should never happen, so ASSERT!
  131. _ASSERT(FALSE);
  132. return E_INVALIDARG;
  133. }
  134. }
  135. // If the handler was executed, we got a bad pointer
  136. __except (EXCEPTION_EXECUTE_HANDLER) {
  137. // This should never happen, so ASSERT!
  138. _ASSERT(FALSE);
  139. return E_POINTER;
  140. }
  141. // Freaky things...
  142. _ASSERT(TBGlobal != NULL);
  143. _ASSERT(TBShell != NULL);
  144. // Scan which item we are referring to
  145. if (wcscmp(Name, OLESTR("Global")) == 0) {
  146. // Check if the call wants the actual module code
  147. if (ReturnMask & SCRIPTINFO_ITYPEINFO) {
  148. // Check to make sure we have a valid TypeInfo
  149. _ASSERT(TBGlobal->TypeInfo != NULL);
  150. *TypeInfo = TBGlobal->TypeInfo;
  151. }
  152. // Check if the call wants the Dispatch
  153. if (ReturnMask & SCRIPTINFO_IUNKNOWN) {
  154. *UnknownItem = TBGlobal;
  155. TBGlobal->AddRef();
  156. }
  157. }
  158. else if (wcscmp(Name, OLESTR("TS")) == 0) {
  159. // Check if the call wants the actual module code
  160. if (ReturnMask & SCRIPTINFO_ITYPEINFO) {
  161. // Check to make sure we have a valid TypeInfo
  162. _ASSERT(TBShell->TypeInfo != NULL);
  163. *TypeInfo = TBShell->TypeInfo;
  164. }
  165. // Check if the call wants the Dispatch
  166. if (ReturnMask & SCRIPTINFO_IUNKNOWN) {
  167. *UnknownItem = TBShell;
  168. TBShell->AddRef();
  169. }
  170. }
  171. else
  172. // We don't have an object by that name!
  173. return TYPE_E_ELEMENTNOTFOUND;
  174. return S_OK;
  175. }
  176. // CActiveScriptEngine::OnScriptError
  177. //
  178. // This event is executed when a script error occurs.
  179. //
  180. // Returns S_OK on success or an OLE defined error on failure.
  181. STDMETHODIMP CActiveScriptEngine::OnScriptError(IActiveScriptError *ScriptError)
  182. {
  183. // Initialize
  184. OLECHAR *ErrorData;
  185. OLECHAR *Message;
  186. DWORD Cookie;
  187. LONG CharPos;
  188. ULONG LineNum;
  189. BSTR LineError = NULL;
  190. EXCEPINFO ExceptInfo = { 0 };
  191. OLECHAR *ScriptText = NULL;
  192. // Get script error data
  193. ScriptError->GetSourcePosition(&Cookie, &LineNum, &CharPos);
  194. ScriptError->GetSourceLineText(&LineError);
  195. ScriptError->GetExceptionInfo(&ExceptInfo);
  196. ScriptText = LineError ? LineError :
  197. (ExceptInfo.bstrHelpFile ? ExceptInfo.bstrHelpFile : NULL);
  198. // Allocate a data buffer for use with our error data
  199. ErrorData = (OLECHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024);
  200. if (ErrorData == NULL)
  201. return E_OUTOFMEMORY;
  202. // Format the error code into text
  203. if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  204. FORMAT_MESSAGE_FROM_SYSTEM, 0, ExceptInfo.scode,
  205. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  206. (LPWSTR)&Message, 0, NULL) == 0)
  207. Message = NULL;
  208. // Make it pretty for whatever data is provided
  209. if (ExceptInfo.bstrSource != NULL && Message != NULL)
  210. wsprintfW(ErrorData, OLESTR("%s\n%s [Line: %d]"),
  211. Message, ExceptInfo.bstrSource, LineNum);
  212. else if (Message != NULL)
  213. wsprintfW(ErrorData, OLESTR("%s\n[Line: %d]"), Message, LineNum);
  214. else if (ExceptInfo.bstrSource != NULL)
  215. wsprintfW(ErrorData, OLESTR("Unknown Exception\n%s [Line: %d]"),
  216. ExceptInfo.bstrSource, LineNum);
  217. else
  218. wsprintfW(ErrorData, OLESTR("Unknown Exception\n[Line: %d]"), LineNum);
  219. if (ScriptText != NULL) {
  220. // Format a long-readable string
  221. wsprintfW(ErrorData, OLESTR("%s\n\n%s:\n\n%s"),
  222. ErrorData,
  223. ExceptInfo.bstrDescription, ScriptText);
  224. }
  225. else {
  226. // Format a readable string
  227. wsprintfW(ErrorData, OLESTR("%s\n\n%s"),
  228. ErrorData, ExceptInfo.bstrDescription);
  229. }
  230. // Deallocate temporary strings
  231. SysFreeString(LineError);
  232. SysFreeString(ExceptInfo.bstrSource);
  233. SysFreeString(ExceptInfo.bstrDescription);
  234. SysFreeString(ExceptInfo.bstrHelpFile);
  235. if (Message != NULL) {
  236. LocalFree(Message);
  237. Message = NULL;
  238. }
  239. // Tell the user about our error
  240. MessageBoxW(GetDesktopWindow(), ErrorData,
  241. OLESTR("TBScript Parse Error"), MB_SETFOREGROUND);
  242. // Free the data buffer
  243. HeapFree(GetProcessHeap(), 0, ErrorData);
  244. return S_OK;
  245. }
  246. // CActiveScriptEngine::GetLCID
  247. //
  248. // Retreives the LCID of the interface.
  249. //
  250. // Returns S_OK on success or E_POINTER on failure.
  251. STDMETHODIMP CActiveScriptEngine::GetLCID(LCID *Lcid)
  252. {
  253. // Get the LCID on this user-defined pointer
  254. __try {
  255. *Lcid = GetUserDefaultLCID();
  256. }
  257. // If the handler was executed, we got a bad pointer
  258. __except (EXCEPTION_EXECUTE_HANDLER) {
  259. // This should never happen, so ASSERT!
  260. _ASSERT(FALSE);
  261. return E_POINTER;
  262. }
  263. return S_OK;
  264. }
  265. // CActiveScriptEngine::GetDocVersionString
  266. //
  267. // Unsupported, returns E_NOTIMPL.
  268. STDMETHODIMP CActiveScriptEngine::GetDocVersionString(BSTR *Version)
  269. {
  270. // Get the LCID on this user-defined pointer
  271. __try {
  272. *Version = NULL;
  273. }
  274. // If the handler was executed, we got a bad pointer
  275. __except (EXCEPTION_EXECUTE_HANDLER) {
  276. // This should never happen, so ASSERT!
  277. _ASSERT(FALSE);
  278. }
  279. return E_NOTIMPL;
  280. }
  281. // CActiveScriptEngine::OnScriptTerminate
  282. //
  283. // Unsupported, returns S_OK.
  284. STDMETHODIMP CActiveScriptEngine::OnScriptTerminate(const VARIANT *varResult,
  285. const EXCEPINFO *ExceptInfo)
  286. {
  287. return S_OK;
  288. }
  289. // CActiveScriptEngine::OnStateChange
  290. //
  291. // Unsupported, returns S_OK.
  292. STDMETHODIMP CActiveScriptEngine::OnStateChange(SCRIPTSTATE ScriptState)
  293. {
  294. return S_OK;
  295. }
  296. // CActiveScriptEngine::OnEnterScript
  297. //
  298. // Unsupported, returns S_OK.
  299. STDMETHODIMP CActiveScriptEngine::OnEnterScript(void)
  300. {
  301. return S_OK;
  302. }
  303. // CActiveScriptEngine::OnLeaveScript
  304. //
  305. // Unsupported, returns S_OK.
  306. STDMETHODIMP CActiveScriptEngine::OnLeaveScript(void)
  307. {
  308. return S_OK;
  309. }