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()); }