| 1 | /*
|
|---|
| 2 | RPC echo server.
|
|---|
| 3 |
|
|---|
| 4 | Copyright (C) Tim Potter 2003
|
|---|
| 5 |
|
|---|
| 6 | This program is free software; you can redistribute it and/or modify
|
|---|
| 7 | it under the terms of the GNU General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 3 of the License, or
|
|---|
| 9 | (at your option) any later version.
|
|---|
| 10 |
|
|---|
| 11 | This program is distributed in the hope that it will be useful,
|
|---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 14 | GNU General Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License
|
|---|
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|---|
| 18 | */
|
|---|
| 19 |
|
|---|
| 20 | #define _WIN32_WINNT 0x0500
|
|---|
| 21 |
|
|---|
| 22 | #include <stdio.h>
|
|---|
| 23 | #include <stdlib.h>
|
|---|
| 24 | #include <ctype.h>
|
|---|
| 25 | #include "rpcecho.h"
|
|---|
| 26 |
|
|---|
| 27 | #define RPC_MIN_CALLS 1
|
|---|
| 28 | #define RPC_MAX_CALLS 20
|
|---|
| 29 | #define RPC_ENDPOINT "\\pipe\\rpcecho"
|
|---|
| 30 |
|
|---|
| 31 | void AddOne(int in_data, __RPC_FAR int *out_data)
|
|---|
| 32 | {
|
|---|
| 33 | printf("AddOne: got in_data = %d\n", in_data);
|
|---|
| 34 | *out_data = in_data + 1;
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | void EchoData(int len, unsigned char __RPC_FAR in_data[],
|
|---|
| 38 | unsigned char __RPC_FAR out_data[])
|
|---|
| 39 | {
|
|---|
| 40 | printf("EchoData: got len = %d\n", len);
|
|---|
| 41 |
|
|---|
| 42 | memcpy(out_data, in_data, len);
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | void SinkData(int len, unsigned char __RPC_FAR in_data[ ])
|
|---|
| 46 | {
|
|---|
| 47 | printf("SinkData: got len = %d\n", len);
|
|---|
| 48 | }
|
|---|
| 49 |
|
|---|
| 50 | void SourceData(int len, unsigned char __RPC_FAR out_data[ ])
|
|---|
| 51 | {
|
|---|
| 52 | int i;
|
|---|
| 53 |
|
|---|
| 54 | printf("SourceData: got len = %d\n", len);
|
|---|
| 55 |
|
|---|
| 56 | for (i = 0; i < len; i++)
|
|---|
| 57 | out_data[i] = i & 0xff;
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 | void TestCall(wchar_t **s1, wchar_t **s2)
|
|---|
| 61 | {
|
|---|
| 62 | if (*s1) {
|
|---|
| 63 | printf("s1='%S'\n", *s1);
|
|---|
| 64 | } else {
|
|---|
| 65 | printf("s1=NULL\n");
|
|---|
| 66 | }
|
|---|
| 67 | *s2 = L"test string";
|
|---|
| 68 | }
|
|---|
| 69 |
|
|---|
| 70 | long TestCall2(short level, echo_Info **info)
|
|---|
| 71 | {
|
|---|
| 72 | static echo_Info i;
|
|---|
| 73 |
|
|---|
| 74 | printf("TestCall2 level %d\n", level);
|
|---|
| 75 |
|
|---|
| 76 | *info = &i;
|
|---|
| 77 |
|
|---|
| 78 | switch (level) {
|
|---|
| 79 | case 1:
|
|---|
| 80 | i.info1.v = 10;
|
|---|
| 81 | break;
|
|---|
| 82 | case 2:
|
|---|
| 83 | i.info2.v = 20;
|
|---|
| 84 | break;
|
|---|
| 85 | case 3:
|
|---|
| 86 | i.info3.v = 30;
|
|---|
| 87 | break;
|
|---|
| 88 | case 4:
|
|---|
| 89 | i.info4.v = 40;
|
|---|
| 90 | break;
|
|---|
| 91 | case 5:
|
|---|
| 92 | i.info5.v1 = 50;
|
|---|
| 93 | i.info5.v2 = 51;
|
|---|
| 94 | break;
|
|---|
| 95 | case 6:
|
|---|
| 96 | i.info6.v1 = 60;
|
|---|
| 97 | i.info6.info1.v = 61;
|
|---|
| 98 | break;
|
|---|
| 99 | case 7:
|
|---|
| 100 | i.info7.v1 = 70;
|
|---|
| 101 | i.info7.info4.v = 71;
|
|---|
| 102 | break;
|
|---|
| 103 | default:
|
|---|
| 104 | return -1;
|
|---|
| 105 | }
|
|---|
| 106 | return 0;
|
|---|
| 107 | }
|
|---|
| 108 |
|
|---|
| 109 | #if 0
|
|---|
| 110 | void TestSleep(PRPC_ASYNC_STATE pAsync, long seconds)
|
|---|
| 111 | {
|
|---|
| 112 | long ret;
|
|---|
| 113 | printf("async Sleeping for %d seconds\n", seconds);
|
|---|
| 114 | Sleep(1000 * seconds);
|
|---|
| 115 | ret = seconds;
|
|---|
| 116 | RpcAsyncCompleteCall(pAsync, &ret);
|
|---|
| 117 | }
|
|---|
| 118 | #else
|
|---|
| 119 | long TestSleep(long seconds)
|
|---|
| 120 | {
|
|---|
| 121 | printf("non-async Sleeping for %d seconds\n", seconds);
|
|---|
| 122 | Sleep(1000 * seconds);
|
|---|
| 123 | return seconds;
|
|---|
| 124 | }
|
|---|
| 125 | #endif
|
|---|
| 126 |
|
|---|
| 127 |
|
|---|
| 128 | void echo_TestEnum(echo_Enum1 *foo1,
|
|---|
| 129 | echo_Enum2 *foo2,
|
|---|
| 130 | echo_Enum3 *foo3)
|
|---|
| 131 | {
|
|---|
| 132 | foo2->e1 = ECHO_ENUM2;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | void echo_TestSurrounding(echo_Surrounding *data)
|
|---|
| 136 | {
|
|---|
| 137 | printf("Incoming array of size %d\n", data->x);
|
|---|
| 138 | data->x *= 2;
|
|---|
| 139 | }
|
|---|
| 140 |
|
|---|
| 141 | short echo_TestDoublePointer(short ***data)
|
|---|
| 142 | {
|
|---|
| 143 | if (!*data) {
|
|---|
| 144 | printf("WARNING: *data == NULL\n");
|
|---|
| 145 | return 0;
|
|---|
| 146 | }
|
|---|
| 147 | if (!**data) {
|
|---|
| 148 | printf("WARNING: **data == NULL\n");
|
|---|
| 149 | return 0;
|
|---|
| 150 | }
|
|---|
| 151 | printf("Incoming double pointer: %d\n", ***data);
|
|---|
| 152 | return ***data;
|
|---|
| 153 | }
|
|---|
| 154 |
|
|---|
| 155 | void main(int argc, char **argv)
|
|---|
| 156 | {
|
|---|
| 157 | RPC_STATUS status;
|
|---|
| 158 | RPC_BINDING_VECTOR *pBindingVector;
|
|---|
| 159 |
|
|---|
| 160 | if (argc != 1) {
|
|---|
| 161 | printf("Usage: rpcechosrv\n");
|
|---|
| 162 | exit(0);
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | status = RpcServerUseProtseqEp("ncacn_np", RPC_MAX_CALLS, "\\pipe\\rpcecho", NULL);
|
|---|
| 166 | if (status) {
|
|---|
| 167 | printf("Failed to register ncacn_np endpoint\n");
|
|---|
| 168 | exit(status);
|
|---|
| 169 | }
|
|---|
| 170 |
|
|---|
| 171 | status = RpcServerUseProtseqEp("ncacn_ip_tcp", RPC_MAX_CALLS, "1234", NULL);
|
|---|
| 172 | if (status) {
|
|---|
| 173 | printf("Failed to register ncacn_ip_tcp endpoint\n");
|
|---|
| 174 | exit(status);
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | status = RpcServerInqBindings(&pBindingVector);
|
|---|
| 178 | if (status) {
|
|---|
| 179 | printf("Failed RpcServerInqBindings\n");
|
|---|
| 180 | exit(status);
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | status = RpcEpRegister(rpcecho_v1_0_s_ifspec, pBindingVector, NULL, "rpcecho server");
|
|---|
| 184 | if (status) {
|
|---|
| 185 | printf("Failed RpcEpRegister\n");
|
|---|
| 186 | exit(status);
|
|---|
| 187 | }
|
|---|
| 188 |
|
|---|
| 189 | status = RpcServerRegisterIf(rpcecho_v1_0_s_ifspec, NULL, NULL);
|
|---|
| 190 |
|
|---|
| 191 | if (status) {
|
|---|
| 192 | printf("Failed to register interface\n");
|
|---|
| 193 | exit(status);
|
|---|
| 194 | }
|
|---|
| 195 |
|
|---|
| 196 | status = RpcServerRegisterAuthInfo(NULL, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, NULL);
|
|---|
| 197 | if (status) {
|
|---|
| 198 | printf("Failed to setup auth info\n");
|
|---|
| 199 | }
|
|---|
| 200 |
|
|---|
| 201 | status = RpcServerListen(RPC_MIN_CALLS, RPC_MAX_CALLS, FALSE);
|
|---|
| 202 |
|
|---|
| 203 | if (status) {
|
|---|
| 204 | printf("RpcServerListen returned error %d\n", status);
|
|---|
| 205 | exit(status);
|
|---|
| 206 | }
|
|---|
| 207 | }
|
|---|
| 208 |
|
|---|