Navigation Menu

Skip to content

Commit

Permalink
Add win32_restore_file_attributes() to compat.c
Browse files Browse the repository at this point in the history
Anticipating on more file attributes that need restoring in the future
and giving these things are pretty close to the lowlevel Windows API we
better use some abstraction function that restores the different file
attributes. This removes some low level calls from the more generic
findlib.
  • Loading branch information
Marco van Wieringen committed May 6, 2015
1 parent 49f2f39 commit 9f7ff08
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 71 deletions.
77 changes: 7 additions & 70 deletions src/findlib/attribs.c
Expand Up @@ -600,19 +600,6 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
return STREAM_UNIX_ATTRIBUTES_EX;
}

/*
* Define attributes that are legal to set with SetFileAttributes()
*/
#define SET_ATTRS ( \
FILE_ATTRIBUTE_ARCHIVE | \
FILE_ATTRIBUTE_HIDDEN | \
FILE_ATTRIBUTE_NORMAL | \
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | \
FILE_ATTRIBUTE_OFFLINE | \
FILE_ATTRIBUTE_READONLY | \
FILE_ATTRIBUTE_SYSTEM | \
FILE_ATTRIBUTE_TEMPORARY)

/*
* Do casting according to unknown type to keep compiler happy
*/
Expand Down Expand Up @@ -641,7 +628,6 @@ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
int64_t val;
WIN32_FILE_ATTRIBUTE_DATA atts;
ULARGE_INTEGER li;
POOLMEM *win32_ofile;

