BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, STREAM* output) { struct STAT st; if (STAT(file->fullpath, &st) != 0) { stream_write_UINT32(output, 0); /* Length */ return FALSE; } switch (FsInformationClass) { case FileBasicInformation: /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ stream_write_UINT32(output, 36); /* Length */ stream_check_size(output, 36); stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ /* Reserved(4), MUST NOT be added! */ break; case FileStandardInformation: /* http://msdn.microsoft.com/en-us/library/cc232088.aspx */ stream_write_UINT32(output, 22); /* Length */ stream_check_size(output, 22); stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT32(output, st.st_nlink); /* NumberOfLinks */ stream_write_BYTE(output, file->delete_pending ? 1 : 0); /* DeletePending */ stream_write_BYTE(output, file->is_dir ? 1 : 0); /* Directory */ /* Reserved(2), MUST NOT be added! */ break; case FileAttributeTagInformation: /* http://msdn.microsoft.com/en-us/library/cc232093.aspx */ stream_write_UINT32(output, 8); /* Length */ stream_check_size(output, 8); stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, 0); /* ReparseTag */ break; default: stream_write_UINT32(output, 0); /* Length */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); return FALSE; } return TRUE; }
static void drive_process_irp_query_volume_information(DRIVE_DEVICE* disk, IRP* irp) { UINT32 FsInformationClass; STREAM* output = irp->output; struct STATVFS svfst; struct STAT st; char* volumeLabel = {"FREERDP"}; char* diskType = {"FAT32"}; WCHAR* outStr = NULL; int length; stream_read_UINT32(irp->input, FsInformationClass); STATVFS(disk->path, &svfst); STAT(disk->path, &st); switch (FsInformationClass) { case FileFsVolumeInformation: /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ length = ConvertToUnicode(CP_UTF8, 0, volumeLabel, -1, &outStr, 0) * 2; stream_write_UINT32(output, 17 + length); /* Length */ stream_check_size(output, 17 + length); stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */ stream_write_UINT32(output, svfst.f_fsid); /* VolumeSerialNumber */ stream_write_UINT32(output, length); /* VolumeLabelLength */ stream_write_BYTE(output, 0); /* SupportsObjects */ /* Reserved(1), MUST NOT be added! */ stream_write(output, outStr, length); /* VolumeLabel (Unicode) */ free(outStr); break; case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ stream_write_UINT32(output, 24); /* Length */ stream_check_size(output, 24); stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ stream_write_UINT64(output, svfst.f_bavail); /* AvailableAllocationUnits */ stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsAttributeInformation: /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ length = ConvertToUnicode(CP_UTF8, 0, diskType, -1, &outStr, 0) * 2; stream_write_UINT32(output, 12 + length); /* Length */ stream_check_size(output, 12 + length); stream_write_UINT32(output, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ stream_write_UINT32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */ stream_write_UINT32(output, length); /* FileSystemNameLength */ stream_write(output, outStr, length); /* FileSystemName (Unicode) */ free(outStr); break; case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ stream_write_UINT32(output, 32); /* Length */ stream_check_size(output, 32); stream_write_UINT64(output, svfst.f_blocks); /* TotalAllocationUnits */ stream_write_UINT64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */ stream_write_UINT64(output, svfst.f_bfree); /* AvailableAllocationUnits */ stream_write_UINT32(output, 1); /* SectorsPerAllocationUnit */ stream_write_UINT32(output, svfst.f_bsize); /* BytesPerSector */ break; case FileFsDeviceInformation: /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ stream_write_UINT32(output, 8); /* Length */ stream_check_size(output, 8); stream_write_UINT32(output, FILE_DEVICE_DISK); /* DeviceType */ stream_write_UINT32(output, 0); /* Characteristics */ break; default: irp->IoStatus = STATUS_UNSUCCESSFUL; stream_write_UINT32(output, 0); /* Length */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); break; } irp->Complete(irp); }
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, STREAM* output) { int length; BOOL ret; WCHAR* ent_path; struct STAT st; struct dirent* ent; DEBUG_SVC("path %s FsInformationClass %d InitialQuery %d", path, FsInformationClass, InitialQuery); if (!file->dir) { stream_write_UINT32(output, 0); /* Length */ stream_write_BYTE(output, 0); /* Padding */ return FALSE; } if (InitialQuery != 0) { rewinddir(file->dir); free(file->pattern); if (path[0]) file->pattern = _strdup(strrchr(path, '\\') + 1); else file->pattern = NULL; } if (file->pattern) { do { ent = readdir(file->dir); if (ent == NULL) continue; if (FilePatternMatchA(ent->d_name, file->pattern)) break; } while (ent); } else { ent = readdir(file->dir); } if (ent == NULL) { DEBUG_SVC(" pattern %s not found.", file->pattern); stream_write_UINT32(output, 0); /* Length */ stream_write_BYTE(output, 0); /* Padding */ return FALSE; } memset(&st, 0, sizeof(struct STAT)); ent_path = (WCHAR*) malloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf((char*) ent_path, "%s/%s", file->fullpath, ent->d_name); if (STAT((char*) ent_path, &st) != 0) { DEBUG_WARN("stat %s failed. errno = %d", (char*) ent_path, errno); } DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path); free(ent_path); ent_path = NULL; length = ConvertToUnicode(CP_UTF8, 0, ent->d_name, -1, &ent_path, 0) * 2; ret = TRUE; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ stream_write_UINT32(output, 64 + length); /* Length */ stream_check_size(output, 64 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write(output, ent_path, length); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ stream_write_UINT32(output, 68 + length); /* Length */ stream_check_size(output, 68 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write_UINT32(output, 0); /* EaSize */ stream_write(output, ent_path, length); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ stream_write_UINT32(output, 93 + length); /* Length */ stream_check_size(output, 93 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_UINT64(output, st.st_size); /* EndOfFile */ stream_write_UINT64(output, st.st_size); /* AllocationSize */ stream_write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write_UINT32(output, 0); /* EaSize */ stream_write_BYTE(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ stream_write_zero(output, 24); /* ShortName */ stream_write(output, ent_path, length); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ stream_write_UINT32(output, 12 + length); /* Length */ stream_check_size(output, 12 + length); stream_write_UINT32(output, 0); /* NextEntryOffset */ stream_write_UINT32(output, 0); /* FileIndex */ stream_write_UINT32(output, length); /* FileNameLength */ stream_write(output, ent_path, length); break; default: stream_write_UINT32(output, 0); /* Length */ stream_write_BYTE(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = FALSE; break; } free(ent_path); return ret; }