summaryrefslogtreecommitdiffstats
path: root/testprogs/win32/rpcecho
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /testprogs/win32/rpcecho
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testprogs/win32/rpcecho')
-rw-r--r--testprogs/win32/rpcecho/Makefile23
-rw-r--r--testprogs/win32/rpcecho/README46
-rw-r--r--testprogs/win32/rpcecho/client.c367
-rw-r--r--testprogs/win32/rpcecho/rpcecho.acf26
-rw-r--r--testprogs/win32/rpcecho/rpcecho.idl146
-rw-r--r--testprogs/win32/rpcecho/server.c208
-rw-r--r--testprogs/win32/rpcecho/utils.c32
7 files changed, 848 insertions, 0 deletions
diff --git a/testprogs/win32/rpcecho/Makefile b/testprogs/win32/rpcecho/Makefile
new file mode 100644
index 0000000..ca0c823
--- /dev/null
+++ b/testprogs/win32/rpcecho/Makefile
@@ -0,0 +1,23 @@
+INCLUDES=-I
+CFLAGS=$(INCLUDES) -Zi -nologo
+LIBS=rpcrt4.lib
+
+all: client server
+
+clean:
+ del *~ *.obj client server rpcecho_c.c rpcecho_s.c rpcecho.h
+
+rpcecho.h rpcecho_s.c rpcecho_c.c: rpcecho.idl rpcecho.acf
+ midl rpcecho.idl
+
+client: client.obj rpcecho_c.obj utils.obj
+ $(CC) $(CFLAGS) -o client client.obj rpcecho_c.obj utils.obj $(LIBS)
+
+server: server.obj rpcecho_s.obj utils.obj
+ $(CC) $(CFLAGS) -o server server.obj rpcecho_s.obj utils.obj $(LIBS)
+
+client.obj: rpcecho.h client.c
+server.obj: rpcecho.h server.c
+rpcecho_c.obj: rpcecho.h rpcecho_c.c
+rpcecho_s.obj: rpcecho.h rpcecho_s.c
+utils.obj: rpcecho.h utils.c
diff --git a/testprogs/win32/rpcecho/README b/testprogs/win32/rpcecho/README
new file mode 100644
index 0000000..2eb6ab9
--- /dev/null
+++ b/testprogs/win32/rpcecho/README
@@ -0,0 +1,46 @@
+This directory contains two win32 programs to test large RPC requests
+and responses. The two programs are:
+
+ server A command line RPC server that listens and processes
+ RPC requests on the \pipe\rpcecho named pipe.
+
+ client A command line RPC client program that
+
+Samba also implements the client and server sides of the rpcecho pipe
+if the --enable-developer option to configure has been used. The
+rpcclient(1) program is used to implement the client side RPC
+operations.
+
+There are currently four RPC calls defined in the rpcecho pipe. They
+are:
+
+ AddOne Adds one to an integer sent by the client
+
+ EchoData The client sends an array of bytes and it is echoed
+ back by the server.
+
+ SourceData The client sends an array of bytes and it is discarded
+ by the server.
+
+ SinkData The server returns an array of bytes.
+
+The Ethereal network protocol decoder (http://www.ethereal.com/) also
+contains support for the rpcecho pipe as part of its DCERPC for
+Windows.
+
+Starting the win32 server program is easy. Just run server.exe in a
+command window. The win32 client program is also run from a command
+window. The usage information is shown below:
+
+ Usage: client hostname cmd [args]
+
+ Where hostname is the name of the host to connect to,
+ and cmd is the command to execute with optional args:
+
+ addone num Add one to num and return the result
+ echodata size Send an array of size bytes and receive it back
+ sinkdata size Send an array of size bytes
+ sourcedata size Receive an array of size bytes
+
+Tim Potter
+tpot@samba.org
diff --git a/testprogs/win32/rpcecho/client.c b/testprogs/win32/rpcecho/client.c
new file mode 100644
index 0000000..dae2a4b
--- /dev/null
+++ b/testprogs/win32/rpcecho/client.c
@@ -0,0 +1,367 @@
+/*
+ RPC echo client.
+
+ Copyright (C) Tim Potter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "rpcecho.h"
+
+void main(int argc, char **argv)
+{
+ RPC_STATUS status;
+ char *binding = NULL;
+ const char *username=NULL;
+ const char *password=NULL;
+ const char *domain=NULL;
+ unsigned sec_options = 0;
+
+ argv += 1;
+ argc -= 1;
+
+ while (argc > 2 && argv[0][0] == '-') {
+ const char *option;
+
+ switch (argv[0][1]) {
+ case 'e':
+ binding = argv[1];
+ break;
+ case 'u':
+ username = argv[1];
+ break;
+ case 'p':
+ password = argv[1];
+ break;
+ case 'd':
+ domain = argv[1];
+ break;
+ case '-':
+ option = &argv[0][2];
+ if (strcmp(option, "sign") == 0) {
+ if (sec_options == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) {
+ printf("You must choose sign or seal, not both\n");
+ exit(1);
+ }
+ sec_options = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
+ } else if (strcmp(option, "seal") == 0) {
+ if (sec_options == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) {
+ printf("You must choose sign or seal, not both\n");
+ exit(1);
+ }
+ sec_options = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
+ } else {
+ printf("Bad security option '%s'\n", option);
+ exit(1);
+ }
+ argv++;
+ argc--;
+ continue;
+ default:
+ printf("Bad option -%c\n", argv[0][0]);
+ exit(1);
+ }
+ argv += 2;
+ argc -= 2;
+ }
+
+ if (argc < 2) {
+ printf("Usage: client [options] hostname cmd [args]\n\n");
+ printf("Where hostname is the name of the host to connect to,\n");
+ printf("and cmd is the command to execute with optional args:\n\n");
+ printf("\taddone num\tAdd one to num and return the result\n");
+ printf("\techodata size\tSend an array of size bytes and receive it back\n");
+ printf("\tsinkdata size\tSend an array of size bytes\n");
+ printf("\tsourcedata size\tReceive an array of size bytes\n");
+ printf("\ttest\trun testcall\n");
+ printf("\noptions:\n");
+ printf("\t-u username -d domain -p password -e endpoint\n");
+ printf("\t--sign --seal\n");
+ printf("\nExamples:\n");
+ printf("\tclient HOSTNAME addone 3\n");
+ printf("\tclient 192.168.115.1 addone 3\n");
+ printf("\tclient -e ncacn_np:HOSTNAME[\\\\pipe\\\\rpcecho] addone 3\n");
+ printf("\tclient -e ncacn_ip_tcp:192.168.115.1 addone 3\n");
+ printf("\tclient -e ncacn_ip_tcp:192.168.115.1 -u tridge -d MYDOMAIN -p PASSWORD addone 3\n");
+ exit(0);
+ }
+
+
+ if (!binding) {
+ char *network_address = argv[0];
+
+ argc--;
+ argv++;
+
+ status = RpcStringBindingCompose(
+ NULL, /* uuid */
+ "ncacn_np",
+ network_address,
+ "\\pipe\\rpcecho",
+ NULL, /* options */
+ &binding);
+
+ if (status) {
+ printf("RpcStringBindingCompose returned %d\n", status);
+ exit(status);
+ }
+ }
+
+ printf("Endpoint is %s\n", binding);
+
+ status = RpcBindingFromStringBinding(
+ binding,
+ &rpcecho_IfHandle);
+
+ if (status) {
+ printf("RpcBindingFromStringBinding returned %d\n", status);
+ exit(status);
+ }
+
+ if (username) {
+ SEC_WINNT_AUTH_IDENTITY ident = { username, strlen(username),
+ domain, strlen(domain),
+ password, strlen(password),
+ SEC_WINNT_AUTH_IDENTITY_ANSI };
+
+ status = RpcBindingSetAuthInfo(rpcecho_IfHandle, NULL,
+ sec_options,
+ RPC_C_AUTHN_WINNT,
+ &ident, 0);
+ if (status) {
+ printf ("RpcBindingSetAuthInfo failed: 0x%x\n", status);
+ exit (1);
+ }
+ }
+
+
+ while (argc > 0) {
+ RpcTryExcept {
+
+ /* Add one to a number */
+
+ if (strcmp(argv[0], "addone") == 0) {
+ int arg, result;
+
+ if (argc < 2) {
+ printf("Usage: addone num\n");
+ exit(1);
+ }
+
+ arg = atoi(argv[1]);
+
+ AddOne(arg, &result);
+ printf("%d + 1 = %d\n", arg, result);
+
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ /* Echo an array */
+
+ if (strcmp(argv[0], "echodata") == 0) {
+ int arg, i;
+ char *indata, *outdata;
+
+ if (argc < 2) {
+ printf("Usage: echo num\n");
+ exit(1);
+ }
+
+ arg = atoi(argv[1]);
+
+ if ((indata = malloc(arg)) == NULL) {
+ printf("Error allocating %d bytes for input\n", arg);
+ exit(1);
+ }
+
+ if ((outdata = malloc(arg)) == NULL) {
+ printf("Error allocating %d bytes for output\n", arg);
+ exit(1);
+ }
+
+ for (i = 0; i < arg; i++)
+ indata[i] = i & 0xff;
+
+ EchoData(arg, indata, outdata);
+
+ printf("echo %d\n", arg);
+
+ for (i = 0; i < arg; i++) {
+ if (indata[i] != outdata[i]) {
+ printf("data mismatch at offset %d, %d != %d\n",
+ i, indata[i], outdata[i]);
+ exit(0);
+ }
+ }
+
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (strcmp(argv[0], "sinkdata") == 0) {
+ int arg, i;
+ char *indata;
+
+ if (argc < 2) {
+ printf("Usage: sinkdata num\n");
+ exit(1);
+ }
+
+ arg = atoi(argv[1]);
+
+ if ((indata = malloc(arg)) == NULL) {
+ printf("Error allocating %d bytes for input\n", arg);
+ exit(1);
+ }
+
+ for (i = 0; i < arg; i++)
+ indata[i] = i & 0xff;
+
+ SinkData(arg, indata);
+
+ printf("sinkdata %d\n", arg);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (strcmp(argv[0], "sourcedata") == 0) {
+ int arg, i;
+ unsigned char *outdata;
+
+ if (argc < 2) {
+ printf("Usage: sourcedata num\n");
+ exit(1);
+ }
+
+ arg = atoi(argv[1]);
+
+ if ((outdata = malloc(arg)) == NULL) {
+ printf("Error allocating %d bytes for output\n", arg);
+ exit(1);
+ }
+
+ SourceData(arg, outdata);
+
+ printf("sourcedata %d\n", arg);
+
+ for (i = 0; i < arg; i++) {
+ if (outdata[i] != (i & 0xff)) {
+ printf("data mismatch at offset %d, %d != %d\n",
+ i, outdata[i], i & 0xff);
+ }
+ }
+
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if (strcmp(argv[0], "test") == 0) {
+ printf("no TestCall\n");
+
+ argc -= 1;
+ argv += 1;
+ continue;
+ }
+
+
+ if (strcmp(argv[0], "enum") == 0) {
+ enum echo_Enum1 v = ECHO_ENUM1;
+ echo_Enum2 e2;
+ echo_Enum3 e3;
+
+ e2.e1 = 76;
+ e2.e2 = ECHO_ENUM1_32;
+ e3.e1 = ECHO_ENUM2;
+
+ argc -= 1;
+ argv += 1;
+
+ echo_TestEnum(&v, &e2, &e3);
+
+ continue;
+ }
+
+ if (strcmp(argv[0], "double") == 0) {
+ typedef unsigned short uint16;
+ uint16 v = 13;
+ uint16 *pv = &v;
+ uint16 **ppv = &pv;
+ uint16 ret;
+
+ argc -= 1;
+ argv += 1;
+
+ ret = echo_TestDoublePointer(&ppv);
+
+ printf("TestDoublePointer v=%d ret=%d\n", v, ret);
+
+ continue;
+ }
+
+ if (strcmp(argv[0], "sleep") == 0) {
+ long arg, result;
+
+ if (argc < 2) {
+ printf("Usage: sleep num\n");
+ exit(1);
+ }
+
+ arg = atoi(argv[1]);
+
+// result = TestSleep(arg);
+// printf("Slept for %d seconds\n", result);
+ printf("Sleep disabled (need async code)\n");
+
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ printf("Invalid command '%s'\n", argv[0]);
+ goto done;
+
+ } RpcExcept(1) {
+ unsigned long ex;
+
+ ex = RpcExceptionCode();
+ printf("Runtime error 0x%x\n", ex);
+ } RpcEndExcept
+ }
+
+done:
+
+ status = RpcStringFree(&binding);
+
+ if (status) {
+ printf("RpcStringFree returned %d\n", status);
+ exit(status);
+ }
+
+ status = RpcBindingFree(&rpcecho_IfHandle);
+
+ if (status) {
+ printf("RpcBindingFree returned %d\n", status);
+ exit(status);
+ }
+
+ exit(0);
+}
diff --git a/testprogs/win32/rpcecho/rpcecho.acf b/testprogs/win32/rpcecho/rpcecho.acf
new file mode 100644
index 0000000..56c7d33
--- /dev/null
+++ b/testprogs/win32/rpcecho/rpcecho.acf
@@ -0,0 +1,26 @@
+/*
+ RPC echo ACF.
+
+ Copyright (C) Tim Potter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+[
+ implicit_handle (handle_t rpcecho_IfHandle)
+]
+interface rpcecho
+{
+/* [async] TestSleep(); */
+}
diff --git a/testprogs/win32/rpcecho/rpcecho.idl b/testprogs/win32/rpcecho/rpcecho.idl
new file mode 100644
index 0000000..b0ddb81
--- /dev/null
+++ b/testprogs/win32/rpcecho/rpcecho.idl
@@ -0,0 +1,146 @@
+/*
+ RPC echo IDL.
+
+ Copyright (C) Tim Potter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __PIDL__
+#define unistr [string] wchar_t *
+#endif
+
+[
+uuid(60a15ec5-4de8-11d7-a637-005056a20182),
+version(1.0)
+]
+interface rpcecho
+{
+ // Add one to an integer
+ void AddOne(
+ [in] int in_data,
+ [out] int *out_data
+ );
+ // Echo an array of bytes back at the caller
+ void EchoData(
+ [in] int len,
+ [in] [size_is(len)] char in_data[],
+ [out] [size_is(len)] char out_data[]
+ );
+ // Sink data to the server
+ void SinkData(
+ [in] int len,
+ [in] [size_is(len)] char in_data[]
+ );
+ // Source data from server
+ void SourceData(
+ [in] int len,
+ [out] [size_is(len)] char out_data[]
+ );
+ const long myconstant = 42;
+
+ /* test strings */
+ void TestCall (
+ [in] unistr *s1,
+ [out] unistr *s2
+ );
+
+ /* test some alignment issues */
+ typedef struct {
+ char v;
+ } echo_info1;
+
+ typedef struct {
+ short v;
+ } echo_info2;
+
+ typedef struct {
+ long v;
+ } echo_info3;
+
+ typedef struct {
+ hyper v;
+ } echo_info4;
+
+ typedef struct {
+ char v1;
+ hyper v2;
+ } echo_info5;
+
+ typedef struct {
+ char v1;
+ echo_info1 info1;
+ } echo_info6;
+
+ typedef struct {
+ char v1;
+ echo_info4 info4;
+ } echo_info7;
+
+ typedef union {
+ [case(1)] echo_info1 info1;
+ [case(2)] echo_info2 info2;
+ [case(3)] echo_info3 info3;
+ [case(4)] echo_info4 info4;
+ [case(5)] echo_info5 info5;
+ [case(6)] echo_info6 info6;
+ [case(7)] echo_info7 info7;
+ } echo_Info;
+
+ long TestCall2 (
+ [in] short level,
+ [out,switch_is(level)] echo_Info **info
+ );
+
+ long TestSleep(
+ [in] long seconds
+ );
+
+ typedef enum {
+ ECHO_ENUM1 = 1,
+ ECHO_ENUM2 = 2
+ } echo_Enum1;
+
+ typedef [v1_enum] enum {
+ ECHO_ENUM1_32 = 1,
+ ECHO_ENUM2_32 = 2
+ } echo_Enum1_32;
+
+ typedef struct {
+ echo_Enum1 e1;
+ echo_Enum1_32 e2;
+ } echo_Enum2;
+
+ typedef union {
+ [case(ECHO_ENUM1)] echo_Enum1 e1;
+ [case(ECHO_ENUM2)] echo_Enum2 e2;
+ } echo_Enum3;
+
+ void echo_TestEnum(
+ [in,out,ref] echo_Enum1 *foo1,
+ [in,out,ref] echo_Enum2 *foo2,
+ [in,out,ref,switch_is(*foo1)] echo_Enum3 *foo3
+ );
+
+ typedef struct {
+ long x;
+ [size_is(x)] short surrounding[*];
+ } echo_Surrounding;
+
+ void echo_TestSurrounding(
+ [in,out,ref] echo_Surrounding *data
+ );
+
+ short echo_TestDoublePointer([in] short ***data);
+}
diff --git a/testprogs/win32/rpcecho/server.c b/testprogs/win32/rpcecho/server.c
new file mode 100644
index 0000000..b092852
--- /dev/null
+++ b/testprogs/win32/rpcecho/server.c
@@ -0,0 +1,208 @@
+/*
+ RPC echo server.
+
+ Copyright (C) Tim Potter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define _WIN32_WINNT 0x0500
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "rpcecho.h"
+
+#define RPC_MIN_CALLS 1
+#define RPC_MAX_CALLS 20
+#define RPC_ENDPOINT "\\pipe\\rpcecho"
+
+void AddOne(int in_data, __RPC_FAR int *out_data)
+{
+ printf("AddOne: got in_data = %d\n", in_data);
+ *out_data = in_data + 1;
+}
+
+void EchoData(int len, unsigned char __RPC_FAR in_data[],
+ unsigned char __RPC_FAR out_data[])
+{
+ printf("EchoData: got len = %d\n", len);
+
+ memcpy(out_data, in_data, len);
+}
+
+void SinkData(int len, unsigned char __RPC_FAR in_data[ ])
+{
+ printf("SinkData: got len = %d\n", len);
+}
+
+void SourceData(int len, unsigned char __RPC_FAR out_data[ ])
+{
+ int i;
+
+ printf("SourceData: got len = %d\n", len);
+
+ for (i = 0; i < len; i++)
+ out_data[i] = i & 0xff;
+}
+
+void TestCall(wchar_t **s1, wchar_t **s2)
+{
+ if (*s1) {
+ printf("s1='%S'\n", *s1);
+ } else {
+ printf("s1=NULL\n");
+ }
+ *s2 = L"test string";
+}
+
+long TestCall2(short level, echo_Info **info)
+{
+ static echo_Info i;
+
+ printf("TestCall2 level %d\n", level);
+
+ *info = &i;
+
+ switch (level) {
+ case 1:
+ i.info1.v = 10;
+ break;
+ case 2:
+ i.info2.v = 20;
+ break;
+ case 3:
+ i.info3.v = 30;
+ break;
+ case 4:
+ i.info4.v = 40;
+ break;
+ case 5:
+ i.info5.v1 = 50;
+ i.info5.v2 = 51;
+ break;
+ case 6:
+ i.info6.v1 = 60;
+ i.info6.info1.v = 61;
+ break;
+ case 7:
+ i.info7.v1 = 70;
+ i.info7.info4.v = 71;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+#if 0
+void TestSleep(PRPC_ASYNC_STATE pAsync, long seconds)
+{
+ long ret;
+ printf("async Sleeping for %d seconds\n", seconds);
+ Sleep(1000 * seconds);
+ ret = seconds;
+ RpcAsyncCompleteCall(pAsync, &ret);
+}
+#else
+long TestSleep(long seconds)
+{
+ printf("non-async Sleeping for %d seconds\n", seconds);
+ Sleep(1000 * seconds);
+ return seconds;
+}
+#endif
+
+
+void echo_TestEnum(echo_Enum1 *foo1,
+ echo_Enum2 *foo2,
+ echo_Enum3 *foo3)
+{
+ foo2->e1 = ECHO_ENUM2;
+}
+
+void echo_TestSurrounding(echo_Surrounding *data)
+{
+ printf("Incoming array of size %d\n", data->x);
+ data->x *= 2;
+}
+
+short echo_TestDoublePointer(short ***data)
+{
+ if (!*data) {
+ printf("WARNING: *data == NULL\n");
+ return 0;
+ }
+ if (!**data) {
+ printf("WARNING: **data == NULL\n");
+ return 0;
+ }
+ printf("Incoming double pointer: %d\n", ***data);
+ return ***data;
+}
+
+void main(int argc, char **argv)
+{
+ RPC_STATUS status;
+ RPC_BINDING_VECTOR *pBindingVector;
+
+ if (argc != 1) {
+ printf("Usage: rpcechosrv\n");
+ exit(0);
+ }
+
+ status = RpcServerUseProtseqEp("ncacn_np", RPC_MAX_CALLS, "\\pipe\\rpcecho", NULL);
+ if (status) {
+ printf("Failed to register ncacn_np endpoint\n");
+ exit(status);
+ }
+
+ status = RpcServerUseProtseqEp("ncacn_ip_tcp", RPC_MAX_CALLS, "1234", NULL);
+ if (status) {
+ printf("Failed to register ncacn_ip_tcp endpoint\n");
+ exit(status);
+ }
+
+ status = RpcServerInqBindings(&pBindingVector);
+ if (status) {
+ printf("Failed RpcServerInqBindings\n");
+ exit(status);
+ }
+
+ status = RpcEpRegister(rpcecho_v1_0_s_ifspec, pBindingVector, NULL, "rpcecho server");
+ if (status) {
+ printf("Failed RpcEpRegister\n");
+ exit(status);
+ }
+
+ status = RpcServerRegisterIf(rpcecho_v1_0_s_ifspec, NULL, NULL);
+
+ if (status) {
+ printf("Failed to register interface\n");
+ exit(status);
+ }
+
+ status = RpcServerRegisterAuthInfo(NULL, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, NULL);
+ if (status) {
+ printf("Failed to setup auth info\n");
+ }
+
+ status = RpcServerListen(RPC_MIN_CALLS, RPC_MAX_CALLS, FALSE);
+
+ if (status) {
+ printf("RpcServerListen returned error %d\n", status);
+ exit(status);
+ }
+}
+
diff --git a/testprogs/win32/rpcecho/utils.c b/testprogs/win32/rpcecho/utils.c
new file mode 100644
index 0000000..09a81d1
--- /dev/null
+++ b/testprogs/win32/rpcecho/utils.c
@@ -0,0 +1,32 @@
+/*
+ RPC echo utility functions.
+
+ Copyright (C) Tim Potter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "rpcecho.h"
+
+/* MIDL allocate and free functions */
+
+void __RPC_FAR *__RPC_USER midl_user_allocate(size_t len)
+{
+ return(malloc(len));
+}
+
+void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
+{
+ free(ptr);
+}