15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_opcodes.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_types.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned short kMaxUniStrSize = 0xfffc; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InitStringUnicode(const wchar_t* source, size_t length, 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNICODE_STRING* ustring) { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustring->Buffer = const_cast<wchar_t*>(source); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustring->Length = static_cast<USHORT>(length) * sizeof(wchar_t); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (length > kMaxUniStrSize) { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustring->MaximumLength = (NULL != source) ? 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ustring->Length + sizeof(wchar_t) : 0; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_INTERCEPT NtExports g_nt; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: The opcodes are implemented as functions (as opposed to classes derived 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from PolicyOpcode) because you should not add more member variables to the 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PolicyOpcode class since it would cause object slicing on the target. So to 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enforce that (instead of just trusting the developer) the opcodes became 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just functions. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In the code that follows I have keep the evaluation function and the factory 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function together to stress the close relationship between both. For example, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// only the factory method and the evaluation function know the stored argument 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// order and meaning. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval(PolicyOpcode* opcode, const ParameterSet* pp, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* match); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpAlwaysFalse: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Does not require input parameter. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpAlwaysFalse(uint32 options) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MakeBase(OP_ALWAYS_FALSE, options, -1); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_ALWAYS_FALSE>(PolicyOpcode* opcode, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(opcode); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(param); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(context); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpAlwaysTrue: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Does not require input parameter. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpAlwaysTrue(uint32 options) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MakeBase(OP_ALWAYS_TRUE, options, -1); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_ALWAYS_TRUE>(PolicyOpcode* opcode, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(opcode); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(param); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(context); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_TRUE; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpAction: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Does not require input parameter. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 0 contains the actual action to return. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpAction(EvalResult action, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = MakeBase(OP_ACTION, options, 0); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == opcode) return NULL; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(0, action); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_ACTION>(PolicyOpcode* opcode, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(param); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(context); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int action = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(0, &action); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<EvalResult>(action); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpNumberMatch: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Requires a unsigned long or void* in selected_param 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 0 is the stored number to match. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 1 is the C++ type of the 0th argument. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpNumberMatch(int16 selected_param, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long match, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = MakeBase(OP_NUMBER_MATCH, options, selected_param); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == opcode) return NULL; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(0, match); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(1, ULONG_TYPE); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpVoidPtrMatch(int16 selected_param, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* match, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = MakeBase(OP_NUMBER_MATCH, options, selected_param); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == opcode) return NULL; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(0, match); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(1, VOIDPTR_TYPE); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_NUMBER_MATCH>(PolicyOpcode* opcode, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(context); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long value_ulong = 0; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (param->Get(&value_ulong)) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long match_ulong = 0; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(0, &match_ulong); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (match_ulong != value_ulong)? EVAL_FALSE : EVAL_TRUE; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* value_ptr = NULL; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (param->Get(&value_ptr)) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* match_ptr = NULL; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(0, &match_ptr); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (match_ptr != value_ptr)? EVAL_FALSE : EVAL_TRUE; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_ERROR; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpUlongMatchRange 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Requires a unsigned long in selected_param. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 0 is the stored lower bound to match. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 1 is the stored upper bound to match. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpUlongMatchRange(int16 selected_param, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long lower_bound, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long upper_bound, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lower_bound > upper_bound) { 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return NULL; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = MakeBase(OP_ULONG_MATCH_RANGE, options, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_param); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == opcode) return NULL; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(0, lower_bound); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(1, upper_bound); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_ULONG_MATCH_RANGE>(PolicyOpcode* opcode, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(context); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long value = 0; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!param->Get(&value)) return EVAL_ERROR; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long lower_bound = 0; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long upper_bound = 0; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(0, &lower_bound); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(1, &upper_bound); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return((lower_bound <= value) && (upper_bound >= value))? 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVAL_TRUE : EVAL_FALSE; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpUlongAndMatch: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Requires a unsigned long in selected_param. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 0 is the stored number to match. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpUlongAndMatch(int16 selected_param, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long match, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = MakeBase(OP_ULONG_AND_MATCH, options, selected_param); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == opcode) return NULL; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(0, match); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_ULONG_AND_MATCH>(PolicyOpcode* opcode, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNREFERENCED_PARAMETER(context); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long value = 0; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!param->Get(&value)) return EVAL_ERROR; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long number = 0; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(0, &number); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (number & value)? EVAL_TRUE : EVAL_FALSE; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode OpWStringMatch: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Requires a wchar_t* in selected_param. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 0 is the byte displacement of the stored string. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 1 is the lenght in chars of the stored string. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 2 is the offset to apply on the input string. It has special values. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as noted in the header file. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Argument 3 is the string matching options. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeOpWStringMatch(int16 selected_param, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* match_str, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_position, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringMatchOptions match_opts, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == match_str) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ('\0' == match_str[0]) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenght = lstrlenW(match_str); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = MakeBase(OP_WSTRING_MATCH, options, selected_param); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == opcode) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptrdiff_t delta_str = AllocRelative(opcode, match_str, wcslen(match_str)+1); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == delta_str) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(0, delta_str); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(1, lenght); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(2, start_position); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->SetArgument(3, match_opts); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult OpcodeEval<OP_WSTRING_MATCH>(PolicyOpcode* opcode, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* param, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* context) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == context) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_ERROR; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* source_str = NULL; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!param->Get(&source_str)) return EVAL_ERROR; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_position = 0; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int match_len = 0; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int match_opts = 0; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(1, &match_len); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(2, &start_position); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->GetArgument(3, &match_opts); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* match_str = opcode->GetRelativeString(0); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance the source string to the last successfully evaluated position 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // according to the match context. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_str = &source_str[context->position]; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int source_len = static_cast<int>(g_nt.wcslen(source_str)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == source_len) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we reached the end of the source string there is nothing we can 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // match against. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_len > source_len) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There can't be a positive match when the target string is bigger than 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the source string 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL case_sensitive = (match_opts & CASE_INSENSITIVE) ? TRUE : FALSE; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have three cases, depending on the value of start_pos: 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Case 1. We skip N characters and compare once. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Case 2: We skip to the end and compare once. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Case 3: We match the first substring (if we find any). 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_position >= 0) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kSeekToEnd == start_position) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_position = source_len - match_len; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (match_opts & EXACT_LENGHT) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A sub-case of case 3 is when the EXACT_LENGHT flag is on 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the match needs to be not just substring but full match. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((match_len + start_position) != source_len) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance start_pos characters. Warning! this does not consider 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // utf16 encodings (surrogate pairs) or other Unicode 'features'. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_str += start_position; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we skipped, lets reevaluate just the lengths again. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((match_len + start_position) > source_len) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNICODE_STRING match_ustr; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitStringUnicode(match_str, match_len, &match_ustr); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNICODE_STRING source_ustr; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitStringUnicode(source_str, match_len, &source_ustr); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == g_nt.RtlCompareUnicodeString(&match_ustr, &source_ustr, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case_sensitive)) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Match! update the match context. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->position += start_position + match_len; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_TRUE; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (start_position < 0) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNICODE_STRING match_ustr; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitStringUnicode(match_str, match_len, &match_ustr); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNICODE_STRING source_ustr; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitStringUnicode(source_str, match_len, &source_ustr); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == g_nt.RtlCompareUnicodeString(&match_ustr, &source_ustr, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case_sensitive)) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Match! update the match context. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->position += (source_ustr.Buffer - source_str) + match_len; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_TRUE; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++source_ustr.Buffer; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --source_len; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (source_len >= match_len); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_FALSE; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OpcodeMaker (other member functions). 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyOpcode* OpcodeFactory::MakeBase(OpcodeID opcode_id, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int16 selected_param) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (memory_size() < sizeof(PolicyOpcode)) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create opcode using placement-new on the buffer memory. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* opcode = new(memory_top_) PolicyOpcode(); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill in the standard fields, that every opcode has. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_top_ += sizeof(PolicyOpcode); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->opcode_id_ = opcode_id; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->options_ = static_cast<int16>(options); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opcode->parameter_ = selected_param; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return opcode; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ptrdiff_t OpcodeFactory::AllocRelative(void* start, const wchar_t* str, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t lenght) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes = lenght * sizeof(wchar_t); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (memory_size() < bytes) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_bottom_ -= bytes; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reinterpret_cast<UINT_PTR>(memory_bottom_) & 1) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(cpu) replace this for something better. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DebugBreak(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(memory_bottom_, str, bytes); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptrdiff_t delta = memory_bottom_ - reinterpret_cast<char*>(start); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delta; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opcode evaluation dispatchers. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function is the one and only entry for evaluating any opcode. It is 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in charge of applying any relevant opcode options and calling EvaluateInner 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// were the actual dispatch-by-id is made. It would seem at first glance that 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the dispatch should be done by virtual function (vtable) calls but you have 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to remember that the opcodes are made in the broker process and copied as 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// raw memory to the target process. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult PolicyOpcode::Evaluate(const ParameterSet* call_params, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t param_count, MatchContext* match) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == call_params) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_ERROR; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ParameterSet* selected_param = NULL; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parameter_ >= 0) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<size_t>(parameter_) >= param_count) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_ERROR; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_param = &call_params[parameter_]; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EvalResult result = EvaluateHelper(selected_param, match); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Apply the general options regardless of the particular type of opcode. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kPolNone == options_) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (options_ & kPolNegateEval) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (EVAL_TRUE == result) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = EVAL_FALSE; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (EVAL_FALSE == result) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = EVAL_TRUE; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (EVAL_ERROR != result) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = EVAL_ERROR; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL != match) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (options_ & kPolClearContext) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match->Clear(); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (options_ & kPolUseOREval) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match->options = kPolUseOREval; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OPCODE_EVAL(op, x, y, z) case op: return OpcodeEval<op>(x, y, z) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult PolicyOpcode::EvaluateHelper(const ParameterSet* parameters, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext* match) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (opcode_id_) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_ALWAYS_FALSE, this, parameters, match); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_ALWAYS_TRUE, this, parameters, match); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_NUMBER_MATCH, this, parameters, match); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_ULONG_MATCH_RANGE, this, parameters, match); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_WSTRING_MATCH, this, parameters, match); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_ULONG_AND_MATCH, this, parameters, match); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPCODE_EVAL(OP_ACTION, this, parameters, match); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EVAL_ERROR; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef OPCODE_EVAL 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 455