/* * check RPC request for (somewhat) correct size * allow any size that does not cause CreateResponse to fail badly */ static unsigned int checkRpcRequestSize(const RPC_REQUEST64 *const Request, const unsigned int requestSize, WORD* NdrCtx, WORD* Ndr64Ctx) { WORD Ctx = LE16(Request->ContextId); # if defined(_PEDANTIC) && !defined(NO_LOG) CheckRpcRequest(Request, requestSize, NdrCtx, Ndr64Ctx, Ctx); # endif // defined(_PEDANTIC) && !defined(NO_LOG) // Anything that is smaller than a v4 request is illegal if (requestSize < sizeof(REQUEST_V4) + (Ctx != *Ndr64Ctx ? sizeof(RPC_REQUEST) : sizeof(RPC_REQUEST64))) return 0; // Get KMS major version uint16_t majorIndex, minor; DWORD version; # ifndef SIMPLE_RPC if (Ctx != *Ndr64Ctx) { version = LE32(*(DWORD*)Request->Ndr.Data); } else { version = LE32(*(DWORD*)Request->Ndr64.Data); } # else // SIMPLE_RPC version = LE32(*(DWORD*)Request->Ndr.Data); # endif // SIMPLE_RPC majorIndex = (uint16_t)(version >> 16) - 4; minor = (uint16_t)(version & 0xffff); // Only KMS v4, v5 and v6 are supported if (majorIndex >= vlmcsd_countof(_Versions) || minor) { # ifndef NO_LOG logger("Fatal: KMSv%hu.%hu unsupported\n", (unsigned short)majorIndex + 4, (unsigned short)minor); # endif // NO_LOG return 0; } // Could check for equality but allow bigger requests to support buggy RPC clients (e.g. wine) // Buffer overrun is check by caller. return (requestSize >= _Versions[majorIndex].RequestSize); }
static unsigned int RpcRequestSize(const RPC_REQUEST *const Request, const unsigned int RequestSize) { uint_fast8_t _v; _v = (uint_fast8_t)LE16(((WORD*)Request->Data)[1]) - 4; if ( _v < vlmcsd_countof(_Versions) && RequestSize >= _Versions[_v].RequestSize + sizeof(RPC_REQUEST) ) { #if defined(_PEDANTIC) && !defined(NO_LOG) CheckRpcRequest(Request, RequestSize, _v); #endif // defined(_PEDANTIC) && !defined(NO_LOG) return MAX_RESPONSE_SIZE + sizeof(RPC_RESPONSE); } return 0; }