[VBSCRIPT]

* Import from Wine 1.5.26.

svn path=/trunk/; revision=59017
This commit is contained in:
Amine Khaldi 2013-05-15 17:33:01 +00:00
parent 5e4681d91e
commit ae89b1ca95
31 changed files with 20395 additions and 0 deletions

View file

@ -207,6 +207,7 @@ add_subdirectory(urlmon)
add_subdirectory(userenv)
add_subdirectory(usp10)
add_subdirectory(uxtheme)
add_subdirectory(vbscript)
add_subdirectory(vdmdbg)
add_subdirectory(version)
if(ARCH STREQUAL "i386")

View file

@ -0,0 +1,40 @@
add_definitions(-D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
spec2def(vbscript.dll vbscript.spec)
list(APPEND SOURCE
compile.c
error.c
global.c
interp.c
lex.c
parser.tab.c
regexp.c
vbdisp.c
vbregexp.c
vbscript.c
vbscript_main.c
${CMAKE_CURRENT_BINARY_DIR}/vbscript.def)
add_library(vbscript SHARED ${SOURCE} vbscript.rc)
add_idl_headers(vbscript_idlheader vbscript_classes.idl vbsglobal.idl vbsregexp55.idl)
add_typelib(vbsglobal.idl vbsregexp10.idl vbsregexp55.idl)
list(APPEND vbscript_rc_deps
${CMAKE_CURRENT_SOURCE_DIR}/vbscript_classes.rgs
${CMAKE_CURRENT_SOURCE_DIR}/vbsglobal.rgs
${CMAKE_CURRENT_SOURCE_DIR}/vbsregexp10.rgs
${CMAKE_CURRENT_SOURCE_DIR}/vbsregexp55.rgs
${CMAKE_CURRENT_BINARY_DIR}/vbsglobal.tlb
${CMAKE_CURRENT_BINARY_DIR}/vbsregexp10.tlb
${CMAKE_CURRENT_BINARY_DIR}/vbsregexp55.tlb)
set_source_files_properties(vbscript.rc PROPERTIES OBJECT_DEPENDS "${vbscript_rc_deps}")
add_dependencies(vbscript vbscript_idlheader stdole2)
set_module_type(vbscript win32dll)
target_link_libraries(vbscript wine)
add_importlibs(vbscript oleaut32 ole32 user32 msvcrt kernel32 ntdll)
add_cd_file(TARGET vbscript DESTINATION reactos/system32 FOR all)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "vbscript.h"
#include "vbscript_defs.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
static HRESULT Err_Description(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Err_HelpContext(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Err_HelpFile(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Err_Number(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Err_Source(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Err_Clear(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Err_Raise(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
FIXME("\n");
return E_NOTIMPL;
}
static const builtin_prop_t err_props[] = {
{DISPID_ERR_DESCRIPTION, Err_Description, BP_GETPUT},
{DISPID_ERR_HELPCONTEXT, Err_HelpContext, BP_GETPUT},
{DISPID_ERR_HELPFILE, Err_HelpFile, BP_GETPUT},
{DISPID_ERR_NUMBER, Err_Number, BP_GETPUT},
{DISPID_ERR_SOURCE, Err_Source, BP_GETPUT},
{DISPID_ERR_CLEAR, Err_Clear},
{DISPID_ERR_RAISE, Err_Raise, 0, 5},
};
HRESULT init_err(script_ctx_t *ctx)
{
HRESULT hres;
ctx->err_desc.ctx = ctx;
ctx->err_desc.builtin_prop_cnt = sizeof(err_props)/sizeof(*err_props);
ctx->err_desc.builtin_props = err_props;
hres = get_typeinfo(ErrObj_tid, &ctx->err_desc.typeinfo);
if(FAILED(hres))
return hres;
return create_vbdisp(&ctx->err_desc, &ctx->err_obj);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,444 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
//#include <assert.h>
#include "vbscript.h"
#include "parse.h"
#include "parser.tab.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
static const WCHAR andW[] = {'a','n','d',0};
static const WCHAR byrefW[] = {'b','y','r','e','f',0};
static const WCHAR byvalW[] = {'b','y','v','a','l',0};
static const WCHAR callW[] = {'c','a','l','l',0};
static const WCHAR caseW[] = {'c','a','s','e',0};
static const WCHAR classW[] = {'c','l','a','s','s',0};
static const WCHAR constW[] = {'c','o','n','s','t',0};
static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
static const WCHAR dimW[] = {'d','i','m',0};
static const WCHAR doW[] = {'d','o',0};
static const WCHAR eachW[] = {'e','a','c','h',0};
static const WCHAR elseW[] = {'e','l','s','e',0};
static const WCHAR elseifW[] = {'e','l','s','e','i','f',0};
static const WCHAR emptyW[] = {'e','m','p','t','y',0};
static const WCHAR endW[] = {'e','n','d',0};
static const WCHAR eqvW[] = {'e','q','v',0};
static const WCHAR errorW[] = {'e','r','r','o','r',0};
static const WCHAR exitW[] = {'e','x','i','t',0};
static const WCHAR explicitW[] = {'e','x','p','l','i','c','i','t',0};
static const WCHAR falseW[] = {'f','a','l','s','e',0};
static const WCHAR forW[] = {'f','o','r',0};
static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
static const WCHAR getW[] = {'g','e','t',0};
static const WCHAR gotoW[] = {'g','o','t','o',0};
static const WCHAR ifW[] = {'i','f',0};
static const WCHAR impW[] = {'i','m','p',0};
static const WCHAR inW[] = {'i','n',0};
static const WCHAR isW[] = {'i','s',0};
static const WCHAR letW[] = {'l','e','t',0};
static const WCHAR loopW[] = {'l','o','o','p',0};
static const WCHAR meW[] = {'m','e',0};
static const WCHAR modW[] = {'m','o','d',0};
static const WCHAR newW[] = {'n','e','w',0};
static const WCHAR nextW[] = {'n','e','x','t',0};
static const WCHAR notW[] = {'n','o','t',0};
static const WCHAR nothingW[] = {'n','o','t','h','i','n','g',0};
static const WCHAR nullW[] = {'n','u','l','l',0};
static const WCHAR onW[] = {'o','n',0};
static const WCHAR optionW[] = {'o','p','t','i','o','n',0};
static const WCHAR orW[] = {'o','r',0};
static const WCHAR privateW[] = {'p','r','i','v','a','t','e',0};
static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
static const WCHAR publicW[] = {'p','u','b','l','i','c',0};
static const WCHAR remW[] = {'r','e','m',0};
static const WCHAR resumeW[] = {'r','e','s','u','m','e',0};
static const WCHAR selectW[] = {'s','e','l','e','c','t',0};
static const WCHAR setW[] = {'s','e','t',0};
static const WCHAR stepW[] = {'s','t','e','p',0};
static const WCHAR stopW[] = {'s','t','o','p',0};
static const WCHAR subW[] = {'s','u','b',0};
static const WCHAR thenW[] = {'t','h','e','n',0};
static const WCHAR toW[] = {'t','o',0};
static const WCHAR trueW[] = {'t','r','u','e',0};
static const WCHAR untilW[] = {'u','n','t','i','l',0};
static const WCHAR wendW[] = {'w','e','n','d',0};
static const WCHAR whileW[] = {'w','h','i','l','e',0};
static const WCHAR xorW[] = {'x','o','r',0};
static const struct {
const WCHAR *word;
int token;
} keywords[] = {
{andW, tAND},
{byrefW, tBYREF},
{byvalW, tBYVAL},
{callW, tCALL},
{caseW, tCASE},
{classW, tCLASS},
{constW, tCONST},
{defaultW, tDEFAULT},
{dimW, tDIM},
{doW, tDO},
{eachW, tEACH},
{elseW, tELSE},
{elseifW, tELSEIF},
{emptyW, tEMPTY},
{endW, tEND},
{eqvW, tEQV},
{errorW, tERROR},
{exitW, tEXIT},
{explicitW, tEXPLICIT},
{falseW, tFALSE},
{forW, tFOR},
{functionW, tFUNCTION},
{getW, tGET},
{gotoW, tGOTO},
{ifW, tIF},
{impW, tIMP},
{inW, tIN},
{isW, tIS},
{letW, tLET},
{loopW, tLOOP},
{meW, tME},
{modW, tMOD},
{newW, tNEW},
{nextW, tNEXT},
{notW, tNOT},
{nothingW, tNOTHING},
{nullW, tNULL},
{onW, tON},
{optionW, tOPTION},
{orW, tOR},
{privateW, tPRIVATE},
{propertyW, tPROPERTY},
{publicW, tPUBLIC},
{remW, tREM},
{resumeW, tRESUME},
{selectW, tSELECT},
{setW, tSET},
{stepW, tSTEP},
{stopW, tSTOP},
{subW, tSUB},
{thenW, tTHEN},
{toW, tTO},
{trueW, tTRUE},
{untilW, tUNTIL},
{wendW, tWEND},
{whileW, tWHILE},
{xorW, tXOR}
};
static inline BOOL is_identifier_char(WCHAR c)
{
return isalnumW(c) || c == '_';
}
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word)
{
const WCHAR *p1 = ctx->ptr;
const WCHAR *p2 = word;
WCHAR c;
while(p1 < ctx->end && *p2) {
c = tolowerW(*p1);
if(c != *p2)
return c - *p2;
p1++;
p2++;
}
if(*p2 || (p1 < ctx->end && is_identifier_char(*p1)))
return 1;
ctx->ptr = p1;
return 0;
}
static int check_keywords(parser_ctx_t *ctx)
{
int min = 0, max = sizeof(keywords)/sizeof(keywords[0])-1, r, i;
while(min <= max) {
i = (min+max)/2;
r = check_keyword(ctx, keywords[i].word);
if(!r)
return keywords[i].token;
if(r > 0)
min = i+1;
else
max = i-1;
}
return 0;
}
static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
{
const WCHAR *ptr = ctx->ptr++;
WCHAR *str;
int len;
while(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr))
ctx->ptr++;
len = ctx->ptr-ptr;
str = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
if(!str)
return 0;
memcpy(str, ptr, (len+1)*sizeof(WCHAR));
str[len] = 0;
*ret = str;
return tIdentifier;
}
static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret)
{
const WCHAR *ptr = ++ctx->ptr;
WCHAR *rptr;
int len = 0;
while(ctx->ptr < ctx->end) {
if(*ctx->ptr == '\n') {
FIXME("newline inside string literal\n");
return 0;
}
if(*ctx->ptr == '"') {
if(ctx->ptr[1] != '"')
break;
len--;
ctx->ptr++;
}
ctx->ptr++;
}
if(ctx->ptr == ctx->end) {
FIXME("unterminated string literal\n");
return 0;
}
len += ctx->ptr-ptr;
*ret = rptr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
if(!rptr)
return 0;
while(ptr < ctx->ptr) {
if(*ptr == '"')
ptr++;
*rptr++ = *ptr++;
}
*rptr = 0;
ctx->ptr++;
return tString;
}
static int parse_numeric_literal(parser_ctx_t *ctx, void **ret)
{
double n = 0;
if(*ctx->ptr == '0' && !('0' <= ctx->ptr[1] && ctx->ptr[1] <= '9') && ctx->ptr[1] != '.')
return *ctx->ptr++;
do {
n = n*10 + *ctx->ptr++ - '0';
}while('0' <= *ctx->ptr && *ctx->ptr <= '9');
if(*ctx->ptr != '.') {
if((LONG)n == n) {
LONG l = n;
*(LONG*)ret = l;
return (short)l == l ? tShort : tLong;
}
}else {
double e = 1.0;
while('0' <= *++ctx->ptr && *ctx->ptr <= '9')
n += (e /= 10.0)*(*ctx->ptr-'0');
}
*(double*)ret = n;
return tDouble;
}
static int hex_to_int(WCHAR c)
{
if('0' <= c && c <= '9')
return c-'0';
if('a' <= c && c <= 'f')
return c+10-'a';
if('A' <= c && c <= 'F')
return c+10-'A';
return -1;
}
static int parse_hex_literal(parser_ctx_t *ctx, LONG *ret)
{
const WCHAR *begin = ctx->ptr;
LONG l = 0, d;
while((d = hex_to_int(*++ctx->ptr)) != -1)
l = l*16 + d;
if(begin + 9 /* max digits+1 */ < ctx->ptr || (*ctx->ptr != '&' && is_identifier_char(*ctx->ptr))) {
FIXME("invalid literal\n");
return 0;
}
if(*ctx->ptr == '&')
ctx->ptr++;
*ret = l;
return (short)l == l ? tShort : tLong;
}
static void skip_spaces(parser_ctx_t *ctx)
{
while(*ctx->ptr == ' ' || *ctx->ptr == '\t' || *ctx->ptr == '\r')
ctx->ptr++;
}
static int comment_line(parser_ctx_t *ctx)
{
ctx->ptr = strchrW(ctx->ptr, '\n');
if(ctx->ptr)
ctx->ptr++;
else
ctx->ptr = ctx->end;
return tNL;
}
static int parse_next_token(void *lval, parser_ctx_t *ctx)
{
WCHAR c;
skip_spaces(ctx);
if(ctx->ptr == ctx->end)
return ctx->last_token == tNL ? tEOF : tNL;
c = *ctx->ptr;
if('0' <= c && c <= '9')
return parse_numeric_literal(ctx, lval);
if(isalphaW(c)) {
int ret = check_keywords(ctx);
if(!ret)
return parse_identifier(ctx, lval);
if(ret != tREM)
return ret;
c = '\'';
}
switch(c) {
case '\n':
ctx->ptr++;
return tNL;
case '\'':
return comment_line(ctx);
case ':':
case ')':
case ',':
case '=':
case '+':
case '*':
case '/':
case '^':
case '\\':
case '.':
case '_':
return *ctx->ptr++;
case '-':
if(ctx->is_html && ctx->ptr[1] == '-' && ctx->ptr[2] == '>')
return comment_line(ctx);
ctx->ptr++;
return '-';
case '(':
/* NOTE:
* We resolve empty brackets in lexer instead of parser to avoid complex conflicts
* in call statement special case |f()| without 'call' keyword
*/
ctx->ptr++;
skip_spaces(ctx);
if(*ctx->ptr == ')') {
ctx->ptr++;
return tEMPTYBRACKETS;
}
return '(';
case '"':
return parse_string_literal(ctx, lval);
case '&':
if(*++ctx->ptr == 'h' || *ctx->ptr == 'H')
return parse_hex_literal(ctx, lval);
return '&';
case '<':
switch(*++ctx->ptr) {
case '>':
ctx->ptr++;
return tNEQ;
case '=':
ctx->ptr++;
return tLTEQ;
case '!':
if(ctx->is_html && ctx->ptr[1] == '-' && ctx->ptr[2] == '-')
return comment_line(ctx);
}
return '<';
case '>':
if(*++ctx->ptr == '=') {
ctx->ptr++;
return tGTEQ;
}
return '>';
default:
FIXME("Unhandled char %c in %s\n", *ctx->ptr, debugstr_w(ctx->ptr));
}
return 0;
}
int parser_lex(void *lval, parser_ctx_t *ctx)
{
int ret;
while(1) {
ret = parse_next_token(lval, ctx);
if(ret == '_') {
skip_spaces(ctx);
if(*ctx->ptr != '\n') {
FIXME("'_' not followed by newline\n");
return 0;
}
ctx->ptr++;
continue;
}
if(ret != tNL || ctx->last_token != tNL)
break;
ctx->last_nl = ctx->ptr-ctx->code;
}
return (ctx->last_token = ret);
}

View file

@ -0,0 +1,272 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
typedef enum {
EXPR_ADD,
EXPR_AND,
EXPR_BOOL,
EXPR_BRACKETS,
EXPR_CONCAT,
EXPR_DIV,
EXPR_DOUBLE,
EXPR_EMPTY,
EXPR_EQUAL,
EXPR_EQV,
EXPR_EXP,
EXPR_GT,
EXPR_GTEQ,
EXPR_IDIV,
EXPR_IMP,
EXPR_IS,
EXPR_LT,
EXPR_LTEQ,
EXPR_ME,
EXPR_MEMBER,
EXPR_MOD,
EXPR_MUL,
EXPR_NEG,
EXPR_NEQUAL,
EXPR_NEW,
EXPR_NOT,
EXPR_NOTHING,
EXPR_NULL,
EXPR_OR,
EXPR_STRING,
EXPR_SUB,
EXPR_ULONG,
EXPR_USHORT,
EXPR_XOR
} expression_type_t;
typedef struct _expression_t {
expression_type_t type;
struct _expression_t *next;
} expression_t;
typedef struct {
expression_t expr;
VARIANT_BOOL value;
} bool_expression_t;
typedef struct {
expression_t expr;
LONG value;
} int_expression_t;
typedef struct {
expression_t expr;
double value;
} double_expression_t;
typedef struct {
expression_t expr;
const WCHAR *value;
} string_expression_t;
typedef struct {
expression_t expr;
expression_t *subexpr;
} unary_expression_t;
typedef struct {
expression_t expr;
expression_t *left;
expression_t *right;
} binary_expression_t;
typedef struct {
expression_t expr;
expression_t *obj_expr;
const WCHAR *identifier;
expression_t *args;
} member_expression_t;
typedef enum {
STAT_ASSIGN,
STAT_CALL,
STAT_CONST,
STAT_DIM,
STAT_DOUNTIL,
STAT_DOWHILE,
STAT_EXITDO,
STAT_EXITFOR,
STAT_EXITFUNC,
STAT_EXITPROP,
STAT_EXITSUB,
STAT_FOREACH,
STAT_FORTO,
STAT_FUNC,
STAT_IF,
STAT_ONERROR,
STAT_SELECT,
STAT_SET,
STAT_STOP,
STAT_UNTIL,
STAT_WHILE,
STAT_WHILELOOP
} statement_type_t;
typedef struct _statement_t {
statement_type_t type;
struct _statement_t *next;
} statement_t;
typedef struct {
statement_t stat;
member_expression_t *expr;
BOOL is_strict;
} call_statement_t;
typedef struct {
statement_t stat;
member_expression_t *member_expr;
expression_t *value_expr;
} assign_statement_t;
typedef struct _dim_decl_t {
const WCHAR *name;
struct _dim_decl_t *next;
} dim_decl_t;
typedef struct _dim_statement_t {
statement_t stat;
dim_decl_t *dim_decls;
} dim_statement_t;
typedef struct _arg_decl_t {
const WCHAR *name;
BOOL by_ref;
struct _arg_decl_t *next;
} arg_decl_t;
typedef struct _function_decl_t {
const WCHAR *name;
function_type_t type;
BOOL is_public;
arg_decl_t *args;
statement_t *body;
struct _function_decl_t *next;
struct _function_decl_t *next_prop_func;
} function_decl_t;
typedef struct {
statement_t stat;
function_decl_t *func_decl;
} function_statement_t;
typedef struct _class_prop_decl_t {
BOOL is_public;
const WCHAR *name;
struct _class_prop_decl_t *next;
} class_prop_decl_t;
typedef struct _class_decl_t {
const WCHAR *name;
function_decl_t *funcs;
class_prop_decl_t *props;
struct _class_decl_t *next;
} class_decl_t;
typedef struct _elseif_decl_t {
expression_t *expr;
statement_t *stat;
struct _elseif_decl_t *next;
} elseif_decl_t;
typedef struct {
statement_t stat;
expression_t *expr;
statement_t *if_stat;
elseif_decl_t *elseifs;
statement_t *else_stat;
} if_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;
statement_t *body;
} while_statement_t;
typedef struct {
statement_t stat;
const WCHAR *identifier;
expression_t *from_expr;
expression_t *to_expr;
expression_t *step_expr;
statement_t *body;
} forto_statement_t;
typedef struct {
statement_t stat;
const WCHAR *identifier;
expression_t *group_expr;
statement_t *body;
} foreach_statement_t;
typedef struct {
statement_t stat;
BOOL resume_next;
} onerror_statement_t;
typedef struct _const_decl_t {
const WCHAR *name;
expression_t *value_expr;
struct _const_decl_t *next;
} const_decl_t;
typedef struct {
statement_t stat;
const_decl_t *decls;
} const_statement_t;
typedef struct _case_clausule_t {
expression_t *expr;
statement_t *stat;
struct _case_clausule_t *next;
} case_clausule_t;
typedef struct {
statement_t stat;
expression_t *expr;
case_clausule_t *case_clausules;
} select_statement_t;
typedef struct {
const WCHAR *code;
const WCHAR *ptr;
const WCHAR *end;
BOOL option_explicit;
BOOL parse_complete;
BOOL is_html;
HRESULT hres;
int last_token;
unsigned last_nl;
statement_t *stats;
statement_t *stats_tail;
class_decl_t *class_decls;
heap_pool_t heap;
} parser_ctx_t;
HRESULT parse_script(parser_ctx_t*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN;
int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN;
void *parser_alloc(parser_ctx_t*,size_t) DECLSPEC_HIDDEN;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,150 @@
/* A Bison parser, made by GNU Bison 2.4.1. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
tEOF = 258,
tNL = 259,
tREM = 260,
tEMPTYBRACKETS = 261,
tTRUE = 262,
tFALSE = 263,
tNOT = 264,
tAND = 265,
tOR = 266,
tXOR = 267,
tEQV = 268,
tIMP = 269,
tNEQ = 270,
tIS = 271,
tLTEQ = 272,
tGTEQ = 273,
tMOD = 274,
tCALL = 275,
tDIM = 276,
tSUB = 277,
tFUNCTION = 278,
tPROPERTY = 279,
tGET = 280,
tLET = 281,
tCONST = 282,
tIF = 283,
tELSE = 284,
tELSEIF = 285,
tEND = 286,
tTHEN = 287,
tEXIT = 288,
tWHILE = 289,
tWEND = 290,
tDO = 291,
tLOOP = 292,
tUNTIL = 293,
tFOR = 294,
tTO = 295,
tSTEP = 296,
tEACH = 297,
tIN = 298,
tSELECT = 299,
tCASE = 300,
tBYREF = 301,
tBYVAL = 302,
tOPTION = 303,
tEXPLICIT = 304,
tSTOP = 305,
tNOTHING = 306,
tEMPTY = 307,
tNULL = 308,
tCLASS = 309,
tSET = 310,
tNEW = 311,
tPUBLIC = 312,
tPRIVATE = 313,
tDEFAULT = 314,
tME = 315,
tERROR = 316,
tNEXT = 317,
tON = 318,
tRESUME = 319,
tGOTO = 320,
tIdentifier = 321,
tString = 322,
tLong = 323,
tShort = 324,
tDouble = 325
};
#endif
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 1676 of yacc.c */
#line 88 "parser.y"
const WCHAR *string;
statement_t *statement;
expression_t *expression;
member_expression_t *member;
elseif_decl_t *elseif;
dim_decl_t *dim_decl;
function_decl_t *func_decl;
arg_decl_t *arg_decl;
class_decl_t *class_decl;
const_decl_t *const_decl;
case_clausule_t *case_clausule;
unsigned uint;
LONG lng;
BOOL bool;
double dbl;
/* Line 1676 of yacc.c */
#line 142 "parser.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif

View file

@ -0,0 +1,965 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
%{
#include "vbscript.h"
#include "parse.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
#define YYLEX_PARAM ctx
#define YYPARSE_PARAM ctx
static int parser_error(const char*);
static void parse_complete(parser_ctx_t*,BOOL);
static void source_add_statement(parser_ctx_t*,statement_t*);
static void source_add_class(parser_ctx_t*,class_decl_t*);
static void *new_expression(parser_ctx_t*,expression_type_t,size_t);
static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
static expression_t *new_string_expression(parser_ctx_t*,const WCHAR*);
static expression_t *new_long_expression(parser_ctx_t*,expression_type_t,LONG);
static expression_t *new_double_expression(parser_ctx_t*,double);
static expression_t *new_unary_expression(parser_ctx_t*,expression_type_t,expression_t*);
static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expression_t*,expression_t*);
static expression_t *new_new_expression(parser_ctx_t*,const WCHAR*);
static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
static void *new_statement(parser_ctx_t*,statement_type_t,size_t);
static statement_t *new_call_statement(parser_ctx_t*,BOOL,member_expression_t*);
static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
static statement_t *new_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*);
static statement_t *new_forto_statement(parser_ctx_t*,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*);
static statement_t *new_foreach_statement(parser_ctx_t*,const WCHAR*,expression_t*,statement_t*);
static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
static statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
static statement_t *new_const_statement(parser_ctx_t*,const_decl_t*);
static statement_t *new_select_statement(parser_ctx_t*,expression_t*,case_clausule_t*);
static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_t*,case_clausule_t*);
static class_decl_t *new_class_decl(parser_ctx_t*);
static class_decl_t *add_class_function(parser_ctx_t*,class_decl_t*,function_decl_t*);
static class_decl_t *add_variant_prop(parser_ctx_t*,class_decl_t*,const WCHAR*,unsigned);
static statement_t *link_statements(statement_t*,statement_t*);
static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
#define STORAGE_IS_PRIVATE 1
#define STORAGE_IS_DEFAULT 2
#define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
%}
%pure_parser
%start Program
%union {
const WCHAR *string;
statement_t *statement;
expression_t *expression;
member_expression_t *member;
elseif_decl_t *elseif;
dim_decl_t *dim_decl;
function_decl_t *func_decl;
arg_decl_t *arg_decl;
class_decl_t *class_decl;
const_decl_t *const_decl;
case_clausule_t *case_clausule;
unsigned uint;
LONG lng;
BOOL bool;
double dbl;
}
%token tEOF tNL tREM tEMPTYBRACKETS
%token tTRUE tFALSE
%token tNOT tAND tOR tXOR tEQV tIMP tNEQ
%token tIS tLTEQ tGTEQ tMOD
%token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST
%token tIF tELSE tELSEIF tEND tTHEN tEXIT
%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP tEACH tIN
%token tSELECT tCASE
%token tBYREF tBYVAL
%token tOPTION tEXPLICIT
%token tSTOP
%token tNOTHING tEMPTY tNULL
%token tCLASS tSET tNEW tPUBLIC tPRIVATE tDEFAULT tME
%token tERROR tNEXT tON tRESUME tGOTO
%token <string> tIdentifier tString
%token <lng> tLong tShort
%token <dbl> tDouble
%type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt IfStatement Else_opt
%type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression
%type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
%type <expression> ConstExpression NumericLiteralExpression
%type <member> MemberExpression
%type <expression> Arguments_opt ArgumentList_opt Step_opt ExpressionList
%type <bool> OptionExplicit_opt DoType
%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
%type <func_decl> FunctionDecl PropertyDecl
%type <elseif> ElseIfs_opt ElseIfs ElseIf
%type <class_decl> ClassDeclaration ClassBody
%type <uint> Storage Storage_opt
%type <dim_decl> DimDeclList
%type <const_decl> ConstDecl ConstDeclList
%type <string> Identifier
%type <case_clausule> CaseClausules
%%
Program
: OptionExplicit_opt SourceElements tEOF { parse_complete(ctx, $1); }
OptionExplicit_opt
: /* empty */ { $$ = FALSE; }
| tOPTION tEXPLICIT tNL { $$ = TRUE; }
SourceElements
: /* empty */
| SourceElements StatementNl { source_add_statement(ctx, $2); }
| SourceElements ClassDeclaration { source_add_class(ctx, $2); }
StatementsNl_opt
: /* empty */ { $$ = NULL; }
| StatementsNl { $$ = $1; }
StatementsNl
: StatementNl { $$ = $1; }
| StatementNl StatementsNl { $$ = link_statements($1, $2); }
StatementNl
: Statement tNL { $$ = $1; }
Statement
: ':' { $$ = NULL; }
| ':' Statement { $$ = $2; }
| SimpleStatement { $$ = $1; }
| SimpleStatement ':' Statement { $1->next = $3; $$ = $1; }
| SimpleStatement ':' { $$ = $1; }
SimpleStatement
: MemberExpression ArgumentList_opt { $1->args = $2; $$ = new_call_statement(ctx, FALSE, $1); CHECK_ERROR; }
| tCALL MemberExpression Arguments_opt { $2->args = $3; $$ = new_call_statement(ctx, TRUE, $2); CHECK_ERROR; }
| MemberExpression Arguments_opt '=' Expression
{ $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
| IfStatement { $$ = $1; }
| tWHILE Expression tNL StatementsNl_opt tWEND
{ $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
| tDO DoType Expression tNL StatementsNl_opt tLOOP
{ $$ = new_while_statement(ctx, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
CHECK_ERROR; }
| tDO tNL StatementsNl_opt tLOOP DoType Expression
{ $$ = new_while_statement(ctx, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
CHECK_ERROR; }
| tDO tNL StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, STAT_DOWHILE, NULL, $3); CHECK_ERROR; }
| FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
| tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0); CHECK_ERROR; }
| tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0); CHECK_ERROR; }
| tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
| tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; }
| tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
| tSET MemberExpression Arguments_opt '=' Expression
{ $2->args = $3; $$ = new_set_statement(ctx, $2, $5); CHECK_ERROR; }
| tSTOP { $$ = new_statement(ctx, STAT_STOP, 0); CHECK_ERROR; }
| tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, TRUE); CHECK_ERROR; }
| tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, FALSE); CHECK_ERROR; }
| tCONST ConstDeclList { $$ = new_const_statement(ctx, $2); CHECK_ERROR; }
| tFOR Identifier '=' Expression tTO Expression Step_opt tNL StatementsNl_opt tNEXT
{ $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
| tFOR tEACH Identifier tIN Expression tNL StatementsNl_opt tNEXT
{ $$ = new_foreach_statement(ctx, $3, $5, $7); }
| tSELECT tCASE Expression tNL CaseClausules tEND tSELECT
{ $$ = new_select_statement(ctx, $3, $5); }
MemberExpression
: Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
| CallExpression '.' Identifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
DimDeclList /* FIXME: Support arrays */
: Identifier { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; }
| Identifier ',' DimDeclList { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; }
ConstDeclList
: ConstDecl { $$ = $1; }
| ConstDecl ',' ConstDeclList { $1->next = $3; $$ = $1; }
ConstDecl
: Identifier '=' ConstExpression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; }
ConstExpression
: LiteralExpression { $$ = $1; }
| '-' NumericLiteralExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
DoType
: tWHILE { $$ = TRUE; }
| tUNTIL { $$ = FALSE; }
Step_opt
: /* empty */ { $$ = NULL;}
| tSTEP Expression { $$ = $2; }
IfStatement
: tIF Expression tTHEN tNL StatementsNl_opt ElseIfs_opt Else_opt tEND tIF
{ $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
| tIF Expression tTHEN Statement { $$ = new_if_statement(ctx, $2, $4, NULL, NULL); CHECK_ERROR; }
| tIF Expression tTHEN Statement tELSE Statement EndIf_opt
{ $$ = new_if_statement(ctx, $2, $4, NULL, $6); CHECK_ERROR; }
EndIf_opt
: /* empty */
| tEND tIF
ElseIfs_opt
: /* empty */ { $$ = NULL; }
| ElseIfs { $$ = $1; }
ElseIfs
: ElseIf { $$ = $1; }
| ElseIf ElseIfs { $1->next = $2; $$ = $1; }
ElseIf
: tELSEIF Expression tTHEN tNL StatementsNl_opt
{ $$ = new_elseif_decl(ctx, $2, $5); }
Else_opt
: /* empty */ { $$ = NULL; }
| tELSE tNL StatementsNl_opt { $$ = $3; }
CaseClausules
: /* empty */ { $$ = NULL; }
| tCASE tELSE tNL StatementsNl { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
| tCASE ExpressionList tNL StatementsNl_opt CaseClausules
{ $$ = new_case_clausule(ctx, $2, $4, $5); }
Arguments_opt
: EmptyBrackets_opt { $$ = NULL; }
| '(' ExpressionList ')' { $$ = $2; }
ArgumentList_opt
: EmptyBrackets_opt { $$ = NULL; }
| ExpressionList { $$ = $1; }
EmptyBrackets_opt
: /* empty */
| tEMPTYBRACKETS
ExpressionList
: Expression { $$ = $1; }
| Expression ',' ExpressionList { $1->next = $3; $$ = $1; }
Expression
: EqvExpression { $$ = $1; }
| Expression tIMP EqvExpression { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
EqvExpression
: XorExpression { $$ = $1; }
| EqvExpression tEQV XorExpression { $$ = new_binary_expression(ctx, EXPR_EQV, $1, $3); CHECK_ERROR; }
XorExpression
: OrExpression { $$ = $1; }
| XorExpression tXOR OrExpression { $$ = new_binary_expression(ctx, EXPR_XOR, $1, $3); CHECK_ERROR; }
OrExpression
: AndExpression { $$ = $1; }
| OrExpression tOR AndExpression { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); CHECK_ERROR; }
AndExpression
: NotExpression { $$ = $1; }
| AndExpression tAND NotExpression { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); CHECK_ERROR; }
NotExpression
: EqualityExpression { $$ = $1; }
| tNOT NotExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; }
EqualityExpression
: ConcatExpression { $$ = $1; }
| EqualityExpression '=' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; }
| EqualityExpression tNEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; }
| EqualityExpression '>' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; }
| EqualityExpression '<' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; }
| EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; }
| EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; }
| EqualityExpression tIS ConcatExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; }
ConcatExpression
: AdditiveExpression { $$ = $1; }
| ConcatExpression '&' AdditiveExpression { $$ = new_binary_expression(ctx, EXPR_CONCAT, $1, $3); CHECK_ERROR; }
AdditiveExpression
: ModExpression { $$ = $1; }
| AdditiveExpression '+' ModExpression { $$ = new_binary_expression(ctx, EXPR_ADD, $1, $3); CHECK_ERROR; }
| AdditiveExpression '-' ModExpression { $$ = new_binary_expression(ctx, EXPR_SUB, $1, $3); CHECK_ERROR; }
ModExpression
: IntdivExpression { $$ = $1; }
| ModExpression tMOD IntdivExpression { $$ = new_binary_expression(ctx, EXPR_MOD, $1, $3); CHECK_ERROR; }
IntdivExpression
: MultiplicativeExpression { $$ = $1; }
| IntdivExpression '\\' MultiplicativeExpression
{ $$ = new_binary_expression(ctx, EXPR_IDIV, $1, $3); CHECK_ERROR; }
MultiplicativeExpression
: ExpExpression { $$ = $1; }
| MultiplicativeExpression '*' ExpExpression
{ $$ = new_binary_expression(ctx, EXPR_MUL, $1, $3); CHECK_ERROR; }
| MultiplicativeExpression '/' ExpExpression
{ $$ = new_binary_expression(ctx, EXPR_DIV, $1, $3); CHECK_ERROR; }
ExpExpression
: UnaryExpression { $$ = $1; }
| ExpExpression '^' UnaryExpression { $$ = new_binary_expression(ctx, EXPR_EXP, $1, $3); CHECK_ERROR; }
UnaryExpression
: LiteralExpression { $$ = $1; }
| CallExpression { $$ = $1; }
| tNEW Identifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; }
| '-' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
CallExpression
: PrimaryExpression { $$ = $1; }
| MemberExpression Arguments_opt { $1->args = $2; $$ = &$1->expr; }
LiteralExpression
: tTRUE { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
| tFALSE { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
| tString { $$ = new_string_expression(ctx, $1); CHECK_ERROR; }
| NumericLiteralExpression { $$ = $1; }
| tEMPTY { $$ = new_expression(ctx, EXPR_EMPTY, 0); CHECK_ERROR; }
| tNULL { $$ = new_expression(ctx, EXPR_NULL, 0); CHECK_ERROR; }
| tNOTHING { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
NumericLiteralExpression
: tShort { $$ = new_long_expression(ctx, EXPR_USHORT, $1); CHECK_ERROR; }
| '0' { $$ = new_long_expression(ctx, EXPR_USHORT, 0); CHECK_ERROR; }
| tLong { $$ = new_long_expression(ctx, EXPR_ULONG, $1); CHECK_ERROR; }
| tDouble { $$ = new_double_expression(ctx, $1); CHECK_ERROR; }
PrimaryExpression
: '(' Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
| tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
ClassDeclaration
: tCLASS Identifier tNL ClassBody tEND tCLASS tNL { $4->name = $2; $$ = $4; }
ClassBody
: /* empty */ { $$ = new_class_decl(ctx); }
| FunctionDecl tNL ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
| Storage tIdentifier tNL ClassBody { $$ = add_variant_prop(ctx, $4, $2, $1); CHECK_ERROR; }
| PropertyDecl tNL ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
PropertyDecl
: Storage_opt tPROPERTY tGET tIdentifier EmptyBrackets_opt tNL StatementsNl_opt tEND tPROPERTY
{ $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, NULL, $7); CHECK_ERROR; }
| Storage_opt tPROPERTY tLET tIdentifier '(' ArgumentDecl ')' tNL StatementsNl_opt tEND tPROPERTY
{ $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
| Storage_opt tPROPERTY tSET tIdentifier '(' ArgumentDecl ')' tNL StatementsNl_opt tEND tPROPERTY
{ $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
FunctionDecl
: Storage_opt tSUB Identifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tSUB
{ $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; }
| Storage_opt tFUNCTION Identifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tFUNCTION
{ $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; }
Storage_opt
: /* empty*/ { $$ = 0; }
| Storage { $$ = $1; }
Storage
: tPUBLIC tDEFAULT { $$ = STORAGE_IS_DEFAULT; }
| tPUBLIC { $$ = 0; }
| tPRIVATE { $$ = STORAGE_IS_PRIVATE; }
ArgumentsDecl_opt
: EmptyBrackets_opt { $$ = NULL; }
| '(' ArgumentDeclList ')' { $$ = $2; }
ArgumentDeclList
: ArgumentDecl { $$ = $1; }
| ArgumentDecl ',' ArgumentDeclList { $1->next = $3; $$ = $1; }
ArgumentDecl
: Identifier { $$ = new_argument_decl(ctx, $1, TRUE); }
| tBYREF Identifier { $$ = new_argument_decl(ctx, $2, TRUE); }
| tBYVAL Identifier { $$ = new_argument_decl(ctx, $2, FALSE); }
/* 'property' may be both keyword and identifier, depending on context */
Identifier
: tIdentifier { $$ = $1; }
| tPROPERTY { $$ = propertyW; }
%%
static int parser_error(const char *str)
{
return 0;
}
static void source_add_statement(parser_ctx_t *ctx, statement_t *stat)
{
if(!stat)
return;
if(ctx->stats) {
ctx->stats_tail->next = stat;
ctx->stats_tail = stat;
}else {
ctx->stats = ctx->stats_tail = stat;
}
}
static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
{
class_decl->next = ctx->class_decls;
ctx->class_decls = class_decl;
}
static void parse_complete(parser_ctx_t *ctx, BOOL option_explicit)
{
ctx->parse_complete = TRUE;
ctx->option_explicit = option_explicit;
}
static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size)
{
expression_t *expr;
expr = parser_alloc(ctx, size ? size : sizeof(*expr));
if(expr) {
expr->type = type;
expr->next = NULL;
}
return expr;
}
static expression_t *new_bool_expression(parser_ctx_t *ctx, VARIANT_BOOL value)
{
bool_expression_t *expr;
expr = new_expression(ctx, EXPR_BOOL, sizeof(*expr));
if(!expr)
return NULL;
expr->value = value;
return &expr->expr;
}
static expression_t *new_string_expression(parser_ctx_t *ctx, const WCHAR *value)
{
string_expression_t *expr;
expr = new_expression(ctx, EXPR_STRING, sizeof(*expr));
if(!expr)
return NULL;
expr->value = value;
return &expr->expr;
}
static expression_t *new_long_expression(parser_ctx_t *ctx, expression_type_t type, LONG value)
{
int_expression_t *expr;
expr = new_expression(ctx, type, sizeof(*expr));
if(!expr)
return NULL;
expr->value = value;
return &expr->expr;
}
static expression_t *new_double_expression(parser_ctx_t *ctx, double value)
{
double_expression_t *expr;
expr = new_expression(ctx, EXPR_DOUBLE, sizeof(*expr));
if(!expr)
return NULL;
expr->value = value;
return &expr->expr;
}
static expression_t *new_unary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *subexpr)
{
unary_expression_t *expr;
expr = new_expression(ctx, type, sizeof(*expr));
if(!expr)
return NULL;
expr->subexpr = subexpr;
return &expr->expr;
}
static expression_t *new_binary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *left, expression_t *right)
{
binary_expression_t *expr;
expr = new_expression(ctx, type, sizeof(*expr));
if(!expr)
return NULL;
expr->left = left;
expr->right = right;
return &expr->expr;
}
static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *obj_expr, const WCHAR *identifier)
{
member_expression_t *expr;
expr = new_expression(ctx, EXPR_MEMBER, sizeof(*expr));
if(!expr)
return NULL;
expr->obj_expr = obj_expr;
expr->identifier = identifier;
expr->args = NULL;
return expr;
}
static expression_t *new_new_expression(parser_ctx_t *ctx, const WCHAR *identifier)
{
string_expression_t *expr;
expr = new_expression(ctx, EXPR_NEW, sizeof(*expr));
if(!expr)
return NULL;
expr->value = identifier;
return &expr->expr;
}
static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size)
{
statement_t *stat;
stat = parser_alloc(ctx, size ? size : sizeof(*stat));
if(stat) {
stat->type = type;
stat->next = NULL;
}
return stat;
}
static statement_t *new_call_statement(parser_ctx_t *ctx, BOOL is_strict, member_expression_t *expr)
{
call_statement_t *stat;
stat = new_statement(ctx, STAT_CALL, sizeof(*stat));
if(!stat)
return NULL;
stat->expr = expr;
stat->is_strict = is_strict;
return &stat->stat;
}
static statement_t *new_assign_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
{
assign_statement_t *stat;
stat = new_statement(ctx, STAT_ASSIGN, sizeof(*stat));
if(!stat)
return NULL;
stat->member_expr = left;
stat->value_expr = right;
return &stat->stat;
}
static statement_t *new_set_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
{
assign_statement_t *stat;
stat = new_statement(ctx, STAT_SET, sizeof(*stat));
if(!stat)
return NULL;
stat->member_expr = left;
stat->value_expr = right;
return &stat->stat;
}
static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, dim_decl_t *next)
{
dim_decl_t *decl;
decl = parser_alloc(ctx, sizeof(*decl));
if(!decl)
return NULL;
decl->name = name;
decl->next = next;
return decl;
}
static statement_t *new_dim_statement(parser_ctx_t *ctx, dim_decl_t *decls)
{
dim_statement_t *stat;
stat = new_statement(ctx, STAT_DIM, sizeof(*stat));
if(!stat)
return NULL;
stat->dim_decls = decls;
return &stat->stat;
}
static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, statement_t *stat)
{
elseif_decl_t *decl;
decl = parser_alloc(ctx, sizeof(*decl));
if(!decl)
return NULL;
decl->expr = expr;
decl->stat = stat;
decl->next = NULL;
return decl;
}
static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type, expression_t *expr, statement_t *body)
{
while_statement_t *stat;
stat = new_statement(ctx, type, sizeof(*stat));
if(!stat)
return NULL;
stat->expr = expr;
stat->body = body;
return &stat->stat;
}
static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *from_expr,
expression_t *to_expr, expression_t *step_expr, statement_t *body)
{
forto_statement_t *stat;
stat = new_statement(ctx, STAT_FORTO, sizeof(*stat));
if(!stat)
return NULL;
stat->identifier = identifier;
stat->from_expr = from_expr;
stat->to_expr = to_expr;
stat->step_expr = step_expr;
stat->body = body;
return &stat->stat;
}
static statement_t *new_foreach_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *group_expr,
statement_t *body)
{
foreach_statement_t *stat;
stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat));
if(!stat)
return NULL;
stat->identifier = identifier;
stat->group_expr = group_expr;
stat->body = body;
return &stat->stat;
}
static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
statement_t *else_stat)
{
if_statement_t *stat;
stat = new_statement(ctx, STAT_IF, sizeof(*stat));
if(!stat)
return NULL;
stat->expr = expr;
stat->if_stat = if_stat;
stat->elseifs = elseif_decl;
stat->else_stat = else_stat;
return &stat->stat;
}
static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr, case_clausule_t *case_clausules)
{
select_statement_t *stat;
stat = new_statement(ctx, STAT_SELECT, sizeof(*stat));
if(!stat)
return NULL;
stat->expr = expr;
stat->case_clausules = case_clausules;
return &stat->stat;
}
static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
{
case_clausule_t *ret;
ret = parser_alloc(ctx, sizeof(*ret));
if(!ret)
return NULL;
ret->expr = expr;
ret->stat = stat;
ret->next = next;
return ret;
}
static statement_t *new_onerror_statement(parser_ctx_t *ctx, BOOL resume_next)
{
onerror_statement_t *stat;
stat = new_statement(ctx, STAT_ONERROR, sizeof(*stat));
if(!stat)
return NULL;
stat->resume_next = resume_next;
return &stat->stat;
}
static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL by_ref)
{
arg_decl_t *arg_decl;
arg_decl = parser_alloc(ctx, sizeof(*arg_decl));
if(!arg_decl)
return NULL;
arg_decl->name = name;
arg_decl->by_ref = by_ref;
arg_decl->next = NULL;
return arg_decl;
}
static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type,
unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body)
{
function_decl_t *decl;
if(storage_flags & STORAGE_IS_DEFAULT) {
if(type == FUNC_PROPGET) {
type = FUNC_DEFGET;
}else {
FIXME("Invalid default property\n");
ctx->hres = E_FAIL;
return NULL;
}
}
decl = parser_alloc(ctx, sizeof(*decl));
if(!decl)
return NULL;
decl->name = name;
decl->type = type;
decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
decl->args = arg_decl;
decl->body = body;
decl->next = NULL;
decl->next_prop_func = NULL;
return decl;
}
static statement_t *new_function_statement(parser_ctx_t *ctx, function_decl_t *decl)
{
function_statement_t *stat;
stat = new_statement(ctx, STAT_FUNC, sizeof(*stat));
if(!stat)
return NULL;
stat->func_decl = decl;
return &stat->stat;
}
static class_decl_t *new_class_decl(parser_ctx_t *ctx)
{
class_decl_t *class_decl;
class_decl = parser_alloc(ctx, sizeof(*class_decl));
if(!class_decl)
return NULL;
class_decl->funcs = NULL;
class_decl->props = NULL;
class_decl->next = NULL;
return class_decl;
}
static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_decl, function_decl_t *decl)
{
function_decl_t *iter;
for(iter = class_decl->funcs; iter; iter = iter->next) {
if(!strcmpiW(iter->name, decl->name)) {
if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION) {
FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
ctx->hres = E_FAIL;
return NULL;
}
while(1) {
if(iter->type == decl->type) {
FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
ctx->hres = E_FAIL;
return NULL;
}
if(!iter->next_prop_func)
break;
iter = iter->next_prop_func;
}
iter->next_prop_func = decl;
return class_decl;
}
}
decl->next = class_decl->funcs;
class_decl->funcs = decl;
return class_decl;
}
static class_decl_t *add_variant_prop(parser_ctx_t *ctx, class_decl_t *class_decl, const WCHAR *identifier, unsigned storage_flags)
{
class_prop_decl_t *prop;
if(storage_flags & STORAGE_IS_DEFAULT) {
FIXME("variant prop van't be default value\n");
ctx->hres = E_FAIL;
return NULL;
}
prop = parser_alloc(ctx, sizeof(*prop));
if(!prop)
return NULL;
prop->name = identifier;
prop->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
prop->next = class_decl->props;
class_decl->props = prop;
return class_decl;
}
static const_decl_t *new_const_decl(parser_ctx_t *ctx, const WCHAR *name, expression_t *expr)
{
const_decl_t *decl;
decl = parser_alloc(ctx, sizeof(*decl));
if(!decl)
return NULL;
decl->name = name;
decl->value_expr = expr;
decl->next = NULL;
return decl;
}
static statement_t *new_const_statement(parser_ctx_t *ctx, const_decl_t *decls)
{
const_statement_t *stat;
stat = new_statement(ctx, STAT_CONST, sizeof(*stat));
if(!stat)
return NULL;
stat->decls = decls;
return &stat->stat;
}
static statement_t *link_statements(statement_t *head, statement_t *tail)
{
statement_t *iter;
for(iter = head; iter->next; iter = iter->next);
iter->next = tail;
return head;
}
void *parser_alloc(parser_ctx_t *ctx, size_t size)
{
void *ret;
ret = heap_pool_alloc(&ctx->heap, size);
if(!ret)
ctx->hres = E_OUTOFMEMORY;
return ret;
}
HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter)
{
const WCHAR html_delimiterW[] = {'<','/','s','c','r','i','p','t','>',0};
ctx->code = ctx->ptr = code;
ctx->end = ctx->code + strlenW(ctx->code);
heap_pool_init(&ctx->heap);
ctx->parse_complete = FALSE;
ctx->hres = S_OK;
ctx->last_token = tNL;
ctx->last_nl = 0;
ctx->stats = ctx->stats_tail = NULL;
ctx->class_decls = NULL;
ctx->option_explicit = FALSE;
ctx->is_html = delimiter && !strcmpiW(delimiter, html_delimiterW);
parser_parse(ctx);
if(FAILED(ctx->hres))
return ctx->hres;
if(!ctx->parse_complete) {
FIXME("parser failed around %s\n", debugstr_w(ctx->code+20 > ctx->ptr ? ctx->code : ctx->ptr-20));
return E_FAIL;
}
return S_OK;
}
void parser_release(parser_ctx_t *ctx)
{
heap_pool_free(&ctx->heap);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,82 @@
/*
* Copyright 2008 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Code in this file is based on files:
* js/src/jsregexp.h
* js/src/jsregexp.c
* from Mozilla project, released under LGPL 2.1 or later.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*/
#define REG_FOLD 0x01 /* fold uppercase to lowercase */
#define REG_GLOB 0x02 /* global exec, creates array of matches */
#define REG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line */
#define REG_STICKY 0x08 /* only match starting at lastIndex */
typedef struct RECapture {
ptrdiff_t index; /* start of contents, -1 for empty */
size_t length; /* length of capture */
} RECapture;
typedef struct match_state_t {
const WCHAR *cp;
DWORD match_len;
DWORD paren_count;
RECapture parens[1];
} match_state_t;
typedef BYTE jsbytecode;
typedef struct regexp_t {
WORD flags; /* flags, see jsapi.h's REG_* defines */
size_t parenCount; /* number of parenthesized submatches */
size_t classCount; /* count [...] bitmaps */
struct RECharSet *classList; /* list of [...] bitmaps */
const WCHAR *source; /* locked source string, sans // */
DWORD source_len;
jsbytecode program[1]; /* regular expression bytecode */
} regexp_t;
regexp_t* regexp_new(void*, heap_pool_t*, const WCHAR*, DWORD, WORD, BOOL) DECLSPEC_HIDDEN;
void regexp_destroy(regexp_t*) DECLSPEC_HIDDEN;
HRESULT regexp_execute(regexp_t*, void*, heap_pool_t*, const WCHAR*,
DWORD, match_state_t*) DECLSPEC_HIDDEN;
HRESULT regexp_set_flags(regexp_t**, void*, heap_pool_t*, WORD) DECLSPEC_HIDDEN;
static inline match_state_t* alloc_match_state(regexp_t *regexp,
heap_pool_t *pool, const WCHAR *pos)
{
size_t size = offsetof(match_state_t, parens) + regexp->parenCount*sizeof(RECapture);
match_state_t *ret;
ret = pool ? heap_pool_alloc(pool, size) : heap_alloc(size);
if(!ret)
return NULL;
ret->cp = pos;
return ret;
}

View file

@ -0,0 +1,971 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "vbscript.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
#define FDEX_VERSION_MASK 0xf0000000
static inline BOOL is_func_id(vbdisp_t *This, DISPID id)
{
return id < This->desc->func_cnt;
}
static BOOL get_func_id(vbdisp_t *This, const WCHAR *name, vbdisp_invoke_type_t invoke_type, BOOL search_private, DISPID *id)
{
unsigned i;
for(i = invoke_type == VBDISP_ANY ? 0 : 1; i < This->desc->func_cnt; i++) {
if(invoke_type == VBDISP_ANY) {
if(!search_private && !This->desc->funcs[i].is_public)
continue;
if(!i && !This->desc->funcs[0].name) /* default value may not exist */
continue;
}else {
if(!This->desc->funcs[i].entries[invoke_type]
|| (!search_private && !This->desc->funcs[i].entries[invoke_type]->is_public))
continue;
}
if(!strcmpiW(This->desc->funcs[i].name, name)) {
*id = i;
return TRUE;
}
}
return FALSE;
}
HRESULT vbdisp_get_id(vbdisp_t *This, BSTR name, vbdisp_invoke_type_t invoke_type, BOOL search_private, DISPID *id)
{
unsigned i;
if(get_func_id(This, name, invoke_type, search_private, id))
return S_OK;
for(i=0; i < This->desc->prop_cnt; i++) {
if(!search_private && !This->desc->props[i].is_public)
continue;
if(!strcmpiW(This->desc->props[i].name, name)) {
*id = i + This->desc->func_cnt;
return S_OK;
}
}
if(This->desc->typeinfo) {
HRESULT hres;
hres = ITypeInfo_GetIDsOfNames(This->desc->typeinfo, &name, 1, id);
if(SUCCEEDED(hres))
return S_OK;
}
*id = -1;
return DISP_E_UNKNOWNNAME;
}
static VARIANT *get_propput_arg(const DISPPARAMS *dp)
{
unsigned i;
for(i=0; i < dp->cNamedArgs; i++) {
if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
return dp->rgvarg+i;
}
return NULL;
}
static HRESULT invoke_variant_prop(VARIANT *v, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
HRESULT hres;
switch(flags) {
case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
case DISPATCH_PROPERTYGET:
if(dp->cArgs) {
WARN("called with arguments\n");
return DISP_E_MEMBERNOTFOUND; /* That's what tests show */
}
hres = VariantCopy(res, v);
break;
case DISPATCH_PROPERTYPUT: {
VARIANT *put_val;
put_val = get_propput_arg(dp);
if(!put_val) {
WARN("no value to set\n");
return DISP_E_PARAMNOTOPTIONAL;
}
if(res)
V_VT(res) = VT_EMPTY;
hres = VariantCopy(v, put_val);
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return hres;
}
static HRESULT invoke_builtin(vbdisp_t *This, const builtin_prop_t *prop, WORD flags, DISPPARAMS *dp, VARIANT *res)
{
VARIANT args[8];
unsigned argn, i;
switch(flags) {
case DISPATCH_PROPERTYGET:
if(!(prop->flags & (BP_GET|BP_GETPUT))) {
FIXME("property does not support DISPATCH_PROPERTYGET\n");
return E_FAIL;
}
break;
case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
if(!prop->proc && prop->flags == BP_GET) {
const int vt = prop->min_args, val = prop->max_args;
switch(vt) {
case VT_I2:
V_VT(res) = VT_I2;
V_I2(res) = val;
break;
case VT_I4:
V_VT(res) = VT_I4;
V_I4(res) = val;
break;
case VT_BSTR: {
const string_constant_t *str = (const string_constant_t*)prop->max_args;
BSTR ret;
ret = SysAllocStringLen(str->buf, str->len);
if(!ret)
return E_OUTOFMEMORY;
V_VT(res) = VT_BSTR;
V_BSTR(res) = ret;
break;
}
DEFAULT_UNREACHABLE;
}
return S_OK;
}
break;
case DISPATCH_METHOD:
if(prop->flags & (BP_GET|BP_GETPUT)) {
FIXME("Call on property\n");
return E_FAIL;
}
break;
case DISPATCH_PROPERTYPUT:
if(!(prop->flags & BP_GETPUT)) {
FIXME("property does not support DISPATCH_PROPERTYPUT\n");
return E_FAIL;
}
FIXME("call put\n");
return E_NOTIMPL;
default:
FIXME("unsupported flags %x\n", flags);
return E_NOTIMPL;
}
argn = arg_cnt(dp);
if(argn < prop->min_args || argn > (prop->max_args ? prop->max_args : prop->min_args)) {
FIXME("invalid number of arguments\n");
return E_FAIL;
}
assert(argn < sizeof(args)/sizeof(*args));
for(i=0; i < argn; i++) {
if(V_VT(dp->rgvarg+dp->cArgs-i-1) == (VT_BYREF|VT_VARIANT))
args[i] = *V_VARIANTREF(dp->rgvarg+dp->cArgs-i-1);
else
args[i] = dp->rgvarg[dp->cArgs-i-1];
}
return prop->proc(This, args, dp->cArgs, res);
}
static BOOL run_terminator(vbdisp_t *This)
{
DISPPARAMS dp = {0};
if(This->terminator_ran)
return TRUE;
This->terminator_ran = TRUE;
if(!This->desc->class_terminate_id)
return TRUE;
This->ref++;
exec_script(This->desc->ctx, This->desc->funcs[This->desc->class_terminate_id].entries[VBDISP_CALLGET],
(IDispatch*)&This->IDispatchEx_iface, &dp, NULL);
return !--This->ref;
}
static void clean_props(vbdisp_t *This)
{
unsigned i;
if(!This->desc)
return;
for(i=0; i < This->desc->prop_cnt; i++)
VariantClear(This->props+i);
}
static inline vbdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
{
return CONTAINING_RECORD(iface, vbdisp_t, IDispatchEx_iface);
}
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IDispatchEx_iface;
}else if(IsEqualGUID(&IID_IDispatch, riid)) {
TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
*ppv = &This->IDispatchEx_iface;
}else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
*ppv = &This->IDispatchEx_iface;
}else {
WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref && run_terminator(This)) {
clean_props(This);
list_remove(&This->entry);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid,
ITypeInfo **ppTInfo)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid,
DISPID *rgDispId)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
lcid, rgDispId);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
grfdex &= ~FDEX_VERSION_MASK;
if(!This->desc)
return E_UNEXPECTED;
/* Tests show that fdexNameCaseSensitive is ignored */
if(grfdex & ~(fdexNameEnsure|fdexNameCaseInsensitive|fdexNameCaseSensitive)) {
FIXME("unsupported flags %x\n", grfdex);
return E_NOTIMPL;
}
return vbdisp_get_id(This, bstrName, VBDISP_ANY, FALSE, pid);
}
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
if(!This->desc)
return E_UNEXPECTED;
if(pvarRes)
V_VT(pvarRes) = VT_EMPTY;
if(id < 0)
return DISP_E_MEMBERNOTFOUND;
if(is_func_id(This, id)) {
function_t *func;
switch(wFlags) {
case DISPATCH_METHOD:
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
func = This->desc->funcs[id].entries[VBDISP_CALLGET];
if(!func) {
FIXME("no invoke/getter\n");
return DISP_E_MEMBERNOTFOUND;
}
return exec_script(This->desc->ctx, func, (IDispatch*)&This->IDispatchEx_iface, pdp, pvarRes);
case DISPATCH_PROPERTYPUT: {
VARIANT *put_val;
DISPPARAMS dp = {NULL, NULL, 1, 0};
if(arg_cnt(pdp)) {
FIXME("arguments not implemented\n");
return E_NOTIMPL;
}
put_val = get_propput_arg(pdp);
if(!put_val) {
WARN("no value to set\n");
return DISP_E_PARAMNOTOPTIONAL;
}
dp.rgvarg = put_val;
func = This->desc->funcs[id].entries[V_VT(put_val) == VT_DISPATCH ? VBDISP_SET : VBDISP_LET];
if(!func) {
FIXME("no letter/setter\n");
return DISP_E_MEMBERNOTFOUND;
}
return exec_script(This->desc->ctx, func, (IDispatch*)&This->IDispatchEx_iface, &dp, NULL);
}
default:
FIXME("flags %x\n", wFlags);
return DISP_E_MEMBERNOTFOUND;
}
}
if(id < This->desc->prop_cnt + This->desc->func_cnt)
return invoke_variant_prop(This->props+(id-This->desc->func_cnt), wFlags, pdp, pvarRes);
if(This->desc->builtin_prop_cnt) {
unsigned min = 0, max = This->desc->builtin_prop_cnt-1, i;
while(min <= max) {
i = (min+max)/2;
if(This->desc->builtin_props[i].id == id)
return invoke_builtin(This, This->desc->builtin_props+i, wFlags, pdp, pvarRes);
if(This->desc->builtin_props[i].id < id)
min = i+1;
else
max = i-1;
}
}
return DISP_E_MEMBERNOTFOUND;
}
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%x)\n", This, id);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%x %p)\n", This, id, pbstrName);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
FIXME("(%p)->(%p)\n", This, ppunk);
return E_NOTIMPL;
}
static IDispatchExVtbl DispatchExVtbl = {
DispatchEx_QueryInterface,
DispatchEx_AddRef,
DispatchEx_Release,
DispatchEx_GetTypeInfoCount,
DispatchEx_GetTypeInfo,
DispatchEx_GetIDsOfNames,
DispatchEx_Invoke,
DispatchEx_GetDispID,
DispatchEx_InvokeEx,
DispatchEx_DeleteMemberByName,
DispatchEx_DeleteMemberByDispID,
DispatchEx_GetMemberProperties,
DispatchEx_GetMemberName,
DispatchEx_GetNextDispID,
DispatchEx_GetNameSpaceParent
};
static inline vbdisp_t *unsafe_impl_from_IDispatch(IDispatch *iface)
{
return iface->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl
? CONTAINING_RECORD(iface, vbdisp_t, IDispatchEx_iface)
: NULL;
}
HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
{
vbdisp_t *vbdisp;
vbdisp = heap_alloc_zero( FIELD_OFFSET( vbdisp_t, props[desc->prop_cnt] ));
if(!vbdisp)
return E_OUTOFMEMORY;
vbdisp->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
vbdisp->ref = 1;
vbdisp->desc = desc;
list_add_tail(&desc->ctx->objects, &vbdisp->entry);
if(desc->class_initialize_id) {
DISPPARAMS dp = {0};
HRESULT hres;
hres = exec_script(desc->ctx, desc->funcs[desc->class_initialize_id].entries[VBDISP_CALLGET],
(IDispatch*)&vbdisp->IDispatchEx_iface, &dp, NULL);
if(FAILED(hres)) {
IDispatchEx_Release(&vbdisp->IDispatchEx_iface);
return hres;
}
}
*ret = vbdisp;
return S_OK;
}
static HRESULT Procedure_invoke(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
{
script_ctx_t *ctx = This->desc->ctx;
HRESULT hres;
TRACE("\n");
IActiveScriptSite_OnEnterScript(ctx->site);
hres = exec_script(ctx, This->desc->value_func, NULL, NULL, NULL);
IActiveScriptSite_OnLeaveScript(ctx->site);
return hres;
}
static const builtin_prop_t procedure_props[] = {
{DISPID_VALUE, Procedure_invoke, 0}
};
HRESULT create_procedure_disp(script_ctx_t *ctx, vbscode_t *code, IDispatch **ret)
{
class_desc_t *desc;
vbdisp_t *vbdisp;
HRESULT hres;
desc = heap_alloc_zero(sizeof(*desc));
if(!desc)
return E_OUTOFMEMORY;
desc->ctx = ctx;
desc->builtin_prop_cnt = sizeof(procedure_props)/sizeof(*procedure_props);
desc->builtin_props = procedure_props;
desc->value_func = &code->main_code;
hres = create_vbdisp(desc, &vbdisp);
if(FAILED(hres)) {
heap_free(desc);
return hres;
}
desc->next = ctx->procs;
ctx->procs = desc;
*ret = (IDispatch*)&vbdisp->IDispatchEx_iface;
return S_OK;
}
struct _ident_map_t {
const WCHAR *name;
BOOL is_var;
union {
dynamic_var_t *var;
function_t *func;
} u;
};
static inline DISPID ident_to_id(ScriptDisp *This, ident_map_t *ident)
{
return (ident-This->ident_map)+1;
}
static inline ident_map_t *id_to_ident(ScriptDisp *This, DISPID id)
{
return 0 < id && id <= This->ident_map_cnt ? This->ident_map+id-1 : NULL;
}
static ident_map_t *add_ident(ScriptDisp *This, const WCHAR *name)
{
ident_map_t *ret;
if(!This->ident_map_size) {
This->ident_map = heap_alloc(4 * sizeof(*This->ident_map));
if(!This->ident_map)
return NULL;
This->ident_map_size = 4;
}else if(This->ident_map_cnt == This->ident_map_size) {
ident_map_t *new_map;
new_map = heap_realloc(This->ident_map, 2*This->ident_map_size*sizeof(*new_map));
if(!new_map)
return NULL;
This->ident_map = new_map;
This->ident_map_size *= 2;
}
ret = This->ident_map + This->ident_map_cnt++;
ret->name = name;
return ret;
}
static inline ScriptDisp *ScriptDisp_from_IDispatchEx(IDispatchEx *iface)
{
return CONTAINING_RECORD(iface, ScriptDisp, IDispatchEx_iface);
}
static HRESULT WINAPI ScriptDisp_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IDispatchEx_iface;
}else if(IsEqualGUID(&IID_IDispatch, riid)) {
TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
*ppv = &This->IDispatchEx_iface;
}else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
*ppv = &This->IDispatchEx_iface;
}else {
WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI ScriptDisp_AddRef(IDispatchEx *iface)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
assert(!This->ctx);
heap_free(This->ident_map);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI ScriptDisp_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
TRACE("(%p)->(%p)\n", This, pctinfo);
*pctinfo = 1;
return S_OK;
}
static HRESULT WINAPI ScriptDisp_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid,
ITypeInfo **ppTInfo)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptDisp_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
UINT i;
HRESULT hres;
TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
lcid, rgDispId);
for(i=0; i < cNames; i++) {
hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
if(FAILED(hres))
return hres;
}
return S_OK;
}
static HRESULT WINAPI ScriptDisp_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
return IDispatchEx_InvokeEx(&This->IDispatchEx_iface, dispIdMember, lcid, wFlags,
pDispParams, pVarResult, pExcepInfo, NULL);
}
static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
dynamic_var_t *var;
ident_map_t *ident;
function_t *func;
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
if(!This->ctx)
return E_UNEXPECTED;
for(ident = This->ident_map; ident < This->ident_map+This->ident_map_cnt; ident++) {
if(!strcmpiW(ident->name, bstrName)) {
*pid = ident_to_id(This, ident);
return S_OK;
}
}
for(var = This->ctx->global_vars; var; var = var->next) {
if(!strcmpiW(var->name, bstrName)) {
ident = add_ident(This, var->name);
if(!ident)
return E_OUTOFMEMORY;
ident->is_var = TRUE;
ident->u.var = var;
*pid = ident_to_id(This, ident);
return S_OK;
}
}
for(func = This->ctx->global_funcs; func; func = func->next) {
if(!strcmpiW(func->name, bstrName)) {
ident = add_ident(This, func->name);
if(!ident)
return E_OUTOFMEMORY;
ident->is_var = FALSE;
ident->u.func = func;
*pid = ident_to_id(This, ident);
return S_OK;
}
}
*pid = -1;
return DISP_E_UNKNOWNNAME;
}
static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
ident_map_t *ident;
HRESULT hres;
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
ident = id_to_ident(This, id);
if(!ident)
return DISP_E_MEMBERNOTFOUND;
if(ident->is_var) {
if(ident->u.var->is_const) {
FIXME("const not supported\n");
return E_NOTIMPL;
}
return invoke_variant_prop(&ident->u.var->v, wFlags, pdp, pvarRes);
}
switch(wFlags) {
case DISPATCH_METHOD:
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
IActiveScriptSite_OnEnterScript(This->ctx->site);
hres = exec_script(This->ctx, ident->u.func, NULL, pdp, pvarRes);
IActiveScriptSite_OnLeaveScript(This->ctx->site);
break;
default:
FIXME("Unsupported flags %x\n", wFlags);
hres = E_NOTIMPL;
}
return hres;
}
static HRESULT WINAPI ScriptDisp_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptDisp_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%x)\n", This, id);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptDisp_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptDisp_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%x %p)\n", This, id, pbstrName);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptDisp_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
return E_NOTIMPL;
}
static HRESULT WINAPI ScriptDisp_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
FIXME("(%p)->(%p)\n", This, ppunk);
return E_NOTIMPL;
}
static IDispatchExVtbl ScriptDispVtbl = {
ScriptDisp_QueryInterface,
ScriptDisp_AddRef,
ScriptDisp_Release,
ScriptDisp_GetTypeInfoCount,
ScriptDisp_GetTypeInfo,
ScriptDisp_GetIDsOfNames,
ScriptDisp_Invoke,
ScriptDisp_GetDispID,
ScriptDisp_InvokeEx,
ScriptDisp_DeleteMemberByName,
ScriptDisp_DeleteMemberByDispID,
ScriptDisp_GetMemberProperties,
ScriptDisp_GetMemberName,
ScriptDisp_GetNextDispID,
ScriptDisp_GetNameSpaceParent
};
HRESULT create_script_disp(script_ctx_t *ctx, ScriptDisp **ret)
{
ScriptDisp *script_disp;
script_disp = heap_alloc_zero(sizeof(*script_disp));
if(!script_disp)
return E_OUTOFMEMORY;
script_disp->IDispatchEx_iface.lpVtbl = &ScriptDispVtbl;
script_disp->ref = 1;
script_disp->ctx = ctx;
*ret = script_disp;
return S_OK;
}
void collect_objects(script_ctx_t *ctx)
{
vbdisp_t *iter, *iter2;
LIST_FOR_EACH_ENTRY_SAFE(iter, iter2, &ctx->objects, vbdisp_t, entry)
run_terminator(iter);
while(!list_empty(&ctx->objects)) {
iter = LIST_ENTRY(list_head(&ctx->objects), vbdisp_t, entry);
IDispatchEx_AddRef(&iter->IDispatchEx_iface);
clean_props(iter);
iter->desc = NULL;
list_remove(&iter->entry);
list_init(&iter->entry);
IDispatchEx_Release(&iter->IDispatchEx_iface);
}
}
HRESULT disp_get_id(IDispatch *disp, BSTR name, vbdisp_invoke_type_t invoke_type, BOOL search_private, DISPID *id)
{
IDispatchEx *dispex;
vbdisp_t *vbdisp;
HRESULT hres;
vbdisp = unsafe_impl_from_IDispatch(disp);
if(vbdisp)
return vbdisp_get_id(vbdisp, name, invoke_type, search_private, id);
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(FAILED(hres)) {
TRACE("using IDispatch\n");
return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
}
hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseInsensitive, id);
IDispatchEx_Release(dispex);
return hres;
}
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp, VARIANT *retv)
{
const WORD flags = DISPATCH_METHOD|(retv ? DISPATCH_PROPERTYGET : 0);
IDispatchEx *dispex;
EXCEPINFO ei;
HRESULT hres;
memset(&ei, 0, sizeof(ei));
if(retv)
V_VT(retv) = VT_EMPTY;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(FAILED(hres)) {
UINT err = 0;
TRACE("using IDispatch\n");
return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, dp, retv, &ei, &err);
}
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, dp, retv, &ei, NULL /* CALLER_FIXME */);
IDispatchEx_Release(dispex);
return hres;
}
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, DISPPARAMS *dp)
{
IDispatchEx *dispex;
EXCEPINFO ei = {0};
HRESULT hres;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) {
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, dp, NULL, &ei, NULL /* FIXME! */);
IDispatchEx_Release(dispex);
}else {
ULONG err = 0;
TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, dp, NULL, &ei, &err);
}
return hres;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,871 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
//#include <assert.h>
#include "vbscript.h"
#include <objsafe.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
#ifdef _WIN64
#define CTXARG_T DWORDLONG
#define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
#define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
#else
#define CTXARG_T DWORD
#define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
#define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
#endif
struct VBScript {
IActiveScript IActiveScript_iface;
IActiveScriptParse IActiveScriptParse_iface;
IActiveScriptParseProcedure2 IActiveScriptParseProcedure2_iface;
IObjectSafety IObjectSafety_iface;
LONG ref;
DWORD safeopt;
SCRIPTSTATE state;
IActiveScriptSite *site;
script_ctx_t *ctx;
LONG thread_id;
LCID lcid;
};
static void change_state(VBScript *This, SCRIPTSTATE state)
{
if(This->state == state)
return;
This->state = state;
if(This->site)
IActiveScriptSite_OnStateChange(This->site, state);
}
static inline BOOL is_started(VBScript *This)
{
return This->state == SCRIPTSTATE_STARTED
|| This->state == SCRIPTSTATE_CONNECTED
|| This->state == SCRIPTSTATE_DISCONNECTED;
}
static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code)
{
HRESULT hres;
code->pending_exec = FALSE;
IActiveScriptSite_OnEnterScript(ctx->site);
hres = exec_script(ctx, &code->main_code, NULL, NULL, NULL);
IActiveScriptSite_OnLeaveScript(ctx->site);
return hres;
}
static void exec_queued_code(script_ctx_t *ctx)
{
vbscode_t *iter;
LIST_FOR_EACH_ENTRY(iter, &ctx->code_list, vbscode_t, entry) {
if(iter->pending_exec)
exec_global_code(ctx, iter);
}
}
static HRESULT set_ctx_site(VBScript *This)
{
HRESULT hres;
This->ctx->lcid = This->lcid;
hres = init_global(This->ctx);
if(FAILED(hres))
return hres;
IActiveScriptSite_AddRef(This->site);
This->ctx->site = This->site;
change_state(This, SCRIPTSTATE_INITIALIZED);
return S_OK;
}
static void release_script(script_ctx_t *ctx)
{
class_desc_t *class_desc;
collect_objects(ctx);
release_dynamic_vars(ctx->global_vars);
ctx->global_vars = NULL;
while(!list_empty(&ctx->named_items)) {
named_item_t *iter = LIST_ENTRY(list_head(&ctx->named_items), named_item_t, entry);
list_remove(&iter->entry);
if(iter->disp)
IDispatch_Release(iter->disp);
heap_free(iter->name);
heap_free(iter);
}
while(ctx->procs) {
class_desc = ctx->procs;
ctx->procs = class_desc->next;
heap_free(class_desc);
}
if(ctx->host_global) {
IDispatch_Release(ctx->host_global);
ctx->host_global = NULL;
}
if(ctx->secmgr) {
IInternetHostSecurityManager_Release(ctx->secmgr);
ctx->secmgr = NULL;
}
if(ctx->site) {
IActiveScriptSite_Release(ctx->site);
ctx->site = NULL;
}
if(ctx->err_obj) {
IDispatchEx_Release(&ctx->err_obj->IDispatchEx_iface);
ctx->err_obj = NULL;
}
if(ctx->global_obj) {
IDispatchEx_Release(&ctx->global_obj->IDispatchEx_iface);
ctx->global_obj = NULL;
}
if(ctx->script_obj) {
ScriptDisp *script_obj = ctx->script_obj;
ctx->script_obj = NULL;
script_obj->ctx = NULL;
IDispatchEx_Release(&script_obj->IDispatchEx_iface);
}
heap_pool_free(&ctx->heap);
heap_pool_init(&ctx->heap);
}
static void destroy_script(script_ctx_t *ctx)
{
while(!list_empty(&ctx->code_list))
release_vbscode(LIST_ENTRY(list_head(&ctx->code_list), vbscode_t, entry));
release_script(ctx);
heap_free(ctx);
}
static void decrease_state(VBScript *This, SCRIPTSTATE state)
{
switch(This->state) {
case SCRIPTSTATE_CONNECTED:
change_state(This, SCRIPTSTATE_DISCONNECTED);
if(state == SCRIPTSTATE_DISCONNECTED)
return;
/* FALLTHROUGH */
case SCRIPTSTATE_STARTED:
case SCRIPTSTATE_DISCONNECTED:
if(This->state == SCRIPTSTATE_DISCONNECTED)
change_state(This, SCRIPTSTATE_INITIALIZED);
if(state == SCRIPTSTATE_INITIALIZED)
break;
/* FALLTHROUGH */
case SCRIPTSTATE_INITIALIZED:
case SCRIPTSTATE_UNINITIALIZED:
change_state(This, state);
if(This->site) {
IActiveScriptSite_Release(This->site);
This->site = NULL;
}
if(This->ctx)
release_script(This->ctx);
This->thread_id = 0;
break;
case SCRIPTSTATE_CLOSED:
break;
DEFAULT_UNREACHABLE;
}
}
static inline VBScript *impl_from_IActiveScript(IActiveScript *iface)
{
return CONTAINING_RECORD(iface, VBScript, IActiveScript_iface);
}
static HRESULT WINAPI VBScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
{
VBScript *This = impl_from_IActiveScript(iface);
if(IsEqualGUID(riid, &IID_IUnknown)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IActiveScript_iface;
}else if(IsEqualGUID(riid, &IID_IActiveScript)) {
TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv);
*ppv = &This->IActiveScript_iface;
}else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) {
TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv);
*ppv = &This->IActiveScriptParse_iface;
}else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure2)) {
TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This, ppv);
*ppv = &This->IActiveScriptParseProcedure2_iface;
}else if(IsEqualGUID(riid, &IID_IObjectSafety)) {
TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
*ppv = &This->IObjectSafety_iface;
}else {
FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI VBScript_AddRef(IActiveScript *iface)
{
VBScript *This = impl_from_IActiveScript(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI VBScript_Release(IActiveScript *iface)
{
VBScript *This = impl_from_IActiveScript(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", iface, ref);
if(!ref) {
if(This->ctx) {
decrease_state(This, SCRIPTSTATE_CLOSED);
destroy_script(This->ctx);
This->ctx = NULL;
}
if(This->site)
IActiveScriptSite_Release(This->site);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI VBScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
{
VBScript *This = impl_from_IActiveScript(iface);
LCID lcid;
HRESULT hres;
TRACE("(%p)->(%p)\n", This, pass);
if(!pass)
return E_POINTER;
if(This->site)
return E_UNEXPECTED;
if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
return E_UNEXPECTED;
This->site = pass;
IActiveScriptSite_AddRef(This->site);
hres = IActiveScriptSite_GetLCID(This->site, &lcid);
if(hres == S_OK)
This->lcid = lcid;
return This->ctx ? set_ctx_site(This) : S_OK;
}
static HRESULT WINAPI VBScript_GetScriptSite(IActiveScript *iface, REFIID riid,
void **ppvObject)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
{
VBScript *This = impl_from_IActiveScript(iface);
TRACE("(%p)->(%d)\n", This, ss);
if(This->thread_id && GetCurrentThreadId() != This->thread_id)
return E_UNEXPECTED;
if(ss == SCRIPTSTATE_UNINITIALIZED) {
if(This->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED;
decrease_state(This, SCRIPTSTATE_UNINITIALIZED);
return S_OK;
}
if(!This->ctx)
return E_UNEXPECTED;
switch(ss) {
case SCRIPTSTATE_STARTED:
case SCRIPTSTATE_CONNECTED: /* FIXME */
if(This->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED;
exec_queued_code(This->ctx);
break;
case SCRIPTSTATE_INITIALIZED:
FIXME("unimplemented SCRIPTSTATE_INITIALIZED\n");
return S_OK;
default:
FIXME("unimplemented state %d\n", ss);
return E_NOTIMPL;
}
change_state(This, ss);
return S_OK;
}
static HRESULT WINAPI VBScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
{
VBScript *This = impl_from_IActiveScript(iface);
TRACE("(%p)->(%p)\n", This, pssState);
if(!pssState)
return E_POINTER;
if(This->thread_id && This->thread_id != GetCurrentThreadId())
return E_UNEXPECTED;
*pssState = This->state;
return S_OK;
}
static HRESULT WINAPI VBScript_Close(IActiveScript *iface)
{
VBScript *This = impl_from_IActiveScript(iface);
TRACE("(%p)->()\n", This);
if(This->thread_id && This->thread_id != GetCurrentThreadId())
return E_UNEXPECTED;
decrease_state(This, SCRIPTSTATE_CLOSED);
return S_OK;
}
static HRESULT WINAPI VBScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstrName, DWORD dwFlags)
{
VBScript *This = impl_from_IActiveScript(iface);
named_item_t *item;
IDispatch *disp = NULL;
HRESULT hres;
TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED;
if(dwFlags & SCRIPTITEM_GLOBALMEMBERS) {
IUnknown *unk;
hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL);
if(FAILED(hres)) {
WARN("GetItemInfo failed: %08x\n", hres);
return hres;
}
hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
IUnknown_Release(unk);
if(FAILED(hres)) {
WARN("object does not implement IDispatch\n");
return hres;
}
if(This->ctx->host_global)
IDispatch_Release(This->ctx->host_global);
IDispatch_AddRef(disp);
This->ctx->host_global = disp;
}
item = heap_alloc(sizeof(*item));
if(!item) {
if(disp)
IDispatch_Release(disp);
return E_OUTOFMEMORY;
}
item->disp = disp;
item->flags = dwFlags;
item->name = heap_strdupW(pstrName);
if(!item->name) {
if(disp)
IDispatch_Release(disp);
heap_free(item);
return E_OUTOFMEMORY;
}
list_add_tail(&This->ctx->named_items, &item->entry);
return S_OK;
}
static HRESULT WINAPI VBScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName, IDispatch **ppdisp)
{
VBScript *This = impl_from_IActiveScript(iface);
TRACE("(%p)->(%p)\n", This, ppdisp);
if(!ppdisp)
return E_POINTER;
if(This->thread_id != GetCurrentThreadId() || !This->ctx || !This->ctx->script_obj) {
*ppdisp = NULL;
return E_UNEXPECTED;
}
*ppdisp = (IDispatch*)&This->ctx->script_obj->IDispatchEx_iface;
IDispatch_AddRef(*ppdisp);
return S_OK;
}
static HRESULT WINAPI VBScript_GetCurrentScriptThreadID(IActiveScript *iface,
SCRIPTTHREADID *pstridThread)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScript_GetScriptThreadID(IActiveScript *iface,
DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScript_GetScriptThreadState(IActiveScript *iface,
SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScript_InterruptScriptThread(IActiveScript *iface,
SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
{
VBScript *This = impl_from_IActiveScript(iface);
FIXME("(%p)->()\n", This);
return E_NOTIMPL;
}
static const IActiveScriptVtbl VBScriptVtbl = {
VBScript_QueryInterface,
VBScript_AddRef,
VBScript_Release,
VBScript_SetScriptSite,
VBScript_GetScriptSite,
VBScript_SetScriptState,
VBScript_GetScriptState,
VBScript_Close,
VBScript_AddNamedItem,
VBScript_AddTypeLib,
VBScript_GetScriptDispatch,
VBScript_GetCurrentScriptThreadID,
VBScript_GetScriptThreadID,
VBScript_GetScriptThreadState,
VBScript_InterruptScriptThread,
VBScript_Clone
};
static inline VBScript *impl_from_IActiveScriptParse(IActiveScriptParse *iface)
{
return CONTAINING_RECORD(iface, VBScript, IActiveScriptParse_iface);
}
static HRESULT WINAPI VBScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
}
static ULONG WINAPI VBScriptParse_AddRef(IActiveScriptParse *iface)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
return IActiveScript_AddRef(&This->IActiveScript_iface);
}
static ULONG WINAPI VBScriptParse_Release(IActiveScriptParse *iface)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
return IActiveScript_Release(&This->IActiveScript_iface);
}
static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
script_ctx_t *ctx, *old_ctx;
TRACE("(%p)\n", This);
if(This->ctx)
return E_UNEXPECTED;
ctx = heap_alloc_zero(sizeof(script_ctx_t));
if(!ctx)
return E_OUTOFMEMORY;
ctx->safeopt = This->safeopt;
heap_pool_init(&ctx->heap);
list_init(&ctx->objects);
list_init(&ctx->code_list);
list_init(&ctx->named_items);
old_ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
if(old_ctx) {
destroy_script(ctx);
return E_UNEXPECTED;
}
return This->site ? set_ctx_site(This) : S_OK;
}
static HRESULT WINAPI VBScriptParse_AddScriptlet(IActiveScriptParse *iface,
LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
BSTR *pbstrName, EXCEPINFO *pexcepinfo)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
FIXME("(%p)->(%s %s %s %s %s %s %s %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), wine_dbgstr_longlong(dwSourceContextCookie),
ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
return E_NOTIMPL;
}
static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface,
LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
vbscode_t *code;
HRESULT hres;
TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode),
debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLine, dwFlags, pvarResult, pexcepinfo);
if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED;
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code);
if(FAILED(hres))
return hres;
if(!is_started(This)) {
code->pending_exec = TRUE;
return S_OK;
}
return exec_global_code(This->ctx, code);
}
static const IActiveScriptParseVtbl VBScriptParseVtbl = {
VBScriptParse_QueryInterface,
VBScriptParse_AddRef,
VBScriptParse_Release,
VBScriptParse_InitNew,
VBScriptParse_AddScriptlet,
VBScriptParse_ParseScriptText
};
static inline VBScript *impl_from_IActiveScriptParseProcedure2(IActiveScriptParseProcedure2 *iface)
{
return CONTAINING_RECORD(iface, VBScript, IActiveScriptParseProcedure2_iface);
}
static HRESULT WINAPI VBScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
{
VBScript *This = impl_from_IActiveScriptParseProcedure2(iface);
return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
}
static ULONG WINAPI VBScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
{
VBScript *This = impl_from_IActiveScriptParseProcedure2(iface);
return IActiveScript_AddRef(&This->IActiveScript_iface);
}
static ULONG WINAPI VBScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
{
VBScript *This = impl_from_IActiveScriptParseProcedure2(iface);
return IActiveScript_Release(&This->IActiveScript_iface);
}
static HRESULT WINAPI VBScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
{
VBScript *This = impl_from_IActiveScriptParseProcedure2(iface);
vbscode_t *code;
HRESULT hres;
TRACE("(%p)->(%s %s %s %s %p %s %s %u %x %p)\n", This, debugstr_w(pstrCode), debugstr_w(pstrFormalParams),
debugstr_w(pstrProcedureName), debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLineNumber, dwFlags, ppdisp);
if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED)
return E_UNEXPECTED;
hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code);
if(FAILED(hres))
return hres;
return create_procedure_disp(This->ctx, code, ppdisp);
}
static const IActiveScriptParseProcedure2Vtbl VBScriptParseProcedureVtbl = {
VBScriptParseProcedure_QueryInterface,
VBScriptParseProcedure_AddRef,
VBScriptParseProcedure_Release,
VBScriptParseProcedure_ParseProcedureText,
};
static inline VBScript *impl_from_IObjectSafety(IObjectSafety *iface)
{
return CONTAINING_RECORD(iface, VBScript, IObjectSafety_iface);
}
static HRESULT WINAPI VBScriptSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
{
VBScript *This = impl_from_IObjectSafety(iface);
return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv);
}
static ULONG WINAPI VBScriptSafety_AddRef(IObjectSafety *iface)
{
VBScript *This = impl_from_IObjectSafety(iface);
return IActiveScript_AddRef(&This->IActiveScript_iface);
}
static ULONG WINAPI VBScriptSafety_Release(IObjectSafety *iface)
{
VBScript *This = impl_from_IObjectSafety(iface);
return IActiveScript_Release(&This->IActiveScript_iface);
}
#define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
static HRESULT WINAPI VBScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{
VBScript *This = impl_from_IObjectSafety(iface);
TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
if(!pdwSupportedOptions || !pdwEnabledOptions)
return E_POINTER;
*pdwSupportedOptions = SUPPORTED_OPTIONS;
*pdwEnabledOptions = This->safeopt;
return S_OK;
}
static HRESULT WINAPI VBScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
VBScript *This = impl_from_IObjectSafety(iface);
TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
return E_FAIL;
This->safeopt = (dwEnabledOptions & dwOptionSetMask) | (This->safeopt & ~dwOptionSetMask) | INTERFACE_USES_DISPEX;
return S_OK;
}
static const IObjectSafetyVtbl VBScriptSafetyVtbl = {
VBScriptSafety_QueryInterface,
VBScriptSafety_AddRef,
VBScriptSafety_Release,
VBScriptSafety_GetInterfaceSafetyOptions,
VBScriptSafety_SetInterfaceSafetyOptions
};
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
VBScript *ret;
HRESULT hres;
TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
ret = heap_alloc_zero(sizeof(*ret));
if(!ret)
return E_OUTOFMEMORY;
ret->IActiveScript_iface.lpVtbl = &VBScriptVtbl;
ret->IActiveScriptParse_iface.lpVtbl = &VBScriptParseVtbl;
ret->IActiveScriptParseProcedure2_iface.lpVtbl = &VBScriptParseProcedureVtbl;
ret->IObjectSafety_iface.lpVtbl = &VBScriptSafetyVtbl;
ret->ref = 1;
ret->state = SCRIPTSTATE_UNINITIALIZED;
ret->safeopt = INTERFACE_USES_DISPEX;
hres = IActiveScript_QueryInterface(&ret->IActiveScript_iface, riid, ppv);
IActiveScript_Release(&ret->IActiveScript_iface);
return hres;
}
typedef struct {
IServiceProvider IServiceProvider_iface;
LONG ref;
IServiceProvider *sp;
} AXSite;
static inline AXSite *impl_from_IServiceProvider(IServiceProvider *iface)
{
return CONTAINING_RECORD(iface, AXSite, IServiceProvider_iface);
}
static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
{
AXSite *This = impl_from_IServiceProvider(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = &This->IServiceProvider_iface;
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
*ppv = &This->IServiceProvider_iface;
}else {
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
{
AXSite *This = impl_from_IServiceProvider(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
{
AXSite *This = impl_from_IServiceProvider(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref)
heap_free(This);
return ref;
}
static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
REFGUID guidService, REFIID riid, void **ppv)
{
AXSite *This = impl_from_IServiceProvider(iface);
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
}
static IServiceProviderVtbl AXSiteVtbl = {
AXSite_QueryInterface,
AXSite_AddRef,
AXSite_Release,
AXSite_QueryService
};
IUnknown *create_ax_site(script_ctx_t *ctx)
{
IServiceProvider *sp;
AXSite *ret;
HRESULT hres;
hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
if(FAILED(hres)) {
ERR("Could not get IServiceProvider iface: %08x\n", hres);
return NULL;
}
ret = heap_alloc(sizeof(*ret));
if(!ret) {
IServiceProvider_Release(sp);
return NULL;
}
ret->IServiceProvider_iface.lpVtbl = &AXSiteVtbl;
ret->ref = 1;
ret->sp = sp;
return (IUnknown*)&ret->IServiceProvider_iface;
}

View file

@ -0,0 +1,412 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#define COBJMACROS
#include <windef.h>
#include <winbase.h>
#include <ole2.h>
#include <dispex.h>
#include <activscp.h>
#include <vbscript_classes.h>
#include <wine/list.h>
#include <wine/unicode.h>
typedef struct {
void **blocks;
DWORD block_cnt;
DWORD last_block;
DWORD offset;
BOOL mark;
struct list custom_blocks;
} heap_pool_t;
void heap_pool_init(heap_pool_t*) DECLSPEC_HIDDEN;
void *heap_pool_alloc(heap_pool_t*,size_t) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN;
void *heap_pool_grow(heap_pool_t*,void*,DWORD,DWORD) DECLSPEC_HIDDEN;
void heap_pool_clear(heap_pool_t*) DECLSPEC_HIDDEN;
void heap_pool_free(heap_pool_t*) DECLSPEC_HIDDEN;
heap_pool_t *heap_pool_mark(heap_pool_t*) DECLSPEC_HIDDEN;
typedef struct _function_t function_t;
typedef struct _vbscode_t vbscode_t;
typedef struct _script_ctx_t script_ctx_t;
typedef struct _vbdisp_t vbdisp_t;
typedef struct named_item_t {
IDispatch *disp;
DWORD flags;
LPWSTR name;
struct list entry;
} named_item_t;
typedef enum {
VBDISP_CALLGET,
VBDISP_LET,
VBDISP_SET,
VBDISP_ANY
} vbdisp_invoke_type_t;
typedef struct {
BOOL is_public;
const WCHAR *name;
} vbdisp_prop_desc_t;
typedef struct {
const WCHAR *name;
BOOL is_public;
function_t *entries[VBDISP_ANY];
} vbdisp_funcprop_desc_t;
#define BP_GET 1
#define BP_GETPUT 2
typedef struct {
DISPID id;
HRESULT (*proc)(vbdisp_t*,VARIANT*,unsigned,VARIANT*);
DWORD flags;
unsigned min_args;
UINT_PTR max_args;
} builtin_prop_t;
typedef struct _class_desc_t {
const WCHAR *name;
script_ctx_t *ctx;
unsigned class_initialize_id;
unsigned class_terminate_id;
unsigned func_cnt;
vbdisp_funcprop_desc_t *funcs;
unsigned prop_cnt;
vbdisp_prop_desc_t *props;
unsigned builtin_prop_cnt;
const builtin_prop_t *builtin_props;
ITypeInfo *typeinfo;
function_t *value_func;
struct _class_desc_t *next;
} class_desc_t;
struct _vbdisp_t {
IDispatchEx IDispatchEx_iface;
LONG ref;
BOOL terminator_ran;
struct list entry;
const class_desc_t *desc;
VARIANT props[1];
};
typedef struct _ident_map_t ident_map_t;
typedef struct {
IDispatchEx IDispatchEx_iface;
LONG ref;
ident_map_t *ident_map;
unsigned ident_map_cnt;
unsigned ident_map_size;
script_ctx_t *ctx;
} ScriptDisp;
HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**) DECLSPEC_HIDDEN;
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
HRESULT vbdisp_get_id(vbdisp_t*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*) DECLSPEC_HIDDEN;
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*) DECLSPEC_HIDDEN;
void collect_objects(script_ctx_t*) DECLSPEC_HIDDEN;
HRESULT create_procedure_disp(script_ctx_t*,vbscode_t*,IDispatch**) DECLSPEC_HIDDEN;
HRESULT create_script_disp(script_ctx_t*,ScriptDisp**) DECLSPEC_HIDDEN;
static inline unsigned arg_cnt(const DISPPARAMS *dp)
{
return dp->cArgs - dp->cNamedArgs;
}
static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
{
return dp->rgvarg + dp->cArgs-i-1;
}
typedef struct _dynamic_var_t {
struct _dynamic_var_t *next;
VARIANT v;
const WCHAR *name;
BOOL is_const;
} dynamic_var_t;
struct _script_ctx_t {
IActiveScriptSite *site;
LCID lcid;
IInternetHostSecurityManager *secmgr;
DWORD safeopt;
IDispatch *host_global;
ScriptDisp *script_obj;
class_desc_t global_desc;
vbdisp_t *global_obj;
class_desc_t err_desc;
vbdisp_t *err_obj;
dynamic_var_t *global_vars;
function_t *global_funcs;
class_desc_t *classes;
class_desc_t *procs;
heap_pool_t heap;
struct list objects;
struct list code_list;
struct list named_items;
};
HRESULT init_global(script_ctx_t*) DECLSPEC_HIDDEN;
HRESULT init_err(script_ctx_t*) DECLSPEC_HIDDEN;
IUnknown *create_ax_site(script_ctx_t*) DECLSPEC_HIDDEN;
typedef enum {
ARG_NONE = 0,
ARG_STR,
ARG_BSTR,
ARG_INT,
ARG_UINT,
ARG_ADDR,
ARG_DOUBLE
} instr_arg_type_t;
#define OP_LIST \
X(add, 1, 0, 0) \
X(and, 1, 0, 0) \
X(assign_ident, 1, ARG_BSTR, ARG_UINT) \
X(assign_member, 1, ARG_BSTR, ARG_UINT) \
X(bool, 1, ARG_INT, 0) \
X(case, 0, ARG_ADDR, 0) \
X(concat, 1, 0, 0) \
X(const, 1, ARG_BSTR, 0) \
X(div, 1, 0, 0) \
X(double, 1, ARG_DOUBLE, 0) \
X(empty, 1, 0, 0) \
X(enumnext, 0, ARG_ADDR, ARG_BSTR) \
X(equal, 1, 0, 0) \
X(errmode, 1, ARG_INT, 0) \
X(eqv, 1, 0, 0) \
X(exp, 1, 0, 0) \
X(gt, 1, 0, 0) \
X(gteq, 1, 0, 0) \
X(icall, 1, ARG_BSTR, ARG_UINT) \
X(icallv, 1, ARG_BSTR, ARG_UINT) \
X(idiv, 1, 0, 0) \
X(imp, 1, 0, 0) \
X(incc, 1, ARG_BSTR, 0) \
X(is, 1, 0, 0) \
X(jmp, 0, ARG_ADDR, 0) \
X(jmp_false, 0, ARG_ADDR, 0) \
X(jmp_true, 0, ARG_ADDR, 0) \
X(long, 1, ARG_INT, 0) \
X(lt, 1, 0, 0) \
X(lteq, 1, 0, 0) \
X(mcall, 1, ARG_BSTR, ARG_UINT) \
X(mcallv, 1, ARG_BSTR, ARG_UINT) \
X(me, 1, 0, 0) \
X(mod, 1, 0, 0) \
X(mul, 1, 0, 0) \
X(neg, 1, 0, 0) \
X(nequal, 1, 0, 0) \
X(new, 1, ARG_STR, 0) \
X(newenum, 1, 0, 0) \
X(not, 1, 0, 0) \
X(nothing, 1, 0, 0) \
X(null, 1, 0, 0) \
X(or, 1, 0, 0) \
X(pop, 1, ARG_UINT, 0) \
X(ret, 0, 0, 0) \
X(set_ident, 1, ARG_BSTR, ARG_UINT) \
X(set_member, 1, ARG_BSTR, ARG_UINT) \
X(short, 1, ARG_INT, 0) \
X(step, 0, ARG_ADDR, ARG_BSTR) \
X(stop, 1, 0, 0) \
X(string, 1, ARG_STR, 0) \
X(sub, 1, 0, 0) \
X(val, 1, 0, 0) \
X(xor, 1, 0, 0)
typedef enum {
#define X(x,n,a,b) OP_##x,
OP_LIST
#undef X
OP_LAST
} vbsop_t;
typedef union {
const WCHAR *str;
BSTR bstr;
unsigned uint;
LONG lng;
double *dbl;
} instr_arg_t;
typedef struct {
vbsop_t op;
instr_arg_t arg1;
instr_arg_t arg2;
} instr_t;
typedef struct {
const WCHAR *name;
BOOL by_ref;
} arg_desc_t;
typedef enum {
FUNC_GLOBAL,
FUNC_FUNCTION,
FUNC_SUB,
FUNC_PROPGET,
FUNC_PROPLET,
FUNC_PROPSET,
FUNC_DEFGET
} function_type_t;
typedef struct {
const WCHAR *name;
} var_desc_t;
struct _function_t {
function_type_t type;
const WCHAR *name;
BOOL is_public;
arg_desc_t *args;
unsigned arg_cnt;
var_desc_t *vars;
unsigned var_cnt;
unsigned code_off;
vbscode_t *code_ctx;
function_t *next;
};
struct _vbscode_t {
instr_t *instrs;
WCHAR *source;
BOOL option_explicit;
BOOL pending_exec;
function_t main_code;
BSTR *bstr_pool;
unsigned bstr_pool_size;
unsigned bstr_cnt;
heap_pool_t heap;
struct list entry;
};
void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
HRESULT exec_script(script_ctx_t*,function_t*,IDispatch*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN;
void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN;
typedef struct {
UINT16 len;
WCHAR buf[7];
} string_constant_t;
#define TID_LIST \
XDIID(ErrObj) \
XDIID(GlobalObj)
typedef enum {
#define XDIID(iface) iface ## _tid,
TID_LIST
#undef XDIID
LAST_tid
} tid_t;
HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
void release_regexp_typelib(void) DECLSPEC_HIDDEN;
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
static inline BOOL is_int32(double d)
{
return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
}
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
HRESULT WINAPI VBScriptRegExpFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
const char *debugstr_variant(const VARIANT*) DECLSPEC_HIDDEN;
static inline void *heap_alloc(size_t len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
}
static inline void *heap_alloc_zero(size_t len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
static inline void *heap_realloc(void *mem, size_t len)
{
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
}
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
}
static inline LPWSTR heap_strdupW(LPCWSTR str)
{
LPWSTR ret = NULL;
if(str) {
DWORD size;
size = (strlenW(str)+1)*sizeof(WCHAR);
ret = heap_alloc(size);
if(ret)
memcpy(ret, str, size);
}
return ret;
}

View file

@ -0,0 +1,42 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windef.h>
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
/* @makedep: vbscript.rgs */
2 WINE_REGISTRY vbscript.rgs
3 WINE_REGISTRY vbsglobal.rgs
4 WINE_REGISTRY vbsregexp10.rgs
5 WINE_REGISTRY vbsregexp55.rgs
6 WINE_REGISTRY vbscript_classes.rgs
1 TYPELIB vbsglobal.tlb
2 TYPELIB vbsregexp10.tlb
3 TYPELIB vbsregexp55.tlb
#define WINE_FILEDESCRIPTION_STR "Wine VBScript"
#define WINE_FILENAME_STR "vbscript.dll"
#define WINE_FILEVERSION 5,8,7601,16978
#define WINE_FILEVERSION_STR "5.8.7601.16978"
#define WINE_PRODUCTVERSION 5,8,0,16978
#define WINE_PRODUCTVERSION_STR "5.8.7601.16978"
#include <wine/wine_common_ver.rc>

View file

@ -0,0 +1,82 @@
HKCR
{
NoRemove CLSID
{
'{B54F3741-5B07-11CF-A4B0-00AA004A55E8}'
{
'Implemented Categories'
{
'{f0b7a1a1-9847-11cf-8f20-00805f2cd064}'
'{f0b7a1a2-9847-11cf-8f20-00805f2cd064}'
}
OLEScript
}
'{B54F3742-5B07-11CF-A4B0-00AA004A55E8}'
{
'Implemented Categories'
{
'{0aee2a92-bcbb-11d0-8c72-00c04fc2b085}'
}
OLEScript
}
'{B54F3743-5B07-11CF-A4B0-00AA004A55E8}'
{
'Implemented Categories'
{
'{f0b7a1a1-9847-11cf-8f20-00805f2cd064}'
'{f0b7a1a2-9847-11cf-8f20-00805f2cd064}'
'{f0b7a1a3-9847-11cf-8f20-00805f2cd064}'
}
OLEScript
}
}
'VBS' = s 'VB Script Language'
{
CLSID = s '{B54F3741-5B07-11CF-A4B0-00AA004A55E8}'
OLEScript
}
'VBS Author' = s 'VB Script Language Authoring'
{
CLSID = s '{B54F3742-5B07-11CF-A4B0-00AA004A55E8}'
OLEScript
}
'VBScript'
{
OLEScript
}
'VBScript Author'
{
OLEScript
}
'VBScript.Encode'
{
OLEScript
}
'VBScript.RegExp'
{
OLEScript
}
ForceRemove VBSFile = s 'VBScript Script File'
{
ScriptEngine = s 'VBScript'
Shell = s 'Open'
{
Edit
{
Command = s '"%%SystemRoot%%\system32\notepad.exe" %%1'
}
Open
{
Command = s '"%%SystemRoot%%\system32\wscript.exe" "%%1" %%*'
}
Open2
{
Command = s '"%%SystemRoot%%\system32\cscript.exe" "%%1" %%*'
}
Print
{
Command = s '"%%SystemRoot%%\system32\notepad.exe" /p %%1'
}
}
}
}

View file

@ -0,0 +1,4 @@
@ stdcall -private DllCanUnloadNow()
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()

View file

@ -0,0 +1,50 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
[
helpstring("VBScript Regular Expression"),
threading(apartment),
progid("VBScript.RegExp"),
version(5.5),
uuid(3f4daca4-160d-11d2-a8e9-00104b365c9f)
]
coclass VBScriptRegExp {}
[
helpstring("VB Script Language"),
threading(both),
progid("VBScript"),
uuid(b54f3741-5b07-11cf-a4b0-00aa004a55e8)
]
coclass VBScript {}
[
helpstring("VB Script Language Authoring"),
threading(both),
progid("VBScript Author"),
uuid(b54f3742-5b07-11cf-a4b0-00aa004a55e8)
]
coclass VBScriptAuthor {}
[
helpstring("VB Script Language Encoding"),
threading(both),
progid("VBScript.Encode"),
uuid(b54f3743-5b07-11cf-a4b0-00aa004a55e8)
]
coclass VBScriptEncode {}

View file

@ -0,0 +1,46 @@
HKCR
{
NoRemove Interface
{
}
NoRemove CLSID
{
'{3F4DACA4-160D-11D2-A8E9-00104B365C9F}' = s 'VBScript Regular Expression'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' }
ProgId = s 'VBScript.RegExp'
Version = s '5.5'
}
'{B54F3741-5B07-11CF-A4B0-00AA004A55E8}' = s 'VB Script Language'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'VBScript'
}
'{B54F3742-5B07-11CF-A4B0-00AA004A55E8}' = s 'VB Script Language Authoring'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'VBScript Author'
}
'{B54F3743-5B07-11CF-A4B0-00AA004A55E8}' = s 'VB Script Language Encoding'
{
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
ProgId = s 'VBScript.Encode'
}
}
'VBScript.RegExp' = s 'VBScript Regular Expression'
{
CLSID = s '{3F4DACA4-160D-11D2-A8E9-00104B365C9F}'
}
'VBScript' = s 'VB Script Language'
{
CLSID = s '{B54F3741-5B07-11CF-A4B0-00AA004A55E8}'
}
'VBScript Author' = s 'VB Script Language Authoring'
{
CLSID = s '{B54F3742-5B07-11CF-A4B0-00AA004A55E8}'
}
'VBScript.Encode' = s 'VB Script Language Encoding'
{
CLSID = s '{B54F3743-5B07-11CF-A4B0-00AA004A55E8}'
}
}

