3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define PIPE "\\PIPE\\"
29 #define PIPELEN strlen(PIPE)
31 extern int DEBUGLEVEL;
32 static int chain_pnum = -1;
34 #ifndef MAX_OPEN_PIPES
35 #define MAX_OPEN_PIPES 50
38 #define PIPE_HANDLE_OFFSET 0x800
40 pipes_struct Pipes[MAX_OPEN_PIPES];
42 #define P_OPEN(p) ((p)->open)
43 #define P_OK(p,c) (P_OPEN(p) && (c)==((p)->cnum))
44 #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
45 #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && P_OPEN(&(Pipes[pnum])))
46 #define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
49 /****************************************************************************
50 reset pipe chain handle number
51 ****************************************************************************/
52 void reset_chain_pnum(void)
57 /****************************************************************************
58 sets chain pipe-file handle
59 ****************************************************************************/
60 void set_chain_pnum(int new_pnum)
62 chain_pnum = new_pnum;
65 /****************************************************************************
66 initialise pipe handle states...
67 ****************************************************************************/
68 void init_rpc_pipe_hnd(void)
71 /* we start at 1 here for an obscure reason I can't now remember,
72 but I think is important :-) */
73 for (i = 1; i < MAX_OPEN_PIPES; i++)
75 Pipes[i].open = False;
77 Pipes[i].pipe_srv_name[0] = 0;
79 Pipes[i].rhdr.data = NULL;
80 Pipes[i].rdata.data = NULL;
81 Pipes[i].rhdr.offset = 0;
82 Pipes[i].rdata.offset = 0;
84 Pipes[i].max_rdata_len = 0;
85 Pipes[i].hdr_offsets = 0;
91 /****************************************************************************
92 find first available file slot
93 ****************************************************************************/
94 int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
97 /* we start at 1 here for an obscure reason I can't now remember,
98 but I think is important :-) */
99 for (i = 1; i < MAX_OPEN_PIPES; i++)
103 Pipes[i].open = True;
104 Pipes[i].device_state = 0;
105 Pipes[i].cnum = cnum;
108 Pipes[i].rhdr.data = NULL;
109 Pipes[i].rdata.data = NULL;
110 Pipes[i].rhdr.offset = 0;
111 Pipes[i].rdata.offset = 0;
113 Pipes[i].max_rdata_len = 0;
114 Pipes[i].hdr_offsets = 0;
116 fstrcpy(Pipes[i].name, pipe_name);
118 DEBUG(4,("Opened pipe %s with handle %x\n",
119 pipe_name, i + PIPE_HANDLE_OFFSET));
127 DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n"));
132 /****************************************************************************
133 reads data from a pipe.
135 headers are interspersed with the data at regular intervals. by the time
136 this function is called, the start of the data could possibly have been
137 read by an SMBtrans (max_rdata_len != 0).
139 calling create_rpc_request() here is a fudge. the data should already
140 have been prepared into arrays of headers + data stream sections.
142 ****************************************************************************/
143 int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
146 pipes_struct *p = &Pipes[pnum - PIPE_HANDLE_OFFSET];
147 DEBUG(6,("read_pipe: %x", pnum));
149 if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
151 DEBUG(6,("name: %s cnum: %d open: %s data_pos: %lx len: %lx",
158 if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET))
166 if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
167 p->rhdr.data->data_used == 0)
172 /* the read request starts from where the SMBtrans2 left off. */
173 data_pos += p->max_rdata_len;
175 /* headers accumulate an offset */
176 data_pos -= p->hdr_offsets;
178 len = mem_buf_len(p->rhdr.data);
179 num = len - (int)data_pos;
181 if (num > n) num = n;
183 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
185 rpc_frag_pos = data_pos % p->hdr.frag_len;
187 if (rpc_frag_pos == 0)
189 /* create and copy in a new header. */
190 create_rpc_reply(p, data_pos, p->rdata.offset);
191 mem_buf_copy(data, p->rhdr.data, 0, 0x18);
193 /* make room in data stream for header */
194 p->hdr_offsets += 0x18;
200 mem_buf_copy(data, p->rhdr.data, data_pos, num);
214 /****************************************************************************
215 gets the name of a pipe
216 ****************************************************************************/
217 BOOL get_rpc_pipe(int pnum, pipes_struct **p)
219 DEBUG(6,("get_rpc_pipe: "));
221 /* mapping is PIPE_HANDLE_OFFSET up... */
223 if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
225 DEBUG(6,("name: %s cnum: %d open: %s ",
226 Pipes[pnum - PIPE_HANDLE_OFFSET].name,
227 Pipes[pnum - PIPE_HANDLE_OFFSET].cnum,
228 BOOLSTR(Pipes[pnum - PIPE_HANDLE_OFFSET].open)));
230 if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET))
233 (*p) = &(Pipes[pnum - PIPE_HANDLE_OFFSET]);
243 /****************************************************************************
244 gets the name of a pipe
245 ****************************************************************************/
246 char *get_rpc_pipe_hnd_name(int pnum)
248 pipes_struct *p = NULL;
249 get_rpc_pipe(pnum, &p);
250 return p != NULL ? p->name : NULL;
253 /****************************************************************************
254 set device state on a pipe. exactly what this is for is unknown...
255 ****************************************************************************/
256 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
258 if (p == NULL) return False;
262 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s cnum=%d)\n",
263 timestring(), device_state, p->name, p->cnum));
265 p->device_state = device_state;
271 DEBUG(3,("%s Error setting pipe device state=%x (name=%s cnum=%d)\n",
272 timestring(), device_state, p->name, p->cnum));
277 /****************************************************************************
279 ****************************************************************************/
280 BOOL close_rpc_pipe_hnd(int pnum, int cnum)
282 pipes_struct *p = NULL;
283 get_rpc_pipe(pnum, &p);
284 /* mapping is PIPE_HANDLE_OFFSET up... */
286 if (p != NULL && P_OK(p, cnum))
288 DEBUG(3,("%s Closed pipe name %s pnum=%x cnum=%d\n",
289 timestring(),Pipes[pnum-PIPE_HANDLE_OFFSET].name, pnum,cnum));
295 mem_buf_free(&(p->rdata.data));
296 mem_buf_free(&(p->rhdr .data));
302 DEBUG(3,("%s Error closing pipe pnum=%x cnum=%d\n",
303 timestring(),pnum, cnum));
308 /****************************************************************************
310 ****************************************************************************/
311 int get_rpc_pipe_num(char *buf, int where)
313 return (chain_pnum != -1 ? chain_pnum : SVAL(buf,where));