1
// System.cpp: ActionScript "System" class, for Gnash.
3
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 3 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include "movie_root.h" // interface callback
22
#include "System_as.h"
24
#include "smart_ptr.h" // for boost intrusive_ptr
25
#include "Global_as.h"
26
#include "builtin_function.h"
27
#include "NativeFunction.h"
28
#include "VM.h" // for getPlayerVersion()
29
#include "Object.h" // for getObjectInterface
36
// Forward declarations.
39
inline std::string trueFalse(bool x) { return x ? "t" : "f"; }
41
template<typename T> inline void convertValue(const std::string& in,
44
const std::string& systemLanguage(as_object& proto);
46
as_value system_security_allowdomain(const fn_call& fn);
47
as_value system_security_allowinsecuredomain(const fn_call& fn);
48
as_value system_security_loadpolicyfile(const fn_call& fn);
49
as_value system_setClipboard(const fn_call& fn);
50
as_value system_showsettings(const fn_call& fn);
51
as_value system_exactsettings(const fn_call& fn);
52
as_value system_usecodepage(const fn_call& fn);
53
void attachSystemSecurityInterface(as_object& o);
54
void attachSystemCapabilitiesInterface(as_object& o);
55
void attachSystemInterface(as_object& proto);
58
as_value system_gc(const fn_call& fn);
59
as_value system_pause(const fn_call& fn);
60
as_value system_resume(const fn_call& fn);
62
// List of domains that can access/modify local data
63
std::vector<std::string> _allowDataAccess;
68
system_class_init(as_object& where, const ObjectURI& uri)
70
registerBuiltinObject(where, attachSystemInterface, uri);
75
registerSystemNative(as_object& where)
77
VM& vm = getVM(where);
79
vm.registerNative(system_security_allowdomain, 12, 0);
80
vm.registerNative(system_showsettings, 2107, 0);
82
// From http://osflash.org/flashcoders/undocumented/asnative
84
// Run once in startup script then deleted...
85
// System.Capabilities.Query 11, 0
87
// System.Product.isRunning 2201, 0
88
// System.Product.isInstalled 2201, 1
89
// System.Product.launch 2201, 2
90
// System.Product.download 2201, 3
94
/// Get the current System.security allowDataAccess list of domains allowed to
95
/// access/modify local data
97
/// @return a std::vector of strings containing urls that can access local data
98
const std::vector<std::string>&
101
return _allowDataAccess;
105
/// Adds a string containing url or ip info to the allowDataAccess list of
106
/// domains that can access/modify local data
108
/// @param url a std::string containing the domain name
110
addAllowDataAccess( const std::string& url )
112
size_t s = _allowDataAccess.size();
113
_allowDataAccess.push_back( url );
115
if( s+1 == _allowDataAccess.size()) return true;
124
attachSystemSecurityInterface(as_object& o)
127
o.init_member("allowDomain", vm.getNative(12, 0));
129
Global_as* gl = getGlobal(o);
130
// TODO: only available when SWF >= 7
131
o.init_member("allowInsecureDomain",
132
gl->createFunction(system_security_allowinsecuredomain));
133
o.init_member("loadPolicyFile",
134
gl->createFunction(system_security_loadpolicyfile));
138
attachSystemCapabilitiesInterface(as_object& o)
140
RcInitFile& rcfile = RcInitFile::getDefaultInstance();
143
// Filesystem, access, miscellaneous hardware information
146
// "Windows XP", "Windows 2000", "Windows NT", "Windows 98/ME",
147
// "Windows 95", "Windows CE", "Linux", "MacOS"
148
// Override in gnashrc
151
const std::string os = vm.getOSName();
153
const std::string language = systemLanguage(o);
155
// FIXME: these need to be implemented properly
156
// Does the NetStream object natively support SSL?
157
const bool hasTLS = true;
159
// Microphone and camera access disabled
160
const bool avHardwareDisable = false;
162
// Not sure: seems to be whether the movie can 'float' above web pages,
163
// and is useful for disabling certain annoying adverts.
164
const bool windowlessDisable = false;
166
const bool hasPrinting = true;
167
const bool hasAccessibility = true;
168
const bool isDebugger = false;
169
const bool localFileReadDisable = false;
172
// Display information (needs active GUI)
175
const movie_root& m = vm.getRoot();
177
int screenResolutionX;
178
convertValue(m.callInterface("System.capabilities.screenResolutionX"),
180
int screenResolutionY;
181
convertValue(m.callInterface("System.capabilities.screenResolutionY"),
184
convertValue(m.callInterface("System.capabilities.screenDPI"), screenDPI);
186
// Documented to be a number, but is in fact a string.
187
const std::string pixelAspectRatio =
188
m.callInterface("System.capabilities.pixelAspectRatio");
190
// "StandAlone", "External", "PlugIn", "ActiveX" (get from GUI)
191
const std::string playerType =
192
m.callInterface("System.capabilities.playerType");
194
const std::string screenColor =
195
m.callInterface("System.capabilities.screenColor");
201
// Is audio available?
202
const bool hasAudio = (vm.getRoot().runResources().soundHandler());
204
// FIXME: these need to be implemented properly. They are mostly
206
const bool hasAudioEncoder = true;
207
const bool hasEmbeddedVideo = true;
208
const bool hasIME = true;
209
const bool hasMP3 = true;
210
const bool hasScreenBroadcast = true;
211
const bool hasScreenPlayback = true;
212
const bool hasStreamingAudio = true;
213
const bool hasStreamingVideo = true;
214
const bool hasVideoEncoder = true;
220
// "LNX 9,0,22,0", "MAC 8,0,99,0"
221
// Override in gnashrc
222
const std::string version = vm.getPlayerVersion();
224
// "Macromedia Windows", "Macromedia Linux", "Macromedia MacOS"
225
// Override in gnashrc
226
const std::string manufacturer = rcfile.getFlashSystemManufacturer();
229
// A URL-encoded string to send system info to a server.
230
// Boolean values are represented as t or f.
231
// Privacy concerns should probably be addressed by
232
// allowing this string to be sent or not; individual
233
// values that might affect privacy can be overridden
236
// hasIME seems not to be included in the server string, though
237
// it is documented to have a server string of IME.
238
// Linux player version 9 has no hasIME property (but no need
241
// TLS and hasTLS are documented for AS3, player version 9.
243
// WD is included in the server string for player version 9,
244
// but not documented. It corresponds to the equally undocumented
245
// windowlessDisable.
247
// This should be the standard order of parameters in the server
249
std::ostringstream serverString;
250
serverString << "A=" << trueFalse(hasAudio)
251
<< "&SA=" << trueFalse(hasStreamingAudio)
252
<< "&SV=" << trueFalse(hasStreamingVideo)
253
<< "&EV=" << trueFalse(hasEmbeddedVideo)
254
<< "&MP3=" << trueFalse(hasMP3)
255
<< "&AE=" << trueFalse(hasAudioEncoder)
256
<< "&VE=" << trueFalse(hasVideoEncoder)
257
<< "&ACC=" << trueFalse(hasAccessibility)
258
<< "&PR=" << trueFalse(hasPrinting)
259
<< "&SP=" << trueFalse(hasScreenPlayback)
260
<< "&SB=" << trueFalse(hasScreenBroadcast)
261
<< "&DEB=" << trueFalse(isDebugger)
262
<< "&V=" << URL::encode(version)
263
<< "&M=" << URL::encode(manufacturer)
264
<< "&R=" << screenResolutionX << "x" << screenResolutionY
265
<< "&DP=" << screenDPI
266
<< "&COL=" << screenColor
267
<< "&AR=" << pixelAspectRatio
268
<< "&OS=" << URL::encode(os)
270
<< "&PT=" << playerType
271
<< "&AVD=" << trueFalse(avHardwareDisable)
272
<< "&LFD=" << trueFalse(localFileReadDisable)
273
<< "&WD=" << trueFalse(windowlessDisable)
274
<< "&TLS=" << trueFalse(hasTLS);
276
const int flags = PropFlags::dontDelete
277
| PropFlags::dontEnum
278
| PropFlags::readOnly;
280
o.init_member("version", version, flags);
281
o.init_member("playerType", playerType, flags);
282
o.init_member("os", os, flags);
283
o.init_member("manufacturer", manufacturer, flags);
284
o.init_member("language", language, flags);
285
o.init_member("hasAudio", hasAudio, flags);
286
o.init_member("screenResolutionX", screenResolutionX, flags);
287
o.init_member("screenResolutionY", screenResolutionY, flags);
288
o.init_member("screenColor", screenColor, flags);
289
o.init_member("screenDPI", screenDPI, flags);
290
o.init_member("pixelAspectRatio", pixelAspectRatio, flags);
291
o.init_member("serverString", serverString.str(), flags);
292
o.init_member("avHardwareDisable", avHardwareDisable, flags);
293
o.init_member("hasAudioEncoder", hasAudioEncoder, flags);
294
o.init_member("hasEmbeddedVideo", hasEmbeddedVideo, flags);
295
o.init_member("hasIME", hasIME, flags);
296
o.init_member("hasMP3", hasMP3, flags);
297
o.init_member("hasPrinting", hasPrinting, flags);
298
o.init_member("hasScreenBroadcast", hasScreenBroadcast, flags);
299
o.init_member("hasScreenPlayback", hasScreenPlayback, flags);
300
o.init_member("hasStreamingAudio", hasStreamingAudio, flags);
301
o.init_member("hasStreamingVideo", hasStreamingVideo, flags);
302
o.init_member("hasVideoEncoder", hasVideoEncoder, flags);
303
o.init_member("hasAccessibility", hasAccessibility, flags);
304
o.init_member("isDebugger", isDebugger, flags);
305
o.init_member("localFileReadDisable", localFileReadDisable, flags);
306
o.init_member("hasTLS", hasTLS, flags);
307
o.init_member("windowlessDisable", windowlessDisable, flags);
310
/// Convert a string to the type passed in, making sure the target variable
314
convertValue(const std::string& in, T& val)
316
std::istringstream is(in);
317
if (!(is >> val)) val = T();
321
attachSystemInterface(as_object& proto)
323
Global_as* gl = getGlobal(proto);
325
string_table& st = getStringTable(proto);
326
registerBuiltinObject(proto, attachSystemSecurityInterface,
327
ObjectURI(st.find("security"), 0));
328
registerBuiltinObject(proto, attachSystemCapabilitiesInterface,
329
ObjectURI(st.find("capabilities"), 0));
331
proto.init_member("setClipboard",
332
gl->createFunction(system_setClipboard));
334
VM& vm = getVM(proto);
335
proto.init_member("showSettings", vm.getNative(2107, 0));
336
proto.init_property("useCodepage", &system_usecodepage,
337
&system_usecodepage);
339
const int flags = PropFlags::dontDelete
340
| PropFlags::dontEnum
341
| PropFlags::readOnly
342
| PropFlags::onlySWF6Up;
344
proto.init_property("exactSettings", &system_exactsettings,
345
&system_exactsettings, flags);
349
// This function returns false if no arguments were passed, true if any
350
// arguments were passed at all, even if they are not strings. There is
351
// currently no known way of accessing the list of allowed domains.
353
system_security_allowdomain(const fn_call& fn)
355
// NOTE: This is the AS2 version of allowDomain, the AS3 version is located
356
// in Security_as.cpp
358
IF_VERBOSE_ASCODING_ERRORS(
359
log_aserror("System.security.allowDomain requires at least one "
362
return as_value(false);
365
LOG_ONCE(log_unimpl ("System.security.allowDomain currently stores "
366
"domains but does nothing else."));
367
for (unsigned int i = 0; i < fn.nargs; ++i) {
368
addAllowDataAccess(fn.arg(i).to_string());
370
return as_value(true);
375
system_security_allowinsecuredomain(const fn_call& /*fn*/)
377
LOG_ONCE(log_unimpl ("System.security.allowInsecureDomain") );
383
system_security_loadpolicyfile(const fn_call& /*fn*/)
385
LOG_ONCE(log_unimpl ("System.security.loadPolicyFile") );
390
system_setClipboard(const fn_call& /*fn*/)
392
LOG_ONCE(log_unimpl ("System.setClipboard") );
397
system_showsettings(const fn_call& /*fn*/)
399
LOG_ONCE(log_unimpl ("System.showSettings") );
404
system_gc(const fn_call& /*fn*/)
406
log_unimpl (__FUNCTION__);
411
system_pause(const fn_call& /*fn*/)
413
log_unimpl (__FUNCTION__);
418
system_resume(const fn_call& /*fn*/)
420
log_unimpl (__FUNCTION__);
425
// FIXME: should return true if shared object files
426
// are stored under an exact domain name (www.gnashdev.org or
427
// gnashdev.org); false if both are stored under gnashdev.org.
430
system_exactsettings(const fn_call& fn)
432
boost::intrusive_ptr<as_object> obj = ensureType<as_object>(fn.this_ptr);
437
// Is always true until we implement it.
438
return as_value(true);
444
LOG_ONCE(log_unimpl ("System.exactSettings") );
450
// FIXME: if true, SWF6+ should treat DisplayObjects as Latin
451
// charset variants. If false (default), as UtrueFalse-8.
454
system_usecodepage(const fn_call& fn)
456
boost::intrusive_ptr<as_object> obj =
457
ensureType<as_object>(fn.this_ptr);
462
// Is always false until we implement it.
463
return as_value(false);
469
LOG_ONCE(log_unimpl ("System.useCodepage") );
477
systemLanguage(as_object& proto)
479
// Two-letter language code ('en', 'de') corresponding to ISO 639-1
480
// Chinese can be either zh-CN or zh-TW. English used to have a
481
// country (GB, US) qualifier, but that was dropped in version 7 of
483
// This method relies on getting a POSIX-style language code of the form
484
// "zh_TW.utf8", "zh_CN" or "it" from the VM.
485
// It is obviously very easy to extend support to all language codes, but
486
// some scripts rely on there being only 20 possible languages. It could
487
// be a run time option if it's important enough to care.
489
static std::string lang = getVM(proto).getSystemLanguage();
491
const char* languages[] = {"en", "fr", "ko", "ja", "sv",
492
"de", "es", "it", "zh", "pt",
493
"pl", "hu", "cs", "tr", "fi",
494
"da", "nl", "no", "ru"};
496
const unsigned int size = sizeof (languages) / sizeof (*languages);
498
if (std::find(languages, languages + size, lang.substr(0,2)) != languages + size)
500
if (lang.substr(0,2) == "zh")
502
// Chinese is the only language since the pp version 7
503
// to need an additional qualifier.
504
if (lang.substr(2, 3) == "_TW") lang = "zh-TW";
505
else if (lang.substr(2, 3) == "_CN") lang = "zh-CN";
510
// All other matching cases: retain just the first
511
// two DisplayObjects.
517
// Unknown language. We also return this if
518
// getSystemLanguage() returns something unexpected.
526
} // anonymous namespace