View file

@ -0,0 +1,236 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define DISPID_GLOBAL_VBUSESYSTEM 0
#define DISPID_GLOBAL_USESYSTEMDAYOFWEEK 1
#define DISPID_GLOBAL_VBSUNDAY 2
#define DISPID_GLOBAL_VBMONDAY 3
#define DISPID_GLOBAL_VBTUESDAY 4
#define DISPID_GLOBAL_VBWEDNESDAY 5
#define DISPID_GLOBAL_VBTHURSDAY 6
#define DISPID_GLOBAL_VBFRIDAY 7
#define DISPID_GLOBAL_VBSATURDAY 8
#define DISPID_GLOBAL_VBFIRSTJAN1 9
#define DISPID_GLOBAL_VBFIRSTFOURDAYS 10
#define DISPID_GLOBAL_VBFIRSTFULLWEEK 11
#define DISPID_GLOBAL_VBOKONLY 12
#define DISPID_GLOBAL_VBOKCANCEL 13
#define DISPID_GLOBAL_VBABORTRETRYIGNORE 14
#define DISPID_GLOBAL_VBYESNOCANCEL 15
#define DISPID_GLOBAL_VBYESNO 16
#define DISPID_GLOBAL_VBRETRYCANCEL 17
#define DISPID_GLOBAL_VBCRITICAL 18
#define DISPID_GLOBAL_VBQUESTION 19
#define DISPID_GLOBAL_VBEXCLAMATION 20
#define DISPID_GLOBAL_VBINFORMATION 21
#define DISPID_GLOBAL_VBDEFAULTBUTTON1 22
#define DISPID_GLOBAL_VBDEFAULTBUTTON2 23
#define DISPID_GLOBAL_VBDEFAULTBUTTON3 24
#define DISPID_GLOBAL_VBDEFAULTBUTTON4 25
#define DISPID_GLOBAL_VBAPPLICATIONMODAL 26
#define DISPID_GLOBAL_VBSYSTEMMODAL 27
#define DISPID_GLOBAL_VBOK 28
#define DISPID_GLOBAL_VBCANCEL 29
#define DISPID_GLOBAL_VBABORT 30
#define DISPID_GLOBAL_VBRETRY 31
#define DISPID_GLOBAL_VBIGNORE 32
#define DISPID_GLOBAL_VBYES 33
#define DISPID_GLOBAL_VBNO 34
#define DISPID_GLOBAL_VBEMPTY 35
#define DISPID_GLOBAL_VBNULL 36
#define DISPID_GLOBAL_VBINTEGER 37
#define DISPID_GLOBAL_VBLONG 38
#define DISPID_GLOBAL_VBSINGLE 39
#define DISPID_GLOBAL_VBDOUBLE 40
#define DISPID_GLOBAL_VBCURRENCY 41
#define DISPID_GLOBAL_VBDATE 42
#define DISPID_GLOBAL_VBSTRING 43
#define DISPID_GLOBAL_VBOBJECT 44
#define DISPID_GLOBAL_VBERROR 45
#define DISPID_GLOBAL_VBBOOLEAN 46
#define DISPID_GLOBAL_VBVARIANT 47
#define DISPID_GLOBAL_VBDATAOBJECT 48
#define DISPID_GLOBAL_VBDECIMAL 49
#define DISPID_GLOBAL_VBBYTE 50
#define DISPID_GLOBAL_VBARRAY 51
#define DISPID_GLOBAL_VBTRUE 52
#define DISPID_GLOBAL_VBFALSE 53
#define DISPID_GLOBAL_VBUSEDEFAULT 54
#define DISPID_GLOBAL_VBBINARYCOMPARE 55
#define DISPID_GLOBAL_VBTEXTCOMPARE 56
#define DISPID_GLOBAL_VBDATABASECOMPARE 57
#define DISPID_GLOBAL_VBGENERALDATE 58
#define DISPID_GLOBAL_VBLONGDATE 59
#define DISPID_GLOBAL_VBSHORTDATE 60
#define DISPID_GLOBAL_VBLONGTIME 61
#define DISPID_GLOBAL_VBSHORTTIME 62
#define DISPID_GLOBAL_VBOBJECTERROR 63
#define DISPID_GLOBAL_VBBLACK 64
#define DISPID_GLOBAL_VBBLUE 65
#define DISPID_GLOBAL_VBCYAN 66
#define DISPID_GLOBAL_VBGREEN 67
#define DISPID_GLOBAL_VBMAGENTA 68
#define DISPID_GLOBAL_VBRED 69
#define DISPID_GLOBAL_VBWHITE 70
#define DISPID_GLOBAL_VBYELLOW 71
#define DISPID_GLOBAL_VBCR 72
#define DISPID_GLOBAL_VBCRLF 73
#define DISPID_GLOBAL_VBNEWLINE 74
#define DISPID_GLOBAL_VBFORMFEED 75
#define DISPID_GLOBAL_VBLF 76
#define DISPID_GLOBAL_VBNULLCHAR 77
#define DISPID_GLOBAL_VBNULLSTRING 78
#define DISPID_GLOBAL_VBTAB 79
#define DISPID_GLOBAL_VBVERTICALTAB 80
#define DISPID_GLOBAL_VBMSGBOXHELPBUTTON 207
#define DISPID_GLOBAL_VBMSGBOXSETFOREGROUND 208
#define DISPID_GLOBAL_VBMSGBOXRIGHT 209
#define DISPID_GLOBAL_VBMSGBOXRTLREADING 210
#define DISPID_GLOBAL_CCUR 100
#define DISPID_GLOBAL_CINT 101
#define DISPID_GLOBAL_CLNG 102
#define DISPID_GLOBAL_CBOOL 103
#define DISPID_GLOBAL_CBYTE 104
#define DISPID_GLOBAL_CDATE 105
#define DISPID_GLOBAL_CDBL 106
#define DISPID_GLOBAL_CSNG 107
#define DISPID_GLOBAL_CSTR 108
#define DISPID_GLOBAL_HEX 109
#define DISPID_GLOBAL_OCT 110
#define DISPID_GLOBAL_VARTYPE 111
#define DISPID_GLOBAL_ISDATE 112
#define DISPID_GLOBAL_ISEMPTY 113
#define DISPID_GLOBAL_ISNULL 114
#define DISPID_GLOBAL_ISNUMERIC 115
#define DISPID_GLOBAL_ISARRAY 116
#define DISPID_GLOBAL_ISOBJECT 117
#define DISPID_GLOBAL_ATN 118
#define DISPID_GLOBAL_COS 119
#define DISPID_GLOBAL_SIN 120
#define DISPID_GLOBAL_TAN 121
#define DISPID_GLOBAL_EXP 122
#define DISPID_GLOBAL_LOG 123
#define DISPID_GLOBAL_SQR 124
#define DISPID_GLOBAL_RANDOMIZE 125
#define DISPID_GLOBAL_RND 126
#define DISPID_GLOBAL_TIMER 127
#define DISPID_GLOBAL_LBOUND 128
#define DISPID_GLOBAL_UBOUND 129
#define DISPID_GLOBAL_RGB 130
#define DISPID_GLOBAL_LEN 131
#define DISPID_GLOBAL_LENB 132
#define DISPID_GLOBAL_LEFT 133
#define DISPID_GLOBAL_LEFTB 134
#define DISPID_GLOBAL_RIGHT 135
#define DISPID_GLOBAL_RIGHTB 136
#define DISPID_GLOBAL_MID 137
#define DISPID_GLOBAL_MIDB 138
#define DISPID_GLOBAL_STRCOMP 139
#define DISPID_GLOBAL_LCASE 140
#define DISPID_GLOBAL_UCASE 141
#define DISPID_GLOBAL_LTRIM 142
#define DISPID_GLOBAL_RTRIM 143
#define DISPID_GLOBAL_TRIM 144
#define DISPID_GLOBAL_SPACE 145
#define DISPID_GLOBAL_STRING 146
#define DISPID_GLOBAL_INSTR 147
#define DISPID_GLOBAL_INSTRB 148
#define DISPID_GLOBAL_ASCB 149
#define DISPID_GLOBAL_CHRB 150
#define DISPID_GLOBAL_ASC 151
#define DISPID_GLOBAL_CHR 152
#define DISPID_GLOBAL_ASCW 153
#define DISPID_GLOBAL_CHRW 154
#define DISPID_GLOBAL_ABS 155
#define DISPID_GLOBAL_FIX 156
#define DISPID_GLOBAL_INT 157
#define DISPID_GLOBAL_SGN 158
#define DISPID_GLOBAL_NOW 159
#define DISPID_GLOBAL_DATE 160
#define DISPID_GLOBAL_TIME 161
#define DISPID_GLOBAL_DAY 162
#define DISPID_GLOBAL_MONTH 163
#define DISPID_GLOBAL_WEEKDAY 164
#define DISPID_GLOBAL_YEAR 165
#define DISPID_GLOBAL_HOUR 166
#define DISPID_GLOBAL_MINUTE 167
#define DISPID_GLOBAL_SECOND 168
#define DISPID_GLOBAL_DATEVALUE 169
#define DISPID_GLOBAL_TIMEVALUE 170
#define DISPID_GLOBAL_DATESERIAL 171
#define DISPID_GLOBAL_TIMESERIAL 172
#define DISPID_GLOBAL_INPUTBOX 173
#define DISPID_GLOBAL_MSGBOX 174
#define DISPID_GLOBAL_CREATEOBJECT 175
#define DISPID_GLOBAL_GETOBJECT 176
#define DISPID_GLOBAL_DATEADD 177
#define DISPID_GLOBAL_DATEDIFF 178
#define DISPID_GLOBAL_DATEPART 179
#define DISPID_GLOBAL_TYPENAME 180
#define DISPID_GLOBAL_ARRAY 181
#define DISPID_GLOBAL_ERASE 182
#define DISPID_GLOBAL_FILTER 183
#define DISPID_GLOBAL_JOIN 184
#define DISPID_GLOBAL_SPLIT 185
#define DISPID_GLOBAL_REPLACE 186
#define DISPID_GLOBAL_STRREVERSE 187
#define DISPID_GLOBAL_INSTRREV 188
#define DISPID_GLOBAL_LOADPICTURE 189
#define DISPID_GLOBAL_SCRIPTENGINE 190
#define DISPID_GLOBAL_SCRIPTENGINEMAJORVERSION 191
#define DISPID_GLOBAL_SCRIPTENGINEMINORVERSION 192
#define DISPID_GLOBAL_SCRIPTENGINEBUILDVERSION 193
#define DISPID_GLOBAL_FORMATNUMBER 194
#define DISPID_GLOBAL_FORMATCURRENCY 195
#define DISPID_GLOBAL_FORMATPERCENT 196
#define DISPID_GLOBAL_FORMATDATETIME 197
#define DISPID_GLOBAL_WEEKDAYNAME 198
#define DISPID_GLOBAL_MONTHNAME 199
#define DISPID_GLOBAL_ROUND 200
#define DISPID_GLOBAL_ESCAPE 201
#define DISPID_GLOBAL_UNESCAPE 202
#define DISPID_GLOBAL_EVAL 203
#define DISPID_GLOBAL_EXECUTE 204
#define DISPID_GLOBAL_EXECUTEGLOBAL 205
#define DISPID_GLOBAL_GETREF 206
#define DISPID_ERR_DESCRIPTION 0
#define DISPID_ERR_HELPCONTEXT 1
#define DISPID_ERR_HELPFILE 2
#define DISPID_ERR_NUMBER 3
#define DISPID_ERR_SOURCE 4
#define DISPID_ERR_CLEAR 100
#define DISPID_ERR_RAISE 101
#define DISPID_SUBMATCHES_COUNT 1
#define DISPID_MATCHCOLLECTION_COUNT 1
#define DISPID_MATCH_FIRSTINDEX 10001
#define DISPID_MATCH_LENGTH 10002
#define DISPID_MATCH_SUBMATCHES 10003
#define DISPID_REGEXP_PATTERN 10001
#define DISPID_REGEXP_IGNORECASE 10002
#define DISPID_REGEXP_GLOBAL 10003
#define DISPID_REGEXP_EXECUTE 10004
#define DISPID_REGEXP_TEST 10005
#define DISPID_REGEXP_REPLACE 10006
#define DISPID_REGEXP_MULTILINE 10007

