Index: subversion/include/svn_error.h
===================================================================
--- subversion/include/svn_error.h	(revision 26609)
+++ subversion/include/svn_error.h	(working copy)
@@ -56,6 +56,9 @@
  */
 char *svn_strerror(apr_status_t statcode, char *buf, apr_size_t bufsize);
 
+#ifdef WIN32
+const char *svn_win32_get_error_string(HRESULT hr, apr_pool_t *pool);
+#endif
 
 /** If @a err has a custom error message, return that, otherwise
  * store the generic error string associated with @a err->apr_err into
Index: subversion/include/svn_ra_svn.h
===================================================================
--- subversion/include/svn_ra_svn.h	(revision 26609)
+++ subversion/include/svn_ra_svn.h	(working copy)
@@ -147,6 +147,12 @@
                                           apr_file_t *out_file,
                                           apr_pool_t *pool);
 
+#ifdef WIN32
+svn_ra_svn_conn_t *svn_ra_svn_create_pipe(HANDLE handle,
+                                          svn_boolean_t useimpersonate,
+                                          apr_pool_t *pool);
+#endif
+
 /** Initialize a connection's capabilities to the ones specified in
  * @a list, which contains svn_ra_svn_item_t entries (which should
  * be of type SVN_RA_SVN_WORD; a malformed data error will result if
Index: subversion/libsvn_ra/ra_loader.c
===================================================================
--- subversion/libsvn_ra/ra_loader.c	(revision 26609)
+++ subversion/libsvn_ra/ra_loader.c	(working copy)
@@ -64,7 +64,11 @@
  * (Currently, this applies to the https scheme, which is only
  * available if SSL is supported.) */
 static const char * const dav_schemes[] = { "http", "https", NULL };
+#ifdef WIN32
+static const char * const svn_schemes[] = { "svn", "pipe", NULL };
+#else
 static const char * const svn_schemes[] = { "svn", NULL };
+#endif
 static const char * const local_schemes[] = { "file", NULL };
 
 static const struct ra_lib_defn {
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c	(revision 26609)
+++ subversion/libsvn_ra_svn/client.c	(working copy)
@@ -88,6 +88,10 @@
 
   if (strncasecmp(url, "svn", 3) != 0)
     return;
+#ifdef WIN32
+  if (strncasecmp(url, "pipe", 4) != 0)
+    return;
+#endif
   url += 3;
 
   /* Get the tunnel specification, if any. */
@@ -152,6 +156,35 @@
   return SVN_NO_ERROR;
 }
 
