static int winfs_stat(struct file *f, struct newstat *buf) { struct winfs_file *winfile = (struct winfs_file *) f; BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle(winfile->handle, &info)) { log_warning("GetFileInformationByHandle() failed.\n"); return -1; /* TODO */ } /* Programs (ld.so) may use st_dev and st_ino to identity files so these must be unique for each file. */ INIT_STRUCT_NEWSTAT_PADDING(buf); buf->st_dev = mkdev(8, 0); // (8, 0): /dev/sda //buf->st_ino = ((uint64_t)info.nFileIndexHigh << 32ULL) + info.nFileIndexLow; /* Hash 64 bit inode to 32 bit to fix legacy applications * We may later add an option for changing this behaviour */ buf->st_ino = info.nFileIndexHigh ^ info.nFileIndexLow; if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) buf->st_mode = 0555; else buf->st_mode = 0755; if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { buf->st_mode |= S_IFDIR; buf->st_size = 0; } else { int r; if ((info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) && (r = winfs_read_symlink(winfile->handle, NULL, 0)) > 0) { buf->st_mode |= S_IFLNK; buf->st_size = r; } else { buf->st_mode |= S_IFREG; buf->st_size = ((uint64_t)info.nFileSizeHigh << 32ULL) + info.nFileSizeLow; } } buf->st_nlink = info.nNumberOfLinks; buf->st_uid = 0; buf->st_gid = 0; buf->st_rdev = 0; buf->st_blksize = PAGE_SIZE; buf->st_blocks = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize; buf->st_atime = filetime_to_unix_sec(&info.ftLastAccessTime); buf->st_atime_nsec = filetime_to_unix_nsec(&info.ftLastAccessTime); buf->st_mtime = filetime_to_unix_sec(&info.ftLastWriteTime); buf->st_mtime_nsec = filetime_to_unix_nsec(&info.ftLastWriteTime); buf->st_ctime = filetime_to_unix_sec(&info.ftCreationTime); buf->st_ctime_nsec = filetime_to_unix_nsec(&info.ftCreationTime); return 0; }
static int stat_gettext(int tag, char *buf) { char *original_buf = buf; /* TODO: Support more than one processors */ LARGE_INTEGER idle_time, kernel_time, user_time; GetSystemTimes((FILETIME *)&idle_time, (FILETIME *)&kernel_time, (FILETIME *)&user_time); uint64_t user = user_time.QuadPart / (TICKS_PER_SECOND / USER_HZ); uint64_t nice = 0; uint64_t system = kernel_time.QuadPart / (TICKS_PER_SECOND / USER_HZ); uint64_t idle = idle_time.QuadPart / (TICKS_PER_SECOND / USER_HZ); system -= idle; /* KernelTime includes IdleTime */ uint64_t iowait = 0; uint64_t irq = 0; uint64_t softirq = 0; uint64_t steal = 0, guest = 0, guest_nice = 0; buf += ksprintf(buf, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice); buf += ksprintf(buf, "intr %llu\n", 0); buf += ksprintf(buf, "swap %llu %llu\n", 0); uint64_t ctxt = 0; buf += ksprintf(buf, "ctxt %llu\n", ctxt); /* Boot time */ SYSTEM_TIMEOFDAY_INFORMATION tod_info; NtQuerySystemInformation(SystemTimeOfDayInformation, &tod_info, sizeof(tod_info), NULL); uint64_t btime = filetime_to_unix_sec((FILETIME *)&tod_info.BootTime); buf += ksprintf(buf, "btime %llu\n", btime); uint64_t processes = 0; buf += ksprintf(buf, "processes %llu\n", processes); int procs_running = 1; buf += ksprintf(buf, "procs_running %d\n", procs_running); int procs_blocked = 0; buf += ksprintf(buf, "procs_blocked %d\n", procs_blocked); return buf - original_buf; }
DEFINE_SYSCALL(time, intptr_t *, c) { log_info("time(%p)", c); if (c && !mm_check_write(c, sizeof(int))) return -L_EFAULT; FILETIME systime; GetSystemTimeAsFileTime(&systime); uint64_t t = filetime_to_unix_sec(&systime); if (c) *c = (intptr_t)t; return t; }
static int winfs_stat(struct file *f, struct newstat *buf) { AcquireSRWLockShared(&f->rw_lock); struct winfs_file *winfile = (struct winfs_file *) f; BY_HANDLE_FILE_INFORMATION info; GetFileInformationByHandle(winfile->handle, &info); /* Programs (ld.so) may use st_dev and st_ino to identity files so these must be unique for each file. */ INIT_STRUCT_NEWSTAT_PADDING(buf); buf->st_dev = mkdev(8, 0); // (8, 0): /dev/sda //buf->st_ino = ((uint64_t)info.nFileIndexHigh << 32ULL) + info.nFileIndexLow; /* Hash 64 bit inode to 32 bit to fix legacy applications * We may later add an option for changing this behaviour */ buf->st_ino = info.nFileIndexHigh ^ info.nFileIndexLow; if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) buf->st_mode = 0555; else buf->st_mode = 0755; if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { buf->st_mode |= S_IFDIR; buf->st_size = 0; } else { buf->st_mode |= S_IFREG; buf->st_size = ((uint64_t)info.nFileSizeHigh << 32ULL) + info.nFileSizeLow; if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { WaitForSingleObject(winfile->fp_mutex, INFINITE); /* Save current file pointer */ LARGE_INTEGER distanceToMove, currentFilePointer; distanceToMove.QuadPart = 0; SetFilePointerEx(winfile->handle, distanceToMove, ¤tFilePointer, FILE_CURRENT); int type = winfs_get_special_file_type(winfile->handle); if (type > 0) { if (type == SPECIAL_FILE_SYMLINK) { buf->st_mode |= S_IFLNK; buf->st_size -= WINFS_SYMLINK_HEADER_LEN; } else if (type == SPECIAL_FILE_SOCKET) { buf->st_mode |= S_IFSOCK; buf->st_size = 0; } } /* Restore current file pointer */ SetFilePointerEx(winfile->handle, currentFilePointer, ¤tFilePointer, FILE_BEGIN); ReleaseMutex(winfile->fp_mutex); } } buf->st_nlink = info.nNumberOfLinks; buf->st_uid = 0; buf->st_gid = 0; buf->st_rdev = 0; buf->st_blksize = PAGE_SIZE; buf->st_blocks = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize; buf->st_atime = filetime_to_unix_sec(&info.ftLastAccessTime); buf->st_atime_nsec = filetime_to_unix_nsec(&info.ftLastAccessTime); buf->st_mtime = filetime_to_unix_sec(&info.ftLastWriteTime); buf->st_mtime_nsec = filetime_to_unix_nsec(&info.ftLastWriteTime); buf->st_ctime = filetime_to_unix_sec(&info.ftCreationTime); buf->st_ctime_nsec = filetime_to_unix_nsec(&info.ftCreationTime); ReleaseSRWLockShared(&f->rw_lock); return 0; }