View file

@ -0,0 +1,383 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <initguid.h>
#include <vbscript.h>
#include <objsafe.h>
#include <mshtmhst.h>
#include <rpcproxy.h>
//#include "vbscript_classes.h"
#include "vbsglobal.h"
#include "vbsregexp55.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
WINE_DECLARE_DEBUG_CHANNEL(heap);
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
static HINSTANCE vbscript_hinstance;
static ITypeLib *typelib;
static ITypeInfo *typeinfos[LAST_tid];
static REFIID tid_ids[] = {
#define XDIID(iface) &DIID_ ## iface,
TID_LIST
#undef XDIID
};
HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
{
HRESULT hres;
if (!typelib) {
ITypeLib *tl;
static const WCHAR vbscript_dll1W[] = {'v','b','s','c','r','i','p','t','.','d','l','l','\\','1',0};
hres = LoadTypeLib(vbscript_dll1W, &tl);
if(FAILED(hres)) {
ERR("LoadRegTypeLib failed: %08x\n", hres);
return hres;
}
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
ITypeLib_Release(tl);
}
if(!typeinfos[tid]) {
ITypeInfo *ti;
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
if(FAILED(hres)) {
ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
return hres;
}
if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
ITypeInfo_Release(ti);
}
*typeinfo = typeinfos[tid];
return S_OK;
}
static void release_typelib(void)
{
unsigned i;
if(!typelib)
return;
for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) {
if(typeinfos[i])
ITypeInfo_Release(typeinfos[i]);
}
ITypeLib_Release(typelib);
}
const char *debugstr_variant(const VARIANT *v)
{
if(!v)
return "(null)";
if(V_ISBYREF(v))
return wine_dbg_sprintf("{V_BYREF -> %s}", debugstr_variant(V_BYREF(v)));
switch(V_VT(v)) {
case VT_EMPTY:
return "{VT_EMPTY}";
case VT_NULL:
return "{VT_NULL}";
case VT_I2:
return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v));
case VT_I4:
return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v));
case VT_UI4:
return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v));
case VT_R8:
return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v));
case VT_BSTR:
return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v)));
case VT_DISPATCH:
return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v));
case VT_BOOL:
return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v));
default:
return wine_dbg_sprintf("{vt %d}", V_VT(v));
}
}
#define MIN_BLOCK_SIZE 128
#define ARENA_FREE_FILLER 0xaa
static inline DWORD block_size(DWORD block)
{
return MIN_BLOCK_SIZE << block;
}
void heap_pool_init(heap_pool_t *heap)
{
memset(heap, 0, sizeof(*heap));
list_init(&heap->custom_blocks);
}
void *heap_pool_alloc(heap_pool_t *heap, size_t size)
{
struct list *list;
void *tmp;
size = (size+3)&~3;
if(!heap->block_cnt) {
if(!heap->blocks) {
heap->blocks = heap_alloc(sizeof(void*));
if(!heap->blocks)
return NULL;
}
tmp = heap_alloc(block_size(0));
if(!tmp)
return NULL;
heap->blocks[0] = tmp;
heap->block_cnt = 1;
}
if(heap->offset + size <= block_size(heap->last_block)) {
tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
heap->offset += size;
return tmp;
}
if(size <= block_size(heap->last_block+1)) {
if(heap->last_block+1 == heap->block_cnt) {
tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
if(!tmp)
return NULL;
heap->blocks = tmp;
heap->blocks[heap->block_cnt] = heap_alloc(block_size(heap->block_cnt));
if(!heap->blocks[heap->block_cnt])
return NULL;
heap->block_cnt++;
}
heap->last_block++;
heap->offset = size;
return heap->blocks[heap->last_block];
}
list = heap_alloc(size + sizeof(struct list));
if(!list)
return NULL;
list_add_head(&heap->custom_blocks, list);
return list+1;
}
void *heap_pool_grow(heap_pool_t *heap, void *mem, DWORD size, DWORD inc)
{
void *ret;
if(mem == (BYTE*)heap->blocks[heap->last_block] + heap->offset-size
&& heap->offset+inc < block_size(heap->last_block)) {
heap->offset += inc;
return mem;
}
ret = heap_pool_alloc(heap, size+inc);
if(ret) /* FIXME: avoid copying for custom blocks */
memcpy(ret, mem, size);
return ret;
}
void heap_pool_clear(heap_pool_t *heap)
{
struct list *tmp;
if(!heap)
return;
while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
list_remove(tmp);
heap_free(tmp);
}
if(WARN_ON(heap)) {
DWORD i;
for(i=0; i < heap->block_cnt; i++)
memset(heap->blocks[i], ARENA_FREE_FILLER, block_size(i));
}
heap->last_block = heap->offset = 0;
heap->mark = FALSE;
}
void heap_pool_free(heap_pool_t *heap)
{
DWORD i;
heap_pool_clear(heap);
for(i=0; i < heap->block_cnt; i++)
heap_free(heap->blocks[i]);
heap_free(heap->blocks);
heap_pool_init(heap);
}
heap_pool_t *heap_pool_mark(heap_pool_t *heap)
{
if(heap->mark)
return NULL;
heap->mark = TRUE;
return heap;
}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
*ppv = iface;
}else if(IsEqualGUID(&IID_IClassFactory, riid)) {
TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
*ppv = iface;
}
if(*ppv) {
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
return E_NOINTERFACE;
}
static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
{
TRACE("(%p)\n", iface);
return 2;
}
static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
TRACE("(%p)\n", iface);
return 1;
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
{
TRACE("(%p)->(%x)\n", iface, fLock);
return S_OK;
}
static const IClassFactoryVtbl VBScriptFactoryVtbl = {
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
VBScriptFactory_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory VBScriptFactory = { &VBScriptFactoryVtbl };
static const IClassFactoryVtbl VBScriptRegExpFactoryVtbl = {
ClassFactory_QueryInterface,
ClassFactory_AddRef,
ClassFactory_Release,
VBScriptRegExpFactory_CreateInstance,
ClassFactory_LockServer
};
static IClassFactory VBScriptRegExpFactory = { &VBScriptRegExpFactoryVtbl };
/******************************************************************
* DllMain (vbscript.@)
*/
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpv);
switch(fdwReason)
{
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstDLL);
vbscript_hinstance = hInstDLL;
break;
case DLL_PROCESS_DETACH:
release_typelib();
release_regexp_typelib();
}
return TRUE;
}
/***********************************************************************
* DllGetClassObject (vbscript.@)
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
if(IsEqualGUID(&CLSID_VBScript, rclsid)) {
TRACE("(CLSID_VBScript %s %p)\n", debugstr_guid(riid), ppv);
return IClassFactory_QueryInterface(&VBScriptFactory, riid, ppv);
}else if(IsEqualGUID(&CLSID_VBScriptRegExp, rclsid)) {
TRACE("(CLSID_VBScriptRegExp %s %p)\n", debugstr_guid(riid), ppv);
return IClassFactory_QueryInterface(&VBScriptRegExpFactory, riid, ppv);
}
FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
return CLASS_E_CLASSNOTAVAILABLE;
}
/***********************************************************************
* DllCanUnloadNow (vbscript.@)
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
return S_FALSE;
}
/***********************************************************************
* DllRegisterServer (vbscript.@)
*/
HRESULT WINAPI DllRegisterServer(void)
{
TRACE("()\n");
return __wine_register_resources(vbscript_hinstance);
}
/***********************************************************************
* DllUnregisterServer (vbscript.@)
*/
HRESULT WINAPI DllUnregisterServer(void)
{
TRACE("()\n");
return __wine_unregister_resources(vbscript_hinstance);
}