+#ifdef WIN32
+static svn_error_t *make_pipe_connection(const char *nodename, unsigned short port,
+                                    HANDLE *handle, apr_pool_t *pool)
+{
+  char *path = apr_palloc(pool, _MAX_PATH);
+  DWORD lastError;
+
+  if (stricmp(nodename, "localhost") == 0)
+	  apr_snprintf(path, _MAX_PATH, "\\\\.\\pipe\\SubVersion%d", port);
+  else
+	  apr_snprintf(path, _MAX_PATH, "\\\\%s\\pipe\\SubVersion%d", nodename, port);
+
+  *handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+    FILE_ATTRIBUTE_NORMAL, NULL);
+  if (*handle == INVALID_HANDLE_VALUE) {
+    lastError = GetLastError();
+	if (lastError == ERROR_PATH_NOT_FOUND)
+		return svn_error_createf(SVN_ERR_RA_SVN_CONNECTION_CLOSED,
+		NULL, _("Pipe connection refused '%s:%d'"), nodename, port);
+	else
+      return svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+        _("Can't connect pipe '%s:%d': %s"), nodename, port,
+        svn_win32_get_error_string(HRESULT_FROM_WIN32(lastError), pool));
+  }
+
+  return SVN_NO_ERROR;
+}
+#endif
+
 /* Set *DIFFS to an array of svn_prop_t, allocated in POOL, based on the
    property diffs in LIST, received from the server. */
 static svn_error_t *parse_prop_diffs(apr_array_header_t *list,
@@ -506,6 +539,9 @@
   svn_ra_svn__session_baton_t *sess;
   svn_ra_svn_conn_t *conn;
   apr_socket_t *sock;
+#ifdef WIN32
+  HANDLE handle;
+#endif
   apr_uint64_t minver, maxver;
   apr_array_header_t *mechlist, *caplist;
 
@@ -514,8 +550,9 @@
   sess->is_tunneled = (tunnel_argv != NULL);
   sess->user = uri->user;
   sess->hostname = uri->hostname;
-  sess->realm_prefix = apr_psprintf(pool, "<svn://%s:%d>", uri->hostname,
-                                    uri->port);
+  sess->realm_prefix = apr_psprintf(pool, "<%s://%s:%d>",
+    uri->scheme, uri->hostname, uri->port);
+
   sess->tunnel_argv = tunnel_argv;
   sess->callbacks = callbacks;
   sess->callbacks_baton = callbacks_baton;
@@ -525,8 +562,20 @@
     SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
   else
     {
+#ifdef WIN32
+      if (stricmp(uri->scheme, "pipe") == 0) {
+        sess->is_tunneled = TRUE;
+        SVN_ERR(make_pipe_connection(uri->hostname, uri->port, &handle, pool));
+        conn = svn_ra_svn_create_pipe(handle, FALSE, pool);
+      }
+      else {
+        SVN_ERR(make_connection(uri->hostname, uri->port, &sock, pool));
+        conn = svn_ra_svn_create_conn(sock, NULL, NULL, pool);
+      }
+#else
       SVN_ERR(make_connection(uri->hostname, uri->port, &sock, pool));
       conn = svn_ra_svn_create_conn(sock, NULL, NULL, pool);
+#endif
     }
 
   /* Make sure we set conn->session before reading from it,
@@ -599,7 +648,7 @@
 static const char * const *
 ra_svn_get_schemes(apr_pool_t *pool)
 {
-  static const char *schemes[] = { "svn", NULL };
+  static const char *schemes[] = { "svn", "pipe", NULL };
 
   return schemes;
 }
Index: subversion/libsvn_ra_svn/marshal.c
===================================================================
--- subversion/libsvn_ra_svn/marshal.c	(revision 26609)
+++ subversion/libsvn_ra_svn/marshal.c	(working copy)
@@ -71,6 +71,32 @@
   return conn;
 }
 
+#ifdef WIN32
+svn_ra_svn_conn_t *svn_ra_svn_create_pipe(HANDLE handle,
+										  svn_boolean_t useimpersonate,
+                                          apr_pool_t *pool)
+{
+  svn_ra_svn_conn_t *conn = apr_palloc(pool, sizeof(*conn));
+
+#ifdef SVN_HAVE_SASL
+  conn->sock = NULL;
+  conn->encrypted = FALSE;
+#endif
+  conn->session = NULL;
+  conn->read_ptr = conn->read_buf;
+  conn->read_end = conn->read_buf;
+  conn->write_pos = 0;
+  conn->block_handler = NULL;
+  conn->block_baton = NULL;
+  conn->capabilities = apr_hash_make(pool);
+  conn->pool = pool;
+
+  conn->stream = svn_ra_svn__stream_from_pipe(handle, useimpersonate, pool);
+
+  return conn;
+}
+#endif
+
 svn_error_t *svn_ra_svn_set_capabilities(svn_ra_svn_conn_t *conn,
                                          apr_array_header_t *list)
 {
Index: subversion/libsvn_ra_svn/ra_svn.h
===================================================================
--- subversion/libsvn_ra_svn/ra_svn.h	(revision 26609)
+++ subversion/libsvn_ra_svn/ra_svn.h	(working copy)
@@ -131,6 +131,12 @@
                                                     apr_file_t *out_file,
                                                     apr_pool_t *pool);
 
+#ifdef WIN32
+svn_ra_svn__stream_t *svn_ra_svn__stream_from_pipe(HANDLE handle,
+                                                    svn_boolean_t useimpersonate,
+                                                    apr_pool_t *pool);
+#endif
+
 /* Create an svn_ra_svn__stream_t using READ_CB, WRITE_CB, TIMEOUT_CB,
  * PENDING_CB, and BATON.
  */
Index: subversion/libsvn_ra_svn/streams.c
===================================================================
--- subversion/libsvn_ra_svn/streams.c	(revision 26609)
+++ subversion/libsvn_ra_svn/streams.c	(working copy)
@@ -48,6 +48,14 @@
   apr_pool_t *pool;
 } file_baton_t;
 
