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
21 #define WIN32_NO_STATUS
31 #include <wine/debug.h>
33 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
35 PFULL_PTR_XLAT_TABLES WINAPI
NdrFullPointerXlatInit(ULONG NumberOfPointers
,
38 ULONG NumberOfBuckets
;
39 PFULL_PTR_XLAT_TABLES pXlatTables
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables
));
41 TRACE("(%d, %d)\n", NumberOfPointers
, XlatSide
);
43 if (!NumberOfPointers
) NumberOfPointers
= 512;
44 NumberOfBuckets
= ((NumberOfPointers
+ 3) & ~3) - 1;
46 pXlatTables
->RefIdToPointer
.XlatTable
=
47 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
48 sizeof(void *) * NumberOfPointers
);
49 pXlatTables
->RefIdToPointer
.StateTable
=
50 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
51 sizeof(unsigned char) * NumberOfPointers
);
52 pXlatTables
->RefIdToPointer
.NumberOfEntries
= NumberOfPointers
;
54 TRACE("NumberOfBuckets = %d\n", NumberOfBuckets
);
55 pXlatTables
->PointerToRefId
.XlatTable
=
56 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
57 sizeof(PFULL_PTR_TO_REFID_ELEMENT
) * NumberOfBuckets
);
58 pXlatTables
->PointerToRefId
.NumberOfBuckets
= NumberOfBuckets
;
59 pXlatTables
->PointerToRefId
.HashMask
= NumberOfBuckets
- 1;
61 pXlatTables
->NextRefId
= 1;
62 pXlatTables
->XlatSide
= XlatSide
;
67 void WINAPI
NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables
)
71 TRACE("(%p)\n", pXlatTables
);
73 /* free the entries in the table */
74 for (i
= 0; i
< pXlatTables
->PointerToRefId
.NumberOfBuckets
; i
++)
76 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
77 for (XlatTableEntry
= pXlatTables
->PointerToRefId
.XlatTable
[i
];
80 PFULL_PTR_TO_REFID_ELEMENT Next
= XlatTableEntry
->Next
;
81 HeapFree(GetProcessHeap(), 0, XlatTableEntry
);
82 XlatTableEntry
= Next
;
86 HeapFree(GetProcessHeap(), 0, pXlatTables
->RefIdToPointer
.XlatTable
);
87 HeapFree(GetProcessHeap(), 0, pXlatTables
->RefIdToPointer
.StateTable
);
88 HeapFree(GetProcessHeap(), 0, pXlatTables
->PointerToRefId
.XlatTable
);
90 HeapFree(GetProcessHeap(), 0, pXlatTables
);
93 static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables
, ULONG RefId
)
95 if (RefId
>= pXlatTables
->RefIdToPointer
.NumberOfEntries
)
97 pXlatTables
->RefIdToPointer
.NumberOfEntries
= RefId
* 2;
98 pXlatTables
->RefIdToPointer
.XlatTable
=
99 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
100 pXlatTables
->RefIdToPointer
.XlatTable
,
101 sizeof(void *) * pXlatTables
->RefIdToPointer
.NumberOfEntries
);
102 pXlatTables
->RefIdToPointer
.StateTable
=
103 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
104 pXlatTables
->RefIdToPointer
.StateTable
,
105 sizeof(unsigned char) * pXlatTables
->RefIdToPointer
.NumberOfEntries
);
107 if (!pXlatTables
->RefIdToPointer
.XlatTable
|| !pXlatTables
->RefIdToPointer
.StateTable
)
108 pXlatTables
->RefIdToPointer
.NumberOfEntries
= 0;
112 int WINAPI
NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables
,
113 void *pPointer
, unsigned char QueryType
,
118 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
120 TRACE("(%p, %p, %d, %p)\n", pXlatTables
, pPointer
, QueryType
, pRefId
);
128 /* simple hashing algorithm, don't know whether it matches native */
129 for (i
= 0; i
< sizeof(pPointer
); i
++)
130 Hash
= (Hash
* 3) ^ ((unsigned char *)&pPointer
)[i
];
132 XlatTableEntry
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
133 for (; XlatTableEntry
; XlatTableEntry
= XlatTableEntry
->Next
)
134 if (pPointer
== XlatTableEntry
->Pointer
)
136 *pRefId
= XlatTableEntry
->RefId
;
137 if (XlatTableEntry
->State
& QueryType
)
139 XlatTableEntry
->State
|= QueryType
;
143 XlatTableEntry
= HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry
));
144 XlatTableEntry
->Next
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
145 XlatTableEntry
->Pointer
= pPointer
;
146 XlatTableEntry
->RefId
= *pRefId
= pXlatTables
->NextRefId
++;
147 XlatTableEntry
->State
= QueryType
;
148 pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
] = XlatTableEntry
;
150 /* insert pointer into mapping table */
151 expand_pointer_table_if_necessary(pXlatTables
, XlatTableEntry
->RefId
);
152 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> XlatTableEntry
->RefId
)
154 pXlatTables
->RefIdToPointer
.XlatTable
[XlatTableEntry
->RefId
] = pPointer
;
155 pXlatTables
->RefIdToPointer
.StateTable
[XlatTableEntry
->RefId
] = QueryType
;
161 int WINAPI
NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables
,
162 ULONG RefId
, unsigned char QueryType
,
165 TRACE("(%p, 0x%x, %d, %p)\n", pXlatTables
, RefId
, QueryType
, ppPointer
);
170 expand_pointer_table_if_necessary(pXlatTables
, RefId
);
172 pXlatTables
->NextRefId
= max(RefId
+ 1, pXlatTables
->NextRefId
);
174 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> RefId
)
176 *ppPointer
= pXlatTables
->RefIdToPointer
.XlatTable
[RefId
];
179 if (pXlatTables
->RefIdToPointer
.StateTable
[RefId
] & QueryType
)
181 pXlatTables
->RefIdToPointer
.StateTable
[RefId
] |= QueryType
;
191 void WINAPI
NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables
,
192 ULONG RefId
, void *pPointer
)
196 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
198 TRACE("(%p, 0x%x, %p)\n", pXlatTables
, RefId
, pPointer
);
200 /* simple hashing algorithm, don't know whether it matches native */
201 for (i
= 0; i
< sizeof(pPointer
); i
++)
202 Hash
= (Hash
* 3) ^ ((unsigned char *)&pPointer
)[i
];
204 XlatTableEntry
= HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry
));
205 XlatTableEntry
->Next
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
206 XlatTableEntry
->Pointer
= pPointer
;
207 XlatTableEntry
->RefId
= RefId
;
208 XlatTableEntry
->State
= 0;
209 pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
] = XlatTableEntry
;
211 /* insert pointer into mapping table */
212 expand_pointer_table_if_necessary(pXlatTables
, RefId
);
213 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> RefId
)
214 pXlatTables
->RefIdToPointer
.XlatTable
[XlatTableEntry
->RefId
] = pPointer
;
217 int WINAPI
NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables
, void *Pointer
)
221 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry
;
224 TRACE("(%p, %p)\n", pXlatTables
, Pointer
);
229 /* simple hashing algorithm, don't know whether it matches native */
230 for (i
= 0; i
< sizeof(Pointer
); i
++)
231 Hash
= (Hash
* 3) ^ ((unsigned char *)&Pointer
)[i
];
233 XlatTableEntry
= pXlatTables
->PointerToRefId
.XlatTable
[Hash
& pXlatTables
->PointerToRefId
.HashMask
];
234 for (; XlatTableEntry
; XlatTableEntry
= XlatTableEntry
->Next
)
235 if (Pointer
== XlatTableEntry
->Pointer
)
237 if (XlatTableEntry
->State
& 0x20)
239 XlatTableEntry
->State
|= 0x20;
240 RefId
= XlatTableEntry
->RefId
;
247 if (pXlatTables
->RefIdToPointer
.NumberOfEntries
> RefId
)
249 pXlatTables
->RefIdToPointer
.StateTable
[RefId
] |= 0x20;