Skip to content

Commit 26fc2a7

Browse files
committed
Fix handling of arrays of pointers to structures.
1 parent 4b584be commit 26fc2a7

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-6
lines changed

NtApiDotNet/Ndr/Marshal/NdrMarshalBuffer.cs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ private void WriteStringArray(string[] array, Action<string> writer, int count)
8888
}
8989
}
9090

91+
private void WriteStructPointerArray<T>(T?[] array, int count) where T : struct, INdrStructure
92+
{
93+
if (array == null)
94+
{
95+
array = new T?[0];
96+
}
97+
98+
for (int i = 0; i < count; ++i)
99+
{
100+
INdrStructure value = i < array.Length ? array[i] : null;
101+
WriteReferent(value);
102+
_deferred_writes.Add(() => WriteStruct(value));
103+
}
104+
}
105+
91106
private void WriteConformance(params int[] conformance)
92107
{
93108
if (_conformance_position.HasValue)
@@ -857,9 +872,18 @@ public void WriteVaryingStructArray<T>(T[] array, long variance) where T : struc
857872

858873
public void WriteVaryingStructPointerArray<T>(T?[] array, long variance) where T : struct, INdrStructure
859874
{
875+
// Offset.
876+
WriteInt32(0);
877+
// Actual Count
878+
int var_int = (int)variance;
879+
if (var_int < 0)
880+
{
881+
var_int = array.Length;
882+
}
883+
WriteInt32(var_int);
860884
using (var queue = _deferred_writes.Push())
861885
{
862-
WriteVaryingArrayCallback(array, t => WriteReferent(t, x => WriteStructInternal(x)), variance);
886+
WriteStructPointerArray(array, (int)variance);
863887
}
864888
}
865889

@@ -987,9 +1011,16 @@ public void WriteConformantStructArray<T>(T[] array, long conformance) where T :
9871011

9881012
public void WriteConformantStructPointerArray<T>(T?[] array, long conformance) where T : struct, INdrStructure
9891013
{
1014+
int var_int = (int)conformance;
1015+
if (var_int < 0)
1016+
{
1017+
var_int = array?.Length ?? 0;
1018+
}
1019+
// Max Count
1020+
WriteConformance(var_int);
9901021
using (var queue = _deferred_writes.Push())
9911022
{
992-
WriteConformantArrayCallback(array, t => WriteReferent(t, x => WriteStructInternal(x)), conformance);
1023+
WriteStructPointerArray(array, var_int);
9931024
}
9941025
}
9951026

@@ -1112,9 +1143,26 @@ public void WriteConformantVaryingStructArray<T>(T[] array, long conformance, lo
11121143

11131144
public void WriteConformantVaryingStructPointerArray<T>(T?[] array, long conformance, long variance) where T : struct, INdrStructure
11141145
{
1146+
// Max Count
1147+
int con_int = (int)conformance;
1148+
if (con_int < 0)
1149+
{
1150+
con_int = array.Length;
1151+
}
1152+
WriteConformance(con_int);
1153+
1154+
// Offset.
1155+
WriteInt32(0);
1156+
// Actual Count
1157+
int var_int = (int)variance;
1158+
if (var_int < 0)
1159+
{
1160+
var_int = array.Length;
1161+
}
1162+
WriteInt32(var_int);
11151163
using (var queue = _deferred_writes.Push())
11161164
{
1117-
WriteVaryingArrayCallback(array, t => WriteReferent(t, x => WriteStructInternal(x)), variance);
1165+
WriteStructPointerArray(array, (int)variance);
11181166
}
11191167
}
11201168

NtApiDotNet/Ndr/Marshal/NdrUnmarshalBuffer.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,25 @@ private string[] ReadStringArray(int[] refs, Func<string> reader)
5454
return ret;
5555
}
5656

57+
private T?[] ReadStructPointerArray<T>(int[] refs, bool full_pointer) where T : struct, INdrStructure
58+
{
59+
T?[] ret = new T?[refs.Length];
60+
for (int i = 0; i < refs.Length; ++i)
61+
{
62+
if (refs[i] == 0)
63+
{
64+
ret[i] = null;
65+
}
66+
else
67+
{
68+
int pos = i;
69+
Func<T> unmarshal = ReadStruct<T>;
70+
_deferred_reads.Add(() => ret[pos] = full_pointer ? ReadFullPointer(refs[i], unmarshal) : unmarshal());
71+
}
72+
}
73+
return ret;
74+
}
75+
5776
private bool SetupConformance(int dimensions)
5877
{
5978
if (_conformance_values == null)
@@ -437,7 +456,7 @@ public T[] ReadConformantArrayCallback<T>(Func<T> reader)
437456
{
438457
using (var queue = _deferred_reads.Push())
439458
{
440-
return ReadConformantArrayCallback(() => ReadReferentValue(ReadStructInternal<T>, full_pointer));
459+
return ReadStructPointerArray<T>(ReadConformantArrayCallback(ReadInt32), full_pointer);
441460
}
442461
}
443462

@@ -539,7 +558,7 @@ public T[] ReadVaryingArrayCallback<T>(Func<T> reader)
539558
{
540559
using (var queue = _deferred_reads.Push())
541560
{
542-
return ReadVaryingArrayCallback(() => ReadReferentValue(ReadStruct<T>, full_pointer));
561+
return ReadStructPointerArray<T>(ReadVaryingArrayCallback(ReadInt32), full_pointer);
543562
}
544563
}
545564

@@ -653,7 +672,7 @@ public T[] ReadConformantVaryingArrayCallback<T>(Func<T> reader)
653672
{
654673
using (var queue = _deferred_reads.Push())
655674
{
656-
return ReadConformantVaryingArrayCallback(() => ReadReferentValue(ReadStructInternal<T>, full_pointer));
675+
return ReadStructPointerArray<T>(ReadConformantVaryingArrayCallback(ReadInt32), full_pointer);
657676
}
658677
}
659678

0 commit comments

Comments
 (0)