Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenscript.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
1.7.6.1
|