]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/novfs-add-the-novell-filesystem-client-kernel-module.patch
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / novfs-add-the-novell-filesystem-client-kernel-module.patch
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(&current->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(&current->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 +