mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
32-bit fixes for encoding of search criteria
This commit is contained in:
parent
0cda2fa0c1
commit
7a885acb71
@ -66,8 +66,7 @@ namespace Acacia.Native.MAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: align is probably wrong for 32-bit
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct PropValue
|
public struct PropValue
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
@ -124,7 +123,9 @@ namespace Acacia.Native.MAPI
|
|||||||
// LONG x; /* case PT_NULL, PT_OBJECT (no usable value) */
|
// LONG x; /* case PT_NULL, PT_OBJECT (no usable value) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[FieldOffset(0)]
|
||||||
public Header header;
|
public Header header;
|
||||||
|
[FieldOffset(8)]
|
||||||
public Data data;
|
public Data data;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
@ -160,13 +161,13 @@ namespace Acacia.Native.MAPI
|
|||||||
return encoder.Allocate(obj.header, obj.data.b);
|
return encoder.Allocate(obj.header, obj.data.b);
|
||||||
case PropType.STRING8:
|
case PropType.STRING8:
|
||||||
IntPtr ptrA = encoder.Allocate(Encoding.ASCII.GetBytes((string)value), new byte[] { 0 });
|
IntPtr ptrA = encoder.Allocate(Encoding.ASCII.GetBytes((string)value), new byte[] { 0 });
|
||||||
return encoder.Allocate(obj.header, ptrA);
|
return encoder.Allocate(obj.header, 8, ptrA);
|
||||||
case PropType.UNICODE:
|
case PropType.UNICODE:
|
||||||
IntPtr ptrW = encoder.Allocate(Encoding.Unicode.GetBytes((string)value), new byte[] { 0, 0 });
|
IntPtr ptrW = encoder.Allocate(Encoding.Unicode.GetBytes((string)value), new byte[] { 0, 0 });
|
||||||
return encoder.Allocate(obj.header, ptrW);
|
return encoder.Allocate(obj.header, 8, ptrW);
|
||||||
case PropType.BINARY:
|
case PropType.BINARY:
|
||||||
obj.data.bin = ((SBinary)value).Marshal(encoder);
|
obj.data.bin = ((SBinary)value).Marshal(encoder);
|
||||||
return encoder.Allocate(obj.header, obj.data.bin);
|
return encoder.Allocate(obj.header, 8, obj.data.bin);
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -207,53 +207,62 @@ namespace Acacia.Native.MAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check this on 32 bit machines
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
unsafe public struct SRestriction
|
unsafe public struct SRestriction
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct Header
|
||||||
|
{
|
||||||
public RestrictionType rt;
|
public RestrictionType rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
unsafe public struct Data
|
||||||
|
{
|
||||||
// And/Or
|
// And/Or
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public SubRestriction sub;
|
public SubRestriction sub;
|
||||||
|
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public NotRestriction not;
|
public NotRestriction not;
|
||||||
|
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public ContentRestriction content;
|
public ContentRestriction content;
|
||||||
|
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public PropertyRestriction prop;
|
public PropertyRestriction prop;
|
||||||
|
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public BitMaskRestriction bitMask;
|
public BitMaskRestriction bitMask;
|
||||||
|
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public ExistRestriction exist;
|
public ExistRestriction exist;
|
||||||
|
|
||||||
[FieldOffset(8)]
|
[FieldOffset(0)]
|
||||||
public CommentRestriction comment;
|
public CommentRestriction comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Header header;
|
||||||
|
public Data data;
|
||||||
|
|
||||||
public SearchQuery ToSearchQuery()
|
public SearchQuery ToSearchQuery()
|
||||||
{
|
{
|
||||||
switch (rt)
|
switch (header.rt)
|
||||||
{
|
{
|
||||||
case RestrictionType.AND:
|
case RestrictionType.AND:
|
||||||
return sub.ToSearchQuery(true);
|
return data.sub.ToSearchQuery(true);
|
||||||
case RestrictionType.OR:
|
case RestrictionType.OR:
|
||||||
return sub.ToSearchQuery(false);
|
return data.sub.ToSearchQuery(false);
|
||||||
case RestrictionType.NOT:
|
case RestrictionType.NOT:
|
||||||
return not.ToSearchQuery();
|
return data.not.ToSearchQuery();
|
||||||
case RestrictionType.CONTENT:
|
case RestrictionType.CONTENT:
|
||||||
return content.ToSearchQuery();
|
return data.content.ToSearchQuery();
|
||||||
case RestrictionType.PROPERTY:
|
case RestrictionType.PROPERTY:
|
||||||
return prop.ToSearchQuery();
|
return data.prop.ToSearchQuery();
|
||||||
case RestrictionType.BITMASK:
|
case RestrictionType.BITMASK:
|
||||||
return bitMask.ToSearchQuery();
|
return data.bitMask.ToSearchQuery();
|
||||||
case RestrictionType.EXIST:
|
case RestrictionType.EXIST:
|
||||||
return exist.ToSearchQuery();
|
return data.exist.ToSearchQuery();
|
||||||
|
|
||||||
/* TODO COMPAREPROPS,
|
/* TODO COMPAREPROPS,
|
||||||
BITMASK,
|
BITMASK,
|
||||||
@ -275,27 +284,27 @@ namespace Acacia.Native.MAPI
|
|||||||
public string ToString(int depth)
|
public string ToString(int depth)
|
||||||
{
|
{
|
||||||
string indent = new string(' ', depth);
|
string indent = new string(' ', depth);
|
||||||
string s = indent + rt.ToString() + "\n" + indent + "{\n";
|
string s = indent + header.rt.ToString() + "\n" + indent + "{\n";
|
||||||
switch (rt)
|
switch (header.rt)
|
||||||
{
|
{
|
||||||
case RestrictionType.AND:
|
case RestrictionType.AND:
|
||||||
case RestrictionType.OR:
|
case RestrictionType.OR:
|
||||||
s += sub.ToString(depth + 1);
|
s += data.sub.ToString(depth + 1);
|
||||||
break;
|
break;
|
||||||
case RestrictionType.NOT:
|
case RestrictionType.NOT:
|
||||||
s += not.ToString(depth + 1);
|
s += data.not.ToString(depth + 1);
|
||||||
break;
|
break;
|
||||||
case RestrictionType.CONTENT:
|
case RestrictionType.CONTENT:
|
||||||
s += content.ToString(depth + 1);
|
s += data.content.ToString(depth + 1);
|
||||||
break;
|
break;
|
||||||
case RestrictionType.PROPERTY:
|
case RestrictionType.PROPERTY:
|
||||||
s += prop.ToString(depth + 1);
|
s += data.prop.ToString(depth + 1);
|
||||||
break;
|
break;
|
||||||
case RestrictionType.BITMASK:
|
case RestrictionType.BITMASK:
|
||||||
s += bitMask.ToString(depth + 1);
|
s += data.bitMask.ToString(depth + 1);
|
||||||
break;
|
break;
|
||||||
case RestrictionType.EXIST:
|
case RestrictionType.EXIST:
|
||||||
s += exist.ToString(depth + 1);
|
s += data.exist.ToString(depth + 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* TODO COMPAREPROPS,
|
/* TODO COMPAREPROPS,
|
||||||
@ -361,15 +370,15 @@ namespace Acacia.Native.MAPI
|
|||||||
|
|
||||||
public void Encode(SearchQuery.PropertyExists part)
|
public void Encode(SearchQuery.PropertyExists part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.EXIST;
|
Current->header.rt = RestrictionType.EXIST;
|
||||||
Current->exist.prop = part.Property.Tag;
|
Current->data.exist.prop = part.Property.Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Encode(SearchQuery.Or part)
|
public void Encode(SearchQuery.Or part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.OR;
|
Current->header.rt = RestrictionType.OR;
|
||||||
Current->sub.cb = (uint)part.Operands.Count;
|
Current->data.sub.cb = (uint)part.Operands.Count;
|
||||||
Current->sub.ptr = EncodePointer(part.Operands);
|
Current->data.sub.ptr = EncodePointer(part.Operands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Encode(SearchQuery.PropertyIdentifier part)
|
public void Encode(SearchQuery.PropertyIdentifier part)
|
||||||
@ -380,15 +389,15 @@ namespace Acacia.Native.MAPI
|
|||||||
|
|
||||||
public void Encode(SearchQuery.Not part)
|
public void Encode(SearchQuery.Not part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.NOT;
|
Current->header.rt = RestrictionType.NOT;
|
||||||
Current->not.ptr = EncodePointer(new[] { part.Operand });
|
Current->data.not.ptr = EncodePointer(new[] { part.Operand });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Encode(SearchQuery.And part)
|
public void Encode(SearchQuery.And part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.AND;
|
Current->header.rt = RestrictionType.AND;
|
||||||
Current->sub.cb = (uint)part.Operands.Count;
|
Current->data.sub.cb = (uint)part.Operands.Count;
|
||||||
Current->sub.ptr = EncodePointer(part.Operands);
|
Current->data.sub.ptr = EncodePointer(part.Operands);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SRestriction* EncodePointer(IEnumerable<SearchQuery> operands)
|
private SRestriction* EncodePointer(IEnumerable<SearchQuery> operands)
|
||||||
@ -425,26 +434,26 @@ namespace Acacia.Native.MAPI
|
|||||||
|
|
||||||
public void Encode(SearchQuery.PropertyContent part)
|
public void Encode(SearchQuery.PropertyContent part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.CONTENT;
|
Current->header.rt = RestrictionType.CONTENT;
|
||||||
Current->content.ulFuzzyLevel = ContentRestriction.FuzzyLevelFromSearchQuery(part);
|
Current->data.content.ulFuzzyLevel = ContentRestriction.FuzzyLevelFromSearchQuery(part);
|
||||||
Current->content.ulPropTag = part.Property.Tag;
|
Current->data.content.ulPropTag = part.Property.Tag;
|
||||||
Current->content.prop = (PropValue*)PropValue.MarshalFromObject(this, part.Property.Tag, part.Content);
|
Current->data.content.prop = (PropValue*)PropValue.MarshalFromObject(this, part.Property.Tag, part.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Encode(SearchQuery.PropertyCompare part)
|
public void Encode(SearchQuery.PropertyCompare part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.PROPERTY;
|
Current->header.rt = RestrictionType.PROPERTY;
|
||||||
Current->prop.relop = (SearchOperation)part.Operation;
|
Current->data.prop.relop = (SearchOperation)part.Operation;
|
||||||
Current->prop.ulPropTag = part.Property.Tag;
|
Current->data.prop.ulPropTag = part.Property.Tag;
|
||||||
Current->prop.prop = (PropValue*)PropValue.MarshalFromObject(this, part.Property.Tag, part.Value);
|
Current->data.prop.prop = (PropValue*)PropValue.MarshalFromObject(this, part.Property.Tag, part.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Encode(SearchQuery.PropertyBitMask part)
|
public void Encode(SearchQuery.PropertyBitMask part)
|
||||||
{
|
{
|
||||||
Current->rt = RestrictionType.BITMASK;
|
Current->header.rt = RestrictionType.BITMASK;
|
||||||
Current->bitMask.bmr = (BMR)(int)part.Operation;
|
Current->data.bitMask.bmr = (BMR)(int)part.Operation;
|
||||||
Current->bitMask.prop = part.Property.Tag;
|
Current->data.bitMask.prop = part.Property.Tag;
|
||||||
Current->bitMask.mask = part.Mask;
|
Current->data.bitMask.mask = part.Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,27 +134,40 @@ namespace Acacia.Native
|
|||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int[] starts = new int[all.Length];
|
int[] starts = new int[all.Length];
|
||||||
|
object[] encode = new object[all.Length];
|
||||||
|
int used = 0;
|
||||||
|
int align = -1;
|
||||||
for (int i = 0; i < all.Length; ++i)
|
for (int i = 0; i < all.Length; ++i)
|
||||||
{
|
{
|
||||||
starts[i] = Align(size);
|
if (all[i] is int)
|
||||||
|
{
|
||||||
|
align = (int)all[i];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
starts[used] = Align(size, align);
|
||||||
int thisSize = Marshal.SizeOf(all[i]);
|
int thisSize = Marshal.SizeOf(all[i]);
|
||||||
size = starts[i] + thisSize;
|
size = starts[used] + thisSize;
|
||||||
|
encode[used] = all[i];
|
||||||
|
align = -1;
|
||||||
|
++used;
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocationBase alloc = Allocate(size);
|
AllocationBase alloc = Allocate(size);
|
||||||
IntPtr ptr = alloc.Pointer;
|
IntPtr ptr = alloc.Pointer;
|
||||||
for (int i = 0; i < all.Length; ++i)
|
for (int i = 0; i < used; ++i)
|
||||||
{
|
{
|
||||||
Marshal.StructureToPtr(all[i], ptr + starts[i], false);
|
Marshal.StructureToPtr(encode[i], ptr + starts[i], false);
|
||||||
}
|
}
|
||||||
return alloc.Pointer;
|
return alloc.Pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private int Align(int size)
|
private int Align(int size, int align)
|
||||||
{
|
{
|
||||||
int align = Marshal.SizeOf<IntPtr>();
|
if (align < 0)
|
||||||
|
align = Marshal.SizeOf<IntPtr>();
|
||||||
int additional = (align - (size % align)) % align;
|
int additional = (align - (size % align)) % align;
|
||||||
return size + additional;
|
return size + additional;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user