ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

script.c
Go to the documentation of this file.
00001 /*
00002  * Implementation of scripting for Microsoft Installer (msi.dll)
00003  *
00004  * Copyright 2007 Misha Koshelev
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #define COBJMACROS
00022 
00023 #include <stdarg.h>
00024 #include "windef.h"
00025 #include "winbase.h"
00026 #include "winerror.h"
00027 #include "winuser.h"
00028 #include "msidefs.h"
00029 #include "msipriv.h"
00030 #include "activscp.h"
00031 #include "oleauto.h"
00032 #include "wine/debug.h"
00033 #include "wine/unicode.h"
00034 
00035 #include "msiserver.h"
00036 
00037 WINE_DEFAULT_DEBUG_CHANNEL(msi);
00038 
00039 static const WCHAR szJScript[] = { 'J','S','c','r','i','p','t',0};
00040 static const WCHAR szVBScript[] = { 'V','B','S','c','r','i','p','t',0};
00041 static const WCHAR szSession[] = {'S','e','s','s','i','o','n',0};
00042 
00043 /*
00044  * MsiActiveScriptSite - Our IActiveScriptSite implementation.
00045  */
00046 
00047 typedef struct {
00048     IActiveScriptSite lpVtbl;
00049     IDispatch *pInstaller;
00050     IDispatch *pSession;
00051     LONG ref;
00052 } MsiActiveScriptSite;
00053 
00054 static const struct IActiveScriptSiteVtbl ASS_Vtbl;
00055 
00056 static HRESULT create_ActiveScriptSite(IUnknown *pUnkOuter, LPVOID *ppObj)
00057 {
00058     MsiActiveScriptSite* object;
00059 
00060     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
00061 
00062     if( pUnkOuter )
00063         return CLASS_E_NOAGGREGATION;
00064 
00065     object = msi_alloc_zero( sizeof(MsiActiveScriptSite) );
00066 
00067     object->lpVtbl.lpVtbl = &ASS_Vtbl;
00068     object->ref = 1;
00069     object->pInstaller = NULL;
00070     object->pSession = NULL;
00071 
00072     *ppObj = object;
00073 
00074     return S_OK;
00075 }
00076 
00077 /*
00078  * Call a script.
00079  */
00080 DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
00081 {
00082     HRESULT hr;
00083     IActiveScript *pActiveScript = NULL;
00084     IActiveScriptParse *pActiveScriptParse = NULL;
00085     MsiActiveScriptSite *pActiveScriptSite = NULL;
00086     IDispatch *pDispatch = NULL;
00087     DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
00088     DISPID dispid;
00089     CLSID clsid;
00090     VARIANT var;
00091     DWORD ret = ERROR_INSTALL_FAILURE;
00092 
00093     CoInitialize(NULL);
00094 
00095     /* Create MsiActiveScriptSite object */
00096     hr = create_ActiveScriptSite(NULL, (void **)&pActiveScriptSite);
00097     if (hr != S_OK) goto done;
00098 
00099     /* Create an installer object */
00100     hr = create_msiserver(NULL, (LPVOID *)&pActiveScriptSite->pInstaller);
00101     if (hr != S_OK) goto done;
00102 
00103     /* Create a session object */
00104     hr = create_session(hPackage, pActiveScriptSite->pInstaller, &pActiveScriptSite->pSession);
00105     if (hr != S_OK) goto done;
00106 
00107     /* Create the scripting engine */
00108     if ((type & 7) == msidbCustomActionTypeJScript)
00109         hr = CLSIDFromProgID(szJScript, &clsid);
00110     else if ((type & 7) == msidbCustomActionTypeVBScript)
00111         hr = CLSIDFromProgID(szVBScript, &clsid);
00112     else {
00113         ERR("Unknown script type %d\n", type);
00114         goto done;
00115     }
00116     if (FAILED(hr)) {
00117         ERR("Could not find CLSID for Windows Script\n");
00118         goto done;
00119     }
00120     hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IActiveScript, (void **)&pActiveScript);
00121     if (FAILED(hr)) {
00122         ERR("Could not instantiate class for Windows Script\n");
00123         goto done;
00124     }
00125 
00126     /* Get the IActiveScriptParse engine interface */
00127     hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse, (void **)&pActiveScriptParse);
00128     if (FAILED(hr)) goto done;
00129 
00130     /* Give our host to the engine */
00131     hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
00132     if (FAILED(hr)) goto done;
00133 
00134     /* Initialize the script engine */
00135     hr = IActiveScriptParse64_InitNew(pActiveScriptParse);
00136     if (FAILED(hr)) goto done;
00137 
00138     /* Add the session object */
00139     hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
00140     if (FAILED(hr)) goto done;
00141 
00142     /* Pass the script to the engine */
00143     hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
00144     if (FAILED(hr)) goto done;
00145 
00146     /* Start processing the script */
00147     hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED);
00148     if (FAILED(hr)) goto done;
00149 
00150     /* Call a function if necessary through the IDispatch interface */
00151     if (function != NULL && strlenW(function) > 0) {
00152         TRACE("Calling function %s\n", debugstr_w(function));
00153 
00154         hr = IActiveScript_GetScriptDispatch(pActiveScript, NULL, &pDispatch);
00155         if (FAILED(hr)) goto done;
00156 
00157         hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, (WCHAR **)&function, 1,LOCALE_USER_DEFAULT, &dispid);
00158         if (FAILED(hr)) goto done;
00159 
00160         hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, &var, NULL, NULL);
00161         if (FAILED(hr)) goto done;
00162 
00163         /* Check return value, if it's not IDOK we failed */
00164         hr = VariantChangeType(&var, &var, 0, VT_I4);
00165         if (FAILED(hr)) goto done;
00166 
00167         if (V_I4(&var) == IDOK)
00168             ret = ERROR_SUCCESS;
00169         else ret = ERROR_INSTALL_FAILURE;
00170 
00171         VariantClear(&var);
00172     } else {
00173         /* If no function to be called, MSI behavior is to succeed */
00174         ret = ERROR_SUCCESS;
00175     }
00176 
00177 done:
00178 
00179     /* Free everything that needs to be freed */
00180     if (pDispatch) IDispatch_Release(pDispatch);
00181     if (pActiveScript) IActiveScriptSite_Release(pActiveScript);
00182     if (pActiveScriptSite &&
00183         pActiveScriptSite->pSession) IUnknown_Release((IUnknown *)pActiveScriptSite->pSession);
00184     if (pActiveScriptSite &&
00185         pActiveScriptSite->pInstaller) IUnknown_Release((IUnknown *)pActiveScriptSite->pInstaller);
00186     if (pActiveScriptSite) IUnknown_Release((IUnknown *)pActiveScriptSite);
00187 
00188     CoUninitialize();    /* must call even if CoInitialize failed */
00189 
00190     return ret;
00191 }
00192 
00193 /*
00194  * MsiActiveScriptSite
00195  */
00196 
00197 /*** IUnknown methods ***/
00198 static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* iface, REFIID riid, void** ppvObject)
00199 {
00200     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00201 
00202     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
00203 
00204     if (IsEqualGUID(riid, &IID_IUnknown) ||
00205         IsEqualGUID(riid, &IID_IActiveScriptSite))
00206     {
00207         IClassFactory_AddRef(iface);
00208         *ppvObject = This;
00209         return S_OK;
00210     }
00211 
00212     TRACE("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
00213 
00214     return E_NOINTERFACE;
00215 }
00216 
00217 static ULONG WINAPI MsiActiveScriptSite_AddRef(IActiveScriptSite* iface)
00218 {
00219     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00220 
00221     TRACE("(%p/%p)\n", iface, This);
00222 
00223     return InterlockedIncrement(&This->ref);
00224 }
00225 
00226 static ULONG WINAPI MsiActiveScriptSite_Release(IActiveScriptSite* iface)
00227 {
00228     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00229     ULONG ref = InterlockedDecrement(&This->ref);
00230 
00231     TRACE("(%p/%p)\n", iface, This);
00232 
00233     if (!ref)
00234         msi_free(This);
00235 
00236     return ref;
00237 }
00238 
00239 /*** IActiveScriptSite methods **/
00240 static HRESULT WINAPI MsiActiveScriptSite_GetLCID(IActiveScriptSite* iface, LCID* plcid)
00241 {
00242     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00243     TRACE("(%p/%p)->(%p)\n", This, iface, plcid);
00244     return E_NOTIMPL;  /* Script will use system-defined locale */
00245 }
00246 
00247 static HRESULT WINAPI MsiActiveScriptSite_GetItemInfo(IActiveScriptSite* iface, LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti)
00248 {
00249     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00250     TRACE("(%p/%p)->(%p,%d,%p,%p)\n", This, iface, pstrName, dwReturnMask, ppiunkItem, ppti);
00251 
00252     /* Determine the kind of pointer that is requested, and make sure placeholder is valid */
00253     if (dwReturnMask & SCRIPTINFO_ITYPEINFO) {
00254         if (!ppti) return E_INVALIDARG;
00255         *ppti = NULL;
00256     }
00257     if (dwReturnMask & SCRIPTINFO_IUNKNOWN) {
00258         if (!ppiunkItem) return E_INVALIDARG;
00259         *ppiunkItem = NULL;
00260     }
00261 
00262     /* Are we looking for the session object? */
00263     if (!strcmpW(szSession, pstrName)) {
00264         if (dwReturnMask & SCRIPTINFO_ITYPEINFO)
00265             return load_type_info(This->pSession, ppti, &DIID_Session, 0);
00266         else if (dwReturnMask & SCRIPTINFO_IUNKNOWN) {
00267             IDispatch_QueryInterface(This->pSession, &IID_IUnknown, (void **)ppiunkItem);
00268             return S_OK;
00269         }
00270     }
00271 
00272     return TYPE_E_ELEMENTNOTFOUND;
00273 }
00274 
00275 static HRESULT WINAPI MsiActiveScriptSite_GetDocVersionString(IActiveScriptSite* iface, BSTR* pbstrVersion)
00276 {
00277     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00278     TRACE("(%p/%p)->(%p)\n", This, iface, pbstrVersion);
00279     return E_NOTIMPL;
00280 }
00281 
00282 static HRESULT WINAPI MsiActiveScriptSite_OnScriptTerminate(IActiveScriptSite* iface, const VARIANT* pvarResult, const EXCEPINFO* pexcepinfo)
00283 {
00284     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00285     TRACE("(%p/%p)->(%p,%p)\n", This, iface, pvarResult, pexcepinfo);
00286     return S_OK;
00287 }
00288 
00289 static HRESULT WINAPI MsiActiveScriptSite_OnStateChange(IActiveScriptSite* iface, SCRIPTSTATE ssScriptState)
00290 {
00291     switch (ssScriptState) {
00292         case SCRIPTSTATE_UNINITIALIZED:
00293               TRACE("State: Uninitialized.\n");
00294               break;
00295 
00296         case SCRIPTSTATE_INITIALIZED:
00297               TRACE("State: Initialized.\n");
00298               break;
00299 
00300         case SCRIPTSTATE_STARTED:
00301               TRACE("State: Started.\n");
00302               break;
00303 
00304         case SCRIPTSTATE_CONNECTED:
00305               TRACE("State: Connected.\n");
00306               break;
00307 
00308         case SCRIPTSTATE_DISCONNECTED:
00309               TRACE("State: Disconnected.\n");
00310               break;
00311 
00312         case SCRIPTSTATE_CLOSED:
00313               TRACE("State: Closed.\n");
00314               break;
00315 
00316         default:
00317               ERR("Unknown State: %d\n", ssScriptState);
00318               break;
00319     }
00320 
00321     return S_OK;
00322 }
00323 
00324 static HRESULT WINAPI MsiActiveScriptSite_OnScriptError(IActiveScriptSite* iface, IActiveScriptError* pscripterror)
00325 {
00326     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00327     EXCEPINFO exception;
00328     HRESULT hr;
00329 
00330     TRACE("(%p/%p)->(%p)\n", This, iface, pscripterror);
00331 
00332     memset(&exception, 0, sizeof(EXCEPINFO));
00333     hr = IActiveScriptError_GetExceptionInfo(pscripterror, &exception);
00334     if (SUCCEEDED(hr))
00335     {
00336         ERR("script error: %s\n", debugstr_w(exception.bstrDescription));
00337         SysFreeString(exception.bstrSource);
00338         SysFreeString(exception.bstrDescription);
00339         SysFreeString(exception.bstrHelpFile);
00340     }
00341 
00342     return S_OK;
00343 }
00344 
00345 static HRESULT WINAPI MsiActiveScriptSite_OnEnterScript(IActiveScriptSite* iface)
00346 {
00347     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00348     TRACE("(%p/%p)\n", This, iface);
00349     return S_OK;
00350 }
00351 
00352 static HRESULT WINAPI MsiActiveScriptSite_OnLeaveScript(IActiveScriptSite* iface)
00353 {
00354     MsiActiveScriptSite *This = (MsiActiveScriptSite *)iface;
00355     TRACE("(%p/%p)\n", This, iface);
00356     return S_OK;
00357 }
00358 
00359 static const struct IActiveScriptSiteVtbl ASS_Vtbl =
00360 {
00361     MsiActiveScriptSite_QueryInterface,
00362     MsiActiveScriptSite_AddRef,
00363     MsiActiveScriptSite_Release,
00364     MsiActiveScriptSite_GetLCID,
00365     MsiActiveScriptSite_GetItemInfo,
00366     MsiActiveScriptSite_GetDocVersionString,
00367     MsiActiveScriptSite_OnScriptTerminate,
00368     MsiActiveScriptSite_OnStateChange,
00369     MsiActiveScriptSite_OnScriptError,
00370     MsiActiveScriptSite_OnEnterScript,
00371     MsiActiveScriptSite_OnLeaveScript
00372 };

Generated on Sun May 27 2012 04:25:07 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.