ReactOS 0.4.16-dev-1946-g52006dd
ndr_contexthandle.c
Go to the documentation of this file.
1/*
2 * NDR data marshalling
3 *
4 * Copyright 2006 Mike McCormack (for CodeWeavers)
5 * Copyright 2006-2007 Robert Shearman (for CodeWeavers)
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdlib.h>
23
24#include "ndr_misc.h"
25#include "rpc_assoc.h"
26#include "rpcndr.h"
27#include "cguid.h"
28
29#include "wine/debug.h"
30#include "wine/list.h"
31
33
34#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
35
36typedef struct ndr_context_handle
37{
41
43{
44 struct list entry;
48};
49
51
54{
55 0, 0, &ndr_context_cs,
57 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
58};
59static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
60
62{
63 struct context_handle_entry *che = CContext;
64
66 return NULL;
67 return che;
68}
69
71{
72 struct context_handle_entry *che;
74 if (IsEqualGUID(&che->wire_data.uuid, uuid))
75 return che;
76 return NULL;
77}
78
80{
81 struct context_handle_entry *che;
83
84 TRACE("%p\n", CContext);
85
88 if (che)
89 handle = che->handle;
91
92 if (!handle)
93 {
94 ERR("invalid handle %p\n", CContext);
96 }
97 return handle;
98}
99
101{
102 struct context_handle_entry *che;
103
104 TRACE("%p %p\n", CContext, pBuff);
105
106 if (CContext)
107 {
110 memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
112 }
113 else
114 {
118 }
119}
120
121/***********************************************************************
122 * RpcSmDestroyClientContext [RPCRT4.@]
123 */
125{
127 struct context_handle_entry *che = NULL;
128
129 TRACE("(%p)\n", ContextHandle);
130
132 che = get_context_entry(*ContextHandle);
133 *ContextHandle = NULL;
134 if (che)
135 {
137 list_remove(&che->entry);
138 }
139
141
142 if (che)
143 {
144 RpcBindingFree(&che->handle);
145 free(che);
146 }
147
148 return status;
149}
150
151/***********************************************************************
152 * RpcSsDestroyClientContext [RPCRT4.@]
153 */
154void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
155{
157 if (status != RPC_S_OK)
159}
160
161/***********************************************************************
162 * RpcSsDontSerializeContext [RPCRT4.@]
163 */
165{
166 FIXME("stub\n");
167}
168
171 const ndr_context_handle *chi)
172{
173 struct context_handle_entry *che = NULL;
174
175 /* a null UUID means we should free the context handle */
176 if (IsEqualGUID(&chi->uuid, &GUID_NULL))
177 {
178 if (*CContext)
179 {
181 if (!che)
183 list_remove(&che->entry);
184 RpcBindingFree(&che->handle);
185 free(che);
186 che = NULL;
187 }
188 }
189 /* if there's no existing entry matching the GUID, allocate one */
190 else if (!(che = context_entry_from_guid(&chi->uuid)))
191 {
192 che = malloc(sizeof *che);
193 if (!che)
194 return RPC_X_NO_MEMORY;
198 che->wire_data = *chi;
199 }
200
201 *CContext = che;
202
203 return RPC_S_OK;
204}
205
206/***********************************************************************
207 * NDRCContextUnmarshall [RPCRT4.@]
208 */
211 void *pBuff, ULONG DataRepresentation)
212{
214
215 TRACE("*%p=(%p) %p %p %08lx\n",
216 CContext, *CContext, hBinding, pBuff, DataRepresentation);
217
221 if (status)
223}
224
225/***********************************************************************
226 * NDRSContextMarshall [RPCRT4.@]
227 */
229 void *pBuff,
230 NDR_RUNDOWN userRunDownIn)
231{
232 TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn);
234 userRunDownIn, NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
235}
236
237/***********************************************************************
238 * NDRSContextMarshallEx [RPCRT4.@]
239 */
241 NDR_SCONTEXT SContext,
242 void *pBuff,
243 NDR_RUNDOWN userRunDownIn)
244{
245 TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn);
246 NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL,
248}
249
250/***********************************************************************
251 * NDRSContextMarshall2 [RPCRT4.@]
252 */
254 NDR_SCONTEXT SContext,
255 void *pBuff,
256 NDR_RUNDOWN userRunDownIn,
257 void *CtxGuard, ULONG Flags)
258{
261 ndr_context_handle *ndr = pBuff;
262
263 TRACE("(%p %p %p %p %p %lu)\n",
264 hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags);
265
266 if (!binding->server || !binding->Assoc)
268
269 if (SContext->userContext)
270 {
271 status = RpcServerAssoc_UpdateContextHandle(binding->Assoc, SContext, CtxGuard, userRunDownIn);
272 if (status != RPC_S_OK)
274 ndr->attributes = 0;
275 RpcContextHandle_GetUuid(SContext, &ndr->uuid);
276
279 }
280 else
281 {
282 if (!RpcContextHandle_IsGuardCorrect(SContext, CtxGuard))
284 memset(ndr, 0, sizeof(*ndr));
285
287 /* Note: release the context handle twice in this case to release
288 * one ref being kept around for the data and one ref for the
289 * unmarshall/marshall sequence */
290 if (!RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE))
291 return; /* this is to cope with the case of the data not being valid
292 * before and so not having a further reference */
294 }
295}
296
297/***********************************************************************
298 * NDRSContextUnmarshall [RPCRT4.@]
299 */
301 ULONG DataRepresentation)
302{
303 TRACE("(%p %08lx)\n", pBuff, DataRepresentation);
305 DataRepresentation, NULL,
307}
308
309/***********************************************************************
310 * NDRSContextUnmarshallEx [RPCRT4.@]
311 */
313 void *pBuff,
314 ULONG DataRepresentation)
315{
316 TRACE("(%p %p %08lx)\n", hBinding, pBuff, DataRepresentation);
317 return NDRSContextUnmarshall2(hBinding, pBuff, DataRepresentation, NULL,
319}
320
321/***********************************************************************
322 * NDRSContextUnmarshall2 [RPCRT4.@]
323 */
325 void *pBuff,
326 ULONG DataRepresentation,
327 void *CtxGuard, ULONG Flags)
328{
330 NDR_SCONTEXT SContext;
332 const ndr_context_handle *context_ndr = pBuff;
333
334 TRACE("(%p %p %08lx %p %lu)\n",
335 hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
336
337 if (!binding->server || !binding->Assoc)
339
340 if (!pBuff || (!context_ndr->attributes &&
341 UuidIsNil((UUID *)&context_ndr->uuid, &status)))
343 &SContext);
344 else
345 {
346 if (context_ndr->attributes)
347 {
348 ERR("non-null attributes 0x%lx\n", context_ndr->attributes);
350 }
351 else
353 &context_ndr->uuid,
354 CtxGuard, Flags,
355 &SContext);
356 }
357
358 if (status != RPC_S_OK)
360
362 return SContext;
363}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: list.h:37
handle_t hBinding
Definition: ctx_c.c:54
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned long DWORD
Definition: ntddk_ex.h:95
Definition: msctf.idl:532
uint32_t entry
Definition: isohybrid.c:63
#define GUID_NULL
Definition: ks.h:106
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static RPC_BINDING_HANDLE binding
Definition: server.c:166
void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
static CRITICAL_SECTION ndr_context_cs
void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding, NDR_SCONTEXT SContext, void *pBuff, NDR_RUNDOWN userRunDownIn)
RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
void WINAPI RpcSsDontSerializeContext(void)
RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
static CRITICAL_SECTION_DEBUG ndr_context_debug
NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding, void *pBuff, ULONG DataRepresentation, void *CtxGuard, ULONG Flags)
void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext, RPC_BINDING_HANDLE hBinding, void *pBuff, ULONG DataRepresentation)
struct ndr_context_handle ndr_context_handle
#define NDR_CONTEXT_HANDLE_MAGIC
static struct context_handle_entry * get_context_entry(NDR_CCONTEXT CContext)
NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding, void *pBuff, ULONG DataRepresentation)
NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff, ULONG DataRepresentation)
static RPC_STATUS ndr_update_context_handle(NDR_CCONTEXT *CContext, RPC_BINDING_HANDLE hBinding, const ndr_context_handle *chi)
void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding, NDR_SCONTEXT SContext, void *pBuff, NDR_RUNDOWN userRunDownIn, void *CtxGuard, ULONG Flags)
void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
static struct context_handle_entry * context_entry_from_guid(LPCGUID uuid)
void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext, void *pBuff, NDR_RUNDOWN userRunDownIn)
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext)
Definition: rpc_assoc.c:488
void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid)
Definition: rpc_assoc.c:542
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine)
Definition: rpc_assoc.c:516
BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard)
Definition: rpc_assoc.c:482
unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock)
Definition: rpc_assoc.c:565
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext)
Definition: rpc_assoc.c:456
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:769
RPC_STATUS RPC_ENTRY RpcBindingCopy(RPC_BINDING_HANDLE SourceBinding, RPC_BINDING_HANDLE *DestinationBinding)
Definition: rpc_binding.c:971
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext)
Definition: rpcrt4_main.c:1026
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext)
Definition: rpcrt4_main.c:1011
RPC_BINDING_HANDLE WINAPI I_RpcGetCurrentCallHandle(void)
Definition: rpc_server.c:1743
#define RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
Definition: rpcdcep.h:56
void(__RPC_USER * NDR_RUNDOWN)(void *context)
Definition: rpcndr.h:118
#define RPC_X_SS_CONTEXT_MISMATCH
Definition: rpcnterr.h:39
#define RPC_X_NO_MEMORY
Definition: rpcnterr.h:35
#define RPC_S_OK
Definition: rpcnterr.h:22
int WINAPI UuidIsNil(UUID *Uuid, RPC_STATUS *Status)
Definition: rpcrt4_main.c:293
void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception)
Definition: rpcrt4_main.c:213
long RPC_STATUS
Definition: rpc.h:48
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
void * userContext
Definition: rpcndr.h:112
ndr_context_handle wire_data
DWORD magic
struct list entry
RPC_BINDING_HANDLE handle
Definition: ps.c:97
#define LIST_INIT(head)
Definition: queue.h:197
#define DWORD_PTR
Definition: treelist.c:76
uint32_t ULONG
Definition: typedefs.h:59
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1369
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList