BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, wStream* 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 */ if (!Stream_EnsureRemainingCapacity(output, 4 + 36)) goto out_fail; Stream_Write_UINT32(output, 36); /* Length */ 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 */ if (!Stream_EnsureRemainingCapacity(output, 4 + 22)) goto out_fail; Stream_Write_UINT32(output, 22); /* Length */ 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_UINT8(output, file->delete_pending ? 1 : 0); /* DeletePending */ Stream_Write_UINT8(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 */ if (!Stream_EnsureRemainingCapacity(output, 4 + 8)) goto out_fail; Stream_Write_UINT32(output, 8); /* Length */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, 0); /* ReparseTag */ break; default: /* Unhandled FsInformationClass */ Stream_Write_UINT32(output, 0); /* Length */ return FALSE; } return TRUE; out_fail: Stream_Write_UINT32(output, 0); /* Length */ return FALSE; }
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; }
boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, uint8 InitialQuery, const char* path, STREAM* output) { struct dirent* ent; char* ent_path; struct stat st; UNICONV* uniconv; size_t len; boolean ret; DEBUG_SVC("path %s FsInformationClass %d", path, FsInformationClass); if (InitialQuery != 0) { rewinddir(file->dir); } ent = readdir(file->dir); if (ent == NULL) { stream_write_uint32(output, 0); /* Length */ stream_write_uint8(output, 0); /* Padding */ return false; } memset(&st, 0, sizeof(struct stat)); ent_path = xmalloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf(ent_path, "%s/%s", file->fullpath, ent->d_name); if (stat(ent_path, &st) != 0) { DEBUG_WARN("stat %s failed.", ent_path); } xfree(ent_path); uniconv = freerdp_uniconv_new(); ent_path = freerdp_uniconv_out(uniconv, ent->d_name, &len); freerdp_uniconv_free(uniconv); ret = true; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ stream_write_uint32(output, 64 + len); /* Length */ stream_check_size(output, 64 + len); 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, len); /* FileNameLength */ stream_write(output, ent_path, len); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ stream_write_uint32(output, 68 + len); /* Length */ stream_check_size(output, 68 + len); 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, len); /* FileNameLength */ stream_write_uint32(output, 0); /* EaSize */ stream_write(output, ent_path, len); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ stream_write_uint32(output, 93 + len); /* Length */ stream_check_size(output, 93 + len); 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, len); /* FileNameLength */ stream_write_uint32(output, 0); /* EaSize */ stream_write_uint8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ stream_write_zero(output, 24); /* ShortName */ stream_write(output, ent_path, len); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ stream_write_uint32(output, 12 + len); /* Length */ stream_check_size(output, 12 + len); stream_write_uint32(output, 0); /* NextEntryOffset */ stream_write_uint32(output, 0); /* FileIndex */ stream_write_uint32(output, len); /* FileNameLength */ stream_write(output, ent_path, len); break; default: stream_write_uint32(output, 0); /* Length */ stream_write_uint8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = false; break; } xfree(ent_path); return ret; }
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, wStream* 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_UINT8(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_UINT8(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_EnsureRemainingCapacity(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_EnsureRemainingCapacity(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_EnsureRemainingCapacity(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_UINT8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ Stream_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_EnsureRemainingCapacity(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_UINT8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = FALSE; break; } free(ent_path); return ret; }
boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, uint8 InitialQuery, const char* path, STREAM* output) { int length; boolean 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_uint8(output, 0); /* Padding */ return false; } if (InitialQuery != 0) { rewinddir(file->dir); xfree(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 (disk_file_wildcard_match(file->pattern, ent->d_name)) 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_uint8(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); xfree(ent_path); length = freerdp_AsciiToUnicodeAlloc(ent->d_name, &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_uint8(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_uint8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = false; break; } xfree(ent_path); return ret; }