#include #include #include #include #include #define _IOC_NRBITS 8 #define _IOC_TYPEBITS 8 #define _IOC_SIZEBITS 14 #define _IOC_DIRBITS 2 #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) #define _IOC_NRSHIFT 0 #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) #define _IOC_NONE 0U #define _IOC_WRITE 1U #define _IOC_READ 2U #define _IOC(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) extern unsigned int __invalid_size_argument_for_IOC; #define _IOC_TYPECHECK(t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC) #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) #define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) #define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) #define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) #define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) typedef unsigned short u16; typedef signed int s32; typedef unsigned int u32; typedef long __kernel_off_t; typedef s32 compat_off_t; struct compat_dirent { u32 d_ino; compat_off_t d_off; u16 d_reclen; char d_name[256]; }; struct dirent { long d_ino; __kernel_off_t d_off; unsigned short d_reclen; char d_name[256]; /* We must not include limits.h! */ }; #define O_DIRECTORY 00200000 /* must be a directory */ int main(int argc, char *argv[]) { struct compat_dirent cdire[2]; struct dirent dire[2]; int fd; printf("%zu : %lx, %lx\n", sizeof(struct dirent), (unsigned long) VFAT_IOCTL_READDIR_BOTH, (unsigned long) VFAT_IOCTL_READDIR_SHORT); printf("%zu : %lx, %lx\n", sizeof(struct compat_dirent), (unsigned long) VFAT_IOCTL_READDIR_BOTH32, (unsigned long) VFAT_IOCTL_READDIR_SHORT32); for (argv++; *argv; argv++) { fd = open(*argv, O_DIRECTORY | O_RDONLY); if (fd < 0) { perror(*argv); exit(1); } printf("Calling VFAT_IOCTL_READDIR_BOTH32\n"); if (ioctl(fd, VFAT_IOCTL_READDIR_BOTH32, cdire) < 0) perror("ioctl"); printf("Calling VFAT_IOCTL_READDIR_BOTH\n"); if (ioctl(fd, VFAT_IOCTL_READDIR_BOTH, dire) < 0) perror("ioctl"); close(fd); } return 0; }