/** if we have neither Win ansi nor wchar API, get out */
if (!(p_SetFileAttributesW || p_SetFileAttributesA)) {
Expand Down Expand Up @@ -682,72 +668,23 @@ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
p += from_base64(&val, p);
plug(atts.nFileSizeLow, val);

/** Convert to Windows path format */
win32_ofile = get_pool_memory(PM_FNAME);
unix_name_to_win32(&win32_ofile, attr->ofname);

/** At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */

if (!is_bopen(ofd)) {
Dmsg1(100, "File not open: %s\n", attr->ofname);
bopen(ofd, attr->ofname, O_WRONLY | O_BINARY, 0, 0); /* attempt to open the file */
}

if (is_bopen(ofd)) {
/*
* Restore file times on the restored file.
*/
Dmsg1(100, "SetFileTime %s\n", attr->ofname);
if (!SetFileTime(bget_handle(ofd),
&atts.ftCreationTime,
&atts.ftLastAccessTime,
&atts.ftLastWriteTime)) {
win_error(jcr, "SetFileTime:", win32_ofile);
}

/*
* Restore the sparse file attribute on the restored file.
*/
if (atts.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) {
Dmsg1(100, "Restore FILE_ATTRIBUTE_SPARSE_FILE on %s\n", attr->ofname);
DeviceIoControl(ofd->fh, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, NULL, NULL);
}

/*
* Restore the compressed file attribute on the restored file.
*/
if (atts.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) {
USHORT format = COMPRESSION_FORMAT_DEFAULT;
DWORD bytesreturned;

Dmsg1(100, "Restore FILE_ATTRIBUTE_COMPRESSED on %s\n", attr->ofname);
if (!DeviceIoControl(ofd->fh, FSCTL_SET_COMPRESSION, &format, sizeof(format), NULL, 0, &bytesreturned, NULL)) {
win_error(jcr, "DeviceIoControl FSCTL_SET_COMPRESSION", win32_ofile);
}
}

bclose(ofd);
/*
* Restore file attributes and times on the restored file.
*/
if (!win32_restore_file_attributes(attr->ofname, bget_handle(ofd), &atts)) {
win_error(jcr, "win32_restore_file_attributes:", attr->ofname);
}

Dmsg1(100, "SetFileAtts %s\n", attr->ofname);
if (!(atts.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (p_SetFileAttributesW) {
POOLMEM *pwszBuf = get_pool_memory(PM_FNAME);
make_win32_path_UTF8_2_wchar(&pwszBuf, attr->ofname);

BOOL b = p_SetFileAttributesW((LPCWSTR)pwszBuf, atts.dwFileAttributes & SET_ATTRS);
free_pool_memory(pwszBuf);

if (!b) {
win_error(jcr, "SetFileAttributesW:", win32_ofile);
}
} else {
if (!p_SetFileAttributesA(win32_ofile, atts.dwFileAttributes & SET_ATTRS)) {
win_error(jcr, "SetFileAttributesA:", win32_ofile);
}
}
if (is_bopen(ofd)) {
bclose(ofd);
}
free_pool_memory(win32_ofile);

return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/findlib/bfile.c
Expand Up @@ -476,7 +476,7 @@ bool is_restore_stream_supported(int stream)

HANDLE bget_handle(BFILE *bfd)
{
return bfd->fh;
return (bfd->mode == BF_CLOSED) ? INVALID_HANDLE_VALUE : bfd->fh;
}

/*
Expand Down
86 changes: 86 additions & 0 deletions src/win32/compat/compat.c
Expand Up @@ -2624,6 +2624,92 @@ int win32_unlink(const char *filename)
return nRetCode;
}

/*
* Define attributes that are legal to set with SetFileAttributes()
*/
#define SET_ATTRS ( \
FILE_ATTRIBUTE_ARCHIVE | \
FILE_ATTRIBUTE_HIDDEN | \
FILE_ATTRIBUTE_NORMAL | \
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | \
FILE_ATTRIBUTE_OFFLINE | \
FILE_ATTRIBUTE_READONLY | \
FILE_ATTRIBUTE_SYSTEM | \
FILE_ATTRIBUTE_TEMPORARY)

bool win32_restore_file_attributes(POOLMEM *ofname, HANDLE handle, WIN32_FILE_ATTRIBUTE_DATA *atts)
{
bool retval = false;

Dmsg1(100, "SetFileAtts %s\n", ofname);
if (!(atts->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (p_SetFileAttributesW) {
BOOL b;
POOLMEM *pwszBuf = get_pool_memory(PM_FNAME);

make_win32_path_UTF8_2_wchar(&pwszBuf, ofname);
b = p_SetFileAttributesW((LPCWSTR)pwszBuf, atts->dwFileAttributes & SET_ATTRS);
free_pool_memory(pwszBuf);

if (!b) {
goto bail_out;
}
} else {
BOOL b;
POOLMEM *win32_ofile = get_pool_memory(PM_FNAME);

unix_name_to_win32(&win32_ofile, ofname);
b = p_SetFileAttributesA(win32_ofile, atts->dwFileAttributes & SET_ATTRS);
free_pool_memory(win32_ofile);

if (!b) {
goto bail_out;
}
}
}

if (handle != INVALID_HANDLE_VALUE) {
/*
* Restore the sparse file attribute on the restored file.
*/
if (atts->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) {
Dmsg1(100, "Restore FILE_ATTRIBUTE_SPARSE_FILE on %s\n", ofname);
if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, NULL, NULL)) {
goto bail_out;
}
}

/*
* Restore the compressed file attribute on the restored file.
*/
if (atts->dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) {
USHORT format = COMPRESSION_FORMAT_DEFAULT;
DWORD bytesreturned;

Dmsg1(100, "Restore FILE_ATTRIBUTE_COMPRESSED on %s\n", ofname);
if (!DeviceIoControl(handle, FSCTL_SET_COMPRESSION, &format, sizeof(format), NULL, 0, &bytesreturned, NULL)) {
goto bail_out;
}
}

/*
* Restore file times on the restored file.
*/
Dmsg1(100, "SetFileTime %s\n", ofname);
if (!SetFileTime(handle,
&atts->ftCreationTime,
&atts->ftLastAccessTime,
&atts->ftLastWriteTime)) {
goto bail_out;
}
}

retval = true;

bail_out:
return retval;
}

#include "mswinver.h"

char WIN_VERSION_LONG[64];
Expand Down
3 changes: 3 additions & 0 deletions src/win32/compat/include/compat.h
Expand Up @@ -404,6 +404,9 @@ inline unsigned long ffs(unsigned long word)

bool win32_get_vmp_devicename(const char *filename, POOLMEM **device);
int win32_ftruncate(int fd, int64_t length);
bool win32_restore_file_attributes(POOLMEM *ofname,
HANDLE handle,
WIN32_FILE_ATTRIBUTE_DATA *atts);

#undef ftruncate
#define ftruncate win32_ftruncate
Expand Down

0 comments on commit 9f7ff08

Please sign in to comment.