Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / libcfs / include / libcfs / winnt / winnt-prim.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * libcfs/include/libcfs/winnt/winnt-prim.h
37  *
38  * Basic library routines.
39  */
40
41 #ifndef __LIBCFS_WINNT_CFS_PRIM_H__
42 #define __LIBCFS_WINNT_CFS_PRIM_H__
43
44 #ifndef __LIBCFS_LIBCFS_H__
45 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
46 #endif
47
48
49 /*
50  * libcfs proc device object
51  */
52
53
54 #define LUSTRE_PROC_DEVICE  L"\\Device\\lproc"      /* proc fs emulator device object */
55 #define LUSTRE_PROC_SYMLNK  L"\\DosDevices\\lproc"  /* proc fs user-visible device */
56
57
58 /*
59  * Device IO Control Code Definitions
60  */
61
62 #define FILE_DEVICE_LIBCFS      ('LC')
63
64 #define FILE_DEVICE_LIBCFS      ('LC')
65
66 #define FUNC_LIBCFS_VERSION     0x101  // get version of current libcfs
67 #define FUNC_LIBCFS_IOCTL       0x102  // Device i/o control to proc fs
68
69
70 #define IOCTL_LIBCFS_VERSION \
71      CTL_CODE (FILE_DEVICE_LIBCFS, FUNC_LIBCFS_VERSION, METHOD_BUFFERED, FILE_ANY_ACCESS)
72 #define IOCTL_LIBCFS_ENTRY   \
73      CTL_CODE(FILE_DEVICE_LIBCFS, FUNC_LIBCFS_IOCTL,   METHOD_BUFFERED, FILE_ANY_ACCESS)
74
75 #pragma pack(4)
76
77 typedef struct _CFS_PROC_IOCTL {
78
79     ULONG           cmd;    // ioctl command identifier
80     ULONG           len;    // length of data
81
82     // UCHAR        data[]; // content of the real ioctl
83
84 } CFS_PROC_IOCTL, *PCFS_PROC_IOCTL;
85
86 #pragma pack()
87
88 #ifdef __KERNEL__
89
90 #include <libcfs/list.h>
91
92 /*
93  * Symbol functions for libcfs
94  *
95  * OSX has no facility for use to register symbol.
96  * So we have to implement it.
97  */
98 #define CFS_SYMBOL_LEN     64
99
100 struct  cfs_symbol {
101         char    name[CFS_SYMBOL_LEN];
102         void    *value;
103         int     ref;
104         struct  list_head sym_list;
105 };
106
107 extern int      cfs_symbol_register(const char *, const void *);
108 extern void     cfs_symbol_unregister(const char *);
109 extern void *   cfs_symbol_get(const char *);
110 extern void     cfs_symbol_put(const char *);
111 extern void     cfs_symbol_clean();
112
113
114
115 typedef struct file_operations cfs_file_operations_t;
116 typedef struct file cfs_file_t;
117
118 /*
119  * Pseudo device register
120  */
121
122 typedef struct
123 {
124     int                     minor;
125     const char *            name;
126     cfs_file_operations_t * fops;
127 } cfs_psdev_t;
128
129 int cfs_psdev_register(cfs_psdev_t * psdev);
130 int cfs_psdev_deregister(cfs_psdev_t * psdev);
131
132
133 /*
134  * Proc emulator file system APIs
135  */
136
137 typedef int cfs_read_proc_t(char *page, char **start, off_t off,
138                           int count, int *eof, void *data);
139 typedef int cfs_write_proc_t(struct file *file, const char *buffer,
140                            ulong_ptr count, void *data);
141
142 #define CFS_PROC_ENTRY_MAGIC 'CPEM'
143
144 #define CFS_PROC_FLAG_DIRECTORY    0x00000001 // directory node
145 #define CFS_PROC_FLAG_ATTACHED     0x00000002 // node is attached to proc
146 #define CFS_PROC_FLAG_MISCDEV      0x00000004 // miscellaneous device
147
148 typedef struct cfs_proc_entry
149 {
150     ULONG                   magic;      // Magic
151     ULONG                   flags;      // Flags
152
153     struct _dir_entry {                 // proc directory entry
154         PRTL_SPLAY_LINKS    root;
155     };
156
157     struct _file_entry {                // proc file / leaf entry
158             cfs_read_proc_t  *  read_proc;
159             cfs_write_proc_t *  write_proc;
160     };
161
162     mode_t                  mode;
163     unsigned short          nlink;
164
165         
166     struct file_operations * proc_fops;
167         void * data;
168
169     // proc_dir_entry ended.
170
171     RTL_SPLAY_LINKS         s_link;       // splay link
172
173     //
174     // Maximum length of proc entry name is 0x20
175     //
176
177     char                    name[0x20];
178
179 } cfs_proc_entry_t, cfs_proc_dir_entry_t;
180
181 typedef cfs_proc_entry_t cfs_proc_dir_entry_t;
182
183 #define PROC_BLOCK_SIZE    PAGE_SIZE
184
185 /*
186  * Sysctl register
187  */
188
189 typedef struct ctl_table                    cfs_sysctl_table_t;
190 typedef struct ctl_table_header         cfs_sysctl_table_header_t;
191
192
193 typedef int ctl_handler (
194             cfs_sysctl_table_t *table,
195             int *name,    int nlen,
196                         void *oldval, size_t *oldlenp,
197                         void *newval, size_t newlen, 
198                         void **context );
199
200 typedef int proc_handler (
201             cfs_sysctl_table_t *ctl,
202             int write, struct file * filp,
203                         void *buffer, size_t *lenp );
204
205
206 int proc_dointvec(cfs_sysctl_table_t *table, int write, struct file *filp,
207                      void *buffer, size_t *lenp);
208
209 int proc_dostring(cfs_sysctl_table_t *table, int write, struct file *filp,
210                   void *buffer, size_t *lenp);
211
212 int sysctl_string(cfs_sysctl_table_t *table, int *name, int nlen,
213                   void *oldval, size_t *oldlenp,
214                   void *newval, size_t newlen, void **context);
215
216
217 /*
218  *  System io control definitions
219  */
220
221 #define CTL_MAXNAME 10
222
223 #define CTL_ANY     -1  /* Matches any name */
224 #define CTL_NONE    0
225
226 enum
227 {
228     CTL_KERN=1,     /* General kernel info and control */
229     CTL_VM=2,       /* VM management */
230     CTL_NET=3,      /* Networking */
231     CTL_PROC=4,     /* Process info */
232     CTL_FS=5,       /* Filesystems */
233     CTL_DEBUG=6,        /* Debugging */
234     CTL_DEV=7,      /* Devices */
235     CTL_BUS=8,      /* Busses */
236     CTL_ABI=9,      /* Binary emulation */
237     CTL_CPU=10      /* CPU stuff (speed scaling, etc) */
238 };
239
240 /* sysctl table definitons */
241 struct ctl_table 
242 {
243         int ctl_name;
244         char *procname;
245         void *data;
246         int maxlen;
247         mode_t mode;
248         cfs_sysctl_table_t *child;
249         proc_handler *proc_handler;     /* text formatting callback */
250         ctl_handler *strategy;          /* read / write callback functions */
251         cfs_proc_entry_t *de;   /* proc entry block */
252         void *extra1;
253         void *extra2;
254 };
255
256
257 /* the mantaner of the cfs_sysctl_table trees */
258 struct ctl_table_header
259 {
260         cfs_sysctl_table_t *    ctl_table;
261         struct list_head        ctl_entry;
262 };
263
264
265 cfs_proc_entry_t * create_proc_entry(char *name, mode_t mod,
266                                           cfs_proc_entry_t *parent);
267 void proc_free_entry(cfs_proc_entry_t *de);
268 void remove_proc_entry(char *name, cfs_proc_entry_t *entry);
269 cfs_proc_entry_t * search_proc_entry(char * name,
270                         cfs_proc_entry_t *  root );
271
272 #define cfs_create_proc_entry create_proc_entry
273 #define cfs_free_proc_entry   proc_free_entry
274 #define cfs_remove_proc_entry remove_proc_entry
275
276 #define register_cfs_sysctl_table(t, a) register_sysctl_table(t, a)
277 #define unregister_cfs_sysctl_table(t)  unregister_sysctl_table(t, a)
278
279
280 /*
281  *  declaration of proc kernel process routines
282  */
283
284 cfs_file_t *
285 lustre_open_file(char * filename);
286
287 int
288 lustre_close_file(cfs_file_t * fh);
289
290 int
291 lustre_do_ioctl( cfs_file_t * fh,
292                  unsigned long cmd,
293                  ulong_ptr arg );
294
295 int
296 lustre_ioctl_file( cfs_file_t * fh,
297                    PCFS_PROC_IOCTL devctl);
298
299 size_t
300 lustre_read_file( cfs_file_t *    fh,
301                   loff_t          off,
302                   size_t          size,
303                   char *          buf
304                   );
305
306 size_t
307 lustre_write_file( cfs_file_t *    fh,
308                    loff_t          off,
309                    size_t          size,
310                    char *          buf
311                    );
312
313 /*
314  * Wait Queue
315  */
316
317
318 typedef int cfs_task_state_t;
319
320 #define CFS_TASK_INTERRUPTIBLE  0x00000001
321 #define CFS_TASK_UNINT          0x00000002
322 #define CFS_TASK_RUNNING        0x00000003
323
324
325 #define CFS_WAITQ_MAGIC     'CWQM'
326 #define CFS_WAITLINK_MAGIC  'CWLM'
327
328 typedef struct cfs_waitq {
329
330     unsigned int        magic;
331     unsigned int        flags;
332     
333     spinlock_t          guard;
334     struct list_head    waiters;
335
336 } cfs_waitq_t;
337
338
339 typedef struct cfs_waitlink cfs_waitlink_t;
340
341 #define CFS_WAITQ_CHANNELS     (2)
342
343 #define CFS_WAITQ_CHAN_NORMAL  (0)
344 #define CFS_WAITQ_CHAN_FORWARD (1)
345
346
347
348 typedef struct cfs_waitlink_channel {
349     struct list_head        link;
350     cfs_waitq_t *           waitq;
351     cfs_waitlink_t *        waitl;
352 } cfs_waitlink_channel_t;
353
354 struct cfs_waitlink {
355
356     unsigned int            magic;
357     int                     flags;
358     event_t  *              event;
359     atomic_t *              hits;
360
361     cfs_waitlink_channel_t  waitq[CFS_WAITQ_CHANNELS];
362 };
363
364 enum {
365         CFS_WAITQ_EXCLUSIVE = 1
366 };
367
368 #define CFS_DECL_WAITQ(name) cfs_waitq_t name
369
370
371 void cfs_waitq_init(struct cfs_waitq *waitq);
372 void cfs_waitlink_init(struct cfs_waitlink *link);
373
374 void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link);
375 void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, 
376                              struct cfs_waitlink *link);
377 void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link);
378 int  cfs_waitq_active(struct cfs_waitq *waitq);
379
380 void cfs_waitq_signal(struct cfs_waitq *waitq);
381 void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr);
382 void cfs_waitq_broadcast(struct cfs_waitq *waitq);
383
384 void cfs_waitq_wait(struct cfs_waitlink *link, cfs_task_state_t state);
385 cfs_duration_t cfs_waitq_timedwait(struct cfs_waitlink *link, 
386                                    cfs_task_state_t state, cfs_duration_t timeout);
387
388
389
390 /* Kernel thread */
391
392 typedef int (*cfs_thread_t) (void *arg);
393
394 typedef struct _cfs_thread_context {
395     cfs_thread_t        func;
396     void *              arg;
397 } cfs_thread_context_t;
398
399 int cfs_kernel_thread(int (*func)(void *), void *arg, int flag);
400
401 /*
402  * thread creation flags from Linux, not used in winnt
403  */
404 #define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
405 #define CLONE_VM        0x00000100      /* set if VM shared between processes */
406 #define CLONE_FS        0x00000200      /* set if fs info shared between processes */
407 #define CLONE_FILES     0x00000400      /* set if open files shared between processes */
408 #define CLONE_SIGHAND   0x00000800      /* set if signal handlers and blocked signals shared */
409 #define CLONE_PID       0x00001000      /* set if pid shared */
410 #define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
411 #define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
412 #define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
413 #define CLONE_THREAD    0x00010000      /* Same thread group? */
414 #define CLONE_NEWNS     0x00020000      /* New namespace group? */
415
416 #define CLONE_SIGNAL    (CLONE_SIGHAND | CLONE_THREAD)
417
418
419 /*
420  * sigset ...
421  */
422
423 typedef sigset_t cfs_sigset_t;
424
425 /*
426  * Task struct
427  */
428
429 #define MAX_SCHEDULE_TIMEOUT    ((long_ptr)(~0UL>>12))
430
431
432 #define NGROUPS 1
433 #define CFS_CURPROC_COMM_MAX (16)
434 typedef struct task_sruct{
435     mode_t umask;
436
437         pid_t pid;
438         pid_t pgrp;
439
440         uid_t uid,euid,suid,fsuid;
441         gid_t gid,egid,sgid,fsgid;
442
443         int ngroups;
444         gid_t   groups[NGROUPS];
445         cfs_kernel_cap_t   cap_effective,
446                        cap_inheritable,
447                        cap_permitted;
448
449         char comm[CFS_CURPROC_COMM_MAX];
450     void * journal_info;
451 }  cfs_task_t;
452
453
454 /*
455  *  linux task struct emulator ...
456  */
457
458 #define TASKMAN_MAGIC  'TMAN'   /* Task Manager */
459 #define TASKSLT_MAGIC  'TSLT'   /* Task Slot */
460
461 typedef struct _TASK_MAN {
462
463     ULONG       Magic;      /* Magic and Flags */
464     ULONG       Flags;
465
466     spinlock_t  Lock;       /* Protection lock */
467
468     cfs_mem_cache_t * slab; /* Memory slab for task slot */
469
470     ULONG       NumOfTasks; /* Total tasks (threads) */
471     LIST_ENTRY  TaskList;   /* List of task slots */
472
473 } TASK_MAN, *PTASK_MAN;
474
475 typedef struct _TASK_SLOT {
476
477     ULONG       Magic;      /* Magic and Flags */
478     ULONG       Flags;
479
480     LIST_ENTRY  Link;       /* To be linked to TaskMan */
481
482     event_t     Event;      /* Schedule event */
483
484     HANDLE      Pid;        /* Process id */
485     HANDLE      Tid;        /* Thread id */
486     PETHREAD    Tet;        /* Pointer to ethread */
487
488     atomic_t    count;      /* refer count */
489     atomic_t    hits;       /* times of waken event singaled */
490
491     KIRQL       irql;       /* irql for rwlock ... */
492
493     cfs_task_t  task;       /* linux task part */
494
495 } TASK_SLOT, *PTASK_SLOT;
496
497
498 #define current                 cfs_current()
499 #define set_current_state(s)    do {;} while (0)
500
501 #define wait_event(wq, condition)                           \
502 do {                                                        \
503     cfs_waitlink_t __wait;                                      \
504                                                             \
505     cfs_waitlink_init(&__wait);                             \
506         while (TRUE) {                                          \
507                 cfs_waitq_add(&wq, &__wait);                        \
508                 if (condition)  {                                           \
509                         break;                                                  \
510         }                                                   \
511                 cfs_waitq_wait(&__wait, CFS_TASK_INTERRUPTIBLE);        \
512                 cfs_waitq_del(&wq, &__wait);                        \
513         }                                                                           \
514         cfs_waitq_del(&wq, &__wait);                                \
515 } while(0)
516
517 #define wait_event_interruptible(wq, condition, __ret)      \
518 do {                                                        \
519     cfs_waitlink_t __wait;                                      \
520                                                             \
521     __ret = 0;                                              \
522     cfs_waitlink_init(&__wait);                             \
523         while (TRUE) {                                          \
524                 cfs_waitq_add(&wq, &__wait);                        \
525                 if (condition)  {                                           \
526                         break;                                                  \
527         }                                                   \
528                 cfs_waitq_wait(&__wait, CFS_TASK_INTERRUPTIBLE);    \
529                 cfs_waitq_del(&wq, &__wait);                        \
530         }                                                                           \
531         cfs_waitq_del(&wq, &__wait);                                \
532 } while(0)
533
534
535 int     init_task_manager();
536 void    cleanup_task_manager();
537 cfs_task_t * cfs_current();
538 int     schedule_timeout(int64_t time);
539 int     schedule();
540 int     wake_up_process(cfs_task_t * task);
541 #define cfs_schedule_timeout(state, time)  schedule_timeout(time)
542 void sleep_on(cfs_waitq_t *waitq);
543
544 #define CFS_DECL_JOURNAL_DATA   
545 #define CFS_PUSH_JOURNAL            do {;} while(0)
546 #define CFS_POP_JOURNAL             do {;} while(0)
547
548
549 /* module related definitions */
550
551 #ifndef __exit
552 #define __exit
553 #endif
554 #ifndef __init
555 #define __init
556 #endif
557
558 #define request_module(x) (0)
559
560 #define EXPORT_SYMBOL(s)
561 #define MODULE_AUTHOR(s)
562 #define MODULE_DESCRIPTION(s)
563 #define MODULE_LICENSE(s)
564 #define MODULE_PARM(a, b)
565 #define MODULE_PARM_DESC(a, b)
566
567 #define module_init(X) int  __init module_##X() {return X();}
568 #define module_exit(X) void __exit module_##X() {X();}
569
570 #define DECLARE_INIT(X) extern int  __init  module_##X(void)
571 #define DECLARE_EXIT(X) extern void __exit  module_##X(void)
572
573 #define MODULE_INIT(X) do { int rc = module_##X(); \
574                             if (rc) goto errorout; \
575                           } while(0)
576
577 #define MODULE_EXIT(X) do { module_##X(); } while(0)
578
579
580 /* Module interfaces */
581 #define cfs_module(name, version, init, fini) \
582 module_init(init);                            \
583 module_exit(fini)
584
585
586 /*
587  *  Linux kernel version definition
588  */
589
590 #define KERNEL_VERSION(a,b,c) ((a)*100+(b)*10+c)
591 #define LINUX_VERSION_CODE (2*100+6*10+7)
592
593
594 /*
595  * Signal
596  */
597 #define SIGNAL_MASK_ASSERT()
598
599 /*
600  * Timer
601  */
602
603 #define CFS_TIMER_FLAG_INITED   0x00000001  // Initialized already
604 #define CFS_TIMER_FLAG_TIMERED  0x00000002  // KeSetTimer is called
605
606 typedef struct cfs_timer {
607
608     KSPIN_LOCK      Lock;
609
610     ULONG           Flags;
611
612     KDPC            Dpc;
613     KTIMER          Timer;
614
615     cfs_time_t      deadline;
616
617     void (*proc)(ulong_ptr);
618     void *          arg;
619
620 } cfs_timer_t;
621
622
623 typedef  void (*timer_func_t)(ulong_ptr);
624
625 #define cfs_init_timer(t)
626
627 void cfs_timer_init(cfs_timer_t *timer, void (*func)(ulong_ptr), void *arg);
628 void cfs_timer_done(cfs_timer_t *t);
629 void cfs_timer_arm(cfs_timer_t *t, cfs_time_t deadline);
630 void cfs_timer_disarm(cfs_timer_t *t);
631 int  cfs_timer_is_armed(cfs_timer_t *t);
632 cfs_time_t cfs_timer_deadline(cfs_timer_t *t);
633
634
635 /* deschedule for a bit... */
636 static inline void cfs_pause(cfs_duration_t ticks)
637 {
638     cfs_schedule_timeout(TASK_UNINTERRUPTIBLE, ticks);
639 }
640
641
642 static inline void cfs_enter_debugger(void)
643 {
644 #if _X86_
645     __asm int 3;
646 #else
647     KdBreakPoint();
648 #endif
649 }
650
651 /*
652  *  libcfs globals initialization/cleanup
653  */
654
655 int
656 libcfs_arch_init(void);
657
658 void
659 libcfs_arch_cleanup(void);
660
661 /*
662  * SMP ...
663  */
664
665 #define SMP_CACHE_BYTES             128
666 #define __cacheline_aligned
667 #define NR_CPUS                                     (2)
668 #define smp_processor_id()                  KeGetCurrentProcessorNumber()
669 #define smp_num_cpus                NR_CPUS
670 #define num_online_cpus() smp_num_cpus
671 #define smp_call_function(f, a, n, w)           do {} while(0)
672
673 /*
674  *  Irp related
675  */
676
677 #define NR_IRQS                             512
678 #define in_interrupt()                  (0)
679
680 /*
681  *  printk flags
682  */
683
684 #define KERN_EMERG      "<0>"   /* system is unusable                   */
685 #define KERN_ALERT      "<1>"   /* action must be taken immediately     */
686 #define KERN_CRIT       "<2>"   /* critical conditions                  */
687 #define KERN_ERR        "<3>"   /* error conditions                     */
688 #define KERN_WARNING    "<4>"   /* warning conditions                   */
689 #define KERN_NOTICE     "<5>"   /* normal but significant condition     */
690 #define KERN_INFO       "<6>"   /* informational                        */
691 #define KERN_DEBUG      "<7>"   /* debug-level messages                 */
692
693 /*
694  * Misc
695  */
696
697
698 #define inter_module_get(n)                     cfs_symbol_get(n)
699 #define inter_module_put(n)                     cfs_symbol_put(n)
700
701 #ifndef likely
702 #define likely(exp) (exp)
703 #endif
704 #ifndef unlikely
705 #define unlikely(exp) (exp)
706 #endif
707
708 #define lock_kernel()               do {} while(0)
709 #define unlock_kernel()             do {} while(0)
710
711 #define USERMODEHELPER(path, argv, envp)        (0)
712
713
714 #define local_irq_save(x)
715 #define local_irq_restore(x)
716
717 #define cfs_assert                      ASSERT
718
719 #define THREAD_NAME
720
721 #else   /* !__KERNEL__ */
722
723 #define PAGE_CACHE_SIZE PAGE_SIZE
724 #define PAGE_CACHE_MASK PAGE_MASK
725
726 #define getpagesize()   (PAGE_SIZE)
727
728
729 typedef struct {
730     int foo;
731 } pthread_mutex_t;
732
733 typedef struct {
734     int foo;
735 } pthread_cond_t;
736
737 #define pthread_mutex_init(x, y)    do {} while(0)
738 #define pthread_cond_init(x, y)     do {} while(0)
739
740 #define pthread_mutex_lock(x)       do {} while(0)
741 #define pthread_mutex_unlock(x)     do {} while(0)
742
743 #define pthread_cond_wait(x,y)      do {} while(0)
744 #define pthread_cond_broadcast(x)   do {} while(0)
745
746 typedef struct file {
747     int foo;
748 } cfs_file_t;
749
750 typedef struct cfs_proc_dir_entry{
751         void            *data;
752 }cfs_proc_dir_entry_t;
753
754
755
756 #include "../user-prim.h"
757
758 #include <sys/stat.h>
759 #include <sys/types.h>
760
761 #define strcasecmp  strcmp
762 #define strncasecmp strncmp
763 #define snprintf   _snprintf
764 #define getpid()   (0)
765
766
767 #define getpwuid(x) (NULL)
768 #define getgrgid(x) (NULL)
769
770 int cfs_proc_mknod(const char *path, mode_t mode, dev_t dev);
771
772 int gethostname(char * name, int namelen);
773
774 #define setlinebuf(x) do {} while(0)
775
776
777 NTSYSAPI VOID NTAPI DebugBreak();
778
779
780 static inline void cfs_enter_debugger(void)
781 {
782 #if _X86_
783     __asm int 3;
784 #else
785     DebugBreak();
786 #endif
787 }
788
789 /* Maximum EA Information Length */
790 #define EA_MAX_LENGTH  (sizeof(FILE_FULL_EA_INFORMATION) + 15)
791
792
793 /*
794  *  proc user mode routines
795  */
796
797 HANDLE cfs_proc_open (char * filename, int oflag);
798 int cfs_proc_close(HANDLE handle);
799 int cfs_proc_read(HANDLE handle, void *buffer, unsigned int count);
800 int cfs_proc_write(HANDLE handle, void *buffer, unsigned int count);
801 int cfs_proc_ioctl(HANDLE handle, int cmd, void *buffer);
802
803
804 /*
805  * Native API definitions
806  */
807
808 //
809 //  Disk I/O Routines
810 //
811
812 NTSYSAPI
813 NTSTATUS
814 NTAPI
815 NtReadFile(HANDLE FileHandle,
816     HANDLE Event OPTIONAL,
817     PIO_APC_ROUTINE ApcRoutine OPTIONAL,
818     PVOID ApcContext OPTIONAL,
819     PIO_STATUS_BLOCK IoStatusBlock,
820     PVOID Buffer,
821     ULONG Length,
822     PLARGE_INTEGER ByteOffset OPTIONAL,
823     PULONG Key OPTIONAL);
824
825 NTSYSAPI
826 NTSTATUS
827 NTAPI
828 NtWriteFile(HANDLE FileHandle,
829     HANDLE Event OPTIONAL,
830     PIO_APC_ROUTINE ApcRoutine OPTIONAL,
831     PVOID ApcContext OPTIONAL,
832     PIO_STATUS_BLOCK IoStatusBlock,
833     PVOID Buffer,
834     ULONG Length,
835     PLARGE_INTEGER ByteOffset OPTIONAL,
836     PULONG Key OPTIONAL);
837
838 NTSYSAPI
839 NTSTATUS
840 NTAPI
841 NtClose(HANDLE Handle);
842
843 NTSYSAPI
844 NTSTATUS
845 NTAPI
846 NtCreateFile(PHANDLE FileHandle,
847     ACCESS_MASK DesiredAccess,
848     POBJECT_ATTRIBUTES ObjectAttributes,
849     PIO_STATUS_BLOCK IoStatusBlock,
850     PLARGE_INTEGER AllocationSize OPTIONAL,
851     ULONG FileAttributes,
852     ULONG ShareAccess,
853     ULONG CreateDisposition,
854     ULONG CreateOptions,
855     PVOID EaBuffer OPTIONAL,
856     ULONG EaLength);
857
858
859 NTSYSAPI
860 NTSTATUS
861 NTAPI
862 NtDeviceIoControlFile(
863     IN HANDLE  FileHandle,
864     IN HANDLE  Event,
865     IN PIO_APC_ROUTINE  ApcRoutine,
866     IN PVOID  ApcContext,
867     OUT PIO_STATUS_BLOCK  IoStatusBlock,
868     IN ULONG  IoControlCode,
869     IN PVOID  InputBuffer,
870     IN ULONG  InputBufferLength,
871     OUT PVOID  OutputBuffer,
872     OUT ULONG  OutputBufferLength
873     ); 
874
875 NTSYSAPI
876 NTSTATUS
877 NTAPI
878 NtFsControlFile(
879     IN HANDLE FileHandle,
880     IN HANDLE Event OPTIONAL,
881     IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
882     IN PVOID ApcContext OPTIONAL,
883     OUT PIO_STATUS_BLOCK IoStatusBlock,
884     IN ULONG FsControlCode,
885     IN PVOID InputBuffer OPTIONAL,
886     IN ULONG InputBufferLength,
887     OUT PVOID OutputBuffer OPTIONAL,
888     IN ULONG OutputBufferLength
889 );
890
891
892 NTSYSAPI
893 NTSTATUS
894 NTAPI
895 NtQueryInformationFile(
896     IN HANDLE  FileHandle,
897     OUT PIO_STATUS_BLOCK  IoStatusBlock,
898     OUT PVOID  FileInformation,
899     IN ULONG  Length,
900     IN FILE_INFORMATION_CLASS  FileInformationClass
901     );
902
903 //
904 // Random routines ...
905 //
906
907 NTSYSAPI
908 ULONG
909 NTAPI
910 RtlRandom(
911     IN OUT PULONG  Seed
912     ); 
913
914 #endif /* __KERNEL__ */
915
916
917 //
918 // Inode flags (Linux uses octad number, but why ? strange!!!)
919 //
920
921 #undef S_IFMT
922 #undef S_IFDIR
923 #undef S_IFCHR
924 #undef S_IFREG
925 #undef S_IREAD
926 #undef S_IWRITE
927 #undef S_IEXEC
928
929 #define S_IFMT   0x0F000            /* 017 0000 */
930 #define S_IFSOCK 0x0C000            /* 014 0000 */
931 #define S_IFLNK  0x0A000            /* 012 0000 */
932 #define S_IFREG  0x08000            /* 010 0000 */
933 #define S_IFBLK  0x06000            /* 006 0000 */
934 #define S_IFDIR  0x04000            /* 004 0000 */
935 #define S_IFCHR  0x02000            /* 002 0000 */
936 #define S_IFIFO  0x01000            /* 001 0000 */
937 #define S_ISUID  0x00800            /* 000 4000 */
938 #define S_ISGID  0x00400            /* 000 2000 */
939 #define S_ISVTX  0x00200            /* 000 1000 */
940
941 #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
942 #define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)
943 #define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
944 #define S_ISFIL(m)      (((m) & S_IFMT) == S_IFFIL)
945 #define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
946 #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
947 #define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
948 #define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
949
950 #define S_IPERMISSION_MASK 0x1FF /*  */
951
952 #define S_IRWXU  0x1C0              /* 0 0700 */
953 #define S_IRUSR  0x100              /* 0 0400 */
954 #define S_IWUSR  0x080              /* 0 0200 */
955 #define S_IXUSR  0x040              /* 0 0100 */
956
957 #define S_IRWXG  0x038              /* 0 0070 */
958 #define S_IRGRP  0x020              /* 0 0040 */
959 #define S_IWGRP  0x010              /* 0 0020 */
960 #define S_IXGRP  0x008              /* 0 0010 */
961
962 #define S_IRWXO  0x007              /* 0 0007 */
963 #define S_IROTH  0x004              /* 0 0004 */
964 #define S_IWOTH  0x002              /* 0 0002 */
965 #define S_IXOTH  0x001              /* 0 0001 */
966
967 #define S_IRWXUGO   (S_IRWXU|S_IRWXG|S_IRWXO)
968 #define S_IALLUGO   (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
969 #define S_IRUGO     (S_IRUSR|S_IRGRP|S_IROTH)
970 #define S_IWUGO     (S_IWUSR|S_IWGRP|S_IWOTH)
971 #define S_IXUGO     (S_IXUSR|S_IXGRP|S_IXOTH)
972
973 /*
974  *  linux ioctl coding definitions
975  */
976  
977 #define _IOC_NRBITS 8
978 #define _IOC_TYPEBITS   8
979 #define _IOC_SIZEBITS   14
980 #define _IOC_DIRBITS    2
981
982 #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
983 #define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)
984 #define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)
985 #define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)
986
987 #define _IOC_NRSHIFT    0
988 #define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
989 #define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
990 #define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)
991
992 /*
993  * Direction bits.
994  */
995 #define _IOC_NONE   0U
996 #define _IOC_WRITE  1U
997 #define _IOC_READ   2U
998
999 #define _IOC(dir,type,nr,size) \
1000     (((dir)  << _IOC_DIRSHIFT) | \
1001      ((type) << _IOC_TYPESHIFT) | \
1002      ((nr)   << _IOC_NRSHIFT) | \
1003      ((size) << _IOC_SIZESHIFT))
1004
1005 /* used to create numbers */
1006 #define _IO(type,nr)      _IOC(_IOC_NONE,(type),(nr),0)
1007 #define _IOR(type,nr,size)    _IOC(_IOC_READ,(type),(nr),sizeof(size))
1008 #define _IOW(type,nr,size)    _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
1009 #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
1010
1011 /* used to decode ioctl numbers.. */
1012 #define _IOC_DIR(nr)        (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
1013 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
1014 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
1015 #define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
1016
1017 /*
1018  * Io vector ...  
1019  */
1020
1021 struct iovec
1022 {
1023     void *iov_base;
1024     size_t iov_len;
1025 };
1026
1027
1028 #define ULONG_LONG_MAX ((__u64)(0xFFFFFFFFFFFFFFFF))
1029 /*
1030  * Convert a string to an unsigned long long integer.
1031  *
1032  * Ignores `locale' stuff.  Assumes that the upper and lower case
1033  * alphabets and digits are each contiguous.
1034  */
1035 static inline __u64
1036 strtoull(
1037         char *nptr,
1038         char **endptr,
1039         int base)
1040 {
1041         char *s = nptr;
1042         __u64 acc, cutoff;
1043         int c, neg = 0, any, cutlim;
1044
1045         /*
1046          * See strtol for comments as to the logic used.
1047          */
1048         do {
1049                 c = *s++;
1050         } while (isspace(c));
1051         if (c == '-') {
1052                 neg = 1;
1053                 c = *s++;
1054         } else if (c == '+')
1055                 c = *s++;
1056         if ((base == 0 || base == 16) &&
1057             c == '0' && (*s == 'x' || *s == 'X')) {
1058                 c = s[1];
1059                 s += 2;
1060                 base = 16;
1061         }
1062         if (base == 0)
1063                 base = c == '0' ? 8 : 10;
1064         cutoff = (__u64)ULONG_LONG_MAX / (__u64)base;
1065         cutlim = (int)((__u64)ULONG_LONG_MAX % (__u64)base);
1066         for (acc = 0, any = 0;; c = *s++) {
1067                 if (isdigit(c))
1068                         c -= '0';
1069                 else if (isalpha(c))
1070                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
1071                 else
1072                         break;
1073                 if (c >= base)
1074                         break;
1075                if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
1076                         any = -1;
1077                 else {
1078                         any = 1;
1079                         acc *= base;
1080                         acc += c;
1081                 }
1082         }
1083         if (any < 0) {
1084                 acc = ULONG_LONG_MAX;
1085         } else if (neg)
1086                 acc = 0 - acc;
1087         if (endptr != 0)
1088                 *endptr = (char *) (any ? s - 1 : nptr);
1089         return (acc);
1090 }
1091
1092 #endif