+#ifdef WIN32
+typedef struct {
+  HANDLE handle;
+  svn_boolean_t impersonating;
+  apr_pool_t *pool;
+} pipe_baton_t;
+#endif
+
 /* Returns TRUE if PFD has pending data, FALSE otherwise. */
 static svn_boolean_t pending(apr_pollfd_t *pfd, apr_pool_t *pool)
 {
@@ -249,3 +257,146 @@
 {
   return stream->pending_fn(stream->baton);
 }
+
+#ifdef WIN32
+/* Implements svn_read_fn_t */
+static svn_error_t *
+pipe_read_cb(void *baton, char *buffer, apr_size_t *len)
+{
+  pipe_baton_t *b = baton;
+  BOOL result, result2, lasterror;
+  DWORD readlen = 0, maxinterval = INFINITE, interval = INFINITE;
+
+  result = GetNamedPipeHandleState(b->handle, NULL, NULL, NULL, &interval, NULL, 0);
+  if (result == TRUE) {
+    /* Always block on read. */
+    result = SetNamedPipeHandleState(b->handle, NULL, NULL, &maxinterval);
+    if (result == FALSE)
+      return svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+        _("Can't set pipe timeout: %s"),
+        svn_win32_get_error_string(HRESULT_FROM_WIN32(GetLastError()), b->pool));
+
+    result = ReadFile(b->handle, buffer, *len, &readlen, NULL);
+    result2 = SetNamedPipeHandleState(b->handle, NULL, NULL, &interval);
+    if (result2 == FALSE)
+      return svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+        _("Can't set pipe timeout: %s"),
+        svn_win32_get_error_string(HRESULT_FROM_WIN32(GetLastError()), b->pool));
+  }
+  else
+    result = ReadFile(b->handle, buffer, *len, &readlen, NULL);
+
+  if (result == FALSE) {
+    lasterror = GetLastError();
+	if (lasterror == ERROR_BROKEN_PIPE)
+      return svn_error_create(SVN_ERR_RA_SVN_CONNECTION_CLOSED, NULL,
+                            _("Connection closed unexpectedly"));
+      return svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+        _("Can't read from connection: %s"),
+        svn_win32_get_error_string(HRESULT_FROM_WIN32(lasterror), b->pool));
+  }
+  if (readlen == 0)
+    return svn_error_create(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+                            _("No read from connection"));
+  *len = readlen;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+pipe_read_cb_with_impersonate(void *baton, char *buffer, apr_size_t *len)
+{
+  pipe_baton_t *b = baton;
+  DWORD lasterror = ERROR_INVALID_FUNCTION;
+  BOOL result = FALSE;
+  svn_error_t *err = NULL;
+
+  err = pipe_read_cb(baton, buffer, len);
+  if (err) return err;
+
+  if (b->impersonating == FALSE) {
+    result = ImpersonateNamedPipeClient(b->handle);
+    if (result == FALSE) {
+      lasterror = GetLastError();
+      return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+        _("Can't impersonate from pipe: %s"),
+        svn_win32_get_error_string(HRESULT_FROM_WIN32(lasterror), b->pool));
+    }
+    b->impersonating = TRUE;
+  }
+
+  return err;
+}
+
+/* Implements svn_write_fn_t */
+static svn_error_t *
+pipe_write_cb(void *baton, const char *buffer, apr_size_t *len)
+{
+  pipe_baton_t *b = baton;
+  DWORD writtenlen = 0;
+  BOOL result = WriteFile(b->handle, buffer, *len, &writtenlen, NULL);
+  if (result == FALSE)
+    return svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+        _("Can't write to connection: %s"),
+        svn_win32_get_error_string(HRESULT_FROM_WIN32(GetLastError()), b->pool));
+  return SVN_NO_ERROR;
+}
+
+/* Implements ra_svn_timeout_fn_t */
+static void
+pipe_timeout_cb(void *baton, apr_interval_time_t interval)
+{
+  pipe_baton_t *b = baton;
+  DWORD newinterval = (DWORD)interval;
+  SetNamedPipeHandleState(b->handle, NULL, NULL, &newinterval);
+}
+
+/* Implements ra_svn_pending_fn_t */
+static svn_boolean_t
+pipe_pending_cb(void *baton)
+{
+  pipe_baton_t *b = baton;
+  BOOL result;
+  DWORD avail = 0;
+
+  result = PeekNamedPipe(b->handle, NULL, 0, NULL, &avail, NULL);
+  if (result == FALSE)
+    return FALSE;
+  return (avail > 0) ? TRUE : FALSE;
+}
+
+static svn_error_t *
+pipe_stream_close(void *baton)
+{
+  pipe_baton_t *b = baton;
+  if (b->impersonating == TRUE)
+    RevertToSelf();
+  DisconnectNamedPipe(b->handle);
+  CloseHandle(b->handle);
+  return SVN_NO_ERROR;
+}
+
+svn_ra_svn__stream_t *
+svn_ra_svn__stream_from_pipe(HANDLE handle, 
+                              svn_boolean_t useimpersonate,
+                              apr_pool_t *pool)
+{
+  pipe_baton_t *b = apr_palloc(pool, sizeof(*b));
+  svn_ra_svn__stream_t *s;
+
+  b->handle = handle;
+  b->impersonating = FALSE;
+  b->pool = pool;
+
+  if (useimpersonate == TRUE)
+    s = svn_ra_svn__stream_create(b, pipe_read_cb_with_impersonate, pipe_write_cb,
+							   pipe_timeout_cb, pipe_pending_cb, pool);
+  else
+    s = svn_ra_svn__stream_create(b, pipe_read_cb, pipe_write_cb,
+                               pipe_timeout_cb, pipe_pending_cb, pool);
+
+  if (s != NULL)
+    svn_stream_set_close(s->stream, pipe_stream_close);
+
+  return s;
+}
+#endif
Index: subversion/libsvn_subr/error.c
===================================================================
--- subversion/libsvn_subr/error.c	(revision 26609)
+++ subversion/libsvn_subr/error.c	(working copy)
@@ -475,3 +475,38 @@
 
   return apr_strerror(statcode, buf, bufsize);
 }
