diff --git a/tools/widl/expr.c b/tools/widl/expr.c index 405b5def1b6..1e6f1ed734c 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -297,15 +297,19 @@ static int is_integer_type(const type_t *type) case TYPE_BASIC_INT32: case TYPE_BASIC_INT64: case TYPE_BASIC_INT: + case TYPE_BASIC_INT3264: case TYPE_BASIC_CHAR: case TYPE_BASIC_HYPER: case TYPE_BASIC_BYTE: case TYPE_BASIC_WCHAR: case TYPE_BASIC_ERROR_STATUS_T: return TRUE; - default: + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + case TYPE_BASIC_HANDLE: return FALSE; } + return FALSE; default: return FALSE; } diff --git a/tools/widl/header.c b/tools/widl/header.c index b6b7be8eccd..26ee4b66557 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -265,6 +265,7 @@ void write_type_left(FILE *h, type_t *t, int declonly) case TYPE_BASIC_INT16: fprintf(h, "short"); break; case TYPE_BASIC_INT: fprintf(h, "int"); break; case TYPE_BASIC_INT64: fprintf(h, "__int64"); break; + case TYPE_BASIC_INT3264: fprintf(h, "__int3264"); break; case TYPE_BASIC_BYTE: fprintf(h, "byte"); break; case TYPE_BASIC_CHAR: fprintf(h, "char"); break; case TYPE_BASIC_WCHAR: fprintf(h, "wchar_t"); break; diff --git a/tools/widl/parser.l b/tools/widl/parser.l index f45b2289e9d..d3f355fb539 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -220,6 +220,7 @@ static const struct keyword keywords[] = { {"TRUE", tTRUE}, {"__cdecl", tCDECL}, {"__fastcall", tFASTCALL}, + {"__int3264", tINT3264}, {"__int64", tINT64}, {"__pascal", tPASCAL}, {"__stdcall", tSTDCALL}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 1929242d3eb..a493024c7d6 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -224,7 +224,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s %token tIMPORT tIMPORTLIB %token tIN tIN_LINE tINLINE %token tINPUTSYNC -%token tINT tINT64 +%token tINT tINT3264 tINT64 %token tINTERFACE %token tLCID %token tLENGTHIS tLIBRARY @@ -767,6 +767,7 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); } | tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); } | tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); } | tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); } + | tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); } ; coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); } @@ -1281,6 +1282,7 @@ static int is_allowed_range_type(const type_t *type) case TYPE_BASIC_INT32: case TYPE_BASIC_INT64: case TYPE_BASIC_INT: + case TYPE_BASIC_INT3264: case TYPE_BASIC_BYTE: case TYPE_BASIC_CHAR: case TYPE_BASIC_WCHAR: diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 6b55d2050bf..3e711005df6 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -116,6 +116,8 @@ const char *string_of_type(unsigned char type) case RPC_FC_C_WSTRING: return "FC_C_WSTRING"; case RPC_FC_CSTRING: return "FC_CSTRING"; case RPC_FC_WSTRING: return "FC_WSTRING"; + case RPC_FC_INT3264: return "FC_INT3264"; + case RPC_FC_UINT3264: return "FC_UINT3264"; default: error("string_of_type: unknown type 0x%02x\n", type); return NULL; @@ -145,6 +147,7 @@ unsigned char get_basic_fc(const type_t *type) case TYPE_BASIC_INT32: return (sign <= 0 ? RPC_FC_LONG : RPC_FC_ULONG); case TYPE_BASIC_INT64: return RPC_FC_HYPER; case TYPE_BASIC_INT: return (sign <= 0 ? RPC_FC_LONG : RPC_FC_ULONG); + case TYPE_BASIC_INT3264: return (sign <= 0 ? RPC_FC_INT3264 : RPC_FC_UINT3264); case TYPE_BASIC_BYTE: return RPC_FC_BYTE; case TYPE_BASIC_CHAR: return RPC_FC_CHAR; case TYPE_BASIC_WCHAR: return RPC_FC_WCHAR; @@ -153,8 +156,8 @@ unsigned char get_basic_fc(const type_t *type) case TYPE_BASIC_DOUBLE: return RPC_FC_DOUBLE; case TYPE_BASIC_ERROR_STATUS_T: return RPC_FC_ERROR_STATUS_T; case TYPE_BASIC_HANDLE: return RPC_FC_BIND_PRIMITIVE; - default: return 0; } + return 0; } static inline unsigned int clamp_align(unsigned int align) @@ -299,6 +302,8 @@ unsigned char get_struct_fc(const type_t *type) case TGT_IFACE_POINTER: return RPC_FC_BOGUS_STRUCT; case TGT_BASIC: + if (type_basic_get_type(t) == TYPE_BASIC_INT3264 && pointer_size != 4) + return RPC_FC_BOGUS_STRUCT; break; case TGT_ENUM: if (get_enum_fc(t) == RPC_FC_ENUM16) @@ -419,6 +424,11 @@ unsigned char get_array_fc(const type_t *type) case TGT_USER_TYPE: fc = RPC_FC_BOGUS_ARRAY; break; + case TGT_BASIC: + if (type_basic_get_type(elem_type) == TYPE_BASIC_INT3264 && + pointer_size != 4) + fc = RPC_FC_BOGUS_ARRAY; + break; case TGT_STRUCT: switch (get_struct_fc(elem_type)) { @@ -447,7 +457,6 @@ unsigned char get_array_fc(const type_t *type) case TGT_RANGE: fc = RPC_FC_BOGUS_ARRAY; break; - case TGT_BASIC: case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_STRING: @@ -1222,6 +1231,12 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) size = 8; if (size > *align) *align = size; break; + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + assert( pointer_size ); + size = pointer_size; + if (size > *align) *align = size; + break; default: error("type_memsize: Unknown type 0x%x\n", get_basic_fc(t)); size = 0; @@ -3031,6 +3046,12 @@ static unsigned int get_required_buffer_size_type( *alignment = 8; return 8; + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + assert( pointer_size ); + *alignment = pointer_size; + return pointer_size; + case RPC_FC_IGNORE: case RPC_FC_BIND_PRIMITIVE: return 0; @@ -3198,28 +3219,36 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, type_t *type = var->type; unsigned int size; unsigned int alignment = 0; - const type_t *ref; /* no work to do for other phases, buffer sizing is done elsewhere */ if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) return; - ref = is_ptr(type) ? type_pointer_get_ref(type) : type; - if (type_get_type(ref) == TYPE_ENUM) + if (type_get_type(type) == TYPE_ENUM || + (type_get_type(type) == TYPE_BASIC && + type_basic_get_type(type) == TYPE_BASIC_INT3264 && + pointer_size != 4)) { - if (get_enum_fc(ref) == RPC_FC_ENUM32) - { - size = 4; - alignment = 4; - } - else /* RPC_FC_ENUM16 */ - { - size = 2; - alignment = 2; - } + unsigned char fc; + + if (type_get_type(type) == TYPE_ENUM) + fc = get_enum_fc(type); + else + fc = get_basic_fc(type); + + if (phase == PHASE_MARSHAL) + print_file(file, indent, "NdrSimpleTypeMarshall(\n"); + else + print_file(file, indent, "NdrSimpleTypeUnmarshall(\n"); + print_file(file, indent+1, "&__frame->_StubMsg,\n"); + print_file(file, indent+1, "(unsigned char *)&%s%s,\n", + local_var_prefix, + var->name); + print_file(file, indent+1, "0x%02x /* %s */);\n", fc, string_of_type(fc)); } else { + const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type; switch (get_basic_fc(ref)) { case RPC_FC_BYTE: @@ -3241,6 +3270,9 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, case RPC_FC_LONG: case RPC_FC_FLOAT: case RPC_FC_ERROR_STATUS_T: + /* pointer_size must be 4 if we got here in these two cases */ + case RPC_FC_INT3264: + case RPC_FC_UINT3264: size = 4; alignment = 4; break; @@ -3261,46 +3293,46 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, var->name, get_basic_fc(ref)); size = 0; } - } - if (phase == PHASE_MARSHAL) - print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); - print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n", - alignment - 1, alignment - 1); + if (phase == PHASE_MARSHAL) + print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); + print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n", + alignment - 1, alignment - 1); - if (phase == PHASE_MARSHAL) - { - print_file(file, indent, "*("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - if (is_ptr(type)) - fprintf(file, " *)__frame->_StubMsg.Buffer = *"); - else - fprintf(file, " *)__frame->_StubMsg.Buffer = "); - fprintf(file, "%s%s", local_var_prefix, varname); - fprintf(file, ";\n"); - } - else if (phase == PHASE_UNMARSHAL) - { - print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n"); - print_file(file, indent, "{\n"); - print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - print_file(file, indent, "}\n"); - print_file(file, indent, "%s%s%s", - (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*", - local_var_prefix, varname); - if (pass == PASS_IN && is_ptr(type)) - fprintf(file, " = ("); - else - fprintf(file, " = *("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - fprintf(file, " *)__frame->_StubMsg.Buffer;\n"); - } + if (phase == PHASE_MARSHAL) + { + print_file(file, indent, "*("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + if (is_ptr(type)) + fprintf(file, " *)__frame->_StubMsg.Buffer = *"); + else + fprintf(file, " *)__frame->_StubMsg.Buffer = "); + fprintf(file, "%s%s", local_var_prefix, varname); + fprintf(file, ";\n"); + } + else if (phase == PHASE_UNMARSHAL) + { + print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n"); + print_file(file, indent, "{\n"); + print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); + print_file(file, indent, "}\n"); + print_file(file, indent, "%s%s%s", + (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*", + local_var_prefix, varname); + if (pass == PASS_IN && is_ptr(type)) + fprintf(file, " = ("); + else + fprintf(file, " = *("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + fprintf(file, " *)__frame->_StubMsg.Buffer;\n"); + } - print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - fprintf(file, ");\n"); + print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + fprintf(file, ");\n"); + } } /* returns whether the MaxCount, Offset or ActualCount members need to be @@ -3553,44 +3585,13 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const break; } case TGT_BASIC: - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); break; case TGT_ENUM: - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - { - if (phase == PHASE_MARSHAL) - print_file(file, indent, "NdrSimpleTypeMarshall(\n"); - else - print_file(file, indent, "NdrSimpleTypeUnmarshall(\n"); - print_file(file, indent+1, "&__frame->_StubMsg,\n"); - print_file(file, indent+1, "(unsigned char *)&%s%s,\n", - local_var_prefix, - var->name); - print_file(file, indent+1, "0x%02x /* %s */);\n", get_enum_fc(type), string_of_type(get_enum_fc(type))); - } + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); break; case TGT_RANGE: - if (type_get_type(type) == TYPE_ENUM) - { - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - { - if (phase == PHASE_MARSHAL) - print_file(file, indent, "NdrSimpleTypeMarshall(\n"); - else - print_file(file, indent, "NdrSimpleTypeUnmarshall(\n"); - print_file(file, indent+1, "&__frame->_StubMsg,\n"); - print_file(file, indent+1, "(unsigned char *)&%s%s,\n", - local_var_prefix, - var->name); - print_file(file, indent+1, "0x%02x /* %s */);\n", get_enum_fc(type), string_of_type(get_enum_fc(type))); - } - } - else - { - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); - } + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); /* Note: this goes beyond what MIDL does - it only supports arguments * with the [range] attribute in Oicf mode */ if (phase == PHASE_UNMARSHAL) @@ -3656,11 +3657,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const if (pointer_type == RPC_FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES)) { case TGT_BASIC: - /* base types have known sizes, so don't need a sizing pass - * and don't have any memory to free and so don't need a - * freeing pass */ - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); break; case TGT_ENUM: /* base types have known sizes, so don't need a sizing pass diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index d675ea951cf..b4dd771d682 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -181,6 +181,21 @@ unsigned short get_type_vt(type_t *t) return VT_UI8; else return VT_I8; + case TYPE_BASIC_INT3264: + if (typelib_kind == SYS_WIN64) + { + if (type_basic_get_sign(t) > 0) + return VT_UI8; + else + return VT_I8; + } + else + { + if (type_basic_get_sign(t) > 0) + return VT_UI4; + else + return VT_I4; + } case TYPE_BASIC_FLOAT: return VT_R4; case TYPE_BASIC_DOUBLE: diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h index 58bad43f2e3..18e6cdbcc56 100644 --- a/tools/widl/typelib.h +++ b/tools/widl/typelib.h @@ -61,6 +61,8 @@ enum VARENUM { VT_LPSTR = 30, VT_LPWSTR = 31, VT_RECORD = 36, + VT_INT_PTR = 37, + VT_UINT_PTR = 38, VT_FILETIME = 64, VT_BLOB = 65, VT_STREAM = 66, @@ -70,6 +72,7 @@ enum VARENUM { VT_BLOB_OBJECT = 70, VT_CF = 71, VT_CLSID = 72, + VT_VERSIONED_STREAM = 73, VT_BSTR_BLOB = 0xfff, VT_VECTOR = 0x1000, VT_ARRAY = 0x2000, diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index e80c7ed821b..d5a4c4388cf 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -230,6 +230,7 @@ enum type_basic_type TYPE_BASIC_INT32, TYPE_BASIC_INT64, TYPE_BASIC_INT, + TYPE_BASIC_INT3264, TYPE_BASIC_CHAR, TYPE_BASIC_HYPER, TYPE_BASIC_BYTE,