📄 file.c
字号:
/* * file.c * * Copyright (C) 2006 Insigme Co., Ltd * * Authors: * - Chenzhan Hu * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute, * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). * * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Revision History: * Jan 2006 - Created. */ /* * file.c: file syscall functions * Reference to Kernel-win32 code */#include <linux/module.h>#include "file.h"#include "objwait.h"#include "process.h"#include "thread.h"#include <linux/file.h>#include <linux/smp_lock.h>#include <linux/nls.h>#include <asm/uaccess.h>#ifdef CONFIG_UNIFIED_KERNELstatic int FileConstructor(struct win32_object *, void *);static int FileReconstructor(struct win32_object *, void *);static void FileDestructor(struct win32_object *);static int FilePoll(struct wait_table_entry *, struct ethread *);static int FileCheckSharing(struct file_args *, struct win32_file_ctrl *);struct win32_object_class file_objclass = { oc_type: "FILE ", constructor: FileConstructor, reconstructor: NULL, destructor: FileDestructor, poll: FilePoll, oc_flags: OCF_DONT_NAME_ANON /* names shared from FCTRL class */};static int FileControlConstructor(struct win32_object *, void *);static int FileControlReconstructor(struct win32_object *, void *);static void FileControlDestructor(struct win32_object *);static int FileControlPoll(struct wait_table_entry *, struct ethread *);struct win32_object_class file_control_objclass = { oc_type: "FCTRL", constructor: FileControlConstructor, reconstructor: FileControlReconstructor, destructor: FileControlDestructor, poll: FileControlPoll,};/* * initialise the file object classes */void FileClassInit(void){ InitObjectClass(&file_objclass); InitObjectClass(&file_control_objclass);} /* end FileClassInit() *//* * open a file object, maybe creating if non-existent */NTSTATUSSTDCALLNtCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength ){ HANDLE hFile; struct win32_object *obj; struct ethread *thread; struct file_args fca; OBJECT_ATTRIBUTES obj_attr; UNICODE_STRING obj_name; IO_STATUS_BLOCK io_status; LARGE_INTEGER alloc_size; ktrace("NtCreateFile\n"); thread = thread_find(); if (!thread) return -EINVAL; if (!ObjectAttributes) return -EINVAL; if (!IoStatusBlock) return -EINVAL; //if (thread->tcb.previous_mode == 1 /* USER_MODE */) { if ((unsigned long)ObjectAttributes < TASK_SIZE) { /* FIXME */ if (copy_from_user(&obj_attr, ObjectAttributes, sizeof(obj_attr))) return -EFAULT; if (copy_from_user(&obj_name, obj_attr.ObjectName, sizeof(obj_name))) return -EFAULT; obj_attr.ObjectName = &obj_name; if (copy_from_user(&io_status, IoStatusBlock, sizeof(io_status))) return -EFAULT; if (AllocationSize) { if (copy_from_user(&alloc_size, AllocationSize, sizeof(alloc_size))) return -EFAULT; fca.AllocationSize = &alloc_size; } else fca.AllocationSize = NULL; fca.ObjectAttributes = &obj_attr; fca.IoStatusBlock = &io_status; } else { /* KERNEL_MODE */ fca.ObjectAttributes = ObjectAttributes; fca.IoStatusBlock = IoStatusBlock; fca.AllocationSize = AllocationSize; } fca.DesiredAccess = DesiredAccess; fca.FileAttributes = FileAttributes; fca.ShareAccess = ShareAccess; fca.CreateDisposition = CreateDisposition; fca.CreateOptions = CreateOptions; fca.EaBuffer = EaBuffer; fca.EaLength = EaLength; /* * ...but create the object _without_ a name and attach one later * (need a separate file-access object for each NtCreateFile */ etget(thread); obj = CreateObject(thread, &file_objclass, NULL, &fca, &hFile); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); objput(obj); if(copy_to_user(FileHandle, &hFile, sizeof(HANDLE))) return -EFAULT; else return STATUS_SUCCESS; } /* end NtCreateFile() *//* * open a file object, failing if non-existent * TODO: not implemented, used NtCreateFile instead */NTSTATUSSTDCALLNtOpenFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions ){ return NtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, NULL, 0, ShareAccess, FILE_OPEN, OpenOptions, NULL, 0);} /* end NtOpenFile() *//* * read from a file */NTSTATUSSTDCALLNtReadFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */ IN PULONG Key OPTIONAL ){ struct win32_file *wf; struct file *file; struct win32_object *obj = NULL; loff_t pos; struct ethread *thread; IO_STATUS_BLOCK io_status; NTSTATUS status = -EACCES; ktrace("NtReadFile(%p,%p)\n", thread, FileHandle); thread = thread_find(); if (!thread) goto cleanup_nobj; if (!IoStatusBlock) return -EINVAL; etget(thread); obj = GetObject(thread, FileHandle, &file_objclass); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); wf = obj->o_private; file = wf->wf_file; /* check the file can actually be read */ if (!(wf->wf_access & GENERIC_READ)) goto cleanup; status = -EBADF; if (!(file->f_mode & FMODE_READ)) goto cleanup; /* read from file */ pos = file->f_pos; if ((unsigned long)Buffer < TASK_SIZE) { /* FIXME */ status = vfs_read(file, Buffer, Length, &pos); file->f_pos = pos; } else status = kernel_read(file, pos, Buffer, Length); if (status >= 0) { /* write _ReadBytes_ to user space */ io_status.Information = (ULONG_PTR)status; if ((unsigned long)Buffer < TASK_SIZE) /* FIXME */ status = copy_to_user(IoStatusBlock, &io_status, sizeof(io_status)) ? -EFAULT : STATUS_SUCCESS; }cleanup: objput(obj);cleanup_nobj: ktrace("*** NtReadFile(%p) = %d\n", obj, status); return status;} /* end NtReadFile() *//* * write to a file */NTSTATUSSTDCALLNtWriteFile ( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */ IN PULONG Key OPTIONAL ){ struct file *file; struct win32_file *wf; struct win32_object *obj = NULL; struct ethread *thread; loff_t pos; IO_STATUS_BLOCK io_status; NTSTATUS status = -EACCES; ktrace("NtWriteFile(%p,%p)\n", thread, FileHandle); thread = thread_find(); if (!thread) goto cleanup_nobj; if (!IoStatusBlock) return -EINVAL; etget(thread); obj = GetObject(thread, FileHandle, &file_objclass); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); wf = obj->o_private; file = wf->wf_file; /* check the file can actually be written */ if (!(wf->wf_access & GENERIC_WRITE)) goto cleanup; status = -EBADF; if (!(file->f_mode & FMODE_WRITE)) goto cleanup; /* write to file */ pos = file->f_pos; status = vfs_write(file, Buffer, Length, &pos); file->f_pos = pos; if (status >= 0) { /* copy _WRITEDBYTES_ to user space */ io_status.Information = (ULONG_PTR)status; if(copy_to_user(IoStatusBlock, &io_status, sizeof(io_status))) status = -EFAULT; else status = STATUS_SUCCESS; }cleanup: objput(obj);cleanup_nobj: ktrace("*** NtWriteFile(%p) = %d\n",obj, status); return status;} /* end NtWriteFile() *//* * set a file information */NTSTATUSSTDCALLNtSetInformationFile( HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass ){ struct file *file; struct win32_file *wf; struct win32_object *obj; struct ethread *thread; loff_t (*fn)(struct file *, loff_t, int); loff_t offset; NTSTATUS status = 0; ktrace("*** NtSetInformationFile (%p,%p)\n", thread, FileHandle); thread = thread_find(); if (!thread) return -EINVAL; etget(thread); obj = GetObject(thread, FileHandle,&file_objclass); etput(thread); if (IS_ERR(obj)) return PTR_ERR(obj); wf = obj->o_private; file = wf->wf_file; switch (FileInformationClass) { case FilePositionInformation: { FILE_POSITION_INFORMATION PosInfo; if (Length < sizeof(PosInfo))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -