mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Patch XLS files to mask out variable data
This workaround the Excel behaviour to write the last access time inside the files as they are opened.
This commit is contained in:
parent
4209f0cec3
commit
1da8660498
2 changed files with 64 additions and 0 deletions
|
|
@ -21,6 +21,62 @@
|
|||
#include "support.h"
|
||||
#include "handle.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* xls */
|
||||
|
||||
static unsigned char XLS_MAGIC[8] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 };
|
||||
|
||||
/**
|
||||
* Patch XLS files to clear hidden modification made by Excel.
|
||||
*
|
||||
* Excel modifies .XLS files even when just opening them, restoring
|
||||
* the timestamp to its original value.
|
||||
*
|
||||
* To avoid that this operation invalidates the parity, we here patches
|
||||
* the XLS files, clearing the date/time data usually modified.
|
||||
*
|
||||
* How to prevent Excel from modifying the file on exit?
|
||||
* http://superuser.com/questions/664549/how-to-prevent-excel-from-modifying-the-file-on-exit
|
||||
*/
|
||||
void xls_patch(unsigned char* data, unsigned size)
|
||||
{
|
||||
unsigned char* p;
|
||||
unsigned char* end;
|
||||
|
||||
if (size < 512)
|
||||
return;
|
||||
|
||||
/* check the header magic */
|
||||
if (memcmp(data, XLS_MAGIC, 8) != 0)
|
||||
return;
|
||||
|
||||
/* check the endianess */
|
||||
if (data[0x1c] != 0xfe || data[0x1d] != 0xff)
|
||||
return;
|
||||
|
||||
/* walk all the records */
|
||||
end = data + size;
|
||||
p = data;
|
||||
while (p + 4 <= end) {
|
||||
unsigned id = p[0] + ((unsigned)p[1] << 8);
|
||||
unsigned len = p[2] + ((unsigned)p[3] << 8);
|
||||
|
||||
p += 4;
|
||||
|
||||
/* check if the record is complely in the block */
|
||||
if (p + len > end)
|
||||
return;
|
||||
|
||||
/* search for the USRINFO 193h record */
|
||||
if (id == 0x193 && len >= 33) {
|
||||
/* clear the data/time information */
|
||||
memset(p + 24,0, 8);
|
||||
}
|
||||
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* handle */
|
||||
|
||||
|
|
@ -161,6 +217,9 @@ int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* identify Excel files (FNM_CASEFOLD is case insensitive) */
|
||||
handle->xls = fnmatch("*.xls", file->sub, FNM_CASEFOLD) == 0;
|
||||
|
||||
pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
|
||||
|
||||
/* for sure not created */
|
||||
|
|
@ -309,6 +368,10 @@ int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned c
|
|||
memset(block_buffer + read_size, 0, block_size - read_size);
|
||||
}
|
||||
|
||||
/* if it's an xls file, patch the header */
|
||||
if (handle->xls && file_pos == 0)
|
||||
xls_patch(block_buffer, block_size);
|
||||
|
||||
/* Here isn't needed to call posix_fadvise(..., POSIX_FADV_DONTNEED) */
|
||||
/* because we already advised sequential access with POSIX_FADV_SEQUENTIAL. */
|
||||
/* In Linux 2.6.33 it's enough to ensure that data is not kept in the cache. */
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ struct snapraid_handle {
|
|||
struct stat st; /**< Stat info of the opened file. */
|
||||
data_off_t valid_size; /**< Size of the valid data. */
|
||||
int created; /**< If the file was created, otherwise it was already existing. */
|
||||
int xls; /**< If it's an .xls name file. */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue