Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions src/dislocker.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,33 +127,36 @@ int dis_initialize(dis_context_t dis_ctx)


/* Open the volume as a (big) normal file */
dis_printf(L_DEBUG, "Trying to open '%s'...\n", dis_ctx->cfg.volume_path);
dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDWR|O_LARGEFILE);
if(dis_ctx->fve_fd < 0)

if(dis_is_read_only(dis_ctx) != 0)
{
/* Trying to open it in read-only if O_RDWR doesn't work */
dis_ctx->fve_fd = dis_open(
dis_ctx->cfg.volume_path,
O_RDONLY|O_LARGEFILE
);
dis_printf(L_DEBUG, "Trying to open RO '%s'...\n", dis_ctx->cfg.volume_path);
dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDONLY|O_LARGEFILE);
}
else
{
dis_printf(L_DEBUG, "Trying to open RW '%s'...\n", dis_ctx->cfg.volume_path);
dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDWR|O_LARGEFILE);

if(dis_ctx->fve_fd < 0)
{
/* Trying to open it in read-only if O_RDWR doesn't work */
dis_ctx->cfg.flags |= DIS_FLAG_READ_ONLY;
dis_printf(
L_CRITICAL,
"Failed to open %s: %s\n",
dis_ctx->cfg.volume_path, strerror(errno)
L_WARNING,
"Failed to open %s for writing. Falling back to read-only.\n",
dis_ctx->cfg.volume_path
);
dis_destroy(dis_ctx);
return DIS_RET_ERROR_FILE_OPEN;

dis_ctx->fve_fd = dis_open(dis_ctx->cfg.volume_path, O_RDONLY|O_LARGEFILE);
}
}

dis_ctx->cfg.flags |= DIS_FLAG_READ_ONLY;
dis_printf(
L_WARNING,
"Failed to open %s for writing. Falling back to read-only.\n",
dis_ctx->cfg.volume_path
);
if(dis_ctx->fve_fd < 0)
{
dis_printf(L_CRITICAL, "Failed to open %s: %s\n", dis_ctx->cfg.volume_path, strerror(errno));
dis_destroy(dis_ctx);
return DIS_RET_ERROR_FILE_OPEN;
}

dis_printf(L_DEBUG, "Opened (fd #%d).\n", dis_ctx->fve_fd);
Expand Down
13 changes: 13 additions & 0 deletions src/inouts/prepare.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

#include <errno.h>
#include <pthread.h>
#include <sys/mount.h>
#include <sys/ioctl.h>
#include <stdint.h>

#include "dislocker/inouts/prepare.h"
#include "dislocker/inouts/sectors.h"
Expand Down Expand Up @@ -98,6 +101,7 @@ int init_keys(bitlocker_dataset_t* dataset, datum_key_t* fvek_datum,
int prepare_crypt(dis_context_t dis_ctx)
{
dis_iodata_t* io_data;
uint64_t part_volume_size = UINT64_MAX;

if(!dis_ctx)
return DIS_RET_ERROR_DISLOCKER_INVAL;
Expand All @@ -113,6 +117,15 @@ int prepare_crypt(dis_context_t dis_ctx)
io_data->encrypted_volume_size = dis_metadata_volume_size_from_vbr(dis_ctx->metadata);
io_data->encrypted_volume_size += io_data->sector_size; //The volume size of Vista should include the DBR backup
}

// Do not trust the encrypted volume size in metadata. After shrinking the volume, metadata
// is not updated at least by Windows 10 1909
if (ioctl(dis_ctx->fve_fd, BLKGETSIZE64, &part_volume_size) >= 0)
{
if (part_volume_size < io_data->encrypted_volume_size)
io_data->encrypted_volume_size = part_volume_size;
}

io_data->backup_sectors_addr = dis_metadata_ntfs_sectors_address(io_data->metadata);
io_data->nb_backup_sectors = dis_metadata_backup_sectors_count(io_data->metadata);

Expand Down