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

📄 ndr_marshall.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    pointer_needs_marshaling = !NdrFullPointerQueryPointer(      pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);    TRACE("writing 0x%08x to buffer\n", pointer_id);    NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);    break;  default:    FIXME("unhandled ptr type=%02x\n", type);    RpcRaiseException(RPC_X_BAD_STUB_DATA);    return;  }  TRACE("calling marshaller for type 0x%x\n", (int)*desc);  if (pointer_needs_marshaling) {    if (attr & RPC_FC_P_DEREF) {      Pointer = *(unsigned char**)Pointer;      TRACE("deref => %p\n", Pointer);    }    m = NdrMarshaller[*desc & NDR_TABLE_MASK];    if (m) m(pStubMsg, Pointer, desc);    else FIXME("no marshaller for data type=%02x\n", *desc);  }  STD_OVERFLOW_CHECK(pStubMsg);}/*********************************************************************** *           PointerUnmarshall [internal] */static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,                              unsigned char *Buffer,                              unsigned char **pPointer,                              PFORMAT_STRING pFormat,                              unsigned char fMustAlloc){  unsigned type = pFormat[0], attr = pFormat[1];  PFORMAT_STRING desc;  NDR_UNMARSHALL m;  DWORD pointer_id = 0;  int pointer_needs_unmarshaling;  TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);  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) */    pointer_needs_unmarshaling = 1;    break;  case RPC_FC_UP: /* unique pointer */    pointer_id = NDR_LOCAL_UINT32_READ(Buffer);    TRACE("pointer_id is 0x%08x\n", pointer_id);    if (pointer_id)      pointer_needs_unmarshaling = 1;    else {      *pPointer = NULL;      pointer_needs_unmarshaling = 0;    }    break;  case RPC_FC_OP: /* object pointer - we must free data before overwriting it */    pointer_id = NDR_LOCAL_UINT32_READ(Buffer);    TRACE("pointer_id is 0x%08x\n", pointer_id);    if (!fMustAlloc && *pPointer)    {        FIXME("free object pointer %p\n", *pPointer);        *pPointer = NULL;    }    if (pointer_id)      pointer_needs_unmarshaling = 1;    else      pointer_needs_unmarshaling = 0;    break;  case RPC_FC_FP:    pointer_id = NDR_LOCAL_UINT32_READ(Buffer);    TRACE("pointer_id is 0x%08x\n", pointer_id);    pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(      pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);    break;  default:    FIXME("unhandled ptr type=%02x\n", type);    RpcRaiseException(RPC_X_BAD_STUB_DATA);    return;  }  if (pointer_needs_unmarshaling) {    if (attr & RPC_FC_P_DEREF) {      if (!*pPointer || fMustAlloc)        *pPointer = NdrAllocate(pStubMsg, sizeof(void *));      pPointer = *(unsigned char***)pPointer;      TRACE("deref => %p\n", pPointer);    }    m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];    if (m) m(pStubMsg, pPointer, desc, fMustAlloc);    else FIXME("no unmarshaller for data type=%02x\n", *desc);    if (type == RPC_FC_FP)      NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,                                *pPointer);  }  TRACE("pointer=%p\n", *pPointer);}/*********************************************************************** *           PointerBufferSize [internal] */static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,                              unsigned char *Pointer,                              PFORMAT_STRING pFormat){  unsigned type = pFormat[0], attr = pFormat[1];  PFORMAT_STRING desc;  NDR_BUFFERSIZE m;  int pointer_needs_sizing;  ULONG pointer_id;  TRACE("(%p,%p,%p)\n", pStubMsg, 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) */    break;  case RPC_FC_OP:  case RPC_FC_UP:    /* NULL pointer has no further representation */    if (!Pointer)        return;    break;  case RPC_FC_FP:    pointer_needs_sizing = !NdrFullPointerQueryPointer(      pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);    if (!pointer_needs_sizing)      return;    break;  default:    FIXME("unhandled ptr type=%02x\n", type);    RpcRaiseException(RPC_X_BAD_STUB_DATA);    return;  }  if (attr & RPC_FC_P_DEREF) {    Pointer = *(unsigned char**)Pointer;    TRACE("deref => %p\n", Pointer);  }  m = NdrBufferSizer[*desc & NDR_TABLE_MASK];  if (m) m(pStubMsg, Pointer, desc);  else FIXME("no buffersizer for data type=%02x\n", *desc);}/*********************************************************************** *           PointerMemorySize [internal] */static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,                                       unsigned char *Buffer,                                       PFORMAT_STRING pFormat){  unsigned type = pFormat[0], attr = pFormat[1];  PFORMAT_STRING desc;  NDR_MEMORYSIZE m;  FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, 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) */    break;  default:    FIXME("unhandled ptr type=%02x\n", type);    RpcRaiseException(RPC_X_BAD_STUB_DATA);  }  if (attr & RPC_FC_P_DEREF) {    TRACE("deref\n");  }  m = NdrMemorySizer[*desc & NDR_TABLE_MASK];  if (m) m(pStubMsg, desc);  else FIXME("no memorysizer for data type=%02x\n", *desc);  return 0;}/*********************************************************************** *           PointerFree [internal] */static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,                        unsigned char *Pointer,                        PFORMAT_STRING pFormat){  unsigned type = pFormat[0], attr = pFormat[1];  PFORMAT_STRING desc;  NDR_FREE m;  TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);  TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);  if (attr & RPC_FC_P_DONTFREE) return;  pFormat += 2;  if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;  else desc = pFormat + *(const SHORT*)pFormat;  if (!Pointer) return;  if (type == RPC_FC_FP) {    int pointer_needs_freeing = NdrFullPointerFree(      pStubMsg->FullPtrXlatTables, Pointer);    if (!pointer_needs_freeing)      return;  }  if (attr & RPC_FC_P_DEREF) {    Pointer = *(unsigned char**)Pointer;    TRACE("deref => %p\n", Pointer);  }  m = NdrFreer[*desc & NDR_TABLE_MASK];  if (m) m(pStubMsg, Pointer, desc);  /* hmm... is this sensible?   * perhaps we should check if the memory comes from NdrAllocate,   * and deallocate only if so - checking if the pointer is between   * BufferStart and BufferEnd is probably no good since the buffer   * may be reallocated when the server wants to marshal the reply */  switch (*desc) {  case RPC_FC_BOGUS_STRUCT:  case RPC_FC_BOGUS_ARRAY:  case RPC_FC_USER_MARSHAL:  case RPC_FC_CARRAY:  case RPC_FC_CVARRAY:    break;  default:    FIXME("unhandled data type=%02x\n", *desc);    break;  case RPC_FC_C_CSTRING:  case RPC_FC_C_WSTRING:    if (pStubMsg->ReuseBuffer) goto notfree;    break;  case RPC_FC_IP:    goto notfree;  }  if (attr & RPC_FC_P_ONSTACK) {    TRACE("not freeing stack ptr %p\n", Pointer);    return;  }  TRACE("freeing %p\n", Pointer);  NdrFree(pStubMsg, Pointer);  return;notfree:  TRACE("not freeing %p\n", Pointer);}/*********************************************************************** *           EmbeddedPointerMarshall */static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,                                               unsigned char *pMemory,                                               PFORMAT_STRING pFormat){  unsigned char *Mark = pStubMsg->BufferMark;  unsigned long Offset = pStubMsg->Offset;  unsigned ofs, rep, count, stride, xofs;  unsigned i;  unsigned char *saved_buffer = NULL;  TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);  if (*pFormat != RPC_FC_PP) return NULL;  pFormat += 2;  if (pStubMsg->PointerBufferMark)  {    saved_buffer = pStubMsg->Buffer;    pStubMsg->Buffer = pStubMsg->PointerBufferMark;    pStubMsg->PointerBufferMark = NULL;  }  while (pFormat[0] != RPC_FC_END) {    switch (pFormat[0]) {    default:      FIXME("unknown repeat type %d\n", pFormat[0]);    case RPC_FC_NO_REPEAT:      rep = 1;      stride = 0;      ofs = 0;      count = 1;      xofs = 0;      pFormat += 2;      break;    case RPC_FC_FIXED_REPEAT:      rep = *(const WORD*)&pFormat[2];      stride = *(const WORD*)&pFormat[4];      ofs = *(const WORD*)&pFormat[6];      count = *(const WORD*)&pFormat[8];      xofs = 0;      pFormat += 10;      break;    case RPC_FC_VARIABLE_REPEAT:      rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;      stride = *(const WORD*)&pFormat[2];      ofs = *(const WORD*)&pFormat[4];      count = *(const WORD*)&pFormat[6];      xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;      pFormat += 8;      break;    }    for (i = 0; i < rep; i++) {      PFORMAT_STRING info = pFormat;      unsigned char *membase = pMemory + ofs + (i * stride);      unsigned char *bufbase = Mark + ofs + (i * stride);      unsigned u;      for (u=0; u<count; u++,info+=8) {        unsigned char *memptr = membase + *(const SHORT*)&info[0];        unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];        unsigned char *saved_memory = pStubMsg->Memory;        pStubMsg->Memory = pMemory;        PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);        pStubMsg->Memory = saved_memory;      }    }    pFormat += 8 * count;  }  if (saved_buffer)  {    pStubMsg->PointerBufferMark = pStubMsg->Buffer;    pStubMsg->Buffer = saved_buffer;  }  STD_OVERFLOW_CHECK(pStubMsg);  return NULL;}/*********************************************************************** *           EmbeddedPointerUnmarshall */static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,                                                 unsigned char **ppMemory,                                                 PFORMAT_STRING pFormat,                                                 unsigned char fMustAlloc){  unsigned char *Mark = pStubMsg->BufferMark;  unsigned long Offset = pStubMsg->Offset;  unsigned ofs, rep, count, stride, xofs;  unsigned i;  unsigned char *saved_buffer = NULL;  TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);  if (*pFormat != RPC_FC_PP) return NULL;  pFormat += 2;  if (pStubMsg->PointerBufferMark)  {    saved_buffer = pStubMsg->Buffer;    pStubMsg->Buffer = pStubMsg->PointerBufferMark;    pStubMsg->PointerBufferMark = NULL;  }  while (pFormat[0] != RPC_FC_END) {    TRACE("pFormat[0] = 0x%x\n", pFormat[0]);    switch (pFormat[0]) {    default:      FIXME("unknown repeat type %d\n", pFormat[0]);    case RPC_FC_NO_REPEAT:      rep = 1;      stride = 0;      ofs = 0;      count = 1;      xofs = 0;      pFormat += 2;      break;    case RPC_FC_FIXED_REPEAT:      rep = *(const WORD*)&pFormat[2];      stride = *(const WORD*)&pFormat[4];      ofs = *(const WORD*)&pFormat[6];      count = *(const WORD*)&pFormat[8];      xofs = 0;      pFormat += 10;      break;    case RPC_FC_VARIABLE_REPEAT:      rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;      stride = *(const WORD*)&pFormat[2];      ofs = *(const WORD*)&pFormat[4];      count = *(const WORD*)&pFormat[6];      xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;      pFormat += 8;      break;    }    /* ofs doesn't seem to matter in this context */    for (i = 0; i < rep; i++) {      PFORMAT_STRING info = pFormat;      unsigned char *membase = *ppMemory + ofs + (i * stride);      unsigned char *bufbase = Mark + ofs + (i * stride);      unsigned u;      for (u=0; u<count; u++,info+=8) {        unsigned char *memptr = membase + *(const SHORT*)&info[0];        unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];        PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, TRUE);      }    }    pFormat += 8 * count;  }  if (saved_buffer)  {    pStubMsg->PointerBufferMark = pStubMsg->Buffer;    pStubMsg->Buffer = saved_buffer;  }  return NULL;}/*********************************************************************** *           EmbeddedPointerBufferSize */static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,                                      unsigned char *pMemory,

⌨️ 快捷键说明

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