View file

@ -0,0 +1,755 @@
/*
* Copyright 2011 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
import "oaidl.idl";
#include "vbscript_defs.h"
[
helpstring("Microsoft VBScript Globals"),
uuid(3eef9758-35fc-11d1-8ce4-00c04fc2b185),
version(1.0)
]
library VBScript_Global
{
importlib("stdole2.tlb");
[
uuid(3eef9758-35fc-11d1-8ce4-00c04fc2B186)
]
dispinterface GlobalObj {
properties:
[id(DISPID_GLOBAL_VBUSESYSTEM), readonly]
VARIANT vbUseSystem;
[id(DISPID_GLOBAL_USESYSTEMDAYOFWEEK), readonly]
VARIANT vbUseSystemDayOfWeek;
[id(DISPID_GLOBAL_VBSUNDAY), readonly]
VARIANT vbSunday;
[id(DISPID_GLOBAL_VBMONDAY), readonly]
VARIANT vbMonday;
[id(DISPID_GLOBAL_VBTUESDAY), readonly]
VARIANT vbTuesday;
[id(DISPID_GLOBAL_VBWEDNESDAY), readonly]
VARIANT vbWednesday;
[id(DISPID_GLOBAL_VBTHURSDAY), readonly]
VARIANT vbThursday;
[id(DISPID_GLOBAL_VBFRIDAY), readonly]
VARIANT vbFriday;
[id(DISPID_GLOBAL_VBSATURDAY), readonly]
VARIANT vbSaturday;
[id(DISPID_GLOBAL_VBFIRSTJAN1), readonly]
VARIANT vbFirstJan1;
[id(DISPID_GLOBAL_VBFIRSTFOURDAYS), readonly]
VARIANT vbFirstFourDays;
[id(DISPID_GLOBAL_VBFIRSTFULLWEEK), readonly]
VARIANT vbFirstFullWeek;
[id(DISPID_GLOBAL_VBOKONLY), readonly]
VARIANT vbOKOnly;
[id(DISPID_GLOBAL_VBOKCANCEL), readonly]
VARIANT vbOKCancel;
[id(DISPID_GLOBAL_VBABORTRETRYIGNORE), readonly]
VARIANT vbAbortRetryIgnore;
[id(DISPID_GLOBAL_VBYESNOCANCEL), readonly]
VARIANT vbYesNoCancel;
[id(DISPID_GLOBAL_VBYESNO), readonly]
VARIANT vbYesNo;
[id(DISPID_GLOBAL_VBRETRYCANCEL), readonly]
VARIANT vbRetryCancel;
[id(DISPID_GLOBAL_VBCRITICAL), readonly]
VARIANT vbCritical;
[id(DISPID_GLOBAL_VBQUESTION), readonly]
VARIANT vbQuestion;
[id(DISPID_GLOBAL_VBEXCLAMATION), readonly]
VARIANT vbExclamation;
[id(DISPID_GLOBAL_VBINFORMATION), readonly]
VARIANT vbInformation;
[id(DISPID_GLOBAL_VBDEFAULTBUTTON1), readonly]
VARIANT vbDefaultButton1;
[id(DISPID_GLOBAL_VBDEFAULTBUTTON2), readonly]
VARIANT vbDefaultButton2;
[id(DISPID_GLOBAL_VBDEFAULTBUTTON3), readonly]
VARIANT vbDefaultButton3;
[id(DISPID_GLOBAL_VBDEFAULTBUTTON4), readonly]
VARIANT vbDefaultButton4;
[id(DISPID_GLOBAL_VBAPPLICATIONMODAL), readonly]
VARIANT vbApplicationModal;
[id(DISPID_GLOBAL_VBSYSTEMMODAL), readonly]
VARIANT vbSystemModal;
[id(DISPID_GLOBAL_VBOK), readonly]
VARIANT vbOK;
[id(DISPID_GLOBAL_VBCANCEL), readonly]
VARIANT vbCancel;
[id(DISPID_GLOBAL_VBABORT), readonly]
VARIANT vbAbort;
[id(DISPID_GLOBAL_VBRETRY), readonly]
VARIANT vbRetry;
[id(DISPID_GLOBAL_VBIGNORE), readonly]
VARIANT vbIgnore;
[id(DISPID_GLOBAL_VBYES), readonly]
VARIANT vbYes;
[id(DISPID_GLOBAL_VBNO), readonly]
VARIANT vbNo;
[id(DISPID_GLOBAL_VBEMPTY), readonly]
VARIANT vbEmpty;
[id(DISPID_GLOBAL_VBNULL), readonly]
VARIANT vbNull;
[id(DISPID_GLOBAL_VBINTEGER), readonly]
VARIANT vbInteger;
[id(DISPID_GLOBAL_VBLONG), readonly]
VARIANT vbLong;
[id(DISPID_GLOBAL_VBSINGLE), readonly]
VARIANT vbSingle;
[id(DISPID_GLOBAL_VBDOUBLE), readonly]
VARIANT vbDouble;
[id(DISPID_GLOBAL_VBCURRENCY), readonly]
VARIANT vbCurrency;
[id(DISPID_GLOBAL_VBDATE), readonly]
VARIANT vbDate;
[id(DISPID_GLOBAL_VBSTRING), readonly]
VARIANT vbString;
[id(DISPID_GLOBAL_VBOBJECT), readonly]
VARIANT vbObject;
[id(DISPID_GLOBAL_VBERROR), readonly]
VARIANT vbError;
[id(DISPID_GLOBAL_VBBOOLEAN), readonly]
VARIANT vbBoolean;
[id(DISPID_GLOBAL_VBVARIANT), readonly]
VARIANT vbVariant;
[id(DISPID_GLOBAL_VBDATAOBJECT), readonly]
VARIANT vbDataObject;
[id(DISPID_GLOBAL_VBDECIMAL), readonly]
VARIANT vbDecimal;
[id(DISPID_GLOBAL_VBBYTE), readonly]
VARIANT vbByte;
[id(DISPID_GLOBAL_VBARRAY), readonly]
VARIANT vbArray;
[id(DISPID_GLOBAL_VBTRUE), readonly]
VARIANT vbTrue;
[id(DISPID_GLOBAL_VBFALSE), readonly]
VARIANT vbFalse;
[id(DISPID_GLOBAL_VBUSEDEFAULT), readonly]
VARIANT vbUseDefault;
[id(DISPID_GLOBAL_VBBINARYCOMPARE), readonly]
VARIANT vbBinaryCompare;
[id(DISPID_GLOBAL_VBTEXTCOMPARE), readonly]
VARIANT vbTextCompare;
[id(DISPID_GLOBAL_VBDATABASECOMPARE), readonly]
VARIANT vbDatabaseCompare;
[id(DISPID_GLOBAL_VBGENERALDATE), readonly]
VARIANT vbGeneralDate;
[id(DISPID_GLOBAL_VBLONGDATE), readonly]
VARIANT vbLongDate;
[id(DISPID_GLOBAL_VBSHORTDATE), readonly]
VARIANT vbShortDate;
[id(DISPID_GLOBAL_VBLONGTIME), readonly]
VARIANT vbLongTime;
[id(DISPID_GLOBAL_VBSHORTTIME), readonly]
VARIANT vbShortTime;
[id(DISPID_GLOBAL_VBOBJECTERROR), readonly]
VARIANT vbObjectError;
[id(DISPID_GLOBAL_VBBLACK), readonly]
VARIANT vbBlack;
[id(DISPID_GLOBAL_VBBLUE), readonly]
VARIANT vbBlue;
[id(DISPID_GLOBAL_VBCYAN), readonly]
VARIANT vbCyan;
[id(DISPID_GLOBAL_VBGREEN), readonly]
VARIANT vbGreen;
[id(DISPID_GLOBAL_VBMAGENTA), readonly]
VARIANT vbMagenta;
[id(DISPID_GLOBAL_VBRED), readonly]
VARIANT vbRed;
[id(DISPID_GLOBAL_VBWHITE), readonly]
VARIANT vbWhite;
[id(DISPID_GLOBAL_VBYELLOW), readonly]
VARIANT vbYellow;
[id(DISPID_GLOBAL_VBCR), readonly]
VARIANT vbCr;
[id(DISPID_GLOBAL_VBCRLF), readonly]
VARIANT vbCrLf;
[id(DISPID_GLOBAL_VBNEWLINE), readonly]
VARIANT vbNewLine;
[id(DISPID_GLOBAL_VBFORMFEED), readonly]
VARIANT vbFormFeed;
[id(DISPID_GLOBAL_VBLF), readonly]
VARIANT vbLf;
[id(DISPID_GLOBAL_VBNULLCHAR), readonly]
VARIANT vbNullChar;
[id(DISPID_GLOBAL_VBNULLSTRING), readonly]
VARIANT vbNullString;
[id(DISPID_GLOBAL_VBTAB), readonly]
VARIANT vbTab;
[id(DISPID_GLOBAL_VBVERTICALTAB), readonly]
VARIANT vbVerticalTab;
[id(DISPID_GLOBAL_VBMSGBOXHELPBUTTON), readonly]
VARIANT vbMsgBoxHelpButton;
[id(DISPID_GLOBAL_VBMSGBOXSETFOREGROUND), readonly]
VARIANT vbMsgBoxSetForeground;
[id(DISPID_GLOBAL_VBMSGBOXRIGHT), readonly]
VARIANT vbMsgBoxRight;
[id(DISPID_GLOBAL_VBMSGBOXRTLREADING), readonly]
VARIANT vbMsgBoxRtlReading;
methods:
[id(DISPID_GLOBAL_CCUR)]
VARIANT CCur(VARIANT expression);
[id(DISPID_GLOBAL_CINT)]
VARIANT CInt(VARIANT expression);
[id(DISPID_GLOBAL_CLNG)]
VARIANT CLng(VARIANT expression);
[id(DISPID_GLOBAL_CBOOL)]
VARIANT CBool(VARIANT expression);
[id(DISPID_GLOBAL_CBYTE)]
VARIANT CByte(VARIANT expression);
[id(DISPID_GLOBAL_CDATE)]
VARIANT CDate(VARIANT expression);
[id(DISPID_GLOBAL_CDBL)]
VARIANT CDbl(VARIANT expression);
[id(DISPID_GLOBAL_CSNG)]
VARIANT CSng(VARIANT expression);
[id(DISPID_GLOBAL_CSTR)]
VARIANT CStr(VARIANT expression);
[id(DISPID_GLOBAL_HEX)]
VARIANT Hex(VARIANT number);
[id(DISPID_GLOBAL_OCT)]
VARIANT Oct(VARIANT number);
[id(DISPID_GLOBAL_VARTYPE)]
VARIANT VarType(VARIANT varname);
[id(DISPID_GLOBAL_ISDATE)]
VARIANT IsDate(VARIANT expression);
[id(DISPID_GLOBAL_ISEMPTY)]
VARIANT IsEmpty(VARIANT expression);
[id(DISPID_GLOBAL_ISNULL)]
VARIANT IsNull(VARIANT expression);
[id(DISPID_GLOBAL_ISNUMERIC)]
VARIANT IsNumeric(VARIANT expression);
[id(DISPID_GLOBAL_ISARRAY)]
VARIANT IsArray(VARIANT expression);
[id(DISPID_GLOBAL_ISOBJECT)]
VARIANT IsObject(VARIANT identifier);
[id(DISPID_GLOBAL_ATN)]
VARIANT Atn(VARIANT number);
[id(DISPID_GLOBAL_COS)]
VARIANT Cos(VARIANT number);
[id(DISPID_GLOBAL_SIN)]
VARIANT Sin(VARIANT number);
[id(DISPID_GLOBAL_TAN)]
VARIANT Tan(VARIANT number);
[id(DISPID_GLOBAL_EXP)]
VARIANT Exp(VARIANT number);
[id(DISPID_GLOBAL_LOG)]
VARIANT Log(VARIANT number);
[id(DISPID_GLOBAL_SQR)]
VARIANT Sqr(VARIANT number);
[id(DISPID_GLOBAL_RANDOMIZE)]
VARIANT Randomize(VARIANT number);
[id(DISPID_GLOBAL_RND)]
VARIANT Rnd(VARIANT number);
[id(DISPID_GLOBAL_TIMER)]
VARIANT Timer();
[id(DISPID_GLOBAL_LBOUND)]
VARIANT LBound(VARIANT arrayname);
[id(DISPID_GLOBAL_UBOUND)]
VARIANT UBound(VARIANT arrayname);
[id(DISPID_GLOBAL_RGB)]
VARIANT RGB(
VARIANT red,
VARIANT green,
VARIANT blue);
[id(DISPID_GLOBAL_LEN)]
VARIANT Len(VARIANT string);
[id(DISPID_GLOBAL_LENB)]
VARIANT LenB(VARIANT string);
[id(DISPID_GLOBAL_LEFT)]
VARIANT Left(
VARIANT string,
VARIANT length);
[id(DISPID_GLOBAL_LEFTB)]
VARIANT LeftB(
VARIANT string,
VARIANT length);
[id(DISPID_GLOBAL_RIGHT)]
VARIANT Right(
VARIANT string,
VARIANT length);
[id(DISPID_GLOBAL_RIGHTB)]
VARIANT RightB(
VARIANT string,
VARIANT length);
[id(DISPID_GLOBAL_MID)]
VARIANT Mid(
VARIANT string,
VARIANT start,
[optional] VARIANT length);
[id(DISPID_GLOBAL_MIDB)]
VARIANT MidB(
VARIANT string,
VARIANT start,
[optional] VARIANT length);
[id(DISPID_GLOBAL_STRCOMP)]
VARIANT StrComp(
VARIANT string1,
VARIANT string2,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_LCASE)]
VARIANT LCase(VARIANT string);
[id(DISPID_GLOBAL_UCASE)]
VARIANT UCase(VARIANT string);
[id(DISPID_GLOBAL_LTRIM)]
VARIANT LTrim(VARIANT string);
[id(DISPID_GLOBAL_RTRIM)]
VARIANT RTrim(VARIANT string);
[id(DISPID_GLOBAL_TRIM)]
VARIANT Trim(VARIANT string);
[id(DISPID_GLOBAL_SPACE)]
VARIANT Space(VARIANT number);
[id(DISPID_GLOBAL_STRING)]
VARIANT string(
[optional] VARIANT number,
[optional] VARIANT character);
[id(DISPID_GLOBAL_INSTR)]
VARIANT InStr(
VARIANT start,
VARIANT string,
VARIANT string2,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_INSTRB)]
VARIANT InStrB(
VARIANT start,
VARIANT string,
VARIANT string2,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_ASCB)]
VARIANT AscB(VARIANT string);
[id(DISPID_GLOBAL_CHRB)]
VARIANT ChrB(VARIANT charcode);
[id(DISPID_GLOBAL_ASC)]
VARIANT Asc(VARIANT string);
[id(DISPID_GLOBAL_CHR)]
VARIANT Chr(VARIANT charcode);
[id(DISPID_GLOBAL_ASCW)]
VARIANT AscW(VARIANT string);
[id(DISPID_GLOBAL_CHRW)]
VARIANT ChrW(VARIANT charcode);
[id(DISPID_GLOBAL_ABS)]
VARIANT Abs(VARIANT number);
[id(DISPID_GLOBAL_FIX)]
VARIANT Fix(VARIANT number);
[id(DISPID_GLOBAL_INT)]
VARIANT Int(VARIANT number);
[id(DISPID_GLOBAL_SGN)]
VARIANT Sgn(VARIANT number);
[id(DISPID_GLOBAL_NOW)]
VARIANT Now();
[id(DISPID_GLOBAL_DATE)]
VARIANT Date();
[id(DISPID_GLOBAL_TIME)]
VARIANT Time();
[id(DISPID_GLOBAL_DAY)]
VARIANT Day(VARIANT Date);
[id(DISPID_GLOBAL_MONTH)]
VARIANT Month(VARIANT Date);
[id(DISPID_GLOBAL_WEEKDAY)]
VARIANT Weekday(
VARIANT Date,
[optional] VARIANT firstdayofweek);
[id(DISPID_GLOBAL_YEAR)]
VARIANT Year(VARIANT Date);
[id(DISPID_GLOBAL_HOUR)]
VARIANT Hour(VARIANT Time);
[id(DISPID_GLOBAL_MINUTE)]
VARIANT Minute(VARIANT Time);
[id(DISPID_GLOBAL_SECOND)]
VARIANT Second(VARIANT Time);
[id(DISPID_GLOBAL_DATEVALUE)]
VARIANT DateValue(VARIANT Date);
[id(DISPID_GLOBAL_TIMEVALUE)]
VARIANT TimeValue(VARIANT Time);
[id(DISPID_GLOBAL_DATESERIAL)]
VARIANT DateSerial(
VARIANT Year,
VARIANT Month,
VARIANT Date);
[id(DISPID_GLOBAL_TIMESERIAL)]
VARIANT TimeSerial(
VARIANT Hour,
VARIANT Minute,
VARIANT Second);
[id(DISPID_GLOBAL_INPUTBOX)]
VARIANT InputBox(
VARIANT prompt,
[optional] VARIANT title,
[optional] VARIANT defaultValue,
[optional] VARIANT xpos,
[optional] VARIANT ypos,
[optional] VARIANT helpfile,
[optional] VARIANT context);
[id(DISPID_GLOBAL_MSGBOX)]
VARIANT MsgBox(
VARIANT prompt,
[optional] VARIANT buttons,
[optional] VARIANT title,
[optional] VARIANT helpfile,
[optional] VARIANT context);
[id(DISPID_GLOBAL_CREATEOBJECT)]
VARIANT CreateObject(VARIANT classValue);
[id(DISPID_GLOBAL_GETOBJECT)]
VARIANT GetObject(
[optional] VARIANT pathname,
[optional] VARIANT classValue);
[id(DISPID_GLOBAL_DATEADD)]
VARIANT DateAdd(
VARIANT interval,
VARIANT number,
VARIANT Date);
[id(DISPID_GLOBAL_DATEDIFF)]
VARIANT DateDiff(
VARIANT interval,
VARIANT date1,
VARIANT date2,
[optional] VARIANT firstdayofweek,
[optional] VARIANT firstdayofyear);
[id(DISPID_GLOBAL_DATEPART)]
VARIANT DatePart(
VARIANT interval,
VARIANT Date,
[optional] VARIANT firstdayofweek,
[optional] VARIANT firstdayofyear);
[id(DISPID_GLOBAL_TYPENAME)]
VARIANT TypeName(VARIANT varname);
[id(DISPID_GLOBAL_ARRAY)]
VARIANT Array(VARIANT arglist);
[id(DISPID_GLOBAL_ERASE)]
VARIANT Erase(VARIANT arraylist);
[id(DISPID_GLOBAL_FILTER)]
VARIANT Filter(
VARIANT InputStrings,
VARIANT Value,
[optional] VARIANT Include,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_JOIN)]
VARIANT Join(
VARIANT list,
[optional] VARIANT delimiter);
[id(DISPID_GLOBAL_SPLIT)]
VARIANT Split(
VARIANT expression,
[optional] VARIANT delimiter,
[optional] VARIANT count,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_REPLACE)]
VARIANT Replace(
VARIANT expression,
VARIANT find,
VARIANT replacement,
[optional] VARIANT start,
[optional] VARIANT count,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_STRREVERSE)]
VARIANT StrReverse(VARIANT string1);
[id(DISPID_GLOBAL_INSTRREV)]
VARIANT InStrRev(
VARIANT string1,
VARIANT string2,
[optional] VARIANT start,
[optional] VARIANT compare);
[id(DISPID_GLOBAL_LOADPICTURE)]
VARIANT LoadPicture([optional] VARIANT stringexpression);
[id(DISPID_GLOBAL_SCRIPTENGINE)]
VARIANT ScriptEngine();
[id(DISPID_GLOBAL_SCRIPTENGINEMAJORVERSION)]
VARIANT ScriptEngineMajorVersion();
[id(DISPID_GLOBAL_SCRIPTENGINEMINORVERSION)]
VARIANT ScriptEngineMinorVersion();
[id(DISPID_GLOBAL_SCRIPTENGINEBUILDVERSION)]
VARIANT ScriptEngineBuildVersion();
[id(DISPID_GLOBAL_FORMATNUMBER)]
VARIANT FormatNumber(
VARIANT expression,
[optional] VARIANT NumDigitsAfterDecimal,
[optional] VARIANT IncludeLeadingDigit,
[optional] VARIANT UseParensForNegativeNumbers,
[optional] VARIANT GroupDigits);
[id(DISPID_GLOBAL_FORMATCURRENCY)]
VARIANT FormatCurrency(
VARIANT expression,
[optional] VARIANT NumDigitsAfterDecimal,
[optional] VARIANT IncludeLeadingDigit,
[optional] VARIANT UseParensForNegativeNumbers,
[optional] VARIANT GroupDigits);
[id(DISPID_GLOBAL_FORMATPERCENT)]
VARIANT FormatPercent(
VARIANT expression,
[optional] VARIANT NumDigitsAfterDecimal,
[optional] VARIANT IncludeLeadingDigit,
[optional] VARIANT UseParensForNegativeNumbers,
[optional] VARIANT GroupDigits);
[id(DISPID_GLOBAL_FORMATDATETIME)]
VARIANT FormatDateTime(
VARIANT Date,
[optional] VARIANT NamedFormat);
[id(DISPID_GLOBAL_WEEKDAYNAME)]
VARIANT WeekdayName(
VARIANT Weekday,
VARIANT abbreviate,
VARIANT firstdayofweek);
[id(DISPID_GLOBAL_MONTHNAME)]
VARIANT MonthName(
VARIANT Month,
[optional] VARIANT abbreviate);
[id(DISPID_GLOBAL_ROUND)]
VARIANT Round(
VARIANT expression,
[optional] VARIANT numdecimalplaces);
[id(DISPID_GLOBAL_ESCAPE)]
VARIANT Escape(VARIANT string);
[id(DISPID_GLOBAL_UNESCAPE)]
VARIANT Unescape(VARIANT string);
[id(DISPID_GLOBAL_EVAL)]
VARIANT Eval(VARIANT string);
[id(DISPID_GLOBAL_EXECUTE)]
VARIANT Execute(VARIANT string);
[id(DISPID_GLOBAL_EXECUTEGLOBAL)]
VARIANT ExecuteGlobal(VARIANT string);
[id(DISPID_GLOBAL_GETREF)]
VARIANT GetRef(VARIANT string);
}
[
uuid(3eef9758-35fc-11d1-8ce4-00c04fc2b187)
]
dispinterface ErrObj {
properties:
[id(DISPID_ERR_DESCRIPTION)]
VARIANT Description;
[id(DISPID_ERR_HELPCONTEXT)]
VARIANT HelpContext;
[id(DISPID_ERR_HELPFILE)]
VARIANT helpfile;
[id(DISPID_ERR_NUMBER)]
VARIANT number;
[id(DISPID_ERR_SOURCE)]
VARIANT Source;
methods:
[id(DISPID_ERR_CLEAR)]
VARIANT Clear();
[id(DISPID_ERR_RAISE)]
VARIANT Raise(
VARIANT number,
VARIANT Source,
VARIANT Description,
VARIANT helpfile,
VARIANT HelpContext);
}
}

View file

@ -0,0 +1,32 @@
HKCR
{
NoRemove Typelib
{
NoRemove '{3EEF9758-35FC-11D1-8CE4-00C04FC2B185}'
{
'1.0' = s 'Microsoft VBScript Globals'
{
'0' { win32 = s '%MODULE%' }
FLAGS = s '0'
}
}
}
NoRemove Interface
{
'{3EEF9758-35FC-11D1-8CE4-00C04FC2B186}' = s 'GlobalObj'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3EEF9758-35FC-11D1-8CE4-00C04FC2B185}' { val Version = s '1.0' }
}
'{3EEF9758-35FC-11D1-8CE4-00C04FC2B187}' = s 'ErrObj'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3EEF9758-35FC-11D1-8CE4-00C04FC2B185}' { val Version = s '1.0' }
}
}
NoRemove CLSID
{
}
}

View file

@ -0,0 +1,144 @@
/*
* Copyright 2013 Piotr Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
import "oaidl.idl";
#include "vbscript_defs.h"
[
helpstring("Microsoft VBScript Regular Expressions 1.0"),
uuid(3f4daca7-160d-11d2-a8e9-00104b365c9f),
version(1.0)
]
library VBScript_RegExp_10
{
importlib("stdole2.tlb");
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4daca0-160d-11d2-a8e9-00104b365c9f),
]
interface IRegExp : IDispatch
{
[id(DISPID_REGEXP_PATTERN), propget]
HRESULT Pattern([out, retval] BSTR *pPattern);
[id(DISPID_REGEXP_PATTERN), propput]
HRESULT Pattern([in] BSTR pPattern);
[id(DISPID_REGEXP_IGNORECASE), propget]
HRESULT IgnoreCase([out, retval] VARIANT_BOOL *pIgnoreCase);
[id(DISPID_REGEXP_IGNORECASE), propput]
HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
[id(DISPID_REGEXP_GLOBAL), propget]
HRESULT Global([out, retval] VARIANT_BOOL *pGlobal);
[id(DISPID_REGEXP_GLOBAL), propput]
HRESULT Global([in] VARIANT_BOOL pGlobal);
[id(DISPID_REGEXP_EXECUTE)]
HRESULT Execute(
[in] BSTR sourceString,
[out, retval] IDispatch **ppMatches);
[id(DISPID_REGEXP_TEST)]
HRESULT Test(
[in] BSTR sourceString,
[out, retval] VARIANT_BOOL *pMatch);
[id(DISPID_REGEXP_REPLACE)]
HRESULT Replace(
[in] BSTR sourceString,
[in] BSTR replaceString,
[out, retval] BSTR *pDestString);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4daca1-160d-11d2-a8e9-00104b365c9f)
]
interface IMatch : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Value([out, retval] BSTR *pValue);
[id(DISPID_MATCH_FIRSTINDEX), propget]
HRESULT FirstIndex([out, retval] LONG *pFirstIndex);
[id(DISPID_MATCH_LENGTH), propget]
HRESULT Length([out, retval] LONG *pLength);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4daca2-160d-11d2-a8e9-00104b365c9f)
]
interface IMatchCollection : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Item(
[in] LONG index,
[out, retval] IDispatch **ppMatch);
[id(DISPID_MATCHCOLLECTION_COUNT), propget]
HRESULT Count([out, retval] LONG *pCount);
[id(DISPID_NEWENUM), propget]
HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
}
[
uuid(3f4daca4-160d-11d2-a8e9-00104b365c9f)
]
coclass RegExp
{
[default] interface IRegExp;
}
[
noncreatable,
uuid(3f4daca5-160d-11d2-a8e9-00104b365c9f)
]
coclass Match
{
[default] interface IMatch;
}
[
noncreatable,
uuid(3f4daca6-160d-11d2-a8e9-00104b365c9f)
]
coclass MatchCollection
{
[default] interface IMatchCollection;
}
}

View file

@ -0,0 +1,38 @@
HKCR
{
NoRemove Typelib
{
NoRemove '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}'
{
'1.0' = s 'Microsoft VBScript Regular Expressions 1.0'
{
'0' { win32 = s '%MODULE%' }
FLAGS = s '0'
}
}
}
NoRemove Interface
{
'{3F4DACA0-160D-11D2-A8E9-00104B365C9F}' = s 'IRegExp'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '1.0' }
}
'{3F4DACA1-160D-11D2-A8E9-00104B365C9F}' = s 'IMatch'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '1.0' }
}
'{3F4DACA2-160D-11D2-A8E9-00104B365C9F}' = s 'IMatchCollection'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '1.0' }
}
}
NoRemove CLSID
{
}
}

View file

@ -0,0 +1,270 @@
/*
* Copyright 2013 Piotr Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
import "oaidl.idl";
#include "vbscript_defs.h"
[
helpstring("Microsoft VBScript Regular Expressions 5.5"),
uuid(3f4daca7-160d-11d2-a8e9-00104b365c9f),
version(5.5)
]
library VBScript_RegExp_55
{
importlib("stdole2.tlb");
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4daca0-160d-11d2-a8e9-00104b365c9f),
]
interface IRegExp : IDispatch
{
[id(DISPID_REGEXP_PATTERN), propget]
HRESULT Pattern([out, retval] BSTR *pPattern);
[id(DISPID_REGEXP_PATTERN), propput]
HRESULT Pattern([in] BSTR pPattern);
[id(DISPID_REGEXP_IGNORECASE), propget]
HRESULT IgnoreCase([out, retval] VARIANT_BOOL *pIgnoreCase);
[id(DISPID_REGEXP_IGNORECASE), propput]
HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
[id(DISPID_REGEXP_GLOBAL), propget]
HRESULT Global([out, retval] VARIANT_BOOL *pGlobal);
[id(DISPID_REGEXP_GLOBAL), propput]
HRESULT Global([in] VARIANT_BOOL pGlobal);
[id(DISPID_REGEXP_EXECUTE)]
HRESULT Execute(
[in] BSTR sourceString,
[out, retval] IDispatch **ppMatches);
[id(DISPID_REGEXP_TEST)]
HRESULT Test(
[in] BSTR sourceString,
[out, retval] VARIANT_BOOL *pMatch);
[id(DISPID_REGEXP_REPLACE)]
HRESULT Replace(
[in] BSTR sourceString,
[in] BSTR replaceString,
[out, retval] BSTR *pDestString);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4dacb0-160d-11d2-a8e9-00104b365c9f)
]
interface IRegExp2 : IDispatch
{
[id(DISPID_REGEXP_PATTERN), propget]
HRESULT Pattern([out, retval] BSTR *pPattern);
[id(DISPID_REGEXP_PATTERN), propput]
HRESULT Pattern([in] BSTR pPattern);
[id(DISPID_REGEXP_IGNORECASE), propget]
HRESULT IgnoreCase([out, retval] VARIANT_BOOL *pIgnoreCase);
[id(DISPID_REGEXP_IGNORECASE), propput]
HRESULT IgnoreCase([in] VARIANT_BOOL pIgnoreCase);
[id(DISPID_REGEXP_GLOBAL), propget]
HRESULT Global([out, retval] VARIANT_BOOL *pGlobal);
[id(DISPID_REGEXP_GLOBAL), propput]
HRESULT Global([in] VARIANT_BOOL pGlobal);
[id(DISPID_REGEXP_MULTILINE), propget]
HRESULT Multiline([out, retval] VARIANT_BOOL *pMultiline);
[id(DISPID_REGEXP_MULTILINE), propput]
HRESULT Multiline([in] VARIANT_BOOL pMultiline);
[id(DISPID_REGEXP_EXECUTE)]
HRESULT Execute(
[in] BSTR sourceString,
[out, retval] IDispatch **ppMatches);
[id(DISPID_REGEXP_TEST)]
HRESULT Test(
[in] BSTR sourceString,
[out, retval] VARIANT_BOOL *pMatch);
[id(DISPID_REGEXP_REPLACE)]
HRESULT Replace(
[in] BSTR sourceString,
[in] VARIANT replaceVar,
[out, retval] BSTR *pDestString);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4daca1-160d-11d2-a8e9-00104b365c9f)
]
interface IMatch : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Value([out, retval] BSTR *pValue);
[id(DISPID_MATCH_FIRSTINDEX), propget]
HRESULT FirstIndex([out, retval] LONG *pFirstIndex);
[id(DISPID_MATCH_LENGTH), propget]
HRESULT Length([out, retval] LONG *pLength);
}
[
odl,
uuid(3f4dacb1-160d-11d2-a8e9-00104b365c9f),
hidden,
dual,
nonextensible,
oleautomation
]
interface IMatch2 : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Value([out, retval] BSTR *pValue);
[id(DISPID_MATCH_FIRSTINDEX), propget]
HRESULT FirstIndex([out, retval] LONG *pFirstIndex);
[id(DISPID_MATCH_LENGTH), propget]
HRESULT Length([out, retval] LONG *pLength);
[id(DISPID_MATCH_SUBMATCHES), propget]
HRESULT SubMatches([out, retval] IDispatch **ppSubMatches);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4daca2-160d-11d2-a8e9-00104b365c9f)
]
interface IMatchCollection : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Item(
[in] LONG index,
[out, retval] IDispatch **ppMatch);
[id(DISPID_MATCHCOLLECTION_COUNT), propget]
HRESULT Count([out, retval] LONG *pCount);
[id(DISPID_NEWENUM), propget]
HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4dacb2-160d-11d2-a8e9-00104b365c9f)
]
interface IMatchCollection2 : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Item(
[in] LONG index,
[out, retval] IDispatch **ppMatch);
[id(DISPID_MATCHCOLLECTION_COUNT), propget]
HRESULT Count([out, retval] LONG *pCount);
[id(DISPID_NEWENUM), propget]
HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
}
[
dual,
hidden,
nonextensible,
odl,
oleautomation,
uuid(3f4dacb3-160d-11d2-a8e9-00104b365c9f)
]
interface ISubMatches : IDispatch
{
[id(DISPID_VALUE), propget]
HRESULT Item(
[in] LONG index,
[out, retval] VARIANT *pSubMatch);
[id(DISPID_SUBMATCHES_COUNT), propget]
HRESULT Count([out, retval] LONG *pCount);
[id(DISPID_NEWENUM), propget]
HRESULT _NewEnum([out, retval] IUnknown **ppEnum);
}
[
uuid(3f4daca4-160d-11d2-a8e9-00104b365c9f)
]
coclass RegExp
{
[default] interface IRegExp2;
}
[
noncreatable,
uuid(3f4daca5-160d-11d2-a8e9-00104b365c9f)
]
coclass Match
{
[default] interface IMatch2;
}
[
noncreatable,
uuid(3f4daca6-160d-11d2-a8e9-00104b365c9f)
]
coclass MatchCollection
{
[default] interface IMatchCollection2;
}
[
noncreatable,
uuid(3f4dacc0-160d-11d2-a8e9-00104b365c9f)
]
coclass SubMatches {
[default] interface ISubMatches;
}
}

View file

@ -0,0 +1,62 @@
HKCR
{
NoRemove Typelib
{
NoRemove '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}'
{
'5.5' = s 'Microsoft VBScript Regular Expressions 5.5'
{
'0' { win32 = s '%MODULE%' }
FLAGS = s '0'
}
}
}
NoRemove Interface
{
'{3F4DACA0-160D-11D2-A8E9-00104B365C9F}' = s 'IRegExp'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
'{3F4DACB0-160D-11D2-A8E9-00104B365C9F}' = s 'IRegExp2'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
'{3F4DACA1-160D-11D2-A8E9-00104B365C9F}' = s 'IMatch'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
'{3F4DACB1-160D-11D2-A8E9-00104B365C9F}' = s 'IMatch2'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
'{3F4DACA2-160D-11D2-A8E9-00104B365C9F}' = s 'IMatchCollection'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
'{3F4DACB2-160D-11D2-A8E9-00104B365C9F}' = s 'IMatchCollection2'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
'{3F4DACB3-160D-11D2-A8E9-00104B365C9F}' = s 'ISubMatches'
{
ProxyStubClsid = s '{00020424-0000-0000-C000-000000000046}'
ProxyStubClsid32 = s '{00020424-0000-0000-C000-000000000046}'
TypeLib = s '{3F4DACA7-160D-11D2-A8E9-00104B365C9F}' { val Version = s '5.5' }
}
}
NoRemove CLSID
{
}
}

View file

@ -184,6 +184,7 @@ reactos/dll/win32/url # Synced to Wine-1.5.19
reactos/dll/win32/urlmon # Synced to Wine-1.5.26
reactos/dll/win32/usp10 # Synced to Wine-1.5.26
reactos/dll/win32/uxtheme # Forked
reactos/dll/win32/vbscript # Synced to Wine-1.5.26
reactos/dll/win32/version # Autosync
reactos/dll/win32/wer # Autosync
reactos/dll/win32/windowscodecs # Synced to Wine-1.5.19