⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndr_marshall.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
{  BYTE dtype = pFormat[0] & 0xf;  short ofs = *(const short *)&pFormat[2];  LPVOID ptr = NULL;  DWORD data = 0;  if (!IsConformanceOrVariancePresent(pFormat)) {    /* null descriptor */    *pCount = def;    goto finish_conf;  }  switch (pFormat[0] & 0xf0) {  case RPC_FC_NORMAL_CONFORMANCE:    TRACE("normal conformance, ofs=%d\n", ofs);    ptr = pMemory;    break;  case RPC_FC_POINTER_CONFORMANCE:    TRACE("pointer conformance, ofs=%d\n", ofs);    ptr = pStubMsg->Memory;    break;  case RPC_FC_TOP_LEVEL_CONFORMANCE:    TRACE("toplevel conformance, ofs=%d\n", ofs);    if (pStubMsg->StackTop) {      ptr = pStubMsg->StackTop;    }    else {      /* -Os mode, *pCount is already set */      goto finish_conf;    }    break;  case RPC_FC_CONSTANT_CONFORMANCE:    data = ofs | ((DWORD)pFormat[1] << 16);    TRACE("constant conformance, val=%d\n", data);    *pCount = data;    goto finish_conf;  case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:    FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);    if (pStubMsg->StackTop) {      ptr = pStubMsg->StackTop;    }    else {      /* ? */      goto done_conf_grab;    }    break;  default:    FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);  }  switch (pFormat[1]) {  case RPC_FC_DEREFERENCE:    ptr = *(LPVOID*)((char *)ptr + ofs);    break;  case RPC_FC_CALLBACK:  {    unsigned char *old_stack_top = pStubMsg->StackTop;    pStubMsg->StackTop = ptr;    /* ofs is index into StubDesc->apfnExprEval */    TRACE("callback conformance into apfnExprEval[%d]\n", ofs);    pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);    pStubMsg->StackTop = old_stack_top;    /* the callback function always stores the computed value in MaxCount */    *pCount = pStubMsg->MaxCount;    goto finish_conf;  }  default:    ptr = (char *)ptr + ofs;    break;  }  switch (dtype) {  case RPC_FC_LONG:  case RPC_FC_ULONG:    data = *(DWORD*)ptr;    break;  case RPC_FC_SHORT:    data = *(SHORT*)ptr;    break;  case RPC_FC_USHORT:    data = *(USHORT*)ptr;    break;  case RPC_FC_CHAR:  case RPC_FC_SMALL:    data = *(CHAR*)ptr;    break;  case RPC_FC_BYTE:  case RPC_FC_USMALL:    data = *(UCHAR*)ptr;    break;  default:    FIXME("unknown conformance data type %x\n", dtype);    goto done_conf_grab;  }  TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);done_conf_grab:  switch (pFormat[1]) {  case RPC_FC_DEREFERENCE: /* already handled */  case 0: /* no op */    *pCount = data;    break;  case RPC_FC_ADD_1:    *pCount = data + 1;    break;  case RPC_FC_SUB_1:    *pCount = data - 1;    break;  case RPC_FC_MULT_2:    *pCount = data * 2;    break;  case RPC_FC_DIV_2:    *pCount = data / 2;    break;  default:    FIXME("unknown conformance op %d\n", pFormat[1]);    goto finish_conf;  }finish_conf:  TRACE("resulting conformance is %ld\n", *pCount);  if (pStubMsg->fHasNewCorrDesc)    return pFormat+6;  else    return pFormat+4;}/* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if * the result overflows 32-bits */static inline ULONG safe_multiply(ULONG a, ULONG b){    ULONGLONG ret = (ULONGLONG)a * b;    if (ret > 0xffffffff)    {        RpcRaiseException(RPC_S_INVALID_BOUND);        return 0;    }    return ret;}/* * NdrConformantString: *  * What MS calls a ConformantString is, in DCE terminology, * a Varying-Conformant String. * [ *   maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') *   offset: DWORD (actual string data begins at (offset) CHARTYPE's *           into unmarshalled string)  *   length: DWORD (# of CHARTYPE characters, inclusive of '\0') *   [  *     data: CHARTYPE[maxlen] *   ]  * ], where CHARTYPE is the appropriate character type (specified externally) * *//*********************************************************************** *            NdrConformantStringMarshall [RPCRT4.@] */unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,  unsigned char *pszMessage, PFORMAT_STRING pFormat){   ULONG esize, size;  TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);    if (*pFormat == RPC_FC_C_CSTRING) {    TRACE("string=%s\n", debugstr_a((char*)pszMessage));    pStubMsg->ActualCount = strlen((char*)pszMessage)+1;    esize = 1;  }  else if (*pFormat == RPC_FC_C_WSTRING) {    TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));    pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;    esize = 2;  }  else {    ERR("Unhandled string type: %#x\n", *pFormat);     /* FIXME: raise an exception. */    return NULL;  }  if (pFormat[1] == RPC_FC_STRING_SIZED)    pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);  else    pStubMsg->MaxCount = pStubMsg->ActualCount;  pStubMsg->Offset = 0;  WriteConformance(pStubMsg);  WriteVariance(pStubMsg);  size = safe_multiply(esize, pStubMsg->ActualCount);  memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */  pStubMsg->Buffer += size;  STD_OVERFLOW_CHECK(pStubMsg);  /* success */  return NULL; /* is this always right? */}/*********************************************************************** *           NdrConformantStringBufferSize [RPCRT4.@] */void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,  unsigned char* pMemory, PFORMAT_STRING pFormat){  ULONG esize;  TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);  SizeConformance(pStubMsg);  SizeVariance(pStubMsg);  if (*pFormat == RPC_FC_C_CSTRING) {    TRACE("string=%s\n", debugstr_a((char*)pMemory));    pStubMsg->ActualCount = strlen((char*)pMemory)+1;    esize = 1;  }  else if (*pFormat == RPC_FC_C_WSTRING) {    TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));    pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;    esize = 2;  }  else {    ERR("Unhandled string type: %#x\n", *pFormat);     /* FIXME: raise an exception */    return;  }  if (pFormat[1] == RPC_FC_STRING_SIZED)    pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);  else    pStubMsg->MaxCount = pStubMsg->ActualCount;  pStubMsg->BufferLength += safe_multiply(esize, pStubMsg->ActualCount);}/************************************************************************ *            NdrConformantStringMemorySize [RPCRT4.@] */ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,  PFORMAT_STRING pFormat ){  ULONG rslt = 0;  FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);  assert(pStubMsg && pFormat);  if (*pFormat == RPC_FC_C_CSTRING) {    rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */  }  else if (*pFormat == RPC_FC_C_WSTRING) {    rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */  }  else {    ERR("Unhandled string type: %#x\n", *pFormat);    /* FIXME: raise an exception */  }  if (pFormat[1] != RPC_FC_PAD) {    FIXME("sized string format=%d\n", pFormat[1]);  }  TRACE("  --> %u\n", rslt);  return rslt;}/************************************************************************ *           NdrConformantStringUnmarshall [RPCRT4.@] */unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,  unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ){  ULONG bufsize, memsize, esize, i;  TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",    pStubMsg, *ppMemory, pFormat, fMustAlloc);  assert(pFormat && ppMemory && pStubMsg);  ReadConformance(pStubMsg, NULL);  ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);  if (*pFormat == RPC_FC_C_CSTRING) esize = 1;  else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;  else {    ERR("Unhandled string type: %#x\n", *pFormat);    /* FIXME: raise an exception */    esize = 0;  }  memsize = safe_multiply(esize, pStubMsg->MaxCount);  bufsize = safe_multiply(esize, pStubMsg->ActualCount);  /* strings must always have null terminating bytes */  if (bufsize < esize)  {    ERR("invalid string length of %d\n", pStubMsg->ActualCount);    RpcRaiseException(RPC_S_INVALID_BOUND);    return NULL;  }  for (i = bufsize - esize; i < bufsize; i++)    if (pStubMsg->Buffer[i] != 0)    {      ERR("string not null-terminated at byte position %d, data is 0x%x\n",        i, pStubMsg->Buffer[i]);      RpcRaiseException(RPC_S_INVALID_BOUND);      return NULL;    }  if (fMustAlloc || !*ppMemory)    *ppMemory = NdrAllocate(pStubMsg, memsize);  memcpy(*ppMemory, pStubMsg->Buffer, bufsize);  pStubMsg->Buffer += bufsize;  if (*pFormat == RPC_FC_C_CSTRING) {    TRACE("string=%s\n", debugstr_a((char*)*ppMemory));  }  else if (*pFormat == RPC_FC_C_WSTRING) {    TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));  }  return NULL; /* FIXME: is this always right? */}/*********************************************************************** *           NdrNonConformantStringMarshall [RPCRT4.@] */unsigned char *  WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,                                unsigned char *pMemory,                                PFORMAT_STRING pFormat){    FIXME("stub\n");    return NULL;}/*********************************************************************** *           NdrNonConformantStringUnmarshall [RPCRT4.@] */unsigned char *  WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,                                unsigned char **ppMemory,                                PFORMAT_STRING pFormat,                                unsigned char fMustAlloc){    FIXME("stub\n");    return NULL;}/*********************************************************************** *           NdrNonConformantStringBufferSize [RPCRT4.@] */void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,                                unsigned char *pMemory,                                PFORMAT_STRING pFormat){    FIXME("stub\n");}/*********************************************************************** *           NdrNonConformantStringMemorySize [RPCRT4.@] */ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,                                PFORMAT_STRING pFormat){    FIXME("stub\n");    return 0;}static inline void dump_pointer_attr(unsigned char attr){    if (attr & RPC_FC_P_ALLOCALLNODES)        TRACE(" RPC_FC_P_ALLOCALLNODES");    if (attr & RPC_FC_P_DONTFREE)        TRACE(" RPC_FC_P_DONTFREE");    if (attr & RPC_FC_P_ONSTACK)        TRACE(" RPC_FC_P_ONSTACK");    if (attr & RPC_FC_P_SIMPLEPOINTER)        TRACE(" RPC_FC_P_SIMPLEPOINTER");    if (attr & RPC_FC_P_DEREF)        TRACE(" RPC_FC_P_DEREF");    TRACE("\n");}/*********************************************************************** *           PointerMarshall [internal] */static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,                            unsigned char *Buffer,                            unsigned char *Pointer,                            PFORMAT_STRING pFormat){  unsigned type = pFormat[0], attr = pFormat[1];  PFORMAT_STRING desc;  NDR_MARSHALL m;  ULONG pointer_id;  int pointer_needs_marshaling;  TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);  TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);  pFormat += 2;  if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;  else desc = pFormat + *(const SHORT*)pFormat;  switch (type) {  case RPC_FC_RP: /* ref pointer (always non-null) */#if 0 /* this causes problems for InstallShield so is disabled - we need more tests */    if (!Pointer)      RpcRaiseException(RPC_X_NULL_REF_POINTER);#endif    pointer_needs_marshaling = 1;    break;  case RPC_FC_UP: /* unique pointer */  case RPC_FC_OP: /* object pointer - same as unique here */    if (Pointer)      pointer_needs_marshaling = 1;    else      pointer_needs_marshaling = 0;    pointer_id = (ULONG)Pointer;    TRACE("writing 0x%08x to buffer\n", pointer_id);    NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);    break;  case RPC_FC_FP:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -