~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/rpcrt4/ndr_contexthandle.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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/rpcfc.h"
 27 
 28 #include "wine/debug.h"
 29 #include "wine/list.h"
 30 
 31 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 32 
 33 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
 34 
 35 typedef struct ndr_context_handle
 36 {
 37     ULONG      attributes;
 38     GUID       uuid;
 39 } ndr_context_handle;
 40 
 41 struct context_handle_entry
 42 {
 43     struct list entry;
 44     DWORD magic;
 45     RPC_BINDING_HANDLE handle;
 46     ndr_context_handle wire_data;
 47 };
 48 
 49 static struct list context_handle_list = LIST_INIT(context_handle_list);
 50 
 51 static CRITICAL_SECTION ndr_context_cs;
 52 static CRITICAL_SECTION_DEBUG ndr_context_debug =
 53 {
 54     0, 0, &ndr_context_cs,
 55     { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
 56       0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
 57 };
 58 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
 59 
 60 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
 61 {
 62     struct context_handle_entry *che = CContext;
 63 
 64     if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
 65         return NULL;
 66     return che;
 67 }
 68 
 69 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
 70 {
 71     struct context_handle_entry *che;
 72     LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
 73         if (IsEqualGUID(&che->wire_data.uuid, uuid))
 74             return che;
 75     return NULL;
 76 }
 77 
 78 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
 79 {
 80     struct context_handle_entry *che;
 81     RPC_BINDING_HANDLE handle = NULL;
 82 
 83     TRACE("%p\n", CContext);
 84 
 85     EnterCriticalSection(&ndr_context_cs);
 86     che = get_context_entry(CContext);
 87     if (che)
 88         handle = che->handle;
 89     LeaveCriticalSection(&ndr_context_cs);
 90 
 91     if (!handle)
 92     {
 93         ERR("invalid handle %p\n", CContext);
 94         RpcRaiseException(ERROR_INVALID_HANDLE);
 95     }
 96     return handle;
 97 }
 98 
 99 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
100 {
101     struct context_handle_entry *che;
102 
103     TRACE("%p %p\n", CContext, pBuff);
104 
105     if (CContext)
106     {
107         EnterCriticalSection(&ndr_context_cs);
108         che = get_context_entry(CContext);
109         memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
110         LeaveCriticalSection(&ndr_context_cs);
111     }
112     else
113     {
114         ndr_context_handle *wire_data = pBuff;
115         wire_data->attributes = 0;
116         wire_data->uuid = GUID_NULL;
117     }
118 }
119 
120 /***********************************************************************
121  *           RpcSmDestroyClientContext [RPCRT4.@]
122  */
123 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
124 {
125     RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
126     struct context_handle_entry *che = NULL;
127 
128     TRACE("(%p)\n", ContextHandle);
129 
130     EnterCriticalSection(&ndr_context_cs);
131     che = get_context_entry(*ContextHandle);
132     *ContextHandle = NULL;
133     if (che)
134     {
135         status = RPC_S_OK;
136         list_remove(&che->entry);
137     }
138 
139     LeaveCriticalSection(&ndr_context_cs);
140 
141     if (che)
142     {
143         RpcBindingFree(&che->handle);
144         HeapFree(GetProcessHeap(), 0, che);
145     }
146 
147     return status;
148 }
149 
150 /***********************************************************************
151  *           RpcSsDestroyClientContext [RPCRT4.@]
152  */
153 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
154 {
155     RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
156     if (status != RPC_S_OK)
157         RpcRaiseException(status);
158 }
159 
160 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
161                                       RPC_BINDING_HANDLE hBinding,
162                                       const ndr_context_handle *chi)
163 {
164     struct context_handle_entry *che = NULL;
165 
166     /* a null UUID means we should free the context handle */
167     if (IsEqualGUID(&chi->uuid, &GUID_NULL))
168     {
169         if (*CContext)
170         {
171             che = get_context_entry(*CContext);
172             if (!che)
173                 return ERROR_INVALID_HANDLE;
174             list_remove(&che->entry);
175             RpcBindingFree(&che->handle);
176             HeapFree(GetProcessHeap(), 0, che);
177             che = NULL;
178         }
179     }
180     /* if there's no existing entry matching the GUID, allocate one */
181     else if (!(che = context_entry_from_guid(&chi->uuid)))
182     {
183         che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
184         if (!che)
185             return ERROR_NOT_ENOUGH_MEMORY;
186         che->magic = NDR_CONTEXT_HANDLE_MAGIC;
187         RpcBindingCopy(hBinding, &che->handle);
188         list_add_tail(&context_handle_list, &che->entry);
189         che->wire_data = *chi;
190     }
191 
192     *CContext = che;
193 
194     return ERROR_SUCCESS;
195 }
196 
197 /***********************************************************************
198  *           NDRCContextUnmarshall [RPCRT4.@]
199  */
200 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
201                                   RPC_BINDING_HANDLE hBinding,
202                                   void *pBuff, ULONG DataRepresentation)
203 {
204     UINT r;
205 
206     TRACE("*%p=(%p) %p %p %08x\n",
207           CContext, *CContext, hBinding, pBuff, DataRepresentation);
208 
209     EnterCriticalSection(&ndr_context_cs);
210     r = ndr_update_context_handle(CContext, hBinding, pBuff);
211     LeaveCriticalSection(&ndr_context_cs);
212     if (r)
213         RpcRaiseException(r);
214 }
215 
216 /***********************************************************************
217  *           NDRSContextMarshall [RPCRT4.@]
218  */
219 void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext,
220                                void *pBuff,
221                                NDR_RUNDOWN userRunDownIn)
222 {
223     TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn);
224     NDRSContextMarshall2(I_RpcGetCurrentCallHandle(), SContext, pBuff,
225                          userRunDownIn, NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
226 }
227 
228 /***********************************************************************
229  *           NDRSContextMarshallEx [RPCRT4.@]
230  */
231 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
232                                   NDR_SCONTEXT SContext,
233                                   void *pBuff,
234                                   NDR_RUNDOWN userRunDownIn)
235 {
236     TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn);
237     NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL,
238                          RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
239 }
240 
241 /***********************************************************************
242  *           NDRSContextMarshall2 [RPCRT4.@]
243  */
244 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
245                                  NDR_SCONTEXT SContext,
246                                  void *pBuff,
247                                  NDR_RUNDOWN userRunDownIn,
248                                  void *CtxGuard, ULONG Flags)
249 {
250     RpcBinding *binding = hBinding;
251     RPC_STATUS status;
252     ndr_context_handle *ndr = pBuff;
253 
254     TRACE("(%p %p %p %p %p %u)\n",
255           hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags);
256 
257     if (!binding->server || !binding->Assoc)
258         RpcRaiseException(ERROR_INVALID_HANDLE);
259 
260     if (Flags & RPC_CONTEXT_HANDLE_FLAGS)
261         FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);
262 
263     if (SContext->userContext)
264     {
265         status = RpcServerAssoc_UpdateContextHandle(binding->Assoc, SContext, CtxGuard, userRunDownIn);
266         if (status != RPC_S_OK)
267             RpcRaiseException(status);
268         ndr->attributes = 0;
269         RpcContextHandle_GetUuid(SContext, &ndr->uuid);
270 
271         RPCRT4_RemoveThreadContextHandle(SContext);
272         RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE);
273     }
274     else
275     {
276         if (!RpcContextHandle_IsGuardCorrect(SContext, CtxGuard))
277             RpcRaiseException(ERROR_INVALID_HANDLE);
278         memset(ndr, 0, sizeof(*ndr));
279 
280         RPCRT4_RemoveThreadContextHandle(SContext);
281         /* Note: release the context handle twice in this case to release
282          * one ref being kept around for the data and one ref for the
283          * unmarshall/marshall sequence */
284         if (!RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE))
285             return; /* this is to cope with the case of the data not being valid
286                      * before and so not having a further reference */
287         RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, FALSE);
288     }
289 }
290 
291 /***********************************************************************
292  *           NDRSContextUnmarshall [RPCRT4.@]
293  */
294 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
295                                           ULONG DataRepresentation)
296 {
297     TRACE("(%p %08x)\n", pBuff, DataRepresentation);
298     return NDRSContextUnmarshall2(I_RpcGetCurrentCallHandle(), pBuff,
299                                   DataRepresentation, NULL,
300                                   RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
301 }
302 
303 /***********************************************************************
304  *           NDRSContextUnmarshallEx [RPCRT4.@]
305  */
306 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
307                                             void *pBuff,
308                                             ULONG DataRepresentation)
309 {
310     TRACE("(%p %p %08x)\n", hBinding, pBuff, DataRepresentation);
311     return NDRSContextUnmarshall2(hBinding, pBuff, DataRepresentation, NULL,
312                                   RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
313 }
314 
315 /***********************************************************************
316  *           NDRSContextUnmarshall2 [RPCRT4.@]
317  */
318 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
319                                            void *pBuff,
320                                            ULONG DataRepresentation,
321                                            void *CtxGuard, ULONG Flags)
322 {
323     RpcBinding *binding = hBinding;
324     NDR_SCONTEXT SContext;
325     RPC_STATUS status;
326     const ndr_context_handle *context_ndr = pBuff;
327 
328     TRACE("(%p %p %08x %p %u)\n",
329           hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
330 
331     if (!binding->server || !binding->Assoc)
332         RpcRaiseException(ERROR_INVALID_HANDLE);
333 
334     if (Flags & RPC_CONTEXT_HANDLE_FLAGS)
335         FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);
336 
337     if (!pBuff || (!context_ndr->attributes &&
338                    UuidIsNil((UUID *)&context_ndr->uuid, &status)))
339         status = RpcServerAssoc_AllocateContextHandle(binding->Assoc, CtxGuard,
340                                                       &SContext);
341     else
342     {
343         if (context_ndr->attributes)
344         {
345             ERR("non-null attributes 0x%x\n", context_ndr->attributes);
346             status = ERROR_INVALID_HANDLE;
347         }
348         else
349             status = RpcServerAssoc_FindContextHandle(binding->Assoc,
350                                                       &context_ndr->uuid,
351                                                       CtxGuard, Flags,
352                                                       &SContext);
353     }
354 
355     if (status != RPC_S_OK)
356         RpcRaiseException(status);
357 
358     RPCRT4_PushThreadContextHandle(SContext);
359     return SContext;
360 }
361 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.