2 * Full Pointer Translation Routines
4 * Copyright 2006 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
25 PFULL_PTR_XLAT_TABLES WINAPI
NdrFullPointerXlatInit(ULONG NumberOfPointers
,
28 ULONG NumberOfBuckets
;
29 PFULL_PTR_XLAT_TABLES pXlatTables
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables
));
31 TRACE("(%d, %d)\n", NumberOfPointers
, XlatSide
);
33 if (!NumberOfPointers
) NumberOfPointers
= 512;
34 NumberOfBuckets
= ((NumberOfPointers
+ 3) & ~3) - 1;
36 pXlatTables
->RefIdToPointer
.XlatTable
=
37 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
38 sizeof(void *) * NumberOfPointers
);
39 pXlatTables
->RefIdToPointer
.StateTable
=
40 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
41 sizeof(unsigned char) * NumberOfPointers
);
42 pXlatTables
->RefIdToPointer
.NumberOfEntries
= NumberOfPointers
;
44 TRACE("NumberOfBuckets = %d\n", NumberOfBuckets
);
45 pXlatTables
->PointerToRefId
.XlatTable
=
46 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
47 sizeof(PFULL_PTR_TO_REFID_ELEMENT
) * NumberOfBuckets
);
48 pXlatTables
->PointerToRefId
.NumberOfBuckets
= NumberOfBuckets
;
49 pXlatTables
->PointerToRefId
.HashMask
= NumberOfBuckets
- 1;
51 pXlatTables
->NextRefId
= 1;
52 pXlatTables
->XlatSide
= XlatSide
;
57 void WINAPI
NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables
)
61 TRACE("(%p)\n", pXlatTables
);
63 /* free the entries in the table */
64 for (i
= 0; i
< pXlatTables
->PointerToRefId
.NumberOfBuckets
; i
++)
66 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
67 for (XlatTableEntry
= pXlatTables
->PointerToRefId
.XlatTable
[i
];
70 PFULL_PTR_TO_REFID_ELEMENT Next
= XlatTableEntry
->Next
;
71 HeapFree(GetProcessHeap(), 0, XlatTableEntry
);
72 XlatTableEntry
= Next
;
76 HeapFree(GetProcessHeap(), 0, pXlatTables
->RefIdToPointer
.XlatTable
);
77 HeapFree(GetProcessHeap(), 0, pXlatTables
->RefIdToPointer
.StateTable
);
78 HeapFree(GetProcessHeap(), 0, pXlatTables
->PointerToRefId
.XlatTable
);
80 HeapFree(GetProcessHeap(), 0, pXlatTables
);
83 static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables
, ULONG RefId
)
85 if (RefId
>= pXlatTables
->RefIdToPointer
.NumberOfEntries
)
87 pXlatTables
->RefIdToPointer
.NumberOfEntries
= RefId
* 2;
88 pXlatTables
->RefIdToPointer
.XlatTable
=
89 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
90 pXlatTables
->RefIdToPointer
.XlatTable
,
91 sizeof(void *) * pXlatTables
->RefIdToPointer
.NumberOfEntries
);
92 pXlatTables
->RefIdToPointer
.StateTable
=
93 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
94 pXlatTables
->RefIdToPointer
.StateTable
,
95 sizeof(unsigned char) * pXlatTables
->RefIdToPointer
.NumberOfEntries
);
97 if (!pXlatTables
->RefIdToPointer
.XlatTable
|| !pXlatTables
->RefIdToPointer
.StateTable
)
98 pXlatTables
->RefIdToPointer
.NumberOfEntries
= 0;
102 int WINAPI
NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables
,
103 void *pPointer
, unsigned char QueryType
,
108 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
110 TRACE("(%p, %p, %d, %p)\n", pXlatTables
, pPointer
, QueryType
, pRefId
);
118 /* simple hashing algorithm, don't know whether it matches native */
119 for (i
= 0; i
< sizeof(pPointer
); i
++)
120 Hash
= (Hash
* 3) ^ ((unsigned char *)&pPointer
)[i
];
122 XlatTableEntry
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
123 for (; XlatTableEntry
; XlatTableEntry
= XlatTableEntry
->Next
)
124 if (pPointer
== XlatTableEntry
->Pointer
)
126 *pRefId
= XlatTableEntry
->RefId
;
127 if (XlatTableEntry
->State
& QueryType
)
129 XlatTableEntry
->State
|= QueryType
;
133 XlatTableEntry
= HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry
));
134 XlatTableEntry
->Next
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
135 XlatTableEntry
->Pointer
= pPointer
;
136 XlatTableEntry
->RefId
= *pRefId
= pXlatTables
->NextRefId
++;
137 XlatTableEntry
->State
= QueryType
;
138 pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
] = XlatTableEntry
;
140 /* insert pointer into mapping table */
141 expand_pointer_table_if_necessary(pXlatTables
, XlatTableEntry
->RefId
);
142 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> XlatTableEntry
->RefId
)
144 pXlatTables
->RefIdToPointer
.XlatTable
[XlatTableEntry
->RefId
] = pPointer
;
145 pXlatTables
->RefIdToPointer
.StateTable
[XlatTableEntry
->RefId
] = QueryType
;
151 int WINAPI
NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables
,
152 ULONG RefId
, unsigned char QueryType
,
155 TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables
, RefId
, QueryType
, ppPointer
);
160 expand_pointer_table_if_necessary(pXlatTables
, RefId
);
162 pXlatTables
->NextRefId
= max(RefId
+ 1, pXlatTables
->NextRefId
);
164 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> RefId
)
166 *ppPointer
= pXlatTables
->RefIdToPointer
.XlatTable
[RefId
];
169 if (pXlatTables
->RefIdToPointer
.StateTable
[RefId
] & QueryType
)
171 pXlatTables
->RefIdToPointer
.StateTable
[RefId
] |= QueryType
;
181 void WINAPI
NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables
,
182 ULONG RefId
, void *pPointer
)
186 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
188 TRACE("(%p, 0x%x, %p)\n", pXlatTables
, RefId
, pPointer
);
190 /* simple hashing algorithm, don't know whether it matches native */
191 for (i
= 0; i
< sizeof(pPointer
); i
++)
192 Hash
= (Hash
* 3) ^ ((unsigned char *)&pPointer
)[i
];
194 XlatTableEntry
= HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry
));
195 XlatTableEntry
->Next
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
196 XlatTableEntry
->Pointer
= pPointer
;
197 XlatTableEntry
->RefId
= RefId
;
198 XlatTableEntry
->State
= 0;
199 pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
] = XlatTableEntry
;
201 /* insert pointer into mapping table */
202 expand_pointer_table_if_necessary(pXlatTables
, RefId
);
203 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> RefId
)
204 pXlatTables
->RefIdToPointer
.XlatTable
[XlatTableEntry
->RefId
] = pPointer
;
207 int WINAPI
NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables
, void *Pointer
)
211 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
214 TRACE("(%p, %p)\n", pXlatTables
, Pointer
);
219 /* simple hashing algorithm, don't know whether it matches native */
220 for (i
= 0; i
< sizeof(Pointer
); i
++)
221 Hash
= (Hash
* 3) ^ ((unsigned char *)&Pointer
)[i
];
223 XlatTableEntry
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
224 for (; XlatTableEntry
; XlatTableEntry
= XlatTableEntry
->Next
)
225 if (Pointer
== XlatTableEntry
->Pointer
)
227 if (XlatTableEntry
->State
& 0x20)
229 XlatTableEntry
->State
|= 0x20;
230 RefId
= XlatTableEntry
->RefId
;
237 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> RefId
)
239 pXlatTables
->RefIdToPointer
.StateTable
[RefId
] |= 0x20;