ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ndr_contexthandle.c
Go to the documentation of this file.
00001 /*
00002  * NDR data marshalling
00003  *
00004  * Copyright 2006 Mike McCormack (for CodeWeavers)
00005  * Copyright 2006-2007 Robert Shearman (for CodeWeavers)
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "ndr_misc.h"
00023 #include "rpc_assoc.h"
00024 #include "rpcndr.h"
00025 
00026 #include "wine/rpcfc.h"
00027 
00028 #include "wine/debug.h"
00029 #include "wine/list.h"
00030 
00031 WINE_DEFAULT_DEBUG_CHANNEL(ole);
00032 
00033 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
00034 
00035 typedef struct ndr_context_handle
00036 {
00037     ULONG      attributes;
00038     GUID       uuid;
00039 } ndr_context_handle;
00040 
00041 struct context_handle_entry
00042 {
00043     struct list entry;
00044     DWORD magic;
00045     RPC_BINDING_HANDLE handle;
00046     ndr_context_handle wire_data;
00047 };
00048 
00049 static struct list context_handle_list = LIST_INIT(context_handle_list);
00050 
00051 static CRITICAL_SECTION ndr_context_cs;
00052 static CRITICAL_SECTION_DEBUG ndr_context_debug =
00053 {
00054     0, 0, &ndr_context_cs,
00055     { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList },
00056       0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") }
00057 };
00058 static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 };
00059 
00060 static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
00061 {
00062     struct context_handle_entry *che = CContext;
00063 
00064     if (che->magic != NDR_CONTEXT_HANDLE_MAGIC)
00065         return NULL;
00066     return che;
00067 }
00068 
00069 static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
00070 {
00071     struct context_handle_entry *che;
00072     LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
00073         if (IsEqualGUID(&che->wire_data.uuid, uuid))
00074             return che;
00075     return NULL;
00076 }
00077 
00078 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
00079 {
00080     struct context_handle_entry *che;
00081     RPC_BINDING_HANDLE handle = NULL;
00082 
00083     TRACE("%p\n", CContext);
00084 
00085     EnterCriticalSection(&ndr_context_cs);
00086     che = get_context_entry(CContext);
00087     if (che)
00088         handle = che->handle;
00089     LeaveCriticalSection(&ndr_context_cs);
00090 
00091     if (!handle)
00092     {
00093         ERR("invalid handle %p\n", CContext);
00094         RpcRaiseException(ERROR_INVALID_HANDLE);
00095     }
00096     return handle;
00097 }
00098 
00099 void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
00100 {
00101     struct context_handle_entry *che;
00102 
00103     TRACE("%p %p\n", CContext, pBuff);
00104 
00105     if (CContext)
00106     {
00107         EnterCriticalSection(&ndr_context_cs);
00108         che = get_context_entry(CContext);
00109         memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle));
00110         LeaveCriticalSection(&ndr_context_cs);
00111     }
00112     else
00113     {
00114         ndr_context_handle *wire_data = pBuff;
00115         wire_data->attributes = 0;
00116         wire_data->uuid = GUID_NULL;
00117     }
00118 }
00119 
00120 /***********************************************************************
00121  *           RpcSmDestroyClientContext [RPCRT4.@]
00122  */
00123 RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle)
00124 {
00125     RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH;
00126     struct context_handle_entry *che = NULL;
00127 
00128     TRACE("(%p)\n", ContextHandle);
00129 
00130     EnterCriticalSection(&ndr_context_cs);
00131     che = get_context_entry(*ContextHandle);
00132     *ContextHandle = NULL;
00133     if (che)
00134     {
00135         status = RPC_S_OK;
00136         list_remove(&che->entry);
00137     }
00138 
00139     LeaveCriticalSection(&ndr_context_cs);
00140 
00141     if (che)
00142     {
00143         RpcBindingFree(&che->handle);
00144         HeapFree(GetProcessHeap(), 0, che);
00145     }
00146 
00147     return status;
00148 }
00149 
00150 /***********************************************************************
00151  *           RpcSsDestroyClientContext [RPCRT4.@]
00152  */
00153 void WINAPI RpcSsDestroyClientContext(void **ContextHandle)
00154 {
00155     RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle);
00156     if (status != RPC_S_OK)
00157         RpcRaiseException(status);
00158 }
00159 
00160 static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
00161                                       RPC_BINDING_HANDLE hBinding,
00162                                       const ndr_context_handle *chi)
00163 {
00164     struct context_handle_entry *che = NULL;
00165 
00166     /* a null UUID means we should free the context handle */
00167     if (IsEqualGUID(&chi->uuid, &GUID_NULL))
00168     {
00169         if (*CContext)
00170         {
00171             che = get_context_entry(*CContext);
00172             if (!che)
00173                 return ERROR_INVALID_HANDLE;
00174             list_remove(&che->entry);
00175             RpcBindingFree(&che->handle);
00176             HeapFree(GetProcessHeap(), 0, che);
00177             che = NULL;
00178         }
00179     }
00180     /* if there's no existing entry matching the GUID, allocate one */
00181     else if (!(che = context_entry_from_guid(&chi->uuid)))
00182     {
00183         che = HeapAlloc(GetProcessHeap(), 0, sizeof *che);
00184         if (!che)
00185             return ERROR_NOT_ENOUGH_MEMORY;
00186         che->magic = NDR_CONTEXT_HANDLE_MAGIC;
00187         RpcBindingCopy(hBinding, &che->handle);
00188         list_add_tail(&context_handle_list, &che->entry);
00189         che->wire_data = *chi;
00190     }
00191 
00192     *CContext = che;
00193 
00194     return ERROR_SUCCESS;
00195 }
00196 
00197 /***********************************************************************
00198  *           NDRCContextUnmarshall [RPCRT4.@]
00199  */
00200 void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext,
00201                                   RPC_BINDING_HANDLE hBinding,
00202                                   void *pBuff, ULONG DataRepresentation)
00203 {
00204     UINT r;
00205 
00206     TRACE("*%p=(%p) %p %p %08x\n",
00207           CContext, *CContext, hBinding, pBuff, DataRepresentation);
00208 
00209     EnterCriticalSection(&ndr_context_cs);
00210     r = ndr_update_context_handle(CContext, hBinding, pBuff);
00211     LeaveCriticalSection(&ndr_context_cs);
00212     if (r)
00213         RpcRaiseException(r);
00214 }
00215 
00216 /***********************************************************************
00217  *           NDRSContextMarshall [RPCRT4.@]
00218  */
00219 void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext,
00220                                void *pBuff,
00221                                NDR_RUNDOWN userRunDownIn)
00222 {
00223     TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn);
00224     NDRSContextMarshall2(I_RpcGetCurrentCallHandle(), SContext, pBuff,
00225                          userRunDownIn, NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
00226 }
00227 
00228 /***********************************************************************
00229  *           NDRSContextMarshallEx [RPCRT4.@]
00230  */
00231 void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding,
00232                                   NDR_SCONTEXT SContext,
00233                                   void *pBuff,
00234                                   NDR_RUNDOWN userRunDownIn)
00235 {
00236     TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn);
00237     NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL,
00238                          RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
00239 }
00240 
00241 /***********************************************************************
00242  *           NDRSContextMarshall2 [RPCRT4.@]
00243  */
00244 void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding,
00245                                  NDR_SCONTEXT SContext,
00246                                  void *pBuff,
00247                                  NDR_RUNDOWN userRunDownIn,
00248                                  void *CtxGuard, ULONG Flags)
00249 {
00250     RpcBinding *binding = hBinding;
00251     RPC_STATUS status;
00252     ndr_context_handle *ndr = pBuff;
00253 
00254     TRACE("(%p %p %p %p %p %u)\n",
00255           hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags);
00256 
00257     if (!binding->server || !binding->Assoc)
00258         RpcRaiseException(ERROR_INVALID_HANDLE);
00259 
00260     if (Flags & RPC_CONTEXT_HANDLE_FLAGS)
00261         FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);
00262 
00263     if (SContext->userContext)
00264     {
00265         status = RpcServerAssoc_UpdateContextHandle(binding->Assoc, SContext, CtxGuard, userRunDownIn);
00266         if (status != RPC_S_OK)
00267             RpcRaiseException(status);
00268         ndr->attributes = 0;
00269         RpcContextHandle_GetUuid(SContext, &ndr->uuid);
00270 
00271         RPCRT4_RemoveThreadContextHandle(SContext);
00272         RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE);
00273     }
00274     else
00275     {
00276         if (!RpcContextHandle_IsGuardCorrect(SContext, CtxGuard))
00277             RpcRaiseException(ERROR_INVALID_HANDLE);
00278         memset(ndr, 0, sizeof(*ndr));
00279 
00280         RPCRT4_RemoveThreadContextHandle(SContext);
00281         /* Note: release the context handle twice in this case to release
00282          * one ref being kept around for the data and one ref for the
00283          * unmarshall/marshall sequence */
00284         if (!RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE))
00285             return; /* this is to cope with the case of the data not being valid
00286                      * before and so not having a further reference */
00287         RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, FALSE);
00288     }
00289 }
00290 
00291 /***********************************************************************
00292  *           NDRSContextUnmarshall [RPCRT4.@]
00293  */
00294 NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff,
00295                                           ULONG DataRepresentation)
00296 {
00297     TRACE("(%p %08x)\n", pBuff, DataRepresentation);
00298     return NDRSContextUnmarshall2(I_RpcGetCurrentCallHandle(), pBuff,
00299                                   DataRepresentation, NULL,
00300                                   RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
00301 }
00302 
00303 /***********************************************************************
00304  *           NDRSContextUnmarshallEx [RPCRT4.@]
00305  */
00306 NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding,
00307                                             void *pBuff,
00308                                             ULONG DataRepresentation)
00309 {
00310     TRACE("(%p %p %08x)\n", hBinding, pBuff, DataRepresentation);
00311     return NDRSContextUnmarshall2(hBinding, pBuff, DataRepresentation, NULL,
00312                                   RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
00313 }
00314 
00315 /***********************************************************************
00316  *           NDRSContextUnmarshall2 [RPCRT4.@]
00317  */
00318 NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding,
00319                                            void *pBuff,
00320                                            ULONG DataRepresentation,
00321                                            void *CtxGuard, ULONG Flags)
00322 {
00323     RpcBinding *binding = hBinding;
00324     NDR_SCONTEXT SContext;
00325     RPC_STATUS status;
00326     const ndr_context_handle *context_ndr = pBuff;
00327 
00328     TRACE("(%p %p %08x %p %u)\n",
00329           hBinding, pBuff, DataRepresentation, CtxGuard, Flags);
00330 
00331     if (!binding->server || !binding->Assoc)
00332         RpcRaiseException(ERROR_INVALID_HANDLE);
00333 
00334     if (Flags & RPC_CONTEXT_HANDLE_FLAGS)
00335         FIXME("unimplemented flags: 0x%x\n", Flags & RPC_CONTEXT_HANDLE_FLAGS);
00336 
00337     if (!pBuff || (!context_ndr->attributes &&
00338                    UuidIsNil((UUID *)&context_ndr->uuid, &status)))
00339         status = RpcServerAssoc_AllocateContextHandle(binding->Assoc, CtxGuard,
00340                                                       &SContext);
00341     else
00342     {
00343         if (context_ndr->attributes)
00344         {
00345             ERR("non-null attributes 0x%x\n", context_ndr->attributes);
00346             status = ERROR_INVALID_HANDLE;
00347         }
00348         else
00349             status = RpcServerAssoc_FindContextHandle(binding->Assoc,
00350                                                       &context_ndr->uuid,
00351                                                       CtxGuard, Flags,
00352                                                       &SContext);
00353     }
00354 
00355     if (status != RPC_S_OK)
00356         RpcRaiseException(status);
00357 
00358     RPCRT4_PushThreadContextHandle(SContext);
00359     return SContext;
00360 }

Generated on Sun May 27 2012 04:26:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.