Example #1
0
        public string GenerateFieldCode()
        {
            StringBuilder function_code = new StringBuilder();
            string        request       = "request";
            string        result        = "result";
            string        real_func     = "real_func";

            function_code.AppendLine($@"malproxy::CallFuncResponse {_function_name}_stub(const malproxy::CallFuncRequest& {request}, FARPROC {real_func})");
            function_code.AppendLine("{");

            // out-only arguments will put an empty input argument as a place holder
            for (int argument_index = 0; argument_index < _parameters.Count; argument_index++)
            {
                function_code.AppendLine(_parameters[argument_index].GetFieldInputCode(request, argument_index));
            }

            string return_type     = _return_type != null ? _return_type.ParameterTypeCast : "void";
            string parameter_types = string.Join(",", _parameters.Select(p => p.ParameterTypeCast));
            string parameter_names = string.Join(",", _parameters.Select(p => p.ParameterInFunctionCall));

            // HANDLE raw_result = ((HANDLE(*)(LPCWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE))real_func)(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
            string raw_retval        = "raw_retval";
            string retval            = "retval";
            string return_value_code = "";

            if (_return_type != null)
            {
                return_value_code = $"{return_type} {raw_retval} = ";
            }
            function_code.AppendLine($"{return_value_code} (({return_type}(*)({parameter_types})){real_func})({parameter_names});");

            function_code.AppendLine($"malproxy::CallFuncResponse {result};");
            if (_return_type != null)
            {
                function_code.AppendLine($"malproxy::Argument {retval}_value; malproxy::Argument* {retval} = &{retval}_value;");
                function_code.AppendLine(_return_type.SetValueCode(retval, raw_retval));
                function_code.AppendLine($"std::unique_ptr<malproxy::Argument> {retval}_allocated_ptr = std::make_unique<malproxy::Argument>({retval}_value);");
                function_code.AppendLine($"{result}.set_allocated_return_value({retval}_allocated_ptr.release());");
            }

            foreach (var arg in _parameters)
            {
                if (!(arg is PointerParameter))
                {
                    continue;
                }
                var arg_ptr = arg as PointerParameter;
                if (!arg_ptr.Direction.HasFlag(ParameterDirection.out_param))
                {
                    continue;
                }

                function_code.AppendLine(arg_ptr.GetFieldOutputCode(result));
            }

            function_code.AppendLine($"return {result};");
            function_code.AppendLine("}");

            return(function_code.ToString());
        }