📄 fileio.c
字号:
memcpy(dirname, fullname, len); dirname[len] = 0; filename = &fullname[len]; rc = co_winnt_utf8_to_unicode(dirname, &dirname_unicode); if (!CO_OK(rc)) goto error_0; rc = co_winnt_utf8_to_unicode(filename, &filename_unicode); if (!CO_OK(rc)) goto error_1; InitializeObjectAttributes(&attributes, &dirname_unicode, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwCreateFile(&handle, FILE_LIST_DIRECTORY, &attributes, &io_status, NULL, 0, FILE_SHARE_DIRECTORY, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(status)) { co_debug_lvl(filesystem, 5, "error %x ZwCreateFile('%s')", (int)status, dirname); rc = status_convert(status); goto error_2; } status = ZwQueryDirectoryFile(handle, NULL, NULL, 0, &io_status, &entry_buffer, sizeof(entry_buffer), FileFullDirectoryInformation, PTRUE, &filename_unicode, PTRUE); if (!NT_SUCCESS(status)) { if (status == STATUS_UNMAPPABLE_CHARACTER) { status = ZwQueryDirectoryFile(handle, NULL, NULL, 0, &io_status, &entry_buffer, sizeof(entry_buffer), FileBothDirectoryInformation, PTRUE, &filename_unicode, PTRUE); if (!NT_SUCCESS(status)) { co_debug_lvl(filesystem, 5, "error %x ZwQueryDirectoryFile('%s')", (int)status, filename); rc = status_convert(status); goto error_3; } else { LastAccessTime = entry_buffer.entry2.LastAccessTime; LastWriteTime = entry_buffer.entry2.LastWriteTime; ChangeTime = entry_buffer.entry2.ChangeTime; EndOfFile = entry_buffer.entry2.EndOfFile; FileAttributes = entry_buffer.entry2.FileAttributes; } } else { co_debug_lvl(filesystem, 5, "error %x ZwQueryDirectoryFile('%s')", (int)status, filename); rc = status_convert(status); goto error_3; } } else { LastAccessTime = entry_buffer.entry.LastAccessTime; LastWriteTime = entry_buffer.entry.LastWriteTime; ChangeTime = entry_buffer.entry.ChangeTime; EndOfFile = entry_buffer.entry.EndOfFile; FileAttributes = entry_buffer.entry.FileAttributes; } attr->uid = 0; attr->gid = 0; attr->rdev = 0; attr->_dummy = 0; attr->atime = windows_time_to_unix_time(LastAccessTime); attr->mtime = windows_time_to_unix_time(LastWriteTime); attr->ctime = windows_time_to_unix_time(ChangeTime); attr->mode = FUSE_S_IRWXU | FUSE_S_IRGRP | FUSE_S_IROTH; /* Hack: WinNT detects "C:\" not as directory! */ if ((FileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (len1 >= 3 && len == len1 && fullname [len1-1] == '\\')) attr->mode |= FUSE_S_IFDIR; else attr->mode |= FUSE_S_IFREG; attr->nlink = 1; attr->size = EndOfFile.QuadPart; attr->blocks = (EndOfFile.QuadPart + ((1<<10)-1)) >> 10; rc = CO_RC(OK);error_3: ZwClose(handle);error_2: co_winnt_free_unicode(&filename_unicode);error_1: co_winnt_free_unicode(&dirname_unicode);error_0: co_os_free(dirname); return rc;}static void remove_read_only_func(void *data, VOID *buffer, ULONG len){ FILE_BASIC_INFORMATION *fbi = (FILE_BASIC_INFORMATION *)buffer; fbi->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;}co_rc_t co_os_file_unlink(char *filename){ OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING unipath; NTSTATUS status; bool_t tried_read_only_removal = PFALSE; co_rc_t rc; rc = co_winnt_utf8_to_unicode(filename, &unipath); if (!CO_OK(rc)) return rc; InitializeObjectAttributes(&ObjectAttributes, &unipath, OBJ_CASE_INSENSITIVE, NULL, NULL);retry: status = ZwDeleteFile(&ObjectAttributes); if (status != STATUS_SUCCESS) { if (!tried_read_only_removal) { FILE_BASIC_INFORMATION fbi; IO_STATUS_BLOCK io_status; co_rc_t rc; rc = co_os_change_file_information(filename, &io_status, &fbi, sizeof(fbi), FileBasicInformation, remove_read_only_func, NULL); tried_read_only_removal = PTRUE; if (CO_RC(OK)) goto retry; } co_debug_lvl(filesystem, 5, "error %x ZwDeleteFile('%s')", (int)status, filename); } co_winnt_free_unicode(&unipath); return status_convert(status);}co_rc_t co_os_file_rmdir(char *filename){ return co_os_file_unlink(filename);}co_rc_t co_os_file_mkdir(char *dirname){ HANDLE handle; co_rc_t rc; rc = co_os_file_create(dirname, &handle, FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, FILE_ATTRIBUTE_DIRECTORY, FILE_CREATE, FILE_DIRECTORY_FILE); if (CO_OK(rc)) { co_os_file_close(handle); } return rc;}co_rc_t co_os_file_rename(char *filename, char *dest_filename){ NTSTATUS status; IO_STATUS_BLOCK io_status; FILE_RENAME_INFORMATION *rename_info; HANDLE handle; int block_size; int char_count; co_rc_t rc; char_count = co_utf8_mbstrlen(dest_filename); block_size = (char_count + 1)*sizeof(WCHAR) + sizeof(FILE_RENAME_INFORMATION); rename_info = co_os_malloc(block_size); if (!rename_info) return CO_RC(OUT_OF_MEMORY); rc = co_os_file_open(filename, &handle, FILE_READ_DATA | FILE_WRITE_DATA); if (!CO_OK(rc)) goto error; rename_info->ReplaceIfExists = TRUE; rename_info->RootDirectory = NULL; rename_info->FileNameLength = char_count * sizeof(WCHAR); rc = co_utf8_mbstowcs(rename_info->FileName, dest_filename, char_count + 1); if (!CO_OK(rc)) goto error2; co_debug_lvl(filesystem, 10, "rename of '%s' to '%s'", filename, dest_filename); status = ZwSetInformationFile(handle, &io_status, rename_info, block_size, FileRenameInformation); rc = status_convert(status); if (!CO_OK(rc)) co_debug_lvl(filesystem, 5, "error %x ZwSetInformationFile rename %s,%s", (int)status, filename, dest_filename);error2: co_os_file_close(handle);error: co_os_free(rename_info); return rc;}co_rc_t co_os_file_mknod(char *filename){ co_rc_t rc; HANDLE handle; rc = co_os_file_create(filename, &handle, FILE_READ_DATA | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL, FILE_CREATE, 0); if (CO_OK(rc)) { co_os_file_close(handle); } return rc;}co_rc_t co_os_file_getdir(char *dirname, co_filesystem_dir_names_t *names){ UNICODE_STRING dirname_unicode; OBJECT_ATTRIBUTES attributes; NTSTATUS status; HANDLE handle; FILE_DIRECTORY_INFORMATION *dir_entries_buffer, *entry; unsigned long dir_entries_buffer_size = 0x1000; IO_STATUS_BLOCK io_status; BOOLEAN first_iteration = TRUE; co_filesystem_name_t *new_name; co_rc_t rc; co_list_init(&names->list); co_debug_lvl(filesystem, 10, "listing of '%s'", dirname); rc = co_winnt_utf8_to_unicode(dirname, &dirname_unicode); if (!CO_OK(rc)) return rc; InitializeObjectAttributes(&attributes, &dirname_unicode, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwCreateFile(&handle, FILE_LIST_DIRECTORY, &attributes, &io_status, NULL, 0, FILE_SHARE_DIRECTORY, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(status)) { co_debug_lvl(filesystem, 5, "error %x ZwCreateFile('%s')", (int)status, dirname); rc = status_convert(status); goto error; } dir_entries_buffer = co_os_malloc(dir_entries_buffer_size); if (!dir_entries_buffer) { rc = CO_RC(OUT_OF_MEMORY); goto error_1; } for (;;) { status = ZwQueryDirectoryFile(handle, NULL, NULL, 0, &io_status, dir_entries_buffer, dir_entries_buffer_size, FileDirectoryInformation, FALSE, NULL, first_iteration); if (!NT_SUCCESS(status)) break; entry = dir_entries_buffer; for (;;) { int filename_utf8_length; filename_utf8_length = co_utf8_wctowbstrlen(entry->FileName, entry->FileNameLength/sizeof(WCHAR)); new_name = co_os_malloc(filename_utf8_length + sizeof(co_filesystem_name_t) + 2); if (!new_name) { rc = CO_RC(OUT_OF_MEMORY); goto error_2; } if (entry->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) new_name->type = FUSE_DT_DIR; else new_name->type = FUSE_DT_REG; rc = co_utf8_wcstombs(new_name->name, entry->FileName, filename_utf8_length + 1); if (!CO_OK(rc)) { co_os_free(new_name); goto error_2; } co_list_add_tail(&new_name->node, &names->list); if (entry->NextEntryOffset == 0) break; entry = (FILE_DIRECTORY_INFORMATION *)(((char *)entry) + entry->NextEntryOffset); } first_iteration = FALSE; } rc = CO_RC(OK);error_2: if (!CO_OK(rc)) co_filesystem_getdir_free(names); co_os_free(dir_entries_buffer);error_1: ZwClose(handle);error: co_winnt_free_unicode(&dirname_unicode); return rc;}co_rc_t co_os_file_fs_stat(co_filesystem_t *filesystem, struct fuse_statfs_out *statfs){ FILE_FS_FULL_SIZE_INFORMATION fsi; HANDLE handle; NTSTATUS status; IO_STATUS_BLOCK io_status; co_pathname_t pathname; co_rc_t rc; int len; int loop = 2; memcpy(&pathname, &filesystem->base_path, sizeof(co_pathname_t)); co_os_fs_add_last_component(&pathname); len = strlen(pathname); do { rc = co_os_file_create(pathname, &handle, FILE_LIST_DIRECTORY, 0, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_OPEN_FOR_FREE_SPACE_QUERY); if (CO_OK(rc)) break; while (len > 0 && pathname[len-1] != '\\') len--; pathname[len] = '\0'; } while (len > 0 && --loop); if (!CO_OK(rc)) return rc; status = ZwQueryVolumeInformationFile(handle, &io_status, &fsi, sizeof(fsi), FileFsFullSizeInformation); if (NT_SUCCESS(status)) { statfs->st.block_size = fsi.SectorsPerAllocationUnit * fsi.BytesPerSector; statfs->st.blocks = fsi.TotalAllocationUnits.QuadPart; statfs->st.blocks_free = fsi.CallerAvailableAllocationUnits.QuadPart; statfs->st.files = 0; statfs->st.files_free = 0; statfs->st.namelen = sizeof(co_pathname_t); } rc = status_convert(status); co_os_file_close(handle); return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -