]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From 9297af3ffd8a1c98f35fb7a273386576e061ff16 Mon Sep 17 00:00:00 2001 |
2 | From: Greg Kroah-Hartman <gregkh@suse.de> | |
3 | Date: Thu, 27 Mar 2008 10:40:48 -0700 | |
4 | Subject: novfs: Add the Novell filesystem client kernel module | |
5 | Patch-mainline: not yet, being worked on. | |
6 | ||
7 | This adds the Novell filesystem client kernel module. | |
8 | ||
9 | Things to do before it can be submitted: | |
10 | - coding style cleanups | |
11 | - remove typedefs | |
12 | - function name lowercase | |
13 | - 80 chars wide | |
14 | - sparse cleanups | |
15 | - __user markings | |
16 | - endian markings | |
17 | - remove functions that are never called and structures never used | |
18 | - yeah, there are a lot of them... | |
19 | - remove wrapper functions | |
20 | - private kmalloc/free? | |
21 | - resolve FIXME markings that have been added to the code | |
22 | - wrong types passed to functions!!! | |
23 | - userspace interface revisit | |
24 | - uses /proc/novfs, not nice. | |
25 | - might need userspace tools rework | |
26 | ||
27 | Cc: Lonnie Iverson <ldiverson@novell.com> | |
28 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
29 | ||
30 | --- | |
31 | fs/Kconfig | 9 | |
32 | fs/Makefile | 1 | |
33 | fs/novfs/Makefile | 19 | |
34 | fs/novfs/commands.h | 1087 ++++++++++ | |
35 | fs/novfs/daemon.c | 2400 ++++++++++++++++++++++ | |
36 | fs/novfs/file.c | 1964 ++++++++++++++++++ | |
37 | fs/novfs/inode.c | 5563 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
38 | fs/novfs/nwcapi.c | 2537 +++++++++++++++++++++++ | |
39 | fs/novfs/nwcapi.h | 2213 ++++++++++++++++++++ | |
40 | fs/novfs/nwerror.h | 658 ++++++ | |
41 | fs/novfs/proc.c | 152 + | |
42 | fs/novfs/profile.c | 687 ++++++ | |
43 | fs/novfs/scope.c | 675 ++++++ | |
44 | fs/novfs/vfs.h | 436 ++++ | |
45 | 14 files changed, 18401 insertions(+) | |
46 | ||
47 | --- a/fs/Kconfig | |
48 | +++ b/fs/Kconfig | |
49 | @@ -2123,6 +2123,15 @@ config 9P_FS | |
50 | ||
51 | If unsure, say N. | |
52 | ||
53 | +config NOVFS | |
54 | + tristate "Novell Netware Filesystem support (novfs) (EXPERIMENTAL)" | |
55 | + depends on INET && EXPERIMENTAL | |
56 | + help | |
57 | + If you say Y here, you will get an experimental Novell Netware | |
58 | + filesystem driver. | |
59 | + | |
60 | + If unsure, say N. | |
61 | + | |
62 | endif # NETWORK_FILESYSTEMS | |
63 | ||
64 | if BLOCK | |
65 | --- a/fs/Makefile | |
66 | +++ b/fs/Makefile | |
67 | @@ -125,3 +125,4 @@ obj-$(CONFIG_HPPFS) += hppfs/ | |
68 | obj-$(CONFIG_DEBUG_FS) += debugfs/ | |
69 | obj-$(CONFIG_OCFS2_FS) += ocfs2/ | |
70 | obj-$(CONFIG_GFS2_FS) += gfs2/ | |
71 | +obj-$(CONFIG_NOVFS) += novfs/ | |
72 | --- /dev/null | |
73 | +++ b/fs/novfs/Makefile | |
74 | @@ -0,0 +1,19 @@ | |
75 | +# | |
76 | +# Makefile for the Novell NetWare Client for Linux filesystem. | |
77 | +# | |
78 | + | |
79 | +NOVFS_VFS_MAJOR = 2 | |
80 | +NOVFS_VFS_MINOR = 0 | |
81 | +NOVFS_VFS_SUB = 0 | |
82 | +NOVFS_VFS_RELEASE = 440 | |
83 | + | |
84 | +EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR) | |
85 | +EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR) | |
86 | +EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB) | |
87 | +EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH) | |
88 | +EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE) | |
89 | + | |
90 | +obj-$(CONFIG_NOVFS) += novfs.o | |
91 | + | |
92 | +novfs-objs := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o | |
93 | + | |
94 | --- /dev/null | |
95 | +++ b/fs/novfs/commands.h | |
96 | @@ -0,0 +1,1087 @@ | |
97 | +/* | |
98 | + * NetWare Redirector for Linux | |
99 | + * Author: James Turner/Richard Williams | |
100 | + * | |
101 | + * This file contains all defined commands. | |
102 | + * | |
103 | + * Copyright (C) 2005 Novell, Inc. | |
104 | + * | |
105 | + * This program is free software; you can redistribute it and/or | |
106 | + * modify it under the terms of the GNU General Public License | |
107 | + * as published by the Free Software Foundation; either version 2 | |
108 | + * of the License, or (at your option) any later version. | |
109 | + */ | |
110 | + | |
111 | +#ifndef __NOVFS_COMMANDS_H | |
112 | +#define __NOVFS_COMMANDS_H | |
113 | + | |
114 | +#define VFS_COMMAND_GET_CONNECTED_SERVER_LIST 0 | |
115 | +#define VFS_COMMAND_GET_SERVER_VOLUME_LIST 1 | |
116 | +#define VFS_COMMAND_VERIFY_FILE 2 | |
117 | +#define VFS_COMMAND_OPEN_CONNECTION_BY_ADDR 3 | |
118 | +#define VFS_COMMAND_LOGIN_IDENTITY 4 | |
119 | +#define VFS_COMMAND_ENUMERATE_DIRECTORY 5 | |
120 | +#define VFS_COMMAND_OPEN_FILE 6 | |
121 | +#define VFS_COMMAND_CREATE_FILE 7 | |
122 | +#define VFS_COMMAND_CLOSE_FILE 8 | |
123 | +#define VFS_COMMAND_READ_FILE 9 | |
124 | +#define VFS_COMMAND_WRITE_FILE 10 | |
125 | +#define VFS_COMMAND_DELETE_FILE 11 | |
126 | +#define VFS_COMMAND_CREATE_DIRECOTRY 12 | |
127 | +#define VFS_COMMAND_START_ENUMERATE 13 | |
128 | +#define VFS_COMMAND_END_ENUMERATE 14 | |
129 | +#define VFS_COMMAND_LOGIN_USER 15 | |
130 | +#define VFS_COMMAND_LOGOUT_USER 16 | |
131 | +#define VFS_COMMAND_CREATE_CONTEXT 17 | |
132 | +#define VFS_COMMAND_DESTROY_CONTEXT 18 | |
133 | +#define VFS_COMMAND_SET_FILE_INFO 19 | |
134 | +#define VFS_COMMAND_TRUNCATE_FILE 20 | |
135 | +#define VFS_COMMAND_OPEN_CONNECTION_BY_NAME 21 | |
136 | +#define VFS_COMMAND_XPLAT_CALL 22 | |
137 | +#define VFS_COMMAND_RENAME_FILE 23 | |
138 | +#define VFS_COMMAND_ENUMERATE_DIRECTORY_EX 24 | |
139 | +#define VFS_COMMAND_GETPWUD 25 | |
140 | +#define VFS_COMMAND_ENUM_XCONN 26 | |
141 | +#define VFS_COMMAND_READ_STREAM 27 | |
142 | +#define VFS_COMMAND_WRITE_STREAM 28 | |
143 | +#define VFS_COMMAND_CLOSE_STREAM 29 | |
144 | +#define VFS_COMMAND_GET_VERSION 30 | |
145 | +#define VFS_COMMAND_SET_MOUNT_PATH 31 | |
146 | +#define VFS_COMMAND_GET_USER_SPACE 32 | |
147 | +#define VFS_COMMAND_DBG 33 | |
148 | +#define VFS_COMMAND_GET_CACHE_FLAG 34 | |
149 | +#define VFS_COMMAND_GET_EXTENDED_ATTRIBUTE 35 | |
150 | +#define VFS_COMMAND_LIST_EXTENDED_ATTRIBUTES 36 | |
151 | +#define VFS_COMMAND_SET_EXTENDED_ATTRIBUTE 37 | |
152 | +#define VFS_COMMAND_SET_FILE_LOCK 38 | |
153 | + | |
154 | +#define NWD_ACCESS_QUERY 0x00000001 | |
155 | +#define NWD_ACCESS_READ 0x00000002 | |
156 | +#define NWD_ACCESS_WRITE 0x00000004 | |
157 | +#define NWD_ACCESS_EXECUTE 0x00000008 | |
158 | +#define NWD_ACCESS_VALID 0x0000000F | |
159 | + | |
160 | +/* | |
161 | + Share Mode | |
162 | + | |
163 | + A value of zero in a shared mode field specifies the caller | |
164 | + desires exclusive access to the object. | |
165 | +*/ | |
166 | + | |
167 | +#define NWD_SHARE_READ 0x00000001 | |
168 | +#define NWD_SHARE_WRITE 0x00000002 | |
169 | +#define NWD_SHARE_DELETE 0x00000004 | |
170 | +#define NWD_SHARE_VALID 0x00000007 | |
171 | + | |
172 | +/* | |
173 | + Creates a new file. The create API will fail if the specified | |
174 | + file already exists. | |
175 | +*/ | |
176 | +#define NWD_DISP_CREATE_NEW 0x00000001 | |
177 | + | |
178 | +/* | |
179 | + Creates a new file. If the specified file already exists, | |
180 | + the create API will overwrite the old file and clear the | |
181 | + existing attributes. | |
182 | +*/ | |
183 | +#define NWD_DISP_CREATE_ALWAYS 0x00000002 | |
184 | + | |
185 | +/* | |
186 | + Opens the file. The API will fail if the file does not exist. | |
187 | +*/ | |
188 | +#define NWD_DISP_OPEN_EXISTING 0x00000003 | |
189 | + | |
190 | +/* | |
191 | + Opens the file. If the file does not exist, the API will | |
192 | + create the file. | |
193 | +*/ | |
194 | +#define NWD_DISP_OPEN_ALWAYS 0x00000004 | |
195 | + | |
196 | +/* | |
197 | + Opens the file. When the file is opened the API will truncate | |
198 | + the stream to zero bytes. The API will fail if the file | |
199 | + does not exist. | |
200 | +*/ | |
201 | +#define NWD_DISP_TRUNCATE_EXISTING 0x00000005 | |
202 | +#define NWD_DISP_MAXIMUM 0x00000005 | |
203 | + | |
204 | +/* | |
205 | + Open/Create returned information values | |
206 | + | |
207 | + The bottom two bytes of NWD_ACTION are returned | |
208 | + as a value. All values are mutually exclusive. | |
209 | +*/ | |
210 | + | |
211 | +#define NWD_ACTION_OPENED 0x00000001 | |
212 | +#define NWD_ACTION_CREATED 0x00000002 | |
213 | + | |
214 | +#define MAX_IO_SIZE (1024 * 32) | |
215 | + | |
216 | +#define MAX_XATTR_NAME_LEN 255 | |
217 | +#define MAX_PATH_LENGTH 255 | |
218 | +#define ENOATTR ENODATA | |
219 | +/*===[ Type definitions ]=================================================*/ | |
220 | + | |
221 | +/*===[ Function prototypes ]==============================================*/ | |
222 | + | |
223 | +#pragma pack(push, 1) | |
224 | + | |
225 | +#ifndef NWHANDLE | |
226 | +typedef void *NWHANDLE; | |
227 | +#endif | |
228 | + | |
229 | +/*typedef struct _ncl_string | |
230 | +{ | |
231 | + unsigned int type; | |
232 | + unsigned char *buffer; | |
233 | + unsigned int len; | |
234 | + | |
235 | +} NclString, *PNclString; | |
236 | +*/ | |
237 | +typedef struct _ncl_string { | |
238 | + unsigned int type; | |
239 | + unsigned char *buffer; | |
240 | + u32 len; | |
241 | + | |
242 | +} NclString, *PNclString; | |
243 | + | |
244 | +typedef struct _nwd_string { | |
245 | + unsigned int type; | |
246 | + unsigned int len; | |
247 | + unsigned int boffset; | |
248 | + | |
249 | +} NwdString, *PNwdString; | |
250 | + | |
251 | +typedef struct _COMMAND_REQUEST_HEADER { | |
252 | + unsigned int CommandType; | |
253 | + unsigned long SequenceNumber; | |
254 | + struct schandle SessionId; | |
255 | +} COMMAND_REQUEST_HEADER, *PCOMMAND_REQUEST_HEADER; | |
256 | + | |
257 | +typedef struct _COMMAND_REPLY_HEADER { | |
258 | + unsigned long Sequence_Number; | |
259 | + unsigned int ErrorCode; | |
260 | + | |
261 | +} COMMAND_REPLY_HEADER, *PCOMMAND_REPLY_HEADER; | |
262 | + | |
263 | +typedef struct _CLOSE_REQUEST { | |
264 | + COMMAND_REQUEST_HEADER Command; | |
265 | + NWHANDLE FileHandle; | |
266 | +} CLOSE_REQUEST, *PCLOSE_REQUEST; | |
267 | + | |
268 | +typedef struct _CLOSE_REPLY { | |
269 | + COMMAND_REPLY_HEADER Reply; | |
270 | +} CLOSE_REPLY, *PCLOSE_REPLY; | |
271 | + | |
272 | +typedef struct _DELETE_FILE_REQUEST { | |
273 | + COMMAND_REQUEST_HEADER Command; | |
274 | + unsigned int isDirectory; | |
275 | + unsigned int pathlength; | |
276 | + unsigned char path[1]; | |
277 | +} DELETE_FILE_REQUEST, *PDELETE_FILE_REQUEST; | |
278 | + | |
279 | +typedef struct _DELETE_FILE_REPLY { | |
280 | + COMMAND_REPLY_HEADER Reply; | |
281 | +} DELETE_FILE_REPLY, *PDELETE_FILE_REPLY; | |
282 | + | |
283 | +typedef struct _FLUSH_REQUEST { | |
284 | + COMMAND_REQUEST_HEADER Command; | |
285 | + NWHANDLE FileHandle; | |
286 | +} FLUSH_REQUEST, *PFLUSH_REQUEST; | |
287 | + | |
288 | +typedef struct _FLUSH_REPLY { | |
289 | + COMMAND_REPLY_HEADER Reply; | |
290 | +} FLUSH_REPLY, *PFLUSH_REPLY; | |
291 | + | |
292 | +typedef struct _GET_FILEINFO_REQUEST { | |
293 | + COMMAND_REQUEST_HEADER Command; | |
294 | + NWHANDLE FileHandle; | |
295 | +} GET_FILEINFO_REQUEST, *PGET_FILEINFO_REQUEST; | |
296 | + | |
297 | +typedef struct _GET_FILEINFO_REPLY { | |
298 | + COMMAND_REPLY_HEADER Reply; | |
299 | +} GET_FILEINFO_REPLY, *PGET_FILEINFO_REPLY; | |
300 | + | |
301 | +typedef struct _GET_CONNECTED_SERVER_LIST_REQUEST { | |
302 | + COMMAND_REQUEST_HEADER Command; | |
303 | +} GET_CONNECTED_SERVER_LIST_REQUEST, *PGET_CONNECTED_SERVER_LIST_REQUEST; | |
304 | + | |
305 | +typedef struct _GET_CONNECTED_SERVER_LIST_REPLY { | |
306 | + COMMAND_REPLY_HEADER Reply; | |
307 | + unsigned char List[1]; | |
308 | +} GET_CONNECTED_SERVER_LIST_REPLY, *PGET_CONNECTED_SERVER_LIST_REPLY; | |
309 | + | |
310 | +typedef struct _GET_CONNECTED_SERVER_LIST_REQUEST_EX { | |
311 | + COMMAND_REQUEST_HEADER Command; | |
312 | +} GET_CONNECTED_SERVER_LIST_REQUEST_EX, *PGET_CONNECTED_SERVER_LIST_REQUEST_EX; | |
313 | + | |
314 | +typedef struct _GET_CONNECTED_SERVER_LIST_REPLY_EX { | |
315 | + COMMAND_REPLY_HEADER Reply; | |
316 | + unsigned int bufferLen; | |
317 | + unsigned char List[1]; | |
318 | + | |
319 | +} GET_CONNECTED_SERVER_LIST_REPLY_EX, *PGET_CONNECTED_SERVER_LIST_REPLY_EX; | |
320 | + | |
321 | +typedef struct _GET_SERVER_VOLUME_LIST_REQUEST { | |
322 | + COMMAND_REQUEST_HEADER Command; | |
323 | + unsigned int Length; | |
324 | + unsigned char Name[1]; | |
325 | +} GET_SERVER_VOLUME_LIST_REQUEST, *PGET_SERVER_VOLUME_LIST_REQUEST; | |
326 | + | |
327 | +typedef struct _GET_SERVER_VOLUME_LIST_REPLY { | |
328 | + COMMAND_REPLY_HEADER Reply; | |
329 | + unsigned char List[1]; | |
330 | +} GET_SERVER_VOLUME_LIST_REPLY, *PGET_SERVER_VOLUME_LIST_REPLY; | |
331 | + | |
332 | +typedef struct _OPEN_CONNECTION_BY_ADDR_REQUEST { | |
333 | + COMMAND_REQUEST_HEADER Command; | |
334 | + unsigned int address; | |
335 | + | |
336 | +} OPEN_CONNECTION_BY_ADDR_REQUEST, *POPEN_CONNECTION_BY_ADDR_REQUEST; | |
337 | + | |
338 | +typedef struct _OPEN_CONNECTION_BY_ADDR_REPLY { | |
339 | + COMMAND_REPLY_HEADER Reply; | |
340 | + unsigned char serverName[64]; | |
341 | + unsigned char treeName[64]; | |
342 | + NWHANDLE connHandle; | |
343 | + | |
344 | +} OPEN_CONNECTION_BY_ADDR_REPLY, *POPEN_CONNECTION_BY_ADDR_REPLY; | |
345 | + | |
346 | +typedef struct _OPEN_CONNECTION_BY_NAME_REQUEST { | |
347 | + COMMAND_REQUEST_HEADER Command; | |
348 | + unsigned int NameLen; | |
349 | + unsigned char Name[1]; | |
350 | + | |
351 | +} OPEN_CONNECTION_BY_NAME_REQUEST, *POPEN_CONNECTION_BY_NAME_REQUEST; | |
352 | + | |
353 | +typedef struct _OPEN_CONNECTION_BY_NAME_REPLY { | |
354 | + COMMAND_REPLY_HEADER Reply; | |
355 | + unsigned char treeName[64]; | |
356 | + NWHANDLE connHandle; | |
357 | + | |
358 | +} OPEN_CONNECTION_BY_NAME_REPLY, *POPEN_CONNECTION_BY_NAME_REPLY; | |
359 | + | |
360 | +/* | |
361 | +typedef struct _LOGIN_IDENTITY_REQUEST | |
362 | +{ | |
363 | + COMMAND_REQUEST_HEADER Command; | |
364 | + unsigned int treeFlags; | |
365 | + unsigned char treeName[64]; | |
366 | + unsigned int serverFlags; | |
367 | + unsigned char serverName[64]; | |
368 | + unsigned int userFlags; | |
369 | + unsigned char userName[512]; | |
370 | + unsigned int passwordFlags; | |
371 | + unsigned char password[128]; | |
372 | + | |
373 | +} LOGIN_IDENTITY_REQUEST, *PLOGIN_IDENTITY_REQUEST; | |
374 | + | |
375 | +typedef struct _LOGIN_IDENTITY_REPLY | |
376 | +{ | |
377 | + COMMAND_REPLY_HEADER Reply; | |
378 | + unsigned char serverName[64]; | |
379 | + unsigned char treeName[64]; | |
380 | + NWHANDLE connHandle; | |
381 | + | |
382 | +} LOGIN_IDENTITY_REPLY, *PLOGIN_IDENTITY_REPLY; | |
383 | +*/ | |
384 | + | |
385 | +typedef struct _VERIFY_FILE_REQUEST { | |
386 | + COMMAND_REQUEST_HEADER Command; | |
387 | + unsigned int pathLen; | |
388 | + unsigned char path[1]; | |
389 | + | |
390 | +} VERIFY_FILE_REQUEST, *PVERIFY_FILE_REQUEST; | |
391 | + | |
392 | +typedef struct _VERIFY_FILE_REPLY { | |
393 | + COMMAND_REPLY_HEADER Reply; | |
394 | + unsigned int lastAccessTime; | |
395 | + unsigned int modifyTime; | |
396 | + unsigned int createTime; | |
397 | + unsigned long long fileSize; | |
398 | + unsigned int fileMode; | |
399 | + | |
400 | +} VERIFY_FILE_REPLY, *PVERIFY_FILE_REPLY; | |
401 | + | |
402 | +typedef struct _BEGIN_ENUMERATE_DIRECTORY_REQUEST { | |
403 | + COMMAND_REQUEST_HEADER Command; | |
404 | + unsigned int pathLen; | |
405 | + unsigned char path[1]; | |
406 | + | |
407 | +} BEGIN_ENUMERATE_DIRECTORY_REQUEST, *PBEGIN_ENUMERATE_DIRECTORY_REQUEST; | |
408 | + | |
409 | +typedef struct _BEGIN_ENUMERATE_DIRECTORY_REPLY { | |
410 | + COMMAND_REPLY_HEADER Reply; | |
411 | + HANDLE enumerateHandle; | |
412 | + | |
413 | +} BEGIN_ENUMERATE_DIRECTORY_REPLY, *PBEGIN_ENUMERATE_DIRECTORY_REPLY; | |
414 | + | |
415 | +typedef struct _END_ENUMERATE_DIRECTORY_REQUEST { | |
416 | + COMMAND_REQUEST_HEADER Command; | |
417 | + HANDLE enumerateHandle; | |
418 | + | |
419 | +} END_ENUMERATE_DIRECTORY_REQUEST, *PEND_ENUMERATE_DIRECTORY_REQUEST; | |
420 | + | |
421 | +typedef struct _END_ENUMERATE_DIRECTORY_REPLY { | |
422 | + COMMAND_REPLY_HEADER Reply; | |
423 | + | |
424 | +} END_ENUMERATE_DIRECTORY_REPLY, *PEND_ENUMERATE_DIRECTORY_REPLY; | |
425 | + | |
426 | +typedef struct _ENUMERATE_DIRECTORY_REQUEST { | |
427 | + COMMAND_REQUEST_HEADER Command; | |
428 | + HANDLE enumerateHandle; | |
429 | + unsigned int pathLen; | |
430 | + unsigned char path[1]; | |
431 | + | |
432 | +} ENUMERATE_DIRECTORY_REQUEST, *PENUMERATE_DIRECTORY_REQUEST; | |
433 | + | |
434 | +typedef struct _ENUMERATE_DIRECTORY_REPLY { | |
435 | + COMMAND_REPLY_HEADER Reply; | |
436 | + HANDLE enumerateHandle; | |
437 | + unsigned int lastAccessTime; | |
438 | + unsigned int modifyTime; | |
439 | + unsigned int createTime; | |
440 | + unsigned long long size; | |
441 | + unsigned int mode; | |
442 | + unsigned int nameLen; | |
443 | + unsigned char name[1]; | |
444 | + | |
445 | +} ENUMERATE_DIRECTORY_REPLY, *PENUMERATE_DIRECTORY_REPLY; | |
446 | + | |
447 | +typedef struct _ENUMERATE_DIRECTORY_EX_REQUEST { | |
448 | + COMMAND_REQUEST_HEADER Command; | |
449 | + HANDLE enumerateHandle; | |
450 | + unsigned int pathLen; | |
451 | + unsigned char path[1]; | |
452 | + | |
453 | +} ENUMERATE_DIRECTORY_EX_REQUEST, *PENUMERATE_DIRECTORY_EX_REQUEST; | |
454 | + | |
455 | +typedef struct _ENUMERATE_DIRECTORY_EX_DATA { | |
456 | + unsigned int length; | |
457 | + unsigned int lastAccessTime; | |
458 | + unsigned int modifyTime; | |
459 | + unsigned int createTime; | |
460 | + unsigned long long size; | |
461 | + unsigned int mode; | |
462 | + unsigned int nameLen; | |
463 | + unsigned char name[1]; | |
464 | + | |
465 | +} ENUMERATE_DIRECTORY_EX_DATA, *PENUMERATE_DIRECTORY_EX_DATA; | |
466 | + | |
467 | +typedef struct _ENUMERATE_DIRECTORY_EX_REPLY { | |
468 | + COMMAND_REPLY_HEADER Reply; | |
469 | + HANDLE enumerateHandle; | |
470 | + unsigned int enumCount; | |
471 | + | |
472 | +} ENUMERATE_DIRECTORY_EX_REPLY, *PENUMERATE_DIRECTORY_EX_REPLY; | |
473 | + | |
474 | +typedef struct _OPEN_FILE_REQUEST { | |
475 | + COMMAND_REQUEST_HEADER Command; | |
476 | + unsigned int access; /* File Access */ | |
477 | + unsigned int mode; /* Sharing Mode */ | |
478 | + unsigned int disp; /* Create Disposition */ | |
479 | + unsigned int pathLen; | |
480 | + unsigned char path[1]; | |
481 | + | |
482 | +} OPEN_FILE_REQUEST, *POPEN_FILE_REQUEST; | |
483 | + | |
484 | +typedef struct _OPEN_FILE_REPLY { | |
485 | + COMMAND_REPLY_HEADER Reply; | |
486 | + HANDLE handle; | |
487 | + unsigned int lastAccessTime; | |
488 | + unsigned int modifyTime; | |
489 | + unsigned int createTime; | |
490 | + unsigned int attributes; | |
491 | + loff_t size; | |
492 | + | |
493 | +} OPEN_FILE_REPLY, *POPEN_FILE_REPLY; | |
494 | + | |
495 | +typedef struct _CREATE_FILE_REQUEST { | |
496 | + | |
497 | + COMMAND_REQUEST_HEADER Command; | |
498 | + unsigned int pathlength; | |
499 | + unsigned char path[1]; | |
500 | + | |
501 | +} CREATE_FILE_REQUEST, *PCREATE_FILE_REQUEST; | |
502 | + | |
503 | +typedef struct _CREATE_FILE_REPLY { | |
504 | + COMMAND_REPLY_HEADER Reply; | |
505 | + | |
506 | +} CREATE_FILE_REPLY, *PCREATE_FILE_REPLY; | |
507 | + | |
508 | +typedef struct _CLOSE_FILE_REQUEST { | |
509 | + COMMAND_REQUEST_HEADER Command; | |
510 | + HANDLE handle; | |
511 | + | |
512 | +} CLOSE_FILE_REQUEST, *PCLOSE_FILE_REQUEST; | |
513 | + | |
514 | +typedef struct _CLOSE_FILE_REPLY { | |
515 | + COMMAND_REPLY_HEADER Reply; | |
516 | + | |
517 | +} CLOSE_FILE_REPLY, *PCLOSE_FILE_REPLY; | |
518 | + | |
519 | +typedef struct _READ_FILE_REQUEST { | |
520 | + COMMAND_REQUEST_HEADER Command; | |
521 | + HANDLE handle; | |
522 | + loff_t offset; | |
523 | + size_t len; | |
524 | + | |
525 | +} READ_FILE_REQUEST, *PREAD_FILE_REQUEST; | |
526 | + | |
527 | +typedef struct _READ_FILE_REPLY { | |
528 | + COMMAND_REPLY_HEADER Reply; | |
529 | + unsigned long long bytesRead; | |
530 | + unsigned char data[1]; | |
531 | + | |
532 | +} READ_FILE_REPLY, *PREAD_FILE_REPLY; | |
533 | + | |
534 | +typedef struct _WRITE_FILE_REQUEST { | |
535 | + COMMAND_REQUEST_HEADER Command; | |
536 | + HANDLE handle; | |
537 | + loff_t offset; | |
538 | + size_t len; | |
539 | + unsigned char data[1]; | |
540 | + | |
541 | +} WRITE_FILE_REQUEST, *PWRITE_FILE_REQUEST; | |
542 | + | |
543 | +typedef struct _WRITE_FILE_REPLY { | |
544 | + COMMAND_REPLY_HEADER Reply; | |
545 | + unsigned long long bytesWritten; | |
546 | +} WRITE_FILE_REPLY, *PWRITE_FILE_REPLY; | |
547 | + | |
548 | +typedef struct _READ_STREAM_REQUEST { | |
549 | + COMMAND_REQUEST_HEADER Command; | |
550 | + HANDLE connection; | |
551 | + unsigned char handle[6]; | |
552 | + loff_t offset; | |
553 | + size_t len; | |
554 | +} READ_STREAM_REQUEST, *PREAD_STREAM_REQUEST; | |
555 | + | |
556 | +typedef struct _READ_STREAM_REPLY { | |
557 | + COMMAND_REPLY_HEADER Reply; | |
558 | + size_t bytesRead; | |
559 | + unsigned char data[1]; | |
560 | +} READ_STREAM_REPLY, *PREAD_STREAM_REPLY; | |
561 | + | |
562 | +typedef struct _WRITE_STREAM_REQUEST { | |
563 | + COMMAND_REQUEST_HEADER Command; | |
564 | + HANDLE connection; | |
565 | + unsigned char handle[6]; | |
566 | + loff_t offset; | |
567 | + size_t len; | |
568 | + unsigned char data[1]; | |
569 | +} WRITE_STREAM_REQUEST, *PWRITE_STREAM_REQUEST; | |
570 | + | |
571 | +typedef struct _WRITE_STREAM_REPLY { | |
572 | + COMMAND_REPLY_HEADER Reply; | |
573 | + size_t bytesWritten; | |
574 | +} WRITE_STREAM_REPLY, *PWRITE_STREAM_REPLY; | |
575 | + | |
576 | +typedef struct _CLOSE_STREAM_REQUEST { | |
577 | + COMMAND_REQUEST_HEADER Command; | |
578 | + HANDLE connection; | |
579 | + unsigned char handle[6]; | |
580 | +} CLOSE_STREAM_REQUEST, *PCLOSE_STREAM_REQUEST; | |
581 | + | |
582 | +typedef struct _CLOSE_STREAM_REPLY { | |
583 | + COMMAND_REPLY_HEADER Reply; | |
584 | + | |
585 | +} CLOSE_STREAM_REPLY, *PCLOSE_STREAM_REPLY; | |
586 | + | |
587 | +typedef struct _CREATE_DIRECTORY_REQUEST { | |
588 | + | |
589 | + COMMAND_REQUEST_HEADER Command; | |
590 | + unsigned int pathlength; | |
591 | + unsigned char path[1]; | |
592 | + | |
593 | +} CREATE_DIRECTORY_REQUEST, *PCREATE_DIRECTORY_REQUEST; | |
594 | + | |
595 | +typedef struct _CREATE_DIRECTORY_REPLY { | |
596 | + COMMAND_REPLY_HEADER Reply; | |
597 | + | |
598 | +} CREATE_DIRECTORY_REPLY, *PCREATE_DIRECTORY_REPLY; | |
599 | + | |
600 | +typedef struct _LOGIN_USER_REQUEST { | |
601 | + COMMAND_REQUEST_HEADER Command; | |
602 | + unsigned int srvNameType; | |
603 | + unsigned int serverLength; | |
604 | + unsigned int serverOffset; | |
605 | + unsigned int usrNameType; | |
606 | + unsigned int userNameLength; | |
607 | + unsigned int userNameOffset; | |
608 | + unsigned int pwdNameType; | |
609 | + unsigned int passwordLength; | |
610 | + unsigned int passwordOffset; | |
611 | + | |
612 | +} LOGIN_USER_REQUEST, *PLOGIN_USER_REQUEST; | |
613 | + | |
614 | +typedef struct _LOGIN_USER_REPLY { | |
615 | + COMMAND_REPLY_HEADER Reply; | |
616 | + unsigned int connectionHandle; | |
617 | + HANDLE loginIdentity; | |
618 | + | |
619 | +} LOGIN_USER_REPLY, *PLOGIN_USER_REPLY; | |
620 | + | |
621 | +typedef struct _LOGOUT_REQUEST { | |
622 | + COMMAND_REQUEST_HEADER Command; | |
623 | + unsigned int length; | |
624 | + unsigned char Name[1]; | |
625 | + | |
626 | +} LOGOUT_REQUEST, *PLOGOUT_REQUEST; | |
627 | + | |
628 | +typedef struct _LOGOUT_REPLY { | |
629 | + COMMAND_REPLY_HEADER Reply; | |
630 | + | |
631 | +} LOGOUT_REPLY, *PLOGOUT_REPLY; | |
632 | + | |
633 | +typedef struct _CREATE_CONTEXT_REQUEST { | |
634 | + COMMAND_REQUEST_HEADER Command; | |
635 | + | |
636 | +} CREATE_CONTEXT_REQUEST, *PCREATE_CONTEXT_REQUEST; | |
637 | + | |
638 | +typedef struct _CREATE_CONTEXT_REPLY { | |
639 | + COMMAND_REPLY_HEADER Reply; | |
640 | + struct schandle SessionId; | |
641 | +} CREATE_CONTEXT_REPLY, *PCREATE_CONTEXT_REPLY; | |
642 | + | |
643 | +typedef struct _DESTROY_CONTEXT_REQUEST { | |
644 | + COMMAND_REQUEST_HEADER Command; | |
645 | + | |
646 | +} DESTROY_CONTEXT_REQUEST, *PDESTROY_CONTEXT_REQUEST; | |
647 | + | |
648 | +typedef struct _DESTROY_CONTEXT_REPLY { | |
649 | + COMMAND_REPLY_HEADER Reply; | |
650 | + | |
651 | +} DESTROY_CONTEXT_REPLY, *PDESTROY_CONTEXT_REPLY; | |
652 | + | |
653 | +/* | |
654 | + * Attribute flags. These should be or-ed together to figure out what | |
655 | + * has been changed! | |
656 | + */ | |
657 | +#ifndef ATTR_MODE | |
658 | +#define ATTR_MODE 1 | |
659 | +#define ATTR_UID 2 | |
660 | +#define ATTR_GID 4 | |
661 | +#define ATTR_SIZE 8 | |
662 | +#define ATTR_ATIME 16 | |
663 | +#define ATTR_MTIME 32 | |
664 | +#define ATTR_CTIME 64 | |
665 | +#define ATTR_ATIME_SET 128 | |
666 | +#define ATTR_MTIME_SET 256 | |
667 | +#define ATTR_FORCE 512 /* Not a change, but a change it */ | |
668 | +#define ATTR_ATTR_FLAG 1024 | |
669 | +#endif | |
670 | + | |
671 | +typedef struct _LNX_FILE_INFO { | |
672 | + unsigned int ia_valid; | |
673 | + unsigned int ia_mode; | |
674 | + uid_t ia_uid; | |
675 | + gid_t ia_gid; | |
676 | + loff_t ia_size; | |
677 | + time_t ia_atime; | |
678 | + time_t ia_mtime; | |
679 | + time_t ia_ctime; | |
680 | + unsigned int ia_attr_flags; | |
681 | + | |
682 | +} LX_FILE_INFO, *PLX_FILE_INFO; | |
683 | + | |
684 | +typedef struct _SET_FILE_INFO_REQUEST { | |
685 | + COMMAND_REQUEST_HEADER Command; | |
686 | + LX_FILE_INFO fileInfo; | |
687 | + unsigned int pathlength; | |
688 | + char path[1]; | |
689 | + | |
690 | +} SET_FILE_INFO_REQUEST, *PSET_FILE_INFO_REQUEST; | |
691 | + | |
692 | +typedef struct _SET_FILE_INFO_REPLY { | |
693 | + COMMAND_REPLY_HEADER Reply; | |
694 | + | |
695 | +} SET_FILE_INFO_REPLY, *PSET_FILE_INFO_REPLY; | |
696 | + | |
697 | +typedef struct _TRUNCATE_FILE_REQUEST { | |
698 | + COMMAND_REQUEST_HEADER Command; | |
699 | + unsigned int pathLen; | |
700 | + char path[1]; | |
701 | + | |
702 | +} TRUNCATE_FILE_REQUEST, *PTRUNCATE_FILE_REQUEST; | |
703 | + | |
704 | +typedef struct _TRUNCATE_FILE_REPLY { | |
705 | + COMMAND_REPLY_HEADER Reply; | |
706 | + | |
707 | +} TRUNCATE_FILE_REPLY, *PTRUNCATE_FILE_REPLY; | |
708 | + | |
709 | +typedef struct _GETPWUID_REQUEST { | |
710 | + COMMAND_REQUEST_HEADER Command; | |
711 | + unsigned int uid; | |
712 | +} GETPWUID_REQUEST, *PGETPWUID_REQUEST; | |
713 | + | |
714 | +typedef struct _GETPWUID_REPLY { | |
715 | + COMMAND_REPLY_HEADER Reply; | |
716 | + unsigned char UserName[1]; | |
717 | +} GETPWUID_REPLY, *PGETPWUID_REPLY; | |
718 | + | |
719 | +typedef struct _GET_VERSION_REQUEST { | |
720 | + COMMAND_REQUEST_HEADER Command; | |
721 | +} GET_VERSION_REQUEST, *PGET_VERSION_REQUEST; | |
722 | + | |
723 | +typedef struct _GET_VERSION_REPLY { | |
724 | + COMMAND_REPLY_HEADER Reply; | |
725 | + unsigned char Version[1]; | |
726 | +} GET_VERSION_REPLY, *PGET_VERSION_REPLY; | |
727 | + | |
728 | +typedef struct _SET_MOUNT_PATH { | |
729 | + COMMAND_REQUEST_HEADER Command; | |
730 | + unsigned int PathLength; | |
731 | + unsigned char Path[1]; | |
732 | +} SET_MOUNT_PATH_REQUEST, *PSET_MOUNT_PATH_REQUEST; | |
733 | + | |
734 | +typedef struct _SET_MOUNT_PATH_REPLY { | |
735 | + COMMAND_REPLY_HEADER Reply; | |
736 | +} SET_MOUNT_PATH, *PSET_MOUNT_PATH_REPLY; | |
737 | + | |
738 | +typedef struct _GET_USER_SPACE { | |
739 | + COMMAND_REQUEST_HEADER Command; | |
740 | +} GET_USER_SPACE_REQUEST, *PGET_USER_SPACE_REQUEST; | |
741 | + | |
742 | +typedef struct _GET_USER_SPACE_REPLY { | |
743 | + COMMAND_REPLY_HEADER Reply; | |
744 | + uint64_t TotalSpace; | |
745 | + uint64_t FreeSpace; | |
746 | + uint64_t TotalEnties; | |
747 | + uint64_t FreeEnties; | |
748 | +} GET_USER_SPACE_REPLY, *PGET_USER_SPACE_REPLY; | |
749 | + | |
750 | +typedef struct _XPLAT_CALL_REQUEST { | |
751 | + COMMAND_REQUEST_HEADER Command; | |
752 | + unsigned int NwcCommand; | |
753 | + unsigned long dataLen; | |
754 | + unsigned char data[1]; | |
755 | + | |
756 | +} XPLAT_CALL_REQUEST, *PXPLAT_CALL_REQUEST; | |
757 | + | |
758 | +typedef struct _XPLAT_CALL_REPLY { | |
759 | + COMMAND_REPLY_HEADER Reply; | |
760 | + unsigned long dataLen; | |
761 | + unsigned char data[1]; | |
762 | + | |
763 | +} XPLAT_CALL_REPLY, *PXPLAT_CALL_REPLY; | |
764 | + | |
765 | +/* XPlat NWC structures used by the daemon */ | |
766 | + | |
767 | +typedef struct _NWD_OPEN_CONN_BY_NAME { | |
768 | + HANDLE ConnHandle; | |
769 | + unsigned int nameLen; | |
770 | + unsigned int oName; /* Ofset to the Name */ | |
771 | + unsigned int serviceLen; | |
772 | + unsigned int oServiceType; /* Offset to service Type; */ | |
773 | + unsigned int uConnFlags; | |
774 | + unsigned int uTranType; | |
775 | + HANDLE newConnHandle; | |
776 | + | |
777 | +} NwdCOpenConnByName, *PNwdCOpenConnByName; | |
778 | + | |
779 | +typedef struct _NWD_TRAN_ADDR { | |
780 | + unsigned int uTransportType; | |
781 | + unsigned int uAddressLength; | |
782 | + unsigned int oAddress; | |
783 | + | |
784 | +} NwdCTranAddr, *PNwdCTranAddr; | |
785 | + | |
786 | +typedef struct _NWD_OPEN_CONN_BY_ADDR { | |
787 | + HANDLE ConnHandle; | |
788 | + unsigned int oServiceType; | |
789 | + unsigned int uConnFlags; | |
790 | + NwdCTranAddr TranAddr; | |
791 | + | |
792 | +} NwdCOpenConnByAddr, *PNwdCOpenConnByAddr; | |
793 | + | |
794 | +typedef struct _NWD_CLOSE_CONN { | |
795 | + HANDLE ConnHandle; | |
796 | + | |
797 | +} NwdCCloseConn, *PNwdCCloseConn; | |
798 | + | |
799 | +typedef struct _NWD_NCP_REQ { | |
800 | + HANDLE ConnHandle; | |
801 | + unsigned int replyLen; | |
802 | + unsigned int requestLen; | |
803 | + unsigned int function; | |
804 | +/* unsigned int subFunction; */ | |
805 | +/* unsigned int verb; */ | |
806 | + unsigned int flags; | |
807 | + unsigned char data[1]; | |
808 | + | |
809 | +} NwdCNCPReq, *PNwdCNCPReq; | |
810 | + | |
811 | +typedef struct _NWD_NCP_REP { | |
812 | + unsigned int replyLen; | |
813 | + unsigned char data[1]; | |
814 | + | |
815 | +} NwdCNCPRep, *PNwdCNCPRep; | |
816 | + | |
817 | +typedef struct _NWC_AUTH_WID { | |
818 | + HANDLE ConnHandle; | |
819 | + u32 AuthenticationId; | |
820 | + | |
821 | +} NwdCAuthenticateWithId, *PNwdCAuthenticateWithId; | |
822 | + | |
823 | +typedef struct _NWC_AUTHENTICATE { | |
824 | + HANDLE ConnHandle; | |
825 | + unsigned int uAuthenticationType; | |
826 | + unsigned int userNameOffset; | |
827 | + unsigned int passwordOffset; | |
828 | + unsigned int MaxInfoLength; | |
829 | + unsigned int InfoLength; | |
830 | + unsigned int authenInfoOffset; | |
831 | + | |
832 | +} NwdCAuthenticate, *PNwdCAuthenticate; | |
833 | + | |
834 | +typedef struct _NWC_UNAUTHENTICATE { | |
835 | + HANDLE ConnHandle; | |
836 | + unsigned int AuthenticationId; | |
837 | + | |
838 | +} NwdCUnauthenticate, *PNwdCUnauthenticate; | |
839 | + | |
840 | +typedef struct _NWC_LISC_ID { | |
841 | + HANDLE ConnHandle; | |
842 | + | |
843 | +} NwdCLicenseConn, *PNwdCLicenseConn; | |
844 | + | |
845 | +typedef struct _NWC_UNLIC_CONN { | |
846 | + HANDLE ConnHandle; | |
847 | + | |
848 | +} NwdCUnlicenseConn, *PNwdCUnlicenseConn; | |
849 | + | |
850 | +typedef struct _NWC_GET_IDENT_INFO { | |
851 | + u32 AuthenticationId; | |
852 | + unsigned int AuthType; | |
853 | + unsigned int NameType; | |
854 | + unsigned short int ObjectType; | |
855 | + unsigned int IdentityFlags; | |
856 | + unsigned int domainLen; | |
857 | + unsigned int pDomainNameOffset; | |
858 | + unsigned int objectLen; | |
859 | + unsigned int pObjectNameOffset; | |
860 | + | |
861 | +} NwdCGetIdentityInfo, *PNwdCGetIdentityInfo; | |
862 | + | |
863 | +typedef struct _NWC_LO_ID { | |
864 | + u32 AuthenticationId; | |
865 | + | |
866 | +} NwdCLogoutIdentity, *PNwdCLogoutIdentity; | |
867 | + | |
868 | +typedef struct _RENAME_FILE_REQUEST { | |
869 | + COMMAND_REQUEST_HEADER Command; | |
870 | + int directoryFlag; | |
871 | + unsigned int newnameLen; | |
872 | + unsigned char newname[256]; | |
873 | + unsigned int oldnameLen; | |
874 | + unsigned char oldname[256]; | |
875 | +} RENAME_FILE_REQUEST, *PRENAME_FILE_REQUEST; | |
876 | + | |
877 | +typedef struct _RENAME_FILE_REPLY { | |
878 | + COMMAND_REPLY_HEADER Reply; | |
879 | + | |
880 | +} RENAME_FILE_REPLY, *PRENAME_FILE_REPLY; | |
881 | + | |
882 | +typedef struct __NwdServerVersion { | |
883 | + unsigned int uMajorVersion; | |
884 | + unsigned short int uMinorVersion; | |
885 | + unsigned short int uRevision; | |
886 | + | |
887 | +} NwdServerVersion, *PNwdServerVersion; | |
888 | + | |
889 | +#define MAX_ADDRESS_LENGTH 32 | |
890 | + | |
891 | +typedef struct tagNwdTranAddrEx { | |
892 | + unsigned int uTransportType; | |
893 | + unsigned int uAddressLength; | |
894 | + unsigned char Buffer[MAX_ADDRESS_LENGTH]; | |
895 | + | |
896 | +} NwdTranAddr, *PNwdTranAddr; | |
897 | + | |
898 | +typedef struct __NWD_CONN_INFO { | |
899 | + unsigned int uInfoVersion; | |
900 | + unsigned int uAuthenticationState; | |
901 | + unsigned int uBroadcastState; | |
902 | + u32 uConnectionReference; | |
903 | + unsigned int pTreeNameOffset; | |
904 | +/* unsigned int pWorkGroupIdOffset; Not used */ | |
905 | + unsigned int uSecurityState; | |
906 | + unsigned int uConnectionNumber; | |
907 | + unsigned int uUserId; | |
908 | + unsigned int pServerNameOffset; | |
909 | + unsigned int uNdsState; | |
910 | + unsigned int uMaxPacketSize; | |
911 | + unsigned int uLicenseState; | |
912 | + unsigned int uPublicState; | |
913 | + unsigned int bcastState; | |
914 | + unsigned int pServiceTypeOffset; | |
915 | + unsigned int uDistance; | |
916 | + u32 uAuthId; | |
917 | + unsigned int uDisconnected; | |
918 | + NwdServerVersion ServerVersion; | |
919 | + NwdTranAddr TranAddress; | |
920 | + | |
921 | +} NwdConnInfo, *PNwdConnInfo; | |
922 | + | |
923 | +typedef struct _nwd_conn_info { | |
924 | + HANDLE ConnHandle; | |
925 | + unsigned int uInfoLevel; | |
926 | + unsigned int uInfoLength; | |
927 | + | |
928 | +} NwdCGetConnInfo, *PNwdCGetConnInfo; | |
929 | + | |
930 | +typedef struct nwd_open_conn_by_Ref { | |
931 | + HANDLE uConnReference; | |
932 | + unsigned int uConnFlags; | |
933 | + HANDLE ConnHandle; | |
934 | + | |
935 | +} NwdCOpenConnByRef, *PNwdCOpenConnByRef; | |
936 | + | |
937 | +typedef struct nwd_get_reqversion { | |
938 | + unsigned int uMajorVersion; | |
939 | + unsigned int uMinorVersion; | |
940 | + unsigned int uRevision; | |
941 | + | |
942 | +} NwdCGetRequesterVersion, *PNwdCGetRequesterVersion; | |
943 | + | |
944 | +typedef struct _nwc_scan_conn_info { | |
945 | + unsigned int uScanIndex; | |
946 | + unsigned int uScanInfoLevel; | |
947 | + unsigned int uScanInfoLen; | |
948 | + unsigned int uScanConnInfoOffset; | |
949 | + unsigned int uScanFlags; | |
950 | + unsigned int uReturnInfoLevel; | |
951 | + unsigned int uReturnInfoLength; | |
952 | + unsigned int uConnectionReference; | |
953 | + unsigned int uReturnConnInfoOffset; | |
954 | + | |
955 | +} NwdCScanConnInfo, *PNwdCScanConnInfo; | |
956 | + | |
957 | +typedef struct nwc_get_pref_ds_tree { | |
958 | + unsigned int uTreeLength; | |
959 | + unsigned int DsTreeNameOffset; | |
960 | + | |
961 | +} NwdCGetPreferredDsTree, *PNwdCGetPreferredDsTree; | |
962 | + | |
963 | +typedef struct nwc_set_pref_ds_tree { | |
964 | + unsigned int uTreeLength; | |
965 | + unsigned int DsTreeNameOffset; | |
966 | + | |
967 | +} NwdCSetPreferredDsTree, *PNwdCSetPreferredDsTree; | |
968 | + | |
969 | +typedef struct nwc_set_def_name_ctx { | |
970 | + unsigned int uTreeLength; | |
971 | + unsigned int TreeOffset; | |
972 | + unsigned int uNameLength; | |
973 | + unsigned int NameContextOffset; | |
974 | + | |
975 | +} NwdCSetDefaultNameContext, *PNwdCSetDefaultNameContext; | |
976 | + | |
977 | +typedef struct nwc_get_def_name_ctx { | |
978 | + unsigned int uTreeLength; | |
979 | + unsigned int TreeOffset; | |
980 | + unsigned int uNameLength; | |
981 | + unsigned int NameContextOffset; | |
982 | + | |
983 | +} NwdCGetDefaultNameContext, *PNwdCGetDefaultNameContext; | |
984 | + | |
985 | +typedef struct _nwc_get_treemonitored_connref { | |
986 | + NwdString TreeName; | |
987 | + HANDLE uConnReference; | |
988 | + | |
989 | +} NwdCGetTreeMonitoredConnRef, *PNwdCGetTreeMonitoredConnRef; | |
990 | + | |
991 | +typedef struct _nwc_enumerate_identities { | |
992 | + unsigned int Iterator; | |
993 | + unsigned int domainNameLen; | |
994 | + unsigned int domainNameOffset; | |
995 | + unsigned int AuthType; | |
996 | + unsigned int objectNameLen; | |
997 | + unsigned int objectNameOffset; | |
998 | + unsigned int NameType; | |
999 | + unsigned short int ObjectType; | |
1000 | + unsigned int IdentityFlags; | |
1001 | + u32 AuthenticationId; | |
1002 | + | |
1003 | +} NwdCDEnumerateIdentities, *PNwdCEnumerateIdentities; | |
1004 | + | |
1005 | +typedef struct nwd_change_key { | |
1006 | + unsigned int domainNameOffset; | |
1007 | + unsigned int domainNameLen; | |
1008 | + unsigned int AuthType; | |
1009 | + unsigned int objectNameOffset; | |
1010 | + unsigned int objectNameLen; | |
1011 | + unsigned int NameType; | |
1012 | + unsigned short int ObjectType; | |
1013 | + unsigned int verifyPasswordOffset; | |
1014 | + unsigned int verifyPasswordLen; | |
1015 | + unsigned int newPasswordOffset; | |
1016 | + unsigned int newPasswordLen; | |
1017 | + | |
1018 | +} NwdCChangeKey, *PNwdCChangeKey; | |
1019 | + | |
1020 | +typedef struct _nwd_get_primary_conn { | |
1021 | + HANDLE uConnReference; | |
1022 | + | |
1023 | +} NwdCGetPrimaryConnection, *PNwdCGetPrimaryConnection; | |
1024 | + | |
1025 | +typedef struct _nwd_set_primary_conn { | |
1026 | + HANDLE ConnHandle; | |
1027 | + | |
1028 | +} NwdCSetPrimaryConnection, *PNwdCSetPrimaryConnection; | |
1029 | + | |
1030 | +typedef struct _nwd_map_drive_ex { | |
1031 | + u32 ConnHandle; | |
1032 | + u32 localUid; | |
1033 | + u32 linkOffsetLength; | |
1034 | + u32 linkOffset; | |
1035 | + u32 dirPathOffsetLength; | |
1036 | + u32 dirPathOffset; | |
1037 | + | |
1038 | +} NwdCMapDriveEx, *PNwdCMapDriveEx; | |
1039 | + | |
1040 | +typedef struct _nwd_unmap_drive_ex { | |
1041 | + unsigned int linkLen; | |
1042 | + char linkPath[1]; | |
1043 | + | |
1044 | +} NwdCUnmapDriveEx, *PNwdCUnmapDriveEx; | |
1045 | + | |
1046 | +typedef struct _nwd_enum_links { | |
1047 | + unsigned int totalLen; | |
1048 | + unsigned int linkCount; | |
1049 | + | |
1050 | +} NwdCEnumLinks, *PNwdCEnumLinks; | |
1051 | + | |
1052 | +typedef struct nwd_getbroadcastnotification { | |
1053 | + unsigned int uMessageFlags; | |
1054 | + HANDLE uConnReference; | |
1055 | + unsigned int messageLen; | |
1056 | + char message[1]; | |
1057 | + | |
1058 | +} NwdCGetBroadcastNotification, *PNwdCGetBroadcastNotification; | |
1059 | + | |
1060 | +typedef struct _enum_entry { | |
1061 | + unsigned int entryLen; | |
1062 | + u32 connHdl; | |
1063 | + char data[0]; | |
1064 | +} NwdCEnumEntry, *PNwdCEnumEntry; | |
1065 | + | |
1066 | +typedef struct _nwd_set_conn_info { | |
1067 | + HANDLE ConnHandle; | |
1068 | + unsigned int uInfoLevel; | |
1069 | + unsigned int uInfoLength; | |
1070 | + unsigned int offsetConnInfo; | |
1071 | + | |
1072 | +} NwdCSetConnInfo, *PNwdCSetConnInfo; | |
1073 | + | |
1074 | +typedef struct _len_string { | |
1075 | + u32 stLen; | |
1076 | + char string[1]; | |
1077 | + | |
1078 | +} LString, *PLString; | |
1079 | + | |
1080 | +typedef struct _DEBUG_REQUEST { | |
1081 | + COMMAND_REQUEST_HEADER Command; | |
1082 | + int cmdlen; | |
1083 | + char dbgcmd[1]; | |
1084 | + | |
1085 | +} DEBUG_REQUEST, *PDEBUG_REQUEST; | |
1086 | + | |
1087 | +typedef struct _DEBUG_REPLY { | |
1088 | + COMMAND_REPLY_HEADER Reply; | |
1089 | + | |
1090 | +} DEBUG_REPLY, *PDEBUG_REPLY; | |
1091 | + | |
1092 | +typedef struct _Nwd_Set_Key { | |
1093 | + HANDLE ConnHandle; | |
1094 | + unsigned int AuthenticationId; | |
1095 | + unsigned int objectNameLen; | |
1096 | + unsigned int objectNameOffset; | |
1097 | + unsigned short int ObjectType; | |
1098 | + unsigned int newPasswordLen; | |
1099 | + unsigned int newPasswordOffset; | |
1100 | + | |
1101 | +} NwdCSetKey, *PNwdCSetKey; | |
1102 | + | |
1103 | +typedef struct _Nwd_Verify_Key { | |
1104 | + unsigned int AuthType; | |
1105 | + unsigned int NameType; | |
1106 | + unsigned short int ObjectType; | |
1107 | + unsigned int domainNameLen; | |
1108 | + unsigned int domainNameOffset; | |
1109 | + unsigned int objectNameLen; | |
1110 | + unsigned int objectNameOffset; | |
1111 | + unsigned int verifyPasswordLen; | |
1112 | + unsigned int verifyPasswordOffset; | |
1113 | + | |
1114 | +} NwdCVerifyKey, *PNwdCVerifyKey; | |
1115 | + | |
1116 | +typedef struct _GET_CACHE_FLAG { | |
1117 | + COMMAND_REQUEST_HEADER Command; | |
1118 | + int pathLen; | |
1119 | + unsigned char path[0]; | |
1120 | + | |
1121 | +} GET_CACHE_FLAG_REQUEST, *PGET_CACHE_FLAG_REQUEST; | |
1122 | + | |
1123 | +typedef struct _GET_CACHE_FLAG_REPLY { | |
1124 | + COMMAND_REPLY_HEADER Reply; | |
1125 | + int CacheFlag; | |
1126 | + | |
1127 | +} GET_CACHE_FLAG_REPLY, *PGET_CACHE_FLAG_REPLY; | |
1128 | + | |
1129 | +typedef struct _XA_LIST_REPLY { | |
1130 | + COMMAND_REPLY_HEADER Reply; | |
1131 | + unsigned char *pData; | |
1132 | + | |
1133 | +} XA_LIST_REPLY, *PXA_LIST_REPLY; | |
1134 | + | |
1135 | +typedef struct _XA_GET_REQUEST { | |
1136 | + COMMAND_REQUEST_HEADER Command; | |
1137 | + unsigned int pathLen; | |
1138 | + unsigned int nameLen; | |
1139 | + unsigned char data[1]; //hold path, attribute name | |
1140 | + | |
1141 | +} XA_GET_REQUEST, *PXA_GET_REQUEST; | |
1142 | + | |
1143 | +typedef struct _XA_GET_REPLY { | |
1144 | + COMMAND_REPLY_HEADER Reply; | |
1145 | + unsigned char *pData; | |
1146 | + | |
1147 | +} XA_GET_REPLY, *PXA_GET_REPLY; | |
1148 | + | |
1149 | +typedef struct _XA_SET_REQUEST { | |
1150 | + COMMAND_REQUEST_HEADER Command; | |
1151 | + unsigned int TtlWriteDataSize; | |
1152 | + unsigned int WritePosition; | |
1153 | + int flags; | |
1154 | + unsigned int pathLen; | |
1155 | + unsigned int nameLen; | |
1156 | + unsigned int valueLen; | |
1157 | + unsigned char data[1]; //hold path, attribute name, value data | |
1158 | + | |
1159 | +} XA_SET_REQUEST, *PXA_SET_REQUEST; | |
1160 | + | |
1161 | +typedef struct _XA_SET_REPLY { | |
1162 | + COMMAND_REPLY_HEADER Reply; | |
1163 | + unsigned char *pData; | |
1164 | + | |
1165 | +} XA_SET_REPLY, *PXA_SET_REPLY; | |
1166 | + | |
1167 | +typedef struct _SET_FILE_LOCK_REQUEST { | |
1168 | + COMMAND_REQUEST_HEADER Command; | |
1169 | + HANDLE handle; | |
1170 | + unsigned char fl_type; | |
1171 | + loff_t fl_start; | |
1172 | + loff_t fl_len; | |
1173 | + | |
1174 | +} SET_FILE_LOCK_REQUEST, *PSET_FILE_LOCK_REQUEST; | |
1175 | + | |
1176 | +typedef struct _SET_FILE_LOCK_REPLY { | |
1177 | + COMMAND_REPLY_HEADER Reply; | |
1178 | + | |
1179 | +} SET_FILE_LOCK_REPLY, *PSET_FILE_LOCK_REPLY; | |
1180 | + | |
1181 | +#pragma pack(pop) | |
1182 | + | |
1183 | +#endif /* __NOVFS_COMMANDS_H */ | |
1184 | --- /dev/null | |
1185 | +++ b/fs/novfs/daemon.c | |
1186 | @@ -0,0 +1,2400 @@ | |
1187 | +/* | |
1188 | + * Novell NCP Redirector for Linux | |
1189 | + * Author: James Turner | |
1190 | + * | |
1191 | + * This file contains all the functions necessary for sending commands to our | |
1192 | + * daemon module. | |
1193 | + * | |
1194 | + * Copyright (C) 2005 Novell, Inc. | |
1195 | + * | |
1196 | + * This program is free software; you can redistribute it and/or | |
1197 | + * modify it under the terms of the GNU General Public License | |
1198 | + * as published by the Free Software Foundation; either version 2 | |
1199 | + * of the License, or (at your option) any later version. | |
1200 | + */ | |
1201 | + | |
1202 | +#include <linux/module.h> | |
1203 | +#include <linux/fs.h> | |
1204 | +#include <linux/slab.h> | |
1205 | +#include <linux/string.h> | |
1206 | +#include <linux/list.h> | |
1207 | +#include <linux/timer.h> | |
1208 | +#include <linux/poll.h> | |
1209 | +#include <linux/pagemap.h> | |
1210 | +#include <linux/smp_lock.h> | |
1211 | +#include <linux/semaphore.h> | |
1212 | +#include <asm/uaccess.h> | |
1213 | +#include <asm/atomic.h> | |
1214 | +#include <linux/time.h> | |
1215 | + | |
1216 | +#include "vfs.h" | |
1217 | +#include "nwcapi.h" | |
1218 | +#include "commands.h" | |
1219 | +#include "nwerror.h" | |
1220 | + | |
1221 | +#define QUEUE_SENDING 0 | |
1222 | +#define QUEUE_WAITING 1 | |
1223 | +#define QUEUE_TIMEOUT 2 | |
1224 | +#define QUEUE_ACKED 3 | |
1225 | +#define QUEUE_DONE 4 | |
1226 | + | |
1227 | +#define TIMEOUT_VALUE 10 | |
1228 | + | |
1229 | +#define DH_TYPE_UNDEFINED 0 | |
1230 | +#define DH_TYPE_STREAM 1 | |
1231 | +#define DH_TYPE_CONNECTION 2 | |
1232 | + | |
1233 | +/*===[ Type definitions ]=================================================*/ | |
1234 | +typedef struct _DAEMON_QUEUE { | |
1235 | + struct list_head list; /* Must be first entry */ | |
1236 | + spinlock_t lock; /* Used to control access to list */ | |
1237 | + struct semaphore semaphore; /* Used to signal when data is available */ | |
1238 | +} daemon_queue_t; | |
1239 | + | |
1240 | +typedef struct _DAEMON_COMMAND { | |
1241 | + struct list_head list; /* Must be first entry */ | |
1242 | + atomic_t reference; | |
1243 | + unsigned int status; | |
1244 | + unsigned int flags; | |
1245 | + struct semaphore semaphore; | |
1246 | + unsigned long sequence; | |
1247 | + struct timer_list timer; | |
1248 | + void *request; | |
1249 | + unsigned long reqlen; | |
1250 | + void *data; | |
1251 | + int datalen; | |
1252 | + void *reply; | |
1253 | + unsigned long replen; | |
1254 | +} daemon_command_t; | |
1255 | + | |
1256 | +typedef struct _DAEMON_HANDLE_ { | |
1257 | + struct list_head list; | |
1258 | + rwlock_t lock; | |
1259 | + session_t session; | |
1260 | +} daemon_handle_t; | |
1261 | + | |
1262 | +typedef struct _DAEMON_RESOURCE_ { | |
1263 | + struct list_head list; | |
1264 | + int type; | |
1265 | + HANDLE connection; | |
1266 | + unsigned char handle[6]; | |
1267 | + mode_t mode; | |
1268 | + loff_t size; | |
1269 | +} daemon_resource_t; | |
1270 | + | |
1271 | +typedef struct _DRIVE_MAP_ { | |
1272 | + struct list_head list; /* Must be first item */ | |
1273 | + session_t session; | |
1274 | + unsigned long hash; | |
1275 | + int namelen; | |
1276 | + char name[1]; | |
1277 | +} drive_map_t; | |
1278 | + | |
1279 | +/*===[ Function prototypes ]==============================================*/ | |
1280 | +int Daemon_Close_Control(struct inode *Inode, struct file *File); | |
1281 | +int Daemon_Library_close(struct inode *inode, struct file *file); | |
1282 | +int Daemon_Library_open(struct inode *inode, struct file *file); | |
1283 | +loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin); | |
1284 | +int Daemon_Open_Control(struct inode *Inode, struct file *File); | |
1285 | +uint Daemon_Poll(struct file *file, struct poll_table_struct *poll_table); | |
1286 | +int Daemon_Remove_Resource(daemon_handle_t * DHandle, int Type, HANDLE CHandle, | |
1287 | + unsigned long FHandle); | |
1288 | + | |
1289 | +int Daemon_SetMountPoint(char *Path); | |
1290 | +void Daemon_Timer(unsigned long data); | |
1291 | +int Daemon_getpwuid(uid_t uid, int unamelen, char *uname); | |
1292 | +int Queue_Daemon_Command(void *request, unsigned long reqlen, void *data, int dlen, | |
1293 | + void **reply, unsigned long * replen, int interruptible); | |
1294 | +void Queue_get(daemon_command_t * que); | |
1295 | +void Queue_put(daemon_command_t * que); | |
1296 | +void Uninit_Daemon_Queue(void); | |
1297 | +daemon_command_t *find_queue(unsigned long sequence); | |
1298 | +daemon_command_t *get_next_queue(int Set_Queue_Waiting); | |
1299 | +int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t * DHandle); | |
1300 | +int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t * DHandle); | |
1301 | +int NwdGetMountPath(PXPLAT pdata); | |
1302 | +static int NwdSetMapDrive(PXPLAT pdata, session_t Session); | |
1303 | +static int NwdUnMapDrive(PXPLAT pdata, session_t Session); | |
1304 | +void RemoveDriveMaps(void); | |
1305 | +int local_unlink(const char *pathname); | |
1306 | + | |
1307 | +/*===[ Global variables ]=================================================*/ | |
1308 | +static daemon_queue_t Daemon_Queue; | |
1309 | + | |
1310 | +static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue); | |
1311 | + | |
1312 | +static atomic_t Sequence = ATOMIC_INIT(-1); | |
1313 | +static atomic_t Daemon_Open_Count = ATOMIC_INIT(0); | |
1314 | + | |
1315 | +static unsigned long Daemon_Command_Timeout = TIMEOUT_VALUE; | |
1316 | + | |
1317 | +static DECLARE_MUTEX(DriveMapLock); | |
1318 | +static LIST_HEAD(DriveMapList); | |
1319 | + | |
1320 | +int MaxIoSize = PAGE_SIZE; | |
1321 | + | |
1322 | +void Init_Daemon_Queue(void) | |
1323 | +{ | |
1324 | + INIT_LIST_HEAD(&Daemon_Queue.list); | |
1325 | + spin_lock_init(&Daemon_Queue.lock); | |
1326 | + init_MUTEX_LOCKED(&Daemon_Queue.semaphore); | |
1327 | +} | |
1328 | + | |
1329 | +/*++======================================================================*/ | |
1330 | +void Uninit_Daemon_Queue(void) | |
1331 | +/* | |
1332 | + * | |
1333 | + * Arguments: | |
1334 | + * | |
1335 | + * Returns: | |
1336 | + * | |
1337 | + * Abstract: | |
1338 | + * | |
1339 | + * Notes: | |
1340 | + * | |
1341 | + * Environment: | |
1342 | + * | |
1343 | + *========================================================================*/ | |
1344 | +{ | |
1345 | + /* Does nothing for now but we maybe should clear the queue. */ | |
1346 | +} | |
1347 | + | |
1348 | +/*++======================================================================*/ | |
1349 | +void Daemon_Timer(unsigned long data) | |
1350 | +/* | |
1351 | + * | |
1352 | + * Arguments: | |
1353 | + * | |
1354 | + * Returns: | |
1355 | + * | |
1356 | + * Abstract: | |
1357 | + * | |
1358 | + * Notes: | |
1359 | + * | |
1360 | + * Environment: | |
1361 | + * | |
1362 | + *========================================================================*/ | |
1363 | +{ | |
1364 | + daemon_command_t *que = (daemon_command_t *) data; | |
1365 | + | |
1366 | + if (QUEUE_ACKED != que->status) { | |
1367 | + que->status = QUEUE_TIMEOUT; | |
1368 | + } | |
1369 | + up(&que->semaphore); | |
1370 | +} | |
1371 | + | |
1372 | +int Queue_Daemon_Command(void *request, unsigned long reqlen, void *data, int dlen, | |
1373 | + void **reply, unsigned long * replen, int interruptible) | |
1374 | +/* | |
1375 | + * Arguments: void *request - pointer to the request that is to be sent. Needs to be kernel memory. | |
1376 | + * int reqlen - length of the request. | |
1377 | + *========================================================================*/ | |
1378 | +{ | |
1379 | + daemon_command_t *que; | |
1380 | + int retCode = 0; | |
1381 | + uint64_t ts1, ts2; | |
1382 | + | |
1383 | + ts1 = get_nanosecond_time(); | |
1384 | + | |
1385 | + DbgPrint("Queue_Daemon_Command: 0x%p %d\n", request, reqlen); | |
1386 | + | |
1387 | + if (atomic_read(&Daemon_Open_Count)) { | |
1388 | + | |
1389 | + que = kmalloc(sizeof(*que), GFP_KERNEL); | |
1390 | + DbgPrint("Queue_Daemon_Command: que=0x%p\n", que); | |
1391 | + if (que) { | |
1392 | + atomic_set(&que->reference, 0); | |
1393 | + que->status = QUEUE_SENDING; | |
1394 | + que->flags = 0; | |
1395 | + | |
1396 | + init_MUTEX_LOCKED(&que->semaphore); | |
1397 | + | |
1398 | + que->sequence = atomic_inc_return(&Sequence); | |
1399 | + | |
1400 | + ((PCOMMAND_REQUEST_HEADER) request)->SequenceNumber = | |
1401 | + que->sequence; | |
1402 | + | |
1403 | + /* | |
1404 | + * Setup and start que timer | |
1405 | + */ | |
1406 | + init_timer(&que->timer); | |
1407 | + que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout); | |
1408 | + que->timer.data = (unsigned long) que; | |
1409 | + que->timer.function = Daemon_Timer; | |
1410 | + add_timer(&que->timer); | |
1411 | + | |
1412 | + /* | |
1413 | + * Setup request | |
1414 | + */ | |
1415 | + que->request = request; | |
1416 | + que->reqlen = reqlen; | |
1417 | + que->data = data; | |
1418 | + que->datalen = dlen; | |
1419 | + que->reply = NULL; | |
1420 | + que->replen = 0; | |
1421 | + | |
1422 | + /* | |
1423 | + * Added entry to queue. | |
1424 | + */ | |
1425 | + /* | |
1426 | + * Check to see if interruptible and set flags. | |
1427 | + */ | |
1428 | + if (interruptible) { | |
1429 | + que->flags |= INTERRUPTIBLE; | |
1430 | + } | |
1431 | + | |
1432 | + Queue_get(que); | |
1433 | + | |
1434 | + spin_lock(&Daemon_Queue.lock); | |
1435 | + list_add_tail(&que->list, &Daemon_Queue.list); | |
1436 | + spin_unlock(&Daemon_Queue.lock); | |
1437 | + | |
1438 | + /* | |
1439 | + * Signal that there is data to be read | |
1440 | + */ | |
1441 | + up(&Daemon_Queue.semaphore); | |
1442 | + | |
1443 | + /* | |
1444 | + * Give a change to the other processes. | |
1445 | + */ | |
1446 | + yield(); | |
1447 | + | |
1448 | + /* | |
1449 | + * Block waiting for reply or timeout | |
1450 | + */ | |
1451 | + down(&que->semaphore); | |
1452 | + | |
1453 | + if (QUEUE_ACKED == que->status) { | |
1454 | + que->status = QUEUE_WAITING; | |
1455 | + mod_timer(&que->timer, | |
1456 | + jiffies + | |
1457 | + (HZ * 2 * Daemon_Command_Timeout)); | |
1458 | + if (interruptible) { | |
1459 | + retCode = | |
1460 | + down_interruptible(&que->semaphore); | |
1461 | + } else { | |
1462 | + down(&que->semaphore); | |
1463 | + } | |
1464 | + } | |
1465 | + | |
1466 | + /* | |
1467 | + * Delete timer | |
1468 | + */ | |
1469 | + del_timer(&que->timer); | |
1470 | + | |
1471 | + /* | |
1472 | + * Check for timeout | |
1473 | + */ | |
1474 | + if ((QUEUE_TIMEOUT == que->status) | |
1475 | + && (NULL == que->reply)) { | |
1476 | + DbgPrint("Queue_Daemon_Command: Timeout\n"); | |
1477 | + retCode = -ETIME; | |
1478 | + } | |
1479 | + *reply = que->reply; | |
1480 | + *replen = que->replen; | |
1481 | + | |
1482 | + /* | |
1483 | + * Remove item from queue | |
1484 | + */ | |
1485 | + Queue_put(que); | |
1486 | + | |
1487 | + } else { /* Error case with no memory */ | |
1488 | + | |
1489 | + retCode = -ENOMEM; | |
1490 | + *reply = NULL; | |
1491 | + *replen = 0; | |
1492 | + } | |
1493 | + } else { | |
1494 | + retCode = -EIO; | |
1495 | + *reply = NULL; | |
1496 | + *replen = 0; | |
1497 | + | |
1498 | + } | |
1499 | + ts2 = get_nanosecond_time(); | |
1500 | + ts2 = ts2 - ts1; | |
1501 | + | |
1502 | + DbgPrint("Queue_Daemon_Command: %llu retCode=%d \n", ts2, retCode); | |
1503 | + return (retCode); | |
1504 | +} | |
1505 | + | |
1506 | +/*++======================================================================*/ | |
1507 | +void Queue_get(daemon_command_t * Que) | |
1508 | +/* | |
1509 | + * | |
1510 | + * Arguments: | |
1511 | + * | |
1512 | + * Returns: | |
1513 | + * | |
1514 | + * Abstract: | |
1515 | + * | |
1516 | + * Notes: | |
1517 | + * | |
1518 | + * Environment: | |
1519 | + * | |
1520 | + *========================================================================*/ | |
1521 | +{ | |
1522 | + DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference)); | |
1523 | + atomic_inc(&Que->reference); | |
1524 | +} | |
1525 | + | |
1526 | +/*++======================================================================*/ | |
1527 | +void Queue_put(daemon_command_t * Que) | |
1528 | +/* | |
1529 | + * | |
1530 | + * Arguments: | |
1531 | + * | |
1532 | + * Returns: | |
1533 | + * | |
1534 | + * Abstract: | |
1535 | + * | |
1536 | + * Notes: | |
1537 | + * | |
1538 | + * Environment: | |
1539 | + * | |
1540 | + *========================================================================*/ | |
1541 | +{ | |
1542 | + | |
1543 | + DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference)); | |
1544 | + spin_lock(&Daemon_Queue.lock); | |
1545 | + | |
1546 | + if (atomic_dec_and_test(&Que->reference)) { | |
1547 | + /* | |
1548 | + * Remove item from queue | |
1549 | + */ | |
1550 | + list_del(&Que->list); | |
1551 | + spin_unlock(&Daemon_Queue.lock); | |
1552 | + | |
1553 | + /* | |
1554 | + * Free item memory | |
1555 | + */ | |
1556 | + kfree(Que); | |
1557 | + } else { | |
1558 | + spin_unlock(&Daemon_Queue.lock); | |
1559 | + } | |
1560 | +} | |
1561 | + | |
1562 | +/*++======================================================================*/ | |
1563 | +daemon_command_t *get_next_queue(int Set_Queue_Waiting) | |
1564 | +/* | |
1565 | + * | |
1566 | + * Arguments: | |
1567 | + * | |
1568 | + * Returns: | |
1569 | + * | |
1570 | + * Abstract: | |
1571 | + * | |
1572 | + * Notes: | |
1573 | + * | |
1574 | + * Environment: | |
1575 | + * | |
1576 | + *========================================================================*/ | |
1577 | +{ | |
1578 | + daemon_command_t *que; | |
1579 | + | |
1580 | + DbgPrint("get_next_queue: que=0x%p\n", Daemon_Queue.list.next); | |
1581 | + | |
1582 | + spin_lock(&Daemon_Queue.lock); | |
1583 | + que = (daemon_command_t *) Daemon_Queue.list.next; | |
1584 | + | |
1585 | + while (que && (que != (daemon_command_t *) & Daemon_Queue.list.next) | |
1586 | + && (que->status != QUEUE_SENDING)) { | |
1587 | + que = (daemon_command_t *) que->list.next; | |
1588 | + } | |
1589 | + | |
1590 | + if ((NULL == que) || (que == (daemon_command_t *) & Daemon_Queue.list) | |
1591 | + || (que->status != QUEUE_SENDING)) { | |
1592 | + que = NULL; | |
1593 | + } else if (Set_Queue_Waiting) { | |
1594 | + que->status = QUEUE_WAITING; | |
1595 | + } | |
1596 | + | |
1597 | + if (que) { | |
1598 | + atomic_inc(&que->reference); | |
1599 | + } | |
1600 | + | |
1601 | + spin_unlock(&Daemon_Queue.lock); | |
1602 | + | |
1603 | + DbgPrint("get_next_queue: return=0x%p\n", que); | |
1604 | + return (que); | |
1605 | +} | |
1606 | + | |
1607 | +/*++======================================================================*/ | |
1608 | +daemon_command_t *find_queue(unsigned long sequence) | |
1609 | +/* | |
1610 | + * | |
1611 | + * Arguments: | |
1612 | + * | |
1613 | + * Returns: | |
1614 | + * | |
1615 | + * Abstract: | |
1616 | + * | |
1617 | + * Notes: | |
1618 | + * | |
1619 | + * Environment: | |
1620 | + * | |
1621 | + *========================================================================*/ | |
1622 | +{ | |
1623 | + daemon_command_t *que; | |
1624 | + | |
1625 | + DbgPrint("find_queue: 0x%x\n", sequence); | |
1626 | + | |
1627 | + spin_lock(&Daemon_Queue.lock); | |
1628 | + que = (daemon_command_t *) Daemon_Queue.list.next; | |
1629 | + | |
1630 | + while (que && (que != (daemon_command_t *) & Daemon_Queue.list.next) | |
1631 | + && (que->sequence != sequence)) { | |
1632 | + que = (daemon_command_t *) que->list.next; | |
1633 | + } | |
1634 | + | |
1635 | + if ((NULL == que) | |
1636 | + || (que == (daemon_command_t *) & Daemon_Queue.list.next) | |
1637 | + || (que->sequence != sequence)) { | |
1638 | + que = NULL; | |
1639 | + } | |
1640 | + | |
1641 | + if (que) { | |
1642 | + atomic_inc(&que->reference); | |
1643 | + } | |
1644 | + | |
1645 | + spin_unlock(&Daemon_Queue.lock); | |
1646 | + | |
1647 | + DbgPrint("find_queue: return 0x%p\n", que); | |
1648 | + return (que); | |
1649 | +} | |
1650 | + | |
1651 | +/*++======================================================================*/ | |
1652 | +int Daemon_Open_Control(struct inode *Inode, struct file *File) | |
1653 | +/* | |
1654 | + * | |
1655 | + * Arguments: | |
1656 | + * | |
1657 | + * Returns: | |
1658 | + * | |
1659 | + * Abstract: | |
1660 | + * | |
1661 | + * Notes: | |
1662 | + * | |
1663 | + * Environment: | |
1664 | + * | |
1665 | + *========================================================================*/ | |
1666 | +{ | |
1667 | + DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, | |
1668 | + atomic_read(&Daemon_Open_Count)); | |
1669 | + atomic_inc(&Daemon_Open_Count); | |
1670 | + | |
1671 | + return (0); | |
1672 | +} | |
1673 | + | |
1674 | +/*++======================================================================*/ | |
1675 | +int Daemon_Close_Control(struct inode *Inode, struct file *File) | |
1676 | +/* | |
1677 | + * | |
1678 | + * Arguments: | |
1679 | + * | |
1680 | + * Returns: | |
1681 | + * | |
1682 | + * Abstract: | |
1683 | + * | |
1684 | + * Notes: | |
1685 | + * | |
1686 | + * Environment: | |
1687 | + * | |
1688 | + *========================================================================*/ | |
1689 | +{ | |
1690 | + daemon_command_t *que; | |
1691 | + | |
1692 | + DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, | |
1693 | + atomic_read(&Daemon_Open_Count)); | |
1694 | + | |
1695 | + if (atomic_dec_and_test(&Daemon_Open_Count)) { | |
1696 | + /* | |
1697 | + * Signal any pending que itmes. | |
1698 | + */ | |
1699 | + | |
1700 | + spin_lock(&Daemon_Queue.lock); | |
1701 | + que = (daemon_command_t *) Daemon_Queue.list.next; | |
1702 | + | |
1703 | + while (que | |
1704 | + && (que != (daemon_command_t *) & Daemon_Queue.list.next) | |
1705 | + && (que->status != QUEUE_DONE)) { | |
1706 | + que->status = QUEUE_TIMEOUT; | |
1707 | + up(&que->semaphore); | |
1708 | + | |
1709 | + que = (daemon_command_t *) que->list.next; | |
1710 | + } | |
1711 | + spin_unlock(&Daemon_Queue.lock); | |
1712 | + | |
1713 | + RemoveDriveMaps(); | |
1714 | + | |
1715 | + Scope_Cleanup(); | |
1716 | + } | |
1717 | + | |
1718 | + return (0); | |
1719 | +} | |
1720 | + | |
1721 | +ssize_t Daemon_Send_Command(struct file *file, char __user *buf, size_t len, loff_t * off) | |
1722 | +{ | |
1723 | + daemon_command_t *que; | |
1724 | + size_t retValue = 0; | |
1725 | + int Finished = 0; | |
1726 | + struct data_list *dlist; | |
1727 | + int i, dcnt, bcnt, ccnt, error; | |
1728 | + char *vadr; | |
1729 | + unsigned long cpylen; | |
1730 | + | |
1731 | + DbgPrint("Daemon_Send_Command: %u %lld\n", len, *off); | |
1732 | + if (len > MaxIoSize) { | |
1733 | + MaxIoSize = len; | |
1734 | + } | |
1735 | + | |
1736 | + while (!Finished) { | |
1737 | + que = get_next_queue(1); | |
1738 | + DbgPrint("Daemon_Send_Command: 0x%p\n", que); | |
1739 | + if (que) { | |
1740 | + retValue = que->reqlen; | |
1741 | + if (retValue > len) { | |
1742 | + retValue = len; | |
1743 | + } | |
1744 | + if (retValue > 0x80) | |
1745 | + mydump(0x80, que->request); | |
1746 | + else | |
1747 | + mydump(retValue, que->request); | |
1748 | + | |
1749 | + cpylen = copy_to_user(buf, que->request, retValue); | |
1750 | + if (que->datalen && (retValue < len)) { | |
1751 | + buf += retValue; | |
1752 | + dlist = que->data; | |
1753 | + dcnt = que->datalen; | |
1754 | + for (i = 0; i < dcnt; i++, dlist++) { | |
1755 | + if (DLREAD == dlist->rwflag) { | |
1756 | + bcnt = dlist->len; | |
1757 | + DbgPrint | |
1758 | + ("Daemon_Send_Command%d: page=0x%p offset=0x%p len=%d\n", | |
1759 | + i, dlist->page, | |
1760 | + dlist->offset, dlist->len); | |
1761 | + if ((bcnt + retValue) <= len) { | |
1762 | + void *km_adr = NULL; | |
1763 | + | |
1764 | + if (dlist->page) { | |
1765 | + km_adr = | |
1766 | + kmap(dlist-> | |
1767 | + page); | |
1768 | + vadr = km_adr; | |
1769 | + vadr += | |
1770 | + (unsigned long) | |
1771 | + dlist-> | |
1772 | + offset; | |
1773 | + } else { | |
1774 | + vadr = | |
1775 | + dlist-> | |
1776 | + offset; | |
1777 | + } | |
1778 | + | |
1779 | + ccnt = | |
1780 | + copy_to_user(buf, | |
1781 | + vadr, | |
1782 | + bcnt); | |
1783 | + | |
1784 | + DbgPrint | |
1785 | + ("Daemon_Send_Command: Copy %d from 0x%p to 0x%p.\n", | |
1786 | + bcnt, vadr, buf); | |
1787 | + if (bcnt > 0x80) | |
1788 | + mydump(0x80, | |
1789 | + vadr); | |
1790 | + else | |
1791 | + mydump(bcnt, | |
1792 | + vadr); | |
1793 | + | |
1794 | + if (km_adr) { | |
1795 | + kunmap(dlist-> | |
1796 | + page); | |
1797 | + } | |
1798 | + | |
1799 | + retValue += bcnt; | |
1800 | + buf += bcnt; | |
1801 | + } else { | |
1802 | + break; | |
1803 | + } | |
1804 | + } | |
1805 | + } | |
1806 | + } | |
1807 | + Queue_put(que); | |
1808 | + break; | |
1809 | + } | |
1810 | + | |
1811 | + if (O_NONBLOCK & file->f_flags) { | |
1812 | + retValue = -EAGAIN; | |
1813 | + break; | |
1814 | + } else { | |
1815 | + if ((error = | |
1816 | + down_interruptible(&Daemon_Queue.semaphore))) { | |
1817 | + DbgPrint | |
1818 | + ("Daemon_Send_Command: after down_interruptible error...%d\n", | |
1819 | + error); | |
1820 | + retValue = -EINTR; | |
1821 | + break; | |
1822 | + } | |
1823 | + DbgPrint | |
1824 | + ("Daemon_Send_Command: after down_interruptible\n"); | |
1825 | + } | |
1826 | + } | |
1827 | + | |
1828 | + *off = *off; | |
1829 | + | |
1830 | + DbgPrint("Daemon_Send_Command: return 0x%x\n", retValue); | |
1831 | + | |
1832 | + return (retValue); | |
1833 | +} | |
1834 | + | |
1835 | +ssize_t Daemon_Receive_Reply(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos) | |
1836 | +{ | |
1837 | + daemon_command_t *que; | |
1838 | + size_t retValue = 0; | |
1839 | + void *reply; | |
1840 | + unsigned long sequence, cpylen; | |
1841 | + | |
1842 | + struct data_list *dlist; | |
1843 | + char *vadr; | |
1844 | + int i; | |
1845 | + | |
1846 | + DbgPrint("Daemon_Receive_Reply: buf=0x%p nbytes=%d ppos=%llx\n", buf, | |
1847 | + nbytes, *ppos); | |
1848 | + | |
1849 | + /* | |
1850 | + * Get sequence number from reply buffer | |
1851 | + */ | |
1852 | + | |
1853 | + cpylen = copy_from_user(&sequence, buf, sizeof(sequence)); | |
1854 | + | |
1855 | + /* | |
1856 | + * Find item based on sequence number | |
1857 | + */ | |
1858 | + que = find_queue(sequence); | |
1859 | + | |
1860 | + DbgPrint("Daemon_Receive_Reply: 0x%x 0x%p %d\n", sequence, que, nbytes); | |
1861 | + if (que) { | |
1862 | + do { | |
1863 | + retValue = nbytes; | |
1864 | + /* | |
1865 | + * Ack packet from novfsd. Remove timer and | |
1866 | + * return | |
1867 | + */ | |
1868 | + if (nbytes == sizeof(sequence)) { | |
1869 | + que->status = QUEUE_ACKED; | |
1870 | + break; | |
1871 | + } | |
1872 | + | |
1873 | + if (NULL != (dlist = que->data)) { | |
1874 | + int thiscopy, left = nbytes; | |
1875 | + retValue = 0; | |
1876 | + | |
1877 | + DbgPrint | |
1878 | + ("Daemon_Receive_Reply: dlist=0x%p count=%d\n", | |
1879 | + dlist, que->datalen); | |
1880 | + for (i = 0; | |
1881 | + (i < que->datalen) && (retValue < nbytes); | |
1882 | + i++, dlist++) { | |
1883 | + DbgPrint("Daemon_Receive_Reply:\n" | |
1884 | + " dlist[%d].page: 0x%p\n" | |
1885 | + " dlist[%d].offset: 0x%p\n" | |
1886 | + " dlist[%d].len: 0x%x\n" | |
1887 | + " dlist[%d].rwflag: 0x%x\n", | |
1888 | + i, dlist->page, i, | |
1889 | + dlist->offset, i, dlist->len, | |
1890 | + i, dlist->rwflag); | |
1891 | + | |
1892 | + if (DLWRITE == dlist->rwflag) { | |
1893 | + void *km_adr = NULL; | |
1894 | + | |
1895 | + if (dlist->page) { | |
1896 | + km_adr = | |
1897 | + kmap(dlist->page); | |
1898 | + vadr = km_adr; | |
1899 | + vadr += | |
1900 | + (unsigned long) dlist-> | |
1901 | + offset; | |
1902 | + } else { | |
1903 | + vadr = dlist->offset; | |
1904 | + } | |
1905 | + | |
1906 | + thiscopy = dlist->len; | |
1907 | + if (thiscopy > left) { | |
1908 | + thiscopy = left; | |
1909 | + dlist->len = left; | |
1910 | + } | |
1911 | + cpylen = | |
1912 | + copy_from_user(vadr, buf, | |
1913 | + thiscopy); | |
1914 | + | |
1915 | + if (thiscopy > 0x80) | |
1916 | + mydump(0x80, vadr); | |
1917 | + else | |
1918 | + mydump(thiscopy, vadr); | |
1919 | + | |
1920 | + if (km_adr) { | |
1921 | + kunmap(dlist->page); | |
1922 | + } | |
1923 | + | |
1924 | + left -= thiscopy; | |
1925 | + retValue += thiscopy; | |
1926 | + buf += thiscopy; | |
1927 | + } | |
1928 | + } | |
1929 | + que->replen = retValue; | |
1930 | + } else { | |
1931 | + reply = kmalloc(nbytes, GFP_KERNEL); | |
1932 | + DbgPrint("Daemon_Receive_Reply: reply=0x%p\n", reply); | |
1933 | + if (reply) { | |
1934 | + retValue = nbytes; | |
1935 | + que->reply = reply; | |
1936 | + que->replen = nbytes; | |
1937 | + | |
1938 | + retValue -= copy_from_user(reply, buf, retValue); | |
1939 | + if (retValue > 0x80) | |
1940 | + mydump(0x80, reply); | |
1941 | + else | |
1942 | + mydump(retValue, reply); | |
1943 | + | |
1944 | + } else { | |
1945 | + retValue = -ENOMEM; | |
1946 | + } | |
1947 | + } | |
1948 | + | |
1949 | + /* | |
1950 | + * Set status that packet is done. | |
1951 | + */ | |
1952 | + que->status = QUEUE_DONE; | |
1953 | + | |
1954 | + } while (0); | |
1955 | + up(&que->semaphore); | |
1956 | + Queue_put(que); | |
1957 | + } | |
1958 | + | |
1959 | + DbgPrint("Daemon_Receive_Reply: return 0x%x\n", retValue); | |
1960 | + | |
1961 | + return (retValue); | |
1962 | +} | |
1963 | + | |
1964 | +int do_login(NclString *Server, NclString *Username, NclString *Password, HANDLE *lgnId, struct schandle *Session) | |
1965 | +{ | |
1966 | + PLOGIN_USER_REQUEST cmd; | |
1967 | + PLOGIN_USER_REPLY reply; | |
1968 | + unsigned long replylen = 0; | |
1969 | + int retCode, cmdlen, datalen; | |
1970 | + unsigned char *data; | |
1971 | + | |
1972 | + datalen = Server->len + Username->len + Password->len; | |
1973 | + cmdlen = sizeof(*cmd) + datalen; | |
1974 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
1975 | + if (!cmd) | |
1976 | + return -ENOMEM; | |
1977 | + | |
1978 | + data = (unsigned char *) cmd + sizeof(*cmd); | |
1979 | + cmd->Command.CommandType = VFS_COMMAND_LOGIN_USER; | |
1980 | + cmd->Command.SequenceNumber = 0; | |
1981 | + memcpy(&cmd->Command.SessionId, Session, sizeof(*Session)); | |
1982 | + | |
1983 | + cmd->srvNameType = Server->type; | |
1984 | + cmd->serverLength = Server->len; | |
1985 | + cmd->serverOffset = (unsigned long) (data - (unsigned char *) cmd); | |
1986 | + memcpy(data, Server->buffer, Server->len); | |
1987 | + data += Server->len; | |
1988 | + | |
1989 | + cmd->usrNameType = Username->type; | |
1990 | + cmd->userNameLength = Username->len; | |
1991 | + cmd->userNameOffset = (unsigned long) (data - (unsigned char *) cmd); | |
1992 | + memcpy(data, Username->buffer, Username->len); | |
1993 | + data += Username->len; | |
1994 | + | |
1995 | + cmd->pwdNameType = Password->type; | |
1996 | + cmd->passwordLength = Password->len; | |
1997 | + cmd->passwordOffset = (unsigned long) (data - (unsigned char *) cmd); | |
1998 | + memcpy(data, Password->buffer, Password->len); | |
1999 | + data += Password->len; | |
2000 | + | |
2001 | + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
2002 | + &replylen, INTERRUPTIBLE); | |
2003 | + if (reply) { | |
2004 | + if (reply->Reply.ErrorCode) { | |
2005 | + retCode = reply->Reply.ErrorCode; | |
2006 | + } else { | |
2007 | + retCode = 0; | |
2008 | + if (lgnId) { | |
2009 | + *lgnId = reply->loginIdentity; | |
2010 | + } | |
2011 | + } | |
2012 | + kfree(reply); | |
2013 | + } | |
2014 | + memset(cmd, 0, cmdlen); | |
2015 | + kfree(cmd); | |
2016 | + return retCode; | |
2017 | + | |
2018 | +} | |
2019 | + | |
2020 | +int do_logout(struct qstr *Server, struct schandle *Session) | |
2021 | +{ | |
2022 | + PLOGOUT_REQUEST cmd; | |
2023 | + PLOGOUT_REPLY reply; | |
2024 | + unsigned long replylen = 0; | |
2025 | + int retCode, cmdlen; | |
2026 | + | |
2027 | + cmdlen = offsetof(LOGOUT_REQUEST, Name) + Server->len; | |
2028 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
2029 | + if (!cmd) | |
2030 | + return -ENOMEM; | |
2031 | + | |
2032 | + cmd->Command.CommandType = VFS_COMMAND_LOGOUT_USER; | |
2033 | + cmd->Command.SequenceNumber = 0; | |
2034 | + memcpy(&cmd->Command.SessionId, Session, sizeof(*Session)); | |
2035 | + cmd->length = Server->len; | |
2036 | + memcpy(cmd->Name, Server->name, Server->len); | |
2037 | + | |
2038 | + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); | |
2039 | + if (reply) { | |
2040 | + if (reply->Reply.ErrorCode) { | |
2041 | + retCode = -EIO; | |
2042 | + } | |
2043 | + kfree(reply); | |
2044 | + } | |
2045 | + kfree(cmd); | |
2046 | + return (retCode); | |
2047 | + | |
2048 | +} | |
2049 | + | |
2050 | +/*++======================================================================*/ | |
2051 | +int Daemon_getpwuid(uid_t uid, int unamelen, char *uname) | |
2052 | +/* | |
2053 | + * | |
2054 | + * Arguments: | |
2055 | + * | |
2056 | + * Returns: | |
2057 | + * | |
2058 | + * Abstract: | |
2059 | + * | |
2060 | + * Notes: | |
2061 | + * | |
2062 | + * Environment: | |
2063 | + * | |
2064 | + *========================================================================*/ | |
2065 | +{ | |
2066 | + GETPWUID_REQUEST cmd; | |
2067 | + PGETPWUID_REPLY reply; | |
2068 | + unsigned long replylen = 0; | |
2069 | + int retCode; | |
2070 | + | |
2071 | + cmd.Command.CommandType = VFS_COMMAND_GETPWUD; | |
2072 | + cmd.Command.SequenceNumber = 0; | |
2073 | + SC_INITIALIZE(cmd.Command.SessionId); | |
2074 | + cmd.uid = uid; | |
2075 | + | |
2076 | + retCode = | |
2077 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
2078 | + &replylen, INTERRUPTIBLE); | |
2079 | + if (reply) { | |
2080 | + if (reply->Reply.ErrorCode) { | |
2081 | + retCode = -EIO; | |
2082 | + } else { | |
2083 | + retCode = 0; | |
2084 | + memset(uname, 0, unamelen); | |
2085 | + replylen = replylen - offsetof(GETPWUID_REPLY, UserName); | |
2086 | + if (replylen) { | |
2087 | + if (replylen > unamelen) { | |
2088 | + retCode = -EINVAL; | |
2089 | + replylen = unamelen - 1; | |
2090 | + } | |
2091 | + memcpy(uname, reply->UserName, replylen); | |
2092 | + } | |
2093 | + } | |
2094 | + kfree(reply); | |
2095 | + } | |
2096 | + return (retCode); | |
2097 | + | |
2098 | +} | |
2099 | + | |
2100 | +/*++======================================================================*/ | |
2101 | +int Daemon_getversion(char *Buf, int length) | |
2102 | +/* | |
2103 | + * | |
2104 | + * Arguments: | |
2105 | + * | |
2106 | + * Returns: | |
2107 | + * | |
2108 | + * Abstract: | |
2109 | + * | |
2110 | + * Notes: | |
2111 | + * | |
2112 | + * Environment: | |
2113 | + * | |
2114 | + *========================================================================*/ | |
2115 | +{ | |
2116 | + GET_VERSION_REQUEST cmd; | |
2117 | + PGET_VERSION_REPLY reply; | |
2118 | + unsigned long replylen = 0; | |
2119 | + int retVal = 0; | |
2120 | + | |
2121 | + cmd.Command.CommandType = VFS_COMMAND_GET_VERSION; | |
2122 | + cmd.Command.SequenceNumber = 0; | |
2123 | + SC_INITIALIZE(cmd.Command.SessionId); | |
2124 | + | |
2125 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
2126 | + &replylen, INTERRUPTIBLE); | |
2127 | + if (reply) { | |
2128 | + if (reply->Reply.ErrorCode) { | |
2129 | + retVal = -EIO; | |
2130 | + } else { | |
2131 | + retVal = replylen - offsetof(GET_VERSION_REPLY, Version); | |
2132 | + if (retVal < length) { | |
2133 | + memcpy(Buf, reply->Version, retVal); | |
2134 | + Buf[retVal] = '\0'; | |
2135 | + } | |
2136 | + } | |
2137 | + kfree(reply); | |
2138 | + } | |
2139 | + return (retVal); | |
2140 | + | |
2141 | +} | |
2142 | + | |
2143 | +static int daemon_login(struct login *Login, struct schandle *Session) | |
2144 | +{ | |
2145 | + int retCode = -ENOMEM; | |
2146 | + struct login lLogin; | |
2147 | + NclString server; | |
2148 | + NclString username; | |
2149 | + NclString password; | |
2150 | + | |
2151 | + if (!copy_from_user(&lLogin, Login, sizeof(lLogin))) { | |
2152 | + server.buffer = kmalloc(lLogin.Server.length, GFP_KERNEL); | |
2153 | + if (server.buffer) { | |
2154 | + server.len = lLogin.Server.length; | |
2155 | + server.type = NWC_STRING_TYPE_ASCII; | |
2156 | + if (!copy_from_user((void *)server.buffer, lLogin.Server.data, server.len)) { | |
2157 | + username.buffer = kmalloc(lLogin.UserName.length, GFP_KERNEL); | |
2158 | + if (username.buffer) { | |
2159 | + username.len = lLogin.UserName.length; | |
2160 | + username.type = NWC_STRING_TYPE_ASCII; | |
2161 | + if (!copy_from_user((void *)username.buffer, lLogin.UserName.data, username.len)) { | |
2162 | + password.buffer = kmalloc(lLogin.Password.length, GFP_KERNEL); | |
2163 | + if (password.buffer) { | |
2164 | + password.len = lLogin.Password.length; | |
2165 | + password.type = NWC_STRING_TYPE_ASCII; | |
2166 | + if (!copy_from_user((void *)password.buffer, lLogin.Password.data, password.len)) { | |
2167 | + retCode = do_login (&server, &username, &password, NULL, Session); | |
2168 | + if (!retCode) { | |
2169 | + char *name; | |
2170 | + name = Scope_Get_UserName(); | |
2171 | + if (name) | |
2172 | + Novfs_Add_to_Root(name); | |
2173 | + } | |
2174 | + } | |
2175 | + memset(password.buffer, 0, password.len); | |
2176 | + kfree(password.buffer); | |
2177 | + } | |
2178 | + } | |
2179 | + memset(username.buffer, 0, username.len); | |
2180 | + kfree(username.buffer); | |
2181 | + } | |
2182 | + } | |
2183 | + kfree(server.buffer); | |
2184 | + } | |
2185 | + } | |
2186 | + | |
2187 | + return (retCode); | |
2188 | +} | |
2189 | + | |
2190 | +static int daemon_logout(struct logout *Logout, struct schandle *Session) | |
2191 | +{ | |
2192 | + struct logout lLogout; | |
2193 | + struct qstr server; | |
2194 | + int retCode = -ENOMEM; | |
2195 | + | |
2196 | + if (copy_from_user(&lLogout, Logout, sizeof(lLogout))) | |
2197 | + return -EFAULT; | |
2198 | + | |
2199 | + server.name = kmalloc(lLogout.Server.length, GFP_KERNEL); | |
2200 | + if (!server.name) | |
2201 | + return -ENOMEM; | |
2202 | + server.len = lLogout.Server.length; | |
2203 | + if (copy_from_user((void *)server.name, lLogout.Server.data, server.len)) | |
2204 | + goto exit; | |
2205 | + | |
2206 | + retCode = do_logout(&server, Session); | |
2207 | +exit: | |
2208 | + kfree(server.name); | |
2209 | + return retCode; | |
2210 | +} | |
2211 | + | |
2212 | +int Daemon_CreateSessionId(struct schandle *SessionId) | |
2213 | +{ | |
2214 | + CREATE_CONTEXT_REQUEST cmd; | |
2215 | + PCREATE_CONTEXT_REPLY reply; | |
2216 | + unsigned long replylen = 0; | |
2217 | + int retCode = 0; | |
2218 | + | |
2219 | + DbgPrint("Daemon_CreateSessionId: %d\n", current->pid); | |
2220 | + | |
2221 | + cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT; | |
2222 | + cmd.Command.SequenceNumber = 0; | |
2223 | + SC_INITIALIZE(cmd.Command.SessionId); | |
2224 | + | |
2225 | + retCode = | |
2226 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
2227 | + &replylen, INTERRUPTIBLE); | |
2228 | + if (reply) { | |
2229 | + if (!reply->Reply.ErrorCode | |
2230 | + && replylen > sizeof(COMMAND_REPLY_HEADER)) { | |
2231 | + *SessionId = reply->SessionId; | |
2232 | + retCode = 0; | |
2233 | + } else { | |
2234 | + SessionId->hTypeId = 0; | |
2235 | + SessionId->hId = 0; | |
2236 | + retCode = -EIO; | |
2237 | + } | |
2238 | + kfree(reply); | |
2239 | + } | |
2240 | + DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId); | |
2241 | + return (retCode); | |
2242 | +} | |
2243 | + | |
2244 | +int Daemon_DestroySessionId(struct schandle *SessionId) | |
2245 | +{ | |
2246 | + DESTROY_CONTEXT_REQUEST cmd; | |
2247 | + PDESTROY_CONTEXT_REPLY reply; | |
2248 | + unsigned long replylen = 0; | |
2249 | + int retCode = 0; | |
2250 | + | |
2251 | + DbgPrint("Daemon_DestroySessionId: 0x%p:%p\n", | |
2252 | + SessionId->hTypeId, SessionId->hId); | |
2253 | + | |
2254 | + cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT; | |
2255 | + cmd.Command.SequenceNumber = 0; | |
2256 | + memcpy(&cmd.Command.SessionId, SessionId, sizeof (*SessionId)); | |
2257 | + | |
2258 | + retCode = | |
2259 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
2260 | + &replylen, INTERRUPTIBLE); | |
2261 | + if (reply) { | |
2262 | + if (!reply->Reply.ErrorCode) { | |
2263 | + drive_map_t *dm; | |
2264 | + struct list_head *list; | |
2265 | + | |
2266 | + retCode = 0; | |
2267 | + | |
2268 | + /* | |
2269 | + * When destroying the session check to see if there are any | |
2270 | + * mapped drives. If there are then remove them. | |
2271 | + */ | |
2272 | + down(&DriveMapLock); | |
2273 | + list_for_each(list, &DriveMapList) { | |
2274 | + struct schandle *temp; | |
2275 | + | |
2276 | + dm = list_entry(list, drive_map_t, list); | |
2277 | + temp = &dm->session; | |
2278 | + if (SC_EQUAL(SessionId, temp)) { | |
2279 | + local_unlink(dm->name); | |
2280 | + list = list->prev; | |
2281 | + list_del(&dm->list); | |
2282 | + kfree(dm); | |
2283 | + } | |
2284 | + | |
2285 | + } | |
2286 | + up(&DriveMapLock); | |
2287 | + | |
2288 | + } else { | |
2289 | + retCode = -EIO; | |
2290 | + } | |
2291 | + kfree(reply); | |
2292 | + } | |
2293 | + return (retCode); | |
2294 | +} | |
2295 | + | |
2296 | +int Daemon_Get_UserSpace(struct schandle *SessionId, uint64_t * TotalSize, | |
2297 | + uint64_t * Free, uint64_t * TotalEnties, | |
2298 | + uint64_t * FreeEnties) | |
2299 | +{ | |
2300 | + GET_USER_SPACE_REQUEST cmd; | |
2301 | + PGET_USER_SPACE_REPLY reply; | |
2302 | + unsigned long replylen = 0; | |
2303 | + int retCode = 0; | |
2304 | + | |
2305 | + DbgPrint("Daemon_Get_UserSpace: 0x%p:%p\n", | |
2306 | + SessionId->hTypeId, SessionId->hId); | |
2307 | + | |
2308 | + cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE; | |
2309 | + cmd.Command.SequenceNumber = 0; | |
2310 | + memcpy(&cmd.Command.SessionId, SessionId, sizeof (*SessionId)); | |
2311 | + | |
2312 | + retCode = | |
2313 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
2314 | + &replylen, INTERRUPTIBLE); | |
2315 | + if (reply) { | |
2316 | + if (!reply->Reply.ErrorCode) { | |
2317 | + | |
2318 | + DbgPrint("TotalSpace: %llu\n", reply->TotalSpace); | |
2319 | + DbgPrint("FreeSpace: %llu\n", reply->FreeSpace); | |
2320 | + DbgPrint("TotalEnties: %llu\n", reply->TotalEnties); | |
2321 | + DbgPrint("FreeEnties: %llu\n", reply->FreeEnties); | |
2322 | + | |
2323 | + if (TotalSize) | |
2324 | + *TotalSize = reply->TotalSpace; | |
2325 | + if (Free) | |
2326 | + *Free = reply->FreeSpace; | |
2327 | + if (TotalEnties) | |
2328 | + *TotalEnties = reply->TotalEnties; | |
2329 | + if (FreeEnties) | |
2330 | + *FreeEnties = reply->FreeEnties; | |
2331 | + retCode = 0; | |
2332 | + } else { | |
2333 | + retCode = -EIO; | |
2334 | + } | |
2335 | + kfree(reply); | |
2336 | + } | |
2337 | + return (retCode); | |
2338 | +} | |
2339 | + | |
2340 | +/*++======================================================================*/ | |
2341 | +int Daemon_SetMountPoint(char *Path) | |
2342 | +/* | |
2343 | + * | |
2344 | + * Arguments: | |
2345 | + * | |
2346 | + * Returns: | |
2347 | + * | |
2348 | + * Abstract: | |
2349 | + * | |
2350 | + * Notes: | |
2351 | + * | |
2352 | + * Environment: | |
2353 | + * | |
2354 | + *========================================================================*/ | |
2355 | +{ | |
2356 | + PSET_MOUNT_PATH_REQUEST cmd; | |
2357 | + PSET_MOUNT_PATH_REPLY reply; | |
2358 | + unsigned long replylen, cmdlen; | |
2359 | + int retCode = -ENOMEM; | |
2360 | + | |
2361 | + DbgPrint("Daemon_SetMountPoint: %s\n", Path); | |
2362 | + | |
2363 | + replylen = strlen(Path); | |
2364 | + cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen; | |
2365 | + | |
2366 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
2367 | + if (!cmd) | |
2368 | + return -ENOMEM; | |
2369 | + | |
2370 | + cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH; | |
2371 | + cmd->Command.SequenceNumber = 0; | |
2372 | + SC_INITIALIZE(cmd->Command.SessionId); | |
2373 | + cmd->PathLength = replylen; | |
2374 | + | |
2375 | + strcpy(cmd->Path, Path); | |
2376 | + | |
2377 | + replylen = 0; | |
2378 | + | |
2379 | + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); | |
2380 | + if (reply) { | |
2381 | + if (!reply->Reply.ErrorCode) { | |
2382 | + retCode = 0; | |
2383 | + } else { | |
2384 | + retCode = -EIO; | |
2385 | + } | |
2386 | + kfree(reply); | |
2387 | + } | |
2388 | + kfree(cmd); | |
2389 | + return retCode; | |
2390 | +} | |
2391 | + | |
2392 | +/*++======================================================================*/ | |
2393 | +int Daemon_SendDebugCmd(char *Command) | |
2394 | +/* | |
2395 | + * | |
2396 | + * Arguments: | |
2397 | + * | |
2398 | + * Returns: | |
2399 | + * | |
2400 | + * Abstract: | |
2401 | + * | |
2402 | + * Notes: | |
2403 | + * | |
2404 | + * Environment: | |
2405 | + * | |
2406 | + *========================================================================*/ | |
2407 | +{ | |
2408 | + DEBUG_REQUEST cmd; | |
2409 | + PDEBUG_REPLY reply; | |
2410 | + DEBUG_REPLY lreply; | |
2411 | + unsigned long replylen, cmdlen; | |
2412 | + struct data_list dlist[2]; | |
2413 | + | |
2414 | + int retCode = -ENOMEM; | |
2415 | + | |
2416 | + DbgPrint("Daemon_SendDebugCmd: %s\n", Command); | |
2417 | + | |
2418 | + dlist[0].page = NULL; | |
2419 | + dlist[0].offset = (char *)Command; | |
2420 | + dlist[0].len = strlen(Command); | |
2421 | + dlist[0].rwflag = DLREAD; | |
2422 | + | |
2423 | + dlist[1].page = NULL; | |
2424 | + dlist[1].offset = (char *)&lreply; | |
2425 | + dlist[1].len = sizeof(lreply); | |
2426 | + dlist[1].rwflag = DLWRITE; | |
2427 | + | |
2428 | + cmdlen = offsetof(DEBUG_REQUEST, dbgcmd); | |
2429 | + | |
2430 | + cmd.Command.CommandType = VFS_COMMAND_DBG; | |
2431 | + cmd.Command.SequenceNumber = 0; | |
2432 | + SC_INITIALIZE(cmd.Command.SessionId); | |
2433 | + cmd.cmdlen = strlen(Command); | |
2434 | + | |
2435 | + replylen = 0; | |
2436 | + | |
2437 | + retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE); | |
2438 | + if (reply) { | |
2439 | + kfree(reply); | |
2440 | + } | |
2441 | + if (0 == retCode) { | |
2442 | + retCode = lreply.Reply.ErrorCode; | |
2443 | + } | |
2444 | + | |
2445 | + return (retCode); | |
2446 | +} | |
2447 | + | |
2448 | +int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
2449 | +{ | |
2450 | + int retCode = -ENOSYS; | |
2451 | + unsigned long cpylen; | |
2452 | + struct schandle session_id; | |
2453 | + | |
2454 | + session_id = Scope_Get_SessionId(NULL); | |
2455 | + | |
2456 | + switch (cmd) { | |
2457 | + case IOC_LOGIN: | |
2458 | + retCode = daemon_login((struct login *)arg, &session_id); | |
2459 | + break; | |
2460 | + | |
2461 | + case IOC_LOGOUT: | |
2462 | + retCode = daemon_logout((struct logout *) arg, &session_id); | |
2463 | + break; | |
2464 | + case IOC_DEBUGPRINT: | |
2465 | + { | |
2466 | + struct Ioctl_Debug { | |
2467 | + int length; | |
2468 | + char *data; | |
2469 | + } io; | |
2470 | + char *buf; | |
2471 | + io.length = 0; | |
2472 | + cpylen = copy_from_user(&io, (char *)arg, sizeof(io)); | |
2473 | + if (io.length) { | |
2474 | + buf = kmalloc(io.length + 1, GFP_KERNEL); | |
2475 | + if (buf) { | |
2476 | + buf[0] = 0; | |
2477 | + cpylen = | |
2478 | + copy_from_user(buf, io.data, | |
2479 | + io.length); | |
2480 | + buf[io.length] = '\0'; | |
2481 | + DbgPrint("%s", buf); | |
2482 | + kfree(buf); | |
2483 | + retCode = 0; | |
2484 | + } | |
2485 | + } | |
2486 | + break; | |
2487 | + } | |
2488 | + | |
2489 | + case IOC_XPLAT: | |
2490 | + { | |
2491 | + XPLAT data; | |
2492 | + | |
2493 | + cpylen = | |
2494 | + copy_from_user(&data, (void *)arg, sizeof(data)); | |
2495 | + retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000); | |
2496 | + | |
2497 | + switch (data.xfunction) { | |
2498 | + case NWC_GET_MOUNT_PATH: | |
2499 | + DbgPrint | |
2500 | + ("[Daemon_ioctl] Call NwdGetMountPath\n"); | |
2501 | + retCode = NwdGetMountPath(&data); | |
2502 | + break; | |
2503 | + } | |
2504 | + | |
2505 | + DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode); | |
2506 | + break; | |
2507 | + } | |
2508 | + | |
2509 | + } | |
2510 | + return (retCode); | |
2511 | +} | |
2512 | + | |
2513 | +int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, HANDLE CHandle, unsigned char *FHandle, unsigned long Mode, unsigned long Size) | |
2514 | +{ | |
2515 | + daemon_resource_t *resource; | |
2516 | + | |
2517 | + if (FHandle) | |
2518 | + DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%p FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u32 *) & FHandle[2], Mode, Size); | |
2519 | + else | |
2520 | + DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%p\n", DHandle, Type, CHandle); | |
2521 | + | |
2522 | + resource = kmalloc(sizeof(daemon_resource_t), GFP_KERNEL); | |
2523 | + if (!resource) | |
2524 | + return -ENOMEM; | |
2525 | + | |
2526 | + resource->type = Type; | |
2527 | + resource->connection = CHandle; | |
2528 | + if (FHandle) | |
2529 | + memcpy(resource->handle, FHandle, sizeof(resource->handle)); | |
2530 | + else | |
2531 | + memset(resource->handle, 0, sizeof(resource->handle)); | |
2532 | + resource->mode = Mode; | |
2533 | + resource->size = Size; | |
2534 | + write_lock(&DHandle->lock); | |
2535 | + list_add(&resource->list, &DHandle->list); | |
2536 | + write_unlock(&DHandle->lock); | |
2537 | + DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource); | |
2538 | + | |
2539 | + return 0; | |
2540 | +} | |
2541 | + | |
2542 | +/*++======================================================================*/ | |
2543 | +int Daemon_Remove_Resource(daemon_handle_t * DHandle, int Type, HANDLE CHandle, | |
2544 | + unsigned long FHandle) | |
2545 | +/* | |
2546 | + * | |
2547 | + * Arguments: | |
2548 | + * | |
2549 | + * Returns: | |
2550 | + * | |
2551 | + * Abstract: | |
2552 | + * | |
2553 | + * Notes: | |
2554 | + * | |
2555 | + * Environment: | |
2556 | + * | |
2557 | + *========================================================================*/ | |
2558 | +{ | |
2559 | + daemon_resource_t *resource; | |
2560 | + struct list_head *l; | |
2561 | + int retVal = -ENOMEM; | |
2562 | + | |
2563 | + DbgPrint | |
2564 | + ("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%p FHandle=0x%x\n", | |
2565 | + DHandle, Type, CHandle, FHandle); | |
2566 | + | |
2567 | + write_lock(&DHandle->lock); | |
2568 | + | |
2569 | + list_for_each(l, &DHandle->list) { | |
2570 | + resource = list_entry(l, daemon_resource_t, list); | |
2571 | + | |
2572 | + if ((Type == resource->type) && | |
2573 | + (resource->connection == CHandle)) { | |
2574 | + DbgPrint | |
2575 | + ("Daemon_Remove_Resource: Found resource=0x%p\n", | |
2576 | + resource); | |
2577 | + l = l->prev; | |
2578 | + list_del(&resource->list); | |
2579 | + kfree(resource); | |
2580 | + break; | |
2581 | + } | |
2582 | + } | |
2583 | + | |
2584 | + write_unlock(&DHandle->lock); | |
2585 | + | |
2586 | + return (retVal); | |
2587 | +} | |
2588 | + | |
2589 | +int Daemon_Library_open(struct inode *inode, struct file *file) | |
2590 | +{ | |
2591 | + daemon_handle_t *dh; | |
2592 | + | |
2593 | + DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file); | |
2594 | + | |
2595 | + dh = kmalloc(sizeof(daemon_handle_t), GFP_KERNEL); | |
2596 | + if (!dh) | |
2597 | + return -ENOMEM; | |
2598 | + | |
2599 | + file->private_data = dh; | |
2600 | + INIT_LIST_HEAD(&dh->list); | |
2601 | + rwlock_init(&dh->lock); | |
2602 | + dh->session = Scope_Get_SessionId(NULL); | |
2603 | + | |
2604 | + return 0; | |
2605 | +} | |
2606 | + | |
2607 | +/*++======================================================================*/ | |
2608 | +int Daemon_Library_close(struct inode *inode, struct file *file) | |
2609 | +/* | |
2610 | + * | |
2611 | + * Arguments: | |
2612 | + * | |
2613 | + * Returns: | |
2614 | + * | |
2615 | + * Abstract: | |
2616 | + * | |
2617 | + * Notes: | |
2618 | + * | |
2619 | + * Environment: | |
2620 | + * | |
2621 | + *========================================================================*/ | |
2622 | +{ | |
2623 | + daemon_handle_t *dh; | |
2624 | + daemon_resource_t *resource; | |
2625 | + struct list_head *l; | |
2626 | + | |
2627 | + char commanddata[sizeof(XPLAT_CALL_REQUEST) + sizeof(NwdCCloseConn)]; | |
2628 | + PXPLAT_CALL_REQUEST cmd; | |
2629 | + PXPLAT_CALL_REPLY reply; | |
2630 | + PNwdCCloseConn nwdClose; | |
2631 | + unsigned long cmdlen, replylen; | |
2632 | + | |
2633 | + DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file); | |
2634 | + if (file->private_data) { | |
2635 | + dh = (daemon_handle_t *) file->private_data; | |
2636 | + | |
2637 | + list_for_each(l, &dh->list) { | |
2638 | + resource = list_entry(l, daemon_resource_t, list); | |
2639 | + | |
2640 | + if (DH_TYPE_STREAM == resource->type) { | |
2641 | + Novfs_Close_Stream(resource->connection, | |
2642 | + resource->handle, | |
2643 | + dh->session); | |
2644 | + } else if (DH_TYPE_CONNECTION == resource->type) { | |
2645 | + cmd = (PXPLAT_CALL_REQUEST) commanddata; | |
2646 | + cmdlen = | |
2647 | + offsetof(XPLAT_CALL_REQUEST, | |
2648 | + data) + sizeof(NwdCCloseConn); | |
2649 | + cmd->Command.CommandType = | |
2650 | + VFS_COMMAND_XPLAT_CALL; | |
2651 | + cmd->Command.SequenceNumber = 0; | |
2652 | + cmd->Command.SessionId = dh->session; | |
2653 | + cmd->NwcCommand = NWC_CLOSE_CONN; | |
2654 | + | |
2655 | + cmd->dataLen = sizeof(NwdCCloseConn); | |
2656 | + nwdClose = (PNwdCCloseConn) cmd->data; | |
2657 | + nwdClose->ConnHandle = | |
2658 | + (HANDLE) resource->connection; | |
2659 | + | |
2660 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, | |
2661 | + 0, (void **)&reply, | |
2662 | + &replylen, 0); | |
2663 | + if (reply) | |
2664 | + kfree(reply); | |
2665 | + } | |
2666 | + l = l->prev; | |
2667 | + list_del(&resource->list); | |
2668 | + kfree(resource); | |
2669 | + } | |
2670 | + kfree(dh); | |
2671 | + file->private_data = NULL; | |
2672 | + } | |
2673 | + | |
2674 | + return (0); | |
2675 | +} | |
2676 | + | |
2677 | +ssize_t Daemon_Library_read(struct file *file, char __user *buf, size_t len, loff_t *off) | |
2678 | +{ | |
2679 | + daemon_handle_t *dh; | |
2680 | + daemon_resource_t *resource; | |
2681 | + | |
2682 | + size_t thisread, totalread = 0; | |
2683 | + loff_t offset = *off; | |
2684 | + | |
2685 | + DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n", file, len, | |
2686 | + *off); | |
2687 | + | |
2688 | + if (file->private_data) { | |
2689 | + dh = file->private_data; | |
2690 | + read_lock(&dh->lock); | |
2691 | + if (&dh->list != dh->list.next) { | |
2692 | + resource = | |
2693 | + list_entry(dh->list.next, daemon_resource_t, list); | |
2694 | + | |
2695 | + if (DH_TYPE_STREAM == resource->type) { | |
2696 | + while (len > 0 && (offset < resource->size)) { | |
2697 | + thisread = len; | |
2698 | + if (Novfs_Read_Stream | |
2699 | + (resource->connection, | |
2700 | + resource->handle, buf, &thisread, | |
2701 | + &offset, 1, dh->session) | |
2702 | + || !thisread) { | |
2703 | + break; | |
2704 | + } | |
2705 | + len -= thisread; | |
2706 | + buf += thisread; | |
2707 | + offset += thisread; | |
2708 | + totalread += thisread; | |
2709 | + } | |
2710 | + } | |
2711 | + } | |
2712 | + read_unlock(&dh->lock); | |
2713 | + } | |
2714 | + *off = offset; | |
2715 | + DbgPrint("Daemon_Library_read return = 0x%x\n", totalread); | |
2716 | + return (totalread); | |
2717 | +} | |
2718 | + | |
2719 | +ssize_t Daemon_Library_write(struct file *file, const char __user *buf, size_t len, loff_t *off) | |
2720 | +{ | |
2721 | + daemon_handle_t *dh; | |
2722 | + daemon_resource_t *resource; | |
2723 | + | |
2724 | + size_t thiswrite, totalwrite = -EINVAL; | |
2725 | + loff_t offset = *off; | |
2726 | + int status; | |
2727 | + | |
2728 | + DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n", file, len, | |
2729 | + *off); | |
2730 | + | |
2731 | + if (file->private_data) { | |
2732 | + dh = file->private_data; | |
2733 | + write_lock(&dh->lock); | |
2734 | + if (&dh->list != dh->list.next) { | |
2735 | + resource = | |
2736 | + list_entry(dh->list.next, daemon_resource_t, list); | |
2737 | + | |
2738 | + if ((DH_TYPE_STREAM == resource->type) && (len >= 0)) { | |
2739 | + totalwrite = 0; | |
2740 | + do { | |
2741 | + thiswrite = len; | |
2742 | + status = | |
2743 | + Novfs_Write_Stream(resource-> | |
2744 | + connection, | |
2745 | + resource->handle, | |
2746 | + (void *)buf, | |
2747 | + &thiswrite, | |
2748 | + &offset, | |
2749 | + dh->session); | |
2750 | + if (status || !thiswrite) { | |
2751 | + /* | |
2752 | + * If len is zero then the file will have just been | |
2753 | + * truncated to offset. Update size. | |
2754 | + */ | |
2755 | + if (!status && !len) { | |
2756 | + resource->size = offset; | |
2757 | + } | |
2758 | + totalwrite = status; | |
2759 | + break; | |
2760 | + } | |
2761 | + len -= thiswrite; | |
2762 | + buf += thiswrite; | |
2763 | + offset += thiswrite; | |
2764 | + totalwrite += thiswrite; | |
2765 | + if (offset > resource->size) { | |
2766 | + resource->size = offset; | |
2767 | + } | |
2768 | + } while (len > 0); | |
2769 | + } | |
2770 | + } | |
2771 | + write_unlock(&dh->lock); | |
2772 | + } | |
2773 | + *off = offset; | |
2774 | + DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite); | |
2775 | + | |
2776 | + return (totalwrite); | |
2777 | +} | |
2778 | + | |
2779 | +/*++======================================================================*/ | |
2780 | +loff_t Daemon_Library_llseek(struct file * file, loff_t offset, int origin) | |
2781 | +/* | |
2782 | + * | |
2783 | + * Arguments: | |
2784 | + * | |
2785 | + * Returns: | |
2786 | + * | |
2787 | + * Abstract: | |
2788 | + * | |
2789 | + * Notes: | |
2790 | + * | |
2791 | + * Environment: | |
2792 | + * | |
2793 | + *========================================================================*/ | |
2794 | +{ | |
2795 | + daemon_handle_t *dh; | |
2796 | + daemon_resource_t *resource; | |
2797 | + | |
2798 | + loff_t retVal = -EINVAL; | |
2799 | + | |
2800 | + DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", | |
2801 | + file, offset, origin); | |
2802 | + | |
2803 | + if (file->private_data) { | |
2804 | + dh = file->private_data; | |
2805 | + read_lock(&dh->lock); | |
2806 | + if (&dh->list != dh->list.next) { | |
2807 | + resource = | |
2808 | + list_entry(dh->list.next, daemon_resource_t, list); | |
2809 | + | |
2810 | + if (DH_TYPE_STREAM == resource->type) { | |
2811 | + switch (origin) { | |
2812 | + case 2: | |
2813 | + offset += resource->size; | |
2814 | + break; | |
2815 | + case 1: | |
2816 | + offset += file->f_pos; | |
2817 | + } | |
2818 | + if (offset >= 0) { | |
2819 | + if (offset != file->f_pos) { | |
2820 | + file->f_pos = offset; | |
2821 | + file->f_version = 0; | |
2822 | + } | |
2823 | + retVal = offset; | |
2824 | + } | |
2825 | + } | |
2826 | + } | |
2827 | + read_unlock(&dh->lock); | |
2828 | + } | |
2829 | + | |
2830 | + DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal); | |
2831 | + | |
2832 | + return retVal; | |
2833 | +} | |
2834 | + | |
2835 | +int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | |
2836 | +{ | |
2837 | + int retCode = -ENOSYS; | |
2838 | + daemon_handle_t *dh; | |
2839 | + HANDLE handle = NULL; | |
2840 | + unsigned long cpylen; | |
2841 | + | |
2842 | + dh = file->private_data; | |
2843 | + | |
2844 | + DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%p dh=0x%p\n", file, | |
2845 | + cmd, arg, dh); | |
2846 | + | |
2847 | + if (dh) { | |
2848 | + | |
2849 | + switch (cmd) { | |
2850 | + case IOC_LOGIN: | |
2851 | + retCode = daemon_login((struct login *)arg, &dh->session); | |
2852 | + break; | |
2853 | + | |
2854 | + case IOC_LOGOUT: | |
2855 | + retCode = daemon_logout((struct logout *)arg, &dh->session); | |
2856 | + break; | |
2857 | + | |
2858 | + case IOC_DEBUGPRINT: | |
2859 | + { | |
2860 | + struct Ioctl_Debug { | |
2861 | + int length; | |
2862 | + char *data; | |
2863 | + } io; | |
2864 | + char *buf; | |
2865 | + io.length = 0; | |
2866 | + cpylen = | |
2867 | + copy_from_user(&io, (void *)arg, | |
2868 | + sizeof(io)); | |
2869 | + if (io.length) { | |
2870 | + buf = kmalloc(io.length + 1, GFP_KERNEL); | |
2871 | + if (buf) { | |
2872 | + buf[0] = 0; | |
2873 | + cpylen = copy_from_user(buf, io.data, io.length); | |
2874 | + buf[io.length] = '\0'; | |
2875 | + DbgPrint("%s", buf); | |
2876 | + kfree(buf); | |
2877 | + retCode = 0; | |
2878 | + } | |
2879 | + } | |
2880 | + break; | |
2881 | + } | |
2882 | + | |
2883 | + case IOC_XPLAT: | |
2884 | + { | |
2885 | + XPLAT data; | |
2886 | + | |
2887 | + cpylen = | |
2888 | + copy_from_user(&data, (void *)arg, | |
2889 | + sizeof(data)); | |
2890 | + retCode = | |
2891 | + ((data. | |
2892 | + xfunction & 0x0000FFFF) | 0xCC000000); | |
2893 | + | |
2894 | + switch (data.xfunction) { | |
2895 | + case NWC_OPEN_CONN_BY_NAME: | |
2896 | + DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n"); | |
2897 | + retCode = NwOpenConnByName(&data, &handle, dh->session); | |
2898 | + if (!retCode) | |
2899 | + Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, NULL, 0, 0); | |
2900 | + break; | |
2901 | + | |
2902 | + case NWC_OPEN_CONN_BY_ADDRESS: | |
2903 | + DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n"); | |
2904 | + retCode = NwOpenConnByAddr(&data, &handle, dh->session); | |
2905 | + if (!retCode) | |
2906 | + Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, NULL, 0, 0); | |
2907 | + break; | |
2908 | + | |
2909 | + case NWC_OPEN_CONN_BY_REFERENCE: | |
2910 | + DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n"); | |
2911 | + retCode = NwOpenConnByRef(&data, &handle, dh->session); | |
2912 | + if (!retCode) | |
2913 | + Daemon_Added_Resource(dh, | |
2914 | + DH_TYPE_CONNECTION, | |
2915 | + handle, NULL, | |
2916 | + 0, 0); | |
2917 | + break; | |
2918 | + | |
2919 | + case NWC_SYS_CLOSE_CONN: | |
2920 | + DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n"); | |
2921 | + retCode = NwSysConnClose(&data, (unsigned long *)&handle, dh->session); | |
2922 | + Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0); | |
2923 | + break; | |
2924 | + | |
2925 | + case NWC_CLOSE_CONN: | |
2926 | + DbgPrint | |
2927 | + ("[VFS XPLAT] Call NwCloseConn\n"); | |
2928 | + retCode = | |
2929 | + NwConnClose(&data, &handle, | |
2930 | + dh->session); | |
2931 | + Daemon_Remove_Resource(dh, | |
2932 | + DH_TYPE_CONNECTION, | |
2933 | + handle, 0); | |
2934 | + break; | |
2935 | + | |
2936 | + case NWC_LOGIN_IDENTITY: | |
2937 | + DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n"); | |
2938 | + retCode = NwLoginIdentity(&data, &dh->session); | |
2939 | + break; | |
2940 | + | |
2941 | + case NWC_RAW_NCP_REQUEST: | |
2942 | + DbgPrint("[VFS XPLAT] Send Raw NCP Request\n"); | |
2943 | + retCode = NwRawSend(&data, dh->session); | |
2944 | + break; | |
2945 | + | |
2946 | + case NWC_AUTHENTICATE_CONN_WITH_ID: | |
2947 | + DbgPrint | |
2948 | + ("[VFS XPLAT] Authenticate Conn With ID\n"); | |
2949 | + retCode = | |
2950 | + NwAuthConnWithId(&data, | |
2951 | + dh->session); | |
2952 | + break; | |
2953 | + | |
2954 | + case NWC_UNAUTHENTICATE_CONN: | |
2955 | + DbgPrint | |
2956 | + ("[VFS XPLAT] UnAuthenticate Conn With ID\n"); | |
2957 | + retCode = | |
2958 | + NwUnAuthenticate(&data, | |
2959 | + dh->session); | |
2960 | + break; | |
2961 | + | |
2962 | + case NWC_LICENSE_CONN: | |
2963 | + DbgPrint("Call NwLicenseConn\n"); | |
2964 | + retCode = | |
2965 | + NwLicenseConn(&data, dh->session); | |
2966 | + break; | |
2967 | + | |
2968 | + case NWC_LOGOUT_IDENTITY: | |
2969 | + DbgPrint | |
2970 | + ("[VFS XPLAT] Call NwLogoutIdentity\n"); | |
2971 | + retCode = | |
2972 | + NwLogoutIdentity(&data, | |
2973 | + dh->session); | |
2974 | + break; | |
2975 | + | |
2976 | + case NWC_UNLICENSE_CONN: | |
2977 | + DbgPrint | |
2978 | + ("[VFS XPLAT] Call NwUnlicense\n"); | |
2979 | + retCode = | |
2980 | + NwUnlicenseConn(&data, dh->session); | |
2981 | + break; | |
2982 | + | |
2983 | + case NWC_GET_CONN_INFO: | |
2984 | + DbgPrint | |
2985 | + ("[VFS XPLAT] Call NwGetConnInfo\n"); | |
2986 | + retCode = | |
2987 | + NwGetConnInfo(&data, dh->session); | |
2988 | + break; | |
2989 | + | |
2990 | + case NWC_SET_CONN_INFO: | |
2991 | + DbgPrint | |
2992 | + ("[VFS XPLAT] Call NwGetConnInfo\n"); | |
2993 | + retCode = | |
2994 | + NwSetConnInfo(&data, dh->session); | |
2995 | + break; | |
2996 | + | |
2997 | + case NWC_SCAN_CONN_INFO: | |
2998 | + DbgPrint | |
2999 | + ("[VFS XPLAT] Call NwScanConnInfo\n"); | |
3000 | + retCode = | |
3001 | + NwScanConnInfo(&data, dh->session); | |
3002 | + break; | |
3003 | + | |
3004 | + case NWC_GET_IDENTITY_INFO: | |
3005 | + DbgPrint | |
3006 | + ("[VFS XPLAT] Call NwGetIdentityInfo\n"); | |
3007 | + retCode = | |
3008 | + NwGetIdentityInfo(&data, | |
3009 | + dh->session); | |
3010 | + break; | |
3011 | + | |
3012 | + case NWC_GET_REQUESTER_VERSION: | |
3013 | + DbgPrint | |
3014 | + ("[VFS XPLAT] Call NwGetDaemonVersion\n"); | |
3015 | + retCode = | |
3016 | + NwGetDaemonVersion(&data, | |
3017 | + dh->session); | |
3018 | + break; | |
3019 | + | |
3020 | + case NWC_GET_PREFERRED_DS_TREE: | |
3021 | + DbgPrint | |
3022 | + ("[VFS XPLAT] Call NwcGetPreferredDsTree\n"); | |
3023 | + retCode = | |
3024 | + NwcGetPreferredDSTree(&data, | |
3025 | + dh->session); | |
3026 | + break; | |
3027 | + | |
3028 | + case NWC_SET_PREFERRED_DS_TREE: | |
3029 | + DbgPrint | |
3030 | + ("[VFS XPLAT] Call NwcSetPreferredDsTree\n"); | |
3031 | + retCode = | |
3032 | + NwcSetPreferredDSTree(&data, | |
3033 | + dh->session); | |
3034 | + break; | |
3035 | + | |
3036 | + case NWC_GET_DEFAULT_NAME_CONTEXT: | |
3037 | + DbgPrint | |
3038 | + ("[VFS XPLAT] Call NwcGetDefaultNameContext\n"); | |
3039 | + retCode = | |
3040 | + NwcGetDefaultNameCtx(&data, | |
3041 | + dh->session); | |
3042 | + break; | |
3043 | + | |
3044 | + case NWC_SET_DEFAULT_NAME_CONTEXT: | |
3045 | + DbgPrint | |
3046 | + ("[VFS XPLAT] Call NwcSetDefaultNameContext\n"); | |
3047 | + retCode = | |
3048 | + NwcSetDefaultNameCtx(&data, | |
3049 | + dh->session); | |
3050 | + break; | |
3051 | + | |
3052 | + case NWC_QUERY_FEATURE: | |
3053 | + DbgPrint | |
3054 | + ("[VFS XPLAT] Call NwQueryFeature\n"); | |
3055 | + retCode = | |
3056 | + NwQueryFeature(&data, dh->session); | |
3057 | + break; | |
3058 | + | |
3059 | + case NWC_GET_TREE_MONITORED_CONN_REF: | |
3060 | + DbgPrint | |
3061 | + ("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n"); | |
3062 | + retCode = | |
3063 | + NwcGetTreeMonitoredConn(&data, | |
3064 | + dh-> | |
3065 | + session); | |
3066 | + break; | |
3067 | + | |
3068 | + case NWC_ENUMERATE_IDENTITIES: | |
3069 | + DbgPrint | |
3070 | + ("[VFS XPLAT] Call NwcEnumerateIdentities\n"); | |
3071 | + retCode = | |
3072 | + NwcEnumIdentities(&data, | |
3073 | + dh->session); | |
3074 | + break; | |
3075 | + | |
3076 | + case NWC_CHANGE_KEY: | |
3077 | + DbgPrint | |
3078 | + ("[VFS XPLAT] Call NwcChangeAuthKey\n"); | |
3079 | + retCode = | |
3080 | + NwcChangeAuthKey(&data, | |
3081 | + dh->session); | |
3082 | + break; | |
3083 | + | |
3084 | + case NWC_CONVERT_LOCAL_HANDLE: | |
3085 | + DbgPrint | |
3086 | + ("[VFS XPLAT] Call NwdConvertLocalHandle\n"); | |
3087 | + retCode = | |
3088 | + NwdConvertLocalHandle(&data, dh); | |
3089 | + break; | |
3090 | + | |
3091 | + case NWC_CONVERT_NETWARE_HANDLE: | |
3092 | + DbgPrint | |
3093 | + ("[VFS XPLAT] Call NwdConvertNetwareHandle\n"); | |
3094 | + retCode = | |
3095 | + NwdConvertNetwareHandle(&data, dh); | |
3096 | + break; | |
3097 | + | |
3098 | + case NWC_SET_PRIMARY_CONN: | |
3099 | + DbgPrint | |
3100 | + ("[VFS XPLAT] Call NwcSetPrimaryConn\n"); | |
3101 | + retCode = | |
3102 | + NwcSetPrimaryConn(&data, | |
3103 | + dh->session); | |
3104 | + break; | |
3105 | + | |
3106 | + case NWC_GET_PRIMARY_CONN: | |
3107 | + DbgPrint | |
3108 | + ("[VFS XPLAT] Call NwcGetPrimaryConn\n"); | |
3109 | + retCode = | |
3110 | + NwcGetPrimaryConn(&data, | |
3111 | + dh->session); | |
3112 | + break; | |
3113 | + | |
3114 | + case NWC_MAP_DRIVE: | |
3115 | + DbgPrint("[VFS XPLAT] Call NwcMapDrive\n"); | |
3116 | + retCode = NwdSetMapDrive(&data, dh->session); | |
3117 | + break; | |
3118 | + | |
3119 | + case NWC_UNMAP_DRIVE: | |
3120 | + DbgPrint | |
3121 | + ("[VFS XPLAT] Call NwcUnMapDrive\n"); | |
3122 | + retCode = NwdUnMapDrive(&data, dh->session); | |
3123 | + break; | |
3124 | + | |
3125 | + case NWC_ENUMERATE_DRIVES: | |
3126 | + DbgPrint | |
3127 | + ("[VFS XPLAT] Call NwcEnumerateDrives\n"); | |
3128 | + retCode = | |
3129 | + NwcEnumerateDrives(&data, | |
3130 | + dh->session); | |
3131 | + break; | |
3132 | + | |
3133 | + case NWC_GET_MOUNT_PATH: | |
3134 | + DbgPrint | |
3135 | + ("[VFS XPLAT] Call NwdGetMountPath\n"); | |
3136 | + retCode = NwdGetMountPath(&data); | |
3137 | + break; | |
3138 | + | |
3139 | + case NWC_GET_BROADCAST_MESSAGE: | |
3140 | + DbgPrint | |
3141 | + ("[VSF XPLAT Call NwdGetBroadcastMessage\n"); | |
3142 | + retCode = | |
3143 | + NwcGetBroadcastMessage(&data, | |
3144 | + dh->session); | |
3145 | + break; | |
3146 | + | |
3147 | + case NWC_SET_KEY: | |
3148 | + DbgPrint("[VSF XPLAT Call NwdSetKey\n"); | |
3149 | + retCode = | |
3150 | + NwdSetKeyValue(&data, dh->session); | |
3151 | + break; | |
3152 | + | |
3153 | + case NWC_VERIFY_KEY: | |
3154 | + DbgPrint | |
3155 | + ("[VSF XPLAT Call NwdVerifyKey\n"); | |
3156 | + retCode = | |
3157 | + NwdVerifyKeyValue(&data, | |
3158 | + dh->session); | |
3159 | + break; | |
3160 | + | |
3161 | + case NWC_RAW_NCP_REQUEST_ALL: | |
3162 | + case NWC_NDS_RESOLVE_NAME_TO_ID: | |
3163 | + case NWC_FRAGMENT_REQUEST: | |
3164 | + case NWC_GET_CONFIGURED_NSPS: | |
3165 | + default: | |
3166 | + break; | |
3167 | + | |
3168 | + } | |
3169 | + | |
3170 | + DbgPrint("[NOVFS XPLAT] status Code = %X\n", | |
3171 | + retCode); | |
3172 | + break; | |
3173 | + } | |
3174 | + } | |
3175 | + } | |
3176 | + | |
3177 | + return (retCode); | |
3178 | +} | |
3179 | + | |
3180 | +unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table) | |
3181 | +{ | |
3182 | + daemon_command_t *que; | |
3183 | + unsigned int mask = POLLOUT | POLLWRNORM; | |
3184 | + | |
3185 | + que = get_next_queue(0); | |
3186 | + if (que) | |
3187 | + mask |= (POLLIN | POLLRDNORM); | |
3188 | + return mask; | |
3189 | +} | |
3190 | + | |
3191 | +int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle) | |
3192 | +{ | |
3193 | + int retVal; | |
3194 | + NwcConvertNetWareHandle nh; | |
3195 | + unsigned long cpylen; | |
3196 | + | |
3197 | + DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle); | |
3198 | + | |
3199 | + cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle)); | |
3200 | + | |
3201 | + retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, | |
3202 | + Uint32toHandle(nh.ConnHandle), | |
3203 | + nh.NetWareHandle, nh.uAccessMode, | |
3204 | + nh.uFileSize); | |
3205 | + | |
3206 | + return retVal; | |
3207 | +} | |
3208 | + | |
3209 | +/*++======================================================================*/ | |
3210 | +int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t * DHandle) | |
3211 | +/* | |
3212 | + * | |
3213 | + * Arguments: | |
3214 | + * | |
3215 | + * Returns: | |
3216 | + * | |
3217 | + * Abstract: | |
3218 | + * | |
3219 | + * Notes: | |
3220 | + * | |
3221 | + * Environment: | |
3222 | + * | |
3223 | + *========================================================================*/ | |
3224 | +{ | |
3225 | + int retVal = NWE_REQUESTER_FAILURE; | |
3226 | + daemon_resource_t *resource; | |
3227 | + NwcConvertLocalHandle lh; | |
3228 | + struct list_head *l; | |
3229 | + unsigned long cpylen; | |
3230 | + | |
3231 | + DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle); | |
3232 | + | |
3233 | + read_lock(&DHandle->lock); | |
3234 | + | |
3235 | + list_for_each(l, &DHandle->list) { | |
3236 | + resource = list_entry(l, daemon_resource_t, list); | |
3237 | + | |
3238 | + if (DH_TYPE_STREAM == resource->type) { | |
3239 | + lh.uConnReference = | |
3240 | + HandletoUint32(resource->connection); | |
3241 | + | |
3242 | +//sgled memcpy(lh.NwWareHandle, resource->handle, sizeof(resource->handle)); | |
3243 | + memcpy(lh.NetWareHandle, resource->handle, sizeof(resource->handle)); //sgled | |
3244 | + if (pdata->repLen >= sizeof(NwcConvertLocalHandle)) { | |
3245 | + cpylen = | |
3246 | + copy_to_user(pdata->repData, &lh, | |
3247 | + sizeof(NwcConvertLocalHandle)); | |
3248 | + retVal = 0; | |
3249 | + } else { | |
3250 | + retVal = NWE_BUFFER_OVERFLOW; | |
3251 | + } | |
3252 | + break; | |
3253 | + } | |
3254 | + } | |
3255 | + | |
3256 | + read_unlock(&DHandle->lock); | |
3257 | + | |
3258 | + return (retVal); | |
3259 | +} | |
3260 | + | |
3261 | +/*++======================================================================*/ | |
3262 | +int NwdGetMountPath(PXPLAT pdata) | |
3263 | +/* | |
3264 | + * | |
3265 | + * Arguments: | |
3266 | + * | |
3267 | + * Returns: | |
3268 | + * | |
3269 | + * Abstract: | |
3270 | + * | |
3271 | + * Notes: | |
3272 | + * | |
3273 | + * Environment: | |
3274 | + * | |
3275 | + *========================================================================*/ | |
3276 | +{ | |
3277 | + int retVal = NWE_REQUESTER_FAILURE; | |
3278 | + int len; | |
3279 | + unsigned long cpylen; | |
3280 | + NwcGetMountPath mp; | |
3281 | + | |
3282 | + cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen); | |
3283 | + | |
3284 | + if (Novfs_CurrentMount) { | |
3285 | + | |
3286 | + len = strlen(Novfs_CurrentMount) + 1; | |
3287 | + if ((len > mp.MountPathLen) && mp.pMountPath) { | |
3288 | + retVal = NWE_BUFFER_OVERFLOW; | |
3289 | + } else { | |
3290 | + if (mp.pMountPath) { | |
3291 | + cpylen = | |
3292 | + copy_to_user(mp.pMountPath, | |
3293 | + Novfs_CurrentMount, len); | |
3294 | + } | |
3295 | + retVal = 0; | |
3296 | + } | |
3297 | + | |
3298 | + mp.MountPathLen = len; | |
3299 | + | |
3300 | + if (pdata->repData && (pdata->repLen >= sizeof(mp))) { | |
3301 | + cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp)); | |
3302 | + } | |
3303 | + } | |
3304 | + | |
3305 | + return (retVal); | |
3306 | +} | |
3307 | + | |
3308 | +static int NwdSetMapDrive(PXPLAT pdata, session_t Session) | |
3309 | +{ | |
3310 | + int retVal; | |
3311 | + NwcMapDriveEx symInfo; | |
3312 | + char *path; | |
3313 | + drive_map_t *drivemap, *dm; | |
3314 | + struct list_head *list; | |
3315 | + | |
3316 | + retVal = NwcSetMapDrive(pdata, Session); | |
3317 | + if (retVal) | |
3318 | + return retVal; | |
3319 | + | |
3320 | + if (copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo))) | |
3321 | + return -EFAULT; | |
3322 | + | |
3323 | + drivemap = kmalloc(sizeof(drive_map_t) + symInfo.linkOffsetLength, GFP_KERNEL); | |
3324 | + if (!drivemap) | |
3325 | + return -ENOMEM; | |
3326 | + | |
3327 | + path = (char *)pdata->reqData; | |
3328 | + path += symInfo.linkOffset; | |
3329 | + if (copy_from_user(drivemap->name, path, symInfo.linkOffsetLength)) { | |
3330 | + kfree(drivemap); | |
3331 | + return -EFAULT; | |
3332 | + } | |
3333 | + | |
3334 | + drivemap->session = Session; | |
3335 | + drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength - 1); | |
3336 | + drivemap->namelen = symInfo.linkOffsetLength - 1; | |
3337 | + DbgPrint("NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name); | |
3338 | + | |
3339 | + dm = (drive_map_t *) & DriveMapList.next; | |
3340 | + | |
3341 | + down(&DriveMapLock); | |
3342 | + | |
3343 | + list_for_each(list, &DriveMapList) { | |
3344 | + dm = list_entry(list, drive_map_t, list); | |
3345 | + DbgPrint("NwdSetMapDrive: dm=0x%p\n" | |
3346 | + " hash: 0x%x\n" | |
3347 | + " namelen: %d\n" | |
3348 | + " name: %s\n", | |
3349 | + dm, dm->hash, dm->namelen, dm->name); | |
3350 | + | |
3351 | + if (drivemap->hash == dm->hash) { | |
3352 | + if (0 == | |
3353 | + strcmp(dm->name, drivemap->name)) { | |
3354 | + dm = NULL; | |
3355 | + break; | |
3356 | + } | |
3357 | + } else if (drivemap->hash < dm->hash) { | |
3358 | + break; | |
3359 | + } | |
3360 | + } | |
3361 | + | |
3362 | + if (dm) { | |
3363 | + if ((dm == (drive_map_t *) & DriveMapList) || | |
3364 | + (dm->hash < drivemap->hash)) { | |
3365 | + list_add(&drivemap->list, &dm->list); | |
3366 | + } else { | |
3367 | + list_add_tail(&drivemap->list, | |
3368 | + &dm->list); | |
3369 | + } | |
3370 | + } else { | |
3371 | + kfree(drivemap); | |
3372 | + } | |
3373 | + up(&DriveMapLock); | |
3374 | + | |
3375 | + return (retVal); | |
3376 | +} | |
3377 | + | |
3378 | +static int NwdUnMapDrive(PXPLAT pdata, session_t Session) | |
3379 | +{ | |
3380 | + int retVal = NWE_REQUESTER_FAILURE; | |
3381 | + NwcUnmapDriveEx symInfo; | |
3382 | + char *path; | |
3383 | + drive_map_t *dm; | |
3384 | + struct list_head *list; | |
3385 | + unsigned long hash; | |
3386 | + | |
3387 | + retVal = NwcUnMapDrive(pdata, Session); | |
3388 | + if (retVal) | |
3389 | + return retVal; | |
3390 | + | |
3391 | + if (copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo))) | |
3392 | + return -EFAULT; | |
3393 | + | |
3394 | + path = kmalloc(symInfo.linkLen, GFP_KERNEL); | |
3395 | + if (!path) | |
3396 | + return -ENOMEM; | |
3397 | + | |
3398 | + if (copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen)) { | |
3399 | + kfree(path); | |
3400 | + return -EFAULT; | |
3401 | + } | |
3402 | + | |
3403 | + hash = full_name_hash(path, symInfo.linkLen - 1); | |
3404 | + DbgPrint("NwdUnMapDrive: hash=0x%x path=%s\n", hash, path); | |
3405 | + | |
3406 | + dm = NULL; | |
3407 | + | |
3408 | + down(&DriveMapLock); | |
3409 | + | |
3410 | + list_for_each(list, &DriveMapList) { | |
3411 | + dm = list_entry(list, drive_map_t, list); | |
3412 | + DbgPrint("NwdUnMapDrive: dm=0x%p %s\n" | |
3413 | + " hash: 0x%x\n" | |
3414 | + " namelen: %d\n", | |
3415 | + dm, dm->name, dm->hash, dm->namelen); | |
3416 | + | |
3417 | + if (hash == dm->hash) { | |
3418 | + if (0 == strcmp(dm->name, path)) { | |
3419 | + break; | |
3420 | + } | |
3421 | + } else if (hash < dm->hash) { | |
3422 | + dm = NULL; | |
3423 | + break; | |
3424 | + } | |
3425 | + } | |
3426 | + | |
3427 | + if (dm) { | |
3428 | + DbgPrint("NwdUnMapDrive: Remove dm=0x%p %s\n" | |
3429 | + " hash: 0x%x\n" | |
3430 | + " namelen: %d\n", | |
3431 | + dm, dm->name, dm->hash, dm->namelen); | |
3432 | + list_del(&dm->list); | |
3433 | + kfree(dm); | |
3434 | + } | |
3435 | + | |
3436 | + up(&DriveMapLock); | |
3437 | + | |
3438 | + return retVal; | |
3439 | +} | |
3440 | + | |
3441 | +/*++======================================================================*/ | |
3442 | +void RemoveDriveMaps(void) | |
3443 | +/* | |
3444 | + * | |
3445 | + * Arguments: | |
3446 | + * | |
3447 | + * Returns: | |
3448 | + * | |
3449 | + * Abstract: | |
3450 | + * | |
3451 | + * Notes: | |
3452 | + * | |
3453 | + * Environment: | |
3454 | + * | |
3455 | + *========================================================================*/ | |
3456 | +{ | |
3457 | + drive_map_t *dm; | |
3458 | + struct list_head *list; | |
3459 | + | |
3460 | + down(&DriveMapLock); | |
3461 | + list_for_each(list, &DriveMapList) { | |
3462 | + dm = list_entry(list, drive_map_t, list); | |
3463 | + | |
3464 | + DbgPrint("RemoveDriveMap: dm=0x%p\n" | |
3465 | + " hash: 0x%x\n" | |
3466 | + " namelen: %d\n" | |
3467 | + " name: %s\n", | |
3468 | + dm, dm->hash, dm->namelen, dm->name); | |
3469 | + local_unlink(dm->name); | |
3470 | + list = list->prev; | |
3471 | + list_del(&dm->list); | |
3472 | + kfree(dm); | |
3473 | + } | |
3474 | + up(&DriveMapLock); | |
3475 | +} | |
3476 | + | |
3477 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) | |
3478 | +/*++======================================================================*/ | |
3479 | +int local_unlink(const char *pathname) | |
3480 | +{ | |
3481 | + int error; | |
3482 | + struct dentry *dentry; | |
3483 | + struct nameidata nd; | |
3484 | + struct inode *inode = NULL; | |
3485 | + | |
3486 | + DbgPrint("local_unlink: %s\n", pathname); | |
3487 | + error = path_lookup(pathname, LOOKUP_PARENT, &nd); | |
3488 | + DbgPrint("local_unlink: path_lookup %d\n", error); | |
3489 | + if (!error) { | |
3490 | + error = -EISDIR; | |
3491 | + if (nd.last_type == LAST_NORM) { | |
3492 | + dentry = lookup_create(&nd, 1); | |
3493 | + DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry); | |
3494 | + | |
3495 | + error = PTR_ERR(dentry); | |
3496 | + if (!IS_ERR(dentry)) { | |
3497 | + if (nd.last.name[nd.last.len]) { | |
3498 | + error = | |
3499 | + !dentry-> | |
3500 | + d_inode ? -ENOENT : S_ISDIR(dentry-> | |
3501 | + d_inode-> | |
3502 | + i_mode) | |
3503 | + ? -EISDIR : -ENOTDIR; | |
3504 | + } else { | |
3505 | + inode = dentry->d_inode; | |
3506 | + if (inode) { | |
3507 | + atomic_inc(&inode->i_count); | |
3508 | + } | |
3509 | + error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt); | |
3510 | + DbgPrint | |
3511 | + ("local_unlink: vfs_unlink %d\n", | |
3512 | + error); | |
3513 | + } | |
3514 | + dput(dentry); | |
3515 | + } | |
3516 | + mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | |
3517 | + | |
3518 | + } | |
3519 | + path_put(&nd.path); | |
3520 | + } | |
3521 | + | |
3522 | + if (inode) { | |
3523 | + iput(inode); /* truncate the inode here */ | |
3524 | + } | |
3525 | + | |
3526 | + DbgPrint("local_unlink: error=%d\n", error); | |
3527 | + return error; | |
3528 | +} | |
3529 | + | |
3530 | +#else | |
3531 | +/*++======================================================================*/ | |
3532 | +int local_unlink(const char *pathname) | |
3533 | +{ | |
3534 | + int error; | |
3535 | + struct dentry *dentry; | |
3536 | + struct nameidata nd; | |
3537 | + struct inode *inode = NULL; | |
3538 | + | |
3539 | + DbgPrint("local_unlink: %s\n", pathname); | |
3540 | + error = path_lookup(pathname, LOOKUP_PARENT, &nd); | |
3541 | + DbgPrint("local_unlink: path_lookup %d\n", error); | |
3542 | + if (!error) { | |
3543 | + error = -EISDIR; | |
3544 | + if (nd.last_type == LAST_NORM) { | |
3545 | + down(&nd.dentry->d_inode->i_sem); | |
3546 | + dentry = | |
3547 | + lookup_one_len(&nd.last, nd.dentry, | |
3548 | + sizeof(nd.last)); | |
3549 | + DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry); | |
3550 | + | |
3551 | + error = PTR_ERR(dentry); | |
3552 | + if (!IS_ERR(dentry)) { | |
3553 | + if (nd.last.name[nd.last.len]) { | |
3554 | + error = | |
3555 | + !dentry-> | |
3556 | + d_inode ? -ENOENT : S_ISDIR(dentry-> | |
3557 | + d_inode-> | |
3558 | + i_mode) | |
3559 | + ? -EISDIR : -ENOTDIR; | |
3560 | + } else { | |
3561 | + inode = dentry->d_inode; | |
3562 | + if (inode) { | |
3563 | + atomic_inc(&inode->i_count); | |
3564 | + } | |
3565 | + error = | |
3566 | + vfs_unlink(nd.dentry->d_inode, | |
3567 | + dentry); | |
3568 | + DbgPrint | |
3569 | + ("local_unlink: vfs_unlink %d\n", | |
3570 | + error); | |
3571 | + } | |
3572 | + dput(dentry); | |
3573 | + } | |
3574 | + up(&nd.dentry->d_inode->i_sem); | |
3575 | + } | |
3576 | + path_release(&nd); | |
3577 | + } | |
3578 | + | |
3579 | + if (inode) { | |
3580 | + iput(inode); /* truncate the inode here */ | |
3581 | + } | |
3582 | + | |
3583 | + DbgPrint("local_unlink: error=%d\n", error); | |
3584 | + return error; | |
3585 | +} | |
3586 | +#endif | |
3587 | --- /dev/null | |
3588 | +++ b/fs/novfs/file.c | |
3589 | @@ -0,0 +1,1964 @@ | |
3590 | +/* | |
3591 | + * Novell NCP Redirector for Linux | |
3592 | + * Author: James Turner | |
3593 | + * | |
3594 | + * This file contains functions for accessing files through the daemon. | |
3595 | + * | |
3596 | + * Copyright (C) 2005 Novell, Inc. | |
3597 | + * | |
3598 | + * This program is free software; you can redistribute it and/or | |
3599 | + * modify it under the terms of the GNU General Public License | |
3600 | + * as published by the Free Software Foundation; either version 2 | |
3601 | + * of the License, or (at your option) any later version. | |
3602 | + */ | |
3603 | + | |
3604 | +#include <linux/module.h> | |
3605 | +#include <linux/kthread.h> | |
3606 | +#include <linux/fs.h> | |
3607 | +#include <linux/file.h> | |
3608 | +#include <linux/sched.h> | |
3609 | +#include <linux/dcache.h> | |
3610 | +#include <linux/pagemap.h> | |
3611 | +#include <linux/stat.h> | |
3612 | +#include <linux/slab.h> | |
3613 | +#include <asm/uaccess.h> | |
3614 | + | |
3615 | +#include "vfs.h" | |
3616 | +#include "commands.h" | |
3617 | +#include "nwerror.h" | |
3618 | + | |
3619 | +/*===[ Function prototypes ]==============================================*/ | |
3620 | +int Novfs_get_alltrees(struct dentry *parent); | |
3621 | +ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t * off); | |
3622 | + | |
3623 | +int Novfs_Find_Name_In_List(struct qstr *Name, unsigned char * List); | |
3624 | + | |
3625 | +int Novfs_Create(unsigned char * Path, int DirectoryFlag, session_t SessionId); | |
3626 | +int Novfs_Close_File(HANDLE Handle, session_t SessionId); | |
3627 | +int Novfs_Read_File(HANDLE Handle, unsigned char * Buffer, size_t * Bytes, | |
3628 | + loff_t * Offset, session_t SessionId); | |
3629 | +int Novfs_Write_File(HANDLE Handle, unsigned char * Buffer, size_t * Bytes, | |
3630 | + loff_t * Offset, session_t SessionId); | |
3631 | +int Novfs_Write_Page(HANDLE Handle, struct page *Page, session_t SessionId); | |
3632 | +int Novfs_Read_Stream(HANDLE ConnHandle, unsigned char * Handle, unsigned char * Buffer, | |
3633 | + size_t * Bytes, loff_t * Offset, int User, | |
3634 | + session_t SessionId); | |
3635 | +int Novfs_Write_Stream(HANDLE ConnHandle, unsigned char * Handle, unsigned char * Buffer, | |
3636 | + size_t * Bytes, loff_t * Offset, session_t SessionId); | |
3637 | +int Novfs_Close_Stream(HANDLE ConnHandle, unsigned char * Handle, session_t SessionId); | |
3638 | +int Novfs_Delete(unsigned char * Path, int DirectoryFlag, session_t SessionId); | |
3639 | +int Novfs_Truncate_File(unsigned char * Path, int PathLen, session_t SessionId); | |
3640 | +int Novfs_Truncate_File_Ex(HANDLE Handle, loff_t Offset, session_t SessionId); | |
3641 | +int Novfs_Rename_File(int DirectoryFlag, unsigned char * OldName, int OldLen, | |
3642 | + unsigned char * NewName, int NewLen, session_t SessionId); | |
3643 | +int Novfs_Set_Attr(unsigned char * Path, struct iattr *Attr, session_t SessionId); | |
3644 | +int Novfs_Get_File_Cache_Flag(unsigned char * Path, session_t SessionId); | |
3645 | + | |
3646 | +static struct file_operations Novfs_tree_operations = { | |
3647 | + read:Novfs_tree_read, | |
3648 | +}; | |
3649 | + | |
3650 | +/* | |
3651 | + * StripTrailingDots was added because some apps will | |
3652 | + * try and create a file name with a trailing dot. NetWare | |
3653 | + * doesn't like this and will return an error. | |
3654 | + */ | |
3655 | +static int StripTrailingDots = 1; | |
3656 | + | |
3657 | +int Novfs_get_alltrees(struct dentry *parent) | |
3658 | +{ | |
3659 | + unsigned char *p; | |
3660 | + PCOMMAND_REPLY_HEADER reply = NULL; | |
3661 | + unsigned long replylen = 0; | |
3662 | + COMMAND_REQUEST_HEADER cmd; | |
3663 | + int retCode; | |
3664 | + struct dentry *entry; | |
3665 | + struct qstr name; | |
3666 | + struct inode *inode; | |
3667 | + | |
3668 | + cmd.CommandType = 0; | |
3669 | + cmd.SequenceNumber = 0; | |
3670 | +//sg ??? cmd.SessionId = 0x1234; | |
3671 | + SC_INITIALIZE(cmd.SessionId); | |
3672 | + | |
3673 | + DbgPrint("Novfs_get_alltrees:\n"); | |
3674 | + | |
3675 | + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); | |
3676 | + DbgPrint("Novfs_get_alltrees: relpy=0x%p replylen=%d\n", reply, | |
3677 | + replylen); | |
3678 | + if (reply) { | |
3679 | + mydump(replylen, reply); | |
3680 | + if (!reply->ErrorCode | |
3681 | + && (replylen > sizeof(COMMAND_REPLY_HEADER))) { | |
3682 | + p = (char *)reply + 8; | |
3683 | + while (*p) { | |
3684 | + DbgPrint("Novfs_get_alltrees: %s\n", p); | |
3685 | + name.len = strlen(p); | |
3686 | + name.name = p; | |
3687 | + name.hash = full_name_hash(name.name, name.len); | |
3688 | + entry = d_lookup(parent, &name); | |
3689 | + if (NULL == entry) { | |
3690 | + DbgPrint("Novfs_get_alltrees: adding %s\n", p); | |
3691 | + entry = d_alloc(parent, &name); | |
3692 | + if (entry) { | |
3693 | + entry->d_op = &Novfs_dentry_operations; | |
3694 | + inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0, 0, &name); | |
3695 | + if (inode) { | |
3696 | + inode->i_fop = &Novfs_tree_operations; | |
3697 | + d_add(entry, inode); | |
3698 | + } | |
3699 | + } | |
3700 | + } | |
3701 | + p += (name.len + 1); | |
3702 | + } | |
3703 | + } | |
3704 | + kfree(reply); | |
3705 | + } | |
3706 | + return (retCode); | |
3707 | +} | |
3708 | + | |
3709 | +ssize_t Novfs_tree_read(struct file * file, char *buf, size_t len, loff_t * off) | |
3710 | +{ | |
3711 | + if (file->f_pos != 0) { | |
3712 | + return (0); | |
3713 | + } | |
3714 | + if (copy_to_user(buf, "Tree\n", 5)) { | |
3715 | + return (0); | |
3716 | + } | |
3717 | + return (5); | |
3718 | +} | |
3719 | + | |
3720 | +int Novfs_Get_Connected_Server_List(unsigned char ** ServerList, struct schandle *SessionId) | |
3721 | +{ | |
3722 | + GET_CONNECTED_SERVER_LIST_REQUEST req; | |
3723 | + PGET_CONNECTED_SERVER_LIST_REPLY reply = NULL; | |
3724 | + unsigned long replylen = 0; | |
3725 | + int retCode = 0; | |
3726 | + | |
3727 | + *ServerList = NULL; | |
3728 | + | |
3729 | + req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST; | |
3730 | + memcpy(&req.Command.SessionId, SessionId, sizeof(*SessionId)); | |
3731 | + | |
3732 | + retCode = | |
3733 | + Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, | |
3734 | + &replylen, INTERRUPTIBLE); | |
3735 | + if (reply) { | |
3736 | + DbgPrint("Novfs_Get_Connected_Server_List: reply\n"); | |
3737 | + replylen -= sizeof(COMMAND_REPLY_HEADER); | |
3738 | + if (!reply->Reply.ErrorCode && replylen) { | |
3739 | + memcpy(reply, reply->List, replylen); | |
3740 | + *ServerList = (unsigned char *) reply; | |
3741 | + retCode = 0; | |
3742 | + } else { | |
3743 | + kfree(reply); | |
3744 | + retCode = -ENOENT; | |
3745 | + } | |
3746 | + } | |
3747 | + return (retCode); | |
3748 | +} | |
3749 | + | |
3750 | +int Novfs_Get_Server_Volume_List(struct qstr *Server, unsigned char ** VolumeList, | |
3751 | + struct schandle *SessionId) | |
3752 | +{ | |
3753 | + PGET_SERVER_VOLUME_LIST_REQUEST req; | |
3754 | + PGET_SERVER_VOLUME_LIST_REPLY reply = NULL; | |
3755 | + unsigned long replylen = 0, reqlen; | |
3756 | + int retCode; | |
3757 | + | |
3758 | + *VolumeList = NULL; | |
3759 | + reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST) + Server->len; | |
3760 | + req = kmalloc(reqlen, GFP_KERNEL); | |
3761 | + if (!req) | |
3762 | + return -ENOMEM; | |
3763 | + req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST; | |
3764 | + req->Length = Server->len; | |
3765 | + memcpy(req->Name, Server->name, Server->len); | |
3766 | + memcpy(&req->Command.SessionId, SessionId, sizeof(*SessionId)); | |
3767 | + | |
3768 | + retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, | |
3769 | + &replylen, INTERRUPTIBLE); | |
3770 | + if (reply) { | |
3771 | + DbgPrint("Novfs_Get_Server_Volume_List: reply\n"); | |
3772 | + mydump(replylen, reply); | |
3773 | + replylen -= sizeof(COMMAND_REPLY_HEADER); | |
3774 | + | |
3775 | + if (!reply->Reply.ErrorCode && replylen) { | |
3776 | + memcpy(reply, reply->List, replylen); | |
3777 | + *VolumeList = (unsigned char *) reply; | |
3778 | + retCode = 0; | |
3779 | + } else { | |
3780 | + kfree(reply); | |
3781 | + retCode = -ENOENT; | |
3782 | + } | |
3783 | + } | |
3784 | + kfree(req); | |
3785 | + return retCode; | |
3786 | +} | |
3787 | + | |
3788 | +int Novfs_Find_Name_In_List(struct qstr *Name, unsigned char * List) | |
3789 | +{ | |
3790 | + int len; | |
3791 | + int retCode = 0; | |
3792 | + | |
3793 | + while (*List) { | |
3794 | + len = strlen(List); | |
3795 | + if ((len == Name->len) && !strncmp(Name->name, List, len)) { | |
3796 | + retCode = 1; | |
3797 | + break; | |
3798 | + } | |
3799 | + List += (len + 1); | |
3800 | + } | |
3801 | + return (retCode); | |
3802 | +} | |
3803 | + | |
3804 | +int Novfs_Get_File_Info(unsigned char * Path, struct entry_info *Info, struct schandle *SessionId) | |
3805 | +{ | |
3806 | + PVERIFY_FILE_REPLY reply = NULL; | |
3807 | + unsigned long replylen = 0; | |
3808 | + PVERIFY_FILE_REQUEST cmd; | |
3809 | + int cmdlen; | |
3810 | + int retCode = -ENOENT; | |
3811 | + int pathlen; | |
3812 | + | |
3813 | + DbgPrint("%s: Path = %s\n", __func__, Path); | |
3814 | + | |
3815 | + Info->mode = S_IFDIR | 0700; | |
3816 | + Info->uid = current->uid; | |
3817 | + Info->gid = current->gid; | |
3818 | + Info->size = 0; | |
3819 | + Info->atime = Info->mtime = Info->ctime = CURRENT_TIME; | |
3820 | + | |
3821 | + if (Path && *Path) { | |
3822 | + pathlen = strlen(Path); | |
3823 | + if (StripTrailingDots) { | |
3824 | + if ('.' == Path[pathlen - 1]) | |
3825 | + pathlen--; | |
3826 | + } | |
3827 | + cmdlen = offsetof(VERIFY_FILE_REQUEST, path) + pathlen; | |
3828 | + cmd = (PVERIFY_FILE_REQUEST) Novfs_Malloc(cmdlen, GFP_KERNEL); | |
3829 | + if (cmd) { | |
3830 | + cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; | |
3831 | + cmd->Command.SequenceNumber = 0; | |
3832 | + memcpy(&cmd->Command.SessionId, SessionId, sizeof(*SessionId)); | |
3833 | + cmd->pathLen = pathlen; | |
3834 | + memcpy(cmd->path, Path, cmd->pathLen); | |
3835 | + | |
3836 | + retCode = | |
3837 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, | |
3838 | + (void *)&reply, &replylen, | |
3839 | + INTERRUPTIBLE); | |
3840 | + | |
3841 | + if (reply) { | |
3842 | + | |
3843 | + if (reply->Reply.ErrorCode) { | |
3844 | + retCode = -ENOENT; | |
3845 | + } else { | |
3846 | + Info->type = 3; | |
3847 | + Info->mode = S_IRWXU; | |
3848 | + | |
3849 | + if (reply-> | |
3850 | + fileMode & NW_ATTRIBUTE_DIRECTORY) { | |
3851 | + Info->mode |= S_IFDIR; | |
3852 | + } else { | |
3853 | + Info->mode |= S_IFREG; | |
3854 | + } | |
3855 | + | |
3856 | + if (reply-> | |
3857 | + fileMode & NW_ATTRIBUTE_READ_ONLY) { | |
3858 | + Info->mode &= ~(S_IWUSR); | |
3859 | + } | |
3860 | + | |
3861 | + Info->uid = current->euid; | |
3862 | + Info->gid = current->egid; | |
3863 | + Info->size = reply->fileSize; | |
3864 | + Info->atime.tv_sec = | |
3865 | + reply->lastAccessTime; | |
3866 | + Info->atime.tv_nsec = 0; | |
3867 | + Info->mtime.tv_sec = reply->modifyTime; | |
3868 | + Info->mtime.tv_nsec = 0; | |
3869 | + Info->ctime.tv_sec = reply->createTime; | |
3870 | + Info->ctime.tv_nsec = 0; | |
3871 | + DbgPrint("%s: replylen=%d sizeof(VERIFY_FILE_REPLY)=%d\n", __func__, replylen, sizeof(VERIFY_FILE_REPLY)); | |
3872 | + if (replylen > sizeof(VERIFY_FILE_REPLY)) { | |
3873 | + unsigned int *lp = &reply->fileMode; | |
3874 | + lp++; | |
3875 | + DbgPrint("%s: extra data 0x%x\n", __func__, *lp); | |
3876 | + Info->mtime.tv_nsec = *lp; | |
3877 | + } | |
3878 | + retCode = 0; | |
3879 | + } | |
3880 | + | |
3881 | + kfree(reply); | |
3882 | + } | |
3883 | + kfree(cmd); | |
3884 | + } | |
3885 | + } | |
3886 | + | |
3887 | + DbgPrint("%s: return 0x%x\n", __func__, retCode); | |
3888 | + return (retCode); | |
3889 | +} | |
3890 | + | |
3891 | +int Novfs_GetX_File_Info(char *Path, const char *Name, char *buffer, | |
3892 | + ssize_t buffer_size, ssize_t * dataLen, | |
3893 | + session_t *SessionId) | |
3894 | +{ | |
3895 | + PXA_GET_REPLY reply = NULL; | |
3896 | + unsigned long replylen = 0; | |
3897 | + PXA_GET_REQUEST cmd; | |
3898 | + int cmdlen; | |
3899 | + int retCode = -ENOENT; | |
3900 | + | |
3901 | + int namelen = strlen(Name); | |
3902 | + int pathlen = strlen(Path); | |
3903 | + | |
3904 | + DbgPrint("%s: xattr: Path = %s, pathlen = %i, Name = %s, namelen = %i\n", __func__, Path, pathlen, Name, namelen); | |
3905 | + | |
3906 | + if (namelen > MAX_XATTR_NAME_LEN) { | |
3907 | + return ENOATTR; | |
3908 | + } | |
3909 | + | |
3910 | + cmdlen = offsetof(XA_GET_REQUEST, data) + pathlen + 1 + namelen + 1; // two '\0' | |
3911 | + cmd = (PXA_GET_REQUEST) Novfs_Malloc(cmdlen, GFP_KERNEL); | |
3912 | + if (cmd) { | |
3913 | + cmd->Command.CommandType = VFS_COMMAND_GET_EXTENDED_ATTRIBUTE; | |
3914 | + cmd->Command.SequenceNumber = 0; | |
3915 | + memcpy(&cmd->Command.SessionId, SessionId, sizeof(*SessionId)); | |
3916 | + | |
3917 | + cmd->pathLen = pathlen; | |
3918 | + memcpy(cmd->data, Path, cmd->pathLen + 1); //+ '\0' | |
3919 | + | |
3920 | + cmd->nameLen = namelen; | |
3921 | + memcpy(cmd->data + cmd->pathLen + 1, Name, cmd->nameLen + 1); | |
3922 | + | |
3923 | + DbgPrint("%s xattr: PXA_GET_REQUEST BEGIN\n", __func__); | |
3924 | + DbgPrint("%s xattr: Queue_Daemon_Command %d\n", __func__, cmd->Command.CommandType); | |
3925 | + DbgPrint("%s xattr: Command.SessionId = %d\n", __func__, cmd->Command.SessionId); | |
3926 | + DbgPrint("%s xattr: pathLen = %d\n", __func__, cmd->pathLen); | |
3927 | + DbgPrint("%s xattr: Path = %s\n", __func__, cmd->data); | |
3928 | + DbgPrint("%s xattr: nameLen = %d\n", __func__, cmd->nameLen); | |
3929 | + DbgPrint("%s xattr: name = %s\n", __func__, (cmd->data + cmd->pathLen + 1)); | |
3930 | + DbgPrint("%s xattr: PXA_GET_REQUEST END\n", __func__); | |
3931 | + | |
3932 | + retCode = | |
3933 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
3934 | + &replylen, INTERRUPTIBLE); | |
3935 | + | |
3936 | + if (reply) { | |
3937 | + | |
3938 | + if (reply->Reply.ErrorCode) { | |
3939 | + DbgPrint("%s xattr: reply->Reply.ErrorCode=%d, %X\n", __func__, reply->Reply.ErrorCode, reply->Reply.ErrorCode); | |
3940 | + DbgPrint("%s xattr: replylen=%d\n", __func__, replylen); | |
3941 | + | |
3942 | + //0xC9 = EA not found (C9), 0xD1 = EA access denied | |
3943 | + if ((reply->Reply.ErrorCode == 0xC9) | |
3944 | + || (reply->Reply.ErrorCode == 0xD1)) { | |
3945 | + retCode = -ENOATTR; | |
3946 | + } else { | |
3947 | + retCode = -ENOENT; | |
3948 | + } | |
3949 | + } else { | |
3950 | + | |
3951 | + *dataLen = | |
3952 | + replylen - sizeof(COMMAND_REPLY_HEADER); | |
3953 | + DbgPrint("%s xattr: replylen=%u, dataLen=%u\n", __func__, replylen, *dataLen); | |
3954 | + | |
3955 | + if (buffer_size >= *dataLen) { | |
3956 | + DbgPrint("%s xattr: copying to buffer from &reply->pData\n", __func__); | |
3957 | + memcpy(buffer, &reply->pData, *dataLen); | |
3958 | + | |
3959 | + retCode = 0; | |
3960 | + } else { | |
3961 | + DbgPrint("%s xattr: (!!!) buffer is smaller then reply\n", __func__); | |
3962 | + retCode = -ERANGE; | |
3963 | + } | |
3964 | + DbgPrint("%s xattr: /dumping buffer\n", __func__); | |
3965 | + mydump(*dataLen, buffer); | |
3966 | + DbgPrint("%s xattr: \\after dumping buffer\n", __func__); | |
3967 | + } | |
3968 | + | |
3969 | + kfree(reply); | |
3970 | + } else { | |
3971 | + DbgPrint("%s xattr: reply = NULL\n", __func__); | |
3972 | + } | |
3973 | + kfree(cmd); | |
3974 | + | |
3975 | + } | |
3976 | + | |
3977 | + return retCode; | |
3978 | +} | |
3979 | + | |
3980 | +int Novfs_SetX_File_Info(char *Path, const char *Name, const void *Value, | |
3981 | + unsigned long valueLen, unsigned long *bytesWritten, | |
3982 | + int flags, struct schandle *SessionId) | |
3983 | +{ | |
3984 | + PXA_SET_REPLY reply = NULL; | |
3985 | + unsigned long replylen = 0; | |
3986 | + PXA_SET_REQUEST cmd; | |
3987 | + int cmdlen; | |
3988 | + int retCode = -ENOENT; | |
3989 | + | |
3990 | + int namelen = strlen(Name); | |
3991 | + int pathlen = strlen(Path); | |
3992 | + | |
3993 | + DbgPrint("%s xattr: Path = %s, pathlen = %i, Name = %s, namelen = %i, value len = %u\n", __func__, | |
3994 | + Path, pathlen, Name, namelen, valueLen); | |
3995 | + | |
3996 | + if (namelen > MAX_XATTR_NAME_LEN) { | |
3997 | + return ENOATTR; | |
3998 | + } | |
3999 | + | |
4000 | + cmdlen = offsetof(XA_SET_REQUEST, data) + pathlen + 1 + namelen + 1 + valueLen; | |
4001 | + cmd = (PXA_SET_REQUEST) Novfs_Malloc(cmdlen, GFP_KERNEL); | |
4002 | + if (cmd) { | |
4003 | + cmd->Command.CommandType = VFS_COMMAND_SET_EXTENDED_ATTRIBUTE; | |
4004 | + cmd->Command.SequenceNumber = 0; | |
4005 | + memcpy(&cmd->Command.SessionId, SessionId, sizeof(*SessionId)); | |
4006 | + | |
4007 | + cmd->flags = flags; | |
4008 | + cmd->pathLen = pathlen; | |
4009 | + memcpy(cmd->data, Path, cmd->pathLen + 1); //+ '\0' | |
4010 | + | |
4011 | + cmd->nameLen = namelen; | |
4012 | + memcpy(cmd->data + cmd->pathLen + 1, Name, cmd->nameLen + 1); | |
4013 | + | |
4014 | + cmd->valueLen = valueLen; | |
4015 | + memcpy(cmd->data + cmd->pathLen + 1 + cmd->nameLen + 1, Value, | |
4016 | + valueLen); | |
4017 | + | |
4018 | + DbgPrint("%s xattr: PXA_SET_REQUEST BEGIN\n", __func__); | |
4019 | + DbgPrint("%s xattr: Queue_Daemon_Command %d\n", __func__, cmd->Command.CommandType); | |
4020 | + DbgPrint("%s xattr: Command.SessionId = %d\n", __func__, cmd->Command.SessionId); | |
4021 | + DbgPrint("%s xattr: pathLen = %d\n", __func__, cmd->pathLen); | |
4022 | + DbgPrint("%s xattr: Path = %s\n", __func__, cmd->data); | |
4023 | + DbgPrint("%s xattr: nameLen = %d\n", __func__, cmd->nameLen); | |
4024 | + DbgPrint("%s xattr: name = %s\n", __func__, (cmd->data + cmd->pathLen + 1)); | |
4025 | + mydump(valueLen < 16 ? valueLen : 16, (char *)Value); | |
4026 | + | |
4027 | + DbgPrint("%s xattr: PXA_SET_REQUEST END\n", __func__); | |
4028 | + | |
4029 | + retCode = | |
4030 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
4031 | + &replylen, INTERRUPTIBLE); | |
4032 | + | |
4033 | + if (reply) { | |
4034 | + | |
4035 | + if (reply->Reply.ErrorCode) { | |
4036 | + DbgPrint("%s xattr: reply->Reply.ErrorCode=%d, %X\n", __func__, reply->Reply.ErrorCode, reply->Reply.ErrorCode); | |
4037 | + DbgPrint("%s xattr: replylen=%d\n", __func__, replylen); | |
4038 | + | |
4039 | + retCode = -reply->Reply.ErrorCode; //-ENOENT; | |
4040 | + } else { | |
4041 | + | |
4042 | + DbgPrint("%s xattr: replylen=%u, real len = %u\n", __func__, replylen, replylen - sizeof(COMMAND_REPLY_HEADER)); | |
4043 | + memcpy(bytesWritten, &reply->pData, | |
4044 | + replylen - sizeof(COMMAND_REPLY_HEADER)); | |
4045 | + | |
4046 | + retCode = 0; | |
4047 | + } | |
4048 | + | |
4049 | + kfree(reply); | |
4050 | + } else { | |
4051 | + DbgPrint("%s xattr: reply = NULL\n", __func__); | |
4052 | + } | |
4053 | + kfree(cmd); | |
4054 | + | |
4055 | + } | |
4056 | + | |
4057 | + return retCode; | |
4058 | +} | |
4059 | + | |
4060 | +int Novfs_ListX_File_Info(char *Path, char *buffer, ssize_t buffer_size, ssize_t * dataLen, struct schandle *SessionId) | |
4061 | +{ | |
4062 | + PXA_LIST_REPLY reply = NULL; | |
4063 | + unsigned long replylen = 0; | |
4064 | + PVERIFY_FILE_REQUEST cmd; | |
4065 | + int cmdlen; | |
4066 | + int retCode = -ENOENT; | |
4067 | + | |
4068 | + int pathlen = strlen(Path); | |
4069 | + DbgPrint("%s xattr: Path = %s, pathlen = %i\n", __func__, Path, pathlen); | |
4070 | + | |
4071 | + *dataLen = 0; | |
4072 | + cmdlen = offsetof(VERIFY_FILE_REQUEST, path) + pathlen; | |
4073 | + cmd = (PVERIFY_FILE_REQUEST) Novfs_Malloc(cmdlen, GFP_KERNEL); | |
4074 | + if (cmd) { | |
4075 | + cmd->Command.CommandType = VFS_COMMAND_LIST_EXTENDED_ATTRIBUTES; | |
4076 | + cmd->Command.SequenceNumber = 0; | |
4077 | + memcpy(&cmd->Command.SessionId, SessionId, sizeof(*SessionId)); | |
4078 | + cmd->pathLen = pathlen; | |
4079 | + memcpy(cmd->path, Path, cmd->pathLen + 1); //+ '\0' | |
4080 | + DbgPrint("%s xattr: PVERIFY_FILE_REQUEST BEGIN\n", __func__); | |
4081 | + DbgPrint("%s xattr: Queue_Daemon_Command %d\n", __func__, cmd->Command.CommandType); | |
4082 | + DbgPrint("%s xattr: Command.SessionId = %d\n", __func__, cmd->Command.SessionId); | |
4083 | + DbgPrint("%s xattr: pathLen = %d\n", __func__, cmd->pathLen); | |
4084 | + DbgPrint("%s xattr: Path = %s\n", __func__, cmd->path); | |
4085 | + DbgPrint("%s xattr: PVERIFY_FILE_REQUEST END\n", __func__); | |
4086 | + | |
4087 | + retCode = | |
4088 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
4089 | + &replylen, INTERRUPTIBLE); | |
4090 | + | |
4091 | + if (reply) { | |
4092 | + | |
4093 | + if (reply->Reply.ErrorCode) { | |
4094 | + DbgPrint("%s xattr: reply->Reply.ErrorCode=%d, %X\n", __func__, reply->Reply.ErrorCode, reply->Reply.ErrorCode); | |
4095 | + DbgPrint("%s xattr: replylen=%d\n", __func__, replylen); | |
4096 | + | |
4097 | + retCode = -ENOENT; | |
4098 | + } else { | |
4099 | + *dataLen = replylen - sizeof(COMMAND_REPLY_HEADER); | |
4100 | + DbgPrint("%s xattr: replylen=%u, dataLen=%u\n", __func__, replylen, *dataLen); | |
4101 | + | |
4102 | + if (buffer_size >= *dataLen) { | |
4103 | + DbgPrint("%s xattr: copying to buffer from &reply->pData\n", __func__); | |
4104 | + memcpy(buffer, &reply->pData, *dataLen); | |
4105 | + } else { | |
4106 | + DbgPrint("%s xattr: (!!!) buffer is smaller then reply\n", __func__); | |
4107 | + retCode = -ERANGE; | |
4108 | + } | |
4109 | + DbgPrint("%s xattr: /dumping buffer\n", __func__); | |
4110 | + mydump(*dataLen, buffer); | |
4111 | + DbgPrint("%s xattr: \\after dumping buffer\n", __func__); | |
4112 | + | |
4113 | + retCode = 0; | |
4114 | + } | |
4115 | + | |
4116 | + kfree(reply); | |
4117 | + } else { | |
4118 | + DbgPrint("%s xattr: reply = NULL\n", __func__); | |
4119 | + } | |
4120 | + kfree(cmd); | |
4121 | + | |
4122 | + } | |
4123 | + | |
4124 | + return retCode; | |
4125 | +} | |
4126 | + | |
4127 | +static int begin_directory_enumerate(unsigned char *Path, int PathLen, HANDLE *EnumHandle, struct schandle *SessionId) | |
4128 | +{ | |
4129 | + PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd; | |
4130 | + PBEGIN_ENUMERATE_DIRECTORY_REPLY reply = NULL; | |
4131 | + unsigned long replylen = 0; | |
4132 | + int retCode, cmdlen; | |
4133 | + | |
4134 | + *EnumHandle = 0; | |
4135 | + | |
4136 | + cmdlen = offsetof(BEGIN_ENUMERATE_DIRECTORY_REQUEST, path) + PathLen; | |
4137 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
4138 | + if (cmd) { | |
4139 | + cmd->Command.CommandType = VFS_COMMAND_START_ENUMERATE; | |
4140 | + cmd->Command.SequenceNumber = 0; | |
4141 | + memcpy(&cmd->Command.SessionId, SessionId, sizeof(*SessionId)); | |
4142 | + | |
4143 | + cmd->pathLen = PathLen; | |
4144 | + memcpy(cmd->path, Path, PathLen); | |
4145 | + | |
4146 | + retCode = | |
4147 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
4148 | + &replylen, INTERRUPTIBLE); | |
4149 | +/* | |
4150 | + * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0); | |
4151 | + */ | |
4152 | + if (reply) { | |
4153 | + if (reply->Reply.ErrorCode) { | |
4154 | + retCode = -EIO; | |
4155 | + } else { | |
4156 | + *EnumHandle = reply->enumerateHandle; | |
4157 | + retCode = 0; | |
4158 | + } | |
4159 | + kfree(reply); | |
4160 | + } | |
4161 | + kfree(cmd); | |
4162 | + } else { | |
4163 | + retCode = -ENOMEM; | |
4164 | + } | |
4165 | + return (retCode); | |
4166 | +} | |
4167 | + | |
4168 | +static int end_directory_enumerate(HANDLE EnumHandle, struct schandle *SessionId) | |
4169 | +{ | |
4170 | + END_ENUMERATE_DIRECTORY_REQUEST cmd; | |
4171 | + PEND_ENUMERATE_DIRECTORY_REPLY reply = NULL; | |
4172 | + unsigned long replylen = 0; | |
4173 | + int retCode; | |
4174 | + | |
4175 | + cmd.Command.CommandType = VFS_COMMAND_END_ENUMERATE; | |
4176 | + cmd.Command.SequenceNumber = 0; | |
4177 | + copy_session_id(&cmd.Command.SessionId, SessionId); | |
4178 | + | |
4179 | + cmd.enumerateHandle = EnumHandle; | |
4180 | + | |
4181 | + retCode = | |
4182 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
4183 | + &replylen, 0); | |
4184 | + if (reply) { | |
4185 | + retCode = 0; | |
4186 | + if (reply->Reply.ErrorCode) { | |
4187 | + retCode = -EIO; | |
4188 | + } | |
4189 | + kfree(reply); | |
4190 | + } | |
4191 | + | |
4192 | + return (retCode); | |
4193 | +} | |
4194 | + | |
4195 | +int directory_enumerate(HANDLE * EnumHandle, struct entry_info *Info, | |
4196 | + session_t SessionId) | |
4197 | +{ | |
4198 | + ENUMERATE_DIRECTORY_REQUEST cmd; | |
4199 | + PENUMERATE_DIRECTORY_REPLY reply = NULL; | |
4200 | + unsigned long replylen = 0; | |
4201 | + int retCode; | |
4202 | + | |
4203 | + cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY; | |
4204 | + cmd.Command.SequenceNumber = 0; | |
4205 | + cmd.Command.SessionId = SessionId; | |
4206 | + | |
4207 | + cmd.enumerateHandle = *EnumHandle; | |
4208 | + cmd.pathLen = 0; | |
4209 | + cmd.path[0] = '\0'; | |
4210 | + | |
4211 | + retCode = | |
4212 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
4213 | + &replylen, INTERRUPTIBLE); | |
4214 | + | |
4215 | + if (reply) { | |
4216 | + /* | |
4217 | + * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an | |
4218 | + * error but there could still be valid data. | |
4219 | + */ | |
4220 | + if (!reply->Reply.ErrorCode || | |
4221 | + ((replylen > sizeof(COMMAND_REPLY_HEADER)) && | |
4222 | + (reply->nameLen > 0))) { | |
4223 | + Info->type = 3; | |
4224 | + Info->mode = S_IRWXU; | |
4225 | + | |
4226 | + if (reply->mode & NW_ATTRIBUTE_DIRECTORY) { | |
4227 | + Info->mode |= S_IFDIR; | |
4228 | + Info->mode |= S_IXUSR; | |
4229 | + } else { | |
4230 | + Info->mode |= S_IFREG; | |
4231 | + } | |
4232 | + | |
4233 | + if (reply->mode & NW_ATTRIBUTE_READ_ONLY) { | |
4234 | + Info->mode &= ~(S_IWUSR); | |
4235 | + } | |
4236 | + | |
4237 | + if (reply->mode & NW_ATTRIBUTE_EXECUTE) { | |
4238 | + Info->mode |= S_IXUSR; | |
4239 | + } | |
4240 | + | |
4241 | + Info->uid = current->uid; | |
4242 | + Info->gid = current->gid; | |
4243 | + Info->size = reply->size; | |
4244 | + Info->atime.tv_sec = reply->lastAccessTime; | |
4245 | + Info->atime.tv_nsec = 0; | |
4246 | + Info->mtime.tv_sec = reply->modifyTime; | |
4247 | + Info->mtime.tv_nsec = 0; | |
4248 | + Info->ctime.tv_sec = reply->createTime; | |
4249 | + Info->ctime.tv_nsec = 0; | |
4250 | + Info->namelength = reply->nameLen; | |
4251 | + memcpy(Info->name, reply->name, reply->nameLen); | |
4252 | + retCode = 0; | |
4253 | + if (reply->Reply.ErrorCode) { | |
4254 | + retCode = -1; /* Eof of data */ | |
4255 | + } | |
4256 | + *EnumHandle = reply->enumerateHandle; | |
4257 | + } else { | |
4258 | + retCode = -ENODATA; | |
4259 | + } | |
4260 | + kfree(reply); | |
4261 | + } | |
4262 | + | |
4263 | + return (retCode); | |
4264 | +} | |
4265 | + | |
4266 | +static int directory_enumerate_ex(HANDLE *EnumHandle, struct schandle *SessionId, int *Count, struct entry_info **PInfo, int Interrupt) | |
4267 | +{ | |
4268 | + ENUMERATE_DIRECTORY_EX_REQUEST cmd; | |
4269 | + PENUMERATE_DIRECTORY_EX_REPLY reply = NULL; | |
4270 | + unsigned long replylen = 0; | |
4271 | + int retCode = 0; | |
4272 | + struct entry_info *info; | |
4273 | + PENUMERATE_DIRECTORY_EX_DATA data; | |
4274 | + int isize; | |
4275 | + | |
4276 | + if (PInfo) { | |
4277 | + *PInfo = NULL; | |
4278 | + } | |
4279 | + *Count = 0; | |
4280 | + | |
4281 | + cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY_EX; | |
4282 | + cmd.Command.SequenceNumber = 0; | |
4283 | + copy_session_id(&cmd.Command.SessionId, SessionId); | |
4284 | + | |
4285 | + cmd.enumerateHandle = *EnumHandle; | |
4286 | + cmd.pathLen = 0; | |
4287 | + cmd.path[0] = '\0'; | |
4288 | + | |
4289 | + retCode = | |
4290 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
4291 | + &replylen, Interrupt); | |
4292 | + | |
4293 | + if (reply) { | |
4294 | + retCode = 0; | |
4295 | + /* | |
4296 | + * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an | |
4297 | + * error but there could still be valid data. | |
4298 | + */ | |
4299 | + | |
4300 | + if (!reply->Reply.ErrorCode || | |
4301 | + ((replylen > sizeof(COMMAND_REPLY_HEADER)) && | |
4302 | + (reply->enumCount > 0))) { | |
4303 | + DbgPrint("directory_enumerate_ex: isize=%d\n", | |
4304 | + replylen); | |
4305 | + data = (PENUMERATE_DIRECTORY_EX_DATA) ((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY)); | |
4306 | + isize = replylen - sizeof(PENUMERATE_DIRECTORY_EX_REPLY) - reply->enumCount * offsetof(ENUMERATE_DIRECTORY_EX_DATA, name); | |
4307 | + isize += (reply->enumCount * offsetof(struct entry_info, name)); | |
4308 | + | |
4309 | + if (PInfo) { | |
4310 | + *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL); | |
4311 | + if (*PInfo) { | |
4312 | + DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info); | |
4313 | + *Count = reply->enumCount; | |
4314 | + do { | |
4315 | + DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data); | |
4316 | + | |
4317 | + info->type = 3; | |
4318 | + info->mode = S_IRWXU; | |
4319 | + | |
4320 | + if (data->mode & NW_ATTRIBUTE_DIRECTORY) { | |
4321 | + info->mode |= S_IFDIR; | |
4322 | + info->mode |= S_IXUSR; | |
4323 | + } else { | |
4324 | + info->mode |= S_IFREG; | |
4325 | + } | |
4326 | + | |
4327 | + if (data->mode & NW_ATTRIBUTE_READ_ONLY) { | |
4328 | + info->mode &= ~(S_IWUSR); | |
4329 | + } | |
4330 | + | |
4331 | + if (data->mode & NW_ATTRIBUTE_EXECUTE) { | |
4332 | + info->mode |= S_IXUSR; | |
4333 | + } | |
4334 | + | |
4335 | + info->uid = current->euid; | |
4336 | + info->gid = current->egid; | |
4337 | + info->size = data->size; | |
4338 | + info->atime.tv_sec = data->lastAccessTime; | |
4339 | + info->atime.tv_nsec = 0; | |
4340 | + info->mtime.tv_sec = data->modifyTime; | |
4341 | + info->mtime.tv_nsec = 0; | |
4342 | + info->ctime.tv_sec = data->createTime; | |
4343 | + info->ctime.tv_nsec = 0; | |
4344 | + info->namelength = data->nameLen; | |
4345 | + memcpy(info->name, data->name, data->nameLen); | |
4346 | + data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen]; | |
4347 | + replylen = (int)((char *)&info->name[info->namelength] - (char *)info); | |
4348 | + DbgPrint("directory_enumerate_ex3: info=0x%p\n", info); | |
4349 | + mydump(replylen, info); | |
4350 | + | |
4351 | + info = (struct entry_info *)&info->name[info->namelength]; | |
4352 | + | |
4353 | + } while (--reply->enumCount); | |
4354 | + } | |
4355 | + } | |
4356 | + | |
4357 | + if (reply->Reply.ErrorCode) { | |
4358 | + retCode = -1; /* Eof of data */ | |
4359 | + } | |
4360 | + *EnumHandle = reply->enumerateHandle; | |
4361 | + } else { | |
4362 | + retCode = -ENODATA; | |
4363 | + } | |
4364 | + kfree(reply); | |
4365 | + } | |
4366 | + | |
4367 | + return (retCode); | |
4368 | +} | |
4369 | + | |
4370 | +int Novfs_Get_Directory_ListEx(unsigned char * Path, HANDLE * EnumHandle, int *Count, | |
4371 | + struct entry_info **Info, struct schandle *SessionId) | |
4372 | +{ | |
4373 | + int retCode = -ENOENT; | |
4374 | + | |
4375 | + if (Count) | |
4376 | + *Count = 0; | |
4377 | + if (Info) | |
4378 | + *Info = NULL; | |
4379 | + | |
4380 | + if ((HANDLE) - 1 == *EnumHandle) { | |
4381 | + return (-ENODATA); | |
4382 | + } | |
4383 | + | |
4384 | + if (0 == *EnumHandle) | |
4385 | + retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId); | |
4386 | + | |
4387 | + if (*EnumHandle) { | |
4388 | + retCode = directory_enumerate_ex(EnumHandle, SessionId, Count, Info, INTERRUPTIBLE); | |
4389 | + if (retCode) { | |
4390 | + end_directory_enumerate(*EnumHandle, SessionId); | |
4391 | + if (-1 == retCode) { | |
4392 | + retCode = 0; | |
4393 | + *EnumHandle = Uint32toHandle(-1); | |
4394 | + } | |
4395 | + } | |
4396 | + } | |
4397 | + return (retCode); | |
4398 | +} | |
4399 | + | |
4400 | +int Novfs_Open_File(unsigned char * Path, int Flags, struct entry_info *Info, HANDLE * Handle, | |
4401 | + session_t SessionId) | |
4402 | +{ | |
4403 | + POPEN_FILE_REQUEST cmd; | |
4404 | + POPEN_FILE_REPLY reply; | |
4405 | + unsigned long replylen = 0; | |
4406 | + int retCode, cmdlen, pathlen; | |
4407 | + | |
4408 | + pathlen = strlen(Path); | |
4409 | + | |
4410 | + if (StripTrailingDots) { | |
4411 | + if ('.' == Path[pathlen - 1]) | |
4412 | + pathlen--; | |
4413 | + } | |
4414 | + | |
4415 | + *Handle = 0; | |
4416 | + | |
4417 | + cmdlen = offsetof(OPEN_FILE_REQUEST, path) + pathlen; | |
4418 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
4419 | + if (cmd) { | |
4420 | + cmd->Command.CommandType = VFS_COMMAND_OPEN_FILE; | |
4421 | + cmd->Command.SequenceNumber = 0; | |
4422 | + cmd->Command.SessionId = SessionId; | |
4423 | + | |
4424 | + cmd->access = 0; | |
4425 | + | |
4426 | + if (!(Flags & O_WRONLY) || (Flags & O_RDWR)) { | |
4427 | + cmd->access |= NWD_ACCESS_READ; | |
4428 | + } | |
4429 | + | |
4430 | + if ((Flags & O_WRONLY) || (Flags & O_RDWR)) { | |
4431 | + cmd->access |= NWD_ACCESS_WRITE; | |
4432 | + } | |
4433 | + | |
4434 | + switch (Flags & (O_CREAT | O_EXCL | O_TRUNC)) { | |
4435 | + case O_CREAT: | |
4436 | + cmd->disp = NWD_DISP_OPEN_ALWAYS; | |
4437 | + break; | |
4438 | + | |
4439 | + case O_CREAT | O_EXCL: | |
4440 | + cmd->disp = NWD_DISP_CREATE_NEW; | |
4441 | + break; | |
4442 | + | |
4443 | + case O_TRUNC: | |
4444 | + cmd->disp = NWD_DISP_CREATE_ALWAYS; | |
4445 | + break; | |
4446 | + | |
4447 | + case O_CREAT | O_TRUNC: | |
4448 | + cmd->disp = NWD_DISP_CREATE_ALWAYS; | |
4449 | + break; | |
4450 | + | |
4451 | + case O_CREAT | O_EXCL | O_TRUNC: | |
4452 | + cmd->disp = NWD_DISP_CREATE_NEW; | |
4453 | + break; | |
4454 | + | |
4455 | + default: | |
4456 | + cmd->disp = NWD_DISP_OPEN_EXISTING; | |
4457 | + break; | |
4458 | + } | |
4459 | + | |
4460 | + cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE; | |
4461 | + | |
4462 | + cmd->pathLen = pathlen; | |
4463 | + memcpy(cmd->path, Path, pathlen); | |
4464 | + | |
4465 | + retCode = | |
4466 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
4467 | + &replylen, INTERRUPTIBLE); | |
4468 | + | |
4469 | + if (reply) { | |
4470 | + if (reply->Reply.ErrorCode) { | |
4471 | + if (NWE_OBJECT_EXISTS == reply->Reply.ErrorCode) { | |
4472 | + retCode = -EEXIST; | |
4473 | + } else if (NWE_ACCESS_DENIED == | |
4474 | + reply->Reply.ErrorCode) { | |
4475 | + retCode = -EACCES; | |
4476 | + } else if (NWE_FILE_IN_USE == | |
4477 | + reply->Reply.ErrorCode) { | |
4478 | + retCode = -EBUSY; | |
4479 | + } else { | |
4480 | + retCode = -ENOENT; | |
4481 | + } | |
4482 | + } else { | |
4483 | + *Handle = reply->handle; | |
4484 | + retCode = 0; | |
4485 | + } | |
4486 | + kfree(reply); | |
4487 | + } | |
4488 | + kfree(cmd); | |
4489 | + } else { | |
4490 | + retCode = -ENOMEM; | |
4491 | + } | |
4492 | + return (retCode); | |
4493 | +} | |
4494 | + | |
4495 | +int Novfs_Create(unsigned char * Path, int DirectoryFlag, session_t SessionId) | |
4496 | +{ | |
4497 | + PCREATE_FILE_REQUEST cmd; | |
4498 | + PCREATE_FILE_REPLY reply; | |
4499 | + unsigned long replylen = 0; | |
4500 | + int retCode, cmdlen, pathlen; | |
4501 | + | |
4502 | + pathlen = strlen(Path); | |
4503 | + | |
4504 | + if (StripTrailingDots) { | |
4505 | + if ('.' == Path[pathlen - 1]) | |
4506 | + pathlen--; | |
4507 | + } | |
4508 | + | |
4509 | + cmdlen = offsetof(CREATE_FILE_REQUEST, path) + pathlen; | |
4510 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
4511 | + if (cmd) { | |
4512 | + cmd->Command.CommandType = VFS_COMMAND_CREATE_FILE; | |
4513 | + if (DirectoryFlag) { | |
4514 | + cmd->Command.CommandType = VFS_COMMAND_CREATE_DIRECOTRY; | |
4515 | + } | |
4516 | + cmd->Command.SequenceNumber = 0; | |
4517 | + cmd->Command.SessionId = SessionId; | |
4518 | + | |
4519 | + cmd->pathlength = pathlen; | |
4520 | + memcpy(cmd->path, Path, pathlen); | |
4521 | + | |
4522 | + retCode = | |
4523 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
4524 | + &replylen, INTERRUPTIBLE); | |
4525 | + | |
4526 | + if (reply) { | |
4527 | + retCode = 0; | |
4528 | + if (reply->Reply.ErrorCode) { | |
4529 | + retCode = -EIO; | |
4530 | + } | |
4531 | + kfree(reply); | |
4532 | + } | |
4533 | + kfree(cmd); | |
4534 | + } else { | |
4535 | + retCode = -ENOMEM; | |
4536 | + } | |
4537 | + return (retCode); | |
4538 | +} | |
4539 | + | |
4540 | +int Novfs_Close_File(HANDLE Handle, session_t SessionId) | |
4541 | +{ | |
4542 | + CLOSE_FILE_REQUEST cmd; | |
4543 | + PCLOSE_FILE_REPLY reply; | |
4544 | + unsigned long replylen = 0; | |
4545 | + int retCode; | |
4546 | + | |
4547 | + cmd.Command.CommandType = VFS_COMMAND_CLOSE_FILE; | |
4548 | + cmd.Command.SequenceNumber = 0; | |
4549 | + cmd.Command.SessionId = SessionId; | |
4550 | + | |
4551 | + cmd.handle = Handle; | |
4552 | + | |
4553 | + retCode = | |
4554 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
4555 | + &replylen, 0); | |
4556 | + if (reply) { | |
4557 | + retCode = 0; | |
4558 | + if (reply->Reply.ErrorCode) { | |
4559 | + retCode = -EIO; | |
4560 | + } | |
4561 | + kfree(reply); | |
4562 | + } | |
4563 | + return (retCode); | |
4564 | +} | |
4565 | + | |
4566 | +int Novfs_Read_File(HANDLE Handle, unsigned char * Buffer, size_t * Bytes, | |
4567 | + loff_t * Offset, session_t SessionId) | |
4568 | +{ | |
4569 | + READ_FILE_REQUEST cmd; | |
4570 | + PREAD_FILE_REPLY reply = NULL; | |
4571 | + unsigned long replylen = 0; | |
4572 | + int retCode = 0; | |
4573 | + size_t len; | |
4574 | + | |
4575 | + len = *Bytes; | |
4576 | + *Bytes = 0; | |
4577 | + | |
4578 | + if ((offsetof(READ_FILE_REPLY, data) + len) > MaxIoSize) { | |
4579 | + len = MaxIoSize - offsetof(READ_FILE_REPLY, data); | |
4580 | + len = (len / PAGE_SIZE) * PAGE_SIZE; | |
4581 | + } | |
4582 | + | |
4583 | + cmd.Command.CommandType = VFS_COMMAND_READ_FILE; | |
4584 | + cmd.Command.SequenceNumber = 0; | |
4585 | + cmd.Command.SessionId = SessionId; | |
4586 | + | |
4587 | + cmd.handle = Handle; | |
4588 | + cmd.len = len; | |
4589 | + cmd.offset = *Offset; | |
4590 | + | |
4591 | + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); | |
4592 | + | |
4593 | + DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen); | |
4594 | + | |
4595 | + if (!retCode) { | |
4596 | + if (reply->Reply.ErrorCode) { | |
4597 | + if (NWE_FILE_IO_LOCKED == reply->Reply.ErrorCode) { | |
4598 | + retCode = -EBUSY; | |
4599 | + } else { | |
4600 | + retCode = -EIO; | |
4601 | + } | |
4602 | + } else { | |
4603 | + replylen -= offsetof(READ_FILE_REPLY, data); | |
4604 | + if (replylen > 0) { | |
4605 | + replylen -= copy_to_user(Buffer, reply->data, replylen); | |
4606 | + *Bytes = replylen; | |
4607 | + } | |
4608 | + } | |
4609 | + } | |
4610 | + | |
4611 | + if (reply) { | |
4612 | + kfree(reply); | |
4613 | + } | |
4614 | + | |
4615 | + DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); | |
4616 | + | |
4617 | + return (retCode); | |
4618 | +} | |
4619 | + | |
4620 | +int Novfs_Read_Pages(HANDLE Handle, struct data_list *DList, int DList_Cnt, | |
4621 | + size_t * Bytes, loff_t * Offset, session_t SessionId) | |
4622 | +{ | |
4623 | + READ_FILE_REQUEST cmd; | |
4624 | + PREAD_FILE_REPLY reply = NULL; | |
4625 | + READ_FILE_REPLY lreply; | |
4626 | + unsigned long replylen = 0; | |
4627 | + int retCode = 0; | |
4628 | + size_t len; | |
4629 | + | |
4630 | + len = *Bytes; | |
4631 | + *Bytes = 0; | |
4632 | + | |
4633 | + DbgPrint | |
4634 | + ("Novfs_Read_Pages: Handle=0x%p Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%p:%p\n", | |
4635 | + Handle, DList, DList_Cnt, len, *Offset, SessionId.hTypeId, | |
4636 | + SessionId.hId); | |
4637 | + | |
4638 | + cmd.Command.CommandType = VFS_COMMAND_READ_FILE; | |
4639 | + cmd.Command.SequenceNumber = 0; | |
4640 | + cmd.Command.SessionId = SessionId; | |
4641 | + | |
4642 | + cmd.handle = Handle; | |
4643 | + cmd.len = len; | |
4644 | + cmd.offset = *Offset; | |
4645 | + | |
4646 | + /* | |
4647 | + * Dlst first entry is reserved for reply header. | |
4648 | + */ | |
4649 | + DList[0].page = NULL; | |
4650 | + DList[0].offset = &lreply; | |
4651 | + DList[0].len = offsetof(READ_FILE_REPLY, data); | |
4652 | + DList[0].rwflag = DLWRITE; | |
4653 | + | |
4654 | + retCode = | |
4655 | + Queue_Daemon_Command(&cmd, sizeof(cmd), DList, DList_Cnt, | |
4656 | + (void *)&reply, &replylen, INTERRUPTIBLE); | |
4657 | + | |
4658 | + DbgPrint("Novfs_Read_Pages: Queue_Daemon_Command 0x%x\n", retCode); | |
4659 | + | |
4660 | + if (!retCode) { | |
4661 | + if (reply) { | |
4662 | + memcpy(&lreply, reply, sizeof(lreply)); | |
4663 | + } | |
4664 | + | |
4665 | + if (lreply.Reply.ErrorCode) { | |
4666 | + if (NWE_FILE_IO_LOCKED == lreply.Reply.ErrorCode) { | |
4667 | + retCode = -EBUSY; | |
4668 | + } else { | |
4669 | + retCode = -EIO; | |
4670 | + } | |
4671 | + } | |
4672 | + *Bytes = replylen - offsetof(READ_FILE_REPLY, data); | |
4673 | + } | |
4674 | + | |
4675 | + if (reply) { | |
4676 | + kfree(reply); | |
4677 | + } | |
4678 | + | |
4679 | + DbgPrint("Novfs_Read_Pages: retCode=0x%x\n", retCode); | |
4680 | + | |
4681 | + return (retCode); | |
4682 | +} | |
4683 | + | |
4684 | +int Novfs_Write_File(HANDLE Handle, unsigned char * Buffer, size_t * Bytes, | |
4685 | + loff_t * Offset, session_t SessionId) | |
4686 | +{ | |
4687 | + WRITE_FILE_REQUEST cmd; | |
4688 | + PWRITE_FILE_REPLY reply = NULL; | |
4689 | + unsigned long replylen = 0; | |
4690 | + int retCode = 0, cmdlen; | |
4691 | + size_t len; | |
4692 | + | |
4693 | + unsigned long boff; | |
4694 | + struct page **pages; | |
4695 | + struct data_list *dlist; | |
4696 | + int res = 0, npage, i; | |
4697 | + WRITE_FILE_REPLY lreply; | |
4698 | + | |
4699 | + len = *Bytes; | |
4700 | + cmdlen = offsetof(WRITE_FILE_REQUEST, data); | |
4701 | + | |
4702 | + *Bytes = 0; | |
4703 | + | |
4704 | + memset(&lreply, 0, sizeof(lreply)); | |
4705 | + | |
4706 | + DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len); | |
4707 | + | |
4708 | + if ((cmdlen + len) > MaxIoSize) { | |
4709 | + len = MaxIoSize - cmdlen; | |
4710 | + len = (len / PAGE_SIZE) * PAGE_SIZE; | |
4711 | + } | |
4712 | + cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; | |
4713 | + cmd.Command.SequenceNumber = 0; | |
4714 | + cmd.Command.SessionId = SessionId; | |
4715 | + cmd.handle = Handle; | |
4716 | + cmd.len = len; | |
4717 | + cmd.offset = *Offset; | |
4718 | + | |
4719 | + DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len); | |
4720 | + | |
4721 | + npage = | |
4722 | + (((unsigned long)Buffer & ~PAGE_MASK) + len + | |
4723 | + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | |
4724 | + | |
4725 | + dlist = Novfs_Malloc(sizeof(struct data_list) * (npage + 1), GFP_KERNEL); | |
4726 | + if (NULL == dlist) { | |
4727 | + return (-ENOMEM); | |
4728 | + } | |
4729 | + | |
4730 | + pages = Novfs_Malloc(sizeof(struct page *) * npage, GFP_KERNEL); | |
4731 | + | |
4732 | + if (NULL == pages) { | |
4733 | + kfree(dlist); | |
4734 | + return (-ENOMEM); | |
4735 | + } | |
4736 | + | |
4737 | + down_read(¤t->mm->mmap_sem); | |
4738 | + | |
4739 | + res = get_user_pages(current, current->mm, (unsigned long)Buffer, npage, 0, /* read type */ | |
4740 | + 0, /* don't force */ | |
4741 | + pages, NULL); | |
4742 | + | |
4743 | + up_read(¤t->mm->mmap_sem); | |
4744 | + | |
4745 | + DbgPrint("Novfs_Write_File res=%d\n", res); | |
4746 | + | |
4747 | + if (res > 0) { | |
4748 | + boff = (unsigned long)Buffer & ~PAGE_MASK; | |
4749 | + | |
4750 | + flush_dcache_page(pages[0]); | |
4751 | + dlist[0].page = pages[0]; | |
4752 | + dlist[0].offset = (char *)boff; | |
4753 | + dlist[0].len = PAGE_SIZE - boff; | |
4754 | + dlist[0].rwflag = DLREAD; | |
4755 | + | |
4756 | + if (dlist[0].len > len) { | |
4757 | + dlist[0].len = len; | |
4758 | + } | |
4759 | + | |
4760 | + DbgPrint("Novfs_Write_File0: page=0x%p offset=0x%p len=%d\n", | |
4761 | + dlist[0].page, dlist[0].offset, dlist[0].len); | |
4762 | + | |
4763 | + boff = dlist[0].len; | |
4764 | + | |
4765 | + DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff); | |
4766 | + | |
4767 | + for (i = 1; (i < res) && (boff < len); i++) { | |
4768 | + flush_dcache_page(pages[i]); | |
4769 | + | |
4770 | + dlist[i].page = pages[i]; | |
4771 | + dlist[i].offset = NULL; | |
4772 | + dlist[i].len = len - boff; | |
4773 | + if (dlist[i].len > PAGE_SIZE) { | |
4774 | + dlist[i].len = PAGE_SIZE; | |
4775 | + } | |
4776 | + dlist[i].rwflag = DLREAD; | |
4777 | + | |
4778 | + boff += dlist[i].len; | |
4779 | + DbgPrint | |
4780 | + ("Novfs_Write_File%d: page=0x%p offset=0x%p len=%d\n", | |
4781 | + i, dlist[i].page, dlist[i].offset, dlist[i].len); | |
4782 | + } | |
4783 | + | |
4784 | + dlist[i].page = NULL; | |
4785 | + dlist[i].offset = &lreply; | |
4786 | + dlist[i].len = sizeof(lreply); | |
4787 | + dlist[i].rwflag = DLWRITE; | |
4788 | + res++; | |
4789 | + | |
4790 | + DbgPrint("Novfs_Write_File Buffer=0x%p boff=0x%x len=%d\n", | |
4791 | + Buffer, boff, len); | |
4792 | + | |
4793 | + retCode = | |
4794 | + Queue_Daemon_Command(&cmd, cmdlen, dlist, res, | |
4795 | + (void *)&reply, &replylen, | |
4796 | + INTERRUPTIBLE); | |
4797 | + | |
4798 | + } else { | |
4799 | + char *kdata; | |
4800 | + | |
4801 | + res = 0; | |
4802 | + | |
4803 | + kdata = Novfs_Malloc(len, GFP_KERNEL); | |
4804 | + if (kdata) { | |
4805 | + len -= copy_from_user(kdata, Buffer, len); | |
4806 | + dlist[0].page = NULL; | |
4807 | + dlist[0].offset = kdata; | |
4808 | + dlist[0].len = len; | |
4809 | + dlist[0].rwflag = DLREAD; | |
4810 | + | |
4811 | + dlist[1].page = NULL; | |
4812 | + dlist[1].offset = &lreply; | |
4813 | + dlist[1].len = sizeof(lreply); | |
4814 | + dlist[1].rwflag = DLWRITE; | |
4815 | + | |
4816 | + retCode = | |
4817 | + Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, | |
4818 | + (void *)&reply, &replylen, | |
4819 | + INTERRUPTIBLE); | |
4820 | + | |
4821 | + kfree(kdata); | |
4822 | + } | |
4823 | + } | |
4824 | + | |
4825 | + DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%p\n", retCode, reply); | |
4826 | + | |
4827 | + if (!retCode) { | |
4828 | + switch (lreply.Reply.ErrorCode) { | |
4829 | + case 0: | |
4830 | + *Bytes = (size_t) lreply.bytesWritten; | |
4831 | + retCode = 0; | |
4832 | + break; | |
4833 | + | |
4834 | + case NWE_INSUFFICIENT_SPACE: | |
4835 | + retCode = -ENOSPC; | |
4836 | + break; | |
4837 | + | |
4838 | + case NWE_ACCESS_DENIED: | |
4839 | + retCode = -EACCES; | |
4840 | + break; | |
4841 | + | |
4842 | + default: | |
4843 | + retCode = -EIO; | |
4844 | + break; | |
4845 | + } | |
4846 | + } | |
4847 | + | |
4848 | + if (res) { | |
4849 | + for (i = 0; i < res; i++) { | |
4850 | + if (dlist[i].page) { | |
4851 | + page_cache_release(dlist[i].page); | |
4852 | + } | |
4853 | + } | |
4854 | + } | |
4855 | + | |
4856 | + kfree(pages); | |
4857 | + kfree(dlist); | |
4858 | + | |
4859 | + DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, | |
4860 | + retCode); | |
4861 | + | |
4862 | + return (retCode); | |
4863 | +} | |
4864 | + | |
4865 | +/* | |
4866 | + * Arguments: HANDLE Handle - novfsd file handle | |
4867 | + * struct page *Page - Page to be written out | |
4868 | + * session_t SessionId - novfsd session handle | |
4869 | + * | |
4870 | + * Returns: 0 - Success | |
4871 | + * -ENOSPC - Out of space on server | |
4872 | + * -EACCES - Access denied | |
4873 | + * -EIO - Any other error | |
4874 | + * | |
4875 | + * Abstract: Write page to file. | |
4876 | + */ | |
4877 | +int Novfs_Write_Page(HANDLE Handle, struct page *Page, session_t SessionId) | |
4878 | +{ | |
4879 | + WRITE_FILE_REQUEST cmd; | |
4880 | + WRITE_FILE_REPLY lreply; | |
4881 | + PWRITE_FILE_REPLY reply = NULL; | |
4882 | + unsigned long replylen = 0; | |
4883 | + int retCode = 0, cmdlen; | |
4884 | + struct data_list dlst[2]; | |
4885 | + | |
4886 | + DbgPrint | |
4887 | + ("Novfs_Write_Page: Handle=0x%p Page=0x%p Index=%lu SessionId=0x%llx\n", | |
4888 | + Handle, Page, Page->index, SessionId); | |
4889 | + | |
4890 | + dlst[0].page = NULL; | |
4891 | + dlst[0].offset = &lreply; | |
4892 | + dlst[0].len = sizeof(lreply); | |
4893 | + dlst[0].rwflag = DLWRITE; | |
4894 | + | |
4895 | + dlst[1].page = Page; | |
4896 | + dlst[1].offset = 0; | |
4897 | + dlst[1].len = PAGE_CACHE_SIZE; | |
4898 | + dlst[1].rwflag = DLREAD; | |
4899 | + | |
4900 | + cmdlen = offsetof(WRITE_FILE_REQUEST, data); | |
4901 | + | |
4902 | + cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; | |
4903 | + cmd.Command.SequenceNumber = 0; | |
4904 | + cmd.Command.SessionId = SessionId; | |
4905 | + | |
4906 | + cmd.handle = Handle; | |
4907 | + cmd.len = PAGE_CACHE_SIZE; | |
4908 | + cmd.offset = (loff_t) Page->index << PAGE_CACHE_SHIFT;; | |
4909 | + | |
4910 | + retCode = | |
4911 | + Queue_Daemon_Command(&cmd, cmdlen, &dlst, 2, (void *)&reply, | |
4912 | + &replylen, INTERRUPTIBLE); | |
4913 | + if (!retCode) { | |
4914 | + if (reply) { | |
4915 | + memcpy(&lreply, reply, sizeof(lreply)); | |
4916 | + } | |
4917 | + switch (lreply.Reply.ErrorCode) { | |
4918 | + case 0: | |
4919 | + retCode = 0; | |
4920 | + break; | |
4921 | + | |
4922 | + case NWE_INSUFFICIENT_SPACE: | |
4923 | + retCode = -ENOSPC; | |
4924 | + break; | |
4925 | + | |
4926 | + case NWE_ACCESS_DENIED: | |
4927 | + retCode = -EACCES; | |
4928 | + break; | |
4929 | + | |
4930 | + default: | |
4931 | + retCode = -EIO; | |
4932 | + break; | |
4933 | + } | |
4934 | + } | |
4935 | + | |
4936 | + if (reply) { | |
4937 | + kfree(reply); | |
4938 | + } | |
4939 | + | |
4940 | + DbgPrint("Novfs_Write_Page retCode=0x%x\n", retCode); | |
4941 | + | |
4942 | + return (retCode); | |
4943 | +} | |
4944 | + | |
4945 | +int Novfs_Write_Pages(HANDLE Handle, struct data_list *DList, int DList_Cnt, | |
4946 | + size_t Bytes, loff_t Offset, session_t SessionId) | |
4947 | +{ | |
4948 | + WRITE_FILE_REQUEST cmd; | |
4949 | + WRITE_FILE_REPLY lreply; | |
4950 | + PWRITE_FILE_REPLY reply = NULL; | |
4951 | + unsigned long replylen = 0; | |
4952 | + int retCode = 0, cmdlen; | |
4953 | + size_t len; | |
4954 | + | |
4955 | + DbgPrint | |
4956 | + ("Novfs_Write_Pages: Handle=0x%p Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%llx\n", | |
4957 | + Handle, DList, DList_Cnt, Bytes, Offset, SessionId); | |
4958 | + | |
4959 | + DList[0].page = NULL; | |
4960 | + DList[0].offset = &lreply; | |
4961 | + DList[0].len = sizeof(lreply); | |
4962 | + DList[0].rwflag = DLWRITE; | |
4963 | + | |
4964 | + len = Bytes; | |
4965 | + cmdlen = offsetof(WRITE_FILE_REQUEST, data); | |
4966 | + | |
4967 | + if (len) { | |
4968 | + cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; | |
4969 | + cmd.Command.SequenceNumber = 0; | |
4970 | + cmd.Command.SessionId = SessionId; | |
4971 | + | |
4972 | + cmd.handle = Handle; | |
4973 | + cmd.len = len; | |
4974 | + cmd.offset = Offset; | |
4975 | + | |
4976 | + retCode = | |
4977 | + Queue_Daemon_Command(&cmd, cmdlen, DList, DList_Cnt, | |
4978 | + (void *)&reply, &replylen, | |
4979 | + INTERRUPTIBLE); | |
4980 | + if (!retCode) { | |
4981 | + if (reply) { | |
4982 | + memcpy(&lreply, reply, sizeof(lreply)); | |
4983 | + } | |
4984 | + switch (lreply.Reply.ErrorCode) { | |
4985 | + case 0: | |
4986 | + retCode = 0; | |
4987 | + break; | |
4988 | + | |
4989 | + case NWE_INSUFFICIENT_SPACE: | |
4990 | + retCode = -ENOSPC; | |
4991 | + break; | |
4992 | + | |
4993 | + case NWE_ACCESS_DENIED: | |
4994 | + retCode = -EACCES; | |
4995 | + break; | |
4996 | + | |
4997 | + default: | |
4998 | + retCode = -EIO; | |
4999 | + break; | |
5000 | + } | |
5001 | + } | |
5002 | + if (reply) { | |
5003 | + kfree(reply); | |
5004 | + } | |
5005 | + } | |
5006 | + DbgPrint("Novfs_Write_Pages retCode=0x%x\n", retCode); | |
5007 | + | |
5008 | + return (retCode); | |
5009 | +} | |
5010 | + | |
5011 | +int Novfs_Read_Stream(HANDLE ConnHandle, unsigned char * Handle, unsigned char * Buffer, | |
5012 | + size_t * Bytes, loff_t * Offset, int User, | |
5013 | + session_t SessionId) | |
5014 | +{ | |
5015 | + READ_STREAM_REQUEST cmd; | |
5016 | + PREAD_STREAM_REPLY reply = NULL; | |
5017 | + unsigned long replylen = 0; | |
5018 | + int retCode = 0; | |
5019 | + size_t len; | |
5020 | + | |
5021 | + len = *Bytes; | |
5022 | + *Bytes = 0; | |
5023 | + | |
5024 | + if ((offsetof(READ_FILE_REPLY, data) + len) > MaxIoSize) { | |
5025 | + len = MaxIoSize - offsetof(READ_FILE_REPLY, data); | |
5026 | + len = (len / PAGE_SIZE) * PAGE_SIZE; | |
5027 | + } | |
5028 | + | |
5029 | + cmd.Command.CommandType = VFS_COMMAND_READ_STREAM; | |
5030 | + cmd.Command.SequenceNumber = 0; | |
5031 | + cmd.Command.SessionId = SessionId; | |
5032 | + | |
5033 | + cmd.connection = ConnHandle; | |
5034 | + memcpy(cmd.handle, Handle, sizeof(cmd.handle)); | |
5035 | + cmd.len = len; | |
5036 | + cmd.offset = *Offset; | |
5037 | + | |
5038 | + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); | |
5039 | + | |
5040 | + DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen); | |
5041 | + | |
5042 | + if (reply) { | |
5043 | + retCode = 0; | |
5044 | + if (reply->Reply.ErrorCode) { | |
5045 | + retCode = -EIO; | |
5046 | + } else { | |
5047 | + replylen -= offsetof(READ_STREAM_REPLY, data); | |
5048 | + if (replylen > 0) { | |
5049 | + if (User) | |
5050 | + replylen -= copy_to_user(Buffer, reply->data, replylen); | |
5051 | + else | |
5052 | + memcpy(Buffer, reply->data, replylen); | |
5053 | + *Bytes = replylen; | |
5054 | + } | |
5055 | + } | |
5056 | + kfree(reply); | |
5057 | + } | |
5058 | + | |
5059 | + DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); | |
5060 | + | |
5061 | + return (retCode); | |
5062 | +} | |
5063 | + | |
5064 | +int Novfs_Write_Stream(HANDLE ConnHandle, unsigned char * Handle, unsigned char * Buffer, | |
5065 | + size_t * Bytes, loff_t * Offset, session_t SessionId) | |
5066 | +{ | |
5067 | + PWRITE_STREAM_REQUEST cmd; | |
5068 | + PWRITE_STREAM_REPLY reply = NULL; | |
5069 | + unsigned long replylen = 0; | |
5070 | + int retCode = 0, cmdlen; | |
5071 | + size_t len; | |
5072 | + | |
5073 | + len = *Bytes; | |
5074 | + cmdlen = len + offsetof(WRITE_STREAM_REQUEST, data); | |
5075 | + *Bytes = 0; | |
5076 | + | |
5077 | + if (cmdlen > MaxIoSize) { | |
5078 | + cmdlen = MaxIoSize; | |
5079 | + len = cmdlen - offsetof(WRITE_STREAM_REQUEST, data); | |
5080 | + } | |
5081 | + | |
5082 | + DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len); | |
5083 | + | |
5084 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
5085 | + | |
5086 | + if (cmd) { | |
5087 | + if (Buffer && len) { | |
5088 | + len -= copy_from_user(cmd->data, Buffer, len); | |
5089 | + } | |
5090 | + | |
5091 | + DbgPrint("Novfs_Write_Stream len=%d\n", len); | |
5092 | + | |
5093 | + cmd->Command.CommandType = VFS_COMMAND_WRITE_STREAM; | |
5094 | + cmd->Command.SequenceNumber = 0; | |
5095 | + cmd->Command.SessionId = SessionId; | |
5096 | + | |
5097 | + cmd->connection = ConnHandle; | |
5098 | + memcpy(cmd->handle, Handle, sizeof(cmd->handle)); | |
5099 | + cmd->len = len; | |
5100 | + cmd->offset = *Offset; | |
5101 | + | |
5102 | + retCode = | |
5103 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
5104 | + &replylen, INTERRUPTIBLE); | |
5105 | + if (reply) { | |
5106 | + switch (reply->Reply.ErrorCode) { | |
5107 | + case 0: | |
5108 | + retCode = 0; | |
5109 | + break; | |
5110 | + | |
5111 | + case NWE_INSUFFICIENT_SPACE: | |
5112 | + retCode = -ENOSPC; | |
5113 | + break; | |
5114 | + | |
5115 | + case NWE_ACCESS_DENIED: | |
5116 | + retCode = -EACCES; | |
5117 | + break; | |
5118 | + | |
5119 | + default: | |
5120 | + retCode = -EIO; | |
5121 | + break; | |
5122 | + } | |
5123 | + DbgPrint | |
5124 | + ("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", | |
5125 | + reply->bytesWritten); | |
5126 | + *Bytes = reply->bytesWritten; | |
5127 | + kfree(reply); | |
5128 | + } | |
5129 | + kfree(cmd); | |
5130 | + } | |
5131 | + DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, | |
5132 | + retCode); | |
5133 | + | |
5134 | + return (retCode); | |
5135 | +} | |
5136 | + | |
5137 | +int Novfs_Close_Stream(HANDLE ConnHandle, unsigned char * Handle, session_t SessionId) | |
5138 | +{ | |
5139 | + CLOSE_STREAM_REQUEST cmd; | |
5140 | + PCLOSE_STREAM_REPLY reply; | |
5141 | + unsigned long replylen = 0; | |
5142 | + int retCode; | |
5143 | + | |
5144 | + cmd.Command.CommandType = VFS_COMMAND_CLOSE_STREAM; | |
5145 | + cmd.Command.SequenceNumber = 0; | |
5146 | + cmd.Command.SessionId = SessionId; | |
5147 | + | |
5148 | + cmd.connection = ConnHandle; | |
5149 | + memcpy(cmd.handle, Handle, sizeof(cmd.handle)); | |
5150 | + | |
5151 | + retCode = | |
5152 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
5153 | + &replylen, 0); | |
5154 | + if (reply) { | |
5155 | + retCode = 0; | |
5156 | + if (reply->Reply.ErrorCode) { | |
5157 | + retCode = -EIO; | |
5158 | + } | |
5159 | + kfree(reply); | |
5160 | + } | |
5161 | + return (retCode); | |
5162 | +} | |
5163 | + | |
5164 | +int Novfs_Delete(unsigned char * Path, int DirectoryFlag, session_t SessionId) | |
5165 | +{ | |
5166 | + PDELETE_FILE_REQUEST cmd; | |
5167 | + PDELETE_FILE_REPLY reply; | |
5168 | + unsigned long replylen = 0; | |
5169 | + int retCode, cmdlen, pathlen; | |
5170 | + | |
5171 | + pathlen = strlen(Path); | |
5172 | + | |
5173 | + if (StripTrailingDots) { | |
5174 | + if ('.' == Path[pathlen - 1]) | |
5175 | + pathlen--; | |
5176 | + } | |
5177 | + | |
5178 | + cmdlen = offsetof(DELETE_FILE_REQUEST, path) + pathlen; | |
5179 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
5180 | + if (cmd) { | |
5181 | + cmd->Command.CommandType = VFS_COMMAND_DELETE_FILE; | |
5182 | + cmd->Command.SequenceNumber = 0; | |
5183 | + cmd->Command.SessionId = SessionId; | |
5184 | + | |
5185 | + cmd->isDirectory = DirectoryFlag; | |
5186 | + cmd->pathlength = pathlen; | |
5187 | + memcpy(cmd->path, Path, pathlen); | |
5188 | + | |
5189 | + retCode = | |
5190 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
5191 | + &replylen, INTERRUPTIBLE); | |
5192 | + if (reply) { | |
5193 | + retCode = 0; | |
5194 | + if (reply->Reply.ErrorCode) { | |
5195 | + if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) { /* Access Denied Error */ | |
5196 | + retCode = -EACCES; | |
5197 | + } else { | |
5198 | + retCode = -EIO; | |
5199 | + } | |
5200 | + } | |
5201 | + kfree(reply); | |
5202 | + } | |
5203 | + kfree(cmd); | |
5204 | + } else { | |
5205 | + retCode = -ENOMEM; | |
5206 | + } | |
5207 | + return (retCode); | |
5208 | +} | |
5209 | + | |
5210 | +int Novfs_Truncate_File(unsigned char * Path, int PathLen, session_t SessionId) | |
5211 | +{ | |
5212 | + PTRUNCATE_FILE_REQUEST cmd; | |
5213 | + PTRUNCATE_FILE_REPLY reply; | |
5214 | + unsigned long replylen = 0; | |
5215 | + int retCode, cmdlen; | |
5216 | + | |
5217 | + if (StripTrailingDots) { | |
5218 | + if ('.' == Path[PathLen - 1]) | |
5219 | + PathLen--; | |
5220 | + } | |
5221 | + cmdlen = offsetof(TRUNCATE_FILE_REQUEST, path) + PathLen; | |
5222 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
5223 | + if (cmd) { | |
5224 | + cmd->Command.CommandType = VFS_COMMAND_TRUNCATE_FILE; | |
5225 | + cmd->Command.SequenceNumber = 0; | |
5226 | + cmd->Command.SessionId = SessionId; | |
5227 | + | |
5228 | + cmd->pathLen = PathLen; | |
5229 | + memcpy(cmd->path, Path, PathLen); | |
5230 | + | |
5231 | + retCode = | |
5232 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
5233 | + &replylen, INTERRUPTIBLE); | |
5234 | + if (reply) { | |
5235 | + if (reply->Reply.ErrorCode) { | |
5236 | + retCode = -EIO; | |
5237 | + } | |
5238 | + kfree(reply); | |
5239 | + } | |
5240 | + kfree(cmd); | |
5241 | + } else { | |
5242 | + retCode = -ENOMEM; | |
5243 | + } | |
5244 | + return (retCode); | |
5245 | +} | |
5246 | + | |
5247 | +int Novfs_Truncate_File_Ex(HANDLE Handle, loff_t Offset, session_t SessionId) | |
5248 | +{ | |
5249 | + WRITE_FILE_REQUEST cmd; | |
5250 | + PWRITE_FILE_REPLY reply = NULL; | |
5251 | + unsigned long replylen = 0; | |
5252 | + int retCode = 0, cmdlen; | |
5253 | + | |
5254 | + DbgPrint("Novfs_Truncate_File_Ex Handle=0x%p Offset=%lld\n", Handle, | |
5255 | + Offset); | |
5256 | + | |
5257 | + cmdlen = offsetof(WRITE_FILE_REQUEST, data); | |
5258 | + | |
5259 | + cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; | |
5260 | + cmd.Command.SequenceNumber = 0; | |
5261 | + cmd.Command.SessionId = SessionId; | |
5262 | + cmd.handle = Handle; | |
5263 | + cmd.len = 0; | |
5264 | + cmd.offset = Offset; | |
5265 | + | |
5266 | + retCode = | |
5267 | + Queue_Daemon_Command(&cmd, cmdlen, NULL, 0, (void *)&reply, | |
5268 | + &replylen, INTERRUPTIBLE); | |
5269 | + | |
5270 | + DbgPrint("Novfs_Truncate_File_Ex retCode=0x%x reply=0x%p\n", retCode, | |
5271 | + reply); | |
5272 | + | |
5273 | + if (!retCode) { | |
5274 | + switch (reply->Reply.ErrorCode) { | |
5275 | + case 0: | |
5276 | + retCode = 0; | |
5277 | + break; | |
5278 | + | |
5279 | + case NWE_INSUFFICIENT_SPACE: | |
5280 | + retCode = -ENOSPC; | |
5281 | + break; | |
5282 | + | |
5283 | + case NWE_ACCESS_DENIED: | |
5284 | + retCode = -EACCES; | |
5285 | + break; | |
5286 | + | |
5287 | + case NWE_FILE_IO_LOCKED: | |
5288 | + retCode = -EBUSY; | |
5289 | + break; | |
5290 | + | |
5291 | + default: | |
5292 | + retCode = -EIO; | |
5293 | + break; | |
5294 | + } | |
5295 | + } | |
5296 | + | |
5297 | + if (reply) { | |
5298 | + kfree(reply); | |
5299 | + } | |
5300 | + | |
5301 | + DbgPrint("Novfs_Truncate_File_Ex retCode=%d\n", retCode); | |
5302 | + | |
5303 | + return (retCode); | |
5304 | +} | |
5305 | + | |
5306 | +int Novfs_Rename_File(int DirectoryFlag, unsigned char * OldName, int OldLen, | |
5307 | + unsigned char * NewName, int NewLen, session_t SessionId) | |
5308 | +{ | |
5309 | + RENAME_FILE_REQUEST cmd; | |
5310 | + PRENAME_FILE_REPLY reply; | |
5311 | + unsigned long replylen = 0; | |
5312 | + int retCode; | |
5313 | + | |
5314 | + DbgPrint("Novfs_Rename_File:\n" | |
5315 | + " DirectoryFlag: %d\n" | |
5316 | + " OldName: %.*s\n" | |
5317 | + " NewName: %.*s\n" | |
5318 | + " SessionId: 0x%llx\n", | |
5319 | + DirectoryFlag, OldLen, OldName, NewLen, NewName, SessionId); | |
5320 | + | |
5321 | + cmd.Command.CommandType = VFS_COMMAND_RENAME_FILE; | |
5322 | + cmd.Command.SequenceNumber = 0; | |
5323 | + cmd.Command.SessionId = SessionId; | |
5324 | + | |
5325 | + cmd.directoryFlag = DirectoryFlag; | |
5326 | + | |
5327 | + if (StripTrailingDots) { | |
5328 | + if ('.' == OldName[OldLen - 1]) | |
5329 | + OldLen--; | |
5330 | + if ('.' == NewName[NewLen - 1]) | |
5331 | + NewLen--; | |
5332 | + } | |
5333 | + | |
5334 | + cmd.newnameLen = NewLen; | |
5335 | + memcpy(cmd.newname, NewName, NewLen); | |
5336 | + | |
5337 | + cmd.oldnameLen = OldLen; | |
5338 | + memcpy(cmd.oldname, OldName, OldLen); | |
5339 | + | |
5340 | + retCode = | |
5341 | + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, | |
5342 | + &replylen, INTERRUPTIBLE); | |
5343 | + if (reply) { | |
5344 | + retCode = 0; | |
5345 | + if (reply->Reply.ErrorCode) { | |
5346 | + retCode = -ENOENT; | |
5347 | + } | |
5348 | + kfree(reply); | |
5349 | + } | |
5350 | + return (retCode); | |
5351 | +} | |
5352 | + | |
5353 | +int Novfs_Set_Attr(unsigned char * Path, struct iattr *Attr, session_t SessionId) | |
5354 | +{ | |
5355 | + PSET_FILE_INFO_REQUEST cmd; | |
5356 | + PSET_FILE_INFO_REPLY reply; | |
5357 | + unsigned long replylen = 0; | |
5358 | + int retCode, cmdlen, pathlen; | |
5359 | + | |
5360 | + pathlen = strlen(Path); | |
5361 | + | |
5362 | + if (StripTrailingDots) { | |
5363 | + if ('.' == Path[pathlen - 1]) | |
5364 | + pathlen--; | |
5365 | + } | |
5366 | + | |
5367 | + cmdlen = offsetof(SET_FILE_INFO_REQUEST, path) + pathlen; | |
5368 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
5369 | + if (cmd) { | |
5370 | + cmd->Command.CommandType = VFS_COMMAND_SET_FILE_INFO; | |
5371 | + cmd->Command.SequenceNumber = 0; | |
5372 | + cmd->Command.SessionId = SessionId; | |
5373 | + cmd->fileInfo.ia_valid = Attr->ia_valid; | |
5374 | + cmd->fileInfo.ia_mode = Attr->ia_mode; | |
5375 | + cmd->fileInfo.ia_uid = Attr->ia_uid; | |
5376 | + cmd->fileInfo.ia_gid = Attr->ia_uid; | |
5377 | + cmd->fileInfo.ia_size = Attr->ia_size; | |
5378 | + cmd->fileInfo.ia_atime = Attr->ia_atime.tv_sec; | |
5379 | + cmd->fileInfo.ia_mtime = Attr->ia_mtime.tv_sec;; | |
5380 | + cmd->fileInfo.ia_ctime = Attr->ia_ctime.tv_sec;; | |
5381 | +/* | |
5382 | + cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags; | |
5383 | +*/ | |
5384 | + cmd->fileInfo.ia_attr_flags = 0; | |
5385 | + | |
5386 | + cmd->pathlength = pathlen; | |
5387 | + memcpy(cmd->path, Path, pathlen); | |
5388 | + | |
5389 | + retCode = | |
5390 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, | |
5391 | + &replylen, INTERRUPTIBLE); | |
5392 | + if (reply) { | |
5393 | + switch (reply->Reply.ErrorCode) { | |
5394 | + case 0: | |
5395 | + retCode = 0; | |
5396 | + break; | |
5397 | + | |
5398 | + case NWE_PARAM_INVALID: | |
5399 | + retCode = -EINVAL; | |
5400 | + break; | |
5401 | + | |
5402 | + case NWE_FILE_IO_LOCKED: | |
5403 | + retCode = -EBUSY; | |
5404 | + break; | |
5405 | + | |
5406 | + default: | |
5407 | + retCode = -EIO; | |
5408 | + break; | |
5409 | + } | |
5410 | + kfree(reply); | |
5411 | + } | |
5412 | + kfree(cmd); | |
5413 | + } else { | |
5414 | + retCode = -ENOMEM; | |
5415 | + } | |
5416 | + return (retCode); | |
5417 | +} | |
5418 | + | |
5419 | +int Novfs_Get_File_Cache_Flag(unsigned char * Path, session_t SessionId) | |
5420 | +{ | |
5421 | + PGET_CACHE_FLAG_REQUEST cmd; | |
5422 | + PGET_CACHE_FLAG_REPLY reply = NULL; | |
5423 | + unsigned long replylen = 0; | |
5424 | + int cmdlen; | |
5425 | + int retCode = 0; | |
5426 | + int pathlen; | |
5427 | + | |
5428 | + DbgPrint("Novfs_Get_File_Cache_Flag: Path = %s\n", Path); | |
5429 | + | |
5430 | + if (Path && *Path) { | |
5431 | + pathlen = strlen(Path); | |
5432 | + if (StripTrailingDots) { | |
5433 | + if ('.' == Path[pathlen - 1]) | |
5434 | + pathlen--; | |
5435 | + } | |
5436 | + cmdlen = offsetof(GET_CACHE_FLAG_REQUEST, path) + pathlen; | |
5437 | + cmd = (PGET_CACHE_FLAG_REQUEST) Novfs_Malloc(cmdlen, GFP_KERNEL); | |
5438 | + if (cmd) { | |
5439 | + cmd->Command.CommandType = VFS_COMMAND_GET_CACHE_FLAG; | |
5440 | + cmd->Command.SequenceNumber = 0; | |
5441 | + cmd->Command.SessionId = SessionId; | |
5442 | + cmd->pathLen = pathlen; | |
5443 | + memcpy(cmd->path, Path, cmd->pathLen); | |
5444 | + | |
5445 | + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, | |
5446 | + (void *)&reply, &replylen, | |
5447 | + INTERRUPTIBLE); | |
5448 | + | |
5449 | + if (reply) { | |
5450 | + | |
5451 | + if (!reply->Reply.ErrorCode) { | |
5452 | + retCode = reply->CacheFlag; | |
5453 | + } | |
5454 | + | |
5455 | + kfree(reply); | |
5456 | + } | |
5457 | + kfree(cmd); | |
5458 | + } | |
5459 | + } | |
5460 | + | |
5461 | + DbgPrint("Novfs_Get_File_Cache_Flag: return %d\n", retCode); | |
5462 | + return (retCode); | |
5463 | +} | |
5464 | + | |
5465 | +/* | |
5466 | + * Arguments: | |
5467 | + * SessionId, file handle, type of lock (read/write or unlock), | |
5468 | + * start of lock area, length of lock area | |
5469 | + * | |
5470 | + * Returns: | |
5471 | + * 0 on success | |
5472 | + * negative value on error | |
5473 | + * | |
5474 | + * Abstract: | |
5475 | + * | |
5476 | + * Notes: lock type - fcntl | |
5477 | + */ | |
5478 | +int Novfs_Set_File_Lock(session_t SessionId, HANDLE Handle, | |
5479 | + unsigned char fl_type, loff_t fl_start, loff_t fl_len) | |
5480 | +{ | |
5481 | + PSET_FILE_LOCK_REQUEST cmd; | |
5482 | + PSET_FILE_LOCK_REPLY reply = NULL; | |
5483 | + unsigned long replylen = 0; | |
5484 | + int retCode; | |
5485 | + | |
5486 | + retCode = -1; | |
5487 | + | |
5488 | + DbgPrint("Novfs_Set_File_Lock:\n" | |
5489 | + " SessionId: 0x%llx\n", SessionId); | |
5490 | + | |
5491 | + cmd = | |
5492 | + (PSET_FILE_LOCK_REQUEST) Novfs_Malloc(sizeof(SET_FILE_LOCK_REQUEST), | |
5493 | + GFP_KERNEL); | |
5494 | + | |
5495 | + if (cmd) { | |
5496 | + DbgPrint("Novfs_Set_File_Lock 2\n"); | |
5497 | + | |
5498 | + cmd->Command.CommandType = VFS_COMMAND_SET_FILE_LOCK; | |
5499 | + cmd->Command.SequenceNumber = 0; | |
5500 | + cmd->Command.SessionId = SessionId; | |
5501 | + | |
5502 | + cmd->handle = Handle; | |
5503 | + if (F_RDLCK == fl_type) { | |
5504 | + fl_type = 1; // LockRegionExclusive | |
5505 | + } else if (F_WRLCK == fl_type) { | |
5506 | + fl_type = 0; // LockRegionShared | |
5507 | + } | |
5508 | + | |
5509 | + cmd->fl_type = fl_type; | |
5510 | + cmd->fl_start = fl_start; | |
5511 | + cmd->fl_len = fl_len; | |
5512 | + | |
5513 | + DbgPrint("Novfs_Set_File_Lock 3\n"); | |
5514 | + | |
5515 | + DbgPrint("Novfs_Set_File_Lock: BEGIN dump arguments\n"); | |
5516 | + DbgPrint("Novfs_Set_File_Lock: Queue_Daemon_Command %d\n", | |
5517 | + cmd->Command.CommandType); | |
5518 | + DbgPrint("Novfs_Set_File_Lock: cmd->handle = 0x%p\n", | |
5519 | + cmd->handle); | |
5520 | + DbgPrint("Novfs_Set_File_Lock: cmd->fl_type = %u\n", | |
5521 | + cmd->fl_type); | |
5522 | + DbgPrint("Novfs_Set_File_Lock: cmd->fl_start = 0x%X\n", | |
5523 | + cmd->fl_start); | |
5524 | + DbgPrint("Novfs_Set_File_Lock: cmd->fl_len = 0x%X\n", | |
5525 | + cmd->fl_len); | |
5526 | + DbgPrint | |
5527 | + ("Novfs_Set_File_Lock: sizeof(SET_FILE_LOCK_REQUEST) = %u\n", | |
5528 | + sizeof(SET_FILE_LOCK_REQUEST)); | |
5529 | + DbgPrint("Novfs_Set_File_Lock: END dump arguments\n"); | |
5530 | + | |
5531 | + retCode = | |
5532 | + Queue_Daemon_Command(cmd, sizeof(SET_FILE_LOCK_REQUEST), | |
5533 | + NULL, 0, (void *)&reply, &replylen, | |
5534 | + INTERRUPTIBLE); | |
5535 | + DbgPrint("Novfs_Set_File_Lock 4\n"); | |
5536 | + | |
5537 | + if (reply) { | |
5538 | + DbgPrint("Novfs_Set_File_Lock 5, ErrorCode = %X\n", | |
5539 | + reply->Reply.ErrorCode); | |
5540 | + | |
5541 | + if (reply->Reply.ErrorCode) { | |
5542 | + retCode = reply->Reply.ErrorCode; | |
5543 | + } | |
5544 | + kfree(reply); | |
5545 | + } | |
5546 | + | |
5547 | + kfree(cmd); | |
5548 | + } | |
5549 | + | |
5550 | + DbgPrint("Novfs_Set_File_Lock 6\n"); | |
5551 | + | |
5552 | + return (retCode); | |
5553 | +} | |
5554 | --- /dev/null | |
5555 | +++ b/fs/novfs/inode.c | |
5556 | @@ -0,0 +1,5563 @@ | |
5557 | +/* | |
5558 | + * Novell NCP Redirector for Linux | |
5559 | + * Author: James Turner | |
5560 | + * | |
5561 | + * This file contains functions used to control access to the Linux file | |
5562 | + * system. | |
5563 | + * | |
5564 | + * Copyright (C) 2005 Novell, Inc. | |
5565 | + * | |
5566 | + * This program is free software; you can redistribute it and/or | |
5567 | + * modify it under the terms of the GNU General Public License | |
5568 | + * as published by the Free Software Foundation; either version 2 | |
5569 | + * of the License, or (at your option) any later version. | |
5570 | + */ | |
5571 | + | |
5572 | +#include <linux/module.h> | |
5573 | +#include <linux/autoconf.h> | |
5574 | +#include <linux/init.h> | |
5575 | +#include <linux/fs.h> | |
5576 | +#include <linux/dcache.h> | |
5577 | +#include <linux/mount.h> | |
5578 | +#include <linux/pagemap.h> | |
5579 | +#include <linux/string.h> | |
5580 | +#include <linux/smp_lock.h> | |
5581 | +#include <linux/slab.h> | |
5582 | +#include <linux/unistd.h> | |
5583 | +#include <asm/statfs.h> | |
5584 | +#include <asm/uaccess.h> | |
5585 | +#include <linux/ctype.h> | |
5586 | +#include <linux/statfs.h> | |
5587 | +#include <linux/pagevec.h> | |
5588 | +#include <linux/writeback.h> | |
5589 | +#include <linux/backing-dev.h> | |
5590 | +#include <linux/mm.h> | |
5591 | +#include <linux/file.h> | |
5592 | + | |
5593 | +/*===[ Include files specific to this module ]============================*/ | |
5594 | +#include "vfs.h" | |
5595 | + | |
5596 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | |
5597 | +#define FSPRIVATE u.generic_ip | |
5598 | +#else | |
5599 | +#define FSPRIVATE i_private | |
5600 | +#endif | |
5601 | + | |
5602 | + | |
5603 | +#define FILE_UPDATE_TIMEOUT 2 | |
5604 | + | |
5605 | +struct inode_data { | |
5606 | + void *Scope; | |
5607 | + unsigned long Flags; | |
5608 | + struct list_head IList; | |
5609 | + struct inode *Inode; | |
5610 | + unsigned long cntDC; | |
5611 | + struct list_head DirCache; | |
5612 | + struct semaphore DirCacheLock; | |
5613 | + HANDLE FileHandle; | |
5614 | + int CacheFlag; | |
5615 | + char Name[1]; /* Needs to be last entry */ | |
5616 | +}; | |
5617 | + | |
5618 | +// FIXME these are wrong, but fake the compiler out for now until the proper people can be flogged... | |
5619 | +extern void *Scope_Get_ScopefromName(struct qstr *Name); | |
5620 | +extern void *Scope_Get_ScopefromPath(struct dentry *Dentry); | |
5621 | + | |
5622 | +/*===[ Function prototypes ]==============================================*/ | |
5623 | +int Novfs_Remove_from_Root(char *RemoveName); | |
5624 | +int Novfs_Add_to_Root(char *); | |
5625 | +char *Novfs_dget_path(struct dentry *d, char *path, unsigned int pathlen); | |
5626 | +int verify_dentry(struct dentry *dentry, int Flags); | |
5627 | +int invalidate_dentry(struct dentry *parent); | |
5628 | +struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name); | |
5629 | +int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add); | |
5630 | +int Novfs_d_strcmp(struct qstr *s1, struct qstr *s2); | |
5631 | +unsigned long Novfs_internal_hash(struct qstr *name); | |
5632 | + | |
5633 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
5634 | +int Novfs_get_sb(struct file_system_type *Fstype, int Flags, | |
5635 | + const char *Dev_name, void *Data, struct vfsmount *Mnt); | |
5636 | +#else | |
5637 | +struct super_block *Novfs_get_sb(struct file_system_type *Fstype, int Flags, | |
5638 | + const char *Dev_name, void *Data); | |
5639 | +#endif | |
5640 | + | |
5641 | +int Novfs_fill_super(struct super_block *SB, void *Data, int Silent); | |
5642 | + | |
5643 | +/* | |
5644 | + * Declared dentry_operations | |
5645 | + */ | |
5646 | +int Novfs_d_revalidate(struct dentry *, struct nameidata *); | |
5647 | +int Novfs_d_hash(struct dentry *, struct qstr *); | |
5648 | +int Novfs_d_compare(struct dentry *, struct qstr *, struct qstr *); | |
5649 | +int Novfs_d_delete(struct dentry *dentry); | |
5650 | +void Novfs_d_release(struct dentry *dentry); | |
5651 | +void Novfs_d_iput(struct dentry *dentry, struct inode *inode); | |
5652 | + | |
5653 | +/* | |
5654 | + * Declared directory operations | |
5655 | + */ | |
5656 | +int Novfs_dir_open(struct inode *inode, struct file *file); | |
5657 | +int Novfs_dir_release(struct inode *inode, struct file *file); | |
5658 | +loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin); | |
5659 | +ssize_t Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t * off); | |
5660 | +void addtodentry(struct dentry *Parent, unsigned char *List, int Level); | |
5661 | +int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, | |
5662 | + ino_t ino, unsigned ftype); | |
5663 | +int Novfs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir); | |
5664 | +int Novfs_dir_fsync(struct file *file, struct dentry *dentry, int datasync); | |
5665 | + | |
5666 | +/* | |
5667 | + * Declared address space operations | |
5668 | + */ | |
5669 | +int Novfs_a_writepage(struct page *page, struct writeback_control *wbc); | |
5670 | +int Novfs_a_writepages(struct address_space *mapping, | |
5671 | + struct writeback_control *wbc); | |
5672 | +int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, | |
5673 | + unsigned to); | |
5674 | +int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, | |
5675 | + unsigned to); | |
5676 | +int Novfs_a_readpage(struct file *file, struct page *page); | |
5677 | +int Novfs_a_readpages(struct file *file, struct address_space *mapping, | |
5678 | + struct list_head *page_lst, unsigned nr_pages); | |
5679 | +ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb, const struct iovec *iov, | |
5680 | + loff_t offset, unsigned long nr_segs); | |
5681 | + | |
5682 | +/* | |
5683 | + * Declared file_operations | |
5684 | + */ | |
5685 | +ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *); | |
5686 | +ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *); | |
5687 | +int Novfs_f_readdir(struct file *, void *, filldir_t); | |
5688 | +int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | |
5689 | +int Novfs_f_mmap(struct file *file, struct vm_area_struct *vma); | |
5690 | +int Novfs_f_open(struct inode *, struct file *); | |
5691 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) | |
5692 | +int Novfs_f_flush(struct file *); | |
5693 | +#else | |
5694 | +int Novfs_f_flush(struct file *, fl_owner_t); | |
5695 | +#endif | |
5696 | +int Novfs_f_release(struct inode *, struct file *); | |
5697 | +int Novfs_f_fsync(struct file *, struct dentry *, int datasync); | |
5698 | +int Novfs_f_lock(struct file *, int, struct file_lock *); | |
5699 | + | |
5700 | +/* | |
5701 | + * Declared inode_operations | |
5702 | + */ | |
5703 | +int Novfs_i_create(struct inode *, struct dentry *, int, struct nameidata *); | |
5704 | +struct dentry *Novfs_i_lookup(struct inode *, struct dentry *, | |
5705 | + struct nameidata *); | |
5706 | +int Novfs_i_mkdir(struct inode *, struct dentry *, int); | |
5707 | +int Novfs_i_unlink(struct inode *dir, struct dentry *dentry); | |
5708 | +int Novfs_i_rmdir(struct inode *, struct dentry *); | |
5709 | +int Novfs_i_mknod(struct inode *, struct dentry *, int, dev_t); | |
5710 | +int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, | |
5711 | + struct dentry *); | |
5712 | +int Novfs_i_permission(struct inode *inode, int mask); | |
5713 | +int Novfs_i_setattr(struct dentry *, struct iattr *); | |
5714 | +int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *); | |
5715 | +int Novfs_i_revalidate(struct dentry *dentry); | |
5716 | + | |
5717 | +/* | |
5718 | + * Extended attributes operations | |
5719 | + */ | |
5720 | + | |
5721 | +int Novfs_i_getxattr(struct dentry *dentry, const char *name, void *buffer, | |
5722 | + size_t size); | |
5723 | +int Novfs_i_setxattr(struct dentry *dentry, const char *name, const void *value, | |
5724 | + size_t value_size, int flags); | |
5725 | +int Novfs_i_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); | |
5726 | + | |
5727 | +void update_inode(struct inode *Inode, struct entry_info *Info); | |
5728 | + | |
5729 | +/* | |
5730 | + * Declared super_operations | |
5731 | + */ | |
5732 | +void Novfs_read_inode(struct inode *inode); | |
5733 | +void Novfs_write_inode(struct inode *inode); | |
5734 | +int Novfs_notify_change(struct dentry *dentry, struct iattr *attr); | |
5735 | +void Novfs_clear_inode(struct inode *inode); | |
5736 | +int Novfs_show_options(struct seq_file *s, struct vfsmount *m); | |
5737 | + | |
5738 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
5739 | +int Novfs_statfs(struct dentry *de, struct kstatfs *buf); | |
5740 | +#else | |
5741 | +int Novfs_statfs(struct super_block *sb, struct kstatfs *buf); | |
5742 | +#endif | |
5743 | + | |
5744 | +/* | |
5745 | + * Declared control interface functions | |
5746 | + */ | |
5747 | +ssize_t | |
5748 | +Novfs_Control_read(struct file *file, char *buf, size_t nbytes, loff_t * ppos); | |
5749 | + | |
5750 | +ssize_t | |
5751 | +Novfs_Control_write(struct file *file, const char *buf, size_t nbytes, | |
5752 | + loff_t * ppos); | |
5753 | + | |
5754 | +int Novfs_Control_ioctl(struct inode *inode, struct file *file, | |
5755 | + unsigned int cmd, unsigned long arg); | |
5756 | + | |
5757 | +int __init init_novfs(void); | |
5758 | +void __exit exit_novfs(void); | |
5759 | + | |
5760 | +int Novfs_lock_inode_cache(struct inode *i); | |
5761 | +void Novfs_unlock_inode_cache(struct inode *i); | |
5762 | +int Novfs_enumerate_inode_cache(struct inode *i, struct list_head **iteration, | |
5763 | + ino_t * ino, struct entry_info *info); | |
5764 | +int Novfs_get_entry(struct inode *i, struct qstr *name, ino_t * ino, | |
5765 | + struct entry_info *info); | |
5766 | +int Novfs_get_entry_by_pos(struct inode *i, loff_t pos, ino_t * ino, | |
5767 | + struct entry_info *info); | |
5768 | +int Novfs_get_entry_time(struct inode *i, struct qstr *name, ino_t * ino, | |
5769 | + struct entry_info *info, u64 * EntryTime); | |
5770 | +int Novfs_get_remove_entry(struct inode *i, ino_t * ino, struct entry_info *info); | |
5771 | +void Novfs_invalidate_inode_cache(struct inode *i); | |
5772 | +static struct dir_cache *Novfs_lookup_inode_cache(struct inode *i, struct qstr *name, ino_t ino); | |
5773 | +int Novfs_lookup_validate(struct inode *i, struct qstr *name, ino_t ino); | |
5774 | +int Novfs_add_inode_entry(struct inode *i, struct qstr *name, ino_t ino, | |
5775 | + struct entry_info *info); | |
5776 | +int Novfs_update_entry(struct inode *i, struct qstr *name, ino_t ino, | |
5777 | + struct entry_info *info); | |
5778 | +void Novfs_remove_inode_entry(struct inode *i, struct qstr *name, ino_t ino); | |
5779 | +void Novfs_free_invalid_entries(struct inode *i); | |
5780 | +void Novfs_free_inode_cache(struct inode *i); | |
5781 | + | |
5782 | +/*===[ Global variables ]=================================================*/ | |
5783 | +struct dentry_operations Novfs_dentry_operations = { | |
5784 | + .d_revalidate = Novfs_d_revalidate, | |
5785 | + .d_hash = Novfs_d_hash, | |
5786 | + .d_compare = Novfs_d_compare, | |
5787 | + //.d_delete = Novfs_d_delete, | |
5788 | + .d_release = Novfs_d_release, | |
5789 | + .d_iput = Novfs_d_iput, | |
5790 | +}; | |
5791 | + | |
5792 | +struct file_operations Novfs_dir_operations = { | |
5793 | + .owner = THIS_MODULE, | |
5794 | + .open = Novfs_dir_open, | |
5795 | + .release = Novfs_dir_release, | |
5796 | + .llseek = Novfs_dir_lseek, | |
5797 | + .read = Novfs_dir_read, | |
5798 | + .readdir = Novfs_dir_readdir, | |
5799 | + .fsync = Novfs_dir_fsync, | |
5800 | +}; | |
5801 | + | |
5802 | +static struct file_operations Novfs_file_operations = { | |
5803 | + .owner = THIS_MODULE, | |
5804 | + .read = Novfs_f_read, | |
5805 | + .write = Novfs_f_write, | |
5806 | + .readdir = Novfs_f_readdir, | |
5807 | + .ioctl = Novfs_f_ioctl, | |
5808 | + .mmap = Novfs_f_mmap, | |
5809 | + .open = Novfs_f_open, | |
5810 | + .flush = Novfs_f_flush, | |
5811 | + .release = Novfs_f_release, | |
5812 | + .fsync = Novfs_f_fsync, | |
5813 | + .llseek = generic_file_llseek, | |
5814 | + .lock = Novfs_f_lock, | |
5815 | +}; | |
5816 | + | |
5817 | +static struct address_space_operations Novfs_nocache_aops = { | |
5818 | + .readpage = Novfs_a_readpage, | |
5819 | +}; | |
5820 | + | |
5821 | +struct backing_dev_info Novfs_backing_dev_info = { | |
5822 | + .ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE, | |
5823 | + .state = 0, | |
5824 | + .capabilities = BDI_CAP_NO_WRITEBACK | BDI_CAP_MAP_COPY, | |
5825 | + .unplug_io_fn = default_unplug_io_fn, | |
5826 | +}; | |
5827 | + | |
5828 | +static struct address_space_operations Novfs_aops = { | |
5829 | + .readpage = Novfs_a_readpage, | |
5830 | + .readpages = Novfs_a_readpages, | |
5831 | + .writepage = Novfs_a_writepage, | |
5832 | + .writepages = Novfs_a_writepages, | |
5833 | + .prepare_write = Novfs_a_prepare_write, | |
5834 | + .commit_write = Novfs_a_commit_write, | |
5835 | + .set_page_dirty = __set_page_dirty_nobuffers, | |
5836 | + .direct_IO = Novfs_a_direct_IO, | |
5837 | +}; | |
5838 | + | |
5839 | +static struct inode_operations Novfs_inode_operations = { | |
5840 | + .create = Novfs_i_create, | |
5841 | + .lookup = Novfs_i_lookup, | |
5842 | + .unlink = Novfs_i_unlink, | |
5843 | + .mkdir = Novfs_i_mkdir, | |
5844 | + .rmdir = Novfs_i_rmdir, | |
5845 | + .mknod = Novfs_i_mknod, | |
5846 | + .rename = Novfs_i_rename, | |
5847 | + .setattr = Novfs_i_setattr, | |
5848 | + .getattr = Novfs_i_getattr, | |
5849 | +/* | |
5850 | + .getxattr = Novfs_i_getxattr, | |
5851 | + .setxattr = Novfs_i_setxattr, | |
5852 | + .listxattr = Novfs_i_listxattr, | |
5853 | +*/ | |
5854 | +}; | |
5855 | + | |
5856 | +static struct inode_operations Novfs_file_inode_operations = { | |
5857 | + .setattr = Novfs_i_setattr, | |
5858 | + .getattr = Novfs_i_getattr, | |
5859 | +/* | |
5860 | + .getxattr = Novfs_i_getxattr, | |
5861 | + .setxattr = Novfs_i_setxattr, | |
5862 | + .listxattr = Novfs_i_listxattr, | |
5863 | +*/ | |
5864 | +}; | |
5865 | + | |
5866 | +static struct super_operations Novfs_ops = { | |
5867 | + .statfs = Novfs_statfs, | |
5868 | + .clear_inode = Novfs_clear_inode, | |
5869 | + .drop_inode = generic_delete_inode, | |
5870 | + .show_options = Novfs_show_options, | |
5871 | + | |
5872 | +}; | |
5873 | + | |
5874 | +/* Not currently used | |
5875 | +static struct file_operations Novfs_Control_operations = { | |
5876 | + .read = Novfs_Control_read, | |
5877 | + .write = Novfs_Control_write, | |
5878 | + .ioctl = Novfs_Control_ioctl, | |
5879 | +}; | |
5880 | +*/ | |
5881 | + | |
5882 | +static atomic_t Novfs_Inode_Number = ATOMIC_INIT(0); | |
5883 | + | |
5884 | +struct dentry *Novfs_root = NULL; | |
5885 | + | |
5886 | +int Novfs_Version_Major = NOVFS_VFS_MAJOR; | |
5887 | +int Novfs_Version_Minor = NOVFS_VFS_MINOR; | |
5888 | +int Novfs_Version_Sub = NOVFS_VFS_SUB; | |
5889 | +int Novfs_Version_Release = NOVFS_VFS_RELEASE; | |
5890 | + | |
5891 | +char *Novfs_CurrentMount = NULL; | |
5892 | + | |
5893 | +DECLARE_MUTEX(InodeList_lock); | |
5894 | + | |
5895 | +LIST_HEAD(InodeList); | |
5896 | + | |
5897 | +DECLARE_MUTEX(TimeDir_Lock); | |
5898 | +uint64_t lastTime; | |
5899 | +char lastDir[PATH_MAX]; | |
5900 | + | |
5901 | +uint64_t inHAXTime; | |
5902 | +int inHAX; | |
5903 | + | |
5904 | +unsigned long InodeCount = 0, DCCount = 0; | |
5905 | +unsigned long File_update_timeout = FILE_UPDATE_TIMEOUT; | |
5906 | +int PageCache = 0; | |
5907 | + | |
5908 | +typedef struct _Novfs_List2 { | |
5909 | + struct list_head list; | |
5910 | + void *data; | |
5911 | +} Novfs_List2; | |
5912 | + | |
5913 | +typedef struct _File_Private2 { | |
5914 | + int listedall; | |
5915 | + HANDLE enumHandle; | |
5916 | +} FilePrivate2; | |
5917 | + | |
5918 | +static void PRINT_DENTRY(const char *s, struct dentry *d) | |
5919 | +{ | |
5920 | + DbgPrint("%s: 0x%p\n", s, d); | |
5921 | + DbgPrint(" d_count: 0x%x\n", d->d_count); | |
5922 | + DbgPrint(" d_lock: 0x%x\n", d->d_lock); | |
5923 | + DbgPrint(" d_inode: 0x%x\n", d->d_inode); | |
5924 | + DbgPrint(" d_lru: 0x%p\n" | |
5925 | + " next: 0x%p\n" | |
5926 | + " prev: 0x%p\n", &d->d_lru, d->d_lru.next, | |
5927 | + d->d_lru.prev); | |
5928 | + DbgPrint(" d_child: 0x%p\n" " next: 0x%p\n" | |
5929 | + " prev: 0x%p\n", &d->D_CHILD, d->D_CHILD.next, | |
5930 | + d->D_CHILD.prev); | |
5931 | + DbgPrint(" d_subdirs: 0x%p\n" " next: 0x%p\n" | |
5932 | + " prev: 0x%p\n", &d->d_subdirs, d->d_subdirs.next, | |
5933 | + d->d_subdirs.prev); | |
5934 | + DbgPrint(" d_alias: 0x%p\n" " next: 0x%p\n" | |
5935 | + " prev: 0x%p\n", &d->d_alias, d->d_alias.next, | |
5936 | + d->d_alias.prev); | |
5937 | + DbgPrint(" d_time: 0x%x\n", d->d_time); | |
5938 | + DbgPrint(" d_op: 0x%p\n", d->d_op); | |
5939 | + DbgPrint(" d_sb: 0x%p\n", d->d_sb); | |
5940 | + DbgPrint(" d_flags: 0x%x\n", d->d_flags); | |
5941 | + DbgPrint(" d_mounted: 0x%x\n", d->d_mounted); | |
5942 | + DbgPrint(" d_fsdata: 0x%p\n", d->d_fsdata); | |
5943 | +/* DbgPrint(" d_cookie: 0x%x\n", d->d_cookie); */ | |
5944 | + DbgPrint(" d_parent: 0x%p\n", d->d_parent); | |
5945 | + DbgPrint(" d_name: 0x%p %.*s\n", &d->d_name, d->d_name.len, | |
5946 | + d->d_name.name); | |
5947 | + DbgPrint(" name: 0x%p\n" " len: %d\n" | |
5948 | + " hash: 0x%x\n", d->d_name.name, d->d_name.len, | |
5949 | + d->d_name.hash); | |
5950 | + DbgPrint(" d_hash: 0x%x\n" " next: 0x%x\n" | |
5951 | + " pprev: 0x%x\n", d->d_hash, d->d_hash.next, | |
5952 | + d->d_hash.pprev); | |
5953 | +} | |
5954 | + | |
5955 | +/*++======================================================================*/ | |
5956 | +int Novfs_Remove_from_Root(char *RemoveName) | |
5957 | +/* | |
5958 | + * Arguments: | |
5959 | + * | |
5960 | + * Returns: | |
5961 | + * | |
5962 | + * Abstract: | |
5963 | + * | |
5964 | + * Notes: | |
5965 | + * | |
5966 | + * Environment: | |
5967 | + * | |
5968 | + *========================================================================*/ | |
5969 | +{ | |
5970 | + struct qstr name; | |
5971 | + struct dentry *dentry; | |
5972 | + struct inode *dir; | |
5973 | + | |
5974 | + DbgPrint("Novfs_Remove_from_Root: %s\n", RemoveName); | |
5975 | + name.len = strlen(RemoveName); | |
5976 | + name.name = RemoveName; | |
5977 | + Novfs_d_hash(Novfs_root, &name); | |
5978 | + | |
5979 | + dentry = d_lookup(Novfs_root, &name); | |
5980 | + if (dentry) { | |
5981 | + if (dentry->d_inode && dentry->d_inode->FSPRIVATE) { | |
5982 | + ((struct inode_data *)(dentry->d_inode->FSPRIVATE))->Scope = | |
5983 | + NULL; | |
5984 | + } | |
5985 | + dput(dentry); | |
5986 | + } | |
5987 | + | |
5988 | + dir = Novfs_root->d_inode; | |
5989 | + | |
5990 | + Novfs_lock_inode_cache(dir); | |
5991 | + Novfs_remove_inode_entry(dir, &name, 0); | |
5992 | + Novfs_unlock_inode_cache(dir); | |
5993 | + | |
5994 | + return (0); | |
5995 | +} | |
5996 | + | |
5997 | +/*++======================================================================*/ | |
5998 | +int Novfs_Add_to_Root(char *AddName) | |
5999 | +/* | |
6000 | + * Arguments: | |
6001 | + * | |
6002 | + * Returns: | |
6003 | + * | |
6004 | + * Abstract: | |
6005 | + * | |
6006 | + * Notes: | |
6007 | + * | |
6008 | + * Environment: | |
6009 | + * | |
6010 | + *========================================================================*/ | |
6011 | +{ | |
6012 | + struct qstr name; | |
6013 | + struct inode *dir; | |
6014 | + struct entry_info info; | |
6015 | + ino_t ino; | |
6016 | + | |
6017 | + DbgPrint("Novfs_Add_to_Root: %s\n", AddName); | |
6018 | + name.len = strlen(AddName); | |
6019 | + name.name = AddName; | |
6020 | + Novfs_d_hash(Novfs_root, &name); | |
6021 | + | |
6022 | + dir = Novfs_root->d_inode; | |
6023 | + | |
6024 | + Novfs_lock_inode_cache(dir); | |
6025 | + | |
6026 | + ino = 0; | |
6027 | + | |
6028 | + if (!Novfs_lookup_inode_cache(dir, &name, 0)) { | |
6029 | + info.mode = S_IFDIR | 0700; | |
6030 | + info.size = 0; | |
6031 | + info.atime = info.ctime = info.mtime = CURRENT_TIME; | |
6032 | + | |
6033 | + ino = (ino_t)atomic_inc_return(&Novfs_Inode_Number); | |
6034 | + Novfs_add_inode_entry(dir, &name, ino, &info); | |
6035 | + } | |
6036 | + | |
6037 | + Novfs_unlock_inode_cache(dir); | |
6038 | + | |
6039 | + return (0); | |
6040 | +} | |
6041 | + | |
6042 | +/*++======================================================================*/ | |
6043 | +int Novfs_Add_to_Root2(char *AddName) | |
6044 | +/* | |
6045 | + * Arguments: | |
6046 | + * | |
6047 | + * Returns: | |
6048 | + * | |
6049 | + * Abstract: | |
6050 | + * | |
6051 | + * Notes: | |
6052 | + * | |
6053 | + * Environment: | |
6054 | + * | |
6055 | + *========================================================================*/ | |
6056 | +{ | |
6057 | + struct dentry *entry; | |
6058 | + struct qstr name; | |
6059 | + struct inode *inode; | |
6060 | + void *scope; | |
6061 | + | |
6062 | + DbgPrint("Novfs_Add_to_Root: %s\n", AddName); | |
6063 | + name.len = strlen(AddName); | |
6064 | + name.name = AddName; | |
6065 | + | |
6066 | + Novfs_d_hash(Novfs_root, &name); | |
6067 | + | |
6068 | + entry = Novfs_d_lookup(Novfs_root, &name); | |
6069 | + DbgPrint("Novfs_Add_to_Root: Novfs_d_lookup 0x%p\n", entry); | |
6070 | + if (NULL == entry) { | |
6071 | + scope = Scope_Lookup(); | |
6072 | + | |
6073 | + entry = d_alloc(Novfs_root, &name); | |
6074 | + DbgPrint("Novfs_Add_to_Root: d_alloc 0x%p\n", entry); | |
6075 | + if (entry) { | |
6076 | + entry->d_op = &Novfs_dentry_operations; | |
6077 | + entry->d_time = jiffies + (File_update_timeout * HZ); | |
6078 | + /* | |
6079 | + * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name ); | |
6080 | + */ | |
6081 | + inode = | |
6082 | + Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name); | |
6083 | + DbgPrint("Novfs_Add_to_Root: Inode=0x%p\n", inode); | |
6084 | + if (inode) { | |
6085 | + inode->i_atime = | |
6086 | + inode->i_ctime = | |
6087 | + inode->i_mtime = CURRENT_TIME; | |
6088 | + if (!Novfs_d_add(Novfs_root, entry, inode, 1)) { | |
6089 | + if (inode->FSPRIVATE) { | |
6090 | + ((struct inode_data *) inode-> | |
6091 | + FSPRIVATE)->Flags = USER_INODE; | |
6092 | + } | |
6093 | + PRINT_DENTRY("After Novfs_d_add", | |
6094 | + entry); | |
6095 | + } else { | |
6096 | + dput(entry); | |
6097 | + iput(inode); | |
6098 | + } | |
6099 | + } | |
6100 | + } | |
6101 | + } else { | |
6102 | + dput(entry); | |
6103 | + PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry); | |
6104 | + } | |
6105 | + return (0); | |
6106 | +} | |
6107 | + | |
6108 | +/*++======================================================================*/ | |
6109 | +char *Novfs_dget_path(struct dentry *Dentry, char *Buf, unsigned int Buflen) | |
6110 | +/* | |
6111 | + * Arguments: struct dentry *Dentry - starting entry | |
6112 | + * char *Buf - pointer to memory buffer | |
6113 | + * unsigned int Buflen - size of memory buffer | |
6114 | + * | |
6115 | + * Returns: pointer to path. | |
6116 | + * | |
6117 | + * Abstract: Walks the dentry chain building a path. | |
6118 | + * | |
6119 | + * Notes: | |
6120 | + * | |
6121 | + * Environment: | |
6122 | + * | |
6123 | + *========================================================================*/ | |
6124 | +{ | |
6125 | + char *retval = &Buf[Buflen]; | |
6126 | + struct dentry *p = Dentry; | |
6127 | + | |
6128 | + *(--retval) = '\0'; | |
6129 | + Buflen--; | |
6130 | + | |
6131 | + if (!IS_ROOT(p) && !IS_ROOT(p->d_parent)) { | |
6132 | + while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent)) { | |
6133 | + if (Buflen > p->d_name.len) { | |
6134 | + retval -= p->d_name.len; | |
6135 | + Buflen -= p->d_name.len; | |
6136 | + memcpy(retval, p->d_name.name, p->d_name.len); | |
6137 | + *(--retval) = '\\'; | |
6138 | + Buflen--; | |
6139 | + p = p->d_parent; | |
6140 | + } else { | |
6141 | + retval = NULL; | |
6142 | + break; | |
6143 | + } | |
6144 | + } | |
6145 | + } else { | |
6146 | + *(--retval) = '\\'; | |
6147 | + } | |
6148 | + | |
6149 | + if (retval) | |
6150 | + DbgPrint("Novfs_dget_path: %s\n", retval); | |
6151 | + return (retval); | |
6152 | +} | |
6153 | + | |
6154 | +/*++======================================================================*/ | |
6155 | +int verify_dentry(struct dentry *dentry, int Flags) | |
6156 | +/* | |
6157 | + * Arguments: struct dentry *dentry - entry to verify | |
6158 | + * | |
6159 | + * Returns: zero - Inode cache has been updated. If not in the cache | |
6160 | + * then file doesn't exist. | |
6161 | + * !zero - Error | |
6162 | + * | |
6163 | + * Abstract: This routine will verify if the file that dentry is pointing | |
6164 | + * at exist and if it does it will put it in the inode cache of | |
6165 | + * the parent. | |
6166 | + * | |
6167 | + * Notes: | |
6168 | + * | |
6169 | + * Environment: | |
6170 | + * | |
6171 | + *========================================================================*/ | |
6172 | +{ | |
6173 | + int retVal = -ENOENT; | |
6174 | + struct inode *dir; | |
6175 | + struct entry_info *info = NULL; | |
6176 | + struct inode_data *id; | |
6177 | + session_t session; | |
6178 | + char *path, *list = NULL, *cp; | |
6179 | + ino_t ino = 0; | |
6180 | + struct qstr name; | |
6181 | + int iLock = 0; | |
6182 | + struct dentry *parent = NULL; | |
6183 | + u64 ctime; | |
6184 | + struct inode *inode; | |
6185 | + | |
6186 | + if (IS_ROOT(dentry)) { | |
6187 | + DbgPrint("verify_dentry: Root entry\n"); | |
6188 | + return (0); | |
6189 | + } | |
6190 | + | |
6191 | + if (dentry && dentry->d_parent && | |
6192 | + (dir = dentry->d_parent->d_inode) && (id = dir->FSPRIVATE)) { | |
6193 | + parent = dget_parent(dentry); | |
6194 | + | |
6195 | + info = Novfs_Malloc(sizeof(struct entry_info) + PATH_LENGTH_BUFFER, GFP_KERNEL); | |
6196 | + | |
6197 | + if (info) { | |
6198 | + if (Novfs_lock_inode_cache(dir)) { | |
6199 | + name.len = dentry->d_name.len; | |
6200 | + name.name = dentry->d_name.name; | |
6201 | + name.hash = Novfs_internal_hash(&name); | |
6202 | + if (!Novfs_get_entry_time(dir, &name, &ino, info, &ctime)) { | |
6203 | + inode = dentry->d_inode; | |
6204 | + if (inode && inode->FSPRIVATE && | |
6205 | + ((inode->i_size != info->size) || | |
6206 | + (inode->i_mtime.tv_sec != | |
6207 | + info->mtime.tv_sec) | |
6208 | + || (inode->i_mtime.tv_nsec != | |
6209 | + info->mtime.tv_nsec))) { | |
6210 | + /* | |
6211 | + * Values don't match so update. | |
6212 | + */ | |
6213 | + ((struct inode_data *) inode->FSPRIVATE)->Flags |= UPDATE_INODE; | |
6214 | + } | |
6215 | + | |
6216 | + ctime = get_jiffies_64() - ctime; | |
6217 | + if (Flags || ctime < (u64) (File_update_timeout * HZ)) { | |
6218 | + retVal = 0; | |
6219 | + Novfs_unlock_inode_cache(dir); | |
6220 | + dput(parent); | |
6221 | + kfree(info); | |
6222 | + return (0); | |
6223 | + } | |
6224 | + } | |
6225 | + Novfs_unlock_inode_cache(dir); | |
6226 | + } | |
6227 | + | |
6228 | + if (IS_ROOT(dentry->d_parent)) { | |
6229 | + session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name)); | |
6230 | + } else { | |
6231 | + session = Scope_Get_SessionId(id->Scope); | |
6232 | + } | |
6233 | + | |
6234 | + if (!SC_PRESENT(session)) { | |
6235 | + id->Scope = Scope_Get_ScopefromPath(dentry); | |
6236 | + session = Scope_Get_SessionId(id->Scope); | |
6237 | + } | |
6238 | + | |
6239 | + ino = 0; | |
6240 | + retVal = 0; | |
6241 | + | |
6242 | + if (IS_ROOT(dentry->d_parent)) { | |
6243 | + DbgPrint("verify_dentry: parent is Root directory\n"); | |
6244 | + list = Scope_Get_ScopeUsers(); | |
6245 | + | |
6246 | + iLock = Novfs_lock_inode_cache(dir); | |
6247 | + Novfs_invalidate_inode_cache(dir); | |
6248 | + | |
6249 | + if (list) { | |
6250 | + cp = list; | |
6251 | + while (*cp) { | |
6252 | + name.name = cp; | |
6253 | + name.len = strlen(cp); | |
6254 | + name.hash = Novfs_internal_hash(&name); | |
6255 | + cp += (name.len + 1); | |
6256 | + ino = 0; | |
6257 | + if (Novfs_get_entry(dir, &name, &ino, info)) { | |
6258 | + info->mode = S_IFDIR | 0700; | |
6259 | + info->size = 0; | |
6260 | + info->atime = info->ctime = info->mtime = CURRENT_TIME; | |
6261 | + ino = (ino_t)atomic_inc_return(&Novfs_Inode_Number); | |
6262 | + Novfs_add_inode_entry(dir, &name, ino, info); | |
6263 | + } | |
6264 | + } | |
6265 | + } | |
6266 | + Novfs_free_invalid_entries(dir); | |
6267 | + } else { | |
6268 | + | |
6269 | + path = | |
6270 | + Novfs_dget_path(dentry, info->name, | |
6271 | + PATH_LENGTH_BUFFER); | |
6272 | + if (path) { | |
6273 | + if (dentry->d_name.len <= | |
6274 | + NW_MAX_PATH_LENGTH) { | |
6275 | + name.hash = | |
6276 | + Novfs_internal_hash | |
6277 | + (&dentry->d_name); | |
6278 | + name.len = dentry->d_name.len; | |
6279 | + name.name = dentry->d_name.name; | |
6280 | + | |
6281 | + retVal = Novfs_Get_File_Info(path, info, &session); | |
6282 | + if (0 == retVal) { | |
6283 | + dentry->d_time = | |
6284 | + jiffies + | |
6285 | + (File_update_timeout | |
6286 | + * HZ); | |
6287 | + iLock = | |
6288 | + Novfs_lock_inode_cache | |
6289 | + (dir); | |
6290 | + if (Novfs_update_entry | |
6291 | + (dir, &name, 0, | |
6292 | + info)) { | |
6293 | + if (dentry-> | |
6294 | + d_inode) { | |
6295 | + ino = dentry->d_inode->i_ino; | |
6296 | + } else { | |
6297 | + ino = (ino_t)atomic_inc_return(&Novfs_Inode_Number); | |
6298 | + } | |
6299 | + Novfs_add_inode_entry | |
6300 | + (dir, &name, | |
6301 | + ino, info); | |
6302 | + } | |
6303 | + if (dentry->d_inode) { | |
6304 | + update_inode | |
6305 | + (dentry-> | |
6306 | + d_inode, | |
6307 | + info); | |
6308 | + id->Flags &= | |
6309 | + ~UPDATE_INODE; | |
6310 | + | |
6311 | + dentry-> | |
6312 | + d_inode-> | |
6313 | + i_flags &= | |
6314 | + ~S_DEAD; | |
6315 | + if (dentry-> | |
6316 | + d_inode-> | |
6317 | + FSPRIVATE) { | |
6318 | + ((struct inode_data *) dentry->d_inode->FSPRIVATE)->Scope = id->Scope; | |
6319 | + } | |
6320 | + } | |
6321 | + } else if (-EINTR != retVal) { | |
6322 | + retVal = 0; | |
6323 | + iLock = Novfs_lock_inode_cache(dir); | |
6324 | + Novfs_remove_inode_entry(dir, &name, 0); | |
6325 | + if (dentry->d_inode | |
6326 | + && !(dentry->d_inode->i_flags & S_DEAD)) { | |
6327 | + dentry->d_inode->i_flags |= S_DEAD; | |
6328 | + dentry->d_inode-> i_size = 0; | |
6329 | + dentry->d_inode->i_atime.tv_sec = | |
6330 | + dentry->d_inode->i_atime.tv_nsec = | |
6331 | + dentry->d_inode->i_ctime.tv_sec = | |
6332 | + dentry->d_inode->i_ctime.tv_nsec = | |
6333 | + dentry->d_inode->i_mtime.tv_sec = | |
6334 | + dentry->d_inode->i_mtime.tv_nsec = 0; | |
6335 | + dentry->d_inode->i_blocks = 0; | |
6336 | + d_delete(dentry); /* Remove from cache */ | |
6337 | + } | |
6338 | + } | |
6339 | + } else { | |
6340 | + retVal = -ENAMETOOLONG; | |
6341 | + } | |
6342 | + } | |
6343 | + } | |
6344 | + } else { | |
6345 | + retVal = -ENOMEM; | |
6346 | + } | |
6347 | + if (iLock) { | |
6348 | + Novfs_unlock_inode_cache(dir); | |
6349 | + } | |
6350 | + dput(parent); | |
6351 | + } | |
6352 | + | |
6353 | + if (list) | |
6354 | + kfree(list); | |
6355 | + if (info) | |
6356 | + kfree(info); | |
6357 | + | |
6358 | + DbgPrint("verify_dentry: return=0x%x\n", retVal); | |
6359 | + | |
6360 | + return (retVal); | |
6361 | +} | |
6362 | + | |
6363 | +/*++======================================================================*/ | |
6364 | +struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name) | |
6365 | +/* | |
6366 | + * Arguments: | |
6367 | + * | |
6368 | + * Returns: | |
6369 | + * | |
6370 | + * Abstract: | |
6371 | + * | |
6372 | + * Notes: | |
6373 | + * | |
6374 | + * Environment: | |
6375 | + * | |
6376 | + *========================================================================*/ | |
6377 | +{ | |
6378 | + return (d_lookup(Parent, Name)); | |
6379 | +} | |
6380 | + | |
6381 | +/*++======================================================================*/ | |
6382 | +int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a) | |
6383 | +/* | |
6384 | + * Arguments: | |
6385 | + * | |
6386 | + * Returns: | |
6387 | + * | |
6388 | + * Abstract: | |
6389 | + * | |
6390 | + * Notes: | |
6391 | + * | |
6392 | + * Environment: | |
6393 | + * | |
6394 | + *========================================================================*/ | |
6395 | +{ | |
6396 | + void *scope; | |
6397 | + struct inode_data *id = NULL; | |
6398 | + | |
6399 | + char *path, *buf; | |
6400 | + | |
6401 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
6402 | + if (buf) { | |
6403 | + path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER); | |
6404 | + if (path) { | |
6405 | + DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, | |
6406 | + i->i_ino, path); | |
6407 | + } | |
6408 | + kfree(buf); | |
6409 | + } | |
6410 | + | |
6411 | + if (Parent && Parent->d_inode && Parent->d_inode->FSPRIVATE) { | |
6412 | + id = (struct inode_data *) Parent->d_inode->FSPRIVATE; | |
6413 | + } | |
6414 | + | |
6415 | + if (id && id->Scope) { | |
6416 | + scope = id->Scope; | |
6417 | + } else { | |
6418 | + scope = Scope_Get_ScopefromPath(d); | |
6419 | + } | |
6420 | + | |
6421 | + ((struct inode_data *) i->FSPRIVATE)->Scope = scope; | |
6422 | + | |
6423 | + d->d_time = jiffies + (File_update_timeout * HZ); | |
6424 | + if (a) { | |
6425 | + d_add(d, i); | |
6426 | + } else { | |
6427 | + d_instantiate(d, i); | |
6428 | + } | |
6429 | + | |
6430 | + return (0); | |
6431 | +} | |
6432 | + | |
6433 | +/*++======================================================================*/ | |
6434 | +int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |
6435 | +/* | |
6436 | + * Arguments: struct dentry *dentry - pointer to dentry to revalidate. | |
6437 | + * struct nameidata *nd - pointer to nameidata. | |
6438 | + * | |
6439 | + * Returns: zero - dentry is not valid. | |
6440 | + * !zero - valid entry | |
6441 | + * | |
6442 | + * Abstract: | |
6443 | + * | |
6444 | + * Notes: | |
6445 | + * | |
6446 | + * Environment: | |
6447 | + * | |
6448 | + *========================================================================*/ | |
6449 | +{ | |
6450 | + int retCode = 0; | |
6451 | + struct inode *dir; | |
6452 | + struct inode_data *id; | |
6453 | + struct qstr name; | |
6454 | + | |
6455 | + DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" | |
6456 | + " d_count: %d\n" | |
6457 | + " d_inode: 0x%p\n", | |
6458 | + dentry, dentry->d_name.len, dentry->d_name.name, | |
6459 | + dentry->d_count, dentry->d_inode); | |
6460 | + | |
6461 | + if (IS_ROOT(dentry)) { | |
6462 | + retCode = 1; | |
6463 | + } else { | |
6464 | + if (dentry->d_inode && | |
6465 | + dentry->d_parent && | |
6466 | + (dir = dentry->d_parent->d_inode) && | |
6467 | + (id = dir->FSPRIVATE)) { | |
6468 | + /* | |
6469 | + * Check timer to see if in valid time limit | |
6470 | + */ | |
6471 | + if (jiffies > dentry->d_time) { | |
6472 | + /* | |
6473 | + * Revalidate entry | |
6474 | + */ | |
6475 | + name.len = dentry->d_name.len; | |
6476 | + name.name = dentry->d_name.name; | |
6477 | + name.hash = | |
6478 | + Novfs_internal_hash(&dentry->d_name); | |
6479 | + dentry->d_time = 0; | |
6480 | + | |
6481 | + if (0 == verify_dentry(dentry, 0)) { | |
6482 | + if (Novfs_lock_inode_cache(dir)) { | |
6483 | + if (Novfs_lookup_inode_cache | |
6484 | + (dir, &name, 0)) { | |
6485 | + dentry->d_time = | |
6486 | + jiffies + | |
6487 | + (File_update_timeout | |
6488 | + * HZ); | |
6489 | + retCode = 1; | |
6490 | + } | |
6491 | + Novfs_unlock_inode_cache(dir); | |
6492 | + } | |
6493 | + } | |
6494 | + } else { | |
6495 | + retCode = 1; | |
6496 | + } | |
6497 | + } | |
6498 | + } | |
6499 | + | |
6500 | + if ((0 == retCode) && dentry->d_inode) { | |
6501 | + /* | |
6502 | + * Entry has become invalid | |
6503 | + */ | |
6504 | +/* dput(dentry); | |
6505 | +*/ | |
6506 | + } | |
6507 | + | |
6508 | + DbgPrint("Novfs_d_revalidate: return 0x%x %.*s\n", retCode, | |
6509 | + dentry->d_name.len, dentry->d_name.name); | |
6510 | + | |
6511 | + return (retCode); | |
6512 | +} | |
6513 | + | |
6514 | +/*++======================================================================*/ | |
6515 | +unsigned long Novfs_internal_hash(struct qstr *name) | |
6516 | +/* | |
6517 | + * Arguments: | |
6518 | + * | |
6519 | + * Returns: | |
6520 | + * | |
6521 | + * Abstract: | |
6522 | + * | |
6523 | + * Notes: | |
6524 | + * | |
6525 | + * Environment: | |
6526 | + * | |
6527 | + *========================================================================*/ | |
6528 | +{ | |
6529 | + unsigned long hash = 0; | |
6530 | + unsigned int len = name->len; | |
6531 | + unsigned char *c = (unsigned char *)name->name; | |
6532 | + | |
6533 | + while (len--) { | |
6534 | + /* | |
6535 | + * Lower case values for the hash. | |
6536 | + */ | |
6537 | + hash = partial_name_hash(tolower(*c++), hash); | |
6538 | + } | |
6539 | + | |
6540 | + return (hash); | |
6541 | +} | |
6542 | + | |
6543 | +/*++======================================================================*/ | |
6544 | +int Novfs_d_hash(struct dentry *dentry, struct qstr *name) | |
6545 | +/* | |
6546 | + * Arguments: | |
6547 | + * | |
6548 | + * Returns: | |
6549 | + * | |
6550 | + * Abstract: | |
6551 | + * | |
6552 | + * Notes: | |
6553 | + * | |
6554 | + * Environment: | |
6555 | + * | |
6556 | + *========================================================================*/ | |
6557 | +{ | |
6558 | + DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name); | |
6559 | + | |
6560 | + name->hash = Novfs_internal_hash(name); | |
6561 | + | |
6562 | + return (0); | |
6563 | +} | |
6564 | + | |
6565 | +/*++======================================================================*/ | |
6566 | +int Novfs_d_strcmp(struct qstr *s1, struct qstr *s2) | |
6567 | +/* | |
6568 | + * Arguments: | |
6569 | + * | |
6570 | + * Returns: | |
6571 | + * | |
6572 | + * Abstract: | |
6573 | + * | |
6574 | + * Notes: | |
6575 | + * | |
6576 | + * Environment: | |
6577 | + * | |
6578 | + *========================================================================*/ | |
6579 | +{ | |
6580 | + int retCode = 1; | |
6581 | + unsigned char *str1, *str2; | |
6582 | + unsigned int len; | |
6583 | + | |
6584 | + DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, | |
6585 | + s2->len, s2->name); | |
6586 | + | |
6587 | + if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash)) { | |
6588 | + len = s1->len; | |
6589 | + str1 = (unsigned char *)s1->name; | |
6590 | + str2 = (unsigned char *)s2->name; | |
6591 | + for (retCode = 0; len--; str1++, str2++) { | |
6592 | + if (*str1 != *str2) { | |
6593 | + if (tolower(*str1) != tolower(*str2)) { | |
6594 | + retCode = 1; | |
6595 | + break; | |
6596 | + } | |
6597 | + } | |
6598 | + } | |
6599 | + } | |
6600 | + | |
6601 | + DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode); | |
6602 | + return (retCode); | |
6603 | +} | |
6604 | + | |
6605 | +/*++======================================================================*/ | |
6606 | +int Novfs_d_compare(struct dentry *parent, struct qstr *s1, struct qstr *s2) | |
6607 | +/* | |
6608 | + * Arguments: | |
6609 | + * | |
6610 | + * Returns: | |
6611 | + * | |
6612 | + * Abstract: | |
6613 | + * | |
6614 | + * Notes: | |
6615 | + * | |
6616 | + * Environment: | |
6617 | + * | |
6618 | + *========================================================================*/ | |
6619 | +{ | |
6620 | + int retCode; | |
6621 | + | |
6622 | + retCode = Novfs_d_strcmp(s1, s2); | |
6623 | + | |
6624 | + DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode); | |
6625 | + return (retCode); | |
6626 | +} | |
6627 | + | |
6628 | +/*++======================================================================*/ | |
6629 | +int Novfs_d_delete(struct dentry *dentry) | |
6630 | +/* | |
6631 | + * Arguments: | |
6632 | + * | |
6633 | + * Returns: | |
6634 | + * | |
6635 | + * Abstract: | |
6636 | + * | |
6637 | + * Notes: | |
6638 | + * | |
6639 | + * Environment: | |
6640 | + * | |
6641 | + *========================================================================*/ | |
6642 | +{ | |
6643 | + int retVal = 0; | |
6644 | + | |
6645 | + DbgPrint("Novfs_d_delete: 0x%p %.*s\n" | |
6646 | + " d_count: %d\n" | |
6647 | + " d_inode: 0x%p\n", | |
6648 | + dentry, dentry->d_name.len, dentry->d_name.name, | |
6649 | + dentry->d_count, dentry->d_inode); | |
6650 | + | |
6651 | + if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD)) { | |
6652 | + retVal = 1; | |
6653 | + } | |
6654 | + | |
6655 | + dentry->d_time = 0; | |
6656 | + | |
6657 | + return (retVal); | |
6658 | +} | |
6659 | + | |
6660 | +/*++======================================================================*/ | |
6661 | +void Novfs_d_release(struct dentry *dentry) | |
6662 | +/* | |
6663 | + * Arguments: | |
6664 | + * | |
6665 | + * Returns: | |
6666 | + * | |
6667 | + * Abstract: | |
6668 | + * | |
6669 | + * Notes: | |
6670 | + * | |
6671 | + * Environment: | |
6672 | + * | |
6673 | + *========================================================================*/ | |
6674 | +{ | |
6675 | + DbgPrint("Novfs_d_release: 0x%p %.*s\n", dentry, dentry->d_name.len, | |
6676 | + dentry->d_name.name); | |
6677 | +} | |
6678 | + | |
6679 | +/*++======================================================================*/ | |
6680 | +void Novfs_d_iput(struct dentry *dentry, struct inode *inode) | |
6681 | +/* | |
6682 | + * Arguments: | |
6683 | + * | |
6684 | + * Returns: | |
6685 | + * | |
6686 | + * Abstract: | |
6687 | + * | |
6688 | + * Notes: | |
6689 | + * | |
6690 | + * Environment: | |
6691 | + * | |
6692 | + *========================================================================*/ | |
6693 | +{ | |
6694 | + DbgPrint | |
6695 | + ("Novfs_d_iput: Inode=0x%p Ino=%d Dentry=0x%p i_state=%d Name=%.*s\n", | |
6696 | + inode, inode->i_ino, dentry, inode->i_state, dentry->d_name.len, | |
6697 | + dentry->d_name.name); | |
6698 | + | |
6699 | + iput(inode); | |
6700 | + | |
6701 | +} | |
6702 | + | |
6703 | +/*++======================================================================*/ | |
6704 | +int Novfs_dir_open(struct inode *dir, struct file *file) | |
6705 | +/* | |
6706 | + * Arguments: | |
6707 | + * | |
6708 | + * Returns: | |
6709 | + * | |
6710 | + * Abstract: | |
6711 | + * | |
6712 | + * Notes: | |
6713 | + * | |
6714 | + * Environment: | |
6715 | + * | |
6716 | + *========================================================================*/ | |
6717 | +{ | |
6718 | + char *path, *buf; | |
6719 | + FilePrivate2 *file_private = NULL; | |
6720 | + | |
6721 | + DbgPrint("Novfs_dir_open: Inode 0x%p %d Name %.*s\n", dir, dir->i_ino, | |
6722 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name); | |
6723 | + | |
6724 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
6725 | + if (buf) { | |
6726 | + path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); | |
6727 | + if (path) { | |
6728 | + DbgPrint("Novfs_dir_open: path %s\n", path); | |
6729 | + } | |
6730 | + kfree(buf); | |
6731 | + } | |
6732 | + | |
6733 | + file_private = Novfs_Malloc(sizeof(FilePrivate2), GFP_KERNEL); | |
6734 | + file_private->listedall = 0; | |
6735 | + file_private->enumHandle = NULL; | |
6736 | + | |
6737 | + file->private_data = file_private; | |
6738 | + | |
6739 | + return (0); | |
6740 | +} | |
6741 | + | |
6742 | +/*++======================================================================*/ | |
6743 | +int Novfs_dir_release(struct inode *dir, struct file *file) | |
6744 | +/* | |
6745 | + * Arguments: | |
6746 | + * | |
6747 | + * Returns: | |
6748 | + * | |
6749 | + * Abstract: | |
6750 | + * | |
6751 | + * Notes: | |
6752 | + * | |
6753 | + * Environment: | |
6754 | + * | |
6755 | + *========================================================================*/ | |
6756 | +{ | |
6757 | + FilePrivate2 *file_private; | |
6758 | + file_private = (FilePrivate2 *) file->private_data; | |
6759 | + | |
6760 | + DbgPrint("Novfs_dir_release: Inode 0x%p %d Name %.*s\n", dir, | |
6761 | + dir->i_ino, file->f_dentry->d_name.len, | |
6762 | + file->f_dentry->d_name.name); | |
6763 | + | |
6764 | + if (file_private) { | |
6765 | + kfree(file_private); | |
6766 | + file->private_data = NULL; | |
6767 | + } | |
6768 | + | |
6769 | + return (0); | |
6770 | +} | |
6771 | + | |
6772 | +/*++======================================================================*/ | |
6773 | +loff_t Novfs_dir_lseek(struct file * file, loff_t offset, int origin) | |
6774 | +/* | |
6775 | + * Arguments: | |
6776 | + * | |
6777 | + * Returns: | |
6778 | + * | |
6779 | + * Abstract: | |
6780 | + * | |
6781 | + * Notes: | |
6782 | + * | |
6783 | + * Environment: | |
6784 | + * | |
6785 | + *========================================================================*/ | |
6786 | +{ | |
6787 | + FilePrivate2 *file_private = NULL; | |
6788 | + | |
6789 | + DbgPrint("Novfs_dir_lseek: offset %lld %d Name %.*s\n", offset, origin, | |
6790 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name); | |
6791 | + //printk("<1> seekdir file = %.*s offset = %i\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, (int)offset); | |
6792 | + | |
6793 | + if (0 != offset) { | |
6794 | + return -ESPIPE; | |
6795 | + } | |
6796 | + | |
6797 | + file->f_pos = 0; | |
6798 | + | |
6799 | + file_private = (FilePrivate2 *) file->private_data; | |
6800 | + file_private->listedall = 0; | |
6801 | + file_private->enumHandle = NULL; | |
6802 | + | |
6803 | + return 0; | |
6804 | + //return(default_llseek(file, offset, origin)); | |
6805 | +} | |
6806 | + | |
6807 | +/*++======================================================================*/ | |
6808 | +ssize_t Novfs_dir_read(struct file * file, char *buf, size_t len, loff_t * off) | |
6809 | +/* | |
6810 | + * Arguments: | |
6811 | + * | |
6812 | + * Returns: | |
6813 | + * | |
6814 | + * Abstract: | |
6815 | + * | |
6816 | + * Notes: | |
6817 | + * | |
6818 | + * Environment: | |
6819 | + * | |
6820 | + *========================================================================*/ | |
6821 | +{ | |
6822 | +/* | |
6823 | + int rlen = 0; | |
6824 | + | |
6825 | + DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off); | |
6826 | + | |
6827 | + if (0 == *off) | |
6828 | + { | |
6829 | + rlen = 8; | |
6830 | + rlen -= copy_to_user(buf, "Testing\n", 8); | |
6831 | + *off += rlen; | |
6832 | + } | |
6833 | + return(rlen); | |
6834 | +*/ | |
6835 | + DbgPrint("Novfs_dir_read: %lld %d Name %.*s\n", *off, len, | |
6836 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name); | |
6837 | + return (generic_read_dir(file, buf, len, off)); | |
6838 | +} | |
6839 | + | |
6840 | +static void Novfs_Dump_Info(struct entry_info *info) | |
6841 | +{ | |
6842 | + char atime_buf[32], mtime_buf[32], ctime_buf[32]; | |
6843 | + char namebuf[512]; | |
6844 | + int len = 0; | |
6845 | + | |
6846 | + if (info == NULL) { | |
6847 | + DbgPrint("Novfs_dir_readdir : Dump_Info info == NULL\n"); | |
6848 | + return; | |
6849 | + } | |
6850 | + | |
6851 | + if (info->namelength >= 512) { | |
6852 | + len = 511; | |
6853 | + } else { | |
6854 | + len = info->namelength; | |
6855 | + } | |
6856 | + | |
6857 | + memcpy(namebuf, info->name, len); | |
6858 | + namebuf[len] = '\0'; | |
6859 | + | |
6860 | + ctime_r(&info->atime.tv_sec, atime_buf); | |
6861 | + ctime_r(&info->mtime.tv_sec, mtime_buf); | |
6862 | + ctime_r(&info->ctime.tv_sec, ctime_buf); | |
6863 | + DbgPrint("Novfs_dir_readdir : type = %i\n", info->type); | |
6864 | + DbgPrint("Novfs_dir_readdir : mode = %x\n", info->mode); | |
6865 | + DbgPrint("Novfs_dir_readdir : uid = %d\n", info->uid); | |
6866 | + DbgPrint("Novfs_dir_readdir : gid = %d\n", info->gid); | |
6867 | + DbgPrint("Novfs_dir_readdir : size = %i\n", info->size); | |
6868 | + DbgPrint("Novfs_dir_readdir : atime = %s\n", atime_buf); | |
6869 | + DbgPrint("Novfs_dir_readdir : mtime = %s\n", mtime_buf); | |
6870 | + DbgPrint("Novfs_dir_readdir : ctime = %s\n", ctime_buf); | |
6871 | + DbgPrint("Novfs_dir_readdir : namelength = %i\n", info->namelength); | |
6872 | + DbgPrint("Novfs_dir_readdir : name = %s\n", namebuf); | |
6873 | +} | |
6874 | + | |
6875 | +/*++======================================================================*/ | |
6876 | +void processList(struct file *file, void *dirent, filldir_t filldir, char *list, | |
6877 | + int type, session_t SessionId) | |
6878 | +/* | |
6879 | + * Arguments: | |
6880 | + * | |
6881 | + * Returns: | |
6882 | + * | |
6883 | + * Abstract: | |
6884 | + * | |
6885 | + * Notes: | |
6886 | + * | |
6887 | + * Environment: | |
6888 | + * | |
6889 | + *========================================================================*/ | |
6890 | +{ | |
6891 | + unsigned char *path, *buf = NULL, *cp; | |
6892 | + struct qstr name; | |
6893 | + struct entry_info *pinfo = NULL; | |
6894 | + | |
6895 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
6896 | + path = buf; | |
6897 | + if (buf) { | |
6898 | + path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); | |
6899 | + if (path) { | |
6900 | + strcpy(buf, path); | |
6901 | + } | |
6902 | + path = buf + strlen(buf); | |
6903 | + *path++ = '\\'; | |
6904 | + } | |
6905 | + | |
6906 | + if (list) { | |
6907 | + cp = list; | |
6908 | + while (*cp) { | |
6909 | + name.name = cp; | |
6910 | + DbgPrint("Novfs_dir_readdir : name.name = %s\n", | |
6911 | + name.name); | |
6912 | + name.len = strlen(cp); | |
6913 | + name.hash = Novfs_internal_hash(&name); | |
6914 | + cp += (name.len + 1); | |
6915 | + | |
6916 | + pinfo = | |
6917 | + Novfs_Malloc(sizeof(struct entry_info) + | |
6918 | + PATH_LENGTH_BUFFER, GFP_KERNEL); | |
6919 | + pinfo->mode = S_IFDIR | 0700; | |
6920 | + pinfo->size = 0; | |
6921 | + pinfo->atime = pinfo->ctime = pinfo->mtime = | |
6922 | + CURRENT_TIME; | |
6923 | + strcpy(pinfo->name, name.name); | |
6924 | + pinfo->namelength = name.len; | |
6925 | + | |
6926 | + Novfs_Dump_Info(pinfo); | |
6927 | + | |
6928 | + filldir(dirent, pinfo->name, pinfo->namelength, | |
6929 | + file->f_pos, file->f_pos, pinfo->mode >> 12); | |
6930 | + file->f_pos += 1; | |
6931 | + | |
6932 | + kfree(pinfo); | |
6933 | + } | |
6934 | + } | |
6935 | + | |
6936 | + if (buf) { | |
6937 | + kfree(buf); | |
6938 | + } | |
6939 | +} | |
6940 | + | |
6941 | +int processEntries(struct file *file, void *dirent, filldir_t filldir, | |
6942 | + HANDLE * enumHandle, session_t sessionId) | |
6943 | +{ | |
6944 | + unsigned char *path = NULL, *buf = NULL; | |
6945 | + int count = 0, status = 0; | |
6946 | + struct entry_info *pinfo = NULL; | |
6947 | + struct entry_info *pInfoMem = NULL; | |
6948 | + | |
6949 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
6950 | + if (!buf) { | |
6951 | + return -ENOMEM; | |
6952 | + } | |
6953 | + | |
6954 | + path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); | |
6955 | + if (!path) { | |
6956 | + kfree(buf); | |
6957 | + return -ENOMEM; | |
6958 | + } | |
6959 | + //NWSearchfiles | |
6960 | + count = 0; | |
6961 | + status = Novfs_Get_Directory_ListEx(path, enumHandle, &count, &pinfo, &sessionId); | |
6962 | + pInfoMem = pinfo; | |
6963 | + | |
6964 | + if ((count == -1) || (count == 0) || (status != 0)) { | |
6965 | + kfree(pInfoMem); | |
6966 | + kfree(buf); | |
6967 | + return -1; | |
6968 | + } | |
6969 | + // parse resultset | |
6970 | + while (pinfo && count--) { | |
6971 | + filldir(dirent, pinfo->name, pinfo->namelength, file->f_pos, | |
6972 | + file->f_pos, pinfo->mode >> 12); | |
6973 | + file->f_pos += 1; | |
6974 | + | |
6975 | + pinfo = (struct entry_info *)(pinfo->name + pinfo->namelength); | |
6976 | + } | |
6977 | + | |
6978 | + kfree(pInfoMem); | |
6979 | + kfree(buf); | |
6980 | + return 0; | |
6981 | +} | |
6982 | + | |
6983 | +/*++======================================================================*/ | |
6984 | +int Novfs_dir_readdir(struct file *file, void *dirent, filldir_t filldir) | |
6985 | +/* | |
6986 | + * Arguments: | |
6987 | + * | |
6988 | + * Returns: | |
6989 | + * | |
6990 | + * Abstract: | |
6991 | + * | |
6992 | + * Notes: | |
6993 | + * | |
6994 | + * Environment: | |
6995 | + * | |
6996 | + *========================================================================*/ | |
6997 | +{ | |
6998 | + unsigned char *list = NULL; | |
6999 | + int status = 0; //-ENOMEM; | |
7000 | + struct inode *inode = file->f_dentry->d_inode; | |
7001 | + session_t sessionId; | |
7002 | + uid_t uid; | |
7003 | + int type = 0; | |
7004 | + FilePrivate2 *file_private = NULL; | |
7005 | + int lComm; | |
7006 | + | |
7007 | + file_private = (FilePrivate2 *) file->private_data; | |
7008 | + DbgPrint("Novfs_dir_readdir: Name %.*s\n", file->f_dentry->d_name.len, | |
7009 | + file->f_dentry->d_name.name); | |
7010 | + | |
7011 | + //printk("<1> file = %.*s\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name); | |
7012 | + | |
7013 | +// Use this hack by default | |
7014 | +#ifndef SKIP_CROSSOVER_HACK | |
7015 | + // Hack for crossover - begin | |
7016 | + down(&TimeDir_Lock); | |
7017 | + if ((file->f_dentry->d_name.len == 7) && | |
7018 | + ((0 == strncmp(file->f_dentry->d_name.name, " !xover", 7)) || | |
7019 | + (0 == strncmp(file->f_dentry->d_name.name, "z!xover", 7)))) { | |
7020 | + //printk("<1> xoverhack: we are in xoverHack\n"); | |
7021 | + | |
7022 | + inHAX = 1; | |
7023 | + inHAXTime = get_nanosecond_time(); | |
7024 | + //up( &TimeDir_Lock ); | |
7025 | + //return 0; | |
7026 | + file_private->listedall = 1; | |
7027 | + } else { | |
7028 | + if (inHAX) { | |
7029 | + if (get_nanosecond_time() - inHAXTime > | |
7030 | + 100 * 1000 * 1000) { | |
7031 | + //printk("<1> xoverhack: it was long, long, long ago...\n"); | |
7032 | + inHAX = 0; | |
7033 | + } else { | |
7034 | + //printk("<1> xoverhack: word gotcha in xoverHack...\n"); | |
7035 | + inHAXTime = get_nanosecond_time(); | |
7036 | + //up( &TimeDir_Lock ); | |
7037 | + //return 0; | |
7038 | + file_private->listedall = 1; | |
7039 | + } | |
7040 | + } | |
7041 | + } | |
7042 | + | |
7043 | + up(&TimeDir_Lock); | |
7044 | + // Hack for crossover - end | |
7045 | +#endif | |
7046 | + | |
7047 | + if (file->f_pos == 0) { | |
7048 | + if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < | |
7049 | + 0) | |
7050 | + return 1; | |
7051 | + file->f_pos++; | |
7052 | + return 1; | |
7053 | + } | |
7054 | + | |
7055 | + if (file->f_pos == 1) { | |
7056 | + if (filldir | |
7057 | + (dirent, "..", 2, file->f_pos, | |
7058 | + file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) | |
7059 | + return 1; | |
7060 | + file->f_pos++; | |
7061 | + return 1; | |
7062 | + } | |
7063 | + | |
7064 | + if (file_private->listedall != 0) { | |
7065 | + return 0; | |
7066 | + } | |
7067 | + | |
7068 | + inode = file->f_dentry->d_inode; | |
7069 | + if (inode && inode->FSPRIVATE) { | |
7070 | + sessionId = | |
7071 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)-> Scope); | |
7072 | + if (0 == SC_PRESENT(sessionId)) { | |
7073 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = | |
7074 | + Scope_Get_ScopefromPath(file->f_dentry); | |
7075 | + sessionId = | |
7076 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
7077 | + } | |
7078 | + uid = Scope_Get_Uid(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
7079 | + } else { | |
7080 | + SC_INITIALIZE(sessionId); | |
7081 | + uid = current->euid; | |
7082 | + } | |
7083 | + | |
7084 | + if (IS_ROOT(file->f_dentry) || // Root | |
7085 | + IS_ROOT(file->f_dentry->d_parent) || // User | |
7086 | + IS_ROOT(file->f_dentry->d_parent->d_parent)) // Server | |
7087 | + { | |
7088 | + if (IS_ROOT(file->f_dentry)) { | |
7089 | + DbgPrint("Novfs_dir_readdir: Root directory\n"); | |
7090 | + list = Scope_Get_ScopeUsers(); | |
7091 | + type = USER_LIST; | |
7092 | + } else if (IS_ROOT(file->f_dentry->d_parent)) { | |
7093 | + DbgPrint | |
7094 | + ("Novfs_dir_readdir: Parent is Root directory\n"); | |
7095 | + Novfs_Get_Connected_Server_List(&list, &sessionId); | |
7096 | + type = SERVER_LIST; | |
7097 | + } else { | |
7098 | + DbgPrint | |
7099 | + ("Novfs_dir_readdir: Parent-Parent is Root directory\n"); | |
7100 | + Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, | |
7101 | + &list, &sessionId); | |
7102 | + type = VOLUME_LIST; | |
7103 | + } | |
7104 | + | |
7105 | + processList(file, dirent, filldir, list, type, sessionId); | |
7106 | + file_private->listedall = 1; | |
7107 | + } else { | |
7108 | + status = | |
7109 | + processEntries(file, dirent, filldir, | |
7110 | + &file_private->enumHandle, sessionId); | |
7111 | + | |
7112 | + if (status != 0) { | |
7113 | + file_private->listedall = 1; | |
7114 | +#ifndef SKIP_CROSSOVER_HACK | |
7115 | + // Hack for crossover part 2 - begin | |
7116 | + lComm = strlen(current->comm); | |
7117 | + if ((lComm > 4) | |
7118 | + && (0 == | |
7119 | + strcmp(current->comm + lComm - 4, ".EXE"))) { | |
7120 | + if (filldir | |
7121 | + (dirent, " !xover", 7, file->f_pos, | |
7122 | + inode->i_ino, DT_DIR) < 0) | |
7123 | + return 1; | |
7124 | + if (filldir | |
7125 | + (dirent, "z!xover", 7, file->f_pos, | |
7126 | + inode->i_ino, DT_DIR) < 0) | |
7127 | + return 1; | |
7128 | + file->f_pos += 2; | |
7129 | + } | |
7130 | + // Hack for crossover part2 - end | |
7131 | +#endif | |
7132 | + } | |
7133 | + } | |
7134 | + | |
7135 | + file->private_data = file_private; | |
7136 | + return 1; | |
7137 | +} | |
7138 | + | |
7139 | +/*++======================================================================*/ | |
7140 | +int Novfs_dir_fsync(struct file *file, struct dentry *dentry, int datasync) | |
7141 | +/* | |
7142 | + * Arguments: | |
7143 | + * | |
7144 | + * Returns: | |
7145 | + * | |
7146 | + * Abstract: | |
7147 | + * | |
7148 | + * Notes: | |
7149 | + * | |
7150 | + * Environment: | |
7151 | + * | |
7152 | + *========================================================================*/ | |
7153 | +{ | |
7154 | + DbgPrint("Novfs_dir_fsync: Name %.*s\n", file->f_dentry->d_name.len, | |
7155 | + file->f_dentry->d_name.name); | |
7156 | + return (simple_sync_file(file, dentry, datasync)); | |
7157 | +} | |
7158 | + | |
7159 | +/*++======================================================================*/ | |
7160 | +ssize_t Novfs_f_read(struct file * file, char *buf, size_t len, loff_t * off) | |
7161 | +/* | |
7162 | + * Arguments: | |
7163 | + * | |
7164 | + * Returns: | |
7165 | + * | |
7166 | + * Abstract: | |
7167 | + * | |
7168 | + * Notes: | |
7169 | + * | |
7170 | + * Environment: | |
7171 | + * | |
7172 | + *========================================================================*/ | |
7173 | +{ | |
7174 | + size_t thisread, totalread = 0; | |
7175 | + loff_t offset = *off; | |
7176 | + struct inode *inode; | |
7177 | + session_t session; | |
7178 | + struct inode_data *id; | |
7179 | + | |
7180 | + if (file->f_dentry && | |
7181 | + (inode = file->f_dentry->d_inode) && | |
7182 | + (id = (struct inode_data *)inode->FSPRIVATE)) { | |
7183 | + | |
7184 | + DbgPrint("Novfs_f_read(0x%p 0x%p %d %lld %.*s)\n", | |
7185 | + file->private_data, | |
7186 | + buf, len, offset, | |
7187 | + file->f_dentry->d_name.len, | |
7188 | + file->f_dentry->d_name.name); | |
7189 | + | |
7190 | + if (PageCache && !(file->f_flags & O_DIRECT) && id->CacheFlag) { | |
7191 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | |
7192 | + totalread = generic_file_read(file, buf, len, off); | |
7193 | +#else | |
7194 | + totalread = do_sync_read(file, buf, len, off); | |
7195 | +#endif | |
7196 | + } else { | |
7197 | + session = Scope_Get_SessionId(id->Scope); | |
7198 | + if (0 == SC_PRESENT(session)) { | |
7199 | + id->Scope = | |
7200 | + Scope_Get_ScopefromPath(file->f_dentry); | |
7201 | + session = Scope_Get_SessionId(id->Scope); | |
7202 | + } | |
7203 | + | |
7204 | + while (len > 0 && (offset < i_size_read(inode))) { | |
7205 | + int retval; | |
7206 | + thisread = len; | |
7207 | + retval = | |
7208 | + Novfs_Read_File(file->private_data, buf, | |
7209 | + &thisread, &offset, | |
7210 | + session); | |
7211 | + if (retval || !thisread) { | |
7212 | + if (retval) { | |
7213 | + totalread = retval; | |
7214 | + } | |
7215 | + break; | |
7216 | + } | |
7217 | + DbgPrint("Novfs_f_read thisread = 0x%x\n", | |
7218 | + thisread); | |
7219 | + len -= thisread; | |
7220 | + buf += thisread; | |
7221 | + offset += thisread; | |
7222 | + totalread += thisread; | |
7223 | + } | |
7224 | + *off = offset; | |
7225 | + } | |
7226 | + } | |
7227 | + DbgPrint("Novfs_f_read return = %d\n", totalread); | |
7228 | + | |
7229 | + return (totalread); | |
7230 | +} | |
7231 | + | |
7232 | +/*++======================================================================*/ | |
7233 | +ssize_t Novfs_f_write(struct file * file, const char *buf, size_t len, | |
7234 | + loff_t * off) | |
7235 | +/* | |
7236 | + * Arguments: | |
7237 | + * | |
7238 | + * Returns: | |
7239 | + * | |
7240 | + * Abstract: | |
7241 | + * | |
7242 | + * Notes: | |
7243 | + * | |
7244 | + * Environment: | |
7245 | + * | |
7246 | + *========================================================================*/ | |
7247 | +{ | |
7248 | + ssize_t thiswrite, totalwrite = 0; | |
7249 | + loff_t offset = *off; | |
7250 | + session_t session; | |
7251 | + struct inode *inode; | |
7252 | + int status; | |
7253 | + struct inode_data *id; | |
7254 | + | |
7255 | + if (file->f_dentry && | |
7256 | + (inode = file->f_dentry->d_inode) && | |
7257 | + (id = file->f_dentry->d_inode->FSPRIVATE)) { | |
7258 | + DbgPrint("Novfs_f_write(0x%p 0x%p 0x%p %d %lld %.*s)\n", | |
7259 | + file->private_data, inode, id->FileHandle, len, offset, | |
7260 | + file->f_dentry->d_name.len, | |
7261 | + file->f_dentry->d_name.name); | |
7262 | + | |
7263 | + if (PageCache && | |
7264 | + !(file->f_flags & O_DIRECT) && | |
7265 | + id->CacheFlag && !(file->f_flags & O_WRONLY)) { | |
7266 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | |
7267 | + totalwrite = generic_file_write(file, buf, len, off); | |
7268 | +#else | |
7269 | + totalwrite = do_sync_write(file, buf, len, off); | |
7270 | +#endif | |
7271 | + } else { | |
7272 | + if (file->f_flags & O_APPEND) { | |
7273 | + offset = i_size_read(inode); | |
7274 | + DbgPrint | |
7275 | + ("Novfs_f_write appending to end %lld %.*s\n", | |
7276 | + offset, file->f_dentry->d_name.len, | |
7277 | + file->f_dentry->d_name.name); | |
7278 | + } | |
7279 | + | |
7280 | + session = Scope_Get_SessionId(id->Scope); | |
7281 | + if (0 == SC_PRESENT(session)) { | |
7282 | + id->Scope = | |
7283 | + Scope_Get_ScopefromPath(file->f_dentry); | |
7284 | + session = Scope_Get_SessionId(id->Scope); | |
7285 | + } | |
7286 | + | |
7287 | + while (len > 0) { | |
7288 | + thiswrite = len; | |
7289 | + if ((status = | |
7290 | + Novfs_Write_File(file->private_data, | |
7291 | + (unsigned char *)buf, | |
7292 | + &thiswrite, &offset, | |
7293 | + session)) || !thiswrite) { | |
7294 | + totalwrite = status; | |
7295 | + break; | |
7296 | + } | |
7297 | + DbgPrint("Novfs_f_write thiswrite = 0x%x\n", | |
7298 | + thiswrite); | |
7299 | + len -= thiswrite; | |
7300 | + buf += thiswrite; | |
7301 | + offset += thiswrite; | |
7302 | + totalwrite += thiswrite; | |
7303 | + if (offset > i_size_read(inode)) { | |
7304 | + i_size_write(inode, offset); | |
7305 | + inode->i_blocks = | |
7306 | + (offset + inode->i_sb->s_blocksize - | |
7307 | + 1) >> inode->i_blkbits; | |
7308 | + } | |
7309 | + inode->i_mtime = inode->i_atime = CURRENT_TIME; | |
7310 | + id->Flags |= UPDATE_INODE; | |
7311 | + | |
7312 | + } | |
7313 | + *off = offset; | |
7314 | + } | |
7315 | + } | |
7316 | + DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite); | |
7317 | + | |
7318 | + return (totalwrite); | |
7319 | +} | |
7320 | + | |
7321 | +int Novfs_f_readdir(struct file *file, void *data, filldir_t fill) | |
7322 | +{ | |
7323 | + return -EISDIR; | |
7324 | +} | |
7325 | + | |
7326 | +int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |
7327 | + unsigned long arg) | |
7328 | +{ | |
7329 | + DbgPrint("Novfs_f_ioctl: file=0x%p cmd=0x%x arg=0x%p\n", file, cmd, | |
7330 | + arg); | |
7331 | + | |
7332 | + return -ENOSYS; | |
7333 | +} | |
7334 | + | |
7335 | +/*++======================================================================*/ | |
7336 | +int Novfs_f_mmap(struct file *file, struct vm_area_struct *vma) | |
7337 | +/* | |
7338 | + * Arguments: | |
7339 | + * | |
7340 | + * Returns: | |
7341 | + * | |
7342 | + * Abstract: | |
7343 | + * | |
7344 | + * Notes: | |
7345 | + * | |
7346 | + * Environment: | |
7347 | + * | |
7348 | + *========================================================================*/ | |
7349 | +{ | |
7350 | + int retCode = -EINVAL; | |
7351 | + | |
7352 | + DbgPrint("Novfs_f_mmap: file=0x%p %.*s\n", file, | |
7353 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name); | |
7354 | + | |
7355 | + retCode = generic_file_mmap(file, vma); | |
7356 | + | |
7357 | + DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode); | |
7358 | + return (retCode); | |
7359 | +} | |
7360 | + | |
7361 | +/*++======================================================================*/ | |
7362 | +int Novfs_f_open(struct inode *inode, struct file *file) | |
7363 | +/* | |
7364 | + * Arguments: | |
7365 | + * | |
7366 | + * Returns: | |
7367 | + * | |
7368 | + * Abstract: | |
7369 | + * | |
7370 | + * Notes: | |
7371 | + * | |
7372 | + * Environment: | |
7373 | + * | |
7374 | + *========================================================================*/ | |
7375 | +{ | |
7376 | + struct entry_info *info = NULL; | |
7377 | + int retCode = -ENOENT; | |
7378 | + session_t session; | |
7379 | + char *path; | |
7380 | + struct dentry *parent; | |
7381 | + ino_t ino; | |
7382 | + struct inode_data *id; | |
7383 | + int errInfo; | |
7384 | + | |
7385 | + DbgPrint | |
7386 | + ("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p %.*s\n", | |
7387 | + inode, file, file->f_dentry, file->f_dentry->d_inode, | |
7388 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name); | |
7389 | + if (file->f_dentry) { | |
7390 | + DbgPrint | |
7391 | + ("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", | |
7392 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name, | |
7393 | + file->f_flags, file->f_mode, inode->i_mode); | |
7394 | + } | |
7395 | + | |
7396 | + if (inode && inode->FSPRIVATE) { | |
7397 | + id = (struct inode_data *) file->f_dentry->d_inode->FSPRIVATE; | |
7398 | + session = Scope_Get_SessionId(id->Scope); | |
7399 | + if (0 == SC_PRESENT(session)) { | |
7400 | + id->Scope = Scope_Get_ScopefromPath(file->f_dentry); | |
7401 | + session = Scope_Get_SessionId(id->Scope); | |
7402 | + } | |
7403 | + | |
7404 | + info = Novfs_Malloc(sizeof(struct entry_info) + PATH_LENGTH_BUFFER, GFP_KERNEL); | |
7405 | + if (info) { | |
7406 | + path = | |
7407 | + Novfs_dget_path(file->f_dentry, info->name, | |
7408 | + PATH_LENGTH_BUFFER); | |
7409 | + if (path) { | |
7410 | + if (file->f_flags & O_TRUNC) { | |
7411 | + errInfo = Novfs_Get_File_Info(path, info, &session); | |
7412 | + | |
7413 | + if (errInfo || info->size == 0) { | |
7414 | + // clear O_TRUNC flag, bug #275366 | |
7415 | + file->f_flags = | |
7416 | + file->f_flags & (~O_TRUNC); | |
7417 | + } | |
7418 | + } | |
7419 | + | |
7420 | + DbgPrint("Novfs_f_open: %s\n", path); | |
7421 | + retCode = Novfs_Open_File(path, | |
7422 | + file-> | |
7423 | + f_flags & ~O_EXCL, | |
7424 | + info, | |
7425 | + &file->private_data, | |
7426 | + session); | |
7427 | + | |
7428 | + DbgPrint("Novfs_f_open: 0x%x 0x%p\n", retCode, | |
7429 | + file->private_data); | |
7430 | + if (!retCode) { | |
7431 | + /* | |
7432 | + *update_inode(inode, &info); | |
7433 | + */ | |
7434 | + //id->FileHandle = file->private_data; | |
7435 | + id->CacheFlag = | |
7436 | + Novfs_Get_File_Cache_Flag(path, | |
7437 | + session); | |
7438 | + | |
7439 | + if (!Novfs_Get_File_Info(path, info, &session)) | |
7440 | + update_inode(inode, info); | |
7441 | + | |
7442 | + parent = dget_parent(file->f_dentry); | |
7443 | + | |
7444 | + if (parent && parent->d_inode) { | |
7445 | + struct inode *dir = | |
7446 | + parent->d_inode; | |
7447 | + Novfs_lock_inode_cache(dir); | |
7448 | + ino = 0; | |
7449 | + if (Novfs_get_entry | |
7450 | + (dir, | |
7451 | + &file->f_dentry->d_name, | |
7452 | + &ino, info)) { | |
7453 | + ((struct inode_data *)inode->FSPRIVATE)->Flags |= | |
7454 | + UPDATE_INODE; | |
7455 | + } | |
7456 | + | |
7457 | + Novfs_unlock_inode_cache(dir); | |
7458 | + } | |
7459 | + dput(parent); | |
7460 | + } | |
7461 | + } | |
7462 | + kfree(info); | |
7463 | + } | |
7464 | + } | |
7465 | + DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode); | |
7466 | + return (retCode); | |
7467 | +} | |
7468 | + | |
7469 | +/*++======================================================================*/ | |
7470 | +int Novfs_flush_mapping(HANDLE Handle, struct address_space *mapping, | |
7471 | + session_t Session) | |
7472 | +/* | |
7473 | + * Arguments: | |
7474 | + * | |
7475 | + * Returns: | |
7476 | + * | |
7477 | + * Abstract: | |
7478 | + * | |
7479 | + * Notes: | |
7480 | + * | |
7481 | + * Environment: | |
7482 | + * | |
7483 | + *========================================================================*/ | |
7484 | +{ | |
7485 | + struct pagevec pagevec; | |
7486 | + unsigned nrpages; | |
7487 | + pgoff_t index = 0; | |
7488 | + int done, rc = 0; | |
7489 | + | |
7490 | + pagevec_init(&pagevec, 0); | |
7491 | + | |
7492 | + do { | |
7493 | + done = 1; | |
7494 | + nrpages = pagevec_lookup_tag(&pagevec, | |
7495 | + mapping, | |
7496 | + &index, | |
7497 | + PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE); | |
7498 | + | |
7499 | + if (nrpages) { | |
7500 | + struct page *page; | |
7501 | + int i; | |
7502 | + | |
7503 | + DbgPrint("Novfs_flush_mapping: %u\n", nrpages); | |
7504 | + | |
7505 | + done = 0; | |
7506 | + for (i = 0; !rc && (i < nrpages); i++) { | |
7507 | + page = pagevec.pages[i]; | |
7508 | + | |
7509 | + DbgPrint("Novfs_flush_mapping: page 0x%p %lu\n", | |
7510 | + page, page->index); | |
7511 | + | |
7512 | + lock_page(page); | |
7513 | + page_cache_get(page); | |
7514 | + if (page->mapping == mapping) { | |
7515 | + if (clear_page_dirty_for_io(page)) { | |
7516 | + rc = Novfs_Write_Page(Handle, | |
7517 | + page, | |
7518 | + Session); | |
7519 | + if (!rc) { | |
7520 | + //ClearPageDirty(page); | |
7521 | + radix_tree_tag_clear | |
7522 | + (&mapping-> | |
7523 | + page_tree, | |
7524 | + page_index(page), | |
7525 | + PAGECACHE_TAG_DIRTY); | |
7526 | + } | |
7527 | + } | |
7528 | + } | |
7529 | + | |
7530 | + page_cache_release(page); | |
7531 | + unlock_page(page); | |
7532 | + } | |
7533 | + pagevec_release(&pagevec); | |
7534 | + } | |
7535 | + } while (!rc && !done); | |
7536 | + | |
7537 | + DbgPrint("Novfs_flush_mapping: return %d\n", rc); | |
7538 | + | |
7539 | + return (rc); | |
7540 | +} | |
7541 | + | |
7542 | +/*++======================================================================*/ | |
7543 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) | |
7544 | +int Novfs_f_flush(struct file *file) | |
7545 | +#else | |
7546 | +int Novfs_f_flush(struct file *file, fl_owner_t ownid) | |
7547 | +#endif | |
7548 | +/* | |
7549 | + * Arguments: | |
7550 | + * | |
7551 | + * Returns: | |
7552 | + * | |
7553 | + * Abstract: | |
7554 | + * | |
7555 | + * Notes: | |
7556 | + * | |
7557 | + * Environment: | |
7558 | + * | |
7559 | + *========================================================================*/ | |
7560 | +{ | |
7561 | + | |
7562 | + int rc = 0; | |
7563 | +#ifdef FLUSH | |
7564 | + struct inode *inode; | |
7565 | + session_t session; | |
7566 | + struct inode_data *id; | |
7567 | + | |
7568 | + DbgPrint("Novfs_f_flush: Called from 0x%p\n", | |
7569 | + __builtin_return_address(0)); | |
7570 | + if (file->f_dentry && (inode = file->f_dentry->d_inode) | |
7571 | + && (id = file->f_dentry->d_inode->FSPRIVATE)) { | |
7572 | + | |
7573 | + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | |
7574 | + inode = file->f_dentry->d_inode; | |
7575 | + DbgPrint | |
7576 | + ("Novfs_f_flush: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", | |
7577 | + file->f_dentry->d_name.len, | |
7578 | + file->f_dentry->d_name.name, file->f_flags, | |
7579 | + file->f_mode, inode->i_mode); | |
7580 | + | |
7581 | + session = Scope_Get_SessionId(id->Scope); | |
7582 | + if (0 == SC_PRESENT(session)) { | |
7583 | + id->Scope = | |
7584 | + Scope_Get_ScopefromPath(file->f_dentry); | |
7585 | + session = Scope_Get_SessionId(id->Scope); | |
7586 | + } | |
7587 | + | |
7588 | + if (inode && | |
7589 | + inode->i_mapping && inode->i_mapping->nrpages) { | |
7590 | + | |
7591 | + DbgPrint("Novfs_f_flush: %.*s pages=%lu\n", | |
7592 | + file->f_dentry->d_name.len, | |
7593 | + file->f_dentry->d_name.name, | |
7594 | + inode->i_mapping->nrpages); | |
7595 | + | |
7596 | + if (file->f_dentry && | |
7597 | + file->f_dentry->d_inode && | |
7598 | + file->f_dentry->d_inode->i_mapping && | |
7599 | + file->f_dentry->d_inode->i_mapping->a_ops && | |
7600 | + file->f_dentry->d_inode->i_mapping->a_ops-> | |
7601 | + writepage) { | |
7602 | + rc = filemap_fdatawrite(file->f_dentry-> | |
7603 | + d_inode-> | |
7604 | + i_mapping); | |
7605 | + } else { | |
7606 | + rc = Novfs_flush_mapping(file-> | |
7607 | + private_data, | |
7608 | + file-> | |
7609 | + f_dentry-> | |
7610 | + d_inode-> | |
7611 | + i_mapping, | |
7612 | + session); | |
7613 | + } | |
7614 | + } | |
7615 | + } | |
7616 | + } | |
7617 | +#endif | |
7618 | + return (rc); | |
7619 | +} | |
7620 | + | |
7621 | +/*++======================================================================*/ | |
7622 | +int Novfs_f_release(struct inode *inode, struct file *file) | |
7623 | +/* | |
7624 | + * Arguments: | |
7625 | + * | |
7626 | + * Returns: | |
7627 | + * | |
7628 | + * Abstract: | |
7629 | + * | |
7630 | + * Notes: | |
7631 | + * | |
7632 | + * Environment: | |
7633 | + * | |
7634 | + *========================================================================*/ | |
7635 | +{ | |
7636 | + int retCode = -EACCES; | |
7637 | + session_t session; | |
7638 | + struct inode_data *id; | |
7639 | + | |
7640 | + DbgPrint("Novfs_f_release: path=%.*s handle=%p\n", | |
7641 | + file->f_dentry->d_name.len, | |
7642 | + file->f_dentry->d_name.name, file->private_data); | |
7643 | + | |
7644 | + if (inode && (id = inode->FSPRIVATE)) { | |
7645 | + session = Scope_Get_SessionId(id->Scope); | |
7646 | + if (0 == SC_PRESENT(session)) { | |
7647 | + id->Scope = Scope_Get_ScopefromPath(file->f_dentry); | |
7648 | + session = Scope_Get_SessionId(id->Scope); | |
7649 | + } | |
7650 | + | |
7651 | + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | |
7652 | + DbgPrint | |
7653 | + ("Novfs_f_release: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", | |
7654 | + file->f_dentry->d_name.len, | |
7655 | + file->f_dentry->d_name.name, file->f_flags, | |
7656 | + file->f_mode, inode->i_mode); | |
7657 | + | |
7658 | + if (inode->i_mapping && inode->i_mapping->nrpages) { | |
7659 | + | |
7660 | + DbgPrint("Novfs_f_release: %.*s pages=%lu\n", | |
7661 | + file->f_dentry->d_name.len, | |
7662 | + file->f_dentry->d_name.name, | |
7663 | + inode->i_mapping->nrpages); | |
7664 | + | |
7665 | + if (inode->i_mapping->a_ops && | |
7666 | + inode->i_mapping->a_ops->writepage) { | |
7667 | + filemap_fdatawrite(file->f_dentry-> | |
7668 | + d_inode->i_mapping); | |
7669 | + } else { | |
7670 | + Novfs_flush_mapping(file->private_data, | |
7671 | + file->f_dentry-> | |
7672 | + d_inode->i_mapping, | |
7673 | + session); | |
7674 | + } | |
7675 | + } | |
7676 | + } | |
7677 | + | |
7678 | + if (file->f_dentry && file->f_dentry->d_inode) { | |
7679 | + invalidate_remote_inode(file->f_dentry->d_inode); | |
7680 | + } | |
7681 | + | |
7682 | + retCode = Novfs_Close_File(file->private_data, session); | |
7683 | + //id->FileHandle = 0; | |
7684 | + } | |
7685 | + return (retCode); | |
7686 | +} | |
7687 | + | |
7688 | +int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync) | |
7689 | +{ | |
7690 | + return 0; | |
7691 | +} | |
7692 | + | |
7693 | +/*++======================================================================*/ | |
7694 | +int Novfs_f_llseek(struct file *file, loff_t offset, int origin) | |
7695 | +/* | |
7696 | + * Arguments: | |
7697 | + * | |
7698 | + * Returns: | |
7699 | + * | |
7700 | + * Abstract: | |
7701 | + * | |
7702 | + * Notes: | |
7703 | + * | |
7704 | + * Environment: | |
7705 | + * | |
7706 | + *========================================================================*/ | |
7707 | +{ | |
7708 | + DbgPrint("Novfs_f_llseek: File=0x%p Name=%.*s offset=%lld origin=%d\n", | |
7709 | + file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, | |
7710 | + offset, origin); | |
7711 | + return (generic_file_llseek(file, offset, origin)); | |
7712 | +} | |
7713 | + | |
7714 | +/*++======================================================================*/ | |
7715 | +int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock) | |
7716 | +/* | |
7717 | + * Arguments: | |
7718 | + * "file" - pointer to file structure - contains file handle in "file->private_data" | |
7719 | + * | |
7720 | + * "cmd" could be F_SETLK, F_SETLKW, F_GETLK | |
7721 | + * F_SETLK/F_SETLKW are for setting/unsetting file lock | |
7722 | + * F_GETLK is for getting infomation about region - is it locked, or not | |
7723 | + * | |
7724 | + * "lock" structure - contains "start" and "end" of locking region | |
7725 | + * | |
7726 | + * Returns: | |
7727 | + * 0 on success | |
7728 | + * -ENOSYS on F_GETLK cmd. It's not implemented. | |
7729 | + * -EINVAL if (lock->fl_start > lock->fl_end) | |
7730 | + * -EAGAIN on all other errors | |
7731 | + * Abstract: | |
7732 | + * | |
7733 | + * Notes: | |
7734 | + * "lock->fl_start" and "lock->fl_end" are of type "long long", | |
7735 | + * but xtier functions in novfsd "NCFsdLockFile" and "NCFsdUnlockFile" | |
7736 | + * receive arguments in u64 type. | |
7737 | + * | |
7738 | + * Environment: | |
7739 | + * | |
7740 | + *========================================================================*/ | |
7741 | +{ | |
7742 | + int err_code; | |
7743 | + | |
7744 | + struct inode *inode; | |
7745 | + session_t session; | |
7746 | + struct inode_data *id; | |
7747 | + loff_t len; | |
7748 | + | |
7749 | + DbgPrint("Novfs_f_lock(0x%p): begin in Novfs_f_lock 0x%p\n", | |
7750 | + __builtin_return_address(0), file->private_data); | |
7751 | + DbgPrint | |
7752 | + ("Novfs_f_lock: cmd = %d, F_GETLK = %d, F_SETLK = %d, F_SETLKW = %d\n", | |
7753 | + cmd, F_GETLK, F_SETLK, F_SETLKW); | |
7754 | + DbgPrint | |
7755 | + ("Novfs_f_lock: lock->fl_start = 0x%llX, lock->fl_end = 0x%llX\n", | |
7756 | + lock->fl_start, lock->fl_end); | |
7757 | + | |
7758 | + err_code = -1; | |
7759 | + if (lock->fl_start <= lock->fl_end) { | |
7760 | + /* Get len from "start" and "end" */ | |
7761 | + len = lock->fl_end - lock->fl_start + 1; | |
7762 | + if ((0 == lock->fl_start) && (OFFSET_MAX == lock->fl_end)) { | |
7763 | + len = 0; | |
7764 | + } | |
7765 | + | |
7766 | + if (file->f_dentry && | |
7767 | + (inode = file->f_dentry->d_inode) && | |
7768 | + (id = (struct inode_data *)inode->FSPRIVATE)) { | |
7769 | + DbgPrint("Novfs_f_lock: (0x%p 0x%p %.*s)\n", | |
7770 | + file->private_data, inode, | |
7771 | + file->f_dentry->d_name.len, | |
7772 | + file->f_dentry->d_name.name); | |
7773 | + | |
7774 | + session = Scope_Get_SessionId(id->Scope); | |
7775 | + if (0 == SC_PRESENT(session)) { | |
7776 | + id->Scope = | |
7777 | + Scope_Get_ScopefromPath(file->f_dentry); | |
7778 | + session = Scope_Get_SessionId(id->Scope); | |
7779 | + } | |
7780 | + | |
7781 | + /* fl_type = F_RDLCK, F_WRLCK, F_UNLCK */ | |
7782 | + switch (cmd) { | |
7783 | + case F_SETLK: | |
7784 | +#ifdef F_GETLK64 | |
7785 | + case F_SETLK64: | |
7786 | +#endif | |
7787 | + | |
7788 | + err_code = | |
7789 | + Novfs_Set_File_Lock(session, | |
7790 | + file->private_data, | |
7791 | + lock->fl_type, | |
7792 | + lock->fl_start, len); | |
7793 | + break; | |
7794 | + | |
7795 | + case F_SETLKW: | |
7796 | +#ifdef F_GETLK64 | |
7797 | + case F_SETLKW64: | |
7798 | +#endif | |
7799 | + err_code = | |
7800 | + Novfs_Set_File_Lock(session, | |
7801 | + file->private_data, | |
7802 | + lock->fl_type, | |
7803 | + lock->fl_start, len); | |
7804 | + break; | |
7805 | + | |
7806 | + case F_GETLK: | |
7807 | +#ifdef F_GETLK64 | |
7808 | + case F_GETLK64: | |
7809 | +#endif | |
7810 | + err_code = -ENOSYS; | |
7811 | + /* | |
7812 | + * Not implemented. We doesn't have appropriate xtier function. | |
7813 | + * */ | |
7814 | + break; | |
7815 | + | |
7816 | + default: | |
7817 | + printk | |
7818 | + ("<1> novfs in Novfs_f_lock, not implemented cmd = %d\n", | |
7819 | + cmd); | |
7820 | + DbgPrint | |
7821 | + ("Novfs_f_lock: novfs in Novfs_f_lock, not implemented cmd = %d\n", | |
7822 | + cmd); | |
7823 | + break; | |
7824 | + } | |
7825 | + } | |
7826 | + | |
7827 | + DbgPrint("Novfs_f_lock: lock->fl_type = %u, err_code 0x%X\n", | |
7828 | + lock->fl_type, err_code); | |
7829 | + | |
7830 | + if ((err_code != 0) && (err_code != -1) | |
7831 | + && (err_code != -ENOSYS)) { | |
7832 | + err_code = -EAGAIN; | |
7833 | + } | |
7834 | + } else { | |
7835 | + err_code = -EINVAL; | |
7836 | + } | |
7837 | + | |
7838 | + return (err_code); | |
7839 | +} | |
7840 | + | |
7841 | +/*++======================================================================*/ | |
7842 | +static void Novfs_copy_cache_pages(struct address_space *mapping, | |
7843 | + struct list_head *pages, int bytes_read, | |
7844 | + char *data, struct pagevec *plru_pvec) | |
7845 | +/* | |
7846 | + * Arguments: | |
7847 | + * | |
7848 | + * Returns: | |
7849 | + * | |
7850 | + * Abstract: | |
7851 | + * | |
7852 | + * Notes: | |
7853 | + * | |
7854 | + * Environment: | |
7855 | + * | |
7856 | + *========================================================================*/ | |
7857 | +{ | |
7858 | + struct page *page; | |
7859 | + char *target; | |
7860 | + | |
7861 | + while (bytes_read > 0) { | |
7862 | + if (list_empty(pages)) | |
7863 | + break; | |
7864 | + | |
7865 | + page = list_entry(pages->prev, struct page, lru); | |
7866 | + list_del(&page->lru); | |
7867 | + | |
7868 | + if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { | |
7869 | + page_cache_release(page); | |
7870 | + data += PAGE_CACHE_SIZE; | |
7871 | + bytes_read -= PAGE_CACHE_SIZE; | |
7872 | + continue; | |
7873 | + } | |
7874 | + | |
7875 | + target = kmap_atomic(page, KM_USER0); | |
7876 | + | |
7877 | + if (PAGE_CACHE_SIZE > bytes_read) { | |
7878 | + memcpy(target, data, bytes_read); | |
7879 | + /* zero the tail end of this partial page */ | |
7880 | + memset(target + bytes_read, 0, | |
7881 | + PAGE_CACHE_SIZE - bytes_read); | |
7882 | + bytes_read = 0; | |
7883 | + } else { | |
7884 | + memcpy(target, data, PAGE_CACHE_SIZE); | |
7885 | + bytes_read -= PAGE_CACHE_SIZE; | |
7886 | + } | |
7887 | + kunmap_atomic(target, KM_USER0); | |
7888 | + | |
7889 | + flush_dcache_page(page); | |
7890 | + SetPageUptodate(page); | |
7891 | + unlock_page(page); | |
7892 | + if (!pagevec_add(plru_pvec, page)) | |
7893 | + __pagevec_lru_add(plru_pvec); | |
7894 | + data += PAGE_CACHE_SIZE; | |
7895 | + } | |
7896 | + return; | |
7897 | +} | |
7898 | + | |
7899 | +/*++======================================================================*/ | |
7900 | +int Novfs_a_writepage(struct page *page, struct writeback_control *wbc) | |
7901 | +/* | |
7902 | + * Arguments: | |
7903 | + * | |
7904 | + * Returns: | |
7905 | + * | |
7906 | + * Abstract: | |
7907 | + * | |
7908 | + * Notes: | |
7909 | + * | |
7910 | + * Environment: | |
7911 | + * | |
7912 | + *========================================================================*/ | |
7913 | +{ | |
7914 | + int retCode = -EFAULT; | |
7915 | + struct inode *inode = page->mapping->host; | |
7916 | + struct inode_data *id = inode->FSPRIVATE; | |
7917 | + loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT); | |
7918 | + session_t session; | |
7919 | + struct data_list dlst[2]; | |
7920 | + size_t len = PAGE_CACHE_SIZE; | |
7921 | + | |
7922 | + session = Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
7923 | + | |
7924 | + page_cache_get(page); | |
7925 | + | |
7926 | + pos = ((loff_t) page->index << PAGE_CACHE_SHIFT); | |
7927 | + | |
7928 | + /* | |
7929 | + * Leave first dlst entry for reply header. | |
7930 | + */ | |
7931 | + dlst[1].page = page; | |
7932 | + dlst[1].offset = NULL; | |
7933 | + dlst[1].len = len; | |
7934 | + dlst[1].rwflag = DLREAD; | |
7935 | + | |
7936 | + /* | |
7937 | + * Check size so we don't write pass end of file. | |
7938 | + */ | |
7939 | + if ((pos + (loff_t) len) > i_size_read(inode)) { | |
7940 | + len = (size_t) (i_size_read(inode) - pos); | |
7941 | + } | |
7942 | + | |
7943 | + retCode = Novfs_Write_Pages(id->FileHandle, dlst, 2, len, pos, session); | |
7944 | + if (!retCode) { | |
7945 | + SetPageUptodate(page); | |
7946 | + } | |
7947 | + | |
7948 | + unlock_page(page); | |
7949 | + page_cache_release(page); | |
7950 | + | |
7951 | + return (retCode); | |
7952 | +} | |
7953 | + | |
7954 | +/*++======================================================================*/ | |
7955 | +int Novfs_a_writepages(struct address_space *mapping, | |
7956 | + struct writeback_control *wbc) | |
7957 | +/* | |
7958 | + * Arguments: | |
7959 | + * | |
7960 | + * Returns: | |
7961 | + * | |
7962 | + * Abstract: | |
7963 | + * | |
7964 | + * Notes: | |
7965 | + * | |
7966 | + * Environment: | |
7967 | + * | |
7968 | + *========================================================================*/ | |
7969 | +{ | |
7970 | + int retCode = 0; | |
7971 | + struct inode *inode = mapping->host; | |
7972 | + session_t session; | |
7973 | + HANDLE fh = 0; | |
7974 | + struct inode_data *id = NULL; | |
7975 | + | |
7976 | + int max_page_lookup = MaxIoSize / PAGE_CACHE_SIZE; | |
7977 | + | |
7978 | + struct data_list *dlist; | |
7979 | + struct data_list *dlptr; | |
7980 | + struct page **pages; | |
7981 | + | |
7982 | + int dlist_idx, i = 0; | |
7983 | + pgoff_t index, next_index = 0; | |
7984 | + loff_t pos = 0; | |
7985 | + size_t tsize; | |
7986 | + | |
7987 | + SC_INITIALIZE(session); | |
7988 | + DbgPrint | |
7989 | + ("Novfs_a_writepages: inode=0x%p mapping=0x%p wbc=0x%p nr_to_write=%d\n", | |
7990 | + inode, mapping, wbc, wbc->nr_to_write); | |
7991 | + | |
7992 | + if (inode) { | |
7993 | + DbgPrint(" Inode=0x%p Ino=%d Id=0x%p\n", inode, inode->i_ino, | |
7994 | + inode->FSPRIVATE); | |
7995 | + | |
7996 | + if (NULL != (id = inode->FSPRIVATE)) { | |
7997 | + session = | |
7998 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
7999 | + fh = ((struct inode_data *)inode->FSPRIVATE)->FileHandle; | |
8000 | + } | |
8001 | + } | |
8002 | + | |
8003 | + dlist = Novfs_Malloc(sizeof(struct data_list) * max_page_lookup, GFP_KERNEL); | |
8004 | + pages = | |
8005 | + Novfs_Malloc(sizeof(struct page *) * max_page_lookup, GFP_KERNEL); | |
8006 | + | |
8007 | + if (id) | |
8008 | + DbgPrint | |
8009 | + ("Novfs_a_writepages: inode=0x%p fh=0x%p dlist=0x%p pages=0x%p %s\n", | |
8010 | + inode, fh, dlist, pages, id->Name); | |
8011 | + else | |
8012 | + DbgPrint | |
8013 | + ("Novfs_a_writepages: inode=0x%p fh=0x%p dlist=0x%p pages=0x%p\n", | |
8014 | + inode, fh, dlist, pages); | |
8015 | + | |
8016 | + if (dlist && pages) { | |
8017 | + struct backing_dev_info *bdi = mapping->backing_dev_info; | |
8018 | + int done = 0; | |
8019 | + int nr_pages = 0; | |
8020 | + int scanned = 0; | |
8021 | + | |
8022 | + if (wbc->nonblocking && bdi_write_congested(bdi)) { | |
8023 | + wbc->encountered_congestion = 1; | |
8024 | + return 0; | |
8025 | + } | |
8026 | + | |
8027 | + if (wbc->sync_mode == WB_SYNC_NONE) { | |
8028 | + index = mapping->writeback_index; /* Start from prev offset */ | |
8029 | + } else { | |
8030 | + index = 0; /* whole-file sweep */ | |
8031 | + scanned = 1; | |
8032 | + } | |
8033 | + | |
8034 | + next_index = index; | |
8035 | + | |
8036 | + while (!done && (wbc->nr_to_write > 0)) { | |
8037 | + dlist_idx = 0; | |
8038 | + dlptr = &dlist[1]; | |
8039 | + | |
8040 | + DbgPrint("Novfs_a_writepages1: nr_pages=%d\n", | |
8041 | + nr_pages); | |
8042 | + if (!nr_pages) { | |
8043 | + memset(pages, 0, | |
8044 | + sizeof(struct page *) * max_page_lookup); | |
8045 | + | |
8046 | + AS_TREE_LOCK(&mapping->tree_lock); | |
8047 | + | |
8048 | + /* | |
8049 | + * Need to ask for one less then max_page_lookup or we | |
8050 | + * will overflow the request buffer. This also frees | |
8051 | + * the first entry for the reply buffer. | |
8052 | + */ | |
8053 | + nr_pages = | |
8054 | + radix_tree_gang_lookup_tag(&mapping-> | |
8055 | + page_tree, | |
8056 | + (void **)pages, | |
8057 | + index, | |
8058 | + max_page_lookup - | |
8059 | + 1, | |
8060 | + PAGECACHE_TAG_DIRTY); | |
8061 | + | |
8062 | + DbgPrint("Novfs_a_writepages2: nr_pages=%d\n", | |
8063 | + nr_pages); | |
8064 | + /* | |
8065 | + * Check to see if there are dirty pages and there is a valid | |
8066 | + * file handle. | |
8067 | + */ | |
8068 | + if (nr_pages && !fh) { | |
8069 | + set_bit(AS_EIO, &mapping->flags); | |
8070 | + done = 1; | |
8071 | + DbgPrint | |
8072 | + ("Novfs_a_writepage: set_bit AS_EIO\n"); | |
8073 | + break; | |
8074 | + } | |
8075 | + | |
8076 | + for (i = 0; i < nr_pages; i++) { | |
8077 | + page_cache_get(pages[i]); | |
8078 | + } | |
8079 | + | |
8080 | + AS_TREE_UNLOCK(&mapping->tree_lock); | |
8081 | + | |
8082 | + if (nr_pages) { | |
8083 | + index = pages[nr_pages - 1]->index + 1; | |
8084 | + pos = | |
8085 | + (loff_t) pages[0]-> | |
8086 | + index << PAGE_CACHE_SHIFT; | |
8087 | + } | |
8088 | + | |
8089 | + if (!nr_pages) { | |
8090 | + if (scanned) { | |
8091 | + index = 0; | |
8092 | + scanned = 0; | |
8093 | + continue; | |
8094 | + } | |
8095 | + done = 1; | |
8096 | + } else { | |
8097 | + next_index = pages[0]->index; | |
8098 | + i = 0; | |
8099 | + } | |
8100 | + } else { | |
8101 | + if (pages[i]) { | |
8102 | + pos = | |
8103 | + (loff_t) pages[i]-> | |
8104 | + index << PAGE_CACHE_SHIFT; | |
8105 | + } | |
8106 | + } | |
8107 | + | |
8108 | + for (; i < nr_pages; i++) { | |
8109 | + struct page *page = pages[i]; | |
8110 | + | |
8111 | + /* | |
8112 | + * At this point we hold neither mapping->tree_lock nor | |
8113 | + * lock on the page itself: the page may be truncated or | |
8114 | + * invalidated (changing page->mapping to NULL), or even | |
8115 | + * swizzled back from swapper_space to tmpfs file | |
8116 | + * mapping | |
8117 | + */ | |
8118 | + | |
8119 | + DbgPrint | |
8120 | + ("Novfs_a_writepages: pos=0x%llx index=%d page->index=%d next_index=%d\n", | |
8121 | + pos, index, page->index, next_index); | |
8122 | + | |
8123 | + if (page->index != next_index) { | |
8124 | + next_index = page->index; | |
8125 | + break; | |
8126 | + } | |
8127 | + next_index = page->index + 1; | |
8128 | + | |
8129 | + lock_page(page); | |
8130 | + | |
8131 | + if (wbc->sync_mode != WB_SYNC_NONE) | |
8132 | + wait_on_page_writeback(page); | |
8133 | + | |
8134 | + if (page->mapping != mapping | |
8135 | + || PageWriteback(page) | |
8136 | + || !clear_page_dirty_for_io(page)) { | |
8137 | + unlock_page(page); | |
8138 | + continue; | |
8139 | + } | |
8140 | + | |
8141 | + dlptr[dlist_idx].page = page; | |
8142 | + dlptr[dlist_idx].offset = NULL; | |
8143 | + dlptr[dlist_idx].len = PAGE_CACHE_SIZE; | |
8144 | + dlptr[dlist_idx].rwflag = DLREAD; | |
8145 | + dlist_idx++; | |
8146 | + DbgPrint | |
8147 | + ("Novfs_a_writepages: Add page=0x%p index=0x%lx\n", | |
8148 | + page, page->index); | |
8149 | + } | |
8150 | + | |
8151 | + DbgPrint("Novfs_a_writepages: dlist_idx=%d\n", | |
8152 | + dlist_idx); | |
8153 | + if (dlist_idx) { | |
8154 | + tsize = dlist_idx * PAGE_CACHE_SIZE; | |
8155 | + /* | |
8156 | + * Check size so we don't write pass end of file. | |
8157 | + */ | |
8158 | + if ((pos + tsize) > i_size_read(inode)) { | |
8159 | + tsize = | |
8160 | + (size_t) (i_size_read(inode) - pos); | |
8161 | + } | |
8162 | + | |
8163 | + retCode = | |
8164 | + Novfs_Write_Pages(fh, dlist, dlist_idx + 1, | |
8165 | + tsize, pos, session); | |
8166 | + switch (retCode) { | |
8167 | + case 0: | |
8168 | + wbc->nr_to_write -= dlist_idx; | |
8169 | + break; | |
8170 | + | |
8171 | + case -ENOSPC: | |
8172 | + set_bit(AS_ENOSPC, &mapping->flags); | |
8173 | + done = 1; | |
8174 | + break; | |
8175 | + | |
8176 | + default: | |
8177 | + set_bit(AS_EIO, &mapping->flags); | |
8178 | + done = 1; | |
8179 | + break; | |
8180 | + } | |
8181 | + | |
8182 | + do { | |
8183 | + unlock_page((struct page *) | |
8184 | + dlptr[dlist_idx - 1].page); | |
8185 | + page_cache_release((struct page *) | |
8186 | + dlptr[dlist_idx - | |
8187 | + 1].page); | |
8188 | + DbgPrint | |
8189 | + ("Novfs_a_writepages: release page=0x%p index=0x%lx\n", | |
8190 | + dlptr[dlist_idx - 1].page, | |
8191 | + ((struct page *) | |
8192 | + dlptr[dlist_idx - | |
8193 | + 1].page)->index); | |
8194 | + if (!retCode) { | |
8195 | + wbc->nr_to_write--; | |
8196 | + } | |
8197 | + } while (--dlist_idx); | |
8198 | + } | |
8199 | + | |
8200 | + if (i >= nr_pages) { | |
8201 | + nr_pages = 0; | |
8202 | + } | |
8203 | + } | |
8204 | + | |
8205 | + mapping->writeback_index = index; | |
8206 | + | |
8207 | + } else { | |
8208 | + DbgPrint("Novfs_a_writepage: set_bit AS_EIO\n"); | |
8209 | + set_bit(AS_EIO, &mapping->flags); | |
8210 | + } | |
8211 | + if (dlist) | |
8212 | + kfree(dlist); | |
8213 | + if (pages) | |
8214 | + kfree(pages); | |
8215 | + | |
8216 | + DbgPrint("Novfs_a_writepage: retCode=%d\n", retCode); | |
8217 | + return (0); | |
8218 | + | |
8219 | +} | |
8220 | + | |
8221 | +/*++======================================================================*/ | |
8222 | +int Novfs_a_readpage(struct file *file, struct page *page) | |
8223 | +/* | |
8224 | + * Arguments: | |
8225 | + * | |
8226 | + * Returns: | |
8227 | + * | |
8228 | + * Abstract: | |
8229 | + * | |
8230 | + * Notes: | |
8231 | + * | |
8232 | + * Environment: | |
8233 | + * | |
8234 | + *========================================================================*/ | |
8235 | +{ | |
8236 | + int retCode = 0; | |
8237 | + void *pbuf; | |
8238 | + struct inode *inode = NULL; | |
8239 | + struct dentry *dentry = NULL; | |
8240 | + loff_t offset; | |
8241 | + size_t len; | |
8242 | + session_t session; | |
8243 | + | |
8244 | + SC_INITIALIZE(session); | |
8245 | + DbgPrint("Novfs_a_readpage: File=0x%p Name=%.*s Page=0x%p", file, | |
8246 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name, page); | |
8247 | + | |
8248 | + dentry = file->f_dentry; | |
8249 | + | |
8250 | + if (dentry) { | |
8251 | + DbgPrint(" Dentry=0x%p Name=%.*s", dentry, dentry->d_name.len, | |
8252 | + dentry->d_name.name); | |
8253 | + if (dentry->d_inode) { | |
8254 | + inode = dentry->d_inode; | |
8255 | + } | |
8256 | + } | |
8257 | + | |
8258 | + if (inode) { | |
8259 | + DbgPrint(" Inode=0x%p Ino=%d", inode, inode->i_ino); | |
8260 | + | |
8261 | + if (inode->FSPRIVATE) { | |
8262 | + session = | |
8263 | + Scope_Get_SessionId(((struct inode_data *)inode-> | |
8264 | + FSPRIVATE)->Scope); | |
8265 | + if (0 == SC_PRESENT(session)) { | |
8266 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = | |
8267 | + Scope_Get_ScopefromPath(file->f_dentry); | |
8268 | + session = Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
8269 | + } | |
8270 | + } | |
8271 | + } | |
8272 | + | |
8273 | + DbgPrint("\n"); | |
8274 | + | |
8275 | + if (!PageUptodate(page)) { | |
8276 | + struct data_list dlst[2]; | |
8277 | + | |
8278 | + offset = page->index << PAGE_CACHE_SHIFT; | |
8279 | + len = PAGE_CACHE_SIZE; | |
8280 | + | |
8281 | + /* | |
8282 | + * Save the first entry for the reply header. | |
8283 | + */ | |
8284 | + dlst[1].page = page; | |
8285 | + dlst[1].offset = NULL; | |
8286 | + dlst[1].len = PAGE_CACHE_SIZE; | |
8287 | + dlst[1].rwflag = DLWRITE; | |
8288 | + | |
8289 | + DbgPrint("Novfs_a_readpage: calling= Novfs_Read_Pages %lld\n", | |
8290 | + offset); | |
8291 | + retCode = | |
8292 | + Novfs_Read_Pages(file->private_data, dlst, 2, &len, &offset, | |
8293 | + session); | |
8294 | + if (len && (len < PAGE_CACHE_SIZE)) { | |
8295 | + pbuf = kmap_atomic(page, KM_USER0); | |
8296 | + memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE - len); | |
8297 | + kunmap_atomic(pbuf, KM_USER0); | |
8298 | + } | |
8299 | + | |
8300 | + flush_dcache_page(page); | |
8301 | + SetPageUptodate(page); | |
8302 | + } | |
8303 | + unlock_page(page); | |
8304 | + | |
8305 | + DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode); | |
8306 | + return (retCode); | |
8307 | + | |
8308 | +} | |
8309 | + | |
8310 | +/*++======================================================================*/ | |
8311 | +int Novfs_a_readpages(struct file *file, struct address_space *mapping, | |
8312 | + struct list_head *page_lst, unsigned nr_pages) | |
8313 | +/* | |
8314 | + * Arguments: | |
8315 | + * | |
8316 | + * Returns: | |
8317 | + * | |
8318 | + * Abstract: | |
8319 | + * | |
8320 | + * Notes: | |
8321 | + * | |
8322 | + * Environment: | |
8323 | + * | |
8324 | + *========================================================================*/ | |
8325 | +{ | |
8326 | + int retCode = 0; | |
8327 | + struct inode *inode = NULL; | |
8328 | + struct dentry *dentry = NULL; | |
8329 | + session_t session; | |
8330 | + loff_t offset; | |
8331 | + size_t len; | |
8332 | + | |
8333 | + unsigned page_idx; | |
8334 | + struct pagevec lru_pvec; | |
8335 | + pgoff_t next_index; | |
8336 | + | |
8337 | + char *rbuf, done = 0; | |
8338 | + SC_INITIALIZE(session); | |
8339 | + | |
8340 | + DbgPrint("Novfs_a_readpages: File=0x%p Name=%.*s Pages=%d\n", file, | |
8341 | + file->f_dentry->d_name.len, file->f_dentry->d_name.name, | |
8342 | + nr_pages); | |
8343 | + | |
8344 | + dentry = file->f_dentry; | |
8345 | + | |
8346 | + if (dentry) { | |
8347 | + DbgPrint(" Dentry=0x%p Name=%.*s\n", dentry, dentry->d_name.len, | |
8348 | + dentry->d_name.name); | |
8349 | + if (dentry->d_inode) { | |
8350 | + inode = dentry->d_inode; | |
8351 | + } | |
8352 | + } | |
8353 | + | |
8354 | + if (inode) { | |
8355 | + DbgPrint(" Inode=0x%p Ino=%d\n", inode, inode->i_ino); | |
8356 | + | |
8357 | + if (inode->FSPRIVATE) { | |
8358 | + session = | |
8359 | + Scope_Get_SessionId(((struct inode_data *)inode-> | |
8360 | + FSPRIVATE)->Scope); | |
8361 | + if (0 == SC_PRESENT(session)) { | |
8362 | + ((struct inode_data *) inode->FSPRIVATE)->Scope = | |
8363 | + Scope_Get_ScopefromPath(file->f_dentry); | |
8364 | + session = | |
8365 | + Scope_Get_SessionId(((struct inode_data *) inode-> | |
8366 | + FSPRIVATE)->Scope); | |
8367 | + } | |
8368 | + } | |
8369 | + } | |
8370 | + | |
8371 | + rbuf = (char *)Novfs_Malloc(MaxIoSize, GFP_KERNEL); | |
8372 | + if (rbuf) { | |
8373 | + pagevec_init(&lru_pvec, 0); | |
8374 | + for (page_idx = 0; page_idx < nr_pages && !done;) { | |
8375 | + struct page *page, *tpage; | |
8376 | + | |
8377 | + if (list_empty(page_lst)) | |
8378 | + break; | |
8379 | + | |
8380 | + page = list_entry(page_lst->prev, struct page, lru); | |
8381 | + | |
8382 | + next_index = page->index; | |
8383 | + offset = (loff_t) page->index << PAGE_CACHE_SHIFT; | |
8384 | + len = 0; | |
8385 | + | |
8386 | + /* | |
8387 | + * Count number of contiguous pages. | |
8388 | + */ | |
8389 | + list_for_each_entry_reverse(tpage, page_lst, lru) { | |
8390 | + if ((next_index != tpage->index) || | |
8391 | + (len >= MaxIoSize - PAGE_SIZE)) { | |
8392 | + break; | |
8393 | + } | |
8394 | + len += PAGE_SIZE; | |
8395 | + next_index++; | |
8396 | + } | |
8397 | + | |
8398 | + if (len && !done) { | |
8399 | + struct data_list dllst[2]; | |
8400 | + | |
8401 | + dllst[1].page = NULL; | |
8402 | + dllst[1].offset = rbuf; | |
8403 | + dllst[1].len = len; | |
8404 | + dllst[1].rwflag = DLWRITE; | |
8405 | + | |
8406 | + DbgPrint | |
8407 | + ("Novfs_a_readpages: calling Novfs_Read_Pages %lld\n", | |
8408 | + offset); | |
8409 | + if (!Novfs_Read_Pages | |
8410 | + (file->private_data, dllst, 2, &len, | |
8411 | + &offset, session)) { | |
8412 | + Novfs_copy_cache_pages(mapping, | |
8413 | + page_lst, len, | |
8414 | + rbuf, &lru_pvec); | |
8415 | + page_idx += len >> PAGE_CACHE_SHIFT; | |
8416 | + if ((int)(len & PAGE_CACHE_MASK) != len) { | |
8417 | + page_idx++; | |
8418 | + } | |
8419 | + if (len == 0) { | |
8420 | + done = 1; | |
8421 | + } | |
8422 | + } else { | |
8423 | + done = 1; | |
8424 | + } | |
8425 | + } | |
8426 | + } | |
8427 | + | |
8428 | + /* | |
8429 | + * Free any remaining pages. | |
8430 | + */ | |
8431 | + while (!list_empty(page_lst)) { | |
8432 | + struct page *page = | |
8433 | + list_entry(page_lst->prev, struct page, lru); | |
8434 | + | |
8435 | + list_del(&page->lru); | |
8436 | + page_cache_release(page); | |
8437 | + } | |
8438 | + | |
8439 | + pagevec_lru_add(&lru_pvec); | |
8440 | + kfree(rbuf); | |
8441 | + } else { | |
8442 | + retCode = -ENOMEM; | |
8443 | + } | |
8444 | + | |
8445 | + DbgPrint("Novfs_a_readpages: retCode=%d\n", retCode); | |
8446 | + return (retCode); | |
8447 | + | |
8448 | +} | |
8449 | + | |
8450 | +/*++======================================================================*/ | |
8451 | +int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, | |
8452 | + unsigned to) | |
8453 | +/* | |
8454 | + * Arguments: | |
8455 | + * | |
8456 | + * Returns: | |
8457 | + * | |
8458 | + * Abstract: | |
8459 | + * | |
8460 | + * Notes: | |
8461 | + * | |
8462 | + * Environment: | |
8463 | + * | |
8464 | + *========================================================================*/ | |
8465 | +{ | |
8466 | + int retVal = 0; | |
8467 | + loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT; | |
8468 | + size_t len = PAGE_CACHE_SIZE; | |
8469 | + session_t session; | |
8470 | + struct data_list dllst[2]; | |
8471 | + struct inode *inode = file->f_dentry->d_inode; | |
8472 | + SC_INITIALIZE(session); | |
8473 | + | |
8474 | + DbgPrint | |
8475 | + ("Novfs_a_prepare_write: File=0x%p Page=0x%p offset=0x%llx From=%u To=%u filesize=%lld\n", | |
8476 | + file, page, offset, from, to, | |
8477 | + i_size_read(file->f_dentry->d_inode)); | |
8478 | + if (!PageUptodate(page)) { | |
8479 | + /* | |
8480 | + * Check to see if whole page | |
8481 | + */ | |
8482 | + if ((to == PAGE_CACHE_SIZE) && (from == 0)) { | |
8483 | + SetPageUptodate(page); | |
8484 | + } | |
8485 | + | |
8486 | + /* | |
8487 | + * Check to see if we can read page. | |
8488 | + */ | |
8489 | + else if ((file->f_flags & O_ACCMODE) != O_WRONLY) { | |
8490 | + /* | |
8491 | + * Get session. | |
8492 | + */ | |
8493 | + if (file->f_dentry && file->f_dentry->d_inode) { | |
8494 | + if (file->f_dentry->d_inode->FSPRIVATE) { | |
8495 | + session = | |
8496 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
8497 | + if (0 == SC_PRESENT(session)) { | |
8498 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = Scope_Get_ScopefromPath(file->f_dentry); | |
8499 | + session = Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
8500 | + } | |
8501 | + } | |
8502 | + } | |
8503 | + | |
8504 | + page_cache_get(page); | |
8505 | + | |
8506 | + len = i_size_read(inode) - offset; | |
8507 | + if (len > PAGE_CACHE_SIZE) { | |
8508 | + len = PAGE_CACHE_SIZE; | |
8509 | + } | |
8510 | + | |
8511 | + if (len) { | |
8512 | + /* | |
8513 | + * Read page from server. | |
8514 | + */ | |
8515 | + | |
8516 | + dllst[1].page = page; | |
8517 | + dllst[1].offset = 0; | |
8518 | + dllst[1].len = len; | |
8519 | + dllst[1].rwflag = DLWRITE; | |
8520 | + | |
8521 | + DbgPrint | |
8522 | + ("Novfs_a_prepare_write: calling Novfs_Read_Pages %lld\n", | |
8523 | + offset); | |
8524 | + Novfs_Read_Pages(file->private_data, dllst, 2, | |
8525 | + &len, &offset, session); | |
8526 | + | |
8527 | + /* | |
8528 | + * Zero unnsed page. | |
8529 | + */ | |
8530 | + } | |
8531 | + | |
8532 | + if (len < PAGE_CACHE_SIZE) { | |
8533 | + char *adr = kmap_atomic(page, KM_USER0); | |
8534 | + memset(adr + len, 0, PAGE_CACHE_SIZE - len); | |
8535 | + kunmap_atomic(adr, KM_USER0); | |
8536 | + } | |
8537 | + } else { | |
8538 | + /* | |
8539 | + * Zero section of memory that not going to be used. | |
8540 | + */ | |
8541 | + char *adr = kmap_atomic(page, KM_USER0); | |
8542 | + memset(adr, 0, from); | |
8543 | + memset(adr + to, 0, PAGE_CACHE_SIZE - to); | |
8544 | + kunmap_atomic(adr, KM_USER0); | |
8545 | + | |
8546 | + DbgPrint("Novfs_a_prepare_write: memset 0x%p\n", adr); | |
8547 | + } | |
8548 | + flush_dcache_page(page); | |
8549 | + SetPageUptodate(page); | |
8550 | + } | |
8551 | +// DbgPrint("Novfs_a_prepare_write: return %d\n", retVal); | |
8552 | + return (retVal); | |
8553 | +} | |
8554 | + | |
8555 | +/*++======================================================================*/ | |
8556 | +int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, | |
8557 | + unsigned to) | |
8558 | +/* | |
8559 | + * Arguments: | |
8560 | + * | |
8561 | + * Returns: | |
8562 | + * | |
8563 | + * Abstract: | |
8564 | + * | |
8565 | + * Notes: | |
8566 | + * | |
8567 | + * Environment: | |
8568 | + * | |
8569 | + *========================================================================*/ | |
8570 | +{ | |
8571 | + int retCode = 0; | |
8572 | + struct inode *inode = page->mapping->host; | |
8573 | + loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to; | |
8574 | + session_t session; | |
8575 | + struct inode_data *id; | |
8576 | + struct data_list dlst[1]; | |
8577 | + size_t len = to - offset; | |
8578 | + | |
8579 | + SC_INITIALIZE(session); | |
8580 | + | |
8581 | + DbgPrint | |
8582 | + ("Novfs_a_commit_write: File=0x%p Page=0x%p offset=0x%x To=%u filesize=%lld\n", | |
8583 | + file, page, offset, to, i_size_read(file->f_dentry->d_inode)); | |
8584 | + if (file->f_dentry->d_inode | |
8585 | + && (id = file->f_dentry->d_inode->FSPRIVATE)) { | |
8586 | + session = Scope_Get_SessionId(id->Scope); | |
8587 | + if (0 == SC_PRESENT(session)) { | |
8588 | + id->Scope = Scope_Get_ScopefromPath(file->f_dentry); | |
8589 | + session = Scope_Get_SessionId(id->Scope); | |
8590 | + } | |
8591 | + | |
8592 | + /* | |
8593 | + * Setup file handle | |
8594 | + */ | |
8595 | + id->FileHandle = file->private_data; | |
8596 | + | |
8597 | + if (pos > inode->i_size) { | |
8598 | + i_size_write(inode, pos); | |
8599 | + } | |
8600 | + | |
8601 | + if (!PageUptodate(page)) { | |
8602 | + pos = | |
8603 | + ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset; | |
8604 | + | |
8605 | + if (to < offset) { | |
8606 | + return (retCode); | |
8607 | + } | |
8608 | + dlst[0].page = page; | |
8609 | + dlst[0].offset = (void *)(unsigned long) offset; | |
8610 | + dlst[0].len = len; | |
8611 | + dlst[0].rwflag = DLREAD; | |
8612 | + | |
8613 | + retCode = | |
8614 | + Novfs_Write_Pages(id->FileHandle, dlst, 1, len, pos, | |
8615 | + session); | |
8616 | + | |
8617 | + } else { | |
8618 | + set_page_dirty(page); | |
8619 | + } | |
8620 | + } | |
8621 | + | |
8622 | + return (retCode); | |
8623 | +} | |
8624 | + | |
8625 | +/*++======================================================================*/ | |
8626 | +ssize_t Novfs_a_direct_IO(int rw, struct kiocb * kiocb, | |
8627 | + const struct iovec * iov, | |
8628 | + loff_t offset, unsigned long nr_segs) | |
8629 | +/* | |
8630 | + * Arguments: | |
8631 | + * | |
8632 | + * Returns: | |
8633 | + * | |
8634 | + * Abstract: | |
8635 | + * | |
8636 | + * Notes: This is a dummy function so that we can allow a file | |
8637 | + * to get the direct IO flag set. Novfs_f_read and | |
8638 | + * Novfs_f_write will do the work. Maybe not the best | |
8639 | + * way to do but it was the easiest to implement. | |
8640 | + * | |
8641 | + * Environment: | |
8642 | + * | |
8643 | + *========================================================================*/ | |
8644 | +{ | |
8645 | + return (-EIO); | |
8646 | +} | |
8647 | + | |
8648 | +/*++======================================================================*/ | |
8649 | +int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, | |
8650 | + struct nameidata *nd) | |
8651 | +/* | |
8652 | + * Arguments: | |
8653 | + * | |
8654 | + * Returns: | |
8655 | + * | |
8656 | + * Abstract: | |
8657 | + * | |
8658 | + * Notes: | |
8659 | + * | |
8660 | + * Environment: | |
8661 | + * | |
8662 | + *========================================================================*/ | |
8663 | +{ | |
8664 | + char *path, *buf; | |
8665 | + struct entry_info info; | |
8666 | + HANDLE handle; | |
8667 | + session_t session; | |
8668 | + int retCode = -EACCES; | |
8669 | + | |
8670 | + DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, | |
8671 | + nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name); | |
8672 | + | |
8673 | + if (IS_ROOT(dentry) || /* Root */ | |
8674 | + IS_ROOT(dentry->d_parent) || /* User */ | |
8675 | + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ | |
8676 | + IS_ROOT(dentry->d_parent->d_parent->d_parent)) { /* Volume */ | |
8677 | + return (-EACCES); | |
8678 | + } | |
8679 | + | |
8680 | + if (mode | S_IFREG) { | |
8681 | + if (dir->FSPRIVATE) { | |
8682 | + session = | |
8683 | + Scope_Get_SessionId(((struct inode_data *)dir->FSPRIVATE)-> | |
8684 | + Scope); | |
8685 | + if (0 == SC_PRESENT(session)) { | |
8686 | + ((struct inode_data *) dir->FSPRIVATE)->Scope = | |
8687 | + Scope_Get_ScopefromPath(dentry); | |
8688 | + session = Scope_Get_SessionId(((struct inode_data *)dir->FSPRIVATE)->Scope); | |
8689 | + } | |
8690 | + | |
8691 | + buf = | |
8692 | + (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, | |
8693 | + GFP_KERNEL); | |
8694 | + if (buf) { | |
8695 | + path = | |
8696 | + Novfs_dget_path(dentry, buf, | |
8697 | + PATH_LENGTH_BUFFER); | |
8698 | + if (path) { | |
8699 | + retCode = | |
8700 | + Novfs_Open_File(path, | |
8701 | + nd-> | |
8702 | + NDOPENFLAGS | | |
8703 | + O_RDWR, &info, | |
8704 | + &handle, session); | |
8705 | + if (!retCode && handle) { | |
8706 | + Novfs_Close_File(handle, | |
8707 | + session); | |
8708 | + if (!Novfs_i_mknod | |
8709 | + (dir, dentry, | |
8710 | + mode | S_IFREG, 0)) { | |
8711 | + if (dentry->d_inode) { | |
8712 | + ((struct inode_data *)dentry->d_inode->FSPRIVATE)->Flags |= UPDATE_INODE; | |
8713 | + } | |
8714 | + } | |
8715 | + } | |
8716 | + } | |
8717 | + kfree(buf); | |
8718 | + } | |
8719 | + } | |
8720 | + } | |
8721 | + return (retCode); | |
8722 | +} | |
8723 | + | |
8724 | +/*++======================================================================*/ | |
8725 | +void update_inode(struct inode *Inode, struct entry_info *Info) | |
8726 | +/* | |
8727 | + * Arguments: | |
8728 | + * | |
8729 | + * Returns: | |
8730 | + * | |
8731 | + * Abstract: | |
8732 | + * | |
8733 | + * Notes: | |
8734 | + * | |
8735 | + * Environment: | |
8736 | + * | |
8737 | + *========================================================================*/ | |
8738 | +{ | |
8739 | + static char dbuf[128]; | |
8740 | + | |
8741 | + DbgPrint("update_inode: Inode=0x%p I_ino=%d\n", Inode, Inode->i_ino); | |
8742 | + | |
8743 | + DbgPrint("update_inode: atime=%s\n", | |
8744 | + ctime_r(&Info->atime.tv_sec, dbuf)); | |
8745 | + DbgPrint("update_inode: ctime=%s\n", | |
8746 | + ctime_r(&Info->ctime.tv_sec, dbuf)); | |
8747 | + DbgPrint("update_inode: mtime=%s %d\n", | |
8748 | + ctime_r(&Info->mtime.tv_sec, dbuf), Info->mtime.tv_nsec); | |
8749 | + DbgPrint("update_inode: size=%lld\n", Info->size); | |
8750 | + DbgPrint("update_inode: mode=0%o\n", Info->mode); | |
8751 | + | |
8752 | + if (Inode && | |
8753 | + ((Inode->i_size != Info->size) || | |
8754 | + (Inode->i_mtime.tv_sec != Info->mtime.tv_sec) || | |
8755 | + (Inode->i_mtime.tv_nsec != Info->mtime.tv_nsec))) { | |
8756 | + DbgPrint | |
8757 | + ("update_inode: calling invalidate_remote_inode sz %d %d\n", | |
8758 | + Inode->i_size, Info->size); | |
8759 | + DbgPrint | |
8760 | + ("update_inode: calling invalidate_remote_inode sec %d %d\n", | |
8761 | + Inode->i_mtime.tv_sec, Info->mtime.tv_sec); | |
8762 | + DbgPrint | |
8763 | + ("update_inode: calling invalidate_remote_inode ns %d %d\n", | |
8764 | + Inode->i_mtime.tv_nsec, Info->mtime.tv_nsec); | |
8765 | + | |
8766 | + if (Inode && Inode->i_mapping) { | |
8767 | + invalidate_remote_inode(Inode); | |
8768 | + } | |
8769 | + } | |
8770 | + | |
8771 | + Inode->i_mode = Info->mode; | |
8772 | + Inode->i_size = Info->size; | |
8773 | + Inode->i_atime = Info->atime; | |
8774 | + Inode->i_ctime = Info->ctime; | |
8775 | + Inode->i_mtime = Info->mtime; | |
8776 | + | |
8777 | + if (Inode->i_size && Inode->i_sb->s_blocksize) { | |
8778 | + Inode->i_blocks = (unsigned long) (Info->size >> (loff_t) Inode->i_blkbits); | |
8779 | + Inode->i_bytes = Info->size & (Inode->i_sb->s_blocksize - 1); | |
8780 | + | |
8781 | + DbgPrint("update_inode: i_sb->s_blocksize=%d\n", Inode->i_sb->s_blocksize); | |
8782 | + DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits); | |
8783 | + DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks); | |
8784 | + DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes); | |
8785 | + } | |
8786 | +} | |
8787 | + | |
8788 | +/*++======================================================================*/ | |
8789 | +struct dentry *Novfs_i_lookup(struct inode *dir, struct dentry *dentry, | |
8790 | + struct nameidata *nd) | |
8791 | +/* | |
8792 | + * Arguments: | |
8793 | + * | |
8794 | + * Returns: | |
8795 | + * | |
8796 | + * Abstract: | |
8797 | + * | |
8798 | + * Notes: | |
8799 | + * | |
8800 | + * Environment: | |
8801 | + * | |
8802 | + *========================================================================*/ | |
8803 | +{ | |
8804 | + struct dentry *retVal = ERR_PTR(-ENOENT); | |
8805 | + struct dentry *parent; | |
8806 | + struct entry_info *info = NULL; | |
8807 | + struct inode_data *id; | |
8808 | + struct inode *inode = NULL; | |
8809 | + uid_t uid = current->euid; | |
8810 | + ino_t ino = 0; | |
8811 | + struct qstr name; | |
8812 | + char *buf; | |
8813 | + | |
8814 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
8815 | + if (buf) { | |
8816 | + char *path; | |
8817 | + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); | |
8818 | + if (path) { | |
8819 | + DbgPrint | |
8820 | + ("Novfs_i_lookup: dir 0x%p %d hash %d inode 0x%0p %s\n", | |
8821 | + dir, dir->i_ino, dentry->d_name.hash, | |
8822 | + dentry->d_inode, path); | |
8823 | + } | |
8824 | + kfree(buf); | |
8825 | + } else { | |
8826 | + DbgPrint | |
8827 | + ("Novfs_i_lookup: dir 0x%p %d name %.*s hash %d inode 0x%0p\n", | |
8828 | + dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, | |
8829 | + dentry->d_name.hash, dentry->d_inode); | |
8830 | + } | |
8831 | + | |
8832 | + if ((dentry->d_name.len == 7) | |
8833 | + && (0 == strncmp(dentry->d_name.name, " !xover", 7))) { | |
8834 | + dentry->d_op = &Novfs_dentry_operations; | |
8835 | + igrab(dir); | |
8836 | + d_add(dentry, dir); | |
8837 | + return NULL; | |
8838 | + } | |
8839 | + if ((dentry->d_name.len == 7) | |
8840 | + && (0 == strncmp(dentry->d_name.name, "z!xover", 7))) { | |
8841 | + dentry->d_op = &Novfs_dentry_operations; | |
8842 | + igrab(dir); | |
8843 | + d_add(dentry, dir); | |
8844 | + return NULL; | |
8845 | + } | |
8846 | + | |
8847 | + if (dir && (id = dir->FSPRIVATE)) { | |
8848 | + retVal = 0; | |
8849 | + if (IS_ROOT(dentry)) { | |
8850 | + DbgPrint("Novfs_i_lookup: Root entry=0x%p\n", | |
8851 | + Novfs_root); | |
8852 | + inode = Novfs_root->d_inode; | |
8853 | + return (0); | |
8854 | + } else { | |
8855 | + info = | |
8856 | + Novfs_Malloc(sizeof(struct entry_info) + | |
8857 | + PATH_LENGTH_BUFFER, GFP_KERNEL); | |
8858 | + if (info) { | |
8859 | + if (NULL == | |
8860 | + (retVal = | |
8861 | + ERR_PTR(verify_dentry(dentry, 1)))) { | |
8862 | + name.name = dentry->d_name.name; | |
8863 | + name.len = dentry->d_name.len; | |
8864 | + name.hash = Novfs_internal_hash(&name); | |
8865 | + | |
8866 | + if (Novfs_lock_inode_cache(dir)) { | |
8867 | + if (!Novfs_get_entry | |
8868 | + (dir, &name, &ino, info)) { | |
8869 | + inode = | |
8870 | + ilookup(dentry-> | |
8871 | + d_sb, ino); | |
8872 | + if (inode) { | |
8873 | + update_inode | |
8874 | + (inode, | |
8875 | + info); | |
8876 | + } | |
8877 | + } | |
8878 | + Novfs_unlock_inode_cache(dir); | |
8879 | + } | |
8880 | + | |
8881 | + if (!inode && ino) { | |
8882 | + uid = Scope_Get_Uid(id->Scope); | |
8883 | + if (Novfs_lock_inode_cache(dir)) { | |
8884 | + inode = Novfs_get_inode (dentry->d_sb, info->mode, 0, uid, ino, &name); | |
8885 | + if (inode) { | |
8886 | + if (!Novfs_get_entry(dir, &dentry->d_name, &ino, info)) { | |
8887 | + update_inode | |
8888 | + (inode, | |
8889 | + info); | |
8890 | + } | |
8891 | + } | |
8892 | + Novfs_unlock_inode_cache | |
8893 | + (dir); | |
8894 | + } | |
8895 | + } | |
8896 | + } | |
8897 | + } | |
8898 | + } | |
8899 | + } | |
8900 | + | |
8901 | + if (!retVal) { | |
8902 | + dentry->d_op = &Novfs_dentry_operations; | |
8903 | + if (inode) { | |
8904 | + parent = dget_parent(dentry); | |
8905 | + Novfs_d_add(dentry->d_parent, dentry, inode, 1); | |
8906 | + dput(parent); | |
8907 | + } else { | |
8908 | + d_add(dentry, inode); | |
8909 | + } | |
8910 | + } | |
8911 | + | |
8912 | + if (info) | |
8913 | + kfree(info); | |
8914 | + | |
8915 | + DbgPrint | |
8916 | + ("Novfs_i_lookup: inode=0x%p dentry->d_inode=0x%p return=0x%p\n", | |
8917 | + dir, dentry->d_inode, retVal); | |
8918 | + | |
8919 | + return (retVal); | |
8920 | +} | |
8921 | + | |
8922 | +/*++======================================================================*/ | |
8923 | +int Novfs_i_unlink(struct inode *dir, struct dentry *dentry) | |
8924 | +/* | |
8925 | + * Arguments: | |
8926 | + * | |
8927 | + * Returns: | |
8928 | + * | |
8929 | + * Abstract: | |
8930 | + * | |
8931 | + * Notes: | |
8932 | + * | |
8933 | + * Environment: | |
8934 | + * | |
8935 | + *========================================================================*/ | |
8936 | +{ | |
8937 | + int retCode = -ENOENT; | |
8938 | + struct inode *inode; | |
8939 | + session_t session; | |
8940 | + char *path, *buf; | |
8941 | + uint64_t t64; | |
8942 | + | |
8943 | + DbgPrint("Novfs_i_unlink: dir=0x%p dir->i_ino=%d %.*s\n", dir, | |
8944 | + dir->i_ino, dentry->d_name.len, dentry->d_name.name); | |
8945 | + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry)); | |
8946 | + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", | |
8947 | + IS_ROOT(dentry->d_parent)); | |
8948 | + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", | |
8949 | + IS_ROOT(dentry->d_parent->d_parent)); | |
8950 | + DbgPrint | |
8951 | + ("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", | |
8952 | + IS_ROOT(dentry->d_parent->d_parent->d_parent)); | |
8953 | + | |
8954 | + if (IS_ROOT(dentry) || /* Root */ | |
8955 | + IS_ROOT(dentry->d_parent) || /* User */ | |
8956 | + (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */ | |
8957 | + IS_ROOT(dentry->d_parent->d_parent->d_parent))) { /* Volume */ | |
8958 | + return (-EACCES); | |
8959 | + } | |
8960 | + | |
8961 | + inode = dentry->d_inode; | |
8962 | + if (inode) { | |
8963 | + DbgPrint | |
8964 | + ("Novfs_i_unlink: dir=0x%p dir->i_ino=%d inode=0x%p ino=%d\n", | |
8965 | + dir, dir->i_ino, inode, inode->i_ino); | |
8966 | + if (inode->FSPRIVATE) { | |
8967 | + session = | |
8968 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
8969 | + if (0 == SC_PRESENT(session)) { | |
8970 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = Scope_Get_ScopefromPath(dentry); | |
8971 | + session = Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
8972 | + } | |
8973 | + | |
8974 | + buf = | |
8975 | + (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, | |
8976 | + GFP_KERNEL); | |
8977 | + if (buf) { | |
8978 | + path = | |
8979 | + Novfs_dget_path(dentry, buf, | |
8980 | + PATH_LENGTH_BUFFER); | |
8981 | + if (path) { | |
8982 | + DbgPrint | |
8983 | + ("Novfs_i_unlink: path %s mode 0%o\n", | |
8984 | + path, inode->i_mode); | |
8985 | + if (IS_ROOT(dentry->d_parent->d_parent)) { | |
8986 | + retCode = do_logout(&dentry->d_name, &session); | |
8987 | + } else { | |
8988 | + retCode = | |
8989 | + Novfs_Delete(path, | |
8990 | + S_ISDIR(inode-> | |
8991 | + i_mode), | |
8992 | + session); | |
8993 | + } | |
8994 | + if (!retCode || IS_DEADDIR(inode)) { | |
8995 | + Novfs_remove_inode_entry(dir, | |
8996 | + &dentry-> | |
8997 | + d_name, | |
8998 | + 0); | |
8999 | + dentry->d_time = 0; | |
9000 | + t64 = 0; | |
9001 | + Scope_Set_UserSpace(&t64, &t64, | |
9002 | + &t64, &t64); | |
9003 | + retCode = 0; | |
9004 | + } | |
9005 | + } | |
9006 | + kfree(buf); | |
9007 | + } | |
9008 | + } | |
9009 | + } | |
9010 | + | |
9011 | + DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode); | |
9012 | + return (retCode); | |
9013 | +} | |
9014 | + | |
9015 | +/*++======================================================================*/ | |
9016 | +int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |
9017 | +/* | |
9018 | + * Arguments: | |
9019 | + * | |
9020 | + * Returns: | |
9021 | + * | |
9022 | + * Abstract: | |
9023 | + * | |
9024 | + * Notes: | |
9025 | + * | |
9026 | + * Environment: | |
9027 | + * | |
9028 | + *========================================================================*/ | |
9029 | +{ | |
9030 | + char *path, *buf; | |
9031 | + session_t session; | |
9032 | + int retCode = 0; | |
9033 | + struct inode *inode; | |
9034 | + struct entry_info info; | |
9035 | + uid_t uid; | |
9036 | + | |
9037 | + DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%lo\n", | |
9038 | + dir, dir->i_ino, dentry, dentry->d_name.len, | |
9039 | + dentry->d_name.name, mode); | |
9040 | + | |
9041 | + if (IS_ROOT(dentry) || /* Root */ | |
9042 | + IS_ROOT(dentry->d_parent) || /* User */ | |
9043 | + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ | |
9044 | + IS_ROOT(dentry->d_parent->d_parent->d_parent)) { /* Volume */ | |
9045 | + return (-EACCES); | |
9046 | + } | |
9047 | + | |
9048 | + mode |= S_IFDIR; | |
9049 | + mode &= (S_IFMT | S_IRWXU); | |
9050 | + if (dir->FSPRIVATE) { | |
9051 | + session = | |
9052 | + Scope_Get_SessionId(((struct inode_data *)dir->FSPRIVATE)->Scope); | |
9053 | + if (0 == SC_PRESENT(session)) { | |
9054 | + ((struct inode_data *)dir->FSPRIVATE)->Scope = | |
9055 | + Scope_Get_ScopefromPath(dentry); | |
9056 | + session = | |
9057 | + Scope_Get_SessionId(((struct inode_data *)dir->FSPRIVATE)->Scope); | |
9058 | + } | |
9059 | + | |
9060 | + uid = Scope_Get_Uid(((struct inode_data *)dir->FSPRIVATE)->Scope); | |
9061 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
9062 | + if (buf) { | |
9063 | + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); | |
9064 | + if (path) { | |
9065 | + DbgPrint("Novfs_i_mkdir: path %s\n", path); | |
9066 | + retCode = | |
9067 | + Novfs_Create(path, S_ISDIR(mode), session); | |
9068 | + if (!retCode) { | |
9069 | + retCode = Novfs_Get_File_Info(path, &info, &session); | |
9070 | + if (!retCode) { | |
9071 | + retCode = Novfs_i_mknod(dir, dentry, mode, 0); | |
9072 | + inode = dentry->d_inode; | |
9073 | + if (inode) { | |
9074 | + update_inode(inode, | |
9075 | + &info); | |
9076 | + ((struct inode_data *)inode->FSPRIVATE)->Flags &= ~UPDATE_INODE; | |
9077 | + | |
9078 | + dentry->d_time = | |
9079 | + jiffies + | |
9080 | + (File_update_timeout | |
9081 | + * HZ); | |
9082 | + | |
9083 | + Novfs_lock_inode_cache | |
9084 | + (dir); | |
9085 | + if (Novfs_update_entry | |
9086 | + (dir, | |
9087 | + &dentry->d_name, 0, | |
9088 | + &info)) { | |
9089 | + Novfs_add_inode_entry | |
9090 | + (dir, | |
9091 | + &dentry-> | |
9092 | + d_name, | |
9093 | + inode-> | |
9094 | + i_ino, | |
9095 | + &info); | |
9096 | + } | |
9097 | + Novfs_unlock_inode_cache | |
9098 | + (dir); | |
9099 | + } | |
9100 | + | |
9101 | + } | |
9102 | + } | |
9103 | + } | |
9104 | + kfree(buf); | |
9105 | + } | |
9106 | + } | |
9107 | + | |
9108 | + return (retCode); | |
9109 | +} | |
9110 | + | |
9111 | +/*++======================================================================*/ | |
9112 | +int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry) | |
9113 | +/* | |
9114 | + * Arguments: | |
9115 | + * | |
9116 | + * Returns: | |
9117 | + * | |
9118 | + * Abstract: | |
9119 | + * | |
9120 | + * Notes: | |
9121 | + * | |
9122 | + * Environment: | |
9123 | + * | |
9124 | + *========================================================================*/ | |
9125 | +{ | |
9126 | + return (Novfs_i_unlink(inode, dentry)); | |
9127 | +} | |
9128 | + | |
9129 | +/*++======================================================================*/ | |
9130 | +int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |
9131 | +/* | |
9132 | + * Arguments: | |
9133 | + * | |
9134 | + * Returns: | |
9135 | + * | |
9136 | + * Abstract: | |
9137 | + * | |
9138 | + * Notes: | |
9139 | + * | |
9140 | + * Environment: | |
9141 | + * | |
9142 | + *========================================================================*/ | |
9143 | +{ | |
9144 | + struct inode *inode = NULL; | |
9145 | + int retCode = -EACCES; | |
9146 | + uid_t uid; | |
9147 | + struct dentry *parent; | |
9148 | + | |
9149 | + if (IS_ROOT(dentry) || /* Root */ | |
9150 | + IS_ROOT(dentry->d_parent) || /* User */ | |
9151 | + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ | |
9152 | + IS_ROOT(dentry->d_parent->d_parent->d_parent)) { /* Volume */ | |
9153 | + return (-EACCES); | |
9154 | + } | |
9155 | + | |
9156 | + if (((struct inode_data *)dir->FSPRIVATE)) { | |
9157 | + uid = Scope_Get_Uid(((struct inode_data *)dir->FSPRIVATE)->Scope); | |
9158 | + if (mode & (S_IFREG | S_IFDIR)) { | |
9159 | + inode = | |
9160 | + Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name); | |
9161 | + } | |
9162 | + } | |
9163 | + if (inode) { | |
9164 | + struct entry_info info; | |
9165 | + | |
9166 | + dentry->d_op = &Novfs_dentry_operations; | |
9167 | + parent = dget_parent(dentry); | |
9168 | + Novfs_d_add(parent, dentry, inode, 0); | |
9169 | + memset(&info, 0, sizeof(info)); | |
9170 | + info.mode = inode->i_mode; | |
9171 | + Novfs_lock_inode_cache(dir); | |
9172 | + Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, | |
9173 | + &info); | |
9174 | + Novfs_unlock_inode_cache(dir); | |
9175 | + | |
9176 | + dput(parent); | |
9177 | + | |
9178 | + retCode = 0; | |
9179 | + } | |
9180 | + DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode); | |
9181 | + return retCode; | |
9182 | +} | |
9183 | + | |
9184 | +int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, | |
9185 | + struct dentry *nd) | |
9186 | +{ | |
9187 | + int retCode = -ENOTEMPTY; | |
9188 | + char *newpath, *newbuf, *newcon; | |
9189 | + char *oldpath, *oldbuf, *oldcon; | |
9190 | + struct qstr newname, oldname; | |
9191 | + struct entry_info *info = NULL; | |
9192 | + int oldlen, newlen; | |
9193 | + session_t session; | |
9194 | + ino_t ino; | |
9195 | + | |
9196 | + if (IS_ROOT(od) || /* Root */ | |
9197 | + IS_ROOT(od->d_parent) || /* User */ | |
9198 | + IS_ROOT(od->d_parent->d_parent) || /* Server */ | |
9199 | + IS_ROOT(od->d_parent->d_parent->d_parent)) { /* Volume */ | |
9200 | + return (-EACCES); | |
9201 | + } | |
9202 | + | |
9203 | + DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, | |
9204 | + odir->i_ino, ndir, ndir->i_ino); | |
9205 | + | |
9206 | + oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER * 2, GFP_KERNEL); | |
9207 | + newbuf = oldbuf + PATH_LENGTH_BUFFER; | |
9208 | + if (oldbuf && newbuf) { | |
9209 | + oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER); | |
9210 | + newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER); | |
9211 | + if (oldpath && newpath) { | |
9212 | + oldlen = PATH_LENGTH_BUFFER - (int)(oldpath - oldbuf); | |
9213 | + newlen = PATH_LENGTH_BUFFER - (int)(newpath - newbuf); | |
9214 | + | |
9215 | + DbgPrint | |
9216 | + ("Novfs_i_rename: od=0x%p od->inode=0x%p od->inode->i_ino=%d %s\n", | |
9217 | + od, od->d_inode, od->d_inode->i_ino, oldpath); | |
9218 | + if (nd->d_inode) { | |
9219 | + DbgPrint | |
9220 | + ("Novfs_i_rename: nd=0x%p nd->inode=0x%p nd->inode->i_ino=%d %s\n", | |
9221 | + nd, nd->d_inode, nd->d_inode->i_ino, | |
9222 | + newpath); | |
9223 | + } else { | |
9224 | + DbgPrint | |
9225 | + ("Novfs_i_rename: nd=0x%p nd->inode=0x%p %s\n", | |
9226 | + nd, nd->d_inode, newpath); | |
9227 | + } | |
9228 | + | |
9229 | + /* | |
9230 | + * Check to see if two different servers or different volumes | |
9231 | + */ | |
9232 | + newcon = strchr(newpath + 1, '\\'); | |
9233 | + oldcon = strchr(oldpath + 1, '\\'); | |
9234 | + DbgPrint("Novfs_i_rename: newcon=0x%p newpath=0x%p\n", | |
9235 | + newcon, newpath); | |
9236 | + DbgPrint("Novfs_i_rename: oldcon=0x%p oldpath=0x%p\n", | |
9237 | + oldcon, oldpath); | |
9238 | + retCode = -EXDEV; | |
9239 | + if (newcon && oldcon | |
9240 | + && ((int)(newcon - newpath) == | |
9241 | + (int)(oldcon - oldpath))) { | |
9242 | + newcon = strchr(newcon + 1, '\\'); | |
9243 | + oldcon = strchr(oldcon + 1, '\\'); | |
9244 | + DbgPrint("Novfs_i_rename2: newcon=0x%p newpath=0x%p\n", newcon, newpath); | |
9245 | + DbgPrint("Novfs_i_rename2: oldcon=0x%p oldpath=0x%p\n", oldcon, oldpath); | |
9246 | + if (newcon && oldcon && | |
9247 | + ((int)(newcon - newpath) == (int)(oldcon - oldpath))) { | |
9248 | + newname.name = newpath; | |
9249 | + newname.len = (int)(newcon - newpath); | |
9250 | + newname.hash = 0; | |
9251 | + | |
9252 | + oldname.name = oldpath; | |
9253 | + oldname.len = (int)(oldcon - oldpath); | |
9254 | + oldname.hash = 0; | |
9255 | + if (!Novfs_d_strcmp(&newname, &oldname)) { | |
9256 | + | |
9257 | + if (od->d_inode | |
9258 | + && od->d_inode->FSPRIVATE) { | |
9259 | + | |
9260 | + if ((nd->d_inode) && | |
9261 | + (nd->d_inode->FSPRIVATE)) { | |
9262 | + session = Scope_Get_SessionId(((struct inode_data *)ndir->FSPRIVATE)->Scope); | |
9263 | + if (0 == SC_PRESENT(session)) { | |
9264 | + ((struct inode_data *)ndir->FSPRIVATE)->Scope = Scope_Get_ScopefromPath(nd); | |
9265 | + session = Scope_Get_SessionId(((struct inode_data *)ndir->FSPRIVATE)->Scope); | |
9266 | + } | |
9267 | + | |
9268 | + retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session); | |
9269 | + } | |
9270 | + | |
9271 | + session = Scope_Get_SessionId(((struct inode_data *) ndir->FSPRIVATE)->Scope); | |
9272 | + if (0 == SC_PRESENT(session)) { | |
9273 | + ((struct inode_data *)ndir->FSPRIVATE)->Scope = Scope_Get_ScopefromPath(nd); | |
9274 | + session = Scope_Get_SessionId(((struct inode_data *) ndir->FSPRIVATE)->Scope); | |
9275 | + } | |
9276 | + retCode = Novfs_Rename_File(S_ISDIR(od->d_inode->i_mode), oldpath, oldlen - 1, newpath, newlen - 1, session); | |
9277 | + | |
9278 | + if (!retCode) { | |
9279 | + info = (struct entry_info *) oldbuf; | |
9280 | + od->d_time = 0; | |
9281 | + Novfs_remove_inode_entry(odir, &od->d_name, 0); | |
9282 | + Novfs_remove_inode_entry(ndir, &nd->d_name, 0); | |
9283 | + Novfs_Get_File_Info(newpath, info, &session); | |
9284 | + nd->d_time = jiffies + (File_update_timeout * HZ); | |
9285 | + | |
9286 | + if (od->d_inode && od->d_inode->i_ino) { | |
9287 | + ino = od->d_inode-> i_ino; | |
9288 | + } else { | |
9289 | + ino = (ino_t)atomic_inc_return(&Novfs_Inode_Number); | |
9290 | + } | |
9291 | + Novfs_add_inode_entry(ndir, &nd->d_name, ino, info); | |
9292 | + } | |
9293 | + } | |
9294 | + } | |
9295 | + } | |
9296 | + } | |
9297 | + } | |
9298 | + } | |
9299 | + | |
9300 | + if (oldbuf) | |
9301 | + kfree(oldbuf); | |
9302 | + | |
9303 | + DbgPrint("Novfs_i_rename: return %d\n", retCode); | |
9304 | + return (retCode); | |
9305 | +} | |
9306 | + | |
9307 | +/*++======================================================================*/ | |
9308 | +int Novfs_i_permission(struct inode *inode, int mask) | |
9309 | +/* | |
9310 | + * Arguments: | |
9311 | + * | |
9312 | + * Returns: | |
9313 | + * | |
9314 | + * Abstract: | |
9315 | + * | |
9316 | + * Notes: | |
9317 | + * | |
9318 | + * Environment: | |
9319 | + * | |
9320 | + *========================================================================*/ | |
9321 | +{ | |
9322 | + int retCode = 0; | |
9323 | + | |
9324 | + return (retCode); | |
9325 | +} | |
9326 | + | |
9327 | +/*++======================================================================*/ | |
9328 | +int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr) | |
9329 | +/* | |
9330 | + * Arguments: | |
9331 | + * | |
9332 | + * Returns: | |
9333 | + * | |
9334 | + * Abstract: | |
9335 | + * | |
9336 | + * Notes: | |
9337 | + * | |
9338 | + * Environment: | |
9339 | + * | |
9340 | + *========================================================================*/ | |
9341 | +{ | |
9342 | + char *path, *buf; | |
9343 | + struct inode *inode = dentry->d_inode; | |
9344 | + char atime_buf[32]; | |
9345 | + char mtime_buf[32]; | |
9346 | + char ctime_buf[32]; | |
9347 | + unsigned int ia_valid = attr->ia_valid; | |
9348 | + session_t session; | |
9349 | + int retVal = 0; | |
9350 | + struct iattr mattr; | |
9351 | + | |
9352 | + if (IS_ROOT(dentry) || /* Root */ | |
9353 | + IS_ROOT(dentry->d_parent) || /* User */ | |
9354 | + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ | |
9355 | + IS_ROOT(dentry->d_parent->d_parent->d_parent)) { /* Volume */ | |
9356 | + return (-EACCES); | |
9357 | + } | |
9358 | + | |
9359 | + if (inode && inode->FSPRIVATE) { | |
9360 | + session = | |
9361 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
9362 | + if (0 == SC_PRESENT(session)) { | |
9363 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = | |
9364 | + Scope_Get_ScopefromPath(dentry); | |
9365 | + session = | |
9366 | + Scope_Get_SessionId(((struct inode_data *) inode-> | |
9367 | + FSPRIVATE)->Scope); | |
9368 | + } | |
9369 | + | |
9370 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
9371 | + if (buf) { | |
9372 | + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); | |
9373 | + if (path) { | |
9374 | + strcpy(atime_buf, "Unspecified"); | |
9375 | + strcpy(mtime_buf, "Unspecified"); | |
9376 | + strcpy(ctime_buf, "Unspecified"); | |
9377 | + if (attr->ia_valid & ATTR_ATIME) { | |
9378 | + ctime_r(&attr->ia_atime.tv_sec, | |
9379 | + atime_buf); | |
9380 | + } | |
9381 | + if (attr->ia_valid & ATTR_MTIME) { | |
9382 | + ctime_r(&attr->ia_mtime.tv_sec, | |
9383 | + mtime_buf); | |
9384 | + } | |
9385 | + if (attr->ia_valid & ATTR_CTIME) { | |
9386 | + ctime_r(&attr->ia_ctime.tv_sec, | |
9387 | + ctime_buf); | |
9388 | + } | |
9389 | + /* Removed for Bug 132374. jlt */ | |
9390 | + DbgPrint("Novfs_i_setattr: %s\n" | |
9391 | + " ia_valid: 0x%x\n" | |
9392 | + " ia_mode: 0%o\n" | |
9393 | + " ia_uid: %d\n" | |
9394 | + " ia_gid: %d\n" | |
9395 | + " ia_size: %lld\n" | |
9396 | + " ia_atime: %s\n" | |
9397 | + " ia_mtime: %s\n" | |
9398 | + " ia_ctime: %s\n", | |
9399 | + path, | |
9400 | + attr->ia_valid, | |
9401 | + attr->ia_mode, | |
9402 | + attr->ia_uid, | |
9403 | + attr->ia_gid, | |
9404 | + attr->ia_size, | |
9405 | + atime_buf, mtime_buf, ctime_buf); | |
9406 | + | |
9407 | + if ((attr->ia_valid & ATTR_FILE) | |
9408 | + && (attr->ia_valid & ATTR_SIZE)) { | |
9409 | + memcpy(&mattr, attr, sizeof(mattr)); | |
9410 | + mattr.ia_valid &= | |
9411 | + ~(ATTR_FILE | ATTR_SIZE); | |
9412 | + attr = &mattr; | |
9413 | + ia_valid = attr->ia_valid; | |
9414 | +#if 0 // thanks to vfs changes in our tree... | |
9415 | + retVal = Novfs_Truncate_File_Ex(attr->ia_file->private_data, attr->ia_size, session); | |
9416 | + if (!retVal) { | |
9417 | + inode->i_size = attr->ia_size; | |
9418 | + ((struct inode_data *)inode->FSPRIVATE)->Flags |= UPDATE_INODE; | |
9419 | + } | |
9420 | +#endif | |
9421 | + } | |
9422 | + | |
9423 | + if (ia_valid | |
9424 | + && !(retVal = | |
9425 | + Novfs_Set_Attr(path, attr, session))) { | |
9426 | + ((struct inode_data *)inode->FSPRIVATE)->Flags |= UPDATE_INODE; | |
9427 | + | |
9428 | + if (ia_valid & ATTR_ATIME) | |
9429 | + inode->i_atime = attr->ia_atime; | |
9430 | + if (ia_valid & ATTR_MTIME) | |
9431 | + inode->i_mtime = attr->ia_mtime; | |
9432 | + if (ia_valid & ATTR_CTIME) | |
9433 | + inode->i_ctime = attr->ia_ctime; | |
9434 | + if (ia_valid & ATTR_MODE) { | |
9435 | + inode->i_mode = | |
9436 | + attr-> | |
9437 | + ia_mode & (S_IFMT | | |
9438 | + S_IRWXU); | |
9439 | + } | |
9440 | + } | |
9441 | + } | |
9442 | + } | |
9443 | + kfree(buf); | |
9444 | + } | |
9445 | + DbgPrint("Novfs_i_setattr: return 0x%x\n", retVal); | |
9446 | + | |
9447 | + return (retVal); | |
9448 | +} | |
9449 | + | |
9450 | +/*++======================================================================*/ | |
9451 | +int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, | |
9452 | + struct kstat *kstat) | |
9453 | +/* | |
9454 | + * Arguments: | |
9455 | + * | |
9456 | + * Returns: | |
9457 | + * | |
9458 | + * Abstract: | |
9459 | + * | |
9460 | + * Notes: | |
9461 | + * | |
9462 | + * Environment: | |
9463 | + * | |
9464 | + *========================================================================*/ | |
9465 | +{ | |
9466 | + int retCode = 0; | |
9467 | + char atime_buf[32]; | |
9468 | + char mtime_buf[32]; | |
9469 | + char ctime_buf[32]; | |
9470 | + struct inode *inode = dentry->d_inode; | |
9471 | + | |
9472 | + struct entry_info info; | |
9473 | + char *path, *buf; | |
9474 | + session_t session; | |
9475 | + struct inode_data *id; | |
9476 | + | |
9477 | + if (!IS_ROOT(dentry) && !IS_ROOT(dentry->d_parent)) { | |
9478 | + SC_INITIALIZE(session); | |
9479 | + id = dentry->d_inode->FSPRIVATE; | |
9480 | + | |
9481 | + if (id && (id->Flags & UPDATE_INODE)) { | |
9482 | + session = Scope_Get_SessionId(id->Scope); | |
9483 | + | |
9484 | + if (0 == SC_PRESENT(session)) { | |
9485 | + id->Scope = Scope_Get_ScopefromPath(dentry); | |
9486 | + session = Scope_Get_SessionId(id->Scope); | |
9487 | + } | |
9488 | + | |
9489 | + buf = | |
9490 | + (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, | |
9491 | + GFP_KERNEL); | |
9492 | + if (buf) { | |
9493 | + path = | |
9494 | + Novfs_dget_path(dentry, buf, | |
9495 | + PATH_LENGTH_BUFFER); | |
9496 | + if (path) { | |
9497 | + retCode = Novfs_Get_File_Info(path, &info, &session); | |
9498 | + if (!retCode) { | |
9499 | + update_inode(inode, &info); | |
9500 | + id->Flags &= ~UPDATE_INODE; | |
9501 | + } | |
9502 | + } | |
9503 | + kfree(buf); | |
9504 | + } | |
9505 | + } | |
9506 | + } | |
9507 | + | |
9508 | + kstat->ino = inode->i_ino; | |
9509 | + kstat->dev = inode->i_sb->s_dev; | |
9510 | + kstat->mode = inode->i_mode; | |
9511 | + kstat->nlink = inode->i_nlink; | |
9512 | + kstat->uid = inode->i_uid; | |
9513 | + kstat->gid = inode->i_gid; | |
9514 | + kstat->rdev = inode->i_rdev; | |
9515 | + kstat->size = i_size_read(inode); | |
9516 | + kstat->atime = inode->i_atime; | |
9517 | + kstat->mtime = inode->i_mtime; | |
9518 | + kstat->ctime = inode->i_ctime; | |
9519 | + kstat->blksize = inode->i_sb->s_blocksize; | |
9520 | + kstat->blocks = inode->i_blocks; | |
9521 | + if (inode->i_bytes) { | |
9522 | + kstat->blocks++; | |
9523 | + } | |
9524 | + ctime_r(&kstat->atime.tv_sec, atime_buf); | |
9525 | + ctime_r(&kstat->mtime.tv_sec, mtime_buf); | |
9526 | + ctime_r(&kstat->ctime.tv_sec, ctime_buf); | |
9527 | + | |
9528 | + DbgPrint("Novfs_i_getattr: 0x%x 0x%p <%.*s>\n" | |
9529 | + " ino: %d\n" | |
9530 | + " dev: 0x%x\n" | |
9531 | + " mode: 0%o\n" | |
9532 | + " nlink: 0x%x\n" | |
9533 | + " uid: 0x%x\n" | |
9534 | + " gid: 0x%x\n" | |
9535 | + " rdev: 0x%x\n" | |
9536 | + " size: 0x%llx\n" | |
9537 | + " atime: %s\n" | |
9538 | + " mtime: %s\n" | |
9539 | + " ctime: %s\n" | |
9540 | + " blksize: 0x%x\n" | |
9541 | + " blocks: 0x%x\n", | |
9542 | + retCode, dentry, dentry->d_name.len, dentry->d_name.name, | |
9543 | + kstat->ino, | |
9544 | + kstat->dev, | |
9545 | + kstat->mode, | |
9546 | + kstat->nlink, | |
9547 | + kstat->uid, | |
9548 | + kstat->gid, | |
9549 | + kstat->rdev, | |
9550 | + kstat->size, | |
9551 | + atime_buf, | |
9552 | + mtime_buf, ctime_buf, kstat->blksize, kstat->blocks); | |
9553 | + return (retCode); | |
9554 | +} | |
9555 | + | |
9556 | +/*++======================================================================*/ | |
9557 | +int Novfs_i_getxattr(struct dentry *dentry, const char *name, void *buffer, | |
9558 | + size_t buffer_size) | |
9559 | +/* | |
9560 | + * Arguments: | |
9561 | + * | |
9562 | + * Returns: | |
9563 | + * | |
9564 | + * Abstract: | |
9565 | + * | |
9566 | + * Notes: | |
9567 | + * | |
9568 | + * Environment: | |
9569 | + * | |
9570 | + *========================================================================*/ | |
9571 | +{ | |
9572 | + struct inode *inode = dentry->d_inode; | |
9573 | + session_t sessionId; | |
9574 | + char *path, *buf, *bufRead; | |
9575 | + ssize_t dataLen; | |
9576 | + | |
9577 | + int retxcode = 0; | |
9578 | + | |
9579 | + SC_INITIALIZE(sessionId); | |
9580 | + | |
9581 | + DbgPrint("Novfs_i_getxattr: Ian\n"); /*%.*s\n", dentry->d_name.len, dentry->d_name.name); */ | |
9582 | + DbgPrint | |
9583 | + ("Novfs_i_getxattr: dentry->d_name.len %u, dentry->d_name.name %s\n", | |
9584 | + dentry->d_name.len, dentry->d_name.name); | |
9585 | + DbgPrint("Novfs_i_getxattr: name %s\n", name); | |
9586 | + DbgPrint("Novfs_i_getxattr: size %u\n", buffer_size); | |
9587 | + | |
9588 | + if (inode && inode->FSPRIVATE) { | |
9589 | + sessionId = | |
9590 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
9591 | + DbgPrint("Novfs_i_getxattr: SessionId = %u\n", sessionId); | |
9592 | + //if (0 == sessionId) | |
9593 | + if (0 == SC_PRESENT(sessionId)) { | |
9594 | + ((struct inode_data *) inode->FSPRIVATE)->Scope = Scope_Get_ScopefromPath(dentry); | |
9595 | + sessionId = Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
9596 | + DbgPrint("Novfs_i_getxattr: SessionId = %u\n", | |
9597 | + sessionId); | |
9598 | + } | |
9599 | + } | |
9600 | + | |
9601 | + dataLen = 0; | |
9602 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
9603 | + if (buf) { | |
9604 | + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); | |
9605 | + if (path) { | |
9606 | + bufRead = (char *)Novfs_Malloc(XA_BUFFER, GFP_KERNEL); | |
9607 | + if (bufRead) { | |
9608 | + retxcode = Novfs_GetX_File_Info(path, name, bufRead, XA_BUFFER, &dataLen, &sessionId); | |
9609 | + DbgPrint("Novfs_i_getxattr: after Novfs_GetX_File_Info retxcode = %d\n", retxcode); | |
9610 | + if (!retxcode) { | |
9611 | + mydump(64, bufRead); | |
9612 | + if (buffer_size != 0) { | |
9613 | + if (buffer_size >= dataLen) { | |
9614 | + memcpy(buffer, bufRead, | |
9615 | + dataLen); | |
9616 | + } else { | |
9617 | + DbgPrint | |
9618 | + ("Novfs_i_getxattr: (!!!) not enough buffer_size. buffer_size = %d, dataLen = %d\n", | |
9619 | + buffer_size, | |
9620 | + dataLen); | |
9621 | + retxcode = -ERANGE; | |
9622 | + } | |
9623 | + } | |
9624 | + | |
9625 | + if (bufRead) { | |
9626 | + kfree(bufRead); | |
9627 | + } | |
9628 | + } | |
9629 | + } | |
9630 | + } | |
9631 | + kfree(buf); | |
9632 | + } | |
9633 | + | |
9634 | + if (retxcode) { | |
9635 | + dataLen = retxcode; | |
9636 | + } else { | |
9637 | + if ((buffer_size > 0) && (buffer_size < dataLen)) { | |
9638 | + dataLen = -ERANGE; | |
9639 | + } | |
9640 | + } | |
9641 | + | |
9642 | + return (dataLen); | |
9643 | +} | |
9644 | + | |
9645 | +/*++======================================================================*/ | |
9646 | +int Novfs_i_setxattr(struct dentry *dentry, const char *name, const void *value, | |
9647 | + size_t value_size, int flags) | |
9648 | +/* | |
9649 | + * Arguments: | |
9650 | + * | |
9651 | + * Returns: | |
9652 | + * | |
9653 | + * Abstract: | |
9654 | + * | |
9655 | + * Notes: | |
9656 | + * | |
9657 | + * Environment: | |
9658 | + * | |
9659 | + *========================================================================*/ | |
9660 | +{ | |
9661 | + | |
9662 | + struct inode *inode = dentry->d_inode; | |
9663 | + session_t sessionId; | |
9664 | + char *path, *buf; | |
9665 | + unsigned long bytesWritten = 0; | |
9666 | + int retError = 0; | |
9667 | + int retxcode = 0; | |
9668 | + | |
9669 | + SC_INITIALIZE(sessionId); | |
9670 | + | |
9671 | + DbgPrint("Novfs_i_setxattr: Ian\n"); /*%.*s\n", dentry->d_name.len, dentry->d_name.name); */ | |
9672 | + DbgPrint | |
9673 | + ("Novfs_i_setxattr: dentry->d_name.len %u, dentry->d_name.name %s\n", | |
9674 | + dentry->d_name.len, dentry->d_name.name); | |
9675 | + DbgPrint("Novfs_i_setxattr: name %s\n", name); | |
9676 | + DbgPrint("Novfs_i_setxattr: value_size %u\n", value_size); | |
9677 | + DbgPrint("Novfs_i_setxattr: flags %d\n", flags); | |
9678 | + | |
9679 | + if (inode && inode->FSPRIVATE) { | |
9680 | + sessionId = | |
9681 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)-> | |
9682 | + Scope); | |
9683 | + DbgPrint("Novfs_i_setxattr: SessionId = %u\n", sessionId); | |
9684 | + //if (0 == sessionId) | |
9685 | + if (0 == SC_PRESENT(sessionId)) { | |
9686 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = | |
9687 | + Scope_Get_ScopefromPath(dentry); | |
9688 | + sessionId = | |
9689 | + Scope_Get_SessionId(((struct inode_data *)inode-> | |
9690 | + FSPRIVATE)->Scope); | |
9691 | + DbgPrint("Novfs_i_setxattr: SessionId = %u\n", | |
9692 | + sessionId); | |
9693 | + } | |
9694 | + } | |
9695 | + | |
9696 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
9697 | + if (buf) { | |
9698 | + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); | |
9699 | + if (path) { | |
9700 | + retxcode = | |
9701 | + Novfs_SetX_File_Info(path, name, value, value_size, | |
9702 | + &bytesWritten, flags, | |
9703 | + &sessionId); | |
9704 | + if (!retxcode) { | |
9705 | + DbgPrint | |
9706 | + ("Novfs_i_setxattr: bytesWritten = %u\n", | |
9707 | + bytesWritten); | |
9708 | + } | |
9709 | + } | |
9710 | + kfree(buf); | |
9711 | + } | |
9712 | + | |
9713 | + if (retxcode) { | |
9714 | + retError = retxcode; | |
9715 | + } | |
9716 | + | |
9717 | + if (bytesWritten < value_size) { | |
9718 | + retError = retxcode; | |
9719 | + } | |
9720 | + return (retError); | |
9721 | +} | |
9722 | + | |
9723 | +int Novfs_i_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |
9724 | +{ | |
9725 | + struct inode *inode = dentry->d_inode; | |
9726 | + session_t sessionId; | |
9727 | + char *path, *buf, *bufList; | |
9728 | + ssize_t dataLen; | |
9729 | + | |
9730 | + int retxcode = 0; | |
9731 | + | |
9732 | + SC_INITIALIZE(sessionId); | |
9733 | + | |
9734 | + DbgPrint("Novfs_i_listxattr: Ian\n"); //%.*s\n", dentry->d_name.len, dentry->d_name.name); | |
9735 | + DbgPrint | |
9736 | + ("Novfs_i_listxattr: dentry->d_name.len %u, dentry->d_name.name %s\n", | |
9737 | + dentry->d_name.len, dentry->d_name.name); | |
9738 | + DbgPrint("Novfs_i_listxattr: size %u\n", buffer_size); | |
9739 | + | |
9740 | + if (inode && inode->FSPRIVATE) { | |
9741 | + sessionId = | |
9742 | + Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)-> Scope); | |
9743 | + DbgPrint("Novfs_i_listxattr: SessionId = %u\n", sessionId); | |
9744 | + //if (0 == sessionId) | |
9745 | + if (0 == SC_PRESENT(sessionId)) { | |
9746 | + ((struct inode_data *)inode->FSPRIVATE)->Scope = Scope_Get_ScopefromPath(dentry); | |
9747 | + sessionId = Scope_Get_SessionId(((struct inode_data *)inode->FSPRIVATE)->Scope); | |
9748 | + DbgPrint("Novfs_i_listxattr: SessionId = %u\n", | |
9749 | + sessionId); | |
9750 | + } | |
9751 | + } | |
9752 | + | |
9753 | + dataLen = 0; | |
9754 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
9755 | + if (buf) { | |
9756 | + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); | |
9757 | + if (path) { | |
9758 | + bufList = (char *)Novfs_Malloc(XA_BUFFER, GFP_KERNEL); | |
9759 | + if (bufList) { | |
9760 | + retxcode = Novfs_ListX_File_Info(path, bufList, XA_BUFFER, &dataLen, &sessionId); | |
9761 | + | |
9762 | + mydump(64, bufList); | |
9763 | + if (buffer_size != 0) { | |
9764 | + if (buffer_size >= dataLen) { | |
9765 | + memcpy(buffer, bufList, | |
9766 | + dataLen); | |
9767 | + } else { | |
9768 | + DbgPrint | |
9769 | + ("Novfs_i_listxattr: (!!!) not enough buffer_size. buffer_size = %d, dataLen = %d\n", | |
9770 | + buffer_size, dataLen); | |
9771 | + retxcode = -1; | |
9772 | + } | |
9773 | + } | |
9774 | + | |
9775 | + if (bufList) { | |
9776 | + kfree(bufList); | |
9777 | + } | |
9778 | + } | |
9779 | + | |
9780 | + } | |
9781 | + kfree(buf); | |
9782 | + } | |
9783 | + | |
9784 | + if (retxcode) { | |
9785 | + dataLen = -1; | |
9786 | + } else { | |
9787 | + | |
9788 | + if ((buffer_size > 0) && (buffer_size < dataLen)) { | |
9789 | + dataLen = -ERANGE; | |
9790 | + } | |
9791 | + } | |
9792 | + return (dataLen); | |
9793 | +} | |
9794 | + | |
9795 | +int Novfs_i_revalidate(struct dentry *dentry) | |
9796 | +{ | |
9797 | + | |
9798 | + DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, | |
9799 | + dentry->d_name.name); | |
9800 | + | |
9801 | + return (0); | |
9802 | +} | |
9803 | + | |
9804 | +void Novfs_read_inode(struct inode *inode) | |
9805 | +{ | |
9806 | + DbgPrint("Novfs_read_inode: 0x%p %d\n", inode, inode->i_ino); | |
9807 | +} | |
9808 | + | |
9809 | +void Novfs_write_inode(struct inode *inode) | |
9810 | +{ | |
9811 | + DbgPrint("Novfs_write_inode: Inode=0x%p Ino=%d\n", inode, inode->i_ino); | |
9812 | +} | |
9813 | + | |
9814 | +int Novfs_notify_change(struct dentry *dentry, struct iattr *attr) | |
9815 | +{ | |
9816 | + struct inode *inode = dentry->d_inode; | |
9817 | + | |
9818 | + DbgPrint | |
9819 | + ("Novfs_notify_change: Dentry=0x%p Name=%.*s Inode=0x%p Ino=%d ia_valid=0x%x\n", | |
9820 | + dentry, dentry->d_name.len, dentry->d_name.name, inode, | |
9821 | + inode->i_ino, attr->ia_valid); | |
9822 | + return (0); | |
9823 | +} | |
9824 | + | |
9825 | +/*++======================================================================*/ | |
9826 | +void Novfs_clear_inode(struct inode *inode) | |
9827 | +/* | |
9828 | + * Arguments: sb - pointer to the super_block | |
9829 | + * buf - pointer to the statfs buffer | |
9830 | + * | |
9831 | + * Returns: 0 | |
9832 | + * | |
9833 | + * Abstract: Called when statfs(2) system called. | |
9834 | + * | |
9835 | + * Notes: | |
9836 | + * | |
9837 | + * Environment: Superblock operation | |
9838 | + * | |
9839 | + *========================================================================*/ | |
9840 | +{ | |
9841 | + InodeCount--; | |
9842 | + | |
9843 | + if (inode->FSPRIVATE) { | |
9844 | + struct inode_data *id = inode->FSPRIVATE; | |
9845 | + | |
9846 | + DbgPrint | |
9847 | + ("Novfs_clear_inode: inode=0x%p ino=%d Scope=0x%p Name=%s\n", | |
9848 | + inode, inode->i_ino, id->Scope, id->Name); | |
9849 | + | |
9850 | + Novfs_free_inode_cache(inode); | |
9851 | + | |
9852 | + down(&InodeList_lock); | |
9853 | + list_del(&id->IList); | |
9854 | + up(&InodeList_lock); | |
9855 | + | |
9856 | + kfree(inode->FSPRIVATE); | |
9857 | + inode->FSPRIVATE = NULL; | |
9858 | + | |
9859 | + remove_inode_hash(inode); | |
9860 | + | |
9861 | + } else { | |
9862 | + DbgPrint("Novfs_clear_inode: inode=0x%p ino=%d\n", inode, | |
9863 | + inode->i_ino); | |
9864 | + } | |
9865 | +} | |
9866 | + | |
9867 | +/*++======================================================================*/ | |
9868 | +int Novfs_show_options(struct seq_file *s, struct vfsmount *m) | |
9869 | +/* | |
9870 | + * Arguments: | |
9871 | + * | |
9872 | + * Returns: 0 | |
9873 | + * | |
9874 | + * Abstract: Called when /proc/mounts is read | |
9875 | + * | |
9876 | + * Notes: | |
9877 | + * | |
9878 | + * Environment: | |
9879 | + * | |
9880 | + *========================================================================*/ | |
9881 | +{ | |
9882 | + char *buf, *path, *tmp; | |
9883 | + | |
9884 | + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
9885 | + if (buf) { | |
9886 | + struct path my_path; | |
9887 | + my_path.mnt = m; | |
9888 | + my_path.dentry = m->mnt_root; | |
9889 | + path = d_path(&my_path, buf, PATH_LENGTH_BUFFER); | |
9890 | + if (path) { | |
9891 | + if (!Novfs_CurrentMount | |
9892 | + || (Novfs_CurrentMount | |
9893 | + && strcmp(Novfs_CurrentMount, path))) { | |
9894 | + DbgPrint("Novfs_show_options: %.*s %.*s %s\n", | |
9895 | + m->mnt_root->d_name.len, | |
9896 | + m->mnt_root->d_name.name, | |
9897 | + m->mnt_mountpoint->d_name.len, | |
9898 | + m->mnt_mountpoint->d_name.name, path); | |
9899 | + tmp = | |
9900 | + (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - | |
9901 | + (int)(path - buf), | |
9902 | + GFP_KERNEL); | |
9903 | + if (tmp) { | |
9904 | + strcpy(tmp, path); | |
9905 | + path = Novfs_CurrentMount; | |
9906 | + Novfs_CurrentMount = tmp; | |
9907 | + Daemon_SetMountPoint | |
9908 | + (Novfs_CurrentMount); | |
9909 | + | |
9910 | + if (path) { | |
9911 | + kfree(path); | |
9912 | + } | |
9913 | + } | |
9914 | + } | |
9915 | + } | |
9916 | + kfree(buf); | |
9917 | + } | |
9918 | + return (0); | |
9919 | +} | |
9920 | + | |
9921 | +/*++======================================================================*/ | |
9922 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
9923 | +int Novfs_statfs(struct dentry *de, struct kstatfs *buf) | |
9924 | +#else | |
9925 | +int Novfs_statfs(struct super_block *sb, struct kstatfs *buf) | |
9926 | +#endif | |
9927 | +/* | |
9928 | + * Arguments: sb - pointer to the super_block | |
9929 | + * buf - pointer to the statfs buffer | |
9930 | + * | |
9931 | + * Returns: 0 | |
9932 | + * | |
9933 | + * Abstract: Called when statfs(2) system called. | |
9934 | + * | |
9935 | + * Notes: | |
9936 | + * | |
9937 | + * Environment: Superblock operation | |
9938 | + * | |
9939 | + *========================================================================*/ | |
9940 | +{ | |
9941 | + uint64_t td, fd, te, fe; | |
9942 | + | |
9943 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
9944 | + struct super_block *sb = de->d_sb; | |
9945 | +#endif | |
9946 | + | |
9947 | + DbgPrint("Novfs_statfs:\n"); | |
9948 | + | |
9949 | + td = fd = te = fe = 0; | |
9950 | + | |
9951 | + Scope_Get_UserSpace(&td, &fd, &te, &fe); | |
9952 | + | |
9953 | + DbgPrint("td=%llu\n", td); | |
9954 | + DbgPrint("fd=%llu\n", fd); | |
9955 | + DbgPrint("te=%llu\n", te); | |
9956 | + DbgPrint("fe=%llu\n", fd); | |
9957 | + | |
9958 | + buf->f_type = sb->s_magic; | |
9959 | + buf->f_bsize = sb->s_blocksize; | |
9960 | + buf->f_namelen = NW_MAX_PATH_LENGTH; | |
9961 | + buf->f_blocks = | |
9962 | + (sector_t) (td + | |
9963 | + (uint64_t) (sb->s_blocksize - | |
9964 | + 1)) >> (uint64_t) sb->s_blocksize_bits; | |
9965 | + buf->f_bfree = (sector_t) fd >> (uint64_t) sb->s_blocksize_bits; | |
9966 | + buf->f_bavail = (sector_t) buf->f_bfree; | |
9967 | + buf->f_files = (sector_t) te; | |
9968 | + buf->f_ffree = (sector_t) fe; | |
9969 | + buf->f_frsize = sb->s_blocksize; | |
9970 | + if (te > 0xffffffff) | |
9971 | + buf->f_files = 0xffffffff; | |
9972 | + | |
9973 | + if (fe > 0xffffffff) | |
9974 | + buf->f_ffree = 0xffffffff; | |
9975 | + | |
9976 | + DbgPrint("f_type: 0x%x\n", buf->f_type); | |
9977 | + DbgPrint("f_bsize: %u\n", buf->f_bsize); | |
9978 | + DbgPrint("f_namelen: %d\n", buf->f_namelen); | |
9979 | + DbgPrint("f_blocks: %llu\n", buf->f_blocks); | |
9980 | + DbgPrint("f_bfree: %llu\n", buf->f_bfree); | |
9981 | + DbgPrint("f_bavail: %llu\n", buf->f_bavail); | |
9982 | + DbgPrint("f_files: %llu\n", buf->f_files); | |
9983 | + DbgPrint("f_ffree: %llu\n", buf->f_ffree); | |
9984 | + DbgPrint("f_frsize: %u\n", buf->f_frsize); | |
9985 | + | |
9986 | + return 0; | |
9987 | +} | |
9988 | + | |
9989 | +struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, | |
9990 | + uid_t Uid, ino_t ino, struct qstr *name) | |
9991 | +{ | |
9992 | + struct inode *inode = new_inode(sb); | |
9993 | + | |
9994 | + if (inode) { | |
9995 | + InodeCount++; | |
9996 | + inode->i_mode = mode; | |
9997 | + inode->i_uid = Uid; | |
9998 | + inode->i_gid = 0; | |
9999 | + /* bug # 340510 tells us to comment this out... */ | |
10000 | +//#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | |
10001 | +// inode->i_blksize = sb->s_blocksize; | |
10002 | +//#else | |
10003 | +// inode->i_sb->s_blocksize = sb->s_blocksize; | |
10004 | +//#endif | |
10005 | + inode->i_blkbits = sb->s_blocksize_bits; | |
10006 | + inode->i_blocks = 0; | |
10007 | + inode->i_rdev = 0; | |
10008 | + inode->i_ino = (ino) ? ino : (ino_t)atomic_inc_return(&Novfs_Inode_Number); | |
10009 | + if (PageCache) { | |
10010 | + inode->i_mapping->a_ops = &Novfs_aops; | |
10011 | + } else { | |
10012 | + inode->i_mapping->a_ops = &Novfs_nocache_aops; | |
10013 | + } | |
10014 | + inode->i_mapping->backing_dev_info = &Novfs_backing_dev_info; | |
10015 | + inode->i_atime.tv_sec = 0; | |
10016 | + inode->i_atime.tv_nsec = 0; | |
10017 | + inode->i_mtime = inode->i_ctime = inode->i_atime; | |
10018 | + | |
10019 | + DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, | |
10020 | + inode->i_ino, name->len); | |
10021 | + | |
10022 | + if (NULL != | |
10023 | + (inode->FSPRIVATE = | |
10024 | + Novfs_Malloc(sizeof(struct inode_data) + name->len, | |
10025 | + GFP_KERNEL))) { | |
10026 | + struct inode_data *id; | |
10027 | + id = inode->FSPRIVATE; | |
10028 | + | |
10029 | + DbgPrint("Novfs_get_inode: FSPRIVATE 0x%p\n", id); | |
10030 | + | |
10031 | + id->Scope = NULL; | |
10032 | + id->Flags = 0; | |
10033 | + id->Inode = inode; | |
10034 | + | |
10035 | + id->cntDC = 1; | |
10036 | + | |
10037 | + INIT_LIST_HEAD(&id->DirCache); | |
10038 | + init_MUTEX(&id->DirCacheLock); | |
10039 | + | |
10040 | + id->FileHandle = 0; | |
10041 | + id->CacheFlag = 0; | |
10042 | + | |
10043 | + down(&InodeList_lock); | |
10044 | + | |
10045 | + list_add_tail(&id->IList, &InodeList); | |
10046 | + up(&InodeList_lock); | |
10047 | + | |
10048 | + id->Name[0] = '\0'; | |
10049 | + | |
10050 | + memcpy(id->Name, name->name, name->len); | |
10051 | + id->Name[name->len] = '\0'; | |
10052 | + | |
10053 | + DbgPrint("Novfs_get_inode: name %s\n", id->Name); | |
10054 | + } | |
10055 | + | |
10056 | + insert_inode_hash(inode); | |
10057 | + | |
10058 | + switch (mode & S_IFMT) { | |
10059 | + | |
10060 | + case S_IFREG: | |
10061 | + inode->i_op = &Novfs_file_inode_operations; | |
10062 | + inode->i_fop = &Novfs_file_operations; | |
10063 | + break; | |
10064 | + | |
10065 | + case S_IFDIR: | |
10066 | + inode->i_op = &Novfs_inode_operations; | |
10067 | + inode->i_fop = &Novfs_dir_operations; | |
10068 | +// Again bug #340510 | |
10069 | +//#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | |
10070 | +// inode->i_blksize = 0; | |
10071 | +//#else | |
10072 | +// inode->i_sb->s_blocksize = 0; | |
10073 | +//#endif | |
10074 | + inode->i_blkbits = 0; | |
10075 | + break; | |
10076 | + | |
10077 | + default: | |
10078 | + init_special_inode(inode, mode, dev); | |
10079 | + break; | |
10080 | + } | |
10081 | + | |
10082 | + DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size); | |
10083 | + DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode); | |
10084 | + DbgPrint("Novfs_get_inode: i_sb->s_blocksize=%d\n", | |
10085 | + inode->i_sb->s_blocksize); | |
10086 | + DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits); | |
10087 | + DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks); | |
10088 | + DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes); | |
10089 | + } | |
10090 | + | |
10091 | + DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino); | |
10092 | + return (inode); | |
10093 | +} | |
10094 | + | |
10095 | +int Novfs_fill_super(struct super_block *SB, void *Data, int Silent) | |
10096 | +{ | |
10097 | + struct inode *inode; | |
10098 | + struct dentry *server, *tree; | |
10099 | + struct qstr name; | |
10100 | + struct entry_info info; | |
10101 | + | |
10102 | + SB->s_blocksize = PAGE_CACHE_SIZE; | |
10103 | + SB->s_blocksize_bits = PAGE_CACHE_SHIFT; | |
10104 | + SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL; /* Max file size */ | |
10105 | + SB->s_op = &Novfs_ops; | |
10106 | + SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL); | |
10107 | + SB->s_magic = NOVFS_MAGIC; | |
10108 | + | |
10109 | + name.len = 1; | |
10110 | + name.name = "/"; | |
10111 | + | |
10112 | + inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); | |
10113 | + if (!inode) { | |
10114 | + return (-ENOMEM); | |
10115 | + } | |
10116 | + | |
10117 | + Novfs_root = d_alloc_root(inode); | |
10118 | + | |
10119 | + if (!Novfs_root) { | |
10120 | + iput(inode); | |
10121 | + return (-ENOMEM); | |
10122 | + } | |
10123 | + Novfs_root->d_time = jiffies + (File_update_timeout * HZ); | |
10124 | + | |
10125 | + inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME; | |
10126 | + | |
10127 | + SB->s_root = Novfs_root; | |
10128 | + | |
10129 | + DbgPrint("Novfs_fill_super: root 0x%p\n", Novfs_root); | |
10130 | + | |
10131 | + if (Novfs_root) { | |
10132 | + Novfs_root->d_op = &Novfs_dentry_operations; | |
10133 | + | |
10134 | + name.name = SERVER_DIRECTORY_NAME; | |
10135 | + name.len = strlen(SERVER_DIRECTORY_NAME); | |
10136 | + name.hash = Novfs_internal_hash(&name); | |
10137 | + | |
10138 | + inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); | |
10139 | + if (inode) { | |
10140 | + info.mode = inode->i_mode; | |
10141 | + info.namelength = 0; | |
10142 | + inode->i_size = info.size = 0; | |
10143 | + inode->i_uid = info.uid = 0; | |
10144 | + inode->i_gid = info.gid = 0; | |
10145 | + inode->i_atime = info.atime = | |
10146 | + inode->i_ctime = info.ctime = | |
10147 | + inode->i_mtime = info.mtime = CURRENT_TIME; | |
10148 | + | |
10149 | + server = d_alloc(Novfs_root, &name); | |
10150 | + if (server) { | |
10151 | + server->d_op = &Novfs_dentry_operations; | |
10152 | + server->d_time = 0xffffffff; | |
10153 | + d_add(server, inode); | |
10154 | + DbgPrint("Novfs_fill_super: d_add %s 0x%p\n", | |
10155 | + SERVER_DIRECTORY_NAME, server); | |
10156 | + Novfs_add_inode_entry(Novfs_root->d_inode, | |
10157 | + &name, inode->i_ino, | |
10158 | + &info); | |
10159 | + } | |
10160 | + } | |
10161 | + | |
10162 | + name.name = TREE_DIRECTORY_NAME; | |
10163 | + name.len = strlen(TREE_DIRECTORY_NAME); | |
10164 | + name.hash = Novfs_internal_hash(&name); | |
10165 | + | |
10166 | + inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); | |
10167 | + if (inode) { | |
10168 | + info.mode = inode->i_mode; | |
10169 | + info.namelength = 0; | |
10170 | + inode->i_size = info.size = 0; | |
10171 | + inode->i_uid = info.uid = 0; | |
10172 | + inode->i_gid = info.gid = 0; | |
10173 | + inode->i_atime = info.atime = | |
10174 | + inode->i_ctime = info.ctime = | |
10175 | + inode->i_mtime = info.mtime = CURRENT_TIME; | |
10176 | + tree = d_alloc(Novfs_root, &name); | |
10177 | + if (tree) { | |
10178 | + tree->d_op = &Novfs_dentry_operations; | |
10179 | + tree->d_time = 0xffffffff; | |
10180 | + | |
10181 | + d_add(tree, inode); | |
10182 | + DbgPrint("Novfs_fill_super: d_add %s 0x%p\n", | |
10183 | + TREE_DIRECTORY_NAME, tree); | |
10184 | + Novfs_add_inode_entry(Novfs_root->d_inode, | |
10185 | + &name, inode->i_ino, | |
10186 | + &info); | |
10187 | + } | |
10188 | + } | |
10189 | + } | |
10190 | + | |
10191 | + return (0); | |
10192 | +} | |
10193 | + | |
10194 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
10195 | +int Novfs_get_sb(struct file_system_type *Fstype, int Flags, | |
10196 | + const char *Dev_name, void *Data, struct vfsmount *Mnt) | |
10197 | +#else | |
10198 | +struct super_block *Novfs_get_sb(struct file_system_type *Fstype, int Flags, | |
10199 | + const char *Dev_name, void *Data) | |
10200 | +#endif | |
10201 | +{ | |
10202 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
10203 | + int sb; | |
10204 | +#else | |
10205 | + struct super_block *sb; | |
10206 | +#endif | |
10207 | + | |
10208 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) | |
10209 | + sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super, Mnt); | |
10210 | +#else | |
10211 | + sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super); | |
10212 | +#endif | |
10213 | + | |
10214 | + DbgPrint("Novfs_get_sb: sb=0x%p Fstype=0x%x Dev_name=%s\n", sb, Fstype, | |
10215 | + Dev_name); | |
10216 | + | |
10217 | + return (sb); | |
10218 | +} | |
10219 | + | |
10220 | +static void novfs_kill_sb(struct super_block *super) | |
10221 | +{ | |
10222 | + /* calling shrink_dcache_sb() fixes novell bugzilla #345179, but I'm | |
10223 | + * not so sure about it... */ | |
10224 | + shrink_dcache_sb(super); | |
10225 | + kill_litter_super(super); | |
10226 | +} | |
10227 | + | |
10228 | +ssize_t Novfs_Control_read(struct file *file, char *buf, size_t nbytes, | |
10229 | + loff_t * ppos) | |
10230 | +{ | |
10231 | + ssize_t retval = 0; | |
10232 | + | |
10233 | + DbgPrint("Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked()); | |
10234 | + | |
10235 | + return retval; | |
10236 | +} | |
10237 | + | |
10238 | +ssize_t Novfs_Control_write(struct file * file, const char *buf, size_t nbytes, | |
10239 | + loff_t * ppos) | |
10240 | +{ | |
10241 | + ssize_t retval = 0; | |
10242 | + | |
10243 | + DbgPrint("Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked()); | |
10244 | + if (buf && nbytes) { | |
10245 | + } | |
10246 | + | |
10247 | + return (retval); | |
10248 | +} | |
10249 | + | |
10250 | +int Novfs_Control_ioctl(struct inode *inode, struct file *file, | |
10251 | + unsigned int cmd, unsigned long arg) | |
10252 | +{ | |
10253 | + int retval = 0; | |
10254 | + | |
10255 | + DbgPrint("Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked()); | |
10256 | + | |
10257 | + return (retval); | |
10258 | +} | |
10259 | + | |
10260 | +static struct file_system_type Novfs_fs_type = { | |
10261 | + .name = "novfs", | |
10262 | + .get_sb = Novfs_get_sb, | |
10263 | + .kill_sb = novfs_kill_sb, | |
10264 | + .owner = THIS_MODULE, | |
10265 | +}; | |
10266 | + | |
10267 | +int __init init_novfs(void) | |
10268 | +{ | |
10269 | + int retCode; | |
10270 | + | |
10271 | + lastDir[0] = 0; | |
10272 | + lastTime = get_nanosecond_time(); | |
10273 | + | |
10274 | + inHAX = 0; | |
10275 | + inHAXTime = get_nanosecond_time(); | |
10276 | + | |
10277 | + retCode = Init_Procfs_Interface(); | |
10278 | + | |
10279 | + init_profile(); | |
10280 | + | |
10281 | + if (!retCode) { | |
10282 | + DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, | |
10283 | + NOVFS_VERSION_STRING); | |
10284 | + Init_Daemon_Queue(); | |
10285 | + Scope_Init(); | |
10286 | + retCode = register_filesystem(&Novfs_fs_type); | |
10287 | + if (retCode) { | |
10288 | + Uninit_Procfs_Interface(); | |
10289 | + Uninit_Daemon_Queue(); | |
10290 | + Scope_Uninit(); | |
10291 | + } | |
10292 | + } | |
10293 | + return (retCode); | |
10294 | +} | |
10295 | + | |
10296 | +void __exit exit_novfs(void) | |
10297 | +{ | |
10298 | + printk(KERN_INFO "exit_novfs\n"); | |
10299 | + | |
10300 | + Scope_Uninit(); | |
10301 | + printk(KERN_INFO "exit_novfs after Scope_Uninit\n"); | |
10302 | + | |
10303 | + Uninit_Daemon_Queue(); | |
10304 | + printk(KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n"); | |
10305 | + | |
10306 | + uninit_profile(); | |
10307 | + printk(KERN_INFO "exit_novfs after uninit_profile\n"); | |
10308 | + | |
10309 | + Uninit_Procfs_Interface(); | |
10310 | + printk(KERN_INFO "exit_novfs Uninit_Procfs_Interface\n"); | |
10311 | + | |
10312 | + unregister_filesystem(&Novfs_fs_type); | |
10313 | + printk(KERN_INFO "exit_novfs: Exit\n"); | |
10314 | + | |
10315 | + if (Novfs_CurrentMount) { | |
10316 | + kfree(Novfs_CurrentMount); | |
10317 | + Novfs_CurrentMount = NULL; | |
10318 | + } | |
10319 | +} | |
10320 | + | |
10321 | +int Novfs_lock_inode_cache(struct inode *i) | |
10322 | +/* | |
10323 | + * | |
10324 | + * Arguments: struct inode *i - pointer to directory inode | |
10325 | + * | |
10326 | + * Returns: 0 - locked | |
10327 | + * -1 - not locked | |
10328 | + * | |
10329 | + * Abstract: Locks the inode cache. | |
10330 | + * | |
10331 | + * Notes: | |
10332 | + * | |
10333 | + * Environment: | |
10334 | + * | |
10335 | + *========================================================================*/ | |
10336 | +{ | |
10337 | + struct inode_data *id; | |
10338 | + int retVal = 0; | |
10339 | + | |
10340 | + DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i); | |
10341 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10342 | + down(&id->DirCacheLock); | |
10343 | + retVal = 1; | |
10344 | + } | |
10345 | + DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal); | |
10346 | + return (retVal); | |
10347 | +} | |
10348 | + | |
10349 | +/*++======================================================================*/ | |
10350 | +void Novfs_unlock_inode_cache(struct inode *i) | |
10351 | +/* | |
10352 | + * Arguments: struct inode *i - pointer to directory inode | |
10353 | + * | |
10354 | + * Returns: nothing | |
10355 | + * | |
10356 | + * Abstract: Unlocks inode cache. | |
10357 | + * | |
10358 | + * Notes: | |
10359 | + * | |
10360 | + * Environment: | |
10361 | + * | |
10362 | + *========================================================================*/ | |
10363 | +{ | |
10364 | + struct inode_data *id; | |
10365 | + | |
10366 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10367 | + up(&id->DirCacheLock); | |
10368 | + } | |
10369 | +} | |
10370 | + | |
10371 | +/*++======================================================================*/ | |
10372 | +int Novfs_enumerate_inode_cache(struct inode *i, struct list_head **iteration, | |
10373 | + ino_t * ino, struct entry_info *info) | |
10374 | +/* | |
10375 | + * Arguments: struct inode *i - pointer to directory inode | |
10376 | + * | |
10377 | + * Returns: 0 - item found | |
10378 | + * -1 - done | |
10379 | + * | |
10380 | + * Abstract: Unlocks inode cache. | |
10381 | + * | |
10382 | + * Notes: DirCacheLock should be held before calling this routine. | |
10383 | + * | |
10384 | + * Environment: | |
10385 | + * | |
10386 | + *========================================================================*/ | |
10387 | +{ | |
10388 | + struct inode_data *id; | |
10389 | + struct dir_cache *dc; | |
10390 | + struct list_head *l = NULL; | |
10391 | + int retVal = -1; | |
10392 | + | |
10393 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10394 | + if ((NULL == iteration) || (NULL == *iteration)) { | |
10395 | + l = id->DirCache.next; | |
10396 | + } else { | |
10397 | + l = *iteration; | |
10398 | + } | |
10399 | + | |
10400 | + if (l == &id->DirCache) { | |
10401 | + l = NULL; | |
10402 | + } else { | |
10403 | + dc = list_entry(l, struct dir_cache, list); | |
10404 | + | |
10405 | + *ino = dc->ino; | |
10406 | + info->type = 0; | |
10407 | + info->mode = dc->mode; | |
10408 | + info->size = dc->size; | |
10409 | + info->atime = dc->atime; | |
10410 | + info->mtime = dc->mtime; | |
10411 | + info->ctime = dc->ctime; | |
10412 | + info->namelength = dc->nameLen; | |
10413 | + memcpy(info->name, dc->name, dc->nameLen); | |
10414 | + info->name[dc->nameLen] = '\0'; | |
10415 | + retVal = 0; | |
10416 | + | |
10417 | + l = l->next; | |
10418 | + } | |
10419 | + } | |
10420 | + *iteration = l; | |
10421 | + return (retVal); | |
10422 | +} | |
10423 | + | |
10424 | +/*++======================================================================*/ | |
10425 | +int Novfs_get_entry(struct inode *i, struct qstr *name, ino_t * ino, | |
10426 | + struct entry_info *info) | |
10427 | +/* | |
10428 | + * Arguments: | |
10429 | + * | |
10430 | + * Returns: | |
10431 | + * | |
10432 | + * Abstract: | |
10433 | + * | |
10434 | + * Notes: DirCacheLock should be held before calling this routine. | |
10435 | + * | |
10436 | + * Environment: | |
10437 | + * | |
10438 | + *========================================================================*/ | |
10439 | +{ | |
10440 | + struct inode_data *id; | |
10441 | + struct dir_cache *dc; | |
10442 | + int retVal = -1; | |
10443 | + char *n = "<NULL>"; | |
10444 | + int nl = 6; | |
10445 | + | |
10446 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10447 | + if (name && name->len) { | |
10448 | + n = (char *)name->name; | |
10449 | + nl = name->len; | |
10450 | + } | |
10451 | + | |
10452 | + dc = Novfs_lookup_inode_cache(i, name, *ino); | |
10453 | + if (dc) { | |
10454 | + dc->flags |= ENTRY_VALID; | |
10455 | + retVal = 0; | |
10456 | + *ino = dc->ino; | |
10457 | + info->type = 0; | |
10458 | + info->mode = dc->mode; | |
10459 | + info->size = dc->size; | |
10460 | + info->atime = dc->atime; | |
10461 | + info->mtime = dc->mtime; | |
10462 | + info->ctime = dc->ctime; | |
10463 | + info->namelength = dc->nameLen; | |
10464 | + memcpy(info->name, dc->name, dc->nameLen); | |
10465 | + info->name[dc->nameLen] = '\0'; | |
10466 | + retVal = 0; | |
10467 | + } | |
10468 | + | |
10469 | + DbgPrint("Novfs_get_entry:\n" | |
10470 | + " inode: 0x%p\n" | |
10471 | + " name: %.*s\n" " ino: %d\n", i, nl, n, *ino); | |
10472 | + } | |
10473 | + DbgPrint("Novfs_get_entry: return %d\n", retVal); | |
10474 | + return (retVal); | |
10475 | +} | |
10476 | + | |
10477 | +int Novfs_get_entry_by_pos(struct inode *i, loff_t pos, ino_t * ino, | |
10478 | + struct entry_info *info) | |
10479 | +/* | |
10480 | + * Arguments: | |
10481 | + * | |
10482 | + * Returns: | |
10483 | + * | |
10484 | + * Abstract: | |
10485 | + * | |
10486 | + * Notes: DirCacheLock should be held before calling this routine. | |
10487 | + * | |
10488 | + * Environment: | |
10489 | + * | |
10490 | + *========================================================================*/ | |
10491 | +{ | |
10492 | + int retVal = -1; | |
10493 | + loff_t count = 0; | |
10494 | + loff_t i_pos = pos - 2; | |
10495 | + struct list_head *inter = NULL; | |
10496 | + while (!Novfs_enumerate_inode_cache(i, &inter, ino, info)) { | |
10497 | + DbgPrint | |
10498 | + ("Novfs_dir_readdir : Novfs_get_entry_by_pos : info->name = %s\n", | |
10499 | + info->name); | |
10500 | + if (count == i_pos) { | |
10501 | + retVal = 0; | |
10502 | + break; | |
10503 | + } else | |
10504 | + count++; | |
10505 | + } | |
10506 | + | |
10507 | + return retVal; | |
10508 | +} | |
10509 | + | |
10510 | +/*++======================================================================*/ | |
10511 | +int Novfs_get_entry_time(struct inode *i, struct qstr *name, ino_t * ino, | |
10512 | + struct entry_info *info, u64 * EntryTime) | |
10513 | +/* | |
10514 | + * Arguments: | |
10515 | + * | |
10516 | + * Returns: | |
10517 | + * | |
10518 | + * Abstract: | |
10519 | + * | |
10520 | + * Notes: DirCacheLock should be held before calling this routine. | |
10521 | + * | |
10522 | + * Environment: | |
10523 | + * | |
10524 | + *========================================================================*/ | |
10525 | +{ | |
10526 | + struct inode_data *id; | |
10527 | + struct dir_cache *dc; | |
10528 | + int retVal = -1; | |
10529 | + char *n = "<NULL>"; | |
10530 | + int nl = 6; | |
10531 | + | |
10532 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10533 | + if (name && name->len) { | |
10534 | + n = (char *)name->name; | |
10535 | + nl = name->len; | |
10536 | + } | |
10537 | + DbgPrint("Novfs_get_entry_time:\n" | |
10538 | + " inode: 0x%p\n" | |
10539 | + " name: %.*s\n" " ino: %d\n", i, nl, n, *ino); | |
10540 | + | |
10541 | + dc = Novfs_lookup_inode_cache(i, name, *ino); | |
10542 | + if (dc) { | |
10543 | + retVal = 0; | |
10544 | + *ino = dc->ino; | |
10545 | + info->type = 0; | |
10546 | + info->mode = dc->mode; | |
10547 | + info->size = dc->size; | |
10548 | + info->atime = dc->atime; | |
10549 | + info->mtime = dc->mtime; | |
10550 | + info->ctime = dc->ctime; | |
10551 | + info->namelength = dc->nameLen; | |
10552 | + memcpy(info->name, dc->name, dc->nameLen); | |
10553 | + info->name[dc->nameLen] = '\0'; | |
10554 | + if (EntryTime) { | |
10555 | + *EntryTime = dc->jiffies; | |
10556 | + } | |
10557 | + retVal = 0; | |
10558 | + } | |
10559 | + } | |
10560 | + DbgPrint("Novfs_get_entry_time: return %d\n", retVal); | |
10561 | + return (retVal); | |
10562 | +} | |
10563 | + | |
10564 | +/*++======================================================================*/ | |
10565 | +int Novfs_get_remove_entry(struct inode *i, ino_t * ino, struct entry_info *info) | |
10566 | +/* | |
10567 | + * Arguments: | |
10568 | + * | |
10569 | + * Returns: | |
10570 | + * | |
10571 | + * Abstract: This routine will return the first entry on the list | |
10572 | + * and then remove it. | |
10573 | + * | |
10574 | + * Notes: DirCacheLock should be held before calling this routine. | |
10575 | + * | |
10576 | + * Environment: | |
10577 | + * | |
10578 | + *========================================================================*/ | |
10579 | +{ | |
10580 | + struct inode_data *id; | |
10581 | + struct dir_cache *dc; | |
10582 | + struct list_head *l = NULL; | |
10583 | + int retVal = -1; | |
10584 | + | |
10585 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10586 | + l = id->DirCache.next; | |
10587 | + | |
10588 | + if (l != &id->DirCache) { | |
10589 | + dc = list_entry(l, struct dir_cache, list); | |
10590 | + | |
10591 | + *ino = dc->ino; | |
10592 | + info->type = 0; | |
10593 | + info->mode = dc->mode; | |
10594 | + info->size = dc->size; | |
10595 | + info->atime = dc->atime; | |
10596 | + info->mtime = dc->mtime; | |
10597 | + info->ctime = dc->ctime; | |
10598 | + info->namelength = dc->nameLen; | |
10599 | + memcpy(info->name, dc->name, dc->nameLen); | |
10600 | + info->name[dc->nameLen] = '\0'; | |
10601 | + retVal = 0; | |
10602 | + | |
10603 | + list_del(&dc->list); | |
10604 | + kfree(dc); | |
10605 | + DCCount--; | |
10606 | + | |
10607 | + id->cntDC--; | |
10608 | + } | |
10609 | + } | |
10610 | + return (retVal); | |
10611 | +} | |
10612 | + | |
10613 | +/*++======================================================================*/ | |
10614 | +void Novfs_invalidate_inode_cache(struct inode *i) | |
10615 | +/* | |
10616 | + * Arguments: struct inode *i - pointer to directory inode | |
10617 | + * | |
10618 | + * Returns: nothing | |
10619 | + * | |
10620 | + * Abstract: Marks all entries in the directory cache as invalid. | |
10621 | + * | |
10622 | + * Notes: DirCacheLock should be held before calling this routine. | |
10623 | + * | |
10624 | + * Environment: | |
10625 | + * | |
10626 | + *========================================================================*/ | |
10627 | +{ | |
10628 | + struct inode_data *id; | |
10629 | + struct dir_cache *dc; | |
10630 | + struct list_head *l; | |
10631 | + | |
10632 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10633 | + list_for_each(l, &id->DirCache) { | |
10634 | + dc = list_entry(l, struct dir_cache, list); | |
10635 | + dc->flags &= ~ENTRY_VALID; | |
10636 | + } | |
10637 | + } | |
10638 | +} | |
10639 | + | |
10640 | +/*++======================================================================*/ | |
10641 | +static struct dir_cache *Novfs_lookup_inode_cache(struct inode *i, struct qstr *name, ino_t ino) | |
10642 | +/* | |
10643 | + * Arguments: struct inode *i - pointer to directory inode | |
10644 | + * struct qstr *name - pointer to name | |
10645 | + * ino_t - inode number | |
10646 | + * | |
10647 | + * Returns: struct dir_cache entry if match | |
10648 | + * NULL - if there is no match. | |
10649 | + * | |
10650 | + * Abstract: Checks a inode directory to see if there are any enties | |
10651 | + * matching name or ino. If name is specified then ino is | |
10652 | + * not used. ino is use if name is not specified. | |
10653 | + * | |
10654 | + * Notes: DirCacheLock should be held before calling this routine. | |
10655 | + * | |
10656 | + * Environment: | |
10657 | + * | |
10658 | + *========================================================================*/ | |
10659 | +{ | |
10660 | + struct inode_data *id; | |
10661 | + struct dir_cache *dc; | |
10662 | + struct dir_cache *retVal = NULL; | |
10663 | + struct list_head *l; | |
10664 | + char *n = "<NULL>"; | |
10665 | + int nl = 6; | |
10666 | + int hash = 0; | |
10667 | + | |
10668 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10669 | + if (name && name->name) { | |
10670 | + nl = name->len; | |
10671 | + n = (char *)name->name; | |
10672 | + hash = name->hash; | |
10673 | + } | |
10674 | + DbgPrint("Novfs_lookup_inode_cache:\n" | |
10675 | + " inode: 0x%p\n" | |
10676 | + " name: %.*s\n" | |
10677 | + " hash: 0x%x\n" | |
10678 | + " len: %d\n" | |
10679 | + " ino: %d\n", i, nl, n, hash, nl, ino); | |
10680 | + | |
10681 | + list_for_each(l, &id->DirCache) { | |
10682 | + dc = list_entry(l, struct dir_cache, list); | |
10683 | + if (name) { | |
10684 | + | |
10685 | +/* DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \ | |
10686 | + " ino: %d\n" \ | |
10687 | + " hash: 0x%x\n" \ | |
10688 | + " len: %d\n" \ | |
10689 | + " name: %.*s\n", | |
10690 | + dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name); | |
10691 | +*/ | |
10692 | + if ((name->hash == dc->hash) && | |
10693 | + (name->len == dc->nameLen) && | |
10694 | + (0 == | |
10695 | + memcmp(name->name, dc->name, name->len))) { | |
10696 | + retVal = dc; | |
10697 | + break; | |
10698 | + } | |
10699 | + } else { | |
10700 | + if (ino == dc->ino) { | |
10701 | + retVal = dc; | |
10702 | + break; | |
10703 | + } | |
10704 | + } | |
10705 | + } | |
10706 | + } | |
10707 | + | |
10708 | + DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal); | |
10709 | + return (retVal); | |
10710 | +} | |
10711 | + | |
10712 | +/*++======================================================================*/ | |
10713 | +int Novfs_lookup_validate(struct inode *i, struct qstr *name, ino_t ino) | |
10714 | +/* | |
10715 | + * Arguments: struct inode *i - pointer to directory inode | |
10716 | + * struct qstr *name - pointer to name | |
10717 | + * ino_t - inode number | |
10718 | + * | |
10719 | + * Returns: 0 if found | |
10720 | + * !0 if not found | |
10721 | + * | |
10722 | + * Abstract: Checks a inode directory to see if there are any enties | |
10723 | + * matching name or ino. If entry is found the valid bit | |
10724 | + * is set. | |
10725 | + * | |
10726 | + * Notes: DirCacheLock should be held before calling this routine. | |
10727 | + * | |
10728 | + * Environment: | |
10729 | + * | |
10730 | + *========================================================================*/ | |
10731 | +{ | |
10732 | + struct inode_data *id; | |
10733 | + struct dir_cache *dc; | |
10734 | + int retVal = -1; | |
10735 | + char *n = "<NULL>"; | |
10736 | + int nl = 6; | |
10737 | + | |
10738 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10739 | + if (name && name->len) { | |
10740 | + n = (char *)name->name; | |
10741 | + nl = name->len; | |
10742 | + } | |
10743 | + DbgPrint("Novfs_update_entry:\n" | |
10744 | + " inode: 0x%p\n" | |
10745 | + " name: %.*s\n" " ino: %d\n", i, nl, n, ino); | |
10746 | + | |
10747 | + dc = Novfs_lookup_inode_cache(i, name, ino); | |
10748 | + if (dc) { | |
10749 | + dc->flags |= ENTRY_VALID; | |
10750 | + retVal = 0; | |
10751 | + } | |
10752 | + } | |
10753 | + return (retVal); | |
10754 | +} | |
10755 | + | |
10756 | +/*++======================================================================*/ | |
10757 | +int Novfs_add_inode_entry(struct inode *i, | |
10758 | + struct qstr *name, ino_t ino, struct entry_info *info) | |
10759 | +/* | |
10760 | + * Arguments: | |
10761 | + * | |
10762 | + * Returns: -ENOMEM - alloc error. | |
10763 | + * 0 - success. | |
10764 | + * | |
10765 | + * Abstract: Added entry to directory cache. | |
10766 | + * | |
10767 | + * Notes: DirCacheLock should be held before calling this routine. | |
10768 | + * | |
10769 | + * Environment: | |
10770 | + * | |
10771 | + *========================================================================*/ | |
10772 | +{ | |
10773 | + struct inode_data *id; | |
10774 | + struct dir_cache *new; | |
10775 | + int retVal = -ENOMEM; | |
10776 | + struct dir_cache *todel; | |
10777 | + struct list_head *todeltmp; | |
10778 | + | |
10779 | + //SClark | |
10780 | + DbgPrint("Novfs_add_inode_entry:\n" " i: %u\n", i); | |
10781 | + if ((id = i->FSPRIVATE)) { | |
10782 | + DbgPrint(" i->FSPRIVATE: %p\n", id); | |
10783 | + if (id->DirCache.next) | |
10784 | + DbgPrint(" id->DirCache.next: %p\n", | |
10785 | + id->DirCache.next); | |
10786 | + } | |
10787 | + //SClark | |
10788 | + | |
10789 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10790 | + new = Novfs_Malloc(sizeof(struct dir_cache) + name->len, GFP_KERNEL); | |
10791 | + if (new) { | |
10792 | + id->cntDC++; | |
10793 | + | |
10794 | + DCCount++; | |
10795 | + DbgPrint("Novfs_add_inode_entry:\n" | |
10796 | + " inode: 0x%p\n" | |
10797 | + " id: 0x%p\n" | |
10798 | + " DC: 0x%p\n" | |
10799 | + " new: 0x%p\n" | |
10800 | + " name: %.*s\n" | |
10801 | + " ino: %d\n" | |
10802 | + " size: %lld\n" | |
10803 | + " mode: 0x%x\n", | |
10804 | + i, id, &id->DirCache, new, name->len, | |
10805 | + name->name, ino, info->size, info->mode); | |
10806 | + | |
10807 | + retVal = 0; | |
10808 | + new->flags = ENTRY_VALID; | |
10809 | + new->jiffies = get_jiffies_64(); | |
10810 | + new->size = info->size; | |
10811 | + new->mode = info->mode; | |
10812 | + new->atime = info->atime; | |
10813 | + new->mtime = info->mtime; | |
10814 | + new->ctime = info->ctime; | |
10815 | + new->ino = ino; | |
10816 | + new->hash = name->hash; | |
10817 | + new->nameLen = name->len; | |
10818 | + memcpy(new->name, name->name, name->len); | |
10819 | + new->name[new->nameLen] = '\0'; | |
10820 | + list_add(&new->list, &id->DirCache); | |
10821 | + | |
10822 | + if (id->cntDC > 20) { | |
10823 | + todeltmp = id->DirCache.prev; | |
10824 | + todel = list_entry(todeltmp, struct dir_cache, list); | |
10825 | + | |
10826 | + list_del(&todel->list); | |
10827 | + | |
10828 | + kfree(todel); | |
10829 | + | |
10830 | + DCCount--; | |
10831 | + id->cntDC--; | |
10832 | + } | |
10833 | + } | |
10834 | + } | |
10835 | + return (retVal); | |
10836 | +} | |
10837 | + | |
10838 | +/*++======================================================================*/ | |
10839 | +int Novfs_update_entry(struct inode *i, struct qstr *name, ino_t ino, | |
10840 | + struct entry_info *info) | |
10841 | +/* | |
10842 | + * Arguments: | |
10843 | + * | |
10844 | + * Returns: | |
10845 | + * | |
10846 | + * Abstract: | |
10847 | + * | |
10848 | + * Notes: DirCacheLock should be held before calling this routine. | |
10849 | + * | |
10850 | + * Environment: | |
10851 | + * | |
10852 | + *========================================================================*/ | |
10853 | +{ | |
10854 | + struct inode_data *id; | |
10855 | + struct dir_cache *dc; | |
10856 | + int retVal = -1; | |
10857 | + char *n = "<NULL>"; | |
10858 | + int nl = 6; | |
10859 | + char atime_buf[32]; | |
10860 | + char mtime_buf[32]; | |
10861 | + char ctime_buf[32]; | |
10862 | + | |
10863 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10864 | + | |
10865 | + if (name && name->len) { | |
10866 | + n = (char *)name->name; | |
10867 | + nl = name->len; | |
10868 | + } | |
10869 | + ctime_r(&info->atime.tv_sec, atime_buf); | |
10870 | + ctime_r(&info->mtime.tv_sec, mtime_buf); | |
10871 | + ctime_r(&info->ctime.tv_sec, ctime_buf); | |
10872 | + DbgPrint("Novfs_update_entry:\n" | |
10873 | + " inode: 0x%p\n" | |
10874 | + " name: %.*s\n" | |
10875 | + " ino: %d\n" | |
10876 | + " size: %lld\n" | |
10877 | + " atime: %s\n" | |
10878 | + " mtime: %s\n" | |
10879 | + " ctime: %s\n", | |
10880 | + i, nl, n, ino, info->size, atime_buf, mtime_buf, | |
10881 | + ctime_buf); | |
10882 | + | |
10883 | + dc = Novfs_lookup_inode_cache(i, name, ino); | |
10884 | + if (dc) { | |
10885 | + retVal = 0; | |
10886 | + dc->flags = ENTRY_VALID; | |
10887 | + dc->jiffies = get_jiffies_64(); | |
10888 | + dc->size = info->size; | |
10889 | + dc->mode = info->mode; | |
10890 | + dc->atime = info->atime; | |
10891 | + dc->mtime = info->mtime; | |
10892 | + dc->ctime = info->ctime; | |
10893 | + | |
10894 | + ctime_r(&dc->atime.tv_sec, atime_buf); | |
10895 | + ctime_r(&dc->mtime.tv_sec, mtime_buf); | |
10896 | + ctime_r(&dc->ctime.tv_sec, ctime_buf); | |
10897 | + DbgPrint("Novfs_update_entry entry: 0x%p\n" | |
10898 | + " flags: 0x%x\n" | |
10899 | + " jiffies: %lld\n" | |
10900 | + " ino: %d\n" | |
10901 | + " size: %lld\n" | |
10902 | + " mode: 0%o\n" | |
10903 | + " atime: %s\n" | |
10904 | + " mtime: %s %d\n" | |
10905 | + " ctime: %s\n" | |
10906 | + " hash: 0x%x\n" | |
10907 | + " nameLen: %d\n" | |
10908 | + " name: %s\n", | |
10909 | + dc, dc->flags, dc->jiffies, dc->ino, dc->size, | |
10910 | + dc->mode, atime_buf, mtime_buf, | |
10911 | + dc->mtime.tv_nsec, ctime_buf, dc->hash, | |
10912 | + dc->nameLen, dc->name); | |
10913 | + } | |
10914 | + } | |
10915 | + DbgPrint("Novfs_update_entry: return %d\n", retVal); | |
10916 | + return (retVal); | |
10917 | +} | |
10918 | + | |
10919 | +/*++======================================================================*/ | |
10920 | +void Novfs_remove_inode_entry(struct inode *i, struct qstr *name, ino_t ino) | |
10921 | +/* | |
10922 | + * Arguments: | |
10923 | + * | |
10924 | + * Returns: nothing | |
10925 | + * | |
10926 | + * Abstract: Removes entry from directory cache. You can specify a name | |
10927 | + * or an inode number. | |
10928 | + * | |
10929 | + * Notes: DirCacheLock should be held before calling this routine. | |
10930 | + * | |
10931 | + * Environment: | |
10932 | + * | |
10933 | + *========================================================================*/ | |
10934 | +{ | |
10935 | + struct inode_data *id; | |
10936 | + struct dir_cache *dc; | |
10937 | + char *n = "<NULL>"; | |
10938 | + int nl = 6; | |
10939 | + | |
10940 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10941 | + dc = Novfs_lookup_inode_cache(i, name, ino); | |
10942 | + if (dc) { | |
10943 | + if (name && name->name) { | |
10944 | + nl = name->len; | |
10945 | + n = (char *)name->name; | |
10946 | + } | |
10947 | + DbgPrint("Novfs_remove_inode_entry:\n" | |
10948 | + " inode: 0x%p\n" | |
10949 | + " id: 0x%p\n" | |
10950 | + " DC: 0x%p\n" | |
10951 | + " name: %.*s\n" | |
10952 | + " ino: %d\n" | |
10953 | + " entry: 0x%p\n" | |
10954 | + " name: %.*s\n" | |
10955 | + " ino: %d\n" | |
10956 | + " next: 0x%p\n" | |
10957 | + " prev: 0x%p\n", | |
10958 | + i, id, &id->DirCache, nl, n, ino, dc, | |
10959 | + dc->nameLen, dc->name, dc->ino, dc->list.next, | |
10960 | + dc->list.prev); | |
10961 | + list_del(&dc->list); | |
10962 | + kfree(dc); | |
10963 | + DCCount--; | |
10964 | + | |
10965 | + id->cntDC--; | |
10966 | + } | |
10967 | + } | |
10968 | +} | |
10969 | + | |
10970 | +/*++======================================================================*/ | |
10971 | +void Novfs_free_invalid_entries(struct inode *i) | |
10972 | +/* | |
10973 | + * Arguments: struct inode *i - pointer to directory inode. | |
10974 | + * | |
10975 | + * Returns: nothing | |
10976 | + * | |
10977 | + * Abstract: Frees all invalid entries in the directory cache. | |
10978 | + * | |
10979 | + * Notes: DirCacheLock should be held before calling this routine. | |
10980 | + * | |
10981 | + * Environment: | |
10982 | + * | |
10983 | + *========================================================================*/ | |
10984 | +{ | |
10985 | + struct inode_data *id; | |
10986 | + struct dir_cache *dc; | |
10987 | + struct list_head *l; | |
10988 | + | |
10989 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
10990 | + list_for_each(l, &id->DirCache) { | |
10991 | + dc = list_entry(l, struct dir_cache, list); | |
10992 | + if (0 == (dc->flags & ENTRY_VALID)) { | |
10993 | + DbgPrint("Novfs_free_invalid_entries:\n" | |
10994 | + " inode: 0x%p\n" | |
10995 | + " id: 0x%p\n" | |
10996 | + " entry: 0x%p\n" | |
10997 | + " name: %.*s\n" | |
10998 | + " ino: %d\n", | |
10999 | + i, id, dc, dc->nameLen, dc->name, | |
11000 | + dc->ino); | |
11001 | + l = l->prev; | |
11002 | + list_del(&dc->list); | |
11003 | + kfree(dc); | |
11004 | + DCCount--; | |
11005 | + | |
11006 | + id->cntDC--; | |
11007 | + } | |
11008 | + } | |
11009 | + } | |
11010 | +} | |
11011 | + | |
11012 | +/*++======================================================================*/ | |
11013 | +void Novfs_free_inode_cache(struct inode *i) | |
11014 | +/* | |
11015 | + * Arguments: struct inode *i - pointer to directory inode. | |
11016 | + * | |
11017 | + * Returns: nothing | |
11018 | + * | |
11019 | + * Abstract: Frees all entries in the inode cache. | |
11020 | + * | |
11021 | + * Notes: DirCacheLock should be held before calling this routine. | |
11022 | + * | |
11023 | + * Environment: | |
11024 | + * | |
11025 | + *========================================================================*/ | |
11026 | +{ | |
11027 | + struct inode_data *id; | |
11028 | + struct dir_cache *dc; | |
11029 | + struct list_head *l; | |
11030 | + | |
11031 | + if (i && (id = i->FSPRIVATE) && id->DirCache.next) { | |
11032 | + list_for_each(l, &id->DirCache) { | |
11033 | + dc = list_entry(l, struct dir_cache, list); | |
11034 | + l = l->prev; | |
11035 | + list_del(&dc->list); | |
11036 | + kfree(dc); | |
11037 | + DCCount--; | |
11038 | + | |
11039 | + id->cntDC--; | |
11040 | + } | |
11041 | + } | |
11042 | +} | |
11043 | + | |
11044 | +void Novfs_dump_inode(void *pf) | |
11045 | +{ | |
11046 | + struct inode *inode; | |
11047 | + void (*pfunc) (char *Fmt, ...) = pf; | |
11048 | + struct inode_data *id; | |
11049 | + struct dir_cache *dc; | |
11050 | + struct list_head *il, *l; | |
11051 | + char atime_buf[32]; | |
11052 | + char mtime_buf[32]; | |
11053 | + char ctime_buf[32]; | |
11054 | + unsigned long icnt = 0, dccnt = 0; | |
11055 | + | |
11056 | + down(&InodeList_lock); | |
11057 | + list_for_each(il, &InodeList) { | |
11058 | + id = list_entry(il, struct inode_data, IList); | |
11059 | + inode = id->Inode; | |
11060 | + if (inode) { | |
11061 | + icnt++; | |
11062 | + | |
11063 | + pfunc("Inode=0x%p I_ino=%d\n", inode, inode->i_ino); | |
11064 | + | |
11065 | + pfunc(" atime=%s\n", | |
11066 | + ctime_r(&inode->i_atime.tv_sec, atime_buf)); | |
11067 | + pfunc(" ctime=%s\n", | |
11068 | + ctime_r(&inode->i_mtime.tv_sec, atime_buf)); | |
11069 | + pfunc(" mtime=%s\n", | |
11070 | + ctime_r(&inode->i_ctime.tv_sec, atime_buf)); | |
11071 | + pfunc(" size=%lld\n", inode->i_size); | |
11072 | + pfunc(" mode=0%o\n", inode->i_mode); | |
11073 | + pfunc(" count=0%o\n", atomic_read(&inode->i_count)); | |
11074 | + } | |
11075 | + | |
11076 | + pfunc(" inode_data: 0x%p Name=%s Scope=0x%p\n", id, id->Name, | |
11077 | + id->Scope); | |
11078 | + | |
11079 | + if (id->DirCache.next) { | |
11080 | + list_for_each(l, &id->DirCache) { | |
11081 | + dccnt++; | |
11082 | + dc = list_entry(l, struct dir_cache, list); | |
11083 | + ctime_r(&dc->atime.tv_sec, atime_buf); | |
11084 | + ctime_r(&dc->mtime.tv_sec, mtime_buf); | |
11085 | + ctime_r(&dc->ctime.tv_sec, ctime_buf); | |
11086 | + | |
11087 | + pfunc(" Cache Entry: 0x%p\n" | |
11088 | + " flags: 0x%x\n" | |
11089 | + " jiffies: %llu\n" | |
11090 | + " ino: %u\n" | |
11091 | + " size: %llu\n" | |
11092 | + " mode: 0%o\n" | |
11093 | + " atime: %s\n" | |
11094 | + " mtime: %s\n" | |
11095 | + " ctime: %s\n" | |
11096 | + " hash: 0x%x\n" | |
11097 | + " len: %d\n" | |
11098 | + " name: %s\n", | |
11099 | + dc, dc->flags, dc->jiffies, | |
11100 | + dc->ino, dc->size, dc->mode, | |
11101 | + atime_buf, mtime_buf, ctime_buf, | |
11102 | + dc->hash, dc->nameLen, dc->name); | |
11103 | + } | |
11104 | + } | |
11105 | + } | |
11106 | + up(&InodeList_lock); | |
11107 | + | |
11108 | + pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, | |
11109 | + dccnt); | |
11110 | + | |
11111 | +} | |
11112 | + | |
11113 | +module_init(init_novfs); | |
11114 | +module_exit(exit_novfs); | |
11115 | + | |
11116 | +MODULE_LICENSE("GPL"); | |
11117 | +MODULE_AUTHOR("Novell Inc."); | |
11118 | +MODULE_DESCRIPTION("Novell NetWare Client for Linux"); | |
11119 | +MODULE_VERSION(NOVFS_VERSION_STRING); | |
11120 | --- /dev/null | |
11121 | +++ b/fs/novfs/nwcapi.c | |
11122 | @@ -0,0 +1,2537 @@ | |
11123 | +/* | |
11124 | + * Novell NCP Redirector for Linux | |
11125 | + * Author: James Turner/Richard Williams | |
11126 | + * | |
11127 | + * This file contains functions used to interface to the library interface of | |
11128 | + * the daemon. | |
11129 | + * | |
11130 | + * Copyright (C) 2005 Novell, Inc. | |
11131 | + * | |
11132 | + * This program is free software; you can redistribute it and/or | |
11133 | + * modify it under the terms of the GNU General Public License | |
11134 | + * as published by the Free Software Foundation; either version 2 | |
11135 | + * of the License, or (at your option) any later version. | |
11136 | + */ | |
11137 | + | |
11138 | +#include <linux/module.h> | |
11139 | +#include <linux/fs.h> | |
11140 | +#include <linux/slab.h> | |
11141 | +#include <linux/list.h> | |
11142 | +#include <linux/timer.h> | |
11143 | +#include <linux/poll.h> | |
11144 | +#include <linux/semaphore.h> | |
11145 | +#include <asm/uaccess.h> | |
11146 | + | |
11147 | +#include "nwcapi.h" | |
11148 | +#include "nwerror.h" | |
11149 | +#include "vfs.h" | |
11150 | +#include "commands.h" | |
11151 | + | |
11152 | +static void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply); | |
11153 | +static void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply); | |
11154 | + | |
11155 | + | |
11156 | +int NwOpenConnByName(PXPLAT pdata, HANDLE * Handle, session_t Session) | |
11157 | +{ | |
11158 | + PXPLAT_CALL_REQUEST cmd; | |
11159 | + PXPLAT_CALL_REPLY reply; | |
11160 | + PNwdCOpenConnByName openConn, connReply; | |
11161 | + NwcOpenConnByName ocbn; | |
11162 | + int retCode = 0; | |
11163 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11164 | + char *data; | |
11165 | + | |
11166 | + cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn)); | |
11167 | + datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType); | |
11168 | + cmdlen = datalen + sizeof(*cmd); | |
11169 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
11170 | + if (!cmd) | |
11171 | + return -ENOMEM; | |
11172 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11173 | + cmd->Command.SequenceNumber = 0; | |
11174 | + cmd->Command.SessionId = Session; | |
11175 | + cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME; | |
11176 | + | |
11177 | + cmd->dataLen = datalen; | |
11178 | + openConn = (PNwdCOpenConnByName) cmd->data; | |
11179 | + | |
11180 | + openConn->nameLen = strlen_user(ocbn.pName->pString); | |
11181 | + openConn->serviceLen = strlen_user(ocbn.pServiceType); | |
11182 | + openConn->uConnFlags = ocbn.uConnFlags; | |
11183 | + openConn->ConnHandle = Uint32toHandle(ocbn.ConnHandle); | |
11184 | + data = (char *)openConn; | |
11185 | + data += sizeof(*openConn); | |
11186 | + openConn->oName = sizeof(*openConn); | |
11187 | + | |
11188 | + openConn->oServiceType = openConn->oName + openConn->nameLen; | |
11189 | + cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen); | |
11190 | + data += openConn->nameLen; | |
11191 | + cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen); | |
11192 | + | |
11193 | + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11194 | + (void **)&reply, &replylen, | |
11195 | + INTERRUPTIBLE); | |
11196 | + if (reply) { | |
11197 | + /* | |
11198 | + * we got reply data from the daemon | |
11199 | + */ | |
11200 | + connReply = (PNwdCOpenConnByName) reply->data; | |
11201 | + retCode = reply->Reply.ErrorCode; | |
11202 | + if (!retCode) { | |
11203 | + /* | |
11204 | + * we got valid data. | |
11205 | + */ | |
11206 | + connReply = (PNwdCOpenConnByName) reply->data; | |
11207 | + ocbn.RetConnHandle = HandletoUint32(connReply->newConnHandle); | |
11208 | + *Handle = connReply->newConnHandle; | |
11209 | + | |
11210 | + cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn)); | |
11211 | + DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle); | |
11212 | + } | |
11213 | + kfree(reply); | |
11214 | + } | |
11215 | + | |
11216 | + kfree(cmd); | |
11217 | + | |
11218 | + return retCode; | |
11219 | + | |
11220 | +} | |
11221 | + | |
11222 | +int NwOpenConnByAddr(PXPLAT pdata, HANDLE * Handle, session_t Session) | |
11223 | +{ | |
11224 | + PXPLAT_CALL_REQUEST cmd; | |
11225 | + PXPLAT_CALL_REPLY reply; | |
11226 | + PNwdCOpenConnByAddr openConn, connReply; | |
11227 | + NwcOpenConnByAddr ocba; | |
11228 | + NwcTranAddr tranAddr; | |
11229 | + int retCode = 0; | |
11230 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11231 | + char addr[MAX_ADDRESS_LENGTH]; | |
11232 | + | |
11233 | + cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba)); | |
11234 | + datalen = sizeof(*openConn); | |
11235 | + cmdlen = datalen + sizeof(*cmd); | |
11236 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
11237 | + if (!cmd) | |
11238 | + return -ENOMEM; | |
11239 | + | |
11240 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11241 | + cmd->Command.SequenceNumber = 0; | |
11242 | + cmd->Command.SessionId = Session; | |
11243 | + cmd->NwcCommand = NWC_OPEN_CONN_BY_ADDRESS; | |
11244 | + cmd->dataLen = datalen; | |
11245 | + openConn = (PNwdCOpenConnByAddr) cmd->data; | |
11246 | + | |
11247 | + cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr)); | |
11248 | + | |
11249 | + DbgPrint("NwOpenConnByAddr: tranAddr\n"); | |
11250 | + mydump(sizeof(tranAddr), &tranAddr); | |
11251 | + | |
11252 | + openConn->TranAddr.uTransportType = tranAddr.uTransportType; | |
11253 | + openConn->TranAddr.uAddressLength = tranAddr.uAddressLength; | |
11254 | + memset(addr, 0xcc, sizeof(addr) - 1); | |
11255 | + | |
11256 | + cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength); | |
11257 | + | |
11258 | + DbgPrint("NwOpenConnByAddr: addr\n"); | |
11259 | + mydump(sizeof(addr), addr); | |
11260 | + | |
11261 | + openConn->TranAddr.oAddress = *(unsigned int*) (&addr[2]); | |
11262 | + | |
11263 | + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11264 | + (void **)&reply, &replylen, | |
11265 | + INTERRUPTIBLE); | |
11266 | + if (reply) { | |
11267 | + /* | |
11268 | + * we got reply data from the daemon | |
11269 | + */ | |
11270 | + connReply = (PNwdCOpenConnByAddr) reply->data; | |
11271 | + retCode = reply->Reply.ErrorCode; | |
11272 | + if (!retCode) { | |
11273 | + /* | |
11274 | + * we got valid data. | |
11275 | + */ | |
11276 | + connReply = (PNwdCOpenConnByAddr) reply->data; | |
11277 | + ocba.ConnHandle = HandletoUint32(connReply->ConnHandle); | |
11278 | + *Handle = connReply->ConnHandle; | |
11279 | + cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba)); | |
11280 | + DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle); | |
11281 | + } | |
11282 | + kfree(reply); | |
11283 | + } | |
11284 | + | |
11285 | + kfree(cmd); | |
11286 | + return retCode; | |
11287 | +} | |
11288 | + | |
11289 | +/*++======================================================================*/ | |
11290 | +int NwOpenConnByRef(PXPLAT pdata, HANDLE * Handle, session_t Session) | |
11291 | +/* | |
11292 | + * Arguments: | |
11293 | + * | |
11294 | + * Returns: | |
11295 | + * | |
11296 | + * Abstract: | |
11297 | + * | |
11298 | + * Notes: | |
11299 | + * | |
11300 | + * Environment: | |
11301 | + * | |
11302 | + *========================================================================*/ | |
11303 | +{ | |
11304 | + PXPLAT_CALL_REQUEST cmd; | |
11305 | + PXPLAT_CALL_REPLY reply; | |
11306 | + PNwdCOpenConnByRef openConn; | |
11307 | + NwcOpenConnByReference ocbr; | |
11308 | + int retCode = -ENOMEM; | |
11309 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11310 | + | |
11311 | + cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr)); | |
11312 | + datalen = sizeof(*openConn); | |
11313 | + cmdlen = datalen + sizeof(*cmd); | |
11314 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
11315 | + if (!cmd) | |
11316 | + return -ENOMEM; | |
11317 | + | |
11318 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11319 | + cmd->Command.SequenceNumber = 0; | |
11320 | + cmd->Command.SessionId = Session; | |
11321 | + cmd->NwcCommand = NWC_OPEN_CONN_BY_REFERENCE; | |
11322 | + cmd->dataLen = datalen; | |
11323 | + openConn = (PNwdCOpenConnByRef) cmd->data; | |
11324 | + | |
11325 | + openConn->uConnReference = (HANDLE) (unsigned long) ocbr.uConnReference; | |
11326 | + openConn->uConnFlags = ocbr.uConnFlags; | |
11327 | + | |
11328 | + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11329 | + (void **)&reply, &replylen, | |
11330 | + INTERRUPTIBLE); | |
11331 | + if (reply) { | |
11332 | + /* | |
11333 | + * we got reply data from the daemon | |
11334 | + */ | |
11335 | + openConn = (PNwdCOpenConnByRef) reply->data; | |
11336 | + retCode = reply->Reply.ErrorCode; | |
11337 | + if (!retCode) { | |
11338 | + /* | |
11339 | + * we got valid data. | |
11340 | + */ | |
11341 | + ocbr.ConnHandle = HandletoUint32(openConn->ConnHandle); | |
11342 | + *Handle = openConn->ConnHandle; | |
11343 | + | |
11344 | + cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr)); | |
11345 | + DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle); | |
11346 | + } | |
11347 | + kfree(reply); | |
11348 | + } | |
11349 | + | |
11350 | + kfree(cmd); | |
11351 | + return (retCode); | |
11352 | + | |
11353 | +} | |
11354 | + | |
11355 | +int NwRawSend(PXPLAT pdata, session_t Session) | |
11356 | +{ | |
11357 | + NwcRequest xRequest; | |
11358 | + PNwcFrag frag = NULL; | |
11359 | + PNwcFrag cFrag = NULL; | |
11360 | + PNwcFrag reqFrag = NULL; | |
11361 | + PXPLAT_CALL_REQUEST cmd; | |
11362 | + PXPLAT_CALL_REPLY reply; | |
11363 | + int retCode = -ENOMEM; | |
11364 | + unsigned long cmdlen, datalen, replylen, cpylen, totalLen; | |
11365 | + unsigned int x; | |
11366 | + PNwdCNCPReq ncpData; | |
11367 | + PNwdCNCPRep ncpReply; | |
11368 | + unsigned char *reqData; | |
11369 | + unsigned long actualReplyLength = 0; | |
11370 | + | |
11371 | + DbgPrint("[XPLAT] Process Raw NCP Send\n"); | |
11372 | + cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest)); | |
11373 | + | |
11374 | + /* | |
11375 | + * Figure out the length of the request | |
11376 | + */ | |
11377 | + frag = kmalloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL); | |
11378 | + DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags); | |
11379 | + | |
11380 | + if (!frag) | |
11381 | + goto exit; | |
11382 | + | |
11383 | + cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag)); | |
11384 | + totalLen = 0; | |
11385 | + | |
11386 | + cFrag = frag; | |
11387 | + for (x = 0; x < xRequest.uNumReplyFrags; x++) { | |
11388 | + DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength); | |
11389 | + totalLen += cFrag->uLength; | |
11390 | + cFrag++; | |
11391 | + } | |
11392 | + | |
11393 | + DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen); | |
11394 | + datalen = 0; | |
11395 | + reqFrag = kmalloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL); | |
11396 | + if (!reqFrag) | |
11397 | + goto exit; | |
11398 | + | |
11399 | + cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag)); | |
11400 | + cFrag = reqFrag; | |
11401 | + for (x = 0; x < xRequest.uNumRequestFrags; x++) { | |
11402 | + datalen += cFrag->uLength; | |
11403 | + cFrag++; | |
11404 | + } | |
11405 | + | |
11406 | + /* | |
11407 | + * Allocate the cmd Request | |
11408 | + */ | |
11409 | + cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData); | |
11410 | + DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags); | |
11411 | + DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen); | |
11412 | + | |
11413 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
11414 | + if (!cmd) | |
11415 | + goto exit; | |
11416 | + | |
11417 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11418 | + cmd->Command.SequenceNumber = 0; | |
11419 | + cmd->Command.SessionId = Session; | |
11420 | + cmd->NwcCommand = NWC_RAW_NCP_REQUEST; | |
11421 | + | |
11422 | + /* | |
11423 | + * build the NCP Request | |
11424 | + */ | |
11425 | + cmd->dataLen = cmdlen - sizeof(*cmd); | |
11426 | + ncpData = (PNwdCNCPReq) cmd->data; | |
11427 | + ncpData->replyLen = totalLen; | |
11428 | + ncpData->requestLen = datalen; | |
11429 | + ncpData->ConnHandle = (HANDLE) (unsigned long) xRequest.ConnHandle; | |
11430 | + ncpData->function = xRequest.uFunction; | |
11431 | + | |
11432 | + reqData = ncpData->data; | |
11433 | + cFrag = reqFrag; | |
11434 | + | |
11435 | + for (x = 0; x < xRequest.uNumRequestFrags; x++) { | |
11436 | + cpylen = | |
11437 | + copy_from_user(reqData, cFrag->pData, | |
11438 | + cFrag->uLength); | |
11439 | + reqData += cFrag->uLength; | |
11440 | + cFrag++; | |
11441 | + } | |
11442 | + | |
11443 | + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11444 | + (void **)&reply, &replylen, | |
11445 | + INTERRUPTIBLE); | |
11446 | + DbgPrint("RawNCP - reply = %x\n", reply); | |
11447 | + DbgPrint("RawNCP - retCode = %x\n", retCode); | |
11448 | + | |
11449 | + if (reply) { | |
11450 | + /* | |
11451 | + * we got reply data from the daemon | |
11452 | + */ | |
11453 | + ncpReply = (PNwdCNCPRep) reply->data; | |
11454 | + retCode = reply->Reply.ErrorCode; | |
11455 | + | |
11456 | + DbgPrint("RawNCP - Reply Frag Count 0x%X\n", | |
11457 | + xRequest.uNumReplyFrags); | |
11458 | + | |
11459 | + /* | |
11460 | + * We need to copy the reply frags to the packet. | |
11461 | + */ | |
11462 | + reqData = ncpReply->data; | |
11463 | + cFrag = frag; | |
11464 | + | |
11465 | + totalLen = ncpReply->replyLen; | |
11466 | + for (x = 0; x < xRequest.uNumReplyFrags; x++) { | |
11467 | + | |
11468 | + DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, | |
11469 | + cFrag->uLength); | |
11470 | + | |
11471 | + datalen = min((unsigned long)cFrag->uLength, totalLen); | |
11472 | + | |
11473 | + cpylen = copy_to_user(cFrag->pData, reqData, datalen); | |
11474 | + totalLen -= datalen; | |
11475 | + reqData += datalen; | |
11476 | + actualReplyLength += datalen; | |
11477 | + | |
11478 | + cFrag++; | |
11479 | + } | |
11480 | + | |
11481 | + kfree(reply); | |
11482 | + } else { | |
11483 | + retCode = -EIO; | |
11484 | + } | |
11485 | + | |
11486 | + kfree(cmd); | |
11487 | + | |
11488 | + xRequest.uActualReplyLength = actualReplyLength; | |
11489 | + cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest)); | |
11490 | + | |
11491 | +exit: | |
11492 | + kfree(reqFrag); | |
11493 | + kfree(frag); | |
11494 | + return retCode; | |
11495 | +} | |
11496 | + | |
11497 | +int NwConnClose(PXPLAT pdata, HANDLE * Handle, session_t Session) | |
11498 | +{ | |
11499 | + PXPLAT_CALL_REQUEST cmd; | |
11500 | + PXPLAT_CALL_REPLY reply; | |
11501 | + NwcCloseConn cc; | |
11502 | + PNwdCCloseConn nwdClose; | |
11503 | + int retCode = 0; | |
11504 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11505 | + | |
11506 | + cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc)); | |
11507 | + | |
11508 | + datalen = sizeof(*nwdClose); | |
11509 | + cmdlen = datalen + sizeof(*cmd); | |
11510 | + cmd = kmalloc(cmdlen, GFP_KERNEL); | |
11511 | + if (!cmd) | |
11512 | + return -ENOMEM; | |
11513 | + | |
11514 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11515 | + cmd->Command.SequenceNumber = 0; | |
11516 | + cmd->Command.SessionId = Session; | |
11517 | + cmd->NwcCommand = NWC_CLOSE_CONN; | |
11518 | + | |
11519 | + nwdClose = (PNwdCCloseConn) cmd->data; | |
11520 | + cmd->dataLen = sizeof(*nwdClose); | |
11521 | + *Handle = nwdClose->ConnHandle = Uint32toHandle(cc.ConnHandle); | |
11522 | + | |
11523 | + /* | |
11524 | + * send the request | |
11525 | + */ | |
11526 | + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11527 | + (void **)&reply, &replylen, 0); | |
11528 | + if (reply) { | |
11529 | + retCode = reply->Reply.ErrorCode; | |
11530 | + kfree(reply); | |
11531 | + } | |
11532 | + kfree(cmd); | |
11533 | + return retCode; | |
11534 | +} | |
11535 | + | |
11536 | +int NwSysConnClose(PXPLAT pdata, unsigned long *Handle, session_t Session) | |
11537 | +{ | |
11538 | + PXPLAT_CALL_REQUEST cmd; | |
11539 | + PXPLAT_CALL_REPLY reply; | |
11540 | + NwcCloseConn cc; | |
11541 | + PNwdCCloseConn nwdClose; | |
11542 | + unsigned int retCode = 0; | |
11543 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11544 | + | |
11545 | + cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc)); | |
11546 | + | |
11547 | + datalen = sizeof(*nwdClose); | |
11548 | + cmdlen = datalen + sizeof(*cmd); | |
11549 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11550 | + if (cmd) { | |
11551 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11552 | + cmd->Command.SequenceNumber = 0; | |
11553 | + cmd->Command.SessionId = Session; | |
11554 | + cmd->NwcCommand = NWC_SYS_CLOSE_CONN; | |
11555 | + | |
11556 | + nwdClose = (PNwdCCloseConn) cmd->data; | |
11557 | + cmd->dataLen = sizeof(*nwdClose); | |
11558 | + nwdClose->ConnHandle = (HANDLE) (unsigned long) cc.ConnHandle; | |
11559 | + *Handle = (unsigned long) cc.ConnHandle; | |
11560 | + | |
11561 | + /* | |
11562 | + * send the request | |
11563 | + */ | |
11564 | + retCode = | |
11565 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11566 | + (void **)&reply, &replylen, 0); | |
11567 | + if (reply) { | |
11568 | + retCode = reply->Reply.ErrorCode; | |
11569 | + kfree(reply); | |
11570 | + } | |
11571 | + kfree(cmd); | |
11572 | + | |
11573 | + } | |
11574 | + | |
11575 | + return (retCode); | |
11576 | + | |
11577 | +} | |
11578 | + | |
11579 | +/*++======================================================================*/ | |
11580 | +int NwLoginIdentity(PXPLAT pdata, struct schandle *Session) | |
11581 | +/* | |
11582 | + * Arguments: | |
11583 | + * | |
11584 | + * Returns: | |
11585 | + * | |
11586 | + * Abstract: | |
11587 | + * | |
11588 | + * Notes: | |
11589 | + * | |
11590 | + * Environment: | |
11591 | + * | |
11592 | + *========================================================================*/ | |
11593 | +{ | |
11594 | + NwcLoginIdentity lgn, *plgn; | |
11595 | + int retCode = -ENOMEM; | |
11596 | + NclString server; | |
11597 | + NclString username; | |
11598 | + NclString password; | |
11599 | + unsigned long cpylen; | |
11600 | + NwcString nwcStr; | |
11601 | + | |
11602 | + cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn)); | |
11603 | + | |
11604 | + DbgPrint("NwLoginIdentity:\n"); | |
11605 | + mydump(sizeof(lgn), &lgn); | |
11606 | + | |
11607 | + cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr)); | |
11608 | + DbgPrint("NwLoginIdentity: DomainName\n"); | |
11609 | + mydump(sizeof(nwcStr), &nwcStr); | |
11610 | + | |
11611 | + if ((server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL))) { | |
11612 | + server.type = nwcStr.DataType; | |
11613 | + server.len = nwcStr.DataLen; | |
11614 | + if (!copy_from_user | |
11615 | + ((void *)server.buffer, nwcStr.pBuffer, server.len)) { | |
11616 | + DbgPrint("NwLoginIdentity: Server\n"); | |
11617 | + mydump(server.len, server.buffer); | |
11618 | + | |
11619 | + cpylen = | |
11620 | + copy_from_user(&nwcStr, lgn.pObjectName, | |
11621 | + sizeof(nwcStr)); | |
11622 | + DbgPrint("NwLoginIdentity: ObjectName\n"); | |
11623 | + mydump(sizeof(nwcStr), &nwcStr); | |
11624 | + | |
11625 | + if ((username.buffer = | |
11626 | + Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL))) { | |
11627 | + username.type = nwcStr.DataType; | |
11628 | + username.len = nwcStr.DataLen; | |
11629 | + if (!copy_from_user | |
11630 | + ((void *)username.buffer, nwcStr.pBuffer, | |
11631 | + username.len)) { | |
11632 | + DbgPrint("NwLoginIdentity: User\n"); | |
11633 | + mydump(username.len, username.buffer); | |
11634 | + | |
11635 | + cpylen = | |
11636 | + copy_from_user(&nwcStr, | |
11637 | + lgn.pPassword, | |
11638 | + sizeof(nwcStr)); | |
11639 | + DbgPrint("NwLoginIdentity: Password\n"); | |
11640 | + mydump(sizeof(nwcStr), &nwcStr); | |
11641 | + | |
11642 | + if ((password.buffer = | |
11643 | + Novfs_Malloc(nwcStr.DataLen, | |
11644 | + GFP_KERNEL))) { | |
11645 | + password.type = nwcStr.DataType; | |
11646 | + password.len = nwcStr.DataLen; | |
11647 | + if (!copy_from_user | |
11648 | + ((void *)password.buffer, | |
11649 | + nwcStr.pBuffer, | |
11650 | + password.len)) { | |
11651 | + retCode = | |
11652 | + do_login(&server, | |
11653 | + &username, | |
11654 | + &password, | |
11655 | + (HANDLE *)&lgn.AuthenticationId, | |
11656 | + Session); | |
11657 | + if (retCode) { | |
11658 | + lgn.AuthenticationId = 0; | |
11659 | + } | |
11660 | + | |
11661 | + plgn = | |
11662 | + (NwcLoginIdentity *) | |
11663 | + pdata->reqData; | |
11664 | + cpylen = | |
11665 | + copy_to_user(&plgn-> | |
11666 | + AuthenticationId, | |
11667 | + &lgn. | |
11668 | + AuthenticationId, | |
11669 | + sizeof | |
11670 | + (plgn-> | |
11671 | + AuthenticationId)); | |
11672 | + | |
11673 | + } | |
11674 | + memset(password.buffer, 0, | |
11675 | + password.len); | |
11676 | + kfree(password.buffer); | |
11677 | + } | |
11678 | + } | |
11679 | + memset(username.buffer, 0, username.len); | |
11680 | + kfree(username.buffer); | |
11681 | + } | |
11682 | + } | |
11683 | + kfree(server.buffer); | |
11684 | + } | |
11685 | + return (retCode); | |
11686 | +} | |
11687 | + | |
11688 | +/*++======================================================================*/ | |
11689 | +int NwAuthConnWithId(PXPLAT pdata, session_t Session) | |
11690 | +/* | |
11691 | + * Arguments: | |
11692 | + * | |
11693 | + * Returns: | |
11694 | + * | |
11695 | + * Abstract: | |
11696 | + * | |
11697 | + * Notes: | |
11698 | + * | |
11699 | + * Environment: | |
11700 | + * | |
11701 | + *========================================================================*/ | |
11702 | +{ | |
11703 | + NwcAuthenticateWithId pauth; | |
11704 | + PNwdCAuthenticateWithId pDauth; | |
11705 | + PXPLAT_CALL_REQUEST cmd; | |
11706 | + PXPLAT_CALL_REPLY reply; | |
11707 | + int retCode = -ENOMEM; | |
11708 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11709 | + | |
11710 | + datalen = sizeof(*pDauth); | |
11711 | + cmdlen = datalen + sizeof(*cmd); | |
11712 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11713 | + | |
11714 | + if (cmd) { | |
11715 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11716 | + cmd->Command.SequenceNumber = 0; | |
11717 | + cmd->Command.SessionId = Session; | |
11718 | + cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID; | |
11719 | + | |
11720 | + cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth)); | |
11721 | + | |
11722 | + pDauth = (PNwdCAuthenticateWithId) cmd->data; | |
11723 | + cmd->dataLen = datalen; | |
11724 | + pDauth->AuthenticationId = pauth.AuthenticationId; | |
11725 | + pDauth->ConnHandle = (HANDLE) (unsigned long) pauth.ConnHandle; | |
11726 | + | |
11727 | + retCode = | |
11728 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11729 | + (void **)&reply, &replylen, | |
11730 | + INTERRUPTIBLE); | |
11731 | + if (reply) { | |
11732 | + retCode = reply->Reply.ErrorCode; | |
11733 | + kfree(reply); | |
11734 | + } | |
11735 | + kfree(cmd); | |
11736 | + } | |
11737 | + return (retCode); | |
11738 | +} | |
11739 | + | |
11740 | +/*++======================================================================*/ | |
11741 | +int NwLicenseConn(PXPLAT pdata, session_t Session) | |
11742 | +/* | |
11743 | + * Arguments: | |
11744 | + * | |
11745 | + * Returns: | |
11746 | + * | |
11747 | + * Abstract: | |
11748 | + * | |
11749 | + * Notes: | |
11750 | + * | |
11751 | + * Environment: | |
11752 | + * | |
11753 | + *========================================================================*/ | |
11754 | +{ | |
11755 | + PXPLAT_CALL_REQUEST cmd; | |
11756 | + PXPLAT_CALL_REPLY reply; | |
11757 | + NwcLicenseConn lisc; | |
11758 | + PNwdCLicenseConn pDLisc; | |
11759 | + int retCode = -ENOMEM; | |
11760 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11761 | + | |
11762 | + datalen = sizeof(*pDLisc); | |
11763 | + cmdlen = datalen + sizeof(*cmd); | |
11764 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11765 | + | |
11766 | + if (cmd) { | |
11767 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11768 | + cmd->Command.SequenceNumber = 0; | |
11769 | + cmd->Command.SessionId = Session; | |
11770 | + cmd->NwcCommand = NWC_LICENSE_CONN; | |
11771 | + | |
11772 | + cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc)); | |
11773 | + | |
11774 | + pDLisc = (PNwdCLicenseConn) cmd->data; | |
11775 | + cmd->dataLen = datalen; | |
11776 | + pDLisc->ConnHandle = (HANDLE) (unsigned long) lisc.ConnHandle; | |
11777 | + | |
11778 | + retCode = | |
11779 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11780 | + (void **)&reply, &replylen, | |
11781 | + INTERRUPTIBLE); | |
11782 | + if (reply) { | |
11783 | + retCode = reply->Reply.ErrorCode; | |
11784 | + kfree(reply); | |
11785 | + } | |
11786 | + kfree(cmd); | |
11787 | + } | |
11788 | + return (retCode); | |
11789 | +} | |
11790 | + | |
11791 | +/*++======================================================================*/ | |
11792 | +int NwLogoutIdentity(PXPLAT pdata, session_t Session) | |
11793 | +/* | |
11794 | + * Arguments: | |
11795 | + * | |
11796 | + * Returns: | |
11797 | + * | |
11798 | + * Abstract: | |
11799 | + * | |
11800 | + * Notes: | |
11801 | + * | |
11802 | + * Environment: | |
11803 | + * | |
11804 | + *========================================================================*/ | |
11805 | +{ | |
11806 | + PXPLAT_CALL_REQUEST cmd; | |
11807 | + PXPLAT_CALL_REPLY reply; | |
11808 | + NwcLogoutIdentity logout; | |
11809 | + PNwdCLogoutIdentity pDLogout; | |
11810 | + int retCode = -ENOMEM; | |
11811 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11812 | + | |
11813 | + datalen = sizeof(*pDLogout); | |
11814 | + cmdlen = datalen + sizeof(*cmd); | |
11815 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11816 | + | |
11817 | + if (cmd) { | |
11818 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11819 | + cmd->Command.SequenceNumber = 0; | |
11820 | + cmd->Command.SessionId = Session; | |
11821 | + cmd->NwcCommand = NWC_LOGOUT_IDENTITY; | |
11822 | + | |
11823 | + cpylen = | |
11824 | + copy_from_user(&logout, pdata->reqData, sizeof(logout)); | |
11825 | + | |
11826 | + pDLogout = (PNwdCLogoutIdentity) cmd->data; | |
11827 | + cmd->dataLen = datalen; | |
11828 | + pDLogout->AuthenticationId = logout.AuthenticationId; | |
11829 | + | |
11830 | + retCode = | |
11831 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11832 | + (void **)&reply, &replylen, | |
11833 | + INTERRUPTIBLE); | |
11834 | + if (reply) { | |
11835 | + retCode = reply->Reply.ErrorCode; | |
11836 | + kfree(reply); | |
11837 | + } | |
11838 | + kfree(cmd); | |
11839 | + } | |
11840 | + return (retCode); | |
11841 | +} | |
11842 | + | |
11843 | +/*++======================================================================*/ | |
11844 | +int NwUnlicenseConn(PXPLAT pdata, session_t Session) | |
11845 | +/* | |
11846 | + * Arguments: | |
11847 | + * | |
11848 | + * Returns: | |
11849 | + * | |
11850 | + * Abstract: | |
11851 | + * | |
11852 | + * Notes: | |
11853 | + * | |
11854 | + * Environment: | |
11855 | + * | |
11856 | + *========================================================================*/ | |
11857 | +{ | |
11858 | + PXPLAT_CALL_REQUEST cmd; | |
11859 | + PXPLAT_CALL_REPLY reply; | |
11860 | + PNwdCUnlicenseConn pUconn; | |
11861 | + NwcUnlicenseConn ulc; | |
11862 | + int retCode = -ENOMEM; | |
11863 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11864 | + | |
11865 | + cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc)); | |
11866 | + datalen = sizeof(*pUconn); | |
11867 | + cmdlen = datalen + sizeof(*cmd); | |
11868 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11869 | + if (cmd) { | |
11870 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11871 | + cmd->Command.SequenceNumber = 0; | |
11872 | + cmd->Command.SessionId = Session; | |
11873 | + cmd->NwcCommand = NWC_UNLICENSE_CONN; | |
11874 | + cmd->dataLen = datalen; | |
11875 | + pUconn = (PNwdCUnlicenseConn) cmd->data; | |
11876 | + | |
11877 | + pUconn->ConnHandle = (HANDLE) (unsigned long) ulc.ConnHandle; | |
11878 | + retCode = | |
11879 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11880 | + (void **)&reply, &replylen, | |
11881 | + INTERRUPTIBLE); | |
11882 | + if (reply) { | |
11883 | + /* | |
11884 | + * we got reply data from the daemon | |
11885 | + */ | |
11886 | + retCode = reply->Reply.ErrorCode; | |
11887 | + kfree(reply); | |
11888 | + } | |
11889 | + | |
11890 | + kfree(cmd); | |
11891 | + } | |
11892 | + return (retCode); | |
11893 | + | |
11894 | +} | |
11895 | + | |
11896 | +/*++======================================================================*/ | |
11897 | +int NwUnAuthenticate(PXPLAT pdata, session_t Session) | |
11898 | +/* | |
11899 | + * Arguments: | |
11900 | + * | |
11901 | + * Returns: | |
11902 | + * | |
11903 | + * Abstract: | |
11904 | + * | |
11905 | + * Notes: | |
11906 | + * | |
11907 | + * Environment: | |
11908 | + * | |
11909 | + *========================================================================*/ | |
11910 | +{ | |
11911 | + PXPLAT_CALL_REQUEST cmd; | |
11912 | + PXPLAT_CALL_REPLY reply; | |
11913 | + NwcUnauthenticate auth; | |
11914 | + PNwdCUnauthenticate pDAuth; | |
11915 | + int retCode = -ENOMEM; | |
11916 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
11917 | + | |
11918 | + datalen = sizeof(*pDAuth); | |
11919 | + cmdlen = datalen + sizeof(*cmd); | |
11920 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11921 | + | |
11922 | + if (cmd) { | |
11923 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11924 | + cmd->Command.SequenceNumber = 0; | |
11925 | + cmd->Command.SessionId = Session; | |
11926 | + cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN; | |
11927 | + | |
11928 | + cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth)); | |
11929 | + | |
11930 | + pDAuth = (PNwdCUnauthenticate) cmd->data; | |
11931 | + cmd->dataLen = datalen; | |
11932 | + pDAuth->AuthenticationId = auth.AuthenticationId; | |
11933 | + pDAuth->ConnHandle = (HANDLE) (unsigned long) auth.ConnHandle; | |
11934 | + | |
11935 | + retCode = | |
11936 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11937 | + (void **)&reply, &replylen, | |
11938 | + INTERRUPTIBLE); | |
11939 | + if (reply) { | |
11940 | + retCode = reply->Reply.ErrorCode; | |
11941 | + kfree(reply); | |
11942 | + } | |
11943 | + kfree(cmd); | |
11944 | + } | |
11945 | + return (retCode); | |
11946 | + | |
11947 | +} | |
11948 | + | |
11949 | +/*++======================================================================*/ | |
11950 | +int NwGetConnInfo(PXPLAT pdata, session_t Session) | |
11951 | +/* | |
11952 | + * Arguments: | |
11953 | + * | |
11954 | + * Returns: | |
11955 | + * | |
11956 | + * Abstract: | |
11957 | + * | |
11958 | + * Notes: | |
11959 | + * | |
11960 | + * Environment: | |
11961 | + * | |
11962 | + *========================================================================*/ | |
11963 | +{ | |
11964 | + PXPLAT_CALL_REQUEST cmd; | |
11965 | + PXPLAT_CALL_REPLY reply; | |
11966 | + NwcGetConnInfo connInfo; | |
11967 | + PNwdCGetConnInfo pDConnInfo; | |
11968 | + int retCode = -ENOMEM; | |
11969 | + unsigned long cmdlen, replylen, cpylen; | |
11970 | + | |
11971 | + cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo); | |
11972 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
11973 | + cpylen = | |
11974 | + copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo)); | |
11975 | + | |
11976 | + if (cmd) { | |
11977 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
11978 | + cmd->Command.SequenceNumber = 0; | |
11979 | + cmd->Command.SessionId = Session; | |
11980 | + cmd->NwcCommand = NWC_GET_CONN_INFO; | |
11981 | + | |
11982 | + pDConnInfo = (PNwdCGetConnInfo) cmd->data; | |
11983 | + | |
11984 | + pDConnInfo->ConnHandle = (HANDLE) (unsigned long) connInfo.ConnHandle; | |
11985 | + pDConnInfo->uInfoLevel = connInfo.uInfoLevel; | |
11986 | + pDConnInfo->uInfoLength = connInfo.uInfoLength; | |
11987 | + cmd->dataLen = sizeof(*pDConnInfo); | |
11988 | + | |
11989 | + retCode = | |
11990 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
11991 | + (void **)&reply, &replylen, | |
11992 | + INTERRUPTIBLE); | |
11993 | + if (reply) { | |
11994 | + retCode = reply->Reply.ErrorCode; | |
11995 | + if (!retCode) { | |
11996 | + GetConnData(&connInfo, cmd, reply); | |
11997 | + } | |
11998 | + | |
11999 | + kfree(reply); | |
12000 | + } | |
12001 | + kfree(cmd); | |
12002 | + | |
12003 | + } | |
12004 | + | |
12005 | + return (retCode); | |
12006 | + | |
12007 | +} | |
12008 | + | |
12009 | +/*++======================================================================*/ | |
12010 | +int NwSetConnInfo(PXPLAT pdata, session_t Session) | |
12011 | +/* | |
12012 | + * Arguments: | |
12013 | + * | |
12014 | + * Returns: | |
12015 | + * | |
12016 | + * Abstract: | |
12017 | + * | |
12018 | + * Notes: | |
12019 | + * | |
12020 | + * Environment: | |
12021 | + * | |
12022 | + *========================================================================*/ | |
12023 | +{ | |
12024 | + PXPLAT_CALL_REQUEST cmd; | |
12025 | + PXPLAT_CALL_REPLY reply; | |
12026 | + NwcSetConnInfo connInfo; | |
12027 | + PNwdCSetConnInfo pDConnInfo; | |
12028 | + int retCode = -ENOMEM; | |
12029 | + unsigned long cmdlen, replylen, cpylen; | |
12030 | + | |
12031 | + cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo); | |
12032 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12033 | + cpylen = | |
12034 | + copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo)); | |
12035 | + | |
12036 | + if (cmd) { | |
12037 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12038 | + cmd->Command.SequenceNumber = 0; | |
12039 | + cmd->Command.SessionId = Session; | |
12040 | + cmd->NwcCommand = NWC_SET_CONN_INFO; | |
12041 | + | |
12042 | + pDConnInfo = (PNwdCSetConnInfo) cmd->data; | |
12043 | + | |
12044 | + pDConnInfo->ConnHandle = (HANDLE) (unsigned long) connInfo.ConnHandle; | |
12045 | + pDConnInfo->uInfoLevel = connInfo.uInfoLevel; | |
12046 | + pDConnInfo->uInfoLength = connInfo.uInfoLength; | |
12047 | + cmd->dataLen = sizeof(*pDConnInfo); | |
12048 | + | |
12049 | + retCode = | |
12050 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12051 | + (void **)&reply, &replylen, | |
12052 | + INTERRUPTIBLE); | |
12053 | + if (reply) { | |
12054 | + retCode = reply->Reply.ErrorCode; | |
12055 | + kfree(reply); | |
12056 | + } | |
12057 | + kfree(cmd); | |
12058 | + | |
12059 | + } | |
12060 | + | |
12061 | + return (retCode); | |
12062 | + | |
12063 | +} | |
12064 | + | |
12065 | +/*++======================================================================*/ | |
12066 | +int NwGetIdentityInfo(PXPLAT pdata, session_t Session) | |
12067 | +/* | |
12068 | + * Arguments: | |
12069 | + * | |
12070 | + * Returns: | |
12071 | + * | |
12072 | + * Abstract: | |
12073 | + * | |
12074 | + * Notes: | |
12075 | + * | |
12076 | + * Environment: | |
12077 | + * | |
12078 | + *========================================================================*/ | |
12079 | +{ | |
12080 | + PXPLAT_CALL_REQUEST cmd; | |
12081 | + PXPLAT_CALL_REPLY reply; | |
12082 | + NwcGetIdentityInfo qidInfo, *gId; | |
12083 | + PNwdCGetIdentityInfo idInfo; | |
12084 | + NwcString xferStr; | |
12085 | + char *str; | |
12086 | + int retCode = -ENOMEM; | |
12087 | + unsigned long cmdlen, replylen, cpylen; | |
12088 | + | |
12089 | + cmdlen = sizeof(*cmd) + sizeof(*idInfo); | |
12090 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12091 | + cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo)); | |
12092 | + | |
12093 | + if (cmd) { | |
12094 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12095 | + cmd->Command.SequenceNumber = 0; | |
12096 | + cmd->Command.SessionId = Session; | |
12097 | + cmd->NwcCommand = NWC_GET_IDENTITY_INFO; | |
12098 | + | |
12099 | + idInfo = (PNwdCGetIdentityInfo) cmd->data; | |
12100 | + | |
12101 | + idInfo->AuthenticationId = qidInfo.AuthenticationId; | |
12102 | + cmd->dataLen = sizeof(*idInfo); | |
12103 | + | |
12104 | + retCode = | |
12105 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12106 | + (void **)&reply, &replylen, | |
12107 | + INTERRUPTIBLE); | |
12108 | + if (reply) { | |
12109 | + retCode = reply->Reply.ErrorCode; | |
12110 | + | |
12111 | + if (!reply->Reply.ErrorCode) { | |
12112 | + /* | |
12113 | + * Save the return info to the user structure. | |
12114 | + */ | |
12115 | + gId = pdata->reqData; | |
12116 | + idInfo = (PNwdCGetIdentityInfo) reply->data; | |
12117 | + cpylen = | |
12118 | + copy_to_user(&gId->AuthenticationId, | |
12119 | + &idInfo->AuthenticationId, | |
12120 | + sizeof(idInfo-> | |
12121 | + AuthenticationId)); | |
12122 | + cpylen = | |
12123 | + copy_to_user(&gId->AuthType, | |
12124 | + &idInfo->AuthType, | |
12125 | + sizeof(idInfo->AuthType)); | |
12126 | + cpylen = | |
12127 | + copy_to_user(&gId->IdentityFlags, | |
12128 | + &idInfo->IdentityFlags, | |
12129 | + sizeof(idInfo->IdentityFlags)); | |
12130 | + cpylen = | |
12131 | + copy_to_user(&gId->NameType, | |
12132 | + &idInfo->NameType, | |
12133 | + sizeof(idInfo->NameType)); | |
12134 | + cpylen = | |
12135 | + copy_to_user(&gId->ObjectType, | |
12136 | + &idInfo->ObjectType, | |
12137 | + sizeof(idInfo->ObjectType)); | |
12138 | + | |
12139 | + cpylen = | |
12140 | + copy_from_user(&xferStr, gId->pDomainName, | |
12141 | + sizeof(NwcString)); | |
12142 | + str = | |
12143 | + (char *)((char *)reply->data + | |
12144 | + idInfo->pDomainNameOffset); | |
12145 | + cpylen = | |
12146 | + copy_to_user(xferStr.pBuffer, str, | |
12147 | + idInfo->domainLen); | |
12148 | + xferStr.DataType = NWC_STRING_TYPE_ASCII; | |
12149 | + xferStr.DataLen = idInfo->domainLen; | |
12150 | + cpylen = | |
12151 | + copy_to_user(gId->pDomainName, &xferStr, | |
12152 | + sizeof(NwcString)); | |
12153 | + | |
12154 | + cpylen = | |
12155 | + copy_from_user(&xferStr, gId->pObjectName, | |
12156 | + sizeof(NwcString)); | |
12157 | + str = | |
12158 | + (char *)((char *)reply->data + | |
12159 | + idInfo->pObjectNameOffset); | |
12160 | + cpylen = | |
12161 | + copy_to_user(xferStr.pBuffer, str, | |
12162 | + idInfo->objectLen); | |
12163 | + xferStr.DataLen = idInfo->objectLen - 1; | |
12164 | + xferStr.DataType = NWC_STRING_TYPE_ASCII; | |
12165 | + cpylen = | |
12166 | + copy_to_user(gId->pObjectName, &xferStr, | |
12167 | + sizeof(NwcString)); | |
12168 | + } | |
12169 | + | |
12170 | + kfree(reply); | |
12171 | + } | |
12172 | + kfree(cmd); | |
12173 | + | |
12174 | + } | |
12175 | + | |
12176 | + return (retCode); | |
12177 | +} | |
12178 | + | |
12179 | +/*++======================================================================*/ | |
12180 | +int NwScanConnInfo(PXPLAT pdata, session_t Session) | |
12181 | +/* | |
12182 | + * Arguments: | |
12183 | + * | |
12184 | + * Returns: | |
12185 | + * | |
12186 | + * Abstract: | |
12187 | + * | |
12188 | + * Notes: | |
12189 | + * | |
12190 | + * Environment: | |
12191 | + * | |
12192 | + *========================================================================*/ | |
12193 | +{ | |
12194 | + PXPLAT_CALL_REQUEST cmd; | |
12195 | + PXPLAT_CALL_REPLY reply; | |
12196 | + NwcScanConnInfo connInfo, *rInfo; | |
12197 | + PNwdCScanConnInfo pDConnInfo; | |
12198 | + int retCode = -ENOMEM; | |
12199 | + unsigned long cmdlen, replylen, cpylen; | |
12200 | + unsigned char *localData; | |
12201 | + | |
12202 | + cpylen = | |
12203 | + copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo)); | |
12204 | + | |
12205 | + cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen; | |
12206 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12207 | + | |
12208 | + if (cmd) { | |
12209 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12210 | + cmd->Command.SequenceNumber = 0; | |
12211 | + cmd->Command.SessionId = Session; | |
12212 | + cmd->NwcCommand = NWC_SCAN_CONN_INFO; | |
12213 | + | |
12214 | + pDConnInfo = (PNwdCScanConnInfo) cmd->data; | |
12215 | + | |
12216 | + DbgPrint("NwScanConnInfo: Input Data\n"); | |
12217 | + DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex); | |
12218 | + DbgPrint("connInfo.uConnectionReference = 0x%X\n", | |
12219 | + connInfo.uConnectionReference); | |
12220 | + DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", | |
12221 | + connInfo.uScanInfoLevel); | |
12222 | + DbgPrint("connInfo.uScanInfoLen = 0x%X\n", | |
12223 | + connInfo.uScanInfoLen); | |
12224 | + DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", | |
12225 | + connInfo.uReturnInfoLength); | |
12226 | + DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", | |
12227 | + connInfo.uReturnInfoLevel); | |
12228 | + DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags); | |
12229 | + | |
12230 | + pDConnInfo->uScanIndex = connInfo.uScanIndex; | |
12231 | + pDConnInfo->uConnectionReference = | |
12232 | + connInfo.uConnectionReference; | |
12233 | + pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel; | |
12234 | + pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen; | |
12235 | + pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength; | |
12236 | + pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel; | |
12237 | + pDConnInfo->uScanFlags = connInfo.uScanFlags; | |
12238 | + | |
12239 | + if (pDConnInfo->uScanInfoLen) { | |
12240 | + localData = (unsigned char *) pDConnInfo; | |
12241 | + pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo); | |
12242 | + localData += pDConnInfo->uScanConnInfoOffset; | |
12243 | + cpylen = | |
12244 | + copy_from_user(localData, connInfo.pScanConnInfo, | |
12245 | + connInfo.uScanInfoLen); | |
12246 | + } else { | |
12247 | + pDConnInfo->uScanConnInfoOffset = 0; | |
12248 | + } | |
12249 | + | |
12250 | + cmd->dataLen = sizeof(*pDConnInfo); | |
12251 | + | |
12252 | + retCode = | |
12253 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12254 | + (void **)&reply, &replylen, | |
12255 | + INTERRUPTIBLE); | |
12256 | + if (reply) { | |
12257 | + DbgPrint("NwScanConnInfo: Reply recieved\n"); | |
12258 | + DbgPrint(" NextIndex = %x\n", connInfo.uScanIndex); | |
12259 | + DbgPrint(" ErrorCode = %x\n", reply->Reply.ErrorCode); | |
12260 | + DbgPrint(" data = %x\n", reply->data); | |
12261 | + | |
12262 | + pDConnInfo = (PNwdCScanConnInfo) reply->data; | |
12263 | + retCode = (unsigned long) reply->Reply.ErrorCode; | |
12264 | + if (!retCode) { | |
12265 | + GetUserData(&connInfo, cmd, reply); | |
12266 | + rInfo = (NwcScanConnInfo *) pdata->repData; | |
12267 | + cpylen = | |
12268 | + copy_to_user(pdata->repData, | |
12269 | + &pDConnInfo->uScanIndex, | |
12270 | + sizeof(pDConnInfo-> | |
12271 | + uScanIndex)); | |
12272 | + cpylen = | |
12273 | + copy_to_user(&rInfo->uConnectionReference, | |
12274 | + &pDConnInfo-> | |
12275 | + uConnectionReference, | |
12276 | + sizeof(pDConnInfo-> | |
12277 | + uConnectionReference)); | |
12278 | + } else { | |
12279 | + unsigned long x; | |
12280 | + | |
12281 | + x = 0; | |
12282 | + rInfo = (NwcScanConnInfo *) pdata->reqData; | |
12283 | + cpylen = | |
12284 | + copy_to_user(&rInfo->uConnectionReference, | |
12285 | + &x, | |
12286 | + sizeof(rInfo-> | |
12287 | + uConnectionReference)); | |
12288 | + } | |
12289 | + | |
12290 | + kfree(reply); | |
12291 | + } else { | |
12292 | + retCode = -EIO; | |
12293 | + } | |
12294 | + kfree(cmd); | |
12295 | + | |
12296 | + } | |
12297 | + | |
12298 | + return (retCode); | |
12299 | +} | |
12300 | + | |
12301 | +/*++======================================================================*/ | |
12302 | +static void GetUserData(NwcScanConnInfo * connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply) | |
12303 | +/* | |
12304 | + * Abstract: Copies the user data out of the scan conn info call. | |
12305 | + * | |
12306 | + *========================================================================*/ | |
12307 | +{ | |
12308 | + unsigned long uLevel; | |
12309 | + PNwdCScanConnInfo pDConnInfo; | |
12310 | + | |
12311 | + unsigned char *srcData = NULL; | |
12312 | + unsigned long dataLen = 0, cpylen; | |
12313 | + | |
12314 | + pDConnInfo = (PNwdCScanConnInfo) reply->data; | |
12315 | + uLevel = pDConnInfo->uReturnInfoLevel; | |
12316 | + DbgPrint | |
12317 | + ("[GetUserData] uLevel = %d, reply = 0x%p, reply->data = 0x%X\n", | |
12318 | + uLevel, reply, reply->data); | |
12319 | + | |
12320 | + switch (uLevel) { | |
12321 | + case NWC_CONN_INFO_RETURN_ALL: | |
12322 | + case NWC_CONN_INFO_NDS_STATE: | |
12323 | + case NWC_CONN_INFO_MAX_PACKET_SIZE: | |
12324 | + case NWC_CONN_INFO_LICENSE_STATE: | |
12325 | + case NWC_CONN_INFO_PUBLIC_STATE: | |
12326 | + case NWC_CONN_INFO_SERVICE_TYPE: | |
12327 | + case NWC_CONN_INFO_DISTANCE: | |
12328 | + case NWC_CONN_INFO_SERVER_VERSION: | |
12329 | + case NWC_CONN_INFO_AUTH_ID: | |
12330 | + case NWC_CONN_INFO_SUSPENDED: | |
12331 | + case NWC_CONN_INFO_WORKGROUP_ID: | |
12332 | + case NWC_CONN_INFO_SECURITY_STATE: | |
12333 | + case NWC_CONN_INFO_CONN_NUMBER: | |
12334 | + case NWC_CONN_INFO_USER_ID: | |
12335 | + case NWC_CONN_INFO_BCAST_STATE: | |
12336 | + case NWC_CONN_INFO_CONN_REF: | |
12337 | + case NWC_CONN_INFO_AUTH_STATE: | |
12338 | + case NWC_CONN_INFO_TREE_NAME: | |
12339 | + case NWC_CONN_INFO_SERVER_NAME: | |
12340 | + case NWC_CONN_INFO_VERSION: | |
12341 | + srcData = (unsigned char *) pDConnInfo; | |
12342 | + srcData += pDConnInfo->uReturnConnInfoOffset; | |
12343 | + dataLen = pDConnInfo->uReturnInfoLength; | |
12344 | + break; | |
12345 | + | |
12346 | + case NWC_CONN_INFO_TRAN_ADDR: | |
12347 | + { | |
12348 | + unsigned char *dstData = connInfo->pReturnConnInfo; | |
12349 | + NwcTranAddr tranAddr; | |
12350 | + | |
12351 | + srcData = (unsigned char *) reply->data; | |
12352 | + dataLen = reply->dataLen; | |
12353 | + | |
12354 | + DbgPrint | |
12355 | + ("GetUserData NWC_CONN_INFO_TRAN_ADDR 0x%p -> 0x%p :: 0x%X\n", | |
12356 | + srcData, connInfo->pReturnConnInfo, dataLen); | |
12357 | + | |
12358 | + cpylen = | |
12359 | + copy_from_user(&tranAddr, dstData, | |
12360 | + sizeof(tranAddr)); | |
12361 | + | |
12362 | + srcData += | |
12363 | + ((PNwdCScanConnInfo) srcData)-> | |
12364 | + uReturnConnInfoOffset; | |
12365 | + | |
12366 | + tranAddr.uTransportType = | |
12367 | + ((PNwdTranAddr) srcData)->uTransportType; | |
12368 | + tranAddr.uAddressLength = | |
12369 | + ((PNwdTranAddr) srcData)->uAddressLength; | |
12370 | + | |
12371 | + cpylen = | |
12372 | + copy_to_user(dstData, &tranAddr, sizeof(tranAddr)); | |
12373 | + cpylen = | |
12374 | + copy_to_user(tranAddr.puAddress, | |
12375 | + ((PNwdTranAddr) srcData)->Buffer, | |
12376 | + ((PNwdTranAddr) srcData)-> | |
12377 | + uAddressLength); | |
12378 | + dataLen = 0; | |
12379 | + break; | |
12380 | + } | |
12381 | + case NWC_CONN_INFO_RETURN_NONE: | |
12382 | + case NWC_CONN_INFO_TREE_NAME_UNICODE: | |
12383 | + case NWC_CONN_INFO_SERVER_NAME_UNICODE: | |
12384 | + case NWC_CONN_INFO_LOCAL_TRAN_ADDR: | |
12385 | + case NWC_CONN_INFO_ALTERNATE_ADDR: | |
12386 | + case NWC_CONN_INFO_SERVER_GUID: | |
12387 | + default: | |
12388 | + break; | |
12389 | + } | |
12390 | + | |
12391 | + if (srcData && dataLen) { | |
12392 | + DbgPrint("Copy Data in GetUserData 0x%p -> 0x%p :: 0x%X\n", | |
12393 | + srcData, connInfo->pReturnConnInfo, dataLen); | |
12394 | + cpylen = | |
12395 | + copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen); | |
12396 | + } | |
12397 | + | |
12398 | + return; | |
12399 | +} | |
12400 | + | |
12401 | +/*++======================================================================*/ | |
12402 | +static void GetConnData(NwcGetConnInfo * connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply) | |
12403 | +/* | |
12404 | + * Abstract: Copies the user data out of the scan conn info call. | |
12405 | + * | |
12406 | + *========================================================================*/ | |
12407 | +{ | |
12408 | + unsigned long uLevel; | |
12409 | + PNwdCGetConnInfo pDConnInfo; | |
12410 | + | |
12411 | + unsigned char *srcData = NULL; | |
12412 | + unsigned long dataLen = 0, cpylen; | |
12413 | + | |
12414 | + pDConnInfo = (PNwdCGetConnInfo) cmd->data; | |
12415 | + uLevel = pDConnInfo->uInfoLevel; | |
12416 | + | |
12417 | + switch (uLevel) { | |
12418 | + case NWC_CONN_INFO_RETURN_ALL: | |
12419 | + srcData = (unsigned char *) reply->data; | |
12420 | + dataLen = reply->dataLen; | |
12421 | + break; | |
12422 | + | |
12423 | + case NWC_CONN_INFO_RETURN_NONE: | |
12424 | + dataLen = 0; | |
12425 | + break; | |
12426 | + | |
12427 | + case NWC_CONN_INFO_TRAN_ADDR: | |
12428 | + { | |
12429 | + unsigned char *dstData = connInfo->pConnInfo; | |
12430 | + NwcTranAddr tranAddr; | |
12431 | + | |
12432 | + srcData = (unsigned char *) reply->data; | |
12433 | + | |
12434 | + cpylen = | |
12435 | + copy_from_user(&tranAddr, dstData, | |
12436 | + sizeof(tranAddr)); | |
12437 | + tranAddr.uTransportType = | |
12438 | + ((PNwdTranAddr) srcData)->uTransportType; | |
12439 | + tranAddr.uAddressLength = | |
12440 | + ((PNwdTranAddr) srcData)->uAddressLength; | |
12441 | + | |
12442 | + cpylen = | |
12443 | + copy_to_user(dstData, &tranAddr, sizeof(tranAddr)); | |
12444 | + cpylen = | |
12445 | + copy_to_user(tranAddr.puAddress, | |
12446 | + ((PNwdTranAddr) srcData)->Buffer, | |
12447 | + ((PNwdTranAddr) srcData)-> | |
12448 | + uAddressLength); | |
12449 | + dataLen = 0; | |
12450 | + break; | |
12451 | + } | |
12452 | + case NWC_CONN_INFO_NDS_STATE: | |
12453 | + case NWC_CONN_INFO_MAX_PACKET_SIZE: | |
12454 | + case NWC_CONN_INFO_LICENSE_STATE: | |
12455 | + case NWC_CONN_INFO_PUBLIC_STATE: | |
12456 | + case NWC_CONN_INFO_SERVICE_TYPE: | |
12457 | + case NWC_CONN_INFO_DISTANCE: | |
12458 | + case NWC_CONN_INFO_SERVER_VERSION: | |
12459 | + case NWC_CONN_INFO_AUTH_ID: | |
12460 | + case NWC_CONN_INFO_SUSPENDED: | |
12461 | + case NWC_CONN_INFO_WORKGROUP_ID: | |
12462 | + case NWC_CONN_INFO_SECURITY_STATE: | |
12463 | + case NWC_CONN_INFO_CONN_NUMBER: | |
12464 | + case NWC_CONN_INFO_USER_ID: | |
12465 | + case NWC_CONN_INFO_BCAST_STATE: | |
12466 | + case NWC_CONN_INFO_CONN_REF: | |
12467 | + case NWC_CONN_INFO_AUTH_STATE: | |
12468 | + case NWC_CONN_INFO_VERSION: | |
12469 | + case NWC_CONN_INFO_SERVER_NAME: | |
12470 | + case NWC_CONN_INFO_TREE_NAME: | |
12471 | + srcData = (unsigned char *) reply->data; | |
12472 | + dataLen = reply->dataLen; | |
12473 | + break; | |
12474 | + | |
12475 | + case NWC_CONN_INFO_TREE_NAME_UNICODE: | |
12476 | + case NWC_CONN_INFO_SERVER_NAME_UNICODE: | |
12477 | + break; | |
12478 | + | |
12479 | + case NWC_CONN_INFO_LOCAL_TRAN_ADDR: | |
12480 | + break; | |
12481 | + | |
12482 | + case NWC_CONN_INFO_ALTERNATE_ADDR: | |
12483 | + break; | |
12484 | + | |
12485 | + case NWC_CONN_INFO_SERVER_GUID: | |
12486 | + break; | |
12487 | + | |
12488 | + default: | |
12489 | + break; | |
12490 | + } | |
12491 | + | |
12492 | + if (srcData && dataLen) { | |
12493 | + cpylen = | |
12494 | + copy_to_user(connInfo->pConnInfo, srcData, | |
12495 | + connInfo->uInfoLength); | |
12496 | + } | |
12497 | + | |
12498 | + return; | |
12499 | +} | |
12500 | + | |
12501 | +/*++======================================================================*/ | |
12502 | +int NwGetDaemonVersion(PXPLAT pdata, session_t Session) | |
12503 | +/* | |
12504 | + * Arguments: | |
12505 | + * | |
12506 | + * Returns: | |
12507 | + * | |
12508 | + * Abstract: | |
12509 | + * | |
12510 | + * Notes: | |
12511 | + * | |
12512 | + * Environment: | |
12513 | + * | |
12514 | + *========================================================================*/ | |
12515 | +{ | |
12516 | + PXPLAT_CALL_REQUEST cmd; | |
12517 | + PXPLAT_CALL_REPLY reply; | |
12518 | + PNwdCGetRequesterVersion pDVersion; | |
12519 | + int retCode = -ENOMEM; | |
12520 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
12521 | + | |
12522 | + datalen = sizeof(*pDVersion); | |
12523 | + cmdlen = datalen + sizeof(*cmd); | |
12524 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12525 | + | |
12526 | + if (cmd) { | |
12527 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12528 | + cmd->Command.SequenceNumber = 0; | |
12529 | + cmd->Command.SessionId = Session; | |
12530 | + cmd->NwcCommand = NWC_GET_REQUESTER_VERSION; | |
12531 | + cmdlen = sizeof(*cmd); | |
12532 | + retCode = | |
12533 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12534 | + (void **)&reply, &replylen, | |
12535 | + INTERRUPTIBLE); | |
12536 | + if (reply) { | |
12537 | + retCode = reply->Reply.ErrorCode; | |
12538 | + pDVersion = (PNwdCGetRequesterVersion) reply->data; | |
12539 | + cpylen = | |
12540 | + copy_to_user(pDVersion, pdata->reqData, | |
12541 | + sizeof(*pDVersion)); | |
12542 | + kfree(reply); | |
12543 | + } | |
12544 | + kfree(cmd); | |
12545 | + } | |
12546 | + return (retCode); | |
12547 | + | |
12548 | +} | |
12549 | + | |
12550 | +/*++======================================================================*/ | |
12551 | +int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session) | |
12552 | +/* | |
12553 | + * Arguments: | |
12554 | + * | |
12555 | + * Returns: | |
12556 | + * | |
12557 | + * Abstract: | |
12558 | + * | |
12559 | + * Notes: | |
12560 | + * | |
12561 | + * Environment: | |
12562 | + * | |
12563 | + *========================================================================*/ | |
12564 | +{ | |
12565 | + PXPLAT_CALL_REQUEST cmd; | |
12566 | + PXPLAT_CALL_REPLY reply; | |
12567 | + PNwdCGetPreferredDsTree pDGetTree; | |
12568 | + NwcGetPreferredDsTree xplatCall, *p; | |
12569 | + int retCode = -ENOMEM; | |
12570 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
12571 | + unsigned char *dPtr; | |
12572 | + | |
12573 | + cpylen = | |
12574 | + copy_from_user(&xplatCall, pdata->reqData, | |
12575 | + sizeof(NwcGetPreferredDsTree)); | |
12576 | + datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength; | |
12577 | + cmdlen = datalen + sizeof(*cmd); | |
12578 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12579 | + | |
12580 | + if (cmd) { | |
12581 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12582 | + cmd->Command.SequenceNumber = 0; | |
12583 | + cmd->Command.SessionId = Session; | |
12584 | + cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE; | |
12585 | + cmdlen = sizeof(*cmd); | |
12586 | + | |
12587 | + retCode = | |
12588 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12589 | + (void **)&reply, &replylen, | |
12590 | + INTERRUPTIBLE); | |
12591 | + if (reply) { | |
12592 | + retCode = reply->Reply.ErrorCode; | |
12593 | + if (!retCode) { | |
12594 | + pDGetTree = | |
12595 | + (PNwdCGetPreferredDsTree) reply->data; | |
12596 | + dPtr = | |
12597 | + reply->data + pDGetTree->DsTreeNameOffset; | |
12598 | + p = (NwcGetPreferredDsTree *) pdata->reqData; | |
12599 | + | |
12600 | + DbgPrint | |
12601 | + ("NwcGetPreferredDSTree: Reply recieved\n"); | |
12602 | + DbgPrint(" TreeLen = %x\n", | |
12603 | + pDGetTree->uTreeLength); | |
12604 | + DbgPrint(" TreeName = %s\n", dPtr); | |
12605 | + | |
12606 | + cpylen = | |
12607 | + copy_to_user(p, &pDGetTree->uTreeLength, 4); | |
12608 | + cpylen = | |
12609 | + copy_to_user(xplatCall.pDsTreeName, dPtr, | |
12610 | + pDGetTree->uTreeLength); | |
12611 | + } | |
12612 | + kfree(reply); | |
12613 | + } | |
12614 | + kfree(cmd); | |
12615 | + } | |
12616 | + return (retCode); | |
12617 | + | |
12618 | +} | |
12619 | + | |
12620 | +/*++======================================================================*/ | |
12621 | +int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session) | |
12622 | +/* | |
12623 | + * Arguments: | |
12624 | + * | |
12625 | + * Returns: | |
12626 | + * | |
12627 | + * Abstract: | |
12628 | + * | |
12629 | + * Notes: | |
12630 | + * | |
12631 | + * Environment: | |
12632 | + * | |
12633 | + *========================================================================*/ | |
12634 | +{ | |
12635 | + PXPLAT_CALL_REQUEST cmd; | |
12636 | + PXPLAT_CALL_REPLY reply; | |
12637 | + PNwdCSetPreferredDsTree pDSetTree; | |
12638 | + NwcSetPreferredDsTree xplatCall; | |
12639 | + int retCode = -ENOMEM; | |
12640 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
12641 | + unsigned char *dPtr; | |
12642 | + | |
12643 | + cpylen = | |
12644 | + copy_from_user(&xplatCall, pdata->reqData, | |
12645 | + sizeof(NwcSetPreferredDsTree)); | |
12646 | + datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength; | |
12647 | + cmdlen = datalen + sizeof(*cmd); | |
12648 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12649 | + | |
12650 | + if (cmd) { | |
12651 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12652 | + cmd->Command.SequenceNumber = 0; | |
12653 | + cmd->Command.SessionId = Session; | |
12654 | + cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE; | |
12655 | + | |
12656 | + pDSetTree = (PNwdCSetPreferredDsTree) cmd->data; | |
12657 | + pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree); | |
12658 | + pDSetTree->uTreeLength = xplatCall.uTreeLength; | |
12659 | + | |
12660 | + dPtr = cmd->data + sizeof(*pDSetTree); | |
12661 | + cpylen = | |
12662 | + copy_from_user(dPtr, xplatCall.pDsTreeName, | |
12663 | + xplatCall.uTreeLength); | |
12664 | + | |
12665 | + retCode = | |
12666 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12667 | + (void **)&reply, &replylen, | |
12668 | + INTERRUPTIBLE); | |
12669 | + if (reply) { | |
12670 | + retCode = reply->Reply.ErrorCode; | |
12671 | + kfree(reply); | |
12672 | + } | |
12673 | + kfree(cmd); | |
12674 | + } | |
12675 | + return (retCode); | |
12676 | + | |
12677 | +} | |
12678 | + | |
12679 | +/*++======================================================================*/ | |
12680 | +int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session) | |
12681 | +/* | |
12682 | + * Arguments: | |
12683 | + * | |
12684 | + * Returns: | |
12685 | + * | |
12686 | + * Abstract: | |
12687 | + * | |
12688 | + * Notes: | |
12689 | + * | |
12690 | + * Environment: | |
12691 | + * | |
12692 | + *========================================================================*/ | |
12693 | +{ | |
12694 | + PXPLAT_CALL_REQUEST cmd; | |
12695 | + PXPLAT_CALL_REPLY reply; | |
12696 | + NwcSetDefaultNameContext xplatCall; | |
12697 | + PNwdCSetDefaultNameContext pDSet; | |
12698 | + int retCode = -ENOMEM; | |
12699 | + unsigned long cmdlen, datalen, replylen, cpylen; | |
12700 | + unsigned char *dPtr; | |
12701 | + | |
12702 | + cpylen = | |
12703 | + copy_from_user(&xplatCall, pdata->reqData, | |
12704 | + sizeof(NwcSetDefaultNameContext)); | |
12705 | + datalen = | |
12706 | + sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength; | |
12707 | + cmdlen = datalen + sizeof(*cmd); | |
12708 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12709 | + | |
12710 | + if (cmd) { | |
12711 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12712 | + cmd->Command.SequenceNumber = 0; | |
12713 | + cmd->Command.SessionId = Session; | |
12714 | + cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT; | |
12715 | + cmd->dataLen = | |
12716 | + sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + | |
12717 | + xplatCall.uNameLength; | |
12718 | + | |
12719 | + pDSet = (PNwdCSetDefaultNameContext) cmd->data; | |
12720 | + dPtr = cmd->data; | |
12721 | + | |
12722 | + pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext); | |
12723 | + pDSet->uTreeLength = xplatCall.uTreeLength; | |
12724 | + pDSet->NameContextOffset = | |
12725 | + pDSet->TreeOffset + xplatCall.uTreeLength; | |
12726 | + pDSet->uNameLength = xplatCall.uNameLength; | |
12727 | + | |
12728 | +//sgled cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength); | |
12729 | + cpylen = copy_from_user(dPtr + pDSet->TreeOffset, xplatCall.pDsTreeName, xplatCall.uTreeLength); //sgled | |
12730 | + cpylen = | |
12731 | + copy_from_user(dPtr + pDSet->NameContextOffset, | |
12732 | + xplatCall.pNameContext, | |
12733 | + xplatCall.uNameLength); | |
12734 | + | |
12735 | + retCode = | |
12736 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12737 | + (void **)&reply, &replylen, | |
12738 | + INTERRUPTIBLE); | |
12739 | + if (reply) { | |
12740 | + retCode = reply->Reply.ErrorCode; | |
12741 | + kfree(reply); | |
12742 | + } | |
12743 | + kfree(cmd); | |
12744 | + } | |
12745 | + return (retCode); | |
12746 | + | |
12747 | +} | |
12748 | + | |
12749 | +/*++======================================================================*/ | |
12750 | +int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session) | |
12751 | +/* | |
12752 | + * Arguments: | |
12753 | + * | |
12754 | + * Returns: | |
12755 | + * | |
12756 | + * Abstract: | |
12757 | + * | |
12758 | + * Notes: | |
12759 | + * | |
12760 | + * Environment: | |
12761 | + * | |
12762 | + *========================================================================*/ | |
12763 | +{ | |
12764 | + PXPLAT_CALL_REQUEST cmd; | |
12765 | + PXPLAT_CALL_REPLY reply; | |
12766 | + NwcGetDefaultNameContext xplatCall; | |
12767 | + PNwdCGetDefaultNameContext pGet; | |
12768 | + char *dPtr; | |
12769 | + int retCode = -ENOMEM; | |
12770 | + unsigned long cmdlen, replylen, cpylen; | |
12771 | + | |
12772 | + cpylen = | |
12773 | + copy_from_user(&xplatCall, pdata->reqData, | |
12774 | + sizeof(NwcGetDefaultNameContext)); | |
12775 | + cmdlen = | |
12776 | + sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + | |
12777 | + xplatCall.uTreeLength; | |
12778 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12779 | + | |
12780 | + if (cmd) { | |
12781 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12782 | + cmd->Command.SequenceNumber = 0; | |
12783 | + cmd->Command.SessionId = Session; | |
12784 | + cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT; | |
12785 | + cmd->dataLen = | |
12786 | + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength; | |
12787 | + | |
12788 | + pGet = (PNwdCGetDefaultNameContext) cmd->data; | |
12789 | + dPtr = cmd->data; | |
12790 | + | |
12791 | + pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext); | |
12792 | + pGet->uTreeLength = xplatCall.uTreeLength; | |
12793 | + | |
12794 | +//sgled cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength); | |
12795 | + cpylen = copy_from_user(dPtr + pGet->TreeOffset, xplatCall.pDsTreeName, xplatCall.uTreeLength); //sgled | |
12796 | + dPtr[pGet->TreeOffset + pGet->uTreeLength] = 0; | |
12797 | + | |
12798 | + retCode = | |
12799 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12800 | + (void **)&reply, &replylen, | |
12801 | + INTERRUPTIBLE); | |
12802 | + if (reply) { | |
12803 | + retCode = reply->Reply.ErrorCode; | |
12804 | + if (!retCode) { | |
12805 | + pGet = (PNwdCGetDefaultNameContext) reply->data; | |
12806 | + | |
12807 | + DbgPrint | |
12808 | + ("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", | |
12809 | + retCode, pGet->uNameLength, | |
12810 | + xplatCall.uNameLength); | |
12811 | + if (xplatCall.uNameLength < pGet->uNameLength) { | |
12812 | + pGet->uNameLength = | |
12813 | + xplatCall.uNameLength; | |
12814 | + retCode = NWE_BUFFER_OVERFLOW; | |
12815 | + } | |
12816 | + dPtr = (char *)pGet + pGet->NameContextOffset; | |
12817 | + cpylen = | |
12818 | + copy_to_user(xplatCall.pNameContext, dPtr, | |
12819 | + pGet->uNameLength); | |
12820 | + } | |
12821 | + | |
12822 | + kfree(reply); | |
12823 | + } | |
12824 | + kfree(cmd); | |
12825 | + } | |
12826 | + return (retCode); | |
12827 | + | |
12828 | +} | |
12829 | + | |
12830 | +int NwQueryFeature(PXPLAT pdata, session_t Session) | |
12831 | +{ | |
12832 | + NwcQueryFeature xpCall; | |
12833 | + int status = 0; | |
12834 | + unsigned long cpylen; | |
12835 | + | |
12836 | + cpylen = | |
12837 | + copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature)); | |
12838 | + switch (xpCall.Feature) { | |
12839 | + case NWC_FEAT_NDS: | |
12840 | + case NWC_FEAT_NDS_MTREE: | |
12841 | + case NWC_FEAT_PRN_CAPTURE: | |
12842 | + case NWC_FEAT_NDS_RESOLVE: | |
12843 | + | |
12844 | + status = NWE_REQUESTER_FAILURE; | |
12845 | + | |
12846 | + } | |
12847 | + return (status); | |
12848 | +} | |
12849 | + | |
12850 | +/*++======================================================================*/ | |
12851 | +int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session) | |
12852 | +/* | |
12853 | + * Arguments: | |
12854 | + * | |
12855 | + * Returns: | |
12856 | + * | |
12857 | + * Abstract: | |
12858 | + * | |
12859 | + * Notes: | |
12860 | + * | |
12861 | + * Environment: | |
12862 | + * | |
12863 | + *========================================================================*/ | |
12864 | +{ | |
12865 | + PXPLAT_CALL_REQUEST cmd; | |
12866 | + PXPLAT_CALL_REPLY reply; | |
12867 | + NwcGetTreeMonitoredConnRef xplatCall, *p; | |
12868 | + PNwdCGetTreeMonitoredConnRef pDConnRef; | |
12869 | + char *dPtr; | |
12870 | + unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; | |
12871 | + | |
12872 | + cpylen = | |
12873 | + copy_from_user(&xplatCall, pdata->reqData, | |
12874 | + sizeof(NwcGetTreeMonitoredConnRef)); | |
12875 | + datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen; | |
12876 | + cmdlen = datalen + sizeof(*cmd); | |
12877 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12878 | + | |
12879 | + if (cmd) { | |
12880 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12881 | + cmd->Command.SequenceNumber = 0; | |
12882 | + cmd->Command.SessionId = Session; | |
12883 | + cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF; | |
12884 | + | |
12885 | + pDConnRef = (PNwdCGetTreeMonitoredConnRef) cmd->data; | |
12886 | + pDConnRef->TreeName.boffset = sizeof(*pDConnRef); | |
12887 | + pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen; | |
12888 | + pDConnRef->TreeName.type = xplatCall.pTreeName->DataType; | |
12889 | + | |
12890 | + dPtr = cmd->data + sizeof(*pDConnRef); | |
12891 | + cpylen = | |
12892 | + copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, | |
12893 | + pDConnRef->TreeName.len); | |
12894 | + status = | |
12895 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12896 | + (void **)&reply, &replylen, | |
12897 | + INTERRUPTIBLE); | |
12898 | + if (reply) { | |
12899 | + pDConnRef = (PNwdCGetTreeMonitoredConnRef) reply->data; | |
12900 | + dPtr = reply->data + pDConnRef->TreeName.boffset; | |
12901 | + p = (NwcGetTreeMonitoredConnRef *) pdata->reqData; | |
12902 | + cpylen = | |
12903 | + copy_to_user(&p->uConnReference, | |
12904 | + &pDConnRef->uConnReference, 4); | |
12905 | + | |
12906 | + status = reply->Reply.ErrorCode; | |
12907 | + kfree(reply); | |
12908 | + } | |
12909 | + kfree(cmd); | |
12910 | + | |
12911 | + } | |
12912 | + | |
12913 | + return (status); | |
12914 | +} | |
12915 | + | |
12916 | +/*++======================================================================*/ | |
12917 | +int NwcEnumIdentities(PXPLAT pdata, session_t Session) | |
12918 | +/* | |
12919 | + * Arguments: | |
12920 | + * | |
12921 | + * Returns: | |
12922 | + * | |
12923 | + * Abstract: | |
12924 | + * | |
12925 | + * Notes: | |
12926 | + * | |
12927 | + * Environment: | |
12928 | + * | |
12929 | + *========================================================================*/ | |
12930 | +{ | |
12931 | + PXPLAT_CALL_REQUEST cmd; | |
12932 | + PXPLAT_CALL_REPLY reply; | |
12933 | + NwcEnumerateIdentities xplatCall, *eId; | |
12934 | + PNwdCEnumerateIdentities pEnum; | |
12935 | + NwcString xferStr; | |
12936 | + char *str; | |
12937 | + unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; | |
12938 | + | |
12939 | + cpylen = | |
12940 | + copy_from_user(&xplatCall, pdata->reqData, | |
12941 | + sizeof(NwcEnumerateIdentities)); | |
12942 | + datalen = sizeof(*pEnum); | |
12943 | + cmdlen = datalen + sizeof(*cmd); | |
12944 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
12945 | + | |
12946 | + if (cmd) { | |
12947 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
12948 | + cmd->Command.SequenceNumber = 0; | |
12949 | + cmd->Command.SessionId = Session; | |
12950 | + cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES; | |
12951 | + | |
12952 | + DbgPrint("NwcEnumIdentities: Send Request\n"); | |
12953 | + DbgPrint(" iterator = %x\n", xplatCall.Iterator); | |
12954 | + DbgPrint(" cmdlen = %d\n", cmdlen); | |
12955 | + | |
12956 | + pEnum = (PNwdCEnumerateIdentities) cmd->data; | |
12957 | + pEnum->Iterator = xplatCall.Iterator; | |
12958 | + status = | |
12959 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
12960 | + (void **)&reply, &replylen, | |
12961 | + INTERRUPTIBLE); | |
12962 | + if (reply) { | |
12963 | + status = reply->Reply.ErrorCode; | |
12964 | + | |
12965 | + eId = pdata->repData; | |
12966 | + pEnum = (PNwdCEnumerateIdentities) reply->data; | |
12967 | + cpylen = | |
12968 | + copy_to_user(&eId->Iterator, &pEnum->Iterator, | |
12969 | + sizeof(pEnum->Iterator)); | |
12970 | + DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", | |
12971 | + pEnum->AuthenticationId); | |
12972 | + cpylen = | |
12973 | + copy_to_user(&eId->AuthenticationId, | |
12974 | + &pEnum->AuthenticationId, | |
12975 | + sizeof(pEnum->AuthenticationId)); | |
12976 | + cpylen = | |
12977 | + copy_to_user(&eId->AuthType, &pEnum->AuthType, | |
12978 | + sizeof(pEnum->AuthType)); | |
12979 | + cpylen = | |
12980 | + copy_to_user(&eId->IdentityFlags, | |
12981 | + &pEnum->IdentityFlags, | |
12982 | + sizeof(pEnum->IdentityFlags)); | |
12983 | + cpylen = | |
12984 | + copy_to_user(&eId->NameType, &pEnum->NameType, | |
12985 | + sizeof(pEnum->NameType)); | |
12986 | + cpylen = | |
12987 | + copy_to_user(&eId->ObjectType, &pEnum->ObjectType, | |
12988 | + sizeof(pEnum->ObjectType)); | |
12989 | + | |
12990 | + if (!status) { | |
12991 | + cpylen = | |
12992 | + copy_from_user(&xferStr, eId->pDomainName, | |
12993 | + sizeof(NwcString)); | |
12994 | + str = | |
12995 | + (char *)((char *)reply->data + | |
12996 | + pEnum->domainNameOffset); | |
12997 | + DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", | |
12998 | + str); | |
12999 | + cpylen = | |
13000 | + copy_to_user(xferStr.pBuffer, str, | |
13001 | + pEnum->domainNameLen); | |
13002 | + xferStr.DataType = NWC_STRING_TYPE_ASCII; | |
13003 | + xferStr.DataLen = pEnum->domainNameLen - 1; | |
13004 | + cpylen = | |
13005 | + copy_to_user(eId->pDomainName, &xferStr, | |
13006 | + sizeof(NwcString)); | |
13007 | + | |
13008 | + cpylen = | |
13009 | + copy_from_user(&xferStr, eId->pObjectName, | |
13010 | + sizeof(NwcString)); | |
13011 | + str = | |
13012 | + (char *)((char *)reply->data + | |
13013 | + pEnum->objectNameOffset); | |
13014 | + DbgPrint("[XPLAT NWCAPI] Found User %s\n", str); | |
13015 | + cpylen = | |
13016 | + copy_to_user(xferStr.pBuffer, str, | |
13017 | + pEnum->objectNameLen); | |
13018 | + xferStr.DataType = NWC_STRING_TYPE_ASCII; | |
13019 | + xferStr.DataLen = pEnum->objectNameLen - 1; | |
13020 | + cpylen = | |
13021 | + copy_to_user(eId->pObjectName, &xferStr, | |
13022 | + sizeof(NwcString)); | |
13023 | + } | |
13024 | + | |
13025 | + kfree(reply); | |
13026 | + | |
13027 | + } | |
13028 | + kfree(cmd); | |
13029 | + | |
13030 | + } | |
13031 | + return (status); | |
13032 | +} | |
13033 | + | |
13034 | +/*++======================================================================*/ | |
13035 | +int NwcChangeAuthKey(PXPLAT pdata, session_t Session) | |
13036 | +/* | |
13037 | + * Arguments: | |
13038 | + * | |
13039 | + * Returns: | |
13040 | + * | |
13041 | + * Abstract: Change the password on the server | |
13042 | + * | |
13043 | + * Notes: | |
13044 | + * | |
13045 | + * Environment: | |
13046 | + * | |
13047 | + *========================================================================*/ | |
13048 | +{ | |
13049 | + PXPLAT_CALL_REQUEST cmd; | |
13050 | + PXPLAT_CALL_REPLY reply; | |
13051 | + NwcChangeKey xplatCall; | |
13052 | + PNwdCChangeKey pNewKey; | |
13053 | + NwcString xferStr; | |
13054 | + char *str; | |
13055 | + unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; | |
13056 | + | |
13057 | + cpylen = | |
13058 | + copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey)); | |
13059 | + | |
13060 | + datalen = | |
13061 | + sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + | |
13062 | + xplatCall.pObjectName->DataLen + xplatCall.pNewPassword->DataLen + | |
13063 | + xplatCall.pVerifyPassword->DataLen; | |
13064 | + | |
13065 | + cmdlen = sizeof(*cmd) + datalen; | |
13066 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13067 | + | |
13068 | + if (cmd) { | |
13069 | + pNewKey = (PNwdCChangeKey) cmd->data; | |
13070 | + cmd->dataLen = datalen; | |
13071 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13072 | + cmd->Command.SequenceNumber = 0; | |
13073 | + cmd->Command.SessionId = Session; | |
13074 | + cmd->NwcCommand = NWC_CHANGE_KEY; | |
13075 | + | |
13076 | + pNewKey->NameType = xplatCall.NameType; | |
13077 | + pNewKey->ObjectType = xplatCall.ObjectType; | |
13078 | + pNewKey->AuthType = xplatCall.AuthType; | |
13079 | + str = (char *)pNewKey; | |
13080 | + | |
13081 | + /* | |
13082 | + * Get the tree name | |
13083 | + */ | |
13084 | + str += sizeof(*pNewKey); | |
13085 | + cpylen = | |
13086 | + copy_from_user(&xferStr, xplatCall.pDomainName, | |
13087 | + sizeof(NwcString)); | |
13088 | + pNewKey->domainNameOffset = sizeof(*pNewKey); | |
13089 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13090 | + pNewKey->domainNameLen = xferStr.DataLen; | |
13091 | + | |
13092 | + /* | |
13093 | + * Get the User Name | |
13094 | + */ | |
13095 | + str += pNewKey->domainNameLen; | |
13096 | + cpylen = | |
13097 | + copy_from_user(&xferStr, xplatCall.pObjectName, | |
13098 | + sizeof(NwcString)); | |
13099 | + pNewKey->objectNameOffset = | |
13100 | + pNewKey->domainNameOffset + pNewKey->domainNameLen; | |
13101 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13102 | + pNewKey->objectNameLen = xferStr.DataLen; | |
13103 | + | |
13104 | + /* | |
13105 | + * Get the New Password | |
13106 | + */ | |
13107 | + str += pNewKey->objectNameLen; | |
13108 | + cpylen = | |
13109 | + copy_from_user(&xferStr, xplatCall.pNewPassword, | |
13110 | + sizeof(NwcString)); | |
13111 | + pNewKey->newPasswordOffset = | |
13112 | + pNewKey->objectNameOffset + pNewKey->objectNameLen; | |
13113 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13114 | + pNewKey->newPasswordLen = xferStr.DataLen; | |
13115 | + | |
13116 | + /* | |
13117 | + * Get the Verify Password | |
13118 | + */ | |
13119 | + str += pNewKey->newPasswordLen; | |
13120 | + cpylen = | |
13121 | + copy_from_user(&xferStr, xplatCall.pVerifyPassword, | |
13122 | + sizeof(NwcString)); | |
13123 | + pNewKey->verifyPasswordOffset = | |
13124 | + pNewKey->newPasswordOffset + pNewKey->newPasswordLen; | |
13125 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13126 | + pNewKey->verifyPasswordLen = xferStr.DataLen; | |
13127 | + | |
13128 | + status = | |
13129 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13130 | + (void **)&reply, &replylen, | |
13131 | + INTERRUPTIBLE); | |
13132 | + if (reply) { | |
13133 | + status = reply->Reply.ErrorCode; | |
13134 | + kfree(reply); | |
13135 | + } | |
13136 | + memset(cmd, 0, cmdlen); | |
13137 | + | |
13138 | + kfree(cmd); | |
13139 | + } | |
13140 | + | |
13141 | + return (status); | |
13142 | +} | |
13143 | + | |
13144 | +/*++======================================================================*/ | |
13145 | +int NwcSetPrimaryConn(PXPLAT pdata, session_t Session) | |
13146 | +/* | |
13147 | + * Arguments: | |
13148 | + * | |
13149 | + * Returns: | |
13150 | + * | |
13151 | + * Abstract: Set the primary connection Id | |
13152 | + * | |
13153 | + * Notes: | |
13154 | + * | |
13155 | + * Environment: | |
13156 | + * | |
13157 | + *========================================================================*/ | |
13158 | +{ | |
13159 | + PXPLAT_CALL_REQUEST cmd; | |
13160 | + PXPLAT_CALL_REPLY reply; | |
13161 | + NwcSetPrimaryConnection xplatCall; | |
13162 | + PNwdCSetPrimaryConnection pConn; | |
13163 | + unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; | |
13164 | + | |
13165 | + cpylen = | |
13166 | + copy_from_user(&xplatCall, pdata->reqData, | |
13167 | + sizeof(NwcSetPrimaryConnection)); | |
13168 | + | |
13169 | + datalen = sizeof(NwdCSetPrimaryConnection); | |
13170 | + cmdlen = sizeof(*cmd) + datalen; | |
13171 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13172 | + if (cmd) { | |
13173 | + pConn = (PNwdCSetPrimaryConnection) cmd->data; | |
13174 | + cmd->dataLen = datalen; | |
13175 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13176 | + cmd->Command.SequenceNumber = 0; | |
13177 | + cmd->Command.SessionId = Session; | |
13178 | + cmd->NwcCommand = NWC_SET_PRIMARY_CONN; | |
13179 | + pConn->ConnHandle = (HANDLE) (unsigned long) xplatCall.ConnHandle; | |
13180 | + status = | |
13181 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13182 | + (void **)&reply, &replylen, | |
13183 | + INTERRUPTIBLE); | |
13184 | + | |
13185 | + if (reply) { | |
13186 | + status = reply->Reply.ErrorCode; | |
13187 | + kfree(reply); | |
13188 | + } | |
13189 | + | |
13190 | + kfree(cmd); | |
13191 | + } | |
13192 | + | |
13193 | + return (status); | |
13194 | +} | |
13195 | + | |
13196 | +/*++======================================================================*/ | |
13197 | +int NwcGetPrimaryConn(PXPLAT pdata, session_t Session) | |
13198 | +/* | |
13199 | + * Arguments: | |
13200 | + * | |
13201 | + * Returns: | |
13202 | + * | |
13203 | + * Abstract: Get the Primary connection | |
13204 | + * | |
13205 | + * Notes: | |
13206 | + * | |
13207 | + * Environment: | |
13208 | + * | |
13209 | + *========================================================================*/ | |
13210 | +{ | |
13211 | + XPLAT_CALL_REQUEST cmd; | |
13212 | + PXPLAT_CALL_REPLY reply; | |
13213 | + unsigned long status = -ENOMEM, cmdlen, replylen, cpylen; | |
13214 | + | |
13215 | + cmdlen = (unsigned long) (&((PXPLAT_CALL_REQUEST) 0)->data); | |
13216 | + | |
13217 | + cmd.dataLen = 0; | |
13218 | + cmd.Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13219 | + cmd.Command.SequenceNumber = 0; | |
13220 | + cmd.Command.SessionId = Session; | |
13221 | + cmd.NwcCommand = NWC_GET_PRIMARY_CONN; | |
13222 | + | |
13223 | + status = | |
13224 | + Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, | |
13225 | + &replylen, INTERRUPTIBLE); | |
13226 | + | |
13227 | + if (reply) { | |
13228 | + status = reply->Reply.ErrorCode; | |
13229 | + if (!status) { | |
13230 | + cpylen = | |
13231 | + copy_to_user(pdata->repData, reply->data, | |
13232 | + sizeof(unsigned long)); | |
13233 | + } | |
13234 | + | |
13235 | + kfree(reply); | |
13236 | + } | |
13237 | + | |
13238 | + return (status); | |
13239 | +} | |
13240 | + | |
13241 | +/*++======================================================================*/ | |
13242 | +int NwcSetMapDrive(PXPLAT pdata, session_t Session) | |
13243 | +/* | |
13244 | + * Arguments: | |
13245 | + * | |
13246 | + * Returns: | |
13247 | + * | |
13248 | + * Abstract: Get the Primary connection | |
13249 | + * | |
13250 | + * Notes: | |
13251 | + * | |
13252 | + * Environment: | |
13253 | + * | |
13254 | + *========================================================================*/ | |
13255 | +{ | |
13256 | + | |
13257 | + PXPLAT_CALL_REQUEST cmd; | |
13258 | + PXPLAT_CALL_REPLY reply; | |
13259 | + unsigned long status = 0, datalen, cmdlen, replylen, cpylen; | |
13260 | + NwcMapDriveEx symInfo; | |
13261 | + | |
13262 | + DbgPrint("Call to NwcSetMapDrive\n"); | |
13263 | + cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); | |
13264 | + cmdlen = sizeof(*cmd); | |
13265 | + datalen = | |
13266 | + sizeof(symInfo) + symInfo.dirPathOffsetLength + | |
13267 | + symInfo.linkOffsetLength; | |
13268 | + | |
13269 | + DbgPrint(" cmdlen = %d\n", cmdlen); | |
13270 | + DbgPrint(" dataLen = %d\n", datalen); | |
13271 | + DbgPrint(" symInfo.dirPathOffsetLength = %d\n", | |
13272 | + symInfo.dirPathOffsetLength); | |
13273 | + DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength); | |
13274 | + DbgPrint(" pdata->datalen = %d\n", pdata->reqLen); | |
13275 | + | |
13276 | + mydump(sizeof(symInfo), &symInfo); | |
13277 | + | |
13278 | + cmdlen += datalen; | |
13279 | + | |
13280 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13281 | + if (cmd) { | |
13282 | + cmd->dataLen = datalen; | |
13283 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13284 | + cmd->Command.SequenceNumber = 0; | |
13285 | + cmd->Command.SessionId = Session; | |
13286 | + cmd->NwcCommand = NWC_MAP_DRIVE; | |
13287 | + | |
13288 | + cpylen = copy_from_user(cmd->data, pdata->reqData, datalen); | |
13289 | + status = | |
13290 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13291 | + (void **)&reply, &replylen, | |
13292 | + INTERRUPTIBLE); | |
13293 | + | |
13294 | + if (reply) { | |
13295 | + status = reply->Reply.ErrorCode; | |
13296 | + kfree(reply); | |
13297 | + } | |
13298 | + kfree(cmd); | |
13299 | + } | |
13300 | + return (status); | |
13301 | + | |
13302 | +} | |
13303 | + | |
13304 | +/*++======================================================================*/ | |
13305 | +int NwcUnMapDrive(PXPLAT pdata, session_t Session) | |
13306 | +/* | |
13307 | + * Arguments: | |
13308 | + * | |
13309 | + * Returns: | |
13310 | + * | |
13311 | + * Abstract: Get the Primary connection | |
13312 | + * | |
13313 | + * Notes: | |
13314 | + * | |
13315 | + * Environment: | |
13316 | + * | |
13317 | + *========================================================================*/ | |
13318 | +{ | |
13319 | + PXPLAT_CALL_REQUEST cmd; | |
13320 | + PXPLAT_CALL_REPLY reply; | |
13321 | + unsigned long status = 0, datalen, cmdlen, replylen, cpylen; | |
13322 | + NwcUnmapDriveEx symInfo; | |
13323 | + | |
13324 | + DbgPrint("Call to NwcUnMapDrive\n"); | |
13325 | + | |
13326 | + cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); | |
13327 | + cmdlen = sizeof(*cmd); | |
13328 | + datalen = sizeof(symInfo) + symInfo.linkLen; | |
13329 | + | |
13330 | + cmdlen += datalen; | |
13331 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13332 | + if (cmd) { | |
13333 | + cmd->dataLen = datalen; | |
13334 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13335 | + cmd->Command.SequenceNumber = 0; | |
13336 | + cmd->Command.SessionId = Session; | |
13337 | + cmd->NwcCommand = NWC_UNMAP_DRIVE; | |
13338 | + | |
13339 | + cpylen = copy_from_user(cmd->data, pdata->reqData, datalen); | |
13340 | + status = | |
13341 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13342 | + (void **)&reply, &replylen, | |
13343 | + INTERRUPTIBLE); | |
13344 | + | |
13345 | + if (reply) { | |
13346 | + status = reply->Reply.ErrorCode; | |
13347 | + kfree(reply); | |
13348 | + } | |
13349 | + kfree(cmd); | |
13350 | + } | |
13351 | + | |
13352 | + return (status); | |
13353 | +} | |
13354 | + | |
13355 | +/*++======================================================================*/ | |
13356 | +int NwcEnumerateDrives(PXPLAT pdata, session_t Session) | |
13357 | +/* | |
13358 | + * Arguments: | |
13359 | + * | |
13360 | + * Returns: | |
13361 | + * | |
13362 | + * Abstract: Get the Primary connection | |
13363 | + * | |
13364 | + * Notes: | |
13365 | + * | |
13366 | + * Environment: | |
13367 | + * | |
13368 | + *========================================================================*/ | |
13369 | +{ | |
13370 | + PXPLAT_CALL_REQUEST cmd; | |
13371 | + PXPLAT_CALL_REPLY reply; | |
13372 | + unsigned long status = 0, cmdlen, replylen, cpylen; | |
13373 | + unsigned long offset; | |
13374 | + char *cp; | |
13375 | + | |
13376 | + DbgPrint("Call to NwcEnumerateDrives\n"); | |
13377 | + | |
13378 | + cmdlen = sizeof(*cmd); | |
13379 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13380 | + if (cmd) { | |
13381 | + cmd->dataLen = 0; | |
13382 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13383 | + cmd->Command.SequenceNumber = 0; | |
13384 | + cmd->Command.SessionId = Session; | |
13385 | + cmd->NwcCommand = NWC_ENUMERATE_DRIVES; | |
13386 | + status = | |
13387 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13388 | + (void **)&reply, &replylen, | |
13389 | + INTERRUPTIBLE); | |
13390 | + | |
13391 | + if (reply) { | |
13392 | + status = reply->Reply.ErrorCode; | |
13393 | + DbgPrint("Status Code = 0x%X\n", status); | |
13394 | + if (!status) { | |
13395 | + offset = | |
13396 | + sizeof(((PNwcGetMappedDrives) pdata-> | |
13397 | + repData)->MapBuffLen); | |
13398 | + cp = reply->data; | |
13399 | + replylen = | |
13400 | + ((PNwcGetMappedDrives) pdata->repData)-> | |
13401 | + MapBuffLen; | |
13402 | + cpylen = | |
13403 | + copy_to_user(pdata->repData, cp, offset); | |
13404 | + cp += offset; | |
13405 | + cpylen = | |
13406 | + copy_to_user(((PNwcGetMappedDrives) pdata-> | |
13407 | + repData)->MapBuffer, cp, | |
13408 | + min(replylen - offset, | |
13409 | + reply->dataLen - offset)); | |
13410 | + } | |
13411 | + | |
13412 | + kfree(reply); | |
13413 | + } | |
13414 | + kfree(cmd); | |
13415 | + } | |
13416 | + | |
13417 | + return (status); | |
13418 | +} | |
13419 | + | |
13420 | +/*++======================================================================*/ | |
13421 | +int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session) | |
13422 | +/* | |
13423 | + * Arguments: | |
13424 | + * | |
13425 | + * Returns: | |
13426 | + * | |
13427 | + * Abstract: Get the Primary connection | |
13428 | + * | |
13429 | + * Notes: | |
13430 | + * | |
13431 | + * Environment: | |
13432 | + * | |
13433 | + *========================================================================*/ | |
13434 | +{ | |
13435 | + PXPLAT_CALL_REQUEST cmd; | |
13436 | + PXPLAT_CALL_REPLY reply; | |
13437 | + unsigned long cmdlen, replylen; | |
13438 | + int status = 0x8866, cpylen; | |
13439 | + NwcGetBroadcastNotification msg; | |
13440 | + PNwdCGetBroadcastNotification dmsg; | |
13441 | + | |
13442 | + cmdlen = sizeof(*cmd) + sizeof(*dmsg); | |
13443 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13444 | + if (cmd) { | |
13445 | + | |
13446 | + cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg)); | |
13447 | + cmd->dataLen = sizeof(*dmsg); | |
13448 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13449 | + cmd->Command.SequenceNumber = 0; | |
13450 | + cmd->Command.SessionId = Session; | |
13451 | + | |
13452 | + cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE; | |
13453 | + dmsg = (PNwdCGetBroadcastNotification) cmd->data; | |
13454 | + dmsg->uConnReference = (HANDLE) (unsigned long) msg.uConnReference; | |
13455 | + | |
13456 | + status = | |
13457 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13458 | + (void **)&reply, &replylen, | |
13459 | + INTERRUPTIBLE); | |
13460 | + | |
13461 | + if (reply) { | |
13462 | + status = reply->Reply.ErrorCode; | |
13463 | + | |
13464 | + if (!status) { | |
13465 | + char *cp = pdata->repData; | |
13466 | + | |
13467 | + dmsg = | |
13468 | + (PNwdCGetBroadcastNotification) reply->data; | |
13469 | + if (pdata->repLen < dmsg->messageLen) { | |
13470 | + dmsg->messageLen = pdata->repLen; | |
13471 | + } | |
13472 | + msg.messageLen = dmsg->messageLen; | |
13473 | + cpylen = offsetof(NwcGetBroadcastNotification, message); | |
13474 | + cp += cpylen; | |
13475 | + cpylen = copy_to_user(pdata->repData, &msg, cpylen); | |
13476 | + cpylen = copy_to_user(cp, dmsg->message, msg.messageLen); | |
13477 | + } else { | |
13478 | + msg.messageLen = 0; | |
13479 | + msg.message[0] = 0; | |
13480 | + cpylen = offsetof(NwcGetBroadcastNotification, message); | |
13481 | + cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg)); | |
13482 | + } | |
13483 | + | |
13484 | + kfree(reply); | |
13485 | + } | |
13486 | + kfree(cmd); | |
13487 | + } | |
13488 | + return (status); | |
13489 | +} | |
13490 | + | |
13491 | +int NwdSetKeyValue(PXPLAT pdata, session_t Session) | |
13492 | +{ | |
13493 | + PXPLAT_CALL_REQUEST cmd; | |
13494 | + PXPLAT_CALL_REPLY reply; | |
13495 | + NwcSetKey xplatCall; | |
13496 | + PNwdCSetKey pNewKey; | |
13497 | + NwcString cstrObjectName, cstrPassword; | |
13498 | + char *str; | |
13499 | + unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; | |
13500 | + | |
13501 | + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey)); | |
13502 | + cpylen = | |
13503 | + copy_from_user(&cstrObjectName, xplatCall.pObjectName, | |
13504 | + sizeof(NwcString)); | |
13505 | + cpylen = | |
13506 | + copy_from_user(&cstrPassword, xplatCall.pNewPassword, | |
13507 | + sizeof(NwcString)); | |
13508 | + | |
13509 | + datalen = | |
13510 | + sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen; | |
13511 | + | |
13512 | + cmdlen = sizeof(*cmd) + datalen; | |
13513 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13514 | + | |
13515 | + if (cmd) { | |
13516 | + pNewKey = (PNwdCSetKey) cmd->data; | |
13517 | + cmd->dataLen = datalen; | |
13518 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13519 | + cmd->Command.SequenceNumber = 0; | |
13520 | + cmd->Command.SessionId = Session; | |
13521 | + cmd->NwcCommand = NWC_SET_KEY; | |
13522 | + | |
13523 | + pNewKey->ObjectType = xplatCall.ObjectType; | |
13524 | + pNewKey->AuthenticationId = xplatCall.AuthenticationId; | |
13525 | + pNewKey->ConnHandle = (HANDLE) (unsigned long) xplatCall.ConnHandle; | |
13526 | + str = (char *)pNewKey; | |
13527 | + | |
13528 | + /* | |
13529 | + * Get the User Name | |
13530 | + */ | |
13531 | + str += sizeof(NwdCSetKey); | |
13532 | + cpylen = | |
13533 | + copy_from_user(str, cstrObjectName.pBuffer, | |
13534 | + cstrObjectName.DataLen); | |
13535 | + | |
13536 | + str += pNewKey->objectNameLen = cstrObjectName.DataLen; | |
13537 | + pNewKey->objectNameOffset = sizeof(NwdCSetKey); | |
13538 | + | |
13539 | + /* | |
13540 | + * Get the Verify Password | |
13541 | + */ | |
13542 | + cpylen = | |
13543 | + copy_from_user(str, cstrPassword.pBuffer, | |
13544 | + cstrPassword.DataLen); | |
13545 | + | |
13546 | + pNewKey->newPasswordLen = cstrPassword.DataLen; | |
13547 | + pNewKey->newPasswordOffset = | |
13548 | + pNewKey->objectNameOffset + pNewKey->objectNameLen; | |
13549 | + | |
13550 | + status = | |
13551 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13552 | + (void **)&reply, &replylen, | |
13553 | + INTERRUPTIBLE); | |
13554 | + if (reply) { | |
13555 | + status = reply->Reply.ErrorCode; | |
13556 | + kfree(reply); | |
13557 | + } | |
13558 | + memset(cmd, 0, cmdlen); | |
13559 | + kfree(cmd); | |
13560 | + } | |
13561 | + | |
13562 | + return (status); | |
13563 | +} | |
13564 | + | |
13565 | +/*++======================================================================*/ | |
13566 | +int NwdVerifyKeyValue(PXPLAT pdata, session_t Session) | |
13567 | +/* | |
13568 | + * Arguments: | |
13569 | + * | |
13570 | + * Returns: | |
13571 | + * | |
13572 | + * Abstract: Change the password on the server | |
13573 | + * | |
13574 | + * Notes: | |
13575 | + * | |
13576 | + * Environment: | |
13577 | + * | |
13578 | + *========================================================================*/ | |
13579 | +{ | |
13580 | + PXPLAT_CALL_REQUEST cmd; | |
13581 | + PXPLAT_CALL_REPLY reply; | |
13582 | + NwcVerifyKey xplatCall; | |
13583 | + PNwdCVerifyKey pNewKey; | |
13584 | + NwcString xferStr; | |
13585 | + char *str; | |
13586 | + unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; | |
13587 | + | |
13588 | + cpylen = | |
13589 | + copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey)); | |
13590 | + | |
13591 | + datalen = | |
13592 | + sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + | |
13593 | + xplatCall.pObjectName->DataLen + xplatCall.pVerifyPassword->DataLen; | |
13594 | + | |
13595 | + cmdlen = sizeof(*cmd) + datalen; | |
13596 | + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); | |
13597 | + | |
13598 | + if (cmd) { | |
13599 | + pNewKey = (PNwdCVerifyKey) cmd->data; | |
13600 | + cmd->dataLen = datalen; | |
13601 | + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; | |
13602 | + cmd->Command.SequenceNumber = 0; | |
13603 | + cmd->Command.SessionId = Session; | |
13604 | + cmd->NwcCommand = NWC_VERIFY_KEY; | |
13605 | + | |
13606 | + pNewKey->NameType = xplatCall.NameType; | |
13607 | + pNewKey->ObjectType = xplatCall.ObjectType; | |
13608 | + pNewKey->AuthType = xplatCall.AuthType; | |
13609 | + str = (char *)pNewKey; | |
13610 | + | |
13611 | + /* | |
13612 | + * Get the tree name | |
13613 | + */ | |
13614 | + str += sizeof(*pNewKey); | |
13615 | + cpylen = | |
13616 | + copy_from_user(&xferStr, xplatCall.pDomainName, | |
13617 | + sizeof(NwcString)); | |
13618 | + pNewKey->domainNameOffset = sizeof(*pNewKey); | |
13619 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13620 | + pNewKey->domainNameLen = xferStr.DataLen; | |
13621 | + | |
13622 | + /* | |
13623 | + * Get the User Name | |
13624 | + */ | |
13625 | + str += pNewKey->domainNameLen; | |
13626 | + cpylen = | |
13627 | + copy_from_user(&xferStr, xplatCall.pObjectName, | |
13628 | + sizeof(NwcString)); | |
13629 | + pNewKey->objectNameOffset = | |
13630 | + pNewKey->domainNameOffset + pNewKey->domainNameLen; | |
13631 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13632 | + pNewKey->objectNameLen = xferStr.DataLen; | |
13633 | + | |
13634 | + /* | |
13635 | + * Get the Verify Password | |
13636 | + */ | |
13637 | + str += pNewKey->objectNameLen; | |
13638 | + cpylen = | |
13639 | + copy_from_user(&xferStr, xplatCall.pVerifyPassword, | |
13640 | + sizeof(NwcString)); | |
13641 | + pNewKey->verifyPasswordOffset = | |
13642 | + pNewKey->objectNameOffset + pNewKey->objectNameLen; | |
13643 | + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); | |
13644 | + pNewKey->verifyPasswordLen = xferStr.DataLen; | |
13645 | + | |
13646 | + status = | |
13647 | + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, | |
13648 | + (void **)&reply, &replylen, | |
13649 | + INTERRUPTIBLE); | |
13650 | + if (reply) { | |
13651 | + status = reply->Reply.ErrorCode; | |
13652 | + kfree(reply); | |
13653 | + } | |
13654 | + memset(cmd, 0, cmdlen); | |
13655 | + kfree(cmd); | |
13656 | + } | |
13657 | + | |
13658 | + return (status); | |
13659 | +} | |
13660 | --- /dev/null | |
13661 | +++ b/fs/novfs/nwcapi.h | |
13662 | @@ -0,0 +1,2213 @@ | |
13663 | +/* | |
13664 | + * NetWare Redirector for Linux | |
13665 | + * Author: Sheffer Clark | |
13666 | + * | |
13667 | + * This file contains all typedefs and constants for the NetWare Client APIs. | |
13668 | + * | |
13669 | + * Copyright (C) 2005 Novell, Inc. | |
13670 | + * | |
13671 | + * This program is free software; you can redistribute it and/or | |
13672 | + * modify it under the terms of the GNU General Public License | |
13673 | + * as published by the Free Software Foundation; either version 2 | |
13674 | + * of the License, or (at your option) any later version. | |
13675 | + */ | |
13676 | +#ifndef __NWCLNX_H__ | |
13677 | +#define __NWCLNX_H__ | |
13678 | + | |
13679 | +#if 0 //sgled hack | |
13680 | +#else //sgled hack (up to endif) | |
13681 | + | |
13682 | +#define NW_MAX_TREE_NAME_LEN 33 | |
13683 | +#define NW_MAX_SERVICE_TYPE_LEN 49 | |
13684 | +/* Transport Type - (nuint32 value) */ | |
13685 | +#define NWC_TRAN_TYPE_IPX 0x0001 | |
13686 | +#define NWC_TRAN_TYPE_DDP 0x0003 | |
13687 | +#define NWC_TRAN_TYPE_ASP 0x0004 | |
13688 | +#define NWC_TRAN_TYPE_UDP 0x0008 | |
13689 | +#define NWC_TRAN_TYPE_TCP 0x0009 | |
13690 | +#define NWC_TRAN_TYPE_UDP6 0x000A | |
13691 | +#define NWC_TRAN_TYPE_TCP6 0x000B | |
13692 | +#define NWC_TRAN_TYPE_WILD 0x8000 | |
13693 | + | |
13694 | +// | |
13695 | +// DeviceIoControl requests for the NetWare Redirector | |
13696 | +// | |
13697 | +// Macro definition for defining DeviceIoControl function control codes. | |
13698 | +// The function codes 0 - 2047 are reserved for Microsoft. | |
13699 | +// Function codes 2048 - 4096 are reserved for customers. | |
13700 | +// The NetWare Redirector will use codes beginning at 3600. | |
13701 | +// | |
13702 | +// METHOD_NEITHER User buffers will be passed directly from the application | |
13703 | +// to the file system. The redirector is responsible for either probing | |
13704 | +// and locking the buffers or using a try - except around access of the | |
13705 | +// buffers. | |
13706 | + | |
13707 | +#define BASE_REQ_NUM 0x4a541000 | |
13708 | + | |
13709 | +// Connection functions | |
13710 | +#define NWC_OPEN_CONN_BY_NAME (BASE_REQ_NUM + 0) | |
13711 | +#define NWC_OPEN_CONN_BY_ADDRESS (BASE_REQ_NUM + 1) | |
13712 | +#define NWC_OPEN_CONN_BY_REFERENCE (BASE_REQ_NUM + 2) | |
13713 | +#define NWC_CLOSE_CONN (BASE_REQ_NUM + 3) | |
13714 | +#define NWC_SYS_CLOSE_CONN (BASE_REQ_NUM + 4) | |
13715 | +#define NWC_GET_CONN_INFO (BASE_REQ_NUM + 5) | |
13716 | +#define NWC_SET_CONN_INFO (BASE_REQ_NUM + 6) | |
13717 | +#define NWC_SCAN_CONN_INFO (BASE_REQ_NUM + 7) | |
13718 | +#define NWC_MAKE_CONN_PERMANENT (BASE_REQ_NUM + 8) | |
13719 | +#define NWC_LICENSE_CONN (BASE_REQ_NUM + 9) | |
13720 | +#define NWC_UNLICENSE_CONN (BASE_REQ_NUM + 10) | |
13721 | +#define NWC_GET_NUM_CONNS (BASE_REQ_NUM + 11) | |
13722 | +#define NWC_GET_PREFERRED_SERVER (BASE_REQ_NUM + 12) | |
13723 | +#define NWC_SET_PREFERRED_SERVER (BASE_REQ_NUM + 13) | |
13724 | +#define NWC_GET_PRIMARY_CONN (BASE_REQ_NUM + 14) | |
13725 | +#define NWC_SET_PRIMARY_CONN (BASE_REQ_NUM + 15) | |
13726 | + | |
13727 | +// Authentication functions | |
13728 | +#define NWC_CHANGE_KEY (BASE_REQ_NUM + 20) | |
13729 | +#define NWC_ENUMERATE_IDENTITIES (BASE_REQ_NUM + 21) | |
13730 | +#define NWC_GET_IDENTITY_INFO (BASE_REQ_NUM + 22) | |
13731 | +#define NWC_LOGIN_IDENTITY (BASE_REQ_NUM + 23) | |
13732 | +#define NWC_LOGOUT_IDENTITY (BASE_REQ_NUM + 24) | |
13733 | +#define NWC_SET_KEY (BASE_REQ_NUM + 25) | |
13734 | +#define NWC_VERIFY_KEY (BASE_REQ_NUM + 26) | |
13735 | +#define NWC_AUTHENTICATE_CONN_WITH_ID (BASE_REQ_NUM + 27) | |
13736 | +#define NWC_UNAUTHENTICATE_CONN (BASE_REQ_NUM + 28) | |
13737 | + | |
13738 | +// Directory Services functions | |
13739 | +#define NWC_GET_DEFAULT_NAME_CONTEXT (BASE_REQ_NUM + 30) | |
13740 | +#define NWC_SET_DEFAULT_NAME_CONTEXT (BASE_REQ_NUM + 31) | |
13741 | +#define NWC_GET_PREFERRED_DS_TREE (BASE_REQ_NUM + 32) | |
13742 | +#define NWC_SET_PREFERRED_DS_TREE (BASE_REQ_NUM + 33) | |
13743 | +#define NWC_GET_TREE_MONITORED_CONN_REF (BASE_REQ_NUM + 34) | |
13744 | +#define NWC_NDS_RESOLVE_NAME_TO_ID (BASE_REQ_NUM + 35) | |
13745 | + | |
13746 | +// NCP Request functions | |
13747 | +#define NWC_FRAGMENT_REQUEST (BASE_REQ_NUM + 40) | |
13748 | +#define NWC_NCP_ORDERED_REQUEST_ALL (BASE_REQ_NUM + 41) | |
13749 | +#define NWC_RAW_NCP_REQUEST (BASE_REQ_NUM + 42) | |
13750 | +#define NWC_RAW_NCP_REQUEST_ALL (BASE_REQ_NUM + 43) | |
13751 | + | |
13752 | +// File Handle Conversion functions | |
13753 | +#define NWC_CONVERT_LOCAL_HANDLE (BASE_REQ_NUM + 50) | |
13754 | +#define NWC_CONVERT_NETWARE_HANDLE (BASE_REQ_NUM + 51) | |
13755 | + | |
13756 | +// Misc. functions | |
13757 | +#define NWC_MAP_DRIVE (BASE_REQ_NUM + 60) | |
13758 | +#define NWC_UNMAP_DRIVE (BASE_REQ_NUM + 61) | |
13759 | +#define NWC_ENUMERATE_DRIVES (BASE_REQ_NUM + 62) | |
13760 | + | |
13761 | +#define NWC_GET_REQUESTER_VERSION (BASE_REQ_NUM + 63) | |
13762 | +#define NWC_QUERY_FEATURE (BASE_REQ_NUM + 64) | |
13763 | + | |
13764 | +#define NWC_GET_CONFIGURED_NSPS (BASE_REQ_NUM + 65) | |
13765 | + | |
13766 | +#define NWC_GET_MOUNT_PATH (BASE_REQ_NUM + 66) | |
13767 | + | |
13768 | +#define NWC_GET_BROADCAST_MESSAGE (BASE_REQ_NUM + 67) | |
13769 | + | |
13770 | +#endif //sgled hack ------------------------------- | |
13771 | + | |
13772 | +#define IOC_XPLAT 0x4a540002 | |
13773 | + | |
13774 | +typedef struct _XPLAT_ { | |
13775 | + int xfunction; | |
13776 | + unsigned long reqLen; | |
13777 | + void *reqData; | |
13778 | + unsigned long repLen; | |
13779 | + void *repData; | |
13780 | + | |
13781 | +} XPLAT, *PXPLAT; | |
13782 | + | |
13783 | +#if 0 | |
13784 | +N_EXTERN_LIBRARY(NWRCODE) | |
13785 | + NWCLnxReq | |
13786 | + (nuint32 request, nptr pInBuf, nuint32 inLen, nptr pOutBuf, nuint32 outLen); | |
13787 | +#endif | |
13788 | +// | |
13789 | +// Network Name Format Type | |
13790 | +// | |
13791 | + | |
13792 | +#define NWC_NAME_FORMAT_NDS 0x0001 | |
13793 | +#define NWC_NAME_FORMAT_BIND 0x0002 | |
13794 | +#define NWC_NAME_FORMAT_BDP 0x0004 | |
13795 | +#define NWC_NAME_FORMAT_NDS_TREE 0x0008 | |
13796 | +#define NWC_NAME_FORMAT_WILD 0x8000 | |
13797 | + | |
13798 | +// | |
13799 | +// API String Types | |
13800 | +// | |
13801 | + | |
13802 | +#define NWC_STRING_TYPE_ASCII 0x0001 // multi-byte, not really ascii | |
13803 | +#define NWC_STRING_TYPE_UNICODE 0x0002 | |
13804 | +#define NWC_STRING_TYPE_UTF8 0x0003 | |
13805 | + | |
13806 | +// | |
13807 | +// Open Connection Flags | |
13808 | +// | |
13809 | + | |
13810 | +#define NWC_OPEN_LICENSED 0x0001 | |
13811 | +#define NWC_OPEN_UNLICENSED 0x0002 | |
13812 | +#define NWC_OPEN_PRIVATE 0x0004 | |
13813 | +#define NWC_OPEN_PUBLIC 0x0008 | |
13814 | +#define NWC_OPEN_EXISTING_HANDLE 0x0010 | |
13815 | +#define NWC_OPEN_NO_HANDLE 0x0020 | |
13816 | +#define NWC_OPEN_PERMANENT 0x0040 | |
13817 | +#define NWC_OPEN_DISCONNECTED 0x0080 | |
13818 | +#define NWC_OPEN_NEAREST 0x0100 | |
13819 | +#define NWC_OPEN_IGNORE_CACHE 0x0200 | |
13820 | + | |
13821 | +// | |
13822 | +// Close Connection Flags | |
13823 | +// | |
13824 | + | |
13825 | +#define NWC_CLOSE_TEMPORARY 0x0000 | |
13826 | +#define NWC_CLOSE_PERMANENT 0x0001 | |
13827 | + | |
13828 | +// | |
13829 | +// Connection Information Levels | |
13830 | +// | |
13831 | + | |
13832 | +#define NWC_CONN_INFO_RETURN_ALL 0xFFFF | |
13833 | +#define NWC_CONN_INFO_RETURN_NONE 0x0000 | |
13834 | +#define NWC_CONN_INFO_VERSION 0x0001 | |
13835 | +#define NWC_CONN_INFO_AUTH_STATE 0x0002 | |
13836 | +#define NWC_CONN_INFO_BCAST_STATE 0x0003 | |
13837 | +#define NWC_CONN_INFO_CONN_REF 0x0004 | |
13838 | +#define NWC_CONN_INFO_TREE_NAME 0x0005 | |
13839 | +#define NWC_CONN_INFO_WORKGROUP_ID 0x0006 | |
13840 | +#define NWC_CONN_INFO_SECURITY_STATE 0x0007 | |
13841 | +#define NWC_CONN_INFO_CONN_NUMBER 0x0008 | |
13842 | +#define NWC_CONN_INFO_USER_ID 0x0009 | |
13843 | +#define NWC_CONN_INFO_SERVER_NAME 0x000A | |
13844 | +#define NWC_CONN_INFO_TRAN_ADDR 0x000B | |
13845 | +#define NWC_CONN_INFO_NDS_STATE 0x000C | |
13846 | +#define NWC_CONN_INFO_MAX_PACKET_SIZE 0x000D | |
13847 | +#define NWC_CONN_INFO_LICENSE_STATE 0x000E | |
13848 | +#define NWC_CONN_INFO_PUBLIC_STATE 0x000F | |
13849 | +#define NWC_CONN_INFO_SERVICE_TYPE 0x0010 | |
13850 | +#define NWC_CONN_INFO_DISTANCE 0x0011 | |
13851 | +#define NWC_CONN_INFO_SERVER_VERSION 0x0012 | |
13852 | +#define NWC_CONN_INFO_AUTH_ID 0x0013 | |
13853 | +#define NWC_CONN_INFO_SUSPENDED 0x0014 | |
13854 | +#define NWC_CONN_INFO_TREE_NAME_UNICODE 0x0015 | |
13855 | +#define NWC_CONN_INFO_SERVER_NAME_UNICODE 0x0016 | |
13856 | +#define NWC_CONN_INFO_LOCAL_TRAN_ADDR 0x0017 | |
13857 | +#define NWC_CONN_INFO_ALTERNATE_ADDR 0x0018 | |
13858 | +#define NWC_CONN_INFO_SERVER_GUID 0x0019 | |
13859 | + | |
13860 | +#define NWC_CONN_INFO_MAX_LEVEL 0x0014 | |
13861 | + | |
13862 | +// | |
13863 | +// Information Versions | |
13864 | +// | |
13865 | + | |
13866 | +#define NWC_INFO_VERSION_1 0x0001 | |
13867 | +#define NWC_INFO_VERSION_2 0x0002 | |
13868 | + | |
13869 | +// | |
13870 | +// Authentication State | |
13871 | +// | |
13872 | + | |
13873 | +#define NWC_AUTH_TYPE_NONE 0x0000 | |
13874 | +#define NWC_AUTH_TYPE_BINDERY 0x0001 | |
13875 | +#define NWC_AUTH_TYPE_NDS 0x0002 | |
13876 | +#define NWC_AUTH_TYPE_PNW 0x0003 | |
13877 | + | |
13878 | +#define NWC_AUTH_STATE_NONE 0x0000 | |
13879 | +#define NWC_AUTH_STATE_BINDERY 0x0001 | |
13880 | +#define NWC_AUTH_STATE_NDS 0x0002 | |
13881 | +#define NWC_AUTH_STATE_PNW 0x0003 | |
13882 | + | |
13883 | +// | |
13884 | +// Authentication Flags | |
13885 | +// | |
13886 | + | |
13887 | +#define NWC_AUTH_PRIVATE 0x00000004 | |
13888 | +#define NWC_AUTH_PUBLIC 0x00000008 | |
13889 | + | |
13890 | +// | |
13891 | +// Broadcast State | |
13892 | +// | |
13893 | + | |
13894 | +#define NWC_BCAST_PERMIT_ALL 0x0000 | |
13895 | +#define NWC_BCAST_PERMIT_SYSTEM 0x0001 | |
13896 | +#define NWC_BCAST_PERMIT_NONE 0x0002 | |
13897 | +#define NWC_BCAST_PERMIT_SYSTEM_POLLED 0x0003 | |
13898 | +#define NWC_BCAST_PERMIT_ALL_POLLED 0x0004 | |
13899 | + | |
13900 | +// | |
13901 | +// Broadcast State | |
13902 | +// | |
13903 | + | |
13904 | +#define NWC_NDS_NOT_CAPABLE 0x0000 | |
13905 | +#define NWC_NDS_CAPABLE 0x0001 | |
13906 | + | |
13907 | +// | |
13908 | +// License State | |
13909 | +// | |
13910 | + | |
13911 | +#define NWC_NOT_LICENSED 0x0000 | |
13912 | +#define NWC_CONNECTION_LICENSED 0x0001 | |
13913 | +#define NWC_HANDLE_LICENSED 0x0002 | |
13914 | + | |
13915 | +// | |
13916 | +// Public State | |
13917 | +// | |
13918 | + | |
13919 | +#define NWC_CONN_PUBLIC 0x0000 | |
13920 | +#define NWC_CONN_PRIVATE 0x0001 | |
13921 | + | |
13922 | +// | |
13923 | +// Scan Connection Information Flags used | |
13924 | +// for finding connections by specific criteria | |
13925 | +// | |
13926 | + | |
13927 | +#define NWC_MATCH_NOT_EQUALS 0x0000 | |
13928 | +#define NWC_MATCH_EQUALS 0x0001 | |
13929 | +#define NWC_RETURN_PUBLIC 0x0002 | |
13930 | +#define NWC_RETURN_PRIVATE 0x0004 | |
13931 | +#define NWC_RETURN_LICENSED 0x0008 | |
13932 | +#define NWC_RETURN_UNLICENSED 0x0010 | |
13933 | + | |
13934 | +// | |
13935 | +// Authentication Types | |
13936 | +// | |
13937 | + | |
13938 | +#define NWC_AUTHENT_BIND 0x0001 | |
13939 | +#define NWC_AUTHENT_NDS 0x0002 | |
13940 | +#define NWC_AUTHENT_PNW 0x0003 | |
13941 | + | |
13942 | +// | |
13943 | +// Disconnected info | |
13944 | +// | |
13945 | + | |
13946 | +#define NWC_SUSPENDED 0x0001 | |
13947 | + | |
13948 | +// | |
13949 | +// Maximum object lengths | |
13950 | +// | |
13951 | + | |
13952 | +#define MAX_DEVICE_LENGTH 16 | |
13953 | +#define MAX_NETWORK_NAME_LENGTH 1024 | |
13954 | +#define MAX_OBJECT_NAME_LENGTH 48 | |
13955 | +#define MAX_PASSWORD_LENGTH 128 | |
13956 | +#define MAX_SERVER_NAME_LENGTH 48 | |
13957 | +#define MAX_SERVICE_TYPE_LENGTH 48 | |
13958 | +#define MAX_TREE_NAME_LENGTH 32 | |
13959 | +#define MAX_ADDRESS_LENGTH 32 | |
13960 | +#define MAX_NAME_SERVICE_PROVIDERS 10 | |
13961 | + | |
13962 | +// | |
13963 | +// Flags for the GetBroadcastMessage API | |
13964 | +// | |
13965 | + | |
13966 | +#define MESSAGE_GET_NEXT_MESSAGE 1 | |
13967 | +#define MESSAGE_RECEIVED_FOR_CONNECTION 2 | |
13968 | + | |
13969 | +// | |
13970 | +// This constant must always be equal to the last device | |
13971 | +// | |
13972 | + | |
13973 | +#define DEVICE_LAST_DEVICE 0x00000003 | |
13974 | + | |
13975 | +// | |
13976 | +// Defined feature set provided by requester | |
13977 | +// | |
13978 | + | |
13979 | +#ifndef NWC_FEAT_PRIV_CONN | |
13980 | +#define NWC_FEAT_PRIV_CONN 1 | |
13981 | +#define NWC_FEAT_REQ_AUTH 2 | |
13982 | +#define NWC_FEAT_SECURITY 3 | |
13983 | +#define NWC_FEAT_NDS 4 | |
13984 | +#define NWC_FEAT_NDS_MTREE 5 | |
13985 | +#define NWC_FEAT_PRN_CAPTURE 6 | |
13986 | +#define NWC_FEAT_NDS_RESOLVE 7 | |
13987 | +#endif | |
13988 | + | |
13989 | +//===[ Type definitions ]================================================== | |
13990 | + | |
13991 | +// | |
13992 | +// Connection Handle returned from all OpenConnByXXXX calls | |
13993 | +// | |
13994 | + | |
13995 | +typedef u32 NW_CONN_HANDLE, *PNW_CONN_HANDLE; | |
13996 | + | |
13997 | +// | |
13998 | +// Authentication Id returned from the NwcCreateAuthenticationId call | |
13999 | +// | |
14000 | + | |
14001 | +typedef u32 AUTHEN_ID, *PAUTHEN_ID; | |
14002 | + | |
14003 | +// | |
14004 | +// Structure for defining what a transport | |
14005 | +// address looks like | |
14006 | +// | |
14007 | + | |
14008 | +typedef struct tagNwcTranAddr { | |
14009 | + u32 uTransportType; | |
14010 | + u32 uAddressLength; | |
14011 | + unsigned char *puAddress; | |
14012 | + | |
14013 | +} NwcTranAddr, *PNwcTranAddr; | |
14014 | + | |
14015 | +// | |
14016 | +// Structure for defining what a new transport | |
14017 | +// address looks like | |
14018 | +// | |
14019 | + | |
14020 | +typedef struct tagNwcTranAddrEx { | |
14021 | + u32 uTransportType; | |
14022 | + u32 uAddressLength; | |
14023 | + unsigned char buBuffer[MAX_ADDRESS_LENGTH]; | |
14024 | + | |
14025 | +} NwcTranAddrEx, *PNwcTranAddrEx; | |
14026 | + | |
14027 | +typedef struct tagNwcReferral { | |
14028 | + u32 uAddrCnt; | |
14029 | + PNwcTranAddrEx pAddrs; | |
14030 | + | |
14031 | +} NwcReferral, *PNwcReferral; | |
14032 | + | |
14033 | +typedef struct tagNwcServerVersion { | |
14034 | + u32 uMajorVersion; | |
14035 | + u16 uMinorVersion; | |
14036 | + u16 uRevision; | |
14037 | + | |
14038 | +} NwcServerVersion, *PNwcServerVersion; | |
14039 | + | |
14040 | +typedef struct tagNwcConnString { | |
14041 | + char *pString; | |
14042 | + u32 uStringType; | |
14043 | + u32 uNameFormatType; | |
14044 | + | |
14045 | +} NwcConnString, *PNwcConnString; | |
14046 | + | |
14047 | +//#if defined(NTYPES_H) | |
14048 | +//typedef NWCString NwcString, *PNwcString; | |
14049 | +//#else | |
14050 | +typedef struct tagNwcString { | |
14051 | + u32 DataType; | |
14052 | + u32 BuffSize; | |
14053 | + u32 DataLen; | |
14054 | + void *pBuffer; | |
14055 | + u32 CodePage; | |
14056 | + u32 CountryCode; | |
14057 | + | |
14058 | +} NwcString, *PNwcString; | |
14059 | +//#endif | |
14060 | + | |
14061 | +// | |
14062 | +// Structure used in NDS Resolve name | |
14063 | +// | |
14064 | + | |
14065 | +#define RESOLVE_INFO_SVC_V1_00 0x00FE0001 | |
14066 | + | |
14067 | +typedef struct tagNwcResolveInfo { | |
14068 | + u32 uResolveInfoVersion; | |
14069 | + u32 luFlags; | |
14070 | + u32 luReqFlags; | |
14071 | + u32 luReqScope; | |
14072 | + u32 luResolveType; | |
14073 | + u32 luRepFlags; | |
14074 | + u32 luResolvedOffset; | |
14075 | + u32 luDerefNameLen; | |
14076 | + u16 *pDerefName; | |
14077 | +} NwcResolveInfo, *PNwcResolveInfo; | |
14078 | + | |
14079 | +// | |
14080 | +// Definition of a fragment for the Raw NCP requests | |
14081 | +// | |
14082 | + | |
14083 | +typedef struct tagNwcFrag { | |
14084 | + void *pData; | |
14085 | + u32 uLength; | |
14086 | + | |
14087 | +} NwcFrag, *PNwcFrag; | |
14088 | + | |
14089 | +// | |
14090 | +// Current connection information available for | |
14091 | +// enumeration using GetConnInfo and ScanConnInfo | |
14092 | +// | |
14093 | + | |
14094 | +#define NW_INFO_BUFFER_SIZE NW_MAX_TREE_NAME_LEN + \ | |
14095 | + NW_MAX_TREE_NAME_LEN + \ | |
14096 | + NW_MAX_SERVICE_TYPE_LEN | |
14097 | + | |
14098 | +typedef struct tagNwcConnInfo { | |
14099 | + u32 uInfoVersion; | |
14100 | + u32 uAuthenticationState; | |
14101 | + u32 uBroadcastState; | |
14102 | + u32 uConnectionReference; | |
14103 | + u32 TreeNameOffset; | |
14104 | + u32 uSecurityState; | |
14105 | + u32 uConnectionNumber; | |
14106 | + u32 uUserId; | |
14107 | + u32 ServerNameOffset; | |
14108 | + u32 uNdsState; | |
14109 | + u32 uMaxPacketSize; | |
14110 | + u32 uLicenseState; | |
14111 | + u32 uPublicState; | |
14112 | + u32 bcastState; | |
14113 | + u32 ServiceTypeOffset; | |
14114 | + u32 uDistance; | |
14115 | + u32 uAuthId; | |
14116 | + u32 uDisconnected; | |
14117 | + NwcServerVersion serverVersion; | |
14118 | + NwcTranAddrEx tranAddress; | |
14119 | + unsigned char buBuffer[NW_INFO_BUFFER_SIZE]; | |
14120 | + | |
14121 | +} NwcConnInfo, *PNwcConnInfo; | |
14122 | + | |
14123 | +// | |
14124 | +// Get Browse Connection References | |
14125 | +// | |
14126 | + | |
14127 | +typedef struct _GetBrowseConnectionsRec { | |
14128 | + | |
14129 | + u32 recordSize; | |
14130 | + u32 numConnectionsReturned; | |
14131 | + u32 numConnectionsAvailable; | |
14132 | + u32 connReferences[1]; | |
14133 | + | |
14134 | +} GetBrowseConnectionRec, *PGetBrowseConnectionRec; | |
14135 | + | |
14136 | +//++======================================================================= | |
14137 | +// API Name: NwcClearBroadcastMessage | |
14138 | +// | |
14139 | +// Arguments In: NONE | |
14140 | +// | |
14141 | +// Arguments Out: NONE | |
14142 | +// | |
14143 | +// Returns: STATUS_SUCCESS | |
14144 | +// | |
14145 | +// Abstract: This API is clears the broadcast message buffer. | |
14146 | +// | |
14147 | +// Notes: | |
14148 | +// | |
14149 | +// Environment: PASSIVE_LEVEL, LINUX | |
14150 | +// | |
14151 | +//=======================================================================-- | |
14152 | + | |
14153 | +//++======================================================================= | |
14154 | +// API Name: NwcCloseConn | |
14155 | +// | |
14156 | +// Arguments In: ConnHandle - The handle to a connection that is | |
14157 | +// no longer needed. | |
14158 | +// | |
14159 | +// Arguments Out: NONE | |
14160 | +// | |
14161 | +// Returns: STATUS_SUCCESS | |
14162 | +// NWE_ACCESS_VIOLATION | |
14163 | +// NWE_CONN_INVALID | |
14164 | +// NWE_INVALID_OWNER | |
14165 | +// NWE_RESOURCE_LOCK | |
14166 | +// | |
14167 | +// Abstract: This API is used by an application that opened the | |
14168 | +// connection using one of the open connection calls | |
14169 | +// is finished using the connection. After it is closed, | |
14170 | +// the handle may no longer be used to access the | |
14171 | +// connection. | |
14172 | +// | |
14173 | +// Notes: | |
14174 | +// | |
14175 | +// Environment: PASSIVE_LEVEL, LINUX | |
14176 | +// | |
14177 | +//=======================================================================-- | |
14178 | + | |
14179 | +typedef struct tagNwcCloseConn { | |
14180 | + NW_CONN_HANDLE ConnHandle; | |
14181 | + | |
14182 | +} NwcCloseConn, *PNwcCloseConn; | |
14183 | + | |
14184 | +//++======================================================================= | |
14185 | +// API Name: NwcConvertLocalFileHandle | |
14186 | +// | |
14187 | +// Arguments In: NONE | |
14188 | +// | |
14189 | +// Arguments Out: uConnReference - The connection reference associated | |
14190 | +// with the returned NetWare file handle. | |
14191 | +// | |
14192 | +// pNetWareFileHandle - The six byte NetWare file handle | |
14193 | +// associated with the given local file handle. | |
14194 | +// | |
14195 | +// Returns: STATUS_SUCCESS | |
14196 | +// NWE_ACCESS_VIOLATION | |
14197 | +// NWE_RESOURCE_NOT_OWNED | |
14198 | +// | |
14199 | +// Abstract: This API is used to return the NetWare handle that | |
14200 | +// has been associated to a local file handle. | |
14201 | +// In addition to returning the NetWare file handle, | |
14202 | +// this API also returns the connection reference to | |
14203 | +// the connection that owns the file. | |
14204 | +// | |
14205 | +// Notes: This API does not create a new NetWare handle, it | |
14206 | +// only returns the existing handle associated to the | |
14207 | +// local handle. | |
14208 | +// | |
14209 | +// Environment: PASSIVE_LEVEL, LINUX | |
14210 | +// | |
14211 | +//=======================================================================-- | |
14212 | + | |
14213 | +typedef struct tagNwcConvertLocalHandle { | |
14214 | + u32 uConnReference; | |
14215 | + unsigned char NetWareHandle[6]; | |
14216 | + | |
14217 | +} NwcConvertLocalHandle, *PNwcConvertLocalHandle; | |
14218 | + | |
14219 | +//++======================================================================= | |
14220 | +// API Name: NwcConvertNetWareHandle | |
14221 | +// | |
14222 | +// Arguments In: ConnHandle - The connection associated with the | |
14223 | +// NetWare file handle to convert. | |
14224 | +// | |
14225 | +// uAccessMode - The access rights to be used when | |
14226 | +// allocating the local file handle. | |
14227 | +// | |
14228 | +// pNetWareHandle - The NetWare handle that will be | |
14229 | +// bound to the new local handle being created. | |
14230 | +// | |
14231 | +// uFileSize - The current file size of the NetWare | |
14232 | +// file associated with the given NetWare file handle. | |
14233 | +// | |
14234 | +// Arguments Out: NONE | |
14235 | +// | |
14236 | +// Returns: STATUS_SUCCESS | |
14237 | +// NWE_ACCESS_VIOLATION | |
14238 | +// NWE_RESOURCE_NOT_OWNED | |
14239 | +// | |
14240 | +// Abstract: This API is used to convert a NetWare file handle | |
14241 | +// to a local file handle. | |
14242 | +// | |
14243 | +// The local handle must have been created previously | |
14244 | +// by doing a local open to \Special\$Special.net. | |
14245 | +// | |
14246 | +// Then an Ioctl to this function must be issued using the | |
14247 | +// handle returned from the special net open. | |
14248 | +// | |
14249 | +// Notes: After making this call, the NetWare file handle | |
14250 | +// should not be closed using the NetWare library | |
14251 | +// call, instead it should be closed using the local | |
14252 | +// operating system's close call. | |
14253 | +// | |
14254 | +// Environment: PASSIVE_LEVEL, LINUX | |
14255 | +// | |
14256 | +//=======================================================================-- | |
14257 | +typedef struct tagNwcConvertNetWareHandle { | |
14258 | + NW_CONN_HANDLE ConnHandle; | |
14259 | + u32 uAccessMode; | |
14260 | + unsigned char NetWareHandle[6]; | |
14261 | + u32 uFileSize; | |
14262 | +} NwcConvertNetWareHandle, *PNwcConvertNetWareHandle; | |
14263 | + | |
14264 | +//++======================================================================= | |
14265 | +// API Name: NwcFragmentRequest | |
14266 | +// | |
14267 | +// Arguments In: ConnHandle | |
14268 | +// The connection handle the request is being | |
14269 | +// directed to. | |
14270 | +// | |
14271 | +// uFunction | |
14272 | +// The NCP function to be called, should be 104 | |
14273 | +// for NDS fragger/defragger requests. | |
14274 | +// | |
14275 | +// uSubFunction | |
14276 | +// The NCP subfunction to be called, should be | |
14277 | +// 2 for NDS fragger/defragger requests. | |
14278 | +// | |
14279 | +// uVerb | |
14280 | +// The actual operation to be completed on the | |
14281 | +// server backend. | |
14282 | +// | |
14283 | +// flags | |
14284 | +// Currently not implemented. Reserved for | |
14285 | +// future use. | |
14286 | +// | |
14287 | +// uNumRequestFrags | |
14288 | +// The number of fragments that the request packet | |
14289 | +// has been broken into. | |
14290 | +// | |
14291 | +// pRequestFrags | |
14292 | +// List of fragments that make up the request packet. | |
14293 | +// Each fragment includes the length of the fragment | |
14294 | +// data and a pointer to the data. | |
14295 | +// | |
14296 | +// uNumReplyFrags | |
14297 | +// The number of fragments the reply packet has been | |
14298 | +// broken into. | |
14299 | +// | |
14300 | +// Arguments Out: pReplyFrags | |
14301 | +// List of fragments that make up the reply packet. | |
14302 | +// Each fragment includes the length of the fragment | |
14303 | +// data and a pointer to the data. | |
14304 | +// | |
14305 | +// uActualReplyLength | |
14306 | +// Total size of the reply packet after any header | |
14307 | +// and tail information is removed. | |
14308 | +// | |
14309 | +// Returns: STATUS_SUCCESS | |
14310 | +// NWE_ACCESS_VIOLATION | |
14311 | +// NWE_CONN_INVALID | |
14312 | +// | |
14313 | +// Abstract: API for sending large NCP/NDS packets that are | |
14314 | +// larger than the max MTU size for the underlying | |
14315 | +// network. | |
14316 | +// | |
14317 | +// Notes: | |
14318 | +// | |
14319 | +// Environment: PASSIVE_LEVEL, LINUX | |
14320 | +// | |
14321 | +//=======================================================================-- | |
14322 | +typedef struct tagNwcFragmentRequest { | |
14323 | + NW_CONN_HANDLE ConnHandle; | |
14324 | + u32 uFunction; | |
14325 | + u32 uSubFunction; | |
14326 | + u32 uVerb; | |
14327 | + u32 flags; | |
14328 | + u32 uNumRequestFrags; | |
14329 | + PNwcFrag pRequestFrags; | |
14330 | + u32 uNumReplyFrags; | |
14331 | + PNwcFrag pReplyFrags; | |
14332 | + u32 uActualReplyLength; | |
14333 | +} NwcFragmentRequest, *PNwcFragmentRequest; | |
14334 | + | |
14335 | +//++======================================================================= | |
14336 | +// API Name: NwcGetBroadcastMessage | |
14337 | +// | |
14338 | +// Arguments In: uMessageFlags - Not currently used. | |
14339 | +// | |
14340 | +// uConnReference - connection reference for | |
14341 | +// pending message. | |
14342 | +// | |
14343 | +// messageLen - length of message buffer. | |
14344 | +// | |
14345 | +// message - message buffer | |
14346 | +// | |
14347 | +// Arguments Out: messageLen - length of the message | |
14348 | +// | |
14349 | +// Returns: STATUS_SUCCESS | |
14350 | +// NWE_ACCESS_VIOLATION | |
14351 | +// NWE_NO_MORE_ENTRIES | |
14352 | +// | |
14353 | +// Abstract: This API is used for notifying a caller of pending | |
14354 | +// broadcast messages on the server. | |
14355 | +// | |
14356 | +// Notes: | |
14357 | +// | |
14358 | +// Environment: PASSIVE_LEVEL, LINUX | |
14359 | +// | |
14360 | +//=======================================================================-- | |
14361 | + | |
14362 | +/* jlt | |
14363 | +typedef struct tagNwcGetBroadcastMessage | |
14364 | +{ | |
14365 | + u32 uMessageFlags; | |
14366 | + u32 uConnReference; | |
14367 | + u32 messageLen; | |
14368 | + unsigned char message[255]; | |
14369 | + | |
14370 | +} NwcGetBroadcastMessage, *PNwcGetBroadcastMessage; | |
14371 | +*/ | |
14372 | + | |
14373 | +//++======================================================================= | |
14374 | +// API Name: NwcGetConnInfo | |
14375 | +// | |
14376 | +// Arguments In: ConnHandle - Connection handle for the connection to | |
14377 | +// get information on. | |
14378 | +// uInfoLevel - Specifies what information should be | |
14379 | +// returned. | |
14380 | +// uInfoLen - Length of the ConnInfo buffer. | |
14381 | +// | |
14382 | +// Arguments Out: pConnInfo - A pointer to a buffer to return connection | |
14383 | +// information in. If the caller is requesting all | |
14384 | +// information the pointer will be to a structure of | |
14385 | +// type NwcConnInfo. If the caller is requesting just | |
14386 | +// a single piece of information, the pointer is the | |
14387 | +// type of information being requested. | |
14388 | +// | |
14389 | +// Returns: STATUS_SUCCESS | |
14390 | +// NWE_ACCESS_VIOLATION | |
14391 | +// NWE_CONN_INVALID | |
14392 | +// NWE_INVALID_OWNER | |
14393 | +// NWE_RESOURCE_LOCK | |
14394 | +// NWE_STRING_TRANSLATION | |
14395 | +// | |
14396 | +// Abstract: This API returns connection information for the specified | |
14397 | +// connection. The requester can receive one piece of | |
14398 | +// information or the whole information structure. | |
14399 | +// Some of the entries in the NwcConnInfo structure are | |
14400 | +// pointers. The requester is responsible for supplying | |
14401 | +// valid pointers for any info specified to be returned. | |
14402 | +// If the requester does not want a piece of information | |
14403 | +// returned, a NULL pointer should be placed in the field. | |
14404 | +// | |
14405 | +// Notes: | |
14406 | +// | |
14407 | +// Environment: PASSIVE_LEVEL, LINUX | |
14408 | +// | |
14409 | +//=======================================================================-- | |
14410 | + | |
14411 | +typedef struct tagNwcGetConnInfo { | |
14412 | + NW_CONN_HANDLE ConnHandle; | |
14413 | + u32 uInfoLevel; | |
14414 | + u32 uInfoLength; | |
14415 | + void *pConnInfo; | |
14416 | + | |
14417 | +} NwcGetConnInfo, *PNwcGetConnInfo; | |
14418 | + | |
14419 | +//++======================================================================= | |
14420 | +// API Name: NwcGetDefaultNameContext | |
14421 | +// | |
14422 | +// Arguments In:: uTreeLength - Length of tree string. | |
14423 | +// | |
14424 | +// pDsTreeName - Pointer to tree string (multi-byte) | |
14425 | +// | |
14426 | +// pNameLength - On input, this is the length of the | |
14427 | +// name context buffer. On output, this is the actual | |
14428 | +// length of the name context string. | |
14429 | +// | |
14430 | +// Arguments Out: pNameContext - The buffer to copy the default name | |
14431 | +// context into (multi-byte). | |
14432 | +// | |
14433 | +// Returns: STATUS_SUCCESS | |
14434 | +// NWE_ACCESS_VIOLATION | |
14435 | +// NWE_BUFFER_OVERFLOW | |
14436 | +// NWE_OBJECT_NOT_FOUND | |
14437 | +// NWE_PARAM_INVALID | |
14438 | +// NWE_RESOURCE_LOCK | |
14439 | +// | |
14440 | +// Abstract: This API returns the default name context that | |
14441 | +// was previously set either by configuration or | |
14442 | +// by calling NwcSetDefaultNameContext. | |
14443 | +// | |
14444 | +// Notes: | |
14445 | +// | |
14446 | +// Environment: PASSIVE_LEVEL, LINUX | |
14447 | +// | |
14448 | +//=======================================================================-- | |
14449 | + | |
14450 | +typedef struct tagNwcGetDefaultNameContext { | |
14451 | + u32 uTreeLength; | |
14452 | + unsigned char *pDsTreeName; | |
14453 | + u32 uNameLength; | |
14454 | +// unsigned short *pNameContext; | |
14455 | + unsigned char *pNameContext; | |
14456 | + | |
14457 | +} NwcGetDefaultNameContext, *PNwcGetDefaultNameContext; | |
14458 | + | |
14459 | +//++======================================================================= | |
14460 | +// API Name: NwcGetTreeMonitoredConnReference | |
14461 | +// | |
14462 | +// Arguments In: NONE | |
14463 | +// | |
14464 | +// Arguments Out: uConnReference - The connection reference associated | |
14465 | +// with the monitored connection. | |
14466 | +// | |
14467 | +// Returns: STATUS_SUCCESS | |
14468 | +// NWE_ACCESS_VIOLATION | |
14469 | +// NWE_OBJECT_NOT_FOUND | |
14470 | +// NWE_RESOURCE_LOCK | |
14471 | +// | |
14472 | +// Abstract: This call returns a connection reference to a | |
14473 | +// connection that is monitored. This connection | |
14474 | +// reference may be used to open the connection. | |
14475 | +// | |
14476 | +// Notes: | |
14477 | +// | |
14478 | +// Environment: PASSIVE_LEVEL, LINUX | |
14479 | +// | |
14480 | +//=======================================================================-- | |
14481 | + | |
14482 | +typedef struct tagNwcGetTreeMonitoredConnRef { | |
14483 | + PNwcString pTreeName; | |
14484 | + u32 uConnReference; | |
14485 | + | |
14486 | +} NwcGetTreeMonitoredConnRef, *PNwcGetTreeMonitoredConnRef; | |
14487 | + | |
14488 | +//++======================================================================= | |
14489 | +// API Name: NwcGetNumberConns | |
14490 | +// | |
14491 | +// Arguments In: NONE | |
14492 | +// | |
14493 | +// Arguments Out: uMaxConns - The maximum number of connections | |
14494 | +// supported by the redirector. -1 for dynamic. | |
14495 | +// | |
14496 | +// uPublicConns - The current number of public | |
14497 | +// connections. | |
14498 | +// | |
14499 | +// uTasksPrivateConns - The current number of private | |
14500 | +// connections that are owned by the calling process. | |
14501 | +// | |
14502 | +// uOtherPrivateConns - The current number of private | |
14503 | +// connections that are not owned by the calling | |
14504 | +// process. | |
14505 | +// | |
14506 | +// Returns: STATUS_SUCCESS | |
14507 | +// NWE_ACCESS_VIOLATION | |
14508 | +// NWE_RESOURCE_LOCK | |
14509 | +// | |
14510 | +// Abstract: This API returns the current number of connections | |
14511 | +// as well as the maximum number of supported | |
14512 | +// connections. If the requester/redirector supports | |
14513 | +// a dynamic connection table, -1 will be returned | |
14514 | +// in the uMaxConns field. | |
14515 | +// | |
14516 | +// Notes: | |
14517 | +// | |
14518 | +// Environment: PASSIVE_LEVEL, LINUX | |
14519 | +// | |
14520 | +//=======================================================================-- | |
14521 | + | |
14522 | +typedef struct tagNwcGetNumberConns { | |
14523 | + u32 uMaxConns; | |
14524 | + u32 uPublicConns; | |
14525 | + u32 uTasksPrivateConns; | |
14526 | + u32 uOtherPrivateConns; | |
14527 | + | |
14528 | +} NwcGetNumberConns, *PNwcGetNumberConns; | |
14529 | + | |
14530 | +//++======================================================================= | |
14531 | +// API Name: NwcGetPreferredServer | |
14532 | +// | |
14533 | +// Arguments In: uServerNameLength - On input, this is the length | |
14534 | +// in bytes of the server buffer. On output, this is | |
14535 | +// the actual length of the server name string in bytes. | |
14536 | +// | |
14537 | +// Arguments Out: pServerName - The buffer to copy the preferred server | |
14538 | +// name into. | |
14539 | +// | |
14540 | +// Returns: STATUS_SUCCESS | |
14541 | +// NWE_ACCESS_VIOLATION | |
14542 | +// NWE_BUFFER_OVERFLOW | |
14543 | +// NWE_OBJECT_NOT_FOUND | |
14544 | +// NWE_PARAM_INVALID | |
14545 | +// NWE_RESOURCE_LOCK | |
14546 | +// | |
14547 | +// Abstract: This API returns the configured preferred bindery | |
14548 | +// server previously set either by configuration or | |
14549 | +// by calling NwcSetPreferredServer. | |
14550 | +// | |
14551 | +// Notes: | |
14552 | +// | |
14553 | +// Environment: PASSIVE_LEVEL, LINUX | |
14554 | +// | |
14555 | +//=======================================================================-- | |
14556 | + | |
14557 | +typedef struct tagNwcGetPreferredServer { | |
14558 | + u32 uServerNameLength; | |
14559 | + char *pServerName; | |
14560 | + | |
14561 | +} NwcGetPreferredServer, *PNwcGetPreferredServer; | |
14562 | + | |
14563 | +//++======================================================================= | |
14564 | +// API Name: NwcGetPreferredDsTree | |
14565 | +// | |
14566 | +// Arguments In: uTreeLength - On input, this is the length in bytes | |
14567 | +// of the DS tree name buffer. On output, this is the | |
14568 | +// actual length of the DS tree name string in bytes. | |
14569 | +// | |
14570 | +// Arguments Out: pDsTreeName - The buffer to copy the DS tree name into. | |
14571 | +// | |
14572 | +// Returns: STATUS_SUCCESS | |
14573 | +// NWE_ACCESS_VIOLATION | |
14574 | +// NWE_BUFFER_OVERFLOW | |
14575 | +// NWE_PARAM_INVALID | |
14576 | +// NWE_DS_PREFERRED_NOT_FOUND | |
14577 | +// NWE_RESOURCE_LOCK | |
14578 | +// | |
14579 | +// Abstract: This API returns the preferred DS tree name that was | |
14580 | +// previously set either by configuration or | |
14581 | +// by calling NwcSetPreferredDsTree. | |
14582 | +// | |
14583 | +// Notes: | |
14584 | +// | |
14585 | +// Environment: PASSIVE_LEVEL, LINUX | |
14586 | +// | |
14587 | +//=======================================================================-- | |
14588 | +typedef struct tagNwcGetPreferredDsTree { | |
14589 | + u32 uTreeLength; | |
14590 | + unsigned char *pDsTreeName; | |
14591 | +} NwcGetPreferredDsTree, *PNwcGetPreferredDsTree; | |
14592 | + | |
14593 | +//++======================================================================= | |
14594 | +// API Name: NwcGetPrimaryConnection | |
14595 | +// | |
14596 | +// Arguments In: NONE | |
14597 | +// | |
14598 | +// Arguments Out: uConnReference - Reference to the primary connection. | |
14599 | +// | |
14600 | +// Returns: STATUS_SUCCESS | |
14601 | +// NWE_ACCESS_VIOLATION | |
14602 | +// NWE_CONN_PRIMARY_NOT_SET | |
14603 | +// | |
14604 | +// Abstract: This API returns the reference to the current primary | |
14605 | +// connection in the redirector. | |
14606 | +// | |
14607 | +// Notes: | |
14608 | +// | |
14609 | +// Environment: PASSIVE_LEVEL, LINUX | |
14610 | +// | |
14611 | +//=======================================================================-- | |
14612 | + | |
14613 | +typedef struct tagNwcGetPrimaryConnection { | |
14614 | + u32 uConnReference; | |
14615 | + | |
14616 | +} NwcGetPrimaryConnection, *PNwcGetPrimaryConnection; | |
14617 | + | |
14618 | +//++======================================================================= | |
14619 | +// API Name: NwcGetRequesterVersion | |
14620 | +// | |
14621 | +// Arguments In: NONE | |
14622 | +// | |
14623 | +// Arguments Out: uMajorVersion | |
14624 | +// uMinorVersion | |
14625 | +// uRevision | |
14626 | +// | |
14627 | +// Returns: STATUS_SUCCESS | |
14628 | +// NWE_ACCESS_VIOLATION | |
14629 | +// | |
14630 | +// Abstract: This API returns the major version, minor version and | |
14631 | +// revision of the requester/redirector. | |
14632 | +// | |
14633 | +// Notes: | |
14634 | +// | |
14635 | +// Environment: PASSIVE_LEVEL, LINUX | |
14636 | +// | |
14637 | +//=======================================================================-- | |
14638 | + | |
14639 | +typedef struct tagNwcGetRequesterVersion { | |
14640 | + u32 uMajorVersion; | |
14641 | + u32 uMinorVersion; | |
14642 | + u32 uRevision; | |
14643 | + | |
14644 | +} NwcGetRequesterVersion, *PNwcGetRequesterVersion; | |
14645 | + | |
14646 | +//++======================================================================= | |
14647 | +// API Name: NwcLicenseConn | |
14648 | +// | |
14649 | +// Arguments In: ConnHandle - An open connection handle that is in | |
14650 | +// an unlicensed state. | |
14651 | +// | |
14652 | +// Arguments Out: NONE | |
14653 | +// | |
14654 | +// Returns: STATUS_SUCCESS | |
14655 | +// NWE_ACCESS_VIOLATION | |
14656 | +// NWE_CONN_INVALID | |
14657 | +// NWE_HANDLE_ALREADY_LICENSED | |
14658 | +// | |
14659 | +// | |
14660 | +// Abstract: This API changes a connections state to licensed. | |
14661 | +// The licensed count will be incremented, and if | |
14662 | +// necessary, the license NCP will be sent. | |
14663 | +// If this handle is already in a licensed state, | |
14664 | +// an error will be returned. | |
14665 | +// | |
14666 | +// Notes: | |
14667 | +// | |
14668 | +// Environment: PASSIVE_LEVEL, LINUX | |
14669 | +// | |
14670 | +//=======================================================================-- | |
14671 | + | |
14672 | +typedef struct tagNwcLicenseConn { | |
14673 | + NW_CONN_HANDLE ConnHandle; | |
14674 | + | |
14675 | +} NwcLicenseConn, *PNwcLicenseConn; | |
14676 | + | |
14677 | +//++======================================================================= | |
14678 | +// API Name: NwcMakeConnPermanent | |
14679 | +// | |
14680 | +// Arguments In: ConnHandle - An open connection handle associated | |
14681 | +// with the connection to be made permanent. | |
14682 | +// | |
14683 | +// Arguments Out: NONE | |
14684 | +// | |
14685 | +// Returns: NWE_ACCESS_VIOLATION | |
14686 | +// NWE_CONN_INVALID | |
14687 | +// NWE_INVALID_OWNER | |
14688 | +// | |
14689 | +// Abstract: This API is used to keep the connection from being | |
14690 | +// destroyed until a NwcSysCloseConn request is made | |
14691 | +// on the connection. This allows the connection to | |
14692 | +// remain after all processes that have the | |
14693 | +// connection open terminate. | |
14694 | +// | |
14695 | +// Notes: | |
14696 | +// | |
14697 | +// Environment: PASSIVE_LEVEL, LINUX | |
14698 | +// | |
14699 | +//=======================================================================-- | |
14700 | + | |
14701 | +typedef struct tagNwcMakeConnPermanent { | |
14702 | + NW_CONN_HANDLE ConnHandle; | |
14703 | + | |
14704 | +} NwcMakeConnPermanent, *PNwcMakeConnPermanent; | |
14705 | + | |
14706 | +//++======================================================================= | |
14707 | +// API Name: NwcMapDrive | |
14708 | +// | |
14709 | +// Arguments In: ConnHandle - The connection handle of the server | |
14710 | +// to where the drive is to be mapped. | |
14711 | +// | |
14712 | +// LocalUID - Local user ID | |
14713 | +// | |
14714 | +// LocalPathLen - Length of local/link directory path string, | |
14715 | +// including nul terminator. | |
14716 | +// | |
14717 | +// LocalPathOffset - Offset of local directory path that will | |
14718 | +// be mapped to NetWare directory path. | |
14719 | +// | |
14720 | +// NetWarePathLen - Offset of NetWare directory path, | |
14721 | +// including nul terminator. | |
14722 | +// | |
14723 | +// NetWarePathOffset - Offset of NetWare directory path in | |
14724 | +// structure. | |
14725 | +// | |
14726 | +// Arguments Out: NONE | |
14727 | +// | |
14728 | +// Returns: STATUS_SUCCESS | |
14729 | +// NWE_ACCESS_VIOLATION | |
14730 | +// NWE_CONN_INVALID | |
14731 | +// NWE_INSUFFICIENT_RESOURCES | |
14732 | +// NWE_STRING_TRANSLATION | |
14733 | +// | |
14734 | +// Abstract: This API maps the target drive to the specified | |
14735 | +// directory. | |
14736 | +// | |
14737 | +// Notes: | |
14738 | +// | |
14739 | +// Environment: PASSIVE_LEVEL, LINUX | |
14740 | +// | |
14741 | +//=======================================================================-- | |
14742 | + | |
14743 | +typedef struct tagNwcMapDrive { | |
14744 | + NW_CONN_HANDLE ConnHandle; | |
14745 | + u32 LocalUID; | |
14746 | + u32 LinkPathLen; | |
14747 | + u32 LinkPathOffset; | |
14748 | + u32 DestPathLen; | |
14749 | + u32 DestPathOffset; | |
14750 | + | |
14751 | +} NwcMapDrive, *PNwcMapDrive; | |
14752 | + | |
14753 | +//++======================================================================= | |
14754 | +// API Name: NwcUnmapDrive | |
14755 | +// | |
14756 | +// Arguments In: LinkPathLen - Length of local/link path string, | |
14757 | +// including nul terminator. | |
14758 | +// | |
14759 | +// LinkPath - Local/link path in structure | |
14760 | +// to be unmapped | |
14761 | +// | |
14762 | +// Arguments Out: NONE | |
14763 | +// | |
14764 | +// Returns: STATUS_SUCCESS | |
14765 | +// NWE_ACCESS_VIOLATION | |
14766 | +// NWE_PARAM_INVALID | |
14767 | +// | |
14768 | +// Abstract: This API deletes a network drive mapping. | |
14769 | +// | |
14770 | +// Notes: | |
14771 | +// | |
14772 | +// Environment: PASSIVE_LEVEL, LINUX | |
14773 | +// | |
14774 | +//=======================================================================-- | |
14775 | + | |
14776 | +typedef struct tagNwcUnmapDrive { | |
14777 | + u32 LinkPathLen; | |
14778 | + unsigned char LinkPath[1]; | |
14779 | + | |
14780 | +} NwcUnmapDrive, *PNwcUnmapDrive; | |
14781 | + | |
14782 | +//++======================================================================= | |
14783 | +// API Name: NWCGetMappedDrives | |
14784 | +// | |
14785 | +// Arguments In: | |
14786 | +// Arguments Out: | |
14787 | +// | |
14788 | +// Returns: STATUS_SUCCESS | |
14789 | +// NWE_ACCESS_VIOLATION | |
14790 | +// NWE_BUFFER_OVERFLOW | |
14791 | +// | |
14792 | +// Abstract: This API returns the NetWare mapped drive info | |
14793 | +// per user. | |
14794 | +// | |
14795 | +// Notes: | |
14796 | +// | |
14797 | +// Environment: PASSIVE_LEVEL, LINUX | |
14798 | +// | |
14799 | +//=======================================================================-- | |
14800 | + | |
14801 | +typedef struct tagNwcMapDriveElem { | |
14802 | + u32 ElemLen; // Lenght of drive element | |
14803 | + u32 ConnRefernce; // Connection reference | |
14804 | + u32 LinkPathLen; // Local/link dir path, length includes nul | |
14805 | + unsigned char LinkPath[1]; // LinkPath[LinkPathLen] | |
14806 | +// u32 DirPathLen; // NetWare dir path, length includes nul (vol:path) | |
14807 | +// unsigned char DirPath[DirPathLen]; // NetWarePath[DirPathLen] | |
14808 | +} NwcMapDriveElem, *PNwcMapDriveElem; | |
14809 | + | |
14810 | +typedef struct tagNwcMapDriveBuff { | |
14811 | + u32 MapCount; // Number of mapped drives | |
14812 | + NwcMapDriveElem MapDriveElem[1]; // MapDriveElem[MapCount] | |
14813 | + | |
14814 | +} NwcMapDriveBuff, *PNwcMapDriveBuff; | |
14815 | + | |
14816 | +typedef struct tagNwcGetMappedDrives { | |
14817 | + u32 MapBuffLen; // Buffer length (actual buffer size returned) | |
14818 | + PNwcMapDriveBuff MapBuffer; // Pointer to map buffer | |
14819 | + | |
14820 | +} NwcGetMappedDrives, *PNwcGetMappedDrives; | |
14821 | + | |
14822 | +//++======================================================================= | |
14823 | +// API Name: NwcGetMountPath | |
14824 | +// | |
14825 | +// Arguments In: MountPathLen - Length of mount path buffer | |
14826 | +// including nul terminator. | |
14827 | +// | |
14828 | +// Arguments Out: MountPath - Pointer to mount path buffer | |
14829 | +// | |
14830 | +// Returns: STATUS_SUCCESS | |
14831 | +// NWE_ACCESS_VIOLATION | |
14832 | +// NWE_BUFFER_OVERFLOW | |
14833 | +// | |
14834 | +// Abstract: This API returns the mount point of the NOVFS file | |
14835 | +// system. | |
14836 | +// | |
14837 | +// Notes: | |
14838 | +// | |
14839 | +// Environment: PASSIVE_LEVEL, LINUX | |
14840 | +// | |
14841 | +//=======================================================================-- | |
14842 | + | |
14843 | +typedef struct tagNwcGetMountPath { | |
14844 | + u32 MountPathLen; | |
14845 | + unsigned char *pMountPath; | |
14846 | + | |
14847 | +} NwcGetMountPath, *PNwcGetMountPath; | |
14848 | + | |
14849 | +//++======================================================================= | |
14850 | +// API Name: NwcMonitorConn | |
14851 | +// | |
14852 | +// Arguments In: ConnHandle - The handle associated with the connection | |
14853 | +// that is to be marked as the monitored connection. | |
14854 | +// | |
14855 | +// Arguments Out: NONE | |
14856 | +// | |
14857 | +// Returns: STATUS_SUCCESS | |
14858 | +// NWE_ACCESS_VIOLATION | |
14859 | +// NWE_RESOURCE_LOCK | |
14860 | +// NWE_CONN_INVALID | |
14861 | +// | |
14862 | +// | |
14863 | +// Abstract: This call marks the connection associated with the | |
14864 | +// connection handle as monitored. | |
14865 | +// | |
14866 | +// Notes: | |
14867 | +// | |
14868 | +// Environment: PASSIVE_LEVEL, LINUX | |
14869 | +// | |
14870 | +//=======================================================================-- | |
14871 | + | |
14872 | +typedef struct tagNwcMonitorConn { | |
14873 | + NW_CONN_HANDLE ConnHandle; | |
14874 | + | |
14875 | +} NwcMonitorConn, *PNwcMonitorConn; | |
14876 | + | |
14877 | +//++======================================================================= | |
14878 | +// API Name: NwcOpenConnByAddr | |
14879 | +// | |
14880 | +// Arguments In: pServiceType - The type of service required. | |
14881 | +// | |
14882 | +// uConnFlags - Specifies whether this connection | |
14883 | +// should be public or private. | |
14884 | +// | |
14885 | +// pTranAddress - Specifies the transport address of | |
14886 | +// the service to open a connection on. | |
14887 | +// a connection to. | |
14888 | +// | |
14889 | +// Arguments Out: ConnHandle - The new connection handle returned. | |
14890 | +// This handle may in turn be used for all requests | |
14891 | +// directed to this connection. | |
14892 | +// | |
14893 | +// Returns: STATUS_SUCCESS | |
14894 | +// NWE_ACCESS_VIOLATION | |
14895 | +// NWE_INSUFFICIENT_RESOURCES | |
14896 | +// NWE_TRAN_INVALID_TYPE | |
14897 | +// NWE_RESOURCE_LOCK | |
14898 | +// NWE_UNSUPPORTED_TRAN_TYPE | |
14899 | +// | |
14900 | +// Abstract: This API will create a service connection to | |
14901 | +// the service specified by the transport address. | |
14902 | +// | |
14903 | +// Notes: | |
14904 | +// | |
14905 | +// Environment: PASSIVE_LEVEL, LINUX | |
14906 | +// | |
14907 | +//=======================================================================-- | |
14908 | + | |
14909 | +typedef struct tagNwcOpenConnByAddr { | |
14910 | + char *pServiceType; | |
14911 | + u32 uConnFlags; | |
14912 | + PNwcTranAddr pTranAddr; | |
14913 | + NW_CONN_HANDLE ConnHandle; | |
14914 | + | |
14915 | +} NwcOpenConnByAddr, *PNwcOpenConnByAddr; | |
14916 | + | |
14917 | +//++======================================================================= | |
14918 | +// API Name: NwcOpenConnByName | |
14919 | +// | |
14920 | +// Arguments In: ConnHandle - The connection to use when resolving | |
14921 | +// a name. For instance, if the name is a bindery name | |
14922 | +// the requester will scan the bindery of the given | |
14923 | +// connection to retrieve the service's address. This | |
14924 | +// value can also be NULL if the caller doesn't care | |
14925 | +// which connection is used to resolve the address. | |
14926 | +// | |
14927 | +// pName - A pointer to the name of the service trying | |
14928 | +// to be connected to. This string is NULL terminated, | |
14929 | +// contains no wild cards, and is a maximum of 512 | |
14930 | +// characters long. | |
14931 | +// | |
14932 | +// pServiceType - The type of service required. | |
14933 | +// | |
14934 | +// uConnFlags - Specifies whether this connection | |
14935 | +// should be public or private. | |
14936 | +// | |
14937 | +// uTranType - Specifies the preferred or required | |
14938 | +// transport type to be used. | |
14939 | +// NWC_TRAN_TYPE_WILD may be ORed with the other values | |
14940 | +// or used alone. When ORed with another value, the | |
14941 | +// wild value indicates an unmarked alternative is | |
14942 | +// acceptable. When used alone, the current preferred | |
14943 | +// transport is used. | |
14944 | +// | |
14945 | +// Arguments Out: ConnHandle - The new connection handle returned. | |
14946 | +// This handle may in turn be used for all requests | |
14947 | +// directed to this connection. | |
14948 | +// | |
14949 | +// Returns: STATUS_SUCCESS | |
14950 | +// NWE_ACCESS_VIOLATION | |
14951 | +// NWE_BUFFER_OVERFLOW | |
14952 | +// NWE_INSUFFICIENT_RESOURCES | |
14953 | +// NWE_INVALID_STRING_TYPE | |
14954 | +// NWE_RESOURCE_LOCK | |
14955 | +// NWE_STRING_TRANSLATION | |
14956 | +// NWE_TRAN_INVALID_TYPE | |
14957 | +// NWE_UNSUPPORTED_TRAN_TYPE | |
14958 | +// | |
14959 | +// Abstract: This API will resolve the given name to a network | |
14960 | +// address then create a service connection to the | |
14961 | +// specified service. | |
14962 | +// | |
14963 | +// Notes: | |
14964 | +// | |
14965 | +// Environment: PASSIVE_LEVEL, LINUX | |
14966 | +// | |
14967 | +//=======================================================================-- | |
14968 | + | |
14969 | +typedef struct tagNwcOpenConnByName { | |
14970 | + NW_CONN_HANDLE ConnHandle; | |
14971 | + PNwcConnString pName; | |
14972 | + char *pServiceType; | |
14973 | + u32 uConnFlags; | |
14974 | + u32 uTranType; | |
14975 | + NW_CONN_HANDLE RetConnHandle; | |
14976 | + | |
14977 | +} NwcOpenConnByName, *PNwcOpenConnByName; | |
14978 | + | |
14979 | +//++======================================================================= | |
14980 | +// API Name: NwcOpenConnByReference | |
14981 | +// | |
14982 | +// Arguments In: uConnReference - A reference handle which identifies | |
14983 | +// a valid connection that the caller wants to obtain | |
14984 | +// a connection handle to. A reference handle can be | |
14985 | +// used to get information about the connection without | |
14986 | +// actually getting a handle to it. A connection handle | |
14987 | +// must be used to make actual requests to that | |
14988 | +// connection. | |
14989 | +// | |
14990 | +// uConnFlags - Currently unused. | |
14991 | +// | |
14992 | +// Arguments Out: ConnHandle - The new connection handle returned. | |
14993 | +// This handle may in turn be used for all requests | |
14994 | +// directed to this connection. | |
14995 | +// | |
14996 | +// Returns: STATUS_SUCCESS | |
14997 | +// NWE_ACCESS_VIOLATION | |
14998 | +// NWE_CONN_INVALID | |
14999 | +// | |
15000 | +// Abstract: This API will open the connection associated with | |
15001 | +// the given connection reference. The connection | |
15002 | +// reference can be obtained by calling the | |
15003 | +// NwcScanConnInfo API. | |
15004 | +// | |
15005 | +// Notes: | |
15006 | +// | |
15007 | +// Environment: PASSIVE_LEVEL, LINUX | |
15008 | +// | |
15009 | +//=======================================================================-- | |
15010 | + | |
15011 | +typedef struct tagNwcOpenConnByReference { | |
15012 | + u32 uConnReference; | |
15013 | + u32 uConnFlags; | |
15014 | + NW_CONN_HANDLE ConnHandle; | |
15015 | + | |
15016 | +} NwcOpenConnByReference, *PNwcOpenConnByReference; | |
15017 | + | |
15018 | +//++======================================================================= | |
15019 | +// API Name: NwcRawRequest | |
15020 | +// | |
15021 | +// Arguments In: ConnHandle - The connection handle of the connection | |
15022 | +// that the request is being directed to. | |
15023 | +// | |
15024 | +// uFunction - The NCP function that is being called. | |
15025 | +// | |
15026 | +// uNumRequestFrags - The number of fragments that the | |
15027 | +// request packet has been broken into. | |
15028 | +// | |
15029 | +// pRequestFrags - List of fragments that make up the | |
15030 | +// request packet. Each fragment includes the length | |
15031 | +// of the fragment data and a pointer to the data. | |
15032 | +// | |
15033 | +// uNumReplyFrags - The number of fragments the reply | |
15034 | +// packet has been broken into. | |
15035 | +// | |
15036 | +// Arguments Out: pReplyFrags - List of fragments that make up the | |
15037 | +// request packet. Each fragment includes the length | |
15038 | +// of the fragment data and a pointer to the data. | |
15039 | +// | |
15040 | +// uActualReplyLength - Total size of the reply packet | |
15041 | +// after any header and tail information is removed. | |
15042 | +// | |
15043 | +// Returns: STATUS_SUCCESS | |
15044 | +// NWE_ACCESS_VIOLATION | |
15045 | +// NWE_CONN_INVALID | |
15046 | +// | |
15047 | +// Abstract: API for sending raw NCP packets directly to a server. | |
15048 | +// | |
15049 | +// Notes: | |
15050 | +// | |
15051 | +// Environment: PASSIVE_LEVEL, LINUX | |
15052 | +// | |
15053 | +//=======================================================================-- | |
15054 | + | |
15055 | +typedef struct tagNwcRequest { | |
15056 | + NW_CONN_HANDLE ConnHandle; | |
15057 | + u32 uFunction; | |
15058 | + u32 uNumRequestFrags; | |
15059 | + PNwcFrag pRequestFrags; | |
15060 | + u32 uNumReplyFrags; | |
15061 | + PNwcFrag pReplyFrags; | |
15062 | + u32 uActualReplyLength; | |
15063 | + | |
15064 | +} NwcRequest, *PNwcRequest; | |
15065 | + | |
15066 | +//++======================================================================= | |
15067 | +// API Name: NwcRawRequestAll | |
15068 | +// | |
15069 | +// Arguments In: uFunction - The NCP function that is being called. | |
15070 | +// | |
15071 | +// uNumRequestFrags - The number of fragments that the | |
15072 | +// request packet has been broken into. | |
15073 | +// | |
15074 | +// pRequestFrags - List of fragments that make up the | |
15075 | +// request packet. Each fragment includes the length | |
15076 | +// of the fragment data and a pointer to the data. | |
15077 | +// | |
15078 | +// Arguments Out: NONE | |
15079 | +// | |
15080 | +// Returns: STATUS_SUCCESS | |
15081 | +// NWE_ACCESS_VIOLATION | |
15082 | +// NWE_CONN_INVALID | |
15083 | +// | |
15084 | +// Abstract: API for sending the given NCP request to all valid | |
15085 | +// connections. If there is a private connection that | |
15086 | +// is not owned by the caller of this function, that | |
15087 | +// connection will not be included. Also, if the | |
15088 | +// caller has both a private and a public connection | |
15089 | +// to the same server, only the private connection | |
15090 | +// will receive the request. | |
15091 | +// | |
15092 | +// Notes: | |
15093 | +// | |
15094 | +// Environment: PASSIVE_LEVEL, LINUX | |
15095 | +// | |
15096 | +//=======================================================================-- | |
15097 | + | |
15098 | +typedef struct tagNwcRequestAll { | |
15099 | + u32 uFunction; | |
15100 | + u32 uNumRequestFrags; | |
15101 | + PNwcFrag pRequestFrags; | |
15102 | + | |
15103 | +} NwcRequestAll, *PNwcRequestAll; | |
15104 | + | |
15105 | +//++======================================================================= | |
15106 | +// API Name: NwcScanConnInfo | |
15107 | +// | |
15108 | +// Arguments In: uScanIndex - The index to be used on the next | |
15109 | +// iteration of the scan. This value should be initially | |
15110 | +// set to zero. The output of this parameter will be | |
15111 | +// used in subsequent calls to this function. | |
15112 | +// | |
15113 | +// uScanInfoLevel - Describes the composition of the | |
15114 | +// pScanConnInfo pointer. If this parameter contains | |
15115 | +// NWC_CONN_INFO_RETURN_ALL, information for all | |
15116 | +// connections will be returned. | |
15117 | +// | |
15118 | +// uScanInfoLen - Lenght of pScanConnInfo buffer | |
15119 | +// | |
15120 | +// pScanConnInfo - This parameter is a pointer to | |
15121 | +// data that describes one piece of connection | |
15122 | +// information. The type of this data depends on | |
15123 | +// which level of information is being scanned for. | |
15124 | +// For instance, if the scan is being used to find all | |
15125 | +// connections with a particular authentication state, | |
15126 | +// pScanConnInfo would be a "pnuint" since | |
15127 | +// authentication state is described as nuint in the | |
15128 | +// NwcConnInfo structure. | |
15129 | +// | |
15130 | +// uScanFlag - This parameter tells whether to return | |
15131 | +// connection information for connections that match | |
15132 | +// the scan criteria or that do not match the scan | |
15133 | +// criteria. If the caller wants to find all the | |
15134 | +// connections that are not in the "NOVELL_INC" DS | |
15135 | +// tree, he would use the call as described below in | |
15136 | +// the description except the uScanFlag parameter would | |
15137 | +// have the value of NWC_MATCH_NOT_EQUALS. This flag | |
15138 | +// is also used to tell the requester whether to | |
15139 | +// return private or public, licensed or unlicensed | |
15140 | +// connections. | |
15141 | +// | |
15142 | +// uReturnInfoLevel - Specifies what information | |
15143 | +// should be returned. | |
15144 | +// | |
15145 | +// uReturnInfoLength - The size in bytes of pConnInfo. | |
15146 | +// | |
15147 | +// Arguments Out: uConnectionReference - Connection reference | |
15148 | +// associated with the information that is being | |
15149 | +// returned. | |
15150 | +// | |
15151 | +// pReturnConnInfo - A pointer to the NwcConnInfo | |
15152 | +// structure defined above. In some of the | |
15153 | +// structures within the union, there are pointers to | |
15154 | +// data to be returned. It is the responsibility of | |
15155 | +// the caller to provide pointers to valid memory | |
15156 | +// to copy this data into. | |
15157 | +// | |
15158 | +// Returns: STATUS_SUCCESS | |
15159 | +// NWE_ACCESS_VIOLATION | |
15160 | +// NWE_RESOURCE_LOCK | |
15161 | +// NWE_CONN_INVALID | |
15162 | +// NWE_INVALID_LEVEL | |
15163 | +// NWE_STRING_TRANSLATION | |
15164 | +// NWE_INVALID_MATCH_DATA | |
15165 | +// NWE_MATCH_FAILED | |
15166 | +// NWE_BUFFER_OVERFLOW | |
15167 | +// NWE_NO_MORE_ENTRIES | |
15168 | +// | |
15169 | +// Abstract: This API is used to return connection information | |
15170 | +// for multiple connections. It will return one | |
15171 | +// piece or the full structure of connection information | |
15172 | +// for one connection at a time. This call is designed | |
15173 | +// to scan for connections based on any piece of | |
15174 | +// connection information as described in the | |
15175 | +// NwcConnInfo structure. For instance, if the caller | |
15176 | +// wants to scan for all connections in the DS tree | |
15177 | +// "NOVELL_INC", the call would be made with the | |
15178 | +// following paramters: | |
15179 | +// | |
15180 | +// uScanLevelInfo = NWC_CONN_INFO_TREE_NAME | |
15181 | +// pScanConnInfo = "NOVELL_INC" | |
15182 | +// uScanFlag = NWC_MATCH_EQUALS | | |
15183 | +// NWC_RETURN_PUBLIC | | |
15184 | +// NWC_RETURN_LICENSED | |
15185 | +// | |
15186 | +// The scan flag is used to tell if the scan is | |
15187 | +// supposed to return connections that match or don't | |
15188 | +// match. This design doesn't allow any other | |
15189 | +// conditions for this flag (such as greater than or | |
15190 | +// less than). | |
15191 | +// | |
15192 | +// If the caller specifies the uReturnInfoLevel = | |
15193 | +// NWC_CONN_INFO_RETURN_ALL, the full NwcConnInfo | |
15194 | +// structure is returned. The caller must supply | |
15195 | +// data for any pointers in the NwcConnInfo structure | |
15196 | +// (these include tree name, workgroup id, server name | |
15197 | +// and transport address). However if the caller | |
15198 | +// doesn't want to get a particular piece of info | |
15199 | +// that is expecting a pointer to some data, a NULL | |
15200 | +// pointer may be used to indicate to the requester | |
15201 | +// that it should not return that piece of information. | |
15202 | +// | |
15203 | +// Notes: | |
15204 | +// | |
15205 | +// Environment: PASSIVE_LEVEL, LINUX | |
15206 | +// | |
15207 | +//=======================================================================-- | |
15208 | + | |
15209 | +typedef struct tagNwcScanConnInfo { | |
15210 | + u32 uScanIndex; | |
15211 | + u32 uScanInfoLevel; | |
15212 | + u32 uScanInfoLen; | |
15213 | + void *pScanConnInfo; | |
15214 | + u32 uScanFlags; | |
15215 | + u32 uReturnInfoLevel; | |
15216 | + u32 uReturnInfoLength; | |
15217 | + u32 uConnectionReference; | |
15218 | + void *pReturnConnInfo; | |
15219 | + | |
15220 | +} NwcScanConnInfo, *PNwcScanConnInfo; | |
15221 | + | |
15222 | +//++======================================================================= | |
15223 | +// API Name: NwcSetConnInfo | |
15224 | +// | |
15225 | +// Arguments In: ConnHandle - Connection handle for the connection to | |
15226 | +// set information on. | |
15227 | +// | |
15228 | +// uInfoLevel - Specifies what information should be set. | |
15229 | +// | |
15230 | +// uInfoLen - Length in bytes of the information being set. | |
15231 | +// | |
15232 | +// pConnInfo - Connection information to set. | |
15233 | +// | |
15234 | +// Arguments Out: NONE | |
15235 | +// | |
15236 | +// Returns: STATUS_SUCCESS | |
15237 | +// NWE_ACCESS_VIOLATION | |
15238 | +// NWE_RESOURCE_LOCK | |
15239 | +// NWE_CONN_INVALID | |
15240 | +// NWE_INVALID_LEVEL | |
15241 | +// | |
15242 | +// | |
15243 | +// Abstract: This API sets information in the connection associated | |
15244 | +// with the connection handle. | |
15245 | +// | |
15246 | +// Notes: At this time the only setable information levels are: | |
15247 | +// NWC_CONN_INFO_AUTH_STATE | |
15248 | +// NWC_CONN_INFO_BCAST_STATE | |
15249 | +// | |
15250 | +// Environment: PASSIVE_LEVEL, LINUX | |
15251 | +// | |
15252 | +//=======================================================================-- | |
15253 | + | |
15254 | +typedef struct tagNwcSetConnInfo { | |
15255 | + NW_CONN_HANDLE ConnHandle; | |
15256 | + u32 uInfoLevel; | |
15257 | + u32 uInfoLength; | |
15258 | + void *pConnInfo; | |
15259 | + | |
15260 | +} NwcSetConnInfo, *PNwcSetConnInfo; | |
15261 | + | |
15262 | +//++======================================================================= | |
15263 | +// API Name: NwcSetDefaultNameContext | |
15264 | +// | |
15265 | +// Arguments In:: uTreeLength - Length of tree string. | |
15266 | +// | |
15267 | +// pDsTreeName - The tree string (multi-byte). | |
15268 | +// | |
15269 | +// uNameLength - The length in bytes of the name | |
15270 | +// context string. | |
15271 | +// | |
15272 | +// pNameContext - The string to be used as the default | |
15273 | +// name context (multi-byte). | |
15274 | +// | |
15275 | +// Arguments Out: NONE | |
15276 | +// | |
15277 | +// Returns: STATUS_SUCCESS | |
15278 | +// NWE_ACCESS_VIOLATION | |
15279 | +// NWE_PARAM_INVALID | |
15280 | +// NWE_RESOURCE_LOCK | |
15281 | +// NWE_STRING_TRANSLATION | |
15282 | +// | |
15283 | +// Abstract: This API sets the default name context. | |
15284 | +// | |
15285 | +// Notes: | |
15286 | +// | |
15287 | +// Environment: PASSIVE_LEVEL, LINUX | |
15288 | +// | |
15289 | +//=======================================================================-- | |
15290 | + | |
15291 | +typedef struct tagNwcSetDefaultNameContext { | |
15292 | + u32 uTreeLength; | |
15293 | + unsigned char *pDsTreeName; | |
15294 | + u32 uNameLength; | |
15295 | +// unsined short *pNameContext; | |
15296 | + unsigned char *pNameContext; | |
15297 | + | |
15298 | +} NwcSetDefaultNameContext, *PNwcSetDefaultNameContext; | |
15299 | + | |
15300 | +//++======================================================================= | |
15301 | +// API Name: NwcSetPreferredDsTree | |
15302 | +// | |
15303 | +// Arguments In: uTreeLength - The length in bytes of the DS tree name. | |
15304 | +// | |
15305 | +// pDsTreeName - The string to be used as the preferred | |
15306 | +// DS tree name. | |
15307 | +// | |
15308 | +// Arguments Out: NONE | |
15309 | +// | |
15310 | +// Returns: STATUS_SUCCESS | |
15311 | +// NWE_ACCESS_VIOLATION | |
15312 | +// NWE_INSUFFICIENT_RESOURCES | |
15313 | +// NWE_RESOURCE_LOCK | |
15314 | +// | |
15315 | +// Abstract: This API sets the preferred DS tree name. | |
15316 | +// | |
15317 | +// Notes: | |
15318 | +// | |
15319 | +// Environment: PASSIVE_LEVEL, LINUX | |
15320 | +// | |
15321 | +//=======================================================================-- | |
15322 | + | |
15323 | +typedef struct tagNwcSetPreferredDsTree { | |
15324 | + u32 uTreeLength; | |
15325 | + unsigned char *pDsTreeName; | |
15326 | + | |
15327 | +} NwcSetPreferredDsTree, *PNwcSetPreferredDsTree; | |
15328 | + | |
15329 | +//++======================================================================= | |
15330 | +// API Name: NwcSetPreferredServer | |
15331 | +// | |
15332 | +// Arguments In: uServerNameLength - The length in bytes of the | |
15333 | +// preferred server string. | |
15334 | +// | |
15335 | +// pServerName - a pointer to an ASCIIZ string of the | |
15336 | +// preferred bindery server. | |
15337 | +// | |
15338 | +// Arguments Out: NONE | |
15339 | +// | |
15340 | +// Returns: STATUS_SUCCESS | |
15341 | +// NWE_ACCESS_VIOLATION | |
15342 | +// NWE_INSUFFICIENT_RESOURCES | |
15343 | +// NWE_RESOURCE_LOCK | |
15344 | +// | |
15345 | +// Abstract: This API sets the preferred server name. | |
15346 | +// | |
15347 | +// Notes: | |
15348 | +// | |
15349 | +// Environment: PASSIVE_LEVEL, LINUX | |
15350 | +// | |
15351 | +//=======================================================================-- | |
15352 | + | |
15353 | +typedef struct tagNwcSetPreferredServer { | |
15354 | + u32 uServerNameLength; | |
15355 | + char *pServerName; | |
15356 | + | |
15357 | +} NwcSetPreferredServer, *PNwcSetPreferredServer; | |
15358 | + | |
15359 | +//++======================================================================= | |
15360 | +// API Name: NwcSetPrimaryConnection | |
15361 | +// | |
15362 | +// Arguments In: ConnHandle - Connection handle associated to the | |
15363 | +// connection reference which the caller wishes to set | |
15364 | +// as primary. | |
15365 | +// | |
15366 | +// Arguments Out: NONE | |
15367 | +// | |
15368 | +// Returns: STATUS_SUCCESS | |
15369 | +// NWE_ACCESS_VIOLATION | |
15370 | +// NWE_CONN_PRIMARY_NOT_SET | |
15371 | +// | |
15372 | +// Abstract: This API sets the primary connection according to | |
15373 | +// the connection handle passed in by the caller. | |
15374 | +// | |
15375 | +// Notes: | |
15376 | +// | |
15377 | +// Environment: PASSIVE_LEVEL, LINUX | |
15378 | +// | |
15379 | +//=======================================================================-- | |
15380 | + | |
15381 | +typedef struct tagNwcSetPrimaryConnection { | |
15382 | + NW_CONN_HANDLE ConnHandle; | |
15383 | + | |
15384 | +} NwcSetPrimaryConnection, *PNwcSetPrimaryConnection; | |
15385 | + | |
15386 | +//++======================================================================= | |
15387 | +// API Name: NwcSysCloseConn | |
15388 | +// | |
15389 | +// Arguments In: ConnHandle - The handle to a connection that is | |
15390 | +// to be destroyed. | |
15391 | +// | |
15392 | +// Arguments Out: NONE | |
15393 | +// | |
15394 | +// Returns: STATUS_SUCCESS | |
15395 | +// NWE_ACCESS_VIOLATION | |
15396 | +// NWE_CONN_INVALID | |
15397 | +// | |
15398 | +// Abstract: This API is similiar to the NwcCloseConn API, except | |
15399 | +// that it forces all handles to the connection closed | |
15400 | +// and destroys the service connection. This is a system | |
15401 | +// level request that will cause all processes that are | |
15402 | +// accessing this connection to lose access to the | |
15403 | +// resources associated to the connection. | |
15404 | +// | |
15405 | +// Notes: | |
15406 | +// | |
15407 | +// Environment: PASSIVE_LEVEL, LINUX | |
15408 | +// | |
15409 | +//=======================================================================-- | |
15410 | + | |
15411 | +typedef struct tagNwcSysCloseConn { | |
15412 | + NW_CONN_HANDLE ConnHandle; | |
15413 | + | |
15414 | +} NwcSysCloseConn, *PNwcSysCloseConn; | |
15415 | + | |
15416 | +//++======================================================================= | |
15417 | +// API Name: NwcUnlicenseConn | |
15418 | +// | |
15419 | +// Arguments In: ConnHandle - Open connection handle that will be | |
15420 | +// accessing the connection in an unlicensed manner. | |
15421 | +// | |
15422 | +// Arguments Out: NONE | |
15423 | +// | |
15424 | +// Returns: STATUS_SUCCESS | |
15425 | +// NWE_ACCESS_VIOLATION | |
15426 | +// NWE_CONN_INVALID | |
15427 | +// NWE_HANDLE_ALREADY_UNLICENSED | |
15428 | +// | |
15429 | +// Abstract: This API is used to change the state of a connection | |
15430 | +// handle from licensed to unlicensed. If all handles | |
15431 | +// to the connection have been changed to the unlicensed | |
15432 | +// state, the unlicensed NCP is sent to the server. | |
15433 | +// | |
15434 | +// Notes: | |
15435 | +// | |
15436 | +// Environment: PASSIVE_LEVEL, LINUX | |
15437 | +// | |
15438 | +//=======================================================================-- | |
15439 | + | |
15440 | +typedef struct tagNwcUnlicenseConn { | |
15441 | + NW_CONN_HANDLE ConnHandle; | |
15442 | + | |
15443 | +} NwcUnlicenseConn, *PNwcUnlicenseConn; | |
15444 | + | |
15445 | +//++======================================================================= | |
15446 | +// API Name: NwcQueryFeature | |
15447 | +// | |
15448 | +// Arguments In: Feature - The number associated with a particular | |
15449 | +// feature that the caller wants to know if the requester | |
15450 | +// is supporting | |
15451 | +// | |
15452 | +// Arguments Out: | |
15453 | +// | |
15454 | +// Returns: STATUS_SUCCESS | |
15455 | +// NWE_REQUESTER_FAILURE | |
15456 | +// NWE_ACCESS_VIOLATION | |
15457 | +// | |
15458 | +// Abstract: | |
15459 | +// | |
15460 | +// Notes: | |
15461 | +// | |
15462 | +// Environment: PASSIVE_LEVEL, LINUX | |
15463 | +// | |
15464 | +//=======================================================================-- | |
15465 | + | |
15466 | +typedef struct tagNwcQueryFeature { | |
15467 | + u32 Feature; | |
15468 | + | |
15469 | +} NwcQueryFeature, *PNwcQueryFeature; | |
15470 | + | |
15471 | +//++======================================================================= | |
15472 | +// API Name: NWCChangePassword | |
15473 | +// | |
15474 | +// Arguments In: | |
15475 | +// | |
15476 | +// Arguments Out: | |
15477 | +// | |
15478 | +// Returns: STATUS_SUCCESS | |
15479 | +// NWE_ACCESS_VIOLATION | |
15480 | +// | |
15481 | +// Abstract: | |
15482 | +// | |
15483 | +// Notes: | |
15484 | +// | |
15485 | +// Environment: PASSIVE_LEVEL, LINUX | |
15486 | +// | |
15487 | +//=======================================================================-- | |
15488 | + | |
15489 | +typedef struct tagNwcChangeKey { | |
15490 | + PNwcString pDomainName; | |
15491 | + u32 AuthType; | |
15492 | + PNwcString pObjectName; | |
15493 | + u32 NameType; | |
15494 | + u16 ObjectType; | |
15495 | + PNwcString pVerifyPassword; | |
15496 | + PNwcString pNewPassword; | |
15497 | + | |
15498 | +} NwcChangeKey, *PNwcChangeKey; | |
15499 | + | |
15500 | +//++======================================================================= | |
15501 | +// API Name: NWCEnumerateIdentities ` | |
15502 | +// | |
15503 | +// Arguments In: | |
15504 | +// | |
15505 | +// Arguments Out: | |
15506 | +// | |
15507 | +// Returns: STATUS_SUCCESS | |
15508 | +// NWE_ACCESS_VIOLATION | |
15509 | +// | |
15510 | +// Abstract: | |
15511 | +// | |
15512 | +// Notes: | |
15513 | +// | |
15514 | +// Environment: PASSIVE_LEVEL, LINUX | |
15515 | +// | |
15516 | +//=======================================================================-- | |
15517 | + | |
15518 | +typedef struct tagNwcEnumerateIdentities { | |
15519 | + u32 Iterator; | |
15520 | + PNwcString pDomainName; | |
15521 | + u32 AuthType; | |
15522 | + PNwcString pObjectName; | |
15523 | + u32 NameType; | |
15524 | + u16 ObjectType; | |
15525 | + u32 IdentityFlags; | |
15526 | + AUTHEN_ID AuthenticationId; | |
15527 | + | |
15528 | +} NwcEnumerateIdentities, *PNwcEnumerateIdentities; | |
15529 | + | |
15530 | +//++======================================================================= | |
15531 | +// API Name: NWCGetIdentityInfo | |
15532 | +// | |
15533 | +// Arguments In: | |
15534 | +// | |
15535 | +// Arguments Out: | |
15536 | +// | |
15537 | +// Returns: STATUS_SUCCESS | |
15538 | +// NWE_ACCESS_VIOLATION | |
15539 | +// | |
15540 | +// Abstract: | |
15541 | +// | |
15542 | +// Notes: | |
15543 | +// | |
15544 | +// Environment: PASSIVE_LEVEL, LINUX | |
15545 | +// | |
15546 | +//=======================================================================-- | |
15547 | + | |
15548 | +typedef struct tagNwcGetIdentityInfo { | |
15549 | + AUTHEN_ID AuthenticationId; | |
15550 | + PNwcString pDomainName; | |
15551 | + u32 AuthType; | |
15552 | + PNwcString pObjectName; | |
15553 | + u32 NameType; | |
15554 | + u16 ObjectType; | |
15555 | + u32 IdentityFlags; | |
15556 | + | |
15557 | +} NwcGetIdentityInfo, *PNwcGetIdentityInfo; | |
15558 | + | |
15559 | +//++======================================================================= | |
15560 | +// API Name: NWCLoginIdentity | |
15561 | +// | |
15562 | +// Arguments In: | |
15563 | +// | |
15564 | +// Arguments Out: | |
15565 | +// | |
15566 | +// Returns: STATUS_SUCCESS | |
15567 | +// NWE_ACCESS_VIOLATION | |
15568 | +// | |
15569 | +// Abstract: | |
15570 | +// | |
15571 | +// Notes: | |
15572 | +// | |
15573 | +// Environment: PASSIVE_LEVEL, LINUX | |
15574 | +// | |
15575 | +//=======================================================================-- | |
15576 | + | |
15577 | +typedef struct tagNwcLoginIdentity { | |
15578 | + PNwcString pDomainName; | |
15579 | + u32 AuthType; | |
15580 | + PNwcString pObjectName; | |
15581 | + u32 NameType; | |
15582 | + u16 ObjectType; | |
15583 | + u32 IdentityFlags; | |
15584 | + PNwcString pPassword; | |
15585 | + AUTHEN_ID AuthenticationId; | |
15586 | + | |
15587 | +} NwcLoginIdentity, *PNwcLoginIdentity; | |
15588 | + | |
15589 | +//++======================================================================= | |
15590 | +// API Name: NWCLogoutIdentity | |
15591 | +//// | |
15592 | + | |
15593 | +// Arguments In: | |
15594 | +// | |
15595 | +// Arguments Out: | |
15596 | +// | |
15597 | +// Returns: STATUS_SUCCESS | |
15598 | +// NWE_ACCESS_VIOLATION | |
15599 | +// | |
15600 | +// Abstract: | |
15601 | +// | |
15602 | +// Notes: | |
15603 | +// | |
15604 | +// Environment: PASSIVE_LEVEL, LINUX | |
15605 | +// | |
15606 | +//=======================================================================-- | |
15607 | + | |
15608 | +typedef struct tagNwcLogoutIdentity { | |
15609 | + AUTHEN_ID AuthenticationId; | |
15610 | + | |
15611 | +} NwcLogoutIdentity, *PNwcLogoutIdentity; | |
15612 | + | |
15613 | +//++======================================================================= | |
15614 | +// API Name: NWCSetPassword | |
15615 | +// | |
15616 | +// Arguments In: | |
15617 | +// | |
15618 | +// Arguments Out: | |
15619 | +// | |
15620 | +// Returns: STATUS_SUCCESS | |
15621 | +// NWE_ACCESS_VIOLATION | |
15622 | +// | |
15623 | +// Abstract: | |
15624 | +// | |
15625 | +// Notes: | |
15626 | +// | |
15627 | +// Environment: PASSIVE_LEVEL, LINUX | |
15628 | +// | |
15629 | +//=======================================================================-- | |
15630 | + | |
15631 | +typedef struct tagNwcSetKey { | |
15632 | + NW_CONN_HANDLE ConnHandle; | |
15633 | + AUTHEN_ID AuthenticationId; | |
15634 | + PNwcString pObjectName; | |
15635 | + u16 ObjectType; | |
15636 | + PNwcString pNewPassword; | |
15637 | + | |
15638 | +} NwcSetKey, *PNwcSetKey; | |
15639 | + | |
15640 | +//++======================================================================= | |
15641 | +// API Name: NWCVerifyPassword | |
15642 | +// | |
15643 | +// Arguments In: | |
15644 | +// | |
15645 | +// Arguments Out: | |
15646 | +// | |
15647 | +// Returns: STATUS_SUCCESS | |
15648 | +// NWE_ACCESS_VIOLATION | |
15649 | +// | |
15650 | +// Abstract: | |
15651 | +// | |
15652 | +// Notes: | |
15653 | +// | |
15654 | +// Environment: PASSIVE_LEVEL, LINUX | |
15655 | +// | |
15656 | +//++======================================================================= | |
15657 | + | |
15658 | +typedef struct tagNwcVerifyKey { | |
15659 | + PNwcString pDomainName; | |
15660 | + u32 AuthType; | |
15661 | + PNwcString pObjectName; | |
15662 | + u32 NameType; | |
15663 | + u16 ObjectType; | |
15664 | + PNwcString pVerifyPassword; | |
15665 | + | |
15666 | +} NwcVerifyKey, *PNwcVerifyKey; | |
15667 | + | |
15668 | +//++======================================================================= | |
15669 | +// API Name: NwcAuthenticateWithId | |
15670 | +// | |
15671 | +// Arguments In: ConnHandle - The connection to be authenticated | |
15672 | +// | |
15673 | +// AuthenticationId - the authentication Id associated | |
15674 | +// to the information necessary to authenticate this | |
15675 | +// connection. | |
15676 | +// | |
15677 | +// Arguments Out: NONE | |
15678 | +// | |
15679 | +// Returns: STATUS_SUCCESS | |
15680 | +// NWE_ACCESS_VIOLATION | |
15681 | +// | |
15682 | +// Abstract: This API is used to authenticate a connection using | |
15683 | +// an authentication ID that has already been created. | |
15684 | +// | |
15685 | +// Notes: | |
15686 | +// | |
15687 | +// Environment: PASSIVE_LEVEL, LINUX | |
15688 | +// | |
15689 | +//=======================================================================-- | |
15690 | + | |
15691 | +typedef struct tagNwcAuthenticateWithId { | |
15692 | + NW_CONN_HANDLE ConnHandle; | |
15693 | + AUTHEN_ID AuthenticationId; | |
15694 | + | |
15695 | +} NwcAuthenticateWithId, *PNwcAuthenticateWithId; | |
15696 | + | |
15697 | +//++======================================================================= | |
15698 | +// API Name: NwcUnauthenticate | |
15699 | +// | |
15700 | +// Arguments In: ConnHandle - The connection to unauthenticate. | |
15701 | +// | |
15702 | +// Arguments Out: NONE | |
15703 | +// | |
15704 | +// Returns: STATUS_SUCCESS | |
15705 | +// NWE_ACCESS_VIOLATION | |
15706 | +// NWE_CONN_INVALID | |
15707 | +// NWE_INVALID_OWNER | |
15708 | +// NWE_RESOURCE_LOCK | |
15709 | +// | |
15710 | +// Abstract: This API removes the authentication for the specified | |
15711 | +// connection. | |
15712 | +// | |
15713 | +// Notes: | |
15714 | +// | |
15715 | +// Environment: PASSIVE_LEVEL, LINUX | |
15716 | +// | |
15717 | +//=======================================================================-- | |
15718 | + | |
15719 | +typedef struct tagNwcUnauthenticate { | |
15720 | + NW_CONN_HANDLE ConnHandle; | |
15721 | + AUTHEN_ID AuthenticationId; | |
15722 | + | |
15723 | +} NwcUnauthenticate, *PNwcUnauthenticate; | |
15724 | + | |
15725 | +//++======================================================================= | |
15726 | +// API Name: NwcGetCfgNameServiceProviders | |
15727 | +// | |
15728 | +// Arguments In: | |
15729 | +// | |
15730 | +// Arguments Out: | |
15731 | +// | |
15732 | +// Returns: STATUS_SUCCESS | |
15733 | +// NWE_ACCESS_VIOLATION | |
15734 | +// | |
15735 | +// Abstract: | |
15736 | +// | |
15737 | +// Notes: | |
15738 | +// | |
15739 | +// Environment: PASSIVE_LEVEL, LINUX | |
15740 | +// | |
15741 | +//=======================================================================-- | |
15742 | + | |
15743 | +typedef struct { | |
15744 | + u32 providerCount; | |
15745 | + u32 providers[MAX_NAME_SERVICE_PROVIDERS]; | |
15746 | + | |
15747 | +} NwcGetCfgNameServiceProviders, *PNwcGetCfgNameServiceProviders; | |
15748 | + | |
15749 | +//++======================================================================= | |
15750 | +// API Name: NwcNdsResolveNameToId | |
15751 | +// | |
15752 | +// Arguments In: connHandle | |
15753 | +// Specifies connection to use to resolve name with. | |
15754 | +// | |
15755 | +// pName | |
15756 | +// Points to the name of the NDS entry to resolve. | |
15757 | +// | |
15758 | +// uReqTranType | |
15759 | +// Specifies the preferred or required transport to | |
15760 | +// be used. | |
15761 | +// | |
15762 | +// pResolveInfo | |
15763 | +// Points to the NwcNdsResolveInfo structure | |
15764 | +// containing information on how the entry is to be | |
15765 | +// resolved. | |
15766 | +// | |
15767 | +// Arguments Out: pResolveInfo | |
15768 | +// Points to the NwcNdsResolveInfo structure | |
15769 | +// containing return information on the resolved | |
15770 | +// entry. | |
15771 | +// | |
15772 | +// pluEntryId | |
15773 | +// Points to the resolved name's entry ID. | |
15774 | +// | |
15775 | +// pReferral | |
15776 | +// Points to the NwcReferral structure which describes | |
15777 | +// network addresses that can be used to locate other | |
15778 | +// NDS partitions that contain the entry name. | |
15779 | +// | |
15780 | +// Returns: STATUS_SUCCESS | |
15781 | +// NWE_CONN_INVALID, | |
15782 | +// NWE_BUFFER_OVERFLOW, | |
15783 | +// NWE_TRAN_INVALID_TYPE, | |
15784 | +// NWE_ACCESS_VIOLATION, | |
15785 | +// NWE_UNSUPPORTED_TRAN_TYPE, | |
15786 | +// Nds error code | |
15787 | +// | |
15788 | +// Abstract: This API resolves a NDS entry name. | |
15789 | +// | |
15790 | +// Notes: | |
15791 | +// | |
15792 | +// Environment: PASSIVE_LEVEL, LINUX | |
15793 | +// | |
15794 | +//=======================================================================-- | |
15795 | + | |
15796 | +typedef struct tagNwcNdsResolveNameToId { | |
15797 | + NW_CONN_HANDLE connHandle; | |
15798 | + PNwcString pName; | |
15799 | + u32 uReqTranType; | |
15800 | + PNwcResolveInfo pResolveInfo; | |
15801 | + u32 entryId; | |
15802 | + PNwcReferral pReferral; | |
15803 | + | |
15804 | +} NwcNdsResolveNameToId, *PNwcNdsResolveNameToId; | |
15805 | + | |
15806 | +//++======================================================================= | |
15807 | +// API Name: NwcOrderedRequest | |
15808 | +// | |
15809 | +// Arguments In: uFunction - The NCP function that is being called. | |
15810 | +// | |
15811 | +// uNumRequestFrags - The number of fragments that the | |
15812 | +// request packet has been broken into. | |
15813 | +// | |
15814 | +// pRequestFrags - List of fragments that make up the | |
15815 | +// request packet. Each fragment includes the length | |
15816 | +// of the fragment data and a pointer to the data. | |
15817 | +// | |
15818 | +// uInverseReqCode - The NCP function that will be called | |
15819 | +// if the request fails. | |
15820 | +// | |
15821 | +// uNumInverseFrags - The number of fragments the inverse | |
15822 | +// request packet has been broken into. | |
15823 | +// | |
15824 | +// pReplyFrags - List of fragments that make up the | |
15825 | +// inverse request packet. Each fragment includes the length | |
15826 | +// of the fragment data and a pointer to the data. | |
15827 | +// | |
15828 | +// Returns: STATUS_SUCCESS | |
15829 | +// NWE_ACCESS_VIOLATION | |
15830 | +// NWE_CONN_INVALID | |
15831 | +// | |
15832 | +// Abstract: API for sending raw NCP packets directly to a server. | |
15833 | +// | |
15834 | +// Notes: | |
15835 | +// | |
15836 | +// Environment: PASSIVE_LEVEL, LINUX | |
15837 | +// | |
15838 | +//=======================================================================-- | |
15839 | + | |
15840 | +typedef struct tagNwcOrderedRequest { | |
15841 | + u32 uReqCode; | |
15842 | + u32 uNumRequestFrags; | |
15843 | + PNwcFrag pRequestFrags; | |
15844 | + u32 uInverseReqCode; | |
15845 | + u32 uNumInverseFrags; | |
15846 | + PNwcFrag pInverseFrags; | |
15847 | + | |
15848 | +} NwcOrderedRequest, *PNwcOrderedRequest; | |
15849 | + | |
15850 | +#if 1 //sgled | |
15851 | +typedef struct tagNwcUnmapDriveEx { | |
15852 | +// unsigned long connHdl; | |
15853 | + unsigned int linkLen; | |
15854 | + char linkData[1]; | |
15855 | + | |
15856 | +} NwcUnmapDriveEx, *PNwcUnmapDriveEx; | |
15857 | + | |
15858 | +typedef struct tagNwcMapDriveEx { | |
15859 | + NW_CONN_HANDLE ConnHandle; | |
15860 | + unsigned int localUid; | |
15861 | + unsigned int linkOffsetLength; | |
15862 | + unsigned int linkOffset; | |
15863 | + unsigned int dirPathOffsetLength; | |
15864 | + unsigned int dirPathOffset; | |
15865 | +} NwcMapDriveEx, *PNwcMapDriveEx; | |
15866 | + | |
15867 | +typedef struct tagNwcGetBroadcastNotification { | |
15868 | + u32 uMessageFlags; | |
15869 | + u32 uConnReference; | |
15870 | + u32 messageLen; | |
15871 | + char message[1]; | |
15872 | +} NwcGetBroadcastNotification, *PNwcGetBroadcastNotification; | |
15873 | + | |
15874 | +#endif | |
15875 | +#endif /* __NWCLNX_H__ */ | |
15876 | --- /dev/null | |
15877 | +++ b/fs/novfs/nwerror.h | |
15878 | @@ -0,0 +1,658 @@ | |
15879 | +/* | |
15880 | + * NetWare Redirector for Linux | |
15881 | + * Author: Tom Buckley | |
15882 | + * | |
15883 | + * This file contains all return error codes. | |
15884 | + * | |
15885 | + * Copyright (C) 2005 Novell, Inc. | |
15886 | + * | |
15887 | + * This program is free software; you can redistribute it and/or | |
15888 | + * modify it under the terms of the GNU General Public License | |
15889 | + * as published by the Free Software Foundation; either version 2 | |
15890 | + * of the License, or (at your option) any later version. | |
15891 | + */ | |
15892 | +#ifndef __NOVFS_ERROR_H | |
15893 | +#define __NOVFS_ERROR_H | |
15894 | + | |
15895 | + | |
15896 | +/* | |
15897 | + * Network errors | |
15898 | + * Decimal values at end of line are 32768 lower than actual | |
15899 | + */ | |
15900 | + | |
15901 | +#define SHELL_ERROR 0x8800 | |
15902 | +#define VLM_ERROR 0x8800 | |
15903 | +#define ALREADY_ATTACHED 0x8800 // 0 - Attach attempted to server with valid, existing connection | |
15904 | +#define INVALID_CONNECTION 0x8801 // 1 - Request attempted with invalid or non-attached connection handle | |
15905 | +#define DRIVE_IN_USE 0x8802 // 2 - OS/2 only (NOT USED) | |
15906 | +#define CANT_ADD_CDS 0x8803 // 3 - Map drive attempted but unable to add new current directory structure | |
15907 | +#define DRIVE_CANNOT_MAP 0x8803 | |
15908 | +#define BAD_DRIVE_BASE 0x8804 // 4 - Map drive attempted with invalid path specification | |
15909 | +#define NET_READ_ERROR 0x8805 // 5 - Attempt to receive from the selected transport failed | |
15910 | +#define NET_RECV_ERROR 0x8805 // 5 | |
15911 | +#define UNKNOWN_NET_ERROR 0x8806 // 6 - Network send attempted with an un-specific network error | |
15912 | +#define SERVER_INVALID_SLOT 0x8807 // 7 - Server request attempted with invalid server connection slot | |
15913 | +#define BAD_SERVER_SLOT 0x8807 // 7 | |
15914 | +#define NO_SERVER_SLOTS 0x8808 // 8 - Attach attempted to server with no connection slots available | |
15915 | +#define NET_WRITE_ERROR 0x8809 // 9 - Attempt to send on the selected transport failed | |
15916 | +#define CONNECTION_IN_ERROR_STATE 0x8809 // Client-32 | |
15917 | +#define NET_SEND_ERROR 0x8809 // 9 | |
15918 | +#define SERVER_NO_ROUTE 0x880A // 10 - Attempted to find route to server where no route exists | |
15919 | +#define BAD_LOCAL_TARGET 0x880B // 11 - OS/2 only | |
15920 | +#define TOO_MANY_REQ_FRAGS 0x880C // 12 - Attempted request with too many request fragments specified | |
15921 | +#define CONNECT_LIST_OVERFLOW 0x880D // 13 | |
15922 | +#define BUFFER_OVERFLOW 0x880E // 14 - Attempt to receive more data than the reply buffer had room for | |
15923 | +#define MORE_DATA_ERROR 0x880E // Client-32 | |
15924 | +#define NO_CONN_TO_SERVER 0x880F // 15 | |
15925 | +#define NO_CONNECTION_TO_SERVER 0x880F // 15 - Attempt to get connection for a server not connected | |
15926 | +#define NO_ROUTER_FOUND 0x8810 // 16 - OS/2 only | |
15927 | +#define BAD_FUNC_ERROR 0x8811 // 17 | |
15928 | +#define INVALID_SHELL_CALL 0x8811 // 17 - Attempted function call to non- existent or illegal function | |
15929 | +#define SCAN_COMPLETE 0x8812 | |
15930 | +#define LIP_RESIZE_ERROR 0x8812 // Client-32 | |
15931 | +#define UNSUPPORTED_NAME_FORMAT_TYPE 0x8813 | |
15932 | +#define INVALID_DIR_HANDLE 0x8813 // Client-32 | |
15933 | +#define HANDLE_ALREADY_LICENSED 0x8814 | |
15934 | +#define OUT_OF_CLIENT_MEMORY 0x8814 // Client-32 | |
15935 | +#define HANDLE_ALREADY_UNLICENSED 0x8815 | |
15936 | +#define PATH_NOT_OURS 0x8815 // Client-32 | |
15937 | +#define INVALID_NCP_PACKET_LENGTH 0x8816 | |
15938 | +#define PATH_IS_PRINT_DEVICE 0x8816 // Client-32 | |
15939 | +#define SETTING_UP_TIMEOUT 0x8817 | |
15940 | +#define PATH_IS_EXCLUDED_DEVICE 0x8817 // Client-32 | |
15941 | +#define SETTING_SIGNALS 0x8818 | |
15942 | +#define PATH_IS_INVALID 0x8818 // Client-32 | |
15943 | +#define SERVER_CONNECTION_LOST 0x8819 | |
15944 | +#define NOT_SAME_DEVICE 0x8819 // Client-32 | |
15945 | +#define OUT_OF_HEAP_SPACE 0x881A | |
15946 | +#define INVALID_SERVICE_REQUEST 0x881B | |
15947 | +#define INVALID_SEARCH_HANDLE 0x881B // Client-32 | |
15948 | +#define INVALID_TASK_NUMBER 0x881C | |
15949 | +#define INVALID_DEVICE_HANDLE 0x881C // Client-32 | |
15950 | +#define INVALID_MESSAGE_LENGTH 0x881D | |
15951 | +#define INVALID_SEM_HANDLE 0x881D // Client-32 | |
15952 | +#define EA_SCAN_DONE 0x881E | |
15953 | +#define INVALID_CFG_HANDLE 0x881E // Client-32 | |
15954 | +#define BAD_CONNECTION_NUMBER 0x881F | |
15955 | +#define INVALID_MOD_HANDLE 0x881F // Client-32 | |
15956 | +#define ASYN_FIRST_PASS 0x8820 | |
15957 | +#define INVALID_DEVICE_INDEX 0x8821 | |
15958 | +#define INVALID_CONN_HANDLE 0x8822 | |
15959 | +#define INVALID_QUEUE_ID 0x8823 | |
15960 | +#define INVALID_PDEVICE_HANDLE 0x8824 | |
15961 | +#define INVALID_JOB_HANDLE 0x8825 | |
15962 | +#define INVALID_ELEMENT_ID 0x8826 | |
15963 | +#define ALIAS_NOT_FOUND 0x8827 | |
15964 | +#define RESOURCE_SUSPENDED 0x8828 | |
15965 | +#define INVALID_QUEUE_SPECIFIED 0x8829 | |
15966 | +#define DEVICE_ALREADY_OPEN 0x882A | |
15967 | +#define JOB_ALREADY_OPEN 0x882B | |
15968 | +#define QUEUE_NAME_ID_MISMATCH 0x882C | |
15969 | +#define JOB_ALREADY_STARTED 0x882D | |
15970 | +#define SPECT_DAA_TYPE_NOT_SUPPORTED 0x882E | |
15971 | +#define INVALID_ENVIR_HANDLE 0x882F | |
15972 | +#define NOT_SAME_CONNECTION 0x8830 // 48 - Internal server request attempted accross different server connections | |
15973 | +#define PRIMARY_CONNECTION_NOT_SET 0x8831 // 49 - Attempt to retrieve default connection with no primary connection set | |
15974 | +#define NO_PRIMARY_SET 0x8831 // 49 | |
15975 | +#define KEYWORD_NOT_FOUND 0x8832 // Client-32 | |
15976 | +#define PRINT_CAPTURE_NOT_IN_PROGRESS 0x8832 // Client-32 | |
15977 | +#define NO_CAPTURE_SET 0x8832 // 50 | |
15978 | +#define NO_CAPTURE_IN_PROGRESS 0x8832 // 50 - Capture information requested on port with no capture in progress | |
15979 | +#define BAD_BUFFER_LENGTH 0x8833 // 51 | |
15980 | +#define INVALID_BUFFER_LENGTH 0x8833 // 51 - Used to indicate length which caller requested on a GetDNC or SetDNC was too large | |
15981 | +#define NO_USER_NAME 0x8834 // 52 | |
15982 | +#define NO_NETWARE_PRINT_SPOOLER 0x8835 // 53 - Capture requested without having the local print spooler installed | |
15983 | +#define INVALID_PARAMETER 0x8836 // 54 - Attempted function with an invalid function parameter specified | |
15984 | +#define CONFIG_FILE_OPEN_FAILED 0x8837 // 55 - OS/2 only | |
15985 | +#define NO_CONFIG_FILE 0x8838 // 56 - OS/2 only | |
15986 | +#define CONFIG_FILE_READ_FAILED 0x8839 // 57 - OS/2 only | |
15987 | +#define CONFIG_LINE_TOO_LONG 0x883A // 58 - OS/2 only | |
15988 | +#define CONFIG_LINES_IGNORED 0x883B // 59 - OS/2 only | |
15989 | +#define NOT_MY_RESOURCE 0x883C // 60 - Attempted request made with a parameter using foriegn resource | |
15990 | +#define DAEMON_INSTALLED 0x883D // 61 - OS/2 only | |
15991 | +#define SPOOLER_INSTALLED 0x883E // 62 - Attempted load of print spooler with print spooler already installed | |
15992 | +#define CONN_TABLE_FULL 0x883F // 63 | |
15993 | +#define CONNECTION_TABLE_FULL 0x883F // 63 - Attempted to allocate a connection handle with no more local connection table entries | |
15994 | +#define CONFIG_SECTION_NOT_FOUND 0x8840 // 64 - OS/2 only | |
15995 | +#define BAD_TRAN_TYPE 0x8841 // 65 | |
15996 | +#define INVALID_TRANSPORT_TYPE 0x8841 // 65 - Attempted function on a connection with an invalid transport selected | |
15997 | +#define TDS_TAG_IN_USE 0x8842 // 66 - OS/2 only | |
15998 | +#define TDS_OUT_OF_MEMORY 0x8843 // 67 - OS/2 only | |
15999 | +#define TDS_INVALID_TAG 0x8844 // 68 - Attempted TDS function with invalid tag | |
16000 | +#define TDS_WRITE_TRUNCATED 0x8845 // 69 - Attempted TDS write with buffer that exceeded buffer | |
16001 | +#define NO_CONNECTION_TO_DS 0x8846 // Client-32 | |
16002 | +#define NO_DIRECTORY_SERVICE_CONNECTION 0x8846 // 70 | |
16003 | +#define SERVICE_BUSY 0x8846 // 70 - Attempted request made to partially asynchronous function in busy state | |
16004 | +#define NO_SERVER_ERROR 0x8847 // 71 - Attempted connect failed to find any servers responding | |
16005 | +#define BAD_VLM_ERROR 0x8848 // 72 - Attempted function call to non-existant or not-loaded overlay | |
16006 | +#define NETWORK_DRIVE_IN_USE 0x8849 // 73 - Attempted map to network drive that was already mapped | |
16007 | +#define LOCAL_DRIVE_IN_USE 0x884A // 74 - Attempted map to local drive that was in use | |
16008 | +#define NO_DRIVES_AVAILABLE 0x884B // 75 - Attempted map to next available drive when none were available | |
16009 | +#define DEVICE_NOT_REDIRECTED 0x884C // 76 - The device is not redirected | |
16010 | +#define NO_MORE_SFT_ENTRIES 0x884D // 77 - Maximum number of files was reached | |
16011 | +#define UNLOAD_ERROR 0x884E // 78 - Attempted unload failed | |
16012 | +#define IN_USE_ERROR 0x884F // 79 - Attempted re-use of already in use connection entry | |
16013 | +#define TOO_MANY_REP_FRAGS 0x8850 // 80 - Attempted request with too many reply fragments specified | |
16014 | +#define TABLE_FULL 0x8851 // 81 - Attempted to add a name into the name table after it was full | |
16015 | +#ifndef SOCKET_NOT_OPEN | |
16016 | +#define SOCKET_NOT_OPEN 0x8852 // 82 - Listen was posted on unopened socket | |
16017 | +#endif | |
16018 | +#define MEM_MGR_ERROR 0x8853 // 83 - Attempted enhanced memory operation failed | |
16019 | +#define SFT3_ERROR 0x8854 // 84 - An SFT3 switch occured mid-transfer | |
16020 | +#define PREFERRED_NOT_FOUND 0x8855 // 85 - the preferred directory server was not established but another directory server was returned | |
16021 | +#define DEVICE_NOT_RECOGNIZED 0x8856 // 86 - used to determine if the device is not used by VISE so pass it on to the next redirector, if any. | |
16022 | +#define BAD_NET_TYPE 0x8857 // 87 - the network type (Bind/NDS) does not match the server version | |
16023 | +#define ERROR_OPENING_FILE 0x8858 // 88 - generic open failure error, invalid path, access denied, etc.. | |
16024 | +#define NO_PREFERRED_SPECIFIED 0x8859 // 89 - no preferred name specified | |
16025 | +#define ERROR_OPENING_SOCKET 0x885A // 90 - error opening a socket | |
16026 | +#define REQUESTER_FAILURE 0x885A // Client-32 | |
16027 | +#define RESOURCE_ACCESS_DENIED 0x885B // Client-32 | |
16028 | +#define SIGNATURE_LEVEL_CONFLICT 0x8861 | |
16029 | +#define NO_LOCK_FOUND 0x8862 // OS/2 - process lock on conn handle failed, process ID not recognized | |
16030 | +#define LOCK_TABLE_FULL 0x8863 // OS/2 - process lock on conn handle failed, process lock table full | |
16031 | +#define INVALID_MATCH_DATA 0x8864 | |
16032 | +#define MATCH_FAILED 0x8865 | |
16033 | +#define NO_MORE_ENTRIES 0x8866 | |
16034 | +#define INSUFFICIENT_RESOURCES 0x8867 | |
16035 | +#define STRING_TRANSLATION 0x8868 | |
16036 | +#define STRING_TRANSLATION_NEEDED 0x8868 // Client-32 | |
16037 | +#define ACCESS_VIOLATION 0x8869 | |
16038 | +#define NOT_AUTHENTICATED 0x886A | |
16039 | +#define INVALID_LEVEL 0x886B | |
16040 | +#define RESOURCE_LOCK_ERROR 0x886C | |
16041 | +#define INVALID_NAME_FORMAT 0x886D | |
16042 | +#define OBJECT_EXISTS 0x886E | |
16043 | +#define OBJECT_NOT_FOUND 0x886F | |
16044 | +#define UNSUPPORTED_TRAN_TYPE 0x8870 | |
16045 | +#define INVALID_STRING_TYPE 0x8871 | |
16046 | +#define INVALID_OWNER 0x8872 | |
16047 | +#define UNSUPPORTED_AUTHENTICATOR 0x8873 | |
16048 | +#define IO_PENDING 0x8874 | |
16049 | +#define INVALID_DRIVE_NUM 0x8875 | |
16050 | +#define SHELL_FAILURE 0x88FF | |
16051 | +#define VLM_FAILURE 0x88FF | |
16052 | + | |
16053 | +#define SVC_ALREADY_REGISTERED 0x8880 // Client-32 | |
16054 | +#define SVC_REGISTRY_FULL 0x8881 // Client-32 | |
16055 | +#define SVC_NOT_REGISTERED 0x8882 // Client-32 | |
16056 | +#define OUT_OF_RESOURCES 0x8883 // Client-32 | |
16057 | +#define RESOLVE_SVC_FAILED 0x8884 // Client-32 | |
16058 | +#define CONNECT_FAILED 0x8885 // Client-32 | |
16059 | +#define PROTOCOL_NOT_BOUND 0x8886 // Client-32 | |
16060 | +#define AUTHENTICATION_FAILED 0x8887 // Client-32 | |
16061 | +#define INVALID_AUTHEN_HANDLE 0x8888 // Client-32 | |
16062 | +#define AUTHEN_HANDLE_ALREADY_EXISTS 0x8889 // Client-32 | |
16063 | + | |
16064 | +#define DIFF_OBJECT_ALREADY_AUTHEN 0x8890 // Client-32 | |
16065 | +#define REQUEST_NOT_SERVICEABLE 0x8891 // Client-32 | |
16066 | +#define AUTO_RECONNECT_SO_REBUILD 0x8892 // Client-32 | |
16067 | +#define AUTO_RECONNECT_RETRY_REQUEST 0x8893 // Client-32 | |
16068 | +#define ASYNC_REQUEST_IN_USE 0x8894 // Client-32 | |
16069 | +#define ASYNC_REQUEST_CANCELED 0x8895 // Client-32 | |
16070 | +#define SESS_SVC_ALREADY_REGISTERED 0x8896 // Client-32 | |
16071 | +#define SESS_SVC_NOT_REGISTERED 0x8897 // Client-32 | |
16072 | +#define PREVIOUSLY_AUTHENTICATED 0x8899 // Client-32 | |
16073 | +#define RESOLVE_SVC_PARTIAL 0x889A // Client-32 | |
16074 | +#define NO_DEFAULT_SPECIFIED 0x889B // Client-32 | |
16075 | +#define HOOK_REQUEST_NOT_HANDLED 0x889C // Client-32 | |
16076 | +#define HOOK_REQUEST_BUSY 0x889D // Client-32 | |
16077 | +#define HOOK_REQUEST_QUEUED 0x889D // Client-32 | |
16078 | +#define AUTO_RECONNECT_SO_IGNORE 0x889E // Client-32 | |
16079 | +#define ASYNC_REQUEST_NOT_IN_USE 0x889F // Client-32 | |
16080 | +#define AUTO_RECONNECT_FAILURE 0x88A0 // Client-32 | |
16081 | +#define NET_ERROR_ABORT_APPLICATION 0x88A1 // Client-32 | |
16082 | +#define NET_ERROR_SUSPEND_APPLICATION 0x88A2 // Client-32 | |
16083 | +#define NET_ERROR_ABORTED_PROCESS_GROUP 0x88A3 // Client-32 | |
16084 | +#define NET_ERROR_PASSWORD_HAS_EXPIRED 0x88A5 // Client-32 | |
16085 | +#define NET_ERROR_NETWORK_INACTIVE 0x88A6 // Client-32 | |
16086 | +#define REPLY_TRUNCATED 0x88E6 // 230 NLM | |
16087 | +#define UTF8_CONVERSION_FAILED 0x88F0 // NWCALLS | |
16088 | + | |
16089 | +/* | |
16090 | + * Server Errors | |
16091 | + */ | |
16092 | + | |
16093 | +#define ERR_INSUFFICIENT_SPACE 0x8901 // 001 | |
16094 | +#define NLM_INVALID_CONNECTION 0x890A // 010 | |
16095 | +#define ERR_TIMEOUT 0x8910 // 016 - nlm connection timeout | |
16096 | +#define ERR_NO_MORE_ENTRY 0x8914 // 020 | |
16097 | +#define ERR_BUFFER_TOO_SMALL 0x8977 // 119 | |
16098 | +#define ERR_VOLUME_FLAG_NOT_SET 0x8978 // 120 the service requested, not avail. on the selected vol. | |
16099 | +#define ERR_NO_ITEMS_FOUND 0x8979 // 121 | |
16100 | +#define ERR_CONN_ALREADY_TEMP 0x897A // 122 | |
16101 | +#define ERR_CONN_ALREADY_LOGGED_IN 0x897B // 123 | |
16102 | +#define ERR_CONN_NOT_AUTHENTICATED 0x897C // 124 | |
16103 | +#define ERR_CONN_NOT_LOGGED_IN 0x897D // 125 | |
16104 | +#define NCP_BOUNDARY_CHECK_FAILED 0x897E // 126 | |
16105 | +#define ERR_LOCK_WAITING 0x897F // 127 | |
16106 | +#define ERR_LOCK_FAIL 0x8980 // 128 | |
16107 | +#define FILE_IN_USE_ERROR 0x8980 // 128 | |
16108 | +#define NO_MORE_FILE_HANDLES 0x8981 // 129 | |
16109 | +#define NO_OPEN_PRIVILEGES 0x8982 // 130 | |
16110 | +#define IO_ERROR_NETWORK_DISK 0x8983 // 131 | |
16111 | +#define ERR_AUDITING_HARD_IO_ERROR 0x8983 // 131 | |
16112 | +#define NO_CREATE_PRIVILEGES 0x8984 // 132 | |
16113 | +#define ERR_AUDITING_NOT_SUPV 0x8984 // 132 | |
16114 | +#define NO_CREATE_DELETE_PRIVILEGES 0x8985 // 133 | |
16115 | +#define CREATE_FILE_EXISTS_READ_ONLY 0x8986 // 134 | |
16116 | +#define WILD_CARDS_IN_CREATE_FILE_NAME 0x8987 // 135 | |
16117 | +#define CREATE_FILENAME_ERROR 0x8987 // 135 | |
16118 | +#define INVALID_FILE_HANDLE 0x8988 // 136 | |
16119 | +#define NO_SEARCH_PRIVILEGES 0x8989 // 137 | |
16120 | +#define NO_DELETE_PRIVILEGES 0x898A // 138 | |
16121 | +#define NO_RENAME_PRIVILEGES 0x898B // 139 | |
16122 | +#define NO_MODIFY_PRIVILEGES 0x898C // 140 | |
16123 | +#define SOME_FILES_AFFECTED_IN_USE 0x898D // 141 | |
16124 | +#define NO_FILES_AFFECTED_IN_USE 0x898E // 142 | |
16125 | +#define SOME_FILES_AFFECTED_READ_ONLY 0x898F // 143 | |
16126 | +#define NO_FILES_AFFECTED_READ_ONLY 0x8990 // 144 | |
16127 | +#define SOME_FILES_RENAMED_NAME_EXISTS 0x8991 // 145 | |
16128 | +#define NO_FILES_RENAMED_NAME_EXISTS 0x8992 // 146 | |
16129 | +#define NO_READ_PRIVILEGES 0x8993 // 147 | |
16130 | +#define NO_WRITE_PRIVILEGES_OR_READONLY 0x8994 // 148 | |
16131 | +#define FILE_DETACHED 0x8995 // 149 | |
16132 | +#define SERVER_OUT_OF_MEMORY 0x8996 // 150 | |
16133 | +#define ERR_TARGET_NOT_A_SUBDIRECTORY 0x8996 // 150 can be changed later (note written by server people). | |
16134 | +#define NO_DISK_SPACE_FOR_SPOOL_FILE 0x8997 // 151 | |
16135 | +#define ERR_AUDITING_NOT_ENABLED 0x8997 // 151 | |
16136 | +#define VOLUME_DOES_NOT_EXIST 0x8998 // 152 | |
16137 | +#define DIRECTORY_FULL 0x8999 // 153 | |
16138 | +#define RENAMING_ACROSS_VOLUMES 0x899A // 154 | |
16139 | +#define BAD_DIRECTORY_HANDLE 0x899B // 155 | |
16140 | +#define INVALID_PATH 0x899C // 156 | |
16141 | +#define NO_MORE_TRUSTEES 0x899C // 156 | |
16142 | +#define NO_MORE_DIRECTORY_HANDLES 0x899D // 157 | |
16143 | +#define INVALID_FILENAME 0x899E // 158 | |
16144 | +#define DIRECTORY_ACTIVE 0x899F // 159 | |
16145 | +#define DIRECTORY_NOT_EMPTY 0x89A0 // 160 | |
16146 | +#define DIRECTORY_IO_ERROR 0x89A1 // 161 | |
16147 | +#define READ_FILE_WITH_RECORD_LOCKED 0x89A2 // 162 | |
16148 | +#define ERR_TRANSACTION_RESTARTED 0x89A3 // 163 | |
16149 | +#define ERR_RENAME_DIR_INVALID 0x89A4 // 164 | |
16150 | +#define ERR_INVALID_OPENCREATE_MODE 0x89A5 // 165 | |
16151 | +#define ERR_ALREADY_IN_USE 0x89A6 // 166 | |
16152 | +#define ERR_AUDITING_ACTIVE 0x89A6 // 166 | |
16153 | +#define ERR_INVALID_RESOURCE_TAG 0x89A7 // 167 | |
16154 | +#define ERR_ACCESS_DENIED 0x89A8 // 168 | |
16155 | +#define ERR_AUDITING_NO_RIGHTS 0x89A8 // 168 | |
16156 | +#define ERR_LINK_IN_PATH 0x89A9 // 169 | |
16157 | +#define INVALID_DATA_TYPE 0x89AA // 170 | |
16158 | +#define INVALID_DATA_STREAM 0x89BE // 190 | |
16159 | +#define INVALID_NAME_SPACE 0x89BF // 191 | |
16160 | +#define NO_ACCOUNTING_PRIVILEGES 0x89C0 // 192 | |
16161 | +#define LOGIN_DENIED_NO_ACCOUNT_BALANCE 0x89C1 // 193 | |
16162 | +#define LOGIN_DENIED_NO_CREDIT 0x89C2 // 194 | |
16163 | +#define ERR_AUDITING_RECORD_SIZE 0x89C2 // 194 | |
16164 | +#define ERR_TOO_MANY_HOLDS 0x89C3 // 195 | |
16165 | +#define ACCOUNTING_DISABLED 0x89C4 // 196 | |
16166 | +#define INTRUDER_DETECTION_LOCK 0x89C5 // 197 | |
16167 | +#define NO_CONSOLE_OPERATOR 0x89C6 // 198 | |
16168 | +#define NO_CONSOLE_PRIVILEGES 0x89C6 // 198 | |
16169 | +#define ERR_Q_IO_FAILURE 0x89D0 // 208 | |
16170 | +#define ERR_NO_QUEUE 0x89D1 // 209 | |
16171 | +#define ERR_NO_Q_SERVER 0x89D2 // 210 | |
16172 | +#define ERR_NO_Q_RIGHTS 0x89D3 // 211 | |
16173 | +#define ERR_Q_FULL 0x89D4 // 212 | |
16174 | +#define ERR_NO_Q_JOB 0x89D5 // 213 | |
16175 | +#define ERR_NO_Q_JOB_RIGHTS 0x89D6 // 214 | |
16176 | +#define ERR_Q_IN_SERVICE 0x89D7 // 215 | |
16177 | +#define PASSWORD_NOT_UNIQUE 0x89D7 // 215 | |
16178 | +#define ERR_Q_NOT_ACTIVE 0x89D8 // 216 | |
16179 | +#define PASSWORD_TOO_SHORT 0x89D8 // 216 | |
16180 | +#define ERR_Q_STN_NOT_SERVER 0x89D9 // 217 | |
16181 | +#define LOGIN_DENIED_NO_CONNECTION 0x89D9 // 217 | |
16182 | +#define ERR_MAXIMUM_LOGINS_EXCEEDED 0x89D9 // 217 | |
16183 | +#define ERR_Q_HALTED 0x89DA // 218 | |
16184 | +#define UNAUTHORIZED_LOGIN_TIME 0x89DA // 218 | |
16185 | +#define UNAUTHORIZED_LOGIN_STATION 0x89DB // 219 | |
16186 | +#define ERR_Q_MAX_SERVERS 0x89DB // 219 | |
16187 | +#define ACCOUNT_DISABLED 0x89DC // 220 | |
16188 | +#define PASSWORD_HAS_EXPIRED_NO_GRACE 0x89DE // 222 | |
16189 | +#define PASSWORD_HAS_EXPIRED 0x89DF // 223 | |
16190 | +#define E_NO_MORE_USERS 0x89E7 // 231 | |
16191 | +#define NOT_ITEM_PROPERTY 0x89E8 // 232 | |
16192 | +#define WRITE_PROPERTY_TO_GROUP 0x89E8 // 232 | |
16193 | +#define MEMBER_ALREADY_EXISTS 0x89E9 // 233 | |
16194 | +#define NO_SUCH_MEMBER 0x89EA // 234 | |
16195 | +#define NOT_GROUP_PROPERTY 0x89EB // 235 | |
16196 | +#define NO_SUCH_SEGMENT 0x89EC // 236 | |
16197 | +#define PROPERTY_ALREADY_EXISTS 0x89ED // 237 | |
16198 | +#define OBJECT_ALREADY_EXISTS 0x89EE // 238 | |
16199 | +#define INVALID_NAME 0x89EF // 239 | |
16200 | +#define WILD_CARD_NOT_ALLOWED 0x89F0 // 240 | |
16201 | +#define INVALID_BINDERY_SECURITY 0x89F1 // 241 | |
16202 | +#define NO_OBJECT_READ_PRIVILEGE 0x89F2 // 242 | |
16203 | +#define NO_OBJECT_RENAME_PRIVILEGE 0x89F3 // 243 | |
16204 | +#define NO_OBJECT_DELETE_PRIVILEGE 0x89F4 // 244 | |
16205 | +#define NO_OBJECT_CREATE_PRIVILEGE 0x89F5 // 245 | |
16206 | +#define NO_PROPERTY_DELETE_PRIVILEGE 0x89F6 // 246 | |
16207 | +#define NO_PROPERTY_CREATE_PRIVILEGE 0x89F7 // 247 | |
16208 | +#define NO_PROPERTY_WRITE_PRIVILEGE 0x89F8 // 248 | |
16209 | +#define NO_FREE_CONNECTION_SLOTS 0x89F9 // 249 | |
16210 | +#define NO_PROPERTY_READ_PRIVILEGE 0x89F9 // 249 | |
16211 | +#define NO_MORE_SERVER_SLOTS 0x89FA // 250 | |
16212 | +#define TEMP_REMAP_ERROR 0x89FA // 250 | |
16213 | +#define INVALID_PARAMETERS 0x89FB // 251 | |
16214 | +#define NO_SUCH_PROPERTY 0x89FB // 251 | |
16215 | +#define ERR_NCP_NOT_SUPPORTED 0x89FB // 251 | |
16216 | +#define INTERNET_PACKET_REQT_CANCELED 0x89FC // 252 | |
16217 | +#define UNKNOWN_FILE_SERVER 0x89FC // 252 | |
16218 | +#define MESSAGE_QUEUE_FULL 0x89FC // 252 | |
16219 | +#define NO_SUCH_OBJECT 0x89FC // 252 | |
16220 | +#define LOCK_COLLISION 0x89FD // 253 | |
16221 | +#define BAD_STATION_NUMBER 0x89FD // 253 | |
16222 | +#define INVALID_PACKET_LENGTH 0x89FD // 253 | |
16223 | +#define UNKNOWN_REQUEST 0x89FD // 253 | |
16224 | +#define BINDERY_LOCKED 0x89FE // 254 | |
16225 | +#define TRUSTEE_NOT_FOUND 0x89FE // 254 | |
16226 | +#define DIRECTORY_LOCKED 0x89FE // 254 | |
16227 | +#define INVALID_SEMAPHORE_NAME_LENGTH 0x89FE // 254 | |
16228 | +#define PACKET_NOT_DELIVERABLE 0x89FE // 254 | |
16229 | +#define SERVER_BINDERY_LOCKED 0x89FE // 254 | |
16230 | +#define SOCKET_TABLE_FULL 0x89FE // 254 | |
16231 | +#define SPOOL_DIRECTORY_ERROR 0x89FE // 254 | |
16232 | +#define SUPERVISOR_HAS_DISABLED_LOGIN 0x89FE // 254 | |
16233 | +#define TIMEOUT_FAILURE 0x89FE // 254 | |
16234 | +#define BAD_PRINTER_ERROR 0x89FF // 255 | |
16235 | +#define BAD_RECORD_OFFSET 0x89FF // 255 | |
16236 | +#define CLOSE_FCB_ERROR 0x89FF // 255 | |
16237 | +#define FILE_EXTENSION_ERROR 0x89FF // 255 | |
16238 | +#define FILE_NAME_ERROR 0x89FF // 255 | |
16239 | +#define HARDWARE_FAILURE 0x89FF // 255 | |
16240 | +#define INVALID_DRIVE_NUMBER 0x89FF // 255 | |
16241 | +#define DOS_INVALID_DRIVE 0x000F // 255 | |
16242 | +#define INVALID_INITIAL_SEMAPHORE_VALUE 0x89FF // 255 | |
16243 | +#define INVALID_SEMAPHORE_HANDLE 0x89FF // 255 | |
16244 | +#define IO_BOUND_ERROR 0x89FF // 255 | |
16245 | +#define NO_FILES_FOUND_ERROR 0x89FF // 255 | |
16246 | +#define NO_RESPONSE_FROM_SERVER 0x89FF // 255 | |
16247 | +#define NO_SUCH_OBJECT_OR_BAD_PASSWORD 0x89FF // 255 | |
16248 | +#define PATH_NOT_LOCATABLE 0x89FF // 255 | |
16249 | +#define QUEUE_FULL_ERROR 0x89FF // 255 | |
16250 | +#define REQUEST_NOT_OUTSTANDING 0x89FF // 255 | |
16251 | +#ifndef SOCKET_ALREADY_OPEN | |
16252 | +#define SOCKET_ALREADY_OPEN 0x89FF // 255 | |
16253 | +#endif | |
16254 | +#define LOCK_ERROR 0x89FF // 255 | |
16255 | +#ifndef FAILURE | |
16256 | +#define FAILURE 0x89FF // 255 Generic Failure | |
16257 | +#endif | |
16258 | + | |
16259 | +#if 0 | |
16260 | +#define NOT_SAME_LOCAL_DRIVE 0x89F6 | |
16261 | +#define TARGET_DRIVE_NOT_LOCAL 0x89F7 | |
16262 | +#define ALREADY_ATTACHED_TO_SERVER 0x89F8 // 248 | |
16263 | +#define NOT_ATTACHED_TO_SERVER 0x89F8 | |
16264 | +#endif | |
16265 | + | |
16266 | +/* | |
16267 | + * Network errors | |
16268 | + * Decimal values at end of line are 32768 lower than actual | |
16269 | + */ | |
16270 | +#define NWE_ALREADY_ATTACHED 0x8800 // 0 - Attach attempted to server with valid, existing connection | |
16271 | +#define NWE_CONN_INVALID 0x8801 // 1 - Request attempted with invalid or non-attached connection handle | |
16272 | +#define NWE_DRIVE_IN_USE 0x8802 // 2 - OS/2 only (NOT USED) | |
16273 | +#define NWE_DRIVE_CANNOT_MAP 0x8803 // 3 - Map drive attempted but unable to add new current directory structure | |
16274 | +#define NWE_DRIVE_BAD_PATH 0x8804 // 4 - Map drive attempted with invalid path specification | |
16275 | +#define NWE_NET_RECEIVE 0x8805 // 5 - Attempt to receive from the selected transport failed | |
16276 | +#define NWE_NET_UNKNOWN 0x8806 // 6 - Network send attempted with an un-specific network error | |
16277 | +#define NWE_SERVER_BAD_SLOT 0x8807 // 7 - Server request attempted with invalid server connection slot | |
16278 | +#define NWE_SERVER_NO_SLOTS 0x8808 // 8 - Attach attempted to server with no connection slots available | |
16279 | +#define NWE_NET_SEND 0x8809 // 9 - Attempt to send on the selected transport failed | |
16280 | +#define NWE_SERVER_NO_ROUTE 0x880A // 10 - Attempted to find route to server where no route exists | |
16281 | +#define NWE_BAD_LOCAL_TARGET 0x880B // 11 - OS/2 only | |
16282 | +#define NWE_REQ_TOO_MANY_REQ_FRAGS 0x880C // 12 - Attempted request with too many request fragments specified | |
16283 | +#define NWE_CONN_LIST_OVERFLOW 0x880D // 13 | |
16284 | +#define NWE_BUFFER_OVERFLOW 0x880E // 14 - Attempt to receive more data than the reply buffer had room for | |
16285 | +#define NWE_SERVER_NO_CONN 0x880F // 15 - Attempt to get connection for a server not connected | |
16286 | +#define NWE_NO_ROUTER_FOUND 0x8810 // 16 - OS/2 only | |
16287 | +#define NWE_FUNCTION_INVALID 0x8811 // 17 - Attempted function call to non- existent or illegal function | |
16288 | +#define NWE_SCAN_COMPLETE 0x8812 | |
16289 | +#define NWE_UNSUPPORTED_NAME_FORMAT_TYP 0x8813 | |
16290 | +#define NWE_HANDLE_ALREADY_LICENSED 0x8814 | |
16291 | +#define NWE_HANDLE_ALREADY_UNLICENSED 0x8815 | |
16292 | +#define NWE_INVALID_NCP_PACKET_LENGTH 0x8816 | |
16293 | +#define NWE_SETTING_UP_TIMEOUT 0x8817 | |
16294 | +#define NWE_SETTING_SIGNALS 0x8818 | |
16295 | +#define NWE_SERVER_CONNECTION_LOST 0x8819 | |
16296 | +#define NWE_OUT_OF_HEAP_SPACE 0x881A | |
16297 | +#define NWE_INVALID_SERVICE_REQUEST 0x881B | |
16298 | +#define NWE_INVALID_TASK_NUMBER 0x881C | |
16299 | +#define NWE_INVALID_MESSAGE_LENGTH 0x881D | |
16300 | +#define NWE_EA_SCAN_DONE 0x881E | |
16301 | +#define NWE_BAD_CONNECTION_NUMBER 0x881F | |
16302 | +#define NWE_MULT_TREES_NOT_SUPPORTED 0x8820 // 32 - Attempt to open a connection to a DS tree other than the default tree | |
16303 | +#define NWE_CONN_NOT_SAME 0x8830 // 48 - Internal server request attempted across different server connections | |
16304 | +#define NWE_CONN_PRIMARY_NOT_SET 0x8831 // 49 - Attempt to retrieve default connection with no primary connection set | |
16305 | +#define NWE_PRN_CAPTURE_NOT_IN_PROGRESS 0x8832 // 50 - Capture information requested on port with no capture in progress | |
16306 | +#define NWE_BUFFER_INVALID_LEN 0x8833 // 51 - Used to indicate length which caller requested on a GetDNC or SetDNC was too large | |
16307 | +#define NWE_USER_NO_NAME 0x8834 // 52 | |
16308 | +#define NWE_PRN_NO_LOCAL_SPOOLER 0x8835 // 53 - Capture requested without having the local print spooler installed | |
16309 | +#define NWE_PARAM_INVALID 0x8836 // 54 - Attempted function with an invalid function parameter specified | |
16310 | +#define NWE_CFG_OPEN_FAILED 0x8837 // 55 - OS/2 only | |
16311 | +#define NWE_CFG_NO_FILE 0x8838 // 56 - OS/2 only | |
16312 | +#define NWE_CFG_READ_FAILED 0x8839 // 57 - OS/2 only | |
16313 | +#define NWE_CFG_LINE_TOO_LONG 0x883A // 58 - OS/2 only | |
16314 | +#define NWE_CFG_LINES_IGNORED 0x883B // 59 - OS/2 only | |
16315 | +#define NWE_RESOURCE_NOT_OWNED 0x883C // 60 - Attempted request made with a parameter using foriegn resource | |
16316 | +#define NWE_DAEMON_INSTALLED 0x883D // 61 - OS/2 only | |
16317 | +#define NWE_PRN_SPOOLER_INSTALLED 0x883E // 62 - Attempted load of print spooler with print spooler already installed | |
16318 | +#define NWE_CONN_TABLE_FULL 0x883F // 63 - Attempted to allocate a connection handle with no more local connection table entries | |
16319 | +#define NWE_CFG_SECTION_NOT_FOUND 0x8840 // 64 - OS/2 only | |
16320 | +#define NWE_TRAN_INVALID_TYPE 0x8841 // 65 - Attempted function on a connection with an invalid transport selected | |
16321 | +#define NWE_TDS_TAG_IN_USE 0x8842 // 66 - OS/2 only | |
16322 | +#define NWE_TDS_OUT_OF_MEMORY 0x8843 // 67 - OS/2 only | |
16323 | +#define NWE_TDS_INVALID_TAG 0x8844 // 68 - Attempted TDS function with invalid tag | |
16324 | +#define NWE_TDS_WRITE_TRUNCATED 0x8845 // 69 - Attempted TDS write with buffer that exceeded buffer | |
16325 | +#define NWE_DS_NO_CONN 0x8846 // 70 | |
16326 | +#define NWE_SERVICE_BUSY 0x8846 // 70 - Attempted request made to partially asynchronous function in busy state | |
16327 | +#define NWE_SERVER_NOT_FOUND 0x8847 // 71 - Attempted connect failed to find any servers responding | |
16328 | +#define NWE_VLM_INVALID 0x8848 // 72 - Attempted function call to non-existant or not-loaded overlay | |
16329 | +#define NWE_DRIVE_ALREADY_MAPPED 0x8849 // 73 - Attempted map to network drive that was already mapped | |
16330 | +#define NWE_DRIVE_LOCAL_IN_USE 0x884A // 74 - Attempted map to local drive that was in use | |
16331 | +#define NWE_DRIVE_NONE_AVAILABLE 0x884B // 75 - Attempted map to next available drive when none were available | |
16332 | +#define NWE_DEVICE_NOT_REDIRECTED 0x884C // 76 - The device is not redirected | |
16333 | +#define NWE_FILE_MAX_REACHED 0x884D // 77 - Maximum number of files was reached | |
16334 | +#define NWE_UNLOAD_FAILED 0x884E // 78 - Attempted unload failed | |
16335 | +#define NWE_CONN_IN_USE 0x884F // 79 - Attempted re-use of already in use connection entry | |
16336 | +#define NWE_REQ_TOO_MANY_REP_FRAGS 0x8850 // 80 - Attempted request with too many reply fragments specified | |
16337 | +#define NWE_NAME_TABLE_FULL 0x8851 // 81 - Attempted to add a name into the name table after it was full | |
16338 | +#define NWE_SOCKET_NOT_OPEN 0x8852 // 82 - Listen was posted on unopened socket | |
16339 | +#define NWE_MEMORY_MGR_ERROR 0x8853 // 83 - Attempted enhanced memory operation failed | |
16340 | +#define NWE_SFT3_ERROR 0x8854 // 84 - An SFT3 switch occured mid-transfer | |
16341 | +#define NWE_DS_PREFERRED_NOT_FOUND 0x8855 // 85 - the preferred directory server was not established but another directory server was returned | |
16342 | +#define NWE_DEVICE_NOT_RECOGNIZED 0x8856 // 86 - used to determine if the device is not used by VISE so pass it on to the next redirector, if any. | |
16343 | +#define NWE_NET_INVALID_TYPE 0x8857 // 87 - the network type (Bind/NDS) does not match the server version | |
16344 | +#define NWE_FILE_OPEN_FAILED 0x8858 // 88 - generic open failure error, invalid path, access denied, etc.. | |
16345 | +#define NWE_DS_PREFERRED_NOT_SPECIFIED 0x8859 // 89 - no preferred name specified | |
16346 | +#define NWE_SOCKET_OPEN_FAILED 0x885A // 90 - error opening a socket | |
16347 | +#define NWE_SIGNATURE_LEVEL_CONFLICT 0x8861 | |
16348 | +#define NWE_NO_LOCK_FOUND 0x8862 // OS/2 - process lock on conn handle failed, process ID not recognized | |
16349 | +#define NWE_LOCK_TABLE_FULL 0x8863 // OS/2 - process lock on conn handle failed, process lock table full | |
16350 | +#define NWE_INVALID_MATCH_DATA 0x8864 | |
16351 | +#define NWE_MATCH_FAILED 0x8865 | |
16352 | +#define NWE_NO_MORE_ENTRIES 0x8866 | |
16353 | +#define NWE_INSUFFICIENT_RESOURCES 0x8867 | |
16354 | +#define NWE_STRING_TRANSLATION 0x8868 | |
16355 | +#define NWE_ACCESS_VIOLATION 0x8869 | |
16356 | +#define NWE_NOT_AUTHENTICATED 0x886A | |
16357 | +#define NWE_INVALID_LEVEL 0x886B | |
16358 | +#define NWE_RESOURCE_LOCK 0x886C | |
16359 | +#define NWE_INVALID_NAME_FORMAT 0x886D | |
16360 | +#define NWE_OBJECT_EXISTS 0x886E | |
16361 | +#define NWE_OBJECT_NOT_FOUND 0x886F | |
16362 | +#define NWE_UNSUPPORTED_TRAN_TYPE 0x8870 | |
16363 | +#define NWE_INVALID_STRING_TYPE 0x8871 | |
16364 | +#define NWE_INVALID_OWNER 0x8872 | |
16365 | +#define NWE_UNSUPPORTED_AUTHENTICATOR 0x8873 | |
16366 | +#define NWE_IO_PENDING 0x8874 | |
16367 | +#define NWE_INVALID_DRIVE_NUMBER 0x8875 | |
16368 | +#define NWE_REPLY_TRUNCATED 0x88e6 // 230 NLM | |
16369 | +#define NWE_REQUESTER_FAILURE 0x88FF | |
16370 | + | |
16371 | +/* | |
16372 | + * Server Errors | |
16373 | + */ | |
16374 | +#define NWE_INSUFFICIENT_SPACE 0x8901 // 001 | |
16375 | +#define NWE_INVALID_CONNECTION 0x890a // 010 - nlm invalid connection | |
16376 | +#define NWE_TIMEOUT 0x8910 // 016 - nlm connection timeout | |
16377 | +#define NWE_NO_MORE_ENTRY 0x8914 // 020 | |
16378 | +#define NWE_BUFFER_TOO_SMALL 0x8977 // 119 | |
16379 | +#define NWE_VOL_FLAG_NOT_SET 0x8978 // 120 the service requested, not avail. on the selected vol. | |
16380 | +#define NWE_NO_ITEMS_FOUND 0x8979 // 121 | |
16381 | +#define NWE_CONN_ALREADY_TEMP 0x897a // 122 | |
16382 | +#define NWE_CONN_ALREADY_LOGGED_IN 0x897b // 123 | |
16383 | +#define NWE_CONN_NOT_AUTHENTICATED 0x897c // 124 | |
16384 | +#define NWE_CONN_NOT_LOGGED_IN 0x897d // 125 | |
16385 | +#define NWE_NCP_BOUNDARY_CHECK_FAILED 0x897e // 126 | |
16386 | +#define NWE_LOCK_WAITING 0x897f // 127 | |
16387 | +#define NWE_LOCK_FAIL 0x8980 // 128 | |
16388 | +#define NWE_FILE_IN_USE 0x8980 // 128 | |
16389 | +#define NWE_FILE_NO_HANDLES 0x8981 // 129 | |
16390 | +#define NWE_FILE_NO_OPEN_PRIV 0x8982 // 130 | |
16391 | +#define NWE_DISK_IO_ERROR 0x8983 // 131 | |
16392 | +#define NWE_AUDITING_HARD_IO_ERROR 0x8983 // 131 | |
16393 | +#define NWE_FILE_NO_CREATE_PRIV 0x8984 // 132 | |
16394 | +#define NWE_AUDITING_NOT_SUPV 0x8984 // 132 | |
16395 | +#define NWE_FILE_NO_CREATE_DEL_PRIV 0x8985 // 133 | |
16396 | +#define NWE_FILE_EXISTS_READ_ONLY 0x8986 // 134 | |
16397 | +#define NWE_FILE_WILD_CARDS_IN_NAME 0x8987 // 135 | |
16398 | +#define NWE_FILE_INVALID_HANDLE 0x8988 // 136 | |
16399 | +#define NWE_FILE_NO_SRCH_PRIV 0x8989 // 137 | |
16400 | +#define NWE_FILE_NO_DEL_PRIV 0x898A // 138 | |
16401 | +#define NWE_FILE_NO_RENAME_PRIV 0x898B // 139 | |
16402 | +#define NWE_FILE_NO_MOD_PRIV 0x898C // 140 | |
16403 | +#define NWE_FILE_SOME_IN_USE 0x898D // 141 | |
16404 | +#define NWE_FILE_NONE_IN_USE 0x898E // 142 | |
16405 | +#define NWE_FILE_SOME_READ_ONLY 0x898F // 143 | |
16406 | +#define NWE_FILE_NONE_READ_ONLY 0x8990 // 144 | |
16407 | +#define NWE_FILE_SOME_RENAMED_EXIST 0x8991 // 145 | |
16408 | +#define NWE_FILE_NONE_RENAMED_EXIST 0x8992 // 146 | |
16409 | +#define NWE_FILE_NO_READ_PRIV 0x8993 // 147 | |
16410 | +#define NWE_FILE_NO_WRITE_PRIV 0x8994 // 148 | |
16411 | +#define NWE_FILE_READ_ONLY 0x8994 // 148 | |
16412 | +#define NWE_FILE_DETACHED 0x8995 // 149 | |
16413 | +#define NWE_SERVER_OUT_OF_MEMORY 0x8996 // 150 | |
16414 | +#define NWE_DIR_TARGET_INVALID 0x8996 // 150 | |
16415 | +#define NWE_DISK_NO_SPOOL_SPACE 0x8997 // 151 | |
16416 | +#define NWE_AUDITING_NOT_ENABLED 0x8997 // 151 | |
16417 | +#define NWE_VOL_INVALID 0x8998 // 152 | |
16418 | +#define NWE_DIR_FULL 0x8999 // 153 | |
16419 | +#define NWE_VOL_RENAMING_ACROSS 0x899A // 154 | |
16420 | +#define NWE_DIRHANDLE_INVALID 0x899B // 155 | |
16421 | +#define NWE_PATH_INVALID 0x899C // 156 | |
16422 | +#define NWE_TRUSTEES_NO_MORE 0x899C // 156 | |
16423 | +#define NWE_DIRHANDLE_NO_MORE 0x899D // 157 | |
16424 | +#define NWE_FILE_NAME_INVALID 0x899E // 158 | |
16425 | +#define NWE_DIR_ACTIVE 0x899F // 159 | |
16426 | +#define NWE_DIR_NOT_EMPTY 0x89A0 // 160 | |
16427 | +#define NWE_DIR_IO_ERROR 0x89A1 // 161 | |
16428 | +#define NWE_FILE_IO_LOCKED 0x89A2 // 162 | |
16429 | +#define NWE_TTS_RANSACTION_RESTARTED 0x89A3 // 163 | |
16430 | +#define NWE_TTS_TRANSACTION_RESTARTED 0x89A3 // 163 | |
16431 | +#define NWE_DIR_RENAME_INVALID 0x89A4 // 164 | |
16432 | +#define NWE_FILE_OPENCREAT_MODE_INVALID 0x89A5 // 165 | |
16433 | +#define NWE_ALREADY_IN_USE 0x89A6 // 166 | |
16434 | +#define NWE_AUDITING_ACTIVE 0x89A6 // 166 | |
16435 | +#define NWE_RESOURCE_TAG_INVALID 0x89A7 // 167 | |
16436 | +#define NWE_ACCESS_DENIED 0x89A8 // 168 | |
16437 | +#define NWE_AUDITING_NO_RIGHTS 0x89A8 // 168 | |
16438 | +#define NWE_LINK_IN_PATH 0x89A9 // 169 | |
16439 | +#define NWE_INVALID_DATA_TYPE_FLAG 0x89AA // 170 (legacy vol with UTF8) | |
16440 | +#define NWE_DATA_STREAM_INVALID 0x89BE // 190 | |
16441 | +#define NWE_NAME_SPACE_INVALID 0x89BF // 191 | |
16442 | +#define NWE_ACCTING_NO_PRIV 0x89C0 // 192 | |
16443 | +#define NWE_ACCTING_NO_BALANCE 0x89C1 // 193 | |
16444 | +#define NWE_ACCTING_NO_CREDIT 0x89C2 // 194 | |
16445 | +#define NWE_AUDITING_RECORD_SIZE 0x89C2 // 194 | |
16446 | +#define NWE_ACCTING_TOO_MANY_HOLDS 0x89C3 // 195 | |
16447 | +#define NWE_ACCTING_DISABLED 0x89C4 // 196 | |
16448 | +#define NWE_LOGIN_LOCKOUT 0x89C5 // 197 | |
16449 | +#define NWE_CONSOLE_NO_PRIV 0x89C6 // 198 | |
16450 | +#define NWE_Q_IO_FAILURE 0x89D0 // 208 | |
16451 | +#define NWE_Q_NONE 0x89D1 // 209 | |
16452 | +#define NWE_Q_NO_SERVER 0x89D2 // 210 | |
16453 | +#define NWE_Q_NO_RIGHTS 0x89D3 // 211 | |
16454 | +#define NWE_Q_FULL 0x89D4 // 212 | |
16455 | +#define NWE_Q_NO_JOB 0x89D5 // 213 | |
16456 | +#define NWE_Q_NO_JOB_RIGHTS 0x89D6 // 214 | |
16457 | +#define NWE_PASSWORD_UNENCRYPTED 0x89D6 // 214 | |
16458 | +#define NWE_Q_IN_SERVICE 0x89D7 // 215 | |
16459 | +#define NWE_PASSWORD_NOT_UNIQUE 0x89D7 // 215 | |
16460 | +#define NWE_Q_NOT_ACTIVE 0x89D8 // 216 | |
16461 | +#define NWE_PASSWORD_TOO_SHORT 0x89D8 // 216 | |
16462 | +#define NWE_Q_STN_NOT_SERVER 0x89D9 // 217 | |
16463 | +#define NWE_LOGIN_NO_CONN 0x89D9 // 217 | |
16464 | +#define NWE_LOGIN_MAX_EXCEEDED 0x89D9 // 217 | |
16465 | +#define NWE_Q_HALTED 0x89DA // 218 | |
16466 | +#define NWE_LOGIN_UNAUTHORIZED_TIME 0x89DA // 218 | |
16467 | +#define NWE_LOGIN_UNAUTHORIZED_STATION 0x89DB // 219 | |
16468 | +#define NWE_Q_MAX_SERVERS 0x89DB // 219 | |
16469 | +#define NWE_ACCT_DISABLED 0x89DC // 220 | |
16470 | +#define NWE_PASSWORD_INVALID 0x89DE // 222 | |
16471 | +#define NWE_PASSWORD_EXPIRED 0x89DF // 223 | |
16472 | +#define NWE_LOGIN_NO_CONN_AVAIL 0x89E0 // 224 | |
16473 | +#define NWE_E_NO_MORE_USERS 0x89E7 // 231 | |
16474 | +#define NWE_BIND_NOT_ITEM_PROP 0x89E8 // 232 | |
16475 | +#define NWE_BIND_WRITE_TO_GROUP_PROP 0x89E8 // 232 | |
16476 | +#define NWE_BIND_MEMBER_ALREADY_EXISTS 0x89E9 // 233 | |
16477 | +#define NWE_BIND_NO_SUCH_MEMBER 0x89EA // 234 | |
16478 | +#define NWE_BIND_NOT_GROUP_PROP 0x89EB // 235 | |
16479 | +#define NWE_BIND_NO_SUCH_SEGMENT 0x89EC // 236 | |
16480 | +#define NWE_BIND_PROP_ALREADY_EXISTS 0x89ED // 237 | |
16481 | +#define NWE_BIND_OBJ_ALREADY_EXISTS 0x89EE // 238 | |
16482 | +#define NWE_BIND_NAME_INVALID 0x89EF // 239 | |
16483 | +#define NWE_BIND_WILDCARD_INVALID 0x89F0 // 240 | |
16484 | +#define NWE_BIND_SECURITY_INVALID 0x89F1 // 241 | |
16485 | +#define NWE_BIND_OBJ_NO_READ_PRIV 0x89F2 // 242 | |
16486 | +#define NWE_BIND_OBJ_NO_RENAME_PRIV 0x89F3 // 243 | |
16487 | +#define NWE_BIND_OBJ_NO_DELETE_PRIV 0x89F4 // 244 | |
16488 | +#define NWE_BIND_OBJ_NO_CREATE_PRIV 0x89F5 // 245 | |
16489 | +#define NWE_BIND_PROP_NO_DELETE_PRIV 0x89F6 // 246 | |
16490 | +#define NWE_BIND_PROP_NO_CREATE_PRIV 0x89F7 // 247 | |
16491 | +#define NWE_BIND_PROP_NO_WRITE_PRIV 0x89F8 // 248 | |
16492 | +#define NWE_BIND_PROP_NO_READ_PRIV 0x89F9 // 249 | |
16493 | +#define NWE_NO_FREE_CONN_SLOTS 0x89F9 // 249 | |
16494 | +#define NWE_NO_MORE_SERVER_SLOTS 0x89FA // 250 | |
16495 | +#define NWE_TEMP_REMAP_ERROR 0x89FA // 250 | |
16496 | +#define NWE_PARAMETERS_INVALID 0x89FB // 251 | |
16497 | +#define NWE_BIND_NO_SUCH_PROP 0x89FB // 251 | |
16498 | +#define NWE_NCP_NOT_SUPPORTED 0x89FB // 251 | |
16499 | +#define NWE_INET_PACKET_REQ_CANCELED 0x89FC // 252 | |
16500 | +#define NWE_SERVER_UNKNOWN 0x89FC // 252 | |
16501 | +#define NWE_MSG_Q_FULL 0x89FC // 252 | |
16502 | +#define NWE_BIND_NO_SUCH_OBJ 0x89FC // 252 | |
16503 | +#define NWE_LOCK_COLLISION 0x89FD // 253 | |
16504 | +#define NWE_CONN_NUM_INVALID 0x89FD // 253 | |
16505 | +#define NWE_PACKET_LEN_INVALID 0x89FD // 253 | |
16506 | +#define NWE_UNKNOWN_REQ 0x89FD // 253 | |
16507 | +#define NWE_BIND_LOCKED 0x89FE // 254 | |
16508 | +#define NWE_TRUSTEE_NOT_FOUND 0x89FE // 254 | |
16509 | +#define NWE_DIR_LOCKED 0x89FE // 254 | |
16510 | +#define NWE_SEM_INVALID_NAME_LEN 0x89FE // 254 | |
16511 | +#define NWE_PACKET_NOT_DELIVERABLE 0x89FE // 254 | |
16512 | +#define NWE_SOCKET_TABLE_FULL 0x89FE // 254 | |
16513 | +#define NWE_SPOOL_DIR_ERROR 0x89FE // 254 | |
16514 | +#define NWE_LOGIN_DISABLED_BY_SUPER 0x89FE // 254 | |
16515 | +#define NWE_TIMEOUT_FAILURE 0x89FE // 254 | |
16516 | +#define NWE_FILE_EXT 0x89FF // 255 | |
16517 | +#define NWE_FILE_NAME 0x89FF // 255 | |
16518 | +#define NWE_HARD_FAILURE 0x89FF // 255 | |
16519 | +#define NWE_FCB_CLOSE 0x89FF // 255 | |
16520 | +#define NWE_IO_BOUND 0x89FF // 255 | |
16521 | +#define NWE_BAD_SPOOL_PRINTER 0x89FF // 255 | |
16522 | +#define NWE_BAD_RECORD_OFFSET 0x89FF // 255 | |
16523 | +#define NWE_DRIVE_INVALID_NUM 0x89FF // 255 | |
16524 | +#define NWE_SEM_INVALID_INIT_VAL 0x89FF // 255 | |
16525 | +#define NWE_SEM_INVALID_HANDLE 0x89FF // 255 | |
16526 | +#define NWE_NO_FILES_FOUND_ERROR 0x89FF // 255 | |
16527 | +#define NWE_NO_RESPONSE_FROM_SERVER 0x89FF // 255 | |
16528 | +#define NWE_NO_OBJ_OR_BAD_PASSWORD 0x89FF // 255 | |
16529 | +#define NWE_PATH_NOT_LOCATABLE 0x89FF // 255 | |
16530 | +#define NWE_Q_FULL_ERROR 0x89FF // 255 | |
16531 | +#define NWE_REQ_NOT_OUTSTANDING 0x89FF // 255 | |
16532 | +#define NWE_SOCKET_ALREADY_OPEN 0x89FF // 255 | |
16533 | +#define NWE_LOCK_ERROR 0x89FF // 255 | |
16534 | +#define NWE_FAILURE 0x89FF // 255 Generic Failure | |
16535 | + | |
16536 | +#endif /* __NOVFS_ERROR_H */ | |
16537 | --- /dev/null | |
16538 | +++ b/fs/novfs/proc.c | |
16539 | @@ -0,0 +1,152 @@ | |
16540 | +/* | |
16541 | + * Novell NCP Redirector for Linux | |
16542 | + * Author: James Turner | |
16543 | + * | |
16544 | + * This module contains functions that create the interface to the proc | |
16545 | + * filesystem. | |
16546 | + * | |
16547 | + * Copyright (C) 2005 Novell, Inc. | |
16548 | + * | |
16549 | + * This program is free software; you can redistribute it and/or | |
16550 | + * modify it under the terms of the GNU General Public License | |
16551 | + * as published by the Free Software Foundation; either version 2 | |
16552 | + * of the License, or (at your option) any later version. | |
16553 | + */ | |
16554 | + | |
16555 | +#include <linux/module.h> | |
16556 | +#include <linux/kernel.h> | |
16557 | +#include <linux/proc_fs.h> | |
16558 | +#include <linux/smp_lock.h> | |
16559 | + | |
16560 | +#include "vfs.h" | |
16561 | + | |
16562 | +struct proc_dir_entry *Novfs_Procfs_dir; | |
16563 | +static struct proc_dir_entry *Novfs_Control; | |
16564 | +static struct proc_dir_entry *Novfs_Library; | |
16565 | +static struct proc_dir_entry *Novfs_Version; | |
16566 | + | |
16567 | +static struct file_operations Daemon_proc_fops; | |
16568 | +static struct file_operations Library_proc_fops; | |
16569 | + | |
16570 | +/*===[ Code ]=============================================================*/ | |
16571 | + | |
16572 | +static int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data) | |
16573 | +{ | |
16574 | + char *buf, tbuf[48]; | |
16575 | + int len = 0, i; | |
16576 | + | |
16577 | + if (!off) { | |
16578 | + buf = page + off; | |
16579 | + *start = buf; | |
16580 | + len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING); | |
16581 | + i = Daemon_getversion(tbuf, sizeof(tbuf)); | |
16582 | + if ((i > 0) && i < (count - len)) { | |
16583 | + len += sprintf(buf + len, "Novfsd Version=%s\n", tbuf); | |
16584 | + } | |
16585 | + | |
16586 | + if (Novfs_CurrentMount) { | |
16587 | + i = strlen(Novfs_CurrentMount); | |
16588 | + if ((i > 0) && i < (count - len)) { | |
16589 | + len += | |
16590 | + sprintf(buf + len, "Novfs mount=%s\n", | |
16591 | + Novfs_CurrentMount); | |
16592 | + } | |
16593 | + } | |
16594 | + DbgPrint("Novfs_Get_Version:\n%s\n", buf); | |
16595 | + } | |
16596 | + *eof = 1; | |
16597 | + return (len); | |
16598 | +} | |
16599 | + | |
16600 | +int Init_Procfs_Interface(void) | |
16601 | +{ | |
16602 | + int retCode = 0; | |
16603 | + | |
16604 | + Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL); | |
16605 | + if (Novfs_Procfs_dir) { | |
16606 | + Novfs_Procfs_dir->owner = THIS_MODULE; | |
16607 | + | |
16608 | + Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir); | |
16609 | + | |
16610 | + if (Novfs_Control) { | |
16611 | + Novfs_Control->owner = THIS_MODULE; | |
16612 | + Novfs_Control->size = 0; | |
16613 | + memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, | |
16614 | + sizeof(struct file_operations)); | |
16615 | + | |
16616 | + /* | |
16617 | + * Setup our functions | |
16618 | + */ | |
16619 | + Daemon_proc_fops.owner = THIS_MODULE; | |
16620 | + Daemon_proc_fops.open = Daemon_Open_Control; | |
16621 | + Daemon_proc_fops.release = Daemon_Close_Control; | |
16622 | + Daemon_proc_fops.read = Daemon_Send_Command; | |
16623 | + Daemon_proc_fops.write = Daemon_Receive_Reply; | |
16624 | + Daemon_proc_fops.ioctl = Daemon_ioctl; | |
16625 | + | |
16626 | + Novfs_Control->proc_fops = &Daemon_proc_fops; | |
16627 | + } else { | |
16628 | + remove_proc_entry(MODULE_NAME, NULL); | |
16629 | + return (-ENOENT); | |
16630 | + } | |
16631 | + | |
16632 | + Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir); | |
16633 | + if (Novfs_Library) { | |
16634 | + Novfs_Library->owner = THIS_MODULE; | |
16635 | + Novfs_Library->size = 0; | |
16636 | + | |
16637 | + /* | |
16638 | + * Setup our file functions | |
16639 | + */ | |
16640 | + memcpy(&Library_proc_fops, Novfs_Library->proc_fops, | |
16641 | + sizeof(struct file_operations)); | |
16642 | + Library_proc_fops.owner = THIS_MODULE; | |
16643 | + Library_proc_fops.open = Daemon_Library_open; | |
16644 | + Library_proc_fops.release = Daemon_Library_close; | |
16645 | + Library_proc_fops.read = Daemon_Library_read; | |
16646 | + Library_proc_fops.write = Daemon_Library_write; | |
16647 | + Library_proc_fops.llseek = Daemon_Library_llseek; | |
16648 | + Library_proc_fops.ioctl = Daemon_Library_ioctl; | |
16649 | + Novfs_Library->proc_fops = &Library_proc_fops; | |
16650 | + } else { | |
16651 | + remove_proc_entry("Control", Novfs_Procfs_dir); | |
16652 | + remove_proc_entry(MODULE_NAME, NULL); | |
16653 | + return (-ENOENT); | |
16654 | + } | |
16655 | + | |
16656 | + Novfs_Version = | |
16657 | + create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, | |
16658 | + Novfs_Get_Version, NULL); | |
16659 | + if (Novfs_Version) { | |
16660 | + Novfs_Version->owner = THIS_MODULE; | |
16661 | + Novfs_Version->size = 0; | |
16662 | + } else { | |
16663 | + remove_proc_entry("Library", Novfs_Procfs_dir); | |
16664 | + remove_proc_entry("Control", Novfs_Procfs_dir); | |
16665 | + remove_proc_entry(MODULE_NAME, NULL); | |
16666 | + retCode = -ENOENT; | |
16667 | + } | |
16668 | + } else { | |
16669 | + retCode = -ENOENT; | |
16670 | + } | |
16671 | + return (retCode); | |
16672 | +} | |
16673 | + | |
16674 | +void Uninit_Procfs_Interface(void) | |
16675 | +{ | |
16676 | + | |
16677 | + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n"); | |
16678 | + remove_proc_entry("Version", Novfs_Procfs_dir); | |
16679 | + | |
16680 | + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n"); | |
16681 | + remove_proc_entry("Control", Novfs_Procfs_dir); | |
16682 | + | |
16683 | + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n"); | |
16684 | + remove_proc_entry("Library", Novfs_Procfs_dir); | |
16685 | + | |
16686 | + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", | |
16687 | + MODULE_NAME); | |
16688 | + remove_proc_entry(MODULE_NAME, NULL); | |
16689 | + | |
16690 | + DbgPrint("Uninit_Procfs_Interface done\n"); | |
16691 | +} | |
16692 | --- /dev/null | |
16693 | +++ b/fs/novfs/profile.c | |
16694 | @@ -0,0 +1,687 @@ | |
16695 | +/* | |
16696 | + * Novell NCP Redirector for Linux | |
16697 | + * Author: James Turner | |
16698 | + * | |
16699 | + * This file contains a debugging code for the novfs VFS. | |
16700 | + * | |
16701 | + * Copyright (C) 2005 Novell, Inc. | |
16702 | + * | |
16703 | + * This program is free software; you can redistribute it and/or | |
16704 | + * modify it under the terms of the GNU General Public License | |
16705 | + * as published by the Free Software Foundation; either version 2 | |
16706 | + * of the License, or (at your option) any later version. | |
16707 | + */ | |
16708 | + | |
16709 | +#include <linux/module.h> | |
16710 | +#include <linux/kernel.h> | |
16711 | +#include <linux/init.h> | |
16712 | +#include <linux/proc_fs.h> | |
16713 | +#include <linux/sched.h> | |
16714 | +#include <linux/vmalloc.h> | |
16715 | +#include <linux/time.h> | |
16716 | +#include <linux/profile.h> | |
16717 | +#include <linux/notifier.h> | |
16718 | +#include <asm/uaccess.h> | |
16719 | + | |
16720 | +#include "vfs.h" | |
16721 | + | |
16722 | +/*===[ Manifest constants ]===============================================*/ | |
16723 | +#define DBGBUFFERSIZE (1024*1024*32) | |
16724 | + | |
16725 | +/*===[ Type definitions ]=================================================*/ | |
16726 | +struct local_rtc_time { | |
16727 | + int tm_sec; | |
16728 | + int tm_min; | |
16729 | + int tm_hour; | |
16730 | + int tm_mday; | |
16731 | + int tm_mon; | |
16732 | + int tm_year; | |
16733 | + int tm_wday; | |
16734 | + int tm_yday; | |
16735 | + int tm_isdst; | |
16736 | +}; | |
16737 | + | |
16738 | +static char *DbgPrintBuffer = NULL; | |
16739 | +static char DbgPrintOn = 0; | |
16740 | +static char DbgSyslogOn = 0; | |
16741 | +static char DbgProfileOn = 0; | |
16742 | + | |
16743 | +static unsigned long DbgPrintBufferOffset = 0; | |
16744 | +static unsigned long DbgPrintBufferReadOffset = 0; | |
16745 | +static unsigned long DbgPrintBufferSize = DBGBUFFERSIZE; | |
16746 | + | |
16747 | +static struct file_operations Dbg_proc_file_operations; | |
16748 | +static struct file_operations dentry_proc_file_ops; | |
16749 | +static struct file_operations inode_proc_file_ops; | |
16750 | + | |
16751 | +static struct proc_dir_entry *dbg_dir = NULL; | |
16752 | +static struct proc_dir_entry *dbg_file = NULL; | |
16753 | +static struct proc_dir_entry *dentry_file = NULL; | |
16754 | +static struct proc_dir_entry *inode_file = NULL; | |
16755 | + | |
16756 | +static DECLARE_MUTEX(LocalPrint_lock); | |
16757 | + | |
16758 | +static ssize_t User_proc_write_DbgBuffer(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos) | |
16759 | +{ | |
16760 | + ssize_t retval = nbytes; | |
16761 | + unsigned char *lbuf; | |
16762 | + unsigned char *p; | |
16763 | + int i; | |
16764 | + | |
16765 | + lbuf = kmalloc(nbytes + 1, GFP_KERNEL); | |
16766 | + if (lbuf) { | |
16767 | + if (copy_from_user(lbuf, buf, nbytes)) | |
16768 | + return -EFAULT; | |
16769 | + | |
16770 | + lbuf[nbytes] = 0; | |
16771 | + DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf); | |
16772 | + | |
16773 | + for (i = 0; lbuf[i] && lbuf[i] != '\n'; i++) | |
16774 | + ; | |
16775 | + | |
16776 | + if ('\n' == lbuf[i]) | |
16777 | + lbuf[i] = '\0'; | |
16778 | + | |
16779 | + if (!strcmp("on", lbuf)) { | |
16780 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
16781 | + DbgPrintOn = 1; | |
16782 | + } else if (!strcmp("off", lbuf)) { | |
16783 | + DbgPrintOn = 0; | |
16784 | + } else if (!strcmp("reset", lbuf)) { | |
16785 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
16786 | + } else if (NULL != (p = strchr(lbuf, ' '))) { | |
16787 | + *p++ = '\0'; | |
16788 | + if (!strcmp("syslog", lbuf)) { | |
16789 | + | |
16790 | + if (!strcmp("on", p)) { | |
16791 | + DbgSyslogOn = 1; | |
16792 | + } else if (!strcmp("off", p)) { | |
16793 | + DbgSyslogOn = 0; | |
16794 | + } | |
16795 | + } else if (!strcmp("novfsd", lbuf)) { | |
16796 | + Daemon_SendDebugCmd(p); | |
16797 | + } else if (!strcmp("file_update_timeout", lbuf)) { | |
16798 | + File_update_timeout = | |
16799 | + simple_strtoul(p, NULL, 0); | |
16800 | + } else if (!strcmp("cache", lbuf)) { | |
16801 | + if (!strcmp("on", p)) { | |
16802 | + PageCache = 1; | |
16803 | + } else if (!strcmp("off", p)) { | |
16804 | + PageCache = 0; | |
16805 | + } | |
16806 | + } else if (!strcmp("profile", lbuf)) { | |
16807 | + if (!strcmp("on", p)) { | |
16808 | + DbgProfileOn = 1; | |
16809 | + } else if (!strcmp("off", p)) { | |
16810 | + DbgProfileOn = 0; | |
16811 | + } | |
16812 | + } | |
16813 | + } | |
16814 | + kfree(lbuf); | |
16815 | + } | |
16816 | + | |
16817 | + return (retval); | |
16818 | +} | |
16819 | + | |
16820 | +static ssize_t User_proc_read_DbgBuffer(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |
16821 | +{ | |
16822 | + ssize_t retval = 0; | |
16823 | + size_t count; | |
16824 | + | |
16825 | + if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset)) { | |
16826 | + | |
16827 | + if (count > nbytes) { | |
16828 | + count = nbytes; | |
16829 | + } | |
16830 | + | |
16831 | + count -= | |
16832 | + copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], | |
16833 | + count); | |
16834 | + | |
16835 | + if (count == 0) { | |
16836 | + if (retval == 0) | |
16837 | + retval = -EFAULT; | |
16838 | + } else { | |
16839 | + DbgPrintBufferReadOffset += count; | |
16840 | + if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset) { | |
16841 | + DbgPrintBufferOffset = | |
16842 | + DbgPrintBufferReadOffset = 0; | |
16843 | + } | |
16844 | + retval = count; | |
16845 | + } | |
16846 | + } | |
16847 | + | |
16848 | + return retval; | |
16849 | +} | |
16850 | + | |
16851 | +static int proc_read_DbgBuffer(char *page, char **start, off_t off, int count, int *eof, void *data) | |
16852 | +{ | |
16853 | + int len; | |
16854 | + | |
16855 | + printk(KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n", off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset); | |
16856 | + | |
16857 | + len = DbgPrintBufferOffset - DbgPrintBufferReadOffset; | |
16858 | + | |
16859 | + if ((int)(DbgPrintBufferOffset - DbgPrintBufferReadOffset) > count) | |
16860 | + len = count; | |
16861 | + | |
16862 | + if (len) { | |
16863 | + memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len); | |
16864 | + DbgPrintBufferReadOffset += len; | |
16865 | + } | |
16866 | + | |
16867 | + if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset) | |
16868 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
16869 | + | |
16870 | + printk(KERN_ALERT "proc_read_DbgBuffer: return %d\n", len); | |
16871 | + | |
16872 | + return len; | |
16873 | +} | |
16874 | + | |
16875 | +#define DBG_BUFFER_SIZE (2*1024) | |
16876 | + | |
16877 | +static int LocalPrint(char *Fmt, ...) | |
16878 | +{ | |
16879 | + int len = 0; | |
16880 | + va_list args; | |
16881 | + | |
16882 | + if (DbgPrintBuffer) { | |
16883 | + va_start(args, Fmt); | |
16884 | + len += vsnprintf(DbgPrintBuffer + DbgPrintBufferOffset, | |
16885 | + DbgPrintBufferSize - DbgPrintBufferOffset, | |
16886 | + Fmt, args); | |
16887 | + DbgPrintBufferOffset += len; | |
16888 | + } | |
16889 | + | |
16890 | + return (len); | |
16891 | +} | |
16892 | + | |
16893 | +int DbgPrint(char *Fmt, ...) | |
16894 | +{ | |
16895 | + char *buf; | |
16896 | + int len = 0; | |
16897 | + unsigned long offset; | |
16898 | + va_list args; | |
16899 | + | |
16900 | + if ((DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn) { | |
16901 | + buf = kmalloc(DBG_BUFFER_SIZE, GFP_KERNEL); | |
16902 | + | |
16903 | + if (buf) { | |
16904 | + va_start(args, Fmt); | |
16905 | + len = sprintf(buf, "[%d] ", current->pid); | |
16906 | + | |
16907 | + len += | |
16908 | + vsnprintf(buf + len, DBG_BUFFER_SIZE - len, Fmt, | |
16909 | + args); | |
16910 | + if (-1 == len) { | |
16911 | + len = DBG_BUFFER_SIZE - 1; | |
16912 | + buf[len] = '\0'; | |
16913 | + } | |
16914 | + /* | |
16915 | + len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts); | |
16916 | + len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args); | |
16917 | + */ | |
16918 | + | |
16919 | + if (len) { | |
16920 | + if (DbgSyslogOn) { | |
16921 | + printk("<6>%s", buf); | |
16922 | + } | |
16923 | + | |
16924 | + if (DbgPrintBuffer && DbgPrintOn) { | |
16925 | + if ((DbgPrintBufferOffset + len) > | |
16926 | + DbgPrintBufferSize) { | |
16927 | + offset = DbgPrintBufferOffset; | |
16928 | + DbgPrintBufferOffset = 0; | |
16929 | + memset(&DbgPrintBuffer[offset], | |
16930 | + 0, | |
16931 | + DbgPrintBufferSize - | |
16932 | + offset); | |
16933 | + } | |
16934 | + | |
16935 | + mb(); | |
16936 | + | |
16937 | + if ((DbgPrintBufferOffset + len) < | |
16938 | + DbgPrintBufferSize) { | |
16939 | + DbgPrintBufferOffset += len; | |
16940 | + offset = | |
16941 | + DbgPrintBufferOffset - len; | |
16942 | + memcpy(&DbgPrintBuffer[offset], | |
16943 | + buf, len + 1); | |
16944 | + } | |
16945 | + } | |
16946 | + } | |
16947 | + kfree(buf); | |
16948 | + } | |
16949 | + } | |
16950 | + | |
16951 | + return (len); | |
16952 | +} | |
16953 | + | |
16954 | +static void doline(unsigned char *b, unsigned char *e, unsigned char *l) | |
16955 | +{ | |
16956 | + unsigned char c; | |
16957 | + | |
16958 | + *b++ = ' '; | |
16959 | + | |
16960 | + while (l < e) { | |
16961 | + c = *l++; | |
16962 | + if ((c < ' ') || (c > '~')) { | |
16963 | + c = '.'; | |
16964 | + } | |
16965 | + *b++ = c; | |
16966 | + *b = '\0'; | |
16967 | + } | |
16968 | +} | |
16969 | + | |
16970 | +void mydump(int size, void *dumpptr) | |
16971 | +{ | |
16972 | + unsigned char *ptr = (unsigned char *)dumpptr; | |
16973 | + unsigned char *line = NULL, buf[100], *bptr = buf; | |
16974 | + int i; | |
16975 | + | |
16976 | + if (DbgPrintBuffer || DbgSyslogOn) { | |
16977 | + if (size) { | |
16978 | + for (i = 0; i < size; i++) { | |
16979 | + if (0 == (i % 16)) { | |
16980 | + if (line) { | |
16981 | + doline(bptr, ptr, line); | |
16982 | + DbgPrint("%s\n", buf); | |
16983 | + bptr = buf; | |
16984 | + } | |
16985 | + bptr += sprintf(bptr, "0x%p: ", ptr); | |
16986 | + line = ptr; | |
16987 | + } | |
16988 | + bptr += sprintf(bptr, "%02x ", *ptr++); | |
16989 | + } | |
16990 | + doline(bptr, ptr, line); | |
16991 | + DbgPrint("%s\n", buf); | |
16992 | + } | |
16993 | + } | |
16994 | +} | |
16995 | + | |
16996 | +#define FEBRUARY 2 | |
16997 | +#define STARTOFTIME 1970 | |
16998 | +#define SECDAY 86400L | |
16999 | +#define SECYR (SECDAY * 365) | |
17000 | +#define leapyear(year) ((year) % 4 == 0) | |
17001 | +#define days_in_year(a) (leapyear(a) ? 366 : 365) | |
17002 | +#define days_in_month(a) (month_days[(a) - 1]) | |
17003 | + | |
17004 | +static int month_days[12] = { | |
17005 | + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 | |
17006 | +}; | |
17007 | + | |
17008 | +/* | |
17009 | + * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) | |
17010 | + */ | |
17011 | +static void Novfs_GregorianDay(struct local_rtc_time *tm) | |
17012 | +{ | |
17013 | + int leapsToDate; | |
17014 | + int lastYear; | |
17015 | + int day; | |
17016 | + int MonthOffset[] = | |
17017 | + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; | |
17018 | + | |
17019 | + lastYear = tm->tm_year - 1; | |
17020 | + | |
17021 | + /* | |
17022 | + * Number of leap corrections to apply up to end of last year | |
17023 | + */ | |
17024 | + leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400; | |
17025 | + | |
17026 | + /* | |
17027 | + * This year is a leap year if it is divisible by 4 except when it is | |
17028 | + * divisible by 100 unless it is divisible by 400 | |
17029 | + * | |
17030 | + * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be | |
17031 | + */ | |
17032 | + if ((tm->tm_year % 4 == 0) && | |
17033 | + ((tm->tm_year % 100 != 0) || (tm->tm_year % 400 == 0)) && | |
17034 | + (tm->tm_mon > 2)) { | |
17035 | + /* | |
17036 | + * We are past Feb. 29 in a leap year | |
17037 | + */ | |
17038 | + day = 1; | |
17039 | + } else { | |
17040 | + day = 0; | |
17041 | + } | |
17042 | + | |
17043 | + day += lastYear * 365 + leapsToDate + MonthOffset[tm->tm_mon - 1] + | |
17044 | + tm->tm_mday; | |
17045 | + | |
17046 | + tm->tm_wday = day % 7; | |
17047 | +} | |
17048 | + | |
17049 | +static void private_to_tm(int tim, struct local_rtc_time *tm) | |
17050 | +{ | |
17051 | + register int i; | |
17052 | + register long hms, day; | |
17053 | + | |
17054 | + day = tim / SECDAY; | |
17055 | + hms = tim % SECDAY; | |
17056 | + | |
17057 | + /* Hours, minutes, seconds are easy */ | |
17058 | + tm->tm_hour = hms / 3600; | |
17059 | + tm->tm_min = (hms % 3600) / 60; | |
17060 | + tm->tm_sec = (hms % 3600) % 60; | |
17061 | + | |
17062 | + /* Number of years in days */ | |
17063 | + for (i = STARTOFTIME; day >= days_in_year(i); i++) | |
17064 | + day -= days_in_year(i); | |
17065 | + tm->tm_year = i; | |
17066 | + | |
17067 | + /* Number of months in days left */ | |
17068 | + if (leapyear(tm->tm_year)) | |
17069 | + days_in_month(FEBRUARY) = 29; | |
17070 | + for (i = 1; day >= days_in_month(i); i++) | |
17071 | + day -= days_in_month(i); | |
17072 | + days_in_month(FEBRUARY) = 28; | |
17073 | + tm->tm_mon = i; | |
17074 | + | |
17075 | + /* Days are what is left over (+1) from all that. */ | |
17076 | + tm->tm_mday = day + 1; | |
17077 | + | |
17078 | + /* | |
17079 | + * Determine the day of week | |
17080 | + */ | |
17081 | + Novfs_GregorianDay(tm); | |
17082 | +} | |
17083 | + | |
17084 | +char *ctime_r(time_t * clock, char *buf) | |
17085 | +{ | |
17086 | + struct local_rtc_time tm; | |
17087 | + static char *DAYOFWEEK[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | |
17088 | + static char *MONTHOFYEAR[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | |
17089 | + | |
17090 | + private_to_tm(*clock, &tm); | |
17091 | + | |
17092 | + sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], | |
17093 | + MONTHOFYEAR[tm.tm_mon - 1], tm.tm_mday, tm.tm_hour, tm.tm_min, | |
17094 | + tm.tm_sec, tm.tm_year); | |
17095 | + return (buf); | |
17096 | +} | |
17097 | + | |
17098 | +static void profile_dump_dt(struct dentry *parent, void *pf) | |
17099 | +{ | |
17100 | + void (*pfunc) (char *Fmt, ...) = pf; | |
17101 | + struct l { | |
17102 | + struct l *next; | |
17103 | + struct dentry *dentry; | |
17104 | + } *l, *n, *start; | |
17105 | + struct list_head *p; | |
17106 | + struct dentry *d; | |
17107 | + char *buf, *path, *sd; | |
17108 | + char inode_number[16]; | |
17109 | + | |
17110 | + buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
17111 | + if (!buf) | |
17112 | + return; | |
17113 | + | |
17114 | + if (parent) { | |
17115 | + pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, | |
17116 | + parent->d_name.name); | |
17117 | + if (parent->d_subdirs.next == &parent->d_subdirs) { | |
17118 | + pfunc("No children...\n"); | |
17119 | + } else { | |
17120 | + start = kmalloc(sizeof(*start), GFP_KERNEL); | |
17121 | + if (start) { | |
17122 | + start->next = NULL; | |
17123 | + start->dentry = parent; | |
17124 | + l = start; | |
17125 | + while (l) { | |
17126 | + p = l->dentry->d_subdirs.next; | |
17127 | + while (p != &l->dentry->d_subdirs) { | |
17128 | + d = list_entry(p, struct dentry, | |
17129 | + D_CHILD); | |
17130 | + p = p->next; | |
17131 | + | |
17132 | + if (d->d_subdirs.next != &d->d_subdirs) { | |
17133 | + n = kmalloc(sizeof(*n), GFP_KERNEL); | |
17134 | + if (n) { | |
17135 | + n->next = l->next; | |
17136 | + l->next = n; | |
17137 | + n->dentry = d; | |
17138 | + } | |
17139 | + } else { | |
17140 | + path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1); | |
17141 | + if (path) { | |
17142 | + pfunc("1-0x%p %s\n" | |
17143 | + " d_name: %.*s\n" | |
17144 | + " d_parent: 0x%p\n" | |
17145 | + " d_count: %d\n" | |
17146 | + " d_flags: 0x%x\n" | |
17147 | + " d_subdirs: 0x%p\n" | |
17148 | + " d_inode: 0x%p\n", | |
17149 | + d, path, | |
17150 | + d->d_name.len, | |
17151 | + d->d_name.name, | |
17152 | + d->d_parent, | |
17153 | + atomic_read(&d->d_count), | |
17154 | + d->d_flags, | |
17155 | + d->d_subdirs. | |
17156 | + next, | |
17157 | + d->d_inode); | |
17158 | + } | |
17159 | + } | |
17160 | + } | |
17161 | + l = l->next; | |
17162 | + } | |
17163 | + l = start; | |
17164 | + while (l) { | |
17165 | + d = l->dentry; | |
17166 | + path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1); | |
17167 | + if (path) { | |
17168 | + sd = " (None)"; | |
17169 | + if (&d->d_subdirs != d->d_subdirs.next) | |
17170 | + sd = ""; | |
17171 | + inode_number[0] = '\0'; | |
17172 | + if (d->d_inode) { | |
17173 | + sprintf(inode_number, | |
17174 | + " (%lu)", | |
17175 | + d->d_inode-> | |
17176 | + i_ino); | |
17177 | + } | |
17178 | + pfunc("0x%p %s\n" | |
17179 | + " d_parent: 0x%p\n" | |
17180 | + " d_count: %d\n" | |
17181 | + " d_flags: 0x%x\n" | |
17182 | + " d_subdirs: 0x%p%s\n" | |
17183 | + " d_inode: 0x%p%s\n", | |
17184 | + d, path, d->d_parent, | |
17185 | + atomic_read(&d->d_count), | |
17186 | + d->d_flags, | |
17187 | + d->d_subdirs.next, sd, | |
17188 | + d->d_inode, inode_number); | |
17189 | + } | |
17190 | + | |
17191 | + n = l; | |
17192 | + l = l->next; | |
17193 | + kfree(n); | |
17194 | + } | |
17195 | + } | |
17196 | + } | |
17197 | + } | |
17198 | + | |
17199 | + kfree(buf); | |
17200 | + | |
17201 | +} | |
17202 | + | |
17203 | +static ssize_t profile_common_read(char __user *buf, size_t len, loff_t *off) | |
17204 | +{ | |
17205 | + ssize_t retval = 0; | |
17206 | + size_t count; | |
17207 | + unsigned long offset = *off; | |
17208 | + | |
17209 | + if (0 != (count = DbgPrintBufferOffset - offset)) { | |
17210 | + if (count > len) { | |
17211 | + count = len; | |
17212 | + } | |
17213 | + | |
17214 | + count -= copy_to_user(buf, &DbgPrintBuffer[offset], count); | |
17215 | + | |
17216 | + if (count == 0) { | |
17217 | + retval = -EFAULT; | |
17218 | + } else { | |
17219 | + *off += (loff_t) count; | |
17220 | + retval = count; | |
17221 | + } | |
17222 | + } | |
17223 | + return retval; | |
17224 | + | |
17225 | +} | |
17226 | + | |
17227 | +static ssize_t profile_inode_read(struct file * file, char __user *buf, size_t len, loff_t *off) | |
17228 | +{ | |
17229 | + ssize_t retval = 0; | |
17230 | + unsigned long offset = *off; | |
17231 | + static char save_DbgPrintOn; | |
17232 | + | |
17233 | + if (offset == 0) { | |
17234 | + down(&LocalPrint_lock); | |
17235 | + save_DbgPrintOn = DbgPrintOn; | |
17236 | + DbgPrintOn = 0; | |
17237 | + | |
17238 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
17239 | + Novfs_dump_inode(LocalPrint); | |
17240 | + } | |
17241 | + | |
17242 | + retval = profile_common_read(buf, len, off); | |
17243 | + | |
17244 | + if (0 == retval) { | |
17245 | + DbgPrintOn = save_DbgPrintOn; | |
17246 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
17247 | + | |
17248 | + up(&LocalPrint_lock); | |
17249 | + } | |
17250 | + | |
17251 | + return retval; | |
17252 | + | |
17253 | +} | |
17254 | + | |
17255 | +static ssize_t profile_dentry_read(struct file *file, char __user *buf, size_t len, loff_t * off) | |
17256 | +{ | |
17257 | + ssize_t retval = 0; | |
17258 | + unsigned long offset = *off; | |
17259 | + static char save_DbgPrintOn; | |
17260 | + | |
17261 | + if (offset == 0) { | |
17262 | + down(&LocalPrint_lock); | |
17263 | + save_DbgPrintOn = DbgPrintOn; | |
17264 | + DbgPrintOn = 0; | |
17265 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
17266 | + profile_dump_dt(Novfs_root, LocalPrint); | |
17267 | + } | |
17268 | + | |
17269 | + retval = profile_common_read(buf, len, off); | |
17270 | + | |
17271 | + if (0 == retval) { | |
17272 | + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; | |
17273 | + DbgPrintOn = save_DbgPrintOn; | |
17274 | + | |
17275 | + up(&LocalPrint_lock); | |
17276 | + } | |
17277 | + | |
17278 | + return retval; | |
17279 | + | |
17280 | +} | |
17281 | + | |
17282 | +uint64_t get_nanosecond_time(void) | |
17283 | +{ | |
17284 | + struct timespec ts; | |
17285 | + uint64_t retVal; | |
17286 | + | |
17287 | + ts = current_kernel_time(); | |
17288 | + | |
17289 | + retVal = (uint64_t) NSEC_PER_SEC; | |
17290 | + retVal *= (uint64_t) ts.tv_sec; | |
17291 | + retVal += (uint64_t) ts.tv_nsec; | |
17292 | + | |
17293 | + return (retVal); | |
17294 | +} | |
17295 | + | |
17296 | +int init_profile(void) | |
17297 | +{ | |
17298 | + int retCode = 0; | |
17299 | + | |
17300 | + if (Novfs_Procfs_dir) { | |
17301 | + dbg_dir = Novfs_Procfs_dir; | |
17302 | + } else { | |
17303 | + dbg_dir = proc_mkdir(MODULE_NAME, NULL); | |
17304 | + } | |
17305 | + | |
17306 | + if (dbg_dir) { | |
17307 | + dbg_dir->owner = THIS_MODULE; | |
17308 | + dbg_file = create_proc_read_entry("Debug", | |
17309 | + 0600, | |
17310 | + dbg_dir, | |
17311 | + proc_read_DbgBuffer, NULL); | |
17312 | + if (dbg_file) { | |
17313 | + dbg_file->owner = THIS_MODULE; | |
17314 | + dbg_file->size = DBGBUFFERSIZE; | |
17315 | + memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, | |
17316 | + sizeof(struct file_operations)); | |
17317 | + Dbg_proc_file_operations.read = User_proc_read_DbgBuffer; | |
17318 | + Dbg_proc_file_operations.write = User_proc_write_DbgBuffer; | |
17319 | + dbg_file->proc_fops = &Dbg_proc_file_operations; | |
17320 | + } else { | |
17321 | + remove_proc_entry(MODULE_NAME, NULL); | |
17322 | + vfree(DbgPrintBuffer); | |
17323 | + DbgPrintBuffer = NULL; | |
17324 | + } | |
17325 | + } | |
17326 | + | |
17327 | + if (DbgPrintBuffer) { | |
17328 | + if (dbg_dir) { | |
17329 | + inode_file = create_proc_entry("inode", 0600, dbg_dir); | |
17330 | + if (inode_file) { | |
17331 | + inode_file->owner = THIS_MODULE; | |
17332 | + inode_file->size = 0; | |
17333 | + memcpy(&inode_proc_file_ops, | |
17334 | + inode_file->proc_fops, | |
17335 | + sizeof(struct file_operations)); | |
17336 | + inode_proc_file_ops.owner = THIS_MODULE; | |
17337 | + inode_proc_file_ops.read = profile_inode_read; | |
17338 | + inode_file->proc_fops = &inode_proc_file_ops; | |
17339 | + } | |
17340 | + | |
17341 | + dentry_file = create_proc_entry("dentry", | |
17342 | + 0600, dbg_dir); | |
17343 | + if (dentry_file) { | |
17344 | + dentry_file->owner = THIS_MODULE; | |
17345 | + dentry_file->size = 0; | |
17346 | + memcpy(&dentry_proc_file_ops, | |
17347 | + dentry_file->proc_fops, | |
17348 | + sizeof(struct file_operations)); | |
17349 | + dentry_proc_file_ops.owner = THIS_MODULE; | |
17350 | + dentry_proc_file_ops.read = profile_dentry_read; | |
17351 | + dentry_file->proc_fops = &dentry_proc_file_ops; | |
17352 | + } | |
17353 | + } else { | |
17354 | + vfree(DbgPrintBuffer); | |
17355 | + DbgPrintBuffer = NULL; | |
17356 | + } | |
17357 | + } | |
17358 | + return (retCode); | |
17359 | +} | |
17360 | + | |
17361 | +void uninit_profile(void) | |
17362 | +{ | |
17363 | + if (dbg_file) { | |
17364 | + DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"); | |
17365 | + remove_proc_entry("Debug", dbg_dir); | |
17366 | + } | |
17367 | + if (inode_file) { | |
17368 | + DbgPrint("Calling remove_proc_entry(inode, NULL)\n"); | |
17369 | + remove_proc_entry("inode", dbg_dir); | |
17370 | + } | |
17371 | + if (dentry_file) { | |
17372 | + DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"); | |
17373 | + remove_proc_entry("dentry", dbg_dir); | |
17374 | + } | |
17375 | + if (dbg_dir && (dbg_dir != Novfs_Procfs_dir)) { | |
17376 | + DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME); | |
17377 | + remove_proc_entry(MODULE_NAME, NULL); | |
17378 | + } | |
17379 | +} | |
17380 | + | |
17381 | + | |
17382 | --- /dev/null | |
17383 | +++ b/fs/novfs/scope.c | |
17384 | @@ -0,0 +1,675 @@ | |
17385 | +/* | |
17386 | + * Novell NCP Redirector for Linux | |
17387 | + * Author: James Turner | |
17388 | + * | |
17389 | + * This file contains functions used to scope users. | |
17390 | + * | |
17391 | + * Copyright (C) 2005 Novell, Inc. | |
17392 | + * | |
17393 | + * This program is free software; you can redistribute it and/or | |
17394 | + * modify it under the terms of the GNU General Public License | |
17395 | + * as published by the Free Software Foundation; either version 2 | |
17396 | + * of the License, or (at your option) any later version. | |
17397 | + */ | |
17398 | + | |
17399 | +#include <linux/version.h> | |
17400 | +#include <linux/module.h> | |
17401 | +#include <linux/kthread.h> | |
17402 | +#include <linux/fs.h> | |
17403 | +#include <linux/file.h> | |
17404 | +#include <linux/sched.h> | |
17405 | +#include <linux/personality.h> | |
17406 | +#include <linux/module.h> | |
17407 | +#include <linux/slab.h> | |
17408 | +#include <linux/synclink.h> | |
17409 | +#include <linux/smp_lock.h> | |
17410 | +#include <linux/semaphore.h> | |
17411 | +#include <linux/security.h> | |
17412 | +#include <linux/syscalls.h> | |
17413 | + | |
17414 | +#include "vfs.h" | |
17415 | + | |
17416 | +#define SHUTDOWN_INTERVAL 5 | |
17417 | +#define CLEANUP_INTERVAL 10 | |
17418 | +#define MAX_USERNAME_LENGTH 32 | |
17419 | + | |
17420 | +struct scope_list { | |
17421 | + struct list_head entry; | |
17422 | + struct schandle ScopeId; | |
17423 | + struct schandle SessionId; | |
17424 | + pid_t ScopePid; | |
17425 | + struct task_struct *ScopeTask; | |
17426 | + unsigned int ScopeHash; | |
17427 | + uid_t ScopeUid; | |
17428 | + u64 ScopeUSize; | |
17429 | + u64 ScopeUFree; | |
17430 | + u64 ScopeUTEnties; | |
17431 | + u64 ScopeUAEnties; | |
17432 | + int ScopeUserNameLength; | |
17433 | + unsigned char ScopeUserName[MAX_USERNAME_LENGTH]; | |
17434 | +}; | |
17435 | + | |
17436 | +static struct list_head Scope_List; | |
17437 | +static struct semaphore Scope_Lock; | |
17438 | +static struct semaphore Scope_Thread_Delay; | |
17439 | +static int Scope_Thread_Terminate; | |
17440 | +static struct timer_list Scope_Timer; | |
17441 | +static unsigned int Scope_Hash_Val = 1; | |
17442 | + | |
17443 | +static struct scope_list *Scope_Search4Scope(struct schandle *Id, bool Session, | |
17444 | + bool Locked) | |
17445 | +{ | |
17446 | + struct scope_list *scope; | |
17447 | + struct scope_list *rscope = NULL; | |
17448 | + struct schandle *cur_scope; | |
17449 | + struct list_head *sl; | |
17450 | + int offset; | |
17451 | + | |
17452 | + DbgPrint("Scope_Search4Scope: 0x%p:%p 0x%x 0x%x\n", | |
17453 | + Id->hTypeId, Id->hId, Session, Locked); | |
17454 | + | |
17455 | + if (Session) | |
17456 | + offset = offsetof(struct scope_list, SessionId); | |
17457 | + else | |
17458 | + offset = offsetof(struct scope_list, ScopeId); | |
17459 | + | |
17460 | + if (!Locked) | |
17461 | + down(&Scope_Lock); | |
17462 | + | |
17463 | + sl = Scope_List.next; | |
17464 | + DbgPrint("Scope_Search4Scope: 0x%p\n", sl); | |
17465 | + while (sl != &Scope_List) { | |
17466 | + scope = list_entry(sl, struct scope_list, entry); | |
17467 | + | |
17468 | + cur_scope = (session_t *) ((char *)scope + offset); | |
17469 | + if (SC_EQUAL(Id, cur_scope)) { | |
17470 | + rscope = scope; | |
17471 | + break; | |
17472 | + } | |
17473 | + | |
17474 | + sl = sl->next; | |
17475 | + } | |
17476 | + | |
17477 | + if (!Locked) | |
17478 | + up(&Scope_Lock); | |
17479 | + | |
17480 | + DbgPrint("Scope_Search4Scope: return 0x%p\n", rscope); | |
17481 | + return rscope; | |
17482 | +} | |
17483 | + | |
17484 | +static struct scope_list *Scope_Find_Scope(bool Create) | |
17485 | +{ | |
17486 | + struct scope_list *scope = NULL; | |
17487 | + struct scope_list *pscope = NULL; | |
17488 | + struct task_struct *task; | |
17489 | + struct schandle scopeId; | |
17490 | + int addscope = 0; | |
17491 | + | |
17492 | + task = current; | |
17493 | + | |
17494 | + DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, | |
17495 | + task->suid, task->fsuid); | |
17496 | + | |
17497 | + /* scopeId = task->euid; */ | |
17498 | + UID_TO_SCHANDLE(scopeId, task->euid); | |
17499 | + | |
17500 | + scope = Scope_Search4Scope(&scopeId, 0, 0); | |
17501 | + if (scope || (!Create)) | |
17502 | + return scope; | |
17503 | + | |
17504 | + scope = kmalloc(sizeof(*pscope), GFP_KERNEL); | |
17505 | + if (!scope) | |
17506 | + return NULL; | |
17507 | + scope->ScopeId = scopeId; | |
17508 | + SC_INITIALIZE(scope->SessionId); | |
17509 | + scope->ScopePid = task->pid; | |
17510 | + scope->ScopeTask = task; | |
17511 | + scope->ScopeHash = 0; | |
17512 | + scope->ScopeUid = task->euid; | |
17513 | + scope->ScopeUserName[0] = '\0'; | |
17514 | + | |
17515 | + if (!Daemon_CreateSessionId(&scope->SessionId)) { | |
17516 | + DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, | |
17517 | + task->euid, task->suid, task->fsuid); | |
17518 | + memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName)); | |
17519 | + scope->ScopeUserNameLength = 0; | |
17520 | + Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), | |
17521 | + scope->ScopeUserName); | |
17522 | + scope->ScopeUserNameLength = strlen(scope->ScopeUserName); | |
17523 | + addscope = 1; | |
17524 | + } | |
17525 | + | |
17526 | + scope->ScopeHash = Scope_Hash_Val++; | |
17527 | + DbgPrint("Scope_Find_Scope: Adding 0x%p\n" | |
17528 | + " ScopeId: 0x%p:%p\n" | |
17529 | + " SessionId: 0x%p:%p\n" | |
17530 | + " ScopePid: %d\n" | |
17531 | + " ScopeTask: 0x%p\n" | |
17532 | + " ScopeHash: %u\n" | |
17533 | + " ScopeUid: %u\n" | |
17534 | + " ScopeUserNameLength: %u\n" | |
17535 | + " ScopeUserName: %s\n", | |
17536 | + scope, | |
17537 | + scope->ScopeId.hTypeId, scope->ScopeId.hId, | |
17538 | + scope->SessionId.hTypeId, scope->SessionId.hId, | |
17539 | + scope->ScopePid, | |
17540 | + scope->ScopeTask, | |
17541 | + scope->ScopeHash, | |
17542 | + scope->ScopeUid, | |
17543 | + scope->ScopeUserNameLength, | |
17544 | + scope->ScopeUserName); | |
17545 | + | |
17546 | + if (SC_PRESENT(scope->SessionId)) { | |
17547 | + down(&Scope_Lock); | |
17548 | + pscope = Scope_Search4Scope(&scopeId, 0, 1); | |
17549 | + if (!pscope) | |
17550 | + list_add(&scope->entry, &Scope_List); | |
17551 | + up(&Scope_Lock); | |
17552 | + | |
17553 | + if (pscope) { | |
17554 | + printk(KERN_ERR "Scope_Find_Scope scope not added " | |
17555 | + "because it was already there...\n"); | |
17556 | + Daemon_DestroySessionId(&scope->SessionId); | |
17557 | + kfree(scope); | |
17558 | + scope = pscope; | |
17559 | + addscope = 0; | |
17560 | + } | |
17561 | + } else { | |
17562 | + kfree(scope); | |
17563 | + scope = NULL; | |
17564 | + } | |
17565 | + | |
17566 | + if (addscope) | |
17567 | + Novfs_Add_to_Root(scope->ScopeUserName); | |
17568 | + | |
17569 | + return scope; | |
17570 | +} | |
17571 | + | |
17572 | +static int Scope_Validate_Scope(struct scope_list *Scope) | |
17573 | +{ | |
17574 | + struct scope_list *s; | |
17575 | + struct list_head *sl; | |
17576 | + int retVal = 0; | |
17577 | + | |
17578 | + DbgPrint("Scope_Validate_Scope: 0x%p\n", Scope); | |
17579 | + | |
17580 | + down(&Scope_Lock); | |
17581 | + | |
17582 | + sl = Scope_List.next; | |
17583 | + while (sl != &Scope_List) { | |
17584 | + s = list_entry(sl, struct scope_list, entry); | |
17585 | + | |
17586 | + if (s == Scope) { | |
17587 | + retVal = 1; | |
17588 | + break; | |
17589 | + } | |
17590 | + | |
17591 | + sl = sl->next; | |
17592 | + } | |
17593 | + | |
17594 | + up(&Scope_Lock); | |
17595 | + | |
17596 | + return retVal; | |
17597 | +} | |
17598 | + | |
17599 | +/* FIXME void stuff */ | |
17600 | +uid_t Scope_Get_Uid(void *foo) | |
17601 | +{ | |
17602 | + struct scope_list *scope = foo; | |
17603 | + uid_t uid = 0; | |
17604 | + | |
17605 | + if (!scope) | |
17606 | + scope = Scope_Find_Scope(1); | |
17607 | + | |
17608 | + if (scope && Scope_Validate_Scope(scope)) | |
17609 | + uid = scope->ScopeUid; | |
17610 | + | |
17611 | + return uid; | |
17612 | +} | |
17613 | + | |
17614 | +char *Scope_Get_UserName(void) | |
17615 | +{ | |
17616 | + char *name = NULL; | |
17617 | + struct scope_list *Scope; | |
17618 | + | |
17619 | + Scope = Scope_Find_Scope(1); | |
17620 | + | |
17621 | + if (Scope && Scope_Validate_Scope(Scope)) | |
17622 | + name = Scope->ScopeUserName; | |
17623 | + | |
17624 | + return name; | |
17625 | +} | |
17626 | + | |
17627 | +/* FIXME the void * needs to get fixed... */ | |
17628 | +session_t Scope_Get_SessionId(void *foo) | |
17629 | +{ | |
17630 | + session_t sessionId; | |
17631 | + struct scope_list *Scope = foo; | |
17632 | + | |
17633 | + DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope); | |
17634 | + SC_INITIALIZE(sessionId); | |
17635 | + if (!Scope) | |
17636 | + Scope = Scope_Find_Scope(1); | |
17637 | + | |
17638 | + if (Scope && Scope_Validate_Scope(Scope)) | |
17639 | + sessionId = Scope->SessionId; | |
17640 | + | |
17641 | + DbgPrint("Scope_Get_SessionId: return 0x%p:%p\n", sessionId.hTypeId, | |
17642 | + sessionId.hId); | |
17643 | + return sessionId; | |
17644 | +} | |
17645 | + | |
17646 | +struct scope_list *Scope_Get_ScopefromName(struct qstr *name) | |
17647 | +{ | |
17648 | + struct scope_list *scope; | |
17649 | + struct scope_list *rscope = NULL; | |
17650 | + struct list_head *sl; | |
17651 | + | |
17652 | + DbgPrint("Scope_Get_ScopefromName: %.*s\n", name->len, name->name); | |
17653 | + | |
17654 | + down(&Scope_Lock); | |
17655 | + | |
17656 | + sl = Scope_List.next; | |
17657 | + while (sl != &Scope_List) { | |
17658 | + scope = list_entry(sl, struct scope_list, entry); | |
17659 | + | |
17660 | + if ((name->len == scope->ScopeUserNameLength) && | |
17661 | + (strncmp(scope->ScopeUserName, name->name, name->len) == 0)) { | |
17662 | + rscope = scope; | |
17663 | + break; | |
17664 | + } | |
17665 | + sl = sl->next; | |
17666 | + } | |
17667 | + | |
17668 | + up(&Scope_Lock); | |
17669 | + | |
17670 | + return rscope; | |
17671 | +} | |
17672 | + | |
17673 | +int Scope_Set_UserSpace(u64 *TotalSize, u64 *Free, | |
17674 | + u64 *TotalEnties, u64 *FreeEnties) | |
17675 | +{ | |
17676 | + struct scope_list *scope; | |
17677 | + int retVal = 0; | |
17678 | + | |
17679 | + scope = Scope_Find_Scope(1); | |
17680 | + | |
17681 | + if (scope) { | |
17682 | + if (TotalSize) | |
17683 | + scope->ScopeUSize = *TotalSize; | |
17684 | + if (Free) | |
17685 | + scope->ScopeUFree = *Free; | |
17686 | + if (TotalEnties) | |
17687 | + scope->ScopeUTEnties = *TotalEnties; | |
17688 | + if (FreeEnties) | |
17689 | + scope->ScopeUAEnties = *FreeEnties; | |
17690 | + } | |
17691 | + | |
17692 | + return retVal; | |
17693 | +} | |
17694 | + | |
17695 | +int Scope_Get_UserSpace(u64 *TotalSize, u64 *Free, | |
17696 | + u64 *TotalEnties, u64 *FreeEnties) | |
17697 | +{ | |
17698 | + struct scope_list *scope; | |
17699 | + int retVal = 0; | |
17700 | + | |
17701 | + u64 td, fd, te, fe; | |
17702 | + | |
17703 | + scope = Scope_Find_Scope(1); | |
17704 | + | |
17705 | + td = fd = te = fe = 0; | |
17706 | + if (scope) { | |
17707 | + | |
17708 | + retVal = Daemon_Get_UserSpace(&scope->SessionId, | |
17709 | + &td, &fd, &te, &fe); | |
17710 | + | |
17711 | + scope->ScopeUSize = td; | |
17712 | + scope->ScopeUFree = fd; | |
17713 | + scope->ScopeUTEnties = te; | |
17714 | + scope->ScopeUAEnties = fe; | |
17715 | + } | |
17716 | + | |
17717 | + if (TotalSize) | |
17718 | + *TotalSize = td; | |
17719 | + if (Free) | |
17720 | + *Free = fd; | |
17721 | + if (TotalEnties) | |
17722 | + *TotalEnties = te; | |
17723 | + if (FreeEnties) | |
17724 | + *FreeEnties = fe; | |
17725 | + | |
17726 | + return retVal; | |
17727 | +} | |
17728 | + | |
17729 | +struct scope_list *Scope_Get_ScopefromPath(struct dentry *dentry) | |
17730 | +{ | |
17731 | + struct scope_list *scope = NULL; | |
17732 | + char *buf, *path, *cp; | |
17733 | + struct qstr name; | |
17734 | + | |
17735 | + buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL); | |
17736 | + if (buf) { | |
17737 | + path = Scope_dget_path(dentry, buf, PATH_LENGTH_BUFFER, 0); | |
17738 | + if (path) { | |
17739 | + DbgPrint("Scope_Get_ScopefromPath: %s\n", path); | |
17740 | + | |
17741 | + if (*path == '/') | |
17742 | + path++; | |
17743 | + | |
17744 | + cp = path; | |
17745 | + if (*cp) { | |
17746 | + while (*cp && (*cp != '/')) | |
17747 | + cp++; | |
17748 | + | |
17749 | + *cp = '\0'; | |
17750 | + name.hash = 0; | |
17751 | + name.len = (int)(cp - path); | |
17752 | + name.name = path; | |
17753 | + scope = Scope_Get_ScopefromName(&name); | |
17754 | + } | |
17755 | + } | |
17756 | + kfree(buf); | |
17757 | + } | |
17758 | + | |
17759 | + return scope; | |
17760 | +} | |
17761 | + | |
17762 | +static char *add_to_list(char *name, char *list, char *endoflist) | |
17763 | +{ | |
17764 | + while (*name && (list < endoflist)) | |
17765 | + *list++ = *name++; | |
17766 | + | |
17767 | + if (list < endoflist) | |
17768 | + *list++ = '\0'; | |
17769 | + | |
17770 | + return list; | |
17771 | +} | |
17772 | + | |
17773 | +char *Scope_Get_ScopeUsers(void) | |
17774 | +{ | |
17775 | + struct scope_list *scope; | |
17776 | + struct list_head *sl; | |
17777 | + int asize = 8 * MAX_USERNAME_LENGTH; | |
17778 | + char *list, *cp, *ep; | |
17779 | + | |
17780 | + DbgPrint("Scope_Get_ScopeUsers\n"); | |
17781 | + | |
17782 | + do { /* Copy list until done or out of memory */ | |
17783 | + list = kmalloc(asize, GFP_KERNEL); | |
17784 | + | |
17785 | + DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list); | |
17786 | + if (list) { | |
17787 | + cp = list; | |
17788 | + ep = cp + asize; | |
17789 | + | |
17790 | + /* | |
17791 | + * Add the tree and server entries | |
17792 | + */ | |
17793 | + cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep); | |
17794 | + cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep); | |
17795 | + | |
17796 | + down(&Scope_Lock); | |
17797 | + | |
17798 | + sl = Scope_List.next; | |
17799 | + while ((sl != &Scope_List) && (cp < ep)) { | |
17800 | + scope = list_entry(sl, struct scope_list, entry); | |
17801 | + | |
17802 | + DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", | |
17803 | + scope, scope->ScopeUserName); | |
17804 | + | |
17805 | + cp = add_to_list(scope->ScopeUserName, cp, ep); | |
17806 | + | |
17807 | + sl = sl->next; | |
17808 | + } | |
17809 | + | |
17810 | + up(&Scope_Lock); | |
17811 | + | |
17812 | + if (cp < ep) { | |
17813 | + *cp++ = '\0'; | |
17814 | + asize = 0; | |
17815 | + } else { /* Allocation was to small, up size */ | |
17816 | + asize *= 4; | |
17817 | + kfree(list); | |
17818 | + list = NULL; | |
17819 | + } | |
17820 | + } else { /* if allocation fails return an empty list */ | |
17821 | + | |
17822 | + break; | |
17823 | + } | |
17824 | + } while (!list); /* list was to small try again */ | |
17825 | + | |
17826 | + return list; | |
17827 | +} | |
17828 | + | |
17829 | +void *Scope_Lookup(void) | |
17830 | +{ | |
17831 | + return Scope_Find_Scope(1); | |
17832 | +} | |
17833 | + | |
17834 | +static void Scope_Timer_Function(unsigned long context) | |
17835 | +{ | |
17836 | + up(&Scope_Thread_Delay); | |
17837 | +} | |
17838 | + | |
17839 | +static int Scope_Cleanup_Thread(void *Args) | |
17840 | +{ | |
17841 | + struct scope_list *scope; | |
17842 | + struct scope_list *rscope; | |
17843 | + struct list_head *sl, cleanup; | |
17844 | + struct task_struct *task; | |
17845 | + | |
17846 | + DbgPrint("Scope_Cleanup_Thread: %d\n", current->pid); | |
17847 | + | |
17848 | + /* | |
17849 | + * Setup and start que timer | |
17850 | + */ | |
17851 | + init_timer(&Scope_Timer); | |
17852 | + | |
17853 | + while (0 == Scope_Thread_Terminate) { | |
17854 | + DbgPrint("Scope_Cleanup_Thread: looping\n"); | |
17855 | + if (Scope_Thread_Terminate) | |
17856 | + break; | |
17857 | + | |
17858 | + /* | |
17859 | + * Check scope list for any terminated processes | |
17860 | + */ | |
17861 | + down(&Scope_Lock); | |
17862 | + | |
17863 | + sl = Scope_List.next; | |
17864 | + INIT_LIST_HEAD(&cleanup); | |
17865 | + | |
17866 | + while (sl != &Scope_List) { | |
17867 | + scope = list_entry(sl, struct scope_list, entry); | |
17868 | + sl = sl->next; | |
17869 | + | |
17870 | + rscope = NULL; | |
17871 | + rcu_read_lock(); | |
17872 | + for_each_process(task) { | |
17873 | + if ((task->uid == scope->ScopeUid) | |
17874 | + || (task->euid == scope->ScopeUid)) { | |
17875 | + rscope = scope; | |
17876 | + break; | |
17877 | + } | |
17878 | + } | |
17879 | + rcu_read_unlock(); | |
17880 | + | |
17881 | + if (!rscope) { | |
17882 | + list_move(&scope->entry, &cleanup); | |
17883 | + DbgPrint("Scope_Cleanup_Thread: Scope=0x%p\n", | |
17884 | + rscope); | |
17885 | + } | |
17886 | + } | |
17887 | + | |
17888 | + up(&Scope_Lock); | |
17889 | + | |
17890 | + sl = cleanup.next; | |
17891 | + while (sl != &cleanup) { | |
17892 | + scope = list_entry(sl, struct scope_list, entry); | |
17893 | + sl = sl->next; | |
17894 | + | |
17895 | + DbgPrint("Scope_Cleanup_Thread: Removing 0x%p\n" | |
17896 | + " ScopeId: 0x%p:%p\n" | |
17897 | + " SessionId: 0x%p:%p\n" | |
17898 | + " ScopePid: %d\n" | |
17899 | + " ScopeTask: 0x%p\n" | |
17900 | + " ScopeHash: %u\n" | |
17901 | + " ScopeUid: %u\n" | |
17902 | + " ScopeUserName: %s\n", | |
17903 | + scope, | |
17904 | + scope->ScopeId, | |
17905 | + scope->SessionId, | |
17906 | + scope->ScopePid, | |
17907 | + scope->ScopeTask, | |
17908 | + scope->ScopeHash, | |
17909 | + scope->ScopeUid, scope->ScopeUserName); | |
17910 | + if (!Scope_Search4Scope(&scope->SessionId, 1, 0)) { | |
17911 | + Novfs_Remove_from_Root(scope->ScopeUserName); | |
17912 | + Daemon_DestroySessionId(&scope->SessionId); | |
17913 | + } | |
17914 | + kfree(scope); | |
17915 | + } | |
17916 | + | |
17917 | + Scope_Timer.expires = jiffies + HZ * CLEANUP_INTERVAL; | |
17918 | + Scope_Timer.data = (unsigned long)0; | |
17919 | + Scope_Timer.function = Scope_Timer_Function; | |
17920 | + add_timer(&Scope_Timer); | |
17921 | + DbgPrint("Scope_Cleanup_Thread: sleeping\n"); | |
17922 | + | |
17923 | + if (down_interruptible(&Scope_Thread_Delay)) | |
17924 | + break; | |
17925 | + | |
17926 | + del_timer(&Scope_Timer); | |
17927 | + } | |
17928 | + Scope_Thread_Terminate = 0; | |
17929 | + | |
17930 | + printk(KERN_INFO "Scope_Cleanup_Thread: Exit\n"); | |
17931 | + DbgPrint("Scope_Cleanup_Thread: Exit\n"); | |
17932 | + return 0; | |
17933 | +} | |
17934 | + | |
17935 | +void Scope_Cleanup(void) | |
17936 | +{ | |
17937 | + struct scope_list *scope; | |
17938 | + struct list_head *sl; | |
17939 | + | |
17940 | + DbgPrint("Scope_Cleanup:\n"); | |
17941 | + | |
17942 | + /* | |
17943 | + * Check scope list for any terminated processes | |
17944 | + */ | |
17945 | + down(&Scope_Lock); | |
17946 | + | |
17947 | + sl = Scope_List.next; | |
17948 | + | |
17949 | + while (sl != &Scope_List) { | |
17950 | + scope = list_entry(sl, struct scope_list, entry); | |
17951 | + sl = sl->next; | |
17952 | + | |
17953 | + list_del(&scope->entry); | |
17954 | + | |
17955 | + DbgPrint("Scope_Cleanup: Removing 0x%p\n" | |
17956 | + " ScopeId: 0x%p:%p\n" | |
17957 | + " SessionId: 0x%p:%p\n" | |
17958 | + " ScopePid: %d\n" | |
17959 | + " ScopeTask: 0x%p\n" | |
17960 | + " ScopeHash: %u\n" | |
17961 | + " ScopeUid: %u\n" | |
17962 | + " ScopeUserName: %s\n", | |
17963 | + scope, | |
17964 | + scope->ScopeId, | |
17965 | + scope->SessionId, | |
17966 | + scope->ScopePid, | |
17967 | + scope->ScopeTask, | |
17968 | + scope->ScopeHash, | |
17969 | + scope->ScopeUid, scope->ScopeUserName); | |
17970 | + if (!Scope_Search4Scope(&scope->SessionId, 1, 1)) { | |
17971 | + Novfs_Remove_from_Root(scope->ScopeUserName); | |
17972 | + Daemon_DestroySessionId(&scope->SessionId); | |
17973 | + } | |
17974 | + kfree(scope); | |
17975 | + } | |
17976 | + | |
17977 | + up(&Scope_Lock); | |
17978 | + | |
17979 | +} | |
17980 | + | |
17981 | +/* | |
17982 | + * Arguments: struct dentry *dentry - starting entry | |
17983 | + * char *Buf - pointer to memory buffer | |
17984 | + * unsigned int Buflen - size of memory buffer | |
17985 | + * | |
17986 | + * Returns: pointer to path. | |
17987 | + * | |
17988 | + * Abstract: Walks the dentry chain building a path. | |
17989 | + */ | |
17990 | +char *Scope_dget_path(struct dentry *dentry, char *Buf, unsigned int Buflen, | |
17991 | + int Flags) | |
17992 | +{ | |
17993 | + char *retval = &Buf[Buflen]; | |
17994 | + struct dentry *p = dentry; | |
17995 | + int len; | |
17996 | + | |
17997 | + *(--retval) = '\0'; | |
17998 | + Buflen--; | |
17999 | + | |
18000 | + do { | |
18001 | + if (Buflen > p->d_name.len) { | |
18002 | + retval -= p->d_name.len; | |
18003 | + Buflen -= p->d_name.len; | |
18004 | + memcpy(retval, p->d_name.name, p->d_name.len); | |
18005 | + *(--retval) = '/'; | |
18006 | + Buflen--; | |
18007 | + p = p->d_parent; | |
18008 | + } else { | |
18009 | + retval = NULL; | |
18010 | + break; | |
18011 | + } | |
18012 | + } while (!IS_ROOT(p)); | |
18013 | + | |
18014 | + if (IS_ROOT(dentry)) | |
18015 | + retval++; | |
18016 | + | |
18017 | + if (Flags) { | |
18018 | + len = strlen(p->d_sb->s_type->name); | |
18019 | + if (Buflen - len > 0) { | |
18020 | + retval -= len; | |
18021 | + Buflen -= len; | |
18022 | + memcpy(retval, p->d_sb->s_type->name, len); | |
18023 | + *(--retval) = '/'; | |
18024 | + Buflen--; | |
18025 | + } | |
18026 | + } | |
18027 | + | |
18028 | + return retval; | |
18029 | +} | |
18030 | + | |
18031 | +void Scope_Init(void) | |
18032 | +{ | |
18033 | + INIT_LIST_HEAD(&Scope_List); | |
18034 | + init_MUTEX(&Scope_Lock); | |
18035 | + init_MUTEX_LOCKED(&Scope_Thread_Delay); | |
18036 | + | |
18037 | + kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST"); | |
18038 | +} | |
18039 | + | |
18040 | +void Scope_Uninit(void) | |
18041 | +{ | |
18042 | + unsigned long expires = jiffies + HZ * SHUTDOWN_INTERVAL; | |
18043 | + | |
18044 | + printk(KERN_INFO "Scope_Uninit: Start\n"); | |
18045 | + | |
18046 | + Scope_Thread_Terminate = 1; | |
18047 | + | |
18048 | + up(&Scope_Thread_Delay); | |
18049 | + | |
18050 | + mb(); | |
18051 | + while (Scope_Thread_Terminate && (jiffies < expires)) | |
18052 | + yield(); | |
18053 | + | |
18054 | + /* down(&Scope_Thread_Delay); */ | |
18055 | + printk(KERN_INFO "Scope_Uninit: Exit\n"); | |
18056 | + | |
18057 | +} | |
18058 | + | |
18059 | + | |
18060 | --- /dev/null | |
18061 | +++ b/fs/novfs/vfs.h | |
18062 | @@ -0,0 +1,436 @@ | |
18063 | +/* | |
18064 | + * Novell NCP Redirector for Linux | |
18065 | + * Author: James Turner | |
18066 | + * | |
18067 | + * Include file for novfs. | |
18068 | + * | |
18069 | + * Copyright (C) 2005 Novell, Inc. | |
18070 | + * | |
18071 | + * This program is free software; you can redistribute it and/or | |
18072 | + * modify it under the terms of the GNU General Public License | |
18073 | + * as published by the Free Software Foundation; either version 2 | |
18074 | + * of the License, or (at your option) any later version. | |
18075 | + */ | |
18076 | +#ifndef __NOVFS_H | |
18077 | +#define __NOVFS_H | |
18078 | + | |
18079 | +#ifndef __STDC_VERSION__ | |
18080 | +#define __STDC_VERSION__ 0L | |
18081 | +#endif | |
18082 | + | |
18083 | +#include <linux/version.h> | |
18084 | +#include <linux/namei.h> | |
18085 | +#include <linux/string.h> | |
18086 | + | |
18087 | +#include "nwcapi.h" | |
18088 | + | |
18089 | +typedef void *HANDLE; | |
18090 | + | |
18091 | +struct schandle { | |
18092 | + void *hTypeId; | |
18093 | + void *hId; | |
18094 | +}; | |
18095 | + | |
18096 | +static inline void copy_schandle(struct schandle *dest, struct schandle *source) | |
18097 | +{ | |
18098 | + memcpy(dest, source, sizeof(struct schandle)); | |
18099 | +} | |
18100 | +#define copy_session_id copy_schandle | |
18101 | + | |
18102 | +typedef struct schandle session_t; | |
18103 | + | |
18104 | +#include "commands.h" | |
18105 | + | |
18106 | +#define SC_PRESENT(X) ((X.hTypeId != NULL) || (X.hId != NULL)) ? 1 : 0 | |
18107 | +#define SC_EQUAL(X, Y) ((X->hTypeId == Y->hTypeId) && (X->hId == Y->hId)) ? 1 : 0 | |
18108 | +#define SC_INITIALIZE(X) {X.hTypeId = X.hId = NULL;} | |
18109 | + | |
18110 | +#define UID_TO_SCHANDLE(hSC, uid) \ | |
18111 | + { \ | |
18112 | + hSC.hTypeId = NULL; \ | |
18113 | + hSC.hId = (HANDLE)(unsigned long)(uid); \ | |
18114 | + } | |
18115 | + | |
18116 | + | |
18117 | + | |
18118 | +/*===[ Manifest constants ]===============================================*/ | |
18119 | +#define NOVFS_MAGIC 0x4e574653 | |
18120 | +#define MODULE_NAME "novfs" | |
18121 | + | |
18122 | +#define TREE_DIRECTORY_NAME ".Trees" | |
18123 | +#define SERVER_DIRECTORY_NAME ".Servers" | |
18124 | + | |
18125 | +#define PATH_LENGTH_BUFFER PATH_MAX | |
18126 | +#define NW_MAX_PATH_LENGTH 255 | |
18127 | + | |
18128 | +#define XA_BUFFER (8 * 1024) | |
18129 | + | |
18130 | +#define IOC_LOGIN 0x4a540000 | |
18131 | +#define IOC_LOGOUT 0x4a540001 | |
18132 | +#define IOC_XPLAT 0x4a540002 | |
18133 | +#define IOC_SESSION 0x4a540003 | |
18134 | +#define IOC_DEBUGPRINT 0x4a540004 | |
18135 | + | |
18136 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) | |
18137 | +#define D_CHILD d_u.d_child | |
18138 | +#define AS_TREE_LOCK(l) read_lock_irq(l) | |
18139 | +#define AS_TREE_UNLOCK(l) read_unlock_irq(l) | |
18140 | +#else | |
18141 | +#define D_CHILD d_child | |
18142 | +#define AS_TREE_LOCK(l) spin_lock_irq(l) | |
18143 | +#define AS_TREE_UNLOCK(l) spin_unlock_irq(l) | |
18144 | +#endif | |
18145 | + | |
18146 | +/* | |
18147 | + * NetWare file attributes | |
18148 | + */ | |
18149 | + | |
18150 | +#define NW_ATTRIBUTE_NORMAL 0x00 | |
18151 | +#define NW_ATTRIBUTE_READ_ONLY 0x01 | |
18152 | +#define NW_ATTRIBUTE_HIDDEN 0x02 | |
18153 | +#define NW_ATTRIBUTE_SYSTEM 0x04 | |
18154 | +#define NW_ATTRIBUTE_EXECUTE_ONLY 0x08 | |
18155 | +#define NW_ATTRIBUTE_DIRECTORY 0x10 | |
18156 | +#define NW_ATTRIBUTE_ARCHIVE 0x20 | |
18157 | +#define NW_ATTRIBUTE_EXECUTE 0x40 | |
18158 | +#define NW_ATTRIBUTE_SHAREABLE 0x80 | |
18159 | + | |
18160 | +/* | |
18161 | + * Define READ/WRITE flag for struct data_list | |
18162 | + */ | |
18163 | +#define DLREAD 0 | |
18164 | +#define DLWRITE 1 | |
18165 | + | |
18166 | +/* | |
18167 | + * Define list type | |
18168 | + */ | |
18169 | +#define USER_LIST 1 | |
18170 | +#define SERVER_LIST 2 | |
18171 | +#define VOLUME_LIST 3 | |
18172 | + | |
18173 | +/* | |
18174 | + * Define flags used in for inodes | |
18175 | + */ | |
18176 | +#define USER_INODE 1 | |
18177 | +#define UPDATE_INODE 2 | |
18178 | + | |
18179 | +/* | |
18180 | + * Define flags for directory cache flags | |
18181 | + */ | |
18182 | +#define ENTRY_VALID 0x00000001 | |
18183 | + | |
18184 | +#ifdef INTENT_MAGIC | |
18185 | +#define NDOPENFLAGS intent.it_flags | |
18186 | +#else | |
18187 | +#define NDOPENFLAGS intent.open.flags | |
18188 | +#endif | |
18189 | + | |
18190 | +/* | |
18191 | + * daemon_command_t flags values | |
18192 | + */ | |
18193 | +#define INTERRUPTIBLE 1 | |
18194 | + | |
18195 | +#ifndef NOVFS_VFS_MAJOR | |
18196 | +#define NOVFS_VFS_MAJOR 0 | |
18197 | +#endif | |
18198 | + | |
18199 | +#ifndef NOVFS_VFS_MINOR | |
18200 | +#define NOVFS_VFS_MINOR 0 | |
18201 | +#endif | |
18202 | + | |
18203 | +#ifndef NOVFS_VFS_SUB | |
18204 | +#define NOVFS_VFS_SUB 0 | |
18205 | +#endif | |
18206 | + | |
18207 | +#ifndef NOVFS_VFS_RELEASE | |
18208 | +#define NOVFS_VFS_RELEASE 0 | |
18209 | +#endif | |
18210 | + | |
18211 | +#define VALUE_TO_STR( value ) #value | |
18212 | +#define DEFINE_TO_STR(value) VALUE_TO_STR(value) | |
18213 | + | |
18214 | +#define NOVFS_VERSION_STRING \ | |
18215 | + DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \ | |
18216 | + DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \ | |
18217 | + DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \ | |
18218 | + DEFINE_TO_STR(NOVFS_VFS_RELEASE) \ | |
18219 | + "\0" | |
18220 | + | |
18221 | +struct entry_info { | |
18222 | + int type; | |
18223 | + umode_t mode; | |
18224 | + uid_t uid; | |
18225 | + gid_t gid; | |
18226 | + loff_t size; | |
18227 | + struct timespec atime; | |
18228 | + struct timespec mtime; | |
18229 | + struct timespec ctime; | |
18230 | + int namelength; | |
18231 | + unsigned char name[1]; | |
18232 | +}; | |
18233 | + | |
18234 | +struct novfs_string { | |
18235 | + int length; | |
18236 | + unsigned char *data; | |
18237 | +}; | |
18238 | + | |
18239 | +struct login { | |
18240 | + struct novfs_string Server; | |
18241 | + struct novfs_string UserName; | |
18242 | + struct novfs_string Password; | |
18243 | +}; | |
18244 | + | |
18245 | +struct logout { | |
18246 | + struct novfs_string Server; | |
18247 | +}; | |
18248 | + | |
18249 | +struct dir_cache { | |
18250 | + struct list_head list; | |
18251 | + int flags; | |
18252 | + u64 jiffies; | |
18253 | + ino_t ino; | |
18254 | + loff_t size; | |
18255 | + umode_t mode; | |
18256 | + struct timespec atime; | |
18257 | + struct timespec mtime; | |
18258 | + struct timespec ctime; | |
18259 | + unsigned long hash; | |
18260 | + int nameLen; | |
18261 | + char name[1]; | |
18262 | +}; | |
18263 | + | |
18264 | +struct data_list { | |
18265 | + void *page; | |
18266 | + void *offset; | |
18267 | + int len; | |
18268 | + int rwflag; | |
18269 | +}; | |
18270 | + | |
18271 | + | |
18272 | +extern char *ctime_r(time_t * clock, char *buf); | |
18273 | + | |
18274 | +static inline u32 HandletoUint32(HANDLE h) | |
18275 | +/* | |
18276 | + * | |
18277 | + * Arguments: HANDLE h - handle value | |
18278 | + * | |
18279 | + * Returns: u32 - u32 value | |
18280 | + * | |
18281 | + * Abstract: Converts a HANDLE to a u32 type. | |
18282 | + * | |
18283 | + * Notes: | |
18284 | + * | |
18285 | + * Environment: | |
18286 | + * | |
18287 | + *========================================================================*/ | |
18288 | +{ | |
18289 | + return (u32) ((unsigned long) h); | |
18290 | +} | |
18291 | + | |
18292 | +/*++======================================================================*/ | |
18293 | +static inline HANDLE Uint32toHandle(u32 ui32) | |
18294 | +/* | |
18295 | + * | |
18296 | + * Arguments: u32 ui32 | |
18297 | + * | |
18298 | + * Returns: HANDLE - Handle type. | |
18299 | + * | |
18300 | + * Abstract: Converts a u32 to a HANDLE type. | |
18301 | + * | |
18302 | + * Notes: | |
18303 | + * | |
18304 | + * Environment: | |
18305 | + * | |
18306 | + *========================================================================*/ | |
18307 | +{ | |
18308 | + return ((HANDLE) (unsigned long) ui32); | |
18309 | +} | |
18310 | + | |
18311 | +/* Global variables */ | |
18312 | + | |
18313 | +extern int Novfs_Version_Major; | |
18314 | +extern int Novfs_Version_Minor; | |
18315 | +extern int Novfs_Version_Sub; | |
18316 | +extern int Novfs_Version_Release; | |
18317 | +extern struct dentry *Novfs_root; | |
18318 | +extern struct proc_dir_entry *Novfs_Procfs_dir; | |
18319 | +extern unsigned long File_update_timeout; | |
18320 | +extern int PageCache; | |
18321 | +extern char *Novfs_CurrentMount; | |
18322 | +extern struct dentry_operations Novfs_dentry_operations; | |
18323 | +extern int MaxIoSize; | |
18324 | + | |
18325 | + | |
18326 | +/* Global functions */ | |
18327 | +extern int Novfs_Remove_from_Root(char *); | |
18328 | +extern void Novfs_dump_inode(void *pf); | |
18329 | + | |
18330 | +extern void mydump(int size, void *dumpptr); | |
18331 | + | |
18332 | +extern int Queue_Daemon_Command(void *request, unsigned long reqlen, void *data, | |
18333 | + int dlen, void **reply, unsigned long * replen, | |
18334 | + int interruptible); | |
18335 | + | |
18336 | +extern int Init_Procfs_Interface(void); | |
18337 | +extern void Uninit_Procfs_Interface(void); | |
18338 | + | |
18339 | +/* | |
18340 | + * daemon.c functions | |
18341 | + */ | |
18342 | +extern void Init_Daemon_Queue(void); | |
18343 | +extern void Uninit_Daemon_Queue(void); | |
18344 | +extern int do_login(NclString * Server, NclString * Username, NclString * Password, HANDLE * lgnId, struct schandle *Session); | |
18345 | +extern int do_logout(struct qstr *Server, struct schandle *Session); | |
18346 | +extern int Daemon_SetMountPoint(char *Path); | |
18347 | +extern int Daemon_CreateSessionId(struct schandle *SessionId); | |
18348 | +extern int Daemon_DestroySessionId(struct schandle *SessionId); | |
18349 | +extern int Daemon_getpwuid(uid_t uid, int unamelen, char *uname); | |
18350 | +extern int Daemon_Get_UserSpace(struct schandle *session_id, u64 *TotalSize, | |
18351 | + u64 *TotalFree, u64 *TotalDirectoryEnties, | |
18352 | + u64 *FreeDirectoryEnties); | |
18353 | +extern int Daemon_SendDebugCmd(char *Command); | |
18354 | +extern ssize_t Daemon_Receive_Reply(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos); | |
18355 | +extern ssize_t Daemon_Send_Command(struct file *file, char __user *buf, size_t len, loff_t *off); | |
18356 | +extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | |
18357 | +extern int Daemon_Library_close(struct inode *inode, struct file *file); | |
18358 | +extern int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | |
18359 | +extern int Daemon_Library_open(struct inode *inode, struct file *file); | |
18360 | +extern ssize_t Daemon_Library_write(struct file *file, const char __user *buf, size_t len, loff_t * off); | |
18361 | +extern ssize_t Daemon_Library_read(struct file *file, char __user *buf, size_t len, loff_t * off); | |
18362 | +extern loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin); | |
18363 | +extern int Daemon_Open_Control(struct inode *Inode, struct file *File); | |
18364 | +extern int Daemon_Close_Control(struct inode *Inode, struct file *File); | |
18365 | +extern int Daemon_getversion(char *Buf, int Length); | |
18366 | + | |
18367 | + | |
18368 | +/* | |
18369 | + * file.c functions | |
18370 | + */ | |
18371 | +extern int Novfs_get_alltrees(struct dentry *parent); | |
18372 | +extern int Novfs_Get_Connected_Server_List(unsigned char **ServerList, struct schandle *SessionId); | |
18373 | +extern int Novfs_Get_Server_Volume_List(struct qstr *Server, unsigned char **VolumeList, struct schandle *SessionId); | |
18374 | +extern int Novfs_Get_File_Info(unsigned char *Path, struct entry_info *Info, struct schandle *SessionId); | |
18375 | +extern int Novfs_GetX_File_Info(char *Path, const char *Name, char *buffer, ssize_t buffer_size, ssize_t *dataLen, struct schandle *SessionId); | |
18376 | +extern int Novfs_ListX_File_Info(char *Path, char *buffer, ssize_t buffer_size, ssize_t * dataLen, struct schandle *SessionId); | |
18377 | +extern int Novfs_SetX_File_Info(char *Path, const char *Name, const void *Value, | |
18378 | + unsigned long valueLen, | |
18379 | + unsigned long *bytesWritten, int flags, | |
18380 | + struct schandle *SessionId); | |
18381 | + | |
18382 | +extern int Novfs_Get_Directory_ListEx(unsigned char *Path, HANDLE *EnumHandle, | |
18383 | + int *Count, struct entry_info **Info, | |
18384 | + struct schandle *SessionId); | |
18385 | +extern int Novfs_Open_File(unsigned char *Path, int Flags, struct entry_info *info, | |
18386 | + HANDLE * Handle, session_t SessionId); | |
18387 | +extern int Novfs_Create(unsigned char *Path, int DirectoryFlag, | |
18388 | + session_t SessionId); | |
18389 | +extern int Novfs_Close_File(HANDLE Handle, session_t SessionId); | |
18390 | +extern int Novfs_Read_File(HANDLE Handle, unsigned char *Buffer, size_t * Bytes, | |
18391 | + loff_t * Offset, session_t SessionId); | |
18392 | +extern int Novfs_Read_Pages(HANDLE Handle, struct data_list *dlist, int DList_Cnt, | |
18393 | + size_t * Bytes, loff_t * Offset, | |
18394 | + session_t SessionId); | |
18395 | +extern int Novfs_Write_File(HANDLE Handle, unsigned char *Buffer, | |
18396 | + size_t * Bytes, loff_t * Offset, | |
18397 | + session_t SessionId); | |
18398 | +extern int Novfs_Write_Page(HANDLE Handle, struct page *Page, | |
18399 | + session_t SessionId); | |
18400 | +extern int Novfs_Write_Pages(HANDLE Handle, struct data_list *dlist, int DList_Cnt, | |
18401 | + size_t Bytes, loff_t Offset, session_t SessionId); | |
18402 | +extern int Novfs_Delete(unsigned char *Path, int DirectoryFlag, | |
18403 | + session_t SessionId); | |
18404 | +extern int Novfs_Truncate_File(unsigned char *Path, int PathLen, | |
18405 | + session_t SessionId); | |
18406 | +extern int Novfs_Truncate_File_Ex(HANDLE Handle, loff_t Offset, | |
18407 | + session_t SessionId); | |
18408 | +extern int Novfs_Rename_File(int DirectoryFlag, unsigned char *OldName, | |
18409 | + int OldLen, unsigned char *NewName, int NewLen, | |
18410 | + session_t SessionId); | |
18411 | +extern int Novfs_Set_Attr(unsigned char *Path, struct iattr *Attr, | |
18412 | + session_t SessionId); | |
18413 | +extern int Novfs_Get_File_Cache_Flag(unsigned char * Path, session_t SessionId); | |
18414 | +extern int Novfs_Set_File_Lock(session_t SessionId, HANDLE fhandle, | |
18415 | + unsigned char fl_type, loff_t fl_start, | |
18416 | + loff_t len); | |
18417 | + | |
18418 | +extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name); | |
18419 | +extern int Novfs_Read_Stream(HANDLE ConnHandle, unsigned char * Handle, | |
18420 | + unsigned char * Buffer, size_t * Bytes, loff_t * Offset, | |
18421 | + int User, session_t SessionId); | |
18422 | +extern int Novfs_Write_Stream(HANDLE ConnHandle, unsigned char * Handle, | |
18423 | + unsigned char * Buffer, size_t * Bytes, loff_t * Offset, | |
18424 | + session_t SessionId); | |
18425 | +extern int Novfs_Close_Stream(HANDLE ConnHandle, unsigned char * Handle, | |
18426 | + session_t SessionId); | |
18427 | + | |
18428 | +extern int Novfs_Add_to_Root(char *); | |
18429 | + | |
18430 | + | |
18431 | +/* | |
18432 | + * scope.c functions | |
18433 | + */ | |
18434 | +extern void Scope_Init(void); | |
18435 | +extern void Scope_Uninit(void); | |
18436 | +extern void *Scope_Lookup(void); | |
18437 | +extern uid_t Scope_Get_Uid(void *); | |
18438 | +extern session_t Scope_Get_SessionId(void *Scope); | |
18439 | +//extern session_t Scope_Get_SessionId(PSCOPE_LIST Scope); | |
18440 | +extern char *Scope_Get_ScopeUsers(void); | |
18441 | +extern int Scope_Set_UserSpace(u64 *TotalSize, u64 *Free, | |
18442 | + u64 *TotalEnties, u64 *FreeEnties); | |
18443 | +extern int Scope_Get_UserSpace(u64 *TotalSize, u64 *Free, | |
18444 | + u64 *TotalEnties, u64 *FreeEnties); | |
18445 | +extern char *Scope_dget_path(struct dentry *Dentry, char *Buf, | |
18446 | + unsigned int Buflen, int Flags); | |
18447 | +extern char *Scope_Get_UserName(void); | |
18448 | +extern void Scope_Cleanup(void); | |
18449 | + | |
18450 | +/* | |
18451 | + * profile.c functions | |
18452 | + */ | |
18453 | +extern u64 get_nanosecond_time(void); | |
18454 | +static inline void *Novfs_Malloc(size_t size, int flags) { return kmalloc(size, flags); } | |
18455 | +extern int DbgPrint(char *Fmt, ...); | |
18456 | +extern int init_profile(void); | |
18457 | +extern void uninit_profile(void); | |
18458 | + | |
18459 | +/* | |
18460 | + * nwcapi.c functions | |
18461 | + */ | |
18462 | +extern int NwAuthConnWithId(PXPLAT pdata, session_t Session); | |
18463 | +extern int NwConnClose(PXPLAT pdata, HANDLE * Handle, session_t Session); | |
18464 | +extern int NwGetConnInfo(PXPLAT pdata, session_t Session); | |
18465 | +extern int NwSetConnInfo(PXPLAT pdata, session_t Session); | |
18466 | +extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session); | |
18467 | +extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session); | |
18468 | +extern int NwLicenseConn(PXPLAT pdata, session_t Session); | |
18469 | +extern int NwLoginIdentity(PXPLAT pdata, struct schandle *Session); | |
18470 | +extern int NwLogoutIdentity(PXPLAT pdata, session_t Session); | |
18471 | +extern int NwOpenConnByAddr(PXPLAT pdata, HANDLE * Handle, session_t Session); | |
18472 | +extern int NwOpenConnByName(PXPLAT pdata, HANDLE * Handle, session_t Session); | |
18473 | +extern int NwOpenConnByRef(PXPLAT pdata, HANDLE * Handle, session_t Session); | |
18474 | +extern int NwQueryFeature(PXPLAT pdata, session_t Session); | |
18475 | +extern int NwRawSend(PXPLAT pdata, session_t Session); | |
18476 | +extern int NwScanConnInfo(PXPLAT pdata, session_t Session); | |
18477 | +extern int NwSysConnClose(PXPLAT pdata, unsigned long * Handle, session_t Session); | |
18478 | +extern int NwUnAuthenticate(PXPLAT pdata, session_t Session); | |
18479 | +extern int NwUnlicenseConn(PXPLAT pdata, session_t Session); | |
18480 | +extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session); | |
18481 | +extern int NwcEnumIdentities(PXPLAT pdata, session_t Session); | |
18482 | +extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session); | |
18483 | +extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session); | |
18484 | +extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session); | |
18485 | +extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session); | |
18486 | +extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session); | |
18487 | +extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session); | |
18488 | +extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session); | |
18489 | +extern int NwcSetMapDrive(PXPLAT pdata, session_t Session); | |
18490 | +extern int NwcUnMapDrive(PXPLAT pdata, session_t Session); | |
18491 | +extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session); | |
18492 | +extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session); | |
18493 | +extern int NwdSetKeyValue(PXPLAT pdata, session_t Session); | |
18494 | +extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session); | |
18495 | + | |
18496 | + | |
18497 | +#endif /* __NOVFS_H */ | |
18498 | + |