ReactOS  0.4.14-dev-55-g2da92ac
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 "ndr_misc.h"
23 #include "rpc_assoc.h"
24 #include "rpcndr.h"
25 
26 #include "wine/debug.h"
27 #include "wine/list.h"
28 
30 
31 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
32 
33 typedef struct ndr_context_handle
34 {
38 
40 {
41  struct list entry;
45 };
46 
48 
51 {
52  0, 0, &ndr_context_cs,
54  0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
55 };
56 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
57 
59 {
60  struct context_handle_entry *che = CContext;
61 
62  if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
63  return NULL;
64  return che;
65 }
66 
68 {
69  struct context_handle_entry *che;
71  if (IsEqualGUID(&che->wire_data.uuid, uuid))
72  return che;
73  return NULL;
74 }
75 
77 {
78  struct context_handle_entry *che;
80 
81  TRACE("%p\n", CContext);
82 
84  che = get_context_entry(CContext);
85  if (che)
86  handle = che->handle;
88 
89  if (!handle)
90  {
91  ERR("invalid handle %p\n", CContext);
93  }
94  return handle;
95 }
96 
97 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
98 {
99  struct context_handle_entry *che;
100 
101  TRACE("%p %p\n", CContext, pBuff);
102 
103  if (CContext)
104  {
106  che = get_context_entry(CContext);
107  memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
109  }
110  else
111  {
112  ndr_context_handle *wire_data = pBuff;
113  wire_data->attributes = 0;
115  }
116 }
117 
118 /***********************************************************************
119  * RpcSmDestroyClientContext [RPCRT4.@]
120  */
122 {
124  struct context_handle_entry *che = NULL;
125 
126  TRACE("(%p)\n", ContextHandle);
127 
129  che = get_context_entry(*ContextHandle);
130  *ContextHandle = NULL;
131  if (che)
132  {
133  status = RPC_S_OK;
134  list_remove(&che->entry);
135  }
136 
138 
139  if (che)
140  {
141  RpcBindingFree(&che->handle);
142  HeapFree(GetProcessHeap(), 0, che);
143  }
144 
145  return status;
146 }
147 
148 /***********************************************************************
149  * RpcSsDestroyClientContext [RPCRT4.@]
150  */
151 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
152 {
154  if (status != RPC_S_OK)
156 }
157 
158 /***********************************************************************
159  * RpcSsDontSerializeContext [RPCRT4.@]
160  */
162 {
163  FIXME("stub\n");
164 }
165 
168  const ndr_context_handle *chi)
169 {
170  struct context_handle_entry *che = NULL;
171 
172  /* a null UUID means we should free the context handle */
173  if (IsEqualGUID(&chi->uuid, &GUID_NULL))
174  {
175  if (*CContext)
176  {
177  che = get_context_entry(*CContext);
178  if (!che)
180  list_remove(&che->entry);
181  RpcBindingFree(&che->handle);
182  HeapFree(GetProcessHeap(), 0, che);
183  che = NULL;
184  }
185  }
186  /* if there's no existing entry matching the GUID, allocate one */
187  else if (!(che = context_entry_from_guid(&chi->uuid)))
188  {
189  che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
190  if (!che)
191  return RPC_X_NO_MEMORY;
195  che->wire_data = *chi;
196  }
197 
198  *CContext = che;
199 
200  return RPC_S_OK;
201 }
202 
203 /***********************************************************************
204  * NDRCContextUnmarshall [RPCRT4.@]
205  */
208  void *pBuff, ULONG DataRepresentation)
209 {
211 
212  TRACE("*%p=(%p) %p %p %08x\n",
213  CContext, *CContext, hBinding, pBuff, DataRepresentation);
214 
216  status = ndr_update_context_handle(CContext, hBinding, pBuff);
218  if (status)
220 }
221 
222 /***********************************************************************
223  * NDRSContextMarshall [RPCRT4.@]
224  */
226  void *pBuff,
227  NDR_RUNDOWN userRunDownIn)
228 {
229  TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn);
231  userRunDownIn, NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
232 }
233 
234 /***********************************************************************
235  * NDRSContextMarshallEx [RPCRT4.@]
236  */
238  NDR_SCONTEXT SContext,
239  void *pBuff,
240  NDR_RUNDOWN userRunDownIn)
241 {
242  TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn);
243  NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL,
245 }
246 
247 /***********************************************************************
248  * NDRSContextMarshall2 [RPCRT4.@]
249  */
251  NDR_SCONTEXT SContext,
252  void *pBuff,
253  NDR_RUNDOWN userRunDownIn,
254  void *CtxGuard, ULONG Flags)
255 {
256  RpcBinding *binding = hBinding;
258  ndr_context_handle *ndr = pBuff;
259 
260  TRACE("(%p %p %p %p %p %u)\n",
261  hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags);
262 
263  if (!binding->server || !binding->Assoc)
265 
267  FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);
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 
278  RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE);
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 */
293  RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, FALSE);
294  }
295 }
296 
297 /***********************************************************************
298  * NDRSContextUnmarshall [RPCRT4.@]
299  */
301  ULONG DataRepresentation)
302 {
303  TRACE("(%p %08x)\n", pBuff, DataRepresentation);
305  DataRepresentation, NULL,
307 }
308 
309 /***********************************************************************
310  * NDRSContextUnmarshallEx [RPCRT4.@]
311  */
313  void *pBuff,
314  ULONG DataRepresentation)
315 {
316  TRACE("(%p %p %08x)\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 {
329  RpcBinding *binding = hBinding;
330  NDR_SCONTEXT SContext;
332  const ndr_context_handle *context_ndr = pBuff;
333 
334  TRACE("(%p %p %08x %p %u)\n",
335  hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
336 
337  if (!binding->server || !binding->Assoc)
339 
341  FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);
342 
343  if (!pBuff || (!context_ndr->attributes &&
344  UuidIsNil((UUID *)&context_ndr->uuid, &status)))
346  &SContext);
347  else
348  {
349  if (context_ndr->attributes)
350  {
351  ERR("non-null attributes 0x%x\n", context_ndr->attributes);
353  }
354  else
356  &context_ndr->uuid,
357  CtxGuard, Flags,
358  &SContext);
359  }
360 
361  if (status != RPC_S_OK)
363 
365  return SContext;
366 }
void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid)
Definition: rpc_assoc.c:542
struct _RpcAssoc * Assoc
Definition: rpc_binding.h:137
#define RPC_X_SS_CONTEXT_MISMATCH
Definition: rpcnterr.h:39
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:784
struct ndr_context_handle ndr_context_handle
#define RPC_X_NO_MEMORY
Definition: rpcnterr.h:35
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
static struct context_handle_entry * context_entry_from_guid(LPCGUID uuid)
#define DWORD_PTR
Definition: treelist.c:76
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
handle_t hBinding
Definition: ctx_c.c:54
NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding, void *pBuff, ULONG DataRepresentation)
void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception)
Definition: rpcrt4_main.c:189
static CRITICAL_SECTION ndr_context_cs
void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext)
Definition: rpc_assoc.c:457
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding, NDR_SCONTEXT SContext, void *pBuff, NDR_RUNDOWN userRunDownIn)
#define RPC_CONTEXT_HANDLE_FLAGS
Definition: rpcdcep.h:57
WINE_DEFAULT_DEBUG_CHANNEL(ole)
void * userContext
Definition: rpcndr.h:147
void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext) DECLSPEC_HIDDEN
Definition: rpcrt4_main.c:981
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
int WINAPI UuidIsNil(UUID *Uuid, RPC_STATUS *Status)
Definition: rpcrt4_main.c:269
long RPC_STATUS
Definition: rpc.h:52
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
void WINAPI RpcSsDontSerializeContext(void)
RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine)
Definition: rpc_assoc.c:516
#define FIXME(fmt,...)
Definition: debug.h:110
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1013
smooth NULL
Definition: ftsmooth.c:416
#define RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
Definition: rpcdcep.h:56
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define TRACE(s)
Definition: solgame.cpp:4
#define NDR_CONTEXT_HANDLE_MAGIC
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define LIST_INIT(head)
Definition: queue.h:197
NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff, ULONG DataRepresentation)
static struct context_handle_entry * get_context_entry(NDR_CCONTEXT CContext)
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static RPC_STATUS ndr_update_context_handle(NDR_CCONTEXT *CContext, RPC_BINDING_HANDLE hBinding, const ndr_context_handle *chi)
void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext) DECLSPEC_HIDDEN
Definition: rpcrt4_main.c:996
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GUID_NULL
Definition: ks.h:106
Definition: _list.h:228
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848
RPC_BINDING_HANDLE WINAPI I_RpcGetCurrentCallHandle(void)
Definition: rpc_server.c:1746
void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
#define ERR(fmt,...)
Definition: debug.h:109
unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock)
Definition: rpc_assoc.c:564
void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext, void *pBuff, NDR_RUNDOWN userRunDownIn)
void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding, NDR_SCONTEXT SContext, void *pBuff, NDR_RUNDOWN userRunDownIn, void *CtxGuard, ULONG Flags)
RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext)
Definition: rpc_assoc.c:488
void(__RPC_USER * NDR_RUNDOWN)(void *context)
Definition: rpcndr.h:153
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
ndr_context_handle wire_data
void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext, RPC_BINDING_HANDLE hBinding, void *pBuff, ULONG DataRepresentation)
Definition: msctf.idl:510
DWORD magic
unsigned int ULONG
Definition: retypes.h:1
struct list entry
static CRITICAL_SECTION_DEBUG ndr_context_debug
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding, void *pBuff, ULONG DataRepresentation, void *CtxGuard, ULONG Flags)
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard)
Definition: rpc_assoc.c:482
RPC_STATUS RPC_ENTRY RpcBindingCopy(RPC_BINDING_HANDLE SourceBinding, RPC_BINDING_HANDLE *DestinationBinding)
Definition: rpc_binding.c:986
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
RPC_BINDING_HANDLE handle
Definition: ps.c:97