+
+#ifdef WIN32
+
+#if 0
+#define USELANG 0
+#else
+#define USELANG MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)
+#endif
+
+const char *svn_win32_get_error_string(HRESULT hr, apr_pool_t *pool)
+{
+  wchar_t *fm = NULL;
+  char *str = NULL, *p = NULL;
+  int length, lengthW;
+
+  lengthW = FormatMessageW(
+    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+    NULL, hr, USELANG, (LPWSTR)&fm, 0, NULL);
+
+  length = WideCharToMultiByte(CP_UTF8, 0, fm, lengthW + 1, NULL, 0, NULL, NULL);
+  str = apr_palloc(pool, length + 20 + 1);
+  length = WideCharToMultiByte(CP_UTF8, 0, fm, lengthW + 1, str, length + 1, NULL, NULL);
+  LocalFree((HLOCAL)fm);
+
+  p = str;
+  while (*p != '\0') {
+    if (iscntrl(*p)) *p = ' ';
+    p++;
+  }
+
+  apr_snprintf(p, 20, " (%08x)", hr);
+
+  return str;
+}
+#endif
Index: subversion/svnserve/main.c
===================================================================
--- subversion/svnserve/main.c	(revision 26609)
+++ subversion/svnserve/main.c	(working copy)
@@ -136,6 +136,8 @@
 #define SVNSERVE_OPT_PID_FILE    261
 #define SVNSERVE_OPT_SERVICE     262
 #define SVNSERVE_OPT_CONFIG_FILE 263
+#define SVNSERVE_OPT_PIPE        264
+#define SVNSERVE_OPT_IMPERSONATE 265
 
 static const apr_getopt_option_t svnserve__options[] =
   {
@@ -167,6 +169,10 @@
 #ifdef WIN32
     {"service",          SVNSERVE_OPT_SERVICE, 0,
      N_("run as a windows service (SCM only)")},
+    {"pipe",              SVNSERVE_OPT_PIPE, 0,
+     N_("pipe is used instead of socket")},
+    {"pipe-with-impersonate", SVNSERVE_OPT_IMPERSONATE, 0,
+     N_("pipe is used with impersonation mode")},
 #endif
     {0,                  0,   0, 0}
   };
@@ -216,6 +222,60 @@
 }
 
 
