📄 file.c
字号:
status = -EINVAL; status = copy_from_user(&PosInfo, FileInformation, sizeof(PosInfo)); /* set the seek function pointer */ fn = default_llseek; if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; lock_kernel(); /* do the seek operation */ offset = fn(file, PosInfo.CurrentByteOffset.LowPart, 0); unlock_kernel(); if (offset < 0) { status = offset; goto cleanup; } status = STATUS_SUCCESS; break; } default: break; }cleanup: objput(obj); ktrace("*** NtSetInformationFile(%p) = %d\n", obj, status); return status;} /* end NtSetInformationFile() *//* * Query File Information */NTSTATUSSTDCALLNtQueryInformationFile( 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); NTSTATUS status = 0; ktrace("NtQueryInformationFile (%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)) status = -EINVAL; /* set the seek function pointer */ fn = default_llseek; if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; lock_kernel(); /* get current file position */ PosInfo.CurrentByteOffset.LowPart = fn(file, 0, 1); unlock_kernel(); if (PosInfo.CurrentByteOffset.LowPart < 0) { status = PosInfo.CurrentByteOffset.LowPart; goto cleanup; } /* copy the information to user space */ if(copy_to_user(FileInformation, &PosInfo, sizeof(PosInfo))) status = -EFAULT; else status = STATUS_SUCCESS; break; } default: break; }cleanup: objput(obj); ktrace("*** NtQueryInformationFile(%p) = %d\n", obj, status); return status;} /* end NtQueryInformationFile() *//* * flush the buffers of a file */NTSTATUSSTDCALLNtFlushBuffersFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock ){ /* TODO */ return -ENOSYS;} /* end NtFlushBuffersFile() *//* * poll is never signalled */static int FilePoll(struct wait_table_entry *wte, struct ethread *thread){ return POLL_NOTSIG;} /* end FilePoll() *//* * check if the desired access is possible without violating the sharing mode * of other opens of the same file * - must call with a lock held on the file control struct */static int FileCheckSharing(struct file_args *args, struct win32_file_ctrl *wfc){ struct list_head *flist; __u32 extant_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; __u32 extant_access = 0; /* scan the file access points */ list_for_each(flist, &wfc->wfc_accessors) { struct win32_file *wf = list_entry(flist, struct win32_file, wf_ctllist); /* build up a picture of current sharing and access modes */ extant_sharing &= wf->wf_sharing; extant_access |= wf->wf_access; } if ((args->DesiredAccess & GENERIC_READ) && !(extant_sharing & FILE_SHARE_READ)) goto sharing_violation; if ((args->DesiredAccess & GENERIC_WRITE) && !(extant_sharing & FILE_SHARE_WRITE)) goto sharing_violation; if ((extant_access & GENERIC_READ) && !(args->ShareAccess & FILE_SHARE_READ)) goto sharing_violation; if ((extant_access & GENERIC_WRITE) && !(args->ShareAccess & FILE_SHARE_WRITE)) goto sharing_violation; return 0;sharing_violation: return -EACCES;} /* end FileCheckSharing() *//* * construct a file access object (allocate its private data) * - called by CreateObject if the file does not already exists * - called with the object class lock held */static int FileConstructor(struct win32_object *obj, void *data){ struct file_args *args = (struct file_args *)data; struct win32_file *wf; struct win32_object *fco; int err, flags, mode; ktrace("FileConstructor(%p)\n", obj); /* construct the file information record */ wf = (struct win32_file *) kmalloc(sizeof(struct win32_file),GFP_KERNEL); if (!wf) return -ENOMEM; obj->o_private = wf; wf->wf_access = args->DesiredAccess; wf->wf_sharing = args->ShareAccess; wf->wf_attrs = args->FileAttributes; /* gain access to the file control object */ fco = AllocObject(&file_control_objclass, (char *)args->ObjectAttributes->ObjectName->Buffer, data); if (IS_ERR(fco)) { err = PTR_ERR(fco); goto cleanup_priv; } wf->wf_control = fco->o_private; spin_lock(&wf->wf_control->wfc_lock); /* file name is stored in file_control_object */ /* make use of the name stored in the file control object */ obj->o_name.name = fco->o_name.name; /* check that we can share access */ err = FileCheckSharing(args,wf->wf_control); if (err < 0) goto cleanup_fco; /* determine Linux file open parameters */ switch (args->CreateDisposition) { case FILE_CREATE: flags = O_CREAT | O_EXCL; break; case FILE_OVERWRITE_IF: flags = O_CREAT | O_TRUNC; break; case FILE_OPEN_IF: flags = O_CREAT; break; case FILE_OVERWRITE: flags = O_TRUNC; break; case FILE_OPEN: flags = 0; break; default: err = -EINVAL; goto cleanup_fco; } switch (args->DesiredAccess & (GENERIC_READ | GENERIC_WRITE)) { case GENERIC_READ: flags |= O_RDONLY; break; case GENERIC_WRITE: flags |= O_WRONLY; break; case GENERIC_READ | GENERIC_WRITE: flags |= O_RDWR; break; default: break; } mode = (args->FileAttributes & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666; /* open the Linux file */ wf->wf_file = filp_open(obj->o_name.name, flags, mode); if (IS_ERR(wf->wf_file)) { err = PTR_ERR(wf->wf_file); goto cleanup_fco; } /* don't permit a directory to be opened */ if (S_ISDIR(wf->wf_file->f_dentry->d_inode->i_mode)) { err = -EACCES; goto cleanup_file; } list_add(&wf->wf_ctllist,&wf->wf_control->wfc_accessors); spin_unlock(&wf->wf_control->wfc_lock); return 0; /* clean up on error */cleanup_file: fput(wf->wf_file);cleanup_fco: obj->o_name.name = NULL; spin_unlock(&wf->wf_control->wfc_lock); objput(wf->wf_control->wfc_myself);cleanup_priv: kfree(wf); return err;} /* end FileConstructor() *//* * reconstruct a file (allocate its private data) * - called by CreateObject if the file already exists * - called without the object class lock held */static int FileReconstructor(struct win32_object *obj, void *data){ /* TODO */ ktrace("FileReconstructor(%p)\n",obj); return 0;} /* end FileReconstructor() *//* * destroy a file (discard its private data) */static void FileDestructor(struct win32_object *obj){ struct win32_file *wf = obj->o_private; ktrace("FileDestructor(%p)\n", obj); /* discard my association with the Linux file */ fput(wf->wf_file); if (wf->wf_control) { /* unlink from the controlling object */ list_del(&wf->wf_ctllist); obj->o_name.name = NULL; objput(wf->wf_control->wfc_myself); } kfree(obj->o_private);} /* end FileDestructor *//* * construct a file control object (allocate its private data) * - called by AllocObject if the file does not already exists * - called with the object class lock held */static int FileControlConstructor(struct win32_object *obj, void *data){ struct win32_file_ctrl *wfc; ktrace("FileControlConstructor(%p)\n",obj); /* construct the file information record */ wfc = (struct win32_file_ctrl *) kmalloc(sizeof(struct win32_file_ctrl), GFP_KERNEL); if (!wfc) return -ENOMEM; obj->o_private = wfc; INIT_LIST_HEAD(&wfc->wfc_accessors); spin_lock_init(&wfc->wfc_lock); wfc->wfc_myself = obj; return 0;} /* end FileControlConstructor()*//* * reconstruct a file (allocate its private data) * - called by AllocObject if the file already exists * - called without the object class lock held */static int FileControlReconstructor(struct win32_object *obj, void *data){ /* TODO */ ktrace("FileControlReconstructor(%p)\n",obj); return 0;} /* end FileControlReconstructor() *//* * destroy a file control (discard its private data) */static void FileControlDestructor(struct win32_object *obj){ /* TODO */ ktrace("FileControlDestructor(%p)\n",obj);} /* end FileControlDestructor()*//* * FileControl is never signalled */static int FileControlPoll(struct wait_table_entry *wte, struct ethread *thread){ return POLL_NOTSIG;} /* end FileControlPoll()*/#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -