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
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
32 PFULL_PTR_XLAT_TABLES WINAPI NdrFullPointerXlatInit(unsigned long NumberOfPointers,
35 unsigned long NumberOfBuckets = ((NumberOfPointers + 3) & 4) - 1;
36 PFULL_PTR_XLAT_TABLES pXlatTables = HeapAlloc(GetProcessHeap(), 0, sizeof(*pXlatTables));
38 TRACE("(%ld, %d)\n", NumberOfPointers, XlatSide);
40 pXlatTables->RefIdToPointer.XlatTable =
41 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
42 sizeof(void *) * NumberOfPointers);
43 pXlatTables->RefIdToPointer.StateTable =
44 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
45 sizeof(unsigned char) * NumberOfPointers);
46 pXlatTables->RefIdToPointer.NumberOfEntries = NumberOfPointers;
48 TRACE("NumberOfBuckets = %ld\n", NumberOfBuckets);
49 pXlatTables->PointerToRefId.XlatTable =
50 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
51 sizeof(PFULL_PTR_TO_REFID_ELEMENT) * NumberOfBuckets);
52 pXlatTables->PointerToRefId.NumberOfBuckets = NumberOfBuckets;
53 pXlatTables->PointerToRefId.HashMask = NumberOfBuckets - 1;
55 pXlatTables->NextRefId = 1;
56 pXlatTables->XlatSide = XlatSide;
61 void WINAPI NdrFullPointerXlatFree(PFULL_PTR_XLAT_TABLES pXlatTables)
63 TRACE("(%p)\n", pXlatTables);
65 HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.XlatTable);
66 HeapFree(GetProcessHeap(), 0, pXlatTables->RefIdToPointer.StateTable);
67 HeapFree(GetProcessHeap(), 0, pXlatTables->PointerToRefId.XlatTable);
69 HeapFree(GetProcessHeap(), 0, pXlatTables);
72 static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, unsigned long RefId)
74 if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries)
76 pXlatTables->RefIdToPointer.NumberOfEntries = RefId * 2;
77 pXlatTables->RefIdToPointer.XlatTable =
78 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
79 pXlatTables->RefIdToPointer.XlatTable,
80 sizeof(void *) * pXlatTables->RefIdToPointer.NumberOfEntries);
81 pXlatTables->RefIdToPointer.StateTable =
82 HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
83 pXlatTables->RefIdToPointer.StateTable,
84 sizeof(unsigned char) * pXlatTables->RefIdToPointer.NumberOfEntries);
86 if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable)
87 pXlatTables->RefIdToPointer.NumberOfEntries = 0;
91 int WINAPI NdrFullPointerQueryPointer(PFULL_PTR_XLAT_TABLES pXlatTables,
92 void *pPointer, unsigned char QueryType,
93 unsigned long *pRefId )
95 unsigned long Hash = 0;
97 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
99 TRACE("(%p, %p, %d, %p)\n", pXlatTables, pPointer, QueryType, pRefId);
107 /* simple hashing algorithm, don't know whether it matches native */
108 for (i = 0; i < sizeof(pPointer); i++)
109 Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
111 XlatTableEntry = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
112 for (; XlatTableEntry; XlatTableEntry = XlatTableEntry->Next)
113 if (pPointer == XlatTableEntry->Pointer)
115 *pRefId = XlatTableEntry->RefId;
116 if (pXlatTables->XlatSide == XLAT_SERVER)
117 return XlatTableEntry->State;
122 XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
123 XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
124 XlatTableEntry->Pointer = pPointer;
125 XlatTableEntry->RefId = *pRefId = pXlatTables->NextRefId++;
126 XlatTableEntry->State = QueryType;
127 pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
129 /* insert pointer into mapping table */
130 expand_pointer_table_if_necessary(pXlatTables, XlatTableEntry->RefId);
131 if (pXlatTables->RefIdToPointer.NumberOfEntries > XlatTableEntry->RefId)
133 pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
134 pXlatTables->RefIdToPointer.StateTable[XlatTableEntry->RefId] = QueryType;
140 int WINAPI NdrFullPointerQueryRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
142 unsigned char QueryType, void **ppPointer)
144 TRACE("(%p, 0x%lx, %d, %p)\n", pXlatTables, RefId, QueryType, ppPointer);
146 expand_pointer_table_if_necessary(pXlatTables, RefId);
148 pXlatTables->NextRefId = max(RefId + 1, pXlatTables->NextRefId);
150 if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
152 *ppPointer = pXlatTables->RefIdToPointer.XlatTable[RefId];
154 return pXlatTables->RefIdToPointer.StateTable[RefId];
162 void WINAPI NdrFullPointerInsertRefId(PFULL_PTR_XLAT_TABLES pXlatTables,
163 unsigned long RefId, void *pPointer)
165 unsigned long Hash = 0;
167 PFULL_PTR_TO_REFID_ELEMENT XlatTableEntry;
169 TRACE("(%p, 0x%lx, %p)\n", pXlatTables, RefId, pPointer);
171 /* simple hashing algorithm, don't know whether it matches native */
172 for (i = 0; i < sizeof(pPointer); i++)
173 Hash = (Hash * 3) ^ ((unsigned char *)&pPointer)[i];
175 XlatTableEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(*XlatTableEntry));
176 XlatTableEntry->Next = pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask];
177 XlatTableEntry->Pointer = pPointer;
178 XlatTableEntry->RefId = RefId;
179 XlatTableEntry->State = 0;
180 pXlatTables->PointerToRefId.XlatTable[Hash & pXlatTables->PointerToRefId.HashMask] = XlatTableEntry;
182 /* insert pointer into mapping table */
183 expand_pointer_table_if_necessary(pXlatTables, RefId);
184 if (pXlatTables->RefIdToPointer.NumberOfEntries > RefId)
185 pXlatTables->RefIdToPointer.XlatTable[XlatTableEntry->RefId] = pPointer;
188 int WINAPI NdrFullPointerFree(PFULL_PTR_XLAT_TABLES pXlatTables, void *Pointer)
190 FIXME("(%p, %p)\n", pXlatTables, Pointer);