+#ifdef WIN32 /* Handle pipe */
+static svn_error_t *get_pipe_handle(HANDLE *handle,
+    apr_uint16_t port, apr_pool_t *pool)
+{
+  SID_IDENTIFIER_AUTHORITY sidIdentifier = SECURITY_NT_AUTHORITY;
+  PSECURITY_DESCRIPTOR pSD = NULL;
+  PSID pAuthUsers = NULL;
+  PACL pAcl = NULL;
+  SECURITY_ATTRIBUTES sa;
+  char *path = NULL;
+  DWORD size = 0;
+  HRESULT hr = E_FAIL;
+
+  /* Initialize SID for AuthenticatedUsers */
+  AllocateAndInitializeSid(&sidIdentifier, 1,
+    SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0, &pAuthUsers);
+
+  /* Initialize ACL */
+  size = sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetLengthSid(pAuthUsers);
+  pAcl = apr_palloc(pool, size);
+  InitializeAcl(pAcl, size, ACL_REVISION); 
+  AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, pAuthUsers);
+
+  /* Initialize SD */
+  pSD = apr_palloc(pool, SECURITY_DESCRIPTOR_MIN_LENGTH);
+  InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+  SetSecurityDescriptorDacl(pSD, TRUE, pAcl, FALSE);
+
+  /* Initialize SA */
+  memset(&sa, 0, sizeof sa);
+  sa.nLength = sizeof sa;
+  sa.lpSecurityDescriptor = pSD;
+  sa.bInheritHandle = TRUE;
+
+  path = apr_palloc(pool, _MAX_PATH);
+  apr_snprintf(path, _MAX_PATH, "\\\\.\\pipe\\SubVersion%d", port);
+
+  *handle = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX,
+    PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+    PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, &sa);
+  hr = HRESULT_FROM_WIN32(GetLastError());
+
+  FreeSid(pAuthUsers);
+
+  if (*handle == INVALID_HANDLE_VALUE)
+    return svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+      _("Can't bind pipe '%d': %s"), port,
+      svn_win32_get_error_string(hr, pool));
+
+  return NULL;
+}
+#endif
+
+
 #if APR_HAS_FORK
 static void sigchld_handler(int signo)
 {
@@ -246,6 +306,8 @@
 struct serve_thread_t {
   svn_ra_svn_conn_t *conn;
   serve_params_t *params;
+  svn_boolean_t useimpersonate; /* Handle pipe */
+  HANDLE handle; /* Handle pipe */
   apr_pool_t *pool;
 };
 
@@ -304,6 +366,14 @@
   enum run_mode run_mode = run_mode_unspecified;
   svn_boolean_t foreground = FALSE;
   apr_socket_t *sock, *usock;
+  void *handle = 0;  /* Win32 HANDLE */
+  svn_boolean_t usepipe = FALSE;
+  svn_boolean_t useimpersonate = FALSE;
+#ifdef WIN32
+  char *path = NULL;
+  BOOL result = FALSE;
+  DWORD lasterror = ERROR_SUCCESS;
+#endif
   apr_file_t *in_file, *out_file;
   apr_sockaddr_t *sa;
   apr_pool_t *pool;
@@ -407,6 +477,13 @@
           break;
 
         case SVNSERVE_OPT_LISTEN_HOST:
+#ifdef WIN32
+          if (usepipe == TRUE) {
+            err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+              _("Can't bind pipe to hostname"));
+            return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
+          }
+#endif
           host = arg;
           break;
 
@@ -466,6 +543,19 @@
               mode_opt_count++;
             }
           break;
+
+        case SVNSERVE_OPT_IMPERSONATE:
+          useimpersonate = TRUE;
+		  /* FALLTHROUGH */
+
+        case SVNSERVE_OPT_PIPE:
+          if (host != NULL) {
+            err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+              _("Can't bind pipe to hostname"));
+            return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
+          }
+          usepipe = TRUE;
+          break;
 #endif
 
         case SVNSERVE_OPT_CONFIG_FILE:
@@ -587,6 +677,16 @@
     }
 #endif /* WIN32 */
 
+#ifdef WIN32 /* Handle pipe */
+  handle = INVALID_HANDLE_VALUE;
+  if (usepipe == TRUE) {
+    sock = NULL;
+    usock = NULL;
+    winservice_svnserve_accept_socket = INVALID_SOCKET;
+  }
+  else {
+#endif
+
   /* Make sure we have IPV6 support first before giving apr_sockaddr_info_get
      APR_UNSPEC, because it may give us back an IPV6 address even if we can't
      create IPV6 sockets. */
@@ -640,6 +740,10 @@
 
   apr_socket_listen(sock, 7);
 
+#ifdef WIN32 /* Handle pipe */
+  }
+#endif /* WIN32 */
+
 #if APR_HAS_FORK
   if (run_mode != run_mode_listen_once && !foreground)
     apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);
@@ -663,9 +767,11 @@
     SVN_INT_ERR(write_pid_file(pid_filename, pool));
 
 #ifdef WIN32
