├── .gitignore ├── LICENSE ├── README.md ├── chrome └── manifest.json ├── dist └── Dummy.dat ├── ffactivex.sln ├── ffactivex ├── GenericNPObject.cpp ├── GenericNPObject.h ├── authorize.cpp ├── authorize.h ├── axhost.cpp ├── axhost.h ├── common │ ├── ControlEventSink.cpp │ ├── ControlEventSink.h │ ├── ControlSite.cpp │ ├── ControlSite.h │ ├── ControlSiteIPFrame.cpp │ ├── ControlSiteIPFrame.h │ ├── IOleCommandTargetImpl.h │ ├── ItemContainer.cpp │ ├── ItemContainer.h │ ├── PropertyBag.cpp │ ├── PropertyBag.h │ ├── PropertyList.h │ └── StdAfx.h ├── dllmain.cpp ├── ffactivex.aps ├── ffactivex.cpp ├── ffactivex.def ├── ffactivex.h ├── ffactivex.rc ├── ffactivex.vcproj ├── resource.h ├── scriptable.cpp ├── scriptable.h ├── stdafx.cpp ├── stdafx.h ├── targetver.h ├── variants.cpp └── variants.h ├── install ├── ffactivex.inc └── ffactivex.iss ├── test.html ├── tool └── mkinst.cmd └── transver ├── transver.cpp └── transver.vcproj /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | Debug/* 3 | Release/* 4 | *.ncb 5 | *.suo 6 | *.user 7 | *.exe 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | _The contents of this file were written long ago. Most, if not all, of the 2 | references to Firefox hold true for Chrome as well_. 3 | 4 | # Introduction 5 | 6 | This plugin was written to try and reduce the gap between IE and FF when it comes to content that can be used in web applications. Sometimes, to create an ideal user experience you have to be able to use some native code. Many times that native code already exists in the form of an ActiveX control. 7 | 8 | The plugin registers its own MIME Type - meaning that currently web pages need to be written with this plugin in mind. It does not work transparently in sites that use ActiveX objects. 9 | 10 | # Security 11 | 12 | The lack of support for ActiveX controls in FF is definitely one of its strong points where security is concerned. This plugin does not aim to reduce the security of FF. To that end several measures have been taken: 13 | 14 | * The plugin *will not* work on regular object tags that are used to embed ActiveX controls in IE. 15 | * The plugin can be compiled with a list of trusted domains that will be allowed to use it. It will refuse to load ActiveX objects for any other domain. 16 | * The plugin can be compiled with a list of trusted control CLSIDs/PROGIDs. Again, trying to use any other control will fail. 17 | 18 | # Features 19 | 20 | The plugin aims to provide full support for embedding ActiveX controls. Here's a list of the features provided: 21 | 22 | * *Scriptable* - Fully scriptable from Javascript, calling methods, retrieving/setting property values, etc. 23 | * *Parameters* - You can pass parameters to the embedded control. 24 | * *Events* - You can bind Javascript function to events. 25 | * *CAB Download* - You can specify a URL for downloading a CAB with the control if it does not exist. 26 | * The URL must match the list of trusted domain if one exists. 27 | 28 | # Preparing the Plugin for Distribution 29 | 30 | The source stored in the SVN repository here can be considered 'vanilla' code. It has no predefined lists of trusted sites/controls. It is provided for the mere purpose of testing and performing simple POCs. The provided XPI is not signed. 31 | 32 | If you would like to use this plugin it is strongly recommended that you fill in these lists (trusted domains, controls), choose a unique MIME Type for your purposes, and sign the XPI. Optionally, you can also provide an auto update mechanism just like with any other FF plugin. 33 | 34 | ## Declaring the MIME Type 35 | 36 | On windows, FF associates plugin with the MIME Type they have defined in their resource key named `MIMEType`. If you open the plugin's properties and go to the Version tab, you will have a list of resource items, `MIMEType` is one of those items. 37 | 38 | To specify which MIME Type you want your version of this plugin to use, open ffactive.rc and edit the value of the `MIMEType` key. 39 | 40 | ## Providing a Trusted Domains List 41 | 42 | In the file ffactivex.cpp you will find the following lines: 43 | ``` 44 | static const char *TrustedLocations[] = {NULL}; 45 | static const unsigned int numTrustedLocations = 0; 46 | ``` 47 | What they mean is that any and all sites will be allowed to use this plugin you are about to compile. Assuming you will sign your plugin and have your users install it, you do not want them complaining later when some other site takes advantage of it in any way you did not intend. 48 | 49 | `TrustedLocations` is an array of simple C strings, each representing a domain name. A domain name may begin with an `*` as a wild card (e.g. `*`.google.com will match code.google.com). Otherwise, the complete domain name must match exactly a member of the `TrustedLocations` array. 50 | 51 | ## Providing a Well Known Control List 52 | 53 | In the file axhost.cpp you will find the following lines: 54 | ``` 55 | static const char *WellKnownProgIds[] = { 56 | NULL 57 | }; 58 | 59 | static const char *WellKnownClsIds[] = { 60 | NULL 61 | }; 62 | 63 | static const bool AcceptOnlyWellKnown = false; 64 | static const bool TrustWellKnown = false; 65 | ``` 66 | 67 | Same as with `TrustedLocations`, `WellKnownProgIds` and `WellKnownClsIds` are arrays of PROGIDs and CLSIDs respectively. 68 | 69 | In addition, `TrustWellKnown` can be set to true in order to create the control using an unsafe for scripting interface. While this is a security issue, there might be a trade-off here between the user experience and security and it is left to you to decide how you want your plugin to behave. 70 | 71 | The reasoning for this flag is that controls that are invoked through their safe for scripting interfaces sometimes prompt the user with different dialogues and therefore spoil an otherwise smooth and fluid user experience of your web application. 72 | 73 | While these dialogues are important when the ActiveX control can be used from anywhere on the net, when its usage is restricted by following the previous guidelines, this trade-off might not be a significant one. 74 | 75 | # Embedding an ActiveX in a Web Page 76 | 77 | FF invokes plugins for rendering content by matching the MIME type of that content as specified in the `` tag. Here's an example: 78 | ``` 79 | 87 | 88 | ``` 89 | 90 | * `type`: the MIME Type the plugin is associated with. 91 | * `clsid`: is the CLSID of the control you wish the plugin to load. 92 | * `progid`: is the PROGID of the control you with the plugin to load. 93 | * `event_XXX`: tells the plugin to bind the event `XXX` to the Javascript function given as value. 94 | * `param_XXX`: requests that the plugin will invoke the requested ActiveX control with the parameter named `XXX` and set its value accordingly. 95 | * `codeBaseURL`: may be used to provide a location from which the plugin will download and install a CAB containing the needed ActiveX control. 96 | 97 | There is no need to provide both a `clsid` and a `progid`, the above is done only for the purpose of demonstration. 98 | 99 | # Troubleshooting 100 | 101 | First of all, get [Firebug](http://getfirebug.com/). Aside from being an invaluable tool for developing with FF, this plugin can print debug messages to Firebug's console. 102 | 103 | ## Error Message: failed to create site 104 | 105 | Check that your control is marked as 'Safe for Scripting'. The only way to load a control that is not marked as safe for scripting is to make it 'well known' (refer to [Documentation#Providing_a_Well_Known_Control_List Providing a Well Known Control List]) and set the `TrustWellKnown` flag to true. 106 | 107 | # Final Note 108 | 109 | If you find this plugin useful and decide to use it, I'd love it if you drop me a line and tell me about it. 110 | 111 | # Author 112 | Developed by Leeor Aharon, at [CloudShare Ltd](http://www.cloudshare.com). 113 | -------------------------------------------------------------------------------- /chrome/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | // Required 3 | "name": "ActiveX hosting plugin", 4 | "homepage_url": "http://code.google.com/p/ff-activex-host/", 5 | "version": "1.38", 6 | 7 | // Recommended 8 | "description": "ActiveX hosting plugin", 9 | 10 | // Add any of these that you need 11 | "plugins": [ 12 | { 13 | "path": "npffax.dll", "public": true 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /dist/Dummy.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leeor/ff-activex-host/673df0d08eb99fad1a694b7a6d9fc12252f8cd87/dist/Dummy.dat -------------------------------------------------------------------------------- /ffactivex.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffactivex", "ffactivex\ffactivex.vcproj", "{B9ACDB28-1D44-4392-A2F1-83CFFD0C3376}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "transver", "transver\transver.vcproj", "{BCA84714-F877-4CDC-9C71-38861C7C0869}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B9ACDB28-1D44-4392-A2F1-83CFFD0C3376}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {B9ACDB28-1D44-4392-A2F1-83CFFD0C3376}.Debug|Win32.Build.0 = Debug|Win32 16 | {B9ACDB28-1D44-4392-A2F1-83CFFD0C3376}.Release|Win32.ActiveCfg = Release|Win32 17 | {B9ACDB28-1D44-4392-A2F1-83CFFD0C3376}.Release|Win32.Build.0 = Release|Win32 18 | {BCA84714-F877-4CDC-9C71-38861C7C0869}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {BCA84714-F877-4CDC-9C71-38861C7C0869}.Debug|Win32.Build.0 = Debug|Win32 20 | {BCA84714-F877-4CDC-9C71-38861C7C0869}.Release|Win32.ActiveCfg = Release|Win32 21 | {BCA84714-F877-4CDC-9C71-38861C7C0869}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /ffactivex/GenericNPObject.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Alternatively, the contents of this file may be used under the terms of 21 | * either the GNU General Public License Version 2 or later (the "GPL"), or 22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 23 | * in which case the provisions of the GPL or the LGPL are applicable instead 24 | * of those above. If you wish to allow use of your version of this file only 25 | * under the terms of either the GPL or the LGPL, and not to allow others to 26 | * use your version of this file under the terms of the MPL, indicate your 27 | * decision by deleting the provisions above and replace them with the notice 28 | * and other provisions required by the GPL or the LGPL. If you do not delete 29 | * the provisions above, a recipient may use your version of this file under 30 | * the terms of any one of the MPL, the GPL or the LGPL. 31 | * 32 | * ***** END LICENSE BLOCK ***** */ 33 | 34 | #include 35 | #include 36 | #include "GenericNPObject.h" 37 | 38 | static NPObject* 39 | AllocateGenericNPObject(NPP npp, NPClass *aClass) 40 | { 41 | return new GenericNPObject(npp, false); 42 | } 43 | 44 | static NPObject* 45 | AllocateMethodNPObject(NPP npp, NPClass *aClass) 46 | { 47 | return new GenericNPObject(npp, true); 48 | } 49 | 50 | static void 51 | DeallocateGenericNPObject(NPObject *obj) 52 | { 53 | if (!obj) { 54 | 55 | return; 56 | } 57 | 58 | GenericNPObject *m = (GenericNPObject *)obj; 59 | delete m; 60 | } 61 | 62 | static void 63 | InvalidateGenericNPObject(NPObject *obj) 64 | { 65 | if (!obj) { 66 | 67 | return; 68 | } 69 | 70 | ((GenericNPObject *)obj)->Invalidate(); 71 | } 72 | 73 | NPClass GenericNPObjectClass = { 74 | /* version */ NP_CLASS_STRUCT_VERSION, 75 | /* allocate */ AllocateGenericNPObject, 76 | /* deallocate */ DeallocateGenericNPObject, 77 | /* invalidate */ InvalidateGenericNPObject, 78 | /* hasMethod */ GenericNPObject::_HasMethod, 79 | /* invoke */ GenericNPObject::_Invoke, 80 | /* invokeDefault */ GenericNPObject::_InvokeDefault, 81 | /* hasProperty */ GenericNPObject::_HasProperty, 82 | /* getProperty */ GenericNPObject::_GetProperty, 83 | /* setProperty */ GenericNPObject::_SetProperty, 84 | /* removeProperty */ GenericNPObject::_RemoveProperty, 85 | /* enumerate */ GenericNPObject::_Enumerate, 86 | /* construct */ NULL 87 | }; 88 | 89 | NPClass MethodNPObjectClass = { 90 | /* version */ NP_CLASS_STRUCT_VERSION, 91 | /* allocate */ AllocateMethodNPObject, 92 | /* deallocate */ DeallocateGenericNPObject, 93 | /* invalidate */ InvalidateGenericNPObject, 94 | /* hasMethod */ GenericNPObject::_HasMethod, 95 | /* invoke */ GenericNPObject::_Invoke, 96 | /* invokeDefault */ GenericNPObject::_InvokeDefault, 97 | /* hasProperty */ GenericNPObject::_HasProperty, 98 | /* getProperty */ GenericNPObject::_GetProperty, 99 | /* setProperty */ GenericNPObject::_SetProperty, 100 | /* removeProperty */ GenericNPObject::_RemoveProperty, 101 | /* enumerate */ GenericNPObject::_Enumerate, 102 | /* construct */ NULL 103 | }; 104 | 105 | // Some standard JavaScript methods 106 | 107 | bool toString(void *object, const NPVariant *args, uint32_t argCount, NPVariant *result) { 108 | 109 | GenericNPObject *map = (GenericNPObject *)object; 110 | 111 | if (!map || map->invalid) return false; 112 | 113 | // no args expected or cared for... 114 | 115 | std::string out; 116 | std::vector::iterator it; 117 | for (it = map->numeric_mapper.begin(); it < map->numeric_mapper.end(); ++it) { 118 | 119 | if (NPVARIANT_IS_VOID(*it)) { 120 | 121 | out += ","; 122 | } 123 | else if (NPVARIANT_IS_NULL(*it)) { 124 | 125 | out += ","; 126 | } 127 | else if (NPVARIANT_IS_BOOLEAN(*it)) { 128 | 129 | if ((*it).value.boolValue) { 130 | 131 | out += "true,"; 132 | } 133 | else { 134 | 135 | out += "false,"; 136 | } 137 | } 138 | else if (NPVARIANT_IS_INT32(*it)) { 139 | 140 | char tmp[50]; 141 | memset(tmp, 0, sizeof(tmp)); 142 | _snprintf(tmp, 49, "%d,", (*it).value.intValue); 143 | out += tmp; 144 | } 145 | else if (NPVARIANT_IS_DOUBLE(*it)) { 146 | 147 | char tmp[50]; 148 | memset(tmp, 0, sizeof(tmp)); 149 | _snprintf(tmp, 49, "%f,", (*it).value.doubleValue); 150 | out += tmp; 151 | } 152 | else if (NPVARIANT_IS_STRING(*it)) { 153 | 154 | out += (*it).value.stringValue.UTF8Characters; 155 | out += ","; 156 | } 157 | else if (NPVARIANT_IS_OBJECT(*it)) { 158 | 159 | out += "[object],"; 160 | } 161 | } 162 | 163 | // calculate how much space we need 164 | std::string::size_type size = out.length(); 165 | 166 | char *s = (char *)NPNFuncs.memalloc(size * sizeof(char)); 167 | if (NULL == s) { 168 | 169 | return false; 170 | } 171 | 172 | memcpy(s, out.c_str(), size); 173 | s[size - 1] = 0; // overwrite the last "," 174 | STRINGZ_TO_NPVARIANT(s, (*result)); 175 | return true; 176 | } 177 | 178 | // Some helpers 179 | 180 | static void free_numeric_element(NPVariant elem) { 181 | 182 | NPNFuncs.releasevariantvalue(&elem); 183 | } 184 | 185 | static void free_alpha_element(std::pair elem) { 186 | 187 | NPNFuncs.releasevariantvalue(&(elem.second)); 188 | } 189 | 190 | // And now the GenericNPObject implementation 191 | 192 | GenericNPObject::GenericNPObject(NPP instance, bool isMethodObj): 193 | invalid(false), defInvoker(NULL), defInvokerObject(NULL) { 194 | 195 | NPVariant val; 196 | 197 | INT32_TO_NPVARIANT(0, val); 198 | immutables["length"] = val; 199 | 200 | if (!isMethodObj) { 201 | 202 | NPObject *obj = NULL; 203 | obj = NPNFuncs.createobject(instance, &MethodNPObjectClass); 204 | if (NULL == obj) { 205 | 206 | throw NULL; 207 | } 208 | ((GenericNPObject *)obj)->SetDefaultInvoker(&toString, this); 209 | 210 | OBJECT_TO_NPVARIANT(obj, val); 211 | immutables["toString"] = val; 212 | } 213 | } 214 | 215 | GenericNPObject::~GenericNPObject() { 216 | 217 | for_each(immutables.begin(), immutables.end(), free_alpha_element); 218 | for_each(alpha_mapper.begin(), alpha_mapper.end(), free_alpha_element); 219 | for_each(numeric_mapper.begin(), numeric_mapper.end(), free_numeric_element); 220 | } 221 | 222 | bool GenericNPObject::HasMethod(NPIdentifier name) { 223 | 224 | if (invalid) return false; 225 | 226 | if (NPNFuncs.identifierisstring(name)) { 227 | 228 | char *key = NPNFuncs.utf8fromidentifier(name); 229 | if (immutables.count(key) > 0) { 230 | 231 | if (NPVARIANT_IS_OBJECT(immutables[key])) { 232 | 233 | return (NULL != immutables[key].value.objectValue->_class->invokeDefault); 234 | } 235 | } 236 | else if (alpha_mapper.count(key) > 0) { 237 | 238 | if (NPVARIANT_IS_OBJECT(alpha_mapper[key])) { 239 | 240 | return (NULL != alpha_mapper[key].value.objectValue->_class->invokeDefault); 241 | } 242 | } 243 | } 244 | 245 | return false; 246 | } 247 | 248 | bool GenericNPObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) { 249 | 250 | if (invalid) return false; 251 | 252 | if (NPNFuncs.identifierisstring(name)) { 253 | 254 | char *key = NPNFuncs.utf8fromidentifier(name); 255 | if (immutables.count(key) > 0) { 256 | 257 | if ( NPVARIANT_IS_OBJECT(immutables[key]) 258 | && immutables[key].value.objectValue->_class->invokeDefault) { 259 | 260 | return immutables[key].value.objectValue->_class->invokeDefault(immutables[key].value.objectValue, args, argCount, result); 261 | } 262 | } 263 | else if (alpha_mapper.count(key) > 0) { 264 | 265 | if ( NPVARIANT_IS_OBJECT(alpha_mapper[key]) 266 | && alpha_mapper[key].value.objectValue->_class->invokeDefault) { 267 | 268 | return alpha_mapper[key].value.objectValue->_class->invokeDefault(alpha_mapper[key].value.objectValue, args, argCount, result); 269 | } 270 | } 271 | } 272 | 273 | return true; 274 | } 275 | 276 | bool GenericNPObject::InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result) { 277 | 278 | if (invalid) return false; 279 | 280 | if (defInvoker) { 281 | 282 | defInvoker(defInvokerObject, args, argCount, result); 283 | } 284 | 285 | return true; 286 | } 287 | 288 | // This method is also called before the JS engine attempts to add a new 289 | // property, most likely it's trying to check that the key is supported. 290 | // It only returns false if the string name was not found, or does not 291 | // hold a callable object 292 | bool GenericNPObject::HasProperty(NPIdentifier name) { 293 | 294 | if (invalid) return false; 295 | 296 | if (NPNFuncs.identifierisstring(name)) { 297 | 298 | char *key = NPNFuncs.utf8fromidentifier(name); 299 | if (immutables.count(key) > 0) { 300 | 301 | if (NPVARIANT_IS_OBJECT(immutables[key])) { 302 | 303 | return (NULL == immutables[key].value.objectValue->_class->invokeDefault); 304 | } 305 | } 306 | else if (alpha_mapper.count(key) > 0) { 307 | 308 | if (NPVARIANT_IS_OBJECT(alpha_mapper[key])) { 309 | 310 | return (NULL == alpha_mapper[key].value.objectValue->_class->invokeDefault); 311 | } 312 | } 313 | 314 | return false; 315 | } 316 | 317 | return true; 318 | } 319 | 320 | static bool CopyNPVariant(NPVariant *dst, const NPVariant *src) 321 | { 322 | dst->type = src->type; 323 | if (NPVARIANT_IS_STRING(*src)) { 324 | 325 | NPUTF8 *str = (NPUTF8 *)NPNFuncs.memalloc((src->value.stringValue.UTF8Length + 1) * sizeof(NPUTF8)); 326 | if (NULL == str) { 327 | 328 | return false; 329 | } 330 | dst->value.stringValue.UTF8Length = src->value.stringValue.UTF8Length; 331 | 332 | memcpy(str, src->value.stringValue.UTF8Characters, src->value.stringValue.UTF8Length); 333 | str[dst->value.stringValue.UTF8Length] = 0; 334 | 335 | dst->value.stringValue.UTF8Characters = str; 336 | } 337 | else if (NPVARIANT_IS_OBJECT(*src)) { 338 | 339 | NPNFuncs.retainobject(NPVARIANT_TO_OBJECT(*src)); 340 | dst->value.objectValue = src->value.objectValue; 341 | } 342 | else { 343 | 344 | dst->value = src->value; 345 | } 346 | 347 | return true; 348 | } 349 | 350 | #define MIN(x, y) ((x) < (y)) ? (x) : (y) 351 | 352 | bool GenericNPObject::GetProperty(NPIdentifier name, NPVariant *result) { 353 | 354 | if (invalid) return false; 355 | 356 | try { 357 | if (NPNFuncs.identifierisstring(name)) { 358 | 359 | char *key = NPNFuncs.utf8fromidentifier(name); 360 | if (immutables.count(key) > 0) { 361 | 362 | if (!CopyNPVariant(result, &(immutables[key]))) { 363 | 364 | return false; 365 | } 366 | } 367 | else if (alpha_mapper.count(key) > 0) { 368 | 369 | if (!CopyNPVariant(result, &(alpha_mapper[key]))) { 370 | 371 | return false; 372 | } 373 | } 374 | } 375 | else { 376 | // assume int... 377 | unsigned long key = (unsigned long)NPNFuncs.intfromidentifier(name); 378 | if (numeric_mapper.size() > key) { 379 | 380 | if (!CopyNPVariant(result, &(numeric_mapper[key]))) { 381 | 382 | return false; 383 | } 384 | } 385 | } 386 | } 387 | catch (...) { 388 | } 389 | 390 | return true; 391 | } 392 | 393 | bool GenericNPObject::SetProperty(NPIdentifier name, const NPVariant *value) { 394 | 395 | if (invalid) return false; 396 | 397 | try { 398 | if (NPNFuncs.identifierisstring(name)) { 399 | 400 | char *key = NPNFuncs.utf8fromidentifier(name); 401 | if (immutables.count(key) > 0) { 402 | // the key is already defined as immutable, check the new value type 403 | if (value->type != immutables[key].type) { 404 | 405 | return false; 406 | } 407 | 408 | // Seems ok, copy the new value 409 | if (!CopyNPVariant(&(immutables[key]), value)) { 410 | 411 | return false; 412 | } 413 | } 414 | else if (!CopyNPVariant(&(alpha_mapper[key]), value)) { 415 | 416 | return false; 417 | } 418 | } 419 | else { 420 | // assume int... 421 | NPVariant var; 422 | if (!CopyNPVariant(&var, value)) { 423 | 424 | return false; 425 | } 426 | 427 | unsigned long key = (unsigned long)NPNFuncs.intfromidentifier(name); 428 | if (key >= numeric_mapper.size()) { 429 | // there's a gap we need to fill 430 | NPVariant pad; 431 | VOID_TO_NPVARIANT(pad); 432 | numeric_mapper.insert(numeric_mapper.end(), key - numeric_mapper.size() + 1, pad); 433 | } 434 | numeric_mapper.at(key) = var; 435 | NPVARIANT_TO_INT32(immutables["length"])++; 436 | } 437 | } 438 | catch (...) { 439 | } 440 | 441 | return true; 442 | } 443 | 444 | bool GenericNPObject::RemoveProperty(NPIdentifier name) { 445 | 446 | if (invalid) return false; 447 | 448 | try { 449 | if (NPNFuncs.identifierisstring(name)) { 450 | 451 | char *key = NPNFuncs.utf8fromidentifier(name); 452 | if (alpha_mapper.count(key) > 0) { 453 | 454 | NPNFuncs.releasevariantvalue(&(alpha_mapper[key])); 455 | alpha_mapper.erase(key); 456 | } 457 | } 458 | else { 459 | // assume int... 460 | unsigned long key = (unsigned long)NPNFuncs.intfromidentifier(name); 461 | if (numeric_mapper.size() > key) { 462 | 463 | NPNFuncs.releasevariantvalue(&(numeric_mapper[key])); 464 | numeric_mapper.erase(numeric_mapper.begin() + key); 465 | } 466 | NPVARIANT_TO_INT32(immutables["length"])--; 467 | } 468 | } 469 | catch (...) { 470 | } 471 | 472 | return true; 473 | } 474 | 475 | bool GenericNPObject::Enumerate(NPIdentifier **identifiers, uint32_t *identifierCount) { 476 | 477 | if (invalid) return false; 478 | 479 | try { 480 | *identifiers = (NPIdentifier *)NPNFuncs.memalloc(sizeof(NPIdentifier) * numeric_mapper.size()); 481 | if (NULL == *identifiers) { 482 | 483 | return false; 484 | } 485 | *identifierCount = 0; 486 | 487 | std::vector::iterator it; 488 | unsigned int i = 0; 489 | char str[10] = ""; 490 | for (it = numeric_mapper.begin(); it < numeric_mapper.end(); ++it, ++i) { 491 | 492 | // skip empty (padding) elements 493 | if (NPVARIANT_IS_VOID(*it)) continue; 494 | _snprintf(str, sizeof(str), "%u", i); 495 | (*identifiers)[(*identifierCount)++] = NPNFuncs.getstringidentifier(str); 496 | } 497 | } 498 | catch (...) { 499 | } 500 | 501 | return true; 502 | } 503 | -------------------------------------------------------------------------------- /ffactivex/GenericNPObject.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Alternatively, the contents of this file may be used under the terms of 21 | * either the GNU General Public License Version 2 or later (the "GPL"), or 22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 23 | * in which case the provisions of the GPL or the LGPL are applicable instead 24 | * of those above. If you wish to allow use of your version of this file only 25 | * under the terms of either the GPL or the LGPL, and not to allow others to 26 | * use your version of this file under the terms of the MPL, indicate your 27 | * decision by deleting the provisions above and replace them with the notice 28 | * and other provisions required by the GPL or the LGPL. If you do not delete 29 | * the provisions above, a recipient may use your version of this file under 30 | * the terms of any one of the MPL, the GPL or the LGPL. 31 | * 32 | * ***** END LICENSE BLOCK ***** */ 33 | 34 | #pragma once 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include "variants.h" 44 | 45 | extern NPNetscapeFuncs NPNFuncs; 46 | extern NPClass GenericNPObjectClass; 47 | 48 | typedef bool (*DefaultInvoker)(void *object, const NPVariant *args, uint32_t argCount, NPVariant *result); 49 | 50 | struct ltnum 51 | { 52 | bool operator()(long n1, long n2) const 53 | { 54 | return n1 < n2; 55 | } 56 | }; 57 | 58 | struct ltstr 59 | { 60 | bool operator()(const char* s1, const char* s2) const 61 | { 62 | return strcmp(s1, s2) < 0; 63 | } 64 | }; 65 | 66 | bool toString(void *object, const NPVariant *args, uint32_t argCount, NPVariant *result); 67 | 68 | class GenericNPObject: public NPObject 69 | { 70 | private: 71 | GenericNPObject(const GenericNPObject &); 72 | 73 | bool invalid; 74 | DefaultInvoker defInvoker; 75 | void *defInvokerObject; 76 | 77 | std::vector numeric_mapper; 78 | // the members of alpha mapper can be reassigned to anything the user wishes 79 | std::map alpha_mapper; 80 | // these cannot accept other types than they are initially defined with 81 | std::map immutables; 82 | 83 | public: 84 | friend bool toString(void *, const NPVariant *, uint32_t, NPVariant *); 85 | 86 | GenericNPObject(NPP instance); 87 | GenericNPObject(NPP instance, bool isMethodObj); 88 | ~GenericNPObject(); 89 | 90 | void Invalidate() {invalid = true;} 91 | 92 | void SetDefaultInvoker(DefaultInvoker di, void *context) { 93 | 94 | defInvoker = di; 95 | defInvokerObject = context; 96 | } 97 | 98 | static bool _HasMethod(NPObject *npobj, NPIdentifier name) { 99 | 100 | return ((GenericNPObject *)npobj)->HasMethod(name); 101 | } 102 | 103 | static bool _Invoke(NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) { 104 | 105 | return ((GenericNPObject *)npobj)->Invoke(methodName, args, argCount, result); 106 | } 107 | 108 | static bool _InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) { 109 | 110 | if (((GenericNPObject *)npobj)->defInvoker) { 111 | 112 | return (((GenericNPObject *)npobj)->InvokeDefault)(args, argCount, result); 113 | } 114 | else { 115 | 116 | return false; 117 | } 118 | } 119 | 120 | static bool _HasProperty(NPObject *npobj, NPIdentifier name) { 121 | 122 | return ((GenericNPObject *)npobj)->HasProperty(name); 123 | } 124 | 125 | static bool _GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) { 126 | 127 | return ((GenericNPObject *)npobj)->GetProperty(name, result); 128 | } 129 | 130 | static bool _SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) { 131 | 132 | return ((GenericNPObject *)npobj)->SetProperty(name, value); 133 | } 134 | 135 | static bool _RemoveProperty(NPObject *npobj, NPIdentifier name) { 136 | 137 | return ((GenericNPObject *)npobj)->RemoveProperty(name); 138 | } 139 | 140 | static bool _Enumerate(NPObject *npobj, NPIdentifier **identifiers, uint32_t *identifierCount) { 141 | 142 | return ((GenericNPObject *)npobj)->Enumerate(identifiers, identifierCount); 143 | } 144 | 145 | bool HasMethod(NPIdentifier name); 146 | bool Invoke(NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); 147 | bool InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result); 148 | bool HasProperty(NPIdentifier name); 149 | bool GetProperty(NPIdentifier name, NPVariant *result); 150 | bool SetProperty(NPIdentifier name, const NPVariant *value); 151 | bool RemoveProperty(NPIdentifier name); 152 | bool Enumerate(NPIdentifier **identifiers, uint32_t *identifierCount); 153 | }; 154 | -------------------------------------------------------------------------------- /ffactivex/authorize.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is RSJ Software GmbH code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * RSJ Software GmbH. 19 | * Portions created by the Initial Developer are Copyright (C) 2009 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributors: 23 | * Ruediger Jungbeck 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | #include 40 | 41 | #include 42 | #include 43 | 44 | #include "ffactivex.h" 45 | #include "common/stdafx.h" 46 | #include "axhost.h" 47 | #include "atlutil.h" 48 | 49 | #include "authorize.h" 50 | 51 | // ---------------------------------------------------------------------------- 52 | #define SUB_KEY L"SOFTWARE\\MozillaPlugins\\@itstructures.com/ffactivex\\MimeTypes\\application/x-itst-activex" 53 | 54 | // ---------------------------------------------------------------------------- 55 | 56 | BOOL TestExplicitAuthorizationUTF8 (const char *MimeType, 57 | const char *AuthorizationType, 58 | const char *DocumentUrl, 59 | const char *ProgramId); 60 | 61 | BOOL TestExplicitAuthorization (const wchar_t *MimeType, 62 | const wchar_t *AuthorizationType, 63 | const wchar_t *DocumentUrl, 64 | const wchar_t *ProgramId); 65 | 66 | BOOL WildcardMatch (const wchar_t *Mask, 67 | const wchar_t *Value); 68 | 69 | HKEY FindKey (const wchar_t *MimeType, 70 | const wchar_t *AuthorizationType); 71 | 72 | // --------------------------------------------------------------------------- 73 | 74 | HKEY BaseKeys[] = { 75 | HKEY_CURRENT_USER, 76 | HKEY_LOCAL_MACHINE 77 | }; 78 | 79 | // ---------------------------------------------------------------------------- 80 | 81 | BOOL TestAuthorization (NPP Instance, 82 | int16 ArgC, 83 | char *ArgN[], 84 | char *ArgV[], 85 | const char *MimeType) 86 | { 87 | BOOL ret = FALSE; 88 | NPObject *globalObj = NULL; 89 | NPIdentifier identifier; 90 | NPVariant varLocation; 91 | NPVariant varHref; 92 | bool rc = false; 93 | int16 i; 94 | char *wrkHref; 95 | 96 | #ifdef NDEF 97 | _asm{int 3}; 98 | #endif 99 | if (Instance == NULL) { 100 | 101 | return (FALSE); 102 | } 103 | 104 | // Determine owning document 105 | // Get the window object. 106 | NPNFuncs.getvalue(Instance, 107 | NPNVWindowNPObject, 108 | &globalObj); 109 | 110 | // Create a "location" identifier. 111 | identifier = NPNFuncs.getstringidentifier("location"); 112 | 113 | // Get the location property from the window object (which is another object). 114 | rc = NPNFuncs.getproperty(Instance, 115 | globalObj, 116 | identifier, 117 | &varLocation); 118 | 119 | NPNFuncs.releaseobject(globalObj); 120 | 121 | if (!rc){ 122 | 123 | log(Instance, 0, "AxHost.TestAuthorization: could not get the location from the global object"); 124 | return false; 125 | } 126 | 127 | // Get a pointer to the "location" object. 128 | NPObject *locationObj = varLocation.value.objectValue; 129 | 130 | // Create a "href" identifier. 131 | identifier = NPNFuncs.getstringidentifier("href"); 132 | 133 | // Get the location property from the location object. 134 | rc = NPNFuncs.getproperty(Instance, 135 | locationObj, 136 | identifier, 137 | &varHref); 138 | 139 | NPNFuncs.releasevariantvalue(&varLocation); 140 | 141 | if (!rc) { 142 | 143 | log(Instance, 0, "AxHost.TestAuthorization: could not get the href from the location property"); 144 | return false; 145 | } 146 | 147 | ret = TRUE; 148 | 149 | wrkHref = (char *) alloca(varHref.value.stringValue.UTF8Length + 1); 150 | 151 | memcpy(wrkHref, 152 | varHref.value.stringValue.UTF8Characters, 153 | varHref.value.stringValue.UTF8Length); 154 | 155 | wrkHref[varHref.value.stringValue.UTF8Length] = 0x00; 156 | NPNFuncs.releasevariantvalue(&varHref); 157 | 158 | for (i = 0; 159 | i < ArgC; 160 | ++i) { 161 | 162 | // search for any needed information: clsid, event handling directives, etc. 163 | if (0 == strnicmp(ArgN[i], PARAM_CLSID, strlen(PARAM_CLSID))) { 164 | 165 | ret &= TestExplicitAuthorizationUTF8(MimeType, 166 | PARAM_CLSID, 167 | wrkHref, 168 | ArgV[i]); 169 | } else if (0 == strnicmp(ArgN[i], PARAM_PROGID, strlen(PARAM_PROGID))) { 170 | // The class id of the control we are asked to load 171 | ret &= TestExplicitAuthorizationUTF8(MimeType, 172 | PARAM_PROGID, 173 | wrkHref, 174 | ArgV[i]); 175 | } else if( 0 == strnicmp(ArgN[i], PARAM_CODEBASEURL, strlen(PARAM_CODEBASEURL))) { 176 | ret &= TestExplicitAuthorizationUTF8(MimeType, 177 | PARAM_CODEBASEURL, 178 | wrkHref, 179 | ArgV[i]); 180 | } 181 | } 182 | 183 | log(Instance, 1, "AxHost.TestAuthorization: returning %s", ret ? "True" : "False"); 184 | return (ret); 185 | } 186 | 187 | // ---------------------------------------------------------------------------- 188 | 189 | BOOL TestExplicitAuthorizationUTF8 (const char *MimeType, 190 | const char *AuthorizationType, 191 | const char *DocumentUrl, 192 | const char *ProgramId) 193 | { 194 | USES_CONVERSION; 195 | BOOL ret; 196 | 197 | ret = TestExplicitAuthorization(A2W(MimeType), 198 | A2W(AuthorizationType), 199 | A2W(DocumentUrl), 200 | A2W(ProgramId)); 201 | 202 | return (ret); 203 | } 204 | 205 | // ---------------------------------------------------------------------------- 206 | 207 | BOOL TestExplicitAuthorization (const wchar_t *MimeType, 208 | const wchar_t *AuthorizationType, 209 | const wchar_t *DocumentUrl, 210 | const wchar_t *ProgramId) 211 | { 212 | BOOL ret = FALSE; 213 | 214 | #ifndef NO_REGISTRY_AUTHORIZE 215 | 216 | HKEY hKey; 217 | HKEY hSubKey; 218 | ULONG i; 219 | ULONG j; 220 | ULONG keyNameLen; 221 | ULONG valueNameLen; 222 | wchar_t keyName[_MAX_PATH]; 223 | wchar_t valueName[_MAX_PATH]; 224 | 225 | if (DocumentUrl == NULL) { 226 | 227 | return (FALSE); 228 | } 229 | 230 | if (ProgramId == NULL) { 231 | 232 | return (FALSE); 233 | } 234 | 235 | #ifdef NDEF 236 | MessageBox(NULL, 237 | DocumentUrl, 238 | ProgramId, 239 | MB_OK); 240 | #endif 241 | 242 | if ((hKey = FindKey(MimeType, 243 | AuthorizationType)) != NULL) { 244 | 245 | for (i = 0; 246 | !ret; 247 | i++) { 248 | 249 | keyNameLen = sizeof(keyName); 250 | 251 | if (RegEnumKey(hKey, 252 | i, 253 | keyName, 254 | keyNameLen) == ERROR_SUCCESS) { 255 | 256 | if (WildcardMatch(keyName, 257 | DocumentUrl)) { 258 | 259 | if (RegOpenKeyEx(hKey, 260 | keyName, 261 | 0, 262 | KEY_QUERY_VALUE, 263 | &hSubKey) == ERROR_SUCCESS) { 264 | 265 | for (j = 0; 266 | ; 267 | j++) { 268 | 269 | valueNameLen = sizeof(valueName); 270 | 271 | if (RegEnumValue(hSubKey, 272 | j, 273 | valueName, 274 | &valueNameLen, 275 | NULL, 276 | NULL, 277 | NULL, 278 | NULL) != ERROR_SUCCESS) { 279 | 280 | break; 281 | } 282 | if (WildcardMatch(valueName, 283 | ProgramId)) { 284 | 285 | ret = TRUE; 286 | break; 287 | } 288 | } 289 | RegCloseKey(hSubKey); 290 | } 291 | if (ret) { 292 | 293 | break; 294 | } 295 | } 296 | } else { 297 | 298 | break; 299 | } 300 | } 301 | RegCloseKey(hKey); 302 | } 303 | #endif 304 | 305 | return (ret); 306 | } 307 | // ---------------------------------------------------------------------------- 308 | 309 | BOOL WildcardMatch (const wchar_t *Mask, 310 | const wchar_t *Value) 311 | { 312 | size_t i; 313 | size_t j = 0; 314 | size_t maskLen; 315 | size_t valueLen; 316 | 317 | maskLen = wcslen(Mask); 318 | valueLen = wcslen(Value); 319 | 320 | for (i = 0; 321 | i < maskLen + 1; 322 | i++) { 323 | 324 | if (Mask[i] == '?') { 325 | 326 | j++; 327 | continue; 328 | } 329 | 330 | if (Mask[i] == '*') { 331 | for (; 332 | j < valueLen + 1; 333 | j++) { 334 | 335 | if (WildcardMatch(Mask + i + 1, 336 | Value + j)) { 337 | 338 | return (TRUE); 339 | } 340 | } 341 | return (FALSE); 342 | } 343 | 344 | if ((j <= valueLen) && 345 | (Mask[i] == tolower(Value[j]))) { 346 | 347 | j++; 348 | continue; 349 | } 350 | 351 | return (FALSE); 352 | } 353 | return (TRUE); 354 | } 355 | 356 | // ---------------------------------------------------------------------------- 357 | 358 | HKEY FindKey (const wchar_t *MimeType, 359 | const wchar_t *AuthorizationType) 360 | { 361 | HKEY ret = NULL; 362 | HKEY plugins; 363 | wchar_t searchKey[_MAX_PATH]; 364 | wchar_t pluginName[_MAX_PATH]; 365 | DWORD j; 366 | size_t i; 367 | 368 | for (i = 0; 369 | i < ARRAYSIZE(BaseKeys); 370 | i++) { 371 | 372 | if (RegOpenKeyEx(BaseKeys[i], 373 | L"SOFTWARE\\MozillaPlugins", 374 | 0, 375 | KEY_ENUMERATE_SUB_KEYS, 376 | &plugins) == ERROR_SUCCESS) { 377 | 378 | for (j = 0; 379 | ret == NULL; 380 | j++) { 381 | 382 | if (RegEnumKey(plugins, 383 | j, 384 | pluginName, 385 | sizeof(pluginName)) != ERROR_SUCCESS) { 386 | 387 | break; 388 | } 389 | 390 | wsprintf(searchKey, 391 | L"%s\\MimeTypes\\%s\\%s", 392 | pluginName, 393 | MimeType, 394 | AuthorizationType); 395 | 396 | if (RegOpenKeyEx(plugins, 397 | searchKey, 398 | 0, 399 | KEY_ENUMERATE_SUB_KEYS, 400 | &ret) == ERROR_SUCCESS) { 401 | 402 | break; 403 | } 404 | 405 | ret = NULL; 406 | } 407 | 408 | RegCloseKey(plugins); 409 | 410 | if (ret != NULL) { 411 | 412 | break; 413 | } 414 | } 415 | } 416 | 417 | return (ret); 418 | } 419 | -------------------------------------------------------------------------------- /ffactivex/authorize.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is RSJ Software GmbH code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * RSJ Software GmbH. 19 | * Portions created by the Initial Developer are Copyright (C) 2009 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributors: 23 | * Ruediger Jungbeck 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | BOOL TestAuthorization (NPP Instance, 40 | int16 ArgC, 41 | char *ArgN[], 42 | char *ArgV[], 43 | const char *MimeType); -------------------------------------------------------------------------------- /ffactivex/axhost.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Contributor: 21 | * Ruediger Jungbeck 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | #include 38 | #include "ffactivex.h" 39 | #include "scriptable.h" 40 | #include "axhost.h" 41 | 42 | #ifdef NO_REGISTRY_AUTHORIZE 43 | 44 | static const char *WellKnownProgIds[] = { 45 | NULL 46 | }; 47 | 48 | static const char *WellKnownClsIds[] = { 49 | NULL 50 | }; 51 | 52 | #endif 53 | 54 | static const bool AcceptOnlyWellKnown = false; 55 | static const bool TrustWellKnown = true; 56 | 57 | static bool 58 | isWellKnownProgId(const char *progid) 59 | { 60 | #ifdef NO_REGISTRY_AUTHORIZE 61 | 62 | unsigned int i = 0; 63 | 64 | if (!progid) { 65 | 66 | return false; 67 | } 68 | 69 | while (WellKnownProgIds[i]) { 70 | 71 | if (!strnicmp(WellKnownProgIds[i], progid, strlen(WellKnownProgIds[i]))) 72 | return true; 73 | 74 | ++i; 75 | } 76 | 77 | return false; 78 | #else 79 | return true; 80 | #endif 81 | } 82 | 83 | static bool 84 | isWellKnownClsId(const char *clsid) 85 | { 86 | #ifdef NO_REGISTRY_AUTHORIZE 87 | unsigned int i = 0; 88 | 89 | if (!clsid) { 90 | 91 | return false; 92 | } 93 | 94 | while (WellKnownClsIds[i]) { 95 | 96 | if (!strnicmp(WellKnownClsIds[i], clsid, strlen(WellKnownClsIds[i]))) 97 | return true; 98 | 99 | ++i; 100 | } 101 | 102 | return false; 103 | #else 104 | return true; 105 | #endif 106 | } 107 | 108 | static LRESULT CALLBACK AxHostWinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 109 | { 110 | LRESULT result; 111 | 112 | CAxHost *host = (CAxHost *)GetWindowLong(hWnd, GWL_USERDATA); 113 | 114 | if (!host) { 115 | 116 | return DefWindowProc(hWnd, msg, wParam, lParam); 117 | } 118 | 119 | switch (msg) 120 | { 121 | case WM_SETFOCUS: 122 | case WM_KILLFOCUS: 123 | case WM_SIZE: 124 | if (host->Site) { 125 | 126 | host->Site->OnDefWindowMessage(msg, wParam, lParam, &result); 127 | return result; 128 | } 129 | else { 130 | 131 | return DefWindowProc(hWnd, msg, wParam, lParam); 132 | } 133 | 134 | // Window being destroyed 135 | case WM_DESTROY: 136 | break; 137 | 138 | default: 139 | return DefWindowProc(hWnd, msg, wParam, lParam); 140 | } 141 | 142 | return true; 143 | } 144 | 145 | CAxHost::~CAxHost() 146 | { 147 | log(instance, 0, "AxHost.~AXHost: destroying the control..."); 148 | 149 | if (Window){ 150 | 151 | if (OldProc) 152 | ::SetWindowLong(Window, GWL_WNDPROC, (LONG)OldProc); 153 | 154 | ::SetWindowLong(Window, GWL_USERDATA, (LONG)NULL); 155 | } 156 | 157 | if (Sink) { 158 | 159 | Sink->UnsubscribeFromEvents(); 160 | Sink->Release(); 161 | } 162 | 163 | if (Site) { 164 | 165 | Site->Detach(); 166 | Site->Release(); 167 | } 168 | 169 | CoFreeUnusedLibraries(); 170 | } 171 | 172 | CAxHost::CAxHost(NPP inst): 173 | instance(inst), 174 | ClsID(CLSID_NULL), 175 | isValidClsID(false), 176 | Sink(NULL), 177 | Site(NULL), 178 | Window(NULL), 179 | OldProc(NULL), 180 | Props(), 181 | isKnown(false), 182 | CodeBaseUrl(NULL) 183 | { 184 | } 185 | 186 | void 187 | CAxHost::setWindow(HWND win) 188 | { 189 | if (win != Window) { 190 | 191 | if (win) { 192 | // subclass window so we can intercept window messages and 193 | // do our drawing to it 194 | OldProc = (WNDPROC)::SetWindowLong(win, GWL_WNDPROC, (LONG)AxHostWinProc); 195 | 196 | // associate window with our CAxHost object so we can access 197 | // it in the window procedure 198 | ::SetWindowLong(win, GWL_USERDATA, (LONG)this); 199 | } 200 | else { 201 | if (OldProc) 202 | ::SetWindowLong(Window, GWL_WNDPROC, (LONG)OldProc); 203 | 204 | ::SetWindowLong(Window, GWL_USERDATA, (LONG)NULL); 205 | } 206 | 207 | Window = win; 208 | } 209 | } 210 | 211 | HWND 212 | CAxHost::getWinfow() 213 | { 214 | return Window; 215 | } 216 | 217 | void 218 | CAxHost::UpdateRect(RECT rcPos) 219 | { 220 | HRESULT hr = -1; 221 | 222 | if (Site && Window) { 223 | 224 | if (Site->GetParentWindow() == NULL) { 225 | 226 | hr = Site->Attach(Window, rcPos, NULL); 227 | if (FAILED(hr)) { 228 | 229 | log(instance, 0, "AxHost.UpdateRect: failed to attach control"); 230 | } 231 | } 232 | else { 233 | 234 | Site->SetPosition(rcPos); 235 | } 236 | 237 | // Ensure clipping on parent to keep child controls happy 238 | ::SetWindowLong(Window, GWL_STYLE, ::GetWindowLong(Window, GWL_STYLE) | WS_CLIPCHILDREN); 239 | } 240 | } 241 | 242 | bool 243 | CAxHost::verifyClsID(LPOLESTR oleClsID) 244 | { 245 | CRegKey keyExplorer; 246 | if (ERROR_SUCCESS == keyExplorer.Open(HKEY_LOCAL_MACHINE, 247 | _T("SOFTWARE\\Microsoft\\Internet Explorer\\ActiveX Compatibility"), 248 | KEY_READ)) { 249 | CRegKey keyCLSID; 250 | if (ERROR_SUCCESS == keyCLSID.Open(keyExplorer, W2T(oleClsID), KEY_READ)) { 251 | 252 | DWORD dwType = REG_DWORD; 253 | DWORD dwFlags = 0; 254 | DWORD dwBufSize = sizeof(dwFlags); 255 | if (ERROR_SUCCESS == ::RegQueryValueEx(keyCLSID, 256 | _T("Compatibility Flags"), 257 | NULL, 258 | &dwType, 259 | (LPBYTE) 260 | &dwFlags, 261 | &dwBufSize)) { 262 | // Flags for this reg key 263 | const DWORD kKillBit = 0x00000400; 264 | if (dwFlags & kKillBit) { 265 | 266 | log(instance, 0, "AxHost.verifyClsID: the control is marked as unsafe by IE kill bits"); 267 | return false; 268 | } 269 | } 270 | } 271 | } 272 | 273 | log(instance, 1, "AxHost.verifyClsID: verified successfully"); 274 | return true; 275 | } 276 | 277 | bool 278 | CAxHost::setClsID(const char *clsid) 279 | { 280 | HRESULT hr = -1; 281 | USES_CONVERSION; 282 | LPOLESTR oleClsID = A2OLE(clsid); 283 | 284 | if (isWellKnownClsId(clsid)) { 285 | 286 | isKnown = true; 287 | } 288 | else if (AcceptOnlyWellKnown) { 289 | 290 | log(instance, 0, "AxHost.setClsID: the requested CLSID is not on the Well Known list"); 291 | return false; 292 | } 293 | 294 | // Check the Internet Explorer list of vulnerable controls 295 | if (oleClsID && verifyClsID(oleClsID)) { 296 | 297 | hr = CLSIDFromString(oleClsID, &ClsID); 298 | if (SUCCEEDED(hr) && !::IsEqualCLSID(ClsID, CLSID_NULL)) { 299 | 300 | isValidClsID = true; 301 | log(instance, 1, "AxHost.setClsID: CLSID %s set", clsid); 302 | return true; 303 | } 304 | } 305 | 306 | log(instance, 0, "AxHost.setClsID: failed to set the requested clsid"); 307 | return false; 308 | } 309 | 310 | void CAxHost::setCodeBaseUrl(LPCWSTR codeBaseUrl) 311 | { 312 | CodeBaseUrl = codeBaseUrl; 313 | } 314 | 315 | bool 316 | CAxHost::setClsIDFromProgID(const char *progid) 317 | { 318 | HRESULT hr = -1; 319 | CLSID clsid = CLSID_NULL; 320 | USES_CONVERSION; 321 | LPOLESTR oleClsID = NULL; 322 | LPOLESTR oleProgID = A2OLE(progid); 323 | 324 | if (AcceptOnlyWellKnown) { 325 | 326 | if (isWellKnownProgId(progid)) { 327 | 328 | isKnown = true; 329 | } 330 | else { 331 | 332 | log(instance, 0, "AxHost.setClsIDFromProgID: the requested PROGID is not on the Well Known list"); 333 | return false; 334 | } 335 | } 336 | 337 | hr = CLSIDFromProgID(oleProgID, &clsid); 338 | if (FAILED(hr)) { 339 | 340 | log(instance, 0, "AxHost.setClsIDFromProgID: could not resolve PROGID"); 341 | return false; 342 | } 343 | 344 | hr = StringFromCLSID(clsid, &oleClsID); 345 | 346 | // Check the Internet Explorer list of vulnerable controls 347 | if ( SUCCEEDED(hr) 348 | && oleClsID 349 | && verifyClsID(oleClsID)) { 350 | 351 | ClsID = clsid; 352 | if (!::IsEqualCLSID(ClsID, CLSID_NULL)) { 353 | 354 | isValidClsID = true; 355 | log(instance, 1, "AxHost.setClsIDFromProgID: PROGID %s resolved and set", progid); 356 | return true; 357 | } 358 | } 359 | 360 | log(instance, 0, "AxHost.setClsIDFromProgID: failed to set the resolved CLSID"); 361 | return false; 362 | } 363 | 364 | bool 365 | CAxHost::hasValidClsID() 366 | { 367 | return isValidClsID; 368 | } 369 | 370 | bool 371 | CAxHost::CreateControl(bool subscribeToEvents) 372 | { 373 | if (!isValidClsID) { 374 | 375 | log(instance, 0, "AxHost.CreateControl: current location is not trusted"); 376 | return false; 377 | } 378 | 379 | // Create the control site 380 | CControlSiteInstance::CreateInstance(&Site); 381 | if (Site == NULL) { 382 | 383 | log(instance, 0, "AxHost.CreateControl: CreateInstance failed"); 384 | return false; 385 | } 386 | 387 | Site->m_bSupportWindowlessActivation = false; 388 | 389 | if (TrustWellKnown && isKnown) { 390 | 391 | Site->SetSecurityPolicy(NULL); 392 | Site->m_bSafeForScriptingObjectsOnly = false; 393 | } 394 | else { 395 | 396 | Site->m_bSafeForScriptingObjectsOnly = true; 397 | } 398 | 399 | Site->AddRef(); 400 | 401 | // Create the object 402 | HRESULT hr; 403 | hr = Site->Create(ClsID, Props, CodeBaseUrl); 404 | 405 | if (FAILED(hr)) { 406 | 407 | LPSTR lpMsgBuf; 408 | DWORD dw = GetLastError(); 409 | 410 | FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | 411 | FORMAT_MESSAGE_FROM_SYSTEM | 412 | FORMAT_MESSAGE_IGNORE_INSERTS, 413 | NULL, 414 | dw, 415 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 416 | (LPSTR) &lpMsgBuf, 417 | 0, 418 | NULL ); 419 | 420 | log(instance, 0, lpMsgBuf); 421 | log(instance, 0, "AxHost.CreateControl: failed to create site"); 422 | return false; 423 | } 424 | 425 | IUnknown *control = NULL; 426 | Site->GetControlUnknown(&control); 427 | if (!control) { 428 | 429 | log(instance, 0, "AxHost.CreateControl: failed to create control (was it just downloaded?)"); 430 | return false; 431 | } 432 | 433 | // Create the event sink 434 | CControlEventSinkInstance::CreateInstance(&Sink); 435 | Sink->AddRef(); 436 | Sink->instance = instance; 437 | hr = Sink->SubscribeToEvents(control); 438 | control->Release(); 439 | 440 | if (FAILED(hr) && subscribeToEvents) { 441 | 442 | LPSTR lpMsgBuf; 443 | DWORD dw = GetLastError(); 444 | 445 | FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | 446 | FORMAT_MESSAGE_FROM_SYSTEM | 447 | FORMAT_MESSAGE_IGNORE_INSERTS, 448 | NULL, 449 | dw, 450 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 451 | (LPSTR) &lpMsgBuf, 452 | 0, 453 | NULL ); 454 | 455 | log(instance, 0, lpMsgBuf); 456 | log(instance, 0, "AxHost.CreateControl: SubscribeToEvents failed"); 457 | return false; 458 | } 459 | 460 | log(instance, 1, "AxHost.CreateControl: control created successfully"); 461 | return true; 462 | } 463 | 464 | bool 465 | CAxHost::AddEventHandler(wchar_t *name, wchar_t *handler) 466 | { 467 | HRESULT hr; 468 | DISPID id = 0; 469 | USES_CONVERSION; 470 | LPOLESTR oleName = name; 471 | 472 | if (!Sink) { 473 | 474 | log(instance, 0, "AxHost.AddEventHandler: no valid sink"); 475 | return false; 476 | } 477 | 478 | hr = Sink->m_spEventSinkTypeInfo->GetIDsOfNames(&oleName, 1, &id); 479 | if (FAILED(hr)) { 480 | 481 | log(instance, 0, "AxHost.AddEventHandler: GetIDsOfNames failed to resolve event name"); 482 | return false; 483 | } 484 | 485 | Sink->events[id] = handler; 486 | log(instance, 1, "AxHost.AddEventHandler: handler %S set for event %S", handler, name); 487 | return true; 488 | } 489 | 490 | int16 491 | CAxHost::HandleEvent(void *event) 492 | { 493 | NPEvent *npEvent = (NPEvent *)event; 494 | LRESULT result = 0; 495 | 496 | if (!npEvent) { 497 | 498 | return 0; 499 | } 500 | 501 | // forward all events to the hosted control 502 | return (int16)Site->OnDefWindowMessage(npEvent->event, npEvent->wParam, npEvent->lParam, &result); 503 | } 504 | 505 | NPObject * 506 | CAxHost::GetScriptableObject() 507 | { 508 | IUnknown *unk; 509 | NPObject *obj = NPNFuncs.createobject(instance, &ScriptableNPClass); 510 | 511 | Site->GetControlUnknown(&unk); 512 | ((Scriptable *)obj)->setControl(unk); 513 | ((Scriptable *)obj)->setInstance(instance); 514 | 515 | return obj; 516 | } 517 | -------------------------------------------------------------------------------- /ffactivex/axhost.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Alternatively, the contents of this file may be used under the terms of 21 | * either the GNU General Public License Version 2 or later (the "GPL"), or 22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 23 | * in which case the provisions of the GPL or the LGPL are applicable instead 24 | * of those above. If you wish to allow use of your version of this file only 25 | * under the terms of either the GPL or the LGPL, and not to allow others to 26 | * use your version of this file under the terms of the MPL, indicate your 27 | * decision by deleting the provisions above and replace them with the notice 28 | * and other provisions required by the GPL or the LGPL. If you do not delete 29 | * the provisions above, a recipient may use your version of this file under 30 | * the terms of any one of the MPL, the GPL or the LGPL. 31 | * 32 | * ***** END LICENSE BLOCK ***** */ 33 | 34 | class CAxHost { 35 | private: 36 | CAxHost(const CAxHost &); 37 | 38 | NPP instance; 39 | bool isValidClsID; 40 | bool isKnown; 41 | 42 | protected: 43 | // The window handle to our plugin area in the browser 44 | HWND Window; 45 | WNDPROC OldProc; 46 | 47 | // The class/prog id of the control 48 | CLSID ClsID; 49 | LPCWSTR CodeBaseUrl; 50 | 51 | CControlEventSinkInstance *Sink; 52 | 53 | public: 54 | CAxHost(NPP inst); 55 | ~CAxHost(); 56 | 57 | CControlSiteInstance *Site; 58 | PropertyList Props; 59 | 60 | void setWindow(HWND win); 61 | HWND getWinfow(); 62 | void UpdateRect(RECT rcPos); 63 | 64 | bool verifyClsID(LPOLESTR oleClsID); 65 | bool setClsID(const char *clsid); 66 | bool setClsIDFromProgID(const char *progid); 67 | void setCodeBaseUrl(LPCWSTR clsid); 68 | bool hasValidClsID(); 69 | 70 | bool CreateControl(bool subscribeToEvents); 71 | 72 | bool AddEventHandler(wchar_t *name, wchar_t *handler); 73 | 74 | int16 HandleEvent(void *event); 75 | NPObject *GetScriptableObject(); 76 | }; 77 | -------------------------------------------------------------------------------- /ffactivex/common/ControlEventSink.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | #include "StdAfx.h" 40 | 41 | #include "ControlEventSink.h" 42 | 43 | CControlEventSink::CControlEventSink() : 44 | m_dwEventCookie(0), 45 | m_bSubscribed(false), 46 | m_EventIID(GUID_NULL), 47 | events() 48 | { 49 | } 50 | 51 | CControlEventSink::~CControlEventSink() 52 | { 53 | UnsubscribeFromEvents(); 54 | } 55 | 56 | BOOL 57 | CControlEventSink::GetEventSinkIID(IUnknown *pControl, IID &iid, ITypeInfo **typeInfo) 58 | { 59 | iid = GUID_NULL; 60 | if (!pControl) 61 | { 62 | return E_INVALIDARG; 63 | } 64 | 65 | // IProvideClassInfo2 way is easiest 66 | // CComQIPtr classInfo2 = pControl; 67 | // if (classInfo2) 68 | // { 69 | // classInfo2->GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid); 70 | // if (!::IsEqualIID(iid, GUID_NULL)) 71 | // { 72 | // return TRUE; 73 | // } 74 | // } 75 | 76 | // Yuck, the hard way 77 | CComQIPtr classInfo = pControl; 78 | if (!classInfo) 79 | { 80 | return FALSE; 81 | } 82 | 83 | // Search the class type information for the default source interface 84 | // which is the outgoing event sink. 85 | 86 | CComPtr classTypeInfo; 87 | classInfo->GetClassInfo(&classTypeInfo); 88 | if (!classTypeInfo) 89 | { 90 | return FALSE; 91 | } 92 | TYPEATTR *classAttr = NULL; 93 | if (FAILED(classTypeInfo->GetTypeAttr(&classAttr))) 94 | { 95 | return FALSE; 96 | } 97 | INT implFlags = 0; 98 | for (UINT i = 0; i < classAttr->cImplTypes; i++) 99 | { 100 | // Search for the interface with the [default, source] attr 101 | if (SUCCEEDED(classTypeInfo->GetImplTypeFlags(i, &implFlags)) && 102 | implFlags == (IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE)) 103 | { 104 | CComPtr eventSinkTypeInfo; 105 | HREFTYPE hRefType; 106 | if (SUCCEEDED(classTypeInfo->GetRefTypeOfImplType(i, &hRefType)) && 107 | SUCCEEDED(classTypeInfo->GetRefTypeInfo(hRefType, &eventSinkTypeInfo))) 108 | { 109 | TYPEATTR *eventSinkAttr = NULL; 110 | if (SUCCEEDED(eventSinkTypeInfo->GetTypeAttr(&eventSinkAttr))) 111 | { 112 | iid = eventSinkAttr->guid; 113 | if (typeInfo) 114 | { 115 | *typeInfo = eventSinkTypeInfo.p; 116 | (*typeInfo)->AddRef(); 117 | } 118 | eventSinkTypeInfo->ReleaseTypeAttr(eventSinkAttr); 119 | } 120 | } 121 | break; 122 | } 123 | } 124 | classTypeInfo->ReleaseTypeAttr(classAttr); 125 | 126 | return (!::IsEqualIID(iid, GUID_NULL)); 127 | } 128 | 129 | void CControlEventSink::UnsubscribeFromEvents() 130 | { 131 | if (m_bSubscribed) 132 | { 133 | DWORD tmpCookie = m_dwEventCookie; 134 | m_dwEventCookie = 0; 135 | m_bSubscribed = false; 136 | // Unsubscribe and reset - This seems to complete release and destroy us... 137 | m_spEventCP->Unadvise(tmpCookie); 138 | // Unadvise handles the Release 139 | //m_spEventCP.Release(); 140 | } 141 | } 142 | 143 | HRESULT CControlEventSink::SubscribeToEvents(IUnknown *pControl) 144 | { 145 | if (!pControl) 146 | { 147 | return E_INVALIDARG; 148 | } 149 | 150 | // Throw away any existing connections 151 | UnsubscribeFromEvents(); 152 | 153 | // Grab the outgoing event sink IID which will be used to subscribe 154 | // to events via the connection point container. 155 | 156 | IID iidEventSink; 157 | CComPtr typeInfo; 158 | if (!GetEventSinkIID(pControl, iidEventSink, &typeInfo)) 159 | { 160 | return E_FAIL; 161 | } 162 | 163 | // Get the connection point 164 | CComQIPtr ccp = pControl; 165 | CComPtr cp; 166 | if (!ccp) 167 | { 168 | return E_FAIL; 169 | } 170 | 171 | // Custom IID 172 | m_EventIID = iidEventSink; 173 | DWORD dwCookie = 0; 174 | if (!ccp || 175 | FAILED(ccp->FindConnectionPoint(m_EventIID, &cp)) || 176 | FAILED(cp->Advise(this, &dwCookie))) 177 | { 178 | return E_FAIL; 179 | } 180 | 181 | m_bSubscribed = true; 182 | m_spEventCP = cp; 183 | m_dwEventCookie = dwCookie; 184 | m_spEventSinkTypeInfo = typeInfo; 185 | return S_OK; 186 | } 187 | 188 | HRESULT 189 | CControlEventSink::InternalInvoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 190 | { 191 | USES_CONVERSION; 192 | 193 | if (DISPATCH_METHOD != wFlags) { 194 | // any other reason to call us?! 195 | return S_FALSE; 196 | } 197 | 198 | EventMap::iterator cur = events.find(dispIdMember); 199 | 200 | if (events.end() != cur) { 201 | // invoke this event handler 202 | NPVariant result; 203 | NPVariant *args = NULL; 204 | 205 | if (pDispParams->cArgs > 0) { 206 | 207 | args = (NPVariant *)calloc(pDispParams->cArgs, sizeof(NPVariant)); 208 | if (!args) { 209 | 210 | return S_FALSE; 211 | } 212 | 213 | for (unsigned int i = 0; i < pDispParams->cArgs; ++i) { 214 | // convert the arguments in reverse order 215 | Variant2NPVar(&pDispParams->rgvarg[i], &args[pDispParams->cArgs - i - 1], instance); 216 | } 217 | } 218 | 219 | NPObject *globalObj = NULL; 220 | NPNFuncs.getvalue(instance, NPNVWindowNPObject, &globalObj); 221 | 222 | NPIdentifier handler = NPNFuncs.getstringidentifier(W2A((*cur).second)); 223 | 224 | bool success = NPNFuncs.invoke(instance, globalObj, handler, args, pDispParams->cArgs, &result); 225 | NPNFuncs.releaseobject(globalObj); 226 | 227 | for (unsigned int i = 0; i < pDispParams->cArgs; ++i) { 228 | // convert the arguments 229 | if (args[i].type == NPVariantType_String) { 230 | // was allocated earlier by Variant2NPVar 231 | NPNFuncs.memfree((void *)args[i].value.stringValue.UTF8Characters); 232 | } 233 | } 234 | 235 | if (!success) { 236 | 237 | return S_FALSE; 238 | } 239 | 240 | if (pVarResult) { 241 | // set the result 242 | NPVar2Variant(&result, pVarResult, instance); 243 | } 244 | 245 | NPNFuncs.releasevariantvalue(&result); 246 | } 247 | 248 | return S_OK; 249 | } 250 | 251 | /////////////////////////////////////////////////////////////////////////////// 252 | // IDispatch implementation 253 | 254 | 255 | HRESULT STDMETHODCALLTYPE CControlEventSink::GetTypeInfoCount(/* [out] */ UINT __RPC_FAR *pctinfo) 256 | { 257 | return E_NOTIMPL; 258 | } 259 | 260 | 261 | HRESULT STDMETHODCALLTYPE CControlEventSink::GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) 262 | { 263 | return E_NOTIMPL; 264 | } 265 | 266 | 267 | HRESULT STDMETHODCALLTYPE CControlEventSink::GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID __RPC_FAR *rgDispId) 268 | { 269 | return E_NOTIMPL; 270 | } 271 | 272 | 273 | HRESULT STDMETHODCALLTYPE CControlEventSink::Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, /* [out] */ VARIANT __RPC_FAR *pVarResult, /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, /* [out] */ UINT __RPC_FAR *puArgErr) 274 | { 275 | return InternalInvoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 276 | } 277 | 278 | 279 | -------------------------------------------------------------------------------- /ffactivex/common/ControlEventSink.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | #ifndef CONTROLEVENTSINK_H 40 | #define CONTROLEVENTSINK_H 41 | 42 | #include 43 | 44 | // This class listens for events from the specified control 45 | 46 | class CControlEventSink : 47 | public CComObjectRootEx, 48 | public IDispatch 49 | { 50 | public: 51 | CControlEventSink(); 52 | 53 | // Current event connection point 54 | CComPtr m_spEventCP; 55 | CComPtr m_spEventSinkTypeInfo; 56 | DWORD m_dwEventCookie; 57 | IID m_EventIID; 58 | 59 | typedef std::map EventMap; 60 | EventMap events; 61 | NPP instance; 62 | 63 | protected: 64 | virtual ~CControlEventSink(); 65 | 66 | bool m_bSubscribed; 67 | 68 | static HRESULT WINAPI SinkQI(void* pv, REFIID riid, LPVOID* ppv, DWORD dw) 69 | { 70 | CControlEventSink *pThis = (CControlEventSink *) pv; 71 | if (!IsEqualIID(pThis->m_EventIID, GUID_NULL) && 72 | IsEqualIID(pThis->m_EventIID, riid)) 73 | { 74 | return pThis->QueryInterface(__uuidof(IDispatch), ppv); 75 | } 76 | return E_NOINTERFACE; 77 | } 78 | 79 | public: 80 | 81 | BEGIN_COM_MAP(CControlEventSink) 82 | COM_INTERFACE_ENTRY(IDispatch) 83 | COM_INTERFACE_ENTRY_FUNC_BLIND(0, SinkQI) 84 | END_COM_MAP() 85 | 86 | virtual HRESULT SubscribeToEvents(IUnknown *pControl); 87 | virtual void UnsubscribeFromEvents(); 88 | virtual BOOL GetEventSinkIID(IUnknown *pControl, IID &iid, ITypeInfo **typeInfo); 89 | virtual HRESULT InternalInvoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); 90 | 91 | // IDispatch 92 | virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(/* [out] */ UINT __RPC_FAR *pctinfo); 93 | virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo); 94 | virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID __RPC_FAR *rgDispId); 95 | virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(/* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, /* [out] */ VARIANT __RPC_FAR *pVarResult, /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, /* [out] */ UINT __RPC_FAR *puArgErr); 96 | }; 97 | 98 | typedef CComObject CControlEventSinkInstance; 99 | 100 | #endif -------------------------------------------------------------------------------- /ffactivex/common/ControlSiteIPFrame.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | #include "stdafx.h" 39 | 40 | #include "ControlSiteIPFrame.h" 41 | 42 | CControlSiteIPFrame::CControlSiteIPFrame() 43 | { 44 | m_hwndFrame = NULL; 45 | } 46 | 47 | 48 | CControlSiteIPFrame::~CControlSiteIPFrame() 49 | { 50 | } 51 | 52 | /////////////////////////////////////////////////////////////////////////////// 53 | // IOleWindow implementation 54 | 55 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::GetWindow(/* [out] */ HWND __RPC_FAR *phwnd) 56 | { 57 | if (phwnd == NULL) 58 | { 59 | return E_INVALIDARG; 60 | } 61 | *phwnd = m_hwndFrame; 62 | 63 | return S_OK; 64 | } 65 | 66 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::ContextSensitiveHelp(/* [in] */ BOOL fEnterMode) 67 | { 68 | return S_OK; 69 | } 70 | 71 | 72 | /////////////////////////////////////////////////////////////////////////////// 73 | // IOleInPlaceUIWindow implementation 74 | 75 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::GetBorder(/* [out] */ LPRECT lprectBorder) 76 | { 77 | return INPLACE_E_NOTOOLSPACE; 78 | } 79 | 80 | 81 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::RequestBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths) 82 | { 83 | return INPLACE_E_NOTOOLSPACE; 84 | } 85 | 86 | 87 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths) 88 | { 89 | return S_OK; 90 | } 91 | 92 | 93 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetActiveObject(/* [unique][in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [unique][string][in] */ LPCOLESTR pszObjName) 94 | { 95 | return S_OK; 96 | } 97 | 98 | 99 | /////////////////////////////////////////////////////////////////////////////// 100 | // IOleInPlaceFrame implementation 101 | 102 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::InsertMenus(/* [in] */ HMENU hmenuShared, /* [out][in] */ LPOLEMENUGROUPWIDTHS lpMenuWidths) 103 | { 104 | return S_OK; 105 | } 106 | 107 | 108 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetMenu(/* [in] */ HMENU hmenuShared, /* [in] */ HOLEMENU holemenu, /* [in] */ HWND hwndActiveObject) 109 | { 110 | return S_OK; 111 | } 112 | 113 | 114 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::RemoveMenus(/* [in] */ HMENU hmenuShared) 115 | { 116 | return S_OK; 117 | } 118 | 119 | 120 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::SetStatusText(/* [in] */ LPCOLESTR pszStatusText) 121 | { 122 | return S_OK; 123 | } 124 | 125 | 126 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::EnableModeless(/* [in] */ BOOL fEnable) 127 | { 128 | return S_OK; 129 | } 130 | 131 | 132 | HRESULT STDMETHODCALLTYPE CControlSiteIPFrame::TranslateAccelerator(/* [in] */ LPMSG lpmsg, /* [in] */ WORD wID) 133 | { 134 | return E_NOTIMPL; 135 | } 136 | 137 | -------------------------------------------------------------------------------- /ffactivex/common/ControlSiteIPFrame.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | #ifndef CONTROLSITEIPFRAME_H 39 | #define CONTROLSITEIPFRAME_H 40 | 41 | class CControlSiteIPFrame : public CComObjectRootEx, 42 | public IOleInPlaceFrame 43 | { 44 | public: 45 | CControlSiteIPFrame(); 46 | virtual ~CControlSiteIPFrame(); 47 | 48 | HWND m_hwndFrame; 49 | 50 | BEGIN_COM_MAP(CControlSiteIPFrame) 51 | COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleInPlaceFrame) 52 | COM_INTERFACE_ENTRY_IID(IID_IOleInPlaceUIWindow, IOleInPlaceFrame) 53 | COM_INTERFACE_ENTRY(IOleInPlaceFrame) 54 | END_COM_MAP() 55 | 56 | // IOleWindow 57 | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(/* [out] */ HWND __RPC_FAR *phwnd); 58 | virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(/* [in] */ BOOL fEnterMode); 59 | 60 | // IOleInPlaceUIWindow implementation 61 | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetBorder(/* [out] */ LPRECT lprectBorder); 62 | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE RequestBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths); 63 | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetBorderSpace(/* [unique][in] */ LPCBORDERWIDTHS pborderwidths); 64 | virtual HRESULT STDMETHODCALLTYPE SetActiveObject(/* [unique][in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [unique][string][in] */ LPCOLESTR pszObjName); 65 | 66 | // IOleInPlaceFrame implementation 67 | virtual HRESULT STDMETHODCALLTYPE InsertMenus(/* [in] */ HMENU hmenuShared, /* [out][in] */ LPOLEMENUGROUPWIDTHS lpMenuWidths); 68 | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetMenu(/* [in] */ HMENU hmenuShared, /* [in] */ HOLEMENU holemenu, /* [in] */ HWND hwndActiveObject); 69 | virtual HRESULT STDMETHODCALLTYPE RemoveMenus(/* [in] */ HMENU hmenuShared); 70 | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetStatusText(/* [in] */ LPCOLESTR pszStatusText); 71 | virtual HRESULT STDMETHODCALLTYPE EnableModeless(/* [in] */ BOOL fEnable); 72 | virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(/* [in] */ LPMSG lpmsg, /* [in] */ WORD wID); 73 | }; 74 | 75 | typedef CComObject CControlSiteIPFrameInstance; 76 | 77 | #endif -------------------------------------------------------------------------------- /ffactivex/common/IOleCommandTargetImpl.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | #ifndef IOLECOMMANDIMPL_H 39 | #define IOLECOMMANDIMPL_H 40 | 41 | // Implementation of the IOleCommandTarget interface. The template is 42 | // reasonably generic and reusable which is a good thing given how needlessly 43 | // complicated this interface is. Blame Microsoft for that and not me. 44 | // 45 | // To use this class, derive your class from it like this: 46 | // 47 | // class CComMyClass : public IOleCommandTargetImpl 48 | // { 49 | // ... Ensure IOleCommandTarget is listed in the interface map ... 50 | // BEGIN_COM_MAP(CComMyClass) 51 | // COM_INTERFACE_ENTRY(IOleCommandTarget) 52 | // // etc. 53 | // END_COM_MAP() 54 | // ... And then later on define the command target table ... 55 | // BEGIN_OLECOMMAND_TABLE() 56 | // OLECOMMAND_MESSAGE(OLECMDID_PRINT, NULL, ID_PRINT, L"Print", L"Print the page") 57 | // OLECOMMAND_MESSAGE(OLECMDID_SAVEAS, NULL, 0, L"SaveAs", L"Save the page") 58 | // OLECOMMAND_HANDLER(IDM_EDITMODE, &CGID_MSHTML, EditModeHandler, L"EditMode", L"Switch to edit mode") 59 | // END_OLECOMMAND_TABLE() 60 | // ... Now the window that OLECOMMAND_MESSAGE sends WM_COMMANDs to ... 61 | // HWND GetCommandTargetWindow() const 62 | // { 63 | // return m_hWnd; 64 | // } 65 | // ... Now procedures that OLECOMMAND_HANDLER calls ... 66 | // static HRESULT _stdcall EditModeHandler(CMozillaBrowser *pThis, const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); 67 | // } 68 | // 69 | // The command table defines which commands the object supports. Commands are 70 | // defined by a command id and a command group plus a WM_COMMAND id or procedure, 71 | // and a verb and short description. 72 | // 73 | // Notice that there are two macros for handling Ole Commands. The first, 74 | // OLECOMMAND_MESSAGE sends a WM_COMMAND message to the window returned from 75 | // GetCommandTargetWindow() (that the derived class must implement if it uses 76 | // this macro). 77 | // 78 | // The second, OLECOMMAND_HANDLER calls a static handler procedure that 79 | // conforms to the OleCommandProc typedef. The first parameter, pThis means 80 | // the static handler has access to the methods and variables in the class 81 | // instance. 82 | // 83 | // The OLECOMMAND_HANDLER macro is generally more useful when a command 84 | // takes parameters or needs to return a result to the caller. 85 | // 86 | template< class T > 87 | class IOleCommandTargetImpl : public IOleCommandTarget 88 | { 89 | struct OleExecData 90 | { 91 | const GUID *pguidCmdGroup; 92 | DWORD nCmdID; 93 | DWORD nCmdexecopt; 94 | VARIANT *pvaIn; 95 | VARIANT *pvaOut; 96 | }; 97 | 98 | public: 99 | typedef HRESULT (_stdcall *OleCommandProc)(T *pT, const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); 100 | 101 | struct OleCommandInfo 102 | { 103 | ULONG nCmdID; 104 | const GUID *pCmdGUID; 105 | ULONG nWindowsCmdID; 106 | OleCommandProc pfnCommandProc; 107 | wchar_t *szVerbText; 108 | wchar_t *szStatusText; 109 | }; 110 | 111 | // Query the status of the specified commands (test if is it supported etc.) 112 | virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID __RPC_FAR *pguidCmdGroup, ULONG cCmds, OLECMD __RPC_FAR prgCmds[], OLECMDTEXT __RPC_FAR *pCmdText) 113 | { 114 | T* pT = static_cast(this); 115 | 116 | if (prgCmds == NULL) 117 | { 118 | return E_INVALIDARG; 119 | } 120 | 121 | OleCommandInfo *pCommands = pT->GetCommandTable(); 122 | ATLASSERT(pCommands); 123 | 124 | BOOL bCmdGroupFound = FALSE; 125 | BOOL bTextSet = FALSE; 126 | 127 | // Iterate through list of commands and flag them as supported/unsupported 128 | for (ULONG nCmd = 0; nCmd < cCmds; nCmd++) 129 | { 130 | // Unsupported by default 131 | prgCmds[nCmd].cmdf = 0; 132 | 133 | // Search the support command list 134 | for (int nSupported = 0; pCommands[nSupported].pCmdGUID != &GUID_NULL; nSupported++) 135 | { 136 | OleCommandInfo *pCI = &pCommands[nSupported]; 137 | 138 | if (pguidCmdGroup && pCI->pCmdGUID && memcmp(pguidCmdGroup, pCI->pCmdGUID, sizeof(GUID)) == 0) 139 | { 140 | continue; 141 | } 142 | bCmdGroupFound = TRUE; 143 | 144 | if (pCI->nCmdID != prgCmds[nCmd].cmdID) 145 | { 146 | continue; 147 | } 148 | 149 | // Command is supported so flag it and possibly enable it 150 | prgCmds[nCmd].cmdf = OLECMDF_SUPPORTED; 151 | if (pCI->nWindowsCmdID != 0) 152 | { 153 | prgCmds[nCmd].cmdf |= OLECMDF_ENABLED; 154 | } 155 | 156 | // Copy the status/verb text for the first supported command only 157 | if (!bTextSet && pCmdText) 158 | { 159 | // See what text the caller wants 160 | wchar_t *pszTextToCopy = NULL; 161 | if (pCmdText->cmdtextf & OLECMDTEXTF_NAME) 162 | { 163 | pszTextToCopy = pCI->szVerbText; 164 | } 165 | else if (pCmdText->cmdtextf & OLECMDTEXTF_STATUS) 166 | { 167 | pszTextToCopy = pCI->szStatusText; 168 | } 169 | 170 | // Copy the text 171 | pCmdText->cwActual = 0; 172 | memset(pCmdText->rgwz, 0, pCmdText->cwBuf * sizeof(wchar_t)); 173 | if (pszTextToCopy) 174 | { 175 | // Don't exceed the provided buffer size 176 | size_t nTextLen = wcslen(pszTextToCopy); 177 | if (nTextLen > pCmdText->cwBuf) 178 | { 179 | nTextLen = pCmdText->cwBuf; 180 | } 181 | 182 | wcsncpy(pCmdText->rgwz, pszTextToCopy, nTextLen); 183 | pCmdText->cwActual = nTextLen; 184 | } 185 | 186 | bTextSet = TRUE; 187 | } 188 | break; 189 | } 190 | } 191 | 192 | // Was the command group found? 193 | if (!bCmdGroupFound) 194 | { 195 | OLECMDERR_E_UNKNOWNGROUP; 196 | } 197 | 198 | return S_OK; 199 | } 200 | 201 | 202 | // Execute the specified command 203 | virtual HRESULT STDMETHODCALLTYPE Exec(const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT __RPC_FAR *pvaIn, VARIANT __RPC_FAR *pvaOut) 204 | { 205 | T* pT = static_cast(this); 206 | BOOL bCmdGroupFound = FALSE; 207 | 208 | OleCommandInfo *pCommands = pT->GetCommandTable(); 209 | ATLASSERT(pCommands); 210 | 211 | // Search the support command list 212 | for (int nSupported = 0; pCommands[nSupported].pCmdGUID != &GUID_NULL; nSupported++) 213 | { 214 | OleCommandInfo *pCI = &pCommands[nSupported]; 215 | 216 | if (pguidCmdGroup && pCI->pCmdGUID && memcmp(pguidCmdGroup, pCI->pCmdGUID, sizeof(GUID)) == 0) 217 | { 218 | continue; 219 | } 220 | bCmdGroupFound = TRUE; 221 | 222 | if (pCI->nCmdID != nCmdID) 223 | { 224 | continue; 225 | } 226 | 227 | // Send ourselves a WM_COMMAND windows message with the associated 228 | // identifier and exec data 229 | OleExecData cData; 230 | cData.pguidCmdGroup = pguidCmdGroup; 231 | cData.nCmdID = nCmdID; 232 | cData.nCmdexecopt = nCmdexecopt; 233 | cData.pvaIn = pvaIn; 234 | cData.pvaOut = pvaOut; 235 | 236 | if (pCI->pfnCommandProc) 237 | { 238 | pCI->pfnCommandProc(pT, pCI->pCmdGUID, pCI->nCmdID, nCmdexecopt, pvaIn, pvaOut); 239 | } 240 | else if (pCI->nWindowsCmdID != 0 && nCmdexecopt != OLECMDEXECOPT_SHOWHELP) 241 | { 242 | HWND hwndTarget = pT->GetCommandTargetWindow(); 243 | if (hwndTarget) 244 | { 245 | ::SendMessage(hwndTarget, WM_COMMAND, LOWORD(pCI->nWindowsCmdID), (LPARAM) &cData); 246 | } 247 | } 248 | else 249 | { 250 | // Command supported but not implemented 251 | continue; 252 | } 253 | 254 | return S_OK; 255 | } 256 | 257 | // Was the command group found? 258 | if (!bCmdGroupFound) 259 | { 260 | OLECMDERR_E_UNKNOWNGROUP; 261 | } 262 | 263 | return OLECMDERR_E_NOTSUPPORTED; 264 | } 265 | }; 266 | 267 | // Macros to be placed in any class derived from the IOleCommandTargetImpl 268 | // class. These define what commands are exposed from the object. 269 | 270 | #define BEGIN_OLECOMMAND_TABLE() \ 271 | OleCommandInfo *GetCommandTable() \ 272 | { \ 273 | static OleCommandInfo s_aSupportedCommands[] = \ 274 | { 275 | 276 | #define OLECOMMAND_MESSAGE(id, group, cmd, verb, desc) \ 277 | { id, group, cmd, NULL, verb, desc }, 278 | 279 | #define OLECOMMAND_HANDLER(id, group, handler, verb, desc) \ 280 | { id, group, 0, handler, verb, desc }, 281 | 282 | #define END_OLECOMMAND_TABLE() \ 283 | { 0, &GUID_NULL, 0, NULL, NULL, NULL } \ 284 | }; \ 285 | return s_aSupportedCommands; \ 286 | }; 287 | 288 | #endif -------------------------------------------------------------------------------- /ffactivex/common/ItemContainer.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | #include "StdAfx.h" 40 | 41 | #include "ItemContainer.h" 42 | 43 | CItemContainer::CItemContainer() 44 | { 45 | } 46 | 47 | CItemContainer::~CItemContainer() 48 | { 49 | } 50 | 51 | /////////////////////////////////////////////////////////////////////////////// 52 | // IParseDisplayName implementation 53 | 54 | 55 | HRESULT STDMETHODCALLTYPE CItemContainer::ParseDisplayName(/* [unique][in] */ IBindCtx __RPC_FAR *pbc, /* [in] */ LPOLESTR pszDisplayName, /* [out] */ ULONG __RPC_FAR *pchEaten, /* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkOut) 56 | { 57 | // TODO 58 | return E_NOTIMPL; 59 | } 60 | 61 | 62 | /////////////////////////////////////////////////////////////////////////////// 63 | // IOleContainer implementation 64 | 65 | 66 | HRESULT STDMETHODCALLTYPE CItemContainer::EnumObjects(/* [in] */ DWORD grfFlags, /* [out] */ IEnumUnknown __RPC_FAR *__RPC_FAR *ppenum) 67 | { 68 | HRESULT hr = E_NOTIMPL; 69 | /* 70 | if (ppenum == NULL) 71 | { 72 | return E_POINTER; 73 | } 74 | 75 | *ppenum = NULL; 76 | typedef CComObject, CNamedObjectList > > enumunk; 77 | enumunk* p = NULL; 78 | p = new enumunk; 79 | if(p == NULL) 80 | { 81 | return E_OUTOFMEMORY; 82 | } 83 | 84 | hr = p->Init(); 85 | if (SUCCEEDED(hr)) 86 | { 87 | hr = p->QueryInterface(IID_IEnumUnknown, (void**) ppenum); 88 | } 89 | if (FAILED(hRes)) 90 | { 91 | delete p; 92 | } 93 | */ 94 | return hr; 95 | } 96 | 97 | 98 | HRESULT STDMETHODCALLTYPE CItemContainer::LockContainer(/* [in] */ BOOL fLock) 99 | { 100 | // TODO 101 | return S_OK; 102 | } 103 | 104 | 105 | /////////////////////////////////////////////////////////////////////////////// 106 | // IOleItemContainer implementation 107 | 108 | 109 | HRESULT STDMETHODCALLTYPE CItemContainer::GetObject(/* [in] */ LPOLESTR pszItem, /* [in] */ DWORD dwSpeedNeeded, /* [unique][in] */ IBindCtx __RPC_FAR *pbc, /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) 110 | { 111 | if (pszItem == NULL) 112 | { 113 | return E_INVALIDARG; 114 | } 115 | if (ppvObject == NULL) 116 | { 117 | return E_INVALIDARG; 118 | } 119 | 120 | *ppvObject = NULL; 121 | 122 | return MK_E_NOOBJECT; 123 | } 124 | 125 | 126 | HRESULT STDMETHODCALLTYPE CItemContainer::GetObjectStorage(/* [in] */ LPOLESTR pszItem, /* [unique][in] */ IBindCtx __RPC_FAR *pbc, /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvStorage) 127 | { 128 | // TODO 129 | return MK_E_NOOBJECT; 130 | } 131 | 132 | 133 | HRESULT STDMETHODCALLTYPE CItemContainer::IsRunning(/* [in] */ LPOLESTR pszItem) 134 | { 135 | // TODO 136 | return MK_E_NOOBJECT; 137 | } 138 | -------------------------------------------------------------------------------- /ffactivex/common/ItemContainer.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | #ifndef ITEMCONTAINER_H 40 | #define ITEMCONTAINER_H 41 | 42 | // typedef std::map CNamedObjectList; 43 | 44 | // Class for managing a list of named objects. 45 | 46 | class CItemContainer : public CComObjectRootEx, 47 | public IOleItemContainer 48 | { 49 | // CNamedObjectList m_cNamedObjectList; 50 | public: 51 | 52 | CItemContainer(); 53 | virtual ~CItemContainer(); 54 | 55 | BEGIN_COM_MAP(CItemContainer) 56 | COM_INTERFACE_ENTRY_IID(IID_IParseDisplayName, IOleItemContainer) 57 | COM_INTERFACE_ENTRY_IID(IID_IOleContainer, IOleItemContainer) 58 | COM_INTERFACE_ENTRY_IID(IID_IOleItemContainer, IOleItemContainer) 59 | END_COM_MAP() 60 | 61 | // IParseDisplayName implementation 62 | virtual HRESULT STDMETHODCALLTYPE ParseDisplayName(/* [unique][in] */ IBindCtx __RPC_FAR *pbc, /* [in] */ LPOLESTR pszDisplayName, /* [out] */ ULONG __RPC_FAR *pchEaten, /* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmkOut); 63 | 64 | // IOleContainer implementation 65 | virtual HRESULT STDMETHODCALLTYPE EnumObjects(/* [in] */ DWORD grfFlags, /* [out] */ IEnumUnknown __RPC_FAR *__RPC_FAR *ppenum); 66 | virtual HRESULT STDMETHODCALLTYPE LockContainer(/* [in] */ BOOL fLock); 67 | 68 | // IOleItemContainer implementation 69 | virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetObject(/* [in] */ LPOLESTR pszItem, /* [in] */ DWORD dwSpeedNeeded, /* [unique][in] */ IBindCtx __RPC_FAR *pbc, /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); 70 | virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetObjectStorage(/* [in] */ LPOLESTR pszItem, /* [unique][in] */ IBindCtx __RPC_FAR *pbc, /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvStorage); 71 | virtual HRESULT STDMETHODCALLTYPE IsRunning(/* [in] */ LPOLESTR pszItem); 72 | }; 73 | 74 | typedef CComObject CItemContainerInstance; 75 | 76 | 77 | #endif -------------------------------------------------------------------------------- /ffactivex/common/PropertyBag.cpp: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * either the GNU General Public License Version 2 or later (the "GPL"), or 26 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 27 | * in which case the provisions of the GPL or the LGPL are applicable instead 28 | * of those above. If you wish to allow use of your version of this file only 29 | * under the terms of either the GPL or the LGPL, and not to allow others to 30 | * use your version of this file under the terms of the MPL, indicate your 31 | * decision by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL or the LGPL. If you do not delete 33 | * the provisions above, a recipient may use your version of this file under 34 | * the terms of any one of the MPL, the GPL or the LGPL. 35 | * 36 | * ***** END LICENSE BLOCK ***** */ 37 | 38 | #include "StdAfx.h" 39 | 40 | #include "PropertyBag.h" 41 | 42 | 43 | CPropertyBag::CPropertyBag() 44 | { 45 | } 46 | 47 | 48 | CPropertyBag::~CPropertyBag() 49 | { 50 | } 51 | 52 | 53 | /////////////////////////////////////////////////////////////////////////////// 54 | // IPropertyBag implementation 55 | 56 | HRESULT STDMETHODCALLTYPE CPropertyBag::Read(/* [in] */ LPCOLESTR pszPropName, /* [out][in] */ VARIANT __RPC_FAR *pVar, /* [in] */ IErrorLog __RPC_FAR *pErrorLog) 57 | { 58 | if (pszPropName == NULL) 59 | { 60 | return E_INVALIDARG; 61 | } 62 | if (pVar == NULL) 63 | { 64 | return E_INVALIDARG; 65 | } 66 | 67 | VARTYPE vt = pVar->vt; 68 | VariantInit(pVar); 69 | 70 | for (unsigned long i = 0; i < m_PropertyList.GetSize(); i++) 71 | { 72 | if (wcsicmp(m_PropertyList.GetNameOf(i), pszPropName) == 0) 73 | { 74 | const VARIANT *pvSrc = m_PropertyList.GetValueOf(i); 75 | if (!pvSrc) 76 | { 77 | return E_FAIL; 78 | } 79 | CComVariant vNew; 80 | HRESULT hr = (vt == VT_EMPTY) ? 81 | vNew.Copy(pvSrc) : vNew.ChangeType(vt, pvSrc); 82 | if (FAILED(hr)) 83 | { 84 | return E_FAIL; 85 | } 86 | // Copy the new value 87 | vNew.Detach(pVar); 88 | return S_OK; 89 | } 90 | } 91 | 92 | // Property does not exist in the bag 93 | return E_FAIL; 94 | } 95 | 96 | 97 | HRESULT STDMETHODCALLTYPE CPropertyBag::Write(/* [in] */ LPCOLESTR pszPropName, /* [in] */ VARIANT __RPC_FAR *pVar) 98 | { 99 | if (pszPropName == NULL) 100 | { 101 | return E_INVALIDARG; 102 | } 103 | if (pVar == NULL) 104 | { 105 | return E_INVALIDARG; 106 | } 107 | 108 | CComBSTR bstrName(pszPropName); 109 | m_PropertyList.AddOrReplaceNamedProperty(bstrName, *pVar); 110 | 111 | return S_OK; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /ffactivex/common/PropertyBag.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | #ifndef PROPERTYBAG_H 39 | #define PROPERTYBAG_H 40 | 41 | #include "PropertyList.h" 42 | 43 | // Object wrapper for property list. This class can be set up with a 44 | // list of properties and used to initialise a control with them 45 | 46 | class CPropertyBag : public CComObjectRootEx, 47 | public IPropertyBag 48 | { 49 | // List of properties in the bag 50 | PropertyList m_PropertyList; 51 | 52 | public: 53 | // Constructor 54 | CPropertyBag(); 55 | // Destructor 56 | virtual ~CPropertyBag(); 57 | 58 | BEGIN_COM_MAP(CPropertyBag) 59 | COM_INTERFACE_ENTRY(IPropertyBag) 60 | END_COM_MAP() 61 | 62 | // IPropertyBag methods 63 | virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read(/* [in] */ LPCOLESTR pszPropName, /* [out][in] */ VARIANT __RPC_FAR *pVar, /* [in] */ IErrorLog __RPC_FAR *pErrorLog); 64 | virtual HRESULT STDMETHODCALLTYPE Write(/* [in] */ LPCOLESTR pszPropName, /* [in] */ VARIANT __RPC_FAR *pVar); 65 | }; 66 | 67 | typedef CComObject CPropertyBagInstance; 68 | 69 | #endif -------------------------------------------------------------------------------- /ffactivex/common/PropertyList.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | #ifndef PROPERTYLIST_H 39 | #define PROPERTYLIST_H 40 | 41 | // A simple array class for managing name/value pairs typically fed to controls 42 | // during initialization by IPersistPropertyBag 43 | 44 | class PropertyList 45 | { 46 | struct Property { 47 | BSTR bstrName; 48 | VARIANT vValue; 49 | } *mProperties; 50 | unsigned long mListSize; 51 | unsigned long mMaxListSize; 52 | 53 | bool EnsureMoreSpace() 54 | { 55 | // Ensure enough space exists to accomodate a new item 56 | const unsigned long kGrowBy = 10; 57 | if (!mProperties) 58 | { 59 | mProperties = (Property *) malloc(sizeof(Property) * kGrowBy); 60 | if (!mProperties) 61 | return false; 62 | mMaxListSize = kGrowBy; 63 | } 64 | else if (mListSize == mMaxListSize) 65 | { 66 | Property *pNewProperties; 67 | pNewProperties = (Property *) realloc(mProperties, sizeof(Property) * (mMaxListSize + kGrowBy)); 68 | if (!pNewProperties) 69 | return false; 70 | mProperties = pNewProperties; 71 | mMaxListSize += kGrowBy; 72 | } 73 | return true; 74 | } 75 | 76 | public: 77 | PropertyList() : 78 | mProperties(NULL), 79 | mListSize(0), 80 | mMaxListSize(0) 81 | { 82 | } 83 | ~PropertyList() 84 | { 85 | } 86 | void Clear() 87 | { 88 | if (mProperties) 89 | { 90 | for (unsigned long i = 0; i < mListSize; i++) 91 | { 92 | SysFreeString(mProperties[i].bstrName); // Safe even if NULL 93 | VariantClear(&mProperties[i].vValue); 94 | } 95 | free(mProperties); 96 | mProperties = NULL; 97 | } 98 | mListSize = 0; 99 | mMaxListSize = 0; 100 | } 101 | unsigned long GetSize() const 102 | { 103 | return mListSize; 104 | } 105 | const BSTR GetNameOf(unsigned long nIndex) const 106 | { 107 | if (nIndex > mListSize) 108 | { 109 | return NULL; 110 | } 111 | return mProperties[nIndex].bstrName; 112 | } 113 | const VARIANT *GetValueOf(unsigned long nIndex) const 114 | { 115 | if (nIndex > mListSize) 116 | { 117 | return NULL; 118 | } 119 | return &mProperties[nIndex].vValue; 120 | } 121 | bool AddOrReplaceNamedProperty(const BSTR bstrName, const VARIANT &vValue) 122 | { 123 | if (!bstrName) 124 | return false; 125 | for (unsigned long i = 0; i < GetSize(); i++) 126 | { 127 | // Case insensitive 128 | if (wcsicmp(mProperties[i].bstrName, bstrName) == 0) 129 | { 130 | return SUCCEEDED( 131 | VariantCopy(&mProperties[i].vValue, const_cast(&vValue))); 132 | } 133 | } 134 | return AddNamedProperty(bstrName, vValue); 135 | } 136 | bool AddNamedProperty(const BSTR bstrName, const VARIANT &vValue) 137 | { 138 | if (!bstrName || !EnsureMoreSpace()) 139 | return false; 140 | Property *pProp = &mProperties[mListSize]; 141 | pProp->bstrName = ::SysAllocString(bstrName); 142 | if (!pProp->bstrName) 143 | { 144 | return false; 145 | } 146 | VariantInit(&pProp->vValue); 147 | if (FAILED(VariantCopy(&pProp->vValue, const_cast(&vValue)))) 148 | { 149 | SysFreeString(pProp->bstrName); 150 | return false; 151 | } 152 | mListSize++; 153 | return true; 154 | } 155 | }; 156 | 157 | #endif -------------------------------------------------------------------------------- /ffactivex/common/StdAfx.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Adam Lock 24 | * Ruediger Jungbeck 25 | * 26 | * Alternatively, the contents of this file may be used under the terms of 27 | * either the GNU General Public License Version 2 or later (the "GPL"), or 28 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 29 | * in which case the provisions of the GPL or the LGPL are applicable instead 30 | * of those above. If you wish to allow use of your version of this file only 31 | * under the terms of either the GPL or the LGPL, and not to allow others to 32 | * use your version of this file under the terms of the MPL, indicate your 33 | * decision by deleting the provisions above and replace them with the notice 34 | * and other provisions required by the GPL or the LGPL. If you do not delete 35 | * the provisions above, a recipient may use your version of this file under 36 | * the terms of any one of the MPL, the GPL or the LGPL. 37 | * 38 | * ***** END LICENSE BLOCK ***** */ 39 | 40 | // stdafx.h : include file for standard system include files, 41 | // or project specific include files that are used frequently, 42 | // but are changed infrequently 43 | 44 | #if !defined(AFX_STDAFX_H__1339B542_3453_11D2_93B9_000000000000__INCLUDED_) 45 | #define AFX_STDAFX_H__1339B542_3453_11D2_93B9_000000000000__INCLUDED_ 46 | 47 | #if _MSC_VER >= 1000 48 | #pragma once 49 | #endif // _MSC_VER >= 1000 50 | 51 | // under MSVC shut off copious warnings about debug symbol too long 52 | #ifdef _MSC_VER 53 | #pragma warning( disable: 4786 ) 54 | #endif 55 | 56 | //#include "jstypes.h" 57 | //#include "prtypes.h" 58 | 59 | // Mozilla headers 60 | 61 | //#include "jscompat.h" 62 | 63 | //#include "prthread.h" 64 | //#include "prprf.h" 65 | //#include "nsID.h" 66 | //#include "nsIComponentManager.h" 67 | //#include "nsIServiceManager.h" 68 | //#include "nsStringAPI.h" 69 | //#include "nsCOMPtr.h" 70 | //#include "nsComponentManagerUtils.h" 71 | //#include "nsServiceManagerUtils.h" 72 | 73 | //#include "nsIDocument.h" 74 | //#include "nsIDocumentObserver.h" 75 | //#include "nsVoidArray.h" 76 | 77 | //#include "nsIDOMNode.h" 78 | //#include "nsIDOMNodeList.h" 79 | //#include "nsIDOMDocument.h" 80 | //#include "nsIDOMDocumentType.h" 81 | //#include "nsIDOMElement.h" 82 | 83 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 84 | // Windows Header Files: 85 | #include 86 | 87 | #define _ATL_APARTMENT_THREADED 88 | //#define _ATL_STATIC_REGISTRY 89 | // #define _ATL_DEBUG_INTERFACES 90 | 91 | // ATL headers 92 | // The ATL headers that come with the platform SDK have bad for scoping 93 | #if _MSC_VER >= 1400 94 | #pragma conform(forScope, push, atlhack, off) 95 | #endif 96 | 97 | #include 98 | 99 | //You may derive a class from CComModule and use it if you want to override 100 | //something, but do not change the name of _Module 101 | extern CComModule _Module; 102 | #include 103 | #include 104 | 105 | #if _MSC_VER >= 1400 106 | #pragma conform(forScope, pop, atlhack) 107 | #endif 108 | 109 | #include 110 | #include 111 | #include 112 | //#include 113 | #include 114 | 115 | #include 116 | #include 117 | #include 118 | 119 | // New winsock2.h doesn't define this anymore 120 | typedef long int32; 121 | 122 | #define NS_SCRIPTABLE 123 | 124 | #include "nscore.h" 125 | #include "npapi.h" 126 | //#include "npupp.h" 127 | #include "npfunctions.h" 128 | 129 | #include "nsID.h" 130 | #include 131 | 132 | #include "../variants.h" 133 | 134 | #include "PropertyList.h" 135 | #include "PropertyBag.h" 136 | #include "ItemContainer.h" 137 | #include "ControlSite.h" 138 | #include "ControlSiteIPFrame.h" 139 | #include "ControlEventSink.h" 140 | 141 | extern NPNetscapeFuncs NPNFuncs; 142 | 143 | // Turn off warnings about debug symbols for templates being too long 144 | #pragma warning(disable : 4786) 145 | 146 | #define TRACE_METHOD(fn) \ 147 | { \ 148 | ATLTRACE(_T("0x%04x %s()\n"), (int) GetCurrentThreadId(), _T(#fn)); \ 149 | } 150 | #define TRACE_METHOD_ARGS(fn, pattern, args) \ 151 | { \ 152 | ATLTRACE(_T("0x%04x %s(") _T(pattern) _T(")\n"), (int) GetCurrentThreadId(), _T(#fn), args); \ 153 | } 154 | 155 | //{{AFX_INSERT_LOCATION}} 156 | // Microsoft Developer Studio will insert additional declarations immediately before the previous line. 157 | 158 | #define NS_ASSERTION(x, y) 159 | 160 | #endif // !defined(AFX_STDAFX_H__1339B542_3453_11D2_93B9_000000000000__INCLUDED) 161 | -------------------------------------------------------------------------------- /ffactivex/dllmain.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Contributor: 21 | * Ruediger Jungbeck 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | // dllmain.cpp : Defines the entry point for the DLL application. 38 | #include "ffactivex.h" 39 | #include "axhost.h" 40 | 41 | CComModule _Module; 42 | 43 | NPNetscapeFuncs NPNFuncs; 44 | 45 | BOOL APIENTRY DllMain( HMODULE hModule, 46 | DWORD ul_reason_for_call, 47 | LPVOID lpReserved 48 | ) 49 | { 50 | 51 | 52 | switch (ul_reason_for_call) 53 | { 54 | case DLL_PROCESS_ATTACH: 55 | case DLL_THREAD_ATTACH: 56 | case DLL_THREAD_DETACH: 57 | case DLL_PROCESS_DETACH: 58 | break; 59 | } 60 | return TRUE; 61 | } 62 | 63 | // ============================== 64 | // ! Scriptability related code ! 65 | // ============================== 66 | // 67 | // here the plugin is asked by Mozilla to tell if it is scriptable 68 | // we should return a valid interface id and a pointer to 69 | // nsScriptablePeer interface which we should have implemented 70 | // and which should be defined in the corressponding *.xpt file 71 | // in the bin/components folder 72 | NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) 73 | { 74 | if(instance == NULL) 75 | return NPERR_INVALID_INSTANCE_ERROR; 76 | 77 | NPError rv = NPERR_NO_ERROR; 78 | 79 | if(instance == NULL) 80 | return NPERR_GENERIC_ERROR; 81 | 82 | CAxHost *host = (CAxHost *)instance->pdata; 83 | if(host == NULL) 84 | return NPERR_GENERIC_ERROR; 85 | 86 | switch (variable) { 87 | case NPPVpluginNameString: 88 | *((char **)value) = "ITSTActiveX"; 89 | break; 90 | 91 | case NPPVpluginDescriptionString: 92 | *((char **)value) = "IT Structures ActiveX for Firefox"; 93 | break; 94 | 95 | case NPPVpluginScriptableNPObject: 96 | *(NPObject **)value = host->GetScriptableObject(); 97 | break; 98 | 99 | default: 100 | rv = NPERR_GENERIC_ERROR; 101 | } 102 | 103 | return rv; 104 | } 105 | 106 | NPError NPP_NewStream(NPP instance, 107 | NPMIMEType type, 108 | NPStream* stream, 109 | NPBool seekable, 110 | uint16* stype) 111 | { 112 | if(instance == NULL) 113 | return NPERR_INVALID_INSTANCE_ERROR; 114 | 115 | NPError rv = NPERR_NO_ERROR; 116 | return rv; 117 | } 118 | 119 | int32_t NPP_WriteReady (NPP instance, NPStream *stream) 120 | { 121 | if(instance == NULL) 122 | return NPERR_INVALID_INSTANCE_ERROR; 123 | 124 | int32 rv = 0x0fffffff; 125 | return rv; 126 | } 127 | 128 | int32_t NPP_Write (NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer) 129 | { 130 | if(instance == NULL) 131 | return NPERR_INVALID_INSTANCE_ERROR; 132 | 133 | int32 rv = len; 134 | return rv; 135 | } 136 | 137 | NPError NPP_DestroyStream (NPP instance, NPStream *stream, NPError reason) 138 | { 139 | if(instance == NULL) 140 | return NPERR_INVALID_INSTANCE_ERROR; 141 | 142 | NPError rv = NPERR_NO_ERROR; 143 | return rv; 144 | } 145 | 146 | void NPP_StreamAsFile (NPP instance, NPStream* stream, const char* fname) 147 | { 148 | if(instance == NULL) 149 | return; 150 | } 151 | 152 | void NPP_Print (NPP instance, NPPrint* printInfo) 153 | { 154 | if(instance == NULL) 155 | return; 156 | } 157 | 158 | void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) 159 | { 160 | if(instance == NULL) 161 | return; 162 | } 163 | 164 | NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) 165 | { 166 | if(instance == NULL) 167 | return NPERR_INVALID_INSTANCE_ERROR; 168 | 169 | NPError rv = NPERR_NO_ERROR; 170 | return rv; 171 | } 172 | 173 | int16 NPP_HandleEvent(NPP instance, void* event) 174 | { 175 | if(instance == NULL) 176 | return 0; 177 | 178 | int16 rv = 0; 179 | CAxHost *host = (CAxHost *)instance->pdata; 180 | if (host) 181 | rv = host->HandleEvent(event); 182 | 183 | return rv; 184 | } 185 | 186 | NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs) 187 | { 188 | 189 | if(pFuncs == NULL) 190 | return NPERR_INVALID_FUNCTABLE_ERROR; 191 | 192 | if(pFuncs->size < sizeof(NPPluginFuncs)) 193 | return NPERR_INVALID_FUNCTABLE_ERROR; 194 | 195 | pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; 196 | pFuncs->newp = NPP_New; 197 | pFuncs->destroy = NPP_Destroy; 198 | pFuncs->setwindow = NPP_SetWindow; 199 | pFuncs->newstream = NPP_NewStream; 200 | pFuncs->destroystream = NPP_DestroyStream; 201 | pFuncs->asfile = NPP_StreamAsFile; 202 | pFuncs->writeready = NPP_WriteReady; 203 | pFuncs->write = NPP_Write; 204 | pFuncs->print = NPP_Print; 205 | pFuncs->event = NPP_HandleEvent; 206 | pFuncs->urlnotify = NPP_URLNotify; 207 | pFuncs->getvalue = NPP_GetValue; 208 | pFuncs->setvalue = NPP_SetValue; 209 | pFuncs->javaClass = NULL; 210 | 211 | return NPERR_NO_ERROR; 212 | } 213 | 214 | #define MIN(x, y) ((x) < (y)) ? (x) : (y) 215 | /* 216 | * Initialize the plugin. Called the first time the browser comes across a 217 | * MIME Type this plugin is registered to handle. 218 | */ 219 | NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs) 220 | { 221 | 222 | // _asm {int 3}; 223 | 224 | if(pFuncs == NULL) 225 | return NPERR_INVALID_FUNCTABLE_ERROR; 226 | 227 | #ifdef NDEF 228 | // The following statements prevented usage of newer Mozilla sources than installed browser at runtime 229 | if(HIBYTE(pFuncs->version) > NP_VERSION_MAJOR) 230 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 231 | 232 | if(pFuncs->size < sizeof(NPNetscapeFuncs)) 233 | return NPERR_INVALID_FUNCTABLE_ERROR; 234 | #endif 235 | 236 | if (!AtlAxWinInit()) { 237 | 238 | return NPERR_GENERIC_ERROR; 239 | } 240 | 241 | CoInitialize(NULL); 242 | 243 | _pAtlModule = &_Module; 244 | 245 | memset(&NPNFuncs, 0, sizeof(NPNetscapeFuncs)); 246 | memcpy(&NPNFuncs, pFuncs, MIN(pFuncs->size, sizeof(NPNetscapeFuncs))); 247 | 248 | return NPERR_NO_ERROR; 249 | } 250 | 251 | /* 252 | * Shutdown the plugin. Called when no more instanced of this plugin exist and 253 | * the browser wants to unload it. 254 | */ 255 | NPError OSCALL NP_Shutdown(void) 256 | { 257 | AtlAxWinTerm(); 258 | 259 | return NPERR_NO_ERROR; 260 | } 261 | -------------------------------------------------------------------------------- /ffactivex/ffactivex.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leeor/ff-activex-host/673df0d08eb99fad1a694b7a6d9fc12252f8cd87/ffactivex/ffactivex.aps -------------------------------------------------------------------------------- /ffactivex/ffactivex.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Contributor: 21 | * Ruediger Jungbeck 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | // ffactivex.cpp : Defines the exported functions for the DLL application. 38 | // 39 | 40 | #include "ffactivex.h" 41 | #include "common/stdafx.h" 42 | #include "axhost.h" 43 | #include "atlutil.h" 44 | 45 | #include "authorize.h" 46 | 47 | // A list of trusted domains 48 | // Each domain name may start with a '*' to specify that sub domains are 49 | // trusted as well 50 | // Note that a '.' is not enforced after the '*' 51 | static const char *TrustedLocations[] = {NULL}; 52 | static const unsigned int numTrustedLocations = 0; 53 | 54 | static const char *LocalhostName = "localhost"; 55 | static const bool TrustLocalhost = true; 56 | 57 | void * 58 | ffax_calloc(unsigned int size) 59 | { 60 | void *ptr = NULL; 61 | 62 | ptr = NPNFuncs.memalloc(size); 63 | if (ptr) { 64 | 65 | memset(ptr, 0, size); 66 | } 67 | 68 | return ptr; 69 | } 70 | 71 | void 72 | ffax_free(void *ptr) 73 | { 74 | if (ptr) 75 | NPNFuncs.memfree(ptr); 76 | } 77 | 78 | // 79 | // Gecko API 80 | // 81 | 82 | static unsigned int log_level = 0; 83 | static char *logger = NULL; 84 | 85 | void 86 | log(NPP instance, unsigned int level, char *message, ...) 87 | { 88 | NPVariant result; 89 | NPVariant args; 90 | NPObject *globalObj = NULL; 91 | bool rc = false; 92 | char *formatted = NULL; 93 | char *new_formatted = NULL; 94 | int buff_len = 0; 95 | int size = 0; 96 | 97 | va_list list; 98 | 99 | if (!logger || (level > log_level)) { 100 | 101 | return; 102 | } 103 | 104 | buff_len = strlen(message); 105 | buff_len += buff_len / 10; 106 | formatted = (char *)calloc(1, buff_len); 107 | while (true) { 108 | 109 | va_start(list, message); 110 | size = vsnprintf_s(formatted, buff_len, _TRUNCATE, message, list); 111 | va_end(list); 112 | 113 | if (size > -1 && size < buff_len) 114 | break; 115 | 116 | buff_len *= 2; 117 | new_formatted = (char *)realloc(formatted, buff_len); 118 | if (NULL == new_formatted) { 119 | 120 | free(formatted); 121 | return; 122 | } 123 | 124 | formatted = new_formatted; 125 | new_formatted = NULL; 126 | } 127 | 128 | NPNFuncs.getvalue(instance, NPNVWindowNPObject, &globalObj); 129 | NPIdentifier handler = NPNFuncs.getstringidentifier(logger); 130 | 131 | STRINGZ_TO_NPVARIANT(formatted, args); 132 | 133 | bool success = NPNFuncs.invoke(instance, globalObj, handler, &args, 1, &result); 134 | NPNFuncs.releasevariantvalue(&result); 135 | NPNFuncs.releaseobject(globalObj); 136 | 137 | free(formatted); 138 | } 139 | 140 | static bool 141 | MatchURL2TrustedLocations(NPP instance, LPCTSTR matchUrl) 142 | { 143 | USES_CONVERSION; 144 | bool rc = false; 145 | CUrl url; 146 | 147 | if (!numTrustedLocations) { 148 | 149 | return true; 150 | } 151 | 152 | rc = url.CrackUrl(matchUrl, ATL_URL_DECODE); 153 | if (!rc) { 154 | 155 | log(instance, 0, "AxHost.MatchURL2TrustedLocations: failed to parse the current location URL"); 156 | return false; 157 | } 158 | 159 | if ( (url.GetScheme() == ATL_URL_SCHEME_FILE) 160 | || (!strncmp(LocalhostName, W2A(url.GetHostName()), strlen(LocalhostName)))){ 161 | 162 | return TrustLocalhost; 163 | } 164 | 165 | for (unsigned int i = 0; i < numTrustedLocations; ++i) { 166 | 167 | if (TrustedLocations[i][0] == '*') { 168 | // sub domains are trusted 169 | unsigned int len = strlen(TrustedLocations[i]); 170 | bool match = 0; 171 | 172 | if (url.GetHostNameLength() < len) { 173 | // can't be a match 174 | continue; 175 | } 176 | 177 | --len; // skip the '*' 178 | match = strncmp(W2A(url.GetHostName()) + (url.GetHostNameLength() - len), // anchor the comparison to the end of the domain name 179 | TrustedLocations[i] + 1, // skip the '*' 180 | len) == 0 ? true : false; 181 | if (match) { 182 | 183 | return true; 184 | } 185 | } 186 | else if (!strncmp(W2A(url.GetHostName()), TrustedLocations[i], url.GetHostNameLength())) { 187 | 188 | return true; 189 | } 190 | } 191 | 192 | return false; 193 | } 194 | 195 | static bool 196 | VerifySiteLock(NPP instance) 197 | { 198 | USES_CONVERSION; 199 | NPObject *globalObj = NULL; 200 | NPIdentifier identifier; 201 | NPVariant varLocation; 202 | NPVariant varHref; 203 | bool rc = false; 204 | 205 | // Get the window object. 206 | NPNFuncs.getvalue(instance, NPNVWindowNPObject, &globalObj); 207 | // Create a "location" identifier. 208 | identifier = NPNFuncs.getstringidentifier("location"); 209 | 210 | // Get the location property from the window object (which is another object). 211 | rc = NPNFuncs.getproperty(instance, globalObj, identifier, &varLocation); 212 | NPNFuncs.releaseobject(globalObj); 213 | if (!rc){ 214 | 215 | log(instance, 0, "AxHost.VerifySiteLock: could not get the location from the global object"); 216 | return false; 217 | } 218 | 219 | // Get a pointer to the "location" object. 220 | NPObject *locationObj = varLocation.value.objectValue; 221 | // Create a "href" identifier. 222 | identifier = NPNFuncs.getstringidentifier("href"); 223 | // Get the location property from the location object. 224 | rc = NPNFuncs.getproperty(instance, locationObj, identifier, &varHref); 225 | NPNFuncs.releasevariantvalue(&varLocation); 226 | if (!rc) { 227 | 228 | log(instance, 0, "AxHost.VerifySiteLock: could not get the href from the location property"); 229 | return false; 230 | } 231 | 232 | rc = MatchURL2TrustedLocations(instance, A2W(varHref.value.stringValue.UTF8Characters)); 233 | NPNFuncs.releasevariantvalue(&varHref); 234 | 235 | if (false == rc) { 236 | 237 | log(instance, 0, "AxHost.VerifySiteLock: current location is not trusted"); 238 | } 239 | 240 | return rc; 241 | } 242 | 243 | /* 244 | * Create a new plugin instance, most probably through an embed/object HTML 245 | * element. 246 | * 247 | * Any private data we want to keep for this instance can be saved into 248 | * [instance->pdata]. 249 | * [saved] might hold information a previous instance that was invoked from the 250 | * same URL has saved for us. 251 | */ 252 | NPError 253 | NPP_New(NPMIMEType pluginType, 254 | NPP instance, uint16 mode, 255 | int16 argc, char *argn[], 256 | char *argv[], NPSavedData *saved) 257 | { 258 | NPError rc = NPERR_NO_ERROR; 259 | NPObject *browser = NULL; 260 | CAxHost *host = NULL; 261 | PropertyList events; 262 | int16 i = 0; 263 | USES_CONVERSION; 264 | 265 | //_asm {int 3}; 266 | 267 | if (!instance || (0 == NPNFuncs.size)) { 268 | 269 | return NPERR_INVALID_PARAM; 270 | } 271 | 272 | #ifdef NO_REGISTRY_AUTHORIZE 273 | // Verify that we're running from a trusted location 274 | if (!VerifySiteLock(instance)) { 275 | 276 | return NPERR_GENERIC_ERROR; 277 | } 278 | #endif 279 | 280 | instance->pdata = NULL; 281 | 282 | #ifndef NO_REGISTRY_AUTHORIZE 283 | 284 | if (!TestAuthorization (instance, 285 | argc, 286 | argn, 287 | argv, 288 | pluginType)) { 289 | return NPERR_GENERIC_ERROR; 290 | } 291 | 292 | #endif 293 | 294 | // TODO: Check the pluginType to make sure we're being called with the rigth MIME Type 295 | 296 | do { 297 | // Create a plugin instance, the actual control will be created once we 298 | // are given a window handle 299 | host = new CAxHost(instance); 300 | if (!host) { 301 | 302 | rc = NPERR_OUT_OF_MEMORY_ERROR; 303 | log(instance, 0, "AxHost.NPP_New: failed to allocate memory for a new host"); 304 | break; 305 | } 306 | 307 | // Iterate over the arguments we've been passed 308 | for (i = 0; 309 | (i < argc) && (NPERR_NO_ERROR == rc); 310 | ++i) { 311 | 312 | // search for any needed information: clsid, event handling directives, etc. 313 | if (0 == strnicmp(argn[i], PARAM_CLSID, strlen(PARAM_CLSID))) { 314 | // The class id of the control we are asked to load 315 | host->setClsID(argv[i]); 316 | } 317 | else if (0 == strnicmp(argn[i], PARAM_PROGID, strlen(PARAM_PROGID))) { 318 | // The class id of the control we are asked to load 319 | host->setClsIDFromProgID(argv[i]); 320 | } 321 | else if (0 == strnicmp(argn[i], PARAM_DEBUG, strlen(PARAM_DEBUG))) { 322 | // Logging verbosity 323 | log_level = atoi(argv[i]); 324 | log(instance, 0, "AxHost.NPP_New: debug level set to %d", log_level); 325 | } 326 | else if (0 == strnicmp(argn[i], PARAM_LOGGER, strlen(PARAM_LOGGER))) { 327 | // Logger function 328 | logger = strdup(argv[i]); 329 | } 330 | else if (0 == strnicmp(argn[i], PARAM_ONEVENT, strlen(PARAM_ONEVENT))) { 331 | // A request to handle one of the activex's events in JS 332 | events.AddOrReplaceNamedProperty(A2W(argn[i] + strlen(PARAM_ONEVENT)), CComVariant(A2W(argv[i]))); 333 | } 334 | else if (0 == strnicmp(argn[i], PARAM_PARAM, strlen(PARAM_PARAM))) { 335 | 336 | CComBSTR paramName = argn[i] + strlen(PARAM_PARAM); 337 | CComBSTR paramValue(Utf8StringToBstr(argv[i], strlen(argv[i]))); 338 | 339 | // Check for existing params with the same name 340 | BOOL bFound = FALSE; 341 | for (unsigned long j = 0; j < host->Props.GetSize(); j++) { 342 | 343 | if (wcscmp(host->Props.GetNameOf(j), (BSTR) paramName) == 0) { 344 | 345 | bFound = TRUE; 346 | break; 347 | } 348 | } 349 | // If the parameter already exists, don't add it to the 350 | // list again. 351 | if (bFound) { 352 | 353 | continue; 354 | } 355 | 356 | // Add named parameter to list 357 | CComVariant v(paramValue); 358 | host->Props.AddNamedProperty(paramName, v); 359 | } 360 | else if(0 == strnicmp(argn[i], PARAM_CODEBASEURL, strlen(PARAM_CODEBASEURL))) { 361 | 362 | if (MatchURL2TrustedLocations(instance, A2W(argv[i]))) { 363 | 364 | host->setCodeBaseUrl(A2W(argv[i])); 365 | } 366 | else { 367 | 368 | log(instance, 0, "AxHost.NPP_New: codeBaseUrl contains an untrusted location"); 369 | } 370 | } 371 | } 372 | 373 | if (NPERR_NO_ERROR != rc) 374 | break; 375 | 376 | // Make sure we have all the information we need to initialize a new instance 377 | if (!host->hasValidClsID()) { 378 | 379 | rc = NPERR_INVALID_PARAM; 380 | log(instance, 0, "AxHost.NPP_New: no valid CLSID or PROGID"); 381 | break; 382 | } 383 | 384 | instance->pdata = host; 385 | 386 | // if no events were requested, don't fail if subscribing fails 387 | if (!host->CreateControl(events.GetSize() ? true : false)) { 388 | 389 | rc = NPERR_GENERIC_ERROR; 390 | log(instance, 0, "AxHost.NPP_New: failed to create the control"); 391 | break; 392 | } 393 | 394 | for (unsigned int j = 0; j < events.GetSize(); j++) { 395 | 396 | if (!host->AddEventHandler(events.GetNameOf(j), events.GetValueOf(j)->bstrVal)) { 397 | 398 | //rc = NPERR_GENERIC_ERROR; 399 | //break; 400 | } 401 | } 402 | 403 | if (NPERR_NO_ERROR != rc) 404 | break; 405 | } while (0); 406 | 407 | if (NPERR_NO_ERROR != rc) { 408 | 409 | delete host; 410 | } 411 | 412 | return rc; 413 | } 414 | 415 | /* 416 | * Destroy an existing plugin instance. 417 | * 418 | * [save] can be used to save information for a future instance of our plugin 419 | * that'll be invoked by the same URL. 420 | */ 421 | NPError 422 | NPP_Destroy(NPP instance, NPSavedData **save) 423 | { 424 | 425 | // _asm {int 3}; 426 | 427 | if (!instance || !instance->pdata) { 428 | 429 | return NPERR_INVALID_PARAM; 430 | } 431 | 432 | log(instance, 0, "NPP_Destroy: destroying the control..."); 433 | 434 | CAxHost *host = (CAxHost *)instance->pdata; 435 | delete host; 436 | instance->pdata = NULL; 437 | 438 | return NPERR_NO_ERROR; 439 | } 440 | 441 | /* 442 | * Sets an instance's window parameters. 443 | */ 444 | NPError 445 | NPP_SetWindow(NPP instance, NPWindow *window) 446 | { 447 | CAxHost *host = NULL; 448 | RECT rcPos; 449 | 450 | if (!instance || !instance->pdata) { 451 | 452 | return NPERR_INVALID_PARAM; 453 | } 454 | 455 | host = (CAxHost *)instance->pdata; 456 | 457 | host->setWindow((HWND)window->window); 458 | 459 | rcPos.left = 0; 460 | rcPos.top = 0; 461 | rcPos.right = window->width; 462 | rcPos.bottom = window->height; 463 | host->UpdateRect(rcPos); 464 | 465 | return NPERR_NO_ERROR; 466 | } 467 | -------------------------------------------------------------------------------- /ffactivex/ffactivex.def: -------------------------------------------------------------------------------- 1 | LIBRARY "npffax" 2 | 3 | EXPORTS 4 | NP_GetEntryPoints @1 5 | NP_Initialize @2 6 | NP_Shutdown @3 7 | -------------------------------------------------------------------------------- /ffactivex/ffactivex.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Contributor: 21 | * Ruediger Jungbeck 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | #pragma once 38 | 39 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 40 | // Windows Header Files: 41 | #include 42 | 43 | #include "npapi.h" 44 | #include 45 | #include 46 | 47 | #include "targetver.h" 48 | 49 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #include "variants.h" 58 | 59 | #include "common/PropertyList.h" 60 | #include "common/PropertyBag.h" 61 | #include "common/ItemContainer.h" 62 | #include "common/ControlSite.h" 63 | #include "common/ControlSiteIPFrame.h" 64 | #include "common/ControlEventSink.h" 65 | 66 | extern NPNetscapeFuncs NPNFuncs; 67 | 68 | //#define NO_REGISTRY_AUTHORIZE 69 | 70 | static const char PARAM_CLSID[] = "clsid"; 71 | static const char PARAM_PROGID[] = "progid"; 72 | static const char PARAM_DEBUG[] = "debugLevel"; 73 | static const char PARAM_LOGGER[] = "logger"; 74 | static const char PARAM_CODEBASEURL [] = "codeBaseUrl"; 75 | static const char PARAM_ONEVENT[] = "Event_"; 76 | static const char PARAM_PARAM[] = "PARAM_"; 77 | 78 | void *ffax_calloc(unsigned int size); 79 | void ffax_free(void *ptr); 80 | void log(NPP instance, unsigned int level, char *message, ...); 81 | NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved); 82 | NPError NPP_Destroy(NPP instance, NPSavedData **save); 83 | NPError NPP_SetWindow(NPP instance, NPWindow *window); 84 | 85 | -------------------------------------------------------------------------------- /ffactivex/ffactivex.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (United States) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 20 | #pragma code_page(1252) 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""afxres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Version 51 | // 52 | 53 | VS_VERSION_INFO VERSIONINFO 54 | FILEVERSION 1,38,0,0 55 | PRODUCTVERSION 1,38,0,0 56 | FILEFLAGSMASK 0x3fL 57 | #ifdef _DEBUG 58 | FILEFLAGS 0x1L 59 | #else 60 | FILEFLAGS 0x0L 61 | #endif 62 | FILEOS 0x4L 63 | FILETYPE 0x2L 64 | FILESUBTYPE 0x0L 65 | BEGIN 66 | BLOCK "StringFileInfo" 67 | BEGIN 68 | BLOCK "040904e4" 69 | BEGIN 70 | VALUE "FileDescription", "ActiveX hosting plugin for Firefox r38" 71 | VALUE "FileExtents", "ocx" 72 | VALUE "FileOpenName", "ActiveX (*.ocx)" 73 | VALUE "FileVersion", "r38" 74 | VALUE "InternalName", "ffactivex.dll" 75 | VALUE "LegalCopyright", "(c) CloudShare Ltd. All rights reserved." 76 | VALUE "MIMEType", "application/x-itst-activex" 77 | VALUE "OriginalFilename", "ffactivex.dll" 78 | VALUE "ProductName", "ActiveX hosting plugin for Firefox" 79 | VALUE "ProductVersion", "r38" 80 | END 81 | END 82 | BLOCK "VarFileInfo" 83 | BEGIN 84 | VALUE "Translation", 0x409, 1252 85 | END 86 | END 87 | 88 | #endif // English (United States) resources 89 | ///////////////////////////////////////////////////////////////////////////// 90 | 91 | 92 | 93 | #ifndef APSTUDIO_INVOKED 94 | ///////////////////////////////////////////////////////////////////////////// 95 | // 96 | // Generated from the TEXTINCLUDE 3 resource. 97 | // 98 | 99 | 100 | ///////////////////////////////////////////////////////////////////////////// 101 | #endif // not APSTUDIO_INVOKED 102 | 103 | -------------------------------------------------------------------------------- /ffactivex/ffactivex.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 28 | 31 | 34 | 37 | 40 | 43 | 56 | 59 | 62 | 65 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 97 | 107 | 110 | 113 | 116 | 119 | 122 | 135 | 138 | 141 | 144 | 156 | 159 | 162 | 165 | 168 | 171 | 174 | 177 | 178 | 179 | 180 | 181 | 182 | 187 | 190 | 191 | 194 | 195 | 198 | 199 | 202 | 203 | 206 | 207 | 210 | 211 | 214 | 217 | 222 | 223 | 226 | 231 | 232 | 233 | 236 | 237 | 240 | 241 | 244 | 245 | 248 | 249 | 252 | 253 | 256 | 257 | 260 | 263 | 267 | 268 | 271 | 275 | 276 | 277 | 280 | 281 | 282 | 287 | 290 | 291 | 294 | 295 | 298 | 299 | 302 | 303 | 306 | 307 | 310 | 311 | 314 | 315 | 318 | 319 | 322 | 323 | 326 | 327 | 330 | 331 | 334 | 335 | 338 | 339 | 342 | 343 | 346 | 347 | 350 | 351 | 352 | 357 | 360 | 361 | 362 | 365 | 366 | 367 | 368 | 369 | 370 | -------------------------------------------------------------------------------- /ffactivex/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by ffactivex.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /ffactivex/scriptable.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Contributor: 21 | * Ruediger Jungbeck 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | #include "scriptable.h" 38 | 39 | static NPObject* 40 | AllocateScriptable(NPP npp, NPClass *aClass) 41 | { 42 | return new Scriptable(); 43 | } 44 | 45 | static void 46 | DeallocateScriptable(NPObject *obj) 47 | { 48 | if (!obj) { 49 | 50 | return; 51 | } 52 | 53 | Scriptable *s = (Scriptable *)obj; 54 | delete s; 55 | } 56 | 57 | static void 58 | InvalidateScriptable(NPObject *obj) 59 | { 60 | if (!obj) { 61 | 62 | return; 63 | } 64 | 65 | ((Scriptable *)obj)->Invalidate(); 66 | } 67 | 68 | NPClass ScriptableNPClass = { 69 | /* version */ NP_CLASS_STRUCT_VERSION, 70 | /* allocate */ AllocateScriptable, 71 | /* deallocate */ DeallocateScriptable, 72 | /* invalidate */ InvalidateScriptable, 73 | /* hasMethod */ Scriptable::_HasMethod, 74 | /* invoke */ Scriptable::_Invoke, 75 | /* invokeDefault */ NULL, 76 | /* hasProperty */ Scriptable::_HasProperty, 77 | /* getProperty */ Scriptable::_GetProperty, 78 | /* setProperty */ Scriptable::_SetProperty, 79 | /* removeProperty */ NULL, 80 | /* enumerate */ NULL, 81 | /* construct */ NULL 82 | }; 83 | -------------------------------------------------------------------------------- /ffactivex/scriptable.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Alternatively, the contents of this file may be used under the terms of 21 | * either the GNU General Public License Version 2 or later (the "GPL"), or 22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 23 | * in which case the provisions of the GPL or the LGPL are applicable instead 24 | * of those above. If you wish to allow use of your version of this file only 25 | * under the terms of either the GPL or the LGPL, and not to allow others to 26 | * use your version of this file under the terms of the MPL, indicate your 27 | * decision by deleting the provisions above and replace them with the notice 28 | * and other provisions required by the GPL or the LGPL. If you do not delete 29 | * the provisions above, a recipient may use your version of this file under 30 | * the terms of any one of the MPL, the GPL or the LGPL. 31 | * 32 | * ***** END LICENSE BLOCK ***** */ 33 | 34 | #pragma once 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "variants.h" 42 | 43 | extern NPNetscapeFuncs NPNFuncs; 44 | extern NPClass ScriptableNPClass; 45 | 46 | class Scriptable: public NPObject 47 | { 48 | private: 49 | Scriptable(const Scriptable &); 50 | 51 | // This method iterates all members of the current interface, looking for the member with the 52 | // id of member_id. If not found within this interface, it will iterate all base interfaces 53 | // recursively, until a match is found, or all the hierarchy was searched. 54 | bool find_member(ITypeInfoPtr info, TYPEATTR *attr, DISPID member_id, unsigned int invKind) { 55 | 56 | bool found = false; 57 | unsigned int i = 0; 58 | 59 | FUNCDESC *fDesc; 60 | 61 | for (i = 0; 62 | (i < attr->cFuncs) 63 | && !found; 64 | ++i) { 65 | 66 | HRESULT hr = info->GetFuncDesc(i, &fDesc); 67 | if ( SUCCEEDED(hr) 68 | && fDesc 69 | && (fDesc->memid == member_id)) { 70 | 71 | if (invKind & fDesc->invkind) 72 | found = true; 73 | } 74 | info->ReleaseFuncDesc(fDesc); 75 | } 76 | 77 | if (!found && (invKind & ~INVOKE_FUNC)) { 78 | 79 | VARDESC *vDesc; 80 | 81 | for (i = 0; 82 | (i < attr->cVars) 83 | && !found; 84 | ++i) { 85 | 86 | HRESULT hr = info->GetVarDesc(i, &vDesc); 87 | if ( SUCCEEDED(hr) 88 | && vDesc 89 | && (vDesc->memid == member_id)) { 90 | 91 | found = true; 92 | } 93 | info->ReleaseVarDesc(vDesc); 94 | } 95 | } 96 | 97 | if (!found) { 98 | // iterate inherited interfaces 99 | HREFTYPE refType = NULL; 100 | 101 | for (i = 0; (i < attr->cImplTypes) && !found; ++i) { 102 | 103 | ITypeInfoPtr baseInfo; 104 | TYPEATTR *baseAttr; 105 | 106 | if (FAILED(info->GetRefTypeOfImplType(0, &refType))) { 107 | 108 | continue; 109 | } 110 | 111 | if (FAILED(info->GetRefTypeInfo(refType, &baseInfo))) { 112 | 113 | continue; 114 | } 115 | 116 | if (FAILED(baseInfo->GetTypeAttr(&baseAttr))) { 117 | 118 | continue; 119 | } 120 | 121 | found = find_member(baseInfo, baseAttr, member_id, invKind); 122 | baseInfo->ReleaseTypeAttr(baseAttr); 123 | } 124 | } 125 | 126 | return found; 127 | } 128 | 129 | DISPID ResolveName(NPIdentifier name, unsigned int invKind) { 130 | 131 | bool found = false; 132 | DISPID dID = -1; 133 | USES_CONVERSION; 134 | 135 | if (!name || !invKind) { 136 | 137 | return -1; 138 | } 139 | 140 | if (!NPNFuncs.identifierisstring(name)) { 141 | 142 | return -1; 143 | } 144 | 145 | NPUTF8 *npname = NPNFuncs.utf8fromidentifier(name); 146 | LPOLESTR oleName = A2W(npname); 147 | 148 | IDispatchPtr disp = control.GetInterfacePtr(); 149 | if (!disp) { 150 | 151 | return -1; 152 | } 153 | 154 | disp->GetIDsOfNames(IID_NULL, &oleName, 1, LOCALE_SYSTEM_DEFAULT, &dID); 155 | if (dID != -1) { 156 | 157 | ITypeInfoPtr info; 158 | disp->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &info); 159 | if (!info) { 160 | 161 | return -1; 162 | } 163 | 164 | TYPEATTR *attr; 165 | if (FAILED(info->GetTypeAttr(&attr))) { 166 | 167 | return -1; 168 | } 169 | 170 | found = find_member(info, attr, dID, invKind); 171 | info->ReleaseTypeAttr(attr); 172 | } 173 | 174 | return found ? dID : -1; 175 | } 176 | 177 | bool InvokeControl(DISPID id, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult) { 178 | 179 | IDispatchPtr disp = control.GetInterfacePtr(); 180 | if (!disp) { 181 | 182 | return false; 183 | } 184 | 185 | HRESULT hr = disp->Invoke(id, IID_NULL, LOCALE_SYSTEM_DEFAULT, wFlags, pDispParams, pVarResult, NULL, NULL); 186 | 187 | return (SUCCEEDED(hr)) ? true : false; 188 | } 189 | 190 | IUnknownPtr control; 191 | NPP instance; 192 | bool invalid; 193 | 194 | public: 195 | Scriptable(): 196 | invalid(false), 197 | control(NULL), 198 | instance(NULL) { 199 | } 200 | 201 | ~Scriptable() {control->Release();} 202 | 203 | void setControl(IUnknown *unk) {control = unk;} 204 | void setControl(IDispatch *disp) {disp->QueryInterface(IID_IUnknown, (void **)&control);} 205 | void setInstance(NPP inst) {instance = inst;} 206 | 207 | void Invalidate() {invalid = true;} 208 | 209 | static bool _HasMethod(NPObject *npobj, NPIdentifier name) { 210 | 211 | return ((Scriptable *)npobj)->HasMethod(name); 212 | } 213 | 214 | static bool _Invoke(NPObject *npobj, NPIdentifier name, 215 | const NPVariant *args, uint32_t argCount, 216 | NPVariant *result) { 217 | 218 | return ((Scriptable *)npobj)->Invoke(name, args, argCount, result); 219 | } 220 | 221 | static bool _HasProperty(NPObject *npobj, NPIdentifier name) { 222 | 223 | return ((Scriptable *)npobj)->HasProperty(name); 224 | } 225 | 226 | static bool _GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) { 227 | 228 | return ((Scriptable *)npobj)->GetProperty(name, result); 229 | } 230 | 231 | static bool _SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) { 232 | 233 | return ((Scriptable *)npobj)->SetProperty(name, value); 234 | } 235 | 236 | bool HasMethod(NPIdentifier name) { 237 | 238 | if (invalid) return false; 239 | 240 | DISPID id = ResolveName(name, INVOKE_FUNC); 241 | return (id != -1) ? true : false; 242 | } 243 | 244 | bool Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) { 245 | 246 | if (invalid) return false; 247 | 248 | DISPID id = ResolveName(name, INVOKE_FUNC); 249 | if (-1 == id) { 250 | 251 | return false; 252 | } 253 | 254 | VARIANT *vArgs = NULL; 255 | if (argCount) { 256 | 257 | vArgs = new VARIANT[argCount]; 258 | if (!vArgs) { 259 | 260 | return false; 261 | } 262 | 263 | for (unsigned int i = 0; i < argCount; ++i) { 264 | 265 | // copy the arguments in reverse order 266 | NPVar2Variant(&args[i], &vArgs[argCount - i - 1], instance); 267 | } 268 | } 269 | 270 | DISPPARAMS params = {NULL, NULL, 0, 0}; 271 | 272 | params.cArgs = argCount; 273 | params.cNamedArgs = 0; 274 | params.rgdispidNamedArgs = NULL; 275 | params.rgvarg = vArgs; 276 | 277 | VARIANT vResult; 278 | 279 | bool rc = InvokeControl(id, DISPATCH_METHOD, ¶ms, &vResult); 280 | if (vArgs) delete[] vArgs; 281 | 282 | if (!rc) { 283 | 284 | return false; 285 | } 286 | 287 | Variant2NPVar(&vResult, result, instance); 288 | return true; 289 | } 290 | 291 | bool HasProperty(NPIdentifier name) { 292 | 293 | if (invalid) return false; 294 | 295 | DISPID id = ResolveName(name, INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT); 296 | return (id != -1) ? true : false; 297 | } 298 | 299 | bool GetProperty(NPIdentifier name, NPVariant *result) { 300 | 301 | if (invalid) return false; 302 | 303 | DISPID id = ResolveName(name, INVOKE_PROPERTYGET); 304 | if (-1 == id) { 305 | 306 | return false; 307 | } 308 | 309 | DISPPARAMS params; 310 | 311 | params.cArgs = 0; 312 | params.cNamedArgs = 0; 313 | params.rgdispidNamedArgs = NULL; 314 | params.rgvarg = NULL; 315 | 316 | VARIANT vResult; 317 | 318 | if (!InvokeControl(id, DISPATCH_PROPERTYGET, ¶ms, &vResult)) { 319 | 320 | return false; 321 | } 322 | 323 | Variant2NPVar(&vResult, result, instance); 324 | return true; 325 | } 326 | 327 | bool SetProperty(NPIdentifier name, const NPVariant *value) { 328 | 329 | if (invalid) return false; 330 | 331 | DISPID id = ResolveName(name, INVOKE_PROPERTYPUT); 332 | if (-1 == id) { 333 | 334 | return false; 335 | } 336 | 337 | VARIANT val; 338 | NPVar2Variant(value, &val, instance); 339 | 340 | DISPPARAMS params; 341 | // Special initialization needed when using propery put. 342 | DISPID dispidNamed = DISPID_PROPERTYPUT; 343 | params.cNamedArgs = 1; 344 | params.rgdispidNamedArgs = &dispidNamed; 345 | params.cArgs = 1; 346 | params.rgvarg = &val; 347 | 348 | VARIANT vResult; 349 | if (!InvokeControl(id, DISPATCH_PROPERTYPUT, ¶ms, &vResult)) { 350 | 351 | return false; 352 | } 353 | 354 | return true; 355 | } 356 | }; 357 | 358 | -------------------------------------------------------------------------------- /ffactivex/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // ffactivex.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ffactivex/stdafx.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Alternatively, the contents of this file may be used under the terms of 21 | * either the GNU General Public License Version 2 or later (the "GPL"), or 22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 23 | * in which case the provisions of the GPL or the LGPL are applicable instead 24 | * of those above. If you wish to allow use of your version of this file only 25 | * under the terms of either the GPL or the LGPL, and not to allow others to 26 | * use your version of this file under the terms of the MPL, indicate your 27 | * decision by deleting the provisions above and replace them with the notice 28 | * and other provisions required by the GPL or the LGPL. If you do not delete 29 | * the provisions above, a recipient may use your version of this file under 30 | * the terms of any one of the MPL, the GPL or the LGPL. 31 | * 32 | * ***** END LICENSE BLOCK ***** */ 33 | 34 | // stdafx.h : include file for standard system include files, 35 | // or project specific include files that are used frequently, but 36 | // are changed infrequently 37 | // 38 | 39 | #pragma once 40 | 41 | #include "targetver.h" 42 | 43 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 44 | // Windows Header Files: 45 | #include 46 | 47 | 48 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 49 | 50 | #include 51 | #include 52 | 53 | // TODO: reference additional headers your program requires here 54 | -------------------------------------------------------------------------------- /ffactivex/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef WINVER // Specifies that the minimum required platform is Windows Vista. 11 | #define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. 15 | #define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. 16 | #endif 17 | 18 | #ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. 19 | #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. 20 | #endif 21 | 22 | #ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. 23 | #define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. 24 | #endif 25 | -------------------------------------------------------------------------------- /ffactivex/variants.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Contributor: 21 | * Ruediger Jungbeck 22 | * 23 | * Alternatively, the contents of this file may be used under the terms of 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 | * in which case the provisions of the GPL or the LGPL are applicable instead 27 | * of those above. If you wish to allow use of your version of this file only 28 | * under the terms of either the GPL or the LGPL, and not to allow others to 29 | * use your version of this file under the terms of the MPL, indicate your 30 | * decision by deleting the provisions above and replace them with the notice 31 | * and other provisions required by the GPL or the LGPL. If you do not delete 32 | * the provisions above, a recipient may use your version of this file under 33 | * the terms of any one of the MPL, the GPL or the LGPL. 34 | * 35 | * ***** END LICENSE BLOCK ***** */ 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | #include "scriptable.h" 45 | #include "GenericNPObject.h" 46 | #include "variants.h" 47 | 48 | extern NPNetscapeFuncs NPNFuncs; 49 | 50 | BSTR 51 | Utf8StringToBstr(LPCSTR szStr, int iSize) 52 | { 53 | BSTR bstrVal; 54 | // Chars required for string 55 | int iReq = 0; 56 | 57 | if (iSize > 0) { 58 | 59 | if ((iReq = MultiByteToWideChar(CP_UTF8, 0, szStr, iSize, 0, 0)) == 0) { 60 | 61 | return (0); 62 | } 63 | } 64 | 65 | // Account for terminating 0. 66 | if (iReq != -1) { 67 | 68 | ++iReq; 69 | } 70 | 71 | if ((bstrVal = ::SysAllocStringLen(0, iReq)) == 0) { 72 | 73 | return (0); 74 | } 75 | 76 | memset(bstrVal, 0, iReq * sizeof(wchar_t)); 77 | 78 | if (iSize > 0) { 79 | // Convert into the buffer. 80 | if (MultiByteToWideChar(CP_UTF8, 0, szStr, iSize, bstrVal, iReq) == 0) { 81 | 82 | ::SysFreeString(bstrVal); 83 | return 0; 84 | } 85 | } 86 | 87 | return (bstrVal); 88 | } 89 | 90 | void 91 | BSTR2NPVar(BSTR bstr, NPVariant *npvar, NPP instance) 92 | { 93 | USES_CONVERSION; 94 | char *npStr = NULL; 95 | size_t sourceLen; 96 | size_t bytesNeeded; 97 | 98 | sourceLen = lstrlenW(bstr); 99 | 100 | bytesNeeded = WideCharToMultiByte(CP_UTF8, 101 | 0, 102 | bstr, 103 | sourceLen, 104 | NULL, 105 | 0, 106 | NULL, 107 | NULL); 108 | 109 | bytesNeeded += 1; 110 | 111 | // complete lack of documentation on Mozilla's part here, I have no 112 | // idea how this string is supposed to be freed 113 | npStr = (char *)NPNFuncs.memalloc(bytesNeeded); 114 | if (npStr) { 115 | 116 | memset(npStr, 0, bytesNeeded); 117 | 118 | WideCharToMultiByte(CP_UTF8, 119 | 0, 120 | bstr, 121 | sourceLen, 122 | npStr, 123 | bytesNeeded - 1, 124 | NULL, 125 | NULL); 126 | 127 | STRINGZ_TO_NPVARIANT(npStr, (*npvar)); 128 | } 129 | else { 130 | 131 | STRINGZ_TO_NPVARIANT(NULL, (*npvar)); 132 | } 133 | } 134 | 135 | void 136 | Dispatch2NPVar(IDispatch *disp, NPVariant *npvar, NPP instance) 137 | { 138 | NPObject *obj = NULL; 139 | 140 | obj = NPNFuncs.createobject(instance, &ScriptableNPClass); 141 | 142 | ((Scriptable *)obj)->setControl(disp); 143 | ((Scriptable *)obj)->setInstance(instance); 144 | OBJECT_TO_NPVARIANT(obj, (*npvar)); 145 | } 146 | 147 | void 148 | Unknown2NPVar(IUnknown *unk, NPVariant *npvar, NPP instance) 149 | { 150 | NPObject *obj = NULL; 151 | 152 | obj = NPNFuncs.createobject(instance, &ScriptableNPClass); 153 | 154 | ((Scriptable *)obj)->setControl(unk); 155 | ((Scriptable *)obj)->setInstance(instance); 156 | OBJECT_TO_NPVARIANT(obj, (*npvar)); 157 | } 158 | 159 | NPObject * 160 | SafeArray2NPObject(SAFEARRAY *parray, unsigned short dim, unsigned long *pindices, NPP instance) 161 | { 162 | unsigned long *indices = pindices; 163 | NPObject *obj = NULL; 164 | bool rc = true; 165 | 166 | if (!parray || !instance) { 167 | 168 | return NULL; 169 | } 170 | 171 | obj = NPNFuncs.createobject(instance, &GenericNPObjectClass); 172 | if (NULL == obj) { 173 | 174 | return NULL; 175 | } 176 | 177 | do { 178 | if (NULL == indices) { 179 | // just getting started 180 | SafeArrayLock(parray); 181 | 182 | indices = (unsigned long *)calloc(1, parray->cDims * sizeof(unsigned long)); 183 | if (NULL == indices) { 184 | 185 | rc = false; 186 | break; 187 | } 188 | } 189 | 190 | NPIdentifier id = NULL; 191 | NPVariant val; 192 | VOID_TO_NPVARIANT(val); 193 | 194 | for(indices[dim] = 0; indices[dim] < parray->rgsabound[dim].cElements; indices[dim]++) { 195 | 196 | if (dim == (parray->cDims - 1)) { 197 | // single dimension (or the bottom of the recursion) 198 | if (parray->fFeatures & FADF_VARIANT) { 199 | 200 | VARIANT variant; 201 | VariantInit(&variant); 202 | 203 | if(FAILED(SafeArrayGetElement(parray, (long *)indices, &variant))) { 204 | 205 | rc = false; 206 | break; 207 | } 208 | 209 | Variant2NPVar(&variant, &val, instance); 210 | VariantClear(&variant); 211 | } 212 | else if (parray->fFeatures & FADF_BSTR) { 213 | 214 | BSTR bstr; 215 | 216 | if(FAILED(SafeArrayGetElement(parray, (long *)indices, &bstr))) { 217 | 218 | rc = false; 219 | break; 220 | } 221 | 222 | BSTR2NPVar(bstr, &val, instance); 223 | } 224 | else if (parray->fFeatures & FADF_DISPATCH) { 225 | 226 | IDispatch *disp; 227 | 228 | if(FAILED(SafeArrayGetElement(parray, (long *)indices, &disp))) { 229 | 230 | rc = false; 231 | break; 232 | } 233 | 234 | Dispatch2NPVar(disp, &val, instance); 235 | } 236 | else if (parray->fFeatures & FADF_UNKNOWN) { 237 | 238 | IUnknown *unk; 239 | 240 | if(FAILED(SafeArrayGetElement(parray, (long *)indices, &unk))) { 241 | 242 | rc = false; 243 | break; 244 | } 245 | 246 | Unknown2NPVar(unk, &val, instance); 247 | } 248 | } 249 | else { 250 | // recurse 251 | NPObject *o = SafeArray2NPObject(parray, dim + 1, indices, instance); 252 | if (NULL == o) { 253 | 254 | rc = false; 255 | break; 256 | } 257 | 258 | OBJECT_TO_NPVARIANT(o, val); 259 | } 260 | 261 | id = NPNFuncs.getintidentifier(parray->rgsabound[dim].lLbound + indices[dim]); 262 | 263 | // setproperty will call retainobject or copy the internal string, we should 264 | // release variant 265 | NPNFuncs.setproperty(instance, obj, id, &val); 266 | NPNFuncs.releasevariantvalue(&val); 267 | VOID_TO_NPVARIANT(val); 268 | } 269 | } while (0); 270 | 271 | if (false == rc) { 272 | 273 | if (!pindices && indices) { 274 | 275 | free(indices); 276 | indices = NULL; 277 | 278 | SafeArrayUnlock(parray); 279 | } 280 | 281 | if (obj) { 282 | 283 | NPNFuncs.releaseobject(obj); 284 | obj = NULL; 285 | } 286 | } 287 | 288 | return obj; 289 | } 290 | 291 | #define GETVALUE(var, val) (((var->vt) & VT_BYREF) ? *(var->p##val) : (var->val)) 292 | 293 | void 294 | Variant2NPVar(const VARIANT *var, NPVariant *npvar, NPP instance) 295 | { 296 | NPObject *obj = NULL; 297 | SAFEARRAY *parray = NULL; 298 | 299 | if (!var || !npvar) { 300 | 301 | return; 302 | } 303 | 304 | VOID_TO_NPVARIANT(*npvar); 305 | 306 | switch (var->vt & ~VT_BYREF) { 307 | case VT_EMPTY: 308 | VOID_TO_NPVARIANT((*npvar)); 309 | break; 310 | 311 | case VT_NULL: 312 | NULL_TO_NPVARIANT((*npvar)); 313 | break; 314 | 315 | case VT_LPSTR: 316 | // not sure it can even appear in a VARIANT, but... 317 | STRINGZ_TO_NPVARIANT(var->pcVal, (*npvar)); 318 | break; 319 | 320 | case VT_BSTR: 321 | BSTR2NPVar(GETVALUE(var, bstrVal), npvar, instance); 322 | break; 323 | 324 | case VT_I1: 325 | INT32_TO_NPVARIANT((int32)GETVALUE(var, cVal), (*npvar)); 326 | break; 327 | 328 | case VT_I2: 329 | INT32_TO_NPVARIANT((int32)GETVALUE(var, iVal), (*npvar)); 330 | break; 331 | 332 | case VT_I4: 333 | INT32_TO_NPVARIANT((int32)GETVALUE(var, lVal), (*npvar)); 334 | break; 335 | 336 | case VT_UI1: 337 | INT32_TO_NPVARIANT((int32)GETVALUE(var, bVal), (*npvar)); 338 | break; 339 | 340 | case VT_UI2: 341 | INT32_TO_NPVARIANT((int32)GETVALUE(var, uiVal), (*npvar)); 342 | break; 343 | 344 | case VT_UI4: 345 | INT32_TO_NPVARIANT((int32)GETVALUE(var, ulVal), (*npvar)); 346 | break; 347 | 348 | case VT_BOOL: 349 | BOOLEAN_TO_NPVARIANT((GETVALUE(var, boolVal) == VARIANT_TRUE) ? true : false, (*npvar)); 350 | break; 351 | 352 | case VT_R4: 353 | DOUBLE_TO_NPVARIANT((double)GETVALUE(var, fltVal), (*npvar)); 354 | break; 355 | 356 | case VT_R8: 357 | DOUBLE_TO_NPVARIANT(GETVALUE(var, dblVal), (*npvar)); 358 | break; 359 | 360 | case VT_DISPATCH: 361 | Dispatch2NPVar(GETVALUE(var, pdispVal), npvar, instance); 362 | break; 363 | 364 | case VT_UNKNOWN: 365 | Unknown2NPVar(GETVALUE(var, punkVal), npvar, instance); 366 | break; 367 | 368 | case VT_CY: 369 | DOUBLE_TO_NPVARIANT((double)GETVALUE(var, cyVal).int64 / 10000, (*npvar)); 370 | break; 371 | 372 | case VT_DATE: 373 | BSTR bstrVal; 374 | VarBstrFromDate(GETVALUE(var, date), 0, 0, &bstrVal); 375 | BSTR2NPVar(bstrVal, npvar, instance); 376 | break; 377 | 378 | default: 379 | if (var->vt & VT_ARRAY) { 380 | 381 | obj = SafeArray2NPObject(GETVALUE(var, parray), 0, NULL, instance); 382 | OBJECT_TO_NPVARIANT(obj, (*npvar)); 383 | } 384 | break; 385 | } 386 | } 387 | #undef GETVALUE 388 | 389 | void 390 | NPVar2Variant(const NPVariant *npvar, VARIANT *var, NPP instance) 391 | { 392 | USES_CONVERSION; 393 | 394 | if (!var || !npvar) { 395 | 396 | return; 397 | } 398 | 399 | switch (npvar->type) { 400 | case NPVariantType_Void: 401 | var->vt = VT_VOID; 402 | var->ulVal = 0; 403 | break; 404 | 405 | case NPVariantType_Null: 406 | var->vt = VT_PTR; 407 | var->byref = NULL; 408 | break; 409 | 410 | case NPVariantType_Bool: 411 | var->vt = VT_BOOL; 412 | var->ulVal = npvar->value.boolValue; 413 | break; 414 | 415 | case NPVariantType_Int32: 416 | var->vt = VT_UI4; 417 | var->ulVal = npvar->value.intValue; 418 | break; 419 | 420 | case NPVariantType_Double: 421 | var->vt = VT_R8; 422 | var->dblVal = npvar->value.doubleValue; 423 | break; 424 | 425 | case NPVariantType_String: 426 | var->vt = VT_BSTR; 427 | var->bstrVal = Utf8StringToBstr(npvar->value.stringValue.UTF8Characters, npvar->value.stringValue.UTF8Length); 428 | break; 429 | 430 | case NPVariantType_Object: 431 | NPIdentifier *identifiers = NULL; 432 | uint32_t identifierCount = 0; 433 | NPObject *object = NPVARIANT_TO_OBJECT(*npvar); 434 | 435 | if (NPNFuncs.enumerate(instance, object, &identifiers, &identifierCount)) { 436 | CComSafeArray variants; 437 | 438 | for (uint32_t index = 0; index < identifierCount; ++index) { 439 | NPVariant npVariant; 440 | 441 | if (NPNFuncs.getproperty(instance, object, identifiers[index], &npVariant)) { 442 | 443 | if (npVariant.type != NPVariantType_Object) { 444 | 445 | CComVariant variant; 446 | 447 | NPVar2Variant(&npVariant, &variant, instance); 448 | variants.Add(variant); 449 | } 450 | 451 | NPNFuncs.releasevariantvalue(&npVariant); 452 | } 453 | } 454 | 455 | NPNFuncs.memfree(identifiers); 456 | *reinterpret_cast(var) = variants; 457 | } 458 | else { 459 | 460 | var->vt = VT_VOID; 461 | var->ulVal = 0; 462 | } 463 | break; 464 | } 465 | } 466 | 467 | -------------------------------------------------------------------------------- /ffactivex/variants.h: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is itstructures.com code. 15 | * 16 | * The Initial Developer of the Original Code is IT Structures. 17 | * Portions created by the Initial Developer are Copyright (C) 2008 18 | * the Initial Developer. All Rights Reserved. 19 | * 20 | * Alternatively, the contents of this file may be used under the terms of 21 | * either the GNU General Public License Version 2 or later (the "GPL"), or 22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 23 | * in which case the provisions of the GPL or the LGPL are applicable instead 24 | * of those above. If you wish to allow use of your version of this file only 25 | * under the terms of either the GPL or the LGPL, and not to allow others to 26 | * use your version of this file under the terms of the MPL, indicate your 27 | * decision by deleting the provisions above and replace them with the notice 28 | * and other provisions required by the GPL or the LGPL. If you do not delete 29 | * the provisions above, a recipient may use your version of this file under 30 | * the terms of any one of the MPL, the GPL or the LGPL. 31 | * 32 | * ***** END LICENSE BLOCK ***** */ 33 | 34 | #pragma once 35 | 36 | void Variant2NPVar(const VARIANT *var, NPVariant *npvar, NPP instance); 37 | void NPVar2Variant(const NPVariant *npvar, VARIANT *var, NPP instance); 38 | BSTR Utf8StringToBstr(LPCSTR szStr, int iSize); 39 | 40 | -------------------------------------------------------------------------------- /install/ffactivex.inc: -------------------------------------------------------------------------------- 1 | [Files] 2 | Source: {#xbasepath}\Release\npffax.dll; DestDir: {app}; DestName: npffax.dll; Flags: overwritereadonly restartreplace uninsrestartdelete 3 | 4 | [Registry] 5 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex; Flags: uninsdeletekey 6 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex; ValueType: string; ValueName: Description; ValueData: {#MyAppName} {#xversion} 7 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex; ValueType: string; ValueName: ProductName; ValueData: {#MyAppName} {#xversion} 8 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex; ValueType: string; ValueName: Path; ValueData: {app}\npffax.dll 9 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex; ValueType: string; ValueName: Version; ValueData: {#xversion} 10 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes 11 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes; ValueType: string; ValueName: Dummy; ValueData: {#xversion} 12 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes\application/x-itst-activex 13 | Root: HKLM32; Subkey: SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes\application/x-itst-activex; ValueType: string; ValueName: "Dummy"; ValueData: "{#xversion}" -------------------------------------------------------------------------------- /install/ffactivex.iss: -------------------------------------------------------------------------------- 1 | #ifndef MyAppName 2 | #define MyAppName "Firefox ActiveX Plugin" 3 | #endif 4 | 5 | #ifndef MyAppURL 6 | #define MyAppURL "http://code.google.com/p/ff-activex-host/" 7 | #endif 8 | 9 | #ifndef xversion 10 | #define xversion "r37" 11 | #endif 12 | 13 | #ifndef xbasepath 14 | #define xbasepath "c:\src\ff-activex-host\ff-activex-host\" 15 | #endif 16 | 17 | [Setup] 18 | AppId={{97F2985C-B74A-4672-960E-E3769AE5657A}} 19 | AppName={#MyAppName} 20 | AppVerName={#MyAppName} {#xversion} 21 | AppSupportURL={#MyAppURL} 22 | AppUpdatesURL={#MyAppURL} 23 | DefaultDirName={pf}\{#MyAppName} 24 | DefaultGroupName={#MyAppName} 25 | OutputBaseFilename=ffactivex-setup 26 | Compression=lzma 27 | SolidCompression=yes 28 | InternalCompressLevel=ultra 29 | ArchitecturesInstallIn64BitMode=x64 ia64 30 | 31 | #include "ffactivex.inc" 32 | 33 | [Registry] 34 | Root: HKLM32; Subkey: "SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes\application/x-itst-activex\clsid\*"; ValueType: string; ValueName: "*"; ValueData: true; 35 | Root: HKLM32; Subkey: "SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes\application/x-itst-activex\progid\*"; ValueType: string; ValueName: "*"; ValueData: true; 36 | Root: HKLM32; Subkey: "SOFTWARE\MozillaPlugins\@itstructures.com/ffactivex\MimeTypes\application/x-itst-activex\codeBaseUrl\*"; ValueType: string; ValueName: "*"; ValueData: true; 37 | 38 | [Files] 39 | Source: {#xbasepath}\Release\transver.exe; DestDir: {app}; DestName: npffax.dll; Flags: overwritereadonly restartreplace uninsrestartdelete 40 | 41 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tool/mkinst.cmd: -------------------------------------------------------------------------------- 1 | setlocal 2 | 3 | 4 | cd install 5 | "c:\Program Files\Inno Setup 5\iscc" /O../dist /dxversion=%1 /dxbasepath=../ ffactivex.iss 6 | 7 | cd .. 8 | 9 | copy dist\ffactivex-setup.exe dist\ffactivex-setup-%1.exe 10 | 11 | endlocal 12 | -------------------------------------------------------------------------------- /transver/transver.cpp: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is RSJ Software GmbH code. 15 | * 16 | * The Initial Developer of the Original Code is 17 | * RSJ Software GmbH. 18 | * Portions created by the Initial Developer are Copyright (C) 2009 19 | * the Initial Developer. All Rights Reserved. 20 | * 21 | * Contributors: 22 | * Ruediger Jungbeck 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * either the GNU General Public License Version 2 or later (the "GPL"), or 26 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 27 | * in which case the provisions of the GPL or the LGPL are applicable instead 28 | * of those above. If you wish to allow use of your version of this file only 29 | * under the terms of either the GPL or the LGPL, and not to allow others to 30 | * use your version of this file under the terms of the MPL, indicate your 31 | * decision by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL or the LGPL. If you do not delete 33 | * the provisions above, a recipient may use your version of this file under 34 | * the terms of any one of the MPL, the GPL or the LGPL. 35 | * 36 | * ***** END LICENSE BLOCK ***** */ 37 | 38 | #include 39 | 40 | #include 41 | #include 42 | 43 | // ---------------------------------------------------------------------------- 44 | 45 | int main (int ArgC, 46 | char *ArgV[]) 47 | { 48 | const char *sourceName; 49 | const char *targetName; 50 | HANDLE targetHandle; 51 | void *versionPtr; 52 | DWORD versionLen; 53 | int lastError; 54 | int ret = 0; 55 | 56 | if (ArgC < 3) { 57 | fprintf(stderr, 58 | "Usage: %s \n", 59 | ArgV[0]); 60 | 61 | exit (1); 62 | } 63 | 64 | sourceName = ArgV[1]; 65 | targetName = ArgV[2]; 66 | 67 | if ((versionLen = GetFileVersionInfoSize(sourceName, 68 | NULL)) == 0) { 69 | fprintf(stderr, 70 | "Could not retrieve version len from %s\n", 71 | sourceName); 72 | 73 | exit (2); 74 | } 75 | 76 | if ((versionPtr = calloc(1, 77 | versionLen)) == NULL) { 78 | 79 | fprintf(stderr, 80 | "Error allocating temp memory\n"); 81 | 82 | exit (3); 83 | } 84 | 85 | if (!GetFileVersionInfo(sourceName, 86 | NULL, 87 | versionLen, 88 | versionPtr)) { 89 | 90 | fprintf(stderr, 91 | "Could not retrieve version info from %s\n", 92 | sourceName); 93 | 94 | exit (4); 95 | } 96 | 97 | if ((targetHandle = BeginUpdateResource(targetName, 98 | FALSE)) == INVALID_HANDLE_VALUE) { 99 | 100 | fprintf(stderr, 101 | "Could not begin update of %s\n", 102 | targetName); 103 | 104 | free(versionPtr); 105 | 106 | exit (5); 107 | } 108 | 109 | 110 | if (!UpdateResource(targetHandle, 111 | RT_VERSION, 112 | MAKEINTRESOURCE(VS_VERSION_INFO), 113 | MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 114 | versionPtr, 115 | versionLen)) { 116 | 117 | lastError = GetLastError(); 118 | 119 | fprintf(stderr, 120 | "Error %d updating resource\n", 121 | lastError); 122 | 123 | ret = 6; 124 | } 125 | 126 | if (!EndUpdateResource(targetHandle, 127 | FALSE)) { 128 | fprintf(stderr, 129 | "Error finishing update\n"); 130 | 131 | ret = 7; 132 | } 133 | 134 | free(versionPtr); 135 | 136 | return (ret); 137 | } 138 | 139 | -------------------------------------------------------------------------------- /transver/transver.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 53 | 56 | 60 | 63 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 93 | 101 | 104 | 107 | 110 | 113 | 116 | 128 | 131 | 135 | 138 | 148 | 151 | 154 | 157 | 160 | 163 | 166 | 169 | 170 | 171 | 172 | 173 | 174 | 179 | 182 | 183 | 184 | 189 | 190 | 195 | 196 | 197 | 198 | 199 | 200 | --------------------------------------------------------------------------------