Пример #1
0
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;
}
Пример #2
0
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, &currentFilePointer, 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, &currentFilePointer, 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;
}