widl: Fix problems with variable-size user types.
This commit is contained in:
parent
e1a3e9a6ef
commit
ff8930f2bf
|
@ -459,6 +459,18 @@ s_make_pyramid_doub_carr(unsigned char n, doub_carr_t **dc)
|
||||||
*dc = t;
|
*dc = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
s_hash_bstr(bstr_t b)
|
||||||
|
{
|
||||||
|
short n = b[-1];
|
||||||
|
short *s = b;
|
||||||
|
unsigned hash = 0;
|
||||||
|
short i;
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
hash = 5 * hash + (unsigned) s[i];
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
s_stop(void)
|
s_stop(void)
|
||||||
{
|
{
|
||||||
|
@ -744,6 +756,38 @@ us_t_UserFree(ULONG *flags, us_t *pus)
|
||||||
HeapFree(GetProcessHeap(), 0, pus->x);
|
HeapFree(GetProcessHeap(), 0, pus->x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG __RPC_USER
|
||||||
|
bstr_t_UserSize(ULONG *flags, ULONG start, bstr_t *b)
|
||||||
|
{
|
||||||
|
return start + FIELD_OFFSET(wire_bstr_t, data[(*b)[-1]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char * __RPC_USER
|
||||||
|
bstr_t_UserMarshal(ULONG *flags, unsigned char *buffer, bstr_t *b)
|
||||||
|
{
|
||||||
|
wire_bstr_t *wb = (wire_bstr_t *) buffer;
|
||||||
|
wb->n = (*b)[-1];
|
||||||
|
memcpy(&wb->data, *b, wb->n * sizeof wb->data[0]);
|
||||||
|
return buffer + FIELD_OFFSET(wire_bstr_t, data[wb->n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char * __RPC_USER
|
||||||
|
bstr_t_UserUnmarshal(ULONG *flags, unsigned char *buffer, bstr_t *b)
|
||||||
|
{
|
||||||
|
wire_bstr_t *wb = (wire_bstr_t *) buffer;
|
||||||
|
short *data = HeapAlloc(GetProcessHeap(), 0, (wb->n + 1) * sizeof *data);
|
||||||
|
data[0] = wb->n;
|
||||||
|
memcpy(&data[1], wb->data, wb->n * sizeof data[1]);
|
||||||
|
*b = &data[1];
|
||||||
|
return buffer + FIELD_OFFSET(wire_bstr_t, data[wb->n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __RPC_USER
|
||||||
|
bstr_t_UserFree(ULONG *flags, bstr_t *b)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, &((*b)[-1]));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pointer_tests(void)
|
pointer_tests(void)
|
||||||
{
|
{
|
||||||
|
@ -754,6 +798,8 @@ pointer_tests(void)
|
||||||
int *pa[4];
|
int *pa[4];
|
||||||
puints_t pus;
|
puints_t pus;
|
||||||
cpuints_t cpus;
|
cpuints_t cpus;
|
||||||
|
short bstr_data[] = { 5, 'H', 'e', 'l', 'l', 'o' };
|
||||||
|
bstr_t bstr = &bstr_data[1];
|
||||||
|
|
||||||
ok(test_list_length(list) == 3, "RPC test_list_length\n");
|
ok(test_list_length(list) == 3, "RPC test_list_length\n");
|
||||||
ok(square_puint(p1) == 121, "RPC square_puint\n");
|
ok(square_puint(p1) == 121, "RPC square_puint\n");
|
||||||
|
@ -794,6 +840,8 @@ pointer_tests(void)
|
||||||
pa[3] = &a[3];
|
pa[3] = &a[3];
|
||||||
ok(sum_pcarr(pa, 4) == 10, "RPC sum_pcarr\n");
|
ok(sum_pcarr(pa, 4) == 10, "RPC sum_pcarr\n");
|
||||||
|
|
||||||
|
ok(hash_bstr(bstr) == s_hash_bstr(bstr), "RPC hash_bstr_data\n");
|
||||||
|
|
||||||
free_list(list);
|
free_list(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -281,5 +281,14 @@ cpp_quote("#endif")
|
||||||
int sum_doub_carr(doub_carr_t *dc);
|
int sum_doub_carr(doub_carr_t *dc);
|
||||||
void make_pyramid_doub_carr(unsigned char n, [out] doub_carr_t **dc);
|
void make_pyramid_doub_carr(unsigned char n, [out] doub_carr_t **dc);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short n;
|
||||||
|
[size_is(n)] short data[];
|
||||||
|
} wire_bstr_t;
|
||||||
|
|
||||||
|
typedef [wire_marshal(wire_bstr_t)] short *bstr_t;
|
||||||
|
unsigned hash_bstr(bstr_t s);
|
||||||
|
|
||||||
void stop(void);
|
void stop(void);
|
||||||
}
|
}
|
||||||
|
|
|
@ -907,13 +907,31 @@ static int processed(const type_t *type)
|
||||||
return type->typestring_offset && !type->tfswrite;
|
return type->typestring_offset && !type->tfswrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int user_type_has_variable_size(const type_t *t)
|
||||||
|
{
|
||||||
|
if (is_ptr(t))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
switch (t->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_PSTRUCT:
|
||||||
|
case RPC_FC_CSTRUCT:
|
||||||
|
case RPC_FC_CPSTRUCT:
|
||||||
|
case RPC_FC_CVSTRUCT:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/* Note: Since this only applies to user types, we can't have a conformant
|
||||||
|
array here, and strings should get filed under pointer in this case. */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
||||||
{
|
{
|
||||||
unsigned int start, absoff, flags;
|
unsigned int start, absoff, flags;
|
||||||
unsigned int align = 0, ualign = 0;
|
unsigned int align = 0, ualign = 0;
|
||||||
const char *name;
|
const char *name;
|
||||||
type_t *utype = get_user_type(type, &name);
|
type_t *utype = get_user_type(type, &name);
|
||||||
size_t usize = type_memsize(utype, &ualign);
|
size_t usize = user_type_has_variable_size(utype) ? 0 : type_memsize(utype, &ualign);
|
||||||
size_t size = type_memsize(type, &align);
|
size_t size = type_memsize(type, &align);
|
||||||
unsigned short funoff = user_type_offset(name);
|
unsigned short funoff = user_type_offset(name);
|
||||||
short reloff;
|
short reloff;
|
||||||
|
@ -949,8 +967,8 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
||||||
print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
|
print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
|
||||||
flags | (align - 1), align - 1, flags);
|
flags | (align - 1), align - 1, flags);
|
||||||
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff);
|
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff);
|
||||||
print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize);
|
|
||||||
print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size);
|
print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size);
|
||||||
|
print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize);
|
||||||
*tfsoff += 8;
|
*tfsoff += 8;
|
||||||
reloff = absoff - *tfsoff;
|
reloff = absoff - *tfsoff;
|
||||||
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", reloff, reloff, absoff);
|
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", reloff, reloff, absoff);
|
||||||
|
|
Loading…
Reference in New Issue