-  status = apr_os_sock_get(&winservice_svnserve_accept_socket, sock);
-  if (status)
-    winservice_svnserve_accept_socket = INVALID_SOCKET;
+  if (usepipe == FALSE) {
+    status = apr_os_sock_get(&winservice_svnserve_accept_socket, sock);
+    if (status)
+      winservice_svnserve_accept_socket = INVALID_SOCKET;
+  }
 
   /* At this point, the service is "running".  Notify the SCM. */
   if (run_mode == run_mode_service)
@@ -684,7 +790,28 @@
          separate pools, that can be cleared at thread exit, are used */
       connection_pool = svn_pool_create(NULL);
 
-      status = apr_socket_accept(&usock, sock, connection_pool);
+#ifdef WIN32 /* Handle pipe */
+      if (usepipe == TRUE) {
+		err = get_pipe_handle(&handle, port, pool);
+		if (err)
+		  return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
+        result = ConnectNamedPipe(handle, NULL);
+        if (result == FALSE) {
+          lasterror = GetLastError();
+          if (lasterror != ERROR_PIPE_CONNECTED) {
+            err = svn_error_createf(SVN_ERR_RA_SVN_IO_ERROR, NULL,
+              _("Can't connect pipe: %s"),
+              svn_win32_get_error_string(HRESULT_FROM_WIN32(lasterror), connection_pool));
+            return svn_cmdline_handle_exit_error(err, connection_pool, "svnserve: ");
+          }
+        }
+	    conn = svn_ra_svn_create_pipe(handle, useimpersonate, connection_pool);
+        params.tunnel = TRUE;
+      }
+      else {
+#endif
+
+	  status = apr_socket_accept(&usock, sock, connection_pool);
       if (handling_mode == connection_mode_fork)
         {
           /* Collect any zombie child processes. */
@@ -704,9 +831,13 @@
           return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
         }
 
-      conn = svn_ra_svn_create_conn(usock, NULL, NULL, connection_pool);
+	  conn = svn_ra_svn_create_conn(usock, NULL, NULL, connection_pool);
 
-      if (run_mode == run_mode_listen_once)
+#ifdef WIN32 /* Handle pipe */
+	  }
+#endif /* WIN32 */
+
+	  if (run_mode == run_mode_listen_once)
         {
           err = serve(conn, &params, connection_pool);
 
@@ -714,11 +845,23 @@
             svn_handle_error2(err, stdout, FALSE, "svnserve: ");
           svn_error_clear(err);
 
+#ifdef WIN32 /* Handle pipe */
+          if (usepipe == TRUE) {
+            CloseHandle(handle);
+            exit(0);
+          }
+          else {
+#endif
+
           apr_socket_close(usock);
           apr_socket_close(sock);
           exit(0);
-        }
 
+#ifdef WIN32 /* Handle pipe */
+	      }
+#endif /* WIN32 */
+	    }
+
       switch (handling_mode)
         {
         case connection_mode_fork:
@@ -769,6 +912,8 @@
           thread_data->conn = conn;
           thread_data->params = &params;
           thread_data->pool = connection_pool;
+		  thread_data->useimpersonate = useimpersonate;
+		  thread_data->handle = handle;
           status = apr_thread_create(&tid, tattr, serve_thread, thread_data,
                                      connection_pool);
           if (status)
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c	(revision 26609)
+++ subversion/svnserve/serve.c	(working copy)
@@ -2253,14 +2253,24 @@
  * if present.  Return NULL if the scheme part is invalid for ra_svn. */
 static const char *skip_scheme_part(const char *url)
 {
-  if (strncmp(url, "svn", 3) != 0)
-    return NULL;
-  url += 3;
-  if (*url == '+')
-    url += strcspn(url, ":");
-  if (strncmp(url, "://", 3) != 0)
-    return NULL;
-  return url + 3;
+  int ofs = 0;
+  if (strncmp(url, "svn", 3) == 0) {
+    ofs = 3;
+    if (*(url + ofs) == '+')
+      ofs += strcspn(url + ofs, ":");
+    if (strncmp(url + ofs, "://", 3) != 0)
+      return NULL;
+    return url + ofs + 3;
+  }
+#ifdef WIN32
+  if (strncmp(url, "pipe", 4) == 0) {
+    ofs = 4;
+    if (strncmp(url + ofs, "://", 3) != 0)
+      return NULL;
+    return url + ofs + 3;
+  }
+#endif
+  return NULL;
 }
 
 /* Check that PATH is a valid repository path, meaning it doesn't contain any
